{"assignment":{"_schema_version":2,"course_id":37,"date_created":"2022-06-28T19:00:00+00:00","date_modified":"2023-09-10T14:05:53.094289+00:00","extra_instructor_files":"","extra_starting_files":"","forked_id":null,"forked_version":null,"hidden":false,"id":1068,"instructions":"## Many Loop Patterns\n\n- **Count:** For counting the number elements in a list.\n- **Sum:** For adding up a list of numbers.\n- **Accumulate:** For combining a list of strings or a list of Booleans.\n- **Map:** For transforming the elements of a list.\n- - **Filter:** Remove/keep elements that match a condition.\n\nThere are so many ways to use `for` loops.\nIn this lesson, we will see a few common patterns.\nThe patterns shown here are just starting points.\nLike the `if` patterns we saw before, think of these patterns as templates that can be adapted and combined to solve more complex problems.\n\n## The Count Pattern\n\n```python count-pattern\na_list = [\"Alpha\", \"Beta\", \"Gamma\"]\n\ncount = 0\nfor item in a_list:\n    count = count + 1\n\nprint(count)\n```\n\n\nWe have a list of items and want to know how many there are.\nA simple algorithm is:\n\nStart with an initial value of 0.\nFor each element, add 1 to a `count` variable. \nWhen the loop is finished, the `count` variable will have the length of the list.\n\nThe code shown here demonstrates how the pattern is written in practice.\nNote that the `item` iteration variable is never actually used, unlike in other patterns!\n\n## The Sum Pattern\n\n```python sum-pattern\na_list = [10, 30, 20]\n\nsum = 0\nfor item in a_list:\n    sum = sum + item\n\nprint(sum)\n```\n\nWe have a list of numbers and want to add them all up.\nThe plus operator can only take two items at a time, however.\nTherefore, we add each element one at a time to a \"sum\" variable, which is also initialized to 0.\nAs you can see, the sum pattern is like the count pattern, except instead of adding 1, we are adding the iteration variable.\n\n\n## Accumulator Pattern\n\n```python\nresult = ___\nfor item in a_list:\n    result = result ___ item\n```\n\nThe sum and count patterns are both more specific examples of the accumulate pattern.\nIn general, this pattern allows us to start with an initial value and use any function or operation that takes in two values.\nThis process of accumulation is also sometimes known as \"reducing\" or \"folding\" a list.\nThis pattern can be applied to numbers, but it also works for strings, Booleans, and any type that can be combined with an operator that takes two operands.\nYou must think critically about what the initial value should be and what operator you will use to combine them.\n\n## String Accumulation\n\n```python string-accumulation\nsentence = \"\"  # Start with an empty string\nwords = [\"Hello, \", \"how \", \"are \", \"you?\"]\n\n# Add the words one by one\nfor word in words:\n    sentence += word\n\nprint(sentence)\n# Output: Hello, how are you?\n```\n\nTechnically, string accumulation is no different than the summation pattern.\nThe only difference is that strings are added together instead of integers.\nThe result is a single string with all the source strings joined together.\nSo, string accumulation is the process of gradually building up a string by adding more characters or other strings to it.\n\n## Boolean Accumulation (any/all)\n\n```python boolean-accumulation\nanswers = [True, True, False, True]\n\n# Any True?\nany_true = False\nfor answer in answers:\n    any_true = any_true or answer\nprint(any_true)\n\n# All True?\nall_true = True\nfor answer in answers:\n    all_true = all_true and answer\nprint(all_true)\n```\n\nThe Boolean accumulation patterns come in two versions: the \"any\" and the \"all.\" With \"any,\" we start with an initial value of `False`.\nThen we check if either the current element is `True` or if the accumulation variable is `True`.\nIf at any point we encounter a `True` value in the list, then the accumulation variable becomes `True` and will evaluate to `True` in every subsequent check.\nOn the other hand, the \"all\" variant starts off with the initial value of `True`.\nEach check is whether the current element is `True` and if the accumulation variable is still `True`.\nIf at any point we encounter a `False` value in the list, then the accumulation variable becomes `False` and will evaluate to `False` in every subsequent check.\n\n## Boolean Accumulation in Action\n\n```python boolean-accumulation-example\nfrom bakery import assert_equal\n\ndef any_red(colors: list[str]) -> bool:\n    result = False\n    for color in colors:\n        result = result or color == \"red\"\n    return result\n\nassert_equal(any_red([\"blue\", \"red\", \"green\"]), True)\nassert_equal(any_red([\"r\", \"g\", \"b\"]), False)\n```\n\nBoolean accumulation is more powerful than it appears at first.\nThe key insight is that the pattern works on more than just a list of Boolean values.\nYou can use an expression that produces a Boolean to ask a question about each element of a list.\nNote that no `if` statement is required; we are simply using `or` to combine logical conditions together and return the final Boolean result.\n\n## The Map Pattern\n\n```python map-pattern\nold_list = [\"Apple\", \"Grape\", \"Orange\"]\n\ncopied_list = []\nfor item in old_list:\n    copied_list.append(item)\n\nprint(copied_list)\n```\n\nWhat happens when we accumulate a list? If we start with an empty list as our initial value and append each value one at a time, we end up with a copy of the original list.\nWe could then make further modifications to the new list without worrying about changing the original list.\nThis is the key idea of the map pattern.\n\n## Modifying a List with the Map Pattern\n\n```python modifying-map-pattern\nfruits = [\"Apple\", \"Grape\", \"Orange\"]\n\nplural_fruits = []\nfor fruit in fruits:\n    plural_fruits.append(fruit + \"s\")\n\nprint(plural_fruits)\n```\n\nAs we're appending values, we can also modify them.\nFor example, you could double each value from the old list, or convert each temperature from Fahrenheit to Celsius.\nIn this program, we are simply adding the string `\"s\"` to the end of each fruit to make the plural version of the word.\nHowever, any valid operation or expression can be used as arguments to the `append` method, allowing us to transform each element of the list.\n\n## Accidental Infinite Loop\n\n```python\nfruits = [\"Apple\", \"Grape\", \"Orange\"]\n\nplural_fruits = []\nfor fruit in fruits:\n    # Uh oh, incorrect accumulation variable!\n    fruits.append(fruit + \"s\")\n\nprint(plural_fruits)\n```\n\nDo you see the mistake in the program shown here? If you tried running it, you would find your program taking a very long time.\nIn fact, it might take forever! The problem is that we are appending to the very same list that we are iterating over.\nIf you append to the `fruits` list while you iterate through the `fruits` list, the `for` loop will keep finding new elements to process.\nPython is more than happy to keep going around in circles until you stop the program or the end of time - whichever comes first.\n\n## The Filter Pattern\n\n```python filter-map-pattern\nnumbers = [50, 100, 200]\n\n# Filter+Map\nnew_list = []\nfor number in numbers:\n    if number < 100:\n        new_list.append(number)\nprint(new_list)\n```\n\nWe have a list of numbers and want to ignore some of them according to a rule.\nBy embedding an IF statement inside the loop, we can optionally include or not include elements in our accumulation.\nThis is the filter pattern, which is more of an optional modification we can make to our other patterns.\nIn the example shown, we have the filter pattern combined with the map pattern.\nTracing the flow of this program can be a little tricky, but keep in mind that it's the same rules as we've seen before.\nThe body of the `for` loop is repeated however many times there are items in the list.\nEach time, the `if` statement's condition is considered, and if `True` then its body with the `append` statement is executed.\nWhen the `for` loop is entirely done, we execute the `print` statement after the `for` loop.\n\n## The Filter Pattern with Count\n\n```python filter-count-pattern\nnumbers = [50, 100, 200]\n\n# Filter + Count\nresult = 0\nfor number in numbers:\n    if number <= 100:\n        result = result + 1\nprint(result)\n```\n\nThe filter pattern is very compatible with the other patterns.\nIn the example shown, we have a variant of the pattern being combined with the count pattern.\nThe basic code structure is the same, with an `if` statement inside of our `for` loop.\nThe big difference comes in the initial value and accumulation step, which match the count pattern instead of the map pattern.\n\n## Inside or Outside of the Body\n\n```python\n# Before\nfor item in a_list:\n    # Inside\n    pass\n# After\n```\n\nNovices struggle with what goes inside or outside of a loop body.\nRemember: Every statement inside the body is executed for each element.\nOnly put things inside if they should happen for each element.\nThe patterns can help you keep track of where things go, but ultimately, you must think critically to know.\n\n## Patterns in Functions\n\n```python patterns-functions\nfrom bakery import assert_equal\n\ndef count_3s(numbers: list[int]) -> int:\n    total = 0\n    for number in numbers:\n        if number == 3:\n            total = total+1\n    return total\n\nassert_equal(count_3s([1, 2, 3]), 1)\nassert_equal(count_3s([3, 3, 3, 3]), 4)\n```\n\nOften, you will use these patterns inside of functions that consume lists.\nAll the same rules about indentation and scope apply as before.\nHowever, it can be confusing to put these complex pieces together.\nIt may not be clear where the `return` statement goes relative to the body of the `for` loop.\nIn the example program shown here, you will notice that the `return` statement goes AFTER the body of the `for` loop, OUTSIDE of the `if` statement, but INSIDE the body of the function definition.\n\n## Summary\n\n- We suggest several `for` loop patterns that can help you structure programs that operate on lists of data:\n  - The count pattern is used to determine the number of elements in a list.\n  - The sum pattern is used to add up a list of integers or floats.\n  - The accumulate pattern can be used to combine strings or Booleans.\n  - The map pattern is used to transform elements of a list, either into new values or possibly even new types of values.\n  - The filter pattern removes or keeps elements that match a condition.\n- Boolean accumulation comes in two varieties: the any pattern finds if any values in a list of Booleans is True, and the all pattern finds if all values in a list of Booleans are True.\n- The map pattern can be dangerous because if you mistakenly append to the list you are iterating over, the program might never end (it will loop infinitely).\n- The filter pattern is compatible with not only the map pattern but also the sum and count patterns.\n- A statement can be before, after, inside, or outside of a loop body.\n- Loop patterns can be used inside of functions, just like any other pattern.\n\n","ip_ranges":"","name":"6A2) For Loop Patterns 1 Reading","on_change":"","on_eval":"","on_run":"","owner_id":1,"owner_id__email":"acbart@udel.edu","points":0,"public":true,"reviewed":false,"sample_submissions":[],"settings":"{\n  \"header\": \"Loop Patterns\",\n  \"slides\": \"bakery_for_patterns.pdf\",\n  \"youtube\": {\n    \"Bart\": \"HUg0SeO1q-Y\",\n    \"Amy\": \"rfLfbB-UVDI\"\n  },\n  \"summary\": \"This lesson builds further on the lesson from the previous day. There are many common ways that FOR loops are used, and the best way to learn this looping structure in general is to learn some core patterns.\",\n  \"small_layout\": true,\n  \"video\": {\n    \"Bart\": \"https://blockpy.cis.udel.edu/videos/bakery_for_patterns-Bart.mp4\",\n    \"Amy\": \"https://blockpy.cis.udel.edu/videos/bakery_for_patterns-Amy.mp4\"\n  }\n}","starting_code":"","subordinate":true,"tags":[],"type":"reading","url":"bakery_for_patterns_read","version":9},"ip":"216.73.216.157","submission":{"_schema_version":3,"assignment_id":1068,"assignment_version":9,"attempts":0,"code":"","correct":false,"course_id":37,"date_created":"2026-05-20T14:01:43.532182+00:00","date_due":"","date_graded":"","date_locked":"","date_modified":"2026-05-20T14:01:43.532182+00:00","date_started":"","date_submitted":"","endpoint":"","extra_files":"","feedback":"","grading_status":"NotReady","id":2036906,"score":0.0,"submission_status":"Started","time_limit":"","url":"submission_url-63dbcfd2-b79a-4de1-92ff-333ee54c1cc8","user_id":2044668,"user_id__email":"","version":0},"success":true}
