Python 全攻略第九節 Python Practice 練習

第九節 Python Practice

引言

這只是 Wilson 老師第九節出的 Python 練習題,算是前面章節的小複習,這篇筆記是我針對這些題目的實作記錄,其實解題的做法不只一種,我也盡可能地讓自己向 Python 之禪看齊,而我當下是在未觀看老師題目解析的錄影狀態下做的,這幫助我能在看老師解題前,先自己試著溫習及回顧之前老師講過的知識點。不過不自覺的,好像有用到一些之前從 Fred 老師那裏學到的類似 Refraction 的概念,而且,我自從學了 Type Hinting 型別提示的概念,就開始勉強自己養成習慣,在所有函式的輸入參數和返回參數都加上型別提示,讓自己習慣這樣的作法,就像當初我學 Markdown 的時候,也是透過這個 Discord 學習平台,勉強自己必須用 Discord 貼 Markdown 格式的筆記文,這有助於讓我從自己的身體反射來學習,不然現在年紀漸大,腦袋已經漸漸不靈光記不住了,希望這些的作法,不會妨礙大家看 Code,如有不清楚的,又或是我有筆誤或觀念不正確的,也歡迎大家指正,一起來討論。

Simple Exercise I

There are totally 7 problems in simple exercise I. Most of the exercises in this module are quite simple. I believe that you can do it pretty well. Good luck!

  1. Write a function called “printMany” that prints out integers 1, 2, 3, …, 100.
printMany();
# 1
# 2
# ...
# 100

Ans1-1:

import typing

def printMany(*args: typing.Any) -> None:
    for arg in args:
        print(arg, sep='\t', end='\t')

printMany(*[x for x in range(101)])
  1. Write a function called “printEvery3” that prints out integers 1, 4, 7, 10, …, 88.
printEvery3();
# 1
# 4
# ... 
# 88

Ans1-2:

def printEvery3(*args: typing.Any) -> None:
    for arg in args:
        if arg % 3 == 1:
            print(arg, sep='\t', end='\t')

printEvery3(*[x for x in range(1, 89)])
  1. Write a function called “position” that returns a tuple of the first uppercase letter and its index location. If not found, returns -1.
position("abcd")  # returns -1
position("AbcD")  # returns ('A', 0)
position("abCD")  # returns ('C', 2)

Ans1-3:

def position(string: str) -> typing.Union[typing.Tuple[str, int], int]:
    for i, char in enumerate(string):
        if char.isupper():
            return (char, i)
    return -1

print(position("abcd"))
print(position("AbcD"))
print(position("abCD"))
  1. Write a function called “findSmallCount” that takes one list of integers and one integer as input, and returns an integer indicating how many elements in the list is smaller than the input integer.
findSmallCount([1, 2, 3], 2); # returns 1
findSmallCount([1, 2, 3, 4, 5], 0); # returns 0

Ans1-4:

def findSmallCount(lst: typing.List[int], n: int) -> int:
    return len([x for x in lst if x < n])

print(findSmallCount([1, 2, 3], 2))
print(findSmallCount([1, 2, 3, 4, 5], 0)) 
  1. Write a function called “findSmallerTotal” that takes one list of integers and one integer as input, and returns the sum of all elements in the list that are smaller than the input integer.
findSmallerTotal([1, 2, 3], 3) # returns 3
findSmallerTotal([1, 2, 3], 1) # returns 0
findSmallerTotal([3, 2, 5, 8, 7], 999) # returns 25
findSmallerTotal([3, 2, 5, 8, 7], 0) # returns 0

Ans1-5:

def findSmallerTotal(lst: typing.List[int], n: int) -> int:
    return sum([x for x in lst if x < n])

print(findSmallerTotal([1, 2, 3], 3))
print(findSmallerTotal([1, 2, 3], 1))
print(findSmallerTotal([3, 2, 5, 8, 7], 999))
print(findSmallerTotal([3, 2, 5, 8, 7], 0))
  1. Write a function called “findAllSmall” that takes one list of integers and another integer as input, and returns an list of integers that contains all elements that are smaller than the input integer.
findAllSmall([1, 2, 3], 10); # returns [1, 2, 3]
findAllSmall([1, 2, 3], 2); # returns [1]
findAllSmall([1, 3, 5, 4, 2], 4); #  returns [1, 3, 2]

Ans1-6:

def findAllSmall(lst: typing.List[int], n: int) -> typing.List[int]:
    return [x for x in lst if x < n]

print(findAllSmall([1, 2, 3], 10))
print(findAllSmall([1, 2, 3], 2))
print(findAllSmall([1, 3, 5, 4, 2], 4))
  1. Write a function called “summ” that takes one list of numbers, and return the sum of all elements in the input list.
summ([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); # returns 55
summ([]); # return 0
summ([-10, -20, -30]); # return -60

Ans1-7:

def summ(lst: typing.List[int]) -> int:
    return sum(lst)

print(summ([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]))
print(summ([]))
print(summ([-10, -20, -30]))

Simple Exercise II

There are 6 more problems in this section of exercises. Most of them are still easy. I believe that you can do most of them. If you get stuck, try to solve it in another way. Good luck!!!

  1. Write a function called “stars” which prints out layers of stars in the following pattern:
stars(1);
# *
stars(4);
# *
# **
# ***
# ****

Ans2-1:

def stars(n: int) -> None:
    for i in range(1, n + 1):
        print("*" * i)

stars(1)
print("-"*30)
stars(4)
print("-"*30)
stars(7)
  1. Write a function called “stars2” which prints out layers of stars in the following pattern:
stars2(1);
# *
stars2(2);
# *
# **
# *
stars2(3);
# *
# **
# ***
# **
# *
stars2(4);
# *
# **
# ***
# ****
# ***
# **
# *

Ans2-2:

def stars2(n: int) -> None:
    for i in range(1, n + 1): # 1, 2, ..., n
        print("*" * i)
    for i in range(n - 1, 0, -1): # n - 1, n - 2, ..., 1
        print("*" * i)
        
stars2(1)
print("-"*30)
stars2(2)
print("-"*30)
stars2(3)
print("-"*30)
stars2(4)
  1. Write a function called “table” which takes an input n, and prints out n x 1 to n x 9
table(3);
# 3 x 1 = 3
# 3 x 2 = 6
# ...
# 3 x 9 = 27

Ans2-3:

def table(n: int) -> None:
    for i in range(1, 10):
        print(f"{n} x {i} = {n * i}")

table(3)
print("-"*30)
table(7)
  1. Write a function called “table9to9” that prints out the multiplication table:
table9to9();
# 1 x 1 = 1
# 1 x 2 = 2
# 1 x 3 = 3
# ...
# 1 x 9 = 9
# 2 x 1 = 2
# 2 x 2 = 4
# ...
# 9 x 9 = 81

Ans2-4:

def table9to9() -> None:
    '''做個稍微變形的九九乘法表'''
    for i in range(1, 10): 
        for j in range(1, 10): 
            print(f"{j} x {i} = {i * j}", end='\t')
        print()
        
table9to9()
  1. Write a function called “swap” that takes a string as input, and returns a new string with lowercase changed to uppercase, uppercase changed to lowercase.
swap("Aloha"); # returns "aLOHA"
swap("Love you."); # returns "lOVE YOU."

Ans2-5:

def swap(string: str) -> str:
    return string.swapcase() # string.swapcase() 會回傳一個大小寫互換的新字串

print(swap("Aloha"))
print(swap("Love you."))
  1. Write a function called “findMin” which takes an list as input, and returns the minimum element in the input list.
findMin([1, 2, 5, 6, 99, 4, 5]); # returns 1
findMin([]); # returns undefined
findMin([1, 6, 0, 33, 44, 88, -10]); # returns -10

Ans2-6:

def findMin(lst: typing.List[int]) -> int:
    try:
        return min(lst)
    except ValueError:
        return 'undefined'

print(findMin([1, 2, 5, 6, 99, 4, 5]))
print(findMin([]))
print(findMin([1, 6, 0, 33, 44, 88, -10]))

Intermediate Exercise I

These 7 quesions are insteresting!! Try your best to do it before looking at the my answer!

  1. Write a function called “mySort” that takes an list of integers as input, and returns the sorted version of the input list. You are not allowed to use the built-in sorted() function.
mySort([17, 0, -3, 2, 1, 0.5]); # returns [-3, 0, 0.5, 1, 2, 17]

Ans3-1:

def mySort(lst: typing.List[int]) -> typing.List[int]:
    for i in range(len(lst) - 1):
        for j in range(i + 1, len(lst)):
            if lst[i] > lst[j]:
                lst[i], lst[j] = lst[j], lst[i]
    return lst  

print(mySort([17, 0, -3, 2, 1, 0.5]))
  1. Write a function called “isPrime” that takes an integer as input, and returns a boolean value that indicates if the input number is prime.
isPrime(1); # returns false
isPrime(5); # returns true
isPrime(91); # returns false
isPrime(1000000); # returns false

Ans3-2:

def isPrime(n: int) -> bool:
    '''判斷 n 是否為質數'''   
    if n < 2:
        return False
    for i in range(2, n):
        if n % i == 0:
            return False
    return True

print(isPrime(1))
print(isPrime(5))
print(isPrime(91))
print(isPrime(1000000))
  1. Write a function called “palindrome” that checks if the input string is a palindrome. (Search on google if you don’t know what a palindrome is.)
  • Note: palind 是正著寫及反著寫都一樣的文字
palindrome("bearaeb"); # true
palindrome("Whatever revetahW"); # true
palindrome("Aloha, how are you today?"); # false

Ans3-3:

def palindrome(string: str) -> bool:
    return string == string[::-1]

print(palindrome("bearaeb"))
print(palindrome("Whatever revetahW"))
print(palindrome("Aloha, how are you today?"))
  1. Write a function called “pyramid” that takes an integer as input, and prints a pyramid in the following pattern:
pyramid(1);
# *
pyramid(2);
#  *
# ***
pyramid(4);
#    *
#   ***
#  *****
# *******

Ans3-4:

def pyramid(n: int) -> None:
    for i in range(1, n + 1):
        # 印出空白與星號的組合  --> 空白數 = n - i, 星號數 = 2 * i - 1
        print(" " * (n - i) + "*" * (2 * i - 1))
        
pyramid(1)
print("-"*30)
pyramid(2)
print("-"*30)
pyramid(4)
  1. Write a function called “inversePyramid” that draws pyramid upside down.
inversePyramid(4);
# *******
#  *****
#   ***
#    *

Ans3-5:

def inversePyramid(n: int) -> None:
    for i in range(n, 0, -1):
        # 印出空白與星號的組合  --> 空白數 = n - i, 星號數 = 2 * i - 1
        print(" " * (n - i) + "*" * (2 * i - 1))
        
inversePyramid(4)
  1. Given a list of ints, return True if the list contains a 3 next to a 3.
print(has_33([1, 5, 7, 3, 3])) # True
print(has_33([])) # False
print(has_33([4, 3, 2, 1, 0])) # False

Ans3-6:

def has_33(lst: typing.List[int]) -> bool:
    '''檢查 lst 中是否有連續兩個 3 的成員'''
    for i in range(len(lst) - 1):
        if lst[i] == lst[i + 1] == 3:
            return True
    return False

print(has_33([1, 5, 7, 3, 3])) # True
print(has_33([])) # False
print(has_33([4, 3, 2, 1, 0])) # False
  1. Write a function that check if a list contains a subsequence of 007
print(spyGame([1, 2, 4, 0, 3, 0, 7])) # True
print(spyGame([1, 2, 5, 0, 3, 1, 7])) # False

Ans3-7:

def spyGame(lst: typing.List[int]) -> bool:
    '''檢查 lst 是否包含 0, 0, 7 的子序列,且 7 的順序必須在 0 之後,且 0 與 7 之間可以有其他數字元素'''
    # 1. 先找出 lst 中所有的 0 與 7 的索引值
    zero_indices = [i for i, x in enumerate(lst) if x == 0]
    seven_indices = [i for i, x in enumerate(lst) if x == 7]
    # 2. 檢查是否有 0, 0, 7 的子序列
    for i in zero_indices:
        for j in seven_indices:
            # 3. 檢查 7 的順序必須在 0 之後
            if j < i:
                return False
    # 4. 檢查 0 與 7 之間可以有其他數字元素,且 0 的元素個數必須大於等於 2,  7 的元素個數必須大於等於 1
    return True & (len(zero_indices) >= 2) & (len(seven_indices) >= 1)

print(spyGame([1, 2, 4, 0, 3, 0, 7])) # True
print(spyGame([1, 2, 5, 0, 3, 1, 7])) # False
print(spyGame([7, 2, 4, 0, 3, 0, 1])) # False
print(spyGame([0, 7, 4, 0, 3, 7, 1])) # False
print(spyGame([0, 4, 1, 0, 3, 7, 2])) # True

Intermediate Exercises II

There are 3 questions in this section. All 3 of them require some programming skill. In fact, if you never learn algorithm and data structure, then these questions might seem hard for you. Try your best. If you can do it, that means you are really talented in programming. Good luck!!

  1. Write a function called “factorPrime” that takes an integer as input, and returns the prime factorization of the input.
factorPrime(120); # returns "2 x 2 x 2 x 3 x 5"

Ans4-1:

def isPrime(n: int) -> bool:
    '''判斷是否為質數'''
    if n < 2:
        return False
    for i in range(2, n):
        if n % i == 0:
            return False
    return True

def factorPrime(n: int) -> str:
    '''回傳 n 的質因數分解結果'''
    returnStr = str(n) + ' = '
    result = []
    for i in range(2, n + 1): # 最大的質因數不會超過 n
        # 如果 i 是質數,且 n 可以被 i 整除
        while isPrime(i) and n % i == 0: 
            result.append(i)
            # 透過遞迴,將 n 針對目前的質因數除到不能再除為止,
            # 然後再換下一個質因數
            n /= i 
    return returnStr + " x ".join([str(x) for x in result])

print(factorPrime(120)) # 120 = 2 x 2 x 2 x 3 x 5
print(factorPrime(210)) # 210 = 2 x 3 x 5 x 7
  1. Write a function called “intersection” that takes 2 lists, and returns an list of elements that are in the intersection of 2 list.
intersection([1, 3, 4, 6, 10], [5, 11, 4, 3, 100, 144, 0]); # returns [3, 4]

Ans4-2:

def intersection(lst1: typing.List[int], lst2: typing.List[int]) -> typing.List[int]:
    # return list(set(lst1).intersection(set(lst2))) # 老師的解法
    return [x for x in lst1 if x in lst2]

print(intersection([1, 3, 4, 6, 10], [5, 11, 4, 3, 100, 144, 0]))
  1. Write a function called “flatten” that flattens an list.
flatten([1, [[], 2, [0, [1]], [3]], [1, 3, [3], [4, [1]], [2]]]);
# returns [1, 2, 0, 1, 3, 1, 3, 3, 4, 1, 2]

Ans4-3:

def flatten(lst: typing.List[typing.Any]) -> typing.List[typing.Any]:
    '''將 lst 中的所有元素取出,並放入一個新的 list 中,且不管 lst 中的元素是不是 list'''
    result = []
    for x in lst:
        # 如果 x 是 list,則將 x 中的元素取出,並放入 result 中
        if isinstance(x, list):
            # 直接反射這個函式來進一步進行遞迴操作
            result.extend(flatten(x)) # result += flatten(x)
        else: # 如果 x 不是 list,則直接將 x 放入 result 中
            result.append(x)
    return result

print(flatten([1, [[], 2, [0, [1]], [3]], [1, 3, [3], [4, [1]], [2]]])) # [1, 2, 0, 1, 3, 1, 3, 3, 4, 1, 2]

結語

這篇筆記也算是回應 fy 同學的自我挑戰。如大家有看不懂的,或是有任何想法或問題,又或是有發現我有筆誤或觀念錯誤的地方,請大家隨時指正,也歡迎大家提出自己看法,一起討論共同參與學習,這才是真正的共學精神,與大家共勉之。

2個讚

剛看完老師解題 Intermediate Exercises I 最後一題,要找 007 的解題視頻,才發現其實老師題目沒寫完全,還必須遵守找到的子集合,必須 7 元素在所有 0 元素之後,這樣才符合隱藏的 007,換言之,如果子集合是 700 或是 070 的都不對,因此我重新解題,把原先實作重改,重新做了修正(在Ans3-7),提供大家參考。
我多找了幾個似是而非的List集合驗證,應該是對的,如果有人有發現我錯的地方,歡迎指正及討論。先謝謝囉~