Skip to content

Commit bfa1343

Browse files
committedJul 24, 2020
Atharva Thorve | Command line quiz app using go
1 parent 25c0b9b commit bfa1343

File tree

3 files changed

+121
-0
lines changed

3 files changed

+121
-0
lines changed
 

‎CMD Quiz App/README.md

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# CMD Quiz App
2+
A simple quiz app on command line interface using golang
3+
4+
# Packages used
5+
- encoding/csv
6+
- flag
7+
- fmt
8+
- os
9+
- strings
10+
- time
11+
12+
# How to use the app
13+
Execute the `main.go` file using the `go run main.go` command.<br>
14+
By default the questions are provided from `problems.csv` file but the user can provide their own questions using the `--csv` flag then path to the file.<br>
15+
The user is given 30 seconds to complete the exercise but that time limit can also be changed by providing the `--limit` flag then the time limit of the test.<br>
16+
At the end of the test the user is shown the answers given, whether they were correct or not and the correct answer and the number of correct answers and the time taken by the user to complete the whole test.<br>
17+
User can use `-h` flag to know more about the flags in the program
18+
19+
# Working
20+
- `flag` package is used to handle inputs from flags provided by the user.
21+
- `encoding/csv` package is used to read and parse csv files
22+
- `time` package and `channels` are used to maintain proper handling of time limits of the quiz

‎CMD Quiz App/src/main.go

+87
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
package main
2+
3+
import (
4+
"encoding/csv"
5+
"flag"
6+
"fmt"
7+
"os"
8+
"strings"
9+
"time"
10+
)
11+
12+
type problem struct {
13+
question string
14+
answer string
15+
userAnswer string
16+
isCorrect bool
17+
}
18+
19+
func main() {
20+
csvFileName := flag.String("csv", "problems.csv", "A csv file of format 'question,answer'")
21+
timeLimit := flag.Int("limit", 30, "The time limit of quiz in seconds")
22+
flag.Parse()
23+
24+
file, err := os.Open(*csvFileName)
25+
if err != nil {
26+
exit(fmt.Sprintf("Could not open file %s\n", *csvFileName))
27+
}
28+
r := csv.NewReader(file)
29+
lines, err := r.ReadAll()
30+
if err != nil {
31+
exit("Failed to parse the CSV file")
32+
}
33+
problems := parseLines(lines)
34+
35+
timer := time.NewTimer(time.Duration((*timeLimit)) * time.Second)
36+
start := time.Now()
37+
38+
correctCount := 0
39+
problemloop:
40+
for i := 0; i < len(problems); i++ {
41+
fmt.Printf("Problem #%d: %s = ", i+1, problems[i].question)
42+
ansChan := make(chan string)
43+
go func() {
44+
var answer string
45+
fmt.Scanf("%s\n", &answer)
46+
problems[i].userAnswer = answer
47+
ansChan <- answer
48+
}()
49+
50+
select {
51+
case <-timer.C:
52+
fmt.Println()
53+
break problemloop
54+
case answer := <-ansChan:
55+
if answer == problems[i].answer {
56+
problems[i].isCorrect = true
57+
correctCount++
58+
}
59+
}
60+
}
61+
timer.Stop()
62+
for i, prob := range problems {
63+
check := "\u274C"
64+
if prob.isCorrect {
65+
check = "\u2705"
66+
}
67+
fmt.Printf("Problem #%d: %s = %s %s %s\n", i+1, prob.question, prob.userAnswer, string(check), prob.answer)
68+
}
69+
70+
fmt.Printf("You scored %d out of %d in time %f seconds.\n", correctCount, len(problems), time.Since(start).Seconds())
71+
}
72+
73+
func parseLines(lines [][]string) []problem {
74+
ret := make([]problem, len(lines))
75+
for i, line := range lines {
76+
ret[i] = problem{
77+
question: line[0],
78+
answer: strings.TrimSpace(line[1]),
79+
}
80+
}
81+
return ret
82+
}
83+
84+
func exit(msg string) {
85+
fmt.Println(msg)
86+
os.Exit(1)
87+
}

‎CMD Quiz App/src/problems.csv

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
5+5,10
2+
1+1,2
3+
8+3,11
4+
1+2,3
5+
8+6,14
6+
3+1,4
7+
1+4,5
8+
5+1,6
9+
2+3,5
10+
3+3,6
11+
2+4,6
12+
5+2,7

0 commit comments

Comments
 (0)
Please sign in to comment.