29/12/09

apt-web

Saat ini apt-web biasa diakses melalui sebuah URL panjang yaitu http://labs.fajran.web.id/p/apt-web/. Untuk memudahkan mengingat alamat apt-web ini, saya telah memindahkannya ke tempat baru, yaitu..

apt-web.dahsy.at

Jadi, silakan perbarui bookmark Anda! =D

23/12/09

Perkalian matrix

.. dalam satu baris! euh, maksudnya 1 statement.

hasil = map(lambda index:
      sum(
        map(lambda n: n[0] * n[1],
          zip(
            [a[i * 4 + (index % 4)] for i in range(4)],  # baris
            [b[(index / 4) * 4 + i] for i in range(4)]   # kolom
          )   # pasangan elemen baris dan kolom
        )   # kalikan setiap pasangan
      ),  # jumlahkan
    range(4*4))

Input adalah dua buah matrix berukuran 4 × 4, yaitu a dan b, dan hasilnya tentu saja matrix 4 × 4 juga yang ada di dalam variabel hasil.

Ketiga matrix ini ditulis dalam bentuk array 1 dimensi dari elemen-elemen yang ada dengan menjejerkan kolom-kolom yang ada. Sebagai contoh, matrix di bawah ini

 1   2   3   4
 5   6   7   8
 9  10  11  12
13  14  15  16

akan ditulis dalam variabel berupa [1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15, 4, 8, 12, 16].

Kalau mau dibalik (urut baris), tukar saja a dan b. Tuk perkalian matrix n x n, ganti saja 4 menjadi n tersebut.

Mohon dikoreksi kalau ada yg salah. Hasil nyoba2 membandingkan hasilnya dg hasil perhitungan dg GNU Octave sih bener.. :D

Jadi pengen latihan functional programming..

Python 32bit di Snow Leopard

Python 2.6.1 bawaan Snow Leopard ternyata secara default bekerja dalam mode 64bit. Pada beberapa kasus, hal ini bisa membawa masalah misalnya jika bekerja dengan pustaka lain yang tidak menyediakan versi 64bit. Contohnya adalah pustaka QuickTime yang digunakan oleh Pyglet.

$ python coba-pyglet.py
Traceback (most recent call last):
  ...
  File "build/bdist.macosx-10.6-universal/egg/pyglet/lib.py", line 226, in load_framework
  File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/ctypes/__init__.py", line 423, in LoadLibrary
    return self._dlltype(name)
  File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/ctypes/__init__.py", line 345, in __init__
    self._handle = _dlopen(self._name, mode)
OSError: dlopen(/System/Library/Frameworks/QuickTime.framework/QuickTime, 6): no suitable image found.  Did find:
    /System/Library/Frameworks/QuickTime.framework/QuickTime: no matching architecture in universal wrapper
    /System/Library/Frameworks/QuickTime.framework/QuickTime: no matching architecture in universal wrapper

Kalau dicek, memang pustaka tersebut tidak mengandung versi 64 bit.

$ file /System/Library/Frameworks/QuickTime.framework/QuickTime
/System/Library/Frameworks/QuickTime.framework/QuickTime: Mach-O universal binary with 2 architectures
/System/Library/Frameworks/QuickTime.framework/QuickTime (for architecture i386):   Mach-O dynamically linked shared library i386
/System/Library/Frameworks/QuickTime.framework/QuickTime (for architecture ppc7400):    Mach-O dynamically linked shared library ppc

Lalu caranya gimana? Ternyata manual python di Snow Leopard sudah memberitahukan informasi ini :D

$ export VERSIONER_PYTHON_PREFER_32_BIT=yes

Cukup mengeset environment variable seperti di atas dan jalankan Python seperti biasa. Python akan dijalankan dalam mode 32 bit dan masalah di atas pun tidak ada.

Kalau ingin diset secara default, maka jalankan perintah berikut.

$ defaults write com.apple.versioner.python Prefer-32-Bit -bool yes

Setiap Python yg dijalankan setelah ini akan secara otomatis berjalan di bawah mode 32 bit. Ganti nilai yes menjadi no untuk mematikannya alias mengembalikan agar berjalan dalam mode 64 bit secara default.

22/12/09

flickr browsr

Contoh aplikasi Kasuari yg lain: photo browser =D

Saya nyoba ngambil 800 foto di Flickr, lalu membuat kolase besar, dan menampilkannya dg Kasuari. Hasil akhir dapat dilihat di:

http://labs.fajran.web.id/p/kasuari/flickr/

Masing-masing foto berukuran 1024x860 pixel sehingga 800 foto berarti sekitar 557 megapixel. Foto-foto ini diambil dg bantuan Flickr API tuk search berdasar interestingness.

3.7 Gigapixel (v2)

Tulisan ini merupakan kelanjutan dari tulisan saya sebelumnya mengenai Kasuari, sebuah skrip untuk menampilkan gambar super besar dg teknik multi-scale pada halaman web dengan bantuan Javascript dan Canvas.

Saya baru saja menulis ulang skrip tersebut. Kali ini saya mematikan dulu fungsi pergerakan halus karena kok rasanya ngga terlalu menunjang sisi interaktivitas. Fungsi ini sebenarnya menunda pergerakan layar sehingga terlihat tidak menempel dengan pointer mouse. Karena penundaan ini, pergerakan terlihat “terlambat” dan tidak mengikuti pergerakan pointer mouse secara langsung. Penundaan ini mungkin bisa membuat pergerakan menjadi lebih “dinamis” dan tidak kaku tapi di lain pihak, pengguna bisa salah mengira kalau keterlambatan ini disebabkan oleh komputer yg lambat. Mungkin saya masih perlu bereksperimen dengan parameter2 yg ada.

Selain itu, saya juga menambahkan satu buah fitur baru, yaitu pembesaran halus. Saat mendekatkan atau menjauhkan gambar yg membuat gambar terlihat lebih besar dan kecil, transisi dilakukan secara bertahap. Dengan demikian, pengguna bisa mengikuti proses yang terjadi (yaitu pembesaran/pengecilan gambar) sehingga diharapkan pengguna tidak kehilangan konteks.

Saya juga menulis ulang aplikasi untuk mempersiapkan gambar yang akan dipakai oleh Kasuari. Awalnya aplikasi (yg saya tulis dg Python) ini hanya bisa menggunakan satu buah sumber gambar yang dijadikan gambar asli dalam resolusi penuh. Aplikasi akan memotong-motong gambar menjadi banyak gambar dengan ukuran lebih kecil (yaitu 256 × 256 piksel) dan lalu membuat gambar dalam skala (ukuran) yg lain dari gambar-gambar ini.

Kekurangan dari aplikasi ini adalah jika gambar berukuran sangat besar, bisa saja gambar disediakan dalam beberapa potongan gambar yang lebih kecil. Oleh karena itu, aplikasi harus dapat memproses beberapa gambar ini dalam menyusun gambar yang dibutuhkan oleh Kasuari.

Saya menggunakan pustaka Python Imaging Library (PIL) untuk membantu mengolah gambar. Namun ternyata PIL ini memiliki masalah jika gambar yang ditangani memiliki ukuran yang besar. PIL bekerja sangat lambat dan butuh memori sangat besar. Mungkin karena gambar yang ada perlu dimasukkan ke memori terlebih dahulu secara keseluruhan sebelum dapat diproses lebih lanjut. Berhubung proses pemotongan gambar dilakukan perbaris, seharusnya ada cara yang lebih cerdas untuk mengatasi masalah ini.

Akhirnya saya mencoba untuk menggunakan libjpeg untuk membuat aplikasi pemotong gambar. Walaupun akhirnya saya harus menulis kode dalam bahasa C, namun hasil akhirnya cukup memuaskan. Aplikasi yang saya tulis ini dapat bekerja dengan cepat dan menggunakan memori secukupnya.

Sebagai bahan uji coba, saya telah melanjutkan usaha gagal yang saya lakukan sebelumnya, yaitu mencoba menyediakan gambar berukuran 3.7 gigapixel dalam Kasuari. Gambar ini adalah peta dunia dari NASA yang memiliki resolusi 500m untuk setiap piksel yang ada. Ukuran gambar adalah 3.7 gigapixel (86400 × 43200) yang awalnya tersusun dari 8 buah gambar berukuran 21600 × 21600 piksel.

Hasil akhir dapat dilihat di http://labs.fajran.web.id/p/kasuari/bluemarble500m/ :)

Kode sumber Kasuari dan aplikasi pemotong gambar dapat dilihat di http://github.com/fajran/kasuari

17/12/09

Tempel sana tempel sini

Hasil iseng2 dg Django: Tempel http://github.com/fajran/tempel :D

Demo yang bisa dilihat dan bahkan bisa dipake ada di http://tempel.sebelah.web.id/

Bisa jadi contoh bagi yang mau belajar Python dan Django. Source code nya ngga banyak jadi mudah2an mudah dipelajari. Ada satu library tambahan yg dipake, yaitu Pygments yang dipakai untuk mewarnai source code. Tuk proyek ini sendiri, Buildout dipakai tuk mempermudah penyiapan semua library yg dipakai.

Kalau mau nyoba..

$ git clone git://github.com/fajran/tempel.git
$ cd tempel
$ easy_install -U setuptools
$ python bootstrap.py
$ ./bin/buildout
$ ./bin/django syncdb
$ ./bin/django runserver

Setelah itu buka http://localhost:8000/ di browser.

Keterangan tambahan

  • Kalau ngga bisa pake git, coba download source codenya di http://github.com/fajran/tempel/tarball/master
  • Saat menjalankan ./bin/buildout, source code Django dan Pygments akan secara otomatis di-download. Jadi pastikan nyambung dg Internet.
  • Kalau ngga mau pake Buildout, siapkan sendiri Django dan Pygments. Source code Tempel sendiri ada di dalam direktori src/

Oya, apaan sih ini? ini adalah tiruan lain lagi dari "pastebin" alias tuk nyimpen apalah.

15/12/09

Cara cepat menyediakan server Mercurial

Langsung aja ke inti masalah..

$ mkdir repo-utama
$ cd repo-utama
$ cat > .hg/hgrc <<EOF
> [web]
> allow_push = *
> push_ssl = false
> EOF
$ hg serve

Selamat! Anda telah memiliki sebuah server Mercurial! Server ini bisa diakses di http://ip-kompi-tersebut:8080/

Berhubung sangat sederhana, server ini tidak butuh otentikasi apa2 sehingga semua orang bisa melakukan push ke sana. Jadi hati-hati juga!

Mari kita salin, tambahkan isinya, dan push kembali.

$ hg clone http://localhost:8000/ salinan
$ cd salinan
$ touch ini itu
$ hg add ini itu
$ hg commit -m 'tambah ini itu'
$ hg push http://localhost:8000/

Selesai!

10/12/09

Duplikasi UUID

Menurut Wikipedia,

… the probability is about 0.00000000006 (6 × 10−11), equivalent to the odds of creating a few tens of trillions of UUIDs in a year and having one duplicate.

However, these probabilities only hold when the UUIDs are generated using sufficient entropy. Otherwise the probability of duplicates may be significantly higher, since the statistical dispersion may be lower.

Ceritanya saya lg bikin aplikasi yg cukup tergantung dengan UUID. Aplikasi ini akan nerima request, membuat sebuah UUID, lalu diasosiasikan dengan data yg dikirim pada request tersebut. Bisa dibilang cukup tergantung karena keunikan UUID yang dibuat itu bisa jadi menjadi harga mati yg harus dipenuhi. Semua ID yang dibuat harus unik, gak boleh tidak. Yang menjadi masalah adalah kemarin saya menemukan ID yang sama :( bahkan saya selalu bisa mereproduksi masalahnya T_T

Aplikasi yg saya bikin ini ditulis dengan Python dan memakai CherryPy tuk HTTP framework. Saya menemukan kasus ini ketika saya menjalankan aplikasi tsb dengan Python 2.5.2 bawaan Ubuntu 8.04.3 (i386) dan Python 2.5.1 yg ada di Fedora 8 (amd64). Saat itu saya mencoba melakukan benchmark aplikasi dengan Apache Benchmark dengan membuat 1024 requests dalam 16 concurrent connections.

Sebagai informasi, CherryPy ini adalah sebuah HTTP framework multi-threading jadi setiap koneksi masuk akan ditangani oleh satu thread berbeda..

Kalau mau diperas sampe habis, kira2 ini aplikasi yg saya buat.

import cherrypy
import uuid

class Root(object):
    @cherrypy.expose
    def index(self):
        id = uuid.uuid4()
        id = str(id)
        print "#%s@" % id
        return ''

cherrypy.config.update({'log.screen': False,
                        'environment': 'production'})
cherrypy.quickstart(Root())

Oh iya, UUID yang saya pakai itu adalah UUID versi 4 yg menggunakan random number generator dalam pembuatan UUIDnya.

Setelah itu saya jalankan aplikasi tsb seperti berikut.

$ python2.5 test.py > daftar

Apache Benchmark lalu saya jalankan tuk membuat 1024 requests dalam 16 concurrent connections.

$ ab -n 1024 -c 16 http://127.0.0.1:8080/

Setelah selesai, saya cek berkas daftar yang terbentuk, memastikan 1 baris hanya berisi 1 buah UUID. Lalu jadikan isi berkas tsb menjadi unik dan membandingkan hasilnya.

$ sort -u daftar > unik
$ wc -l daftar unik

Seharusnya kedua berkas tersebut memiliki jumlah baris yang sama yang berarti setiap baris adalah unik. Namun sayangnya, saya tidak menjumpai hal tsb :(

Berhubung masih penasaran, saya akhirnya nyoba menggunakan Python 2.5.4 dan Python 2.6.4 hasil kompilasi sendiri di mesin Fedora tsb. Saya melakukan pengujian hal yang sama dan hasil yg saya temui adalah saya masih menemukan duplikasi UUID pada saat menggunakan Python 2.5.4. Sedangkan penggunaan Python 2.6.4 memberikan hasil yang saya harapkan, tidak ada duplikasi UUID.

Apa ini artinya Python 2.5.x bermasalah dalam hal ini? Saya belum menemukan kasus serupa setelah nyoba2 googling. Ada yang punya informasi lbh?

Ups, belum juga tulisan ini dipublish, saya dah nemuin sumber masalahnya :D Tadi salah kata kunci spertinya hehehe.. intinya adalah Python 2.5 memang memiliki bug di UUIDv4 generatornya. Silakan baca http://bugs.python.org/issue4607

Oh ya lagi.. asya dah nyoba jg pake UUIDv1 tapi ternyata masalah masih ada di Python 2.5 :(

05/12/09

GPL FAQ

Iseng2 saya baca GPL FAQ dan inilah beberapa isi yang menarik yang terkait dg masalah distribusi ulang dan penggunaan bersama aplikasi tidak bebas.

Maaf kalau tulisan ini lumayan panjang tapi isinya hanya copy-paste =P

Oh iya, penebalan tulisan dan pemberian garis bawah dilakukan oleh saya.

Kalau boleh ngasih kesimpulan sendiri (eh tapi saya bukan pengacara loh), semuanya berawal dari kegiatan distribusi. Kombinasi erat aplikasi kita dengan aplikasi lain yang dirilis dg GPL memang mengharuskan kita merilis aplikasi kita di bawah GPL. Namun kita berhak untuk tidak mendistribusikan aplikasi kita ke orang lain sehingga orang lain tidak berhak untuk meminta source code aplikasi kita (ya, walaupun itu GPL). Mohon dikoreksi kalau kesimpulan ini salah..

***

Tentang redistribusi

If I know someone has a copy of a GPL-covered program, can I demand he give me a copy?

No. The GPL gives him permission to make and redistribute copies of the program if he chooses to do so. He also has the right not to redistribute the program, if that is what he chooses.

Tentang penjualan

Does the GPL allow me to sell copies of the program for money?

Yes, the GPL allows everyone to do this. The right to sell copies is part of the definition of free software. Except in one special situation, there is no limit on what price you can charge. (The one exception is the required written offer to provide source code that must accompany binary-only release.)

Non-Disclosure Agreement - Jika didistribusikan

Does the GPL allow me to distribute copies under a nondisclosure agreement?

No. The GPL says that anyone who receives a copy from you has the right to redistribute copies, modified or not. You are not allowed to distribute the work on any more restrictive basis.

Non-Disclosure Agreement - Jika tidak/belum didistribusikan

Does the GPL allow me to develop a modified version under a nondisclosure agreement?

Yes. For instance, you can accept a contract to develop changes and agree not to release your changes until the client says ok. This is permitted because in this case no GPL-covered code is being distributed under an NDA.

You can also release your changes to the client under the GPL, but agree not to release them to anyone else unless the client says ok. In this case, too, no GPL-covered code is being distributed under an NDA, or under any additional restrictions.

The GPL would give the client the right to redistribute your version. In this scenario, the client will probably choose not to exercise that right, but does have the right.

Kombinasi

What is the difference between an “aggregate” and other kinds of “modified versions”?

An “aggregate” consists of a number of separate programs, distributed together on the same CD-ROM or other media. The GPL permits you to create and distribute an aggregate, even when the licenses of the other software are non-free or GPL-incompatible. The only condition is that you cannot release the aggregate under a license that prohibits users from exercising rights that each program’s individual license would grant them.

Where’s the line between two separate programs, and one program with two parts? This is a legal question, which ultimately judges will decide. We believe that a proper criterion depends both on the mechanism of communication (exec, pipes, rpc, function calls within a shared address space, etc.) and the semantics of the communication (what kinds of information are interchanged).

If the modules are included in the same executable file, they are definitely combined in one program. If modules are designed to run linked together in a shared address space, that almost surely means combining them into one program.

By contrast, pipes, sockets and command-line arguments are communication mechanisms normally used between two separate programs. So when they are used for communication, the modules normally are separate programs. But if the semantics of the communication are intimate enough, exchanging complex internal data structures, that too could be a basis to consider the two parts as combined into a larger program.

Kombinasi (lanjutan)

I’d like to incorporate GPL-covered software in my proprietary system. Can I do this?

You cannot incorporate GPL-covered software in a proprietary system. The goal of the GPL is to grant everyone the freedom to copy, redistribute, understand, and modify a program. If you could incorporate GPL-covered software into a non-free system, it would have the effect of making the GPL-covered software non-free too.

A system incorporating a GPL-covered program is an extended version of that program. The GPL says that any extended version of the program must be released under the GPL if it is released at all. This is for two reasons: to make sure that users who get the software get the freedom they should have, and to encourage people to give back improvements that they make.

However, in many cases you can distribute the GPL-covered software alongside your proprietary system. To do this validly, you must make sure that the free and non-free programs communicate at arms length, that they are not combined in a way that would make them effectively a single program.

The difference between this and “incorporating” the GPL-covered software is partly a matter of substance and partly form. The substantive part is this: if the two programs are combined so that they become effectively two parts of one program, then you can’t treat them as two separate programs. So the GPL has to cover the whole thing.

If the two programs remain well separated, like the compiler and the kernel, or like an editor and a shell, then you can treat them as two separate programs—but you have to do it properly. The issue is simply one of form: how you describe what you are doing. Why do we care about this? Because we want to make sure the users clearly understand the free status of the GPL-covered software in the collection.

If people were to distribute GPL-covered software calling it “part of” a system that users know is partly proprietary, users might be uncertain of their rights regarding the GPL-covered software. But if they know that what they have received is a free program plus another program, side by side, their rights will be clear.

Akses via jaringan

A company is running a modified version of a GPL’ed program on a web site. Does the GPL say they must release their modified sources?

The GPL permits anyone to make a modified version and use it without ever distributing it to others. What this company is doing is a special case of that. Therefore, the company does not have to release the modified sources.

It is essential for people to have the freedom to make modifications and use them privately, without ever publishing those modifications. However, putting the program on a server machine for the public to talk to is hardly “private” use, so it would be legitimate to require release of the source code in that special case. Developers who wish to address this might want to use the GNU Affero GPL for programs designed for network server use.

Penggunaan dalam organisasi

Is making and using multiple copies within one organization or company “distribution”?

No, in that case the organization is just making the copies for itself. As a consequence, a company or other organization can develop a modified version and install that version through its own facilities, without giving the staff permission to release that modified version to outsiders.

However, when the organization transfers copies to other organizations or individuals, that is distribution. In particular, providing copies to contractors for use off-site is distribution.

Kalau cuma make

If I only make copies of a GPL-covered program and run them, without distributing or conveying them to others, what does the license require of me?

Nothing. The GPL does not place any conditions on this activity.

04/12/09

Pentingnya koma

Coba lihat potongan eksekusi Python berikut.

>>> type(1)
<type 'int'>

>>> type([1])
<type 'list'>

>>> type((1))
<type 'int'>

>>> type((1,))
<type 'tuple'>

Pada saat membuat sebuah tuple, jika hanya ada satu elemen yang ingin kita masukkan, jangan lupa menambahkan tanda koma! Jadi alih-alih menulis ("isinya"), jika kita benar-benar ingin membuatnya menjadi sebuah tuple, tulislah ("isinya",).

Supaya makin jelas bedanya, coba lihat lagi contoh di bawah ini.

>>> a = ("satu", "dua")
>>> a[0]
'satu'

>>> a = ("satu")
>>> a[0]
's'

>>> a = ("satu",)
>>> a[0]
'satu'