給老婆寫個Python教程

AI科技大本營發表於2019-02-26

640?wx_fmt=jpeg

 

作者 | 水風

來源 | 水風知乎問答

 

如何挑戰百萬年薪的人工智慧!

https://edu.csdn.net/topic/ai30?utm_source=csdn_bw

 

什麼是code

 

code就是一種語言,一種計算機能讀懂的語言。計算機是一個傻逼,他理解不了預設兩可的任何東西。比如,你讓你老公去買個西瓜,你老公會自己決定去哪裡買,買幾個,找個搞活動打折的買,總之,你給他錢,他就給你買回來讓你吃到爽的西瓜。但是,你想讓計算機買一個西瓜?你要告訴他:去門口的鮮豐水果店買,買沙瓤無子西瓜,若旁邊的店打折,就去旁邊的店買。總之,你不能讓計算機做任何決定,你要清楚的告訴他所有情況下的所有的行為。而code,就是你和計算機交流的語言,或者說是對計算機的命令。

 

我們就把計算機理解為一個人,這個人很死板,只能按照你給他的詳細命令進行工作。而這個人工作速度特別特別快,並且保證工作結果都是正確的。

 

程式語言其實不重要,重要的是要明白如何和計算機交流,明白了這個也就能看懂程式碼了。

 

python就是一種和計算機交流的語言,這種語言單詞(關鍵字)不多,規則也少。下面所有的內容都基於python。

 

判斷

 

當你命令計算機做一件事情的時候,這件事情可能分一些情況進行處理。

判斷通常涉及到的關鍵字有:if , else, elseif, and, or,<, >,=,<=,>=,==

 

比如,你讓計算機買西瓜,希望買到打折的西瓜,不打折的話你就不吃了。

 


 

if  水果店打折:
    買西瓜
else:
    不買了

 

通過這個命令,計算機變得更智慧了一些,他可以根據情況執行你的命令。

 

水果店不打折你就吃不到西瓜,你不開心。那麼,我們讓計算機更智慧一些。假如西瓜打折,就買西瓜;不打折的話讓計算機跟老闆講價,老闆同意打折,就買西瓜;不同意,不吃了;

 

 


 

if  水果店打折:
    買西瓜
else:
    與老闆講價
    if 講價成功:
        買西瓜
    else:
        不吃了。

 

 

雖然和老闆講價一般都能講成功,但是有的老闆給力給打五折,有的老闆只給打九折。你就想了,若老闆打五折,我就買兩個,今天吃一個,明天吃一個。若老闆不給力,打折不到五折,就買一個,今天先吃,明天再說。

 

 


 

if  水果店打折:
    買西瓜
else:
    與老闆講價
    if 打折成功 and 打折力度<=5
        買兩個西瓜
    elseif 打折成功 and 打折力度 > 5
        買一個西瓜
    else:
        不吃了。

 

 

此外,有沒有發現,打著成功這段程式碼其實也可以寫成:

 

 


 

if 打折成功:
        if 打折力度<=5:
            買兩個西瓜
        else:
            買一個西瓜
    else:
        不吃了。

 

 

由此可見,計算機也不是完全的一成不變,只要你給他的命令他能理解並且不會預設兩可,他都可以完成工作。

 

and的意思代表且,or的意思代表或。and和or的順序不同,結果也不同,可以通過括號來說明判斷條件的優先順序。

 

a==b是比較a和b是否相等的意思,而=代表賦值。賦值的含義,我在下面的變數章節介紹。

 

迴圈

 

python中涉及到迴圈的關鍵字包括:for...in... ,while,break,continue

 

上面的例子我們已經讓電腦成功的可以根據不同的情況去水果店買西瓜了,但是若老闆不打折,你就吃不到西瓜了。這時,你就想了,我們們小區門口有三家水果店,分別是鮮豐水果、四季水果和路邊攤,一家不打折不代表三家都不打折啊,所以你希望電腦可以去三家都去看看,挑一家打折的店買西瓜。

 

 


 

for 水果店 in (鮮豐水果、四季水果和路邊攤):
    if 水果店 打折:
        買西瓜
        break(迴圈結束)
    else:
        啥都不做
帶西瓜回家

 

 

迴圈的意義在於,可以用電腦對不同的物件執行相同的命令。

 

介紹下break,break的意思就是結束迴圈。比如,這段程式碼中的break表示,我們一旦買了西瓜,那麼就帶西瓜回家。

 

變數

 

現在是時候介紹'變數'這個重要的東西了。

 

我們依然把電腦理解為幫我們工作的一個人,那麼作為一個人,他需要有記憶力,而我們就可以通過變數去控制、利用計算機的記憶力。

 

變數可以理解為計算機的一個記憶單元,計算機擁有極好的記憶力,所以,可以隨心所欲的使用,用完了就扔,需要了就要。(當然,說隨心所欲是不嚴謹的,但是你可以理解為隨心所欲)

 

那為什麼叫變數呢,就是因為可以改變。為什麼要改變呢?比如我們都有自己的年齡,我今年18,明年就19了。所以,'年齡'在我的記憶裡是每年改變的。

 

變數對應的一個東西叫常量,在我的記憶力,我的老婆是江江同學。而這個'老婆'這個記憶單元在我的腦子裡是不會變的,她永遠都是江江同學。常量你現在可以不用理解,我寫主要是為了秀恩愛。

 

現在,計算機又要去買西瓜了。不過這次,你希望計算機可以在三個水果店中,找到一個打折力度最大的水果店去買水果。

 

 


 

之前所有水果店的最大折扣 = None
之前給最大折扣的水果店 = None
for 水果店 in (鮮豐水果、四季水果和路邊攤):
    當前水果店折扣 = 老闆給的折扣
    if 當前水果店折扣 < 之前所有水果店的最大折扣:#4折比5折力度大
        之前所有水果店的最大折扣 = 當前水果店折扣
        之前給最大折扣的水果店 = 水果店

去 之前給最大折扣的水果店 買一個西瓜

 

 

以上有以下幾個記憶單元:

 

  • 之前所有水果店的最大折扣

  • 之前給最大折扣的水果店

  • 當前水果店折扣

  • 水果店 注意,for a in b,a也是一個變數,他在每次執行的時候都是b中的當前執行的一個元素。

 

這裡需要介紹一些概念:

 

  • None 在python中表示空,表示這個記憶單元現在啥都沒有。比如在我情竇初開時,腦海中就已經有了情人這個記憶單元,我一直在尋找,但遇到你之前一直沒有找到,所以那段時間這個記憶單元裡面一直是空。

  • 賦值符號:=。 注意,在計算機語言裡面,一個'='號表示賦值,兩個等號'=='表示比較前後元素。賦值的意思是,把後面的元素,放到前面的變數裡面。

 

變數的作用域

 

作用域這個東西非常重要,但是真心不想講,因為沒辦法結合現實的例子,不過還是大體說明下。

 

還是剛才的例子,我加了行號,並且我使用-代表空格,表示程式碼的縮排。

 

 


 

1 之前所有水果店的最大折扣 = None
2 之前給最大折扣的水果店 = None
3 for 水果店 in (鮮豐水果、四季水果和路邊攤):
4 ---當前水果店折扣 = 老闆給的折扣
5 ---if 當前水果店折扣 < 之前所有水果店的最大折扣:#4折比5折力度大
6 ------之前所有水果店的最大折扣 = 當前水果店折扣
7 ---之前給最大折扣的水果店 = 水果店
8 去 之前給最大折扣的水果店 買一個西瓜

 

 

你看這個例子可能納悶,為什麼要先給'之前所有水果店的最大折扣'、'之前給最大折扣的水果店'這兩個變數賦值為None呢。就是因為作用域問題。

 

你看這個程式,每行程式碼的縮排都是不一樣的。變數作用域可以理解為:一個變數,只有在其第一次出現的地方的縮排,以及縮排更多的程式碼裡面,才有效。我們第1、2行的變數,就可以用於3-8行,因為這些程式碼的縮排都在1、2行的後面。而第四行的變數'當前水果店折扣',只在5、6、7行有效

 

 


 

1  A = None
2  ————B = None
3  ————..
4  ————————C = None
5  ————————..
6  ————D = None
7  ————..
8  ————————..
9  ————————..
10 ..
11 ..

 

 

再舉個例子,ABCD是變數,..代表某些程式碼。A的作用域就是1-11行,即1-11行都可以使用A。B的作用域是2-9行,C的作用域只有4-5行,注意,8-9行就不能再使用C了,雖然他的縮排和4、5行一樣,作用域遇到第一個不能用縮排行程式碼即結束。D的作用域就是6-9行。

 

函式和模組

 

看懂以上幾節,大概應該明白計算機如何執行程式碼的了。

 

而函式和模組,和之前的介紹不太一樣。之前是介紹如何讓計算機工作,是面向計算機的。而這一節,是面向人的,是如何讓我們寫給計算機的程式碼看起來更加簡潔、明瞭。函式和模組都是對程式碼結構的優化,否則一個稍微大點的專案,一大坨程式碼,計算機看得懂人看不懂,不利於管理和交流。

 

首先說函式。函式是一系列程式碼的集合,用函式一般是有幾個原因:

 

1.給一段程式碼起個名字。

2.這段程式碼和使用它的程式碼關係不大,所以可以抽出來,抽出來後程式碼更簡潔。關係不大的意思就是:使用函式的程式碼通過傳給函式幾個引數,函式就可以執行。

3.程式碼集合起來就可以在程式碼的不同地方使用。

 

依然我們去買西瓜,不過我們希望電腦可以今天買完西瓜明天再買一個。按照之前的方式,這個邏輯應該寫成這樣:

 

 


 

for 水果店 in (鮮豐水果、四季水果和路邊攤):
    if  水果店打折:
        買西瓜
    else:
        與老闆講價
        if 打折成功 and 打折力度<=5
            買兩個西瓜
        elseif 打折成功 and 打折力度 > 5
            買一個西瓜
        else:
            不吃了。

休息一天。

for 水果店 in (鮮豐水果、四季水果和路邊攤):
    if  水果店打折:
        買西瓜
    else:
        與老闆講價
        if 打折成功 and 打折力度<=5
            買兩個西瓜
        elseif 打折成功 and 打折力度 > 5
            買一個西瓜
        else:
            不吃了。

 

 

上面的程式碼可以實現我們的要求,但是買西瓜的程式碼其實是重複的,對於重複程式碼,管理起來比較麻煩,比如你想改一點,那麼就要去各個地方都改一次。

 

那麼,我們把買西瓜的程式碼弄成一個函式,程式碼就可以整理為:

 

 


 

def 買西瓜_函式():
    for 水果店 in (鮮豐水果、四季水果和路邊攤):
        if  水果店打折:
            買西瓜
        else:
            與老闆講價
            if 打折成功 and 打折力度<=5
                買兩個西瓜
            elseif 打折成功 and 打折力度 > 5
                買一個西瓜
            else:
                不吃了。

買西瓜_函式()
休息一天。
買西瓜_函式()

 

 

這一次,程式碼整潔多了,而且,我們每次想修改買西瓜的程式碼,都只需要改這個函式一處程式碼都可以。

 

在python中,使用def function_name():定義函式,函式下面所有的縮排都屬於這個函式,叫函式體。

 

使用function_name()呼叫函式。

 

函式引數

 

現在你又不滿足與電腦只會買西瓜了,你又想吃柚子。怎麼辦呢,那麼是不是我們又要寫一個買柚子的函式呢。

 

當然可以再寫一個買柚子函式,但是買柚子函式的邏輯和買西瓜函式的邏輯都是一樣的,命令也一樣,唯一的區別就是之前是賣西瓜,現在是買柚子。如果再寫一個類似的買柚子函式,那麼又出現剛才說的問題,每次修改買水果的邏輯,都需要同時去修改買西瓜、買柚子函式,如果柚子吃膩了,又要買香蕉、蘋果、梨,豈不是要寫非常多的函式?

 

為了解決這個問題,其實有一個更好的方法,就是使用函式引數。

 

由於我們買水果(無論是西瓜、還是柚子)的功能都是一樣的,所以我們可以寫一個買水果函式,買水果函式定義了買一個水果的流程,當我們使用這個函式的時候,我們只要告訴這個函式我們要買什麼水果,函式就可以根據你告訴他的水果名,去買對應的水果。

 

買水果函式的程式碼如下:

 

 


 

def 買水果函式(水果名):
    for 水果店 in (鮮豐水果、四季水果和路邊攤):
        if  水果店打折:
            買[水果名]
        else:
            與老闆講價
            if 打折成功 and 打折力度<=5
                買兩個[水果名]
            elseif 打折成功 and 打折力度 > 5
                買一個[水果名]
            else:
                不吃了。


買水果函式(西瓜)#讓電腦去買西瓜
買水果函式(柚子)#讓電腦去買柚子

 

 

在python中想使用函式引數,只需要在函式定義的時候,在括號裡面加上引數即可,我們這裡的引數就是'水果名'。在函式體中程式碼可以使用函式引數。

 

在呼叫函式的時候,把一個變數或者常量寫在函式名後面的括號裡面,傳給函式。

 

注意,若是存在多個引數,函式定義和呼叫函式的引數順序一定要一致。

 

在python中,還存在預設引數、關鍵字引數等稍微高階一點的使用方式,舉個例子,不詳細說明了。

 

 


 

def sum(a, b = 0,c = 1):#b/c是預設引數
   return a+b+c

func(1,0,1)
func(1)
func(1,c=1)

 

 

這三個func呼叫的結果都是一樣的。

 

未完待續....

 

原文地址:

https://www.zhihu.com/question/60766946/answer/183072131

 

(本文為 AI大本營轉載文章,轉載請聯絡原作者)

 

人工智慧的現狀及今後發展趨勢如何? 

https://edu.csdn.net/topic/ai30?utm_source=csdn_bw

 

 

群招募

 

掃碼新增小助手微信,回覆:公司+研究方向(學校+研究方向),邀你加入技術交流群。技術群稽核較嚴,敬請諒解。

640?wx_fmt=jpeg

推薦閱讀:

                         640?wx_fmt=png

點選“閱讀原文”,檢視歷史精彩文章。

相關文章