課時4:改進我們的小遊戲

那是個好男孩發表於2018-07-24

目錄:

一、改進我們的小遊戲

二、條件分支

三、while迴圈

四、引入外援

五、課時04課後習題及答案

 

**************************

一、改進我們的小遊戲

**************************

很多魚油對改善這個遊戲提出了建議,小甲魚做了一下總結,大概有以下幾個方面需要改進:
>猜錯的時候程式應該給點提示,例如告訴使用者輸入的值是大了還是小了。
>每執行一次程式只能猜一次,應該提供多次機會給使用者猜測。
>每次執行程式,答案可以是隨機的。因為程式答案固定,容易導致答案外洩。

 

****************

二、條件分支

****************

第一個改進要求:猜錯的時候程式提示使用者當前的輸入比答案大了還是小了。

                                                               

例如:

 1 >>> 1<3
 2 True
 3 >>> 1 < 3
 4 True
 5 >>> 1 <= 3
 6 True
 7 >>> 1 == 3
 8 False
 9 >>> 1 != 3
10 True

這裡1和3進行比較,判斷1是否小於3,在小於號左右分別留了一個空格,這不是必需的,但是程式碼量一多,看上去會美觀很多。

Python的條件分支語法:

 

****************

三、while迴圈

****************

第二個改進要求:程式應該提供多次機會給使用者猜測,專業點來講就是程式需要重複執行某些程式碼。

temp =input("不妨猜一下小甲魚現在心裡想的是哪個數字:")
guess = int(temp)
while guess!=8:
      temp = input("猜錯了哦,重新猜一猜:")
      guess = int(temp)
      
      if guess == 8:
              print("哇草,你是小甲魚心裡的蛔蟲嗎?")
              print("哼,猜中了也沒有獎勵")
      else:
              if guess > 8:
                      print("哥,大了大了~~")
              else:
                      print("嘿,小了!小了!!")
print("遊戲結束,不玩啦~~")

說一說自己對這一段程式碼的理解:while迴圈條件為假的話,執行最後一行的程式碼。為真的話執行while迴圈裡縮排的內容。值得一提的是,迴圈體內if-else的guess變數是重新賦值了的。

運用了if-else的巢狀結構。看程式碼時首先把大的縮排程式碼區域判斷清楚,在判斷好每個小的縮排程式碼區域,這樣有便於理清思路。

 

這裡的程式碼好像跟第2個要求有點不同,後面會進行完善。這裡我們給大家的提示是:使用and邏輯操作符Python的and邏輯操作符可以將任意表示式連線在一起,並得到一個布林型別的值。

 

****************

四、引入外援

****************

第三個改進要求:每次執行程式產生的答案是隨機的。
我們需要引入外援random模組
這個random模組裡邊有一個函式叫做:randint(),Ta會返回一個隨機的整數。
我們可以利用這個函式來改造我們的遊戲!

 

import random

secret = random.randint(1,10)
temp =input("不妨猜一下小甲魚現在心裡想的是哪個數字:")
guess = int(temp)

while guess!=secret:
      temp = input("猜錯了哦,重新猜一猜:")
      guess = int(temp)

      if guess > secret:
            print("哥,大了大了~~")
      else:
            print("嘿,小了!小了!!")
                      
      if guess == secret:
              print("哇草,你是小甲魚心裡的蛔蟲嗎?")
              print("哼,猜中了也沒有獎勵")
              
print("遊戲結束,不玩啦~~")

 

*******************************

五、課時04課後習題及答案

*******************************

測試題:

0. 請問以下程式碼會列印多少次“我愛魚C!”

while 'C':  
    print('我愛魚C!')  

1.請問以下程式碼會列印多少次“我愛魚C!”

i = 10  
while i:  
    print('我愛魚C!')  
    i = i - 1  

每經過迴圈體一次,迴圈體內的i減去1,因而i-=1寫在print語句前和語句後都一樣!

2.請寫出與10 < cost < 50等價的表示式

3.Python3中,一行可以書寫多個語句嗎?

4.Python3中,一個語句可以分成多行書寫嗎?

5.請問Python的and操作符和C語言的&&操作符有何不同?

6.聽說過“短路邏輯(short-circuitlogic)”嗎?

動動手:

0. 完善第二個改進要求(為使用者提供三次機會嘗試,機會用完或者使用者猜中答案均退出迴圈)並改進視訊中小甲魚的程式碼。

1.嘗試寫程式碼實現以下截圖功能:

 

 2.嘗試寫程式碼實現以下截圖功能:

 

 

答案:

 

測試題:

 

0. 請問以下程式碼會列印多少次“我愛魚C!”

死迴圈,會一直列印我愛魚C(嗯,這也算是永遠支援魚C的方法之一),直到崩潰或者使用者按下快捷鍵 CTRL + C(強制結束)
造成死迴圈的原因是 while 後邊的條件永遠為真(True),在 Python 看來,只有以下內容會被看作假(注意冒號括號裡邊啥都沒有,連空格都不要有!):False None 0 "" '' () [] {}
其他一切都被解釋為真!
不妨試試:

while '':
    print('進入迴圈')
print('退出迴圈')
while Flase:
    print('進入迴圈')
print('退出迴圈')

或者:

while 0:
    print('進入迴圈')
print('退出迴圈')   

 

1.請問以下程式碼會列印多少次“我愛魚C!” 

10次,每次迴圈i減1,10次後i=0,while語句不成立,停止列印。

 

2.請寫出與10 < cost < 50等價的表示式

(cost > 10) and (cost < 50)  

 

3.Python3中,一行可以書寫多個語句嗎?

可以。如果有括號(小括號{}、中括號[]、大括號()),可以在任意地方斷行。如果沒有,需要在斷開的地方新增 \ 字元,表示這一行尚未結束。例如:

>>> d={
    1,
    2
    }
>>> d
{1, 2}
>>> print(d)
{1, 2}
>>> a=1;b=2
>>> c=a+\
       b
>>> c
3

一行過長的語句可以使用反斜槓或者括號分解成幾行,不妨試試

>>> 3 < 4 and 1 < 2
True
>>> 3 < 4 and \
    1 < 2
True
>>> (3 <4 and
     1 < 2)
True

 

4.Python3中,一個語句可以分成多行書寫嗎?

可以。

 

5.請問Python的and操作符和C語言的&&操作符有何不同?

and 布林”與” ——如果aFalse(a and b)返回False,否則它返回b的計算值。
or 布林”或” —— 如果aTrue(a or b)返回True,否則它返回b的計算值。
not 布林”非” —— 如果aTruenot a 返回False。如果aFalsenot a返回True
在C中,0&&3 = 0,1&&3 = 1。在python中,,0 and 3 = 0,1 and 3 = 3。

>>> 0 and 3
0
>>> 1 and 3
3
>>> 1 or 3
1
>>> 0 or 3
3

 

6.聽說過“短路邏輯(short-circuitlogic)”嗎?

邏輯操作符有個有趣的特性:在不需要求值的時候不進行操作。舉個例子,表示式 a and b,需要 a 和 b 兩個變數同時為真(True)的時候,結果才為真。             因此,如果當 a 變數得知是假(False)的時候,表示式就會立刻返回 False,而不用去管 b 變數的值。 這種行為被稱為短路邏輯(short-circuit logic)或者惰性求值(lazy evaluation) 這種行為同樣也應用與 or 操作符。

邏輯操作符有個有趣的特性:在不需要求值的時候不進行操作。這麼說可能比較“高深”,舉個例子,表示式 x and y,需要 x 和 y 兩個變數同時為真(True)的時候,結果才為真。因此,如果當 x 變數得知是假(False)的時候,表示式就會立刻返回 False,而不用去管 y 變數的值。
這種行為被稱為短路邏輯(short-circuit logic)或者惰性求值(lazy evaluation),這種行為同樣也應用與 or 操作符,這個後邊的課程小甲魚會講到,不急。
實際上,Python 的做法是如果 x 為假,表示式會返回 x 的值(0),否則它就會返回 y 的值(例子參考樓上那題)。

 

值得注意的是 0 代表的是False。and式子是同真為真,or式子是有真為真。

也就是說,判斷式子是否為真,and 式子中a都為false了,還管b幹嘛,無論它是真是假,and式子都為假了。or式子中a都為true了,還管b幹嘛,無論它是真是假,or式子都為真了。

 

 

動動手:

 

 0. 完善第二個改進要求(為使用者提供三次機會嘗試,機會用完或者使用者猜中答案均退出迴圈)並改進視訊中小甲魚的程式碼。

import random
secret = random.randint(1,10)
i = 3
temp = input("不妨猜一下小甲魚現在心裡想的是哪個數字:")
number = int(temp)
while i > -1: #並不意味著在這裡 i=0 時,判斷語句就會為False;單獨寫個 while 0: 才是False。
      if number == secret:
            print("哇草,你是小甲魚心裡的蛔蟲嗎?")
            print("哼,猜中了也沒有獎勵")
            break
      else:  
            if number < secret:
                  print("小了小了")
            else:
                  print("大了大了")
            #次數的判斷 就可以用if-else語句!!!     
            if i != 0:
                  temp = input("請重新猜,還有"+ str(i) +"機會:")
                  number = int(temp)
            else:
                  print("三次機會已用完,遊戲結束")
                   
            i = i - 1 #為什麼i>-1 因為i=1 時還要有一次機會,這裡執行了i-1 此時i等於0 要使判斷語句為True。
              

 !!!! if 不是迴圈體!!!!!

以下是大佬提供的簡化版本,學習了。

import random
secret = random.randint(1,10)
i = 3
number = int(input("不妨猜一下小甲魚現在心裡想的是哪個數字:"))
while i > -1:
      if number == secret:
            print("哇草,你是小甲魚心裡的蛔蟲嗎?\n哼,猜中了也沒有獎勵")
            break
      else:
            print("小了小了") if number < secret else print("大了大了")
            number = int(input("請重新猜,還有"+ str(i) +"機會:")) if i != 0 else print("三次機會已用完,遊戲結束")
      i -= 1

使用了三元運算子和自運算等等的簡化版本。
最好少用三元運算子,因為這是個不好的習慣,這會導致你的程式碼可讀性極差。

以下是小甲魚的程式碼!

import random
times = 3
secret = random.randint(1,10)
print('------------------我愛魚C工作室------------------')
# 這裡先給guess賦值(賦一個絕對不等於secret的值)
guess = 0
# print()預設是列印完字串會自動新增一個換行符,end=" "引數告訴print()用空格代替換行!
# 嗯,小甲魚覺得富有創意的你應該會嘗試用 end="JJ"?
print("不妨猜一下小甲魚現在心裡想的是哪個數字:", end=" ")
while (guess != secret) and (times > 0):# 先前定義guess為0 有此妙用 直接可以輸入一次數字。將接下來兩行程式碼納入迴圈體系,減少了程式碼量。
    temp = input() #因為end=“ ” 所以在print輸出到螢幕的語句後面直接輸入
    guess = int(temp)
    times = times - 1 # 使用者每輸入一次,可用機會就-1
    if guess == secret:
        print("我草,你是小甲魚心裡的蛔蟲嗎?!")
        print("哼,猜中了也沒有獎勵!")
    else:
        if guess > secret:
            print("哥,大了大了~~~")
        else:
            print("嘿,小了,小了~~~")
        if times > 0:
            print("再試一次吧:", end=" ")
        else:
            print("機會用光咯T_T")
print("遊戲結束,不玩啦^_^")

值得學習的思維方式有兩點:其一 在while迴圈外用print,並用了end,迴圈體內用了input(),後面的程式碼print("再試一次",end" "),與input很好的切合,以便於在使用者輸入數字前可以寫不同的說明語句。其二 while判斷語句中 and的用法 同時結合了guess等於0 這一妙用。其實這裡不必要用and也可以實現。總有條件下可以用到的,學到啦!!

 

通過實踐證明,在if-else中,先判斷輸入是否一樣,會方便許多。

 

1. 嘗試寫程式碼實現以下截圖功能:

temp = input('請輸入一個整數:')
number = int(temp)
i = 1
while number:
    print(i)
    i = i + 1
    number = number - 1

 

2. 嘗試寫程式碼實現以下截圖功能:

temp = input('請輸入一個整數:')
number = int(temp)
while number:
    i = number - 1
    while i:
        print(' ', end = '')
        i = i - 1
    j = number
    while j:
        print('*', end = '')
        j = j - 1
    print()
    number = number - 1

談一談我對這一段程式的理解:先觀察最終實現的效果圖,結合程式碼,很清楚的知道,3個迴圈體分別代表的含義,外迴圈表明有多少行,內迴圈,一個迴圈打出空格,一個迴圈打出*(星號),各個迴圈自成一體,所以都會有類似於 i -= 1的程式碼,以便終止當前迴圈。而end = " ",因為空格和*是一個一個迴圈打出的,所以是避免換行。而兩次內迴圈的結束,print()語句實現了換行。

 

簡化版本:

temp = input("輸入一個數字:")
number = int(temp)
while number:
      print(" "*(number-1) + "*"*number)
      number -= 1

 

補充:

稱述:在寫程式的時候,不小心將 -=寫成了 =- 因而程式並沒有得到想要的結果,過後我查閱了相關的資料,可以借鑑這一網址:網址(多看兩遍就明白了)

>>> a = 2
>>> b = a
>>> id(a)
140728562340928
>>> id(b)
140728562340928
>>> a = a + 3
>>> id(a)
140728562341024
>>> id(b)
140728562340928

>>> c = 5
>>> d = 5
>>> id(c)
140728562341024
>>> id(d)
140728562341024
>>> c += 1
>>> id(c)
140728562341056
>>> id(d)
140728562341024

這一部分首先要理解python記憶體機制,Python中萬物皆物件。

對於不可變物件,改變了原來的值,其別名(變數名)繫結到了新值上面,id肯定會改變

>>> aa = [3,4,5]
>>> bb = aa
>>> id(aa)
3007589114056
>>> id(bb)
3007589114056
>>> aa = aa + [10]
>>> id(aa)
3007588801672
>>> id(bb)
3007589114056
>>> aa
[3, 4, 5, 10]
>>> bb
[3, 4, 5]

對於可變物件,+ 操作改變了值,id肯定會變,而+= 是本地操作,其值原地修改

>>> aa = [3,4,5]
>>> bb = aa
>>> id(aa)
1985188852296
>>> id(bb)
1985188852296
>>> aa += [10]
>>> aa
[3, 4, 5, 10]
>>> bb
[3, 4, 5, 10]
>>> id(aa)
1985188852296
>>> id(bb)
1985188852296
>>> cc = [2,3,4]
>>> dd = [2,3,4]
>>> id(cc)
3007586184840
>>> id(dd)
3007589046728
>>> cc += [0]
>>> cc
[2, 3, 4, 0]
>>> id(cc)
3007586184840
>>> dd = dd + [0]
>>> dd
[2, 3, 4, 0]
>>> id(dd)
3007589105160

對於+號操作,可變物件和不可變物件呼叫的都是__add__操作

對於+=號操作,可變物件呼叫__add__,不可變物件呼叫的是__iadd__(不可變物件沒有__iadd__)   __iadd__是原地修改

 總結一下:對於不可變的物件,例如數字啥的,你用 a = a + 10,亦或者用 a += 10的形式 其id值都會發生改變。而對於可變的物件,例如列表之類的,這裡有另種情況要討論,<1>aa = bb的前提下,aa 和bb的id是相同的,用 aa = aa + [10] 的形式只會改變aa的id,bb的id還是原來的id,不會改變;倘若用aa += [10]的形式,aa和bb的值會同時發生改變,但aa和bb的id還是原來的味道,不會改變!!!<2>cc = [2,3,4] dd = [2,3,4]的前提下,雖然兩者的值相同,但是他倆的id是不同的,不同的!!!不明白的看看上面的例子就懂了。好繞,多看兩遍就記在心中了,emmm。腦闊痛。

 

相關文章