Alur kerja analis tidak berhenti di memori. Data penjualan diekspor aplikasi kasir ke berkas CSV, rekap harian ditulis ulang menjadi laporan teks, dan hasil analisis perlu disimpan agar bisa dibagikan. Membaca serta menulis berkas adalah jembatan antara cakram dan program — dan Python bawaan sudah cukup untuk semuanya, tanpa library tambahan apa pun. Pada chapter ini kita memakai satu berkas kecil penjualan.csv milik Toko Kopi Kita: membacanya dengan open() dan with, menulis dan menambah isi berkas, menguraikan CSV dengan modul csv, lalu merapikan pengelolaan jalur berkas dengan pathlib.

Membaca Berkas dengan open() dan with #

Sepanjang chapter kita memakai berkas berikut — catatan lima transaksi selama tiga hari, lengkap dengan baris kepala berisi nama kolom:

csv
tanggal,produk,jumlah
2026-01-12,kopi susu,3
2026-01-12,teh tawar,2
2026-01-13,kopi susu,1
2026-01-13,matcha,4
2026-01-14,americano,2

Membacanya memakai open() yang dibungkus with. Blok with memastikan berkas ditutup otomatis — baik ketika pembacaan selesai maupun ketika terjadi galat di tengah jalan — sehingga kita tidak pernah lupa menutup berkas. Dua metode inti pembacaan adalah read() yang mengambil seluruh isi sebagai satu string, dan readlines() yang memotongnya menjadi list baris:

python
with open("penjualan.csv") as berkas:
    isi = berkas.read()

print("--- Hasil read() ---")
print(isi, end="")

with open("penjualan.csv") as berkas:
    daftar_baris = berkas.readlines()

print("--- Hasil readlines() ---")
print("Jumlah baris :", len(daftar_baris))
print("Baris pertama:", daftar_baris[0].rstrip())
print("Baris terakhir:", daftar_baris[-1].rstrip())

Output yang Dihasilkan:

text
--- Hasil read() ---
tanggal,produk,jumlah
2026-01-12,kopi susu,3
2026-01-12,teh tawar,2
2026-01-13,kopi susu,1
2026-01-13,matcha,4
2026-01-14,americano,2
--- Hasil readlines() ---
Jumlah baris : 6
Baris pertama: tanggal,produk,jumlah
Baris terakhir: 2026-01-14,americano,2

Mari kita bedah baris-barisnya:

  1. Baris 1 (with open(...)): open("penjualan.csv") tanpa mode berarti mode baca "r". Berkas ditemukan karena ia berada satu folder dengan skrip; jalur relatif dihitung dari direktori kerja.
  2. Baris 2 (read()): seluruh isi berkas menjadi satu string, termasuk setiap karakter baris baru \n di ujung tiap baris.
  3. Baris 5 (print(isi, end="")): argumen end="" mengganti baris baru bawaan print dengan string kosong, sehingga tidak muncul baris kosong ganda — isi string sudah membawa karakter baris barunya sendiri.
  4. Baris 8 (readlines()): isi berkas menjadi list; setiap elemen adalah satu baris beserta \n di ujungnya.
  5. Baris 11-12 (rstrip()): .rstrip() membuang spasi dan \n di ujung tiap baris agar tercetak rapi; len(daftar_baris) sekaligus membuktikan berkas ini berisi enam baris — satu kepala dan lima data.

Untuk menulis, open() diberi mode: "w" membuat berkas baru (atau mengosongkan yang sudah ada!), sedangkan "a" menempel di akhir berkas tanpa menyentuh isi lama. Contoh berikut memakai direktori sementara supaya latihan kita tidak meninggalkan berkas percobaan di folder proyek:

python
import tempfile
from pathlib import Path

with tempfile.TemporaryDirectory() as tmp:
    lokasi = Path(tmp) / "ringkasan.txt"

    with open(lokasi, "w") as berkas:
        berkas.write("Ringkasan penjualan Toko Kopi Kita\n")
        berkas.write("Total cangkir terjual: 12\n")

    with open(lokasi, "a") as berkas:
        berkas.write("Pelanggan paling rajin: Budi\n")

    with open(lokasi) as berkas:
        print(berkas.read(), end="")

Output yang Dihasilkan:

text
Ringkasan penjualan Toko Kopi Kita
Total cangkir terjual: 12
Pelanggan paling rajin: Budi

Alurnya tiga babak: blok with pertama menulis dua baris awal, blok kedua menambah satu baris lewat mode "a" tanpa menghapus dua baris sebelumnya, dan blok ketiga membaca ulang untuk membuktikan hasilnya. Metode write() menulis persis apa adanya, sehingga baris baru \n harus kita tulis sendiri di ujung tiap baris.

Membaca CSV dengan csv.reader #

CSV (comma-separated values) adalah format pertukaran data paling umum: tiap baris adalah record, tiap kolom dipisah koma. Secara teknis kita bisa memecah baris dengan baris.split(","), tetapi cara itu rapuh — begitu ada nilai yang memuat koma di dalam tanda kutip, hasil pecahannya salah. Modul csv dari pustaka standar menangani seluruh aturan tersebut untuk kita:

python
import csv

total_per_produk = {}

with open("penjualan.csv") as berkas:
    for baris in csv.reader(berkas):
        if baris[0] == "tanggal":  # lewati baris kepala
            continue
        produk = baris[1]
        jumlah = int(baris[2])
        total_per_produk[produk] = total_per_produk.get(produk, 0) + jumlah

for produk in sorted(total_per_produk):
    print(f"{produk:12} {total_per_produk[produk]} cangkir")
print("Total:", sum(total_per_produk.values()), "cangkir")

Output yang Dihasilkan:

text
americano    2 cangkir
kopi susu    4 cangkir
matcha       4 cangkir
teh tawar    2 cangkir
Total: 12 cangkir

Mari kita bedah intinya:

  1. Baris 6 (csv.reader(berkas)): untuk setiap baris berkas, reader menghasilkan list string — misalnya ["2026-01-12", "kopi susu", "3"] — dengan pemisahan koma yang benar, termasuk saat sebuah nilai memuat koma di dalam tanda kutip.
  2. Baris 7-8 (melewati kepala): baris pertama berisi nama kolom, bukan data, sehingga dilewati dengan continue.
  3. Baris 10 (int(baris[2])): semua nilai CSV datang sebagai string; sebelum dijumlahkan, kolom jumlah dikonversi menjadi bilangan.
  4. Baris 11 (dict.get): pola total_per_produk.get(produk, 0) + jumlah mengakumulasi penjualan tiap produk — persis pola dictionary dari chapter Struktur Data Python .
  5. Baris 13-15 (sorted): hasil dicetak terurut menurut nama produk agar laporan konsisten antar eksekusi.

Modul csv juga punya csv.writer untuk menulis CSV — kebalikan dari reader, dengan metode writerow(). Di proyek analisis sesungguhnya kita nantinya jarang menguraikan CSV manual karena pandas menyediakan read_csv() yang mengerjakan semuanya sekaligus; namun memahami mekanik di baliknya membuat kita tahu apa yang sebenarnya terjadi ketika hasil pd.read_csv tidak sesuai dugaan.

Merapikan Pengelolaan Berkas dengan pathlib #

Sejauh ini kita memakai string jalur. Pendekatan itu merepotkan begitu foldernya bertingkat: penggabungan dengan +, penyesuaian pemisah /, dan pengecekan keberadaan berkas semuanya manual. Modul pathlib menggantinya dengan objek Path yang mengerti operasi berkas:

python
import tempfile
from pathlib import Path

with tempfile.TemporaryDirectory() as tmp:
    folder = Path(tmp)

    (folder / "penjualan_januari.csv").write_text("tanggal,produk,jumlah\n")
    (folder / "penjualan_februari.csv").write_text("tanggal,produk,jumlah\n")
    (folder / "catatan.txt").write_text("Menunggu data Maret\n")

    print("Isi folder:")
    for berkas in sorted(folder.iterdir()):
        print("-", berkas.name)

    print("Catatan:", (folder / "catatan.txt").read_text().rstrip())

Output yang Dihasilkan:

text
Isi folder:
- catatan.txt
- penjualan_februari.csv
- penjualan_januari.csv
Catatan: Menunggu data Maret

Tiga kemampuan yang langsung terlihat:

  1. Operator /: folder / "catatan.txt" merangkai jalur tanpa peduli pemisah folder di sistem operasi mana pun — jauh lebih bersih daripada menggabungkan string.
  2. write_text dan read_text: masing-masing cukup satu baris untuk menulis dan membaca seluruh isi berkas teks — keduanya pembungkus rapi di atas pola open()-with yang kita pakai di bagian sebelumnya.
  3. iterdir(): menghasilkan isi satu folder; kita bungkus sorted() karena urutan mentahnya tidak dijamin — kebiasaan yang sama seperti pada set.

Jalur berbasis Path juga kompatibel dengan open(), csv.reader, dan hampir semua fungsi pustaka standar, sehingga tidak ada alasan menunda memakainya sejak sekarang.

Referensi Resmi #

  • pandas.read_csv — cara membaca CSV yang akan kita pakai sehari-hari di proyek analisis; pemahaman manual di atas menjadi bekal saat hasilnya perlu ditelusuri.

Rangkuman #

  • with open(...) menjamin berkas tertutup otomatis; read() mengembalikan satu string, readlines() mengembalikan list baris yang ujungnya perlu rstrip().
  • Mode "w" mengosongkan berkas sebelum menulis, "a" menambah di akhir; write() tidak menambahkan baris baru secara otomatis.
  • Modul csv menguraikan CSV dengan benar termasuk nilai berkoma dalam tanda kutip; kolom angka tetap harus dikonversi dari string.
  • pathlib.Path merangkai jalur dengan operator / serta menyediakan read_text, write_text, dan iterdir yang ringkas.
  • Pemrosesan manual ini adalah fondasi; dalam proyek nyata pandas read_csv() yang akan mengambil peran.

Kita kini bisa mengambil data dari cakram — tetapi berkas yang dibaca belum tentu ada, dan isinya belum tentu rapi: nama berkas salah ketik, kolom angka menyimpan teks, daftar bisa saja kosong. Chapter berikutnya, Penanganan Error , mengajarkan cara menangkap galat tersebut dengan try-except agar program analisis tetap terkendali.