Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
{
"cells": [
{
"cell_type": "raw",
"metadata": {},
"source": "---\nlayout: post\ncourses: { csp: {week: 5} }\ntoc: true\ncomments: false\ntitle: '3.9 Developing Algorithms'\nauthor: Noor Mohammed Saif Bijapur, Yiming Yin, Luke Sanders\ndescription: Compare, trace, and build algorithms using a mountain bike trail matcher.\ncategories: [CSP]\npermalink: /csp/developing-algorithms/trail-matcher\n---"
},
{
"cell_type": "markdown",
"metadata": {},
"source": "# Developing Algorithms\n\n## The Core Idea\n\nTwo algorithms can look completely different and still produce **exactly the same result**. Two algorithms can look almost identical and produce **completely different results**.\n\nHere is the whole lesson in one example. A mountain biker wants to know if a trail fits in the distance they are willing to ride.\n\n```\n// Algorithm A\nIF (trailLength <= maxDistance)\n{\n RETURN(true)\n}\nELSE\n{\n RETURN(false)\n}\n\n// Algorithm B - different code, same result\nRETURN(trailLength <= maxDistance)\n```\n\nAlgorithm B is four lines shorter, but for every possible input it returns the same answer as Algorithm A. Learning to tell when that is true, and when it is *not* true, is what Topic 3.9 is about.\n\n| Term | What it means here |\n| --- | --- |\n| **Equivalent algorithms** | Different code, same result for every input |\n| **Side effect** | A change the algorithm makes beyond its return value, like updating a counter |\n| **Trace** | Stepping through code line by line to predict the output |\n| **Combine** | Using two working algorithms together to solve a bigger problem |\n\n---"
},
{
"cell_type": "markdown",
"metadata": {},
"source": "## What College Board Expects\n\nTopic 3.9 sits inside **Big Idea 3: Algorithms and Programming**, which College Board weights at 30-35% of the AP exam, the largest single portion of the multiple-choice section.\n\nThe topic covers two learning objectives. The first is about **comparing** algorithms. College Board's Essential Knowledge states that *\"Algorithms can be written in different ways and still accomplish the same tasks\"* and that *\"Algorithms that appear similar can yield different side effects or results.\"* It also specifies that *\"Some conditional statements can be written as equivalent Boolean expressions\"* and that the reverse is true as well.\n\nThe second learning objective is about **creating** algorithms: you can write a new algorithm from scratch, combine two existing algorithms, or modify one that already works.\n\n> **Reference:** College Board. *AP Computer Science Principles Course and Exam Description*. Big Idea 3: Algorithms and Programming, Topic 3.9 \"Developing Algorithms,\" Learning Objectives AAP-2.K and AAP-2.L. College Board, 2020.\n\n**Why this matters beyond the exam:** these are the same two skills the Create Performance Task is graded on. When you write your CPT program, you reuse known patterns like finding a maximum or counting matches, then explain in writing how your algorithm works. That explanation is worth points.\n\n### How this lesson is split\n\n| Part | Topic | Presenter |\n| --- | --- | --- |\n| 1 | Algorithms that look different but do the same thing | Luke Sanders |\n| 2 | Algorithms that look the same but do different things | Yiming Yin |\n| 3 | Creating, combining, and modifying algorithms | Noor Mohammed Saif Bijapur |\n\nEvery example uses the same running scenario: a **mountain bike trail matcher** that helps a rider pick trails.\n\n---"
},
{
"cell_type": "markdown",
"metadata": {},
"source": "## Part 1 - Same Result, Different Code\n\n**Presenter: Luke Sanders**\n\nStart with the easier half of 3.9. Two algorithms are **equivalent** when they return the same result for every possible input, even if the code looks nothing alike.\n\nThe most common version of this on the AP exam is swapping a conditional statement for a Boolean expression, or flipping which branch of an `IF` does the work.\n\nBelow, `fitsA` checks whether the trail is short enough. `fitsB` checks whether it is too long and flips the answers. Different logic, identical output.\n\nRun it, then change `trailLength` to `15` and run it again. Both algorithms should still agree."
},
{
"cell_type": "markdown",
"metadata": {},
"source": "{% capture challenge1 %}\nRun both algorithms. They use opposite conditions but return the same answer. Change `trailLength` to 15 and confirm they still agree.\n{% endcapture %}\n\n{% capture code1 %}\ntrailLength ← 8\nmaxDistance ← 10\n\nPROCEDURE fitsA(length, maxDist)\n{\n IF (length <= maxDist)\n {\n RETURN(\"yes\")\n }\n ELSE\n {\n RETURN(\"no\")\n }\n}\n\nPROCEDURE fitsB(length, maxDist)\n{\n IF (length > maxDist)\n {\n RETURN(\"no\")\n }\n ELSE\n {\n RETURN(\"yes\")\n }\n}\n\nDISPLAY(\"Trail length: \" + trailLength)\nDISPLAY(\"Algorithm A says: \" + fitsA(trailLength, maxDistance))\nDISPLAY(\"Algorithm B says: \" + fitsB(trailLength, maxDistance))\n{% endcapture %}\n\n{% include runners/code.html\n runner_id=\"csp-39-part1-equivalent\"\n language=\"pseudocode\"\n challenge=challenge1\n code=code1\n%}"
},
{
"cell_type": "markdown",
"metadata": {},
"source": "### How to check equivalence\n\nYou cannot tell whether two algorithms are equivalent by looking at how similar the code is. You have to compare **behavior**, which means testing the inputs that sit on the boundary.\n\nFor this trail check, the inputs worth testing are:\n\n| Input | Why it matters |\n| --- | --- |\n| `trailLength = 8` | Clearly under the limit |\n| `trailLength = 15` | Clearly over the limit |\n| `trailLength = 10` | Exactly at the limit, where `<=` and `<` disagree |\n\nThat third row is where most \"equivalent\" algorithms turn out not to be. If `fitsB` used `>=` instead of `>`, the two algorithms would agree on 8 and 15 but disagree on 10.\n\n---"
},
{
"cell_type": "markdown",
"metadata": {},
"source": "## Part 2 - Same Code, Different Result\n\n**Presenter: Yiming Yin**\n\nThis is the harder half of 3.9, and the version the exam asks about most. Two algorithms can be nearly character-for-character identical and still produce different output, because of where a single line sits.\n\nA rider has a list of trail lengths and wants to know how many fit within their maximum distance. Both algorithms below loop through the list and count. One of them is wrong.\n\n**Do not run this yet.** Read it first and predict what each algorithm displays."
},
{
"cell_type": "markdown",
"metadata": {},
"source": "{% capture challenge2 %}\nPredict the output of BOTH algorithms before you press Run. Write your two numbers down, then run it and see if you were right.\n{% endcapture %}\n\n{% capture code2 %}\ntrailLengths ← [4, 9, 12, 6, 15]\nmaxDistance ← 10\n\n// Algorithm A\ncountA ← 0\nFOR EACH length IN trailLengths\n{\n IF (length <= maxDistance)\n {\n countA ← countA + 1\n }\n}\nDISPLAY(\"Algorithm A counted: \" + countA)\n\n// Algorithm B\ncountB ← 0\nFOR EACH length IN trailLengths\n{\n IF (length <= maxDistance)\n {\n countB ← countB + 1\n }\n countB ← countB + 1\n}\nDISPLAY(\"Algorithm B counted: \" + countB)\n{% endcapture %}\n\n{% include runners/code.html\n runner_id=\"csp-39-part2-sideeffects\"\n language=\"pseudocode\"\n challenge=challenge2\n code=code2\n%}"
},
{
"cell_type": "markdown",
"metadata": {},
"source": "### Tracing the difference\n\nThe only difference is that Algorithm B has one extra `countB ← countB + 1` **outside** the `IF` block. That single line changes what the algorithm measures.\n\n| Trail length | Algorithm A does | Algorithm B does |\n| --- | --- | --- |\n| 4 | Fits, count becomes 1 | Fits, count becomes 1, then +1 = 2 |\n| 9 | Fits, count becomes 2 | Fits, count becomes 3, then +1 = 4 |\n| 12 | Too long, no change | No match, but +1 anyway = 5 |\n| 6 | Fits, count becomes 3 | Fits, count becomes 6, then +1 = 7 |\n| 15 | Too long, no change | No match, but +1 anyway = 8 |\n\nAlgorithm A answers \"how many trails fit.\" Algorithm B answers \"how many trails fit, plus how many trails exist.\" That second number is not useful to anybody, which is exactly why this bug is hard to notice: the program still runs, still prints a number, and never crashes.\n\nThis is what College Board means by algorithms that *appear similar* yielding *different results*.\n\n> ### Popcorn Hack (in class, 2 minutes)\n>\n> Copy the Algorithm B code above into the runner and **fix it** so it counts the same as Algorithm A. Then answer in one sentence: what number did Algorithm B actually compute, and why would a rider find that number useless?\n>\n> Paste your corrected code and your sentence into the class chat.\n\n---"
},
{
"cell_type": "markdown",
"metadata": {},
"source": "## Part 3 - Creating, Combining, and Modifying\n\n**Presenter: Noor Mohammed Saif Bijapur**\n\nThe second learning objective in 3.9 is about building algorithms rather than comparing them. College Board lists three ways to do it, and you almost never need the first one:\n\n1. **Create** a new algorithm from scratch\n2. **Combine** two existing algorithms\n3. **Modify** an existing algorithm\n\nMost real programs, including your CPT, are built from patterns you already know. Two patterns cover a huge amount of ground:\n\n| Pattern | Shape |\n| --- | --- |\n| **Count matches** | Start at 0, loop, add 1 when a condition is true |\n| **Find the extreme** | Assume the first item wins, loop, replace when you find better |\n\nHere are both, working on the same trail data."
},
{
"cell_type": "markdown",
"metadata": {},
"source": "{% capture challenge3 %}\nTwo separate algorithms built from known patterns. Read how each one works, then run it.\n{% endcapture %}\n\n{% capture code3 %}\ntrailLengths ← [5, 8, 15, 12]\nmaxDistance ← 10\n\n// Pattern 1: count the matches\nPROCEDURE countInRange(lengths, maxDist)\n{\n count ← 0\n FOR EACH length IN lengths\n {\n IF (length <= maxDist)\n {\n count ← count + 1\n }\n }\n RETURN(count)\n}\n\n// Pattern 2: find the extreme\nPROCEDURE findLongest(lengths)\n{\n longest ← lengths[1]\n FOR EACH length IN lengths\n {\n IF (length > longest)\n {\n longest ← length\n }\n }\n RETURN(longest)\n}\n\nDISPLAY(\"Trails within range: \" + countInRange(trailLengths, maxDistance))\nDISPLAY(\"Longest trail: \" + findLongest(trailLengths))\n{% endcapture %}\n\n{% include runners/code.html\n runner_id=\"csp-39-part3-patterns\"\n language=\"pseudocode\"\n challenge=challenge3\n code=code3\n%}"
},
{
"cell_type": "markdown",
"metadata": {},
"source": "### Modifying a pattern\n\n`countInRange` counts trails but does not tell the rider **which** trails. Modifying it takes three changes to the pattern, not a rewrite:\n\n| Counting version | Collecting version |\n| --- | --- |\n| `count ← 0` | `matches ← []` |\n| `count ← count + 1` | `APPEND(matches, name)` |\n| `RETURN(count)` | `RETURN(matches)` |\n\nThe loop and the `IF` condition stay exactly the same. That is what modifying an algorithm looks like: keep the structure, change what it accumulates.\n\n### Combining two algorithms\n\nCombining means using one algorithm's output as another's input, or running both and comparing. For example, a rider could use `countInRange` to check whether *any* trail fits, and only call `findLongest` if the count is greater than zero.\n\n```\nfitCount ← countInRange(trailLengths, maxDistance)\n\nIF (fitCount > 0)\n{\n DISPLAY(\"Found \" + fitCount + \" trails. Longest option: \" + findLongest(trailLengths))\n}\nELSE\n{\n DISPLAY(\"No trails match. Try increasing your max distance.\")\n}\n```\n\nNeither procedure had to change. That is the payoff of building algorithms out of reusable pieces, and it is what earns abstraction points on the CPT.\n\n---"
},
{
"cell_type": "markdown",
"metadata": {},
"source": "## Homework Hack\n\nBuild the trail matcher. You are modifying the counting pattern from Part 3 so it returns **names** instead of a number.\n\nThe starter code below has two lists that line up by position: `trailNames[1]` is the name of the trail whose length is `trailLengths[1]`. Your procedure needs to walk both at once using an index counter, the same way College Board's linear search examples do.\n\n**Your task:** fill in the three `TODO` lines so the program displays the names of every trail within `maxDistance`.\n\n**Expected output:**\n\n```\nTrails you can ride:\nCreek Bed\nSunset Ridge\n```\n\n> **Two reminders:**\n> - College Board pseudocode lists start at index **1**, not 0. Starting your index at 0 will break the program.\n> - To type the assignment arrow yourself, type `<--` and the editor converts it to `←` automatically. Do not type `<-`."
},
{
"cell_type": "markdown",
"metadata": {},
"source": "{% capture challenge4 %}\nFill in the three TODO lines so the procedure returns a list of trail NAMES that fit within maxDistance. Expected output is Creek Bed and Sunset Ridge.\n{% endcapture %}\n\n{% capture code4 %}\ntrailNames ← [\"Creek Bed\", \"Sunset Ridge\", \"Rock Garden\", \"Iron Mountain\"]\ntrailLengths ← [5, 8, 15, 12]\nmaxDistance ← 10\n\nPROCEDURE findMatchingTrails(names, lengths, maxDist)\n{\n matches ← []\n index ← 1\n\n FOR EACH length IN lengths\n {\n // TODO 1: write the IF condition that checks if this trail fits\n\n // TODO 2: APPEND the matching trail NAME to matches\n\n index ← index + 1\n }\n\n // TODO 3: return the matches list\n}\n\nresults ← findMatchingTrails(trailNames, trailLengths, maxDistance)\n\nDISPLAY(\"Trails you can ride:\")\nFOR EACH name IN results\n{\n DISPLAY(name)\n}\n{% endcapture %}\n\n{% include runners/code.html\n runner_id=\"csp-39-homework-matcher\"\n language=\"pseudocode\"\n challenge=challenge4\n code=code4\n%}"
},
{
"cell_type": "markdown",
"metadata": {},
"source": "### Submitting\n\n1. Create a notebook in `_notebooks/homework` in your portfolio.\n2. Add a markdown cell at the top with this frontmatter:\n\n```raw\n---\nlayout: post\ntitle: 3.9 Developing Algorithms HW\ncategories: [CSP]\npermalink: /csp/developing-algorithms-hw\nauthor: githubID\n---\n```\n\n3. Paste your completed pseudocode and your Popcorn Hack answer into the notebook.\n4. Run it and check the output before submitting.\n\n---"
},
{
"cell_type": "markdown",
"metadata": {},
"source": "## Grading Plan (1 point total)\n\n### Popcorn Hack - 0.3 points\n\n- **0.15** - Corrected Algorithm B so it counts only matching trails\n- **0.15** - Explained in one sentence what the broken version actually computed\n\n### Homework Hack - 0.7 points\n\n- **0.3 - Selection.** The `IF` condition correctly compares this trail's length against `maxDist`\n- **0.3 - List handling.** `APPEND` adds the trail **name**, not the length, and the index starts at 1\n- **0.1 - Return value.** The procedure returns `matches`, and the program displays the two expected names\n\n### Quick validation checklist\n\nBefore submitting, confirm all of these:\n\n- Output shows exactly `Creek Bed` and `Sunset Ridge`, in that order\n- The procedure returns a list, not a number\n- `index` starts at `1`\n- No trail lengths appear in the output, only names\n\n---"
},
{
"cell_type": "markdown",
"metadata": {},
"source": "## LxD Cycle Process\n\n> **Team: fill this in after your trial run. These notes are the starting point, not the finished section.**\n\n**Empathize:** Students can usually write a loop that works, but freeze when an exam question shows two loops that look nearly identical and asks which one is correct. The skill being tested is tracing, and it is rarely practiced directly.\n\n**Define:**\n- **POV:** CSP students need practice comparing algorithms by behavior because they currently judge whether two algorithms match by how similar the code looks.\n- **Learning Goal:** Students will determine whether two algorithms produce the same result by tracing them, and will build a new algorithm by modifying a known pattern.\n\n**Ideate:**\n- **HMW Question:** How might we make students trace code before running it, instead of guessing and checking?\n- **Activity:** Show two nearly identical counting loops, require a written prediction, then reveal the output.\n\n**Prototype & Test:** *(Replace this with what actually happened when you tested the lesson on someone outside your group.)*\n\n---"
},
{
"cell_type": "markdown",
"metadata": {},
"source": "## Lesson Revisions & Feedback Evidence\n\n> **Team: this section must be real. Run the lesson past someone before presenting and write down what they said.**\n\n- **Feedback Received:** *(What did your test student find confusing, too long, or too easy?)*\n- **Revision Made:** *(What did you change in response, and why?)*\n\n---\n\n## References\n\nCollege Board. *AP Computer Science Principles Course and Exam Description*. Big Idea 3: Algorithms and Programming, Topic 3.9 \"Developing Algorithms.\" College Board, 2020.\n\nOpen Coding Society. [Create Performance Task Concepts](https://pages.opencodingsociety.com/csp/cpt-concepts). Week 0 lesson on College Board pseudocode syntax.\n\nOpen Coding Society. [Intro to Python](https://pages.opencodingsociety.com/python/intro) and [Intro to JavaScript](https://pages.opencodingsociety.com/javascript/intro/csp/)."
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"name": "python",
"version": "3.12.0"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Loading