首页 > 其他分享 >结对项目

结对项目

时间:2024-09-24 22:13:49浏览次数:3  
标签:结对 项目 self answers file expression generate def

所属课程 https://edu.cnblogs.com/campus/gdgy/CSGrade22-34
作业要求 https://edu.cnblogs.com/campus/gdgy/CSGrade22-34/homework/13230
作业目标 按照要求合作实现一个自动生成小学四则运算题目的命令行程序
成员1 于海洋3122004758
成员2 钟启腾3122004761

Github链接: https://github.com/hhai12345678/3122004758

1. PSP表格

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

2. 效能分析

3. 设计实现过程

3.1 要求分析

  • 输入参数:程序需要支持命令行参数 -n、-r、-e 和 -a。其中 -n 表示生成的题目数量,-r 表示数字范围,-e 和 -a 用于验证答案。

  • 题目生成

    • 数值范围受 -r 控制,支持自然数和真分数。
    • 题目中不能有负数结果,除法结果必须是分数。
    • 运算符最多出现 3 次。
  • 答案验证

    • 通过对比生成的答案文件与用户提供的答案文件,输出正确与错误的题目编号。

3. 2 实现步骤

  1. 处理命令行参数

  2. 题目生成

    • 随机生成操作数和运算符。

    • 检查运算符顺序是否符合规则。

    • 检查结果是否合法。

  3. 计算答案

  4. 文件输出

    • 题目输出到 Exercises.txt。

    • 答案输出到 Answers.txt。

  5. 答案验证

    • 读取用户提供的题目和答案文件。

    • 逐一对比,生成统计结果 Grade.txt。

3.3 使用方法

生成 10 个数值范围为 10 的题目:

python main.py -n 10 -r 10

验证题目和答案文件:

python main.py -e Exercises.txt -a Answers.txt

4. 代码说明

4.1 代码实现

Main.py代码

import argparse
import random
import fractions

# 定义生成题目所需的常量和函数
OPERATORS = ['+', '-', '*', '/']


def generate_fraction(max_denominator):
    denominator = random.randint(2, max_denominator)
    numerator = random.randint(1, denominator - 1)
    return fractions.Fraction(numerator, denominator)


def generate_operand(max_range):
    if random.choice([True, False]):
        return str(random.randint(1, max_range - 1))  # 避免出现0作为分母
    else:
        fraction = generate_fraction(max_range)
        return f"{fraction.numerator}/{fraction.denominator}"


def generate_expression(max_range, max_operators):
    num_operators = random.randint(1, max_operators)
    expression = generate_operand(max_range)
    for _ in range(num_operators):
        operator = random.choice(OPERATORS)
        operand = generate_operand(max_range)
        expression += f" {operator} {operand}"
    return expression


def calculate_expression(expression):
    try:
        # 将除法替换为分数形式计算
        tokens = expression.split()
        result = fractions.Fraction(tokens[0])

        for i in range(1, len(tokens), 2):
            operator = tokens[i]
            operand = fractions.Fraction(tokens[i + 1])

            if operator == '+':
                result += operand
            elif operator == '-':
                result -= operand
            elif operator == '*':
                result *= operand
            elif operator == '/':
                result /= operand  # 保证除法结果为分数
        return result
    except ZeroDivisionError:
        return None


def generate_exercise(num_exercises, max_range, max_operators):
    exercises = []
    answers = []
    while len(exercises) < num_exercises:
        expression = generate_expression(max_range, max_operators)
        result = calculate_expression(expression)
        if result is not None:
            exercises.append(expression)
            answers.append(
                f"{result.numerator}/{result.denominator}" if result.denominator != 1 else str(result.numerator))
    return exercises, answers


def write_to_file(filename, lines):
    with open(filename, 'w', encoding='utf-8') as file:
        for line in lines:
            file.write(line + '\n')


def read_file(filename):
    with open(filename, 'r', encoding='utf-8') as file:
        return [line.strip() for line in file]


def check_answers(exercise_file, answer_file):
    exercises = read_file(exercise_file)
    answers = read_file(answer_file)
    correct_indices = []
    wrong_indices = []

    for index, (exercise, user_answer) in enumerate(zip(exercises, answers), start=1):
        correct_answer = calculate_expression(exercise)
        correct_answer_str = f"{correct_answer.numerator}/{correct_answer.denominator}" if correct_answer.denominator != 1 else str(
            correct_answer.numerator)
        if user_answer == correct_answer_str:
            correct_indices.append(index)
        else:
            wrong_indices.append(index)

    return correct_indices, wrong_indices


def write_grades(correct, wrong):
    with open('Grade.txt', 'w', encoding='utf-8') as file:
        file.write(f"Correct: {len(correct)} ({', '.join(map(str, correct))})\n")
        file.write(f"Wrong: {len(wrong)} ({', '.join(map(str, wrong))})\n")


def main():
    parser = argparse.ArgumentParser(description="Generate and check elementary arithmetic problems.")
    parser.add_argument('-n', type=int, help="Number of exercises to generate.")
    parser.add_argument('-r', type=int, help="Range of numbers in exercises.")
    parser.add_argument('-e', type=str, help="Exercise file to check answers.")
    parser.add_argument('-a', type=str, help="Answer file to check answers.")

    args = parser.parse_args()

    if args.n and args.r:
        exercises, answers = generate_exercise(args.n, args.r, 3)
        write_to_file('Exercises.txt', exercises)
        write_to_file('Answers.txt', answers)
        print(f"Generated {args.n} exercises with answers.")
    elif args.e and args.a:
        correct, wrong = check_answers(args.e, args.a)
        write_grades(correct, wrong)
        print("Checked answers and wrote grades to Grade.txt.")
    else:
        parser.print_help()


if __name__ == "__main__":
    main()

测试单元代码

import random
import unittest
import fractions
from io import StringIO
import sys
from main import (generate_fraction, generate_operand, generate_expression,
                              calculate_expression, generate_exercise, write_to_file, read_file,
                              check_answers)


class TestMathExercise(unittest.TestCase):

    def test_generate_fraction(self):
        fraction = generate_fraction(10)
        self.assertTrue(isinstance(fraction, fractions.Fraction))
        self.assertGreaterEqual(fraction.denominator, 2)
        self.assertGreaterEqual(fraction.numerator, 1)





    def test_generate_expression(self):
        random.seed(0)  # 固定随机种子保证生成结果一致
        expression = generate_expression(10, 3)
        self.assertTrue(any(op in expression for op in ['+', '-', '*', '/']))

    def test_calculate_expression_addition(self):
        expression = "1/2 + 1/2"
        result = calculate_expression(expression)
        self.assertEqual(result, fractions.Fraction(1, 1))

    def test_calculate_expression_subtraction(self):
        expression = "3/4 - 1/4"
        result = calculate_expression(expression)
        self.assertEqual(result, fractions.Fraction(1, 2))

    def test_calculate_expression_multiplication(self):
        expression = "2/3 * 3/4"
        result = calculate_expression(expression)
        self.assertEqual(result, fractions.Fraction(1, 2))

    def test_calculate_expression_division(self):
        expression = "2/3 / 4/5"
        result = calculate_expression(expression)
        self.assertEqual(result, fractions.Fraction(10, 12))

    def test_generate_exercise(self):
        exercises, answers = generate_exercise(5, 10, 3)
        self.assertEqual(len(exercises), 5)
        self.assertEqual(len(answers), 5)

    def test_check_answers(self):
        exercises = ["1/2 + 1/2", "3/4 - 1/4", "2/3 * 3/4", "2/3 / 4/5"]
        answers = ["1", "1/2", "1/2", "5/6"]

        # 模拟写入和读取文件
        with open('Exercises.txt', 'w') as f_ex:
            f_ex.write('\n'.join(exercises))

        with open('Answers.txt', 'w') as f_ans:
            f_ans.write('\n'.join(answers))

        correct, wrong = check_answers('Exercises.txt', 'Answers.txt')
        self.assertEqual(correct, [1, 2, 3, 4])
        self.assertEqual(wrong, [])

    def test_write_to_file(self):
        data = ["1 + 1", "2 - 2", "3 * 3", "4 / 4"]
        write_to_file("TestOutput.txt", data)

        read_back = read_file("TestOutput.txt")
        self.assertEqual(data, read_back)

    def test_read_file(self):
        data = ["5 + 5", "6 - 6"]
        write_to_file("TestRead.txt", data)
        read_back = read_file("TestRead.txt")
        self.assertEqual(data, read_back)


if __name__ == '__main__':
    unittest.main()

4.2 详细说明

  • generate_fraction: 生成随机真分数。

  • generate_operand: 生成随机操作数,可以是自然数或真分数。

  • generate_expression: 根据给定的操作符数量生成一个表达式。

  • calculate_expression: 计算生成的表达式的结果,如果有除以零等非法操作,返回 None。

  • generate_exercise: 根据给定数量和范围生成不重复的题目和答案。

  • write_to_file: 将生成的题目或答案写入文件。

  • read_file: 从文件读取题目或答案。

  • check_answers: 对比题目文件和答案文件,输出正确和错误的编号。

  • write_grades: 将对错题目编号写入文件 Grade.txt。

5. 测试运行

6. 实际运行结果

7. 项目小结

  • 在本次项目中,我们加深了对 Python语言理解和掌握。

  • 通过设计和实现一个具有特定功能的程序——从需求分析到设计,再到代码实现和测试,我们经历了完整的软件开发流程,积累了宝贵的实践经验。

  • 我们学会了共同沟通,共同思考得出解决方法,提高了通过团队解决问题的能力。

标签:结对,项目,self,answers,file,expression,generate,def
From: https://www.cnblogs.com/guazai/p/18430187

相关文章

  • 医学数据分析实训 项目八 医疗保险欺诈行为分析
    文章目录综合实践一:医疗保险欺诈行为分析一分析目标二实现步骤三数据准备四特征工程五模型训练六性能度量七提交要求代码块三数据准备4特征工程六、模型训练和性能度量综合实践一:医疗保险欺诈行为分析实践项目概述本实践项目的数据集包括:投保人信息(Poli......
  • 结对项目
    结对项目这个作业属于哪个课程计科22级12班这个作业要求在哪里个人项目这次作业的目标完成一个论文查重的个人项目github仓库地址Github仓库地址团队成员团队成员学号肖睿3122004921麦麦提萨力江·卡西木31220049151、PSPPSP2.1Pers......
  • 项目实战:Qt+OSG爆破动力学仿真三维引擎测试工具v1.1.0(加载.K模型,子弹轨迹模拟动画,支持
    需求  1.使用osg三维引擎进行动力学模型仿真性能测试;  2.打开动力学仿真模型文件,.k后缀的模型文件,测试加载解析过程;  3.解决第三方company的opengl制作的三维引擎,绘制面较多与弹丸路径模拟较卡顿的问题;  4.测试时,使用的模型为公开模型,基础面数量达到160多万个;  5.测......
  • 结对项目
    一、作业信息Github仓库地址:https://github.com/guzhouyiye/MathFormulaGenerator这个作业属于哪个课程软件工程这个作业要求在哪里结对项目这个作业的目标实现一个自动生成小学四则运算题目的命令行程序姓名学号陈国金3122004301廖俊龙3118005......
  • 如何在django项目中启动websocket服务
    首先下载redis,windows上要下5.0以上的版本,链接为:Releases·tporadowski/redis(github.com)紧接着python要安装redis,channls以及daphne,asgi_redis然后在settings中配置 必须放在第一行,以及channlesWSGI_APPLICATION="start_up_file_km.wsgi.application"ASGI_APPLICATI......
  • 基于SSM的选题管理系统(有报告)。Javaee项目。
    演示视频:基于SSM的选题管理系统(有报告)。Javaee项目。项目介绍:采用M(model)V(view)C(controller)三层体系结构,通过Spring+SpringMvc+Mybatis+Jsp+Maven来实现。MySQL数据库作为系统数据储存平台,实现了基于B/S结构的Web系统。系统设计思想一个成功的网站应明确......
  • Office project 2019安装图文安装教程下载项目管理
    不仅可以快速、准确地创建项目计划,而且可以帮助项目经理实现项目进度、成本的控制、分析和预测,使项目工期大大缩短,资源得到有效利用,提高经济效益。是专案管理软件程序由微软开发销售。软件设计目的在于协助专案经理发展计划、为任务分配资源、跟踪进度、管理预算和分析工作量。......
  • 微服务项目部署
    将微服务部署到云服务器是微服务架构中的常见操作,以下是三种常见的部署方式:使用SpringBoot内嵌Tomcat、Docker容器化、和外部Tomcat部署。1.使用SpringBoot内嵌Tomcat部署这是SpringBoot微服务最常用、也是最简单的部署方式。SpringBoot项目内置了Tomcat......
  • 结对项目:生成四则运算
    个人项目——论文查重这个作业属于哪个课程计科12班这个作业的要求在哪里作业要求这个作业的目标实现一个自动生成小学四则运算题目的命令行程序github链接:github题目需求使用-n参数控制生成题目的个数,例如Myapp.exe-n10将生成10个题目。使用-......
  • 使用通义灵码,参与开源项目全程纪实
    作者:shuipin100-34561背景缘起OceanBase。作为一个充满好奇心的DBA,一直一来想探寻数据库的内部世界。开源为我们这些好奇的猫打开了一扇新世界的大门。OceanBase作为分布式关系型数据库的排头兵,自然进入了我的优选名单。起初走进了OceanBase[1]的世界逛了一圈,这对于一个......