Sam Yang
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights
    • Engagement control
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Versions and GitHub Sync Note Insights Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       owned this note    owned this note      
    Published Linked with GitHub
    Subscribed
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    Subscribe
    --- title: Python 入門教學-程式結構 tags: python_beginner --- # 程式結構 ## 註解與換行 * 註解 ```python= # 單行註解 ''' 這 不 是 註 解 但運作的方式像註解 ''' ``` * 程式碼換行 ```python= >>> alphabet= 'abcdefg' + \ ... 'hijklmn' + \ ... 'opqrstuv' + \ ... 'wxyzw' ``` ## 判斷式 * if, elif, else ```python= >>> grade = 65 >>> level = '' >>> if grade >= 80: >>> level = 'A' >>> elif grade >= 70: >>> level = 'B' >>> elif grade >= 60: >>> level = 'C' >>> else: >>> level = 'F' ``` * 比較運算子 * == 相等 * != 不相等 * < 小於 * <= 小於等於 * \> 大於 * \>= 大於等於 * in 是否為...的其中之一 ```python= >>> classA = ['Sam', 'Neko', 'Chia'] >>> if 'Neko' in classA: ... print('Neko is in class A') ... else: ... print('Neko is not in class A') ``` * 布林運算子 * and * or * not ```python= >>> if 'Sam' in classA and not 'Sean' in classA: ... print('Sam is in class A, and Sean is not.') ... else: ... print('Sam is not in classA, or Sean is in class A.') ``` * What is False? * False * None * 0 * 0.0 * '' * [] * () * {} * set() * 其他都是True ## 迴圈 * while ```python= >>> count = 1 >>> while count <= 5: ... print(count) ... count += 1 ``` * for * iterable: 可迭代,list, dictionary, set, tuple, string... 檢查是否為iterable ```python= >>> from collections import Iterable >>> isinstance((), Iterable) True >>> isinstance([], Iterable) True >>> isinstance({}, Iterable) True >>> isinstance('abc', Iterable) True >>> isinstance(100, Iterable) False ``` > 參考: [迭代器 (Iterator)](http://wiki.jikexueyuan.com/project/explore-python/Advanced-Features/iterator.html) * list ```python= >>> # while寫法 >>> cats = ['Vincent', 'Peter', 'Fluffy'] >>> current = 0 >>> while current < len(cats): ... print(cats[current]) ... current += 1 >>> # for寫法 >>> for cat in cats: ... print(cat) ``` * string ```python= >>> # 也可以印出字串中的每個字 >>> name = 'Jimmy Page' >>> for letter in name: ... print(letter) ``` * dictionary 會回傳key ```python= for food in foods: print(food) dict1 = { 'classA':['Sam', 'John', 'David'], 'classB':['Jack', 'Peter', 'Tom'], 'classC':['Sean', 'Victor'] } for names in dict1.values(): for name in names: print(name) ``` 使用values()回傳值 ```python= >>> for ingredient in foods.values(): ... print(ingredient) ``` 使用items()回傳key, value的tuple ```python= >>> for item in foods.items(): ... print(item) ``` 將tuple值指派給變數 ```python= for food, ingredient in foods.items(): print('Food:', food) print('Ingredient:', ingredient) print('---------------') dict1 = { 'classA':['Sam', 'John', 'David'], 'classB':['Jack', 'Peter', 'Tom'], 'classC':['Sean', 'Victor'] } for myClass, names in dict1.items(): print("myClass:", myClass) print("names:", names) print("--------") # 再把每個人給印出來呢? ``` * break break可用來中斷迴圈 * while ```python= >>> count = 0 >>> while True: ... if count >= 5: ... break ... print(count) ... count += 1 ``` * for ```python= >>> for food in foods: ... if food == 'Chocolate Cake': ... break ... print(food) ``` * continue continue可以跳過這次迴圈 ```python= >>> count = 0 >>> while count < 10: ... if count % 2 == 0: ... continue ... print(count) ``` * while-else, for-else 假設沒有break掉,就會執行else裡面的東西 ```python= >>> for food in foods: ... if food == 'Spaghetti': ... break ... print(food) ... else: ... print('Spaghetti not found.') ``` * zip() 用zip()可以同時迭代多個序列 ```python= days = ['Monday', 'Tuesday', 'Wednesday'] courses = ['Math', 'English', 'Music'] classrooms = ['A', 'B', 'C', 'D'] for day, course, classroom in zip(days, courses, classrooms): print("{} : Take a {} course, in the classroom {}".format(day, course, classroom)) ``` * range() range()會回傳可迭代的數列,語法為`range(start, end, step)` ```python= print(list(range(0, 5))) for i in range(0, 5): print(i) print(list(range(4, 10, 2))) for i in range(4, 10, 2): print(i) ``` :::warning 我們也可以定義自己的iterator物件,例如這個Fibonocci數列的iterator ```python= from collections import Iterator class Fib(object): def __init__(self): self.a, self.b = 0, 1 def __iter__(self): return self def __next__(self): self.a, self.b = self.b, self.a + self.b return self.a def main(): fib = Fib() print('isinstance(fib, Iterator): ', isinstance(fib, Iterator)) for i in fib: if i > 10: break print(i) main() ``` ::: ## 生成式 * 串列生成式 一開始我們建立串列的方式 ```python= num_list = [] num_list.append(1) num_list.append(2) num_list.append(3) num_list.append(4) num_list.append(5) print(num_list) ``` 使用for來建立串列 ```python= num_list = [] for num in range(1, 6): num_list.append(num) print(num_list) ``` 使用生成式建立串列 `[運算式 for 項目 in 可迭代的東西]` ```python= num_list = [num for num in range(1, 6)] print(num_list) ``` `[運算式 for 項目 in 可迭代的東西 if 條件式]` ```python= num_list = [num for num in range(1, 10) if num % 2 == 0] print(num_list) ``` 也可以用生成式來建立雙重迴圈才能建立的東西 ```python= # 使用雙重迴圈建立3*3矩陣 cells = [] for row in range(1, 4): for col in range(1, 4): cells.append([row, col]) print(cells) # 使用生成式建立3*3矩陣 cells = [[row, col] for row in range(1, 4) for col in range(1, 4)] print(cells) ``` Python要建立二維串列要使用生成式 ```python= # 不帶初始值 two_dim_list = [[] for i in range(3)] # 帶初始值 two_dim_list = [[0] for i in range(3)] # 決定內部串列的項目數量 two_dim_list = [[0 for j in range(3)] for i in range(3)] ``` :::info 既然講到二維串列,就一定要提一下深複製根淺複製 * **淺複製** 前面我們提到,python複製串列不能用等於,要使用copy()。我們來複製一個二維串列試試看 ```python= two_dim_list = [[0 for j in range(3)] for i in range(3)] copy_list = two_dim_list.copy() ``` 乍看之下沒甚麼問題,但是: ```python= two_dim_list[0][0] = 2 print(two_dim_list) print(copy_list) ``` 神奇的事情發生了,我們只改了原本的串列中的第一個串列的第一個元素,但複製的那個也跟著改了。 這是因為copy()在複製的時候,python只是將最外層的串列指派新的一個記憶體空間,但是裡面的元素其實是引用到同一個地方的,看看下面的例子就知道了 ```python= print(two_dim_list is copy_list) print(two_dim_list[0] is copy_list[0]) ``` 當改動串列中的串列時,因為是同一個串列,所以複製的那個串列也會變動 * **深複製** 要解決這個問題就要使用deepcopy(),深複製的函式 我們使用help()來看看有沒有這個東西 ```python= >>> help(list()) ``` 沒有看到deepcopy(),這代表list本身沒有內建深複製的函式。 要使用的話就要從別的地方引入進來,方法如下,之後會再細講 ```python= from copy import deepcopy ``` 我們做一樣的事情觀察看看 ```python= from copy import deepcopy two_dim_list = [[0 for j in range(3)] for i in range(3)] copy_list = deepcopy(two_dim_list) two_dim_list[0][0] = 2 print(two_dim_list) print(copy_list) print(two_dim_list is copy_list) print(two_dim_list[0] is copy_list[0]) ``` ::: ## 函式 * 什麼是函式 假設有一個你很常使用的功能,你不想要每次用這個功能時都重新打一遍這個功能,那就可以把這個功能包成一個函式。函式的結構如下 * 參數(Input) * 動作 * 回傳(Output) ```python= # 無回傳函式 def print_two_num(num1, num2): print(num1, num2) # 有回傳的函式 def connect_two_num(num1, num2): return str(num1) + str(num2) # 呼叫函式 print_two_num(1, 2) # 函式沒有回傳值,所以直接呼叫即可 connected = connect_two_num(1, 2) # 函式有回傳值,所以要宣告一個變數來把值存起來 ``` 函數不只可以回傳字串,也可以回傳list, tuple, set, dictionary等等,所以如果你覺得創建一個二微串列很麻煩,你也可以做一個函式來創建二維串列 ```python= def create_2d_list(num1, num2): return [[0 for j in range(num2)] for i in range(num1)] list_2d = create_2d_list(3, 5) ``` 為你的函式加上說明,讓別人(還有你自己)知道這個函式的功能 ```python= def create_2d_list(num1, num2): ''' Create and return an 2 dimension list. First number is height, and second number is width. ''' return [[0 for j in range(num2)] for i in range(num1)] # 查看說明 help(create_2d_list) # 只查看我們自己寫的文件字串 print(create_2d_list.__doc__) # __什麼什麼__的這種東西以後我們再介紹 ``` * 命名空間(namespace)與範圍 為了不要互相影響,只會在自己所在的命名空間中作用,不同命名空間的變數就算名稱相同也不會互相影響。命名空間的範圍分為兩種: * global(全域): 在函式外面命名的變數都屬於全域的命名空間,不論在這個程式中的哪個地方都可以取用,我們把這些變數稱為全域變數(global variable) * local(區域): 在函式內部定義的變數只能在這個函式中使用,我們稱作區域變數(local variable) 使用`locals()`以及`globals()`這兩個函式可以查看目前有哪些變數是local的,那些是global的 ```python= global_name = "Jack" print("global:", globals()) ``` ```python= def i_am_local(): local_name = "Sam" print("locals:", locals()) ``` 在函式當中可以直接取得全域變數的值,注意下面的例子,函數並沒有接收到任何的輸入,而是直接使用全域變數 ```python= global_name = "Jack" def print_name(): print(global_name) ``` 但是如果要在函式內對全域變數進行更改,就必須加上變數前面加上global ```python= # 這樣等同於在區域變數當中再開一個同名變數,但其實外面的變數根本沒有改變 global_name = "Jack" def error_global(): global_name = "HaHaHa" # 在函式中宣告一個新的global_name print(global_name) print(global_name) # 外面的global_name並沒有改變 #這樣才是對的,至始至終都是使用全域變數 global_name = "Jack" def correct_global(): global global_name global_name = "HaHaHa" print(global_name) print(global_name) ``` * 參數 Python傳遞參數的方式有很多種 * 位置參數: 依照位置來指定參數,這個位置放甚麼變數,函數就接收甚麼 ```python= def print_num(first, second, third): print(first, second, third) print_num(1, 2, 3) ``` * 關鍵字參數: 依照名字來指定這個變數要傳給哪個參數 ```python= def print_num(first, second, third): print(first, second, third) print_num(second=2, third=3, first=1) ``` * 預設參數: 參數可以給預設值,如果呼叫時沒有傳這個參數,就會使用他的預設值 ```python= def diner(appetizer, main_course, dessert='pudding'): print("Appetizer:", appetizer) print("Main course:", main_course) print("Dessert:", dessert) diner("soup", "chicken") diner("soup", "chicken", "chocolate icecream") ``` :::info python不支援多載(overloading),但是透過預設參數,可以達到跟多載一樣的效果。 去搜尋一下多載什麼意思,關鍵字: * function overloading * 函式多載 * 函式重載 ::: * 用\*收集位置參數: 假設你不能確認總共有多少參數會傳進來,也可以使用\*來定義你的函數,記得要寫在最後面 ```python= def print_num(first, second, *rest): print("first:", first) print("second:", second) print("All the rest:", rest) print_num(1, 2, 3, 4, 5, 6, 7, 8) ``` \*rest會接收剩下的參數,用tuple存起來 :::info 使用慣例上,會用args來當作這個參數的名稱 ```python= def print_num(first, second, *args): print("first:", first) print("second:" second) print("All the rest:", rest) ``` ::: * 用\*\*收集關鍵字參數: \*\*可以用來收集不確定數量的關鍵字參數 ```python= def print_foods(**foods): print(foods) print_foods(appetizer='salad', main_course='steak', dessert='pudding') ``` python會把這些值用dictionary存起來 :::info 慣例上使用\*\*kwargs來命名 ```python= def print_foods(**kwargs): print(kwargs) ``` ::: * 把函數當成參數來傳遞 :::warning 這個特性只有在那些號稱"everything is object"的程式語言當中才有,例如Python以及JavaScript。 其他語言,像是C/C++、JAVA是沒有的 ::: 在python當中,所有東西都是物件(everything is object),函數也是。你可以把函數指派給變數,也可以回傳一個函數,當然也可以把函數當成參數來傳遞 ```python= def add_args(*args): result = 0 for n in args: result += n return result def mul_args(*args): result = 1 for n in args: result *= n return result def run_something_with_args(func, *args): return func(*args) add_this = run_something_with_args(add_args, 1, 2, 3, 4, 5) mul_this = run_something_with_args(mul_args, 1, 2, 3, 4, 5) ``` :::info 注意,我們前面在呼叫函數的時候,都有加上括號,例如`add_num(1, 2)`,但仔細看,在定義run_something_with_args時、還有呼叫它的時候,我們傳遞進去的只有函數的名稱,而沒有加上括號。 函數加上括號代表的是呼叫這個函數,也就是使用這個函數。 而沒有上括號,代表我們目前是把函數視為一個名為function的物件。既然是物件,那就可以拿來傳來傳去當然沒問題。 既然是物件,那當然可以用`type(add_args)`來看看add_args的type是甚麼東西。也可以用`id(add_args)`來看看這個函式在什麼記憶體位置。 這沒那麼好懂,想一下 ::: * lambda(): 匿名函式 假設要寫的函式很短,也可以用lambda來定義一個函式 語法: `lambda arg1, arg2: expression` ```python # 原本的函式 def add(a, b): return a + b result = add(2, 5) print(result) # 使用lambda add = lambda a, b: a + b result = add(2, 3) print(result) ``` ## 作業1 - 終極密碼 * 要求 1. 請於程式第一行輸出電腦亂數出來的數字,範圍1~100,亂數產生的程式碼如下 ```python= import random # 引入random套件,來產生亂數 target = random.randint(1, 100) # randint(a, b),隨機產生整數,範圍為 a <= x <= b print(target) ``` 2. 每次輸入前,輸出一個提示,告訴使用者目前可能範圍為多少到多少之間 3. 如果使用者輸入的數字大於目標數字,則輸出"太大囉",反之輸出"太小囉" 4. 使用者答對了之後要輸出"恭喜答對",並且輸出使用者總共猜了幾次 * 範例 ![](https://i.imgur.com/U6xQbaX.png) ## 作業2 - 請利用函數設計一個Text Adventure RPG Text Adventure RPG(Role Play Game)文字冒險角色扮演遊戲,是一種很古老的遊戲。在電腦還只有黑底白字的CLI時代,人們玩遊戲的方式只能透過文字去想像遊戲的場景,並透過各種設定好的選項來進行動作。如果你完全沒概念的話,請參考"勇者鬥阿德"。 請你利用不同的函式代表各個關卡,角色需要通過這些關卡才能通關遊戲,請提供至少兩種結局(good end, dead end)。內容自行設計,規模可大可小,重點是要熟悉函數的使用。 使用者輸入時請以`> `作為提示符號,以區分使用者輸入與遊戲輸出文字,例如: ```python= print("一隻龐大的甜甜圈正齜牙裂嘴的朝你大吼(你覺得這很可笑),請問你要逃跑還是攻擊?") while True: move = input("> ") if move == "逃跑": print("雖然不知為何要逃離這可笑的東西,但你還是逃跑了") break; elif move == "攻擊": print("你看起來想餓了十天一樣,朝甜甜圈咬去") print("甜甜圈受到激烈的攻擊,倒下") break; else: print("輸入錯誤,請重新輸入") ``` 這邊先幫你定義好開始的函數,以及死亡的函數,這只是預設內容,可自行改掉。 ```python= def in_the_room(): # 這個關卡你要設計的內容 def dead(why): print("你死於「%s」" % why) def start(): print("某天清晨,你帶著迷迷糊糊的眼神從床上起來。") print("發現一塊餅乾正衝著你微微一笑。") print("請問你決定繼續睡覺還是起床?") move = input("> ") while true: if move == "繼續睡覺": print("在你睡覺的時候,餅乾大軍來襲,合力把你壓死了。") dead("被餅乾壓死") elif move == "起床": in_the_room() # 呼叫第一個關卡 else: print("輸入錯誤,請重新輸入") start() # 記得呼叫你的start函數,以開始遊戲 ```

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully