测试条件时出现意外结果:检查输入是否以0开头或以数字结尾

0 投票
1 回答
59 浏览
提问于 2025-04-14 18:35

我正在学习Python,最近在解决一个问题。这个问题的目标是检查一个字符字符串是否符合以下条件:

  • 至少包含2个字符,最多6个字符
  • 以2个字母开头
  • 如果包含数字,这些数字必须放在字符串的最后
  • 数字不能以0开头
  • 字符串中不能有标点符号

根据我的理解,代码中只有两个部分出现了问题,所以我只展示这两个问题:

我的代码如下:

def number_end_plate(s):
    if s.isalpha():
        return False
    else:
       number = ""
       for char in s:
           if char.isnumeric():
               number = number + char
           else:
               number = number
           result = number.startswith("0")
           return(result)

# Function "number_end_plate" checks if the numbers starts with zero. If "True" then this will be rejected in the above function

def numbers_after_letter(s):
    if s.isalpha():
        return True
    elif len(s) == 4 and s == s[3:4].isnumeric():
         return True
    elif len(s) == 4 and s == s[3:3].isalpha() and s == s[4:4].isnumeric():
         return True
    elif len(s) == 5 and s == s[3:5].isnumeric():
         return True
    elif len(s) == 5 and s == s[3:4].isalpha() and s == s[5:5].isnumeric():
         return True
    elif len(s) == 5 and s == s[3:3].isalpha() and s == s[4:5].isnumeric():
         return True
    elif len(s) == 6 and s == s[3:6].isnumeric():
        return True
    elif len(s) == 6 and s == s[3:3].isalpha() and s == s[4:6].isnumeric():
        return True
    elif len(s) == 6 and s == s[3:4].isalpha() and s == s[5:6].isnumeric():
        return True
    elif len(s) == 6 and s == s[3:5].isalpha() and s == s[6:6].isnumeric():
        return True

#Function checks if the numbers (if any) are always at the end of the string

我在以下测试中失败了,我不明白为什么结果是“无效”:

  • AK88
  • ECZD99
  • IKLMNV

1 个回答

1

你的代码有很多问题和不一致的地方,但你问题的答案在这个函数里:

def number_end_plate(s):
    if s.isalpha():
        return False
    else:
       number = ""
       for char in s:
           if char.isnumeric():
               number = number + char
           else:
               number = number
           result = number.startswith("0")
           return(result)

返回语句缩进在for循环里面,所以它只会执行一次。而且它到底要检查什么也不太清楚。看起来是要检查车牌是否以数字结尾,但你用的是这样的代码:and number_end_plate(s) == False——所以,显然以数字结尾的车牌应该总是无效的?

这和你提供的描述不符。然后你有一个非常复杂的函数, supposedly 用来检查字符串末尾是否都是数字。

你代码的其他问题包括空格(代码之间的垂直空白,以及更糟糕的不一致缩进),拼写错误(在名称中),函数的工作方式不一致(有时候简洁直接返回结果,有时候又是冗长的if语句),还有可能有更多逻辑错误,超出了我上面提到的。

修复这些问题,同时保持你程序的整体结构(虽然还是很啰嗦),你最终会得到这样的代码:

import string


def main():
    plate = input("Plate: ")
    if is_valid(plate):
        print("Valid")
    else:
        print("Invalid")


def is_valid(s):
    return valid_length(s) and starts_alpha(s) and no_punctuation(s) and number_end_plate(s)


def valid_length(s):
    return 2 <= len(s) <= 6


def starts_alpha(s):
    return s[0:2].isalpha()


def no_punctuation(s):
    return not any(character in string.punctuation for character in s)


def number_end_plate(s):
    found_number = False
    for ch in s:
        if ch.isdigit():
            if not found_number:
                if ch == '0':
                    # the first number cannot be a 0
                    return False
            found_number = True
        else:
            if found_number:
                # if there's something that's not a number after a number
                return False
    # at this point, the text is valid
    return True


main()

补充:你问number_end_plate(s)到底是怎么工作的,这里有逐行解释和注释:

def number_end_plate(s):
    # found_number represents whether we've found any number so far
    # it starts `False` because we haven't found one yet
    found_number = False

    # `ch` will go over every character in `s`
    for ch in s:
        # if we run into a digit (0-9) ...
        if ch.isdigit():
            # then, if we haven't found a number yet ...
            if not found_number:
                # then, if the number we found is a zero ...
                if ch == '0':
                    # then the first number is a zero, and that's not allowed
                    return False  # this stops the execution, and returns False

            # in any case, if we keep going, remember we found a number
            found_number = True
        else:
            # otherwise (if `ch` is not a digit),
            # if we previously found a number
            if found_number:
                # then, this means there's 'not a number' after a number
                return False

    # if we get here, we've looped through all characters without returning False
    # that means none of the conditions we were looking for arose
    # and the string is valid for the condition that numbers are at then end
    # and the first number is not a 0 (or there are no numbers at all)
    return True

撰写回答