BAB 9: Catatan dan Laporan: Berkas dan Merakit Teks
Studi kasus: "Kirim ringkasannya dalam bentuk tabel" #
Kepala Seksi meminta daftar petak jati berumur tua dalam berkas yang bisa dibuka di Excel. Hasil skrip Anda sejauh ini hanya tampil di layar, dan hilang saat jendela ditutup. Anda perlu dua kemampuan: menulis ke berkas, dan merakit teks dengan rapi supaya laporannya enak dibaca.
Konsep: berkas dan teks dalam tiga kalimat #
Berkas adalah buku catatan di disk: skrip Anda bisa menulisnya, menutupnya, lalu membacanya lagi besok. with open(...) adalah cara aman membuka buku itu, karena Python menutupnya sendiri setelah selesai. Merakit teks adalah menempelkan nilai ke dalam kalimat, seperti mengisi titik-titik pada surat.

Istilah baru di bagian ini:
open: perintah membuka berkas. Mode"w"untuk menulis,"r"untuk membaca.with: bungkus yang menutup berkas otomatis.- CSV: berkas teks berisi tabel, kolom dipisah koma. Bisa dibuka di Excel.
- JSON: berkas teks berisi data bersusun, mirip kamus.
- f-string: teks bertanda
fdi depan, yang boleh memuat{nilai}di dalamnya.
Merakit teks: tiga cara #
nama = "KPH Gamma"
luas = 8.0
print("%s luasnya %.2f ha" % (nama, luas))
print(f"{nama} luasnya {luas:.2f} ha")
print("{} luasnya {:.2f} ha".format(nama, luas))Tiga baris itu menghasilkan teks yang sama.
- Cara
%:%smenandai tempat teks,%.2fmenandai angka dengan dua desimal. Nilainya menyusul setelah tanda%dalam kurung. Cara ini dipakai di Buku I4 dan skrip ArcMap. - Cara f-string: awali dengan huruf
f, lalu tulis nama kotak di dalam{ }. Bagian:.2fmengatur dua desimal. Paling mudah dibaca, tetapi hanya ada di Python 3.6 ke atas, jadi tidak ada di ArcMap. - Cara
.format:{}menandai tempat nilai. Nilainya menyusul di.format(...).
KPH Gamma luasnya 8.00 ha
KPH Gamma luasnya 8.00 ha
KPH Gamma luasnya 8.00 haMenulis dan membaca berkas teks #
with open("catatan.txt", "w", encoding="utf-8") as f:
f.write("Petak P-01\n")
f.write("Petak P-02\n")
with open("catatan.txt", "r", encoding="utf-8") as f:
for baris in f:
print(baris.strip())Penjelasannya:
open("catatan.txt", "w", ...)membuka berkas untuk ditulis. Berkas lama dengan nama itu ditimpa.encoding="utf-8"menjaga huruf Indonesia dan simbol tidak rusak. Biasakan menulisnya.f.write(...)menulis teks.\nberarti pindah baris.- Blok kedua membuka berkas untuk dibaca. Perulangan
for baris in fmembaca satu baris tiap putaran. .strip()membuang spasi dan pindah baris di ujung teks.
Petak P-01
Petak P-02Tabel dalam berkas: CSV #
Modul csv mengurus koma dan tanda kutip untuk Anda.
import csv
baris = [["KODE_PETAK", "NAMA_KPH", "LUAS_HA"], ["P-01", "KPH Alpha", 4.0], ["P-02", "KPH Beta", 4.0]]
with open("jati.csv", "w", newline="", encoding="utf-8") as fh:
w = csv.writer(fh)
for b in baris:
w.writerow(b)
with open("jati.csv", encoding="utf-8") as fh:
for b in csv.reader(fh):
print(b)Penjelasannya:
newline=""mencegah baris kosong ekstra di Windows.csv.writer(fh)membuat penulis.w.writerow(...)menulis satu baris tabel.csv.reader(fh)membaca berkas itu, baris demi baris, dalam bentuk daftar.- Perhatikan: saat dibaca kembali, semua isi berupa teks, termasuk angka
4.0menjadi'4.0'. Ubah denganfloat(...)bila perlu menghitung.
['KODE_PETAK', 'NAMA_KPH', 'LUAS_HA']
['P-01', 'KPH Alpha', '4.0']
['P-02', 'KPH Beta', '4.0']Data bersusun: JSON #
JSON menyimpan kamus dan daftar sebagai teks. Cocok untuk pengaturan atau data yang berlapis.
import json
data = {"kph": "KPH Alpha", "petak": ["P-01", "P-02"], "luas_ha": 4.0}
teks = json.dumps(data, ensure_ascii=False)
print(teks)
kembali = json.loads(teks)
print(kembali["petak"][1])json.dumps mengubah kamus menjadi teks JSON. json.loads mengubah teks itu kembali menjadi kamus. ensure_ascii=False menjaga huruf non-Latin tetap terbaca.
{"kph": "KPH Alpha", "petak": ["P-01", "P-02"], "luas_ha": 4.0}
P-02Skrip yang dibedah: ekspor ke CSV di b2_07 #
Skrip b2_07_laporan.py membuat rekap akhir dari sebuah layer QGIS. Di bab ini kita bedah bagian akhirnya, yang mengekspor petak jati berumur tua ke berkas CSV. Skrip lengkapnya dibahas di Bab 15.
Tujuan. Menulis daftar petak terpilih ke berkas CSV yang bisa dibuka di Excel.
Bahan. Layer lap yang sudah ada dan berisi seleksi (dari bagian atas skrip), serta folder KELUAR. Potongan ini hanya bisa dijalankan sebagai bagian dari skrip lengkap, di dalam QGIS.
Skrip (potongan):
with open(KELUAR + "/Jati_Tua.csv", "w", newline="", encoding="utf-8") as fh:
w = csv.writer(fh)
w.writerow(["KODE_PETAK", "NAMA_KPH", "LUAS_HA", "UMUR", "POHON_HA", "VOL_HA"])
for f in lap.selectedFeatures():
w.writerow([f["KODE_PETAK"], f["NAMA_KPH"], f["LUAS_HA"], f["UMUR"], f["POHON_HA"], f["VOL_HA"]])Penjelasan baris demi baris. Nomor baris dihitung dari potongan di atas.
| Baris | Tulisan | Artinya |
|---|---|---|
| 1 | with open(KELUAR + "/Jati_Tua.csv", "w", ...) as fh: | Buka berkas CSV untuk ditulis di folder hasil. Sambungan teks dengan + merangkai alamatnya. Berkas diberi nama pendek fh. |
| 2 | w = csv.writer(fh) | Buat penulis CSV yang menulis ke berkas itu. |
| 3 | w.writerow([...]) | Tulis baris judul kolom. |
| 4 | for f in lap.selectedFeatures(): | Ulangi untuk tiap petak yang sedang terpilih di layer. |
| 5 | w.writerow([f["KODE_PETAK"], ...]) | Tulis satu baris tabel: isi enam kolom dari petak yang sedang dibaca. |
Hasil. Berkas Jati_Tua.csv berisi satu baris judul dan satu baris untuk tiap petak terpilih. Bentuk isinya mengikuti contoh jati.csv di atas.
Bagian yang boleh diubah.
- Nama berkas (baris 1): ganti
Jati_Tua.csvmenjadi nama lain. - Baris judul (baris 3): ganti nama kolom, dan sesuaikan isi di baris 5 dengan urutan yang sama.
- Kolom yang ditulis (baris 5): tambah atau kurangi kolom. Jumlah dan urutannya harus sama dengan baris judul.
Jebakan.
- Lupa
newline="". Di Windows, berkas CSV punya baris kosong di antara isi. - Menimpa berkas lama tanpa sadar. Mode
"w"menimpa. Pakai nama berbeda, atau mode"a"untuk menambah di ujung. - Nilai kosong. Kolom yang kosong di data (nilai
None) ditulis sebagai teks kosong. Cek dulu bila hasilnya akan dihitung. - Huruf rusak di Excel. Bila nama berisi huruf khusus, Excel di beberapa versi lebih suka
utf-8-sig. [CEK]
Latihan variasi. Tulis skrip mandiri yang menulis daftar tiga petak (kode dan luas) ke petak.csv, lalu membacanya kembali dan mencetak jumlah luas seluruhnya.
Contoh jawaban:
import csv
petak = [["P-01", 4.0], ["P-02", 8.0], ["P-03", 2.5]]
with open("petak.csv", "w", newline="", encoding="utf-8") as fh:
w = csv.writer(fh)
w.writerow(["KODE", "LUAS_HA"])
for p in petak:
w.writerow(p)
total = 0
with open("petak.csv", encoding="utf-8") as fh:
pembaca = csv.reader(fh)
next(pembaca)
for baris in pembaca:
total = total + float(baris[1])
print("Total luas:", total, "ha")Total luas: 14.5 haBaris next(pembaca) melewati satu baris pertama, yaitu baris judul. Baris float(baris[1]) mengubah teks kembali menjadi angka.
Cek paham #
- Apa keuntungan
with open(...)dibandingopen(...)saja? - Mengapa angka yang dibaca dari CSV perlu diubah dengan
float(...)? - Apa bedanya mode
"w"dan"r"?
Jawaban.
- Berkas ditutup otomatis setelah blok selesai, bahkan bila terjadi galat.
- Karena semua isi CSV terbaca sebagai teks, dan teks tidak bisa dijumlahkan sebagai angka.
"w"untuk menulis dan menimpa isi lama."r"untuk membaca.
Kesalahan umum #
- Memakai alamat berkas yang folder induknya belum ada. Perbaikan: buat dulu dengan
os.makedirs(..., exist_ok=True). - Membuka berkas CSV di Excel saat skrip masih menulis. Perbaikan: tutup Excel dulu, jalankan skrip, lalu buka hasilnya.
- Mencampur cara merakit teks dalam satu skrip. Perbaikan: pilih satu cara dan konsisten.
Ringkasan dan latihan #
- Berkas ditulis dan dibaca dengan
with open(...). Mode"w"menulis,"r"membaca. - Rakit teks dengan
%,.format, atau f-string. csvuntuk tabel,jsonuntuk data bersusun.
Latihan. Buat berkas rekap.csv yang berisi daftar tiga KPH dan luasnya. Lalu tulis skrip yang membacanya dan mencetak satu kalimat untuk tiap KPH dengan f-string.
Tabel perbandingan: tiga cara merakit teks #
| Cara | Contoh | Catatan |
|---|---|---|
% | "%s %.2f" % (nama, luas) | Tersedia di Python 2.7 dan 3 |
.format | "{} {:.2f}".format(nama, luas) | Tersedia di Python 2.7 dan 3 |
| f-string | f"{nama} {luas:.2f}" | Hanya Python 3.6 ke atas |