Python Segera/Python Segera

Ini adalah kursus segera tentang bahasa pengaturcaraan Python. Untuk pelajaran lenbih lanjut, baca dokumentasi yang terdapat di tapak Python, khususnya tutorial rasmi. Jika anda bertanya mengapa anda harus berminat tentangnya lihat perbandingan Python dengan bahasa-bahasa pengaturcaraan lain.

Pengenalan ataupun pengantar ini sudahpun diterjemahkan ke dalam beberapa bahasa, termasuk bahasa Portugis, Itali, Sepanyol, Rusia, Perancis, Lithuania, Jepun, Jerman, dan Yunani. Buat masa ini ia juga sedang diterjemahkan ke dalam bahasa Norway, Poland dan Korea. Oleh sebab dokumen ini masih mungkin berubah, terjemahan-terjemahan tersebut berkemungkinan tidak merupakan terjemahan mutakhir.

Nota : Agar contoh-contoh yang diberikan dapat berfungsi dengan betul, tulis program-program dalam fail [w:teks biasa teks biasa] dan laksanakan programdengan pentafsir; jangan laksanakan secara langsung dengan pentafsir – bukan semua yang akan bekerja. (Sila jangan tanya saya tentang butirannya! Saya mendapat terlalu banyak e-mel tentang perkara ini ... Periksa dokumentasi, ataukirimkan e-mel kepada help@python.org).

Sebagai permulaan, fikirkan Python sebagai sebuah pseudokod. Ini hampir benar. Pemboleh ubah tidak memiliki jenis (type) jadi anda tidak perlu mengisytiharkannya. Pemboleh ubah muncul apabila anda mengumpukkannya, dan lenyap jika anda tidak menggunnya lagi. Umpukkan dilakukan dengan operator =. Kesamaan diuji dengan operator ==. Anda dapat mengumpukkan beberapa pemboleh ubah sekali gus:

x,y,z = 1,2,3

pertama, kedua = kedua, pertama

a = b = 123

Blok kod dibatasi oleh pengengsotan, dan hanya oleh pengengsotan. (Tidak ada BEGIN/END atau tanda kurungan).

Struktur kawalan yang sering diketemui termasuk:

if x < 5 or (x > 10 and x < 20):
    print "Nilainya OK."

if x < 5 or 10 < x < 20:
    print "Nilainya OK."

for i in [1,2,3,4,5]:
    print "Ini bilangan lelaran nombor", i

x = 10
while x >= 0:
    print "x masih bukan negatif."
    x = x-1

Contoh-contoh pertama dan kedua sama.

Pemboleh ubah indeks yang diberikan dalam gelung for melakukan lelaran unsur-unsur sesebuah senarai (list) (seperti yang diberikan dalam contoh). Untuk membuat gelung "biasa" (yakni sebagai gelung penghitung), gunakan "fungsi" (function) range() (julat).

# Cetak nilai-nilai dari 0 hingga 99 terangkum.

for nilai in range(100):
    print nilai

(Baris yang bermula dengan # ialah ulasan atau (comment), dan diabaikan oleh pentafsir.)

OK; sekarang anda sudah pengetahun yang mencukupi (dalam teori) untuk melaksanakan apa jua algoritme dengan Python. Mari kita tambah sedikit interaksi pengguna. Untuk mendapatkan input (dari prom teks), gunakan fungsi input yang terbina dalam Python.

x = input("Sila masukkan nombor: ")
print "Kuasa dua nombor itu adalah", x*x

Fungsi input memaparkan prom yang diberikan (yang mungkin tidak mengandungi apa-apa) dan yang membolehkan si pengguna untuk memasukkan apa jua nilai Python yang sah. Dalam kes ini kita menjangkakan nombor – jika terdapat sesuatu yang lain (seperti rentetan atau string) dimasukkan, program akan terhenti. Bagi mengelakkan itu, kita perlukan pemeriksaan ralat. Saya tidak akan membincangkan itu dengan panjang lebar di sini; memadai dengan berkata yang jika anda mahukan input pengguna distor secara verbatim sebagai sebuah rentetan (agar apa jua dapat menjadi input) gunakan fungsi raw_input. Jika anda mahu menukar rentetan s kepada integer, anda boleh menggunakan int(s).

Nota: Jika anda mahu memasukkan rentetan sebagai input, si pengguna perlu menggunakan tanda petikan [P: ', atau " secara tersurat. Dengan Python, rentetan boleh dikurung dengan tanda kurungan tunggal atau berganda.

Jadi, kita sudah membincangkan struktur kawalan, input dan output – sekarang kita perlukan struktur data. Yang paling mustahak adalah "senarai" dan "kamus" (dictionary). Senarai ditulis dengan menggunakan tanda kurung siku, dan boleh (sudah tentunya) disarangkan:

nama = ["Sabun", "Mat"]

x = [[1,2,3],[y,z],[[[]]]]

Satu perkara yang menarik dengan senarai adalah anda dapat mencapai unsur-unsur senarai berasingan, atupun secara berkumpulan, dengan menggunakan pengindeksan (indexing) dan penghirisan (slicing). Pengindeksan dilakukan (seperti dilakukan dengan banyak bahasa lain) dengan menambah indeks dalam tanda kurung pada senarai. (Perhatikan bahawa unsur pertama memiliki indeks 0).

print nama[1], name[0] # Mencetak "Mat Sabun"

nama[0] = "Kulop"

Penghirisan hampir sama dengan pengindeksan, melainkan anda memberi kedua-dua indeks permulaan dan pengakhiran keputusan dengan tanda titik bertindih (':') yang mengasingkan indeks-indek tersebut:

x = ["sate","sate","sate","sate","sate","timun","dan","sate"]

print x[5:7] # Mencetak senarai ["timun","dan"]

Perhatikan yang pengakhirannya tidak terangkum. Jika satu daripada indek digugurkan, Python akan menganggap yang mahu mahukan kesemua yang terdapat dalam arah itu. Yakni, list[:3] bermaksud "setiap unsur dalam senarai sehinggalah unsur ketiga (3), tidak terangkum." (Boleh dikatakan yang ia sebenarnya bermaksud unsur 4, memandangkan pengiraan bermula dengan 0...aduhai.) Sebaliknya, list[3:] akan bermaksud, "setiap unsur dari senarai, bermula dengan unsur 3 (terangkum) sehingga, dan termasuk, yang akhir." Untuk mendapatkan keputusan yang menarik, anda juga boleh menggunakan nombor negatif: list[-3] adalah unsur ketiga dari akhir senarai...

Sambil kita membincangkan pengindeksan, anda mungkin juga berminat untuk mengetahui yang fungsi terbina len memberikan anda panjang senarai.

Baiklah, sekarang – bagaimana pula dengan kamus? Secara mudah, kamus mirip senarai, hanya kandaungan kamus tidak tertib. Bagaimana pula anda melakukan pengindeksan terhadap kamus? jawapannya adalah, setiap unsur mempunyai kinci (key), atau "nama" yang dapat digunakan untuk menggelintar unsur, sama dengan kamus sebenar.

Beberapa contoh kamus:

{ "Alice" : 23452532, "Boris" : 252336,
  "Clarice" : 2352525, "Doris" : 23624643}

orang = { ʼnama pertamaʼ: "Hang", ʼnama akhirʼ: "Tuah",
           ʼpekerjaanʼ: "Laksamana" }

Untuk mendapatkan pekerjaan seseorang itu, kita gunakan ungkapan orang["pekerjaan"]. Jika kita mahu menukar nama keduanya, kita boleh tulis:

orang[ʼnama terakhirʼ] = "Jebat"

Mudah, bukan? Sama dengan senarai, kamus juga boleh mengandungi kamus lain. Ataupun senarai. Dan tentulahlah senarai juga boleh mengandungi kamus. Dengan cara ini, anda dapat membina struktur data yang agak maju.

Fungsi

sunting

Langkah selanjutnya: Pengabstrakan. Kita mahu memberikan nama kepada sesebuah kod, dan memanggilnya dengan beberapa parameter. Dengan kata lain, kita mahu memberi definisi pada sesuah fungsi (ataupun "prosedur"). Ini mudah. Gunakan kata kunci def seperti di bawah:

def segi_empat_sama(x):
    return x*x

print segi_empat_sama(2) # Mencetak angka 4

Buat anda yang memahaminya: Apabila anda menghulurkan parameter kepada fungsi, anda mengikat (bind) parameter pada nilai, justeru mewujudkan sebuah rujukan baharu. Jika anda mengubah "kandungan" nama parameter ini (yakni, mengikat semula, rebind), anda tidak mengusik yang asal. Ini bekerja macam dengan [[w:Java|Java],misalnya. Mari kita lihat sebuah contoh:

x = [1,2,3] # Senarai

def ubah(sebuah_senarai):
    sebuah_senarai[1] = 4

ubah(x)
print x # Mencetak [1,4,3]

Seperti anda dapat lihat, senarai asal dihulurkan kepada fungsi, dan jika fungi mengubahnya, perubahan ini dibawa ke tempat fungsi itu dipanggil. Bagaimanapun, perhatikan kelakuan dalam contoh berikut:

def tak_tukar(x):
    x = 0

y = 1
tak_tukar(y)
print y # Mencetak angka 1

Mengapa sekarang tidak ada perubahan? Oleh sebab kita tidak menukar nilai! Nilai yang dihulurkan ialah angka 1 – kita tidak boleh mengubah nombor sama seperti kita mengubah senarai. Nombor 1 adalah (dan akan kekal) nombor 1. Apa yang telah kita lakukan adalah mengubah kandungan p[emboleh ubah lokal (parameter) x, dan ini tidak di bawa kepada sekitaran.

Buat sesiapa yang tidak memahami ini: Jangan risau – ia agak mudah jika anda tidak terlalu memikirkannya :)

Python memiliki banyak perkara pintar seperti argumen ternama dan argumen lalai dan dapat menggalas beberapa argumen buat fungsi tunggal. Untuk maklumat lebih tentang ini, lihat tutorial rasmi Python (seksyen 4.7).

Jika anda mengetahui bagaimana mahu menggunakan fungsi secara am, asasnya ini adalah apa yang anda perlu tahu tentang fungsi dengan Python. (Oh, ya... katakunci return menghentikan pelaksanaan fungsi dan memulangkan nilai yang diberikan.) Namun, satu perkara yang mungkin berguna diketahui adalah hakikat yang fungsi merupakan nilai dengan Python. Jadi, jika anda ada fungsi seperi kuasa_dua, and boleh melakukan sesuatu seperti ini:

queeble = kuasa_dua
print queeble(2) # Mencetak angka 4

Untuk memanggil fungsi tanpa argumen, anda perlu ingat untuk menulis "fungsi_lakukan()" dan tidak "fungsi_lakukan". Yang terkemudian itu, seperi yang ditunjukkan, hanya memulangkan fungsi itu sendiri, sebagai sebuah nilai. (Ini juga sama dengan methods dengan objek...Sila lihat di bawah.)

Objek dan Perkara Lain

sunting

Saya anggap yang anda tahu bagaimana pengaturcaraan berorientasi objek bekerja. (Jika tidak, bahagian ini mungkin tidak akan bermakna buat anda. Tidak ada masalah...Mulakan bermain dengan objek-objek ini :).) Dengan Python, anda memberi definisi kelas dengan (berteriak!) kata kunci class seperti berikut:

# P: Jangan lupa memastikan pengengsotan kod

class Bakul:

    # Jangan lupa dengan argumen *self* 
    def __init__(self,kandungan=None):
        self.kandungan = kandungan or []

    def add(self,unsur):
        self.kandungan.append(unsur)

    def cetak_saya(self):
        keputusan = ""
        for unsur in self.kandungan:
            keputusan = keputusan + " " + `unsur`
        print "Mengandungi:"+keputusan

Perkara-perkara baharu di sini:

  1. Semua kaedah atau method (fungsi dalam sesebuah objek) menerima argumen tambahan pada permulaan senarai argumen, yang mengandungi objek itu sendiri. (Disebut "self" dalam contoh ini, mengikut kelazimannya.)
  2. Method dipanggil macam ini: objek.kaedah(arg1, arg2) ( object.method(arg1,arg2).
  3. Beberapa nama method, seperti __init__ (dengan dua tanda garisan bawah sebelum dan selepas), diberi definisi dalam bahasa, dan membawa maksud khusus. __init__ ialah nama pembina (constructor) kelas, yakni ia merupakan fungsi yang dipanggil apabila anda membuat tika.
  4. Beberapa argumen menjadi opsyen dan diberi nilai lalai (seperti disebutkan sebelum ini, di bawah bahagian fungsi). Ini dilakukan dengan menulis definisi fungsi seperti: def contoh(umur=32): .... Di sini, contoh dapat dipanggil dengan sifar atau satu parameter. Jika tiada parameter digunakan, parameter umur akan mengambil nilai 32.
  5. "Logik pintas." Ini bahagian yang pintar... Lihat bawah.
  6. Tanda backquote (`) mengubah sesuatu objek kepada wakil rentetannya. (Jadi, jika sesuatu unsur itu mengandungi nombor 1, `unsur` sama dengan "1", sementara 'unsur' adalah rentetan literal.
  7. Tanda tambah ( + ) digunakan untuk menjerait (conctenate) senarai, dan rentetan sebenarnya senarai aksara (yang bermaksud anda boleh menggunakan pengindeksan dan penghirisan dan juga fungsi len terhadap rentetan. Cool! bukan?)

Tidak ada method atau pemboleh ubah ahli (member variable) yang dilindungi (protected) mahupun persendirian (private atau seumpamanya) dengan Python. Dengan Python pengkapsulan lebih pada gaya pengaturcaraan. (Jika nada betul-betul memerlukannya, terdapat beberapa resam penamaan yang boleh membenarkan pengkapsulan :)).

Sekarang, tentang logik pintas...

Dengan Python, semua nilai boleh digunakan sebagai nilai logik. Beberapa nilai yang "kosong", seperti [], 0 "" dan None mewakili kepalsuan logikal (logical falsity), sementara nilai-nilai lain (seperti [0], 1 atau "Helo, dunia") mewakili kebenaran logikal (logical truth).

Sekarang, ungkapan logik seperti a and b dinilai seperti berikut: Pertama, periksa sama ada a benar. Jika tidak benar, pulangkannya. Jika benar, pulangkan b(yang akan mewakili nilai kebenaran ungkapan.) Logik sepadan buat a or b adalah: Jika a benar, pulangkannya. Jika tidak benar, pulangkan b.

Mekanisme ini membuat and dan> or berfungsi seperti operator boolean yang sepatutnya dilaksanakan operator-operator tersebut, akan tetapi operator-operator ini juga membolehkan anda menulis ungkapan bersyarat yang pendek dan manis. Misalnya, pernyataan

if a:
    print a
else:
    print b

dapat ditulis:

print a or b

Sebenarnya, ini merupakan idiom Python, jadi eloklah anda membiasakan diri dengannya. Inilah yang kita lakukan dalam Bakul.__init__. Kandungan argumen memiliki nilai lalai None (yang antara lain, bermaksud nilai palsu). Jadi, untuk memeriksa sama ada ia memiliki nilai, kita boleh tulis:

if kandungan:
    self.kandungan = kandungan
else:
    self.kandungan = []

Sudah tentu, sekarang anda tahu cara yang lebih baik untuk menulisnya. Dan mengapa kita memberinya nilai lalai []? Sebab, dengan cara pelaksanaan Python, ini akan memberikan semua Bakul senarai kosong yang sama buat kandungan lalai. Apabila sahaja satu daripada Bakul diisi, kesemua Bakul akan mengandungi unsur-unsur yang sama, dan lalai tidak akan kekal sebagai kosong lagi... Untuk mengetahui ini dengan lebih lanjut, anda harus baca dokumentasi dan cari perbezaan antara kepercaman (identity) dan kesamaan (equality).

Satu cara lain untuk melaksanakan yang atas adalah:

def __init__(self, kandungan=[]):
    self.kandungan = kandungan[:]

Dapatkah anda agak bagaimana kod ini bekerja? Kita tidak menggunakan senarai kosong di seluruh tempat, akan sebaliknya kita gunakan ungkapan kandungan[:] untuk membuat salinan. (Kita menghiris seluruh senarai.)

Jadi, untuk membuat kelas Bakul dan menggunanya (yakni memanggil beberapa method terhadapnya) kita lakukan seperti berikut:

b = Bakul(['epal','oren'])
b.add('limau')
b.cetak_saya()

Terdapat method magis lain selain daripada __init__. Satu daripadanya ialah __str__ yang memberi definisi bagaimana objek akan kelihatan jika ia dibuat seperti rentetan. Kita dapat menggunakan ini untuk bakul kita selain daripada cetak_saya:

def __str__(self):
    result = ""
    for element in self.contents:
        result = result + " " + `element`
    return "Contains:"+result

Sekarang, jika kita mahun mencetak bakul b, kita boleh gunakan:

print b

Cool, bukan?

Membuat subkelas dilakukan begini:

class SpamBakul(Bakul):
    # ...

Python membenarkan pewarisan berganda (multiple inheritance), jadi anda boleh membuat beberapa kelas super (superclass) yang diletakkan dalam kurungan dan diasingankan dengan koma. Penseketikaan (instantiation) kelas dilakukan begini:

 x = Bakul()

Seperti yang saya katakan, pembina dixipta dengan memberi definisi fungsi khas ahli __init__. Katakan SpamBakul mempunyai pembina __init__(self,type). Anda kemudiannya dapat membuat spam bakul begini:

y = SpamBakul("apel").

Jika anda, dalam pembina SpamBakul perlu memanggil pembina buat satu atau lebih superclass, anda dapat melakukannya begini:

Bakul.__init__(self).

Perhatikan yang anda perlu membekalkan self secara tersurat selain daripada membekalkan parameter biasa, oleh sebab __init__ superclass tidak mengetahui tika (instance) mana yang dimaksudkan.

Dan sekarang ...

Hanya beberapa perkara pada akhir tutorial. Kebanyakan fungsi dan kelas yang berguna diletakkan dalam modul, yang sebenarnya fail teks yang mengandungi kod Python. Anda boleh mengimport modul-modul ini dan menggunanya dalam program anda. Misalnya, untuk mengguna "split" daripada modul "string", anda boleh lakukan sama ada:

import string

x = string.split(y)

atau ...

from string import split

x = split(y)

Nota: Modul string jarang digunakan sekarang; anda seharusnya menggunakan x=y.split(). Untuk maklumat lanjut tentang modul perpustakaan piawai, lihat www.python.org/doc/lib. Dokumen ini mengandungi banyak perkara yang berguna.

Semua kod dalam modul/skrip dilaksanakan apabila diimport. Jika anda mahu program anda menjadi modul yang dapat diimport dan juga sebuah program yang dapat terlaksana, anda mungkin mahu meletakkan sesuatu seperti ini pada penghujung program anda:

if __name__ == "__main__": go()

Ini cara magis untuk mengatakan yang jika modul ini dilaksana sebagai skrip boleh laku (executable script) (yakni, ia tidak diimport ke dalam skrip yang lain), fungsi go harus dipanggil. Sudah tentu, anda boleh meletakkan apa sahaja selepas tanda titik berganda... :)

Dan, buat sesiapa yang mahu membuat skrip boleh laku pada sistem UN*X, gunakan baris pertama ini untuk membolehkannya terlaksana sendiri:

#!/usr/bin/env python

Akhir sekali, sedikit maklumat tentang satu konsep penting: Pengecualian (Exceptions). Sesetengah operasi (seperti pembahagian sesuatu dengan sifar ataupun membaca daripada fail yang tak wujud) akan menimbulkan ralat atau pengecualian. Anda juga dapat membuat ataupun menimbulkan pengecualian anda sendiri pada tempat-tempat yang bersesuaian dalam kod anda.

Jika tidak ada apa-apa yang dilakukan dengan pengecualian, program anda terhenti dan mencetak pesanan ralat. Anda dapat mengelak ini daripada berlaku dengan menggunakan pernyataan try/except. Sebagai contoh:

def pembahagian_selamat(a,b): #P: definisi fungsi
    try:
        return a/b
    except ZeroDivisionError:
        return None

ZeroDivisionError ialah pengecualian piawai. Dalam kes ini, anda boleh semak sama ada b itu sifar, tetapi dalam banyak kes, strategi ini tidak dapat dilaksanakan. Lagipun, jika kita tidak memiliki klausa try dalam pembahagian_selamat, dan dengan itu membuatnya satu panggilan yang berisiko, kita masih boleh lakukan sesuatu seperti ini:

try:
    pembahagian_tak_selamat(a,b)
except ZeroDivisionError:
    print "Sesuatu yang dibahagikan dengan sifar dalam pembahagian_tak_selamat"

Dalam kes-kes yang tidak sepatutnya menimbulkan masalah spesifik, akan tetapi masalah itu mungkin berlaku, penggunaan pengecualian dapat membolehkan anda untuk mengelak daripada terpaksa melakukan ujian-ujian dan sebagainya.

Bailkah, itu sahaja. Saya harap anda telah mempelajari sesuatu. Sekaran pergi bermain dengan Python. Dan ingatlah moto pembelajaran Python:"Use the source, Luke." (P: "Gunakan sumber, Luke") (Terjemahan: Baca semua kod yang anda jumpa :)) Untuk bermula, ini sebuah contoh. Ia algoritme "QuickSort" yang terkenal oleh Hoare.

Satu perkara perlu dinayatakan tentang contoh ini. Pemboleh ubah done (baris 20 dalam kod) mengawal sama ada sekatan sudah selesai menggerakkan unsur. Jadi apabila satu daripada dua gelung dalaman mahu mengakhiri jujukan silih, ia menetapkan done kepada 1 dan kemudiannya keluar dengan break (baris 28, 32, 39 dan 43 dalam kod). Mengapa gelung dalaman menggunakan break? Oleh sebab apabila gelung dalaman pertama berakhir dengan break, persoalan sama ada gelung berikutnya bermula atau tidak bergantung pada gelung utama sudah berakhir, iaitu, sama ada done telah ditetapkan kepada 1:

#P: pseudokod
sementara belum terlaksana: 
    sementara belum terlaksana:
        # lelaran sehingga "break"

    sementara belum terlaksana:
        # Hanya dilakukan jika gelung pertama tidak menetapkan "done" pada 1

Kod sama, mungkin lebih jelas, tetapi saya kira kurang cantik adalah:

#P: pseudokod
sementara belum terlaksana: 
    while 1:
        # lelaran sehingga "break"

    jika belum terlaksana:
        while 1:
            # Hanya dilaksanakan jika gelung pertama tidak menetapkan "done" pada 1

Sebab saya gunakan pemboleh ubah done dalam gelung pertama adalah saya mahu mengekalkan simetri antara kedua-dua gelung. Dengan cara ini kita dapat membalikkan susunan gelung dan algoritme masih akan bekerja.

Contoh-contoh tambahan dapat dilihat di laman tidbit milik Joe Strout.