golang实现批量生成数学加减法练习题
背景
家里的娃儿处于幼升小阶段,作为即将步入鸡娃家长行列中的一员,自然少不了催着娃儿去学习数学加减法了,以前都是在家里手写题目让孩子做,但费事费劲,如果哪天忘了布置作业,娃就不做了,甩锅是我们没布置作业!所以就想来个偷懒的做法,使用程序自动生成题目,让她在家有做不完的题。这个算是技术为孩子幼升小赋能么?
以MVP的产品思路来快速迭代该程序,简单规划了下,分成如下三个阶段来完成:
第一阶段:实现程序快速自动生成题目,支持简单规则设定,并能输出为word文档(采用打印纸张的方式)【能用就行的阶段:主要解决布置题目的痛点,但需要人工参与打印题目】
第二阶段:实现IPad程序,支持在IPad上做题,并且能自动校验答案,形成每天必打卡的机制【自动化的阶段:实现智能判题,并且节省纸张成本】
第三阶段:针对每天打卡进行耗时时间、错题率统计,通过数据分析孩子成绩进度的情况以及找出薄弱的点后期进行有针对的练习【成长阶段:通过数据分析来辅助成绩的提升,形成闭环】
参考代码
废话不说了,今天开工的,完成了生成题目的代码,支持设定多少以内加减法,支持设置算式里的最小数,支持指定题目的数量,下面是实现代码:
package expression
import (
"fmt"
"math"
"math/rand"
"time"
)
// OperatorType ...
type OperatorType int32
// Operator define
const (
OperatorAdd OperatorType = 0
OperatorSub OperatorType = 1
)
// operator string
var operatorMap = map[OperatorType]string{
OperatorAdd: "+",
OperatorSub: "-",
}
func (o OperatorType) String() string {
return operatorMap[o]
}
// Expression ...
type Expression struct {
NumberA int
NumberB int
Operator OperatorType
}
func maxInt(a, b int) int {
if a > b {
return a
}
return b
}
func gap(max, number int, operator OperatorType) int {
switch operator {
case OperatorAdd:
return maxInt(max-number, 2)
case OperatorSub:
return max
default:
return max
}
}
// Generate ...
func Generate(max, min, count int) (list []Expression) {
rand.Seed(time.Now().Unix())
maps := make(map[string]Expression)
for {
a := rand.Intn(max)
o := OperatorType(rand.Intn(2))
t := gap(max, a, o)
b := rand.Intn(t)
if (o == OperatorSub && b > a) || (a < min || b < min) {
continue
}
key := fmt.Sprintf("%d.%d.%d", a, 0, b)
if _, ok := maps[key]; !ok {
exp := Expression{
NumberA: a,
Operator: o,
NumberB: b,
}
maps[key] = exp
list = append(list, exp)
}
if len(list) >= count {
break
}
}
return
}
// Result calc result
func Result(exp Expression) int {
switch exp.Operator {
case OperatorAdd:
return exp.NumberA + exp.NumberB
case OperatorSub:
return exp.NumberA - exp.NumberB
default:
return math.MinInt32
}
}调用Demo:
package main
import (
"fmt"
"prodigy/expression"
)
func main() {
list := expression.Generate(20, 5, 30)
for _, v := range list {
fmt.Println(fmt.Sprintf("%d %s %d = %d", v.NumberA, v.Operator.String(), v.NumberB, expression.Result(v)))
}
}运行效果如下:
