mirror of
https://github.com/AmanTahiliani/gophercises.git
synced 2026-08-08 12:07:19 -04:00
132 lines
2.5 KiB
Go
132 lines
2.5 KiB
Go
|
|
package quiz
|
||
|
|
|
||
|
|
import (
|
||
|
|
"bufio"
|
||
|
|
"encoding/csv"
|
||
|
|
"flag"
|
||
|
|
"fmt"
|
||
|
|
"io"
|
||
|
|
"log"
|
||
|
|
"os"
|
||
|
|
"strings"
|
||
|
|
"time"
|
||
|
|
)
|
||
|
|
|
||
|
|
//Number of Questions to ask
|
||
|
|
const totalQuestions = 5
|
||
|
|
|
||
|
|
//Question struct that stores question with answer
|
||
|
|
type Question struct {
|
||
|
|
question string
|
||
|
|
answer string
|
||
|
|
}
|
||
|
|
|
||
|
|
func main() {
|
||
|
|
filename, timeLimit := readArguments()
|
||
|
|
f, err := openFile(filename)
|
||
|
|
if err != nil {
|
||
|
|
return
|
||
|
|
}
|
||
|
|
questions, err := readCSV(f)
|
||
|
|
|
||
|
|
if err != nil {
|
||
|
|
// err := fmt.Errorf("Error in Reading Questions")
|
||
|
|
fmt.Println(err.Error())
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
if questions == nil {
|
||
|
|
return
|
||
|
|
}
|
||
|
|
score, err := askQuestion(questions, timeLimit)
|
||
|
|
if err != nil {
|
||
|
|
fmt.Println(err)
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
fmt.Printf("Your Score %d/%d\n", score, totalQuestions)
|
||
|
|
}
|
||
|
|
|
||
|
|
func readArguments() (string, int) {
|
||
|
|
filename := flag.String("filename", "problem.csv", "CSV File that conatins quiz questions")
|
||
|
|
timeLimit := flag.Int("limit", 30, "Time Limit for each question")
|
||
|
|
flag.Parse()
|
||
|
|
return *filename, *timeLimit
|
||
|
|
}
|
||
|
|
|
||
|
|
func readCSV(f io.Reader) ([]Question, error) {
|
||
|
|
// defer f.Close() // this needs to be after the err check
|
||
|
|
allQuestions, err := csv.NewReader(f).ReadAll()
|
||
|
|
if err != nil {
|
||
|
|
return nil, err
|
||
|
|
}
|
||
|
|
|
||
|
|
numOfQues := len(allQuestions)
|
||
|
|
if numOfQues == 0 {
|
||
|
|
return nil, fmt.Errorf("No Question in file")
|
||
|
|
}
|
||
|
|
|
||
|
|
var data []Question
|
||
|
|
for _, line := range allQuestions {
|
||
|
|
ques := Question{}
|
||
|
|
ques.question = line[0]
|
||
|
|
ques.answer = line[1]
|
||
|
|
data = append(data, ques)
|
||
|
|
}
|
||
|
|
|
||
|
|
return data, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func openFile(filename string) (io.Reader, error) {
|
||
|
|
return os.Open(filename)
|
||
|
|
}
|
||
|
|
func getInput(input chan string) {
|
||
|
|
for {
|
||
|
|
in := bufio.NewReader(os.Stdin)
|
||
|
|
result, err := in.ReadString('\n')
|
||
|
|
if err != nil {
|
||
|
|
log.Fatal(err)
|
||
|
|
}
|
||
|
|
|
||
|
|
input <- result
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func askQuestion(questions []Question, timeLimit int) (int, error) {
|
||
|
|
totalScore := 0
|
||
|
|
timer := time.NewTimer(time.Duration(timeLimit) * time.Second)
|
||
|
|
done := make(chan string)
|
||
|
|
|
||
|
|
go getInput(done)
|
||
|
|
|
||
|
|
for i := range [totalQuestions]int{} {
|
||
|
|
ans, err := eachQuestion(questions[i].question, questions[i].answer, timer.C, done)
|
||
|
|
if err != nil && ans == -1 {
|
||
|
|
return totalScore, nil
|
||
|
|
}
|
||
|
|
totalScore += ans
|
||
|
|
|
||
|
|
}
|
||
|
|
return totalScore, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func eachQuestion(Quest string, answer string, timer <-chan time.Time, done <-chan string) (int, error) {
|
||
|
|
fmt.Printf("%s: ", Quest)
|
||
|
|
|
||
|
|
for {
|
||
|
|
select {
|
||
|
|
case <-timer:
|
||
|
|
return -1, fmt.Errorf("Time out")
|
||
|
|
case ans := <-done:
|
||
|
|
score := 0
|
||
|
|
if strings.Compare(strings.Trim(strings.ToLower(ans), "\n"), answer) == 0 {
|
||
|
|
score = 1
|
||
|
|
} else {
|
||
|
|
return 0, fmt.Errorf("Wrong Answer")
|
||
|
|
}
|
||
|
|
|
||
|
|
return score, nil
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|