首页 > 编程语言 >软件工程(结对编程项目)

软件工程(结对编程项目)

时间:2023-09-25 20:33:22浏览次数:48  
标签:formular 结对 题目 算式 编程 list 软件工程 answer arithmetic

Github作业链接

成员:刘鸿杰 林程星

软件工程 计科21级4班
作业要求 作业3要求连接
作业目标 实现四则运算题目的命令行程序

PSP表格

PSP2.1 ersonal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 10 10
· Estimate · 估计这个任务需要多少时间 10 10
Development 开发 200 188
· Analysis · 需求分析 (包括学习新技术) 15 20
· Design Spec · 生成设计文档 8 6
· Design Review · 设计复审 3 3
· Coding Standard · 代码规范 (为目前的开发制定合适的规范) 3 3
· Design · 具体设计 25 30
· Coding · 具体编码 116 100
· Code Review · 代码复审 10 6
· Test · 测试(自我测试,修改代码,提交修改) 20 20
Reporting 报告 15 12
· Test Repor · 测试报告 6 6
· Size Measurement · 计算工作量 3 3
· Postmortem & Process Improvement Plan · 事后总结, 并提出过程改进计划 6 3
· 合计 225 210

需求描述

题目:实现一个自动生成小学四则运算题目的命令行程序

  1. 使用 -n 参数控制生成题目的个数
  2. 使用 -r 参数控制题目中数值(自然数、真分数和真分数分母)的范围,该参数必须给定,否则程序报错并给出帮助信息
  3. 生成的题目中计算过程不能产生负数,也就是说算术表达式中如果存在形如e1− e2的子表达式,那么e1≥ e2
  4. 生成的题目中如果存在形如e1÷ e2的子表达式,那么其结果应是真分数
  5. 每道题目中出现的运算符个数不超过3个
  6. 程序一次运行生成的题目不能重复,即任何两道题目不能通过有限次交换+和×左右的算术表达式变换为同一道题目,生成的题目存入执行程序的当前目录下的Exercises.txt文件
  7. 在生成题目的同时,计算出所有题目的答案,并存入执行程序的当前目录下的Answers.txt文件
  8. 程序应能支持一万道题目的生成
  9. 程序支持对给定的题目文件和答案文件,判定答案中的对错并进行数量统计,统计结果输出到文件Grade.txt

需求分析

题目分析

  • 使用参数控制生成题目个数和数值范围

  • 作业要求生成四则运算式,运算符最多三个,不能出现负数,分数必须是真分数,题目不能重复

  • 将生成的算式,答案,判题结果都存储到文件中,支持一万道题目生成

涉及到程序参数获取,随机数生成,字符串拼接,数值校验,文件I/O流操作等,本次作业采用python完成,使用到argparse参数解析,re正则匹配,random随机数生成,Fraction分数计算

思路分析

  1. 使用随机数生成运算符个数和操作数,同时判断运算符为减号时,不能出现负数;运算符为除号时,不能出现假分数;将操作数和运算符拼接,并在随机位置插入括号,这样就可生成算式
  2. 计算算式的值时,先将运算符转换为计算机能识别的运算符,使用正则表达式匹配操作数使用Fraction类将操作数分数化,便于结果的输出表示,再调用eval函数计算算式的答案
  3. 使用文件I/O流将算式和答案按要求的格式保存到指定文件中,当要校对答案时,将题目文件和答卷文件进行读取,将标准答案与输入答案比对,计算答对信息和答错信息保存到指定成绩文件中

流程分析

详细设计

  • 设计一个算式类Arithmetic,包含两个静态方法generate_arithmetic,calculate_arithmetic,分别用于生成算式,计算答案,在初始化方法里生成具体算式,对应答案,并赋值给formula,result属性
  • 为了保存算式和答案,读取算式和答案,保存成绩信息,设计write_exercises,write_answer,read_exercises,read_answer,write_grade五个函数
  • 设计exercises函数,实例化Arithmetic对象,根据题目数量和数值范围要求得到算式和答案,调用write_exercises,write_answer函数保存算式和答案
  • 设计correct_answer函数,调用read_exercises函数和read_answer函数读取题目文件和答卷文件,调用Arithmetic类的静态方法calculate_arithmetic来计算答案,与答卷文件中的答案比对,统计答对与答错的信息,调用write_grade函数将统计结果保存到指定文件中
  • 最后为了使用接收命令行参数实现功能,创建两个文件main_exercises和main_correct,使用argparse来解析命令行参数,然后分别调用moudle文件中的exercises函数和correct_answer函数,分开实现生成四则运算式和校对答案获取成绩信息两个大功能

关键代码

关键代码在于Arithmetic类,含有两个静态方法,generate_arithmetic和calculate_arithmetic,用于生成四则运算式和计算算式答案,主要运用到随机数生成,字符串拼接,正则表达式匹配等

# Arithmetic 算数类
class Arithmetic:
    def __init__(self, r):
        try:
            if not isinstance(r, int) or r < 0:
                raise TypeError
        except TypeError:
            print("输入的参数范围值必须是自然数")
        self.result = -1
        while self.result < 0:
            self.formula = self.generate_arithmetic(r)
            try:
                self.result = self.calculate_arithmetic(self.formula)
            except ZeroDivisionError:
                continue

    @staticmethod
    def generate_arithmetic(r):
        """
        :param r: 数字上限
        :return: 字符串:算式
        """
        num_operator = random.randint(1, 3)
        operator_list = []
        for _ in range(num_operator):
            idx = random.randint(0, 3)
            operator = '+-×÷'
            operator_list.append(operator[idx])
        operator_list.append('=')

        # 生成运算数
        number_list = []
        for i in range(num_operator + 1):
            number = random.randint(0, r)
            if i != 0:
                if operator_list[i - 1] == '-':
                    number = random.randint(0, int(number_list[i - 1]))
                elif operator_list[i - 1] == '÷':
                    if number_list[i - 1] == 0:
                        number = random.randint(1, r)
                    else:
                        number = random.randint(int(number_list[i - 1]), r)

            number_list.append(number)
        # 加括号
        idx_left_bracket = random.randint(0, len(number_list) - 2)

        arithmetic = []
        for i in range(len(number_list)):
            if i == idx_left_bracket and num_operator > 1:
                arithmetic.append('( ' + str(number_list[i]) + ' ' + operator_list[i] + ' ')
            elif i == idx_left_bracket + 1 and num_operator > 1:
                arithmetic.append(str(number_list[i]) + ' ) ' + operator_list[i] + ' ')
            else:
                arithmetic.append(str(number_list[i]) + ' ' + operator_list[i] + ' ')

        arithmetic = ''.join(arithmetic)

        return arithmetic

    @staticmethod
    def calculate_arithmetic(formula):
        """
        :param formula: string:算式
        :return: Fraction对象:答案
        """
        # 将符号替换成python能识别的运算符
        formula = formula.replace('=', '')
        formula = formula.replace('×', '*')
        formula = formula.replace('÷', '/')
        formula = formula.replace(' ', '')

        # 使用正则表达式将所有数字转换为Fraction类型,便于分数计算,再使用eval()函数计算字符串内的表达式
        res = eval(re.sub(r'(\d+)', r'Fraction(\1)', formula))

        return res

性能分析

性能分析主要包含对main_exercises.py和main_correct.py两个文件进行执行时间的分析,主要消耗在哪个函数或哪个模块,然后才能清楚性能瓶颈在哪,方便后期能够升级改进

  • 首先分析main_exercises.py文件,该文件main方法主要是进行命令函参数解析,然后调用moudle中exercises函数根据指定范围生成默认10道题目,然后将题目和答案写入文件中

通过分析发现时间主要花费在moudle文件中的exercises函数,指定生成10000道题目,花费时间为1279ms,花费时间主要在calculate_arithmetic方法上,为642ms,执行eval表达式计算答案花费其中443ms

  • 接着分析main_correct.py文件,该文件main方法主要是进行命令函参数解析,然后调用moudle中correct_answer函数读取题目文件和答卷文件,然后进行校对,统计答对和答错的信息,最后将成绩写入到指定文件中

通过分析发现时间主要花费在moudle文件中的correct_answer函数,测试时读取10000道题目和答案进行校对,且花费时间为569ms,花费时间主要在calculate_arithmetic函数,为404ms

测试运行

单元测试

为了对程序功能进行较为全面的测试,本次项目设计了10个测试用例,检测代码的健壮性,对程序实现进行较为全面的评估,从不同角度,不同函数进行测试分析

  1. test_arithmetic_parameters:测试生成算式时参数范围不是自然数

        # 测试生成算式时参数范围不是自然数
        def test_arithmetic_parameters(self):
            modules.Arithmetic(-2)
    
  2. test_generate_formular:测试生成10条算式是否符合要求

    # 测试生成10条算式是否符合要求
        def test_generate_formular(self):
            for _ in range(10):
                formular = modules.Arithmetic.generate_arithmetic(8)
                print(formular)
    
  3. test_generate_enough_formular:测试能否生成一万条算式

    # 测试能否生成一万条算式
        def test_generate_enough_formular(self):
            for _ in range(10000):
                formular = modules.Arithmetic.generate_arithmetic(10)
                print(formular)
    
  4. test_answer_express:测试文件内容分词效果

    # 测试计算的答案表示是否符合要求
        def test_answer_express(self):
            formular = '3 + 6 ÷ 7 ='
            answer = modules.Arithmetic.calculate_arithmetic(formular)
            print(formular, "", answer)
    
  5. test_formular_answer:测试生成算式后计算的答案是否正确

    # 测试生成算式后计算的答案是否正确
        def test_formular_answer(self):
            for _ in range(10):
                formular = modules.Arithmetic.generate_arithmetic(8)
                answer = modules.Arithmetic.calculate_arithmetic(formular)
                print(formular, " ", answer)
    
  6. test_write_file:测试将生成的题目和答案写入指定文件

    # 测试将生成的题目和答案写入指定文件
        def test_write_file(self):
            formular_list = []
            answer_list = []
            for _ in range(10):
                arithmetic = modules.Arithmetic(10)
                formular_list.append(arithmetic.formula)
                answer_list.append(arithmetic.result)
            modules.write_exercises(formular_list)
            modules.write_answer(answer_list)
    
  7. test_read_not_exist_file:测试读取的题目文件和答案文件不存在

    # 测试读取的题目文件和答案文件不存在
        def test_read_not_exist_file(self):
            formular_list = modules.read_exercises("train.txt")
            answer_list = modules.read_answer("result.txt")
            print(formular_list)
            print(answer_list)
    
  8. test_read_file:测试将题目文件和答案文件进行读取

    # 测试将题目文件和答案文件进行读取
        def test_read_file(self):
            formular_list = modules.read_exercises("Exercises.txt")
            answer_list = modules.read_answer("Answer.txt")
            print(formular_list)
            print(answer_list)
    
  9. test_exercises:测试生成算式和计算相应答案,并写入到指定文件

    # 测试生成算式和计算相应答案,并写入到指定文件
        def test_exercises(self):
            modules.exercises(10, 10)
    
  10. test_correct_answer:测试校对答案

    # 测试校对答案
        def test_correct_answer(self):
            modules.correct_answer("Exercises.txt", "Answer.txt")
    

测试结果

10个单元测试全部执行成功,全部花费时间为11.608s,其中test_generate_enough_formular单元测试为生成一万条算式,花费时间为11.579s

代码覆盖率

由于在文件I/O流等部分需要捕获处理异常,所以代码覆盖率为以上所显示

项目总结

  1. 结对编程体现了沟通交流,思想灵感碰撞的魅力与无限创新可能,在项目中互相讨论,提出自己的思路见解,不断完善设计规划,锻炼了沟通的能力,体现了协作交流的重要性
  2. 结对编程体现了合作的关键性,在项目经过需求分析和详细设计后,要进入真正实现的过程,对于程序的推进,需要明确各自的目标,尽可能达到最优的实现方案,完成负责的模块,提高开发效率
  3. 为完成项目需求,需要分析具体的实现方式来解决遇到的难题,学习新的思维模式,采用相关技术克服难题,在这个过程锻炼了逻辑思维,提升了编程能力

标签:formular,结对,题目,算式,编程,list,软件工程,answer,arithmetic
From: https://www.cnblogs.com/Lhj-develop/p/17728792.html

相关文章

  • 如何在低代码平台中应用可视化编程
    可视化编程,亦即可视化程序设计:以“所见即所得”的编程思想为原则,力图实现编程工作的可视化,即随时可以看到结果,程序与结果的调整同步。可视化编程的理念来源于可视化技术,它指的是一种把计算机程序中的文本指令转换为用户可以完全理解和操作的图形化界面。传统上,用户通过文本编程来......
  • 《软件工程:一种实践方法》读后感一
    《软件工程:一种实践方法》是由RogerS.Pressman所著的一本著名的软件工程教科书。该书系统地介绍了软件工程的理论、方法和实践,是软件工程领域的经典之作。阅读完这本书后,你可能会对软件工程的以下方面有了更深的理解和认识:1.软件开发过程模型:书中介绍了各种软件开发过程模型,如......
  • 软件工程测试--hive数据分析,步骤
    下面这里的语句在上一个博客里有需要的伙伴可以去找......
  • 结对项目:实现自动生成小学四则运算题目
    这个作业属于哪个课程计科21级12班这个作业要求在哪里结对项目这个作业的目标熟悉结对项目的的合作方法与模式团队成员信息姓名学号刘晋延3121004832张建文3121004845PSP表格PSP2.1PersonalSoftwareProcessStages预估耗时(分钟)实际......
  • Spring 04 SpringAOP 切面编程
    Aop:面向切面,在不修改代码的前提下对方法进行增强 pom.xml<dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.2.10.RELEASE</version>......
  • Windows网络编程(一)
    一、WSAStartup函数WSAStartup是Windows套接字API中的一个函数,它用于初始化Winsock库,这是Windows中用于网络编程的库。使用Winsock,您可以创建客户端和服务器应用程序,以便它们能够通过网络进行通信。函数的原型如下:intWSAStartup(WORDwVersionRequested,......
  • 结对项目:用Python实现四则运算
    这个作业属于哪个课程计科1/2班这个作业要求在哪里结对项目这个作业的目标实现一个自动生成小学四则运算题目的命令行程序团队成员姓名学号梁昊东3121005000李铭伟3121004145github链接:https://github.com/e1ecb0t/e1ecb0t/tree/main/cacul......
  • 编程笔记·开篇
    2023年9月,经过一夜的辗转难眠,最后在一个清晨,我坐上了久违的地铁......
  • 多线程实现实例-简单的聊天小程序TCP编程尝试
    运用TCP编程,实现一个从客户端到服务端多线程聊天的功能。 获取信息线程的代码Get.javapackagecom.xyq.HW;importjava.io.BufferedReader;importjava.io.InputStream;importjava.io.InputStreamReader;importjava.net.Socket;publicclassGetextendsThread{......
  • 第三周Linux教材第十章学习笔记——sh编程
    第十章——sh编程sh脚本1.sh脚本是一种为shell编写的脚本程序。这个程序用纯文本文件,将一些shell的语法与命令(含外部命令)写在里面,搭配正则表达式、管道命令与数据流重定向等功能。第一行必须为#!/bin/sh2.命令行使用chmod+x <filename>编译后才能用./filename来运行。3.......