每个月,你的伴侣都要和最好的朋友见一次面。两个人的日程都很满,想找一个合适的日期并不容易!考虑到你自己的日程也很忙,你的伴侣总是会先跟你确认可能的见面日期:
在这个月的通话里,你的伴侣问了你这样一个问题:
你一头雾水,便问什么是“teenth”日。你的伴侣解释说,teenth 日是他们自己编出来的一个概念,指的是一个月里以“-teenth”结尾的那些日期:
由于一周也有七天,因此可以保证,每个月里每个星期几都_恰好_有一个 teenth 日。
现在你已经明白了 teenth 日的概念,便查看自己的日历。teenth 星期四那天你没有别的安排,于是你愉快地和伴侣确认了这个日期。
你的任务是:给定月份、年份、星期几和周次,找出聚会的确切日期。
需要考虑的周次值有六个:first、second、third、fourth、last、teenth。
例如,可能需要你找出 2018 年 1 月的第 1 个星期一的聚会日期(2018 年 1 月 1 日)。
类似地,也可能需要你找出:
teenth 周指的是一个月中以 “-teenth” 结尾的那七天(13 日、14 日、15 日、16 日、17 日、18 日和 19 日)。
如果要找出 1953 年 8 月的 teenth 星期六,我们就查看它的日历:
August 1953
Su Mo Tu We Th Fr Sa
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31
由此可知,teenth 星期六是 1953 年 8 月 15 日。
我们额外增加了一个星期描述符(fifth),用来表示某个月里第五次出现的那个星期几(如果存在的话)。
如果某个月里没有第五次出现的星期几,你应该抛出异常。
有时,你的代码需要同时自定义和raise异常。这时,你始终应该提供一条有意义的错误信息,说明错误的来源。这能让你的代码更易读,对调试也有很大帮助。
自定义异常可以通过新建异常类来创建(详见classes),这些类通常是Exception的子类。
如果你知道错误来源会是某种异常类型的衍生物,可以选择继承 Exception 类下面的某个built in error types。抛出该错误时,你仍然应该附上一条有意义的错误信息。
这个练习要求你创建一个_自定义异常_,当传给meetup()函数的星期名称和数字组合无效时,将其抛出(也就是“抛”)。只有当你自定义了合适的异常、raise 了这些异常,并附上合适的错误信息,测试才会通过。
要自定义一个built-in exception,就创建一个继承自该异常的class。在带消息抛出这个自定义异常时,把消息作为参数传给exception类型:
# subclassing the built-in ValueError to create MeetupDayException
class MeetupDayException(ValueError):
"""Exception raised when the Meetup weekday and count do not result in a valid date.
message: explanation of the error.
"""
def __init__(self, message):
self.message = message
# raising a MeetupDayException
raise MeetupDayException("That day does not exist.")