這個作業屬於哪個課程 | <2021春軟件工程實踐_W班 (福州大學)> |
---|---|
這個作業要求在哪里 | <軟工實踐寒假作業2/2> |
這個作業的目標 | <1.閱讀《構建之法》並提問2.完成詞頻統計個人作業> |
作業正文 | 見下方目錄 |
其他參考文獻 | 菜鳥教程-python學習 CSDN-fork與pull request CSDN-測試用例如何提高代碼覆蓋率 CSDN-python使用unnitest測試 CSDN-元典排序 知乎-計算機領域的大牛、大神們(包括歷史上的以及現在的)有哪些奇聞軼事? |
GitHub地址:詳情
作業基本信息 2021-3-3...
目錄:
-
任務一
Question1-Chapter3軟件工程師的成長
Question2-Chapter3軟件工程師的成長
Question3-Chapter5
Question4-Chapter8需求分析
Question5-Chapter8需求分析
Question6-Chapter9項目經理
Question7-Chapter4兩人合作
附加題 -
任務二
GitHub項目地址
PSP表格
解題思路描述
代碼規范制定鏈接
設計與實現過程
性能改進
單元測試
異常處理說明
心路歷程與收獲
任務一
提問
Question1-Chapter3軟件工程師的成長
我閱讀了第三章關於初級軟件工程師成長的5個小點(P49),對於其中的積累問題領域的知識和經驗和提升職業技能這兩點感觸頗深,但對於同樣成長的初級工程師如何去量化這兩個方面的提升呢(作為學生)?還是說這樣的積累是在工作崗位中不斷累積最終形成職業的晉升呢?這兩個點的掌握程度上級可以通過面試評估出來但作為學生的我們又需要如何去提升它們呢?
A:我個人認為初級軟件工程師的成長有小部分在於學生階段的培養,很大部分在於工作崗位中不斷積累的能力。我更傾向於一種說法
在學校里學會學習的能力,在社會運用學習的能力
。故此,有工作經驗的人總歸是更具有優勢的,所以才提出來這一問題想知道在學校能否通過某些量化的方式去提升自己的職業素質。
Question2-Chapter3軟件工程師的成長
我閱讀了第三章練習與討論中第四個問題。(如下圖)我認為這是在程序開發過程中難以避免的問題,然而我們該 如何降低這種問題發生的頻率 呢?(個人認為前期的面向對象分析與設計是很重要,可是沒有投入到實際實踐中空於理論一定是會產生偏差的。即使是我在完成學生成績系統時,寫到后面也會發現冗余的可能影響篇幅巨大的需要修改的地方。)
A:在設計前期先確立一個面向對象系統,然后進行評估測試,在設計出一個demo時通過調查問卷的形式修改系統設計。到后期如果依舊出現這個問題,還是選擇重新設計再度修改,否則后期的新的修改可能會產生新的影響。希望能夠有其他的回答方向…(再重新回來看認為這個問題有些鑽空洞式的回答,畢竟無法去准確評估形勢與情況)
Question3-Chapter5
我閱讀了第五章對於團隊模式的集中分類后,認為功能團隊模式是最符合成熟的軟件開發流程的,然而究竟是是團隊創造項目還是項目主導團隊,我依舊對此感到難以權衡。
A:等到團隊成熟后應當是項目主導團隊,因為懂得擅長之處能夠快速高效;在團隊初成立時還是應當遵循項目經理的規划走。之所以提出這個問題,是因為在一次賽前我與一位同學交談,那個時候我們小組尚未確定選題,但是那位同學和我說其實是組長想要做什么項目為此去選擇符合他的隊員,最終得到一個適合這一項目的團隊進行開發,讓我思考了許久。
Question4-Chapter8需求分析
我閱讀了第八章需求分析,在其中筆者提及調差問卷式的提問具有兩個關鍵疏漏:實際答案並非我們所希望得到的答案(例:選擇最喜歡的搜索引擎,用戶給的回答可能是使用最頻繁的)以及容易帶有引導性。於是筆者引導我們去正確的設置調差問卷評估用戶需求。然而個人以為,不論是一個新產品的問世還是一個新需求的呈現,無非都是具有極其強烈引導性的,因為我們要抓住用戶的痛點,擴大化其痛點。與其不停的讓痛點用戶模糊的表述需求,似乎選擇先行制造界面再引導用戶修改效率更高?誠然,這樣做會使得軟件可能需要進行大規模修改,然后選擇題和主觀題是不是選擇題更容易作答些。但換句話來說這兩種方式皆有利有弊,個人偏向於先做demo再詢問,私以為效率更高些。
A:已在問題中給出個人理解。
Question5-Chapter8需求分析
我閱讀了第八章需求分析中的功能分析四象限,對於其中的殺手功能有一些疑惑。我曾經想要開發一個類似於收集衣服搭配的軟件,然而在我的不斷設想中(當時還沒有接觸產品學習)我所謂的功能在不斷的增加,新的功能(虛擬試衣)會覆蓋之前的功能成為“殺手功能”,可慢慢的我發現這一新出功能慢慢的成為了這個軟件中篇幅最大的內容,或者說他的內容超過了原先我認為的用戶痛點(也就是搭配模塊)。如果出現這種情況我們又該如何應對呢?就像我們常說根據用戶需求或是軟件發展添加新功能后,慢慢地隱蔽了原先的亮點。一個軟件功能的擴充是必不可少的,可如果失去了主次會不會就像沒有初心的人逐漸喪失競爭力一般。
A:我個人認為在設計時如果有更沖擊的思想點都可以再重新規划重點;如果確立中心了就不必再添加了。然而對這個問題還是請求助教老師能夠給予我答復。
回顧這一問題后,我個人認為成熟的產品經理可能就能夠合理的規避掉這一問題了。不懂得取舍,系統過於龐大沒有重點,那這個軟件也就沒有了亮點,雖然提供了便捷。專且精才是迎合大眾的點。但是不可置否,在未來軟件成熟后一定會有系統化的增加功能的用戶反饋,那么到那個時候該如何應對呢?
Question6-Chapter9項目經理
在小組開會的過程中,我們總是會抓住很小的但是重要的點討論非常久的時間,但整個主流框架都沒有討論清楚,花大量的時間在重要的末流過多的浪費了開會的時間,作為項目經理該如何去規避這個問題發生的頻率呢?
A:可能提前做好會議大綱會能夠起到一些幫助,但還是不足以解決。本質上,開放式的思考回答與獨斷式的思考回答有利有弊,但針對於項目初期,這兩種方式我並不能明確哪種方式更好。
Question7-Chapter4兩人合作
在第四章中看到這句話
結對編程中駕駛員和領航員的角色要經常互換,避免長時間緊張工作而導致觀察力和判斷力下降?
在這句話中我聯想到前后端的合作,是否前后端也需要適當的角色互換才能夠更理解互相交流時的需求呢?在實際生活中似乎少見這種互換的發生。
A:可能加強溝通交流也可以起到相應效果。角色互換在生活中似乎很少見到。
附加題
:大家知道了軟件和軟件工程的起源,請問軟件工程發展的過程中有什么你覺得有趣的冷知識和故事?
來源:知乎
自我小結
:在本次課程結束后回顧,你對你提出的問題是否有了新的理解?在實踐的過程當中,你用到了哪些知識?
任務二-WordCount編程
一、GitHub項目地址:詳情
二、PSP表格
PSP | Personal Software Process Stages | 預估耗時(分鍾) | 實際耗時(分鍾) |
---|---|---|---|
Planning | 計划 | 30 | 30+20(后又重新規划) |
• Estimate | • 估計這個任務需要多少時間 | 60 | 60 |
Development | • 開發 | 660 | 600 |
• Analysis | • 需求分析 (包括學習新技術) | 90 | 120 |
• Design Spec | • 生成設計文檔 | 30 | 40 |
• Design Review | • 設計復審 | 30 | 20 |
• Coding Standard | • 代碼規范 (為目前的開發制定合適的規范) | 120 | 90 |
• Design | • 具體設計 | 60 | 40 |
• Coding | • 具體編碼 | 60 | 40 |
• Code Review | • 代碼復審 | 60 | 90(尋求性能優化) |
• Test | • 測試(自我測試,修改代碼,提交修改) | 180 | 300 |
Reporting | 報告 | 120 | 100 |
• Test Repor | • 測試報告 | 90 | 90 |
• Size Measurement | • 計算工作量 | 10 | 10 |
• Postmortem & Process Improvement Plan | • 事后總結, 並提出過程改進計划 | 30 | 30 |
合計 | 1600 | 1630 |
解題思路描述
1.首先解決文件讀入問題。先編寫了一個打開文件並將文件內容輸出到控制窗的函數,並測試通過。
2.編寫函數框架,確立了幾個計算文件行數、字符數、單詞總數及輸出文件單詞前十的函數功能。
#啟動WordCount
def count_file(file1,file2)
#讀取文件內容並輸出到控制台 該函數測試通過后已刪除
#def read_file(filename)
#將字符串s輸出到指定文件路徑
def out_file(filename,s)
#清空指定文件內容
def clear_file(filename)
#統計文件的總字符數
def count_chars(file_name)
#計算文件中每一行的字符數
def count_line_chars(content)
#統計文件的有效行數
def count_lines(file_name)
#將文件內容轉換為單詞元組
def analy_word(file_name)
#統計文件的單詞總數(對應輸出第2行)
def count_word(file_name)
#統計文件中的各單詞出現次數
def count_words(file_name)
3.填充函數。進一步復習python語法,然后根據相關函數補齊功能,並通過自定義的方式測試函數的正確率。
4.通過main函數進行測試,將需要輸出的內容輸出到控制窗中。編寫一個input.txt作為測試用例。
5.將原本輸出到控制窗的內容輸出到output文件中。
6.將功能模塊化,並進行相應的修改與性能提升。
7.進行測試。
8.回顧與總結。
代碼規范制定鏈接
在代碼規范制定時,我發現在整個程序書寫完畢后最容易產生不匹配的便是空行和注釋的填寫。還沒有養成良好的代碼即寫即加注釋的習慣,需要繼續努力。
設計與實現過程
將函數列舉出來然后實現。
1.實現計算文件總字符數的函數的關鍵代碼
通過將文件中的每一行內容通過轉換成set函數形式然后計算該set的長度,最后添加。
#打開文件 將每行的字符數相加 然后返回字符串
with open(file_name,"r",encoding='utf-8') as file_obj:
for content in file_obj:
c_cs += count_line_chars(content)
#計算文件中每一行的字符數
result = 0
for i in set(content):
result = result + int(content.count(i))
2.實現計算文件有效行數的函數的關鍵代碼
將文件的每一行通過strip函數將換行符'\n'切割下來,以避免計算了空行,然后通過len函數計算實際的有效行數。
#統計文件的有效行數
for line in f:
line = line.strip('\n')
if len(line) == 0:
continue
s += 1
3.實現提取文件詞數的函數的關鍵代碼
一開始我將計算單詞總數和單詞詞頻的函數分開來,后來復查代碼時,為了提高函數速度提取出來。
通過compile函數和strip函數將文章中的單詞划分好,再通過lower函數將其中單詞最小化,用split函數將空格提取。在words元典中不斷添加word,並且重新將words中重復的添加到一起。最后將words元典返回。
def analy_word(file_name):
words = {}
r = re.compile(r"[,!\*\.]")
with open(file_name, "r",encoding='utf-8') as f:
for line in f:
for word in r.sub("", line.strip()).lower().split(" "):
if word in words:
words[word] += 1
words.setdefault(word, 1)
return words
4.實現計算文章單詞數量的函數的關鍵代碼
將返回的words元典,通過sum函數將每個values時添加起來。
#統計文件的單詞總數(對應輸出第2行)
words = analy_word(file_name)
result = sum(words.values())
5.實現計算文章單詞詞頻的函數的關鍵代碼
將words元典采用lambda函數按values降序,按key降序排序。最后輸出前十的單詞數和出現次數。
#統計文件中的各單詞出現次數
words = analy_word(file_name)
words2 = copy.deepcopy(sorted(words.items(), key=lambda k:(k[1],k[0]),reverse=True))
m = 0
s = ""
for i in words2:
if (m<10):
s += str(i[0])+":"+str(i[1])+"\n"
m+=1
性能改進
仔細查看了代碼后認為能夠提升性能的便是給字符排序的性能提升和錄入字符的性能提升。錄入字符可采用正則表達式進行分割(但在網絡上查閱正則表達式尚不理解,寫出來有bug存在故沒有進行改動),字符排序采用快速排序替代冒泡排序,可提升性能。
1.0個字符
2.10個字符
3.100個字符
4.1000個字符
5.10000個字符
6.100000個字符
7.1000000個字符
單元測試
1.實現統計文件字符數函數的測試
str內包含了特殊字符,測試了\t \r \n 三個字符的字符數皆為1。
def test_count_char(self):
str = "I have! a \t \r brother? \n"
...
#系統測試
WordCount.count_file(dir,"output_count_char.txt")
#單獨測試
WordCount.clear_file("s_output_count_chars.txt")
WordCount.out_file("s_output_count_chars.txt",s)
2.實現統計文件行數函數的測試
測試了\t和\n的區別,以及有效行數的判斷,若單純為\t一行不包含其他字符,也默認為1行。
str = "hello\nworld\t\nwwwwI \thave! a \t \r brother? \naaaaa\n"
...
#系統測試
WordCount.count_file(dir,"output_count_line.txt")
#單獨測試
WordCount.clear_file("s_output_count_line.txt")
WordCount.out_file("s_output_count_line.txt", s)
3.實現統計文件詞數和詞頻的測試
測試了特殊字符是否會被記為單詞。
str = "I have! a \t \r brother? \n He is four years older than me. "
WordCount.count_file(dir,"output_count_word.txt")
str = "I have a brother.have a brother. He is four years older than me. Now he is fifteen years old, and he is a student of Grade Nine. He is tall and handsome. His classmates like playing with him. He works hard in study. His teachers speak highly of him. Besides, basketball and running are his favorites."
#系統測試
WordCount.count_file(dir, "output_count_words.txt")
#單獨測試
WordCount.clear_file("s_output_count_word.txt")
WordCount.out_file("s_output_count_word.txt", s)
WordCount.clear_file("s_output_count_words.txt")
WordCount.out_file("s_output_count_words.txt", s)
使用Coverage計算測試覆蓋率:
如何優化測試覆蓋率:
通俗而言,采用完整業務流程進行測試,采用特定情況流程進行測試,要使得測試點覆蓋所有流程就能夠達到較高的覆蓋率。函數本身有太多的文件打開異常判斷,但由於文件打開異常判斷無法提取到函數前方,因為文件打開異常有可能隨時發生。其他由於字符串為空的判斷是根據文件打開異常所寫的,但由於打開異常便會自動結束程序所以也無法走到,應當修改這一塊的代碼。
異常處理說明
由於暫時只考慮到文件打開異常和文件不存在異常。
采用try-except語句,當文件不存在時報出異常並終止程序。
心路歷程與收獲
1.重新溫習了python基礎語法,重點溫習了文件輸入輸出相關函數。
2.針對出現的錯誤進行debug,然后發現很多錯誤出現在編碼方式里,有python等級不夠的問題也有python自身編碼方式的問題,最終修改成功。gebug果然需要耐心與細心才能完成,中間通過百度、尋找同學進行幫助,最終終於解決bug。
3.針對幾個函數的填充,我采用了python自帶的相應函數。相比而言,python真的比其他語言代碼長度簡短清晰。
4.模塊化的編碼方式改變了我以往喜歡在main函數里“大刀闊斧”的排版方式,轉變成精短的main函數構造,並且在測試文件中的引用也確實使得這個py文件能夠廣泛被調用。
5.單元測試模塊不斷地發現bug尋找解決方式,然后再發現bug…在這一模塊中我發覺了前期規划的不夠仔細,函數中的細微差錯和編碼方式問題。這種種問題令我不斷的重新返工修改函數。在這一模塊花費的時間與我想象中的差距很大,也讓我真正的意識到測試的重要性,僅僅是一個小小的WordCount文件就需要我不斷的返工修改,以達到相對的順利,那么未來那些復雜的文件便更需要我們的“無差錯”,更需要單元測試的完善與系統化。