{"assignment":{"_schema_version":2,"course_id":37,"date_created":"2022-06-28T19:00:00+00:00","date_modified":"2026-02-06T19:33:39.940623+00:00","extra_instructor_files":"","extra_starting_files":"","forked_id":null,"forked_version":null,"hidden":false,"id":1039,"instructions":"## Lists\n\n```python list-examples\n# List of integers\nprint([45, 55, 32])\n\n# List of strings\nprint([\"Apples\", \"Oranges\", \"Bananas\"])\n\n# List of booleans\nprint([True, False, True])\n\n# Empty List\nprint([])\n```\n\nThe next data structure we will learn about is the `list` type.\nA list is a sequence of values of the same type.\nFor instance, you could have a list of numbers or a list of strings.\nYou can even have a generic empty list.\nBecause lists are composed of other values, we say they are also a _composite_ data type.\n\n## Element Type\n\n```python integer-list-print\n# list[int]\nprint([45, 55, 32])\n```\n\nUnlike dataclasses, a `list` _is_ a type, much the same way that `int` (short for \"integer\") is a type.\nHowever, the `list` will also have an _element type_, which is what the list is composed of.\nSo, if you have a list of integers, its type is \"list\" and its element type is \"integer.\"\nFor now, the only kind of list that will not have an element type is the empty list.\nSince there are no elements, there is no element type.\n\n## Defining a List\n\n```python integer-list-assignment\nmy_numbers = [45, 55, 32]\n\nprint(my_numbers)\n```\n\nWe create lists using square brackets on their own.\nEach value that we want to put into the list is separated by commas.\nThe square brackets are critical to making the value a list; without them, it is not a list.\n\n## Square Brackets\n\n```python square-brackets\n# Creating lists with square brackets\nvalues = [\"Hello\", \"World\", \"!\"]\n\n# Subscripting with square brackets\nmessage = \"Hello World!\"\nprint(message[1])\n```\n\nWe've seen square brackets used before when we were subscripting and indexing a string.\nConfusingly, Python ALSO uses square brackets for creating lists.\nYou might struggle at first figuring out when you're looking at slicing or list creation.\nThe key is whether the square brackets come AFTER an expression \u2014 that means slicing.\nIf the square brackets are on their own, you have a list.\n\n## Empty Lists\n\n![Two rows of code, with a picture of a bag next to each one. The first line of code is an empty list symbolized by a pair of square brackets, next to an empty bag. The second line of code is a list with three integers inside of the square brackets, next to a bag with three integers inside.](bakery_structures_lists_empty_list.png)\n\nA pair of square brackets with nothing between them creates an empty list.\nAn empty list is like an empty bag: you may not have anything in the bag, but you still have the bag itself.\nEmpty lists do not have an element type until you put something in the list.\n\n## Truthiness of Lists\n\n```python list-truthiness\nmy_money = []\nif my_money:\n    print(\"I have some money!\")\nelse:\n    print(\"I have no money.\")\n\nyour_money = [10, 10, 20, 1, 1]\nif your_money:\n    print(\"You have some money!\")\nelse:\n    print(\"You have no money.\")\n```\n\nWhen used as a conditional, a list value evaluates to `True` unless the list is empty.\nThis matches the truthiness rules for strings.\nUsing the truthiness of lists can be very convenient when writing conditional expressions involving lists.\nIf you want to test if the list is not empty, you just write the name of the variable holding the list.\n\n## Printing Lists\n\n```python printing-lists\nnames = [\"Alice\", \"Bob\", \"Carol\"]\nprint(names)\n# ['Alice', 'Bob', 'Carol']\n```\n\nWhen you print a list, you will notice that the square brackets are printed too.\nIn fact, Python prints each value of the list as if that value were a literal value.\nNotice that the strings have quotes around them now!\n\nWe usually only want to print the entire list value when we are debugging code and want to inspect the value of the list.\nWe will learn other ways to print out the contents of a list so that we can avoid having extra characters.\n\n## The Box Model\n\n![A stack/heap diagram showing the way that a list of integers gets placed on the heap, with an arrow pointing from the variable on the stack.](bakery_structures_list_stack_heap.png)\n\nLists are often shown in diagrams as a row of boxes to help us visualize the data.\nEach box will have a value inside.\nThe boxes may also have numbers below them, showing the indices of the values starting from zero (just like string indexing.) When we store lists inside of variables, we can visualize the data using a stack/heap diagram.\n\nNotice that we draw an arrow from the variable to the list value; when a list is assigned to a variable, we say that the variable points to the given list.\nLike dataclasses, this is more complex than when we only had primitive values in stack frames where the value was placed directly next to the variable.\nHowever, because the list values are kept on the heap, the lists are allowed to grow and shrink in size as needed.\nBut it becomes critical to keep track of the references between the two locations.\n\n## List Type\n\n```python list-type\n# Function that consumes a list of integers\ndef add_numbers(numbers: list[int]) -> int:\n    pass\n\n# Function that consumes a list of strings\ndef join_strings(texts: list[str]) -> str:\n    pass\n\n# Function that makes a generic list\ndef make_list() -> list:\n    pass\n```\n\nWhen you define a function, you need to specify the types of the parameters and the return value.\nIf the function consumes a list and you don't know the element type of the list, you can just use the `list` type like we would `str` (string) or `int` (integer).\nThe left function consumes a list and produces an integer.\nBut if we do know the element type, we include the element type, wrapped in square brackets, after the word `list`.\nFollowing are some examples; we do not know how to implement these functions yet, but they demonstrate how the function headers can be written.\n\n## Terminology: Lists Are Not Arrays\n\n![The term \"List\" is different from the terms \"Array\" or \"Vector\".](bakery_structures_lists_list_terminology.png)\n\nSome people use the word _array_ to describe lists.\nThese are slightly different concepts.\nBasically, an array is like a list, but _arrays have a limited size and work at a much lower level of your computer_.\nPython does support arrays, but they are very rarely used (they require an import, like dataclasses do).\nYou are likely to use arrays in other languages the way that you use lists in Python, so it is not surprising that people use the terms interchangeably.\nDon't be thrown off if someone refers to a list as an \"array,\" but don't use that word yourself! Be aware that they are a **different** data structure.\n\n## Lists in Drafter\n\n```python lists-in-drafter\nfrom drafter import *\n\n@dataclass\nclass State:\n    items: list[str]\n\n@route\ndef index(state: State) -> Page:\n    return Page(state, [\n      Header(\"Grocery List\"),\n      \"Need to pick up the following\",\n      BulletedList(state.items)\n    ])\n\n\nstart_server(State([\"Eggs\", \"Milk\", \"Bread\"]))\n```\n\nLists are a really helpful data structure in Drafter.\nFirst of all, it is common to return a `list` of page content instead of a single component (as we have previously been doing with the `Div` component).\nSecond, some components can natively display lists, like the `BulletedList`, `NumberedList`, and `Table` components.\n\nIn this example, we render a grocery list using a `BulletedList` component.\nThe entire content is actually a list of components, instead of using the `Div` tag. The end result is largely the same, but using a list is slightly shorter and more convenient.\n\n## Testing Lists in Drafter\n\n```python testing-lists-drafter\nfrom drafter import *\n\n@dataclass\nclass State:\n    player1_health: int\n    player2_health: int\n\n@route\ndef index(state: State) -> Page:\n    return Page(state, [\n        Header(\"Player Health\"),\n        \"Player 1: \" + str(state.player1_health),\n        \"Player 2: \" + str(state.player2_health)\n    ])\n\n# Full Test\nassert_equal(index(State(100, 50)).content, [\n    Header(\"Player Health\"),\n    \"Player 1: 100\",\n    \"Player 2: 50\"\n])\n# Test whether list has content anywhere\ncontent = index(State(100, 50)).content\nassert_equal(\"Player 1: 100\" in content, True)\n# Test second item in list\nassert_equal(content[1], \"Player 1: 100\")\n```\n\nDrafter `Page` objects have a `content` field, which is usually actually a list\nof components and strings. The content will be laid out vertically on the page.\n\nWhen we write tests for Drafter applications, we can check the content of the page by accessing the `content` field of the `Page` instance returned by a route function.\nThis allows us to write tests that check the content of the page without having to check the entire structure of the `Page` instance, which would be more difficult to write and maintain.\n\nIn this example, we are checking the content of the page returned by the `index` route function. First, we do a full test that checks the entire content list. Then, we do a test that checks whether a specific string is in the content list. Finally, we do a test that checks the second item in the content list. All three of these tests are valid ways to check the content of the page, and they demonstrate the flexibility of testing lists in Drafter. Note that the first one will give more complete debugging information if the test fails, but it is also more brittle to changes in the content list. The second and third tests are more robust to changes in the content list, but they may not give as much debugging information if the test fails. They also might be brittle if the content list changes significantly; for example, the third test would fail if the order of the items in the list changed (or cause an error if the list became shorter than 2 items), even if the content was still correct.\n\n## Summary\n\n- Lists are a composite data structure that can hold many values of the same type.\n- All the values inside of a list should be the same type, which is known as the \"element type\" of the list.\n- List literals are created using square brackets but should not be confused for square brackets used for slicing strings.\n- The truthiness of a list is based on whether the list is empty (`False`) or not empty (`True`).\n- Functions can consume or produce lists, with the parameter and return types being written like `list[int]`, `list[str]`, or in the case of a generic list, just `list`.\n- Like dataclasses, lists live on the heap, which allows them to grow and shrink to hold any number of elements. We draw arrows from the variable on the stack to the list value on the heap to show the reference relationship.\n- Although a related concept, the term \"array\" is not the same as the term \"list\".\n- Drafter `Page` objects can accept a list of components as their content, and some Drafter components also accept lists (e.g., `BulletedList`, `NumberedList`, `Table`).\n\n","ip_ranges":"","name":"4B1) Lists 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\": \"Lists\",\n  \"slides\": \"bakery_structures_lists.pdf\",\n  \"youtube\": {\n    \"Bart\": \"PNORle-Exs0\",\n    \"Amy\": \"I38uX075700\"\n  },\n  \"summary\": \"In this lesson, you learn about the List type. Unlike the primitive types, the List type is a complex type composed of other types. They are essential for creating programs that do more complex and interesting things at a bigger scale.\",\n  \"small_layout\": true,\n  \"video\": {\n    \"Bart\": \"https://blockpy.cis.udel.edu/videos/bakery_structures_lists-Bart.mp4\",\n    \"Amy\": \"https://blockpy.cis.udel.edu/videos/bakery_structures_lists-Amy.mp4\"\n  }\n}","starting_code":"","subordinate":true,"tags":[],"type":"reading","url":"bakery_structures_lists_read","version":8},"ip":"216.73.216.157","submission":{"_schema_version":3,"assignment_id":1039,"assignment_version":8,"attempts":0,"code":"","correct":false,"course_id":37,"date_created":"2026-05-20T12:51:54.137078+00:00","date_due":"","date_graded":"","date_locked":"","date_modified":"2026-05-20T12:51:54.137078+00:00","date_started":"","date_submitted":"","endpoint":"","extra_files":"","feedback":"","grading_status":"NotReady","id":2036883,"score":0.0,"submission_status":"Started","time_limit":"","url":"submission_url-a4d8fa90-dc78-4f95-b53a-14d2c8b2260e","user_id":2044663,"user_id__email":"","version":0},"success":true}
