1. 程式人生 > >Python入門教程(二)

Python入門教程(二)

ack 布爾代數 記事本 成對 .py 語法錯誤 是什麽 ech eclips


  今天講編程思維。


  可能這對初次接觸編程的人有用——我不是不想切入正題,我只是想強調根本沒什麽正題,我可能在其他文章裏提過這一點。“編程語言就是語法糖”,可能你不知道什麽是語法糖,但是知道的人也未必認同我。我不保證你們能聽懂……python的教程有很多,但是我對很多都不滿意,所以這算是我的嘗試吧。


  我們將實現一個【篩選100以內素數】的程序。我不用python語言,而是用偽代碼——偽代碼沒有固定寫法,但是自然不是所有東西都叫偽代碼。成為偽代碼需要兩個性質:

  1. 沒有歧義。可能別人會覺得有歧義,只要你覺得沒有就行。

  2. 可執行。這意味著你必須輸入一個動作,而不是“今天天氣很好”等等。


  但可執行的不都是機器可以做的。一般地,你可以讓機器做:

  • 創建一個變量。變量就像空盒子,你可以往裏放一個東西,但只能放一個。最常見的是裝一個數,0,12345,-233333,等等。

  • 向變量裏放東西。

  • 對數進行數學運算,並把結果放到某個變量

  • 打印字符串;打印一個數。(“打印”僅僅表示顯示在屏幕上,這是一般說法)

  • 條件選擇。(以後再說)

  • 循環。(以後再說)


  絕大部分你覺得比較“機械”的工作,機器都可以做。雖說我不知道你們對機器有何感覺……


  現在我們試圖實現一個篩選100以內素數的程序。你完全可以按著自己的意願寫,比如:

如果1是素數,打印1
如果2是素數,打印2
如果3是素數,打印3
如果4是素數,打印4
如果5是素數,打印5
如果6是素數,打印6
如果7是素數,打印7
如果8是素數,打印8
如果9是素數,打印9
如果10是素數,打印10
如果11是素數,打印11
如果12是素數,打印12
如果13是素數,打印13
如果14是素數,打印14
如果15是素數,打印15
如果16是素數,打印16
如果17是素數,打印17
如果18是素數,打印18
如果19是素數,打印19
如果20是素數,打印20
如果21是素數,打印21
如果22是素數,打印22
如果23是素數,打印23
如果24是素數,打印24
如果25是素數,打印25
如果26是素數,打印26
如果27是素數,打印27
如果28是素數,打印28
如果29是素數,打印29
如果30是素數,打印30
如果31是素數,打印31
如果32是素數,打印32
如果33是素數,打印33
如果34是素數,打印34
如果35是素數,打印35
如果36是素數,打印36
如果37是素數,打印37
如果38是素數,打印38
如果39是素數,打印39
如果40是素數,打印40
如果41是素數,打印41
如果42是素數,打印42
如果43是素數,打印43
如果44是素數,打印44
如果45是素數,打印45
如果46是素數,打印46
如果47是素數,打印47
如果48是素數,打印48
如果49是素數,打印49
如果50是素數,打印50
如果51是素數,打印51
如果52是素數,打印52
如果53是素數,打印53
如果54是素數,打印54
如果55是素數,打印55
如果56是素數,打印56
如果57是素數,打印57
如果58是素數,打印58
如果59是素數,打印59
如果60是素數,打印60
如果61是素數,打印61
如果62是素數,打印62
如果63是素數,打印63
如果64是素數,打印64
如果65是素數,打印65
如果66是素數,打印66
如果67是素數,打印67
如果68是素數,打印68
如果69是素數,打印69
如果70是素數,打印70
如果71是素數,打印71
如果72是素數,打印72
如果73是素數,打印73
如果74是素數,打印74
如果75是素數,打印75
如果76是素數,打印76
如果77是素數,打印77
如果78是素數,打印78
如果79是素數,打印79
如果80是素數,打印80
如果81是素數,打印81
如果82是素數,打印82
如果83是素數,打印83
如果84是素數,打印84
如果85是素數,打印85
如果86是素數,打印86
如果87是素數,打印87
如果88是素數,打印88
如果89是素數,打印89
如果90是素數,打印90
如果91是素數,打印91
如果92是素數,打印92
如果93是素數,打印93
如果94是素數,打印94
如果95是素數,打印95
如果96是素數,打印96
如果97是素數,打印97
如果98是素數,打印98
如果99是素數,打印99
如果100是素數,打印100

  這【是】偽代碼,因為既沒有歧義,又可以執行。但機器沒法執行,因為“是素數”我們理解,機器並不能理解。但是我們可以把“是素數”拆成幾個分開的條件,使得機器可以理解較簡單的條件。不過在此之前,我們該先考慮一下,這100行是不是太多了?我們可以用上一些小技巧:

新建一個變量A
把1放進A
如果A中的數是素數,打印A中的數
把A中的數增加1
回到第三行

  原本要100行的代碼,現在只要5行了——這就是循環的一大用處,顯然“回到第三行”導致了一個循環的形成。但是這個代碼並不對,因為它會無限循環下去,根本不會結束,“能不斷地打印素數”。所以要做一些修改:

新建一個變量A
把1放進A
如果A中的數是素數,打印A中的數
把A中的數增加1
如果A大於100,跳出循環
回到第三行

  因為這裏只有一個循環,所以“跳出循環”是偽代碼。python是強大的語言,理應可以把這些偽代碼改成python語言,可惜世界上有一個詭異的規定(絕大多數語言,C是例外):不許用“回到第三行”這種話。為了彌補,可以這樣寫:

新建一個變量A
把1放進A
把下面括號裏的話重復100遍
(
如果A中的數是素數,打印A中的數
把A中的數增加1
)

  接下來我們處理“是素數”。如果一個數大於3,並且除以所有大於1、比自身小1的數都有余數,那麽它是素數。所以以下兩段代碼功能是一樣的:

1:

如果A中的數是素數,打印A中的數

2:(一般地,我們用直接用變量名稱呼其中的東西,雖說用盒子的名字稱呼裏面的東西很奇怪)

新建一個變量B
新建一個變量“這個數還有可能是素數嗎”
把2放進B
把字符串“有可能”放進變量“這個數還有可能是素數嗎”
把下面括號裏的句子一直重復下去
(
如果A除以B沒有余數,那麽把字符串“不可能”放進變量“這個數還有可能是素數嗎”
把B加上1
如果此時B等於A,那麽跳出循環
)
如果變量“這個數還有可能是素數嗎”中是“有可能”,打印A中的數

  加到一起,就是這樣:(同時循環的只有一層,跳出循環仍然沒有歧義)

新建一個變量A
把1放進A
把下面括號裏的話重復100遍
(
新建一個變量B
新建一個變量“這個數還有可能是素數嗎”
把2放進B
把字符串“有可能”放進變量“這個數還有可能是素數嗎”
把下面括號裏的句子一直重復下去
(
如果A除以B沒有余數,那麽把字符串“不可能”放進變量“這個數還有可能是素數嗎”
把B加上1
如果此時B等於A,那麽跳出循環
)
如果變量“這個數還有可能是素數嗎”中是“有可能”,打印A中的數
把A中的數增加1
)

  現在我們第一次正式使用python代碼:(#號到行末是註釋,不會當成語句運行,僅僅為了方便程序員閱讀)

a = 1                                               #   新建變量A, 並把1放進A
for i in range(100):                                #   把下面括號裏的話重復100遍
                                                    #(
    b = 2                                           #   新建變量B, 並把2放進B
    這個數還有可能是素數嗎 = "有可能"                     #   新建變量“這個數還有可能是素數嗎”, 並放入字符串“有可能”
    while True:                                     #   把下面括號裏的句子一直重復下去
                                                    #(
        if a % b == 0:這個數還有可能是素數嗎 = "不可能"   #   如果A除以B沒有余數,那麽把字符串“不可能”放進變量“這個數還有可能是素數嗎”
        b += 1                                      #   把B加上1
        if a == b:  break                           #   如果此時B等於A,那麽跳出循環
                                                    #)
    if 這個數還有可能是素數嗎 == "有可能":print(a)        #   如果變量“這個數還有可能是素數嗎”中是“有可能”,打印A中的數
    a += 1                                          #   把A中的數增加1
                                                    #)

  “把數放進變量”——即“賦值操作”,用的符號是等號。其實這並不符合直覺,並且用久了會產生錯覺。代碼中出現的雙等號表示比較操作,等號只能用於賦值。

  這段代碼中,for i in range(100) 意思是新建一個叫 i 的變量,並且使其為0。python中必須在創建時賦值,其實等於在第一次使用時創建。然後括號——python不用括號,而是在需要括號的時候縮進4格,括號結束的時候向前4格,這樣就能對齊了——括號中的內容執行一遍,i 加上1,就這麽繼續下去。

  然而上面的代碼並不工作。你會看到光標不停地閃——因為1並不能用上述方法檢驗是否為素數。但是從3開始就沒問題了——大於1、且比自身小1的數得以存在,邏輯也得以運行了。所以我們把第一行改成a=3 。

  然而結果中出現了101……所以我們再改改……但是這些邏輯錯誤——而不是語法錯誤,是這門語言之外的東西了。我們在寫偽代碼的時候就沒有考慮周全,並不是我們沒有學好這門語言。


  這個小程序非常原始,但是很關乎思維。我們至少能看到3個啟示:(並且長久地有效)

  • 用循環取代重復的東西

  • 註意循環如何結束

  • 註意循環能否開始


  而編程思維以外的東西,也就是傳統書籍的絕大多數,我決定略過。但是學會了去提問,你就會發現,你確實只要學這麽多就夠了,授人以魚不如授人以漁。接下來講解幾個關鍵詞。


函數

  請看代碼:

def f(x):
	return 2*x

a = f(7)	
print(a)

  函數就是函數,可以簡化數學操作。然而除了數學操作,函數也可以做其他操作,但是受一些限制。如果你要反復計算一個數的2倍(或者2倍+3+2的這個數倍+……這樣的復雜函數),def是很好的選擇。def應該是define(中文:定義)的縮寫。你可以在函數裏寫print,引用函數之外的變量,以及 不能 修改函數之外的變量,等等。

  想了解更多,百度搜索“python3函數”,一個技巧是,看不懂就先挑看得懂的看。


字符串

  在python中,【半角,也就是英文下的】引號中的內容會被當成字符串。在英文中是沒有前引號和後引號之分的,在從前往後讀的時候,第一個會被當成前引號,第二個則與前一個匹配,被當做後引號。可以把字符串賦值給一個變量。如果一串英文不在引號裏,那麽它會被看成一個變量名稱。中文引號起不到引號的作用。空格是一個字符,換行符也是一個字符(不妨print("hello\nworld")),但是換行符不能一下子打出來,人們用“\”後跟一個字母表示這些不可見的符號,\n為換行,\\為\自身,\"為雙引號(顯然引號不能單獨打出來)。犧牲一個符號,獲得一堆額外的符號還是值得的。python中,單雙引號可以成對混用(匹配同種),但我習慣用單引號處理單個字符(單個字符也是字符串)。

  能放進變量裏的東西——比如“字符串”,可以百度“python3字符串方法”(又比如“python3復數方法”,但字符串的方法尤其多)。“方法”就是加個點後跟一個函數,是函數的一種。說“方法”而不說“函數”的人,大多是強調這種函數可以用一個“.”來調用之。至於是怎麽回事,下一個教程再說(與“類”有關)


列表

l = [1,2,3,4,5]
print(l [0])
print(l [1])
print(l [2])
print(l [3])
print(l [4])

  五個print打印出12345 。a[ i ]表示a中第 i 個元素,但是起始的一個是“第0個元素”。就像有些樓的底層是“第0層”——這一習慣並非沒有優點。

  如果把第一行改成 l=1 ,到下一行會出錯。因為整數沒有“第n個元素”。

  l後括號前一般不用空格,這裏是為了看得清楚

  (“python3列表方法”)


元組

t = (1,2,3,4,5)
print(t[0])
print(t[1])
print(t[2])
print(t[3])
print(t[4])

  元組和列表很相似。但是列表可以在被創建後再次賦值,比如可以a[2] = 100 。但試圖用於元組時,會報錯。元組不可改變——也並非沒有優點

  可以用a, b = (1,2) 一下子賦多個值,僅元組可以。

字典

d = {"name" : "Jack", "age" : "7", "hobby" : "nothing"}
print(d["name"])
print(d["age"])
print(a["hobby"])

  你知道會打印出什麽。"name" "age" "hobby"(註意有引號,是字符串)都是字典的“鍵”,"Jack" 7 "hobby"都是“值”,"Jack"是鍵"name"對應的值,"name" : "Jack"稱為一個“鍵值對”。值可以說任何能放進變量的東西,鍵必須是不可修改的東西(比如整數,字符串,元組)


else

  百度“python3條件語句”


異常

  百度“python3條件語句”,“python3 assert”(斷言)


文件操作

  代碼:(自行理解)(r是read,用讀取模式打開;w是write,用寫入模式打開,將清除原有內容;還可以用a,用追加模式打開,將在最後繼續寫入。總之不能回改)

with open("演示.txt",'w') as tp:
	tp.write("六個演示文字\n")
	tp.write("十三個演示文字")
	tp.write("二十個演示文字")
	
	
with open("演示.txt",'r') as tp:
	print(tp.read())
	

print("="*20)
print("===============")

with open("演示.txt",'r') as tp:
	print(tp.readline())
	print(tp.readline())


鍵盤輸入

  代碼:(回車確認輸入)

s = input("輸入提示符> ")
print("剛才輸入的是:",s)


模塊(導入)

  from xxx import * ,相當於把同一文件夾下的xxx.py 文件內容全部粘貼在這裏。

  import xxx,類似上一條,但是如果要使用那個文件中的變量a,要寫成xxx.a ;用那個文件中的函數,寫成xxx.f( )


布爾值

  True和False,和普通變量名看起來沒什麽大區別(首字母大寫而已),但是為python保留字,即不可對其賦值。1 == 1的值為True,1!= 1為False(不等於的意思),1=='a' 的值為False,3 > 2的值為True,字符串和數字可以比較是否相等,比較大小會報錯。如果強制對布爾值做加法,True被視為1,False為0 。

  可搜索“布爾代數”


標準庫

  庫是模塊。多數放在環境變量下。

  例如 import os 後可以使用os.system("echo hello"),你知道那是什麽; import sys 後可以sys.stdout = open("xxxxxxxxxxxxxxxxxxxxxxx.txt",'w') ,然後接著隨便print點東西看看後果

  搜索“python標準庫”


IDE

  有些教程一開始就配置IDE,我認為命令行有必要先講。所謂IDE就是一個豪華些的記事本,另外會給你一個按鈕(但是往往不止一個按鈕),點一下,就會給命令行發送消息,比如“python xxx.py”。我用的是Geany,感覺還不錯。反正我堅決反對新手用VS和eclipse,我到現在也剛剛能看懂罷了(畢竟不用)。網上搜索“geany python”有教程,但是最後一步我放個圖(環境變量的用處來了)

技術分享圖片

  只有執行一欄有用,因為python幾乎不編譯。而且好像只能一下子粘貼,不能輸入(我電腦的問題?),在記事本裏打完整復制吧。


類、面向對象

  下次的內容。


Python入門教程(二)