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

结对对对项目

时间:2024-09-17 23:12:52浏览次数:11  
标签:结对 题目 questions 项目 答案 const document Math

结对对对项目

这个作业属于哪个课程 软件工程课程
这个作业要求在哪里 个人项目 - 作业 - 计科22级34班 - 班级博客 - 博客园 (cnblogs.com)
这个作业的目标 按照要求写一个四则运算生成器
成员一 3122004883许億驰

任务列表

[x] 1. 实现命令行程序

  • 创建一个命令行程序,能够生成小学四则运算题目。

[x] 2. 支持参数控制

  • 使用 -n 参数控制生成题目的个数。
  • 使用 -r 参数控制题目中数值的范围。
  • 该参数必须给定,否则程序报错并给出帮助信息。

[x] 3. 确保计算过程无负数

  • 生成的题目中计算过程不能产生负数。
  • 如果存在形如 e1 - e2 的子表达式,那么 e1 ≥ e2

[x] 4. 确保除法结果为真分数

  • 生成的题目中如果存在形如 e1 ÷ e2 的子表达式,那么其结果应是真分数。

[x] 5. 限制运算符个数

  • 每道题目中出现的运算符个数不超过3个。

[x] 6. 确保题目不重复

  • 程序一次运行生成的题目不能重复。
  • 任何两道题目不能通过有限次交换 +× 左右的算术表达式变换为同一道题目。

[x] 7. 生成题目文件

  • 生成的题目存入执行程序的当前目录下的 Exercises.txt 文件。
  • 真分数在输入输出时采用特定格式(如 3/52’3/8)。

[x] 8. 生成答案文件

  • 在生成题目的同时,计算出所有题目的答案,并存入执行程序的当前目录下的 Answers.txt 文件。
  • 真分数的运算结果应符合规范。

[x] 9. 支持题目数量

  • 程序应能支持一万道题目的生成。

[x] 10. 支持答案校验

  • 程序支持对给定的题目文件和答案文件,判定答案中的对错并进行数量统计。
  • 输入参数为 -e <exercisefile>.txt -a <answerfile>.txt
  • 统计结果输出到文件 Grade.txt,格式如下:
    Correct: 5 (1, 3, 5, 7, 9)
    Wrong: 5 (2, 4, 6, 8, 10)
    

作业正文

作业仓库地址

效能分析

性能分析中,代码执行时间最长的是

function generateQuestions() {
    const numQuestions = parseInt(document.getElementById('numQuestions').value, 10);


    questions = [];
    answers = [];
    const questionsDiv = document.getElementById('questions');
    questionsDiv.innerHTML = '';


    for (let i = 0; i < numQuestions; i++) {
      let question, answer;

      // 随机选择是否包含括号
      const hasBrackets = Math.random() > 0.5;

      if (hasBrackets) {
        question = generateExpressionWithBrackets();
      } else {
        question = generateSimpleExpression();
      }

      questions.push(question);

      // 计算答案
      answer = calculateAnswer(question);
      answers.push(answer);



      const questionElement = document.createElement('p');
      questionElement.innerText = `${i + 1}. ${question} =`;
      questionsDiv.appendChild(questionElement);
    }
  }

设计思路

设计思路是通过一个前端网页来生成、下载、上传和校验小学四则运算题目。以下是对你设计思路的详细解释:

  • 用户界面:
    创建一个包含输入框和按钮的网页界面,用户可以通过输入框设置生成题目的数量和数值范围。
    提供文件上传功能,用户可以上传包含答案和题目的文本文件。
    提供按钮用于生成题目、下载题目和答案、以及计算正确率。

  • 生成题目:
    用户输入生成题目的数量和数值范围。
    程序根据用户输入生成指定数量的四则运算题目,并显示在页面上。
    生成的题目可能包含括号和带分数。

  • 下载题目和答案:
    用户可以点击按钮下载生成的题目和答案,分别保存为 questions.txt 和 answers.txt 文件。
    上传答案和题目文件:
    用户可以上传包含答案和题目的文本文件。
    程序解析上传的文件,提取题目和答案,并显示在页面上。
    计算正确率:
    用户上传答案文件后,程序可以计算上传答案的正确率。
    程序将正确率和正确/错误的题目编号输出到 grade.txt 文件中。

  • 具体实现步骤
    生成题目:
    使用 generateQuestions 函数生成题目,根据用户输入的数量和数值范围生成题目。
    使用 generateSimpleExpression 和 generateExpressionWithBrackets 函数生成简单的和带括号的表达式。
    使用 generateNumber 函数生成自然数或带分数。
    计算答案:
    使用 calculateAnswer 函数计算表达式的答案。
    使用 convertToMathExpression 函数将带分数转换为浮点数以便计算。
    下载题目和答案:
    使用 downloadQuestions 和 downloadAnswers 函数将生成的题目和答案下载为文本文件。
    上传答案和题目文件:
    使用 parseAnswersFile 和 parseQuestionsFile 函数解析上传的答案和题目文件。
    提取文件内容并显示在页面上。
    计算正确率:
    使用 calculateAccuracy 函数计算上传答案的正确率。
    将正确率和正确/错误的题目编号输出到 grade.txt 文件中。
    代码结构
    HTML部分:
    包含输入框和按钮,用于设置生成题目的数量和数值范围,以及上传和下载文件。
    包含一个显示题目的容器。
    JavaScript部分:
    包含生成题目、计算答案、下载文件、上传文件和计算正确率的函数。
    使用 document.getElementById 获取页面元素,使用 FileReader 读取上传的文件。

代码说明

let questions = [];
  let answers = [];
  let userAnswers = [];
  function generateQuestions() {
    const numQuestions = parseInt(document.getElementById('numQuestions').value, 10);


    questions = [];
    answers = [];
    const questionsDiv = document.getElementById('questions');
    questionsDiv.innerHTML = '';


    for (let i = 0; i < numQuestions; i++) {
      let question, answer;

      // 随机选择是否包含括号
      const hasBrackets = Math.random() > 0.5;

      if (hasBrackets) {
        question = generateExpressionWithBrackets();
      } else {
        question = generateSimpleExpression();
      }

      questions.push(question);

      // 计算答案
      answer = calculateAnswer(question);
      answers.push(answer);



      const questionElement = document.createElement('p');
      questionElement.innerText = `${i + 1}. ${question} =`;
      questionsDiv.appendChild(questionElement);
    }
  }

  function generateSimpleExpression() {
    const num1 = generateNumber();
    const num2 = generateNumber();
    const operator = ['+', '-', '*', '/'][Math.floor(Math.random() * 4)];
    return `${num1} ${operator} ${num2}`;
  }

  function generateExpressionWithBrackets() {
    const num1 = generateNumber();
    const num2 = generateNumber();
    const num3 = generateNumber();
    const operator1 = ['+', '-', '*', '/'][Math.floor(Math.random() * 4)];
    const operator2 = ['+', '-', '*', '/'][Math.floor(Math.random() * 4)];
    return `(${num1} ${operator1} ${num2}) ${operator2} ${num3}`;
  }

  function generateNumber() {

    const numSetUp = parseInt(document.getElementById('numSetUp').value, 10);

    const isFraction = Math.random() > 0.5;
    if (isFraction) {
      const numerator = Math.floor(Math.random() * 10) + 1;
      const denominator = Math.floor(Math.random() * 10) + 1;
      return convertToMixedNumber(`${numerator}/${denominator}`);
    } else {
      return Math.floor(Math.random() * numSetUp).toString();
    }
  }

  function convertToMixedNumber(fraction) {
    const [numerator, denominator] = fraction.split('/').map(Number);
    const integerPart = Math.floor(numerator / denominator);
    const remainder = numerator % denominator;

    if (integerPart === 0) {
      return fraction;
    }else if (remainder ===0){
      return integerPart;
    } else {
      return `${integerPart}'${remainder}/${denominator}`;
    }
  }

  function calculateAnswer(expression) {
    // 使用 eval 计算表达式,注意 eval 的安全性问题
    try {
      return eval(convertToMathExpression(expression));
    } catch (e) {
      return 'Error';
    }
  }

  function convertToMathExpression(expression) {
    // 将带分数转换为浮点数
    return expression.replace(/(\d+)'(\d+)\/(\d+)/g, (match, p1, p2, p3) => parseFloat(p1) + parseFloat(p2) / parseFloat(p3));
  }

  function downloadQuestions() {
    if (questions.length === 0) {
      alert('请先生成题目!');
      return;
    }

    const questionsText = questions.map((q, i) => `${i + 1}. ${q}`).join('\n');
    const allText = `题目:\n${questionsText}\n`;

    const blob = new Blob([allText], { type: 'text/plain' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = 'questions.txt';
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    URL.revokeObjectURL(url);
  }

  function downloadAnswers() {
    if (answers.length === 0) {
      alert('请先生成题目!');
      return;
    }

    const answersText = answers.map((a, i) => `${i + 1}. ${a}`).join('\n');
    const allText = `答案:\n${answersText}\n`;

    const blob = new Blob([allText], { type: 'text/plain' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = 'answers.txt';
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    URL.revokeObjectURL(url);
  }


  function parseAnswersFile(file) {

    userAnswers = [];

    const reader = new FileReader();
    reader.onload = function(event) {
      const content = event.target.result;
      const lines = content.split('\n').map(line => line.trim()).filter(line => line);
      const answersText = lines.join('\n');
      userAnswers = answersText.replace(/^答案:\n/, '').split('\n').map(line => line.trim().split('. ')[1]).filter(line => line);

    };
    reader.readAsText(file);
  }

  function parseQuestionsFile(file) {

    questions = [];

    const reader = new FileReader();
    reader.onload = function(event) {
      const content = event.target.result;
      const lines = content.split('\n').map(line => line.trim()).filter(line => line);
      const answersText = lines.join('\n');
      questions = answersText.replace(/^题目:\n/, '').split('\n').map(line => line.trim().split('. ')[1]).filter(line => line);


      const questionsDiv = document.getElementById('questions');
      questionsDiv.innerHTML = '';

      // 显示题目
      questions.forEach((question) => {
        const questionElement = document.createElement('p');
        questionElement.innerText = `${question}=`;
        questionsDiv.appendChild(questionElement);
      });

      // 计算答案
      questions.forEach((question) => {
        const answer = calculateAnswer(question);
        answers.push(answer);
      });
    };
    reader.readAsText(file);
  }

  function calculateAccuracy(userAnswers) {

    let rightGrade = [];
    let wrongGrade = [];

    if (userAnswers.length === 0) {
      alert('请先上传答案文件!');
      return;
    }
    if (answers.length === 0) {
      alert('请先生成题目!');
      return;
    }
    let correctCount = 0;
    for (let i = 0; i < answers.length; i++) {
      if (parseFloat(userAnswers[i]) === answers[i]) {
        rightGrade.push(i + 1);
        correctCount++;
      }else {
        wrongGrade.push(i + 1);
      }
    }
    const accuracy = (correctCount / answers.length) * 100;
    alert(`正确率: ${accuracy.toFixed(2)}%`);


    grade = `正确题目:${rightGrade.join(', ')}\n错误题目:${wrongGrade.join(', ')}\n正确率: ${accuracy.toFixed(2)}%\n`;

    const blob = new Blob([grade], { type: 'text/plain' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = 'grade.txt';
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    URL.revokeObjectURL(url);
  }

测试运行

运行效果

PSP表格如下

2.在PSP表格[附录2]记录下你估计在程序开发各个步骤上耗费的时间

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

项目小结

  • 在本次结对编程项目中,我们共同开发了一个小学四则运算生成器。该程序能够生成指定数量和数值范围的四则运算题目,支持带分数和括号的表达式,并能够下载题目和答案文件,上传答案文件进行校验,计算正确率。

  • 结对编程能够提高代码质量,减少错误。两个人可以互相监督,及时发现和解决问题。

  • 结对编程能够提高开发效率,两个人可以分工合作,共同完成任务。

标签:结对,题目,questions,项目,答案,const,document,Math
From: https://www.cnblogs.com/crazylychee/p/18417720

相关文章

  • 开源项目dotnet/eshop 和 dotnet/eshopsupport
    dotnet/eshop[1]和dotnet/eshopsupport[2]是两个与.NET相关的开源项目,分别用于展示电子商务应用的不同方面。dotnet/eshop:功能与架构:dotnet/eshop是一个基于.NETAspire的参考电商应用,展示了服务架构在构建现代在线购物平台中的应用。项目涵盖产品目录、购物车和订单管理......
  • 【JDK8新特性】Stream API 结合Lambda语法在项目中的实战应用
    Lambda语法回顾在JDK8中,Lambda表达式支持的引用类型主要有以下几种,如表1所示。种类Lambda表达式示例对应的引用示例类名引用普通方法(x,y,...)->对象名x.类普通方法名(y,...)类名::类普通方法名类名引用静态方法(x,y,...)->类名.类静态方法名(x,y,...)......
  • 实景三维助力工程建设项目智慧选址
    随着科技的不断进步,实景三维技术已经成为城市规划和工程建设中不可或缺的一部分。它通过高精度的地理信息数据,为工程建设项目提供了智慧选址的新思路。1.实景三维技术简介实景三维技术,是一种利用遥感、地理信息系统(GIS)、三维建模等技术手段,将现实世界的地理信息......
  • 项目测试用例:
    项目概述该项目是一款网上点餐系统,满足普通商家和普通用户的基本需求,主要有两大功能模块,分别是管理员模块(商家端)和用户模块(客户端)。系统供管理员登录和普通用户,登录进去会有对应相关管理操作:商家端主要实现了对员工和菜品的增删改査以及订单相关数据的查看与分析,客户端基于......
  • 如何使用Maven将项目中的依赖打进jar包
    需求有时候写一些库,需要其它三方依赖,但是又不想这个依赖影响到使用方,可以将这些三方依赖打到自己的项目jar包,并且更换包名,避免冲突(更换包名之后,项目中的类引用第三方依赖的类import语句也会跟着变化)。如Mybatis就使用了Ognl库,在打包时把Ognl的所有类都打到了Mybatis自己的jar中......
  • 系统架构设计师教程 第5章 5.7 软件项目管理 笔记
    5.7软件项目管理★★☆☆☆5.7.1项目管理概述软件项目管理的对象是软件工程项目。它所涉及的范围覆盖了整个软件工程过程。为使软件项目开发获得成功,关键问题是必须对软件项目的工作范围、可能风险、需要资源(人、硬件/软件)、要实现的任务、经历的里程碑、花费工作量......
  • 网络编程速递小项目
    一.项目需求功能描述:仿照顺丰速运功能,实现一个自己的速递项目。自行定义项目名,最终可以提现到简历中服务器:处理客户端的请求,并将数据存入数据库中,客户端请求的数据从数据库进行获取,服务器转发给客户端。用户客户端:实现账号的注册、登录、注销、修改用户密码功能,当登录成......
  • 在远程的ubuntu服务器安装了rust环境,本地的windows上也安装了VSCode并且连接到了ubunt
    你已经在Ubuntu服务器上安装了Rust环境,并且在本地Windows上安装了VSCode并通过Remote-SSH扩展连接到了Ubuntu服务器。接下来,我将指导你如何在Ubuntu上创建一个Rust项目,并使用VSCode进行开发和调试。步骤1:在Ubuntu上创建Rust项目连接到Ubuntu服务器(......
  • Vue路由配置、网络请求访问框架项目、element组件介绍学习
    系列文章目录第一章基础知识、数据类型学习第二章万年历项目第三章代码逻辑训练习题第四章方法、数组学习第五章图书管理系统项目第六章面向对象编程:封装、继承、多态学习第七章封装继承多态习题第八章常用类、包装类、异常处理机制学习第九章集合学习第......
  • 基于Java+Vue+Mysql的人力资源管理系统:简单易用,高效协同(项目源码分享)
      前言:eHR(ElectronicHumanResources)人力资源管理系统是一个综合性的软件平台,用于管理组织的人力资源相关的各种活动和数据。该系统可以显著提高人力资源部门的工作效率,确保数据准确性和一致性,同时提供决策支持。以下是eHR人力资源管理系统的六个主要模块及其功能的简要介......