Penggodaman Segera/Penggodaman Segera
Rencana ini ialah sebuah pengenalan tentang seni pengaturcaraan, dengan contoh-contoh yang ditulis dalam bahasa pengaturcaraan Python. (Jika anda sudahpun tahu bagaimana mahu membuat pengaturcaraan, akan tetapi anda mahukan pengenalan ringkas tentang Python, anda mungkin mahu membaca rencana saya Python Segera.
Rencana ini bukan tentang bagaimana mahu menceroboh sistem-sistem komputer orang lain dan sebagainya. Saya tidak berminat tentang pekerjaan itu, jadi sila jangan hantar e-mel kepada saya untuk bertanyakan tentang perkara itu.
Nota: Agar contoh-contoh yang terkandung dalam rencana ini dapat terlaksana dengan betul, tuliskan program dalam fail teks dan kemudian laksanakanfail tersebut dengan pentafsir; jangan cuba untuk melaksanakan program secara langsung dalam pentafsir interaktif – tidak semua akan terlaksana dengan betul. (Sila jangan tanya saya tentang perincian perkara ini. Semak dokumentasi di http://www.python.org/doc, ataupun kirimkan e-mel kepada help@python.org.
Sekitaran
[sunting]Anda perlu memasang pentafsir Python untuk mengaturcara dengan Python. Pentafsir ini terdapat buat kebanyakan platform (termasuk Macintosh, Unix dan Windows). Maklumat lanjut tentang ini dapat diperoleh di tapak Python, www.python.org. Anda juga perlukan penyunting teks (seperti Emacs, notepad, notepad++ atau yang sama dengannya.
Apa itu Pengaturcaraan?
[sunting]Mengaturcara komputer bermakna memberinya satu set suruhan tentang apa yang perlu dilakukannya. Dalam banyak cara, pengaturcaraan komputer menyerupai resipi, sama seperti resipi yang kita gunakan untuk memasak. Sebagai contoh [1]:
Salad Fiesta
Ramuan:
Perap:
1/4 cawan air limau nipis
1/4 cawan kicap rendah garam
1/4 cawan air
1 sudu besar minyak sayuran
3/4 camca jintan putih
1/2 camca oregano
1/4 camca sos cili pedas
2 ulas bawang putih, dikisar
Salad:
1 tin (12-auns) daging, dihiris
1 ulas bawang, diricih
1 cili kembung, diricih
Salad
12 biji tomato ceri, dibahagi dua
Arahan:
Campurkan semua bahan perap di dalam sebuah jar yang ditutp ketat; goncang.
Letakkan ricihan daging di dalam beg plastik. Tuangkan perapan. Tutup beg; perap selama 30 minit di dalam peti sejuk. Keluarkan daging dari beg; ketepikan dua sudu besar perapan.
Panaskan perapan yangdiketepikan di dalam kuali. Tambahkan daging, bawang, dan lada hijau.
Masak selama 3 ke 4 minit atau sehingga daging panas.
Letak salad ke dalam empat pinggan salad. Sudukan campuran salad yang panas ke atas salad.
Hidangan untuk 4 orang.
Sudah tentu tidak ada komputer yang akan memahami arahan ini. Dan kebanyakan komputer tidak akan dapat membuat salad mahupun dapat memahami resipi. Jadi, apa yang harus kita lakukan untuk membuat resipi ini lebih mesra komputer? Sebenarnya dua perkara asas. Kita perlu (1) "bercakap" dengan cara yang dapat difahami komputer, dan (2) bercakap tentang perkara yang dapat digunakan komputer.
Hujah pertama bermaksud kita perlu menggunakan bahasa – sebuah bahasa pengaturcaraan yang memiliki program pentafsir, dan hujah kedua bermaksud kita tidak boleh mengharapkan komputer untuk membuat salad – akan tetapi kita dapat mengharapkan komputer itu untuk mencampurkan nombor, menulis pada skrin, dan sebagainya.
Helo…
[sunting]Terdapat satu tradisi tutorial-tutorial pengaturcaraan yang menyatakan bahawa tutorail harus bermula dengan aturcara atau program yang mencetak "Hello, world!" (Helo, dunia!) pada skrin. Dengan Python, ini agak mudah:
print "Hello, World!"
Pada asasnya ini sama dengan resipi di atas (meskipun ia jauh leibh ringkas!). Ia memberitahu komputer apa yang perlu dilakukan: mencetak "Hello, world!". Mudah sahaja. Bagaimana kiranya jika kita mahukan ia melakukan perkara lain?
print "Helo, dunia!"
print "Selamat tinggal, dunia!"
Tidak terlalu susah bukan? Dan juga tida terlalu menarik. Kita mahu melakukan sesuatu dengan bahan ramuan, sama seperti salad daging. Jadi – apakah ramuan yang kita miliki? Pertama, kita ada rentetan teks, seperti "Hello, world!"
; tapi kita juga memiliki nombor. Katakan kita mahu komputer mencongakkan kawasan segi empat tepat. Kita dapat berikan resipi berikut kepada komputer:
# Keluasan Segi Empat Tepat
# Ramuan:
lebar = 20
tinggi = 30
# Arahan:
keluasan = lebar*tinggi
print keluasan
Anda mungkin dapat lihat persamaan (mahupun sedikit) dengan resipi salad tadi. Bagaimana ia bertindak? Pertama sekali semua baris yang bermula dengan #
disebut ulasan (comments) dan sebenarnya tidak diendahkan oleh komputer. Walau bagaimanapun, menyisipkan keterangan kecil seperti ini mungkin penting buat menjadikan program anda mudah dibaca oleh manusia.
Baris-baris yang menyerupai foo = bar
dipanggil umpukan (assignment). Dalam kes lebar = 20
kita memberitahu komputer yang lebar seharusnya mempunyai nilai 20 bermula dari titik ini. Apakah maksudnya "lebar ialah 20"? Ia bermaksud pemboleh ubah (variable) dengan nama "lebar" diwujudkan (jika ia sudah wujud, diguna kembali) dan diberi nilai 20. Justeru, jika kita mengguna pemboleh ini kemudian, komputer akan mengetahui nilainya. Jadi,
lebar*tinggi
pada asasnya sama dengan
20*30
yang dihitung sebagai 600, yang kenudiannya diumpukkan kepada pemboleh ubah yang bernama "keluasan". Penyataan terakhir program mencetak nilai pemboleh ubah "keluasan", jadi apabila anda melaksanakan program ini, anada hanya akan melihat
600
Nota: Dengan beberapa bahasa pengaturcaraan, anda perlu memberitahu komputer pemboleh ubah yang diperlukan pada permulaan program (sama seperti ramuan untuk salad) – Python pintar dan dapat menentukan ini semasa melaksankan sesuatu program.
Suap balik
[sunting]OK. Sekarang anda dapat melakukan perhitungan mudah danjuga yang agak rumit. Misalnya, anda mungkin mahu menulis program untuk menghitung keluasan bulatan dan tidak segi empat tepat:
jejari = 30
print jejari*jejari*3.14
Walau bagaimanapun, ini tidaklah lebih menarik daripada program segi empat tepat. Sekurang-kurangnya pada pendapat saya. Ia agak ketat dan tidak fleksibel. Bagaimana kalau jejari bulatan kita itu adalah 31? Bagaimana komputer akan tahu? Ia agak serupa dengan bahagian resipi salad yang berbunyi, "masak selama 3 ke 4 minit atau sehingga daging panas." Untuk mengetahui bila ia sudah masak, kita perlu periksa. Kita perlukan suapan balik atau input. Bagaiman komputer tahu tentang jejari bulatan kita? Ia juga memerlukan input. Apa yang kita dapat buat adalah memberitahunya untuk memeriksa jejari:
jejari = input("Apakah nilai jejari?")
print jejari*jejari*3.14
OK, sekarang sudah menjadi rancak sedikit...input
ialah sesuatu yang dipanggil "fungsi" (function). (Anda akan belajar membuat fungsi anda sendiri tidak lama lagi. input
ialah fungsi yang terbina dalam Python. Hanya menulis
input
sahaja tidak memadai. Anda perlu letak sepasang tanda kurungan pada hujungnya. Jadi input()
akan bekerja – ia akan menunggu pengguna untuk memasukkan jejari (yakni, input). Versi di atas mungkin agak lebih mesra pengguna kerana ia mencetak soalan terdahulu. Apabila kita memasukkan sesuatu seperti rentetan soalan "Apakah nilai jejari?" di dalam tanda kurungan sebuah "panggilan fungsi" (function call) ia dipanggil "penghuluran parameter" (passing a parameter) kepada fungsi. Perkara di dalam tanda kurungan merupakan "parameter". Dalam kes ini, kita menghulurkan soalan sebagai parameter agarinput
tahun apa yang perlu dicetak sebelum mendapatkan jawapan daripada pengguna.
Tetapi, bagaimanakah jawapan disampaikan kepada pemboleh ubah jejari
? Apabila dipanggil, fungsi input
, memulangkan (return) sesuatu nilai (sama seperti fungsi-fungsi lain). Anda tidak perlu menggunakan nilai ini, akan tetapi dalam kes ini, kita mahu menggunakannya. Justeru, pernayataan-pernyataan berikut memiliki maksud yang berlainan:
foo = input
bar = input()
foo
sekarang mengandungi dirinya sebagai fungsi input (agar ia dapat digunakan seperti foo("Berapa umur anda?")
; ini dikenali sebagai fungsi dinamik sementara bar
mengandungi apa saja yang dimasukkan oleh pengguna.
Aliran
[sunting]Anda boleh menulis program yang melakukan tindakan mudah (aritmetik dan cetak) dan yang boleh menerima input daripada pengguna. Ini berguna, akan tetapi kita masih terbatas pada apa yang dikenali sebagai "pelaksanaan berjujukan" (sequential execution) perintah-perintah, yakni perintah dilaksanakan mengikut aturan tetap. Sebahagian besar resipi salad kita dilaksanakan secara berjujukan atau linear macam ini. Tetapi apa kata kalau kita mahu memberitahu komputer bagai mahu memeriksa daging yang masak? Jika ia dipanaskan, ia seharusnya dialih dari ketuhar – jika tidak, ia seharusnya dipanaskan untuk seminit atau dua lagi. Jadi, bagaimana harus kita mengungkapkannya?
Apa yang perlu kita buat ialah mengawal aliran program. Aliran ini boleh bergerak dalam dua arah – sama ada mengalihkan daging, atau terus meninggalkannya di dalam ketuhar.Kita bolehmembuat pilihan, dan syarat adalah sama ada ia dipanaskan dengan cukup ataupun tidak. Ini dipanggil "pelaksanaan bersyarat" (conditional execution). We dapat mealkukannya seperti berikut:
suhu = input("Apakah suhu daging?")
if suhu > 50:
print "Salad sudah cukup masak."
else:
print "Masak lagi."
Maksud suruhan ini seharusnya jelas: Jika suhu melebihi 50 (Celcius), cetak pesanan yang memaklumkan pengguna yang salad sudah cukup masak, jika tidak, maklumkan pengguna agar memasakinya lagi.
Nota: Pengengsotan penting dengan Python. Blok yang terdapat dalam pelaksanaan bersyarat (dan "gelung" serta "definisi fungsi", lihat bawah) mesti diengsotkan (dan diengsotkan dengan jumlah ruang putih yang sama; tab dikira sebagai 8 ruang) agar pentafsir dapat di mana titik mula dan akhir blok. Ia juga memudahkan pembacaan kod oleh manusia.
Mari kita pulang kepada penghitungan keluasan kita. Dapatkah anda lihat apa yang dilakukan program?
# Program penghitung keluasan
print "Selamat datang ke program penghitungan keluasan"
print "---------------------------------------"
print
# Cetak menu:
print "Sila pilih bentuk:"
print "1 Segi empat tepat"
print "2 Bulatan"
# Dapatkan pilihan pengguna:
bentuk = input("> ")
# Hitung keluasan:
# Blok 1 dengan 'if'
if bentuk == 1:
tinggi = input("Sila masukkan tinggi: ")
lebar = input("Sila masukkan lebar: ")
keluasan = tinggi*lebar
print "Keluasan ialah ", keluasan
#Blok 2 dengan 'else'
else:
jejari = input("Sila masukkan jejari: ")
keluasan = 3.14*(jejari**2)
print "Keluasan ialah", keluasan
Perkara-perkara baharu dalam contoh ini:
-
print
yang digunakan dengan tersendiri akan mencetak baris kosong -
==
memeriksa sama ada dua perkara/benda sama, berbanding dengan=
, yang mengumpukkan nilai di sebelah kanan kepada pemboleh ubah di sebelah kirinya. Perbezaan ini amatpenting.! -
**
ialah operator "kuasa" Python. Justeru jejari yang digandakan ditulisradius**2
. -
print
boleh mencetak lebih daripada satu perkara. Asingkan perkara-perkara tersebut dengan koma. (Perkara-perkara itu akan diasingkan dengan ruang tungal dalam output.)
Program ini agak mudah: Ia meminta sebuah nombor, yang memberitahunya sama ada pengguna mahu menghitung keluasan segi empat tepat atau bulatan. Kemudian ia mengguna pernyataan if
(pelaksanaan bersyarat) bagi membuat keputusan blok mana (Blok 1 atu 2, lihat kod) yang harus digunakan untuk menghitung keluasan. Pada asasnya blok-blok ini sama dengan blok yang digunakan untuk contoh-contoh penghitungan keluasan terdahulu. Perhatikan bagaimana komen menjadikan kod lebih mudah untuk dibaca. Dikatakan bahawa rukun pertama pengaturcaraan adalah: "Anda akan sentiasa menulis komen!" Apapun menulis komen ialah sesuatu yang harus diamalkan.
Latihan 1
[sunting]Kembangkan program di atas untuk merangkumi penghituan keluasan buat segi empat sama, yang memerlukan pengguna untuk memasukkan nilai untuk hanya satu sisi. Anda perlu tahu satu perkara untuk melakukan ini: Sekiranya anada memiliki lebih dari dua pilihan, anda boleh menulis kod mirip cebisan kod berikut:
if foo == 1:
# Lakukan ini...
elif foo == 2:
# Lakukan benda lain...
elif foo == 3:
# Lakukan sesuatu yang berbeza...
else:
# Jika semua gagal...
Di sini elif
merupakan kod misteri yang bermaksud else if ("jika tidak") :)
. Jadi, jika foo
ialah satu, lakukan sesuatu; jika tidak, jika foo
dua, lakukan sesuatu yang berlainan, danseterusnya. Anda mungkin mahu menambah pilihan lain program, seperti segi tida, poligon dan sebagainya. Ia terpulang pada anda.
Gelung
[sunting]Pelaksanaan berjujukan dan bersyarat adalah hanya dua daripada tiga blok pembinaan asas pengaturcaraan. Yang ketiga ialah "gelung" (loop). Dalam bahagian terdahulu, saya telah mencadangkan penyelesaian untuk memeriksa sama ada daging dipanaskan, akan tetapi nyata bahawa ia tidak berapa mencukupi. Bagiamankalau daging tidak cukuppasa apabila kita memeriksa buat kali kedua dan berikutnya? Bagaimana dapat kita tahu berapakali kita harus memeriksannya? Hakikatnya adalah kita tidak dapatmelakukannya. Dan seharusnya kita tidak melakukannya. Kita seharusnya dapat menyuruh komputer untuk terus memeriksa sehinggalah daging itu masak. Bagaimana harus kita mealkukannya? Anda sudah agak – kita gunakan gelung atau "pelaksanaan berulang-ulang" (repeated execution).
Python memiliki dua jenis gelung: while ("sementara masih") dan for ("untuk"). Gelung for
mungkin gelung yang paling mudah. Misalnya:
for makanan in "daging", "telur", "tomato":
print "Saya meminati", makanan
Ini bermaksud: Untuk (for) setiap unsur dalam senarai (list) "daging", "telur", "tomato"
, cetakkan yang anda meminatinya. Blok dalam gelung dilaksanakan sekali buat setiap unsur, dan setiap kali ini berlaku, unsur semasa diumpukkan kepada pemboleh ubah <code<makanan (dalam kes ini). Satu lagi contoh:
for nombor in range(1,100):
print "Hello, world!"
print "Hanya", 100 - nombor, "lagi sebelum selesai..."
print "Hello, world"
print "Itu yang terakhir... Phew!"
Fungsi range
("julat") memulangkan sebuah senarai nombor dalam julat yang diberikan (termasuk yang pertama, tidak termasuk yang terakhir...dalam kes ini, [1 ... 99]. Jadi, dengan kata lain:
- Kandungan dalam gelung dilaksanakan untuk setiap nombor dalam julat nombor bermula dari (dan termasuk) 1 sehinggalah (dan tidak termasuk) 100. (Apa yang dilakukan oleh kod dalam badan gelung dan pernyataan-pernyataan berikutnya ditinggalkan sebagai latihan.)
Namun, sebenarnya ini tidak membantu kita dengan masalah masakan kita. Jika kita mahu memeriksa daging seratus kali, ia merupakan penyelesaian yang baik; akan tetapi kita tidak tahu sama ada ia memadai – atau ia terlalu banyak. Kita hanya mahu terus memeriksa selagi ia tidak cukup panas (ataupun sehingga ia cukup panas). Jadi, kita gunakan while:
# Program untuk memasak daging
# Ambil fungsi *sleep* ("tidur")
from time import sleep # P: Import fungsi "tidur" daripada modul "time" atau masa
print "Sila mulakan masakan. (Saya akan kembali dalam masa 3 minit.)"
# Tunggu selama 3 minit (yakni, 3*60 saat)...
sleep(180)
print "Saya sudah kembali :)"
# Berapa panaskah panas?
cukup_panas = 50
suhu = input("Berapa panaskah daging? ")
while suhu < cukup_panas:
print "Tidak cukup panas... Masak sikit lagi..."
sleep(30)
suhu = input("OK. Berapa panaskah sekarang? ")
print "Sudah cukup panas - Siap!!"
Perkara-perkara baharu dalam contoh ini:
- Beberapa fungsi berguna distor dalam modul dan dapat diimport. Dalam kes ini kita import fungsi
sleep
(yang tidur buat beberapa saat yang ditentukan) daripada modul "time" yang terbina dalam Python. (Anda boleh membuat modul anda sendiri...).
Latihan 2
[sunting]Tulis sebuah program yang membaca nombor daripada pengguna secara berterusan sehinggalah mencapai jumlah 100. Tulis ebuah program lagi yang membaca 100 nombor daripada pengguna dan mencetak jumlahnya.
Program-program yang lebih besar — Pengabstrakan
[sunting]Jika anda perlukan gambaran menyeluruh tentang kandungan sebuah buku, anda tidak membaca seluruh buku – anda lihat jadual isi kandungan, betul tak? Ia secara ringkasnya menyenaraikan topik-topik utama buku. Sekarang – bayangkan anda menulis sebuah buku memasak. Kebanyakan resipi, seperti, "Nasi Lemak Lauk Daging" dan "Nasi Lmak Sambal Sotong" mungkin mengandungi bahan yang sama, seperti nasi dalam kes ini. Namun anda tidak mahu menulis tentang bagaimana mahu memasak nasi. Jadi anda sebenarnya tidak menulis tentang memasak nasi lemak dalam setiap bab. Anda menulis resipi nasi lemak dalam bab berasingan, dan hanya merujuk kepadanya dalam bab-bab berkaitan. Jadi, anda hanya menulis nama bab tentang nasi lemak dan tidak menulis resipi nasi lemak setiap kali anda menulis tentang masakan nasi lemak. Dalam pengaturcaraan komputer, ini disebut pengabstrakan atau abstraction.
Adakah kita sudah terlintas dengan sesuatu seperti ini? Ya. Daripada memberitahu komputer bagaimana caranya untuk mendapatkan jawapan daripada pengguna, kita menggunakan input
– sebuah fungsi. Kita sebenarnya boleh membuat fungsi kita sendiri bagi penggunaan pengabstrakan seperti ini.
Katakan kita mahu mendapatkan integer terbesar yang kurang daripad nilai sebuah nombor positif. Misalnya, apabila diberi nombor 2.7, nilai integer adalah 2. Ini sering disebut "lantai" (floor) nombor tersebut. (ini sebenarnya dapat dilaksanakan dengan sebuah fungsi terbina Python, int
, tapi sekali lagi, biar saya jelaskan lebih lanjut...) Bagaiman dapat kita lakukan ini? Penyelesaian yang mudah ialah dengan mencuba semua kemungkinan bermula dengan sifar:
nombor = input("Apakah nombor? ")
lantai = 0
while lantai <= nombor:
lantai = lantai+1
lantai = lantai-1
print "Lantai buat", nombor, "adalah", lantai
Perhatikan yang gelung berakhir sebaik sahaja lantai tidak lagi kurang daripada (atau sama dengan) nombor; kita telah menambah satu lebih. Justeru kita kena tolak satu kemudiannya. Bagaimana kalau kita mahu "lantai" ini dalam sebuah ungkaapan matematik yang kompleks? Kita perlu menulis kesemua gelung buat setiap nombor yang memerlukan "lantai". Tidak berapa menarik...Anda mungkin sudah meneka apa yang perlu kita lakukan sebaliknya: Letakkan semua dalam sebuah fungsi yang dipanggil "lantai":
def lantai(nombor):
hasil = 0
while hasil <= nombor:
hasil = hasil+1
hasil = hasil-1
return hasil
Perkara-perkara baharu dalam contoh ini:
- Fungsi diberi definisi dengan kata kunci
def
, diikuti oleh nama fungsi dan parameter-parameter yang diletakkan dalam kurungan. - Jika fungsi itu perlu memulangkan nilai, ini dilakukan dengan kata kunci
return
(yang secaraautomatik akan menamatkan fungsi).
Baiklah, sekarang kita sudah memberikan definisi kepada fungsi. Kiat dapat menggunakannya seperti ini:
x = 2.7
y = lantai(2.7)
Selepas ini y
seharusnya memiliki nilai 2. Kita juga boleh membuat fungsi yang meiliki lebih daripada satu parameter:
def tambah(x,y):
return x+y
Tambahan tentang fungsi
[sunting]Pengabkstrakan yang kita gunakan apabila membina fungsi sering dipanggil "pengabstrakan prosedur" (procedural abstraction), dan banyak bahasa menggunakan prosedur kata (word procedure) selain fungsi kata. Sebenarnya, kedua-dua konsep ini berlainan, akan tetapi dengan Python, kedua-duanya dipanggil "fungsi" (oleh sebab kedua-duanya diberi definisi dan digunakan dengan cara yang lebih kurang sama).
Dalam bahasa-bahasa pengaturcaraan lain, apa perbezaan antara fungsi dan prosedur? Anda telah lihat dalam bahagian terdahulu yang fungsi memulangkan nilai. Perbezaan terletak pada hakikat yang prosedur tidak memulangkan nilai. Dalam banyak keadaan, pembahagian fungsi kepada dua jenis – yang memulangkan nilai dan yang tidak memulangkan nilai – amat berguna.
Sebuah fungsi yang tidak memulangkan nilai (yakni, "prosedur") digunakan sebagai subprogram atau subrutin. Kita panggil fungsi, dan program akan melakukan sebuah tugas. Kiat dapat menggunakan fungsi ini di banyak tempat tanpa menulis kod semula. (Ini dipanggil penggunaan semula kod (code reuse) – maklumat lanjut kemudian.)
Kebergunaan fungsi (ataupun prosedur) sedemikian terletak pada kesan sampingannya – ia mengubah sektarannya. Mari kita lihat sebuah contoh:
def helo(siapa):
print "Helo,", siapa
helo("dunia")
# Mencetak "Hello, dunia"
Pencetakan dikira sebagai kesan sampingan, dan oleh sebab itu sahajayang dilakukan fungsi ini, ia sama dengan prosedur. Tetapi... ia tidak menukar sekir=tarannya bukan? Bagaiman dapat ia melakukan itu? Mari kita cuba:
# Cara yang *salah* untuk melakukannya
umur = 0
def tetapUmur(a):
umur = a
tetapUmur(100)
print umur
# Mencetak "0"
Apa yang tak kena di sini? Masalahnya ialah fungsi tetapUmur
membuat pemboleh ubah lokalnya sendiri, juga dinamakan umur
yang hanya dilihat dalam tetapUmur. bagaimana dapat kita mengelakkan itu daripada berlaku? Kita guna sesuatu yang disebut "pemboleh ubah global" (global variable).
Nota: Pemboleh ubah global tidak banyak digunakan dengan Python. Pemboleh ubah sedemikian boleh membawa kepada struktur salah, atau apa yang dipanggil kod spageti. Saya gunakan pemboleh ubah global di sini kerana mahu mengutarakan teknik-teknik yang kompleks & ndash; tolong elakkan pemboleh ubuh global jika boleh.
Dengan memberitahu pentafsir yang sesuatu pemboleh ubah itu global (melalui sebuah pernyataan seperti global umur
) kita sebenarnya memberitahu pentafsir untuk menggunakan pemboleh ubah yang berada di luar fungsi; sepatutnya fungsi tersebut membuat pemboleh ubah lokal baru. (Jadi, ia menjadi global, dan bukan lokal.) Program dapat ditulis semual seperti ini:
# Cara betul, tapi tak sempurna
umur = 0
def tetapUmur(a):
global umur
umur = a
tetapUmur(100)
print umur
# Mencetak "100"
Apabila anda mempelajari objek (lihat bawah), anda akan melihat yang cara yang lebih sesuai untuk melakukan ini adalah dengan menggunakan objek dengan sifat (property) umur dan kaedah (method) tetapUmur. Dalam bahagian tentang struktur data, anda juga akan ketemu beberapa contoh fungsi yang mengubah sekitarannya.
Baiklah, bagaimana pula dengan fungsi sebenar? Apakah fungsi sebenarnya? Fungsi matematik mirip sebuah "mesin" yang mendapatkan input dan menghitung hasilnya. Ia akan memulangkan hasil yang sama selagi ia diberikan input yang sama. Misalnya:
def kuasa_dua(x):
return x*x
Ini sama dengan fungsi matematik f(x)=x^2.
. Ia bertindak seperti fungsi yang sebenar, kerana ia hanya bergantung pada inputnya dan ia tidak menukar sekitarannyadalam apa jua cara.
Jadi – saya sudah menggariskan dua cara untuk membuat fungsi: Satu jenis lebih mirip prosedur, dan tidak memulangkan hasilnya; satu lagi lebih mirip fungsi matematik dan tidak melakukan apa-apa selain memulangkan hasilnya (hampir kesemuanya). Sudah tentu tidak mustahil untuk melakukan sesuatu di antara kedua-dua pelaksanaan yang bertentangan ini, mahupun apabila fungsi mengubah keadaan, perlulah jelas yang ia mengubahnya. Anda dapat melakukan ini dengan namanya, misalnya dengan menggunakan kata nama buat fungsi "tulen" (misalnya umur
) dan kata bentuk imperatif untuk fungsi yang mirip prosedur, seperti tetapUmur
.
Ramuan tambahan — struktur data
[sunting]Baik — setakat ini anda sudahpun banyak yang anda tahu: bagaimana mendapatkan input dan memberi output, bagaimana membina algoritme kompleks (program) dan bagaimana melaksanakan hitungan aritmetik; bamun, yang paling baik masih belum diselami.
Apakah jenis bahan yang telah kita gunakan sehingga sekarang? Nombor dan rentetan. Betul? agak membosankan... Baik, mari kita perkenalkan beberapa bahan yang lebih menarik.
Struktur-struktur data adalah ramuan yang memberi struktur ataupun membina data (amat memeranjatkan... :) ) Sebuah nombor tunggal sebenarnya tidak mempunyai struktur, bukan begitu? Tapi katalah kita mahu meletakkan lebih banyak nombor dalam sebuah bahan – itu akan memiliki sedikit struktur. Misalnya kita mungkin mahu sebuah senarai nombor. Itu mudah:
[3,6,78,93]
Saya ada menyebut senarai dalam bahagian yang berkaitan dengan gelung, akan tetapi saya tidak bercakap banyak tentang senarai. Baiklah – ini caranya anda membuat senarai. Senaraikan sahaja unsur-unsur yang dibezakan oleh tanda koma dan letakkan dalam tanda kurungan siku seperti di atas.
Mari kita selami sebuah contoh yang menghitung nombor perdana (nombor yang hanya dapat dibahagikan sendiri ataupun 1):
# Hitung semua nombor perdana yang kurang daripada 1000
# (Bukan cara yang terbaik melakukannya, tetapi...)
keputusan = [1]
calon = range(3,1000)
base = 2
hasil = base
while calon:
while hasil < 1000:
if hasil in calon:
calon.remove(hasil)
hasil = hasil+base
keputusan.append(base)
base = calon[0]
hasil = base
del calon[0]
keputusan.append(base)
print keputusan
Perkara-perkara baharu dalam contoh ini...
- Fungsi yang terbina dalam Python,
range
("julat") sebenarnya memulangkan sebuah senarai yang dapat digunakan sama seperti senarai lain. (Ini termasuk indeks pertama, akan tetapi bukan yang terakhir.) - Sebuah senarai boleh digunakan sebagai pemboleh ubah logik. Jika ia tidak kosong, ia dikira benar. Jika ia kosong, ia palsu. Justeru, ungkapan "while calon" bermaksud "sementara senarai bernama calon tidak kosong" atau lebih mudah lagi, "sementara masih ada calon".
- Anda boleh menulis "if ('jika') sebuahUnsur in ('ada dalam') sebuahSenarai untuk memeriksa sama ada sesuatu unsur terdapat dalam sesebuah senarai.
- Anda boleh tulis sesuatuSenarai.remove(sesuatuUnsur) untuk menyingkir (P: 'remove' yang bermaksud buang atau singkir) sesuatuUnsur daripada sesuatuSenarai.
- Anda boleh tambah (append) sebuah unsur pada senarai dengan menggunakan sesuatuSenarai.append(sesuatu benda). Sebenarnya, anda juga boleh menggunakan fungsi
+
(seperti dalam cebisan kod sesuatuSenarai = sesuatuSenarai+[sesuatu benda]) namun cara begini tidak berapa cekap. - Anda boleh dapatkan unsur sesebuah senarai dengna memberikan posisinya sebagai nombor (perhatikan yang unsur pertama terletak pada posisi 0) dalam kurungan siku selepas nama senarai. Justeru sesuatuSenarai[3] menunjuk kepada unsur keempat dalam senarai yang bernama sesuatuSenarai. (Lebih banyak tentang ini di bawah.)
- Anda boleh membuang atau menyingkir pemboleh ubah dengan menggunakan kata kunci
del
. Ia juga boleh digunakan (seperti di sini) untuk menyingkir unsur daripada senarai. Justeru sesuatuSenarai[0] menyingkirkan unsur pertama daripada sesuatuSenarai. Jika senarai berupa [1,2,3] sebelum penyingkiran, ia menjadi [2,3] selepasnya.
Sebelum kita menerangkan misteri-misteri pengindeksan senarai, saya akan berikan penerangan ringkas tentang contoh.
Ini adalah versi sebuah logaritme kuno bergelar Sieve of Erastothenes ("Penapis Erastothenes"). Ia memeriksa sebuah set (atau dalam kes ini, sebuah senarai) calon-calon nombor, dan kemudian membuang nombor yang diketahui bukan nombor perdana secara sistematik. Bagaimana kita tahu? Oleh sebab calon nombor ini adalah hasil dua nombor lain.
Kita bermula dengan senarai calon yang mengandungi nombor [2..999] — kita tahu yang 1 adalah nombor perdana dan kita mahukan sebuah nombor perdana yang kurang daripada 1000. (Sebenarnya, senarai calon kita adalah [3..999], akan tetapi 2 juga calon, memandangkan yang ia merupakan asas (base) pertama kita. Kita juga ada sebuah senarai yang dipanggil "keputusan" yang sentiasa mengandungi keptusan mutakhir. Sebagi permulaan, senarai ini hanya mengandungi nombor 1. Kita juga ada pemboleh ubah yang dipanggil "asas". Bagi setiap lelaran ("pusingan") algoritme, kita buang semua nombor yang merupakan angka kandungan nombor asas ini (yang sentiasa yang paling kecil dalam kalangan calon). Selepas etiap lelaran, kita tahu yang nombor terkecil yang tinggal ialah nombor perdana (oleh sebab semua nombor yang merupakan hasilan nombor-nombor kecil sudah disingkirkan — dapat tak?). Justeru, kita tambahkannya pada keputusan , tetapkan asas pada nombor ini, dan buangnya daripada senarai calon (agar kita tidak memprosesnya sekali lagi.) Apabila senarai calon menjadi kosong, senarai keputusan akan mengandungi kesemua nombor perdana. Pintar, bukan?
Perkara-perkara yang harus difikirkan: Apa yang istimewa tentang lelaran pertama? Di sini asasnya adalah 2, akan tetapi ia juga dibuang dalam proses "penapisan". Mengapa? Kenapa ini tidak berlaku dengan asas-asas lain? Bolehkah kita pasti yang keputusan sentiasa berada dalam senarai calon semasa kita mahu membuangnya?
Sekarang — apa berikutnya? Ah, ya... Pengindeksan. Dan penghirisan. Ini merupakan cara-cara untuk mendapatkan unsur individu dalam senarai Python. Anda sudahpun melihat pengindeksan biasa. Ia mudah sahaja, an sebenarnya saya sudahpun memaklumkan anda semua perihalnya melainkan satu perkara: Indeks negatif bermula dari penghujung senarai. Jadi, sesuatuSenarai[-1] ialah unsur terakhir sesuatuSenarai, sesuatuSenarai[-2] ialah unsur sebelumnya, dan seterusnya.
Walau bagaimanapun, penghirisan seharusnya merupakan perkara baharu buat anda. Ia mirip pengindeksan, melainkan, dengan penghirisan anda boleh menyasarkan kesemua hirisan senarai, dan bukan sahaja sebuah unsur. Bagaimana ia dilakukan? Seperti ini:
makanan = ["sosej","sosej","telur","burger","sosej"]
print makanan[2:4]
# Mencetak "[ʼtelurʼ, ʼsosejʼ]"
Pengabstrakan tambahan — Objek dan Pengaturcaraan Berorientasi Objek
[sunting]Ini ungkapan yang amat popular: "Pengaturcaraan Berorientasi Objek."
Sebagai yang dibayangkan oleh tajuk bahagian ini, pengaturcaraan berorientasi objek (OOP) tidak lebih daripada satu lagi cara untuk pengabstrakan dan mengurangkan butir-butir semasa menulis program. Prosedur-prosedur mengabstrak pernyataan mudah kepada operasi-operasi kompleks dengan memberi pernyataan-pernyataan ini sebuah nama. Dalam OOP, kita bukan sahaja mengendali operasi-operasi sebagai operasi, tetapi sebagai objek. Misalnya, jika kita ingin membuat program yang memasak daging, daripada menulis banyak prosedur yang berkaitan dengan suhu, masa, bahan dll, kita boleh menggabungkannya ke dalam sebuah objek-daging. ataupun, mungkin kita boleh membuat objek-ketuhar dan objek-jam... dengan cara ini suhu boleh menjadi atribut objek-daging, sementara masa boleh dibaca dari objek-jam. Dan agar program kita dapat melakukan sesuatu, kita boleh objek kita beberapa kaedah; misalnya ketuhar mungkin tahu bagaimana memasak daging, dll.
Jadi, bagaimana kita laksanakan ini dengan Python? Kita tidak boleh membuat objek secara langsung. daripada membuat ketuhar, kita buat resipi yang memerikan ketuhar. Resipi ini kemudian memerikan kelas objek-objek yang kita panggil ketuhar. Kelas ketuhar yang paling mudah mungkin:
class Ketuhar:
def masukkanSate(self, sate):
self.sate = sate
def dapatkanSate(self):
return self.sate
Nah, adakah ini kelihatan pelik?
Perkara-perkara baharu dalam contoh ini...
- Kelas objek diberi definisi dengan kata kunci
class
. - Nama-nama kelas lazimnya bermula dengan huruf besar, sementara nama-nama fungsi dan pemboleh ubah (dan juga kaedah dan atribut) bermula dengan huruf kecil.
- Method (yakni fungsi atau operasi yang digunakan ibjek) diberi definisi dengan cara yang sama,akan tetapi dalam blok kelas.
- Semua kaedah objek perlu ada parameter pertama yang dipanggil
self
(ataupun sesuatu yang agak sama, misalnyadiri
). Sebabnya akan kelihatan jelas sebentar lagi. - Atribut dan kaedah sesebuah objek dicapai seperti berikut:
sateSaya.suhue = 2, atau sate.dengan_ketupat().
Saya agak masih ada perkara yang masih kabur tentang contoh di atas. Misalnya, apakah benda yang dipanggil "self"? Dan, sekarang kita ada resipi objek (yakni, class
), bagaimana kita membuat objek?
Mari kita tangani hujah terakhir itu dulu. Sebuah objek diwujudkan dengan memanggil nama kelas (classname) sama seolah-olah ia sebuah fungsi:
ketuharSaya = Ketuhar()
ketuharSaya sekarang mengandungi sebuah objek Ketuhar, lazimnya dipanggil tika (instance) kelas Ketuhar. Katakan kita juga sudah membuat sebuah kelas bernama Sate; kita boleh lakukan seperti berikut:
sateSaya = Sate()
ketuharSaya.masukkanSate(sateSaya)
ketuharSaya.sate sekarang akan mengandungi sateSaya. Mengapa? Kerana, apabila kita memanggil satu daripada kaedah sesuatu objek, parameter pertama, lazimnya dipanggil "self" [P: boleh juga dipanggil "diri", "gua" dan sebagainya, tetapi lebih mudah jika dikekalkan "self"] sentiasa mengandungi objek itu sendiri. (Bijak, bukan?) Jadi, baris self.sate = sate
menetapkan atribut sate milik objek Ketuhar semasa pada nilai parameter sate. Perhatikan bahawa benda-benda ini berbeza, mahupun memiliki nama "sate" dalam contoh ini.