问题
I am doing this problem set, and I cannot get passed the Test Case for when the List is None.
I have tested for almost all the cases, and I have noticed that other users got it right with a code that is very similar to mine, I need help debugging and checking if I am missing a test case in my Conditionals.
The test cases that come back negative are testing to see if the List is None, which I found out by testing in the Python interpreter that it does not necessarily imply empty.
Here is the Code:
def likes(names):
for i in names:
if not names:
return "no one likes this"
elif len(names) <= 0:
return "no one likes this"
elif len(names) == 1:
text = "{} likes this"
return text.format(names[0])
elif names == None:
return "no one likes this"
elif len(names) > 2 and len(names) <= 4 and len(names) != 3:
additional = len(names) - 2
text = "{}, {} and {} others like this"
return text.format(names[0], names[1], additional)
elif len(names) > 2 and len(names) > 4 and len(names) != 3:
additional = len(names) - 2
text = "{}, {} and {} others like this"
return text.format(names[0], names[1], additional)
elif len(names) == 2:
text = "{} and {} like this"
return text.format(names[0], names[1])
elif len(names) == 3:
text = "{}, {} and {} like this"
return text.format(names[0], names[1], names[2])
else:
text = "{} likes this"
return text.format(names[0])
回答1:
I am not sure what you are trying to do with the for i in names: line in your code. I assume you are trying to iterate through the list of names. If this is the case, I would change the line to for name in names:.
Keep in mind that list = None is different from list = []. When list = None, list is undefined. On the other hand, list = [] signifies an empty list.
Here is an example that may be helpful.
def checkListVal(valList):
# Checks to see if valList stores some data
if valList == None:
print("valList is undefined")
# Returns out of this function
return
# Checks to see if the list is empty
if len(valList) == 0:
print("valList is empty")
return
for val in valList:
if val == "val1":
print("val1 in valList")
elif val == "val2":
print("val2 in valList")
else:
print("val equals " + val)
valList1 = ["val1", "val2", "val3"]
valList2 = []
valList3 = None
checkListVal(valList1)
print()
checkListVal(valList2)
print()
checkListVal(valList3)
The output is as follows:
val1 in valList
val2 in valList
val equals val3
valList is empty
valList is undefined
回答2:
Thanks to @JohnGordon, I only needed to remove the for loop around the conditionals, it works just fine
def likes(names):
if not names:
return "no one likes this"
elif len(names) <= 0:
return "no one likes this"
elif len(names) == 1:
text = "{} likes this"
return text.format(names[0])
elif names == None:
return "no one likes this"
elif len(names) > 2 and len(names) <= 4 and len(names) != 3:
additional = len(names) - 2
text = "{}, {} and {} others like this"
return text.format(names[0], names[1], additional)
elif len(names) > 2 and len(names) > 4 and len(names) != 3:
additional = len(names) - 2
text = "{}, {} and {} others like this"
return text.format(names[0], names[1], additional)
elif len(names) == 2:
text = "{} and {} like this"
return text.format(names[0], names[1])
elif len(names) == 3:
text = "{}, {} and {} like this"
return text.format(names[0], names[1], names[2])
else:
text = "{} likes this"
return text.format(names[0])
回答3:
The main issue is that if None is a possible argument, the for loop will crash. As mentioned in the comments, this loop isn't relevant to the logic anyway because it simply returns on the first iteration. We're only interested in properties about the length of the list (if it exists), not its elements, so remove the loop.
Having said that, the logic here is extremely confusing and there are many redundant branches. Conditionals that have more than 3 or 4 branches or nesting greater than a couple levels are difficult to reason about and should be eliminated.
The branch
elif len(names) > 2 and len(names) > 4 and len(names) != 3:can be simplified to
elif len(names) > 4because iflen(names)is greater than 4, we know for sure it's definitely!= 3and> 2.The branch
if not names:covers casesnames is Noneas well aslen(names) <= 0(the<is unnecessary here), so we can toss out two more branches.The branch
elif len(names) > 2 and len(names) <= 4 and len(names) != 3:is the same as
elif len(names) == 4.
Taking a step back, there are only 5 cases:
- we have no names
- we have 1 name
- we have 2 names
- we have 3 names
- we have 4 or more names
Here's a re-write to express this clearly:
def likes(names):
if not names:
return "no one likes this"
elif len(names) == 1:
return f"{names[0]} likes this"
elif len(names) == 2:
return f"{names[0]} and {names[1]} like this"
elif len(names) == 3:
return f"{names[0]}, {names[1]} and {names[2]} like this"
return f"{names[0]}, {names[1]} and {len(names) - 2} others like this"
if __name__ == "__main__":
names = ["alice", "bob", "carol", "doug", "eric", "fred"]
print("None =>", likes(None))
for i in range(len(names)):
print(names[:i], "=>", likes(names[:i]))
Output:
None => no one likes this
[] => no one likes this
['alice'] => alice likes this
['alice', 'bob'] => alice and bob like this
['alice', 'bob', 'carol'] => alice, bob and carol like this
['alice', 'bob', 'carol', 'doug'] => alice, bob and 2 others like this
['alice', 'bob', 'carol', 'doug', 'eric'] => alice, bob and 3 others like this
来源:https://stackoverflow.com/questions/59201962/how-to-check-if-a-list-argument-is-none