测试条件时出现意外结果:检查输入是否以0开头或以数字结尾
我正在学习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