Top Banner
125

Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

Feb 07, 2018

Download

Documents

LêHạnh
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

Database PostgreSQL, Pemrograman Python,

dan SMS Gateway

RAB Linux Indonesia

©2010

Page 2: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

Daftar Isi

1 Alasan 4

2 Pemasangan 5

3 Hello World! 83.1 Variabel dan Tipe Datanya . . . . . . . . . . . . . . . . . . . . . 93.2 Kondisi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113.3 Perulangan . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

4 Tipe Data 164.1 String . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164.2 Bilangan . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

4.2.1 Konversi Tipe Data . . . . . . . . . . . . . . . . . . . . . 184.2.2 Formatting . . . . . . . . . . . . . . . . . . . . . . . . . . 184.2.3 Kalkulator . . . . . . . . . . . . . . . . . . . . . . . . . . 19

4.3 List . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194.3.1 Pemenggalan . . . . . . . . . . . . . . . . . . . . . . . . . 204.3.2 Keberadaan Elemen . . . . . . . . . . . . . . . . . . . . . 214.3.3 Mengubah Elemen . . . . . . . . . . . . . . . . . . . . . . 24

4.4 Dictionary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254.5 Waktu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

5 Modularitas 305.1 Membuat Fungsi . . . . . . . . . . . . . . . . . . . . . . . . . . . 315.2 Membuat Modul . . . . . . . . . . . . . . . . . . . . . . . . . . . 325.3 Search Path . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34

6 Fungsi 366.1 Memanggil Dirinya Sendiri . . . . . . . . . . . . . . . . . . . . . 366.2 Format Uang . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36

7 Database 417.1 Tabel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43

7.1.1 Sequence . . . . . . . . . . . . . . . . . . . . . . . . . . . 457.1.2 Mengubah Struktur . . . . . . . . . . . . . . . . . . . . . 48

1

Page 3: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

DAFTAR ISI 2

7.2 View . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 507.3 Backup dan Restore . . . . . . . . . . . . . . . . . . . . . . . . . 52

7.3.1 Encoding . . . . . . . . . . . . . . . . . . . . . . . . . . . 537.4 Fungsi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54

7.4.1 PL/pgSQL . . . . . . . . . . . . . . . . . . . . . . . . . . 557.4.2 PL/Python . . . . . . . . . . . . . . . . . . . . . . . . . . 60

8 Python Akses Database 628.1 Active Record . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 638.2 Auto Commit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 708.3 Synchronizer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72

8.3.1 Aspek Keamanan . . . . . . . . . . . . . . . . . . . . . . . 738.3.2 Tambah, Perbaharui, Hapus . . . . . . . . . . . . . . . . . 75

8.4 Migrasi dari Database Lain . . . . . . . . . . . . . . . . . . . . . 77

9 Lintas Sistem 799.1 Command Line . . . . . . . . . . . . . . . . . . . . . . . . . . . . 799.2 File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 819.3 Database . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 829.4 XMLRPC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83

9.4.1 PHP sebagai XMLRPC Client . . . . . . . . . . . . . . . 869.4.2 Drupal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87

10 Pengemasan 8910.1 Paket Debian . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8910.2 Debian Repository . . . . . . . . . . . . . . . . . . . . . . . . . . 9410.3 Remastering Ubuntu . . . . . . . . . . . . . . . . . . . . . . . . . 95

11 Graphical User Interface 9811.1 Orientasi Objek . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9911.2 Daftar Pegawai . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100

12 Object Oriented Programming 10512.1 Lebih Terstruktur . . . . . . . . . . . . . . . . . . . . . . . . . . . 10612.2 Lebih Umum . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10712.3 Tingkat Kerumitan . . . . . . . . . . . . . . . . . . . . . . . . . . 108

13 Kerja Sampingan 111

14 SMS Gateway 11414.1 Pemasangan . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114

14.1.1 IMEI Chip . . . . . . . . . . . . . . . . . . . . . . . . . . 11614.1.2 Database . . . . . . . . . . . . . . . . . . . . . . . . . . . 117

14.2 Hello world! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11714.3 Instant Messenger Gateway . . . . . . . . . . . . . . . . . . . . . 118

14.3.1 Yahoo! Messenger . . . . . . . . . . . . . . . . . . . . . . 11814.3.2 XMPP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120

Page 4: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

DAFTAR ISI 3

14.4 Broadcast . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121

Page 5: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

Bab 1

Alasan

Mengapa Python merupakan bahasa yang tepat untuk pembuatan berbagaiaplikasi ? Berikut ini alasannya.

Multiplatform Python merupakan bahasa pemrograman yang tersedia di ber-bagai platform seperti Linux, Windows, Mac, Unix. Bahkan sudah terse-dia di platform handphone seperti Symbian dan Android.

Mudah Python tergolong scripting, artinya Anda cukup tulis source-nya ditext editor biasa, lalu jalankan.

Hemat Bahasa ini berkonsep hemat source. Tampak pada cara penulisannyayang tidak membutuhkan karakter atau kata khusus untuk BEGIN danEND. Sebagai gantinya sub-block dipisahkan dengan indent (penulisanmenjorok ke kanan).

Lalu mengapa PostgreSQL dipilih sebagai media penyimpanan datanya ?

Multiplatform PostgreSQL tersedia di Linux, Windows, Mac, dan Unix.

Lengkap PostgreSQL tergolong lengkap dan mudah dikembangkan. Memili-ki sifat umum traditional database seperti transaction, stored procedure(function), dan trigger. Bahkan function bisa ditulis dalam berbagai baha-sa (tidak hanya SQL), Python, Perl, Shell, dan Java adalah contoh bahasayang didukungnya. Ia juga memiliki modul khusus untuk kebutuhan GIS(Geographic Information System).

4

Page 6: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

Bab 2

Pemasangan

Untuk memudahkan penjelasan, kita gunakan distro Linux berbasis Ubuntu.Pada saat tulisan ini dibuat kami menggunakan Ubuntu 10.04 (Lucid). Andajuga bisa menggunakan jenis Ubuntu lainnya seperti Kubuntu (window managerKDE), atau BlankOn (buatan Indonesia).

Pasca instalasi Ubuntu Python sudah disertakan. Namun masih ada yangperlu diunduh (download) lagi. Sebelumnya perbaharui daftar paket yang akandiunduh, lakukan ini di konsole:

1 $ sudo apt−get update

Pasang PostgreSQL:

1 $ sudo apt−get i n s t a l l p o s t g r e s q l po s tg r e sq l−plpython −8.4

plpython digunakan saat kita membuat function di PostgreSQL, alternatiflain dari plpgsql yang terpasang secara default.

Pasang SQLAlchemy agar Python bisa menggunakan PostgreSQL:

1 $ sudo apt−get i n s t a l l python−sqla lchemy python−psycopg2

Saat pemasangan paket postgresql secara otomatis paket postgresql-client-8.4terpasang. Paket ini memuat psql yang digunakan untuk terhubung ke Pos-tgreSQL server, secara command line. Ada baiknya Anda juga memasang versiweb-nya:

1 $ sudo apt−get i n s t a l l phppgadmin

Kadang web server Apache tidak otomatis hidup:

1 $ sudo / e tc / i n i t . d/apache2 s t a r t

Secara default Apache hidup otomatis saat komputer boot. Lalu buatlah sym-link phppgadmin:

1 $ sudo ln −s / usr / share /phppgadmin /var /www/

Kemudian di browser (sebaiknya Firefox) buka url:

5

Page 7: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 2. PEMASANGAN 6

http://localhost/phppgadmin

Bagi pengguna window manager Gnome Anda bisa gunakan gedit sebagai texteditor. Sedangkan pengguna KDE bisa gunakan kate. Keduanya berbasis GUI.Jika Anda lebih nyaman dengan konsole bisa gunakan nano, joe, atau vi.

1 $ sudo apt−get i n s t a l l vim

Kemudian sesuaikan /etc/vim/vimrc,

1 $ sudo v i / e t c /vim/vimrc

Biasanya option sudah disediakan, Anda tinggal menghapus tanda kutip diawal option. Aktifkan pewarnaan agar nyaman saat membaca source:

1 " Vim5 and l a t e r v e r s i on s support syntax h i g h l i g h t i n g .Uncommenting the next

2 " l i n e enab l e s syntax h i g h l i g h t i n g by de f au l t .3 syntax on

Saat Anda membuka �le untuk keduakalinya, maka kursor langsung menujuke lokasi sebelumnya.

1 " Uncomment the f o l l ow i ng to have Vim jump to the l a s tp o s i t i o n when

2 " reopening a f i l e3 i f has (" autocmd")4 au BufReadPost * i f l i n e (" '\"") > 0 && l i n e (" '\"") <=

l i n e (" $ ") | exe "normal g '\"" | end i f5 end i f

Menjorok otomatis (auto indent), dan penekanan tombol TAB diganti de-ngan SPACE 4 kali:

1 " Uncomment the f o l l ow i ng to have Vim load indenta t i onr u l e s accord ing to the

2 " detec ted f i l e t y p e . Per d e f au l t Debian Vim only loadf i l e t y p e s p e c i f i c

3 " p lug in s .4 i f has (" autocmd")5 f i l e t y p e indent on6 s e t smart indent7 s e t expandtab8 s e t tabstop=49 s e t s o f t t ab s t op=4

10 s e t s h i f tw id th=411 end i f

Pencarian mengabaikan huruf besar atau kecil (incasesensitive).

1 s e t i gno r e ca s e " Do case i n s e n s i t i v e matching

Page 8: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 2. PEMASANGAN 7

Bila kata yang dicari mengandung huruf besar dan huruf kecil, maka penca-rian memperhatikan huruf besar atau kecil (casesensitive).

1 s e t smartcase " Do smart case matching

Aktifkan kedua opsi pencarian di atas, maka pencarian di vim ( menggunak-an perintah slash / ) semakin mudah.

Page 9: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

Bab 3

Hello World!

Anda bisa memulai Python dalam modus interaktif. Nanti kalau source sudahmulai panjang kita simpan dalam �le. Modus interaktif dijalankan di konsole,lalu ketik:

1 $ python

maka sambutannya seperti ini:

1 Python 2 . 6 . 5 ( r265 :79063 , Apr 16 2010 , 1 3 : 5 7 : 4 1 )2 [GCC 4 . 4 . 3 ] on l inux23 Type " help " , " copyr ight " , " c r e d i t s " or " l i c e n s e " f o r more4 i n fo rmat ion .5 >>>

Mulailah dengan yang sederhana, menampilkan sebuah pesan menggunakanperintah print.

1 >>> pr in t ' He l l o World ! '2 Hel lo World !

Gunakan tombol panah atas untuk mengulang perintah sebelumnya, lalu ki-ta coba sedikit salah satu ciri pemgrograman berorientasi objek (object orientedprogramming / OOP).

1 >>> pr in t ' He l l o World ! ' . upper ( )2 HELLO WORLD!3 >>> pr in t ' He l l o World ! ' . lower ( )4 h e l l o world !

'Hello World!' adalah sebuah string, yaitu DATA yang boleh berisi alphanu-meric, boleh terdiri dari huruf dan angka atau karakter lainnya. Contoh di atasmenyebutkan bahwa string tidak hanya berisi data, ia juga memuat FUNGSIyang bernama upper() dan lower(). Dengan demikian 'Hello World!' bukansekedar string, tapi disebut OBJEK string. Inilah ciri objek, memuat data danfungsi.

8

Page 10: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 3. HELLO WORLD! 9

Bingung ? Lupakan dulu pemrograman berorientasi objek. Untuk keluardari modus interaktif tekan Ctrl-D.

3.1 Variabel dan Tipe Datanya

Selain menggunakan kutip tunggal, string juga dapat dibatasi oleh kutip ganda:

1 >>> pr in t "Hari Jum' at "2 Hari Jum' at

Bila string lebih dari satu baris Anda bisa gunakan kutip tiga kali:

1 >>> pr in t """Nama: Bummi Dwi Putera2 . . . Alamat : Bogor3 . . . Hobi : Menggambar"""4 Nama: Bummi Dwi Putera5 Alamat : Bogor6 Hobi : Menggambar

Perhatikan tiga buah titik di atas yang berarti sebuah perintah belum ber-akhir.

Selanjutnya marilah membuat script yang akan menanyakan nama, alamat,dan hobi, lalu menampilkannya kembali di layar. Kali ini kita simpan dalamsebuah �le pegawai.py. Anda bisa gunakan text editor favorit seperti gedit,kate, nano, joe, atau vi.

Listing 3.1: pegawai.py

1 nama = raw_input ( 'Nama: ' )2 alamat = raw_input ( 'Alamat : ' )3 hobi = raw_input ( ' Hobi : ' )4 print 'Nama: ' , nama5 print ' Alamat : ' , alamat6 print ' Hobi : ' , hobi

Setelah disimpan jalankan:

1 $ python pegawai . py

Lalu masukkan data seperti yang diminta:

1 Nama: Bummi Dwi Putera2 Alamat : Bogor3 Hobi : Menggambar

raw_input() adalah fungsi untuk menerima masukkan dari user. Fungsi inimenghasilkan string yang berisi masukkan user tersebut, dan dilimpahkan kevariabel nama, alamat, dan hobi. Anda bisa kembali ke modus interaktif untuksekedar mengetahui tipe data dari variabel nama.

Page 11: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 3. HELLO WORLD! 10

1 >>> nama = raw_input ( 'Nama: ' )2 Nama: Bummi3 >>> pr in t type (nama)4 <type ' s t r '>

Pada script di atas kita mulai mengenal apa yang disebut variabel, yaitunama, alamat, dan hobi. Variabel bisa dikatakan sebagai penampung. Tipedata ketiga variabel di atas adalah string. Mari kita coba tipe data lainnya.

1 >>> a = 32 >>> b = 53 >>> pr in t a + b4 85 >>> pr in t type ( a )6 <type ' int '>

Variabel a dan b bertipe integer alias bilangan bulat. Berikut ini untukbilangan pecahan (�oat).

1 >>> c = 7.22 >>> pr in t type ( c )3 <type ' f l o a t '>

Ya, pemisah bilangan bulat dengan pecahannya adalah dengan titik. Oh ya,Python tergolong ketat dalam hal pengoperasian antar tipe data. Kita tidakdiperkenankan menambahkan string dengan integer.

1 >>> nama = 'Bummi'2 >>> umur = 243 >>> pr in t nama + ' us i a ' + umur + ' tahun '4 Traceback (most r e c ent c a l l l a s t ) :5 F i l e "<std in >", l i n e 1 , in <module>6 TypeError : cannot concatenate ' s t r ' and ' int ' ob j e c t s

Untuk mengatasinya jadikan variabel umur menjadi string:

1 >>> pr in t nama + ' us i a ' + s t r (umur) + ' tahun '2 Bummi us i a 24 tahun

Atau dengan cara lain yg lebih mudah dibaca:

1 >>> pr in t '%s us i a %s tahun ' % (nama , umur)2 Bummi us i a 24 tahun

Meski string tidak bisa ditambah dengan integer, namun string bisa dikalikandengan integer:

1 >>> pr in t ' ab ' * 102 abababababababababab

Kembali ke �le pegawai.py, tidak diperkenankan menulis �tidak rapi�. Co-balah membuat kesalahan di baris terakhir pada �le pegawai.py, yaitu denganmenambahkan dua spasi sebelum print:

Page 12: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 3. HELLO WORLD! 11

1 nama = raw_input ( 'Nama: ' )2 alamat = raw_input ( ' Alamat : ' )3 hobi = raw_input ( ' Hobi : ' )4 pr in t 'Nama: ' , nama5 pr in t 'Alamat : ' , alamat6 pr in t ' Hobi : ' , hobi

Kemudian jalankan:

1 $ python pegawai . py

hasilnya Python protes karena ada indent (menjorok masuk) yang tidakdiperkenankan:

1 $ python pegawai . py2 F i l e "pegawai . py" , l i n e 63 pr in t ' Hobi : ' , hobi4 ^5 Indentat ionError : unexpected indent

Seperti kita lihat, script Python tanpa diawali suatu BEGIN .. END atau{ .. } atau berbagai penanda lainnya sebagai bentuk awal dan akhir program.Baris-baris utama selalu tanpa indent alias rapat kiri. Baris yang memilikiindent berarti dianggap bagian dari sub-blok seperti dalam looping (for) ataukondisi (if).

1 nama = raw_input ( 'Nama: ' )2 alamat = raw_input ( ' Alamat : ' )3 hobi = raw_input ( ' Hobi : ' )4 pr in t 'Nama: ' , nama5 pr in t 'Alamat : ' , alamat6 i f hobi :7 pr in t ' Hobi : ' , hobi

Script di atas berarti jika hobi diisi maka ditampilkan.

3.2 Kondisi

Python punya semacam pedoman dalam hal kondisi (if), dimana jika suatuvariabel ada isinya maka True, jika kosong maka False.

1 i f hobi :2 pr in t ' Hobi : ' , hobi

bisa juga ditulis dengan

1 i f hobi != ' ' :2 pr in t ' Hobi : ' , hobi

Secara tipe data hobi tentulah sebuah string, tapi bagaimana dengan hobi!= � ? Mari kita uji di modus interaktif dimana variabel hobi ada isinya.

Page 13: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 3. HELLO WORLD! 12

Tipe False True (Contoh)

String � 'abc'Integer 0 1Float 0 1.2List [] [10,20,30]

Dictionary {} {'nama': 'Bummi', 'alamat': 'Bogor'}Objek None True

Tabel 3.1: Kondisi False di berbagai tipe data

1 >>> hobi = 'Menggambar '2 >>> hobi != ' '3 True4 >>> hobi == ' '5 False

Lalu cobalah variabel hobi kosong.

1 >>> hobi = ' '2 >>> hobi != ' '3 False4 >>> hobi == ' '5 True

Pahami baik-baik perbedaan keduanya. Perhatikan juga penggunaan karak-ter samadengan dua kali ( == ) yang berarti operasi logika (boolean operation).

1 >>> kosong = hobi == ' '2 >>> pr in t kosong3 True

Kembali ke pegawai.py dimana bila hobi tidak diisi maka program akanmemberikan saran. Salinlah menjadi pegawai1.py seperti berikut ini.

Listing 3.2: pegawai1.py

1 nama = raw_input ( 'Nama: ' )2 alamat = raw_input ( 'Alamat : ' )3 hobi = raw_input ( ' Hobi : ' )4 print 'Nama: ' , nama5 print ' Alamat : ' , alamat6 i f hobi :7 print ' Hobi : ' , hobi8 else :9 print ' Sebaiknya hobi d i i s i . '

else digunakan untuk kondisi sebaliknya (False). Bagaimana jika kondisitambahan ? Misalkan jika hobinya menggambar maka pesan untuk hadir dihari Sabtu ditampilkan.

Page 14: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 3. HELLO WORLD! 13

Listing 3.3: pegawai2.py

1 nama = raw_input ( 'Nama: ' )2 alamat = raw_input ( 'Alamat : ' )3 hobi = raw_input ( ' Hobi : ' )4 print 'Nama: ' , nama5 print ' Alamat : ' , alamat6 i f hobi . upper ( ) == 'MENGGAMBAR' :7 print ' Datanglah d i pe l a t ihan gambar s e t i a p Sabtu . '8 e l i f hobi :9 print ' Hobi : ' , hobi

10 else :11 print ' Sebaiknya hobi d i i s i . '

Perhatikan juga penggunaan titik dua ( : ) pada if dan else. Ini ciri lainuntuk menandai awal suatu sub-blok. Jadi bisa dipastikan setelah titik duabaris berikutnya selalu menjorok ke dalam (indent).

3.3 Perulangan

Mari kita buat input pegawai jadi lebih mudah, dimana program akan mena-nyakan data terus-menerus dan baru berhenti bila nama tidak diisi.

Listing 3.4: pegawai3.py

1 while True :2 nama = raw_input ( 'Nama: ' )3 i f not nama :4 break5 alamat = raw_input ( 'Alamat : ' )6 hobi = raw_input ( ' Hobi : ' )7 print 'Nama: ' , nama8 print ' Alamat : ' , alamat9 i f hobi :

10 print ' Hobi : ' , hobi11 else :12 print ' Sebaiknya hobi d i i s i . '

Perhatikan baris pertama yang berarti perulangan tanpa henti. Yang meng-hentikannya adalah baris ke empat. break adalah kata khusus untuk menghen-tikan perulangan dimana alur keluar menuju blok bawah di luar perulangantersebut. Kebetulan dalam contoh ini tidak ada blok lain di luar perulangan.

Selanjutnya kita buat aturan baru untuk pengisian data ini, dimana:

1. Nama dan alamat harus diisi.

2. Bila selesai satu data pegawai maka program akan menanyakan apakahakan memasukkan data berikutnya.

Page 15: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 3. HELLO WORLD! 14

Di sini akan kita ubah sedikit logika while-nya.

Listing 3.5: pegawai4.py

1 l a n j u t = 'Y '2 while l a n j u t != 'S ' :3 nama = raw_input ( 'Nama: ' )4 i f not nama :5 print 'Nama harus d i i s i . '6 continue7 alamat = raw_input ( 'Alamat : ' )8 i f not alamat :9 print ' Alamat harus d i i s i . '

10 continue11 hobi = raw_input ( ' Hobi : ' )12 print 'Nama: ' , nama13 print ' Alamat : ' , alamat14 i f hobi :15 print ' Hobi : ' , hobi16 else :17 print ' Sebaiknya hobi d i i s i . '18 l a n j u t = raw_input ( 'Tekan "S" j i k a s e l e s a i : ' ) . upper ( )

continue pada baris ke 6 menandakan alur kembali ke while pada baris ke2. Perhatikan juga penggunaan raw_input() pada baris terakhir. Karena fung-si ini mengembalikan nilai string maka kita bisa lanjutkan dengan memanggilfungsi upper(). Dengan cara ini user diperbolehkan memasukkan dengan s kecilmaupun S besar.

while cocok untuk perulangan yang kondisinya �tidak menentu�. Bagaimanabila kita butuh perulangan yang jumlahnya sudah diketahui ? Misalkan cetakangka 1 hingga 5.

1 f o r i in [ 1 , 2 , 3 , 4 , 5 ] :2 pr in t i

Hasilnya:

1

2

3

4

5

Perhatikan [1,2,3,4,5] yang merupakan data bertipe list atau sering juga disebutsebagai array. Kita bisa persingkat penulisannya dengan fungsi range().

1 f o r i in range (5 ) :2 pr in t i

Hasilnya

Page 16: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 3. HELLO WORLD! 15

0

1

2

3

4

Meski tidak dimulai dari 1 tapi jumlah barisnya tetap 5. Jika tetap ingin dimulaidari 1 gunakan range(1,6).

1 f o r i in range (1 , 6 ) :2 pr in t i

Karena for merupakan perulangan juga sebagaimana while, maka perintahbreak dan continue juga berlaku di dalamnya.

Page 17: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

Bab 4

Tipe Data

Memperhatikan tipe data salah satu pokok pada Python dan ini juga menjadisalah satu kunci agar mudah dalam pencarian kesalahan (debugging).

4.1 String

Sudah dibahas sebelumnya bagaimana menuliskan data bertipe string.

1 >>> nama = 'Agus '

Atau bisa juga menggunakan kutip ganda.

1 >>> nama = Agus

Jika Anda butuh kutip tunggal di dalam string, siasatilah.

1 >>> har i = Jum' at

Masih belum yakin apa tipe data variabel nama ? Gunakan type().

1 >>> type (nama)2 <type ' s t r '>

Data bertipe string bisa berisi karakter apa saja seperti huruf, angka, tandabaca, atau gabungannya.

Menggabungkan dua buah variabel string bisa menggunakan tanda plus ( +).

1 >>> pr in t nama + ' l a h i r ha r i ' + har i2 Agus l a h i r ha r i Jum' at

Namun cara ini tidak disarankan karena membuat program menjadi sulitdibaca. Kalau program sulit dibaca menyulitkan penelusuran bila ada kesalahan(debugging). Jadi sebaiknya gunakan formatting.

1 >>> pr in t '%s l a h i r ha r i %s ' % (nama , ha r i )2 Agus l a h i r ha r i Jum' at

16

Page 18: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 4. TIPE DATA 17

Lalu bagaimana menampilkan % itu sendiri di dalam formatting ? Sebutka-nlah dua kali.

1 >>> pr in t 'Keuntungan bulan i n i meningkat %d %%' % (10)2 Keuntungan bulan i n i meningkat 10 %

4.2 Bilangan

Bilangan bulat atau integer atau disingkat int dinyatakan tanpa titik.

1 >>> a = 10

a ditambah 2

1 >>> a + 2

2 12

a dikurang 4

1 >>> a − 42 6

a dikali 5

1 >>> a * 52 50

a dibagi dengan 3

1 >>> a / 32 3

Mengapa bukan 3.3333 ?Pembagian bilangan bulat dengan bilangan bulat menghasilkan bilangan bu-

lat juga. Jika Anda mengharapkan hasil yang lebih rinci maka salah satunyaharus bilangan pecahan (�oat).

1 >>> a / 3 .02 3.3333333333333335

Untuk mendapatkan sisa pembagian (modulus) gunakan tanda persen ( %).

1 >>> a % 32 1

a pangkat 2

1 >>> a ** 22 100

Page 19: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 4. TIPE DATA 18

4.2.1 Konversi Tipe Data

Konversi dari string menjadi bilangan bulat menggunakan fungsi int().

1 >>> in t ( ' 1 0 ' )2 10

int() juga dapat digunakan untuk pembulatan.

1 >>> in t ( 1 0 . 2 )2 10

Untuk pembulatan �yang mendekati� gunakan round().

1 >>> round ( 1 0 . 4 )2 103 >>> round ( 1 0 . 5 )4 11

round() akan membulatkan ke bawah bila pecahan suatu bilangan lebih kecildari 0,5. Sebaliknya ia akan membulatkan ke atas.

Untuk konversi dari string menjadi bilangan pecahan menggunakan fungsi�oat().

1 >>> f l o a t ( ' 1 0 . 5 ' )2 10 .5

4.2.2 Formatting

Menuliskan bilangan ke dalam string bisa menggunakan formatting.

1 >>> a = 32 >>> b = 23 >>> pr in t '%s + %s = %s ' % (a , b , a+b)4 3 + 2 = 5

Meski formatting %s bisa digunakan untuk tipe data apa saja, sebaiknyaAnda menggunakan formatting yang lebih spesi�k sesuai tipe datanya. Kata-kanlah Anda menetapkan bahwa variabel a itu harus bertipe bilangan bulat(integer), begitu pula dengan variabel b, maka gunakanlah %d.

1 >>> pr in t '%d + %d = %d ' % (a , b , a+b)2 3 + 2 = 5

Untuk bilangan pecahan (�oat) gunakan %f.

1 >>> a = 3.52 >>> pr in t '% f + %f = %f ' % (a , b , a+b)3 3.500000 + 2.000000 = 5.500000

Anda juga bisa mengatur jumlah digit di belakang koma.

1 >>> print '%.2f + %.2f = %.2f' % (a, b, a+b)

2 3.50 + 2.00 = 5.50

Page 20: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 4. TIPE DATA 19

4.2.3 Kalkulator

Membuat kalkulator tidaklah sulit, Anda cukup gunakan eval(). Buatlah �lecalc.py berikut ini.

Listing 4.1: calc.py

1 while True :2 hitung = raw_input ( ' Hitung : ' )3 i f not hitung :4 break5 print eva l ( hitung )

Jalankan.

1 $ python ca l c . py2 Hitung : 2+33 54 Hitung : 7**25 496 Hitung : 7 + 2 * 37 138 Hitung :9 $

Perhatikan baik-baik. Semua kalimat Python diterjemahkan oleh eval(), baikkalimat itu mengandung spasi ataupun tidak, eval() sanggup memahaminya.Mudah bukan?

Perhatikan juga kalimat 7 + 2 * 3 yang menghasilkan nilai 13. Ini artinyaaturan prioritas pada matematika umum berlaku, dimana perkalian lebih duludilakukan ( 2 * 3 ). Barulah hasilnya ( 6 ) ditambahkan dengan 7.

Program di atas akan terus meminta masukkan dari user hingga tombolEnter saja yang ditekan.

4.3 List

Tipe data list kerap digunakan. Kita lihat pada contoh sebelumnya bagaimanalist menjadi wajib pada perulangan for. Bahkan string sebenarnya bisa dianggapsebagai list.

1 f o r ch in 'Bummi ' :2 pr in t ch ,

hasilnya:

1 Bummi

Perhatikan penggunaan koma pada print yang berarti �jangan ganti baris�.Mari kembali ke modus interaktif untuk mencoba list.

Page 21: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 4. TIPE DATA 20

Gambar 4.1: Struktur list

1 >>> data = [ 'Bummi Dwi Putera ' , ' Bogor ' , ' Menggambar ' , 2 4 ]2 >>> pr in t data [ 0 ]3 'Bummi Dwi Putera '4 >>> pr in t data [ 1 ]5 ' Bogor '

Tampilkan elemen terakhir:

1 >>> pr in t data [−1]2 24

Elemen kedua dari terakhir:

1 >>> pr in t data [−2]2 'Menggambar '

4.3.1 Pemenggalan

Selain dapat diambil per elemen, juga dapat diambil beberapa elemen sekali-gus, ini disebut sebagai pemenggalan (slicing). Tampilkan elemen pertama dankedua:

1 >>> pr in t data [ 0 : 2 ]2 [ 'Bummi Dwi Putera ' , ' Bogor ' ]

Atau cukup ditulis tanpa 0:

1 >>> pr in t data [ : 2 ]2 [ 'Bummi Dwi Putera ' , ' Bogor ' ]

Tampilkan 3 elemen terakhir:

1 >>> pr in t data [ −3 : ]2 [ ' Bogor ' , 'Menggambar ' , 24 ]

Ada baiknya kita pahami cara kerjanya. Pemenggalan list bekerja denganbatas elemen. Gambar 4.1 adalah contoh string Python yang bisa dianggapsebagai list. Cermati baik-baik bagaimana bekerja dengan elemen dan bataselemen (untuk pemenggalan).

Page 22: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 4. TIPE DATA 21

4.3.2 Keberadaan Elemen

Anda memiliki daftar nama buah yang dapat dicari oleh user. Setelah usermemasukkan nama buah program akan mencarinya dalam list dan memberi-tahukan hasilnya. Setelah itu program akan kembali menanyakan nama buahberikutnya. Program berakhir jika user hanya menekan Enter saja, alias tidakmemasukkan apapun. Sekarang buatlah produk.py berikut ini.

Listing 4.2: produk.py

1 da f t a r = [ ' j e ruk ' , 'mangga ' , ' ape l ' , ' p i sang ' , ' jambu ' ]2

3 while True :4 c a r i = raw_input ( ' Cari buah : ' )5 i f not c a r i :6 print ' S e l e s a i '7 break8 i f c a r i in da f t a r :9 print ( 'Ditemukan ' )

10 else :11 print ( ' Tidak ditemukan ' )

Jalankanlah.

1 $ python produk . py2 Cari buah : mangga3 Ditemukan4 Cari buah : duku5 Tidak ditemukan6 Cari buah :7 S e l e s a i

Keberadaan elemen bisa digunakan sebagai kondisi. Misalkan program Andadapat menerima masukan (input parameter) sesaat sebelum dijalankan, seringdisebut sebagai argument. Seperti pada contoh cat.py berikut ini.

Listing 4.3: cat.py

1 import sys2 print sys . argv

Jalankanlah.

1 $ python cat . py2 [ ' cat . py ' ]

Jalankan lagi dengan input parameter.

1 $ python cat . py / e tc / hos t s2 [ ' cat . py ' , '/ e t c / hosts ' ]

Perhatikan elemen pertama adalah �le cat.py itu sendiri, dan elemen keduaadalah nama �le yang akan ditampilkan. Ya, kita akan membuatnya dapatmembuka �le yang disebutkan dan menampilkannya di layar.

Page 23: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 4. TIPE DATA 22

Listing 4.4: cat1.py

1 import sys2

3 f i l ename = sys . argv [ 1 ]4 f = open ( f i l ename )5 print f . read ( )6 f . c l o s e ( )

Jalankan.

1 $ python cat1 . py / e tc / hos t s2 1 2 7 . 0 . 0 . 1 l o c a l h o s t compaq3 1 2 7 . 0 . 1 . 1 compaq4

5 # The f o l l ow i ng l i n e s are d e s i r a b l e f o r IPv6 capablehos t s

6 : : 1 l o c a l h o s t ip6−l o c a l h o s t ip6−loopback7 f e00 : : 0 ip6−l o c a l n e t8 f f 0 0 : : 0 ip6−mcastpre f ix9 f f 0 2 : : 1 ip6−a l l n od e s

10 f f 0 2 : : 2 ip6−a l l r o u t e r s11 f f 0 2 : : 3 ip6−a l l h o s t s

Kita perlu mengantisipasi kesalahan yang dilakukan user, dimana bisa sajaia tidak tahu cara menggunakan cat1.py, yaitu langsung menjalankan tanpamenyertakan nama �le.

1 $ python cat1 . py2 Traceback (most r e c ent c a l l l a s t ) :3 F i l e " cat . py" , l i n e 3 , in <module>4 f i l ename = sys . argv [ 1 ]5 IndexError : l i s t index out o f range

Tampilan kesalahan ini jelas kurang informatif dan bisa jadi user tidak tahuapa yang harus dilakukan. Saatnya menggunakan deteksi keberadaan elemen.

Listing 4.5: cat2.py

1 import sys2

3 i f not sys . argv [ 1 : ] :4 print ( ' Cara menggunakannya : python %s <nama− f i l e >' %

sys . argv [ 0 ] )5 sys . e x i t ( )6

7 f i l ename = sys . argv [ 1 ]8 f = open ( f i l ename )9 print f . read ( )

10 f . c l o s e ( )

Page 24: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 4. TIPE DATA 23

Jalankanlah tanpa input parameter,

1 $ python cat2 . py2 Cara menggunakannya : python cat . py <nama− f i l e >

Kini program akan menampilkan petunjuk cara menggunakannya. Mari kitabahas cara kerjanya.

Perhatikan baris ketiga

if not sys.argv[1:]:

Kalau kita perhatikan lagi isi dari sys.argv pada saat tidak diberikan inputparameter adalah:

['cat.py']

Dengan begitu sys.argv[1:] akan bernilai list hampa:

[]

Ingatlah mengenai pemenggalan list pada pembahasan sebelumnya. Bila suatuvariabel hampa maka ia bisa dianggap sebagai boolean False, sehingga

if not sys.argv[1:]:

bisa berarti

if not []:

yang berarti

if not False:

dan ini bisa diartikan menjadi:

if True:

True berarti kondisi terpenuhi dan blok di dalam if dijalankan, dan akhirnyatampillah pesan cara penggunaan cat2.py tadi.

Lalu apa yang terjadi jika program mendapat input parameter ? Nilaisys.argv menjadi

['cat.py', '/etc/hosts']

Dengan begitu

if not sys.argv[1:]:

bisa berarti

if not ['/etc/hosts']:

Page 25: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 4. TIPE DATA 24

Karena ['/etc/hosts'] adalah list yang berisi (tidak hampa) maka bisa dianggapsebagai boolean True

if not True:

dan ini berarti juga

if False:

False berarti kondisi tidak terpenuhi sehingga blok di dalam if tidak dijalankan.Pahamilah baik-baik penjelasan ini, Anda akan banyak menemuinya nanti.

Inilah salah satu mengapa program yang dibuat dengan Python begitu ringkasnamun tetap mudah dibaca.

4.3.3 Mengubah Elemen

Contoh sebelumnya menjelaskan bagaimana menggunakan list. Kini kita cobaberawal dari list hampa dan mengisinya dengan elemen data. Kembali ke modusinteraktif.

1 >>> da f ta r = [ ]2 >>> da f ta r3 [ ]

Tambahkan mangga.

1 >>> da f ta r . append ( 'mangga ' )2 >>> da f ta r3 [ ' mangga ' ]

Bisa juga dengan cara lain.

1 >>> da f ta r += [ ' pisang ' ]2 >>> da f ta r3 [ ' mangga ' , ' pisang ' ]

Kita akan ubah elemen kedua (index ke 1) dari pisang menjadi jeruk.

1 >>> da f ta r [ 1 ] = ' jeruk '2 >>> da f ta r3 [ ' mangga ' , ' jeruk ' ]

Selanjutnya mangga dihapus yang berarti elemen pertama atau index ke 0.

1 >>> de l da f t a r [ 0 ]2 >>> da f ta r3 [ ' j eruk ' ]

Page 26: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 4. TIPE DATA 25

4.4 Dictionary

List adalah serangkaian elemen yang �alamatnya� adalah nomor urut, seringdisebut sebagai index. Dictionary juga mirip, hanya saja alamatnya tidak ha-rus berupa angka yang berurutan. Bahkan bisa bertipe string atau tipe datalainnya. Sekarang buatlah script berikut ini.

Listing 4.6: produk1.py

1 da f t a r = {2 2 : ' j e ruk ' ,3 7 : 'mangga ' ,4 4 : ' p i sang ' ,5 3 : ' jambu ' ,6 9 : ' ape l ' ,7 }8

9 print da f t a r

Jalankan.

1 $ python produk1 . py2 {9 : ' apel ' , 2 : ' jeruk ' , 3 : ' jambu ' , 4 : ' pisang ' , 7 : '

mangga ' }

Perhatikan urutan pada source, dan bandingkan urutan buah saat ditam-pilkan. Begitulah dictionary, dia memang tidak memperhatikan urutan. Inilahsalah satu yang membedakannya dengan list. Dictionary cocok untuk pencari-an. Pada contoh di atas angka 2, 7, 4, 3, dan 9 merupakan kunci (key) bagivariabel daftar. Key ini bisa saja dianggap sebagai kode barang atau kode bu-ah. Sedangkan apel, jeruk, jambu, pisang, dan mangga merupakan nilai (value).Karena itu dictionary sering disebut sebagai tipe data dengan formasi key value.

Sekarang kita buat pencarian berdasarkan kode barang.

Listing 4.7: produk2.py

1 da f t a r = {2 2 : ' j e ruk ' ,3 7 : 'mangga ' ,4 4 : ' p i sang ' ,5 3 : ' jambu ' ,6 9 : ' ape l ' ,7 }8

9 while True :10 key = raw_input ( 'Kode barang : ' )11 i f not key :12 print ' S e l e s a i '13 break14 i f key in da f t a r :

Page 27: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 4. TIPE DATA 26

15 print da f t a r [ key ]16 else :17 print 'Kode barang ' , key , ' t idak ditemukan '

Cobalah.

1 $ python produk2 . py2 Kode barang : 53 Kode barang 5 t idak ditemukan4 Kode barang : 95 Kode barang 9 t idak ditemukan6 Kode barang :7 S e l e s a i

Kode barang 5 boleh jadi tidak ditemukan, karena memang tidak ada 5dalam variabel daftar. Tapi mengapa 9 juga tidak ditemukan ? Seharusnyaprogram menampilkan apel.

Jawabannya ada pada tipe data. Fungsi raw_input() itu mengembalikannilai bertipe string. Berarti key pada baris

key = raw_input('Kode barang: ')

juga bertipe string. Lalu

if key in daftar:

berarti mencari string key dalam daftar yang isinya bilangan bulat (integer)semua, yaitu 2, 7, 4, 3, dan 9. Jelas tidak akan ditemukan. Untuk membuktikanbahwa key itu adalah string ubahlah sedikit pada baris terakhir

print 'Kode barang', key, 'tidak ditemukan'

menjadi

print 'Kode barang', [key], 'tidak ditemukan'

Coba jalankan lagi.

1 $ python produk2 . py2 Kode barang : 93 Kode barang [ ' 9 ' ]4 t idak ditemukan5 Kode barang :6 S e l e s a i

Dengan memberikan kurung siku pada variabel maka akan tampak bahwakey adalah string. Terlihat adanya kutip tunggal pada '9'. Lalu bagaimanamengubah key agar bertipe integer ? Gunakan fungsi int().

Page 28: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 4. TIPE DATA 27

Listing 4.8: produk3.py

1 da f t a r = {2 2 : ' j e ruk ' ,3 7 : 'mangga ' ,4 4 : ' p i sang ' ,5 3 : ' jambu ' ,6 9 : ' ape l ' ,7 }8

9 while True :10 key = raw_input ( 'Kode barang : ' )11 i f not key :12 print ' S e l e s a i '13 break14 key = in t ( key )15 i f key in da f t a r :16 print da f t a r [ key ]17 else :18 print 'Kode barang ' , key , ' t idak ditemukan '

Jalankan lagi.

1 $ python produk3 . py2 Kode barang : 53 Kode barang [ 5 ] t idak ditemukan4 Kode barang : 95 ape l6 Kode barang :7 S e l e s a i

Resapi kembali mengenai tipe data ini karena akan sering dijumpai nanti.

4.5 Waktu

Modul time digunakan untuk penanganan waktu. Kita kembali ke modus inte-raktif dulu untuk memudahkan latihan.

1 >>> import time2 >>> t = time . l o c a l t ime ( )3 >>> t4 time . struct_time ( tm_year=2010 , tm_mon=8, tm_mday=20,

tm_hour=11, tm_min=44, tm_sec=47, tm_wday=4, tm_yday=232 , tm_isdst=0)

Fungsi time.localtime() digunakan untuk mendapatkan waktu saat ini. Per-hatikan variabel t di atas. Jika Anda ingin mengambil tahunnya:

1 >>> t . tm_year2 2010

Page 29: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 4. TIPE DATA 28

atau bulannya

1 >>> t .tm_mon2 8

atau harinya

1 >>> t . tm_mday2 20

dan seterusnya hingga jam, menit, dan detiknya, ada di sana.Waktu juga bisa diwujudkan dalam bilangan pecahan (�oat), sering disebut

sebagai epoch atau Unix time.

1 >>> time . time ( )2 1282280699.2280381

Epoch ini adalah jumlah detik sejak 1 Januari 1970 jam 00:00:00 (GMT)hingga saat ini.

Fungsi time.localtime() sebenarnya bisa diberikan masukan berupa epochini. Kita bisa mulai dengan angka 0.

1 >>> time . l o c a l t ime (0 )2 time . struct_time ( tm_year=1970 , tm_mon=1, tm_mday=1,

tm_hour=7, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=1,tm_isdst=0)

Epoch 0 berarti 1 Januari 1970. Lalu mengapa tm_hour menunjukkan angka7 ? Ini terkait dengan zona waktu (timezone) pada komputer yang berartiwilayah Jakarta (+7). Jika komputer Anda diset pada zona waktu Bali makanilai tm_hour menjadi 8.

Untuk mendapatkan epoch pada tanggal 17 Agustus 2010 maka bisa gunakantime.mktime():

1 >>> time . mktime ( (2010 , 8 , 17 , 0 , 0 , 0 , 0 , 0 , 0 ) )2 1281978000.0

Dengan epoch kita bisa mendapatkan jumlah hari sejak 1 Agustus 2010hingga 17 Agustus 2010.

1 >>> awal = time . mktime ( (2010 , 8 , 1 , 0 , 0 , 0 , 0 , 0 , 0 ) )2 >>> akhi r = time . mktime ( (2010 , 8 , 17 , 0 , 0 , 0 , 0 , 0 , 0 ) )3 >>> akhi r − awal4 1382400.0

Itu adalah jumlah detiknya. Untuk mendapatkan hari kita perlu mengolah-nya kembali.

1 >>> ( akh i r − awal ) / 24 / 60 / 602 16 .0

Sehingga diperoleh 16 hari.

Page 30: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 4. TIPE DATA 29

Modul datetime

Menghitung hari lebih mudah menggunakan modul datetime.

1 >>> from datet ime import date2 >>> awal = date (2010 ,8 ,1 )3 >>> akhi r = date (2010 ,8 ,17)4 >>> d = akhi r − awal5 >>> d . days6 16

Dengan modul ini kita juga dapat menghitung jumlah detik sejak 16 Agustus2010 jam 22:00 hingga 17 Agustus 2010 jam 10:00.

1 >>> from datet ime import datet ime2 >>> awal = datet ime (2010 ,8 , 16 , 22 , 0 , 0 )3 >>> akhi r = datet ime (2010 ,8 , 17 ,10 ,0 , 0 )4 >>> d = akhi r − awal5 >>> d . seconds6 43200

Untuk mendapatkan jumlah jamnya:

1 >>> d . seconds / 60 / 602 12

Page 31: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

Bab 5

Modularitas

Mari kita buat program yang menghitung nilai faktorial. Apa itu faktorial ?Berikut ini contohnya:

5! = 5 * 4 * 3 * 2 * 1 = 120

4! = 4 * 3 * 2 * 1 = 24

3! = 3 * 2 * 1 = 6

2! = 2 * 1 = 2

1! = 1

0! = 1

-1! = 1

Dengan demikian rumus faktorial memiliki ketentuan:

1. Jika n < 2 maka n! = 1

2. n! = n * (n-1)!

Selanjutnya kita akan buat program yang akan menanyakan nilai n dan menam-pilkan nilai faktorial-nya.

Listing 5.1: faktorial1.py

1 print 'Menghitung n i l a i f a k t o r i a l '2 while True :3 n = raw_input ( 'n = ' )4 i f not n :5 break6 n = in t (n)7 i f n < 2 :8 f = 19 else :

10 f = 111 for i in range (1 , n+1) :12 f = f * i13 print '%d ! = %d ' % (n , f )

30

Page 32: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 5. MODULARITAS 31

Jalankan.

1 $ python f a k t o r i a l 1 . py2 Menghitung n i l a i f a k t o r i a l3 n = 24 2 ! = 25 n = 36 3 ! = 67 n = 48 4 ! = 249 n =

10 $

Selesai sudah. Berikutnya Anda diminta membuatnya dalam lingkungangra�s (graphical user interface / GUI). Tentu saja tidak ada lagi yang namanyaraw_input() dan print, karena ia digunakan untuk lingkungan teks (console).Juga tidak ada lagi while karena GUI sudah mengatur perulangannya.

Lalu apa yang diambil untuk mengambil source faktorial ? Baris 6 - 12saja yang perlu di-copy-paste di source GUI nanti. Anda juga harus menye-suaikan variabel n yang menjadi masukannya, karena n tidak lagi berasal dariraw_input() melainkan dari komponen GUI.

Di sini mulai terasa source faktorial di atas tidak modular karena menyu-litkan copy-paste. Kesulitan yang dimaksud adalah source faktorial menyatudengan source yang mengurus tampilan. Faktorial adalah contoh sederhana,bagaimana kalau nanti Anda diminta membuat rumus lainnya yang jauh lebihrumit ?

5.1 Membuat Fungsi

Sudah saatnya Anda mengenal pembuatan fungsi. Dengannya Anda pisahkanurusan menghitung nilai faktorial dengan urusan input dan output tampilannya.

Listing 5.2: faktoria2l.py

1 def f a k t o r i a l (n ) :2 i f n < 2 :3 return 14 f = 15 for i in range (1 , n+1) :6 f = f * i7 return f8

9

10 print 'Menghitung n i l a i f a k t o r i a l '11 while True :12 n = raw_input ( 'n = ' )13 i f not n :

Page 33: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 5. MODULARITAS 32

14 break15 n = in t (n)16 h a s i l = f a k t o r i a l (n )17 print '%d ! = %d ' % (n , h a s i l )

Jalankan.

1 $ python f a k t o r i a l 2 . py2 Menghitung n i l a i f a k t o r i a l3 n = 54 5 ! = 1205 n = 26 2 ! = 27 n = 18 1 ! = 19 n = −1

10 −1! = 111 n =

Hasilnya memang sama saja, namun kini source faktorial lebih mudah dibacadan di-copy-paste. Perhatikan juga penggunaan return yang membuat alurkeluar dari fungsi.

Apa ini sudah cukup modular ? Jawabannya belum.

5.2 Membuat Modul

Copy-paste source seperti itu tentu saja lebih sulit ketimbang copy-paste �le-nya. Oleh karena itu Anda perlu membuat source itu menjadi modul faktorialyang berarti namanya menjadi faktorial.py sehingga program lain yang mem-butuhkannya cukup menggunakannya seperti ini (contoh):

1 from f a k t o r i a l import f a k t o r i a l2 n = 53 pr in t f a k t o r i a l (n )

Sekarang buatlah faktorial.py.

Listing 5.3: faktorial.py

1 def f a k t o r i a l ( a ) :2 i f a < 2 :3 return 14 for i in range (1 , a ) :5 a = a * i6 return a

Lalu buatlah cobafaktorial.py yang menggunakan modul faktorial ini.

Listing 5.4: cobafaktorial.py

1 from f a k t o r i a l import f a k t o r i a l

Page 34: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 5. MODULARITAS 33

2

3 print 'Menghitung n i l a i f a k t o r i a l '4 while True :5 n = raw_input ( 'n = ' )6 i f not n :7 break8 n = in t (n)9 h a s i l = f a k t o r i a l (n )

10 print '%d ! = %d ' % (n , h a s i l )

Jalankan.

1 $ python c oba f a k t o r i a l . py2 Menghitung N i l a i Fak to r i a l3 n = 54 5 ! = 1205 n = 26 2 ! = 27 n =

Hasilnya tetap sama, namun kini Anda lebih mudah copy-paste source fungsifaktorial() karena cukup faktorial.py yang di-copy ke direktori program lainnya.

Untuk mencoba modul faktorial Anda perlu membuat �le lainnya yaitu co-bafaktorial.py. Agar lebih praktis, mengapa tidak disatukan saja ?

Benar, alangkah praktisnya jika source untuk menguji fungsi faktorial() jugaberada di �le yang sama.

Namun Anda perlu membuat sedikit perubahan agar saat

from faktorial import faktorial

source uji coba tersebut tidak dijalankan. Silahkan ubah faktorial.py menjadiberikut ini.

Listing 5.5: faktorial.py

1 def f a k t o r i a l ( a ) :2 i f a < 2 :3 return 14 for i in range (1 , a ) :5 a = a * i6 return a7

8 i f __name__ == '__main__ ' :9 print 'Menghitung n i l a i f a k t o r i a l '

10 while True :11 n = raw_input ( 'n = ' )12 i f not n :13 break14 n = in t (n)

Page 35: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 5. MODULARITAS 34

15 h a s i l = f a k t o r i a l (n )16 print '%d ! = %d ' % (n , h a s i l )

Perhatikan bahwa __name__ adalah name yang diawali dan diakhiri olehdua underscore. Begitu juga dengan __main__. Kemudian jalankan.

1 $ python f a k t o r i a l . py2 Menghitung n i l a i f a k t o r i a l3 n = 34 3 ! = 65 n = 46 4 ! = 247 n =

Jadi perubahannya adalah pada

if __name__ == '__main__':

Dengan baris ini Python diberitahu bahwa source dibawahnya hanya dijalankanjika faktorial.py merupakan program utama. Kalau faktorial.py sebagai modulmaka ia tidak dijalankan.

Anda juga masih bisa menggunakan cobafaktorial.py seperti biasa.

1 $ python c oba f a k t o r i a l . py

5.3 Search Path

Meng-copy faktorial.py ke berbagai direktori program yang membutuhkan tentusaja merepotkan. Apalagi bila ada perubahan source pada faktorial.py, makaAnda harus menyebarkannya lagi.

Ada banyak direktori dimana Python akan mencari modul yang dipang-gil. Untuk mengetahui direktori mana saja yang terdaftar gunakan variabelsys.path. Masuklah ke modus interaktif untuk melihatnya.

1 >>> import sys2 >>> sys . path3 [ ' ' ,4 '/ usr / l i b /python2 . 6 ' ,5 '/ usr / l i b /python2 .6/ plat−l inux2 ' ,6 '/ usr / l i b /python2 .6/ l i b−tk ' ,7 '/ usr / l i b /python2 .6/ l i b−old ' ,8 '/ usr / l i b /python2 .6/ l i b−dynload ' ,9 '/ usr / l i b /python2 .6/ d i s t−packages ' ,

10 '/ usr / l i b /python2 .6/ d i s t−packages /PIL ' ,11 '/ usr / l i b /python2 .6/ d i s t−packages / gst −0.10 ' ,12 '/ usr / l i b /pymodules/python2 . 6 ' ,13 '/ usr / l i b /python2 .6/ d i s t−packages /gtk −2.0 ' ,14 '/ usr / l i b /pymodules/python2 .6/ gtk −2.0 ' ,15 '/ usr / l o c a l / l i b /python2 .6/ d i s t−packages ' ]

Page 36: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 5. MODULARITAS 35

Pertama kali Python akan mencari di direktori dimana program utama ber-ada. Selanjutnya ia akan mencari di direktori lainnya seperti yang Anda lihatdi atas.

Lalu dimana sebaiknya faktorial.py diletakkan ? Karena meletakkannya ti-dak melalui instalasi paket Debian, maka saya sarankan diletakkan di direktori

/usr/local/lib/python2.6/dist-packages

Anda bisa menyalinnya menggunakan perintah

1 $ sudo cp f a k t o r i a l . py / usr / l o c a l / l i b /python2 .6/ d i s t−packages

Supaya lebih yakin pindahkan sekalian.

1 $ sudo mv f a k t o r i a l . py / usr / l o c a l / l i b /python2 .6/ d i s t−packages

Jika Anda punya direktori lain, Anda bisa tambahkan pada sys.path terlebihdahulu sebelum import.

1 >>> import sys2 >>> sys . path . append ( '/home/ sugiana / l i b ' )3 >>> from f a k t o r i a l import f a k t o r i a l

Page 37: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

Bab 6

Fungsi

6.1 Memanggil Dirinya Sendiri

Fungsi faktorial() sudah bekerja dengan baik. Tapi mungkin source-nya terlalupanjang. Cobalah ubah menjadi seperti di bawah ini pada faktorial.py.

1 de f f a k t o r i a l ( a ) :2 i f a < 2 :3 re turn 14 re turn a * f a k t o r i a l ( a−1)

Jauh lebih e�sien bukan? Teknik seperti ini disebut juga sebagai rekursif.Pertama kali yang harus diperhatikan dalam pembuatan fungsi rekursif ada-

lah batas kedalaman. Batas ini ditunjukkan pada baris 2-3. Rekursif yang tidakmemiliki batas kedalaman akan menampilkan pesan kesalahan.

6.2 Format Uang

Untuk menampilkan uang biasanya ada pemisah ribuannya. Untuk Indonesiapemisah ribuan adalah titik, sedangkan pemisah pecahan adalah koma. Untukkebutuhan tersebut kita bisa gunakan modul locale.

1 >>> import l o c a l e2 >>> l o c a l e . s e t l o c a l e ( l o c a l e .LC_ALL, ' id_ID .UTF−8 ')3 ' id_ID .UTF8'4 >>> l o c a l e . format ( '%.2 f ' , 10000 , True )5 ' 10 . 000 , 00 '

Jika pecahannya tidak ingin ditampilkan:

1 >>> l o c a l e . format ( '%.0 f ' , 10000 , True )2 ' 1 0 . 000 '

Namun jika saat setlocale Anda menjumpai pesan kesalahan seperti ini:

36

Page 38: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 6. FUNGSI 37

1 Traceback (most r e c ent c a l l l a s t ) :2 F i l e "<std in >", l i n e 1 , in <module>3 F i l e "/ usr / l i b /python2 .6/ l o c a l e . py" , l i n e 513 , in

s e t l o c a l e4 re turn _se t l o ca l e ( category , l o c a l e )5 l o c a l e . Error : unsupported l o c a l e s e t t i n g

Berarti Anda perlu memasang format id_ID.UTF-8 pada sistem. Keluarlahdari modus interaktif dan jalankan:

1 $ sudo l o c a l e−gen id_ID .UTF−82 Generating l o c a l e s . . .3 id_ID .UTF−8 . . . up−to−date4 Generation complete .

Kalau sudah cobalah kembali contoh pemisah ribuan di atas.Kini saatnya membuat fungsi untuk menampilkan nilai uang ini. Kita na-

makan dengan uang(). Fungsi ini akan menerima dua masukan:

1. Nilai uang yang akan ditampilkan

2. Jumlah digit pecahan yang akan ditampilkan, default-nya adalah 2 digitpecahan.

Karena uang() adalah fungsi umum yang akan banyak digunakan di berbagaiprogram, ada baiknya kita simpan sebagai modul bernama uang.py.

Listing 6.1: uang.py

1 import l o c a l e2 l o c a l e . s e t l o c a l e ( l o c a l e .LC_ALL, ' id_ID .UTF−8 ' )3

4

5 def uang ( n i l a i , pecahan=2) :6 return l o c a l e . format ( '%%.%df ' % pecahan , n i l a i , True )7

8

9 i f __name__ == '__main__ ' :10 print uang (10000)11 print uang (10000 . 3 )12 print uang (10000 . 5 , 0 )

Cobalah.

1 $ python uang . py2 10 .000 ,003 10 .000 ,304 10 .000

Perhatikan bagian

'%%.%df' % pecahan

Page 39: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 6. FUNGSI 38

Itu adalah formatting seperti yang dijelaskan di halaman 16.Butuh fungsi yang lebih cerdas ? Misalkan dengan sifat seperti ini:

1. Jika pecahan tidak disebutkan maka modus otomatis berlaku. Otomatisyang dimaksud adalah bila tipe data variabel nilai adalah bilangan bulat(integer) maka pecahan tidak ditampilkan. Selain kondisi itu berarti di-anggap bilangan pecahan (�oat) maka pecahan ditampilkan sebanyak 2digit.

2. Selain kondisi di atas maka nilai uang ditampilkan seperti biasa sesuaijumlah pecahan yang disebutkan.

Masih di uang.py.

Listing 6.2: uang.py

1 import l o c a l e2 l o c a l e . s e t l o c a l e ( l o c a l e .LC_ALL, ' id_ID .UTF−8 ' )3

4

5 def uang ( n i l a i , pecahan=None ) :6 i f pecahan i s None :7 i f type ( n i l a i ) == type (0 ) :8 pecahan = 09 else :

10 pecahan = 211 return l o c a l e . format ( '%%.%df ' % pecahan , n i l a i , True )12

13

14 i f __name__ == '__main__ ' :15 print uang (10000)16 print uang (10000 . 3 )17 print uang (10000 . 5 , 4 )

Jalankan lagi.

$ python uang.py

10.000

10.000,30

10.000,5000

Cermatilah baik-baik hasilnya. Di sini kita sudah mengenal fungsi yang memilikidua masukan dan juga memiliki nilai default pada salah satu masukannya. Jugaada objek hampa bawaan Python bernama None.

Rasanya fungsi uang kurang lengkap bila tidak disertai dengan mata uang-nya. Kita akan jalankan skenario berikut ini:

1. Fungsi uang diberi satu masukan baru yaitu variabel tanda untuk memberikesempatan programmer memasukkan mata uang seperti Rp, $, dst.

Page 40: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 6. FUNGSI 39

2. Bila variabel tanda tidak diisi maka mata uang diambil dari sistem, meng-gunakan module locale.

Listing 6.3: uang.py

1 import l o c a l e2 l o c a l e . s e t l o c a l e ( l o c a l e .LC_ALL, ' id_ID .UTF−8 ' )3 from types import IntType4

5

6 def r ibu ( n i l a i , pecahan=None) :7 i f pecahan i s None :8 i f type ( n i l a i ) == IntType :9 pecahan = 0

10 else :11 pecahan = 212 return l o c a l e . format ( '%%.%df ' % pecahan , n i l a i , True )13

14 def uang ( n i l a i , pecahan=None , tanda=None ) :15 i f tanda i s None :16 tanda = l o c a l e . l o c a l e conv ( ) [ ' currency_symbol ' ]17 return '%s%s ' % ( tanda , r ibu ( n i l a i , pecahan ) )18

19

20 i f __name__ == '__main__ ' :21 print r ibu (10000)22 print r ibu (10000 . 3 )23 print r ibu (10000 .5 , 4)24 print uang (10000 . 7 )25 print uang (10000 .7 , 2 , ' $ ' )26 print uang (10000 .7 , tanda=' $ ' )

Perhatikan fungsi tambahan ribu(). Fungsi ini sebenarnya salinan dari fungsiuang() sebelumnya. Mengapa tidak langsung mengubah fungsi uang() sepertibiasanya ?

Tujuannya adalah kita tidak ingin mengganggu algoritma yang sudah ber-jalan baik itu. Sehingga bila ada kekeliruan pada algoritma di uang(), areapencarian kesalahan bisa diminimalisir.

Perhatikan juga baris terakhir,

print uang(10000.7, tanda='$')

dimana kita melewatkan variabel kedua, yaitu pecahan pada fungsi uang(),

def uang(nilai, pecahan=None, tanda=None):

Python tidak mempermasalahkan variabel pecahan dilewatkan, karena variabelini telah diberi nilai default yaitu None.

Page 41: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 6. FUNGSI 40

Karena modul uang ini merupakan modul umum yang bisa digunakan olehbanyak aplikasi, maka letakkanlah uang.py di /usr/local/lib/python2.6/dist-packages agar bisa digunakan oleh program lainnya. Lalu uji keberadaannya dimodus interaktif.

1 >>> from uang import uang2 >>> uang (10000)3 ' 1 0 . 000 '

Page 42: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

Bab 7

Database

Database atau penyimpan data biasa digunakan untuk aplikasi bisnis sepertikasir (point of sales), accounting, payroll, dsb.

Pasanglah

1 $ sudo apt−get i n s t a l l p o s t g r e s q l

Superuser di PostgreSQL adalah postgres. Nama ini tercantum di sistem Li-nux maupun di sistem PostgreSQL itu sendiri. Pasca pemasangan user postgrestidak memiliki password. Jadi gunakanlah sudo:

1 $ sudo su

Masukkan password user yang Anda gunakan ketika login pertama kali. KiniAnda telah menjadi root, dan mulailah sebagai user postgres:

1 # su − pos tg r e s

Kini Anda sudah menjadi user postgres. Menurut ketentuan default, bilauser Linux dan user PostgreSQL sama maka tidak perlu password untuk loginke PostgreSQL server. Sekarang mulailah membuat user database:

1 $ c r e a t eu s e r −P ilham2 Enter password f o r new r o l e :3 Enter i t again :4 Sha l l the new r o l e be a superuse r ? ( y/n) n5 Sha l l the new r o l e be a l lowed to c r e a t e databases ? ( y/n)

n6 Sha l l the new r o l e be a l lowed to c r e a t e more new r o l e s ? (

y/n) n

Isilah password dengan 1234. Saat diketik password tidak akan ditampilk-an. Selebihnya user ilham ini tidak dizinkan sebagai superuser, tidak diizinkanmembuat database, dan tidak diizinkan membuat user.

Untuk menghapusnya:

1 $ dropuser ilham

41

Page 43: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 7. DATABASE 42

Selanjutnya membuat database:

1 $ createdb −O ilham to t a l i ndo

Ini artinya kita membuat database bernama totalindo yang dimiliki oleh userilham. Untuk menghapusnya:

1 $ dropdb t o t a l i ndo

Untuk melihat daftar database bisa menggunakan psql:

1 $ psq l2 psq l ( 8 . 4 . 4 )3 Type " help " f o r he lp .4

5 pos tg r e s=# \ l6 L i s t o f databases7 Name | Owner | Encoding | Co l l a t i on |8 −−−−−−−−−−−+−−−−−−−−−−+−−−−−−−−−−+−−−−−−−−−−−−−+9 pos tg r e s | po s t g r e s | UTF8 | id_ID .UTF−8 |

10 template0 | po s tg r e s | UTF8 | id_ID .UTF−8 |11 template1 | po s tg r e s | UTF8 | id_ID .UTF−8 |12 t o t a l i ndo | i lham | UTF8 | id_ID .UTF−8 |13 (4 rows )14

15 pos tg r e s=#

Untuk keluar gunakan \q atau tekan Ctrl-D:

1 pos tg r e s=# \q2 $ whoami3 pos tg r e s

Anda masih sebagai user postgres, keluarlah dengan perintah logout atautekan Ctrl-D:

1 $ logout2 # whoami3 root

Kini Anda sebagai root, keluarlah lagi dengan perintah logout agar kembalisebagai user biasa:

1 # logout2 $ whoami3 sug iana

Sekarang kita login ke database totalindo sebagai user ilham:

1 $ psq l −U ilham to t a l i ndo −h l o c a l h o s t2 Password f o r user ilham :3 psq l ( 8 . 4 . 4 )4 SSL connect ion ( c iphe r : DHE−RSA−AES256−SHA, b i t s : 256)

Page 44: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 7. DATABASE 43

5 Type " help " f o r he lp .6

7 t o t a l i ndo=>

Perhatikan di sini kita menggunakan option yang lengkap di psql, padahalpada saat sebagai user postgres kita cukup mengetikkan psql saja. Apa bedanya?

psql saja tanpa option apapun berarti:

1. Usernya sesuai user Linux.

2. Nama database sesuai nama user.

3. Koneksi melalui jalur UNIX socket, tidak melalui network.

7.1 Tabel

Panduan membuat tabel:

1. Harus memiliki PRIMARY KEY, yaitu sebuah / beberapa �eld yang men-jadi identitas record.

2. Sebisa mungkin setiap �eld memiliki DEFAULT value dimana kalau tidakdiisi maka nilai default digunakan.

3. Sebisa mungkin setiap �eld NOT NULL yang berarti harus diisi.

Mulailah membuat tabel pegawai di psql menggunakan perintah CREATE TA-BLE.

1 t o t a l i ndo=> CREATE TABLE pegawai (2 t o t a l i ndo (> id s e r i a l NOT NULL,3 t o t a l i ndo (> nama varchar (30) NOT NULL,4 t o t a l i ndo (> tg l_ l ah i r DATE NOT NULL,5 t o t a l i ndo (> PRIMARY KEY( id )6 t o t a l i ndo (> ) ;7 NOTICE: CREATE TABLE w i l l c r e a t e imp l i c i t sequence "

pegawai_id_seq" f o r s e r i a l column "pegawai . id "8 NOTICE: CREATE TABLE / PRIMARY KEY w i l l c r e a t e imp l i c i t

index "pegawai_pkey" f o r t ab l e "pegawai " CREATE TABLE9 t o t a l i ndo=>

Perhatikan prompt

totalindo=>

dan bedakan dengan prompt

totalindo(>

Page 45: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 7. DATABASE 44

yang bermakna prompt itu kelanjutan dari prompt sebelumnya. Penulisan

CREATE TABLE pegawai(

yang diikuti dengan penekanan tombol Enter membuat prompt memberitahukanAnda bahwa kurung buka masih aktif dan membutuhkan kurung tutup sebelumdiakhiri dengan titik koma.

Perintah dalam SQL (structured query language) sebenarnya tidak memper-hatikan huruf besar / kecil (incasesensitive). Anda boleh menuliskan

CREATE TABLE

menjadi

create table

Sekarang kita lihat daftar tabel yang ada di database totalindo ini menggunakanperintah \dt.

1 t o t a l i ndo=> \dt2 L i s t o f r e l a t i o n s3 Schema | Name | Type | Owner4 −−−−−−−−+−−−−−−−−−+−−−−−−−+−−−−−−−5 pub l i c | pegawai | t ab l e | i lham6 (1 row )7

8 t o t a l i ndo=>

Perintah yang diawali backslash ( \ ) adalah perintah program psql,bukan jenis query seperti CREATE TABLE, SELECT, dst.

Lalu lihat struktur tabelnya menggunakan perintah \d diikuti nama tabel.

1 t o t a l i ndo=> \d pegawai2 Table " pub l i c . pegawai"3 Column | Type |

Mod i f i e r s4 −−−−−−−−−−−+−−−−−−−−−−−−−−−−−−−−−−−+−−−−−−−−−−−−−−−−−−−5 id | i n t e g e r | not nu l l d e f au l t

nextva l ( ' pegawai_id_seq ' : : r e g c l a s s )6 nama | cha rac t e r vary ing (30) | not nu l l7 t g l_ l ah i r | date | not nu l l8 Indexes :9 "pegawai_pkey" PRIMARY KEY, bt ree ( id )

10

11 t o t a l i ndo=>

Page 46: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 7. DATABASE 45

Perhatikan kolom / �eld id yang bertipe integer, padahal sebelumnya kitatulis bertipe serial. Mengapa demikian ?

Tipe serial hanyalah cara cepat untuk membuat sebuah �eld menjadi au-toincrement (nomor urut). Jadi pende�nisian suatu �eld menjadi serial akanmembuat:

1. Tipenya menjadi integer (bilangan bulat).

2. Memiliki default value nomor urut berikutnya. Nomor urut berikutnyatersimpan dalam sebuah sequence.

Apa itu sequence ?

7.1.1 Sequence

Sequence mirip tabel, tepatnya tabel satu record yang berisi data untuk ke-butuhan nomor urut. Pada contoh di atas sequence bernama pegawai_id_seqotomatis terbentuk saat �eld id pada tabel pegawai dide�nisikan sebagai seri-al. Data pada sequence bisa dilihat sebagaimana tabel menggunakan perintahSELECT.

1 t o t a l i ndo=> SELECT * FROM pegawai_id_seq ;2 sequence_name | la s t_va lue | i s_ca l l e d |3 −−−−−−−−−−−−−−−−+−−−−−−−−−−−−+−−−−−−−−−−−+4 pegawai_id_seq | 1 | f |5

6 (1 row )

Sekarang kita lihat isi tabel pegawai.

1 t o t a l i ndo=> SELECT * FROM pegawai ;2 id | nama | t g l_ l ah i r3 −−−−+−−−−−−+−−−−−−−−−−−4 (0 rows )

Tampak tabel pegawai masih kosong, mari tambah datanya.

1 t o t a l i ndo=> INSERT INTO pegawai (nama , t g l_ l ah i r )2 to ta l i ndo−> VALUES ( 'Bummi Dwi Putera ' , '1985−8−17 ') ;3 INSERT 0 1

Perhatikan perintah di baris pertama tidak diakhiri dengan titik koma yangberarti perintah belum berakhir dan dilanjutkan di baris berikutnya. Perhatikanjuga prompt pada baris kedua menjadi

totalindo->

yakni menggunakan karakter minus ( - ) yang berarti baris ini merupakan ke-lanjutan dari baris sebelumnya. Jika Anda salah dalam menuliskan perintah dibaris pertama dan terlanjur menekan Enter, akhiri saja dengan titik koma dibaris kedua. Kemudian mulai lagi dari awal. Berikut ini contoh kesalahan yangbisa saja terjadi.

Page 47: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 7. DATABASE 46

1 t o t a l i ndo=> INSERT INT pegawai (nama , t g l_ l ah i r )2 to ta l i ndo−> ;3 ERROR: syntax e r r o r at or near "INT"4 LINE 1 : INSERT INT pegawai (nama , t g l_ l ah i r )5 ^6 t o t a l i ndo=>

Untuk mengulangi perintah sebelumnya tekan tombol panah atas.Kembali ke tabel pegawai yang sudah kita isi dengan perintah INSERT.

Sekarang lihat hasilnya.

1 t o t a l i ndo=> SELECT * FROM pegawai ;2 id | nama | t g l_ l ah i r3 −−−−+−−−−−−−−−−−−−−−−−−+−−−−−−−−−−−−4 1 | Bummi Dwi Putera | 1985−08−175 (1 row )

Perhatikan saat INSERT tadi �eld id tidak disertakan, namun perintah SE-LECT memperlihatkan bahwa �eld id terisi dengan angka 1. Inilah yang dise-but dengan �eld autoincrement. Lalu apa yang terjadi dengan sequence pega-wai_id_seq ?

1 t o t a l i ndo=> SELECT * FROM pegawai_id_seq ;2 sequence_name | la s t_va lue | i s_ca l l e d3 −−−−−−−−−−−−−−−−+−−−−−−−−−−−−+−−−−−−−−−−−4 pegawai_id_seq | 1 | t5

6 (1 row )

Bandingkan dengan nilai-nilai pegawai_id_seq pada SELECT sebelum IN-SERT. Yang perlu diperhatikan adalah �eld is_called dimana sebelumnya f(False) kini menjadi t (True). Ini artinya sequence sudah digunakan agar ne-xtval() berikutnya tahu bahwa nilai berikutnya menghasilkan last_value + 1 =2.

Sekarang lanjut dengan pegawai berikutnya.

1 t o t a l i ndo=> INSERT INTO pegawai (nama , t g l_ l ah i r )2 to ta l i ndo−> VALUES ( ' Ar i e f Se t i ad i ' , '1972−5−2 ') ;3 INSERT 0 14 t o t a l i ndo=> SELECT * FROM pegawai ;5 id | nama | t g l_ l ah i r6 −−−−+−−−−−−−−−−−−−−−−−−+−−−−−−−−−−−−7 1 | Bummi Dwi Putera | 1985−08−178 2 | Ar i e f S e t i a d i | 1972−05−029 (2 rows )

Perhatikan kembali �eld id yang terisi dengan angka 2, dan lihat juga pega-wai_id_seq.

1 t o t a l i ndo=> SELECT * FROM pegawai_id_seq ;

Page 48: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 7. DATABASE 47

2 sequence_name | la s t_va lue | i s_ca l l e d |3 −−−−−−−−−−−−−−−−+−−−−−−−−−−−−+−−−−−−−−−−−+4 pegawai_id_seq | 2 | t | 15

6 (1 row )

Kini last_value menjadi 2, sehingga nextval() berikutnya last_value + 1 =3. Mudah-mudahan bisa dipahami.

Mengenai �eld tgl_lahir, bolehkah diisi menggunakan format Indonesia yaitudengan urutan tanggal-bulan-tahun ?

Jawabannya boleh, hanya ada yang perlu diperhatikan pada kon�gurasi Pos-tgreSQL, yaitu pada �le

/etc/postgresql/8.4/main/postgresql.conf

Coba lihat dengan text editor.

1 $ sudo nano / e tc / po s t g r e s q l /8 .4/main/ po s t g r e s q l . conf

Carilah kata datestyle.

datestyle = 'iso, dmy'

Jika sudah tampak dmy seperti di atas maka Anda diizinkan mengisi �eld tang-gal dengan format tanggal-bulan-tahun. Namun jika Anda mendapati isinya

datestyle = 'iso, mdy'

maka ubahlah mdy menjadi dmy, simpan, logout semua psql, dan restart Pos-tgreSQL.

1 $ sudo / e tc / i n i t . d/ po s tg r e sq l −8.4 r e s t a r t

Perlu Anda ketahui, format dmy otomatis Anda dapatkan bila saat instalasiUbuntu menggunakan bahasa Indonesia.

Cobalah untuk menambah data pegawai lagi dengan tanggal lahir berformattanggal-bulan-tahun.

1 t o t a l i ndo=> INSERT INTO pegawai (nama , t g l_ l ah i r )2 to ta l i ndo−> VALUES ( ' Cecep Zahrudin ' , '1−6−1972 ') ;3 INSERT 0 14 t o t a l i ndo=> SELECT * FROM pegawai ;5 id | nama | t g l_ l ah i r6 −−−−+−−−−−−−−−−−−−−−−−−+−−−−−−−−−−−−7 1 | Bummi Dwi Putera | 1985−08−178 2 | Ar i e f S e t i a d i | 1972−05−029 3 | Cecep Zahrudin | 1972−06−01

10 (3 rows )

Agar tampil urut sesuai abjad gunakan ORDER BY.

Page 49: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 7. DATABASE 48

1 t o t a l i ndo=> SELECT * FROM pegawai ORDER BY nama ;2 id | nama | t g l_ l ah i r3 −−−−+−−−−−−−−−−−−−−−−−−+−−−−−−−−−−−−4 2 | Ar i e f S e t i a d i | 1972−05−025 1 | Bummi Dwi Putera | 1985−08−176 3 | Cecep Zahrudin | 1972−06−017 (3 rows )

Gunakan WHERE untuk mendapatkan record tertentu.

1 t o t a l i ndo=> SELECT * FROM pegawai WHERE id = 1 ;2 id | nama | t g l_ l ah i r3 −−−−+−−−−−−−−−−−−−−−−−−+−−−−−−−−−−−−4 1 | Bummi Dwi Putera | 1985−08−175 (1 row )

Tampilkan pegawai yang lahir di tahun 1972 dan diurutkan mulai yang ter-tua.

1 t o t a l i ndo=> SELECT * FROM pegawai2 to ta l i ndo−> WHERE date_part ( ' year ' , t g l_ l ah i r ) = 19723 to ta l i ndo−> ORDER BY tg l_ l ah i r ;4 id | nama | t g l_ l ah i r5 −−−−+−−−−−−−−−−−−−−−−+−−−−−−−−−−−−6 2 | Ar i e f S e t i a d i | 1972−05−027 3 | Cecep Zahrudin | 1972−06−018 (2 rows )

Gunakan DESC pada ORDER BY jika ingin diurut mulai yang termuda.Tekan tombol panah atas untuk mengulang perintah sebelumnya dan tambahk-an DESC.

1 t o t a l i ndo=> SELECT * FROM pegawai2 WHERE date_part ( ' year ' , t g l_ l ah i r ) = 19723 ORDER BY tg l_ l ah i r DESC;4 id | nama | t g l_ l ah i r5 −−−−+−−−−−−−−−−−−−−−−+−−−−−−−−−−−−6 3 | Cecep Zahrudin | 1972−06−017 2 | Ar i e f S e t i a d i | 1972−05−028 (2 rows )

7.1.2 Mengubah Struktur

Pegawai sebelumnya tampak sebagai laki-laki, terlihat dari namanya. Cobalahuntuk memasukkan nama perempuan.

1 t o t a l i ndo=> INSERT INTO pegawai (nama , t g l_ l ah i r )2 to ta l i ndo−> VALUES ( ' Nita Pandria ' , '19−9−1976 ') ;3 INSERT 0 1

Page 50: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 7. DATABASE 49

Manusia bisa jadi memahami mana nama laki-laki dan mana perempuan.Namun komputer mengalami kesulitan bila mengandalkan nama. Oleh karenaitu kita perlu menambah �eld pria yang bertipe logika (boolean). Kita membu-tuhkan perintah ALTER TABLE di sini.

1 t o t a l i ndo=> ALTER TABLE pegawai ADD pr i a boolean NOT NULLDEFAULT true ;

2 ALTER TABLE

Seperti dijelaskan pada sesi Python sebelumnya, boolean hanya bisa diisidengan dua nilai, bisa True atau False. Kita menamakan �eld ini dengan priadengan begitu nilai default-nya adalah True. Jika �eld pria False berarti pegawaitersebut perempuan. Sekarang kita lihat isi tabel pegawai setelah penambahan�eld di atas.

1 t o t a l i ndo=> SELECT * FROM pegawai ORDER BY nama ;2 id | nama | t g l_ l ah i r | p r i a3 −−−−+−−−−−−−−−−−−−−−−−−+−−−−−−−−−−−−+−−−−−−4 2 | Ar i e f S e t i a d i | 1972−05−02 | t5 1 | Bummi Dwi Putera | 1985−08−17 | t6 3 | Cecep Zahrudin | 1972−06−01 | t7 4 | Nita Pandria | 1976−09−19 | t8 (4 rows )

Perhatikan �eld pria, tampak semua tertulis t yang artinya True. Apa datatabel ini sudah benar? Jelas belum.

Nita Pandria adalah perempuan, sedangkan tabel pegawai menyatakannyalaki-laki. Kita perlu mengubahnya dengan perintah UPDATE.

1 t o t a l i ndo=> UPDATE pegawai SET pr i a = False WHERE id = 4 ;2 UPDATE 13 t o t a l i ndo=> SELECT * FROM pegawai ORDER BY nama ;4 id | nama | t g l_ l ah i r | p r i a5 −−−−+−−−−−−−−−−−−−−−−−−+−−−−−−−−−−−−+−−−−−−6 2 | Ar i e f S e t i a d i | 1972−05−02 | t7 1 | Bummi Dwi Putera | 1985−08−17 | t8 3 | Cecep Zahrudin | 1972−06−01 | t9 4 | Nita Pandria | 1976−09−19 | f

10 (4 rows )

Kita sudah membuat record dengan INSERT, menampilkannya dengan SE-LECT, dan mengubahnya dengan UPDATE. Kini kita coba untuk menghapus-nya dengan DELETE FROM yaitu pegawai dengan id 2.

1 t o t a l i ndo=> DELETE FROM pegawai WHERE id = 2 ;2 DELETE 13 t o t a l i ndo=> SELECT * FROM pegawai ORDER BY nama ;4 id | nama | t g l_ l ah i r | p r i a5 −−−−+−−−−−−−−−−−−−−−−−−+−−−−−−−−−−−−+−−−−−−

Page 51: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 7. DATABASE 50

6 1 | Bummi Dwi Putera | 1985−08−17 | t7 3 | Cecep Zahrudin | 1972−06−01 | t8 4 | Nita Pandria | 1976−09−19 | f9 (3 rows )

Jika Anda kurang suka dengan �eld pria yang bertipe boolean bisa dihapusdengan perintah ALTER TABLE.

1 t o t a l i ndo=> ALTER TABLE pegawai DROP pr i a ;2 ALTER TABLE

Anda masih kurang berkenan dengan struktur tabel pegawai ? Silahkanhapus dengan perintah DROP TABLE.

1 t o t a l i ndo=> DROP TABLE pegawai ;2 DROP TABLE

SELECT, INSERT, UPDATE, dan DELETE adalah hal yang terkait de-ngan record / baris data sehingga disebut sebagai Data Manipulation Language(DML). Sedangkan CREATE, ALTER, dan DROP terkait dengan struktur ta-bel sehingga disebut sebagai Data De�nition Language (DDL).

7.2 View

Dibutuhkan sebuah laporan yang menampilkan data pegawai beserta usianya.Untuk mendapatkan usia kita bisa gunakan rumus:

usia = tgl sekarang - tgl lahir

Lalu kita tampilkan dengan urutan diawali yang paling tua.

1 t o t a l i ndo=> SELECT id , nama , now( ) − t g l_ l ah i r FROMpegawai ORDER BY tg l_ l ah i r ;

2 id | nama | ?column?3 −−−−+−−−−−−−−−−−−−−−−−−+−−−−−−−−−−−−−−−−−−−−−−−−−−−−4 2 | Ar i e f S e t i a d i | 13957 days 11 : 21 : 54 . 0830225 3 | Cecep Zahrudin | 13927 days 11 : 21 : 54 . 0830226 4 | Nita Pandria | 12356 days 11 : 21 : 54 . 0830227 1 | Bummi Dwi Putera | 9102 days 11 : 21 : 54 . 0830228 (4 rows )

Kolom ketiga berisi usia, tapi PostgreSQL tidak tahu harus dinamakan apa,sehingga jadilah bernama ?column?. Ada baiknya kita berikan nama �usia�.

1 t o t a l i ndo=> SELECT id , nama , now( ) − t g l_ l ah i r AS us i a2 to ta l i ndo−> FROM pegawai ORDER BY tg l_ l ah i r ;3 id | nama | u s i a4 −−−−+−−−−−−−−−−−−−−−−−−+−−−−−−−−−−−−−−−−−−−−−−−−−−−−5 2 | Ar i e f S e t i a d i | 13957 days 11 : 28 : 34 . 0011426 3 | Cecep Zahrudin | 13927 days 11 : 28 : 34 . 001142

Page 52: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 7. DATABASE 51

7 4 | Nita Pandria | 12356 days 11 : 28 : 34 . 0011428 1 | Bummi Dwi Putera | 9102 days 11 : 28 : 34 . 0011429 (4 rows )

Satuan usia menggunakan hari tentu saja kurang nyaman dibaca. Sebaiknyakita ganti rumusnya:

usia = tahun sekarang - tahun kelahiran

sehingga query-nya menjadi:

1 t o t a l i ndo=> SELECT id , nama ,2 to ta l i ndo−> ext ra c t ( year from now( ) ) − ex t r a c t ( year from

tg l_ l ah i r ) AS us i a3 to ta l i ndo−> FROM pegawai ORDER BY tg l_ l ah i r ;4 id | nama | u s i a5 −−−−+−−−−−−−−−−−−−−−−−−+−−−−−−6 2 | Ar i e f S e t i a d i | 387 3 | Cecep Zahrudin | 388 4 | Nita Pandria | 349 1 | Bummi Dwi Putera | 25

10 (4 rows )

Perintah SQL (query) di atas dapat disimpan dalam sebuah VIEW.

1 t o t a l i ndo=> CREATE VIEW v_pegawai AS SELECT id , nama ,2 ex t r a c t ( year from now( ) ) − ex t r a c t ( year from tg l_ l ah i r )

AS us i a3 FROM pegawai ORDER BY tg l_ l ah i r ;4 CREATE VIEW

Selanjutnya kita tampilkan VIEW tadi layaknya sebuah tabel.

1 t o t a l i ndo=> SELECT * FROM v_pegawai ;2 id | nama | u s i a3 −−−−+−−−−−−−−−−−−−−−−−−+−−−−−−4 2 | Ar i e f S e t i a d i | 385 3 | Cecep Zahrudin | 386 4 | Nita Pandria | 347 1 | Bummi Dwi Putera | 258 (4 rows )

Penamaan VIEW tidak harus berawalan �v_�. Penggunaan awalan itu un-tuk membedakan VIEW dengan tabel sebenarnya. Meski ia dapat di-SELECTnamun VIEW tidak dapat di-INSERT begitu saja.

Walau v_pegawai sudah mengandung ORDER BY, kita masih bisa meng-gunakan ORDER BY saat SELECT, misalnya diurut berdasar nama.

1 t o t a l i ndo=> SELECT * FROM v_pegawai ORDER BY nama ;2 id | nama | u s i a

Page 53: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 7. DATABASE 52

3 −−−−+−−−−−−−−−−−−−−−−−−+−−−−−−4 2 | Ar i e f S e t i a d i | 385 1 | Bummi Dwi Putera | 256 3 | Cecep Zahrudin | 387 4 | Nita Pandria | 348 (4 rows )

7.3 Backup dan Restore

Jika tabel pegawai benar-benar Anda hapus, sebaiknya mulailah membuatnyalagi dan mengisinya. Selain langsung melalui psql modus interaktif, Anda bisamembuatnya dulu dalam sebuah �le pegawai.sql.

Listing 7.1: pegawai.sql

1 CREATE TABLE pegawai (2 id s e r i a l ,3 nama varchar (30) NOT NULL,4 t g l_ l ah i r date NOT NULL,5 pr i a boolean NOTNULL DEFAULT true ,6 PRIMARYKEY( id )7 ) ;8

9 INSERT INTO pegawai (nama , tg l_ lah i r , p r i a ) VALUES ( 'Bummi Dwi Putera ' , ' 1985−8−17 ' , true ) ;

10 INSERT INTO pegawai (nama , tg l_ lah i r , p r i a ) VALUES ( ' Ar i e f S e t i a d i ' , ' 1972−5−2 ' , true ) ;

11 INSERT INTO pegawai (nama , tg l_ lah i r , p r i a ) VALUES ( ' Cecep Zahrudin ' , ' 1972−6−1 ' , true ) ;

12 INSERT INTO pegawai (nama , tg l_ lah i r , p r i a ) VALUES ( ' Nita Pandria ' , ' 1976−9−19 ' , fa l se ) ;

Lalu di psql jalankan �le tersebut:

1 t o t a l i ndo=> \ i pegawai . s q l2 psq l : s q l /pegawai . s q l : 7 : NOTICE: CREATE TABLE w i l l c r e a t e

imp l i c i t sequence "pegawai_id_seq" f o r s e r i a l column"pegawai . id "

3 psq l : s q l /pegawai . s q l : 7 : NOTICE: CREATE TABLE / PRIMARYKEY w i l l c r e a t e imp l i c i t index "pegawai_pkey" f o rt ab l e "pegawai "

4 CREATE TABLE5 INSERT 0 16 INSERT 0 17 INSERT 0 18 INSERT 0 1

Kalau Anda menemui kegagalan

Page 54: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 7. DATABASE 53

No such file or directory

cobalah menuliskan nama �le secara fullpath, misalnya.

1 t o t a l i ndo=> \ i /home/ sugiana /pegawai . s q l

Sesuaikan dengan direktori dimana Anda menyimpan pegawai.sql. Mudah-mudahan Anda mengerti maksudnya.

Kini backup database totalindo dalam sebuah �le berformat tar.

1 $ pg_dump −U ilham to t a l i ndo −h l o c a l h o s t −F t −ft o t a l i ndo . s q l . t a r

Mulailah untuk latihan restore, yaitu dengan membuat database lain ber-nama totalindo_1 (lihat pembuatan database di awal bab ini). Lalu jalankan:

1 $ pg_restore −U ilham −h l o c a l h o s t −d tota l indo_1to t a l i ndo . s q l . t a r

Anda juga bisa backup menggunakan format teks biasa (plaintext):

1 $ pg_dump −U ilham to t a l i ndo −h l o c a l h o s t −f t o t a l i ndo .s q l

dan restore dengan psql:

1 $ psq l −U ilham tota l indo_1 −h l o c a l h o s t −f t o t a l i ndo . s q l

Manfaat penggunaan plaintext adalah Anda bisa mengubah �le totalindo.sqlmenggunakan teks editor biasa. Namun penggunaan format ini terkadang me-nimbulkan masalah saat restore bila ada �karakter aneh�, yaitu karakter dengannomor ASCII lebih besar dari 126.

7.3.1 Encoding

PostgreSQL versi terdahulu biasanya menggunakan SQL_ASCII sebagai enco-ding character. Anda bisa lihat dengan perintah \l di psql.

1 $ psq l −U ilham template1 −h l o c a l h o s t2 psq l ( 8 . 4 . 4 )3 Type " help " f o r he lp .4

5 pos tg r e s=# \ l6 L i s t o f databases7 Name | Owner | Encoding | Co l l a t i on |8 −−−−−−−−−−−−−+−−−−−−−−−−+−−−−−−−−−−+−−−−−−−−−−−−−+9 pos tg r e s | po s t g r e s | UTF8 | id_ID .UTF−8 |

10 template0 | po s tg r e s | UTF8 | id_ID .UTF−8 |11 template1 | po s tg r e s | UTF8 | id_ID .UTF−8 |12 t o t a l i ndo | i lham | UTF8 | id_ID .UTF−8 |13 tota l indo_1 | ilham | UTF8 | id_ID .UTF−8 |14 (5 rows )

Page 55: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 7. DATABASE 54

Perhatikan di versi ini default encoding adalah UTF8. Jika Anda membac-kup, perhatikanlah encoding ini. Misalkan menggunakan SQL_ASCII, makadi database yang baru pun Anda sebaiknya tetap menggunakan encoding yangsama. Sebagai latihan kembalilah ke konsole, lalu buat database totalindo_2dengan encoding SQL_ASCII.

1 $ sudo su2 # su − pos tg r e s3 $ createdb −O ilham −T template0 −E sq l_a s c i i tota l indo_2

Kembali ke psql dan lihat daftar database. Karena masih sebagai user pos-tgres maka cukup ketik psql.

1 $ psq l2 psq l ( 8 . 4 . 4 )3 Type " help " f o r he lp .4

5 pos tg r e s=# \ l6 L i s t o f databases7 Name | Owner | Encoding | Co l l a t i on |8 −−−−−−−−−−−−−+−−−−−−−−−−+−−−−−−−−−−−+−−−−−−−−−−−−−+9 pos tg r e s | po s t g r e s | UTF8 | id_ID .UTF−8 |

10 template0 | po s tg r e s | UTF8 | id_ID .UTF−8 |11 template1 | po s tg r e s | UTF8 | id_ID .UTF−8 |12 t o t a l i ndo | i lham | UTF8 | id_ID .UTF−8 |13 tota l indo_1 | ilham | UTF8 | id_ID .UTF−8 |14 tota l indo_2 | ilham | SQL_ASCII | id_ID .UTF−8 |15 (6 rows )

Mengenai cara backup dan restore lainnya sama seperti sebelumnya.Mengapa kita perlu memperhatikan encoding ?Bila database yang Anda backup tidak mengandung karakter aneh (ASCII

> 126) maka bisa dengan nyaman di-restore dari ke UTF8. Namun bila meng-andung ASCII > 126 maka restore ke UTF8 dari sumber SQL_ASCII bisamenimbulkan masalah.

7.4 Fungsi

Sama seperti Python, PostgreSQL juga mengenal fungsi. Contoh fungsi bawaan(built-in) adalah now().

1 t o t a l i ndo=> SELECT now( ) ;2 now3 −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−4 2010−08−24 16:06 :58 .678056+075 (1 row )

Keunikan fungsi pada PostgreSQL adalah pada nama dan susunan masu-kannya (input parameter). Perhatikan contoh rata kanan berikut ini.

Page 56: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 7. DATABASE 55

1 t o t a l i ndo=> SELECT lpad ( 'A' , 5 ) ;2 lpad3 −−−−−−−4 A5 (1 row )

Fungsi lpad() berguna untuk memberi spasi di sebelah kiri. Jumlah spasiditambah jumlah karakter string 'A' tidak boleh melebihi 5. Jadi pada contohdi atas jumlah spasi di sebelah kiri 'A' sebanyak 4 buah. Untuk membuktikanjumlah karakternya adalah 5 maka kita gunakan fungsi length().

1 t o t a l i ndo=> SELECT length ( lpad ( 'A' , 5 ) ) ;2 l ength3 −−−−−−−−4 55 (1 row )

Sekarang kita membutuhkan awalan '0' pada sebuah nomor, misalnya '00001'.Ini lazim kita temui pada beberapa laporan. Fungsi apa yang akan digunakan.Jawabannya masih menggunakan fungsi lpad().

1 t o t a l i ndo=> SELECT lpad ( ' 1 ' , 5 , ' 0 ' ) ;2 lpad3 −−−−−−−4 000015 (1 row )

Di sinilah letak keunikan sebuah fungsi pada PostgreSQL. Fungsi lpad()bisa menerima masukan dua buah atau tiga buah. Jika dua buah saja yangdigunakan maka lpad() akan mengawalinya dengan spasi. Namun jika tiga buahmasukan, maka lpad() akan mengawalinya sesuai dengan karakter pada masukanketiga. Cermatilah baik-baik.

Jadi bila kita ingin membuat beberapa fungsi dengan nama sama maka ha-rus dibedakan dengan:

1. Jumlah masukannya.

2. Jika jumlah masukannya sama maka bedakan tipe data setiap masukantersebut.

7.4.1 PL/pgSQL

Salah satu yang membuat PostgreSQL begitu mudah dikembangkan adalahfungsi tersebut bisa ditulis dalam berbagai bahasa. Dimana Anda bisa me-nulis fungsi dalam bahasa pgSQL, Python, Perl, hingga Tcl. Secara defaultbahasa yang didukungnya adalah plpgsql. Namun Anda perlu memasangnyaterlebih dahulu pada database yang dimaksud.

1 $ sudo su po s tg r e s −c " c r e a t e l ang p lpg sq l t o t a l i ndo "

Page 57: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 7. DATABASE 56

Selanjutnya siapkanlah dua konsole, yang pertama untuk

1 $ psq l −U ilham to t a l i ndo −h l o c a l h o s t

sedangkan yang kedua untuk text editor vi. Tentu saja Anda bisa menggu-nakan gedit. Text editor akan kita gunakan untuk membuat �le-�le *.sql.

Sekarang kita akan membuat fungsi sederhana hello(), tanpa masukan apa-pun, disimpan dalam �le hello.sql.

Listing 7.2: hello.sql

1 CREATEOR REPLACE FUNCTION he l l o ( )2 RETURNS text3 LANGUAGE p lpg sq l4 AS $$5 BEGIN6 RETURN ' He l lo world . ' ;7 END8 $$ ;

Setelah disimpan jalankan di psql tadi:

1 t o t a l i ndo=> \ i h e l l o . s q l2 CREATE FUNCTION

lalu cobalah

1 t o t a l i ndo=> SELECT he l l o ( ) ;2 h e l l o3 −−−−−−−−−−−−−−4 Hel lo world .5 (1 row )

Transaksi Perbankan

Kita sudah punya tabel pegawai dimana setiap pegawai dianggap sebagai na-sabah pada perusahaan ini. Saat mendapat gaji saldonya bertambah. Saatambil gaji saldonya berkurang. Saat kas bon (pinjam) saldonya juga berku-rang. Jadi saldo juga bisa negatif yang berarti pegawai tersebut punya hutangke perusahaan.

Pertama kita butuh �eld saldo pada tabel pegawai.

1 ALTER TABLE pegawai ADD sa ldo f loat NOT NULL DEFAULT 0 ;

Kemudian untuk mencatat aktivitas transaksi kita memerlukan tabel tran-saksi berikut ini.

Listing 7.3: transaksi.sql

1 CREATE TABLE t r an s ak s i (2 id s e r i a l PRIMARYKEY,3 pid integer NOT NULL REFERENCES pegawai ,

Page 58: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 7. DATABASE 57

4 t g l timestamp NOTNULL DEFAULT now( ) ,5 ket varchar (100) NOT NULL,6 nominal f loat NOT NULL,7 sa ldo f loat NOT NULL8 ) ;

Misalkan ID pegawai 1 bernama Bummi Dwi Putera mendapat gaji untukbulan Nopember 2010 sebesar Rp 3.000.000,- maka query-nya adalah:

1 UPDATE pegawai SET sa ldo = sa ldo + 3000000 WHERE id = 1 ;2

3 INSERT INTO t r an s ak s i ( pid , ket , nominal , sa ldo )4 SELECT id , 'GAJI 11−2010 ' ,3000000 , sa ldo5 FROM pegawai6 WHERE id = 1 ;

Ya, kita butuh dua query untuk sebuah transaksi. Mungkin ada pertanyaan,untuk apa �eld saldo pada tabel transaksi ? Field ini digunakan untuk memu-dahkan pencetakan buku tabungan yang biasanya mencantumkan saldo padasetiap transaksi.

Kalau diperhatikan, transaksi tersebut membutuhkan 3 parameter masukan:

1. ID pegawai

2. Keterangan transaksi

3. Nominal transaksi

Kalau transaksi ini dikemas dalam sebuah fungsi, lalu apa keluarannya ? Ke-luaran atau output yang paling tepat adalah ID transaksi. Query-nya bisa kitaperoleh dengan cara berikut ini.

1 SELECT id FROM tran s ak s i ORDER BY id DESC LIMIT 1 ;

Artinya dapatkan record terakhir dari tabel transaksi.

1 id | pid | t g l |2 −−−−+−−−−−+−−−−−−−−−−−−−−−−−−−−−−−−+3 1 | 1 | 2010−10−22 17 : 5 8 : 0 1 . 8 6 |4

5 ket | nominal | sa ldo6 −−−−−−−−−−−−−−+−−−−−−−−−+−−−−−−−−−7 GAJI 11−2010 | 3000000 | 3000000

Selanjutnya kita buat functransaksi.sql untuk fungsi dimaksud.

Listing 7.4: functransaksi.sql

1 CREATEOR REPLACE FUNCTION t r an s ak s i (2 p_pid integer ,3 p_ket text ,4 p_nominal f loat )

Page 59: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 7. DATABASE 58

5 RETURNS integer6 LANGUAGE p lpg sq l7 AS $$8 DECLARE9 r e c record ;

10 BEGIN11 UPDATE pegawai12 SET sa ldo = sa ldo + p_nominal13 WHERE id = p_pid ;14

15 INSERT INTO t r an s ak s i (16 id , pid , nominal , ket , sa ldo )17 SELECT t id , p_pid , p_nominal , p_ket , sa ldo18 FROM pegawai19 WHERE id = p_pid ;20

21 SELECT id22 INTO r e c23 FROM t r an s ak s i24 ORDERBY id DESC25 LIMIT 1 ;26

27 RETURN rec . id ;28 END29 $$

Restore script ini.

1 t o t a l i ndo=> \ i f un c t r an s ak s i . s q l2 CREATE FUNCTION

Misalkan ID pegawai 1 meminjam (cash bon) sebesar Rp200.000,- maka:

1 t o t a l i ndo=> SELECT t r an s ak s i ( 1 , 'BON' ,−200000) ;2 t r an s ak s i3 −−−−−−−−−−−4 25 (1 row )

Perhatikan nominal berisi nilai negatif yang artinya mengurangi saldo. Se-karang lihat keseluruhan transaksi.

1 t o t a l i ndo=> SELECT * FROM tran s ak s i ;2 id | pid | t g l | ket |

nominal | sa ldo3 −−−−+−−−−−+−−−−−−−−−−−−−−−−−−−−−−−−−−−−+−−−−−−−−−−−−−−+−−−−−−−−−+−−−−−−−−−

4 1 | 1 | 2010−10−22 17 : 58 : 01 . 869139 | GAJI 11−2010 |3000000 | 3000000

Page 60: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 7. DATABASE 59

5 2 | 1 | 2010−10−22 18 : 20 : 08 . 845091 | BON |−200000 | 2800000

6 (2 rows )

Dilihat dari aspek kecepatan, query SELECT terhadap tabel transaksi bisadihindari. Maklumlah tabel transaksi ini tergolong cepat pertumbuhan record-nya. Jadi untuk mendapatkan ID transaksi kita perlu menggunakan sequenceyang dimiliki tabel transaksi tersebut. Ubahlah functransaksi.sql menjadi beri-kut ini.

Listing 7.5: functransaksi.sql

1 CREATEOR REPLACE FUNCTION t r an s ak s i (2 p_pid integer ,3 p_ket text ,4 p_nominal f loat )5 RETURNS integer6 LANGUAGE p lpg sq l7 AS $$8 DECLARE9 t i d integer ;

10 BEGIN11 UPDATE pegawai12 SET sa ldo = sa ldo + p_nominal13 WHERE id = p_pid ;14

15 t i d = nextva l ( ' transaks i_id_seq ' ) ;16

17 INSERT INTO t r an s ak s i (18 id , pid , nominal , ket , sa ldo )19 SELECT t id , p_pid , p_nominal , p_ket , sa ldo20 FROM pegawai21 WHERE id = p_pid ;22

23 RETURN t id ;24 END25 $$

Restore.

1 t o t a l i ndo=> \ i t r an s ak s i . s q l2 CREATE FUNCTION

Kini kita coba ID pegawai 5 bernama Ilham untuk transaksi.

1 t o t a l i ndo=> SELECT t r an s ak s i ( 5 , 'GAJI 11−2010 ' ,1500000) ;2 t r an s ak s i3 −−−−−−−−−−−4 35 (1 row )

Page 61: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 7. DATABASE 60

Lalu lihat hasilnya.

1 t o t a l i ndo=> SELECT * FROM tran s ak s i ;2 id | pid | t g l | ket |

nominal | sa ldo3 −−−−+−−−−−+−−−−−−−−−−−−−−−−−−−−−−−−−−−−+−−−−−−−−−−−−−−+−−−−−−−−−+−−−−−−−−−

4 1 | 1 | 2010−10−22 17 : 58 : 01 . 869139 | GAJI 11−2010 |3000000 | 3000000

5 2 | 1 | 2010−10−22 18 : 20 : 08 . 845091 | BON |−200000 | 2800000

6 3 | 5 | 2010−10−22 18 : 41 : 45 . 309451 | GAJI 11−2010 |1500000 | 1500000

7 (3 rows )

7.4.2 PL/Python

Penulisan fungsi PostgreSQL bisa juga dalam bahasa Python. Biasanya sayagunakan bahasa ini untuk algoritma yang tidak membutuhkan akses database.Pasanglah terlebih dahulu.

1 $ sudo apt−get i n s t a l l po s tg r e sq l−plpython −8.42 $ sudo su po s tg r e s −c " c r e a t e l ang plpythonu t o t a l i ndo "

Masih ingat modul uang yang ditaruh di /usr/local/lib/python2.6/dist-packages? Kali ini akan kita gunakan pada fungsi di PostgreSQL. Buatlah uang.sql ber-ikut ini.

Listing 7.6: uang.sql

1 CREATEOR REPLACE FUNCTION uang (n f loat )2 RETURNS text3 LANGUAGE plpythonu4 AS $$5 from uang import uang6 re turn uang (n)7 $$ ;8

9 CREATEOR REPLACE FUNCTION uang (n integer )10 RETURNS text11 LANGUAGE plpythonu12 AS $$13 from uang import uang14 re turn uang (n)15 $$ ;

Tidak seperti plpgsql, fungsi yang ditulis menggunakan plpythonu harusdibuat oleh user postgres.

Page 62: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 7. DATABASE 61

1 $ sudo su po s tg r e s −c " psq l t o t a l i ndo −f uang . s q l "2 [ sudo ] password f o r sugiana :3 CREATE FUNCTION4 CREATE FUNCTION

Lalu cobalah.

1 t o t a l i ndo=> SELECT uang (10000) ;2 uang3 −−−−−−−−4 10 .0005 (1 row )

Page 63: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

Bab 8

Python Akses Database

Data yang ada di PostgreSQL dapat digunakan oleh aplikasi yang ditulis de-ngan bahasa Python menggunakan pustaka tambahan bernama SQLAlchemy.Pustaka ini dipilih karena sifatnya yang luwes dimana ia juga bisa menanganidatabase lainnya, tidak hanya PostgreSQL.

Sekarang pasanglah terlebih dahulu.

1 $ sudo apt−get i n s t a l l python−sqla lchemy2 $ sudo apt−get i n s t a l l python−psycopg2

Selanjutnya masuk ke modus interaktif untuk mencoba.

1 >>> import sqla lchemy as sa2 >>> ur l = ' po s t g r e s q l : // ilham :1234 @loca lhos t / to ta l i ndo '3 >>> db = sa . create_engine ( u r l )4 >>> db . connect ( )5 <sqla lchemy . eng ine . base . Connection ob j e c t at 0x8b0872c>

Sampai di sini Python sudah terhubung ke PostgreSQL dan uji coba loginberhasil dengan perintah connect(). Anda bisa lanjutkan dengan perintah queryuntuk melihat record tabel pegawai.

1 >>> sq l = "SELECT * FROM pegawai"2 >>> q = db . execute ( s q l )3 >>> fo r r in q :4 . . . p r i n t r5 . . .6 (1 , 'Bummi Dwi Putera ' , datet ime . date (1985 , 8 , 17) , True )7 (2 , ' Ar i e f Se t i ad i ' , datet ime . date (1972 , 5 , 2) , True )8 (3 , ' Cecep Zahrudin ' , datet ime . date (1972 , 6 , 1) , True )9 (4 , ' Nita Pandria ' , datet ime . date (1976 , 9 , 19) , Fa l se )

Lalu bagaimana kalau kita ingin melihat nilai berdasarkan nama �eld-nya? Untunglah variabel r di atas bisa dianggap sebagai dictionary yang keys-nyaberisi nama �eld dari query bersangkutan.

62

Page 64: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 8. PYTHON AKSES DATABASE 63

1 >>> q = db . execute ( s q l )2 >>> fo r r in q :3 . . . p r i n t r [ ' id ' ] , r [ ' nama ' ]4 . . .5 1 Bummi Dwi Putera6 2 Ar i e f S e t i a d i7 3 Cecep Zahrudin8 4 Nita Pandria

Bahkan �eld id dan nama bisa dianggap variabel milik r:

1 >>> q = db . execute ( s q l )2 >>> fo r r in q :3 . . . p r i n t r . id , r . nama4 . . .5 1 Bummi Dwi Putera6 2 Ar i e f S e t i a d i7 3 Cecep Zahrudin8 4 Nita Pandria

Mudah bukan ?Fungsi execute() bisa juga digunakan untuk perintah query lainnya seperti

INSERT, UPDATE, dan DELETE. Contohnya mengganti huruf pada �eld namadengan kapital.

1 >>> sq l = "UPDATE pegawai SET nama = upper (nama) "2 >>> db . execute ( s q l )3 <sqla lchemy . eng ine . base . ResultProxy ob j e c t at 0xb748a9ac>4 >>> sq l = "SELECT * FROM pegawai"5 >>> q = db . execute ( s q l )6 >>> fo r r in q :7 . . . p r i n t r . nama8 . . .9 BUMMI DWI PUTERA

10 ARIEF SETIADI11 CECEP ZAHRUDIN12 NITA PANDRIA

8.1 Active Record

Anda memiliki data pegawai dalam sebuah �le yang berformat CSV yang isinyaseperti ini:

Listing 8.1: pegawai.csv

1 1 ;BUMMI DWI PUTERA, ST;1985−08−17; t2 2 ;ARIEF SETIADI;1972−05−02; t3 3 ;CECEP ZAHRUDIN;1972−06−01; t

Page 65: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 8. PYTHON AKSES DATABASE 64

4 4 ;NITA PANDRIA;1976−09−19; f5 5 ;ILHAM;1984−11−05; t

File ini mencerminkan tabel pegawai dimana setiap �eld dipisahkan dengantitik koma ( ; ). Sedangkan identitas baris berupa ID pegawai yang berada dikolom pertama, persis seperti tabel pegawai. Tugasnya adalah menyalin isi �leini ke dalam tabel pegawai. Jika ID pegawai sudah ada maka lakukan UPDATE,jika belum berarti INSERT.

Mari kita lihat terlebih dahulu isi tabel pegawai melalui psql.

1 $ psq l −U ilham −h l o c a l h o s t t o t a l i ndo2 Password f o r user ilham :3 psq l ( 8 . 4 . 4 )4 SSL connect ion ( c iphe r : DHE−RSA−AES256−SHA, b i t s : 256)5 Type " help " f o r he lp .6

7 t o t a l i ndo=> SELECT * FROM pegawai ;8 id | nama | t g l_ l ah i r | p r i a9 −−−−+−−−−−−−−−−−−−−−−−−+−−−−−−−−−−−−+−−−−−−

10 1 | BUMMI DWI PUTERA | 1985−08−17 | t11 2 | ARIEF SETIADI | 1972−05−02 | t12 3 | CECEP ZAHRUDIN | 1972−06−01 | t13 4 | NITA PANDRIA | 1976−09−19 | f14 (4 rows )

Bandingkanlah dengan �le pegawai.csv sebelumnya dimana perubahannyananti adalah:

1. ID 1 nama akan berubah dari BUMMI DWI PUTERA menjadi BUMMIDWI PUTERA, ST (bergelar).

2. Jumlah baris tabel pegawai bertambah dengan adanya ID 5 bernama IL-HAM.

Buatlah �le pegawai.csv terlebih dahulu dengan isi seperti di atas. Kemudianbuatlah �le updatepegawai.py.

Listing 8.2: updatepegawai.py

1 import sqla lchemy as sa2

3 u r l = ' po s t g r e s q l : // ilham :1234 @loca lhos t / t o t a l i ndo '4 db = sa . create_engine ( u r l )5 db . connect ( )6

7 f i l ename = ' pegawai . csv '8 f = open ( f i l ename )9 for l i n e in f . r e a d l i n e s ( ) :

10 pid , nama , tg l_ lah i r , p r i a = l i n e . s t r i p ( ) . s p l i t ( ' ; ' )

Page 66: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 8. PYTHON AKSES DATABASE 65

11 pid = in t ( pid )12 pr i a = pr i a == ' t ' # Agar boo lean True / False13 s q l = "SELECT * FROM pegawai WHERE id = %d" % pid14 q = db . execute ( s q l )15 i f q . rowcount :16 s q l = "UPDATE pegawai SET " + \17 "nama = '%s ' , " + \18 " t g l_ l ah i r = '%s ' , " + \19 " pr i a = %s " + \20 "WHERE id = %d"21 s q l = sq l % (nama , tg l_ lah i r , pr ia , pid )22 else :23 s q l = "INSERT INTO pegawai " + \24 " ( id , nama , tg l_ lah i r , p r i a ) " + \25 "SELECT %d , '%s ' , '%s ' , %s "26 s q l = sq l % ( pid , nama , tg l_ lah i r , p r i a )27 db . execute ( s q l )

Jalankan.

1 $ python updatepegawai . py

Kemudian ke psql, lihat tabel pegawai.

1 t o t a l i ndo=> SELECT * FROM pegawai ORDER BY id ;2 id | nama | t g l_ l ah i r | p r i a3 −−−−+−−−−−−−−−−−−−−−−−−−−−−+−−−−−−−−−−−−+−−−−−−4 1 | BUMMI DWI PUTERA, ST | 1985−08−17 | t5 2 | ARIEF SETIADI | 1972−05−02 | t6 3 | CECEP ZAHRUDIN | 1972−06−01 | t7 4 | NITA PANDRIA | 1976−09−19 | f8 5 | ILHAM | 1984−11−05 | t9 (5 rows )

Perubahan sudah sesuai dengan yang diharapkan. Meski begitu source upda-tepegawai.py tergolong sulit dibaca, dan ini bisa menyulitkan debugging (pene-lusuran kesalahan). Cara yang lebih nyaman adalah menggunakan teknik yangdisebut active record.

Terlebih dahulu pasang paket Elixir.

1 $ sudo apt−get i n s t a l l python−e l i x i r

Agar proses UPDATE dan INSERT masih terasa, buatlah perubahan padapegawai.csv berikut ini.

Listing 8.3: pegawai.csv

1 1 ;BUMMI DWI PUTERA, ST;1985−08−17; t2 2 ;ARIEF SETIADI;1972−05−02; t3 3 ;CECEP ZAHRUDIN, ST;1972−06−01; t

Page 67: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 8. PYTHON AKSES DATABASE 66

4 4 ;NITA PANDRIA;1976−09−19; f5 5 ;ILHAM;1984−11−05; t6 6 ;MIRANDA;1978−10−01; f

Perubahannya adalah UPDATE pada CECEP ZAHRUDIN menjadi CE-CEP ZAHRUDIN, ST, dan INSERT pada MIRANDA. Selanjutnya buat �leupdatepegawai1.py.

Listing 8.4: updatepegawai1.py

1 from e l i x i r import Entity , using_options , setup_al l ,metadata , \

2 s e s s i o n3

4 class Pegawai ( Ent ity ) :5 using_options ( tablename=' pegawai ' , auto load=True )6

7 metadata . bind = ' po s tg r e s : // ilham :1234 @loca lhos t /t o t a l i ndo '

8 se tup_al l ( )9

10 f i l ename = ' pegawai . csv '11 f = open ( f i l ename )12 for l i n e in f . r e a d l i n e s ( ) :13 pid , nama , tg l_ lah i r , p r i a = l i n e . s t r i p ( ) . s p l i t ( ' ; ' )14 pid = in t ( pid )15 p = Pegawai . query . f i l t e r_by ( id=pid )16 i f p . count ( ) :17 r = p . one ( )18 else :19 r = Pegawai ( )20 r . id = pid21 r . nama = nama22 r . t g l_ l ah i r = tg l_ l ah i r23 r . p r i a = pr i a == ' t '24 s e s s i o n . commit ( )

Jalankanlah.

1 $ python updatepegawai1 . py

Lalu lihat hasilnya di psql.

1 t o t a l i ndo=> SELECT * FROM pegawai ORDER BY id ;2 id | nama | t g l_ l ah i r | p r i a3 −−−−+−−−−−−−−−−−−−−−−−−−−−−+−−−−−−−−−−−−+−−−−−−4 1 | BUMMI DWI PUTERA, ST | 1985−08−17 | t5 2 | ARIEF SETIADI | 1972−05−02 | t6 3 | CECEP ZAHRUDIN, ST | 1972−06−01 | t

Page 68: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 8. PYTHON AKSES DATABASE 67

7 4 | NITA PANDRIA | 1976−09−19 | f8 5 | ILHAM | 1984−11−05 | t9 6 | MIRANDA | 1978−10−01 | f

10 (6 rows )

Hasil sudah sesuai harapan dengan source yang jauh lebih mudah dibaca.Pahamilah baik-baik mengenai konsep active record ini.

Lalu bagaimana menghapus salah satu record ? Buatlah �le deletepega-wai.py berikut ini.

Listing 8.5: deletepegawai.py

1 from e l i x i r import Entity , using_options , metadata ,setup_al l , \

2 s e s s i o n3 import sys4

5 class Pegawai ( Ent ity ) :6 using_options ( tablename=' pegawai ' , auto load=True )7

8 i f not sys . argv [ 1 : ] :9 sys . e x i t ( ' Caranya : python %s <id>' % sys . argv [ 0 ] )

10

11 try :12 pid = in t ( sys . argv [ 1 ] )13 except ValueError :14 sys . e x i t ( ' ID pegawai harus angka ' )15

16 metadata . bind = ' po s tg r e s : // ilham :1234 @loca lhos t /t o t a l i ndo '

17 se tup_al l ( )18

19 p = Pegawai . query . f i l t e r_by ( id=pid )20 i f not p . count ( ) :21 sys . e x i t ( ' ID pegawai %d t idak ada ' % pid )22

23 r = p . one ( )24 r . d e l e t e ( )25 s e s s i o n . commit ( )26 print ' ID pegawai %d sudah dihapus ' % pid

Script ini membutuhkan parameter masukan (argument) saat dijalankan,yaitu berupa ID pegawai yang akan dihapus. Kita coba menghapus ID pegawai4 NITA PANDRIA.

1 $ python delete_pegawai . py 42 ID pegawai 4 sudah dihapus

Periksa hasilnya di psql.

Page 69: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 8. PYTHON AKSES DATABASE 68

1 t o t a l i ndo=> SELECT * FROM pegawai ORDER BY id ;2 id | nama | t g l_ l ah i r | p r i a3 −−−−+−−−−−−−−−−−−−−−−−−−−−−+−−−−−−−−−−−−+−−−−−−4 1 | BUMMI DWI PUTERA, ST | 1985−08−17 | t5 2 | ARIEF SETIADI | 1972−05−02 | t6 3 | CECEP ZAHRUDIN, ST | 1972−06−01 | t7 5 | ILHAM | 1984−11−05 | t8 6 | MIRANDA | 1978−10−01 | f9 (5 rows )

Bagaimana dengan SELECT ? Contoh sebelumnya menggunakan �lter_by()yang sama artinya dengan WHERE. Kini kita tampilkan semua record tabel pe-gawai tanpa kondisi apapun yaitu mengganti �lter_by() dengan all(). Buatlahselectpegawai.py.

Listing 8.6: selectpegawai.py

1 from e l i x i r import Entity , using_options , metadata ,se tup_al l

2 import sys3

4 class Pegawai ( Ent ity ) :5 using_options ( tablename=' pegawai ' , auto load=True )6

7 metadata . bind = ' po s tg r e s : // ilham :1234 @loca lhos t /t o t a l i ndo '

8 se tup_al l ( )9

10 for r in Pegawai . query . a l l ( ) :11 print r . id , r . nama , r . t g l_ lah i r , r . p r i a

Jalankan.

$ python select_pegawai.py

1 BUMMI DWI PUTERA, ST 1985-08-17 True

2 ARIEF SETIADI 1972-05-02 True

3 CECEP ZAHRUDIN, ST 1972-06-01 True

5 ILHAM 1984-11-05 True

6 MIRANDA 1978-10-01 False

Butuh tampilan yang urut berdasarkan nama ? Kita biasa menggunakan ORDERBY pada query, disini bisa menggunakan order_by() sebagai pengganti all().

Listing 8.7: selectpegawai2.py

1 from e l i x i r import Entity , using_options , metadata ,se tup_al l

2 import sys3

Page 70: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 8. PYTHON AKSES DATABASE 69

4 class Pegawai ( Ent ity ) :5 using_options ( tablename=' pegawai ' , auto load=True )6

7 metadata . bind = ' po s tg r e s : // ilham :1234 @loca lhos t /t o t a l i ndo '

8 se tup_al l ( )9

10 for r in Pegawai . query . order_by ( 'nama ' ) :11 print r . id , r . nama , r . t g l_ lah i r , r . p r i a

Jalankan.

1 $ python se lect_pegawai . py2 2 ARIEF SETIADI 1972−05−02 True3 1 BUMMI DWI PUTERA, ST 1985−08−17 True4 3 CECEP ZAHRUDIN, ST 1972−06−01 True5 5 ILHAM 1984−11−05 True6 6 MIRANDA 1978−10−01 Fal se

Ingin yang lebih rapi ? Ubahlah seperti ini.

Listing 8.8: selectpegawai.py

1 from e l i x i r import *

2 import sys3

4 class Pegawai ( Ent ity ) :5 using_options ( tablename=' pegawai ' , auto load=True )6

7 metadata . bind = ' po s tg r e s : // ilham :1234 @loca lhos t /t o t a l i ndo '

8 se tup_al l ( )9

10 j e n i s = {True : ' Pr ia ' ,11 False : 'Wanita ' }12

13 p = Pegawai . query . order_by ( 'nama ' )14 for r in p :15 print s t r ( r . id ) . c en te r (3 ) , \16 r . nama . l j u s t (20) , \17 r . t g l_ lah i r , \18 j e n i s [ r . p r i a ]

Jalankan.

1 $ python se lect_pegawai . py2 2 ARIEF SETIADI 1972−05−02 Pria3 1 BUMMI DWI PUTERA, ST 1985−08−17 Pria4 3 CECEP ZAHRUDIN, ST 1972−06−01 Pria

Page 71: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 8. PYTHON AKSES DATABASE 70

5 5 ILHAM 1984−11−05 Pria6 6 MIRANDA 1978−10−01 Wanita

Elixir vs SQLAlchemy ?

Sebenarnya Elixir bukanlah menggantikan SQLAlchemy, karena Elixir sendi-ri menggunakan engine SQLAlchemy. Ini bisa terlihat pada penjelasan paketpython-elixir.

1 $ dpkg −s python−e l i x i r2 Package : python−e l i x i r3 Vers ion : 0.7.1−14 Depends : python (>= 2 . 4 ) , python−support (>= 0 . 9 0 . 0 ) ,

python−sqla lchemy (>= 0 . 4 . 0 )5 Desc r ip t i on : Dec l a ra t i v e Mapper f o r SQLAlchemy

8.2 Auto Commit

Masih ingat fungsi sql bernama transaksi() ? Kali ini akan kita buat transaksiperbankan secara interaktif. Buatlah transaksi.py berikut.

Listing 8.9: transaksi.py

1 import sqla lchemy as sa2 import sys3

4 u r l = ' po s t g r e s q l : // ilham :1234 @loca lhos t / t o t a l i ndo '5 db = sa . create_engine ( u r l )6

7 print ' Transaks i '8 pid = raw_input ( ' ID pegawai : ' )9 try :

10 pid = in t ( pid )11 except ValueError :12 sys . e x i t ( ' ID pegawai %s t idak benar ' % pid )13

14 s q l = "SELECT nama FROM pegawai WHERE id = %d" % pid15 q = db . execute ( s q l )16 i f not q . rowcount :17 sys . e x i t ( ' ID pegawai %d t idak ada ' % pid )18 print 'Nama: ' , q . f e t chone ( ) . nama19

20 ket = raw_input ( ' Keterangan : ' )21 i f not ket :22 sys . e x i t ( ' Keterangan harus d i i s i ' )23

Page 72: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 8. PYTHON AKSES DATABASE 71

24 nominal = raw_input ( ' Nominal : ' )25 try :26 nominal = f l o a t ( nominal )27 except ValueError :28 sys . e x i t ( ' Nominal %s t idak benar ' % nominal )29

30 s q l = "SELECT t r an s ak s i (%d, '% s ' ,%.2 f ) " % ( pid , ket ,nominal )

31 q = db . execute ( s q l )32 print ' Transaks i be rha s i l , ID ' , q . f e t chone ( ) . t r an s ak s i

Jalankan.

1 $ python t r an s ak s i . py2 Transaks i3 ID pegawai : 34 Nama: CECEP ZAHRUDIN, ST5 Keterangan : GAJI 11−20106 Nominal : 45000007 Transaks i b e rha s i l , ID 4

Untuk memastikan transaksi benar-benar berhasil, lihatlah di psql.

1 t o t a l i ndo=> SELECT * FROM tran s ak s i ;2 id | pid | t g l | ket | nominal | sa ldo3 −−−−+−−−−−+−−−−−−−−−−−−+−−−−−−−−−−−−−−+−−−−−−−−−+−−−−−−−−4 1 | 1 | 2010−10−22 | GAJI 11−2010 | 3000000 | 30000005 2 | 1 | 2010−10−22 | BON | −200000 | 28000006 3 | 5 | 2010−10−22 | GAJI 11−2010 | 1500000 | 15000007 (3 rows )

Perhatikan, tidak ada ID transaksi 4, padahal eksekusi transaksi.py berjalanbaik. Apa yang terjadi ?

SQL function transaksi() yang dijalankan oleh transaksi.py dijalankan padamodus transaction. Ini bisa diartikan SQLAlchemy atau mungkin Psycopg2yang digunakan SQLAlchemy otomatis menjalankan BEGIN sebelum SELECTtransaksi( ... ). Seperti kita ketahui BEGIN tanpa COMMIT sama artinya de-ngan ROLLBACK. Itu artinya semua akti�tas DML seperti INSERT, UPDATE,DELETE setelah BEGIN dibatalkan, seolah tidak terjadi.

Solusinya adalah memberitahukan SQLAlchemy untuk menjalankan autocommit. Ubahlah transaksi.py menjadi berikut ini.

Listing 8.10: transaksi.py

1 import sqla lchemy as sa2 from sqla lchemy . s q l . e xp r e s s i on import t ex t3 import sys4

5 u r l = ' po s t g r e s q l : // ilham :1234 @loca lhos t / t o t a l i ndo '

Page 73: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 8. PYTHON AKSES DATABASE 72

6 db = sa . create_engine ( u r l )7

8 print ' Transaks i '9 pid = raw_input ( ' ID pegawai : ' )

10 try :11 pid = in t ( pid )12 except ValueError :13 sys . e x i t ( ' ID pegawai %s t idak benar ' % pid )14

15 s q l = "SELECT nama FROM pegawai WHERE id = %d" % pid16 q = db . execute ( s q l )17 i f not q . rowcount :18 sys . e x i t ( ' ID pegawai %d t idak ada ' % pid )19 print 'Nama: ' , q . f e t chone ( ) . nama20

21 ket = raw_input ( ' Keterangan : ' )22 i f not ket :23 sys . e x i t ( ' Keterangan harus d i i s i ' )24

25 nominal = raw_input ( ' Nominal : ' )26 try :27 nominal = f l o a t ( nominal )28 except ValueError :29 sys . e x i t ( ' Nominal %s t idak benar ' % nominal )30

31 s q l = "SELECT t r an s ak s i (%d, '% s ' ,%.2 f ) " % ( pid , ket ,nominal )

32 q = db . execute ( t ex t ( sq l , autocommit=True ) )33 print ' Transaks i be rha s i l , ID ' , q . f e t chone ( ) . t r an s ak s i

Penambahan pada baris 2:

from sqlalchemy.sql.expression import text

dan perubahan pada baris 32 dari

q = db.execute(sql)

menjadi

q = db.execute(text(sql, autocommit=True))

8.3 Synchronizer

Pelanggan Anda memiliki usaha di bidang mini market dan telah memiliki bebe-rapa outlet. Semua outlet itu telah terhubung ke Internet. Internet digunakanuntuk mengambil data produk yang dikirim kantor pusat melalui email. Data

Page 74: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 8. PYTHON AKSES DATABASE 73

produk tersebut tersimpan dalam attachment. User di outlet menyimpannya kefolder tertentu untuk selanjutnya dimasukkan ke database outlet melalui menuRestore yang telah disediakan di aplikasi. Begitu juga dengan data transak-si. Data disimpan terlebih dahulu ke dalam sebuah �le melalui menu Backup.Selanjutnya �le tersebut di-email ke kantor pusat.

Teknik ini sudah baik, namun lebih baik lagi jika pekerjaan itu dilakukanoleh script yang disebut synchronizer.

Kita membicarakan mekanisme otomatis penuh, dimana synchronizer dipicuoleh waktu, misalkan jam 9:00 dan jam 17:00 setiap harinya. Berbeda denganteknik sebelumnya, synchronizer tidak menggunakan email untuk komunikasidata. Ia bekerja langsung dengan database pusat dan database outlet.

Lalu bagaimana kedua host outlet dan pusat saling terhubung ?Ya, kita memerlukan IP publik di kantor pusat agar synchronizer di

outlet dapat mengakses database pusat. IP publik ini dapat dipesan ke ISP(Internet Service Provider) bersangkutan. Setelah IP publik didapat, tambahk-an baris berikut ini di /etc/postgresql/8.4/main/pg_hba.conf:

host all all 0.0.0.0/0 md5

Kon�gurasi ini artinya semua host dapat mengakses database pusat, tentunyadengan otenti�kasi username dan password. Simpan dan restart daemon-nya:

1 $ sudo s e r v i c e po s tg r e sq l −8.4 r e s t a r t2 * Restar t ing PostgreSQL 8 .4 database s e r v e r

Kini saatnya uji konektivitas database. Misalkan IP publiknya adalah 110.137.120.251,maka jalankan di outlet:

1 $ psq l −U ilham −h 110 . 137 . 120 . 251 t o t a l i ndo

Di script Python gantilah localhost dengan IP publik tadi.

url = 'postgresql://ilham:[email protected]/totalindo'

Mudah bukan ?

8.3.1 Aspek Keamanan

Tapi nanti dulu. Meski outlet itu hanya mendapat akses terbatas di databasepusat, namun tetap saja ini masih menimbulkan resiko keamanan data. Alang-kah baiknya menggunakan teknik sebaliknya, yaitu synchronizer berada dipusat. Dengan kata lain pusat-lah yang membaca database outlet, sedangkanoutlet tidak mendapat hak akses apapun di database pusat.

Lalu bagaimana host pusat mengakses host outlet ? Apa perlu pesan IPpublik lagi ke ISP yang ada di outlet ?

Idealnya ya, namun tidak harus. Kita bisa menerapkan VPN alias VirtualPrivate Network. Cukup pasang VPN server di pusat, dan pasang VPN clientdi outlet. Dengan VPN ini terbentuk jaringan baru dengan IP pusat 10.8.0.1,

Page 75: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 8. PYTHON AKSES DATABASE 74

sedangkan IP outlet 10.8.0.6, 10.8.0.10, 10.8.0.14, dst. Baik VPN server maupunVPN client bisa kita gunakan OpenVPN. Untuk pemasangan keduanya silahkanbaca url berikut ini:

http://jabber.rab.co.id/os/konfigurasi-openvpn

Apakah OpenVPN dapat bekerja di Windows mengingat masih banyak outletyang menggunakan sistem operasi ini ?

Ya, untungnya OpenVPN tersedia di untuk sistem operasi itu, dan tetapdapat diatur agar otomatis aktif saat komputer dihidupkan.

Baik di pusat maupun di outlet jalankan perintah ini untuk mengetahi IPVPN masing-masing:

1 $ i f c o n f i g tun02 tun0 Link encap :UNSPEC HWaddr

00−00−00−00−00−00−00−00−00−00−00−00−00−00−00−003 i n e t addr : 1 0 . 8 . 0 . 6 P−t−P: 1 0 . 8 . 0 . 5 Mask

: 2 5 5 . 2 5 5 . 2 5 5 . 2 5 54 UP POINTOPOINT RUNNING NOARP MULTICAST MTU

:1500 Metric : 15 RX packets : 0 e r r o r s : 0 dropped : 0 overruns : 0

frame : 06 TX packets : 6 e r r o r s : 0 dropped : 0 overruns : 0

c a r r i e r : 07 c o l l i s i o n s : 0 txqueue len :1008 RX bytes : 0 ( 0 . 0 B) TX bytes :963 (963 . 0 B)

Tampak IP VPN di outlet adalah 10.8.0.6, sedangkan IP VPN di pusatbiasanya 10.8.0.1. Di host pusat, Anda juga bisa lihat IP masing-masing client di�le /etc/openvpn/ipp.txt. Jangan lupa untuk menguji konektivitas networkdengan perintah ping.

OpenVPN telah terpasang dan kedua host pusat dan outlet sudah bisa salingping. Selanjutnya apa yang harus dilakukan ?

Tambahkan baris berikut ini di /etc/postgresql/8.4/main/pg_hba.confdi outlet.

host all all 10.8.0.1/32 md5

Lalu restart daemon-nya.

1 $ sudo s e r v i c e po s tg r e sq l −8.4 r e s t a r t2 * Restar t ing PostgreSQL 8 .4 database s e r v e r

Di pusat lakukan uji konektivitas dengan psql.

1 $ psq l −U ilham −h 1 0 . 8 . 0 . 6 t o t a l i ndo

Jika sudah terhubung baik, saatnya membuat script synchronizer.

Page 76: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 8. PYTHON AKSES DATABASE 75

8.3.2 Tambah, Perbaharui, Hapus

Adalah sebuah tabel produk dengan struktur sebagai berikut:

Listing 8.11: produk.sql

1 create table produk (2 id s e r i a l primary key ,3 nama name not null unique ,4 harga f loat not null5 ) ;

Isilah dengan beberapa record berikut ini:

1 INSERT INTO produk (nama , harga ) SELECT ' Jeruk Pontianak ', 10500 ;

2 INSERT INTO produk (nama , harga ) SELECT ' Salak Pondoh ', 9250 ;

3 INSERT INTO produk (nama , harga ) SELECT 'Mangga Indramayu ',14300 ;

Untuk menyamakan data produk, kita memerlukan dua perulangan (loop).Yang pertama untuk INSERT dan UPDATE, sedangkan yang kedua untuk DE-LETE. Berikut yang pertama:

1. Setiap record pusat dibaca.

2. Field id menjadi acuan, karena dia primary key.

3. Jika id tidak ditemukan di outlet maka tambahkan.

4. Jika id ditemukan maka perbaharui.

Sedangkan untuk menghapus:

1. Setiap record outlet dibaca.

2. Jika id tidak ditemukan di pusat maka hapus yang ada di outlet.

Lalu mulailah membuat sync.py berikut ini.

Listing 8.12: sync.py

1 import sqla lchemy as sa2 from e l i x i r import Entity , using_options , setup_al l ,

metadata3 from sqla lchemy . orm import scoped_sess ion , sess ionmaker4 from sqla lchemy . schema import ThreadLocalMetaData5

6

7 es = sa . create_engine ( ' p o s t g r e s q l : // ilham :1234 @loca lhos t /t o t a l i ndo ' )

Page 77: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 8. PYTHON AKSES DATABASE 76

8 et = sa . create_engine ( ' p o s t g r e s q l : // ilham :1234 @loca lhos t /t o t a l i ndo2 ' )

9

10 s s = scoped_sess ion ( sess ionmaker ( bind=es ) )11 s t = scoped_sess ion ( sess ionmaker ( bind=et ) )12

13 ms = metadata14 mt = ThreadLocalMetaData ( )15

16 ms . bind = es17 mt . bind = et18

19

20 class ProdukS ( Entity ) :21 using_options ( tablename=' produk ' , auto load=True ,

metadata=ms , s e s s i o n=s s )22

23 class ProdukT( Entity ) :24 using_options ( tablename=' produk ' , auto load=True ,

metadata=mt , s e s s i o n=s t )25

26 se tup_al l ( )27

28 # INSERT & UPDATE29

30 a l l_ps = [ ]31 for ps in ProdukS . query . a l l ( ) :32 print ps . id , ps . nama , ps . harga ,33 try :34 pt = ProdukT . query . f i l t e r_by ( id=ps . id ) . one ( )35 print ' diubah '36 except sa . orm . exc . NoResultFound , e :37 print ' ditambah '38 pt = ProdukT( id=ps . id )39 pt . nama = ps . nama40 pt . harga = ps . harga41 s t . commit ( )42 a l l_ps . append ( ps . id )43

44 # DELETE45

46 for pt in ProdukT . query . a l l ( ) :47 i f pt . id not in a l l_ps :48 print pt . id , pt . nama , pt . harga , ' dihapus '49 pt . d e l e t e ( )50 s t . commit ( )

Page 78: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 8. PYTHON AKSES DATABASE 77

8.4 Migrasi dari Database Lain

Anda sudah memiliki aplikasi yang menggunakan MySQL, dan kini ingin beralihke PostgreSQL. Setidaknya dibutuhan penyalinan struktur tabel beserta isinya.

Terlebih dahulu pasanglah driver MySQL.

1 $ sudo apt−get i n s t a l l python−mysqldb

Lalu buatlah dbmigration.py berikut ini.

Listing 8.13: dbmigration.py

1 import sqla lchemy as sa2 from sqla lchemy . schema import ThreadLocalMetaData3 from sqla lchemy . orm import scoped_sess ion , sess ionmaker4 from e l i x i r import *

5 import sys6

7

8 dbs = sa . create_engine ( sys . argv [ 1 ] ) # source9 dbt = sa . create_engine ( sys . argv [ 2 ] ) # ta r g e t

10 dbs . connect ( )11 dbt . connect ( )12 s e s s i on_s = scoped_sess ion ( sess ionmaker ( bind=dbs ) )13 s e s s i on_t = scoped_sess ion ( sess ionmaker ( bind=dbt ) )14 metadata_s = metadata15 metadata_t = ThreadLocalMetaData ( )16 metadata_s . bind = dbs17 metadata_t . bind = dbt18

19 for tablename in dbs . table_names ( ) :20 class Source ( Entity ) :21 using_options ( tablename=tablename , auto load=True ,22 metadata=metadata_s , s e s s i o n=ses s i on_s )23

24 se tup_al l ( )25

26 class Target ( Entity ) :27 using_options ( tablename=tablename ,28 metadata=metadata_t , s e s s i o n=ses s i on_t )29 for column in Source . mapper . columns :30 has_f i e ld ( column . name , column . type ,31 primary_key=column . primary_key ,32 r equ i r ed=not column . nu l l ab l e ,33 )34

35 se tup_al l (True )36

Page 79: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 8. PYTHON AKSES DATABASE 78

Database Paket

PostgreSQL python-psycopg2MySQL python-mysqldbSQLite python-sqlite2Interbase python-kinterbasdbMS SQL python-pymssql

Tabel 8.1: Driver database

37 for source in Source . query . a l l ( ) :38 t a r g e t = Target ( )39 t a r g e t . from_dict ( source . to_dict ( ) )40 s e s s i on_t . commit ( )

Contoh penggunaan:

1 python dbmigration . py mysql : // root :6789 @loca lhos t /sumberpo s tg r e s : // j e f r i :1234 @loca lhos t / t a r g e t

Proses migrasi ini sudah menyertakan pembuatan tabel berikut constraintseperti PRIMARY KEY dan NULL.

Untuk driver database lainnya Anda bisa lihat di informasi paket python-sqlalchemy, dan perhatikan bagian Suggests.

1 $ dpkg −s python−sqla lchemy2 . .3 Suggests : python−sqlalchemy−doc , python−psycopg2 , python−

mysqldb (>= 1.2.1−p2−2) , python (>= 2 . 5 ) | python−py s q l i t e 2 (>= 2.3.0−1) | python−py s q l i t e 1 . 1 (>=1.1.7−2) | python−s q l i t e (>= 1.0.1−5) , python−k interbasdb (>= 3.1 .2 −0 .3 ) , python−pymssql

4 . .

Perhatikan bagian Suggests.

Page 80: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

Bab 9

Lintas Sistem

Kita telah membahas mengenai manfaat modularitas dalam fungsi dan moduldimana sebuah aplikasi disusun bagaikan sebuah lego. Jika keseluruhan sistemsemakin kompleks maka hindari �konsep pemaksaan� seperti �semua harus ditu-lis dengan Python� atau �semua harus menggunakan PostgreSQL�. Kali ini kitacoba pahami bagaimana komunikasi antar sistem bisa terjadi tanpa pemaksaanplatform tertentu.

9.1 Command Line

Script Python Anda membutuhkan informasi mengenai network device berikutIP-nya. Anda tidak tahu modul apa yang bisa digunakan. Namun Anda tahubetul bahwa command line ifcon�g sanggup melakukannya.

1 $ i f c o n f i g2 eth0 Link encap : Ethernet HWaddr 0 0 : 2 5 : b3 : 7 7 : 3 e : 993 i n e t addr : 1 9 2 . 1 6 8 . 1 1 . 1 1 1 Bcast : 1 9 2 . 1 6 8 . 1 1 . 2 5 5

Mask : 2 5 5 . 2 5 5 . 2 5 5 . 04 UP BROADCAST MULTICAST MTU:1500 Metric : 15 RX packets : 0 e r r o r s : 0 dropped : 0 overruns : 0

frame : 06 TX packets : 0 e r r o r s : 0 dropped : 0 overruns : 0

c a r r i e r : 07 c o l l i s i o n s : 0 txqueue len :10008 RX bytes : 0 ( 0 . 0 B) TX bytes : 0 ( 0 . 0 B)9 In t e r rup t : 17

10

11 l o Link encap : Local Loopback12 i n e t addr : 1 2 7 . 0 . 0 . 1 Mask : 2 5 5 . 0 . 0 . 013 i n e t 6 addr : : : 1 / 128 Scope : Host14 UP LOOPBACK RUNNING MTU:16436 Metric : 1

79

Page 81: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 9. LINTAS SISTEM 80

15 RX packets :562 e r r o r s : 0 dropped : 0 overruns : 0frame : 0

16 TX packets :562 e r r o r s : 0 dropped : 0 overruns : 0c a r r i e r : 0

17 c o l l i s i o n s : 0 txqueue len : 018 RX bytes :540848 (540 . 8 KB) TX bytes :540848

(540 . 8 KB)19

20 wlan0 Link encap : Ethernet HWaddr 00 :1 f : 3 c : e0 : 6 6 : 5 621 i n e t addr : 1 9 2 . 1 6 8 . 1 . 4 Bcast : 1 9 2 . 1 6 8 . 1 . 2 5 5

Mask : 2 5 5 . 2 5 5 . 2 5 5 . 022 i n e t 6 addr : f e80 : : 2 1 f : 3 c f f : f e e 0 :6656/64 Scope :

Link23 UP BROADCAST RUNNING MULTICAST MTU:1500

Metric : 124 RX packets :3219 e r r o r s : 0 dropped : 0 overruns : 0

frame : 025 TX packets :3608 e r r o r s : 0 dropped : 0 overruns : 0

c a r r i e r : 026 c o l l i s i o n s : 0 txqueue len :100027 RX bytes :1586297 ( 1 . 5 MB) TX bytes :761173

(761 . 1 KB)

Bagaimana memanggil command line di script Python dan mengolah hasil-nya ? Gunakan modul commands. Buatlah netdev.py berikut ini.

Listing 9.1: netdev.py

1 import commands2 import re3

4 def netdev ( ) :5 r = {}6 for l i n e in commands . getoutput ( ' i f c o n f i g ' ) . s p l i t l i n e s

( ) :7 l i n e = l i n e . s t r i p ( )8 match = re . compi le ( ' ( . * ) Link encap ( . * ) ' ) . s earch (

l i n e )9 i f match :

10 dev i c e = match . group (1) . s t r i p ( )11 r [ dev i c e ] = {}12 match = re . compi le ( 'HWaddr ( . * ) ' ) . s earch ( l i n e

)13 i f match :14 r [ dev i c e ] [ ' addr ' ] = match . group (1 )15 continue16 match = re . compi le ( ' i n e t addr : ( . * ) ' ) . s earch ( l i n e )

Page 82: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 9. LINTAS SISTEM 81

17 i f match :18 r [ dev i c e ] [ ' ip ' ] = match . group (1) . s p l i t ( ) [ 0 ]19 return r20

21

22 i f __name__ == '__main__ ' :23 nd = netdev ( )24 for dev in nd :25 print dev , nd [ dev ]

Jalankan.

1 $ python netdev . py2 wlan0 { ' ip ' : ' 1 9 2 . 1 6 8 . 1 . 4 ' , ' addr ' : ' 0 0 : 1 f : 3 c : e0 : 6 6 : 5 6 ' }3 l o { ' ip ' : ' 1 2 7 . 0 . 0 . 1 ' }4 eth0 { ' ip ' : ' 1 9 2 . 1 68 . 1 1 . 1 11 ' , ' addr ' : ' 0 0 : 2 5 : b3 : 7 7 : 3 e

: 99 ' }

Lintas sistem yang menggunakan command line ini tergolong lokal, artinyanetdev.py harus berada di komputer yang sama dengan ifcon�g.

9.2 File

File bisa digunakan sebagai sarana pemersatu input dan output. Misalkan An-da sudah membuat sebuah daemon yang dapat menerima dan mengirim SMS.Daemon ini pengendali modem. Oh ya, daemon adalah program yang selaluhidup untuk siap menerima perintah.

Di sisi lain Anda juga punya program penerjemah SMS yang masuk (SMSparser) dan juga berfungsi untuk membalas ke si pengirim. Bagaimana keduaprogram ini dapat berhubungan ?

Anda bisa menggunakan �le sebagai perantara. Saat ada SMS masuk, dae-mon pengendali modem menyimpannya dalam sebuah �le di direktori /var/spo-ol/modem/inbox. Kemudian SMS parser membaca direktori ini, menerjemahk-an �lenya, dan membalas SMS tersebut dengan cara membuat �le di direktori/var/spool/modem/outbox. File tersebut dibaca oleh daemon si modem untukkemudian mengirim SMS yang dimaksud.

Baik daemon modem maupun SMS parser bisa ditulis dengan bahasa yangberbeda. Mungkin yang pertama dengan C++, sementara yang satunya di tulisdengan Python. Namun keduanya bekerja menggunakan direktori yang sama.

Ini juga tergolong lintas sistem yang lokal, keduanya harus di komputer yangsama.

Dengan teknik NFS atau Samba Anda bisa membuat direktori ber-sama (sharing directory) di komputer lain (remote host).

Page 83: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 9. LINTAS SISTEM 82

9.3 Database

Pelanggan Anda telah memiliki sebuah sistem pengisian pulsa dimana terdapatfungsi yang berkaitan dengan GSM modem. Fungsi yang dimaksud adalah yangberkaitan dengan SMS gateway yaitu mengirim dan menerima SMS.

Pelanggan ini telah membuat sistemnya menggunakan Borland Delphi (ba-hasa Pascal) dan menggunakan database MySQL. Ia mengeluh pada Anda se-laku developer outsourcing dimana komponen SMS gateway yang dibangunnyatidak stabil. Di sisi lain Anda telah membuat SMS gateway yang ditulis de-ngan bahasa Python dan database PostgreSQL. Tidak seperti yang dimiliki pe-langgan tersebut, SMS gateway yang Anda buat sangat stabil dan telah terujibertahun-tahun. Masalah penyatuan semakin bertambah dimana SMS gatewayAnda berada di sistem operasi Linux, sementara pelanggan Anda menggunakanMicrosoft Windows.

Langkah apa yang diambil untuk membuat SMS gateway-nya stabil ? Andabelajar Borland Delphi untuk menerjemahkan algoritma Python ? Atau me-maksa pelanggan Anda itu untuk belajar Python dan membangun ulang sistempengisian pulsanya ?

Langkah yang bijaksana tentu tidak keduanya, karena porsi tidak seimbangyang mengakibatkan penyatuan menjadi sangat lama. Solusi sederhana adalahmenggunakan database sebagai perantara. Mintalah padanya untuk menyedi-akan sebuah komputer lagi untuk SMS gateway Anda, sebut saja server SMSgateway. Server ini terhubung melalui LAN (local area network) dengan serverpengisian pulsa yang berbasis Windows tadi.

Tanpa perubahan ? Tentu saja ada.Rancangan SMS gateway yang Anda buat harus dapat mengirim SMS hanya

dengan menggunakan perintah INSERT. Contoh:

1 INSERT INTO im . ant r i an ( penerima , pesan ) SELECT '+628177654321 ' , ' Selamat bergabung ' ;

Lalu apa yang dilakukan oleh pelanggan Anda tadi ? Ia perlu mengubahsource Borland Delphi-nya, yaitu pada fungsi pengiriman SMS menggunakankoneksi ke database PostgreSQL yang ada di server SMS gateway. Biasanyadriver ODBC dapat mengatasi hal ini.

Lho, bukankah ia menggunakan MySQL sebagai database ? Benar, MySQLuntuk komponen pengisian pulsa tetap berlaku. Jadi dalam aplikasi BorlandDelphi terdapat dua koneksi database, yaitu ke MySQL yang ada di localhostMicrosoft Windows, dan ke PostgreSQL yang ada di remote host Linux.

Lalu bagaimana untuk membaca SMS yang masuk ? Kembali, Anda dimintauntuk menyimpan SMS yang masuk ke dalam sebuah tabel, katakanlah bernamainbox. Selanjutnya pelanggan Anda dapat membacanya menggunakan perintahSELECT pada Borland Delphi.

1 SELECT * FROM im . ant r i an WHERE NOT kir im ;

Mudah bukan ? Lebih lanjut mengenai SMS gateway bisa lihat halaman114.

Page 84: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 9. LINTAS SISTEM 83

Lintas sistem ini tergolong bisa beda komputer, karena baik PostgreSQLmaupun MySQL dapat diakses melalui jalur network.

9.4 XMLRPC

Database sebagai perantara bisa jadi ditolak dengan berbagai alasan. Salahsatunya adalah aspek tanggung jawab, atau biasa disebut aspek keamanan (se-curity). Misalkan dalam sistem perbankan. Sistem utama sebuah bank diba-ngun oleh PT Software Aman Banget (SAB). Namanya juga sistem utama, iamemuat data penting nasabah serta data yang menyangkut sistem.

Suatu saat bank ini ingin go Internet dimana nasabah dapat melakukan tran-saksi melalui browser Firefox. Berarti dibutuhkan web developer dan dipilihlahPT Web Perkasa (WP) untuk mengembangkannya. Karena mengembangkanInternet banking, berarti ada proses login untuk nasabah. Ini berarti ada al-goritma pemeriksaan username dan password. Sampai disini tidaklah menjadimasalah karena username dan password web bisa berada di web server yangdibangun oleh WP.

Tibalah saatnya nasabah ingin melihat mutasi transaksinya. Apakah WPmelakukan SELECT tabel ke sistem utama bank tersebut yang dibangun olehSAB ?

Mayoritas jawabannya tidak. Mengapa ?SELECT berarti kita bicara koneksi ke database. Itu artinya WP meng-

etahui username dan password untuk login ke database sistem utama. Kalausudah begitu maka WP bisa melihat-lihat data nasabah lainnya, bahkan meli-hat tabel-tabel yang menyangkut sistem. Jelas ini sudah terlalu jauh dan bisamenimbulkan hal-hal yang tak perlu.

Untuk menghindari koneksi database ke sistem utama, maka digunakanlahXMLRPC sebagai perantaranya. Makanan apakah ini ?

XMLRPC adalah XML Remote Procedure Call, yaitu sebuah �bahasa� per-tukaran data yang ditulis dalam format XML. Kita dapat memandang RPCsebagai pemanggilan fungsi yang memiliki nilai masukan (input parameter) dannilai keluaran (output / return value). Sebagaimana fungsi sederhana ini.

1 de f tambah (a , b) :2 re turn a + b

XMLRPC bisa juga disebut sebagai web service karena dokumen XML ter-sebut dikirim menggunakan HTTP atau HTTPS dengan method POST. Karenaweb service, maka kita bicara koneksi client - server, sehingga ada penyebutanXMLRPC client dan XMLRPC server. Penggunaannya tergolong simple danpustakanya (library) banyak tersedia untuk berbagai bahasa seperti Python,PHP, Java, Borland Delphi, Visual Basic, dst.

Kembali pada web developer di atas. WP mengembangkan web-nya menggu-nakan PHP, sementara SABmengembangkan sistem bank menggunakan Python.Database keduanya juga berbeda dimana WP menggunakan MySQL, sedangkanSAB menggunakan PostgreSQL. Namun semuanya itu tidak lagi menjadi hal.

Page 85: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 9. LINTAS SISTEM 84

Langkah apa yang harus dikembangkan terlebih dahulu ?Jelas bahwa SAB harus mengembangkan XMLRPC server terlebih dahulu

yang berisi fungsi mutasi(). Mari kita mulai membuat �le serverbank.py.

Listing 9.2: serverbank.py

1 from SimpleXMLRPCServer import SimpleXMLRPCServer2 import sqla lchemy as sa3

4

5 class Server (SimpleXMLRPCServer ) :6 al low_reuse_address = True7

8 def ve r i f y_reque s t ( s e l f , request , c l i en t_addre s s ) :9 s e r v e r . i p_c l i en t = c l i en t_addre s s [ 0 ]

10 print s e r v e r . i p_c l i en t11 return s e r v e r . i p_c l i en t in [ ' 1 2 7 . 0 . 0 . 1 ' , '

1 9 2 . 1 6 8 . 0 . 1 ' , ' 1 9 2 . 1 6 8 . 1 . 5 ' ]12

13

14 def re sp ( code , msg) :15 return { ' kode ' : code ,16 ' pesan ' : msg}17

18

19 class Agent :20 def _dispatch ( s e l f , method , params=() ) :21 print method , params22 try :23 func = ge t a t t r ( s e l f , ' export_ ' + method )24 except Attr ibuteError :25 return re sp (−1 , ' Fungsi %s t idak d ikena l ' %

method )26 return func (*params )27

28 def export_mutasi ( s e l f , p ) :29 s q l = "SELECT t g l : : date , ket , nominal , sa ldo " +

\30 "FROM t r an s ak s i WHERE pid = %d " + \31 "AND t g l : : date BETWEEN '%s ' AND '%s ' " + \32 "ORDER BY id "33 s q l = sq l % (p [ ' pid ' ] , p [ ' awal ' ] , p [ ' akh i r ' ] )34 q = db . execute ( s q l )35 m = [ ]36 for r in q :37 m. append ( [ s t r ( r . t g l ) , r . ket , r . nominal , r .

s a ldo ] )

Page 86: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 9. LINTAS SISTEM 85

38 r = resp (0 , 'OK' )39 r [ ' mutasi ' ] = m40 return r41

42

43

44 u r l = ' po s t g r e s q l : // ilham :1234 @loca lhos t / t o t a l i ndo '45 db = sa . create_engine ( u r l )46

47 port = 930348 s e r v e r = Server ( ( ' 0 . 0 . 0 . 0 ' , port ) )49 s e r v e r . r e g i s t e r_ in t r o sp e c t i on_ func t i on s ( )50 s e r v e r . r e g i s t e r_ in s t an c e (Agent ( ) )51 print 'HTTP XMLRPC s e r v e r port ' , port52 s e r v e r . s e rve_foreve r ( )

Jalankan.

1 $ python serverbank . py2 HTTP XMLRPC se rv e r port 9303

Proses seolah hang, tapi sebenarnya ia sedang menunggu permintaan (re-quest) dari XMLRPC client. Port 9303 hanya contoh saja dimana Anda bisamengganti dengan nilai lainnya. Security yang diterapkan di sini adalah IPclient yang hanya menerima permintaan dari 127.0.0.1 dan 192.168.0.1.

Selanjutnya membuat XMLRPC client bernama clientbank.py.

Listing 9.3: clientbank.py

1 import xmlrpc l ib2

3 u r l = ' http : / / 1 2 7 . 0 . 0 . 1 : 9 3 0 3 '4 remote = xmlrpc l ib . ServerProxy ( u r l )5 d = { ' pid ' : 1 ,6 ' awal ' : ' 20101022 ' ,7 ' akh i r ' : ' 20101023 ' }8 r = remote . mutasi (d)9 i f r [ ' kode ' ] == 0 :

10 for tg l , ket , nominal , sa ldo in r [ ' mutasi ' ] :11 print tg l , ket . l j u s t (15) , \12 s t r ( i n t ( nominal ) ) . r j u s t (10) , \13 s t r ( i n t ( sa ldo ) ) . r j u s t (10)14 else :15 print r [ ' pesan ' ]

Bukalah konsole lainnya, lalu jalankan �le ini.

1 $ python c l i en tbank . py2 2010−10−22 GAJI 11−2010 3000000 30000003 2010−10−22 BON −200000 2800000

Page 87: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 9. LINTAS SISTEM 86

Cermati baik-baik konsepnya. Juga perhatikan tipe data dictionary dan listyang digunakan sebagai nilai keluaran (return value) dari fungsi mutasi.

9.4.1 PHP sebagai XMLRPC Client

Unduh xmlrpc.inc dari http://phpxmlrpc.sourceforge.net. File itu berada dixmlrpc-2.2.2.tar.gz. Carilah. Versi lain sepertinya juga tidak masalah. Lalubuatlah �le clientbank.php.

Listing 9.4: clientbank.php

1 <?php2 include ( ' xmlrpc . inc ' ) ;3 $params = new xmlrpcval (4 array (5 ' pid ' => new xmlrpcval (1 , ' i n t ' ) ,6 ' awal ' => new xmlrpcval ( ' 20101022 ' ) ,7 ' akh i r ' => new xmlrpcval ( ' 20101023 ' )8 ) ,9 ' s t r u c t '

10 ) ;11 $ f = new xmlrpcmsg ( ' mutasi ' , array ( $params ) ) ;12 $c = new xmlrpc_cl ient ( ' / ' , ' 1 2 7 . 0 . 0 . 1 ' , 9303) ;13 $r = $c−>send ( $ f ) ;14 $v = $r−>value ( ) ;15 i f ( $r−>faultCode ( ) ) {16 print $r−>f au l t S t r i n g ( ) ;17 } else {18 $resp = $v−>s c a l a r v a l ( ) ;19 i f ( $resp [ ' kode ' ]−>s c a l a r v a l ( ) == 0) {20 foreach ( $resp [ ' mutasi ' ]−>s c a l a r v a l ( ) as $ i=>$m) {21 $ f = $m−>s c a l a r v a l ( ) ;22 $ t g l = $ f [0]−> s c a l a r v a l ( ) ;23 $ket = $ f [1]−> s c a l a r v a l ( ) ;24 $nominal = $ f [2]−> s c a l a r v a l ( ) ;25 $sa ldo = $ f [3]−> s c a l a r v a l ( ) ;26 print $ t g l . " " .27 str_pad ( $ket , 2 0 ) . " " .28 str_pad ( $nominal , 1 0 ) . " " .29 str_pad ( $saldo , 1 0 ) . "\n" ;30 }31 } else {32 print $resp [ ' pesan ' ]−>s c a l a r v a l ( ) ;33 }34 }35 ?>

Page 88: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 9. LINTAS SISTEM 87

Karena script ini akan kita jalankan sebagai command line, maka pasangdulu paket terkait.

1 $ sudo apt−get i n s t a l l php5−c l i

Lalu jalankan.

1 $ php cl ient_bank . php2 2010−10−22 GAJI 11−2010 3000000 30000003 2010−10−22 BON −200000 2800000

9.4.2 Drupal

Drupal1 juga ditulis dengan PHP. Ia sudah memuat function xmlrpc, sehinggaAnda tidak perlu memasang modul tambahan. Cara penulisannya juga lebihmudah. Contoh berikut ini untuk Drupal 6.

Buatlah �le sites/all/modules/pegawai/pegawai.module berikut.

Listing 9.5: pegawai.module

1 <?php2 f unc t i on pegawai_menu ( ) {3 $items = array ( ) ;4 $items [ ' pegawai/ t rx/%/%/% ' ] = array (5 ' t i t l e ' => ' Transaks i ' ,6 ' page ca l l ba ck ' => ' pegawai_trx ' ,7 ' page arguments ' => array ( 2 , 3 , 4 ) ,8 ' a c c e s s ca l l b a ck ' => ' user_access ' ,9 ' type ' => MENU_CALLBACK,

10 ) ;11 re turn $items ;12 }13

14 f unc t i on pegawai_trx ( $pid , $awal , $akh i r ) {15 $ur l = ' http : / / 1 2 7 . 0 . 0 . 1 : 9 3 0 3 ' ;16 $p = array ( ' pid ' => intval ( $pid ) ,17 ' awal ' => $awal ,18 ' akh i r ' => $akhi r ) ;19 $r = xmlrpc ( $ur l , ' mutasi ' , $p ) ;20 i f ( ! $r [ ' mutasi ' ] ) {21 re turn drupal_set_message ( ' Tidak ada data ' ) ;22 }23 $c = '<table><th>Tanggal</th><th>Keterangan</th>' .24 '<th>Nominal</th><th>Saldo</th></tr>' ;25 foreach ( $r [ ' mutasi ' ] as $ i=>$f ) {26 $ t g l = $ f [ 0 ] ;

1http://drupal.org

Page 89: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 9. LINTAS SISTEM 88

27 $ket = $ f [ 1 ] ;28 $nominal = $ f [ 2 ] ;29 $sa ldo = $ f [ 3 ] ;30 $c .= '<tr><td>' . $ t g l . '</td>' ;31 $c .= '<td>' . $ket . '</td>' ;32 $c .= '<td a l i g n="r i gh t"> ' . format_number ( $nominal

) . '</td>' ;33 $c .= '<td a l i g n="r i gh t"> ' . format_number ( $sa ldo ) .

'</td>' ;34 $c .= '</tr>' ;35 }36 re turn $c ;37 }

Juga buat sites/all/modules/pegawai/pegawai.info.

Listing 9.6: pegawai.info

1 name = Pegawai2 d e s c r i p t i o n = Data pegawai3 core = 6 . x4 ve r s i on = "6 . x−1.0"

Setelah login di browser, masuklah ke menu admin/build/modules. Centangmodul pegawai dan klik Save. Lalu masukkan URL di browser seperti

pegawai/trx/1/20101022/20101023

Page 90: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

Bab 10

Pengemasan

10.1 Paket Debian

Pada bab sebelumnya kita sudah membuat modul uang.py. Agar modul ini da-pat digunakan oleh user lainnya maka diletakkanlah di direktori /usr/local/lib/python2.6/dist-packages. Proses copy modul seperti ini memang sudah mudah, tapi ada lagiyang lebih memudahkan, yaitu dengan mengemasnya dalam bentuk paket De-bian.

Langkah kemudahan yang dimaksud adalah:

1. Tambahkan URL daftar paket dalam sebuah �le /etc/apt/sources.list.d/custom.listyang berisideb http://192.168.0.1/deb ./

2. Perbaharui daftar paket$ sudo apt-get update

3. Pasang paket dimaksud$ sudo apt-get install python-uang

Manfaat lain pemaketan adalah mudahnya pemasangan paket lainnya yang di-butuhkan oleh paket utama, sering disebut sebagai dependencies. Misalkanpaket python-uang tadi membutuhkan python-sqlalchemy, maka pada saat

1 $ sudo apt−get i n s t a l l python−uang

otomatis python-sqlalchemy juga ikut dipasang.

Penamaan python-uang dimana ada awalan python- dikarenakanuang.py adalah modul Python yang umum. Dengan kata lain bi-sa digunakan di aplikasi apa saja. Tidak ada koneksi database disana. Juga tidak ada perintah akses database seperti SELECT dkk.Awalan ini juga meniru dari paket umum lainnya seperti python-sqlalchemy, python-psycopg2, python-serial, dst.

89

Page 91: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 10. PENGEMASAN 90

Mulailah membuat direktori kerja, yaitu /usr/local/src/python-uang.

1 $ sudo mkdir −p / usr / l o c a l / s r c /python−uang/DEBIAN

Perintah ini otomatis membuat dua buah direktori yaitu

1. /usr/local/src/python-uang

2. /usr/local/src/python-uang/DEBIAN

Direktori DEBIAN digunakan untuk meletakkan �le-�le yang berkaitan dengansistem paket seperti

control berisi informasi seputar paket.

postinst script yang dijalankan saat pemasangan berlangsung, yaitu saat apt-get install atau dpkg -i. Script ini harus executable yang bisa diset denganchmod 755.

prerm script yang dijalankan saat penghapusan berlangsung, yaitu saat apt-get remove atau dpkg -r. Script ini juga harus executable.

con�les berisi daftar nama �le kon�gurasi yang digunakan paket ini. Misal-nya berisi /etc/uang.conf. File kon�gurasi ini berisi format negara yangdigunakan oleh fungsi uang(). Jadi tidak hard-code menggunakan loca-le id_ID.UTF-8. Dengan begitu python-uang semakin umum (general).Dengan didaftarkannya /etc/uang.conf di dalam con�les, maka terhindardari penibanan (timpa / overwrite) saat upgrade berlangsung. Misalk-an kini python-uang versi 0.1. Kemudian dibuatlah versi 0.2 yang jugamemuat /etc/uang.conf. Jika di dalam versi 0.2 tidak ada perubahanapa-apa pada /etc/uang.conf maka apt-get install tidak akan melakukantimpa pada /etc/uang.conf yang sudah terpasang. Karena siapa tahuAnda sudah mengganti isi /etc/uang.conf terpasang dengan de_DE.ISO-8859-1. Dengan begitu kita terhindar dari mengubah ulang kon�gurasi.Mudah-mudahan paham maksudnya.

Mulailah membuat �le python-uang/DEBIAN/control.

Listing 10.1: DEBIAN/control

1 Package : python−uang2 Pr i o r i t y : op t i ona l3 Sect i on : python4 Maintainer : Owo Sugiana <sugiana@rab . co . id>5 Arch i t e c tu r e : a l l6 Vers ion : 0 . 17 Depends : python−c en t r a l (>= 0 . 6 . 7 )8 Python−Vers ion : a l l9 Desc r ip t i on : Format uang

Lanjutkan dengan membuat direktori modulnya.

Page 92: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 10. PENGEMASAN 91

1 $ cd / usr / l o c a l / s r c2 $ sudo mkdir −p python−uang/ usr / share / pycent ra l /python−

uang/ s i t e−packages

Perhatikanlah direktori setelah /usr/local/src/python-uang. Semua direk-tori tersebut nantinya akan dipasang di root directory ( / ), kecuali direktoriDEBIAN.

Lalu mengapa menggunakan /usr/share ? Padahal sebelumnya kita mele-takkan uang.py di /usr/local ? Direktori /usr/local yang kita gunakan sebe-lumnya bermakna bahwa uang.py belum menjadi bagian dari paket Debian.Bila sudah menjadi bagian dari paket Debian, maka diletakkan di /usr/share.Begitulah ketentuan umumnya.

1 $ sudo cp / usr / l o c a l / l i b /python2 .6/ d i s t−packages /uang . pypython−uang/ usr / share / pycent ra l /python−uang/ s i t e−packages /

Karena akan menggunakan /etc/user.conf, lakukan perubahan pada uang.pymenjadi berikut ini.

Listing 10.2: usr/share/pycentral/python-uang/site-packages/uang.py

1 import l o c a l e2 from types import IntType3 from Conf igParser import Conf igParser4

5 conf = Conf igParser ( )6 conf . read ( ' / e t c /uang . conf ' )7

8 l o c a l e . s e t l o c a l e ( l o c a l e .LC_ALL, conf . get ( ' d e f au l t ' , 'l o c a l e ' ) )

9

10 DECIMAL = conf . g e t i n t ( ' d e f au l t ' , ' dec imal ' )11

12 def r ibu ( n i l a i , pecahan=None) :13 i f pecahan i s None :14 i f type ( n i l a i ) == IntType :15 pecahan = 016 else :17 pecahan = DECIMAL18 return l o c a l e . format ( '%%.%df ' % pecahan , n i l a i , True )19

20 def uang ( n i l a i , pecahan=None , tanda=None ) :21 i f tanda i s None :22 tanda = l o c a l e . l o c a l e conv ( ) [ ' currency_symbol ' ]23 return '%s%s ' % ( tanda , r ibu ( n i l a i , pecahan ) )24

25

Page 93: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 10. PENGEMASAN 92

26

27 i f __name__ == '__main__ ' :28 n = 10000.529 print uang (n)30 print uang ( i n t (n) )31 print uang (n , 3 )

Buat direktori etc.

1 $ sudo mkdir −p python−uang/ e tc

Selanjutnya buat python-uang/etc/uang.conf.

Listing 10.3: etc/uang.conf

1 [ d e f au l t ]2 l o c a l e = id_ID .UTF−83 decimal = 2

Lalu buat python-uang/DEBIAN/con�les berisi satu baris berikut.

Listing 10.4: DEBIAN/con�les

1 / e tc /uang . conf

Kemudian buat python-uang/DEBIAN/postinst yang berisi perintah untukmendaftarkan uang.py agar dikenal sebagai modul.

Listing 10.5: DEBIAN/postinst

1 #!/bin / sh2 pycent ra l p k g i n s t a l l python−uang

Juga python-uang/DEBIAN/prerm.

Listing 10.6: DEBIAN/prerm

1 #!/bin / sh2 pycent ra l pkgremove python−uang

Buat keduanya executable.

1 $ sudo chmod 755 python−uang/DEBIAN/ po s t i n s t2 $ sudo chmod 755 python−uang/DEBIAN/prerm

Pastikan semua �le dimiliki root.

1 $ sudo chown −R root . root python−uang

Lihat lagi apa yang sudah dibuat.

1 $ f i nd python−uang2 python−uang/3 python−uang/DEBIAN4 python−uang/DEBIAN/ con t r o l5 python−uang/DEBIAN/prerm

Page 94: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 10. PENGEMASAN 93

6 python−uang/DEBIAN/ c o n f f i l e s7 python−uang/DEBIAN/ po s t i n s t8 python−uang/ usr9 python−uang/ usr / share

10 python−uang/ usr / share / pycent ra l11 python−uang/ usr / share / pycent ra l /python−uang12 python−uang/ usr / share / pycent ra l /python−uang/ s i t e−packages13 python−uang/ usr / share / pycent ra l /python−uang/ s i t e−packages

/uang . py14 python−uang/ e tc15 python−uang/ e tc /uang . conf

Kemas.

1 $ sudo dpkg−deb −−bu i ld python−uang .2 dpkg−deb : per ingatan : ' python−uang/DEBIAN/ contro l '

conta in s user−de f ined f i e l d 'Python−Version '3 dpkg−deb : membuat paket ` python−uang ' d i dalam ` . / python−

uang_0 . 1 _al l . deb ' .4 dpkg−deb : per ingatan : i gno r i ng 1 warnings about the

con t r o l f i l e ( s )

Perhatikan ada titik diakhirnya yang berarti letakkan di current directory.Abaikan saja peringatan itu. Karena Python-Version memang bukan standarDebian, tapi digunakan oleh pycentral. Sampai di sini pembuatan paket selesai.

Kini telah terbentuk python-uang_0.1_all.deb yang siap dipasang.

1 $ sudo dpkg − i python−uang_0 . 1 _al l . deb2 Memilih paket python−uang yang sebelumnya t idak d i p i l i h .3 ( Sedang membaca ba s i s data . . . 2 1 3 4 5 8 berkas dan d i r e k t o r i

t e l ah terpasang . )4 Sedang membuka paket python−uang ( da r i python−uang_0 . 1

_al l . deb ) . . .5 Sedang menyetel python−uang ( 0 . 1 ) . . .6 Proce s s ing t r i g g e r s f o r python−c en t r a l . . .

Untuk menghindari kerancuan karena ada dua modul uang yang terpasang,sebaiknya buang yang ada di /usr/local.

1 $ sudo mv /usr / l o c a l / l i b /python2 .6/ d i s t−packages /uang . py/tmp

Lalu ujilah di modus interaktif.

1 $ python2 Python 2 . 6 . 5 ( r265 :79063 , Apr 16 2010 , 1 3 : 0 9 : 5 6 )3 [GCC 4 . 4 . 3 ] on l inux24 Type " help " , " copyr ight " , " c r e d i t s " or " l i c e n s e " f o r more

in fo rmat ion .5 >>> from uang import uang

Page 95: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 10. PENGEMASAN 94

6 >>> uang (10000)7 ' 1 0 . 000 '

Ujian terakhir hapuslah paket ini untuk memastikan script DEBIAN/prermberfungsi dengan baik.

1 $ sudo apt−get remove python−uang2 Sedang membaca da f t a r paket . . . S e l e s a i3 Membangun pohon ketergantungan4 Membaca in f o rmas i yang t e r s e d i a . . . S e l e s a i5 Paket be r ikut akan DIHAPUS:6 python−uang7 0 dimutakhirkan , 0 baru t e r i n s t a l , 1 akan dihapus dan 192

t idak akan dimutakhirkan .8 Sete l ah ope r a s i i n i , 0B ruang kosong harddisk akan

digunakan .9 Anda ing in melanjutkan [Y/ t ] ?

10 ( Sedang membaca ba s i s data . . . 2 1 3 4 6 0 berkas dan d i r e k t o r it e l ah terpasang . )

11 Sedang membuang python−uang . . .

10.2 Debian Repository

Kini saatnya membuat repository agar bisa di-apt-get dari komputer lain. Pa-sanglah paket yang dibutuhkan untuk membaca �le-�le *.deb.

1 $ sudo apt−get i n s t a l l dpkg−dev

Letakkan paketnya di tempat yang sudah ditentukan web server Apache.

1 $ sudo mkdir /var /www/deb2 $ sudo cp / usr / l o c a l / s r c /python−uang_0 . 1 _al l . deb /var /www

/deb

Lalu buatlah /var/www/deb/update-list.sh. File ini digunakan untuk mem-perbaharui daftar paket yang tersedia.

Listing 10.7: updatelist.sh

1 rm −f Packages . gz2 dpkg−scanpackages −−arch a l l . /dev/ nu l l > Packages3 gz ip −−best Packages

Setiap ada paket baru jalankan �le ini.

1 $ cd /var /www/deb2 $ sudo sh update− l i s t . sh

Akan terbentuk �le Packages.gz. File inilah yang akan dibaca saat apt-getupdate.

Selanjutnya kita uji repository ini dengan membuat �le /etc/apt/sources.list.d/custom.list.

Page 96: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 10. PENGEMASAN 95

Listing 10.8: /etc/apt/sources.list.d/custom.list

1 deb http : / / 1 9 2 . 1 6 8 . 0 . 1 / deb . /

Perbaharui daftar paket.

1 $ sudo apt−get update

Pasang paket yang dimaksud.

1 $ sudo apt−get i n s t a l l python−uang

10.3 Remastering Ubuntu

Untuk semakin memudahkan pemasangan, ada baiknya pasang paket-paketyang dimaksud ke dalam sebuah �le ISO. Bukan hanya memasang, bahkan An-da bisa mengkon�gurasi secara manual untuk memastikan pemasangan LinuxUbuntu dan aplikasi yang dimaksud berlangsung lancar dan mudah.

Mulailah pasang paket yang dibutuhkan.

1 $ sudo apt−get i n s t a l l squashfs−t o o l s mkiso f s

Buat �le conf.

Listing 10.9: remaster/conf

1 SOURCE="/home/ sugiana /Unduhan/blankon−6.0− cd l i v e−i 386 . i s o"

2 TARGET="blankon−6.0− cd l i v e−soho−i 386 . i s o "3 LABEL="BlankOn 6 SOHO"

Sesuaikanlah ketiganya. Kemudian buat �le 1-extract.sh:

Listing 10.10: remaster/1-extract.sh

1 . . / conf2 mkdir −p /tmp/cdrom /tmp/ root3 mount −o loop $SOURCE /tmp/cdrom4 rsync −−exc lude ' f i l e s y s t em . squashfs ' −a /tmp/cdrom/

cdrom/5 mount −o loop −t squash f s /tmp/cdrom/ casper / f i l e s y s t em .

squash f s /tmp/ root6 cp −a /tmp/ root .7 umount /tmp/ root8 umount /tmp/cdrom

Lalu buat �le 2-chroot.sh.

Listing 10.11: remaster/2-chroot.sh

1 cp / e tc / r e s o l v . conf root / e t c2 chroot root mount −t proc none /proc3 chroot root mount −t s y s f s none / sys

Page 97: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 10. PENGEMASAN 96

4 chroot root rm −f root / e t c / r e s o l v . conf5 chroot root apt−get c l ean6 chroot root umount sys7 chroot root umount proc8 chroot root rm −r f /tmp/* / root / . bash_history9 rm −r f cdrom/programs

10 chmod +w cdrom/ casper / f i l e s y s t em . mani f e s t11 chroot root dpkg−query −W −−showformat='${Package} ${

Vers ion }\n ' > cdrom/ casper / f i l e s y s t em . mani f e s t12 cp cdrom/ casper / f i l e s y s t em . mani f e s t cdrom/ casper /

f i l e s y s t em . mani fest−desktop13 sed − i e '/ ub iqu i ty /d ' cdrom/ casper / f i l e s y s t em . mani fest−

desktop

Terakhir buat �le 3-pack.sh.

Listing 10.12: remaster/3-pack.sh

1 . . / conf2 rm −f cdrom/ casper / f i l e s y s t em . squash f s3 awal=`date `4 mksquashfs root cdrom/ casper / f i l e s y s t em . squash f s5 cd cdrom6 f i nd . −type f −pr in t0 | xargs −0 md5sum > md5sum . txt7 mkiso f s −r −V "${LABEL}" −cache−i nodes −J − l −b i s o l i n u x /

i s o l i n u x . bin −c i s o l i n u x /boot . cat −no−emul−boot −boot−load−s i z e 4 −boot−i n fo−t ab l e −o . . /$TARGET .

8 echo "Awal $awal"9 echo "Akhir " ` date `

10 echo "Source " ` l s − l $SOURCE | awk '{ p r i n t $5 } ' `11 echo "Target " ` l s − l . . /$TARGET | awk '{ p r i n t $5 } ' `

Jalankan script pertama.

1 $ sudo sh 1−ex t r a c t . sh

Dia akan mengekstrak �le iso menjadi root directory. Kemudian jalankanscript kedua:

1 $ sudo sh 2−chroot . sh

Script ini untuk masuk ke sistem Linux yang lain, yaitu root directory tadi.

1 root@laptop :/#

Di sini Anda bisa melakukan perubahan sebagaimana biasa. Contoh:

1 root@laptop :/# cd / e tc /apt/ sourc e s . l i s t . d2 root@laptop :/# wget http :// debian . rab . co . id / rab . l i s t3 root@laptop :/# apt−get update4 root@laptop :/# apt−get i n s t a l l i n t e rne t−shar ing dhcp3−

s e r v e r squid vim

Page 98: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 10. PENGEMASAN 97

Kalau sudah selesai keluarlah dari chroot dengan menekan Ctrl-D atau ketikexit:

1 root@laptop :/# ex i t2 e x i t3 sugiana@laptop :~ $

Root directory kini telah berisi aplikasi yang dibutuhkan. Saatnya membuatiso dengan menjalankan script ketiga.

1 $ sudo 3−pack . sh

Tunggu sekitar 5 menit.

1 Pa r a l l e l mksquashfs : Using 2 p r o c e s s o r s2 Creat ing 4 .0 f i l e s y s t em on cdrom/ casper / f i l e s y s t em .

squashfs , b lock s i z e 131072.3 [==========================| ] 15063/84258 17%

Terakhir script akan memberikan informasi ukuran iso yang dihasilkan ber-ikut iso aslinya.

1 357433 extent s wr i t t en (698 MB)2 Awal Sen Agu 2 09 : 45 : 39 WIT 20103 Akhir Sen Agu 2 09 : 50 : 52 WIT 20104 Source 7318691845 Target 732022784

Jika media yang Anda tuju nanti adalah CDROM, pastikan ukurannya di-bawah 700MB. Lebih mudahnya bandingkan dengan ukuran ISO aslinya. Padacontoh di atas terlihat ukuran Target masih lebih besar dari Source. Jika masihterlalu besar jalankan lagi script kedua untuk menghapus paket yang tak perlu.

1 $ sudo sh 2−chroot . sh

Setelah selesai jalankan lagi script ketiga:

1 $ sudo sh 3−pack . sh

File ISO yang dihasilkan bisa Anda coba terlebih dahulu di VirtualBox1.Anda juga bisa memasangnya di �ashdisk menggunakan usb-creator-gtk. Jikasudah yakin barulah membakarnya (burn) ke CD-ROM.

1virtualbox.org

Page 99: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

Bab 11

Graphical User Interface

Bab-bab sebelumnya kita mempelajari bagaimana membuat aplikasi dalam ling-kungan teks (text mode), beberapa menyebutnya lingkungan konsole. Contoh-nya fungsi raw_input() yang meminta masukan user dari konsole. Lingkunganyang dimaksud bercirikan tidak membutuhkan mouse, cukup dengan keyboardsaja sebagai alat masukan (input device).

Kali ini kita masuk pemrograman berbasis gra�s dimana mouse bisa digu-nakan sebagai alat masukan untuk klik tombol, copy paste, dsb. Graphical UsetInterface (GUI) tidaklah wajib di Python, ia hanya sebagai modul. Berbeda de-ngan Visual Basic atau Borland Delphi yang mewajibkan GUI.

Modul berbasis GUI tidak hanya satu di Python, ada Qt, Wx, GTk, Tcl, dst.Di sini kita akan membahas Qt sebagai pustaka antarmuka gra�s. Pasanglahpaketnya.

1 $ sudo apt−get i n s t a l l python−qt4

Juga dokumentasinya, meski tidak wajib.

1 $ sudo apt−get i n s t a l l qt4−doc−html

Seperti biasa, mulailah dari yang sederhana, yaitu membuat aplikasi Helloworld dalam �le hello.py.

Listing 11.1: hello.py

1 import sys2 from PyQt4 import Qt3 from PyQt4 . QtGui import *

4

5 class FormUtama(QMainWindow) :6 def __init__( s e l f ) :7 QMainWindow .__init__( s e l f )8 s e l f . setWindowTitle ( ' He l l o world ' )9

10

98

Page 100: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 11. GRAPHICAL USER INTERFACE 99

Gambar 11.1: Hello world

11 app = Qt . QApplication ( sys . argv )12 fm = FormUtama( )13 fm . show ( )14 app . exec_ ( )

Butuh tampilan penuh ? Gantilah

fm.show()

menjadi

fm.showMaximized()

11.1 Orientasi Objek

Di sini teknik pemrograman semakin terstruktur dimana pemrograman bero-rientasi objek (Object Oriented Programming / OOP) diterapkan. Mari kitarinci lagi pembahasan source hello.py tersebut.

Class bisa dianggap sebuah tipe data, disejajarkan dengan tipe string, inte-ger, �oat, list, dictionary, datetime, dst. Dengan demikian FormUtama meru-pakan tipe data. Perhatikan baris 5

class FormUtama(QMainWindow):

itu artinya FormUtama merupakan turunan (inheritance) dari class QMainWin-dow. Itu artinya variabel dan fungsi yang dimiliki class QMainWindow juga di-miliki oleh class FormUtama. Bahasa lainnya FormUtama mewarisi sifat QMa-inWindow.

Selanjutnya ada fungsi __init__(). Fungsi ini merupakan fungsi khususyang dijalankan saat pembentukan sehingga disebut sebagai constructor. Saatpembentukan ? Ya, perhatikan baris 12

fm = FormUtama()

Itu adalah pembentukan variabel fm yang bertipe FormUtama. Disinilah fungsi__init__() dipanggil.

Page 101: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 11. GRAPHICAL USER INTERFACE 100

Dalam istilah OOP, fm disebut sebagai instance atau variabel ber-tipe class. Namun di Python rasanya semua tipe data adalah class.Misalnya tipe string. Ia tidak hanya memuat data seperti 'abcd'saja, melainkan juga memuat fungsi seperti replace(), rjust(), dst.Hal ini bisa dibuktikan dengan print dir('abcd'). Sehingga boleh di-katakan di Python semua variabel adalah objek. Bagi programmerPHP Anda bisa cermati bahwa string 'abcd' hanya sekedar data.

Sekarang perhatikan baris 7

QMainWindow.__init__(self)

Fungsi __init__() yang dimiliki QMainWindow perlu dipanggil lagi. Mengapa? Karena FormUtama mende�nisikan ulang fungsi __init__().

Lalu apa itu self ? self adalah variabel yang mewakili FormUtama itu sendiri.Setiap fungsi yang dimiliki oleh suatu class setidaknya memiliki satu masukan(input parameter) yaitu self.

Selanjutnya lihat baris 13

fm.show()

dimana kita tidak pernah mende�nisikan fungsi show() di dalam class FormU-tama. Kenyataannya variabel fm memiliki fungsi show(). Darimana ia berasal? Seperti dijelaskan tadi, FormUtama mewarisi sifat QMainWindow, jadi fungsishow() itu berasal darinya. Fungsi ini digunakan untuk menampilkan form.

Lalu apa itu form ? Kotak Hello world itulah yang disebut form seperti padagambar 11.1.

Sekarang lihat baris 11

app = Qt.QApplication(sys.argv)

dimana QApplication dibutuhkan untuk loop. Loop yang dimaksud adalah baristerakhir

app.exec_()

tanpa loop, alur langsung berakhir. Form bisa banyak, tapi QApplication cukupsatu saja.

Pahami lagi baik-baik konsep OOP ini agar semakin mudah untuk membuataplikasi yang lebih besar.

11.2 Daftar Pegawai

Mari kita buat form yang lebih lengkap. Form ini untuk memasukkan datapegawai, terinspirasi dari tabel pegawai yang pernah kita buat. Namun disinibelum menggunakan database, semuanya tersimpan sementara saja.

Page 102: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 11. GRAPHICAL USER INTERFACE 101

Listing 11.2: gui/pegawai.py

1 import sys2 from PyQt4 import Qt3 from PyQt4 . QtGui import *

4 from PyQt4 . QtCore import QDate , SIGNAL5

6 class FormUtama(QMainWindow) :7 def __init__( s e l f ) :8 QMainWindow .__init__( s e l f )9 s e l f . setWindowTitle ( ' Pegawai ' )

10 s e l f . r e s i z e (550 ,550)11 s e l f . labelNama = QLabel ( s e l f )12 s e l f . labelAlamat = QLabel ( s e l f )13 s e l f . l abe lTg lLah i r = QLabel ( " t g l l a h i r " , s e l f )14 s e l f . l a b e l J e n i s = QLabel ( s e l f )15 s e l f . editNama = QLineEdit ( s e l f )16 s e l f . editAlamat = QTextEdit ( s e l f )17 s e l f . ed i tTg lLah i r = QDateEdit ( s e l f )18 s e l f . e d i t J e n i s = QComboBox( s e l f )19 s e l f . buttonSimpan = QPushButton ( s e l f )20 s e l f . l i s tPegawa i = QTableWidget ( s e l f )21 s e l f . labelNama . setText ( 'Nama ' )22 s e l f . labelAlamat . setText ( 'Alamat ' )23 #s e l f . l a b e lTg lLah i r . s e tTex t ( ' Tgl Lahir ' )24 s e l f . l a b e l J e n i s . setText ( ' J en i s Kelamin ' )25 s e l f . ed i tTg lLah i r . setDisplayFormat ( 'dd−MM−yyyy ' )26 s e l f . ed i tTg lLah i r . setDate (QDate (2010 ,10 ,23) )27 s e l f . e d i t J e n i s . addItems ( [ ' Pr ia ' , 'Wanita ' ] )28 s e l f . buttonSimpan . setText ( ' Simpan ' )29 s e l f . l i s tPegawa i . setColumnCount (5 )30 s e l f . l i s tPegawa i . s e tHor i zonta lHeaderLabe l s ( [31 ' ID ' , 'Nama ' , 'Alamat ' , ' Tgl Lahir ' , ' Kelamin ' ] )32 s e l f . l i s tPegawa i . setColumnWidth (0 ,20 )33 s e l f . l i s tPegawa i . setColumnWidth (1 ,150)34 #s e l f . editNama . r e s i z e (200 ,30)35 s e l f . editAlamat . r e s i z e (200 ,100)36 s e l f . l i s tPegawa i . r e s i z e (500 ,200)37 s e l f . labelNama .move (10 ,10)38 s e l f . labelAlamat .move (10 ,40)39 s e l f . l abe lTg lLah i r . move (10 ,140)40 s e l f . l a b e l J e n i s . move (10 ,170)41 #s e l f . editNama .move (100 ,10)42 s e l f . editNama . setGeometry (100 ,10 , 200 ,30)43 s e l f . editAlamat .move (100 ,40)44 s e l f . ed i tTg lLah i r . move (100 ,140)

Page 103: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 11. GRAPHICAL USER INTERFACE 102

45 s e l f . e d i t J e n i s . move (100 ,170)46 s e l f . buttonSimpan .move (100 ,200)47 s e l f . l i s tPegawa i . move (10 ,300)48 s e l f . connect ( s e l f . buttonSimpan , SIGNAL( ' c l i c k e d ( )

' ) , s e l f . simpan )49

50 def c loseEvent ( s e l f , event ) :51 s = ' '52 for row in range ( s e l f . l i s tPegawa i . rowCount ( ) ) :53 r = ' '54 for c o l in range ( s e l f . l i s tPegawa i . columnCount

( ) ) :55 v = s t r ( s e l f . l i s tPegawa i . item ( row , c o l ) .

t ex t ( ) )56 r += v + ' , '57 #r = r + v + ' , '58 s += r . s t r i p ( ' , ' ) + ' \n ' # chr (13)59 f = open ( ' pegawai . csv ' , 'w ' )60 f . wr i t e ( s )61 f . c l o s e ( )62 QMainWindow . c loseEvent ( s e l f , event )63

64 def simpan ( s e l f ) :65 row = s e l f . l i s tPegawa i . rowCount ( )66 pid = row+167 s e l f . l i s tPegawa i . setRowCount ( pid )68 s e l f . l i s tPegawa i . set I tem ( row , 0 , QTableWidgetItem (

s t r ( pid ) ) )69 s e l f . l i s tPegawa i . set I tem ( row , 1 , QTableWidgetItem (

s e l f . editNama . t ex t ( ) ) )70 s e l f . l i s tPegawa i . set I tem ( row , 2 , QTableWidgetItem (

s e l f . editAlamat . toPla inText ( ) ) )71 s e l f . l i s tPegawa i . set I tem ( row , 3 , QTableWidgetItem (

s e l f . ed i tTg lLah i r . t ex t ( ) ) )72 s e l f . l i s tPegawa i . set I tem ( row , 4 , QTableWidgetItem (

s e l f . e d i t J e n i s . currentText ( ) ) )73 s e l f . editNama . c l e a r ( )74 s e l f . editAlamat . c l e a r ( )75 s e l f . e d i t J e n i s . setCurrentIndex (0 )76 s e l f . editNama . setFocus ( )77

78

79 app = Qt . QApplication ( sys . argv )80 fm = FormUtama( )81 fm . show ( )82 app . exec_ ( )

Page 104: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 11. GRAPHICAL USER INTERFACE 103

Gambar 11.2: Daftar Pegawai

Bagaimana, panjang bukan ?Ya, contoh kali ini menyertakan class yang kerap digunakan. Berikut ini

ulasan masing-masing class tersebut.

QLabel Menampilkan tulisan saja, tidak bisa diedit user.

QLineEdit Untuk memasukkan tulisan, satu baris saja.

QTextEdit Untuk memasukkan tulisan juga, tapi bisa lebih dari satu baris.

QDateEdit Untuk mengisi tanggal.

QComboBox Untuk menetapkan pilihan.

QPushButton Tombol yang bila di-klik menjalankan suatu fungsi. Dalam halini menyimpan data pegawai ke QTableWidget yang ada di bawahnya.

QTableWidget Menampilkan data berbentuk tabel.

Dari source tersebut dan menganalisa tampilan form, rasanya Anda bisa me-mahami cara penggunaan class di atas.

Page 105: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 11. GRAPHICAL USER INTERFACE 104

Untuk mengetahui class lainnya beserta fungsi yang ada di dalamnyaAnda bisa lihat di /usr/share/qt4/doc/html/classes.html. Gunaka-nlah browser untuk melihatnya.

Page 106: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

Bab 12

Object Oriented

Programming

Kita membuat fungsi dengan tujuan e�siensi source, agar proses-proses yangsama dapat diwakili dengan memanggil fungsi tertentu. Begitu juga pada pem-buatan objek. Mari mulai pada kasus.

Ada sebuah �le teks bernama barang.txt dengan isi seperti berikut ini.

Listing 12.1: barang.txt

1 1Jeruk 34 90002 2Mangga 80003 3Pisang 7 10000

Pembuat �le itu memastikan data barang tersimpan dengan lebar kolomtetap. Kolom kode barang 3 karakter, nama barang 10 karakter, stok 2 ka-rakter, dan harga barang 8 karakter atau sisanya. Anda diminta memindahkandata ini ke sebuah tabel di database. Mari mulai mempertimbangkan langkah-langkah yang bisa ditempuh.

Andai saja kita bisa menggunakan split() yang bisa mengubah string menjadilist, sehingga dengan mudah kolom pertama ada kode barang, kolom keduanama barang, dan seterusnya. Sayang sekali hal ini tidak dapat dilakukan.Mengapa ?

Perhatikan baris Mangga dimana nilai stok kosong. Ini artinya kolom ketigamenjadi harga barang. Tentu saja tidak konsisten dengan baris Jeruk dimanakolom ketiga adalah stok. Idealnya pembuat �le itu mengubah programnyaagar kalau stok kosong diberi angka 0. Namun posisi kita sedang tidak bisamemaksa.

Baik, kita ikuti saja petunjuk pembuatnya dimana lebar kolom menjadiacuan. Sementara ini kita tidak perlu terlalu jauh bagaimana struktur tabelnya.Dari sudut pandang Python saja dulu, tipe data apa yang cocok untuk mewakili�le ini. Untuk sementara anggap saja tipe data list yang sesuai karena inimerupakan bentuk tabel.

105

Page 107: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 12. OBJECT ORIENTED PROGRAMMING 106

Mulailah membuat script barang1.py.

Listing 12.2: barang1.py

1 import sys2

3 f i l ename = sys . argv [ 1 ]4 f = open ( f i l ename )5 for l i n e in f . r e a d l i n e s ( ) :6 kode = l i n e [ : 3 ] . s t r i p ( )7 nama = l i n e [ 3 : 3+10 ] . s t r i p ( )8 s tok = l i n e [3+10:3+10+2]. s t r i p ( )9 harga = l i n e [3+10+2: ] . s t r i p ( )

10 print [ kode , nama , stok , harga ]11 f . c l o s e ( )

Jalankan.

1 $ python barang1 . py barang . txt2 [ ' 1 ' , ' Jeruk ' , ' 34 ' , ' 9 000 ' ]3 [ ' 2 ' , 'Mangga ' , ' ' , ' 8 000 ' ]4 [ ' 3 ' , ' Pisang ' , ' 7 ' , ' 10000 ' ]

Tahap ini sudah baik, dimana setiap nilai sudah dapat diwakili dalam vari-abel kode, nama, stok, dan harga. Namun barang1.py masih kurang modularkarena masukannya berupa nama �le yang diberikan melalui command line.

12.1 Lebih Terstruktur

Kita perlu meningkatkan kadar modularitas dengan membuat fungsi. Buatlahbarang2.py berikut.

Listing 12.3: barang2.py

1 def barang ( f i l ename ) :2 f = open ( f i l ename )3 rows = [ ]4 for l i n e in f . r e a d l i n e s ( ) :5 kode = l i n e [ : 3 ] . s t r i p ( )6 nama = l i n e [ 3 : 3+10 ] . s t r i p ( )7 s tok = l i n e [3+10:3+10+2]. s t r i p ( )8 harga = l i n e [3+10+2: ] . s t r i p ( )9 row = [ kode , nama , stok , harga ]

10 rows . append ( row )11 f . c l o s e ( )12 return rows13

14

15 i f __name__ == '__main__ ' :

Page 108: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 12. OBJECT ORIENTED PROGRAMMING 107

16 import sys17 f i l ename = sys . argv [ 1 ]18 for row in barang ( f i l ename ) :19 print row

Jalankan.

1 $ python barang2 . py barang . txt2 [ ' 1 ' , ' Jeruk ' , ' 34 ' , ' 9 000 ' ]3 [ ' 2 ' , 'Mangga ' , ' ' , ' 8 000 ' ]4 [ ' 3 ' , ' Pisang ' , ' 7 ' , ' 10000 ' ]

Hasil tetap sama, namun kini script tidak hanya mengandung fungsi tetapijuga bisa digunakan sebagai modul.

12.2 Lebih Umum

Sekarang aspek generalitas, atau tingkat ke-umum-an fungsi, dimana lebar se-tiap kolom sudah ditetapkan di dalam fungsi (hardcode). Bisakah ditingkatkangeneralitasnya ?

Kebutuhannya adalah ada �le lain selain barang.txt dengan lebar setiapkolom berbeda dengan barang.txt, namun sifatnya masih sama yaitu setiapkolom memiliki lebar tertentu. Kalau barang.txt menggunakan lebar kolommasing-masing 3, 10, 2, dan 8, mungkin pegawai.txt menggunakan 5, 30, 10,50, dan 20. Jadi bukan hanya lebar kolomnya berbeda, jumlah kolomnya punberbeda.

Karena sudah bersifat umum sebaiknya nama fungsi dan nama �lenya punumum. Buatlah �xtable.py berikut.

Listing 12.4: �xtable.py

1 def f i x t a b l e ( f i l ename , widths ) :2 f = open ( f i l ename )3 rows = [ ]4 for l i n e in f . r e a d l i n e s ( ) :5 awal = 06 row = [ ]7 for width in widths :8 akh i r = awal + width9 f i e l d = l i n e [ awal : akh i r ] . s t r i p ( )

10 row . append ( f i e l d )11 awal = akh i r12 rows . append ( row )13 f . c l o s e ( )14 return rows15

16

17 i f __name__ == '__main__ ' :

Page 109: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 12. OBJECT ORIENTED PROGRAMMING 108

18 import sys19 f i l ename = sys . argv [ 1 ]20 for row in f i x t a b l e ( f i l ename , [ 3 , 1 0 , 2 , 8 ] ) :21 print row

Jalankan.

1 $ python f i x t a b l e . py barang . txt2 [ ' 1 ' , ' Jeruk ' , ' 34 ' , ' 9 000 ' ]3 [ ' 2 ' , 'Mangga ' , ' ' , ' 8 000 ' ]4 [ ' 3 ' , ' Pisang ' , ' 7 ' , ' 10000 ' ]

Perhatikan lagi, hasil masih sama. Anda bisa uji dengan membuat pega-wai.txt.

Listing 12.5: pegawai.txt

1 1BUMMI DWI PUTERA, ST 1985−08−17L2 2ARIEF SETIADI 1972−05−02L3 3CECEP ZAHRUDIN, ST 1972−06−01L4 4NITA PANDRIA 1976−09−19P5 5ILHAM 1984−11−05L6 6MIRANDA 1978−10−01P

Lalu �xpegawai.py.

Listing 12.6: �xpegawai.py

1 from f i x t a b l e import f i x t a b l e2 import sys3

4 f i l ename = sys . argv [ 1 ]5

6 for row in f i x t a b l e ( f i l ename , [ 2 , 2 2 , 1 0 , 1 ] ) :7 print row

Jalankan.

1 $ python f ixpegawa i . py pegawai . txt2 [ ' 1 ' , 'BUMMI DWI PUTERA, ST' , '1985−08−17 ' , 'L ' ]3 [ ' 2 ' , 'ARIEF SETIADI ' , '1972−05−02 ' , 'L ' ]4 [ ' 3 ' , 'CECEP ZAHRUDIN, ST' , '1972−06−01 ' , 'L ' ]5 [ ' 4 ' , 'NITA PANDRIA' , '1976−09−19 ' , 'P ' ]6 [ ' 5 ' , 'ILHAM' , '1984−11−05 ' , 'L ' ]7 [ ' 6 ' , 'MIRANDA' , '1978−10−01 ' , 'P ' ]

Fungsi �xtable teruji.

12.3 Tingkat Kerumitan

Kompleksitas masalah kian bertambah. Kini Anda membutuhkan hasil yangmemperhatikan tipe data. Perhatikan lagi barang.txt dimana:

Page 110: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 12. OBJECT ORIENTED PROGRAMMING 109

� kolom pertama, kode barang, bertipe integer

� kolom kedua, nama barang, bertipe string

� kolom ketiga, stok, bertipe integer

� kolom keempat, harga, bertipe integer

Lalu apa nilai yang cocok untuk stok Mangga yang tidak tertulis apapun aliasstring hampa ? Apa tetap diisi sebagai string hampa ? Sebaiknya tidak, karenakita akan menetapkan �eld stok bertipe integer. Maka nilai yang cocok untukstring hampa adalah None, alias objek hampa. Buatlah �le FixTableType.pyberikut ini.

Listing 12.7: FixTableType.py

1 from types import IntType , StringType2

3

4 def f i x t a b l e ( f i l ename , f t ype s ) :5 f = open ( f i l ename )6 rows = [ ]7 for l i n e in f . r e a d l i n e s ( ) :8 awal = 09 row = [ ]

10 for width , f type in f t ype s :11 akh i r = awal + width12 f i e l d = l i n e [ awal : akh i r ] . s t r i p ( )13 i f not f i e l d :14 f i e l d = None15 e l i f f type == IntType :16 f i e l d = in t ( f i e l d )17 row . append ( f i e l d )18 awal = akh i r19 rows . append ( row )20 f . c l o s e ( )21 return rows22

23

24 i f __name__ == '__main__ ' :25 import sys26 f i l ename = sys . argv [ 1 ]27 f i e l d s = [28 [ 3 , IntType ] ,29 [ 1 0 , StringType ] ,30 [ 2 , IntType ] ,31 [ 8 , IntType ]32 ]

Page 111: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 12. OBJECT ORIENTED PROGRAMMING 110

33 for row in f i x t a b l e ( f i l ename , f i e l d s ) :34 print row

Jalankan.

1 $ python FixTableType . py barang . txt2 [ 1 , ' Jeruk ' , 34 , 9000 ]3 [ 2 , 'Mangga ' , None , 8000 ]4 [ 3 , ' Pisang ' , 7 , 10000 ]

Perhatikan, tidak ada lagi kutip di kolom pertama, ketiga, dan keempat.Selanjutnya ada kebutuhan untuk menyimpan kembali data tersebut ke se-

buah �le sejenis, meski tidak harus ke barang.txt lagi. Fitur semakin bertambahdimana:

� Tipe integer

Page 112: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

Bab 13

Kerja Sampingan

Anda diminta membuat sebuah program yang bertugas mengendalikan sebuahGSM modem. Program ini bersifat daemon yang artinya selalu berjalan seolahtanpa akhir. Tugas utamanya adalah mengirim SMS yang berasal dari seluruh�le yang ada di direktori /tmp/job. Hasil pengiriman SMS (berhasil / tidak)dikirim ke SMS gateway induk melalui XMLRPC, inilah kerja sampingannyaatau sering disebut sebagai multi-thread.

Mengapa kita perlu multi-thread ?Modem tersebut hanya bisa mengirim sebuah SMS pada satu saat yang

membutuhkan waktu 10 detik. Di sisi lain daemon ini harus mengabari statuspengiriman ke SMS gateway induk melalui XMLRPC yang membutuhkan waktu5 detik. Bahkan kalau terkena masalah bandwidth XMLRPC client ini bisamembutuhkan waktu 60 detik. Bayangkan kalau hanya single-thread.

Saat Thread 1

1 Mengirim SMS 1 selama 10 detik2 Mengabari status SMS 1 selama 5 detik3 Mengirim SMS 2 selama 10 detik4 Mengirim status SMS 2 selama 5 detik

Total waktu yang dibutuhkan untuk mengirim dua SMS adalah 30 detik.Sekarang bandingkan bila menggunakan multi-thread.

Saat Thread 1 Thread 2

1 Mengirim SMS 1 10 detik2 Mengirim SMS 2 10 detik Mengabari status SMS 1 5 detik3 Mengabari status SMS 2 5 detik

Total waktu yang dibutuhkan adalah 10+10+5 = 25 detik, selisih 5 detikdari single-thread. Bagi SMS gateway itu merupakan jeda yang cukup berartimengingat banyaknya SMS yang dikirim.

Mari kita mulai simulasinya dengan membuat test_thread.py.

Listing 13.1: testthread.py

1 from thread ing import Thread

111

Page 113: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 13. KERJA SAMPINGAN 112

2 import time3 import os4 from glob import glob5

6

7 class Kirim (Thread ) :8 def __init__( s e l f , k ) :9 s e l f . k e r j a = True

10 s e l f . kabar = k11 Thread . __init__( s e l f )12

13 def run ( s e l f ) :14 print time . s t r f t ime ( '%H:%M:%S ' ) , ' Kerja sampingan

dimula i '15 while s e l f . k e r j a :16 time . s l e e p (1 )17 i f not s e l f . kabar :18 continue19 h a s i l = s e l f . kabar [ 0 ]20 del s e l f . kabar [ 0 ]21 #s e l f . kabar = s e l f . kabar [ 1 : ]22 print '%s KABARI %s ' % ( time . s t r f t ime ( '%H:%M

:%S ' ) , h a s i l )23

24 def j o i n ( s e l f ) :25 print ' Kerja sampingan berakh i r '26 s e l f . k e r j a = False27 Thread . j o i n ( s e l f )28

29

30 job_dir = ' /tmp/ job '31 kabar = [ ]32

33 sampingan = Kirim ( kabar )34 sampingan . s t a r t ( )35

36 print time . s t r f t ime ( '%H:%M:%S ' ) , ' Pekerjaan utama dimula i '

37 while True :38 time . s l e e p (1 )39 i f not os . path . e x i s t s ( job_dir ) :40 continue41 f i l enames = glob ( '%s /* ' % job_dir )42 i f not f i l enames :43 continue44 f i l ename = f i l enames [ 0 ]

Page 114: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 13. KERJA SAMPINGAN 113

45 f = open ( f i l ename )46 job = f . read ( )47 f . c l o s e ( )48 os . remove ( f i l ename )49 print '%s KERJAKAN %s ' % ( time . s t r f t ime ( '%H:%M:%S ' ) ,

job )50 kabar . append ( job )51

52 print ' Pekerjaan utama berakh i r '53 sampingan . j o i n ( )

Jalankan.

1 $ python t e s t th r ead . py2 04 : 56 : 54 Pekerjaan utama dimula i3 04 : 56 : 54 Kerja sampingan dimula i

Sampai di sini ia menunggu keberadaan �le di direktori /tmp/job. Bukakonsole lain dan buatlah direktori /tmp/job.

1 $ mkdir /tmp/ job

Lalu buatlah �le apa saja.

1 $ echo h e l l o > /tmp/ job / h e l l o . txt

Kemudian lihat konsole testthread.py tadi.

1 04 : 56 : 56 KERJAKAN he l l o2 04 : 56 : 57 KABARI h e l l o

Pointer

Perlu diperhatikan variabel kabar yang bertipe list (baris 30). Ini adalah vari-abel bersama, artinya dapat diolah baik oleh thread 1 maupun thread 2. Disini berlaku apa yang disebut pointer yang artinya alokasi memori pada baris30 dengan baris 10

1 s e l f . kabar = k

adalah sama. Perhatikan juga penghapusan antrian pertama di baris 20

1 de l s e l f . kabar [ 0 ]

dimana pada program biasa bisa saja Anda membuatnya menjadi

1 s e l f . kabar = s e l f . kabar [ 1 : ]

Namun teknik ini akan membuat alokasi memori yang baru dimana thread 2tidak lagi menggunakan variabel kabar sebagaimana yang digunakan oleh thread1.

Mudah-mudahan Anda paham apa yang dimaksud dengan multi-thread ini.

Page 115: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

Bab 14

SMS Gateway

SMS Gateway adalah salah satu produk RAB yang memanfaatkan Python danPostgreSQL. Akses ke database menggunakan SQLAlchemy dan Elixir. Diran-cang semodular mungkin agar mudah dipakai oleh sistem lainnya yang bukanPython, bukan PostgreSQL, bahkan bukan Linux.

Produk ini juga menerapkan teknik event driven dan plug-in.

14.1 Pemasangan

1 $ sudo apt−get i n s t a l l im−gw

Proses instalasi akan meminta Anda menyesuaikan �le /etc/im/gw/con-�g.py. File ini perlu diisi dengan otenti�kasi ke database yang sudah dibuattadi.

1 db_url = ' po s tg r e s : // ilham :1234 @loca lhos t :5432/ to ta l i ndo '

Kemudian jalankan:

1 $ sudo dpkg−r e c on f i g u r e im−gw

Proses ini akan membuat tabel yang dibutuhkan ke database totalindo.Paket im-gw digunakan untuk hal yang berkaitan dengan database seperti

menyimpan dan mengirim pesan. Daemonnya bisa Anda stop dan start dengancara:

1 $ sudo / e tc / i n i t . d/im−gw r e s t a r t

im-gw juga otomatis hidup saat komputer dihidupkan. Anda bisa memantaulog-nya dengan cara:

1 $ sudo t a i l −f / var / l og /im/gw . l og2 2011−01−18 05 :12 : 20 , 883 INFO Star t r e s u l t d i r /var / spoo l /

im/ r e s u l t /3 2011−01−18 05 :12 : 20 , 886 INFO Star t job at pid 1202

114

Page 116: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 14. SMS GATEWAY 115

4 2011−01−18 05 :12 : 20 , 928 INFO Star t r e s u l t xmlrpc s e r v e ron port 9317

Tekan Ctrl-C untuk mengakhiri. Tapi sebaiknya tetap terpantau, dan Andabisa gunakan konsole lain untuk aktivitas berikutnya.

Untuk mengirim dan menerima SMS yang sebenarnya dibutuhkan pengen-dali modem:

1 $ sudo apt−get i n s t a l l im−modem

Paket ini juga akan membuat tabel, menggunakan kon�gurasi yang samadengan im-gw.

Pasanglah modem GSM atau CDMA. Merk yang sudah teruji adalah Wave-com, iTegno, dan Multitech. USB device lebih disarankan karena mendukunghotplug, dimana saat modem ditancapkan pengendalinya otomatis aktif. Andabisa periksa dengan perintah:

1 $ ps ax | grep modem2 5627 ? SN 0:06 / usr / bin /python / usr /bin /modem−hotplug3 28464 ? S l 0 :01 python / usr / bin /modem /dev/ttyUSB0

Perhatikan /usr/bin/modem-hotplug, dialah yang memantau aktivitas pe-masangan perangkat USB. Lalu ada juga /usr/bin/modem, daemon inilah yangdipanggil oleh modem-hotplug saat USB modem ditancapkan. Lalu bagaimanajika perangkatnya ditancapkan di serial port ?

Anda pastikan dulu modem itu terpasang di serial port berapa. Keberadaanserial port bisa dilihat dengan perintah berikut:

1 $ dmesg | grep ttyS2 [ 25 . 972197 ] s e r i a l 8 2 5 0 : ttyS0 at I /O 0 x3f8 ( i r q = 4) i s

a 16550A3 [ 25 . 973141 ] 0 0 : 0 7 : ttyS0 at I /O 0 x3f8 ( i r q = 4) i s a

16550A4 [ 42 . 442528 ] 0 0 0 0 : 0 5 : 0 1 . 0 : ttyS4 at I /O 0xd100 ( i r q = 17)

i s a 16550A5 [ 42 . 442750 ] 0 0 0 0 : 0 5 : 0 1 . 0 : ttyS5 at I /O 0xd200 ( i r q = 17)

i s a 16550A6 [ 42 . 538359 ] 0 0 0 0 : 0 5 : 0 2 . 0 : ttyS6 at I /O 0xd700 ( i r q = 19)

i s a 16550A7 [ 42 . 538574 ] 0 0 0 0 : 0 5 : 0 2 . 0 : ttyS7 at I /O 0xd800 ( i r q = 19)

i s a 16550A

Anda bisa menyebutkan semua serial port yang ada pada �le /etc/im/mo-dem/modem.conf:

1 [ d ev i c e ]2 ; d ev i c e d i /dev/ tty3 port = USB0 USB1 USB2 USB3 USB4 USB5 USB6 USB7 S0 S4 S5

S6 S7

Lalu restart semua modem:

Page 117: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 14. SMS GATEWAY 116

1 $ sudo / e tc / i n i t . d/modem r e s t a r t

Tunggu sekitar 30 detik, lalu jalankan

1 $ ps ax | grep modem2 11211 ? Rl 10 :29 python / usr / bin /modem /dev/

ttyS0

untuk mengetahui serial port mana yg digunakan. Anda bisa menge�sienkanmodem.conf diatas dengan hanya mencantumkan S0 saja, namun tidak diubahpun tidak menjadi masalah.

Sedangkan untuk melihat log-nya, terlebih dahulu Anda periksa direktori/var/log/modem, ada �le apa di sana:

1 $ sudo l s /var / log /modem2 510012541218911. l og

Selanjutnya mulailah memantau:

1 $ sudo t a i l −f / var / l og /modem/510012541218911. l og −n 302 2011−01−18 01 :45 : 22 , 304 INFO −> AT+CSQ3 2011−01−18 01 :45 : 24 , 307 INFO <− AT+CSQ4 2011−01−18 01 :45 : 24 , 308 INFO <− +CSQ: 20 ,05 2011−01−18 01 :45 : 24 , 308 INFO <− OK6 2011−01−18 01 :45 : 24 , 309 INFO −> AT+CLIP=17 2011−01−18 01 :45 : 26 , 312 INFO <− AT+CLIP=18 2011−01−18 01 :45 : 26 , 312 INFO <− OK9 2011−01−18 01 :45 : 26 , 312 INFO −> AT+CGMM

10 2011−01−18 01 :45 : 27 , 326 INFO <− AT+CGMM11 2011−01−18 01 :45 : 27 , 326 INFO <− MULTIBAND 900E 180012 2011−01−18 01 :45 : 27 , 327 INFO <− OK13 2011−01−18 01 :45 : 27 , 327 INFO −> AT+CNMI=0 ,1 ,1 ,1 ,014 2011−01−18 01 :45 : 29 , 330 INFO <− AT+CNMI=0 ,1 ,1 ,1 ,015 2011−01−18 01 :45 : 29 , 330 INFO <− OK16 2011−01−18 01 :45 : 29 , 330 INFO −> AT+CMGF=117 2011−01−18 01 :45 : 31 , 332 INFO <− AT+CMGF=118 2011−01−18 01 :45 : 31 , 333 INFO <− OK19 2011−01−18 01 :45 : 31 , 333 INFO −> AT+CMGL="ALL"20 2011−01−18 01 :45 : 32 , 346 INFO <− AT+CMGL="ALL"21 2011−01−18 01 :45 : 32 , 346 INFO <− OK22 2011−01−18 01 :45 : 32 , 352 INFO Serv ing /dev/ttyUSB1 and /

var / spoo l /im/ job /modem/510012541218911/ at pid 28464

Bila Anda sudah berjumpa kalimat yang berawalan Serving seperti di atas,maka modem sudah siap.

14.1.1 IMEI Chip

Lalu apa yang dimaksud dengan angka 510012541218911 pada nama �le log ?Mengapa tidak USB0.log atau S0.log saja ?

Page 118: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 14. SMS GATEWAY 117

Angka itu disebut dengan IMEI alias identitas chip / SIM card. Jika kom-puter membutuhkan informasi device port untuk mengendalikan modem, makamanusia / user membutuhkan IMEI sebagai identitas chip yang ada di dalammodem. Aktivitas menerima dan mengirim SMS tentu melekat pada chip, buk-an pada modem. Karena itu penggunaan IMEI pada nama log adalah yangpaling tepat untuk menjaga konsistensi history.

Lagi pula device port yang digunakan modem USB kadang berubah. Saatini mungkin modem dikenali di USB0. Coba Anda lepas dan pasang lagi ditempat yang sama, bisa jadi kini USB1 yang digunakannya.

14.1.2 Database

Saat /usr/bin/modem mulai mengendalikan sebuah modem, ia melaporkan ke/usr/bin/im-gw bahwa IMEI 510012541218911 baru saja hidup. Kejadian inidisebut sebagai startup. Saat itulah im-gw memeriksa keberadaan IMEI terse-but di tabel im.agent. Kalau belum ada ia tambahkan, dan kalau sudah ada iaperbaharui statusnya.

1 $ psq l −U ilham −h l o c a l h o s t t o t a l i ndo2 Password f o r user ilham :3 psq l ( 8 . 4 . 4 )4 SSL connect ion ( c iphe r : DHE−RSA−AES256−SHA, b i t s : 256)5 Type " help " f o r he lp .6 t o t a l i ndo=> SELECT id , s t a tu s FROM im . agent ;7 id | s t a tu s8 −−−−−−−−−−−−−−−−−+−−−−−−−−9 510012541218911 | 0

10 (1 row )

Status 0 berarti modem siap, status negatif berarti sebaliknya. Alasan untukstatus negatif bisa Anda lihat di tabel im.status.

14.2 Hello world!

Mari mulai mengirim SMS ke handphone Anda, masih di psql.

1 t o t a l i ndo=> INSERT INTO im . ant r i an ( penerima , pesan )2 to ta l i ndo−> SELECT '+628179140068 ' , ' He l l o world ! ' ;3 INSERT 0 1

Untuk penerima sesuaikanlah dengan nomor handphone Anda.Status pengiriman bisa Anda lihat di tabel im.selesai.

1 t o t a l i ndo=> SELECT id , s tatus , pengirim , penerima , pesan2 to ta l i ndo−> FROM im . s e l e s a i ORDER BY 1 DESC LIMIT 1 ;3 id | s t a tu s | pengir im | penerima |

pesan

Page 119: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 14. SMS GATEWAY 118

4 −−−−−−+−−−−−−−−+−−−−−−−−−−−−−−−−−+−−−−−−−−−−−−−−−+−−−−−−−−−−−−−−

5 1065 | 0 | 510012541218911 | +628179140068 | He l loworld !

6 (1 row )

Status 0 berarti telah terkirim, negatif sebaliknya, sedangkan positif berartisedang diproses. Penjelasannya bisa dilihat di tabel im.status.

Setelah Anda menerima SMS di handphone, balaslah SMS itu dengan:

Diterima

Tunggu sekitar 30 detik, dan lihat tabel im.antrian.

1 t o t a l i ndo=> SELECT id , kir im , pengirim , penerima , pesan2 to ta l i ndo−> FROM im . ant r i an ;3 id | k i r im | pengir im | penerima | pesan4 −−−−−−+−−−−−−−+−−−−−−−−−−−−−−−+−−−−−−−−−−−−−−−−−+−−−−−−−−−−

5 1071 | f | +628179140068 | 510012541218911 |Diterima

6 (1 row

Mungkin Anda bertanya-tanya, saat mengirim pesan tabel im.antrian yangdigunakan, begitu juga saat menerima pesan. Lalu apa pembedanya ?

Perhatikan �eld kirim di atas. Jika �eld kirim = f (False), itu berarti recordpesan masuk. Jika bernilai t (True) berarti pengiriman pesan. Defaultnyaadalah True (pengiriman pesan).

14.3 Instant Messenger Gateway

Ada dua paket utama di sini, yaitu im-gw dan im-modem. Keduanya terhubungsebagaimana pada gambar 14.1. Lalu mengapa harus ada dua paket ?

Meski judul tulisan ini adalah SMS Gateway, namun pada konsepnya sistemini dapat disanding dengan paket instant messenger seperti Yahoo! Messengerdan XMPP (Jabber, GTalk). Keduanya ada di paket im-ym dan im-xmpp.Jadi im-modem, im-ym, dan im-xmpp sejajar kedudukannya. Kalau im-modemmemerlukan �sik modem, maka im-ym dan im-xmpp membutuhkan koneksiInternet.

Jadi bila Anda ingin mencoba sistem ini namun belum memiliki modem,maka bisa gunakan im-ym dan im-xmpp.

14.3.1 Yahoo! Messenger

Sebelum pemasangan, sebaiknya Anda siapkan Yahoo! account yang baru yangakan digunakan oleh /usr/bin/ym (daemon dari paket im-ym). Selanjutnyapasang paketnya.

Page 120: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 14. SMS GATEWAY 119

Gambar 14.1: Alur IM gateway

Page 121: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 14. SMS GATEWAY 120

1 $ sudo apt−get i n s t a l l im−ym

Kemudian sesuaikan /etc/im/ym/con�g.py, seperti contoh berikut:

1 use r s = { ' i n f o r ab ' : ' 1234 ' }

dimana inforab adalah Yahoo! account dan 1234 adalah passwordnya.Setelah disimpan tunggu satu menit dan periksa keberadaannya.

1 $ ps ax | grep ym2 2339 ? S l 24 :44 python / usr / bin /ym in f o r ab

Log-nya juga tersedia.

1 $ sudo t a i l −f / var / l og /ym/ in f o r ab . l og2 2011−02−25 14 :24 : 46 , 729 INFO Startup { ' s tatus ' : 0}

Sekarang coba add buddy dari Yahoo! Messenger client seperti Pidgin. Ten-tu saja gunakan Yahoo! account yang lain. Daemon ym secara otomatis akanmenambahkannya ke dalam daftar.

Selanjutnya kirim pesan seperti biasa, lalu lihat log-nya:

1 2011−02−25 15 :10 : 43 , 885 INFO Inbox { ' tg l_operator ' :'2011−02−25 15 :10 :43+7 ' , ' pesan ' : ' h e l l o world ' , 'pengirim ' : ' info_rab ' }

dan lihat juga tabel im.antrian.

1 t o t a l i ndo=> SELECT id , kir im , j a l u r , pengirim , penerima ,pesan

2 to ta l i ndo−> FROM im . ant r i an ;3 id | k i r im | j a l u r | pengir im | penerima | pesan4 −−−−−−+−−−−−−−+−−−−−−−+−−−−−−−−−−+−−−−−−−−−−+−−−−−−−−−−−−−

5 2074 | f | 5 | info_rab | i n f o r ab | h e l l o world6 (1 row )

Sekarang perhatikan kolom jalur yang berisi 5. Itu artinya jalur ym. Se-dangkan jalur modem berisi 1 (default). Daftar jalur ini ada di tabel jalur.

14.3.2 XMPP

Jika Anda punya account di Gmail maka Anda dapat chatting dengan user Gma-il lainnya. Namun sebenarnya Anda dapat chatting dengan user dari server lainyang menggunakan protokol XMPP seperti jabber.org atau jabber.rab.co.id.Ya, seperti email, protokol XMPP memungkinkan user dari server berbeda da-pat saling mengirim pesan.

Jika Anda berminat menggunakan XMPP untuk chatting dengan server,pasang paket im-xmpp.

1 $ sudo apt−get i n s t a l l im−xmpp

Lalu sesuaikan /etc/im/xmpp/con�g.py.

Page 122: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 14. SMS GATEWAY 121

1 use r s = { ' inforab@gmai l . com ' :2 { ' password ' : ' 1234 ' , ' s a s l ' : True ,3 ' port ' : 5223 , ' s e r v e r ' : ' t a l k . goog l e . com ' }4 }

Sesuaikan inforab dan 1234. Setelah disimpan tunggu satu menit hinggadaemon-nya up. Setelah hidup, Anda bisa lakukan pengujian yang serupa se-perti ym.

Jika Anda ingin menggunakan server lokal, bisa coba daftar ke jabber.rab.co.idmenggunakan Pidgin. Lalu sesuaikan /etc/im/xmpp/con�g.py seperti contohberikut.

1 use r s = { ' inforab@gmai l . com ' :2 { ' password ' : ' 1234 ' , ' s a s l ' : True ,3 ' port ' : 5223 , ' s e r v e r ' : ' t a l k . goog l e . com ' } ,4 ' in fo@jabber . rab . co . id ' : ' 1234 '5 }

Ya, im-xmpp juga dapat menghidupkan lebih dari satu account. Kebetulanjabber.rab.co.id menggunakan kon�gurasi yang lebih sederhana sebagaimanacontoh di atas.

14.4 Broadcast

Anda telah memiliki banyak pelanggan dan ingin mengirim pesan yang samake mereka. Dengan mudah lakukan query berikut.

1 INSERT INTO im . ant r i an ( penerima , pesan )2 SELECT no_hp , ' Selamat t ransaks i ' FROM pelanggan ;

Sayangnya untuk jumlah penerima yang sangat banyak tidak bisa semudahitu, karena /usr/bin/modem memiliki nilai job timeout yang default-nya 420detik alias 7 menit. Jika setiap pesan membutuhkan waktu 10 detik untuk diki-rim, maka hanya 42 pesan saja yang akan dikirim. Selebihnya akan dilaporkanoleh /usr/bin/modem sebagai status -9 alias Timeout.

Menaikkan nilai timeout di /etc/im/modem/modem.conf bisa juga jadi solu-si, namun tidak disarankan. Teknik yang paling pas adalah menyiapkan daemonbaru yang memantau nilai �eld job. Jika job lebih besar dari 5 maka tidak di-lakukan INSERT ke im.antrian.

Untuk kebutuhan ini sudah disiapkan paket im-broadcast.

1 $ sudo apt−get i n s t a l l im−broadcast

Untuk mengirim pesan kita perlu melakukan INSERT ke dua tabel, yai-tu im.broadcast dan im.broadcast_penerima. Tabel pertama berisi pesan, se-dangkan tabel kedua berisi penerimanya. Kedua tabel ini akan diproses olehdaemon /usr/bin/im-broadcast untuk disalin ke tabel im.antrian.

Pertama kita memerlukan nilai ID untuk broadcast yang baru.

Page 123: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

BAB 14. SMS GATEWAY 122

1 t o t a l i ndo=> SELECT nextva l ( ' im . broadcast_id_seq ' ) ;2 nextva l3 −−−−−−−−−4 85 (1 row )

Kemudian tambahkan pesannya.

1 t o t a l i ndo=> INSERT INTO im . broadcast ( id , judul , pesan )2 to ta l i ndo−> SELECT 8 , ' Uj i broadcast ' , ' Selamat t ransaks i

' ;3 INSERT 0 1

Field judul hanya untuk keterangan saja. Field pesan-lah yang nanti akandikirim. Berikutnya tambahkan penerima pesan.

1 t o t a l i ndo=> INSERT INTO im . broadcast_penerima ( id ,penerima )

2 to ta l i ndo−> SELECT 8 , '+628179140068 ' ;3 INSERT 0 1

Jalur default yang digunakan adalah 1 (modem). Untuk jalur lainnya ser-takan �eld jalur.

1 t o t a l i ndo=> INSERT INTO im . broadcast_penerima ( id , penerima, j a l u r )

2 to ta l i ndo−> SELECT 8 , ' info_rab ' , 5 ;3 INSERT 0 1

Dimana jalur 5 adalah ym.

Page 124: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

Indeks

__name__, 34

ALTER TABLE, 49, 50Android, 4apt-get install, 5apt-get update, 5autoincrement �eld, 45

BlankOn, 5break, 13

continue, 14CREATE TABLE, 43CREATE VIEW, 51createdb, 42createuser, 41

Data De�nition Language, 50Data Manipulation Language, 50date(), 29datestyle, 47datetime(), 29DEFAULT, 43DELETE FROM, 49DROP TABLE, 50dropdb, 42dropuser, 41

epoch, 28eval(), 19

�oat, 10for, 15formatting, 16, 18fullpath, 53

Gnome, 6

int(), 18, 26

integer, 10

KDE, 5, 6konsole, 5

length(), 55Linux, 4locale-gen, 37localtime(), 27lower(), 8lpad(), 55

Mac, 4mktime(), 28modul datetime, 29modul locale, 36modul time, 27

nextval(), 46None, 38NOT NULL, 43

objek hampa, 38ORDER BY, 47ORDER BY, DESC, 48

pg_dump, 53pg_restore, 53plpgsql, 5plpython, 5postgresql.conf, 47PRIMARY KEY, 43print, 8, 19psql, 5, 42

rata kanan, 54raw_input(), 9, 26

sequence, 45

123

Page 125: Database PostgreSQL, Pemrograman Python, dan SMS …customer.rab.co.id/py-pg-2.pdf · Database PostgreSQL, Pemrograman Python, ... 7 Database 41 7.1 abT el ... Shell, dan Jaav adalah

INDEKS 124

serial, 45sisa pembagian, 17SQLAlchemy, 5string, 8, 10sudo, 41Symbian, 4

text editor, 6time(), 28tipe data dictionary, 25tipe data �oat, 17tipe data integer, 17tipe data list, 19transaction, 71transaction, auto commit, 71type(), 16

Ubuntu, 5Unix, 4Unix time, 28UPDATE, 49upper(), 8

variabel, 10vi, 6

while, 14