Chapter 2 - Conditionals and Loops

Exercise 1: Calling Methods

The strings package has a Builder type that is used to build a long text string out of multiple shorter strings. A strings.Builder value has a variety of different methods you can call, but this exercise is going to focus on these three:

  • The WriteRune method accepts a rune as an argument and adds that rune onto the end of the string being built.
  • The WriteString method works just like WriteRune, except that it accepts a string as an argument.
  • The String method takes no arguments. Its return value is the accumulated string.

Complete the code sample below. The sample contains YOUR CODE HERE comments in the places you should add code, with a description of what your code should do.

package main

import (
	"fmt"
	"strings"
)

func main() {
	// The "builder" variable holds a "strings.Builder"
	// value. We're not assigning a value to "builder",
	// but that's okay; you can call methods on the
	// zero value for the "strings.Builder" type.
	var builder strings.Builder
	
	// YOUR CODE HERE: Call the "WriteRune" method on
	// "builder" 3 times, once with the rune 'a', once
	// with the rune 'b', and a third time with 'c'.
	
	// YOUR CODE HERE: Call the "WriteString" method on
	// "builder" once, with the string "defg".
	
	// YOUR CODE HERE: Call the "String" method on
	// "builder", and pass the return value to
	// "fmt.Println".
	
}

Output:

abcdefg

When you’re ready, have a look at the solution.

Exercise 2: if Statements

We’re writing a program that asks the user for a racer’s name and the position they finished the race in, and prints out what type of medal they should get.

Complete the code sample below. The final call to fmt.Println at the bottom includes a variable that you’ll need to declare and assign a value to. There are comments in the sample showing where to insert your code, and explaining what it should do.

Solution

package main

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

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

	fmt.Print("Enter racer name: ")
	name, err := reader.ReadString('\n')
	if err != nil {
		log.Fatal(err)
	}
	name = strings.TrimSpace(name)

	fmt.Print("Enter racer rank: ")
	input, err := reader.ReadString('\n')
	if err != nil {
		log.Fatal(err)
	}
	input = strings.TrimSpace(input)
	rank, err := strconv.ParseInt(input, 10, 64)
	if err != nil {
		log.Fatal(err)
	}

	// YOUR CODE HERE: Write some code that looks at the
	// "rank" variable and sets the "medal" variable to an
	// appropriate string. If "rank" is 1, "medal" should
	// be set to "gold". If "rank" is 2, "medal" should be
	// "silver". A rank of 3 should get a "bronze" medal,
	// and any other rank should get a "participant" medal.

	fmt.Println(name, "gets a", medal, "medal!")
}

Example output:

Enter racer name: Noam
Enter racer rank: 1
Noam gets a gold medal!

When you’re ready, have a look at the solution.

Exercise 3: for Loops

Here we have a program that’s meant to ask the user for a series of numbers and add them together, like this:

Enter a number: 1.1
Add more? [Y/n] y
Enter a number: 2.3
Add more? [Y/n]
Enter a number: 3.4
Add more? [Y/n] n
Sum is 6.8

But right now, the program only asks for a single number. It asks the user “Add more?”, but even if they respond “y”, the program ends and prints the total.

Enter a number: 12.5
Add more? [Y/n] y
Sum is 12.5

Your goal is to modify the program so that it keeps asking the user for as many additional numbers as they want. It should stop only when the user types “n” in response to the “Add more?” prompt. (Notice that the “Y” in “Y/n” is capitalized, indicating that it’s the default. If the user hits Enter without typing anything, or indeed if they enter anything at all besides “n”, the program should ask for another number to add.)

Hint: You’ll probably want to use a for loop with no init or post statements to solve this.

For your first attempt, just make the program stop if the user enters “n”. But then see if you can make the program stop if the user enters “n” or “N”!

package main

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

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

	var sum float64
	more := "y"

	fmt.Print("Enter a number: ")
	input, err := reader.ReadString('\n')
	if err != nil {
		log.Fatal(err)
	}
	input = strings.TrimSpace(input)
	number, err := strconv.ParseFloat(input, 64)
	if err != nil {
		log.Fatal(err)
	}

	sum += number

	fmt.Print("Add more? [Y/n] ")
	more, err = reader.ReadString('\n')
	if err != nil {
		log.Fatal(err)
	}
	more = strings.TrimSpace(more)

	fmt.Println("Sum is", sum)
}