CS入门学习笔记9-MIT 6.00.1x

Lecture 8 Assertions and Exceptions

1. what is exception
----exceptions to what was expected
CS入门学习笔记9-MIT 6.00.1x_第1张图片python中带有的提示error的方式为:raise an exception
raise Exception(“descriptive string”)

2. python’s handlers for exceptions

try:
    f = open('grades.txt')
except:
    #若执行try中语句遇到error,则会显示下面的提示
    raise Exception("Can't open grades file")

CS入门学习笔记9-MIT 6.00.1x_第2张图片CS入门学习笔记9-MIT 6.00.1x_第3张图片可以在except后根据error的类型做判断,并且可以直接用print或者进行关闭程序等操作,不一定只能raise error

【其他可以跟在try语句后的语句】

CS入门学习笔记9-MIT 6.00.1x_第4张图片

3. types of exceptions
CS入门学习笔记9-MIT 6.00.1x_第5张图片【关于try语句的相关示例】:

def divide(x, y):
    try:
        result = x / y
    except ZeroDivisionError, e:
        print "division by zero! " + str(e)
    else:
        print "result is", result
    finally:
        # 下面这个语句无论try的结果如何都会被执行
        print "executing finally clause"

def divideNew(x, y):
    try:
        result = x / y
    except ZeroDivisionError, e:
        print "division by zero! " + str(e)
    except TypeError:
        divideNew(int(x), int(y))
    else:
        print "result is", result
    finally:
        print "executing finally clause"
>>> divide(3,4)
>result is 0
executing finally clause

>>> divide(3,0)
>division by zero! integer division or modulo by zero
executing finally clause

>>> divide('3','4')
>executing finally clause
# 由于divide未排除掉typeerror这种错误,所以会出现系统报错
TypeErrorTraceback (most recent call last)
<ipython-input-17-7559625dc61f> in <module>()
----> 1 divide('3','4')

c:\users\zoedin~1\appdata\local\temp\tmp_j6lpp.py in divide(x, y)
TypeError: unsupported operand type(s) for /: 'str' and 'str'

>>> divideNew('3','4')
>result is 0
executing finally clause
executing finally clause

4. 利用exceptions as control flow
使用exception来做判断,可以在某些情况下让code更加简洁明了——easier to think about processing on data structure abstractly, with exceptions to deal with unusual or unexpected cases:

因为系统提示的exception是各种个别情况导致的结果,此种方法可以直接通过会产生的结果来进行判断,而不用考虑如何将不同的情形分类、列举。

CS入门学习笔记9-MIT 6.00.1x_第6张图片
CS入门学习笔记9-MIT 6.00.1x_第7张图片
5. assertions

  • 确保code在计算过程中符合我们的假设(如特定的input)
  • 无法控制结果,但可以raise an AssertionError exception
  • this is a good defensive programming

示例:

def avg(grades, weights):
    # 只要assert后面的语句为真,则程序正常运转;若为False,则为AssertionError,并print逗号后的语句
    assert not len(grades) == 0, 'no grades data'
    newgrades = [convertLetterGrade(elt) for elt in grades]
    return dotProduct(newgrades, weights)/len(newgrades)

【作为一个good defensive programming,具有如下作用:】
CS入门学习笔记9-MIT 6.00.1x_第8张图片
【使用assertions的场合】
CS入门学习笔记9-MIT 6.00.1x_第9张图片

6. 本节的小结性示例----计算每个学生的加权成绩

CS入门学习笔记9-MIT 6.00.1x_第10张图片

def getSubjectStats(subject, weights):
    return [[elt[0], elt[1], avg(elt[1], weights)]
            for elt in subject]

def dotProduct(a,b):
    result = 0.0
    for i in range(len(a)):
        result += a[i]*b[i]
    return result

def avg(grades, weights):
    try:
        return dotProduct(grades, weights)/len(grades)
    # 在某同学没有成绩时不会报错,并且返回加权成绩为0.0
    except ZeroDivisionError:
        print 'no grades data'
        return 0.0

def convertLetterGrade(grade):
    if type(grade) == int:
        return grade
    elif grade == 'A':
        return 90.0
    elif grade == 'B':
        return 80.0
    elif grade == 'C':
        return 70.0
    elif grade == 'D':
        return 60.0
    else:
        return 50.0

def avg(grades, weights):
    try:
        return dotProduct(grades, weights)/len(grades)
    except ZeroDivisionError:
        print 'no grades data'
        return 0.0
    # 当有科目的分数显示为字母时,可以不报typeerror的错误,利用另一个函数将其转化为数字后代入计算
    except TypeError:
        newgrades = [convertLetterGrade(elt) for elt in grades]
        return dotProduct(newgrades, weights)/len(newgrades)
-------------------------------------------------------------------------------------
def avg(grades, weights):
    assert not len(grades) == 0, 'no grades data'
    newgrades = [convertLetterGrade(elt) for elt in grades]
    return dotProduct(newgrades, weights)/len(newgrades)

def avg(grades, weights):
    # pre-conditions on input:
    assert not len(grades) == 0, 'no grades data'
    assert len(grades) == len(weights), 'wrong number grades'
    newgrades = [convertLetterGrade(elt) for elt in grades]
    result = dotProduct(newgrades, weights)/len(newgrades)
    # post-conditions on output, 限制计算后的结果值(现实意义:确保没有人作弊或信息录入错误)
    assert 0.0 <= result <= 100.0, 'grade exceeds limits'
    return result


test = [[['fred', 'flintstone'], [10.0, 5.0, 85.0]],
        [['barney', 'rubble'], [10.0, 8.0, 74.0]],
        [['wilma', 'flintstone'], [8.0, 10.0, 96.0]],
        [['dino'], []]]

weights = [.3, .2, .5]

weights1 = [.15, .1, .25, .25]

test1 = [[['fred', 'flintstone'], [10.0, 5.0, 85.0, 'D']],
         [['barney', 'rubble'], [10.0, 8.0, 74.0, 'B']],
         [['wilma', 'flintstone'], [8.0, 10.0, 96.0, 'A']],
         [['dino'], []]]

test2 = [[['fred', 'flintstone'], [10.0, 5.0, 8500, 'D']],
         [['barney', 'rubble'], [10.0, 8.0, 74.0, 'B']],
         [['wilma', 'flintstone'], [8.0, 10.0, 96.0, 'A']]]


你可能感兴趣的:(CS入门)