七、判断

测试、测试

程序需要能够根据输入做不同的事情。下面给出几个例子:

  • ˆˆ如果 Tim 给出的答案正确,就为他加 1 分;
  • 如果 Jane 击中外星人,就发出爆炸声;
  • 如果文件没找到,就显示错误消息。

决策时,程序要做出检查(完成一个测试),查看某个条件是否为真。在上面的第一个例子中,这个条件就是“答案正确”。

Python 完成测试的方法很有限,而且每个测试只有两个可能的答案:真(true)或者假(false)。Python 在测试时可能会问下面这些问题:

  • ˆˆ这两个东西相等吗?
  • 其中一个是不是小于另一个?
  • 其中一个是不是大于另一个?

如果 Tim 的答案是正确的,这两个变量就是相等的,所以条件(condition)为真(true)。如果他的答案不正确,这两个变量就不相等,条件则为假(false)。

Python 使用关键字 if 来测试条件,如下:

  1. if timsAnswer == correctAnswer:
  2. print("You got it right!")
  3. score = score + 1
  4. print("Thanks for playing.")

缩进

在 Python 中,编写代码时缩进是必不可少的一部分。缩进会告诉 Python 代码块从哪里开始,到哪里结束。一些语句(如 if 语句)需要一个代码块来告诉它们要做什么。对于 if 语句,代码块会告诉 Python 如果条件为真时做什么。

Python 中有一个惯例:总是将代码块缩进 4 个空格。在你的程序中最好也采用这种风格。

左右比较

人们通常这么说,“5 加 4 等于 9”,另外会这么问“5 加 4 等于 9 吗?”。前一个 是陈述句(statement):另一个是疑问句

在 Python 中,也同样有陈述句以及疑问句。陈述句将值赋给一个变量。疑问句查看变量是否等于某个值。前者是在做某种设置(赋值或设置为相等),后者在做某种检查或测试(是否相等,对还是错),所以 Python 使用了两种不同的符号。我们已经看到,等号(=)用来设置变量或赋值。下面再给出几个例子:

  1. correctAnswer = 5 + 3
  2. temperature = 35
  3. name = "Bill"

要测试两个东西是否相等,Python 使用了一个双等号(==),如下:

  1. if myAnswer == correctAnswer:
  2. if temperature == 40:
  3. if name == "Fred":

其他比较操作符:小于(<)、大于(>)和不等于(!=)。可以把 > 或 < 与 = 结合起来表示大于或等于(>=)以及小于或等于(<=)。数学课上你可能已经见过这样一些符号。还可以把两个大于和小于操作符“串”在一起完成一个范围测试,比如:

  1. if 8 < age < 12:
  2. if 8 <= age <= 12:

一个简单的示例程序:

  1. num1 = float(input("Enter the first number: "))
  2. num2 = float(input("Enter the second number: "))
  3. if num1 < num2:
  4. print(num1, "is less than", num2)
  5. if num1 > num2:
  6. print(num1, "is greater than", num2)
  7. if num1 == num2:
  8. print(num1, "is equal to", num2)
  9. if num1 != num2:
  10. print(num1, "is not equal to", num2)

测试结果为假

我们已经看到了,如果测试的结果为真,Python 会做些什么。不过,如果测试为假,Python 又会做一些什么呢?

在 Python 中,有以下 3 种可能。

  1. 做另一个测试。如果第一个测试结果为假,可以利用关键字 elif 再做另一个测试
  2. 如果所有其他测试结果都是假,做其他工作。这要利用 else 关键字完成。
  3. 继续。 ```python if expr: #true do_something elif expr2: #false1 do_other elif expr3: do_other else: #false2 do_else

if expr: #true do_something do_something_anyway #false3

  1. <a name="vdTIR"></a>
  2. ## 利用 `if` 赋值
  3. ```python
  4. smaller = x if x < y else y

测试多个条件

假设你要为 8 岁以上的人创建一个游戏,另外你希望玩家至少上三年级。这就要满足两个条件。下面是测试这两个条件的一种方法:

age = float(input("Enter your age: ")) 
grade = int(input("Enter your grade: ")) 
if age >= 8:
    if grade >= 3:
        print("You can play this game.")
else:
    print("Sorry, you can’t play the game.")

使用 and 关键简化代码:

age = float(input("Enter your age: ")) 
grade = int(input("Enter your grade: ")) 
if age >= 8 and grade >= 3:
    print("You can play this game.")
else:
    print("Sorry, you can’t play the game.")

注:关键词 or 表示满足任意条件,关键词 not 表示不满足此条件

Revision

  • 比较测试和关系操作符。
  • 缩进和代码块。
  • 使用 andor 结合测试。
  • 使用 not 来进行反向测试。

测试题

  1. 运行下面的程序会得到什么输出:

    my_number = 7
    if my_number < 20:    
     print('Under 20')
    else:
     print('20 or over')
    
  2. 基于第一个问题中的程序,如果把 my_number 改为 25,输出会是什么?

  3. 要检查一个数是否大于 30 但小于或等于 40,要用哪种 if 语句?
  4. 要检查用户输入的字母“Q”是大写还是小写,要使用哪种 if 语句?

动手试一试

  1. 家商场在降价促销。如果购买金额低于或等于10元,会给10%的折扣,如果购买金额大于10元,会给20%的折扣。编写一个程序,询问购买价格,再显示折扣(10%或20%)和最终价格。
  2. 一个足球队在寻找年龄在10到12岁之间的小女孩加入。编写一个程序,询问用户的年龄和性别(m表示男性,f表示女性)。显示一条消息指出这个人是否可以加入球队。
    1. 额外提示:要合理地建立程序,如果用户不是女孩就不必询问年龄。
  3. 你在长途旅行,刚到一个加油站,距下一个加油站还有 200 km。编写一个程序确定是不是需要在这里加油,还是可以等到下一个加油站再加油。这个程序应当问下面几个问题:
    1. 你的油箱有多大(单位是升)?
    2. 油箱有多满(按百分比,例如,半满就是50%)?
    3. 你的汽车每升油可以走多远(km)?
    4. 示例输入如下: ```shell Size of tank: 60 percent full: 40 km per liter: 10 You can go another 240 km The next gas station is 200 km away You can wait for the next station.

Size of tank: 60 percent full: 30 km per liter: 8 You can go another 144 km The next gas station is 200 km away Get gas now!


4. 建立一个程序,用户必须输入密码才能使用这个程序。你当然知道密码(因为它会写在你的代码中)。不过,你的朋友要得到这个密码就必须问你或者直接猜,也可以学习足够的 Python 知识查看代码来找出密码!对程序没什么要求,可以是你已经编写的程序,也可以是一个非常简单的程序,只在用户输人正确的口令时显示一条 `You're in!` 之类的消息。
4. 小明身高1.75,体重80.5kg。请根据BMI公式(体重除以身高的平方)帮小明计算他的BMI指数,并根据BMI指数,用 `if-elif` 判断并打印结果:

低于18.5:过轻 18.5-25:正常 25-28:过重 28-32:肥胖 高于32:严重肥胖


<a name="063d7520"></a>
# 八、转圈圈(循环)
<a name="YyWwt"></a>
## 计数循环
也叫做 `for` 循环,因为很多语言 (包括 Python)在程序中都使用 `for` 关键字来创建这种类型的循环。
```python
for looper in [1, 2, 3, 4, 5]:
    print("hello")

hello
hello
hello
hello
hello


for looper in [1, 2, 3, 4, 5]:
    print(looper)
1
2
3
4
5
  1. 变量 looper 的值从 1 开始(所以 looper = 1)。
  2. 对应列表中的每一个值,这个循环会把下一个指令块中的所有工作完成一次
  3. 每次执行循环时,变量 looper 会赋为这个列表中的下一个值。

打印一个乘法表。这里只对前面的程序做一个小小的修改。

for looper in [1, 2, 3, 4, 5]:
    print(looper, 'times 8 =', looper * 8)

1 times 8 = 8
2 times 8 = 16
3 times 8 = 24 
4 times 8 = 32 
5 times 8 = 40

range()

在上面的例子中,我们只循环了 5 次,如果希望循环运行 100 次或者 1000 次呢?这就得键入很多很多的数!

image.png

利用 range() 函数,你可以只输入起始值和结束值,它就会为你创建这二者之间的所有值。

for looper in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, ...]

for looper in range(1, 5):
    print(looper, "times 8 =", looper * 8)

for looper in range(5):
    print(looper, "times 8 =", looper * 8)

for looper in range(1, 10, 2):
    print(looper, "times 8 =", looper * 8)

for looper in range(10, 0, -2):
    print(looper, "times 8 =", looper * 8)

enumerate()

#********************
# sequence: 一个序列、迭代器或其他支持迭代对象。 
# start: 下标起始位置。
# return: enumerate(枚举)对象
#********************
enumerate(sequence, [start=0])


>>> seasons = ['Spring', 'Summer', 'Fall', 'Winter']
>>> lst = list(enumerate(seasons))
>>> print(lst)
[(0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'Winter')]
>>> lst = list(enumerate(seasons, 1))
>>> print(lst)
[(1, 'Spring'), (2, 'Summer'), (3, 'Fall'), (4, 'Winter')]

enumerate()for 循环的结合使用。用 enumerate(A) 不仅返回了 A 中的元素,还顺便给该元素一个索引值 (默认从 0 开始)。此外,用 enumerate(A, j) 还可以确定索引起始值为 j

languages = ['Python', 'R', 'Swift', 'Matlab']
for j, language in enumerate(languages, 2):
    print(j, 'I love', language)
    pass
'''
2 I love Python
3 I love R
4 I love Matlab
5 I love C++
'''

条件循环

如果你能提前知道希望循环运行多少次,那么 for 循环很合适。不过,有时你可能希望循环一直运行,直到发生某种情况时才结束,而且你不知道发生这种情况之前会有多少次迭代。这就可以使用 while 循环来实现。

while 循环并不统计运行多少次循环,它会使用一个测试来确定什么时候停止循环。while 循环也称为条件循环(conditional loop)。条件循环会在满足某个条件时一直保持循环。

print("Type 3 to continue, anything else to quit.")
someInput = input() 
while someInput != '3':
    print("Thank you for the 3. Very kind of you.")
    print("Type 3 to continue, anything else to quit.")
    someInput = input()
print("That's not 3, so I'm quitting now.")
sum = 0
n = 99
while n > 0:
    sum = sum + n
    n = n - 2
print(sum)

跳出循环

有时可能希望在中间离开循环,也就是 for 循环结束计数之前,或者 while 循环找到结束条件之前。有两种方法来做到:可以用 continue 直接跳到循环的下一次迭代,或者用 break 完全中止循环。

提前跳转(continue)

如果希望停止执行循环的当前迭代,提前跳到下一次迭代,你需要的就是一条 continue 语句。

for i in range(1, 6):
    print('i =', i)
    print('Hello, how')
    if i > 3:
        continue
    print(' are you today?')

跳出(break)

如果我们想完全跳出循环一不再完成计数,或者放弃等待结束条件,该怎么做呢?这个工作由 break 语句完成。

Revision

  • ˆˆfor 循环(也称为计数循环)。 ˆˆ
  • range() 函数— 计数循环的一个捷径。
  • ˆˆrange() 的不同步长大小。
  • ˆˆwhile 循环(也称为条件循环)。
  • continue 跳到下一次迭代。
  • break 跳出循环。

测试题

  • 下面的循环会运行多少次?

    for i inrange(1,6):
      print('Hi, Warren ')
    
  • 下面的循环会运行多少次?每次循环时 i 的值是什么?

    for i in range(1, 6, 2):
      print('Hi, Warren ')
    
  1. range(1,8) 会给出一个怎样的数字列表?
  2. range(8) 会给出一个怎样的数字列表?
  3. range(2,9, 2) 会给出一个怎样的数字列表?
  4. range(10,0,-2) 会给出一个怎样的数字列表?
  5. 使用哪个关键字停止循环的当前迭代,提前跳到下一次迭代?
  6. while 循环什么时候结束?

动手试一试

  1. 编写一个程序,显示一个乘法表。开始时要询问用户显示哪个数的乘法表。输出应该如下所示:

    Which multiplication table would you like? 5
    Here's your table :
    5 x 1 = 5
    5 x 2 = 10
    5 x 3 = 15
    5 x 4 = 20
    5 x 5 = 25
    5 x 6 = 30
    5 x 7 = 35
    5 x 8 = 40
    5 x 9 = 45
    5 x 10 = 50
    
  2. 向乘法表程序中再加点东西。询问用户想要的乘法表之后,再问问用户希望最大乘到几。输出应当如下所示: ``` Which multiplication table would you like? 7 How high ao you want to go? 12

Here’s your table: 7 x 1 = 7 7 x 2 = 14 7 x 3 = 21 7 x 4 = 28 7 x 5 = 35 7 x 6 = 42 7 x 7 = 49 7 x 8 = 56 7 x 9 = 63 7 x 10 = 70 7 x 11 = 77 7 x 12 = 84

完成上面两题的程序时你可能使用了 `for` 循环。大多数人都会这么做。不过,可以再做个练习,试着用 `while` 循环完成同样的工作。或者如果你已经使用了 `while` 循环,现在可以试着用 `for` 循环来完成。


<a name="AwYmv"></a>
# 九、嵌套
在循环体(也就是代码块)中可以放入其他代码,这些代码本身也可以有自己的代码块。
```python
while guess != secret and tries < 6:
    guess = input("What's yer guess? " )
    if guess < secret:
        print("Too low, ye scurvy dog!")
    elif guess > secret:
        print("Too high, landlubber!")
    tries = tries + 1

嵌套循环

嵌套循环就是一个循环出现在另一个循环里。对于外循环的每次迭代,内循环都要完成它的所有迭代。

for multiplier in range(5, 8):
    for i in range(1, 11):
        print(i, " x ", multiplier, " = ", i * multiplier)
    print('\n')

输出如下:

1 x 5 = 5
2 x 5 = 10
3 x 5 = 15
4 x 5 = 20
5 x 5 = 25
6 x 5 = 30
7 x 5 = 35
8 x 5 = 40
9 x 5 = 45
10 x 5 = 50

1 x 6 = 6
2 x 6 = 12
3 x 6 = 18
4 x 6 = 24
5 x 6 = 30
6 x 6 = 36
7 x 6 = 42
8 x 6 = 48
9 x 6 = 54
10 x 6 = 60

1 x 7 = 7
2 x 7 = 14
3 x 7 = 21
4 x 7 = 28
5 x 7 = 35
6 x 7 = 42
7 x 7 = 49
8 x 7 = 56
9 x 7 = 63
10 x 7 = 70

可变循环

固定的数(比如 range() 函数中使用的数)也称为常数(constant)。如果在一个 for 循环的 range() 函数中使用常数,程序运行时循环总会运行相同的次数。在这种情况下,我们称循环次数是硬编码的(hard-coded),因为它在你的代码中被定义了,而且永远不会改变。这往往不是我们真正想要的。

有时我们希望循环次数由用户来决定,或者由程序的另一部分决定。对于这种情况,我们就需要一个变量。

numStars = int(input("How many stars do you want? "))
for i in range(1, numStars + 1): 
    print('* ', end='')

可变嵌套循环

现在来尝试一个可变嵌套循环。这就是一个嵌套循环,只不过其中一个或多个循环在 range() 函数中使用了变量。

numLines = int(input('How many lines of stars do you want? '))
numStars = int(input('How many stars per line? '))
for line in range(0,numLines):
    for star in range(0,numStars):
        print('* ')
    print('\n')


'''
How many lines of stars do you want? 3
How many stars per line? 5
★ ★ ★ ★ ★
★ ★ ★ ★ ★
★ ★ ★ ★ ★
'''
numBlocks = int(input('How many blocks of stars do you want? '))
numLines = int(input('How many lines of stars do you want? '))
numStars = int(input('How many stars per line? '))
for block in range(0, numBlocks):
    for line in range(0,numLines):
        for star in range(0,numStars):
            print('* ')
        print('\n')
    print('\n')


'''
How many blocks of s>t>a>rs do you want? 3
How many lines of stars do you want? 4
How many stars per line? 8
* * * * * * * *
* * * * * * * *
* * * * * * * *
* * * * * * * *

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

* * * * * * * *
* * * * * * * *
* * * * * * * *
* * * * * * * *
'''

排列和组合

那么我们能够用嵌套循环做些什么呢?嵌套循环最擅长的工作就是得出一系列决定的所有可能的排列和组合。

如果要从1到20选择3个数,可以选择

  • 5, 8, 14
  • 2, 12, 20

如果想建立一个列表,列出从1到20选择3个数的所有排列,下面这两项是不同的:

  • 5, 8, 14
  • 8, 5, 14

这是因为,对于排列,元素出现的顺序很重要。如果建立一个包含所有组合的列表,下面这些都会视为一项:

  • 5, 8, 14
  • 8, 5, 14
  • 8, 14, 5

这是因为对于组合来说,顺序并不重要。

Revision

  • 嵌套循环。
  • 可变循环。
  • 排列和组合。

测试题

  1. Python 中如何建立可变循环?
  2. Python 中如何建立嵌套循环?
  3. 下面的代码总共会打印出多少星号:
    for i in range(5):
     for j in range(3):
         print('* ')
     print()
    
  • 第3题中的代码会得到什么输出?

动手试一试

使用一个可变循环修改程序。打印向下计数,直到 0 为止,这个程序要询问用户向下计数应当从哪里开始。根据写的程序,让它除了打印各个数之外还要打印一行星号,如下:

Countdown: How many seconds? 4
4
3
2
1

Countdown: How many seconds? 4
4 * * * *
3 * * *
2 * *
1 *