个人作业二 小学四则运算系统
一、作业信息
| 作业班级 | 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类中一个方法的使用错误导致了四个小时的调试时间,最终在网络上找到解答方法,但是不知为何出错。