Pernahkah mendengar istilah dokumentasi data? Dokumentasi data atau yang sering disebut dengan data provenance adalah sebuah langkah untuk melihat sumber data yang kita peroleh. Kata provenance sendiri berasal dari bahasa perancis provenir yang berarti “berasal” atau dalam istilah juga disebut silsilah.
Dalam konsep sejarah seni, kata provenance sering digunakan dalam dokumentasi sebuah karya seni sehingga setiap detailnya tetap tercatat. Misalnya kapan pertama kali sebuah karya seni diciptakan dari sisi ide, eksekusi, hingga akhirnya menjadi yang dapat kita nikmati saat ini.
Contoh lainnya, coba bayangkan Anda berperan sebagai seorang Data Scientist. Anda mendapatkan sebuah dataset yang siap untuk dianalisis. Anda tidak tahu data ini berasal dari mana, bagaimana validitasnya, apakah ia akan berubah selama proses pengerjaan Anda, dan sebagainya. Gawat kan? Padahal dokumentasi data ini penting untuk mengetahui keabsahan data dan memungkinkan kita menggunakannya kembali di waktu yang lain.
W3C Provenance Incubator Group menjelaskan tentang dokumentasi data sebagai berikut:
“a record that describes entities and processes involved in producing and delivering or otherwise influencing that resource. Provenance provides a critical foundation for assessing authenticity, enabling trust, and allowing reproducibility. Provenance assertions are a form of contextual metadata and can themselves become important records with their own provenance.”
Terdengar rumit? Baiklah. Berikut ini contoh sebuah penggambaran dokumentasi data yang ditunjukkan dalam sebuah metadata.
Contoh data provenance di atas didapat dari website kaggle. Pada gambar di atas terlihat dokumentasi yang menyertakan sumber data, metodologi pembuatan data, dan juga pemilik dari dataset. Berikut contoh lain dari dokumentasi data yang familiar bagi Anda.
Tampilan di atas merupakan version history dari berkas Google Spreadsheet. Semua perubahan data tercatat mulai dari tanggal hingga nama orang yang melakukan perubahan. Version history ini dapat Anda temukan saat klik bagian berikut:
Untuk dapat kembali ke penulisan sebelumnya kita dapat melakukan restore version dengan memilih dari riwayat penulisan dan klik Restore this version.
Website adalah sebuah halaman yang menampilkan informasi melalui teks atau gambar. Website dapat diakses melalui internet dengan menggunakan browser.
Website ini unik karena tiap halaman dapat saling terhubung dengan menggunakan hypertext links. Umumnya sebuah website memuat informasi yang disediakan secara perorangan, kelompok, atau organisasi. Semua informasi yang tersedia pada halaman website disimpan pada server.
Website sudah berkembang sangat pesat. Sekarang, website digunakan tidak hanya untuk media berbagi informasi atau berita. Layaknya sebuah aplikasi pada komputer dan handphone kita, website dapat digunakan untuk komunikasi secara real-time, mendengarkan sebuah lagu bahkan photo editing sekarang dapat dilakukan pada sebuah website.
Module Python adalah berkas teks berekstensi .py yang berisikan kode Python. Anda dapat mereferensi berkas .py apa pun sebagai modul.
Modul-modul umum yang disediakan oleh Python Standard Library dan mungkin sudah terinstal secara default pada instalasi Python Anda. PIP juga dapat dimanfaatkan untuk menginstal modul atau library berikut dengan dependensi yang dibutuhkannya. Anda pun dapat membuat dan menghasilkan modul Python Anda sendiri.
Menulis Modul
Menuliskan modul pada bahasa Python dapat dimulai dengan menuliskan definisi fungsi, kelas, dan variabel yang dapat digunakan kembali pada program lainnya. Misalkan saja kita membuat berkas hello.py yang akan kita panggil di berkas lain.
hello.py
# Define a function
defworld():
print("Hello, World!")
Jika hello.py dijalankan, maka program tidak akan menjalankan apapun karena world() hanya berupa definisi fungsi, kita belum memanggilnya. Jika kita biasanya memanggil sebuah fungsi dari berkas yang sama di bagian main, kali ini kita akan membuat berkas lain main.py yang seolah mengimpor hello.py. Pastikan hello.py dan main.py berada dalam satu direktori agar dapat diimpor dan dipanggil.
main.py
#impor
import hello
#panggil
hello.world()
Saat memanggil sebuah fungsi dari modul yang kita impor, jangan lupa untuk menambahkan nama modulnya diikuti tanda titik, baru fungsi yang akan kita panggil. Dalam hal ini karena kita mengimpor hello.py, maka cukup kita tulis import hello, dan saat memanggilnya dengan hello.world(). Selain itu, kita juga dapat menggunakan from ... import ..., dalam hal ini adalah from hello import world dan memanggil fungsinya langsung yakni world().
Sekarang, saat memanggil main.py, maka akan menghasilkan:
Hello, World!
Menambahkan variabel
Menambahkan variabel pada modul hello, tambahkan variabel nama, misalnya Dicoding.
hello.py
defworld():
print("Hello, World!")
nama ="Dicoding"
Berikutnya, kita coba cetak variabel nama.
main.py
#impor
import hello
#panggil
hello.world()
#cetak
print(hello.nama)
Saat Dijalankan:
Hello, World! Dicoding
Menambahkan kelas
Contoh yang lain, mari tambahkan kelas di modul hello. Kita akan membuat kelas Reviewer dengan atribut nama dan kelas, serta fungsi review() yang akan mencetak atribut yang telah didefinisikan.
hello.py
defworld():
print("Hello, World!")
nama ="Dicoding"
classReviewer:
def__init__(self, nama, kelas):
self.nama = nama
self.kelas = kelas
def review(self):
print("Reviewer "+self.nama +" bertanggung jawab di kelas "+self.kelas)
Tambahkan kelas pada main.py
main.py
#impor
import hello
#panggil
hello.world()
#cetak
print(hello.nama)
#review
diko = hello.Reviewer("Diko","Python")
diko.review()
Seperti umumnya kelas pada bahasa pemrograman lainnya, Fungsi dan Atributnya dapat diakses setelah kita melakukan instansiasi. Fungsi Review adalah fungsi yang melekat pada kelas Reviewer. Kita juga dapat memanggil diko.Nama atau diko.Kelas sebagai atribut yang melekat di kelas tersebut.
Output:
Hello, World! Dicoding Reviewer Diko bertanggung jawab di kelas Python
Lihat kedua variabel "nama" yang dapat menghasilkan dua nilai berbeda, karena nama yang pertama (hello.nama) melekat pada modul, sementara diko. Nama adalah atribut nama pada kelas Reviewer. Anda harus cukup berhati-hati dalam memastikan variabel seperti pada pembahasan fungsi yang lalu.
Implementasi Kode
Seringkali, modul dimanfaatkan untuk dapat memisahkan antara definisi dan implementasi kode. Namun modul juga dapat berfungsi selayaknya program pada umumnya, yang juga langsung mengeksekusi dalam modul itu sendiri. Contohnya, kita buat hello2.py seperti berikut:
hello2.py
# Definisi
defworld():
print("Hello, World!")
# Panggil disini
world()
Kemudian bersihkan main.py hingga menyisakan import hello saja.
main_program.py
import hello2
Saat main_program dijalankan, langsung muncul:
Hello, World!
Sehingga modul dapat digunakan dengan berbagai metode pemanggilan, bergantung pada definisi, maupun implementasi.
Mengakses Modul dari Folder Lain
Jika Anda bekerja dengan beberapa proyek secara paralel, berikut adalah opsi untuk mengakses modul dari folder lain:
Menambahkan path folder
Opsi ini dipilih umumnya di tahap awal pengembangan, sebagai solusi temporer. Untuk mengetahui path pemanggilan utama, Anda perlu bantuan dari modul sys yang sudah tersedia. Impor modul sys di main program dan gunakan fungsi sys.path.append. Berikut contoh jika berkas hello.py kita berada di direktori /home/dicoding/ dan main.py di direktori lainnya, pada Anda akan menambahkan path /home/dicoding pada main.py dengan cara:
import sys
sys.path.append('/home/dicoding')
import hello
…
Menambahkan modul pada Python Path
Alternatif ini dapat dipilih saat Anda melakukan pemanggilan modul >1x. Pada intinya pilihan ini akan menambahkan modul yang Anda buat pada Path yang diperiksa oleh Python sebagai modul dan paket-paket bawaan. Anda dapat memanfaatkan sys.path kembali untuk mengetahui posisi Anda saat ini.
print(sys.path)
Anda mungkin akan menerima output seperti berikut, sangat bergantung dengan jenis environment Anda, tapi pilihlah (atau cobalah satu per satu) jika ada beberapa output.
Pindahkan hello.py pada direktori di atas. Maka Ia akan dikenali sebagai sebuah modul yang dapat diimpor oleh siapa saja dalam environment tersebut.
Pada main_program.py cukup impor.
import hello
Pastikan path yang Anda assign tepat untuk menghasilkan pemanggilan yang tepat. Modul yang tersebar pada beberapa folder mungkin akan menghasilkan galat. Usahakan peletakan yang se-sederhana mungkin
Fungsi adalah blok kode yang terorganisasi dengan baik sehingga dapat digunakan kembali (reusable).
Beberapa syarat umum fungsi adalah modularisasi dan fungsionalitasnya. Jadi sebaiknya fungsi hanya memiliki satu kegunaan spesifik namun dapat digunakan kembali.
Fungsi-fungsi umum telah disediakan oleh Python misalnya print(). Namun Anda dapat selalu mendefinisikan fungsi Anda sendiri.
Mendefinisikan fungsi
Fungsi didefinisikan dengan keyword def diikuti dengan nama fungsi dan parameternya dalam kurung (). Secara opsional, Anda dapat menambahkan docstring - string dokumentasi dari fungsi. Blok kode dalam setiap fungsi dimulai dengan titik dua dan menggunakan indentasi. Fungsi berhenti ketika terdapat statement return [expression]. Mengembalikan [expression] kepada pemanggilnya. Sebuah return statement yang tidak membawa [expression] apapun sama dengan return None.
Sintaksis fungsi pada Python:
def functionname( parameters ):
"function_docstring"
function_suite
return[expression]
Secara default, Python akan memposisikan setiap parameter sesuai dengan urutan pendaftaran pada saat didefinisikan, dan harus dipanggil sesuai dengan urutan tersebut. Contoh:
Fungsi berikut akan menerima sebuah string sebagai parameter dan mencetaknya.
def printme( str ):
print(str)
return
Sintaksis return tanpa ekspresi dapat juga tidak dituliskan. Fungsi di atas akan sama seperti di bawah ini.
def printme(str):
print(str)
Memanggil Fungsi
Mendefinisikan sebuah fungsi hanya memberikan namanya, menentukan parameter yang ingin menjadi bagian dari fungsi dan struktur dasar kode tersebut. Setelah struktur dasar terpenuhi, Anda dapat memanggilnya pada fungsi yang lain atau dari Python prompt. Contoh berikut untuk memanggil fungsi printme().
def printme( str ):
print(str)
return
#panggil
printme("Panggilan Pertama")
printme("Panggilan Kedua")
Saat kode diatas dijalankan, akan menghasilkan berikut:
Output:
Panggilan Pertama Panggilan Kedua
Return
Pernyataan return [expression] akan membuat eksekusi program keluar dari fungsi saat itu, sekaligus mengembalikan nilai tertentu. Nilai return yang tidak mengembalikan (ekspresi) nilai bersifat sama dengan contoh di bawah ini.
returnNone
Contoh fungsi dengan return:
def sum(arg1, arg2):
# Add both the parameters and return them.
total = arg1 + arg2
print('Inside the function: {}'.format(total))
return total
# Panggil sum
total = sum(10,20);
print('Outside the function: {}'.format(total))
Saat dipanggil:
Inside the function : 30 Outside the function : 30
Nilai kembalian dari sebuah fungsi dapat disimpan dalam sebuah variabel. Ini yang akan membedakan sebuah fungsi yang mengembalikan nilai dengan sebuah fungsi yang tidak mengembalikan nilai (sering disebut sebagai prosedur).
def kuadrat(x):
return x*x
a =10
k = kuadrat(a)
print('nilai kuadrat dari {} adalah {}'.format(a, k))
Pass by reference vs value
Seluruh parameter (argumen) pada bahasa Python bersifat “passed by reference”. Artinya saat Anda mengubah sebuah variabel, maka data yang mereferensi padanya juga akan berubah, baik di dalam fungsi, maupun di luar fungsi pemanggil. Kecuali jika anda melakukan operasi assignment yang akan mengubah reference parameter.
Contohnya:
def changeme(mylist):
mylist.append([1,2,3,4])
print('Nilai di dalam fungsi: {}'.format(mylist))
# Panggil changeme
mylist =[10,20,30]
changeme(mylist)
print('Nilai di luar fungsi: {}'.format(mylist))
Dapat dilihat dalam kode diatas, objek yang direferensi adalah sama. Sehingga nilai tersebut:
Nilai di dalam fungsi: [10, 20, 30, [1, 2, 3, 4]] Nilai di luar fungsi: [10, 20, 30, [1, 2, 3, 4]]
Contoh lain di mana argumen ditimpa dalam fungsi:
# Function definition is here
def changeme(mylist):
"Variabel mylist berikut hanya dikenali (berlaku) di dalam fungsi"
mylist =[1,2,3,4]# This would assign new reference in mylist
print('Nilai di dalam fungsi: {}'.format(mylist))
# Panggil fungsi changeme
mylist =[10,20,30]
changeme(mylist)
print('Nilai di luar fungsi: {}'.format(mylist))
Reference parameter mylist diperbarui dalam fungsi changeme dengan operator assignment (sama dengan), sehingga nilai mylist akan berbeda karena bersifat lokal dalam fungsi changeme saja. Hasilnya akan sebagai berikut:
Nilai di dalam fungsi: [1, 2, 3, 4] Nilai di luar fungsi: [10, 20, 30]
Argumen Fungsi
Beberapa argumen yang umum digunakan dalam fungsi:
Required arguments : Argumen yang wajib disertakan dan disusun secara terurut dalam pemanggilan fungsi.
Keyword arguments : Argumen yang ditambahkan dengan menyertakan nama variabel/keywordnya dalam pemanggilan fungsi.
Default arguments : Argumen yang bersifat tidak wajib diisi, karena telah memiliki nilai default.
Variable-length arguments : Argumen yang bersifat opsional namun dapat disesuaikan banyaknya dan tidak didefinisikan secara spesifik dalam definisi fungsi.
Contoh Fungsi dengan Required arguments
Untuk memanggil fungsi printme(), Anda wajib menyertakan satu parameter string saat pemanggilan. Misalnya Anda tidak menyertakan parameter -- hanya memanggil printme.
printme()
Maka akan muncul error sebagai berikut:
Traceback (most recent call last): File "test.py", line 11, in <module> printme(); TypeError: printme() takes exactly 1 argument (0 given)
Bagian ini hanya memberikan gambaran tentang pemanggilan fungsi, Anda akan mempelajari lebih jauh tentang kesalahan (Error) di modul Penanganan Kesalahan.
Contoh Fungsi dengan Keyword arguments
printme(str ="My string")
Dan sesuai definisi, fungsi akan mencetak seperti di bawah ini.
My String
Jika Anda memanggil fungsi dengan argumen kata kunci (keyword) atau dengan menyebutkan nama variabelnya, Anda tidak wajib meletakkan urutan variabel sesuai dengan urutan saat fungsi didefinisikan. Contoh:
def printinfo(name, age):
"This prints a passed info into this function"
print('Name: ', name)
print('Age: ', age)
# Now you can call printinfo function (with age argument first)
printinfo(age=5, name="Dicoding")
Saat dieksekusi, hasilnya:
Name: Dicoding Age: 5
Contoh Fungsi dengan Default arguments
Sebuah fungsi yang memiliki sejumlah argumen, dapat diatur nilai bawaannya (default), agar pada saat pemanggilan nilainya bisa menjadi opsional untuk diisi.
Argumen dengan nilai bawaan harus didefinisikan setelah argumen yang tidak memiliki nilai bawaan.
def printinfo(name, age=35):
"This prints a passed info into this function"
print('Name: ', name)
print('Age: ', age)
# Now you can call printinfo function (with optional argument age)
printinfo(age=5, name='Dicoding')
printinfo(name='Data')
Saat dieksekusi akan menghasilkan:
Name: Dicoding Age: 5 Name: Data Age: 35
# fungsi berikut ini akan error saat didefinisikan
# argumen dengan nilai bawaan harus setelah argumen tanpa bawaaan
Bagian ini hanya memberikan gambaran tentang pemanggilan fungsi, Anda akan mempelajari lebih jauh tentang kesalahan (Error) di modul Penanganan Kesalahan
Contoh Implementasi Variable-length arguments
Contoh Implementasi argument dengan panjang yang dinamis (variable-length). Seperti yang telah dijelaskan, sebuah fungsi dapat memiliki argumen posisi juga argumen kata kunci (keyword). Keduanya memiliki kemampuan untuk bersifat dinamis, sehingga masukan fungsi dan panjang argumen dapat berubah-ubah.
def functionname([formal_args,]*var_args_tuple ):
"function_docstring"
function_suite
return[expression]
Argumen posisi dapat bersifat dinamis dengan menambahkan sintaksis tanda bintang (*), untuk menampung kontainer (Tuple). Kontainer (Tuple) ini bisa bersifat opsional, artinya tidak wajib diisi (boleh kosong), jika memang tidak ada argumen yang perlu ditambahkan. Pada saat diisi, seperti layaknya Tuple dapat memiliki jumlah/panjang yang dinamis.
def printinfo(fixedarg,*args):
"This prints a variable passed arguments"
print('Output: fixedarg {}'.format(fixedarg))
for a in args:
print('argumen posisi {}'.format(a))
# Panggil printinfo
printinfo(10)
printinfo(70,60,50)
Saat dipanggil, hasilnya:
Output: fixedarg 10
Output: fixedarg 70
argumen posisi 60
argumen posisi 50
Argumen kata kunci (keyword) dapat bersifat dinamis dengan menambahkan sintaksis dua tanda bintang (**) untuk menampung kontainer (Dictionary).
Kontainer (Dictionary) ini bisa bersifat opsional, artinya tidak wajib diisi (boleh kosong), jika memang tidak ada argumen yang perlu ditambahkan. Pada saat diisi, seperti layaknya Dictionary dapat memiliki jumlah/panjang yang dinamis, dengan pasangan kunci-nilai (key-value) yang bervariasi. Jika ada argumen posisi dinamis dan argument kata kunci (keyword) dinamis, maka urutannya adalah argumen posisi dahulu, baru argumen kata kunci.
def printinfo(*args,**kwargs):
for a in args:
print('argumen posisi {}'.format(a))
for key,valuein kwargs.items():
print('argument kata kunci {}:{}'.format(key,value))
# Panggil printinfo
printinfo()
printinfo(1,2,3)
printinfo(i=7, j=8, k=9)
printinfo(1,2, j=8, k=9)
printinfo(*(2,3),**{'i':7,'j':8})
Output:
# printinfo() --> kosong
argumen posisi 1 argumen posisi 2 argumen posisi 3
argumen kata kunci i:7 argumen kata kunci j:8 argumen kata kunci k:9
argumen posisi 1 argumen posisi 2 argumen kata kunci j:8 argumen kata kunci k:9
argumen posisi 2 argumen posisi 3 argumen kata kunci i:7 argumen kata kunci j:8
Fungsi Anonim
Fungsi Anonim (anonymous) tidak dideklarasikan seperti halnya fungsi pada umumnya dengan kata kunci def, melainkan menggunakan kata kunci (keyword) lambda. Sebuah fungsi lambda dapat menerima argumen dalam jumlah berapa pun, namun hanya mengembalikan satu nilai expression. Fungsi Lambda tidak dapat memuat perintah atau ekspresi lainnya, misalnya tidak bisa melakukan print.
Fungsi lambda bersifat mandiri, memiliki namespace-nya sendiri, dan tidak dapat mengakses nilai apapun selain yang berada dalam parameter list dan variabel global. Meskipun mirip, Lambda tidak dapat disamakan dengan inline statement pada bahasa C/C++.
Sintaks:
lambda[arg1 [,arg2,.....argn]]:expression
Contoh penggunaannya:
#!/usr/bin/python
sum =lambda arg1, arg2: arg1 + arg2;
print("Value of total : ", sum(10,20))
print("Value of total : ", sum(20,20))
Hasilnya
Value of total : 30 Value of total : 40
Cakupan Variabel
Variabel dapat didesain untuk diakses atau tidak dapat diakses dalam lokasi atau cakupan (scope) tertentu. Hal ini bergantung lokasi Anda mendeklarasikan variabel. Cakupan variabel secara umum dibagi menjadi dua, yakni variabel Lokal dan variabel Global.
Variabel yang didefinisikan dalam fungsi bersifat lokal (di fungsi tersebut), dan yang didefinisikan di luar fungsi bersifat global. Perbandingkan kode berikut pada bagian yang ditebalkan dan keluarannya.
Artinya, variabel Lokal hanya dapat diakses dan dioperasikan dalam fungsi tempat variabel tersebut dideklarasikan.
total =0# ini variabel global
def sum(arg1, arg2):
# tambahkan kedua parameter dan return
total = arg1 + arg2
print('Inside the function: {}'.format(total))
return total
# panggil sum
sum(10,20)
print('Outside the function: {}'.format(total))
Output:
Inside the function local total : 30 Outside the function global total : 0
Untuk mengenali variabel Global, tambahkan kata kunci (keyword) global saat memanggil nama variabel.
Penggunaan variabel global dinilai sebagai praktek yang tidak baik dalam pemrograman, karena tingkat kesulitan saat pencarian kesalahan (debugging) untuk variabel yang memiliki cakupan global akan lebih rumit dibanding variabel lokal.
total =0# This is global variable.
# fungsi didefinisikan di bawah ini
def sum(arg1, arg2):
global total
total = arg1 + arg2 # variabel lokal total
print('Inside the function local total: ', total)
return total
sum(10,20)
print('Outside the function (global) total: ', total)
Output:
Inside the function local total : 30 Outside the function global total : 30