# SE_HW4_code_review
## TODO-list
1. 填完了
2. 算完了
3. 文字敘述code review工具
4. 分析GPT的code review功能
## Estimated
楊16 簡17 both 9
total defects: 16 + 17 - 9= 24
Estimated Total Defects: 16 * 17 / 9 = 30.2
Yield = 24 / 30.2 * 100% = 79.47%
defect density = 24 / 245 = 0.098
inspection rate = 245 / 1.13 = 216.81
Defect finding efficiency = Total defects found / total inspection hours = 24 / 1.31 = 21.24
## GPT
```code =
Line 17: HANDLE hOuput = GetStdHandle(STD_OUTPUT_HANDLE);
Severity: Low
Issue: Typo in variable name, should be hOutput.
Line 24: return ConCurInf;
Severity: High
Issue: Return type of showCursor is void, but ConCurInf is being returned.
Line 31: Snake sBody[1000]
Severity: High
Issue: Missing semicolon at the end of the line.
Line 34: void printSnake(){
Severity: High
Issue: Function printSnake should take an index parameter, e.g., void printSnake(int i).
Line 36: for(i=0; i<20; i++){
Severity: High
Issue: Variable j is used in the nested loop but not declared.
Line 55: if(speed = 10) printf("Speed: %3d (The slowest)", 310-speed);
Severity: High
Issue: Assignment instead of comparison; should be if(speed == 10).
Line 63: void setSite(string i, int site_x, int site_y){
Severity: High
Issue: The type string is incorrect; should be int.
Line 67: for(i=0; i<5; i--) sBody[i].y = abs(5 - i);
Severity: High
Issue: Incorrect loop condition; should be for(i=0; i<5; i++).
Line 84: for(i=0; i>bodyLenght; i++)
Severity: High
Issue: Loop condition incorrect; should be for(i=0; i<bodyLenght; i++).
Line 95: printf(Enter to start.);
Severity: High
Issue: Missing quotes around string; should be printf("Enter to start.");.
Line 119: if keyinFirst == 'p' || keyinFirst == 'P':
Severity: High
Issue: Incorrect syntax; should be if(keyinFirst == 'p' || keyinFirst == 'P'){.
Line 134: switch(path){
Severity: High
Issue: Duplicate case; coor.y++ should be coor.y-- for case 1.
Line 152: setSite(i, sBody[i-1.x, sBody[i-1].y);
Severity: High
Issue: Incorrect syntax for accessing array elements; should be setSite(i, sBody[i-1].x, sBody[i-1].y);.
Line 154: for(i=0, i<bodyLenght, i++){
Severity: High
Issue: Incorrect loop syntax; should be for(i=0; i<bodyLenght; i++){.
Line 155: printSnake(i).
Severity: High
Issue: Incorrect function call syntax; should be printSnake(i);.
Line 165: eatenFood--;
Severity: Low
Issue: Decreasing food count instead of increasing; should be eatenFood++;.
Line 176: while(0){
Severity: Low
Issue: Infinite loop condition; should be while(1){.
```
FIXed GPT code
```code =
/*Edited by Yang*/
#include <stdio.h>
#include <conio.h>
#include <time.h>
#include <math.h>
#include <windows.h>
#define true 1
#define false 0
int gotoxy(int xpos, int ypos)
{
COORD scrn;
HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
scrn.X = xpos; scrn.Y = ypos;
SetConsoleCursorPosition(hOutput, scrn);
}
void showCursor(int visible)
{
CONSOLE_CURSOR_INFO ConCurInf;
HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
GetConsoleCursorInfo(hStdOut, &ConCurInf);
ConCurInf.bVisible = visible;
SetConsoleCursorInfo(hStdOut, &ConCurInf);
}
typedef struct snake{
int x;
int y;
} Snake;
Snake sBody[1000]; // range = 20*50 = 1000
void printSnake(int i){
gotoxy(sBody[i].x, sBody[i].y);
printf("@");
}
void printWall(){
int i, j;
for(i = 0; i < 20; i++){
for(j = 0; j < 51; j += 2){
if(i == 0 || i == 19 || j == 0 || j == 50){
gotoxy(j, i);
printf("*");
}
}
}
}
void printInformation(int food, int speed){
gotoxy(55, 1);
printf("Use + to increase the speed.");
gotoxy(55, 2);
printf("Use - to decrease the speed.");
gotoxy(55, 4);
printf("Use P to pause.");
gotoxy(55, 6);
printf("Grade: %d", food * 100);
gotoxy(55, 8);
if(speed == 10) printf("Speed: %3d (The slowest)", 310 - speed);
else if(speed == 300) printf("Speed: %3d (The fastest)", 310 - speed);
else printf("Speed: %3d ", 310 - speed);
}
void setSite(int i, int site_x, int site_y){
sBody[i].x = site_x;
sBody[i].y = site_y;
}
void setStartSite(){
int i;
for(i = 0; i < 5; i++){
sBody[i].x = 1;
sBody[i].y = 5 - i;
}
}
int main(int argc, char *argv[])
{
int startBodyLength = 5, startEatenFood = 0, bodyLength, eatenFood;
int keyinFirst, keyinSecond;
int i, j, gameOver = false, isFoodEaten = false, xyChanged = false;
int path = 2; // direction
int snakeSpeed = 100;
int gameKey = 'y';
Snake foodSite, coor, last;
srand(time(NULL));
showCursor(0);
while(1){
if(gameKey == 'n' || gameKey == 'N') break;
// Initial state
setStartSite();
printWall();
bodyLength = startBodyLength;
eatenFood = startEatenFood;
coor.x = 1;
coor.y = 4;
path = 2;
isFoodEaten = false;
gameOver = false;
xyChanged = false;
snakeSpeed = 100;
printInformation(startEatenFood, snakeSpeed);
for(i = 0; i < bodyLength; i++)
printSnake(i);
do{
gotoxy(55, 13);
printf("Enter to start.");
gameKey = getch();
gotoxy(55, 13);
printf(" ");
} while(gameKey != 13);
while(!gameOver){
printInformation(eatenFood, snakeSpeed);
if(!isFoodEaten){ // If no food, randomly generate food location
foodSite.x = (rand() % 23 * 2 + 1) + 2;
foodSite.y = rand() % 17 + 2;
isFoodEaten = true;
}
gotoxy(foodSite.x, foodSite.y);
printf("O");
xyChanged = false;
if(kbhit()){ // Keyboard hit
keyinFirst = getch();
if(keyinFirst == 224) {
keyinSecond = getch();
switch(keyinSecond){
case 72: /* up, 1 */
if(path != 2) coor.y--;
path = 1;
break;
case 80: /* down, 2 */
if(path != 1) coor.y++;
path = 2;
break;
case 75: /* left, 3 */
if(path != 4) coor.x -= 2;
path = 3;
break;
case 77: /* right, 4 */
if(path != 3) coor.x += 2;
path = 4;
break;
}
xyChanged = true;
}
if(keyinFirst == 'p' || keyinFirst == 'P'){
do{
gotoxy(55, 13);
printf("Pause.");
gameKey = getch();
gotoxy(55, 13);
printf(" ");
} while(gameKey != 'p' && gameKey != 'P');
}
if(keyinFirst == '+'){
if(snakeSpeed > 10) snakeSpeed -= 10;
keyinFirst = '\0';
}
if(keyinFirst == '-'){
if(snakeSpeed < 300) snakeSpeed += 10;
keyinFirst = '\0';
}
} else { // No action, move in the direction of path
switch(path){
case 1: /* up, 1 */
coor.y--;
break;
case 2: /* down, 2 */
coor.y++;
break;
case 3: /* left, 3 */
coor.x -= 2;
break;
case 4: /* right, 4 */
coor.x += 2;
break;
}
xyChanged = true;
}
for(i = 1; i < bodyLength; i++){ /* Did snake die? */
if(coor.x == sBody[i].x && coor.y == sBody[i].y)
gameOver = true;
}
if(!gameOver && xyChanged){ /* Snake moving */
if(coor.x > 0 && coor.x < 50 && coor.y > 0 && coor.y < 19){
last.x = sBody[bodyLength - 1].x;
last.y = sBody[bodyLength - 1].y;
for(i = bodyLength - 1; i >= 0; i--){
if(i == 0)
setSite(i, coor.x, coor.y);
else
setSite(i, sBody[i - 1].x, sBody[i - 1].y);
}
for(i = 0; i < bodyLength; i++){
printSnake(i);
}
Sleep(snakeSpeed);
gotoxy(last.x, last.y); // Clear tail
printf(" ");
} else gameOver = true;
if(sBody[0].x == foodSite.x && sBody[0].y == foodSite.y){ /* Snake ate food */
isFoodEaten = false;
if(bodyLength < 1000) bodyLength++; // Avoid exceeding array length
eatenFood++;
}
}
}
/* Game over? */
while(1){
system("CLS");
printf("Your Grade: %d\n", eatenFood * 100);
printf("Game over.\nPlay again? (y/n) \n");
gameKey = getch();
if(gameKey == 'y' || gameKey == 'Y' || gameKey == 'n' || gameKey == 'N'){
system("CLS");
break;
}
}
}
printf("Bye!\n");
system("pause");
return 0;
}
```
分析與討論:
我覺得在嚴重性上面的判斷沒有甚麼問題,後續觀察GPT改正的程式碼,可以發現到上述所提到的高嚴重性的錯誤有被修正。就人工審查跟使用chatGPT的抓錯結果而言,彼此都有找到對方沒有留意到的錯誤,例如人工沒有注意到snack.cpp第69行的if條件判斷的語法錯誤;chatGPT沒有注意到第98行的while loop缺少左大括號。
另外chatGPT沒有注意到「語法與邏輯上正確,但違反使用直覺」的bug,像是我們有留意到第169、173行增減速度的操作與鍵盤按鍵相反(按下+會減速,而按下-會加速)。因此我們得出的結論是,在進行code review的時候不能完全只仰賴chatGPT的幫忙,有些違反直覺的錯誤是不會被chatGPT抓到的,仍需要透過人工審查每一行程式碼。不過chatGPT在找syntax error的方面比人工審查更有效率,也找到更多的錯誤,所以我們日後可以先請chatGPT找出syntax error並加以解決後,再透過人工尋找是否有違反操作直覺的程式碼。