# 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並加以解決後,再透過人工尋找是否有違反操作直覺的程式碼。