Different solution for Gophercise 1

This commit is contained in:
2025-05-31 13:14:20 -04:00
parent b22ab92d79
commit 1da6e395bf
56 changed files with 3374 additions and 0 deletions

View File

@@ -0,0 +1,13 @@
5+5,10
7+3,10
1+1,2
8+3,11
1+2,3
8+6,14
3+1,4
1+4,5
5+1,6
2+3,5
3+3,6
2+4,6
5+2,7
1 5+5 10
2 7+3 10
3 1+1 2
4 8+3 11
5 1+2 3
6 8+6 14
7 3+1 4
8 1+4 5
9 5+1 6
10 2+3 5
11 3+3 6
12 2+4 6
13 5+2 7

View File

@@ -0,0 +1,131 @@
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
}
}
}

View File

@@ -0,0 +1,59 @@
package quiz
import (
"strings"
"testing"
"time"
"gotest.tools/assert"
)
func testEachQuestion(t *testing.T) {
timer := time.NewTimer(time.Duration(2) * time.Second).C
done := make(chan string)
var quest Question
quest.question = "1+1"
quest.answer = "2"
var ans int
var err error
allDone := make(chan bool)
go func() {
ans, err = eachQuestion(quest.question, quest.answer, timer, done)
allDone <- true
}()
done <- "2"
<-allDone
if err != nil {
t.Error(err)
}
assert.Equal(t, ans, 1)
}
func testReadCSV(t *testing.T) {
str := "1+1,2\n2+1,3\n9+9,18\n"
quest, err := readCSV(strings.NewReader(str))
if err != nil {
t.Error(err)
}
var que [3]Question
que[0].answer = "2"
que[1].answer = "3"
que[2].answer = "18"
que[0].question = "1+1"
que[1].question = "2+1"
que[2].question = "9+9"
assert.Equal(t, que[0], quest[0])
assert.Equal(t, que[1], quest[1])
assert.Equal(t, que[2], quest[2])
}
func TestEachQuestion(t *testing.T) {
t.Run("test eachQuestion", testEachQuestion)
}
func TestReadCSV(t *testing.T) {
t.Run("test ReadCSV", testReadCSV)
}