201871030133-徐作朝 實驗三 結對項目—《D{0-1}KP 實例數據集算法實驗平台》項目報告


項目 內容
課程班級博客鏈接 課程班級博客鏈接
這個作業要求鏈接 作業要求鏈接
我的課程學習目標 (1)體驗軟件項目開發中的兩人合作,練習結對編程(Pair programming)。
(2)掌握Github協作開發程序的操作方法。
這個作業在哪些方面幫助我實現學習目標 (1)通過該實驗練習結對編程
(2)練習github操作方法並掌握
(3)掌握代碼編寫能力及規范
結對方學號-姓名 201871030109_韓誠
結對方本次博客作業鏈接 結對方本次博客作業鏈接
本項目Github的倉庫鏈接地址 項目Github的倉庫鏈接地址

任務一:理解並掌握代碼風格規范、代碼設計規范、代碼復審、結對編程概念

1.代碼規范

2.代碼復審

定義:看代碼是否在“代碼規范”的框架內正確地解決了問題

代碼復審形式:
名稱 形式 目的
自我復審 自己vs.自己 用同伴復審的標准來要求自己
同伴復審 復審者vs.開發者 簡便易行(最基本復審手段)
團隊復審 團隊vs.開發者 有比較嚴格的規定和流程,適用於關鍵的代碼
代碼復審目的:

1.找出代碼的錯誤

2.發現邏輯錯誤

3.發現算法錯誤

4.發現潛在的錯誤和回歸性錯誤

5.發現可能需要改進的地方

6.教育開發人員

代碼復審步驟:

復審前:

​ 1.代碼必須成功編譯

​ 2.程序員必須測試過代碼

​ 3.程序員必須提供新的代碼以及文件差異分析工作。用Windiff或VSTS自帶工具都可以

​ 4.面對面復審中,一般是開發者控制流程

​ 5.復審者必須逐一提供反饋意見

​ 6.開發者必須負責讓所有的問題都得到滿意解釋

​ 7.復審意見必須達成一致

復審后:

​ 1.更正明顯錯誤

​ 2.對於無法更正錯誤在項目管理軟件中創建Bug並記錄

​ 3.把錯誤記在“我常犯的錯誤”表中

3.結對編程
為什么要結對編程?

​ 每人在各自獨立設計、實現軟件的過程中不免要犯這樣那樣的錯誤。在結對編程中,因為有隨時的復審和交流,程序各方面的質量取決於一對程序員中各方面水平較高的那一位。這樣,程序中的錯誤就會少得多,程序的初始質量會高很多,這樣會省下很多以后修改、測試的時間。具體地說,結對編程有如下的好處:

(1)在開發層次,結對編程能提供更好的設計質量和代碼質量,兩人合作能有更強的解決問題的能力。

(2)對開發人員自身來說,結對工作能帶來更多的信心,高質量的產出能帶來更高的滿足感。

(3)在心理上, 當有另一個人在你身邊和你緊密配合, 做同樣一件事情的時候, 你不好意思開小差, 也不好意思糊弄。

(4)在企業管理層次上,結對能更有效地交流,相互學習和傳遞經驗,能更好地處理人員流動。因為一個人的知識已經被其他人共享。

如何結對編程?

(1)駕駛員:寫設計文檔,進行編碼和單元測試等XP開發流程。

(2)領航員:審閱駕駛員的文檔、駕駛員對編碼等開發流程的執行;考慮單元測試的覆蓋程度;是否需要和如何重構;幫助駕駛員解決具體的技術問題。

(3)駕駛員和領航員不斷輪換角色,不宜連續工作超過一小時。領航員要控制時間。

(4)主動參與。任何一個任務都首先是兩個人的責任,也是所有人的責任。沒有“我的代碼”、“你的代碼”或“她的代碼”,只有“我們的代碼”。

(5)只有水平上的差距,沒有級別上的差異。盡管可能大家的級別資歷不同,但不管在分析、設計或編碼上,雙方都擁有平等的決策權利。

結對編程是個漸進的過程

有效率的結對編程不是一天就能做到的。結對編程是一個相互學習、相互磨合的漸進過程。開發人員需要時間來適應這種新的開發模式。剛開始的結對編程很可能不比單獨開發效率更高。但是在度過了學習階段后,結對編程小組的開發質量、開發時間通常比兩人單獨開發有明顯的改善。

要避免的誤區
  1. 不分情況強迫每個任務都用結對編程的方式, 或者固執地遵守一些教條 (例如 "結對的成員必須水平相當..." 等等)

  2. 沒有提供足夠的支持就匆忙上馬結對編程 - 工作環境, 硬件, 對結果的期望都要准備好。

  3. 在具體作法上加入過多限制或要求 - 應該讓兩位程序員自己決定具體的方式。

不適合結對編程的情況

並不是所有的項目都適合結對編程,下面是一些不適合使用的例子。

1)處於探索階段的項目,需要深入地研究,在這種情況下,一個人長時間的獨立鑽研是有必要的。

2)在做后期維護的時候,如果維護的技術含量不高,只需要做有效的復審即可,不必拘泥於形式,硬拉一個人來結對唱二人轉。

3)如果驗證測試需要運行很長時間,那么兩個人在那里等待結果是有點浪費時間。

4)如果團隊的人員要在多個項目中工作,不能充分保證足夠的結對編程時間,那么成員要經常處於等待的狀態,反而影響效率。

5)關鍵是如何最大限度地發揮“領航員”的作用,如果用處不大,也就無需結對。

兩人合作的不同階段

1.萌芽

2.磨合階段

3.規范階段

4.創造階段

5.解體階段

兩人的合作——如何影響對方
方式 簡介 邏輯/感情 推/拉 注解
斷言 (Assertion) 就是這樣吧,聽我的,沒錯! 感情 推—— 主動推動同伴做某事 感情很強烈,適用於有充分信任的同伴。語音、語調、肢體語言都能幫助傳遞強烈的信息
橋梁 (Bridge) 能不能再給我講講你的理由…… 邏輯 拉—— 吸引對方,建立共識 給雙方充分條件互相了解
說服 (Persuasion) 如果我們這樣做,根據我的分析,我們會有這樣的好處,a、 b、 c…… 邏輯 推—— 讓對方思考 有條理,建立在邏輯分析的基礎上。即使不能全部說服,對方也可能接受部分意見
吸引 (Attraction) 你想過舒適的生活么?你想在家里發財么?加入我們的傳銷隊伍吧,幾個月后就可以有上萬元的收入…… 感情 拉—— 描述理想狀態,吸引對方加入 可以有效地傳遞信息,但是要注意信息的准確性。誇大的渲染會降低個人的可信度

任務二:對結對方《實驗二 軟件工程個人項目》的項目成果進行評價

結對方博客鏈接 https://www.cnblogs.com/hc82/p/14599887.html
結對方Github項目倉庫鏈接 https://github.com/ThreeTeaZ/ThreeTea
符合(1)要求的博客評論 https://www.cnblogs.com/hc82/p/14599887.html
clone結對方作業

代碼復審的核查表:
1.概要部分
(1)代碼能符合需求和規格說明么?
(2)代碼設計是否有周全的考慮?
(3)代碼可讀性如何? 良好
(4)代碼容易維護么? 容易
(5)代碼的每一行都執行並檢查過了嗎?
2.設計規范部分
(1)設計是否遵從已知的設計模式或項目中常用的模式?
(2)有沒有硬編碼或字符串/數字等存在?
(3)代碼有沒有依賴於某一平台,是否會影響將來的移植(如Win32到Win64)?
(4)開發者新寫的代碼能否用已有的Library/SDK/Framework中的功能實現?
(5)在本項目中是否存在類似的功能可以調用而不用全部重新實現?
(6)有沒有無用的代碼可以清除?
3.代碼規范部分
(1)修改的部分符合代碼標准和風格么(詳細條文略)? 符合
4.具體代碼部分
(1)有沒有對錯誤進行處理?對於調用的外部函數,是否檢查了返回值或處理了異常?
(2)參數傳遞有無錯誤,字
(3)邊界條件是如何處理的?Switch語句的Default是如何處理的?循環有沒有可能出現死循環? 無死循環
(4)有沒有使用斷言(Assert)來保證我們認為不變的條件真的滿足?
(5)有沒有可能優化?
(6)數據結構中是否有無用的元素?
5.效能
(1)代碼的效能(Performance)如何?最壞的情況是怎樣的?
(2)代碼中,特別是循環中是否有明顯可優化的部分?
(3)對於系統和網絡調用是否會超時?如何處理?
6.可讀性
代碼可讀性如何? 良好
7.可測試性
代碼是否需要更新或創建新的單元測試? 不需要

任務三:開發一款D{0-1}KP 實例數據集算法實驗平台

1.需求分析

​ 背包問題(Knapsack Problem,KP)是NP Complete問題,也是一個經典的組合優化問題,有着廣泛而重要的應用背景。它的一般描述為:給定n種物品和一背包。物品i的重量是wi,其價值為vi,背包的容量為C。問應如何選擇裝入背包的物品,使得裝 入背包中物品的總價值最大?
D{0-1} KP 是經典{ 0-1}背包問題的一個拓展形式,用以對實際商業活動中折扣銷售、捆綁銷售 等現象進行最優化求解,達到獲利最大化。D{0-1}KP數據集由一組項集組成,每個項集有3項物品可 供背包裝入選擇,其中第三項價值是前兩項之和,第三項的重量小於其他兩項之和,算法求解過程中, 如果選擇了某個項集,則需要確定選擇項集的哪個物品,每個項集的三個項中至多有一個可以被選擇 裝入背包,D{0-1} KP問題要求計算在不超過背包載重量 的條件下,從給定的一組項集中選擇滿 足要求裝入背包的項,使得裝入背包所有項的價值系數之和達到最大;D{0-1}KP instances數據 集是研究D{0-1}背包問題時,用於評測和觀察設計算法性能的標准數據集。

2.功能介紹

(1)平台基礎功能:實驗二 任務3;

(2)D{0-1}KP 實例數據集需存儲在數據庫;

(3)平台可動態嵌入任何一個有效的D{0-1}KP 實例求解算法,並保存算法實驗日志數據;

(4)人機交互界面要求為GUI界面(WEB頁面、APP頁面都可);

(5)查閱資料,設計遺傳算法求解D{0-1}KP,並利用此算法測試要求(3);

(6)附加功能:除(1)-(5)外的任意有效平台功能實現。

3.核心代碼
1)所需庫函數
import matplotlib.pyplot as plt
import linecache
import time
import datetime
import numpy as np
import os
import wx
2)界面類
class MyFrame(wx.Frame):
    def __init__(self,parent,id):
        wx.Frame.__init__(self, parent,id, title="首頁",size=(600,450))
        #創建面板
        panel = wx.Panel(self) 
        # 創建文本和輸入框
        self.title1 = wx.StaticText(panel ,label="D{0-1}KP 實例數據集算法實驗平台",pos=(60,20))
     
        #font  = wx.Font(14, wx.DEFAULT, wx.FONTSTYLE_NORMAL, wx.NORMAL)
        font  = wx.Font(16, wx.SWISS, wx.ITALIC, wx.LIGHT)
        self.title1.SetFont(font)
        
        self.bt_con  = wx.Button(panel,label='登錄/注冊',pos=(500,20))
        self.bt_con.Bind(wx.EVT_BUTTON,self.OnclickSubmit)
    
        self.bt_confirm = wx.Button(panel,label='首     頁',pos=(0,90))
        self.bt_cancel  = wx.Button(panel,label='查看數據',pos=(0,115))
        self.bt_cancel  = wx.Button(panel,label='動態規划',pos=(0,140))
        self.bt_cancel  = wx.Button(panel,label='回 溯 法',pos=(0,165))
        self.bt_cancel  = wx.Button(panel,label='遺傳算法',pos=(0,190))
        self.bt_cancel  = wx.Button(panel,label='降序排列',pos=(0,215))
        self.bt_cancel  = wx.Button(panel,label='畫散點圖',pos=(0,235))
        
        self.title2 = wx.StaticText(panel ,label="聯系我們",pos=(230,285))
        font1  = wx.Font(14, wx.DEFAULT, wx.FONTSTYLE_NORMAL, wx.NORMAL)
        #font  = wx.Font(16, wx.SWISS, wx.ITALIC, wx.LIGHT)
        self.title2.SetFont(font1)
        self.title = wx.StaticText(panel ,label="電子郵件:1119786516@qq.com",pos=(180,315))
        self.title = wx.StaticText(panel ,label="地址:西北師范大學",pos=(200,340))
        self.title = wx.StaticText(panel ,label="郵政編碼",pos=(230,365))
        self.title = wx.StaticText(panel ,label="聯系電話",pos=(230,390))

    def OnclickSubmit(self,event):
        """ 點擊確定按鈕,執行方法 """
        def fun():
            os.system("登錄.py")
        fun()
3)畫散點圖
def s1():
    weight=list4 
    profit=list3 
    plt.figure(figsize=(10, 10), dpi=100)
    plt.scatter(weight,profit)
    plt.show()
4)遺傳算法求解
def s4():
    start = time.time()
    def init(N,n):
        C = []
        for i in range(N):
            c = []
            for j in range(n):
                a = np.random.randint(0,2)
                c.append(a)
            C.append(c)
        return C
	##評估函數
	# x(i)取值為1表示被選中,取值為0表示未被選中
	# w(i)表示各個分量的重量,v(i)表示各個分量的價值,w表示最大承受重量
    def fitness(C,N,n,W,V,w):
        S = []##用於存儲被選中的下標
        F = []## 用於存放當前該個體的最大價值
        for i in range(N):
            s = []
            h  = 0  # 重量
            h=int(h)
            f  = 0  # 價值
            f=int(f)
            for j in range(n):
                if C[i][j]==1:
                    if h+W[j]<=w:
                        h=h+W[j]
                        f = f+V[j]
                        s.append(j)
            S.append(s)
            F.append(f)
        return S,F

	##適應值函數,B位返回的種族的基因下標,y為返回的最大值
    def best_x(F,S,N):
        y = 0
        x = 0
        B = [0]*N
        for i in range(N):
            if y<F[i]:
                x = i
            y = F[x]
            B = S[x]
        return B,y

## 計算比率
    def rate(x):
        p = [0] * len(x)
        s = 0
        for i in x:
            s += i
        for i in range(len(x)):
            p[i] = x[i] / s
        return p

	## 選擇
    def chose(p, X, m, n):
        X1 = X
        r = np.random.rand(m)
        for i in range(m):
            k = 0
            for j in range(n):
                k = k + p[j]
                if r[i] <= k:
                    X1[i] = X[j]
                    break
        return X1

	##交配
    def match(X, m, n, p):
        r = np.random.rand(m)
        k = [0] * m
        for i in range(m):
            if r[i] < p:
                k[i] = 1
        u = v = 0
        k[0] = k[0] = 0
        for i in range(m):
            if k[i]:
                if k[u] == 0:
                    u = i
                elif k[v] == 0:
                    v = i
            if k[u] and k[v]:
                # print(u,v)
                q = np.random.randint(n - 1)
                # print(q)
                for i in range(q + 1, n):
                    X[u][i], X[v][i] = X[v][i], X[u][i]
                k[u] = 0
                k[v] = 0
        return X
    
	##變異
    def vari(X, m, n, p):
        for i in range(m):
            for j in range(n):
                q = np.random.rand()
                if q < p:
                    X[i][j] = np.random.randint(0,2)

        return X
4.程序測試
1)界面

2)降序排序

3)畫散點圖

4)回溯法求解

5)遺傳算法求解

6)動態規划求解

5.描述結對過程

​ 由於我的結對方為舍友,所以我們都是在一起討論,並沒有在社交軟件上進行交流。

6.PSP
PSP2.1 任務內容 計划共完成需要的時間(min) 實際完成需要的時間(min)
Planning 計划 30 20
Estimate 估計這個任務需要多少時間,並規划大致工作步驟 30 20
Development 開發 450 385
Analysis 需求分析 (包括學習新技術) 30 18
Design Spec 生成設計文檔 20 15
Design Review 設計復審 (和同事審核設計文檔) 10 6
Coding Standard 代碼規范 (為目前的開發制定合適的規范) 20 15
Design 具體設計 100 90
Coding 具體編碼 180 200
Code Review 代碼復審 30 20
Test 測試(自我測試,修改代碼,提交修改) 30 21
Reporting 報告 60 70
Test Report 測試報告 20 20
Size Measurement 計算工作量 20 20
Postmortem & Process Improvement Plan 事后總結 ,並提出過程改進計划 20 30
7.實驗總結

​ 通過本次實驗,我對於github操作方法更加熟悉,並且對PSP的作用有了更深刻的認識,而且通過閱讀構建之法學習了代碼規范和代碼復審的知識,對於結對很有感想,結對以后會有三種效果,1+1<2;1+1=2;1+1>2;我認為這效果主要取決與和結對方的溝通,總的來說,結對做項目利大於弊。


免責聲明!

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



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