Kategori
Python

Pemecahan Masalah

Setelah sebelumnya kita telah mengeksplorasi berbagai bagian bahasa Python, sekarang kita coba untuk menggabungkan bagian-bagian tadi menjadi satu kesatuan, dengan mendesain dan membuat program yang benar-benar berguna. Idenya adalah belajar bagaimana Anda menulis skrip Python sendiri.

Permasalahan

Permasalahan yang ingin dipecahkan adalah “Saya ingin membuat sebuah program yang membackup semua berkas-berkas saya yang penting.”.

Meskipun ini masalah sederhana, namun tidak ada informasi yang cukup bagi kita untuk mulai dengan pemecahannya. Hal ini membutuhkan sedikit analisis lanjutan. Sebagai contoh, bagaimana kita menentukan berkas mana yang penting sehingga perlu dibackup? Bagaimana berkas-berkas tersebut disimpan? Di mana tempat penyimpanannya?

Setelah menganalisis masalah tersebut secara lebih mendalam, kita mulai mendesain program kita. Kita bisa mulai dengan membuat daftar bagaimana program kita akan berjalan nantinya. Dalam kasus ini, Saya telah membuat daftar berikut tentang bagaimana Saya ingin program tersebut bekerja. Jika Anda melakukan sendiri desainnya, mungkin Anda akan membuat analisis berbeda mengingat setiap orang punya pendekatan berbeda tentang bagaimana cara mereka melakukan pekerjaannya. Dan ini sama sekali bukan masalah. Tidak apa-apa.

  • Berkas dan direktori akan disimpan dalam berkas pendukung (backup) secara khusus dalam list.
  • Berkas pendukung harus disimpan dalam direktori pendukung utama.
  • Semua berkas disimpan dalam berkas pendukung dengan format zip.
  • Penamaan dalam berkas arsip berformat zip dibuat dalam tanggal dan waktu sekarang.
  • Kita menggunakan perintah baku zip yang sudah tersedia dalam setiap distribusi Linux/Unix. Pengguna Windows dapat memasang dari Halaman Proyek GnuWin32 and add C:\Program Files\GnuWin32\bin ke dalam variabel lingkungan yang dikenal oleh PATH sistem, sama seperti cara kita mengenal perintah python sendiri. Perhatikan bahwa perintah untuk mengarsipkan berkas dapat Anda gunakan selama aplikasi tersebut tersedia dan bisa diakses melalui baris perintah.

Solusi

Mengingat desain program kita relatif sudah komplet dan stabil, sekarang kita dapat menuliskan kode sebagai implementasi dari solusi kita.

Simpan sebagai backup_ver1.py:

import os
import time

# 1. Berkas dan direktori akan disimpan dalam berkas pendukung (_back up_) secara khusus dalam list.
source = ['"C:\\My Documents"', 'C:\\Code']
# Perhatikan bahwa kita harus menggunakan petik dua di dalam string yang memiliki spasi di dalamnya.

# 2. Berkas pendukung harus disimpan dalam direktori pendukung utama.
target_dir = 'E:\\Backup' # Ingat bahwa ini harus diganti dengan direktori yang benar-benar Anda gunakan

# 3. Semua berkas disimpan dalam berkas pendukung dengan format zip.
# 4. Penamaan dalam berkas arsip berformat zip  dibuat dalam tanggal dan waktu sekarang.
target = target_dir + os.sep + time.strftime('%Y%m%d%H%M%S') + '.zip'

# 5. Kita gunakan perintah zip untuk memasukkan berkas ke dalam arsip zip
zip_command = "zip -qr {0} {1}".format(target, ' '.join(source))

# Jalankan backup
if os.system(zip_command) == 0:
    print('Backup berhasil dilakukan ke', target)
else:
    print('Backup GAGAL')

Keluaran:

$ python backup_ver1.py
Backup berhasil dilakukan ke E:\Backup\20080702185040.zip

Sekarang, kita dalam fase testing untuk menguji apakah program yang kita buat dapat berjalan dengan baik. Jika tidak berjalan sesuai harapan, kita harus melakukan debug terhadap program kita, yakni dengan memperbaiki bus (kesalahan) dari program.

Jika kode program di atas tidak berjalan, buat satu baris perintah print(zip_command) di atas baris `os.system’, dan jalankan program kembali. Kemudian, salin/tempel hasil keluaran print zip_command yang ada di layar, dan lihat apakah tulisan yang tampil sudah menunjukkan bahwa program sudah berjalan dengan benar. Jika perintah tersebut gagal, cek kembali petunjuk perintah zip dan cari kemungkinan-kemungkinan kekeliruan. Jika perintah ini berhasil dijalankan, lihat kembali program Python Anda apakah keluarannya sesuai dengan apa yang tertulis di atas.

Bagaimana Cara Kerjanya

Anda akan memahami bahwa kita telah mengonversi desain menjadi kode program langkah demi langkah.

Kita menggunakan modul os dan time dengan cara mengimpornya terlebih dahulu. Kemudian, kita tentukan berkas dan direktori yang akan dibackup ke dalam direktori yang kita namakan lewat variabel target_dir. Nama file arsip zip yang akan kita buat, terdiri dari tanggal dan waktu saat perintah tersebut dijalankan dengan menggunakan fungsi time.strftime(). Pembuatan berkas tersebut juga akan menambahkan ekstensi .zip dan akan disimpan pada direktori target_dir.

Perhatikan bahwa variabel os.sep – yang akan memberikan pemisah antar direktori yang sesuai dengan sistem operasi Anda, yakni '/' jika berada dalam lingkungan Linux dan Unix, atau '\\' di Windows dan ':' di Mac OS. Penggunaan fungsi os.sep daripada menuliskan langsung karakter pemisahnya akan membuat program kita portabel dan berjalan di sistem yang heterogen.

Fungsi time.strftime() akan mengambil karakter tertentu yang sudah ditentukan untuk kita gunakan di program di atas. Karakter spesifik %Y akan diganti dengan tahun. Sedangkan %m akan diganti nama bulan dengan format desimal antara 01 hingga 12 dan seterusnya. Spesifikasi lengkap terhadap hal ini bisa dilihat di Manual Referensi Python.

Kita membuat nama dari file arsip yang dituju dengan tambahan operator yang menggabungkan/concatenates string, yakni dengan menggabungkan dua string untuk menjadi satu string gabungan. Kemudian kita juga membuat string zip_command yang berisi seluruh perintah yang akan kita eksekusi. Anda dapat mengecek apakah perintah ini berjalan atau tidak dengan menjalankannya di shell (baik di terminal Linux atau prompt DOS).

Perintah zip yang kita gunakan memiliki opsi dan parameter yang bisa dimasukkan. Opsi -q digunakan sebagai indikasi bahwa perintah zip haraus berjalan secara diam-diam (quietly). Opsi -r menunjukkan bahwa perintah zip harus dijalankan secara rekursif di dalam direktori, yakni dengan memasukkan seluruh sub direktori dan berkas di bawahnya. Kedua parameter tersebut dapat digabung menjadi satu parameter -qr. Opsi tersebut diikuti nama berkas arsip zip yang didalamnya akan diisi arsip seluruh berkas dan direktori yang akan dibackup. Kita mengonversi list source menjadi string lewat metode yang sudah pernah kita lihat penggunaannya sebelumnya, yakni join string.

Lalu kita benar-benar menjalankan perintah tersebut lewat fungsi os.system di mana fungsi tersebut akan menjalankan perintah seolah-olah dijalankan oleh sistem, yakni akan memberikan kembalian 0 jika berhasil, dan jika gagal akan memberikan nomor pesan kesalahan yang sesuai dengan sistem operasinya.

Tergantung dari keluaran perintah di atas, kita akan mencetak pesan pelaksanaan backup tersebut apakah gagal atau berhasil.

Itu saja, kita telah membuat skrip untuk membackup seluruh berkas-berkas penting kita!Catatan untuk pengguna Windows

Selain menggunakan backslash (garis miring kiri) untuk lepas dari urutan (sequences), Anda bisa menggunakan string dasar. Sebagai contoh 'C:\\Documents' atau r'C:\Documents'. Meskipun demikian jangan menggunakan 'C:\Documents' karena nantinya akan dianggap sebagai string urutan lepas (escape sequence\D.

Sekarang kita sudah memiliki skrip backup yang berjalan dengan baik, dan kita bisa menggunakannya setiap saat kita butuhkan untuk membuat backup berkas. Pengguna Linux/Unix sangat disarankan untuk menggunakan metode yang bisa dieksekusi sebagaimana yang telah kita diskusikan sebelumnya, sehingga kita dapat menjalankan skrip backup kapan saja dan di mana saja. Hal ini sering disebut fase operasi atau fase deployment dari sebuah perangkat lunak.

Meskipun program di atas dapat berjalan sebagaimana mestinya, tapi (biasanya) program pertama kali dijalankan tidak sesuai dengan yang diinginkan. Sebagai conth, mungkin akan ada masalah jika Anda tidak mendesain program dengan layak, atau Anda melakukan kesalahan saat mengetikkan kode sintaks, dan sebagainya. Selayaknya, kita harus kembali ke fase desain atau nanti Anda harus debug program yang Anda buat.

Versi Kedua

Versi pertama dari program yang kita buat telah berjalan sebagaimana mestinya. Meskipun demikian, kita bisa saja membuat beberapa perbaikan sehingga dapat berjalan lebih baik setiap harinya. Ini disebut sebagai fase pemeliharaan dari pengembangan perangkat lunak.

Salah satu perbaikan yang saya pikir akan berguna lebih baik adalah mekanisme penamaan berkas – dengan menggunakan waktu sebagai bagian dari nama berkas di dalam direktori backup utama. Keuntungan pertama adalah, backup Anda akan disimpan dalam format yang hierarkis sehingga lebih mudah untuk diatur. Keuntungan kedua, nama berkas jauh lebh pendek. Keuntungan ketiga, direktori yang terpisah akan membantu Anda jika Anda mambuat backup tiap hari, dan direktori yang terbuat adalah direktori yang memang benar-benar dibuat di hari itu.

Simpan sebagai backup_ver2.py:

import os
import time

# 1. Berkas dan direktori yang dibackup disebut secara khusus dalam daftar(_list_).
sumber = ['"C:\\My Documents"', 'C:\\Code']
# Perhatikan bahwa kita menggunakan tanda petik dua di dalam string untuk nama yang memiliki spasi.

# 2. Backup harus disimpan di dalam direktori backup utama
target_dir = 'E:\\Backup' # Mohon diingat untuk ganti ini dengan folder yang akan Anda gunakan

# 3. Berkas akan dibackup ke dalam berkas zip.
# 4. Nama sub direktori dengan nama hari ini di dalam direktori utama 
today = target_dir + os.sep + time.strftime('%Y%m%d')
# Waktu hari ini adalah nama dari arsip zip 
now = time.strftime('%H%M%S')

# Buat sub direktori jika belum ada di sana 
if not os.path.exists(today):
    os.mkdir(today) # make directory
    print('Berhasil membuat direktori', today)

# Nama berkas zip 
target = today + os.sep + now + '.zip'

# 5. Sekarang kita gunakan perintah zip untuk memasukkan berkas ke dalam arsip zip
zip_command = "zip -qr {0} {1}".format(target, ' '.join(source))

# Jalankan backup 
if os.system(zip_command) == 0:
    print('Berhasil backup ke dalam ', target)
else:
    print('Backup GAGAL')

Keluaran:

$ python3 backup_ver2.py
Berhasil membuat direktori E:\Backup\20080702
Berhasil backup ke dalam E:\Backup\20080702\202311.zip

$ python3 backup_ver2.py
Berhasil backup ke dalam E:\Backup\20080702\202325.zip

Bagaimana Cara Kerjanya

Hampir sebagian besar program sama dengan yang sebelumnya. Perbedaannya hanya ketika saat kita mengecek apakah sudah ada direktori yang namanya sama dengan nama hari ini di dalam direkotri backup utama dengan fungsi os.path.exists. Jika tidak ada, kita akan buat direktori dengan fungsi os.mkdir

Versi Ketiga

Versi kedua berjalan baik saat saya melakukan backup, tapi saat ada banyak berkas yang perlu dibackup, saya kesulitan untuk membedakan berkas-berkas yang saya backup! Misalnya saya membuat perubahan besar dalam program atau presentasi, lalu saya ingin mengasosiasikan perubahan tersebut dalam nama berkas atau nama arsip zip. Ini dapat diperoleh dengan mudah dengan memberikan komentar ddi dalam nama berkas arsip zip-nya.Catatan

Program berikut ini tidak akan jalan, jadi tidak perlu khawatir. Mohon ikuti karena ada pelajaran di sini.

Simpan sebagai backup_ver3.py:

import os
import time

# 1. Berkas-berkas dan direktori akan dibackup dalam list 
sumber = ['"C:\\My Documents"', 'C:\\Code']
# Perhatikan bahwa kita menggunakan petik dua di dalam string untuk nama yang memiliki spasi.

# 2. Backup harus disimpan dalam direktori backup utama 
target_dir = 'E:\\Backup' # Ingat untuk mengganti ini dengan direktori yang akan Anda gunakan

# 3. Berkas akan dibackup dalam format zip
# 4. Hari ini adalah nama sub direktori di bawah direktori utama

hari_ini = target_dir + os.sep + time.strftime('%Y%m%d')
# Waktu sekarang digunakan sebagai nama dalam arsip zip
sekarang = time.strftime('%H%M%S')

# Simpan komentar dari pengguna untuk membuat nama yang digunakan dalam berkas zip
komentar = input('Masukkan komentar --> ')
if len(komentar) == 0: # cek apakah komentar sudah diisikan
    target = hari_ini + os.sep + sekarang + '.zip'
else:
    target = hari_ini + os.sep + sekarang + '_' +
        komentar.replace(' ', '_') + '.zip'

# Buat sub direktori dulu jika belum ada
if not os.path.exists(hari_ini):
    os.mkdir(hari_ini) # membuat direktori 
    print('Berhasil membuat direktori ', hari_ini)

# 5. Selanjutnya kita gunakan perintah zip untuk memasukkan berkas ke dalam arsip zip
zip_command = "zip -qr {0} {1}".format(target, ' '.join(sumber))

# Jalankan backup 
if os.system(zip_command) == 0:
    print('Berhasil membuat backup di ', target)
else:
    print('Backup GAGAL')

Keluaran:

$ python3 backup_ver3.py
  File "backup_ver3.py", line 25
    target = hari_ini + os.sep + sekarang + '_' +
                                        ^
SyntaxError: invalid syntax

Kenapa ini (tidak) Berjalan:

Program ini tidak berjalan! Python mengatakan ada kesalahan sintaks, yang berarti bahwa skirp tidak sesuai dengan struktur yang diharapkan oleh Python. Ketika kita melihat pesan kesalahan yang diberikan oleh Python, pesan tersebut juga mengatakan di mana sebetulnya letak kesalahannya. Jadi kita memulai proses debugging untuk pemecahan masalah dari program kita di baris tersebut.

Saat melihat lebih dalam, kita lihat ada satu baris yang secara fisik satu, namun dipisah menjadi dua baris, namun kita tidak menetukan bahwa dua baris yang berbeda ini merupakan satu kesatuan. Pada dasarnya, Python telah menemukan bahwa operator tambahan (+) tanpa operand dalam baris tersebut, sehingga tidak tahu bagaimana harus melanjutkan. Ingat bahwa kita bisa menentukan satu bagis logis di dalam dua baris fisik namun tetap menjadi satu kesatuan. Jadi kita akan perbaiki program kita. Perbaikan program saat kita menemukan pesan kesalahan semacam ini dinamakan bug fixing.

Versi ke Empat

Simpan sebagai backup_ver4.py:

import os
import time

# 1. Berkas-berkas dan direktori akan dibackup dalam list 
sumber = ['"C:\\My Documents"', 'C:\\Code']
# Perhatikan bahwa kita menggunakan petik dua di dalam string untuk nama yang memiliki spasi.

# 2. Backup harus disimpan dalam direktori backup utama 
target_dir = 'E:\\Backup' # Ingat untuk mengganti ini dengan direktori yang akan Anda gunakan

# 3. Berkas akan dibackup dalam format zip
# 4. Hari ini adalah nama sub direktori di bawah direktori utama

hari_ini = target_dir + os.sep + time.strftime('%Y%m%d')
# Waktu sekarang digunakan sebagai nama dalam arsip zip
sekarang = time.strftime('%H%M%S')

# Simpan komentar dari pengguna untuk membuat nama yang digunakan dalam berkas zip
komentar = input('Masukkan komentar --> ')
if len(komentar) == 0: # cek apakah komentar sudah diisikan
    target = hari_ini + os.sep + sekarang + '.zip'
else:
    target = hari_ini + os.sep + sekarang + '_' + \
        komentar.replace(' ', '_') + '.zip'

# Buat sub direktori dulu jika belum ada
if not os.path.exists(hari_ini):
    os.mkdir(hari_ini) # membuat direktori 
    print('Berhasil membuat direktori ', hari_ini)

# 5. Selanjutnya kita gunakan perintah zip untuk memasukkan berkas ke dalam arsip zip
zip_command = "zip -qr {0} {1}".format(target, ' '.join(sumber))

# Jalankan backup 
if os.system(zip_command) == 0:
    print('Berhasil membuat backup di ', target)
else:
    print('Backup GAGAL')

Keluaran:

$ python3 backup_ver4.py
Masukkan komentar --> tambah contoh baru 
Berhasil membuat backup di E:\Backup\20080702\202836_tambah_contoh_baru.zip

$ python3 backup_ver4.py
Masukkan komentar -->
Berhasil membuat backup di E:\Backup\20080702\202839.zip

Bagaimana Cara Kerjanya

Sekarang program ini berjalan sesuai dengan yang kita harapkan! Mari kita lihat bersama, di sebelah mana yang kita perbaiki dari versi 3. Kita meminta komentar/masukan dengan menggunakan fungsi input, kemudian kita cek kembali apakah pengguna memasukkan komentar sesuai dengan panjang yang kita tentukan lewat fungsi len. Jika pengguna menekan tombol enter tanpa memasukkan apapun (mungkin hanya backup rutin atau tidak ada perubahan berkasnya), kita langsung memproses sesuai langkah yang telah kita lakukan sebelumnya.

Meskipun demikian, jika ada komentar yang dituliskan, komentar ini akan dimasukkan ke dalam nama berkas, sebelum ekstensi .zip. Perhatikan bahwa kita mengganti spasi yang ada dalam komentar dengan garis bawah _. Alasannya adalah karena lebih mudah mengatur berkas-berkas dengan nama tanpa spasi.

Perbaikan Lebih Lanjut

Versi ke empat merupakan skrip yang berjalan secara memuaskan bagi banyak pengguna, namun selalu ada ruang untuk perbaikan. Sebagai contoh, Anda dapat menambahkan level verbosity (lebih banyak kata/informasi yang ditampilkan oleh skrip) dengan menambahkan opsi -v agar program Anda lebih berbicara.

Kemungkinan perbaikan lainnya misalkan dengan memperbolehkan berkas-berkas tambahan dan direktori untuk diumpankan pada baris perintah. Kita dapat memperoleh informasi pilihan kata yang diumpankan ini lewat fungsi sys.argv yang berupa list, sehingga kita dapat menambahkan metode extend yang telah diberikan oleh class list.

Perbaikan terbaik yang bisa Anda lakukan adalah dengan tidak menggunakan cara os.system untuk membuat berkas arsip, namun menggunakan modul yang secara baku sudah ada, yakni zipfile atau tarfile. Keduanya merupakan bagian dari pustaka standar dan langsung tersedia tanpa memerlukan dependensi program zip eksternal yang mengharuskan program zip tersedia terlebih dahulu di komputer Anda.

Namun, saya menggunakan cara os.system dalam membuat backup di program di atas untuk kepentingan pembelajaran, sehingga contoh yang diberikan cukup sederhana untuk dipahami oleh setiap orang, namun juga nyata karena dapat dijalankan untuk diambil manfaatnya.

Dapatkah Anda coba membuat versi ke lima yang menggunakan modul zipfile daripada fungsi sistem os.system?

Proses Pengembangan Perangkat Lunak

Kita telah melakukan beberapa fase dalam proses pengembangan perangkat lunak. Fase ini dapat diringkas sebagai berikut:

  1. Apa (Analisis)
  2. Bagaimana (Desain)
  3. Mengerjakan (Implementasi)
  4. Uji coba (Uji coba dan debugging)
  5. Menggunakan (Operasi atau Pemasangan)
  6. Perawatan (Perbaikan terus menerus)

Salah satu prosedur menulis perangkat lunak yang direkomendasikan sudah kita ikuti satu demi satu dalam membuat skrip backup sebelumnya: Dimulai dengan analisis dan desain. Lalu Mulai dengan implementasi untuk program yang sederhana. Kemudian kita lakukan ujicoba dan debug. Kita gunakan programnya agar berjalan sesuai dengan yang diharapkan. Sekarang, kita menambahkan fitur-fitur yang diinginkan, kemudian melakukan kembali proses dari siklus Kerjakan-Ujicoba-Gunakan sebanyak yang dibutuhkan. Ingat bahwa Perangkat lunak tidak tumbuh, namun dibangun.

Ringkasan

Kita telah melihat bagaimana membuat program/skrip Python kita sendiri, dan berbagai tahapan yang dibutuhkan dalam menulis sebuah perangkat lunak. Anda mungkin dapat memanfaatkannya untuk menulis program Anda sendiri sebagaimana yang sudah Anda kerjakan di bab ini hingga Anda nyaman dengan Python sebagaimana Anda nyaman dengan pemecahan-masalah.

Selanjutnya, kita akan diskusikan pemrograman berbasis-objek.

Tinggalkan Balasan

Alamat email Anda tidak akan dipublikasikan. Ruas yang wajib ditandai *