---
# System prepended metadata

title: TQC Python3術科參考解答-1/2
tags: [Python, pylint, TQC]

---

[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)



