From 7367827e4245e8bd738ca5668f8d075755a91858 Mon Sep 17 00:00:00 2001 From: Bart Bucknill Date: Fri, 15 Feb 2019 21:04:53 +0000 Subject: [PATCH 1/2] Solutions for part 1 and 2 --- students/bart/main.go | 93 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 students/bart/main.go diff --git a/students/bart/main.go b/students/bart/main.go new file mode 100644 index 0000000..438da1a --- /dev/null +++ b/students/bart/main.go @@ -0,0 +1,93 @@ +package main + +import ( + "bufio" + "encoding/csv" + "flag" + "fmt" + "io" + "log" + "os" + "time" +) + +func fatalError(message string, err error) { + if err != nil { + log.Fatalln(message, ":", err) + } +} + +type question struct { + question string + answer string +} + +type quiz struct { + answered int + answeredCorrectly int + questions []question +} + +// loadQuiz loads all questions into memory, assumed to be safe as +// the instructions state that the quiz will be < 100 questions +func loadQuiz(filePath string) *quiz { + csvFile, err := os.Open(filePath) + fatalError("Error opening quiz CSV file", err) + defer csvFile.Close() + reader := csv.NewReader(bufio.NewReader(csvFile)) + var quiz quiz + for { + line, err := reader.Read() + if err == io.EOF { + break + } + fatalError("Error parsing CSV", err) + question := question{line[0], line[1]} + quiz.questions = append(quiz.questions, question) + } + return &quiz +} + +// run prints questions, check answers, and records total +// answered and total correct +func (quiz *quiz) run() { + timer := time.NewTimer(time.Duration(*timeLimit) * time.Second) +quizLoop: + for _, question := range quiz.questions { + fmt.Println(question.question) + scanner.Scan() + answer := scanner.Text() + select { + case <-timer.C: + break quizLoop + default: + if answer == question.answer { + quiz.answeredCorrectly++ + } + quiz.answered++ + } + } + return +} + +// report prints summary of quiz performance +func (quiz *quiz) report() { + fmt.Printf( + "You answered %v questions out of a total of %v and got %v correct", + quiz.answered, + len(quiz.questions), + quiz.answeredCorrectly, + ) +} + +var ( + scanner = bufio.NewScanner(os.Stdin) + filePathPtr = flag.String("file", "../problems.csv", "Path to csv file containing quiz.") + timeLimit = flag.Int64("time-limit", 30, "Set the total time in seconds allowed for the quiz.") +) + +func main() { + quiz := loadQuiz(*filePathPtr) + quiz.run() + quiz.report() +} From 77ba9f0eab9157a0e0d9c695047c66df3cc57eb4 Mon Sep 17 00:00:00 2001 From: Bart Bucknill Date: Fri, 15 Feb 2019 21:23:26 +0000 Subject: [PATCH 2/2] Time limit to end quiz without waiting for next input --- students/bart/main.go | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/students/bart/main.go b/students/bart/main.go index 438da1a..4a20565 100644 --- a/students/bart/main.go +++ b/students/bart/main.go @@ -55,12 +55,16 @@ func (quiz *quiz) run() { quizLoop: for _, question := range quiz.questions { fmt.Println(question.question) - scanner.Scan() - answer := scanner.Text() + answerCh := make(chan string) + go func() { + scanner.Scan() + answer := scanner.Text() + answerCh <- answer + }() select { case <-timer.C: break quizLoop - default: + case answer := <-answerCh: if answer == question.answer { quiz.answeredCorrectly++ } @@ -82,7 +86,7 @@ func (quiz *quiz) report() { var ( scanner = bufio.NewScanner(os.Stdin) - filePathPtr = flag.String("file", "../problems.csv", "Path to csv file containing quiz.") + filePathPtr = flag.String("file", "./problems.csv", "Path to csv file containing quiz.") timeLimit = flag.Int64("time-limit", 30, "Set the total time in seconds allowed for the quiz.") )