zoukankan      html  css  js  c++  java
  • 小学四则运算改进版

    小学四则运算改进版

    软件工程第四周作业 —— 四则运算改进

    1. 项目要求

    1.1 要求阐述

      在上一次作业的基础上进行一次升级,如下,至少选择一个升级方向:

    • 功能升级
    • 性能升级
    • 界面升级
    • 使用不同语言升级

    1.2 详细要求【易知大学

    2. 项目成果

    2.1 当前版本:2.0

    2.2 GitHub代码【GitHub

    2.3 相比1.0版本改进之处

    • 改进了进入界面
    • 增加输入模式的错误判断
    • 增加输出模式:直接输出、问答模式、文件模式
    • 弃用字符串而使用列表存放算式
    • 改进中缀表达式的生成方式
    • 改进中缀表达式转换后缀表达式的方法
    • 改进后缀表达式的计算方法

    3. PSP表格

    PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
    Planning 计划 15 15
    + Estimate + 估计这个任务需要多少时间 15 15
    Development 开发 235 255
    + Analysis + 需求分析 (包括学习新技术) 25 30
    + Design Spec + 生成设计文档 20 25
    + Design Review + 设计复审 (和同事审核设计文档) 20 15
    + Coding Standard + 代码规范 (为目前的开发制定合适的规范) 25 25
    + Design + 具体设计 15 10
    + Coding + 具体编码 60 75
    + Code Review + 代码复审 25 20
    + Test + 测试(自我测试,修改代码,提交修改) 45 45
    Reporting 报告 85 80
    + Test Report + 测试报告 35 35
    + Size Measurement + 计算工作量 25 25
    + Postmortem & Process Improvement Plan + 事后总结, 并提出过程改进计划 25 20
    合计 335 350

    4. 代码示例

    4.1 ComputeFormular.getPostFormular()方法

    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
    

    4.2 ComputeFormular.compute()方法

    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"
    

    4.3 ComputeFormular.calcFormular()方法

    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()
    

    5. 单元测试

    import unittest
    from formula import OPT, GeneralFormular, ComputeFormular
    
    class FormulaUnitTest(unittest.TestCase):
        def test_gf_catFormular(self):
            '''
             * 测试拼接算式
            '''
            gf = GeneralFormular(OPT())
            self.assertEqual(gf.catFormula("12", "+", "34"), "12#+#34")
            self.assertEqual(gf.catFormula("23", "+", "456"), "23#+#456")
            self.assertEqual(gf.catFormula("12", "+", "32"), "12#+#32")
    
        def test_cf_getPostFormular(self):
            '''
             * 测试中缀表达式转为后缀表达式
            '''
            cf = ComputeFormular()
            self.assertEqual(cf.getPostFormular(['3', '+', '7']), ['3', '7', '+'])
            self.assertEqual(cf.getPostFormular(['3', '×', '(', '7', '+', '2', '+', '1', ')']), ['3', '7', '2', '+', '1', '+', '×'])
            self.assertEqual(cf.getPostFormular(['6', '×', '(', '2', '+', '1', ')', '÷', '(', '9', '-', '2', '+', '3', ')']), ['6', '2', '1', '+', '×', '9', '2', '-', '3', '+', '÷'])
            self.assertEqual(cf.getPostFormular(['6', '×', '(', '2', '+', '1', ')', '÷', '0']), ['6', '2', '1', '+', '×', '0', '÷'])
    
        def test_cf_calcFormular(self):
            '''
             * 测试后缀表达式计算为数值
            '''
            cf = ComputeFormular()
            self.assertEqual(cf.calcFormular(['3', '7', '+']), "10")
            self.assertEqual(cf.calcFormular(['3', '7', '2', '+', '1', '+', '×']), "30")
            self.assertEqual(cf.calcFormular(['6', '2', '1', '+', '×', '9', '2', '-', '3', '+', '÷']), "9/5")
            self.assertEqual(cf.calcFormular(['6', '2', '1', '+', '×', '0', '÷']), "NaN")
    
        def test_cf_compute(self):
            '''
             * 测试计算算式的值
            '''
            cf = ComputeFormular()
            self.assertEqual(cf.compute('+', '29', '0'), '29')
            self.assertEqual(cf.compute('-', '19', '0'), '-19')
            self.assertEqual(cf.compute('×', '99', '0'), '0')
            self.assertEqual(cf.compute('÷', '9', '0'), '0')
            self.assertEqual(cf.compute('÷', '0', '9'), 'NaN')
            self.assertEqual(cf.compute('÷', '0', '0'), 'NaN')
            self.assertEqual(cf.compute('+', '1/4', '3/8'), '5/8')
    
    
    if __name__ == "__main__":
        unittest.main()
    

    单元测试

    6. 性能分析

    6.1 GeneralFormular.solve()

    6.2 ComputeFormular.calcFormular()

    6.3 ComputeFormular.solve()

    7. 100万次运行

    生成算式 计算算式
    version 1.0 0:00:49 0:01:26
    version 2.0 0:00:37 0:01:20

      从表格来看,改进后的性能差别不是很大,但还是有一小点点的提升。

    8. 运行测试

    8.1 包含加减乘除、包含分数、直接输出模式

    8.2 包含加减、问答模式


    8.3 包括加减乘、文件模式


    8.4 测试错误输入

  • 相关阅读:
    SQL Server 查看正在运行的事务信息的 2 种方法。
    SQL Server 查看正在运行的事务信息的 2 种方法。
    js防抖和限流
    js防抖和限流
    CSS cursor 属性
    CSS cursor 属性
    JS-中使用Math.round(x)保留1位小数点
    I/O系列教材 (一)- Java 的File类,以及常用方法
    异常处理系列教材 (五)- Java 自定义异常
    异常处理系列教材 (四)- java Throwable接口
  • 原文地址:https://www.cnblogs.com/bpf-1024/p/13739401.html
Copyright © 2011-2022 走看看