首页 > 编程语言 >HNU结对编程之队友代码互评

HNU结对编程之队友代码互评

时间:2023-09-19 22:44:32浏览次数:38  
标签:status index 结对 tree question 互评 HNU root 节点

一、前言

在本次互评中,我有幸审阅了zjx同学的项目。zjx同学的代码风格严谨,对于代码规范的遵循和对于项目需求的理解都让人印象深刻。以下是我对他的项目的评价和建议。

 

二、测试

1. 黑盒测试

我首先进行了黑盒测试,也就是从用户的角度,不考虑程序内部结构和属性,只关注程序的输入与输出结果。

(1) 账户管理功能测试

我首先测试了账户管理功能,这包括账户的登录与退出。我尝试创使用不同的用户名和密码进行登录,并尝试了账户退出。当输入错误时会有提示, 而且切换用户登录的功能也能正常工作。

2) 题目生成功能测试

接着,我测试了题目生成功能。这包括了不同难度、不同类型题目的生成。我设定了多种条件进行试验,无论是高中, 小学还是初中, 程序都能生成符合预期的题目。同时,对于不合法的生成条件(超出范围或切换范围错误),程序也能给出正确的错误提示。

生成的题目相当随机, 其中不乏一些根本做不出来的题目.

2. 白盒测试

接着,我进行了白盒测试,也就是从程序员的角度,考虑程序的内部逻辑结构和运行过程。由于zjx同学的代码量较大, 我只选择了最精髓的部分, 即Lex, sort, IsEquivalent

 

(1) "Lex"函数测试

Lex函数的目的是将输入的字符串 the_question 转换为一个 n-ary 树,类似于语法树。每个树节点代表 the_question 中的一个值或操作符。构建树的方式考虑了操作符的优先级和括号嵌套关系。

// Converts the string `the_question` into a n-ary tree, similar to a syntax tree.
// Each node in the tree represents a value or an operator from `the_question`.
// The tree is built in a way that respects the operator precedence and bracket nesting in `the_question`.
tree::nary_tree<TreeNode> Lex(string the_question) {
  int index=0,status=0,times=0;
  stack<int> status_stack;
  tree::nary_tree<TreeNode> result(TreeNode("root"));
  auto curr_root=result.GetRoot();
  while(++times<200) {
    string curr_word=NextOperator(status,the_question,index);
    if (curr_word=="") break;
    if (status>=0) index+=curr_word.size();
    else status=-status-1;
    if (curr_word==")") {
      SubLevel(0,status,curr_root,status_stack,false);
      if (GetNextWord(the_question,index)!="") 
        SubLevel(GetOperatorStatus(GetNextWord(the_question,index)), status, curr_root, 
                 status_stack, true);
    } else {
      string next_word=GetNextWord(the_question,index);
      index+=next_word.size();
      if (next_word[0]<0x30 || next_word[0]>0x39) {//complex
        int end_bracket_index=GetEndBracket(the_question,index);
        string end_string=GetNextWord(the_question,end_bracket_index);
        if (end_bracket_index==the_question.size() || 
            GetOperatorStatus(end_string)<=status) {
          curr_root=result.insert(curr_root,TreeNode(curr_word+next_word+")"));
          status_stack.push(status);
          if (the_question[index]!='-') status=-1;
        } else {
          AddLevel(result,curr_root,curr_word,status_stack,status,index,next_word);
        }
      } else {
        string undetermined_word=GetNextWord(the_question,index);
        int undetermined_status=GetOperatorStatus(undetermined_word);
        if (undetermined_word=="" || 
            undetermined_status==status || 
            undetermined_status==-1) {
          result.insert(curr_root,TreeNode(curr_word,std::stoi(next_word),kLeaf));
        } else if (undetermined_status<status) {
          result.insert(curr_root,TreeNode(curr_word,std::stoi(next_word),kLeaf));
          SubLevel(undetermined_status,status,curr_root,status_stack,false);
          status=GetOperatorStatus(undetermined_word);
        } else if (undetermined_status>status) {
          AddLevel(result,curr_root,curr_word,status_stack,status,index,next_word);
        }
      }
    }
  }
  return result;
}
View Code
  • 它会逐个读取输入表达式中的字符,分析它们是数字还是操作符。
  • 如果是操作符,它会将操作符放入树的适当位置,考虑到了操作符的优先级和括号的影响。
  • 如果是数字,它将数字也放入树中,确保树的结构正确反映了数学表达式的含义。

(2) "TestIfLegal"函数解析
函数 TestIfLegal 检查 the_question 是否适用于目前登录的用户。如果问题通过以下所有测试,则被视为适用:1. 操作符与用户所在年级相匹配。 2. 它不包含多个连续的 "^" 操作符。 3. 用户之前生成的题目没有包含它。 如果问题合法,则返回 true;否则返回 false。

bool TestIfLegal(Account* the_account,string the_question) {
  bool legal=TestIfHasEssentialOperator(the_account->GetType(),the_question);
  legal|=TestIfMultipleExp(the_question);
  legal|=TestIfDuplicated(the_account,(the_question[0]=='-')?the_question:("+"+the_question));
  return legal;
}

(3) "sort_tree"函数解析
sort_tree的目的是对以 root 为根的 n-ary 树的子树进行排序。排序的具体标准没有在函数签名中指定,而是取决于实际的实现。通常,这个函数用于重新排列树中的节点,以便更轻松地进行处理或更高效的计算。

void sort_tree(std::shared_ptr<tree::nary_tree<TreeNode>::Node<TreeNode>> root) {
  if (!root || root->value.GetType()==kLeaf) return;
  for (const auto& i:root->children) sort_tree(i);
  std::sort(root->children.begin(), root->children.end(), 
    [](const std::shared_ptr<tree::nary_tree<TreeNode>::Node<TreeNode>>& a,
      const std::shared_ptr<tree::nary_tree<TreeNode>::Node<TreeNode>>& b) {
      if (a->value!=b->value) {
        return a->value<b->value;
      } else {
        if (a->children.size()!=b->children.size())
          return a->children.size()<b->children.size();
        for (size_t i=0;i<a->children.size();++i) {
          if (a->children[i]->value!=b->children[i]->value)
            return a->children[i]->value<b->children[i]->value;
         }
        return false;
       }
    }
  );
}
View Code
  1. 首先,函数会检查根节点 root 是否存在且不是叶子节点。如果不存在或者是叶子节点,它将不做任何操作。

  2. 接着,它会递归地对所有子节点进行排序,确保整棵子树的节点都被处理。

  3. 最重要的部分是使用 std::sort 函数对子节点进行排序。排序规则由一个函数来定义,这个函数会比较两个节点,决定它们的顺序。

  4. 比较的规则是:首先,根据节点的值来排序,小的排在前面。如果节点的值相同,就比较它们子节点的数量,少的排在前面。如果子节点数量也相同,就逐个比较它们的子节点,直到找到不同的节点为止。

  5. 最终,这个函数会将树的子节点按照上述规则重新排列,使得整棵树按照一定的次序组织起来。

三、评价与建议

1. 代码风格和规范

zjx同学的代码风格严谨,遵循了Google的编码规范,包括行数要求、类的继承关系、函数注释、命名规则等。他的代码整洁有序,易于阅读和理解。

在注释方面,zjx同学还细心地为代码编译选项添加了注释:

/**

 * @file main.cpp

 * @brief This is the main file.

 *

 * This file uses UTF-8 encoding for the source code and GBK encoding

 * for the execution. When compiling, use the following options:

 * -finput-charset=UTF-8 -fexec-charset=GBK

 */

 

2. nary_tree.h文件

zjx同学编写的这个多叉树文件非常出色,他实现的模板类nary_tree功能强大,显示了他在数据结构和算法设计上的深厚功底。不愧是能手写编译器的人

3. 题目生成方式

zjx同学的题目生成方式新颖,他采用生成后判断合法的方式,真正做到了随机生成. 这种方式更加公平和随机,能够生成更多样化的题目。

虽然zjx同学的项目非常出色,但还有一些可以改进的地方:

zjx同学的main函数缺少退出程序的功能,这可能会在某些情况下导致程序难以结束。建议添加退出程序的功能。

四、总结

这次的互评过程让我对zjx同学的编程技能有了更深的认识。他在项目中展现出的代码规范性、创新性思维以及对需求的深入理解都让人印象深刻。尽管有些小的问题需要改进,但这都不影响他的项目整体质量。我希望这次的互评能对他有所帮助,也期待在未来的学习、工作中,我们能有更多的交流和学习。



标签:status,index,结对,tree,question,互评,HNU,root,节点
From: https://www.cnblogs.com/lwy20/p/17716050.html

相关文章

  • 个人项目互评代码分析
    个人项目互评代码分析软件2105-刘一凡在看完金颖希同学的代码后,我有了一些看法与建议,在这篇博客中将对她的代码进行分析,并提出一些建议性的优化方案。个人拙见,希望能为项目的进一步改进提供一些思路。整体结构:代码结构相对清晰,分为数学题生成器和用户两部分,其中每个数学题生成......
  • 个人项目互评
    一.整体分析:苏晨阳同学的代码包括了大量的类,大致分析如下:1.User类:这是一个抽象类,包含了用户的基本信息(name、password、authority)和一个设置用户权限的方法。其他用户类(如Teacher)可以继承这个类来共享属性和方法。2.Teacher类:这个类继承了User类,表示教师用户。它包含了各种方......
  • HNU个人项目互评——中小学数学卷子自动生成程序
    结对编程互评代码作者:软件2104潘胜蓝互评作者:软件2104苏晨阳一、摘要该作业是由潘胜蓝同学使用Java语言完成的“中小学数学卷子自动生成程序”。在代码设计方面,对小学教师、初中教师、高中教师三种角色属性进行了抽象提取,利用java抽象类和继承的优点进行编写;通过自行编......
  • HNU个人项目互评:中小学数学卷子自动生成程序
    一、功能测试1.登录功能命令行输入用户名与密码,当用户名与密码都正确时,显示当前为XX出题 正常输入时功能正常,但是当只输入用户名时发生了异常,应该是没有考虑只输入一个(没有测试bug呀!)Stringstr[]=in.nextLine().split("\\s+");nuser.setName(str[0]);......
  • 个人项目互评
    软件2103桑健康队友李明胜功能测试登录模块需求:系统提示“准备生成XX数学题目,请输入生成题目数量(输入-1将退出当前用户,重新登录):”,XX为小学、初中和高中三个选项中的一个,用户输入所需出的卷子的题目数量,系统默认将根据账号类型进行出题。每道题目的操作数在1-5个之间,操作数取......
  • 个人项目互评
    本博客为湖南大学2021级软件工程导论课程的结对小组个人项目互评。根据本课程“做中学”的要求,我们第一周完成了个人项目代码,现在结对完成代码互评。编程语言:C++结对成员:顾问、郑雨凡文章作者(评价人):顾问代码作者:郑雨凡一、个人项目要求:用户:小学、初中和高中数学老师......
  • HNU个人项目中小学数学卷子自动生成程序互评
    一、简介本博客是对结对编程队友代码的分析与总结,代码使用语言为JAVA。完成情况:很好的实现了项目的需求,功能完整。同时每个页面的提示信息都比较完整,在不需要他人协助的情况下,可以根据屏幕上的提示信息进行操作,如果用户输入不正确,系统会出现指示,显示正确输入格式,用户可根据提示......
  • 【HNU 个人项目互评】结对编程互评-Java
    【结对编程互评-Java】中小学数学卷子自动生成程序项目名称:中小学数学卷子自动生成程序编程语言:Java代码作者:张钉评价人:张诗泉目录1项目要求1.1目标用户1.2实现功能2代码分析3功能测试3.1登录功能测试3.2出题功能测试3.3保存与查重功能测试4优缺......
  • 个人项目互评
    这两天完成了和谢文琛同学的个人项目作业互评。一.功能测试: 能够正常登录各用户且出题符合要求小学难度: 初中难度: 高中难度: 切换难度可以正常实现 输入-1后退出到登录界面 二.优点:1.首先非常完整地实现了系统所需要的功能,生成题目也符合要求。    ......
  • hnu个人编程项目评价
    一、简介1.项目名称:中小学数学卷子自动生成程序2.编程语言:JAVA3.完成情况:按照个人项目需求完成了要求的功能4.完成同学:朱智星,评价者:杨安然5.项目需求:5.1、命令行输入用户名和密码,两者之间用空格隔开(程序预设小学、初中和高中各三个账号,具体见附表),如果用户名和密码都正确,将根......