CS50 Python Week3 pset 问题“过时” - 如何拒绝输入而不是重新提示

问题描述 投票:0回答:1

当我遇到这个问题时,我正在做 CS50 的 week3 pset 问题。整个问题如下:

在美国,日期通常采用月-日-年格式 order (MM/DD/YYYY),也称为中端顺序,即 可以说是糟糕的设计。该格式的日期无法轻松排序 因为日期的年份出现在最后而不是第一个。尝试排序,对于 例如,2/2/1800、3/3/1900 和 1/1/2000(按时间顺序) 程序(例如电子表格)。该格式的日期也是 模糊的。哈佛大学成立于 1636 年 9 月 8 日,但 9/8/1636 也可以解释为 1636 年 8 月 9 日!

幸运的是,计算机倾向于使用 ISO 8601 这一国际标准 规定日期应采用年月日格式 (YYYY-MM-DD) 顺序,无论哪个国家/地区,将年份格式化为四 数字、两位数月份和两位数日,“填充” 每个都根据需要带有前导零。

在名为 outdated.py 的文件中,实现一个程序,提示 用户输入日期,anno Domini,按月日年顺序,格式如下 9/8/1636 或 1636 年 9 月 8 日,其中后者的月份可能 可以是下面列表中的任何值:

[ “一月”, “二月”, “行进”, “四月”, “可能”, “六月”, “七月”, “八月”, “九月”, “十月”, “十一月”, 《十二月》]

然后以 YYYY-MM-DD 格式输出相同的日期。如果用户输入的日期不是任一格式的有效日期,则提示用户 再次。假设每个月不超过31天;无需 验证一个月是否有 28、29、30 或 31 天。

我编写了代码,当我运行 check50 来检查我的答案时,此图中显示了一些输入失败 enter image description here 显然,如果日期或月份超出范围,我的代码应该重新提示,但如果整个格式错误,则需要拒绝

mth = [
    "January",
    "February",
    "March",
    "April",
    "May",
    "June",
    "July",
    "August",
    "September",
    "October",
    "November",
    "December"
]

def check(d):

    if "/" in d:
        numeric(d)
    else:
        words(d)

def numeric(d):
    
    list = d.split("/")
    month = int(list[0])
    day = int(list[1])
    year = int(list[2])

    while True:
        if month > 12 or day > 31:
            date = input("Date: ")
            check(date)
        else:
            break

    print(f"{year}-{str(month).zfill(2)}-{str(day).zfill(2)}")

def words(d):

    list = d.split(" ")
    month = list[0]
    day = list[1]
    year = list[2]

    while True:
        if not str(month).title() in mth:
            date = input("Date: ")
            check(date)
        else:
            index = mth.index(month)
            day = str(day).strip(",")
            break

    while True:
        if int(day) > 31:
            date = input("Date: ")
            check(date)
        else:
            break

    print(f"{year}-{str(index+1).zfill(2)}-{str(day).zfill(2)}")

date = input("Date: ")
check(date)

这是我到目前为止写的代码,我假设我需要添加一些东西,比如如果 d.isalpha() 在函数 numeric() 中为 true,则引发异常,但我尝试过,但它不起作用(也许我使用了错误的筹集方式)。我想知道如何解决这个问题并拒绝输入。真的很感激:)

python function exception try-catch cs50
1个回答
0
投票

我相信您的代码在“October/9/1701”失败的原因是它抛出异常而不是重新提示用户。 “/”分隔符将处理月份的代码标记为

int()
,并且
int("October")
抛出
ValueError

请注意,还有很多其他事情也可能抛出

ValueError
,因此您可能只想让任何验证失败都抛出它。

我可以尝试:

def try_parse_date(date_string):
    valid_month_names = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]

    ## -------------------
    ## Try to pick out the year, month, and day
    ## -------------------
    if "/" in date_string:
        month, day, year = date_string.split("/")
    else:
        month, day, year = date_string.split(" ")
        month = valid_month_names.index(month) + 1
        day = day.strip(",")
    ## -------------------

    ## -------------------
    ## Do some validation
    ## -------------------
    year = int(year)
    month = int(month)
    day = int(day)

    if year < 1:  # https://en.wikipedia.org/wiki/Anno_Domini
        raise ValueError

    if not (0 < month < 13):
        raise ValueError

    if not (0 < day < 32):
        raise ValueError
    ## -------------------

    return f"{year:>04}-{month:>02}-{day:>02}"

def prompt_for_date_until_valid():
    while True:
        user_date_string = input("Date: ")
        try:
            return try_parse_date(user_date_string)
        except ValueError:
            pass

iso_date = prompt_for_date_until_valid()
print(iso_date)

注意:对于尚未为该课程创建一次性帐户的任何人来说,使用 cs50.dev 是一个巨大的安全问题,因为它需要访问 private Github 存储库。

© www.soinside.com 2019 - 2024. All rights reserved.