2012
Daftar Isi
1 Alasan
2 Pemasangan
3 Hello World!
3.1
3.2
Kondisi
3.3
Perulangan
4 Tipe Data
5
6
9
. . . . . . . . . . . . . . . . . . . . .
10
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
12
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
17
4.1
String
4.2
Bilangan . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
18
4.2.1
. . . . . . . . . . . . . . . . . . . . .
19
4.2.2
Formatting
. . . . . . . . . . . . . . . . . . . . . . . . . .
19
4.2.3
Kalkulator
. . . . . . . . . . . . . . . . . . . . . . . . . .
20
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
20
4.3
List
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
14
. . . . . . . . . . . . . . . . . . . . . . . . .
17
4.3.1
Pemenggalan
4.3.2
Keberadaan Elemen
. . . . . . . . . . . . . . . . . . . . .
22
21
4.3.3
Mengubah Elemen . . . . . . . . . . . . . . . . . . . . . .
25
4.4
Di tionary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
26
4.5
Waktu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
28
5 Modularitas
31
5.1
Membuat Fungsi
. . . . . . . . . . . . . . . . . . . . . . . . . . .
5.2
Membuat Modul
. . . . . . . . . . . . . . . . . . . . . . . . . . .
33
5.3
Sear h Path . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
35
6 Fungsi
6.1
6.2
Format Uang
7 Database
7.1
Tabel
. . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7.1.1
Sequen e
. . . . . . . . . . . . . . . . . . . . . . . . . . .
7.1.2
Mengubah Struktur
. . . . . . . . . . . . . . . . . . . . .
32
37
37
37
42
44
46
49
DAFTAR ISI
7.2
View . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
51
7.3
. . . . . . . . . . . . . . . . . . . . . . . . .
53
. . . . . . . . . . . . . . . . . . . . . . . . . . .
54
Fungsi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
55
7.4.1
PL/pgSQL
. . . . . . . . . . . . . . . . . . . . . . . . . .
56
7.4.2
PL/Python
. . . . . . . . . . . . . . . . . . . . . . . . . .
61
7.3.1
7.4
En oding
A tive Re ord . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.2
Auto Commit . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.3
Syn hronizer
8.4
63
64
71
. . . . . . . . . . . . . . . . . . . . . . . . . . . . .
73
8.3.1
Aspek Keamanan . . . . . . . . . . . . . . . . . . . . . . .
74
8.3.2
. . . . . . . . . . . . . . . . . . . . .
9 Lintas Sistem
76
78
80
9.1
Command Line . . . . . . . . . . . . . . . . . . . . . . . . . . . .
9.2
File
9.3
Database
9.4
XMLRPC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
84
9.4.1
. . . . . . . . . . . . . . .
87
9.4.2
Drupal . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
88
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10 Pengemasan
80
82
83
90
90
. . . . . . . . . . . . . . . . . . . . . . . . . .
95
96
99
106
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
13 Kerja Sampingan
14 SMS Gateway
112
115
. . . . . . . . . . . . . . . . . . . . . . . . . . 117
. . . . . . . . . . . . . . . . . . . . . . . . . . . 118
. . . . . . . . . . . . . . . . . . . . . 119
. . . . . . . . . . . . . . . . . . . . . . 119
DAFTAR ISI
15 Web
124
16 Hosting
16.1 Virtualmin
125
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
. . . . . . . . . . . . . . . . 130
. . . . . . . . . . . . . . . . . . . . . . . . . . 139
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140
Kata Pengantar
Terimakasih saya u
apkan untuk I Made Wiryana yang telah mengusulkan
Python kepada penulis untuk pertama kali.
Bab 1
Alasan
Mengapa Python merupakan bahasa yang tepat untuk pembuatan berbagai
aplikasi ? Berikut ini alasannya.
Multiplatform
Mudah
Hemat
yang tidak membutuhkan karakter atau kata khusus untuk BEGIN dan
END. Sebagai gantinya sub-blo
k dipisahkan dengan indent (penulisan
menjorok ke kanan).
Multiplatform
Lengkap
Memili-
ki sifat umum traditional database seperti transa
tion, stored pro
edure
(fun
tion), dan trigger. Bahkan fun
tion bisa ditulis dalam berbagai ba-
hasa (tidak hanya SQL), Python, Perl, Shell, dan Java adalah
ontoh bahasa yang didukungnya. Ia juga memiliki modul khusus untuk kebutuhan
GIS (Geographi
Information System).
Bab 2
Pemasangan
Untuk memudahkan penjelasan, kita gunakan distro Linux berbasis Ubuntu.
Pada saat tulisan ini dibuat kami menggunakan Ubuntu 10.04 (Lu
id). Anda
juga bisa menggunakan jenis Ubuntu lainnya seperti Kubuntu (window manager
KDE), atau BlankOn (buatan Indonesia).
Pas
a instalasi Ubuntu Python sudah disertakan. Namun masih ada yang
perlu diunduh (download) lagi. Sebelumnya perbaharui daftar paket yang akan
diunduh, lakukan ini di konsole:
1
sudo
a p t g e t
update
Pasang PostgreSQL:
1
sudo
a p t g e t
install
postgresql
p o s t g r e s q l p l p y t h o n
8.4
sudo
a p t g e t
install
python s q l a l h e m y
python p s y o p g 2
sudo
a p t g e t
install
phppgadmin
sudo
/ e t / i n i t . d/ apa he2
start
Se
ara default Apa
he hidup otomatis saat komputer boot. Lalu buatlah symlink phppgadmin:
1
sudo
ln
/ u s r / s h a r e / phppgadmin
/ v a r /www/
BAB 2.
PEMASANGAN
http://lo
alhost/phppgadmin
Bagi pengguna window manager Gnome Anda bisa gunakan gedit sebagai text
editor. Sedangkan pengguna KDE bisa gunakan kate. Keduanya berbasis GUI.
Jika Anda lebih nyaman dengan konsole bisa gunakan nano, joe, atau vi.
1
sudo
a p t g e t
install
vim
sudo
vi
/ e t / vim / v i m r
later
versions
Un
ommenting
2
"
syntax
line
enables
the
support
syntax
highlighting .
next
syntax
highlighting
by
default .
on
Saat Anda membuka le untuk keduakalinya, maka kursor langsung menuju
ke lokasi sebelumnya.
1
" Un
omment
position
"
if
reopening
the
to
h a v e Vim jump
to
the
last
file
BufReadPost
l i n e (" $ ")
following
when
if
l i n e ( " ' \ " " ) > 0 && l i n e ( " ' \ " " ) <=
exe
" normal
g '\""
endif
endif
Menjorok otomatis (auto indent), dan penekanan tombol TAB diganti dengan SPACE 4 kali:
" Un
omment
rules
"
dete
ted
filetype
"
if
the
following
a ording
to
filetype .
to
h a v e Vim
load
indentation
the
Per
default
D e b i a n Vim
only
load
spe ifi
plugins .
h a s ( " auto
md " )
filetype
set
smartindent
indent
on
set
expandtab
set
t a b s t o p=4
set
s o f t t a b s t o p =4
10
set
s h i f t w i d t h =4
11
endif
Pen
arian mengabaikan huruf besar atau ke
il (in
asesensitive).
set
ignore ase
" Do
ase
insensitive
mat hing
BAB 2.
PEMASANGAN
Bila kata yang di
ari mengandung huruf besar dan huruf ke
il, maka pen
arian memperhatikan huruf besar atau ke
il (
asesensitive).
1
set
smart ase
" Do s m a r t
ase
mat hing
Aktifkan kedua opsi pen arian di atas, maka pen arian di vim ( menggunakan perintah slash / ) semakin mudah.
Bab 3
Hello World!
Anda bisa memulai Python dalam modus interaktif. Nanti kalau sour
e sudah
mulai panjang kita simpan dalam le. Modus interaktif dijalankan di konsole,
lalu ketik:
1
python
maka sambutannya seperti ini:
Python
[GCC 4 . 4 . 3
Type
information .
2.6.5
( r265 : 7 9 0 6 3 ,
on
Apr
16
2010 ,
13:57:41)
linux2
" redits"
or
for
more
>>>
Mulailah dengan yang sederhana, menampilkan sebuah pesan menggunakan
perintah print.
1
2
>>> p r i n t
Hello
' Hello
World ! '
World !
Gunakan tombol panah atas untuk mengulang perintah sebelumnya, lalu kita
oba sedikit salah satu
iri pemgrograman berorientasi objek (obje
t oriented
programming / OOP).
1
>>> p r i n t
HELLO WORLD!
>>> p r i n t
hello
' Hello
' Hello
World ! ' . u p p e r ( )
World ! ' . l o w e r ( )
world !
'Hello World!' adalah sebuah string, yaitu DATA yang boleh berisi alphanumeri
, boleh terdiri dari huruf dan angka atau karakter lainnya. Contoh di atas
menyebutkan bahwa string tidak hanya berisi data, ia juga memuat FUNGSI
yang bernama upper() dan lower().
bukan
sekedar string, tapi disebut OBJEK string. Inilah
iri objek, memuat data dan
fungsi.
BAB 3.
10
HELLO WORLD!
Bingung ?
Untuk keluar
3.1
Selain menggunakan kutip tunggal, string juga dapat dibatasi oleh kutip ganda:
1
2
>>> p r i n t
H a r i Jum ' a t
Bila string lebih dari satu baris Anda bisa gunakan kutip tiga kali:
1
2
3
>>> p r i n t
...
Alamat :
...
Hobi :
Nama :
Alamat :
Hobi :
Bummi Dwi
Putera
Bogor
Bummi Dwi
Putera
Bogor
Menggambar
Perhatikan tiga buah titik di atas yang berarti sebuah perintah belum berakhir.
Selanjutnya marilah membuat s
ript yang akan menanyakan nama, alamat,
dan hobi, lalu menampilkannya kembali di layar. Kali ini kita simpan dalam
sebuah le pegawai.py.
a l a m a t = r a w _ i n p u t ( ' Alamat :
h o b i = r a w _ i n p u t ( ' Hobi :
4
5
6
print
print
print
' Nama :
' ,
' Alamat :
' Hobi :
')
')
')
nama
' ,
' ,
alamat
hobi
python
p e g a w a i . py
Nama :
Alamat :
Bummi Dwi
Hobi :
Putera
Bogor
Menggambar
raw_input() adalah fungsi untuk menerima masukkan dari user. Fungsi ini
menghasilkan string yang berisi masukkan user tersebut, dan dilimpahkan ke
variabel nama, alamat, dan hobi. Anda bisa kembali ke modus interaktif untuk
sekedar mengetahui tipe data dari variabel nama.
BAB 3.
11
HELLO WORLD!
Nama :
>>> p r i n t
<t y p e
')
Bummi
t y p e ( nama )
' s t r '>
Pada s
ript di atas kita mulai mengenal apa yang disebut variabel, yaitu
nama, alamat, dan hobi.
Tipe
data ketiga variabel di atas adalah string. Mari kita
oba tipe data lainnya.
1
>>> a = 3
>>> b = 5
>>> p r i n t
a + b
>>> p r i n t
<t y p e
type ( a )
' i n t '>
>>> = 7 . 2
>>> p r i n t
<t y p e
type ( )
' f l o a t '>
Ya, pemisah bilangan bulat dengan pe
ahannya adalah dengan titik. Oh ya,
Python tergolong ketat dalam hal pengoperasian antar tipe data. Kita tidak
diperkenankan menambahkan string dengan integer.
1
>>> nama =
>>> umur = 2 4
>>> p r i n t
Tra eba k
5
6
File
nama +
( most
'
"< s t d i n >" ,
TypeError :
usia
re
ent
line
annot
' + umur +
all
1,
'
tahun '
last ) :
i n <module>
on atenate
and
obje ts
>>> p r i n t
Bummi
usia
nama +
24
'
usia
' + s t r ( umur ) +
'
tahun '
tahun
>>> p r i n t
Bummi
usia
'% s
24
u s i a %s
umur )
tahun
Meski string tidak bisa ditambah dengan integer, namun string bisa dikalikan
dengan integer:
1
2
>>> p r i n t
' ab '
10
a b a b a b a b a b a b ab ab ab ab
Kembali ke le pegawai.py, tidak diperkenankan menulis tidak rapi. Cobalah membuat kesalahan di baris terakhir pada le pegawai.py, yaitu dengan
menambahkan dua spasi sebelum print:
BAB 3.
12
HELLO WORLD!
a l a m a t = r a w _ i n p u t ( ' Alamat :
h o b i = r a w _ i n p u t ( ' Hobi :
' Nama :
' Alamat :
',
' Hobi :
')
')
')
nama
',
alamat
',
hobi
Kemudian jalankan:
1
python
p e g a w a i . py
hasilnya Python protes karena ada indent (menjorok masuk) yang tidak
diperkenankan:
1
python
File
4
5
p e g a w a i . py
" p e g a w a i . py " ,
' Hobi :
',
line
hobi
^
IndentationError :
unexpe ted
indent
Seperti kita lihat, s
ript Python tanpa diawali suatu BEGIN .. END atau
{ .. } atau berbagai penanda lainnya sebagai bentuk awal dan akhir program.
Baris-baris utama selalu tanpa indent alias rapat kiri.
indent berarti dianggap bagian dari sub-blok seperti dalam looping (for) atau
kondisi (if ).
1
a l a m a t = r a w _ i n p u t ( ' Alamat :
h o b i = r a w _ i n p u t ( ' Hobi :
' Nama :
' Alamat :
if
',
')
')
')
nama
',
alamat
',
hobi
hobi :
print
' Hobi :
3.2
Kondisi
Python punya sema
am pedoman dalam hal kondisi (if ), dimana jika suatu
variabel ada isinya maka True, jika kosong maka False.
1
if
hobi :
print
' Hobi :
',
hobi
if
hobi
print
!=
' ':
' Hobi :
',
hobi
Se
ara tipe data hobi tentulah sebuah string, tapi bagaimana dengan hobi
!= ? Mari kita uji di modus interaktif dimana variabel hobi ada isinya.
BAB 3.
13
HELLO WORLD!
Tipe
False
True (Contoh)
String
'ab '
Integer
Float
1.2
List
[10,20,30
Di tionary
{}
Objek
None
True
>>> h o b i =
>>> h o b i
3
4
5
!=
''
>>> h o b i ==
''
True
False
Lalu
obalah variabel hobi kosong.
>>> h o b i =
>>> h o b i
3
4
5
''
!=
''
>>> h o b i ==
''
False
True
Pahami baik-baik perbedaan keduanya. Perhatikan juga penggunaan karakter samadengan dua kali ( == ) yang berarti operasi logika (boolean operation).
>>> k o s o n g = h o b i ==
>>> p r i n t
''
kosong
True
Kembali ke pegawai.py dimana bila hobi tidak diisi maka program akan
memberikan saran. Salinlah menjadi pegawai1.py seperti berikut ini.
Listing 3.2: pegawai1.py
a l a m a t = r a w _ i n p u t ( ' Alamat :
h o b i = r a w _ i n p u t ( ' Hobi :
4
5
6
7
8
9
print
print
if
print
else
print
' Nama :
' ,
' Alamat :
')
')
')
nama
' ,
alamat
' ,
hobi
hobi :
' Hobi :
' Sebaiknya
hobi
diisi . '
BAB 3.
14
HELLO WORLD!
a l a m a t = r a w _ i n p u t ( ' Alamat :
h o b i = r a w _ i n p u t ( ' Hobi :
4
5
6
7
8
9
10
11
print
print
if
print
elif
print
else
print
' Nama :
' ,
' Alamat :
')
')
')
nama
' ,
alamat
h o b i . u p p e r ( ) ==
' Datanglah
'MENGGAMBAR' :
di
pelatihan
gambar
setiap
Sabtu . '
hobi :
' Hobi :
' ,
hobi
' Sebaiknya
hobi
diisi . '
Perhatikan juga penggunaan titik dua ( : ) pada if dan else. Ini
iri lain
untuk menandai awal suatu sub-blok.
3.3
Perulangan
Mari kita buat input pegawai jadi lebih mudah, dimana program akan menanyakan
data terus-menerus dan baru berhenti bila nama tidak diisi.
1
2
3
4
5
6
7
8
9
10
11
12
while
if not
break
True :
')
nama :
a l a m a t = r a w _ i n p u t ( ' Alamat :
h o b i = r a w _ i n p u t ( ' Hobi :
print
print
if
print
else
print
' Nama :
' ,
' Alamat :
')
')
nama
' ,
alamat
' ,
hobi
hobi :
' Hobi :
' Sebaiknya
hobi
diisi . '
Perhatikan baris pertama yang berarti perulangan tanpa henti. Yang menghentikannya adalah baris ke empat. break adalah kata khusus untuk menghentikan
perulangan dimana alur keluar menuju blok bawah di luar perulangan tersebut.
Kebetulan dalam
ontoh ini tidak ada blok lain di luar perulangan.
Selanjutnya kita buat aturan baru untuk pengisian data ini, dimana:
1. Nama dan alamat harus diisi.
2. Bila selesai satu data pegawai maka program akan menanyakan apakah
akan memasukkan data berikutnya.
BAB 3.
15
HELLO WORLD!
lanjut =
'Y '
while
if not
print
ontinue
if not
print
ontinue
print
print
if
print
else
print
lanjut
!=
'S ' :
')
nama :
' Nama h a r u s
diisi . '
a l a m a t = r a w _ i n p u t ( ' Alamat :
')
alamat :
' Alamat
harus
h o b i = r a w _ i n p u t ( ' Hobi :
' Nama :
' ,
' Alamat :
diisi . '
')
nama
' ,
alamat
' ,
hobi
hobi :
' Hobi :
' Sebaiknya
lanjut
hobi
diisi . '
= r a w _ i n p u t ( ' Tekan
"S"
jika
selesai :
' ) . upper ( )
for
in
[1 ,2 ,3 ,4 ,5:
Hasilnya:
1
2
3
4
5
Perhatikan [1,2,3,4,5 yang merupakan data bertipe list atau sering juga disebut
sebagai array. Kita bisa persingkat penulisannya dengan fungsi range().
1
2
for
in
range ( 5 ) :
i
Hasilnya
BAB 3.
HELLO WORLD!
16
0
1
2
3
4
Meski tidak dimulai dari 1 tapi jumlah barisnya tetap 5. Jika tetap ingin dimulai
dari 1 gunakan range(1,6).
1
2
for
in
range ( 1 , 6 ) :
i
Bab 4
Tipe Data
Memperhatikan tipe data salah satu pokok pada Python dan ini juga menjadi
salah satu kun
i agar mudah dalam pen
arian kesalahan (debugging).
4.1
String
>>> nama =
>>> t y p e ( nama )
<t y p e
' s t r '>
Data bertipe string bisa berisi karakter apa saja seperti huruf, angka, tanda
ba
a, atau gabungannya.
Menggabungkan dua buah variabel string bisa menggunakan tanda plus ( +
).
1
>>> p r i n t
Agus
lahir
nama +
hari
'
lahir
hari
' + hari
Jum ' a t
Namun
ara ini tidak disarankan karena membuat program menjadi sulit
diba
a. Kalau program sulit diba
a menyulitkan penelusuran bila ada kesalahan
(debugging). Jadi sebaiknya gunakan formatting.
1
>>> p r i n t
Agus
lahir
'% s
lahir
hari
h a r i %s ' % ( nama ,
Jum ' a t
17
hari )
BAB 4.
18
TIPE DATA
Lalu bagaimana menampilkan % itu sendiri di dalam formatting ? Sebutkanlah dua kali.
1
2
>>> p r i n t
' Keuntungan
Keuntungan
4.2
bulan
ini
bulan
ini
meningkat
m e n i n g k a t %d %%' % ( 1 0 )
10 %
Bilangan
Bilangan bulat atau integer atau disingkat int dinyatakan tanpa titik.
1
>>> a = 1 0
a ditambah 2
>>> a + 2
12
1
2
a dikurang 4
1
2
>>> a
6
a dikali 5
1
2
>>> a
50
a dibagi dengan 3
1
2
>>> a
3
Mengapa bukan 3.3333 ?
Pembagian bilangan bulat dengan bilangan bulat menghasilkan bilangan bulat juga. Jika Anda mengharapkan hasil yang lebih rin
i maka salah satunya
harus bilangan pe
ahan (oat).
1
2
>>> a
3.0
3.3333333333333335
Untuk mendapatkan sisa pembagian (modulus) gunakan tanda persen ( %
).
1
2
>>> a % 3
1
a pangkat 2
1
2
>>> a
100
**
BAB 4.
19
TIPE DATA
1
2
>>> i n t ( 1 0 . 2 )
10
Untuk pembulatan yang mendekati gunakan round().
1
2
3
4
>>> r o u n d ( 1 0 . 4 )
10
>>> r o u n d ( 1 0 . 5 )
11
round() akan membulatkan ke bawah bila pe
ahan suatu bilangan lebih ke
il
dari 0,5. Sebaliknya ia akan membulatkan ke atas.
Untuk konversi dari string menjadi bilangan pe
ahan menggunakan fungsi
oat().
1
2
>>>
10.5
4.2.2 Formatting
Menuliskan bilangan ke dalam string bisa menggunakan formatting.
1
>>> a = 3
>>> b = 2
>>> p r i n t
3 + 2 = 5
'% s + %s = %s ' % ( a ,
b,
a+b )
Meski formatting %s bisa digunakan untuk tipe data apa saja, sebaiknya Anda menggunakan formatting yang lebih spesik sesuai tipe datanya. Katakanlah
Anda menetapkan bahwa variabel a itu harus bertipe bilangan bulat (integer),
begitu pula dengan variabel b, maka gunakanlah %d.
1
>>> p r i n t
3 + 2 = 5
'%d + %d = %d ' % ( a ,
b,
a+b )
>>> a = 3 . 5
>>> p r i n t
'% f + %f = %f ' % ( a ,
b,
a+b )
BAB 4.
20
TIPE DATA
4.2.3 Kalkulator
Membuat kalkulator tidaklah sulit, Anda
ukup gunakan eval().
Buatlah le
1
2
3
4
5
while
if not
break
print
True :
')
hitung :
eval ( hitung )
Jalankan.
1
Hitung
python
Hitung
49
Hitung
13
Hitung
a l . py
2+3
7 ** 2
7 + 2
4.3
List
Tipe data list kerap digunakan. Kita lihat pada
ontoh sebelumnya bagaimana
list menjadi wajib pada perulangan for. Bahkan string sebenarnya bisa dianggap
sebagai list.
1
2
for
in
h ,
hasilnya:
1
Bummi
Perhatikan penggunaan koma pada print yang berarti jangan ganti baris.
Mari kembali ke modus interaktif untuk men
oba list.
BAB 4.
21
TIPE DATA
>>> p r i n t
3
4
5
data [ 0
Putera '
data [ 1
1
2
>>> p r i n t
data [ 1
24
Elemen kedua dari terakhir:
1
2
>>> p r i n t
data [ 2
4.3.1 Pemenggalan
Selain dapat diambil per elemen, juga dapat diambil beberapa elemen sekaligus, ini disebut sebagai pemenggalan (sli
ing). Tampilkan elemen pertama dan
kedua:
1
2
>>> p r i n t
data [ 0 : 2
Putera ' ,
>>> p r i n t
data [ : 2
Putera ' ,
>>> p r i n t
data [
3:
24
Ada baiknya kita pahami
ara kerjanya. Pemenggalan list bekerja dengan
batas elemen.
sebagai list.
BAB 4.
22
TIPE DATA
Setelah user
memasukkan nama buah program akan men
arinya dalam list dan memberitahukan hasilnya. Setelah itu program akan kembali menanyakan nama buah
berikutnya. Program berakhir jika user hanya menekan Enter saja, alias tidak
memasukkan apapun. Sekarang buatlah produk.py berikut ini.
Listing 4.2: produk.py
1
d a f t a r = [ ' j e r u k ' , ' mangga ' , ' a p e l ' , ' p i s a n g ' , ' jambu '
while
if not
print
break
if
in
print
else
print
3
4
5
6
7
8
9
10
11
True :
a r i = raw_input ( ' C a r i
buah :
')
ari :
ari
( ' Tidak
ditemukan ' )
Jalankanlah.
1
Cari
python
Ditemukan
p r o d u k . py
buah :
Cari
Tidak
buah :
Cari
Selesai
mangga
duku
ditemukan
buah :
1
2
import
print
Jalankanlah.
1
[ ' a t . py '
python
a t . py
[ ' a t . py ' ,
python
a t . py
/et /hosts
Perhatikan elemen pertama adalah le
at.py itu sendiri, dan elemen kedua
adalah nama le yang akan ditampilkan.
BAB 4.
1
2
23
TIPE DATA
import
sys
f i l e n a m e = sys . argv [ 1
5
6
f = open ( f i l e n a m e )
f . read ( )
f .
lose ()
Jalankan.
127.0.0.1
python
a t 1 . py
lo alhost
/et /hosts
127.0.1.1
ompaq
ompaq
4
5
# The
following
lines
are
desirable
for
IPv6
apable
hosts
6
::1
lo alhost
fe00 : : 0
i p 6l o a l n e t
i p 6l o a l h o s t
ff00 ::0
i p 6 m a s t p r e f i x
ff02 ::1
i p 6 a l l n o d e s
10
ff02 ::2
ip6a l l r o u t e r s
11
ff02 ::3
ip6a l l h o s t s
i p 6 l o o p b a k
Kita perlu mengantisipasi kesalahan yang dilakukan user, dimana bisa saja
ia tidak tahu
ara menggunakan
at1.py, yaitu langsung menjalankan tanpa
menyertakan nama le.
1
Tra eba k
3
4
5
python
File
a t 1 . py
( most
" a t . py " ,
re
ent
line
all
3,
last ) :
i n <module>
f i l e n a m e = sys . argv [ 1
IndexError :
list
index
out
of
range
Tampilan kesalahan ini jelas kurang informatif dan bisa jadi user tidak tahu
apa yang harus dilakukan. Saatnya menggunakan deteksi keberadaan elemen.
1
2
3
4
import
if not
print
sys
sys . argv [ 1 : :
( ' Cara
menggunakannya :
sys . argv [ 0 )
sys . exit ()
6
7
f i l e n a m e = sys . argv [ 1
9
10
f = open ( f i l e n a m e )
f . read ( )
f . lose ()
BAB 4.
24
TIPE DATA
Cara
python
a t 2 . py
menggunakannya :
python
a t . py <nama f i l e >
if not sys.argv[1::
Kalau kita perhatikan lagi isi dari sys.argv pada saat tidak diberikan input
parameter adalah:
['
at.py'
Dengan begitu sys.argv[1: akan bernilai list hampa:
[
Ingatlah mengenai pemenggalan list pada pembahasan sebelumnya. Bila suatu
variabel hampa maka ia bisa dianggap sebagai boolean False, sehingga
if not sys.argv[1::
bisa berarti
if not [:
yang berarti
if not False:
dan ini bisa diartikan menjadi:
if True:
True berarti kondisi terpenuhi dan blok di dalam if dijalankan, dan akhirnya
tampillah pesan
ara penggunaan
at2.py tadi.
Lalu apa yang terjadi jika program mendapat input parameter ?
sys.argv menjadi
if not sys.argv[1::
bisa berarti
Nilai
BAB 4.
25
TIPE DATA
Karena ['/et
/hosts' adalah list yang berisi (tidak hampa) maka bisa dianggap
sebagai boolean True
if not True:
dan ini berarti juga
if False:
False berarti kondisi tidak terpenuhi sehingga blok di dalam if tidak dijalankan.
Pahamilah baik-baik penjelasan ini, Anda akan banyak menemuinya nanti.
Inilah salah satu mengapa program yang dibuat dengan Python begitu ringkas
namun tetap mudah diba
a.
>>> d a f t a r =
>>> d a f t a r
[
Tambahkan mangga.
>>> d a f t a r
>>> d a f t a r
Kita akan ubah elemen kedua (index ke 1) dari pisang menjadi jeruk.
1
>>> d a f t a r [ 1
>>> d a f t a r
>>> d e l
>>> d a f t a r
daftar [ 0
BAB 4.
4.4
26
TIPE DATA
Di tionary
List adalah serangkaian elemen yang alamatnya adalah nomor urut, sering
disebut sebagai index. Di
tionary juga mirip, hanya saja alamatnya tidak harus
berupa angka yang berurutan. Bahkan bisa bertipe string atau tipe data lainnya. Sekarang buatlah s
ript berikut ini.
Listing 4.6: produk1.py
1
daftar = {
2:
7:
4:
3:
9:
daftar
Jalankan.
1
{9:
python
p r o d u k 1 . py
2:
3:
4:
7:
'
mangga ' }
Perhatikan urutan pada sour
e, dan bandingkan urutan buah saat ditampilkan. Begitulah di
tionary, dia memang tidak memperhatikan urutan. Inilah salah satu yang membedakannya dengan list. Di
tionary
o
ok untuk pen
arian.
bagi variabel daftar. Key ini bisa saja dianggap sebagai kode barang atau kode
buah. Sedangkan apel, jeruk, jambu, pisang, dan mangga merupakan nilai (value). Karena itu di
tionary sering disebut sebagai tipe data dengan formasi key
value.
Sekarang kita buat pen
arian berdasarkan kode barang.
Listing 4.7: produk2.py
1
daftar = {
2:
7:
4:
3:
9:
8
9
10
11
12
13
while
if not
print
break
True :
k e y = r a w _ i n p u t ( ' Kode
key :
' Selesai '
barang :
')
BAB 4.
if
in
print
else
print
14
key
15
16
27
TIPE DATA
daftar :
d a f t a r [ key
17
' Kode
barang ' ,
key ,
' tidak
ditemukan '
Cobalah.
1
Kode
python
barang :
p r o d u k 2 . py
Kode
barang
Kode
barang :
Kode
barang
Kode
barang :
Selesai
5
5
tidak
ditemukan
tidak
ditemukan
9
9
Kode barang 5 boleh jadi tidak ditemukan, karena memang tidak ada 5
dalam variabel daftar.
Seharusnya
if key in daftar:
berarti men
ari 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
Kode
python
barang :
Kode
barang
tidak
Kode
Selesai
p r o d u k 2 . py
9
[ '9 '
ditemukan
barang :
Dengan memberikan kurung siku pada variabel maka akan tampak bahwa
key adalah string.
Lalu bagaimana
BAB 4.
28
TIPE DATA
daftar = {
2:
7:
4:
3:
9:
8
9
10
11
12
13
14
15
16
17
18
while
if not
print
break
if
in
print
else
print
True :
k e y = r a w _ i n p u t ( ' Kode
barang :
')
key :
' Selesai '
key = i n t ( key )
key
daftar :
d a f t a r [ key
' Kode
barang ' ,
key ,
' tidak
ditemukan '
Jalankan lagi.
1
Kode
python
barang :
Kode
barang
Kode
barang :
apel
Kode
Selesai
p r o d u k 3 . py
5
[5
tidak
ditemukan
barang :
Resapi kembali mengenai tipe data ini karena akan sering dijumpai nanti.
4.5
Waktu
Modul time digunakan untuk penanganan waktu. Kita kembali ke modus interaktif dulu untuk memudahkan latihan.
1
>>> i m p o r t
>>> t = t i m e . l o a l t i m e ( )
>>> t
time
t m _ i s d s t =0)
Fungsi time.lo
altime() digunakan untuk mendapatkan waktu saat ini. Perhatikan variabel t di atas. Jika Anda ingin mengambil tahunnya:
1
2
>>> t . tm_year
2010
BAB 4.
29
TIPE DATA
atau bulannya
1
2
>>> t . tm_mon
8
atau harinya
1
2
>>> t . tm_mday
20
dan seterusnya hingga jam, menit, dan detiknya, ada di sana.
Waktu juga bisa diwujudkan dalam bilangan pe
ahan (oat), sering disebut
sebagai epo
h atau Unix time.
1
2
>>> t i m e . t i m e ( )
1282280699.2280381
Epo
h ini adalah jumlah detik sejak 1 Januari 1970 jam 00:00:00 (GMT)
hingga saat ini.
Fungsi time.lo
altime() sebenarnya bisa diberikan masukan berupa epo
h
ini. Kita bisa mulai dengan angka 0.
1
2
>>> t i m e . l o
a l t i m e ( 0 )
t i m e . s t r u
t _ t i m e ( tm_year = 1 9 7 0 , tm_mon=1 , tm_mday=1 ,
tm_hour=7 , tm_min=0 ,
t m _ i s d s t =0)
Epo
h 0 berarti 1 Januari 1970. Lalu mengapa tm_hour menunjukkan angka
7 ?
Ini terkait dengan zona waktu (timezone) pada komputer yang berarti
wilayah Jakarta (+7). Jika komputer Anda diset pada zona waktu Bali maka
nilai tm_hour menjadi 8.
Untuk mendapatkan epo
h pada tanggal 17 Agustus 2010 maka bisa gunakan
time.mktime():
1
2
>>> t i m e . mktime ( ( 2 0 1 0 , 8 , 1 7 , 0 , 0 , 0 , 0 , 0 , 0 ) )
1281978000.0
Dengan epo
h kita bisa mendapatkan jumlah hari sejak 1 Agustus 2010
hingga 17 Agustus 2010.
>>> a w a l = t i m e . mktime ( ( 2 0 1 0 , 8 , 1 , 0 , 0 , 0 , 0 , 0 , 0 ) )
>>> a k h i r = t i m e . mktime ( ( 2 0 1 0 , 8 , 1 7 , 0 , 0 , 0 , 0 , 0 , 0 ) )
>>> a k h i r
1382400.0
awal
Itu adalah jumlah detiknya. Untuk mendapatkan hari kita perlu mengolahnya kembali.
1
2
>>> ( a k h i r
awal )
24
16.0
Sehingga diperoleh 16 hari.
60
60
BAB 4.
30
TIPE DATA
Modul datetime
Menghitung hari lebih mudah menggunakan modul datetime.
1
>>> f r o m
>>> a w a l = d a t e ( 2 0 1 0 , 8 , 1 )
>>> a k h i r = d a t e ( 2 0 1 0 , 8 , 1 7 )
>>> d = a k h i r
>>> d . d a y s
datetime
import
date
awal
16
Dengan modul ini kita juga dapat menghitung jumlah detik sejak 16 Agustus
2010 jam 22:00 hingga 17 Agustus 2010 jam 10:00.
>>> f r o m
>>> a w a l = d a t e t i m e ( 2 0 1 0 , 8 , 1 6 , 2 2 , 0 , 0 )
>>> a k h i r = d a t e t i m e ( 2 0 1 0 , 8 , 1 7 , 1 0 , 0 , 0 )
>>> d = a k h i r
>>> d . s e o n d s
datetime
import
datetime
awal
43200
Untuk mendapatkan jumlah jamnya:
1
2
>>> d . s e
o n d s
12
60
60
Bab 5
Modularitas
Mari kita buat program yang menghitung nilai faktorial.
5!
4!
3!
2!
1!
0!
-1!
=
=
=
=
=
=
=
5
4
3
2
1
1
1
*
*
*
*
4
3
2
1
*
*
*
=
3 * 2 * 1 = 120
2 * 1 = 24
1 = 6
2
1
2
3
4
5
6
7
8
9
10
11
12
13
print
while
if not
break
if
else
for in
*
print
' Menghitung
nilai
faktorial '
True :
n = raw_input ( ' n =
')
n:
n = int (n)
n < 2:
f = 1
:
f = 1
i
f = f
'%d !
r a n g e ( 1 , n+1) :
i
= %d ' % ( n ,
f)
31
BAB 5.
32
MODULARITAS
Jalankan.
1
Menghitung
python
n = 2
2! = 2
n = 3
3! = 6
n = 4
4 ! = 24
n =
10
f a k t o r i a l 1 . py
nilai
faktorial
$
Selesai sudah.
gras (graphi
al user interfa
e / GUI). Tentu saja 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 perulangannya.
Lalu apa yang diambil untuk mengambil sour
e faktorial ?
saja yang perlu di-
opy-paste di sour
e GUI nanti.
Baris 6 - 12
suaikan variabel n yang menjadi masukannya, karena n tidak lagi berasal dari
raw_input() melainkan dari komponen GUI.
Di sini mulai terasa sour
e faktorial di atas tidak modular karena menyulitkan
opy-paste. Kesulitan yang dimaksud adalah sour
e faktorial menyatu dengan
sour
e yang mengurus tampilan. Faktorial adalah
ontoh sederhana, bagaimana
kalau nanti Anda diminta membuat rumus lainnya yang jauh lebih rumit ?
5.1
Membuat Fungsi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
def
if
return
for in
*
return
f = 1
i
f = f
r a n g e ( 1 , n+1) :
i
print
while
if not
break
' Menghitung
nilai
True :
n = raw_input ( ' n =
n:
')
faktorial '
BAB 5.
33
MODULARITAS
15
n = int (n)
16
h a s i l = f a k t o r i a l (n)
17
'%d !
= %d ' % ( n ,
hasil )
Jalankan.
1
Menghitung
python
n = 5
5 ! = 120
n = 2
2! = 2
n = 1
1! = 1
n =
10
1!
= 1
11
n =
f a k t o r i a l 2 . py
nilai
faktorial
Hasilnya memang sama saja, namun kini sour
e faktorial lebih mudah diba
a
dan di-
opy-paste.
5.2
Membuat Modul
Copy-paste sour
e seperti itu tentu saja lebih sulit ketimbang
opy-paste lenya. Oleh karena itu Anda perlu membuat sour
e itu menjadi modul faktorial
yang berarti namanya menjadi faktorial.py sehingga program lain yang membutuhkannya
ukup menggunakannya seperti ini (
ontoh):
1
from
n = 5
faktorial
import
faktorial
f a k t o r i a l (n)
1
2
3
4
5
6
def
if
return
for in
*
return
faktorial (a) :
a < 2:
i
a = a
1
range ( 1 , a ) :
i
from
faktorial
import
faktorial
BAB 5.
2
3
4
5
6
7
8
34
MODULARITAS
print
while
if not
break
' Menghitung
nilai
faktorial '
True :
n = raw_input ( ' n =
')
n:
n = int (n)
h a s i l = f a k t o r i a l (n)
10
'%d !
= %d ' % ( n ,
hasil )
Jalankan.
1
Menghitung
python
n = 5
5 ! = 120
n = 2
2! = 2
n =
o b a f a k t o r i a l . py
Nilai
Faktorial
Hasilnya tetap sama, namun kini Anda lebih mudah
opy-paste sour
e fungsi
faktorial() karena
ukup faktorial.py yang di-
opy ke direktori program lainnya.
Untuk men
oba modul faktorial Anda perlu membuat le lainnya yaitu
obafaktorial.py. Agar lebih praktis, mengapa tidak disatukan saja ?
Benar, alangkah praktisnya jika sour
e untuk menguji fungsi faktorial() juga
berada di le yang sama.
Namun Anda perlu membuat sedikit perubahan agar saat
1
2
3
4
5
6
7
8
9
10
11
12
13
14
def
if
return
for in
*
return
if
print
while
if not
break
faktorial (a) :
a < 2:
i
a = a
1
range ( 1 , a ) :
i
__name__ ==
'__main__ ' :
' Menghitung
nilai
True :
n = raw_input ( ' n =
n:
n = int (n)
')
faktorial '
BAB 5.
15
hasil =
16
35
MODULARITAS
'%d ! = %d ' % ( n ,
hasil )
Perhatikan bahwa __name__ adalah name yang diawali dan diakhiri oleh
dua unders
ore. Begitu juga dengan __main__. Kemudian jalankan.
1
Menghitung
python
n = 3
3! = 6
n = 4
4 ! = 24
n =
f a k t o r i a l . py
nilai
faktorial
if __name__ == '__main__':
Dengan baris ini Python diberitahu bahwa sour
e dibawahnya hanya dijalankan
jika faktorial.py merupakan program utama. Kalau faktorial.py sebagai modul
maka ia tidak dijalankan.
Anda juga masih bisa menggunakan
obafaktorial.py seperti biasa.
1
python
5.3
o b a f a k t o r i a l . py
Sear h Path
>>> i m p o r t
>>> s y s . p a t h
sys
[ ' ' ,
' / u s r / l i b / p y t h o n 2 . 6 / p l a t l i n u x 2 ' ,
' / u s r / l i b / python2 . 6 / l i b
11
t k ' ,
o l d ' ,
' / u s r / l i b / p y t h o n 2 . 6 / l i b d y n l o a d ' ,
' / 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 ' ,
' / 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 / PIL ' ,
' / 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
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
14
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 '
7
8
9
10
' / u s r / l i b / python2 . 6 / l i b
2.0 ' ,
2.0 ' ,
BAB 5.
36
MODULARITAS
Pertama kali Python akan men
ari di direktori dimana program utama berada. Selanjutnya ia akan men
ari di direktori lainnya seperti yang Anda lihat
di atas.
Lalu dimana sebaiknya faktorial.py diletakkan ?
Karena meletakkannya
tidak melalui instalasi paket Debian, maka saya sarankan diletakkan di direktori
sudo
f a k t o r i a l . py
/ u s r / l o a l / l i b / python2 . 6 / d i s t
pa
kages
Supaya lebih yakin pindahkan sekalian.
1
s u d o mv
f a k t o r i a l . py
/ u s r / l o a l / l i b / python2 . 6 / d i s t
pa
kages
Jika Anda punya direktori lain, Anda bisa tambahkan pada sys.path terlebih
dahulu sebelum import.
1
>>> i m p o r t
sys
>>> f r o m
faktorial
import
faktorial
Bab 6
Fungsi
6.1
Fungsi faktorial() sudah bekerja dengan baik. Tapi mungkin sour
e-nya terlalu
panjang. Cobalah ubah menjadi seperti di bawah ini pada faktorial.py.
1
2
def
if
3
4
faktorial (a) :
a < 2:
return
return
f a k t o r i a l ( a 1)
Jauh lebih esien bukan? Teknik seperti ini disebut juga sebagai rekursif.
Pertama kali yang harus diperhatikan dalam pembuatan fungsi rekursif adalah
batas kedalaman. Batas ini ditunjukkan pada baris 2-3. Rekursif yang tidak
memiliki batas kedalaman akan menampilkan pesan kesalahan.
6.2
Format Uang
>>> i m p o r t
>>>
3
4
5
lo ale
10000 ,
True )
1
2
>>>
10000 ,
True )
'10.000 '
Namun jika saat setlo
ale Anda menjumpai pesan kesalahan seperti ini:
37
BAB 6.
38
FUNGSI
Tra eba k
( most
re
ent
line
all
1,
last ) :
File
"< s t d i n >" ,
i n <module>
File
" / u s r / l i b / p y t h o n 2 . 6 / l o a l e . py " ,
line
513 ,
in
setlo
ale
4
5
return
_ s e t l o a l e ( ategory ,
l o a l e . Error :
unsupported
lo ale
lo
ale )
setting
Generating
3
4
sudo
l o a l e g e n
id_ID . UTF 8 . . .
Generation
id_ID . UTF8
lo
ales . . .
upt o d a t e
omplete .
1
2
import
3
4
5
6
7
8
9
10
def
return
uang ( n i l a i ,
if
11
12
__name__ ==
print
print
print
p e a h a n =2) :
l o a l e . f o r m a t ( '%%.%d f ' % p e a h a n ,
'__main__ ' :
uang ( 1 0 0 0 0 )
uang ( 1 0 0 0 0 . 3 )
uang ( 1 0 0 0 0 . 5 , 0 )
Cobalah.
1
10.000 ,00
python
10.000 ,30
10.000
uang . py
Perhatikan bagian
'%%.%df' % pe ahan
nilai ,
True )
BAB 6.
39
FUNGSI
1
2
import
lo ale
3
4
5
6
7
def
if
12
16
17
p e
a h a n=None ) :
None :
t y p e ( n i l a i ) == t y p e ( 0 ) :
:
pe ahan = 2
11
15
is
pe ahan = 0
10
14
pe ahan
if
else
return
13
uang ( n i l a i ,
if
l o a l e . f o r m a t ( '%%.%d f ' % p e a h a n ,
__name__ ==
print
print
print
nilai ,
True )
'__main__ ' :
uang ( 1 0 0 0 0 )
uang ( 1 0 0 0 0 . 3 )
uang ( 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 objek hampa bawaan Python bernama None.
Rasanya fungsi uang kurang lengkap bila tidak disertai dengan mata uangnya.
Kita akan jalankan skenario berikut ini:
1. Fungsi uang diberi satu masukan baru yaitu variabel tanda untuk memberi
kesempatan programmer memasukkan mata uang seperti Rp, $, dst.
BAB 6.
40
FUNGSI
2. Bila variabel tanda tidak diisi maka mata uang diambil dari sistem, menggunakan module lo ale.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import
from
lo ale
def
if
import
ribu ( n i l a i ,
is
pe ahan
if
else
return
def
if
return
IntType
p e
a h a n=None ) :
None :
t y p e ( n i l a i ) == I n t T y p e :
pe
ahan = 0
:
pe
ahan = 2
l o
a l e . f o r m a t ( '%%.%d f ' % p e
a h a n ,
uang ( n i l a i ,
tanda
is
p e a h a n=None ,
nilai ,
True )
t a n d a=None ) :
None :
if
'%s%s ' % ( t a n d a ,
__name__ ==
print
print
print
print
print
print
ribu ( n i l a i ,
pe ahan ) )
'__main__ ' :
ribu (10000)
ribu (10000.3)
ribu (10000.5 ,
4)
uang ( 1 0 0 0 0 . 7 )
uang ( 1 0 0 0 0 . 7 ,
2,
uang ( 1 0 0 0 0 . 7 ,
t a n d a= ' $ ' )
'$ ' )
Perhatikan fungsi tambahan ribu(). Fungsi ini sebenarnya salinan dari fungsi
uang() sebelumnya. Mengapa tidak langsung mengubah fungsi uang() seperti
biasanya ?
Tujuannya adalah kita tidak ingin mengganggu algoritma yang sudah berjalan baik itu.
BAB 6.
41
FUNGSI
Karena modul uang ini merupakan modul umum yang bisa digunakan oleh
banyak aplikasi, maka letakkanlah uang.py di /usr/lo
al/lib/python2.6/distpa
kages agar bisa digunakan oleh program lainnya. Lalu uji keberadaannya di
modus interaktif.
1
>>> f r o m
>>> uang ( 1 0 0 0 0 )
'10.000 '
uang
import
uang
Bab 7
Database
Database atau penyimpan data biasa digunakan untuk aplikasi bisnis seperti
kasir (point of sales), a
ounting, payroll, dsb.
Pasanglah
1
sudo
a p t g e t
install
postgresql
Linux maupun di sistem PostgreSQL itu sendiri. Pas
a pemasangan user postgres tidak memiliki password. Jadi gunakanlah sudo:
1
sudo
su
Masukkan password user yang Anda gunakan ketika login pertama kali. Kini
Anda telah menjadi root, dan mulailah sebagai user postgres:
1
# su
postgres
user Linux dan user PostgreSQL sama maka tidak perlu password untuk login
ke PostgreSQL server. Sekarang mulailah membuat user database:
1
Enter
reateuser
password
ilham
Enter
it
Shall
the
new
role
be
Shall
the
new
role
be
allowed
to
reate
databases?
the
new
role
be
allowed
to
reate
more new
for
new
role :
again :
superuser?
( y /n )
n
( y/n )
n
6
Shall
y /n )
roles?
Isilah password dengan 1234. Saat diketik password tidak akan ditampilkan.
Selebihnya user ilham ini tidak dizinkan sebagai superuser, tidak diizinkan membuat database, dan tidak diizinkan membuat user.
Untuk menghapusnya:
1
dropuser
ilham
42
BAB 7.
43
DATABASE
reatedb
ilham
totalindo
Ini artinya kita membuat database bernama totalindo yang dimiliki oleh user
ilham. Untuk menghapusnya:
1
dropdb
totalindo
psql
psql
(8.4.4)
Type
for
help .
4
5
p o s t g r e s=# \ l
List
7
8
9
10
11
12
13
of
databases
Name
Owner
En oding
Collation
++++
postgres
| p o s t g r e s | UTF8
| id_ID . UTF8 |
t e m p l a t e 0 | p o s t g r e s | UTF8
| id_ID . UTF8 |
t e m p l a t e 1 | p o s t g r e s | UTF8
| id_ID . UTF8 |
t o t a l i n d o | ilham
| UTF8
| id_ID . UTF8 |
(4
rows )
14
15
p o s t g r e s=#
Untuk keluar gunakan \q atau tekan Ctrl-D:
p o s t g r e s=# \ q
postgres
whoami
Anda masih sebagai user postgres, keluarlah dengan perintah logout atau
tekan Ctrl-D:
1
# whoami
logout
root
Kini Anda sebagai root, keluarlah lagi dengan perintah logout agar kembali
sebagai user biasa:
# logout
sugiana
whoami
Password
psql
psql
SSL
ilham
for
totalindo
user
lo alhost
ilham :
(8.4.4)
onne
tion
( ipher :
DHERSAAES256SHA,
bits :
256)
BAB 7.
Type
44
DATABASE
for
help .
6
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 postgres kita
ukup mengetikkan psql saja. Apa bedanya
?
psql saja tanpa option apapun berarti:
1. Usernya sesuai user Linux.
2. Nama database sesuai nama user.
3. Koneksi melalui jalur UNIX so
ket, tidak melalui network.
7.1
Tabel
t o t a l i n d o (>
t o t a l i n d o (> nama
t o t a l i n d o (>
6
7
t o t a l i n d o (>
id
serial
will
for
reate
serial
impli it
olumn
" p e g a w a i _ p ke y"
t o t a l i n d o=>
Perhatikan prompt
totalindo=>
dan bedakan dengan prompt
totalindo(>
for
table
sequen e
"
NOT NULL,
v a r h a r ( 3 0 ) NOT NULL,
reate
impli it
BAB 7.
45
DATABASE
CREATE TABLE
menjadi
reate table
Sekarang kita lihat daftar tabel yang ada di database totalindo ini menggunakan
perintah \dt.
1
t o t a l i n d o=> \ d t
2
3
4
5
6
List
S
hema
of
relations
Name
Type
Owner
+++
publi
(1
pegawai
table
ilham
row )
7
8
t o t a l i n d o=>
t o t a l i n d o=> \d
2
3
pegawai
Table
Column
Type
|
Modifiers
4
5
++
id
integer
not
null
nama
hara ter
tgl_lahir
date
8
9
not
null
not
null
Indexes :
" p e g a w a i _ p k ey" PRIMARY KEY,
10
11
varying (30)
t o t a l i n d o=>
btree
( id )
default
BAB 7.
46
DATABASE
membuat:
1. Tipenya menjadi integer (bilangan bulat).
2. Memiliki default value nomor urut berikutnya.
7.1.1 Sequen
e
Sequen
e mirip tabel, tepatnya
t o t a l i n d o=> SELECT
sequen
e_name
FROM p e g a w a i _ i d _ s e q
last_value
is_ alled
;
|
+++
pegawai_id_seq
5
6
(1
row )
Sekarang kita lihat isi tabel pegawai.
1
2
3
4
t o t a l i n d o=> SELECT
id
nama
FROM p e g a w a i ;
tgl_lahir
++
(0
rows )
Tampak tabel pegawai masih kosong, mari tambah datanya.
INSERT 0
Perhatikan perintah di baris pertama tidak diakhiri dengan titik koma yang
berarti perintah belum berakhir dan dilanjutkan di baris berikutnya. Perhatikan
juga prompt pada baris kedua menjadi
totalindo->
yakni menggunakan karakter minus ( - ) yang berarti baris ini merupakan kelanjutan dari baris sebelumnya. Jika Anda salah dalam menuliskan perintah di
baris pertama dan terlanjur menekan Enter, akhiri saja dengan titik koma di
baris kedua. Kemudian mulai lagi dari awal. Berikut ini
ontoh kesalahan yang
bisa saja terjadi.
BAB 7.
47
DATABASE
t o t a l i n d o > ;
ERROR:
syntax
LINE
INSERT INT
1:
5
6
error
p e g a w a i ( nama , t g l _ l a h i r )
at
or
near
"INT"
p e g a w a i ( nama , t g l _ l a h i r )
^
t o t a l i n d o=>
Untuk mengulangi perintah sebelumnya tekan tombol panah atas.
Kembali ke tabel pegawai yang sudah kita isi dengan perintah INSERT.
Sekarang lihat hasilnya.
1
2
3
4
5
t o t a l i n d o=> SELECT
id
FROM p e g a w a i ;
nama
tgl_lahir
++
1 | Bummi Dwi P u t e r a | 1985 08 17
(1
row )
Perhatikan saat INSERT tadi eld id tidak disertakan, namun perintah SE-
LECT memperlihatkan bahwa eld id terisi dengan angka 1. Inilah yang disebut dengan eld autoin rement.
gawai_id_seq ?
1
2
3
4
t o t a l i n d o=> SELECT
sequen
e_name
FROM p e g a w a i _ i d _ s e q
last_value
is_ alled
++
pegawai_id_seq
5
6
(1
row )
Bandingkan dengan nilai-nilai pegawai_id_seq pada SELECT sebelum IN-
SERT. Yang perlu diperhatikan adalah eld is_
alled dimana sebelumnya f
(False) kini menjadi t (True).
INSERT 0
t o t a l i n d o=> SELECT
5
6
7
8
9
id
nama
FROM p e g a w a i ;
|
tgl_lahir
++
1 | Bummi Dwi P u t e r a | 1985 08 17
2 | Arief Setiadi
| 1972 05 02
(2
rows )
Perhatikan kembali eld id yang terisi dengan angka 2, dan lihat juga pe-
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.
2
3
48
DATABASE
sequen e_name
last_value
is_ alled
+++
pegawai_id_seq
5
6
(1
row )
Kini last_value menjadi 2, sehingga nextval() berikutnya last_value + 1 =
sudo
nano
/ e t / p o s t g r e s q l / 8 . 4 / main / p o s t g r e s q l . o n f
sudo
/ e t / i n i t . d/ p o s t g r e s q l
8.4
restart
Perlu Anda ketahui, format dmy otomatis Anda dapatkan bila saat instalasi
Ubuntu menggunakan bahasa Indonesia.
Cobalah untuk menambah data pegawai lagi dengan tanggal lahir berformat
tanggal-bulan-tahun.
1
INSERT 0
t o t a l i n d o=> SELECT
5
6
7
8
9
10
id
1
nama
FROM p e g a w a i ;
|
tgl_lahir
++
1 | Bummi Dwi P u t e r a | 1985 08 17
2 | Arief Setiadi
| 1972 05 02
3 | Ce
ep Z a h r u d i n
| 1972 06 01
(3
rows )
Agar tampil urut sesuai abjad gunakan ORDER BY.
BAB 7.
1
2
3
4
5
6
7
t o t a l i n d o=> SELECT
id
49
DATABASE
nama
tgl_lahir
++
2 | Arief Setiadi
| 1972 05 02
1 | Bummi Dwi P u t e r a | 1985 08 17
3 | Ce
ep Z a h r u d i n
| 1972 06 01
(3
rows )
Gunakan WHERE untuk mendapatkan re
ord tertentu.
1
2
3
4
5
t o t a l i n d o=> SELECT
id
FROM p e g a w a i WHERE i d = 1 ;
nama
tgl_lahir
++
1 | Bummi Dwi P u t e r a | 1985 08 17
(1
row )
Tampilkan pegawai yang lahir di tahun 1972 dan diurutkan mulai yang ter-
tua.
t o t a l i n d o=> SELECT
t o t a l i n d o > ORDER BY t g l _ l a h i r ;
4
5
6
7
8
id
nama
FROM p e g a w a i
t g l _ l a h i r ) = 1972
tgl_lahir
++
2 | Arief Setiadi
| 1972 05 02
3 | Ce
ep Z a h r u d i n | 1972 06 01
(2
rows )
Gunakan DESC pada ORDER BY jika ingin diurut mulai yang termuda.
Tekan tombol panah atas untuk mengulang perintah sebelumnya dan tambahkan DESC.
1
t o t a l i n d o=> SELECT
FROM p e g a w a i
ORDER BY t g l _ l a h i r
4
5
6
7
8
id
nama
t g l _ l a h i r ) = 1972
DESC ;
|
tgl_lahir
++
3 | Ce
ep Z a h r u d i n | 1972 06 01
2 | Arief Setiadi
| 1972 05 02
(2
rows )
INSERT 0
BAB 7.
50
DATABASE
Manusia bisa jadi memahami mana nama laki-laki dan mana perempuan.
Namun komputer mengalami kesulitan bila mengandalkan nama. Oleh karena
itu kita perlu menambah eld pria yang bertipe logika (boolean). Kita membutuhkan perintah ALTER TABLE di sini.
1
b o o l e a n NOT NULL
DEFAULT t r u e ;
2
ALTER TABLE
Seperti dijelaskan pada sesi Python sebelumnya, boolean hanya bisa diisi
dengan dua nilai, bisa True atau False. Kita menamakan eld ini dengan pria
dengan begitu nilai default-nya adalah True. Jika eld pria False berarti pegawai
tersebut perempuan. Sekarang kita lihat isi tabel pegawai setelah penambahan
eld di atas.
1
2
3
4
5
6
7
8
t o t a l i n d o=> SELECT
id
nama
tgl_lahir
pria
+++
2 | Arief Setiadi
| 1972 05 02 | t
1 | Bummi Dwi P u t e r a | 1985 08 17 | t
3 | Ce
ep Z a h r u d i n
| 1972 06 01 | t
4 | Nita Pandria
| 1976 09 19 | t
(4
rows )
Perhatikan eld pria, tampak semua tertulis t yang artinya True. Apa data
p r i a = F a l s e WHERE i d = 4 ;
UPDATE 1
t o t a l i n d o=> SELECT
id
nama
tgl_lahir
pria
+++
2 | Arief Setiadi
| 1972 05 02 | t
1 | Bummi Dwi P u t e r a | 1985 08 17 | t
3 | Ce
ep Z a h r u d i n
| 1972 06 01 | t
4 | Nita Pandria
| 1976 09 19 | f
(4
rows )
Kita sudah membuat re
ord dengan INSERT, menampilkannya dengan SE-
LECT, dan mengubahnya dengan UPDATE. Kini kita
oba untuk menghapusnya dengan DELETE FROM yaitu pegawai dengan id 2.
1
2
3
4
5
nama
tgl_lahir
pria
+++
BAB 7.
Bummi Dwi
Ce ep
Nita
(3
51
DATABASE
Putera
Zahrudin
Pandria
1985 08 17
1972 06 01
1976 09 19
rows )
Jika Anda kurang suka dengan eld pria yang bertipe boolean bisa dihapus
Silahkan
7.2
View
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
3
id
nama
? olumn ?
++
Arief
Setiadi
13957
days
11:21:54.083022
Ce ep
Zahrudin
13927
days
11:21:54.083022
Nita
Bummi Dwi
(4
Pandria
Putera
12356
9102
days
days
11:21:54.083022
11:21:54.083022
rows )
Kolom ketiga berisi usia, tapi PostgreSQL tidak tahu harus dinamakan apa,
sehingga jadilah bernama ?
olumn?. Ada baiknya kita berikan nama usia.
1
t o t a l i n d o=> SELECT i d ,
3
4
id
nama
nama ,
now ( )
tgl_lahir
AS
usia
usia
++
Arief
Setiadi
13957
days
11:28:34.001142
Ce ep
Zahrudin
13927
days
11:28:34.001142
BAB 7.
Nita
Bummi Dwi
(4
52
DATABASE
Pandria
Putera
12356
9102
days
days
11:28:34.001142
11:28:34.001142
rows )
Satuan usia menggunakan hari tentu saja kurang nyaman diba
a. Sebaiknya
t o t a l i n d o=> SELECT i d ,
t o t a l i n d o > e x t r a
t ( y e a r
tgl_lahir )
3
4
5
AS
nama ,
from
e x t r a t ( year
from
nama
usia
++
Arief
Setiadi
38
Ce ep
Zahrudin
38
Nita
Bummi Dwi
10
now ( ) )
usia
(4
Pandria
Putera
34
25
rows )
Perintah SQL (query) di atas dapat disimpan dalam sebuah VIEW.
e x t r a
t ( year
AS
from
now ( ) )
e x t r a t ( year
from
nama ,
tgl_lahir )
usia
FROM p e g a w a i ORDER BY t g l _ l a h i r ;
CREATE VIEW
Selanjutnya kita tampilkan VIEW tadi layaknya sebuah tabel.
1
2
3
t o t a l i n d o=> SELECT
id
FROM v_pegawai ;
nama
usia
++
Arief
Setiadi
38
Ce ep
Zahrudin
38
Nita
Bummi Dwi
(4
Pandria
Putera
34
25
rows )
Penamaan VIEW tidak harus berawalan v_. Penggunaan awalan itu un-
t o t a l i n d o=> SELECT
id
nama
usia
BAB 7.
++
Arief
Bummi Dwi
Ce ep
Nita
53
DATABASE
(4
Setiadi
Putera
Zahrudin
Pandria
38
25
38
34
rows )
7.3
1
2
3
4
5
6
7
8
9
CREATE TABLE
var
har NOT NULL
date NOT NULL
NOT NULL DEFAULT true
PRIMARY KEY
pegawai (
id
serial ,
nama
pria
boolean
) ;
INSERT INTO
INSERT INTO
INSERT INTO
INSERT INTO
p e g a w a i ( nama , t g l _ l a h i r , p r i a )
true
true
true
false
);
p e g a w a i ( nama , t g l _ l a h i r , p r i a )
12
);
p e g a w a i ( nama , t g l _ l a h i r , p r i a )
11
( id )
Dwi
10
(30)
tgl_lahir
);
p e g a w a i ( nama , t g l _ l a h i r , p r i a )
) ;
VALUES
VALUES
VALUES
VALUES
( ' Bummi
( ' Arief
( ' Ce
ep
( ' Nita
t o t a l i n d o=> \ i
p s q l : s q l / pegawai . s q l : 7 :
impli
it
pegawai . s q l
sequen e
NOTICE :
CREATE TABLE
for
will
serial
reate
olumn
p s q l : s q l / pegawai . s q l : 7 :
KEY w i l l
table
reate
NOTICE :
impli it
CREATE TABLE
INSERT 0
INSERT 0
INSERT 0
INSERT 0
index
" p e g a w a i _ p ke y"
for
BAB 7.
54
DATABASE
t o t a l i n d o=> \ i
/home/ s u g i a n a / p e g a w a i . s q l
Sesuaikan dengan direktori dimana Anda menyimpan pegawai.sql. Mudahmudahan Anda mengerti maksudnya.
Kini ba
kup database totalindo dalam sebuah le berformat tar.
1
$ pg_dump
ilham
totalindo
lo alhost
pg_restore
ilham
lo alhost
Lalu jalankan:
totalindo_1
$ pg_dump
ilham
totalindo
lo alhost
totalindo .
sql
dan restore dengan psql:
1
psql
ilham
totalindo_1
lo alhost
totalindo . sql
Manfaat penggunaan plaintext adalah Anda bisa mengubah le totalindo.sql menggunakan teks editor biasa. Namun penggunaan format ini terkadang
menimbulkan masalah saat restore bila ada karakter aneh, yaitu karakter dengan nomor ASCII lebih besar dari 126.
7.3.1 En
oding
PostgreSQL versi terdahulu biasanya menggunakan SQL_ASCII sebagai en
oding
hara
ter. Anda bisa lihat dengan perintah \l di psql.
1
psql
psql
(8.4.4)
ilham
Type
for
template1
lo alhost
help .
4
5
p o s t g r e s=# \ l
List
7
8
9
10
11
12
13
14
of
databases
Name
Owner
En oding
Collation
++++
postgres
| p o s t g r e s | UTF8
| id_ID . UTF8 |
template0
| p o s t g r e s | UTF8
| id_ID . UTF8 |
template1
| p o s t g r e s | UTF8
| id_ID . UTF8 |
totalindo
| ilham
| UTF8
| id_ID . UTF8 |
totalindo_1 | ilham
| UTF8
| id_ID . UTF8 |
(5
rows )
BAB 7.
55
DATABASE
Perhatikan di versi ini default en
oding adalah UTF8. Jika Anda memba
kup, perhatikanlah en
oding ini. Misalkan menggunakan SQL_ASCII, maka di
database yang baru pun Anda sebaiknya tetap menggunakan en
oding yang
sama. Sebagai latihan kembalilah ke konsole, lalu buat database totalindo_2
dengan en
oding SQL_ASCII.
1
# su
sudo
su
postgres
reatedb
ilham
template0
sql_as ii
totalindo_2
Kembali ke psql dan lihat daftar database. Karena masih sebagai user postgres maka
ukup ketik psql.
1
psql
psql
(8.4.4)
Type
for
help .
4
5
p o s t g r e s=# \ l
List
7
8
9
10
11
12
13
14
15
of
databases
Name
Owner
En oding
Collation
++++
postgres
| p o s t g r e s | UTF8
| id_ID . UTF8 |
template0
| p o s t g r e s | UTF8
| id_ID . UTF8 |
template1
| p o s t g r e s | UTF8
| id_ID . UTF8 |
totalindo
| ilham
| UTF8
| id_ID . UTF8 |
totalindo_1 | ilham
| UTF8
| id_ID . UTF8 |
totalindo_2 | ilham
| SQL_ASCII | id_ID . UTF8 |
(6
rows )
Mengenai
ara ba
kup dan restore lainnya sama seperti sebelumnya.
Mengapa kita perlu memperhatikan en
oding ?
Bila database yang Anda ba
kup tidak mengandung karakter aneh (ASCII
> 126) maka bisa dengan nyaman di-restore dari ke UTF8. Namun bila mengandung ASCII > 126 maka restore ke UTF8 dari sumber SQL_ASCII bisa
menimbulkan masalah.
7.4
Fungsi
Sama seperti Python, PostgreSQL juga mengenal fungsi. Contoh fungsi bawaan
(built-in) adalah now().
1
2
3
4
5
now
2010 08 24 1 6 : 0 6 : 5 8 . 6 7 8 0 5 6 + 0 7
(1
row )
Keunikan fungsi pada PostgreSQL adalah pada nama dan susunan masukan-
BAB 7.
2
3
lpad
4
5
56
DATABASE
A
(1
row )
Fungsi lpad() berguna untuk memberi spasi di sebelah kiri. Jumlah spasi
ditambah jumlah karakter string 'A' tidak boleh melebihi 5. Jadi pada
ontoh
di atas jumlah spasi di sebelah 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
length
4
5
l e n g t h ( l p a d ( ' A' , 5 ) ) ;
5
(1
row )
Sekarang kita membutuhkan awalan '0' pada sebuah nomor, misalnya '00001'.
Ini lazim kita temui pada beberapa laporan. Fungsi apa yang akan digunakan.
Jawabannya masih menggunakan fungsi lpad().
1
2
3
lpad
4
5
00001
(1
row )
Di sinilah letak keunikan sebuah fungsi pada PostgreSQL. Fungsi lpad()
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 beberapa fungsi dengan nama sama maka harus
dibedakan dengan:
1. Jumlah masukannya.
2. Jika jumlah masukannya sama maka bedakan tipe data setiap masukan
tersebut.
7.4.1 PL/pgSQL
Salah satu yang membuat PostgreSQL begitu mudah dikembangkan adalah
fungsi tersebut bisa ditulis dalam berbagai bahasa. Dimana Anda bisa menulis
fungsi dalam bahasa pgSQL, Python, Perl, hingga T
l. Se
ara default bahasa
yang didukungnya adalah plpgsql. Namun Anda perlu memasangnya terlebih
dahulu pada database yang dimaksud.
1
sudo
su
postgres
" reatelang
plpgsql
totalindo "
BAB 7.
57
DATABASE
psql
ilham
totalindo
lo alhost
sedangkan yang kedua untuk text editor vi. Tentu saja Anda bisa menggunakan 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.
1
2
3
4
5
6
7
8
CREATE OR
RETURNS
REPLACE FUNCTION h e l l o ( )
text
LANGUAGE p l p g s q l
AS
$$
BEGIN
RETURN
END
' Hello
world . ' ;
$$ ;
t o t a l i n d o=> \ i
hello . sql
CREATE FUNCTION
lalu
obalah
t o t a l i n d o=> SELECT
2
3
4
5
hello () ;
hello
Hello
(1
world .
row )
Transaksi Perbankan
Kita sudah punya tabel pegawai dimana setiap pegawai dianggap sebagai nasabah
pada perusahaan ini. Saat mendapat gaji saldonya bertambah. Saat ambil gaji
saldonya berkurang. Saat kas bon (pinjam) saldonya juga berkurang. Jadi saldo
juga bisa negatif yang berarti pegawai tersebut punya hutang ke perusahaan.
Pertama kita butuh eld saldo pada tabel pegawai.
ALTER TABLE
pegawai
ADD
saldo
0;
Kemudian untuk men
atat aktivitas transaksi kita memerlukan tabel transaksi berikut ini.
Listing 7.3: transaksi.sql
1
2
3
4
CREATE TABLE
PRIMARY KEY
integer NOT NULL
timestamp NOT NULL DEFAULT
transaksi (
id
pid
tgl
serial
REFERENCES p e g a w a i ,
now ( ) ,
BAB 7.
var
har
NOT NULL
float NOT NULL
float NOT NULL
ket
nominal
7
8
58
DATABASE
(100)
saldo
) ;
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 ;
2
3
INSERT INTO
FROM p e g a w a i
WHERE i d = 1 ;
Ya, kita butuh dua query untuk sebuah transaksi. Mungkin ada pertanyaan,
untuk apa eld saldo pada tabel transaksi ? Field ini digunakan untuk memudahkan pen
etakan buku tabungan yang biasanya men
antumkan saldo pada
setiap transaksi.
Kalau diperhatikan, transaksi tersebut membutuhkan 3 parameter masukan:
1. ID pegawai
2. Keterangan transaksi
3. Nominal transaksi
Kalau transaksi ini dikemas dalam sebuah fungsi, lalu apa keluarannya ? Keluaran atau output yang paling tepat adalah ID transaksi. Query-nya bisa kita
peroleh dengan
ara berikut ini.
1
SELECT
1;
id
pid
tgl
+++
1 |
1 | 2010 10 22 1 7 : 5 8 : 0 1 . 8 6 |
4
5
6
7
ket
nominal
saldo
++
GAJI 11 2010 | 3 0 0 0 0 0 0 | 3 0 0 0 0 0 0
Selanjutnya kita buat fun
transaksi.sql untuk fungsi dimaksud.
1
2
3
4
5
CREATE OR
integer
float
integer
REPLACE FUNCTION t r a n s a k s i (
p_pid
p_ket
text ,
p_nominal
RETURNS
BAB 7.
6
7
8
LANGUAGE p l p g s q l
AS
$$
DECLARE
re
10
BEGIN
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
59
DATABASE
re ord ;
UPDATE
SET
WHERE
INSERT INTO
SELECT
FROM
WHERE
SELECT
INTO
FROM
ORDER BY DESC
LIMIT
pegawai
s a l d o = s a l d o + p_nominal
i d = p_pid ;
transaksi (
id ,
pid ,
nominal ,
tid ,
ket ,
p_pid ,
saldo )
p_nominal ,
p_ket ,
saldo
pegawai
i d = p_pid ;
id
re
transaksi
id
1;
RETURN r e . i d ;
END
$$
t o t a l i n d o=> \ i
CREATE FUNCTION
Misalkan ID pegawai 1 meminjam (
ash bon) sebesar Rp200.000,- maka:
t o t a l i n d o=> SELECT
transaksi
4
5
t r a n s a k s i ( 1 , 'BON' ,
200000) ;
2
(1
row )
Perhatikan nominal berisi nilai negatif yang artinya mengurangi saldo. Sekarang
t o t a l i n d o=> SELECT
id
pid
FROM t r a n s a k s i ;
tgl
nominal
3
|
|
ket
saldo
+++++
1
2010 10 22
3000000
3000000
17:58:01.869139
GAJI 11 2010
BAB 7.
2010 10 22
200000
6
(2
60
DATABASE
18:20:08.845091
| BON
2800000
rows )
Dilihat dari aspek ke
epatan, query SELECT terhadap tabel transaksi bisa
dihindari. Maklumlah tabel transaksi ini tergolong
epat pertumbuhan re
ordnya. Jadi untuk mendapatkan ID transaksi kita perlu menggunakan sequen
e
yang dimiliki tabel transaksi tersebut. Ubahlah fun
transaksi.sql menjadi berikut
ini.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
CREATE OR
integer
float
integer
AS
integer
UPDATE
SET
WHERE
REPLACE FUNCTION t r a n s a k s i (
p_pid
p_ket
17
18
19
20
21
22
23
24
25
text ,
p_nominal
RETURNS
LANGUAGE p l p g s q l
$$
DECLARE
tid
BEGIN
pegawai
s a l d o = s a l d o + p_nominal
i d = p_pid ;
15
16
INSERT INTO
SELECT
FROM
WHERE
id ,
pid ,
transaksi (
nominal ,
tid ,
ket ,
p_pid ,
saldo )
p_nominal ,
p_ket ,
saldo
pegawai
i d = p_pid ;
RETURN t i d ;
END
$$
Restore.
1
2
t o t a l i n d o=> \ i
transaksi . sql
CREATE FUNCTION
Kini kita
oba ID pegawai 5 bernama Ilham untuk transaksi.
t o t a l i n d o=> SELECT
transaksi
4
5
3
(1
row )
t r a n s a k s i ( 5 , ' GAJI
BAB 7.
61
DATABASE
id
pid
tgl
|
ket
saldo
+++++
2010 10 22
3000000
5
|
|
17:58:01.869139
GAJI 11 2010
18:20:08.845091
| BON
18:41:45.309451
3000000
2800000
2010 10 22
1500000
(3
2010 10 22
200000
FROM t r a n s a k s i ;
nominal
3
t o t a l i n d o=> SELECT
GAJI 11 2010
1500000
rows )
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
sudo
a p t g e t
sudo
su
install
Kali ini akan kita gunakan pada fungsi di PostgreSQL. Buatlah uang.sql
postgres
p o s t g r e s q l p l p y t h o n
"
reatelang
8.4
plpythonu
totalindo "
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
CREATE OR
RETURNS
text
float
LANGUAGE p l p y t h o n u
AS
from
$$
uang
return
import
uang
uang ( n )
$$ ;
CREATE OR
RETURNS
text
integer
LANGUAGE p l p y t h o n u
AS
from
$$
uang
return
import
uang
uang ( n )
$$ ;
Tidak seperti plpgsql, fungsi yang ditulis menggunakan plpythonu harus
dibuat oleh user postgres.
BAB 7.
[ sudo
62
DATABASE
sudo
su
postgres
password
CREATE FUNCTION
CREATE FUNCTION
for
"psql
totalindo
sugiana :
Lalu
obalah.
1
uang
4
5
10.000
(1
row )
uang . s q l "
Bab 8
sudo
a p t g e t
install
python s q l a l h e m y
sudo
a p t g e t
install
python p s y o p g 2
>>> i m p o r t
>>> u r l =
sqlal hemy
as
sa
>>> db = s a . r e a t e _ e n g i n e ( u r l )
>>> db . o n n e t ( )
<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
obje t
at
0 x8b0872 >
berhasil dengan perintah
onne
t(). Anda bisa lanjutkan dengan perintah query
untuk melihat re
ord tabel pegawai.
>>> s q l
>>> q = db . e x e u t e ( s q l )
>>> f o r
...
= "SELECT
in
FROM p e g a w a i "
q:
r
...
(1 ,
(2 ,
' Arief
(3 ,
' Ce ep
(4 ,
' Nita
Putera ' ,
Setiadi ' ,
Zahrudin ' ,
Pandria ' ,
8,
5,
9,
17) ,
2) ,
6,
1) ,
19) ,
True )
True )
True )
False )
Lalu bagaimana kalau kita ingin melihat nilai berdasarkan nama eld-nya
? Untunglah variabel r di atas bisa dianggap sebagai di
tionary yang keys-nya
berisi nama eld dari query bersangkutan.
63
BAB 8.
64
>>> q = db . e x e u t e ( s q l )
>>> f o r
in
...
...
1 Bummi Dwi
Arief
Ce ep
Nita
q:
r [ ' id ' ,
Putera
Setiadi
Zahrudin
Pandria
>>> q = db . e x e u t e ( s q l )
>>> f o r
in
...
...
1 Bummi Dwi
Arief
Ce ep
Nita
q:
r . id ,
r . nama
Putera
Setiadi
Zahrudin
Pandria
Mudah bukan ?
Fungsi exe
ute() bisa juga digunakan untuk perintah query lainnya seperti
INSERT, UPDATE, dan DELETE. Contohnya mengganti huruf pada eld nama
dengan kapital.
1
>>> s q l
>>> db . e x e u t e ( s q l )
<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
>>> s q l
>>> q = db . e x e u t e ( s q l )
>>> f o r
7
8
9
...
= "SELECT
r
in
obje t
at
0 x b 7 4 8 a 9 a >
FROM p e g a w a i "
q:
r . nama
...
BUMMI DWI PUTERA
10
ARIEF SETIADI
11
CECEP ZAHRUDIN
12
NITA PANDRIA
8.1
A tive Re ord
Anda memiliki data pegawai dalam sebuah le yang berformat CSV yang isinya
seperti ini:
Listing 8.1: pegawai.
sv
1
ST; 1 9 8 5 0 8 1 7 ; t
2 ; ARIEF SETIADI ; 1 9 7 2 0 5 0 2 ; t
3 ;CECEP ZAHRUDIN; 1 9 7 2 0 6 0 1 ; t
BAB 8.
65
4 ; NITA PANDRIA; 1 9 7 6 0 9 1 9 ; f
5 ; ILHAM; 1 9 8 4 1 1 0 5 ; t
File ini men
erminkan tabel pegawai dimana setiap eld dipisahkan dengan
titik koma ( ; ). Sedangkan identitas baris berupa ID pegawai yang berada di
kolom pertama, persis seperti tabel pegawai. Tugasnya adalah menyalin isi le
ini ke dalam tabel pegawai. Jika ID pegawai sudah ada maka lakukan UPDATE,
jika belum berarti INSERT.
Mari kita lihat terlebih dahulu isi tabel pegawai melalui psql.
Password
psql
psql
SSL
Type
ilham
for
user
lo alhost
totalindo
ilham :
(8.4.4)
onne
tion
" help "
( ipher :
for
DHERSAAES256SHA,
bits :
256)
help .
6
7
8
9
10
11
12
13
14
t o t a l i n d o=> SELECT
id
FROM p e g a w a i ;
nama
tgl_lahir
pria
+++
1 | BUMMI DWI PUTERA | 1985 08 17 | t
2 | ARIEF SETIADI
| 1972 05 02 | t
3 | CECEP ZAHRUDIN
| 1972 06 01 | t
4 | NITA PANDRIA
| 1976 09 19 | f
(4
rows )
Bandingkanlah dengan le pegawai.
sv sebelumnya dimana perubahannya
nanti adalah:
1. ID 1 nama akan berubah dari BUMMI DWI PUTERA menjadi BUMMI
DWI PUTERA, ST (bergelar).
2. Jumlah baris tabel pegawai bertambah dengan adanya ID 5 bernama ILHAM.
Buatlah le pegawai.
sv terlebih dahulu dengan isi seperti di atas. Kemudian
buatlah le updatepegawai.py.
1
2
import
as
sa
url =
db = s a . r e a t e _ e n g i n e ( u r l )
db . o n n e t ( )
6
7
filename =
f = open ( f i l e n a m e )
9
10
for
line
pid ,
in
nama ,
tgl_lahir ,
BAB 8.
11
pid = i n t ( pid )
12
p r i a = p r i a ==
13
sql
14
q = db . e x e u t e ( s q l )
if
15
16
66
= "SELECT
't '
# Agar b o o l e a n True / F a l s e
q . row
ount :
s q l = "UPDATE p e g a w a i SET " + \
17
18
19
" p r i a = %s
20
" + \
" + \
" + \
"WHERE i d = %d "
21
else
22
23
s q l = s q l % ( nama ,
tgl_lahir ,
pria ,
s q l = "INSERT INTO p e g a w a i
" ( id ,
25
"SELECT %d ,
'% s ' ,
s q l = s q l % ( pid ,
nama ,
tgl_lahir ,
27
nama ,
" + \
24
26
pid )
:
tgl_lahir ,
pria )
" + \
pria )
db . e x e
u t e ( s q l )
Jalankan.
python
u p d a t e p e g a w a i . py
t o t a l i n d o=> SELECT
2
3
4
5
6
7
8
9
id
FROM p e g a w a i ORDER BY i d ;
nama
tgl_lahir
pria
+++
1 | BUMMI DWI PUTERA, ST | 1985 08 17 | t
2 | ARIEF SETIADI
| 1972 05 02 | t
3 | CECEP ZAHRUDIN
| 1972 06 01 | t
4 | NITA PANDRIA
| 1976 09 19 | f
5 | ILHAM
| 1984 11 05 | t
(5
rows )
Perubahan sudah sesuai dengan yang diharapkan.
a tive re ord
sudo
a p t g e t
install
python e l i x i r
Agar proses UPDATE dan INSERT masih terasa, buatlah perubahan pada
pegawai.
sv berikut ini.
Listing 8.3: pegawai.
sv
1
2 ; ARIEF SETIADI ; 1 9 7 2 0 5 0 2 ; t
ST; 1 9 8 5 0 8 1 7 ; t
3 ;CECEP ZAHRUDIN ,
ST; 1 9 7 2 0 6 0 1 ; t
BAB 8.
67
4 ; NITA PANDRIA; 1 9 7 6 0 9 1 9 ; f
5 ; ILHAM; 1 9 8 4 1 1 0 5 ; t
6 ;MIRANDA; 1 9 7 8 1 0 0 1 ; f
Perubahannya adalah UPDATE pada CECEP ZAHRUDIN menjadi CECEP ZAHRUDIN, ST, dan INSERT pada MIRANDA. Selanjutnya buat le
updatepegawai1.py.
from
import
elixir
metadata ,
2
3
4
5
Entity ,
using_options ,
setup_all ,
session
lass
Pegawai ( E n t i t y ) :
6
7
metadata . b i n d =
totalindo '
8
setup_all ()
9
10
filename =
11
f = open ( f i l e n a m e )
12
13
for
in
line
pid ,
f . readlines () :
nama ,
tgl_lahir ,
14
pid = i n t ( pid )
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 )
if
else
16
p . ount ( ) :
17
18
19
20
r = p . one ( )
:
r = Pegawai ( )
r . id = pid
21
r . nama = nama
22
r . tgl_lahir = tgl_lahir
23
r . p r i a = p r i a ==
24
s e s s i o n . ommit ( )
't '
Jalankanlah.
1
python
u p d a t e p e g a w a i 1 . py
t o t a l i n d o=> SELECT
id
nama
FROM p e g a w a i ORDER BY i d ;
|
tgl_lahir
pria
+++
1 | BUMMI DWI PUTERA, ST | 1985 08 17 | t
2 | ARIEF SETIADI
| 1972 05 02 | t
3 | CECEP ZAHRUDIN , ST
| 1972 06 01 | t
BAB 8.
68
NITA PANDRIA
1976 09 19
ILHAM
1984 11 05
| MIRANDA
1978 10 01
9
10
6
(6
rows )
Hasil sudah sesuai harapan dengan sour
e yang jauh lebih mudah diba
a.
from
import
elixir
setup_all ,
2
3
4
5
6
7
8
9
10
11
12
13
14
import
lass
using_options ,
metadata ,
session
sys
Pegawai ( E n t i t y ) :
if not
sys . argv [ 1 : :
s y s . e x i t ( ' Caranya :
try
ex
ept
s y s . e x i t ( ' ID
pegawai
harus
angka ' )
15
16
metadata . b i n d =
totalindo '
17
setup_all ()
18
19
20
21
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 )
if not
p . ount ( ) :
s y s . e x i t ( ' ID
p e g a w a i %d
tidak
ada ' % p i d )
22
23
r = p . one ( )
24
r . delete ()
25
26
s e s s i o n .
ommit ( )
' ID
p e g a w a i %d
sudah
ID
python
d e l e t e _ p e g a w a i . py
pegawai
sudah
dihapus
BAB 8.
1
2
3
4
5
6
7
8
9
t o t a l i n d o=> SELECT
id
69
FROM p e g a w a i ORDER BY i d ;
nama
tgl_lahir
pria
+++
1 | BUMMI DWI PUTERA, ST | 1985 08 17 | t
2 | ARIEF SETIADI
| 1972 05 02 | t
3 | CECEP ZAHRUDIN , ST
| 1972 06 01 | t
5 | ILHAM
| 1984 11 05 | t
6 | MIRANDA
| 1978 10 01 | f
(5
rows )
Bagaimana dengan SELECT ? Contoh sebelumnya menggunakan lter_by()
yang sama artinya dengan WHERE. Kini kita tampilkan semua re
ord tabel pegawai tanpa kondisi apapun yaitu mengganti lter_by() dengan all(). Buatlah
sele
tpegawai.py.
from
import
lass
elixir
import
using_options ,
metadata ,
setup_all
2
3
4
5
sys
Pegawai ( E n t i t y ) :
6
7
metadata . b i n d =
totalindo '
8
setup_all ()
for
10
11
in
print
r
Pegawai . q u e r y . a l l ( ) :
r . id ,
r . nama ,
r . tgl_lahir ,
r . pria
Jalankan.
$
1
2
3
5
6
Butuh tampilan yang urut berdasarkan nama ? Kita biasa menggunakan ORDER BY pada query, disini bisa menggunakan order_by() sebagai pengganti
all().
from
import
elixir
import
setup_all
sys
Entity ,
using_options ,
metadata ,
BAB 8.
3
4
5
70
lass
Pegawai ( E n t i t y ) :
6
7
metadata . b i n d =
totalindo '
8
setup_all ()
for
10
11
in
print
r
r . nama ,
r . tgl_lahir ,
r . pria
Jalankan.
1
python
s e l e t _ p e g a w a i . py
3 CECEP ZAHRUDIN ,
6 MIRANDA 1978 10 01
ST 1985 08 17 True
ST 1972 06 01 True
False
1
2
3
4
5
from
import
lass
elixir
sys
import
Pegawai ( E n t i t y ) :
6
7
metadata . b i n d =
totalindo '
8
setup_all ()
9
10
jenis
= { True :
11
False :
12
13
14
15
for
16
in
print
r
p:
str ( r . id ) .
enter (3) ,
r . nama . l j u s t ( 2 0 ) ,
17
r . tgl_lahir ,
18
jeni s [ r . pria
Jalankan.
1
python
s e l e t _ p e g a w a i . py
ARIEF SETIADI
1972 05 02
Pria
ST 1985 08 17
Pria
BAB 8.
71
CECEP ZAHRUDIN ,
1972 06 01
Pria
ILHAM
ST
1984 11 05
Pria
MIRANDA
1978 10 01 Wanita
python-elixir.
1
Pa kage :
dpkg
python e l i x i r
python e l i x i r
Version :
0.7.1 1
Depends :
p y t h o n (>=
2.4) ,
python s q l a l
h e m y
5
Des ription :
8.2
(>=
De larative
python s u p p o r t (>=
0.90.0) ,
0.4.0)
Mapper
for
SQLAl hemy
Auto Commit
Masih ingat fungsi sql bernama transaksi() ? Kali ini akan kita buat transaksi
perbankan se
ara interaktif. Buatlah transaksi.py berikut.
1
2
3
import
import
as
sa
sys
url =
db = s a . r e a t e _ e n g i n e ( u r l )
print
try
ex
ept
7
8
9
10
11
12
p i d = r a w _ i n p u t ( ' ID
pegawai :
')
pid = i n t ( pid )
ValueError :
s y s . e x i t ( ' ID
p e g a w a i %s
tidak
13
14
sql
15
q = db . e x e u t e ( s q l )
16
17
18
19
20
21
22
if not
print
q . row ount :
s y s . e x i t ( ' ID
' Nama : ' ,
p e g a w a i %d
if not
tidak
ada ' % p i d )
q . f e t
h o n e ( ) . nama
')
ket :
s y s . e x i t ( ' Keterangan
harus
diisi ')
BAB 8.
72
23
24
25
26
27
28
n o m i n a l = r a w _ i n p u t ( ' Nominal :
try
ex
ept
')
nominal = f l o a t ( nominal )
ValueError :
s y s . e x i t ( ' Nominal %s
tidak
29
30
sql
= "SELECT
ket ,
nominal )
31
32
q = db . e x e u t e ( s q l )
' Transaksi
berhasil ,
ID ' ,
Jalankan.
1
Transaksi
python
t r a n s a k s i . py
ID
Nama :
pegawai :
Keterangan :
Nominal :
Transaksi
CECEP ZAHRUDIN ,
ST
GAJI 11 2010
4500000
berhasil ,
ID
t o t a l i n d o=> SELECT
id
pid
FROM t r a n s a k s i ;
tgl
ket
nominal
saldo
+++++
1 |
1 | 2010 10 22 | GAJI 11 2010 | 3 0 0 0 0 0 0 | 3 0 0 0 0 0 0
2 |
1 | 2010 10 22 | BON
| 200000 | 2 8 0 0 0 0 0
3 |
5 | 2010 10 22 | GAJI 11 2010 | 1 5 0 0 0 0 0 | 1 5 0 0 0 0 0
(3
rows )
Perhatikan, tidak ada ID transaksi 4, padahal eksekusi transaksi.py berjalan
transa tion
ommit
1
2
3
4
import
from
import
as
sa
import
text
auto
BAB 8.
url =
db = s a . r e a t e _ e n g i n e ( u r l )
print
try
ex
ept
8
9
10
11
12
13
73
p i d = r a w _ i n p u t ( ' ID
pegawai :
')
pid = i n t ( pid )
ValueError :
s y s . e x i t ( ' ID
p e g a w a i %s
tidak
14
15
sql
16
q = db . e x e u t e ( s q l )
17
18
19
20
21
22
23
if not
print
q . row ount :
s y s . e x i t ( ' ID
' Nama : ' ,
p e g a w a i %d
tidak
if not
ada ' % p i d )
q . f e t
h o n e ( ) . nama
')
ket :
s y s . e x i t ( ' Keterangan
harus
diisi ')
24
25
26
27
28
29
n o m i n a l = r a w _ i n p u t ( ' Nominal :
try
ex
ept
')
nominal = f l o a t ( nominal )
ValueError :
s y s . e x i t ( ' Nominal %s
tidak
30
31
sql
= "SELECT
ket ,
nominal )
32
33
q = db . e x e u t e ( t e x t ( s q l ,
' Transaksi
a u t o o m m i t=True ) )
berhasil ,
ID ' ,
q = db.exe
ute(sql)
menjadi
Syn hronizer
Pelanggan Anda memiliki usaha di bidang mini market dan telah memiliki beberapa outlet. Semua outlet itu telah terhubung ke Internet. Internet digunakan
BAB 8.
74
untuk mengambil data produk yang dikirim kantor pusat melalui email. Data
produk tersebut tersimpan dalam atta
hment. User di outlet menyimpannya ke
folder tertentu untuk selanjutnya dimasukkan ke database outlet melalui menu
Restore yang telah disediakan di aplikasi.
si. Data disimpan terlebih dahulu ke dalam sebuah le melalui menu Ba
kup.
Selanjutnya le tersebut di-email ke kantor pusat.
Teknik ini sudah baik, namun lebih baik lagi jika pekerjaan itu dilakukan
oleh s
ript yang disebut syn
hronizer.
Kita membi
arakan mekanisme otomatis penuh, dimana syn
hronizer dipi
u
oleh waktu, misalkan jam 9:00 dan jam 17:00 setiap harinya. Berbeda dengan
teknik sebelumnya, syn
hronizer tidak menggunakan email untuk komunikasi
data. Ia bekerja langsung dengan database pusat dan database outlet.
Lalu bagaimana kedua host outlet dan pusat saling terhubung ?
Ya, kita memerlukan
let dapat mengakses database pusat. IP publik ini dapat dipesan ke ISP (Internet Servi
e Provider) bersangkutan. Setelah IP publik didapat, tambahkan
baris berikut ini di
sudo
Restarting
servi e
postgresql
PostgreSQL
8.4
8.4
restart
database
server
psql
di outlet
ilham
110.137.120.251
totalindo
url = 'postgresql://ilham:1234110.137.120.251/totalindo'
Mudah bukan ?
Dengan kata lain pusat-lah yang memba
a database outlet, sedangkan outlet
tidak mendapat hak akses apapun di database pusat.
Lalu bagaimana host pusat mengakses host outlet ?
BAB 8.
75
di outlet. Dengan VPN ini terbentuk 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 OpenVPN. Untuk pemasangan keduanya silahkan
ba
a url berikut ini:
http://jabber.rab.
o.id/os/konfigurasi-openvpn
Apakah OpenVPN dapat bekerja di Windows mengingat masih banyak outlet
yang menggunakan sistem operasi ini ?
Ya, untungnya OpenVPN tersedia di untuk sistem operasi itu, dan tetap
dapat diatur agar otomatis aktif saat komputer dihidupkan.
Baik di pusat maupun di outlet jalankan perintah ini untuk mengetahi IP
VPN masing-masing:
1
tun0
if onfig
tun0
Link
e n a p : UNSPEC
HWaddr
00000000000000000000000000000000
3
inet
addr : 1 0 . 8 . 0 . 6
Pt P : 1 0 . 8 . 0 . 5
Mask
:255.255.255.255
4
MTU
Metri : 1
RX p a k e t s : 0
errors :0
dropped : 0
overruns :0
errors :0
dropped : 0
overruns :0
frame : 0
6
TX p a
k e t s : 6
arrier :0
o l li s i on s :0
RX b y t e s : 0
txqueuelen :100
(0.0
B)
TX b y t e s : 9 6 3
( 9 6 3 . 0 B)
/et /openvpn/ipp.txt.
di outlet
sudo
Restarting
servi e
postgresql
PostgreSQL
8.4
8.4
restart
database
server
psql
ilham
10.8.0.6
totalindo
BAB 8.
76
1
2
reate table
id
produk (
primary key
not null unique
float not null
serial
nama name
harga
) ;
INSERT INTO
INSERT INTO
INSERT INTO
SELECT
SELECT
SELECT
p r o d u k ( nama , h a r g a )
,10500;
p r o d u k ( nama , h a r g a )
,9250;
p r o d u k ( nama , h a r g a )
,14300;
' Jeruk
Pontianak '
' Salak
Pondoh '
re ord pusat
diba a.
re ord outlet
diba a.
1
2
import
from
from
from
elixir
metadata
3
4
5
import
as
s q l a l h e m y . orm
sa
Entity ,
using_options ,
import
import
s q l a l h e m y . s hema
s oped_session ,
setup_all ,
sessionmaker
ThreadLo alMetaData
6
7
BAB 8.
77
9
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
21
lass
ProdukS ( E n t i t y ) :
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 ' ,
m e t a d a t a=ms ,
22
23
24
lass
a u t o l o a d=True ,
s e s s i o n=s s )
ProdukT ( E n t i t y ) :
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 ' ,
m e t a d a t a=mt ,
a u t o l o a d=True ,
s e s s i o n=s t )
25
26
27
28
setup_all ()
29
30
31
32
all_ps =
for
33
in
print
try
print
ex
ept
print
ps
ProdukS . q u e r y . a l l ( ) :
ps . id ,
p s . nama ,
34
p t = ProdukT . q u e r y . f i l t e r _ b y ( i d=p s . i d ) . o n e ( )
35
36
s a . orm . e x . NoResultFound ,
37
38
p t = ProdukT ( i d=p s . i d )
p t . nama = p s . nama
40
pt . harga = ps . harga
41
s t . ommit ( )
42
a l l _ p s . append ( p s . i d )
44
45
46
47
48
49
50
e:
39
43
ps . harga ,
# DELETE
for
pt
if
in
not in
print
ProdukT . q u e r y . a l l ( ) :
pt . i d
pt . id ,
pt . d e l e t e ( )
s t .
ommit ( )
all_ps :
p t . nama ,
pt . harga ,
BAB 8.
8.4
78
Anda sudah memiliki aplikasi yang menggunakan MySQL, dan kini ingin beralih
ke PostgreSQL. Setidaknya dibutuhan penyalinan struktur tabel beserta isinya.
Terlebih dahulu pasanglah driver MySQL.
1
sudo
a p t g e t
install
python mysqldb
1
2
3
4
5
6
import
from
from
from
import
as
sa
import
import
s q l a l
h e m y . s
hema
s q l a l
h e m y . orm
elixir
sys
import
ThreadLo alMetaData
s oped_session ,
7
8
dbs = s a . r e a t e _ e n g i n e ( s y s . a r g v [ 1 )
dbt = s a . r e a t e _ e n g i n e ( s y s . a r g v [ 2 )
sessionmaker
# sour
e
# target
10
dbs . o n n e t ( )
11
dbt . 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
metadata_s = m e t a d a t a
15
metadata_t = T h r e a d L o a l M e t a D a t a ( )
16
metadata_s . b i n d = d b s
17
metadata_t . b i n d = d b t
18
for
19
20
21
tablename
lass
in
dbs . table_names ( ) :
Sour e ( Entity ) :
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=True ,
22
m e t a d a t a=metadata_s , s e s s i o n=s e s s i o n _ s )
23
24
setup_all ()
25
lass
26
27
28
29
30
Target ( Entity ) :
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 ,
for
m e t a d a t a=metadata_t , s e s s i o n=s e s s i o n _ t )
olumn
in
S o u r e . mapper . o l u m n s :
h a s _ f i e l d ( olumn . name ,
31
not
32
r e q u i r e d=
33
34
35
36
olumn . t y p e ,
p r i m a r y _ k e y= olumn . primary_key ,
s e t u p _ a l l ( True )
olumn . n u l l a b l e ,
BAB 8.
79
Database
Paket
PostgreSQL
python-psy opg2
MySQL
python-mysqldb
SQLite
python-sqlite2
Interbase
python-kinterbasdb
MS SQL
python-pymssql
for
37
38
sour e
in
Sour e . query . a l l ( ) :
t a r g e t = Target ( )
39
40
s e s s i o n _ t .
ommit ( )
Contoh penggunaan:
python
d b m i g r a t i o n . py
m y s q l : / / r o o t : 6 7 8 9 l o a l h o s t / sumber
..
dpkg
Suggests :
python s q l a l
h e m y
python s q l a l
h e m y do
,
mysqldb (>= 1 . 2 . 1 p2 2) ,
pysqlite2
1.1.7 2)
(>= 2 . 3 . 0 1 )
|
kinterbasdb
4
python s q l i t e
(>=
3.1.2
..
Perhatikan bagian Suggests.
python p s y o p g 2 ,
p y t h o n (>=
2.5)
python p y s q l i t e 1 . 1
(>= 1 . 0 . 1 5 ) ,
0.3)
(>=
python
python p y m s s q l
python
python
Bab 9
Lintas Sistem
Kita telah membahas mengenai manfaat modularitas dalam fungsi dan modul
dimana sebuah aplikasi disusun bagaikan sebuah lego. Jika keseluruhan sistem
semakin kompleks maka hindari konsep pemaksaan seperti semua harus ditulis dengan Python atau semua harus menggunakan PostgreSQL. Kali ini kita
oba pahami bagaimana komunikasi antar sistem bisa terjadi tanpa pemaksaan
platform tertentu.
9.1
Command Line
eth0
if
onfig
Link
en ap : Ethernet
inet
addr : 1 9 2 . 1 6 8 . 1 1 . 1 1 1
HWaddr
0 0 : 2 5 : b3 : 7 7 : 3 e : 9 9
B ast : 1 9 2 . 1 6 8 . 1 1 . 2 5 5
Mask : 2 5 5 . 2 5 5 . 2 5 5 . 0
4
UP BROADCAST MULTICAST
RX p a k e t s : 0
TX p a k e t s : 0
MTU: 1 5 0 0
Metri : 1
errors :0
dropped : 0
overruns :0
errors :0
dropped : 0
overruns :0
frame : 0
arrier :0
7
o l li s i on s :0
RX b y t e s : 0
txqueuelen :1000
(0.0
B)
TX b y t e s : 0
(0.0
B)
Interrupt :17
10
11
Link
en ap : Lo al
12
inet
addr : 1 2 7 . 0 . 0 . 1
13
inet6
14
lo
addr :
Loopba
k
Mask : 2 5 5 . 0 . 0 . 0
::1/128
S ope : Host
UP LOOPBACK RUNNING
MTU: 1 6 4 3 6
80
Metri : 1
BAB 9.
81
LINTAS SISTEM
15
RX p a k e t s : 5 6 2
errors :0
dropped : 0
overruns :0
errors :0
dropped : 0
overruns :0
frame : 0
16
TX p a
k e t s : 5 6 2
arrier :0
17
o l li s i on s :0
18
txqueuelen :0
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
Link
en ap : Ethernet
21
wlan0
inet
addr : 1 9 2 . 1 6 8 . 1 . 4
22
inet6
HWaddr
0 0 : 1 f : 3 : e0 : 6 6 : 5 6
B ast : 1 9 2 . 1 6 8 . 1 . 2 5 5
Mask : 2 5 5 . 2 5 5 . 2 5 5 . 0
addr :
fe80 : : 2 1 f : 3 f f : f e e 0 :6656/64
S ope :
Link
23
MTU: 1 5 0 0
Metri
: 1
24
RX p a k e t s : 3 2 1 9
errors :0
dropped : 0
overruns :0
errors :0
dropped : 0
overruns :0
frame : 0
25
TX p a
k e t s : 3 6 0 8
arrier :0
26
o l li s i on s :0
27
txqueuelen :1000
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 s
ript Python dan mengolah hasilnya ? Gunakan modul
ommands. Buatlah netdev.py berikut ini.
1
2
3
4
5
6
7
8
9
10
import
import
def
for
netdev ( ) :
r = {}
line
() :
line
in
= line . strip ()
mat h = r e . o m p i l e ( ' ( . * ) L i n k
if
en ap ( . * ) ' ) . s e a r h (
line )
mat
h :
d e v i
e = mat
h . g r o u p ( 1 ) . s t r i p ( )
11
r [ devi e
12
= {}
( . * ) ' ) . sear
h ( l i n e
13
14
15
16
if
ontinue
mat
h :
r [ d e v i
e [ ' addr '
mat h = r e . o m p i l e ( ' i n e t
= mat
h . g r o u p ( 1 )
addr : ( . * ) ' ) . s e a r
h ( l i n e )
BAB 9.
if
return
17
18
19
20
21
22
23
if
82
LINTAS SISTEM
mat
h :
r [ devi
e [ ' ip '
= mat h . g r o u p ( 1 ) . s p l i t ( ) [ 0
__name__ ==
'__main__ ' :
nd = n e t d e v ( )
for
24
25
in
print
dev
nd :
dev ,
nd [ d e v
Jalankan.
1
wlan0
python
lo
eth0
n e t d e v . py
{ ' ip ' :
{ ' ip ' :
'192.168.1.4 ' ,
' 0 0 : 1 f : 3 : e0 : 6 6 : 5 6 ' }
'127.0.0.1 '}
{ ' ip ' :
'192.168.11.111 ' ,
' 0 0 : 2 5 : b3 : 7 7 : 3 e
:99 '}
Lintas sistem yang menggunakan
ommand line ini tergolong lokal, artinya
netdev.py harus berada di komputer yang sama dengan if
ong.
9.2
File
File bisa digunakan sebagai sarana pemersatu input dan output. Misalkan Anda sudah membuat sebuah daemon yang dapat menerima dan mengirim SMS.
Daemon ini pengendali modem.
BAB 9.
9.3
83
LINTAS SISTEM
Database
Pelanggan Anda telah memiliki sebuah sistem pengisian pulsa dimana terdapat
fungsi yang berkaitan dengan GSM modem. Fungsi yang dimaksud adalah yang
berkaitan dengan SMS gateway yaitu mengirim dan menerima SMS.
Pelanggan ini telah membuat sistemnya menggunakan Borland Delphi (bahasa Pas
al) dan menggunakan database MySQL. Ia mengeluh pada Anda selaku developer outsour
ing dimana komponen SMS gateway yang dibangunnya tidak stabil. Di sisi lain Anda telah membuat SMS gateway yang ditulis
dengan bahasa Python dan database PostgreSQL. Tidak seperti yang dimiliki
pelanggan tersebut, SMS gateway yang Anda buat sangat stabil dan telah teruji
bertahun-tahun. Masalah penyatuan semakin bertambah dimana SMS gateway
Anda berada di sistem operasi Linux, sementara pelanggan Anda menggunakan
Mi
rosoft Windows.
Langkah apa yang diambil untuk membuat SMS gateway-nya stabil ? Anda belajar Borland Delphi untuk menerjemahkan algoritma Python ?
Atau
memaksa pelanggan Anda itu untuk belajar Python dan membangun ulang
sistem pengisian pulsanya ?
Langkah yang bijaksana tentu tidak keduanya, karena porsi tidak seimbang
yang mengakibatkan penyatuan menjadi sangat lama. Solusi sederhana adalah
menggunakan database sebagai perantara. Mintalah padanya untuk menyediakan sebuah komputer lagi untuk SMS gateway Anda, sebut saja server SMS
gateway. Server ini terhubung melalui LAN (lo
al area network) dengan server
pengisian pulsa yang berbasis Windows tadi.
Tanpa perubahan ? Tentu saja ada.
Ran
angan SMS gateway yang Anda buat harus dapat mengirim SMS hanya
dengan menggunakan perintah INSERT. Contoh:
INSERT INTO
im . a n t r i a n ( p e n e r i m a ,
+628177654321 ' ,
' Selamat
pesan )
bergabung ' ;
SELECT
'
Ia perlu mengubah
Biasanya
Delphi terdapat dua koneksi database, yaitu ke MySQL yang ada di lo
alhost
Mi
rosoft Windows, dan ke PostgreSQL yang ada di remote host Linux.
Lalu bagaimana untuk memba
a SMS yang masuk ? Kembali, Anda diminta
untuk menyimpan SMS yang masuk ke dalam sebuah tabel, katakanlah bernama
inbox. Selanjutnya pelanggan Anda dapat memba
anya menggunakan perintah
SELECT pada Borland Delphi.
1
SELECT
Mudah bukan ? Lebih lanjut mengenai SMS gateway bisa lihat halaman115.
BAB 9.
84
LINTAS SISTEM
Lintas sistem ini tergolong bisa beda komputer, karena baik PostgreSQL
maupun MySQL dapat diakses melalui jalur network.
9.4
XMLRPC
Salah
satunya adalah aspek tanggung jawab, atau biasa disebut aspek keamanan (se
urity). Misalkan dalam sistem perbankan. Sistem utama sebuah bank dibangun oleh PT Software Aman Banget (SAB). Namanya juga sistem utama, ia
memuat data penting nasabah serta data yang menyangkut sistem.
Suatu saat bank ini ingin go Internet dimana nasabah dapat melakukan
transaksi melalui browser Firefox. Berarti dibutuhkan web developer dan dipilihlah PT Web Perkasa (WP) untuk mengembangkannya.
Karena mengem-
bangkan Internet banking, berarti ada proses login untuk nasabah. Ini berarti
ada algoritma pemeriksaan username dan password.
menjadi masalah karena username dan password web bisa berada di web server
yang dibangun oleh WP.
Tibalah saatnya nasabah ingin melihat mutasi transaksinya. Apakah WP
melakukan SELECT tabel ke sistem utama bank tersebut yang dibangun oleh
SAB ?
Mayoritas jawabannya tidak. Mengapa ?
SELECT berarti kita bi
ara koneksi ke database. Itu artinya WP mengetahui username dan password untuk login ke database sistem utama.
Kalau
sudah begitu maka WP bisa melihat-lihat data nasabah lainnya, bahkan melihat tabel-tabel yang menyangkut sistem. Jelas ini sudah terlalu jauh dan bisa
menimbulkan hal-hal yang tak perlu.
Untuk menghindari koneksi database ke sistem utama, maka digunakanlah
XMLRPC sebagai perantaranya. Makanan apakah ini ?
XMLRPC adalah XML Remote Pro
edure Call, yaitu sebuah bahasa pertukaran data yang ditulis dalam format XML. Kita dapat memandang RPC
sebagai pemanggilan fungsi yang memiliki nilai masukan (input parameter) dan
nilai keluaran (output / return value). Sebagaimana fungsi sederhana ini.
1
2
def
tambah ( a ,
return
b) :
a + b
web servi e
BAB 9.
85
LINTAS SISTEM
1
2
3
4
5
6
from
import
SimpleXMLRPCServer
lass
sqlal hemy
as
sa
import
SimpleXMLRPCServer
S e r v e r ( SimpleXMLRPCServer ) :
a l l o w _ r e u s e _ a d d r e s s = True
def
8
9
10
11
verify_request ( self ,
request ,
lient_address ) :
print
return
in
12
13
14
15
16
def
r e s p ( ode ,
return
msg ) :
ode ,
msg }
17
18
19
20
21
lass
def
Agent :
22
_dispat h ( s e l f ,
print
try
ex
ept
return
return
method ,
method ,
params =() ) :
params
23
fun = g e t a t t r ( s e l f ,
24
AttributeError :
25
r e s p ( 1 ,
' F u n g s i %s
tidak
dikenal ' %
method )
f u n ( * params )
26
27
28
29
def
export_mutasi ( s e l f ,
s q l = "SELECT
p) :
t g l : : date ,
ket ,
nominal ,
saldo
" +
\
30
31
32
"ORDER BY i d "
33
34
q = db . e x e u t e ( s q l )
35
m =
36
37
for
[
r
in
" + \
q:
m. append ( [ s t r ( r . t g l ) ,
saldo )
r . ket ,
r . nominal ,
r.
BAB 9.
86
LINTAS SISTEM
38
r = r e s p ( 0 , 'OK ' )
39
return
40
41
42
43
44
url =
45
db = s a . r e a t e _ e n g i n e ( u r l )
46
47
port = 9303
48
49
50
51
52
s e r v e r . r e g i s t e r _ i n s t a n
e ( Agent ( ) )
'HTTP XMLRPC s e r v e r
port ' ,
port
server . serve_forever ()
Jalankan.
HTTP XMLRPC s e r v e r
python
s e r v e r b a n k . py
port
9303
Proses seolah hang, tapi sebenarnya ia sedang menunggu permintaan (request) dari XMLRPC
lient. Port 9303 hanya
ontoh saja dimana Anda bisa
mengganti dengan nilai lainnya.
1
2
import
xmlrp lib
url =
remote = x m l r p l i b . ServerProxy ( u r l )
1,
8
9
10
if
r [ ' k o d e ' == 0 :
for
12
14
15
r = remote . mutasi ( d )
11
13
else
tgl ,
ket ,
tgl ,
nominal ,
saldo
ket . l j u s t (15) ,
in
s t r ( i n t ( nominal ) ) . r j u s t ( 1 0 ) ,
s t r ( int ( saldo ) ) . r j u s t (10)
python
l i e n t b a n k . py
3000000
3000000
2010 10 22 BON
200000
2800000
BAB 9.
87
LINTAS SISTEM
Cermati baik-baik konsepnya. Juga perhatikan tipe data di
tionary dan list
yang digunakan sebagai nilai keluaran (return value) dari fungsi mutasi.
Carilah.
Lalu
<?php
in
lude
array
$params = new
xmlrp val
7
9
xmlrp val
12
$ = new
13
$ r = $ >s e n d ( $ f ) ;
14
$v = $ r >v a l u e ( ) ;
17
11
16
) ,
10
15
(1 ,
xmlrp val
xmlrp val
if
18
( $ r >f a u l t C o d e ( ) )
print
else
if
forea
h
array
( $params ) ) ;
9303) ;
$r >f a u l t S t r i n g ( ) ;
$ r e s p = $ r >s a l a r v a l ( ) ;
19
20
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
print
str_pad
str_pad
str_pad
else
print
$tgl . "
27
28
29
30
".
( $ket ,
20) . "
( $nominal ,
( $saldo ,
".
10) . "
".
1 0 ) . " \n" ;
31
32
33
34
35
?>
as
$ i=>$m)
BAB 9.
88
LINTAS SISTEM
Karena s
ript ini akan kita jalankan sebagai
ommand line, maka pasang
dulu paket terkait.
1
sudo
a p t g e t
install
php5 l i
Lalu jalankan.
1
php
l i e n t _ b a n k . php
3000000
3000000
2010 10 22 BON
200000
2800000
9.4.2 Drupal
Drupal
1 juga ditulis dengan PHP. Ia sudah memuat fun tion xmlrp , sehingga
Anda tidak perlu memasang modul tambahan. Cara penulisannya juga lebih
mudah. Contoh berikut ini untuk Drupal 6.
Buatlah le sites/all/modules/pegawai/pegawai.module berikut.
Listing 9.5: pegawai.module
1
<?php
fun tion
pegawai_menu ( )
array
$items =
() ;
' page
a l l b a k ' =>
' page
a r g u m e n t s ' =>
' a ess
array
array
a l l b a k ' =>
(2 ,
3,
4) ,
10
) ;
11
12
return
$items ;
13
14
fun tion
15
$url =
16
$p =
17
pegawai_trx ( $pid ,
array
20
21
if
23
$ =
25
26
intval
( $pid ) ,
22
24
$akhir )
18
19
$awal ,
return
$p ) ;
ada
data ' ) ;
forea h
$tgl = $f [ 0 ;
1 http://drupal.org
as
$ i=>$ f )
BAB 9.
89
LINTAS SISTEM
27
$ket = $f [ 1 ;
28
$nominal = $ f [ 2 ;
29
$saldo = $f [ 3 ;
30
.=
31
.=
32
.=
'<t d
.=
'<t d
</td> ' ;
34
35
.=
36
return
37
38
?>
$ ;
name = P e g a w a i
d e s r i p t i o n = Data
ore = 6. x
v e r s i o n = " 6 . x 1.0"
pegawai
pegawai/trx/1/20101022/20101023
Bab 10
Pengemasan
10.1
Paket Debian
Pada bab sebelumnya kita sudah membuat modul uang.py. Agar modul ini dapat digunakan oleh user lainnya maka diletakkanlah di direktori /usr/lo
al/lib/python2.6/distpa
kages. Proses
opy modul seperti ini memang sudah mudah, tapi ada lagi
yang lebih memudahkan, yaitu dengan mengemasnya dalam bentuk paket Debian.
Langkah kemudahan yang dimaksud adalah:
1. Tambahkan URL daftar paket dalam sebuah le /et
/apt/sour
es.list.d/
ustom.list
yang berisi
deb http://192.168.0.1/deb ./
2. Perbaharui daftar paket
$ sudo apt-get update
3. Pasang paket dimaksud
$ sudo apt-get install python-uang
Manfaat lain pemaketan adalah mudahnya pemasangan paket lainnya yang
dibutuhkan oleh paket utama, sering disebut sebagai
dependen ies
. Misalkan
sudo
a p t g e t
install
python uang
sana. Juga tidak ada perintah akses database seperti SELECT dkk.
Awalan ini juga meniru dari paket umum lainnya seperti pythonsqlal
hemy, python-psy
opg2, python-serial, dst.
90
BAB 10.
91
PENGEMASAN
sudo
mkdir
ontrol
postinst
get install atau dpkg -i. S
ript ini harus exe
utable yang bisa diset dengan
hmod 755.
prerm
get remove atau dpkg -r. S ript ini juga harus exe utable.
onles
berisi daftar nama le kongurasi yang digunakan paket ini. Misalnya
berisi /et /uang. onf. File kongurasi ini berisi format negara yang di-
Dengan didaftarkannya /et
/uang.
onf di dalam
onles, maka terhindar dari penibanan (timpa / overwrite) saat upgrade berlangsung. Misalkan kini python-uang versi 0.1. Kemudian dibuatlah versi 0.2 yang juga
memuat /et
/uang.
onf.
Jika
di dalam
sudah terpasang
apa-apa pada /et
/uang.
onf maka apt-get install tidak akan melakukan
timpa pada /et
/uang.
onf yang
Anda sudah mengganti isi /et
/uang.
onf terpasang dengan de_DE.ISO8859-1. Dengan begitu kita terhindar dari mengubah ulang kongurasi.
Mudah-mudahan paham maksudnya.
Mulailah membuat le python-uang/DEBIAN/
ontrol.
Listing 10.1: DEBIAN/
ontrol
1
Pa kage :
Priority :
python uang
Se tion :
Maintainer :
Ar hite ture :
Version :
0.1
Depends :
python e n t r a l
Python V e r s i o n :
Des ription :
optional
python
Owo S u g i a n a <s u g i a n a r a b .
o . i d >
all
(>=
0.6.7)
all
Format
uang
BAB 10.
sudo
92
PENGEMASAN
/ usr/ l o
a l / sr
mkdir
uang / s i t e
Perhatikanlah direktori setelah /usr/lo
al/sr
/python-uang. Semua direktori tersebut nantinya akan dipasang di root dire
tory ( / ), ke
uali direktori
DEBIAN.
Lalu mengapa menggunakan /usr/share ? Padahal sebelumnya kita meletakkan uang.py di /usr/lo
al ? Direktori /usr/lo
al yang kita gunakan sebelumnya bermakna bahwa uang.py belum menjadi bagian dari paket Debian. Bila
sudah menjadi bagian dari paket Debian, maka diletakkan di /usr/share. Begitulah ketentuan umumnya.
1
sudo
/ 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 / uang . py
pa
kages/
Karena akan menggunakan /et
/user.
onf, lakukan perubahan pada uang.py
menjadi berikut ini.
Listing 10.2: usr/share/py
entral/python-uang/site-pa
kages/uang.py
1
2
3
import
from
lo ale
ConfigParser
import
ConfigParser
onf = ConfigParser ()
6
7
l o a l e . s e t l o a l e ( l o a l e . LC_ALL,
lo
ale '))
8
9
10
11
12
13
14
def
if
17
19
23
24
25
p e
a h a n=None ) :
None :
t y p e ( n i l a i ) == t y p e ( 0 ) :
:
p e a h a n = DECIMAL
18
22
is
pe ahan = 0
16
21
pe ahan
if
else
return
15
20
uang ( n i l a i ,
if
l o a l e . f o r m a t ( '%%.%d f ' % p e a h a n ,
__name__ ==
'__main__ ' :
n = 10000.5
print
print
print
uang ( n )
uang ( i n t ( n ) )
uang ( n , 3 )
nilai ,
True )
BAB 10.
93
PENGEMASAN
Buat direktori et
.
1
sudo
mkdir
python uang / e t
[ default
l o a l e = id_ID . UTF8
de
imal = 2
Lalu buat python-uang/DEBIAN/
onles berisi satu baris berikut.
Listing 10.4: DEBIAN/
onles
/ e t
/ uang .
o n f
Kemudian buat python-uang/DEBIAN/postinst yang berisi perintah untuk
mendaftarkan uang.py agar dikenal sebagai modul.
Listing 10.5: DEBIAN/postinst
#!/ b i n / s h
py entral
pkginstall
python uang
Juga python-uang/DEBIAN/prerm.
Listing 10.6: DEBIAN/prerm
1
#!/ b i n / s h
py entral
pkgremove
python uang
sudo
hmod 7 5 5
sudo
hmod 7 5 5
sudo
hown
root . root
python uang
python uang /
find
python uang
python uang / u s r
python uang / u s r / s h a r e
10
python uang / u s r / s h a r e / p y e n t r a l
11
12
p a k a g e s
BAB 10.
13
94
PENGEMASAN
p a k a g e s
/ uang . py
14
python uang / e t
15
dpkgdeb :
sudo
dpkgdeb
dpkgdeb :
b u i l d
peringatan :
ontains
python uang
u s e r d e f i n e d
membuat
paket
field
di
dalam
` . / python
dpkgdeb :
peringatan :
ontrol
ignoring
warnings
about
the
file (s)
Perhatikan ada titik diakhirnya yang berarti letakkan di
urrent dire
tory.
Abaikan saja peringatan itu. Karena Python-Version memang bukan standar
Debian, tapi digunakan oleh py
entral. Sampai di sini pembuatan paket selesai.
Kini telah terbentuk python-uang_0.1_all.deb yang siap dipasang.
1
Memilih
sudo
dpkg
( S e d a n g memba a
S e d a n g membuka
paket
telah
Sedang
Pro essing
basis
yang
data
sebelumnya
...213458
tidak
berkas
dan
dipilih .
direktori
terpasang . )
_ a l l . deb )
5
paket
python uang
( dari
python uang_0 . 1
...
menyetel
python uang
triggers
for
(0.1)
...
python e n t r a l
...
Untuk menghindari keran
uan karena ada dua modul 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 / uang . py
/tmp
Lalu ujilah di modus interaktif.
Python
python
[GCC 4 . 4 . 3
Type
2.6.5
( r265 : 7 9 0 6 3 ,
on
Apr
16
2010 ,
13:09:56)
linux2
" redits"
or
for
more
information .
5
>>> f r o m
>>> uang ( 1 0 0 0 0 )
uang
import
uang
'10.000 '
Ujian terakhir hapuslah paket ini untuk memastikan s
ript DEBIAN/prerm
berfungsi dengan baik.
a p t g e t
remove
python uang
S e d a n g memba a
sudo
daftar
paket . . .
Selesai
BAB 10.
Membangun pohon
Memba a
Paket
6
7
ketergantungan
informasi
berikut
yang
tersedia . . .
Selesai
akan DIHAPUS :
python uang
0
dimutakhirkan ,
tidak
95
PENGEMASAN
Setelah
akan
operasi
baru
terinstal ,
akan
dihapus
dan
192
dimutakhirkan .
ini ,
0B r u a n g
kosong
harddisk
akan
digunakan .
9
10
Anda
ingin
telah
11
melanjutkan
( S e d a n g memba a
[ Y/ t ?
data
...213460
berkas
dan
direktori
terpasang . )
S e d a n g membuang
10.2
basis
python uang
...
Debian Repository
Kini saatnya membuat repository agar bisa di-apt-get dari komputer lain. Pasanglah
paket yang dibutuhkan untuk memba
a le-le *.deb.
1
sudo
a p t g e t
install
dpkgd e v
Letakkan paketnya di tempat yang sudah ditentukan web server Apa
he.
1
sudo
mkdir
sudo
/ v a r /www/ deb
/ v a r /www
/ deb
Lalu buatlah /var/www/deb/update-list.sh. File ini digunakan untuk memperbaharui daftar paket yang tersedia.
Listing 10.7: updatelist.sh
1
rm
dpkgs a n p a k a g e s
Pa kages . gz
gzip
b e s t
a r h
all
>/d e v / n u l l > P a k a g e s
Pa kages
sudo
/ v a r /www/ deb
sh
u p d a t e l i s t . sh
Akan terbentuk le Pa
kages.gz. File inilah yang akan diba
a saat apt-get
update.
Selanjutnya kita uji repository ini dengan membuat le /et
/apt/sour
es.list.d/
ustom.list.
Listing 10.8: /et
/apt/sour
es.list.d/
ustom.list
1
deb
h t t p : / / 1 9 2 . 1 6 8 . 0 . 1 / deb
sudo
a p t g e t
update
./
BAB 10.
96
PENGEMASAN
sudo
10.3
a p t g e t
install
python uang
Remastering Ubuntu
sudo
a p t g e t
install
s q u a s h f s t o o l s
mudah
mkisofs
LABEL=" BlankOn
"
6 SOHO"
mkdir
./ onf
mount
rsyn
'
/tmp / drom /
drom /
5
mount
loop
squashfs
squashfs
/tmp / drom / a s p e r / f i l e s y s t e m .
/tmp / r o o t
umount /tmp / r o o t
/tmp / r o o t
/ et / r e s o l v . onf
hroot
root
mount
hroot
root
mount
hroot
root
rm
hroot
root
a p t g e t
hroot
root
umount
sys
hroot
root
umount
pro
root / et
t
t
pro
sysfs
root / et
/ r e s o l v .
onf
lean
none
none
/ pro
/sys
BAB 10.
97
PENGEMASAN
root
rm
drom / p r o g r a m s
11
hmod +w drom / a s p e r / f i l e s y s t e m . m a n i f e s t
12
hroot
r f
rm
/tmp / *
hroot
10
root
r f
dpkgq u e r y
/ root / . bash_history
W s h o w f o r m a t = ' $ { P a k a g e }
${
drom / a s p e r / f i l e s y s t e m . m a n i f e s t
drom / 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
sed
ie
' / u b i q u i t y /d '
drom / a s p e r / f i l e s y s t e m . m a n i f e s t
desktop
rm
awal=` date `
5
6
7
8
9
10
11
./ onf
drom / a s p e r / f i l e s y s t e m . s q u a s h f s
mksquashfs
root
drom / a s p e r / f i l e s y s t e m . s q u a s h f s
drom
find
mkisofs
e
ho
e
ho
e
ho
e
ho
at
" Awal
$awal "
" Akhir
" ` date `
" Sour e
" ` ls
" Target
" ` ls
l
l
$SOURCE |
awk
awk
. . / $TARGET |
$5 } ' `
$5 } ' `
sudo
s h 1 e x t r a t . s h
Dia akan mengekstrak le iso menjadi root dire
tory. Kemudian jalankan
s
ript kedua:
1
sudo
s h 2 h r o o t . s h
S
ript ini untuk masuk ke sistem Linux yang lain, yaitu root dire
tory tadi.
1
r o o t l a p t o p :/#
Di sini Anda bisa melakukan perubahan sebagaimana biasa. Contoh:
r o o t l a p t o p :/#
r o o t l a p t o p :/#
wget
r o o t l a p t o p :/#
a p t g e t
update
r o o t l a p t o p :/#
a p t g e t
install
server
squid
/ e t
/ apt / s o u r
e s . l i s t . d
http : / / debian . rab .
o . i d / rab . l i s t
internet
s h a r i n g
dh p3
vim
Kalau sudah selesai keluarlah dari
hroot dengan menekan Ctrl-D atau ketik
exit:
BAB 10.
98
PENGEMASAN
r o o t l a p t o p :/#
exit
exit
sugianalaptop :~ $
Root dire
tory kini telah berisi aplikasi yang dibutuhkan. Saatnya membuat
iso dengan menjalankan s
ript ketiga.
s u d o 3 p a
k . s h
Tunggu sekitar 5 menit.
Parallel
mksquashfs :
Creating
4.0
squashfs ,
3
Using
filesystem
blo
k
size
on
pro essors
drom / a s p e r / f i l e s y s t e m .
131072.
[==========================|
15063/84258
17%
Terakhir s
ript akan memberikan informasi ukuran iso yang dihasilkan berikut
iso aslinya.
1
357433
Awal
Sen Agu
extents
written
Akhir
Sen Agu 2
Sour e
731869184
Target
732022784
( 6 9 8 MB)
0 9 : 4 5 : 3 9 WIT 2 0 1 0
0 9 : 5 0 : 5 2 WIT 2 0 1 0
Jika media yang Anda tuju nanti adalah CDROM, pastikan ukurannya
dibawah 700MB. Lebih mudahnya bandingkan dengan ukuran ISO aslinya. Pada
ontoh di atas terlihat ukuran Target masih lebih besar dari Sour
e. Jika
masih terlalu besar jalankan lagi s
ript kedua untuk menghapus paket yang tak
perlu.
1
sudo
s h 2 h r o o t . s h
sudo
s h 3 p a k . s h
File ISO yang dihasilkan bisa Anda
oba terlebih dahulu di VirtualBox .
Anda juga bisa memasangnya di ashdisk menggunakan usb-
reator-gtk. Jika
sudah yakin barulah membakarnya (burn) ke CD-ROM.
1 virtualbox.org
Bab 11
Berbeda
sudo
a p t g e t
install
python q t 4
sudo
a p t g e t
install
q t 4 do h t m l
Seperti biasa, mulailah dari yang sederhana, yaitu membuat aplikasi Hello
world dalam le hello.py.
1
2
3
4
5
6
7
8
import
from
from
lass
def
PyQt4
import
PyQt4 . QtGui
Qt
import
FormUtama ( QMainWindow) :
__init__ ( s e l f ) :
QMainWindow . __init__ ( s e l f )
s e l f . setWindowTitle ( ' Hello
9
10
99
world ' )
BAB 11.
100
11
app = Qt . Q A p p l i a t i o n ( s y s . a r g v )
12
fm = FormUtama ( )
13
14
fm . show ( )
#app . exe
_ ( )
Butuh tampilan penuh ? Gantilah
fm.show()
menjadi
fm.showMaximized()
11.1
Orientasi Objek
Di sini teknik pemrograman semakin terstruktur dimana pemrograman berorientasi objek (Obje t Oriented Programming / OOP) diterapkan.
Mari kita
lass FormUtama(QMainWindow):
itu artinya FormUtama merupakan turunan (inheritan
e) dari
lass QMainWindow.
juga dimiliki oleh
lass FormUtama. Bahasa lainnya FormUtama mewarisi sifat
QMainWindow.
Selanjutnya ada fungsi __init__().
yang dijalankan saat pembentukan sehingga disebut sebagai
onstru
tor. Saat
pembentukan ? Ya, perhatikan baris 12
fm = FormUtama()
Itu adalah pembentukan variabel fm yang bertipe FormUtama. Disinilah fungsi
__init__() dipanggil.
BAB 11.
101
QMainWindow.__init__(self)
Fungsi __init__() yang dimiliki QMainWindow perlu dipanggil lagi. Mengapa
? Karena FormUtama mendenisikan ulang fungsi __init__().
Lalu apa itu self ? self adalah variabel 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 pernah mendenisikan fungsi show() di dalam
lass FormUtama. Kenyataannya variabel fm memiliki fungsi show(). Darimana ia berasal
? Seperti dijelaskan tadi, FormUtama mewarisi sifat QMainWindow, jadi fungsi
show() itu berasal darinya. Fungsi ini digunakan untuk menampilkan form.
Lalu apa itu form ? Kotak Hello world itulah yang disebut form seperti pada
gambar 11.1.
Sekarang lihat baris 11
app.exe
_()
tanpa loop, alur langsung berakhir. Form bisa banyak, tapi QAppli
ation
ukup
satu saja.
Pahami lagi baik-baik konsep OOP ini agar semakin mudah untuk membuat
aplikasi yang lebih besar.
11.2
Daftar Pegawai
pegawai, terinspirasi dari tabel pegawai yang pernah kita buat. Namun disini
belum menggunakan database, semuanya tersimpan sementara saja.
BAB 11.
1
2
3
4
5
6
7
8
9
import
from
from
from
lass
def
102
PyQt4
import
PyQt4 . QtGui
PyQt4 . QtCore
Qt
import *
import
QDate ,
SIGNAL
FormUtama ( QMainWindow) :
__init__ ( s e l f ) :
QMainWindow . __init__ ( s e l f )
s e l f . s e t W i n d o w T i t l e ( ' Pegawai ' )
10
s e l f . r e s i z e (550 ,550)
11
s e l f . l a b e l N a m a = QLabel ( s e l f )
12
s e l f . l a b e l A l a m a t = QLabel ( s e l f )
13
s e l f . l a b e l T g l L a h i r = QLabel ( s e l f )
14
sel f . labelJenis
15
s e l f . editNama = 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 = QTextEdit ( s e l f )
17
s e l f . e d i t T g l L a h i r = QDateEdit ( s e l f )
18
s e l f . e d i t J e n i s = QComboBox ( s e l f )
19
s e l f . b u t t o n S i m p a n = QPushButton ( s e l f )
20
s e l f . listPegawai
21
22
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 ( ' Tgl
24
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 ( ' ddMM
yyyy ' )
26
s e l f . e d i t T g l L a h i r . s e t D a t e ( QDate ( 2 0 1 0 , 1 0 , 2 3 ) )
27
28
29
s e l f . l i s t P e g a w a i . setColumnCount ( 5 )
30
s e l f . listPegawai . setHorizontalHeaderLabels ( [
31
= QLabel ( s e l f )
= QTableWidget ( s e l f )
Lahir ' )
Kelamin ' )
32
s e l f . l i s t P e g a w a i . setColumnWidth ( 0 , 2 0 )
33
s e l f . l i s t P e g a w a i . setColumnWidth ( 1 , 1 5 0 )
34
s e l f . editNama . r e s i z e ( 2 0 0 , 3 0 )
35
36
37
s e l f . l a b e l N a m a . move ( 1 0 , 1 0 )
38
s e l f . l a b e l A l a m a t . move ( 1 0 , 4 0 )
39
s e l f . l a b e l T g l L a h i r . move ( 1 0 , 1 4 0 )
40
s e l f . l a b e l J e n i s . move ( 1 0 , 1 7 0 )
41
s e l f . editNama . move ( 1 0 0 , 1 0 )
42
s e l f . e d i t A l a m a t . move ( 1 0 0 , 4 0 )
43
s e l f . e d i t T g l L a h i r . move ( 1 0 0 , 1 4 0 )
44
s e l f . e d i t J e n i s . move ( 1 0 0 , 1 7 0 )
BAB 11.
45
s e l f . b u t t o n S i m p a n . move ( 1 0 0 , 2 0 0 )
46
s e l f . l i s t P e g a w a i . move ( 1 0 , 3 0 0 )
47
s e l f .
o n n e
t ( s e l f . buttonSimpan ,
') ,
48
49
50
def
103
SIGNAL ( ' l i k e d ( )
s e l f . simpan )
simpan ( s e l f ) :
row =
s e l f . l i s t P e g a w a i . rowCount ( )
51
p i d = row+1
52
s e l f . l i s t P e g a w a i . setRowCount ( 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 ( row , 0 , QTableWidgetItem (
54
s e l f . l i s t P e g a w a i . s e t I t e m ( row , 1 , QTableWidgetItem (
55
s e l f . l i s t P e g a w a i . s e t I t e m ( row , 2 , QTableWidgetItem (
56
s e l f . l i s t P e g a w a i . s e t I t e m ( row , 3 , QTableWidgetItem (
57
s e l f . l i s t P e g a w a i . s e t I t e m ( row , 4 , QTableWidgetItem (
58
s e l f . editNama . l e a r ( )
59
s e l f . editAlamat . l e a r ( )
60
s e l f . e d i t J e n i s . setCurrentIndex (0)
61
s e l f . editNama . s e t F o u s ( )
s t r ( pid ) ) )
s e l f . editNama . t e x t ( ) ) )
s e l f . editAlamat . toPlainText ( ) ) )
s e l f . editTglLahir . text () ) )
s e l f . e d i t J e n i s .
urrentText ( ) ) )
62
63
64
app = Qt . Q A p p l i a t i o n ( s y s . a r g v )
65
fm = FormUtama ( )
66
fm . show ( )
67
app . exe
_ ( )
Bagaimana, panjang bukan ?
Ya,
ontoh kali ini menyertakan
lass yang kerap digunakan.
Berikut ini
QLabel
QLineEdit
QTextEdit
QDateEdit
QComboBox
QPushButton
QTableWidget
BAB 11.
104
BAB 11.
105
Dari sour
e tersebut dan menganalisa tampilan form, rasanya Anda bisa memahami
ara penggunaan
lass di atas.
Untuk mengetahui
lass lainnya beserta fungsi yang ada di dalamnya Anda bisa lihat di /usr/share/qt4/do
/html/
lasses.html. Gunakanlah browser untuk melihatnya.
Bab 12
Obje
t Oriented
Programming
Kita membuat fungsi dengan tujuan esiensi sour
e, agar proses-proses yang
sama dapat diwakili dengan memanggil fungsi tertentu. Begitu juga pada pembuatan objek. Mari mulai pada kasus.
Ada sebuah le teks bernama barang.txt dengan isi seperti berikut ini.
Listing 12.1: barang.txt
1
1 Jeruk
2 Mangga
3 Pisang
34
9000
10000
8000
tetap
lebar kolom
data ini ke sebuah tabel di database. Mari mulai mempertimbangkan langkahlangkah yang bisa ditempuh.
Andai saja kita bisa menggunakan split() yang bisa mengubah string menjadi
list, sehingga dengan mudah kolom pertama ada kode barang, kolom kedua
nama barang, dan seterusnya.
Mengapa ?
Perhatikan baris Mangga dimana nilai stok kosong. Ini artinya kolom ketiga
menjadi harga barang. Tentu saja tidak konsisten dengan baris Jeruk dimana
kolom ketiga adalah stok.
memaksa.
Baik, kita ikuti saja petunjuk pembuatnya dimana lebar kolom menjadi
a
uan. Sementara ini kita tidak perlu terlalu jauh bagaimana struktur tabelnya.
Dari sudut pandang Python saja dulu, tipe data apa yang
o
ok untuk mewakili
le ini.
Untuk sementara anggap saja tipe data list yang sesuai karena ini
106
BAB 12.
107
1
2
import
sys
f i l e n a m e = sys . argv [ 1
for
5
6
f = open ( f i l e n a m e )
in
line
f . readlines () :
kode = l i n e [ : 3 . s t r i p ( )
nama = l i n e [ 3 : 3 + 1 0 . s t r i p ( )
stok = l i n e [3+10:3+10+2. s t r i p ( )
harga = l i n e [3+10+2:. s t r i p ( )
10
11
[ kode ,
nama ,
stok ,
harga
f . lose ()
Jalankan.
1
[ '1 ' ,
python
b a r a n g 1 . py
[ '2 ' ,
' ' ,
[ '3 ' ,
'7 ' ,
barang . t x t
'34 ' ,
'9000 '
'8000 '
'10000 '
Tahap ini sudah baik, dimana setiap nilai sudah dapat diwakili dalam variabel kode, nama, stok, dan harga. Namun barang1.py masih kurang modular
karena masukannya berupa nama le yang diberikan melalui
ommand line.
12.1
Lebih Terstruktur
1
2
def
for
4
5
6
line
in
f . readlines () :
kode = l i n e [ : 3 . s t r i p ( )
nama = l i n e [ 3 : 3 + 1 0 . s t r i p ( )
stok = l i n e [3+10:3+10+2. s t r i p ( )
harga = l i n e [3+10+2:. s t r i p ( )
10
r o w s . append ( row )
11
f . lose ()
return
12
13
14
15
if
rows
__name__ ==
'__main__ ' :
BAB 12.
import
for
in
print
16
108
sys
17
f i l e n a m e = sys . argv [ 1
18
row
19
barang ( f i l e n a m e ) :
row
Jalankan.
1
[ '1 ' ,
python
b a r a n g 2 . py
[ '2 ' ,
' ' ,
[ '3 ' ,
'7 ' ,
'34 ' ,
barang . t x t
'9000 '
'8000 '
'10000 '
Hasil tetap sama, namun kini s
ript tidak hanya mengandung fungsi tetapi
juga bisa digunakan sebagai modul.
12.2
Lebih Umum
Sekarang aspek generalitas, atau tingkat ke-umum-an fungsi, dimana lebar setiap kolom sudah ditetapkan di dalam fungsi (hard
ode). Bisakah ditingkatkan
generalitasnya ?
Kebutuhannya adalah ada le lain selain barang.txt dengan lebar setiap
kolom berbeda dengan barang.txt, namun sifatnya masih sama yaitu
setiap
1
2
def
for
4
5
6
line
in
for
f . readlines () :
awal = 0
row =
widths ) :
f = open ( f i l e n a m e )
width
field
10
in
widths :
a k h i r = awal + width
= l i n e [ awal : a k h i r . s t r i p ( )
row . append ( f i e l d )
11
awal = a k h i r
12
r o w s . append ( row )
13
f . lose ()
return
14
15
16
17
if
rows
__name__ ==
'__main__ ' :
BAB 12.
import
for
in
print
18
109
sys
19
f i l e n a m e = sys . argv [ 1
20
row
21
f i x t a b l e ( filename ,
[3 ,10 ,2 ,8) :
row
Jalankan.
1
[ '1 ' ,
python
f i x t a b l e . py
[ '2 ' ,
' ' ,
[ '3 ' ,
'7 ' ,
barang . t x t
'34 ' ,
'9000 '
'8000 '
'10000 '
gawai.txt.
Listing 12.5: pegawai.txt
1
2ARIEF SETIADI
ST
1985 08 17L
3CECEP ZAHRUDIN ,
4NITA PANDRIA
1976 09 19P
5ILHAM
1984 11 05L
6MIRANDA
1978 10 01P
1972 05 02L
ST
1972 06 01L
Lalu xpegawai.py.
1
2
3
from
import
fixtable
sys
import
fixtable
f i l e n a m e = sys . argv [ 1
for
6
7
in
print
row
f i x t a b l e ( filename ,
row
Jalankan.
1
[ '1 ' ,
python
f i x p e g a w a i . py
pegawai . t x t
[ '2 ' ,
[ '3 ' ,
'CECEP ZAHRUDIN ,
[ '4 ' ,
[ '5 ' ,
'ILHAM' ,
[ '6 ' ,
'MIRANDA' ,
ST ' ,
'1985 08 17 ' ,
'1972 05 02 ' ,
ST ' ,
'1972 06 01 ' ,
'1976 09 19 ' ,
'1984 11 05 ' ,
'L '
'L '
'L '
'P '
'L '
'1978 10 01 ' ,
'P '
12.3
Tingkat Kerumitan
BAB 12.
110
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 bertipe integer. Maka nilai yang
o
ok untuk
string hampa adalah None, alias objek hampa. Buatlah le FixTableType.py
berikut ini.
1
2
3
4
5
from
def
types
f i x t a b l e ( filename ,
for
8
9
line
for
11
12
in
ftypes ) :
f . readlines () :
width ,
ftype
field
14
field :
= None
f t y p e == I n t T y p e :
16
field
17
= int ( f i e ld )
row . append ( f i e l d )
18
awal = a k h i r
19
r o w s . append ( row )
20
f . lose ()
return
21
22
24
25
26
27
ftypes :
= l i n e [ awal : a k h i r . s t r i p ( )
field
15
in
a k h i r = awal + width
if not
elif
13
23
StringType
awal = 0
row =
10
IntType ,
f = open ( f i l e n a m e )
rows =
import
if
rows
__name__ ==
import
'__main__ ' :
sys
f i l e n a m e = sys . argv [ 1
fields
= [
28
[ 3 , IntType ,
29
[ 1 0 , StringType ,
30
[ 2 , IntType ,
31
[ 8 , IntType
32
BAB 12.
for
33
34
in
print
row
f i x t a b l e ( filename ,
111
fields ) :
row
Jalankan.
1
[1 ,
python
F i x T a b l e T y p e . py
[2 ,
None ,
[3 ,
7,
34 ,
barang . t x t
9000
8000
10000
Perhatikan, tidak ada lagi kutip di kolom pertama, ketiga, dan keempat.
Selanjutnya ada kebutuhan untuk menyimpan kembali data tersebut ke sebuah le sejenis, meski tidak harus ke barang.txt lagi. Fitur semakin bertambah
dimana:
Tipe integer
Bab 13
Kerja Sampingan
Anda diminta membuat sebuah program yang bertugas mengendalikan sebuah
GSM modem. Program ini bersifat daemon yang artinya selalu berjalan seolah
tanpa akhir. Tugas utamanya adalah mengirim SMS yang berasal dari seluruh
le yang ada di direktori /tmp/job. Hasil pengiriman SMS (berhasil / tidak)
dikirim ke SMS gateway induk melalui XMLRPC, inilah kerja sampingannya
atau sering disebut sebagai
multi-thread
Modem tersebut hanya bisa mengirim sebuah SMS pada satu saat yang
membutuhkan waktu 10 detik. Di sisi lain daemon ini harus mengabari status
pengiriman ke SMS gateway induk melalui XMLRPC yang membutuhkan waktu
5 detik.
Thread 1
Total waktu yang dibutuhkan untuk mengirim dua SMS adalah 30 detik.
Sekarang bandingkan bila menggunakan multi-thread.
Saat
Thread 1
Thread 2
from
threading
import
Thread
112
BAB 13.
2
3
4
5
6
7
8
9
import
import
from
113
KERJA SAMPINGAN
time
os
glob
lass
def
import
glob
K i r i m ( Thread ) :
__init__ ( s e l f ,
k) :
s e l f . k e r j a = True
10
s e l f . kabar = k
11
Thread . __init__ ( s e l f )
12
13
14
def
run ( s e l f ) :
print
while
if not
ontinue
del
#s e l f . kabar =
print
t i m e . s t r f t i m e ( '%H:%M:%S ' ) ,
dimulai
15
time . s l e e p ( 1 )
17
s e l f . kabar :
18
19
hasil =
20
s e l f . kabar [ 0
s e l f . kabar [ 0
21
22
25
s e l f . kabar [ 1 :
:%S ' ) ,
24
sampingan
s e l f . kerja :
16
23
' Kerja
'
def
26
hasil )
join ( sel f ) :
' Kerja
sampingan
berakhir '
s e l f . kerja = False
27
Thread . j o i n ( s e l f )
28
29
30
job_dir =
31
kabar =
32
33
34
sampingan . s t a r t ( )
35
print
while
if not
ontinue
if not
ontinue
36
t i m e . s t r f t i m e ( '%H:%M:%S ' ) ,
' Pekerjaan
'
37
38
39
40
41
42
43
44
True :
time . s l e e p ( 1 )
os . path . e x i s t s ( job_dir ) :
filenames
= g l o b ( '%s / * ' % j o b _ d i r )
filenames :
filename = filenames [ 0
utama
dimulai
BAB 13.
45
f = open ( f i l e n a m e )
46
job = f . read ( )
47
f . lose ()
48
o s . remove ( f i l e n a m e )
49
114
KERJA SAMPINGAN
job )
50
51
52
53
k a b a r . append ( j o b )
' Pekerjaan
utama
berakhir '
sampingan . j o i n ( )
Jalankan.
04:56:54
python
Pekerjaan
t e s t t h r e a d . py
04:56:54
Kerja
utama
dimulai
sampingan
dimulai
Buka
mkdir
/tmp / j o b
e ho
h e l l o > /tmp / j o b / h e l l o . t x t
0 4 : 5 6 : 5 6 KERJAKAN
04:56:57
KABARI
hello
hello
Pointer
Perlu diperhatikan variabel kabar yang bertipe list (baris 30). Ini adalah
abel bersama
vari-
sini berlaku apa yang disebut pointer yang artinya alokasi memori pada baris
30 dengan baris 10
s e l f . kabar = k
adalah
del
sama
s e l f . kabar [ 0
s e l f . kabar =
s e l f . kabar [ 1 :
Namun teknik ini akan membuat alokasi memori yang baru dimana thread 2
tidak lagi menggunakan variabel 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 produk RAB yang memanfaatkan Python dan
PostgreSQL. Akses ke database menggunakan SQLAl
hemy dan Elixir. Diran
ang semodular mungkin agar mudah dipakai oleh sistem lainnya yang bukan
Python, bukan PostgreSQL, bahkan bukan Linux.
Produk ini juga menerapkan teknik event driven dan plug-in.
14.1
Pemasangan
a p t g e t
sudo
install
imgw
Proses instalasi akan meminta Anda menyesuaikan le /et /im/gw/ ong.py.
File ini perlu diisi dengan otentikasi ke database yang sudah dibuat
tadi.
1
db_url =
Kemudian jalankan:
1
sudo
dpkg r e o n f i g u r e
imgw
sudo
/ e t / i n i t . d / imgw
restart
im-gw juga otomatis hidup saat komputer dihidupkan. Anda bisa memantau
log-nya dengan
ara:
1
2011 01 18
sudo
tail
/ v a r / l o g / im /gw . l o g
05:12:20 ,883
INFO
Start
result
dir
/ var / s p o o l /
INFO
Start
job
pid
1202
im / r e s u l t /
3
2011 01 18
05:12:20 ,886
115
at
BAB 14.
2011 01 18
on
116
SMS GATEWAY
05:12:20 ,928
port
INFO
Start
result
xmlrp
server
9317
Tekan Ctrl-C untuk mengakhiri. Tapi sebaiknya tetap terpantau, dan Anda
bisa gunakan konsole lain untuk aktivitas berikutnya.
Untuk mengirim dan menerima SMS yang sebenarnya dibutuhkan pengendali modem:
1
sudo
a p t g e t
install
immodem
Paket ini juga akan membuat tabel, menggunakan kongurasi yang sama
dengan im-gw.
Pasanglah modem GSM atau CDMA. Merk yang sudah teruji adalah Wave
om, iTegno, dan Multite
h. USB devi
e lebih disarankan karena mendukung
hotplug, dimana saat modem ditan
apkan pengendalinya otomatis aktif. Anda
bisa periksa dengan perintah:
1
ps
ax
5627
28464
g r e p modem
? SN
0:06
/ u s r / b i n / python
0:01
python
Sl
/ u s r / b i n /modemh o t p l u g
/ u s r / b i n /modem / d e v / ttyUSB0
Perhatikan /usr/bin/modem-hotplug, dialah yang memantau aktivitas pemasangan perangkat USB. Lalu ada juga /usr/bin/modem, daemon inilah yang
dipanggil oleh modem-hotplug saat USB modem ditan
apkan. Lalu bagaimana
jika perangkatnya ditan
apkan di serial port ?
Anda pastikan dulu modem itu terpasang di serial port berapa. Keberadaan
serial port bisa dilihat dengan perintah berikut:
1
dmesg
25.972197
a
grep
ttyS
serial8250 :
ttyS0
at
I /O 0 x 3 f 8
( i r q = 4)
is
1 6 5 5 0A
25.973141
00:07:
ttyS0
at
I /O 0 x 3 f 8
( i r q = 4)
is
1 6 5 5 0A
4
42.442528
is
[
[
[
a
a
at
I /O 0 x d 1 0 0
( i r q = 17)
0000:05:01.0:
ttyS5
at
I /O 0 x d 2 0 0
( i r q = 17)
0000:05:02.0:
ttyS6
at
I /O 0 x d 7 0 0
( i r q = 19)
ttyS7
at
I /O 0 x d 8 0 0
( i r q = 19)
1 6 5 5 0A
42.538574
is
ttyS4
1 6 5 5 0A
42.538359
is
0000:05:01.0:
1 6 5 5 0A
42.442750
is
0000:05:02.0:
1 6 5 5 0A
Anda bisa menyebutkan semua serial port yang ada pada le /et
/im/modem/modem.
onf:
1
[ devi e
devi
e
S6
di
/ dev / t t y
S7
S4
S5
BAB 14.
sudo
117
SMS GATEWAY
/ e t / i n i t . d /modem
restart
11211
ps
ax
g r e p modem
Rl
10:29
python
/ u s r / b i n /modem / d e v /
ttyS0
untuk mengetahui serial port mana yg digunakan. Anda bisa mengesienkan
modem.
onf diatas dengan hanya men
antumkan S0 saja, namun tidak diubah
pun tidak menjadi masalah.
Sedangkan untuk melihat log-nya, terlebih dahulu Anda periksa direktori
/var/log/modem, ada le apa di sana:
1
510012541218911. l o g
sudo
ls
/ v a r / l o g /modem
2011 01 18
sudo
tail
01:45:22 ,304
/ 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
INFO
2011 01 18
01:45:24 ,307
INFO
2011 01 18
01:45:24 ,308
INFO
2011 01 18
01:45:24 ,308
INFO
2011 01 18
01:45:24 ,309
INFO
2011 01 18
01:45:26 ,312
INFO
2011 01 18
01:45:26 ,312
INFO
>
<
<
<
>
<
<
>
<
<
<
>
<
<
>
<
<
>
<
<
30
AT+CSQ
AT+CSQ
+CSQ :
20 ,0
OK
AT+CLIP=1
AT+CLIP=1
OK
2011 01 18
01:45:26 ,312
INFO
10
2011 01 18
01:45:27 ,326
INFO
AT+CGMM
11
2011 01 18
01:45:27 ,326
INFO
12
2011 01 18
01:45:27 ,327
INFO
13
2011 01 18
01:45:27 ,327
INFO
14
2011 01 18
01:45:29 ,330
INFO
15
2011 01 18
01:45:29 ,330
INFO
16
2011 01 18
01:45:29 ,330
INFO
17
2011 01 18
01:45:31 ,332
INFO
18
2011 01 18
01:45:31 ,333
INFO
19
2011 01 18
01:45:31 ,333
INFO
20
2011 01 18
01:45:32 ,346
INFO
21
2011 01 18
01:45:32 ,346
INFO
22
2011 01 18
01:45:32 ,352
INFO S e r v i n g
AT+CGMM
MULTIBAND
9 0 0E
1800
OK
AT+CNMI= 0 , 1 , 1 , 1 , 0
AT+CNMI= 0 , 1 , 1 , 1 , 0
OK
AT+CMGF=1
AT+CMGF=1
OK
AT+CMGL="ALL"
AT+CMGL="ALL"
OK
/ d e v / ttyUSB1
v a r / s p o o l / im / j o b /modem/ 5 1 0 0 1 2 5 4 1 2 1 8 9 1 1 /
at
pid
and
28464
Bila Anda sudah berjumpa kalimat yang berawalan Serving seperti di atas,
maka modem sudah siap.
BAB 14.
118
SMS GATEWAY
Angka itu disebut dengan IMEI alias identitas
hip / SIM
ard. Jika komputer membutuhkan informasi devi
e port untuk mengendalikan modem, maka
manusia / user membutuhkan IMEI sebagai identitas
hip yang ada di dalam
modem. Aktivitas menerima dan mengirim SMS tentu melekat pada
hip, bukan
pada modem. Karena itu penggunaan IMEI pada nama log adalah yang paling
tepat untuk menjaga konsistensi history.
Lagi pula devi
e port yang digunakan modem USB kadang berubah. Saat
ini mungkin modem dikenali di USB0.
14.1.2 Database
Saat /usr/bin/modem mulai mengendalikan sebuah modem, ia melaporkan ke
/usr/bin/im-gw bahwa IMEI 510012541218911 baru saja hidup. Kejadian ini
disebut sebagai startup. Saat itulah im-gw memeriksa keberadaan IMEI tersebut di tabel im.agent. Kalau belum ada ia tambahkan, dan kalau sudah ada ia
perbaharui statusnya.
1
Password
psql
ilham
for
user
lo alhost
psql
SSL
Type
(8.4.4)
t o t a l i n d o=> SELECT i d ,
onne
tion
" help "
7
8
9
10
totalindo
ilham :
( ipher :
for
DHERSAAES256SHA,
bits :
256)
help .
id
s t a t u s FROM im . a g e n t ;
status
+
510012541218911
(1
row )
Status 0 berarti modem siap, status negatif berarti sebaliknya. Alasan untuk
14.2
Hello world!
t o t a l i n d o > SELECT
INSERT 0
world ! ' ;
t o t a l i n d o=> SELECT i d ,
t o t a l i n d o > FROM im . s e l e s a i
id
status
pesan
status ,
pengirim ,
penerima ,
pengirim
penerima
pesan
1;
BAB 14.
4
5
119
SMS GATEWAY
++++
1065
510012541218911
+628179140068
Hello
world !
6
(1
row )
Status 0 berarti telah terkirim, negatif sebaliknya, sedangkan positif berarti
Diterima
Tunggu sekitar 30 detik, dan lihat tabel im.antrian.
1
t o t a l i n d o=> SELECT i d ,
t o t a l i n d o > FROM im . a n t r i a n ;
3
4
5
id
kirim
kirim ,
pengirim
pengirim ,
|
penerima ,
penerima
pesan
pesan
++++
1071
+628179140068
510012541218911
Diterima
6
(1
row
Mungkin Anda bertanya-tanya, saat mengirim pesan tabel im.antrian yang
Defaultnya
14.3
Ada dua paket utama di sini, yaitu im-gw dan im-modem. 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 seperti Yahoo! Messenger
dan XMPP (Jabber, GTalk).
Selanjutnya
BAB 14.
SMS GATEWAY
120
BAB 14.
sudo
121
SMS GATEWAY
a p t g e t
install
imym
2339
ps
ax
g r e p ym
Sl
24:44
python
/ u s r / b i n /ym i n f o r a b
2011 02 25
sudo
tail
/ v a r / l o g /ym/ i n f o r a b . l o g
14:24:46 ,729
INFO S t a r t u p
0}
Sekarang
oba add buddy dari Yahoo! Messenger
lient seperti Pidgin. Tentu saja gunakan Yahoo! a
ount yang lain. Daemon ym se
ara otomatis akan
menambahkannya ke dalam daftar.
Selanjutnya kirim pesan seperti biasa, lalu lihat log-nya:
1
2011 02 25
15:10:43 ,885
'2011 02 25
pengirim ' :
INFO I n b o x
15:10:43+7 ' ,
' hello
world ' ,
'
t o t a l i n d o=> SELECT i d ,
kirim ,
jalur ,
pengirim ,
penerima ,
pesan
2
t o t a l i n d o > FROM im . a n t r i a n ;
3
4
id
5
6
kirim
jalur
pengirim
penerima
pesan
+++++
2074
(1
info_rab
inforab
hello
world
row )
Sekarang perhatikan kolom jalur yang berisi 5. Itu artinya jalur ym. Sedan-
gkan jalur modem berisi 1 (default). Daftar jalur ini ada di tabel jalur.
14.3.2 XMPP
Jika Anda punya a
ount di Gmail maka Anda dapat
hatting dengan user
Gmail lainnya. Namun sebenarnya Anda dapat
hatting dengan user dari server
lain yang menggunakan protokol XMPP seperti jabber.org atau jabber.rab.
o.id.
Ya, seperti email, protokol XMPP memungkinkan user dari server berbeda dapat saling mengirim pesan.
Jika Anda berminat menggunakan XMPP untuk
hatting dengan server,
pasang paket im-xmpp.
1
sudo
a p t g e t
install
imxmpp
BAB 14.
122
SMS GATEWAY
u s e r s = { ' i n f o r a b g m a i l . om ' :
5223 ,
True ,
' t a l k . g o o g l e . om ' }
}
Sesuaikan inforab dan 1234.
daemon-nya up. Setelah hidup, Anda bisa lakukan pengujian yang serupa seperti ym.
Jika Anda ingin menggunakan server lokal, bisa
oba daftar ke jabber.rab.
o.id
menggunakan Pidgin.
berikut.
1
u s e r s = { ' i n f o r a b g m a i l . om ' :
5223 ,
True ,
' t a l k . g o o g l e .
om ' } ,
' 1234 '
}
Ya, im-xmpp juga dapat menghidupkan lebih dari satu a
ount. Kebetulan
jabber.rab.
o.id menggunakan kongurasi yang lebih sederhana sebagaimana
ontoh di atas.
14.4
Broad ast
Anda telah memiliki banyak pelanggan dan ingin mengirim pesan yang sama
ke mereka. Dengan mudah lakukan query berikut.
1
INSERT INTO im . a n t r i a n ( p e n e r i m a ,
SELECT no_hp ,
' Selamat
pesan )
t r a n s a k s i ' FROM p e l a n g g a n ;
Sayangnya untuk jumlah penerima yang sangat banyak tidak bisa semudah
itu, karena /usr/bin/modem memiliki nilai job timeout yang default-nya 420 detik alias 7 menit. Jika setiap pesan membutuhkan waktu 10 detik untuk dikirim,
maka hanya 42 pesan saja yang akan dikirim. Selebihnya akan dilaporkan oleh
/usr/bin/modem sebagai status -9 alias Timeout.
Menaikkan nilai timeout di /et
/im/modem/modem.
onf bisa juga jadi solusi, namun tidak disarankan. Teknik yang paling pas adalah menyiapkan daemon baru yang memantau nilai eld job. Jika job lebih besar dari 5 maka tidak
dilakukan INSERT ke im.antrian.
Untuk kebutuhan ini sudah disiapkan paket im-broad
ast.
1
sudo
a p t g e t
install
im b r o a d a s t
Untuk mengirim pesan kita perlu melakukan INSERT ke dua tabel, yaitu
im.broad
ast dan im.broad
ast_penerima. Tabel pertama berisi pesan, sedangkan tabel kedua berisi penerimanya. Kedua tabel ini akan diproses oleh daemon
/usr/bin/im-broad
ast untuk disalin ke tabel im.antrian.
Pertama kita memerlukan nilai ID untuk broad
ast yang baru.
BAB 14.
t o t a l i n d o=> SELECT
nextval
4
5
123
SMS GATEWAY
n e x t v a l ( ' im . b r o a d a s t _ i d _ s e q ' ) ;
8
(1
row )
Kemudian tambahkan pesannya.
t o t a l i n d o > SELECT
8,
' Uji
' Selamat
transaksi
';
3
INSERT 0
Field judul hanya untuk keterangan saja. Field pesan-lah yang nanti akan
dikirim. Berikutnya tambahkan penerima pesan.
1
t o t a l i n d o > SELECT
INSERT 0
penerima )
8,
'+628179140068 ';
Jalur default yang digunakan adalah 1 (modem). Untuk jalur lainnya sertakan eld jalur.
1
t o t a l i n d o > SELECT
INSERT 0
, jalur )
8 , ' info_rab ' , 5 ;
Bab 15
Web
15.1
Django
15.2
Webpy
124
Bab 16
Hosting
16.1
Virtualmin
Ingin berbisnis web hosting ? Terbentur biaya untuk pengadaan CPanel ? Saat-
nya menggunakan Virtualmin . Ingin membidik pangsa developer Python selain 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 berbagai hal terkait
dengan bisnis web hosting Anda.
taran domain, pemberian hak akses, dan juga kuota. Ia merupakan produk open
sour
e yang mengatur berbagai aplikasi standar lainnya seperti Apa
he, PHP,
Postx, Dove
ot, PostgreSQL, dst. Namun begitu, ia menghindari "sentuhan
sihir" alias tetap mengikuti aturan-aturan yang ditetapkan masing-masing aplikasi tersebut.
gunakan Ubuntu jenis LTS (Long Term Support), seperti Hardy (8.04) atau
Lu
id (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 pengkategorian lainnya, yaitu versi desktop atau server. Jika
server sering berada di depan Anda - misalkan server ada di rumah - sebaiknya
pilih yang desktop, karena telah dilengkapi GUI , sehingga Firefox tersedia.
Namun jika server diletakkan nun jauh di sana, pilihlah versi server agar Anda
tidak berlama-lama saat melakukan upgrade.
1 http://virtualmin.
om
2 http://ubuntu.
om
3 Graphi
al User Interfa
e
125
BAB 16.
126
HOSTING
Amannya pilih yang mana ? Pilihlah Ubuntu 10.04 i386 Desktop Edition .
ISO bisa di-burn ke CD-ROM 700 MB. Rata-rata motherboard sekarang sudah mendukung boot melalui ashdisk. Jadi ada baiknya burn ISO ke ashdisk
menggunakan aplikasi Unetbootin, tersedia untuk sistem operasi Windows dan
Linux.
Setelah di-burn, boot, dan ikuti langkah-langkah petunjuk pemasangannya.
Sebaiknya pilihlah Bahasa Indonesia agar default format sesuai dengan Indonesia seperti format tanggal (dmy), pemisah ribuan (thousand separator), dsb.
Setelah pemasangan selesai dan server sudah di-boot, ubahlah hak akses
pada home dire
tory Anda agar user lain tidak bisa melihat isinya.
ifa e
address
eth0
202.59.201.67
inet
stati
netmask
255.255.255.192
gateway
203.130.231.65
$ telnet 203.130.231.120 80
Jika Anda mendapati baris "Es
ape
hara
ter is" berarti gateway berfungsi
dengan baik:
Trying 203.130.231.120...
Conne
ted to 203.130.231.120.
Es
ape
hara
ter is '^'.
Oh iya, juga sesuaikan
(DNS), misalnya:
nameserver 203.130.231.120
Lalu ujilah DNS ini dengan memanggil nama:
BAB 16.
127
HOSTING
$ telnet google.
om 80
Trying 74.125.235.20...
Conne
ted to google.
om.
Es
ape
hara
ter is '^'.
Sesuaikanlah gateway dan DNS ini dengan menanyakan ke Internet Servi
e
Provider Anda.
Server Anda terhubung dengan modem ADSL ? Biasanya IP sudah diset se
ara otomatis melalui mekanisme DHCP. Meski begitu sebaiknya Anda
memastikan IP LAN tetap statik. Bisa diset melalui menu tadi, atau melalui
modem ADSL-nya dimana biasanya modem akan menentukan MAC address
00:1f:3
:e0:66:56 mendapat IP 192.168.1.2 (
ontoh).
$ sudo sh install.sh
Saat ia menanyakan hostname, jawablah sesuai nama domain hosting yang Anda
kelola:
Please enter a fully qualied hostname (for example, example.
om):
sabilawebhosting. om
eth0
akhirnya adalah:
INFO - Rule updates done
Namun ada kalanya Anda mendapatkan pesan ini:
FATAL - in /root/virtualmin-install.log
Kadang selama proses unduh terjadi "
onne
tion refused".
Mungkin server
Virtualmin sedang di-restart. Tunggulah beberapa saat, dan jalankan lagi s
ript
instalasi seperti tadi.
$ sudo sh install.sh
Biasanya ia mengerti untuk tidak melakukannya dari awal.
BAB 16.
128
HOSTING
$ 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 kenyamanan:
/et /vim/vimr .
Kongurasi berikut
ini untuk mengingat posisi kursor pada le yang pernah Anda buka:
1
" Un omment
the
position
2
"
if
reopening
to
h a v e Vim jump
to
the
last
file
BufReadPost
l i n e (" $ ")
following
when
if
exe
l i n e ( " ' \ " " ) > 1 && l i n e ( " ' \ " " ) <=
" normal !
g '\""
endif
endif
Terkait dengan penulisan sour
e, pastikan auto-indent bekerja.
Gunakan
" Un
omment
rules
"
if
the
and
a ording
following
to
h a v e Vim
load
indentation
plugins
to
the
dete ted
filetype .
filetype
set
smartindent
plugin
indent
set
expandtab
set
t a b s t o p=4
set
s o f t t a b s t o p =4
set
s h i f t w i d t h =4
10
endif
on
Aktifkan pen
arian pintar dimana kalau Anda menuliskan huruf ke
il semua
saat pen
arian maka tidak mempedulikan huruf ke
il ataupun besar (in
asesensitive).
berlaku.
1
set
ignore ase
set
smart ase
" Do
ase
" Do s m a r t
insensitive
ase
mat hing
mat hing
BAB 16.
129
HOSTING
suphp
pemiliknya:
/home
ganti baris
do
root=/var/www:${HOME}/publi
_html
menjadi
do
root=/home
Non-aktif-kan modul php5 karena sudah diganti dengan modul suphp:
m a x _ e x e u t i o n _t i m e = 1 0 0 0
max_input_time = 1 0 0 0
memory_limit = 1 2 8M
p o s t _ m a x _ s i z e = 1 0 0M
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:
master. f,
aktifkan baris
submission
inet
smtps
inet
submission
dan
smtps :
/et /postx/-
n smtpd
smtpd
Karena user a ount menggunakan Linux user, ubahlah /et /default/saslauthd, dari baris:
BAB 16.
130
HOSTING
MECHANISMS="pam"
menjadi
MECHANISMS="shadow"
Restart daemon-nya:
16.1.7 PostgreSQL
Sebaiknya Anda periksa default en
oding yang digunakan PostgreSQL.
superuser,
Yes
dan klik
Next
hingga selesai.
Setelah Next
BAB 16.
131
HOSTING
guration.
Pada pilihan
ternal address
Klik Save. Jangan lupa mengatur modem ADSL untuk mengarahkan seluruh
permintaan dari luar ke server 192.168.1.2. Mekanisme ini sering disebut sebagai
port forwarding, atau ada juga yang bilang DMZ.
Jika Anda tidak pernah memesan IP publik statik pada ISP, hampir dipastikan Anda hanya mendapat IP publik dinamik. Dengan demikian abaikan
saja urusan DNS di atas, karena DNS yang Anda butuhkan perlu ditangani
server lain yang memiliki IP publik statik, misalnya
dyndns.org.
route )
tidak bisa berbisnis hosting. Untuk memastikannya,
oba minta teman Anda
yang ada di "seberang" sana untuk mengakses http://180.252.150.215.
Sesuaikanlah IP-nya sebagaimana yang dilaporkan Virtualmin di atas. Jika
ia mendapatkan pesan:
It works!
maka server Anda telah memiliki IP publik.
gin.
3. Pada bagian
pilihlah
user-
4. Klik Save.
Khusus administrator domain bersangkutan, 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.
132
HOSTING
memiliki domain
Unlimited
sederhana, yaitu
memiliki
1
2
# enable
if
3
4
[
.
bash
ompletion
in
intera tive
/ e t / bash_ ompletion
&& !
shells
shopt
oq
posix ;
then
/ e t / bash_ ompletion
fi
Agar lebih nyaman dalam memasang berbagai aplikasi dari GitHub dan
Bitbu
ket, pasanglah aplikasi pengunduhnya:
Server Template.
Saat pendaf-
taran domain, admin diberikan kesempatan memilih bahasa apa yang akan digunakan pelanggannya.
BAB 16.
133
HOSTING
Create Virtual Server, Server
onguDefault Settings yang berarti PHP yang
digunakan dengan direktori publi
_html sebagai Do
umentRoot.
Python.
ration template.
Lalu dimana pilihan Python ? Seharusnya ada di bawahnya, namun saat ini
belum ada. Inilah yang akan kita buat sekarang.
Klik
Python
Sub-servers
Template name:
(bebas)
( entang)
Pada bagian
Ini untuk mengganti form isian dengan hal-hal yang bersifat Apa he.
Pada
Dire
tives and settings for new websites, dan pada radio button Apa
he
dire
tives below
baris-baris WSGI berikut ini (paling bawah):
bagian
tambahkan
$HOME/publi _html
untuk
sour
e PHP, dimana bila URL yang dimaksud dipanggil melalui browser - misalkan http://sabilawebhosting.
om - maka sour
e PHP yang ada di direktori
itulah yang dijalankan Apa
he.
s
ript
Istilahnya
$HOME/wsgi/wsgi_handler.py.
Sebenarnya dengan apa yang Anda sudah pasang tadi sudah
ukup bagi
user untuk menyiapkan segala sesuatunya.
pada
Masuklah ke menu System Settings, Virtualmin Conguration. Pada Conguration
ategory, pilihlah A
tions upon server and user
reation. Lalu pada
Command to run after making
hanges to a server isilah:
/usr/lo
al/bin/virtualmin
Klik Save. Selanjutnya buatlah s
ript berikut ini.
Listing 16.1: /usr/lo
al/bin/virtualmin
1
#! / usr / b i n / python
BAB 16.
2
3
4
5
6
7
8
9
import
import
if
134
HOSTING
os
sys
o s . e n v i r o n [ 'VIRTUALSERVER_ACTION ' ==
o s . system ( ' p
'CREATE_DOMAIN' :
/ u s r / l o a l / e t / v i r t u a l m i n / w s g i %s ' % (
o s . e n v i r o n [ 'VIRTUALSERVER_HOME' ) )
o s . s y s t e m ( '
d %s / w s g i
ln
VIRTUALSERVER_HOME' )
10
11
o s . s y s t e m ( ' hown
VIRTUALSERVER_HOME' )
%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 exe
utable:
$HOME/ :
autoreload
daemon Python.
Daemon Python ?
Ya. Setiap s
ript Python yang dibuat oleh user akan dijalankan oleh Apa
he
sebagai daemon, dalam sebuah sub-pro
ess. Monitoring s
ript berguna untuk
memantau perubahan le pada direktori $HOME/wsgi. Bila s
ript ini mendapati ada le yang berubah, se
ara otomatis ia akan mengakhiri dirinya sendiri,
dan pada saat URL situs dipanggil lagi melalui browser, Apa
he - se
ara otomatis pula - menghidupkan kembali daemon ini.
1
2
3
4
5
6
7
8
9
import
import
import
import
import
import
import
_interval = 1.0
5 Interpreter Python mengizinkan kita untuk mengubah le *.py selama s ript sedang berjalan (runtime ). Namun perubahan itu berfungsi saat s ript itu dijalankan ulang.
BAB 16.
135
HOSTING
10
_times = {}
11
_files
12
13
_running = F a l s e
14
15
_ l o k = t h r e a d i n g . Lo k ( )
16
def
17
18
19
_ r e s t a r t ( path ) :
_queue . p u t ( True )
prefix =
print
print
20
' monitor
% ( prefix ,
21
( p i d=%d ) : ' % o s . g e t p i d ( )
>> s y s . s t d e r r ,
'%s
Change
dete ted
'%s
Triggering
to
path )
>> s y s . s t d e r r ,
pro ess
restart . '
% prefix
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
os . k i l l ( os . getpid ( ) ,
def
s i g n a l . SIGINT )
_modified ( path ) :
try
if not
return
os . path . i s f i l e ( path ) :
path
in
_times
# Che k f o r when f i l e l a s t m o d i f i e d .
37
38
39
40
41
42
43
44
45
46
mtime = o s . s t a t ( p a t h ) . st_mtime
if
path
not in
_times :
_ t i m e s [ p a t h = mtime
if
mtime
!=
_times [ path :
BAB 16.
47
ex ept
48
50
51
52
53
54
56
57
return
True
49
55
136
HOSTING
return
return
True
False
def
_monitor ( ) :
while
1:
# Che
k m o d i f i
a t i o n times on a l l f i l e s in s y s .
modules .
58
59
for
60
61
in
if not
ontinue
if not
ontinue
if
module
s y s . modules . v a l u e s ( ) :
h a s a t t r ( module ,
62
63
p a t h = g e t a t t r ( module ,
64
path :
65
66
os . path . s p l i t e x t ( path ) [ 1
pyo ' ,
67
path = path [ :
if
68
69
70
in
'.
_modified ( path ) :
return
_ r e s t a r t ( path )
71
72
73
for
74
75
path
if
76
77
in
return
_files :
_modified ( path ) :
_ r e s t a r t ( path )
# 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 .
78
79
try
return
ex
ept
pass
80
81
82
_queue . g e t ( t i m e o u t=_ i n t e r v a l )
83
84
85
_ t h r e a d = t h r e a d i n g . Thread ( t a r g e t=_monitor )
86
_ t h r e a d . setDaemon ( True )
87
def
88
[ ' . py ' ,
_exiting () :
BAB 16.
137
HOSTING
try
ex
ept
pass
89
90
_queue . p u t ( True )
91
92
93
_thread . j o i n ( )
94
95
a t e x i t . r e g i s t e r ( _exiting )
96
def
97
98
99
100
101
102
t r a k ( path ) :
if not
path
in
_files :
_ f i l e s . append ( p a t h )
def
103
s t a r t ( i n t e r v a l =1.0) :
global
if
_interval
i n t e r v a l < _interval :
104
_interval = i n t e r v a l
105
global
if not
print
106
_running
107
_lo k . a q u i r e ( )
108
_running :
109
prefix =
110
' monitor
( p i d=%d ) : ' % o s . g e t p i d ( )
>> s y s . s t d e r r ,
'%s
Starting
hange
monitor .
' % prefix
111
_ r u n n i n g = True
112
_thread . s t a r t ( )
113
_lo
k . r e l e a s e ( )
Anda bisa salin dari situs aslinya:
http://
ode.google.
om/p/modwsgi/wiki/ReloadingSour
eCode
Selanjutnya buat
1
2
def
root do
ument.
Listing 16.3: wsgi_handler.py
a p p l i
a t i o n ( environ ,
status =
' 2 0 0 OK '
output =
' Hello
response_headers =
start_response ) :
World ! '
[ ( ' C o n t e n t t y p e ' ,
( ' C o n t e n t L e n g t h ' ,
s t r ( l e n ( output
)))
6
7
8
9
10
11
12
start_response ( status ,
return
import
os ,
[ output
sys
response_headers )
BAB 16.
138
HOSTING
13
s y s . p a t h . append ( 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 ( __file__ )
14
env_ver =
))
' . ' . j o i n ( map (
[:2) )
15
lambda
x:
str (x) ,
sys . version_info
env_path = 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 ( __file__ ) ) ) + \
16
17
18
19
20
21
22
23
24
' / e n v / l i b / p y t h o n%s / s i t e
p a k a g e s '
% env_ver
s y s . p a t h . append ( env_path )
import
monitor
monitor . s t a r t ( i n t e r v a l =1.0)
Selesai sudah kongurasi server. Kini saatnya produ
tion.
sabilawebhosting.
om.
tual Server. Isilah:
hal ini
Domain name:
Create Vir-
sabilawebhosting. om
Create Server.
http://sabilawebhosting.
om
Kalau Anda menjumpai:
Hello world!
berarti pendaftaran sudah berlangsung dengan baik. Bila Anda menjumpai:
Server not found
hampir dipastikan domain tersebut belum sepenuhnya dikenal oleh para ISP.
Jika Anda browsing di server pastikan baris berikut ini ada di urutan teratas
nameserver 127.0.0.1
Namun jika Firefox Anda berada di mesin berbeda, pastikan DNS teratas adalah
IP server, masih di
BAB 16.
139
HOSTING
nameserver 202.59.201.67
Anda bisa membuka Virtualmin dengan subdomain
admin,
http://admin.sabilawebhosting.
om
Hal serupa dapat dilakukan oleh pelanggan Anda sesuai domain mereka masingmasing.
Sedangkan untuk mail, mereka bisa mengunjungi subdomain
webmail, dalam
reymanx.web.id
reymanx.
maka Virtualmin
pip
yang tersedia di
virtual environment 7 :
$
d wsgi
$ ../env/bin/django-admin.py startproje
t myproje
t
Lalu ubahlah
1
2
import
$HOME/wsgi/wsgi_handler.py
sys
s y s . p a t h . append ( 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 ( __file__ )
env_ver =
))
' . ' . j o i n ( map (
[:2) )
6
lambda
x:
str (x) ,
sys . version_info
env_path = 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 ( __file__ ) ) ) + \
7
8
' / e n v / l i b / p y t h o n%s / s i t e
p a k a g e s '
% env_ver
s y s . p a t h . append ( env_path )
9
10
o s . e n v i r o n [ 'DJANGO_SETTINGS_MODULE'
' myproje t .
settings '
11
import
6 http://djangoproje
t.
om
7 Python virtual environment
BAB 16.
140
HOSTING
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 . WSGIHandler ( )
13
import
14
15
monitor
monitor . 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!
Beberapa hal lain yang biasa digunakan user adalah:
Apply Changes
di kanan atas.
Webmin Mod-
arankan karena masih menggunakan Fast CGI (konon yang terbaik menggunakan WSGI seperti yang sudah diulas).
Template telah siap. Kini
obalah mendaftarkan domain baru pada menu
dan
Administration
Create Server.
Klik
wsgi/wsgi_handler.py. Jika tadi Anda pilih Default SetServer onguration template, seharusnya Anda menjumpai pesan:
tings
pada
Forbidden
yang artinya Apa
he mengharapkan le
16.2
Google Apps
publi _html/index.php.
Bibliogra
[1 http://jabber.rab.
o.id/os/web-admin-dengan-virtualmin
[2 http://jabber.rab.
o.id/os/pas
a-instalasi-linux
[3 http://ja
obian.org/writing/pg-en
oding-ubuntu
[4 https://
onvore.
om/id-python/gathering-online-22-july-2011
[5 http://
ode.google.
om/p/modwsgi/wiki/ReloadingSour
eCode
141
Indeks
__name__, 35
integer, 11
KDE, 6, 7
Android, 5
konsole, 6
apt-get install, 6
apt-get update, 6
length(), 56
Linux, 5
lo
ale-gen, 38
BlankOn, 6
lo altime(), 28
break, 14
lower(), 9
lpad(), 56
ontinue, 15
CREATE TABLE, 44
Ma , 5
CREATE VIEW, 52
mktime(), 29
reatedb, 43
modul datetime, 30
reateuser, 42
modul lo
ale, 37
modul time, 28
nextval(), 47
date(), 30
None, 39
datestyle, 48
NOT NULL, 44
datetime(), 30
DEFAULT, 44
objek hampa, 39
DELETE FROM, 50
ORDER BY, 48
DROP TABLE, 51
dropdb, 43
dropuser, 42
pg_dump, 54
pg_restore, 54
epo h, 29
plpgsql, 6
eval(), 20
plpython, 6
postgresql.
onf, 48
oat, 11
PRIMARY KEY, 44
for, 16
print, 9, 20
formatting, 17, 19
psql, 6, 43
fullpath, 54
rata kanan, 55
Gnome, 7
raw_input(), 10, 27
int(), 19, 27
sequen
e, 46
142
INDEKS
serial, 46
sisa pembagian, 18
SQLAl
hemy, 6
string, 9, 11
sudo, 42
Symbian, 5
text editor, 7
time(), 29
tipe data di
tionary, 26
tipe data oat, 18
tipe data integer, 18
tipe data list, 20
transa
tion, 72
transa
tion, auto
ommit, 72
type(), 17
Ubuntu, 6
Unix, 5
Unix time, 29
UPDATE, 50
upper(), 9
variabel, 11
vi, 7
while, 15
143