為自己Coding
為自己Coding

YO~~ 剛跨入AI人工智慧領域的小小工程師, 熱愛自學, 熱愛分享, 下班後的我想為自己Coding, 積極撰寫教學文, 想將自學的程式知識分享給大家, 不斷追求進步的自己, 希望有一天能回饋社會,幫助需要幫助的人, 如果您有什麼很酷的想法,也覺得我還行,歡迎您找我合作~~ IG: https://www.instagram.com/coding_4_me/

IPython各種用法 - 讀書筆記 - Python Data Science Handbook - Python數據科學 - IPython的快捷鍵與神奇的魔術指令 - 原來In[] 和 Out[] 可以這樣用 - IPython中執行Shell指令 - Errors and Debugging 重要的除錯功能 - 筆記#2



Github連結

嗨嗨,如果覺得圖片不清楚,都可以直接參考我的Github喔


攝影師:ArtHouse Studio,連結:Pexels



1.2章IPython快捷鍵


1. 如何打開IPython shell?

打開Anaconda Prompt,並輸入ipython,按下Enter鍵



2. IPython shell中的快捷鍵

領航快捷鍵(Navigation shortcuts)



文字輸入快捷鍵(Text Entry Shortcuts)



指定歷史的快捷鍵(Command History Shortcuts)



雜項快捷鍵(Miscellaneous Shortcuts)



1.3章 IPython的魔術指令(IPython Magic Commands)


1. %paste & %cpaste - 張貼程式碼

大家應該都有遇到過這個問題,就是複製了網路上的程式碼,直接貼上到我們的編譯器上時,竟然報錯了,這可能是因為編譯器被額外的提示符搞亂了,就可以使用%paste和%cpaste來解決

情況舉例:

原本想複製網路上的程式碼

>>> def add(a,b):
...  return a+b 

然後直接複製貼上到IPython會報錯

這時候就可以使用%paste,它專門處理編譯器被一些額外的提示符搞亂了的情況


自己嘗試的結果:但我自己嘗試了書本上的範例發現要很特定的情況下用%paste,才不會報錯,要不然就是原本就不會有錯,感覺基本上它還是張貼的作用


使用說明

  • %paste: 一打上去,就會將我們當前複製的程式碼貼上
  • %cpaste: 在IPython中輸入後,會出現一個交互式的多行提示符,使我們可以貼上多個程式碼塊,然後批量執行它們

示範一:

In [1]: %paste
>>> def add(a,b):
...  return a+b
​
## -- End pasted text --
​
In [2]: add(2,6)
Out[2]: 8
​
In [3]: %cpaste
Pasting code; enter '--' alone on the line to stop or use Ctrl-D.
:>>> def add(a,b):
:... return a+b
:>>> def add(a,b):
:... return 2a+2b
:>>> def add(a,b):
:... return 3a+3b
:--

示範二: 在%cpaste中使用%paste

In [1]: %cpaste
Pasting code; enter '--' alone on the line to stop or use Ctrl-D.
:%paste
:--
>>> def add(a,b):
...  return a+b
​
## -- End pasted text --


2. %run - 在IPython中,執行外部的Python檔

  • 格式:%run (執行的Python檔名稱)
  • 舉例:我們有一個Python檔
## python_script.py
​
def multiply(a,b):
  '''a multiply of b'''
  
  return a*b
​
​
if __name__ == '__main__':
  
  for i in range(10):
    print(str(i) + ' multiply of ' + str(i+1) + ' : ' , multiply(i,i+1))
 
  • 在IPython中執行這個Python檔,如果沒有給目錄位置,就要到Python檔的目錄位置底下執行喔
%run python_script_demo.py 

執行結果

In [1]: %run python_script.py
0 multiply of 1 : 0
1 multiply of 2 : 2
2 multiply of 3 : 6
3 multiply of 4 : 12
4 multiply of 5 : 20
5 multiply of 6 : 30
6 multiply of 7 : 42
7 multiply of 8 : 56
8 multiply of 9 : 72
9 multiply of 10 : 90

執行完後,還能在IPython使用這些在Python檔中定義好的函數

In [2]: multiply(2,8)
Out[2]: 16


3. %timeit - 程式碼執行時間計時,瞭解哪個用法更快

.格式:%timeit (要執行計時的程式碼)

範例一:

In [3]: %timeit new_list = [x**2 for x in range(1000)]
282 µs ± 10.1 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

範例二:換個方式寫程式碼,但目的一樣

In [4]: %%timeit
 ...: new_list = []
 ...: for x in range(1000):
 ...:  new_list.append(x**2)
 ...:
317 µs ± 15 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

可以看出雖然目的是一樣的,但兩個不同的程式碼寫法,執行時間是不同的喔

補充:如果想在IPython中使用多行就要兩個%,像是%%timeit



4. 如何查詢魔術指令的資訊與列出所有的魔術指令 - ?、%magic、%lsmagic

  • ?: 如果想查詢某個魔術指令的資訊,像是%run?
  • %magic: 獲得魔術指令的通用敘述與舉例
  • %lsmagic: 列出所有可用的魔術指令

我這邊列出一些魔術指令喔




1.4章 Input 和 Output 的歷史 - 使用In 和 Out 來獲取歷史記錄


1. In 和 Out 的用法

大家一定都有看到IPython中的提示符 - In[] 和 Out[],但大部分的人以為只是為了美觀所採用的修飾符,但其實它有很厲害的功用的,它能夠讓我們簡單獲得以前的輸入和輸出內容

範例:我們先照著以下的程式執行 - 我們導入math套件,並計算開根號、sin、cos和tan

In [1]: import math
​
In [2]: math.sqrt(2)
Out[2]: 1.4142135623730951
​
In [3]: math.sin(6)
Out[3]: -0.27941549819892586
​
In [4]: math.cos(6)
Out[4]: 0.960170286650366
​
In [5]: math.tan(6)
Out[5]: -0.29100619138474915

接下來,利用In和Out列印出我們執行過的輸入與輸出內容

In [6]: In
Out[6]:
['',
 'import math',
 'math.sqrt(2)',
 'math.sin(6)',
 'math.cos(6)',
 'math.tan(6)',
 'In']
​
In [7]: Out
Out[7]:
{2: 1.4142135623730951,
 3: -0.27941549819892586,
 4: 0.960170286650366,
 5: -0.29100619138474915,
 6: ['',
 'import math',
 'math.sqrt(2)',
 'math.sin(6)',
 'math.cos(6)',
 'math.tan(6)',
 'In',
 'Out']}
  • In: 返回輸入過的內容,會以串列(list)的形式傳回
  • Out: 返回輸出過的內容,會以字典的形式回傳

指定我們要看第幾個輸出或輸入

In [8]: print(In[1])
import math
​
In [9]: print(Out[4])
0.960170286650366


提醒:並不是所有輸入都會有輸出,像是import和print的語句就不會影響輸出(Output)內容,簡單來說就是import和print的結果,會返回None,而任何指令返回None都不會加入到Out中,所以print(Out)會看不到他們的結果


這個方法,對於拿過去的計算結果做運算,是非常方便的

In [1]: import math
​
In [2]: math.sin(6)
Out[2]: -0.27941549819892586
​
In [3]: math.cos(6)
Out[3]: 0.960170286650366
​
In [4]: Out[2]**2 + Out[3]**2
Out[4]: 0.9999999999999999


2. _下滑線用法 - 回到過去的輸出(Output)

想回到上一個輸出結果,就輸入一個""下滑線,前兩個輸出結果就兩個下滑線"",前三個輸出結果就三個下滑線_,但注意沒有以此類推囉XD,IPython最多只支援三個下滑線,而且它會自動跳過沒有輸出結果的命令喔

In [5]: print(_)
0.9999999999999999
​
In [6]: print(__)
0.960170286650366
​
In [7]: print(___)
-0.27941549819892586

也可以使用 格式:_ (第幾個輸出結果)來直接印出之前的輸出結果,像是我們會寫Out[4]來引出第四個輸出結果,而這邊有個更簡潔的寫法_4

In [8]: Out[4]
Out[8]: 0.9999999999999999
​
In [9]: _4
Out[9]: 0.9999999999999999


3. ";" - 不要將執行結果,加入道輸出結果的歷史中

  • 只要在指令後面加上";",就不會將這次的執行結果加入到Out裡
In [16]: math.sin(6)**2 + math.cos(6)**2;
​
In [17]: Out[16]
---------------------------------------------------------------------------
KeyError                Traceback (most recent call last)
<ipython-input-17-7ca36f6eddac> in <module>
----> 1 Out[16]
​
KeyError: 16
​
In [18]: 16 in Out
Out[18]: False


4. %history 批量查看歷史記錄(Input)

可以查看過去第幾個的輸入(Input)

  • 範例:我想查看過去第一到第四個輸入(Input)與第一到第五個輸入(Input)
In [1]: import math
​
In [2]: math.sin(6)
Out[2]: -0.27941549819892586
​
In [3]: math.cos(6)
Out[3]: 0.960170286650366
​
In [4]: math.tan(6)
Out[4]: -0.29100619138474915
​
In [5]: print(Out)
{2: -0.27941549819892586, 3: 0.960170286650366, 4: -0.29100619138474915}
​
In [6]: %history -n 1-4
 1: import math
 2: math.sin(6)
 3: math.cos(6)
 4: math.tan(6)
​
In [7]: %history -n 1-5
 1: import math
 2: math.sin(6)
 3: math.cos(6)
 4: math.tan(6)
 5: print(Out)



1.5章 IPython 和 Shell 指令 - 如何在IPython中下達Shell指令 - ls、cd、mkdir等等

  • 在Python環境中,當我們想要一邊下達對操作系統的Shell指令,一邊撰寫Python,我們只能再開一個終端窗口,或是退出Python環境,然後下達完指令,再切回Python,但是IPython可以讓我們同時在它的環境下,做到這兩種事


1. "!" - 輕鬆幫我們在IPython Shell中,執行Shell指令

In [2]: ls
 磁碟區 C 中的磁碟是 Windows
 磁碟區序號: 1C71-9B46
​
 C:\Users\user\Desktop\Book\Python-Data-Science-Handbook-Personal-Note\IPython-introduction\images 的目錄
​
2021/02/10 下午 12:10 <DIR>    .
2021/02/10 下午 12:10 <DIR>    ..
2020/11/28 下午 12:26     21,909 Command History Shortcuts.png
2020/11/24 下午 08:27      6,225 image1.PNG
2020/11/24 下午 08:30     55,914 image2.png
2020/11/24 下午 08:35     110,153 image3.png
2020/11/24 下午 08:37     138,940 image4.png
2020/11/24 下午 08:40     159,651 image5.png
2020/11/24 下午 08:41     239,450 image6.png
2021/02/10 下午 12:09     104,667 magic_function1.png
2021/02/10 下午 12:10     105,858 magic_function2.png
2020/11/28 下午 12:29     15,005 Miscellaneous Shortcuts.png
2020/11/28 下午 12:19     27,758 Navigation shortcuts.png
2020/11/28 下午 12:23     35,943 Text Entry Shortcuts.png
      12 個檔案   1,021,473 位元組
       2 個目錄 35,393,601,536 位元組可用
​
In [3]: pwd
Out[3]: 'C:\\Users\\user\\Desktop\\Book\\Python-Data-Science-Handbook-Personal-Note\\IPython-introduction\\images'
​
In [4]: !echo "Shell command - Printing"
"Shell command - Printing""

我自己試了在Windoes系統中,如果不加!會有作用嗎,發現也會有喔!!但是加了!,看起來更簡潔清楚


2. 從Shell中傳回值,並保存成一個看似Python的列表,但多了一些功能的列表

In [8]: file_list = !ls
​
In [9]: print(file_list)
["'ls' ���O�����Υ~���R�O�B�i���檺�{���Χ妸�ɡC"]
​
In [10]: directory_list = !pwd
​
In [11]: type(directory_list)
Out[11]: IPython.utils.text.SList

從印出的類型來看,它看起來像是Python的列表(list),但是多了一些額外的功能,像是grep和fields方法,以及s、n和p屬性,使我們能夠用簡單的方式進行搜索、過濾和顯示結果 file_list?


3. 從Python中傳值給Shell使用

  • Python也可以傳變數名稱給Shell使用,只要透過{變數名稱}即可
In [12]: context = "Values from Python"
​
In [13]: !echo {context}
Values from Python
​
In [14]: echo {context}
Values from Python


4. !cd 沒辦法在IPython中移動目錄位置

  • 原因:因為notebook中的Shell是在一個暫時的子Shell空間中運行的
  • 解決辦法:將!cd指令改成%cd或cd
  • 補充:除了%cd,其它相似的Shell指令,像是%cat、%cp、%env、%ls、%rmdir、%mkdir、%more、%rm、%pwd、%man和%mv,這些魔術命令在automagic啟動(打上%automagic來啟動或關閉)時都可以不用有%就能使用,也就是把IPython shell當成我們系統的shell使用



1.6章 Errors and Debugging - 非常重要的錯誤與除錯功能


1. %xmode - Controlling Exception - 異常控制 - Plain、Context和Verbose

  • %xmode - Exception mode的縮寫,用來控制異常發生時,錯誤訊息的數量
  • 模式:Plain、Context、Verbose,預設為Context
  • 使用方法:%xmode (一種模式名稱)

一般情況下,當程式出現錯誤時,系統會報的錯誤資訊

def divided(a, b):
  c = b - 1
  return a/c
​
divided(8,1)

執行結果

---------------------------------------------------------------------------
ZeroDivisionError            Traceback (most recent call last)
<ipython-input-3-c36e5fec3a86> in <module>
  3  return a/c
  4 
----> 5 divided(8,1)
​
<ipython-input-3-c36e5fec3a86> in divided(a, b)
  1 def divided(a, b):
  2  c = b - 1
----> 3  return a/c
  4 
  5 divided(8,1)
​
ZeroDivisionError: division by zero

當編譯器遇到了異常狀況的時候,會將錯誤產生的原因壓縮到眼前程式執行的追溯(Traceback)中,而IPython使我們可以控制異常發生時錯誤訊息的數量


2. Context模式: 預設模式

%xmode Context 
​
def divided(a, b):
  c = b - 1
  return a/c
​
divided(8,1)

執行結果

Exception reporting mode: Context
---------------------------------------------------------------------------
ZeroDivisionError            Traceback (most recent call last)
<ipython-input-4-b54a250447e3> in <module>
  5  return a/c
  6 
----> 7 divided(8,1)
​
<ipython-input-4-b54a250447e3> in divided(a, b)
  3 def divided(a, b):
  4  c = b - 1
----> 5  return a/c
  6 
  7 divided(8,1)
​
ZeroDivisionError: division by zero


3. Plain模式:更簡短的,較少的錯誤資訊內容

%xmode Plain
​
def divided(a, b):
  c = b - 1
  return a/c
​
divided(8,1)

執行結果

Exception reporting mode: Plain
Traceback (most recent call last):
​
 File "<ipython-input-8-01362f71b695>", line 7, in <module>
 divided(8,1)
​
 File "<ipython-input-8-01362f71b695>", line 5, in divided
 return a/c
​
ZeroDivisionError: division by zero


4. Verbose模式:更多訊息,包括函數調用時的參數值

%xmode Verbose
​
def divided(a, b):
  c = b - 1
  return a/c
​
divided(8,1)

執行結果

Exception reporting mode: Verbose
---------------------------------------------------------------------------
ZeroDivisionError            Traceback (most recent call last)
<ipython-input-10-6808dfac2ac2> in <module>
  5  return a/c
  6 
----> 7 divided(8,1)
   global divided = <function divided at 0x000002405C314048>
​
<ipython-input-10-6808dfac2ac2> in divided(a=8, b=1)
  3 def divided(a, b):
  4  c = b - 1
----> 5  return a/c
   a = 8
   c = 0
  6 
  7 divided(8,1)
​
ZeroDivisionError: division by zero


Verbose可以擁有那麼多的錯誤資訊,為什麼不都用它就好?

當我們的程式越來越多的時候,太多的訊息很難閱讀,所以要視情況,有時候簡短才能幫助我們快速進行除錯(Debugging)喔



5. %debug 進階用法 - 當Traceback已經不能滿足問題

  • Python - 標準Python下有一個交互式的除錯工具 - pdb
  • IPython - 有一個增強版的除錯工具 - ipdb


ipdbb是什麼?

ipdbb讓我們可以查看當前的Traceback訊息,還可以顯示變數與它們的值,甚至還能直接執行Python命令


當執行%debug,就會啟動ipdbb交互式界面,讓我們查詢變數值等等功能

%debug 

範例:像是我們現在有一個程式執行的時候會報錯

def divided(a, b):
  c = b - 1
  return a/c
​
divided(8,1)

這時候就執行%debug,來開啟ipdbb

%debug

使用print來得知變數值

> <ipython-input-11-c36e5fec3a86>(3)divided()
   1 def divided(a, b):
   2  c = b - 1
----> 3  return a/c
   4 
   5 divided(8,1)
​
ipdb> print(a)
8
ipdb> print(b)
1
ipdb> print(c)
0
ipdb> print(a/c)
*** ZeroDivisionError: division by zero
ipdb> quit

使用up、down來回溯上一層或下一層,當很多個Function互相調用(call)對方時,幫助我們從眾多Function中找尋哪個Function出問題

> <ipython-input-11-c36e5fec3a86>(3)divided()
   1 def divided(a, b):
   2  c = b - 1
----> 3  return a/c
   4 
   5 divided(8,1)
​
ipdb> up
> <ipython-input-11-c36e5fec3a86>(5)<module>()
   1 def divided(a, b):
   2  c = b - 1
   3  return a/c
   4 
----> 5 divided(8,1)
​
ipdb> down
> <ipython-input-11-c36e5fec3a86>(3)divided()
   1 def divided(a, b):
   2  c = b - 1
----> 3  return a/c
   4 
   5 divided(8,1)



如何將除錯工具ipdbb保持啟動的狀態,程式執行報錯就會馬上開啟

  • 使用%pdb,後面加上on/off 來開啟或關閉除錯工具的自動開啟模式
  • 使用方法:%pdb (on/off)
%xmode Verbose
%pdb on
​
​
def divided(a, b):
  c = b - 1
  return a/c
​
divided(8,1)

執行結果

Exception reporting mode: Verbose
Automatic pdb calling has been turned ON
---------------------------------------------------------------------------
ZeroDivisionError            Traceback (most recent call last)
<ipython-input-16-2425b790b5b2> in <module>
  7  return a/c
  8 
----> 9 divided(8,1)
   global divided = <function divided at 0x000002405C3F70D8>
​
<ipython-input-16-2425b790b5b2> in divided(a=8, b=1)
  5 def divided(a, b):
  6  c = b - 1
----> 7  return a/c
   a = 8
   c = 0
  8 
  9 divided(8,1)
​
ZeroDivisionError: division by zero
ipdb> 
> <ipython-input-16-2425b790b5b2>(7)divided()
  5 def divided(a, b):
  6  c = b - 1
----> 7  return a/c
  8 
  9 divided(8,1)



外部的Python檔,如何在IPython中交互式的執行,並且同時打開除錯工具 - ipdbb

  • 使用%run -d來執行Python檔,然後使用next在交互模式下進行一步一步執行Python檔中的程式
In [1]: %run python_script.py
0 multiply of 1 : 0
1 multiply of 2 : 2
2 multiply of 3 : 6
3 multiply of 4 : 12
4 multiply of 5 : 20
5 multiply of 6 : 30
6 multiply of 7 : 42
7 multiply of 8 : 56
8 multiply of 9 : 72
9 multiply of 10 : 90
​
In [2]: %run -d python_script.py
*** Blank or comment
*** Blank or comment
*** Blank or comment
NOTE: Enter 'c' at the ipdb> prompt to continue execution.
> c:\users\user\desktop\book\python-data-science-handbook-personal-note\ipython-introduction\python_script.py(3)<module>()
   1 ## python_script.py
   2
----> 3 def multiply(a,b):
   4  '''a multiply of b'''
   5
​
ipdb> 



開啟除錯模式ipdbb,可以下達的命令



ipdbb 的官方文檔:https//github.com/gotcha/ipdb

CC BY-NC-ND 2.0 版权声明

喜欢我的文章吗?
别忘了给点支持与赞赏,让我知道创作的路上有你陪伴。

加载中…
加载中…

发布评论