Git地址 | Calculator |
Git用户名 | FantaPi |
学号后五位 | 62132 |
博客地址 | 地址链接 |
作业链接 | 第二次作业 |
Part 1.配置环境
vs的安装配置已经在以前学习过程中配置好了,以下是我的vs安装引导程序显示的已安装的模块。
Part 2.克隆项目
通过GitHub将阿超的四则运算Fork到了自己的仓库中,如下图:
同样的,git在以前做项目时已经安装好了,而这次我选择的是GitHub Desktop来Clone仓库(GitHub desktop可以直接通过URL等方式克隆下来,不同于Git的命令行操作,GitHub Desktop的操作很简单。),下图则是显示了GitHub Desktop clone仓库后的情况:
github desktop
我的电脑从GitHub仓库上clone下来的文件存放情况
在这一步骤中,因为要求使用C#编写,因此需要改变默认克隆分支,而我用的不是Git,而是GitHub,导致我花费了十几分钟才找到解决方法:我需要在GitHub仓库网址中修改默认分支为cplusplus(我一直在应用程序,即GitHub Desktop上操作,致使我找不到好的解决办法)。做完上述步骤以后,便打开vs新建一个c#控制台应用,项目地址便位于clone下的仓库下,上面的图片可以看到项目的文件夹地址。
代码部分:
public Calculator() {
WriteHomeWork();
}
private static Random rd = new Random();
public static void WriteHomeWork()//向文件中写入数据
{
StringBuilder resultExp = new StringBuilder();
Console.WriteLine("请输入生成四则混合运算个数:");
int num=int.Parse(Console.ReadLine());
string expExample="";
int k = 0;
for(int i = 0;;)
{
expExample=createExpression();
if (Calculate(expExample) == -1)
{
i++;
continue;
}
resultExp.Append(expExample+"="+Calculate(expExample)+"\r\n");
k++;
if (k == num)
{
break;
}
i++;
}
System.IO.File.WriteAllText("D://homework.txt", resultExp.ToString(), Encoding.Default);
}
public static int Calculate(string s)//进行运算
{
int result = 0;
string[] addop = s.Split(new string[] { "+" }, StringSplitOptions.RemoveEmptyEntries);
for (int i = 0; i < addop.Length; i++)
{
string[] subop = addop[i].Split(new string[] { "-" }, StringSplitOptions.RemoveEmptyEntries);
int[] subint = new int[subop.Length];
for (int j = 0; j < subint.Length; j++)
{
subint[j] = Operate(subop[j]);
}
int subval = subint.Aggregate((a, b) => a - b);
if (subval < 0)
{
return -1;
}
result += subval;
}
return result;
}
public static string createExpression()//创建四则混和运算公式
{
string s = "";
int a = rd.Next(3, 5);
for(int i = 0; i < a; i++)
{
int b = rd.Next(1, 100);
s += b.ToString();
if (i == a - 1) break;
int c = rd.Next(0,4);
if (c == 0) s += '+';
if (c == 1) s += '-';
if (c == 2) s += '*';
if (c == 3) s += '/';
}
return s;
}
private static int Operate(string exp)
{
if (exp.Contains("*") == false && exp.Contains("/") == false)
{
return Convert.ToInt32(exp);
}
string[] num = new string[2] { "", "" };
string lastop = "";
for (int i = 0; i < exp.Length; i++)
{
if (exp[i] == '*')
{
if (lastop == "")
lastop = "*";
else
{
if (lastop == "*")
{
num[0] = (Convert.ToInt32(num[0]) * Convert.ToInt32(num[1])).ToString();
num[1] = "";
lastop = "*";
}
else
{
num[0] = (Convert.ToInt32(num[0]) / Convert.ToInt32(num[1])).ToString();
num[1] = "";
lastop = "*";
}
}
}
else if (exp[i] == '/')
{
if (lastop == "")
lastop = "/";
else
{
if (lastop == "*")
{
num[0] = (Convert.ToInt32(num[0]) * Convert.ToInt32(num[1])).ToString();
num[1] = "";
lastop = "/";
}
else
{
num[0] = (Convert.ToInt32(num[0]) / Convert.ToInt32(num[1])).ToString();
num[1] = "";
lastop = "/";
}
}
}
else
{
if (lastop == "")
num[0] += exp[i];
else
num[1] += exp[i];
}
}
if (lastop == "*")
{
return (Convert.ToInt32(num[0]) * Convert.ToInt32(num[1]));
}
else
{
return (Convert.ToInt32(num[0]) / Convert.ToInt32(num[1]));
}
}
下图便是运行程序过后生成的文档:
Part 3.单元测试
当我看到单元测试这一部分时,并没有注意到提示里面讲的是c++,导致我在做单元测试时,一直照着c++的格式去做,结果找不到附加依赖项,最后才发现我眼瞎?,最后按着c#的方法去做,单击右键创建单元测试,如下图,很轻易地便弄了出来,下次再也不敢粗心大意了:(:(:(。
并在相对应位置写下单元测试代码:
[TestMethod()]
public void CalculatorTest()
{
StringBuilder s = new StringBuilder();
string tmp = Calculator.createExpression();
while (true)
{
if (Calculator.Calculate(tmp) >= 0)
{
s.Append(tmp + " = " + Calculator.Calculate(tmp) + "\r\n");
break;
}
}
System.IO.File.WriteAllText("D://test.txt", s.ToString(), Encoding.Default);
}
运行结果如下,第一幅是vs单元测试成功后的图片,第二幅则是单元测试产生的结果:
Part 4.基本操作
在vs中,通过打断点的方式进行单步调试,可以很清楚的看到各个变量的值,并判断它是否与预期相符,这样很容易发现错误的根源。在程序的编写过程中,运行时一直出现数组越界访问的情况,这种情况令我发狂,以至于在很长时间找不到解决方法,最后静下心来,通过单步调试才找到问题根源出现在我定义的字符串数组上,于是我便改用另一种方法存储数据,才解决这一问题。
Part 5.回归测试
本次作业是第一次进行,因此代码层面来看,回归测试很有必要,从而以此保障程序的正常运行,而不至于因为一些bug的存在而致使产生严重的错误。同时,也因为时间较短,回归测试做得较少,只是修改了一两次,在上面GitHub desktop下的图片可以看出修改情况以及每一次修改的备注。
Part 6.效能工具使用
下面几张图是我这个小程序通过效能工具得出来的相应结果:
Part 7.提交代码
Part 8.感想与分享
在这次实验中,我收获最大的方面就是单元测试与效能分析了。以前在写程序的时候,代码总会有各种各样的问题,而这些问题我又总是要花费很多时间在这上面,虽然了解单步调试等调试方法,但是在效率上我总是提不上来,而这次通过单元测试,我对代码的问题测试有了大概的方向。同样,通过把握相关测试要点,才会系统的学习到有关代码测试的知识,而不是漫无目的的修修补补。同时在这一过程中,对于像vs这种工具也有了更进一步的了解,对多个程序的同时使用以达到编程目的的方法也有了一定的掌握。
同样的,越了解Github这样的版本控制工具,越发觉得它的实用之处,它不仅能够让多人合作的项目更易于管理,还能够实时的更新与操作。以后的编程或项目中,Git或许会成为我的一大助力。