CS5001 / CS5003:
Intensive Foundations of Computer Science

# Lecture 6: Lab Review

• Let's first talk about last week's lab on Facebook and the Seven Dwarfs

I didn't mean for you to write the `get_choice()` function -- oops! But, here is the sample output, and it should be straightforward to figure out how to write the function:

``````def get_choice():
"""
Ask the user to make a selection between Print friend list, Add a friend,
Unfriend someone, and Quit
:return: 'p', 'a', 'u', or 'q'
"""``````

# Lecture 6: Lab Review

• Let's first talk about last week's lab on Facebook and the Seven Dwarfs
``````def get_choice():
"""
Ask the user to make a selection between Print friend list, Add a friend,
Unfriend someone, and Quit
:return: 'p', 'a', 'u', or 'q'
"""
print("\tP: Print a friend list")
print("\tU: Unfriend Someone")
print("\tQ: Quit")
choice = ''
while choice not in ['p', 'a', 'u', 'q']:
choice = input("Your selection? (P/A/U/Q): ").lower()
return choice``````
• The `'\t'` means "tab" (you could have put a couple of spaces)
• It is nice to let the user put upper- or lowercase letters, so we just convert the choice to lowercase using the string's .lower() function.

# Lecture 6: Lab Review

• Here is the read_friends() docstring:
``````def read_friends(filename):
"""
with each dwarf as the keys, and a list of dwarfs as the value,
representing the dwarf's friends.
The file should be formatted as follows:

dwarf_name1 friend1 friend2 friend3 ...
dwarf_name2 friend1 friend2 friend3 ...
...

The names will be space-separated.

A particular Dwarf's dict key/value might look like this:
dwarf_friends = {
'Happy': ['Dopey', 'Bashful', 'Sneezy', 'Sleepy', 'Doc', 'Grumpy'],
}

:param filename: The file name of the file to read from
:return: A dict of dwarf friends
"""
database = {}
try:
with open(filename, "r") as f:
pass
return database
except FileNotFoundError:
print(f"Could not open the database file, '{filename}'")
return None
``````

We need to read in the space separated words, with the first as the key and the rest as the friends.

# Lecture 6: Lab Review

``````def read_friends(filename):
database = {}
try:
with open(filename, "r") as f:
for line in f:
line = line[:-1]  # remove newline
dwarfs = line.split(' ')  # space separated
database[dwarfs[0]] = dwarfs[1:]  # add first as key, rest as friends
return database
except FileNotFoundError:
print(f"Could not open the database file, '{filename}'")
return None``````
• Use slices when you can!
• Use the string's `.split()` method when you have data that is separated by a particular character
• Know how to add to a dictionary:
• d[key] = value

# Lecture 6: Lab Review

``````def print_friends(friend_database, dwarf):
"""
Prints out the friends for a particular dwarf from friend_database. The list
should print as follows, for example:
Dopey
Bashful
Sneezy
Sleepy
Doc
Grumpy

:param friend_database The database of friends
:param dwarf: The dwarf whose friends will get printed
:return: True if the dwarf is in the database, False otherwise
"""
pass
``````
• The `print_friends()` function:

# Lecture 6: Lab Review

``````def print_friends(friend_database, dwarf):
"""
Prints out the friends for a particular dwarf from friend_database. The list
should print as follows, for example:
Dopey
Bashful
Sneezy
Sleepy
Doc
Grumpy

:param friend_database The database of friends
:param dwarf: The dwarf whose friends will get printed
:return: True if the dwarf is in the database, False otherwise
"""
friend_list = friend_database[dwarf] # get friend list from database
for friend in friend_list:
print(friend)
``````
• The `print_friends()` function:

# Lecture 6: Lab Review

``````def add_friend(friend_database, dwarf, new_friend):
"""
Adds new_friend to the dwarf's friend list, but only if the friend is not
:param friend_database:
:param dwarf: The dwarf who is adding a new friend
:param new_friend: The new friend to add
:return: True if the friend was added, False otherwise
"""
pass``````
• The `add_friend()` function:

# Lecture 6: Lab Review

``````def add_friend(friend_database, dwarf, new_friend):
"""
Adds new_friend to the dwarf's friend list, but only if the friend is not
:param friend_database:
:param dwarf: The dwarf who is adding a new friend
:param new_friend: The new friend to add
:return: True if the friend was added, False otherwise
"""
friend_list = friend_database[dwarf] # get friend list from database
if new_friend in friend_list:
return False
else:
friend_list.append(new_friend)
return True``````
• The `add_friend()` function:
• Don't add the friend again if they are already in the list!
• Note that you actually get a reference to the friend list, so you can add the friend directly to the list and don't have to re-populate the original database (line 15)

# Lecture 6: Lab Review

``````def unfriend(friend_database, dwarf, current_friend):
"""
Unfriends current_friend from dwarf's friend list.
:param friend_database: The database of friends
:param dwarf: The dwarf whose friend will be unfriended
:param current_friend: The friend of the dwarf who will be unfriended
:return: True if the dwarf had the friend, False if the dwarf did not
have the friend
"""
pass``````
• The `unfriend()` function:

Let's use try/except! How does a list removal fail? I don't know -- let's check:

``````>>> a = [1,5,7]
>>> a.remove(5)
>>> a.remove(2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: list.remove(x): x not in list``````

It looks like we have a ValueError.

# Lecture 6: Lab Review

``````def unfriend(friend_database, dwarf, current_friend):
"""
Unfriends current_friend from dwarf's friend list.
:param friend_database: The database of friends
:param dwarf: The dwarf whose friend will be unfriended
:param current_friend: The friend of the dwarf who will be unfriended
:return: True if the dwarf had the friend, False if the dwarf did not
have the friend
"""
friend_list = friend_database[dwarf] # get friend list from database
try:
friend_list.remove(current_friend)
return True
except ValueError:
return False``````
• The `unfriend()` function:
• With `try/except` it is a very straightforward function.

# Lecture 6: Lab Review

``````def save_friends(friend_database, filename):
"""
Saves friend_database to filename
:param friend_database: The friend database
:param filename: The file to save the database to
:return: True if the database was saved, False otherwise
"""
pass``````
• The `save_friends()` function:
• We will overwrite the filename

# Lecture 6: Lab Review

• The `save_friends()` function:
• This is the "one-liner" write statement, but you have to understand a few things:
• Adding two lists together concatenates them (and we have to create a list out of the dwarf by surrounding it with brackets)
• The join function with a space puts the space between all the values
• Adding two strings concatenates the strings
• That's a lot to do in one line! Let's make it a bit more verbose (but okay)
``````def save_friends(friend_database, filename):
"""
Saves friend_database to filename
:param friend_database: The friend database
:param filename: The file to save the database to
:return: True if the database was saved, False otherwise
"""
try:
with open(filename, "w") as f:
for dwarf, friends in friend_database.items():
f.write(" ".join([dwarf] + friends) + '\n')
return True
except FileNotFoundError:
return False``````

# Lecture 6: Lab Review

``````def save_friends(friend_database, filename):
"""
Saves friend_database to filename
:param friend_database: The friend database
:param filename: The file to save the database to
:return: True if the database was saved, False otherwise
"""
try:
with open(filename, "w") as f:
for dwarf, friends in friend_database.items():
f.write(dwarf)
f.write(" ")
for friend in friends[:-1]:  # handle last as special case (no space)
f.write(friend)
f.write(" ")
f.write(friends[-1])  # last does not have a space
f.write("\n")  # but it does have a newline
return True
except FileNotFoundError:
return False``````
• The `save_friends()` function:
• This is more verbose, but easier to understand if you go one line at a time

# Lecture 6: Course Recap - what have we covered?

• Here are the topics that we have covered so far, and that will be on the midterm next Tuesday. There has been a lot to learn!
• Week 1:
• Arithmetic, Variables, The Python REPL
• Week 2:
• Functions, Doctests, Passing values to functions, Branching
• Week 3:
• Iteration, Lists
• Week 4:
• Tuples, List slicing, List comprehensions, Strings
• Week 5:
• Recursion and Dictionaries
• ​Week 6:
• ​File processing and exception handling

# Lecture 6: Course Recap - what have we covered?

• Week 1: Arithmetic, Variables, The Python REPL
• Sample arithmetic midterm question:
• Write a function that has three parameters `a`, `b`, and `c`, and returns `a` multiplied by `b` and then added to `c`:
``````def linear_combination(a, b, c):
"""
:return The value of a multiplied by b and added to c
"""
pass``````

# Lecture 6: Course Recap - what have we covered?

• Week 1: Arithmetic, Variables, The Python REPL
• Sample arithmetic midterm question:
• Write a function that has three parameters `a`, `b`, and `c`, and returns `a` multiplied by `b` and then added to `c`:
``````def linear_combination(a, b, c):
"""
:return The value of a multiplied by b and added to c
"""
return a * b + c``````

# Lecture 6: Course Recap - what have we covered?

• Week 1: Arithmetic, Variables, The Python REPL
• Sample variables and REPL question:
• Multiple choice: What is the next line in the REPL going to print?
``````>>> def first_and_last(lst):
...   first = lst[0]
...   last = lst[-1]
...   return (first, last)
...
>>> result = first_and_last([5,10,15,20])
>>> print(result)
(5, 20)
>>> print(first)``````
1. ```5 >>>```
2. ```10 >>>```
3. ```[5, 10, 15, 20] >>>```
4. ```Traceback (most recent call last):   File "<stdin>", line 1, in <module> NameError: name 'first' is not defined >>>```

# Lecture 6: Course Recap - what have we covered?

• Week 1: Arithmetic, Variables, The Python REPL
• Sample variables and REPL question:
• Multiple choice: What is the next line in the REPL going to print?
``````>>> def first_and_last(lst):
...   first = lst[0]
...   last = lst[-1]
...   return (first, last)
...
>>> result = first_and_last([5, 10, 15, 20])
>>> print(result)
(5, 20)
>>> print(first)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'first' is not defined
>>>``````
• The answer was (D). This is something we probably didn't go over enough -- variables inside a function are local, and are not available outside the function (this is called scoping).
• In other words: you cannot access a variable defined in another function. This is a good thing! It means that you can use as many variables inside a function, and when you use the function, you don't have to know those names.

# Lecture 6: Course Recap - what have we covered?

• Week 2: Functions, Doctests, Passing values to functions, Branching
``````def mystery_func(n):
if n < 2:
return False
for i in range(2, n):
if n % i == 0:
return False
return True

def main():
count = 0
lst = [2, 3, 4]
for num in lst:
if mystery_func(num):
count += 1

if count == 0:
print("None")
elif count < len(lst):
print("Some")
else:
print("All")

if __name__ == "__main__":
main()``````
• Lots of potential functions questions.
• You should be able to write a doctest for any function that does not have user input, open a file, etc.
• Sample functions question (this would be a challenging problem)

A. What does `mystery_func` do?

B. Write a non-trivial doctest for mystery_func.

C. What does main() print out for this program?

# Lecture 6: Course Recap - what have we covered?

• Week 2: Functions, Doctests, Passing values to functions, Branching
``````def mystery_func(n):
if n < 2:
return False
for i in range(2, n):
if n % i == 0:
return False
return True

def main():
count = 0
lst = [2, 3, 4]
for num in lst:
if mystery_func(num):
count += 1

if count == 0:
print("None")
elif count < len(lst):
print("Some")
else:
print("All")

if __name__ == "__main__":
main()``````

A. What does `mystery_func` do?

B. Write two non-trivial doctests for mystery_func.

C. What does main() print out for this program?

To solve this problem, I suggest trying a few numbers in the function, and going through each line. Let's try mystery_func(5):

• n is 5, and is not less than 2, so skip line 3
• On line 4, the range is 2,3,4
• On line 5, when i==2,  5 % 2 is 1, so we continue in the loop:
• when i==3,  5 % 3 is 1, so we continue in the loop
• when i==4,  5 % 4 is 1, so we finish the loop
• ​The loop is complete, so we return True

# Lecture 6: Course Recap - what have we covered?

• Week 2: Functions, Doctests, Passing values to functions, Branching
``````def mystery_func(n):
if n < 2:
return False
for i in range(2, n):
if n % i == 0:
return False
return True

def main():
count = 0
lst = [2, 3, 4]
for num in lst:
if mystery_func(num):
count += 1

if count == 0:
print("None")
elif count < len(lst):
print("Some")
else:
print("All")

if __name__ == "__main__":
main()``````

A. What does `mystery_func` do?

B. Write two non-trivial doctests for mystery_func.

C. What does main() print out for this program?

Let's try mystery_func(9):

• n is 9, and is not less than 2, so skip line 3
• On line 4, the range is 2,3,4,5,6,7,8
• On line 5, when i==2,  9 % 2 is 1, so we continue in the loop:
• when i==2,  9 % 3 is 0, so we return False

Based on mystery_func(3) returning True and mystery_func(9) returning False, can you figure out what the function is doing? If not, try some more:

mystery_func(2) returns False,  mystery_func(3) returns True,  mystery_func(4) returns False,   mystery_func(6) returns False,  mystery_func(7) returns True.

# Lecture 6: Course Recap - what have we covered?

• Week 2: Functions, Doctests, Passing values to functions, Branching
``````def mystery_func(n):
if n < 2:
return False
for i in range(2, n):
if n % i == 0:
return False
return True

def main():
count = 0
lst = [2, 3, 4]
for num in lst:
if mystery_func(num):
count += 1

if count == 0:
print("None")
elif count < len(lst):
print("Some")
else:
print("All")

if __name__ == "__main__":
main()``````

A. What does `mystery_func` do?

B. Write two non-trivial doctests for mystery_func.

C. What does main() print out for this program?

At this point, hopefully you can see that the function returns whether or not n is prime.

The doctests:

``````def mystery_func(n):
"""
>>> mystery_func(7)
True
>>> mystery_func(6)
False
"""
if n < 2:
return False
for i in range(2, n):
if n % i == 0:
return False
return True

def main():
count = 0
lst = [2, 3, 4]
for num in lst:
if mystery_func(num):
count += 1

if count == 0:
print("None")
elif count < len(lst):
print("Some")
else:
print("All")

if __name__ == "__main__":
main()``````

main() prints:

Some

(because  4 is not prime, and 2 and 3 are prime.

``````def main():
count = 0
lst = [2, 3, 4]
for num in lst:
if mystery_func(num):
count += 1

if count == 0:
print("None")
elif count < len(lst):
print("Some")
else:
print("All")

if __name__ == "__main__":
main()``````

# Lecture 6: Course Recap - what have we covered?

• Week 2: Functions, Doctests, Passing values to functions, Branching
• Potential branching question:
• Write the output for the following values of the parameters a, b, and c. (2 pts. each)

1. a: 3, b: 3, c: 9

2. a: 8, b: 7, c: 9

3. a: 1, b: 4, c: 4

4. a: 4, b: 7, c: 2

5. a: 2, b: 4, c: 7

``````def batman(a, b, c):
if a > 3:
if a < c:
print("Robin")
else:
print("Batman")
elif b == 4:
if b != c:
print("Batmobile")
else:
print("Toolbelt")
else:
print("Alfred")``````

# Lecture 6: Course Recap - what have we covered?

• Week 2: Functions, Doctests, Passing values to functions, Branching
• Potential branching question:
• Write the output for the following values of the parameters a, b, and c. (2 pts. each)

1. a: 3, b: 3, c: 9

2. a: 8, b: 7, c: 9

3. a: 1, b: 4, c: 4

4. a: 4, b: 7, c: 2

5. a: 2, b: 4, c: 7

``````def batman(a, b, c):
if a > 3:
if a < c:
print("Robin")
else:
print("Batman")
elif b == 4:
if b != c:
print("Batmobile")
else:
print("Toolbelt")
else:
print("Alfred")``````

Alfred

Robin

Toolbelt

Batman

Batmobile

# Lecture 6: Course Recap - what have we covered?

• Week 3: Iteration, Lists
• You should be able to iterate through a list, and you should be able to iterate with a range. You should be able to write `while` and `for` loops for your code. You should also understand how the enumerate function works.
• Sample iteration problem:
• Write a function that asks a user for n numbers and then returns the sum and product of the numbers as a Tuple:
``````def sum_product(n):
pass``````
• Sample run:

```Please provide 4 numbers: Number 0: 2 Number 1: 4 Number 2: 5 Number 3: 7 Sum: 18, Product: 280 ```

# Lecture 6: Course Recap - what have we covered?

• Week 3: Iteration, Lists
• You should be able to iterate through a list, and you should be able to iterate with a range. You should be able to write `while` and `for` loops for your code. You should also understand how the enumerate function works.
• Sample iteration problem:
• Write a function that asks a user for n numbers and then returns the sum and product of the numbers as a Tuple:
``````def sum_product(n):
sum = 0
product = 1
for i in range(n):
next_num = int(input(f"Number {i}: "))
sum += next_num
product *= next_num
return sum, product``````
• Sample run:

```Please provide 4 numbers: Number 0: 2 Number 1: 4 Number 2: 5 Number 3: 7 Sum: 18, Product: 280 ```

# Lecture 6: Course Recap - what have we covered?

• Week 3: Iteration, Lists
• Sample lists problem:
• Write a function that counts the number of elements in a list within a specified range:
``````def count_list_range(lst, min, max):
"""
:return a count of numbers in the list
between (and including) min and max
"""``````
• Example:
``````>>> print(count_list_range([1, 5, 2, 11, 6, 18, 4, 9], 5, 10))
3``````

# Lecture 6: Course Recap - what have we covered?

• Week 3: Iteration, Lists
• Sample lists problem:
• Write a function that counts the number of elements in a list within a specified range:
``````def count_list_range(lst, min, max):
"""
:return a count of numbers in the list
between (and including) min and max
"""
count = 0
for value in lst:
if min <= value <= max:
count += 1
return count``````
• One-liner solution:
``````def count_list_range(lst, min, max):
"""
:return a count of numbers in the list
between (and including) min and max
"""
return len([x for x in lst if min <= x <= max])``````

# Lecture 6: Course Recap - what have we covered?

• Week 3: Iteration, Lists
• Sample lists problem 2:
• Return the "centered" average of an array of ints, which we'll say is the mean average of the values, except ignoring the largest and smallest values in the array. If there are multiple copies of the smallest value, ignore just one copy, and likewise for the largest value. Use int division (e.g., `a // b`) to produce the final average. You may assume that the array is length 3 or more. You can use the `sum()`, `min()`, and `max()` functions.
``````def centered_average(lst):
pass``````

# Lecture 6: Course Recap - what have we covered?

• Week 3: Iteration, Lists
• Sample lists problem 2:
• Return the "centered" average of an array of ints, which we'll say is the mean average of the values, except ignoring the largest and smallest values in the array. If there are multiple copies of the smallest value, ignore just one copy, and likewise for the largest value. Use int division (e.g., `a // b`) to produce the final average. You may assume that the array is length 3 or more. You can use the `sum()`, `min()`, and `max()` functions.
``````def centered_average(lst):
lst_cpy = list(lst)
lst_cpy.remove(min(lst_cpy))
lst_cpy.remove(max(lst_cpy))
return sum(lst_cpy) // len(lst_cpy)``````

# Lecture 6: Course Recap - what have we covered?

• Week 4: Tuples, List slicing, List comprehensions, Strings
• Remember, tuples cannot be modified. Often, we return a tuple as a return value, to return more than one value (as tuple elements)
• List comprehensions always return another list
• Strings are iterable, and each character has an ASCII value
• Sample list comprehension problem:
• Use a list comprehension to generate a list of all the numbers between 1 and n that are divisible by 7
``````def div_by_seven(n):
pass``````

# Lecture 6: Course Recap - what have we covered?

• Week 4: Tuples, List slicing, List comprehensions, Strings
• Remember, tuples cannot be modified. Often, we return a tuple as a return value, to return more than one value (as tuple elements)
• List comprehensions always return another list
• Strings are iterable, and each character has an ASCII value
• Sample list comprehension problem:
• Use a list comprehension to generate a list of all the numbers between 1 and n that are divisible by 7
``````def div_by_seven(n):
return [x for x in range(1, n) if x % 7 == 0]``````

# Lecture 6: Course Recap - what have we covered?

• Week 4: Tuples, List slicing, List comprehensions, Strings
• Sample list comprehension problem 2:
• Use a list comprehension to remove all the vowels in a string (don't forget to join the string back together once you have the list!)
``````def remove_vowels(str):
pass``````

# Lecture 6: Course Recap - what have we covered?

• Week 4: Tuples, List slicing, List comprehensions, Strings
• Sample list comprehension problem 2:
• Use a list comprehension to remove all the vowels in a string (don't forget to join the string back together once you have the list!)
``````def remove_vowels(str):
return "".join([x for x in str if x.lower() not in "aeiou"])``````

# Lecture 6: Course Recap - what have we covered?

• Week 4: Tuples, List slicing, List comprehensions, Strings
• Sample list comprehension problem 3:
``````def words_not_the(sentence):
"""Words not 'the'
Given a sentence, produce a list of the lengths of each word in the sentence,
but only if the word is not 'the'.
>>> words_not_the('the quick brown fox jumps over the lazy dog')
[5, 5, 3, 5, 4, 4, 3]
"""
pass``````

# Lecture 6: Course Recap - what have we covered?

• Week 4: Tuples, List slicing, List comprehensions, Strings
• Sample list comprehension problem 3:
``````def words_not_the(sentence):
"""Words not 'the'
Given a sentence, produce a list of the lengths of each word in the sentence,
but only if the word is not 'the'.
>>> words_not_the('the quick brown fox jumps over the lazy dog')
[5, 5, 3, 5, 4, 4, 3]
"""
return [len(x) for x in sentence.split(' ') if x != 'the']``````

# Lecture 6: Course Recap - what have we covered?

• Week 5: Recursion and Dictionaries
• ​You should be able to trace rudimentary recursive functions, and write simple recursive functions
• You should understand how to create dictionaries, and how to access the key/value pairs
• Example recursion problem:
• ​Write a recursive function that returns the sum of the ints from 1 to n
``````def recursive_sum(n):
pass``````

# Lecture 6: Course Recap - what have we covered?

• Week 5: Recursion and Dictionaries
• ​You should be able to trace rudimentary recursive functions, and write simple recursive functions
• You should understand how to create dictionaries, and how to access the key/value pairs
• Example recursion problem:
• ​Write a recursive function that returns the sum of the ints from 1 to n
``````def recursive_sum(n):
if n == 1:
return 1
return n + recursive_sum(n - 1)``````

# Lecture 6: Course Recap - what have we covered?

• Week 5: Recursion and Dictionaries
• ​You should be able to trace rudimentary recursive functions, and write simple recursive functions
• You should understand how to create dictionaries, and how to access the key/value pairs
• Example recursion problem 2:
• What does the following recursive function do?
``````def mystery(i):
if i < 1:
return
print(i)
mystery(i - 1)
print(i)``````

# Lecture 6: Course Recap - what have we covered?

• Week 5: Recursion and Dictionaries
• ​You should be able to trace rudimentary recursive functions, and write simple recursive functions
• You should understand how to create dictionaries, and how to access the key/value pairs
• Example recursion problem 2:
• What does the following recursive function do?
``````def mystery(i):
if i < 1:
return
print(i)
mystery(i - 1)
print(i)``````

Example:

```printFun(3) 3 2 1 1 2 3```

The function prints `i` down to `1`, and then `1` back up to `i`.

# Lecture 6: Course Recap - what have we covered?

• Week 5: Recursion and Dictionaries
• Example dictionary problem:
• Given a list of integers, produce a dictionary that counts the number of values between 0 and 9, 10 and 19, and 20 and 29. The keys should be 0, 10, and 20, and the values should be the counts in the ranges above.
``````def histogram(lst):
pass``````

Example:

``````>>> histogram([12, 5, 3, 19, 28, 15, 14, 1, 23])
{0: 3, 10: 4, 20: 2}``````

# Lecture 6: Course Recap - what have we covered?

• Week 5: Recursion and Dictionaries
• Example dictionary problem:
• Given a list of integers, produce a dictionary that counts the number of values between 0 and 9, 10 and 19, and 20 and 29. The keys should be 0, 10, and 20, and the values should be the counts in the ranges above.
``````def histogram(lst):
hist = {}
for value in lst:
if value // 10 * 10 not in hist:
hist[value // 10 * 10] = 1
else:
hist[value // 10 * 10] += 1
return hist
``````

Short, generic solution:

``````>>> histogram([12, 5, 3, 19, 28, 15, 14, 1, 23])
{0: 3, 10: 4, 20: 2}``````
``````def histogram2(lst):
hist = {}
for value in lst:
if 0 <= value < 10:
if 0 not in hist:
hist[0] = 1
else:
hist[0] += 1
elif 10 <= value < 20:
if 10 not in hist:
hist[10] = 1
else:
hist[10] += 1
elif 20 <= value <= 30:
if 20 not in hist:
hist[20] = 1
else:
hist[20] += 1
return hist``````

Verbose solution:

Example:

# Lecture 6: Course Recap - what have we covered?

• ​Week 6: ​File processing and exception handling
• ​You should be able to open files to read or write, and you should be able to read from them and write to them. You should be using one of the following patterns:
``````with open(filename, "r") as f:
for line in f:
line = line[:-1]  # remove newline
# do something with the line``````
``````with open(filename, "r") as f:
allText = f.readlines()  # read all lines into a list (will still have newlines)
allText = [x[:-1] for x in allText]  # remove newlines (if necessary)
# now allText has a list of all the lines in the file with no newlines at the end``````
``````with open(filename, "w") as f:
f.write(mydata)
f.write('\n')  # each line should end with a newline``````
``````with open(filename, "r") as f:
for line in f:
# now allText has the entire file``````

# Lecture 6: Course Recap - what have we covered?

• ​Week 6: ​File processing and exception handling
• ​Example file processing problem:
• ​Reverse the lines in a file. Do not provide error checking.
``````def reverse_lines(filename):
pass``````

# Lecture 6: Course Recap - what have we covered?

• ​Week 6: ​File processing and exception handling
• ​Example file processing problem:
• ​Reverse the lines in a file. Do not provide error checking.
``````def reverse_lines(filename):
with open(filename, "r") as f:

lines = lines[::-1]
with open(filename, "w") as f:
for line in lines:
f.write(line)``````

# Lecture 6: Course Recap - what have we covered?

• ​Week 6: ​File processing and exception handling
• ​For exception handling, you should be able to use `try/except` to catch errors. We will give you the error types (e.g., `FileNotFoundError`)
• Example exception handling problem:
• ​Write a function that returns the value for a given key in a dictionary, and returns None if the value does not exist.
``````def get(dict, key):
pass``````

# Lecture 6: Course Recap - what have we covered?

• ​Week 6: ​File processing and exception handling
• ​For exception handling, you should be able to use `try/except` to catch errors. We will give you the error types (e.g., `FileNotFoundError`)
• Example exception handling problem:
• ​Write a function that returns the value for a given key in a dictionary, and returns None if the value does not exist.
``````def get(dict, key):
try:
return dict[key]
except KeyError:
return None``````
• It turns out that this function already exists in the dictionary definition!
``````help(dict.get)

get(self, key, default=None, /)
Return the value for key if key is in the dictionary, else default.``````
• You use it like this:
``````>>> d = {'name': 'Chris'}
>>> age = d.get('age')
>>> print(age)
None
>>> age = d['age']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'age'
>>>``````

# Lecture 6: Course Recap - what have we covered?

• We could have made our original letter histogram easier. Original:
``````def letter_histogram(s):
freqs = {}
for c in s:
if c not in freqs:
freqs[c] = 1
else:
freqs[c] += 1

return freqs``````
``````def letter_histogram(s):
freqs = {}
for c in s:
freqs[c] = freqs.get(c, 0) + 1

return freqs``````
``````>>> letter_histogram("the quick brown fox jumps over the lazy dog")
{'t': 2, 'h': 2, 'e': 3, ' ': 8, 'q': 1, 'u': 2, 'i': 1, 'c': 1, 'k': 1, 'b': 1, 'r': 2, 'o': 4,
'w': 1, 'n': 1, 'f': 1, 'x': 1, 'j': 1, 'm': 1, 'p': 1, 's': 1, 'v': 1, 'l': 1, 'a': 1, 'z': 1,
'y': 1, 'd': 1, 'g': 1}``````
• Version with `get()`:

# Lecture 6: Studying for the Midterm

1. Check out the Midterm study guide: https://tinyurl.com/cs5001-midterm
2. Review all lecture slides and examples, assignments, and labs
3. Practice! Go through the practice problems we went over in class today, and the ones you will see in lab. You should be able to answer every practice problem correctly!
4. Look at the reference sheet that we will give you during the exam: https://tinyurl.com/cs5001-midterm-reference
5. Practice some more!

The midterm will be 2.5 hours long, from 7pm-9:30pm next Tuesday. It will be using a computerized testing system called BlueBook -- more details about that will follow.

By Chris Gregg

• 625