A document from MCS 275 Spring 2024, instructor Emily Dumas. You can also get the notebook file.

MCS 275 Spring 2024 Homework 4

  • Course Instructor: Emily Dumas

Instructions:

  • Complete the problems below in a Python notebook.
  • Upload the notebook directly to gradescope (as a .ipynb file).

Deadline

This homework assignment must be submitted in Gradescope by Noon central time on Tuesday February 6, 2024.

Collaboration

Collaboration is prohibited, and you may only access resources (books, online, etc.) listed below.

Content

This assignment corresponds to Worksheet 4, which involves the Python notebook interface, context managers, and recursion.

Resources you may consult

The materials you may refer to for this homework are:

Point distribution

This homework assignment has 3 problems, numbered 2, 3, and 4. Problem 2 merely requies you to follow some formatting rules, while problems 3 and 4 are based on mastery of content. The grading breakdown is:

Points Item
4 Autograder (Problem 1)
5 Notebook formatting (Problem 2)
5 Problem 3
5 Problem 4
19 Total

What to do if you're stuck

Ask your instructor or TA a question by email, in office hours, or on discord.

( No problem 1, as usual )

Problem 2: Submit your homework as a notebook file (.ipynb)

To demonstrate your proficiency with the Python notebook interface, put all of your work on this assignment in a Python notebook named hwk4 and submit the notebook file (hwk4.ipynb) to Gradescope.

Your score on this problem will reflect whether or not you submitted a valid notebook file containing all your work on the problems below, and whether it followed the formatting guidelines below.

Notebook formatting requirements

  • Title & name at top: Include a markdown cell at the top that uses a header to title the document MCS 275 Spring 2024 Homework 4. In the same cell, include your name as a subheading. Put the authorship statement you would usually include in a homework Python script in this cell, too.
  • Problem numbers: Label problems 3 and 4 using a markdown cell with a subheading like Problem 3
  • Code goes in code cells: Put your solution to each problem in one or more code cell(s) below the problem number heading. The code cells don't need headers, module-level docstrings, or authorship statements. The markdown cell at the top of the notebook replaces these.
  • Nothing else: The notebook should only contain the items described above. For example, do not restate the question before giving your answer.

Help making/uploading a notebook

If you work in Jupyter (as installed with python3 -m pip install notebook), just name the notebook hwk4 and it will be saved with the .ipynb extension in the directory where you started Jupyter.

If you work in Colab, you can download the .ipynb file to your computer using the menu bar that Colab displays at the top of the notebook. Select File, then Download, and in the submenu, Download .ipynb.

Anticipated question: Can you use the notebook of this assignment as a starting point?

Sure, though you'll need to delete a lot of stuff in order to make it conform to the formatting requirements above. I'm not sure if that's easier than starting a notebook from scratch.

Problem 3: Timed block context manager

First of all, in this problem you'll need to

In [24]:
import time

so that you can use time.time() for timing calculations.

Now, create a class TimedBlock that is a context manager which keeps track of the total amount of time between the start and end of the with-block. It should print a message upon the start of the with-block, and then another upon exit which includes the timing information. The constructor should accept an argument title which specifies a string used to identify the block in the output messages, as shown below.

Make sure your solution behaves exactly as in these examples:

In [27]:
# Sample usage to time a bunch of calculations
with TimedBlock("Gigantic integer arithmetic"):
    digits = 0
    for k in range(5000):
        x = 3**k - 2**k
        digits += len(str(x))
    print("Total of {} digits".format(digits))
Starting timed block 'Gigantic integer arithmetic'
Total of 5965321 digits
Exited timed block 'Gigantic integer arithmetic' after 0.2335s
In [28]:
# Sample usage showing we still get timing data if the with-block
# raises an exception
with TimedBlock("Float arithmetic that eventually fails"):
    for k in range(5000):
        x = 1 / (3**(4000-k) - 2**(4000-k))
Starting timed block 'Float arithmetic that eventually fails'
Exited timed block 'Float arithmetic that eventually fails' after 0.0642s
---------------------------------------------------------------------------
ZeroDivisionError                         Traceback (most recent call last)
/tmp/ipykernel_6198/973717916.py in <module>
      3 with TimedBlock("Float arithmetic that eventually fails"):
      4     for k in range(5000):
----> 5         x = 1 / (3**(4000-k) - 2**(4000-k))

ZeroDivisionError: division by zero
In [23]:
# Sample usage showing output is only printed when we enter the with-block
# and NOT when the class is instantiated
B = TimedBlock("Notice the constructor doesn't print anything")
In [31]:
# Sample usage showing that timing begins when the with-block begins
# and NOT whent he TimedBlock constructor is called.
B = TimedBlock("Should take about 0.5 seconds")
# The next delay isn't part of the timing
time.sleep(1.5)
with B:
    # This delay IS part of the timing
    time.sleep(0.5)
Starting timed block 'Should take about 0.5 seconds'
Exited timed block 'Should take about 0.5 seconds' after 0.5006s

Problem 4. Digital recursion breadth

Define a sequence of integers $R_n$ as follows:

$$ \begin{split} R_0 &= 1\\ R_1 &= 1\\ R_2 &= 1\\ R_n &= R_{n-1} + R_{n-2} + \cdots + R_{n-(d+2)} \text{ if }n>2\text{ and }n\text{ has }d\text{ decimal digits.} \end{split} $$

In other words, for $n>2$ the $n^{\mathrm{th}}$ term is the sum of the $d+2$ preceding terms where $d$ is the number of decimal digits in $n$.

For example, since the number $3$ has a single digit ($d=1$), the term $R_3$ is the sum of $d+2=3$ previous terms: $$ R_3 = R_2 + R_1 + R_0 = 3$$

Similarly, since the number $42$ has two digits ($d=2$), the term $R_{42}$ is the sum of $d+2=4$ previous terms: $$ R_{42} = R_{41} + R_{40} + R_{39} + R_{38}$$

The sequence thus begins $$1, 1, 1, 3, 5, 9, 17, 31, 57, 105, 210, 403, \ldots $$

with $R_{10} = 210 = 105 + 57 + 31 + 17$ being the first case where the sum includes four previous terms.

A. Recursive implementation

Write a function DRB(n) that calculates and returns $R_n$ using recursion.

B. Iterative implementation

Write a function DRB_iterative(n) that calculates and returns $R_n$ using iteration.

C. Test

Verify (by including a code cell and its output in your notebook) that the values returned by these two functions agree for $0 \leq n < 20$.

Revision history

  • 2024-02-01 Initial publication
  • 2024-02-05 Clarify how to handle authorship statement, headers, and module docstrings in the notebook format. Changes in blue.