標籤:分享圖片 列表 有一個 分行符號 寫入 water 數字 python3 存在
今天講編程思維。
可能這對初次接觸編程的人有用——我不是不想切入正題,我只是想強調根本沒什麼正題,我可能在其他文章裡提過這一點。“程式設計語言就是文法糖”,可能你不知道什麼是文法糖,但是知道的人也未必認同我。我不保證你們能聽懂……python的教程有很多,但是我對很多都不滿意,所以這算是我的嘗試吧。
我們將實現一個【篩選100以內素數】的程式。我不用python語言,而是用虛擬碼——虛擬碼沒有固定寫法,但是自然不是所有東西都叫虛擬碼。成為虛擬碼需要兩個性質:
沒有歧義。可能別人會覺得有歧義,只要你覺得沒有就行。
可執行。這意味著你必須輸入一個動作,而不是“今天天氣很好”等等。
但可執行檔不都是機器可以做的。一般地,你可以讓機器做:
絕大部分你覺得比較“機械”的工作,機器都可以做。雖說我不知道你們對機器有何感覺……
現在我們試圖實現一個篩選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放進Afor 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*xa = 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入門教程(二)