iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 12
0
Software Development

從零開始學Python系列 第 12

[Day 12] 從零開始學Python - 物件與類別:我們不一樣,每個人都有不同的際遇(上)

  • 分享至 

  • xImage
  •  

註:本文同步刊載在Medium,若習慣Medium的話亦可去那邊看呦!

先來解答昨天的問題吧!

  1. 給定兩個字串s跟t,已經知道t的組成,
    是將s的字母打亂以後進行重組,再隨機加上一個字母。
    請用前面所學,找出被加上的那個字母。

以這題來說,我們可以採用內建的方式來處理,
或者使用上一篇提到的Counter()。
首先,讓我們再額外教一對有用的方法:ord()跟chr()。

一般狀況下,程式語言中有時候會提到char(字元)這個單位,
字元的單位就是單一一個英文字母或符號,
是用8個二進位來組成,有定義的有128個不同的字元。
這種字元的表達方是我們稱之為ASCII Code(阿斯奇扣德)。
更詳細的介紹可以看 https://zh.wikipedia.org/wiki/ASCII

我們只需要知道,ASCI Code上面65~90是A~Z,而97~122是a~z。
而要如何在數字和對應的字元做轉換呢?
在Python中會使用ord(),也就是order,將一個字元轉成對應的ASCII Code;
而使用chr(),則可以將一個數字轉為對應的字元。

利用這點,我們可以取一個長度為26的list,
把a放到list的index 0,b放到list的index 1...,z放到list的index 25。
什麼?你不記得哪個數字對應的ASCII Code?
我們只需要拿ord('a')為基準去相減就好囉!
因此,我們要做的事情就是將s的東西全部當做減1次,
t的東西全部當做加1次,最後因為t只比s多一個字元而已,
留下來計數是1的那個就會是答案囉!

如果先減後加的話,只要我們找到即將由0轉1的時候的那個字元,
就是我們要的答案囉!

# 變數後面加冒號,再加資料型態,可以提示輸入的資料型態。
# 但實質上Python並不會強制檢查是否正確。
# "->" 後面接的則是回傳的資料型態
def findTheDifference(s: str, t: str) -> str:
    cnt = [0] * 26
    for c in s:
        cnt[ord(c) - ord('a')] -= 1

    for c in t:
        if cnt[ord(c) - ord('a')] == 0: return c
        cnt[ord(c) - ord('a')] += 1

第二種方法,我們可以直接使用Counter()。

def findTheDifference(self, s: str, t: str) -> str:
    from collections import Counter
    cnt_s = Counter(s)
    cnt_t = Counter(t)
    # most_common(1)[0]取到了唯一的一組,再一個[0]取到key的部分
    return (cnt_t - cnt_s).most_common(1)[0][0]

接下來今天我們要講很多程式語言都有的重要的東西:物件。
我們先前講過函式,就是透過自己組合一些程式碼,做成自己想要的一組功能。
事實上,以Python的角度來說,任何東西都是一種物件,
物件不只有自己的函式(方法),還有一些屬於它的變數(屬性)

舉例來說:
如果有一個人叫阿明,另一個人叫小美,
他們都是同一個高中同一班的學生,
所以要考試時,阿明要考數學跟英文,小美也要考數學跟英文。
如果我們要記錄阿明跟小美的成績的話,按照先前所學的,
讀者可能會做類似如下的變數設定:

ming_score_math = 55
ming_score_english = 70
mei_score_math = 90
mei_score_english = 88

這麼做有以下幾個缺點:

  1. 字很長XD
  2. 每個變數都要重新再命名一次,如果今天要40個同學都這樣的話,
    寫變數命名就累死了!
    所以為了加以簡化,我們可以用物件的概念來處理這個問題。
    在創造一個物件(object)之前,我們要先定義類別(class)
    什麼是類別呢?
    我們要考慮處理的目標,其共通性是什麼?
    比方說阿明是學生,小美也是學生,
    阿明會有考試的成績,小美也是,同時,阿明和小美都會上課。
    那麼我們就會可以定義一個類別稱為Student(一般類別習慣會使用第一個字大寫)。

最基礎的類別定義如下:

class Student():
    pass # pass表示暫時不做任何事情,但將來必須要將其填補好。

如果要從一個定義產生物件,其用法如下:

ming = Student() # 阿明是個學生
mei = Student() # 小美是個學生,但和阿明不一樣

上面的ming和mei都是分別都是一個物件,其類別為Student。
以最初始的定義來說,它什麼事情都不會做,接下來我們來加入一些屬性:

class Student():
    def __init__(self, name):
        self.name = name

在一個物件被初始化的時候,最先會呼叫其中的__init__()函式。
它最前面必須要是self開頭,self的概念是指這個物件本體
我們可以透過self.xxx的方式來取得或修改物件的其他屬性或方法。
注意到除了self以外,我們還增加一個name,
代表當我們呼叫Student()時,其第一個位置傳入的將會是name。
self.name = name則代表我們要在開始時,
將從外面傳入進來的name的值,
存放進這個物件本體的name的值。

所以我們現在在來修改一下剛剛產生物件的方式:

ming = Student('阿明') # 阿明是個學生
mei = Student('小美') # 小美是個學生,但和阿明不一樣
# 要使用'.'來取得各自的名字
print(ming.name)
print(mei.name)

除了屬性以外,我們還可以為類別新增一些方法,
其方式基本和前面函式定義的方法一致,只是要加上self。

class Student():
    def __init__(self, name):
        self.name = name
    
    # 可以利用self取得自己這個類別裡面的變數
    def readMyName(self):
        print('聽清楚了,我的名字是' + self.name + '!!!')
        
ming = Student('阿明')
mei = Student('小美')
print(ming.name)
print(mei.name)
ming.readMyName()
mei.readMyName()

由於物件概念比較需要仔細釐清,我們就分成兩篇來細講,
請務必仔細完成今天的練習呦!

那我們來練習一下題目吧!

  1. 在上述的例子當中,請為類別新增一個字典,名稱為score,
    將該字典用來儲存{'科目':'分數'}的各科成績,並修改__init__()的函式,
    在產生阿明及小美時,同時輸入各科成績,
    如未輸入則預設為0分(也就是缺考)。
    阿明的成績分別為:數學55/英文70/物理55
    小美的成績分別為:數學90/英文88/物理100

  2. 承上題,請新增一名Student,其name為'HowHow',
    數學成績為80,英文成績為60,物理成績為40。

  3. 請為Student新增一個方法,讓兩個Student可以互相比較,
    名稱為compare()。
    例如A.compare(B),假設:
    A的總分高於B -> A的名字 + '贏了!'
    A的總分等於B -> '什麼?竟然平手?!'
    A的總分小於B -> '可...可惡,難道,這就是' + B的名字 + '真正的實力嗎?'

並分別讓阿明和HowHow比較、阿明和小美比較、小美和HowHow比較,輸出結果。

辛苦啦!我們明天見!


上一篇
[Day 11] 從零開始學Python - 標準程式庫:你的機車不機車,載我瀏覽世界景色
下一篇
[Day 13] 從零開始學Python - 物件與類別:我們不一樣,每個人都有不同的際遇(中)
系列文
從零開始學Python30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言