Sindikasi

Setelah lama tak ditengok, ternyata tempat saya naro RSS feeds tuk blog ini tak bisa diakses πŸ˜€ dann ternyata itu gara2 lupa ngubah konfigurasi Apache saat dulu upgrade dari versi 2.2 ke 2.4 (doh)!

Satu hal yang berubah di Apache 2.4 itu adalah cara ngasih izin akses ke sebuah direktori. Kalau sebelumnya make yang berikut

Order allow,deny
allow from all

Apache versi lebih baru berubah menjadi seperti yang berikut ini

Require all granted

Kirain semua udah diubah saat dulu upgrade, ternyata ada yang ketinggalan T_T

JSON prettifier

Once in a while I need to prettify a JSON document (read: add indentations and new lines) to make it (more) readable. Usually what I will do is finding an online prettifier and copy-paste the JSON onto there. What I usually don’t realize is that I already have that tool in my toolbox! I figured this out from a post somewhere on the net, sorry I don’t remember exactly where.

If you have Python installed, that means you already have a tool that can make a JSON document pretty. Just use it as the following.

$ python -m json.tool document.json

Or if you are an stdin fan, it can also read from there.

$ python -m json.tool < document.json

There you have it!

Blokir Website dengan iptables

Ceritanya saya sedang browsing sana sini pake tablet pc. Tiba2.. si halaman web yang mestinya tampil biasa saja kalo dibuka lewat komputer biasa, skr berubah jadi ala majalah. Selidik sana selidik sini, itu ternyata gara2 si onswipe dot com.

Si tablet mestinya cukup mampu tuk menampilkan halaman web tsb apa adanya berhubung layarnya cukup luas. Tapi entah mengapa si pemilik website bekerja sama dg layanan tersebut yang malah membuat membaca menjadi tidak nyaman.

Akhirnya saya putuskan saja tuk menutup akses ke si layanan langsung di router berhubung si tablet pc gak bisa dioprek2 tuk beginian. Router yang saya pakai memakai dd-wrt yang memiliki fasilitas untuk menutup akses ke website yang kita atur. Cara mengaturnya terlihat mudah tapi entah mengapa ngga berhasil saya pakai. Kalau saya lihat, tabel iptables tidak berubah sama sekali.

Setelah mencari kesana kemari, akhirnya saya temukan juga cara memasukan isian iptables secara manual tuk kepentingan memblokir akses. Berikut inilah perintahnya..

# iptables -A FORWARD  -p tcp -m tcp -m webstr --host "onswipe.com<&nbsp;>" -j REJECT --reject-with tcp-reset

boom! akses ke layanan mengesalkan itu pun terblokir.

Mengelompokkan barisan nilai

*Sepertinya judul tulisan ini aga2 tidak menjelaskan xD*

Intinya begini. Saya punya sebuah barisan nilai, katakanlah seperti di bawah ini

nilai = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

Nah saya ingin membuat kelompok untuk setiap 2 buah nilai berurutan. Barisan di atas ingin saya ubah menjadi seperti berikut.

pasangan = [(1, 2), (3, 4), (5, 6), (7, 8), (9, 10), (11, 12)]

Bagaimana cara cepatnya?Β Salah satu trik yang saya temukan (di Internet :P) adalah dengan menggunakan fungsi zip dan iter.

Fungsi zip sudah dikenal dapat dipakai untuk menggabungkan dua atau lebih barisan untuk membuat barisan kelompok dari setiap elemen yang ada (err..?). Contohnya

>>> angka = [1, 2, 3]
>>> tulisan = ["satu", "dua", "tiga"]
>>> zip(angka, tulisan)
[(1, 'satu'), (2, 'dua'), (3, 'tiga')]

Nah yang saya mau adalah saya ingin membuat kelompok dari setiap dua elemen berurutan. Untuk ini, fungsi iter dapat kita salahgunakan πŸ˜€ Mari kembali ke contoh awal.

>>> nilai = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
>>> iter_nilai = iter(nilai)
>>> zip(iter_nilai, iter_nilai)
[(1, 2), (3, 4), (5, 6), (7, 8), (9, 10), (11, 12)]

Hore jadi πŸ˜€

Apa yang terjadi di belakang layar? Setelah baca2 source code fungsi zip (Python 2.7.5), setiap barisan yang dimasukkan ke dalam fungsi zip akan dijadikan iterator dan nilainya akan diambil satu persatu sampai salah satu barisan tidak dapat mengeluarkan elemen berikutnya. Andaikan parameter yang dimasukkan sudah berupa iterator, saya asumsikan Python tidak akan membuat iterator baru. Nah berhubung parameter yang dimasukkan berasal dari iterator yang sama, maka nilai akan disebar selang-seling ke kelompok/tuple yang dihasilkan.

Bagaimana cara membuat kelompok dari setiap 3 bilangan berurutan? Tambahkan lagi saja parameter si zip!

>>> nilai = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
>>> iter_nilai = iter(nilai)
>>> zip(iter_nilai, iter_nilai, iter_nilai)
[(1, 2, 3), (4, 5, 6), (7, 8, 9), (10, 11, 12)]

Himpunan unik di Python

Sebelum ini, saya sempat menulis tentang cara membuat fungsi pembanding sendiri untuk keperluan pembuatan himpunan unik. Singkatnya, di bahasa Java, Scala, dan mungkin bahasa lain yang jalan di atas JVM, kita perlu mengimplementasikan ulang method hashCode dan equals. Setelah menulis itu, saya sempat berpikir bagaimana cara melakukannya di Python?

Yang ingin saya lakukan adalah jika saya memiliki beberapa objek penampung nilai, saya ingin membuat mereka unik (katakanlah dengan memasukkannya ke dalam set). Jadi jika ada lebih dari satu objek yang bernilai sama, hanya satu di antara mereka saja yang diambil. Sisanya bisa dibuang karena saya tidak memerlukannya.

Katakanlah saya memiliki kelas seperti berikut.

class M(object):
    def __init__(self, posisi, asam_amino):
        self.posisi = posisi
        self.asam_amino = asam_amino

    def __repr__(self):
        return "%s%s" % (self.posisi, self.asam_amino)

Lalu saya membuat beberapa objek dari kelas tersebut.

mutasi = [ M(1, "a"), M(2, "b"), M(1, "c"), M(3, "b"), M(1, "a") ]

Mari kita coba panggil fungsi set

>>> print mutasi
[1a, 2b, 1c, 3b, 1a]
>>> print set(mutasi)
set([3b, 1c, 1a, 1a, 2b])

Seperti yang sudah diduga, fungsi set belum berhasil menghapus nilai ganda.

Setelah ngubek2 sana sini, ternyata di Python kita juga harus mengimplementasikan dua buah method yang sama (versi Python tentunya)! Kedua method tersebut adalah __eq__ dan __hash__. Kedua method ini dapat diimplementasikan ulang seperti berikut.

    def __eq__(self, o):
        if not isinstance(o, M):
            return False
        return self.posisi == o.posisi \
               and self.asam_amino == o.asam_amino

    def __hash__(self):
        return hash((self.posisi, self.asam_amino))

Mari kita coba lagi sekarang.

>>> mutasi = [ M(1, "a"), M(2, "b"), M(1, "c"), M(3, "b"), M(1, "a") ]
>>> print mutasi
[1a, 2b, 1c, 3b, 1a]
>>> print set(mutasi)
set([1c, 1a, 2b, 3b])

Klopt!

Kode lengkap dapat dilihat di https://gist.github.com/fajran/5744836

Himpunan unik di Scala

Katakanlah saya memiliki sebuah List dari angka seperti berikut

val list = List(1, 2, 3, 4, 2, 3, 4)

Jika saya ingin membuatnya tidak berisi angka berulang, saya bisa panggil method distinct dari List tersebut.

scala> val list = List(1, 2, 3, 4, 2, 3, 4)
list: List[Int] = List(1, 2, 3, 4, 2, 3, 4)

scala> list.distinct
res1: List[Int] = List(1, 2, 3, 4)

Nah bagaimana jika isi List adalah objek dari kelas buatan sendiri?

Pertama, mari kita coba gunakan case class. Katakanlah saya butuh menyimpan dua buah nilai yaitu posisi: Int dan asamAmino: String yang menyatakan sebuah mutasi gen seperti berikut.

case class M1(val posisi: Int, val asamAmino: String)

Mari kita uji apakah distinct bisa bekerja sesuai harapan.

scala> case class M1(val posisi: Int, val asamAmino: String)
defined class M1

scala> val list = List(M1(1, "a"), M1(2, "b"), M1(1, "c"), M1(3, "b"), M1(1, "a"))
list: List[M1] = List(M1(1,a), M1(2,b), M1(1,c), M1(3,b), M1(1,a))

scala> list.distinct
res2: List[M1] = List(M1(1,a), M1(2,b), M1(1,c), M1(3,b))

Terlihat masih oke.. Bagaimana kalau pakai class biasa?

scala> class M2(val posisi: Int, val asamAmino: String) {
     | override def toString() = "%d%s".format(posisi, asamAmino)
     | }
defined class M2

scala> val list = List(new M2(1, "a"), new M2(2, "b"), new M2(1, "c"), new M2(3, "b"), new M2(1, "a"))
list: List[M2] = List(1a, 2b, 1c, 3b, 1a)

scala> list.distinct
res3: List[M2] = List(1a, 2b, 1c, 3b, 1a)

Wah tidak bekerja sesuai harapan ternyata πŸ™ Mutasi 1a masih berjumlah ganda. Mungkin karena si Scala atau Java tidak tahu cara mengecek dengan benar apakah dua buah objek M2 itu bernilai sama atau tidak. Kalau yang dibandingkan hanyalah alamat memori, tentu saja akan berbeda semua.

Setelah ngubek2 internet, akhirnya saya mendapatkan sebuah petunjuk di StackOverflow.com. Pada saat pengecekan kesamaan nilai, Scala menggunakan dua buah method untuk mencari tahu apakah dua buah objek bernilai sama atau tidak. Dua method tersebut adalah hashCode dan equals. Nilai hashCode akan dibandingkan terlebih dahulu dan jika sama, maka method equals akan dipanggil agar si objek membandingkan sendiri dengan objek lain apakah mereka bernilai sama atau tidak.

Berbekal dari informasi tersebut, kita bisa ubah si kelas M2 menjadi seperti berikut.

class M3(val posisi: Int, val asamAmino: String) {
  override def toString() = "%d%s".format(posisi, asamAmino)

  override def hashCode = posisi

  override def equals(other: Any) =
    if (other.isInstanceOf[M3]) {
      val m = other.asInstanceOf[M3]
      m.posisi == posisi && m.asamAmino == asamAmino
    } else false
}

Untuk hashCode, agar sederhana saya samakan saja nilainya dengan nilai posisi. Pada saat pemangilan equals, nilai posisi dan asamAmino akan dibandingkan untuk memutuskan apakah dua buah mutasi bernilai sama atau tidak.

Mari kita coba lagi..

scala> val list = List(new M3(1, "a"), new M3(2, "b"), new M3(1, "c"), new M3(3, "b"), new M3(1, "a"))
list: List[M3] = List(1a, 2b, 1c, 3b, 1a)

scala> list.distinct
res0: List[M3] = List(1a, 2b, 1c, 3b)

Hore berhasil!

Mengapa saya ngga memakai case class saja sehingga tidak perlu repot2 mengimplementasikan hashCode dan equals? Karena dalam kasus yang saya hadapi, kelas mutasi ini berada dalam wilayah bahasa Java! Yap, saya sedang mencampur2 kode Java dan Scala.

Mari kita ubah si kelas mutasi menjadi bahasa Java lalu digunakan dari Scala.

public class M4 {
  private int posisi;
  private String asamAmino;

  public M4(int posisi, String asamAmino) {
    this.posisi = posisi;
    this.asamAmino = asamAmino;
  }

  public int getPosisi() {
    return posisi;
  }

  public String getAsamAmino() {
    return asamAmino;
  }

  @Override
  public int hashCode() {
    return posisi;
  }

  @Override
  public boolean equals(Object other) {
    if (other instanceof M4) {
      M4 m = (M4)other;
      return posisi == m.getPosisi() && asamAmino.equals(m.getAsamAmino());
    }
    return false;
  }

  @Override
  public String toString() {
    return posisi + asamAmino;
  }
}

Wah kodenya jadi bengkak ya? πŸ˜€ Silakan lihat kode lengkap dapat dilihat di https://gist.github.com/fajran/5718827

Log of Debian/Ubuntu packages

I have a plan to do a little research about packages in Debian and/or Ubuntu repositories. For this, I think I need a preferably complete log of packages that coming in and out of the repositories.

A friend of mine pointed me the following two mailing list archives where Debian and Ubuntu seem to be logging the packages.

If somebody knows the other sources, or if the above sources are unsuitable for the purpose I am looking for, please let me know πŸ™‚

Alur aplikasi OpenGL (dan WebGL?)

Aplikasi OpenGL (dan sepertinya aplikasi berbasis grafis lainnya) memiliki sebuah alur kerja yang bisa saya bilang cukup standar. Dimulai dengan melakukan persiapan, lalu ada sebuah perulangan utama, dan diakhiri dengan rutin bersih-bersih sebelum aplikasi selesai dieksekusi. Pada perulangan utama ini, operasi yang terjadi secara umum bisa dikelompokkan menjadi tiga: baca input (mouse, keyboard, dll), proses, dan gambar.

Main Loop

Pada tahapan membaca input, seluruh masukan dari keyboard, mouse, dan sumber lainnya akan ditangkap dan digunakan untuk mengubah kondisi yang sedang dipantau. Misalnya jika tombol spasi ditekan, maka si aplikasi harus membuat pesawat dalam game mengeluarkan tembakan.

Setelah ini, semua pemrosesan akan dilakukan. Misalnya peluru yang ditembakkan mesti sampai di pojok kanan atas layar dalam waktu 1 detik. Maka perlu dihitung dimana dan kapan saja gambar peluru harus diletakkan di layar.

Pada tahapan menggambar, gambar peluru yang telah dibaca dari berkas akan disalin ke layar. Gambar akan diletakkan pada posisi yang telah dihitung sebelumnya. Begitu pula untuk objek-objek lain yang perlu digambar di layar.

Seberapa cepat perulangan utama yang menjalankan 3 tahapan di atas ini harus dijalankan? Dengan kata lain, berapa gambar yang harus dibuat setiap detiknya? Semakin banyak gambar yang dibuat setiap detiknya, akan semakin halus pergerakan animasi yang dibuat. Namun dengan demikian, proses yang dikerjakan tidak boleh berlangsung terlalu lama karena tentunya dapat menunda tahapan menggambar yang efeknya akan mengurangi jumlah gambar yang dibuat tiap detiknya.

Monitor yang ada sekarang umumnya dapat menggambar 60 kali setiap detiknya (60 frame per second atau 60 Hz). Bagaimana kalau kita targetkan agar aplikasi dapat mengikuti kecepatan monitor? Mari kita hitung. Jika dalam 1 detik kita harus menggambar 60 gambar, berarti 1 gambar harus dibuat dalam waktu 1/60 detik atau sekitar 16 milidetik (16 ms)! Membaca input, melakukan pemrosesan data, dan menggambar semuanya harus terjadi dalam waktu 16ms saja agar kita bisa meraih kecepatan menggambar 60 gambar per detik!

Apakah 60 fps adalah angka yang harus selalu dicapai? Tergantung.. semakin cepat, animasi akan semakin halus. Namun jika aplikasi yang kita buat tidak sering menampilkan aplikasi, maka batasan kecepatan penggambaran ini bisa kita perlonggar. Tuk perbandingan, film umumnya hanya memiliki 24 gambar setiap detiknya alias 24 fps.