3.09 Developing Algorithms HW
3.09 Developing Algorithms
Source lesson: csp/python/developing-algorithms
Learning Objective: Decide whether two algorithms are equivalent by testing and tracing, and build new algorithms by modifying and combining known patterns.
Submission notes
- Lesson: CSP 3.09 Developing Algorithms
- Notebook: https://jupiterian.opencodingsociety.com/python/developing-algorithms-hw
-
MCQ 3.09: 4/4 answers: C,B,C,B - Popcorn Hacks 1-3 completed in class and copied to notebook: yes
- Homework output: Restock needed: / Blankets: need 12 / Shampoo: need 10 / Total items needed: 22 / Most urgent: Blankets (short by 12)
Popcorn
Popcorn Hack 1: Translate pseudocode to Python
Prediction: 3 + 5 + 2 + 4 = 14, and 14 / 4 = 3.5
Code Runner Challenge
3.09 Popcorn 1 - Translate the pseudocode into Python
View IPYNB Source
# CODE_RUNNER: 3.09 Popcorn 1 - Translate the pseudocode into Python
# Step 1: make the hours list
hours = [3, 5, 2, 4]
# Step 2: start total at 0
total = 0
# Step 3: FOR EACH -> for loop, add each h to total
for h in hours:
total = total + h
# Step 4: LENGTH(hours) -> len(hours), compute the average
average = total / len(hours)
# Step 5: print total, then average
print(total)
print(average)
Actual output: 14 and 3.5. FOR EACH h IN hours turns into for h in hours:, and LENGTH turns into len.
Popcorn Hack 2: Predict, then fix
Prediction (before running the original): 1. With count > capacity, 12 isn’t greater than 12, so Self-Defense doesn’t get counted and only Fitness (15) does.
Fix: changed > to >= so a workshop at exactly 12 counts as full.
Code Runner Challenge
3.09 Popcorn 2 - Predict, then fix the full-workshop counter
View IPYNB Source
# CODE_RUNNER: 3.09 Popcorn 2 - Predict, then fix the full-workshop counter
signed_up = [12, 7, 15, 9] # Self-Defense, Parenting Skills, Fitness, Self-Sufficiency
capacity = 12
full = 0
for count in signed_up:
if count >= capacity: # was >, which skipped the workshop at exactly 12
full = full + 1
print("Full workshops:", full)
# My prediction before running: 1 (the original > misses Self-Defense at 12)
Actual output: Full workshops: 2 after the fix (the original printed 1, same as my prediction). It’s a one-character bug that doesn’t cause any error, it just gives the wrong count at the boundary.
Popcorn Hack 3: Modify the counter into a collector
Code Runner Challenge
3.09 Popcorn 3 - Modify the counter into a collector
View IPYNB Source
# CODE_RUNNER: 3.09 Popcorn 3 - Modify the counter into a collector
workshops = ["Self-Defense", "Parenting Skills", "Fitness", "Self-Sufficiency"]
signed_up = [12, 7, 15, 9] # signed_up[0] goes with workshops[0], and so on
capacity = 12
# collect names instead of counting
open_workshops = []
for i in range(len(workshops)):
if signed_up[i] < capacity:
open_workshops.append(workshops[i])
# print how many, then the list
print("Workshops with open seats:", len(open_workshops))
print(open_workshops)
Actual output: Workshops with open seats: 2 and ['Parenting Skills', 'Self-Sufficiency']. Self-Defense is at exactly 12 so < 12 leaves it out. The loop and the if are the same as a counter, the only thing that changed is count = count + 1 became open_workshops.append(...).
MCQ
| **MCQ 3.09: 4/4 | answers: C,B,C,B** |
1. What does this code print?
Code Runner Challenge
3.09 Homework - Safe Passage Heals supply restock report
View IPYNB Source
gifts = [20, 120, 60]
count = 0
for g in gifts:
if g >= 100:
count = count + 1
count = count + 1
print(count)
A 1 · B 3 · C 4 · D 2
Answer: C. The last line is outside the if so it runs for all 3 gifts, plus 1 more for the $120 gift. 3 + 1 = 4.
2. Both return 60. Which one has a side effect on the list passed in? (top_a returns max(amounts), top_b does amounts.sort() then returns amounts[-1])
A top_a · B top_b · C Both · D Neither
Answer: B. max() only reads the list, sort() rearranges the original list.
3. A workshop holds 10. A checks signed_up < 10, B checks signed_up <= 10. Which input proves they are NOT equivalent?
A 5 · B 9 · C 10 · D 15
Answer: C. At exactly 10 they disagree. Every other input gives the same answer.
4. You change a working count-low-supplies algorithm so it appends each low item to a list and returns the list. In College Board terms, you:
A Created one from scratch · B Modified an existing algorithm · C Combined two algorithms · D Made them equivalent
Answer: B. The loop and condition stayed the same, only what it tracks changed.
Homework
Homework Hack: Supply closet restock report
Combines three patterns: collect the items below target, sum the shortages, and find the max shortage, then picks between “Fully stocked!” and the report.
Prediction:
- Toothbrushes 40/30 and Notebooks 30/30 aren’t short
- Socks is 25/25, exactly at target, so
25 < 25is False and it’s not short either - Blankets needs 20 - 8 = 12, Shampoo needs 15 - 5 = 10
- Total 22, most urgent is Blankets (12)
Code Runner Challenge
3.09 Homework - Test 2: fully stocked
View IPYNB Source
# CODE_RUNNER: 3.09 Homework - Safe Passage Heals supply restock report
items = ["Toothbrushes", "Blankets", "Socks", "Shampoo", "Notebooks"]
in_stock = [40, 8, 25, 5, 30] # in the closet now
target = [30, 20, 25, 15, 30] # what staff want on hand
# Step 1: COLLECT items below target, and how many of each are needed
short_items = []
short_amounts = []
for i in range(len(items)):
if in_stock[i] < target[i]:
short_items.append(items[i])
short_amounts.append(target[i] - in_stock[i])
# Step 2: SUM the shortages with a loop (no sum())
total_needed = 0
for amount in short_amounts:
total_needed = total_needed + amount
# Step 3: FIND THE MAX shortage (track its position so you know the item's name)
most_urgent = 0
for i in range(len(short_amounts)):
if short_amounts[i] > short_amounts[most_urgent]:
most_urgent = i
# Step 4: COMBINE: print "Fully stocked!" if nothing is short, otherwise the report
if len(short_items) == 0:
print("Fully stocked!")
else:
print("Restock needed:")
for i in range(len(short_items)):
print(f"{short_items[i]}: need {short_amounts[i]}")
print("Total items needed:", total_needed)
print(f"Most urgent: {short_items[most_urgent]} (short by {short_amounts[most_urgent]})")
Actual output:
Code Runner Challenge
3.09 Homework - Test 3: Shampoo most urgent
View IPYNB Source
Restock needed:
Blankets: need 12
Shampoo: need 10
Total items needed: 22
Most urgent: Blankets (short by 12)
Matches the expected output exactly.
For the max I track the position (most_urgent) instead of the amount, since short_items and short_amounts line up by index, so the position gives me both the name and the number.
Tests
Each test is a fresh run where only in_stock changes.
Test 1: Main: the homework cell above. Blankets 12, Shampoo 10, total 22, most urgent Blankets.
Test 2: Nothing is short
Prediction: every item is at or above target, so it should print Fully stocked! and nothing else.
# CODE_RUNNER: 3.09 Homework - Test 2: fully stocked
items = ["Toothbrushes", "Blankets", "Socks", "Shampoo", "Notebooks"]
in_stock = [40, 20, 25, 15, 30] # in the closet now
target = [30, 20, 25, 15, 30] # what staff want on hand
# Step 1: COLLECT items below target, and how many of each are needed
short_items = []
short_amounts = []
for i in range(len(items)):
if in_stock[i] < target[i]:
short_items.append(items[i])
short_amounts.append(target[i] - in_stock[i])
# Step 2: SUM the shortages with a loop (no sum())
total_needed = 0
for amount in short_amounts:
total_needed = total_needed + amount
# Step 3: FIND THE MAX shortage (track its position so you know the item's name)
most_urgent = 0
for i in range(len(short_amounts)):
if short_amounts[i] > short_amounts[most_urgent]:
most_urgent = i
# Step 4: COMBINE: print "Fully stocked!" if nothing is short, otherwise the report
if len(short_items) == 0:
print("Fully stocked!")
else:
print("Restock needed:")
for i in range(len(short_items)):
print(f"{short_items[i]}: need {short_amounts[i]}")
print("Total items needed:", total_needed)
print(f"Most urgent: {short_items[most_urgent]} (short by {short_amounts[most_urgent]})")
Actual output: Fully stocked!
Test 3: A different item is most urgent
Prediction: with only 2 Shampoo it’s short by 13, which beats Blankets (12), so the max should switch to Shampoo. Total 12 + 13 = 25.
# CODE_RUNNER: 3.09 Homework - Test 3: Shampoo most urgent
items = ["Toothbrushes", "Blankets", "Socks", "Shampoo", "Notebooks"]
in_stock = [40, 8, 25, 2, 30] # in the closet now
target = [30, 20, 25, 15, 30] # what staff want on hand
# Step 1: COLLECT items below target, and how many of each are needed
short_items = []
short_amounts = []
for i in range(len(items)):
if in_stock[i] < target[i]:
short_items.append(items[i])
short_amounts.append(target[i] - in_stock[i])
# Step 2: SUM the shortages with a loop (no sum())
total_needed = 0
for amount in short_amounts:
total_needed = total_needed + amount
# Step 3: FIND THE MAX shortage (track its position so you know the item's name)
most_urgent = 0
for i in range(len(short_amounts)):
if short_amounts[i] > short_amounts[most_urgent]:
most_urgent = i
# Step 4: COMBINE: print "Fully stocked!" if nothing is short, otherwise the report
if len(short_items) == 0:
print("Fully stocked!")
else:
print("Restock needed:")
for i in range(len(short_items)):
print(f"{short_items[i]}: need {short_amounts[i]}")
print("Total items needed:", total_needed)
print(f"Most urgent: {short_items[most_urgent]} (short by {short_amounts[most_urgent]})")
Actual output: Blankets 12, Shampoo 13, total 25, Most urgent: Shampoo (short by 13).
| Test | in_stock | Expected | Actual | Pass |
|---|---|---|---|---|
| Main | [40, 8, 25, 5, 30] | Blankets 12, Shampoo 10, total 22, most urgent Blankets | same | Yes |
| Fully stocked | [40, 20, 25, 15, 30] | Fully stocked! | Fully stocked! | Yes |
| Different max | [40, 8, 25, 2, 30] | total 25, most urgent Shampoo (13) | same | Yes |
Socks stays at exactly 25/25 in every test and never shows up, so the boundary works. With <= it would’ve been listed as “Socks: need 0”.
Design Thinking
| Step | Notes |
|---|---|
| Need | Before a donation drive, Safe Passage Heals staff need to know what’s missing from the supply closet and what to ask for first. |
| Goal | One report that lists only the short items, the total to collect, and the most urgent item, or just says “Fully stocked!” if nothing’s missing. |
| Methods considered | Built-in sum() / max() vs. writing the loops myself (the lesson wants loops), and tracking the max amount vs. tracking its position. |
| Prototype | Three separate loops (collect, sum, max) and an if / else to combine them. |
| Test | My first version of Step 3 tracked the biggest amount, which gave me 12 but not which item it belonged to. |
| Revision | Switched to tracking the index (most_urgent) so I can pull the name and amount from the two lists. Then reran all 3 tests, including the Shampoo one, to make sure the max actually moves. |