I just started golang development about two weeks ago and recently finished the recommended introduction book.
I'm now working my way through Gophercises - a sort of collection of exercises to improve beginner's understanding of Golang through small projects.
This is my solution to the first project: writing a quiz (cli-)application.
The requirements are simple:
Read a csv file, each line consisting of a question and an answer:
5+5,10 1+1,2 8+3,11 1+2,3 8+6,14 3+1,4 1+4,5 5+1,6 2+3,5 3+3,6 2+4,6 5+2,7
Print the question to the user
Validate if the supplied answer is correct.
Print the correct answers.
Here is my solution to the problem:
package main
import (
"bufio"
"encoding/csv"
"flag"
"fmt"
"io"
"log"
"os"
)
type q struct {
question, answer string
}
func (q q) ask() bool {
fmt.Println(q.question, " equals: ")
scanner := bufio.NewScanner(os.Stdin)
scanner.Scan()
if scanner.Err() != nil {
log.Fatal(scanner.Err())
}
if scanner.Text() == q.answer {
return true
}
return false
}
func quizLoop(path string, verbose bool) {
// Loop should:
// 1. Read records line by line
// 2. Ask the question (i/o)
// 3. Keep score.
file, err := os.Open(path)
correct, lines := 0, 0
if err != nil {
log.Fatal(err)
}
defer file.Close()
reader := csv.NewReader(file)
for {
record, err := reader.Read()
if err != nil {
if err == io.EOF {
break
}
log.Fatal(err)
}
q := q{question: record[0], answer: record[1]}
if q.ask() {
if verbose {
fmt.Println("Correct")
}
correct++
} else if verbose {
fmt.Println("Incorrect")
}
lines++
}
fmt.Printf("You had %d/%d correct answers!\n", correct, lines)
}
func main() {
// Setup flags.
p := flag.String("path", "problems.csv", "Specify the path to the quiz questions.")
v := flag.Bool("verbose", false, "A boolean value to check if you want the program to be verbose or not.")
flag.Parse()
// Invoke loop.
quizLoop(*p, *v)
}
As mentioned in my introduction I am rather new to the language, and couldn't see any caveats where it could have been beneficial to use things like interfaces or go routines in this particular project.
These are the things I'm the most interested in having reviewed:
- Best Practices
- Refactoring
- How to use more advanced functionality to solve it (ie. go routines or interfaces)
- Adding unit tests to it. What can be tested?
- Overall design