Skip to content

Commit

Permalink
Added dimdiden solution (gophercises#38)
Browse files Browse the repository at this point in the history
  • Loading branch information
dimdiden authored and joncalhoun committed Jul 22, 2019
1 parent 14e3609 commit 024f75b
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 0 deletions.
13 changes: 13 additions & 0 deletions students/dimdiden/problems.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
5+5,10
7+3,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
87 changes: 87 additions & 0 deletions students/dimdiden/quiz.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package main

import (
"bufio"
"encoding/csv"
"errors"
"flag"
"fmt"
"io"
"log"
"os"
"strings"
"time"
)

// DEFAULTFILE is the quiz file expected to be load by default
const DEFAULTFILE = "problems.csv"

func main() {
// Flag block
file := flag.String("f", DEFAULTFILE, "specify the path to file")
timeout := flag.Int("t", 0, "specify the number of seconds for timeout")
flag.Parse()
// Failed if the number of seconds is negative
if *timeout < 0 {
flag.PrintDefaults()
os.Exit(1)
}
// Open file
f, err := os.Open(*file)
if err != nil {
log.Fatal(err)
}
defer f.Close()
// Run the main logic
total, correct, err := run(f, *timeout)
if err != nil {
log.Println(err)
}
fmt.Printf("Number of questions: %v\nNumber of correct answers: %v\n", total, correct)
}

// run is the main function to execute quiz app
func run(qinput io.Reader, timeout int) (total, correct int, err error) {
// Reading csv file and parse it to the records var
r := csv.NewReader(qinput)
records, err := r.ReadAll()
if err != nil {
return total, correct, err
}
// Two channels. One for answers, another for timeout
answerChan := make(chan string)
timerChan := make(chan time.Time, 1)
// Iterate over the records
for _, record := range records {
question, expected := record[0], record[1]
fmt.Printf("Question: %v. Answer: ", question)
total++
// Listening for input in the separate goroutine
go getAnswer(answerChan)
// Run the timer in separate goroutine if the timeout is specified
if timeout > 0 {
go func() { timerChan <- <-time.After(time.Duration(timeout) * time.Second) }()
}
// Main select block
select {
case answer := <-answerChan:
if answer == expected {
correct++
}
case <-timerChan:
fmt.Println()
return total, correct, errors.New("Timeout reached!")
}
}
return total, correct, nil
}

// getAnswer func is for listening input from user
func getAnswer(answerChan chan string) {
reader := bufio.NewReader(os.Stdin)
answer, err := reader.ReadString('\n')
if err != nil {
log.Fatal(err)
}
answerChan <- strings.Replace(answer, "\n", "", -1)
}

0 comments on commit 024f75b

Please sign in to comment.