zoukankan      html  css  js  c++  java
  • psp下的四则运算

    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

    代码截图

     

     

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

  • 相关阅读:
    local 不能解析为127.0.0.1
    完全使用接口方式调用WCF 服务
    【人生】自己对于求职应聘的一些感受
    OO的经典例子
    剪刀、石头、布机器人比赛
    TextTree 文本资料收集轻量级工具
    两个代替重复输入的小工具
    桌面助手 Desktop Helper 自动帮你关闭指定的窗口
    磁盘可用空间平衡
    用C#制造可以继承的“枚举”
  • 原文地址:https://www.cnblogs.com/1qwe/p/15339920.html
Copyright © 2011-2022 走看看