个人作业二 小学四则运算系统

一、作业信息

| 作业班级 | https://edu.cnblogs.com/campus/ahgc/AHPU-se-JSJ18 |
| ---- | ---- | ---- |
| 作业要求 | https://edu.cnblogs.com/campus/ahgc/AHPU-se-JSJ18/homework/11377 |
| 作业目的| 对需求进行分析并实现;编码格式需规范;|
|学号|3180301128|

二、作业要求
写一个能自动生成小学四则运算题目的程序,然后在此基础上扩展:

1)除了整数以外,还要支持真分数的四则运算,例如:1/6+1/8=7/24

2)程序要求能处理用户的输入,判断对错,累积分数

3)程序支持可以由用户自行选择加、减、乘、除运算

4)使用-n参数控制生成题目的个数,例如Myapp.exe -n 10,将生成10个题目

三、代码提交与运行截图
import unicodedata
import string
import math
import random
import tkinter as tk
expression_var ='v'
expression_label ='la'
class App(tk.Frame):

#expression_label=0

User_answer_Entry=''

total_score=0

ARITHMETIC_OPERATOR=''

rand1=1

rand2=1

rand3=1

rand4=1

rand_denominator_of_fraction_1  =  1

rand_denominator_of_fraction_2  =  1
#expression_var=''#expression_var store four Arithmetic operations expression
def __init__(self, master):
    super().__init__(master)

    #print(type(self))
    #self.pack()
    self.master.geometry('300x300')  # 这里的乘是小x
    self.master.title('小学四则运算器')
    # 第4步,在图形界面上设定标签
    self.Main_menu_label = tk.Label(self.master,text='你好!欢迎来到小学四则运算训练系统', bg='green', font=('Arial', 10), width=30,
                       height=2)
    # 说明: bg为背景,font为字体,width为长,height为高,这里的长和高是字符的长和高,
    #比如height=2,就是标签有2个字符这么高
     
    # 第5步,放置标签
    self.Main_menu_label .pack()    # Label内容content区域放置位置,自动调节尺寸

        
    self.Integer_operations = tk.Button(self.master, text='整数运算', font=('Arial', 10), width=10, height=1, command=self.Four_integer_operations_interface)

    self.Integer_operations.pack()
    
    self.True_fraction_operations = tk.Button(self.master, text='真分数运算', font=('Arial', 10), width=10, height=1, command=self.True_fraction_operation_interface)

    self.True_fraction_operations.pack()

    
def Four_integer_operations_interface(self):                         #整数的四则运算
    
    # 第1步,实例化object,建立窗口window
    Four_integer_operations_window = tk.Tk()
     
    # 第2步,给窗口的可视化起名字
    Four_integer_operations_window.title('整数四则训练器')

    # 第3步,设定窗口的大小(长 * 宽)
    Four_integer_operations_window.geometry('300x300')  # 这里的乘是小x
     
    # 第4步,在图形界面上设定标签
    Integer_operations_menu_label = tk.Label(Four_integer_operations_window, text='请选择一种运算规则',bg='green', font=('Arial', 10), width=30,height=2)
    # 说明: bg为背景,font为字体,width为长,height为高,这里的长和高是字符的长和高,
    #比如height=2,就是标签有2个字符这么高
     
    # 第5步,放置标签
    Integer_operations_menu_label .pack()    # Label内容content区域放置位置,自动调节尺寸
    
    # 放置lable的方法有:1)l.pack(); 2)l.place();

        
    Integer_addition_operation = tk.Button(Four_integer_operations_window, text='整数加法运算',font=('Arial', 10), width=10, height=1,command=(lambda:self.Expression_interface('+')))

    Integer_addition_operation.pack()

    Integer_subtraction_operation = tk.Button(Four_integer_operations_window, text='整数减法运算',font=('Arial', 10), width=10, height=1,command=(lambda:self.Expression_interface('-')))

    Integer_subtraction_operation.pack()

    Integer_multiplication_operation = tk.Button(Four_integer_operations_window, text='整数乘法运算',font=('Arial', 10), width=10, height=1,command=(lambda:self.Expression_interface('*')))

    Integer_multiplication_operation.pack()

    Integer_division_operation = tk.Button(Four_integer_operations_window, text='整数除法运算',font=('Arial', 10), width=10, height=1,command=(lambda:self.Expression_interface('/')))

    Integer_division_operation.pack()
    
    Four_integer_operations_window.mainloop()


def True_fraction_operation_interface(self):

    # 第1步,实例化object,建立窗口window
    Four_True_fraction_operations_window = tk.Tk()
     
    # 第2步,给窗口的可视化起名字
    Four_True_fraction_operations_window.title('真分数四则训练器')

    # 第3步,设定窗口的大小(长 * 宽)
    Four_True_fraction_operations_window.geometry('300x300')  # 这里的乘是小x
     
    # 第4步,在图形界面上设定标签
    True_fraction_operations_note_label = tk.Label(Four_True_fraction_operations_window, text='请选择一种运算规则',bg='green', font=('Arial', 10), width=30,height=2)
    # 说明: bg为背景,font为字体,width为长,height为高,这里的长和高是字符的长和高,
    #比如height=2,就是标签有2个字符这么高
     
    # 第5步,放置标签
    True_fraction_operations_note_label .pack()    # Label内容content区域放置位置,自动调节尺寸
    
    # 放置lable的方法有:1)l.pack(); 2)l.place();

        
    True_fraction_addition_operation = tk.Button(Four_True_fraction_operations_window, text='真分数加法运算',font=('Arial', 10), width=12, height=1,command=(lambda:self.Expression_interface('fraction+')))

    True_fraction_addition_operation.pack()

    True_fraction_subtraction_operation = tk.Button(Four_True_fraction_operations_window, text='真分数减法运算',font=('Arial', 10), width=12, height=1,command=(lambda:self.Expression_interface('fraction-')))

    True_fraction_subtraction_operation.pack()

    True_fraction_multiplication_operation = tk.Button(Four_True_fraction_operations_window, text='真分数乘法运算',font=('Arial', 10), width=12, height=1,command=(lambda:self.Expression_interface('fraction*')))

    True_fraction_multiplication_operation.pack()

    True_fraction_division_operation = tk.Button(Four_True_fraction_operations_window, text='真分数除法运算',font=('Arial', 10), width=12, height=1,command=(lambda:self.Expression_interface('fraction/')))

    True_fraction_division_operation.pack()
    
    Four_True_fraction_operations_window.mainloop()

    

def is_num(self,users_input_str):

    #接受一个用户输入的字符串,判断其是否是一个整数或小数

    try:
        float(users_input_str)
        return True
    except Exception as  e:
        
        pass

    return False

def Judge_users_fraction(self,users_input_str):
    
    #接受一个用户输入的字符串,判断其是否是一个分数,如果是分数返回True,否则返回False,
    #判断条件是字符串中“/”出现的次数为1次而且字符串中第一个分号'/'之后的第一个字符不是'0',同时分号'/'不能
    #出现在字符串的开头或结尾,并且字符串唯一分号‘/’的所在位置前面与后面都必须是数字且不能以数字‘0’开头

    Number_of_division_signs=0

    for i in users_input_str:

        if(i=='/'):

            Number_of_division_signs+=1

    first_division_sign = users_input_str.index('/')  #找到用户输入的分数的第一个除号在字符串中的位置传给变量first_division_sign用以存储

    if(users_input_str[0]=='0' or (users_input_str[first_division_sign+1] == '0')):#字符串的首字符不能是'0'且字符串中第一个分号'/'之后的第一个字符不是'0'

        return False

    for i in range(0,first_division_sign ):#判断分号‘/’前面的字符,只要有一个不是数字,这个字符串就不是分数,则返回False
       
        if(users_input_str[i] not in ['0','1','2','3','4','5','6','7','8','9']):

            return False

    for i in range(first_division_sign+1, len(users_input_str)):#判断分号‘/’后面的字符,只要有一个不是数字,这个字符串就不是分数,则返回False
       
        if(users_input_str[i] not in ['0','1','2','3','4','5','6','7','8','9']):

            return False

    if((Number_of_division_signs==1) and (first_division_sign !=0 ) and (first_division_sign !=(len(users_input_str)-1))):
        #分号只有一个,分号所在位置既不是首位也不是末尾。
    
        return True
    
    else:

        return False

def Judge_correct_and_Calculate_the_total_score(self):

    #global User_answer_Entry
    
    #global users_answer
    
    users_answer = self.User_answer_Entry.get()#users_answer是用户从键盘输入的字符串类型的答案 只要用户输入的不是整数 就提示回答错误,且得分为零
    
    if (self.is_num(users_answer)==True):#如果is_num(users_answer)==True 代表用户输入的字符串(users_answer)是整数或小数

        #global instance1

        if(self.ARITHMETIC_OPERATOR == '+'):#
            
            if(abs(float(users_answer) - (self.rand1+self.rand2)) < (1e-3) ): #两个数都是整数时,取相应的浮点数再相减,精度在范围内的话,
                                                                                   #两个数实际上就是相同的整数
                #global total_score
                
                self.total_score+=1
               
                tk.messagebox.showinfo(title='提示信息',message='回答正确,累计分数:'+str(self.total_score))

                self.Next_expression_example()
                '''
                remember this usage
                
                ui=tkinter.messagebox.askyesno(title='eeeeee', message='你好!')
                if((ui==True) or (ui==False)):#可以保证答题机会只有一次
                   print('adf')

                '''
            else:
                                
                #global total_score
                
                #total_score+=1
               
                tk.messagebox.showinfo(title='提示信息',message='回答错误,累计分数:'+str(self.total_score))

                self.Next_expression_example()

        elif(self.ARITHMETIC_OPERATOR == '-'):
            
            if(abs(float(users_answer) - (self.rand1-self.rand2)) < (1e-3) ): #两个数都是整数时,取相应的浮点数再相减,精度在范围内的话,
                                                                                   #两个数实际上就是相同的整数
                #global total_score
                
                self.total_score+=1
               
                tk.messagebox.showinfo(title='提示信息',message='回答正确,累计分数:'+str(self.total_score))

                self.Next_expression_example()
                '''
                remember this usage
                
                ui=tkinter.messagebox.askyesno(title='eeeeee', message='你好!')
                if((ui==True) or (ui==False)):#可以保证答题机会只有一次
                   print('adf')

                '''
            else:
                                
                #global total_score
                
                #total_score+=1
               
                tk.messagebox.showinfo(title='提示信息',message='回答错误,累计分数:'+str(self.total_score))

                self.Next_expression_example()

        elif(self.ARITHMETIC_OPERATOR == '*'):
            
            if(abs(float(users_answer) - (self.rand1*self.rand2)) < (1e-3) ): #两个数都是整数时,取相应的浮点数再相减,精度在范围内的话,
                                                                                   #两个数实际上就是相同的整数
                #global total_score
                
                self.total_score+=1
               
                tk.messagebox.showinfo(title='提示信息',message='回答正确,累计分数:'+str(self.total_score))

                self.Next_expression_example()
                '''
                remember this usage
                
                ui=tkinter.messagebox.askyesno(title='eeeeee', message='你好!')
                if((ui==True) or (ui==False)):#可以保证答题机会只有一次
                   print('adf')

                '''
            else:
                                
                #global total_score
                
                #total_score+=1
               
                tk.messagebox.showinfo(title='提示信息',message='回答错误,累计分数:'+str(self.total_score))

                self.Next_expression_example()

        elif(self.ARITHMETIC_OPERATOR == '/'):
            
            if(abs(float(users_answer) - (self.rand1/self.rand2)) < (1e-3) ): #两个数都是整数时,取相应的浮点数再相减,精度在范围内的话,
                                                                                   #两个数实际上就是相同的整数
                #global total_score
                
                self.total_score+=1
               
                tk.messagebox.showinfo(title='提示信息',message='回答正确,累计分数:'+str(self.total_score))

                self.Next_expression_example()
                '''
                remember this usage
                
                ui=tkinter.messagebox.askyesno(title='eeeeee', message='你好!')
                if((ui==True) or (ui==False)):#可以保证答题机会只有一次
                   print('adf')

                '''
            else:
                                
                #global total_score
                
                #total_score+=1
               
                tk.messagebox.showinfo(title='提示信息',message='回答错误,累计分数:'+str(self.total_score))

                self.Next_expression_example()

def Next_expression_example(self):
    
    self.rand1=random.randint(-100,100)# rand1 and rand2 are both positive or negative integer 

    self.rand2=random.randint(-100,100)

    
    self.rand3=random.randint(1,100)# rand3 and rand4 are both positive integer which will be the rand numerator of fraction

    self.rand4=random.randint(1,100)

    self.rand_denominator_of_fraction_1  =  random.randint(101,200)

    self.rand_denominator_of_fraction_2  =  random.randint(101,200)

    

    #self.rand_positive_integer1=random.randint(1,100)

    #self.rand_negative_integer1=random.randint(-100,-1)

    #self.rand_positive_integer2=random.randint(1,100)

    #self.rand_negative_integer2=random.randint(-100,-1)

    #self.rand_denominator_of_fraction_1  =  random.choice([self.rand_positive_integer1 ,self.rand_negative_integer1])
    
    #take a Non-zero integer as a denominator of a fraction from a list which only contain a positive integer and a negative integer

    #self.rand_denominator_of_fraction_2  =  random.choice([self.rand_positive_integer2 ,self.rand_negative_integer2])
    
    global expression_var

    global expression_label
    
    if(self.ARITHMETIC_OPERATOR == '+'):#根据类变量的值生成相应的算术表达式,如果self.ARITHMETIC_OPERATOR的值是('+','-','*','/')中的一个,则生成整数表达式,
                                        #如果self.ARITHMETIC_OPERATOR的值是('fraction+','fraction-','fraction*','fraction/')中的一个,则生成真分数表达式。
        print('#################')
        print(self.ARITHMETIC_OPERATOR)
        print(self.rand1,self.rand2)
        #global expression_var
        print(expression_var)
        #self.hi_there["text"] = "Hello World\n(click me)"
        try:
            
            expression_var.set(str(self.rand1)+' + '+ '('+str(self.rand2)+')')
            #global expression_label
            expression_label['text']=expression_var.get()
        except Exception as  e:
            
            print(e)
        #self.expression_var.set('self.rand1 + self.rand2))
        #self.expression_var=str(self.rand1)+' + '+str(self.rand2)
        #self.expression_label(textvariable=self.expression_var)
        print(expression_var)
        print(expression_var.get())
        print(type(expression_var))#self.expression_var 是一个对象 不能直接传值
    
    elif(self.ARITHMETIC_OPERATOR == '-'):
        
        print('#################')
        print(self.ARITHMETIC_OPERATOR)
        print(self.rand1,self.rand2)
        #global expression_var
        print(expression_var)
        #self.hi_there["text"] = "Hello World\n(click me)"
        try:
            
            expression_var.set(str(self.rand1)+' - '+ '('+str(self.rand2)+')')
            #global expression_label
            expression_label['text']=expression_var.get()
        except Exception as  e:
            
            print(e)
        #self.expression_var.set('self.rand1 + self.rand2))
        #self.expression_var=str(self.rand1)+' + '+str(self.rand2)
        #self.expression_label(textvariable=self.expression_var)
        print(expression_var)
        print(expression_var.get())
        
        #self.expression_var.set(str(self.rand1)+' - '+str(self.rand2))
        

    elif(self.ARITHMETIC_OPERATOR == '*'):
        print('#################')
        print(self.ARITHMETIC_OPERATOR)
        print(self.rand1,self.rand2)
        #global expression_var
        print(expression_var)
        #self.hi_there["text"] = "Hello World\n(click me)"
        try:
            
            expression_var.set(str(self.rand1)+' * '+ '('+str(self.rand2)+')')
            #global expression_label
            expression_label['text']=expression_var.get()
        except Exception as  e:
            
            print(e)
        #self.expression_var.set('self.rand1 + self.rand2))
        #self.expression_var=str(self.rand1)+' + '+str(self.rand2)
        #self.expression_label(textvariable=self.expression_var)
        print(expression_var)
        print(expression_var.get())
        
        #self.expression_var.set(str(self.rand1)+' * '+str(self.rand2))

    elif(self.ARITHMETIC_OPERATOR == '/'):
        print('#################')
        print(self.ARITHMETIC_OPERATOR)
        print(self.rand1,self.rand2)
        #global expression_var
        print(expression_var)
        #self.hi_there["text"] = "Hello World\n(click me)"
        try:
            
            expression_var.set(str(self.rand1)+ ' / ' + '('+str(self.rand2)+')')
            #global expression_label
            expression_label['text']=expression_var.get()
        except Exception as  e:
            
            print(e)
        #self.expression_var.set('self.rand1 + self.rand2))
        #self.expression_var=str(self.rand1)+' + '+str(self.rand2)
        #self.expression_label(textvariable=self.expression_var)
        print(expression_var)
        print(expression_var.get())


    elif(self.ARITHMETIC_OPERATOR == 'fraction+'):
        
        print('#################')
        print(self.ARITHMETIC_OPERATOR)
        print(self.rand1,self.rand_denominator_of_fraction_1,self.rand_denominator_of_fraction_2)
        #global expression_var
        print(expression_var)
        #self.hi_there["text"] = "Hello World\n(click me)"
        try:
            
            expression_var.set('('+str(self.rand3)+ '/' +str(self.rand_denominator_of_fraction_1) +')'+  ' + '  + '('+str(self.rand4)+ '/' +str(self.rand_denominator_of_fraction_2)+')')
            #global expression_label
            expression_label['text']=expression_var.get()
        except Exception as  e:
            
            print(e)
        #self.expression_var.set('self.rand1 + self.rand2))
        #self.expression_var=str(self.rand1)+' + '+str(self.rand2)
        #self.expression_label(textvariable=self.expression_var)
        print(expression_var)
        print(expression_var.get())
        
        #self.expression_var.set(str(self.rand1)+' - '+str(self.rand2))
        

    elif(self.ARITHMETIC_OPERATOR == 'fraction-'):
        print('#################')
        print(self.ARITHMETIC_OPERATOR)
        print(self.rand1,self.rand_denominator_of_fraction_1,self.rand_denominator_of_fraction_2)
        #global expression_var
        print(expression_var)
        #self.hi_there["text"] = "Hello World\n(click me)"
        try:
            
            expression_var.set('('+str(self.rand3)+ '/' +str(self.rand_denominator_of_fraction_1) +')'+  ' - ' + '(' +str(self.rand4)+ '/' +str(self.rand_denominator_of_fraction_2)+ ')')
            #global expression_label
            expression_label['text']=expression_var.get()
        except Exception as  e:
            
            print(e)
        #self.expression_var.set('self.rand1 + self.rand2))
        #self.expression_var=str(self.rand1)+' + '+str(self.rand2)
        #self.expression_label(textvariable=self.expression_var)
        print(expression_var)
        print(expression_var.get())
        
        #self.expression_var.set(str(self.rand1)+' * '+str(self.rand2))

    elif(self.ARITHMETIC_OPERATOR == 'fraction*'):
        print('#################')
        print(self.ARITHMETIC_OPERATOR)
        print(self.rand1,self.rand_denominator_of_fraction_1,self.rand_denominator_of_fraction_2)
        #global expression_var
        print(expression_var)
        #self.hi_there["text"] = "Hello World\n(click me)"
        try:
            
            expression_var.set('('+str(self.rand3)+ '/' +str(self.rand_denominator_of_fraction_1)+')'+  ' * ' + '(' +str(self.rand4)+ '/' +str(self.rand_denominator_of_fraction_2)+ ')')
            #global expression_label
            expression_label['text']=expression_var.get()
        except Exception as  e:
            
            print(e)
        #self.expression_var.set('self.rand1 + self.rand2))
        #self.expression_var=str(self.rand1)+' + '+str(self.rand2)
        #self.expression_label(textvariable=self.expression_var)
        print(expression_var)
        print(expression_var.get())

    elif(self.ARITHMETIC_OPERATOR == 'fraction/'):
        print('#################')
        print(self.ARITHMETIC_OPERATOR)
        print(self.rand1,self.rand_denominator_of_fraction_1,self.rand_denominator_of_fraction_2)
        #global expression_var
        print(expression_var)
        #self.hi_there["text"] = "Hello World\n(click me)"
        try:
            
            expression_var.set('('+str(self.rand3)+ '/' +str(self.rand_denominator_of_fraction_1)+')' +  ' / ' + '(' +str(self.rand4)+ '/' +str(self.rand_denominator_of_fraction_2)+ ')')
            #global expression_label
            expression_label['text']=expression_var.get()
        except Exception as  e:
            
            print(e)
        #self.expression_var.set('self.rand1 + self.rand2))
        #self.expression_var=str(self.rand1)+' + '+str(self.rand2)
        #self.expression_label(textvariable=self.expression_var)
        print(expression_var)
        print(expression_var.get())
        
        
        
        #self.expression_var.set(str(self.rand1)+' / '+str(self.rand2))
    
    #add_expr=str(rand1)+' + '+str(rand2)

    #return add_expr
    


def Expression_interface(self,Operator):
    
    #Operator 是运算符 即  '+'   '-'   '*'  '/'  中的一个
    self.ARITHMETIC_OPERATOR  =  Operator

    # 第1步,实例化object,建立加法例题窗口Addition_example_window,此窗口有一个可以更新的label "Addition_expression_label"用于
    #输出每道加法运算的题目(采用button “Change_question”来显示第一道题或切到下一题),有一个Entry "User_answer_Entry"用于接收用户输入的
    #加法表达式的答案,有两个文字标签“word_label_1”和“word_label_2”用于显示提示信息,有三个button:“Change_question”,“Submit”,End_practice
    #功能1显示加法运算的题目,
    example_window = tk.Tk()
     
    # 第2步,给窗口的可视化起名字
    example_window.title('例题')

    # 第3步,设定窗口的大小(长 * 宽)
    example_window.geometry('500x300')  # 这里的乘是小x
     
    # 第4步,在图形界面上设定标签
    word_label_1= tk.Label(example_window, text='题目', bg='green', fg='white', font=('Arial', 10), width=10, height=2)

    word_label_1.pack()     #放置文字标签"题目"

    global expression_var  #global only need using just one time 

    expression_var= tk.StringVar()  

    #self.expression_var = tk.StringVar()  textvariable
    try:#全局变量向类变量传值 expression_var是全局变量
        global expression_label
        print(expression_label)
        print(expression_var)
        expression_label= tk.Label(example_window, text=expression_var, bg='green', fg='white', font=('Arial', 10), width=20, height=2)
        expression_label.pack()
        print(expression_label)
        print(type(expression_label))
        print(expression_var)
        #self.expression_label= tk.Label(example_window, textvariable=self.expression_var, bg='green', fg='white', font=('Arial', 10), width=20, height=2)

        #self.expression_label.pack()#显示每个题目

    except Exception as  e:
        print(e)

    word_label_2= tk.Label(example_window, text='请输入答案', bg='green', fg='white', font=('Arial', 10), width=10, height=2)

    word_label_2.pack()     #放置文字标签"请输入答案"

    self.User_answer_Entry= tk.Entry(example_window, show=None, font=('Arial', 14))  # 显示成明文形式

    self.User_answer_Entry.pack()     #User_answer Entry 窗口部件用于接收用户输入

    Change_question = tk.Button(example_window, text='开始/下一题', font=('Arial', 10), width=10, height=1, command=self.Next_expression_example)

    Change_question.pack()#放置切题按钮

    Submit = tk.Button(example_window, text='提交', font=('Arial', 10), width=10, height=1, command=self.Judge_correct_and_Calculate_the_total_score)

    Submit.pack()#放置提交按钮

    example_window.mainloop()

'''
End_practice = tk.Button(example_window, text='结束训练', font=('Arial', 12), width=10, height=1, command=Addition_example)

    End_practice.pack()#放置“结束训练”按钮

'''
#example_window.mainloop()

root = tk.Tk()
myapp = App(root)
myapp.mainloop()

'''

test case:

is_num('132')
True
is_num('-123')
True
is_num('131.13232')
True
is_num('-143.1234143')
True
is_num('redfsj0--)_{":>&%$#@!~!%&*()><>?"|')
False

'''

'''

test case;

float('243')
243.0
float('-12')
-12.0
float('234.4421')
234.4421
float('-1423.41243')
-1423.41243
'''
截图:

四、个人小结
首先,第一次接触博客园,许多使用方法很陌生,但是通过这一次的实际操作,慢慢地学会了一些基本的操作。其次,最重要的是练习了Python的GUI编程知识。其中STRING类中一个方法的使用错误导致了四个小时的调试时间,最终在网络上找到解答方法,但是不知为何出错。

posted @ 2021-01-21 17:49  计算机182俞奥  阅读(69)  评论(0编辑  收藏  举报