mirror of
https://github.com/AmanTahiliani/gophercises.git
synced 2026-08-08 04:06:16 -04:00
Different solution for Gophercise 1
This commit is contained in:
141
1. Quiz Game Sol2/students/latentgenius/quiz.go
Normal file
141
1. Quiz Game Sol2/students/latentgenius/quiz.go
Normal file
@@ -0,0 +1,141 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"encoding/csv"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"math/rand"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
flagFilePath string
|
||||
flagRandom bool
|
||||
flagTime int
|
||||
wg sync.WaitGroup
|
||||
)
|
||||
|
||||
func init() {
|
||||
flag.StringVar(&flagFilePath, "file", "questions.csv", "path/to/csv_file")
|
||||
flag.BoolVar(&flagRandom, "random", true, "randomize order of questions")
|
||||
flag.IntVar(&flagTime, "time", 10, "test duration")
|
||||
flag.Parse()
|
||||
}
|
||||
|
||||
func main() {
|
||||
// this program will progress as follows
|
||||
// read a csv filepath and a time limit from flags
|
||||
// prompt for a key press
|
||||
// on key press, start the quiz as follows
|
||||
//
|
||||
// while time has not elapsed:
|
||||
// print a random question to the screen
|
||||
// prompt the user for an answer
|
||||
// store the answer in a container
|
||||
// normalize answers so they compare correctly
|
||||
// output total questions answered correctly and how many questions there
|
||||
// were.
|
||||
|
||||
csvPath, err := filepath.Abs(flagFilePath)
|
||||
if err != nil {
|
||||
log.Fatalln("Unable to parse path" + csvPath)
|
||||
}
|
||||
file, err := os.Open(csvPath)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
csvReader := csv.NewReader(file)
|
||||
csvData, err := csvReader.ReadAll()
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
var totalQuestions = len(csvData)
|
||||
questions := make(map[int]string, totalQuestions)
|
||||
answers := make(map[int]string, totalQuestions)
|
||||
responses := make(map[int]string, totalQuestions)
|
||||
|
||||
for i, data := range csvData {
|
||||
questions[i] = data[0]
|
||||
answers[i] = data[1]
|
||||
}
|
||||
|
||||
respondTo := make(chan string)
|
||||
|
||||
// block until user presses enter
|
||||
fmt.Println("Press [Enter] to start test.")
|
||||
bufio.NewScanner(os.Stdout).Scan()
|
||||
if flagRandom {
|
||||
// seed the random number generator with the current time
|
||||
rand.Seed(time.Now().UTC().UnixNano())
|
||||
}
|
||||
// randPool should contain random indexes into the questions map
|
||||
randPool := rand.Perm(totalQuestions)
|
||||
|
||||
wg.Add(1)
|
||||
timeUp := time.After(time.Second * time.Duration(flagTime))
|
||||
go func() {
|
||||
label:
|
||||
for i := 0; i < totalQuestions; i++ {
|
||||
index := randPool[i]
|
||||
go askQuestion(os.Stdout, os.Stdin, questions[index], respondTo)
|
||||
select {
|
||||
case <-timeUp:
|
||||
fmt.Fprintln(os.Stderr, "\nTime up!")
|
||||
break label
|
||||
case ans, ok := <-respondTo:
|
||||
if ok {
|
||||
responses[index] = ans
|
||||
} else {
|
||||
break label
|
||||
}
|
||||
}
|
||||
}
|
||||
wg.Done()
|
||||
}()
|
||||
wg.Wait()
|
||||
|
||||
correct := 0
|
||||
for i := 0; i < totalQuestions; i++ {
|
||||
if checkAnswer(answers[i], responses[i]) {
|
||||
correct++
|
||||
}
|
||||
}
|
||||
summary(correct, totalQuestions)
|
||||
}
|
||||
|
||||
func askQuestion(w io.Writer, r io.Reader, question string, replyTo chan string) {
|
||||
reader := bufio.NewReader(r)
|
||||
fmt.Fprintln(w, "Question: "+question)
|
||||
fmt.Fprint(w, "Answer: ")
|
||||
answer, err := reader.ReadString('\n')
|
||||
if err != nil {
|
||||
close(replyTo)
|
||||
if err == io.EOF {
|
||||
return
|
||||
}
|
||||
log.Fatalln(err)
|
||||
}
|
||||
replyTo <- answer
|
||||
}
|
||||
|
||||
func checkAnswer(ans string, expected string) bool {
|
||||
if strings.EqualFold(strings.TrimSpace(ans), strings.TrimSpace(expected)) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func summary(correct, totalQuestions int) {
|
||||
fmt.Fprintf(os.Stdout, "You answered %d questions correctly (%d / %d)\n", correct,
|
||||
correct, totalQuestions)
|
||||
}
|
||||
Reference in New Issue
Block a user