Menggabungkan Image PNG menggunakan library PIL

Sebenarnya apa yang ingin saya tulis ini sudah ada di dokumentasi dan tutorial-tutorial online. Tetapi tidak ada salahnya saya kira kalau saya membagikan apa yang saya tahu. Kalaupun ternyata ada salahnya, ya mumpung ini masih terhitung Hari Lebaran, saya mohon maaf lahir dan batin. 😀

Library PIL adalah library pengolah gambar di bahasa pemrograman Python. Yang saya bagikan ini hanyalah sebagian kecil sekali dari fasilitas yang ada di library tersebut. Fokus saya adalah di bagian penggabungan gambar.

Kadang kita ingin menggabungkan dua atau lebih gambar, hal yang sebenarnya sangat mudah dilakukan dengan menggunakan software pengolah gambar seperti Photoshop atau Gimp. Tetapi kalau yang ingin digabungkan itu ada banyak sekali file, maka kadang kita perlu juga melirik script untuk otomatisasinya.

Batasan Kasus

Supaya tidak terlalu melebar, saya akan membatasi kasus ini dengan penggabungan gambar yang sama ukurannya. Tekniknya seperti overlay layer di css dengan positioning. Untuk kebutuhan ini saya akan menggunakan metode paste dari library PIL.Image.

Biasanya yang saya lakukan adalah membuka satu persatu image/gambar yang mau digabung tersebut.

from PIL import Image #import dulu library yang ingin digunakan

im = Image.open('/path/asli/lokasi/gambar.png')
im2 = Image.open('/path/asli/lokasi/gambar2.png')

#misalnya dua gambar itu yang ingin kita gabungkan

Setelah itu kita siapkan canvas tempat kita akan menggabungkan dua gambar tersebut. Karena dua gambar itu ukurannya sama, kita ambil saja salah satunya sebagai dasar ukuran canvas.

canvas_size = im.size #mengambil ukuran dimensi gambar
bg = Image.new('RGB',canvas_size,(255,255,255))
# RGB adalah mode gambar. 255,255,255 berarti kita beri warna putih

Setelah canvas siap, maka kita bisa menggabungkan gambar di atas, misalnya kita ingin menimpa gambar im dengan im2. Di sini filenya adalah png transparent, sehingga ketika ditimpa, gambar im tidak seluruhnya tertutup oleh gambar im2. Langkahnya sebagai berikut:

bg.paste(im,(0,0))
#gambar im kita timpa di atas canvas, di koordinat 0,0.

Maka di atas canvas (bg) sudah akan muncul gambar im. Tetapi kita ingin agar transparansi gambar im tetap ada, sehingga background putih canvas tidak tertutup blok hitam. Untuk hal ini, script di atas kita ubah menjadi:

bg.paste(im,(0,0),im)
# seperti langkah di atas, tetapi kita tambahkan masking im

#lalu dilanjut dengan menempatkan gambar im2 di atas im
#maka kita lanjutkan dengan script berikut

bg.paste(im2,(0,0),im2)

Voila! gambar im2 sudah bergabung dengan gambar im. Untuk melihatnya, kita bisa menggunakan perintah bg.show()

Script lengkapnya jadinya begini:

from PIL import Image #import dulu library yang ingin digunakan

im = Image.open('/path/asli/lokasi/gambar.png')
im2 = Image.open('/path/asli/lokasi/gambar2.png')

canvas_size = im.size #mengambil ukuran dimensi gambar
bg = Image.new('RGB',canvas_size,(255,255,255))
bg.paste(im,(0,0),im)
bg.paste(im2,(0,0),im2)
bg.show()

Menyimpan hasil ke django model ImageField

Nah, setelah gambar itu tergabung, seandainya kita menggunakan django, maka kita perlu menyimpan image itu ke models. Untuk kebutuhan ini, saya kadang menggunakan memory untuk meredraw hasil gabungan gambar tersebut, lalu memanfaatkan fasilitas InMemoryUploadedFile di django untuk menyimpannya ke database.

Sehingga script di atas akan menjadi seperti ini

#misalkan kita mempunyai models seperti ini

class DataImage(models.Model):
    title = models.CharField(max_length=255)
    image = models.ImageField(upload_to='image')

maka kita ubah script lengkap yang saya tulis di atas tadi, menjadi seperti ini:

import StringIO

tempFile = StringIO.StringIO()

im = Image.open('/path/asli/lokasi/gambar.png')
im2 = Image.open('/path/asli/lokasi/gambar2.png')

canvas_size = im.size #mengambil ukuran dimensi gambar
bg = Image.new('RGB',canvas_size,(255,255,255))
bg.paste(im,(0,0),im)
bg.paste(im2,(0,0),im2)

# menyimpan hasil generate ke stringIO file

bg.save(tempFile, format="JPEG")
#format bisa diubah sesuai kebutuhan. 
#dalam contoh ini, saya menyimpannya dengan kompresi jpeg

Setelah itu, kita bisa menyimpannya ke model DataImage dengan langkah berikut:

from django.core.files.uploadedfile import InMemoryUploadedFile

image_file = InMemoryUploadedFile(tempFile, None, 'nama_file.jpg','image/jpeg',tempFile.len, None)

#nama file diubah sesuai nama yang ingin kita simpan

Dari sini kita bisa langsung menyimpannya ke database.

daim = DataImage()
daim.title = "nama file"
daim.image.save("nama_file.jpg",image_file)
daim.save()

image hasil gabunganpun tersimpan ke database. File disimpan ke MEDIA_DIRECTORY sesuai setelan di settings.py

Demikian serba sedikit yang bisa saya bagi. Tidak begitu penting, tetapi semoga bisa bermanfaat bagi yang membutuhkan 😀

vale, demi parsletongue

el rony, mendesissssssss ssss sssss

nb. sekedar untuk lucu-lucuan, kita juga bisa menggunakan php untuk hal ini

<?php
$ibody = base_url('path/relative/to/body.png');
$istrap = base_url('path/relative/to/strap.png');
$ipads = base_url('path/relative/to/pads.png');
$imgInfo = getimagesize($ibody);
$basebody= imageCreateFromPNG($ibody);

// menentukan ukuran canvas
$w = "319";
$h = "221";

// men-scale image ke ukuran canvas dg aspect ratio
if ($imgInfo[0] <= $w && $imgInfo[1] <= $h) {
    $nHeight = $imgInfo[1];
    $nWidth = $imgInfo[0];
} else {
    if ($w/$imgInfo[0] > $h/$imgInfo[1]) {
        $nWidth = $w;
        $nHeight = $imgInfo[1]*($w/$imgInfo[0]);
    }else{
        $nWidth = $imgInfo[0]*($h/$imgInfo[1]);
        $nHeight = $h;
    }
}
$nWidth = round($nWidth);
$nHeight = round($nHeight);

// membuat canvas
$base = imagecreatetruecolor($nWidth, $nHeight);

imagealphablending($base, false);
imagesavealpha($base, true);
$transparent = imagecolorallocatealpha($base, 255, 255, 255, 127);
imagefilledrectangle($base, 0, 0, $nWidth, $nHeight, $transparent);
imagealphablending($base, true);
imagecopyresampled($base, $basebody, 0, 0, 0, 0, $nWidth, $nHeight, $imgInfo[0], $imgInfo[1]);

$insert2 = imageCreateFromPNG($istrap);
imagealphablending($insert2, true);
imagesavealpha($insert2, true);
imagecopyresampled($base,$insert2,0,0,0,0,$nWidth,$nHeight,$imgInfo[0], $imgInfo[1]);


$insert3 = imageCreateFromPNG($ipads);
imagealphablending($insert3, false);
imagesavealpha($insert3, true);
imagecopyresampled($base,$insert3,0,0,0,0,$nWidth,$nHeight,$imgInfo[0], $imgInfo[1]);


header('Content-type: image/png');
imagepng($base);
imagedestroy($base);
if(isset($insert2)){
    imagedestroy($insert2);
}
if(isset($insert3)){
    imagedestroy($insert3);
}
?>

iya.. script-script ini yang saya pakai untuk webnya NOKNbag 😀

Missconception about UX and Design

First of all, I’m not really good at English, but I hope you’ll find the ideas. So, please bear with me. No, I’m not asking you to ‘bare with me’.

Lately, I’ve stumbled to a bunch of images like this (bellow), comparing between design and user experience. All of them showing that most designs are wrong in real live regarding to user experience. Let’s take a look.

hClOzhD

taken from http://www.reddit.com/r/funny/comments/2taxzn/workaround/

taken from http://cimota.com/blog/2015/05/12/ae-in-ni-a-problem-of-emergent-use-versus-public-service-development/

taken from http://cimota.com/blog/2015/05/12/ae-in-ni-a-problem-of-emergent-use-versus-public-service-development/

image002

taken from http://cimota.com/blog/2015/05/12/ae-in-ni-a-problem-of-emergent-use-versus-public-service-development/

So, what do you think? Is it true that the design is wrong? Or is it something else? As for me, this is my opinion:

It’s More About Ignorance, Not UX

In our live as a society member, we are bound to several unwritten rules. Rules that are not really give any impact to us if we ignored it. Those images are the very good example about that. People do ignore, and sometimes because they are lazy.

Why I come to this conclusion, you may ask. Well, because that was really happen. The road design has to be in the most effective form. And by effective, the road design should accommodate several things. Things including the land property and the city plans. And for that purpose, square is almost he most perfect form for it.

But most of the time, people are so unrasionalistically (pffttt.. what kind of word is it?) lazy and ignorance. They simply ignore the fact that they were ‘vandalize’ other rights. They simply reject the rules, by crossing other properties. Imagine if that was a private property, which in some country they take very seriously about it, those people who ignore the rules could be end in the hospitals, or worse cemeteries.

So, back to our main topic, I stand my position that there is no wrong with the road design and what people do about it is nothing to do with user experience.

If User Experience means the design should accommodate people laziness and ignorances, then the world will be in a chaos. Let’s bring this to web design mater, so we can discuss about it more widely.

In the web design, for example the e-commerce design, lazy people will ignore a bunch of form that we ask them to fill, like address form for example. So, if in the name of user experience we simply get rid of that form, or just ignore it if people left it blank and keep submit it to our system, will we be able to finish the transaction? Shipping the product for example? No, right?

So, long story short, please do distinguish between use experience issues and how people act. People tend to be lazy, ignorance and simply stubborn, but put that away if we want to discuss about user experience.

Discuss about UX are only match for nobble people who respect rules.

vale, el rony

sedang embuh

 

Tentang “Eye Catching”

Beberapa hari ini saya bergulat dengan beberapa hal terkait dengan visual. Ada perdebatan-perdebatan dan asumsi-asumsi yang terbangun dari diskusi-diskusi ini. Dengan para NOKNwarrior saya berdiskusi tentang bagaimana tampilan sebuah website enak dipandang, nyaman dihinggapi pengunjung sekaligus berhasil mewakili kerennya produk mereka, NOKNbag. Selain itu saya juga terlibat pembicaraan yang cukup serius tetapi santai dengan teman-teman MojokCo. Walaupun lebih ke konten, tetapi pada akhirnya menyinggung juga tentang tampilan.

Hal yang selalu muncul adalah tentang sesuatu yang bagus, neat, simple, modern dan sejenisnya hingga style-style yang mengarah ke trend kekinian semisal flat design. Berdiskusi dengan mereka-mereka yang mengerti dan paham akan kebutuhannya tentunya memberikan pencerahan yang tak bisa dibilang sedikit.

Lantas pembahasan dengan tim software, kebetulan saya selama dua tahun ini terlibat pengembangan sebuah project yang super wangun yang sayangnya belum bisa saya bagi di sini, pokmen wangun wae, situ percaya waelah sama saya. Nah, project wangun itu juga butuh tampilan, bukan? Nah lagi-lagi hal-hal terkait UX dan UI menjadi pokok pembicaraan.

Lantas Makbedunduk Saya Tertampar

Tadi malam saya menemukan sebuah link yang bercerita tentang seorang S2 design yang gagal mendapatkan pekerjaan yang “sesuai” dengan kapasitas dia. Akhirnya mbak-mbak –yang cantik itu– terdampar pada pekerjaan menjadi pembuat banner situs porno.

Apa yang membuat saya tertampar? Ternyata ilmu yang penuh wiyu-wiyu dan super nehno dari dunia design tidak berlaku di dunia perpornoan ini. Mbak itu bercerita bahwa karya-karya awal dia ditolak mentah-mentah oleh perusahaan lendir tempat dia bekerja. Alasannya? Terlalu bagus dan terlalu profesional. Dhuengg!!

Bagi perusahaan porno, ternyata, karya desain yang dibutuhkan justru yang jelek, terasa “home made” — bedebah memang perusahaan ini, emangnya home made itu pasti jelek? fak — dan ini dia kata kunci penting “amateur“. Sudahlah merusak kata home made, masih juga rela merusak citra amatir. Fak adalah Fak!!

Maka jadilah si mbak-mbak — yang cakep ini– membuat karya-karya banner dengan kualitas apa adanya, font helvetica dibuang diganti dengan impact dan mungkin comics sans, warna-warna norak dan animasi-animasi ala web jaman geocities.

Efeknya? Klik yang didapat selalu super duper tinggi. Nah loh! Lantas apa kuncinya? Kata si mbak ini kuncinya adalah Eye Catching! Begitu tertangkap mata, entah oleh warna, font, atau typo — ini sih keahlian baba @rasarab dan tim ngonoo — selanjutnya orang tergiring untuk mengklik banner itu.

Kalau Kamu Kaya, Sejelek Apapun Kamu, Pasti Laku

Di dunia nyata mungkin itu padanannya. Dalam hal ini, situs porno memiliki kekuatan melebihi situs lain. Bisnis lendir yang usianya setua peradaban manusia ini, merupakan modal tersendiri yang oleh karenanya tidak lagi dibutuhkan copywriter handal, designer wiyu-wiyu super nehno. Tugas utamanya hanya agar orang melihat “woh apa ini? banner apa ini? kok jelek?” yang kemudian akan dilanjutkan sendiri oleh pesan di dalamnya yang ngawe-awe setiap orang dengan penawaran purbanya.

Mirip sekali dengan para bapak-bapak gaek tuwek berdagu panjang, tapi bisa menggandeng wanita sintal montok dan membawanya ke meldaifes. Ndak penting bentuk bungkusnya, yang penting berapa harga pembungkusnya, yo ra?

Lantas saya kembali ke si mbak itu, dan saya kembali manggut-manggut. Di dunia ini, kata dia, ada dua hal yang laku dan tak perlu endorsement super duper nehno, yaitu sex dan war.

Nah, yang kedua ini kemudian mengingatkan kembali ke situs-situs abal-abal ala piyungan dan sosok-sosok ala jonru. Mereka laku karena menjual perang. Maka tak penting kayak apa hancurnya wajahnya jonru, nggak penting seperti apa hancurnya layout website piyungan, yang penting ajakan perangnya. Laku.

Maka, bagi kita para visualist, tantangannya tinggal dua, bersetia dengan UI dan UX yang bagus mengikuti kaidah-kaidah GoodUI atau jualan perang/sex. Apapun yang kalian pilih, berhati-hatilah, jangan sampai terpeleset, apalagi kalau masuk bisnis lendir.

vale, demi visual

el rony, mencuci mata.

nb: link soal mbak itu ada di sini

Query MySQL sebagai dictionary menggunakan Python

Hai, halo..

Tulisan ini sekedar catatan saja, kebetulan baru saja memindah bahasakan program buatan Uda @ivanlanin (SELAMAT ULANG TAHUN!) yang berbasis PHP di sini, menjadi bahasa Python.

Sebelumnya, perlu saya sampaikan bahwa repository github di atas adalah repository corpus Bahasa Indonesia untuk keperluan Natural Language Processing. Perlu saya ceritakan sedikit juga bahwa corpus itu dibangun oleh om Jim Geovedi untuk keperluan robot-robot yang dia bikin. Dalam penyusunan corpus tersebut, om Jim dibantu oleh Uda Ivan salah satunya dengan menyediakan data lexicon Bahasa Indonesia.

Berkas kode dari Uda Ivan di dalam repository tadi sebenarnya adalah dump data dari MySQL menjadi berkas json. Saya sebagai cheerleader tentu saja merasa perlu untuk ikut ngrusuhi –yak mulai di sini saya sudah capek ber-EYD. maafkan saya haha–.

Fetch All

Bagi Anda yang sudah terbiasa dengan pemrograman PHP, tentu tidak asing dengan fungsi fetchall baik ketika menggunakan pdo maupun cli. Fungsi ini mengembalikan query sql menjadi array.

Di Python, fungsi inipun ada juga. Dalam hal ini saya menggunakan MySQL-python untuk koneksi ke MySQL. Tetapi ada “kelemahan” dari fungsi ini di Python, dimana keluaran dari fungsi tersebut adalah list (list juga array sih..tapi..) bukan dictionary (semacam list dengan key,value. bodhone ngono, aku kan bodho).

Nah, karena di baris-baris di dalam kode Uda Ivan banyak menggunakan key value ini, maka saya bikinlah script ini, agar query database keluar sebagai dictionary. Berikut scriptnya:

def FetchAllAssoc(cursor, sql):
    try:
        result = []
        cursor.execute(sql)
        cols   = tuple([field[0].decode('utf8') for field in cursor.description])
        for row in cursor.fetchall():
            result.append(dict(zip(cols,row)))
    except Exception as e:
        result = {"error": str(e)}
    return result

Penggunaannya tentu saja mudah, misalnya saja kode di atas disimpan sebagai file utils.py, maka begini:

import MySQLdb #you'll get this module by installing MySQL-python

from utils import FetchAllAssoc 

db = MySQLdb.connect('host','user','pass','dbname')
cur = db.cursor()

sql = "SELECT a,b FROM c WHERE a IS NOT NULL"

result = FetchAllAssoc(cur,sql)

#if you want to see the result, use pprint to get nice output
from pprint import pprint
pprint(result)

#or you can iterate the value
for row in result:
    print row['key']

Demikian, nggak ada yang istimewa bukan? Gapapa, yang istimewa itu Jogja.

vale, demi senam otak

el rony — tunggal guru, tunggal ngelmu, ojo nggeguyu

woya kelupaan, fork saya belum dimerge. kalau mau lihat fork-fork-an saya, di sini

Serba-serbi Apple Krowak

Postingan ini ya postingan selo saja, ndak ada yang istimewa. Sudah lama ndak ngeblog, jadinya ya seadanya yang pingin diblogkan saja. Postingan ini sebenarnya dipicu —halah— oleh risinya saya karena file .DS_Store yang selalu muncul di desktop. Sebagai orang visualhalah maneh— ini kan sangat mengganggu. Maka sayapun mencari cara untuk menanggulanginya, maka –lagi-lagi maka– inilah olah kanuragan selanjutnya —halahraimundes–.

Baiklah, semuanya berawal dari kebutuhan saya untuk memunculkan semua hidden files di Finder Mac. Kebetulan saya sedang senang bermain-main dengan bahasa kaum slytherin, Python. Nah, saya merasa nyaman bekerja di bawah virtual environment (virtualenvs). Namun ada kalanya saya perlu juga mengedit file core module yang di folder virtualenvs ini, yang mana sebenarnya bisa dengan mudah diakses dengan terminal, tapi karena saya ini bukan preman kayaknya kok perlu juga sekali-sekali ndak nongkrong di terminal. Nah karena virtualenvs ini foldernya hidden, agar muncul di Finder saya jalankan perintah ini:

defaults write com.apple.finder AppleShowAllFiles TRUE

Maka muncullah semua file hidden di Finder, sehingga saya bisa klik kanan dan jalankan sublime text untuk mengedit file-file hidden maupun di dalam folder hidden itu. Tapi ya itu tadi, lantas muncul file .DS_Store di desktop. Mengganggu banget!

Apa sih file .DS_Store ini? Sebenarnya ini file semacam Thumbs.db di Windows. Tugasnya cuma menyimpan settingan finder saja. Jadi kalau kita pingin misalnya view as thumbnails di folder A, view as list di folder B, dan seterusnya, informasi ini disimpan di file .DS_Store ini. Penting? ya penting buat kamu yang pingin nyimpen informasi itu, sehingga ke depan settingan per foldermu tidak berubah. Tapi bagi saya, lebih penting kalau desktop bersih dari file ini. hihi. Bagaimana caranya? Dua langkah yang harus dijalankan, yang pertama adalah mendisable pembuatan .DS_Store, dengan script ini:

defaults write com.apple.desktopservices DSDontWriteNetworkStores true

dan yang kedua adalah mendelete semua file .DS_Store di dalam komputer apel krowak kamu. Atau ya sebenarnya bisa saja delete di folder yang ingin kamu delete sih, tapi karena ini saya ingin sharing apa yang saya lakukan, jadi saya lakukan ini:

sudo find / -name ".DS_Store" -depth -exec rm {} \;

Nah, sekarang bersih sudah.

Kalau nanti kamu pingin meng-hide lagi file-file hidden dari Finder, ya tinggal mengubah script untuk show file hidden tadi dari True menjadi False. Kalau ingin mengaktifkan .DS_Store, ya tinggal mengubah DSDontWriteNetworkStores dari true menjadi false juga.

Begitu ya, vale ini, demi keselonan tentu saja.

Setup Opengraph di Themes WordPress

Sebenarnya postingan semacam ini sudah banyak sekali beredar, dan tawaran solusi dari mulai berbentuk plugins sampai themes yang sudah dilengkapi dengan meta opengraph juga sudah berlimpah, hanya saja kebetulan themes yang saya pakai kok tidak support hal ini, jadilah saya meng-extend themesnya.

Opengraph ini dipakai terutama (yang paling kelihatan) untuk share post di facebook. Dengan memasang meta opengraph (ini istilah saya sendiri, silakan cari istilah yang lebih benar deh) di themes, maka kita bisa memasang thumbnail, mengatur excerpt dan lain-lain ketika postingan kita di share ke halaman facebook.

Nah, tidak perlu berpanjang-panjang, ada dua cara untuk memperbaiki themes yang tidak support opengraph ini (nampak ketika dishare di facebook, caption dan thumbnail tidak muncul). Satu, dengan memasang script/kode ini di functions.php atau bisa juga dipasang di header.php sebelum tag penutup head.

Untuk dipasang di functions.php

function insert_fb_in_head() {
    global $post;
    if ( !is_singular()) //jika bukan post atau page return kosong
        return;
    echo '<meta property="fb:admins" content="ID_AKUN_FB_ANDA"/>';
    echo '<meta property="og:title" content="' . get_the_title() . '"/>';
    echo '<meta property="og:type" content="article"/>';
    echo '<meta property="og:url" content="' . get_permalink() . '"/>';
    echo '<meta property="og:site_name" content="NAMA_SITUS_ANDA"/>';
    $args = array(
        'post_type'   => 'attachment',
        'numberposts' => -1,
        'post_status' => null,
        'post_parent' => $post->ID,
        'exclude'     => get_post_thumbnail_id()
    );

    $attachments = get_posts( $args );

    if ( !$attachments ) {
        $default_image="URL_IMAGE_DEFAULT_ANDA"; //isi dengan url image Anda lengkap dg http-nya
        echo '<meta property="og:image" content="' . $default_image . '"/>';
    } else{
        foreach ( $attachments as $attachment ) {
            $thumbnail_src = wp_get_attachment_image_src($attachment->ID,'large');
        }
        echo '<meta property="og:image" content="' . esc_attr( $thumbnail_src[0] ) . '"/>';
    }
    echo "";
}
add_action( 'wp_head', 'insert_fb_in_head', 5 );

 .. atau script ini pasang di header.php

function insert_fb_in_head() {
    global $post;
    if ( !is_singular()) //jika bukan post atau page return kosong
        return;
    echo '<meta property="fb:admins" content="ID_AKUN_FB_ANDA"/>';
    echo '<meta property="og:title" content="' . get_the_title() . '"/>';
    echo '<meta property="og:type" content="article"/>';
    echo '<meta property="og:url" content="' . get_permalink() . '"/>';
    echo '<meta property="og:site_name" content="NAMA_SITUS_ANDA"/>';
    $args = array(
        'post_type'   => 'attachment',
        'numberposts' => -1,
        'post_status' => null,
        'post_parent' => $post->ID,
        'exclude'     => get_post_thumbnail_id()
    );

    $attachments = get_posts( $args );

    if ( !$attachments ) {
        $default_image="URL_IMAGE_DEFAULT_ANDA"; //isi dengan url image Anda lengkap dg http-nya
        echo '<meta property="og:image" content="' . $default_image . '"/>';
    } else{
        foreach ( $attachments as $attachment ) {
            $thumbnail_src = wp_get_attachment_image_src($attachment->ID,'large');
        }
        echo '<meta property="og:image" content="' . esc_attr( $thumbnail_src[0] ) . '"/>';
    }
    echo "";
}
insert_fb_in_head();

Untuk mengecek apakah settingan Anda sudah benar, silakan kunjungi halaman fb lint ini. Masukkan URL postingan Anda di sana (bukan URL homepage, karena dari script di atas, kalau bukan postingan, meta-nya dikosongi), maka kalau sudah benar, Anda akan mendapatkan hasil seperti di bawah ini:

fblint

 

Untuk mendapatkan FB ID, Anda bisa menggunakan tools di halaman ini.

Demikian.

Nggak penting? Lha emang iya 😀

vale, demi pokokmen

el rony, sing penting

Tentang Machine Learning (Pembelajaran Mesin)

Penjelasan ringkas ala Geovedi.

Machine Learning adalah bagian dari Artificial Intelligence. Intinya tentang bagaimana sebuah mesin “belajar” dan mengenali bahasa manusia. Proses di dalamnya melibatkan rumus-rumus yang rumit dan juga proses trial and error dari banyak pihak. Ilmu ini berkembang pesat, dan nampaknya di Indonesia juga semakin banyak yang tertarik dengan dunia ini.

Permasalahannya — kalau boleh dibilang masalah — adalah bagaimana menerangkan hal itu kepada orang yang tidak bergerak di bidang IT? Mereka yang bergerak di bidang IT, terbiasa googling, banyak baca wikipedia, paling nggak sedikit banyak ngerti alur maupun logika dari yang dinamakan machine learning, tetapi bagi mereka yang bukan “golongan” itu, tentu kesulitan.

Apa kebutuhannya menerangkan hal ini kepada orang non IT? Bagi saya, karena AI itu kurang lebih muncul sebagai jawaban atas kebutuhan manusia. Dan adalah bodoh jika apa yang disebut “jawaban” itu tidak dipahami oleh si manusia itu sendiri. Maka, berikut ini gambaran machine learning diterangkan oleh masternya, Jim Geovedi, dengan bahasa yang gamblang. Oh iya, Jim menerangkan ini kepada neng yuke dan lola yang notabene adalah Event Organizer, maka perumpamaan yang diambil seputar band. Semoga hal ini bisa jadi acuan tentang bagaimana menerangkan machine learning, atau umumnya AI, kepada masyarakat lebih luas. Teks di bawah ini saya kutip sesuai aslinya.

neng yuke dan lola kan biasa ngurus acara yang melibatkan banyak band. dan suatu ketika manage suatu acara yang melibatkan beberapa band dengan berbagai genre. masalah muncul ketika harus bikin rundown atau membedakan stage setiap group band, supaya tidak class genre dan punya rundown yang enak.

nah, cara yang paling mudah mungkin langsung bertanya dengan personil atau manajemen band tersebut, atau ke orang lain yang sudah lebih dulu mengenal band tersebut. tapi mungkin kalian iseng… coba untuk mengidentifikasi berdasarkan sejumlah informasi yang sifatnya terbatas. misalnya, nama band, kota asal, logo band, kemudian jumlah personil dan instrumen yang digunakan.

contoh yang paling mudah, ini adalah contoh nama-nama band: ‘besok bubar’, ‘suffocation’, ‘om soneta’, ‘runtah’, ‘ragaji mesin’, ‘death vomit’, ‘seringai’, ‘dewa’, ‘kahitna’, ‘java jive’, ‘ dan ‘padi’

berbekal pengalaman terdahulu, ada stereotype dari penamaan band seperti:

– kalau band metal biasanya punya nama-nama gahar, gak jauh-jauh dari unsur terror, horror, death, dsb.
– kalau band dangdut biasanya dimulai dengan awalan ‘om’ (orkes melayu)
– band punk atau hardcore punya nama yang cenderung umum namun gak lazim digunakan.
– band pop atau rock, cenderung netral

dari beberapa nama tersebut, sudah mulai bisa diklasifikasikan:
– band metal: [‘suffocation’, ‘death vomit’]
– band dangdut: [‘om soneta’]
– band punk/hardcore: [‘besok bubar’, ‘seringai’, ‘ragaji mesin’]
– band pop/rock: [‘dewa’, ‘padi’, ‘kahitna’, ‘java jive’]

kemudian dari koleksi band pop/rock [‘dewa’, ‘padi’, ‘kahitna’, ‘java jive’] ingin diketahui mana band rock dan mana band pop. informasi yang sudah diketahui adalah jumlah personil band rock biasanya berjumlah 5 orang atau kurang dengan 2 pemain gitar (lead & rhythm), dan ada beberapa yang extra keyboard player. sementara band pop ada kecenderungan punya beberapa vokalis dan biasanya punya keyboard player.

dari informasi tersebut akhirnya diklasifikasikan:
– band rock: [‘dewa’, ‘padi’]
– band pop: [‘kahitna’, ‘java jive’]

nah, dalam teknologi machine learning, informasi nama band, kota asal, logo band, kemudian jumlah personil dan instrumen yang digunakan itu dikenal sebagai ‘features’. kemudian, informasi stereotype yang diketahui dikenal sebagai ‘frequency distribution’.

dengan membandingkan features dan frekuensi, bisa data bisa diproses. tingkat akurasinya tergantung berapa besar features yang dimiliki dan seberapa sering features yang berhubungan dengan data tersebut muncul untuk kasus-kasus lain. dan tentunya tidak 100% akurat karena akan ditemukan penyimpangan di sana-sini. misalnya band ‘kuburan’ yang mungkin akan diklasifikasikan sebagai band ‘metal’, namun ternyata genrenya ‘rock’ (walaupun pada kenyataannya benar dulu mereka main metal, namun namanya masih dipertahankan).

gitu… deh. :-“

Nah, bagaimana? gamblang bukan? 🙂
vale, demi pemahaman
el rony, belajar agar bisa bilang “cara mudahnya”

Frameworks, sebuah kitab baru bagi CTO

Tidak semua CTO tentu saja, hanya satu orang CTO yang mempublish tulisan tidak bermutu. Di tulisannya, dia bilang,”dear programmers, please don’t use your own frameworks”. Sudah ada balasan komentar di postingan tersebut, dan sudah mewakili apa yang ingin saya bicarakan sebenarnya, tetapi saya merasa perlu menulis ulang dalam bahasa Indonesia mengenai hal ini. Oh iya, postingan itu bisa Anda cari sendiri melalui google dengan judul dalam tanda kutip tadi.

Jadi begini..

Mas CTO, frameworks itu tak lebih hanyalah satuan kode saja, rangkuman dari sekian library yang membuat proses pembuatan software/web menjadi lebih cepat. Oleh karenanya, frameworks itu dibikin oleh programmers juga. Kenapa? Karena programmers juga yang tahu apa saja yang dibutuhkan olehnya untuk membuat sebuah produk.

Sebuah frameworks bisa jadi dianggap sebagai sebuah produk jadi ketika frameworks tersebut sudah dipakai oleh banyak orang, diendorse oleh banyak community. Tetapi penentu baik atau tidaknya sebuah frameworks tentu bukan semata-mata karena hal ini, titik utamanya adalah bagaimana programmers bisa menyelesaikan pekerjaannya dengan cepat dan sesedikit mungkin bugs. Tentu dengan mengingat pentingnya masalah security.

Menyinggung masalah security, ketika sebuah frameworks tidak dikenal oleh orang banyak, maka dia memiliki satu keuntungan, algoritma kodenya tidak banyak diketahui orang, sehingga sedikit ada harapan “lebih aman”. Sedikit. Harapan. Tanda kutip. Karena tentu hal itu jelas terkait pada kualitas kodingnya.

Maka mas CTO..

Mengejar keuntungan itu sah-sah saja. Anda pingin cepat kaya, programmers Anda perah supaya segera menghasilkan susu. Tapi kalau Anda terus menerus memeras dan bahkan mengekang programmers Anda, maka kehilangan besar ada di depan mata Anda.

Seorang programmers menemukan satu cara workaround, katakanlah itu reinventing the wheels, tetap adalah satu proses bagi dia. Ibaratnya dia belajar berjalan, maka dia sudah siap berlari. Proses ini tidak boleh dimatikan, oleh alasan apapun. Oh Anda mungkin akan berkata, “itu tidak berlaku untuk proses produksi”. Tetapi apa yang akan terjadi jika seorang programmers hanya mengenal satu atau dua atau tiga frameworks saja? Mereka tak lebih seperti kera yang tidak berani makan pisang karena tiap kali mau makan pisang Anda semprot dengan air dingin.

Dan ketika nantinya muncul bugs (oh bugs adalah sahabat tiap frameworks, dear CTO), karena kreativitasnya sudah Anda kekang, yang terjadi adalah proses memakan waktu yang lebih mahal dibanding kalau sang programmers sudah dibebaskan kreativitasnya sejak awal.

Programmer yang cerdas, kreatif, adalah asset mahal. Anda menjadi CTO tanpa memahami hal ini, maka Anda tak lebih hanyalah manager yang salah memegang peta.

Dear CTO, please learn how to behave

vale, demi kreativitas

el rony, memintal kode

Fixing jQuery Tab Slide Out

William Paoli menerbitkan plugin jQuery yang cukup menarik, yaitu jquery tabslideout. Sebuah plugin yang memungkinkan kita memasang sliding panel di sisi kiri, kanan, atas atau bawah page website kita. Dia merilis plugin tersebut pada tanggal 1 September 2009.

Plugin ini dibikin ketika library jQuery masih versi 1.3.x. Ini adalah plugin perbaikan terakhir yang dibikin oleh Wiliam Paoli. Entah kenapa setelah itu dia tidak mengupdate plugin ini lagi. Mungkin karena menurut dia teknologi ini sudah usang, atau entah.

Nah, bagi teman-teman yang ingin memakai plugins ini dengan menggunakan library jQuery terbaru atau 1.8.x maka perlu mengubah kode bikinan Wiliam Paoli ini. Kode yang perlu diubah tidak banyak, hanya pada line 79 hingga line 82. Dari yang semula:

containerWidth: parseInt(obj.outerWidth(), 10) + ‘px’,
containerHeight: parseInt(obj.outerHeight(), 10) + ‘px’,
tabWidth: parseInt(settings.tabHandle.outerWidth(), 10) + ‘px’,
tabWidth: parseInt(settings.tabHandle.outerWidth(), 10) + ‘px’,

menjadi seperti ini:

containerWidth: parseInt(obj.outerWidth(true), 10) + ‘px’,
containerHeight: parseInt(obj.outerHeight(true), 10) + ‘px’,
tabWidth: parseInt(settings.tabHandle.outerWidth(true), 10) + ‘px’,
tabWidth: parseInt(settings.tabHandle.outerWidth(true), 10) + ‘px’,

Selesai, dan plugin ini bisa dipakai di library jQuery versi 1.8.x. Hanya perlu menambahkan true/false untuk outerWidth, outerHeight saja.

Sebenarnya menambahkan argument true atau false itu untuk memberitahu jQuery apakah dia akan menghitung value termasuk margin atau tidak. Tetapi dalam kasus tab slide out ini, memang sudah jelas bahwa outerWidth dan outerHeight ini untuk mendapatkan nilai termasuk marginnya. Sehingga kita bisa memposisikan tab dengan benar di kanan, kiri, atas atau bawah.

Demikian.

NB: sebenarnya saya pingin nulis tentang plugin lain, tetapi yang itu tidak terselesaikan dan masih di dalam draft. Sedang capek bikin screenshoot. *alesan* 😀

Slytherine’s Language to Extend User Model

Lama tidak ngeblog, sekali ngeblog tidak lama. Ini sikap.

Jadi ceritanya saya sedang belajar bahasa kaum slytherine, bahasa ular alias python. Berhubung saya pada dasarnya adalah desainer yang terjebak dalam dunia perkodingan, jadilah saya segera melirik framework-framework yang ada. Oh sebenarnya sih saya sempat bergulat dengan core python, raw coding atau apapun istilahnya lah ya, yang tidak pakai framework, tetapi ketika sudah sampai pada bagaimana memunculkan di website, maka framework adalah sahabat terbaik.

Framework yang sudah saya gunakan saat ini adalah django dan web.py. Django sepenuhnya karena mengejar rapid development, sementara web.py lebih ke kebutuhan untuk membuat API. API di django sempat terhambat oleh restriksi stdout di framework itu, sehingga saya berpindah ke web.py. Dan API tentu saja penting, mengingat negara kita termasuk produsen tembakau yang besar. hubungane opo mas? ngrokok ki butuh geni mas.

Mengenai bagaimana membuat API dengan web.py mungkin lain kali akan saya tuliskan, tentu saja tulisan seorang newbie lho ya, ndak ada ninja-ninjaannya. Paling nggak biar ndang rilis API gitu, mosok bertahun-tahun ngrilis API saja ndak jadi-jadi. Malah jadi sejarah.

User Model

Django sudah memiliki Core Module untuk manajemen User. Karena ini framework MVC, maka di dalamnya ada User Model. Nah, masalahnya di Core Module ini kadang ada field yang belum terfasilitasi, misalnya kita ingin memasukkan jenis kelamin atau usia. Di Indonesia ini penting, karena kadang kita harus menentukan menyapa dengan bapak atau ibu atau mas atau piyambakan mbak? 

Continue reading “Slytherine’s Language to Extend User Model” »