Lewati navigasi

Tadi ada yang menanyakan di forum Yii tentang bagaimana membuat file excel yang dapat didownload di Yii. Intinya di sini kita tinggal pakai HTTP Header Content-Disposition yang dapat menyatakan sebuah halaman dapat diunduh ke dalam sebuah file. Setelah itu kita tinggal menggunakan library PHPExcel.

Ini contoh kodenya. Belum saya coba, tapi harusnya jalan.

<?php

class DownloadController extends CController {

        public function actionIndex(){
                //Pertama-tama download phpexcel terus ditaruh di /protected/extension/

                //Load data ke dalam array sebelum dimasukkan ke file Excel
                //ActiveRecord dan kelas-kelas bawaan Yii kemungkinan tidak akan jalan setelah kita nyalakan PHPExcel

                $users = User::model()->findAll();

                $arrayUsers = array();
                foreach($users as $user){
                        $arrayUsers[] = array(
                                'nama' => $user->nama,
                                'email' => $user->email,
                        );
                }

                //Matikan autoloader bawaannya Yii
                $phpExcelPath = Yii::getPathOfAlias('ext.phpexcel.Classes');
                spl_autoload_unregister(array('YiiBase', 'autoload'));
                //Include PHPExcel
                include($phpExcelPath . DIRECTORY_SEPARATOR . 'PHPExcel.php');
                //Setelah ini kelas-kelas bawaan Yii kemungkinan besar tidak akan jalan

                //Buat object PHPExcel Baru
                $objPHPExcel = new PHPExcel();
                $objPHPExcel->getProperties()->setCreator("Petra Barus");
                $objPHPExcel->getProperties()->setLastModifiedBy("Petra Barus");
                $objPHPExcel->getProperties()->setTitle("Dokumen Saya");
                $objPHPExcel->getProperties()->setSubject("Dokumen Saya");
                $objPHPExcel->getProperties()->setDescription("Dokumen Saya");

                //Selecting sheets
                $objPHPExcel->setActiveSheetIndex(0);

                //Mengisi Excel
                foreach($arrayUsers as $k => $u){
                        $objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow(1, $k, $u['nama']);
                        $objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow(2, $k, $u['email']);
                }

                //HTTP Header untuk download
                header('Content-type: application/ms-excel');
                header('Content-Disposition:  inline; attachment; filename=dokumen.xls');
                flush();

                //Dumping data to HTTP
                $writer = new PHPExcel_Writer($objPHPExcel);
                $writer->save('php://output');

		exit();

        }
}

Salah satu aplikasi yang sedang saya kembangkan menggunakan username vanity URL. Maksudnya adalah pada setiap pengguna akan mempunyai sebuah link yakni username pengguna yang ditempelkan pada domain. Contohnya adalah seperti twitter. URL twitter saya adalah http://www.twitter.com/petrabarus. Pada URL tersebut username saya petrabarus ditambahkan pada domain twitter.com. Sekarang kita ingin membuat sebuah aplikasi yang dapat mengakses user saya petrabarus dengan alamat http://aplikasi/petrabarus.

Sebelum Yii 1.1.8, implementasi ini agak sedikit kompleks (saya tidak tertarik untuk membahasnya). Tapi sejak adanya kelas CBaseUrlRule, ini jadi lebih mudah.

Pertama-tama, misalnya kita mempunyai kelas model User yang digenerate dari Gii. Saya yakin hampir semua aplikasi Yii memiliki kelas seperti di bawah.

/*
* The followings are the available columns in table 'Users':
* @property integer $id
* @property string $username
* @property string $email
*/
class User extends CActiveRecord {
}

Dengan adanya ActiveRecord class bawaan Yii, kita dapat dengan mudah mengkueri user berdasarkan usernamenya

$username = 'petrabarus';
User::model()->find('username = :username', array(':username' => $username));

Kemudian kita mempunyai sebuah controller untuk melihat user tersebut

class UserController extends CController {
	public function actionView(){
		$username = $_GET['username'];
		$model = User::model()->find('username = :username', array(':username' => $username));
		$this->render('view', array('model' => $model));
	}
}

Untuk mengakses URLnya biasanya yang kita lakukan adalah mengakses http://aplikasi/user?username=petrabarus.

Sekarang kita tinggal membuat sebuah URL Rule seperti di bawah

class UserUrlRule extends CBaseUrlRule {

	public $connectionID = 'db';

	public function createUrl($manager, $route, $params, $ampersand) {
		if ($route === 'user/view' && isset($params['username'])) {
			$newroute = $params['username'];
			unset($params['username']);
			if (count($params) > 0) {
				$newroute.= '?' . http_build_query($params);
			}
			return $newroute;
		}
		return false;
	}

	public function parseUrl($manager, $request, $pathInfo, $rawPathInfo) {
		if (preg_match('/[a-zA-Z0-9\.]+/', $pathInfo, $matches)) {
			$username = $matches[0];
			$exists = User::model()->exists('username = :username', array(':username' => $username));
			if ($exists) {
				$_GET['username'] = $username;
				return 'user/view';
			} else
				return false;
		}
		return false;
	}

}

Method parseUrl dibutuhkan untuk memparsing url yang diakses melalui address bar browser. Sementara itu method createUrl adalah untuk membentuk URL yang kita inginkan. Method createUrl ini nantinya akan digunakan oleh method createUrl milik Controller. Pada method parseUrl itu saya memfilter URL tersebut dengan regex /[a-zA-Z0-9\.]+/ yang merupakan pattern rule dari username pada aplikasi saya. Kemudian jika ada yang mirip maka string pada URL tersebut akan saya periksa apakah ada user yang memiliki nama yang sama. Jika ada maka request dialihkan ke Controller user/view.

Perlu diperhatikan, agar username tidak bentrok dengan URL-URL yang dimiliki oleh Controller ada baiknya kita mempunyai daftar username yang diblacklist, yang diantaranya adalah nama-nama Controller seperti misalnya login, logout, signin, signout, register, dan lain-lain.

Lalu kita tambahkan ke rule di konfigurasi.

'urlManager' => array(
	    'urlFormat' => 'path',
	    'showScriptName' => false,
	    'rules' => array(
		array(
		    'class' => 'application.components.UserUrlRule',
		    'connectionID' => 'db',
		),
		'<controller:\w+>/<id:\d+>' => '<controller>/view',
		'<controller:\w+>/<action:\w+>/<id:\d+>' => '<controller>/<action>',
		'<controller:\w+>/<action:\w+>' => '<controller>/<action>',
	    ),
	),

Dan sekarang kita bisa mengakses halaman user dari http://aplikasi/petrabarus. Untuk mendapatkan URL ini pada Controller, kita cukup memanggil

$this->createUrl('user/view', array('username' => 'petrabarus'));

Saya membutuhkan sebuah fungsi untuk menyisipkan parameter query pada sebuah parameter di kode Javascript saya.

Misalnya, untuk URL

http://www.example.com/home?foo1=bar1#anchor

saya ingin menyisipkan parameter “foo2″ dengan nilai “bar2″, sehingga menjadi

 http://www.example.com/home?foo1=bar1&foo2=bar2#anchor
 

Lihat bahwa penyisipannya cukup rapi dengan menempatkan variabel tersebut pada bagian parameter dan masih menangani anchor “#anchor”.

Setelah mencari di StackOverflow (When in doubt, ask StackOverflow), saya mendapatkan kodenya.

function addParameter(url, parameterName, parameterValue){

	replaceDuplicates = true;
	
	if(url.indexOf('#') > 0){
		var cl = url.indexOf('#');
		urlhash = url.substring(url.indexOf('#'),url.length);
	} else {
		urlhash = '';
		cl = url.length;
	}
	
	sourceUrl = url.substring(0,cl);
	
	
	
	var urlParts = sourceUrl.split("?");
	var newQueryString = "";
	
	if (urlParts.length > 1)
	{
		var parameters = urlParts[1].split("&");
		for (var i=0; (i < parameters.length); i++)
		{
			var parameterParts = parameters[i].split("=");
			if (!(replaceDuplicates && parameterParts[0] == parameterName))
			{
				if (newQueryString == "")
					newQueryString = "?";
				else
					newQueryString += "&";
				newQueryString += parameterParts[0] + "=" + parameterParts[1];
			}
		}
	}
	if (newQueryString == "")
		newQueryString = "?";
	else
		newQueryString += "&";
	newQueryString += parameterName + "=" + parameterValue;

	return urlParts[0] + newQueryString + urlhash;
}

Cara menggunakannya adalah

url = addParameter("http://www.example.com/home?foo1=bar1#anchor", "foo2", "bar2");

Kodenya di StackOverflow dapat dilihat di sini.

 

Kemaren, seperti beberapa tahun sebelumnya, saya kembali mengisi sesi pengantar Linux untuk Pelatihan Nasional bagi Tim Olimpiade Komputer Indonesia yang akan mengikuti International Olympiads of Informatics tahun 2012 di Milan.

Pengantar Linux ini memiliki tujuan agar siswa bisa terbiasa untuk memrograman dalam lingkungan sistem operasi Linux. Ini tidak lain karena di IOI nanti lingkungan pemrograman yang disediakan adalah Linux. Dalam pengantar ini, selain memperkenalkan tentang Linux serta program-program apa saja yang ada di sana (Nautilus, GCC, GEdit, Geany, dsb), saya juga memperkenalkan bagaimana menggunakan terminal untuk membantu dalam pemrograman.

Materinya dapat dilihat di bawah. Semoga bermanfaat.

NB: Materi ini merupakan versi terbaru dari yang sudah saya tulis tahun lalu. Ada beberapa tambahan seperti time dan batch processing.

Sering kelupaan dan malas nyari-nyari lagi snippet di internet.

#!/bin/bash
dir='/path/to/dir';
for file in `ls $dir`; do
        echo $file;
done;


Ralat:

Tips dari Pak Jo

Kode di atas bisa tidak berjalan dengan baik untuk path yang memiliki karakter spasi. Berikut adalah kode yang sudah diralat.

#!/bin/sh
dir='/etc';
ls "$dir" | while read file ; do
	echo $file;
done;

Beberapa hari ini saya berkutat dengan aplikasi Excel menggunakan Macro VBA. Sebenarnya sejak dulu saya kurang suka memrogram menggunakan Visual Basic, tapi kali ini bisa dijadikan pengalaman yang cukup menarik.

Salah satu hal yang membuat saya merasa kesulitan di awal memrogram macro Excel adalah dalam penamaan cell pada Excel di mana terdapat aturan penanda kolom yang menggunakan alfabet sementara penanda baris menggunakan angka. Misalnya saya ingin menunjuk cell pada kolom ke-2 dan baris ke-3, saya harus mengubahnya menjadi “B3″. Di bawah ini adalah kode untuk melakukan pengubahan nomor kolom menjadi nama. Kode ini saya dapatkan dari salah satu pertanyaan di StackOverflow.com. (I love StackOverflow.com!)

Public Function getColumnName(colNum As Integer) As String
    Dim d As Integer
    Dim m As Integer
    Dim name As String
    d = colNum
    name = ""
    Do While (d > 0)
        m = (d - 1) Mod 26
        name = Chr(65 + m) + name
        d = Int((d - m) / 26)
    Loop
    getColumnName = name
End Function

Contoh penggunaannya adalah

Dim rngData as Range
rngData = Worksheet(0).Range(getColumnName(1) & 2, getColumnName(3) & 4)

Kode di atas akan mengembalikan Range data dari cell A2 hingga C4.

Berikut adalah tips-tips dari Brian Marshal (Bronze Medalist IOI 2007) dalam menghadapi Olimpiade Sains Provinsi. Tips-tips ini dikutip (dan dikemas ulang) dari twitter beliau (@microbrainx)

  1. Coba cari dan kerjakan soal OSK dan OSP yang sudah pernah dikeluarkan sebelumnya. Banyak soal model soal yang mirip dan serupa.
  2. Soal-soal secara garis besar dibagi ke dalam 3 kelompok: Analitika, Aritmatika, dan Algoritmika. Kenali kemampuan diri sendiri dalam kelompok-kelompok soal tersebut.
  3. Jika kamu merasa dirimu kurang menguasai bagian tertentu berlatihlah lebih giat lagi pada bagian tersebut.
  4. Jika menghadapi soal, kerjakanlah mulai dari soal yang kamu rasa mudah. Setiap orang mungkin bisa berbeda-beda tergantung dari kemampuan yang dimiliki.
  5. Biasakan untuk menggunakan kertas buram dalam menulis langkah demi langkah solusi yang kamu kerjakan. Ini akan lebih memudahkan kamu jika kamu menemukan kesalahan atau ingin memeriksa ulang jawaban.
  6. Jika kamu menemukan sebuah soal yang membutuhkan penghitungan atau pengerjaan yang sangat banyak, jangan langsung dikerjakan. Coba diam dan berpikir sejenak. Biasanya ada cara yang lebih kreatif untuk menyelesaikan soal tersebut.
  7. Jangan pernah berusaha mencari-cari kesalahan penulisan soal algoritmika (compile error, dll) karena yang digunakan adalah bahasa yang digunakan pseudopascal. Ini akan menghabiskan waktu yang disediakan untuk mengerjakan soal.
  8. Percayalah bahwa ada hubungan yang erat antara kegemaran mengerjakan soal problem solving teori dengan kesuksesan pada soal problem solving dalam pemrograman.
  9. Jangan sampai kelelahan di dekat hari ujian. Belajar keras di menit-menit terakhir tidak akan banyak membantu. Tidur yang cukup, makan yang cukup, main yang cukup, dan tertawa yang cukup.
  10. Ingat, perjalanan masih sangat panjang tetapi akan ada penghargaan yang sangat besar menanti di ujung jalan.

Tetap semangat! Sampai berjumpa di Manado bulan September nanti!

Salah satu hal yang menyebalkan dari GEdit adalah biasanya dia menaruh berkas-berkas sementara di direktor berkas yang sedang disunting. Berkas-berkas tersebut biasanya berakhiran karakter ‘~’. Untuk menghilangkan semua berkas cadangan yang ada di direktori kerja kita, cukup mengeksekusi perintah berikut.

find /path/to/folder -iname "*~" -exec rm '{}' ';'

Perintah di atas akan mencari semua berkas berakhiran ‘~’ dan langsung menghapusnya.

Satu hal yang perlu dilakukan setelah melakukan instalasi CUDA Toolkit dkk di komputer (selain program “Hello World!” tentunya) adalah menampilkan device CUDA yang ada di komputer. Hal ini dapat dilakukan dengan memanggil fungsi cudaGetDeviceProperties. Fungsi ini akan mengisi properti dari device yang diinginkan ke dalam sebuah struktur data cudaDeviceProp. Kode sederhananya saya dapatkan dari link ini.

#include <stdlib.h>
#include <stdio.h>
#include <cuda.h>
#include <cuda_runtime.h>

int main(int argc, char **argv)
{
    int ct, dev;
    cudaError_t code;
    struct cudaDeviceProp prop;

    cudaGetDeviceCount(&ct);
    code = cudaGetLastError();
    if (code)
	printf("%s\n", cudaGetErrorString(code));

    if (ct == 0) {
	printf("Cuda device not found.\n");
	exit(0);
    }
    printf("Found %i Cuda device(s).\n", ct);

    for (dev = 0; dev < ct; ++dev) {
	printf("Cuda device %i\n", dev);

	cudaGetDeviceProperties(&prop, dev);
	printf("\tname : %s\n", prop.name);
	printf("\ttotalGlobablMem: %lu\n",
	       (unsigned long) prop.totalGlobalMem);
	printf("\tsharedMemPerBlock: %i\n", prop.sharedMemPerBlock);
	printf("\tregsPerBlock: %i\n", prop.regsPerBlock);
	printf("\twarpSize: %i\n", prop.warpSize);
	printf("\tmemPitch: %i\n", prop.memPitch);
	printf("\tmaxThreadsPerBlock: %i\n", prop.maxThreadsPerBlock);
	printf("\tmaxThreadsDim: %i, %i, %i\n", prop.maxThreadsDim[0],
	       prop.maxThreadsDim[1], prop.maxThreadsDim[2]);
	printf("\tmaxGridSize: %i, %i, %i\n", prop.maxGridSize[0],
	       prop.maxGridSize[1], prop.maxGridSize[2]);
	printf("\tclockRate: %i\n", prop.clockRate);
	printf("\ttotalConstMem: %i\n", prop.totalConstMem);
	printf("\tmajor: %i\n", prop.major);
	printf("\tminor: %i\n", prop.minor);
	printf("\ttextureAlignment: %i\n", prop.textureAlignment);
	printf("\tdeviceOverlap: %i\n", prop.deviceOverlap);
	printf("\tmultiProcessorCount: %i\n", prop.multiProcessorCount);
    }
}

Tinggal kompilasi kode ini dengan nvcc

$nvcc -o deviceprop deviceprop.c
$./deviceprop

Hasil keluarannya untuk komputer pribadi saya

Found 1 Cuda device(s).
Cuda device 0
	name : GeForce GTS 250
	totalGlobablMem: 1073020928
	sharedMemPerBlock: 16384
	regsPerBlock: 8192
	warpSize: 32
	memPitch: 2147483647
	maxThreadsPerBlock: 512
	maxThreadsDim: 512, 512, 64
	maxGridSize: 65535, 65535, 1
	clockRate: 1912000
	totalConstMem: 65536
	major: 1
	minor: 1
	textureAlignment: 256
	deviceOverlap: 1
	multiProcessorCount: 16

Beberapa hari yang lalu saya menginstall tools nVidia CUDA di komputer saya yang Ubuntu 10.10. Ternyata cara instalasinya sangat mudah. Ada di sini. Untuk yang di link itu CUDA yang diinstal adalah versi 3.2 untuk Ubuntu 10.4 64 bit, sedangkan saya menginstall CUDA versi terbaru 4.0.11 RC di Ubuntu 10.10.
Instalasinya mulus, tetapi masalah yang terjadi adalah tiba-tiba GUInya stuck di resolusi 640×480. Di setting Ubuntu dan nVidia Control Panelnya pun tidak bisa dinaikkan resolusinya. Ini bisa diperbaiki dengan mengedit konfigurasi X Window di /etc/X11/xorg.conf.

Ikuti

Get every new post delivered to your Inbox.