etelah program selesai, entah itu ada exception atau tidak, pesan
try:
total_banana = int(input("total banana: "))
total_people = int(input("number of person: "))
res = total_banana / total_people
print(f"in fair distribution, each person shall receive {res:.0f}
banana")
except ValueError as err:
print(f"oops! not valid number detected. {err}")
except ZeroDivisionError as err:
print(f"oops! unable to distribute banana because there is no person
available. {err}")
except Exception as err:
print(f"oops! something wrong. {err}")
finally:
print(f"program completed")
program completed di-print
A.47.5. Keyword try , except , else &
finally
Bentuk sempurna dari exception handler yaitu kombinasi dari 4 keyword
yang telah dipelajari ( try , except , else & finally ).
• Block try untuk eksekusi statement
• Block except untuk menangkap exception
• Block else untuk kebutuhan ketika tidak ada exception
• Block finally untuk menandai bahwa eksekusi block exception handler
telah selesai
Contoh program dengan penerapan 4 keyword ini:
try:
total_banana = int(input("total banana: "))
total_people = int(input("number of person: "))
res = total_banana / total_people
except ValueError as err:
Penjelasan alur program di atas:
1. Program diawali dengan eksekusi statement dalam block try
2. Jika terjadi exception ValueError , maka dimunculkan pesan error
3. Jika terjadi exception ZeroDivisionError , maka dimunculkan pesan error
4. Jika terjadi exception lainnya, maka dimunculkan pesan error
5. Jika tidak terjadi exception sama sekali, maka block else dijalankan
6. Setelah program selesai, entah itu ada exception atau tidak, pesan
program completed di-print
Catatan chapter 📑📑
â—‰ Source code praktik
github.com/novalagung/dasarpemrogramanpython-example/../exception-
handling-try-except-else-finally
â—‰ Chapter relevan lainnya
• Error & Exception
â—‰ TBA
• catch custom exception
â—‰ Referensi
• https://docs.python.org/3/library/exceptions.html
• https://docs.python.org/3/tutorial/errors.html
A.48. Python DocString
Pada chapter ini kita akan membahas tentang docstring beserta cara
penerapan dan manfaatnya.
A.48.1. Pengenalan docstring
Di pembelajaran awal yaitu pada chapter Komentar, telah disinggung bahwa
salah satu cara menulis komentar yaitu memakai karakter """ dengan
penulisan di awal dan akhir komentar. Contoh: """ ini komentar """ .
Komentar yang ada di dalam karakter tersebut disebut docstring. DocString
memiliki keistimewaan dibanding komentar biasa yang ditulis memakai
karakter # .
Komentar docstring otomatis menempel pada unit dimana komentar ditulis.
Misalnya ditulis tepat dibawah deklarasi fungsi bernama
print_random_quote() , maka komentarnya menembel ke fungsi tersebut.
Benefitnya, informasi komentar bisa muncul setidaknya di 2 tempat:
• Komentar bisa diakses memakai attribute __doc__ yang menempel
ke fungsi print_random_quote() .
• Komentar dimunculkan sewaktu fungsi tersebut di-hover (dengan catatan
extension Python/Pylance ter-install di editor).
Perihal unit yang bisa ditempeli docstring bisa berupa fungsi, class, method,
atau lainnya.
A.48.2. Praktek penerapan docstring
Mari kita praktekan agar lebih jelas. Siapkan project sederhana dengan
struktur seperti ini. Isinya hanya dua file saja:
• File quote.py berisi class Quote
• File main.py berisi kode penggunaan class Quote
Project structure
Tulis kode berikut di file quote.py :
File quote.py
praktek-docstring/
│─── quote.py
└─── main.py
quotes = [
"never let anyone live in your head rent free",
"if others can do it, then why should I?",
"\n".join([
"I'm sick of following my dreams, man.",
"I'm just going to ask where they're going and hook up with 'em
later."
]),
]
from random import randint
# function `print_random_quote()`:
# print one random quote,
Kemudian di file main.py , import unit-unit dari module quote.py lalu
gunakan.
File main.py
Sampai sini penulis rasa cukup jelas.
Selanjutnya coba hover fungsi atau class yang di-import dari module
Quote.py yang dipergunakan di main.py . Popup muncul tapi isinya hanya
informasi deklarasi fungsi itu sendiri. Komentar yang telah ditulis tidak muncul
di popup.
Ok, sekarang kita akan modifikasi komentar pada kode yang sudah ditulis
dengan mengubahnya menjadi komentar docstring. Komentar hanya dianggap
docstring ketika ditulis dengan diapit karakter """ """ dan penulisannya
berada tepat dibawah unit yang ingin dikomentari.
from quote import Quote, print_random_quote
if __name__ == '__main__':
print_random_quote()
# output ➜ <random quote appears here>
Quote.print_quote(2)
# output ➜ I'm just going to ask where they're going and hook up with
'em later.
â—‰ DocString pada class dan fungsi/method
Ubah isi quote.py menjadi seperti ini:
File quote.py
quotes = [
"never let anyone live in your head rent free",
"if others can do it, then why should I?",
"\n".join([
"I'm sick of following my dreams, man.",
"I'm just going to ask where they're going and hook up with 'em
later."
]),
]
from random import randint
def print_random_quote():
"""
function `print_random_quote()`:
print one random quote,
so nothing special
"""
i = randint(0, len(quotes)-1)
print(quotes[i])
class Quote:
"""
class `Quote`:
A class Quote represent a quote.
It has the following two attributes:
- class attribute `note`
- instance method `print_quote()`
"""
Sekarang coba hover lagi, lihat isi popup-nya.
• Hover fungsi print_random_quote()
• Hover class Quote
• Hover class method Quote.print_quote()
Mantab bukan? DocString ini menjadi salah satu hal yang sangat membantu
dalam pengembangan.
â—‰ DocString pada attribute dan variable
Untuk penerapan docstring pada attribute, caranya juga sama, yaitu dengan
menuliskan komentar tepat dibawah attribute atau variabel dengan karakter
""" """ .
File quote.py
Coba sekarang Output ketika di-hover:
# ...
class Quote:
"""
class `Quote`:
A class Quote represent a quote.
It has the following two attributes:
- class attribute `note`
- instance method `print_quote()`
"""
note = "A class to represent quote"
"""
instance method `print_quote()`:
Responsible to print specific quote by index
"""
@classmethod
def print_quote(cls, i):
"""
instance method `print_quote()`:
Responsible to print specific quote by index
"""
print(quotes[i])
A.48.3. Special name ➜ class attribute__doc__
Informasi docstring milik fungsi, method, dan class bisa diakses secara excplit
memakai class attribute __doc__ . Jika mengacu ke kode yang sudah
ditulis, maka pengaksesannya seperti ini:
Output program:
from quote import Quote, print_random_quote
if __name__ == '__main__':
# menampilkan docstring fungsi `print_random_quote()`
print(print_random_quote.__doc__)
# menampilkan docstring class `Quote`
print(Quote.__doc__)
# menampilkan docstring class method `Quote.print_quote()`
print(Quote.print_quote.__doc__)
Catatan chapter 📑📑
â—‰ Source code praktik
github.com/novalagung/dasarpemrogramanpython-example/../docstring
â—‰ Chapter relevan lainnya
• Komentar
â—‰ Referensi
• https://peps.python.org/pep-0257/
A.49. Python File I/O
Pada chapter ini kita akan belajar tentang pengolahan file dan folder, dan beberapa
hal relevan lainnya yang masih berhubungan dengan manajemen file & folder.
A.49.1. Membuka stream file
Di Python, hampir semua operasi file diawali dengan pemanggilan fungsi open() ,
dan diakhiri pemanggilan method close() (milik object yang dikembalikan oleh
fungsi open() ).
Fungsi open() dalam penggunannya membutuhkan pengisian beberapa
parameter:
• Parameter ke-1: nama file.
• Parameter ke-2: mode I/O, ada beberapa mode operasi file, diantaranya:
â—¦ w untuk mode tulis dengan posisi kursor ada di baris paling awal. Jadi
operasi penulisan bisa menimpa konten yang sudah ada. Selain itu, mode
ini membuat isi file otomatis menjadi kosong saat fungsi open() dipanggil.
â—¦ a untuk mode append, yaitu mode tulis dengan posisi kursor sudah di
baris paling akhir. Jadi penambahan konten tidak akan menimpa konten
sebelumnya, tapi ditambahkan di akhir.
â—¦ r untuk mode baca.
• Ada juga parameter opsional lainnya, salah satunya encoding yang umum diisi
dengan nilai utf-8 .
Bentuk paling sederhana penerapan operasi buka file:
f = open("/path/to/file/file.txt", "w", encoding="utf-8")
# ...
Kode di atas akan membuka stream I/O file bernama file.txt . Jika file tujuan
belum ada, maka otomatis dibuatkan oleh Python. Dari object kembalian fungsi
open() nantinya kita bisa lakukan banyak jenis operasi seperti membaca isi file,
menulis, menghapus, dan lainnya.
Untuk pengguna Windows, tulis saja path-nya dengan karakter \ ter-escape.
Contoh: "C:\\Users\\novalagung\\Desktop\\file.txt"
Silakan tulis kode di atas, lalu ganti path-nya dengan current path (atau bisa
gunakan . ), kemudian run programnya. Hasil eksekusi program yaitu pembuatan
sebuah file baru bernama file.txt yang isinya kosong.
Mode w digunakan disitu, artinya file dibuka dengan mode tulis. Salah satu efek
dari penggunaan mode w yaitu ketika file dibuka isinya pasti dikosongkan
terlebih dahulu.
File yang dibuka, wajib untuk selalu ditutup di akhir. Karena membiarkan file tetap
terbuka beresiko membuat isi file rusak ketika ada lebih dari 1 pengakses yang
melakukan operasi terhadap file tersebut secara bersamaan.
Untuk mengecek apakah file sedang terbuka stream-nya, bisa dengan melihat nilai
attribute closed .
f = open("file.txt", "w", encoding="utf-8")
print("file is closed:", f.closed)
# output ➜ file is closed: False
# ...
A.49.2. Keyword with
Ada cara yang lebih efisien dalam operasi buka file agar file otomatis ter-close
setelah digunakan, yaitu dengan memakai keyword with diikuti statement
open() lalu syntax as nama_variabel . Kurang lebih seperti ini penulisannya:
A.49.3. Menulis file
Operasi penulisan konten ke file dilakukan via method write() milik object file.
Contoh penerapannya bisa dilihat pada kode berikut, dimana ada method write()
digunakan 3x untuk menulis karakter string.
Output program:
with open("file.txt", "w", encoding="utf-8") as f:
print("file is closed:", f.closed)
# output ➜ file is closed: False
# ...
print("file is closed:", f.closed)
# output ➜ file is closed: True
with open("file.txt", "w", encoding="utf-8") as f:
f.write("hello")
f.write("python\n")
f.write("how are you?\n")
Program di-run 3x dan isinya tetap sama (tidak menumpuk), ini karena setiap kali
statement open() dijalankan dengan mode w , file akan dikosongkan terlebih
dahulu.
A.49.4. Append konten ke file
Gunakan mode a untuk append konten ke file yang isinya bisa saja tidak kosong
(agar isi konten tidak ditimpa).
Coba jalankan kode berikut terahdap file file.txt yang sebelumnya sudah dibuat.
Saat program di-run kondisi file sudah terisi dan tidak dikosongkan terlebih dahulu.
Dengan mengeksekusi write() disitu maka isi konten akan bertambah terus
setiap kali program di-run.
Output program:
with open("file.txt", "a", encoding="utf-8") as f:
f.write("happy monday\n")
Bisa dilihat, setiap kali program dieksekusi konten happy monday\n bertambah
terus.
A.49.5. Membaca file
Method readline() dan read() milik object file, keduanya digunakan untuk
membaca isi file.
• Method readline() akan membaca isi file baris per baris. Pembacaan dimulai
dari baris paling atas dan proses pembacaan terjadi setiap kali method
readline() dipanggil. Ketika method ini mengembalikan string kosong, bisa
jadi menandakan semua baris konten file sudah terbaca.
Disini penulis gunakan kata bisa jadi karena ada kasus dimana pada beberapa
baris bisa saja memang isinya sengaja kosong.
• Method read() akan membaca seluruh isi file. Pemanggilan method ini untuk
kedua kalinya pasti mengembalikan string kosong, menandakan semua baris
konten file sudah terbaca.
Mari praktekan penggunaan 2 method di atas. Pertama isi file file.txt secara
manual dengan konten berikut:
Kemudian baca isinya per baris memakai kode berikut:
Output program:
Malah error? Kok bisa? Error ini disebabkan karena kita memakai mode a
hellopython
how are you?
happy monday
with open("file.txt", "a", encoding="utf-8") as f:
print(f"line 1: {f.readline()}")
print(f"line 2: {f.readline()}")
print(f"line 3: {f.readline()}")
print(f"line 4: {f.readline()}")
print(f"line 5: {f.readline()}")
yang mode tersebut hanya valid untuk operasi append. Kita perlu mengubah mode
menjadi r untuk operasi pembacaan file.
Output program:
Bisa dilihat method readline() mengembalikan data per baris dari atas ke bawah
dengan jumlah sesuai dengan berapa kali baris method tersebut dipanggil.
Dalam penerapannya, dianjurkan untuk memakai method ini dalam
perulangan kemudian ditambahkan pengecekan isi konten untuk menandai bahwa
konten sudah terbaca semua. Contohnya seperti ini:
with open("file.txt", "r", encoding="utf-8") as f:
print(f"line 1: {f.readline()}")
print(f"line 2: {f.readline()}")
print(f"line 3: {f.readline()}")
print(f"line 4: {f.readline()}")
print(f"line 5: {f.readline()}")
with open("file.txt", "r", encoding="utf-8") as f:
i = 0
while True:
line = f.readline()
Kode di atas bisa disederhanakan lagi dengan cara langsung mengiterasi object file-
nya. Jadi variabel f digunakan secara langsung pada statement perulangan. Hal
ini bisa dilakukan karena tipe data kembalian fungsi open() yaitu
TextIOWrapper dan tipe ini termasuk tipe data yang iterable.
Lebih detailnya mengenai tipe data iterable dibahas pada chapter Iterator
Kode yang sudah cukup ringkas di atas bisa disederhanakan lagi dengan cara
membungkus tipe data f dalam fungsi enumerate() . Fungsi ini membuat suatu
object yang iterable menjadi memiliki index di setiap element-nya.
Jika goal dari program yaitu hanya membaca isi file secara menyeluruh,
sebenarnya lebih praktis lagi memakai method read() .
A.49.6. Membaca dan menulis dalam 1 sesi
Di awal chapter telah dijelaskan tentang kegunaan mode w , a , dan r . Lalu
bagaimana jika ada kebutuhan untuk membaca dan menulis file dalam satu sesi?
Jawabannya yaitu dengan menambahkan tanda + pada mode (jadinya w+ , a+ ,
with open("file.txt", "r", encoding="utf-8") as f:
i = 1
for line in f:
print(f"line {i}: {line}")
i += 1
with open("file.txt", "r", encoding="utf-8") as f:
for i, line in enumerate(f):
print(f"line {i+1}: {line}")
with open("file.txt", "r", encoding="utf-8") as f:
print(f.read())
atau r+ ).
Sebagai contoh, pada program berikut, mode r+ digunakan. O iya, proses
pembacaan file dilakukan 2x ya, penjelasan disertakan dibawahnya.
Output program:
Bisa dilihat di program, block with pertama yang berisi operasi baca dan juga tulis
with open("file.txt", "r+", encoding="utf-8") as f:
print(f"read:\n{f.read()}")
f.write("lorem ipsum dolor\n")
print(f"read:\n{f.read()}")
with open("file.txt", "r+", encoding="utf-8") as f:
print(f"read:\n{f.read()}")
tidak menghasilkan error. Namun ada yang aneh, yaitu tepat setelah lorem ipsum
dolor\n ditulis ke file, proses baca menghasilkan string kosong. Tapi ketika file
dibaca lagi memakai block with baru, isinya sesuai harapan. Jawabannya
yaitu karena pergerakan cursor.
Flow program di atas kurang lebih seperti ini:
1. Cursor awal pembacaan file ada di baris paling awal, karena mode r+
digunakan.
2. Setelah method read() dipanggil, cursor berada di posisi paling akhir.
3. Kemudian lorem ipsum dolor\n ditulis ke file, maka text tersebut ada di baris
baru di akhir file.
4. Lalu ketika method read() dibaca lagi, isinya kosong, karena cursor posisinya
sudah ada di baris akhir file.
5. Kemudian ketika file dibaca ulang memakai fungsi open() dengan block
with baru, cursor kembali aktif di baris paling awal.
6. Lalu file dibaca, maka seluruh isi konten yang beru dikembalikan.
Mode w+ , a+ , dan r+ kesemuanya bisa digunakan untuk baca dan tulis dalam 1
sesi, dengan perbedaan ada di posisi kursornya aktif dimana. Jika pembaca tertarik
untuk mempelajarinya lebih detail, silakan baca diskusi di StackOverflow berikut:
https://stackoverflow.com/questions/1466000/difference-between-modes-a-a-w-w-
and-r-in-built-in-open-function/30566011#30566011
A.49.7. Mengosongkan isi file
Cara mengosongkan file bisa dilakukan dengan mudah memakai mode w .
Baca file memakai mode tersebut kemudian langsung close() saja. Boleh
memakai keyword with atau bisa langsung sebaris statement. Contoh
penerapannya bisa dilihat di kode berikut. 3 block statement di situ semuanya
ekuivalen, membuat isi file menjadi kosong.
Opsi lainnya yaitu memakai method truncate() .
A.49.8. Menghapus file atau folder
API os.remove() digunakan untuk menghapus file, sedangkan os.rmdir() untuk
menghapus folder. Contoh penerapan:
• Menghapus file:
• Menghapus folder:
Untuk path berbasis windows, pastikan karakter \ ditulis dengan cara di-
escape (ditulis \\ ).
with open("file.txt", "w", encoding="utf-8") as f:
pass
with open("file.txt", "w", encoding="utf-8"):
pass
open("file.txt", "w", encoding="utf-8").close()
with open("file.txt", "w", encoding="utf-8") as f:
f.truncate()
import os
os.remove("/path/to/something/file.txt")
import os
os.rmdir("/path/to/something")
A.49.9. Mengecek apakah file atau folder
ada
API os.path.isfile() digunakan untuk mengecek apakah suatu file ada.
Untuk pengecekan terhadap folder, gunakan os.path.exists() . Fungsi ini bisa
digunakan baik untuk pengecekan file ataupun folder.
Untuk path berbasis windows, pastikan karakter \ ditulis dengan cara di-escape
(ditulis \\ ).
import os
os.rmdir("C:\\LibsSoftLink\\dasarpemrogramanpython\\examples")
import os.path
if os.path.isfile("/path/to/something/file.txt"):
print("file.txt is exists")
else:
print("file.txt is not exists")
if os.path.exists("/path/to/something"):
print("something is exists")
else:
print("something is not exists")
if
os.path.exists("C:\\LibsSoftLink\\dasarpemrogramanpython\\examples\\file.txt"):
print("file.txt is exists")
else:
print("file.txt is not exists")
A.49.10. Membuat folder baru
API os.makedirs() digunakan untuk membuat folder baru.
Untuk path berbasis windows, pastikan karakter \ ditulis dengan cara di-escape
(ditulis \\ ).
A.49.11. Menampilkan isi folder
• memakai os.listdir() :
• memakai os.walk() :
import os
os.makedirs("/path/to/somefolder")
import os
os.makedirs("C:\\LibsSoftLink\\dasarpemrogramanpython\\examples")
import os
path_location = "C:\\LibsSoftLink\\dasarpemrogramanpython\\examples\\file"
for f in os.listdir(path_location):
print(f)
import os
path_location = "C:\\LibsSoftLink\\dasarpemrogramanpython\\examples\\file"
for (dirpath, dirnames, filenames) in os.walk(path_location):
Penjelasan:
â—¦ Variabel dirpath berisi current
â—¦ Variabel dirnames berisi folder yang berada dalam current folder
â—¦ Variabel filenames berisi file yang berada dalam current folder
• memakai glob.glob() :
API glob.glob() ini didesain untuk pencarian. Jadi pada penerapannya perlu
ditambahi kondisi wildcard pencarian. Misalnya, dengan menambahkan ** di
akhir path, maka pencarian dilakukan terhadap semua jenis file dan folder.
Catatan chapter 📑📑
â—‰ Source code praktik
github.com/novalagung/dasarpemrogramanpython-example/../file
â—‰ Chapter relevan lainnya
• File/Data Format ➜ CSV
• File/Data Format ➜ JSON
import glob
path_location = "C:\\LibsSoftLink\\dasarpemrogramanpython\\examples\\file"
for f in glob.glob(f"{path_location}\\**", recursive=True):
print(f)
â—‰ TBA
• Pathlib https://docs.python.org/3/library/pathlib.html
• Search pattern
â—‰ Referensi
• https://docs.python.org/3/tutorial/inputoutput.html#reading-and-writing-files
• https://stackoverflow.com/questions/1466000/difference-between-modes-a-a-w-
w-and-r-in-built-in-open-function/30566011#30566011
• https://builtin.com/data-science/python-list-files-in-directory
A.50. Python CLI
Arguments & Flags
Chapter ini membahas tentang pengaksesan CLI argument eksekusi program
Python. Yang dimaksud dengan argument yaitu apapun yang ditulis setelah
command python (atau python.exe di Windows). Umumnya program yang
dibuat untuk keperluan tooling ataupun utility lainnya banyak memanfaatkan
command line interface arguments ini.
Python mengenal 2 jenis CLI arguments, yaitu raw arguments (atau cukup
arguments) dan flags, keduanya dibahas di sini.
A.50.1. CLI arguments sys.argv
Data CLI argument eksekusi program bisa diakses via sys.argv . Variabel
sys.argv ini berisi data argument bertipe string tersimpan dalam list.
Dalam penggunaannya module sys harus di-import terlebih dahulu
Misalnya, pada command berikut ini, pengaksesan variabel sys.argv
menghasilkan data ["main.py"] , karena main.py merupakan CLI argument
yang ditulis setelah command python / python.exe .
Argument bisa saja ada banyak, misalnya pada kode berikut terdapat 3
argument, main.py , sesuk , dan prei . Penulisan banyak argument ditandai
python main.py
dengan pembatas karakter spasi.
Mengenai command python sendiri, dia hanya membutuhkan informasi
argument pertama saja untuk menentukan file mana yang akan dieksekusi.
Argument ke-2, ke-3, dan seterusnya tidak dibutuhkan oleh command python ,
tetapi tetap bisa dipergunakan untuk keperluan lainnya.
Silakan coba tulis kode berikut kemudian run program-nya memakai
command di bawahnya.
Command eksekusi program:
Output program:
python main.py sesuk prei
import sys
if __name__ == "__main__":
print(f"type: {type(sys.argv).__name__}")
print(f"len: {len(sys.argv)}")
for arg in sys.argv:
print(f" ➜ {arg}")
python.exe main_1.py
python.exe main_1.py hello python
python.exe main_1.py "hello python" 24562 😊 True
Silakan lihat perbandingan antara command dengan output. Pada command
ke-2, hello dan python merupakan dua argument berbeda, sedangkan pada
command ke-3, hello python yaitu satu argument karena penulisannya
diapit tanda literal string ( " ).
Semua argument, baik itu angka, emoji, ataupun karakter unicode lainnya akan
ditampung sebagai elemen list bertipe string di sys.argv .
â—‰ Best practice pengaksesan argument
sys.argv merupakan list, maka pengaksesan element tertentu yang index-
nya diluar kapasitas yaitu menghasilkan error. Karena alasan ini ada baiknya
untuk berhati-hati dalam mengakses argument di index tertentu pada variabel
tersebut, pastikan untuk menambahkan seleksi kondisi terlebih dahulu untuk
mengecek apakah index dari element yang dicari masih dalam kapasitas.
Salah satu solusi aman bisa dengan membuat fungsi terpisah untuk
pengaksesan argument, contohnya bisa dilihat pada kode berikut dimana jika
argument yang dicari tidak ada, maka nilai None dikembalikan. Metode ini
lebih efisien.
Output program:
import sys
def get_arg(index):
if len(sys.argv) > index:
return sys.argv[index]
else:
return None
if __name__ == "__main__":
print(f"type: {type(sys.argv).__name__}")
print(f"len: {len(sys.argv)}")
print(f"arg1: {get_arg(0)}")
print(f"arg2: {get_arg(1)}")
print(f"arg3: {get_arg(2)}")
print(f"arg4: {get_arg(3)}")
print(f"arg5: {get_arg(4)}")
A.50.2. CLI flags argparse
Flags yaitu istilah untuk argument dengan label. Contohnya seperti python
main.py --name Noval yaitu contoh pengaplikasian flag, dengan label yaitu
--name berisi data string Noval .
Python menyediakan module argparse berisi banyak API untuk keperluan
operasi flag argument.
Untuk menerapkan flag, sebuah object parser perlu dibuat memakai
argparse.ArgumentParser() , dengan isi parameter yaitu informasi program
(seperti nama dan deskripsi). Kemudian dari object tersebut, didaftarkan
beberapa flag argument (misalnya --name ) beserta property-nya. Lalu di
akhir, method parse_args() wajib ditulis dan pengaksesan nilai flag dilakukan
dari object kembalian method tersebut.
Program di bawah ini berisi peneprapan flag argument untuk program
sederhana yang kegunaannya untuk pembuatan file. Nama dan path file
beserta isinya dikontrol via CLI flag.
Coba jalankan program di atas dengan perintah standar python main.py .
Outpunya:
Error muncul, karena ada salah satu flag yang di-setting untuk wajib diisi, yaitu
--path . Bisa dilihat pada statement parser.add_argument("--path", ...)
di atas, disitu parameter required di-isi dengan True , menjadikan
pemanggilan program tanpa flag ini memunculkan error.
import argparse
def main():
parser = argparse.ArgumentParser(
prog='File Manager',
description='Managing file easily'
)
parser.add_argument("--path", help="path of the file/folder",
default="file.txt", required=True)
parser.add_argument("--content", help="content of the file",
default="")
args = parser.parse_args()
with open(args.path, 'a') as f:
f.write(args.content)
if __name__ == "__main__":
main()
Untuk melihat flag apa saja yang tersedia, gunakan flag --help atau -h .
Dengan flag tersebut, informasi nama program dan flag yang tersedia
dimunculkan.
Sekarang coba jalankan command dengan disertai isi flag --path dan --
content . Program akan berjalan sesuai desain. File terbuat dengan isi sesuai
nilai flag --content .
python main.py --path "./file.txt" --content "hello python"
cat file.txt
Kembali ke bagian deklarasi flag memakai parser.add_argument() ,
dalam pembuatannya ada beberapa konfigurasi yang bisa dimanfaatkan sesuai
kebutuhan, diantaranya:
Parameter Keterangan
Positional param
Diisi dengan nama flag, umumnya
memakai notasi --nama untuk flag
dengan label kata atau frasa, dan -n saja
untuk huruf. Keduanya juga bisa digunakan
bersamaan, misalnya
parser.add_argument("--path", "-p", ...)
baru setelahnya diikuti keyword argument.
Keyword param help Diisi dengan informasi keterangan flag.Nantinya muncul saat --help digunakan.
Keyword param default Diisi dengan nilai default flag ketika tidakditulis nilainya secara explicit.
Keyword param required
Penanda apakah flag wajib diisi atau opsional.
Jika diisi True maka wajib untuk diisi dan
memunculkan error jika tidak diisi
Keyword param choices
Jika diisi dengan nilai list, maka element list
menjadi opsi pengisian flag. Jika saat
pemanggilan flag diisi dengan nilai yang tidak
ada di list maka error muncul.
Selain parameter di atas, ada juga beberapa lainnya. Selengkapnya bisa
cek di halaman dokumentasi https://docs.python.org/3/library/
argparse.html
Ok, agar makin paham, mari praktek lagi dengan memodifikasi program
sebelumnya menjadi seperti ini:
Perbedaan program terbaru dibanding sebelumnya:
• Flag baru ditambahkan bernama --operation-mode atau -op , flag ini
yang wajib diisi nilai write file atau list items .
def main():
parser = argparse.ArgumentParser(
prog='File Manager',
description='Managing file easily'
)
parser.add_argument("--operation-mode", "-op", help="choose
operation", choices=["write file", "list items"], required=True)
parser.add_argument("--path", "-p", help="path of the file/folder",
default=".", required=True)
parser.add_argument("--content", "-c", help="content of the file",
default="")
args = parser.parse_args()
if args.operation_mode == "write file":
with open(args.path, 'a') as f:
f.write(args.content)
elif args.operation_mode == "list items":
for f in glob.glob(f"{args.path}/**", recursive=True):
print(f)
if __name__ == "__main__":
main()
• Flag --path dibuatkan shorthand-nya yaitu -p .
• Flag --content dibuatkan shorthand-nya yaitu -c .
• Ketika flag -op bernilai write file , maka program melakukan penulisan
konten dengan isi dan tujuan file sesuai dengan nilai flag saat eksekusi.
• Ketika flag -op bernilai list items , maka program menampilkan list
files/folders pada path yang ditentukan via flag --path .
O iya, perlu diketahui bahwa ketika flag labelnya yaitu frasa dan
memakai karakter - sebagai pembatas kata, maka pengaksesannya
memakai pembatas _ . Contohnya bisa dilihat pada flag --operation-
mode yang pengaksesan nilainya dilakukan via args.operation_mode .
Jalankan program dengan 3 perintah berikut lalu lihat outputnya:
Output program:
python.exe main_4.py --help
python.exe main_4.py --op "write file" -p "./file.txt" -c "hello python"
python.exe main_4.py --op "list items" -p "./"
Catatan chapter 📑📑
â—‰ Source code praktik
github.com/novalagung/dasarpemrogramanpython-example/../cli-
arguments-flags
â—‰ Chapter relevan lainnya
• File I/O
â—‰ TBA
• Flag without value https://stackoverflow.com/questions/8259001/python-
argparse-command-line-flags-without-arguments
â—‰ Referensi
• https://docs.python.org/3/library/argparse.html
• https://stackoverflow.com/questions/35603729/difference-between-single-
dash-and-double-dash-in-argparse
A.51. Python CSV File/
Data Format
Pada chapter ini kita akan belajar tentang penggunaan Python untuk membaca
dan mengelola data CSV.
INFO
CSV sendiri merupakan suatu format data yang sangat populer digunakan
untuk menyimpan data berbasis tabular. Struktur isi CSV kurang lebih
seperti ini:
Penjelasan singkat tentang CSV:
• Baris pertama umumnya berisi informasi header, atau nama kolom.
• Di contoh di atas, ada 3 buah header, yaitu name , email , dan
phone .
• Tanda koma default-nya digunakan sebagai pembatas data dan kolom.
• Setiap baris data ditandai dengan newline atau baris baru. Umumnya
data dimulai pada baris ke-2.
• Di setiap baris, data ditulis sesuai urutan header memakai
pembatas tanda koma.
• Bisa saja ada data yang isinya tidak lengkap, misalnya di contoh data
name,email,phone
Noval,[email protected],087877665
John Doe,[email protected],
Garrosh Hellscream,,098878212
ke-2 tidak memiliki data phone , dan data ke-3 tidak memiliki data
email .
A.51.1. Implementasi CSV di Python
Python menyediakan beberapa API untuk berinteraksi dengan data CSV, ada
csv.DictWriter() dan csv.writer() untuk operasi tulis data, dan
csv.DictReader() dan csv.reader() untuk operasi baca data.
Pembelajaran pada chapter ini dilakukan lewat pembuatan program sederhana
yang mengakomodir operasi create, read, dan delete data.
Sebelum mulai, silakan siapkan project baru dengan isi sebuah file main.py
berisi kode berikut:
def control_flow():
while True:
print("Choose mode:")
print("1. Write data")
print("2. Read data")
print("3. Delete by row")
print("4. Exit")
mode = input('Choice (1/2/3/4): ')
if mode == '1':
pass # to be replaced
elif mode == '2':
pass # to be replaced
elif mode == '3':
pass # to be replaced
elif mode == '4':
break
else:
Program yang dibuat yaitu aplikasi CLI interaktif, dimana user bisa
berinteraksi dengan program sesuai pilihan mode. Ada 4 buah mode:
1. Insert data (ke file CSV)
2. Read data (dari file CSV)
3. Delete data berdasarkan index
4. Exit program
Selanjutnya, program dimodifikasi dengan penambahan implementasi untuk
masing-masing mode.
A.51.2. Insert data CSV
Sebuah file CSV akan dibuat dan difungsikan sebagai database untuk
penyimpanan data yang di-insert via program. File CSV berisi 3 buah kolom
data point:
• Name
• Email
• Phone
Pertama, buka file dimana kode ditulis, lalu tambahkan kode berikut di awal
program:
import csv
filename = 'data.csv'
fieldnames = ['name', 'email', 'phone']
def prepare_csv():
with open(filename, 'w', newline='') as f:
writer = csv.DictWriter(f, fieldnames=fieldnames)
Fungsi prepare_csv() bertugas untuk membuat file csv bernama data.csv
dengan isi kosong. Di dalam fungsi tersebut proses berikut dilakukan:
• Fungsi open() membuka file data.csv dengan mode tulis ( w ). Disitu
parameter opsional newline diisi dengan string kosong agar di akhir file
tidak dituliskan baris baru.
• Fungsi csv.DictWriter() parameter pertama diisi object file, dan
parameter fieldnames diisi informasi header dalam bentuk list.
• Method writeheader() milik object writer digunakan untuk menulis
header ke file.
Sekarang fokus ke fungsi main() , panggil fungsi prepare_csv() yang telah
dibuat. Kode fungsi main() setelah perubahan menjadi seperti ini:
Coba jalankan program, lalu cek isi file data.csv untuk memastikan operasi
penulisan header berjalan sesuai seharusnya.
Output program:
def main():
prepare_csv()
control_flow()
Selanjutnya, buat lagi fungsi baru bernama write_data() , gunanya untuk
penulisan data name , email , dan phone ke file data.csv .
Untuk menulis data CSV, cara awalnya kurang lebih sama, yaitu object file
dibuat dulu memakai fungsi open() kemudian dimasukan ke
csv.DictWriter() . Selain itu, ada beberapa perbedaan dibanding kode
sebelumnya:
• Disini file dibuka memakai mode append ( a ). Hal ini agar header
yang sudah ditulis di file tidak hilang.
• Method writerow() milik writer digunakan untuk pengisian data.
Penggunaannya mengharuskan data untuk diformat dalam bentuk
dictionary.
Data yang bisa dituliskan ke CSV yaitu int , float , dan str . Jika ada tipe
data lain yang perlu disimpan di CSV, harus dikonversi ke format yang
kompatibel terlebih dahulu, misalnya str .
Selanjutnya, pada fungsi control_flow() pada seleksi kondisi mode == 1
ganti statement pass dengan kode baru yang meminta 3 inputan dari user
kemudian memakai nya sebagai argument pemanggilan fungsi
write_data() .
def write_data(name, email, phone):
with open(filename, 'a', newline='') as f:
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writerow({
'name': name,
'email': email,
'phone': phone
})
Jalankan program lalu coba test fungsionalitasnya dengan insert beberapa
data. Bisa dilihat pada contoh eksekusi program berikut, file CSV berisi data
sesuai operasi insert saat eksekusi program.
def control_flow():
while True:
print("Choose mode:")
print("1. Write data")
print("2. Read data")
print("3. Delete by row")
print("4. Exit")
mode = input('Choice (1/2/3/4): ')
if mode == '1':
name = input("Name: ")
email = input("Email: ")
phone = input("Phone: ")
write_data(name, email, phone)
elif mode == '2':
pass # to be replaced
elif mode == '3':
pass # to be replaced
elif mode == '4':
break
else:
print('Invalid mode')
A.51.3. Read data CSV
Operasi baca data dilakukan via fungsi csv.DictReader() dengan argument
parameter yaitu object file. Lewat object reader, gunakan fungsi
enumerate() untuk membungkusnya lalu lakukan iterasi memakai
keyword for . Lebih jelasnya silakan lihat kode read_data() berikut, dan tak
lupa tambahkan ke program.
Di fungsi control_flow() panggil fungsi read_data() pada block seleksi
kondisi mode == 2 .
Sekarang jalankan program untuk pengetesan.
def read_data():
with open(filename, 'r') as csvfile:
reader = csv.DictReader(csvfile)
for index, row in enumerate(reader):
print(" ->", f"(row {index + 1})", row['name'], row['email'],
row['phone'])
def control_flow():
while True:
print("Choose mode:")
print("1. Write data")
print("2. Read data")
print("3. Delete by row")
print("4. Exit")
mode = input('Choice (1/2/3/4): ')
if mode == '1':
name = input("Name: ")
email = input("Email: ")
phone = input("Phone: ")
write_data(name, email, phone)
elif mode == '2':
read_data()
elif mode == '3':
pass # to be replaced
elif mode == '4':
break
else:
print('Invalid mode')
Bisa dilihat isi data yang muncul via pemanggilan fungsi read_data() sesuai
dengan data yang di-insert.
A.51.4. Delete data CSV
Operasi delete data bisa dilakukan dengan menuliskan ulang isi file CSV tetapi
meng-exclude data yang ingin dihapus. Kurang lebih kodenya seperti ini:
File CSV dibaca dua kali:
• Pembacaan pertama yaitu untuk pengambilan list data untuk disimpan
ke variabel rows
• Pembacaan ke-2 yaitu untuk penulisan ulang header ke file CSV dan juga
data terkecuali untuk baris data yang dihapus.
Setelah itu, panggil fungsi delete_data() di fungsi control_flow() :
def delete_data(row_index):
with open(filename, 'r') as csvfile:
reader = csv.DictReader(csvfile)
rows = list(reader)
with open(filename, 'w', newline='') as csvfile:
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
writer.writeheader()
for index, row in enumerate(rows):
if index != (row_index - 1):
writer.writerow({
'name': row['name'],
'email': row['email'],
'phone': row['phone']
})
Jalankan ulang program, test fungsionalitas mode 1, 2, dan 3.
def control_flow():
while True:
print("Choose mode:")
print("1. Write data")
print("2. Read data")
print("3. Delete by row")
print("4. Exit")
mode = input('Choice (1/2/3/4): ')
if mode == '1':
name = input("Name: ")
email = input("Email: ")
phone = input("Phone: ")
write_data(name, email, phone)
elif mode == '2':
read_data()
elif mode == '3':
row_index = int(input("Row index: "))
delete_data(row_index)
elif mode == '4':
break
else:
print('Invalid mode')
Kurang lebih seperti itu penerapan operasi CSV di Python. Silakan lanjut
explore dan praktek dengan pembuatan program sejenis lainnya agar makin
paham.
A.51.4. csv.writer() dan csv.reader()
Selain memakai fungsi csv.DictWriter() dan csv.DictReader() ,
operasi baca tulis CSV bisa dilakukan memakai fungsi csv.writer() dan
csv.reader() .
Caranya mirip namun ada perbedaan di bagian struktur data sewaktu menulis
dan membaca data. Di 2 method sebelumnya, data perlu dibentuk dalam
format dictionary. Sedangkan pada 2 fungsi ini, data ditulis dalam list.
Program berikut berisi fungsionalitas yang sama persis dengan program
sebelumnya, namun memakai fungsi csv.writer() dan csv.reader() .
Dari sini silakan pelajari perbedaannya.
import csv
def prepare_csv():
with open('data.csv', 'w', newline='') as f:
writer = csv.writer(f)
writer.writerow(['name', 'email', 'phone'])
def write_data(name, email, phone):
with open('data.csv', 'a', newline='') as f:
writer = csv.writer(f)
writer.writerow([name, email, phone])
def read_data():
with open('data.csv', 'r') as csvfile:
reader = csv.reader(csvfile)
for index, row in enumerate(reader):
Catatan chapter 📑📑
â—‰ Source code praktik
github.com/novalagung/dasarpemrogramanpython-example/../csv
â—‰ Chapter relevan lainnya
• File I/O
â—‰ Referensi
• https://docs.python.org/3/library/csv.html
A.52. Python JSON File/
Data Format
Pada chapter ini kita akan belajar tentang penerapan tipe data JSON di Python.
INFO
JSON atau JavaScript Object Notation yaitu format data yang sangat
populer digunakan dalam pembuatan aplikasi. Strukturnya sederhana dan
mudah dipahami.
Contoh data JSON:
{
"glossary": {
"title": "example glossary",
"GlossDiv": {
"title": "S",
"GlossList": {
"GlossEntry": {
"ID": "SGML",
"SortAs": "SGML",
"GlossTerm": "Standard Generalized Markup
Language",
"Acronym": "SGML",
"Abbrev": "ISO 8879:1986",
"GlossDef": {
"para": "A meta-markup language, used to
create markup languages such as DocBook.",
"GlossSeeAlso": ["GML", "XML"]
},
"GlossSee": "markup"
Data JSON bisa tersimpan di file berekstensi .json atau bisa juga
tersimpan di variabel sebagai data string. Contoh:
A.52.1. Implementasi JSON di Python
Operasi JSON di Python umumnya dilakukan terhadap data yang tersimpan di
variabel/memory atau data yang tersimpan di file, dengan memanfaatkan
module json (baawan Python Standard Library) untuk proses decode maupun
encode data json.
• Operasi pembacaan data JSON dari file, isi file harus dibaca terlebih dahulu
secara menyeluruh, kemudian barulah di-decode ke bentuk dictionary atau
slice atau lainnya (sesuai kebutuhan).
• Sedangkan operasi penulisan data JSON ke file bisa, caranya dengan
menulis langsung data json dalam bentuk string ke file.
JSON (yang basisnya yaitu JavaScript) memiliki kompatibilitas yang cukup
bagus dengan tipe data yang tersedia di Python. Lebih jelasnya silakan lihat
tabel kompatibilitas tipe data berikut:
jstr1 = '{ "id": 2, "name": "Noval Agung Prayogo" }'
jstr2 = """
[{
"id": 2,
"name": "Noval Agung Prayogo"
}]
"""
Python data type JSON data type
int number
float float
str string
bool boolean
list array
tuple array
dict object
â—‰ Encode data Python ke JSON string
Operasi konversi data ke bentuk JSON string dilakukan memakai
json.dumps() , tersedia di Python Standard Library.
Selama data object yang akan di-encode berisi tipe yang di-support sesuai
tabel di atas, maka operasi encode ke JSON string berjalan sukses. Sedangkan
jika object berisi tipe yang tidak di-support, maka harus dikonversi ke salah
satu tipe data yang kompatibel terlebih dahulu (misalnya str ) sebelum di-
encode memakai json.dumps() .
Contoh operasi encode data dict dengan isi item str dan list :
import json
Contoh data lain dengan struktur list berisi elemen dictionary:
import json
data = [
{
'faction': 'Horde',
'color': 'red',
'founding_members': [
'Orc',
'Undead',
'Tauren',
'Troll',
'Blood Elf',
'Goblin'
],
'total_members': 13,
'active': True,
},
{
'faction': 'Alliance',
'color': 'blue',
'founding_members': [
'Human',
'Dwarf',
'Night Elf',
'Gnome',
'Draenei',
'Worgen'
],
'total_members': 13,
'active': True,
}
]
jstr = json.dumps(data, indent=4)
print(jstr)
Pada contoh di atas, JSON string di-format dengan indent sebanyak 4.
Nilai indent bisa dikonfigurasi via parameter opsional indent .
Untuk data dengan isi yaitu tipe data yang tidak kompatibel dengan operasi
JSON di Python, penggunaannya pada json.dumps() menghasilkan error.
Contohnya pada kode berikut ada tipe data set disitu.
Output program:
import json
data = [
{
'colors': {'black', 'white'},
}
]
jstr = json.dumps(data)
print(jstr)
â—‰ Decode JSON string ke data Python
Proses decode data JSON string ke tipe data Python dilakukan memakai
fungsi json.loads() . Fungsi ini mengembalikan data sesuai dengan struktur
JSON string-nya (misalnya: JSON string berisi array object, maka data
kembalian fungsi json.loads() yaitu slice berisi dictionary).
import json
jstr1 = '{ "name": "Maiev Shadowsong", "affliations": ["Warden",
Contoh lain operasi decode data JSON string berisi array object:
â—‰ Menulis data JSON ke file
Penulisan data JSON ke file sangat mudah, dilakukan memakai teknik
penulisan standar file (kombinasi keyword with , fungsi open() dan method
write() milik object file) dengan syarat: data yang akan ditulis ke file harus
berbentuk string.
• Contoh penulisan data JSON string ke JSON file:
jstr2 = """
[{
"name": "Maiev Shadowsong",
"affliations": ["Warden", "Alliance"],
"age": 10000
}, {
"name": "Illidan Stormrage",
"affliations": ["Illidari", "Armies of Legionfall"],
"age": 15000
}]
"""
data2 = json.loads(jstr2)
print(f"type: {type(data2).__name__}")
# output ➜ type: list
for row in data2:
print(f"-> name: {row["name"]}, afflications: {row["affliations"]},
age: {row["age"]}")
# output ↓
#
# -> name: Maiev Shadowsong, afflications: ['Warden', 'Alliance'], age:
10000
# -> name: Illidan Stormrage, afflications: ['Illidari', 'Armies of
Legionfall'], age: 15000
Outcome program: file data.json terbuat dengan isi yaitu JSON string
yang ada di variabel jstr .
• Penulisan data Python ke JSON file dilakukan dengan mengkonversi data ke
JSON string terlebih dahulu, kemudian barulah ditulis ke file. Contoh:
Outcome program: file data.json terbuat dengan isi yaitu JSON string
hasil proses encoding json.dumps() terhadap data di variabel data .
jstr = """
[{
"name": "Maiev Shadowsong",
"affliations": ["Warden", "Alliance"],
"age": 10000
}, {
"name": "Illidan Stormrage",
"affliations": ["Illidari", "Armies of Legionfall"],
"age": 15000
}]
"""
with open('data.json', 'w') as f:
f.write(jstr)
import json
data = {
'name': 'Maiev Shadowsong',
'affliations': ['Warden', 'Alliance']
}
jstr = json.dumps(data)
with open('data.json', 'w') as f:
f.write(jstr)
â—‰ Membaca JSON file
Operasi baca JSON file dilakukan dengan membaca file seperti biasa lalu di-
decode memakai fungsi json.loads() .
Contoh penerapannya bisa dilihat pada program di bawah ini. Sebelumnya,
pastikan untuk menyediakan sebuah file JSON untuk keperluan testing dengan
nama data.json . Isi file tersebut dengan data JSON string berikut:
Lalu tulis kode berikut kemudian run:
{"name": "Maiev Shadowsong", "affliations": ["Warden", "Alliance"]}
import json
data = []
with open('data.json', 'r') as f:
data = json.loads(f.read())
for key in data:
print(f"{key}: {data[key]}")
# output ↓
#
# name: Maiev Shadowsong
# affliations: ['Warden', 'Alliance']
Catatan chapter 📑📑
â—‰ Source code praktik
github.com/novalagung/dasarpemrogramanpython-example/../json
â—‰ Chapter relevan lainnya
• File I/O
â—‰ Referensi
• https://docs.python.org/3/library/csv.html
A.53. Python Date, Time,
DateTime, Timezone
Pada chapter ini kita akan belajar tentang tipe data date , time , datetime
untuk penyimpanan informasi tanggal dan waktu di Python, serta peran dari
tipe data timezone untuk penentuan zona waktu.
A.53.1. Pengenalan date , time , dan
datetime
Python menyediakan package datetime berisi banyak sekali API untuk
keperluan operasi data yang berhubungan dengan tanggal dan waktu. Tiga
diantaranya yaitu tipe data berikut:
• Tipe data class date untuk penyimpanan informasi tanggal
from datetime import date
data_date = date(year=2020, month=1, day=31)
print("date:", data_date)
print(" ➜ year:", data_date.year)
print(" ➜ month:", data_date.month)
print(" ➜ day:", data_date.day)
# output ↓
#
# date: 2020-01-31
# ➜ year: 2020
# ➜ month: 1
# ➜ day: 31
• Tipe data class time untuk penyimpanan informasi waktu (jam, menit,
detik)
• Tipe data class datetime untuk penyimpanan informasi tanggal dan
waktu
from datetime import time
data_time = time(hour=13, minute=14, second=31)
print("time:", data_time)
print(" ➜ hour:", data_time.hour)
print(" ➜ minute:", data_time.minute)
print(" ➜ second:", data_time.second)
print(" ➜ timezone:", data_time.tzinfo)
# output ↓
#
# time: 13:14:31
# ➜ hour: 13
# ➜ minute: 14
# ➜ second: 31
# ➜ timezone: None
from datetime import datetime
data_datetime = datetime(year=2020, month=1, day=31, hour=13,
minute=14, second=31)
print("datetime:", data_datetime)
print(" ➜ year:", data_datetime.year)
print(" ➜ month:", data_datetime.month)
print(" ➜ day:", data_datetime.day)
print(" ➜ hour:", data_datetime.hour)
print(" ➜ minute:", data_datetime.minute)
print(" ➜ second:", data_datetime.second)
Pengaksesan informasi unit waktu (seperti hari, tahun, jam, dan lainnya)
dilakukan via attribute. Mengenai nama attribute-nya silakan lihat di kode di
atas.
Tipe data datetime berada di package bernama sama yaitu datetime .
Pada contoh di atas, tipe data datetime di-import dari package-nya.
Contoh jika yang di-import yaitu package datetime penggunaan tipe
datetime seperti ini:
datetime.datetime(year=2020, month=1, day=31, hour=13,
minute=14, second=31)
Jangan sampai bingung ya.
Khusus untuk tipe data yang juga menyimpan informasi waktu (seperti time
dan datetime ), disitu ada attribute bernama timezone isinya informasi zona
waktu. By default, zona waktu yaitu kosong atau None .
â—‰ Combining date & time
Tipe date dan time bisa dikominasikan untuk menciptakan object baru
bertipe datetime . Caranya via class method combine milik tipe data
datetime
data_datetime = datetime.combine(data_date, data_time)
print("datetime:", data_datetime)
print(" ➜ year:", data_datetime.year)
print(" ➜ month:", data_datetime.month)
print(" ➜ day:", data_datetime.day)
print(" ➜ hour:", data_datetime.hour)
print(" ➜ minute:", data_datetime.minute)
â—‰ Mengambil datetime hari ini / sekarang
Mengambil waktu hari ini dilakukan memakai method today , ini bisa
diterapkan untuk tipe data datetime maupun date . Sedangkan mengambil
waktu sekarang hanya bisa dilakukan pada tipe data datetime memakai
method now . Contoh penerapannya bisa dilihat pada kode berikut.
Kode di atas outputnya yaitu sesuai dengan output program di local
penulis saat program di run. Di tempat pembaca output pastinya
berbeda.
A.53.2. Pengenalan timezone ( tz )
Setiap tipe data yang menyimpan informasi waktu (seperti time dan
datetime ) didalamnya ada informasi timezone yang bisa diakses ataupun
ditentukan saat pembuatan data. Informasi timezone direpresentasikan
memakai dateutil.tz , tipe data tz dalam package dateutil .
data1 = datetime.now()
print("sekarang (datetime):", data1)
# output ➜ sekarang (datetime): 2023-12-23 11:50:45.303421
data2 = datetime.today()
print("sekarang (datetime):", data2)
# output ➜ sekarang (datetime): 2023-12-23 11:50:45.303422
data2 = date.today()
print("sekarang (date):", data2)
# output ➜ sekarang (date): 2023-12-23
Method tz.gettz() digunakan untuk membuat data timezone. Contoh
pengaplikasiannya:
• Membuat data timezone New York atau EST (Eastern Time):
• Membuat data timezone WIB (Waktu Indonesia Barat) atau GMT+7:
Selengkapnya mengenai list timezone identifier silakan cek di
https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
Penerapan tz dalam pembuatan data time dan timezone dilakukan via
pengisian parameter tzinfo . Contoh penerapannya:
• Timezone pada tipe time :
• Timezone pada tipe datetime :
tzinfo = tz.gettz("America/New_York")
tzinfo = tz.gettz("Asia/Jakarta")
from dateutil import tz
from datetime import time
tzinfo = tz.gettz("America/New_York")
data_time = time(hour=13, minute=14, second=31, tzinfo=tzinfo)
print("time:", data_time)
# output ➜ time: 13:14:31
print("timezone:", data_time.tzinfo)
# output ➜ timezone: tzfile('US/Eastern')
• Timezone pada tipe datetime hasil kombinasi date dan time :
â—‰ Local timezone vs. UTC vs. specific timezone vs. no
timezone
Selain method tz.gettz() ada juga 2 method untuk keperluan timezone
lainnya, yaitu:
from dateutil import tz
from datetime import datetime
tzinfo = tz.gettz("America/New_York")
data_datetime = datetime(year=2020, month=1, day=31, hour=13,
minute=14, second=31, tzinfo=tzinfo)
print("datetime:", data_datetime)
# output ➜ datetime: 2020-01-31 13:14:31-05:00
print("timezone:", data_time.tzinfo)
# output ➜ timezone: tzfile('US/Eastern')
from dateutil import tz
from datetime import date, time
tzinfo = tz.gettz("America/New_York")
data_date = date(year=2020, month=1, day=31)
data_time = time(hour=13, minute=14, second=31)
data_datetime = datetime.combine(data_date, data_time, tzinfo=tzinfo)
print("datetime:", data_datetime)
# output ➜ datetime: 2020-01-31 13:14:31-05:00
print("timezone:", data_time.tzinfo)
# output ➜ timezone: tzfile('US/Eastern')
• Method tz.tzlocal() untuk membuat data timezone sesuai waktu local
• Method tz.tzutc() untuk membuat data timezone dengan offset UTC
Contoh penerapan:
Silakan perhatikan ke-4 output statement print di atas. Kesemuanya berisi
informasi datetime yang sama persis namun berbeda timezone. Meskipun
informasi tanggal dan waktunya sama persis, jika timezone-nya berbeda maka
data tersebut menunjukkan datetime yang benar-benar berbeda.
â—‰ Konversi datetime antar timezone
Melanjutkan pembahasan section sebelumnya, data 2020-01-31
from dateutil import tz
from datetime import date, time, datetime
tzinfo = tz.tzlocal()
data_datetime = datetime(2020, 1, 31, 13, 14, 31, tzinfo=tzinfo)
print("datetime:", data_datetime)
# output ➜ datetime: 2020-01-31 13:14:31+07:00
tzinfo = tz.tzutc()
data_datetime = datetime(2020, 1, 31, 13, 14, 31, tzinfo=tzinfo)
print("datetime:", data_datetime)
# output ➜ datetime: 2020-01-31 13:14:31+00:00
tzinfo = tz.gettz("America/New_York")
data_datetime = datetime(2020, 1, 31, 13, 14, 31, tzinfo=tzinfo)
print("datetime:", data_datetime)
# output ➜ datetime: 2020-01-31 13:14:31-05:00
data_datetime = datetime(2020, 1, 31, 13, 14, 31)
print("datetime:", data_datetime)
# output ➜ datetime: 2020-01-31 13:14:31
13:14:31+07:00 yaitu ekuivalen dengan:
• Data 2020-01-31 06:14:31+00:00 pada zona waktu UTC
• Data 2020-01-31 01:14:31-05:00 pada zona waktu New York
Sampai sini bisa disimpulkan bahwa:
• Dua buah datetime yaitu tidak sama jika informasi datetime sama persis
namun timezone-nya berbeda.
• Dua buah datetime bisa saja ekuivalen atau sama meskipun informasi
datetime dan timezone-nya berbeda.
Cara manual untuk mencari data datetime di zona waktu lain yaitu dengan
melakukan operasi tambah/kurang terhadap timezone-nya. Misalnya: Data
2020-01-31 13:14:31 WIB (GMT+7), kalau dikonversi ke timezone UTC
caranya cukup dengan kurangi saja dengan 7 jam, hasilnya: 2020-01-31
06:14:31 UTC (GMT+0).
Atau, praktisnya bisa dengan memakai method astimezone() milik tipe
data datetime .
def print_dt(d):
print("datetime:", d, "| tz:", d.tzname())
from dateutil import tz
from datetime import date, time, datetime
data = datetime(2020, 1, 31, 13, 14, 31, tzinfo=None)
print_dt(data)
# output ➜ datetime: 2020-01-31 13:14:31 | tz: None
data_local_tz = data.astimezone(tz.tzlocal())
print_dt(data_local_tz)
# output ➜ datetime: 2020-01-31 13:14:31+07:00 | tz: SE Asia Standard Time
Penjelasan:
• Variabel data dibuat dengan isi datetime 2020-01-31 13:14:31 tanpa
informasi timezone.
• Penerapan method astimezone() terhadap data tanpa timezone berefek
ke penambahan timezone tanpa perubahan waktu.
â—¦ Variabel data_local_tz berisi informasi datetime yang sama persis
dengan data tapi dengan timezone yaitu WIB atau GMT+7.
• Kemudian variabel data_local_tz dikonversi ke timezone New York dan
hasilnya disimpan di variabel data_new_york_tz . Variabel ini berisi data
yang mengarah ke suatu waktu yang sama tapi berbeda timezone.
â—¦ Pada tanggal 31 Januari 2020, selisih jam antara GMT+7 dan New York
tz (EST) yaitu sebanyak -12 jam , maka output hasil konversi
timezone data 2020-01-31 13:14:31+07:00 WIB yaitu 2020-01-31
01:14:31-05:00 EST.
• Lalu variabel data_new_york_tz dikonversi ke UTC timezone dengan hasil
disimpan di variabel data_utc_tz .
â—¦ Pada tanggal 31 Januari 2020, selisih jam antara New York tz (EST) dan
UTC yaitu sebanyak +5 jam , maka output hasil konversi timezone
data 2020-01-31 01:14:31-05:00 EST yaitu 2020-01-31
06:14:31+00:00 UTC.
Semoga sampai sini cukup jelas.
INFO
Dalam konversi timezone, komputer membutuhkan setidaknya 2 hal agar
konversi timezone terhadap data datetime menghasilkan output yang
valid, yaitu:
• Informasi timezone asal dan tujuan
• Informasi tanggal timezone asal atau tujuan.
Poin ke-2 sangat penting untuk diketahui karena beberapa timezone
mengadopsi sistem yang didalamnya ada pergeseran jam sebanyak 2 kali
dalam setahun. Contohnya seperti timezone Pacific Time (PT). Selisih atau
offset timezone PT terhadap UTC di bulan Juni yaitu -7 jam sedangkan
pada bulan Desember yaitu −8 jam . Unik bukan?
Selengkapnya https://en.wikipedia.org/wiki/Pacific_Time_Zone
â—‰ Mengubah timezone tanpa konversi datetime
Untuk mengkonversi suatu data datetime ke timezone lain, gunakan method
astimezone() . Namun untuk merubah timezone tanpa melakukan konversi
waktu, maka gunakan method replace() . Contoh:
def print_dt(d):
print("datetime:", d, "| tz:", d.tzname())
from dateutil import tz
from datetime import date, time, datetime
data = datetime(2020, 1, 31, 13, 14, 31, tzinfo=None)
print_dt(data)
# output ➜ datetime: 2020-01-31 13:14:31 | tz: None
data_local_tz = data.replace(tzinfo=tz.tzlocal())
Catatan chapter 📑📑
â—‰ Source code praktik
github.com/novalagung/dasarpemrogramanpython-example/../datetime-
timezone
â—‰ Chapter relevan lainnya
• DateTime ➜ Parsing & Formatting
â—‰ TBA
• Locale
â—‰ Referensi
• https://docs.python.org/3/library/datetime.html
• https://stackoverflow.com/questions/3305413/
• https://realpython.com/python-datetime/
• https://en.wikipedia.org/wiki/Pacific_Time_Zone
A.54. Python DateTime
Parsing & Formatting
Chapter ini merupakan lanjutan dari chapter sebelumnmya. Di sini kita akan
belajar tentang teknik parsing dan formatting pada tipe data datetime .
A.54.1. Parsing datetime
Parsing yaitu teknik konversi data date time berbentuk string ke tipe data
datetime . Ada beberapa method yang tersedia untuk kebutuhan operasi ini:
â—‰ Via datetime.strptime() dan kode format
Class method datetime.strptime() digunakan untuk parsing string ke
datetime dalam kombinasi kode format tertentu. Kode format sendiri
merepresentasikan setiap unit waktu, misalnya:
• Kode format tahun yaitu %Y
• Kode format jam yaitu %H
• Kode format menit yaitu %M
• dan lainnya.
Contoh implementasinya seperti ini:
• Contoh ke-1, parsing data 1985-04-12 23:20:50 :
from datetime import datetime
• Contoh ke-2, parsing data 1985-04-12T23:20:50.52+0700 :
Selengkapnya silakan cek di bagian A.54.3. Tabel kode format.
â—‰ Via datetime.fromisoformat() terhadap data ISO
Date Time (ISO 8601)
Untuk data waktu berbentuk string sesuai spesifikasi ISO Date Time atau ISO
8601, konversi ke bentuk datetime bisa dilakukan secara praktis
memakai datetime.fromisoformat() .
â—‰ Via datetime.fromtimestamp() terhadap data UNIX
timestamp
Data dengan format UNIX timestamp 10 digit bisa dikonversi ke bentuk
from datetime import datetime
date_string = '1985-04-12T23:20:50.52+0700'
format_string = '%Y-%m-%dT%H:%M:%S.%f%z'
data_datetime = datetime.strptime(date_string, format_string)
print("datetime:", data_datetime)
# output ➜ datetime: 1985-04-12 23:20:50.520000+07:00
data_datetime = datetime.fromisoformat('1985-04-12T23:20:50.52')
print("datetime:", data_datetime)
# output ➜ datetime: 1985-04-12 23:20:50.520000
data_datetime = datetime.fromisoformat('1985-04-12T23:20:50.52+0700')
print("datetime:", data_datetime)
# output ➜ datetime: 1985-04-12 23:20:50.520000+07:00
datetime memakai method fromtimestamp() .
Untuk timestamp dengan digit lebih dari 10, informasi milisecond-nya bisa
ditulis sebagai nilai floating point, misalnya:
Informasi timezone juga bisa ditentukan pada saat parsing. Caranya gunakan
parameter tz method di atas:
â—‰ Via dateutil.parser.parse()
Method parse() milik dateutil.parser cukup cerdas untuk mengenali
banyak jenis format (selama format tersebut umum digunakan). Contoh
penerapannya:
data_datetime = datetime.fromtimestamp(1702980333)
print("datetime:", data_datetime)
# output ➜ datetime: 2023-12-19 17:05:33
data_datetime = datetime.fromtimestamp(1702980333.244)
print("datetime:", data_datetime)
# output ➜ datetime: 2023-12-19 17:05:33.244000
from dateutil import tz
data_datetime = datetime.fromtimestamp(1702980333.244,
tz=tz.gettz("America/New_York"))
print("datetime:", data_datetime)
# output ➜ datetime: 2023-12-19 05:05:33.244000-05:00
from dateutil import parser
Selengkapnya mengenai format yang didukung oleh parser ini bisa di cek di
halaman dokumentasi Python https://dateutil.readthedocs.io/en/stable/
parser.html
A.54.2. Formatting datetime
Formatting yaitu teknik untuk memformat data datetime menjadi bentuk
string dengan susunan/format sesuai keinginan. Beberapa method untuk
operasi formatting datetime bisa dilihat di bawah ini:
â—‰ Method datetime.strftime() dan kode format
Method formatting datetime.strftime() tersedia pada tipe data datetime,
pemanggilannya disertai dengan kode format yang diinginkan untuk output.
Perihal kode format sendiri yaitu sama dengan yang digunakan pada teknik
parsing via strptime() .
Contoh penerapannya:
Selengkapnya silakan cek di bagian A.54.3. Tabel kode format.
◉ Method datetime.isoformat() ➜ ISO Date Time (ISO
from datetime import datetime
data_datetime = datetime.fromtimestamp(1702980333, tz=None)
print(data_datetime.strftime('%Y-%m-%dT%H:%M:%S.%f%z'))
# output ➜ 2023-12-19T17:05:33.000000
data_datetime = datetime.fromisoformat('1985-04-12T23:20:50.52+0700')
print(data_datetime.strftime('%m/%d/%Y %H:%M:%S %z'))
# output ➜ 04/12/1985 23:20:50 +0700
8601)
Method ini menghasilkan output berbentuk string sesuai format ISO Date Time
(ISO 8601). Contoh penggunaan:
◉ Method datetime.timestamp() ➜ UNIX timestamp
Method ini menghasilkan output berbentuk UNIX timestamp bertipe float.
Angka dibelakang koma merepresentasikan miliseconds. Contoh penggunaan:
A.54.3. Tabel kode format
Tabel kode format sesuai 1989 C standard:
Kode format Penjelasan Contoh
%a Weekday as locale’s abbreviated name
Sun, Mon, …,
Sat (en_US); So,
Mo, …, Sa
(de_DE)
data_datetime = datetime.now()
print(data_datetime.isoformat())
# output ➜ 2023-12-23T14:01:03.088274
data_datetime = datetime.now()
print(data_datetime.timestamp())
# output ➜ 1703314863.975431
Kode format Penjelasan Contoh
%A Weekday as locale’s full name
Sunday,
Monday, …,
Saturday
(en_US);
Sonntag,
Montag, …,
Samstag
(de_DE)
%w Weekday as a decimal number, where0 is Sunday and 6 is Saturday 0, 1, …, 6
%d Day of the month as a zero-paddeddecimal number 01, 02, …, 31
%b Month as locale’s abbreviated name Jan, Feb, …, Dec(en_US)
%B Month as locale’s full name
January,
February, …,
December
(en_US)
%m Month as a zero-padded decimalnumber 01, 02, …, 12
%y Year without century as a zero-paddeddecimal number 00, 01, …, 99
Kode format Penjelasan Contoh
%Y Year with century as a decimal number
0001, 0002, …,
2013, 2014, …,
9998, 9999
%H Hour (24-hour clock) as a zero-paddeddecimal number 00, 01, …, 23
%I Hour (12-hour clock) as a zero-paddeddecimal number 01, 02, …, 12
%p Locale’s equivalent of either AM or PM AM, PM (en_US)
%M Minute as a zero-padded decimalnumber 00, 01, …, 59
%S Second as a zero-padded decimalnumber 00, 01, …, 59
%f Microsecond as a decimal number,zero-padded to 6 digits
000000,
000001, …,
999999
%z
UTC offset in the form
±HHMM[SS[.ffffff]] (empty string if the
object is naive)
(empty),
+0000, -0400,
+1030,
+063415,
-030712.345216
Kode format Penjelasan Contoh
%Z Time zone name (empty string if theobject is naive)
(empty), UTC,
GMT
%j Day of the year as a zero-paddeddecimal number
001, 002, …,
366
%U
Week number of the year (Sunday as
the first day of the week) as a zero-
padded decimal number. All days in a
new year preceding the first Sunday
are considered to be in week 0
00, 01, …, 53
%W
Week number of the year (Monday as
the first day of the week) as a zero-
padded decimal number. All days in a
new year preceding the first Monday
are considered to be in week 0
00, 01, …, 53
%c Locale’s appropriate date and timerepresentation
Tue Aug 16
21:30:00 1988
(en_US)
%x Locale’s appropriate daterepresentation
08/16/88
(None); 08/16/
1988 (en_US);
16.08.1988
(de_DE)
Kode format Penjelasan Contoh
%X Locale’s appropriate timerepresentation
21:30:00
(en_US);
21:30:00
(de_DE)
%% A literal '%' character %
Tabel kode format sesuai C89 standard:
Kode format Penjelasan Contoh
%G
ISO 8601 year with century
representing the year that contains
the greater part of the ISO week
(%V)
0001, 0002, …,
2013, 2014, …,
9998, 9999
%u ISO 8601 weekday as a decimalnumber where 1 is Monday 1, 2, …, 7
%V
ISO 8601 week as a decimal number
with Monday as the first day of the
week. Week 01 is the week
containing Jan 4
01, 02, …, 53
%:z
UTC offset in the form
±HH:MM[:SS[.ffffff]] (empty string if
the object is naive)
(empty), +00:00,
-04:00, +10:30,
+06:34:15,
Kode format Penjelasan Contoh
-03:07:12.345216
Catatan chapter 📑📑
â—‰ Source code praktik
github.com/novalagung/dasarpemrogramanpython-example/../datetime-
parsing-formatting
â—‰ Chapter relevan lainnya
• Date, Time, DateTime, Timezone
â—‰ TBA
• Locale
â—‰ Referensi
• https://docs.python.org/3/library/datetime.html
• https://dateutil.readthedocs.io/en/stable/parser.html
• https://stackoverflow.com/questions/3305413/how-to-preserve-timezone-
when-parsing-date-time-strings-with-strptime
• https://stackoverflow.com/questions/13182075/how-to-convert-a-timezone-
aware-string-to-datetime-in-python-without-dateutil
• https://stackoverflow.com/questions/1941927/convert-an-rfc-3339-time-to-
a-standard-python-timestamp
• https://realpython.com/python-datetime/
A.55. Python Delete
Object
Pada sekian chapter yang lalu kita telah belajar tentang object None, fungsinya
untuk menandai variabel agar bernilai kosong.
Kali ini yang kita pelajari yaitu keyword del untuk operasi delete object.
Hasil penggunaan keyword del benar-benar menghapus variabel beserta
isinya, jadi tidak hanya mengosongkan nilainya.
A.55.1. Keyword del
Penggunaan None sebagai nilai suatu variabel menjadikan variabel tersebut
tetap ada tapi nilainya berubah menjadi None . Jadi penggunaan None disini
berguna untuk mengosongkan variabel tanpa menghapus variabel itu sendiri.
Bagaimana jika kita ingin benar-benar menghapus suatu variabel? Caranya
memakai keyword del . Contoh penggunaannya bisa dilihat di bawah ini:
Operasi print pertama memunculkan nilai variabel name tanpa kendala.
Namun di statement print ke-2, variabel name tidak dikenal dan menghasilkan
error karena variabel tersebut telah dihapus memakai keyword del .
name = "Noval Agung"
print(name)
del name
print(name)
Jadi keyword del ini benar-benar menghapus variabel ya.
Tak hanya ke variabel saja, keyword ini bisa digunakan untuk menghapus
attribute, item list, class, fungsi, dan banyak lainnya!
â—‰ Delete list item
â—‰ Delete dictionary item
obj = ["Noval", "Malang", "Chad"]
print(obj)
# output ➜ ['Noval', 'Malang', 'Chad']
del obj[1]
print(obj)
# output ➜ ['Noval', 'Chad']
obj = {
"name": "Noval",
"city": "Malang",
"gender": "Chad"
}
print(obj)
# output ➜ {'name': 'Noval', 'city': 'Malang', 'gender': 'Chad'}
del obj["city"]
â—‰ Delete class/object property
Keyword del dalam penggunaannya terhadap property class/object membuat
property tersebut menjadi tidak ada.
Pada contoh berikut statement delete dibungkus block try untuk menangkap
error yang muncul karena mencoba mengakses property yang tidak terdaftar.
â—‰ Delete function
Tak hanya object, fungsi juga bisa dihapus.
class Person:
def __init__(self, name, city, gender):
self.name = name
self.city = city
self.gender = gender
p = Person("Noval", "Malang", "Chad")
print(p.name, p.city, p.gender)
# output ➜ Noval Malang Chad
try:
del p.city
print(p.name, p.city, p.gender)
# raise exception ⬇
except Exception as err:
print(err)
# output ➜ 'Person' object has no attribute 'city'
def say_hello():
print("hello world")
â—‰ Delete class
Catatan chapter 📑📑
â—‰ Source code praktik
github.com/novalagung/dasarpemrogramanpython-example/../del
â—‰ Chapter relevan lainnya
• None
class Person:
def __init__(self, name, city, gender):
self.name = name
self.city = city
self.gender = gender
p = Person("Noval", "Malang", "Chad")
print(p.name, p.city, p.gender)
# output ➜ Noval Malang Chad
try:
del Person
p = Person("Noval", "Malang", "Chad")
# raise exception ⬇
except Exception as err:
print(err)
# output ➜ name 'Person' is not defined
â—‰ Referensi
• https://docs.python.org/3/tutorial/datastructures.html#the-del-statement
• https://docs.python.org/3/reference/simple_stmts.html#del
A.56. Python Enumeration
Enumeration (Enum) yaitu nilai konstan, umumnya disiapkan untuk
merepresentasikan sekumpulan data konstan yang konteksnya masih sama.
Misalnya, warna yang isinya bisa merah, biru, kuning, atau warna lain.
Pembuatan enum di Python sangat mudah. Caranya dengan mendeklarasikan
class baru yang meng-inherit class enum.Enum , kemudian menuliskan
kumpulan data sebagai class property-nya.
A.56.1. Enum / Enumeration
Di bawah ini, disiapkan sebuah enum bernama City dengan isi ada 4 buah
pilihan kota.
Nilai property enum bisa diisi dengan data apapun. Pada contoh di atas, nilai
property enum City diisi dengan angka numerik.
Property enum bisa diakses dalam bentuk list dengan cukup
from enum import Enum
class City(Enum):
MALANG = 1
SURABAYA = 2
YOGYAKARTA = 3
JAKARTA = 4
print(list(City))
# output ➜ [<City.MALANG: 1>, <City.SURABAYA: 2>, <City.YOGYAKARTA: 3>,
<City.JAKARTA: 4>
membungkusnya memakai fungsi list() .
Selanjutnya, buat satu variabel, isi nilainya dengan salah satu property enum
(misalnya City.YOGYAKARTA ), kemudian print.
Nama enum property bisa diambil memakai property name sedangkan
value-nya diambil via property value .
A.56.2. Naming convention enum
Sesuai penjelasan di halaman dokumentasi Python, nama class enum
dianjurkan ditulis memakai CamelCase, sedangkan nama class property
dituliskan UPPERCASE.
A.56.3. Notasi penulisan pengaksesan
enum property
Dalam penggunaannya setidaknya ada 3 notasi pengaksesan enum property
yang bisa digunakan.
city1 = City.YOGYAKARTA
print(city1)
# output ➜ City.YOGYAKARTA
print(f"name {city1.name}")
# output ➜ name YOGYAKARTA
print(f"value {city1.value}")
# output ➜ value 3
• Cara pertama memakai notasi Enum.PROPERTY .
• Cara ke-2 memakai notasi pengaksesan dictionary dengan key berupa
string.
Metode ini cukup berguna pada case ketika key enum yang perlu diambil
yang sudah diketahui nilainya.
• Cara ke-3 memakai notasi pengaksesan Enum(value) .
city1 = City.YOGYAKARTA
print(city1)
# output ➜ City.YOGYAKARTA
print(f"name {city1.name}")
# output ➜ name YOGYAKARTA
print(f"value {city1.value}")
# output ➜ value 3
city2 = City["SURABAYA"]
print(city2)
# output ➜ City.SURABAYA
print(f"name {city2.name}")
# output ➜ name SURABAYA
print(f"value {city2.value}")
# output ➜ value 2
city3 = City(4)
print(city3)
# output ➜ City.JAKARTA
print(f"name {city3.name}")
# output ➜ name JAKARTA
print(f"value {city3.value}")
Metode ini pas digunakan ketika value enum sudah diketahui nilainya.
A.56.4. Nilai property enum
Property enum nilainya bisa berisi data numerik, string, atau tipe data lainnya.
Di atas telah dicontohkan enum City yang property-nya berisi data numerik.
Pada contoh ke-2 ini, enum Color property-nya berisi data string.
Selain memakai class enum.Enum saat deklarasi, bisa juga memakai
salah satu class turunan enum lainnya, diantaranya ada:
• Class enum.Enum ➡ property boleh berisi data bertipe apapun
• Class enum.StrEnum ➡ property hanya boleh berisi tipe data string
• Class enum.IntEnum ➡ property hanya boleh berisi tipe data integer
Cara penerapan variant enum yang telah disebut di atas yaitu masih sama.
Cukup ganti Enum dengan turunan class yang diinginkan, lalu sesuaikan tipe
from enum import Enum
class Color(Enum):
RED = "red"
BLUE = "blue"
print(list(Color))
# output ➜ [<Color.RED: 'red'>, <Color.BLUE: 'blue'>]
color1 = Color("red")
color2 = Color.RED
color3 = Color["BLUE"]
print(color1, color2, color3)
# output ➜ Color.RED Color.RED Color.BLUE
data nilai property di dalamnya.
â—‰ StrEnum
Misalnya, enum Color kita ubah dari memakai Enum ke StrEnum ,
maka kodenya seperti ini:
â—‰ IntEnum dan fungsi auto()
Untuk enum dengan property bertipe numerik, bisa memakai fungsi
auto() untuk generate nilai numerik unik secara otomatis. Contoh:
from enum import StrEnum
class Color(StrEnum):
RED = "red"
BLUE = "blue"
print(list(Color))
# output ➜ [<Color.RED: 'red'>, <Color.BLUE: 'blue'>]
color1 = Color("red")
color2 = Color.RED
color3 = Color["BLUE"]
print(color1, color2, color3)
# output ➜ Color.RED Color.RED Color.BLUE
from enum import IntEnum, auto
class Size(IntEnum):
S = auto()
M = auto()
L = auto()
XL = auto()
print(list(Size))
A.56.5. Pengecekan nilai enum
Operator identitas is dan operator perbandingan == dan != bisa
digunakan untuk pengecekan nilai enum.
A.56.6. Perulangan enum
Enum merupakan tipe yang bisa langsung digunakan pada perulangan. Contoh
penggunaannya:
from enum import Enum
class City(Enum):
MALANG = 1
SURABAYA = 2
YOGYAKARTA = 3
JAKARTA = 4
def say_anything(c):
if c is City.MALANG:
print("Oyi sam")
elif c == City.JAKARTA:
print("lo gue lo gue")
elif c == City.SURABAYA:
print("coeg")
elif c == City.YOGYAKARTA:
print("monggo")
city1 = City.YOGYAKARTA
say_anything(city1)
# output ➜ monggo
for c in City:
Catatan chapter 📑📑
â—‰ Source code praktik
github.com/novalagung/dasarpemrogramanpython-example/../enum
â—‰ Chapter relevan lainnya
• Konstanta
â—‰ TBA
• IntFlag and Flag https://docs.python.org/3/howto/enum.html#intflag
â—‰ Referensi
• https://docs.python.org/3/library/enum.html
• https://docs.python.org/3/howto/enum.html
A.57. Python Eval & Exec
Pada chapter ini kita akan mempelajari fungsi eval() untuk eksekusi
expression, fungsi exec() untuk eksekusi syntax Python, dan fungsi
compile() .
A.57.1. Fungsi eval()
String berisi ekspresi seperti PI * r * r bisa dieksekusi kemudian diambil
hasilnya memakai fungsi eval() . Cara penggunaannya sangat mudah,
tulis saja ekspresi sebagai argument pemanggilan fungsi. Misalnya:
Variabel a , b , dan c di ekspresi '(a + b) / 20 + (c * c)' nilainya terisi
oleh nilai variabel a , b , dan c yang sudah dideklarasikan sebelumnya.
Ekspresi string berisi apapun bisa digunakan pada fungsi eval() ini, asalkan
ekspresinya hanya 1 baris.
Jika ekspresi tidak valid, maka eksekusi fungsi eval() menghasilkan error,
dan ketika itu terjadi ada baiknya di-handle dengan baik. Contoh:
a = 10
b = 5
c = 8
area = eval('(a + b) / 20 + (c * c)')
print(area)
# output ➜ 64.75
try:
area = eval('(a + b asd / 20 + (c * c)')
By default, variabel dalam ekspresi terisi oleh nilai variabel yang sudah
dideklarasikan. Selain itu, nilai variabel juga bisa ditentukan secara eksplisit
via parameter ke-2 atau ke-3 fungsi eval() .
• Jika ekspresi berisi variabel yang kesemuanya ditentukan secara eksplisit,
bisa gunakan parameter ke-2.
• Jika eskresi berisi variabel yang hanya sebagaian saja yang nilainya
ditentukan secara eksplisit, maka gunakan globals() sebagai argument
parameter ke-2 dan tulis variabel pada parameter ke-3.
Pemanggilan eval('expr') tanpa parameter ke-2 dan ke-3 yaitu
ekuivalen dengan statement eval('expr', globals(), locals())
A.57.2. Fungsi exec()
Fungsi exec() berguna untuk eksekusi string berisi kode Python. Cara
penggunaannya mirip seperti eval() . Contoh:
• Eksekusi statement dengan operasi assignment
area = eval('PI * r * r', { "PI": 3.14, "r": 10 })
print(area)
# output ➜ 314.0
PI = 3.14
area = eval('PI * r * r', globals(), { "r": 10 })
print(area)
# output ➜ 314.0
Eksekusi (a + b) / 20 + (c * c) nilainya disimpan ke variabel res
yang efeknya mengubah nilai variabel res yang telah dideklarasikan.
• Eksekusi perulangan
• Eksekusi kode berisi statement import dan fungsi
a = 10
b = 5
c = 8
res = 0
exec('res = (a + b) / 20 + (c * c)')
print(res)
# output ➜ 64.75
r = 4
stmt = """
for x in range(r):
print(x)
"""
exec(stmt)
# output ↓
#
# 0
# 1
# 2
# 3
r = 10
res = 0
stmt = """
from typing import Final
PI: Final = 3.14
Selama string berisi kode Python dengan syntax valid, maka bisa dijalankan via
fungsi exec() ini.
A.57.3. Fungsi compile()
Fungsi compile() digunakan untuk kompilasi expression maupun kode
Python, untuk kemudian digunakan pada fungsi eval() , exec() , ataupun
untuk keperluan lainnya (seperti parse AST dan lainnya).
Fungsi ini memiliki 3 parameter yang harus diisi saat pemanggilan:
• Parameter ke-1 diisi dengan nilai string expression atau kode Python
• Parameter ke-2 diisi string '<string>'
• Parameter ke-3 diisi eval atau exec
Dengan mengkompilasi string terlebih dahulu, kita bisa mengantisipasi syntax
error ataupun expression error yang ada dalam string tanpa harus
mengeksekusinya terlebih dahulu.
Pengaplikasian fungsi compile() dalam penggunaannya dibedakan
berdasarkan isi string yang di-compile.
â—‰ Compile expression
Penggunaan fungsi compile() untuk expression, parameter ke-3 perlu diisi
nilai 'eval' .
Contoh:
compiled = compile('expr', '<string>', 'eval')
res = eval(compiled)
â—‰ Compile Python source code
Sedangkan untuk eksekusi kode Python, parameter ke-3 diisi nilai 'exec' .
Contoh:
a = 10
b = 5
c = 8
compiled = compile('(a + b) / 20 + (c * c)', '<string>', 'eval')
area = eval(compiled)
print(area)
# output ➜ 64.75
compiled = compile(stmt, '<string>', 'exec')
res = exec(compiled)
r = 10
res = 0
stmt = """
from typing import Final
PI: Final = 3.14
def calculate_area_of_circle():
print(f"calculating area of circle with r: {r}")
return PI * r * r
res = calculate_area_of_circle()
"""
compiled = compile(stmt, '<string>', 'exec')
area = exec(compiled)
print(res)
# output ↓
Catatan chapter 📑📑
â—‰ Source code praktik
github.com/novalagung/dasarpemrogramanpython-example/../eval-exec
â—‰ Referensi
• https://stackoverflow.com/questions/2220699/whats-the-difference-
between-eval-exec-and-compile
A.58. Python Iterable &
Iterator
Pada chapter ini kita akan belajar tentang konsep sekaligus penerapan iterable
dan iterator di Python.
A.58.1. Apa itu iterable?
Iteration atau iterasi yaitu proses pengaksesan item-item suatu data
kolektif sesuai urutannya satu-per-satu (memakai metode perulangan).
Penerapan keyword for in pada data string, list, atau data kolektif lainnya
yaitu contoh dari iterasi.
Di atas, variabel condition di-iterasi memakai keyword for in ,
variabel c disetiap perulangan terisi dengan huruf string satu-per-satu,
bergantian, mulai huruf pertama hingga terakhir.
Begitu juga dengan variabel numbers , nilai numerik dalam list di-iterasi
dengan setiap nilai ditampung variabel n untuk kemudian di-print.
Iterable yaitu object yang bisa di-iterasi, contohnya seperti tuple, list, string,
condition = "weteng luwe"
for c in condition:
print(c)
numbers = [10, 12, 32, 44]
for n in numbers:
print(n)
dan tipe data kolektif lainnya. Sederhananya, setiap object yang bisa
digunakan pada keyword for in yaitu pasti iterable.
A.58.2. Apa itu iterator?
Iterator berbeda dibanding iterable. Iterator yaitu object iterable yang bisa
mengingat state perulangannya. Jadi object tersebut tau informasi seperti
perulangan sedang berada di indeks ke berapa, elemen berikutnya apa, dan
info mengenai kapan perulangan berhenti.
Object iterable bisa dikonversi menjadi iterator, caranya dengan
membungkusnya memakai fungsi iter() . Contoh:
Ok, lalu apa benefitnya? apa bedanya dengan iterable biasa? Jika mengacu ke
contoh di atas, tidak akan terlihat perbedaannya dimana, karena object
iterable dan iterator keduanya pasti bisa digunakan pada perulangan
memakai keyword for in .
Agar lebih jelas, kita berkenalan dulu dengan fungsi baru bernama next() .
Fungsi ini berguna untuk mengembalikan data iterasi berikutnya. Contoh
penerapannya silakan lihat kode berikut ini:
condition = "weteng luwe"
for c in iter(condition):
print(c)
numbers = [10, 12, 32, 44]
for n in iter(numbers):
print(n)
numbers = [10, 12, 32, 44]
Data list numbers dikonversi ke bentuk iterator memakai fungsi iter() ,
kemudian digunakan sebagai argument pemanggilan fungsi next() 4 kali,
hasilnya:
• Pemanggilan ke-1 mengembalikan item index ke-1, yaitu angka 10
• Pemanggilan ke-2 mengembalikan item index ke-2, yaitu angka 12
• Pemanggilan ke-3 mengembalikan item index ke-3, yaitu angka 32
• Pemanggilan ke-4 mengembalikan item index ke-4, yaitu angka 44
Dari sini terlihat bahwa object iterator benar-benar mengingat informasi state-
nya. Setelah pemanggilan fungsi next() pertama, object numbers_iter tau
bahwa item indeks ke-1 sudah diakses, dan pengaksesan berikutnya yaitu
indeks ke-2, dan seterusnya.
Penggunaan fungsi next() terhadap object iterator yang sudah
terakses semua itemnya menghasilkan error. Manfaatkan keyword try
except jika diperlukan.
A.58.3. Custom iterator
Selain memakai fungsi iter() pembuatan iterator juga bisa dilakukan
via custom class. Caranya dengan mendesain custom class agar memiliki 2 hal
berikut:
1. Custom class harus inherit class Iterator milik module
collections.abc .
2. Di dalam class harus ada fungsi __next__(self) yang otomatis dipanggil
setiap kali object digunakan pada fungsi next() .
Pada contoh berikut, disiapkan class bernama LoopReverse dengan tugas
yaitu menghasilkan object iterator yang mengembalikan item data kolektif
berurutan dari belakang (terbalik).
Penjelasan:
• Sewaktu class dinisialisasi, instance attribute i disiapkan dengan nilai 0
dan attribute data berisi data yang disisipkan via argument (pada
konteks ini yang dimaksud yaitu data [23, 2, 1, 54] ).
• Di setiap perulangan, fungsi __next__(self) dipanggil, ketika nilai i
from collections.abc import Iterator
class LoopReverse(Iterator):
def __init__(self, data):
self.data = data
self.i = 0
def __next__(self):
if (self.i+1) > len(self.data):
raise StopIteration
else:
r = self.data[len(self.data)-self.i-1]
self.i = self.i + 1
return r
numbers = [23, 2, 1, 54]
for n in LoopReverse(numbers):
print(n)
# output ↓
#
# 54
# 1
# 2
# 23
masih di bawah jumlah item data , maka item nomor i dari belakang
dikembalikan. Selebihnya, exception StopIteration di-raise untuk
menandai bahwa iterasi sudah dihentikan.
Coba test juga pengaksesan item iterator via fungsi next() . Contoh:
Selain memakai class Iterator sebagai superclass, iterator custom
class juga bisa dibuat dengan cukup menambahkan fungsi __iter__(self)
yang mengembalikan data self tanpa perlu meng-inherit class Iterator .
Contoh:
numbers = [23, 2, 1, 54]
numbers_iter = LoopReverse(numbers)
n = next(numbers_iter)
print(n) # output ➜ 54
n = next(numbers_iter)
print(n) # output ➜ 1
n = next(numbers_iter)
print(n) # output ➜ 2
n = next(numbers_iter)
print(n) # output ➜ 23
class LoopReverse:
def __init__(self, data):
self.data = data
self.i = 0
def __iter__(self):
return self
Method __iter__(self) harus mengembalikan object iterator yang dimana
harus memiliki method __next__(self) . Di contoh di atas, method
__next__(self) kebetulan memang posisinya satu level dengan method
__iter__(self) , oleh karena itu object self dijadikan nilai balik.
Catatan chapter 📑📑
â—‰ Source code praktik
github.com/novalagung/dasarpemrogramanpython-example/../iterable-
iterator
â—‰ Chapter relevan lainnya
• Perulangan ➜ for & range
â—‰ Referensi
• https://docs.python.org/3/glossary.html#term-iterator
• https://docs.python.org/3/library/functions.html#iter
• https://docs.python.org/3/library/functions.html#next
A.59. Python Generator &
Yield
Pada chapter ini kita akan belajar tentang konsep generator serta
pengaplikasiannya memakai keyword yield dan generator expression.
A.59.1. Generator object
Generator object yaitu object iterator yang dibuat via fungsi generator
(memakai keyword yield ) atau via generator expression.
Mengenai apa itu iterator, pembahasannya ada di chapter sebelumnya,
yaitu Iterable & Iterator
A.59.2. Generator function
Generator function yaitu salah satu cara pembuatan generator object. Ciri
khasnya di dalam fungsi ada statement berisi keyword yield .
Mari praktekan. Di bawah ini, fungsi random_messages() didesain untuk
mengembalikan generator object.
def random_messages():
yield "hello python"
yield "how are you"
yield "nice to meet you"
Variabel messages menampung nilai balik pemanggilan fungsi
random_messages() (data generator object), ketika di-print nilainya yang
muncul yaitu generator object.
Selayaknya iterator, generator (yang juga merupakan iterator) pengaksesan
itemnya dilakukan via perulangan for in , atau memakai fungsi
next() .
Pada contoh berikutnya ini, generator random_messages() digunakan pada
perulangan. Hasilnya, di setiap iterasi for in , data yang dikembalikan via
keyword yield di-print.
Karena ada 3 statement yield disitu, maka generator ketika digunakan di
perulangan hasilnya iterasi sebanyak 3x.
• Iterasi ke-1, variabel message berisi statement yield ke-1, yaitu hello
python
• Iterasi ke-2, variabel message berisi statement yield ke-2, yaitu how are
you
• Iterasi ke-3, variabel message berisi statement yield ke-3, yaitu nice to
def random_messages():
yield "hello python"
yield "how are you"
yield "nice to meet you"
for message in random_messages():
print(message)
# output ↓
#
# hello python
# how are you
# nice to meet you
meet you
Contoh implementasi penerapan generator via fungsi next() :
Berikut yaitu 2 contoh tambahan penerapan fungsi generator dan keyword
yield .
â—‰ Infinite counter
Keyword yield bisa dikombinasikan dengan perulangan while untuk
membuat logic infinite counter.
gen = random_messages()
message = next(gen)
print(f"message 1: {message}")
# output ➜ message 1: hello python
message = next(gen)
print(f"message 2: {message}")
# output ➜ message 2: how are you
message = next(gen)
print(f"message 3: {message}")
# output ➜ message 3: nice to meet you
def infinite_counter():
i = 0
while True:
yield i
i = i + 1
c = infinite_counter()
print(next(c))
â—‰ Operasi baca file
Contoh operasi baca file yang setiap baris konten file dikembalikan sebagai
data iterasi via keyword yield .
A.59.3. Generator expression
Generator comprehension (atau yang umumnya dikenal sebagai generator
expression) yaitu ekspresi statement yang ditulis dalam format tertentu yang
otomatis terdeteksi sebagai generator object.
Penulisan ekspresi generator mirip seperti penulisan list comprehension,
perbedaannya ada pada karakter yang digunakan untuk membungkus
ekspresi. Pada list comprehension memakai tanda [ ] , pada generator
comprehension/expression memakai tanda ( ) .
Contoh penerapan:
def file_reader(file_name):
for row in open(file_name, "r"):
yield row
for row in open('content.txt'):
print(row.strip())
exp1 = [num**2 for num in range(5)]
print(exp1)
# output ➜ [0, 1, 4, 9, 16]
exp2 = (num**2 for num in range(5))
print(exp2)
Catatan chapter 📑📑
â—‰ Source code praktik
github.com/novalagung/dasarpemrogramanpython-example/../generator-
yield
â—‰ Chapter relevan lainnya
• List Comprehension
• Iterable & Iterator
â—‰ Referensi
• https://docs.python.org/3/reference/expressions.html#generator-
expressions
• https://docs.python.org/3/reference/expressions.html#yield-expressions