Lompat ke konten

Dasar Pemrograman

Ilmu Komputer Universitas · Topik 1

1.1

Apa kursus ini, dan bagaimana menggunakannya

Ini adalah kursus pertama di Ilmu Komputer Universitas: prinsip dasar pemrograman , diajarkan menggunakan Python 3. Kursus ini tidak memerlukan pengalaman pemrograman sebelumnya. Setiap program dalam modul ini lengkap dan dapat dijalankan — ketik, jalankan, ubah satu baris, dan prediksi apa yang berubah sebelum menjalankannya lagi. Siklus prediksi-lalu-jalankan inilah seluruh keterampilan tersebut.

Kursus ini merupakan sebuah tangga:

  • Unit 1.1 hingga 1.3 membangun mekanisme: nilai dan jenis, pemilihan, iterasi.
  • Unit 1.4 mengemas pekerjaan ke dalam fungsi.
  • Unit 1.5 dan 1.6 menambahkan koleksi standar dan file dengan penanganan kesalahan.
  • Unit 1.7 adalah disiplin utama: menguraikan masalah, pengujian, dan perbaikan kesalahan.

Cara membaca setiap unit: sebuah cerita singkat menjelaskan mengapa hal itu penting; sebuah gambar atau aturan praktis datang sebelum sintaks apa pun; kemudian aturan yang presisi; lalu contoh kerja yang semakin sulit, setiap satu memiliki jejak yang dapat Anda periksa dengan menjalankan kode; kemudian kesalahan yang sebenarnya dibuat orang; lalu ringkasan tiga baris. Setiap contoh di sini dapat diperiksa dengan cara kedua — menjalankannya. Membaca kode tanpa menjalankannya seperti membaca notasi musik tanpa mendengarkannya.

Kosa kata Latih
English Bahasa Indonesia
set/set/ set: himpunan
file/faɪl/ file: file
exceptions pengecualian
decomposition/ˌdiːkɒmpəˈzɪʃn/ decomposition: dekomposisi
testing/ˈtestɪŋ/ pengujian
debugging/ˈdiːbʌɡɪŋ/ penyelarasan
1.1

Nilai, tipe, dan input/OUTPUT

Aplikasi belanja menampilkan "4.20" — apakah itu teks atau angka? Jika itu teks, menambahkan dua harga menghasilkan "4.203.50"; jika itu angka, hasilnya 8.7. Yang mana yang terjadi ditentukan oleh tipe, dan seluruh unit 1.1 adalah belajar melihat tipe sebelum Anda menjalankan apa pun.

Sebuah nilai memiliki tipe, dan tipe menentukan apa yang dapat Anda lakukan dengannya: int (bilangan bulat ), float (desimal), str (teks), bool (True/False). Fungsi type(...) menyebutkan tipe dari setiap nilai — tanyakan secara bebas saat belajar.

age = 21              # int
price = 4.20          # float
name = "Ada"          # str
open_ = True          # bool
print(type(age))      # <class 'int'>

Variabel adalah nama yang dikaitkan dengan nilai; penugasan age = 22 mengikat ulang nama tersebut — tidak pernah mengedit nilai lama. Peta mental yang layak untuk dijaga sepanjang masa kuliah:

Keadaan program sebagai kotak: setiap label nama menunjuk ke kotak nilainya sendiri; pengikatan ulang memindahkan label, tidak pernah mengedit kotak. Ekspresi 6 * 3.50 membaca dua kotak dan menghasilkan kotak float baru 21.0
Nama adalah label pada kotak; ekspresi membaca kotak dan membuat kotak baru

Membaca ekspresi berarti "buka kotak, hitung, tutup kotak baru": count * 3.50 dengan count = 6 membuka kotak int 6 dan kotak float 3.50, dan pencampuran Python aturan mendorong int — hasilnya adalah float 21.0, bukan int 21.

Konversi bersifat eksplisit: int("21") adalah 21, tetapi "4" + 2 adalah TypeError — Python menolak menebak apakah Anda bermaksud "42" atau 6. Keluaran dengan print(...); masukan dengan input(...), yang selalu mengembalikan string, sehingga angka perlu dikonversi:

born = int(input("Birth year? "))
print("About", 2026 - born, "years old")

Contoh terpecahkan 1 (mesin kasir kafe). count = int(input("Coffees? ")), kemudian print("Total:", count * 3.50). Pada 6 cangkir kopi ini mencetak Total: 21.0 — yaitu .0 menandai float, karena int * float didorong ke float. Memantau jenis apa yang keluar dari sebuah ekspresi adalah kebiasaan utuh dari unit 1.1. Telusuri dengan cara keadaan: input mengembalikan string "6"; int(...) membuka kotak baru yang berisi int 6; perkalian membuat kotak float baru 21.0; print menampilkannya.

Contoh terpecahkan 2 (kecelakaan klasik, diperbaiki). Sebuah pencetak spanduk menggabungkan hitungan kepada sebuah pesan:

count = int(input("Tickets? "))
print("Sold " + count + " today")

Jalankan dan Python akan memicu TypeError: can only concatenate str (not "int") to str — aturan menolak menebak. Perbaikan tersebut menyebutkan konversi secara eksplisit: print("Sold " + str(count) + " today"), atau yang lebih bersih print("Sold", count, "today"), which inserts the spaces for you. The lesson to carry: + berarti penjumlahan untuk angka, penggabungan untuk string, dan never campur diam-diam.

Kesalahan umum. Melupakan bahwa input() selalu menghasilkan string, sehingga input() * 2 mengulang teks daripada melipatgandakan angka. Menulis 4.20 + 6 dan mengharapkan jawaban int — setiap float dalam ekspresi menghasilkan float. Percaya 0.1 + 0.2 == 0.3 (ini adalah False; pembulatan biner — unit 1.2 menunjukkan perbaikannya).

Ringkasan: empat jenis dasar menentukan setiap operasi; nama adalah tag, penugasan mengikat ulang; ekspresi mencampur tipe dengan promosi ke float; konversi bersifat eksplisit dan input() membutuhkan satu.

Kosa kata Latih
English Bahasa Indonesia
programming fundamentals/ˈprəʊɡræmɪŋ ˌfʌndəˈmentlz/ prinsip pemrograman
type/taɪp/ tipe
string/strɪŋ/ string
selection/sɪˈlekʃn/ pemilihan
iteration/ˌɪtəˈreɪʃn/ iterasi
infinite loop/ˈɪnfɪnət luːp/ infinite loop: perulangan tak hingga
trace table/treɪs ˈteɪbl/ trace table: tabel pelacakan
1.2

Seleksi: memilih antara jalur

Pintu gerbang taman hiburan harus menagih anak-anak, orang dewasa, dan lansia secara berbeda — satu program, beberapa jalur. Seleksi adalah cara program memilih: if, elif, else menjalankan blok hanya ketika suatu kondisi terpenuhi.

Diagram alur aturan harga bioskop dengan pemeriksaan usia sebelum pemeriksaan pelajar; pelajar berusia 70 tahun mengambil cabang pertama yang benar dan membayar 5
Usia 70, mahasiswa: cabang pertama yang benar menentukan harga

Kondisi adalah ekspresi boolean apa pun; perbandingan (==, !=, <, >=) dan logika (and, or, not) membangunnya. Dua aturan membuat setiap keputusan mudah dibaca:

  1. Cabang diuji dari atas ke bawah; cabang pertama yang benar menang dan sisanya dilewati.
  2. Indentasi bukan sekadar hiasan — ia ADALAH blok. Satu spasi ekstra mengubah garis mana yang termasuk dalam cabang tersebut.
temp = 37.5
if temp >= 38:
    print("Fever")
elif temp >= 36 and temp < 38:
    print("Normal")
else:
    print("Low")

Contoh terpecahkan 1 (harga bioskop). Di bawah 12 atau 65+ bayar 5, mahasiswa membayar 7, semua orang lain 10:

age = int(input("Age? "))
student = input("Student? y/n ") == "y"
if age < 12 or age >= 65:
    price = 5
elif student:
    price = 7
else:
    price = 10
print("Pay", price)

Urutan itu penting: cabang pertama yang benar menang, itulah sebabnya pengecekan usia mendahului pengecekan mahasiswa — mahasiswa berusia 70 seharusnya membayar 5, dan pengurutan ini menyatakannya. Jalankan dengan 70 dan y untuk melihat jalur paling kiri pada diagram alir diambil.

Contoh terpecahkan 2 (rentang nilai, ditingkatkan). Rangka yang sama, kini dengan rantai di mana setiap elif hanya memerlukan satu perbandingan, karena uji di atasnya sudah gagal:

score = int(input("Score? "))
if score >= 80:
    band = "A"
elif score >= 70:
    band = "B"
elif score >= 60:
    band = "C"
else:
    band = "F"
print("Band:", band)

Di 79 uji pertama gagal, kedua berhasil: Band: B. Peningkatan ke perhatian: elif score >= 70 tidak juga membutuhkan and score < 80 — mencapai baris tersebut sudah membuktikan skor berada di bawah 80. Mempercayai alur jatuh seperti ini adalah yang membuat rantai pendek; menguji semuanya kembali adalah versi pemula yang lebih panjang dan salah. versi.

Perbandingan bilangan floating-point memerlukan kehati-hatian: 0.1 + 0.2 == 0.3 adalah False (biner pembulatan), jadi bandingkan terhadap toleransi: abs(x - y) < 1e-9.

Kesalahan umum. Menulis = di mana seharusnya == — bug klasik, dan Python menolaknya dalam kondisi (SyntaxError) tepat karena hal itu sangat umum. Menguji kasus khusus setelah kasus umum, sehingga kasus umum selalu menang. Menggunakan elif dengan kondisi yang tidak pernah dapat dicapai karena cabang sebelumnya sudah menangkapnya.

Ringkasan: kondisi memilih jalur, menang-nyata-pertama, indentasi adalah blok; urutkan uji dari spesifik-ke-umum; titik-mengambang dibandingkan melalui toleransi, bukan oleh ==.

1.3

Iterasi: melakukannya lagi

Membayar tagihan 5,000 secara manual adalah sebuah karier; dengan perulangan ia menjadi program. Iterasi mengulang pekerjaan: perulangan for menelusuri urutan yang diketahui; perulangan while berjalan selama syarat terpenuhi. Pertanyaan desainnya selalu: apakah Anda tahu berapa banyak trip, atau apakah sebuah syarat yang menentukannya?

total = 0
for i in range(1, 101):      # 1..100 — range stops BEFORE its end
    total += i
print(total)                  # 5050

Gunakan for ketika jumlah trip diketahui; gunakan while ketika syarat yang menentukannya. Setiap while membutuhkan tiga hal yang terlihat dalam kode: awal variabel, kondisi, dan sesuatu di dalamnya yang bergerak menuju keluar — jika tidak, itu adalah loop tak terbatas. loop**.

Perulangan while faktorial berdampingan dengan tabel pelacakannya: n dan factorial setelah setiap putaran, dari 5 dan 1 hingga 1 dan 120, saat kondisi berubah menjadi False
Tabel jejak untuk loop faktorial
n = 5
factorial = 1
while n > 1:
    factorial *= n
    n -= 1                    # the step toward exiting
print(factorial)              # 120

Tabel jejak adalah kebiasaan pengecekan kursus untuk loop: ikuti variabel-variabelnya dari putaran ke putaran, di atas kertas terlebih dahulu. Untuk loop faktorial: (n=5, f=1) → (4, 5) → (3, 20) → (2, 60) → (1, 120). Bangun tabel secara manual, lalu tambahkan print(n, factorial) di dalam loop dan biarkan Python mengoreksi Anda.

Contoh terpecahkan 2 (pencarian dengan break, ditingkatkan). Temukan kelipatan pertama dari 7 yang lebih besar dari 100 — jumlah trip tidak diketahui, syarat yang menentukannya:

n = 100
while True:
    if n % 7 == 0:
        break                 # found it — leave the loop now
    n += 1
print(n)                      # 105

Jejaknya singkat: 100, 101, …, 104 semuanya gagal tes; 105 lolos dan break keluar. break meninggalkan loop lebih awal; continue melompat ke putaran berikutnya. Keduanya adalah alat keterbacaan — loop yang harus memindai hingga menemukan sesuatu, lalu berhenti, terbaca terbaik dengan break. Peningkatan lebih lanjut, menggandakan uang: pada 5% per tahun, berapa lama 1000 butuh untuk mencapai 2000?

balance = 1000.0
years = 0
while balance < 2000.0:       # the condition itself is the goal
    balance *= 1.05
    years += 1
print(years, round(balance, 2))   # 15 2078.93

Lima belas tahun, dan loop berhenti saat syarat berubah — tabel jejak akan menunjukkan saldo melewati garis di 2078.93, bukan mendarat tepat di 2000.

Kesalahan umum. Mengedit daftar (unit 1.5) atau variabel perulangan yang Anda for-berputar. range(1, 100) ketika 100 seharusnya digunakan — akhir tidak termasuk. A while yang langkah keluarannya hilang atau dikomentari: kondisi tidak pernah berubah, dan program macet.

Ringkasan: for untuk jumlah perjalanan yang diketahui, while untuk kondisi; setiap loop menunjukkan awal, syarat dan langkah; jejak di atas kertas, lalu cetak-tingkat; break dan continue untuk keluaran dini yang bersih.

1.4

Fungsi: memberi nama pekerjaan sekali

Perhitungan harga yang sama muncul di lima tempat; aturan pajak berubah; empat dari lima diperbarui. A function mengemas pekerjaan di balik nama agar ditulis sekali dan dipercaya di mana saja: parameter masuk, a return value keluar. def mendefinisikan; pemanggilan menjalankan.

def total_price(count, unit=3.50):
    """Return the total for count items at unit price."""
    return count * unit

print(total_price(6))            # 21.0
print(total_price(6, unit=4.0))  # 24.0

Definisi memberikan a parameter (count, unit); pemanggilan menyediakan a argument (6). Nilai default (unit=3.50) membuat argumen opsional. return mengembalikan nilai dan mengakhiri pemanggilan; printing is not returning — a fungsi tanpa return mengembalikan None, dan pemanggil yang mencoba aritmatika padanya mendapatkan a TypeError.

Three call frames: print calls order_total(250, 4), which pauses while add_fee(1000) runs; 1003 is returned back along the chain
Panggilan bersarang: Caller berhenti hingga nilai kembali

Setiap pemanggilan mendapatkan a local scope: nama di dalamnya tidak terlihat di luar, dan menghilang ketika panggilan berakhir. Jejak panggilan untuk panggilan bersarang membaca: pemanggil berhenti → penerima berjalan → nilai pengembalian mendarat di pemanggil.

Contoh terpecahkan 1 (pesanan termasuk biaya).

def add_fee(amount):
    """Return amount plus a fixed 3 pence fee."""
    return amount + 3

def order_total(unit_pence, quantity):
    """Return the order total: subtotal plus the fixed fee."""
    return add_fee(unit_pence * quantity)

print(order_total(250, 4))   # 1003

Kontrak dalam docstring itu penting: pence bulat masuk, pence bulat keluar. Melacak order_total(250, 4): subtotal 1000, add_fee mengembalikan 1003 — dan bingkai diagram di atas menunjukkan jeda dan serah terima.

Contoh terpecahkan 2 (algoritma nyata di dalam fungsi kecil, ditingkatkan). is_prime(n) mengembalikan True ketika tidak ada dari 2 hingga $\sqrt{n}$ yang membagi n:

def is_prime(n):
    if n < 2:
        return False
    d = 2
    while d * d <= n:        # only test up to the square root
        if n % d == 0:
            return False     # found a divisor — answer known, stop
        d += 1
    return True

print([p for p in range(2, 30) if is_prime(p)])
# [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]

Dua kebiasaan fungsi bertemu di sini: return awal mengakhiri panggilan segera setelah jawaban diketahui (tidak perlu variabel flag), dan batas perulangan d * d <= n berasal dari penurunan — jika $n = a \times b$ dengan $a \le b$, maka $a \le \sqrt{n}$, sehingga pengujian melebihi $\sqrt{n}$ menguji kembali pembagi yang sudah dilihat. Jalankan: daftar tersebut adalah tepat bilangan prima di bawah 30.

Kesalahan umum. Mencetak di dalam fungsi alih-alih mengembalikan, sehingga hasilnya tidak dapat digunakan kembali. Lupa return pada salah satu cabang — jalur itu secara diam-diam menghasilkan None. Menjangkau ke lokal fungsi dari luar; mereka hilang ketika panggilan berakhir.

Ringkasan: def sekali, panggil di mana saja; parameter masuk, satu nilai keluar melalui return; pengembalian awal mengakhiri panggilan; lokal hidup dan mati bersama panggilan; docstrings menyatakan kontrak.

Kosa kata Latih
English Bahasa Indonesia
value/ˈvæljuː/ nilai
variables/ˈveərɪəblz/ variabel
function/ˈfʌŋkʃn/ function: fungsi
return value/rɪˈtɜːn ˈvæljuː/ nilai pengembalian
parameter/pəˈræmɪtə/ parameter
argument/ˈɑːɡjuːmənt/ argument: argumen aktual
local scope/ˈləʊkl skəʊp/ skop lokal
1.5

Koleksi: daftar, kamus, tuple, himpunan

Kasir kafe memerlukan pesanan harian yang tertata, menu berdasarkan nama, lokasi yang tidak boleh bergeser, dan minuman unik hari ini. Empat pekerjaan, empat wadah — memilih di antara mereka adalah keputusan desain unit 1.5.

List adalah urutan yang tertata dan dapat diubah: marks = [72, 85, 61], diindeks dari 0, dipotong dengan marks[1:3]. Dictionary memetakan kunci ke nilai: price = {"flat white": 3.5, "tea": 2.8}, dibaca dan ditulis berdasarkan kunci. Tuple adalah urutan tetap (53.1, -1.5) — cocok untuk koordinat yang tidak boleh berubah. Set menyimpan item unik tanpa urutan: {"a", "b"}.

marks = [72, 85, 61]
marks.append(90)               # [72, 85, 61, 90]
best = max(marks)              # 90
average = sum(marks) / len(marks)   # 77.0
Nama a dan b keduanya menunjuk ke satu objek list, yang memegang 1 dan 2 setelah b.append(2)
Aliasing: dua nama, satu list

Penugasan tidak pernah menyalin: a = [1]; b = a; b.append(2) membuat a [1, 2] — list dibagikan, namanya tidak. Aliasing ini adalah kotak unit 1.1 lagi, sekarang dengan dua label pada satu kotak, dan hal ini juga menjelaskan aturan berikutnya: memodifikasi list saat mengiterasi melompati elemen — iterasikan salinan (for m in marks[:]) atau buat list baru.

Contoh terpecahkan 1 (rekapitulasi per kategori).

orders = ["tea", "flat white", "tea", "tea", "mocha"]
tally = {}
for item in orders:
    tally[item] = tally.get(item, 0) + 1
print(tally)   # {'tea': 3, 'flat white': 1, 'mocha': 1}

.get(key, 0) dari dictionary menyediakan 0 untuk pengamatan pertama — idiom yang membuat perhitungan menjadi satu baris. Verifikasi manual: "tea" muncul tiga kali dalam orders, dan rekapitulasi yang dicetak mengonfirmasi hal itu.

Contoh terpecahkan 2 (penjual terbaik hari ini, ditingkatkan). Berbekal rekapitulasi, laporkan item teratas dan jumlahnya:

best = max(tally, key=tally.get)
print(best, tally[best])       # tea 3

Argumen key=tally.get meminta max untuk membandingkan item berdasarkan jumlah mereka daripada secara alfabetis — trik key= yang sama mengurutkan koleksi apa pun berdasarkan ukuran tertentu. Hal peningkatan ini penting: program nyata menggabungkan alat-alat ini (menghitung, lalu mengurut) daripada memindai ulang orders dua kali.

Memilih koleksi adalah keputusan desain: urutan + duplikat → list; pencarian berdasarkan nama → dictionary; pengelompokan tetap → tuple; keunikan → set.

Kesalahan umum. Mengakses tally[item] += 1 pada kunci yang belum ada di dictionary (KeyError) — .get adalah solusinya. Mengharapkan set atau dictionary untuk mengingat urutan. Menganggap bahwa b = a menyalin sebuah list; ia hanya membuat referensi (alias).

Ringkasan: empat wadah untuk empat tugas; penugasan berbagi referensi, bukan menyalin; .get membuat penghitungan aman; key= membuat peringkat menjadi satu baris kode.

Kosa kata Latih
English Bahasa Indonesia
list/lɪst/ list: daftar
dictionary/ˈdɪkʃənəri/ dictionary: kamus
tuple/ˈtuːpl/ tuple: tuple
aliasing/ˈeɪlɪəsɪŋ/ aliasing: penamaan ganda
1.6

File dan kesalahan

Kafe tutup, listrik mati — dan rekap pagi itu hanya terselamat jika program menuliskannya ke disk. File bertahan lebih lama daripada program. with open(path) as f: opens, closes on exit, and reads text; open(path, "w") menulis (dan mengosongkannya terlebih dahulu — kecelakaan klasik).

with open("log.txt", "w") as f:
    f.write("opened\n")

with open("log.txt") as f:
    for line in f:
        print(line.rstrip())     # rstrip removes the trailing newline

Blok with adalah pengaman: apa pun yang terjadi di dalamnya, file akan tertutup. Membaca memberikan baris berserta karakter baris baru, sehingga .rstrip() wajib ada dalam setiap perulangan.

Kesalahan adalah nilai yang Python bangkitkan sebagai kecualian: FileNotFoundError, ValueError, KeyError, TypeError. try/except menangkap tipe bernama — jangan pernah menggunakan except: polos yang menyembunyikan bug nyata.

Contoh terpecahkan 1 (file pengaturan yang hilang). Membaca ukuran teks dari file pengaturan file yang mungkin hilang, atau mungkin tidak berisi bilangan bulat:

try:
    with open("settings.txt") as f:
        size = int(f.read().strip())
except FileNotFoundError:
    size = 12                    # no file yet: a sensible default
except ValueError:
    size = 12                    # the file holds "big", not a number
print("Text size", size)

Jalankan tiga kali — dengan 16 dalam file, tanpa file, dan dengan big dalam file — dan mencetak ukuran yang dapat digunakan setiap kali, dari tiga rute berbeda. Inilah bentuk kode yang tangguh: satu cara yang logis beberapa jalan menuju sana. Tangani kesalahan yang Anda harapkan, di mana Anda dapat merespons padanya; biarkan sisanya crash dengan keras.

Pembaca pengaturan: blok try membuka, membaca, dan mengonversi nilai; jika berhasil, atau percabangan FileNotFoundError atau ValueError menetapkan ukuran default 12; ketiga jalur bertemu dan program terus berjalan

Contoh terpecahkan 2 (loop input tangguh, eskalasi). Minta hingga pengguna mengetik bilangan bulat:

def read_count():
    while True:
        try:
            return int(input("How many? "))
        except ValueError:
            print("Whole numbers only.")

print(read_count())

Berikan ke x lalu 4: perjalanan pertama memicu, ditangkap, mencetak pesan, dan while True meminta lagi; perjalanan kedua dari int(...) berhasil dan return keluar dari loop dan fungsi dalam satu gerakan. Tiga unit bergabung di sini — loop (1.3), kontrak fungsi (1.4) dan pengecualian (1.6) — yang merupakan inti dari eskalasi.

Kesalahan umum. Memasukkan ke open(path, "w") pada jalur yang salah: file dibuat atau dikosongkan sebelum Anda menyadari. Menangkap Exception secara luas dan melanjutkan dengan keadaan rusak. Melupakan .rstrip(), sehingga output menampilkan baris dengan spasi ganda.

Ringkasan: Gunakan with open(...) untuk membaca dan menulis; "w" kosongkan terlebih dahulu; pengecualian adalah nilai — tangkap tipe bernama yang Anda harapkan, gunakan alternatif yang masuk akal, biarkan sisa crash.

1.7

Dekomposisi, pengujian, dan perbaikan kode

Dua tim menulis aplikasi yang sama; satu selesai dalam seminggu, satu lagi tenggelam selama sebulan. Perbedaan bukanlah kecepatan mengetik — melainkan kode tim cepat dibangun dari potongan-potongan kecil yang masing-masing dapat dibuktikan kebenarannya, sementara tim lambat melakukan perbaikan pada seluruh aplikasi sekaligus. Unit 1.7 adalah disiplin tersebut.

Dekomposisi memecah masalah menjadi fungsi dengan satu tugas masing-masing — setiap bagian kecil cukup untuk diuji secara terpisah. Pengujian membandingkan output aktual sebuah fungsi dengan hasil yang diharapkan, pada batas-batas: nol, satu, kosong, negatif, sangat besar.

Siklus berbasis pengujian: tulis tes yang gagal yang menyatakan kontrak; jalankan dan lihat kegagalan yang tepat; tulis tubuh fungsi paling sederhana yang lolos; jalankan ulang hingga hijau; refaktor dengan tes menjaga struktur
Siklus berbasis pengujian: merah, hijau, refaktor
def add_fee(amount):
    return amount + 3

def order_total(unit_pence, quantity):
    return add_fee(unit_pence * quantity)

assert order_total(250, 4) == 1003
assert order_total(250, 0) == 3      # the zero-quantity boundary
assert order_total(0, 4) == 3

Sebuah assert yang tidak pernah aktif adalah tes yang berhasil. Tulis tes sebelum Anda menulis tubuh fungsi jika memungkinkan — mereka adalah kontrak yang dieksekusi, dan siklus di atas (merah → hijau → refaktor) adalah kebiasaan yang berjalan terus-menerus.

Contoh terpecahkan 1 (perluas tes dengan fungsi). Perpanjang order_total dengan sebuah diskon 10% di atas £10 — tes ditulis terlebih dahulu, pada batas baru:

def order_total(unit_pence, quantity):
    subtotal = add_fee(unit_pence * quantity)
    if subtotal >= 1000:             # pence: over £10
        subtotal = int(subtotal * 0.9)
    return subtotal

assert order_total(200, 4) == 803    # under £10 — unchanged
assert order_total(250, 4) == 902    # 1003 pence → 10% off → 902.7 → 902
assert order_total(250, 5) == 1127   # 1253 pence → 1127.7 → 1127

Periksa tes tengah secara manual: subtotal 1003, diskon sepuluh persen menghasilkan 902.7, dan int(...) dibulatkan ke bawah menjadi 902. Perhatikan assert pertama juga: pada 200 pence dan empat cangkir total tetap 803 — tes batas membuktikan bahwa diskon aktif dan juga tidak aktif terlalu dini.

Contoh terpecahkan 2 (memotong dua bug dengan cetakan, ditingkatkan). Total dari 1.5 cetakan {'tea': 3} tetapi baris terlaris mencetak minuman yang salah. Metodenya: (1) reproduksi dengan input gagal terkecil; (2) cetak nilai pada batas antara bagian terpercaya dan bagian yang dicurigai — di sini, total sebelum max; (3) perbaiki satu hal; (4) jalankan kembali tes. Memindahkan print di tengah-tengah kode setiap menjalankan memotong separuh pencarian: empat cetakan menemukan bug dalam program sebelas belas baris, namun seberapa pun ia bersembunyi.

Penyelarasan adalah menemukan perbedaan antara apa yang Anda yakini dilakukan kode dan apa yang sebenarnya dilakukannya — cetakan pada batas percaya/curiga adalah alatnya.

Kesalahan umum. Menguji hanya jalur bahagia: batas-batas (nol, satu, kosong, negatif) adalah tempat program rusak. Menulis minggu kode sebelum tes pertama, lalu menyelaraskan gunung. Memperbaiki dua hal sekaligus, sehingga tidak ada hasil yang bermakna sesuatu lainnya.

Ringkasan: dekomposisikan hingga setiap bagian diuji secara mandiri; nyatakan batas-batas segera setelah sebuah fungsi ada; tulis tes terlebih dahulu jika memungkinkan; selaraskan dengan biseksi menggunakan cetakan pada batas kepercayaan — kebiasaan yang menjadi fondasi seluruh gelar ini.

Pelajaran interaktif untuk topik ini

Kerjakan langkah demi langkah, dengan latihan pengecekan instan.

Topik lain dalam Ilmu Komputer Universitas

Masuk atau buat akun

IGCSE, A-Level & AP