Archive for the ‘Works’ Category

The corruption of the last syllable containing the vowel ‘a’ on Indonesian

Sunday, December 23rd, 2007 by Agro Rachmatullah

In spoken Indonesian, the vocal ‘a’ on the last syllable of many words change into ‘e’. When this colloquial corruption exists, using the correct version sounds very very stiff and formal. Here are some examples:

teman -> temen (friend)
Temenmu tadi juga kuliah di UGM? - Does your friend (which we met earlier) also study in UGM?

But not preman -> premen (even though it has the same last syllable as the previous example)

dalam -> dalem (inside)
Bukunya ada di dalem tas yang kecil itu. - The book is inside that small bag.

malam -> malem (night)
Gimana kalo ngerjainnya nanti malem aja? - How about doing it later tonight?

But not salam -> salem

tanam -> tanem (to plant), also its derived word tanaman -> taneman (plant)
Tadi aku ngeliat taneman aneh lo di kuburan! - I found a weird plant on the cemetery, you know!

enam -> enem (six)
Aku udah nyoba enem kali tapi masih belum bisa menang juga. - I’ve tried six times but still couldn’t win.

But not senam -> senem

senang -> seneng (to like)
Aku nggak gitu seneng lagu ini. - I don’t really like this song.

But not renang -> reneng

simpan - simpen (to keep something in a place)
Simpen di tempat yang aman lo! - Make sure you keep it in a safe place!

But not depan -> depen

malas -> males (lazy)
Kalau kamu males-malesan, mana bisa lulus? - If you act lazy, how can you pass?

But not kelas -> keles

Most of the words that I could think of ends with -n, -m, or -ng (which in Japanese is all represented by ん). Can you find other examples?

It is OK to use the corrupted vocabulary presented here when talking to someone higher (e.g., teacher). However, it is not used in formal writing or speech.

Translation attempt: Haikara-san ga Tooru

Tuesday, December 11th, 2007 by Agro Rachmatullah

Konno Asami on Uta Doki! Pop Classics singing Haikara-san ga Tooru with Michishige Sayumi as MC

Haikara-san ga Tooru” is the theme song for a 1987 movie of the same name. I stumbled upon this song on Uta Doki! Pop Classics, a short regular TV show where Hello! Project members sing old songs requested by the viewers.

On Uta Doki! #301, this particular song was sung by Konno Asami with Michishige Sayumi as the MC and spontaneous uninvited dancer (see screenshot). A very nice and warm song (YouTube links: Original song by Minamino Yoko; Konno Asami version in Uta Doki!).

I present you below the kanji, romaji, and my translation. Corrections are welcomed. Sorry, no bahasa Indonesia because it is planned to be released as an MMIF (Morning Musume Indonesia Fansub) product for international consumption :).

Kanji:

曲名:はいからさんが通る/歌手:南野陽子

朝もやにけむってる 運命のわかれ道
あなたに出逢ってしまって
あやうい方へ 歩き出したの

木洩れ日が踊る日は 笑いころげたりして
曇った風が走る日は
心の奥がキュンと音をたてた

くちびるを重ねた数では
愛情をつなぎとめられない
知ってるけど…

凛凛しく恋してゆきたいんです 私
傷つくことに弱虫なんて 乙女がすたるもの
ややこしいかけひきは 苦手です私
晴れた空が好きです

ふれあう肌のぬくもりほど
さきゆきは 確かじゃないこと
知ってるけど…

たとえ涙の嵐がきたって平気
あなたとみた青空が 一番胸に輝くわ
別れてもまた出逢えば いいもの平気
前を向いてゆきます

うつむかずに 歩きたいの
あなたへの愛しさも
せつなさも まっすぐみつめて

凛凛しく恋してゆきたいんです 私
傷つくことに弱虫なんて 乙女がすたるもの
凛凛しく恋してゆきたいんです 私
晴れた空が好きです

Romaji:

Song: Haikara-san ga Tooru
Singer: Minamino Yoko

asamoya ni kemutteru unmei no wakare michi
anata ni deatteshimatte
ayaui hou e arukidashita no

komorebi ga odoru hi wa waraikorogetari shite
kumotta kaze ga hashiru hi wa
kokoro no oku ga kyunto oto o tateta

kuchibiru o kasaneta kazu de wa
kimochi o tsunagitomerarenai
shitteru kedo…

ririshiku koishiteyukitain desu watashi
kizutsuku koto ni yowamushi nante otome ga sutaru mono
yayakoshii kakehiki wa nigate desu watashi
hareta sora ga suki desu

fureau hada no nukumori hodo
sakiyuki wa tashika janai koto
shitteru kedo…

tatoe namida no arashi ga kitatte heiki
anata to mita aozora ga ichiban mune ni kagayaku wa
wakarete mo mata deaeba ii mono heiki
mae o muite yukimasu

utsumukazu ni arukitai no
anata e no itoshisa mo
setsunasa mo massugu mitsumete

ririshiku koishite yukitain desu watashi
kizutsuku koto ni yowamushi nante otome ga sutaru mono
ririshiku koishite yukitain desu watashi
hareta sora ga suki desu

English Translation:

Translated by agro1986 aka koushi

Here Comes Miss Stylish

The crossroad of fate shrouded in the morning mist
I met you by chance
And walked the path of risk

We laughed on the days when sun rays danced through the leaves
And on the days when the fog ran away
My heart sounded with joy

By our number of kisses
I wouldn’t be able to keep your feelings long
I know it, but…

I want to love you gallantly
Being afraid to get hurt would be a dishonor
I’m not good at making intricate plans
A clear sky is what I like

There is no certainty that our future
Will be as warm as our touching skin
I know it, but…

I don’t care if this will end in tears
The blue sky that I saw with you lit my heart the most
Even if we break up, I’ll be fine if we meet again
Move forward positively

I want to walk without hanging my head low
Please look honestly
At my love for you and my pain

I want to love you gallantly
Being afraid to get hurt would be a dishonor
I want to love you gallantly
A clear sky is what I like

Panduan Yahoo! Jisho: Kamus Jepang Inggris dengan Banyak Contoh Kalimat

Saturday, December 8th, 2007 by Agro Rachmatullah

Saat aku sedang terhubung ke Internet, Yahoo! Jisho adalah situs kamus Jepang-Inggris yang selalu kukunjungi. Banyaknya contoh kalimat untuk tiap makna yang berbeda membuat kamus ini sangat berguna saat aku menemui kata baru. Alamatnya ada di http://dic.yahoo.co.jp. Artikel ini akan memandu kamu menggunakan situs tersebut sebagai kamus Jepang-Inggris. (Situs tersebut juga bisa digunakan sebagai kamus lain, misalnya Jepang-Jepang.)

Kamus Jepang Inggris Yahoo!

Situsnya berbahasa Jepang, namun jangan panik karena panduan ini akan menjelaskan semua bagian pada form pencarian tersebut.

Nomor 1 merupakan kotak teks untuk menulis kata yang ingin dicari. Kalau kata yang ingin dicari tersebut bersumber dari halaman web atau sejenisnya, cukup dicopy-paste ke tempat ini. Sebagai contoh, kamu bisa mencoba kata-kata berikut: わたし, アイドル, 好き. Kotak tersebut menerima hiragana, katakana, maupun kanji dari suatu kata. Contohnya, untuk mencari kata “kirei” kamu bisa memberikan きれい, キレイ , maupun 奇麗. Tentu saja kita tidak bisa memasukkan romaji, karena bahasa Jepang memang tidaklah ditulis menggunakan romaji.

Bagaimana kalau kamu ingin menuliskan katanya sendiri, tetapi di komputer kamu tidak ada IME? Kunjungi saja http://agro1986.googlepages.com/ime.htm (Uhuk, uhuk, promosi…).

Gama Web-based Japanese Input Method Editor (IME) with Ajax!!!

Pada aplikasi web tersebut, klik tombol “Turn IME On” lalu mulailah mengetik suatu kata di kotak teksnya, misalnya “sugoi”. Katanya akan langsung dirubah menjadi hiragana (sugoiiii). Tekan Enter setelah selesai mengetik katanya, lalu copy-paste hasilnya ke kotak teks Yahoo! Jisho. (Tips: Sebelum menekan Enter, tekan F7 untuk merubahnya ke katakana.)

Berikutnya, nomor 2 adalah metode pencocokan kata. Pilihannya, dari atas ke bawah, adalah:

  1. で始まる (INPUT de hajimaru): Dimulai dengan masukan. Sebagai contoh, jika masukan adalah かみ (kami), maka selain kata tersebut, kata seperti かみなり (kaminari) juga akan dicari.
  2. に一致する (INPUT ni icchi suru): Cocok persis dengan masukan. Jika memberi かみ (kami), maka hanya kata tersebut yang akan dicari.
  3. を含む (INPUT o fukumu): Berisi masukan. Dengan kata lain, masukan bisa berada di awal, tengah, maupun akhir kata. Dengan masukan かみ (kami), maka selain kata tersebut, kata seperti かみなり (kaminari), おかみさん (okamisan), dan あかみ (akami) juga akan dicari.
  4. で終わる (INPUT de owaru): Diakhiri masukan. Sebagai contoh, jika masukan adalah かみ (kami), maka selain kata tersebut, kata seperti あかみ (akami) juga akan dicari.
  5. を解説に含む (INPUT o kaisetsu ni fukumu): Berisi masukan pada penjelasannya. Sebagi contoh, jika masukan adalah かみ (kami), maka あな (ana, “lubang”) akan menjadi salah satu hasil pencarian karena halaman penjelasannya berisi contoh kalimat 「おおかみの穴」 (ookami no ana).

Pada umumnya, yang aku gunakan adalah pilihan kedua dari atas (に一致する, cocok persis).

Nomor 3 di screenshot pertama adalah pilihan kamus. Dari kiri ke kanan, pilihannya adalah:

  1. 国語 (kokugo): Kamus Jepang-Jepang. Memberikan penjelasan yang sangat mendetil mengenai tiap kata… dalam bahasa Jepang.
  2. 類語 (ruigo): Kamus sinonim. Berguna untuk mencari alternatif kata yang tidak umum untuk membuat teman-teman kamu terkagum-kagum.
  3. 英和 (eiwa): Kamus Inggris-Jepang. Ingatlah untuk memberikan masukan berupa bahasa Inggris.
  4. 和英 (waei): Kamus Jepang-Inggris. Topik yang dibahas di panduan ini.
  5. すべての辞書 (subete no jisho): Cari di semua kamus.

Kalau kamu seperti aku, yang menggunakan kamus ini saat menemukan kata baru waktu membaca, maka kamu akan memilih pilihan keempat.

Terakhir, pilih tombol yang ditandai dengan 4 pada screenshot pertama yaitu 検索 (kensaku, cari). Inilah contoh suatu hasil pencarian:

Hasil pencarian Yahoo! Dictionary

Jangan kaget kalau sekali lagi tidak ada romaji. Ayo belajar huruf Jepang yang sebenarnya! Di balik rintangan berupa sistem penulisan yang indah tersebut, kamu akan menemukan kamus ini sebagai kamus yang kaya akan contoh kalimat dan sangat berguna sebagai teman membaca kamu.

Kalau kamu menuliskan kana (hiragana ataupun katakana) sebagai masukannya, seluruh kata dengan bunyi tersebut akan dicari. Sebagi contoh, kalau kamu melakukan pencarian persis terhadap kata きく, maka kamu akan mendapatkan mulai dari 菊 (bunga Krisantemum) sampai 聞く (mendengar, bertanya).

Di lain pihak, kalau kamu menuliskan kanji sebagai masukan, maka seluruh bacaannya akan diberikan. Sebagai contoh, kalau kamu memberikan 間, maka berbagai bacaannya mulai dari あいだ (aida) sampai ま (ma) akan diperoleh.

Untuk pencarian yang mengembalikan banyak hasil tersebut, kamu bisa berganti hasil pencarian melalui kotak pilihan yang terletak di sebelah kanan:

Alternatif hasil pencarian Kamus Yahoo!

Masih banyak yang bisa dibahas dari penggunaan Yahoo! Dictionary ini, namun aku harap panduan ini sudah cukup untuk membuat kamu tertarik untuk mulai menggunakan situs tersebut. Semoga berguna!

Tutorial penggunaan SQLite dari .NET menggunakan bahasa C#

Monday, June 11th, 2007 by Agro Rachmatullah

Pada artikel sebelumnya, telah diperkenalkan SQLite yaitu mesin SQL yang kecil dan cepat. Kalau kamu memerlukan akses basis data pada program kamu, kemungkinan besar SQLite adalah pilihan terbaik sebab deployment-nya tidak rumit (SQLite akan menjadi bagian program kamu dan basis datanya disimpan pada 1 berkas).

SQLite memiliki binding untuk banyak bahasa, termasuk untuk bahasa-bahasa di lingkungan pemrograman .NET. Di artikel ini kita akan menggunakan C# (pada .NET 2.0) untuk membuat dan mengakses basis data SQLite.

(Tutorial ini spesifik Windows. Di lain waktu akan diposting cara yang bisa digunakan di Linux+Mono.)

Instalasi dan kompilasi

Ada banyak cara untuk menggunakan SQLite dari .NET, dan yang akan digunakan di tutorial ini adalah System.Data.SQLite.dll. Pertama-tama, unduh dan jalankan installer-nya. Setelah selesai, kamu akan menemukan berkas System.Data.SQLite.dll yang secara default ada di C:\Program Files\SQLite.NET\bin.

(Saat artikel ini ditulis, di halaman depan situs System.Data.SQLite terdapat pranala untuk mengunduh versi stabil dan alpha. Pembuatan artikel ini menggunakan versi stabilnya.)

Kalau kamu menggunakan IDE seperti SharpDevelop dan Visual C# Express, tambahkan referensi ke berkas tersebut pada proyek kamu (karena tidak di-install di GAC, kamu perlu mem-browse lokasinya. Kamu juga perlu menambahkan referensi ke System.Data.dll yang merupakan assembly bawaan .NET (ada di GAC). Ini contoh screenshot hasilnya pada SharpDevelop 2.1:

Mereferensi System.Data.SQLite.dll dari SharpDevelop

Kalau kamu melakukan kompilasi dari terminal, jangan lupa mereferensikan kedua assembly tersebut, misalnya:

csc /r:"C:\\Program Files\\SQLite.NET\\bin\\System.Data.SQLite.dll",System.Data.dll Test.cs

Dengan mereferensikan kedua assembly tersebut, kita bisa menggunakan kelas-kelas yang terdefinisi di dalamnya. Namun agar program kamu bisa berjalan, System.Data.SQLite.dll harus berada pada direktori yang sama dengan program kamu. IDE seperti SharpDevelop akan menyalin System.Data.SQLite.dll secara otomatis, namun pada kompilasi manual kamu harus menyalin berkasnya sendiri.

Cek lagi semua langkah yang diberikan di bagian ini kalau nanti menjumpai masalah saat mengkompilasi atau menjalankan program kamu.

Pengenalan ADO.NET

Dalam Framework .NET, ADO.NET adalah teknologi yang memungkinkan kita untuk berinteraksi dengan sumber data. Pada umumnya sumber data itu adalah basis data, namun bisa saja sumber datanya adalah berkas teks atau berkas spreadsheet.

Kelas yang digunakan pada ADO.NET tergantung sumber datanya. Misalnya, untuk berinteraksi dengan Microsoft SQL Server digunakan kelas seperti SqlConnection, SqlCommand, dan SqlDataReader. Untuk berinteraksi dengan basis data melalui ODBC, kelas-kelas yang digunakan misalnya OdbcConnection, OdbcCommand, dan OdbcDataReader. Walaupun nama kelasnya untuk tiap sumber data berbeda, cara penggunaanya sama karena kelas-kelas tersebut diturunkan dari kelas dasar yang sama di ADO.NET.

System.Data.SQLite.dll memberikan implementasi ADO.NET untuk mengakses basis data SQLite. Istilah teknisnya adalah "ADO.NET data provider". Kita akan mempelajari cara menggunakan kelas SQLiteConnection, SQLiteCommand, dan SQLiteDataReader untuk berinteraksi dengan basis data SQLite.

Membuat tabel dan mengisinya dengan data

Karena kelas-kelas pada System.Data.SQLite.dll terdapat di namespace System.Data.SQLite, kita akan menggunakan statement using di awal program:

using System.Data.SQLite;

Objek SQLiteConnection berfungsi untuk membuka suatu berkas basis data SQLite. Jika berkas yang ditentukan tidak ada, maka akan dibuat berkas baru. Kita menginstansiasi objek SQLiteConnection baru dengan memberinya string koneksi sebagai argumen. Di string tersebutlah kita tentukan nama berkasnya. Ini contohnya:

SQLiteConnection conn = new SQLiteConnection("Data Source=test.db3");

Setelah nanti koneksi dibuka dengan memanggil metode Open, kita bisa menggunakan objek SQLiteCommand untuk menjalankan perintah-perintah SQL. Secara umum urutan langkah saat menggunakan objek koneksi adalah:

  1. Meninstansiasi objek SQLiteConnection.
  2. Membuka koneksi dengan metode Open.
  3. Objek lain, misalnya objek SQLiteCommand, menggunakan koneksi tersebut.
  4. Menutup koneksi dengan metode Close.

Inilah contoh program di mana objek SQLiteCommand menggunakan koneksi yang sudah berjalan untuk membuat tabel:

using System;
using System.Data.SQLite;

class Test
{
   static void Main()
   {
      SQLiteConnection conn = null;
      try
      {
         conn = new SQLiteConnection("Data Source=test.db3");
         conn.Open();

         SQLiteCommand cmd =
            new SQLiteCommand("CREATE TABLE mahasiswa" +
               "(nim INTEGER PRIMARY KEY, " +
               "nama TEXT, prodi CHAR(2));",
               conn);
         cmd.ExecuteNonQuery();

         cmd.CommandText = "INSERT INTO mahasiswa(nama, prodi) " +
            "VALUES('Linus Torvalds', 'IK');";
         cmd.ExecuteNonQuery();

         cmd.CommandText = "INSERT INTO mahasiswa " +
            "VALUES(9374, 'Agro', 'IK');";
         cmd.ExecuteNonQuery();
      }
      finally
      {
         if(conn != null)
         {
            conn.Close();
         }
      }
   }
}

(string yang panjang sengaja dipecah agar tampil baik di situs ini)

Bisa dilihat bahwa setelah objek SQLiteConnection dibuat, yang pertama kali dilakukan adalah membuka koneksinya dengan metode Open. Melakukan operasi pada koneksi yang belum dibuka akan menghasilkan eksepsi.

Saat membuat objek SQLiteCommand, kita memberikan perintah SQL sebagai argumen pertama dan objek koneksi yang telah kita buat sebelumnya sebagai argumen kedua. Lalu kita menjalankan perintah SQL tersebut dengan memanggil metode ExecuteNonQuery. ExecuteNonQuery kita gunakan karena kita tidaklah mencari data pada basis data. Kalau operasi yang kita lakukan adalah pencarian data misalnya dengan perintah SQL SELECT, maka metode yang digunakan berbeda (akan dibahas belakangan).

Untuk menjalankan perintah SQL lain, kita tidak perlu membuat objek baru. Yang perlu dilakukan adalah mengubah perintahnya melalui properti CommandText dan memanggil ExecuteNonQuery kembali. Kita juga bisa merubah koneksi yang ingin digunakan melalui properti Connection jika diperlukan.

Perhatikan bahwa koneksi ditutup di blok finally. Ini adalah agar koneksi tetap ditutup walaupun terjadi eksepsi di blok try. Sebagai contoh, kalau program tersebut dijalankan untuk yang kedua kalinya maka akan terjadi eksepsi saat tabel akan dibuat. Ini karena tabel mahasiswa sudah ada (dibuat saat program pertama kali dijalankan). Walaupun terjadi eksepsi, blok finally tetap akan dijalankan sehingga koneksi bisa ditutup.

Sebelum koneksi ditutup, dicek apakah variabel conn bernilai null. Ini karena bisa saja eksepsi terjadi saat objek koneksi diinstansiasi (misal string koneksi ngawur), dan pada kasus tersebut variabel conn akan bernilai null (nilai awalnya). Mencoba memanggil Close pada variabel yang bernilai null akan melempar eksepsi yang lain lagi dan kita tidak ingin hal itu terjadi.

Melakukan query dengan perintah SELECT

Untuk melakukan query, kita akan berkenalan dengan dua metode baru pada kelas SQLiteCommand yaitu ExecuteScalar dan ExecuteReader. ExecuteScalar digunakan kalau hasil query-nya berupa sebuah nilai, misalnya jumlah baris yang ada di tabel. ExecuteReader digunakan kalau haisl query-nya berupa baris-baris pada basis data kita.

ExecuteReader akan mengembalikan suatu objek SQLiteDataReader. Dari objek tersebut kita bisa mengambil nilai kolom pada baris-baris hasil query. Contoh programnya yang diikuti penjelasannya adalah sebagai berikut:

using System;
using System.Data.SQLite;

class Test
{
   static void Main()
   {
      SQLiteConnection conn = null;
      SQLiteDataReader rdr = null;
      try
      {
         conn =
            new SQLiteConnection("Data Source=test.db3");
         conn.Open();

         SQLiteCommand cmd =
            new SQLiteCommand("SELECT COUNT(*) FROM mahasiswa;",
               conn);

         long jumlah = (long)cmd.ExecuteScalar();
         Console.WriteLine("Jumlah: " + jumlah);

         cmd.CommandText = "SELECT * FROM mahasiswa;";
         rdr = cmd.ExecuteReader();

         while(rdr.Read())
         {
            Console.WriteLine("===");
            Console.WriteLine("NIM: " + rdr[0]);
            Console.WriteLine(”Nama: ” + rdr["nama"]);
         }
      }
      finally
      {
         if(rdr != null)
         {
            rdr.Close();
         }
         if(conn != null)
         {
            conn.Close();
         }
      }
   }
}

Ini contoh outputnya:

Jumlah: 2
===
NIM: 1
Nama: Linus Torvalds
===
NIM: 9374
Nama: Agro

Pada query pertama di contoh tersebut (SELECT COUNT(*) FROM mahasiswa;), hasil query-nya adalah sebuah angka yang menunjukkan jumlah baris pada tabel mahasiswa. Karena hasil querynya berupa nilai tunggal, maka kita cukup memanggil ExecuteScalar. Dalam kasus ini, hasil kembaliannya adalah integer 64 bit (tipe long pada C#) yang dibungkus sebagai Object. Oleh karena itu, kita perlu menggunakan cast untuk menyimpannya sebagai variabel long.

Query berikutnya (SELECT * FROM mahasiswa;) mengembalikan baris-baris pada tabel mahasiswa, oleh karenanya digunakan metode ExecuteReader. Metode tersebut mengembalikan objek SQLiteDataReader yang disimpan di variabel rdr.

Nilai pada baris-baris hasil dibaca dalam perulangan while. Di sini digunakan metode Read pada SQLiteDataReader yang berfungsi untuk membaca baris berikutnya dan mengembalikan true jika berhasil. Jika semua baris sudah dibaca, metode tersebut akan mengembalikan false sehingga eksekusi program bisa keluar dari perulangan.

Untuk mengambil nilai kolom tertentu, kita bisa menggunakan indeksnya (misal rdr[0] untuk kolom pertama) maupun nama kolomnya (misal rdr["nama"]). Agar kodenya mudah dibaca disarankan untuk menggunakan nama kolomnya.

Sebagaimana koneksi, reader juga perlu ditutup kalau sudah selesai digunakan. Digunakan teknik yang sama seperti cara menutup koneksi, yaitu pada blok finally.

Penutup

SQLite adalah mesin SQL yang menyediakan binding untuk banyak bahasa, salah satunya untuk bahasa-bahasa .NET. Di tutorial ini telah dibahas penggunaan kelas-kelas pada System.Data.SQLite.dll yang merupakan penyedia data ADO.NET. Dengan pendekatan ini, yang perlu dilakukan saat mendistribusikan program hanyalah menyertakan System.Data.SQLite.dll, tanpa perlu meng-install server SQL di komputer klien.

SQLite, mesin SQL yang kecil dan cepat

Tuesday, May 29th, 2007 by Agro Rachmatullah

Waktu dulu aku mengambil mata kuliah basis data, aku menginstall server SQL kelas berat yaitu MySQL. Padahal, yang dulu ingin kulakukan hanyalah mengenal dan bermain-main dengan perintah SQL.

Berkas zip MySQL 3 yang waktu itu kusalin dari teman ukurannya sekitar 12 MB. Installer Windows MySQL 5 “Essential” ukurannya sekitar 22 MB. Adakah alternatifnya?

Mari berkenalan dengan SQLite, sebuah mesin SQL yang kecil dan cepat. Program dengan lisensi public domain ini sudah mencapai versi 3 saat artikel ini ditulis. Pada dasarnya, SQLite adalah pustaka bahasa C untuk dilink oleh program yang membutuhkannya (sqlite3.dll untuk Windows dan sqlite-3.x.x.so untuk Linux). Tersedia juga binding untuk banyak bahasa lain (misalnya System.Data.SQLite.dll untuk .NET). Contoh program yang menggunakan SQLite adalah Firefox 3 untuk basis data bookmarknya dan Banshee (pemutar musik C#) untuk basis data lagunya. Jadi dia bukanlah program server yang berjalan sendiri dan menunggu koneksi dari program lain sebagaimana MySQL.

Seluruh database (definisi, tabel, indeks, dan data) pada SQLite disimpan dalam satu berkas. Berkas ini cross platform.

Tapi kembali ke permasalahan semula. Kita ingin bermain-main dengan perintah SQL, bukannya membuat program yang menggunakan basis data. Untuk keperluan ini, di halaman download SQLite disediakan program konsol yang bisa membuat dan membaca berkas basis data SQLite. Program konsol itu sendiri merupakan contoh program yang memanfaatkan pustaka SQLite (tapi pada program ini SQLitenya dicompile bersama, tidak berada di file pustaka terpisah). Ukurannya sangat kecil, misalnya sqlite3-3.3.17.bin.gz untuk Linux berukuran 173.46 KiB dan sqlite-3_3_17.zip berukuran 174.64 KiB!

Tutorial Program Konsol SQLite

PS: Diasumsikan pembaca sudah mengerti perintah-perintah SQL dasar sehingga tidak ada penjelasan panjang lebar tentangnya. Walaupun begitu, mungkin artikel ini juga bisa dimanfaatkan sebagai tutorial kotor tentang perintah SQL.

Programnya dijalankan dengan memberikan satu argumen berupa nama berkas basis data yang diinginkan. Jika berkasnya tidak ada, maka berkas baru akan dibuat. Ekstensi berkasnya bisa sembarang. Kita akan menggunakan db3 untuk menandakan bahwa itu adalah berkas database yang dibuat SQLite versi 3. Contohnya adalah:

$ sqlite3 test.db3

(Untuk pengguna Linux, ganti nama sqlite3-3.3.17.bin atau buat symbolic link seperlunya)

Setelah mengetikkan perintah tersebut kita akan dibawa ke konsol SQL!

SQLite version 3.3.17
Enter ".help" for instructions
sqlite>

Untuk melihat tabel-tabel yang ada pada basis data yang sedang digunakan, masukkan perintah .table:

sqlite> .table
sqlite>

Perintah yang diawali titik (seperti .table) adalah perintah khusus program konsol ini. Tentu saja, kalau basis datanya baru dibuat tidak akan ada tabel apa-apa.

Kita bisa membuat tabel baru dengan perintah SQL CREATE, misalnya:

sqlite> CREATE TABLE mahasiswa(
   ...> nim INTEGER PRIMARY KEY,
   ...> nama TEXT,
   ...> prodi CHAR(2));
sqlite> .table
mahasiswa
sqlite>

Perintah untuk membuatnya adalah “CREATE TABLE mahasiswa(nim INTEGER PRIMARY KEY, nama TEXT, prodi CHAR(2));“. Walaupun begitu, pada contoh penulisan perintahnya dipecah menjadi 3 baris. Perintah SQL diakhiri dengan titik koma, jadi selama kita belum menuliskan titik koma program tersebut masih menunggu input di baris berikutnya (ditandai dengan prompt...>“). Dengan perintah .table, bisa dilihat bahwa tabelnya memang sudah tercipta.

Berikutnya adalah memasukkan data pada tabel tersebut dengan perintah SQL INSERT dan menampilkan isi tabel dengan perintah SQL SELECT:

sqlite> INSERT INTO mahasiswa(nama, prodi) VALUES('Linus Torvalds', 'IK');
sqlite> INSERT INTO mahasiswa(nama, prodi) VALUES('Richard Stallman', 'FI');
sqlite> INSERT INTO mahasiswa VALUES(9374, 'Agro', 'IK');
sqlite> INSERT INTO mahasiswa VALUES(9374, 'Wijaya', 'IK');
SQL error: PRIMARY KEY must be unique
sqlite> INSERT INTO mahasiswa(nama, prodi) VALUES('Ace Ventura', 'KH');
sqlite> SELECT * FROM mahasiswa;
1|Linus Torvalds|IK
2|Richard Stallman|FI
9374|Agro|IK
9375|Ace Ventura|KH
sqlite>

Bisa dilihat bahwa kalau kunci primer nim tidak ditentukan, maka nilainya akan ditentukan secara otomatis dimulai dari 1. Terlihat jelas juga bahwa tidak mungkin memasukkan dua baris dengan kunci primer yang sama.

Contoh perintah SELECT lain yang hanya menampilkan mahasiswa ilmu komputer (IK):

sqlite> SELECT nama,nim FROM mahasiswa WHERE prodi='IK';
Linus Torvalds|1
Agro|9374
sqlite>

Karena Richard Stallman ingin pindah dari prodi filsafat (FI) ke ilmu komputer, mari kita bantu dia dengan perintah SQL UPDATE:

sqlite> UPDATE mahasiswa SET prodi='IK' WHERE nim=2;
sqlite> SELECT * FROM mahasiswa;
1|Linus Torvalds|IK
2|Richard Stallman|IK
9374|Agro|IK
9375|Ace Ventura|KH
sqlite>

Sayangnya di ilmu komputer ada aturan bahwa rambut tidak boleh gondrong. Richard Stallman, orang yang keras kepala, lebih memilih dikeluarkan daripada harus mencukur rambutnya. Terpaksa perintah SQL DELETE dipakai:

sqlite> DELETE FROM mahasiswa WHERE nim=2;
sqlite> SELECT * FROM mahasiswa;
1|Linus Torvalds|IK
9374|Agro|IK
9375|Ace Ventura|KH
sqlite>

PS: Rambut Agro belum cukup gondrong untuk ditindak.

Dan terakhir, karena mahasiswanya tidak ada yang mampu membayar kuliah (terlalu mahal!), jadinya tidak ada yang membayar kuliah. Universitasnya pun bangkrut sehingga tabel mahasiswa tidak ada gunanya lagi. Perintah SQL DROP digunakan untuk menghapus tabel:

sqlite> DROP TABLE mahasiswa;
sqlite> .table
sqlite>

Untuk keluar dari program, gunakan perintah .q, .quit, atau .exit. Bisa dicek bahwa berkas test.db3 (atau nama lain yang dipilih) telah tercipta.

Bagaimana, keren kan? Setelah mengetahui tentang SQLite, kamu bisa merekomendasikan program ini pada teman-temanmu yang mengambil basis data.

Untuk tutorial mengenai hal-hal yang lebih kompleks (misal trigger), kunjungi tutorial di freshmeat. Untuk daftar perintah-perintah SQL yang didukung SQLite, kunjungi halaman di situs resminya. Ada benchmark (agak kuno) untuk melihat bahwa SQLite tidaklah lambat. Untuk penggunaan SQLite pada .NET (C#), mungkin kapan-kapan aku bakal bikin tutorialnya :)…

I knew it! Files are living things! They have genes!!!

Saturday, May 26th, 2007 by Agro Rachmatullah

The problematic file is freetest.htm. I have identified that it has an NS_ERROR_XPC_NOT_ENOUGH_ARGS gene. With that gene, you cannot do any AJAX from the file on certain environments…

No, I’m not on a crack… Listen to my detailed account, all you Javascript developers… That defective gene might be on YOUR file.

After learning how to use AJAX on a dummy page, I coded the real thing on freetest.htm, the real page. Like most Javascript programming, sure enough it only works on one browser. The lucky one is Opera 9 this time. The suckers are Firefox 2 and IE 6.

Browser programmers are ultra-smart guys, I assume the mistake is on my part. OK, so I copied the AJAX code to a dummy, clean, HTML page to find the bug. However it works!

Ah, so it must be some arcane interaction between the previously-existing Javascript code and the newly-added AJAX code. But my AJAX code is pretty complicated. Therefore I tried adding the simplest possible AJAX action in my real page, trying to see whether a simple AJAX works at all. The simple AJAX creates an XMLHttpRequest, sends a request, and retrieves the response. This time it works in Opera 9 and IE 5. Firefox (using Firebug debugger) gives this error:

uncaught exception: [Exception... "Not enough arguments"
nsresult: "0x80570001 (NS_ERROR_XPC_NOT_ENOUGH_ARGS)"
location: "JS frame :: http://localhost/aspx/freetest.htm ::
doAjax :: line 26" data: no]

It’s time to hunt which other js file conflicts with this one. I deleted the reference to other js files one by one, until there is no Javascript code other then the AJAX itself! But still AJAX doesn’t work!

Lol now that’s funny. OK, so I tried modifying my real file further (I’ve backed it up), deleting more useless things like CSS and title, until it matched another dummy file (freetest-simpleajax.htm) with the same AJAX code down to every character. Browsers are weird, so there is still the slight possibility that the TITLE tag messes things up. However it still doesn’t work while AJAX works on the other dummy file!

Obligatory md5 result:

1ab3bdf1ab23aabd6cfa4b1210bc7ee2 *freetest.htm
1ab3bdf1ab23aabd6cfa4b1210bc7ee2 *freetest-simpleajax.htm

(since the content of the files are identical, the genes must be stored somewhere else such as in the NTFS Master File Table)

Lol… I tried using the save as command to save freetest.htm into freetestxxx.htm. That’s probably the equivalent of reproduction. Amusingly, freetestxxx.htm works fine. Did the defective gene not get passed?

Ah, I forgot a very basic thing! Phenotype (visible traits, like the body height of an ape and an HTML page throwing exception) comes from the intricate interaction between genotype and the environment! Basic Biology… Let’s try opening freetest.htm on another tab of the still-running firefox.exe instance…

Result…

It works!

So, it must be the environment. The other tab must be too humid or something for freetest.htm to do AJAX. It’s not a problem of cache (the tab loading an old, nonworking version of the file). I tried modifying freetest.htm by adding visible text and reloading it on both tabs. The text appears on both, signifying that both tabs opened the most recent version of the file. However AJAX still doesn’t work on that cursed tab…

Whatever… I still haven’t achieved what I wanted, making the real AJAX code work on the real page… Back to work…

Edit: The culprit is the function named parent. Renamed it to domParent. What’s weird is that after the exception occurs, the tab will be unable to do AJAX on that page even after the problem has been corrected (hence the story above).

Edit 2: It doesn’t work in IE! The ringleader is different this time… In IE 6, there is no XMLHttpRequest required for AJAX, but we can achieve the same thing by creating an ActiveXObject as shown:

var foo = new ActiveXObject('Msxml2.XMLHTTP');

However, it turns out that the variable foo won’t behave completely like a real Javascript object! It fails when we try to dynamically add a property, such as:

foo.bar = 'This thing normally works';

My code adds an id for every XMLHttpRequest object created, so it fails miserably in IE 6… Geesh, I now have to code a different way of tracking those requests…

Using the prefix -an to make an informal verb from a noun

Saturday, May 12th, 2007 by Agro Rachmatullah

In Bahasa Indonesia, the prefix -an is a very powerful grammatical construct. Here I will discuss one of its uses, to make an informal verb from a noun.

Given a noun, by attaching -an to its end we can create a verb which means “to do something with the noun”. An example noun is Internet. Using the -an prefix, we can make internetan which means “to access the Internet”:

Aku mau internetan di perpus.
I’m going to access the Internet in the library.

Note that it is colloquial, so you shouldn’t use it in formal writing. Here are more examples:

sepeda (bicycle) -> sepedaan (to ride bicycle)
Dia lagi sepedaan di lapangan.
He’s riding bike at the field.

pacar (girlfriend/boyfriend) -> pacaran (to date someone)
Anto lagi pacaran.
Anto is out on a date.

PS (Playstation) -> PS-an (to play the Playstation)
Belajar! Jangan PS-an terus!
Study! Don’t play Playstation all the time!

Sikat ((tooth)brush) -> sikatan (to brush the teeth)
Udah sikatan?
Have you brushed your teeth?

The hard part is that you can’t just slap it to any noun. It might be correct gramatically but nobody use it so it will sound weird. For example, TV-an (supposedly “to watch TV”) is never used. So are “rokokan” (supposedly “to smoke”), “kursian” (supposedly “to sit”), and “sapuan” (supposedly “to sweep”). I don’t think there is an easy rule to sort the nouns. You just have to figure it out by immersing yourself in the language.

Kenapa aku (dulu) tidak mau jadi dokter

Saturday, May 5th, 2007 by Agro Rachmatullah

Cerebellum highlighted in blue

Aku barusan ngeliat (sebagian) One Litre of Tears episode 1 yang ditayangin Indosiar. Tahu kan? Ini drama menyentuh yang diangkat dari buku harian Kitou Aya, pasien Spinocerebellar ataxia (SCA). Pernah dijiplak Indonesia jadi Buku Harian Nayla (jiplak, bukan adaptasi, wong sama sekali tidak mengakui sumber cerita aslinya).

Aku sebelumnya udah pernah namatin drama yang dibintangi Sawajiri Erika ini. Minjem CD-nya adikku, suara asli Jepang dengan fansub Inggris. Tadi nonton soalnya penasaran aja, seperti apa versi dubbing-nya. (nggak berencana nonton lanjutannya, harus ngerjain TA dan nggak mau numpahin liter ke-2)

Secara umum dub-nya OK lah. Tapi aku cukup kaget dengan penyebaran informasi yang salah di beberapa menit pertama. Versi Indosiar menyebutkan bahwa pengidap penyakit ini akan “susah menggerakkan anggota tubuh, susah berbicara, dan mengalami gangguan berpikir” (kira-kira, nggak kurekam soalnya). Lalu belakangan disebutkan bahwa perlahan-lahan pengidap juga akan mengalami “…hilang ingatan” (kira-kira juga).

Aku bukan dokter, tapi dari yang kubaca di Wikipedia:

Generally, a sufferer retains full mental capacity but may progressively lose physical control.

Kata Wikipedia, mental (termasuk kemampuan bepikir dan ingatan) tidak terganggu, hanya saja perlahan-lahan kendali fisik bisa hilang (kesulitan berbicara, menggerakkan tangan, dll). Jadi, skor akurasi teknis -1 buat Indosiar. Seingatku, terjemahan fansub yang kutonton juga tidak menyinggung-nyinggung tentang gangguan pada fungsi mental. Pingin denger dialog Jepang aslinya tapi CD-nya lagi nggak di sini.

SCA adalah penyakit yang belum bisa disembuhkan. Selain 1 Litre of Tears, aku juga pernah nonton/baca beberapa cerita lain tentang penyakit-penyakit yang tak bisa disembuhkan. Film A Beautiful Mind diangkat dari kisah nyata John Nash, matematikawan penerima Nobel Ekonomi yang terkena Schizophrenia (ada adegan Igo-nya!!!). Film The Notebook merupakan adopsi dari novel dengan judul yang sama, kali ini tentang Alzheimer. Ada juga game novel interaktif yang mengangkat gagal ginjal kronis.

Di cerita-cerita tersebut, kita diajak menangis melihat betapa tidak berdayanya manusia. Ini abad 21 dengan segala kejayaannya seperti pembuktian Teorema Terakhir Fermat, disket holografik 3.9 TB, dan teleportasi kuantum. Tapi kita masih hidup dihantui berbagai penyakit yang belum ada obatnya. Di manakah sirup sakti Doraemon yang sekali teguk bisa menyembuhkan semua macam penyakit?

OK, kembali ke… uhm… inti dari postingan ini. (aku nggak punya laptop)

Apa cita-cita pertamaku? Jadi dokter kandungan. Ya, benar. Kok bisa? Karena saat ibuku bertanya “Agro besar mau jadi apa?”, aku diajarkan jawaban “dokter kandungan”. Omonganku waktu itu masih belum sempurna, jadi mungkin yang kuucapkan semacam “o-te… andunan”.

OK, mungkin itu bukan cita-cita. Aku hanyalah bagai pensistesis suara seperti Festival. Waktu itu aku masih terlalu kecil untuk tahu apa itu “cita-cita” dan “dokter kandungan”.

Setelah aku cukup besar untuk membayangkan berbagai cita-cita, anehnya “dokter” sama sekali tidak pernah kuminati. Orang-orang banyak yang mengatakan hal-hal seperti “jadi dokter nanti kaya…”, “jadi dokter banyak duitnya…”. Mungkin itu yang membuatku anti. Bukan anti duitnya, tapi karena orang-orang HANYA menekankan duitnya, jadi seakan-akan dokter hanyalah mesin pencetak duit yang membosankan. Pasien bertanya, kita mendiagnosis dan memberi obat, orang sembuh, dan kita dapat duit. Aku milih yang lebih menyenangkan aja misalnya bikin komik (salah satu cita-citaku zaman SD dulu).

Tapi, cerita-cerita tentang penyakit yang tak bisa disembuhkan tersebut merubah sudut pandangku tentang pekerjaan di dunia kedokteran. Sebetulnya sejak sebelumya aku tahu bahwa ada penyakit yang belum bisa disembuhkan (contoh populernya AIDS), tapi itu hanyalah pengetahuan semata yang tidak menyentuh. Di lain pihak, dengan mengenal sosok seperti Aya hati ini benar-benar sakit karena aku tidak bisa berbuat apa-apa melihat dia menderita. Ingin rasanya bisa membantu dia. Ya, aku menjadi terbuka pada alternatif di dunia kedokteran selain menjadi buruh pencetak duit yang hidup bahagia ever after. Alternatifnya adalah meneliti penyakit-penyakit ganas tersebut, mencari obat yang menjawab rintihan orang-orang yang masih menyimpan sebenih harapan. Sama-sama bertujuan menyembuhkan layaknya dokter pada umumnya, tapi yang ini jauh lebih menantang dan menarik buatku.

Ah, tapi manusia itu terbatas. Kalau kita mencoba menjadi segalanya, kita malah tidak akan jadi apa-apa. Aku nggak berencana pindah ke kedokteran, tapi paling tidak aku sekarang lebih mengapresiasi dunia tersebut. Toh perkembangan di satu bidang ilmu akan mempengaruhi bidang lainnya kan? Laser, mainan para fisikawan, kini jadi alat penting di dunia kedokteran. Proyek komputasi terdistribusi Folding@home membantu usaha pencarian obat kanker. Jadi aku bisa sedikit puas, karena berada di dunia MIPA yang cukup dekat dengan bidang kedokteran.

強く前へ。。。

Recording karaoke using Audacity

Tuesday, April 10th, 2007 by Agro Rachmatullah

Audacity is a free (open source) audio recording application. It is multiplatform, with versions for Windows, Linux, and OS X. By default it outputs the final audio in ogg/vorbis, but mp3 support can be added quite easily.

In this article I’ll guide you how to record a karaoke using Audacity. What it means is that you have an instrumental (music-only) version of a song and you want to add your (horrible) sound to it.

First of all you need to have the instrumental version of the song itself. In the Japanese music scene, singles are released in CD which also includes its instrumental version so download go buy that CD and rip the audio. Audacity supports wav, mp3, ogg, and some other formats as its input.

After that download the program and install it. For this guide I’m using version 1.2.6 for Windows. The first screen should look like this:

Audacity initial screen

Now make sure your mike is plugged to the right place and the correct stream (e.g., “Mic”) is selected in the input drop down. Press the record (red circle) button and mumble some words. You’ll see a new audio track created. Press the stop (yellow square) button and try to play back by pressing the play (green arrow) button.

Audacity audio track

In the top left of every audio track, there is a small “x” button (pictured above). You can click it to delete the track. If you think the recorded volume is too loud or small, delete your first audio track, adjust the volume (the slider with a mic icon), and try another recording. When you are satisfied with the volume, you can go to the next step.

Load the instrumental version of the song from “File”->”Open…”. After the importing process is done you will see the the audio tracks. Before you start recording though, you need to make sure that Audacity plays those tracks while recording. This step is probably the most important but nonobvious. Go to “Edit”->”Preferences…”, open “Audio I/O” tab, and select “Play other tracks while recording new one” (see below).

Audacity preferences

After that you can go to the real fun. Press the record button and sing until the song ends. Your voice will be kept in a new track so if you’re not satisfied just delete the track and record again. To finish, select “File”->”Export As Ogg Vorbis…” and the resulting file can be played in any sane media player (such as VLC or Windows Media Player after installing the codecs).

Below are some stuffs which you probably want to do…

Changing pitch

If you can’t hit some note because it’s too low or high, you might want to change the pitch of the musical instruments before recording your sound. To do it, press CTRL+A (select all) and go to “Effect”->”Change Pitch…”. For example, to lower it you might select from “F” “down” to “E”. Note that the instruments will have a lower quality and sound unnatural if you do this.

MP3 export

OGG Vorbis is a free format while MP3 is proprietary so you should prefer OGG Vorbis when possible. In cases where using MP3 is a must (such as to play on MP3 players) the supports can be easily enabled.

First download LAME MP3 encoder for your operating system. Then extract the compressed file somewhere. After that go to “Edit”->”Preferences…” and open the “File Formats” tab. Press “Find Library” and browse for the requested file (e.g., lame_enc.dll for Windows). With that, you can export to MP3 from “File”->”Export As MP3…”.

Closing

I won’t give an example exported file here. Just have fun, but remember to respect your friend’s ears.

Japanese kanji handwriting recognition in Windows XP’s IME

Saturday, March 31st, 2007 by Agro Rachmatullah

Did you know that in Windows XP’s IME we can input a kanji by drawing it? (Does Ubuntu, and Linux in general, have it?) I will outlay the steps here.

Obviously you need to have the IME installed. See this Wikibook page. For illustration, we’ll use Notepad. So fire up Notepad, switch the IME on, and input any character on the keyboard. I use ‘a’, which the IME will convert to hiragana ‘あ’ on the fly:

あ on Notepad

The magic key is ‘F5′, which will launch the IME pad. Press it and you’ll get this:

IME pad welcome dialog

Press “OK” and you’ll get this:

IME pad

On the screen pictured above, you can find a kanji by its radical (部首, bushu). However that’s not what we’re interested in right now. To input by drawing, click the top-leftmost button (circled red). You’ll get this:

IME handwriting pad

Here’s the explanation for the UI elements:

  1. This is the drawing area. You draw the strokes here by holding the left mouse button and dragging.
  2. Matching shapes (and not-so-matching shapes) you draw in (1) will be listed here. If you’ve found the kanji you want, just click it.
  3. 戻す (modosu) means “to return”. Click this to undo the last stroke.
  4. 消去 (shoukyo) means “erasing”. Click this to clear the drawing area.

One thing to note is that stroke order matters! Try to draw a perfectly matching shape but with a random stroke order, and chances are the program will not give the kanji you want.

The power of this tool cannot be underestimated. For one thing, it allows you to quickly find a printed character you see. Suppose you went to a mini market and see a notice written in Japanese (for example, in Circle K Terban, Yogyakarta). If there is an unknown kanji there, you won’t have any information other than its shape. Finding the kanji through the method explained above will be very easy. After you have the digital form of the character, you can find its readings, compounds, and meanings in electronic dictionaries.

Second, you can use it to input rare kanji easily. Suppose for some insane reason you want to write “koe” (sound) using the rare kanji 聲 instead of the normal 声 (see for example “Endless Rain” by X Japan). You know its sound (no pun intended), but you can’t find it by typing in the IME because that kanji is archaic (even EDICT don’t list it). However, by drawing it you can find the kanji.

The third is for writing names. When IME don’t recognize a name, you can input it by drawing character per character.