如何改进我的“生日有效性检查”(Python)笨拙的代码?

2024-04-19 04:56:32 发布

您现在位置:Python中文网/ 问答频道 /正文

我已经编写了一个代码来检查任何生日输入的有效性。由于我是编程新手,经过几个调试步骤后,代码变得非常难看。代码如下:

month_dict = {'jan':'January',
          'feb':'February',
          'mar':'March',
          'may':'May',
          'jul':'July',
          'sep':'September',
          'oct':'October',
          'dec':'December',
          'apr':'April',
          'jun':'June',
          'aug':'August',
          'nov':'November'}

day = int(raw_input ('Enter your birth day: '))
month = raw_input ("Enter your birth month: ")
year_input = int (raw_input ('Enter your birth year: '))

days_31 = ['jan', 'mar', 'may', 'jul', 'aug', 'oct', 'dec']
days_30 = ['apr', 'jun', 'sep', 'nov']
days_28 = ['feb']

def valid_day_finding ():
    global valid_day
    if month_name in days_31:
        if day > 0 and day < 32:
            valid_day = day
        else:
            valid_day = 'invalid'
    elif month_name in days_30:
        if day >= 1 and day <= 30:
            valid_day = day
        else:
            valid_day = 'invalid'
    elif month_name in days_28:
        if year != 'invalid':
            if (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0):
                if day >= 1 and day <= 29:
                    valid_day = day
                else:
                    valid_day = 'invalid'
            else:
                if day >= 1 and day <= 28:
                    valid_day = day
                else:
                    valid_day = 'invalid'
        else:
            valid_day = 'invalid'
    else:
        valid_day = 'invalid'             
def valid_month_finding():   
    global month_name
    if month in month_dict.keys():
        month_name = month
    else:
        month_name = 'invalid'
def valid_year_finding():
    global year
    if year_input > 1900 and year_input <2020:
        year = year_input
    else:
        year = 'invalid'
def birthday_checking():
    if valid_day != 'invalid' and month_name != 'invalid' and year != 'invalid':
        print 'your birthdate is %d - %s - %d' % (valid_day, month_dict[month_name], year)
    else:
        print 'Your Birthday is invalid'
valid_year_finding()    
valid_month_finding()
valid_day_finding()
birthday_checking()

这个代码效率很低。您有什么建议来改进代码?提前谢谢。你知道吗


Tags: and代码nameinputyourifdefdays
1条回答
网友
1楼 · 发布于 2024-04-19 04:56:32

首先,在任何地方都使用相同的约定!不要使用单引号,然后无缘无故地使用双引号。这同样适用于制表符和空格,不过最好使用制表符进行缩进,使用空格进行对齐。那么daymonth,然后是year_input;需要_input吗?不,它只提供命名不一致。你知道吗

其次,在valid_day_finding()中有很多不需要的代码(嗯。。。if year != 'invalid'即使year是整数。你知道吗

第三,你也变得铁板一块了!多点模块化,不要让validate_birthday()什么都用globals。改用参数。而且从不按全局范围返回值,如果它们是布尔值,则不要使用字符串/整数来保存它们!这会引入非常微妙的bug。你知道吗

第四,days_xxxvalidate_birthday之外是无用的,所以他们应该去那里,毕竟应该被命名为months_xxx。。。而且,在浇头方面,month_dict设计得很糟糕。它应该将月份名称映射为整数,而不是更短的月份名称!当然,month_dict处于完全紊乱状态。你知道吗

第五,为了避免太多缩进,在if语句中使用andor等运算符,而不是根据缩进级别比较单个表达式。你知道吗

第六,不要老是重复你自己!你知道吗

因此,考虑到这一点和其他许多微妙的东西,代码可能如下所示:

def validate_birthday(day, month, year):
    month_limits = {
        1:  31,
        2:  28,
        3:  31,
        4:  30,
        5:  31,
        6:  30,
        7:  31,
        8:  31,
        9:  30,
        10: 31,
        11: 30,
        12: 31
        }

    # This won't *ever* be valid! (Negative years mean b.C.)
    if month <= 0 or month > 12 or day <= 0:
            return False

    # The year is leap, so let February 29 be valid
    if (year % 4 == 0 and year % 100 != 0) or year % 400 == 0:
            month_limits[2] += 1

    return day <= month_limits[month]

months = {
    'jan': 1,
    'feb': 2,
    'mar': 3,
    'apr': 4,
    'may': 5,
    'jun': 6,
    'jul': 7,
    'aug': 8,
    'sep': 9,
    'oct': 10,
    'nov': 11,
    'dec': 12       
    }

day = int(raw_input('Enter your birth day: '))
month = months[raw_input('Enter your birth month: ')]
year = int(raw_input('Enter your birth year: '))

print 'Your input birthday is{} valid!'.format("n't" if not validate_birthday(day, month, year) else '')

相关问题 更多 >