Kursus Pengembangan Python Lanjutan
Bab
>
Tingkat

Modul Serialisasi
Modul Struct

Tujuan

Siapkan pemecahan data akhir untuk lahan pertanian baru menggunakan modul struct.

Di ujung jalan terdapat stasiun layanan yang mengelola lahan pertanian baru yang telah dibangun dan tanaman yang telah ditanam. Di sini kita akan memeriksa dan memproses data tanaman yang telah ditanam dan perkiraan hasil dari lahan pertanian tersebut. Seperti level lain dalam bab ini, kita akan bekerja dengan serialisasi dan deserialisasi data, memperkenalkan satu modul terakhir bernama modul struct.

Modul struct memperkenalkan serangkaian fungsi serialisasi yang mengemas data dalam format biner. Tidak seperti modul lain yang telah kita gunakan, modul ini memberikan kontrol lebih besar atas cara kita menyusun data saat diserialisasi dan saat nantinya dideserialisasi, menjadikannya lebih serbaguna dibanding modul lain. Gunakan import struct untuk mengakses fungsi-fungsi berikut yang akan kita gunakan untuk memproses data:

  • struct.calcsize(): Menentukan berapa banyak byte yang dibutuhkan oleh string format tertentu. Fungsi ini memerlukan satu (1) argumen, yaitu format yang ingin Anda periksa ukuran bytE-nya. Format yang akan kita gunakan adalah:
    • integer: direpresentasikan sebagai 'i', format untuk data berupa bilangan bulat.
    • float: direpresentasikan sebagai 'f', format untuk data berupa bilangan desimal.
    • double: direpresentasikan sebagai 'd', format untuk data berupa bilangan desimal lebih kompleks ketika format float tidak mencukupi.
  • struct.pack(): Men serialisasi data ke dalam biner, dikemas dalam format pilihan Anda. Fungsi ini mengambil dua (2) atau lebih argumen, yaitu format yang ingin Anda gunakan dan nilai-nilai yang ingin Anda serialisasi. Format yang digunakan adalah yang telah dijelaskan sebelumnya dan Anda harus menambahkannya sesuai jumlah argumen nilai.
  • struct.unpack(): Mendesserialisasi data biner yang telah dikemas, mengambil dua (2) argumen, yaitu format yang harus sesuai dengan format saat data diserialisasi, dan data yang telah diserialisasi.
  • struct.iter_unpack(): Mendesserialisasi data biner yang telah dikemas, bekerja sama seperti struct.unpack() tetapi mengiterasi setiap blok data secara individual menggunakan loop.
  • struct.pack_into(): Versi lanjutan dari struct.pack(), mengambil empat (4) argumen: format yang ingin digunakan, buffer data tempat Anda akan memasukkan data, posisi dalam buffer tempat data akan ditempatkan, dan data yang akan Anda kemas.
  • struct.unpack_from(): Versi lanjutan dari struct.unpack(), mengambil tiga (3) argumen: format yang ingin digunakan, buffer data tempat Anda akan mendesserialisasi, dan lokasi dalam buffer yang ingin Anda deserialisasi. Ini memungkinkan Anda untuk mendesserialisasi bagian tertentu dari data.

Jalanlah ke tanda X bercahaya di stasiun layanan dan hadap meja, buat tiga (3) variabel bernama: integer, float, dan double. Kita akan menggunakan variabel ini untuk memverifikasi ukuran dalam byte setiap format dengan menggunakan fungsi struct.calcsize(). Untuk variabel integer gunakan fungsi dengan 'i' sebagai argumen, untuk variabel float gunakan fungsi dengan 'f' sebagai argumen, dan terakhir untuk variabel double gunakan fungsi dengan 'd' sebagai argumen. Contohnya: integer = struct.calcsize('i'). Tambahkan ketiga (3) variabel tersebut ke fungsi write() yang telah disediakan.

Berjalanlah ke tanda X emas dan gunakan fungsi read() untuk mengumpulkan data tentang lahan pertanian baru, catat titik data dan formatnya untuk penggunaan selanjutnya, yaitu: Resources, Size, dan Estimate. Setelah mencatatnya, berjalanlah ke tanda X bercahaya di atas karpet biru dan buat variabel bernama blue_data.

Pada variabel blue_data, simpan nilai dari fungsi struct.pack(), menetapkan argumennya sesuai format dan nilai yang telah Anda catat sebelumnya. Saat menulis format, Anda harus “mengemas” jenis format menjadi satu kesatuan. Sebagai contoh, format integer dilabeli 'i' seperti dijelaskan sebelumnya; jika Anda menambahkan tiga tipe data integer, formatnya menjadi 'iii'. Demikian pula, jika Anda menambahkan integer, float, dan double, formatnya menjadi 'ifd'. Saat menambahkan datanya, tempatkan masing-masing secara terpisah sebagai argumen. Berikut contoh keseluruhan:

data_1 = 8 # adalah integer data_2 = 2.25 # adalah float data_3 = 900.702938103 # adalah double blue_data = struct.pack('ifd', data_1, data_2, data_3)

Fungsi struct.pack() sangat fleksibel, memungkinkan Anda menentukan format data dan menyerialisasi beberapa titik data sekaligus sesuai keinginan Anda. Tambahkan data yang telah dibaca sebelumnya menggunakan contoh di atas sebagai dasar. Gunakan fungsi display() dengan blue_data sebagai argumen untuk melihat data yang telah dikemas.

Berjalanlah ke tanda X gelap di atas karpet biru dan hadap terminal, buat variabel bernama blue_unpack dan simpan nilai dari fungsi struct.unpack(), dengan menambahkan format yang sama digunakan saat mengemas data dan variabel blue_data sebagai argumen. Format ditulis sama seperti pada struct.pack(), sehingga Anda dapat mendesserialisasi data sama seperti saat pertama kali menyerialisasinya. Gunakan fungsi write() dengan blue_unpack sebagai argumen untuk memverifikasi data yang telah Anda kemas sebelumnya.

Di lokasi yang sama, kita juga akan menggunakan fungsi struct.iter_unpack(). Fungsi ini mengambil argumen yang sama persis dengan struct.unpack(), tetapi diformat dalam bentuk loop for, sehingga memungkinkan kita mengiterasi data alih-alih menulisnya sekaligus. Fungsi ini dikodekan sebagai berikut:

for values in struct.iter_unpack(-insert value-, -insert value-): player.speak(values)

Kita akan menggunakan fungsi speak() untuk menampilkan nilai. Untuk argumen yang hilang pada fungsi struct.iter_unpack(), tambahkan argumen yang sama seperti yang digunakan sebelumnya pada struct.unpack(), karena ini adalah variasi dari fungsi yang sama dari segi penggunaan.

Berjalanlah ke tanda X emas di atas karpet merah dan hadap meja, gunakan fungsi read() untuk meninjau jumlah hasil panen. Catat semua kuantitas dan format untuk setiap jenis tanaman. Berjalanlah ke tanda X bercahaya di atas karpet merah dan buat objek bernama buffer, serta beri nilai bytearray(16). Ini adalah kumpulan byte yang dapat kita akses sebelum mengisinya; untuk tujuan kita, ini berfungsi seperti bank data di mana Anda dapat menyimpan data secara manual. Angka 16 sebagai argumen menunjukkan panjang byte yang dapat Anda simpan di objek buffer.

Gunakan fungsi struct.pack_into() untuk mengisi objek buffer yang telah Anda buat. Tidak perlu membuat variabel untuk menyimpan nilai fungsi ini karena fungsi itu sendiri akan memasukkan nilai langsung ke objek buffer. Kita akan menggunakan fungsi ini untuk setiap nilai yang telah Anda catat sebelumnya dan mengisi argumennya sesuai.

Sebagai contoh, untuk nilai tanaman pertama yang diberikan, Anda akan diberikan formatnya, posisi byte-nya, dan kuantitasnya. Tambahkan format sebagai argumen pertama, lokasi tempat Anda ingin menyerialisasi byte, dalam hal ini adalah buffer. Untuk argumen ketiga, tetapkan posisi di dalam buffer tempat Anda ingin menambahkan nilai; format menentukan byte yang terpakai, jadi pastikan untuk mengemas data ke area yang belum terisi. Terakhir, tambahkan nilai yang ingin Anda serialisasi dan kemas ke dalam objek buffer.

struct.pack_into('i', buffer, 0, 82)

Objek buffer memiliki 16 byte seperti disebutkan sebelumnya; dalam kode di atas, format integer menggunakan 4 byte dan disisipkan di posisi 0. Ini berarti setelah data dimasukkan ke dalam buffer, hanya tersisa 12 byte di dalam buffer yang belum terisi, dengan posisi 0-3 telah diisi oleh nilai yang diberikan, dalam hal ini 82. Lakukan hal ini untuk semua titik data tanaman yang telah dibaca dan dicatat sebelumnya, ada tiga (3) total. Gunakan fungsi display() dan tambahkan buffer untuk menampilkan data yang telah diserialisasi.

Berjalanlah ke tanda X gelap di atas karpet merah dan hadap terminal; di sini kita akan mendesserialisasi data untuk memverifikasi isinya agar memastikan penyimpanan yang benar. Buat tiga variabel bernama: lettuce, carrots, dan melons; kita akan mendesserialisasi data dari setiap titik data secara individual. Untuk setiap variabel, simpan nilai dari struct.unpack_from() dan tetapkan argumen sesuai data yang Anda catat saat mengemas data. Untuk argumen pertama, tetapkan format; untuk argumen kedua, tambahkan objek buffer yang menjadi lokasi untuk mendesserialisasi; dan terakhir tambahkan posisi dalam buffer tempat Anda ingin mendesserialisasi. Misalnya:

lettuce = struct.unpack_from('i', buffer, 0)

Data ini sesuai dengan contoh pengemasan sebelumnya yang sedang dikerjakan; lakukan hal yang sama untuk dua variabel lainnya dan masukkan lettuce, carrots, dan melons ke dalam fungsi write() yang telah disediakan untuk menyelesaikan level.

Buku Kode