Function 1
def any_lowercase1(s):
for c in s:
if c islower():
return True
else:
return False
Explanation
This function evaluates only the first letter. It returns True for a lowercase first letter and
False for any other first letter regardless of what the remainder of the string has.
Incorrect Behavior Example
any_lowercase1("ABCd") # Returns False
Even though "d" is in lowercase it is never evaluated because the function returns after
evaluating "A".
Why it's Incorrect;
The return in the loop returns the result of the first stop (the first letter) and hence any
lowercase letters later in the string are ignored
Function 2
def any_lowercase2(s):
for c in s:
if 'c'.islower():
return 'True'
else:
return 'False'
Explanation
This function evaluates whether the string literal 'c' is a lowercase in each iteration, and it
evaluates to True every time. It returns the string 'True', instead of returning the Boolean
True.
Incorrect Behavior Example
any_lowercase2("XYZ") # Returns 'True'
Why it's Incorrect
Does not evaluate the actual character c from the string. Also, returns string 'True' or string
'False', rather than returning Boolean. This will lead to misleading results during logic checks.
Function 3
def any_lowercase3(s):
for c in s:
flag = c.islower()
return flag
Explanation
This function iterates through the string, but keeps just the result of the last character.
Incorrect Behavior Example
any_lowercase3("ABCd") # Returns True
any_lowercase3("abCD") # Returns False
Why it's incorrect
The variable flag is rewritten in each loop. Therefore, the result is part of the evaluation of the
last character.
Function 4
def any_lowercase4(s):
flag = False
for c in s:
flag = flag or c.islower()
return flag
Explanation
This function works correctly. It will know any of the characters in the string is lowercase. It
will use logical or to keep a True if any c.islower() is True.
Correct Behavior Example
any_lowercase4("ABCd") # Returns True
any_lowercase4("ABCD") # Returns False
Why it's correct
Flag becomes True when a lowercase letter is found, and remains True. This is the right logic
for this check.
Function 5
def any_lowercase5(s):
for c in s:
if not c.islower():
return False
return True
Explanation
This function checks if all characters are lowercase (and returns False when merging to
character that is not lowercase) vs. if any character is lowercase.
Incorrect Behavior Example
any_lowercase5("abcD") # Returns False
any_lowercase5("abc") # Returns True
any_lowercase5("ABCd") # Returns False
Why it's incorrect
The logic checks all characters being lowercase which is a different condition (i.e.,
str.islower() on the string). Additionally, the name of the function could be misleading.
Summary Comparison Table
Function Checks Only First? Logic Correct? Returns Boolean? Issue
any_lowercase1 Yes No Yes Returns on
first character
any_lowercase2 No No No Tests string 'c'
not variable c, returns string
any_lowercase3 No No Yes Only checks
the last character
any_lowercase4 No Yes Yes Correct logic
and behavior
any_lowercase5 No No Yes Checks if all are
lowercase
Conclusion
Out of the five, only any_lowercase4 correctly implements the logic of checking any
character in a string being lowercase. Through the journey on this check, I saw the
importance of understanding how loops behaved and how short-circuit logic worked in
conjunction with the potential placement of return statements in Python functions. A beginner
could confuse the any vs. all conditions as they use similar syntax and result. This reinforces
the importance in beginner curriculum of understanding Boolean logic and control flow in
Python.
Discussion Question:
Why do you think it is important to be careful about the placement of the return statement
inside loops and how does placement affect the correctness of your function in Python?
Reference
Downey, A. (2015). Think Python: How to think like a computer scientist (2nd ed.). Green
Tea Press. https://greenteapress.com/wp/think-python-2e/