Anda di sini

Pemrograman

Python 3 RLE BAB 4: Pengenalan Fungsi

Aditya Suranata - 17 Desember 2015 17:14:21 0

Di Python, fungsi adalah urutan pernyataan-pernyataan yang diberikan nama dan merupakan satu kesatuan. Tujuan utamanya adalah untuk membantu kita menyusun progam menjadi bilahan-bilahan yang cocok dengan bagaimana cara kita memikirkan masalahnya.

Syntax untuk mendefinisikan fungsi adalah:

def NAMA( PARAMETER ):
    PERNYATAAN

Kita bisa menggunakan nama apa saja yang kita mau untuk fungsi yang kita buat, kecuali kita tidak bisa menggunakan nama yang merupakan bagian dari keyword Python seperti yang telah dijelaskan dalam bab sebelumnya, dan namanya juga harus mengikuti aturan untuk legal identifier.

Bisa terdapat banyak pernyataan di dalam fungsi, dan penulisannya harus bertakuk ke dalam dari keyword def. Pada contoh-contoh di buku ini, kita akan menggunakan indentasi standar sebanyak empat spasi. Definisi fungsi merupakan yang kedua dari beberapa pernyataan majemuk (compound statements) yang akan kita lihat, semuanya memiliki pola sama:

  1. Baris header yang dimulai dengan sebuah keyword dan diakhiri dengan titik dua.
  2. Body yang terdiri dari satu atau banyak pernyataan Python, masing-masing bertakuk dalam jumlah yang sama -- Python style guide merekomendasikan 4 spasi -- dari baris header.

Kita sudah melihat perulangan for yang juga menggunakan pola ini.

Sekarang perhatikan lagi pada definisi fungsi, keyword yang digunakan pada header adalah def, yang kemudian diikuti oleh nama fungsi dan beberapa parameter yang diapit dengan tanda kurung. List parameter bisa saja dikosongkan, atau bisa berisi banyak parameter yang dipisahkan antara satu dengan yang lain menggunakan tanda koma. Dalam kedua kasus, baik dengan parameter atau tanpa parameter, tanda kurung tetap diperlukan. Parameter menentukan informasi apa, jika ada, yang kita harus sediakan untuk bisa menggunakan fungsi baru tersebut.

Anggap kita sedang bermain dengan turtle, dan operasi umum yang kita perlukan adalah untuk menggambar persegi. "Gambar sebuah persegi" adalah sebuah abstraksi (abstraction), atau mental pembilahan, beberapa jumlah dari langkah-langkah yang lebih kecil. Mari tulis sebuah fungsi untuk menangkap pola dari "blok bangunan" ini:

import turtle

def draw_square(t, sz):
    """Suruh turtle t menggambar sebuah kotak dari sz."""
    for i in range(4):
        t.forward(sz)
        t.left(90)


wn = turtle.Screen()        # Atur window dan atributnya
wn.bgcolor("lightgreen")
wn.title("Alex meets a function")

alex = turtle.Turtle()      # Buat alex
draw_square(alex, 50)       # Panggil fungsi untuk menggambar kotak
wn.mainloop()

Fungsi yang kita buat ini dinamakan draw_square. Ia memiliki dua parameter: pertama untuk memberitahu fungsi, turtle yang mana yang harus digerakan, dan yang kedua untuk memberitahu ukuran dari persegi yang ingin kita gambar. Pastikan kamu tahu dimana body dari fungsinya berakhir -- yang mana bergantung pada indentasi, dan baris kosong tidak berarti dalam kasus ini!

Docstring untuk dokumentasi

Jika yang paling pertama setelah header fungsi adalah sebuah string, maka itu akan ditangani sebagai sebuah docstring dan mendapatkan penanganan spesial di Python dan dalam beberapa tools pemrograman. Contohnya, ketika kita mengetik nama fungsi built-in dengan tanda kurung yang belum di tutup di PySripter, sebuah tooltip akan muncul, memberitahu kita argumen apa yang diambil oleh fungsi itu, dan akan memperlihatkan kepada kita teks lain yang juga ada dalam docstring.

Docstring merupakan kunci utama untuk mendokumentasikan fungsi kita di Python dan bagian dokumentasi tentu sangat penting. Karena siapapun yang nantinya akan memanggil fungsi kita tidak lagi mesti tahu apa yang terjadi pada fungsi atau bagaimana ia bekerja; mereka hanya perlu tahu argumen apa yang diperlukan oleh fungsi kita, apa yang dilakukan, dan apa hasil yang diharapkan akan keluar. Cukup untuk bisa menggunakan fungsi tanpa harus mengobrak-abrik barisan kode fungsi hingga ke akar-akarnya. Ini kembali lagi ke konsep dari abstraksi yang akan kita bahas lebih dalam lagi.

Docstring biasanya dibentuk menggunakan petik tiga kali, tentu karena ini akan memungkinkan kita untuk mengembangkan docstring lagi nanti seperti halnya kita ingin menulis lebih dari satu baris dokumentasi.

Untuk membedakan dengan komentar, sebuah string yang dimulai di awal fungsi (sebuah docstring) adalah dapat diterima oleh Python tools saat runtime. Sebaliknya, komentar seluruhnya dihilangkan ketika program telah di-parse.

Mendefinisikan sebuah fungsi baru tidak membuatnya langsung dijalankan. Untuk menjalankan fungsi kita perlu memanggil fungsinya (function call). Kita sudah melihat bagaimana cara memanggil beberapa fungsi built-in seperti print, range dan int. Function call berisi nama dari fungsi yang akan dieksekusi dan diikuti oleh daftar (list) beberapa nilai, dinamakan sebagai argumen, yang kemudian diberikan nilainya ke parameter dalam definisi fungsi. Jadi pada baris kedua dari akhir program, kita memanggil fungsinya, dan memasukan alex sebagai turtle yang akan dimanipulasi, dan 50 sebagai ukuran dari persegi yang kita inginkan. Sementara fungsinya dieksekusi, lalu, variabel sz mengacu ke nilai 50, dan variabel t mengacu ke instan turtle yang sama yang diacu oleh alex.

Setelah kita mendefinisikan sebuah fungsi, kita bisa memanggilnya sesering yang kita mau, dan pernyataannya akan dieksekusi setiap kali kita memanggilnya. Dan kita bisa menggunakannya untuk menyuruh turtle kita untuk menggambar sebuah persegi. Pada contoh selanjutnya, kita merubah sedikit fungsi draw_square, dan kita akan menyuruh si tess untuk menggambar 15 persegi, dengan beberapa variasi.

import turtle

def draw_multicolor_square(t, sz):
    """Suruh turtle t menggambar kotak warna-warni dari sz."""
    for i in ["red", "purple", "hotpink", "blue"]:
        t.color(i)
        t.forward(sz)
        t.left(90)

wn = turtle.Screen()        # Atur window dan atributnya
wn.bgcolor("lightgreen")

tess = turtle.Turtle()      # Buat tess dan atur beberapa atribut
tess.pensize(3)

size = 20                   # Ukuran dari kotak terkecil
for i in range(15):
    draw_multicolor_square(tess, size)
    size = size + 10        # Tambahkan ukuran selanjutnya
    tess.forward(10)        # Gerakan tess
    tess.right(18)          # Dan beri beberapa belokan

wn.mainloop()

4.2. Fungsi Bisa Memanggil Fungsi Lain

Mari asumsikan sekarang kita ingin sebuah fungsi untuk menggambar persegi panjang. Kita perlu memanggil fungsi dengan argumen berbeda untuk panjang dan lebar. Dan, tidak seperti kasus dari persegi, kita tidak bisa mengulang hal yang sama empat kali, karena keempat sisinya tidak sama.

Jadi akhirnya kita muncul dengan kode bagus ini yang bisa menggambar sebuah persegi panjang.

def draw_rectangle(t, w, h):
    """Buat turtle t menggambar sebuah persegi panjang dengan panjang w 
    dan lebar h."""
    for i in range(2):
        t.forward(w)
        t.left(90)
        t.forward(h)
        t.left(90)

Nama-nama parameter sengaja dipilih menggunakan huruf tunggal untuk memastikan mereka tidak dipahami dengan salah. Dalam program riil, ketika kita sudah punya pengalaman banyak, kita tentu akan bersikeras menggunakan nama variabel yang lebih baik dari ini. Tapi intinya adalah bahwa program tidak "mengerti" kalau kita menggambar sebuah persegi panjang, atau parameternya merepresentasikan panjang dan lebar. Konsep seperti persegi panjang, panjang, dan lebar merupakan arti yang dimiliki kita manusia, bukan konsep yang dimengerti oleh program atau komputer.

Berpikir layaknya ilmuan komputer melibatkan pencarian pola-pola dan hubungan-hubungan. Pada kode diatas, kita telah melakukan beberapa pengembangan. Kita tidak hanya menggambar empat sisi. Namun, kita menyadari kalau kita bisa menggambar persegi dalam dua bagian, dan menggnakan loop untuk mengulangi polanya dua kali.

Tapi sekarang kita mungkin menyadari kalau persegi adalah jenis spesial dari kotak. Kita sudah punya fungsi untuk menggambar sebuah persegi, jadi kita bisa menggunakannya untuk menggambar persegi kita.

def draw_square(tx, sz):        # Versi baru dari draw_square
    draw_rectangle(tx, sz, sz)

Ada beberapa poin yang perlu diperhatikan disini:

  • Fungsi bisa memanggil fungsi lainnya.
  • Menulis ulang draw_square seperti ini, akan menangkap hubungan yang telah kita lihat antara persegi dan persegi panjang.
  • Pemanggil (caller) dari fungsi ini mungkin berkata draw_square(tess, 50). Parameter dari fungsi ini, tx dan sz, masing-masing diberikan nilai dari objek tess, dan juga int 50.
  • Pada body fungsi mereka juga sama seperti fungsi lainnya.
  • Ketika dilakukan pemanggilan ke draw_rectangle, nilai dari variabel tx dan sz diambil pertama kali, lalu pemanggilan berlangsung. Jadi saat kita memasuki bagian atas dari fungsi draw_rectangle, variabel t nya diberikan nilai objek tess, dan w dan h pada fungsi tersebut keduanya diberikan nilai 50.

Sejauh ini, mungkin terasa belum jelas kenapa kita mesti membuat semua fungsi baru itu. Sebenarnya asalannya ada banyak, tapi contoh ini cukup mendemonstrasikan dua diantaranya:

  1. Membuat fungsi baru memberikan kita kesempatan untuk menamai sekumpulan pernyataan. Fungsi bisa menyederhanakan program dengan menyelipkan perhitungan rumit dibalik satu perintah. Fungsi (termasuk namanya) bisa mengasah mental pembilahan kita, atau abstraksi, dari masalah.
  2. Membuat fungsi baru bisa membuat program menjadi lebih kecil dengan menghilangkan kode-kode yang berulang.

Seperti yang kita duga, kita harus membuat fungsi sebelum kita bisa mengeksekusinya. Dengan kata lain, definisi fungsi mesti dieksekusi sebelum fungsinya dipanggil.

4.3. Flow of Execution (alur eksekusi)

Untuk memastikan kalau fungsi sudah didefinisikan sebelum penggunaan pertamanya, kita mesti tahu urutan dari eksekusi pernyataan, yang dinamakan dengan flow of execution. Kita sudah sempat membahas ini sedikit pada bab sebelumnya.

Eksekusi selalu dimulai dari pernyataan pertama dari program. Pernyataan dieksekusi sekali dalam satu hentakan, dengan urutan dari atas ke bawah.

Definisi fungsi tidak mengubah alur eksekusi dari program, tapi ingat kalau pernyataan didalam fungsi tidak dieksekusi hingga fungsi itu dipanggil. Meskipun tidak umum, kita bisa mendefiniskan satu fungsi didalam fungsi lainnya. Dalam kasus ini, definisi yang berada di dalam tidak dieksekusi hingga fungsi luarnya dipanggil.

Pada alur eksekusi, pemanggilan fungsi (function call) adalah seperti jalan memutar. Daripada pergi ke pernyataan selanjutnya, flow atau alurnya akan melompat ke baris pertama dari fungsi yang dipanggil, mengeksekusi semua pernyataan yang ada disana, dan kembali lagi untuk mengambil pekerjaan selanjutnya dimana ia sebelumnya melompat.

Itu terdengar cukup sederhana, hingga kita ingat kalau satu fungsi bisa memanggil fungsi lainnya. Sementara dalam pertengahan satu fungsi, program mungkin harus melompat lagi dan mengeksekusi pernyataan dalam fungsi lainnya. Tapi sementara fungsi lain tersebut dieksekusi, program mungkin mesti mengeksekusi fungsi lainnya lagi dan lagi!

Syukurnya, Python mahir dalam hal lacak melacak, jadi setiap kali fungsi selesai dijalankan, program akan kembali ke titik dimana ia melompat ke fungsi yang memanggilnya. Ketika sampai pada akhir dari program, ia akan mengakhirinya.

Apa moral dari kisah rumit ini? Ketika kita membaca program, jangan membaca dari atas ke bawah. Tapi, ikuti alur dari eksekusinya.

Amati flow of execution in action

Pada PyScripter, kita bisa mengamati alur dari eksekusi "langkah-demi-langkah" pada program apa saja. PyScripter akan menandai setiap baris kode yang akan dieksekusi.

PyScripter juga memungkinkan kita mengarahkan mouse ke setiap variabel dalam program, dan akan memunculkan nilai yang dipegang variabel saat ini. Jadi ini akan memudahkan kita memeriksa "state of snapshot" dari program -- yaitu nilai sekarang yang diberikan ke variabel program.

Ini adalah mekanisme yang sangat powerful untuk membangun pemahaman yang dalam dari apa yang terjadi pada setiap langkah dari jalannya program. Belajarlah untuk menggunakan fitur single-stepping dengan baik, dan tanamkan mental proaktif: dalam mengerjakan kode-kode program, tantang diri mu sendiri langkah demi langkah: "Perubahan apa yang bisa diakibatkan oleh baris ini pada setiap variabel dalam program?" dan "Kemana alur eksekusi akan melanjutkan?"

Mari kita mundur kebelakang untuk melihat bagaimana ini bekerja pada program diatas yang menggambar 15 persegi warna-warni. Pertama, kita akan menambahkan satu baris ajaib dibawah pernyataan import -- tidak terlalu penting, tapi ini akan membuat hidup kita jauh lebih mudah, karena ini akan mencegah stepping ke modul yang berisi kode turtle.

import turtle
__import__("turtle").__traceable__ = False

Sekarang kita siap untuk mulai. Letakan kursor mouse pada baris dari program dimana kita membuat screen turtle, dan tekan tombol F4. Ini akan menjalankan program Python hingga ke, tapi tidak termasuk, baris dimana kita meletakan kursornya. Program kita akan "berhenti" sekarang, dan membuat tanda pada baris berikutnya yang akan dieksekusi, yang terlihat seperti ini:

Pada poin ini kita bisa menekan tombol F7 (melangkah ke) berulangkali untuk bergerak satu langkah eksekusi. Amati ketika kita mengeksekusi baris 10, 11, 12, ... bagaimana window dari turtle dibuat, bagaimana canvasnya berubah warna, bagaimana judulnya berganti, bagaimana turtle dibuat pada canvas, dan kemudian bagaimana flow of execution bergerak memasuki loop, dan dari sana masuk ke fungsi, dan masuk lagi ke loop fungsi, dan berulang kali mengeksekusi body dari loop.

Sementara kita melakukan ini, kita bisa juga mengarahkan mousenya ke beberapa variabel pada program, dan memastikan nilai mereka cocok dengan model konseptual dan bayangan kita mengenai apa yang terjadi.

Setelah beberapa loop, ketika kita akan mengeksekusi baris 20 dan kita mulai merasa bosan mengulang-ngulang, kita bisa menggunakan tombol F8 untuk "step over / menjalankan tanpa stepping" fungsi yang kita panggil. Ini akan mengeksekusi semua pernyataan dalam fungsi, tapi tanpa melakukannya langkah demi langkah. Kita selalu punya pilihan untuk "melihat dengan detil", atau "melihat secara garis besar" dan mengeksekusi fungsi sebagai satu bilahan.

Terdapat pula beberapa pilihan lain, termasuk satu yang memungkinkan kita untuk melanjutkan eksekusi tanpa harus melakukan stepping lagi. Temukan opsi ini pada menu Run dari PyScripter.

4.4. Fungsi yang Memerlukan Argument

Kebanyakan fungsi akan memerlukan argumen: argumen-argumen menyediakan generalisasi. Contohnya, jika kita ingin mencari nilai absolut dari sebuah bilangan, kita harus menunjukan apa bilangan tersebut. Python memiliki fungsi built-in untuk menghitung nilai absolut:

>>> abs(5)
5
>>> abs(-5)
5

Dalam contoh ini, argmen untuk fungsi abs adalah 5 dan - 5.

Beberapa fungsi mengambil lebih dari satu argument. Contohnya fungsi built-in pow yang mengambil dua argumen, bilangan basis dan eksponennya. Di dalam fungsi, nilai yang dimasukan akan diberikan ke variabel yang dinamakan parameter.

>>> pow(2, 3)
8
>>> pow(7, 4)
2401

Fungsi built-in yang juga mengambil lebih dari satu argumen adalah max.

>>> max(7, 11)
11
>>> max(4, 1, 17, 2, 12)
17
>>> max(3 * 11, 5**3, 512 - 9, 1024**0)
503

max bisa dimasukan argumen bilangan apa saja, dipisahkan dengan koma, dan akan mengembalikan nilai yang paling besar. Argumennya juga bisa berbentuk nilai ekspresi sederhana. Pada contoh sebelumnya, 503 dikembalikan, karena nilainya lebih besar dari 33, 125, dan 1.

4.5. Fungsi yang Mengembalikan Nilai (return)

Semua fungsi pada sesi sebelumnya mengembalikan nilai. Lebih jauh lagi, fungsi seperti range, int, abs semua mengembalikan nilai yang bisa digunakan untuk membangun ekspresi yang jauh lebih rumit.

Jadi perbedaan terpenting antara fungsi tersebut dengan fungsi seperti draw_square adalah bahwa draw_square dieksekusi karena kita tidak menginginkan dia untuk menghitung dan mengembalikan sebuah nilai -- namun sebaliknya, kita menulis draw_square karena kita ingin mengeksekusi urutan langkah-langkah yang menyebabkan turtle menggambar.

Fungsi yang me-return / mengembalikan sebuah nilai dalam buku ini dinamakan dengan fruitful function. Lawan dari fruitful function adalah void function -- fungsi yang dieksekusi bukan untuk mendapatkan nilai, tapi dieksekusi karena ia melakukan sesuatu yang berguna. (Bahasa seperti Java, C#, C dan C++ menggunakan istilah "void function", bahasa lain seperti Pascal menamainya procedure.) Meskipun void function tidak dieksekusi untuk menghasilkan sebuah nilai, Python selalu ingin mengembalikan sesuatu, jadi jika programmer tidak menyusun sebuah nilai return, Python akan dengan otomatis mereturn dengan nilai None.

Bagaimana kita menyusun fruitful function kita sendiri? Pada latihan diakhir bab 2 kita melihat rumus standar untuk bunga berganda, yang sekarang kita akan coba tulis sebagai fruitful function:

def final_amt(p, r, n, t):
    """
    Masukan rumus bunga berganda ke p
    untuk mendapatkan jumlah akhir.
    """

    a = p * (1 + r/n) ** (n*t)
    return a         # Ini tambahan baru, yang membuat fungsi menjadi fruitful

# sekarang kita sudah punya fungsi diatas, coba kita panggil
toInvest = float(input("How much do you want to invest?"))
fnl = final_amt(toInvest, 0.08, 12, 5)
print("At the end of the period you'll have", fnl)
  • Pernyataan return diikuti dengan sebuah ekspresi (dalam kasus ini a). Ekspresi ini akan dinilai dan dikembalikan ke pemanggil sebagai "fruit/buah" dari pemanggilan fungsi ini.
  • Kita menanyakan pengguna berapa principal amount-nya (jumlah pokok). Tipe dari toInvest adalah string, tapi kita perlu tipe angka sebelum bisa menggunakannya. Karena ini adalah uang, dan bisa memiliki angka dibelakang koma, kita menggunakan konverter tipe float untuk mem-parse string dan mengembalikan sebuah float.
  • Perhatikan bagaimana kita memasukan argumen untuk interest 8%, dicicil 12 kali setahun, untuk 5 tahun.
  • Ketika kita menjalankannya, kita mendapatkan output:

At the end of the period you'll have 14898.457083

Terlihat cukup kotor dengan semua angka dibelakang komanya, tapi ingat kalau Python tidak mengerti kalau kita bekerja dengan uang: ia hanya melakukan perhitungan dengan kemampuan terbaiknya tanpa pembulatan. Nanti kita akan tahu bagaimana mem-format string sehingga bisa melakukan pembulatan dua angka sebelum mencetaknya ke layar.

  • Baris toInvest = float(input("How much do you want to invest?")) juga memperlihatkan contoh lainnya dari komposisi -- kita bisa memanggil fungsi seperti float, dan argumennya bisa merupakan hasil dari pemanggilan fungsi lainnya (seperti input) yang telah sering kita panggil.

Perhatikan hal lain yang juga sangat penting disini. Nama dari variabel yang kita masukan sebagai argumen -- toInvest -- tidak ada kaitannya dengan nama dari parameternya -- p. Artinya sama dengan p = toInvest dieksekusi ketika final_amt dipanggil. Tidak penting apa nama yang dipakai pada pemanggil (caller), pada final_amt namanya tetaplah p.

Nama singkat variabel menjadi sedikit menyulitkan, jadi mungkin kita lebih memilih menggunakan versi ini:

def final_amt_v2(principalAmount, nominalPercentageRate, numTimesPerYear, years):
    a = principalAmount * (1 + nominalPercentageRate / numTimesPerYear) ** (numTimesPerYear*years)
    return a
    
def final_amt_v3(amt, rate, compounded, years):
    a = amt * (1 + rate/compounded) ** (componded*years)
    return a

Keduanya melakukan hal yang sama. Gunakan penilaian mu untuk menulis kode yang bisa dimengerti dengan baik oleh orang lain! Variabel dengan nama singkat lebih ekonomis dan kadang membuat kode lebih mudah untuk dibaca: E = mc2 akan sangat sulit dimengeri jika Einstein menggunakan nama variabel yang lebih panjang! Jika kamu lebih suka nama singkat, maka pastikan kamu juga punya beberapa komentar untuk menjelaskan pada pembaca mengenai apa guna dari variabel tersebut.

4.6. Variabel dan Parameter Lokal

Ketika kita membuat variabel lokal di dalam sebuah fungsi, maka ia hanya akan ada di dalam fungsi tersebut, dan kita tidak bisa menggunakannya diluar. Contoh, pertimbangkan lagi fungsi berikut:

def final_amt(p, r, n, t):
    a = p * (1 + r/n) ** (n*t)
    return a

Jika kita mencoba menggunakan a, diluar fungsi, kita akan mendapatkan error seperti ini:

>>> a
NameError: name 'a' is not defined

Variabel a bersifat lokal dan berada dalam fungsi final_amt, dan tidak terlihat diluar fungsi.

Tambahan lagi, a hanya ada ketika fungsi dieksekusi -- kita menamai ini sebagai lifetime (waktu hidup / umur). Ketika eksekusi dari fungsi telah selesai, maka variabel lokal akan dihancurkan.

Parameter juga sifatnya lokal, dan berprilaku juga seperti variabel lokal. Sebagai contoh, lifetime dari p, r, n, t dimulai ketika final_amt dipanggil, dan lifetimenya berakhir ketika fungsinya selesai dieksekusi.

Jadi tidak dimungkinkan untuk sebuah fungsi mengatur beberapa variabel lokal ke sebuah nilai, menyelesaikan eksekusi, lalu kemudian ketika ia dipanggil dan dieksekusi lagi dilain waktu, ia masih menyimpan dan mengembalikan nilai dari variabel lokalnya. Setiap pemanggilan fungsi akan membuat variabel lokal baru, dan lifetimenya habis ketika fungsinya berakhir dan kembali ke pemanggil.

4.7. Turtle Revisited

Sekarang kita telah mengetahui fruitful function, kita bisa fokuskan perhatian kita untuk mengatur kode kita sehingga akan masuk lebih baik ke dalam mental pembilahan kita. Proses dari pengaturan ulang ini dinamakan dengan refactoring the code.

Dua hal yang selalu kita ingin lakukan ketika bekerja dengan turtle adalah untuk membuat window untuk turtle, dan membuat satu atau lebih turtle. Kita bisa menulis beberapa fungsi untuk membuat tugas tersebut lebih mudah nanti:

def make_window(colr, ttle):
    """
      Set up the window with the given background color and title.
      Returns the new window.
    """
    w = turtle.Screen()
    w.bgcolor(colr)
    w.title(ttle)
    return w

def make_turtle(colr, sz):
    """
      Set up a turtle with the given color and pensize.
      Returns the new turtle.
    """
    t = turtle.Turtle()
    t.color(colr)
    t.pensize(sz)
    return t

wn = make_window("lightgreen", "Tess and Alex dancing")
tess = make_turtle("hotpink", 5)
alex = make_turtle("black", 1)
dave = make_turtle("yellow", 2)

Trik dari refactoring code adalah mengantisipasi bagian mana yang perlu kita ganti setiap kali kita memanggil fungsinya: bagian-bagian itu umumnya adalah parameter, atau bagian yang bisa diganti, dari fungsi yang kita tulis.

4.8. Glosarium

argumen

Nilai yang disediakan untuk fungsi ketika fungsi dipanggil. Nilai ini diberikan ke parameter yang terkait di dalam fungsi. Argumen bisa merupakan hasil dari sebuah ekspresi yang melibatkan operator, operand dan pemanggilan ke fungsi fruitful lainnya.

body

Bagian kedua dari pernyataan manjemuk (compound statements). Body terdiri dari urutan statement / pernyataan yang semua bertakuk dengan jumlah takukan yang sama yang dimulai dari header. Jumlah indentasi / takukan standar dalam komunitas Python adalah 4 spasi.

compound statement (penyataan majemuk)

Pernyataan yang terdiri dari dua bagian:
1. header - yang dimulai dengan sebuah keyword yang menentukan tipe pernyataan, dan diakhiri dengan sebuah tanda titik dua.
2. body - berisi satu atau lebih pernyataan yang bertakuk (indented) dengan jumlah takukan yang sama dimulai dari header.
Syntax dari compound statement terlihat seperti berikut:

keyword ... :
statement
statement ...

docstring

String spesial yang dikaitkan ke sebuah fungsi sebagai atribut dokumentasi __doc___. Tool seperti PyScripter bisa menggunakan docstring untuk menyediakan dokumentasi atau petunjuk untuk programmer. Ketika kita menggunakan modul, kelas, dan metode, kita juga akan tahu kalau docstring juga digunakan disana.

flow of execution

Urutan dari statement yang dieksekusi selama program berjalan.

frame

Sebuah kotak dalam diagram stack yang merepresentasikan pemanggilan fungsi. Ia berisi variabel lokal dan parameter dari fungsi.

function (fungsi)

Urutan pernyataan yang diberikan nama dan melakukan operasi yang berguna. Fungsi bisa memerlukan atau tidak memerlukan parameter dan menghasilkan atau tidak menghasilkan sebuah hasil.

function call (pemanggilan fungsi)

Pernyataan yang mengeksekusi sebuah fungsi. Ia terdiri dari nama fungsi diikuti dengan daftar argumen yang diapit oleh tanda kurung.

function composition

Menggunakan output dari satu pemanggilan fungsi sebagai input untuk fungsi lainnya.

function definition

Pernyataan yang membuat fungsi baru, menentukan namanya, parameter, dan pernyataan yang dieksekusinya.

fruitful function

Fungsi yang me-return / mengembalikan sebuah nilai ketika ia dipanggil.

header line (baris header)

Bagian pertama dari compound statement. Baris header dimulai dengan sebuah keyword dan diakhiri dengan sebuah tanda titik dua (:).

import statement

Pernyataan yang mengijinkan fungsi dan variabel yang didefinisikan dalam modul Python lain agar masuk ke lingkungan dari script lain. Untuk menggunakan fitur dari turtle, kita pertama-tama mesti mengimport modul turtle.

lifetime (waktu hidup / umur)

Variabel dan objek memiliki lifetime -- mereka dibuat pada suatu titik selama eksekusi program, dan akan dihancurkan pada suatu waktu atau ketika eksekusi berakhir.

local variable (variabel lokal)

Variabel yang didefinisikan didalam sebuah fungsi. Variabel lokal hanya bisa digunakan didalam fungsinya sendiri. Parameter dari sebuah fungsi adalah jenis spesial dari variabel lokal.

parameter

Nama yang digunakan didalam sebuah fungsi untuk mengacu pada nilai yang dimasukan kedalamnya sebagai sebuah argumen.

refactor

Istilah keren untuk menjelaskan penyusunan ulang kode program kita, biasanya digunakan untuk membuatnya lebih mudah dimengerti. Khususnya, kita memiliki program yang sudah bekerja, lalu kita mengopreknya kembali untuk "mengencangkannya". Proses ini umumnya melibatkan pemilihan nama variabel yang lebih bagus, atau pencarian pola-pola berulang dan memindahkan kode tersebut ke sebuah fungsi.

stack diagram

Representasi grafis dari tumpukan fungsi-fungsi, variabel mereka, dan nilai yang mereka acu.

traceback

Daftar fungsi yang dieksekusi, dan akan tercetak pada saat terjadi runtime error. Traceback umumnya juga dikaitkan dengan stack trace, karena ia mencatat urutan fungsi yang disimpan di runtime stack.

void function

Lawan dari fruitful function: jenis fungsi yang tidak me-return atau mengembalikan nilai. Ia dieksekusi untuk pekerjaan yang dilakukannya, ketimbang untuk nilai yang ia kembalikan.

4.9. Latihan

1. Tulis void function (non-fruitful) untuk menggambar sebuah persegi. Gunakan untuk menggambar gambar dibawah. Asumsikan setiap sisinya adalah 20 unit. (Petunjuk: perhatikan bahwa turtle sudah bergerak menjauh dari titik akhir dari persegi terkahir ketika programnya berakhir.)

2. Buat program untuk menggambar ini. Asumsikan kotak yang paling dalam 20 unit per sisi, dan setiap persegi baru 20 unit lebih besar, per sisi, dari persegi didalamnya.

3. Buat fungsi void draw_poly(t, n, sz) yang akan membuat turtle menggambar poligon reguler (sama sisi). Ketika dipanggil dengan draw_poly(tess, 8, 50), ia akan menggambar bentuk seperti ini:

4. Gambar pola yang cantik ini:

5. Dua spiral pada gambar berikut hanya berbeda karena sudut putarnya. Coba gambar keduanya.

6. Tulis sebuah fungsi void draw_equitriangle(t, sz) yang memanggil draw_poly dari pertanyaan sebelumnya untuk membuat turtle menggambar segitiga sama sisi.

7. Tulis fungsi fruitful sum_to(n) yang mengembalikan sum dari semua integer hingga dan termasuk n. Jadi sum_to(10) akan menjadi 1+2+3...+10 yang akan mengembalikan / me-return nilai 55.

8. Tulis sebuah fungsi area_of_circle(r) yang me-return luas lingkaran dari radius r.

9. Buat fungsi void untuk menggambar sebuah bintang, dimana panjang dari setiap sisinya adalah 100 unit. (Petunjuk: Kamu mesti memutar turtle 144 derajat pada setiap titiknya.)

10. Kembangkan program yang kamu buat tadi. Gambar 5 bintang, tapi untuk mebuat jarak, angkat pensilnya, gerakan maju 350 unit, putar kanan 144 derajat, turunkan lagi pensilnya, dan gambar bintang selanjutnya. Kamu akan mendapatkan hasil seperti ini:

Apa yang akan terjadi jika kamu tidak mengangkat pensilnya ?

3.767
Daftar Artikel Terkait
Image

Aditya Suranata

Aditya suka menulis, bukan hanya sekedar hobi, menulis menjadi medianya untuk mencurahkan pikiran dan perasaan. Di TutorKeren.com kebanyakan menyumbang tulisan sesuai dengan minat dan keahliannya yaitu pada kategori pemrograman dan elektronika. Selain itu juga gemar menulis mengenai hal-hal umum, seperti ilmu alam, sosial dan beberapa pengalamannya yang mungkin bisa berguna untuk orang lain.

Artikel Menarik Lainnya
Mari Gabung

Halo Emo 51 , Ada yang ingin disampaikan? Jangan sungkan untuk gabung diskusi ini. Silahkan Login dulu atau Daftar baru.