14. Working with text — Homework solutions

The .go solution files are in exercises/14/homework/solutions/.

Problem 1 — Loud and quiet

Problem. Print a name three times: original, upper, lower.

How to think about it. You need two functions from strings: ToUpper and ToLower. Neither changes the original variable, so all three prints use the same name.

Worked solution.

package main

import (
    "fmt"
    "strings"
)

func main() {
    name := "Keiko"

    fmt.Println(name)
    fmt.Println(strings.ToUpper(name))
    fmt.Println(strings.ToLower(name))
}

Output:

Keiko
KEIKO
keiko

Common mistakes.

  • Writing name = strings.ToUpper(name) between prints. That overwrites the original value, so a later print uses the changed text instead of "Keiko". Keep the original untouched and only transform it inside each print call.
  • Calling strings.ToUpper(name) on a line by itself. It compiles, but the new string is thrown away.

Problem 2 — Contains

Problem. Print whether a sentence holds go, and whether it holds cake.

How to think about it. strings.Contains gives true when the piece of text is found. fmt.Println can print a bool directly.

Worked solution.

package main

import (
    "fmt"
    "strings"
)

func main() {
    sentence := "i am learning go this year"

    fmt.Println(strings.Contains(sentence, "go"))
    fmt.Println(strings.Contains(sentence, "cake"))
}

Output:

true
false

Chapter 16 uses a bool like this one to choose what the program does next.

Common mistakes.

  • Swapping the arguments. strings.Contains("go", sentence) asks whether "go" contains the whole sentence, which is false. The string to search comes first.
  • Assuming it looks for whole words. strings.Contains("dragon", "go") is true, because those letters are in the word.

Problem 3 — Censor

Problem. Replace every space with a dash.

Worked solution.

package main

import (
    "fmt"
    "strings"
)

func main() {
    message := "meet me at noon"

    dashed := strings.ReplaceAll(message, " ", "-")
    fmt.Println(dashed)
}

Output:

meet-me-at-noon

Common mistakes.

  • Expecting strings.ReplaceAll to change message. Strings in Go cannot be changed; the function gives a new string. Store the result in a variable to use it.

Challenge — Title block

Problem. Print a title with a dashed border above and below. The border length is computed from the title length, not typed out.

How to think about it. The middle row is the title with -- before it and -- after it, which adds six characters. So the border has to be len(title)+6 characters long. Build a row of dashes that length with strings.Repeat, and build the middle row with fmt.Sprintf.

Worked solution.

package main

import (
    "fmt"
    "strings"
)

func main() {
    title := "INVENTORY"

    border := strings.Repeat("-", len(title)+6)
    middle := fmt.Sprintf("-- %s --", title)

    fmt.Println(border)
    fmt.Println(middle)
    fmt.Println("Inside text goes here")
    fmt.Println(middle)
    fmt.Println(border)
}

The output for title := "INVENTORY":

---------------
-- INVENTORY --
Inside text goes here
-- INVENTORY --
---------------

Change title to "SHOP" and the border shrinks. That is why you use len(title) instead of counting dashes by hand.

Common mistakes.

  • Hard-coding the number of dashes. The challenge is to compute the length from len(title).
  • Writing strings.Repeat("-", len(title)) + 6, with the + 6 outside the parentheses. That adds the number 6 to a string, which is a mismatched types error.
  • Using a title with accented letters. len counts bytes, so the border comes out too long. Chapter 12 explains why.

Done?

You can now search, replace, format, and convert text. Part 3's last chapter — Getting input — lets users type values, arriving as strings to trim and convert.