·Github地址:https://github.com/Dioikawa/Myapp
·成员:陈杰才(3118005089)
蔡越(3118005086)
·耗费时间估计:
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 30 | |
Estimate | 估计这个任务需要多少时间 | 30 | |
Development | 开发 | 13 | |
Analysis | 需求分析 (包括学习新技术) | 60 | |
Design Spec | 生成设计文档 | 0 | |
Design Review | 设计复审 (和同事审核设计文档) | 0 | |
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 10 | |
Design | 具体设计 | 180 | |
Coding | 具体编码 | 1000 | |
Code Review | 代码复审 | 30 | |
Test | 测试(自我测试,修改代码,提交修改) | 30 | |
Reporting | 报告 | 120 | |
Test Report | 测试报告 | 60 | |
Size Measurement | 计算工作量 | 30 | |
Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 30 | |
总计 | 1460 |
·程序结构(函数调用关系):
·关键代码展示:
·生成题目文件函数:只能生成六种固定格式的题目,受数学题目的合法性限制,没能生成形式任意且合法的运算式。
1 int question(int y,int r)//生成题目 2 { 3 FILE *fp; 4 fp=fopen("Exercises.txt","a"); 5 //time_t t; 6 //srand(time(NULL)); 7 int num,num1,num2,num3,num4,ans; 8 char opt1,opt2,opt3; 9 char str[25]={};//用于传进答案函数 10 char strf[25]={};//用于写进文件 11 char strt[5]={" ÷ "}; 12 opt1=getopt(); 13 opt2=getopt(); 14 opt3=getopt(); 15 16 num1=rand()%r; 17 num2=rand()%r; 18 num3=rand()%r; 19 num4=rand()%r; 20 21 if(r<3) num=rand()%4+1;//r小于3时,不产生分数 22 else num=rand()%6+1; 23 24 if(num==1)//a+b 25 { 26 while(r==1&&opt1==-10) 27 opt1=getopt();//r是1则除号不参与运算 28 29 while(opt1==-10&&num2==0) 30 num2=rand()%r;//0不可作为除数 31 32 char str1[5]={}; 33 itoa(num1,str1,10); 34 strcat(str,str1); 35 strcat(strf,str1); 36 37 char str2[5]={' ',opt1,' '}; 38 strcat(str,str2); 39 if(opt1==-10) strcat(strf,strt); 40 else strcat(strf,str2); 41 42 char str3[5]={}; 43 itoa(num2,str3,10); 44 strcat(str,str3); 45 strcat(strf,str3); 46 } 47 if(num==2)//a+b+c 48 { while(r==1&&(opt1==-10||opt2==-10)) 49 { 50 opt1=getopt(); 51 opt2=getopt(); 52 }//r是1则除号不参与运算 53 54 while(opt1==-10&&num2==0) 55 num2=rand()%r;//0不可作为除数 56 while(opt2==-10&&num3==0) 57 num2=rand()%r;//0不可作为除数 58 59 char str1[5]={}; 60 itoa(num1,str1,10); 61 strcat(str,str1); 62 strcat(strf,str1); 63 64 char str2[5]={' ',opt1,' '}; 65 strcat(str,str2); 66 if(opt1==-10) strcat(strf,strt); 67 else strcat(strf,str2); 68 69 char str3[5]={}; 70 itoa(num2,str3,10); 71 strcat(str,str3); 72 strcat(strf,str3); 73 74 char str4[5]={' ',opt2,' '}; 75 strcat(str,str4); 76 if(opt2==-10) strcat(strf,strt); 77 else strcat(strf,str4); 78 79 char str5[5]={}; 80 itoa(num3,str5,10); 81 strcat(str,str5); 82 strcat(strf,str5); 83 } 84 if(num==3)//a+b+c+d 85 { 86 while(r==1&&(opt1==-10||opt2==-10||opt3==-10)) 87 { 88 opt1=getopt(); 89 opt2=getopt(); 90 opt3=getopt(); 91 }//r是1则除号不参与运算 92 93 while(opt1==-10&&num2==0) 94 num2=rand()%r;//0不可作为除数 95 while(opt2==-10&&num3==0) 96 num3=rand()%r;//0不可作为除数 97 while(opt3==-10&&num4==0) 98 num4=rand()%r;//0不可作为除数 99 100 char str1[5]={}; 101 itoa(num1,str1,10); 102 strcat(str,str1); 103 strcat(strf,str1); 104 105 char str2[5]={' ',opt1,' '}; 106 strcat(str,str2); 107 if(opt1==-10) strcat(strf,strt); 108 else strcat(strf,str2); 109 110 char str3[5]={}; 111 itoa(num2,str3,10); 112 strcat(str,str3); 113 strcat(strf,str3); 114 115 char str4[5]={' ',opt2,' '}; 116 strcat(str,str4); 117 if(opt2==-10) strcat(strf,strt); 118 else strcat(strf,str4); 119 120 char str5[5]={}; 121 itoa(num3,str5,10); 122 strcat(str,str5); 123 strcat(strf,str5); 124 125 char str6[5]={' ',opt3,' '}; 126 strcat(str,str6); 127 if(opt3==-10) strcat(strf,strt); 128 else strcat(strf,str6); 129 130 char str7[5]={}; 131 itoa(num4,str7,10); 132 strcat(str,str7); 133 strcat(strf,str7); 134 } 135 136 if(num==5)//a/b+c 137 { 138 while(opt1==-10&&num1==0) 139 num1=rand()%r;//0不可作为除数 140 141 Truescore(r,str); 142 strcpy(strf,str); 143 144 char str1[5]={' ',opt1,' '}; 145 strcat(str,str1); 146 if(opt1==-10) strcat(strf,strt); 147 else strcat(strf,str1); 148 149 char str2[5]={}; 150 itoa(num1,str2,10); 151 strcat(str,str2); 152 strcat(strf,str2); 153 } 154 155 if(num==6)//a+b/c+d 156 { 157 while(opt2==-10&&num2==0) 158 num2=rand()%r;//0不可作为除数 159 160 char str1[5]={}; 161 itoa(num1,str1,10); 162 strcat(str,str1); 163 strcat(strf,str1); 164 165 char str2[5]={' ',opt1,' '}; 166 strcat(str,str2); 167 if(opt1==-10) strcat(strf,strt); 168 else strcat(strf,str2); 169 170 char str3[8]={}; 171 Truescore(r,str3); 172 strcat(str,str3); 173 strcat(strf,str3); 174 175 char str4[5]={' ',opt2,' '}; 176 strcat(str,str4); 177 if(opt2==-10) strcat(strf,strt); 178 else strcat(strf,str4); 179 180 char str5[5]={}; 181 itoa(num2,str5,10); 182 strcat(str,str5); 183 strcat(strf,str5); 184 } 185 186 if(num==4)//a+(b+c) 187 { 188 while(r==1&&(opt1==-10||opt2==-10)) 189 { 190 opt1=getopt(); 191 opt2=getopt(); 192 }//r是1则除号不参与运算 193 194 while(opt1==-10&&num2==0) 195 num2=rand()%r;//0不可作为除数 196 while(opt2==-10&&num3==0) 197 num3=rand()%r;//0不可作为除数 198 199 char str1[5]={}; 200 itoa(num1,str1,10); 201 strcat(str,str1); 202 strcat(strf,str1); 203 204 char str2[5]={' ',opt1,' '}; 205 strcat(str,str2); 206 if(opt1==-10) strcat(strf,strt); 207 else strcat(strf,str2); 208 209 char left[3]={'('}; 210 strcat(str,left); 211 strcat(strf,left); 212 213 char str3[5]={}; 214 itoa(num2,str3,10); 215 strcat(str,str3); 216 strcat(strf,str3); 217 218 char str4[5]={' ',opt2,' '}; 219 strcat(str,str4); 220 if(opt2==-10) strcat(strf,strt); 221 else strcat(strf,str4); 222 223 char str5[5]={}; 224 itoa(num3,str5,10); 225 strcat(str,str5); 226 strcat(strf,str5); 227 228 char right[3]={')'}; 229 strcat(str,right); 230 strcat(strf,right); 231 } 232 233 // ans=Answer(str,y);//将题目字符串str传进生成答案函数Answer 234 if(Answer(str,y)<0) 235 { fclose(fp); 236 return -1; 237 }//若计算答案过程中产生负数,则返回-1给main()处理 238 else//否则将题目写进Exercises.txt文件,并返回1给main()处理 239 { 240 //printf("%d.%s",y,str) ; 241 fprintf(fp,"%d.%s = \n",y,strf); 242 fclose(fp); 243 return 1; 244 } 245 }
·生成答案函数:将题目字符串作为参数,利用栈计算运算结果并转换为字符串写进答案文件,同时想生成问题文件并返回标识。
1 int Answer(char str[],int y)//答案函数,str为运算式子,y为序号 2 { 3 Stack1 num;//分数数栈 4 Stack2 opt;//运算符栈 5 int i = 0, tmp = 0; 6 int s,m; 7 int a1,a2,a3,a4,a5; 8 char temps[20]="\0";//存放中间运算结果 9 char fans[20]="\0";//答案字符串 10 FILE *fp; 11 fp=fopen("Answers.txt","a"); 12 13 if(InitStack1(&num) != OK || InitStack2(&opt) != OK) 14 { 15 printf("Init Failure!\n"); 16 exit(1); 17 } 18 19 while(str[i] != '\0' || EmptyStack(&opt) != OK) 20 { 21 if(str[i]==32) 22 { 23 i++; 24 continue; 25 } 26 if(str[i] >= '0' && str[i] <= '9') 27 { 28 tmp = tmp * 10 + str[i] - '0'; 29 i++; 30 if(str[i] < '0' || str[i] > '9') 31 { 32 if(Push1(&num,1,tmp)==ERROR) 33 printf("Push1 ERROR!");//数字tmp/1入栈 34 tmp = 0; 35 } 36 } 37 else 38 { 39 if((EmptyStack(&opt) == OK) || (GetTop(&opt) == '(' && str[i] != ')') || Priority(str[i]) > Priority(GetTop(&opt)))//进栈不参与运算 40 { 41 if(Push2(&opt,str[i])==ERROR) 42 printf("Push2 ERROR!");//运算符入栈 43 i++; 44 continue; 45 } 46 if(GetTop(&opt) == '(' && str[i] == ')')//出栈不参与运算 47 { 48 Popt(&opt); 49 i++; 50 continue; 51 } 52 if((str[i] == '\0' && EmptyStack(&opt) != OK) || (str[i] == ')' && GetTop(&opt) != '(') || Priority(str[i]) <= Priority(GetTop(&opt)))//出栈并参与运算 53 { a1=Pop2(&num); 54 a2=Pop1(&num); 55 a3=Pop2(&num); 56 a4=Pop1(&num); 57 a5=Popt(&opt); 58 Calculator(a1,a2,a3,a4,a5,temps);//计算中间结果,得到字符串temps 59 // getfenzifenmu(&s,&m,temps); 60 if(temps[0]=='-') 61 return -1;//判断中间结果是否为负 62 63 getfenzifenmu(&s,&m,temps); 64 if(Push1(&num,m,s)==ERROR) 65 printf("Push3 ERROR!");//非负则中间结果入栈 66 continue; 67 } 68 } 69 } 70 71 Simplify(s,m,fans);//化简分数,得到字符串fans 72 //printf("%d.是%s\n",y,fans); 73 fprintf(fp,"%d.%s\n",y,fans);//将答案写进文件 74 fclose(fp); 75 return 1; 76 }
·分数化简函数:将原始分数化简为整数,真分数或带分数,将结果返回生成答案函数以写进答案文件。
1 void Simplify(int s,int m,char str[])//分数化简 2 { 3 int d,g,s1; //d为带分数的整数部分或者整数,g为s和m的最大公约数 4 char son[20]={'\0'}; 5 char mom[20]={'\0'}; 6 char n[20]={'\0'}; 7 if(s%m==0){ 8 d=s/m; 9 itoa(d,str,10); 10 } 11 else if(s>m){ 12 d=s/m; 13 s1=s-d*m; 14 g=gcd(s1,m); 15 itoa(d,n,10); 16 itoa(s1/g,son,10); 17 itoa(m/g,mom,10); 18 strcat(n,"'"); 19 strcat(n,son); 20 strcat(n,"/"); 21 strcat(n,mom); 22 strcpy(str,n); 23 } 24 else{ 25 g=gcd(s,m); 26 itoa(s/g,son,10); 27 itoa(m/g,mom,10); 28 strcat(son,"/"); 29 strcat(son,mom); 30 strcpy(str,son); 31 } 32 }
·生成成绩函数:以给定题目文件和答案文件作为参数,由题目文件利用求答案函数计算正确答案,并与给定答案进行比对,最后生成成绩文件,显示正确和错误的 题目数和具体题号。
1 void check(char exercisefile[],char answerfile[]) 2 { 3 FILE *f1,*f2,*f3; 4 int correct=0,wrong=0; //分别为对和错的题目数量 5 int n1=0,n2=0;//题目序号 6 int i; 7 int correctno[10000]={0}; 8 int wrongno[10000]={0}; 9 char question[25]="\0"; 10 char answer[25]="\0"; 11 char canswer[25]="\0"; //正确答案 12 f1=fopen(exercisefile,"r"); 13 f2=fopen(answerfile,"r"); 14 f3=fopen("Grade.txt","w"); 15 while(!feof(f1)) 16 { 17 if(getquestion(f1,&n1,question)) //读取题目失败 18 break; 19 getanswer(f2,&n2,answer); 20 Answer1(question,canswer); 21 if(!strcmp(canswer,answer)) //答案正确 22 { 23 correctno[correct]=n1; 24 correct++; 25 } 26 else{ 27 wrongno[wrong]=n2; 28 wrong++; 29 } 30 } 31 fprintf(f3,"Correct: %d (",correct); 32 for(i=0;i<correct;i++) 33 { 34 fprintf(f3,"%d",correctno[i]); 35 if(i!=correct-1) 36 fprintf(f3,", "); 37 } 38 fprintf(f3,")\nWrong: %d (",wrong); 39 for(i=0;i<wrong;i++) 40 { 41 fprintf(f3,"%d",wrongno[i]); 42 if(i!=wrong-1) 43 fprintf(f3,", "); 44 } 45 fprintf(f3,")"); 46 fclose(f1); 47 fclose(f2); 48 fclose(f3); 49 }
·测试运行:
·生成10道题目且数字不超过10的文件Exercises.txt同时生成答案文件Answers.txt:
·当-r后的参数为1时,即出现的数字均为0,此时没有分数出现且没有除运算:
·给定题目文件Exercises.txt和答案文件Answers.txt,生成成绩文件Grade.txt:
·当用户参数输入缺漏时,将输出提示:
·PSP:
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 30 | 15 |
Estimate | 估计这个任务需要多少时间 | 30 | 15 |
Development | 开发 | 1310 | 1410 |
Analysis | 需求分析 (包括学习新技术) | 60 | 100 |
Design Spec | 生成设计文档 | 0 | 0 |
Design Review | 设计复审 (和同事审核设计文档) | 0 | 0 |
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 10 | 30 |
Design | 具体设计 | 180 | 210 |
Coding | 具体编码 | 1000 | 1020 |
Code Review | 代码复审 | 30 | 30 |
Test | 测试(自我测试,修改代码,提交修改) | 30 | 20 |
Reporting | 报告 | 120 | 145 |
Test Report | 测试报告 | 60 | 120 |
Size Measurement | 计算工作量 | 30 | 10 |
Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 30 | 15 |
总计 | 1460 | 1570 |
·项目小结,结对感受:
·结对编程,重在协助与交流,及时反馈进度,不断互相帮助,共同完成任务。
·要将自己的需求或遇到的难题表达清楚,表达模糊会为后续的工作带来麻烦。
·该项目存在许多细节问题,开发前应尽量做到全面思考和程序结构组织,有利于开发工作的顺利进行。
来源:https://www.cnblogs.com/Tsaiyue/p/12617260.html