• 结对编程-四则运算(挑战出题)


    结对编程-四则运算(挑战出题)

    过去两周,大家都对四则运算有了一定概念,完成了出题、判题。
    接下来我们在现有的工作基础上继续做一些挑战:只出题,不判题

    描述

    小明(又是小明:D)目前在一家企业从事软件开发。过年回到老家,顺便看望自己的小学恩师林老师,时光飞逝,当年走路带风的林老师已经是头发花白,就快要退休了,目前还在教数学课。小明同林老师聊天交流这些年的见闻,林老师的日常则没有大风大浪,孜孜不倦地教导学生一年又一年,但是有个烦恼:几乎每一年都会遇上几个计算能力特别好的学生,他们喜欢计算题目,而且记忆力好,还能经常发现自己做过某些题目。因此林老师在出题上可谓是伤透了脑筋,重复的工作费时费力,让小明帮想想有没有什么更好的方法。小明眼睛一亮,一拍大腿,嘿~这不正是我擅长的么!

    小明说道:“我帮您写个软件,在电脑上运行就可以随机生成题目,省去您的烦恼。”

    林老师皱皱眉头:“前几年上面组织过培训如何使用电脑,这主意听起来好像也不错,不过……我这里没电脑可以用啊!”

    小明抬头想了几秒:“对,手机!我给您做个手机app也可以。”

    林老师从口袋里掏出手机:“你看我这诺基亚3310可以吗?”

    小明挠头:“这不好办呀……有了,我回家写个程序,直接在自己电脑上帮您生成1万道题目,保证不重复,应该可以用到我下次回家,那时候再帮您重新生成。”

    林老师:“这主意不错。那小明同学,拜托了,你可算帮了我大忙!”

    小明说干就干,开始分析需求,跟林老师沟通后,得出以下几点:

    • 每次生成的题目不能有重复

      • 题目去重-引用自:http://www.cnblogs.com/jiel/p/4810756.html

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

        例如:

        • 23 + 4545 + 23 是重复的题目
        • 6 * 88 * 6 也是重复的题目
        • 3 + (2 + 1)1 + 2 + 3 这两个题目是重复的
          • 由于+是左结合的,1 + 2 + 3 等价于(1 + 2) + 3,也就是 3 + (1 + 2),也就是3 + (2 + 1)
        • 但是1 + 2 + 33 + 2 + 1是不重复的两道题
          • 因为1 + 2 + 3等价于(1 + 2) + 3,而3 + 2 + 1等价于(3 + 2) + 1,它们之间不能通过有限次交换变成同一个题目
    • 要能指定生成题目的数量

    • 要能指定题目包含的运算符数量

    输入

    通过命令行参数形式指定题目要求

    输出

    输出题目到文件,一行一个题目

    输入示例

    $ java ExpressionGenerator 10000 5 expressions.txt
    
    • ExpressionGenerator 为最终执行的类(包含main函数)
    • 第一个参数 10000 代表需要生成的题目数量
    • 第二个参数 5 代表每个题目需包含的运算符数量(除括号以外的运算符数量)
    • 第三个参数 expressions.txt 代表存放生成题目的文件名

    输出示例

    查看 expressions.txt,部分内容如下:

    ...
    7 - 8 * 9 / 1 + 2 - 3
    4 * 5 / 6 + 7 - 8 * 9
    1 / 2 + 3 - 4 * 5 / 6
    7 / 8 + 9 - 1 * 2 / 3
    ...
    

    特别说明

    • 可执行的入口类必须为 ExpressionGenerator,方便后续验证
    • 参数顺序必须遵守以上 输入示例 说明,方便后续验证
    • 输出格式必须遵守以上 输出示例 说明,方便后续验证
    • 为了减小随机空间,体现出去重功能:
      • 操作数为个位整数,即选择范围只能是:1,2,3,4,5,6,7,8,9这9个数字
      • 操作符选择范围只能是:+,-,*,/, 还有括号

    要求

    • 此次作业请在http://git.oschina.net/上新建一个仓库提交代码,并且在博客中给出仓库连接(代码托管)
    • 请将所有需要的参与编译的.java文件都放在该仓库的根目录,如:
    ProjectDir
    ├── ExpressionGenerator.java
    ├── ...
    └── Other.java
    
    • 结对编程的两位同学须各自发表博客

    • 博客需描述各环节的输出,如:

      • 需求分析(描述自己对需求的理解,以及后续扩展的可能性
      • 设计思路(同时输出UML类图
      • 实现过程中的关键代码解释
      • 测试方法
      • 运行过程截图
      • 代码托管地址
      • 遇到的困难及解决方法
    • 对结对的小伙伴做出评价(重点指出需要改进的地方

    • 博客内容中如需展示两人的共同成果,请进行说明

    • 如有参考或引用的设计、实现,请进行说明

    • PSP

      • 实现之前先在PSP中预估时间

      • 实施后各个环节实际花费多少时间也请做记录

      • 表中有一项: Estimate 指的“预估”这个活动,“预估时间”也是一项任务。

        • 例如:我估计自己需要花30分钟来估算出整个项目需要多少时间完成,结果我花了20分钟估算出整个项目需要6个小时完成。Estimate这一项应该在“预估耗时”填写30分钟,实际耗时填写“20”分钟。
      • 一级和二级活动的包含关系:

        • Planning 这个一级活动包含了1个二级活动(Estimate)
        • Development 这个一级活动包含了8个二级活动
        • Reporting 这个一级活动包含了3个二级活动
      • 大家在记录时间的时候, 只用记录二级活动, 然后把总数加了, 就是相应的一级活动的时间

      • 这个时间的长短并不会对分数有直接影响,这是为了大家自己总结。

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

    打分细则

    最终提交的代码将会被拉取执行,通过传入不同参数进行测试,测试包括:

    • 记录程序运行耗时

    • 验证最终结果的正确性(即是否有重复的题目)

    • 程序得分数将根据耗时,重复率计算得出(共65分)

      • 程序不符合以上定义的输入输出,即不能使用工具进行正常测试,0分
      • 生成题目重复率,根据题目重复率映射至10~45分
      • 生成题目耗时,根据平均耗时映射至5~20分
      • 测试以下情况(详见下文 测试工具):
        • 仅能完成至生成10题的,以上得分打1折
        • 仅能完成至生成30题的,以上得分打2折
        • 仅能完成至生成100题的,以上得分打4折
        • 仅能完成至生成1000题的,以上得分打6折
        • 仅能完成至生成10000题的,以上得分打8折
        • 完成至20000题的,以上得分不打折
    • 博客(共35分)

      • 基础分(按时提交)5分
      • PSP表格 5分
      • 需求分析 5分
      • 设计思路 5分
      • 实现过程中的关键代码解释 5分
      • 遇到的困难及解决方法 5分
      • 对结对小伙伴做出评价 5分
    • 为自己的队友打分 (在博客中说明)

      • 这里有独立的100分供分配
        • 例如:一人如果得70分,另一人只能得30分
      • 要求不能均分(即不能每人50分)
      • 打分要给出依据,依据可以有:
        • 代码提交记录
        • 设计文档
        • 测试

    约定

    • 博客中说明代码结构,并指明如何编译(提供编译命令)
    • 如果博客不说明,评分老师根据自己经验猜测执行(编译不通过的后果由自己承担)
    • 以作业截止日期的线上代码版本为准
    • 编译不通过 0分
    • 不严格遵守题目输入输出 0分
    • 运行过程有崩溃,能得分的项目得分减半
    • 如遇特殊环境问题,可在成绩公布至次日凌晨截止时间内提出复查
    • 复查一般仅接受处理环境差异带来的问题
    • 复查原则上不对新提交的功能代码进行评分
    • 结对编程、团队项目中Git代码提交不能是一个人(要看到所有人的贡献),贡献可以是代码、设计、文档和测试

    参考示例

    以下是一份简单的题目生成示例(生成题目没进行去重,不够随机,也无括号,需要同学们自行动手设计实现满足以上要求的程序):

    import java.util.Random;
    import java.io.IOException;
    import java.io.FileWriter;
    
    public class ExpressionGenerator {
        public static void main(String[] args) throws IOException {
            if (args.length != 3) {
                System.err.println("java ExpressionGenerator <number-of-expressions> <number-of-operator> <output-file-path>");
                System.exit(1);
            }
    
            int expr_num = Integer.parseInt(args[0]);
            int optr_num = Integer.parseInt(args[1]);
            String file_path = args[2];
    
            String digits = "123456789";
            String operators = "+-*/";
    
            Random rnd = new Random();
            StringBuffer expr = new StringBuffer();
            FileWriter fw = new FileWriter(file_path);
    
            int r1 = rnd.nextInt(100);
            for (int i = 0; i < expr_num; ++i) {
                expr.append(digits.charAt(++r1 % 9));
                int r2 = rnd.nextInt(100);
                for (int j = 0; j < optr_num; ++j) {
                    expr.append(' ');
                    expr.append(operators.charAt(++r2 % 4));
                    expr.append(' ');
                    expr.append(digits.charAt(++r1 % 9));
                }
                expr.append('
    ');
                fw.write(expr.toString());
                expr.delete(0, expr.length());
            }
            fw.close();
        }
    }
    

    执行:

    > java ExpressionGenerator 10 5 1.txt
    

    在文件 1.txt中输出:

    4 - 5 * 6 / 7 + 8 - 9
    1 * 2 / 3 + 4 - 5 * 6
    7 + 8 - 9 * 1 / 2 + 3
    4 * 5 / 6 + 7 - 8 * 9
    1 - 2 * 3 / 4 + 5 - 6
    7 - 8 * 9 / 1 + 2 - 3
    4 * 5 / 6 + 7 - 8 * 9
    1 / 2 + 3 - 4 * 5 / 6
    7 / 8 + 9 - 1 * 2 / 3
    4 - 5 * 6 / 7 + 8 - 9
    

    测试工具

    exprchecker.zip

    功能:

    • 测试:
      • 生成10道1个运算符题目
      • 生成30道1个运算符题目
      • 生成100道1个运算符题目
      • 生成1000道3个运算符题目
      • 生成10000道5个运算符题目
      • 生成20000道7个运算符题目
    • 发现重复的题目(按上述题目要求)
    • 计算程序生成题目耗时

    注意:

    • 输出题目中出现不在1~9范围内的数值,工具会abort退出(当前设计)
    • 该工具并不完善,使用过程中可能出现报错,崩溃,行为不正确的情况,请不要尝试使用各类输入来测试该工具。如果发现问题,请及时与我联系

    使用条件:

    • Windows环境(在Windows10使用VS2017编译Win32,未进行版本兼容性测试)
    • 须安装JDK并配置相关环境变量
    • 你编写的Java程序须严格遵守以上约定

    使用方法:

    • 下载后,请将 exprchecker.exe 与将要执行的类 ExpressionGenerator.class 放置在统一目录,如:
    ProjectDir
    ├── ExpressionGenerator.class
    ├── exprchecker.exe
    ├── ...
    └── Other.class
    
    • 双击 exprchecker.exe 将自动执行你的类 ExpressionGenerator.class,按照以上约定的参数,执行6组测试,输出信息如下:
    Executing command: "java ExpressionGenerator 10 1 10.txt" ... DONE with status: 0
    Checking your result in 10.txt ... DONE
    Generating report into report_10.txt ... DONE
    
    Executing command: "java ExpressionGenerator 30 1 30.txt" ... DONE with status: 0
    Checking your result in 30.txt ... DONE
    Generating report into report_30.txt ... DONE
    
    Executing command: "java ExpressionGenerator 100 1 100.txt" ... DONE with status: 0
    Checking your result in 100.txt ... DONE
    Generating report into report_100.txt ... DONE
    
    Executing command: "java ExpressionGenerator 1000 3 1000.txt" ... DONE with status: 0
    Checking your result in 1000.txt ... DONE
    Generating report into report_1000.txt ... DONE
    
    Executing command: "java ExpressionGenerator 10000 5 10000.txt" ... DONE with status: 0
    Checking your result in 10000.txt ... DONE
    Generating report into report_10000.txt ... DONE
    
    Executing command: "java ExpressionGenerator 20000 7 20000.txt" ... DONE with status: 0
    Checking your result in 20000.txt ... DONE
    Generating report into report_20000.txt ... DONE
    
    Press [Enter] to exit ...
    

    查看 report_10.txt:

    ===============================
    total expressions: 10
    duplicated expressions: 0
    ===============================
    Generation cost 125 ms.
    
    • 生成10道题目
    • 没有发现重复的题目
    • 生成题目耗时125毫秒

    查看 report_30.txt:

    [2 + 3] @ line 12 is repeated with:
       -> [2 + 3] @ line 21
    
    [7 / 8] @ line 10 is repeated with:
       -> [7 / 8] @ line 19
    
    [9 * 1] @ line 2 is repeated with:
       -> [9 * 1] @ line 29
    
    [4 * 5] @ line 4 is repeated with:
       -> [4 * 5] @ line 13
    
    [1 + 2] @ line 7 is repeated with:
       -> [1 + 2] @ line 25
    
    [5 + 6] @ line 9 is repeated with:
       -> [5 + 6] @ line 18
    
    ===============================
    total expressions: 30
    duplicated expressions: 6
    ===============================
    Generation cost 133 ms.
    
    • 生成30道题目
    • 发现6道题目重复(未成功去重哦!)
    • 生成题目耗时133毫秒
    • 重复题目的详细信息在文件前面部分说明
  • 相关阅读:
    "INVALID" is not a valid start token
    Win+R 快速启动程序
    assert False 与 try 结合 在开发中的使用
    token的分层图如下
    https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/ReferenceError
    获取控制台的错误信息 onerror
    状态git
    icmp
    git commit前检测husky与pre-commit 提交钩子
    git diff
  • 原文地址:https://www.cnblogs.com/vertextao/p/6896953.html
Copyright © 2020-2023  润新知