目录

Control Structures

Chapter 3 notes


Control Structures

Conditionals

indentation and conditionals

scope

scope in python
if / else in python

condition & boolean operators

使用 member op 作为条件表达式

可以通过 in 成员查询条件是否属于某个条件集合:

club_members = ["John", "Jenny", "Jason", "Jane"]
my_name = "Jenny"
if my_name in club_members:
    print("Welcome back!")
in 关键字还可以用于匹配字符串,比如:
mystery_string = "zizazzle"
if "zzz" in mystery_string = "zizazzle":
    do sth....

使用 function 作为条件表达式

#isdigit() is an member function of string that used as the condition
myNumericString = "12345"
if myNumericString.isdigit():
    prtin("something")

scope 与 condition

Loops

For loop

For Loops in Python

基本写法:

for i in range(1, 11):
    print(i)
range 是左闭右开区间 $[1,11)$。range() 函数的几种初始化方法:
#0 - 9, implicitly
range(10)
#0 - 9, explicitly
range (0 , 10)
#0, 2, 4, 6, 8
range(0, 10, 2)
#count down(reverse) 10 - 1
range(10, 1, -1)

Primer on Indices
for each loop

for each loop 与 for loop 类似。但相比 for loop,for each 使用变量(list)来作为范围,for each loop 会循环 list 中所有的元素。比如:

listOfNumbers = [1,2,3,4,5]
for i in listOfNumbers:
    sum += i
这个等同于如下的 for loop:
for i in range(0, len(listOfNumbers)):
    sum += i
python 中,string 也可以作为范围变量;for each 访问的是 string 中的每一个字母:
mystring = "abcde"
for char in mystring:
    do sth

While Loop

While Loop 适用于我们不清楚循环要进行多少次的情况下。

python 的随机数

import random

# Returns a random integer greater than or equal to min and less than or equal to max.
random.randint(min, max)

nested loop

使用 nested loop 统计 list string 中有多少词:

list_of_strings = ["This is the 1st string", "This is the 2nd string", 
                   "This is the 3rd string", "This is the 4th string", 
                   "This is the 5tj string" ]

space_count = 0

for current_string in list_of_strings:
    for curr_char in current_string:
        if curr_char == " ":
            space_count += 1

word_counts = space_count + len(list_of_strings)
print(word_counts)

相关概念

重要的 loop 关键字
scope & loop

Functions

什么是 call 和 definitaion
call 的过程

function in python

定义 function

#defination
def printYen():
    print("$", end='')

# call
printYen()

python 中必须先定义函数再使用。

parameter & returns

# return
def returnYen():
    return "Y"

# using parameter
def returnYenAmount(amount):
    return "Y" + str(amount)
print(returnYenAmount(5))

return 会直接终止当前 function body 的继续运行

注意事项
常见错误
None
keyword parameters

keyword prarameter 指函数中的自带的,用于实现某种特殊功能的可选参数(可忽略)。比如 print()

#sep is the character between string A and string B
#end is the character added at the end of the printed string
#output will be A#B!
# by default, sep = space, end = newline
print("A", "B", sep = "#", end = "!")
keyword parameter 处于所有函数 parameter 的后方,可以自定义;功能类似 C++ 的函数默认值。比如:
#currency has default value USD
def currencyAmount(amount, currency = "USD")
#when calling, currency can be changed by signing an parameter to it
currencyAmount(5, currency = "GBP")

Exception Handling

catching” Errors

catching error 与通常避免错误的处理方式不同。通常的处理的方式是阻止错误的发生;比如不允许除零的行为,来保证程序的正常运行。而 catching error 是对 error 做处理,保证遭遇错误的时候程序依然能够正常运行:比如当用户进行除零的行为时,catching error 首先告诉电脑不要 crash,其次再通过电脑告知用户除零这种操作是不允许的。

Catch Error 的优势
  1. 对于独立的 function, catching error 允许我们首先考虑 code 本身的功能,在之后再去考虑可能产生什么样的 error
    • catching error 的方式可以允许程序执行一部分直到错误的出现
  2. 相比把所有错误检测的条件语句放到程序之前,catch error 将所有 error 的处理放到最后,使程序更易读
  3. catching error 可以在遭遇未知错误的时候阻止程序 crash

Try-Catch-Finally

Try block 中的代码是试错用的, catch 是处理 error 用的 ,Final 中的代码是之前两步完成以后一定会运行的代码(应该放一些比较稳当的代码)

Try and Except

在 python 中, try-catch 以 try - except 关键字的形式存在。比如下列的例子:

try:
    print("Converting myString to int....")
    myInt = int(myString)
    print(myInt)
except:
    pass
print(done)

需要注意的是,如果 try block 中有任意错误出现,那么代码会直接跳转到之后的 except block 中;try block 之后的语句都不会执行。相反,如果 try block 中的语句没有出现错误,那么 except block 永远不会执行。

指定 except block 中的内容

execpt block 中可以指定对错误内容的反馈(log),比如:

try:
    print("Converting myString to int....")
    myInt = int(myString)
    print(myInt)
except:
    print("Can't convert an non-number string to int")

指定需要捕获的 error

python 中允许我们对指定类型的 error 进行捕获,比如:

try:
    print(1 / 0)
    print("No error occurred!")
except ZeroDivisionError:
    print("An error occurred!")
print("Done!")
这里的 print(1/0)ZeroDivisionError 的错误类型,因此 except block 会成功匹配该错误,并执行该错误下的语句,这里是 print(“An error occurred!”)

但需要注意的是,这种情况下,python 只能捕获 except block 中指定的错误类型。如果出现了别的类型的错误,python 会:

  1. 按通常一样,跳转到 except block
  2. 寻找是否存在与该错误类型对应的 block
  3. 如果没有找到,那么该程序会 crash
使用变量存储错误信息

如果我们希望看到一些额外的,关于错误如何抛出的信息,我们可以使用 as 关键字来存储该信息。写法如下:

try:
    print(1 / 0)
except ZeroDivisionError as error:
    print(error) # variable error stores error info from ZeroDivisionError 
print("Done!")
此处的 error 变量可以为任何名字,存储的是 ZeroDivisionError 带来的信息 division by zero。因此,打印结果为:
division by zero
Done!

同时处理多种 error

python 提供了同时处理多种 error 的机制:

try:
    print("String" + 1)
    print(1 / 0)
except ZeroDivisionError:
    print("A ZeroDivisionError occurred!")
except TypeError:
    print("A TypeError occurred!")
print("Done!")
可以注意到, print(“String” + 1) 会导致 TypeError. 当该错误出现时,python 会跳转到 except block 中,以从上到下的顺序寻找与该错误类型匹配的 except block。我们的程序中有对应 TypeError 的处理,因此会打印:
A TypeError occurred!
Done!
需要注意的是,即便同时存在多种类型的错误,只要成功捕获了一个错误,python 就会执行对应的 except block 中的内容,以及 except block 之后的内容了。即便是 try 中还存在着其他类型的错误,python 也不会在进行执行,比如:
try:
    print("String" + 1)
    myInt = int("This is string")
    print(1 / 0)

except TypeError:
    print("A TypeError occurred!")
except ZeroDivisionError:
    print("A ZeroDivisionError occurred!")
print("Done!")
这里的 myInt = int(“This is string”)ValueError 类型的错误。按道理来说,由于我们没有提供对应的错误处理,程序应该 crash 掉。但实际上,在其执行之前已经出现了 TypeError 类型的错误,因此该行代码以及其之后的,在 try block 中的内容都不会执行。因此打印结果与之前的例子一样。

如果需要对其他剩余的错误做一个总的处理,可以使用关键字 Exception,比如
try:
    myInt = int("This is string")
    print("String" + 1)
    print(1 / 0)

except TypeError as error:
    print(error)
except ZeroDivisionError as error:
    print(error)
except Exception as error:
    print(error)
print("Done!")
如果不指定具体打印内容,python 会自动根据具体的错误类型信息将错误打印出来:
Invalid literal for int() with base 10: 'This is string'
Done!

Else and Finally

else 关键字

else 关键字是 python 特有的一个机制。当所有其他 except block 中的内容都没有执行的时候(也就是 try block 中程序无错运行完毕的时候),python 会跳转到 else block 下的语句运行,比如:

mystery_value = 9

try:
    print( 10 / mystery_value)
except ZeroDivisionError:
    print("Can't divide by zero")
except Exception:
    print("Not possible")
else:
    print("No error found!")
将打印:
1.1111111111111112
No error found!

else 关键字可能看起来有些多余。但实际上,因为这个关键字属于 except block 的一部分,而只有当所有 expect block 都没有执行,也就是没有错误被捕获的时候,else block 才会运行。因此,当 else block 中的语句被执行时,我们就可以百分之百的确认之前 try block 里的代码是没有(非逻辑)错误的。

else 的重要应用:读取文件

该应用由如下程序所示:

try:
    #open file in read only mode
    input_file = open("Fake.txt", mode = "r")
except IOError as error:
    print("An input error occurred!")
else:
    for line in input_file:
        print lines
    input_file.close()
该应用中,如果在打开 Fake.txt 的过程中出现了任何错误,都会被 python 捕获。如果打开正确,则会执行剩余的逐行读取操作(else block 中的部分)。

Finally 关键字

无论 try block 中有没有内容被捕获,Finally block 中内容都会运行:

try:
    #open file in read only mode
    input_file = open("Fake.txt", mode = "r")
except IOError as error:
    print("An input error occurred!")
else:
    for line in input_file:
        print lines
finally:
    input_file.close()
这里的 input_file.close() 一定会被执行。

为什么不在 try block 后面直接加无论如何都想要运行的代码?

finally 可以保证即便是 try block 中出现无法处理的错误(Uncaught Errors)的情况下,也能继续运行 finally block 内的语句。如果直接在 try block 后面添加语句,当出现 Uncaught Errors 时,程序会直接 crash,因此后面的语句也没有机会执行了。

使用嵌套的 try block 处理不同的错误

有如下代码:

try:
    #Open InputFile.txt in read-only mode
    input_file = open("FakeFile.txt", mode = "r")  
    try:
        #For each line in the file
        for line in input_file:  
            #Print the line
            print(int(line)) 
    #Catch a ValueError
    except ValueError as error:    
        print("A value error occurred!")
    else:
        print("No errors occurred converting the file!")
    finally:
        #Close the file
        input_file.close()
#Catch an IOError
except IOError as error:
    print("An error occurred reading the file!")
这段代码中,我们的本意是先验证文件是否能正常打开,再验证文件的内容是否能正确的从 string 转化为 int。对此,我们可以使用嵌套的 try block 结构来处理。可以看到,外部的 try block 处理的是 IOError,而内部的 try block 处理的是 ValueError。几点需要注意的是:

return 与 try block 的配合使用

return 可以终止函数的运行并返回结果。我们可以将这个功能放置在 except block 中来达到终止函数的运行并返回错误信息的效果:

def return_file_text(filename):
     try:
         file = open(filename)
     except:
         return "Error opening file!"
     file_text = file.read()
     return file_text

Error Handling and Control Structures

Error Handling and For Loops

如果 loop 出现问题就希望结束 loop,那么应该把 try block 包含整个 loop:

try:
    #For each line in the file
    for line in input_file:  
        #Print the line
        print(int(line)) 
#Catch a ValueError
except ValueError as error:    
    print("A value error occurred!")
如果希望对单次的 iteration 进行错误捕获,则应该把 try block 放到 loop 中:

#For each line in the file
for line in input_file:  
    try:
        #Print the line
        print(int(line)) 
        #Catch a ValueError
    except ValueError as error:    
        print("A value error occurred!")
这样的结构只会在出现错误时打断当前的迭代,loop 还会继续执行剩余的部分。

可以在 except block 中使用 break 语句强制结束循环

Error Handling and Functions