CS1101 Discussion Assignment Unit 5 - Does the following program actually check whether its argument has any lowercase letters?

Questions

This assignment is based on Exercise 8.4 from your textbook. Each of the following Python functions is supposed to check whether its argument has any lowercase letters.

For each function, describe what it actually does when called with a string argument. If it does not correctly check for lowercase letters, give an example argument that produces incorrect results, and describe why the result is incorrect.

1. Program 1

1.1. Codes

1
2
3
4
5
6
def any_lowercase1(s):
for c in s:
if c.islower():
return True
else:
return False

1.2. What the code actually does

Check whether the first letter of the string is uppercase or lowercase.

1.3. The argument that produces incorrect results

The argument:

1
"Abc"

The test statement and incorrect output:

1
2
>>> print(any_lowercase1("Abc"))
False

1.4. The reasons for the incorrect result

As seen from the above call statement, when I pass a parameter “Abc” to the function, the return value is False. In theory, the argument contains lowercase letters b and c, and the return value should be True, but the function returned False.

The reason is that the function only checks the first character in the string. After judging whether the first character is uppercase or lowercase, the function returns the value and ends the program, causing subsequent characters in the string not to be checked.

2. Program 2

2.1. Codes

1
2
3
4
5
6
def any_lowercase2(s):
for c in s:
if 'c'.islower():
return 'True'
else:
return 'False'

2.2. What the code actually does

Check whether the string ‘c’ is a lowercase letter, and because ‘c’ is a lowercase letter, the function will always return the string ‘True’, regardless of the input argument.

2.3. The argument that produces incorrect results

The argument:

1
"AAA"

The test statement and incorrect output:

1
2
3
4
5
>>> result = any_lowercase2("AAA")
>>> print(result)
True
>>> print(type(result))
<class 'str'>

2.4. The reasons for the incorrect result

As seen from the above call statement, when I pass a parameter “AAA” to the function, the return value is True and its type is a str. In theory, the argument are all uppercase letters, and the return value should be a bool value False, but the function returned a string ‘True’.

The reason is that the string ‘c’ is a lowercase letter, so ‘c’.islower() is always True, and the statement return ‘True’ will always be executed, leading to the function always return the string ‘True’.

The first point to note is the difference between ‘c’ and c. The ‘c’ is a lowercase string, and the c in the statement “for c in s” is a variable named c. You can assign each letter in s to the variable c. Because the ‘c’ is a lowercase string, therefore, the boolean expression ‘c’.islower() is always True, so the branch return “True” will always be executed and return the string ‘True’.

The second point to note is the difference between ‘True’ and True. ‘True’ is a string, and True is a boolean value. The function’s return value is a string of ‘True’, not a Boolean value of True. We can use the type function to view the output value’s type, and you will find that the type of ‘True’ is str, not bool.

3. Program 3

3.1. Codes

1
2
3
4
def any_lowercase3(s):
for c in s:
flag = c.islower()
return flag

3.2. What the code actually does

Check whether the last letter of the argument is lowercase.

3.3. The argument that produces incorrect results

The argument:

1
"abC"

The test statement and incorrect output:

1
2
>>> print(any_lowercase3("abC"))
False

3.4. The reasons for the incorrect result

As seen from the above call statement, when I pass a parameter “abC” to the function, the return value is False. In theory, the argument contains lowercase letters a and b, and the return value should be True, but the function returned False.

The reason is as follows. When traversing the string s, the value of the flag is continually updated. The following value overwrites the previous value. The return value is whether the last letter of the string is a lowercase letter or an uppercase one.

4. Program 4

4.1. Codes

1
2
3
4
5
def any_lowercase4(s):
flag = False
for c in s:
flag = flag or c.islower()
return flag

4.2. What the code actually does

Check whether the argument has any lowercase letters

4.3. The argument that produces incorrect results

The argument:

1
2
3
4
5
6
7
8
9
"Abc"
"aBc"
"abC"
"aBC"
"AbC"
"ABc"
"abc"
"ABC"
""

The test statement and incorrect output:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# There is only one lowercase letter in the argument
print(any_lowercase4("aBC")) # True
print(any_lowercase4("AbC")) # True
print(any_lowercase4("ABc")) # True

# There are two lowercase letters in the argument
print(any_lowercase4("Abc")) # True
print(any_lowercase4("aBc")) # True
print(any_lowercase4("abC")) # True

# There are three lowercase letters in the argument
print(any_lowercase4("abc")) # True

# There is no lowercase letter in the argument
print(any_lowercase4("ABC")) # False
print(any_lowercase4("")) # False

4.4. The reasons for the incorrect result

As seen from the above call statement, the return value is True when I pass a argument that includes a lowercase letter. The return value is False when I pass a argument that does not include a lowercase letter. So, this code is correct.

The reason is as follows. If two expressions are connected by the logical operator or, as long as one of the expressions is True, the result of the entire expression is True. Therefore, for the expression flag or c.islower(), as long as there is a lowercase letter in the argument, the value of c.islower() is True, so the value of the expression flag or c.islower() is True, so this code is correct, and it can check whether the argument has any lowercase letters.

5. Program 5

5.1. Codes

1
2
3
4
5
def any_lowercase5(s):
for c in s:
if not c.islower():
return False
return True

5.2. What the code actually does

Check whether the argument has any uppercase letters. If there are uppercase letters, it returns False. Otherwise, it returns True.

5.3. The argument that produces incorrect results

The argument:

1
"abC"

The test statement and incorrect output:

1
2
>>> print(any_lowercase3("abC"))
False

5.4. The reasons for the incorrect result

The logical operator not is a negation operator. So as long as there are uppercase characters, the value of the expression not c.islower() is True, and then the function returns False and ends. So the code can check whether the argument has any uppercase letters. If there are uppercase letters, it returns False. Otherwise, it returns True.

Word count: 979

References

1.Downey, A. (2015). Think Python. Green Tea Press.
https://greenteapress.com/thinkpython2/thinkpython2.pdf

​


This is the ending, thanks for reading.