Functions¶
Sampai dengan sekarang, semua kode Python yang kita tulis berupa potongan-potongan kode dan dijalankan secara sendiri-sendiri. Ini mungkin berguna dan dipakai untuk eksplorasi dan eksekusi singkat, tapi jika skrip kode sudah mulai kompleks, tidak mungkin kita menulis ulang semua kode tersebut. Oleh karena itu, diperlukan suatu cara untuk mengelompokkan dan mengorganisir kode menjadi bagian-bagian yang lebih mudah untuk di kelola.
Cara pertama yang bisa dilakukan adalah mengumpulkan kode-kode yang memiliki alur dan tujuan agar bisa digunakan kembali tanpa menulis ulang kodenya ke dalam sebuah fungsi (function). Kita bisa anggap sebuah fungsi sebagai kumpulan kode yang bekerja untuk suatu tugas tertentu yang bisa menerima input apapun jenisnya dan berapapun jumlahnya, serta mengembalikan output apapun jenisnya dan berapapun jumlahnya. [Lub19]
Mendefinisikan Fungsi dengan def
¶
Untuk mendefinisikan fungsi, kita mulai dengan kata kunci def
, diikuti oleh nama fungsi (aturan penamaan sama dengan variabel), tanda kurung (()
) yang berisikan nol atau lebih parameter masukan yang diperlukan fungsi tersebut, dan diakhiri dengan :
.
Mari kita coba definisikan fungsi yang paling sederhana terlebih dahulu yang tidak memerlukan parameter masukan apapun dan tidak melakukan apapun.
def do_nothing():
pass
Note
Pernyataan pass
pada Python digunakan sebagai penampung atau placeholder untuk kode nantinya. Ketika dieksekusi, pass
tidak melakukan apa-apa, tapi kode tetap berjalan tanpa eror kekosongan kode, karena kode kosong (empty code) tidak diperbolehkan dalam sebuah perulangan, pendefinisian fungsi, pendefinisan kelas (class), atau pernyataan kondisional if
.
def do_nothing():
pass
Untuk menggunakan fungsi tersebut, kita bisa langsung panggil seperti ini.
do_nothing()
Sekarang, kita coba buat fungsi baru yang masih tidak memerlukan parameter masukan, tapi akan menampilkan suatu string dengan fungsi print
.
def make_sound():
print("moo..")
make_sound()
moo..
Fungsi make_sound
yang sudah didefinisikan, jika dipanggil, akan menampilkan string "moo.."
sesuai dengan blok kode di dalamnya.
Pernyataan return
pada Fungsi¶
Sekarang, kita coba buat fungsi yang mengembalikan sebuah nilai True
seperti di bawah ini.
def agree():
return True
agree()
True
Suatu fungsi yang memiliki pernyataan return
, akan mengembalikan sebuah nilai keluaran ke pernyataan yang memanggilnya. Pernyataan return
terdiri dari kata kunci return
yang kemudian diikuti oleh nilai balikan, dan dipisahkan dengan spasi. Jika kita ingin mengembalikan lebih dari satu nilai dari suatu fungsi, maka kita bisa tulis nilai-nilai tersebut dan dipisahkan dengan ,
, seperti return value1, value2
.
Note
Suatu fungsi yang tidak memiliki pernyataan return
, seperti pada fungsi do_nothing
ataupun make_sound
, maka nilai balikannya adalah None
.
Untuk membandingkan fungsi dengan return
dan yang tidak, mari kita coba definisikan sebuah variabel sound
dan is_agree
dengan memanggil fungsi make_sound
dan agree
secara berturut-turut.
sound = make_sound()
is_agree = agree()
moo..
Setelah kita jalankan cell di atas, kita mendapatkan tampilan moo..
yang berasal dari fungsi make_sound
. Sedangkan, variabel is_agree
tidak menampilkan apa-apa. Ini sama halnya saat kita mendefinisikan variabel sebelumnya, kita hanya memberikan nilai pada variabel.
Jika kita coba tampilkan kedua variabel tersebut dengan print
, maka sound
tidak akan menampilkan apa-apa, sedangkan is_agree
akan menampilkan nilai True
. Ini terjadi karena fungsi make_sound
tidak mengembalikan nilai apa-apa untuk disimpan dalam variabel sound
, sedangkan agree
mengembalikan nilai True
yang kemudian disimpan dalam variabel is_agree
.
print(sound)
None
print(is_agree)
True
Fungsi dengan Parameter Masukan¶
Misalkan kita ingin membuat sebuah fungsi, yang bisa gunakan berkali-kali, untuk menghitung volume sebuah silinder. Ada beberapa hal yang harus kita ketahui terlebih dahulu:
Nilai \(\Pi\)
Tinggi silinder
Jari-jari silinder
Ingat bahwa persamaan volume silinder adalah
di mana \(V\) adalah volume yang dihasilkan, \(r\) adalah jari-jari silinder, dan \(h\) adalah tinggi silinder.
Untuk membuat fungsi tersebut dengan 3 nilai yang harus diketahui terlebih dahulu, ini berarti kita bisa membuat fungsi yang membutuhkan parameter masukan, dalam hal ini yaitu r
dan h
. Nilai \(Pi\) tidak perlu kita anggap sebagai parameter karena nilainya yang selalu konstan. Sehingga, kita definisikan fungsi cylinder_volume
seperti di bawah ini.
def cylinder_volume(radius, height):
pi = 3.14159
return pi * height * radius**2
volume = cylinder_volume(10, 3)
print("Cylinder volume:", volume)
Cylinder volume: 942.4769999999999
Eksplorasi
Buatlah sebuah fungsi commentary
yang menerima masukan dalam parameter color
dan mengembalikan string tertentu sesuai dengan nilai color
pada tabel di bawah ini.
color |
comment |
---|---|
red |
It’s a tomato |
green |
It’s a green pepper |
bees |
I don’t know what it is, but looks like a bee |
Jika nilai color
tidak tersedia dalam tabel di atas, kembalikan string dengan pola di bawah ini
"I've never heard of the color yellow before"
def commentary(color):
# KETIK DI SINI
pass
green = commentary("green")
red = commentary("red")
yellow = commentary("yellow")
print("Have you heard color green?", green)
print("Have you heard color red?", red)
print("Have you heard color yellow?", yellow)
Have you heard color green? None
Have you heard color red? None
Have you heard color yellow? None
Argumen dan Parameter¶
Argumen dan parameter beberapa kali disebut pada penjelasan di atas. Kedua istilah ini seringkali disebut untuk mengacu pada hal yang sama, meskipun argumen berbeda dengan parameter. Fungsi cylinder_volume
sebelumnya memiliki 2 parameter, height
dan radius
. Saat cylinder_volume
dipanggil, kita menyediakkan 2 argumen, 10
dan 3
untuk radius
dan height
secara berturut-turut.
Note
Saying it another way: they’re called arguments ouside of the function, but parameters inside. [Lub19]
Kita bisa anggap parameter adalah variabel khusus dalam sebuah fungsi yang nilainya diambil dari argumen yang dimasukkan saat pemanggilan. Pada fungsi echo
yang didefinisikan di bawah ini, nilai bitlabs
yang kita masukkan saat memanggil fungsi echo
akan “diganti” dengan parameter anything
dalam fungsi tersebut. Nilai bitlabs
disebut sebagai argumen, sedangkan anything
adalah parameter dalam fungsi.
def echo(anything):
return anything + " " + anything
echo("bitlabs")
'bitlabs bitlabs'
Jika kita memasukkan sejumlah argumen yang kurang atau lebih dari jumlah parameter yang seharusnya fungsi tersebut butuhkan, maka kita akan mendapatkan eror TypeError
yang memberi tahu kita bahwa ada kesalahan dalam memasukkan argumen. Perhatikan contoh kode di bawah ini.
cylinder_volume(10)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/var/folders/gn/lh5142px2tb1x8mbqzsf3ckh0000gn/T/ipykernel_46164/1510587952.py in <module>
----> 1 cylinder_volume(10)
TypeError: cylinder_volume() missing 1 required positional argument: 'height'
echo(100, 200)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/var/folders/gn/lh5142px2tb1x8mbqzsf3ckh0000gn/T/ipykernel_46164/2668369315.py in <module>
----> 1 echo(100, 200)
TypeError: echo() takes 1 positional argument but 2 were given
Kita bisa memasukkan input langsung sesuai dengan posisi parameter dalam fungsi atau secara tidak berurutan dengan menyediakan nama parameternya.
def is_bounded(x, lower, upper):
return lower <= x <= upper
is_bounded(2, 3, 4)
False
is_bounded(lower=2, x=3, upper=4)
True
Pemanggilan fungsi yang pertama, is_bounded(2, 3, 4)
, menghasilkan nilai False
karena x=2
, lower=3
, dan upper=4
, sehingga 3 <= 2 <= 4
sama dengan False
. Sedangkan, pada pemanggilan fungsi yang kedua, karena kita memasukkan argumen dengan berdasarkan dan menyediakan parameternya, maka meskipun urutan nilai masukannya sama dengan pemanggilan fungsi pertama, tapi kita memberi tahu is_bounded
bahwa argumen pertama ditujukan untuk lower
dengan menuliskan lower=2
. Urutan parameter tidak berlaku di sini dan yang terpenting adalah semua parameter yang dibutuhkan fungsi ditentukan.
# pernyataan di bawah ini semuanya ekuivalen
print(is_bounded(3, 2, 4))
print(is_bounded(upper=4, lower=2, x=3))
print(is_bounded(upper=4, x=3, lower=2))
True
True
True
Pemberian argumen dengan cara seperti ini disebut dengan keyword argument, yaitu pemberian argumen dengan keyword parameter yang dituju.
Note
Keyword argument adalah sebuah argumen yang didahului oleh pengindentifikasi (misal name=
) dalam sebuah pemanggilan fungsi. [Fou21c]
Tidak semua argumen harus disediakan dengan keyword argument. Kita juga bisa menggabungkan positional argument dengan keyword argment seperti di bawah ini.
is_bounded(3, lower=2, upper=4)
Potongan kode di atas berarti kita menyediakan argumen 3
sebagai positional argument sehingga akan ditempatkan sesuai dengan posisi pertama parameter fungsi, yaitu x
. Sedangkan, argumen 2
dan 3
sebagai keyword argument yang tidak dipengaruhi oleh posisi parameter.
Warning
Jika kita sudah memberikan argumen dalam bentuk keyword argument, maka argumen-argumen setelahnya juga harus dalam keyword argument. Jika setelah keyword argument kita memberikan argumen sebagai positional argument, maka akan memunculkan eror SyntaxError
.
is_bounded(3, lower=2, upper=4)
True
is_bounded(3, upper=3, 4)
File "/var/folders/gn/lh5142px2tb1x8mbqzsf3ckh0000gn/T/ipykernel_46164/2158825987.py", line 1
is_bounded(3, upper=3, 4)
^
SyntaxError: positional argument follows keyword argument
Kita bisa menyediakan nilai default parameter saat pendefinisian fungsi. Nilai default ini akan dipakai jika fungsi dipanggil tanpa menyediakan argumen untuk parameter tersebut atau memang ingin menggunakan nilai default. Coba kita lihat fungsi is_bounded
sebelumnya. Andaikan fungsi tersebut dipanggil untuk menentukan apakah x
berada pada interval \([0, 10]\) dan sangat jarang untuk interval yang lain. Jika demikian, kita bisa menyediakan parameter lower
dan upper
dengan nilai default seperti di bawah ini.
def is_bounded(x, lower=0, upper=10):
return lower <= x <= upper
Sekarang, kita bisa memanggil is_bounded
hanya dengan menyediakan nilai x
saja karena parameter yang lain sudah memiliki argumen default.
is_bounded(2)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/var/folders/gn/lh5142px2tb1x8mbqzsf3ckh0000gn/T/ipykernel_46164/350797906.py in <module>
----> 1 is_bounded(2)
TypeError: is_bounded() missing 2 required positional arguments: 'lower' and 'upper'
Tentu saja, jika kita ingin menggunakan interval yang berbeda, kita bisa memberikan argumen sendiri yang akan mengganti argumen default fungsi.
is_bounded(2, lower=5)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/var/folders/gn/lh5142px2tb1x8mbqzsf3ckh0000gn/T/ipykernel_46164/4126019150.py in <module>
----> 1 is_bounded(2, lower=5)
TypeError: is_bounded() missing 1 required positional argument: 'upper'
Warning
Pendefinisian fungsi dengan argumen default pada parameter tidak boleh diikuti oleh positional argument, seperti di bawah ini.
def is_bounded(x, lower=0, upper):
return lower <= x <= upper
Definisi fungsi di atas akan memunculkan eror SyntaxError
, sama dengan saat kita menyediakan keyword argument dan diikuti oleh positional argument sebelumya.
Eksplorasi Mandiri
Python mengutamakan readability yang berarti kode yang ditulis haruslah mudah dibaca dan dipahami, baik bagi pengembang, pengguna, ataupun pembaca. Oleh karena itu, coba baca, eksplor, dan terapkan bagaimana kita membuat dokumentasi fungsi yang sudah kita buat melalui link berikut: PEP-257 Docstring Convention
Cakupan Variabel¶
Cakupan variabel merujuk pada bagaimana suatu variabel dapat diakses oleh interpreter [Sok21]. Variabel-variabel atau parameter dalam sebuah fungsi hanya bisa diakses dan berlaku di dalam fungsi tersebut. Andaikan kita mendefinisikan variabel dengan nama yang sama diluar fungsi tersebut, maka fungsi tersebut tetap menggunakan variabel yang didefinisikan di dalamnya. Akan tetapi, jika kita mendefinisikan variabel di luar fungsi, lalu mengaksesnya di dalam fungsi, di mana tidak ada variabel dengan nama yang sama, maka fungsi tersebut akan menggunakan variabel dari luar fungsi.
Untuk lebih jelasnya, kita gunakan fungsi func
terakhir kita yang mengombinasikan positional argument dan variable-length positional/keyword argument
x = 10
y = 100
func(5, 50)
print("x outside function:", x)
print("y outside function:", y)
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
/var/folders/gn/lh5142px2tb1x8mbqzsf3ckh0000gn/T/ipykernel_46164/555556745.py in <module>
2 y = 100
3
----> 4 func(5, 50)
5
6 print("x outside function:", x)
NameError: name 'func' is not defined
Good practice
It is best to define variables in the smallest scope they will be needed in. While functions can refer to variables defined in a larger scope, this is very rarely a good idea since you may not know what variables you have defined if your program has a lot of variables. [Uda21]