阿超的四則運算(第二次作業)


GIT地址 https://github.com/StepEnter
GIT用戶名 StepEnter
學號后五位 62404
博客地址  https://www.cnblogs.com/step-enter/p/11543291.html
作業鏈接 https://www.cnblogs.com/harry240/p/11515697.html

 

 

 

 

 

 

 

Part 0. 背景

阿超家里的孩子上小學一年級了,這個暑假老師給家長們布置了一個作業:家長每天要給孩子出一些合理的,但要有些難度的四則運算題目,並且家長要對孩子的作業打分記錄。

作為程序員的阿超心想,既然每天都需要出題,那何不做一個可以自動生成小學四則運算題目與解決題目的命令行 “軟件”呢。他把老師的話翻譯一下,就形成了這個軟件的需求:

  • 程序接收一個命令行參數 n,然后隨機產生 n 道加減乘除(分別使用符號+-*/來表示)練習題,每個數字在 0 和 100 之間,運算符在 2 個 到 3 個之間。
  • 由於阿超的孩子才上一年級,並不知道分數。所以軟件所出的練習題在運算過程中不得出現非整數,比如不能出現 3÷5+2=2.6 這樣的算式。

創建程序,我在這里使用Visual Studio 2019

 

 

Part 1. 配置環境

由於配置環境安裝Git和VS2019篇幅較多,所以分開寫了,詳見上一篇博客:https://www.cnblogs.com/step-enter/p/11542956.html

安裝VS時沒有遇到什么問題。現在就來說說安裝Git時吧。Git是一個超好用的分布式版本控制系統,它能敏捷高效的處理任何或小或大的項目,但安裝Git時,總是安裝不上,過了很久才發現,自己安裝了一個與自己電腦不一樣的版本,導致一致安裝不上。后來在官網上重新下載了一個,最后安裝成功。

 

 

Part 2. 克隆項目

要求:我們需要將我們做的項目放在倉庫地址中:步驟如下所示:

1.如圖所示: https://github.com/join 這個網址處成功申請注冊一個 Github 賬號登陸名為:StepEnter

 

2.成功登錄后,輸入阿超倉庫的網址 https://github.com/Cherish599/AchaoCalculator 點擊Fork ,將阿超的四則運算庫拷貝到自己的同名倉庫中,如下圖所示:

 

3.如下圖所示,賬號名為StepEnter的用戶以從AchaoCalculator中獲取到了阿超的四則運算庫。

 

4.點擊Clone or download,復制下拉框鏈接,如圖所示:

 

 

 5.返回桌面,點擊右鍵,點擊Git Bash Here,如圖所示:

 

出現Git命令行界面:

 

Git命令行中寫入:

git clone https://github.com/StepEnter/AchaoCalculator.git(這個地址是我們 Fork 后倉庫的地址,點擊回車

git config --global user.name "你的用戶名"

git config --global user.email 你的郵箱號

接連:git add .

git commit -m "分支名稱"(如:git commit -m "apple")

得到以下界面:

 

 此刻即用Git記錄下所有的改動

現在到文件C:\Users\ASUS\Desktop中查找與倉庫同名的文件夾AchaoCalculator,這就是克隆到本地的項目截圖如下:

 

打開AchaoCalculator文件夾,截圖如下:

 

進入項目文件夾,新建一個文件夾,重命名為你的Github賬號名我的賬號為StepEnter截圖如下:

 

VS2019中新建項目,以Github賬號為項目名稱,以上述AchaoCalculator中剛創建的StepEnter文件夾的存放位置為路徑(如我的路徑為C:\Users\ASUS\Desktop\AchaoCalculator\StepEnter)。截圖如下:

 

項目創建成功后就開始我們的代碼部分,如下所示:

代碼部分

 創建一個Question的類,將所有有關問題的方法都放在Question里面,

public class Question

針對阿超這個問題我們需要設置下列幾個變量,從用戶端輸入的問題個數,隨機數,存放'+', '-', '*', '/'的字符數組,存放四則運算數字數組和存放四冊運算符號數組。如下所示

        public int question_num;//從用戶端輸入的問題個數
        public Random rand = new Random();//設置隨機數
        public char[] option = { '+', '-', '*', '/' };//將四則運算符號放在option里
        public int[] arr = new int[4];//一個存放四則運算數字數組
        public char[] op = new char[3];//一個存放四冊運算符號數組

創造一個制造表達式的函數,CreateQuestion。

        public void CreateQuestion(int question_num)//創造question_num個四則運算
        {
            this.question_num = question_num;
            for (int i = 0; i < this.question_num; )
            {
                int op_cnt = rand.Next(2, 4);//從rand中選出2-3個符號,op_cnt即符號個數
                for (int j = 0; j < op_cnt; j++)
                {
                    arr[j] = rand.Next(0, 100);//從0-99中隨機選出一個數放在arr[j]里
                    int temp = rand.Next(0, 4);//從0-3中取出一個數作為option的下標
                    op[j] = option[temp];//option[temp]里的符號存放在op[j]里
                }
                arr[op_cnt] = rand.Next(1, 100);//最后一個數(因為數字數始終比字符數大一個)
                if (Judge(op_cnt) == true)//判斷這個表達式是否滿足阿超的要求
                {
                    Write(op_cnt);//若滿足要求,則打印表達式
                    i++;//若滿足要求,繼續下一個表達式
                } 
            }
        }

其中Judge是一個判斷函數,若滿足條件返回一個bool形式的值。

        public bool Judge(int op_cnt)//判斷這個表達式是否滿足阿超的要求
        {
            for (int i = 0; i < op_cnt; ++i)
            {
                bool judge = calculate(arr[i], op[i], arr[i + 1]);
                if (judge == false)
                    return false;
            }
            return true;
        }

其中calculate是一個判斷函數,它的返回值也是一個bool形的值,如滿足條件,返回值為真。

        public bool calculate(int num1, char op_1, int num2)//判斷單個表達式是否滿足要求
        {
            int ans;
            switch (op_1)
            {
                case '+':
                    ans = num1 + num2;
                    break;
                case '-':
                    ans = num1 - num2;
                    if (ans < 0 )//判斷表達式是否會出現負數
                        return false;
                    break;
                case '*':
                    ans = num1 * num2;
                    break;
                case '/':
                    if (num2 == 0 || num1 % num2 != 0)//判斷分母不為零並計算是否是分數
                        return false;
                    break;
                default:
                    Console.WriteLine("發生錯誤!");
                    break;
            }
            return true;
        }

其中的打印函數為Write。

        public void Write(int op_cnt)//打印表達式
        {
            Console.WriteLine("-------------------------------------");
            for (int i = 0; i < op_cnt; i++)
            {
                Console.Write(arr[i]);
                Console.Write(op[i]);
            }
            Console.WriteLine(arr[op_cnt]);
        }    

程序運行結果為:

 說說感悟吧!這個題被老師提出來之后,我就在腦海中構思了一下這個題的過程,想着用C語言運用幾個函數在20分鍾內就能被搞定。但當我動手敲的時候,發現這個題並沒有我之前想的那么簡單。C#,這門語言雖然在暑期的時候學過,但當時沒有大量的練習,導致很多基礎的東西都忘記了,因此寫這個代碼花了很長的時間。最后我想說的是,因為太馬虎了,把CreateQuestion的循環中,下標j寫成了i,導致整個程序跑出來一直都是錯誤的,就這個問題花了我一下午的時間。這里希望大家能夠認真對待自己的程序,不要馬虎,一定要認真檢查代碼。

 

 

Part 3. 單元測試

在 VS2019里進行單元測試:

右鍵點擊Question大類,點擊創建單元測試,如圖所示:

 

 創建第一個測試:首先創建名為CreateQuestionTest類,目的是為了對隨機出現的option下標進行測試,如圖所示:

 

 按照以上方法分別對Judge,calculate進行測試,截圖如下:

 

 感悟:以前一直以為測試是需要很多大型機器和一群優秀的人通過復雜的編碼做的一項偉大的事。當我接觸到VS中測試時,我之前也一直以為測試對於我們這些小程序來說,跟設置斷點Debug是一樣的,但現在我才發現,測試不僅可以找Bug,還能進行很多更為復雜的測試。測試是指對一個完成了全部或部分功能、模塊的計算機程序在正式使用前的檢測,以確保該程序能按預定的方式正確地運行。為了發現程序中的錯誤,我通過對一個方法不斷地測試,最后改正錯誤后全部通過測試。

 

 

 

Part 4. 基本操作

1.斷點

設置斷點和單步運行。將要設置斷點的行號前左鍵單擊,如下圖所示,我在第 272930 行設了個斷點:

 

 設置斷點后運行截圖如下:可以看出我們進入的程序里面當前值的大小,比如這opop_cnt的值為3,也就是與我們控制台上輸入的n值一致。

 

 查找快捷鍵:點擊調試,則可看到以下界面:逐語句快捷鍵為F11,逐過程的快捷鍵為F10,跳出快捷鍵為shift+F11

 

 我們逐語句查看當前值的大小,截圖如下:

 

 

 

Part 5. 回歸測試

單元測試不僅僅用來保證當前代碼的正確性,更重要的是用來保證代碼修復、改進或重構之后的正確性。也就是說,在每次修改完 Bug 之后,我們其實都需要運行一遍來看看是不是滿足之前所有的單元測試樣例。所以,在每次因為現有的 failed test 而修復原有代碼后,最好都全部運行一遍單元測試,保證以前 passed test 仍然是可以通過的。

因此修復原有代碼后,運行全部的單元測試的截圖如下:

 

 

Part 6.效能分析


點擊工具欄里的分析,再點擊性能探察器,截圖如下:

 

選擇GPU使用情況和CPU占用率,截圖如下:

 

選擇GPU使用情況,截圖如下:

 CPU使用率截圖如下:

 

查看該解決方案在運行中占用CPU的情況,可以細化到每個調用的函數。可以以此分析所編寫的程序在哪里可以進行優化。

 效能分析可以查看當前具體函數的CPU使用率,這里比如查看StepEnter.Program::Main的函數CPU使用率,截圖如下:

 

 

Part 7.提交代碼

 利用 Github中git add和git commit命令對本地的倉庫進行修改,而這些操作都是離線的,因此,使用git push命令將Github跟蹤到最新改變。

 在使用該命令前,請確保所有本地的改動都已經 add 並 commit 了。可以用 git status來檢查:

 

 出現如圖所示的 nothing to commit 即說明已經可以 push 了。使用 push 命令后,會彈出一個窗口要求登錄 Github,此時輸入 Github 的 用戶名或郵箱 與 密碼 即可成功 push。

 

 登陸成功后,出現下列截圖:

在完成 push 后,我們就可以開始向源倉庫(即阿超的倉庫)發起 Pull Request(簡稱 PR ,指發起請求給倉庫貢獻代碼)。打開你 Fork 后的項目主頁,如圖所示,點擊按鈕 New pull request

 

 此時點擊 Create pull request 即可發起請求。

 

 

 

 Part 8. 感想與分享

 1. 這些天來,一直都在與馬虎做“斗爭”。不僅僅是安裝Git安裝錯版本,代碼下標i、j問題,還有單元測試問題。單元測試是真的弄得我都要絕望了,我在VS類里點擊右鍵,發現右鍵屬性里沒有“創建單元測試”這一項,我就在百度上尋找解決方案,發現可以用工具-->自定義-->上下文菜單->-編輯器上下文菜單|代碼窗口-->將“創建單元測試”這個菜單移到運行測試菜單下面,我以為這樣可以解決我右鍵屬性沒有創建單元測試的問題,結果發現還是沒有這一選項,然后我又重啟VS,右鍵出現了創建單元測試這一項,但這一項是暗的,不能點開。就這一個創建單元測試的小問題我就弄了好久好久。最后在同學的幫助下才發現,一開始創建項目的時候就創建錯了,導致后面創建不了單元測試,不能完成單元測試和回歸測試。折騰了一天,終於創建單元測試成功。雖然這些都是小問題,但還是需要細心謹慎,小問題可以牽扯出大問題,一個一個小問題堆積起來變得越來越大,因此在小問題出現時就要解決,不要等到最后才回過頭來找。

2.這些天我又使用VS創建一些小程序,不是我最熟悉的C語言,而是我最不熟悉的C#。通過這幾天的學習,我看到了我在C#學習上的不足,因為以前貪玩,導致C#的學習都落下了。到現在選喲使用C#時,才發現自己以前的問題。在學習每一門語言時,我們都要一步一個腳印,不要貪玩,更不要用意念編程,所有程序都需要自己手動敲一下,熟悉一下語言特有的規則,在學習的時候找到自己的錯誤和不足,不要等到后面做項目的時候才追悔莫及。

3.通過Git的安裝和使用,我了解到很多關於Git命令行的知識,通過簡易的命令,就可將我們所寫的代碼放到Github平台上。GitHub記錄了我們所有改動后的代碼,版本控制工具可以用於記錄程序開發過程中的每個版本。由於 Git 本身就是相當好用的工具,以及 GitHub 上聚集了許多牛人牛項目,所以除了單純的代碼托管以外,GitHub 也被視作程序員的 知識庫。學習Github的使用,讓我們提前進入了項目管理版本控制部分,感謝這次作業!!Y(^0^)Y

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM