15. Getting input — Homework solutions
The .go solution files are in
exercises/15/homework/solutions/.
Problem 1 — Greet by name
Problem. Prompt, read a name, greet with an exclamation mark.
How to think about it. Make the reader, print the prompt, read the line, trim it, then print the greeting. The exclamation mark goes inside the string, after the variable.
Worked solution.
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 + "!")
}Common mistakes.
- Forgetting
strings.TrimSpace. The line ending stays in the name, so the!lands on the line below. - Forgetting the trailing space in the prompt.
"First name:"jams the cursor against the colon;"First name: "leaves room. - Writing
"\n"instead of'\n'.ReadStringwants one character, in single quotes, and Go stops with acannot useerror on the double-quoted form.
Problem 2 — Sum of two
Problem. Read two numbers; print
a + b = c.
How to think about it. Two prompts, two reads, each
one trimmed and converted with strconv.Atoi. The first read
declares text with := and the second one
reuses it with =. Build the output with
fmt.Printf.
Worked solution.
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)
}Typing 3 and 4, the output is:
First number: 3
Second number: 4
3 + 4 = 7
Common mistakes.
- Skipping the conversion. The values stay strings, so
a + bjoins them instead of adding:"3" + "4"is"34", not7. - Skipping
strings.TrimSpace. Eachstrconv.Atoithen sees the line ending and gives0, so the output is0 + 0 = 0. - Writing
text, _ := reader.ReadString('\n')for the second read. Go stops withno new variables on left side of :=. - Writing
a := strconv.Atoi(...)with one name. Go stops withassignment mismatch: 1 variable but strconv.Atoi returns 2 values.
Problem 3 — Years to retirement
Problem. Compute 65 - age and print a
labelled sentence.
How to think about it. Prompt, read, trim, convert,
subtract, print. Mind the order: 65 - age, not
age - 65.
Worked solution.
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)
}Common mistakes.
- Doing
age - 65, which prints a negative for everyone under 65. Subtraction is not commutative — order matters. - Reading the result for bad input as an age. Typing
abcmakesage0, so the program saysYou have 65 years until retirement.and shows no sign that anything went wrong.
Challenge — BMI
Problem. Prompt for height and weight (decimals), compute BMI, print it to one decimal place.
How to think about it. Two prompts, two reads, both
through strconv.ParseFloat because the values have decimal
points. weight / (height * height) gives a float64;
%.1f shows one digit after the decimal point.
Worked solution.
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)
}Typing 1.78 and 72.5, the output is:
Height in metres (e.g. 1.78): 1.78
Weight in kg (e.g. 72.5): 72.5
BMI: 22.9
Common mistakes.
- Using
strconv.Atoiinstead ofstrconv.ParseFloat. Heights like1.78are not whole numbers, sostrconv.Atoigives0. Dividing an int by an int zero stops the program withpanic: runtime error: integer divide by zero. - Typing letters for the height.
strconv.ParseFloatgives0, and the BMI prints as+Inf, Go's way of showing a float64 divided by zero. - Forgetting the parentheses in
height * height. Without them,weight / height * heightruns left to right: divide by height, then multiply by it again — the heights cancel and you get weight back. - Entering height in centimetres (like
178) instead of metres (1.78). BMI uses metres, as the prompt says.
Done?
Every Part 3 chapter is done. The mini-project — the Character Sheet — uses everything from chapters 11 to 15.