{"assignment":{"_schema_version":2,"course_id":37,"date_created":"2022-06-28T19:00:00+00:00","date_modified":"2025-09-14T15:03:53.748261+00:00","extra_instructor_files":"","extra_starting_files":"","forked_id":null,"forked_version":null,"hidden":false,"id":1033,"instructions":"## Introduction to Data Structures\n\n* Lists: A new type that can hold multiple values of the same type.\n* Dataclasses: A way of making new types that combine multiple bits of different kinds of data into one bundle.\n\nPreviously, we have learned about five primitive types: integers, floats, strings, booleans, and the special None value.\nIn this chapter, we get a new type and an entire system for making additional types that greatly extend our capabilities.\nFirst we will learn about dataclasses, that essentially allow us to combine different types of data into a single new type.\nThen we will learn about lists, which is a type that allow us to group together values of the same type into a single value.\nBoth types have mutability, which introduces an exciting new way for our programs to go badly!\n\n## Dataclasses\n\n```python dataclasses\nfrom dataclasses import dataclass\n\n@dataclass\nclass Food:\n    name: str\n    calories: int\n    cost: float\n  \nmilk = Food(\"Jug of Milk\", 2400, 4.33)\napples = Food(\"Bag of Apples\", 285, 1.31)\n\nprint(milk.calories//milk.cost)\nprint(\"Would you like\", apples.name+\"?\")\n```\n\nDataclasses are basically collections of variables that can be combined to represent a single thing.\nTo be clear, dataclasses are not a monolithic type themselves, but a way to make new types.\nIn the example program shown here, we create a new `Food` dataclass and then make *instances* of the new type, storing them in variables named `milk` and `apples`.\nThe syntax for creating dataclasses is a little tricky, requiring not only an `import` but also a new annotation called a decorator (the `@dataclass` bit above the `class` keyword).\nForgetting any part of the syntax will prevent the dataclass from being properly formed, and can cause quite a few errors.\nIn addition to learning the new syntax, you also have to learn quite a bit of terminology.\nDefining the dataclass, or class, creates not only a new type but also gives you a *constructor* function with the same name, which is what is called to create *instances* of the dataclass.\nAfterwards, you can access *fields* (also known as *attributes*) that were passed into the constructor, by using a period and the name of the field.\n\n## Dataclasses in Action\n\n```python dataclasses-in-action\nfrom dataclasses import dataclass\nfrom bakery import assert_equal\n\n@dataclass\nclass Food:\n    name: str\n    calories: int\n    cost: float\n\ndef calories_per_dollar(a_food: Food) -> float:\n    return a_food.calories // a_food.cost\napples = Food(\"Bag of Apples\", 285, 1.31)\nassert_equal(calories_per_dollar(apples), 217.0)\n```\n\nA primary use case for dataclasses is that we can pass them into or return them from functions, reducing the number of parameters we need and letting our functions do more.\nThis requires us to use the dataclasses name as a type in our parameters and header return types, but is otherwise no different than any other type of value being used as a parameter.\nDataclasses really only support two kinds of operations, the equality operator and the attribute lookup with the period.\nHowever, that attribute lookup is extremely powerful, allowing us to access and modify data in the dataclass.\nIn general, attribute lookup is just another kind of expression that results in a value, and can be used in math operations, function calls, and return statements like anything else.\n\n\n## Lists\n\n```python list-examples\n# list[int]\nscores = [100, 95, 33, 85]\n\n# list[str]\nanimals = [\"dog\", \"cat\", \"gerbil\"]\n\n# list\nempty = []\n```\n\nThe other data structure in this chapter is the list, which is used to combine multiple values of the same type.\nLists are created using square brackets with the elements inside separate by commas.\nThe elements should all be of the same type, which becomes the element type of the list.\nIn the example code shown, we have the type that would be used for the list if it were used as a parameter or a return value.\n\n## List Operations\n\n```python list-operations\nanimals = [\"dog\", \"cat\", \"gerbil\"]\n# Indexing\nprint(animals[0])\nprint(animals[-1])\n# Subscripting\nprint(animals[:2])\n# Membership test\nprint(\"cat\" in animals)\nprint(\"rabbit\" in animals)\n# Appending\nanimals.append(\"snake\")\nprint(animals)\n```\n\nMuch more so than dataclasses, lists introduce many operations that you can use to manipulate and access their contents.\nMost of the operators are similar to ones we have previously seen with strings.\nHowever, there are also methods that need to be used in precise ways when it comes to adding new elements to the list.\nThe list operations we cover in this chapter are indexing, subscripting, membership tests, append, and pop.\n\n## Mutability\n\n```python mutability-example\ndef add_5(items: list[int], number: int):\n    items.append(5)\n    number = number + 5\n\nvalues = [1, 2, 3]\nage = 1\nprint(values, age)\n\n# Only `values` changes!\nadd_5(values, age)\nprint(values, age)\n```\n\nIn the final section, we confront one of the great challenges associated with our new data structures: mutability.\nUnlike the primitive types we learned before, both dataclasses and lists are mutable.\nThat means you can manipulate the actual underlying value of the data as opposed to only creating new values in their place.\nWhen you modify a string or an integer, you were never actually modifying those values - you were actually creating new values and changing the variable to hold those new values instead.\nBut with lists and dataclasses, the actual data changes.\nThis has serious implications when it comes to functions, which can suddenly manipulate data outside of our scope rules!\n\n## Drafter\n\n```python drafter-state\nfrom drafter import *\nfrom dataclasses import dataclass\n\n@dataclass\nclass State:\n    name: str\n    age: int\n\n@route\ndef index(state: State) -> Page:\n    return Page(state, Div(\n        TextBox(\"name\", state.name),\n        TextBox(\"age\", state.age),\n        Button(\"Change\", \"update\")\n    ))\n\n@route\ndef update(state: State, name: str, age: int) -> Page:\n    state.name = name\n    state.age = age\n    return index(state)\n\nstart_server(State(\"Alice\", 30))\n```\n\nThis chapter also has two lessons that touch on how composite data structures can be used in Drafter. In fact, Drafter has used dataclasses from the beginning, since all its components (e.g., `Page`, `Div`) are actually just dataclasses. However, dataclasses are also useful to manage complex application state when building interactive web apps with the Python Drafter framework (through the drafter convention of a `State` dataclass). Since Dataclasses can contain multiple fields, such as a user's name and age, routes can read and modify several values at once. Drafter supports both mutable and immutable approaches: you can either change a dataclass instance directly or create a new one with updated data, giving developers flexibility but requiring care to avoid bugs. Later, in the lists half of this chapter, we can return longer, more complicated `Page` content by returning a list instead of a single component.","ip_ranges":"","name":"4) Primer Reading","on_change":"","on_eval":"","on_run":"","owner_id":1,"owner_id__email":"acbart@udel.edu","points":4,"public":true,"reviewed":false,"sample_submissions":[],"settings":"{\n  \"small_layout\": true,\n  \"disable_timeout\": true,\n  \"header\": \"Chapter 4 Primer) Dataclasses\"\n}","starting_code":"","subordinate":true,"tags":[],"type":"reading","url":"bakery_structures_primer_read","version":11},"ip":"216.73.216.157","submission":{"_schema_version":3,"assignment_id":1033,"assignment_version":11,"attempts":0,"code":"","correct":false,"course_id":37,"date_created":"2026-05-20T12:42:02.823436+00:00","date_due":"","date_graded":"","date_locked":"","date_modified":"2026-05-20T12:42:02.823436+00:00","date_started":"","date_submitted":"","endpoint":"","extra_files":"","feedback":"","grading_status":"NotReady","id":2036764,"score":0.0,"submission_status":"Started","time_limit":"","url":"submission_url-3cc1d6fd-bcd7-4924-8746-8dc127dfc75d","user_id":2044660,"user_id__email":"","version":0},"success":true}
