[TOC] ## 前言 題目來自TQC網站公開的參考試題,可以自行去搜尋相關詳情。 自己研究的解法,不一定是最好或最正確的,歡迎留言討論! 若對你有幫助請幫忙按讚以及留言,轉載請註明出處,畢竟也是花費時間心血想出來的。 希望對學習有幫助~~~ ^ O ^ 順便用此機會練習用pylint改善code,使pylint可以達到滿分10分,來增加寫法的可讀性以及通用性 pylint是一種python 格式語法檢查器,其他還可以使用pyflakes或pep8。 試卷編號:PY3-0001 考試時間100分鐘,滿分100分,合格分數70分。 ## 進入正題-TQC Python3 術科參考試題與參考解答 1. 數字、字串格式處理 ![image](https://hackmd.io/_uploads/SJX_l4OBR.png) * 參考答案 ```PYTHON= import math def main(): num_list=[] count = 0 print("Enter 1 to 4 digits below the decimal point") while count< 4: input_num = input('') # limit input less or equal to 4 digits below the decimal point # check not a symbol or char # check enter total 4 numbers if(len(input_num.split(".")[1])<=4 and float(input_num) and count<=4): count+=1 num_list.append(input_num) else: print("Usage: Enter 1 to 4 digits below the decimal point") quit() # print num_list align to right for i in range(0,4): # display a float with two decimal places list_num = str('%.2f'% float(num_list[i])) if (i+1)%2!=0: print("|", end="") #str.rjust(align in n space) print(list_num.rjust(7,' '),end="") elif (i+1)%2==0: print(list_num.rjust(8,' '), end="") print("|") # print num_list align to left for i in range(0,4): # display a float with two decimal places list_num = str('%.2f'% float(num_list[i])) if (i+1)%2!=0: print("|", end="") #str.rjust(align in n space) print(list_num.ljust(8,' '),end="") elif (i+1)%2==0: print(list_num.ljust(7,' '), end="") print("|") main() ``` * result: ![image](https://hackmd.io/_uploads/ByV5pAFBC.png) </br> * 1st time scored by pylint ![image](https://hackmd.io/_uploads/BJJ5cmiSA.png) </br></br> 看起來很糟糕只有5.52分,查pylint doc改寫一下。 ```python= """Module print 4 numbers align to left and right, having 7 spaces for each number""" import sys def main(): """print out numbers formated as: |....num.....num| |....num.....num| |num.....num....| |num.....num....|""" num_list=[] count = 0 print("Enter 1 to 4 digits below the decimal point") while count< 4: input_num = input('') if(len(str(float(input_num)).split(".")[1])<=4 and float(input_num) and count<=4): count+=1 num_list.append(input_num) else: print("Usage: Enter 1 to 4 digits below the decimal point") sys.exit() # print num_list align to right, using str.rjust(align in n space) for i in range(0,4): # display a float with two decimal places if (i+1)%2!=0: print("|" + f"{float(num_list[i]):0.2f}".rjust(7,' '),end="") elif (i+1)%2==0: print(f"{float(num_list[i]):0.2f}".rjust(8,' ') + "|") # print num_list align to left, using str.ljust(align in n space) for i in range(0,4): if (i+1)%2!=0: print("|" + f"{float(num_list[i]):0.2f}".ljust(8,' '),end="") elif (i+1)%2==0: print(f"{float(num_list[i]):0.2f}".ljust(7,' ') + "|") main() ``` * 再次確認輸出結果正確 ![image](https://hackmd.io/_uploads/HyXyExnrC.png) * 不斷的改進後得到pylint新的評價為滿分 ![image](https://hackmd.io/_uploads/HJv9VenHC.png) ![image](https://hackmd.io/_uploads/ryTFVg3rR.png) ![image](https://hackmd.io/_uploads/Sygc_Ve2HR.png) ![image](https://hackmd.io/_uploads/r1fGNe2SA.png) * 其他解法,盡量用f string的方式以及內建函式: ```python= """Using other expression""" def main(): """use format()""" listnum = [input("") for _ in range(4)] try: check_if_number = [f'{float(string):0.2f}' for string in listnum] # alternative: check_if_number = ['{:0.2f}'.format(float(string)) for string in listnum] align_rtext = '|'+ '{:>7}' + '{:>8}' + '|' align_ltext = '|'+ '{:<8}' + '{:<7}' + '|' print(align_rtext.format(check_if_number[0], check_if_number[1])) print(align_rtext.format(check_if_number[2], check_if_number[3])) print(align_ltext.format(check_if_number[0], check_if_number[1])) print(align_ltext.format(check_if_number[2], check_if_number[3])) except ValueError: print("Usage: Enter 4 numbers") main() ``` </br></br></br> 2. 確認是否是某數的倍數__ ![image](https://hackmd.io/_uploads/r1uxlaYrR.png) </br> * 參考答案 ```PYTHON= """Module function checks the input number is multiply of 5 or 3 or both or neither""" import sys while True: try: input_num = int(input("Enter a positive integer: ")) if input_num % 5==0 or input_num%3==0: if input_num % 5==0 and input_num%3==0: print(f"{input_num}" +" "+"is a multiple of 3 and 5.") elif input_num % 5==0: print(f"{input_num }" +" "+"is a multiple 5.") else: print(f"{input_num }" +" "+"is a multiple 3.") else: print(f"{input_num }" +" "+"is not a multiple of 3 or 5.") except ValueError: sys.exit("Usage: Enter a positive integer") ``` 增加功能:如果使用者輸入非整數(小數或符號),則會顯示"Usage: Enter a positive integer",並離開程式。 * result: ![image](https://hackmd.io/_uploads/SJL7CKcr0.png) </br></br></br> 3. 迴圈偶數連加 ![image](https://hackmd.io/_uploads/rJOORtqS0.png) * 參考答案 ```python= """This module calculate sum range from input numbers, if it's even""" import sys def check_even(num): """check input number is even or odd""" if num%2==0: return True return False def main(): """calculate and print sum""" list_num=[] try: for _ in range(2): num=input(" ") if num.isdigit(): list_num.append(int(num)) except IndexError: sys.exit("Enter 2 positive integers a, b. a < b") if list_num[1]<list_num[0]: print("The first input has to be smaller than the second input") sys.exit() else: if check_even(list_num[0]): stnum = list_num[0] else: stnum = list_num[0]+1 if check_even(list_num[1]): endnum = list_num[1] else: endnum = list_num[1]-1 sum_even = (stnum + endnum)*((endnum-stnum)//2+1)//2 print(sum_even) main() ``` * result ![image](https://hackmd.io/_uploads/rJrscp5rA.png) </br></br></br> 4.不定數迴圈-最小值 ![image](https://hackmd.io/_uploads/SJL05pcSC.png) * 參考答案 ```python= """This module print out the smallest number""" import sys list_num=[] while True: try: num = int(input("")) list_num.append(num) if num ==9999: break except TypeError: sys.exit("Enter numeric number") list.remove(list[len(list)-1]) print(min(list)) sys.exit() ``` * result ![image](https://hackmd.io/_uploads/SyHoE09HR.png) </br></br></br> 5. 乘積 ![image](https://hackmd.io/_uploads/SyLEB09S0.png) * 參考答案 ```python= """This module compute sum""" import sys def compute(x, y): """compute multiply of two input numbers""" return x*y def main(): """Print out result""" try: a = (int)(input("")) b = (int)(input("")) except TypeError: sys.exit("Enter 2 integers") print(compute(a, b)) main() ``` * result ![image](https://hackmd.io/_uploads/SkCMvAcrA.png) </br></br> 6. 撲克牌總和 ![image](https://hackmd.io/_uploads/BkUGY09SC.png) </br> * 參考答案 ```python= """This module prints the sum of 5 cards in the poker cards""" def main(): """print out 5 cards user typed, and the sum of cards""" card=('A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K') total = 0 for _ in range(5): rank=input("") if rank in card and rank.isdigit() is True: total = total + int(rank) elif rank.isalpha() is True: rank = rank.upper() if rank=='A': total = total + 1 elif rank=='J': total = total + 11 elif rank=='Q': total = total + 12 elif rank=='K': total = total + 13 else: print("Usage: Enter rank in deck of the card: A, J, Q, K, 2~10") exit() else: print("Usage: Enter rank in deck of the card: A, J, Q, K, 2~10") exit() print(total) main() ``` * result ![image](https://hackmd.io/_uploads/Hkri-rWUR.png) 上述程式雖然執行出正確結果,但寫法十分不簡潔, 改用另一種資料結構dict的方式後改進後如下: ```python= """This module prints the sum of 5 cards in the poker cards""" import sys def main(): """print out 5 cards user typed, and the sum of cards""" card={'A':1, '2':2, '3':3, '4':4, '5':5, '6':6, '7':7, '8':8, '9':9, '10':10, 'J':11, 'Q':12, 'K':13} total = 0 for _ in range(5): rank=input("").upper() if rank in card: total = total + card[rank] else: sys.exit("Usage: Enter rank in deck of the card: A, J, Q, K, 2~10") print(total) main() ``` </br></br></br> 7. 數組合併排序 ![image](https://hackmd.io/_uploads/ByLXvbnBA.png) </br> * 參考答案 ```python= """This module print list before and after sorting""" import fontstyle def create_num(): """create tuple, till enter -9999""" list_number=[] value = input('') while value !='-9999': list_number.append(int(value)) value = input('') return list_number def main(): """print out sorted and unsorted combined tuple/list""" text1 = fontstyle.apply('Create tuple1:', 'bold') print(text1) list1 = create_num() text2 = fontstyle.apply('Create tuple2:', 'bold') print(text2) list2 = create_num() combined_tuple = str(tuple(list1 + list2)) text_before = "Combined tuple before sorting: " combined_before_sorting = fontstyle.apply(text_before + combined_tuple, 'bold') print(combined_before_sorting) combined_list = list1 + list2 combined_list.sort() text_after = "Combined list after sorting: " combined_after_sorting = fontstyle.apply(text_after + str(combined_list), 'bold') print(combined_after_sorting) main() ``` * result ![image](https://hackmd.io/_uploads/ryekfpprA.png) 在正式考試當中,不能加入新的套件,所以字體變粗體的方式可以改用ANSI的方式: ```python= print("\033[1m" + "Create tuple1:" + "\033[1m") ``` 在下一題中也會應用到 </br></br></br> 8. 字元對應 ![image](https://hackmd.io/_uploads/BkR4PbhSA.png) </br> * 參考答案 ```python= """This module returns ascll value of input""" string = input(" ") lstring=list(string) TOTAL = 0 for i, lstring in enumerate(lstring): TEXT_1 = "\033[31mASCII\033[0m code \033[34mfor\033[0m " TEXT_2 = "\033[32m'\033[0m"+f"\033[32m{string[i]}\033[0m"+"\033[32m'\033[0m"+ " is " TEXT_3 = f"\033[31m{str(ord(lstring))}\033[0m" print(TEXT_1+TEXT_2+TEXT_3) TOTAL = ord(lstring) + TOTAL print(f"\033[31m{TOTAL}\033[0m") ``` * result ![image](https://hackmd.io/_uploads/Hy50IdCHC.png) </br></br></br> --- ## 綜合一下遇到的Pylint建議 從pylint列出來的建議當中,發現有許多是源於不良的程式撰寫習慣,像是在檔案一開頭添加檔案功能註解、函式下一行添加函示功能說明,或是刪除多餘空格,沒有使用或錯誤使用snake_case變數命名方式等。藉此機會改寫,讓程式碼遵守通用規範並讓其他人便於閱讀。 1. Trailing whiltspace 2. Final newline missing 3. Missing module docstring 4. Missin function or method docstring 5. Variable name "Sum_even" doesn't conform to snake_case naming style 6. No exception type(s) specified (bare-except) 這個error是在使用try...except遇到的,當時以為只要印出錯誤信息即可: ```python= try: ... except : sys.exit("Enter 2 positive integers, and the first input has to be smaller than the second one.") ``` 但卻沒列出exception的types,exception 的 types可以在官方文件上找到[pylint doc](https://pylint.readthedocs.io/en/latest/user_guide/messages/warning/bare-except.html),並查詢pylint的error code: ![image](https://hackmd.io/_uploads/rysc6l2rR.png) 或是如果有裝pylint 在vscode上的extension的話,滑鼠懸空在有問題的程式碼上方,就可以點擊連結查看建議。 ![image](https://hackmd.io/_uploads/SyCP1Z2HA.png) [點進去錯誤代碼w0702的頁面建議](https://pylint.readthedocs.io/en/latest/user_guide/messages/warning/bare-except.html) --- ## Reference material * [基本-熟悉built-in function](https://docs.python.org/3/library/functions.html#ord) * [pylint messages doc](https://pylint.readthedocs.io/en/latest/user_guide/messages/messages_overview.html) * [python exceptions lib](https://docs.python.org/3/library/exceptions.html)