自动生成小学四则运算题目并进行效能分析-改进版

github地址:https://github.com/lzhida/First-assignment/tree/newbranch

改进:

  可以删除一些无意义的括号

题目要求:

  1、能自动生成小学四则运算题目,并且不能出现负数;

  2、支持真分数四则运算

PSP表格

    预计耗时(分钟) 是实际耗时(分钟)
Planning 计划 30 30
·Estimate 估计这个任务需要多少时间 180 240
Development 开发 150 180
·Analysis 需求分析 5 10
·Design Spec 生成设计文档 30 30
·Design Review 设计复审(和同事审核设计文档) 5 5
·Coding Standerd 代码规范(为目前的开发制定合适的规范) 5 5
·Design 具体设计 5 10
·Coding 具体编码 90 110
·Code Review 代码复审 5 5
·Test 测试(自测,修改代码,提交修改) 5 5
Reporting 报告 30 80
·Test Report 测试报告 10 60
·Size Measurement 计算工作量 5 10
·Postmortem & Process Improvement Plan 事后总结,并提出过程改进计划 5 10
Sum 合计 240 260

解题思路:

  (1)生成四则运算表达式

  (2)计算表达式结果

  (3)定制一定数量的四则运算题

 解题过程:

  (1)get_expression():生成一个表达式

  (2) get_num():生成一个数字

  (3)get_symbol():生成一个符号

  (4)expression_generate():生成表达式

  (5)compare(symbol_1, symbol_2):比较符号优先级

  (6)one_calculate(num, symbol):进行一次运算

  (7)calculate(expression):计算整个表达式

  (8)output_expression(expression):规范表达式输出

  (9)main():定制生成的题目

代码如下:

  1 from fractions import Fraction
  2 import random
  3 
  4 def get_expression():
  5     """
  6     获得一个四则运算表达式
  7     支持整数和真分数混合运算
  8     返回数组
  9     :return: list
 10     """
 11     n = random.randint(1,2) #表达式长度
 12     expression = list() # 结果
 13 
 14     for i in range(n):
 15         expression.append(get_num())
 16         if i != n - 1: # 当不是最后一个数时,添加一个运算符
 17             expression.append(get_symbol())
 18 
 19     return expression
 20 
 21 def get_num():
 22     """
 23     随机获得一个整数或真分数
 24     返回Fraction对象
 25     :return: Fraction
 26     """
 27     m = random.random()
 28     if m >= 0.1: # 整数
 29         a = random.randint(1,20)
 30         x = Fraction(a)
 31     else: # 真分数
 32         a = random.randint(1, 20)
 33         b = random.randint(1, 20)
 34         x = Fraction(a, b)
 35     return x
 36 
 37 def get_symbol():
 38     """
 39     获得随机运算符号
 40     输入0-3的整数
 41     输出字符串
 42     :param r: int
 43     :return: string
 44     """
 45     r = random.randint(0,3)
 46     if r == 0:
 47         return '+'
 48     elif r == 1:
 49         return '-'
 50     elif r == 2:
 51         return '*'
 52     elif r == 3:
 53         return '/'
 54 
 55 
 56 def expression_generate():
 57     """
 58     生成一个表达式
 59     带括号
 60     :return:
 61     """
 62     n = random.randint(1,3)
 63     expr = []
 64     for i in range(n):
 65         e = get_expression()
 66         if len(e) > 1: # 当表示式长度大于1时可以加括号
 67             m = random.random()
 68             if m > 0.8: # 判断是否加括号
 69                 expr = expr + e
 70             elif m > 0.4: # 是否加嵌套的括号
 71                 expr.insert(0, '(')
 72                 expr = expr + e
 73                 expr.append(')')
 74             else: # 是否直接在表达式两端加括号
 75                 expr.append('(')
 76                 expr = expr + e
 77                 expr.append(')')
 78         else: # 表达式长度小于1
 79             expr = expr + e
 80         if i != n-1: # 判断是否是最后一个表达式,是则不加运算符
 81             expr.append(get_symbol())
 82 
 83 
 84     return expr
 85 
 86 def compare(symbol_1, symbol_2):
 87     """
 88     比较两个符号的优先级
 89     */的优先级高于+-的优先级
 90     如果symbol_1的符号优先级高于symbol_2的优先级返回True,否则返回Fals
 91     :param symbol_1:
 92     :param symbol_2:
 93     :return:
 94     """
 95     if symbol_1 in ["*", "/"] and symbol_2 in ["+", "-"]:
 96         return True
 97     else:
 98         return False
 99 
100 def one_calculate(num, symbol):
101     """
102     计算一次四则运算
103     :param num: list
104     :param symbol: list
105     :return:
106     """
107     b = num.pop()
108     a = num.pop()
109     s = symbol.pop()
110     if s == '+':
111         result = a + b
112     elif s == '-':
113         result = a - b
114     elif s == '*':
115         result = a * b
116     elif s == '/':
117         result = a / b
118 
119     num.append(result)
120 
121 def calculate(expression):
122     """
123     计算表达式的结果
124     输入表达式
125     输出结果
126     :param expression: string
127     :return: int or float
128     """
129     num = []
130     symbol = []
131     i = 0
132     while i < len(expression): # 取出表达式的值
133         if isinstance(expression[i], Fraction): # 如果是数字则加到num中
134             num.append(expression[i])
135         elif expression[i] == ")": # 如果是")",则symbol出栈并计算结果,直到遇到"("
136             while symbol[-1] != "(":
137                 one_calculate(num, symbol)
138             symbol.pop()
139         elif not symbol or symbol[-1] == "(": # 如果栈为空,或栈顶为"(",直接进栈
140             symbol.append(expression[i])
141         elif expression[i] == "(" or compare(expression[i], symbol[-1]): # 如果表达式的值为"(",或比栈顶的优先级高,则进栈
142             symbol.append(expression[i])
143         else: # 其他情况
144             while symbol and not compare(expression[i], symbol[-1]): # 栈不为空,且优先级比栈顶低,则直接进行运算
145                 if symbol[-1] == "(": # 直到栈顶为"(",退出
146                     break
147                 one_calculate(num, symbol) # 计算
148             symbol.append(expression[i]) # 进栈,优先级高
149         i += 1
150     while symbol: # 将栈清空,全部计算完毕
151         one_calculate(num, symbol)
152 
153     return num.pop()
154 
155 def output_expression(expression):
156     """
157     使输出的表达式更规范
158     输入表达式数组
159     输出表达式字符串
160     :param expression: list
161     :return: string
162     """
163     result = str()
164     n = len(expression)
165     for i in range(n):
166         if expression[i] == '/':
167             result = result + '÷'
168         elif expression[i] == '*':
169             result = result + 'x'
170         else:
171             result = result + str(expression[i]) + ''
172     return result
173 
174 
175 def test_brackets(expression):
176     """
177     删除无意义的括号
178     """
179     i = 1
180     a = 0
181     if len(expression) <= 3:
182         return expression
183 
184     while i < len(expression):
185         if expression[i-1] == "(":
186             a += 1
187             b = 0
188             j = i
189             while j < len(expression):
190                 if expression[j] == ")":
191                     b += 1
192                 if a == b:
193                     break
194                 j += 1
195 
196             temp = expression[:]
197             del temp[j]
198             del temp[i-1]
199             if calculate(temp) == calculate(expression):
200                 expression = temp[:]
201                 a -= 1
202         i += 1
203     return expression
204 
205 
206 def main():
207     """
208     主函数
209     :return:
210     """
211     n = int(input('输入题目的个数:'))
212     lis = list()
213     while True: # 直到满足题目个数,结束
214         expression = expression_generate() # 获取表达式
215         expression = test_brackets(expression) # 删除无意义的括号
216         result = calculate(expression) # 计算表达式
217         if float(result) >= 0: # 将表达式和结果保存到字典中
218             dic = dict()
219             expression = output_expression(expression)
220             dic['expression'] = expression
221             dic['result'] = str(result)
222             lis.append(dic) # 把字典添加到列表中
223         if len(lis) >= n: # 当列表长度大于等于题目个数时,退出循环
224             break
225 
226     print('保存数据到文本')
227     with open('result.txt', 'w') as file:
228         for i in range(len(lis)):
229             file.write(lis[i]['expression'] + ' = ' + lis[i]['result'] + '\n')
230 
231 
232 if __name__ == '__main__':
233     main()

效能分析:

  

猜你喜欢

转载自www.cnblogs.com/lzhida/p/10690168.html