iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 1
5
Software Development

活用python- 路遙知碼力,日久練成精系列 第 1

Day1- 前言: python簡潔?跟著小馬一起「路遙知碼力,日久練成精」吧

路遙知碼力,日久練成精- 只要在程式之路鑽研的夠深,便能夠充分發揮程式碼的力量; 練習的日子夠久,便能夠練成寫出精簡代碼的能力。

大家好,我是心原一馬,內心原來一心喜歡打程式碼。
首先小馬先定位本系列文想鎖定的讀者群,
因為我相信一篇好的文章不太可能滿足所有客群。
若是寫的太簡單,老鳥容易覺得無聊; 但若教的太深入,新手來看又會覺得艱澀難懂。

那麼小馬這次的鐵人賽文究竟寫呈現給什麼客群呢?
首先本系列文是進階文,希望進階的探討如何發揮python語言的簡潔特性,
一些非常基礎的東西不會在這邊講。
如果你還沒學過程式,只是剛好路過這邊想找個適合學習的教程,
那麼「路遙知碼力,日久練成精」並不適合做為你的入門教材,
小馬則建議你可以先去看我的【python 超入門】系列的文章,
【python 超入門】系列是專門為完全零基礎的新手而寫,
有生動的故事講解基礎的重要程式概念。

另外,程式希望幫人們解決以前手算無法解決的複雜問題,
不免用到一些基礎數學概念。
但是不要緊,小馬要求大家只要還記得中學數學的基礎概念即可,
如會加減乘除、四則運算,知道什麼是因數、倍數、質數。
若你是被小馬前陣子寫過的【python 超入門】系列教學文吸引過來,
也喜歡小馬的教學風格,
嗯…你也可以試著學習本系列文章,
小馬將有很多實例操作幫助大家理解。

建議閱讀門檻?

避免未學走就想學飛,本系列文的建議閱讀對象的門檻為:

  1. 至少會使用一門程式語言(如常見語言: C、C++、java、python、javascript、…皆可),了解基礎程式概念,如: 變數、陣列、函數、迴圈等概念。當然若略懂一點python基礎語法更好(如縮排的概念)。
  2. 有些中學數學的知識基礎,如知道什麼是因數、倍數、質數

非必要的門檻?

  1. 你不必是資工相關科系出身
  2. 你可以不必先學過python,當然如果會python基礎的話理解起來更快,但程式基礎概念是相通的。
  3. 當今「資料結構」和「演算法」很熱門,是解決問題的好工具。但你不必先學過這兩門知識。

給你個練習題自我檢驗是否適合學習本系列文

怎麼知道自己算不算會一門程式了呢?
以下給你一道練習題自我檢驗。
中學時,我們應該都學過質因數分解,
例如 20 = 2 * 2 * 5, 30 = 2 * 3 *5, 7=7;
現在給你兩個小時的時間,
找個安靜的地方慢慢打程式,
你可以使用任意你覺得最熟悉的程式語言,
可以查詢語法但不可以直接上網或翻書找答案,
完成底下質因數分解的程式。

首先讓使用者輸入一個正整數,
透過你的程式由小到大印出所有質因數分解的結果(以空格隔開數字),
例如:
若輸入 20 ,要印出「2 2 5 」;
若輸入 30 ,要印出「2 3 5 」;
若輸入 7,因為7本身是質數,直接印出「7 」。
不必想出最有效率的解法,
你只要做的出來就可以。

教學理念及目標?

本系列文不只是講解高級語法的教科書叫大家背誦,
亦會帶出解決問題的思維,如何換種思考方式,
使得複雜問題簡單化,
也希望讓讀者有「哦,原來這個問題還能這樣解。」的豁然開朗吧。
若您是其它語言的讀者,說不定也會因為見識到python語法的精簡,
而萌生「那我也來試著專精python看看好了」的念頭呢。

「路遙知碼力,日久練成精」這系列的文章向大家介紹如何寫出一手漂亮的python代碼,
使得程式碼行數少又不失可讀性。
前幾天可能會簡單比較C/C++和python的code,
讓大家感受到python之美。
我們如果去查python程式語言,
大概會查到python語言最大的特性是簡潔,
但是很多人學了python語言之後,
似乎感受不到python語言的簡潔特性。
不就是c++的cout函數變成python的print,
c++的s.length()變成python的len(s)的差別嗎?

小馬的python老師說的好,
很多人第一個語言不是學python,
把寫其它語言的習慣帶進python中了。

例如我們如果想要宣告一個初始值為1~100的陣列(array),
如果你學過C語言,你可能會這樣寫,
先宣告一個大小為100的陣列,
初始值設為0,再用for 迴圈去改它的值,如下:

int main()
{
    int arr[100]={0};
    int idx=0;
    for(idx=0; idx<100;idx++){
        arr[idx]=idx+1;
    }
}

如果你學過C++,你可能會先宣告一個空的vector,
再用for迴圈把1~100的數字依序加進去,如下:

int main()
{
    vector<int> v;
    for(int i=1; i<=100;i++){
        v.push_back(i);
    }
}

於是當你學了python之後,
知道python的list是類似C語言的array,
類似C++的vector時,
你很容易這樣去寫code:

L=[]
for i in range(1,101):
    L.append(i) 

看似好像就只是不必寫C語言的main()函數而已嘛,
好像也沒精簡到哪裡去。

但其實我們有以下優雅的寫法 (後面篇章會再詳談這是什麼東西):

L=[i for i in range(1,101)]

一行解決,看起來是不是漂亮多了?
在python語言中,
因為有很有好用的內建函數及一些精簡的語法,
使得在其它語言中需要寫很多行的程式,
到了python往往都是一行解決的事情。

好啦,你或許會說,
把程式寫的精簡意思不是都一樣嗎,
把程式寫的很精簡有什麼好處嗎?
列舉幾點:
一、 方便日後閱讀程式碼或除錯,愈長的程式愈容易暗藏bug
二、 美感
三、 美感
四、 還是美感

美感不解釋,
可能有點像國文成語之美?
就像一句「鳥語花香」可能比一段「哇,這邊風景真好,彷彿可以聽到鳥兒唱歌。」來的有意境。

好啦,回歸正題。
試想,如果我們想要「把x的值連加8次」,
用for迴圈來寫當然也是可以做的,如下:

x= 100
result = 0
for i in range(8):
    result = result + x 

可是其實「把x的值連加8次」可以簡單用「x乘以8」來表達,邏輯就可以精簡成這樣:

result = 8*x

這樣程式是不是簡單多了?

服用精簡之鑰須知

需注意,本系列文談的程式碼精簡同時會兼顧程式的可讀性,
未必字打的愈少程式就愈精簡,
例如把變數名稱命名為a,b,c,d,… ,
這樣無法從變數名字看出涵義,
並不在需要精簡的範圍內。

例如下面這個函數:

def foo(n):
    a,b=1,1
    if n==1 or n==2:
        b=1
    else:
        for i in range(2,n):
            c=b
            b=a+b
            a=c
    return b

變數名稱都用a,b,c隨便亂取,估計只有作者肚子裡的迴蟲才看的懂吧?
但是一旦我們幫變數換上適當的名稱:

def fibonacci(n):
    front=1
    result=1
    if n==1 or n==2:
        result=1
    else:
        for i in range(2,n):
            temp = result
            result += front
            front= temp
    return result

相信能看懂這個函數的族群從10%上升到50%沒什麼問題。
(此函數計算的是著名的費式數列1,1,2,3,5,8,13,…的第n項)

邀請大家一起學習

當然,要把python程式寫到精簡又好懂也並不是能夠一步登天就可以學成的,
故本系列文命名為「路遙知碼力,日久練成精」,
期許各位讀者能夠跟著小馬的腳步,
日子久了練成寫出精簡代碼的功力。

想用短短程式碼實現豐富的功能?
想學將問題化繁為簡的思維模式嗎?
想試試看python與其它語言與眾不同的地方?

若你覺得五行程式用一行表達是有美感的,或覺得很炫的,
來來,不必猶豫了,
追蹤小馬吧,
訂閱小馬吧,
一同踏向探索python之路吧。

對於教學文有疑問的邦友,也很歡迎在留言區提問交流討論,
小馬會儘量常駐線上協助解惑的。


下一篇
Day2 – 鐵人賽既出,駟馬難追,來學習python特性吧
系列文
活用python- 路遙知碼力,日久練成精30

尚未有邦友留言

立即登入留言