{"assignment":{"_schema_version":2,"course_id":37,"date_created":"2025-10-09T18:00:00+00:00","date_modified":"2025-10-23T14:19:51.611272+00:00","extra_instructor_files":"{\"&food_simple.tsv\": \"Tuna\\tTuna, canned, water pack\\t26155190\\t19.0\\nFish\\tFish, NS as to type, baked or broiled, made with cooking spray\\t26100124\\t22.75\\nCrumpet\\tCrumpet\\t52101040\\t8.87\\nPotato chips\\tPotato chips, fat free\\t71201060\\t7.03\\nCreamy dressing\\tCreamy dressing, fat free\\t83300300\\t1.4\\nCrepe\\tCrepe, plain\\t55401000\\t8.78\\nPotato salad\\tPotato salad, made with creamy dressing\\t71603030\\t1.59\\nMushroom soup\\tMushroom soup, cream of, canned, reduced sodium, prepared with water\\t75607140\\t0.61\\nNectarine\\tNectarine, raw\\t63131010\\t1.06\\nTurnip greens\\tTurnip greens, fresh, cooked, no added fat\\t72128211\\t1.14\\nBear\\tBear, cooked\\t23323500\\t32.28\\nGeneral Tso chicken\\tGeneral Tso chicken\\t27445150\\t12.9\\nEgg omelet or scrambled egg\\tEgg omelet or scrambled egg, made with animal fat or meat drippings\\t32130040\\t11.85\\nRoll\\tRoll, NS as to major flour\\t51000200\\t9.77\\nPotato salad with egg\\tPotato salad with egg, made with light mayonnaise-type salad dressing\\t71601025\\t2.72\\nWaffle\\tWaffle, plain, reduced fat\\t55211050\\t9.03\\nMacaroni or noodles with cheese and frankfurters or hot dogs\\tMacaroni or noodles with cheese and frankfurters or hot dogs\\t58145160\\t6.29\\nFlounder\\tFlounder, coated, baked or broiled, made with butter\\t26115131\\t13.92\\nSausage with tomato-based sauce\\tSausage with tomato-based sauce\\t27120110\\t13.28\\nCereal (Post Honey Bunches of Oats with Almonds)\\tCereal (Post Honey Bunches of Oats with Almonds)\\t57237300\\t7.7\\nSteak\\tSteak, NS as to type of meat, cooked, lean and fat eaten\\t21001010\\t27.06\\nYogurt\\tYogurt, whole milk, baby food, with fruit and multigrain cereal puree, NFS\\t11480020\\t3.4\\nHam\\tHam, smoked or cured, cooked, lean and fat eaten\\t22311010\\t20.09\\nCereal (Uncle Sam)\\tCereal (Uncle Sam)\\t57408100\\t15.98\\nPotato\\tPotato, baked, peel not eaten, with chili\\t71507030\\t4.04\\nPralines\\tPralines\\t91735000\\t2.1\\nCheese\\tCheese, Colby\\t14104200\\t23.76\\nRussian dressing\\tRussian dressing, light\\t83206000\\t0.5\\nPork\\tPork, NS as to cut, cooked, NS as to fat eaten\\t22000100\\t27.69\\nShrimp teriyaki\\tShrimp teriyaki\\t27150410\\t21.62\\nCornmeal mush\\tCornmeal mush, no added fat\\t56201516\\t1.12\\nPeanut butter morsels\\tPeanut butter morsels\\t91734500\\t18.3\\nTurkey\\tTurkey, ground\\t24207000\\t27.14\\nCorn flour patty or tart\\tCorn flour patty or tart, fried\\t52207010\\t3.98\\nFlan\\tFlan\\t13210350\\t5.27\\nCrackers\\tCrackers, wheat, reduced fat\\t54338100\\t9.34\\nGrapefruit juice\\tGrapefruit juice,100%, frozen, reconstituted\\t61201620\\t0.55\\nChicken or turkey broth\\tChicken or turkey broth, bouillon, or consomme\\t28340110\\t0.64\\nChicken or turkey salad\\tChicken or turkey salad, made with any type of fat free dressing\\t27446260\\t13.37\\nTurkey ham\\tTurkey ham, prepackaged or deli, luncheon meat\\t25230800\\t19.6\\nCream puff\\tCream puff, no filling or icing\\t53420250\\t9.0\\nCrab\\tCrab, soft shell, coated, fried\\t26307140\\t18.93\\nWhite pizza\\tWhite pizza, cheese, with meat, thick crust\\t58107224\\t12.84\\nIce cream\\tIce cream, vanilla\\t13110100\\t3.5\\nSweet potato\\tSweet potato, canned, fat added\\t73407060\\t1.58\\nPotato\\tPotato, baked, peel not eaten, with butter\\t71507005\\t1.9\\nPork egg foo yung\\tPork egg foo yung\\t32105220\\t13.36\\nGreen beans\\tGreen beans, fresh, cooked, no added fat\\t75205021\\t1.9\\nLamb or mutton goulash\\tLamb or mutton goulash\\t27130050\\t13.07\\nCodfish salad\\tCodfish salad, Puerto Rican style, Serenata\\t27451070\\t6.61\\nPizza\\tPizza, cheese and vegetables, gluten-free thick crust\\t58109150\\t6.68\\nFish sandwich\\tFish sandwich, fried, on wheat bun, with cheese\\t27550415\\t16.02\\nCrackers\\tCrackers, wheat, flavored (Wheat Thins)\\t54338020\\t8.94\\nCereal or granola bar with nuts\\tCereal or granola bar with nuts, chocolate coated\\t53714220\\t9.6\\nPizza with extra meat\\tPizza with extra meat, medium crust\\t58106655\\t13.85\\nInfant formula\\tInfant formula, NS as to form (PurAmino)\\t11740320\\t1.81\\nSalisbury steak with gravy\\tSalisbury steak with gravy, potatoes, vegetable, frozen meal\\t28110310\\t6.82\\nPotato\\tPotato, mashed, from fresh, made with milk, with gravy\\t71501012\\t1.86\\nChicken leg\\tChicken leg, drumstick and thigh, grilled without sauce, skin not eaten\\t24134101\\t23.87\\nOysters\\tOysters, baked or broiled, fat added\\t26315120\\t6.81\\nFrankfurter or hot dog sandwich\\tFrankfurter or hot dog sandwich, reduced fat or light, plain, on whole wheat bun\\t27564302\\t14.58\\nBeef steak\\tBeef steak, fried, NS as to fat eaten\\t21102110\\t29.23\\nCereal (Kellogg's Froot Loops)\\tCereal (Kellogg's Froot Loops)\\t57213000\\t5.3\\nGarlic bread\\tGarlic bread, with parmesan cheese, from fast food / restaurant\\t51121045\\t8.76\\nFrench toast sticks\\tFrench toast sticks, plain, from frozen\\t55301031\\t7.53\\nFlowers or blossoms of sesbania\\tFlowers or blossoms of sesbania, squash, or lily, cooked\\t75217301\\t1.06\\nCoffee creamer\\tCoffee creamer, liquid, flavored\\t12210210\\t0.69\\nCream puff\\tCream puff, eclair, custard or cream filled, not iced\\t53420100\\t4.92\\nHalibut\\tHalibut, coated, baked or broiled, made with cooking spray\\t26118034\\t20.47\\nFrozen yogurt\\tFrozen yogurt, vanilla\\t11460000\\t3.0\\nSeasoned shredded soup meat\\tSeasoned shredded soup meat\\t27418110\\t18.22\\nTurnover filled with meat and vegetable\\tTurnover filled with meat and vegetable, no potatoes, no gravy\\t58126170\\t10.66\\nBeef\\tBeef, rice, and vegetables excluding carrots, broccoli, and dark-green leafy; mushroom sauce\\t27315320\\t5.81\\nYeast extract spread\\tYeast extract spread\\t75236500\\t23.88\\nCookie\\tCookie, marshmallow, with rice cereal and chocolate chips\\t53226550\\t4.55\\nSports drink\\tSports drink, NFS\\t95321000\\t0.0\\nQueso cotija\\tQueso cotija\\t14134000\\t20.0\\nPan Dulce\\tPan Dulce, with fruit, no frosting\\t51161000\\t6.2\\nPork ears\\tPork ears, tail, head, snout, miscellaneous parts, cooked\\t22705010\\t26.14\\nTaco or tostada with chicken and sour cream\\tTaco or tostada with chicken and sour cream\\t58101525\\t11.01\\nEgg omelet or scrambled egg\\tEgg omelet or scrambled egg, with vegetables other than dark green and/or tomatoes, NS as to fat\\t32130510\\t10.71\\nInfant formula\\tInfant formula, powder, made with tap water (Similac Isomil Soy)\\t11720417\\t1.58\\nMILKY WAY MIDNIGHT Bar\\tMILKY WAY MIDNIGHT Bar\\t91726140\\t3.2\\nBeef\\tBeef, noodles, and vegetables excluding carrots, broccoli, and dark-green leafy; mushroom sauce\\t27313320\\t6.63\\nSoy nuts\\tSoy nuts\\t41410010\\t38.55\\nLima beans and corn\\tLima beans and corn, cooked, no added fat\\t75301110\\t4.3\\nBeef\\tBeef, potatoes, and vegetables including carrots, broccoli, and/or dark-green leafy; cream sauce, white sauce, or mushroom sauce\\t27311610\\t5.28\\nTilapia\\tTilapia, baked or broiled, made with oil\\t26158010\\t24.55\\nWinter melon\\tWinter melon, cooked\\t75235750\\t0.4\\nSalami\\tSalami, made from any type of meat, reduced fat\\t25221505\\t19.2\\nTurkey or chicken and beef sausage\\tTurkey or chicken and beef sausage\\t25220650\\t16.47\\nIce cream\\tIce cream, chocolate, with additional ingredients\\t13110112\\t3.93\\nSugar cane beverage\\tSugar cane beverage\\t92612010\\t0.0\\nCoffee\\tCoffee, Latte, nonfat\\t92101901\\t2.87\\nGreen beans and potatoes\\tGreen beans and potatoes, baby food, strained\\t76402000\\t2.2\\nBeef stew\\tBeef stew, meat with gravy, no potatoes, Puerto Rican style\\t27118180\\t16.52\\nTilapia\\tTilapia, baked or broiled, no added fat\\t26158013\\t25.29\\nCongee\\tCongee, with meat, poultry, and/or seafood\\t58157300\\t4.81\\nChicken or turkey stew with potatoes and vegetables including carrots\\tChicken or turkey stew with potatoes and vegetables including carrots, broccoli, and/or dark-green leafy; gravy\\t27341310\\t6.08\\nCake\\tCake, shortcake, sponge type, with fruit\\t53123080\\t4.44\\nCorn\\tCorn, frozen, cooked, no added fat\\t75216112\\t2.54\\nMargarine\\tMargarine, tub\\t81102020\\t0.17\\nApple juice\\tApple juice, with added calcium, baby food\\t67202010\\t0.06\\nCookie\\tCookie, chocolate sandwich\\t53209015\\t5.21\\nEgg omelet or scrambled egg\\tEgg omelet or scrambled egg, with cheese, meat, tomatoes, and dark-green vegetables, fat added\\t32131060\\t12.21\\nCereal (General Mills Fiber One Honey Clusters)\\tCereal (General Mills Fiber One Honey Clusters)\\t57206710\\t7.69\\nCaramel candy\\tCaramel candy, chocolate covered\\t91703040\\t5.3\\nHamburger (Burger King)\\tHamburger (Burger King)\\t27510551\\t13.63\\nAlmonds\\tAlmonds, unroasted\\t42101000\\t21.15\\nPotato\\tPotato, french fries, with cheese, school\\t71401041\\t4.55\\nBeef\\tBeef, dumplings, and vegetables including carrots, broccoli, and/or dark-green leafy; gravy\\t27317100\\t6.09\\nHam and vegetables excluding carrots\\tHam and vegetables excluding carrots, broccoli, and dark-green leafy; no potatoes, no sauce\\t27420270\\t7.56\\nHollandaise sauce\\tHollandaise sauce\\t81302010\\t5.3\\nFrankfurter or hot dog sandwich\\tFrankfurter or hot dog sandwich, beef and pork, plain, on whole wheat bun\\t27564122\\t11.47\\nVenison/deer steak\\tVenison/deer steak, cooked, NS as to cooking method\\t23321200\\t29.8\\nCoffee\\tCoffee, pre-sweetened with sugar\\t92130020\\t0.1\\nPotato salad\\tPotato salad, made with Italian dressing\\t71603040\\t1.44\\nEgg omelet or scrambled egg\\tEgg omelet or scrambled egg, with tomatoes and dark-green vegetables, fat added\\t32130460\\t10.47\\nInfant formula\\tInfant formula, liquid concentrate, made with water, NFS (Gerber Good Start Soy)\\t11720612\\t1.63\\nBroccoli\\tBroccoli, cooked, from restaurant\\t72201190\\t2.8\\nBean and ham soup\\tBean and ham soup, canned, reduced sodium, prepared with water or ready-to-serve\\t41601160\\t4.19\\nCod\\tCod, coated, baked or broiled, made with cooking spray\\t26109134\\t17.27\\nBread\\tBread, Italian, Grecian, Armenian, toasted\\t51109040\\t10.43\\nPizza\\tPizza, cheese, from school lunch, thin crust\\t58106235\\t12.72\\nChicken drumstick\\tChicken drumstick, stewed, skin not eaten\\t24143220\\t23.71\\nFruit and vegetable smoothie\\tFruit and vegetable smoothie, non-dairy, added protein\\t78101118\\t7.18\\nPasta\\tPasta, whole grain, with cream sauce and meat, home recipe\\t58146702\\t6.34\\nPork chop\\tPork chop, broiled or baked, NS as to fat eaten\\t22101100\\t27.69\\nPasta\\tPasta, cooked\\t56130000\\t5.76\\nChicken\\tChicken, tail\\t24198340\\t20.36\\nTopping from meat and vegetable pizza\\tTopping from meat and vegetable pizza\\t14620330\\t17.55\\nTurkey or chicken sausage\\tTurkey or chicken sausage, reduced fat\\t25221860\\t19.65\\nGreen peas\\tGreen peas, fresh, cooked, no added fat\\t75224021\\t5.63\\nCatfish\\tCatfish, coated, baked or broiled, made with cooking spray\\t26107134\\t17.23\\nPancakes\\tPancakes, with chocolate\\t55103100\\t7.7\\n3 MUSKETEERS Bar\\t3 MUSKETEERS Bar\\t91726420\\t2.6\\nCoffee substitute\\tCoffee substitute, dry powder\\t92291300\\t6.01\\nFruit flavored drink\\tFruit flavored drink, diet\\t92550620\\t0.01\\nPineapple\\tPineapple, canned, NFS\\t63141110\\t0.42\\nHam salad spread\\tHam salad spread\\t25240220\\t8.68\\nCarp\\tCarp, coated, baked or broiled, no added fat\\t26105131\\t19.82\\nCereal (General Mills Cheerios Honey Nut)\\tCereal (General Mills Cheerios Honey Nut)\\t57241000\\t8.85\\nOnion dip\\tOnion dip, light\\t12350225\\t2.0\\nPotato tots\\tPotato tots, frozen, baked\\t71505040\\t2.03\\nBeef\\tBeef, potatoes, and vegetables excluding carrots, broccoli, and dark-green leafy; cheese sauce\\t27311640\\t8.17\\nVegetable noodle soup\\tVegetable noodle soup, home recipe\\t75649150\\t2.17\\nEgg omelet or scrambled egg\\tEgg omelet or scrambled egg, with dark-green vegetables, no added fat\\t32130440\\t11.28\\nPizza with meat and vegetables\\tPizza with meat and vegetables, from frozen, thin crust\\t58106700\\t11.28\\nPotato\\tPotato, hash brown, ready-to-heat\\t71405040\\t2.62\\nChili con carne with chicken or turkey and beans\\tChili con carne with chicken or turkey and beans\\t27141500\\t8.42\\nEgg\\tEgg, whole, baked, no added fat\\t31106010\\t12.52\\nLight ice cream bar\\tLight ice cream bar, vanilla\\t13140000\\t3.23\\nGrits\\tGrits, with cheese, no added fat\\t56201091\\t3.6\\nWhite pizza\\tWhite pizza, cheese, with vegetables, thin crust\\t58107212\\t10.13\\nPotato\\tPotato, hash brown, from fast food\\t71404010\\t2.58\\nPancakes\\tPancakes, cornmeal\\t55105100\\t4.77\\nChocolate milk\\tChocolate milk, made from dry mix with reduced fat milk\\t11513150\\t3.42\\nMilk shake\\tMilk shake, bottled, flavors other than chocolate\\t11543010\\t3.37\\nGreens\\tGreens, NS as to form, cooked\\t72118220\\t2.89\\nInfant formula\\tInfant formula, ready-to-feed (Enfamil ProSobee)\\t11720311\\t1.62\\nTzatziki dip\\tTzatziki dip\\t11440060\\t5.35\\nPie\\tPie, rhubarb, two crust\\t53311000\\t3.39\\nGarlic sauce\\tGarlic sauce\\t81301000\\t1.4\\nBiscuit\\tBiscuit, from refrigerated dough\\t52102040\\t6.79\\nOlives\\tOlives, black\\t75510020\\t0.84\\nCrackers\\tCrackers, butter, flavored\\t54301020\\t6.64\\nEgg omelet or scrambled egg\\tEgg omelet or scrambled egg, NS as to fat\\t32129990\\t11.72\\nCookie\\tCookie, gingersnaps\\t53223000\\t5.6\\nMixed cereal with bananas\\tMixed cereal with bananas, baby food, dry, instant\\t57806000\\t10.7\\nFried mushrooms\\tFried mushrooms\\t75414030\\t4.6\\nSports drink\\tSports drink, low calorie (Powerade Zero)\\t95322500\\t0.0\\nPastry\\tPastry, meat / poultry-filled\\t58124230\\t11.27\\nGreen beans\\tGreen beans, frozen, cooked, no added fat\\t75205022\\t1.49\\nCereal (Kellogg's Low Fat Granola)\\tCereal (Kellogg's Low Fat Granola)\\t57229000\\t9.96\\nRice\\tRice, brown, with peas, NS as to fat\\t58161430\\t3.18\\nChili con carne without beans\\tChili con carne without beans\\t27111420\\t7.53\\nSnowpea\\tSnowpea, frozen, cooked, fat added\\t75231022\\t3.4\\nRice\\tRice, brown, with dark green vegetables and tomatoes and/or tomato-based sauce, NS as to fat\\t58161490\\t2.41\\nSpinach and artichoke dip\\tSpinach and artichoke dip\\t14620115\\t4.0\\nChinese pancake\\tChinese pancake\\t55501000\\t4.05\\nBread\\tBread, egg, Challah\\t51119010\\t9.5\\nHot chocolate / Cocoa\\tHot chocolate / Cocoa, made with dry mix and whole milk\\t11514110\\t3.73\\nYam buns; Puerto Rican style\\tYam buns; Puerto Rican style\\t71945020\\t3.47\\nVada\\tVada, fried dumpling\\t58175000\\t12.75\\nApple\\tApple, baked\\t63101310\\t0.32\\nInfant formula\\tInfant formula, liquid concentrate, made with water, NFS (Similac Isomil Soy)\\t11720412\\t1.58\\nSweet potato fries\\tSweet potato fries, from fresh, fried\\t73410330\\t1.74\\nVenison/deer\\tVenison/deer, cured\\t23321050\\t35.11\\nFish\\tFish, NS as to type, coated, baked or broiled, made with margarine\\t26100132\\t19.22\\nOatmeal\\tOatmeal, regular or quick, made with non-dairy milk, NS as to fat\\t56203075\\t3.21\\nTurkey\\tTurkey, ham, and roast beef club sandwich, with lettuce, tomato and spread\\t27541000\\t7.8\\nPears and pineapple\\tPears and pineapple, baby food, junior\\t67114020\\t0.3\\nFish\\tFish, NS as to type, from fast food\\t26100200\\t13.49\\nTea\\tTea, hot, leaf, green, decaffeinated\\t92303100\\t0.0\\nPotato tots\\tPotato tots, frozen, fried\\t71505050\\t1.9\\nMilk shake\\tMilk shake, home recipe, flavors other than chocolate, light\\t11541135\\t3.88\\nChicken\\tChicken, meatless, breaded, fried\\t41810610\\t21.28\\nSardines\\tSardines, skinless, boneless, packed in water\\t26139190\\t20.86\\nRaisins\\tRaisins, chocolate covered\\t91739010\\t4.1\\nCheese\\tCheese, Swiss, nonfat or fat free\\t14109040\\t28.4\"}","extra_starting_files":"","forked_id":null,"forked_version":null,"hidden":false,"id":2539,"instructions":"# Protein Lookup\n\n## A Longer Example\n\n-   Protein Lookup: Check your food!\n\nIn this example program, we created a simple application that allows users to look up the protein content of various foods. The program reads in a big file containing nutritional information about many different foods, and then allows the user to search for specific foods and see how much protein they contain. The user can \"remember\" food in a list, and then see the total protein content of all the foods they have remembered.\n\nThe `State` in this application is much simpler than in the Ghost Hunt example. It only contains a list of remembered foods. However, there is a lot more data being processed in this example, since we are reading from a large TSV file and searching through it.\n\nBecause there is so much data, we actually only load a small portion of it in here in the browser. The full dataset contains records on over 7000 foods. The version here in the browser only contains about 200 foods, but it is still enough to demonstrate how the program works. We strongly recommend you download the full dataset and run the program locally to see how it works with the complete data.\n\n## The Code\n\n```python food-lookup\nfrom dataclasses import dataclass\nfrom drafter import *\n\n# The path to the food data file.\nFOOD_DATA_FILE = \"food_simple.tsv\"\n\n\n@dataclass\nclass State:\n    \"\"\"\n    Represents the state of the food lookup application.\n\n    Attributes:\n        food_items (list[int]): A list of food item IDs that the user has selected.\n    \"\"\"\n\n    food_items: list[int]\n\n\n@dataclass\nclass Food:\n    \"\"\"\n    Represents a food item with its details.\n\n    Attributes:\n        category (str): The category of the food item.\n        name (str): The name of the food item.\n        id (int): The unique identifier of the food item.\n        protein (float): The protein content of the food item in grams.\n    \"\"\"\n\n    category: str\n    name: str\n    id: int\n    protein: float\n\n\ndef parse_food(line: str) -> Food:\n    \"\"\"\n    Parses a line from the food_simple.tsv file and returns a Food object.\n\n    Args:\n        line (str): A line from the food_simple.tsv file.\n    Returns:\n        Food: A Food object with the parsed details.\n    \"\"\"\n    pieces = line.strip().split(\"\\t\")\n    category = pieces[0]\n    name = pieces[1]\n    food_id = int(pieces[2])\n    protein = float(pieces[3])\n    return Food(category, name, food_id, protein)\n\n\ndef load_foods() -> list[Food]:\n    \"\"\"\n    Loads food items from the food_simple.tsv file.\n\n    Returns:\n        list[Food]: A list of Food objects loaded from the file.\n    \"\"\"\n    food_items = []\n    with open(FOOD_DATA_FILE) as file:\n        for line in file:\n            food_items.append(parse_food(line))\n    return food_items\n\n\n# Load the food items once at the start of the program.\nFOODS = load_foods()\n\n\ndef find_foods(foods: list[Food], query: str) -> list[Food]:\n    \"\"\"\n    Finds food items that match the given query. Ignores capitalization.\n    As long as the query is a substring of the food name, it is considered a match.\n\n    Args:\n        foods (list[Food]): A list of Food objects to search.\n        query (str): The search query string.\n    Returns:\n        list[Food]: A list of Food objects that match the query.\n    \"\"\"\n    results = []\n    query_lower = query.lower()\n    for food in foods:\n        if query_lower in food.name.lower():\n            results.append(food)\n    return results\n\n\ndef get_food(foods: list[Food], food_ids: list[int]) -> list[Food]:\n    \"\"\"\n    Retrieves food items that match the given list of food IDs.\n\n    Args:\n        foods (list[Food]): A list of Food objects to search.\n        food_ids (list[int]): A list of food IDs to look for.\n    Returns:\n        list[Food]: A list of Food objects that match the given food IDs.\n    \"\"\"\n    selected_foods = []\n    for food in foods:\n        if food.id in food_ids:\n            selected_foods.append(food)\n    return selected_foods\n\n\n@route\ndef index(state: State):\n    \"\"\"\n    The main page of the food lookup application, where users can search for foods\n    and see their protein content. Also lists the foods the user has selected, and\n    shows the total protein content of those foods.\n\n    Args:\n        state (State): The current state of the application.\n    Returns:\n        Page: The main page of the application.\n    \"\"\"\n    selected_foods = get_food(FOODS, state.food_items)\n    total_protein_value = total_protein(selected_foods)\n    return Page(\n        state,\n        [\n            Header(\"Food Lookup\"),\n            \"Find foods by name and see their protein content.\",\n            TextBox(\"query\"),\n            Button(\"Search\", \"search\"),\n            Table(selected_foods),\n            \"Total protein:\",\n            str(total_protein_value),\n        ],\n    )\n\n\ndef total_protein(foods: list[Food]) -> float:\n    \"\"\"\n    Calculates the total protein content of a list of food items.\n\n    Args:\n        foods (list[Food]): A list of Food objects.\n    Returns:\n        float: The total protein content of the food items.\n    \"\"\"\n    total = 0.0\n    for food in foods:\n        total += food.protein\n    return total\n\n\ndef no_food_found_page(state: State) -> Page:\n    \"\"\"\n    Displays a page indicating that no food items were found for the given search query.\n\n    Args:\n        state (State): The current state of the application.\n    Returns:\n        Page: A page indicating that no food items were found.\n    \"\"\"\n    return Page(\n        state,\n        [\n            Header(\"No results found\"),\n            \"Try a different search term.\",\n            Button(\"Back\", \"index\"),\n        ],\n    )\n\n\ndef make_food_button(food: Food) -> PageContent:\n    \"\"\"\n    Creates a button for a food item that can be added to the user's selected foods.\n    Also shows the category and protein content of the food item.\n\n    Args:\n        food (Food): The food item to create a button for.\n    Returns:\n        Button: A button that, when clicked, will add the food item to the user's selected foods.\n    \"\"\"\n    return Row(\n        Button(food.name, \"add_food\", arguments=[Argument(\"food_id\", food.id)]),\n        food.category + \" - \" + str(food.protein) + \"g protein\",\n    )\n\n\n@route\ndef search(state: State, query: str):\n    \"\"\"\n    Searches for food items that match the given query and displays the results.\n    If no results are found, an error message is displayed.\n\n    Args:\n        state (State): The current state of the application.\n        query (str): The search query string.\n    Returns:\n        Page: A page displaying the search results or an error message.\n    \"\"\"\n    results = find_foods(FOODS, query)\n    if not results:\n        return no_food_found_page(state)\n    buttons = []\n    for food in results:\n        buttons.append(make_food_button(food))\n    return Page(\n        state,\n        [\n            Header(f\"Search results for '{query}'\"),\n            BulletedList(buttons),\n            Button(\"Back\", \"index\"),\n        ],\n    )\n\n\n@route\ndef add_food(state: State, food_id: int):\n    \"\"\"\n    Adds a food item to the user's selected foods.\n\n    Args:\n        state (State): The current state of the application.\n        food_id (int): The ID of the food item to add.\n    Returns:\n        Page: The main page of the application with the updated selected foods.\n    \"\"\"\n    if food_id not in state.food_items:\n        state.food_items.append(food_id)\n\n    return index(state)\n\n\nstart_server(State([]))\n```\n\n## Running Locally\n\n-   [food_lookup.py](https://gist.githubusercontent.com/acbart/8bfb48903b6e5a5073a32d602afdff4a/raw/be48bf598b7a6312a5b261e4578ed11a4e035565/food_lookup.py)\n-   [food_simple.tsv](https://gist.githubusercontent.com/acbart/8bfb48903b6e5a5073a32d602afdff4a/raw/be48bf598b7a6312a5b261e4578ed11a4e035565/food_simple.tsv)\n\nIn order to run the program locally, you need to make sure that you download both the Python program file (`food_lookup.py`) and the data file (`food_simple.tsv`). These files need to be in the same directory so that the program can find the data file when it runs. Otherwise, you may get an error saying that the file cannot be found.\n\nIf you open up the file and it doesn't download correctly, you can copy the contents of the file and paste it into a blank file in Thonny. Be careful that the contents of the file are exactly the same as what is shown below.\n\n## The Data File\n\n```tsv\nMuffin|Muffin, English, rye|51401200|8.5\nBread|Bread, pumpernickel|51404010|8.7\nBread|Bread, pumpernickel, toasted|51404020|9.56\nBagel|Bagel, pumpernickel|51404500|10.2\nMuffin|Muffin, English, pumpernickel|51404550|8.7\nBread|Bread, black|51407010|8.7\nBread|Bread, black, toasted|51407020|9.56\nRoll|Roll, rye|51420000|8.5\nRoll|Roll, pumpernickel|51421000|10.8\n```\n\nAt the heart of this application is a large TSV (tab-separated values) file that contains nutritional information about various foods. Each line in the file represents a different food item. The first column is a category (like \"Bread\" or \"Muffin\"), the second column is the specific name of the food, the third column is a unique identifier, and the fourth column is the amount of protein in grams per serving.\n\nThis file was sourced from The CORGIS Dataset Project, which provides a variety of datasets for educational purposes. You can find more information about this dataset and others at [https://corgis-edu.github.io/corgis/datasets/](https://corgis-edu.github.io/corgis/datasets/).\n\nIn particular, this CORGIS dataset was based off data collected by the United States Department of Agriculture's Food Composition Database. The complete dataset contains data for various types of food including the amounts of different vitamins and minerals found in the foods as well as macronutrient percentages. The food covered spans a large variety of foods from \"butter to Campbell's soup\".","ip_ranges":"","name":"9A2) Protein Lookup 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":"{\"summary\": \"This is another example of a longer Drafter program.\", \"small_layout\": true, \"disable_timeout\": true, \"hide_files\": false}","starting_code":"","subordinate":true,"tags":[],"type":"reading","url":"bakery_project2_example2_read","version":3},"ip":"216.73.216.157","submission":{"_schema_version":3,"assignment_id":2539,"assignment_version":3,"attempts":0,"code":"","correct":false,"course_id":37,"date_created":"2026-05-20T12:38:50.790764+00:00","date_due":"","date_graded":"","date_locked":"","date_modified":"2026-05-20T12:38:50.790764+00:00","date_started":"","date_submitted":"","endpoint":"","extra_files":"","feedback":"","grading_status":"NotReady","id":2036723,"score":0.0,"submission_status":"Started","time_limit":"","url":"submission_url-85c7b043-60af-4dd8-9698-a82bf5cd8917","user_id":2044658,"user_id__email":"","version":0},"success":true}
