mirror of
https://github.com/AmanTahiliani/gophercises.git
synced 2026-08-07 11:53:44 -04:00
121 lines
2.7 KiB
Go
121 lines
2.7 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/csv"
|
|
"flag"
|
|
"fmt"
|
|
"io"
|
|
"log"
|
|
"os"
|
|
"time"
|
|
|
|
quiz "github.com/gophercises/quiz/students/hackeryarn/myquiz"
|
|
"github.com/gophercises/quiz/students/hackeryarn/problem"
|
|
)
|
|
|
|
const (
|
|
// FileFlag is used to set a file for the questions
|
|
FileFlag = "file"
|
|
// FileFlagValue is the value used when no FileFlag is provided
|
|
FileFlagValue = "problems.csv"
|
|
// FileFlagUsage is the help string for the FileFlag
|
|
FileFlagUsage = "Questions file"
|
|
|
|
// TimerFlag is used for setting a timer for the quiz
|
|
TimerFlag = "timer"
|
|
// TimerFlagValue is the value used when no TimerFlag is provided
|
|
TimerFlagValue = 30
|
|
// TimerFlagUsage is the help string for the TimerFlag
|
|
TimerFlagUsage = "Amount of seconds the quiz will allow"
|
|
)
|
|
|
|
// Flagger configures the flags used
|
|
type Flagger interface {
|
|
StringVar(p *string, name, value, usage string)
|
|
IntVar(p *int, name string, value int, usage string)
|
|
}
|
|
|
|
type quizFlagger struct{}
|
|
|
|
func (q *quizFlagger) StringVar(p *string, name, value, usage string) {
|
|
flag.StringVar(p, name, value, usage)
|
|
}
|
|
|
|
func (q *quizFlagger) IntVar(p *int, name string, value int, usage string) {
|
|
flag.IntVar(p, name, value, usage)
|
|
}
|
|
|
|
// Timer is used to start a timer
|
|
type Timer interface {
|
|
NewTimer(d time.Duration) *time.Timer
|
|
}
|
|
|
|
type quizTimer struct{}
|
|
|
|
func (q quizTimer) NewTimer(d time.Duration) *time.Timer {
|
|
return time.NewTimer(d)
|
|
}
|
|
|
|
// ReadCSV parses the CSV file into a Problem struct
|
|
func ReadCSV(reader io.Reader) quiz.Quiz {
|
|
csvReader := csv.NewReader(reader)
|
|
|
|
problems := []problem.Problem{}
|
|
for {
|
|
record, err := csvReader.Read()
|
|
if err == io.EOF {
|
|
break
|
|
} else if err != nil {
|
|
log.Fatalln("Error reading CSV:", err)
|
|
}
|
|
|
|
problems = append(problems, problem.New(record))
|
|
}
|
|
|
|
return quiz.New(problems)
|
|
}
|
|
|
|
// TimerSeconds is the amount of time allowed for the quiz
|
|
var TimerSeconds int
|
|
var file string
|
|
|
|
// ConfigFlags sets all the flags used by the application
|
|
func ConfigFlags(f Flagger) {
|
|
f.StringVar(&file, FileFlag, FileFlagValue, FileFlagUsage)
|
|
f.IntVar(&TimerSeconds, TimerFlag, TimerFlagValue, TimerFlagUsage)
|
|
}
|
|
|
|
// StartTimer begins a timer once the user provides input
|
|
func StartTimer(w io.Writer, r io.Reader, timer Timer) *time.Timer {
|
|
fmt.Fprint(w, "Ready to start?")
|
|
fmt.Fscanln(r)
|
|
|
|
return timer.NewTimer(time.Second * time.Duration(TimerSeconds))
|
|
}
|
|
|
|
func init() {
|
|
flagger := &quizFlagger{}
|
|
ConfigFlags(flagger)
|
|
|
|
flag.Parse()
|
|
}
|
|
|
|
func main() {
|
|
file, err := os.Open(file)
|
|
if err != nil {
|
|
log.Fatalln("Could not open file", err)
|
|
}
|
|
|
|
quiz := ReadCSV(file)
|
|
|
|
timer := StartTimer(os.Stdout, os.Stdin, quizTimer{})
|
|
go func() {
|
|
<-timer.C
|
|
fmt.Println("")
|
|
quiz.PrintResults(os.Stdout)
|
|
os.Exit(0)
|
|
}()
|
|
|
|
quiz.Run(os.Stdout, os.Stdin)
|
|
}
|