---
title: Homework 7
tags: Homeworks-S24
---
# Homework 7: As Memory Serves
### Due: Monday, November 25th at 11:59 pm
### Setup
- Create three files:
- A document named `tracing` in which you will answer Tasks A-1 through A-6 (export as a PDF before handing in)
- `hw7_code.py` in which you will run the code as instructed in Task-4. You will **not** hand this in.
- `test_hw7.py` which contains your tests (add `import pytest` at the top of this file)
- Do **not** put your name anywhere in your homework files
### Resources
- [Working with VSCode for CS111](https://hackmd.io/@cs111/vscode-guide)
- [Python testing and style guide](https://hackmd.io/@cs111/python_guide)
- [TA hours](https://brown-csci0111.github.io/pages/calendar)
- [EdStem](https://edstem.org/us/courses/64952)
## The Assignment
Honey Beester is going shopping with his family to decorate his snazzy new college dorm! When shopping, he has to keep track of all his family members' orders and the items that they are ordering. In this homework, you will keep track of these orders through memory diagrams.
<figure style="text-align: center;">
<img src="https://static.vecteezy.com/system/resources/thumbnails/002/881/693/small_2x/smiling-bee-at-flower-field-collecting-honey-free-vector.jpg" alt="bee with bucket" width="80%">
<figcaption><em>Image hosted by Vector4Free</em></figcaption>
</figure>
## Learning Objectives
This assignment mostly has you working with memory diagrams, which we cover to help you understand what your code actually does when updating data. The last part gives you some practice with dictionaries, which you will need for the final project.
:::info
Learning Goals:
- Check your understanding of how different bits of code affect the connections between data at the level of memory
- Make sure you can write tests for functions that update data in memory
- Practice using dictionaries
:::
## Memory Tracing (No Programming)
**For tasks involving memory diagrams (Task A-2 and Task A-5), use [this template](https://docs.google.com/spreadsheets/d/1NyJbBWopNezH-fJsZz7iD13JORsWqKEsrN_bfR9_xFY/edit?usp=sharing) as a starting point.** To edit it, make a copy (File -> Make a copy). This is the same template that you saw in [Lab 10](https://hackmd.io/@cs111/f24-lab10) – refer to that lab for an example of how to fill out a memory diagram.
To turn in your final memory diagrams, take a screenshot of each diagram and insert it into a single file called `tracing.pdf`. Clearly mark which image goes with which memory point. Your final submission for this section should contain your memory diagrams alongside your written answers (see the note at the bottom of this section for full hand-in instructions). *Do not submit the spreadsheet itself.*
__Bee__-low is part of a program for managing orders in an online store. There is a data structure for the `Items` for sale, as well as a catalog of all items. There is a data structure for `Orders`, which capture the name of a customer and a list of items that the customer wants to buy. There are also two versions of a function to update the price of an item in the catalog.
At the bottom of the file is a sequence of expressions to evaluate.
:::spoiler **Program code dropdown**
```=python
from dataclasses import dataclass
@dataclass
class Item:
descr : str
price : float
@dataclass
class Order:
customer : str
items: list
# Several Items
bee_book = Item("The Busy Bee", 17.95)
cap = Item("baseball cap", 12.95)
radio = Item("radio", 10)
laptop = Item("laptop", 900)
# a catalog is a list of items
catalog = [bee_book, radio, laptop]
# Some orders
k_order = Order("Kathi", [radio, bee_book, laptop])
m_order = Order("Milda", [laptop, Item("radio", 10)])
# The companies list of open orders (that haven't been paid for yet)
open_orders = [k_order, m_order]
def update_price1(for_descr : str, new_price : float) -> None:
"""update the price for the item with the given description"""
for item in catalog:
if item.descr == for_descr:
item.price = new_price
def update_price2(for_descr : str, new_price : float) -> None:
"""update the price for the item with the given description"""
global catalog
new_catalog = []
for item in catalog:
if item.descr == for_descr:
new_catalog.append(Item(item.descr, new_price))
else:
new_catalog.append(item)
# Memory point 2
catalog = new_catalog
# The expressions to run
update_price1("radio", 8.50)
# Memory point 1
update_price2("radio", 7)
# Memory point 3
update_price1("radio", 5)
update_price1("laptop", 1100)
# Memory point 4
```
:::
<br>
**Task A-1:** *Without running the program* or drawing a memory diagram, predict what will be in each of `k_order`, `m_order`, and `catalog` (items and their prices) after the four expressions evaluate. Write down your answers.
*Note: You will not lose points for an inaccurate prediction. The point of the question is to help you calibrate your understanding of memory as you work through the problem.*
*Note: In the code, there is a line that says `global catalog`. This just means that the function is going to update the value of `catalog` which was defined outside the function.*
**Task A-2:** There are four comments in the code marked "Memory point." Show the contents of memory (variables and heap) at each of these four points. **Make sure to include a different memory diagram for each memory point (you should have 4 distinct diagrams).** Remember to use [the template](https://docs.google.com/spreadsheets/d/1NyJbBWopNezH-fJsZz7iD13JORsWqKEsrN_bfR9_xFY/edit?usp=sharing) for your memory diagrams.
**Task A-3:** *Based on your memory diagram*, predict what will be in each of `k_order`, `m_order`, and `catalog` (items and their prices) after the four expressions evaluate. Write down your answers.
*Note: You will not lose points for an inaccurate answer for this task (as long as you appeared to take the problem seriously)*
**Task A-4:** Now, copy and run the code and compare the final contents of `k_order`, `m_order`, and `catalog` to your answer to the previous task. If they differ, that is an indication that you have a mistake in your memory diagram.
:::spoiler Hint for checking your work
**We will show an example of this in class on Friday.** Add a `pass` statement at the end of this code, and add a breakpoint (click to the left of the `pass` statement's line number, so that a red dot appears).
Run the debugger (Run -> Debug) and observe what the contents of `k_order`, `m_order`, and `catalog` are on the left side of the screen.
:::
<br>
**Task A-5:** Revise your memory diagrams from **Task A-2** as needed and write down your final answers for each of the four memory points.
:::spoiler Hint for checking your work as you go
You can add breakpoints in other parts of your code and step through to check if the values each variable takes on are the same as you put in the memory diagram at each step. Refer back to [Lab 9](https://hackmd.io/@cs111/BJA1vtm30) and the 11/17 lecture for instructions on using the debugger.
:::
<br>
**Task A-6:** Reflect on your process: were your predictions correct? If yes, write down one way you approached the tasks that you feel was particularly helpful in your thinking. If no, write down a *conceptual misconception* (not just a wrong answer, but where you think you had a mistake in your thinking) you had and fixed.
:::warning
**Note:** Your final file should include:
1. Your prediction from task A-1
2. Your initial answer from task A-3
3. Images of your final, revised memory diagrams from task A-5 (builds upon / corrects any mistakes from the memory diagrams from task A-2). Clearly mark which image goes with which memory point.
4. Your reflection from task A-6
Remember to check the [Handin](#Handin) section for more details!
:::
## Testing Under Mutation
For this section, create a file called `test_hw7.py`. We will ask you to create test data and write assertions for functions that we will describe but not provide, meaning that you will **not be running your testing file.** The point of this section is to show that you understand how you would set up data for testing under mutation!
Say you were given a function `discount_order(ord : Order) -> None` that goes through every `Item` in the provided order and takes $1 off the price of each item that costs more than $10.
**Task B-1:** Write a function called `test_discount_order` that sets up at least two `Order`s (similar to how `k_order` and `m_order` were set up above, but you should make your own) and tests that `discount_order` behaves as intended. **You are only writing a test function for this question**. You are NOT writing code for `discount_order` itself.
You will be graded on what your `Order`s look like (think back to the things you learned about writing comprehensive test examples in Pyret -- what sorts of `Orders` would be helpful for testing that `discount_order` works?). You will also be graded on the correctness of the assertions you write and whether they correctly test the effects of the `discount_order` function as described.
Recall that, when testing under mutation, we follow a template where we set up data, call the mutating function, and then test the side-effects of the mutation.
:::spoiler Template for testing under mutation
:::info
Your function will need to set up some data (items and orders), make one or more calls to `discount_order`, then run a series of assertions to check the impacts of the `discount_order` call on the data. The general form of your function should be as follows:
```=python
def test_discount_order():
"SETUP"
# create Orders here
"PERFORM MODIFICATIONS"
# call discount_order on the Orders
"CHECK EFFECTS"
# assertions go here
```
:::
---
Now let's assume that someone wants to use a `dict` from strings to floats, instead of a list of `Item`s, to keep track of the catalog. For example, the catalog in part A, rewritten in this format, would look like
```
catalog = {"The Busy Bee": 17.95, "Radio": 10, "Laptop": 900}
```
You're given a function `update_cat_dict(cat_dict : dict, itm : Item)` that adds a key-value pair of `itm`'s description and price to the given dictionary if and only if a key of the given description doesn't already exist in `cat_dict` (for example, calling `update_cat_dict(catalog, Item("Radio", 8))` would have no effect whereas `update_cat_dict(catalog, Item("Phone", 540)` would add the key-value pair `"Phone": 540` to `catalog`).
**Task B-2:** Let's assume that someone has given us the `update_cat_dict` function **and** data to test with. Fill in the assertion parts of the following testing function. Think back to the beginning of the November 13th lecture for an example of how we reason about writing tests when we don't know *exactly* what our testing data looks like. Think about the assumptions you can and cannot make about `test_cat_dict` and what it will look like after each call of `update_cat_dict`. Just like we did in class, you can create variable(s) to help you in your assertions.
```=python
def test_update_cat_dict():
"SETUP"
shoe1 = Item("Sneaker", 45)
shoe2 = Item("Sneaker", 32)
# the variable test_cat_dict was defined elsewhere in the file
update_cat_dict(test_cat_dict, shoe1)
# assertion(s) go here
update_cat_dict(test_cat_dict, shoe2)
# assertion(s) go here
```
<!--
## Dictionaries
**Task C-1:** In `hw7_code.py`, using the provided `catalog` list and the relevant items (`bee_book, radio, laptop`), create a dictionary named `catalog_dict` that maps the item's description to its price.


:::spoiler Details
:::info
This task is asking you to translate the information that appears in the `catalog` list into a dictionary. `catalog_dict` should be a dictionary whose keys are strings (the item description). The values should be a float that represents the item's price.
:::


**Task C-2:** In `hw7_code.py`, rewrite the function `update_price1` such that it updates an item's price in `catalog_dict`. You do not have to write tests for this function inside `test_hw7.py` (since your `test_hw7.py` file will not run after doing the Task Bs), but you should manually interact with your code to double-check that the function works. How you do this is up to you -- you can run the code in the terminal, you can add some more print statements to the file, or you can create a testing file that you do not turn in.
- Call this new function `new_update_price1`. **Do not modify `update_price1`.**
- `new_update_price1` should take the same inputs as `update_price1`, and it shouldn't return anything. It should update the existing `catalog_dict` dictionary.
- `new_update_price1` should have the same effect as `update_price1` does on items that don't exist in the catalog (we want you to reason about what happens in `update_price1` in this case. How can you do something similar in `new_update_price1`?)
**Task C-3:** You now have two different implementations of `catalog`. One that uses lists, and another that uses a dictionary. In `hw7_code.py`, write a multiline comment describing the tradeoffs between both implementations, which one do you think is better? Write down your answer in a multi-line comment using `#`.
-->
## Handin
You will be submitting two separate files to [Gradescope](https://www.gradescope.com/courses/844129) under Homework 7 -- note that you're not submitting a code file!
- `tracing.pdf` with your answers to the "Memory Tracing" section exercises
- `test_hw7.py`, which will contain the testing function from the "Testing Under Mutation" section
## Theme Song
### [Honeybee - The Head and the Heart](https://www.youtube.com/watch?v=kU0SJTmdFp4)
[![Video Title](https://img.youtube.com/vi/kU0SJTmdFp4/maxresdefault.jpg)](https://www.youtube.com/watch?v=kU0SJTmdFp4)
## Staff Spotify Playlist
### <iframe style="border-radius:12px" src="https://open.spotify.com/embed/playlist/0aKOuytJkMBHpiyINAwQKo?utm_source=generator" width="100%" height="352" frameBorder="0" allowfullscreen="" allow="autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture" loading="lazy"></iframe>
------
> Brown University CSCI 0111 (Fall 2024)
<iframe src="https://forms.gle/KELp5QcM3NdRvhy17" width="640" height="372" frameborder="0" marginheight="0" marginwidth="0">Loading…</iframe>