工欲善其事,必先利其器

GIT地址 https://github.com/ordinaryload
GIT用户名 ordinaryload
学号后五位 23214
博客地址 https://www.cnblogs.com/xnch/
作业链接 https://www.cnblogs.com/ChildishChange/p/10398212.html

项目背景

  阿超家里的孩子上小学一年级了,这个暑假老师给家长们布置了一个作业:家长每天要给孩子出一些合理的,但要有些难度的四则运算题目,并且家长要对孩子的作业打分记录。
  作为程序员的阿超心想,既然每天都需要出题,那何不做一个可以自动生成小学四则运算题目与解决题目的命令行 “软件”呢。他把老师的话翻译一下,就形成了这个软件的需求:
  程序接收一个命令行参数 n,然后随机产生 n 道加减乘除(分别使用符号+-*/来表示)练习题,每个数字在 0 和 100 之间,运算符在 2 个 到 3 个之间。由于阿超的孩子才上一年级,并不知道分数。所以软件所出的练习题在运算过程中不得出现非整数,比如不能出现 3÷5+2=2.6 这样的算式。
  练习题生成好后,将生成的 n 道练习题及其对应的正确答案输出到一个文件 subject.txt 中。
  当程序接收的参数为4时,以下为一个输出文件示例。

13+17-1=29
11*15-5=160
3+10+4-16=1
15÷5+3-2=4

一、配置环境

  在一个项目开始之前,肯定要把编码环境,测试工具,效能分析等工具安装完成。下面我将先从环境配置开始,从而开始整个项目。

1、VS2017安装与配置

  VS是一个基本完整的开发工具集,它包括了整个软件生命周期中所需要的大部分工具,如UML工具、代码管控工具、集成开发环境(IDE)等等。


在这里插入图片描述


  这里使用的vs2017工具,由于之前学习的过程中已经使用过,在这里就不再贴出具体安装过程。在安装过程中好像没有什么问题,就是这个工具太大了,安装过程时间较长,还有就是切记不要安装在C盘

1、Git安装及Github创建

  Git 是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目。Github是一个代码托管平台和开发者社区,开发者可以在Github上创建自己的开源项目并与其他开发者协作编码。
由于我在之前已经使用过git以及github了,所以这里也就不再重复安装过程了。安装成功后应该是这样的:


在这里插入图片描述
在这里插入图片描述

二、代码思路及实现

  写C#代码着实头大,花了大半天才把程序弄好,其中创建不同的控制台应用还会出现不同的问题。(随机数产生重复的函数)但是当创建控制台应用(.net Core)应用时则不会出现此问题,于是我就百度了原因是什么以及这两者之间的关系。参考博文:https://blog.csdn.net/weixin_39730950/article/details/90767418
在这里插入图片描述
   .NET Core是一个新的开源并且跨平台的用来构建可以所有操作系统(包括Windows, Mac, and Linux)上面运行的应用的的框架。

  • .NET Framework的优势:
       如果你需要快速开发并部署一个 .NET 应用并且你没有充足的时间去学习 .NET Core,那么你应该选 .NET Framework。因为 .NET Core有一定的学习曲线。
       如果你要维护并升级现有的 .NET应用程序,那么你应该选择.NET Framework。移植一个现有的.NET程序去.NET Core 框架线面需要一定的工作量。
      .NET Framework 现在的版本是.NET Framework 4.8,很有可能这是.NET Framework的最后一个版本了。在未来并没有计划有新的.NET Framework版本。
  • .NET Core的优势:
       加入你要开发一个新的应用并且有.NET Framework 和.NET Core 供你选择,那么应该选.NET Core。
       .微软刚刚宣布.NET Core V3.0,这是一个有很大提升的.NET Core版本。.NET Core将是你以后学习并开发一个应用程序时的选择。
       .NET Core 3.0支持已经支持了WPF和Windows Forms。.NET Core 3.0 还支持UWP,WPF和Windows Forms三者的开发。
       .NET Core 很适合跨平台的开发。 .NET Core 应用支持Windows,Linux和Mac OS。微软的很受欢迎的开源文本编辑器 Visual Code 支持Windows,Linux和Mac OS。VS Code还支持IntelliSense 和 debugging,就像Sublime, Emacs, and VI, work w那样 。
       .NET Core 也是支持微服务的,它支持跨平台的服务与.NET Core 一起工作,即使这写服务是.NET Framework, Java, Ruby,等等,开发的。

综上所述: 可能.Net Core的性能优于.NET Framework,所以在根据当前时间产生随机数的时候一般不会产生重复的数据,而.NET Framework下就需要自己手动去解决重复的问题。
部分代码如下:
解决方案:设置当前时间及线程睡眠

	long tick = DateTime.Now.Ticks;
    Thread.Sleep(10);
    Random random = new Random((int)(tick & 0xffffffffL) | (int)(tick >> 32));

RandomFormula.cs

  设计一个随机函数,生成我们所需要的随机序列的等式,运算符的个数也同样是随机的(2-3个)

/*
     * 生成公式类
     * 通过随机函数Random及其一些方法,来随机生成0-100数字,
     * 从而通过字符串的拼接得出公式
     */
    class RandomFormula
    {
        private static String[] Operation = { "+", "-", "*", "/" };//设置四则运算字符串数组,通过后面随机选取来匹配
        public String randFormula()
        {
            StringBuilder stringBuider = new StringBuilder();//为了便于操作字符串及一些性能,这里使用StringBuilder类
            long tick = DateTime.Now.Ticks;
            Thread.Sleep(10);
            Random random = new Random((int)(tick & 0xffffffffL) | (int)(tick >> 32));
            int counts = (int)(random.NextDouble() * 2 + 2);//记录随机生成算式,运算符在 2 个 到 3 个之间。
            int start = 0;
            int[] number = new int[4];//定义一个数组来记录随机生成的数字
            number[0] = (int)(random.NextDouble() * 100) + 1;//随机生成0-100数字
            stringBuider.Append(number[0]);//将参数添加到stringBuider对象中
            start++;
            while (start <= counts)
            {
                int operation = (int)(random.NextDouble() * 4);
                number[start] = (int)(random.NextDouble() * 100) + 1;
                if (operation == 3)//若为除,进行判断操作
                {
                    while (!(number[start - 1] % number[start] == 0))
                    {
                        number[start] = (int)(random.NextDouble() * 100) + 1;
                    }
                    stringBuider.Append(Operation[operation]).Append(number[start]);
                }
                else
                {
                    stringBuider.Append(Operation[operation]).Append(number[start]);
                }

                start++;
            }
            return stringBuider.ToString();
        }
    }

FormulaFile.cs

  将随机生成的四则混合运算存入文件中

/*
     * 输出文件类
     * 将随机生成的四则混合运算存入文件中
     * 
     */
    class FormulaFile
    {
       
        public  void printFile(string result)
        {
            string path = @"F:\formula.txt";//定义路径
            System.IO.FileInfo fileInfo = new System.IO.FileInfo(path);
            System.IO.StreamWriter streamWriter = fileInfo.AppendText();//字符输出流
            streamWriter.WriteLine(result);
            streamWriter.Close();
        }
    }

testFormula.cs

  通过主测试类来循环输出所需要的出题数量

class testFormula
    {
        private static int sumTotal;
        static void Main(string[] args)
        {
            Console.WriteLine("请输入需要出题的数目:");
            String sum = Console.ReadLine();//输入需要的题目数量
            sumTotal = Convert.ToInt32(sum);
            printFormula();
            Console.ReadKey();
        }
        public static void printFormula()
        {
            int makeCounts = 0;
            while (makeCounts < sumTotal)
            {
                FormulaFile formulaFile = new FormulaFile();
                RandomFormula randomFormula = new RandomFormula();
                String formula = randomFormula.randFormula();

                DataTable dataTable = new DataTable();
                object result = dataTable.Compute(formula, "");//将字符串转换为算术表达式计算
                String strResult = Convert.ToString(result);
                if (!(strResult.Contains(".") || strResult.Contains("-")))
                {
                    formulaFile.printFile(formula + " = ");//将算式写入文件
                    Console.WriteLine(formula + " = " + result);
                    makeCounts++;
                }


            }

        }
    }

测试结果如下:

在这里插入图片描述

三、单元测试

  在解决方案上,右键添加新建项目,然后再类型里面选择单元测试,自己重命名即可。


在这里插入图片描述


  创建好单元测试后,找到引用,然后添加默认本项目的测试即可。


在这里插入图片描述


  随后创建单个类的单元测试,鼠标右键选择创建单元测试


在这里插入图片描述


  但是目前会出如下问题,意思就是在公共类才能进行单元测试。


在这里插入图片描述


  在这里,我们可以在类前面加上public。然后右键选择单元测试就可以进行测试了。


在这里插入图片描述


  在完成单元测试的项目配置后,下面我们就可以开始写单元测试代码了。下面是我写好过后的测试结果:


在这里插入图片描述

四、断点及回归测试

断点调试

  众所周知,程序不是编出来的,是调出来的,那么怎么能少了我们强大的debug工具呢。下面我们就来介绍一下 Visual Studio 的调试方法。

1、断点

  调试程序首先要会设置断点,断点通知调试器,使应用程序在某点上(暂停执行)或某情况发生时中断。发生中断时,称程序和调试器处于中断模式。进入中断模式并不会终止或结束程序的执行,所有元素(如函数、变量和对象)都保留在内存中。执行可以在任何时候继续。
  插入断点有3种方式:在要设置断点的代码行旁边的灰色空白中单击;右键单击要设置断点的代码行,在弹出的快捷菜单中选择“断点”→“插入断点”命令。单击要设置断点的代码行,选择菜单中的“调试”→“切换断点(G)”命令。插入断点后,就会在设置断点的行旁边的灰色空白处出现一个红色圆点,并且该行代码也呈高亮显示。


在这里插入图片描述


  单步运行有两种:Step Into(逐语句,快捷捷F11) 和 Step Over(逐过程,快捷捷F10)。

  1. 逐语句
      一条一条语句的去执行,在遇到函数等其他语句时,会调到函数中,接着逐语句的去运行,当函数运行完毕再跳回来,就是程序一卡一卡的去执行。

  2. 逐过程
      也是一条一条的去执行,但是是流水式的去执行,把函数当一条语句去执行,不会有跳转这种行为。相当于从断点一直刷到最后,没有什么逻辑在其中。


    在这里插入图片描述


      如果选择“启动调试”菜单,则应用程序启动并一直运行到断点,此时断点处的代码以黄色底色显示。也可以在任何时刻中断执行,以查看值(将鼠标移动到相应的变量或者对象上,即可查看其具体值)


    在这里插入图片描述

回归测试

  回归测试其实就是在改了代码后再进行单元测试。开发人员修复了上一轮测试发现的BUG后,再次提交配置管理中心,配置管理中心再把程序交给测试部进行测试。这里不再赘述实验过程截图。具体我改后的代码及测试,通过再次commit,已提交至github。

五、效能分析

  为了测试并改进程序生成四则运算算式的效率,我们需要使用效能分析工具。效能分析工具可以帮我们分析找到代码中执行效率最差的部分。Visual Studio 内置了非常棒的效能工具——性能探查器 。点击 IDE 顶部菜单栏中的分析,即可看到性能探查器。如下图所示:


在这里插入图片描述


  在这里我们只关心程序的执行效率,所以我们选择CUP测试


在这里插入图片描述


  按照老师给出的博文指示,给出10000000万组数据,保证测试结果,让程序跑一会儿后,就可以结束。点击效能分析工具界面左上角的停止收集即可停止收集数据。完整测试报告如下:


在这里插入图片描述


  点击创建详细报告即可看到详细报告:


在这里插入图片描述


  随便点击一个我们写的一个函数,即可很清晰的看到每行代码占用CPU时间比例,然后我们就可以对代码进行改进来提高执行效率了。


在这里插入图片描述

五、Github提交代码

  在这一步来查看如何提交代码到Github上,并利用 Github 进行团队协作。首先通过 git add .git commit -m "201731023214"命令对本地的仓库进行修改,离线的操作。然后我们在通过 git push命令,就可以上传到我们的github上了。


在这里插入图片描述


  在完成 push 后,我们就可以开始向源仓库(即阿超的仓库)发起 Pull Request(发起请求给仓库贡献代码)。打开你 Fork 后的项目主页,如图所示,点击按钮 New pull request。


在这里插入图片描述


  最后点击 Create pull request 即可发起请求。等待仓库主人阿超通过审核后,代码就可以成功合并进阿超的仓库。

六、总结感悟

  博客写到这里,呼~~终于写完了,先吐槽一下,然后再说收货吧。这个时间真是花费太多了,而且各种问题浮现。本以为一上午就可以搞定,没想到硬生生花费了一天半的时间,多次想着放弃,要不随便写写就算了,反正也才占比5分,七八十分总能拿到吧,最后也没什么关系。最后两个我不断的打架,打着打着也就差不多做完了。
收获:

  1. 坚持,一个错误会花很长时间去解决,一个工具配置问题(如git),发现众里寻他千百度,那人却在灯火阑珊处。坚持下去,一定可以解决。
  2. 克服了心理因素,在做作业的过程中,曾想过等别人写完问问,或是随便完成就好,克服了与你打架的那个自己,那便是柳暗花明。
  3. 不停的学习,本次实验中,VS以前安装过,Git也安装过,但是一般没怎么使用,又或是新的东西,不停的学习才能激发最深的潜力。
  4. 温故而知新。比如之前学过的数据结构,栈、树、图等等,在这次实验中我深深的意识到已经差不多还给老师了,在学习的过程中应该留一些时间来回顾以前的知识。
  5. 软件工程难的不仅仅是代码,还有较多的工具及文档。
  6. 多实践,开阔视野,掌握新技术。做了实验才真正了解到git的强大,以前也就只是听说而已,自己没有真正去实践,应当多去了解新技术并且自己来实践它。

参考链接

posted @ 2019-09-19 13:58  许你长欢  阅读(415)  评论(4编辑  收藏  举报