ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

psp下的四则运算

2021-09-26 20:32:21  阅读:191  来源: 互联网

标签:formular oper return self 四则运算 list psp wx


psp:

psp任务内容计划完成需要的时间(min)实际完成需要的时间(min)
Planning 计划 10 15
Estimate 估计这个任务需要多少时间,并规划大致工作步骤 6 6
Development 开发 120 120
Analysis 需求分析(包括学习新技术) 10 10
Design Spec 生成设计文档 20 20
Coding Standard 代码规范 5 8
Design 具体设计 15 22
Coding 具体编码 40 35
Code Review 代码复审 5 4
Test 测试(自我测试,修改代码,提交修改) 20 15
Reporting 报告 10 10
Test Report 测试报告 2 3

 

代码:

sizeyusuan代码:

import wx
from wx.core import CLEAR
from formula import OPT, GeneralFormular, ComputeFormular

class MyApp(wx.App):
def OnInit(self):
frame = wx.Frame(parent=None, title="四则运算生成器") # 新建框架
panel = wx.Panel(frame, -1) # 生成面板
Text = wx.StaticText(panel,-1,"请输入相关需求",pos=(150,2))

label1=wx.StaticText(panel,-1,"生成算式数量(>=1)",pos=(10,30)) #标签
text1=wx.TextCtrl(panel,-1,pos=(200,30),size=(180,20), #输入框
style=wx.TE_MULTILINE)

label2=wx.StaticText(panel,-1,"每个数值的上限(>=10)",pos=(10,60))
text2=wx.TextCtrl(panel,-1,pos=(200,60),size=(180,20),
style=wx.TE_MULTILINE)

label3=wx.StaticText(panel,-1,"操作数个数(>=2)",pos=(10,90))
text3=wx.TextCtrl(panel,-1,pos=(200,90),size=(180,20),
style=wx.TE_MULTILINE)

label4=wx.StaticText(panel,-1,"运算符种数(1~4)",pos=(10,120))
text4=wx.TextCtrl(panel,-1,pos=(200,120),size=(180,20),
style=wx.TE_MULTILINE)

label5=wx.StaticText(panel,-1,"是否要包含分数(0,1)",pos=(10,150))
text5=wx.TextCtrl(panel,-1,pos=(200,150),size=(180,20),
style=wx.TE_MULTILINE)

button = wx.Button(panel,-1, '确定', pos=(150, 180)) # 确定按钮位置

self.text1=text1 #方便跨函数调用
self.text2=text2
self.text3=text3
self.text4=text4
self.text5=text5

self.button1 = button
self.Bind(wx.EVT_BUTTON, # 绑定事件,如果是按钮被点击
self.GetInPut, # 激发的按钮事件
self.button1) # 激发的按钮

frame.Center()
frame.Show() # 显示
return True

def GetInPut(self,event): #事件的激发函数,获得输入
while True:

n = self.text1.GetValue()
try:
n = abs(int(n))
if n < 1:
wx.MessageBox("生成算式数量-[Eror]: Input illegal! Please input again... "\
, "INFO", wx.OK|wx.ICON_INFORMATION)
break
except Exception as e:
wx.MessageBox("生成算式数量-[Eror]: Input illegal! Please input again... "\
, "INFO", wx.OK|wx.ICON_INFORMATION)
break

up_limit = self.text2.GetValue()
try:
up_limit = abs(int(up_limit))
if up_limit < 10:
wx.MessageBox("每个数值的上限-[Eror]: Input illegal! Please input again... "\
, "INFO", wx.OK|wx.ICON_INFORMATION)
break
except Exception as e:
wx.MessageBox("每个数值的上限-[Eror]: Input illegal! Please input again... "\
, "INFO", wx.OK|wx.ICON_INFORMATION)
break

oper_num = self.text3.GetValue()
try:
oper_num = abs(int(oper_num))
if oper_num < 2:
wx.MessageBox("操作数个数-[Eror]: Input illegal! Please input again... "\
, "INFO", wx.OK|wx.ICON_INFORMATION)
break
except Exception as e:
wx.MessageBox("操作数个数-[Eror]: Input illegal! Please input again... "\
, "INFO", wx.OK|wx.ICON_INFORMATION)
break

oper_variety = self.text4.GetValue()
try:
oper_variety = abs(int(oper_variety))
if oper_variety < 1 or oper_variety > 4:
wx.MessageBox("运算符种数-[Eror]: Input illegal! Please input again... "\
, "INFO", wx.OK|wx.ICON_INFORMATION)
break
except Exception as e:
wx.MessageBox("运算符种数-[Eror]: Input illegal! Please input again... "\
, "INFO", wx.OK|wx.ICON_INFORMATION)
break

has_fraction = self.text5.GetValue()
try:
has_fraction = abs(int(has_fraction))
if has_fraction != 0 and has_fraction != 1:
wx.MessageBox("是否要包含分数-[Eror]: Input illegal! Please input again... "\
, "INFO", wx.OK|wx.ICON_INFORMATION)
break
except Exception as e:
wx.MessageBox("是否要包含分数-[Eror]: Input illegal! Please input again... "\
, "INFO", wx.OK|wx.ICON_INFORMATION)
break

self.n = int(n)
self.up_limit = int(up_limit)
self.oper_num = int(oper_num)
self.oper_variety = int(oper_variety)
self.has_fraction = int(has_fraction)

self.solveFormular()
break

def solveFormular(self):
opt = OPT(self.up_limit, self.oper_num, self.oper_variety, self.has_fraction)

gf = GeneralFormular(opt)
cf = ComputeFormular()

formulars = []
results = []
for i in range(int(self.n)):
f = gf.solve()
formulars.append(" ".join(i for i in f) + " = ")
results.append(cf.solve(f))

self.formulars=formulars
self.results=results
self.displayFormular()

def displayFormular(self):
frame = wx.Frame(parent=None, title="计算界面", size=(500,500))
self.panel = wx.Panel(frame, -1) # 生成面板

self.Column = 30
self.Row = 10
self.N =len(self.formulars)
self.i = 0

self.GetResult()

frame.Center()
frame.Show() # 显示
return True

def GetResult(self): #显示题目和答题文本框
if self.Column >= 800:
self.Row += 500
self.Column = 30
T_label=wx.StaticText(self.panel,-1,"第{}题:".format(self.i+1) + self.formulars[self.i],pos=(self.Row,self.Column)) #标签
T_text=wx.TextCtrl(self.panel,-1,pos=(self.Row+340,self.Column),size=(100,20), #输入框
style=wx.TE_PROCESS_ENTER)
self.T_text = T_text

self.Bind(wx.EVT_TEXT_ENTER, self.judgeResult, T_text)

def judgeResult(self,event): #判断正误
self.result = self.T_text.GetValue()
self.Column += 30
if self.result == self.results[self.i]:
flag = "正确 √ √ √"
else:
flag = "错误❌❌❌"

T_label=wx.StaticText(self.panel,-1," 正确答案:{} 回答{}"\
.format(self.results[self.i], flag),pos=(self.Row,self.Column))

self.i += 1
try:
if self.i <= self.N-1:
self.Column = self.Column+30
self.GetResult()
else:
End_label=wx.StaticText(self.panel,-1," ---------答题结束--------- ",pos=(self.Row, self.Column+50))
End_label.SetFont(wx.Font(12, wx.SWISS))
except Exception as e:
return True

if __name__ == '__main__':
app = MyApp() # 启动
app.MainLoop() # 进入消息循环

 

formula代码:

import random
import datetime
import argparse
import re
from fractions import Fraction

def OPT(up_limit=10, oper_num=2, oper_variety=4, has_fraction=True, be_negetive=False):
'''
* 设置参数

* @param up_limit {int} 操作数数值上限

* @param oper_num {int} 操作数个数

* @param oper_variety {int} 运算符种类

* @param has_fraction {bool} 是否带有分数

* @param be_negative {bool} 可否存在负数
'''
parse = argparse.ArgumentParser()
# 操作数数值上限
parse.add_argument('--up_limit', type=int, default=up_limit)
# 操作数个数
parse.add_argument('--oper_num', type=int, default=oper_num)
# 运算符种类
parse.add_argument('--oper_variety', type=int, default=oper_variety)
# 是否带有分数
parse.add_argument('--has_fraction', type=bool, default=has_fraction)
# 可否存在负数
parse.add_argument('--be_negative', type=bool, default=be_negetive)

return parse.parse_args(args=[])

class GeneralFormular:
'''
* 生成算式

* @param opt {OPT} 参数
'''
def __init__(self, opt):
self.opt = opt
# 定义运算符
self.operator = ['+', '-', '×', '÷']

# @profile
def catFormula(self, operand1, operator, operand2):
'''
* 连接算式

* @param operand1 {str} 操作数1

* @param opertor {str} 运算符

* @param operand2 {str} 操作数2

* @return {str}
'''

return "{}#{}#{}".format(operand1, operator, operand2)

# @profile
def getRandomIntOperand(self):
'''
* 返回随机整数操作数

* @return {int}
'''
return random.randint(0, self.opt.up_limit)

# @profile
def getRandomFractionOperand(self):
'''
* 返回随机分数操作数

* @return {str}
'''
# 生成两个整数,一个作为分子,一个作为分母
num01 = self.getRandomIntOperand()
num02 = self.getRandomIntOperand()
while num01 == num02 or num02==0:
num02 = self.getRandomIntOperand()
while num01 == 0:
num01 = self.getRandomIntOperand()

# 保证分数为真分数, 化简
if num01 < num02:
return Fraction(num01, num02).__str__()
else:
return Fraction(num02, num01).__str__()

# @profile
def getRandomOperator(self):
'''
* 返回随机运算符

* @return {str}
'''
index = random.randint(0, self.opt.oper_variety-1)
return self.operator[index]

# @profile
def getOriginFormular(self):
'''
* 生成整数源算式

* @return {list}
'''
# 通过self.opt.oper_num控制操作数个数,循环调用catFormula()方法构造算式
formular = self.getRandomIntOperand()
for i in range(self.opt.oper_num-1):
formular = self.catFormula(formular, self.getRandomOperator(), self.getRandomIntOperand())

# 去掉'÷0'
while(True):
if '÷#0' in formular:
formular = formular.replace('÷#0', '÷#' + str(self.getRandomIntOperand()))
else:
break
# 通过'#'分割生成列表
formular_list = formular.split('#')

return formular_list

# @profile
def insertBracket(self, formular_list):
'''
* 插入括号

* @param formular_list {list} 源算式列表

* @return {list}
'''
# print(formular)

# 若只包含+号 或 只有两个操作数 则不用加括号
if self.opt.oper_variety <= 2 or self.opt.oper_num == 2:
return formular_list
# 若不包含×÷ 则不用加括号
if '×' not in formular_list and '÷' not in formular_list:
return formular_list

# 存储添加括号的算式
new_formular_list = []

# flag表示是否已存在左括号,作用在于构造出一对括号
flag = 0

# 添加括号
while(len(formular_list) > 1):
oper = formular_list.pop(1)
# 若下一个符号为 + or - , 则插入括号
if oper == '-' or oper == '+':
if flag == 0:
new_formular_list.append("(")
flag = 1
new_formular_list.append(formular_list.pop(0))
new_formular_list.append(oper)
else:
new_formular_list.append(formular_list.pop(0))

if flag == 1:
new_formular_list.append(")")
flag = 0

new_formular_list.append(oper)
# print(operand_list, operator_list, new_formular)

new_formular_list.append(formular_list.pop(0))
if flag == 1:
new_formular_list.append(")")

return new_formular_list

# @profile
def replaceFraction(self, formular_list):
'''
* 带入分数

* @param formular_list {list} 源算式列表,可能包含括号

* @return {list}
'''

# 带入分数个数
fraction_num = 1
if self.opt.oper_num > 2:
fraction_num = (self.opt.oper_num - 1) / 2
index = random.randint(0, len(formular_list)-1)

interval = 1
while True:
if formular_list[index].isdigit():
break
elif formular_list[index - interval].isdigit():
index -= interval
break
elif formular_list[index + interval].isdigit():
index += interval
break
else:
interval += 1
formular_list[index] = self.getRandomFractionOperand()

return formular_list

# @profile
def solve(self):
'''
* 整合生成算式的后缀表达式,带括号

* @return {list}
'''
# 生成原生算式
ori_formular = self.getOriginFormular()
# 添加括号
bra_formular = self.insertBracket(ori_formular)
# 带入分数
if self.opt.has_fraction:
bra_formular = self.replaceFraction(bra_formular)

return bra_formular

class ComputeFormular:
'''
* 计算算式的值
'''
def __init__(self):
pass

# @profile
def getPostFormular(self, formular_list):
'''
* 中缀表达式转为后缀表达式

* @param formular_list {list} 中缀表达式

* @return {list}
'''
# 运算符优先级
priority = {'×': 3, '÷': 3, '+': 2, '-': 2, '(': 1}

# 运算符栈
operator_stack = []

# 后缀表达式
post_formular_list = []

# 中缀表达式转为后缀表达式
while formular_list:
char = formular_list.pop(0)
if char == '(':
operator_stack.append(char)
elif char == ')':
oper_char = operator_stack.pop()
while oper_char != '(':
post_formular_list.append(oper_char)
oper_char = operator_stack.pop()
elif char in '+-×÷':
while operator_stack and priority[operator_stack[-1]] >= priority[char]:
post_formular_list.append(operator_stack.pop())
operator_stack.append(char)
else:
post_formular_list.append(char)

# 若符号栈不为空则循环
while operator_stack:
post_formular_list.append(operator_stack.pop())

# print(post_formular)
return post_formular_list

# @profile
def compute(self, char, num01, num02):
'''
* 计算算式的值

* @param char {str} 运算符

* @param num01 {str} 第二个数字,可能为分数

* @param num02 {str} 第二个数字,可能为分数

* @return {str}
'''
if char == '+':
return (Fraction(num02) + Fraction(num01)).__str__()
elif char == '-':
return (Fraction(num02) - Fraction(num01)).__str__()
elif char == '×':
return (Fraction(num02) * Fraction(num01)).__str__()
elif char == '÷':
try:
return (Fraction(num02) / Fraction(num01)).__str__()
except Exception as e:
# print("Error: ", e)
return "NaN"

# @profile
def calcFormular(self, post_formular_list):
'''
* 计算算式的值

* @param post_formular_list {list} 后缀表达式

* @return {str}
'''
# 操作数栈
operand_stack = []

while post_formular_list:
char = post_formular_list.pop(0)
if char in '+-×÷':
result = self.compute(char, operand_stack.pop(), operand_stack.pop())
if result == "NaN":
return result
operand_stack.append(result)
else:
operand_stack.append(char)

return operand_stack.pop()

# @profile
def solve(self, formular):
'''
* 整合计算中缀表达式的值

* @param formular {list} 后缀表达式

* @return {str}
'''
# 转为后缀表达式
post_formular = self.getPostFormular(formular)
# 计算值
value = self.calcFormular(post_formular)

return value

代码截图

 

 

 

 

 

 

 

 

 本文代码借鉴一名作者(昵称:玩的三立方)的项目代码,

标签:formular,oper,return,self,四则运算,list,psp,wx
来源: https://www.cnblogs.com/1qwe/p/15339920.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有