Skip to content

Homework 6: For Loops

Objectives

The goal of this assignment is to gain experience working with:

  • for loops:
    • Iterating over a collection
    • Iterating over a range of integers

Submissions Limited

For HW6, you may submit each exercise up to 20 times. Before you submit to Gradescope, make sure that you:

  1. Test your code, either in the shell or in the __main__ block.
  2. Run !flake8, and resolve all PEP 8 and docstring issues.

Don't Use while

This homework is about for loops. Be sure not to use while loops (which we'll learn about next week) in any of the exercises.

Stubs Provided

To save you time on this assignment, we are giving you starter files with all the docstrings already written. Download and unzip HW6-stubs.zip. Don't forget to write your name at the top of each file!

Exercise 6.1 Street Addresses

For this exercise you will write a function to help with generating street addresses in new housing developments. Create a file addressing.py with a function generate_addresses. This function must take four arguments:

  1. The name of the street
  2. The lower bound of house numbers (inclusive)
  3. The upper bound of house numbers (exclusive)
  4. The interval between house numbers

The function must return a list of street addresses formatted with the number of the address, followed by a single space, followed by the name of the street. For example:

>>> print(generate_addresses('Carrier Drive', 1000, 1030, 10))
['1000 Carrier Drive', '1010 Carrier Drive', '1020 Carrier Drive']

Note

The provided stubs use assert statements instead of printing the results. The assert keyword allows you to test if a condition is true. For example:

assert generate_addresses('Carrier Drive', 1000, 1030, 10) == [
    '1000 Carrier Drive', '1010 Carrier Drive', '1020 Carrier Drive']

The assert statement above compares the return value from generate_addresses() with the expected result. If the return value equals the expected result, nothing happens. If the return value does not equal the expected result, the program ends with an AssertionError.

You are encouraged to add other assert statements under __main__ to test your code with other inputs before submitting to Gradescope.

Exercise 6.2 Intervals

For this exercise, write a function that takes a list of floats and returns a new list containing only the numbers that are within a designated interval. The file must be named interval.py and it must contain a function named in_interval with four parameters:

  • The original list of float numbers.
  • The lower bound of the interval.
  • The upper bound of the interval.
  • Boolean indicating whether this is a closed interval. This parameter should have a default value of True, indicating that an interval is closed by default.

The numbers in the returned list must be in the same order as they appeared in the original list. You may assume that the provided lower and upper values represent a valid interval.

Here are some examples illustrating the expected behavior:

>>> in_interval([20.1, 0.0, 2.5, 1.4, -6.0], 0.0, 5.0)  # Default is closed
[0.0, 2.5, 1.4]
>>> in_interval([20.1, 0.0, 2.5, 1.4, -6.0], 0.0, 5.0, False)
[2.5, 1.4]

Exercise 6.3 Shift Cipher

One of the simplest forms of encryption is the Caesar Cipher, also known as a shift cipher. In this technique, each letter in the plaintext is replaced by a letter a fixed distance away in the alphabet, wrapping around at the end (or beginning) as necessary.

image Shift cipher example

For example, if you encoded 'dog' by shifting two to the right, 'd' would be replaced by 'f', 'o' would be replaced by 'q', and 'g' would be replaced by 'i', so the final encoded text would be 'fqi'. 'zoo' would be encoded as 'bqq', because the 'z' would wrap around to the beginning of the alphabet again.

Create program called shift_cipher.py containing the function encode. The function should take as parameters the text to encode (in all lower case), and the number of letters to shift (guaranteed to be between -26 and 26). It should return the encoded text, and leave spaces and punctuation as-is, without changing them.

>>> print(encode("the quick brown fox.", 4))
xli uymgo fvsar jsb.

Hint: You will need to use ord() and chr() to convert letters to numbers and back again in order to shift them. You should also use the remainder operator (%), although a less optimal solution is possible using if statements.

Exercise 6.4 Count Rivers

It is useful to be able to find out what words you can make with a collection of letters, using each letter no more than once: for example, for playing scrabble or for creating a note by cutting out letters from a newspaper. In this problem, you will solve something similar.

Create a file called river.py and write a function called count_rivers which takes a str parameter letters and returns the number of times the word "river" can be formed from the letters in letters, using each letter at most once. You may assume that the letters in the letters parameter are lowercase.

Here are some examples. Notice in the second example, there are not enough r characters to make the word river twice.

>>> print(count_rivers("rrrriive dddddddddddive lllllllive"))
2
>>> print(count_rivers("rrriivedddddddddddive -- lllllllive"))
1

You must use a loop to solve this problem. No use of the count method or the Counter object is permitted.

Hint: Consider using a dict to help you keep track of the number of letters.

Exercise 6.5 Parking Lot

There's a major event happening at the fairgrounds, and cars are lining up from everywhere. We need a program to help vehicles find a parking spot when they arrive. Since parking is limited, and not all of the spots are the same size, we need to be careful to put smaller vehicles in the smaller spots so that we can save the larger spots for vehicles that need them.

For the sake of simplicity both cars and parking spots will be represented as a tuple which contains the width of the car/spot followed by the length of the car/spot. Define a function named best_fit in parking.py with the following arguments:

  • a tuple representing the car that is trying to park
  • a list of tuples representing the available parking spots

In order to fit in a parking spot, there must be at least 2 feet of space around all sides of the car when parked. This will allow people to safely enter and exit their cars, walk around the vehicles and load and unload items. The image below shows a car with tuple (6, 10) that exactly fits in a parking spot with tuple (10, 14), due to the 2 feet of space in all directions.

image

The function should return the position in the list of the parking spot which best fits this car, i.e. the spot with the least amount of total excess space around the car. In the case of ties, the spot with the larger index should be selected. If there is no spot that can accommodate the car, then the function must return None.

Here are some examples:

>>> print(best_fit((3, 4), [(5, 5), (10, 12), (7, 8), (7, 9), (8, 8)]))
2
>>> print(best_fit((3, 4), [(5, 5), (10, 12), (3, 4), (7, 9), (8, 8)]))
3
>>> print(best_fit((3, 4), [(5, 5), (10, 12), (3, 4), (7, 9), (7, 9)]))
4
>>> print(best_fit((9, 12), [(5, 5), (10, 12), (3, 4), (7, 9), (7, 9)]))
None

HW6 Reflection (required)

Submit the graded survey on Canvas after completing the assignment.