问题描述
在命令行界面,给出12道数学加法算数题(这12道数学题目来自于problems.csv这个文件),最后12道题目做完,能够给出最后最终的得分,实验最终实现的效果如下图。
![](https://img.haomeiwen.com/i3072403/17a4171d22b4dab7.png)
关键技能点
csv文件读取,命令行参数解析,字典
该项目下有两个文件
![](https://img.haomeiwen.com/i3072403/25a8eaf9dc4a500f.png)
在main.go文件中,全部的实现代码如下
package main
import (
"bufio"
"encoding/csv"
"flag"
"fmt"
"log"
"os"
"strings"
"time"
)
var (
//加一个定时,如果30秒内没有答题,就报告超时
//关于flag的用法详见 http://www.cppblog.com/kenkao/archive/2017/06/21/215013.html
// set flags
csvPath = flag.String("csv", "problems.csv", "a csv file in the format of 'question,answer'")
limit = flag.Int("limit", 30, "the time limit for the quiz in seconds'")
)
func main() {
//通过调用flag.Parse()来进行对命令行参数的解析
// parse the flags
flag.Parse()
// open the csv file
file, err := os.Open(*csvPath)
if err != nil {
log.Println(err)
return
}
defer file.Close()
// open the csv file
csvReader := csv.NewReader(file)
// parse the csv file
csvData, err := csvReader.ReadAll()
if err != nil {
log.Println(err)
return
}
// put question/answer pairs into a map where questions are keys and answers are values
//map这里会把读取的东西转换为字典,for循环中_这里替换的是key,也就是序号1234
qaPair := make(map[string]string, len(csvData))
for _, data := range csvData {
qaPair[data[0]] = data[1]
}
// create a ticker for the time limit and a channel to signal the user finished the quiz
ticker := time.NewTicker(time.Second * time.Duration(*limit))
done := make(chan bool)
// create a scanner for user input
scanner := bufio.NewScanner(os.Stdin)
var userAnswer string
qNum, numCorrect := 0, 0
go func() {
// iteration order for maps in go is randomized so the questions won't be in the same order every time
for question, answer := range qaPair {
qNum++
// ask a question
fmt.Printf("Problem #%d: %s = ", qNum, question)
// get an answer
scanner.Scan()
userAnswer = scanner.Text()
// trim leading and trailing whitespace
//TrimSpace的作用就是去除空格等符号
userAnswer = strings.TrimSpace(userAnswer)
userAnswer = strings.ToLower(userAnswer)
answer = strings.ToLower(answer)
// check the answer
if answer == userAnswer {
numCorrect++
}
}
done <- true
}()
// select chooses the first channel with an available value
// if done is available first, the user finished
// if ticker is available first, the time limit has been reached
select {
case <-done:
case <-ticker.C:
fmt.Println("time's up!")
}
// print the results
fmt.Printf("You scored %d out of %d.\n", numCorrect, len(qaPair))
}
参考链接:
Quiz Game
网友评论