• 软件工程第五次作业--四则运算


    题目

       (1)能自动生成小学四则运算题目;

       (2)能支持任意分数的四则运算;

       (3)能支持任意括号运算

    思路

      根据参数生成不定长度的表达式,以及能控制是否生成分数,能生成任意数量的中缀表达式,支持四则运算,括号运算以及分数运算

      构造函数接口  def __init__(self, exps_num=10, num_l=1, num_r=10, exp_limit_len=10, has_fraction=True)

      提供接口生成中缀表达式,返回表达式数据集   def create_express(self)

      提供接口将中缀表达式化为后缀表达式  def get_postfix(self, exp)

      提供接口将后缀表达式进行计算并返回结果  def cal_express(self, exp)

      提供接口以用户友好方式显示中缀表达式  def get_showExp(self, exp)


    源代码
    # -*- coding: utf-8 -*-
    # author: 'boliang'
    # date: 2018/4/18 21:04

    import profile
    import random
    from fractions import Fraction

    class Solution(object):
    def __init__(self, exps_num=10, num_l=1, num_r=10, exp_limit_len=10, has_fraction=True):
    self.__exps_num = exps_num
    self.__has_fraction = has_fraction
    self.__exp_limit_len = exp_limit_len
    self.__num_l = num_l
    self.__num_r = num_r

    # 生成中缀表达式
    def create_express(self):
    exps = []
    num = self.__exps_num
    while num > 0:
    num_len = random.randint(2, self.__exp_limit_len)
    tmp_len = num_len - 1
    exp = [self.__get_num(self.__has_fraction)]
    while tmp_len > 0:
    # 1为+,2为-,3为*,4为/
    op_flag = random.randint(1, 4)
    if op_flag == 1:
    exp.append('+')
    elif op_flag == 2:
    exp.append('-')
    elif op_flag == 3:
    exp.append('*')
    else:
    exp.append('/')
    exp.append(self.__get_num(self.__has_fraction))
    tmp_len -= 1

    brackets = random.randint(0, int(len(exp)/8))
    while brackets > 0:
    if self.__set_bracket(exp, num_len):
    brackets -= 1

    exps.append(exp)
    num -= 1

    return exps


    def __set_bracket(self, exp, num_len):
    index_a = 0
    index_b = 0
    while index_a == index_b:
    rec = list(map(lambda x:random.randint(0, num_len-1), range(2)))
    index_a = min(rec) + 1
    index_b = max(rec) + 1

    cal = 0
    length = len(exp)
    for i in range(length):
    if type(exp[i]) != type('+'):
    cal += 1

    if cal == index_a:
    if i+1 <= length and exp[i+1] == ')':
    return False
    exp.insert(i, '(')

    cal = 0

    for i in range(len(exp)):
    if type(exp[i]) != type('+'):
    cal += 1

    if cal == index_b:
    if i-1 >= 0 and exp[i-1] == '(':
    return False
    exp.insert(i+1, ')')
    break

    return True

    # 生成一个数, 包括分数
    def __get_num(self, has_fraction=True):

    # 生成包括有分数
    if has_fraction:
    # 80%几率为整数
    flag = random.randint(1, 10)
    if flag <= 8:
    return self.__get_num(False)
    else:
    return Fraction(self.__get_num(False), self.__get_num(False))
    # 生成整数
    else:
    return random.randint(self.__num_l, self.__num_r)

    # 计算后缀表达式
    def cal_express(self, exp):
    record = []
    for val in exp:
    if type(val) == type('+'):
    b = record.pop(-1)
    a = record.pop(-1)
    if val == '+':
    record.append(a+b)
    elif val == '-':
    record.append(a-b)
    elif val == '*':
    record.append(a*b)
    else:
    record.append(a/b)
    else:
    record.append(val)

    return record[0]

    # 通过中缀表达式得到后缀表达式
    def get_postfix(self, exp):
    l_ops = {
    '(': 1, '*': 5, '/': 5,
    '+': 3, '-': 3, ')': 6
    }

    r_ops = {
    '(': 6, '*': 4, '/': 4,
    '+': 2, '-': 2, ')': 1
    }

    op_stack = []
    post_stack = []
    for val in exp:
    if type(val) != type('+'):
    post_stack.append(val)
    elif len(op_stack) > 0:
    while len(op_stack) > 0 and l_ops[op_stack[-1]] >= r_ops[val]:
    if op_stack[-1] != '(' and op_stack[-1] != ')':
    post_stack.append(op_stack.pop(-1))
    else:
    op_stack.pop(-1)

    op_stack.append(val)
    else:
    op_stack.append(val)

    while len(op_stack) > 0:
    if op_stack[-1] != '(' and op_stack[-1] != ')':
    post_stack.append(op_stack.pop(-1))
    else:
    op_stack.pop(-1)

    return post_stack


    def get_showExp(self, exp):
    op = {'+': '+', '-': '-', '*': '×', '/': '÷', '(':'(', ')':')'}
    jud_fun = lambda val: str(val) if type(val) != type('+') else op[val]
    return ' '.join(map(jud_fun, exp))


    # 测试函数
    def test():
    # 1. 测试程序自动生成10组表达式数据(包括分数和括号运算)
    # 2. 测试通过中缀表达式计算得到后缀表达式
    # 3. 根据后缀表达式计算结果(包括分数)

    # 设置接口参数
    # 表达式个数
    express_num = 10
    # 生成的数的下界
    num_l = 1
    # 生成的数的上界
    num_r = 10
    # 表达式的数字个数
    exp_limit_len = 10
    # 是否会生成分数
    has_fraction = True

    sol = Solution(express_num, num_l, num_r, exp_limit_len, has_fraction)

    # 生成中缀表达式
    exps = sol.create_express()


    for ind, exp in enumerate(exps):
    print('.......................................')
    print('第{0}条表达式:{1}'.format(ind+1, exp))
    tmp = sol.get_postfix(exp)
    print('后缀表达式为:{0}'.format(tmp))
    print('用户界面中显示的表达式:{0}'.format(sol.get_showExp(exp)))
    print('运算结果为:{0}'.format(sol.cal_express(tmp)))
    print('.......................................')


    if __name__ == '__main__':
    profile.run('test()')

    根据单元测试,测试结果如下

    效能分析, 运用Python profile库

    PSP表格

      预计耗时(分钟) 是实际耗时(分钟)
    Planning 计划 10 10
    Estimate 估计这个任务需要多少时间 100 100
    Development 开发 120 240
    Analysis 需求分析 5 10
    Design Spec 生成设计文档 3 23
    Design Review 设计复审(和同事审核设计文档) 2 2
    Coding Standerd 代码规范(为目前的开发制定合适的规范) 3 3
    Design 具体设计 5 10
    Coding 具体编码 30 60
    Code Review 代码复审 5 10
    Text 测试(自测,修改代码,提交修改) 10 30
    Reporting 报告 10 20
    Text Report 测试报告 10 20
    Size Measurement 计算工作量 5 5
    Postmortem & Process Improvement Plan 事后总结,并提出过程改进计划 5 5
    Sum 合计 215 420
     
  • 相关阅读:
    MapReduce实例
    hadoop 分布式安装
    redis缓存
    Flink初始
    Flume初始
    大数据学习之路(持续更新中...)
    使用VisualVM分析性能
    JVM的理解
    Java日记
    UI笔记2
  • 原文地址:https://www.cnblogs.com/lbliang/p/8878753.html
Copyright © 2020-2023  润新知