17. Boolean logic in depth — Homework solutions
The .go solution files are in
exercises/17/homework/solutions/.
Problem 1 — Default colour
Problem. Fall back to "blue" when
fav is empty.
How to think about it. Start colour
with the value of fav. Replace it only when it is
"".
Worked solution.
package main
import "fmt"
func main() {
fav := "" // try a real colour too
colour := fav
if colour == "" {
colour = "blue"
}
fmt.Println("Your colour is " + colour)
}With fav := "" it prints:
Your colour is blue
With fav := "red" it prints:
Your colour is red
Common mistakes.
- Writing
colour := fav || "blue".||only works on bools, so Go stops with anoperator || not definederror. - Writing
if fav {. A string is not a bool. The test isfav == "". - Declaring
colourwith:=inside theif. It then disappears at the closing}, as Chapter 16 showed.
Problem 2 — Say what you mean
Problem. Show whether each value differs from its zero value.
How to think about it. The test depends on the type:
!= 0 for an int and != "" for a string. A bool
is already an answer, so isReady needs no comparison at
all.
Worked solution.
package main
import "fmt"
func main() {
count := 0
name := ""
isReady := false
greeting := "hi"
level := 1
fmt.Println(count, count != 0)
fmt.Printf("%q %v\n", name, name != "")
fmt.Println(isReady, isReady)
fmt.Printf("%q %v\n", greeting, greeting != "")
fmt.Println(level, level != 0)
}Output:
0 false
"" false
false false
"hi" true
1 true
Common mistakes.
- Writing
countby itself as the test. It prints the number, not a bool. - Comparing across types, like
name != 0. That is amismatched typeserror.
Problem 3 — Guarded division
Problem. Print the average only when it can be worked out and is over 20.
How to think about it. count > 0
goes first, so total/count never runs when
count is 0. The comparison uses whole number
division, which is good enough to test against 20. The printed average
needs decimals, so both numbers are converted to float64, as in Chapter
13.
Worked solution.
package main
import "fmt"
func main() {
total := 90
count := 0 // try 3 and 10 too
if count > 0 && total/count > 20 {
average := float64(total) / float64(count)
fmt.Printf("High average: %.2f\n", average)
} else {
fmt.Println("no high average")
}
}With count := 0, the count > 0 test is
false, so Go skips the division and prints:
no high average
With count := 3 it prints:
High average: 30.00
With count := 10, the average is 9, so it prints
no high average again.
Common mistakes.
- Writing
total/count > 20 && count > 0. The division now runs first, and withcountat0the program crashes withpanic: runtime error: integer divide by zero. - Printing
total / countwith%.2f. That is an int, so the output is%!f(int=30). Convert both numbers first.
Challenge — First value that exists
Problem. Print the first of a,
b, c that is not empty.
How to think about it. A switch with no
value runs the first case whose condition is true, and that is exactly
the question. default handles the case where all three are
empty.
Worked solution.
package main
import "fmt"
func main() {
a := ""
b := ""
c := "third"
switch {
case a != "":
fmt.Println(a)
case b != "":
fmt.Println(b)
case c != "":
fmt.Println(c)
default:
fmt.Println("none")
}
}Output:
third
Common mistakes.
- Using separate
ifstatements with noelse. Every non-empty variable then prints, not just the first. - Forgetting
default, so nothing prints when all three are empty.
Done?
You now know that && and || take
bools and give a bool, that they short-circuit, and that a default value
comes from an explicit comparison. Next is Loops, the
other way to make a program do more than the same thing each time.