第二次博客作业

《构建之法》第二次博客 熟悉工具

一、作业要求

GIT地址 GIT地址
GIt用户名 Loserhqs
学号后五位 62322
我的博客地址 博客

二、项目背景

阿超家里的孩子上小学一年级了,这个暑假老师给家长们布置了一个作业:家长每天要给孩子出一些合理的,但要有些难度的四则运算题目,并且家长要对孩子的作业打分记录。

作为程序员的阿超心想,既然每天都需要出题,那何不做一个可以自动生成小学四则运算题目与解决题目的命令行 “软件”呢。他把老师的话翻译一下,就形成了这个软件的需求:

程序接收一个命令行参数 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

三、环境配置

Visual Studio 2013是我大一的时候就安装好的,版本不是很高,但是觉得再安装一个Visual Studio 2017或者Visual Studio 2019很浪费时间,同时也增加了电脑的负担。所以这次四则运算的作业我还是用的Visual Studio 2013来实现的。如果没有的可以去官网下载或者在网上找百度云盘的资源。

同时github也是以前就开始用了,当然注册一个账号也不是什么难事,有的博客说最好用谷歌浏览器来注册,我记得当时没有用谷歌,也没遇到什么问题。所以我觉得用什么浏览器应该没关系吧,当然最好用谷歌浏览器嘛。

对于git的安装,在Git的官网https://git-scm.com/点击Downloads

下载git 2.23

下载完成后,点击该应用程序,跟着引导一步一步的点击Next就OK了。git的安装十分简单,应该不需要什么安装教程,如果有需要的可以参考:https://www.cnblogs.com/wj-1314/p/7993819.html

四、项目克隆

登录自己的github账号,登陆成功后,输入阿超的仓库地址:

https://github.com/Cherish599/AchaoCalculator,进入阿超四则运算生成器仓库,点击右上角的Fork键,将该仓库拷贝到自己的同名仓库中。

回到自己的首页中,查看是否拷贝成功。如果自己主页下面有“阿超四则运算生成器”,则说明拷贝成功,否则还需要重新拷贝。

点击该页面右下角的Clone or download会出现一个网址,将该网站复制下来。

在想要下载该项目的地方,鼠标右键点击Git Bash Here,在给窗口下输入git clone并且将刚刚复制的网址粘贴上去。

在保存的地方会出现刚下载的文件。在此我们可以新建自己的项目保存在这个文件夹中。

五、创建项目

打开自己的Visual Studio,在开始栏下点击新建项目。

选择Visual C#的控制台应用程序,将该项目保存在刚刚下载的四则运算文件夹下。如果不熟悉C#的话,也可以用C++语言来编程。

代码块:
产生随机数的方法

public class Rand
{
    //产生随机数
    public static Random rand = new Random();
    /*
    public int n1 = rand.Next(0, 100);
    public int n2 = rand.Next(0, 100);
    public int n3 = rand.Next(0, 100);
    public int n4 = rand.Next(0, 100);
    public int s1 = rand.Next(0, 4);
    public int s2 = rand.Next(0, 4);
    public int s3 = rand.Next(0, 4);
    public int type = rand.Next(0, 2);
    */
}

输入输出的方法

public class Input
{
    public static int input()
    {
        Console.WriteLine("请输入需要产生的题目数:");
        //题目数量
        int n = Convert.ToInt32(Console.ReadLine());
        return n;
    }
    //文本输出
    public static StreamWriter sw1 = new StreamWriter(@"E:\gitKU\AchaoCalculator\Loserhqs\Primarymath\Primarymath\result.txt");
}

衔接的方法,即中间过程

将运算的情况进行分类

public class Linkup
{
    //判断算式结果是否为整数
    public static bool nonnegint(double sum)
    {
        if (sum == (int)sum)
            return true;
        else
            return false;
    }
    //两个数的运算
    public static double arith(int a, int b, int s)
    {
        if (s == 0)
            return a + b;
        else if (s == 1)
            return a - b;
        else if (s == 2)
            return a * b;
        else
        {
            if (b != 0)
            {
                int temp = a / b;
                if (temp * b == a)
                    return a / b;
                else
                    return -1;
            }
            else
                return -1;
        }
    }
}


public class Opterator
{
    //两个运算符
    public static int optwo(int n1, int n2, int n3, int s1, int s2, char[] oper)
    {
        int flag = 0;
        //if ((oper[s1] == '+' || oper[s1] == '-') && (oper[s2] == '*' || oper[s2] == '/'))
        if ((s1 / 2) == 0 && (s2 / 2) == 1)
        {
            double sum = Linkup.arith(n2, n3, s2);
            if (sum >= 0)
            {
                if (Linkup.nonnegint(sum))
                {
                    double temp = Linkup.arith(n1, (int)sum, s1);
                    if (temp >= 0)
                    {
                        if (Linkup.nonnegint(temp))
                        {
                            flag = 1;
                            Console.WriteLine(n1 + "" + oper[s1] + "" + n2 + "" + oper[s2] + "" + n3 + "=" + (int)temp);
                            Input.sw1.Write(n1 + "" + oper[s1] + "" + n2 + "" + oper[s2] + "" + n3 + "=" + (int)temp + "\r\n");
                        }
                    }
                }
            }
        }
        else
        {
            double sum = Linkup.arith(n1, n2, s1);
            if (sum >= 0)
            {
                if (Linkup.nonnegint(sum))
                {
                    double temp = Linkup.arith((int)sum, n3, s2);
                    if (temp >= 0)
                    {
                        if (Linkup.nonnegint(temp))
                        {
                            flag = 1;
                            Console.WriteLine(n1 + "" + oper[s1] + "" + n2 + "" + oper[s2] + "" + n3 + "=" + (int)temp);
                            Input.sw1.Write(n1 + "" + oper[s1] + "" + n2 + "" + oper[s2] + "" + n3 + "=" + (int)temp + "\r\n");
                        }
                    }
                }
            }
        }
        return flag;
    }
    //三个运算符
    public static int opthree(int n1, int n2, int n3, int n4, int s1, int s2, int s3, char[] oper)
    {
        int flag = 0;
        //if ((oper[s1] == '+' || oper[s1] == '-') && (oper[s2] == '*' || oper[s2] == '/') && (oper[s3] == '*' || oper[s3] == '/'))
        if ((s1 / 2) == 0 && (s2 / 2) == 1 && (s3 / 2) == 1)
        {
            double sum = Linkup.arith(n2, n3, s2);
            if (sum >= 0)
            {
                if (Linkup.nonnegint(sum))
                {
                    double temp = Linkup.arith((int)sum, n4, s3);
                    if (temp >= 0)
                    {
                        double temp1 = Linkup.arith(n1, (int)temp, s1);
                        if (temp1 >= 0)
                        {
                            if (Linkup.nonnegint(temp1))
                            {
                                flag = 1;
                                Console.WriteLine(n1 + "" + oper[s1] + "" + n2 + "" + oper[s2] + "" + n3 + "" + oper[s3] + n4 + "=" + (int)temp1);
                                Input.sw1.Write(n1 + "" + oper[s1] + "" + n2 + "" + oper[s2] + "" + n3 + "" + oper[s3] + n4 + "=" + (int)temp1 + "\r\n");
                            }
                        }
                    }
                }
            }
        }
        else if ((s1 / 2) == 0 && (s2 / 2) == 1 && (s3 / 2) == 0)
        {
            double sum = Linkup.arith(n2, n3, s2);
            if (sum >= 0)
            {
                if (Linkup.nonnegint(sum))
                {
                    double temp = Linkup.arith(n1, (int)sum, s1);
                    if (temp >= 0)
                    {
                        double temp1 = Linkup.arith((int)temp, n4, s3);
                        if (temp >= 0)
                        {
                            if (Linkup.nonnegint(temp1))
                            {
                                flag = 1;
                                Console.WriteLine(n1 + "" + oper[s1] + "" + n2 + "" + oper[s2] + "" + n3 + "" + oper[s3] + n4 + "=" + (int)temp1);
                                Input.sw1.Write(n1 + "" + oper[s1] + "" + n2 + "" + oper[s2] + "" + n3 + "" + oper[s3] + n4 + "=" + (int)temp1 + "\r\n");
                            }
                        }
                    }
                }
            }
        }
        else if ((s1 / 2) == 0 && (s2 / 2) == 0 && (s3 / 2) == 1)
        {
            double sum = Linkup.arith(n3, n4, s3);
            if (sum >= 0)
            {
                if (Linkup.nonnegint(sum))
                {
                    double temp = Linkup.arith(n1, n2, s1);
                    if (temp >= 0)
                    {
                        double temp1 = Linkup.arith((int)temp, (int)sum, s2);
                        if (temp1 >= 0)
                        {
                            if (Linkup.nonnegint(temp1))
                            {
                                flag = 1;
                                Console.WriteLine(n1 + "" + oper[s1] + "" + n2 + "" + oper[s2] + "" + n3 + "" + oper[s3] + n4 + "=" + (int)temp1);
                                Input.sw1.Write(n1 + "" + oper[s1] + "" + n2 + "" + oper[s2] + "" + n3 + "" + oper[s3] + n4 + "=" + (int)temp1 + "\r\n");
                            }
                        }
                    }
                }
            }
        }
        else if ((s1 / 2) == 1 && (s2 / 2) == 0 && (s3 / 2) == 1)
        {
            double sum = Linkup.arith(n1, n2, s1);
            if (sum >= 0)
            {
                if (Linkup.nonnegint(sum))
                {
                    double temp = Linkup.arith(n3, n4, s3);
                    if (temp >= 0)
                    {
                        double temp1 = Linkup.arith((int)sum, (int)temp, s2);
                        if (temp1 >= 0)
                        {
                            if (Linkup.nonnegint(temp1))
                            {
                                flag = 1;
                                Console.WriteLine(n1 + "" + oper[s1] + "" + n2 + "" + oper[s2] + "" + n3 + "" + oper[s3] + n4 + "=" + (int)temp1);
                                Input.sw1.Write(n1 + "" + oper[s1] + "" + n2 + "" + oper[s2] + "" + n3 + "" + oper[s3] + n4 + "=" + (int)temp1 + "\r\n");
                            }
                        }
                    }
                }
            }
        }
        else
        {
            double sum = Linkup.arith(n1, n2, s1);
            if (sum >= 0)
            {
                if (Linkup.nonnegint(sum))
                {
                    double temp = Linkup.arith((int)sum, n3, s2);
                    if (temp >= 0)
                    {
                        double temp1 = Linkup.arith((int)temp, n4, s3);
                        if (temp1 >= 0)
                        {
                            if (Linkup.nonnegint(temp1))
                            {
                                flag = 1;
                                Console.WriteLine(n1 + "" + oper[s1] + "" + n2 + "" + oper[s2] + "" + n3 + "" + oper[s3] + n4 + "=" + (int)temp1);
                                Input.sw1.Write(n1 + "" + oper[s1] + "" + n2 + "" + oper[s2] + "" + n3 + "" + oper[s3] + n4 + "=" + (int)temp1 + "\r\n");
                            }
                        }
                    }
                }
            }
        }
        return flag;
    }
}

生成一定数量的题目

public class Produce
{
    //存放运算符号的数组
    public static char[] oper = new char[4] { '+', '-', '*', '/' };
    public static void produce(int n)
    {
        int i=0;
        //有n道题
        while(i<n)
        {
            //生成两个或三个运算符的题目
            int type = Rand.rand.Next(0, 2);
            if (type == 0)
            {
                //随机生成三个数
                int num1 = Rand.rand.Next(0, 100);
                int num2 = Rand.rand.Next(0, 100);
                int num3 = Rand.rand.Next(0, 100);
                //随机生成两种运算符号
                int index1 = Rand.rand.Next(0, 4);
                int index2 = Rand.rand.Next(0, 4);
                int flag=Opterator.optwo(num1, num2, num3, index1, index2, Produce.oper);
                if(flag==1)
                {
                    i++;
                }
            }
            else
            {
                //随机生成四个数
                int num1 = Rand.rand.Next(0, 10);
                int num2 = Rand.rand.Next(0, 100);
                int num3 = Rand.rand.Next(0, 100);
                int num4 = Rand.rand.Next(0, 100);
                //随机生成三种运算符号
                int index1 = Rand.rand.Next(0, 4);
                int index2 = Rand.rand.Next(0, 4);
                int index3 = Rand.rand.Next(0, 4);
                int flag=Opterator.opthree(num1, num2, num3, num4, index1, index2, index3, Produce.oper);
                if(flag==1)
                {
                    i++;
                }
            }
        }
    }
}

运行结果:

控制台输出:

记事本TXT文件:

六、单元测试与回归测试

点击项目解决方案,选择该菜单页中的添加,然后新建项目。

选择Visual C#下的测试,然后选择单元测试项目。在.cs文件下编写单元测试的程序。

如果没有加该项目的引用的话,在写测试代码时,调用该项目中的方法会报错,我们需要在解决方案中添加该项目的引用。

当单元测试程序编写完成后,对项目中各个类进行单元测试,测试所编写的代码是否有错误。

如果有,找到相应的位置进行修改;如果没有则通过测试。


回归测试是测试在修改了原有代码的基础上还能不能运行通过,会不会影响程序的整体实现,步骤其实和单元测试相同。

单元测试与回归分析的代码:

public class UnitTest1
{
    [TestMethod]
    public void TestMethod()
    {
        //TestMethod1();
        //TestMethod2();
        //TestMethod3();
        //TestMethod4();
        TestMethod5();
    }
    public void TestMethod1()
    {
        //测试随机数
        int testnum = Rand.rand.Next(0, 100);
        int testopr = Rand.rand.Next(0, 4);
        int testtype = Rand.rand.Next(0, 2);
        Console.WriteLine(testnum);
        Console.WriteLine(Produce.oper[testopr]);
        if (testtype == 0)
        {
            Console.WriteLine("三个数的运算");
        }
        else
        {
            Console.WriteLine("四个数的运算");
        }
    }
    //测试两个数的运算
    public void TestMethod2()
    {
        //testA=8*9
        double ResultA = 72;
        double TestA = Linkup.arith(8, 9, 2);
        if (ResultA == TestA)
        {
            Console.WriteLine("testA的测试结果正确");
        }
        else
        {
            Console.WriteLine("testA的测试结果错误");
        }
        //testB=20/40
        double ResultB = 0.5;
        double TestB = Linkup.arith(20, 40, 3);
        if (ResultB == TestB)
        {
            Console.WriteLine("testB的测试结果正确");
        }
        else
        {
            Console.WriteLine("testB的测试结果错误");
        }
        //testC=56/8
        double ResultC = 7;
        double TestC = Linkup.arith(56, 8, 3);
        if (ResultB == TestB)
        {
            Console.WriteLine("testC的测试结果正确");
        }
        else
        {
            Console.WriteLine("testC的测试结果错误");
        }
    }
    //测试结果是否为整数
    public void TestMethod3()
    {
        double testnum1 = 5.63;
        double testnum2 = 45;
        if(Linkup.nonnegint(testnum1))
        {
            Console.WriteLine("testnum1测试正确");
        }
        else
        {
            Console.WriteLine("testnum1测试错误");
        }
        if (Linkup.nonnegint(testnum2))
        {
            Console.WriteLine("testnum2测试正确");
        }
        else
        {
            Console.WriteLine("testnum2测试错误");
        }
    }
    //测试运算函数
    public void TestMethod4()
    {
        //三个数的运算
        //testop1=78-5*9
        //int resultop1 = 33;
        Console.WriteLine("预测结果为33");
        Console.WriteLine("真实结果如下:");
        int flag1 = Opterator.optwo(78, 5, 9, 1, 2, Produce.oper);
        if(flag1==1)
        {
            Console.WriteLine("结果正确");
        }
        else
        {
            Console.WriteLine("结果错误");
        }
        //testop2=23+12/4
        //int resultop2 = 26;
        Console.WriteLine("预测结果为26");
        Console.WriteLine("真实结果如下:");
        int flag2 = Opterator.optwo(23, 12, 4, 0, 3, Produce.oper);
        if (flag2 == 1)
        {
            Console.WriteLine("结果正确");
        }
        else
        {
            Console.WriteLine("结果错误");
        }
        //四个数的运算
        //testop3=5*9-42/7
        //int resultop3 = 39;
        Console.WriteLine("预测结果为26");
        Console.WriteLine("真实结果如下:");
        int flag3 = Opterator.opthree(5, 9, 42, 7, 2,1,3 ,Produce.oper);
        if (flag3 == 1)
        {
            Console.WriteLine("结果正确");
        }
        else
        {
            Console.WriteLine("结果错误");
        }
        //testop4=5-9+77/11
        //int resultop4 = 11;
        Console.WriteLine("预测结果为11");
        Console.WriteLine("真实结果如下:");
        int flag4 = Opterator.opthree(5, 9, 77, 11, 1, 0, 3, Produce.oper);
        if (flag4 == 1)
        {
            Console.WriteLine("结果正确");
        }
        else
        {
            Console.WriteLine("结果错误");
        }
    }
    //测试能否生成相应数量的题目
    public void TestMethod5()
    {
        int n = 5;
        Produce.produce(n);
    }
}

七、断点调试

在主函数中设置断点,然后可以按F11步入,逐语句调试。

下面是在F11逐语句调试过程中的情况。

八、效能分析

通过分析栏下的性能与诊断,我们可以看到该项目的调用关系树:

调用方/被调用方的情况,函数名称,非独占/独占样本数。

还可以喊道调用函数,当前函数以及已调用函数的情况。

同时也可以看到进程的情况。

所有函数的的情况:非独占样本数,独占样本数以及它们的百分比都可以清楚的看到。

九、上传提交

在AchaoCalculator 文件夹下,右键鼠标,git bash here,输入git add . 将项目文件添加到版本控制中。

因为没有绑定github 用户的原因,我需要git config的指令来绑定我的用户,如果绑定的的话,可以直接输入git commit -m以及相关的备注,进行提交修改。

下图为绑定用户的过程:

下图为提交的过程:

输入git push,上传到github上面去。

打开自己的github,查看是否上传成功。如果上传成功的话,会出现自己的文件名。

点击走上角的New pull requst,将该项目的代码上传到阿超四则运算的仓库中去。打开刚开始获取阿超四则运算仓库中是否有自己的文件。

十、总结

1.在安装git过程中,没有什么意外。整体来说,安装软件也是没有什么难的地方。只是第一次用git,不是很清楚它的一些指令,需要看相关的资料才能交文件下载与上传。

2.在用C#编程的过程中,也没有什么大的问题。可能是因为这个题的难度我还能接受的原因吧。但是有一段时间没有用C#编程了,有些用法与Python都能搞混,我也真是垃圾。

3.在用C#编程的过程中一定要注意静态变量的使用,因为C#是没有全局变量一说的。

4.第一次使用单元测试和回归测试,觉得很棒。以后的学习工作中,要经常使用这一功能。

posted @ 2019-09-20 18:48  STJinBo  阅读(182)  评论(2编辑  收藏  举报