结对项目

这个作业属于哪个课程 https://edu.cnblogs.com/campus/gdgy/CSGrade22-34/
这个作业要求在哪里 https://edu.cnblogs.com/campus/gdgy/CSGrade22-34/homework/13230
这个作业的目标 编程开发结对项目,实现项目单元测试
成员一 3122004755杨睿
成员二 3122004960木萨江·米吉提

github链接
https://github.com/rayrain13/pair-project

psp表格

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

性能分析



通过效能分析得,占用时间最长的是generateProblems方法,主要用于生成指定数量的数学问题,并且确保不重复。

流程图

接口设计和实现


主类ArithmeticProblemGenerator,测试类ArithmeticProblemGeneratorTest
主类中包括:
主方法main:接受命令行参数,以决定生成问题或批改练习。解析输入参数,调用相应的方法。
Fraction类:表示分数,包含分子和分母。提供加、减、乘、除等运算方法,确保分数简化为最简形式。包含与其他分数比较大小的方法以及格式化为字符串的方法。
Expression类:表示一个算术表达式,包括一个Fraction值和其字符串表示。
generateProblems:生成指定数量的独特问题,并将其写入文件。

代码说明

Fraction分数类:用于表示分数并进行基本的四则运算。
Fraction 类:
包含两个属性:numerator(分子)和 denominator(分母)。
构造函数:
接受分子和分母作为参数。
检查分母是否为零,如果为零则抛出异常。
通过调用 gcd 方法计算分子和分母的最大公约数,以简化分数。
如果分母为负,则将分子和分母同时取反,以保持分数的标准形式(分母为正)。

static class Fraction {
        int numerator;
        int denominator;

        public Fraction(int numerator, int denominator) {
            if (denominator == 0) {
                throw new IllegalArgumentException("Denominator cannot be zero");
            }
            int gcd = gcd(Math.abs(numerator), Math.abs(denominator));
            this.numerator = numerator / gcd;
            this.denominator = denominator / gcd;
            if (this.denominator < 0) {
                this.numerator = -this.numerator;
                this.denominator = -this.denominator;
            }
        }

        private static int gcd(int a, int b) {
            return b == 0 ? a : gcd(b, a % b);
        }

        public Fraction add(Fraction other) {
            int newNumerator = this.numerator * other.denominator + other.numerator * this.denominator;
            int newDenominator = this.denominator * other.denominator;
            return new Fraction(newNumerator, newDenominator);
        }

        public Fraction subtract(Fraction other) {
            int newNumerator = this.numerator * other.denominator - other.numerator * this.denominator;
            int newDenominator = this.denominator * other.denominator;
            return new Fraction(newNumerator, newDenominator);
        }

        public Fraction multiply(Fraction other) {
            return new Fraction(this.numerator * other.numerator, this.denominator * other.denominator);
        }

        public Fraction divide(Fraction other) {
            if (other.numerator == 0) {
                throw new ArithmeticException("Cannot divide by zero");
            }
            return new Fraction(this.numerator * other.denominator, this.denominator * other.numerator);
        }

generateProblems 方法用于生成指定数量的数学问题并确保它们的唯一性。
初始化:
创建一个 Set 用于存储唯一问题(uniqueProblems)。
创建两个 List 分别用于存储生成的问题(problems)和答案(answers)。
循环生成问题:
使用 while 循环,直到生成的问题数量达到 count。
调用 generateExpression(range, MAX_OPERATORS) 方法生成一个随机表达式(expr)。
构建问题字符串 problem,格式为 expr.repr + " = "。
确保唯一性:
检查 uniqueProblems 中是否已包含该问题。
如果未包含,则将问题添加到 uniqueProblems、problems 和答案列表 answers 中。
写入文件:
调用 writeToFile("Exercises.txt", problems) 将生成的问题写入文件。
调用 writeToFile("Answers.txt", answers) 将对应的答案写入文件。

 static void generateProblems(int count, int range) {
        Set<String> uniqueProblems = new HashSet<>();
        List<String> problems = new ArrayList<>();
        List<String> answers = new ArrayList<>();

        while (problems.size() < count) {
            Expression expr = generateExpression(range, MAX_OPERATORS);
            String problem = expr.repr + " = ";

            if (!uniqueProblems.contains(problem)) {
                uniqueProblems.add(problem);
                problems.add(problem);
                answers.add(expr.value.toString());
            }
        }

        writeToFile("Exercises.txt", problems);
        writeToFile("Answers.txt", answers);
    }

单元测试

测试函数:

import org.junit.Test;

import java.util.List;

import static junit.framework.Assert.assertEquals;
import static org.junit.jupiter.api.Assertions.*;

public class ArithmeticProblemGeneratorTest {

    @Test
    public void testFractionAddition() {
        ArithmeticProblemGenerator.Fraction f1 = new ArithmeticProblemGenerator.Fraction(1, 2);
        ArithmeticProblemGenerator.Fraction f2 = new ArithmeticProblemGenerator.Fraction(1, 3);
        ArithmeticProblemGenerator.Fraction result = f1.add(f2);
        assertEquals("5/6", result.toString());
    }

    @Test
    public void testFractionSubtraction() {
        ArithmeticProblemGenerator.Fraction f1 = new ArithmeticProblemGenerator.Fraction(1, 2);
        ArithmeticProblemGenerator.Fraction f2 = new ArithmeticProblemGenerator.Fraction(1, 3);
        ArithmeticProblemGenerator.Fraction result = f1.subtract(f2);
        assertEquals("1/6", result.toString());
    }

    @Test
    public void testFractionMultiplication() {
        ArithmeticProblemGenerator.Fraction f1 = new ArithmeticProblemGenerator.Fraction(1, 2);
        ArithmeticProblemGenerator.Fraction f2 = new ArithmeticProblemGenerator.Fraction(2, 3);
        ArithmeticProblemGenerator.Fraction result = f1.multiply(f2);
        assertEquals("1/3", result.toString());
    }

    @Test
    public void testFractionDivision() {
        ArithmeticProblemGenerator.Fraction f1 = new ArithmeticProblemGenerator.Fraction(1, 2);
        ArithmeticProblemGenerator.Fraction f2 = new ArithmeticProblemGenerator.Fraction(2, 3);
        ArithmeticProblemGenerator.Fraction result = f1.divide(f2);
        assertEquals("3/4", result.toString());
    }

    @Test
    public void testGenerateExpression() {
        ArithmeticProblemGenerator.Expression expr = ArithmeticProblemGenerator.generateExpression(10, 2);
        assertNotNull(expr);
        assertNotNull(expr.value);
        assertFalse(expr.repr.isEmpty());
    }

    @Test
    public void testGenerateProblems() {
        ArithmeticProblemGenerator.generateProblems(5, 10);
        List<String> exercises = ArithmeticProblemGenerator.readFile("Exercises.txt");
        List<String> answers = ArithmeticProblemGenerator.readFile("Answers.txt");

        assertEquals(5, exercises.size());
        assertEquals(5, answers.size());
    }

    @Test
    public void testEvaluateExpression() {
        String expression = "(1/2 + 1/3)";
        ArithmeticProblemGenerator.Fraction result = ArithmeticProblemGenerator.evaluateExpression(expression);
        assertEquals("5/6", result.toString());
    } 
}

测试结果:
Excercises.txt

Answers.txt

覆盖率:

项目小结

木萨江:我们充分发挥了各自的优势取长补短,提高了项目完成的质量。但是在项目初期,由于沟通不畅,我们浪费了一些时间在重复的工作上。在项目执行过程中,我们要合理安排时间,确保各项工作按时完成。总之,本次结对项目使我们受益匪浅。我们相信,在今后的工作中,我们会更好地运用本次项目的经验,不断提高自己的能力,实现共同成长。
杨睿:在此次结对项目中,我们通过密切合作完成了项目任务,提升了问题分析和解决能力。结对编程促进了双方的沟通与协调,减少了错误的发生,同时相互学习对方的长处,共同提高了代码质量和开发效率。这次合作为今后的项目开发奠定了良好的基础。

posted @ 2024-09-25 13:20  kairosr  阅读(38)  评论(0编辑  收藏  举报