【问题标题】:function tests haven't gone as expected(part of AoC day4)功能测试没有按预期进行(AoC day4 的一部分)
【发布时间】:2021-01-05 18:09:27
【问题描述】:

我写了一个检查数据是否正确的函数。 要求如下:

byr-(出生年份) - 四位数字;至少 1920 年,最多 2002 年。

iyr(发行年份)- 四位数字;至少 2010 年,最多 2020 年。

eyr(到期年份)- 四位数字;至少 2020 年,最多 2030 年。

def check_byr_iyr_eyr(line):
    statement = True
    if line[:3] == "byr":
        if (len(line[line.index(':')+1:]) != 4 or
        1920 > int(line[line.index(':')+1:]) > 2002 ):
            statement = False
    elif line[:3] == "iyr":
        if (len(line[line.index(':')+1:]) != 4 or
        2010 > int(line[line.index(':')+1:]) > 2020 ):
            statement = False
    elif line[:3] == "eyr":
        if (len(line[line.index(':')+1:]) != 4 or
        2020 > int(line[line.index(':')+1:]) > 2030 ):
            statement = False
    return statement


list = ['byr:1919', 'iyr:2010', 'eyr:2021', 'iyr:2019', 'iyr:1933',
        'byr:1946', 'iyr:1919', 'eyr:2005']

for i in list:
    print(check_byr_iyr_eyr(i))

'''
    expected result:
        False
        True
        True
        True
        False
        True
        False
        False
'''

并且检查提供的样本的结果应该类似于多行注释“预期结果”,但不幸的是结果始终为 True。

我不知道我做错了什么 - 条件对我来说似乎很好......

【问题讨论】:

    标签: python function if-statement


    【解决方案1】:

    考虑这一行:

    1920 > val > 2002
    

    结果相同:

    val < 1920 and val > 2002
    

    这意味着 val 小于 1920,又大于 2002,这不可能是真的。

    【讨论】:

      【解决方案2】:

      一个优雅的解决方案,使用过多的if 语句不是 DRY(不要重复自己):

      def check_byr_iyr_eyr(line):
          # split the string on the colon to get the two parts
          prefix, year = line.split(':')
          # getting around python's lack of case statements with a dictionary
          cases = {
              'byr': {'min': 1920, 'max': 2002},
              'iyr': {'min': 2010, 'max': 2020},
              'eyr': {'min': 2020, 'max': 2030},
          }
          # get the corresponding min and max and check if the year is inclusively between them
          # (note the <= instead of <)
          return cases[prefix]['min'] <= int(year) <= cases[prefix]['max']
      
      
      data = ['byr:1919', 'iyr:2010', 'eyr:2021', 'iyr:2019', 'iyr:1933',
              'byr:1946', 'iyr:1919', 'eyr:2005']
      
      for i in data:
          print(check_byr_iyr_eyr(i))
      

      输出:

      False
      True
      True
      True
      False
      True
      False
      False
      

      【讨论】:

        【解决方案3】:

        你的函数有两个问题:

        1. 不要进行复杂的字符串切片来检查它是什么类型,只需执行string in line。它更简单易读。

        2. 正如wim 提到的,表达式5 &gt; x &gt; 7 等价于and 语句。由于 x 不能既小于 5 又大于 7,所以这永远不是 True。请改用x &gt; 7 or x &lt; 5

        以下是具有正确输出的更正代码:

        def check_byr_iyr_eyr(line):
            statement = True
            if "byr" in line:
                if (len(line[line.index(':')+1:]) != 4 or
                int(line[line.index(':')+1:]) > 2002 or 
                int(line[line.index(':')+1:]) < 1920):
                    statement = False
            elif "iyr" in line:
                if (len(line[line.index(':')+1:]) != 4 or
                int(line[line.index(':')+1:]) > 2020 or 
                int(line[line.index(':')+1:]) < 2010):
                    statement = False
            elif "eyr" in line:
                if (len(line[line.index(':')+1:]) != 4 or
                int(line[line.index(':')+1:]) > 2030 or
                int(line[line.index(':')+1:]) < 2020):
                    statement = False
            return statement
        
        
        list = ['byr:1919', 'iyr:2010', 'eyr:2021', 'iyr:2019', 'iyr:1933',
                'byr:1946', 'iyr:1919', 'eyr:2005']
        
        for i in list:
            print(check_byr_iyr_eyr(i))
        
        '''
            expected result:
                False
                True
                True
                True
                False
                True
                False
                False
        '''
        

        查看 Tenacious B 的答案以获得更优雅的解决方案!

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-12-26
          • 2023-01-05
          • 1970-01-01
          • 1970-01-01
          • 2015-02-23
          • 1970-01-01
          • 1970-01-01
          • 2016-08-27
          相关资源
          最近更新 更多