15. Mendapatkan input — Solusi PR

File solusi .go ada di exercises/15/homework/solutions/.

Soal 1 — Sapa dengan nama

Soal. Beri prompt, baca nama, sapa dengan tanda seru.

Cara berpikir. Buat reader, cetak prompt, baca barisnya, rapikan, lalu cetak sapaan. Tanda seru ada di dalam string, setelah variabel.

Solusi yang dikerjakan.

package main

import (
    "bufio"
    "fmt"
    "os"
    "strings"
)

func main() {
    reader := bufio.NewReader(os.Stdin)

    fmt.Print("First name: ")
    text, _ := reader.ReadString('\n')
    name := strings.TrimSpace(text)

    fmt.Println("Hello, " + name + "!")
}

Kesalahan umum.

  • Lupa strings.TrimSpace. Akhiran baris tetap ada di dalam nama, sehingga ! jatuh ke baris di bawahnya.
  • Lupa spasi di akhir prompt. "First name:" membuat kursor menempel pada titik dua; "First name: " memberi ruang.
  • Menulis "\n", bukan '\n'. ReadString meminta satu karakter, dengan tanda kutip tunggal, dan Go berhenti dengan error cannot use pada bentuk bertanda kutip ganda.

Soal 2 — Jumlah dua angka

Soal. Baca dua angka; cetak a + b = c.

Cara berpikir. Dua prompt, dua pembacaan, masing-masing dirapikan dan dikonversi dengan strconv.Atoi. Pembacaan pertama mendeklarasikan text dengan := dan pembacaan kedua memakainya lagi dengan =. Buat outputnya dengan fmt.Printf.

Solusi yang dikerjakan.

package main

import (
    "bufio"
    "fmt"
    "os"
    "strconv"
    "strings"
)

func main() {
    reader := bufio.NewReader(os.Stdin)

    fmt.Print("First number:  ")
    text, _ := reader.ReadString('\n')
    a, _ := strconv.Atoi(strings.TrimSpace(text))

    fmt.Print("Second number: ")
    text, _ = reader.ReadString('\n')
    b, _ := strconv.Atoi(strings.TrimSpace(text))

    c := a + b
    fmt.Printf("%d + %d = %d\n", a, b, c)
}

Kalau mengetik 3 dan 4, outputnya:

First number:  3
Second number: 4
3 + 4 = 7

Kesalahan umum.

  • Melewati konversi. Nilainya tetap string, jadi a + b menyambungnya, bukan menjumlahkan: "3" + "4" adalah "34", bukan 7.
  • Melewati strings.TrimSpace. Setiap strconv.Atoi lalu melihat akhiran baris dan memberikan 0, sehingga outputnya 0 + 0 = 0.
  • Menulis text, _ := reader.ReadString('\n') untuk pembacaan kedua. Go berhenti dengan no new variables on left side of :=.
  • Menulis a := strconv.Atoi(...) dengan satu nama. Go berhenti dengan assignment mismatch: 1 variable but strconv.Atoi returns 2 values.

Soal 3 — Tahun menuju pensiun

Soal. Hitung 65 - age dan cetak kalimat berlabel.

Cara berpikir. Prompt, baca, rapikan, konversi, kurangi, cetak. Perhatikan urutannya: 65 - age, bukan age - 65.

Solusi yang dikerjakan.

package main

import (
    "bufio"
    "fmt"
    "os"
    "strconv"
    "strings"
)

func main() {
    reader := bufio.NewReader(os.Stdin)

    fmt.Print("Your current age: ")
    text, _ := reader.ReadString('\n')
    age, _ := strconv.Atoi(strings.TrimSpace(text))

    yearsLeft := 65 - age
    fmt.Printf("You have %d years until retirement.\n", yearsLeft)
}

Kesalahan umum.

  • Menulis age - 65, yang mencetak angka negatif untuk semua orang di bawah 65. Pengurangan tidak komutatif — urutan berpengaruh.
  • Menganggap hasil dari input yang salah sebagai umur. Mengetik abc membuat age bernilai 0, jadi program mencetak You have 65 years until retirement. tanpa tanda bahwa ada yang salah.

Tantangan — BMI

Soal. Minta tinggi dan berat (desimal), hitung BMI, cetak dengan satu angka desimal.

Cara berpikir. Dua prompt, dua pembacaan, keduanya melalui strconv.ParseFloat karena nilainya punya titik desimal. weight / (height * height) menghasilkan float64; %.1f menampilkan satu angka setelah titik desimal.

Solusi yang dikerjakan.

package main

import (
    "bufio"
    "fmt"
    "os"
    "strconv"
    "strings"
)

func main() {
    reader := bufio.NewReader(os.Stdin)

    fmt.Print("Height in metres (e.g. 1.78): ")
    text, _ := reader.ReadString('\n')
    height, _ := strconv.ParseFloat(strings.TrimSpace(text), 64)

    fmt.Print("Weight in kg (e.g. 72.5):     ")
    text, _ = reader.ReadString('\n')
    weight, _ := strconv.ParseFloat(strings.TrimSpace(text), 64)

    bmi := weight / (height * height)
    fmt.Printf("BMI: %.1f\n", bmi)
}

Kalau mengetik 1.78 dan 72.5, outputnya:

Height in metres (e.g. 1.78): 1.78
Weight in kg (e.g. 72.5):     72.5
BMI: 22.9

Kesalahan umum.

  • Memakai strconv.Atoi, bukan strconv.ParseFloat. Tinggi seperti 1.78 bukan bilangan bulat, jadi strconv.Atoi memberikan 0. Membagi int dengan int nol menghentikan program dengan panic: runtime error: integer divide by zero.
  • Mengetik huruf untuk tinggi. strconv.ParseFloat memberikan 0, dan BMI tercetak sebagai +Inf, cara Go menampilkan float64 yang dibagi nol.
  • Lupa tanda kurung pada height * height. Tanpa tanda kurung, weight / height * height berjalan dari kiri ke kanan: bagi dengan tinggi, lalu kalikan lagi dengan tinggi — tingginya saling menghapus dan kamu mendapatkan berat lagi.
  • Memasukkan tinggi dalam sentimeter (seperti 178), bukan meter (1.78). BMI memakai meter, seperti yang disebut prompt.

Selesai?

Semua bab Bagian 3 sudah selesai. Mini-proyeknya — Lembar Karakter — memakai semua yang ada di Bab 11 sampai 15.