《构建之法》作业:python写口算出题器
实现功能:
- 输入一个正整数n,随机生成n道运算符为2或3的整数四则运算(无括号)
- 题目和结果均为整数
- 生成两个文件,equation0.txt用于存放题目,result0.txt用于存放答案
- 成功生成文件以后,程序不结束,可以继续输入正整数n,在当前目录下生成equation1.txt,result1.txt,以此类推
- 当n为0时程序退出
- 若退出后重新执行,生成的文件接着当前目录下已存在文件序号继续生成
环境:
pip install numpy(不装也可以,直接用random就行了)
代码:
import numpy as np
import os
filepath = "./"
filename_list = os.listdir(filepath)
seg_tmp = 0
for filename in filename_list:
if "equation" in filename:
seg_tmp1 = filename[filename.rfind('n')+1:]
seg_tmp2 = seg_tmp1[0:seg_tmp1.rfind('.txt')]
if seg_tmp < int(seg_tmp2):
seg_tmp = int(seg_tmp2)
k = seg_tmp + 1 # 计算执行次数
# k = 1
while 1:
name_equ = "equation" + str(k) + ".txt" # 存放题目
name_res = "result" + str(k) + ".txt" # 存放答案
ops = ['+', '-', '*', '/'] # 运算符
cal_time = input("please enter the quantity (input 0000 to end):")
cal_time = int(cal_time)
i = 1 # 题数量
while i <= cal_time:
a = np.random.randint(0,2) # 随机两个数还是三个数进行运算
if a == 0:
element = np.random.randint(0, 101, 3)
op = np.random.randint(0, 4, 2)
if 2 not in op and 3 not in op: # 仅有加减运算
while 1:
element = np.random.randint(0, 101, 3)
if op[0] == 1: # 第一个运算为减法,被减数要大于减数
if element[0] < element[1]:
element[0], element[1] = element[1], element[0]
tmp = eval(str(element[0]) + ops[op[0]] + str(element[1])) # 第一个运算的的结果作为中间量
equation = str(element[0]) + ops[op[0]] + str(element[1]) + ops[op[1]] + str(element[2]) # 算式表示
val = eval(str(tmp) + ops[op[1]] + str(element[2])) # 实际结果
if val >= 0:
break
elif 0 not in op and 1 not in op: # 仅有乘除运算
element = np.random.randint(0, 101, 3)
if op[0] == 3: # 第一个为除法
element[1] = np.random.randint(1, 101)
if element[0] < element[1]:
element[0], element[1] = element[1], element[0]
if element[1] == 0: # 如果除数为0,在1-100重新随机除数
element[1] = np.random.randint(1, 101)
while element[0] % element[1] != 0:
if element[0] == 0:
break
element[1] -= 1
tmp = eval(str(element[0]) + ops[op[0]] + str(element[1]))
if op[1] == 3: # 第二个为除法
element[2] = np.random.randint(1, 101)
if tmp < element[2]:
if tmp == 0:
element[2] = np.random.randint(1,101)
else:
element[2] = np.random.randint(1,tmp+1)
while tmp % element[2] != 0:
if tmp == 0:
break
element[2] -= 1
equation = str(element[0]) + ops[op[0]] + str(element[1]) + ops[op[1]] + str(element[2]) # 算式表示
val = eval(str(tmp) + ops[op[1]] + str(element[2])) # 实际结果
else: # 加减乘除都有的混合运算
element = np.random.randint(0, 101, 3)
if op[0] > op[1]: # 乘除在前面
if op[0] == 3: # 第一个为除法
element[1] = np.random.randint(1, 101)
if element[0] < element[1]:
element[0], element[1] = element[1], element[0]
if element[1] == 0:
element[1] = np.random.randint(1, 101)
while element[0] % element[1] != 0:
if element[0] == 0:
break
element[1] -= 1
tmp = eval(str(element[0]) + ops[op[0]] + str(element[1]))
if op[1] == 1: # 第二个为减法时,重新随机减数,使其小于被减数
if tmp < element[2]:
if tmp == 0:
element[2] = 0
else:
element[2] = np.random.randint(1,tmp+1)
equation = str(element[0]) + ops[op[0]] + str(element[1]) + ops[op[1]] + str(element[2]) # 算式表示
val = eval(str(tmp) + ops[op[1]] + str(element[2])) # 实际结果
else: # 乘除在后面
while 1:
element = np.random.randint(0, 101, 4)
if op[1] == 3:
element[2] = np.random.randint(1, 101)
if element[1] < element[2]:
if element[1] == 0:
element[2] = np.random.randint(1, 101) #被除数为0,除数随机
else:
element[2] = np.random.randint(1, element[1]+1)
while element[1] % element[2] != 0:
if element[1] == 0:
break
else:
element[2] -= 1
tmp = eval(str(element[1]) + ops[op[1]] + str(element[2]))
equation = str(element[0]) + ops[op[0]] + str(element[1]) + ops[op[1]] + str(element[2]) # 算式表示
val = eval(str(element[0]) + ops[op[0]] + str(tmp))
if val >= 0:
break
# print(op)
# print("%s = "%equation)
# print(val)
else:
element = np.random.randint(0, 101, 4)
op = np.random.randint(0, 4, 3)
if 2 not in op and 3 not in op: # 只有加减
while 1:
element = np.random.randint(1, 101, 4)
if op[0] == 1: # 第一个是减
element[0] = np.random.randint(2, 101)
if element[0] < element[1]:
element[1] = np.random.randint(1,element[0])
tmp1 = eval(str(element[0]) + ops[op[0]] + str(element[1])) # 第一个运算的的结果作为中间量
if tmp1 > 0:
break
while 1:
element[2] = np.random.randint(1, 101)
if op[1] == 1:
if tmp1 < element[2]:
element[2] = np.random.randint(1,tmp1+1)
tmp2 = eval(str(tmp1) + ops[op[1]] + str(element[2]))
if tmp2 >= 0:
break
if op[2] == 1:
if tmp2 < element[3]:
element[3] = np.random.randint(0,tmp2+1)
equation = str(element[0]) + ops[op[0]] + str(element[1]) + ops[op[1]] + str(element[2]) + ops[op[2]] + str(element[3]) # 算式表示
val = eval(str(tmp2) + ops[op[2]] + str(element[3])) # 实际结果
elif 0 not in op and 1 not in op: # 仅有乘除运算
if op[0] == 3: # 第一个为除法
element[1] = np.random.randint(1, 101)
if element[0] < element[1]:
element[0], element[1] = element[1], element[0]
if element[1] == 0: # 如果除数为0,在1-100重新随机除数
element[1] = np.random.randint(1, 101)
while element[0] % element[1] != 0:
if element[0] == 0:
break
element[1] -= 1
tmp1 = eval(str(element[0]) + ops[op[0]] + str(element[1]))
if op[1] == 3: # 第二个为除法
element[2] = np.random.randint(1, 101)
if tmp1 < element[2]:
if tmp1 == 0:
element[2] = np.random.randint(1, 101)
else:
element[2] = np.random.randint(1, tmp1+1)
while tmp1 % element[2] != 0:
if tmp1 == 0:
break
else:
element[2] -= 1
tmp2 = eval(str(tmp1) + ops[op[1]] + str(element[2]))
if op[2] == 3: # 第三个为除法
element[3] = np.random.randint(1, 101)
if tmp2 < element[3]:
if tmp2 == 0:
element[3] = np.random.randint(1, 101)
else:
element[3] = np.random.randint(1, tmp2+1)
while tmp2 % element[3] != 0:
if tmp2 == 0:
break
element[3] -= 1
equation = str(element[0]) + ops[op[0]] + str(element[1]) + ops[op[1]] + str(element[2]) + ops[op[2]] + str(element[3]) # 算式表示
val = eval(str(tmp2) + ops[op[2]] + str(element[3])) # 实际结果
else: # 加减乘除都有的混合运算
if element[2] > 100:
element[2] = np.random.randint(0, 101)
if op[0] > 1 and op[1] > 1 and op[2] <= 1: # 乘除,乘除,加减
if op[0] == 3: # 第一个是除
element[1] = np.random.randint(1, 101)
if element[0] < element[1]:
element[0], element[1] = element[1], element[0]
if element[1] == 0:
element[1] = np.random.randint(1, 101)
while element[0] % element[1] != 0:
if element[0] == 0:
break
element[1] -= 1
tmp1 = eval(str(element[0]) + ops[op[0]] + str(element[1]))
if op[1] == 3: # 第二个是除
element[2] = np.random.randint(1, 101)
if tmp1 == 0:
element[2] = np.random.randint(1, 101)
else:
element[2] = np.random.randint(1, tmp1+1)
while tmp1 % element[2] != 0:
if tmp1 == 0:
break
element[2] -= 1
tmp2 = eval(str(tmp1) + ops[op[1]] + str(element[2]))
if op[2] == 1: # 第三个是减
if tmp2 < element[3]:
if tmp2 == 0:
element[3] = 0
else:
element[3] = np.random.randint(1,tmp2+1)
equation = str(element[0]) + ops[op[0]] + str(element[1]) + ops[op[1]] + str(element[2]) + ops[op[2]] + str(element[3])
val = eval(str(tmp2) + ops[op[2]] + str(element[3]))
if op[0] > 1 and op[1] <= 1 and op[2] <= 1: # 乘除,加减,加减
if op[0] == 3: # 第一个是除
element[1] = np.random.randint(1, 101)
if element[0] < element[1]:
element[0], element[1] = element[1], element[0]
if element[1] == 0:
element[1] = np.random.randint(1, 101)
while element[0] % element[1] != 0:
if element[1] == 0:
break
element[1] -= 1
tmp1 = eval(str(element[0]) + ops[op[0]] + str(element[1]))
if op[1] == 1: # 第二个是减
if tmp1 < element[2]:
if tmp1 == 0:
element[2] = 0
else:
element[2] = np.random.randint(1,tmp1+1)
tmp2 = eval(str(tmp1) + ops[op[1]] + str(element[2]))
if op[2] == 1: # 第三个是减
if tmp2 < element[3]:
if tmp2 == 0:
element[3] = 0
else:
element[3] = np.random.randint(1,tmp2+1)
equation = str(element[0]) + ops[op[0]] + str(element[1]) + ops[op[1]] + str(element[2]) + ops[op[2]] + str(element[3])
val = eval(str(tmp2) + ops[op[2]] + str(element[3]))
if op[0] > 1 and op[1] <= 1 and op[2] > 1: # 乘除,加减,乘除
if op[1] == 1: # 第二个是减
while 1:
element = np.random.randint(0, 101, 4)
if op[0] == 3: # 第一个是除
element[1] = np.random.randint(1, 101)
if element[0] < element[1]:
element[0], element[1] = element[1], element[0]
if element[1] == 0:
element[1] = np.random.randint(1, 101)
while element[0] % element[1] != 0:
if element[0] == 0:
break
element[1] -= 1
tmp1 = eval(str(element[0]) + ops[op[0]] + str(element[1]))
if op[2] == 3: # 第三个是除
element[3] = np.random.randint(1, 101)
if element[2] < element[3]:
element[2], element[3] = element[3], element[2]
if element[3] == 0:
element[3] = np.random.randint(1, 101)
while element[2] % element[3] != 0:
if element[2] == 0:
break
element[3] -= 1
tmp2 = eval(str(element[2]) + ops[op[2]] + str(element[3]))
if tmp1 >= tmp2: # 保证减法不出现负数
break
else:
if op[0] == 3: # 第一个是除
element[1] = np.random.randint(1, 101)
if element[0] < element[1]:
element[0], element[1] = element[1], element[0]
if element[1] == 0:
element[1] = np.random.randint(1, 101)
while element[0] % element[1] != 0:
if element[0] == 0:
break
element[1] -= 1
tmp1 = eval(str(element[0]) + ops[op[0]] + str(element[1]))
if op[2] == 3: # 第三个是除
element[3] = np.random.randint(1, 101)
if element[2] < element[3]:
element[2], element[3] = element[3], element[2]
if element[3] == 0:
element[3] = np.random.randint(1, 101)
while element[2] % element[3] != 0:
if element[2] == 0:
break
element[3] -= 1
tmp2 = eval(str(element[2]) + ops[op[2]] + str(element[3]))
equation = str(element[0]) + ops[op[0]] + str(element[1]) + ops[op[1]] + str(element[2]) + ops[op[2]] + str(element[3])
val = eval(str(tmp1) + ops[op[1]] + str(tmp2))
if op[0] <= 1 and op[1] <= 1 and op[2] > 1: # 加减,加减,乘除
while 1:
element = np.random.randint(0, 101, 4)
if op[2] == 3: # 第三个是除
element[3] = np.random.randint(1, 101)
if element[2] < element[3]:
element[2], element[3] = element[3], element[2]
if element[3] == 0:
element[3] = np.random.randint(1, 101)
while element[2] % element[3] != 0:
if element[2] == 0:
break
element[3] -= 1
tmp2 = eval(str(element[2]) + ops[op[2]] + str(element[3]))
equation = str(element[0]) + ops[op[0]] + str(element[1]) + ops[op[1]] + str(element[2]) + ops[op[2]] + str(element[3])
val = eval(str(element[0]) + ops[op[0]] + str(element[1]) + ops[op[1]] + str(tmp2))
if val >= 0:
break
if op[0] <= 1 and op[1] > 1 and op[2] > 1: # 加减,乘除,乘除
while 1:
element = np.random.randint(0, 101, 4)
if op[1] == 3: # 第二个为除法
element[2] = np.random.randint(1, 101)
if element[1] < element[2]:
element[1], element[2] = element[2], element[1]
if element[2] == 0: # 如果除数为0,在1-100重新随机除数
element[2] = np.random.randint(1, 101)
while element[1] % element[2] != 0:
if element[1] == 0:
break
element[2] -= 1
tmp1 = eval(str(element[1]) + ops[op[1]] + str(element[2]))
if op[2] == 3: # 第三个为除法
element[3] = np.random.randint(1, 101)
if tmp1 < element[3]:
if tmp1 == 0:
element[3] = np.random.randint(1,101)
else:
element[3] = np.random.randint(1,tmp1+1)
while tmp1 % element[3] != 0:
if tmp1 == 0:
break
element[3] -= 1
tmp2 = eval(str(tmp1) + ops[op[2]] + str(element[3]))
equation = str(element[0]) + ops[op[0]] + str(element[1]) + ops[op[1]] + str(element[2]) + ops[op[2]] + str(element[3])
val = eval(str(element[0]) + ops[op[0]] + str(tmp2))
if val >= 0:
break
if op[0] <= 1 and op[1] > 1 and op[2] <= 1: # 加减,乘除,加减
while 1:
element = np.random.randint(0,101,4)
if op[1] == 3: # 第二个为除
element[2] = np.random.randint(1, 101)
if element[1] < element[2]:
element[1], element[2] = element[2], element[1]
if element[2] == 0:
element[2] = np.random.randint(1, 101)
while element[1] % element[2] != 0:
if element[1] == 0:
break
element[2] -= 1
tmp1 = eval(str(element[1]) + ops[op[1]] + str(element[2]))
val = eval(str(element[0]) + ops[op[0]] + str(tmp1) + ops[op[2]] + str(element[3]))
equation = str(element[0]) + ops[op[0]] + str(element[1]) + ops[op[1]] + str(element[2]) + ops[op[2]] + str(element[3])
if val >= 0:
break
# print(op)
# print("%s = "%equation)
# print(val)
i += 1
val = int(val)
with open(name_equ,"a") as e, open(name_res,"a") as r:
e.write(equation + "=" + "\n")
r.write(equation + " = " + str(val) + "\n")
k += 1
if cal_time == 0000:
break
结果:
总结:
交作业前一个下午赶出来的,由于时间紧迫,整个程序写的很乱。
难点主要是:
- 遇到除法如何保证结果为整数?
一开始想用判断做,首先生成的除数要在[1,被除数],被除数大于等于1,其次若结果不为整数,则除数自减,直到减至1。
但次方法在多元运算时变得麻烦,被除数或除数是前面运算的结果,不好控制,所以最后还是使用了暴力随机法,非常笨拙。
- 随机到连乘,结果可能是非常大的数,从使用的角度来说不合理,如何避免?
考虑直接在连续生成乘法时重新随机,暂时未实现