Skip to content

Commit 024f75b

Browse files
dimdidenjoncalhoun
authored andcommitted
Added dimdiden solution (#38)
1 parent 14e3609 commit 024f75b

File tree

2 files changed

+100
-0
lines changed

2 files changed

+100
-0
lines changed

students/dimdiden/problems.csv

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
5+5,10
2+
7+3,10
3+
1+1,2
4+
8+3,11
5+
1+2,3
6+
8+6,14
7+
3+1,4
8+
1+4,5
9+
5+1,6
10+
2+3,5
11+
3+3,6
12+
2+4,6
13+
5+2,7

students/dimdiden/quiz.go

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
package main
2+
3+
import (
4+
"bufio"
5+
"encoding/csv"
6+
"errors"
7+
"flag"
8+
"fmt"
9+
"io"
10+
"log"
11+
"os"
12+
"strings"
13+
"time"
14+
)
15+
16+
// DEFAULTFILE is the quiz file expected to be load by default
17+
const DEFAULTFILE = "problems.csv"
18+
19+
func main() {
20+
// Flag block
21+
file := flag.String("f", DEFAULTFILE, "specify the path to file")
22+
timeout := flag.Int("t", 0, "specify the number of seconds for timeout")
23+
flag.Parse()
24+
// Failed if the number of seconds is negative
25+
if *timeout < 0 {
26+
flag.PrintDefaults()
27+
os.Exit(1)
28+
}
29+
// Open file
30+
f, err := os.Open(*file)
31+
if err != nil {
32+
log.Fatal(err)
33+
}
34+
defer f.Close()
35+
// Run the main logic
36+
total, correct, err := run(f, *timeout)
37+
if err != nil {
38+
log.Println(err)
39+
}
40+
fmt.Printf("Number of questions: %v\nNumber of correct answers: %v\n", total, correct)
41+
}
42+
43+
// run is the main function to execute quiz app
44+
func run(qinput io.Reader, timeout int) (total, correct int, err error) {
45+
// Reading csv file and parse it to the records var
46+
r := csv.NewReader(qinput)
47+
records, err := r.ReadAll()
48+
if err != nil {
49+
return total, correct, err
50+
}
51+
// Two channels. One for answers, another for timeout
52+
answerChan := make(chan string)
53+
timerChan := make(chan time.Time, 1)
54+
// Iterate over the records
55+
for _, record := range records {
56+
question, expected := record[0], record[1]
57+
fmt.Printf("Question: %v. Answer: ", question)
58+
total++
59+
// Listening for input in the separate goroutine
60+
go getAnswer(answerChan)
61+
// Run the timer in separate goroutine if the timeout is specified
62+
if timeout > 0 {
63+
go func() { timerChan <- <-time.After(time.Duration(timeout) * time.Second) }()
64+
}
65+
// Main select block
66+
select {
67+
case answer := <-answerChan:
68+
if answer == expected {
69+
correct++
70+
}
71+
case <-timerChan:
72+
fmt.Println()
73+
return total, correct, errors.New("Timeout reached!")
74+
}
75+
}
76+
return total, correct, nil
77+
}
78+
79+
// getAnswer func is for listening input from user
80+
func getAnswer(answerChan chan string) {
81+
reader := bufio.NewReader(os.Stdin)
82+
answer, err := reader.ReadString('\n')
83+
if err != nil {
84+
log.Fatal(err)
85+
}
86+
answerChan <- strings.Replace(answer, "\n", "", -1)
87+
}

0 commit comments

Comments
 (0)