Вы находитесь на странице: 1из 178

Database PostgreSQL, Pemrograman Python,

dan SMS Gateway

RAB Linux Indonesia

© 2012

Daftar Isi

1 Alasan 5

2 Pemasangan 6

3 Hello World! 9

3.1 Variab el dan Tip e Datanya . . . . . . . . . . . . . . . . . . . . . 10

3.2 Kondisi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

3.3 Perulangan . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

4 Tip e Data 17

4.1 String . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

4.2 Bilangan . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

4.2.1 Konversi Tip e Data . . . . . . . . . . . . . . . . . . . . . 19

4.2.2 Formatting . . . . . . . . . . . . . . . . . . . . . . . . . . 19

4.2.3 Kalkulator . . . . . . . . . . . . . . . . . . . . . . . . . . 20

4.3 List . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

4.3.1 Pemenggalan . . . . . . . . . . . . . . . . . . . . . . . . . 21

4.3.2 Keb eradaan Elemen . . . . . . . . . . . . . . . . . . . . . 22

4.3.3 Mengubah Elemen . . . . . . . . . . . . . . . . . . . . . . 25

4.4 Ditionary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26

4.5 Waktu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28

5 Mo dularitas 31

5.1 Membuat Fungsi . . . . . . . . . . . . . . . . . . . . . . . . . . . 32

5.2 Membuat Mo dul . . . . . . . . . . . . . . . . . . . . . . . . . . . 33

5.3 Searh Path . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

6 Fungsi 37

6.1 Memanggil Dirinya Sendiri . . . . . . . . . . . . . . . . . . . . . 37


6.2 Format Uang . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37

7 Database 42

7.1 Tab el . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44

7.1.1 Sequene . . . . . . . . . . . . . . . . . . . . . . . . . . . 46

7.1.2 Mengubah Struktur . . . . . . . . . . . . . . . . . . . . . 49

DAFTAR ISI 2

7.2 View . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51

7.3 Bakup dan Restore . . . . . . . . . . . . . . . . . . . . . . . . . 53

7.3.1 Eno ding . . . . . . . . . . . . . . . . . . . . . . . . . . . 54

7.4 Fungsi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55

7.4.1 PL/pgSQL . . . . . . . . . . . . . . . . . . . . . . . . . . 56

7.4.2 PL/Python . . . . . . . . . . . . . . . . . . . . . . . . . . 61

8 Python Akses Database 63

8.1 Ative Reord . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64

8.2 Auto Commit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71

8.3 Synhronizer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73

8.3.1 Asp ek Keamanan . . . . . . . . . . . . . . . . . . . . . . . 74

8.3.2 Tambah, Perbaharui, Hapus . . . . . . . . . . . . . . . . . 76

8.4 Migrasi dari Database Lain . . . . . . . . . . . . . . . . . . . . . 78

9 Lintas Sistem 80

9.1 Command Line . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80

9.2 File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82

9.3 Database . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83

9.4 XMLRPC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84

9.4.1 PHP sebagai XMLRPC Client . . . . . . . . . . . . . . . 87

9.4.2 Drupal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88

10 Pengemasan 90

10.1 Paket Debian . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90


10.2 Debian Rep ository . . . . . . . . . . . . . . . . . . . . . . . . . . 95

10.3 Remastering Ubuntu . . . . . . . . . . . . . . . . . . . . . . . . . 96

11 Graphial User Interfae 99

11.1 Orientasi Ob jek . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100

11.2 Daftar Pegawai . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101

12 Ob jet Oriented Programming 106

12.1 Lebih Terstruktur . . . . . . . . . . . . . . . . . . . . . . . . . . . 107

12.2 Lebih Umum . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108

12.3 Tingkat Kerumitan . . . . . . . . . . . . . . . . . . . . . . . . . . 109

13 Kerja Sampingan 112

14 SMS Gateway 115

14.1 Pemasangan . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115

14.1.1 IMEI Chip . . . . . . . . . . . . . . . . . . . . . . . . . . 117

14.1.2 Database . . . . . . . . . . . . . . . . . . . . . . . . . . . 118

14.2 Hello world! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118

14.3 Instant Messenger Gateway . . . . . . . . . . . . . . . . . . . . . 119

14.3.1 Yaho o! Messenger . . . . . . . . . . . . . . . . . . . . . . 119

14.3.2 XMPP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121

DAFTAR ISI 3

14.4 Broadast . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122

15 Web 124

15.1 Django . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124

15.2 Webpy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124

16 Hosting 125

16.1 Virtualmin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125

16.1.1 Pemasangan Ubuntu . . . . . . . . . . . . . . . . . . . . . 125

16.1.2 Kon#gurasi Network . . . . . . . . . . . . . . . . . . . . . 126

16.1.3 Pemasangan Virtualmin . . . . . . . . . . . . . . . . . . . 127

16.1.4 Text Editor . . . . . . . . . . . . . . . . . . . . . . . . . . 128

16.1.5 Kon#gurasi PHP . . . . . . . . . . . . . . . . . . . . . . . 129


16.1.6 Mail Server . . . . . . . . . . . . . . . . . . . . . . . . . . 129

16.1.7 PostgreSQL . . . . . . . . . . . . . . . . . . . . . . . . . . 130

16.1.8 Kon#gurasi Awal Virtualmin . . . . . . . . . . . . . . . . 130

16.1.9 Mail Aount . . . . . . . . . . . . . . . . . . . . . . . . . 131

16.1.10 Hak Akses . . . . . . . . . . . . . . . . . . . . . . . . . . . 132

16.1.11 Berikan Bash . . . . . . . . . . . . . . . . . . . . . . . . . 132

16.1.12 Kon#gurasi Python . . . . . . . . . . . . . . . . . . . . . . 132

16.1.13 Mengubah Sifat Virtualmin . . . . . . . . . . . . . . . . . 133

16.1.14 Pendaftaran Domain . . . . . . . . . . . . . . . . . . . . . 138

16.1.15 User Spae . . . . . . . . . . . . . . . . . . . . . . . . . . 139

16.2 Go ogle Apps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140

Kata Pengantar

Terimakasih saya uapkan untuk I Made Wiryana yang telah mengusulkan

Python kepada p enulis untuk p ertama kali. Juga kepada Arie Zanahar yang

mengusulkan p enggunaan Virtualmin sebagai hosting management.

Bab 1

Alasan

Mengapa Python merupakan bahasa yang tepat untuk p embuatan b erbagai

aplikasi ? Berikut ini alasannya.

Multiplatform Python merupakan bahasa p emrograman yang tersedia di b erba-

gai platform sep erti Linux, Windows, Ma, Unix. Bahkan sudah tersedia

di platform handphone sep erti Symbian dan Android.

Mudah Python tergolong sripting, artinya Anda ukup tulis soure-nya di

text editor biasa, lalu jalankan.

Hemat Bahasa ini b erkonsep hemat soure. Tampak pada ara p enulisannya

yang tidak membutuhkan karakter atau kata khusus untuk BEGIN dan

END. Sebagai gantinya sub-blo k dipisahkan dengan indent (p enulisan

menjorok ke kanan).
Lalu mengapa PostgreSQL dipilih sebagai media p enyimpanan datanya ?

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

Lengkap PostgreSQL tergolong lengkap dan mudah dikembangkan. Memili-

ki sifat umum traditional database sep erti transation, stored pro edure

(funtion), dan trigger. Bahkan funtion bisa ditulis dalam b erbagai ba-

hasa (tidak hanya SQL), Python, Perl, Shell, dan Java adalah ontoh ba-

hasa yang didukungnya. Ia juga memiliki mo dul khusus untuk kebutuhan

GIS (Geographi Information System).

Bab 2

Pemasangan

Untuk memudahkan p enjelasan, kita gunakan distro Linux b erbasis Ubuntu.

Pada saat tulisan ini dibuat kami menggunakan Ubuntu 10.04 (Luid). Anda

juga bisa menggunakan jenis Ubuntu lainnya sep erti Kubuntu (window manager

KDE), atau BlankOn (buatan Indonesia).

Pasa instalasi Ubuntu Python sudah disertakan. Namun masih ada yang

p erlu diunduh (download) lagi. Seb elumnya p erbaharui daftar paket yang akan

diunduh, lakukan ini di konsole:

1 $ s u d o a p t − g e t u p d a t e

Pasang PostgreSQL:

1 $ s u d o a p t − g e t i n s t a l l p o s t g r e s q l p o s t g r e s q l − p
l p y t h o n − 8 . 4

plpython digunakan saat kita membuat funtion di PostgreSQL, alternatif

lain dari plpgsql yang terpasang seara default.

Pasang SQLAlhemy agar Python bisa menggunakan PostgreSQL:

1 $ s u d o a p t − g e t i n s t a l l p y t h o n − s q l a l h e m y p y t h o
n −p s y o p g 2

Saat p emasangan paket p ostgresql seara otomatis paket p ostgresql-lient-8.4

terpasang. Paket ini memuat psql yang digunakan untuk terhubung ke Post-

greSQL server, seara ommand line. Ada baiknya Anda juga memasang versi

web-nya:
1 $ s u d o a p t − g e t i n s t a l l p h p p g a d m i n

Kadang web server Apahe tidak otomatis hidup:

1 $ s u d o / e t / i n i t . d / a p a h e 2 s t a r t

Seara default Apahe hidup otomatis saat komputer b o ot. Lalu buatlah sym-

link phppgadmin:

1 $ s u d o l n − s / u s r / s h a r e / p h p p g a d m i n / v a r /www/

Kemudian di browser (sebaiknya Firefox) buka url:

BAB 2. PEMASANGAN 7

http://loalhost/phppgadmin

Bagi p engguna window manager Gnome Anda bisa gunakan gedit sebagai text

editor. Sedangkan p engguna KDE bisa gunakan kate. Keduanya b erbasis GUI.

Jika Anda lebih nyaman dengan konsole bisa gunakan nano, jo e, atau vi.

1 $ s u d o a p t − g e t i n s t a l l v i m

Kemudian sesuaikan /et/vim/vimr,

1 $ s u d o v i / e t / v i m / v i m r

Biasanya option sudah disediakan, Anda tinggal menghapus tanda kutip di

awal option. Aktifkan p ewarnaan agar nyaman saat membaa soure:

1 " V i m 5 a n d l a t e r v e r s i o n s s u p p o r t s y n t a x h i g h l i g
h t i n g .

U n o m m e n t i n g t h e n e x t

2 " l i n e e n a b l e s s y n t a x h i g h l i g h t i n g b y d e f a u l t .

3 s y n t a x o n

Saat Anda membuka #le untuk keduakalinya, maka kursor langsung menuju

ke lokasi seb elumnya.

1 " U n o m m e n t t h e f o l l o w i n g t o h a v e Vim j u m p t o t h e l a
s t

p o s i t i o n w h e n

2 " r e o p e n i n g a f i l e

3 i f h a s ( " a u t o m d " )
4 a u B u f R e a d P o s t * i f l i n e ( " ' \ " " ) > 0 && l i n e ( " ' \ "
" ) <=

l i n e ( " $ " ) | e x e " n o r m a l g ' \ " " | e n d i f

5 e n d i f

Menjorok otomatis (auto indent), dan p enekanan tomb ol TAB diganti den-

gan SPACE 4 kali:

1 " U n o m m e n t t h e f o l l o w i n g t o h a v e Vim l o a d i n d e n t a
t i o n

r u l e s a o r d i n g t o t h e

2 " d e t e t e d f i l e t y p e . P e r d e f a u l t D e b i a n Vim o n l y l
o a d

f i l e t y p e s p e i f i

3 " p l u g i n s .

4 i f h a s ( " a u t o m d " )

5 f i l e t y p e i n d e n t o n

6 s e t s m a r t i n d e n t

7 s e t e x p a n d t a b

8 s e t t a b s t o p =4

9 s e t s o f t t a b s t o p =4

10 s e t s h i f t w i d t h =4

11 e n d i f

Penarian mengabaikan huruf b esar atau keil (inasesensitive).

1 s e t i g n o r e a s e " Do a s e i n s e n s i t i v e m a t h i n g

BAB 2. PEMASANGAN 8

Bila kata yang diari mengandung huruf b esar dan huruf keil, maka p en-

arian memp erhatikan huruf b esar atau keil (asesensitive).

1 s e t s m a r t a s e " Do s m a r t a s e m a t h i n g

Aktifkan kedua opsi p enarian di atas, maka p enarian di vim ( menggu-

nakan p erintah slash / ) semakin mudah.

Bab 3

Hello World!
Anda bisa memulai Python dalam mo dus interaktif. Nanti kalau soure sudah

mulai panjang kita simpan dalam #le. Mo dus interaktif dijalankan di konsole,

lalu ketik:

1 $ p y t h o n

maka sambutannya sep erti ini:

1 P y t h o n 2 . 6 . 5 ( r 2 6 5 : 7 9 0 6 3 , A p r 1 6 2 0 1 0 , 1 3 : 5 7 : 4 1
)

2 [ GCC 4 . 4 . 3 ℄ o n l i n u x 2

3 T y p e " h e l p " , " o p y r i g h t " , " r e d i t s " o r " l i e n s e


" f o r m o r e

4 i n f o r m a t i o n .

5 >>>

Mulailah dengan yang sederhana, menampilkan sebuah p esan menggunakan

p erintah print.

1 >>> p r i n t ' H e l l o W o r l d ! '

2 H e l l o W o r l d !

Gunakan tomb ol panah atas untuk mengulang p erintah seb elumnya, lalu ki-

ta oba sedikit salah satu iri p emgrograman b erorientasi ob jek (ob jet oriented

programming / OOP).

1 >>> p r i n t ' H e l l o W o r l d ! ' . u p p e r ( )

2 HELLO WORLD !

3 >>> p r i n t ' H e l l o W o r l d ! ' . l o w e r ( )

4 h e l l o w o r l d !

'Hello World!' adalah sebuah string, yaitu DATA yang b oleh b erisi alphanu-

meri, b oleh terdiri dari huruf dan angka atau karakter lainnya. Contoh di atas

menyebutkan bahwa string tidak hanya b erisi data, ia juga memuat FUNGSI

yang b ernama upp er() dan lower(). Dengan demikian 'Hello World!' bukan

sekedar string, tapi disebut OBJEK string. Inilah iri ob jek, memuat data dan

fungsi.

BAB 3. HELLO WORLD! 10


Bingung ? Lupakan dulu p emrograman b erorientasi ob jek. Untuk keluar

dari mo dus interaktif tekan Ctrl-D.

3.1 Variab el dan Tip e Datanya

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

1 >>> p r i n t " H a r i Jum ' a t "

2 H a r i Jum ' a t

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

1 >>> p r i n t " " " Nama : Bummi D w i P u t e r a

2 . . . A l a m a t : B o g o r

3 . . . H o b i : M e n g g a m b a r " " "

4 Nama : Bummi D w i P u t e r a

5 A l a m a t : B o g o r

6 H o b i : M e n g g a m b a r

Perhatikan tiga buah titik di atas yang b erarti sebuah p erintah b elum b e-

rakhir.

Selanjutnya marilah membuat sript yang akan menanyakan nama, alamat,

dan hobi, lalu menampilkannya kembali di layar. Kali ini kita simpan dalam

sebuah #le p egawai.py. Anda bisa gunakan text editor favorit sep erti gedit,

kate, nano, jo e, atau vi.

Listing 3.1: p egawai.py

1 nama = r a w _ i n p u t ( ' Nama : ' )

2 a l a m a t = r a w _ i n p u t ( ' A l a m a t : ' )

3 h o b i = r a w _ i n p u t ( ' H o b i : ' )

4 p r i n t ' Nama : ' , nama

5 p r i n t ' A l a m a t : ' , a l a m a t

6 p r i n t ' H o b i : ' , h o b i

Setelah disimpan jalankan:

1 $ p y t h o n p e g a w a i . p y

Lalu masukkan data sep erti yang diminta:


1 Nama : Bummi D w i P u t e r a

2 A l a m a t : B o g o r

3 H o b i : M e n g g a m b a r

raw_input() adalah fungsi untuk menerima masukkan dari user. Fungsi ini

menghasilkan string yang b erisi masukkan user tersebut, dan dilimpahkan ke

variab el nama, alamat, dan hobi. Anda bisa kembali ke mo dus interaktif untuk

sekedar mengetahui tip e data dari variab el nama.

BAB 3. HELLO WORLD! 11

1 >>> nama = r a w _ i n p u t ( ' Nama : ' )

2 Nama : Bummi

3 >>> p r i n t t y p e ( nama )

4 < t y p e ' s t r ' >

Pada sript di atas kita mulai mengenal apa yang disebut variab el, yaitu

nama, alamat, dan hobi. Variab el bisa dikatakan sebagai p enampung. Tip e

data ketiga variab el di atas adalah string. Mari kita oba tip e data lainnya.

1 >>> a = 3

2 >>> b = 5

3 >>> p r i n t a + b

4 8

5 >>> p r i n t t y p e ( a )

6 < t y p e ' i n t ' >

Variab el a dan b b ertip e integer alias bilangan bulat. Berikut ini untuk

bilangan p eahan (#oat).

1 >>> = 7 . 2

2 >>> p r i n t t y p e ( )

3 < t y p e ' f l o a t ' >

Ya, p emisah bilangan bulat dengan p eahannya adalah dengan titik. Oh ya,

Python tergolong ketat dalam hal p engop erasian antar tip e data. Kita tidak

dip erkenankan menambahkan string dengan integer.

1 >>> nama = ' Bummi '


2 >>> u m u r = 2 4

3 >>> p r i n t nama + ' u s i a ' + u m u r + ' t a h u n '

4 T r a e b a k ( m o s t r e e n t a l l l a s t ) :

5 F i l e "< s t d i n > " , l i n e 1 , i n <m o d u l e >

6 T y p e E r r o r : a n n o t o n a t e n a t e ' s t r ' a n d ' i n t ' o b


j e t s

Untuk mengatasinya jadikan variab el umur menjadi string:

1 >>> p r i n t nama + ' u s i a ' + s t r ( u m u r ) + ' t a h u n '

2 Bummi u s i a 2 4 t a h u n

Atau dengan ara lain yg lebih mudah dibaa:

1 >>> p r i n t ' % s u s i a %s t a h u n ' % ( nama , u m u r )

2 Bummi u s i a 2 4 t a h u n

Meski string tidak bisa ditambah dengan integer, namun string bisa dikalikan

dengan integer:

1 >>> p r i n t ' a b ' * 1 0

2 a b a b a b a b a b a b a b a b a b a b

Kembali ke #le p egawai.py, tidak dip erkenankan menulis #tidak rapi#. Cobal-

ah membuat kesalahan di baris terakhir pada #le p egawai.py, yaitu dengan

menambahkan dua spasi seb elum print:

BAB 3. HELLO WORLD! 12

1 nama = r a w _ i n p u t ( ' Nama : ' )

2 a l a m a t = r a w _ i n p u t ( ' A l a m a t : ' )

3 h o b i = r a w _ i n p u t ( ' H o b i : ' )

4 p r i n t ' Nama : ' , nama

5 p r i n t ' A l a m a t : ' , a l a m a t

6 p r i n t ' H o b i : ' , h o b i

Kemudian jalankan:

1 $ p y t h o n p e g a w a i . p y

hasilnya Python protes karena ada indent (menjorok masuk) yang tidak

dip erkenankan:
1 $ p y t h o n p e g a w a i . p y

2 F i l e " p e g a w a i . p y " , l i n e 6

3 p r i n t ' H o b i : ' , h o b i

4 ^

5 I n d e n t a t i o n E r r o r : u n e x p e t e d i n d e n t

Sep erti kita lihat, sript Python tanpa diawali suatu BEGIN .. END atau

{ .. } atau b erbagai p enanda lainnya sebagai b entuk awal dan akhir program.

Baris-baris utama selalu tanpa indent alias rapat kiri. Baris yang memiliki

indent b erarti dianggap bagian dari sub-blok sep erti dalam lo oping (for) atau

kondisi (if ).

1 nama = r a w _ i n p u t ( ' Nama : ' )

2 a l a m a t = r a w _ i n p u t ( ' A l a m a t : ' )

3 h o b i = r a w _ i n p u t ( ' H o b i : ' )

4 p r i n t ' Nama : ' , nama

5 p r i n t ' A l a m a t : ' , a l a m a t

6 i f h o b i :

7 p r i n t ' H o b i : ' , h o b i

Sript di atas b erarti jika hobi diisi maka ditampilkan.

3.2 Kondisi

Python punya semaam p edoman dalam hal kondisi (if ), dimana jika suatu

variab el ada isinya maka True, jika kosong maka False.

1 i f h o b i :

2 p r i n t ' H o b i : ' , h o b i

bisa juga ditulis dengan

1 i f h o b i ! = ' ' :

2 p r i n t ' H o b i : ' , h o b i

Seara tip e data hobi tentulah sebuah string, tapi bagaimana dengan hobi

!= # ? Mari kita uji di mo dus interaktif dimana variab el hobi ada isinya.

BAB 3. HELLO WORLD! 13


Tip e False True (Contoh)

String # 'ab '

Integer 0 1

Float 0 1.2

List [℄ [10,20,30℄

Ditionary {} {'nama': 'Bummi', 'alamat': 'Bogor'}

Ob jek None True

Tab el 3.1: Kondisi False di b erbagai tip e data

1 >>> h o b i = ' M e n g g a m b a r '

2 >>> h o b i ! = ' '

3 T r u e

4 >>> h o b i == ' '

5 F a l s e

Lalu obalah variab el hobi kosong.

1 >>> h o b i = ' '

2 >>> h o b i ! = ' '

3 F a l s e

4 >>> h o b i == ' '

5 T r u e

Pahami baik-baik p erb edaan keduanya. Perhatikan juga p enggunaan karak-

ter samadengan dua kali ( == ) yang b erarti op erasi logika (b o olean op


eration).

1 >>> k o s o n g = h o b i == ' '

2 >>> p r i n t k o s o n g

3 T r u e

Kembali ke p egawai.py dimana bila hobi tidak diisi maka program akan

memb erikan saran. Salinlah menjadi p egawai1.py sep erti b erikut ini.

Listing 3.2: p egawai1.py

1 nama = r a w _ i n p u t ( ' Nama : ' )

2 a l a m a t = r a w _ i n p u t ( ' A l a m a t : ' )
3 h o b i = r a w _ i n p u t ( ' H o b i : ' )

4 p r i n t ' Nama : ' , nama

5 p r i n t ' A l a m a t : ' , a l a m a t

6 i f h o b i :

7 p r i n t ' H o b i : ' , h o b i

8 e l s e :

9 p r i n t ' S e b a i k n y a h o b i d i i s i . '

else digunakan untuk kondisi sebaliknya (False). Bagaimana jika kondisi

tambahan ? Misalkan jika hobinya menggambar maka p esan untuk hadir di

hari Sabtu ditampilkan.

BAB 3. HELLO WORLD! 14

Listing 3.3: p egawai2.py

1 nama = r a w _ i n p u t ( ' Nama : ' )

2 a l a m a t = r a w _ i n p u t ( ' A l a m a t : ' )

3 h o b i = r a w _ i n p u t ( ' H o b i : ' )

4 p r i n t ' Nama : ' , nama

5 p r i n t ' A l a m a t : ' , a l a m a t

6 i f h o b i . u p p e r ( ) == 'MENGGAMBAR ' :

7 p r i n t ' D a t a n g l a h d i p e l a t i h a n g a m b a r s e t i a
p S a b t u . '

8 e l i f h o b i :

9 p r i n t ' H o b i : ' , h o b i

10 e l s e :

11 p r i n t ' S e b a i k n y a h o b i d i i s i . '

Perhatikan juga p enggunaan titik dua ( : ) pada if dan else. Ini iri lain

untuk menandai awal suatu sub-blok. Jadi bisa dipastikan setelah titik dua

baris b erikutnya selalu menjorok ke dalam (indent).

3.3 Perulangan

Mari kita buat input p egawai jadi lebih mudah, dimana program akan menanyakan

data terus-menerus dan baru b erhenti bila nama tidak diisi.


Listing 3.4: p egawai3.py

1 w h i l e T r u e :

2 nama = r a w _ i n p u t ( ' Nama : ' )

3 i f n o t nama :

4 b r e a k

5 a l a m a t = r a w _ i n p u t ( ' A l a m a t : ' )

6 h o b i = r a w _ i n p u t ( ' H o b i : ' )

7 p r i n t ' Nama : ' , nama

8 p r i n t ' A l a m a t : ' , a l a m a t

9 i f h o b i :

10 p r i n t ' H o b i : ' , h o b i

11 e l s e :

12 p r i n t ' S e b a i k n y a h o b i d i i s i . '

Perhatikan baris p ertama yang b erarti p erulangan tanpa henti. Yang menghen-

tikannya adalah baris ke empat. break adalah kata khusus untuk menghentikan

p erulangan dimana alur keluar menuju blok bawah di luar p erulangan tersebut.

Keb etulan dalam ontoh ini tidak ada blok lain di luar p erulangan.

Selanjutnya kita buat aturan baru untuk p engisian data ini, dimana:

1. Nama dan alamat harus diisi.

2. Bila selesai satu data p egawai maka program akan menanyakan apakah

akan memasukkan data b erikutnya.

BAB 3. HELLO WORLD! 15

Di sini akan kita ubah sedikit logika while-nya.

Listing 3.5: p egawai4.py

1 l a n j u t = ' Y '

2 w h i l e l a n j u t ! = ' S ' :

3 nama = r a w _ i n p u t ( ' Nama : ' )

4 i f n o t nama :

5 p r i n t ' Nama h a r u s d i i s i . '

6 o n t i n u e
7 a l a m a t = r a w _ i n p u t ( ' A l a m a t : ' )

8 i f n o t a l a m a t :

9 p r i n t ' A l a m a t h a r u s d i i s i . '

10 o n t i n u e

11 h o b i = r a w _ i n p u t ( ' H o b i : ' )

12 p r i n t ' Nama : ' , nama

13 p r i n t ' A l a m a t : ' , a l a m a t

14 i f h o b i :

15 p r i n t ' H o b i : ' , h o b i

16 e l s e :

17 p r i n t ' S e b a i k n y a h o b i d i i s i . '

18 l a n j u t = r a w _ i n p u t ( ' T e k a n " S " j i k a s e l e s a


i : ' ) . u p p e r ( )

ontinue pada baris ke 6 menandakan alur kembali ke while pada baris ke 2.

Perhatikan juga p enggunaan raw_input() pada baris terakhir. Karena fungsi

ini mengembalikan nilai string maka kita bisa lanjutkan dengan memanggil

fungsi upp er(). Dengan ara ini user dip erb olehkan memasukkan dengan s keil

maupun S b esar.

while o ok untuk p erulangan yang kondisinya #tidak menentu#. Bagaimana

bila kita butuh p erulangan yang jumlahnya sudah diketahui ? Misalkan etak

angka 1 hingga 5.

1 f o r i i n [ 1 , 2 , 3 , 4 , 5 ℄ :

2 p r i n t i

Hasilnya:

Perhatikan [1,2,3,4,5℄ yang merupakan data b ertip e list atau sering juga disebut
sebagai array. Kita bisa p ersingkat p enulisannya dengan fungsi range().

1 f o r i i n r a n g e ( 5 ) :

2 p r i n t i

Hasilnya

BAB 3. HELLO WORLD! 16

Meski tidak dimulai dari 1 tapi jumlah barisnya tetap 5. Jika tetap ingin dimulai

dari 1 gunakan range(1,6).

1 f o r i i n r a n g e ( 1 , 6 ) :

2 p r i n t i

Karena for merupakan p erulangan juga sebagaimana while, maka p erintah

break dan ontinue juga b erlaku di dalamnya.

Bab 4

Tip e Data

Memp erhatikan tip e data salah satu p okok pada Python dan ini juga menjadi

salah satu kuni agar mudah dalam p enarian kesalahan (debugging).

4.1 String

Sudah dibahas seb elumnya bagaimana menuliskan data b ertip e string.

1 >>> nama = ' A g u s '

Atau bisa juga menggunakan kutip ganda.

1 >>> nama = A g u s

Jika Anda butuh kutip tunggal di dalam string, siasatilah.

1 >>> h a r i = Jum ' a t

Masih b elum yakin apa tip e data variab el nama ? Gunakan typ e().

1 >>> t y p e ( nama )
2 < t y p e ' s t r ' >

Data b ertip e string bisa b erisi karakter apa sa ja sep erti huruf, angka, tanda

baa, atau gabungannya.

Menggabungkan dua buah variab el string bisa menggunakan tanda plus ( +

).

1 >>> p r i n t nama + ' l a h i r h a r i ' + h a r i

2 A g u s l a h i r h a r i Jum ' a t

Namun ara ini tidak disarankan karena membuat program menjadi sulit

dibaa. Kalau program sulit dibaa menyulitkan p enelusuran bila ada kesalahan

(debugging). Jadi sebaiknya gunakan formatting.

1 >>> p r i n t ' % s l a h i r h a r i %s ' % ( nama , h a r i )

2 A g u s l a h i r h a r i Jum ' a t

17

BAB 4. TIPE DATA 18

Lalu bagaimana menampilkan % itu sendiri di dalam formatting ? Sebutkan-

lah dua kali.

1 >>> p r i n t ' K e u n t u n g a n b u l a n i n i m e n i n g k a t %d %%' %


( 1 0 )

2 K e u n t u n g a n b u l a n i n i m e n i n g k a t 1 0 %

4.2 Bilangan

Bilangan bulat atau integer atau disingkat int dinyatakan tanpa titik.

1 >>> a = 1 0

a ditambah 2

1 > > > a + 2

2 1 2

a dikurang 4

1 >>> a − 4

2 6

a dikali 5

1 >>> a * 5
2 5 0

a dibagi dengan 3

1 >>> a / 3

2 3

Mengapa bukan 3.3333 ?

Pembagian bilangan bulat dengan bilangan bulat menghasilkan bilangan bu-

lat juga. Jika Anda mengharapkan hasil yang lebih rini maka salah satunya

harus bilangan p eahan (#oat).

1 >>> a / 3 . 0

2 3 . 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 5

Untuk mendapatkan sisa p embagian (mo dulus) gunakan tanda p ersen ( %

).

1 >>> a % 3

2 1

a pangkat 2

1 >>> a * * 2

2 1 0 0

BAB 4. TIPE DATA 19

4.2.1 Konversi Tip e Data

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

1 >>> i n t ( ' 1 0 ' )

2 1 0

int() juga dapat digunakan untuk p embulatan.

1 >>> i n t ( 1 0 . 2 )

2 1 0

Untuk p embulatan #yang mendekati# gunakan round().

1 >>> r o u n d ( 1 0 . 4 )

2 1 0

3 >>> r o u n d ( 1 0 . 5 )

4 1 1
round() akan membulatkan ke bawah bila p eahan suatu bilangan lebih keil

dari 0,5. Sebaliknya ia akan membulatkan ke atas.

Untuk konversi dari string menjadi bilangan p eahan menggunakan fungsi

#oat().

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

2 1 0 . 5

4.2.2 Formatting

Menuliskan bilangan ke dalam string bisa menggunakan formatting.

1 >>> a = 3

2 >>> b = 2

3 >>> p r i n t ' % s + %s = %s ' % ( a , b , a+b )

4 3 + 2 = 5

Meski formatting %s bisa digunakan untuk tip e data apa sa ja, sebaiknya An-

da menggunakan formatting yang lebih sp esi#k sesuai tip e datanya. Katakanlah

Anda menetapkan bahwa variab el a itu harus b ertip e bilangan bulat (integer),

b egitu pula dengan variab el b, maka gunakanlah %d.

1 >>> p r i n t ' % d + %d = %d ' % ( a , b , a+b )

2 3 + 2 = 5

Untuk bilangan p eahan (#oat) gunakan %f.

1 >>> a = 3 . 5

2 >>> p r i n t ' % f + % f = %f ' % ( a , b , a+b )

3 3 . 5 0 0 0 0 0 + 2 . 0 0 0 0 0 0 = 5 . 5 0 0 0 0 0

Anda juga bisa mengatur jumlah digit di b elakang koma.

1 > > > p r i n t ' % . 2 f + % . 2 f = % . 2 f ' % ( a , b , a + b )

2 3 . 5 0 + 2 . 0 0 = 5 . 5 0

BAB 4. TIPE DATA 20

4.2.3 Kalkulator

Membuat kalkulator tidaklah sulit, Anda ukup gunakan eval(). Buatlah #le

al.py b erikut ini.


Listing 4.1: al.py

1 w h i l e T r u e :

2 h i t u n g = r a w _ i n p u t ( ' H i t u n g : ' )

3 i f n o t h i t u n g :

4 b r e a k

5 p r i n t e v a l ( h i t u n g )

Jalankan.

1 $ p y t h o n a l . p y

2 H i t u n g : 2+3

3 5

4 H i t u n g : 7 * * 2

5 4 9

6 H i t u n g : 7 + 2 * 3

7 1 3

8 H i t u n g :

9 $

Perhatikan baik-baik. Semua kalimat Python diterjemahkan oleh eval(), baik

kalimat itu mengandung spasi ataupun tidak, eval() sanggup memahaminya.

Mudah bukan?

Perhatikan juga kalimat 7 + 2 * 3 yang menghasilkan nilai 13. Ini artinya

aturan prioritas pada matematika umum b erlaku, dimana p erkalian lebih dulu

dilakukan ( 2 * 3 ). Barulah hasilnya ( 6 ) ditambahkan dengan 7.

Program di atas akan terus meminta masukkan dari user hingga tomb ol

Enter sa ja yang ditekan.

4.3 List

Tip e data list kerap digunakan. Kita lihat pada ontoh seb elumnya bagaimana

list menjadi wa jib pada p erulangan for. Bahkan string seb enarnya bisa dianggap

sebagai list.

1 f o r h i n ' Bummi ' :

2 p r i n t h ,
hasilnya:

1 Bummi

Perhatikan p enggunaan koma pada print yang b erarti #jangan ganti baris#.

Mari kembali ke mo dus interaktif untuk menoba list.

BAB 4. TIPE DATA 21

Gambar 4.1: Struktur list

1 >>> d a t a = [ ' Bummi D w i P u t e r a ' , ' B o g o r ' , ' M e n g g a m b a


r ' , 2 4 ℄

2 >>> p r i n t d a t a [ 0 ℄

3 ' Bummi D w i P u t e r a '

4 >>> p r i n t d a t a [ 1 ℄

5 ' B o g o r '

Tampilkan elemen terakhir:

1 >>> p r i n t d a t a [ − 1 ℄

2 2 4

Elemen kedua dari terakhir:

1 >>> p r i n t d a t a [ − 2 ℄

2 ' M e n g g a m b a r '

4.3.1 Pemenggalan

Selain dapat diambil p er elemen, juga dapat diambil b eb erapa elemen sekali-

gus, ini disebut sebagai p emenggalan (sliing). Tampilkan elemen p ertama dan

kedua:

1 >>> p r i n t d a t a [ 0 : 2 ℄

2 [ ' Bummi D w i P u t e r a ' , ' B o g o r ' ℄

Atau ukup ditulis tanpa 0:

1 >>> p r i n t d a t a [ : 2 ℄

2 [ ' Bummi D w i P u t e r a ' , ' B o g o r ' ℄

Tampilkan 3 elemen terakhir:

1 >>> p r i n t d a t a [ − 3 : ℄

2 [ ' B o g o r ' , ' M e n g g a m b a r ' , 2 4 ℄


Ada baiknya kita pahami ara kerjanya. Pemenggalan list b ekerja dengan

batas elemen. Gambar 4.1 adalah ontoh string Python yang bisa dianggap

sebagai list. Cermati baik-baik bagaimana b ekerja dengan elemen dan batas

elemen (untuk p emenggalan).

BAB 4. TIPE DATA 22

4.3.2 Keb eradaan Elemen

Anda memiliki daftar nama buah yang dapat diari oleh user. Setelah user

memasukkan nama buah program akan menarinya dalam list dan memb eri-

tahukan hasilnya. Setelah itu program akan kembali menanyakan nama buah

b erikutnya. Program b erakhir jika user hanya menekan Enter sa ja, alias tidak

memasukkan apapun. Sekarang buatlah pro duk.py b erikut ini.

Listing 4.2: pro duk.py

1 d a f t a r = [ ' j e r u k ' , ' m a n g g a ' , ' a p e l ' , ' p i s a n g ' ,


' j a m b u ' ℄

3 w h i l e T r u e :

4 a r i = r a w _ i n p u t ( ' C a r i b u a h : ' )

5 i f n o t a r i :

6 p r i n t ' S e l e s a i '

7 b r e a k

8 i f a r i i n d a f t a r :

9 p r i n t ( ' D i t e m u k a n ' )

10 e l s e :

11 p r i n t ( ' T i d a k d i t e m u k a n ' )

Jalankanlah.

1 $ p y t h o n p r o d u k . p y

2 C a r i b u a h : m a n g g a

3 D i t e m u k a n

4 C a r i b u a h : d u k u

5 T i d a k d i t e m u k a n
6 C a r i b u a h :

7 S e l e s a i

Keb eradaan elemen bisa digunakan sebagai kondisi. Misalkan program Anda

dapat menerima masukan (input parameter) sesaat seb elum dijalankan, sering

disebut sebagai argument. Sep erti pada ontoh at.py b erikut ini.

Listing 4.3: at.py

1 i m p o r t s y s

2 p r i n t s y s . a r g v

Jalankanlah.

1 $ p y t h o n a t . p y

2 [ ' a t . p y ' ℄

Jalankan lagi dengan input parameter.

1 $ p y t h o n a t . p y / e t / h o s t s

2 [ ' a t . p y ' , ' / e t / h o s t s ' ℄

Perhatikan elemen p ertama adalah #le at.py itu sendiri, dan elemen kedua

adalah nama #le yang akan ditampilkan. Ya, kita akan membuatnya dapat

membuka #le yang disebutkan dan menampilkannya di layar.

BAB 4. TIPE DATA 23

Listing 4.4: at1.py

1 i m p o r t s y s

3 f i l e n a m e = s y s . a r g v [ 1 ℄

4 f = o p e n ( f i l e n a m e )

5 p r i n t f . r e a d ( )

6 f . l o s e ( )

Jalankan.

1 $ p y t h o n a t 1 . p y / e t / h o s t s

2 1 2 7 . 0 . 0 . 1 l o a l h o s t o m p a q

3 1 2 7 . 0 . 1 . 1 o m p a q
4

5 # T h e f o l l o w i n g l i n e s a r e d e s i r a b l e f o r I P v 6 a p a
b l e

h o s t s

6 : : 1 l o a l h o s t i p 6 − l o a l h o s t i p 6 − l o o p b a k

7 f e 0 0 : : 0 i p 6 − l o a l n e t

8 f f 0 0 : : 0 i p 6 − m a s t p r e f i x

9 f f 0 2 : : 1 i p 6 − a l l n o d e s

10 f f 0 2 : : 2 i p 6 − a l l r o u t e r s

11 f f 0 2 : : 3 i p 6 − a l l h o s t s

Kita p erlu mengantisipasi kesalahan yang dilakukan user, dimana bisa sa ja

ia tidak tahu ara menggunakan at1.py, yaitu langsung menjalankan tanpa

menyertakan nama #le.

1 $ p y t h o n a t 1 . p y

2 T r a e b a k ( m o s t r e e n t a l l l a s t ) :

3 F i l e " a t . p y " , l i n e 3 , i n <m o d u l e >

4 f i l e n a m e = s y s . a r g v [ 1 ℄

5 I n d e x E r r o r : l i s t i n d e x o u t o f r a n g e

Tampilan kesalahan ini jelas kurang informatif dan bisa jadi user tidak tahu

apa yang harus dilakukan. Saatnya menggunakan deteksi keb eradaan elemen.

Listing 4.5: at2.py

1 i m p o r t s y s

3 i f n o t s y s . a r g v [ 1 : ℄ :

4 p r i n t ( ' C a r a m e n g g u n a k a n n y a : p y t h o n %s <nama −
f i l e > ' %

s y s . a r g v [ 0 ℄ )

5 s y s . e x i t ( )

7 f i l e n a m e = s y s . a r g v [ 1 ℄

8 f = o p e n ( f i l e n a m e )
9 p r i n t f . r e a d ( )

10 f . l o s e ( )

BAB 4. TIPE DATA 24

Jalankanlah tanpa input parameter,

1 $ p y t h o n a t 2 . p y

2 C a r a m e n g g u n a k a n n y a : p y t h o n a t . p y <nama − f i l e >

Kini program akan menampilkan p etunjuk ara menggunakannya. Mari kita

bahas ara kerjanya.

Perhatikan baris ketiga

if not sys.argv[1:℄:

Kalau kita p erhatikan lagi isi dari sys.argv pada saat tidak dib erikan input

parameter adalah:

['at.py'℄

Dengan b egitu sys.argv[1:℄ akan b ernilai list hampa:

[℄

Ingatlah mengenai p emenggalan list pada p embahasan seb elumnya. Bila suatu

variab el hampa maka ia bisa dianggap sebagai b o olean False, sehingga

if not sys.argv[1:℄:

bisa b erarti

if not [℄:

yang b erarti

if not False:

dan ini bisa diartikan menjadi:

if True:

True b erarti kondisi terp enuhi dan blok di dalam if dijalankan, dan akhirnya

tampillah p esan ara p enggunaan at2.py tadi.

Lalu apa yang terjadi jika program mendapat input parameter ? Nilai

sys.argv menjadi

['at.py', '/et/hosts'℄
Dengan b egitu

if not sys.argv[1:℄:

bisa b erarti

if not ['/et/hosts'℄:

BAB 4. TIPE DATA 25

Karena ['/et/hosts'℄ adalah list yang b erisi (tidak hampa) maka bisa dianggap

sebagai b o olean True

if not True:

dan ini b erarti juga

if False:

False b erarti kondisi tidak terp enuhi sehingga blok di dalam if tidak dijalankan.

Pahamilah baik-baik p enjelasan ini, Anda akan banyak menemuinya nanti.

Inilah salah satu mengapa program yang dibuat dengan Python b egitu ringkas

namun tetap mudah dibaa.

4.3.3 Mengubah Elemen

Contoh seb elumnya menjelaskan bagaimana menggunakan list. Kini kita oba

b erawal dari list hampa dan mengisinya dengan elemen data. Kembali ke mo dus

interaktif.

1 >>> d a f t a r = [ ℄

2 >>> d a f t a r

3 [ ℄

Tambahkan mangga.

1 >>> d a f t a r . a p p e n d ( ' m a n g g a ' )

2 >>> d a f t a r

3 [ ' m a n g g a ' ℄

Bisa juga dengan ara lain.

1 >>> d a f t a r += [ ' p i s a n g ' ℄

2 >>> d a f t a r

3 [ ' m a n g g a ' , ' p i s a n g ' ℄


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

1 >>> d a f t a r [ 1 ℄ = ' j e r u k '

2 >>> d a f t a r

3 [ ' m a n g g a ' , ' j e r u k ' ℄

Selanjutnya mangga dihapus yang b erarti elemen p ertama atau index ke 0.

1 >>> d e l d a f t a r [ 0 ℄

2 >>> d a f t a r

3 [ ' j e r u k ' ℄

BAB 4. TIPE DATA 26

4.4 Ditionary

List adalah serangkaian elemen yang #alamatnya# adalah nomor urut, sering

disebut sebagai index. Ditionary juga mirip, hanya sa ja alamatnya tidak harus

b erupa angka yang b erurutan. Bahkan bisa b ertip e string atau tip e data lain-

nya. Sekarang buatlah sript b erikut ini.

Listing 4.6: pro duk1.py

1 d a f t a r = {

2 2 : ' j e r u k ' ,

3 7 : ' m a n g g a ' ,

4 4 : ' p i s a n g ' ,

5 3 : ' j a m b u ' ,

6 9 : ' a p e l ' ,

7 }

9 p r i n t d a f t a r

Jalankan.

1 $ p y t h o n p r o d u k 1 . p y

2 { 9 : ' a p e l ' , 2 : ' j e r u k ' , 3 : ' j a m b u ' , 4 : ' p i s a n g ' ,


7 : '

m a n g g a ' }

Perhatikan urutan pada soure, dan bandingkan urutan buah saat dita-
mpilkan. Begitulah ditionary, dia memang tidak memp erhatikan urutan. Ini-

lah salah satu yang memb edakannya dengan list. Ditionary o ok untuk p en-

arian. Pada ontoh di atas angka 2, 7, 4, 3, dan 9 merupakan kuni (key)

bagi variab el daftar. Key ini bisa sa ja dianggap sebagai ko de barang atau ko de

buah. Sedangkan ap el, jeruk, jambu, pisang, dan mangga merupakan nilai (val-

ue). Karena itu ditionary sering disebut sebagai tip e data dengan formasi key

value.

Sekarang kita buat p enarian b erdasarkan ko de barang.

Listing 4.7: pro duk2.py

1 d a f t a r = {

2 2 : ' j e r u k ' ,

3 7 : ' m a n g g a ' ,

4 4 : ' p i s a n g ' ,

5 3 : ' j a m b u ' ,

6 9 : ' a p e l ' ,

7 }

9 w h i l e T r u e :

10 k e y = r a w _ i n p u t ( ' K o d e b a r a n g : ' )

11 i f n o t k e y :

12 p r i n t ' S e l e s a i '

13 b r e a k

BAB 4. TIPE DATA 27

14 i f k e y i n d a f t a r :

15 p r i n t d a f t a r [ k e y ℄

16 e l s e :

17 p r i n t ' K o d e b a r a n g ' , k e y , ' t i d a k d i t e m u k a n '

Cobalah.

1 $ p y t h o n p r o d u k 2 . p y

2 K o d e b a r a n g : 5
3 K o d e b a r a n g 5 t i d a k d i t e m u k a n

4 K o d e b a r a n g : 9

5 K o d e b a r a n g 9 t i d a k d i t e m u k a n

6 K o d e b a r a n g :

7 S e l e s a i

Ko de barang 5 b oleh jadi tidak ditemukan, karena memang tidak ada 5

dalam variab el daftar. Tapi mengapa 9 juga tidak ditemukan ? Seharusnya

program menampilkan ap el.

Jawabannya ada pada tip e data. Fungsi raw_input() itu mengembalikan

nilai b ertip e string. Berarti key pada baris

key = raw_input('Kode barang: ')

juga b ertip e string. Lalu

if key in daftar:

b erarti menari string key dalam daftar yang isinya bilangan bulat (integer)

semua, yaitu 2, 7, 4, 3, dan 9. Jelas tidak akan ditemukan. Untuk membuktikan

bahwa 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 $ p y t h o n p r o d u k 2 . p y

2 K o d e b a r a n g : 9

3 K o d e b a r a n g [ ' 9 ' ℄

4 t i d a k d i t e m u k a n

5 K o d e b a r a n g :

6 S e l e s a i

Dengan memb erikan kurung siku pada variab el maka akan tampak bahwa

key adalah string. Terlihat adanya kutip tunggal pada '9'. Lalu bagaimana

mengubah key agar b ertip e integer ? Gunakan fungsi int().


BAB 4. TIPE DATA 28

Listing 4.8: pro duk3.py

1 d a f t a r = {

2 2 : ' j e r u k ' ,

3 7 : ' m a n g g a ' ,

4 4 : ' p i s a n g ' ,

5 3 : ' j a m b u ' ,

6 9 : ' a p e l ' ,

7 }

9 w h i l e T r u e :

10 k e y = r a w _ i n p u t ( ' K o d e b a r a n g : ' )

11 i f n o t k e y :

12 p r i n t ' S e l e s a i '

13 b r e a k

14 k e y = i n t ( k e y )

15 i f k e y i n d a f t a r :

16 p r i n t d a f t a r [ k e y ℄

17 e l s e :

18 p r i n t ' K o d e b a r a n g ' , k e y , ' t i d a k d i t e m u k a n '

Jalankan lagi.

1 $ p y t h o n p r o d u k 3 . p y

2 K o d e b a r a n g : 5

3 K o d e b a r a n g [ 5 ℄ t i d a k d i t e m u k a n

4 K o d e b a r a n g : 9

5 a p e l

6 K o d e b a r a n g :

7 S e l e s a i

Resapi kembali mengenai tip e data ini karena akan sering dijumpai nanti.

4.5 Waktu
Mo dul time digunakan untuk p enanganan waktu. Kita kembali ke mo dus inter-

aktif dulu untuk memudahkan latihan.

1 >>> i m p o r t t i m e

2 >>> t = t i m e . l o a l t i m e ( )

3 >>> t

4 t i m e . s t r u t _ t i m e ( t m _ y e a r = 2 0 1 0 , tm_mon= 8 , tm_mday =
2 0 ,

t m _ h o u r = 1 1 , tm_min = 4 4 , t m _ s e = 4 7 , tm_wday = 4 , t m _ y d a y

= 2 3 2 , t m _ i s d s t = 0 )

Fungsi time.lo altime() digunakan untuk mendapatkan waktu saat ini. Per-

hatikan variab el t di atas. Jika Anda ingin mengambil tahunnya:

1 >>> t . t m _ y e a r

2 2 0 1 0

BAB 4. TIPE DATA 29

atau bulannya

1 >>> t . tm_mon

2 8

atau harinya

1 >>> t . tm_mday

2 2 0

dan seterusnya hingga jam, menit, dan detiknya, ada di sana.

Waktu juga bisa diwujudkan dalam bilangan p eahan (#oat), sering disebut

sebagai ep o h atau Unix time.

1 >>> t i m e . t i m e ( )

2 1 2 8 2 2 8 0 6 9 9 . 2 2 8 0 3 8 1

Ep o h ini adalah jumlah detik sejak 1 Januari 1970 jam 00:00:00 (GMT)

hingga saat ini.

Fungsi time.lo altime() seb enarnya bisa dib erikan masukan b erupa ep o h

ini. Kita bisa mulai dengan angka 0.


1 >>> t i m e . l o a l t i m e ( 0 )

2 t i m e . s t r u t _ t i m e ( t m _ y e a r = 1 9 7 0 , tm_mon= 1 , tm_mday= 1
,

t m _ h o u r = 7 , tm_min = 0 , t m _ s e = 0 , tm_wday = 3 , t m _ y d a y = 1 ,

t m _ i s d s t = 0 )

Ep o h 0 b erarti 1 Januari 1970. Lalu mengapa tm_hour menunjukkan angka

7 ? Ini terkait dengan zona waktu (timezone) pada komputer yang b erarti

wilayah Jakarta (+7). Jika komputer Anda diset pada zona waktu Bali maka

nilai tm_hour menjadi 8.

Untuk mendapatkan ep o h pada tanggal 17 Agustus 2010 maka bisa gunakan

time.mktime():

1 >>> t i m e . m k t i m e ( ( 2 0 1 0 , 8 , 1 7 , 0 , 0 , 0 , 0 , 0 , 0 ) )

2 1 2 8 1 9 7 8 0 0 0 . 0

Dengan ep o h kita bisa mendapatkan jumlah hari sejak 1 Agustus 2010

hingga 17 Agustus 2010.

1 >>> a w a l = t i m e . m k t i m e ( ( 2 0 1 0 , 8 , 1 , 0 , 0 , 0 , 0 , 0 , 0 )
)

2 >>> a k h i r = t i m e . m k t i m e ( ( 2 0 1 0 , 8 , 1 7 , 0 , 0 , 0 , 0 , 0 ,
0 ) )

3 >>> a k h i r − a w a l

4 1 3 8 2 4 0 0 . 0

Itu adalah jumlah detiknya. Untuk mendapatkan hari kita p erlu mengolah-

nya kembali.

1 >>> ( a k h i r − a w a l ) / 2 4 / 6 0 / 6 0

2 1 6 . 0

Sehingga dip eroleh 16 hari.

BAB 4. TIPE DATA 30

Mo dul datetime

Menghitung hari lebih mudah menggunakan mo dul datetime.

1 >>> f r o m d a t e t i m e i m p o r t d a t e

2 >>> a w a l = d a t e ( 2 0 1 0 , 8 , 1 )
3 >>> a k h i r = d a t e ( 2 0 1 0 , 8 , 1 7 )

4 >>> d = a k h i r − a w a l

5 >>> d . d a y s

6 1 6

Dengan mo dul ini kita juga dapat menghitung jumlah detik sejak 16 Agustus

2010 jam 22:00 hingga 17 Agustus 2010 jam 10:00.

1 >>> f r o m d a t e t i m e i m p o r t d a t e t i m e

2 >>> a w a l = d a t e t i m e ( 2 0 1 0 , 8 , 1 6 , 2 2 , 0 , 0 )

3 >>> a k h i r = d a t e t i m e ( 2 0 1 0 , 8 , 1 7 , 1 0 , 0 , 0 )

4 >>> d = a k h i r − a w a l

5 >>> d . s e o n d s

6 4 3 2 0 0

Untuk mendapatkan jumlah jamnya:

1 >>> d . s e o n d s / 6 0 / 6 0

2 1 2

Bab 5

Mo dularitas

Mari kita buat program yang menghitung nilai faktorial. Apa itu faktorial ?

Berikut ini ontohnya:

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 menampilkan

nilai faktorial-nya.

Listing 5.1: faktorial1.py

1 p r i n t ' M e n g h i t u n g n i l a i f a k t o r i a l '

2 w h i l e T r u e :

3 n = r a w _ i n p u t ( ' n = ' )

4 i f n o t n :

5 b r e a k

6 n = i n t ( n )

7 i f n < 2 :

8 f = 1

9 e l s e :

10 f = 1

11 f o r i i n r a n g e ( 1 , n + 1 ) :

12 f = f * i

13 p r i n t '%d ! = %d ' % ( n , f )

31

BAB 5. MODULARITAS 32

Jalankan.

1 $ p y t h o n f a k t o r i a l 1 . p y

2 M e n g h i t u n g n i l a i f a k t o r i a l

3 n = 2

4 2 ! = 2

5 n = 3

6 3 ! = 6

7 n = 4

8 4 ! = 2 4

9 n =

10 $

Selesai sudah. Berikutnya Anda diminta membuatnya dalam lingkungan


gra#s (graphial user interfae / GUI). Tentu sa ja tidak ada lagi yang namanya

raw_input() dan print, karena ia digunakan untuk lingkungan teks (onsole).

Juga tidak ada lagi while karena GUI sudah mengatur p erulangannya.

Lalu apa yang diambil untuk mengambil soure faktorial ? Baris 6 - 12

sa ja yang p erlu di-opy-paste di soure GUI nanti. Anda juga harus menye-

suaikan variab el n yang menjadi masukannya, karena n tidak lagi b erasal dari

raw_input() melainkan dari komp onen GUI.

Di sini mulai terasa soure faktorial di atas tidak mo dular karena menyulitkan

opy-paste. Kesulitan yang dimaksud adalah soure faktorial menyatu

dengan

soure yang mengurus tampilan. Faktorial adalah ontoh sederhana, bagaimana

kalau nanti Anda diminta membuat rumus lainnya yang jauh lebih rumit ?

5.1 Membuat Fungsi

Sudah saatnya Anda mengenal p embuatan fungsi. Dengannya Anda pisahkan

urusan menghitung nilai faktorial dengan urusan input dan output tampilannya.

Listing 5.2: faktoria2l.py

1 d e f f a k t o r i a l ( n ) :

2 i f n < 2 :

3 r e t u r n 1

4 f = 1

5 f o r i i n r a n g e ( 1 , n + 1 ) :

6 f = f * i

7 r e t u r n f

10 p r i n t ' M e n g h i t u n g n i l a i f a k t o r i a l '

11 w h i l e T r u e :

12 n = r a w _ i n p u t ( ' n = ' )

13 i f n o t n :
14 b r e a k

BAB 5. MODULARITAS 33

15 n = i n t ( n )

16 h a s i l = f a k t o r i a l ( n )

17 p r i n t '%d ! = %d ' % ( n , h a s i l )

Jalankan.

1 $ p y t h o n f a k t o r i a l 2 . p y

2 M e n g h i t u n g n i l a i f a k t o r i a l

3 n = 5

4 5 ! = 1 2 0

5 n = 2

6 2 ! = 2

7 n = 1

8 1 ! = 1

9 n = − 1

10 − 1 ! = 1

11 n =

Hasilnya memang sama sa ja, namun kini soure faktorial lebih mudah dibaa

dan di-opy-paste. Perhatikan juga p enggunaan return yang membuat alur

keluar dari fungsi.

Apa ini sudah ukup mo dular ? Jawabannya b elum.

5.2 Membuat Mo dul

Copy-paste soure sep erti itu tentu sa ja lebih sulit ketimbang opy-paste #le-

nya. Oleh karena itu Anda p erlu membuat soure itu menjadi mo dul faktorial

yang b erarti namanya menjadi faktorial.py sehingga program lain yang mem-

butuhkannya ukup menggunakannya sep erti ini (ontoh):

1 f r o m f a k t o r i a l i m p o r t f a k t o r i a l

2 n = 5

3 p r i n t f a k t o r i a l ( n )

Sekarang buatlah faktorial.py.


Listing 5.3: faktorial.py

1 d e f f a k t o r i a l ( a ) :

2 i f a < 2 :

3 r e t u r n 1

4 f o r i i n r a n g e ( 1 , a ) :

5 a = a * i

6 r e t u r n a

Lalu buatlah obafaktorial.py yang menggunakan mo dul faktorial ini.

Listing 5.4: obafaktorial.py

1 f r o m f a k t o r i a l i m p o r t f a k t o r i a l

BAB 5. MODULARITAS 34

3 p r i n t ' M e n g h i t u n g n i l a i f a k t o r i a l '

4 w h i l e T r u e :

5 n = r a w _ i n p u t ( ' n = ' )

6 i f n o t n :

7 b r e a k

8 n = i n t ( n )

9 h a s i l = f a k t o r i a l ( n )

10 p r i n t '%d ! = %d ' % ( n , h a s i l )

Jalankan.

1 $ p y t h o n o b a f a k t o r i a l . p y

2 M e n g h i t u n g N i l a i F a k t o r i a l

3 n = 5

4 5 ! = 1 2 0

5 n = 2

6 2 ! = 2

7 n =

Hasilnya tetap sama, namun kini Anda lebih mudah opy-paste soure fungsi
faktorial() karena ukup faktorial.py yang di-opy ke direktori program lainnya.

Untuk menoba mo dul faktorial Anda p erlu membuat #le lainnya yaitu

obafaktorial.py. Agar lebih praktis, mengapa tidak disatukan sa ja ?

Benar, alangkah praktisnya jika soure untuk menguji fungsi faktorial() juga

b erada di #le yang sama.

Namun Anda p erlu membuat sedikit p erubahan agar saat

from faktorial import faktorial

soure uji oba tersebut tidak dijalankan. Silahkan ubah faktorial.py menjadi

b erikut ini.

Listing 5.5: faktorial.py

1 d e f f a k t o r i a l ( a ) :

2 i f a < 2 :

3 r e t u r n 1

4 f o r i i n r a n g e ( 1 , a ) :

5 a = a * i

6 r e t u r n a

8 i f __name__ == ' __main__ ' :

9 p r i n t ' M e n g h i t u n g n i l a i f a k t o r i a l '

10 w h i l e T r u e :

11 n = r a w _ i n p u t ( ' n = ' )

12 i f n o t n :

13 b r e a k

14 n = i n t ( n )

BAB 5. MODULARITAS 35

15 h a s i l = f a k t o r i a l ( n )

16 p r i n t '%d ! = %d ' % ( n , h a s i l )

Perhatikan bahwa __name__ adalah name yang diawali dan diakhiri oleh

dua

undersore. Begitu juga dengan __main__. Kemudian jalankan.


1 $ p y t h o n f a k t o r i a l . p y

2 M e n g h i t u n g n i l a i f a k t o r i a l

3 n = 3

4 3 ! = 6

5 n = 4

6 4 ! = 2 4

7 n =

Jadi p erubahannya adalah pada

if __name__ == '__main__':

Dengan baris ini Python dib eritahu bahwa soure dibawahnya hanya dijalankan

jika faktorial.py merupakan program utama

. Kalau faktorial.py sebagai mo dul

maka ia tidak dijalankan.

Anda juga masih bisa menggunakan obafaktorial.py sep erti biasa.

1 $ p y t h o n o b a f a k t o r i a l . p y

5.3 Searh Path

Meng-opy faktorial.py ke b erbagai direktori program yang membutuhkan tentu

sa ja merep otkan. Apalagi bila ada p erubahan soure pada faktorial.py, maka

Anda harus menyebarkannya lagi.

Ada banyak direktori dimana Python akan menari mo dul yang dipang-

gil. Untuk mengetahui direktori mana sa ja yang terdaftar gunakan variab el

sys.path. Masuklah ke mo dus interaktif untuk melihatnya.

1 >>> i m p o r t s y s

2 >>> s y s . p a t h

3 [ ' ' ,

4 ' / u s r / l i b / p y t h o n 2 . 6 ' ,

5 ' / u s r / l i b / p y t h o n 2 . 6 / p l a t − l i n u x 2 ' ,

6 ' / u s r / l i b / p y t h o n 2 . 6 / l i b − t k ' ,

7 ' / u s r / l i b / p y t h o n 2 . 6 / l i b −o l d ' ,
8 ' / u s r / l i b / p y t h o n 2 . 6 / l i b − d y n l o a d ' ,

9 ' / u s r / l i b / p y t h o n 2 . 6 / d i s t −p a k a g e s ' ,

10 ' / u s r / l i b / p y t h o n 2 . 6 / d i s t −p a k a g e s / P I L ' ,

11 ' / u s r / l i b / p y t h o n 2 . 6 / d i s t −p a k a g e s / g s t − 0 . 1
0 ' ,

12 ' / u s r / l i b / p y m o d u l e s / p y t h o n 2 . 6 ' ,

13 ' / u s r / l i b / p y t h o n 2 . 6 / d i s t −p a k a g e s / g t k − 2 . 0
' ,

14 ' / u s r / l i b / p y m o d u l e s / p y t h o n 2 . 6 / g t k − 2 . 0 ' ,

15 ' / u s r / l o a l / l i b / p y t h o n 2 . 6 / d i s t −p a k a g e s ' ℄

BAB 5. MODULARITAS 36

Pertama kali Python akan menari di direktori dimana program utama b e-

rada. Selanjutnya ia akan menari di direktori lainnya sep erti yang Anda lihat

di atas.

Lalu dimana sebaiknya faktorial.py diletakkan ? Karena meletakkannya

tidak melalui instalasi paket Debian, maka saya sarankan diletakkan di direktori

/usr/loal/lib/python2.6/dist-pakages

Anda bisa menyalinnya menggunakan p erintah

1 $ s u d o p f a k t o r i a l . p y / u s r / l o a l / l i b / p y t h o n 2 .
6 / d i s t −

p a k a g e s

Supaya lebih yakin pindahkan sekalian.

1 $ s u d o mv f a k t o r i a l . p y / u s r / l o a l / l i b / p y t h o n 2 .
6 / d i s t −

p a k a g e s

Jika Anda punya direktori lain, Anda bisa tambahkan pada sys.path terlebih

dahulu seb elum imp ort.

1 >>> i m p o r t s y s

2 >>> s y s . p a t h . a p p e n d ( ' / h o m e / s u g i a n a / l i b ' )

3 >>> f r o m f a k t o r i a l i m p o r t f a k t o r i a l

Bab 6

Fungsi
6.1 Memanggil Dirinya Sendiri

Fungsi faktorial() sudah b ekerja dengan baik. Tapi mungkin soure-nya terlalu

panjang. Cobalah ubah menjadi sep erti di bawah ini pada faktorial.py.

1 d e f f a k t o r i a l ( a ) :

2 i f a < 2 :

3 r e t u r n 1

4 r e t u r n a * f a k t o r i a l ( a − 1 )

Jauh lebih e#sien bukan? Teknik sep erti ini disebut juga sebagai rekursif.

Pertama kali yang harus dip erhatikan dalam p embuatan fungsi rekursif adalah

batas kedalaman. Batas ini ditunjukkan pada baris 2-3. Rekursif yang tidak

memiliki batas kedalaman akan menampilkan p esan kesalahan.

6.2 Format Uang

Untuk menampilkan uang biasanya ada p emisah ribuannya. Untuk Indonesia

p emisah ribuan adalah titik, sedangkan p emisah p eahan adalah koma. Untuk

kebutuhan tersebut kita bisa gunakan mo dul lo ale.

1 >>> i m p o r t l o a l e

2 >>> l o a l e . s e t l o a l e ( l o a l e . LC_ALL, ' i d _ I D . UTF − 8


' )

3 ' i d _ I D . UTF8 '

4 >>> l o a l e . f o r m a t ( ' % . 2 f ' , 1 0 0 0 0 , T r u e )

5 ' 1 0 . 0 0 0 , 0 0 '

Jika p eahannya tidak ingin ditampilkan:

1 >>> l o a l e . f o r m a t ( ' % . 0 f ' , 1 0 0 0 0 , T r u e )

2 ' 1 0 . 0 0 0 '

Namun jika saat setlo ale Anda menjumpai p esan kesalahan sep erti ini:

37

BAB 6. FUNGSI 38

1 T r a e b a k ( m o s t r e e n t a l l l a s t ) :

2 F i l e "< s t d i n > " , l i n e 1 , i n <m o d u l e >

3 F i l e " / u s r / l i b / p y t h o n 2 . 6 / l o a l e . p y " , l i n e 5 1
3 , i n

s e t l o a l e

4 r e t u r n _ s e t l o a l e ( a t e g o r y , l o a l e )

5 l o a l e . E r r o r : u n s u p p o r t e d l o a l e s e t t i n g

Berarti Anda p erlu memasang format id_ID.UTF-8 pada sistem. Keluarlah

dari mo dus interaktif dan jalankan:

1 $ s u d o l o a l e − g e n i d _ I D . UTF − 8

2 G e n e r a t i n g l o a l e s . . .

3 i d _ I D . UTF − 8 . . . u p − t o − d a t e

4 G e n e r a t i o n o m p l e t e .

Kalau sudah obalah kembali ontoh p emisah 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 p eahan yang akan ditampilkan, default-nya adalah 2 digit

p eahan.

Karena uang() adalah fungsi umum yang akan banyak digunakan di b erbagai

program, ada baiknya kita simpan sebagai mo dul b ernama uang.py.

Listing 6.1: uang.py

1 i m p o r t l o a l e

2 l o a l e . s e t l o a l e ( l o a l e . LC_ALL, ' i d _ I D . UTF − 8 ' )

5 d e f u a n g ( n i l a i , p e a h a n = 2 ) :

6 r e t u r n l o a l e . f o r m a t ( ' %%.% d f ' % p e a h a n , n i l a i ,


T r u e )

9 i f __name__ == ' __main__ ' :

10 p r i n t u a n g ( 1 0 0 0 0 )
11 p r i n t u a n g ( 1 0 0 0 0 . 3 )

12 p r i n t u a n g ( 1 0 0 0 0 . 5 , 0 )

Cobalah.

1 $ p y t h o n u a n g . p y

2 1 0 . 0 0 0 , 0 0

3 1 0 . 0 0 0 , 3 0

4 1 0 . 0 0 0

Perhatikan bagian

'%%.%df' % peahan

BAB 6. FUNGSI 39

Itu adalah formatting sep erti yang dijelaskan di halaman 17.

Butuh fungsi yang lebih erdas ? Misalkan dengan sifat sep erti ini:

1. Jika p eahan tidak disebutkan

maka mo dus otomatis b erlaku. Otomatis

yang dimaksud adalah bila tip e data

variab el nilai adalah bilangan bulat

(integer) maka p eahan tidak ditampilkan. Selain kondisi itu b erarti di-

anggap bilangan p eahan (#oat) maka p eahan ditampilkan sebanyak 2

digit.

2. Selain kondisi di atas maka nilai uang ditampilkan sep erti biasa sesuai

jumlah p eahan yang disebutkan.

Masih di uang.py.

Listing 6.2: uang.py

1 i m p o r t l o a l e

2 l o a l e . s e t l o a l e ( l o a l e . LC_ALL, ' i d _ I D . UTF − 8 ' )

5 d e f u a n g ( n i l a i , p e a h a n=N o n e ) :

6 i f p e a h a n i s N o n e :

7 i f t y p e ( n i l a i ) == t y p e ( 0 ) :
8 p e a h a n = 0

9 e l s e :

10 p e a h a n = 2

11 r e t u r n l o a l e . f o r m a t ( ' %%.% d f ' % p e a h a n , n i l a i ,


T r u e )

12

13

14 i f __name__ == ' __main__ ' :

15 p r i n t u a n g ( 1 0 0 0 0 )

16 p r i n t u a n g ( 1 0 0 0 0 . 3 )

17 p r i n t u a n g ( 1 0 0 0 0 . 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 memiliki

dua masukan dan juga memiliki nilai default pada salah satu masukannya. Juga

ada ob jek hampa bawaan Python b ernama None.

Rasanya fungsi uang kurang lengkap bila tidak disertai dengan mata uangnya.

Kita akan jalankan skenario b erikut ini:

1. Fungsi uang dib eri satu masukan baru yaitu variab el tanda untuk memb eri

kesempatan programmer memasukkan mata uang sep erti Rp, $, dst.

BAB 6. FUNGSI 40

2. Bila variab el tanda tidak diisi maka mata uang diambil dari sistem, meng-

gunakan mo dule lo ale.

Listing 6.3: uang.py

1 i m p o r t l o a l e

2 l o a l e . s e t l o a l e ( l o a l e . LC_ALL, ' i d _ I D . UTF − 8 ' )

3 f r o m t y p e s i m p o r t I n t T y p e
4

6 d e f r i b u ( n i l a i , p e a h a n=N o n e ) :

7 i f p e a h a n i s N o n e :

8 i f t y p e ( n i l a i ) == I n t T y p e :

9 p e a h a n = 0

10 e l s e :

11 p e a h a n = 2

12 r e t u r n l o a l e . f o r m a t ( ' %%.% d f ' % p e a h a n , n i l a i ,


T r u e )

13

14 d e f u a n g ( n i l a i , p e a h a n=N o n e , t a n d a=N o n e ) :

15 i f t a n d a i s N o n e :

16 t a n d a = l o a l e . l o a l e o n v ( ) [ ' u r r e n y _ s y m b o l '

17 r e t u r n '%s%s ' % ( t a n d a , r i b u ( n i l a i , p e a h a n ) )

18

19

20 i f __name__ == ' __main__ ' :

21 p r i n t r i b u ( 1 0 0 0 0 )

22 p r i n t r i b u ( 1 0 0 0 0 . 3 )

23 p r i n t r i b u ( 1 0 0 0 0 . 5 , 4 )

24 p r i n t u a n g ( 1 0 0 0 0 . 7 )

25 p r i n t u a n g ( 1 0 0 0 0 . 7 , 2 , ' $ ' )

26 p r i n t u a n g ( 1 0 0 0 0 . 7 , t a n d a= ' $ ' )

Perhatikan fungsi tambahan ribu(). Fungsi ini seb enarnya salinan dari fungsi

uang() seb elumnya. Mengapa tidak langsung mengubah fungsi uang() sep erti

biasanya ?

Tujuannya adalah kita tidak ingin mengganggu algoritma yang sudah b er-

jalan baik itu. Sehingga bila ada kekeliruan pada algoritma di uang(), area
p enarian kesalahan bisa diminimalisir.

Perhatikan juga baris terakhir,

print uang(10000.7, tanda='$')

dimana kita melewatkan variab el kedua, yaitu p eahan pada fungsi uang(),

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

Python tidak memp ermasalahkan variab el p eahan dilewatkan, karena variab el

ini telah dib eri nilai default yaitu None.

BAB 6. FUNGSI 41

Karena mo dul uang ini merupakan mo dul umum yang bisa digunakan oleh

banyak aplikasi, maka letakkanlah uang.py di /usr/lo al/lib/python2.6/dist-

pakages agar bisa digunakan oleh program lainnya. Lalu uji keb eradaannya di

mo dus interaktif.

1 >>> f r o m u a n g i m p o r t u a n g

2 >>> u a n g ( 1 0 0 0 0 )

3 ' 1 0 . 0 0 0 '

Bab 7

Database

Database atau p enyimpan data biasa digunakan untuk aplikasi bisnis sep erti

kasir (p oint of sales), aounting, payroll, dsb.

Pasanglah

1 $ s u d o a p t − g e t i n s t a l l p o s t g r e s q l

Sup eruser di PostgreSQL adalah p ostgres. Nama ini terantum di sistem

Linux maupun di sistem PostgreSQL itu sendiri. Pasa p emasangan user p ost-

gres tidak memiliki password. Jadi gunakanlah sudo:

1 $ s u d o s u

Masukkan password user yang Anda gunakan ketika login p ertama kali. Kini

Anda telah menjadi ro ot, dan mulailah sebagai user p ostgres:

1 # s u − p o s t g r e s

Kini Anda sudah menjadi user p ostgres. Menurut ketentuan default, bila

user Linux dan user PostgreSQL sama maka tidak p erlu password untuk login
ke PostgreSQL server. Sekarang mulailah membuat user database:

1 $ r e a t e u s e r − P i l h a m

2 E n t e r p a s s w o r d f o r n e w r o l e :

3 E n t e r i t a g a i n :

4 S h a l l t h e n e w r o l e b e a s u p e r u s e r ? ( y / n ) n

5 S h a l l t h e n e w r o l e b e a l l o w e d t o r e a t e d a t a b a s e
s ? ( y / n )

6 S h a l l t h e n e w r o l e b e a l l o w e d t o r e a t e m o r e n e w r o
l e s ? (

y / n ) n

Isilah password dengan 1234. Saat diketik password tidak akan ditampilkan.

Selebihnya user ilham ini tidak dizinkan sebagai sup eruser, tidak diizinkan mem-

buat database, dan tidak diizinkan membuat user.

Untuk menghapusnya:

1 $ d r o p u s e r i l h a m

42

BAB 7. DATABASE 43

Selanjutnya membuat database:

1 $ r e a t e d b − O i l h a m t o t a l i n d o

Ini artinya kita membuat database b ernama totalindo yang dimiliki oleh user

ilham. Untuk menghapusnya:

1 $ d r o p d b t o t a l i n d o

Untuk melihat daftar database bisa menggunakan psql:

1 $ p s q l

2 p s q l ( 8 . 4 . 4 )

3 T y p e " h e l p " f o r h e l p .

5 p o s t g r e s =# \ l

6 L i s t o f d a t a b a s e s
7 Name | O w n e r | E n o d i n g | C o l l a t i o n |

8 −−−−−−−−−−− + −−−−−−−−−− + −−−−−−−−−− + −−−−−−−−−−−−− +

9 p o s t g r e s | p o s t g r e s | UTF8 | i d _ I D . UTF − 8 |

10 t e m p l a t e 0 | p o s t g r e s | UTF8 | i d _ I D . UTF − 8 |

11 t e m p l a t e 1 | p o s t g r e s | UTF8 | i d _ I D . UTF − 8 |

12 t o t a l i n d o | i l h a m | UTF8 | i d _ I D . UTF − 8 |

13 ( 4 r o w s )

14

15 p o s t g r e s =#

Untuk keluar gunakan \q atau tekan Ctrl-D:

1 p o s t g r e s =# \ q

2 $ w h o a m i

3 p o s t g r e s

Anda masih sebagai user p ostgres, keluarlah dengan p erintah logout atau

tekan Ctrl-D:

1 $ l o g o u t

2 # w h o a m i

3 r o o t

Kini Anda sebagai ro ot, keluarlah lagi dengan p erintah logout agar kembali

sebagai user biasa:

1 # l o g o u t

2 $ w h o a m i

3 s u g i a n a

Sekarang kita login ke database totalindo sebagai user ilham:

1 $ p s q l − U i l h a m t o t a l i n d o − h l o a l h o s t

2 P a s s w o r d f o r u s e r i l h a m :

3 p s q l ( 8 . 4 . 4 )

4 S S L o n n e t i o n ( i p h e r : DHE − RSA − A E S 2 5 6 − SHA , b i t s :


2 5 6 )

BAB 7. DATABASE 44
5 T y p e " h e l p " f o r h e l p .

7 t o t a l i n d o =>

Perhatikan di sini kita menggunakan option yang lengkap di psql, padahal

pada saat sebagai user p ostgres kita ukup mengetikkan psql sa ja. Apa b edanya

psql sa ja tanpa option apapun b erarti:

1. Usernya sesuai user Linux.

2. Nama database sesuai nama user.

3. Koneksi melalui jalur UNIX so ket, tidak melalui network.

7.1 Tab el

Panduan membuat tab el:

1. Harus memiliki PRIMARY KEY, yaitu sebuah / b eb erapa #eld yang men-

jadi identitas reord.

2. Sebisa mungkin setiap #eld memiliki DEFAULT value dimana kalau tidak

diisi maka nilai default digunakan.

3. Sebisa mungkin setiap #eld NOT NULL yang b erarti harus diisi.

Mulailah membuat tab el p egawai di psql menggunakan p erintah CREATE TA-

BLE.

1 t o t a l i n d o => CREATE TABLE p e g a w a i (

2 t o t a l i n d o ( > i d s e r i a l NOT NULL ,

3 t o t a l i n d o ( > nama v a r h a r ( 3 0 ) NOT NULL ,

4 t o t a l i n d o ( > t g l _ l a h i r DATE NOT NULL ,

5 t o t a l i n d o ( > PRIMARY KEY( i d )

6 t o t a l i n d o ( > ) ;

7 NOTICE : CREATE TABLE w i l l r e a t e i m p l i i t s e q u e n e "

p e g a w a i _ i d _ s e q " f o r s e r i a l o l u m n " p e g a w a i . i d "

8 NOTICE : CREATE TABLE / PRIMARY KEY w i l l r e a t e i m p l i i t

i n d e x " p e g a w a i _ p k e y " f o r t a b l e " p e g a w a i " CREATE


TABLE
9 t o t a l i n d o =>

Perhatikan prompt

totalindo=>

dan b edakan dengan prompt

totalindo(>

BAB 7. DATABASE 45

yang b ermakna prompt itu kelanjutan dari prompt seb elumnya. Penulisan

CREATE TABLE pegawai(

yang diikuti dengan p enekanan tomb ol Enter membuat prompt memb eritahukan

Anda bahwa kurung buka masih aktif dan membutuhkan kurung tutup seb elum

diakhiri dengan titik koma.

Perintah dalam SQL (strutured query language) seb enarnya tidak memp er-

hatikan huruf b esar / keil (inasesensitive). Anda b oleh menuliskan

CREATE TABLE

menjadi

reate table

Sekarang kita lihat daftar tab el yang ada di database totalindo ini menggunakan

p erintah \dt.

1 t o t a l i n d o => \ d t

2 L i s t o f r e l a t i o n s

3 S h e m a | Name | T y p e | O w n e r

4 −−−−−−−− + −−−−−−−−− + −−−−−−− + −−−−−−−

5 p u b l i | p e g a w a i | t a b l e | i l h a m

6 ( 1 r o w )

8 t o t a l i n d o =>

Perintah yang diawali bakslash ( \ ) adalah p erintah program psql,

bukan jenis query sep erti CREATE TABLE, SELECT, dst.

Lalu lihat struktur tab elnya menggunakan p erintah \d diikuti nama tab el.

1 t o t a l i n d o => \ d p e g a w a i
2 T a b l e " p u b l i . p e g a w a i "

3 C o l u m n | T y p e |

M o d i f i e r s

4 −−−−−−−−−−− + −−−−−−−−−−−−−−−−−−−−−−− + −−−−−−−−−−−−−−−−−−−

5 i d | i n t e g e r | n o t n u l l d e f a u l t

n e x t v a l ( ' p e g a w a i _ i d _ s e q ' : : r e g l a s s )

6 nama | h a r a t e r v a r y i n g ( 3 0 ) | n o t n u l l

7 t g l _ l a h i r | d a t e | n o t n u l l

8 I n d e x e s :

9 " p e g a w a i _ p k e y " PRIMARY KEY, b t r e e ( i d )

10

11 t o t a l i n d o =>

BAB 7. DATABASE 46

Perhatikan kolom / #eld id yang b ertip e integer, padahal seb elumnya kita

tulis b ertip e serial. Mengapa demikian ?

Tip e serial hanyalah ara epat untuk membuat sebuah #eld menjadi au-

toinrement (nomor urut). Jadi p ende#nisian suatu #eld menjadi serial akan

membuat:

1. Tip enya menjadi integer (bilangan bulat).

2. Memiliki default value nomor urut b erikutnya. Nomor urut b erikutnya

tersimpan dalam sebuah sequene.

Apa itu sequene ?

7.1.1 Sequene

Sequene mirip tab el, tepatnya tab el satu reord yang b erisi data untuk ke-

butuhan nomor urut. Pada ontoh di atas sequene b ernama p egawai_id_seq

otomatis terb entuk saat #eld id pada tab el p egawai dide#nisikan sebagai seri-

al. Data pada sequene bisa dilihat sebagaimana tab el menggunakan p erintah

SELECT.

1 t o t a l i n d o => SELECT * FROM p e g a w a i _ i d _ s e q ;


2 s e q u e n e _ n a m e | l a s t _ v a l u e | i s _ a l l e d |

3 −−−−−−−−−−−−−−−− + −−−−−−−−−−−− + −−−−−−−−−−− +

4 p e g a w a i _ i d _ s e q | 1 | f |

6 ( 1 r o w )

Sekarang kita lihat isi tab el p egawai.

1 t o t a l i n d o => SELECT * FROM p e g a w a i ;

2 i d | nama | t g l _ l a h i r

3 −−−− + −−−−−− + −−−−−−−−−−−

4 ( 0 r o w s )

Tampak tab el p egawai masih kosong, mari tambah datanya.

1 t o t a l i n d o => INSERT INTO p e g a w a i ( nama , t g l _ l a h i r )

2 t o t a l i n d o − > VALUES ( ' Bummi D w i P u t e r a ' , ' 1 9 8 5 − 8 − 1 7


' ) ;

3 INSERT 0 1

Perhatikan p erintah di baris p ertama tidak diakhiri dengan titik koma yang

b erarti p erintah b elum b erakhir dan dilanjutkan di baris b erikutnya.


Perhatikan

juga prompt pada baris kedua menjadi

totalindo->

yakni menggunakan karakter minus ( - ) yang b erarti baris ini merupakan ke-

lanjutan dari baris seb elumnya. Jika Anda salah dalam menuliskan p erintah di

baris p ertama dan terlanjur menekan Enter, akhiri sa ja dengan titik koma di

baris kedua. Kemudian mulai lagi dari awal. Berikut ini ontoh kesalahan yang

bisa sa ja terjadi.

BAB 7. DATABASE 47

1 t o t a l i n d o => INSERT INT p e g a w a i ( nama , t g l _ l a h i r )

2 t o t a l i n d o − > ;

3 ERROR : s y n t a x e r r o r a t o r n e a r " INT "

4 LINE 1 : INSERT INT p e g a w a i ( nama , t g l _ l a h i r )

5 ^
6 t o t a l i n d o =>

Untuk mengulangi p erintah seb elumnya tekan tomb ol panah atas.

Kembali ke tab el p egawai yang sudah kita isi dengan p erintah INSERT.

Sekarang lihat hasilnya.

1 t o t a l i n d o => SELECT * FROM p e g a w a i ;

2 i d | nama | t g l _ l a h i r

3 −−−− + −−−−−−−−−−−−−−−−−− + −−−−−−−−−−−−

4 1 | Bummi D w i P u t e r a | 1 9 8 5 − 0 8 − 1 7

5 ( 1 r o w )

Perhatikan saat INSERT tadi #eld id tidak disertakan, namun p erintah SE-

LECT memp erlihatkan bahwa #eld id terisi dengan angka 1. Inilah yang dise-

but dengan #eld autoinrement. Lalu apa yang terjadi dengan sequene p e-

gawai_id_seq ?

1 t o t a l i n d o => SELECT * FROM p e g a w a i _ i d _ s e q ;

2 s e q u e n e _ n a m e | l a s t _ v a l u e | i s _ a l l e d

3 −−−−−−−−−−−−−−−− + −−−−−−−−−−−− + −−−−−−−−−−−

4 p e g a w a i _ i d _ s e q | 1 | t

6 ( 1 r o w )

Bandingkan dengan nilai-nilai p egawai_id_seq pada SELECT seb elum IN-

SERT. Yang p erlu dip erhatikan adalah #eld is_alled dimana seb elumnya f

(False) kini menjadi t (True). Ini artinya sequene sudah digunakan agar

nextval() b erikutnya tahu bahwa nilai b erikutnya menghasilkan last_value + 1

= 2.

Sekarang lanjut dengan p egawai b erikutnya.

1 t o t a l i n d o => INSERT INTO p e g a w a i ( nama , t g l _ l a h i r )

2 t o t a l i n d o − > VALUES ( ' A r i e f S e t i a d i ' , ' 1 9 7 2 − 5 − 2


' ) ;

3 INSERT 0 1

4 t o t a l i n d o => SELECT * FROM p e g a w a i ;


5 i d | nama | t g l _ l a h i r

6 −−−− + −−−−−−−−−−−−−−−−−− + −−−−−−−−−−−−

7 1 | Bummi D w i P u t e r a | 1 9 8 5 − 0 8 − 1 7

8 2 | A r i e f S e t i a d i | 1 9 7 2 − 0 5 − 0 2

9 ( 2 r o w s )

Perhatikan kembali #eld id yang terisi dengan angka 2, dan lihat juga p e-

gawai_id_seq.

1 t o t a l i n d o => SELECT * FROM p e g a w a i _ i d _ s e q ;

BAB 7. DATABASE 48

2 s e q u e n e _ n a m e | l a s t _ v a l u e | i s _ a l l e d |

3 −−−−−−−−−−−−−−−− + −−−−−−−−−−−− + −−−−−−−−−−− +

4 p e g a w a i _ i d _ s e q | 2 | t | 1

6 ( 1 r o w )

Kini last_value menjadi 2, sehingga nextval() b erikutnya last_value + 1 =

3. Mudah-mudahan bisa dipahami.

Mengenai #eld tgl_lahir, b olehkah diisi menggunakan format Indonesia yaitu

dengan urutan tanggal-bulan-tahun ?

Jawabannya b oleh, hanya ada yang p erlu dip erhatikan pada kon#gurasi

PostgreSQL, yaitu pada #le

/et/postgresql/8.4/main/postgresql.onf

Coba lihat dengan text editor.

1 $ s u d o n a n o / e t / p o s t g r e s q l / 8 . 4 / m a i n / p o s t g r e
s q l . o n f

Carilah kata datestyle.

datestyle = 'iso, dmy'

Jika sudah tampak dmy sep erti 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 Post-
greSQL.

1 $ s u d o / e t / i n i t . d / p o s t g r e s q l − 8 . 4 r e s t a r t

Perlu Anda ketahui, format dmy otomatis Anda dapatkan bila saat instalasi

Ubuntu menggunakan bahasa Indonesia.

Cobalah untuk menambah data p egawai lagi dengan tanggal lahir b erformat

tanggal-bulan-tahun.

1 t o t a l i n d o => INSERT INTO p e g a w a i ( nama , t g l _ l a h i r )

2 t o t a l i n d o − > VALUES ( ' C e e p Z a h r u d i n ' , ' 1 − 6 − 1 9 7 2 '


) ;

3 INSERT 0 1

4 t o t a l i n d o => SELECT * FROM p e g a w a i ;

5 i d | nama | t g l _ l a h i r

6 −−−− + −−−−−−−−−−−−−−−−−− + −−−−−−−−−−−−

7 1 | Bummi D w i P u t e r a | 1 9 8 5 − 0 8 − 1 7

8 2 | A r i e f S e t i a d i | 1 9 7 2 − 0 5 − 0 2

9 3 | C e e p Z a h r u d i n | 1 9 7 2 − 0 6 − 0 1

10 ( 3 r o w s )

Agar tampil urut sesuai ab jad gunakan ORDER BY.

BAB 7. DATABASE 49

1 t o t a l i n d o => SELECT * FROM p e g a w a i ORDER BY nama ;

2 i d | nama | t g l _ l a h i r

3 −−−− + −−−−−−−−−−−−−−−−−− + −−−−−−−−−−−−

4 2 | A r i e f S e t i a d i | 1 9 7 2 − 0 5 − 0 2

5 1 | Bummi D w i P u t e r a | 1 9 8 5 − 0 8 − 1 7

6 3 | C e e p Z a h r u d i n | 1 9 7 2 − 0 6 − 0 1

7 ( 3 r o w s )

Gunakan WHERE untuk mendapatkan reord tertentu.

1 t o t a l i n d o => SELECT * FROM p e g a w a i WHERE i d = 1 ;

2 i d | nama | t g l _ l a h i r

3 −−−− + −−−−−−−−−−−−−−−−−− + −−−−−−−−−−−−


4 1 | Bummi D w i P u t e r a | 1 9 8 5 − 0 8 − 1 7

5 ( 1 r o w )

Tampilkan p egawai yang lahir di tahun 1972 dan diurutkan mulai yang ter-

tua.

1 t o t a l i n d o => SELECT * FROM p e g a w a i

2 t o t a l i n d o − > WHERE d a t e _ p a r t ( ' y e a r ' , t g l _ l a h i r )


= 1 9 7 2

3 t o t a l i n d o − > ORDER BY t g l _ l a h i r ;

4 i d | nama | t g l _ l a h i r

5 −−−− + −−−−−−−−−−−−−−−− + −−−−−−−−−−−−

6 2 | A r i e f S e t i a d i | 1 9 7 2 − 0 5 − 0 2

7 3 | C e e p Z a h r u d i n | 1 9 7 2 − 0 6 − 0 1

8 ( 2 r o w s )

Gunakan DESC pada ORDER BY jika ingin diurut mulai yang termuda.

Tekan tomb ol panah atas untuk mengulang p erintah seb elumnya dan tam-

bahkan DESC.

1 t o t a l i n d o => SELECT * FROM p e g a w a i

2 WHERE d a t e _ p a r t ( ' y e a r ' , t g l _ l a h i r ) = 1 9 7 2

3 ORDER BY t g l _ l a h i r DESC ;

4 i d | nama | t g l _ l a h i r

5 −−−− + −−−−−−−−−−−−−−−− + −−−−−−−−−−−−

6 3 | C e e p Z a h r u d i n | 1 9 7 2 − 0 6 − 0 1

7 2 | A r i e f S e t i a d i | 1 9 7 2 − 0 5 − 0 2

8 ( 2 r o w s )

7.1.2 Mengubah Struktur

Pegawai seb elumnya tampak sebagai laki-laki, terlihat dari namanya. Cobalah

untuk memasukkan nama p erempuan.

1 t o t a l i n d o => INSERT INTO p e g a w a i ( nama , t g l _ l a h i r )

2 t o t a l i n d o − > VALUES ( ' N i t a P a n d r i a ' , ' 1 9 − 9 − 1 9 7 6


' ) ;
3 INSERT 0 1

BAB 7. DATABASE 50

Manusia bisa jadi memahami mana nama laki-laki dan mana p erempuan.

Namun komputer mengalami kesulitan bila mengandalkan nama. Oleh karena

itu kita p erlu menambah #eld pria yang b ertip e logika (b o olean). Kita membu-

tuhkan p erintah ALTER TABLE di sini.

1 t o t a l i n d o => ALTER TABLE p e g a w a i ADD p r i a b o o l e a n NOT NULL

DEFAULT t r u e ;

2 ALTER TABLE

Sep erti dijelaskan pada sesi Python seb elumnya, b o olean hanya bisa diisi

dengan dua nilai, bisa True atau False. Kita menamakan #eld ini dengan pria

dengan b egitu nilai default-nya adalah True. Jika #eld pria False b erarti p
egawai

tersebut p erempuan. Sekarang kita lihat isi tab el p egawai setelah p enambahan

#eld di atas.

1 t o t a l i n d o => SELECT * FROM p e g a w a i ORDER BY nama ;

2 i d | nama | t g l _ l a h i r | p r i a

3 −−−− + −−−−−−−−−−−−−−−−−− + −−−−−−−−−−−− + −−−−−−

4 2 | A r i e f S e t i a d i | 1 9 7 2 − 0 5 − 0 2 | t

5 1 | Bummi D w i P u t e r a | 1 9 8 5 − 0 8 − 1 7 | t

6 3 | C e e p Z a h r u d i n | 1 9 7 2 − 0 6 − 0 1 | t

7 4 | N i t a P a n d r i a | 1 9 7 6 − 0 9 − 1 9 | t

8 ( 4 r o w s )

Perhatikan #eld pria, tampak semua tertulis t yang artinya True. Apa data

tab el ini sudah b enar? Jelas b elum.

Nita Pandria adalah p erempuan, sedangkan tab el p egawai menyatakannya

laki-laki. Kita p erlu mengubahnya dengan p erintah UPDATE.

1 t o t a l i n d o => UPDATE p e g a w a i SET p r i a = F a l s e WHERE i d = 4 ;

2 UPDATE 1
3 t o t a l i n d o => SELECT * FROM p e g a w a i ORDER BY nama ;

4 i d | nama | t g l _ l a h i r | p r i a

5 −−−− + −−−−−−−−−−−−−−−−−− + −−−−−−−−−−−− + −−−−−−

6 2 | A r i e f S e t i a d i | 1 9 7 2 − 0 5 − 0 2 | t

7 1 | Bummi D w i P u t e r a | 1 9 8 5 − 0 8 − 1 7 | t

8 3 | C e e p Z a h r u d i n | 1 9 7 2 − 0 6 − 0 1 | t

9 4 | N i t a P a n d r i a | 1 9 7 6 − 0 9 − 1 9 | f

10 ( 4 r o w s )

Kita sudah membuat reord dengan INSERT, menampilkannya dengan SE-

LECT, dan mengubahnya dengan UPDATE. Kini kita oba untuk menghapus-

nya dengan DELETE FROM yaitu p egawai dengan id 2.

1 t o t a l i n d o => DELETE FROM p e g a w a i WHERE i d = 2 ;

2 DELETE 1

3 t o t a l i n d o => SELECT * FROM p e g a w a i ORDER BY nama ;

4 i d | nama | t g l _ l a h i r | p r i a

5 −−−− + −−−−−−−−−−−−−−−−−− + −−−−−−−−−−−− + −−−−−−

BAB 7. DATABASE 51

6 1 | Bummi D w i P u t e r a | 1 9 8 5 − 0 8 − 1 7 | t

7 3 | C e e p Z a h r u d i n | 1 9 7 2 − 0 6 − 0 1 | t

8 4 | N i t a P a n d r i a | 1 9 7 6 − 0 9 − 1 9 | f

9 ( 3 r o w s )

Jika Anda kurang suka dengan #eld pria yang b ertip e b o olean bisa dihapus

dengan p erintah ALTER TABLE.

1 t o t a l i n d o => ALTER TABLE p e g a w a i DROP p r i a ;

2 ALTER TABLE

Anda masih kurang b erkenan dengan struktur tab el p egawai ? Silahkan

hapus dengan p erintah DROP TABLE.

1 t o t a l i n d o => DROP TABLE p e g a w a i ;

2 DROP TABLE

SELECT, INSERT, UPDATE, dan DELETE adalah hal yang terkait den-
gan reord / baris data sehingga disebut sebagai Data Manipulation Language

(DML). Sedangkan CREATE, ALTER, dan DROP terkait dengan struktur tab el

sehingga disebut sebagai Data De#nition Language (DDL).

7.2 View

Dibutuhkan sebuah lap oran yang menampilkan data p egawai b eserta 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 n d o => SELECT i d , nama , now ( ) − t g l _ l a h i r FROM

p e g a w a i ORDER BY t g l _ l a h i r ;

2 i d | nama | ? o l u m n ?

3 −−−− + −−−−−−−−−−−−−−−−−− + −−−−−−−−−−−−−−−−−−−−−−−−−−−−

4 2 | A r i e f S e t i a d i | 1 3 9 5 7 d a y s 1 1 : 2 1 : 5 4 . 0 8 3 0 2 2

5 3 | C e e p Z a h r u d i n | 1 3 9 2 7 d a y s 1 1 : 2 1 : 5 4 . 0 8 3 0 2 2

6 4 | N i t a P a n d r i a | 1 2 3 5 6 d a y s 1 1 : 2 1 : 5 4 . 0 8 3 0 2 2

7 1 | Bummi D w i P u t e r a | 9 1 0 2 d a y s 1 1 : 2 1 : 5 4 . 0 8 3 0 2 2

8 ( 4 r o w s )

Kolom ketiga b erisi usia, tapi PostgreSQL tidak tahu harus dinamakan apa,

sehingga jadilah b ernama ?olumn?. Ada baiknya kita b erikan nama #usia#.

1 t o t a l i n d o => SELECT i d , nama , now ( ) − t g l _ l a h i r AS u s i a

2 t o t a l i n d o − > FROM p e g a w a i ORDER BY t g l _ l a h i r ;

3 i d | nama | u s i a

4 −−−− + −−−−−−−−−−−−−−−−−− + −−−−−−−−−−−−−−−−−−−−−−−−−−−−

5 2 | A r i e f S e t i a d i | 1 3 9 5 7 d a y s 1 1 : 2 8 : 3 4 . 0 0 1 1 4 2

6 3 | C e e p Z a h r u d i n | 1 3 9 2 7 d a y s 1 1 : 2 8 : 3 4 . 0 0 1 1 4 2

BAB 7. DATABASE 52

7 4 | N i t a P a n d r i a | 1 2 3 5 6 d a y s 1 1 : 2 8 : 3 4 . 0 0 1 1 4 2

8 1 | Bummi D w i P u t e r a | 9 1 0 2 d a y s 1 1 : 2 8 : 3 4 . 0 0 1 1 4 2

9 ( 4 r o w s )
Satuan usia menggunakan hari tentu sa ja kurang nyaman dibaa. Sebaiknya

kita ganti rumusnya:

usia = tahun sekarang - tahun kelahiran

sehingga query-nya menjadi:

1 t o t a l i n d o => SELECT i d , nama ,

2 t o t a l i n d o − > e x t r a t ( y e a r f r o m now ( ) ) − e x t r a t ( y
e a r f r o m

t g l _ l a h i r ) AS u s i a

3 t o t a l i n d o − > FROM p e g a w a i ORDER BY t g l _ l a h i r ;

4 i d | nama | u s i a

5 −−−− + −−−−−−−−−−−−−−−−−− + −−−−−−

6 2 | A r i e f S e t i a d i | 3 8

7 3 | C e e p Z a h r u d i n | 3 8

8 4 | N i t a P a n d r i a | 3 4

9 1 | Bummi D w i P u t e r a | 2 5

10 ( 4 r o w s )

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

1 t o t a l i n d o => CREATE VIEW v _ p e g a w a i AS SELECT i d , nama ,

2 e x t r a t ( y e a r f r o m now ( ) ) − e x t r a t ( y e a r f r o m t g l _
l a h i r )

AS u s i a

3 FROM p e g a w a i ORDER BY t g l _ l a h i r ;

4 CREATE VIEW

Selanjutnya kita tampilkan VIEW tadi layaknya sebuah tab el.

1 t o t a l i n d o => SELECT * FROM v _ p e g a w a i ;

2 i d | nama | u s i a

3 −−−− + −−−−−−−−−−−−−−−−−− + −−−−−−

4 2 | A r i e f S e t i a d i | 3 8

5 3 | C e e p Z a h r u d i n | 3 8

6 4 | N i t a P a n d r i a | 3 4

7 1 | Bummi D w i P u t e r a | 2 5
8 ( 4 r o w s )

Penamaan VIEW tidak harus b erawalan #v_#. Penggunaan awalan itu un-

tuk memb edakan VIEW dengan tab el seb enarnya. Meski ia dapat di-SELECT

namun VIEW tidak dapat di-INSERT b egitu sa ja.

Walau v_p egawai sudah mengandung ORDER BY, kita masih bisa meng-

gunakan ORDER BY saat SELECT, misalnya diurut b erdasar nama.

1 t o t a l i n d o => SELECT * FROM v _ p e g a w a i ORDER BY nama ;

2 i d | nama | u s i a

BAB 7. DATABASE 53

3 −−−− + −−−−−−−−−−−−−−−−−− + −−−−−−

4 2 | A r i e f S e t i a d i | 3 8

5 1 | Bummi D w i P u t e r a | 2 5

6 3 | C e e p Z a h r u d i n | 3 8

7 4 | N i t a P a n d r i a | 3 4

8 ( 4 r o w s )

7.3 Bakup dan Restore

Jika tab el p egawai b enar-b enar Anda hapus, sebaiknya mulailah membuatnya

lagi dan mengisinya. Selain langsung melalui psql mo dus interaktif, Anda bisa

membuatnya dulu dalam sebuah #le p egawai.sql.

Listing 7.1: p egawai.sql

1 CREATE TABLE p e g a w a i (

2 i d s e r i a l ,

3 nama v a r h a r ( 3 0 ) NOT NULL ,

4 t g l _ l a h i r d a t e NOT NULL ,

5 p r i a b o o l e a n NOT NULL DEFAULT t r u e ,

6 PRIMARY KEY ( i d )

7 ) ;

9 INSERT INTO p e g a w a i ( nama , t g l _ l a h i r , p r i a ) VALUES ( ' Bummi


D w i P u t e r a ' , ' 1 9 8 5 − 8 − 1 7 ' , t r u e ) ;

10 INSERT INTO p e g a w a i ( nama , t g l _ l a h i r , p r i a ) VALUES ( ' A r


i e f

S e t i a d i ' , ' 1 9 7 2 − 5 − 2 ' , t r u e ) ;

11 INSERT INTO p e g a w a i ( nama , t g l _ l a h i r , p r i a ) VALUES ( ' C e


e p

Z a h r u d i n ' , ' 1 9 7 2 − 6 − 1 ' , t r u e ) ;

12 INSERT INTO p e g a w a i ( nama , t g l _ l a h i r , p r i a ) VALUES ( ' N i


t a

P a n d r i a ' , ' 1 9 7 6 − 9 − 1 9 ' , f a l s e ) ;

Lalu di psql jalankan #le tersebut:

1 t o t a l i n d o => \ i p e g a w a i . s q l

2 p s q l : s q l / p e g a w a i . s q l : 7 : NOTICE : CREATE TABLE w i l l r e


a t e

i m p l i i t s e q u e n e " p e g a w a i _ i d _ s e q " f o r s e r i a l o
l u m n

" p e g a w a i . i d "

3 p s q l : s q l / p e g a w a i . s q l : 7 : NOTICE : CREATE TABLE / PRIMARY

KEY w i l l r e a t e i m p l i i t i n d e x " p e g a w a i _ p k e y " f o r

t a b l e " p e g a w a i "

4 CREATE TABLE

5 INSERT 0 1

6 INSERT 0 1

7 INSERT 0 1

8 INSERT 0 1

Kalau Anda menemui kegagalan

BAB 7. DATABASE 54

No suh file or diretory

obalah menuliskan nama #le seara fullpath, misalnya.

1 t o t a l i n d o => \ i / h o m e / s u g i a n a / p e g a w a i . s q l

Sesuaikan dengan direktori dimana Anda menyimpan p egawai.sql. Mudah-

mudahan Anda mengerti maksudnya.


Kini bakup database totalindo dalam sebuah #le b erformat tar.

1 $ pg_dump − U i l h a m t o t a l i n d o − h l o a l h o s t − F t − f

t o t a l i n d o . s q l . t a r

Mulailah untuk latihan restore, yaitu dengan membuat database lain b erna-

ma totalindo_1 (lihat p embuatan database di awal bab ini). Lalu jalankan:

1 $ p g _ r e s t o r e − U i l h a m − h l o a l h o s t − d t o t a l i n d o _
1

t o t a l i n d o . s q l . t a r

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

1 $ pg_dump − U i l h a m t o t a l i n d o − h l o a l h o s t − f t o t a l i n
d o .

s q l

dan restore dengan psql:

1 $ p s q l − U i l h a m t o t a l i n d o _ 1 − h l o a l h o s t − f t o t a l
i n d o . s q l

Manfaat p enggunaan plaintext adalah Anda bisa mengubah #le totalin-

do.sql menggunakan teks editor biasa. Namun p enggunaan format ini terkadang

menimbulkan masalah saat restore bila ada #karakter aneh#, yaitu karakter den-

gan nomor ASCI I lebih b esar dari 126.

7.3.1 Eno ding

PostgreSQL versi terdahulu biasanya menggunakan SQL_ASCI I sebagai eno d-

ing harater. Anda bisa lihat dengan p erintah \l di psql.

1 $ p s q l − U i l h a m t e m p l a t e 1 − h l o a l h o s t

2 p s q l ( 8 . 4 . 4 )

3 T y p e " h e l p " f o r h e l p .

5 p o s t g r e s =# \ l

6 L i s t o f d a t a b a s e s

7 Name | O w n e r | E n o d i n g | C o l l a t i o n |

8 −−−−−−−−−−−−− + −−−−−−−−−− + −−−−−−−−−− + −−−−−−−−−−−−− +

9 p o s t g r e s | p o s t g r e s | UTF8 | i d _ I D . UTF − 8 |
10 t e m p l a t e 0 | p o s t g r e s | UTF8 | i d _ I D . UTF − 8 |

11 t e m p l a t e 1 | p o s t g r e s | UTF8 | i d _ I D . UTF − 8 |

12 t o t a l i n d o | i l h a m | UTF8 | i d _ I D . UTF − 8 |

13 t o t a l i n d o _ 1 | i l h a m | UTF8 | i d _ I D . UTF − 8 |

14 ( 5 r o w s )

BAB 7. DATABASE 55

Perhatikan di versi ini default eno ding adalah UTF8. Jika Anda membak-

up, p erhatikanlah eno ding ini. Misalkan menggunakan SQL_ASCI I, maka di

database yang baru pun Anda sebaiknya tetap menggunakan eno ding yang

sama. Sebagai latihan kembalilah ke konsole, lalu buat database totalindo_2

dengan eno ding SQL_ASCI I.

1 $ s u d o s u

2 # s u − p o s t g r e s

3 $ r e a t e d b − O i l h a m − T t e m p l a t e 0 − E s q l _ a s i i t o t a
l i n d o _ 2

Kembali ke psql dan lihat daftar database. Karena masih sebagai user p ost-

gres maka ukup ketik psql.

1 $ p s q l

2 p s q l ( 8 . 4 . 4 )

3 T y p e " h e l p " f o r h e l p .

5 p o s t g r e s =# \ l

6 L i s t o f d a t a b a s e s

7 Name | O w n e r | E n o d i n g | C o l l a t i o n |

8 −−−−−−−−−−−−− + −−−−−−−−−− + −−−−−−−−−−− + −−−−−−−−−−−−− +

9 p o s t g r e s | p o s t g r e s | UTF8 | i d _ I D . UTF − 8 |

10 t e m p l a t e 0 | p o s t g r e s | UTF8 | i d _ I D . UTF − 8 |

11 t e m p l a t e 1 | p o s t g r e s | UTF8 | i d _ I D . UTF − 8 |

12 t o t a l i n d o | i l h a m | UTF8 | i d _ I D . UTF − 8 |

13 t o t a l i n d o _ 1 | i l h a m | UTF8 | i d _ I D . UTF − 8 |
14 t o t a l i n d o _ 2 | i l h a m | SQL_ASCII | i d _ I D . UTF − 8 |

15 ( 6 r o w s )

Mengenai ara bakup dan restore lainnya sama sep erti seb elumnya.

Mengapa kita p erlu memp erhatikan eno ding ?

Bila database yang Anda bakup tidak mengandung karakter aneh (ASCI I

> 126) maka bisa dengan nyaman di-restore dari ke UTF8. Namun bila men-

gandung ASCI I > 126 maka restore ke UTF8 dari sumb er SQL_ASCI I bisa

menimbulkan masalah.

7.4 Fungsi

Sama sep erti Python, PostgreSQL juga mengenal fungsi. Contoh fungsi bawaan

(built-in) adalah now().

1 t o t a l i n d o => SELECT now ( ) ;

2 now

3 −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

4 2 0 1 0 − 0 8 − 2 4 1 6 : 0 6 : 5 8 . 6 7 8 0 5 6 + 0 7

5 ( 1 r o w )

Keunikan fungsi pada PostgreSQL adalah pada nama dan susunan masukan-

nya (input parameter). Perhatikan ontoh rata kanan b erikut ini.

BAB 7. DATABASE 56

1 t o t a l i n d o => SELECT l p a d ( ' A ' , 5 ) ;

2 l p a d

3 −−−−−−−

4 A

5 ( 1 r o w )

Fungsi lpad() b erguna untuk memb eri spasi di seb elah kiri. Jumlah spasi

ditambah jumlah karakter string 'A' tidak b oleh melebihi 5. Jadi pada ontoh

di atas jumlah spasi di seb elah kiri 'A' sebanyak 4 buah. Untuk membuktikan

jumlah karakternya adalah 5 maka kita gunakan fungsi length().

1 t o t a l i n d o => SELECT l e n g t h ( l p a d ( ' A ' , 5 ) ) ;


2 l e n g t h

3 −−−−−−−−

4 5

5 ( 1 r o w )

Sekarang kita membutuhkan awalan '0' pada sebuah nomor, misalnya '00001'.

Ini lazim kita temui pada b eb erapa lap oran. Fungsi apa yang akan digunakan.

Jawabannya masih menggunakan fungsi lpad().

1 t o t a l i n d o => SELECT l p a d ( ' 1 ' , 5 , ' 0 ' ) ;

2 l p a d

3 −−−−−−−

4 0 0 0 0 1

5 ( 1 r o w )

Di sinilah letak keunikan sebuah fungsi pada PostgreSQL. Fungsi lpad()

bisa menerima masukan dua buah atau tiga buah. Jika dua buah sa ja yang

digunakan maka lpad() akan mengawalinya dengan spasi. Namun jika tiga buah

masukan, maka lpad() akan mengawalinya sesuai dengan karakter pada masukan

ketiga. Cermatilah baik-baik.

Jadi bila kita ingin membuat b eb erapa fungsi dengan nama sama

maka harus

dib edakan dengan:

1. Jumlah masukannya.

2. Jika jumlah masukannya sama maka b edakan tip e data setiap masukan

tersebut.

7.4.1 PL/pgSQL

Salah satu yang membuat PostgreSQL b egitu mudah dikembangkan adalah

fungsi tersebut bisa ditulis dalam b erbagai bahasa. Dimana Anda bisa menulis

fungsi dalam bahasa pgSQL, Python, Perl, hingga Tl. Seara default bahasa

yang didukungnya adalah plpgsql. Namun Anda p erlu memasangnya terlebih

dahulu pada database yang dimaksud.

1 $ s u d o s u p o s t g r e s − " r e a t e l a n g p l p g s q l t o t a l i n
d o "

BAB 7. DATABASE 57

Selanjutnya siapkanlah dua konsole, yang p ertama untuk

1 $ p s q l − U i l h a m t o t a l i n d o − h l o a l h o s t

sedangkan yang kedua untuk text editor vi. Tentu sa ja Anda bisa menggu-

nakan gedit. Text editor akan kita gunakan untuk membuat #le-#le *.sql.

Sekarang kita akan membuat fungsi sederhana hello(), tanpa masukan apapun,

disimpan dalam #le hello.sql.

Listing 7.2: hello.sql

1 CREATE OR REPLACE FUNCTION h e l l o ( )

2 RETURNS t e x t

3 LANGUAGE p l p g s q l

4 AS $ $

5 BEGIN

6 RETURN ' H e l l o w o r l d . ' ;

7 END

8 $ $ ;

Setelah disimpan jalankan di psql tadi:

1 t o t a l i n d o => \ i h e l l o . s q l

2 CREATE FUNCTION

lalu obalah

1 t o t a l i n d o => SELECT h e l l o ( ) ;

2 h e l l o

3 −−−−−−−−−−−−−−

4 H e l l o w o r l d .

5 ( 1 r o w )

Transaksi Perbankan

Kita sudah punya tab el p egawai dimana setiap p egawai dianggap sebagai nasabah

pada p erusahaan ini. Saat mendapat ga ji saldonya b ertambah. Saat ambil ga ji

saldonya b erkurang. Saat kas b on (pinjam) saldonya juga b erkurang. Jadi saldo
juga bisa negatif yang b erarti p egawai tersebut punya hutang ke p erusahaan.

Pertama kita butuh #eld saldo pada tab el p egawai.

1 ALTER TABLE p e g a w a i ADD s a l d o f l o a t NOT NULL DEFAULT 0 ;

Kemudian untuk menatat aktivitas transaksi kita memerlukan tab el transak-

si b erikut ini.

Listing 7.3: transaksi.sql

1 CREATE TABLE t r a n s a k s i (

2 i d s e r i a l PRIMARY KEY ,

3 p i d i n t e g e r NOT NULL REFERENCES p e g a w a i ,

4 t g l t i m e s t a m p NOT NULL DEFAULT now ( ) ,

BAB 7. DATABASE 58

5 k e t v a r h a r ( 1 0 0 ) NOT NULL ,

6 n o m i n a l f l o a t NOT NULL ,

7 s a l d o f l o a t NOT NULL

8 ) ;

Misalkan ID p egawai 1 b ernama Bummi Dwi Putera mendapat ga ji untuk

bulan Nop emb er 2010 seb esar Rp 3.000.000,- maka query-nya adalah:

1 UPDATE p e g a w a i SET s a l d o = s a l d o + 3 0 0 0 0 0 0 WHERE i d = 1 ;

3 INSERT INTO t r a n s a k s i ( p i d , k e t , n o m i n a l , s a l d o )

4 SELECT i d , ' GAJI 1 1 − 2 0 1 0 ' , 3 0 0 0 0 0 0 , s a l d o

5 FROM p e g a w a i

6 WHERE i d = 1 ;

Ya, kita butuh dua query untuk sebuah transaksi. Mungkin ada p ertanyaan,

untuk apa #eld saldo pada tab el transaksi ? Field ini digunakan untuk memu-

dahkan p enetakan buku tabungan yang biasanya menantumkan saldo pada

setiap transaksi.

Kalau dip erhatikan, transaksi tersebut membutuhkan 3 parameter masukan:

1. ID p egawai
2. Keterangan transaksi

3. Nominal transaksi

Kalau transaksi ini dikemas dalam sebuah fungsi, lalu apa keluarannya ? Kelu-

aran atau output yang paling tepat adalah ID transaksi. Query-nya bisa kita

p eroleh dengan ara b erikut ini.

1 SELECT i d FROM t r a n s a k s i ORDER BY i d DESC LIMIT 1 ;

Artinya dapatkan reord terakhir dari tab el transaksi.

1 i d | p i d | t g l |

2 −−−− + −−−−− + −−−−−−−−−−−−−−−−−−−−−−−− +

3 1 | 1 | 2 0 1 0 − 1 0 − 2 2 1 7 : 5 8 : 0 1 . 8 6 |

5 k e t | n o m i n a l | s a l d o

6 −−−−−−−−−−−−−− + −−−−−−−−− + −−−−−−−−−

7 GAJI 1 1 − 2 0 1 0 | 3 0 0 0 0 0 0 | 3 0 0 0 0 0 0

Selanjutnya kita buat funtransaksi.sql untuk fungsi dimaksud.

Listing 7.4: funtransaksi.sql

1 CREATE OR REPLACE FUNCTION t r a n s a k s i (

2 p _ p i d i n t e g e r ,

3 p _ k e t t e x t ,

4 p _ n o m i n a l f l o a t )

5 RETURNS i n t e g e r

BAB 7. DATABASE 59

6 LANGUAGE p l p g s q l

7 AS $ $

8 DECLARE

9 r e r e o r d ;

10 BEGIN

11 UPDATE p e g a w a i

12 SET s a l d o = s a l d o + p _ n o m i n a l

13 WHERE i d = p _ p i d ;
14

15 INSERT INTO t r a n s a k s i (

16 i d , p i d , n o m i n a l , k e t , s a l d o )

17 SELECT t i d , p _ p i d , p _ n o m i n a l , p _ k e t , s a l d o

18 FROM p e g a w a i

19 WHERE i d = p _ p i d ;

20

21 SELECT i d

22 INTO r e

23 FROM t r a n s a k s i

24 ORDER BY i d DESC

25 LIMIT 1 ;

26

27 RETURN r e . i d ;

28 END

29 $ $

Restore sript ini.

1 t o t a l i n d o => \ i f u n t r a n s a k s i . s q l

2 CREATE FUNCTION

Misalkan ID p egawai 1 meminjam (ash b on) seb esar Rp200.000,- maka:

1 t o t a l i n d o => SELECT t r a n s a k s i ( 1 , ' BON' , − 2 0 0 0 0 0 ) ;

2 t r a n s a k s i

3 −−−−−−−−−−−

4 2

5 ( 1 r o w )

Perhatikan nominal b erisi nilai negatif yang artinya mengurangi saldo. Sekarang

lihat keseluruhan transaksi.

1 t o t a l i n d o => SELECT * FROM t r a n s a k s i ;

2 i d | p i d | t g l | k e t |
n o m i n a l | s a l d o

3 −−−− + −−−−− + −−−−−−−−−−−−−−−−−−−−−−−−−−−− + −−−−−−−−−−−−−− + −−−−−−−−− + −−−−−−


−−−

4 1 | 1 | 2 0 1 0 − 1 0 − 2 2 1 7 : 5 8 : 0 1 . 8 6 9 1 3 9 | GAJI 1 1 − 2 0 1 0 |

3 0 0 0 0 0 0 | 3 0 0 0 0 0 0

BAB 7. DATABASE 60

5 2 | 1 | 2 0 1 0 − 1 0 − 2 2 1 8 : 2 0 : 0 8 . 8 4 5 0 9 1 | BON |
− 2 0 0 0 0 0 | 2 8 0 0 0 0 0

6 ( 2 r o w s )

Dilihat dari asp ek keepatan, query SELECT terhadap tab el transaksi bisa

dihindari. Maklumlah tab el transaksi ini tergolong epat p ertumbuhan reord-

nya. Jadi untuk mendapatkan ID transaksi kita p erlu menggunakan sequene

yang dimiliki tab el transaksi tersebut. Ubahlah funtransaksi.sql menjadi b erikut

ini.

Listing 7.5: funtransaksi.sql

1 CREATE OR REPLACE FUNCTION t r a n s a k s i (

2 p _ p i d i n t e g e r ,

3 p _ k e t t e x t ,

4 p _ n o m i n a l f l o a t )

5 RETURNS i n t e g e r

6 LANGUAGE p l p g s q l

7 AS $ $

8 DECLARE

9 t i d i n t e g e r ;

10 BEGIN

11 UPDATE p e g a w a i

12 SET s a l d o = s a l d o + p _ n o m i n a l

13 WHERE i d = p _ p i d ;

14

15 t i d = n e x t v a l ( ' t r a n s a k s i _ i d _ s e q ' ) ;

16
17 INSERT INTO t r a n s a k s i (

18 i d , p i d , n o m i n a l , k e t , s a l d o )

19 SELECT t i d , p _ p i d , p _ n o m i n a l , p _ k e t , s a l d o

20 FROM p e g a w a i

21 WHERE i d = p _ p i d ;

22

23 RETURN t i d ;

24 END

25 $ $

Restore.

1 t o t a l i n d o => \ i t r a n s a k s i . s q l

2 CREATE FUNCTION

Kini kita oba ID p egawai 5 b ernama Ilham untuk transaksi.

1 t o t a l i n d o => SELECT t r a n s a k s i ( 5 , ' GAJI 1 1 − 2 0 1 0 ' , 1 5


0 0 0 0 0 ) ;

2 t r a n s a k s i

3 −−−−−−−−−−−

4 3

5 ( 1 r o w )

BAB 7. DATABASE 61

Lalu lihat hasilnya.

1 t o t a l i n d o => SELECT * FROM t r a n s a k s i ;

2 i d | p i d | t g l | k e t |

n o m i n a l | s a l d o

3 −−−− + −−−−− + −−−−−−−−−−−−−−−−−−−−−−−−−−−− + −−−−−−−−−−−−−− + −−−−−−−−− + −−−−−−


−−−

4 1 | 1 | 2 0 1 0 − 1 0 − 2 2 1 7 : 5 8 : 0 1 . 8 6 9 1 3 9 | GAJI 1 1 − 2 0 1 0 |

3 0 0 0 0 0 0 | 3 0 0 0 0 0 0

5 2 | 1 | 2 0 1 0 − 1 0 − 2 2 1 8 : 2 0 : 0 8 . 8 4 5 0 9 1 | BON |
− 2 0 0 0 0 0 | 2 8 0 0 0 0 0

6 3 | 5 | 2 0 1 0 − 1 0 − 2 2 1 8 : 4 1 : 4 5 . 3 0 9 4 5 1 | GAJI 1 1 − 2 0 1 0 |
1 5 0 0 0 0 0 | 1 5 0 0 0 0 0

7 ( 3 r o w s )

7.4.2 PL/Python

Penulisan fungsi PostgreSQL bisa juga dalam bahasa Python. Biasanya saya

gunakan bahasa ini untuk algoritma yang tidak membutuhkan akses database.

Pasanglah terlebih dahulu.

1 $ s u d o a p t − g e t i n s t a l l p o s t g r e s q l − p l p y t h o n − 8 .
4

2 $ s u d o s u p o s t g r e s − " r e a t e l a n g p l p y t h o n u t o t a l
i n d o "

Masih ingat mo dul uang yang ditaruh di /usr/lo al/lib/python2.6/dist-pakages

? Kali ini akan kita gunakan pada fungsi di PostgreSQL. Buatlah uang.sql

b erikut ini.

Listing 7.6: uang.sql

1 CREATE OR REPLACE FUNCTION u a n g ( n f l o a t )

2 RETURNS t e x t

3 LANGUAGE p l p y t h o n u

4 AS $ $

5 f r o m u a n g i m p o r t u a n g

6 r e t u r n u a n g ( n )

7 $ $ ;

9 CREATE OR REPLACE FUNCTION u a n g ( n i n t e g e r )

10 RETURNS t e x t

11 LANGUAGE p l p y t h o n u

12 AS $ $

13 f r o m u a n g i m p o r t u a n g

14 r e t u r n u a n g ( n )

15 $ $ ;

Tidak sep erti plpgsql, fungsi yang ditulis menggunakan plpythonu harus
dibuat oleh user p ostgres.

BAB 7. DATABASE 62

1 $ s u d o s u p o s t g r e s − " p s q l t o t a l i n d o − f u a n g . s q l
"

2 [ s u d o ℄ p a s s w o r d f o r s u g i a n a :

3 CREATE FUNCTION

4 CREATE FUNCTION

Lalu obalah.

1 t o t a l i n d o => SELECT u a n g ( 1 0 0 0 0 ) ;

2 u a n g

3 −−−−−−−−

4 1 0 . 0 0 0

5 ( 1 r o w )

Bab 8

Python Akses Database

Data yang ada di PostgreSQL dapat digunakan oleh aplikasi yang ditulis den-

gan bahasa Python menggunakan pustaka tambahan b ernama SQLAlhemy.

Pustaka ini dipilih karena sifatnya yang luwes dimana ia juga bisa menangani

database lainnya, tidak hanya PostgreSQL.

Sekarang pasanglah terlebih dahulu.

1 $ s u d o a p t − g e t i n s t a l l p y t h o n − s q l a l h e m y

2 $ s u d o a p t − g e t i n s t a l l p y t h o n − p s y o p g 2

Selanjutnya masuk ke mo dus interaktif untuk menoba.

1 >>> i m p o r t s q l a l h e m y a s s a

2 >>> u r l = ' p o s t g r e s q l : / / i l h a m : 1 2 3 4 # l o a l h o s t /
t o t a l i n d o '

3 >>> d b = s a . r e a t e _ e n g i n e ( u r l )

4 >>> d b . o n n e t ( )

5 < s q l a l h e m y . e n g i n e . b a s e . C o n n e t i o n o b j e t a t
0 x 8 b 0 8 7 2 >

Sampai di sini Python sudah terhubung ke PostgreSQL dan uji oba login
b erhasil dengan p erintah onnet(). Anda bisa lanjutkan dengan p erintah query

untuk melihat reord tab el p egawai.

1 >>> s q l = "SELECT * FROM p e g a w a i "

2 >>> q = d b . e x e u t e ( s q l )

3 >>> f o r r i n q :

4 . . . p r i n t r

5 . . .

6 ( 1 , ' Bummi D w i P u t e r a ' , d a t e t i m e . d a t e ( 1 9 8 5 , 8 , 1 7


) , T r u e )

7 ( 2 , ' A r i e f S e t i a d i ' , d a t e t i m e . d a t e ( 1 9 7 2 , 5 , 2 )
, T r u e )

8 ( 3 , ' C e e p Z a h r u d i n ' , d a t e t i m e . d a t e ( 1 9 7 2 , 6 ,
1 ) , T r u e )

9 ( 4 , ' N i t a P a n d r i a ' , d a t e t i m e . d a t e ( 1 9 7 6 , 9 , 1 9 )
, F a l s e )

Lalu bagaimana kalau kita ingin melihat nilai b erdasarkan nama #eld-nya

? Untunglah variab el r di atas bisa dianggap sebagai ditionary yang keys-nya

b erisi nama #eld dari query b ersangkutan.

63

BAB 8. PYTHON AKSES DATABASE 64

1 >>> q = d b . e x e u t e ( s q l )

2 >>> f o r r i n q :

3 . . . p r i n t r [ ' i d ' ℄ , r [ ' nama ' ℄

4 . . .

5 1 Bummi D w i P u t e r a

6 2 A r i e f S e t i a d i

7 3 C e e p Z a h r u d i n

8 4 N i t a P a n d r i a

Bahkan #eld id dan nama bisa dianggap variab el milik r:

1 >>> q = d b . e x e u t e ( s q l )

2 >>> f o r r i n q :

3 . . . p r i n t r . i d , r . nama
4 . . .

5 1 Bummi D w i P u t e r a

6 2 A r i e f S e t i a d i

7 3 C e e p Z a h r u d i n

8 4 N i t a P a n d r i a

Mudah bukan ?

Fungsi exeute() bisa juga digunakan untuk p erintah query lainnya sep erti

INSERT, UPDATE, dan DELETE. Contohnya mengganti huruf pada #eld nama

dengan kapital.

1 >>> s q l = "UPDATE p e g a w a i SET nama = u p p e r ( nama ) "

2 >>> d b . e x e u t e ( s q l )

3 < s q l a l h e m y . e n g i n e . b a s e . R e s u l t P r o x y o b j e t a
t 0 x b 7 4 8 a 9 a >

4 >>> s q l = "SELECT * FROM p e g a w a i "

5 >>> q = d b . e x e u t e ( s q l )

6 >>> f o r r i n q :

7 . . . p r i n t r . nama

8 . . .

9 BUMMI DWI PUTERA

10 ARIEF SETIADI

11 CECEP ZAHRUDIN

12 NITA PANDRIA

8.1 Ative Reord

Anda memiliki data p egawai dalam sebuah #le yang b erformat CSV yang isinya

sep erti ini:

Listing 8.1: p egawai.sv

1 1 ; BUMMI DWI PUTERA, ST ; 1 9 8 5 − 0 8 − 1 7 ; t

2 2 ; ARIEF SETIADI ; 1 9 7 2 − 0 5 − 0 2 ; t

3 3 ; CECEP ZAHRUDIN; 1 9 7 2 − 0 6 − 0 1 ; t

BAB 8. PYTHON AKSES DATABASE 65


4 4 ; NITA PANDRIA ; 1 9 7 6 − 0 9 − 1 9 ; f

5 5 ; ILHAM ; 1 9 8 4 − 1 1 − 0 5 ; t

File ini menerminkan tab el p egawai dimana setiap #eld dipisahkan dengan

titik koma ( ; ). Sedangkan identitas baris b erupa ID p egawai yang b erada di

kolom p ertama, p ersis sep erti tab el p egawai. Tugasnya adalah menyalin isi #le

ini ke dalam tab el p egawai. Jika ID p egawai sudah ada maka lakukan UPDATE,

jika b elum b erarti INSERT.

Mari kita lihat terlebih dahulu isi tab el p egawai melalui psql.

1 $ p s q l − U i l h a m − h l o a l h o s t t o t a l i n d o

2 P a s s w o r d f o r u s e r i l h a m :

3 p s q l ( 8 . 4 . 4 )

4 S S L o n n e t i o n ( i p h e r : DHE − RSA − A E S 2 5 6 − SHA , b i t s :


2 5 6 )

5 T y p e " h e l p " f o r h e l p .

7 t o t a l i n d o => SELECT * FROM p e g a w a i ;

8 i d | nama | t g l _ l a h i r | p r i a

9 −−−− + −−−−−−−−−−−−−−−−−− + −−−−−−−−−−−− + −−−−−−

10 1 | BUMMI DWI PUTERA | 1 9 8 5 − 0 8 − 1 7 | t

11 2 | ARIEF SETIADI | 1 9 7 2 − 0 5 − 0 2 | t

12 3 | CECEP ZAHRUDIN | 1 9 7 2 − 0 6 − 0 1 | t

13 4 | NITA PANDRIA | 1 9 7 6 − 0 9 − 1 9 | f

14 ( 4 r o w s )

Bandingkanlah dengan #le p egawai.sv seb elumnya dimana p erubahannya

nanti adalah:

1. ID 1 nama akan b erubah dari BUMMI DWI PUTERA menjadi BUMMI

DWI PUTERA, ST (b ergelar).

2. Jumlah baris tab el p egawai b ertambah dengan adanya ID 5 b ernama IL-

HAM.

Buatlah #le p egawai.sv terlebih dahulu dengan isi sep erti di atas. Kemudian
buatlah #le up datep egawai.py.

Listing 8.2: up datep egawai.py

1 i m p o r t s q l a l h e m y a s s a

3 u r l = ' p o s t g r e s q l : / / i l h a m : 1 2 3 4 # l o a l h o s t / t o
t a l i n d o '

4 d b = s a . r e a t e _ e n g i n e ( u r l )

5 d b . o n n e t ( )

7 f i l e n a m e = ' p e g a w a i . s v '

8 f = o p e n ( f i l e n a m e )

9 f o r l i n e i n f . r e a d l i n e s ( ) :

10 p i d , nama , t g l _ l a h i r , p r i a = l i n e . s t r i p ( ) . s p l i t
( ' ; ' )

BAB 8. PYTHON AKSES DATABASE 66

11 p i d = i n t ( p i d )

12 p r i a = p r i a == ' t ' # A g a r b o o l e a n T r u e / F a l s e

13 s q l = "SELECT * FROM p e g a w a i WHERE i d = %d " % p i d

14 q = d b . e x e u t e ( s q l )

15 i f q . r o w o u n t :

16 s q l = "UPDATE p e g a w a i SET " + \

17 " nama = ' % s ' , " + \

18 " t g l _ l a h i r = ' % s ' , " + \

19 " p r i a = %s " + \

20 "WHERE i d = %d "

21 s q l = s q l % ( nama , t g l _ l a h i r , p r i a , p i d )

22 e l s e :

23 s q l = " INSERT INTO p e g a w a i " + \

24 " ( i d , nama , t g l _ l a h i r , p r i a ) " + \

25 "SELECT %d , ' % s ' , ' % s ' , %s "


26 s q l = s q l % ( p i d , nama , t g l _ l a h i r , p r i a )

27 d b . e x e u t e ( s q l )

Jalankan.

1 $ p y t h o n u p d a t e p e g a w a i . p y

Kemudian ke psql, lihat tab el p egawai.

1 t o t a l i n d o => SELECT * FROM p e g a w a i ORDER BY i d ;

2 i d | nama | t g l _ l a h i r | p r i a

3 −−−− + −−−−−−−−−−−−−−−−−−−−−− + −−−−−−−−−−−− + −−−−−−

4 1 | BUMMI DWI PUTERA, ST | 1 9 8 5 − 0 8 − 1 7 | t

5 2 | ARIEF SETIADI | 1 9 7 2 − 0 5 − 0 2 | t

6 3 | CECEP ZAHRUDIN | 1 9 7 2 − 0 6 − 0 1 | t

7 4 | NITA PANDRIA | 1 9 7 6 − 0 9 − 1 9 | f

8 5 | ILHAM | 1 9 8 4 − 1 1 − 0 5 | t

9 ( 5 r o w s )

Perubahan sudah sesuai dengan yang diharapkan. Meski b egitu soure

up datep egawai.py tergolong sulit dibaa, dan ini bisa menyulitkan debugging

(p enelusuran kesalahan). Cara yang lebih nyaman adalah menggunakan teknik

yang disebut ative reord .

Terlebih dahulu pasang paket Elixir.

1 $ s u d o a p t − g e t i n s t a l l p y t h o n − e l i x i r

Agar proses UPDATE dan INSERT masih terasa, buatlah p erubahan pada

p egawai.sv b erikut ini.

Listing 8.3: p egawai.sv

1 1 ; BUMMI DWI PUTERA, ST ; 1 9 8 5 − 0 8 − 1 7 ; t

2 2 ; ARIEF SETIADI ; 1 9 7 2 − 0 5 − 0 2 ; t

3 3 ; CECEP ZAHRUDIN , ST ; 1 9 7 2 − 0 6 − 0 1 ; t

BAB 8. PYTHON AKSES DATABASE 67

4 4 ; NITA PANDRIA ; 1 9 7 6 − 0 9 − 1 9 ; f

5 5 ; ILHAM ; 1 9 8 4 − 1 1 − 0 5 ; t

6 6 ; MIRANDA ; 1 9 7 8 − 1 0 − 0 1 ; f
Perubahannya adalah UPDATE pada CECEP ZAHRUDIN menjadi CE-

CEP ZAHRUDIN, ST, dan INSERT pada MIRANDA. Selanjutnya buat #le

up datep egawai1.py.

Listing 8.4: up datep egawai1.py

1 f r o m e l i x i r i m p o r t E n t i t y , u s i n g _ o p t i o n s , s e t u
p _ a l l ,

m e t a d a t a , \

2 s e s s i o n

4 l a s s P e g a w a i ( E n t i t y ) :

5 u s i n g _ o p t i o n s ( t a b l e n a m e = ' p e g a w a i ' , a u t o l o a
d =T r u e )

7 m e t a d a t a . b i n d = ' p o s t g r e s : / / i l h a m : 1 2 3 4 # l o a
l h o s t /

t o t a l i n d o '

8 s e t u p _ a l l ( )

10 f i l e n a m e = ' p e g a w a i . s v '

11 f = o p e n ( f i l e n a m e )

12 f o r l i n e i n f . r e a d l i n e s ( ) :

13 p i d , nama , t g l _ l a h i r , p r i a = l i n e . s t r i p ( ) . s p l i t
( ' ; ' )

14 p i d = i n t ( p i d )

15 p = P e g a w a i . q u e r y . f i l t e r _ b y ( i d =p i d )

16 i f p . o u n t ( ) :

17 r = p . o n e ( )

18 e l s e :

19 r = P e g a w a i ( )

20 r . i d = p i d

21 r . nama = nama
22 r . t g l _ l a h i r = t g l _ l a h i r

23 r . p r i a = p r i a == ' t '

24 s e s s i o n . o m m i t ( )

Jalankanlah.

1 $ p y t h o n u p d a t e p e g a w a i 1 . p y

Lalu lihat hasilnya di psql.

1 t o t a l i n d o => SELECT * FROM p e g a w a i ORDER BY i d ;

2 i d | nama | t g l _ l a h i r | p r i a

3 −−−− + −−−−−−−−−−−−−−−−−−−−−− + −−−−−−−−−−−− + −−−−−−

4 1 | BUMMI DWI PUTERA, ST | 1 9 8 5 − 0 8 − 1 7 | t

5 2 | ARIEF SETIADI | 1 9 7 2 − 0 5 − 0 2 | t

6 3 | CECEP ZAHRUDIN , ST | 1 9 7 2 − 0 6 − 0 1 | t

BAB 8. PYTHON AKSES DATABASE 68

7 4 | NITA PANDRIA | 1 9 7 6 − 0 9 − 1 9 | f

8 5 | ILHAM | 1 9 8 4 − 1 1 − 0 5 | t

9 6 | MIRANDA | 1 9 7 8 − 1 0 − 0 1 | f

10 ( 6 r o w s )

Hasil sudah sesuai harapan dengan soure yang jauh lebih mudah dibaa.

Pahamilah baik-baik mengenai konsep ative reord ini.

Lalu bagaimana menghapus salah satu reord ? Buatlah #le deletep egawai.py

b erikut ini.

Listing 8.5: deletep egawai.py

1 f r o m e l i x i r i m p o r t E n t i t y , u s i n g _ o p t i o n s , m e t a
d a t a ,

s e t u p _ a l l , \

2 s e s s i o n

3 i m p o r t s y s

5 l a s s P e g a w a i ( E n t i t y ) :

6 u s i n g _ o p t i o n s ( t a b l e n a m e = ' p e g a w a i ' , a u t o l o a
d =T r u e )
7

8 i f n o t s y s . a r g v [ 1 : ℄ :

9 s y s . e x i t ( ' C a r a n y a : p y t h o n %s < i d > ' % s y s . a r g


v [ 0 ℄ )

10

11 t r y :

12 p i d = i n t ( s y s . a r g v [ 1 ℄ )

13 e x e p t V a l u e E r r o r :

14 s y s . e x i t ( ' I D p e g a w a i h a r u s a n g k a ' )

15

16 m e t a d a t a . b i n d = ' p o s t g r e s : / / i l h a m : 1 2 3 4 # l o a
l h o s t /

t o t a l i n d o '

17 s e t u p _ a l l ( )

18

19 p = P e g a w a i . q u e r y . f i l t e r _ b y ( i d = p i d )

20 i f n o t p . o u n t ( ) :

21 s y s . e x i t ( ' I D p e g a w a i %d t i d a k a d a ' % p i d )

22

23 r = p . o n e ( )

24 r . d e l e t e ( )

25 s e s s i o n . o m m i t ( )

26 p r i n t ' I D p e g a w a i %d s u d a h d i h a p u s ' % p i d

Sript ini membutuhkan parameter masukan (argument) saat dijalankan,

yaitu b erupa ID p egawai yang akan dihapus. Kita oba menghapus ID p egawai

4 NITA PANDRIA.

1 $ p y t h o n d e l e t e _ p e g a w a i . p y 4

2 I D p e g a w a i 4 s u d a h d i h a p u s

Periksa hasilnya di psql.

BAB 8. PYTHON AKSES DATABASE 69


1 t o t a l i n d o => SELECT * FROM p e g a w a i ORDER BY i d ;

2 i d | nama | t g l _ l a h i r | p r i a

3 −−−− + −−−−−−−−−−−−−−−−−−−−−− + −−−−−−−−−−−− + −−−−−−

4 1 | BUMMI DWI PUTERA, ST | 1 9 8 5 − 0 8 − 1 7 | t

5 2 | ARIEF SETIADI | 1 9 7 2 − 0 5 − 0 2 | t

6 3 | CECEP ZAHRUDIN , ST | 1 9 7 2 − 0 6 − 0 1 | t

7 5 | ILHAM | 1 9 8 4 − 1 1 − 0 5 | t

8 6 | MIRANDA | 1 9 7 8 − 1 0 − 0 1 | f

9 ( 5 r o w s )

Bagaimana dengan SELECT ? Contoh seb elumnya menggunakan #lter_by()

yang sama artinya dengan WHERE. Kini kita tampilkan semua reord tab el p e-

gawai tanpa kondisi apapun yaitu mengganti #lter_by() dengan all(). Buatlah

seletp egawai.py.

Listing 8.6: seletp egawai.py

1 f r o m e l i x i r i m p o r t E n t i t y , u s i n g _ o p t i o n s , m e t a
d a t a ,

s e t u p _ a l l

2 i m p o r t s y s

4 l a s s P e g a w a i ( E n t i t y ) :

5 u s i n g _ o p t i o n s ( t a b l e n a m e = ' p e g a w a i ' , a u t o l o a
d =T r u e )

7 m e t a d a t a . b i n d = ' p o s t g r e s : / / i l h a m : 1 2 3 4 # l o a
l h o s t /

t o t a l i n d o '

8 s e t u p _ a l l ( )

10 f o r r i n P e g a w a i . q u e r y . a l l ( ) :

11 p r i n t r . i d , r . nama , r . t g l _ l a h i r , r . p r i a

Jalankan.
$ python selet_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 b erdasarkan nama ? Kita biasa menggunakan OR-

DER BY pada query, disini bisa menggunakan order_by() sebagai p engganti

all().

Listing 8.7: seletp egawai2.py

1 f r o m e l i x i r i m p o r t E n t i t y , u s i n g _ o p t i o n s , m e t a
d a t a ,

s e t u p _ a l l

2 i m p o r t s y s

BAB 8. PYTHON AKSES DATABASE 70

4 l a s s P e g a w a i ( E n t i t y ) :

5 u s i n g _ o p t i o n s ( t a b l e n a m e = ' p e g a w a i ' , a u t o l o a
d =T r u e )

7 m e t a d a t a . b i n d = ' p o s t g r e s : / / i l h a m : 1 2 3 4 # l o a
l h o s t /

t o t a l i n d o '

8 s e t u p _ a l l ( )

10 f o r r i n P e g a w a i . q u e r y . o r d e r _ b y ( ' nama ' ) :

11 p r i n t r . i d , r . nama , r . t g l _ l a h i r , r . p r i a

Jalankan.

1 $ p y t h o n s e l e t _ p e g a w a i . p y

2 2 ARIEF SETIADI 1 9 7 2 − 0 5 − 0 2 T r u e

3 1 BUMMI DWI PUTERA, ST 1 9 8 5 − 0 8 − 1 7 T r u e


4 3 CECEP ZAHRUDIN , ST 1 9 7 2 − 0 6 − 0 1 T r u e

5 5 ILHAM 1 9 8 4 − 1 1 − 0 5 T r u e

6 6 MIRANDA 1 9 7 8 − 1 0 − 0 1 F a l s e

Ingin yang lebih rapi ? Ubahlah sep erti ini.

Listing 8.8: seletp egawai.py

1 f r o m e l i x i r i m p o r t *

2 i m p o r t s y s

4 l a s s P e g a w a i ( E n t i t y ) :

5 u s i n g _ o p t i o n s ( t a b l e n a m e = ' p e g a w a i ' , a u t o l o a
d =T r u e )

7 m e t a d a t a . b i n d = ' p o s t g r e s : / / i l h a m : 1 2 3 4 # l o a
l h o s t /

t o t a l i n d o '

8 s e t u p _ a l l ( )

10 j e n i s = { T r u e : ' P r i a ' ,

11 F a l s e : ' W a n i t a ' }

12

13 p = P e g a w a i . q u e r y . o r d e r _ b y ( ' nama ' )

14 f o r r i n p :

15 p r i n t s t r ( r . i d ) . e n t e r ( 3 ) , \

16 r . nama . l j u s t ( 2 0 ) , \

17 r . t g l _ l a h i r , \

18 j e n i s [ r . p r i a ℄

Jalankan.

1 $ p y t h o n s e l e t _ p e g a w a i . p y

2 2 ARIEF SETIADI 1 9 7 2 − 0 5 − 0 2 P r i a

3 1 BUMMI DWI PUTERA, ST 1 9 8 5 − 0 8 − 1 7 P r i a

BAB 8. PYTHON AKSES DATABASE 71


4 3 CECEP ZAHRUDIN , ST 1 9 7 2 − 0 6 − 0 1 P r i a

5 5 ILHAM 1 9 8 4 − 1 1 − 0 5 P r i a

6 6 MIRANDA 1 9 7 8 − 1 0 − 0 1 W a n i t a

Elixir vs SQLAlhemy ?

Seb enarnya Elixir bukanlah menggantikan SQLAlhemy, karena Elixir sendiri

menggunakan engine SQLAlhemy. Ini bisa terlihat pada p enjelasan paket

python-elixir.

1 $ d p k g − s p y t h o n − e l i x i r

2 P a k a g e : p y t h o n − e l i x i r

3 V e r s i o n : 0 . 7 . 1 − 1

4 D e p e n d s : p y t h o n (>= 2 . 4 ) , p y t h o n − s u p p o r t (>= 0 . 9 0
. 0 ) ,

p y t h o n − s q l a l h e m y (>= 0 . 4 . 0 )

5 D e s r i p t i o n : D e l a r a t i v e M a p p e r f o r S Q L A l h e m y

8.2 Auto Commit

Masih ingat fungsi sql b ernama transaksi() ? Kali ini akan kita buat transaksi

p erbankan seara interaktif. Buatlah transaksi.py b erikut.

Listing 8.9: transaksi.py

1 i m p o r t s q l a l h e m y a s s a

2 i m p o r t s y s

4 u r l = ' p o s t g r e s q l : / / i l h a m : 1 2 3 4 # l o a l h o s t / t o
t a l i n d o '

5 d b = s a . r e a t e _ e n g i n e ( u r l )

7 p r i n t ' T r a n s a k s i '

8 p i d = r a w _ i n p u t ( ' I D p e g a w a i : ' )

9 t r y :

10 p i d = i n t ( p i d )

11 e x e p t V a l u e E r r o r :
12 s y s . e x i t ( ' I D p e g a w a i %s t i d a k b e n a r ' % p i d )

13

14 s q l = "SELECT nama FROM p e g a w a i WHERE i d = %d " % p i d

15 q = d b . e x e u t e ( s q l )

16 i f n o t q . r o w o u n t :

17 s y s . e x i t ( ' I D p e g a w a i %d t i d a k a d a ' % p i d )

18 p r i n t ' Nama : ' , q . f e t h o n e ( ) . nama

19

20 k e t = r a w _ i n p u t ( ' K e t e r a n g a n : ' )

21 i f n o t k e t :

22 s y s . e x i t ( ' K e t e r a n g a n h a r u s d i i s i ' )

BAB 8. PYTHON AKSES DATABASE 72

23

24 n o m i n a l = r a w _ i n p u t ( ' N o m i n a l : ' )

25 t r y :

26 n o m i n a l = f l o a t ( n o m i n a l )

27 e x e p t V a l u e E r r o r :

28 s y s . e x i t ( ' N o m i n a l %s t i d a k b e n a r ' % n o m i n a
l )

29

30 s q l = "SELECT t r a n s a k s i (% d , ' % s ' , % . 2 f ) " % ( p i d , k e


t ,

n o m i n a l )

31 q = d b . e x e u t e ( s q l )

32 p r i n t ' T r a n s a k s i b e r h a s i l , I D ' , q . f e t h o n e (
) . t r a n s a k s i

Jalankan.

1 $ p y t h o n t r a n s a k s i . p y

2 T r a n s a k s i

3 I D p e g a w a i : 3

4 Nama : CECEP ZAHRUDIN , ST


5 K e t e r a n g a n : GAJI 1 1 − 2 0 1 0

6 N o m i n a l : 4 5 0 0 0 0 0

7 T r a n s a k s i b e r h a s i l , I D 4

Untuk memastikan transaksi b enar-b enar b erhasil, lihatlah di psql.

1 t o t a l i n d o => SELECT * FROM t r a n s a k s i ;

2 i d | p i d | t g l | k e t | n o m i n a l | s a l d o

3 −−−− + −−−−− + −−−−−−−−−−−− + −−−−−−−−−−−−−− + −−−−−−−−− + −−−−−−−−

4 1 | 1 | 2 0 1 0 − 1 0 − 2 2 | GAJI 1 1 − 2 0 1 0 | 3 0 0 0 0 0 0 | 3 0 0 0 0 0 0

5 2 | 1 | 2 0 1 0 − 1 0 − 2 2 | BON | − 2 0 0 0 0 0 | 2 8 0 0 0 0 0

6 3 | 5 | 2 0 1 0 − 1 0 − 2 2 | GAJI 1 1 − 2 0 1 0 | 1 5 0 0 0 0 0 | 1 5 0 0 0 0 0

7 ( 3 r o w s )

Perhatikan, tidak ada ID transaksi 4, padahal eksekusi transaksi.py b erjalan

baik. Apa yang terjadi ?

SQL funtion transaksi() yang dijalankan oleh transaksi.py dijalankan pada

mo dus transation . Ini bisa diartikan SQLAlhemy atau mungkin Psyopg2

yang digunakan SQLAlhemy otomatis menjalankan BEGIN seb elum SELECT

transaksi( ... ). Sep erti kita ketahui BEGIN tanpa COMMIT sama artinya den-

gan ROLLBACK. Itu artinya semua akti#tas DML sep erti INSERT, UPDATE,

DELETE setelah BEGIN dibatalkan, seolah tidak terjadi.

Solusinya adalah memb eritahukan SQLAlhemy untuk menjalankan auto

ommit . Ubahlah transaksi.py menjadi b erikut ini.

Listing 8.10: transaksi.py

1 i m p o r t s q l a l h e m y a s s a

2 f r o m s q l a l h e m y . s q l . e x p r e s s i o n i m p o r t t e x t

3 i m p o r t s y s

BAB 8. PYTHON AKSES DATABASE 73

5 u r l = ' p o s t g r e s q l : / / i l h a m : 1 2 3 4 # l o a l h o s t / t o
t a l i n d o '

6 d b = s a . r e a t e _ e n g i n e ( u r l )
7

8 p r i n t ' T r a n s a k s i '

9 p i d = r a w _ i n p u t ( ' I D p e g a w a i : ' )

10 t r y :

11 p i d = i n t ( p i d )

12 e x e p t V a l u e E r r o r :

13 s y s . e x i t ( ' I D p e g a w a i %s t i d a k b e n a r ' % p i d )

14

15 s q l = "SELECT nama FROM p e g a w a i WHERE i d = %d " % p i d

16 q = d b . e x e u t e ( s q l )

17 i f n o t q . r o w o u n t :

18 s y s . e x i t ( ' I D p e g a w a i %d t i d a k a d a ' % p i d )

19 p r i n t ' Nama : ' , q . f e t h o n e ( ) . nama

20

21 k e t = r a w _ i n p u t ( ' K e t e r a n g a n : ' )

22 i f n o t k e t :

23 s y s . e x i t ( ' K e t e r a n g a n h a r u s d i i s i ' )

24

25 n o m i n a l = r a w _ i n p u t ( ' N o m i n a l : ' )

26 t r y :

27 n o m i n a l = f l o a t ( n o m i n a l )

28 e x e p t V a l u e E r r o r :

29 s y s . e x i t ( ' N o m i n a l %s t i d a k b e n a r ' % n o m i n a
l )

30

31 s q l = "SELECT t r a n s a k s i (% d , ' % s ' , % . 2 f ) " % ( p i d , k e


t ,

n o m i n a l )

32 q = d b . e x e u t e ( t e x t ( s q l , a u t o o m m i t=T r u e ) )

33 p r i n t ' T r a n s a k s i b e r h a s i l , I D ' , q . f e t h o n e (
) . t r a n s a k s i
Penambahan pada baris 2:

from sqlalhemy.sql.expression import text

dan p erubahan pada baris 32 dari

q = db.exeute(sql)

menjadi

q = db.exeute(text(sql, autoommit=True))

8.3 Synhronizer

Pelanggan Anda memiliki usaha di bidang mini market dan telah memiliki b e-

b erapa outlet. Semua outlet itu telah terhubung ke Internet. Internet digunakan

BAB 8. PYTHON AKSES DATABASE 74

untuk mengambil data pro duk yang dikirim kantor pusat melalui email. Data

pro duk tersebut tersimpan dalam attahment. User di outlet menyimpannya ke

folder tertentu untuk selanjutnya dimasukkan ke database outlet melalui menu

Restore yang telah disediakan di aplikasi. Begitu juga dengan data transak-

si. Data disimpan terlebih dahulu ke dalam sebuah #le melalui menu Bakup.

Selanjutnya #le tersebut di-email ke kantor pusat.

Teknik ini sudah baik, namun lebih baik lagi jika p ekerjaan itu dilakukan

oleh sript yang disebut synhronizer.

Kita membiarakan mekanisme otomatis p enuh, dimana synhronizer dipiu

oleh waktu, misalkan jam 9:00 dan jam 17:00 setiap harinya. Berb eda dengan

teknik seb elumnya, synhronizer tidak menggunakan email untuk komunikasi

data. Ia b ekerja 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 synhronizer di out-

let dapat mengakses database pusat. IP publik ini dapat dip esan ke ISP (In-

ternet Servie Provider) b ersangkutan. Setelah IP publik didapat, tambahkan

baris b erikut ini di /et/postgresql/8.4/main/pg_hba.onf :

host all all 0.0.0.0/0 md5

Kon#gurasi ini artinya semua host dapat mengakses database pusat, tentunya

dengan otenti#kasi username dan password. Simpan dan restart daemon-nya:


1 $ s u d o s e r v i e p o s t g r e s q l − 8 . 4 r e s t a r t

2 * R e s t a r t i n g P o s t g r e S Q L 8 . 4 d a t a b a s e s e r v e r

Kini saatnya uji konektivitas database. Misalkan IP publiknya adalah


110.137.120.251,

maka jalankan di outlet :

1 $ p s q l − U i l h a m − h 1 1 0 . 1 3 7 . 1 2 0 . 2 5 1 t o t a l i n d o

Di sript Python gantilah lo alhost dengan IP publik tadi.

url = 'postgresql://ilham:1234#110.137.120.251/totalindo'

Mudah bukan ?

8.3.1 Asp ek Keamanan

Tapi nanti dulu. Meski outlet itu hanya mendapat akses terbatas di database

pusat, namun tetap sa ja ini masih menimbulkan resiko keamanan data. Alangkah

baiknya menggunakan teknik sebaliknya, yaitu synhronizer b erada di pusat .

Dengan kata lain pusat-lah yang membaa database outlet, sedangkan outlet

tidak mendapat hak akses apapun di database pusat.

Lalu bagaimana host pusat mengakses host outlet ? Apa p erlu p esan IP

publik lagi ke ISP yang ada di outlet ?

Idealnya ya, namun tidak harus. Kita bisa menerapkan VPN alias Virtual

Private Network. Cukup pasang VPN server di pusat, dan pasang VPN lient

BAB 8. PYTHON AKSES DATABASE 75

di outlet. Dengan VPN ini terb entuk jaringan baru dengan IP pusat 10.8.0.1,

sedangkan IP outlet 10.8.0.6, 10.8.0.10, 10.8.0.14, dst. Baik VPN server maupun

VPN lient bisa kita gunakan Op enVPN. Untuk p emasangan keduanya silahkan

baa url b erikut ini:

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

Apakah Op enVPN dapat b ekerja di Windows mengingat masih banyak outlet

yang menggunakan sistem op erasi ini ?

Ya, untungnya Op enVPN tersedia di untuk sistem op erasi itu, dan tetap

dapat diatur agar otomatis aktif saat komputer dihidupkan.

Baik di pusat maupun di outlet jalankan p erintah ini untuk mengetahi IP


VPN masing-masing:

1 $ i f o n f i g t u n 0

2 t u n 0 L i n k e n a p : UNSPEC HWaddr

0 0 − 0 0 − 0 0 − 0 0 − 00 −0 0 − 00 − 00 −0 0 − 00 −00 − 00 − 00 −0 0 − 00 − 00

3 i n e t a d d r : 1 0 . 8 . 0 . 6 P − t − P : 1 0 . 8 . 0 . 5 M a s k

: 2 5 5 . 2 5 5 . 2 5 5 . 2 5 5

4 UP POINTOPOINT RUNNING NOARP MULTICAST MTU

: 1 5 0 0 M e t r i : 1

5 RX p a k e t s : 0 e r r o r s : 0 d r o p p e d : 0 o v e r r u n s : 0

f r a m e : 0

6 TX p a k e t s : 6 e r r o r s : 0 d r o p p e d : 0 o v e r r u n s : 0

a r r i e r : 0

7 o l l i s i o n s : 0 t x q u e u e l e n : 1 0 0

8 RX b y t e s : 0 ( 0 . 0 B ) TX b y t e s : 9 6 3 ( 9 6 3 . 0 B )

Tampak IP VPN di outlet adalah 10.8.0.6, sedangkan IP VPN di pusat

biasanya 10.8.0.1. Di host pusat, Anda juga bisa lihat IP masing-masing lient di

#le /et/openvpn/ipp.txt . Jangan lupa untuk menguji konektivitas network

dengan p erintah ping.

Op enVPN telah terpasang dan kedua host pusat dan outlet sudah bisa saling

ping. Selanjutnya apa yang harus dilakukan ?

Tambahkan baris b erikut ini di /et/postgresql/8.4/main/pg_hba.onf

di outlet .

host all all 10.8.0.1/32 md5

Lalu restart daemon-nya.

1 $ s u d o s e r v i e p o s t g r e s q l − 8 . 4 r e s t a r t

2 * R e s t a r t i n g P o s t g r e S Q L 8 . 4 d a t a b a s e s e r v e r

Di pusat lakukan uji konektivitas dengan psql.

1 $ p s q l − U i l h a m − h 1 0 . 8 . 0 . 6 t o t a l i n d o

Jika sudah terhubung baik, saatnya membuat sript synhronizer.


BAB 8. PYTHON AKSES DATABASE 76

8.3.2 Tambah, Perbaharui, Hapus

Adalah sebuah tab el pro duk dengan struktur sebagai b erikut:

Listing 8.11: pro duk.sql

1 r e a t e t a b l e p r o d u k (

2 i d s e r i a l p r i m a r y k e y ,

3 nama n a m e n o t n u l l u n i q u e ,

4 h a r g a f l o a t n o t n u l l

5 ) ;

Isilah dengan b eb erapa reord b erikut ini:

1 INSERT INTO p r o d u k ( nama , h a r g a ) SELECT ' J e r u k P o n t i a n a


k '

, 1 0 5 0 0 ;

2 INSERT INTO p r o d u k ( nama , h a r g a ) SELECT ' S a l a k P o n d o h '

, 9 2 5 0 ;

3 INSERT INTO p r o d u k ( nama , h a r g a ) SELECT ' M a n g g a I n d r a m a


y u '

, 1 4 3 0 0 ;

Untuk menyamakan data pro duk, kita memerlukan dua p erulangan (lo op).

Yang p ertama untuk INSERT dan UPDATE, sedangkan yang kedua untuk

DELETE. Berikut yang p ertama:

1. Setiap reord pusat dibaa.

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

3. Jika id tidak ditemukan di outlet maka tambahkan.

4. Jika id ditemukan maka p erbaharui.

Sedangkan untuk menghapus:

1. Setiap reord outlet dibaa.

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

Lalu mulailah membuat syn.py b erikut ini.

Listing 8.12: syn.py

1 i m p o r t s q l a l h e m y a s s a
2 f r o m e l i x i r i m p o r t E n t i t y , u s i n g _ o p t i o n s , s e t u
p _ a l l ,

m e t a d a t a

3 f r o m s q l a l h e m y . o r m i m p o r t s o p e d _ s e s s i o n , s e s
s i o n m a k e r

4 f r o m s q l a l h e m y . s h e m a i m p o r t T h r e a d L o a l M e t a
D a t a

7 e s = s a . r e a t e _ e n g i n e ( ' p o s t g r e s q l : / / i l h a m : 1
2 3 4 # l o a l h o s t /

t o t a l i n d o ' )

BAB 8. PYTHON AKSES DATABASE 77

8 e t = s a . r e a t e _ e n g i n e ( ' p o s t g r e s q l : / / i l h a m : 1
2 3 4 # l o a l h o s t /

t o t a l i n d o 2 ' )

10 s s = s o p e d _ s e s s i o n ( s e s s i o n m a k e r ( b i n d= e s ) )

11 s t = s o p e d _ s e s s i o n ( s e s s i o n m a k e r ( b i n d= e t ) )

12

13 ms = m e t a d a t a

14 mt = T h r e a d L o a l M e t a D a t a ( )

15

16 ms . b i n d = e s

17 mt . b i n d = e t

18

19

20 l a s s P r o d u k S ( E n t i t y ) :

21 u s i n g _ o p t i o n s ( t a b l e n a m e = ' p r o d u k ' , a u t o l o a
d =T r u e ,

m e t a d a t a =ms , s e s s i o n = s s )

22
23 l a s s P r o d u k T ( E n t i t y ) :

24 u s i n g _ o p t i o n s ( t a b l e n a m e = ' p r o d u k ' , a u t o l o a
d =T r u e ,

m e t a d a t a =mt , s e s s i o n = s t )

25

26 s e t u p _ a l l ( )

27

28 # INSERT & UPDATE

29

30 a l l _ p s = [ ℄

31 f o r p s i n P r o d u k S . q u e r y . a l l ( ) :

32 p r i n t p s . i d , p s . nama , p s . h a r g a ,

33 t r y :

34 p t = P r o d u k T . q u e r y . f i l t e r _ b y ( i d =p s . i d ) . o n e (
)

35 p r i n t ' d i u b a h '

36 e x e p t s a . o r m . e x . N o R e s u l t F o u n d , e :

37 p r i n t ' d i t a m b a h '

38 p t = P r o d u k T ( i d =p s . i d )

39 p t . nama = p s . nama

40 p t . h a r g a = p s . h a r g a

41 s t . o m m i t ( )

42 a l l _ p s . a p p e n d ( p s . i d )

43

44 # DELETE

45

46 f o r p t i n P r o d u k T . q u e r y . a l l ( ) :

47 i f p t . i d n o t i n a l l _ p s :

48 p r i n t p t . i d , p t . nama , p t . h a r g a , ' d i h a p u s '

49 p t . d e l e t e ( )

50 s t . o m m i t ( )
BAB 8. PYTHON AKSES DATABASE 78

8.4 Migrasi dari Database Lain

Anda sudah memiliki aplikasi yang menggunakan MySQL, dan kini ingin b eralih

ke PostgreSQL. Setidaknya dibutuhan p enyalinan struktur tab el b eserta isinya.

Terlebih dahulu pasanglah driver MySQL.

1 $ s u d o a p t − g e t i n s t a l l p y t h o n − m y s q l d b

Lalu buatlah dbmigration.py b erikut ini.

Listing 8.13: dbmigration.py

1 i m p o r t s q l a l h e m y a s s a

2 f r o m s q l a l h e m y . s h e m a i m p o r t T h r e a d L o a l M e t a
D a t a

3 f r o m s q l a l h e m y . o r m i m p o r t s o p e d _ s e s s i o n , s e s
s i o n m a k e r

4 f r o m e l i x i r i m p o r t *

5 i m p o r t s y s

8 d b s = s a . r e a t e _ e n g i n e ( s y s . a r g v [ 1 ℄ ) # s o u r e

9 d b t = s a . r e a t e _ e n g i n e ( s y s . a r g v [ 2 ℄ ) # t a r g e t

10 d b s . o n n e t ( )

11 d b t . o n n e t ( )

12 s e s s i o n _ s = s o p e d _ s e s s i o n ( s e s s i o n m a k e r ( b i n
d=d b s ) )

13 s e s s i o n _ t = s o p e d _ s e s s i o n ( s e s s i o n m a k e r ( b i n
d=d b t ) )

14 m e t a d a t a _ s = m e t a d a t a

15 m e t a d a t a _ t = T h r e a d L o a l M e t a D a t a ( )

16 m e t a d a t a _ s . b i n d = d b s

17 m e t a d a t a _ t . b i n d = d b t

18

19 f o r t a b l e n a m e i n d b s . t a b l e _ n a m e s ( ) :
20 l a s s S o u r e ( E n t i t y ) :

21 u s i n g _ o p t i o n s ( t a b l e n a m e =t a b l e n a m e , a u t o l o a
d =T r u e ,

22 m e t a d a t a=m e t a d a t a _ s , s e s s i o n = s e s s i o n _ s )

23

24 s e t u p _ a l l ( )

25

26 l a s s T a r g e t ( E n t i t y ) :

27 u s i n g _ o p t i o n s ( t a b l e n a m e =t a b l e n a m e ,

28 m e t a d a t a=m e t a d a t a _ t , s e s s i o n = s e s s i o n _ t )

29 f o r o l u m n i n S o u r e . m a p p e r . o l u m n s :

30 h a s _ f i e l d ( o l u m n . n a m e , o l u m n . t y p e ,

31 p r i m a r y _ k e y= o l u m n . p r i m a r y _ k e y ,

32 r e q u i r e d = n o t o l u m n . n u l l a b l e ,

33 )

34

35 s e t u p _ a l l ( T r u e )

36

BAB 8. PYTHON AKSES DATABASE 79

Database Paket

PostgreSQL python-psyopg2

MySQL python-mysqldb

SQLite python-sqlite2

Interbase python-kinterbasdb

MS SQL python-pymssql

Tab el 8.1: Driver database

37 f o r s o u r e i n S o u r e . q u e r y . a l l ( ) :

38 t a r g e t = T a r g e t ( )

39 t a r g e t . f r o m _ d i t ( s o u r e . t o _ d i t ( ) )

40 s e s s i o n _ t . o m m i t ( )
Contoh p enggunaan:

1 p y t h o n d b m i g r a t i o n . p y m y s q l : / / r o o t : 6 7 8 9 # l o
a l h o s t / s u m b e r

p o s t g r e s : / / j e f r i : 1 2 3 4 # l o a l h o s t / t a r g e t

Proses migrasi ini sudah menyertakan p embuatan tab el b erikut onstraint

sep erti PRIMARY KEY dan NULL.

Untuk driver database lainnya Anda bisa lihat di informasi paket python-

sqlalhemy, dan p erhatikan bagian Suggests.

1 $ d p k g − s p y t h o n − s q l a l h e m y

2 . .

3 S u g g e s t s : p y t h o n − s q l a l h e m y − d o , p y t h o n − p s y
o p g 2 , p y t h o n −

m y s q l d b (>= 1 . 2 . 1 − p 2 − 2 ) , p y t h o n (>= 2 . 5 ) | p y t h o n −

p y s q l i t e 2 (>= 2 . 3 . 0 − 1 ) | p y t h o n − p y s q l i t e 1 . 1 (>=

1 . 1 . 7 − 2 ) | p y t h o n − s q l i t e (>= 1 . 0 . 1 − 5 ) , p y t h o n −

k i n t e r b a s d b (>= 3 . 1 . 2 − 0 . 3 ) , p y t h o n − p y m s s q l

4 . .

Perhatikan bagian Suggests.

Bab 9

Lintas Sistem

Kita telah membahas mengenai manfaat mo dularitas dalam fungsi dan mo dul

dimana sebuah aplikasi disusun bagaikan sebuah lego. Jika keseluruhan sistem

semakin kompleks maka hindari #konsep p emaksaan# sep erti #semua harus dit-

ulis dengan Python# atau #semua harus menggunakan PostgreSQL#. Kali ini kita

oba pahami bagaimana komunikasi antar sistem bisa terjadi tanpa p emaksaan

platform tertentu.

9.1 Command Line

Sript Python Anda membutuhkan informasi mengenai network devie b erikut

IP-nya. Anda tidak tahu mo dul apa yang bisa digunakan. Namun Anda tahu

b etul bahwa ommand line ifon#g sanggup melakukannya.

1 $ i f o n f i g
2 e t h 0 L i n k e n a p : E t h e r n e t HWaddr 0 0 : 2 5 : b 3 : 7 7 : 3 e : 9
9

3 i n e t a d d r : 1 9 2 . 1 6 8 . 1 1 . 1 1 1 B a s t : 1 9 2 . 1 6 8 . 1 1 . 2
5 5

M a s k : 2 5 5 . 2 5 5 . 2 5 5 . 0

4 UP BROADCAST MULTICAST MTU: 1 5 0 0 M e t r i : 1

5 RX p a k e t s : 0 e r r o r s : 0 d r o p p e d : 0 o v e r r u n s : 0

f r a m e : 0

6 TX p a k e t s : 0 e r r o r s : 0 d r o p p e d : 0 o v e r r u n s : 0

a r r i e r : 0

7 o l l i s i o n s : 0 t x q u e u e l e n : 1 0 0 0

8 RX b y t e s : 0 ( 0 . 0 B ) TX b y t e s : 0 ( 0 . 0 B )

9 I n t e r r u p t : 1 7

10

11 l o L i n k e n a p : L o a l L o o p b a k

12 i n e t a d d r : 1 2 7 . 0 . 0 . 1 M a s k : 2 5 5 . 0 . 0 . 0

13 i n e t 6 a d d r : : : 1 / 1 2 8 S o p e : H o s t

14 UP LOOPBACK RUNNING MTU: 1 6 4 3 6 M e t r i : 1

80

BAB 9. LINTAS SISTEM 81

15 RX p a k e t s : 5 6 2 e r r o r s : 0 d r o p p e d : 0 o v e r r u n s : 0

f r a m e : 0

16 TX p a k e t s : 5 6 2 e r r o r s : 0 d r o p p e d : 0 o v e r r u n s : 0

a r r i e r : 0

17 o l l i s i o n s : 0 t x q u e u e l e n : 0

18 RX b y t e s : 5 4 0 8 4 8 ( 5 4 0 . 8 KB ) TX b y t e s : 5 4 0 8 4 8

( 5 4 0 . 8 KB )

19

20 w l a n 0 L i n k e n a p : E t h e r n e t HWaddr 0 0 : 1 f : 3 : e 0 : 6 6 :
5 6

21 i n e t a d d r : 1 9 2 . 1 6 8 . 1 . 4 B a s t : 1 9 2 . 1 6 8 . 1 . 2 5 5
M a s k : 2 5 5 . 2 5 5 . 2 5 5 . 0

22 i n e t 6 a d d r : f e 8 0 : : 2 1 f : 3 f f : f e e 0 : 6 6 5 6 / 6 4 S o p
e :

L i n k

23 UP BROADCAST RUNNING MULTICAST MTU: 1 5 0 0

M e t r i : 1

24 RX p a k e t s : 3 2 1 9 e r r o r s : 0 d r o p p e d : 0 o v e r r u n s : 0

f r a m e : 0

25 TX p a k e t s : 3 6 0 8 e r r o r s : 0 d r o p p e d : 0 o v e r r u n s : 0

a r r i e r : 0

26 o l l i s i o n s : 0 t x q u e u e l e n : 1 0 0 0

27 RX b y t e s : 1 5 8 6 2 9 7 ( 1 . 5 MB) TX b y t e s : 7 6 1 1 7 3

( 7 6 1 . 1 KB )

Bagaimana memanggil ommand line di sript Python dan mengolah hasil-

nya ? Gunakan mo dul ommands. Buatlah netdev.py b erikut ini.

Listing 9.1: netdev.py

1 i m p o r t o m m a n d s

2 i m p o r t r e

4 d e f n e t d e v ( ) :

5 r = { }

6 f o r l i n e i n o m m a n d s . g e t o u t p u t ( ' i f 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 m a t h = r e . o m p i l e ( ' ( . * ) L i n k e n a p ( . * ) ' ) . s e a
r h (

l i n e )

9 i f m a t h :

10 d e v i e = m a t h . g r o u p ( 1 ) . s t r i p ( )

11 r [ d e v i e ℄ = { }
12 m a t h = r e . o m p i l e ( ' HWaddr ( . * ) ' ) . s e a r h ( l i n e

13 i f m a t h :

14 r [ d e v i e ℄ [ ' a d d r ' ℄ = m a t h . g r o u p ( 1 )

15 o n t i n u e

16 m a t h = r e . o m p i l e ( ' i n e t a d d r : ( . * ) ' ) . s e a r h (
l i n e )

BAB 9. LINTAS SISTEM 82

17 i f m a t h :

18 r [ d e v i e ℄ [ ' i p ' ℄ = m a t h . g r o u p ( 1 ) . s p l i t ( ) [ 0 ℄

19 r e t u r n r

20

21

22 i f __name__ == ' __main__ ' :

23 n d = n e t d e v ( )

24 f o r d e v i n n d :

25 p r i n t d e v , n d [ d e v ℄

Jalankan.

1 $ p y t h o n n e t d e v . p y

2 w l a n 0 { ' i p ' : ' 1 9 2 . 1 6 8 . 1 . 4 ' , ' a d d r ' : ' 0 0 : 1 f : 3


: e 0 : 6 6 : 5 6 ' }

3 l o { ' i p ' : ' 1 2 7 . 0 . 0 . 1 ' }

4 e t h 0 { ' i p ' : ' 1 9 2 . 1 6 8 . 1 1 . 1 1 1 ' , ' a d d r ' : ' 0 0 : 2 5 :


b 3 : 7 7 : 3 e

: 9 9 ' }

Lintas sistem yang menggunakan ommand line ini tergolong lokal, artinya

netdev.py harus b erada di komputer yang sama dengan ifon#g.

9.2 File

File bisa digunakan sebagai sarana p emersatu input dan output. Misalkan An-

da sudah membuat sebuah daemon yang dapat menerima dan mengirim SMS.

Daemon ini p engendali mo dem. Oh ya, daemon adalah program yang selalu
hidup untuk siap menerima p erintah.

Di sisi lain Anda juga punya program p enerjemah SMS yang masuk (SMS

parser) dan juga b erfungsi untuk membalas ke si p engirim. Bagaimana kedua

program ini dapat b erhubungan ?

Anda bisa menggunakan #le sebagai p erantara. Saat ada SMS masuk, dae-

mon p engendali mo dem menyimpannya dalam sebuah #le di direktori /var/sp o ol/-

mo dem/inb ox. Kemudian SMS parser membaa direktori ini, menerjemahkan

#lenya, dan membalas SMS tersebut dengan ara membuat #le di direktori

/var/sp o ol/mo dem/outb ox. File tersebut dibaa oleh daemon si mo dem untuk

kemudian mengirim SMS yang dimaksud.

Baik daemon mo dem maupun SMS parser bisa ditulis dengan bahasa yang

b erb eda. Mungkin yang p ertama dengan C++, sementara yang satunya di tulis

dengan Python. Namun keduanya b ekerja menggunakan direktori yang sama.

Ini juga tergolong lintas sistem yang lokal, keduanya harus di komputer yang

sama.

Dengan teknik NFS atau Samba Anda bisa membuat direktori b ersama

(sharing diretory) di komputer lain (remote host).

BAB 9. LINTAS SISTEM 83

9.3 Database

Pelanggan Anda telah memiliki sebuah sistem p engisian pulsa dimana terdapat

fungsi yang b erkaitan dengan GSM mo dem. Fungsi yang dimaksud adalah yang

b erkaitan dengan SMS gateway yaitu mengirim dan menerima SMS.

Pelanggan ini telah membuat sistemnya menggunakan Borland Delphi (ba-

hasa Pasal) dan menggunakan database MySQL. Ia mengeluh pada Anda se-

laku develop er outsouring dimana komp onen SMS gateway yang dibangun-

nya tidak stabil. Di sisi lain Anda telah membuat SMS gateway yang ditulis

dengan bahasa Python dan database PostgreSQL. Tidak sep erti yang dimiliki

p elanggan tersebut, SMS gateway yang Anda buat sangat stabil dan telah teruji

b ertahun-tahun. Masalah p enyatuan semakin b ertambah dimana SMS gateway


Anda b erada di sistem op erasi Linux, sementara p elanggan Anda menggunakan

Mirosoft Windows.

Langkah apa yang diambil untuk membuat SMS gateway-nya stabil ? An-

da b ela jar Borland Delphi untuk menerjemahkan algoritma Python ? Atau

memaksa p elanggan Anda itu untuk b ela jar Python dan membangun ulang

sistem p engisian pulsanya ?

Langkah yang bijaksana tentu tidak keduanya, karena p orsi tidak seimbang

yang mengakibatkan p enyatuan menjadi sangat lama. Solusi sederhana adalah

menggunakan database sebagai p erantara. Mintalah padanya untuk menyedi-

akan sebuah komputer lagi untuk SMS gateway Anda, sebut sa ja server SMS

gateway. Server ini terhubung melalui LAN (lo al area network) dengan server

p engisian pulsa yang b erbasis Windows tadi.

Tanpa p erubahan ? Tentu sa ja ada.

Ranangan SMS gateway yang Anda buat harus dapat mengirim SMS hanya

dengan menggunakan p erintah INSERT. Contoh:

1 INSERT INTO i m . a n t r i a n ( p e n e r i m a , p e s a n ) SELECT '

+ 6 2 8 1 7 7 6 5 4 3 2 1 ' , ' S e l a m a t b e r g a b u n g ' ;

Lalu apa yang dilakukan oleh p elanggan Anda tadi ? Ia p erlu mengubah

soure Borland Delphi-nya, yaitu pada fungsi p engiriman SMS menggunakan

koneksi ke database PostgreSQL yang ada di server SMS gateway. Biasanya

driver ODBC dapat mengatasi hal ini.

Lho, bukankah ia menggunakan MySQL sebagai database ? Benar, MySQL

untuk komp onen p engisian pulsa tetap b erlaku. Jadi dalam aplikasi Borland

Delphi terdapat dua koneksi database, yaitu ke MySQL yang ada di lo alhost

Mirosoft Windows, dan ke PostgreSQL yang ada di remote host Linux.

Lalu bagaimana untuk membaa SMS yang masuk ? Kembali, Anda diminta

untuk menyimpan SMS yang masuk ke dalam sebuah tab el, katakanlah b ernama

inb ox. Selanjutnya p elanggan Anda dapat membaanya menggunakan p erintah

SELECT pada Borland Delphi.

1 SELECT * FROM i m . a n t r i a n WHERE NOT k i r i m ;


Mudah bukan ? Lebih lanjut mengenai SMS gateway bisa lihat halaman115.

BAB 9. LINTAS SISTEM 84

Lintas sistem ini tergolong bisa b eda komputer, karena baik PostgreSQL

maupun MySQL dapat diakses melalui jalur network.

9.4 XMLRPC

Database sebagai p erantara bisa jadi ditolak dengan b erbagai alasan. Salah

satunya adalah asp ek tanggung jawab, atau biasa disebut asp ek keamanan (se-

urity). Misalkan dalam sistem p erbankan. Sistem utama sebuah bank diban-

gun oleh PT Software Aman Banget (SAB). Namanya juga sistem utama, ia

memuat data p enting nasabah serta data yang menyangkut sistem.

Suatu saat bank ini ingin go Internet dimana nasabah dapat melakukan

transaksi melalui browser Firefox. Berarti dibutuhkan web develop er dan dip-

ilihlah PT Web Perkasa (WP) untuk mengembangkannya. Karena mengem-

bangkan Internet banking, b erarti ada proses login untuk nasabah. Ini b erarti

ada algoritma p emeriksaan username dan password. Sampai disini tidaklah

menjadi masalah karena username dan password web bisa b erada di web server

yang dibangun oleh WP.

Tibalah saatnya nasabah ingin melihat mutasi transaksinya. Apakah WP

melakukan SELECT tab el ke sistem utama bank tersebut yang dibangun oleh

SAB ?

Mayoritas jawabannya tidak. Mengapa ?

SELECT b erarti kita biara koneksi ke database. Itu artinya WP menge-

tahui username dan password untuk login ke database sistem utama. Kalau

sudah b egitu maka WP bisa melihat-lihat data nasabah lainnya, bahkan meli-

hat tab el-tab el yang menyangkut sistem. Jelas ini sudah terlalu jauh dan bisa

menimbulkan hal-hal yang tak p erlu.

Untuk menghindari koneksi database ke sistem utama, maka digunakanlah

XMLRPC sebagai p erantaranya. Makanan apakah ini ?

XMLRPC adalah XML Remote Pro edure Call, yaitu sebuah #bahasa# p er-
tukaran data yang ditulis dalam format XML. Kita dapat memandang RPC

sebagai p emanggilan fungsi yang memiliki nilai masukan (input parameter) dan

nilai keluaran (output / return value). Sebagaimana fungsi sederhana ini.

1 d e f t a m b a h ( a , b ) :

2 r e t u r n a + b

XMLRPC bisa juga disebut sebagai web servie karena dokumen XML

tersebut dikirim menggunakan HTTP atau HTTPS dengan metho d POST.

Karena web servie, maka kita biara koneksi lient - server, sehingga ada

p enyebutan XMLRPC lient dan XMLRPC server. Penggunaannya tergolong

simple dan pustakanya (library) banyak tersedia untuk b erbagai bahasa sep erti

Python, PHP, Java, Borland Delphi, Visual Basi, dst.

Kembali pada web develop er di atas. WP mengembangkan web-nya menggu-

nakan PHP, sementara SAB mengembangkan sistem bank menggunakan Python.

Database keduanya juga b erb eda dimana WP menggunakan MySQL, sedangkan

SAB menggunakan PostgreSQL. Namun semuanya itu tidak lagi menjadi hal.

BAB 9. LINTAS SISTEM 85

Langkah apa yang harus dikembangkan terlebih dahulu ?

Jelas bahwa SAB harus mengembangkan XMLRPC server terlebih dahulu

yang b erisi fungsi mutasi(). Mari kita mulai membuat #le serverbank.py.

Listing 9.2: serverbank.py

1 f r o m S i m p l e X M L R P C S e r v e r i m p o r t S i m p l e X M L R P C S
e r v e r

2 i m p o r t s q l a l h e m y a s s a

5 l a s s S e r v e r ( S i m p l e X M L R P C S e r v e r ) :

6 a l l o w _ r e u s e _ a d d r e s s = T r u e

8 d e f v e r i f y _ r e q u e s t ( s e l f , r e q u e s t , l i e n t _ a d d
r e s s ) :

9 s e r v e r . i p _ l i e n t = l i e n t _ a d d r e s s [ 0 ℄
10 p r i n t s e r v e r . i p _ l i e n t

11 r e t u r n s e r v e r . i p _ l i e n t i n [ ' 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 d e f r e s p ( o d e , m s g ) :

15 r e t u r n { ' k o d e ' : o d e ,

16 ' p e s a n ' : m s g }

17

18

19 l a s s A g e n t :

20 d e f _ d i s p a t h ( s e l f , m e t h o d , p a r a m s = ( ) ) :

21 p r i n t m e t h o d , p a r a m s

22 t r y :

23 f u n = g e t a t t r ( s e l f , ' e x p o r t _ ' + m e t h o d )

24 e x e p t A t t r i b u t e E r r o r :

25 r e t u r n r e s p ( − 1 , ' F u n g s i %s t i d a k d i k e n a l ' %

m e t h o d )

26 r e t u r n f u n ( * p a r a m s )

27

28 d e f e x p o r t _ m u t a s i ( s e l f , p ) :

29 s q l = "SELECT t g l : : d a t e , k e t , n o m i n a l , s a l d o
" +

30 "FROM t r a n s a k s i WHERE p i d = %d " + \

31 "AND t g l : : d a t e BETWEEN ' % s ' AND ' % s ' " + \

32 "ORDER BY i d "

33 s q l = s q l % ( p [ ' p i d ' ℄ , p [ ' a w a l ' ℄ , p [ ' a k h i r ' ℄ )

34 q = d b . e x e u t e ( s q l )

35 m = [ ℄
36 f o r r i n q :

37 m . a p p e n d ( [ s t r ( r . t g l ) , r . k e t , r . n o m i n a l , r .

s a l d o ℄ )

BAB 9. LINTAS SISTEM 86

38 r = r e s p ( 0 , 'OK ' )

39 r [ ' m u t a s i ' ℄ = m

40 r e t u r n r

41

42

43

44 u r l = ' p o s t g r e s q l : / / i l h a m : 1 2 3 4 # l o a l h o s t / t o
t a l i n d o '

45 d b = s a . r e a t e _ e n g i n e ( u r l )

46

47 p o r t = 9 3 0 3

48 s e r v e r = S e r v e r ( ( ' 0 . 0 . 0 . 0 ' , p o r t ) )

49 s e r v e r . r e g i s t e r _ i n t r o s p e t i o n _ f u n t i o n s ( )

50 s e r v e r . r e g i s t e r _ i n s t a n e ( A g e n t ( ) )

51 p r i n t ' HTTP XMLRPC s e r v e r p o r t ' , p o r t

52 s e r v e r . s e r v e _ f o r e v e r ( )

Jalankan.

1 $ p y t h o n s e r v e r b a n k . p y

2 HTTP XMLRPC s e r v e r p o r t 9 3 0 3

Proses seolah hang, tapi seb enarnya ia sedang menunggu p ermintaan (re-

quest) dari XMLRPC lient. Port 9303 hanya ontoh sa ja dimana Anda bisa

mengganti dengan nilai lainnya. Seurity yang diterapkan di sini adalah IP

lient yang hanya menerima p ermintaan dari 127.0.0.1 dan 192.168.0.1.

Selanjutnya membuat XMLRPC lient b ernama lientbank.py.

Listing 9.3: lientbank.py

1 i m p o r t x m l r p l i b
2

3 u r l = ' h t t p : / / 1 2 7 . 0 . 0 . 1 : 9 3 0 3 '

4 r e m o t e = x m l r p l i b . S e r v e r P r o x y ( u r l )

5 d = { ' p i d ' : 1 ,

6 ' a w a l ' : ' 2 0 1 0 1 0 2 2 ' ,

7 ' a k h i r ' : ' 2 0 1 0 1 0 2 3 ' }

8 r = r e m o t e . m u t a s i ( d )

9 i f r [ ' k o d e ' ℄ == 0 :

10 f o r t g l , k e t , n o m i n a l , s a l d o i n r [ ' m u t a s i ' ℄ :

11 p r i n t t g l , k e t . l j u s t ( 1 5 ) , \

12 s t r ( i n t ( n o m i n a l ) ) . r j u s t ( 1 0 ) , \

13 s t r ( i n t ( s a l d o ) ) . r j u s t ( 1 0 )

14 e l s e :

15 p r i n t r [ ' p e s a n ' ℄

Bukalah konsole lainnya, lalu jalankan #le ini.

1 $ p y t h o n l i e n t b a n k . p y

2 2 0 1 0 − 1 0 − 2 2 GAJI 1 1 − 2 0 1 0 3 0 0 0 0 0 0 3 0 0 0 0 0 0

3 2 0 1 0 − 1 0 − 2 2 BON − 2 0 0 0 0 0 2 8 0 0 0 0 0

BAB 9. LINTAS SISTEM 87

Cermati baik-baik konsepnya. Juga p erhatikan tip e data ditionary dan list

yang digunakan sebagai nilai keluaran (return value) dari fungsi mutasi.

9.4.1 PHP sebagai XMLRPC Client

Unduh xmlrp .in dari http://phpxmlrp .soureforge.net. File itu b erada di

xmlrp -2.2.2.tar.gz. Carilah. Versi lain sep ertinya juga tidak masalah. Lalu

buatlah #le lientbank.php.

Listing 9.4: lientbank.php

1 <? p h p

2 i n l u d e ( ' x m l r p . i n ' ) ;

3 $ p a r a m s = n e w x m l r p v a l (
4 a r r a y (

5 ' p i d ' => n e w x m l r p v a l ( 1 , ' i n t ' ) ,

6 ' a w a l ' => n e w x m l r p v a l ( ' 2 0 1 0 1 0 2 2 ' ) ,

7 ' a k h i r ' => n e w x m l r p v a l ( ' 2 0 1 0 1 0 2 3 ' )

8 ) ,

9 ' s t r u t '

10 ) ;

11 $ f = n e w x m l r p m s g ( ' m u t a s i ' , a r r a y ( $ p a r a m s ) ) ;

12 $ = n e w x m l r p _ l i e n t ( ' / ' , ' 1 2 7 . 0 . 0 . 1 ' , 9 3 0 3 ) ;

13 $ r = $ − >s e n d ( $ f ) ;

14 $ v = $ r − > v a l u e ( ) ;

15 i f ( $ r − > f a u l t C o d e ( ) ) {

16 p r i n t $ r − > f a u l t S t r i n g ( ) ;

17 } e l s e {

18 $ r e s p = $ r − > s a l a r v a l ( ) ;

19 i f ( $ r e s p [ ' k o d e ' ℄ − > s a l a r v a l ( ) == 0 ) {

20 f o r e a h ( $ r e s p [ ' m u t a s i ' ℄ − > s a l a r v a l ( ) a s $ i


=>$m ) {

21 $ f = $m − > s a l a r v a l ( ) ;

22 $ t g l = $ f [ 0 ℄ − > s a l a r v a l ( ) ;

23 $ k e t = $ f [ 0 ℄ − > s a l a r v a l ( ) ;

24 $ n o m i n a l = $ f [ 0 ℄ − > s a l a r v a l ( ) ;

25 $ s a l d o = $ f [ 0 ℄ − > s a l a r v a l ( ) ;

26 p r i n t $ t g l . " " .

27 s t r _ p a d ( $ k e t , 2 0 ) . " " .

28 s t r _ p a d ( $ n o m i n a l , 1 0 ) . " " .

29 s t r _ p a d ( $ s a l d o , 1 0 ) . " \ n " ;

30 }

31 } e l s e {
32 p r i n t $ r e s p [ ' p e s a n ' ℄ − > s a l a r v a l ( ) ;

33 }

34 }

35 ?>

BAB 9. LINTAS SISTEM 88

Karena sript ini akan kita jalankan sebagai ommand line, maka pasang

dulu paket terkait.

1 $ s u d o a p t − g e t i n s t a l l p h p 5 − l i

Lalu jalankan.

1 $ p h p l i e n t _ b a n k . p h p

2 2 0 1 0 − 1 0 − 2 2 GAJI 1 1 − 2 0 1 0 3 0 0 0 0 0 0 3 0 0 0 0 0 0

3 2 0 1 0 − 1 0 − 2 2 BON − 2 0 0 0 0 0 2 8 0 0 0 0 0

9.4.2 Drupal

Drupal
1

juga ditulis dengan PHP. Ia sudah memuat funtion xmlrp , sehingga

Anda tidak p erlu memasang mo dul tambahan. Cara p enulisannya juga lebih

mudah. Contoh b erikut ini untuk Drupal 6.

Buatlah #le sites/all/mo dules/p egawai/p egawai.mo dule b erikut.

Listing 9.5: p egawai.mo dule

1 <? p h p

2 f u n t i o n p e g a w a i _ m e n u ( ) {

3 $ i t e m s = a r r a y ( ) ;

4 $ i t e m s [ ' p e g a w a i / t r x /%/%/% ' ℄ = a r r a y (

5 ' t i t l e ' => ' T r a n s a k s i ' ,

6 ' p a g e a l l b a k ' => ' p e g a w a i _ t r x ' ,

7 ' p a g e a r g u m e n t s ' => a r r a y ( 2 , 3 , 4 ) ,

8 ' a e s s a l l b a k ' => ' u s e r _ a e s s ' ,

9 ' t y p e ' => MENU_CALLBACK,

10 ) ;
11 r e t u r n $ i t e m s ;

12 }

13

14 f u n t i o n p e g a w a i _ t r x ( $ p i d , $ a w a l , $ a k h i r ) {

15 $ u r l = ' h t t p : / / 1 2 7 . 0 . 0 . 1 : 9 3 0 3 ' ;

16 $ p = a r r a y ( ' p i d ' => i n t v a l ( $ p i d ) ,

17 ' a w a l ' => $ a w a l ,

18 ' a k h i r ' => $ a k h i r ) ;

19 $ r = x m l r p ( $ u r l , ' m u t a s i ' , $ p ) ;

20 i f ( ! $ r [ ' m u t a s i ' ℄ ) {

21 r e t u r n d r u p a l _ s e t _ m e s s a g e ( ' T i d a k a d a d a t a
' ) ;

22 }

23 $ = '< t a b l e ><t h >T a n g g a l </ t h ><t h >K e t e r a n g a n </ t h


> ' .

24 '<t h >N o m i n a l </ t h ><t h >S a l d o </ t h ></ t r > ' ;

25 f o r e a h ( $ r [ ' m u t a s i ' ℄ a s $ i => $ f ) {

26 $ t g l = $ f [ 0 ℄ ;

http://drupal.org

BAB 9. LINTAS SISTEM 89

27 $ k e t = $ f [ 1 ℄ ;

28 $ n o m i n a l = $ f [ 2 ℄ ;

29 $ s a l d o = $ f [ 3 ℄ ;

30 $ . = '< t r ><t d > ' . $ t g l . ' </ t d > ' ;

31 $ . = '<t d > ' . $ k e t . ' </ t d > ' ;

32 $ . = '< t d a l i g n =" r i g h t "> ' . f o r m a t _ n u m b e r ( $ n o


m i n a l ) .

' </ t d > ' ;

33 $ . = '< t d a l i g n =" r i g h t "> ' . f o r m a t _ n u m b e r ( $ s a


l d o ) . '

</ t d > ' ;


34 $ . = ' </ t r > ' ;

35 }

36 r e t u r n $ ;

37 }

38 ?>

Juga buat sites/all/mo dules/p egawai/p egawai.info.

Listing 9.6: p egawai.info

1 n a m e = P e g a w a i

2 d e s r i p t i o n = D a t a p e g a w a i

3 o r e = 6 . x

4 v e r s i o n = " 6 . x − 1 . 0 "

Setelah login di browser, masuklah ke menu admin/build/mo dules. Centang

mo dul p egawai dan klik Save. Lalu masukkan URL di browser sep erti

pegawai/trx/1/20101022/20101023

Bab 10

Pengemasan

10.1 Paket Debian

Pada bab seb elumnya kita sudah membuat mo dul uang.py. Agar mo dul ini dap-

at digunakan oleh user lainnya maka diletakkanlah di direktori /usr/lo


al/lib/python2.6/dist-

pakages. Proses opy mo dul sep erti ini memang sudah mudah, tapi ada lagi

yang lebih memudahkan, yaitu dengan mengemasnya dalam b entuk paket De-

bian.

Langkah kemudahan yang dimaksud adalah:

1. Tambahkan URL daftar paket dalam sebuah #le /et/apt/soures.list.d/ustom.list

yang b erisi

deb http://192.168.0.1/deb ./

2. Perbaharui daftar paket

$ sudo apt-get up date

3. Pasang paket dimaksud


$ sudo apt-get install python-uang

Manfaat lain p emaketan adalah mudahnya p emasangan paket lainnya yang

dibutuhkan oleh paket utama, sering disebut sebagai dep endenies . Misalkan

paket python-uang tadi membutuhkan python-sqlalhemy, maka pada saat

1 $ s u d o a p t − g e t i n s t a l l p y t h o n − u a n g

otomatis python-sqlalhemy juga ikut dipasang.

Penamaan python-uang dimana ada awalan python- dikarenakan

uang.py adalah mo dul Python yang umum. Dengan kata lain bisa

digunakan di aplikasi apa sa ja. Tidak ada koneksi database di

sana. Juga tidak ada p erintah akses database sep erti SELECT dkk.

Awalan ini juga meniru dari paket umum lainnya sep erti python-

sqlalhemy, python-psyopg2, python-serial, dst.

90

BAB 10. PENGEMASAN 91

Mulailah membuat direktori kerja, yaitu /usr/lo al/sr/python-uang.

1 $ s u d o m k d i r − p / u s r / l o a l / s r / p y t h o n − u a n g /DEBIAN

Perintah ini otomatis membuat dua buah direktori yaitu

1. /usr/lo al/sr/python-uang

2. /usr/lo al/sr/python-uang/DEBIAN

Direktori DEBIAN digunakan untuk meletakkan #le-#le yang b erkaitan dengan

sistem paket sep erti

ontrol b erisi informasi seputar paket.

p ostinst sript yang dijalankan saat p emasangan b erlangsung, yaitu saat apt-

get install atau dpkg -i. Sript ini harus exeutable yang bisa diset dengan

hmo d 755.

prerm sript yang dijalankan saat p enghapusan b erlangsung, yaitu saat apt-

get remove atau dpkg -r. Sript ini juga harus exeutable.

on#les b erisi daftar nama #le kon#gurasi yang digunakan paket ini. Misalnya

b erisi /et/uang.onf. File kon#gurasi ini b erisi format negara yang di-
gunakan oleh fungsi uang(). Jadi tidak hard-o de menggunakan lo ale

id_ID.UTF-8. Dengan b egitu python-uang semakin umum (general).

Dengan didaftarkannya /et/uang.onf di dalam on#les, maka terhin-

dar dari p enibanan (timpa / overwrite) saat upgrade b erlangsung. Mis-

alkan kini python-uang versi 0.1. Kemudian dibuatlah versi 0.2 yang juga

memuat /et/uang.onf. Jika di dalam versi 0.2 tidak ada p erubahan

apa-apa pada /et/uang.onf maka apt-get install tidak akan melakukan

timpa pada /et/uang.onf yang sudah terpasang . Karena siapa tahu

Anda sudah mengganti isi /et/uang.onf terpasang dengan de_DE.ISO-

8859-1. Dengan b egitu kita terhindar dari mengubah ulang kon#gurasi.

Mudah-mudahan paham maksudnya.

Mulailah membuat #le python-uang/DEBIAN/ontrol.

Listing 10.1: DEBIAN/ontrol

1 P a k a g e : p y t h o n − u a n g

2 P r i o r i t y : o p t i o n a l

3 S e t i o n : p y t h o n

4 M a i n t a i n e r : Owo S u g i a n a < s u g i a n a # r a b . o . i d >

5 A r h i t e t u r e : a l l

6 V e r s i o n : 0 . 1

7 D e p e n d s : p y t h o n − e n t r a l (>= 0 . 6 . 7 )

8 P y t h o n − V e r s i o n : a l l

9 D e s r i p t i o n : F o r m a t u a n g

Lanjutkan dengan membuat direktori mo dulnya.

BAB 10. PENGEMASAN 92

1 $ d / u s r / l o a l / s r

2 $ s u d o m k d i r − p p y t h o n − u a n g / u s r / s h a r e / p y e n t r
a l / p y t h o n −

u a n g / s i t e −p a k a g e s

Perhatikanlah direktori setelah /usr/lo al/sr/python-uang. Semua direk-

tori tersebut nantinya akan dipasang di ro ot diretory ( / ), keuali direktori


DEBIAN.

Lalu mengapa menggunakan /usr/share ? Padahal seb elumnya kita mele-

takkan uang.py di /usr/lo al ? Direktori /usr/lo al yang kita gunakan seb elum-

nya b ermakna bahwa uang.py b elum menjadi bagian dari paket Debian. Bila

sudah menjadi bagian dari paket Debian, maka diletakkan di /usr/share. Begi-

tulah ketentuan umumnya.

1 $ s u d o p / u s r / l o a l / l i b / p y t h o n 2 . 6 / d i s t −p a k a g
e s / u a n g . p y

p y t h o n − u a n g / u s r / s h a r e / p y e n t r a l / p y t h o n − u a n
g / s i t e −

p a k a g e s /

Karena akan menggunakan /et/user.onf, lakukan p erubahan pada uang.py

menjadi b erikut ini.

Listing 10.2: usr/share/pyentral/python-uang/site-pakages/uang.py

1 i m p o r t l o a l e

2 f r o m C o n f i g P a r s e r i m p o r t C o n f i g P a r s e r

4 o n f = C o n f i g P a r s e r ( )

5 o n f . r e a d ( ' / e t / u a n g . o n f ' )

7 l o a l e . s e t l o a l e ( l o a l e . LC_ALL, o n f . g e t ( ' d e f a u
l t ' , '

l o a l e ' ) )

9 DECIMAL = o n f . g e t i n t ( ' d e f a u l t ' , ' d e i m a l ' )

10

11

12 d e f u a n g ( n i l a i , p e a h a n=N o n e ) :

13 i f p e a h a n i s N o n e :

14 i f t y p e ( n i l a i ) == t y p e ( 0 ) :

15 p e a h a n = 0
16 e l s e :

17 p e a h a n = DECIMAL

18 r e t u r n l o a l e . f o r m a t ( ' %%.% d f ' % p e a h a n , n i l a i ,


T r u e )

19

20

21 i f __name__ == ' __main__ ' :

22 n = 1 0 0 0 0 . 5

23 p r i n t u a n g ( n )

24 p r i n t u a n g ( i n t ( n ) )

25 p r i n t u a n g ( n , 3 )

BAB 10. PENGEMASAN 93

Buat direktori et.

1 $ s u d o m k d i r − p p y t h o n − u a n g / e t

Selanjutnya buat python-uang/et/uang.onf.

Listing 10.3: et/uang.onf

1 [ d e f a u l t ℄

2 l o a l e = i d _ I D . UTF − 8

3 d e i m a l = 2

Lalu buat python-uang/DEBIAN/on#les b erisi satu baris b erikut.

Listing 10.4: DEBIAN/on#les

1 / e t / u a n g . o n f

Kemudian buat python-uang/DEBIAN/p ostinst yang b erisi p erintah untuk

mendaftarkan uang.py agar dikenal sebagai mo dul.

Listing 10.5: DEBIAN/p ostinst

1 # ! / b i n / s h

2 p y e n t r a l p k g i n s t a l l p y t h o n − u a n g

Juga python-uang/DEBIAN/prerm.

Listing 10.6: DEBIAN/prerm

1 # ! / b i n / s h
2 p y e n t r a l p k g r e m o v e p y t h o n − u a n g

Buat keduanya exeutable.

1 $ s u d o h m o d 7 5 5 p y t h o n − u a n g /DEBIAN / p o s t i n s t

2 $ s u d o h m o d 7 5 5 p y t h o n − u a n g /DEBIAN / p r e r m

Pastikan semua #le dimiliki ro ot.

1 $ s u d o h o w n − R r o o t . r o o t p y t h o n − u a n g

Lihat lagi apa yang sudah dibuat.

1 $ f i n d p y t h o n − u a n g

2 p y t h o n − u a n g /

3 p y t h o n − u a n g /DEBIAN

4 p y t h o n − u a n g /DEBIAN / o n t r o l

5 p y t h o n − u a n g /DEBIAN / p r e r m

6 p y t h o n − u a n g /DEBIAN / o n f f i l e s

7 p y t h o n − u a n g /DEBIAN / p o s t i n s t

8 p y t h o n − u a n g / u s r

9 p y t h o n − u a n g / u s r / s h a r e

10 p y t h o n − u a n g / u s r / s h a r e / p y e n t r a l

11 p y t h o n − u a n g / u s r / s h a r e / p y e n t r a l / p y t h o n − u a
n g

12 p y t h o n − u a n g / u s r / s h a r e / p y e n t r a l / p y t h o n − u a
n g / s i t e − p a k a g e s

BAB 10. PENGEMASAN 94

13 p y t h o n − u a n g / u s r / s h a r e / p y e n t r a l / p y t h o n − u a
n g / s i t e − p a k a g e s

/ u a n g . p y

14 p y t h o n − u a n g / e t

15 p y t h o n − u a n g / e t / u a n g . o n f

Kemas.

1 $ s u d o d p k g − d e b −− b u i l d p y t h o n − u a n g .

2 d p k g − d e b : p e r i n g a t a n : ' p y t h o n − u a n g /DEBIAN / o n t
r o l '
o n t a i n s u s e r − d e f i n e d f i e l d ' P y t h o n − V e r s i o n '

3 d p k g − d e b : m e m b u a t p a k e t ` p y t h o n − u a n g ' d i d a l a m
` . / p y t h o n −

u a n g _ 0 . 1 _ a l l . d e b ' .

4 d p k g − d e b : p e r i n g a t a n : i g n o r i n g 1 w a r n i n g s a b o u
t t h e

o n t r o l f i l e ( s )

Perhatikan ada titik diakhirnya yang b erarti letakkan di urrent diretory.

Abaikan sa ja p eringatan itu. Karena Python-Version memang bukan standar

Debian, tapi digunakan oleh pyentral. Sampai di sini p embuatan paket selesai.

Kini telah terb entuk python-uang_0.1_all.deb yang siap dipasang.

1 $ s u d o d p k g − i p y t h o n − u a n g _ 0 . 1 _ a l l . d e b

2 M e m i l i h p a k e t p y t h o n − u a n g y a n g s e b e l u m n y a t i d a
k d i p i l i h .

3 ( S e d a n g m e m b a a b a s i s d a t a . . . 2 1 3 4 5 8 b e r k a s d a n
d i r e k t o r i

t e l a h t e r p a s a n g . )

4 S e d a n g membuka p a k e t p y t h o n − u a n g ( d a r i p y t h o n − u a n
g _ 0 . 1

_ a l l . d e b ) . . .

5 S e d a n g m e n y e t e l p y t h o n − u a n g ( 0 . 1 ) . . .

6 P r o e s s i n g t r i g g e r s f o r p y t h o n − e n t r a l . . .

Untuk menghindari keranuan karena ada dua mo dul uang yang terpasang,

sebaiknya buang yang ada di /usr/lo al.

1 $ s u d o mv / u s r / l o a l / l i b / p y t h o n 2 . 6 / d i s t −p a k a g
e s / u a n g . p y

/ tmp

Lalu ujilah di mo dus interaktif.

1 $ p y t h o n

2 P y t h o n 2 . 6 . 5 ( r 2 6 5 : 7 9 0 6 3 , A p r 1 6 2 0 1 0 , 1 3 : 0 9 : 5 6
)

3 [ GCC 4 . 4 . 3 ℄ o n l i n u x 2

4 T y p e " h e l p " , " o p y r i g h t " , " r e d i t s " o r " l i e n s e


" f o r m o r e
i n f o r m a t i o n .

5 >>> f r o m u a n g i m p o r t u a n g

6 >>> u a n g ( 1 0 0 0 0 )

7 ' 1 0 . 0 0 0 '

Ujian terakhir hapuslah paket ini untuk memastikan sript DEBIAN/prerm

b erfungsi dengan baik.

1 $ s u d o a p t − g e t r e m o v e p y t h o n − u a n g

2 S e d a n g m e m b a a d a f t a r p a k e t . . . S e l e s a i

BAB 10. PENGEMASAN 95

3 Membangun p o h o n k e t e r g a n t u n g a n

4 Membaa i n f o r m a s i y a n g t e r s e d i a . . . S e l e s a i

5 P a k e t b e r i k u t a k a n DIHAPUS :

6 p y t h o n − u a n g

7 0 d i m u t a k h i r k a n , 0 b a r u t e r i n s t a l , 1 a k a n d i h a p u
s d a n 1 9 2

t i d a k a k a n d i m u t a k h i r k a n .

8 S e t e l a h o p e r a s i i n i , 0B r u a n g k o s o n g h a r d d i s k a k
a n

d i g u n a k a n .

9 A n d a i n g i n m e l a n j u t k a n [ Y/ t ℄ ?

10 ( S e d a n g m e m b a a b a s i s d a t a . . . 2 1 3 4 6 0 b e r k a s d a n
d i r e k t o r i

t e l a h t e r p a s a n g . )

11 S e d a n g membuang p y t h o n − u a n g . . .

10.2 Debian Rep ository

Kini saatnya membuat rep ository agar bisa di-apt-get dari komputer lain. Pasanglah

paket yang dibutuhkan untuk membaa #le-#le *.deb.

1 $ s u d o a p t − g e t i n s t a l l d p k g − d e v

Letakkan paketnya di tempat yang sudah ditentukan web server Apahe.

1 $ s u d o m k d i r / v a r /www/ d e b
2 $ s u d o p / u s r / l o a l / s r / p y t h o n − u a n g _ 0 . 1 _ a l l .
d e b / v a r /www

/ d e b

Lalu buatlah /var/www/deb/up date-list.sh. File ini digunakan untuk mem-

p erbaharui daftar paket yang tersedia.

Listing 10.7: up datelist.sh

1 rm − f P a k a g e s . g z

2 d p k g − s a n p a k a g e s −− a r h a l l . >/ d e v / n u l l > P a k a g
e s

3 g z i p −− b e s t P a k a g e s

Setiap ada paket baru jalankan #le ini.

1 $ d / v a r /www/ d e b

2 $ s u d o s h u p d a t e l i s t . s h

Akan terb entuk #le Pakages.gz. File inilah yang akan dibaa saat apt-get

up date.

Selanjutnya kita uji rep ository ini dengan membuat #le /et/apt/soures.list.d/
ustom.list.

Listing 10.8: /et/apt/soures.list.d/ustom.list

1 d e b h t t p : / / 1 9 2 . 1 6 8 . 0 . 1 / d e b . /

Perbaharui daftar paket.

1 $ s u d o a p t − g e t u p d a t e

BAB 10. PENGEMASAN 96

Pasang paket yang dimaksud.

1 $ s u d o a p t − g e t i n s t a l l p y t h o n − u a n g

10.3 Remastering Ubuntu

Untuk semakin memudahkan p emasangan, ada baiknya pasang paket-paket

yang dimaksud ke dalam sebuah #le ISO. Bukan hanya memasang, bahkan An-

da bisa mengkon#gurasi seara manual untuk memastikan p emasangan Linux

Ubuntu dan aplikasi yang dimaksud b erlangsung lanar dan mudah .

Mulailah pasang paket yang dibutuhkan.

1 $ s u d o a p t − g e t i n s t a l l s q u a s h f s − t o o l s m k i s o f s
Buat #le onf.

Listing 10.9: remaster/onf

1 SOURCE=" / h o m e / s u g i a n a / U n d u h a n / b l a n k o n − 6 . 0 − d l
i v e − i 3 8 6 . i s o

"

2 TARGET=" b l a n k o n − 6 . 0 − d l i v e − s o h o − i 3 8 6 . i s o "

3 LABEL=" B l a n k O n 6 SOHO"

Sesuaikanlah ketiganya. Kemudian buat #le 1-extrat.sh:

Listing 10.10: remaster/1-extrat.sh

1 . . / o n f

2 m k d i r − p / tmp / d r o m / tmp / r o o t

3 m o u n t − o l o o p $SOURCE / tmp / d r o m

4 r s y n −− e x l u d e ' f i l e s y s t e m . s q u a s h f s ' − a / tmp / d


r o m /

d r o m /

5 m o u n t − o l o o p − t s q u a s h f s / tmp / d r o m / a s p e r / f i l e
s y s t e m .

s q u a s h f s / tmp / r o o t

6 p − a / tmp / r o o t .

7 u m o u n t / tmp / r o o t

8 u m o u n t / tmp / d r o m

Lalu buat #le 2-hro ot.sh.

Listing 10.11: remaster/2-hro ot.sh

1 p / e t / r e s o l v . o n f r o o t / e t

2 h r o o t r o o t m o u n t − t p r o n o n e / p r o

3 h r o o t r o o t m o u n t − t s y s f s n o n e / s y s

4 h r o o t r o o t

5 rm − f r o o t / e t / r e s o l v . o n f

6 h r o o t r o o t a p t − g e t l e a n

7 h r o o t r o o t u m o u n t s y s

8 h r o o t r o o t u m o u n t p r o
BAB 10. PENGEMASAN 97

9 h r o o t r o o t rm − r f / tmp / * / r o o t / . b a s h _ h i s t o r y

10 rm − r f d r o m / p r o g r a m s

11 h m o d +w d r o m / a s p e r / f i l e s y s t e m . m a n i f e s t

12 h r o o t r o o t d p k g −q u e r y − W −−s h o w f o r m a t = ' $ { P a k a
g e } $ {

V e r s i o n } \ n ' > d r o m / a s p e r / f i l e s y s t e m . m a n i f e s
t

13 p d r o m / a s p e r / f i l e s y s t e m . m a n i f e s t d r o m / a s
p e r /

f i l e s y s t e m . m a n i f e s t −d e s k t o p

14 s e d − i e ' / u b i q u i t y / d ' d r o m / a s p e r / f i l e s y s t e
m . m a n i f e s t −

d e s k t o p

Terakhir buat #le 3-pak.sh.

Listing 10.12: remaster/3-pak.sh

1 . . / o n f

2 rm − f d r o m / a s p e r / f i l e s y s t e m . s q u a s h f s

3 a w a l = ` d a t e `

4 m k s q u a s h f s r o o t d r o m / a s p e r / f i l e s y s t e m . s q u a
s h f s

5 d d r o m

6 f i n d . − t y p e f − p r i n t 0 | x a r g s − 0 md5sum > md5sum . t x t

7 m k i s o f s − r − V " $ {LABEL} " − a h e − i n o d e s − J − l − b i s o l i


n u x /

i s o l i n u x . b i n − i s o l i n u x / b o o t . a t − n o − e m u l −b o o
t − b o o t −

l o a d − s i z e 4 − b o o t − i n f o − t a b l e − o . . / $TARGET .

8 e h o " A w a l $ a w a l "

9 e h o " A k h i r " ` d a t e `

10 e h o " S o u r e " ` l s − l $SOURCE | awk ' { p r i n t $ 5 } ' `

11 e h o " T a r g e t " ` l s − l . . / $TARGET | awk ' { p r i n t $ 5 } ' `

Jalankan sript p ertama.


1 $ s u d o s h 1 − e x t r a t . s h

Dia akan mengekstrak #le iso menjadi ro ot diretory. Kemudian jalankan

sript kedua:

1 $ s u d o s h 2 − h r o o t . s h

Sript ini untuk masuk ke sistem Linux yang lain, yaitu ro ot diretory tadi.

1 r o o t # l a p t o p : / #

Di sini Anda bisa melakukan p erubahan sebagaimana biasa. Contoh:

1 r o o t # l a p t o p : / # d / e t / a p t / s o u r e s . l i s t . d

2 r o o t # l a p t o p : / # w g e t h t t p : / / d e b i a n . r a b . o . i
d / r a b . l i s t

3 r o o t # l a p t o p : / # a p t − g e t u p d a t e

4 r o o t # l a p t o p : / # a p t − g e t i n s t a l l i n t e r n e t − s h a r
i n g d h p 3 −

s e r v e r s q u i d v i m

Kalau sudah selesai keluarlah dari hro ot dengan menekan Ctrl-D atau ketik

exit:

BAB 10. PENGEMASAN 98

1 r o o t # l a p t o p : / # e x i t

2 e x i t

3 s u g i a n a # l a p t o p : ~ $

Ro ot diretory kini telah b erisi aplikasi yang dibutuhkan. Saatnya membuat

iso dengan menjalankan sript ketiga.

1 $ s u d o 3 − p a k . s h

Tunggu sekitar 5 menit.

1 P a r a l l e l m k s q u a s h f s : U s i n g 2 p r o e s s o r s

2 C r e a t i n g 4 . 0 f i l e s y s t e m o n d r o m / a s p e r / f i l e s y
s t e m .

s q u a s h f s , b l o k s i z e 1 3 1 0 7 2 .

3 [==========================| ℄ 1 5 0 6 3 / 8 4 2 5 8 17%

Terakhir sript akan memb erikan informasi ukuran iso yang dihasilkan b erikut

iso aslinya.
1 3 5 7 4 3 3 e x t e n t s w r i t t e n ( 6 9 8 MB)

2 A w a l S e n Agu 2 0 9 : 4 5 : 3 9 WIT 2 0 1 0

3 A k h i r S e n Agu 2 0 9 : 5 0 : 5 2 WIT 2 0 1 0

4 S o u r e 7 3 1 8 6 9 1 8 4

5 T a r g e t 7 3 2 0 2 2 7 8 4

Jika media yang Anda tuju nanti adalah CDROM, pastikan ukurannya

dibawah 700MB. Lebih mudahnya bandingkan dengan ukuran ISO aslinya. Pa-

da ontoh di atas terlihat ukuran Target masih lebih b esar dari Soure. Jika

masih terlalu b esar jalankan lagi sript kedua untuk menghapus paket yang tak

p erlu.

1 $ s u d o s h 2 − h r o o t . s h

Setelah selesai jalankan lagi sript ketiga:

1 $ s u d o s h 3 − p a k . s h

File ISO yang dihasilkan bisa Anda oba terlebih dahulu di VirtualBox
1

Anda juga bisa memasangnya di #ashdisk menggunakan usb-reator-gtk. Jika

sudah yakin barulah membakarnya (burn) ke CD-ROM.

virtualb ox.org

Bab 11

Graphial User Interfae

Bab-bab seb elumnya kita memp ela jari bagaimana membuat aplikasi dalam lingkun-

gan teks (text mo de), b eb erapa menyebutnya lingkungan konsole. Contohnya

fungsi raw_input() yang meminta masukan user dari konsole. Lingkungan yang

dimaksud b eririkan tidak membutuhkan mouse, ukup dengan keyb oard sa ja

sebagai alat masukan (input devie).

Kali ini kita masuk p emrograman b erbasis gra#s dimana mouse bisa digu-

nakan sebagai alat masukan untuk klik tomb ol, opy paste, dsb. Graphial Uset

Interfae (GUI) tidaklah wa jib di Python, ia hanya sebagai mo dul. Berb eda
dengan Visual Basi atau Borland Delphi yang mewa jibkan GUI.

Mo dul b erbasis GUI tidak hanya satu di Python, ada Qt, Wx, GTk, Tl, dst.

Di sini kita akan membahas Qt sebagai pustaka antarmuka gra#s. Pasanglah

paketnya.

1 $ s u d o a p t − g e t i n s t a l l p y t h o n −q t 4

Juga dokumentasinya, meski tidak wa jib.

1 $ s u d o a p t − g e t i n s t a l l q t 4 − d o − h t m l

Sep erti biasa, mulailah dari yang sederhana, yaitu membuat aplikasi Hello

world dalam #le hello.py.

Listing 11.1: hello.py

1 i m p o r t s y s

2 f r o m P y Q t 4 i m p o r t Q t

3 f r o m P y Q t 4 . Q t G u i i m p o r t *

5 l a s s FormUtama ( QMainWindow ) :

6 d e f _ _ i n i t _ _ ( s e l f ) :

7 QMainWindow . _ _ i n i t _ _ ( s e l f )

8 s e l f . s e t W i n d o w T i t l e ( ' H e l l o w o r l d ' )

10

99

BAB 11. GRAPHICAL USER INTERFACE 100

Gambar 11.1: Hello world

11 a p p = Q t . Q A p p l i a t i o n ( s y s . a r g v )

12 f m = FormUtama ( )

13 f m . s h o w ( )

14 #a p p . e x e _ ( )

Butuh tampilan p enuh ? Gantilah

fm.show()

menjadi
fm.showMaximized()

11.1 Orientasi Ob jek

Di sini teknik p emrograman semakin terstruktur dimana p emrograman b eror-

ientasi ob jek (Ob jet Oriented Programming / OOP) diterapkan. Mari kita

rini lagi p embahasan soure hello.py tersebut.

Class bisa dianggap sebuah tip e data, diseja jarkan dengan tip e string, inte-

ger, #oat, list, ditionary, datetime, dst. Dengan demikian FormUtama meru-

pakan tip e data. Perhatikan baris 5

lass FormUtama(QMainWindow):

itu artinya FormUtama merupakan turunan (inheritane) dari lass QMain-

Window. Itu artinya variab el dan fungsi yang dimiliki lass QMainWindow

juga dimiliki oleh lass FormUtama. Bahasa lainnya FormUtama mewarisi sifat

QMainWindow.

Selanjutnya ada fungsi __init__(). Fungsi ini merupakan fungsi khusus

yang dijalankan saat p emb entukan

sehingga disebut sebagai onstrutor. Saat

p emb entukan ? Ya, p erhatikan baris 12

fm = FormUtama()

Itu adalah p emb entukan variab el fm yang b ertip e FormUtama. Disinilah fungsi

__init__() dipanggil.

BAB 11. GRAPHICAL USER INTERFACE 101

Dalam istilah OOP, fm disebut sebagai instane atau variab el b ertip e

lass. Namun di Python rasanya semua tip e data adalah lass. Mis-

alnya tip e string. Ia tidak hanya memuat data sep erti 'ab d' sa ja,

melainkan juga memuat fungsi sep erti replae(), rjust(), dst. Hal ini

bisa dibuktikan dengan print dir('ab d'). Sehingga b oleh dikatakan

di Python semua variab el adalah ob jek. Bagi programmer PHP An-

da bisa ermati bahwa string 'ab d' hanya sekedar data.

Sekarang p erhatikan baris 7


QMainWindow.__init__(self)

Fungsi __init__() yang dimiliki QMainWindow p erlu dipanggil lagi. Mengapa

? Karena FormUtama mende#nisikan ulang fungsi __init__().

Lalu apa itu self ? self adalah variab el yang mewakili FormUtama itu sendiri.

Setiap fungsi yang dimiliki oleh suatu lass setidaknya memiliki satu masukan

(input parameter) yaitu self.

Selanjutnya lihat baris 13

fm.show()

dimana kita tidak p ernah mende#nisikan fungsi show() di dalam lass FormU-

tama. Kenyataannya variab el fm memiliki fungsi show(). Darimana ia b erasal

? Sep erti dijelaskan tadi, FormUtama mewarisi sifat QMainWindow, jadi fungsi

show() itu b erasal darinya. Fungsi ini digunakan untuk menampilkan form.

Lalu apa itu form ? Kotak Hello world itulah yang disebut form sep erti pada

gambar 11.1.

Sekarang lihat baris 11

app = Qt.QAppliation(sys.argv)

dimana QAppliation dibutuhkan untuk lo op. Lo op yang dimaksud adalah baris

terakhir

app.exe_()

tanpa lo op, alur langsung b erakhir. Form bisa banyak, tapi QAppliation ukup

satu sa ja.

Pahami lagi baik-baik konsep OOP ini agar semakin mudah untuk membuat

aplikasi yang lebih b esar.

11.2 Daftar Pegawai

Mari kita buat form yang lebih lengkap. Form ini untuk memasukkan data

p egawai, terinspirasi dari tab el p egawai yang p ernah kita buat. Namun disini

b elum menggunakan database, semuanya tersimpan sementara sa ja.

BAB 11. GRAPHICAL USER INTERFACE 102

Listing 11.2: gui/p egawai.py

1 i m p o r t s y s
2 f r o m P y Q t 4 i m p o r t Q t

3 f r o m P y Q t 4 . Q t G u i i m p o r t *

4 f r o m P y Q t 4 . Q t C o r e i m p o r t Q D a t e , SIGNAL

6 l a s s FormUtama ( QMainWindow ) :

7 d e f _ _ i n i t _ _ ( s e l f ) :

8 QMainWindow . _ _ i n i t _ _ ( s e l f )

9 s e l f . s e t W i n d o w T i t l e ( ' P e g a w a i ' )

10 s e l f . r e s i z e ( 5 5 0 , 5 5 0 )

11 s e l f . l a b e l N a m a = Q L a b e l ( s e l f )

12 s e l f . l a b e l A l a m a t = Q L a b e l ( s e l f )

13 s e l f . l a b e l T g l L a h i r = Q L a b e l ( s e l f )

14 s e l f . l a b e l J e n i s = Q L a b e l ( s e l f )

15 s e l f . e d i t N a m a = Q L i n e E d i t ( s e l f )

16 s e l f . e d i t A l a m a t = Q T e x t E d i t ( s e l f )

17 s e l f . e d i t T g l L a h i r = Q D a t e E d i t ( 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 . b u t t o n S i m p a n = Q P u s h B u t t o n ( s e l f )

20 s e l f . l i s t P e g a w a i = Q T a b l e W i d g e t ( s e l f )

21 s e l f . l a b e l N a m a . s e t T e x t ( ' Nama ' )

22 s e l f . l a b e l A l a m a t . s e t T e x t ( ' A l a m a t ' )

23 s e l f . l a b e l T g l L a h i r . s e t T e x t ( ' T g l L a h i r ' )

24 s e l f . l a b e l J e n i s . s e t T e x t ( ' J e n i s K e l a m i n ' )

25 s e l f . e d i t T g l L a h i r . s e t D i s p l a y F o r m a t ( ' d d − MM
− y y y y ' )

26 s e l f . e d i t T g l L a h i r . s e t D a t e ( Q D a t e ( 2 0 1 0 , 1 0 ,
2 3 ) )

27 s e l f . e d i t J e n i s . a d d I t e m s ( [ ' P r i a ' , ' W a n i t a '


℄ )

28 s e l f . b u t t o n S i m p a n . s e t T e x t ( ' S i m p a n ' )

29 s e l f . l i s t P e g a w a i . s e t C o l u m n C o u n t ( 5 )
30 s e l f . l i s t P e g a w a i . s e t H o r i z o n t a l H e a d e r L a b e
l s ( [

31 ' I D ' , ' Nama ' , ' A l a m a t ' , ' T g l L a h i r ' , ' K e l a m i n '
℄ )

32 s e l f . l i s t P e g a w a i . s e t C o l u m n W i d t h ( 0 , 2 0 )

33 s e l f . l i s t P e g a w a i . s e t C o l u m n W i d t h ( 1 , 1 5 0 )

34 s e l f . e d i t N a m a . r e s i z e ( 2 0 0 , 3 0 )

35 s e l f . e d i t A l a m a t . r e s i z e ( 2 0 0 , 1 0 0 )

36 s e l f . l i s t P e g a w a i . r e s i z e ( 5 0 0 , 2 0 0 )

37 s e l f . l a b e l N a m a . m o v e ( 1 0 , 1 0 )

38 s e l f . l a b e l A l a m a t . m o v e ( 1 0 , 4 0 )

39 s e l f . l a b e l T g l L a h i r . m o v e ( 1 0 , 1 4 0 )

40 s e l f . l a b e l J e n i s . m o v e ( 1 0 , 1 7 0 )

41 s e l f . e d i t N a m a . m o v e ( 1 0 0 , 1 0 )

42 s e l f . e d i t A l a m a t . m o v e ( 1 0 0 , 4 0 )

43 s e l f . e d i t T g l L a h i r . m o v e ( 1 0 0 , 1 4 0 )

44 s e l f . e d i t J e n i s . m o v e ( 1 0 0 , 1 7 0 )

BAB 11. GRAPHICAL USER INTERFACE 103

45 s e l f . b u t t o n S i m p a n . m o v e ( 1 0 0 , 2 0 0 )

46 s e l f . l i s t P e g a w a i . m o v e ( 1 0 , 3 0 0 )

47 s e l f . o n n e t ( s e l f . b u t t o n S i m p a n , SIGNAL ( ' l i k e
d ( )

' ) , s e l f . s i m p a n )

48

49 d e f s i m p a n ( s e l f ) :

50 r o w = s e l f . l i s t P e g a w a i . r o w C o u n t ( )

51 p i d = r o w+1

52 s e l f . l i s t P e g a w a i . s e t R o w C o u n t ( p i d )

53 s e l f . l i s t P e g a w a i . s e t I t e m ( r o w , 0 , Q T a b l e W i d
g e t I t e m (

s t r ( p i d ) ) )
54 s e l f . l i s t P e g a w a i . s e t I t e m ( r o w , 1 , Q T a b l e W i d
g e t I t e m (

s e l f . e d i t N a m a . t e x t ( ) ) )

55 s e l f . l i s t P e g a w a i . s e t I t e m ( r o w , 2 , Q T a b l e W i d
g e t I t e m (

s e l f . e d i t A l a m a t . t o P l a i n T e x t ( ) ) )

56 s e l f . l i s t P e g a w a i . s e t I t e m ( r o w , 3 , Q T a b l e W i d
g e t I t e m (

s e l f . e d i t T g l L a h i r . t e x t ( ) ) )

57 s e l f . l i s t P e g a w a i . s e t I t e m ( r o w , 4 , Q T a b l e W i d
g e t I t e m (

s e l f . e d i t J e n i s . u r r e n t T e x t ( ) ) )

58 s e l f . e d i t N a m a . l e a r ( )

59 s e l f . e d i t A l a m a t . l e a r ( )

60 s e l f . e d i t J e n i s . s e t C u r r e n t I n d e x ( 0 )

61 s e l f . e d i t N a m a . s e t F o u s ( )

62

63

64 a p p = Q t . Q A p p l i a t i o n ( s y s . a r g v )

65 f m = FormUtama ( )

66 f m . s h o w ( )

67 a p p . e x e _ ( )

Bagaimana, panjang bukan ?

Ya, ontoh kali ini menyertakan lass yang kerap digunakan. Berikut ini

ulasan masing-masing lass tersebut.

QLab el Menampilkan tulisan sa ja, tidak bisa diedit user.

QLineEdit Untuk memasukkan tulisan, satu baris sa ja.

QTextEdit Untuk memasukkan tulisan juga, tapi bisa lebih dari satu baris.

QDateEdit Untuk mengisi tanggal.

QComb oBox Untuk menetapkan pilihan.

QPushButton Tomb ol yang bila di-klik menjalankan suatu fungsi. Dalam hal

ini menyimpan data p egawai ke QTableWidget yang ada di bawahnya.


QTableWidget Menampilkan data b erb entuk tab el.

BAB 11. GRAPHICAL USER INTERFACE 104

Gambar 11.2: Daftar Pegawai

BAB 11. GRAPHICAL USER INTERFACE 105

Dari soure tersebut dan menganalisa tampilan form, rasanya Anda bisa mema-

hami ara p enggunaan lass di atas.

Untuk mengetahui lass lainnya b eserta fungsi yang ada di dalam-

nya Anda bisa lihat di /usr/share/qt4/do /html/lasses.html. Gu-

nakanlah browser untuk melihatnya.

Bab 12

Ob jet Oriented

Programming

Kita membuat fungsi dengan tujuan e#siensi soure, agar proses-proses yang

sama dapat diwakili dengan memanggil fungsi tertentu. Begitu juga pada p em-

buatan ob jek. Mari mulai pada kasus.

Ada sebuah #le teks b ernama barang.txt dengan isi sep erti b erikut ini.

Listing 12.1: barang.txt

1 1 J e r u k 3 4 9 0 0 0

2 2 M a n g g a 8 0 0 0

3 3 P i s a n g 7 1 0 0 0 0

Pembuat #le itu memastikan data barang tersimpan dengan lebar kolom

tetap . Kolom ko de barang 3 karakter, nama barang 10 karakter, stok 2 karak-

ter, dan harga barang 8 karakter atau sisanya. Anda diminta memindahkan

data ini ke sebuah tab el di database. Mari mulai memp ertimbangkan langkah-

langkah yang bisa ditempuh.

Andai sa ja kita bisa menggunakan split() yang bisa mengubah string menjadi

list, sehingga dengan mudah kolom p ertama ada ko de barang, kolom kedua

nama barang, dan seterusnya. Sayang sekali hal ini tidak dapat dilakukan.

Mengapa ?
Perhatikan baris Mangga dimana nilai stok kosong. Ini artinya kolom ketiga

menjadi harga barang. Tentu sa ja tidak konsisten dengan baris Jeruk dimana

kolom ketiga adalah stok. Idealnya p embuat #le itu mengubah programnya

agar kalau stok kosong dib eri angka 0. Namun p osisi kita sedang tidak bisa

memaksa.

Baik, kita ikuti sa ja p etunjuk p embuatnya dimana lebar kolom menjadi

auan. Sementara ini kita tidak p erlu terlalu jauh bagaimana struktur tab elnya.

Dari sudut pandang Python sa ja dulu, tip e data apa yang o ok untuk mewakili

#le ini. Untuk sementara anggap sa ja tip e data list yang sesuai karena ini

merupakan b entuk tab el.

106

BAB 12. OBJECT ORIENTED PROGRAMMING 107

Mulailah membuat sript barang1.py.

Listing 12.2: barang1.py

1 i m p o r t s y s

3 f i l e n a m e = s y s . a r g v [ 1 ℄

4 f = o p e n ( f i l e n a m e )

5 f o r l i n e i n f . r e a d l i n e s ( ) :

6 k o d e = l i n e [ : 3 ℄ . s t r i p ( )

7 nama = l i n e [ 3 : 3 + 1 0 ℄ . s t r i p ( )

8 s t o k = l i n e [ 3 + 1 0 : 3 + 1 0 + 2 ℄ . s t r i p ( )

9 h a r g a = l i n e [ 3 + 1 0 + 2 : ℄ . s t r i p ( )

10 p r i n t [ k o d e , nama , s t o k , h a r g a ℄

11 f . l o s e ( )

Jalankan.

1 $ p y t h o n b a r a n g 1 . p y b a r a n g . t x t

2 [ ' 1 ' , ' J e r u k ' , ' 3 4 ' , ' 9 0 0 0 ' ℄

3 [ ' 2 ' , ' M a n g g a ' , ' ' , ' 8 0 0 0 ' ℄

4 [ ' 3 ' , ' P i s a n g ' , ' 7 ' , ' 1 0 0 0 0 ' ℄


Tahap ini sudah baik, dimana setiap nilai sudah dapat diwakili dalam vari-

ab el ko de, nama, stok, dan harga. Namun barang1.py masih kurang mo dular

karena masukannya b erupa nama #le yang dib erikan melalui ommand line.

12.1 Lebih Terstruktur

Kita p erlu meningkatkan kadar mo dularitas dengan membuat fungsi. Buatlah

barang2.py b erikut.

Listing 12.3: barang2.py

1 d e f b a r a n g ( f i l e n a m e ) :

2 f = o p e n ( f i l e n a m e )

3 r o w s = [ ℄

4 f o r l i n e i n f . r e a d l i n e s ( ) :

5 k o d e = l i n e [ : 3 ℄ . s t r i p ( )

6 nama = l i n e [ 3 : 3 + 1 0 ℄ . s t r i p ( )

7 s t o k = l i n e [ 3 + 1 0 : 3 + 1 0 + 2 ℄ . s t r i p ( )

8 h a r g a = l i n e [ 3 + 1 0 + 2 : ℄ . s t r i p ( )

9 r o w = [ k o d e , nama , s t o k , h a r g a ℄

10 r o w s . a p p e n d ( r o w )

11 f . l o s e ( )

12 r e t u r n r o w s

13

14

15 i f __name__ == ' __main__ ' :

BAB 12. OBJECT ORIENTED PROGRAMMING 108

16 i m p o r t s y s

17 f i l e n a m e = s y s . a r g v [ 1 ℄

18 f o r r o w i n b a r a n g ( f i l e n a m e ) :

19 p r i n t r o w

Jalankan.

1 $ p y t h o n b a r a n g 2 . p y b a r a n g . t x t
2 [ ' 1 ' , ' J e r u k ' , ' 3 4 ' , ' 9 0 0 0 ' ℄

3 [ ' 2 ' , ' M a n g g a ' , ' ' , ' 8 0 0 0 ' ℄

4 [ ' 3 ' , ' P i s a n g ' , ' 7 ' , ' 1 0 0 0 0 ' ℄

Hasil tetap sama, namun kini sript tidak hanya mengandung fungsi tetapi

juga bisa digunakan sebagai mo dul.

12.2 Lebih Umum

Sekarang asp ek generalitas, atau tingkat ke-umum-an fungsi, dimana lebar se-

tiap kolom sudah ditetapkan di dalam fungsi (hardo de). Bisakah ditingkatkan

generalitasnya ?

Kebutuhannya adalah ada #le lain selain barang.txt dengan lebar setiap

kolom b erb eda dengan barang.txt, namun sifatnya masih sama yaitu setiap

kolom memiliki lebar tertentu . Kalau barang.txt menggunakan lebar kolom

masing-masing 3, 10, 2, dan 8, mungkin p egawai.txt menggunakan 5, 30, 10,

50, dan 20. Jadi bukan hanya lebar kolomnya b erb eda, jumlah kolomnya pun

b erb eda.

Karena sudah b ersifat umum sebaiknya nama fungsi dan nama #lenya pun

umum. Buatlah #xtable.py b erikut.

Listing 12.4: #xtable.py

1 d e f f i x t a b l e ( f i l e n a m e , w i d t h s ) :

2 f = o p e n ( f i l e n a m e )

3 r o w s = [ ℄

4 f o r l i n e i n f . r e a d l i n e s ( ) :

5 a w a l = 0

6 r o w = [ ℄

7 f o r w i d t h i n w i d t h s :

8 a k h i r = a w a l + w i d t h

9 f i e l d = l i n e [ a w a l : a k h i r ℄ . s t r i p ( )

10 r o w . a p p e n d ( f i e l d )

11 a w a l = a k h i r

12 r o w s . a p p e n d ( r o w )
13 f . l o s e ( )

14 r e t u r n r o w s

15

16

17 i f __name__ == ' __main__ ' :

BAB 12. OBJECT ORIENTED PROGRAMMING 109

18 i m p o r t s y s

19 f i l e n a m e = s y s . a r g v [ 1 ℄

20 f o r r o w i n f i x t a b l e ( f i l e n a m e , [ 3 , 1 0 , 2 , 8 ℄ ) :

21 p r i n t r o w

Jalankan.

1 $ p y t h o n f i x t a b l e . p y b a r a n g . t x t

2 [ ' 1 ' , ' J e r u k ' , ' 3 4 ' , ' 9 0 0 0 ' ℄

3 [ ' 2 ' , ' M a n g g a ' , ' ' , ' 8 0 0 0 ' ℄

4 [ ' 3 ' , ' P i s a n g ' , ' 7 ' , ' 1 0 0 0 0 ' ℄

Perhatikan lagi, hasil masih sama. Anda bisa uji dengan membuat p e-

gawai.txt.

Listing 12.5: p egawai.txt

1 1BUMMI DWI PUTERA, ST 1 9 8 5 − 0 8 − 1 7L

2 2 ARIEF SETIADI 1 9 7 2 − 0 5 − 0 2L

3 3CECEP ZAHRUDIN , ST 1 9 7 2 − 0 6 − 0 1L

4 4NITA PANDRIA 1 9 7 6 − 0 9 − 1 9P

5 5ILHAM 1 9 8 4 − 1 1 − 0 5L

6 6MIRANDA 1 9 7 8 − 1 0 − 0 1P

Lalu #xp egawai.py.

Listing 12.6: #xp egawai.py

1 f r o m f i x t a b l e i m p o r t f i x t a b l e

2 i m p o r t s y s

3
4 f i l e n a m e = s y s . a r g v [ 1 ℄

6 f o r r o w i n f i x t a b l e ( f i l e n a m e , [ 2 , 2 2 , 1 0 , 1 ℄ ) :

7 p r i n t r o w

Jalankan.

1 $ p y t h o n f i x p e g a w a i . p y p e g a w a i . t x t

2 [ ' 1 ' , 'BUMMI DWI PUTERA, ST ' , ' 1 9 8 5 − 0 8 − 1 7 ' , ' L ' ℄

3 [ ' 2 ' , ' ARIEF SETIADI ' , ' 1 9 7 2 − 0 5 − 0 2 ' , ' L ' ℄

4 [ ' 3 ' , ' CECEP ZAHRUDIN , ST ' , ' 1 9 7 2 − 0 6 − 0 1 ' , ' L ' ℄

5 [ ' 4 ' , ' NITA PANDRIA ' , ' 1 9 7 6 − 0 9 − 1 9 ' , ' P ' ℄

6 [ ' 5 ' , ' ILHAM ' , ' 1 9 8 4 − 1 1 − 0 5 ' , ' L ' ℄

7 [ ' 6 ' , ' MIRANDA ' , ' 1 9 7 8 − 1 0 − 0 1 ' , ' P ' ℄

Fungsi #xtable teruji.

12.3 Tingkat Kerumitan

Kompleksitas masalah kian b ertambah. Kini Anda membutuhkan hasil yang

memp erhatikan tip e data . Perhatikan lagi barang.txt dimana:

BAB 12. OBJECT ORIENTED PROGRAMMING 110

ˆ kolom p ertama, ko de barang, b ertip e integer

ˆ kolom kedua, nama barang, b ertip e string

ˆ kolom ketiga, stok, b ertip e integer

ˆ kolom keempat, harga, b ertip e integer

Lalu apa nilai yang o ok untuk stok Mangga yang tidak tertulis apapun alias

string hampa ? Apa tetap diisi sebagai string hampa ? Sebaiknya tidak, karena

kita akan menetapkan #eld stok b ertip e integer. Maka nilai yang o ok untuk

string hampa adalah None, alias ob jek hampa. Buatlah #le FixTableTyp e.py

b erikut ini.

Listing 12.7: FixTableTyp e.py

1 f r o m t y p e s i m p o r t I n t T y p e , S t r i n g T y p e

3
4 d e f f i x t a b l e ( f i l e n a m e , f t y p e s ) :

5 f = o p e n ( f i l e n a m e )

6 r o w s = [ ℄

7 f o r l i n e i n f . r e a d l i n e s ( ) :

8 a w a l = 0

9 r o w = [ ℄

10 f o r w i d t h , f t y p e i n f t y p e s :

11 a k h i r = a w a l + w i d t h

12 f i e l d = l i n e [ a w a l : a k h i r ℄ . s t r i p ( )

13 i f n o t f i e l d :

14 f i e l d = N o n e

15 e l i f f t y p e == I n t T y p e :

16 f i e l d = i n t ( f i e l d )

17 r o w . a p p e n d ( f i e l d )

18 a w a l = a k h i r

19 r o w s . a p p e n d ( r o w )

20 f . l o s e ( )

21 r e t u r n r o w s

22

23

24 i f __name__ == ' __main__ ' :

25 i m p o r t s y s

26 f i l e n a m e = s y s . a r g v [ 1 ℄

27 f i e l d s = [

28 [ 3 , I n t T y p e ℄ ,

29 [ 1 0 , S t r i n g T y p e ℄ ,

30 [ 2 , I n t T y p e ℄ ,

31 [ 8 , I n t T y p e ℄

32 ℄
BAB 12. OBJECT ORIENTED PROGRAMMING 111

33 f o r r o w i n f i x t a b l e ( f i l e n a m e , f i e l d s ) :

34 p r i n t r o w

Jalankan.

1 $ p y t h o n F i x T a b l e T y p e . p y b a r a n g . t x t

2 [ 1 , ' J e r u k ' , 3 4 , 9 0 0 0 ℄

3 [ 2 , ' M a n g g a ' , N o n e , 8 0 0 0 ℄

4 [ 3 , ' P i s a n g ' , 7 , 1 0 0 0 0 ℄

Perhatikan, tidak ada lagi kutip di kolom p ertama, 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 b ertambah

dimana:

ˆ Tip e integer

Bab 13

Kerja Sampingan

Anda diminta membuat sebuah program yang b ertugas mengendalikan sebuah

GSM mo dem. Program ini b ersifat daemon yang artinya selalu b erjalan seolah

tanpa akhir. Tugas utamanya adalah mengirim SMS yang b erasal dari seluruh

#le yang ada di direktori /tmp/job. Hasil p engiriman SMS (b erhasil / tidak)

dikirim ke SMS gateway induk melalui XMLRPC, inilah kerja sampingannya

atau sering disebut sebagai multi-thread .

Mengapa kita p erlu multi-thread ?

Mo dem tersebut hanya bisa mengirim sebuah SMS pada satu saat yang

membutuhkan waktu 10 detik. Di sisi lain daemon ini harus mengabari status

p engiriman ke SMS gateway induk melalui XMLRPC yang membutuhkan waktu

5 detik. Bahkan kalau terkena masalah bandwidth XMLRPC lient ini bisa

membutuhkan waktu 60 detik. Bayangkan kalau hanya single-thread.

Saat Thread 1

1 Mengirim SMS 1 selama 10 detik

2 Mengabari status SMS 1 selama 5 detik


3 Mengirim SMS 2 selama 10 detik

4 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 detik

2 Mengirim SMS 2 10 detik Mengabari status SMS 1 5 detik

3 Mengabari status SMS 2 5 detik

Total waktu yang dibutuhkan adalah 10+10+5 = 25 detik, selisih 5 detik

dari single-thread. Bagi SMS gateway itu merupakan jeda yang ukup b erarti

mengingat banyaknya SMS yang dikirim.

Mari kita mulai simulasinya dengan membuat test_thread.py.

Listing 13.1: testthread.py

1 f r o m t h r e a d i n g i m p o r t T h r e a d

112

BAB 13. KERJA SAMPINGAN 113

2 i m p o r t t i m e

3 i m p o r t o s

4 f r o m g l o b i m p o r t g l o b

7 l a s s K i r i m ( T h r e a d ) :

8 d e f _ _ i n i t _ _ ( s e l f , k ) :

9 s e l f . k e r j a = T r u e

10 s e l f . k a b a r = k

11 T h r e a d . _ _ i n i t _ _ ( s e l f )

12

13 d e f r u n ( s e l f ) :

14 p r i n t t i m e . s t r f t i m e ( '%H: %M: % S ' ) , ' K e r j a s a m p i


n g a n
d i m u l a i '

15 w h i l e s e l f . k e r j a :

16 t i m e . s l e e p ( 1 )

17 i f n o t s e l f . k a b a r :

18 o n t i n u e

19 h a s i l = s e l f . k a b a r [ 0 ℄

20 d e l s e l f . k a b a r [ 0 ℄

21 # s e l f . k a b a r = s e l f . k a b a r [ 1 : ℄

22 p r i n t '%s KABARI %s ' % ( t i m e . s t r f t i m e ( '%H: %M

: % S ' ) , h a s i l )

23

24 d e f j o i n ( s e l f ) :

25 p r i n t ' K e r j a s a m p i n g a n b e r a k h i r '

26 s e l f . k e r j a = F a l s e

27 T h r e a d . j o i n ( s e l f )

28

29

30 j o b _ d i r = ' / tmp / j o b '

31 k a b a r = [ ℄

32

33 s a m p i n g a n = K i r i m ( k a b a r )

34 s a m p i n g a n . s t a r t ( )

35

36 p r i n t t i m e . s t r f t i m e ( '%H: %M: % S ' ) , ' P e k e r j a a n u


t a m a d i m u l a i

'

37 w h i l e T r u e :

38 t i m e . s l e e p ( 1 )

39 i f n o t o s . p a t h . e x i s t s ( j o b _ d i r ) :

40 o n t i n u e
41 f i l e n a m e s = g l o b ( '%s / * ' % j o b _ d i r )

42 i f n o t f i l e n a m e s :

43 o n t i n u e

44 f i l e n a m e = f i l e n a m e s [ 0 ℄

BAB 13. KERJA SAMPINGAN 114

45 f = o p e n ( f i l e n a m e )

46 j o b = f . r e a d ( )

47 f . l o s e ( )

48 o s . r e m o v e ( f i l e n a m e )

49 p r i n t '%s KERJAKAN %s ' % ( t i m e . s t r f t i m e ( '%H: %M: % S ' ) ,

j o b )

50 k a b a r . a p p e n d ( j o b )

51

52 p r i n t ' P e k e r j a a n u t a m a b e r a k h i r '

53 s a m p i n g a n . j o i n ( )

Jalankan.

1 $ p y t h o n t e s t t h r e a d . p y

2 0 4 : 5 6 : 5 4 P e k e r j a a n u t a m a d i m u l a i

3 0 4 : 5 6 : 5 4 K e r j a s a m p i n g a n d i m u l a i

Sampai di sini ia menunggu keb eradaan #le di direktori /tmp/job. Buka

konsole lain dan buatlah direktori /tmp/job.

1 $ m k d i r / tmp / j o b

Lalu buatlah #le apa sa ja.

1 $ e h o h e l l o > / tmp / j o b / h e l l o . t x t

Kemudian lihat konsole testthread.py tadi.

1 0 4 : 5 6 : 5 6 KERJAKAN h e l l o

2 0 4 : 5 6 : 5 7 KABARI h e l l o

Pointer

Perlu dip erhatikan variab el kabar yang b ertip e list (baris 30). Ini adalah
vari-
ab el b ersama , artinya dapat diolah baik oleh thread 1 maupun thread 2. Di

sini b erlaku apa yang disebut p ointer yang artinya alokasi memori pada baris

30 dengan baris 10

1 s e l f . k a b a r = k

adalah sama . Perhatikan juga p enghapusan antrian p ertama di baris 20

1 d e l s e l f . k a b a r [ 0 ℄

dimana pada program biasa bisa sa ja Anda membuatnya menjadi

1 s e l f . k a b a r = s e l f . k a b a r [ 1 : ℄

Namun teknik ini akan membuat alokasi memori yang baru dimana thread 2

tidak lagi menggunakan variab el kabar sebagaimana yang digunakan oleh thread

1.

Mudah-mudahan Anda paham apa yang dimaksud dengan multi-thread ini.

Bab 14

SMS Gateway

SMS Gateway adalah salah satu pro duk RAB yang memanfaatkan Python dan

PostgreSQL. Akses ke database menggunakan SQLAlhemy dan Elixir. Diran-

ang semo dular mungkin agar mudah dipakai oleh sistem lainnya yang bukan

Python, bukan PostgreSQL, bahkan bukan Linux.

Pro duk ini juga menerapkan teknik event driven dan plug-in.

14.1 Pemasangan

1 $ s u d o a p t − g e t i n s t a l l i m − gw

Proses instalasi akan meminta Anda menyesuaikan #le /et/im/gw/on-

#g.py. File ini p erlu diisi dengan otenti#kasi ke database yang sudah dibuat

tadi.

1 d b _ u r l = ' p o s t g r e s : / / i l h a m : 1 2 3 4 # l o a l h o s t : 5
4 3 2 / t o t a l i n d o '

Kemudian jalankan:

1 $ s u d o d p k g − r e o n f i g u r e i m − gw

Proses ini akan membuat tab el yang dibutuhkan ke database totalindo.

Paket im-gw digunakan untuk hal yang b erkaitan dengan database sep erti
menyimpan dan mengirim p esan. Daemonnya bisa Anda stop dan start dengan

ara:

1 $ s u d o / e t / i n i t . d / i m − gw r e s t a r t

im-gw juga otomatis hidup saat komputer dihidupkan. Anda bisa memantau

log-nya dengan ara:

1 $ s u d o t a i l − f / v a r / l o g / i m / gw . l o g

2 2 0 1 1 − 0 1 − 1 8 0 5 : 1 2 : 2 0 , 8 8 3 INFO S t a r t r e s u l t d i r / v
a r / s p o o l /

i m / r e s u l t /

3 2 0 1 1 − 0 1 − 1 8 0 5 : 1 2 : 2 0 , 8 8 6 INFO S t a r t j o b a t p i d 1 2 0
2

115

BAB 14. SMS GATEWAY 116

4 2 0 1 1 − 0 1 − 1 8 0 5 : 1 2 : 2 0 , 9 2 8 INFO S t a r t r e s u l t x m l r p
s e r v e r

o n p o r t 9 3 1 7

Tekan Ctrl-C untuk mengakhiri. Tapi sebaiknya tetap terpantau, dan Anda

bisa gunakan konsole lain untuk aktivitas b erikutnya.

Untuk mengirim dan menerima SMS yang seb enarnya dibutuhkan p engen-

dali mo dem:

1 $ s u d o a p t − g e t i n s t a l l i m − modem

Paket ini juga akan membuat tab el, menggunakan kon#gurasi yang sama

dengan im-gw.

Pasanglah mo dem GSM atau CDMA. Merk yang sudah teruji adalah Wave-

om, iTegno, dan Multiteh. USB devie lebih disarankan karena mendukung

hotplug, dimana saat mo dem ditanapkan p engendalinya otomatis aktif. Anda

bisa p eriksa dengan p erintah:

1 $ p s a x | g r e p modem

2 5 6 2 7 ? SN 0 : 0 6 / u s r / b i n / p y t h o n / u s r / b i n / modem − h o
t p l u g

3 2 8 4 6 4 ? S l 0 : 0 1 p y t h o n / u s r / b i n / modem / d e v / t t y U S B
0
Perhatikan /usr/bin/mo dem-hotplug, dialah yang memantau aktivitas p e-

masangan p erangkat USB. Lalu ada juga /usr/bin/mo dem, daemon inilah yang

dipanggil oleh mo dem-hotplug saat USB mo dem ditanapkan. Lalu bagaimana

jika p erangkatnya ditanapkan di serial p ort ?

Anda pastikan dulu mo dem itu terpasang di serial p ort b erapa. Keb eradaan

serial p ort bisa dilihat dengan p erintah b erikut:

1 $ d m e s g | g r e p t t y S

2 [ 2 5 . 9 7 2 1 9 7 ℄ s e r i a l 8 2 5 0 : t t y S 0 a t I /O 0 x 3 f 8 ( i r q
= 4 ) i s

a 1 6 5 5 0A

3 [ 2 5 . 9 7 3 1 4 1 ℄ 0 0 : 0 7 : t t y S 0 a t I /O 0 x 3 f 8 ( i r q = 4 ) i s
a

1 6 5 5 0A

4 [ 4 2 . 4 4 2 5 2 8 ℄ 0 0 0 0 : 0 5 : 0 1 . 0 : t t y S 4 a t I /O 0 x d 1 0 0
( i r q = 1 7 )

i s a 1 6 5 5 0A

5 [ 4 2 . 4 4 2 7 5 0 ℄ 0 0 0 0 : 0 5 : 0 1 . 0 : t t y S 5 a t I /O 0 x d 2 0 0
( i r q = 1 7 )

i s a 1 6 5 5 0A

6 [ 4 2 . 5 3 8 3 5 9 ℄ 0 0 0 0 : 0 5 : 0 2 . 0 : t t y S 6 a t I /O 0 x d 7 0 0
( i r q = 1 9 )

i s a 1 6 5 5 0A

7 [ 4 2 . 5 3 8 5 7 4 ℄ 0 0 0 0 : 0 5 : 0 2 . 0 : t t y S 7 a t I /O 0 x d 8 0 0
( i r q = 1 9 )

i s a 1 6 5 5 0A

Anda bisa menyebutkan semua serial p ort yang ada pada #le /et/im/-

mo dem/mo dem.onf:

1 [ d e v i e ℄

2 ; d e v i e d i / d e v / t t y

3 p o r t = USB0 USB1 USB2 USB3 USB4 USB5 USB6 USB7 S 0 S 4 S 5

S 6 S 7

Lalu restart semua mo dem:


BAB 14. SMS GATEWAY 117

1 $ s u d o / e t / i n i t . d / modem r e s t a r t

Tunggu sekitar 30 detik, lalu jalankan

1 $ p s a x | g r e p modem

2 1 1 2 1 1 ? R l 1 0 : 2 9 p y t h o n / u s r / b i n / modem / d e v /

t t y S 0

untuk mengetahui serial p ort mana yg digunakan. Anda bisa menge#sienkan

mo dem.onf diatas dengan hanya menantumkan S0 sa ja, namun tidak diubah

pun tidak menjadi masalah.

Sedangkan untuk melihat log-nya, terlebih dahulu Anda p eriksa direktori

/var/log/mo dem, ada #le apa di sana:

1 $ s u d o l s / v a r / l o g / modem

2 5 1 0 0 1 2 5 4 1 2 1 8 9 1 1 . l o g

Selanjutnya mulailah memantau:

1 $ s u d o t a i l − f / v a r / l o g / modem / 5 1 0 0 1 2 5 4 1 2 1 8 9 1 1 . l
o g − n 3 0

2 2 0 1 1 − 0 1 − 1 8 0 1 : 4 5 : 2 2 , 3 0 4 INFO − > AT+CSQ

3 2 0 1 1 − 0 1 − 1 8 0 1 : 4 5 : 2 4 , 3 0 7 INFO < − AT+CSQ

4 2 0 1 1 − 0 1 − 1 8 0 1 : 4 5 : 2 4 , 3 0 8 INFO < − +CSQ : 2 0 , 0

5 2 0 1 1 − 0 1 − 1 8 0 1 : 4 5 : 2 4 , 3 0 8 INFO < − OK

6 2 0 1 1 − 0 1 − 1 8 0 1 : 4 5 : 2 4 , 3 0 9 INFO − > AT+CLIP=1

7 2 0 1 1 − 0 1 − 1 8 0 1 : 4 5 : 2 6 , 3 1 2 INFO < − AT+CLIP=1

8 2 0 1 1 − 0 1 − 1 8 0 1 : 4 5 : 2 6 , 3 1 2 INFO < − OK

9 2 0 1 1 − 0 1 − 1 8 0 1 : 4 5 : 2 6 , 3 1 2 INFO − > AT+CGMM

10 2 0 1 1 − 0 1 − 1 8 0 1 : 4 5 : 2 7 , 3 2 6 INFO < − AT+CGMM

11 2 0 1 1 − 0 1 − 1 8 0 1 : 4 5 : 2 7 , 3 2 6 INFO < − MULTIBAND 9 0 0 E 1 8 0 0

12 2 0 1 1 − 0 1 − 1 8 0 1 : 4 5 : 2 7 , 3 2 7 INFO < − OK

13 2 0 1 1 − 0 1 − 1 8 0 1 : 4 5 : 2 7 , 3 2 7 INFO − > AT+CNMI = 0 , 1 , 1 , 1 , 0

14 2 0 1 1 − 0 1 − 1 8 0 1 : 4 5 : 2 9 , 3 3 0 INFO < − AT+CNMI = 0 , 1 , 1 , 1 , 0


15 2 0 1 1 − 0 1 − 1 8 0 1 : 4 5 : 2 9 , 3 3 0 INFO < − OK

16 2 0 1 1 − 0 1 − 1 8 0 1 : 4 5 : 2 9 , 3 3 0 INFO − > AT+CMGF=1

17 2 0 1 1 − 0 1 − 1 8 0 1 : 4 5 : 3 1 , 3 3 2 INFO < − AT+CMGF=1

18 2 0 1 1 − 0 1 − 1 8 0 1 : 4 5 : 3 1 , 3 3 3 INFO < − OK

19 2 0 1 1 − 0 1 − 1 8 0 1 : 4 5 : 3 1 , 3 3 3 INFO − > AT+CMGL="ALL"

20 2 0 1 1 − 0 1 − 1 8 0 1 : 4 5 : 3 2 , 3 4 6 INFO < − AT+CMGL="ALL"

21 2 0 1 1 − 0 1 − 1 8 0 1 : 4 5 : 3 2 , 3 4 6 INFO < − OK

22 2 0 1 1 − 0 1 − 1 8 0 1 : 4 5 : 3 2 , 3 5 2 INFO S e r v i n g / d e v / t t y U
S B 1 a n d /

v a r / s p o o l / i m / j o b / modem / 5 1 0 0 1 2 5 4 1 2 1 8 9 1 1 / a t p i d
2 8 4 6 4

Bila Anda sudah b erjumpa kalimat yang b erawalan Serving sep erti di atas,

maka mo dem 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 sa ja ?

BAB 14. SMS GATEWAY 118

Angka itu disebut dengan IMEI alias identitas hip / SIM ard. Jika kom-

puter membutuhkan informasi devie p ort untuk mengendalikan mo dem, maka

manusia / user membutuhkan IMEI sebagai identitas hip yang ada di dalam

mo dem. Aktivitas menerima dan mengirim SMS tentu melekat pada hip, bukan

pada mo dem. Karena itu p enggunaan IMEI pada nama log adalah yang paling

tepat untuk menjaga konsistensi history.

Lagi pula devie p ort yang digunakan mo dem USB kadang b erubah. Saat

ini mungkin mo dem dikenali di USB0. Coba Anda lepas dan pasang lagi di

tempat yang sama, bisa jadi kini USB1 yang digunakannya.

14.1.2 Database

Saat /usr/bin/mo dem mulai mengendalikan sebuah mo dem, ia melap orkan ke

/usr/bin/im-gw bahwa IMEI 510012541218911 baru sa ja hidup. Kejadian ini

disebut sebagai startup. Saat itulah im-gw memeriksa keb eradaan IMEI terse-

but di tab el im.agent. Kalau b elum ada ia tambahkan, dan kalau sudah ada ia
p erbaharui statusnya.

1 $ p s q l − U i l h a m − h l o a l h o s t t o t a l i n d o

2 P a s s w o r d f o r u s e r i l h a m :

3 p s q l ( 8 . 4 . 4 )

4 S S L o n n e t i o n ( i p h e r : DHE − RSA − A E S 2 5 6 − SHA , b i t s :


2 5 6 )

5 T y p e " h e l p " f o r h e l p .

6 t o t a l i n d o => SELECT i d , s t a t u s FROM i m . a g e n t ;

7 i d | s t a t u s

8 −−−−−−−−−−−−−−−−− + −−−−−−−−

9 5 1 0 0 1 2 5 4 1 2 1 8 9 1 1 | 0

10 ( 1 r o w )

Status 0 b erarti mo dem siap, status negatif b erarti sebaliknya. Alasan untuk

status negatif bisa Anda lihat di tab el im.status.

14.2 Hello world!

Mari mulai mengirim SMS ke handphone Anda, masih di psql.

1 t o t a l i n d o => INSERT INTO i m . a n t r i a n ( p e n e r i m a , p e s a


n )

2 t o t a l i n d o − > SELECT ' + 6 2 8 1 7 9 1 4 0 0 6 8 ' , ' H e l l o w o r l


d ! ' ;

3 INSERT 0 1

Untuk p enerima sesuaikanlah dengan nomor handphone Anda.

Status p engiriman bisa Anda lihat di tab el im.selesai.

1 t o t a l i n d o => SELECT i d , s t a t u s , p e n g i r i m , p e n e r i m a
, p e s a n

2 t o t a l i n d o − > FROM i m . s e l e s a i ORDER BY 1 DESC LIMIT 1 ;

3 i d | s t a t u s | p e n g i r i m | p e n e r i m a |

p e s a n

BAB 14. SMS GATEWAY 119

4 −−−−−− + −−−−−−−− + −−−−−−−−−−−−−−−−− + −−−−−−−−−−−−−−− + −−−−−−−−−−−−−−

5 1 0 6 5 | 0 | 5 1 0 0 1 2 5 4 1 2 1 8 9 1 1 | + 6 2 8 1 7 9 1 4 0 0 6 8 | H e l l
o
w o r l d !

6 ( 1 r o w )

Status 0 b erarti telah terkirim, negatif sebaliknya, sedangkan p ositif b erarti

sedang diproses. Penjelasannya bisa dilihat di tab el im.status.

Setelah Anda menerima SMS di handphone, balaslah SMS itu dengan:

Diterima

Tunggu sekitar 30 detik, dan lihat tab el im.antrian.

1 t o t a l i n d o => SELECT i d , k i r i m , p e n g i r i m , p e n e r i m a ,
p e s a n

2 t o t a l i n d o − > FROM i m . a n t r i a n ;

3 i d | k i r i m | p e n g i r i m | p e n e r i m a | p e s a n

4 −−−−−− + −−−−−−− + −−−−−−−−−−−−−−− + −−−−−−−−−−−−−−−−− + −−−−−−−−−−

5 1 0 7 1 | f | + 6 2 8 1 7 9 1 4 0 0 6 8 | 5 1 0 0 1 2 5 4 1 2 1 8 9 1 1 |

D i t e r i m a

6 ( 1 r o w

Mungkin Anda b ertanya-tanya, saat mengirim p esan tab el im.antrian yang

digunakan, b egitu juga saat menerima p esan. Lalu apa p emb edanya ?

Perhatikan #eld kirim di atas. Jika #eld kirim = f (False), itu b erarti reord

p esan masuk. Jika b ernilai t (True) b erarti p engiriman p esan. Defaultnya

adalah True (p engiriman p esan).

14.3 Instant Messenger Gateway

Ada dua paket utama di sini, yaitu im-gw dan im-mo dem. Keduanya terhubung

sebagaimana pada gambar 14.1. Lalu mengapa harus ada dua paket ?

Meski judul tulisan ini adalah SMS Gateway, namun pada konsepnya sistem

ini dapat disanding dengan paket instant messenger sep erti Yaho o! Messenger

dan XMPP (Jabb er, GTalk). Keduanya ada di paket im-ym dan im-xmpp.

Jadi im-mo dem, im-ym, dan im-xmpp seja jar kedudukannya. Kalau im-mo dem

memerlukan #sik mo dem, maka im-ym dan im-xmpp membutuhkan koneksi

Internet.

Jadi bila Anda ingin menoba sistem ini namun b elum memiliki mo dem,
maka bisa gunakan im-ym dan im-xmpp.

14.3.1 Yaho o! Messenger

Seb elum p emasangan, sebaiknya Anda siapkan Yaho o! aount yang baru yang

akan digunakan oleh /usr/bin/ym (daemon dari paket im-ym). Selanjutnya

pasang paketnya.

BAB 14. SMS GATEWAY 120

Gambar 14.1: Alur IM gateway

BAB 14. SMS GATEWAY 121

1 $ s u d o a p t − g e t i n s t a l l i m − ym

Kemudian sesuaikan /et/im/ym/on#g.py, sep erti ontoh b erikut:

1 u s e r s = { ' i n f o r a b ' : ' 1 2 3 4 ' }

dimana inforab adalah Yaho o! aount dan 1234 adalah passwordnya.

Setelah disimpan tunggu satu menit dan p eriksa keb eradaannya.

1 $ p s a x | g r e p ym

2 2 3 3 9 ? S l 2 4 : 4 4 p y t h o n / u s r / b i n /ym i n f o r a b

Log-nya juga tersedia.

1 $ s u d o t a i l − f / v a r / l o g /ym/ i n f o r a b . l o g

2 2 0 1 1 − 0 2 − 2 5 1 4 : 2 4 : 4 6 , 7 2 9 INFO S t a r t u p { ' s t a t u s
' : 0 }

Sekarang oba add buddy dari Yaho o! Messenger lient sep erti Pidgin. Ten-

tu sa ja gunakan Yaho o! aount yang lain. Daemon ym seara otomatis akan

menambahkannya ke dalam daftar.

Selanjutnya kirim p esan sep erti biasa, lalu lihat log-nya:

1 2 0 1 1 − 0 2 − 2 5 1 5 : 1 0 : 4 3 , 8 8 5 INFO I n b o x { ' t g l _ o p e r a
t o r ' :

' 2 0 1 1 − 0 2 − 2 5 1 5 : 1 0 : 4 3 + 7 ' , ' p e s a n ' : ' h e l l o w o r l d


' , '

p e n g i r i m ' : ' i n f o _ r a b ' }

dan lihat juga tab el im.antrian.

1 t o t a l i n d o => SELECT i d , k i r i m , j a l u r , p e n g i r i m , p e n
e r i m a ,
p e s a n

2 t o t a l i n d o − > FROM i m . a n t r i a n ;

3 i d | k i r i m | j a l u r | p e n g i r i m | p e n e r i m a | p e s a n

4 −−−−−− + −−−−−−− + −−−−−−− + −−−−−−−−−− + −−−−−−−−−− + −−−−−−−−−−−−−

5 2 0 7 4 | f | 5 | i n f o _ r a b | i n f o r a b | h e l l o w o r l d

6 ( 1 r o w )

Sekarang p erhatikan kolom jalur yang b erisi 5. Itu artinya jalur ym. Sedan-

gkan jalur mo dem b erisi 1 (default). Daftar jalur ini ada di tab el jalur.

14.3.2 XMPP

Jika Anda punya aount di Gmail maka Anda dapat hatting dengan user

Gmail lainnya. Namun seb enarnya Anda dapat hatting dengan user dari server

lain yang menggunakan protokol XMPP sep erti jabb er.org atau jabb er.rab.o.id.

Ya, sep erti email, protokol XMPP memungkinkan user dari server b erb eda da-

pat saling mengirim p esan.

Jika Anda b erminat menggunakan XMPP untuk hatting dengan server,

pasang paket im-xmpp.

1 $ s u d o a p t − g e t i n s t a l l i m − xmpp

Lalu sesuaikan /et/im/xmpp/on#g.py.

BAB 14. SMS GATEWAY 122

1 u s e r s = { ' i n f o r a b # g m a i l . om ' :

2 { ' p a s s w o r d ' : ' 1 2 3 4 ' , ' s a s l ' : T r u e ,

3 ' p o r t ' : 5 2 2 3 , ' s e r v e r ' : ' t a l k . g o o g l e . om ' }

4 }

Sesuaikan inforab dan 1234. Setelah disimpan tunggu satu menit hingga

daemon-nya up. Setelah hidup, Anda bisa lakukan p engujian yang serupa sep er-

ti ym.

Jika Anda ingin menggunakan server lokal, bisa oba daftar ke jabb er.rab.o.id

menggunakan Pidgin. Lalu sesuaikan /et/im/xmpp/on#g.py sep erti ontoh

b erikut.

1 u s e r s = { ' i n f o r a b # g m a i l . om ' :
2 { ' p a s s w o r d ' : ' 1 2 3 4 ' , ' s a s l ' : T r u e ,

3 ' p o r t ' : 5 2 2 3 , ' s e r v e r ' : ' t a l k . g o o g l e . om ' } ,

4 ' i n f o # j a b b e r . r a b . o . i d ' : ' 1 2 3 4 '

5 }

Ya, im-xmpp juga dapat menghidupkan lebih dari satu aount. Keb etulan

jabb er.rab.o.id menggunakan kon#gurasi yang lebih sederhana sebagaimana

ontoh di atas.

14.4 Broadast

Anda telah memiliki banyak p elanggan dan ingin mengirim p esan yang sama

ke mereka. Dengan mudah lakukan query b erikut.

1 INSERT INTO i m . a n t r i a n ( p e n e r i m a , p e s a n )

2 SELECT n o _ h p , ' S e l a m a t t r a n s a k s i ' FROM p e l a n g g a n ;

Sayangnya untuk jumlah p enerima yang sangat banyak tidak bisa semudah

itu, karena /usr/bin/mo dem memiliki nilai job timeout yang default-nya 420 de-

tik alias 7 menit. Jika setiap p esan membutuhkan waktu 10 detik untuk dikirim,

maka hanya 42 p esan sa ja yang akan dikirim. Selebihnya akan dilap orkan oleh

/usr/bin/mo dem sebagai status -9 alias Timeout.

Menaikkan nilai timeout di /et/im/mo dem/mo dem.onf bisa juga jadi so-

lusi, namun tidak disarankan. Teknik yang paling pas adalah menyiapkan dae-

mon baru yang memantau nilai #eld job. Jika job lebih b esar dari 5 maka tidak

dilakukan INSERT ke im.antrian.

Untuk kebutuhan ini sudah disiapkan paket im-broadast.

1 $ s u d o a p t − g e t i n s t a l l i m − b r o a d a s t

Untuk mengirim p esan kita p erlu melakukan INSERT ke dua tab el, yaitu

im.broadast dan im.broadast_p enerima. Tab el p ertama b erisi p esan, sedan-

gkan tab el kedua b erisi p enerimanya. Kedua tab el ini akan diproses oleh daemon

/usr/bin/im-broadast untuk disalin ke tab el im.antrian.

Pertama kita memerlukan nilai ID untuk broadast yang baru.

BAB 14. SMS GATEWAY 123


1 t o t a l i n d o => SELECT n e x t v a l ( ' i m . b r o a d a s t _ i d _ s e
q ' ) ;

2 n e x t v a l

3 −−−−−−−−−

4 8

5 ( 1 r o w )

Kemudian tambahkan p esannya.

1 t o t a l i n d o => INSERT INTO i m . b r o a d a s t ( i d , j u d u l , p e s


a n )

2 t o t a l i n d o − > SELECT 8 , ' U j i b r o a d a s t ' , ' S e l a m a t t r


a n s a k s i

' ;

3 INSERT 0 1

Field judul hanya untuk keterangan sa ja. Field p esan-lah yang nanti akan

dikirim. Berikutnya tambahkan p enerima p esan.

1 t o t a l i n d o => INSERT INTO i m . b r o a d a s t _ p e n e r i m a ( i d ,

p e n e r i m a )

2 t o t a l i n d o − > SELECT 8 , ' + 6 2 8 1 7 9 1 4 0 0 6 8 ' ;

3 INSERT 0 1

Jalur default yang digunakan adalah 1 (mo dem). Untuk jalur lainnya ser-

takan #eld jalur.

1 t o t a l i n d o => INSERT INTO i m . b r o a d a s t _ p e n e r i m a ( i d ,


p e n e r i m a

, j a l u r )

2 t o t a l i n d o − > SELECT 8 , ' i n f o _ r a b ' , 5 ;

3 INSERT 0 1

Dimana jalur 5 adalah ym.

Bab 15

Web

15.1 Django

15.2 Webpy
124

Bab 16

Hosting

16.1 Virtualmin

Ingin b erbisnis web hosting ? Terb entur biaya untuk p engadaan CPanel ? Saat-

nya menggunakan Virtualmin


1

. Ingin membidik pangsa develop er Python se-

lain pangsa PHP ? Anda masih bisa mengubah kemampuan Virtualmin. Tidak

punya IP publik statik ? Hanya dapat IP publik dinamik ? Jangan ragu, tetap

gunakan Virtualmin.

Virtualmin merupakan antarmuka web untuk mengatur b erbagai hal terkait

dengan bisnis web hosting Anda. Ia memb erikan kemudahan dalam p endaf-

taran domain, p emb erian hak akses, dan juga kuota. Ia merupakan pro duk op en

soure yang mengatur b erbagai aplikasi standar lainnya sep erti Apahe, PHP,

Post#x, Doveot, PostgreSQL, dst. Namun b egitu, ia menghindari "sentuhan

sihir" alias tetap mengikuti aturan-aturan yang ditetapkan masing-masing ap-

likasi tersebut.

16.1.1 Pemasangan Ubuntu

Ya, kita akan gunakan Ubuntu


2

di sini. Kebiasaan Virtualmin adalah meng-

gunakan Ubuntu jenis LTS (Long Term Supp ort), sep erti Hardy (8.04) atau

Luid (10.04). Kali ini kita akan gunakan versi 10.04 dimana Anda bisa pilih

untuk prosesor 32 bit (i386) atau 64 bit (amd64). Paling aman gunakan i386,

tapi prosesor terbaru rata-rata sudah mendukung versi amd64, bahkan yang

dikeluarkan Intel sekalipun.

Oh iya, ada lagi p engkategorian lainnya, yaitu versi desktop atau server. Jika

server sering b erada di depan Anda - misalkan server ada di rumah - sebaiknya

pilih yang desktop, karena telah dilengkapi GUI


3
, sehingga Firefox tersedia.

Namun jika server diletakkan nun jauh di sana, pilihlah versi server agar Anda

tidak b erlama-lama saat melakukan upgrade.

http://virtualmin.om

http://ubuntu.om

Graphial User Interfae

125

BAB 16. HOSTING 126

Amannya pilih yang mana ? Pilihlah Ubuntu 10.04 i386 Desktop Edition
4

ISO bisa di-burn ke CD-ROM 700 MB. Rata-rata motherb oard sekarang su-

dah mendukung b o ot melalui #ashdisk. Jadi ada baiknya burn ISO ke #ashdisk

menggunakan aplikasi Unetb o otin, tersedia untuk sistem op erasi Windows dan

Linux.

Setelah di-burn, b o ot, dan ikuti langkah-langkah p etunjuk p emasangannya.

Sebaiknya pilihlah Bahasa Indonesia agar default format sesuai dengan Indone-

sia sep erti format tanggal (dmy), p emisah ribuan (thousand separator), dsb.

Setelah p emasangan selesai dan server sudah di-b o ot, ubahlah hak akses

pada home diretory Anda agar user lain tidak bisa melihat isinya.

$ hmod 750 /home/sugiana

Anda tidak p erlu melakukan ini jika membuat user baru melalui Virtualmin

nanti.

16.1.2 Kon#gurasi Network

Untuk menetapkan IP, Anda bisa menggunakan menu System, Preferenes, Net-

work Connetions. Jika Anda tidak memasang GUI, bisa lakukan kon#gurasi

melalui #le /et/network/interfaes sep erti ini:


1 i f a e e t h 0 i n e t s t a t i

2 a d d r e s s 2 0 2 . 5 9 . 2 0 1 . 6 7

3 n e t m a s k 2 5 5 . 2 5 5 . 2 5 5 . 1 9 2

4 g a t e w a y 2 0 3 . 1 3 0 . 2 3 1 . 6 5

Lalu reb o ot server untuk memastikan kon#gurasi dijalankan saat server

hidup. Kemudian ujilah dengan mengunjungi salah satu IP yang Anda kenal:

$ telnet 203.130.231.120 80

Jika Anda mendapati baris "Esap e harater is" b erarti gateway b erfungsi

dengan baik:

Trying 203.130.231.120...

Conneted to 203.130.231.120.

Esape harater is '^℄'.

Oh iya, juga sesuaikan /et/resolv.onf agar Anda bisa memanggil dengan nama

(DNS), misalnya:

nameserver 203.130.231.120

Lalu ujilah DNS ini dengan memanggil nama:

http://op enstorage.gunadarma.a.id/linux/iso/ubuntu/lu id/ubunt u-10.04-deskt op-

i386.iso

BAB 16. HOSTING 127

$ telnet google.om 80

Trying 74.125.235.20...

Conneted to google.om.

Esape harater is '^℄'.

Sesuaikanlah gateway dan DNS ini dengan menanyakan ke Internet Servie

Provider Anda.

Server Anda terhubung dengan mo dem ADSL ? Biasanya IP sudah dis-

et seara otomatis melalui mekanisme DHCP. Meski b egitu sebaiknya Anda

memastikan IP LAN tetap statik. Bisa diset melalui menu tadi, atau melalui

mo dem ADSL-nya dimana biasanya mo dem akan menentukan MAC address


00:1f:3:e0:66:56 mendapat IP 192.168.1.2 (ontoh).

16.1.3 Pemasangan Virtualmin

Sudah terhubung ke Internet ? Selanjutnya unduh sript instalasinya:

$ wget http://software.virtualmin.om/gpl/sripts/install.sh

Lalu jalankan:

$ sudo sh install.sh

Saat ia menanyakan hostname, jawablah sesuai nama domain hosting yang Anda

kelola:

Please enter a fully quali#ed hostname (for example, example.om):

sabilawebhosting.om

Lalu saat ia menanyakan network interfae, p eriksalah di konsole lain dengan

ifon#g, interfae apa yang digunakan. Kalau terhubung dengan kab el biasanya

eth0, kalau wireless biasanya wlan0:

Please enter the name of your primary network interfae: eth0

Selanjutnya ia mengunduh aplikasi yang dip erlukan dan melakuan kon#gurasi.

Tunggulah, ini memerlukan waktu b eb erapa lama. Jika b erhasil, p esan ter-

akhirnya adalah:

INFO - Rule up dates done

Namun ada kalanya Anda mendapatkan p esan ini:

FATAL - in /ro ot/virtualmin-install.log

Kadang selama proses unduh terjadi "onnetion refused". Mungkin server

Virtualmin sedang di-restart. Tunggulah b eb erapa saat, dan jalankan lagi sript

instalasi sep erti tadi.

$ sudo sh install.sh

Biasanya ia mengerti untuk tidak melakukannya dari awal.

BAB 16. HOSTING 128

16.1.4 Text Editor

Jika Anda menggunakan GUI, gedit bisa digunakan untuk text editor:

$ sudo gedit
Namun jika Anda terbiasa dengan konsole, vi dan nano sudah tersedia. Bagi

yang terbiasa dengan vi ada baiknya pasang vim (vi improved) untuk kenya-

manan:

$ sudo apt-get install vim

Lalu sesuaikan b eb erapa kon#gurasi pada /et/vim/vimr . Kon#gurasi b erikut

ini untuk mengingat p osisi kursor pada #le yang p ernah Anda buka:

1 " U n o m m e n t t h e f o l l o w i n g t o h a v e Vim j u m p t o t h e l a
s t

p o s i t i o n w h e n

2 " r e o p e n i n g a f i l e

3 i f h a s ( " a u t o m d " )

4 a u B u f R e a d P o s t * i f l i n e ( " ' \ " " ) > 1 && l i n e ( " ' \ "


" ) <=

l i n e ( " $ " ) | e x e " n o r m a l ! g ' \ " " | e n d i f

5 e n d i f

Terkait dengan p enulisan soure, pastikan auto-indent b ekerja. Gunakan

karakter spasi untuk indent ketimbang karakter tab:

1 " U n o m m e n t t h e f o l l o w i n g t o h a v e Vim l o a d i n d e n t a
t i o n

r u l e s a n d p l u g i n s

2 " a o r d i n g t o t h e d e t e t e d f i l e t y p e .

3 i f h a s ( " a u t o m d " )

4 f i l e t y p e p l u g i n i n d e n t o n

5 s e t s m a r t i n d e n t

6 s e t e x p a n d t a b

7 s e t t a b s t o p =4

8 s e t s o f t t a b s t o p =4

9 s e t s h i f t w i d t h =4

10 e n d i f

Aktifkan p enarian pintar dimana kalau Anda menuliskan huruf keil semua

saat p enarian maka tidak memp edulikan huruf keil ataupun b esar (inase-
sensitive). Namun jika Anda menyertakan huruf b esar maka ase-sensitive

b erlaku.

1 s e t i g n o r e a s e " Do a s e i n s e n s i t i v e m a t h i n g

2 s e t s m a r t a s e " Do s m a r t a s e m a t h i n g

Selesai dan simpanlah. Kon#gurasi ini seara otomatis juga b erlaku bagi

user Anda nantinya. Sehingga kenyamanan programmer makin b ertambah.

BAB 16. HOSTING 129

16.1.5 Kon#gurasi PHP

Ya, kita atur dulu urusan PHP sebagai bahasa yang umum digunakan oleh

p engembang web. Pasang mo dul suphp agar setiap sript PHP dijalankan oleh

p emiliknya:

$ sudo apt-get install libapahe2-mod-suphp

Pastikan direktori /home sebagai basis suphp, ubah /et/suphp/suphp.onf ,

ganti baris

doroot=/var/www:${HOME}/publi_html

menjadi

doroot=/home

Non-aktif-kan mo dul php5 karena sudah diganti dengan mo dul suphp:

$ sudo a2dismod php5

Kemudian pasang mo dul untuk PostgreSQL, MySQL, dan gra#k:

$ sudo apt-get install php5-pgsql php5-mysql php5-gd

Ubahlah /et/php5/gi/php.ini agar p engunjung web nyaman unggah video:

1 m a x _ e x e u t i o n _ t i m e = 1 0 0 0

2 m a x _ i n p u t _ t i m e = 1 0 0 0

3 m e m o r y _ l i m i t = 1 2 8M

4 p o s t _ m a x _ s i z e = 1 0 0M

5 u p l o a d _ m a x _ f i l e s i z e = 1 0 0 0M

Lalu restart web server:

$ sudo servie apahe2 restart

Kon#gurasi PHP selesai.


16.1.6 Mail Server

Post#x p erlu diatur agar b oleh menerima relay dari network lain. Misalkan user

mengirim email dari noteb o ok menggunakan Thunderbird. Ubah /et/post#x/-

master.f , aktifkan baris submission dan smtps :

1 s u b m i s s i o n i n e t n − − − − s m t p d

2 s m t p s i n e t n − − − − s m t p d

Karena user aount menggunakan Linux user, ubahlah /et/default/saslau-

thd, dari baris:

BAB 16. HOSTING 130

MECHANISMS="pam"

menjadi

MECHANISMS="shadow"

Restart daemon-nya:

$ sudo servie saslauthd restart

$ sudo servie postfix restart

16.1.7 PostgreSQL

Sebaiknya Anda p eriksa default eno ding yang digunakan PostgreSQL.

$ sudo su postgres - "psql - '\l'"

Kalau eno ding masih SQL_ASCI I b erarti Anda harus menggantinya ke UTF8.

Mengapa ? Karena SQL_ASCI I bisa b erarti "kalau ada karakter sampah,

biarkan sa ja". Berikut ini ara mengubahnya:

$ sudo pg_dropluster --stop 8.4 main

$ sudo pg_reateluster --start -e UTF-8 8.4 main

16.1.8 Kon#gurasi Awal Virtualmin

Berikutnya kon#gurasi awal melalui web. Jika Anda memasang desktop, bisa

langsung ke url:

https://127.0.0.1:10000

Namun jika server sudah b erada di remote, Anda bisa gunakan IP publiknya

sehingga url menjadi (ontoh):


https://202.59.201.67:10000

Selanjutnya web Virtualmin meminta kita untuk login menggunakan superuser ,

dalam hal ini user saat p emasangan Ubuntu p ertama kali.

Pada awal login, Anda dihadapkan pada wizard untuk kon#gurasi. Seara

umum Anda ukup memilih Yes dan klik Next hingga selesai. Setelah Next

terakhir di-klik, Anda diminta untuk klik:

Re-hek and refresh on#guration

Jika lanar, Anda akan menemui p esan ini:

.. your system is ready for use by Virtualmin.

Jika server b erada di b elakang #rewall, misalnya Anda menggunakan mo dem

ADSL sebagai gateway, biasanya akan menemui p esan b erikut ini:

BAB 16. HOSTING 131

Default IP address is set to 192.168.1.2, but the deteted external

address is atually 180.252.150.215. This is typially the result of

b eing b ehind a NAT #rewall, and should b e orreted on the mo dule

on#guration page.

Jika IP publik server adalah statik, maka lanjutkan klik mo dule on#guration

yang dimaksud. Atau seara menu melalui System Settings, Virtualmin Con-

#guration . Pada pilihan Con#guration Category , pilih Network settings , lalu:

Default IP address for DNS reords: Automatially detet ex-

ternal address

Klik Save. Jangan lupa mengatur mo dem ADSL untuk mengarahkan seluruh

p ermintaan dari luar ke server 192.168.1.2. Mekanisme ini sering disebut sebagai

p ort forwarding, atau ada juga yang bilang DMZ.

Jika Anda tidak p ernah memesan IP publik statik pada ISP, hampir di-

pastikan Anda hanya mendapat IP publik dinamik. Dengan demikian abaikan

sa ja urusan DNS di atas, karena DNS yang Anda butuhkan p erlu ditangani

server lain yang memiliki IP publik statik, misalnya dyndns.org .

Yang lebih mengkhawatirkan lagi bila server tidak mendapatkan IP publik.

Ini artinya server tidak bisa disentuh (baa: di- route ) dari luar. Praktis Anda
tidak bisa b erbisnis hosting. Untuk memastikannya, oba minta teman Anda

yang ada di "seb erang" sana untuk mengakses http://180.252.150.215.

Sesuaikanlah IP-nya sebagaimana yang dilap orkan Virtualmin di atas. Jika

ia mendapatkan p esan:

It works!

maka server Anda telah memiliki IP publik.

16.1.9 Mail Aount

Seara default, Virtualmin menggunakan format user.domain untuk IMAP lo-

gin . Akan lebih nyaman bila formatnya menggunakan user#domain , agar sama

dengan emailnya. Ikuti langkah b erikut ini:

1. Masuk ke menu System Settings, Server Templates, Default Settings .

2. Pada bagian Edit template setion , pilihlah Mail for domain .

3. Pada bagian Format for usernames that inlude domain pilihlah user-

name#domain .

4. Klik Save.

Khusus administrator domain b ersangkutan, IMAP login tidak memerlukan

#domain . Lebih jelasnya Anda bisa lihat di menu Edit Mail and FTP users

kolom IMAP/FTP login , setelah Anda membuat domain nanti.

BAB 16. HOSTING 132

16.1.10 Hak Akses

Berikanlah user hak untuk membuat virtual server . Ini artinya jika user Anda

memiliki domain reymanx.web.id , maka ia dapat membuat sub domain


blog.reymanx.web.id ,

download.reymanx.web.id , dst. Atur melalui menu System Settings, Aount

Plans, Default Plan :

Limit on numb er virtual servers: Unlimited

Klik Save.

16.1.11 Berikan Bash

Bila nanti user login menggunakan ssh (seure shell), ia akan mendapat shell

sederhana, yaitu /bin/sh . Terus terang, shell ini kurang nyaman, dimana tidak
memiliki history dan autoompletion . Sebaiknya Anda memb erikan /bin/bash .

Klik menu System Customization, Custom Shel l, Custom shel ls below . Gantilah

/bin/sh menjadi /bin/bash , lalu klik Save.

Aktifkan auto ompletion di /et/bash.bashr :

1 # e n a b l e b a s h o m p l e t i o n i n i n t e r a t i v e s h e l l s

2 i f [ − f / e t / b a s h _ o m p l e t i o n ℄ && ! s h o p t − o q p o s i
x ; t h e n

3 . / e t / b a s h _ o m p l e t i o n

4 f i

Agar lebih nyaman dalam memasang b erbagai aplikasi dari GitHub dan

Bitbuket, pasanglah aplikasi p engunduhnya:

$ sudo apt-get install git-ore merurial

16.1.12 Kon#gurasi Python

Ya, akhirnya kita sampai ke bagian ini, dimana user seara default menggunakan

Python untuk membuat web. Pasanglah mo dul WSGI untuk Apahe:

$ sudo apt-get install libapahe2-mod-wsgi

Juga Virtual Environment agar user dimudahkan dalam memasang mo dul Python

lainnya tanpa p erlu memanggil Anda sebagai p engelola hosting.

$ sudo apt-get install python-virtualenv

Driver untuk akses database juga p erlu disiapkan:

$ sudo apt-get install python-psyopg2 python-mysqldb

Virtualmin sudah menyediakan apa yang disebut Server Template . Saat p endaf-

taran domain, admin dib erikan kesempatan memilih bahasa apa yang akan di-

gunakan p elanggannya. Default-nya adalah PHP, dan alternatif lain adalah

BAB 16. HOSTING 133

Python. Pilihan ini terdapat di menu Create Virtual Server, Server on#gu-

ration template . Di sana ada pilihan Default Settings yang b erarti PHP yang

digunakan dengan direktori publi_html sebagai DoumentRoot .

Lalu dimana pilihan Python ? Seharusnya ada di bawahnya, namun saat ini

b elum ada. Inilah yang akan kita buat sekarang.


Masuklah ke menu System Settings, Server Templates, Create a template

from the default settings . Isilah:

Template name: Python (b ebas)

For use by: Sub-servers (entang)

Klik Create and Next . Pada bagian Edit template setion , pilih Apahe website .

Ini untuk mengganti form isian dengan hal-hal yang b ersifat Apahe. Pada

bagian Diretives and settings for new websites , dan pada radio button Apahe

diretives below tambahkan baris-baris WSGI b erikut ini (paling bawah):

WSGISriptAlias / ${HOME}/wsgi/wsgi_handler.py

WSGIDaemonProess ${DOM} user=${USER} group=${GROUP} threads=15

WSGIProessGroup ${DOM}

Klik Save.

16.1.13 Mengubah Sifat Virtualmin

Seara default Virtualmin menyiapkan direktori $HOME/publi_html untuk

soure PHP, dimana bila URL yang dimaksud dipanggil melalui browser - mis-

alkan http://sabilawebhosting.om - maka soure PHP yang ada di direktori

itulah yang dijalankan Apahe. Istilahnya root doument . Karena kita juga

akan membangun Python hosting, maka root doument akan diganti dengan

sript $HOME/wsgi/wsgi_hand ler.py .

Seb enarnya dengan apa yang Anda sudah pasang tadi sudah ukup bagi

user untuk menyiapkan segala sesuatunya. Namun sebagai p engelola hosting

yang memahami kebutuhan p elanggan, sebaiknya Anda menyiapkan sript yang

dimaksud, lengkap dengan Python virtual environment pada home diretory .

Untunglah Virtualmin memb eri kesempatan pada kita untuk menyisipkan

sript yang dijalankan setelah sebuah domain dibuat. Praktis ini mengurangi

sentuhan manual saat p endaftaran domain.

Masuklah ke menu System Settings, Virtualmin Con#guration . Pada Con-

#guration ategory , pilihlah Ations upon server and user reation . Lalu pada

Command to run after making hanges to a server isilah:


/usr/loal/bin/virtualmin

Klik Save. Selanjutnya buatlah sript b erikut ini.

Listing 16.1: /usr/lo al/bin/virtualmin

1 # ! / u s r / b i n / p y t h o n

BAB 16. HOSTING 134

3 i m p o r t o s

4 i m p o r t s y s

6 i f o s . e n v i r o n [ ' VIRTUALSERVER_ACTION ' ℄ == 'CREATE_DOMAIN ' :

7 o s . s y s t e m ( ' p − r / u s r / l o a l / e t / v i r t u a l m i
n / w s g i %s ' % (

8 o s . e n v i r o n [ 'VIRTUALSERVER_HOME ' ℄ ) )

9 o s . s y s t e m ( ' d %s / w s g i ; l n − s . w s g i ' % o s . e
n v i r o n [ '

VIRTUALSERVER_HOME ' ℄ )

10 o s . s y s t e m ( ' v i r t u a l e n v %s / e n v ' % o s . e n v i r o n
[ '

VIRTUALSERVER_HOME ' ℄ )

11 o s . s y s t e m ( ' h o w n − R %s . % s %s / w s g i %s / e n v ' % (

12 o s . e n v i r o n [ ' VIRTUALSERVER_USER ' ℄ ,

13 o s . e n v i r o n [ ' VIRTUALSERVER_GROUP ' ℄ ,

14 o s . e n v i r o n [ 'VIRTUALSERVER_HOME ' ℄ ,

15 o s . e n v i r o n [ 'VIRTUALSERVER_HOME ' ℄ ) )

Pastikan exeutable:

$ sudo hmod 755 /usr/loal/bin/virtualmin

Lalu siapkan direktori /usr/loal/et/virtualmin/wsgi yang nantinya akan di-

taruh di $HOME/ :

$ sudo mkdir -p /usr/loal/et/virtualmin/wsgi

Buatlah monitoring sript yang b erguna untuk autoreload daemon Python.

Daemon Python ?
Ya. Setiap sript Python yang dibuat oleh user akan dijalankan oleh Apahe

sebagai daemon, dalam sebuah sub-pro ess. Monitoring sript b erguna untuk

memantau p erubahan #le pada direktori $HOME/wsgi. Bila sript ini menda-

pati ada #le yang b erubah, seara otomatis ia akan mengakhiri dirinya sendiri,

dan pada saat URL situs dipanggil lagi melalui browser, Apahe - seara otoma-

tis pula - menghidupkan kembali daemon ini.


5

Listing 16.2: /usr/lo al/et/virtualmin/wsgi/monitor.py

1 i m p o r t o s

2 i m p o r t s y s

3 i m p o r t t i m e

4 i m p o r t s i g n a l

5 i m p o r t t h r e a d i n g

6 i m p o r t a t e x i t

7 i m p o r t Q u e u e

9 _ i n t e r v a l = 1 . 0

Interpreter Python mengizinkan kita untuk mengubah #le *.py selama sript sedang b
er-

jalan ( runtime ). Namun p erubahan itu b erfungsi saat sript itu dijalankan ulang.

BAB 16. HOSTING 135

10 _ t i m e s = { }

11 _ f i l e s = [ ℄

12

13 _ r u n n i n g = F a l s e

14 _ q u e u e = Q u e u e . Q u e u e ( )

15 _ l o k = t h r e a d i n g . L o k ( )

16

17 d e f _ r e s t a r t ( p a t h ) :

18 _ q u e u e . p u t ( T r u e )
19 p r e f i x = ' m o n i t o r ( p i d=%d ) : ' % o s . g e t p i d ( )

20 p r i n t >> s y s . s t d e r r , '%s C h a n g e d e t e t e d t o \
' % s \ ' . '

% ( p r e f i x , p a t h )

21 p r i n t >> s y s . s t d e r r , '%s T r i g g e r i n g p r o e s s r
e s t a r t . '

% p r e f i x

22 o s . k i l l ( o s . g e t p i d ( ) , s i g n a l . S I G I N T )

23

24 d e f _ m o d i f i e d ( p a t h ) :

25 t r y :

26 # I f p a t h d o e s n ' t d e n o t e a f i l e a n d w e r e

p r e v i o u s l y

27 # t r a k i n g i t , t h e n i t h a s b e e n r e m o v e d o r t h e

f i l e t y p e

28 # h a s h a n g e d s o f o r e a r e s t a r t . I f n o t

p r e v i o u s l y

29 # t r a k i n g t h e f i l e t h e n w e a n i g n o r e i t a s

p r o b a b l y

30 # p s e u d o r e f e r e n e s u h a s w h e n f i l e e x t r a t e d

f r o m a

31 # o l l e t i o n o f m o d u l e s o n t a i n e d i n a z i p f i l e .

32

33 i f n o t o s . p a t h . i s f i l e ( p a t h ) :

34 r e t u r n p a t h i n _ t i m e s

35

36 # C h e k f o r w h e n f i l e l a s t m o d i f i e d .

37

38 m t i m e = o s . s t a t ( p a t h ) . s t _ m t i m e

39 i f p a t h n o t i n _ t i m e s :
40 _ t i m e s [ p a t h ℄ = m t i m e

41

42 # F o r e r e s t a r t w h e n m o d i f i a t i o n t i m e h a s

h a n g e d , e v e n

43 # i f t i m e n o w o l d e r , a s t h a t o u l d i n d i a t e o l d e r

f i l e

44 # h a s b e e n r e s t o r e d .

45

46 i f m t i m e ! = _ t i m e s [ p a t h ℄ :

BAB 16. HOSTING 136

47 r e t u r n T r u e

48 e x e p t :

49 # I f a n y e x e p t i o n o u r e d , l i k e l y t h a t f i l e h a s

b e e n

50 # b e e n r e m o v e d j u s t b e f o r e s t a t ( ) , s o f o r e a

r e s t a r t .

51

52 r e t u r n T r u e

53

54 r e t u r n F a l s e

55

56 d e f _ m o n i t o r ( ) :

57 w h i l e 1 :

58 # C h e k m o d i f i a t i o n t i m e s o n a l l f i l e s i n s y s .

m o d u l e s .

59

60 f o r m o d u l e i n s y s . m o d u l e s . v a l u e s ( ) :

61 i f n o t h a s a t t r ( m o d u l e , ' _ _ f i l e _ _ ' ) :

62 o n t i n u e

63 p a t h = g e t a t t r ( m o d u l e , ' _ _ f i l e _ _ ' )
64 i f n o t p a t h :

65 o n t i n u e

66 i f o s . p a t h . s p l i t e x t ( p a t h ) [ 1 ℄ i n [ ' . p y ' , ' .

p y o ' , ' . p y d ' ℄ :

67 p a t h = p a t h [ : − 1 ℄

68 i f _ m o d i f i e d ( p a t h ) :

69 r e t u r n _ r e s t a r t ( p a t h )

70

71 # C h e k m o d i f i a t i o n t i m e s o n f i l e s w h i h h a v e

72 # s p e i f i a l l y b e e n r e g i s t e r e d f o r m o n i t o r i n g .

73

74 f o r p a t h i n _ f i l e s :

75 i f _ m o d i f i e d ( p a t h ) :

76 r e t u r n _ r e s t a r t ( p a t h )

77

78 # Go t o s l e e p f o r s p e i f i e d i n t e r v a l .

79

80 t r y :

81 r e t u r n _ q u e u e . g e t ( t i m e o u t = _ i n t e r v a l )

82 e x e p t :

83 p a s s

84

85 _ t h r e a d = t h r e a d i n g . T h r e a d ( t a r g e t =_ m o n i t o r )

86 _ t h r e a d . s e t D a e m o n ( T r u e )

87

88 d e f _ e x i t i n g ( ) :

BAB 16. HOSTING 137

89 t r y :

90 _ q u e u e . p u t ( T r u e )
91 e x e p t :

92 p a s s

93 _ t h r e a d . j o i n ( )

94

95 a t e x i t . r e g i s t e r ( _ e x i t i n g )

96

97 d e f t r a k ( p a t h ) :

98 i f n o t p a t h i n _ f i l e s :

99 _ f i l e s . a p p e n d ( p a t h )

100

101 d e f s t a r t ( i n t e r v a l = 1 . 0 ) :

102 g l o b a l _ i n t e r v a l

103 i f i n t e r v a l < _ i n t e r v a l :

104 _ i n t e r v a l = i n t e r v a l

105

106 g l o b a l _ r u n n i n g

107 _ l o k . a q u i r e ( )

108 i f n o t _ r u n n i n g :

109 p r e f i x = ' m o n i t o r ( p i d=%d ) : ' % o s . g e t p i d ( )

110 p r i n t >> s y s . s t d e r r , '%s S t a r t i n g h a n g e m o n i


t o r .

' % p r e f i x

111 _ r u n n i n g = T r u e

112 _ t h r e a d . s t a r t ( )

113 _ l o k . r e l e a s e ( )

Anda bisa salin dari situs aslinya:

http://o de.go ogle.om/p/mo dwsgi/wiki/ReloadingSoureCo de

Selanjutnya buat root doument .

Listing 16.3: wsgi_handler.py

1 d e f a p p l i a t i o n ( e n v i r o n , s t a r t _ r e s p o n s e ) :
2 s t a t u s = ' 2 0 0 OK '

3 o u t p u t = ' H e l l o W o r l d ! '

4 r e s p o n s e _ h e a d e r s = [ ( ' C o n t e n t −t y p e ' , ' t e x t / p


l a i n ' ) ,

5 ( ' C o n t e n t − L e n g t h ' , s t r ( l e n ( o u t p u t

) ) ) ℄

6 s t a r t _ r e s p o n s e ( s t a t u s , r e s p o n s e _ h e a d e r s )

7 r e t u r n [ o u t p u t ℄

10 i m p o r t o s , s y s

11

12 s y s . s t d o u t = s y s . s t d e r r

BAB 16. HOSTING 138

13 s y s . p a t h . a p p e n d ( o s . p a t h . d i r n a m e ( o s . p a t h .
a b s p a t h ( _ _ f i l e _ _ )

) )

14 e n v _ v e r = ' . ' . j o i n ( map ( lambda x : s t r ( x ) , s y s . v e r s


i o n _ i n f o

[ : 2 ℄ ) )

15 e n v _ p a t h = o s . p a t h . d i r n a m e ( o s . p a t h . d i r n a m e
( o s . p a t h .

a b s p a t h ( _ _ f i l e _ _ ) ) ) + \

16 ' / e n v / l i b / p y t h o n%s / s i t e −p a k a g e s ' % e n v _ v e r

17 s y s . p a t h . a p p e n d ( e n v _ p a t h )

18

19 #o s . e n v i r o n [ ' DJANGO_SETTINGS_MODULE ' ℄ = ' m y p r o j e t .

s e t t i n g s '

20 #i m p o r t d j a n g o . o r e . h a n d l e r s . w s g i

21 # a p p l i a t i o n = d j a n g o . o r e . h a n d l e r s . w s g i . W S
G I H a n d l e r ( )

22
23 i m p o r t m o n i t o r

24 m o n i t o r . s t a r t ( i n t e r v a l = 1 . 0 )

Selesai sudah kon#gurasi server. Kini saatnya pro dution.

16.1.14 Pendaftaran Domain

Mari dimulai dengan membuat domain p erusahaan hosting Anda sendiri, dalam

hal ini sabilawebhosting.om . Masih di Virtualmin, masuk ke menu Create Vir-

tual Server . Isilah:

Domain name: sabilawebhosting.om

Administration password: ****

Server on#guration template: Python

Klik Create Server . Sekarang obalah kunjungi:

http://sabilawebhosting.om

Kalau Anda menjumpai:

Hello world!

b erarti p endaftaran sudah b erlangsung dengan baik. Bila Anda menjumpai:

Server not found

hampir dipastikan domain tersebut b elum sep enuhnya dikenal oleh para ISP.

Jika Anda browsing di server pastikan baris b erikut ini ada di urutan teratas

/et/resolv.onf :

nameserver 127.0.0.1

Namun jika Firefox Anda b erada di mesin b erb eda, pastikan DNS teratas adalah

IP server, masih di /et/resolv.onf dimana Firefox b erada:

BAB 16. HOSTING 139

nameserver 202.59.201.67

Anda bisa membuka Virtualmin dengan sub domain admin , yaitu dengan url:

http://admin.sabilawebhosting.om

Hal serupa dapat dilakukan oleh p elanggan Anda sesuai domain mereka masing-

masing.

Sedangkan untuk mail, mereka bisa mengunjungi sub domain webmail , dalam
hal ini ontohnya adalah:

http://webmail.sabilawebhosting.om.

16.1.15 User Spae

User dip erkenankan melakukan SSH ke server dengan username awalan nama

domain (default). Jadi jika Anda membuat reymanx.web.id maka Virtualmin

seara otomatis akan membuat user reymanx .

Katakanlah user reymanx ingin memasang Django


6

, maka setelah ia SSH ke

server, ia bisa gunakan pip yang tersedia di virtual environment


7

$ env/bin/pip install django

Setelah selesai mulailah membuat pro jet:

$ d wsgi

$ ../env/bin/django-admin.py startprojet myprojet

Lalu ubahlah $HOME/wsgi/wsgi_hand ler.py menjadi sep erti ini:

Listing 16.4: wsgi_handler.py untuk Django

1 i m p o r t o s , s y s

3 s y s . s t d o u t = s y s . s t d e r r

4 s y s . p a t h . a p p e n d ( o s . p a t h . d i r n a m e ( o s . p a t h . a
b s p a t h ( _ _ f i l e _ _ )

) )

5 e n v _ v e r = ' . ' . j o i n ( map ( lambda x : s t r ( x ) , s y s . v e r s


i o n _ i n f o

[ : 2 ℄ ) )

6 e n v _ p a t h = o s . p a t h . d i r n a m e ( o s . p a t h . d i r n a m e (
o s . p a t h .

a b s p a t h ( _ _ f i l e _ _ ) ) ) + \

7 ' / e n v / l i b / p y t h o n%s / s i t e −p a k a g e s ' % e n v _ v e r

8 s y s . p a t h . a p p e n d ( e n v _ p a t h )
9

10 o s . e n v i r o n [ ' DJANGO_SETTINGS_MODULE ' ℄ = ' m y p r o j e t .

s e t t i n g s '

11 i m p o r t d j a n g o . o r e . h a n d l e r s . w s g i

http://djangopro jet.om

Python virtual environment otomatis terb entuk saat p embuatan domain.

BAB 16. HOSTING 140

12 a p p l i a t i o n = d j a n g o . o r e . h a n d l e r s . w s g i . W S G
I H a n d l e r ( )

13

14 i m p o r t m o n i t o r

15 m o n i t o r . s t a r t ( i n t e r v a l = 1 . 0 )

Kembali ke Firefox url http://reymanx.web.id , seharusnya tampil:

It worked!

Beb erapa hal lain yang biasa digunakan user adalah:

ˆ Untuk p embuatan alias, misalnya untuk path /site_media/ , bisa melalui

Virtualmin, yaitu menu Servies, Con#gure Website, Aliases and Redi-

rets . Isilah pada bagian Doument diretory aliases . Misalkan From diisi

/site_media/ , dan To diisi /home/reymanx/wsgi/myprojet/site_media/ .

Klik Save. Perubahan baru tersimpan sa ja, b elum dilaksanakan. Untuk

p elaksanaannya klik Apply Changes di kanan atas.

ˆ Untuk mendaftarkan ron job (sheduler), masuk ke menu Webmin Mod-

ules, Sheduled Cron Jobs .

ˆ Pendaftaran sub domain melalui menu Create Virtual Server .

Oh iya, seb enarnya juga tersedia Installer Django di sini. Namun tidak dis-

arankan karena masih menggunakan Fast CGI (konon yang terbaik menggu-

nakan WSGI sep erti yang sudah diulas).

Template telah siap. Kini obalah mendaftarkan domain baru pada menu
Create Virtual Server . Setelah memasukkan Domain name dan Administration

password , pilih Python pada Server on#guration template . Klik Create Server .

Kini obalah mengunjungi domain baru tersebut, seharusnya dijumpai p e-

san:

Hello World!

yang b erasal dari #le wsgi/wsgi_hand ler.py . Jika tadi Anda pilih Default Set-

tings pada Server on#guration template , seharusnya Anda menjumpai p esan:

Forbidden

yang artinya Apahe mengharapkan #le publi_html/index.php .

16.2 Go ogle Apps

Bibliogra#

[1℄ http://jabb er.rab.o.id/os/web-admin-dengan-virtualmin

[2℄ http://jabb er.rab.o.id/os/pasa-instalasi-linux

[3℄ http://jaobian.org/writing/pg-eno ding-ubuntu

[4℄ https://onvore.om/id-python/gathering-online-22-july-2011

[5℄ http://o de.go ogle.om/p/mo dwsgi/wiki/ReloadingSoureCo de

141

Indeks

__name__, 35

ALTER TABLE, 50, 51

Android, 5

apt-get install, 6

apt-get up date, 6

autoinrement #eld, 46

BlankOn, 6

break, 14

ontinue, 15

CREATE TABLE, 44

CREATE VIEW, 52

reatedb, 43
reateuser, 42

Data De#nition Language, 51

Data Manipulation Language, 51

date(), 30

datestyle, 48

datetime(), 30

DEFAULT, 44

DELETE FROM, 50

DROP TABLE, 51

drop db, 43

dropuser, 42

ep o h, 29

eval(), 20

#oat, 11

for, 16

formatting, 17, 19

fullpath, 54

Gnome, 7

int(), 19, 27
integer, 11

KDE, 6, 7

konsole, 6

length(), 56

Linux, 5

lo ale-gen, 38

lo altime(), 28

lower(), 9

lpad(), 56

Ma, 5

mktime(), 29
mo dul datetime, 30

mo dul lo ale, 37

mo dul time, 28

nextval(), 47

None, 39

NOT NULL, 44

ob jek hampa, 39

ORDER BY, 48

ORDER BY, DESC, 49

pg_dump, 54

pg_restore, 54

plpgsql, 6

plpython, 6

p ostgresql.onf, 48

PRIMARY KEY, 44

print, 9, 20

psql, 6, 43

rata kanan, 55

raw_input(), 10, 27

sequene, 46

142

INDEKS 143

serial, 46

sisa p embagian, 18

SQLAlhemy, 6

string, 9, 11

sudo, 42

Symbian, 5

text editor, 7
time(), 29

tip e data ditionary, 26

tip e data #oat, 18

tip e data integer, 18

tip e data list, 20

transation, 72

transation, auto ommit, 72

typ e(), 17

Ubuntu, 6

Unix, 5

Unix time, 29

UPDATE, 50

upp er(), 9

variab el, 11

vi, 7

while, 15

Вам также может понравиться