python生成小学数学练习题

小学生的计算能力比较差,错误率高,防不胜防。

好好一道应用题,到最后就计算错误引起前功尽弃,确实很可惜。

我用python3写了一个程序,可以生成2位小数的方程和加减法练习题。

能生成的效果如下:

  • 30以内,3个数字,加减法

20 - 16 => 4

11 - 9 => 2

10 + 12 => 22

 

  • 100以内,3个数字,加法

4 + 47 => 51

114 - 8 => 106

77 + 15 => 92

 

  • 0-9乘法

9 * 9 => 81

3 * 9 => 27

5 * 3 => 15

 

  • 3位小数乘除法

90.25 * 19.76 => 1783.34

51.71 * 5.87 => 303.538

0.81 * 15.94 => 12.911

 

  • 3位小数二元一次方程  五年级用

67.50 / 25.62 / 21.94 * ( 5.98*x ) = ( 75.50*x ) x=> 0.0

88.18 = ( 3.08*x ) + ( 64.09*x ) / 3.77 + 95.96 x=> -0.387

31.57 - 69.97 = ( 19.58*x ) + 93.50 / 80.81 x=> -2.02

 

 

class Expression():
    def __init__(self):
        self.Num1=0
        self.Symbol=''
        self.Num2=0
        self.Question=""
        self.Answer=""
        self.RoundN = 3 #表示保留小数点位数


    #return 5+6+7=18
    def toString(self):
        #保留self.RoundN位小数点
        eqs = self.Question + " => " + str(round(self.Answer,self.RoundN))
        return eqs


class Equation():
    def __init__(self):
        self.Symbols=['+','-']
        self.Numbers=['0','1','2','3','4','5','6','7','8','9']
        self.bAnswerIt=True
        self.expr=Expression()
        self.nDigit=3 #3个数字相加减

    def RandomSymbol(self):
        length=len(self.Symbols)
        start=0
        end=length
        step=1
        return self.Symbols[random.randrange(start,end,step)]


    #['0','1','2','3','4','5','6','7','8','9']
    def RandomNumber(self):
        length=len(self.Numbers)
        start=0
        end=length
        step=1
        return self.Numbers[random.randrange(start,end,step)]



    # return : 25+18-36
    def generate(self):
        digit=self.nDigit
        
        eqs=""
        while True :
            if digit==self.nDigit: #首次
                self.expr.Num1=self.RandomNumber()
                self.expr.Symbol=self.RandomSymbol()
                self.expr.Num2=self.RandomNumber()
                
                eqs=self.expr.Num1+" "+\
                    self.expr.Symbol+" "+\
                    self.expr.Num2
            else:
                self.expr.Symbol=self.RandomSymbol()
                self.expr.Num2=self.RandomNumber()

                eqs=eqs+" "+\
                    self.expr.Symbol+" "+\
                    self.expr.Num2

            self.expr.Question=eqs
            self.expr.Answer=self.AnswerIt(eqs)
                        
            #判断两个数字是否符合要求
            if not self.AssertNumberRange(self.expr):
                digit=self.nDigit
                eqs=""
                continue
            
            if not self.AssertRange(self.expr):
                digit=self.nDigit
                eqs=""
                continue
            
            digit=digit-1
            if digit<=1: #3位满了
                break #while ,  get correct Equation
        return self.expr


  
    # eqs : 5+8-6
    # return : 7
    def AnswerIt(self,eqs):
        return eval(eqs)


    #assert anwser range,
    #eg. less than 20 ,or less than 100
    def AssertRange(self,expr):
        #pass
        return False

        
    def AssertNumberRange(self,expr):
        return True
    
class EquationGroup():
    def __init__(self,eqs2):
        self.EqsList=[]
        self.eqs=eqs2
        

    def generate(self,nCount):
        while nCount>0:
            expr= Expression()
            expr1=self.eqs.generate()
            expr.Question=expr1.Question
            expr.Answer=expr1.Answer
            self.EqsList.append(expr)
            nCount=nCount-1
        return self.EqsList

    def printList(self):
        for i in self.EqsList:  # 带答案输出
            eqs=""
            if self.eqs.bAnswerIt:
                eqs=i.toString()
            else:
                eqs=i.Question+" = "
            print ( eqs )
            
        for i in self.EqsList:  # 不带答案输出
            eqs=""
            if self.eqs.bAnswerIt:
                eqs=i.Question
                print ( eqs )

    
    
# 30以内,3个数字,加减法
# 5+8-6
class LessThanThirtyEquation(Equation):
......

# 150以内,3个数字,加法
# 25+18-36
class LessThanHundredEquation(Equation):
......

# 乘法(0-9)
# 3*6
class TimeEquation(Equation):
......

#"   4 - 3位小数乘除法",
# 3位小数乘除法
# 99.543*0.678
class DecimalTimeDevideEquation(Equation):
......

#"   4 - 3位小数解二元一次方程"
# 3位小数乘除法
# 99.543x + 0.678 - 0.88 x = 6.9 x + 2.2
class OneUnknownEquation(Equation):
......
    
    

调用方法:    
eqs=LessThanThirtyEquation()
eqs.bAnswerIt=self.bAnswer
eg=EquationGroup(eqs)
eg.generate(self.nCount)
if self.bQuiz :
    print( "quiz now")
    self.quizNow(eg)
else:
    eg.printList()    
    
一元一次方程求解
def test2():
    from sympy.abc import x
    res = solve([(x*20+32)/14-8],[x])
    print(res)

#"   4 - 3位小数解二元一次方程"
# 3位小数乘除法
# 99.543x + 0.678 - 0.88 x = 6.9 x + 2.2
class OneUnknownEquation(Equation):
    def __init__(self):
        Equation.__init__(self)
        self.Symbols=['+','-','/','*']
        self.Numbers=[]
        for i in range(0,100000): # 0-99999
            m = round(float(float(i)/1000),3)  
            self.Numbers.append(('%0.2f' % m )) # 生成固定长度字符串,并右侧补齐零 ,保留2位小数

        self.nDigit=5 #2个数字相乘除
        self.eqs_makeZero="" # 归零后的等式, 9+x-8=0
        

    def AssertRange(self,expr):
        if expr.Answer<0  or expr.Answer>3000: #小于0 或 大于3000,重新获取
            return False
        else:
            return True


    def AssertNumberRange(self,expr):
        #return True
        if float(expr.Num1)>301  or float(expr.Num2)>100: #小于0 或 大于3000,重新获取
            return False
        else:
            return True

    # return : 25+18-36
    def generate(self):
        digit=self.nDigit
        
        for f in range(1,6):
            nums = []
            eqs=""
            for i in range(0,digit): #获取每项的系数
                nums.append(self.RandomNumber())

            #获取x所在位置
            list_Xpos = []
            list_Xpos.append( random.randrange(0,digit) )# 0 - (digit-1)
            list_Xpos.append( random.randrange(0,digit) )# 0 - (digit-1)
            list_Xpos = list(set(list_Xpos)) #去除重复项

            #获取等号所在位置
            EQpos = random.randrange(0,digit-1)

            #运算符号 , + - * /
            list_Symbols =[]
            for i in range(0,digit-1): #获取每项的系数
                s = random.randrange(0,len(self.Symbols))
                list_Symbols.append(self.Symbols[s])

            for i in range(0,digit): #加入未知数
                #nums[i] = self.Symbols[list_Symbols[i]] + " " + str(nums[i])
                if i in list_Xpos:
                    nums[i] = "( " + nums[i] + "*x )"

            list_Symbols[EQpos] = "="

            #正常的等式
            eqs = nums[0]
            for i in range(1,digit):
                eqs = eqs + " " + list_Symbols[i-1] + " " + str(nums[i])

            self.expr.Question=eqs

            #归零的等式
            for i in range(EQpos,len(list_Symbols)):
                if list_Symbols[i] == "+":
                    list_Symbols[i] = "-"
                elif list_Symbols[i] == "-":
                    list_Symbols[i] = "+"
                elif list_Symbols[i] == "=":
                    list_Symbols[i] = "-"


            eqs = nums[0]
            for i in range(1,digit):
                eqs = eqs + " " + list_Symbols[i-1] + " " + str(nums[i])
            self.eqs_makeZero = eqs + " = 0"
            self.expr.Answer=self.AnswerIt(self.eqs_makeZero)
            if self.expr.Answer != -99999: # 判断等式符合了要求,退出循环
                break
        return self.expr



    # eqs : 5+8-6
    # return : 7
    def AnswerIt(self,eqs):
        pos = eqs.find("=")
        ans = solve(eqs[:pos])
        if len(ans)==1:
            return ans[0]
        else:
            return -99999

不断更新中...

我可以预先生成一些练习题(几千道应该也够用了),通过私信发给你。

代码下载链接:https://pan.baidu.com/s/1YmjFqt3E-j5IRe4yQHndKA 
提取码:v618 
 

 

 

 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值