12/4¶
Reminders¶
- PA3 is due Tuesday 12/5
- Final exam will follow the JMU final exam schedule
Avoiding Argument Modification¶
Some of the functions from PA3 take collections as arguments and
include the requirement that the arguments must not be modified. For
example, the wording from the json_to_catalog
docstring is: "This
will return an exact copy of the provided dictionary except for the
following:" It does not say "this will modify the provided dictionary".
Here is an example function that illustrates the issue:
def all_upper(words):
"""Return a list with all words converted to upper-case.
The provided list will not be modified.
Args:
words (list): A list of strings
Returns:
list: A list of upper-case strings
"""
for i in range(len(words)):
words[i] = words[i].upper()
return words
if __name__ == "__main__":
some_words = ["tree", "house"]
up_words = all_upper(some_words)
print(some_words)
print(up_words)
When this code is executed, the output is:
['TREE', 'HOUSE']
['TREE', 'HOUSE']
This is bad! The provided argument, some_words
should not have been modified.
We might try to fix it like this:
def all_upper(words):
"""Return a list with all words converted to upper-case.
The provided list will not be modified.
Args:
words (list): A list of strings
Returns:
list: A list of upper-case strings
"""
words_copy = words # This doesn't actually make a copy! We just have
# two names for the exact same list.
for i in range(len(words)):
words_copy[i] = words[i].upper()
return words_copy
if __name__ == "__main__":
some_words = ["tree", "house"]
up_words = all_upper(some_words)
print(some_words)
print(up_words)
This doesn't help at all. Instead, we need to make a new list object that has the desired contents:
def all_upper(words):
"""Return a list with all words converted to upper-case.
The provided list will not be modified.
Args:
words (list): A list of strings
Returns:
list: A list of upper-case strings
"""
result = []
for word in words:
result.append(word.upper())
return result
if __name__ == "__main__":
some_words = ["tree", "house"]
up_words = all_upper(some_words)
print(some_words)
print(up_words)
This works. Now we'll see:
['tree', 'house']
['TREE', 'HOUSE']
Recursion Practice¶
Complete the following function so that it conforms to the docstring:
from pathlib import Path
def all_files(path):
"""Return the file names of all files that can found under the provided path.
Directory names are not included. This includes all files stored in the provided
directory, plus all of the files in any directories contained in that directory,
and so on. If the argument is itself a path to a file, then that filename will
be returned
Args:
path (str or Path object): the starting path
Returns:
list: A list of string filenames.
"""
p = Path(path) # First convert the file/directory name to a Path object.
# Nothing bad happens if path was already a Path object.
# Useful methods:
# p.is_dir() -- True if p is a directory, false if it is a file.
# p.name -- The name of a file
# p.iterdir() -- All of the entries in the directory p (files and directories).
if __name__ == "__main__":
print(all_files("."))
Quiz Practice¶
Two Practice Canvas Quizzes: