[Python] PEP 簡介


簡介

PEP 全名 Python Enhancement Proposals , 是 Python 社群裡持續在不斷更新和維護的標準技術文件,其目的是要讓所有程式設計師在開發程式時有統一的規範和標準可以遵循,以避免因資訊的不完整而產生的混亂。

每個 PEP 都有唯一的編號用來代表它內容,一但給定了編號後就不會在隨意更動了。
PEP 依內容可以分成三類:
  • Standards Track - 說明 Python 的新功能。
  • Informational - 說明 Python 因設計所導致問題、建議的風格指南。
  • Process - 紀錄 Python 發展中的重要抉擇。

*雖然只是「建議」要遵循 Informational PEP 而已,不過就像 Python之父 Guido van Rossum 所認為的:【程式碼被閱讀的次數遠大於程式碼撰寫的次數】,因此程式設計師若在開發程式時都能遵循共同的標準,在閱讀程式碼時想必可以減少很多不必要的誤解,且可以更清楚快速的了解到整個程式碼的邏輯思維。


  • PEP 0 - 全部 PEP 的列表
  • PEP 1 - 說明 PEP 的目的和指南



*底下介紹一些建議可以看的 PEP 文件[會不定時更新]:

風格指南


實用



參考資料

[UVa] 10994 - Simple Addition



題目

時間限制: 3秒
輸入: int, int

輸入兩個整數 p, q 然後計算出 S(p, q) 的值


$$
\begin{align*}
F(n) = \left\{ \begin{array}{cc}
  n\%10 ,& \hspace{5mm} if\quad(n\%10)>0 \\
  0,& \hspace{5mm} if \quad n=0 \\
  F(n/10),& \hspace{5mm} Otherwise \\
  \end{array} \right.
\end{align*}
$$
$$
S(p,q) = \sum_{i=p}^{q} F(i)$$

解題思維


最直觀的想法為用迴圈從 F(s) 不斷的累加直到 F(q) ,不過這樣會超過題目要求的時間。

稍微想下後發現,F(n)的值都介於 0~9 之間
因此可以把F(n)的數列看成這樣:
(0、1、2  ... 8、9)、F(10)、(1 、2 ... 8、9)、F(20)  ... (1、2 ... F(n))

然後根據函示 F(n) 的定義如果 n 可以被 10 整除,則 F(n) = F(n/10)
再把上面的式子化簡成下面這樣:
(0、1、2  ... 8、9)、F(1)、(1 、2 ... 8、9)、F(2)  ... (1、2 ... F(n))

整理後這樣題目就好解多了!


程式碼解說


這題可以分成三個函式
*回傳的值有可能超過 int 能表示的上限因此用 long long int

  1. f => 計算 F(n) 的值。
  2. sum => 計算等差級數的總和。
  3. f_sum => 計算 S(p, q) 的值,也就是算 F(p) 累加到 F(q) 的總和。
// C++
int f(int n);
long long int sum(int from, int to);
long long int f_sum(int p, int q);


先根據定義寫出一個 F(n) 的函式
// C++
int f(int n)
{
    if(n%10) return n%10;
    else if(!n) return 0;
    else return n/10;
}

再來寫一個計算等差級數總和的函式
// C++
long long int sum(int from, int to)
{
    int count = to - from + 1;

    return (from+to) * count / 2;
}


接下來寫一個函式計算 S(p, q)
先把結尾是 (1~9) 的數字做一個間隔來切割,如下:
0、(1、2 ... 9)、10、(11、12 ... 19)、20、(21、22 ... 29) ...

如果 p 跟 q 在同一個區間的話則直接累加
// C++
if((p/10) == (q/10))
{
    ans += sum(f(p), f(q));
}



若 p 、q 在不同區間的話,先把不能湊成一個完整區間的數字累加起來。
ex:
(8、9)、10、(11、12 ... 18 、 19)、20、(21、22、23)
=> 10、(11、12 ... 18 、 19)、20 為一個完整的區間
=> (8、9) 、 (21、22、23) 不是完整的區間

讓 F(p) 一直累加到 9,並更新 p 的位置到還沒運算的地方
// C++
if(p%10)
{
    ans += sum(f(p), 9);
    p += (10-p%10);
}
作法跟上面類似,從 1 累加到 F(q),並更新 q 的位置到還沒運算的地方
// C++
if(q%10){
    ans += sum(1, f(q));
    q -= q%10;
}


在來用 p、q 來計算之間有幾個間隔,在乘上每個間隔中的總和
// C++
ans += ((q/10 - p/10) * sum(1, 9));

最後再加上 10 的倍數序列 的總和就可以得出答案了
*若 n 是10的倍數 根據 F(n) 定義也就等同於 F(n/10)
// C++
ans += f_sum(p/10, q/10);

完整程式碼(github)

  

[Linux] 套件安裝教學 (APT)


簡介

APT (Advanced Package Tool) 是 Debian, Ubuntu, Kali ...等 Ubuntu based Linux 上用來管理套件的指令,其它 Linux發行版 有各自適用的安裝指令。

APT主要有兩個工具:
  1. apt-get - 安裝、更新、清除套件
  2. apt-cache - 查詢套件

*通常 apt-get 的指令需要 root權限 才可以執行,因此在使用上會搭配 sudo 指令:
sudo apt-get XXX



apt-get 指令介紹

APT是藉由搜尋資料庫來得知套件資訊的
  • update - 更新資料庫的資訊
  • sudo apt-get update
  • upgrade - 更新已安裝的套件
  • sudo apt-get upgrade
  • install - 安裝新的套件
  • sudo apt-get install <*套件名稱>
  • remove - 移除已安裝的套件
  • sudo apt-get remove <*套件名稱>
  • clean - 清理沒必要的檔案
  • sudo apt-get clean
  • purge - 完整移除套件
  • sudo apt-get purge <*套件名稱>

apt-cache指令介紹

  • search - 搜尋套件
  • apt-cache search <*要搜尋的套件名>
  • showpkg - 查看套件資訊
  • apt-cache showpkg <*套件名稱>

*剛安裝好 Linux 後記得要先 update 和 upgrade 套件
sudo apt-get update && sudo apt-get upgrade -y



參考資料


Windows Subsystem for Linux (WSL) - 簡易安裝和配置



簡介


微軟在2016年8月的 Windows 10 更新(Version 1607) 裡介紹了 Bash for Windows 這個新功能,在Version 1709更新後發布正式版本並命名為 Windows Subsystem for Linux 。此更新使得 Windows 的用戶可以直接使用 Linux 的指令和 bash shell,不須再額外使用虛擬機或模擬器,使得效能還是相容性都獲得了大大的提升。



安裝需求


  • 64位元的Windows 10 (目前並不支援32位元系統)
  • 起碼要 Windows 10 version 1607 以上的版本
    • 不過建議最好要升級到 version 1709 以上



一、 啟用WSL

*以下步驟只適用於 version 1709 後的版本 (我的電腦是英文版 對照看下吧)

方法一

  1. 打開Windows的 [設定]
  2. 點選 [Apps]
  3. 找到並開啟 [程式和功能]
  4. 打開 [開啟或關閉 Windows 功能]
  5. 找到並勾選 [適用於 Linux 的 Windows 子系統]

方法二

  1. 按下 Win + X
  2. 打開Powershell (管理員權限)
  3. 輸入以下指令
  4. Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux



二、 選擇Linux發行版(Distro)並安裝


  1. 打開Windows Store
  2. 搜尋你想裝的Linux發行版
  3. 安裝
目前Windows Store上已經有的Linux發行版:



三、 啟用


  1. 以上步驟都完成後,讓電腦重新開機
  2. 在[開始]選單找到安裝的Linux後打開
  3. 等待初始化
  4. 輸入使用者名稱&密碼
  5. 完成!



參考資料

[演算法] 指數運算 (Exponentiation)


         現在很多程式語言內建就有包括指數運算的函式或運算子了,但如果今天你想要做的是矩陣的指數運算或著說程式內建函式庫沒有指數運算那該怎麼辦呢?

假設我要算 bn,最直觀的想法為讓b自乘以n次
#python程式碼
def power(b, n):
    ans = 1
    for i in range(n):
        ans = ans * b
    return ans
不過問題是這樣程式執行起來很沒有效率,時間複雜度為O(n)。

-----------------------------------------------------------

我要來介紹另一種演算法叫 快速冪 :

假設我要算 b8, 與其讓b自乘以8次,我可以改用以下步驟來求得
  1. b2 = b · b 
  2. b4 = b2 · b2
  3. b8 = b4 · b4
這樣從原本的8次運算變成只要3(log8)次就可以求出結果了。

 b的定義廣義化:
  • 如果 n 等於 0:  b0  =  1
  • 如果 n 是偶數: bn  =  (bn/2)2
  • 如果 n 是奇數: bn  =  b · bn-1
#python程式碼
def fast_power(b, n):
    if(n==0):
        return 1
    else:
        if(n%2==0):
            pow_half = fast_power(b, n/2)
            return pow_half * pow_half
        else:
            return b * fast_power(b, n-1)
時間複雜度為(logn)




參考資料


  • Structure and Interpretation of Computer Programs (SICP)