---
# System prepended metadata

title: Day 6 - Beginner - PythonFunctions & Karel
tags: [python, 100 Days Of Code, Udemy]

---

Udemy課程：[100 Days Of Code（Dr. Angela Yu）](https://www.udemy.com/course/100-days-of-code/)
# Day 6 - Beginner - PythonFunctions & Karel
###### tags: `python` `Udemy` `100 Days Of Code`
2021.01.30（Sat.）～2021.02.02（Tue.）
## ● 前言 / 心得
進入到第6天了，這次的課程真的相當不輕鬆，尤其對於robot往左往右後會往哪個方向，常常分不清楚，所以這堂Day 6分了兩次才把他看完。

這次課程全部都是在Reeborg’s World完成，我覺得整體來說看似簡單，可是如果基礎沒打好，就很容易胡亂做一通，然後搞不清楚原理。

而關於新的內容，這堂課有提到縮排的問題，還放了Silicon Valley的片段，正好前陣子開始追XD所以看完覺得很有趣～另外是while loops也是這堂新的觀念，也有說明到何時適合使用for還是while會比較好，剛好上週在上另外一堂Udemy的Web developer課程也才剛提到，所以在此處又再次加深了印象！

雖然整個過程其實滿燒腦滿累的，但又很期待每次的上課！也期待看著自己慢慢的在這些練習實作中成長！

## ● 上課筆記

## 其他
> [Function](https://docs.python.org/3/library/functions.html)：python的各種funtions

## 0.code
[day-6-start](https://repl.it/@tina0915tw/day-6-start#main.py)
[Hurdle 1](https://reeborg.ca/reeborg.html?lang=en&mode=python&menu=worlds%2Fmenus%2Freeborg_intro_en.json&name=Hurdle%201&url=worlds%2Ftutorial_en%2Fhurdle1.json)：答案見底下上課筆記第3點
[Hurdle 2](https://reeborg.ca/reeborg.html?lang=en&mode=python&menu=worlds%2Fmenus%2Freeborg_intro_en.json&name=Hurdle%202&url=worlds%2Ftutorial_en%2Fhurdle2.json)：答案見底下上課筆記第6點
[Hurdle 3](https://reeborg.ca/reeborg.html?lang=en&mode=python&menu=worlds%2Fmenus%2Freeborg_intro_en.json&name=Hurdle%203&url=worlds%2Ftutorial_en%2Fhurdle3.json)：答案見底下上課筆記第8點
[Hurdle 4](https://reeborg.ca/reeborg.html?lang=en&mode=python&menu=worlds%2Fmenus%2Freeborg_intro_en.json&name=Hurdle%204&url=worlds%2Ftutorial_en%2Fhurdle4.json)：答案見底下上課筆記第9點
[Final Project](https://reeborg.ca/reeborg.html?lang=en&mode=python&menu=worlds%2Fmenus%2Freeborg_intro_en.json&name=Maze&url=worlds%2Ftutorial_en%2Fmaze1.json)：答案見底下上課筆記第10點

## 1.自訂function
第一步要先從關鍵字「def」開始，然後在def後面自己定義一個function的名字後，要再加上括號（parentheses）括號裡面可以輸入東西，沒有則可以空著，最後再加上冒號（colon），而冒號底下就是那個function要做的事情。

以下方為例，則是定義了一個名為my_function的function，而這個function能做的事情就是分別print出Hello跟Bye（會Line by line一行行按順序去執行）。
```python=
#Defining functions
def my_funtion():
    print("Hello")
    print("Bye")
```
接著自訂好function，想要執行他只要如下步驟即可：
```python=
#Calling functions
my_funtion()
```
他就會去找叫做my_funtion()這個function執行。

## 2.Reeborg's World
網址：[Reeborg's World](https://reeborg.ca/reeborg.html?lang=en&mode=python&menu=worlds%2Fmenus%2Freeborg_intro_en.json&name=Alone&url=worlds%2Ftutorial_en%2Falone.json)

這是6-57的小小練習，可以透過網頁上方的Reeborg's keyboard來看他有甚麼function，你想要執行的。

例如說他有move()，用來往前走一格；turn_lefe()，很明顯地往左轉。不過會發現他並沒有turn right或turn around，此時我們可以自己定義新function，如下：
```python=
def turn_around():
    turn_left()
    turn_left()
```
如此一來，每次想要turn around時，只要Call出那個function，而不必每次都要打兩次turn_left()，同理可知想要turn right的方法。
```python=
def turn_right():
    turn_left()
    turn_left()
    turn_left()
```

## 3.[Hurdle 1](https://reeborg.ca/reeborg.html?lang=en&mode=python&menu=worlds%2Fmenus%2Freeborg_intro_en.json&name=Hurdle%201&url=worlds%2Ftutorial_en%2Fhurdle1.json)的答案

* 我的寫法：
```python=
def turn_right():
    turn_left()
    turn_left()
    turn_left()

def hurdle():
    move()
    turn_left()
    move()
    turn_right()
    move()
    turn_right()
    move()
    turn_left()
     
hurdle()
hurdle()
hurdle()
hurdle()
hurdle()
hurdle()
```

* 老師的寫法：
用了for loop來寫最後的部分
```python=
def turn_right():
    turn_left()
    turn_left()
    turn_left()

def hurdle():
    move()
    turn_left()
    move()
    turn_right()
    move()
    turn_right()
    move()
    turn_left()

#range(6)表示從0開始，但不包含6，也就是0,1,2,3,4,5，所以事實上確實執行了6次
for step in range(6):
    hurdle()
```

## 4.Indentation（縮排）
先來看個silicon valley影集片段（這幾天剛入坑XD）

{%youtube SsoOG6ZeyUI %}

那課堂中老師有放上一個很有趣的折線圖：

![](https://i.imgur.com/hwuEaWH.jpg)

薪資越高的人通常都用spaces！

那兩者的差別其實就差在說，按一次「tab」等於要按四次「space」，但老師也有提到其實現今大多數的code editor都可以調整，讓按一次「space」的空格跟一次「tab」一樣多。

如果想知道更詳細關於Indentation的內容，可以點以下：
網址：[Style Guide for Python Code](https://www.python.org/dev/peps/pep-0008/#tabs-or-spaces)
（下方contents找indentation）

## 5.While loops
while的語法：
```python=
while something_is_true :
    Do this
    Then do this
    Then do this
```

這裡同樣以「3.[Hurdle 1](https://reeborg.ca/reeborg.html?lang=en&mode=python&menu=worlds%2Fmenus%2Freeborg_intro_en.json&name=Hurdle%201&url=worlds%2Ftutorial_en%2Fhurdle1.json)的答案」的題目一樣，但改用while來寫。
```python=
def turn_right():
    turn_left()
    turn_left()
    turn_left()

def hurdle():
    move()
    turn_left()
    move()
    turn_right()
    move()
    turn_right()
    move()
    turn_left()

number_of_hurdles = 6
while number_of_hurdles > 0:
    hurdle()
    number_of_hurdles -= 1
```
## 6.[Hurdle 2](https://reeborg.ca/reeborg.html?lang=en&mode=python&menu=worlds%2Fmenus%2Freeborg_intro_en.json&name=Hurdle%202&url=worlds%2Ftutorial_en%2Fhurdle2.json)的答案
Hurdle 2 的挑戰加深了難度，這次旗子（終點）不再是固定都在最後，而是隨機出現在每個hurdle的後面，共有六種可能性。並且要使用到while loops，另外此處有一可使用的函數at_goal( )，可以偵測robot有沒有在旗子（終點）上。
```python=
def turn_right():
    turn_left()
    turn_left()
    turn_left()

def hurdle():
    move()
    turn_left()
    move()
    turn_right()
    move()
    turn_right()
    move()
    turn_left()
    
while at_goal() != True:
    hurdle()
    
```
最後兩行也可寫成下面這樣：
```python=
while not at_goal():
    hurdle()
```

## 7.何時用for loops、何時用while loops？
當loop的範圍是有限制、有一個明確的range時，那就用for loops。

例如說我要把1~5給印出來，那如此明確的目標，我們可以直接用for loops：
```python=
for i in range(1,6):
    print(i) #1 2 3 4 5
```
那相對地，如果我們不必在意範圍，而且通常可能都會希望執行多次（幾次你也不知道），但就是不停執行直到達到你設定的目標變成False。

所以其實使用while loops也會比較危險，因為for loops你是可以自己設有一個停止點的，而while loops則是要不斷輪迴直到目標變成False，那假如你的目標永遠為真，那將會進入到無限迴圈「Infinite loop」。

例如以下例子：
```python=
while 5 > 3:
    Do this
    Then do this
    Then do this
```
因為5恆大於3，所以此處將不斷在迴圈中，永遠跳不出來。

## 8.[Hurdle 3](https://reeborg.ca/reeborg.html?lang=en&mode=python&menu=worlds%2Fmenus%2Freeborg_intro_en.json&name=Hurdle%203&url=worlds%2Ftutorial_en%2Fhurdle3.json)的答案
Hurdle 3 則又比 Hurdle 2 多了兩個函數：front_is_clear( )、wall_in_front( )，並且過關方法改為隨機的地圖，也就是說無法預測hurdle會出現在甚麼地方，但無倫如何都要讓robot走到旗子（終點）。

* 我的寫法：
```python=
def turn_right():
    turn_left()
    turn_left()
    turn_left()

def hurdle():
    turn_left()
    move()
    turn_right()
    move()
    turn_right()
    move()
    turn_left()
    
while at_goal() != True:
    if front_is_clear() != True:
        hurdle()
    else:
        move()
```

* 老師的寫法：
```python=
def turn_right():
    turn_left()
    turn_left()
    turn_left()

def hurdle():
    turn_left()
    move()
    turn_right()
    move()
    turn_right()
    move()
    turn_left()
    
while not at_goal():
    if wall_in_front():
        hurdle()
    else:
        move()
```
## 9.[Hurdle 4](https://reeborg.ca/reeborg.html?lang=en&mode=python&menu=worlds%2Fmenus%2Freeborg_intro_en.json&name=Hurdle%204&url=worlds%2Ftutorial_en%2Fhurdle4.json)的答案
FINAL HURDLE !
最後的挑戰果然超難的！試做了一次（還花了滿多時間），結果竟然失敗，原本想乾脆放棄直接聽老師解說，但還是決定再給自己一次機會，果然就有做出來了！看到robot自己走到終點那一刻，真的超級感動XD

* 我的寫法：
```python=
def turn_right():
    turn_left()
    turn_left()
    turn_left()
    
def hurdle():
    turn_left()
    while right_is_clear() != True:
        move()
    turn_right()
    move()
    turn_right()
    while wall_in_front() != True:
        move()
    turn_left()
    
while at_goal() != True:
    if front_is_clear() != True:
        hurdle()
    else:
        move()
```

* 老師的寫法：
```python=
def turn_right():
    turn_left()
    turn_left()
    turn_left()

def hurdle():
    turn_left()
    while wall_on_right():
        move()
    turn_right()
    move()
    turn_right()
    while front_is_clear():
        move()
    turn_left()
    
while not at_goal():
    if wall_in_front():
        hurdle()
    else:
        move()
```
從上面兩題看下來，可以發現我超愛用不等於True，但其實這樣真的很容易搞混，不如跟老師一樣，直接讓條件是True就好了。

## 10.[Final Project](https://reeborg.ca/reeborg.html?lang=en&mode=python&menu=worlds%2Fmenus%2Freeborg_intro_en.json&name=Maze&url=worlds%2Ftutorial_en%2Fmaze1.json)的答案
這個project主要就是，每次robot出生的地點都會不一樣，然後要讓他走出迷宮，那走出迷宮的方法很簡單，就是沿著右邊的牆移動，不管如何最後都一定走得出去。（之前就有聽別人說，假如我們走進一座迷宮，只要用右手摸著牆壁，然後一直走下去，一定會走到出口）
* 老師的寫法：
那這題我沒寫出來，直接看了答案，才發現自己想太多了。
第一步先寫出這樣：
```python=
def turn_right():
    turn_left()
    turn_left()
    turn_left()

while at_goal() != True:
    if right_is_clear():
        turn_right()
        move()
    elif front_is_clear():
        move()
    else:
        turn_left()
```
再來，為了避免infinite loop必須debug，不過老師有建議如果是初學者，可以等看完Day15再回來這裡debug。

這裡直接放上正解：
```python=
def turn_right():
    turn_left()
    turn_left()
    turn_left()

#程式是從上而下執行的，所以在執行下面那條while loops前，先執行此條while。
#用意是如果前方沒有遮擋物的話，他就會不斷往前走，直到前方有牆壁為止
#之後再向左轉，這樣就能確保右邊有牆
while front_is_claer():
    move()
turn_left()

while at_goal() != True:
    if right_is_clear():
        turn_right()
        move()
    elif front_is_clear():
        move()
    else:
        turn_left()
```