forked from gophercises/quiz
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
105 lines (92 loc) · 2.05 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package main
import (
"bufio"
"encoding/csv"
"flag"
"fmt"
"log"
"os"
"path/filepath"
"strconv"
"time"
)
var defaultCSV = "problems.csv"
var csvFilename = flag.String("f", defaultCSV, "csv file in the format of 'problem, correct answer'")
var timeLimit = flag.Int("t", 30, "the time limit for a quiz in seconds")
// Problems is a type describing a collection of all questions to solve in a single round.
type Problems = []problem
func main() {
flag.Parse()
var appPath string
if *csvFilename == defaultCSV {
appPath = filepath.Dir(os.Args[0])
}
file, err := os.Open(filepath.Join(appPath, *csvFilename))
if err != nil {
log.Fatalf("Failed to open a CSV file: %s\n", *csvFilename)
}
defer func() {
if err = file.Close(); err != nil {
log.Fatal(err)
}
}()
csv := csv.NewReader(file)
records, err := csv.ReadAll()
if err != nil {
log.Printf("Could not parse CSV file: %v\n", err)
}
problems := questionsPool(records)
scan := bufio.NewScanner(os.Stdin)
answers := make([]int, len(problems))
resp := make(chan int)
timeout := time.Tick(time.Duration(*timeLimit) * time.Second)
quizloop:
for i, p := range problems {
fmt.Printf("Question #%d: %s\n", i+1, p.q)
go func(<-chan int) {
scan.Scan()
if scan.Err() != nil {
log.Fatal("scanner internal error")
}
ans := scan.Text()
value, err := strconv.Atoi(ans)
if err != nil {
log.Println(err)
}
resp <- value
}(resp)
select {
case ans := <-resp:
answers[i] = ans
case <-timeout:
fmt.Println("Time ran out, sorry!")
break quizloop
}
}
var score int
for i, a := range answers {
problem := problems[i]
if a == problem.ans {
score++
}
}
fmt.Printf("You scored: %d out of %d\n", score, len(problems))
}
type problem struct {
q string
ans int
}
func questionsPool(r [][]string) Problems {
quiz := make(Problems, len(r))
for i, v := range r {
var p problem
p.q = v[0]
num, err := strconv.Atoi(v[1])
if err != nil {
log.Fatalln("CSV answer field is not convertable to integer")
}
p.ans = num
quiz[i] = p
}
return quiz
}