[不做怎麼知道系列之Android開發者的30天後端養成故事 Day2] - 建立自信心 #一起練Python語法 #不能拖 #先照著教學做

所以我說,剛開始要做什麼呢?

RS 個人覺得,不管學習什麼,不論是新技能、新知識,必須先在一開始就 迅速 建立 自信心,相信這一點大家都知道,但很多人會忽略一點是 迅速 兩個字,人閒著就很容易想東想西,一旦你沒有動手執行,隨著時間的經過,你的自信心會呈現非線性的衰弱狀態。

不知道你有沒有這樣子的經驗,有些事情做著做著,就突然感覺很有自信,覺得你問什麼問題我都可以回答你,沒在怕的;還有一個經驗是,以前明明很會做某件事,可是好一段時間沒再接觸了,突然有人問我以前很熟的事情,我卻懷疑自己認為的是不是真正的事實。

而快速建立自信的方法,就是 先照著教學做 就對了,而且執行的中間盡量不要休息或隔太久,讓自己保持在一個 啟動 的狀態,這就有點像是騎車的起步總是最難、靜止到移動需要克服最大靜摩擦力一樣,當你呈現啟動的狀態後,摩擦力相對就沒有像一開始那麼大。

這也是為什麼 30 天鐵人賽這麼迷人的地方,當你持續不間斷的做同一件事情,你會 非常 有信心,不信嗎? 你可以試試看。

攝影師:bruce mars,連結:Pexels

沒有頁碼的目錄

避免加上程式碼會讓文章冗長,所以先上目錄,各位看官可以挑選自己有興趣或不足的章節:

  • 那我們就開始囉
    • 版本選擇 & 安裝
    • 第一支程式 (Hello World)
  • 基礎語法們
    1. 變數(Variables) & 資料型別 (Data Type)
      • 基本型別
      • 關於型別,你需要瞭解更多 (檢查記憶體、型別轉換、各種進位)
      • 區域變數 (Local variables) & 全域變數 (Global variables) & 作用範圍(Scope)
    2. 邏輯控制 (Control Statements)
      • if else & for loop
    3. 好用小技巧
      • 給多個變數單行指定同一個值
      • 給冗長或難讀的 function name 指定成一個好讀的別稱吧 !

那我們就開始囉

「工欲善其事,必先利其器」,而我們選定的框架是 Django,它是用 Python 寫的,我們在這 30 天也必須跟 Python 搞好關係,Python 是著名的好寫好上手,它不像 Java 一樣有很嚴格的型態宣告,大大地加快編寫程式碼的速度,當然有好就有壞的一面,這就是程式語言之間的戰爭了 XD

我們這邊將專注在熟悉 Python 的 語法,關於安裝、版本選擇、第一支程式可以參考以下文章:

版本選擇 & 安裝

  1. Python有許多版本,除非你有特殊需求,不然一律選擇 Python 3.x 的穩定版,有可以參考簡體文章 是选择学习 Python2 还是 Python 3?,內有分析各版的差異性。
  2. Windows 用戶可以參考 (2018 11 月的文章) 在Windows底下最適當安裝Python環境的方法,這位邦友已經先幫大家踩過雷了,請服用。
  3. Mac 用戶可以參考 (2015撰 2019更新) 在 Mac 上用 pyenv 輕鬆安裝 Python3 (可直接支援安裝多種版本),這位是用 terminal 中 brew 套件來安裝的,適合熟悉 terminal 的捧油們。
  4. 如果以上兩種都覺得太麻煩或看不懂,還可以參考 (2017 10月) 給自學者的Python教學(0) : 如何安裝Python(Mac/Windows),其中包含了 Windows 與 Mac 的安裝方法,而 Mac 是選用 pkg 安裝檔來安裝 Python,適合喜歡無腦安裝的捧油們。
  5. 至於 Linux 用戶,我相信你們都選擇用 Linux 了,應該有能力自己解決 XD

第一支程式 (Hello World)

Python 的開發方式有很多種,可以在 cmd 直接 > python、也可以在文字編輯器寫好再到 cmd 用 > python helloworld.py、也可以用 Jupyter Notebook、也可以用 IDE,總之就看每個人喜好的方式,RS 建議可以從 IDE 切入,在我們對一個程式語言不熟悉的時候,有時候 IDE 可以給我們一些錯誤提醒或智慧補齊程式碼等功能,可以參考 Python IDE and Python HelloWorld Program

基礎語法們

注意,雖然很基礎,但卻是寫出高品質程式碼,所不可忽略的部分,尤其是已經有點 coding 經驗的人們,學習另一個程式語言需要 避免傲氣,因為每個程式語言的特性都不一樣,可能兩種程式語言同樣都有 int 整數,可是其代表的值域可能不同,舉例來說,在極值的情況下,可能你的程式碼就出錯了,這時候可怪不了別人,總之,千萬不可因為你好像懂了,就自動跳過這個階段,怎麼判斷你懂了沒,一個簡單的判斷方式就是:「你能夠不看資料就回答出 python 有幾種資料型別,並且講出每個型別的值域範圍。」

還有另一個重點,就是 你必須自己執行你自己寫的程式碼,參考我的程式碼、修改參數、按下執行、檢查輸出值是不是和自己想像的相同,跟看 RS 寫的輸出結果,所帶來的感受度是完全不一樣的,透過修改參數,驗證自己的觀念是否正確,會帶給你無限大的自信。以上講的,都是 RS 本人痛過的經驗談。

  1. 變數 (Variables) & 資料型別 (Data Type)

    • 基本型別: Python 是隱式宣告(宣告變數時,不需要表明它的型別),所以你更需要清楚瞭解 !

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      # ####################################################################
      # Boolean(布林/二元),值域範圍是 0(False) 和 1(True),注意: 是大寫
      # ####################################################################
      this_is_boolean = True

      # ####################################################################
      # String(字串)
      # ####################################################################
      this_is_string = "字串可以用 雙引號 所框起來"
      another_string = '也可以用 單引號 框起來,這兩種都是字串'
      more_specific_about_string = '''如果你的字太多,
      還可以用多行的方式呈現,
      只要三個單引號或三個雙引號就可以了。'''
      more_info = """
      用單、雙引號交錯的好處,
      就是你不需要使用跳脫字元(escape char,反斜線(\)),
      你可以在裡面大膽的用'單引號'
      有些情況還有跳脫你的跳脫,~~根本就像在玩風聲,我識破你的識破XD~~ (誤
      e.g.
      1. print("我想t吃飯") # 輸出為: 我想t吃飯
      2. print("我想\t吃飯") # 輸出為: 我想 吃飯
      3. print("我想\\t吃飯") # 輸出為: 我想\t吃飯
      """

      # ####################################################################
      # Integer(整數),值域範圍在 Python 2 可以用 sys.maxint 來檢查最大值,
      # 而最小值自然就是 -sys.maxint-1,但這件事情在 Python 3 就不一樣了,
      # int 是沒有值域限制的,說是這樣說,但還是要看你的系統的位元數,
      # 可以用 sys.maxsize 來檢查,所以值域是在 -sys.maxsize-1 ~ sys.maxsize。
      #
      # 但 RS 必須老實說,我自己也沒有搞得很懂 Python 3 的 int 範圍,
      # 我的電腦是 64-bit,"理論上最大值"應該要是 9223372036854775807,
      # 我卻可以將 int 設超過這個"最大值",如果大家有想法可以提出來救一下 RS。
      #
      # 值得注意的是,在 Java 與 Kotlin 中,有區分出 Long(長整數),
      # Python 2 也還有 Long,而 Python 3 就只有 int。
      # ####################################################################
      this_is_int = 9487

      import sys # 必須先引入 sys 套件,才可以使用
      max_int = sys.maxsize * 10
      print(max_int) # 輸出為 92233720368547758070
      print(type(max_int)) # 輸出為 <class 'int'>

      # ####################################################################
      # Float(浮點數),值域範圍為 sys.float_info.min ~ sys.float_info.max
      # 值得注意的是,在 Java 與 Kotlin 中,
      # 有區分 float 與 double 這兩種精度不同的浮點數,
      # 而 Python 只有 float 這一種浮點數。
      # ####################################################################
      this_is_float = 3.14159

      min_float = sys.float_info.min
      max_float = sys.float_info.max
      print("float max: ", sys.float_info.max, ", min: ", sys.float_info.min)
      # 輸出為 float max: 1.7976931348623157e+308, min: 2.2250738585072014e-308

      # ####################################################################
      # Complex(複數),也就是實數和虛數的結合,在極座標等運算較常用到,這裡先不討論
      # 值得注意的是,這邊 Python 使用的是 j,而在數學上慣用的是 i。
      # ####################################################################
      this_is_complex = 1 + 2j

      基礎型別小結

      • Boolean 要記得大寫 (True, False)
      • Integer 理論值無上下限
      • Python 3 沒有 Long, Double 型別
    • 關於型別,你需要瞭解更多

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64
      65
      66
      67
      68
      69
      70
      # ####################################################################
      # 怎麼確認一個變數的型別?
      # 假設我們用一個 Float 乘上一個 Int,那麼會變成什麼型別呢?
      # ####################################################################
      this_is_float = 0.9527
      this_is_int = 5278
      secret_variable = this_is_float * this_is_int
      print(type(secret_variable)) # 輸出為 <class 'float'>

      # ####################################################################
      # 各種進位該怎麼表示? 假設以十進位的 10,轉換成各種進位呢?
      # 十進位(Decimal)/ 二進位(Binary)/ 八進位(Octal)/ 十六進位(Hexadecimal)
      # ####################################################################
      decimal = 10
      binary = bin(decimal)
      octal = oct(decimal)
      hexa = hex(decimal)

      print("num: ", decimal, ", bin: ", binary, ", octal: ", octal, ", hex: ", hexa)
      # 輸出為 num: 10, bin: 0b1010 , octal: 0o12 , hex: 0xa

      # ####################################################################
      # 如何在各種基本型別中遊走? 如何轉換型別?
      # ####################################################################

      # 為了排版漂亮,各位就原諒 RS 不打 print 了齁

      # int/float/boolean to string
      int_to_string = str(100) # 輸出為 100
      float_to_string = str(0.2266) # 輸出為 0.2266
      boolean_to_string = str(True) # 輸出為 True
      complex_to_string = str(2+3j) # 輸出為 (2+3j)

      # string to int/float/boolean
      string_to_int = int("100") # 輸出為 100
      string_to_int_base8 = int("14", 8) # 輸出為 12
      string_to_float = float("0.618") # 輸出為 0.618
      string_to_boolean = bool("True") # 輸出為 True
      string_to_boolean = bool("False") # 輸出為 True
      # 有沒有覺得哪裡奇怪? 為什麼 bool("False") 會輸出 True?
      # 事實上,bool() 內只要有值,就會輸出 True
      # print(bool()) 或 print(bool("")) 就會輸出 False
      # 如果你沒有自己去替換這些參數
      # 或許發現這件事的時候,就是你的程式碼在系統出錯的時候了,然後被老闆釘在牆上
      string_to_complex = complex("2-3j") # 輸出為 (2-3j)
      string_to_complex = complex(2, 3) # 輸出為 (2+3j)

      # ####################################################################
      # 如何知道各個型別占多少記憶體?
      # 用 sys.getsizeof 來檢查看看你的記憶體配置吧
      # ####################################################################

      # 浮點數測試
      print(sys.getsizeof(3.14159)) # 輸出為 24
      print(sys.getsizeof(3.14e+100)) # 輸出為 24
      print(sys.getsizeof(3.14e-100)) # 輸出為 24

      # 整數測試
      print(sys.getsizeof(100)) # 輸出為 28
      print(sys.getsizeof(sys.maxsize)) # 輸出為 36
      print(sys.getsizeof(int(1e+308))) # 輸出為 164

      # 自創型別測試
      class MyCustomObject:
      def __init__(self, var1, var2, var3):
      self.var1 = var1
      self.arbitrary = var2
      self.name = var3

      print(sys.getsizeof(MyCustomObject(1, 2, 3))) # 輸出為 48
    • 區域變數 (Local variables) & 全域變數 (Global variables) & 作用範圍(Scope)

      Python 的 Scope 和 Java 有很大的不同,Java 除了 import 之外,所有變數、所有運算都要在 class 內宣告和執行,而 Python 雖然彈性,卻可能讓初學者替自己埋下許多坑。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      # 我們的全域變數,藉由觀察 global_var 在各階段的值,
      # 可以看出 Variables 與 Scope 的互動關係
      global_var = 10

      # 注意: 在 local scope 宣告的變數名稱,可以跟 global variable 同名,
      # 在邏輯上容易出錯,應盡量避免同名的用法

      def first_local_scope():
      local_var = 20 # 此為 local variable,
      # 與 second_local_scope() 的 local_var,
      # 雖然同名,但兩個是完全不相關的變數

      global_var = 30 # 此為 local variable,與 global variable 的同名
      print("global_var: ", global_var, ", local_var: ", local_var)

      def second_local_scope():
      local_var = 40 # 此為 local variable,與 first_local_scope 無相關

      # 在這個 local scope 中,雖然可以讀取到 global_var,
      # 但無法修改 global_var 的值,如真的需要修改,需加入 global 關鍵字
      print("global_var: ", global_var, ", local_var: ", local_var)

      def third_local_scope():
      global global_var
      global_var = 50 # 因為有先加入 global 關鍵字,
      # 所以這次修改的是真正的全域變數
      print("global_var: ", global_var)

      # 真正的執行順序
      print("global_var: ", global_var) # 輸出為 10,全域變數的初始值
      first_local_scope() # 輸出為 30, 20,此處輸出的是假的全域變數,事實上是區域變數
      second_local_scope() # 輸出為 10, 40,存取得到全域變數,可是無法修改
      third_local_scope() # 輸出為 50,此處修改的是真正的全域變數
      print("global_var: ", global_var) # 輸出為 50,被 third_local_scope() 修改為 50

      關於更詳細的 Scope 測試,可以參考 (2017 5月) 有點複雜的 Python Scope,推薦從 Java 轉 Python 的人們研究。

      區域變數、全域變數、作用範圍小結

      • local scope 和 global scope 的變數可以取一樣的變數名稱,但不要找自己麻煩,盡量用變數名稱區分開來
      • 各個 local scopes 間的變數,不能互相修改
      • local scope 可以取用 global scope 的變數,但需要加入 global 的關鍵字
      • 盡量避免在 local scope 直接取用 global scope 變數,改用參數傳入與 return 的方式處理
  2. 邏輯控制 (Control Statements)

    • if else & for loop

      讓我們一起來用任性的鬼抓人小遊戲感受一下迴圈以及邏輯判斷:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      print("鬼抓人開始!")

      # 值得注意的點是,counter 的值是從 0 到 11,不會到 12
      for counter in range(0,12):
      if counter == 10:
      print("數到十囉,我要去抓人囉。")
      elif counter > 10:
      print("原來時間已經到了喔,我竟然還在發呆沒去抓人。")
      else: # 除了等於、大於,剩下的自然就是小於的情況囉
      print("現在數到 ", counter)

      print("遊戲結束")

      輸出結果

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      鬼抓人開始!
      現在數到 0
      現在數到 1
      現在數到 2
      現在數到 3
      現在數到 4
      現在數到 5
      現在數到 6
      現在數到 7
      現在數到 8
      現在數到 9
      數到十囉,我要去抓人囉。
      原來時間已經到了喔,我竟然還在發呆沒去抓人。
      算了,我不玩了。

      值得注意的地方是,沒有 ++-- 來做變數遞增遞減,到現在還是很不習慣QQ,至於 Python 為什麼沒有,可以參考 Python integer incrementing with ++

  3. 好用小技巧

    • 給多個變數單行指定同一個值

      1
      2
      a = b = c = 10
      print("a = ", a, ", b = ", b, ", c = ", c) # 輸出為 10, 10, 10
    • 給冗長或難讀的 function name 指定成一個好讀的別稱吧 !

      1
      2
      3
      4
      5
      6
      def just_print(var1):
      print(var1)

      custom_name = just_print # 將原本可能很長或可讀性不好的 function,
      # 指定成一個自己好讀的別稱
      custom_name(10) # 輸出為 10

單日心得總結

先跟各位說抱歉,今天的量已經讓文章長到不好閱讀了,畢竟要在一篇的篇幅,把這麼多東西塞進去真的很不容易,很想把基本但卻占篇幅的講完,但這是文章,不是出書QQ。

從各標題的篇幅就可以抓到 RS 覺得的重點在哪裡,光是變數就占了一半,因為基礎,才要更瞭解,希望大家可以耐住性子,真的花點時間,自己做過一次這些觀念驗證,找到自己的知識盲區那瞬間會很興奮哈哈。

我是 RS,這是我的 不做怎麼知道系列 文章,我們 明天見。


  • 喜歡我的文章嗎? 趕快來看看我都發了什麼文章吧:我的文章目錄
  • 歡迎閱讀我的上一篇: [不做怎麼知道系列之Android開發者的30天後端養成故事 Day1] - 起源 #我是誰 #為什麼 #目標
  • 歡迎閱讀我的下一篇: [不做怎麼知道系列之Android開發者的30天後端養成故事 Day3] - 讓熱情燒一會兒 #別間斷很重要 #Python資料結構
  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.
  • Copyrights © 2021-2022 Sam Ho
  • Visitors: | Views:

請我喝杯咖啡吧~

支付宝
微信