1. 程式人生 > 其它 >201971010157-張穎 實驗三 結對專案-《{0-1}KP例項資料集演算法實驗平臺》

201971010157-張穎 實驗三 結對專案-《{0-1}KP例項資料集演算法實驗平臺》

專案 內容
課程班級部落格連結 2019級卓越班
這個作業要求連結 實驗三 軟體工程結對專案
我的課程學習目標
  1. 體驗軟體專案開發中的兩人合作,練習結對程式設計(Pair programming)。
  2. 掌握Github協作開發軟體的操作方法。
這個作業在哪些方面幫助我實現學習目標
  1. 自學《構建之法》第3、4章的內容,理解並體驗了結對程式設計
  2. 兩人一起共同討論,發現問題並解決問題
  3. 在github對結對方的程式碼進行一系列的操作
結對方學號-姓名 201971010106-陳玉英
結對方本次部落格作業連結 201971010106-陳玉英 實驗三 結對專案-《{0-1}KP例項資料集演算法實驗平臺》專案報告
本專案Github的倉庫連結地址 https://github.com/xiaokaxi08042/text2

任務1:閱讀《現代軟體工程—構建之法》第3-4章內容,理解並掌握程式碼風格規範、程式碼設計規範、程式碼複審、結對程式設計概念

程式碼規範-

  • 程式碼規範可以分為兩個部分:
  1. 程式碼風格規範-主要是文字上的規定、看似表面文章,實際上非常重要
  2. 程式碼設計規範-牽扯到程式設計、模組之間的關係、設計模式等方方面面的通用規則

程式碼風格規範-

  • 程式碼風格的原則是:簡明,易讀,無二義性
  1. 縮排:4個空格比tab鍵更好,tab鍵在不同的情況下會顯示不同的長度,嚴重干擾閱讀體驗,4個空格的距離從可讀性來說,正好。
  2. 行寬:行寬必須限制,以前有些文件規定的80字元行寬太小,現在可以先定為100字元
  3. 括號:在複雜的條件表示式中,用括號清楚地表示邏輯優先順序
  4. 斷行與空白的{}行:每個“{”和“}”都獨佔一行
  5. 分行:不要把多條語句放在一行上,更嚴格的說,不要把多個變數定義在一行上
  6. 命名:(1)在變數名中不要提到型別或其他語法方面的描述(2)避免過多的描述(3)如果資訊可以從上下文中得到,那麼此類資訊就不必寫在變數名中(4)避免可要不可要的修飾詞
  7. 下劃線:用來分隔變數名字中的作用域標註和變數的語義
  8. 大小寫:所有單詞的第一個字母都大寫(Pascal);第一個單詞全部小寫,隨後單詞隨Pascal形式
  9. 註釋:(1)解釋程式做什麼,為什麼這樣做,以及要特別注意的地方(2)複雜的註釋應該放在函式頭(3)註釋要隨著程式的修改而不斷更新(4)註釋應該只用ASCII字元,不要用中文或其他特殊字元

碼設計規範-

  • 程式碼設計規範不光是程式書寫的格式問題,而且牽扯到程式設計、模組之間的關係、設計模式等方方面面,這裡又有不少內容與具體程式設計語言息息相關,但是也有通用的規則,主要有——
  1. 函式:現代程式設計語言中的絕大部分功能,都在程式 的函式中實現
  2. goto:函式最好有單一的出口,為了達到這一目的,可以使用goto
  3. 錯誤處理:(1)引數處理(2)斷言
  4. 處理c++中的類

程式碼複審-

  • 定義:看程式碼是否在程式碼規範的框架內正確的解決了問題
  • 形式:

名稱

形式

目的

自我複審

自己vs.自己

用同伴複審的標準來要求自己。不一定最有效,因為開發者對自己總是過於自信。如果能持之以恆,則對個人有很大好處

同伴複審

複審者vs.開發者

簡單易行

團隊複審

團隊vs.開發者

有比較嚴格的規定和流程,適用於關鍵的程式碼,以及複審後不再更新的程式碼覆蓋率高——有很多雙眼睛盯著程式,但效率可能不高

  • 目的:
  1. 找出程式碼的錯誤
  2. 發現邏輯錯誤
  3. 發現演算法錯誤
  4. 發現潛在的錯誤和迴歸性錯誤
  5. 發現可能需要改進的地方
  6. 互相教育開發人員,傳授經驗
  • 步驟:
  1. 程式碼必須成功地編譯
  2. 程式設計師必須測試過程式碼
  3. 程式設計師必須提供新的程式碼,以及檔案差異分析工具
  4. 在面對面的複審中,一般是開發者控制流程,講述修改的前因後果。但是複審者有權在任何時候打斷敘述,提出自己的意見。
  5. 複審者必須逐一提供反饋意見。
  6. 開發者必須負責讓所有的問題都得到滿意的解釋或解答,或者在TFS中建立愛你新的工作項以確保這些問題會得到處理。
  7. 對於複審的結果,雙方必須達成一致的意見
  • 程式碼複審的核查表:
概要部分
  1. 程式碼符合需求和規格說明麼?
  2. 程式碼設計是否考慮周全?
  3. 程式碼可讀性如何?
  4. 程式碼容易維護麼?
  5. 程式碼的每一行都執行並檢查過了嗎?
設計規範部分
  1. 設計是否遵從已知的設計模式或專案中常用的模式?
  2. 有沒有硬編碼或字串/數字等存在?
  3. 程式碼有沒有依賴於某一平臺,是否會影響將來的移植(如Win32到 Win64 ) ?
  4. 開發者新寫的程式碼能否用已有的 Library/SDK/Framework 中的功能實現?在本專案中是否存在類似的功能可以呼叫而不用全部重新實現?
  5. 有沒有無用的程式碼可以清除?
程式碼規範部分

     修改的部分符合程式碼標準和風格麼?

具體程式碼部分
  1. 有沒有對錯誤進行處理?對於呼叫的外部函式,是否檢查了返回值或處理了異常?
  2. 引數傳遞有無錯誤,字串的長度是位元組的長度還是字元(可能是單/雙位元組)的長度,是以0開始計數還是以1開始計數?
  3. 邊界條件是如何處理的? switch語句的default分支是如何處理的?迴圈有沒有可能出現死迴圈?
  4. 有沒有使用斷言(Assert)來保證我們認為不變的條件真的得到滿足?
  5. 對資源的利用,是在哪裡申請,在哪裡釋放的?有無可能存在資源洩漏(記憶體、檔案、各種GUI資源、資料庫訪問的連線等等)?有沒有優化的空間?
  6. 資料結構中有沒有用不到的元素?
效能
  1. 程式碼的效能(Performance)如何?最壞的情況是怎樣的?
  2. 程式碼中,特別是迴圈中是否有明顯可優化的部分(C++中反覆建立類,C# 中 string的操作是否能用StringBuilder來優化)?
可讀性

      程式碼可讀性如何?有沒有足夠的註釋?

可測試性

      程式碼是否需要更新或建立新的單元測試?針對特定領域的開發(如資料庫、網頁、多執行緒等),可以整理專門的核查表。

結對程式設計-

  • 結程式設計是一個相互學習、相互磨合的漸進過程。
  • 優點:
  1. 在開發層次,結對程式設計能提供更好的設計質量和程式碼質量,良人合作解決問題的能力更強。兩人合作,還有相互激勵的作用,工程師看到別人的思路和技能,得到實時的講解,受到激勵,從而努力的提高自己的水平,提出更多的創意。
  2. 對開發人員來說,就地工作能帶來更多的信心,高質量的產出能帶來更高的滿足感。
  3. 在企業管理層次上,就地能更有效地交流,相互學習和傳遞經驗、分享知識,能更好地應對人員流動。
  • 兩人合作的不同階段和技巧:
  1. 萌芽階段
  2. 磨合階段
  3. 規範階段
  4. 創造階段
  5. 解體階段
  • 影響他人的幾種方式:
  1. 斷言
  2. 橋樑
  3. 說服
  4. 吸引
  • 評論別人的三種層次:
  1. 最外層:行為和後果
  2. 中間層:習慣與動機
  3. 最內層:本質和固有屬性
  • 如何正確地給予反饋:“三明治”辦法
  1. 先來一片面包,做好鋪墊:強調雙方的共同點,從團隊共同的願景講起,讓對方覺得處於一個安全的環境。
  2. 再把肉放上:這時就可以把建設性的意見加工好,加上生菜、佐料等。怎麼準備這塊肉也有講究,在提供反饋時,不宜完全沉溺於過去的陳年穀子爛芝麻,給別人做評價,下結論。這樣會造成一種“你就是做得不好,我恨你”的情緒。不妨換個角度,展望將來的結果,強調“過去你做得不夠,但是我們以後可以做得更好”。在技術團隊裡,我們的反饋還是要著重於“行為和後果”這一層面,不要貿然深入到“習慣和動機”、“本質”除非情況非常嚴峻,需要觸動別人內心深處,讓別人懸崖勒馬。
  3. 再來一片面包:呼應開頭,鼓勵對方把工作做好。

任務2:兩兩自由結對,對結對方《實驗二 軟體工程個人專案》的專案成果進行評價

  • 符合(2)要求的程式碼審查表:
概要部分                                       
程式碼符合需求和規格說明麼? 符合
程式碼設計是否考慮周全? 考慮的不是很周全
程式碼可讀性如何? 可讀性好,有註釋
程式碼容易維護麼? 層次清晰,模組化不錯,遵從基於介面而非實現程式設計的原則,容易維護
程式碼的每一行都執行並檢查過了嗎?
設計規範部分  
設計是否遵從已知的設計模式或專案中常用的模式?
有沒有硬編碼或字串/數字等存在? 沒有直接將資料嵌入到程式中,沒有硬編碼存在
程式碼有沒有依賴於某一平臺,是否會影響將來的移植(如Win32到 Win64 ) ? 沒有依賴於某一平臺
開發者新寫的程式碼能否用已有的 Library/SDK/Framework 中的功能實現?在本專案中是否存在類似的功能可以呼叫而不用全部重新實現? 沒有用其功能實現
有沒有無用的程式碼可以清除?
程式碼規範部分  
修改的部分符合程式碼標準和風格麼? 符合
具體程式碼部分  
有沒有對錯誤進行處理?對於呼叫的外部函式,是否檢查了返回值或處理了異常? 有對錯誤進行處理,對於呼叫的外部函式,檢查了返回值沒有發現錯誤
引數傳遞有無錯誤,字串的長度是位元組的長度還是字元(可能是單/雙位元組)的長度,是以0開始計數還是以1開始計數? 引數傳遞沒有錯誤,字串的長度是字元的個數,ASCII碼下也是位元組數,是以0開始計數
邊界條件是如何處理的? switch語句的default分支是如何處理的?迴圈有沒有可能出現死迴圈? 沒有用到switch語句,沒有出現死迴圈
有沒有使用斷言(Assert)來保證我們認為不變的條件真的得到滿足? 沒有使用斷言
對資源的利用,是在哪裡申請,在哪裡釋放的?有無可能存在資源洩漏(記憶體、檔案、各種GUI資源、資料庫訪問的連線等等)?有沒有優化的空間? 因程式功能較為簡單,沒有使用到GUI資源、資料庫等
資料結構中有沒有用不到的元素? 沒有用不到的元素
效能  
程式碼的效能(Performance)如何?最壞的情況是怎樣的? 效能一般,在資料量很大時會執行較長時間
程式碼中,特別是迴圈中是否有明顯可優化的部分? 沒有明顯可優化的部分
可讀性  
程式碼可讀性如何?有沒有足夠的註釋? 可讀性很好,註釋足夠
可測試性  
程式碼是否需要更新或建立新的單元測試?針對特定領域的開發(如資料庫、網頁、多執行緒等),可以整理專門的核查表。 實驗二的程式碼沒有使用到資料庫、網頁等的開發
  • 結對方專案倉庫中的Fork、Clone、Push、Pull request、Merge pull request日誌資料

    Fork 是 Github 上的常用操作之一,不同於 Star,Fork 會將進行 Fork 操作那一刻的倉庫程式碼完全複製到自己的倉庫下。Fork 之後,可能會為原倉庫新增一個 Feature,之後發起 Pull Request

克隆:

執行:

fork:

任務3:採用兩人結對程式設計方式,設計開發一款{0-1}KP 例項資料集演算法實驗平臺

  • 需求分析陳述——採用“3W”分析法
    • what:需求是什麼
    1. 採用動態規劃法、貪心演算法和回溯演算法求解不超過揹包容量的最大價值和解向量
    2. 繪製價值重量為橫軸,價值為縱軸的資料散點圖
    3. 輸出的最優解和求解時間可儲存為txt檔案
    4. 例項資料集儲存在資料庫
    5. 平臺可動態嵌入任何一個有效的{0-1}KP 例項求解演算法,並儲存演算法實驗日誌資料;
    6. 人機互動介面為GUI介面
    7. 設計遺傳演算法求解{0-1}KP,並利用此演算法測試要求
    • why:為什麼會產生這樣的需求
    1. 用多種演算法解決0-1揹包問題
    2. 更好的儲存和管理資料
    3. 增加使用者的體驗感
    • how:如何將需求轉化為產品進行後續的價值分析
  • 軟體設計說明
  • 軟體實現及核心功能程式碼展示:軟體包括哪些類,這些類分別負責什麼功能,他們之間的關係怎樣?類內有哪些重要的方法,關鍵的方法是否需要畫出流程圖?

    遺傳演算法:遺傳演算法類似於自然進化,通過作用於染色體上基因尋找好染色體來求解問題。及自然界相似,遺傳演算法對求解問題本身一無所知,它所需要僅是對演算法所產生每個染色體進行評價,並基於適應值來選擇染色體,使適應性好染色體有更多繁殖機會。在遺傳演算法中,通過隨機方式產生若干個所求解問題數字編碼,即染色體,形成初始群體;通過適應度函式給每個個體一個數值評價,淘汰低適應度個體,選擇高適應度個體參加遺傳操作,經過遺傳操作後個體集合形成下一代新種群。對這個新種群進行下一輪進化。

    演算法流程圖:

    • 遺傳演算法-GAType類
class GAType(): # 種群
    def __init__(self, obj_count):
        self.gene = [0 for x in range(0, obj_count, 1)]   # 序列編碼 0 / 1
        self.fitness = 0 # 適應度
        self.cho_feq = 0 # choose 選擇概率
        self.cum_feq = 0 # cumulative 累積概率
class genetic():
    def __init__(self, value, weight, max_weight):
        self.value = value
        self.weight = weight
        self.max_weight = max_weight
        self.obj_count = len(weight)
        self._gatype = [GAType(self.obj_count) for x in range(0, population_size, 1)]
        self.total_fitness = 0

Back_pack類:(部分功能程式碼)

 def draw(self):  # 畫散點圖
        nums_pro = self.str_profit[0:len(self.str_profit)]
        nums_wei = self.str_weight[0:len(self.str_weight)]
        nums_pro = [int(i) for i in nums_pro]
        nums_wei = [int(i) for i in nums_wei]
        df = pd.DataFrame({'profit': nums_pro, 'weight': nums_wei})
        df.plot(kind="scatter", x="weight", y="profit")
        plt.show()
    def DP(self):  # 動態規劃演算法
        dp = [[[0 for k in range(self.cubage + 5)] for i in range(4)] for j in range(self.size + 5)]  # 三維dp陣列
        for k in range(1, self.size + 1):
            for i in range(1, 4):
                for v in range(self.cubage + 1):
                    for j in range(1, 4):
                        dp[k][i][v] = max(dp[k][i][v], dp[k - 1][j][v])
                        if v >= self.items[k - 1].pack[i - 1].weight:
                            dp[k][i][v] = max(dp[k][i][v],dp[k - 1][j][v - self.items[k - 1].pack[i - 1].weight]+self.items[k - 1].pack[i - 1].profit)
                        self.max_val = max(self.max_val, dp[k][i][v])

資料庫-sql

config = {
    'host': 'localhost',
    'port': 3306,
    'user': 'root',
    'password': 'root',
    'db': 'dk',
    'charset': 'utf8',
    'cursorclass': pymysql.cursors.DictCursor,
}
  • 程式執行:程式執行時每個功能介面截圖。

主頁面(GUI介面):

繪製散點圖:

    • 資料庫儲存的資料:

遺傳演算法:

匯出結果檔案:

  • 描述結對的過程,提供兩人在討論、細化和程式設計時的結對照片(非擺拍)。

    理解了領航員和駕駛員兩種角色關係:兩人都必須參與編碼工作,在結對程式設計中兩個人輪流做對方的角色。

    採用了漢堡包法實施專案結對中兩個人的溝通:

討論的步驟總結:

  • 提交原始碼到Github專案倉庫中,編撰兩人合作開發遵守共同認可的編碼規範,提交專案程式碼規範文件到Github專案倉庫根目錄下

 

  • 提供此次結對作業的PSP。
PSP2.1 任務內容 計劃完成需要的時間(h) 實際完成需要的時間(h)
Planning 計劃 1 1
Estimate 估計這個任務需要多少時間,並規劃大致工作步驟 1 1
Development 開發 16.5 21.5
Analysis 需求分析(包括學習新技術) 5 7
Design Spec 生成設計文件 0.5 0.5
Design Review 設計複審 0.5 0.5
Coding Standard 程式碼規範 0.5 0.5
Design 具體設計 1 1
Coding 具體編碼 5 5
Code Review 程式碼複審 1 2
Test 測試 3 5
Reporting 報告 6.3 9.8
Test Report 測試報告 5 8
Size Measurement 計算工作量 0.3 0.3
Postmortem &Process Improvement Plan 事後總結,並提出過程改進計劃 1 1.5
  • 小結感受:兩人合作真的能夠帶來1+1>2的效果嗎?通過這次結對合作,請談談你的感受和體會。

    通過這次結對實驗合作,讓我覺得1+1真的大於2,我們兩個人在彼此溝通的過程中,都能發現對方沒有注意到的問題,這是一個人需要經過很長時間才能意識到的。三人行,必有我師。也就是說每個人都有自己的優劣點以及自己獨創的想法。結對完成專案有助於產生不同種想法,從而有助於在決策的時候可以集思廣益而產生一種比較好的方案。人無完人,一個人的力量有限,若是個人單打獨鬥難以把全部事情都做盡做全。但是兩人分工合作的話,就會有監督有分工,還能提高自身的效率。

任務4:完成結對專案報告博文作業