From 4e88cb6b7cc708489a0554e9fd6a5f11756d35cc Mon Sep 17 00:00:00 2001 From: Alex Hall Date: Sun, 30 Mar 2025 16:25:09 +0200 Subject: [PATCH 01/16] CreatingKeyValuePairs draft --- core/chapters/c12_dictionaries.py | 393 +++++- tests/golden_files/en/test_transcript.json | 209 +++ translations/english.po | 1216 ++++++++++++++++- .../locales/en/LC_MESSAGES/futurecoder.mo | Bin 297007 -> 308487 bytes 4 files changed, 1802 insertions(+), 16 deletions(-) diff --git a/core/chapters/c12_dictionaries.py b/core/chapters/c12_dictionaries.py index 6b70b08c..7cba16e2 100644 --- a/core/chapters/c12_dictionaries.py +++ b/core/chapters/c12_dictionaries.py @@ -2,17 +2,14 @@ import ast import random from collections import Counter -from typing import List, Dict +from copy import deepcopy +from typing import Dict, List from core import translation as t from core.exercises import assert_equal from core.exercises import generate_string, generate_dict -from core.text import ( - ExerciseStep, - Page, - Step, - VerbatimStep, -) +from core.text import Page, VerbatimStep, ExerciseStep, Step +from core.utils import returns_stdout, wrap_solution # Similar to word_must_be_hello @@ -668,3 +665,385 @@ def print_words(words): final_text = """ Congratulations! You've reached the end of the course so far. More is on the way! """ + # TODO + + +class CreatingKeyValuePairs(Page): + title = "Creating Key-Value Pairs" + + class list_append_reminder(VerbatimStep): + """ + Now we'll learn how to add key-value pairs to a dictionary, + e.g. so that we can keep track of what the customer is buying. + Before looking at dictionaries, let's remind ourselves how to add items to a list. Run this program: + + __copyable__ + __program_indented__ + """ + + def program(self): + cart = [] + cart.append('dog') + cart.append('box') + print(cart) + + class list_assign_reminder(VerbatimStep): + """ + Pretty simple. We can also change the value at an index, replacing it with a different one: + + __copyable__ + __program_indented__ + """ + predicted_output_choices = [ + "['dog', 'box']", + "['box', 'cat']", + "['dog', 'cat']", + ] + + def program(self): + cart = ['dog', 'cat'] + cart[1] = 'box' + print(cart) + + class list_assign_invalid(VerbatimStep): + """ + What if we used that idea to create our list in the first place? + We know we want a list where `cart[0]` is `'dog'` and `cart[1]` is `'box'`, so let's just say that: + + __copyable__ + __program_indented__ + """ + correct_output = "Error" # This program raises an IndexError + + def program(self): + cart = [] + cart[0] = 'dog' + cart[1] = 'box' + print(cart) + + class dict_assignment_valid(VerbatimStep): + """ + Sorry, that's not allowed. For lists, subscript assignment only works for existing valid indices. + But that's not true for dictionaries! Try this: + + __copyable__ + __program_indented__ + + Note that `{}` means an empty dictionary, i.e. a dictionary with no key-value pairs. + This is similar to `[]` meaning an empty list or `""` meaning an empty string. + """ + predicted_output_choices = [ + "{}", + "{'dog': 5000000}", + "{'box': 2}", + "{'dog': 5000000, 'box': 2}", + "{'box': 2, 'dog': 5000000}", # Order might vary, though CPython 3.7+ preserves insertion order + ] + + def program(self): + quantities = {} + quantities['dog'] = 5000000 + quantities['box'] = 2 + print(quantities) + + class buy_quantity_exercise(ExerciseStep): + """ + That's exactly what we need. When the customer says they want 5 million boxes, + we can just put that information directly into our dictionary. So as an exercise, let's make a generic version of that. + Write a function `buy_quantity(quantities)` which calls `input()` twice to get an item name and quantity from the user + and assigns them in the `quantities` dictionary. Here's some starting code: + + __copyable__ + def buy_quantity(quantities): + print('Item:') + item = input() + print('Quantity:') + ... + + def test(): + quantities = {} + buy_quantity(quantities) + print(quantities) + buy_quantity(quantities) + print(quantities) + + test() + + and an example of how a session should look: + + Item: + dog + Quantity: + 5000000 + {'dog': 5000000} + Item: + box + Quantity: + 2 + {'dog': 5000000, 'box': 2} + + Note that `buy_quantity` should *modify* the dictionary that's passed in, and doesn't need to return anything. + You can assume that the user will enter a valid integer for the quantity. + """ + requirements = "Your function should modify the `quantities` argument. It doesn't need to `return` or `print` anything." + no_returns_stdout = True # The function itself doesn't print/return, the test harness does + + hints = """ + The function needs to get two inputs from the user: the item name and the quantity. + The item name is already stored in the `item` variable. You need to get the quantity similarly. + Remember that `input()` returns a string. The quantity needs to be stored as a number (`int`). + How do you convert a string to an integer? + Once you have the `item` (string) and the quantity (integer), you need to add them to the `quantities` dictionary. + Use the dictionary assignment syntax you just learned: `dictionary[key] = value`. + What should be the key and what should be the value in this case? + """ + + def solution(self): + def buy_quantity(quantities: Dict[str, int]): + print('Item:') + item = input() + print('Quantity:') + quantity_str = input() + quantities[item] = int(quantity_str) + return buy_quantity + + @classmethod + def wrap_solution(cls, func): + @returns_stdout + @wrap_solution(func) + def wrapper(**kwargs): + quantities_name = t.get_code_bit("quantities") + quantities = kwargs[quantities_name] = deepcopy(kwargs[quantities_name]) + + func(**kwargs) + print(quantities) + return wrapper + + @classmethod + def generate_inputs(cls): + return { + "stdin_input": [generate_string(5), str(random.randint(1, 10))], + "quantities": generate_dict(str, int), + } + + tests = [ + ( + dict( + quantities={}, + stdin_input=[ + "dog", "5000000", + ] + ), + """\ +Item: + +Quantity: + +{'dog': 5000000} + """ + ), + ( + dict( + quantities={'dog': 5000000}, + stdin_input=[ + "box", "2", + ] + ), + """\ +Item: + +Quantity: + +{'dog': 5000000, 'box': 2} + """ + ), + ] + + class total_cost_per_item_exercise(ExerciseStep): + """ + Well done! + + Next exercise: earlier we defined a function `total_cost(quantities, prices)` which returned a single number + with a grand total of all the items in the cart. Now let's make a function `total_cost_per_item(quantities, prices)` + which returns a new dictionary with the total cost for each item: + + __copyable__ + def total_cost_per_item(quantities, prices): + totals = {} + for item in quantities: + ... = quantities[item] * prices[item] + return totals + + assert_equal( + total_cost_per_item({'apple': 2}, {'apple': 3, 'box': 5}), + {'apple': 6}, + ) + + assert_equal( + total_cost_per_item({'dog': 5000000, 'box': 2}, {'dog': 100, 'box': 5}), + {'dog': 500000000, 'box': 10}, + ) + """ + hints = """ + You need to iterate through the items in the `quantities` dictionary. + For each `item`, calculate the total cost for that item (quantity * price). + Store this calculated cost in the `totals` dictionary. + The key for the `totals` dictionary should be the `item` name. + Use the dictionary assignment syntax: `totals[item] = calculated_cost`. + Make sure this assignment happens *inside* the loop. + The function should return the `totals` dictionary after the loop finishes. + """ + + def solution(self): + def total_cost_per_item(quantities: Dict[str, int], prices: Dict[str, int]): + totals = {} + for item in quantities: + totals[item] = quantities[item] * prices[item] + return totals + return total_cost_per_item + + tests = [ + (({'apple': 2}, {'apple': 3, 'box': 5}), {'apple': 6}), + (({'dog': 5000000, 'box': 2}, {'dog': 100, 'box': 5}), {'dog': 500000000, 'box': 10}), + (({'pen': 5, 'pencil': 10}, {'pen': 1, 'pencil': 0.5, 'eraser': 2}), {'pen': 5, 'pencil': 5.0}), + (({}, {'apple': 1}), {}), + ] + + @classmethod + def generate_inputs(cls): + prices = generate_dict(str, int) + quantities = {k: random.randint(1, 10) for k in prices if random.choice([True, False])} + return {"quantities": quantities, "prices": prices} + + class make_english_to_german_exercise(ExerciseStep): + """ + Perfect! This is like having a nice receipt full of useful information. + + Let's come back to the example of using dictionaries for translation. Suppose we have one dictionary + for translating from English to French, and another for translating from French to German. + Let's use that to create a dictionary that translates from English to German: + + __copyable__ + def make_english_to_german(english_to_french, french_to_german): + ... + + assert_equal( + make_english_to_german( + {'apple': 'pomme', 'box': 'boite'}, + {'pomme': 'apfel', 'boite': 'kasten'}, + ), + {'apple': 'apfel', 'box': 'kasten'}, + ) + """ + parsons_solution = True + + hints = """ + You need to create a new empty dictionary, let's call it `english_to_german`. + Iterate through the keys (English words) of the `english_to_french` dictionary. + Inside the loop, for each `english` word: + 1. Find the corresponding French word using `english_to_french`. + 2. Use that French word as a key to find the German word in `french_to_german`. + 3. Add the `english` word as a key and the `german` word as the value to your new `english_to_german` dictionary. + After the loop, return the `english_to_german` dictionary. + """ + + def solution(self): + def make_english_to_german(english_to_french: Dict[str, str], french_to_german: Dict[str, str]): + english_to_german = {} + for english in english_to_french: + french = english_to_french[english] + german = french_to_german[french] + english_to_german[english] = german + return english_to_german + return make_english_to_german + + tests = [ + (({'apple': 'pomme', 'box': 'boite'}, {'pomme': 'apfel', 'boite': 'kasten'}), + {'apple': 'apfel', 'box': 'kasten'}), + (({'one': 'un', 'two': 'deux', 'three': 'trois'}, {'un': 'eins', 'deux': 'zwei', 'trois': 'drei'}), + {'one': 'eins', 'two': 'zwei', 'three': 'drei'}), + (({}, {}), {}), + ] + + @classmethod + def generate_inputs(cls): + english_to_french = generate_dict(str, str) + french_to_german = {v: generate_string() for v in english_to_french.values()} + return {"english_to_french": english_to_french, "french_to_german": french_to_german} + + class swap_keys_values_exercise(ExerciseStep): + """ + Great job! + + Of course, language isn't so simple, and there are many ways that using a dictionary like this could go wrong. + So...let's do something even worse! Write a function which takes a dictionary and swaps the keys and values, + so `a: b` becomes `b: a`. + + __copyable__ + def swap_keys_values(d): + ... + + assert_equal( + swap_keys_values({'apple': 'pomme', 'box': 'boite'}), + {'pomme': 'apple', 'boite': 'box'}, + ) + """ + hints = """ + Create a new empty dictionary to store the result. + Iterate through the keys of the input dictionary `d`. + Inside the loop, for each `key`: + 1. Get the corresponding `value` from `d`. + 2. Add an entry to the new dictionary where the *key* is the original `value` and the *value* is the original `key`. + Return the new dictionary after the loop. + """ + + def solution(self): + def swap_keys_values(d: Dict[str, str]): + new_dict = {} + for key in d: + value = d[key] + new_dict[value] = key + return new_dict + return swap_keys_values + + tests = [ + (({'apple': 'pomme', 'box': 'boite'},), {'pomme': 'apple', 'boite': 'box'}), + (({'a': 1, 'b': 2},), {1: 'a', 2: 'b'}), + (({10: 'x', 20: 'y'},), {'x': 10, 'y': 20}), + (({},), {}), + ] + + final_text = """ +Magnificent! + +Jokes aside, it's important to remember how exactly this can go wrong. Just like multiple items in the store +can have the same price, multiple words in English can have the same translation in French. If the original dictionary +has duplicate *values*, what happens when you try to swap keys and values? Since dictionary keys must be unique, +some data will be lost. + +But there are many situations where you can be sure that the values in a dictionary *are* unique and that this +'inversion' makes sense. For example, we saw this code [earlier in the chapter](#UsingDictionariesInPractice): + + __copyable__ + __no_auto_translate__ + def substitute(string, d): + result = "" + for letter in string: + result += d[letter] + return result + + plaintext = 'helloworld' + encrypted = 'qpeefifmez' + letters = {'h': 'q', 'e': 'p', 'l': 'e', 'o': 'f', 'w': 'i', 'r': 'm', 'd': 'z'} + reverse = {'q': 'h', 'p': 'e', 'e': 'l', 'f': 'o', 'i': 'w', 'm': 'r', 'z': 'd'} + assert_equal(substitute(plaintext, letters), encrypted) + assert_equal(substitute(encrypted, reverse), plaintext) + +Now we can construct the `reverse` dictionary automatically: + + reverse = swap_keys_values(letters) + +For this to work, we just have to make sure that all the values in `letters` are unique. +Otherwise it would be impossible to decrypt messages properly. If both `'h'` and `'j'` got replaced with `'q'` +during encryption, there would be no way to know whether `'qpeef'` means `'hello'` or `'jello'`! +""" diff --git a/tests/golden_files/en/test_transcript.json b/tests/golden_files/en/test_transcript.json index 4ba82422..47ed4659 100644 --- a/tests/golden_files/en/test_transcript.json +++ b/tests/golden_files/en/test_transcript.json @@ -7228,5 +7228,214 @@ ] }, "step": "nested_dictionaries" + }, + { + "get_solution": "program", + "page": "Creating Key-Value Pairs", + "program": [ + "cart = []", + "cart.append('dog')", + "cart.append('box')", + "print(cart)" + ], + "response": { + "passed": true, + "result": [ + { + "text": "['dog', 'box']\n", + "type": "stdout" + } + ] + }, + "step": "list_append_reminder" + }, + { + "get_solution": "program", + "page": "Creating Key-Value Pairs", + "program": [ + "cart = ['dog', 'cat']", + "cart[1] = 'box'", + "print(cart)" + ], + "response": { + "passed": true, + "prediction": { + "answer": "['dog', 'box']", + "choices": [ + "['dog', 'box']", + "['box', 'cat']", + "['dog', 'cat']", + "Error" + ] + }, + "result": [ + { + "text": "['dog', 'box']\n", + "type": "stdout" + } + ] + }, + "step": "list_assign_reminder" + }, + { + "get_solution": "program", + "page": "Creating Key-Value Pairs", + "program": [ + "cart = []", + "cart[0] = 'dog'", + "cart[1] = 'box'", + "print(cart)" + ], + "response": { + "passed": true, + "result": [ + { + "data": [ + { + "didyoumean": [], + "exception": { + "message": "list assignment index out of range", + "type": "IndexError" + }, + "frames": [ + { + "filename": "/my_program.py", + "lineno": 2, + "lines": [ + { + "is_current": true, + "lineno": 2, + "text": "cart[0] = 'dog'", + "type": "line" + } + ], + "name": "", + "type": "frame", + "variables": [ + { + "name": "cart\n", + "value": "[]\n" + } + ] + } + ], + "friendly": "

An IndexError occurs when you try to get an item from a list,\na tuple, or a similar object (sequence), and use an index which\ndoes not exist; typically, this happens because the index you give\nis greater than the length of the sequence.

\n

You have tried to assign a value to index 0 of cart,\na list which contains no item.

", + "tail": "" + } + ], + "text": [ + "Traceback (most recent call last):", + " File \"/my_program.py\", line 2, in ", + " 1 | cart = []", + "--> 2 | cart[0] = 'dog'", + " ^^^^^^^", + "cart = []", + "", + "IndexError: list assignment index out of range" + ], + "type": "traceback" + } + ] + }, + "step": "list_assign_invalid" + }, + { + "get_solution": "program", + "page": "Creating Key-Value Pairs", + "program": [ + "quantities = {}", + "quantities['dog'] = 5000000", + "quantities['box'] = 2", + "print(quantities)" + ], + "response": { + "passed": true, + "prediction": { + "answer": "{'dog': 5000000, 'box': 2}", + "choices": [ + "{}", + "{'dog': 5000000}", + "{'box': 2}", + "{'dog': 5000000, 'box': 2}", + "{'box': 2, 'dog': 5000000}", + "Error" + ] + }, + "result": [ + { + "text": "{'dog': 5000000, 'box': 2}\n", + "type": "stdout" + } + ] + }, + "step": "dict_assignment_valid" + }, + { + "get_solution": "program", + "page": "Creating Key-Value Pairs", + "program": [ + "def buy_quantity(quantities):", + " print('Item:')", + " item = input()", + " print('Quantity:')", + " quantity_str = input()", + " quantities[item] = int(quantity_str)" + ], + "response": { + "passed": true, + "result": [] + }, + "step": "buy_quantity_exercise" + }, + { + "get_solution": "program", + "page": "Creating Key-Value Pairs", + "program": [ + "def total_cost_per_item(quantities, prices):", + " totals = {}", + " for item in quantities:", + " totals[item] = quantities[item] * prices[item]", + " return totals" + ], + "response": { + "passed": true, + "result": [] + }, + "step": "total_cost_per_item_exercise" + }, + { + "get_solution": "program", + "page": "Creating Key-Value Pairs", + "program": [ + "def make_english_to_german(english_to_french, french_to_german):", + " english_to_german = {}", + " for english in english_to_french:", + " french = english_to_french[english]", + " german = french_to_german[french]", + " english_to_german[english] = german", + " return english_to_german" + ], + "response": { + "passed": true, + "result": [] + }, + "step": "make_english_to_german_exercise" + }, + { + "get_solution": "program", + "page": "Creating Key-Value Pairs", + "program": [ + "def swap_keys_values(d):", + " new_dict = {}", + " for key in d:", + " value = d[key]", + " new_dict[value] = key", + " return new_dict" + ], + "response": { + "passed": true, + "result": [] + }, + "step": "swap_keys_values_exercise" } ] \ No newline at end of file diff --git a/translations/english.po b/translations/english.po index ea379858..ca2e6007 100644 --- a/translations/english.po +++ b/translations/english.po @@ -2512,6 +2512,36 @@ msgstr "'Hello there'" msgid "code_bits.'Hello'" msgstr "'Hello'" +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise +#. +#. def buy_quantity(quantities): +#. print('Item:') +#. item = input() +#. print('Quantity:') +#. quantity_str = input() +#. quantities[item] = int(quantity_str) +#. +#. ------ +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise.text +#. +#. def buy_quantity(quantities): +#. print('Item:') +#. item = input() +#. print('Quantity:') +#. ... +#. +#. def test(): +#. quantities = {} +#. buy_quantity(quantities) +#. print(quantities) +#. buy_quantity(quantities) +#. print(quantities) +#. +#. test() +msgid "code_bits.'Item:'" +msgstr "'Item:'" + #. https://poeditor.com/projects/view_terms?id=490053&search=pages.IfAndElse.steps.first_if_else #. #. condition = True @@ -2572,6 +2602,36 @@ msgstr "'One more exercise, and then you can relax.'" msgid "code_bits.'Python'" msgstr "'Python'" +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise +#. +#. def buy_quantity(quantities): +#. print('Item:') +#. item = input() +#. print('Quantity:') +#. quantity_str = input() +#. quantities[item] = int(quantity_str) +#. +#. ------ +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise.text +#. +#. def buy_quantity(quantities): +#. print('Item:') +#. item = input() +#. print('Quantity:') +#. ... +#. +#. def test(): +#. quantities = {} +#. buy_quantity(quantities) +#. print(quantities) +#. buy_quantity(quantities) +#. print(quantities) +#. +#. test() +msgid "code_bits.'Quantity:'" +msgstr "'Quantity:'" + #. https://poeditor.com/projects/view_terms?id=490053&search=pages.Types.steps.fixing_type_errors_with_conversion #. #. number = '1' @@ -3185,6 +3245,21 @@ msgstr "'abcqwe'" msgid "code_bits.'aeiou'" msgstr "'aeiou'" +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise.text +#. +#. def make_english_to_german(english_to_french, french_to_german): +#. ... +#. +#. assert_equal( +#. make_english_to_german( +#. {'apple': 'pomme', 'box': 'boite'}, +#. {'pomme': 'apfel', 'boite': 'kasten'}, +#. ), +#. {'apple': 'apfel', 'box': 'kasten'}, +#. ) +#. +#. ------ +#. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.DictionaryKeysAndValues.steps.english_to_german.text #. #. def print_words(french, german): @@ -3221,6 +3296,33 @@ msgstr "'aeiou'" msgid "code_bits.'apfel'" msgstr "'apfel'" +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise.text +#. +#. def make_english_to_german(english_to_french, french_to_german): +#. ... +#. +#. assert_equal( +#. make_english_to_german( +#. {'apple': 'pomme', 'box': 'boite'}, +#. {'pomme': 'apfel', 'boite': 'kasten'}, +#. ), +#. {'apple': 'apfel', 'box': 'kasten'}, +#. ) +#. +#. ------ +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.swap_keys_values_exercise.text +#. +#. def swap_keys_values(d): +#. ... +#. +#. assert_equal( +#. swap_keys_values({'apple': 'pomme', 'box': 'boite'}), +#. {'pomme': 'apple', 'boite': 'box'}, +#. ) +#. +#. ------ +#. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.DictionaryKeysAndValues.steps.cleanup_shopping_cart.text #. #. def total_cost(quantities, prices): @@ -3408,6 +3510,33 @@ msgstr "'are'" msgid "code_bits.'bc'" msgstr "'bc'" +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise.text +#. +#. def make_english_to_german(english_to_french, french_to_german): +#. ... +#. +#. assert_equal( +#. make_english_to_german( +#. {'apple': 'pomme', 'box': 'boite'}, +#. {'pomme': 'apfel', 'boite': 'kasten'}, +#. ), +#. {'apple': 'apfel', 'box': 'kasten'}, +#. ) +#. +#. ------ +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.swap_keys_values_exercise.text +#. +#. def swap_keys_values(d): +#. ... +#. +#. assert_equal( +#. swap_keys_values({'apple': 'pomme', 'box': 'boite'}), +#. {'pomme': 'apple', 'boite': 'box'}, +#. ) +#. +#. ------ +#. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.DictionaryKeysAndValues.steps.english_to_french.text #. #. def print_words(french): @@ -3459,6 +3588,68 @@ msgstr "'bc'" msgid "code_bits.'boite'" msgstr "'boite'" +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.dict_assignment_valid +#. +#. quantities = {} +#. quantities['dog'] = 5000000 +#. quantities['box'] = 2 +#. print(quantities) +#. +#. ------ +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.list_append_reminder +#. +#. cart = [] +#. cart.append('dog') +#. cart.append('box') +#. print(cart) +#. +#. ------ +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.list_assign_invalid +#. +#. cart = [] +#. cart[0] = 'dog' +#. cart[1] = 'box' +#. print(cart) +#. +#. ------ +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.list_assign_reminder +#. +#. cart = ['dog', 'cat'] +#. cart[1] = 'box' +#. print(cart) +#. +#. ------ +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise.text +#. +#. def make_english_to_german(english_to_french, french_to_german): +#. ... +#. +#. assert_equal( +#. make_english_to_german( +#. {'apple': 'pomme', 'box': 'boite'}, +#. {'pomme': 'apfel', 'boite': 'kasten'}, +#. ), +#. {'apple': 'apfel', 'box': 'kasten'}, +#. ) +#. +#. ------ +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.swap_keys_values_exercise.text +#. +#. def swap_keys_values(d): +#. ... +#. +#. assert_equal( +#. swap_keys_values({'apple': 'pomme', 'box': 'boite'}), +#. {'pomme': 'apple', 'boite': 'box'}, +#. ) +#. +#. ------ +#. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.DictionaryKeysAndValues.steps.cleanup_shopping_cart.text #. #. def total_cost(quantities, prices): @@ -3582,6 +3773,14 @@ msgstr "'boite'" msgid "code_bits.'box'" msgstr "'box'" +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.list_assign_reminder +#. +#. cart = ['dog', 'cat'] +#. cart[1] = 'box' +#. print(cart) +#. +#. ------ +#. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.DictionaryKeysAndValues.steps.cleanup_shopping_cart.text #. #. def total_cost(quantities, prices): @@ -3723,6 +3922,41 @@ msgstr "'de'" msgid "code_bits.'def'" msgstr "'def'" +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.dict_assignment_valid +#. +#. quantities = {} +#. quantities['dog'] = 5000000 +#. quantities['box'] = 2 +#. print(quantities) +#. +#. ------ +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.list_append_reminder +#. +#. cart = [] +#. cart.append('dog') +#. cart.append('box') +#. print(cart) +#. +#. ------ +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.list_assign_invalid +#. +#. cart = [] +#. cart[0] = 'dog' +#. cart[1] = 'box' +#. print(cart) +#. +#. ------ +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.list_assign_reminder +#. +#. cart = ['dog', 'cat'] +#. cart[1] = 'box' +#. print(cart) +#. +#. ------ +#. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.DictionaryKeysAndValues.steps.cleanup_shopping_cart.text #. #. def total_cost(quantities, prices): @@ -4102,6 +4336,21 @@ msgstr "'is'" msgid "code_bits.'jklmn'" msgstr "'jklmn'" +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise.text +#. +#. def make_english_to_german(english_to_french, french_to_german): +#. ... +#. +#. assert_equal( +#. make_english_to_german( +#. {'apple': 'pomme', 'box': 'boite'}, +#. {'pomme': 'apfel', 'boite': 'kasten'}, +#. ), +#. {'apple': 'apfel', 'box': 'kasten'}, +#. ) +#. +#. ------ +#. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.DictionaryKeysAndValues.steps.english_to_german.text #. #. def print_words(french, german): @@ -4220,6 +4469,33 @@ msgstr "'list'" msgid "code_bits.'on'" msgstr "'on'" +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise.text +#. +#. def make_english_to_german(english_to_french, french_to_german): +#. ... +#. +#. assert_equal( +#. make_english_to_german( +#. {'apple': 'pomme', 'box': 'boite'}, +#. {'pomme': 'apfel', 'boite': 'kasten'}, +#. ), +#. {'apple': 'apfel', 'box': 'kasten'}, +#. ) +#. +#. ------ +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.swap_keys_values_exercise.text +#. +#. def swap_keys_values(d): +#. ... +#. +#. assert_equal( +#. swap_keys_values({'apple': 'pomme', 'box': 'boite'}), +#. {'pomme': 'apple', 'boite': 'box'}, +#. ) +#. +#. ------ +#. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.DictionaryKeysAndValues.steps.english_to_french.text #. #. def print_words(french): @@ -4374,6 +4650,30 @@ msgstr "'you'" msgid "code_bits.Hello" msgstr "Hello" +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.dict_assignment_valid.text +#. +#. __program_indented__ +#. +#. ------ +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.list_append_reminder.text +#. +#. __program_indented__ +#. +#. ------ +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.list_assign_invalid.text +#. +#. __program_indented__ +#. +#. ------ +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.list_assign_reminder.text +#. +#. __program_indented__ +#. +#. ------ +#. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.DictionaryKeysAndValues.steps.keys_are_iterable.text #. #. __program_indented__ @@ -4857,6 +5157,33 @@ msgstr "all_numbers" #. #. ------ #. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise.text +#. +#. def make_english_to_german(english_to_french, french_to_german): +#. ... +#. +#. assert_equal( +#. make_english_to_german( +#. {'apple': 'pomme', 'box': 'boite'}, +#. {'pomme': 'apfel', 'boite': 'kasten'}, +#. ), +#. {'apple': 'apfel', 'box': 'kasten'}, +#. ) +#. +#. ------ +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.swap_keys_values_exercise.text +#. +#. def swap_keys_values(d): +#. ... +#. +#. assert_equal( +#. swap_keys_values({'apple': 'pomme', 'box': 'boite'}), +#. {'pomme': 'apple', 'boite': 'box'}, +#. ) +#. +#. ------ +#. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.DictionaryKeysAndValues.steps.cleanup_shopping_cart.text #. #. def total_cost(quantities, prices): @@ -6422,6 +6749,36 @@ msgstr "board" msgid "code_bits.board_size" msgstr "board_size" +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise +#. +#. def buy_quantity(quantities): +#. print('Item:') +#. item = input() +#. print('Quantity:') +#. quantity_str = input() +#. quantities[item] = int(quantity_str) +#. +#. ------ +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise.text +#. +#. def buy_quantity(quantities): +#. print('Item:') +#. item = input() +#. print('Quantity:') +#. ... +#. +#. def test(): +#. quantities = {} +#. buy_quantity(quantities) +#. print(quantities) +#. buy_quantity(quantities) +#. print(quantities) +#. +#. test() +msgid "code_bits.buy_quantity" +msgstr "buy_quantity" + #. https://poeditor.com/projects/view_terms?id=490053&search=pages.IntroducingNestedLoops.steps.crack_password_exercise #. #. letters = 'AB' @@ -6466,6 +6823,32 @@ msgstr "c3" msgid "code_bits.c4" msgstr "c4" +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.list_append_reminder +#. +#. cart = [] +#. cart.append('dog') +#. cart.append('box') +#. print(cart) +#. +#. ------ +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.list_assign_invalid +#. +#. cart = [] +#. cart[0] = 'dog' +#. cart[1] = 'box' +#. print(cart) +#. +#. ------ +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.list_assign_reminder +#. +#. cart = ['dog', 'cat'] +#. cart[1] = 'box' +#. print(cart) +#. +#. ------ +#. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.UsingDictionaries.steps.shopping_cart1 #. #. def total_cost(cart, prices): @@ -8612,6 +8995,57 @@ msgstr "doubles" msgid "code_bits.element" msgstr "element" +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise +#. +#. def make_english_to_german(english_to_french, french_to_german): +#. english_to_german = {} +#. for english in english_to_french: +#. french = english_to_french[english] +#. german = french_to_german[french] +#. english_to_german[english] = german +#. return english_to_german +msgid "code_bits.english" +msgstr "english" + +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise +#. +#. def make_english_to_german(english_to_french, french_to_german): +#. english_to_german = {} +#. for english in english_to_french: +#. french = english_to_french[english] +#. german = french_to_german[french] +#. english_to_german[english] = german +#. return english_to_german +#. +#. ------ +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise.text +#. +#. def make_english_to_german(english_to_french, french_to_german): +#. ... +#. +#. assert_equal( +#. make_english_to_german( +#. {'apple': 'pomme', 'box': 'boite'}, +#. {'pomme': 'apfel', 'boite': 'kasten'}, +#. ), +#. {'apple': 'apfel', 'box': 'kasten'}, +#. ) +msgid "code_bits.english_to_french" +msgstr "english_to_french" + +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise +#. +#. def make_english_to_german(english_to_french, french_to_german): +#. english_to_german = {} +#. for english in english_to_french: +#. french = english_to_french[english] +#. german = french_to_german[french] +#. english_to_german[english] = german +#. return english_to_german +msgid "code_bits.english_to_german" +msgstr "english_to_german" + #. https://poeditor.com/projects/view_terms?id=490053&search=pages.IntroducingTicTacToe.steps.intro_row_winner #. #. def row_winner(board): @@ -10302,6 +10736,18 @@ msgstr "format_board" msgid "code_bits.found" msgstr "found" +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise +#. +#. def make_english_to_german(english_to_french, french_to_german): +#. english_to_german = {} +#. for english in english_to_french: +#. french = english_to_french[english] +#. german = french_to_german[french] +#. english_to_german[english] = german +#. return english_to_german +#. +#. ------ +#. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.DictionaryKeysAndValues.steps.english_to_french #. #. def print_words(french): @@ -10374,6 +10820,33 @@ msgstr "found" msgid "code_bits.french" msgstr "french" +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise +#. +#. def make_english_to_german(english_to_french, french_to_german): +#. english_to_german = {} +#. for english in english_to_french: +#. french = english_to_french[english] +#. german = french_to_german[french] +#. english_to_german[english] = german +#. return english_to_german +#. +#. ------ +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise.text +#. +#. def make_english_to_german(english_to_french, french_to_german): +#. ... +#. +#. assert_equal( +#. make_english_to_german( +#. {'apple': 'pomme', 'box': 'boite'}, +#. {'pomme': 'apfel', 'boite': 'kasten'}, +#. ), +#. {'apple': 'apfel', 'box': 'kasten'}, +#. ) +msgid "code_bits.french_to_german" +msgstr "french_to_german" + #. https://poeditor.com/projects/view_terms?id=490053&search=pages.IntroducingFstrings.steps.introduce_f_strings #. #. name = "Alice" @@ -10412,6 +10885,18 @@ msgstr "friend" msgid "code_bits.game_board" msgstr "game_board" +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise +#. +#. def make_english_to_german(english_to_french, french_to_german): +#. english_to_german = {} +#. for english in english_to_french: +#. french = english_to_french[english] +#. german = french_to_german[french] +#. english_to_german[english] = german +#. return english_to_german +#. +#. ------ +#. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.DictionaryKeysAndValues.steps.english_to_german #. #. def print_words(french, german): @@ -10863,19 +11348,59 @@ msgstr "is_friend" msgid "code_bits.is_valid_percentage" msgstr "is_valid_percentage" -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.DictionaryKeysAndValues.steps.cleanup_shopping_cart +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise #. -#. def total_cost(quantities, prices): -#. result = 0 -#. for item in quantities: -#. price = prices[item] -#. quantity = quantities[item] -#. result += price * quantity -#. return result +#. def buy_quantity(quantities): +#. print('Item:') +#. item = input() +#. print('Quantity:') +#. quantity_str = input() +#. quantities[item] = int(quantity_str) #. #. ------ #. -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.DictionaryKeysAndValues.steps.cleanup_shopping_cart.text +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise.text +#. +#. def buy_quantity(quantities): +#. print('Item:') +#. item = input() +#. print('Quantity:') +#. ... +#. +#. def test(): +#. quantities = {} +#. buy_quantity(quantities) +#. print(quantities) +#. buy_quantity(quantities) +#. print(quantities) +#. +#. test() +#. +#. ------ +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.total_cost_per_item_exercise +#. +#. def total_cost_per_item(quantities, prices): +#. totals = {} +#. for item in quantities: +#. totals[item] = quantities[item] * prices[item] +#. return totals +#. +#. ------ +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.DictionaryKeysAndValues.steps.cleanup_shopping_cart +#. +#. def total_cost(quantities, prices): +#. result = 0 +#. for item in quantities: +#. price = prices[item] +#. quantity = quantities[item] +#. result += price * quantity +#. return result +#. +#. ------ +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.DictionaryKeysAndValues.steps.cleanup_shopping_cart.text #. #. def total_cost(quantities, prices): #. result = 0 @@ -11076,6 +11601,17 @@ msgstr "joined_row" msgid "code_bits.joined_rows" msgstr "joined_rows" +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.swap_keys_values_exercise +#. +#. def swap_keys_values(d): +#. new_dict = {} +#. for key in d: +#. value = d[key] +#. new_dict[value] = key +#. return new_dict +#. +#. ------ +#. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.DictionaryKeysAndValues.steps.keys_are_iterable #. #. quantities = {'apple': 1, 'cat': 10} @@ -11335,6 +11871,12 @@ msgstr "lengths" msgid "code_bits.letter" msgstr "letter" +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.final_text.text +#. +#. reverse = swap_keys_values(letters) +#. +#. ------ +#. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.IntroducingNestedLoops.steps.crack_password_exercise #. #. letters = 'AB' @@ -12113,6 +12655,33 @@ msgstr "make_board" msgid "code_bits.make_cube" msgstr "make_cube" +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise +#. +#. def make_english_to_german(english_to_french, french_to_german): +#. english_to_german = {} +#. for english in english_to_french: +#. french = english_to_french[english] +#. german = french_to_german[french] +#. english_to_german[english] = german +#. return english_to_german +#. +#. ------ +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise.text +#. +#. def make_english_to_german(english_to_french, french_to_german): +#. ... +#. +#. assert_equal( +#. make_english_to_german( +#. {'apple': 'pomme', 'box': 'boite'}, +#. {'pomme': 'apfel', 'boite': 'kasten'}, +#. ), +#. {'apple': 'apfel', 'box': 'kasten'}, +#. ) +msgid "code_bits.make_english_to_german" +msgstr "make_english_to_german" + #. https://poeditor.com/projects/view_terms?id=490053&search=pages.IntroducingFstrings.steps.introduce_f_strings #. #. name = "Alice" @@ -12680,6 +13249,17 @@ msgstr "middle" msgid "code_bits.name" msgstr "name" +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.swap_keys_values_exercise +#. +#. def swap_keys_values(d): +#. new_dict = {} +#. for key in d: +#. value = d[key] +#. new_dict[value] = key +#. return new_dict +msgid "code_bits.new_dict" +msgstr "new_dict" + #. https://poeditor.com/projects/view_terms?id=490053&search=pages.TheEqualityOperator.steps.if_equals_replacing_characters #. #. name = 'kesha' @@ -14640,6 +15220,16 @@ msgstr "present" msgid "code_bits.price" msgstr "price" +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.total_cost_per_item_exercise +#. +#. def total_cost_per_item(quantities, prices): +#. totals = {} +#. for item in quantities: +#. totals[item] = quantities[item] * prices[item] +#. return totals +#. +#. ------ +#. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.DictionaryKeysAndValues.steps.cleanup_shopping_cart #. #. def total_cost(quantities, prices): @@ -15268,6 +15858,55 @@ msgstr "printed" msgid "code_bits.quadruple" msgstr "quadruple" +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise +#. +#. def buy_quantity(quantities): +#. print('Item:') +#. item = input() +#. print('Quantity:') +#. quantity_str = input() +#. quantities[item] = int(quantity_str) +#. +#. ------ +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise.text +#. +#. def buy_quantity(quantities): +#. print('Item:') +#. item = input() +#. print('Quantity:') +#. ... +#. +#. def test(): +#. quantities = {} +#. buy_quantity(quantities) +#. print(quantities) +#. buy_quantity(quantities) +#. print(quantities) +#. +#. test() +#. +#. ------ +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.dict_assignment_valid +#. +#. quantities = {} +#. quantities['dog'] = 5000000 +#. quantities['box'] = 2 +#. print(quantities) +#. +#. ------ +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.total_cost_per_item_exercise +#. +#. def total_cost_per_item(quantities, prices): +#. totals = {} +#. for item in quantities: +#. totals[item] = quantities[item] * prices[item] +#. return totals +#. +#. ------ +#. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.DictionaryKeysAndValues.steps.cleanup_shopping_cart #. #. def total_cost(quantities, prices): @@ -15428,6 +16067,17 @@ msgstr "quantities" msgid "code_bits.quantity" msgstr "quantity" +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise +#. +#. def buy_quantity(quantities): +#. print('Item:') +#. item = input() +#. print('Quantity:') +#. quantity_str = input() +#. quantities[item] = int(quantity_str) +msgid "code_bits.quantity_str" +msgstr "quantity_str" + #. https://poeditor.com/projects/view_terms?id=490053&search=pages.DictionaryKeysAndValues.steps.cleanup_shopping_cart #. #. def total_cost(quantities, prices): @@ -15581,6 +16231,12 @@ msgstr "quantity" msgid "code_bits.result" msgstr "result" +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.final_text.text +#. +#. reverse = swap_keys_values(letters) +msgid "code_bits.reverse" +msgstr "reverse" + #. https://poeditor.com/projects/view_terms?id=490053&search=pages.IntroducingNestedLoops.steps.times_table_exercise #. #. for left in range(12): @@ -17961,6 +18617,35 @@ msgstr "super_secret_number" msgid "code_bits.surround" msgstr "surround" +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.final_text.text +#. +#. reverse = swap_keys_values(letters) +#. +#. ------ +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.swap_keys_values_exercise +#. +#. def swap_keys_values(d): +#. new_dict = {} +#. for key in d: +#. value = d[key] +#. new_dict[value] = key +#. return new_dict +#. +#. ------ +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.swap_keys_values_exercise.text +#. +#. def swap_keys_values(d): +#. ... +#. +#. assert_equal( +#. swap_keys_values({'apple': 'pomme', 'box': 'boite'}), +#. {'pomme': 'apple', 'boite': 'box'}, +#. ) +msgid "code_bits.swap_keys_values" +msgstr "swap_keys_values" + #. https://poeditor.com/projects/view_terms?id=490053&search=pages.BuildingUpStrings.steps.name_triangle.text #. #. temp = hello @@ -17975,6 +18660,25 @@ msgstr "surround" msgid "code_bits.temp" msgstr "temp" +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise.text +#. +#. def buy_quantity(quantities): +#. print('Item:') +#. item = input() +#. print('Quantity:') +#. ... +#. +#. def test(): +#. quantities = {} +#. buy_quantity(quantities) +#. print(quantities) +#. buy_quantity(quantities) +#. print(quantities) +#. +#. test() +#. +#. ------ +#. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.MakingTheBoard.steps.final_text.text #. #. def make_board(size): @@ -18434,6 +19138,26 @@ msgstr "total" msgid "code_bits.total_cost" msgstr "total_cost" +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.total_cost_per_item_exercise +#. +#. def total_cost_per_item(quantities, prices): +#. totals = {} +#. for item in quantities: +#. totals[item] = quantities[item] * prices[item] +#. return totals +msgid "code_bits.total_cost_per_item" +msgstr "total_cost_per_item" + +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.total_cost_per_item_exercise +#. +#. def total_cost_per_item(quantities, prices): +#. totals = {} +#. for item in quantities: +#. totals[item] = quantities[item] * prices[item] +#. return totals +msgid "code_bits.totals" +msgstr "totals" + #. https://poeditor.com/projects/view_terms?id=490053&search=pages.DictionaryKeysAndValues.steps.nested_dictionaries #. #. def print_words(words): @@ -18526,6 +19250,17 @@ msgstr "upper" msgid "code_bits.valid_image" msgstr "valid_image" +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.swap_keys_values_exercise +#. +#. def swap_keys_values(d): +#. new_dict = {} +#. for key in d: +#. value = d[key] +#. new_dict[value] = key +#. return new_dict +#. +#. ------ +#. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.FunctionsAndMethodsForLists.steps.index_predict_exercise.text #. #. some_list.index(value) @@ -21483,6 +22218,469 @@ msgstr "" msgid "pages.CombiningCompoundStatements.title" msgstr "Combining Compound Statements" +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise +msgid "pages.CreatingKeyValuePairs.steps.buy_quantity_exercise.hints.0.text" +msgstr "The function needs to get two inputs from the user: the item name and the quantity." + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise +msgid "pages.CreatingKeyValuePairs.steps.buy_quantity_exercise.hints.1.text" +msgstr "The item name is already stored in the `item` variable. You need to get the quantity similarly." + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise +msgid "pages.CreatingKeyValuePairs.steps.buy_quantity_exercise.hints.2.text" +msgstr "Remember that `input()` returns a string. The quantity needs to be stored as a number (`int`)." + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise +msgid "pages.CreatingKeyValuePairs.steps.buy_quantity_exercise.hints.3.text" +msgstr "How do you convert a string to an integer?" + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise +msgid "pages.CreatingKeyValuePairs.steps.buy_quantity_exercise.hints.4.text" +msgstr "" +"Once you have the `item` (string) and the quantity (integer), you need to add them to the `quantities` dictionary." + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise +msgid "pages.CreatingKeyValuePairs.steps.buy_quantity_exercise.hints.5.text" +msgstr "Use the dictionary assignment syntax you just learned: `dictionary[key] = value`." + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise +msgid "pages.CreatingKeyValuePairs.steps.buy_quantity_exercise.hints.6.text" +msgstr "What should be the key and what should be the value in this case?" + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +msgid "pages.CreatingKeyValuePairs.steps.buy_quantity_exercise.requirements" +msgstr "Your function should modify the `quantities` argument. It doesn't need to `return` or `print` anything." + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. # __code0__: +#. def buy_quantity(quantities): +#. print('Item:') +#. item = input() +#. print('Quantity:') +#. ... +#. +#. def test(): +#. quantities = {} +#. buy_quantity(quantities) +#. print(quantities) +#. buy_quantity(quantities) +#. print(quantities) +#. +#. test() +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.%27Item%3A%27 +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.%27Quantity%3A%27 +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.buy_quantity +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.item +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.quantities +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.test +msgid "pages.CreatingKeyValuePairs.steps.buy_quantity_exercise.text" +msgstr "" +"That's exactly what we need. When the customer says they want 5 million boxes,\n" +"we can just put that information directly into our dictionary. So as an exercise, let's make a generic version of that.\n" +"Write a function `buy_quantity(quantities)` which calls `input()` twice to get an item name and quantity from the user\n" +"and assigns them in the `quantities` dictionary. Here's some starting code:\n" +"\n" +" __copyable__\n" +"__code0__\n" +"\n" +"and an example of how a session should look:\n" +"\n" +" Item:\n" +" dog\n" +" Quantity:\n" +" 5000000\n" +" {'dog': 5000000}\n" +" Item:\n" +" box\n" +" Quantity:\n" +" 2\n" +" {'dog': 5000000, 'box': 2}\n" +"\n" +"Note that `buy_quantity` should *modify* the dictionary that's passed in, and doesn't need to return anything.\n" +"You can assume that the user will enter a valid integer for the quantity." + +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.dict_assignment_valid +msgid "pages.CreatingKeyValuePairs.steps.dict_assignment_valid.output_prediction_choices.1" +msgstr "{'dog': 5000000}" + +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.dict_assignment_valid +msgid "pages.CreatingKeyValuePairs.steps.dict_assignment_valid.output_prediction_choices.2" +msgstr "{'box': 2}" + +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.dict_assignment_valid +msgid "pages.CreatingKeyValuePairs.steps.dict_assignment_valid.output_prediction_choices.3" +msgstr "{'dog': 5000000, 'box': 2}" + +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.dict_assignment_valid +msgid "pages.CreatingKeyValuePairs.steps.dict_assignment_valid.output_prediction_choices.4" +msgstr "{'box': 2, 'dog': 5000000}" + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. # __code0__: +#. __program_indented__ +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.__program_indented__ +msgid "pages.CreatingKeyValuePairs.steps.dict_assignment_valid.text" +msgstr "" +"Sorry, that's not allowed. For lists, subscript assignment only works for existing valid indices.\n" +"But that's not true for dictionaries! Try this:\n" +"\n" +" __copyable__\n" +"__code0__\n" +"\n" +"Note that `{}` means an empty dictionary, i.e. a dictionary with no key-value pairs.\n" +"This is similar to `[]` meaning an empty list or `\"\"` meaning an empty string." + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. # __code0__: +#. reverse = swap_keys_values(letters) +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.letters +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.reverse +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.swap_keys_values +msgid "pages.CreatingKeyValuePairs.steps.final_text.text" +msgstr "" +"Magnificent!\n" +"\n" +"Jokes aside, it's important to remember how exactly this can go wrong. Just like multiple items in the store\n" +"can have the same price, multiple words in English can have the same translation in French. If the original dictionary\n" +"has duplicate *values*, what happens when you try to swap keys and values? Since dictionary keys must be unique,\n" +"some data will be lost.\n" +"\n" +"But there are many situations where you can be sure that the values in a dictionary *are* unique and that this\n" +"'inversion' makes sense. For example, we saw this code [earlier in the chapter](#UsingDictionariesInPractice):\n" +"\n" +" __copyable__\n" +" __no_auto_translate__\n" +" def substitute(string, d):\n" +" result = \"\"\n" +" for letter in string:\n" +" result += d[letter]\n" +" return result\n" +"\n" +" plaintext = 'helloworld'\n" +" encrypted = 'qpeefifmez'\n" +" letters = {'h': 'q', 'e': 'p', 'l': 'e', 'o': 'f', 'w': 'i', 'r': 'm', 'd': 'z'}\n" +" reverse = {'q': 'h', 'p': 'e', 'e': 'l', 'f': 'o', 'i': 'w', 'm': 'r', 'z': 'd'}\n" +" assert_equal(substitute(plaintext, letters), encrypted)\n" +" assert_equal(substitute(encrypted, reverse), plaintext)\n" +"\n" +"Now we can construct the `reverse` dictionary automatically:\n" +"\n" +"__code0__\n" +"\n" +"For this to work, we just have to make sure that all the values in `letters` are unique.\n" +"Otherwise it would be impossible to decrypt messages properly. If both `'h'` and `'j'` got replaced with `'q'`\n" +"during encryption, there would be no way to know whether `'qpeef'` means `'hello'` or `'jello'`!" + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. # __code0__: +#. __program_indented__ +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.__program_indented__ +msgid "pages.CreatingKeyValuePairs.steps.list_append_reminder.text" +msgstr "" +"Now we'll learn how to add key-value pairs to a dictionary,\n" +"e.g. so that we can keep track of what the customer is buying.\n" +"Before looking at dictionaries, let's remind ourselves how to add items to a list. Run this program:\n" +"\n" +" __copyable__\n" +"__code0__" + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. # __code0__: +#. __program_indented__ +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.__program_indented__ +msgid "pages.CreatingKeyValuePairs.steps.list_assign_invalid.text" +msgstr "" +"What if we used that idea to create our list in the first place?\n" +"We know we want a list where `cart[0]` is `'dog'` and `cart[1]` is `'box'`, so let's just say that:\n" +"\n" +" __copyable__\n" +"__code0__" + +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.list_assign_reminder +msgid "pages.CreatingKeyValuePairs.steps.list_assign_reminder.output_prediction_choices.0" +msgstr "['dog', 'box']" + +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.list_assign_reminder +msgid "pages.CreatingKeyValuePairs.steps.list_assign_reminder.output_prediction_choices.1" +msgstr "['box', 'cat']" + +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.list_assign_reminder +msgid "pages.CreatingKeyValuePairs.steps.list_assign_reminder.output_prediction_choices.2" +msgstr "['dog', 'cat']" + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. # __code0__: +#. __program_indented__ +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.__program_indented__ +msgid "pages.CreatingKeyValuePairs.steps.list_assign_reminder.text" +msgstr "" +"Pretty simple. We can also change the value at an index, replacing it with a different one:\n" +"\n" +" __copyable__\n" +"__code0__" + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise +msgid "pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise.hints.0.text" +msgstr "You need to create a new empty dictionary, let's call it `english_to_german`." + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise +msgid "pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise.hints.1.text" +msgstr "Iterate through the keys (English words) of the `english_to_french` dictionary." + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise +msgid "pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise.hints.2.text" +msgstr "Inside the loop, for each `english` word:" + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise +msgid "pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise.hints.3.text" +msgstr "1. Find the corresponding French word using `english_to_french`." + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise +msgid "pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise.hints.4.text" +msgstr "2. Use that French word as a key to find the German word in `french_to_german`." + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise +msgid "pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise.hints.5.text" +msgstr "" +"3. Add the `english` word as a key and the `german` word as the value to your new `english_to_german` dictionary." + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise +msgid "pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise.hints.6.text" +msgstr "After the loop, return the `english_to_german` dictionary." + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. # __code0__: +#. def make_english_to_german(english_to_french, french_to_german): +#. ... +#. +#. assert_equal( +#. make_english_to_german( +#. {'apple': 'pomme', 'box': 'boite'}, +#. {'pomme': 'apfel', 'boite': 'kasten'}, +#. ), +#. {'apple': 'apfel', 'box': 'kasten'}, +#. ) +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.%27apfel%27 +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.%27apple%27 +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.%27boite%27 +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.%27box%27 +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.%27kasten%27 +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.%27pomme%27 +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.assert_equal +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.english_to_french +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.french_to_german +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.make_english_to_german +msgid "pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise.text" +msgstr "" +"Perfect! This is like having a nice receipt full of useful information.\n" +"\n" +"Let's come back to the example of using dictionaries for translation. Suppose we have one dictionary\n" +"for translating from English to French, and another for translating from French to German.\n" +"Let's use that to create a dictionary that translates from English to German:\n" +"\n" +" __copyable__\n" +"__code0__" + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.swap_keys_values_exercise +msgid "pages.CreatingKeyValuePairs.steps.swap_keys_values_exercise.hints.0.text" +msgstr "Create a new empty dictionary to store the result." + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.swap_keys_values_exercise +msgid "pages.CreatingKeyValuePairs.steps.swap_keys_values_exercise.hints.1.text" +msgstr "Iterate through the keys of the input dictionary `d`." + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.swap_keys_values_exercise +msgid "pages.CreatingKeyValuePairs.steps.swap_keys_values_exercise.hints.2.text" +msgstr "Inside the loop, for each `key`:" + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.swap_keys_values_exercise +msgid "pages.CreatingKeyValuePairs.steps.swap_keys_values_exercise.hints.3.text" +msgstr "1. Get the corresponding `value` from `d`." + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.swap_keys_values_exercise +msgid "pages.CreatingKeyValuePairs.steps.swap_keys_values_exercise.hints.4.text" +msgstr "" +"2. Add an entry to the new dictionary where the *key* is the original `value` and the *value* is the original `key`." + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.swap_keys_values_exercise +msgid "pages.CreatingKeyValuePairs.steps.swap_keys_values_exercise.hints.5.text" +msgstr "Return the new dictionary after the loop." + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. # __code0__: +#. def swap_keys_values(d): +#. ... +#. +#. assert_equal( +#. swap_keys_values({'apple': 'pomme', 'box': 'boite'}), +#. {'pomme': 'apple', 'boite': 'box'}, +#. ) +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.%27apple%27 +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.%27boite%27 +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.%27box%27 +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.%27pomme%27 +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.assert_equal +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.swap_keys_values +msgid "pages.CreatingKeyValuePairs.steps.swap_keys_values_exercise.text" +msgstr "" +"Great job!\n" +"\n" +"Of course, language isn't so simple, and there are many ways that using a dictionary like this could go wrong.\n" +"So...let's do something even worse! Write a function which takes a dictionary and swaps the keys and values,\n" +"so `a: b` becomes `b: a`.\n" +"\n" +" __copyable__\n" +"__code0__" + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.total_cost_per_item_exercise +msgid "pages.CreatingKeyValuePairs.steps.total_cost_per_item_exercise.hints.0.text" +msgstr "You need to iterate through the items in the `quantities` dictionary." + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.total_cost_per_item_exercise +msgid "pages.CreatingKeyValuePairs.steps.total_cost_per_item_exercise.hints.1.text" +msgstr "For each `item`, calculate the total cost for that item (quantity * price)." + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.total_cost_per_item_exercise +msgid "pages.CreatingKeyValuePairs.steps.total_cost_per_item_exercise.hints.2.text" +msgstr "Store this calculated cost in the `totals` dictionary." + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.total_cost_per_item_exercise +msgid "pages.CreatingKeyValuePairs.steps.total_cost_per_item_exercise.hints.3.text" +msgstr "The key for the `totals` dictionary should be the `item` name." + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.total_cost_per_item_exercise +msgid "pages.CreatingKeyValuePairs.steps.total_cost_per_item_exercise.hints.4.text" +msgstr "Use the dictionary assignment syntax: `totals[item] = calculated_cost`." + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.total_cost_per_item_exercise +msgid "pages.CreatingKeyValuePairs.steps.total_cost_per_item_exercise.hints.5.text" +msgstr "Make sure this assignment happens *inside* the loop." + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.total_cost_per_item_exercise +msgid "pages.CreatingKeyValuePairs.steps.total_cost_per_item_exercise.hints.6.text" +msgstr "The function should return the `totals` dictionary after the loop finishes." + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +msgid "pages.CreatingKeyValuePairs.steps.total_cost_per_item_exercise.text" +msgstr "" +"Well done!\n" +"\n" +"Next exercise: earlier we defined a function `total_cost(quantities, prices)` which returned a single number\n" +"with a grand total of all the items in the cart. Now let's make a function `total_cost_per_item(quantities, prices)`\n" +"which returns a new dictionary with the total cost for each item:\n" +"\n" +" __copyable__\n" +" def total_cost_per_item(quantities, prices):\n" +" totals = {}\n" +" for item in quantities:\n" +" ... = quantities[item] * prices[item]\n" +" return totals\n" +"\n" +" assert_equal(\n" +" total_cost_per_item({'apple': 2}, {'apple': 3, 'box': 5}),\n" +" {'apple': 6},\n" +" )\n" +"\n" +" assert_equal(\n" +" total_cost_per_item({'dog': 5000000, 'box': 2}, {'dog': 100, 'box': 5}),\n" +" {'dog': 500000000, 'box': 10},\n" +" )" + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +msgid "pages.CreatingKeyValuePairs.title" +msgstr "Creating Key-Value Pairs" + #. https://futurecoder.io/course/#DefiningFunctions #. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.DefiningFunctions.steps.change_function_name diff --git a/translations/locales/en/LC_MESSAGES/futurecoder.mo b/translations/locales/en/LC_MESSAGES/futurecoder.mo index 03910361628a1a71198bc484fa5bf0eba822d73f..5b843e1d940c895c6dfe605d16bf2ddc52d054e0 100644 GIT binary patch delta 35123 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 Jjy>7_{{Uok_O<{3 From 391edca048ef0751471ad29a00d5cfc907d0145a Mon Sep 17 00:00:00 2001 From: Alex Hall Date: Sun, 30 Mar 2025 16:34:38 +0200 Subject: [PATCH 02/16] tweaks --- core/chapters/c12_dictionaries.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/core/chapters/c12_dictionaries.py b/core/chapters/c12_dictionaries.py index 7cba16e2..facc56e7 100644 --- a/core/chapters/c12_dictionaries.py +++ b/core/chapters/c12_dictionaries.py @@ -784,9 +784,10 @@ def test(): Note that `buy_quantity` should *modify* the dictionary that's passed in, and doesn't need to return anything. You can assume that the user will enter a valid integer for the quantity. + You can also assume that the user won't enter an item that's already in `quantities`. """ requirements = "Your function should modify the `quantities` argument. It doesn't need to `return` or `print` anything." - no_returns_stdout = True # The function itself doesn't print/return, the test harness does + no_returns_stdout = True hints = """ The function needs to get two inputs from the user: the item name and the quantity. @@ -1022,7 +1023,7 @@ def swap_keys_values(d: Dict[str, str]): some data will be lost. But there are many situations where you can be sure that the values in a dictionary *are* unique and that this -'inversion' makes sense. For example, we saw this code [earlier in the chapter](#UsingDictionariesInPractice): +'inversion' makes sense. For example, we saw this code [earlier in the chapter](#UsingDictionaries): __copyable__ __no_auto_translate__ From 73421388171842891ef078ea6e15acaab3664ae5 Mon Sep 17 00:00:00 2001 From: Alex Hall Date: Sun, 6 Apr 2025 09:32:55 +0200 Subject: [PATCH 03/16] CopyingDictionaries --- core/chapters/c12_dictionaries.py | 241 +++++ tests/golden_files/en/test_transcript.json | 105 ++ translations/english.po | 998 +++++++++++++++++- .../locales/en/LC_MESSAGES/futurecoder.mo | Bin 308487 -> 315576 bytes 4 files changed, 1342 insertions(+), 2 deletions(-) diff --git a/core/chapters/c12_dictionaries.py b/core/chapters/c12_dictionaries.py index facc56e7..0249df55 100644 --- a/core/chapters/c12_dictionaries.py +++ b/core/chapters/c12_dictionaries.py @@ -1048,3 +1048,244 @@ def substitute(string, d): Otherwise it would be impossible to decrypt messages properly. If both `'h'` and `'j'` got replaced with `'q'` during encryption, there would be no way to know whether `'qpeef'` means `'hello'` or `'jello'`! """ + + +class CopyingDictionaries(Page): + title = "Copying Dictionaries" + + class shared_references(VerbatimStep): + """ + Remember how assigning one list variable to another (`list2 = list1`) made both names point to the *same* list? Dictionaries work the same way because they are also *mutable* (can be changed). + + Predict what the following code will print, then run it to see: + + __copyable__ + __program_indented__ + """ + def program(self): + d1 = {'a': 1, 'b': 2} + d2 = d1 + + print("d1 before:", d1) + print("d2 before:", d2) + print("Are they the same object?", d1 is d2) + + d2['c'] = 3 # Modify via d2 + + print("d1 after:", d1) # Is d1 affected? + print("d2 after:", d2) + + predicted_output_choices = [ + # Incorrect prediction (d1 unaffected) + """d1 before: {'a': 1, 'b': 2} +d2 before: {'a': 1, 'b': 2} +Are they the same object? True +d1 after: {'a': 1, 'b': 2} +d2 after: {'a': 1, 'b': 2, 'c': 3}""", + + # Correct prediction + """d1 before: {'a': 1, 'b': 2} +d2 before: {'a': 1, 'b': 2} +Are they the same object? True +d1 after: {'a': 1, 'b': 2, 'c': 3} +d2 after: {'a': 1, 'b': 2, 'c': 3}""", + + # Incorrect prediction (is False) + """d1 before: {'a': 1, 'b': 2} +d2 before: {'a': 1, 'b': 2} +Are they the same object? False +d1 after: {'a': 1, 'b': 2} +d2 after: {'a': 1, 'b': 2, 'c': 3}""", + ] + + class making_copies(VerbatimStep): + """ + Because `d1` and `d2` referred to the exact same dictionary object (`d1 is d2` was `True`), changing it via `d2` also changed what `d1` saw. + + To get a *separate* dictionary with the same contents, use the `.copy()` method. + + Predict how using `.copy()` changes the outcome, then run this code: + + __copyable__ + __program_indented__ + """ + def program(self): + d1 = {'a': 1, 'b': 2} + d2 = d1.copy() # Create a separate copy + + print("d1 before:", d1) + print("d2 before:", d2) + print("Are they the same object?", d1 is d2) + + d2['c'] = 3 # Modify the copy + + print("d1 after:", d1) # Is d1 affected now? + print("d2 after:", d2) + + predicted_output_choices = [ + # Incorrect prediction (is True) + """d1 before: {'a': 1, 'b': 2} +d2 before: {'a': 1, 'b': 2} +Are they the same object? True +d1 after: {'a': 1, 'b': 2, 'c': 3} +d2 after: {'a': 1, 'b': 2, 'c': 3}""", + + # Incorrect prediction (d1 affected) + """d1 before: {'a': 1, 'b': 2} +d2 before: {'a': 1, 'b': 2} +Are they the same object? False +d1 after: {'a': 1, 'b': 2, 'c': 3} +d2 after: {'a': 1, 'b': 2, 'c': 3}""", + + # Correct prediction + """d1 before: {'a': 1, 'b': 2} +d2 before: {'a': 1, 'b': 2} +Are they the same object? False +d1 after: {'a': 1, 'b': 2} +d2 after: {'a': 1, 'b': 2, 'c': 3}""", + ] + + class positive_stock_exercise(ExerciseStep): + """ + Making an exact copy is useful, but often we want a *modified* copy. Let's practice creating a new dictionary based on an old one. + + Write a function `positive_stock(stock)` that takes a dictionary `stock` (mapping item names to integer quantities) and returns a *new* dictionary containing only the items from the original `stock` where the quantity is strictly greater than 0. The original `stock` dictionary should not be changed. + + __copyable__ + def positive_stock(stock): + # Your code here + ... + + assert_equal( + positive_stock({'apple': 10, 'banana': 0, 'pear': 5, 'orange': 0}), + {'apple': 10, 'pear': 5} + ) + assert_equal( + positive_stock({'pen': 0, 'pencil': 0}), + {} + ) + assert_equal( + positive_stock({'book': 1, 'paper': 5}), + {'book': 1, 'paper': 5} + ) + """ + hints = """ + Start by creating a new empty dictionary, e.g., `result = {}`. + Loop through the keys of the input `stock` dictionary. + Inside the loop, get the `quantity` for the current `item` using `stock[item]`. + Use an `if` statement to check if `quantity > 0`. + If the quantity is positive, add the `item` and its `quantity` to your `result` dictionary using `result[item] = quantity`. + After the loop finishes, return the `result` dictionary. + Make sure you don't modify the original `stock` dictionary passed into the function. Creating a new `result` dictionary ensures this. + """ + + def solution(self): + def positive_stock(stock: Dict[str, int]): + result = {} + for item in stock: + quantity = stock[item] + if quantity > 0: + result[item] = quantity + return result + return positive_stock + + tests = [ + (({'apple': 10, 'banana': 0, 'pear': 5, 'orange': 0},), {'apple': 10, 'pear': 5}), + (({'pen': 0, 'pencil': 0},), {}), + (({'book': 1, 'paper': 5},), {'book': 1, 'paper': 5}), + (({},), {}), # Empty input + (({'gadget': -5, 'widget': 3},), {'widget': 3}), # Negative values + ] + + @classmethod + def generate_inputs(cls): + # Generate a dictionary with some zero/negative and positive values + stock = {} + num_items = random.randint(3, 8) + for _ in range(num_items): + item = generate_string(random.randint(3, 6)) + # Ensure some variety in quantities + if random.random() < 0.4: + quantity = 0 + elif random.random() < 0.2: + quantity = random.randint(-5, -1) + else: + quantity = random.randint(1, 20) + stock[item] = quantity + # Ensure at least one positive if dict not empty + if stock and all(q <= 0 for q in stock.values()): + stock[generate_string(4)] = random.randint(1, 10) + return {"stock": stock} + + class add_item_exercise(ExerciseStep): + """ + Let's practice combining copying and modifying. Imagine we want to represent adding one unit of an item to our stock count. + + Write a function `add_item(item, quantities)` that takes an item name (`item`) and a dictionary `quantities`. You can assume the `item` *already exists* as a key in the `quantities` dictionary. + + The function should return a *new* dictionary which is a copy of `quantities`, but with the value associated with `item` increased by 1. The original `quantities` dictionary should not be changed. + + __copyable__ + def add_item(item, quantities): + # Your code here + ... + + stock = {'apple': 5, 'banana': 2} + new_stock = add_item('apple', stock) + assert_equal(stock, {'apple': 5, 'banana': 2}) # Original unchanged + assert_equal(new_stock, {'apple': 6, 'banana': 2}) # Copy has incremented value + + new_stock_2 = add_item('banana', new_stock) + assert_equal(new_stock, {'apple': 6, 'banana': 2}) # Previous copy unchanged + assert_equal(new_stock_2, {'apple': 6, 'banana': 3}) # New copy incremented + """ + hints = """ + First, create a *copy* of the input `quantities` dictionary using the `.copy()` method. Store this in a new variable, e.g., `new_quantities`. + Since we assume `item` is already a key, you don't need to check for its existence in this exercise. + Find the current quantity of the `item` in the `new_quantities` copy using `new_quantities[item]`. + Calculate the new quantity by adding 1 to the current quantity. + Update the value for `item` in the `new_quantities` copy with this new quantity using assignment: `new_quantities[item] = ...`. + Return the `new_quantities` dictionary. + """ + + def solution(self): + def add_item(item: str, quantities: Dict[str, int]): + new_quantities = quantities.copy() + new_quantities[item] = new_quantities[item] + 1 + return new_quantities + return add_item + + tests = [ + (('apple', {'apple': 5, 'banana': 2}), {'apple': 6, 'banana': 2}), + (('banana', {'apple': 6, 'banana': 2}), {'apple': 6, 'banana': 3}), + (('pen', {'pen': 1}), {'pen': 2}), + (('a', {'a': 0, 'b': 99}), {'a': 1, 'b': 99}), + ] + + @classmethod + def generate_inputs(cls): + quantities = generate_dict(str, int) + # Ensure the dictionary is not empty + if not quantities: + quantities[generate_string(4)] = random.randint(0, 10) + # Pick an existing item to increment + item = random.choice(list(quantities.keys())) + return {"item": item, "quantities": quantities} + + final_text = """ + Well done! Notice that the line where you increment the value: + + new_quantities[item] = new_quantities[item] + 1 + + can also be written more concisely using the `+=` operator, just like with numbers: + + new_quantities[item] += 1 + + This does the same thing: it reads the current value, adds 1, and assigns the result back. + """ + + final_text = """ + Great! You now know why copying dictionaries is important (because they are mutable) and how to do it using `.copy()`. You've also practiced creating modified copies, which is a common and safe way to work with data without accidentally changing things elsewhere in your program. + + Next, we'll see how to check if a key exists *before* trying to use it, to avoid errors. + """ \ No newline at end of file diff --git a/tests/golden_files/en/test_transcript.json b/tests/golden_files/en/test_transcript.json index 47ed4659..99b77e70 100644 --- a/tests/golden_files/en/test_transcript.json +++ b/tests/golden_files/en/test_transcript.json @@ -7437,5 +7437,110 @@ "result": [] }, "step": "swap_keys_values_exercise" + }, + { + "get_solution": "program", + "page": "Copying Dictionaries", + "program": [ + "d1 = {'a': 1, 'b': 2}", + "d2 = d1", + "", + "print(\"d1 before:\", d1)", + "print(\"d2 before:\", d2)", + "print(\"Are they the same object?\", d1 is d2)", + "", + "d2['c'] = 3 # Modify via d2", + "", + "print(\"d1 after:\", d1) # Is d1 affected?", + "print(\"d2 after:\", d2)" + ], + "response": { + "passed": true, + "prediction": { + "answer": "d1 before: {'a': 1, 'b': 2}\nd2 before: {'a': 1, 'b': 2}\nAre they the same object? True\nd1 after: {'a': 1, 'b': 2, 'c': 3}\nd2 after: {'a': 1, 'b': 2, 'c': 3}", + "choices": [ + "d1 before: {'a': 1, 'b': 2}\nd2 before: {'a': 1, 'b': 2}\nAre they the same object? True\nd1 after: {'a': 1, 'b': 2}\nd2 after: {'a': 1, 'b': 2, 'c': 3}", + "d1 before: {'a': 1, 'b': 2}\nd2 before: {'a': 1, 'b': 2}\nAre they the same object? True\nd1 after: {'a': 1, 'b': 2, 'c': 3}\nd2 after: {'a': 1, 'b': 2, 'c': 3}", + "d1 before: {'a': 1, 'b': 2}\nd2 before: {'a': 1, 'b': 2}\nAre they the same object? False\nd1 after: {'a': 1, 'b': 2}\nd2 after: {'a': 1, 'b': 2, 'c': 3}", + "Error" + ] + }, + "result": [ + { + "text": "d1 before: {'a': 1, 'b': 2}\nd2 before: {'a': 1, 'b': 2}\nAre they the same object? True\nd1 after: {'a': 1, 'b': 2, 'c': 3}\nd2 after: {'a': 1, 'b': 2, 'c': 3}\n", + "type": "stdout" + } + ] + }, + "step": "shared_references" + }, + { + "get_solution": "program", + "page": "Copying Dictionaries", + "program": [ + "d1 = {'a': 1, 'b': 2}", + "d2 = d1.copy() # Create a separate copy", + "", + "print(\"d1 before:\", d1)", + "print(\"d2 before:\", d2)", + "print(\"Are they the same object?\", d1 is d2)", + "", + "d2['c'] = 3 # Modify the copy", + "", + "print(\"d1 after:\", d1) # Is d1 affected now?", + "print(\"d2 after:\", d2)" + ], + "response": { + "passed": true, + "prediction": { + "answer": "d1 before: {'a': 1, 'b': 2}\nd2 before: {'a': 1, 'b': 2}\nAre they the same object? False\nd1 after: {'a': 1, 'b': 2}\nd2 after: {'a': 1, 'b': 2, 'c': 3}", + "choices": [ + "d1 before: {'a': 1, 'b': 2}\nd2 before: {'a': 1, 'b': 2}\nAre they the same object? True\nd1 after: {'a': 1, 'b': 2, 'c': 3}\nd2 after: {'a': 1, 'b': 2, 'c': 3}", + "d1 before: {'a': 1, 'b': 2}\nd2 before: {'a': 1, 'b': 2}\nAre they the same object? False\nd1 after: {'a': 1, 'b': 2, 'c': 3}\nd2 after: {'a': 1, 'b': 2, 'c': 3}", + "d1 before: {'a': 1, 'b': 2}\nd2 before: {'a': 1, 'b': 2}\nAre they the same object? False\nd1 after: {'a': 1, 'b': 2}\nd2 after: {'a': 1, 'b': 2, 'c': 3}", + "Error" + ] + }, + "result": [ + { + "text": "d1 before: {'a': 1, 'b': 2}\nd2 before: {'a': 1, 'b': 2}\nAre they the same object? False\nd1 after: {'a': 1, 'b': 2}\nd2 after: {'a': 1, 'b': 2, 'c': 3}\n", + "type": "stdout" + } + ] + }, + "step": "making_copies" + }, + { + "get_solution": "program", + "page": "Copying Dictionaries", + "program": [ + "def positive_stock(stock):", + " result = {}", + " for item in stock:", + " quantity = stock[item]", + " if quantity > 0:", + " result[item] = quantity", + " return result" + ], + "response": { + "passed": true, + "result": [] + }, + "step": "positive_stock_exercise" + }, + { + "get_solution": "program", + "page": "Copying Dictionaries", + "program": [ + "def add_item(item, quantities):", + " new_quantities = quantities.copy()", + " new_quantities[item] = new_quantities[item] + 1", + " return new_quantities" + ], + "response": { + "passed": true, + "result": [] + }, + "step": "add_item_exercise" } ] \ No newline at end of file diff --git a/translations/english.po b/translations/english.po index ca2e6007..979f5305 100644 --- a/translations/english.po +++ b/translations/english.po @@ -536,6 +536,38 @@ msgstr "\"Alice's Diner\"" msgid "code_bits.\"Amazing! Are you psychic?\"" msgstr "\"Amazing! Are you psychic?\"" +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.making_copies +#. +#. d1 = {'a': 1, 'b': 2} +#. d2 = d1.copy() # Create a separate copy +#. +#. print("d1 before:", d1) +#. print("d2 before:", d2) +#. print("Are they the same object?", d1 is d2) +#. +#. d2['c'] = 3 # Modify the copy +#. +#. print("d1 after:", d1) # Is d1 affected now? +#. print("d2 after:", d2) +#. +#. ------ +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.shared_references +#. +#. d1 = {'a': 1, 'b': 2} +#. d2 = d1 +#. +#. print("d1 before:", d1) +#. print("d2 before:", d2) +#. print("Are they the same object?", d1 is d2) +#. +#. d2['c'] = 3 # Modify via d2 +#. +#. print("d1 after:", d1) # Is d1 affected? +#. print("d2 after:", d2) +msgid "code_bits.\"Are they the same object?\"" +msgstr "\"Are they the same object?\"" + #. https://poeditor.com/projects/view_terms?id=490053&search=pages.DefiningFunctions.steps.change_function_name #. #. def say_hello(name): @@ -1372,6 +1404,134 @@ msgstr "\"abc\"" msgid "code_bits.\"cat.jpg\"" msgstr "\"cat.jpg\"" +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.making_copies +#. +#. d1 = {'a': 1, 'b': 2} +#. d2 = d1.copy() # Create a separate copy +#. +#. print("d1 before:", d1) +#. print("d2 before:", d2) +#. print("Are they the same object?", d1 is d2) +#. +#. d2['c'] = 3 # Modify the copy +#. +#. print("d1 after:", d1) # Is d1 affected now? +#. print("d2 after:", d2) +#. +#. ------ +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.shared_references +#. +#. d1 = {'a': 1, 'b': 2} +#. d2 = d1 +#. +#. print("d1 before:", d1) +#. print("d2 before:", d2) +#. print("Are they the same object?", d1 is d2) +#. +#. d2['c'] = 3 # Modify via d2 +#. +#. print("d1 after:", d1) # Is d1 affected? +#. print("d2 after:", d2) +msgid "code_bits.\"d1 after:\"" +msgstr "\"d1 after:\"" + +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.making_copies +#. +#. d1 = {'a': 1, 'b': 2} +#. d2 = d1.copy() # Create a separate copy +#. +#. print("d1 before:", d1) +#. print("d2 before:", d2) +#. print("Are they the same object?", d1 is d2) +#. +#. d2['c'] = 3 # Modify the copy +#. +#. print("d1 after:", d1) # Is d1 affected now? +#. print("d2 after:", d2) +#. +#. ------ +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.shared_references +#. +#. d1 = {'a': 1, 'b': 2} +#. d2 = d1 +#. +#. print("d1 before:", d1) +#. print("d2 before:", d2) +#. print("Are they the same object?", d1 is d2) +#. +#. d2['c'] = 3 # Modify via d2 +#. +#. print("d1 after:", d1) # Is d1 affected? +#. print("d2 after:", d2) +msgid "code_bits.\"d1 before:\"" +msgstr "\"d1 before:\"" + +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.making_copies +#. +#. d1 = {'a': 1, 'b': 2} +#. d2 = d1.copy() # Create a separate copy +#. +#. print("d1 before:", d1) +#. print("d2 before:", d2) +#. print("Are they the same object?", d1 is d2) +#. +#. d2['c'] = 3 # Modify the copy +#. +#. print("d1 after:", d1) # Is d1 affected now? +#. print("d2 after:", d2) +#. +#. ------ +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.shared_references +#. +#. d1 = {'a': 1, 'b': 2} +#. d2 = d1 +#. +#. print("d1 before:", d1) +#. print("d2 before:", d2) +#. print("Are they the same object?", d1 is d2) +#. +#. d2['c'] = 3 # Modify via d2 +#. +#. print("d1 after:", d1) # Is d1 affected? +#. print("d2 after:", d2) +msgid "code_bits.\"d2 after:\"" +msgstr "\"d2 after:\"" + +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.making_copies +#. +#. d1 = {'a': 1, 'b': 2} +#. d2 = d1.copy() # Create a separate copy +#. +#. print("d1 before:", d1) +#. print("d2 before:", d2) +#. print("Are they the same object?", d1 is d2) +#. +#. d2['c'] = 3 # Modify the copy +#. +#. print("d1 after:", d1) # Is d1 affected now? +#. print("d2 after:", d2) +#. +#. ------ +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.shared_references +#. +#. d1 = {'a': 1, 'b': 2} +#. d2 = d1 +#. +#. print("d1 before:", d1) +#. print("d2 before:", d2) +#. print("Are they the same object?", d1 is d2) +#. +#. d2['c'] = 3 # Modify via d2 +#. +#. print("d1 after:", d1) # Is d1 affected? +#. print("d2 after:", d2) +msgid "code_bits.\"d2 before:\"" +msgstr "\"d2 before:\"" + #. https://poeditor.com/projects/view_terms?id=490053&search=pages.IntroducingNestedLists.steps.double_subscripting #. #. strings = ["abc", "def", "ghi"] @@ -3296,6 +3456,44 @@ msgstr "'aeiou'" msgid "code_bits.'apfel'" msgstr "'apfel'" +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.add_item_exercise.text +#. +#. def add_item(item, quantities): +#. # Your code here +#. ... +#. +#. stock = {'apple': 5, 'banana': 2} +#. new_stock = add_item('apple', stock) +#. assert_equal(stock, {'apple': 5, 'banana': 2}) # Original unchanged +#. assert_equal(new_stock, {'apple': 6, 'banana': 2}) # Copy has incremented value +#. +#. new_stock_2 = add_item('banana', new_stock) +#. assert_equal(new_stock, {'apple': 6, 'banana': 2}) # Previous copy unchanged +#. assert_equal(new_stock_2, {'apple': 6, 'banana': 3}) # New copy incremented +#. +#. ------ +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.positive_stock_exercise.text +#. +#. def positive_stock(stock): +#. # Your code here +#. ... +#. +#. assert_equal( +#. positive_stock({'apple': 10, 'banana': 0, 'pear': 5, 'orange': 0}), +#. {'apple': 10, 'pear': 5} +#. ) +#. assert_equal( +#. positive_stock({'pen': 0, 'pencil': 0}), +#. {} +#. ) +#. assert_equal( +#. positive_stock({'book': 1, 'paper': 5}), +#. {'book': 1, 'paper': 5} +#. ) +#. +#. ------ +#. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise.text #. #. def make_english_to_german(english_to_french, french_to_german): @@ -3502,6 +3700,44 @@ msgstr "'apple'" msgid "code_bits.'are'" msgstr "'are'" +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.add_item_exercise.text +#. +#. def add_item(item, quantities): +#. # Your code here +#. ... +#. +#. stock = {'apple': 5, 'banana': 2} +#. new_stock = add_item('apple', stock) +#. assert_equal(stock, {'apple': 5, 'banana': 2}) # Original unchanged +#. assert_equal(new_stock, {'apple': 6, 'banana': 2}) # Copy has incremented value +#. +#. new_stock_2 = add_item('banana', new_stock) +#. assert_equal(new_stock, {'apple': 6, 'banana': 2}) # Previous copy unchanged +#. assert_equal(new_stock_2, {'apple': 6, 'banana': 3}) # New copy incremented +#. +#. ------ +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.positive_stock_exercise.text +#. +#. def positive_stock(stock): +#. # Your code here +#. ... +#. +#. assert_equal( +#. positive_stock({'apple': 10, 'banana': 0, 'pear': 5, 'orange': 0}), +#. {'apple': 10, 'pear': 5} +#. ) +#. assert_equal( +#. positive_stock({'pen': 0, 'pencil': 0}), +#. {} +#. ) +#. assert_equal( +#. positive_stock({'book': 1, 'paper': 5}), +#. {'book': 1, 'paper': 5} +#. ) +msgid "code_bits.'banana'" +msgstr "'banana'" + #. https://poeditor.com/projects/view_terms?id=490053&search=pages.TheEqualityOperator.steps.introducing_equality #. #. print(1 + 2 == 3) @@ -3588,6 +3824,27 @@ msgstr "'bc'" msgid "code_bits.'boite'" msgstr "'boite'" +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.positive_stock_exercise.text +#. +#. def positive_stock(stock): +#. # Your code here +#. ... +#. +#. assert_equal( +#. positive_stock({'apple': 10, 'banana': 0, 'pear': 5, 'orange': 0}), +#. {'apple': 10, 'pear': 5} +#. ) +#. assert_equal( +#. positive_stock({'pen': 0, 'pencil': 0}), +#. {} +#. ) +#. assert_equal( +#. positive_stock({'book': 1, 'paper': 5}), +#. {'book': 1, 'paper': 5} +#. ) +msgid "code_bits.'book'" +msgstr "'book'" + #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.dict_assignment_valid #. #. quantities = {} @@ -4469,6 +4726,111 @@ msgstr "'list'" msgid "code_bits.'on'" msgstr "'on'" +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.positive_stock_exercise.text +#. +#. def positive_stock(stock): +#. # Your code here +#. ... +#. +#. assert_equal( +#. positive_stock({'apple': 10, 'banana': 0, 'pear': 5, 'orange': 0}), +#. {'apple': 10, 'pear': 5} +#. ) +#. assert_equal( +#. positive_stock({'pen': 0, 'pencil': 0}), +#. {} +#. ) +#. assert_equal( +#. positive_stock({'book': 1, 'paper': 5}), +#. {'book': 1, 'paper': 5} +#. ) +msgid "code_bits.'orange'" +msgstr "'orange'" + +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.positive_stock_exercise.text +#. +#. def positive_stock(stock): +#. # Your code here +#. ... +#. +#. assert_equal( +#. positive_stock({'apple': 10, 'banana': 0, 'pear': 5, 'orange': 0}), +#. {'apple': 10, 'pear': 5} +#. ) +#. assert_equal( +#. positive_stock({'pen': 0, 'pencil': 0}), +#. {} +#. ) +#. assert_equal( +#. positive_stock({'book': 1, 'paper': 5}), +#. {'book': 1, 'paper': 5} +#. ) +msgid "code_bits.'paper'" +msgstr "'paper'" + +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.positive_stock_exercise.text +#. +#. def positive_stock(stock): +#. # Your code here +#. ... +#. +#. assert_equal( +#. positive_stock({'apple': 10, 'banana': 0, 'pear': 5, 'orange': 0}), +#. {'apple': 10, 'pear': 5} +#. ) +#. assert_equal( +#. positive_stock({'pen': 0, 'pencil': 0}), +#. {} +#. ) +#. assert_equal( +#. positive_stock({'book': 1, 'paper': 5}), +#. {'book': 1, 'paper': 5} +#. ) +msgid "code_bits.'pear'" +msgstr "'pear'" + +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.positive_stock_exercise.text +#. +#. def positive_stock(stock): +#. # Your code here +#. ... +#. +#. assert_equal( +#. positive_stock({'apple': 10, 'banana': 0, 'pear': 5, 'orange': 0}), +#. {'apple': 10, 'pear': 5} +#. ) +#. assert_equal( +#. positive_stock({'pen': 0, 'pencil': 0}), +#. {} +#. ) +#. assert_equal( +#. positive_stock({'book': 1, 'paper': 5}), +#. {'book': 1, 'paper': 5} +#. ) +msgid "code_bits.'pen'" +msgstr "'pen'" + +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.positive_stock_exercise.text +#. +#. def positive_stock(stock): +#. # Your code here +#. ... +#. +#. assert_equal( +#. positive_stock({'apple': 10, 'banana': 0, 'pear': 5, 'orange': 0}), +#. {'apple': 10, 'pear': 5} +#. ) +#. assert_equal( +#. positive_stock({'pen': 0, 'pencil': 0}), +#. {} +#. ) +#. assert_equal( +#. positive_stock({'book': 1, 'paper': 5}), +#. {'book': 1, 'paper': 5} +#. ) +msgid "code_bits.'pencil'" +msgstr "'pencil'" + #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise.text #. #. def make_english_to_german(english_to_french, french_to_german): @@ -4650,6 +5012,18 @@ msgstr "'you'" msgid "code_bits.Hello" msgstr "Hello" +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.making_copies.text +#. +#. __program_indented__ +#. +#. ------ +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.shared_references.text +#. +#. __program_indented__ +#. +#. ------ +#. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.dict_assignment_valid.text #. #. __program_indented__ @@ -4960,6 +5334,32 @@ msgstr "__program_indented__" msgid "code_bits.actual" msgstr "actual" +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.add_item_exercise +#. +#. def add_item(item, quantities): +#. new_quantities = quantities.copy() +#. new_quantities[item] = new_quantities[item] + 1 +#. return new_quantities +#. +#. ------ +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.add_item_exercise.text +#. +#. def add_item(item, quantities): +#. # Your code here +#. ... +#. +#. stock = {'apple': 5, 'banana': 2} +#. new_stock = add_item('apple', stock) +#. assert_equal(stock, {'apple': 5, 'banana': 2}) # Original unchanged +#. assert_equal(new_stock, {'apple': 6, 'banana': 2}) # Copy has incremented value +#. +#. new_stock_2 = add_item('banana', new_stock) +#. assert_equal(new_stock, {'apple': 6, 'banana': 2}) # Previous copy unchanged +#. assert_equal(new_stock_2, {'apple': 6, 'banana': 3}) # New copy incremented +msgid "code_bits.add_item" +msgstr "add_item" + #. https://poeditor.com/projects/view_terms?id=490053&search=pages.IntroducingFstrings.steps.basic_f_string_exercise #. #. name = "Alice" @@ -5157,6 +5557,44 @@ msgstr "all_numbers" #. #. ------ #. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.add_item_exercise.text +#. +#. def add_item(item, quantities): +#. # Your code here +#. ... +#. +#. stock = {'apple': 5, 'banana': 2} +#. new_stock = add_item('apple', stock) +#. assert_equal(stock, {'apple': 5, 'banana': 2}) # Original unchanged +#. assert_equal(new_stock, {'apple': 6, 'banana': 2}) # Copy has incremented value +#. +#. new_stock_2 = add_item('banana', new_stock) +#. assert_equal(new_stock, {'apple': 6, 'banana': 2}) # Previous copy unchanged +#. assert_equal(new_stock_2, {'apple': 6, 'banana': 3}) # New copy incremented +#. +#. ------ +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.positive_stock_exercise.text +#. +#. def positive_stock(stock): +#. # Your code here +#. ... +#. +#. assert_equal( +#. positive_stock({'apple': 10, 'banana': 0, 'pear': 5, 'orange': 0}), +#. {'apple': 10, 'pear': 5} +#. ) +#. assert_equal( +#. positive_stock({'pen': 0, 'pencil': 0}), +#. {} +#. ) +#. assert_equal( +#. positive_stock({'book': 1, 'paper': 5}), +#. {'book': 1, 'paper': 5} +#. ) +#. +#. ------ +#. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise.text #. #. def make_english_to_german(english_to_french, french_to_german): @@ -8208,6 +8646,70 @@ msgstr "consonants" msgid "code_bits.cube" msgstr "cube" +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.making_copies +#. +#. d1 = {'a': 1, 'b': 2} +#. d2 = d1.copy() # Create a separate copy +#. +#. print("d1 before:", d1) +#. print("d2 before:", d2) +#. print("Are they the same object?", d1 is d2) +#. +#. d2['c'] = 3 # Modify the copy +#. +#. print("d1 after:", d1) # Is d1 affected now? +#. print("d2 after:", d2) +#. +#. ------ +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.shared_references +#. +#. d1 = {'a': 1, 'b': 2} +#. d2 = d1 +#. +#. print("d1 before:", d1) +#. print("d2 before:", d2) +#. print("Are they the same object?", d1 is d2) +#. +#. d2['c'] = 3 # Modify via d2 +#. +#. print("d1 after:", d1) # Is d1 affected? +#. print("d2 after:", d2) +msgid "code_bits.d1" +msgstr "d1" + +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.making_copies +#. +#. d1 = {'a': 1, 'b': 2} +#. d2 = d1.copy() # Create a separate copy +#. +#. print("d1 before:", d1) +#. print("d2 before:", d2) +#. print("Are they the same object?", d1 is d2) +#. +#. d2['c'] = 3 # Modify the copy +#. +#. print("d1 after:", d1) # Is d1 affected now? +#. print("d2 after:", d2) +#. +#. ------ +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.shared_references +#. +#. d1 = {'a': 1, 'b': 2} +#. d2 = d1 +#. +#. print("d1 before:", d1) +#. print("d2 before:", d2) +#. print("Are they the same object?", d1 is d2) +#. +#. d2['c'] = 3 # Modify via d2 +#. +#. print("d1 after:", d1) # Is d1 affected? +#. print("d2 after:", d2) +msgid "code_bits.d2" +msgstr "d2" + #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CombiningAndAndOr.steps.final_text.text #. #. diagonal1 = all_equal([board[0][0], board[1][1], board[2][2]]) @@ -11348,6 +11850,44 @@ msgstr "is_friend" msgid "code_bits.is_valid_percentage" msgstr "is_valid_percentage" +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.add_item_exercise +#. +#. def add_item(item, quantities): +#. new_quantities = quantities.copy() +#. new_quantities[item] = new_quantities[item] + 1 +#. return new_quantities +#. +#. ------ +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.add_item_exercise.text +#. +#. def add_item(item, quantities): +#. # Your code here +#. ... +#. +#. stock = {'apple': 5, 'banana': 2} +#. new_stock = add_item('apple', stock) +#. assert_equal(stock, {'apple': 5, 'banana': 2}) # Original unchanged +#. assert_equal(new_stock, {'apple': 6, 'banana': 2}) # Copy has incremented value +#. +#. new_stock_2 = add_item('banana', new_stock) +#. assert_equal(new_stock, {'apple': 6, 'banana': 2}) # Previous copy unchanged +#. assert_equal(new_stock_2, {'apple': 6, 'banana': 3}) # New copy incremented +#. +#. ------ +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.positive_stock_exercise +#. +#. def positive_stock(stock): +#. result = {} +#. for item in stock: +#. quantity = stock[item] +#. if quantity > 0: +#. result[item] = quantity +#. return result +#. +#. ------ +#. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise #. #. def buy_quantity(quantities): @@ -13312,6 +13852,15 @@ msgstr "new_numbers" msgid "code_bits.new_nums" msgstr "new_nums" +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.add_item_exercise +#. +#. def add_item(item, quantities): +#. new_quantities = quantities.copy() +#. new_quantities[item] = new_quantities[item] + 1 +#. return new_quantities +msgid "code_bits.new_quantities" +msgstr "new_quantities" + #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CombiningCompoundStatements.steps.final_text.text #. #. sentence = 'Hello World' @@ -13442,6 +13991,40 @@ msgstr "new_nums" msgid "code_bits.new_sentence" msgstr "new_sentence" +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.add_item_exercise.text +#. +#. def add_item(item, quantities): +#. # Your code here +#. ... +#. +#. stock = {'apple': 5, 'banana': 2} +#. new_stock = add_item('apple', stock) +#. assert_equal(stock, {'apple': 5, 'banana': 2}) # Original unchanged +#. assert_equal(new_stock, {'apple': 6, 'banana': 2}) # Copy has incremented value +#. +#. new_stock_2 = add_item('banana', new_stock) +#. assert_equal(new_stock, {'apple': 6, 'banana': 2}) # Previous copy unchanged +#. assert_equal(new_stock_2, {'apple': 6, 'banana': 3}) # New copy incremented +msgid "code_bits.new_stock" +msgstr "new_stock" + +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.add_item_exercise.text +#. +#. def add_item(item, quantities): +#. # Your code here +#. ... +#. +#. stock = {'apple': 5, 'banana': 2} +#. new_stock = add_item('apple', stock) +#. assert_equal(stock, {'apple': 5, 'banana': 2}) # Original unchanged +#. assert_equal(new_stock, {'apple': 6, 'banana': 2}) # Copy has incremented value +#. +#. new_stock_2 = add_item('banana', new_stock) +#. assert_equal(new_stock, {'apple': 6, 'banana': 2}) # Previous copy unchanged +#. assert_equal(new_stock_2, {'apple': 6, 'banana': 3}) # New copy incremented +msgid "code_bits.new_stock_2" +msgstr "new_stock_2" + #. https://poeditor.com/projects/view_terms?id=490053&search=pages.FunctionsAndMethodsForLists.steps.subscript_assignment_predict.text #. #. some_list[index] = new_value @@ -15099,6 +15682,39 @@ msgstr "player2" msgid "code_bits.players" msgstr "players" +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.positive_stock_exercise +#. +#. def positive_stock(stock): +#. result = {} +#. for item in stock: +#. quantity = stock[item] +#. if quantity > 0: +#. result[item] = quantity +#. return result +#. +#. ------ +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.positive_stock_exercise.text +#. +#. def positive_stock(stock): +#. # Your code here +#. ... +#. +#. assert_equal( +#. positive_stock({'apple': 10, 'banana': 0, 'pear': 5, 'orange': 0}), +#. {'apple': 10, 'pear': 5} +#. ) +#. assert_equal( +#. positive_stock({'pen': 0, 'pencil': 0}), +#. {} +#. ) +#. assert_equal( +#. positive_stock({'book': 1, 'paper': 5}), +#. {'book': 1, 'paper': 5} +#. ) +msgid "code_bits.positive_stock" +msgstr "positive_stock" + #. https://poeditor.com/projects/view_terms?id=490053&search=pages.LoopingOverNestedLists.steps.list_contains_word_exercise #. #. strings = [['hello there', 'how are you'], ['goodbye world', 'hello world']] @@ -15858,6 +16474,32 @@ msgstr "printed" msgid "code_bits.quadruple" msgstr "quadruple" +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.add_item_exercise +#. +#. def add_item(item, quantities): +#. new_quantities = quantities.copy() +#. new_quantities[item] = new_quantities[item] + 1 +#. return new_quantities +#. +#. ------ +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.add_item_exercise.text +#. +#. def add_item(item, quantities): +#. # Your code here +#. ... +#. +#. stock = {'apple': 5, 'banana': 2} +#. new_stock = add_item('apple', stock) +#. assert_equal(stock, {'apple': 5, 'banana': 2}) # Original unchanged +#. assert_equal(new_stock, {'apple': 6, 'banana': 2}) # Copy has incremented value +#. +#. new_stock_2 = add_item('banana', new_stock) +#. assert_equal(new_stock, {'apple': 6, 'banana': 2}) # Previous copy unchanged +#. assert_equal(new_stock_2, {'apple': 6, 'banana': 3}) # New copy incremented +#. +#. ------ +#. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise #. #. def buy_quantity(quantities): @@ -16002,6 +16644,18 @@ msgstr "quadruple" msgid "code_bits.quantities" msgstr "quantities" +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.positive_stock_exercise +#. +#. def positive_stock(stock): +#. result = {} +#. for item in stock: +#. quantity = stock[item] +#. if quantity > 0: +#. result[item] = quantity +#. return result +#. +#. ------ +#. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.DictionaryKeysAndValues.steps.cleanup_shopping_cart #. #. def total_cost(quantities, prices): @@ -16078,6 +16732,18 @@ msgstr "quantity" msgid "code_bits.quantity_str" msgstr "quantity_str" +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.positive_stock_exercise +#. +#. def positive_stock(stock): +#. result = {} +#. for item in stock: +#. quantity = stock[item] +#. if quantity > 0: +#. result[item] = quantity +#. return result +#. +#. ------ +#. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.DictionaryKeysAndValues.steps.cleanup_shopping_cart #. #. def total_cost(quantities, prices): @@ -17771,6 +18437,56 @@ msgstr "some_list" msgid "code_bits.spaces" msgstr "spaces" +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.add_item_exercise.text +#. +#. def add_item(item, quantities): +#. # Your code here +#. ... +#. +#. stock = {'apple': 5, 'banana': 2} +#. new_stock = add_item('apple', stock) +#. assert_equal(stock, {'apple': 5, 'banana': 2}) # Original unchanged +#. assert_equal(new_stock, {'apple': 6, 'banana': 2}) # Copy has incremented value +#. +#. new_stock_2 = add_item('banana', new_stock) +#. assert_equal(new_stock, {'apple': 6, 'banana': 2}) # Previous copy unchanged +#. assert_equal(new_stock_2, {'apple': 6, 'banana': 3}) # New copy incremented +#. +#. ------ +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.positive_stock_exercise +#. +#. def positive_stock(stock): +#. result = {} +#. for item in stock: +#. quantity = stock[item] +#. if quantity > 0: +#. result[item] = quantity +#. return result +#. +#. ------ +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.positive_stock_exercise.text +#. +#. def positive_stock(stock): +#. # Your code here +#. ... +#. +#. assert_equal( +#. positive_stock({'apple': 10, 'banana': 0, 'pear': 5, 'orange': 0}), +#. {'apple': 10, 'pear': 5} +#. ) +#. assert_equal( +#. positive_stock({'pen': 0, 'pencil': 0}), +#. {} +#. ) +#. assert_equal( +#. positive_stock({'book': 1, 'paper': 5}), +#. {'book': 1, 'paper': 5} +#. ) +msgid "code_bits.stock" +msgstr "stock" + #. https://poeditor.com/projects/view_terms?id=490053&search=pages.IntroducingNestedLists.steps.double_subscripting.text #. #. string = strings[1] @@ -22218,6 +22934,283 @@ msgstr "" msgid "pages.CombiningCompoundStatements.title" msgstr "Combining Compound Statements" +#. https://futurecoder.io/course/#CopyingDictionaries +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.add_item_exercise +msgid "pages.CopyingDictionaries.steps.add_item_exercise.hints.0.text" +msgstr "" +"First, create a *copy* of the input `quantities` dictionary using the `.copy()` method. Store this in a new variable, " +"e.g., `new_quantities`." + +#. https://futurecoder.io/course/#CopyingDictionaries +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.add_item_exercise +msgid "pages.CopyingDictionaries.steps.add_item_exercise.hints.1.text" +msgstr "Since we assume `item` is already a key, you don't need to check for its existence in this exercise." + +#. https://futurecoder.io/course/#CopyingDictionaries +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.add_item_exercise +msgid "pages.CopyingDictionaries.steps.add_item_exercise.hints.2.text" +msgstr "Find the current quantity of the `item` in the `new_quantities` copy using `new_quantities[item]`." + +#. https://futurecoder.io/course/#CopyingDictionaries +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.add_item_exercise +msgid "pages.CopyingDictionaries.steps.add_item_exercise.hints.3.text" +msgstr "Calculate the new quantity by adding 1 to the current quantity." + +#. https://futurecoder.io/course/#CopyingDictionaries +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.add_item_exercise +msgid "pages.CopyingDictionaries.steps.add_item_exercise.hints.4.text" +msgstr "" +"Update the value for `item` in the `new_quantities` copy with this new quantity using assignment: " +"`new_quantities[item] = ...`." + +#. https://futurecoder.io/course/#CopyingDictionaries +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.add_item_exercise +msgid "pages.CopyingDictionaries.steps.add_item_exercise.hints.5.text" +msgstr "Return the `new_quantities` dictionary." + +#. https://futurecoder.io/course/#CopyingDictionaries +#. +#. # __code0__: +#. def add_item(item, quantities): +#. # Your code here +#. ... +#. +#. stock = {'apple': 5, 'banana': 2} +#. new_stock = add_item('apple', stock) +#. assert_equal(stock, {'apple': 5, 'banana': 2}) # Original unchanged +#. assert_equal(new_stock, {'apple': 6, 'banana': 2}) # Copy has incremented value +#. +#. new_stock_2 = add_item('banana', new_stock) +#. assert_equal(new_stock, {'apple': 6, 'banana': 2}) # Previous copy unchanged +#. assert_equal(new_stock_2, {'apple': 6, 'banana': 3}) # New copy incremented +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.%27apple%27 +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.%27banana%27 +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.add_item +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.assert_equal +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.item +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.new_stock +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.new_stock_2 +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.quantities +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.stock +msgid "pages.CopyingDictionaries.steps.add_item_exercise.text" +msgstr "" +"Let's practice combining copying and modifying. Imagine we want to represent adding one unit of an item to our stock count.\n" +"\n" +"Write a function `add_item(item, quantities)` that takes an item name (`item`) and a dictionary `quantities`. You can assume the `item` *already exists* as a key in the `quantities` dictionary.\n" +"\n" +"The function should return a *new* dictionary which is a copy of `quantities`, but with the value associated with `item` increased by 1. The original `quantities` dictionary should not be changed.\n" +"\n" +" __copyable__\n" +"__code0__" + +#. https://futurecoder.io/course/#CopyingDictionaries +msgid "pages.CopyingDictionaries.steps.final_text.text" +msgstr "" +"Great! You now know why copying dictionaries is important (because they are mutable) and how to do it using `.copy()`. You've also practiced creating modified copies, which is a common and safe way to work with data without accidentally changing things elsewhere in your program.\n" +"\n" +"Next, we'll see how to check if a key exists *before* trying to use it, to avoid errors." + +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.making_copies +msgid "pages.CopyingDictionaries.steps.making_copies.output_prediction_choices.0" +msgstr "" +"d1 before: {'a': 1, 'b': 2}\n" +"d2 before: {'a': 1, 'b': 2}\n" +"Are they the same object? True\n" +"d1 after: {'a': 1, 'b': 2, 'c': 3}\n" +"d2 after: {'a': 1, 'b': 2, 'c': 3}" + +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.making_copies +msgid "pages.CopyingDictionaries.steps.making_copies.output_prediction_choices.1" +msgstr "" +"d1 before: {'a': 1, 'b': 2}\n" +"d2 before: {'a': 1, 'b': 2}\n" +"Are they the same object? False\n" +"d1 after: {'a': 1, 'b': 2, 'c': 3}\n" +"d2 after: {'a': 1, 'b': 2, 'c': 3}" + +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.making_copies +msgid "pages.CopyingDictionaries.steps.making_copies.output_prediction_choices.2" +msgstr "" +"d1 before: {'a': 1, 'b': 2}\n" +"d2 before: {'a': 1, 'b': 2}\n" +"Are they the same object? False\n" +"d1 after: {'a': 1, 'b': 2}\n" +"d2 after: {'a': 1, 'b': 2, 'c': 3}" + +#. https://futurecoder.io/course/#CopyingDictionaries +#. +#. # __code0__: +#. __program_indented__ +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.__program_indented__ +msgid "pages.CopyingDictionaries.steps.making_copies.text" +msgstr "" +"Because `d1` and `d2` referred to the exact same dictionary object (`d1 is d2` was `True`), changing it via `d2` also changed what `d1` saw.\n" +"\n" +"To get a *separate* dictionary with the same contents, use the `.copy()` method.\n" +"\n" +"Predict how using `.copy()` changes the outcome, then run this code:\n" +"\n" +" __copyable__\n" +"__code0__" + +#. https://futurecoder.io/course/#CopyingDictionaries +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.positive_stock_exercise +msgid "pages.CopyingDictionaries.steps.positive_stock_exercise.hints.0.text" +msgstr "Start by creating a new empty dictionary, e.g., `result = {}`." + +#. https://futurecoder.io/course/#CopyingDictionaries +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.positive_stock_exercise +msgid "pages.CopyingDictionaries.steps.positive_stock_exercise.hints.1.text" +msgstr "Loop through the keys of the input `stock` dictionary." + +#. https://futurecoder.io/course/#CopyingDictionaries +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.positive_stock_exercise +msgid "pages.CopyingDictionaries.steps.positive_stock_exercise.hints.2.text" +msgstr "Inside the loop, get the `quantity` for the current `item` using `stock[item]`." + +#. https://futurecoder.io/course/#CopyingDictionaries +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.positive_stock_exercise +msgid "pages.CopyingDictionaries.steps.positive_stock_exercise.hints.3.text" +msgstr "Use an `if` statement to check if `quantity > 0`." + +#. https://futurecoder.io/course/#CopyingDictionaries +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.positive_stock_exercise +msgid "pages.CopyingDictionaries.steps.positive_stock_exercise.hints.4.text" +msgstr "" +"If the quantity is positive, add the `item` and its `quantity` to your `result` dictionary using `result[item] = " +"quantity`." + +#. https://futurecoder.io/course/#CopyingDictionaries +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.positive_stock_exercise +msgid "pages.CopyingDictionaries.steps.positive_stock_exercise.hints.5.text" +msgstr "After the loop finishes, return the `result` dictionary." + +#. https://futurecoder.io/course/#CopyingDictionaries +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.positive_stock_exercise +msgid "pages.CopyingDictionaries.steps.positive_stock_exercise.hints.6.text" +msgstr "" +"Make sure you don't modify the original `stock` dictionary passed into the function. Creating a new `result` " +"dictionary ensures this." + +#. https://futurecoder.io/course/#CopyingDictionaries +#. +#. # __code0__: +#. def positive_stock(stock): +#. # Your code here +#. ... +#. +#. assert_equal( +#. positive_stock({'apple': 10, 'banana': 0, 'pear': 5, 'orange': 0}), +#. {'apple': 10, 'pear': 5} +#. ) +#. assert_equal( +#. positive_stock({'pen': 0, 'pencil': 0}), +#. {} +#. ) +#. assert_equal( +#. positive_stock({'book': 1, 'paper': 5}), +#. {'book': 1, 'paper': 5} +#. ) +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.%27apple%27 +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.%27banana%27 +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.%27book%27 +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.%27orange%27 +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.%27paper%27 +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.%27pear%27 +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.%27pen%27 +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.%27pencil%27 +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.assert_equal +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.positive_stock +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.stock +msgid "pages.CopyingDictionaries.steps.positive_stock_exercise.text" +msgstr "" +"Making an exact copy is useful, but often we want a *modified* copy. Let's practice creating a new dictionary based on an old one.\n" +"\n" +"Write a function `positive_stock(stock)` that takes a dictionary `stock` (mapping item names to integer quantities) and returns a *new* dictionary containing only the items from the original `stock` where the quantity is strictly greater than 0. The original `stock` dictionary should not be changed.\n" +"\n" +" __copyable__\n" +"__code0__" + +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.shared_references +msgid "pages.CopyingDictionaries.steps.shared_references.output_prediction_choices.0" +msgstr "" +"d1 before: {'a': 1, 'b': 2}\n" +"d2 before: {'a': 1, 'b': 2}\n" +"Are they the same object? True\n" +"d1 after: {'a': 1, 'b': 2}\n" +"d2 after: {'a': 1, 'b': 2, 'c': 3}" + +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.shared_references +msgid "pages.CopyingDictionaries.steps.shared_references.output_prediction_choices.1" +msgstr "" +"d1 before: {'a': 1, 'b': 2}\n" +"d2 before: {'a': 1, 'b': 2}\n" +"Are they the same object? True\n" +"d1 after: {'a': 1, 'b': 2, 'c': 3}\n" +"d2 after: {'a': 1, 'b': 2, 'c': 3}" + +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.shared_references +msgid "pages.CopyingDictionaries.steps.shared_references.output_prediction_choices.2" +msgstr "" +"d1 before: {'a': 1, 'b': 2}\n" +"d2 before: {'a': 1, 'b': 2}\n" +"Are they the same object? False\n" +"d1 after: {'a': 1, 'b': 2}\n" +"d2 after: {'a': 1, 'b': 2, 'c': 3}" + +#. https://futurecoder.io/course/#CopyingDictionaries +#. +#. # __code0__: +#. __program_indented__ +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.__program_indented__ +msgid "pages.CopyingDictionaries.steps.shared_references.text" +msgstr "" +"Remember how assigning one list variable to another (`list2 = list1`) made both names point to the *same* list? Dictionaries work the same way because they are also *mutable* (can be changed).\n" +"\n" +"Predict what the following code will print, then run it to see:\n" +"\n" +" __copyable__\n" +"__code0__" + +#. https://futurecoder.io/course/#CopyingDictionaries +msgid "pages.CopyingDictionaries.title" +msgstr "Copying Dictionaries" + #. https://futurecoder.io/course/#CreatingKeyValuePairs #. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise @@ -22318,7 +23311,8 @@ msgstr "" " {'dog': 5000000, 'box': 2}\n" "\n" "Note that `buy_quantity` should *modify* the dictionary that's passed in, and doesn't need to return anything.\n" -"You can assume that the user will enter a valid integer for the quantity." +"You can assume that the user will enter a valid integer for the quantity.\n" +"You can also assume that the user won't enter an item that's already in `quantities`." #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.dict_assignment_valid msgid "pages.CreatingKeyValuePairs.steps.dict_assignment_valid.output_prediction_choices.1" @@ -22373,7 +23367,7 @@ msgstr "" "some data will be lost.\n" "\n" "But there are many situations where you can be sure that the values in a dictionary *are* unique and that this\n" -"'inversion' makes sense. For example, we saw this code [earlier in the chapter](#UsingDictionariesInPractice):\n" +"'inversion' makes sense. For example, we saw this code [earlier in the chapter](#UsingDictionaries):\n" "\n" " __copyable__\n" " __no_auto_translate__\n" diff --git a/translations/locales/en/LC_MESSAGES/futurecoder.mo b/translations/locales/en/LC_MESSAGES/futurecoder.mo index 5b843e1d940c895c6dfe605d16bf2ddc52d054e0..14d74342357f6589a2158f7534cc816ef9345670 100644 GIT binary patch delta 32367 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 Date: Sat, 19 Jul 2025 14:42:10 +0200 Subject: [PATCH 04/16] Fix syntax highlighting of one code block --- core/chapters/c12_dictionaries.py | 4 +- core/utils.py | 2 +- translations/english.po | 253 ++++++++++++++++-- .../locales/en/LC_MESSAGES/futurecoder.mo | Bin 315580 -> 315192 bytes 4 files changed, 241 insertions(+), 18 deletions(-) diff --git a/core/chapters/c12_dictionaries.py b/core/chapters/c12_dictionaries.py index 0249df55..cf463336 100644 --- a/core/chapters/c12_dictionaries.py +++ b/core/chapters/c12_dictionaries.py @@ -872,7 +872,7 @@ class total_cost_per_item_exercise(ExerciseStep): def total_cost_per_item(quantities, prices): totals = {} for item in quantities: - ... = quantities[item] * prices[item] + ___ = quantities[item] * prices[item] return totals assert_equal( @@ -1288,4 +1288,4 @@ def generate_inputs(cls): Great! You now know why copying dictionaries is important (because they are mutable) and how to do it using `.copy()`. You've also practiced creating modified copies, which is a common and safe way to work with data without accidentally changing things elsewhere in your program. Next, we'll see how to check if a key exists *before* trying to use it, to avoid errors. - """ \ No newline at end of file + """ diff --git a/core/utils.py b/core/utils.py index d6a32817..709b9c2b 100644 --- a/core/utils.py +++ b/core/utils.py @@ -56,7 +56,7 @@ def clean_spaces(string): assert spaces <= {" ", "\n"}, (spaces, string) # In translation, special codes like `__copyable__` often get the wrong indentation. # They must be preceded by 0 or 4 spaces. - if re.search(r"^( {1,3}| {5,})_", string, re.MULTILINE): + if re.search(r"^( {1,3}| {5,})__[a-z]+", string, re.MULTILINE): qa_error("Incorrect indentation of code:\n" + string) return string diff --git a/translations/english.po b/translations/english.po index a32d52ed..0ca152f9 100644 --- a/translations/english.po +++ b/translations/english.po @@ -3521,6 +3521,26 @@ msgstr "'apfel'" #. #. ------ #. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.total_cost_per_item_exercise.text +#. +#. def total_cost_per_item(quantities, prices): +#. totals = {} +#. for item in quantities: +#. ___ = quantities[item] * prices[item] +#. return totals +#. +#. assert_equal( +#. total_cost_per_item({'apple': 2}, {'apple': 3, 'box': 5}), +#. {'apple': 6}, +#. ) +#. +#. assert_equal( +#. total_cost_per_item({'dog': 5000000, 'box': 2}, {'dog': 100, 'box': 5}), +#. {'dog': 500000000, 'box': 10}, +#. ) +#. +#. ------ +#. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.DictionaryKeysAndValues.steps.cleanup_shopping_cart.text #. #. def total_cost(quantities, prices): @@ -3907,6 +3927,26 @@ msgstr "'book'" #. #. ------ #. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.total_cost_per_item_exercise.text +#. +#. def total_cost_per_item(quantities, prices): +#. totals = {} +#. for item in quantities: +#. ___ = quantities[item] * prices[item] +#. return totals +#. +#. assert_equal( +#. total_cost_per_item({'apple': 2}, {'apple': 3, 'box': 5}), +#. {'apple': 6}, +#. ) +#. +#. assert_equal( +#. total_cost_per_item({'dog': 5000000, 'box': 2}, {'dog': 100, 'box': 5}), +#. {'dog': 500000000, 'box': 10}, +#. ) +#. +#. ------ +#. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.DictionaryKeysAndValues.steps.cleanup_shopping_cart.text #. #. def total_cost(quantities, prices): @@ -4214,6 +4254,26 @@ msgstr "'def'" #. #. ------ #. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.total_cost_per_item_exercise.text +#. +#. def total_cost_per_item(quantities, prices): +#. totals = {} +#. for item in quantities: +#. ___ = quantities[item] * prices[item] +#. return totals +#. +#. assert_equal( +#. total_cost_per_item({'apple': 2}, {'apple': 3, 'box': 5}), +#. {'apple': 6}, +#. ) +#. +#. assert_equal( +#. total_cost_per_item({'dog': 5000000, 'box': 2}, {'dog': 100, 'box': 5}), +#. {'dog': 500000000, 'box': 10}, +#. ) +#. +#. ------ +#. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.DictionaryKeysAndValues.steps.cleanup_shopping_cart.text #. #. def total_cost(quantities, prices): @@ -5012,6 +5072,26 @@ msgstr "'you'" msgid "code_bits.Hello" msgstr "Hello" +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.total_cost_per_item_exercise.text +#. +#. def total_cost_per_item(quantities, prices): +#. totals = {} +#. for item in quantities: +#. ___ = quantities[item] * prices[item] +#. return totals +#. +#. assert_equal( +#. total_cost_per_item({'apple': 2}, {'apple': 3, 'box': 5}), +#. {'apple': 6}, +#. ) +#. +#. assert_equal( +#. total_cost_per_item({'dog': 5000000, 'box': 2}, {'dog': 100, 'box': 5}), +#. {'dog': 500000000, 'box': 10}, +#. ) +msgid "code_bits.___" +msgstr "___" + #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.making_copies.text #. #. __program_indented__ @@ -5622,6 +5702,26 @@ msgstr "all_numbers" #. #. ------ #. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.total_cost_per_item_exercise.text +#. +#. def total_cost_per_item(quantities, prices): +#. totals = {} +#. for item in quantities: +#. ___ = quantities[item] * prices[item] +#. return totals +#. +#. assert_equal( +#. total_cost_per_item({'apple': 2}, {'apple': 3, 'box': 5}), +#. {'apple': 6}, +#. ) +#. +#. assert_equal( +#. total_cost_per_item({'dog': 5000000, 'box': 2}, {'dog': 100, 'box': 5}), +#. {'dog': 500000000, 'box': 10}, +#. ) +#. +#. ------ +#. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.DictionaryKeysAndValues.steps.cleanup_shopping_cart.text #. #. def total_cost(quantities, prices): @@ -11928,6 +12028,26 @@ msgstr "is_valid_percentage" #. #. ------ #. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.total_cost_per_item_exercise.text +#. +#. def total_cost_per_item(quantities, prices): +#. totals = {} +#. for item in quantities: +#. ___ = quantities[item] * prices[item] +#. return totals +#. +#. assert_equal( +#. total_cost_per_item({'apple': 2}, {'apple': 3, 'box': 5}), +#. {'apple': 6}, +#. ) +#. +#. assert_equal( +#. total_cost_per_item({'dog': 5000000, 'box': 2}, {'dog': 100, 'box': 5}), +#. {'dog': 500000000, 'box': 10}, +#. ) +#. +#. ------ +#. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.DictionaryKeysAndValues.steps.cleanup_shopping_cart #. #. def total_cost(quantities, prices): @@ -15846,6 +15966,26 @@ msgstr "price" #. #. ------ #. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.total_cost_per_item_exercise.text +#. +#. def total_cost_per_item(quantities, prices): +#. totals = {} +#. for item in quantities: +#. ___ = quantities[item] * prices[item] +#. return totals +#. +#. assert_equal( +#. total_cost_per_item({'apple': 2}, {'apple': 3, 'box': 5}), +#. {'apple': 6}, +#. ) +#. +#. assert_equal( +#. total_cost_per_item({'dog': 5000000, 'box': 2}, {'dog': 100, 'box': 5}), +#. {'dog': 500000000, 'box': 10}, +#. ) +#. +#. ------ +#. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.DictionaryKeysAndValues.steps.cleanup_shopping_cart #. #. def total_cost(quantities, prices): @@ -16549,6 +16689,26 @@ msgstr "quadruple" #. #. ------ #. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.total_cost_per_item_exercise.text +#. +#. def total_cost_per_item(quantities, prices): +#. totals = {} +#. for item in quantities: +#. ___ = quantities[item] * prices[item] +#. return totals +#. +#. assert_equal( +#. total_cost_per_item({'apple': 2}, {'apple': 3, 'box': 5}), +#. {'apple': 6}, +#. ) +#. +#. assert_equal( +#. total_cost_per_item({'dog': 5000000, 'box': 2}, {'dog': 100, 'box': 5}), +#. {'dog': 500000000, 'box': 10}, +#. ) +#. +#. ------ +#. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.DictionaryKeysAndValues.steps.cleanup_shopping_cart #. #. def total_cost(quantities, prices): @@ -19861,6 +20021,26 @@ msgstr "total_cost" #. for item in quantities: #. totals[item] = quantities[item] * prices[item] #. return totals +#. +#. ------ +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.total_cost_per_item_exercise.text +#. +#. def total_cost_per_item(quantities, prices): +#. totals = {} +#. for item in quantities: +#. ___ = quantities[item] * prices[item] +#. return totals +#. +#. assert_equal( +#. total_cost_per_item({'apple': 2}, {'apple': 3, 'box': 5}), +#. {'apple': 6}, +#. ) +#. +#. assert_equal( +#. total_cost_per_item({'dog': 5000000, 'box': 2}, {'dog': 100, 'box': 5}), +#. {'dog': 500000000, 'box': 10}, +#. ) msgid "code_bits.total_cost_per_item" msgstr "total_cost_per_item" @@ -19871,6 +20051,26 @@ msgstr "total_cost_per_item" #. for item in quantities: #. totals[item] = quantities[item] * prices[item] #. return totals +#. +#. ------ +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.total_cost_per_item_exercise.text +#. +#. def total_cost_per_item(quantities, prices): +#. totals = {} +#. for item in quantities: +#. ___ = quantities[item] * prices[item] +#. return totals +#. +#. assert_equal( +#. total_cost_per_item({'apple': 2}, {'apple': 3, 'box': 5}), +#. {'apple': 6}, +#. ) +#. +#. assert_equal( +#. total_cost_per_item({'dog': 5000000, 'box': 2}, {'dog': 100, 'box': 5}), +#. {'dog': 500000000, 'box': 10}, +#. ) msgid "code_bits.totals" msgstr "totals" @@ -23646,6 +23846,43 @@ msgid "pages.CreatingKeyValuePairs.steps.total_cost_per_item_exercise.hints.6.te msgstr "The function should return the `totals` dictionary after the loop finishes." #. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. # __code0__: +#. def total_cost_per_item(quantities, prices): +#. totals = {} +#. for item in quantities: +#. ___ = quantities[item] * prices[item] +#. return totals +#. +#. assert_equal( +#. total_cost_per_item({'apple': 2}, {'apple': 3, 'box': 5}), +#. {'apple': 6}, +#. ) +#. +#. assert_equal( +#. total_cost_per_item({'dog': 5000000, 'box': 2}, {'dog': 100, 'box': 5}), +#. {'dog': 500000000, 'box': 10}, +#. ) +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.%27apple%27 +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.%27box%27 +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.%27dog%27 +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.___ +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.assert_equal +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.item +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.prices +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.quantities +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.total_cost_per_item +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.totals msgid "pages.CreatingKeyValuePairs.steps.total_cost_per_item_exercise.text" msgstr "" "Well done!\n" @@ -23655,21 +23892,7 @@ msgstr "" "which returns a new dictionary with the total cost for each item:\n" "\n" " __copyable__\n" -" def total_cost_per_item(quantities, prices):\n" -" totals = {}\n" -" for item in quantities:\n" -" ... = quantities[item] * prices[item]\n" -" return totals\n" -"\n" -" assert_equal(\n" -" total_cost_per_item({'apple': 2}, {'apple': 3, 'box': 5}),\n" -" {'apple': 6},\n" -" )\n" -"\n" -" assert_equal(\n" -" total_cost_per_item({'dog': 5000000, 'box': 2}, {'dog': 100, 'box': 5}),\n" -" {'dog': 500000000, 'box': 10},\n" -" )" +"__code0__" #. https://futurecoder.io/course/#CreatingKeyValuePairs msgid "pages.CreatingKeyValuePairs.title" diff --git a/translations/locales/en/LC_MESSAGES/futurecoder.mo b/translations/locales/en/LC_MESSAGES/futurecoder.mo index d171e0a94720e1c3adc35c3670f79fbb86cfbefa..49615ae46932b4a01563f0b1f2ea2ddbaaece42b 100644 GIT binary patch delta 27258 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 Lx5mciKlXnBO>LU@ From 07c644f39676fc2e78a584096f1d154c430eb456 Mon Sep 17 00:00:00 2001 From: Alex Hall Date: Sat, 19 Jul 2025 16:58:42 +0200 Subject: [PATCH 05/16] tweaks --- core/chapters/c12_dictionaries.py | 78 ++++++--- tests/golden_files/en/test_transcript.json | 51 ++++-- translations/english.po | 153 +++++++++++++----- .../locales/en/LC_MESSAGES/futurecoder.mo | Bin 315192 -> 317203 bytes 4 files changed, 205 insertions(+), 77 deletions(-) diff --git a/core/chapters/c12_dictionaries.py b/core/chapters/c12_dictionaries.py index cf463336..1eb14a61 100644 --- a/core/chapters/c12_dictionaries.py +++ b/core/chapters/c12_dictionaries.py @@ -687,6 +687,16 @@ def program(self): cart.append('box') print(cart) + predicted_output_choices = [ + "[]", + "['dog']", + "['box']", + "['dog', 'box']", + "['box', 'dog']", + "['dog', 'dog']", + "['box', 'box']", + ] + class list_assign_reminder(VerbatimStep): """ Pretty simple. We can also change the value at an index, replacing it with a different one: @@ -694,17 +704,24 @@ class list_assign_reminder(VerbatimStep): __copyable__ __program_indented__ """ - predicted_output_choices = [ - "['dog', 'box']", - "['box', 'cat']", - "['dog', 'cat']", - ] def program(self): cart = ['dog', 'cat'] cart[1] = 'box' print(cart) + predicted_output_choices = [ + "['box']", + "['dog', 'cat']", + "['box', 'dog']", + "['box', 'cat']", + "['dog', 'box']", + "['cat', 'box']", + "['box', 'dog', 'cat']", + "['dog', 'box', 'cat']", + "['dog', 'cat', 'box']", + ] + class list_assign_invalid(VerbatimStep): """ What if we used that idea to create our list in the first place? @@ -713,7 +730,6 @@ class list_assign_invalid(VerbatimStep): __copyable__ __program_indented__ """ - correct_output = "Error" # This program raises an IndexError def program(self): cart = [] @@ -721,34 +737,44 @@ def program(self): cart[1] = 'box' print(cart) + predicted_output_choices = [ + "[]", + "['dog']", + "['box']", + "['dog', 'box']", + "['box', 'dog']", + "['dog', 'dog']", + "['box', 'box']", + ] + + correct_output = "Error" + class dict_assignment_valid(VerbatimStep): """ Sorry, that's not allowed. For lists, subscript assignment only works for existing valid indices. But that's not true for dictionaries! Try this: - __copyable__ __program_indented__ Note that `{}` means an empty dictionary, i.e. a dictionary with no key-value pairs. This is similar to `[]` meaning an empty list or `""` meaning an empty string. """ predicted_output_choices = [ - "{}", - "{'dog': 5000000}", - "{'box': 2}", - "{'dog': 5000000, 'box': 2}", - "{'box': 2, 'dog': 5000000}", # Order might vary, though CPython 3.7+ preserves insertion order + "{'dog': 500, 'box': 2}", + "{'dog': 2, 'box': 500}", + "{2: 'dog', 500: 'box'}", + "{500: 'dog', 2: 'box'}", ] def program(self): quantities = {} - quantities['dog'] = 5000000 + quantities['dog'] = 500 quantities['box'] = 2 print(quantities) class buy_quantity_exercise(ExerciseStep): """ - That's exactly what we need. When the customer says they want 5 million boxes, + That's exactly what we need. Whether the customer says they want 500 or 5 million dogs, we can just put that information directly into our dictionary. So as an exercise, let's make a generic version of that. Write a function `buy_quantity(quantities)` which calls `input()` twice to get an item name and quantity from the user and assigns them in the `quantities` dictionary. Here's some starting code: @@ -774,19 +800,19 @@ def test(): Item: dog Quantity: - 5000000 - {'dog': 5000000} + 500 + {'dog': 500} Item: box Quantity: 2 - {'dog': 5000000, 'box': 2} + {'dog': 500, 'box': 2} Note that `buy_quantity` should *modify* the dictionary that's passed in, and doesn't need to return anything. You can assume that the user will enter a valid integer for the quantity. You can also assume that the user won't enter an item that's already in `quantities`. """ - requirements = "Your function should modify the `quantities` argument. It doesn't need to `return` or `print` anything." + requirements = "Your function should modify the `quantities` argument. It doesn't need to `return` anything." no_returns_stdout = True hints = """ @@ -832,20 +858,20 @@ def generate_inputs(cls): dict( quantities={}, stdin_input=[ - "dog", "5000000", + "dog", "500", ] ), """\ Item: Quantity: - -{'dog': 5000000} + +{'dog': 500} """ ), ( dict( - quantities={'dog': 5000000}, + quantities={'dog': 500}, stdin_input=[ "box", "2", ] @@ -855,7 +881,7 @@ def generate_inputs(cls): Quantity: -{'dog': 5000000, 'box': 2} +{'dog': 500, 'box': 2} """ ), ] @@ -881,8 +907,8 @@ def total_cost_per_item(quantities, prices): ) assert_equal( - total_cost_per_item({'dog': 5000000, 'box': 2}, {'dog': 100, 'box': 5}), - {'dog': 500000000, 'box': 10}, + total_cost_per_item({'dog': 500, 'box': 2}, {'dog': 100, 'box': 5}), + {'dog': 50000, 'box': 10}, ) """ hints = """ @@ -905,7 +931,7 @@ def total_cost_per_item(quantities: Dict[str, int], prices: Dict[str, int]): tests = [ (({'apple': 2}, {'apple': 3, 'box': 5}), {'apple': 6}), - (({'dog': 5000000, 'box': 2}, {'dog': 100, 'box': 5}), {'dog': 500000000, 'box': 10}), + (({'dog': 500, 'box': 2}, {'dog': 100, 'box': 5}), {'dog': 50000, 'box': 10}), (({'pen': 5, 'pencil': 10}, {'pen': 1, 'pencil': 0.5, 'eraser': 2}), {'pen': 5, 'pencil': 5.0}), (({}, {'apple': 1}), {}), ] diff --git a/tests/golden_files/en/test_transcript.json b/tests/golden_files/en/test_transcript.json index 99b77e70..e3497114 100644 --- a/tests/golden_files/en/test_transcript.json +++ b/tests/golden_files/en/test_transcript.json @@ -7240,6 +7240,19 @@ ], "response": { "passed": true, + "prediction": { + "answer": "['dog', 'box']", + "choices": [ + "[]", + "['dog']", + "['box']", + "['dog', 'box']", + "['box', 'dog']", + "['dog', 'dog']", + "['box', 'box']", + "Error" + ] + }, "result": [ { "text": "['dog', 'box']\n", @@ -7262,9 +7275,15 @@ "prediction": { "answer": "['dog', 'box']", "choices": [ - "['dog', 'box']", - "['box', 'cat']", + "['box']", "['dog', 'cat']", + "['box', 'dog']", + "['box', 'cat']", + "['dog', 'box']", + "['cat', 'box']", + "['box', 'dog', 'cat']", + "['dog', 'box', 'cat']", + "['dog', 'cat', 'box']", "Error" ] }, @@ -7288,6 +7307,19 @@ ], "response": { "passed": true, + "prediction": { + "answer": "Error", + "choices": [ + "[]", + "['dog']", + "['box']", + "['dog', 'box']", + "['box', 'dog']", + "['dog', 'dog']", + "['box', 'box']", + "Error" + ] + }, "result": [ { "data": [ @@ -7344,26 +7376,25 @@ "page": "Creating Key-Value Pairs", "program": [ "quantities = {}", - "quantities['dog'] = 5000000", + "quantities['dog'] = 500", "quantities['box'] = 2", "print(quantities)" ], "response": { "passed": true, "prediction": { - "answer": "{'dog': 5000000, 'box': 2}", + "answer": "{'dog': 500, 'box': 2}", "choices": [ - "{}", - "{'dog': 5000000}", - "{'box': 2}", - "{'dog': 5000000, 'box': 2}", - "{'box': 2, 'dog': 5000000}", + "{'dog': 500, 'box': 2}", + "{'dog': 2, 'box': 500}", + "{2: 'dog', 500: 'box'}", + "{500: 'dog', 2: 'box'}", "Error" ] }, "result": [ { - "text": "{'dog': 5000000, 'box': 2}\n", + "text": "{'dog': 500, 'box': 2}\n", "type": "stdout" } ] diff --git a/translations/english.po b/translations/english.po index 0ca152f9..0583eb6d 100644 --- a/translations/english.po +++ b/translations/english.po @@ -3535,8 +3535,8 @@ msgstr "'apfel'" #. ) #. #. assert_equal( -#. total_cost_per_item({'dog': 5000000, 'box': 2}, {'dog': 100, 'box': 5}), -#. {'dog': 500000000, 'box': 10}, +#. total_cost_per_item({'dog': 500, 'box': 2}, {'dog': 100, 'box': 5}), +#. {'dog': 50000, 'box': 10}, #. ) #. #. ------ @@ -3868,7 +3868,7 @@ msgstr "'book'" #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.dict_assignment_valid #. #. quantities = {} -#. quantities['dog'] = 5000000 +#. quantities['dog'] = 500 #. quantities['box'] = 2 #. print(quantities) #. @@ -3941,8 +3941,8 @@ msgstr "'book'" #. ) #. #. assert_equal( -#. total_cost_per_item({'dog': 5000000, 'box': 2}, {'dog': 100, 'box': 5}), -#. {'dog': 500000000, 'box': 10}, +#. total_cost_per_item({'dog': 500, 'box': 2}, {'dog': 100, 'box': 5}), +#. {'dog': 50000, 'box': 10}, #. ) #. #. ------ @@ -4222,7 +4222,7 @@ msgstr "'def'" #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.dict_assignment_valid #. #. quantities = {} -#. quantities['dog'] = 5000000 +#. quantities['dog'] = 500 #. quantities['box'] = 2 #. print(quantities) #. @@ -4268,8 +4268,8 @@ msgstr "'def'" #. ) #. #. assert_equal( -#. total_cost_per_item({'dog': 5000000, 'box': 2}, {'dog': 100, 'box': 5}), -#. {'dog': 500000000, 'box': 10}, +#. total_cost_per_item({'dog': 500, 'box': 2}, {'dog': 100, 'box': 5}), +#. {'dog': 50000, 'box': 10}, #. ) #. #. ------ @@ -5086,8 +5086,8 @@ msgstr "Hello" #. ) #. #. assert_equal( -#. total_cost_per_item({'dog': 5000000, 'box': 2}, {'dog': 100, 'box': 5}), -#. {'dog': 500000000, 'box': 10}, +#. total_cost_per_item({'dog': 500, 'box': 2}, {'dog': 100, 'box': 5}), +#. {'dog': 50000, 'box': 10}, #. ) msgid "code_bits.___" msgstr "___" @@ -5716,8 +5716,8 @@ msgstr "all_numbers" #. ) #. #. assert_equal( -#. total_cost_per_item({'dog': 5000000, 'box': 2}, {'dog': 100, 'box': 5}), -#. {'dog': 500000000, 'box': 10}, +#. total_cost_per_item({'dog': 500, 'box': 2}, {'dog': 100, 'box': 5}), +#. {'dog': 50000, 'box': 10}, #. ) #. #. ------ @@ -12042,8 +12042,8 @@ msgstr "is_valid_percentage" #. ) #. #. assert_equal( -#. total_cost_per_item({'dog': 5000000, 'box': 2}, {'dog': 100, 'box': 5}), -#. {'dog': 500000000, 'box': 10}, +#. total_cost_per_item({'dog': 500, 'box': 2}, {'dog': 100, 'box': 5}), +#. {'dog': 50000, 'box': 10}, #. ) #. #. ------ @@ -15980,8 +15980,8 @@ msgstr "price" #. ) #. #. assert_equal( -#. total_cost_per_item({'dog': 5000000, 'box': 2}, {'dog': 100, 'box': 5}), -#. {'dog': 500000000, 'box': 10}, +#. total_cost_per_item({'dog': 500, 'box': 2}, {'dog': 100, 'box': 5}), +#. {'dog': 50000, 'box': 10}, #. ) #. #. ------ @@ -16673,7 +16673,7 @@ msgstr "quadruple" #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.dict_assignment_valid #. #. quantities = {} -#. quantities['dog'] = 5000000 +#. quantities['dog'] = 500 #. quantities['box'] = 2 #. print(quantities) #. @@ -16703,8 +16703,8 @@ msgstr "quadruple" #. ) #. #. assert_equal( -#. total_cost_per_item({'dog': 5000000, 'box': 2}, {'dog': 100, 'box': 5}), -#. {'dog': 500000000, 'box': 10}, +#. total_cost_per_item({'dog': 500, 'box': 2}, {'dog': 100, 'box': 5}), +#. {'dog': 50000, 'box': 10}, #. ) #. #. ------ @@ -20038,8 +20038,8 @@ msgstr "total_cost" #. ) #. #. assert_equal( -#. total_cost_per_item({'dog': 5000000, 'box': 2}, {'dog': 100, 'box': 5}), -#. {'dog': 500000000, 'box': 10}, +#. total_cost_per_item({'dog': 500, 'box': 2}, {'dog': 100, 'box': 5}), +#. {'dog': 50000, 'box': 10}, #. ) msgid "code_bits.total_cost_per_item" msgstr "total_cost_per_item" @@ -20068,8 +20068,8 @@ msgstr "total_cost_per_item" #. ) #. #. assert_equal( -#. total_cost_per_item({'dog': 5000000, 'box': 2}, {'dog': 100, 'box': 5}), -#. {'dog': 500000000, 'box': 10}, +#. total_cost_per_item({'dog': 500, 'box': 2}, {'dog': 100, 'box': 5}), +#. {'dog': 50000, 'box': 10}, #. ) msgid "code_bits.totals" msgstr "totals" @@ -23456,7 +23456,7 @@ msgstr "What should be the key and what should be the value in this case?" #. https://futurecoder.io/course/#CreatingKeyValuePairs msgid "pages.CreatingKeyValuePairs.steps.buy_quantity_exercise.requirements" -msgstr "Your function should modify the `quantities` argument. It doesn't need to `return` or `print` anything." +msgstr "Your function should modify the `quantities` argument. It doesn't need to `return` anything." #. https://futurecoder.io/course/#CreatingKeyValuePairs #. @@ -23489,7 +23489,7 @@ msgstr "Your function should modify the `quantities` argument. It doesn't need t #. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.test msgid "pages.CreatingKeyValuePairs.steps.buy_quantity_exercise.text" msgstr "" -"That's exactly what we need. When the customer says they want 5 million boxes,\n" +"That's exactly what we need. Whether the customer says they want 500 or 5 million dogs,\n" "we can just put that information directly into our dictionary. So as an exercise, let's make a generic version of that.\n" "Write a function `buy_quantity(quantities)` which calls `input()` twice to get an item name and quantity from the user\n" "and assigns them in the `quantities` dictionary. Here's some starting code:\n" @@ -23502,33 +23502,33 @@ msgstr "" " Item:\n" " dog\n" " Quantity:\n" -" 5000000\n" -" {'dog': 5000000}\n" +" 500\n" +" {'dog': 500}\n" " Item:\n" " box\n" " Quantity:\n" " 2\n" -" {'dog': 5000000, 'box': 2}\n" +" {'dog': 500, 'box': 2}\n" "\n" "Note that `buy_quantity` should *modify* the dictionary that's passed in, and doesn't need to return anything.\n" "You can assume that the user will enter a valid integer for the quantity.\n" "You can also assume that the user won't enter an item that's already in `quantities`." +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.dict_assignment_valid +msgid "pages.CreatingKeyValuePairs.steps.dict_assignment_valid.output_prediction_choices.0" +msgstr "{'dog': 500, 'box': 2}" + #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.dict_assignment_valid msgid "pages.CreatingKeyValuePairs.steps.dict_assignment_valid.output_prediction_choices.1" -msgstr "{'dog': 5000000}" +msgstr "{'dog': 2, 'box': 500}" #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.dict_assignment_valid msgid "pages.CreatingKeyValuePairs.steps.dict_assignment_valid.output_prediction_choices.2" -msgstr "{'box': 2}" +msgstr "{2: 'dog', 500: 'box'}" #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.dict_assignment_valid msgid "pages.CreatingKeyValuePairs.steps.dict_assignment_valid.output_prediction_choices.3" -msgstr "{'dog': 5000000, 'box': 2}" - -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.dict_assignment_valid -msgid "pages.CreatingKeyValuePairs.steps.dict_assignment_valid.output_prediction_choices.4" -msgstr "{'box': 2, 'dog': 5000000}" +msgstr "{500: 'dog', 2: 'box'}" #. https://futurecoder.io/course/#CreatingKeyValuePairs #. @@ -23541,7 +23541,6 @@ msgstr "" "Sorry, that's not allowed. For lists, subscript assignment only works for existing valid indices.\n" "But that's not true for dictionaries! Try this:\n" "\n" -" __copyable__\n" "__code0__\n" "\n" "Note that `{}` means an empty dictionary, i.e. a dictionary with no key-value pairs.\n" @@ -23592,6 +23591,30 @@ msgstr "" "Otherwise it would be impossible to decrypt messages properly. If both `'h'` and `'j'` got replaced with `'q'`\n" "during encryption, there would be no way to know whether `'qpeef'` means `'hello'` or `'jello'`!" +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.list_append_reminder +msgid "pages.CreatingKeyValuePairs.steps.list_append_reminder.output_prediction_choices.1" +msgstr "['dog']" + +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.list_append_reminder +msgid "pages.CreatingKeyValuePairs.steps.list_append_reminder.output_prediction_choices.2" +msgstr "['box']" + +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.list_append_reminder +msgid "pages.CreatingKeyValuePairs.steps.list_append_reminder.output_prediction_choices.3" +msgstr "['dog', 'box']" + +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.list_append_reminder +msgid "pages.CreatingKeyValuePairs.steps.list_append_reminder.output_prediction_choices.4" +msgstr "['box', 'dog']" + +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.list_append_reminder +msgid "pages.CreatingKeyValuePairs.steps.list_append_reminder.output_prediction_choices.5" +msgstr "['dog', 'dog']" + +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.list_append_reminder +msgid "pages.CreatingKeyValuePairs.steps.list_append_reminder.output_prediction_choices.6" +msgstr "['box', 'box']" + #. https://futurecoder.io/course/#CreatingKeyValuePairs #. #. # __code0__: @@ -23607,6 +23630,30 @@ msgstr "" " __copyable__\n" "__code0__" +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.list_assign_invalid +msgid "pages.CreatingKeyValuePairs.steps.list_assign_invalid.output_prediction_choices.1" +msgstr "['dog']" + +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.list_assign_invalid +msgid "pages.CreatingKeyValuePairs.steps.list_assign_invalid.output_prediction_choices.2" +msgstr "['box']" + +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.list_assign_invalid +msgid "pages.CreatingKeyValuePairs.steps.list_assign_invalid.output_prediction_choices.3" +msgstr "['dog', 'box']" + +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.list_assign_invalid +msgid "pages.CreatingKeyValuePairs.steps.list_assign_invalid.output_prediction_choices.4" +msgstr "['box', 'dog']" + +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.list_assign_invalid +msgid "pages.CreatingKeyValuePairs.steps.list_assign_invalid.output_prediction_choices.5" +msgstr "['dog', 'dog']" + +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.list_assign_invalid +msgid "pages.CreatingKeyValuePairs.steps.list_assign_invalid.output_prediction_choices.6" +msgstr "['box', 'box']" + #. https://futurecoder.io/course/#CreatingKeyValuePairs #. #. # __code0__: @@ -23623,15 +23670,39 @@ msgstr "" #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.list_assign_reminder msgid "pages.CreatingKeyValuePairs.steps.list_assign_reminder.output_prediction_choices.0" -msgstr "['dog', 'box']" +msgstr "['box']" #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.list_assign_reminder msgid "pages.CreatingKeyValuePairs.steps.list_assign_reminder.output_prediction_choices.1" -msgstr "['box', 'cat']" +msgstr "['dog', 'cat']" #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.list_assign_reminder msgid "pages.CreatingKeyValuePairs.steps.list_assign_reminder.output_prediction_choices.2" -msgstr "['dog', 'cat']" +msgstr "['box', 'dog']" + +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.list_assign_reminder +msgid "pages.CreatingKeyValuePairs.steps.list_assign_reminder.output_prediction_choices.3" +msgstr "['box', 'cat']" + +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.list_assign_reminder +msgid "pages.CreatingKeyValuePairs.steps.list_assign_reminder.output_prediction_choices.4" +msgstr "['dog', 'box']" + +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.list_assign_reminder +msgid "pages.CreatingKeyValuePairs.steps.list_assign_reminder.output_prediction_choices.5" +msgstr "['cat', 'box']" + +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.list_assign_reminder +msgid "pages.CreatingKeyValuePairs.steps.list_assign_reminder.output_prediction_choices.6" +msgstr "['box', 'dog', 'cat']" + +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.list_assign_reminder +msgid "pages.CreatingKeyValuePairs.steps.list_assign_reminder.output_prediction_choices.7" +msgstr "['dog', 'box', 'cat']" + +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.list_assign_reminder +msgid "pages.CreatingKeyValuePairs.steps.list_assign_reminder.output_prediction_choices.8" +msgstr "['dog', 'cat', 'box']" #. https://futurecoder.io/course/#CreatingKeyValuePairs #. @@ -23860,8 +23931,8 @@ msgstr "The function should return the `totals` dictionary after the loop finish #. ) #. #. assert_equal( -#. total_cost_per_item({'dog': 5000000, 'box': 2}, {'dog': 100, 'box': 5}), -#. {'dog': 500000000, 'box': 10}, +#. total_cost_per_item({'dog': 500, 'box': 2}, {'dog': 100, 'box': 5}), +#. {'dog': 50000, 'box': 10}, #. ) #. #. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.%27apple%27 diff --git a/translations/locales/en/LC_MESSAGES/futurecoder.mo b/translations/locales/en/LC_MESSAGES/futurecoder.mo index 49615ae46932b4a01563f0b1f2ea2ddbaaece42b..8b13e2c3bcdd247941c5cd8e0d428ce8bb88ffdd 100644 GIT binary patch delta 28286 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 From 45c8ddad77e4a652a3f94f02e3ae0abdb2f4f74d Mon Sep 17 00:00:00 2001 From: Alex Hall Date: Sat, 19 Jul 2025 17:15:17 +0200 Subject: [PATCH 06/16] simplify buy_quantity_exercise --- core/chapters/c12_dictionaries.py | 110 +++---- tests/golden_files/en/test_transcript.json | 8 +- tests/test_steps.py | 4 + translations/english.po | 302 +++++++----------- .../locales/en/LC_MESSAGES/futurecoder.mo | Bin 317203 -> 315682 bytes 5 files changed, 165 insertions(+), 259 deletions(-) diff --git a/core/chapters/c12_dictionaries.py b/core/chapters/c12_dictionaries.py index 1eb14a61..52976934 100644 --- a/core/chapters/c12_dictionaries.py +++ b/core/chapters/c12_dictionaries.py @@ -776,113 +776,93 @@ class buy_quantity_exercise(ExerciseStep): """ That's exactly what we need. Whether the customer says they want 500 or 5 million dogs, we can just put that information directly into our dictionary. So as an exercise, let's make a generic version of that. - Write a function `buy_quantity(quantities)` which calls `input()` twice to get an item name and quantity from the user - and assigns them in the `quantities` dictionary. Here's some starting code: + Write a function `buy_quantity(quantities, item, quantity)` which adds a new key-value pair to the `quantities` dictionary. + Here's some starting code: __copyable__ - def buy_quantity(quantities): - print('Item:') - item = input() - print('Quantity:') + def buy_quantity(quantities, item, quantity): ... def test(): quantities = {} - buy_quantity(quantities) - print(quantities) - buy_quantity(quantities) - print(quantities) + buy_quantity(quantities, 'dog', 500) + assert_equal(quantities, {'dog': 500}) + buy_quantity(quantities, 'box', 2) + assert_equal(quantities, {'dog': 500, 'box': 2}) test() - and an example of how a session should look: - - Item: - dog - Quantity: - 500 - {'dog': 500} - Item: - box - Quantity: - 2 - {'dog': 500, 'box': 2} - - Note that `buy_quantity` should *modify* the dictionary that's passed in, and doesn't need to return anything. - You can assume that the user will enter a valid integer for the quantity. - You can also assume that the user won't enter an item that's already in `quantities`. + Note that `buy_quantity` should *modify* the dictionary that's passed in, and doesn't need to `return` or `print` anything. + You can assume that `item` isn't already in `quantities`. """ - requirements = "Your function should modify the `quantities` argument. It doesn't need to `return` anything." - no_returns_stdout = True + requirements = "Your function should modify the `quantities` argument. It doesn't need to `return` or `print` anything." hints = """ - The function needs to get two inputs from the user: the item name and the quantity. - The item name is already stored in the `item` variable. You need to get the quantity similarly. - Remember that `input()` returns a string. The quantity needs to be stored as a number (`int`). - How do you convert a string to an integer? - Once you have the `item` (string) and the quantity (integer), you need to add them to the `quantities` dictionary. - Use the dictionary assignment syntax you just learned: `dictionary[key] = value`. - What should be the key and what should be the value in this case? + TODO """ + no_returns_stdout = True # because the solution doesn't return anything, returning stdout would be assumed + def solution(self): - def buy_quantity(quantities: Dict[str, int]): - print('Item:') - item = input() - print('Quantity:') - quantity_str = input() - quantities[item] = int(quantity_str) + def buy_quantity(quantities: Dict[str, int], item: str, quantity: int): + quantities[item] = quantity return buy_quantity @classmethod def wrap_solution(cls, func): - @returns_stdout @wrap_solution(func) def wrapper(**kwargs): quantities_name = t.get_code_bit("quantities") quantities = kwargs[quantities_name] = deepcopy(kwargs[quantities_name]) func(**kwargs) - print(quantities) + return quantities return wrapper @classmethod def generate_inputs(cls): + quantities = generate_dict(str, int) + item = generate_string() + quantities.pop(item, None) + quantity = random.randint(1, 100) return { - "stdin_input": [generate_string(5), str(random.randint(1, 10))], - "quantities": generate_dict(str, int), + "quantities": quantities, + "item": item, + "quantity": quantity, } tests = [ ( dict( quantities={}, - stdin_input=[ - "dog", "500", - ] + item='dog', + quantity=500 ), - """\ -Item: - -Quantity: - -{'dog': 500} - """ + {'dog': 500} ), ( dict( quantities={'dog': 500}, - stdin_input=[ - "box", "2", - ] + item='box', + quantity=2 + ), + {'dog': 500, 'box': 2} + ), + ( + dict( + quantities={'apple': 3, 'banana': 5}, + item='orange', + quantity=10 + ), + {'apple': 3, 'banana': 5, 'orange': 10} + ), + ( + dict( + quantities={}, + item='cat', + quantity=1 ), - """\ -Item: - -Quantity: - -{'dog': 500, 'box': 2} - """ + {'cat': 1} ), ] diff --git a/tests/golden_files/en/test_transcript.json b/tests/golden_files/en/test_transcript.json index e3497114..f9ed18d1 100644 --- a/tests/golden_files/en/test_transcript.json +++ b/tests/golden_files/en/test_transcript.json @@ -7405,12 +7405,8 @@ "get_solution": "program", "page": "Creating Key-Value Pairs", "program": [ - "def buy_quantity(quantities):", - " print('Item:')", - " item = input()", - " print('Quantity:')", - " quantity_str = input()", - " quantities[item] = int(quantity_str)" + "def buy_quantity(quantities, item, quantity):", + " quantities[item] = quantity" ], "response": { "passed": true, diff --git a/tests/test_steps.py b/tests/test_steps.py index 7f1443ad..12d0a4da 100644 --- a/tests/test_steps.py +++ b/tests/test_steps.py @@ -97,6 +97,10 @@ def normalise_response(response, is_message, substep): message_sections = response.pop("message_sections") if not is_message: + if message_sections: + for section in message_sections: + for message in section['messages']: + print(message) assert not message_sections else: section = message_sections[0] diff --git a/translations/english.po b/translations/english.po index 0583eb6d..9ad7d0e3 100644 --- a/translations/english.po +++ b/translations/english.po @@ -2672,36 +2672,6 @@ msgstr "'Hello there'" msgid "code_bits.'Hello'" msgstr "'Hello'" -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise -#. -#. def buy_quantity(quantities): -#. print('Item:') -#. item = input() -#. print('Quantity:') -#. quantity_str = input() -#. quantities[item] = int(quantity_str) -#. -#. ------ -#. -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise.text -#. -#. def buy_quantity(quantities): -#. print('Item:') -#. item = input() -#. print('Quantity:') -#. ... -#. -#. def test(): -#. quantities = {} -#. buy_quantity(quantities) -#. print(quantities) -#. buy_quantity(quantities) -#. print(quantities) -#. -#. test() -msgid "code_bits.'Item:'" -msgstr "'Item:'" - #. https://poeditor.com/projects/view_terms?id=490053&search=pages.IfAndElse.steps.first_if_else #. #. condition = True @@ -2762,36 +2732,6 @@ msgstr "'One more exercise, and then you can relax.'" msgid "code_bits.'Python'" msgstr "'Python'" -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise -#. -#. def buy_quantity(quantities): -#. print('Item:') -#. item = input() -#. print('Quantity:') -#. quantity_str = input() -#. quantities[item] = int(quantity_str) -#. -#. ------ -#. -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise.text -#. -#. def buy_quantity(quantities): -#. print('Item:') -#. item = input() -#. print('Quantity:') -#. ... -#. -#. def test(): -#. quantities = {} -#. buy_quantity(quantities) -#. print(quantities) -#. buy_quantity(quantities) -#. print(quantities) -#. -#. test() -msgid "code_bits.'Quantity:'" -msgstr "'Quantity:'" - #. https://poeditor.com/projects/view_terms?id=490053&search=pages.Types.steps.fixing_type_errors_with_conversion #. #. number = '1' @@ -3865,6 +3805,22 @@ msgstr "'boite'" msgid "code_bits.'book'" msgstr "'book'" +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise.text +#. +#. def buy_quantity(quantities, item, quantity): +#. ... +#. +#. def test(): +#. quantities = {} +#. buy_quantity(quantities, 'dog', 500) +#. assert_equal(quantities, {'dog': 500}) +#. buy_quantity(quantities, 'box', 2) +#. assert_equal(quantities, {'dog': 500, 'box': 2}) +#. +#. test() +#. +#. ------ +#. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.dict_assignment_valid #. #. quantities = {} @@ -4219,6 +4175,22 @@ msgstr "'de'" msgid "code_bits.'def'" msgstr "'def'" +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise.text +#. +#. def buy_quantity(quantities, item, quantity): +#. ... +#. +#. def test(): +#. quantities = {} +#. buy_quantity(quantities, 'dog', 500) +#. assert_equal(quantities, {'dog': 500}) +#. buy_quantity(quantities, 'box', 2) +#. assert_equal(quantities, {'dog': 500, 'box': 2}) +#. +#. test() +#. +#. ------ +#. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.dict_assignment_valid #. #. quantities = {} @@ -5675,6 +5647,22 @@ msgstr "all_numbers" #. #. ------ #. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise.text +#. +#. def buy_quantity(quantities, item, quantity): +#. ... +#. +#. def test(): +#. quantities = {} +#. buy_quantity(quantities, 'dog', 500) +#. assert_equal(quantities, {'dog': 500}) +#. buy_quantity(quantities, 'box', 2) +#. assert_equal(quantities, {'dog': 500, 'box': 2}) +#. +#. test() +#. +#. ------ +#. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise.text #. #. def make_english_to_german(english_to_french, french_to_german): @@ -7289,29 +7277,22 @@ msgstr "board_size" #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise #. -#. def buy_quantity(quantities): -#. print('Item:') -#. item = input() -#. print('Quantity:') -#. quantity_str = input() -#. quantities[item] = int(quantity_str) +#. def buy_quantity(quantities, item, quantity): +#. quantities[item] = quantity #. #. ------ #. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise.text #. -#. def buy_quantity(quantities): -#. print('Item:') -#. item = input() -#. print('Quantity:') +#. def buy_quantity(quantities, item, quantity): #. ... #. #. def test(): #. quantities = {} -#. buy_quantity(quantities) -#. print(quantities) -#. buy_quantity(quantities) -#. print(quantities) +#. buy_quantity(quantities, 'dog', 500) +#. assert_equal(quantities, {'dog': 500}) +#. buy_quantity(quantities, 'box', 2) +#. assert_equal(quantities, {'dog': 500, 'box': 2}) #. #. test() msgid "code_bits.buy_quantity" @@ -11990,29 +11971,22 @@ msgstr "is_valid_percentage" #. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise #. -#. def buy_quantity(quantities): -#. print('Item:') -#. item = input() -#. print('Quantity:') -#. quantity_str = input() -#. quantities[item] = int(quantity_str) +#. def buy_quantity(quantities, item, quantity): +#. quantities[item] = quantity #. #. ------ #. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise.text #. -#. def buy_quantity(quantities): -#. print('Item:') -#. item = input() -#. print('Quantity:') +#. def buy_quantity(quantities, item, quantity): #. ... #. #. def test(): #. quantities = {} -#. buy_quantity(quantities) -#. print(quantities) -#. buy_quantity(quantities) -#. print(quantities) +#. buy_quantity(quantities, 'dog', 500) +#. assert_equal(quantities, {'dog': 500}) +#. buy_quantity(quantities, 'box', 2) +#. assert_equal(quantities, {'dog': 500, 'box': 2}) #. #. test() #. @@ -16642,29 +16616,22 @@ msgstr "quadruple" #. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise #. -#. def buy_quantity(quantities): -#. print('Item:') -#. item = input() -#. print('Quantity:') -#. quantity_str = input() -#. quantities[item] = int(quantity_str) +#. def buy_quantity(quantities, item, quantity): +#. quantities[item] = quantity #. #. ------ #. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise.text #. -#. def buy_quantity(quantities): -#. print('Item:') -#. item = input() -#. print('Quantity:') +#. def buy_quantity(quantities, item, quantity): #. ... #. #. def test(): #. quantities = {} -#. buy_quantity(quantities) -#. print(quantities) -#. buy_quantity(quantities) -#. print(quantities) +#. buy_quantity(quantities, 'dog', 500) +#. assert_equal(quantities, {'dog': 500}) +#. buy_quantity(quantities, 'box', 2) +#. assert_equal(quantities, {'dog': 500, 'box': 2}) #. #. test() #. @@ -16816,6 +16783,29 @@ msgstr "quantities" #. #. ------ #. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise +#. +#. def buy_quantity(quantities, item, quantity): +#. quantities[item] = quantity +#. +#. ------ +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise.text +#. +#. def buy_quantity(quantities, item, quantity): +#. ... +#. +#. def test(): +#. quantities = {} +#. buy_quantity(quantities, 'dog', 500) +#. assert_equal(quantities, {'dog': 500}) +#. buy_quantity(quantities, 'box', 2) +#. assert_equal(quantities, {'dog': 500, 'box': 2}) +#. +#. test() +#. +#. ------ +#. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.DictionaryKeysAndValues.steps.cleanup_shopping_cart #. #. def total_cost(quantities, prices): @@ -16881,17 +16871,6 @@ msgstr "quantities" msgid "code_bits.quantity" msgstr "quantity" -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise -#. -#. def buy_quantity(quantities): -#. print('Item:') -#. item = input() -#. print('Quantity:') -#. quantity_str = input() -#. quantities[item] = int(quantity_str) -msgid "code_bits.quantity_str" -msgstr "quantity_str" - #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.positive_stock_exercise #. #. def positive_stock(stock): @@ -19538,18 +19517,15 @@ msgstr "temp" #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise.text #. -#. def buy_quantity(quantities): -#. print('Item:') -#. item = input() -#. print('Quantity:') +#. def buy_quantity(quantities, item, quantity): #. ... #. #. def test(): #. quantities = {} -#. buy_quantity(quantities) -#. print(quantities) -#. buy_quantity(quantities) -#. print(quantities) +#. buy_quantity(quantities, 'dog', 500) +#. assert_equal(quantities, {'dog': 500}) +#. buy_quantity(quantities, 'box', 2) +#. assert_equal(quantities, {'dog': 500, 'box': 2}) #. #. test() #. @@ -23415,70 +23391,32 @@ msgstr "Copying Dictionaries" #. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise msgid "pages.CreatingKeyValuePairs.steps.buy_quantity_exercise.hints.0.text" -msgstr "The function needs to get two inputs from the user: the item name and the quantity." - -#. https://futurecoder.io/course/#CreatingKeyValuePairs -#. -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise -msgid "pages.CreatingKeyValuePairs.steps.buy_quantity_exercise.hints.1.text" -msgstr "The item name is already stored in the `item` variable. You need to get the quantity similarly." - -#. https://futurecoder.io/course/#CreatingKeyValuePairs -#. -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise -msgid "pages.CreatingKeyValuePairs.steps.buy_quantity_exercise.hints.2.text" -msgstr "Remember that `input()` returns a string. The quantity needs to be stored as a number (`int`)." - -#. https://futurecoder.io/course/#CreatingKeyValuePairs -#. -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise -msgid "pages.CreatingKeyValuePairs.steps.buy_quantity_exercise.hints.3.text" -msgstr "How do you convert a string to an integer?" - -#. https://futurecoder.io/course/#CreatingKeyValuePairs -#. -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise -msgid "pages.CreatingKeyValuePairs.steps.buy_quantity_exercise.hints.4.text" -msgstr "" -"Once you have the `item` (string) and the quantity (integer), you need to add them to the `quantities` dictionary." - -#. https://futurecoder.io/course/#CreatingKeyValuePairs -#. -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise -msgid "pages.CreatingKeyValuePairs.steps.buy_quantity_exercise.hints.5.text" -msgstr "Use the dictionary assignment syntax you just learned: `dictionary[key] = value`." - -#. https://futurecoder.io/course/#CreatingKeyValuePairs -#. -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise -msgid "pages.CreatingKeyValuePairs.steps.buy_quantity_exercise.hints.6.text" -msgstr "What should be the key and what should be the value in this case?" +msgstr "TODO" #. https://futurecoder.io/course/#CreatingKeyValuePairs msgid "pages.CreatingKeyValuePairs.steps.buy_quantity_exercise.requirements" -msgstr "Your function should modify the `quantities` argument. It doesn't need to `return` anything." +msgstr "Your function should modify the `quantities` argument. It doesn't need to `return` or `print` anything." #. https://futurecoder.io/course/#CreatingKeyValuePairs #. #. # __code0__: -#. def buy_quantity(quantities): -#. print('Item:') -#. item = input() -#. print('Quantity:') +#. def buy_quantity(quantities, item, quantity): #. ... #. #. def test(): #. quantities = {} -#. buy_quantity(quantities) -#. print(quantities) -#. buy_quantity(quantities) -#. print(quantities) +#. buy_quantity(quantities, 'dog', 500) +#. assert_equal(quantities, {'dog': 500}) +#. buy_quantity(quantities, 'box', 2) +#. assert_equal(quantities, {'dog': 500, 'box': 2}) #. #. test() #. -#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.%27Item%3A%27 +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.%27box%27 +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.%27dog%27 #. -#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.%27Quantity%3A%27 +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.assert_equal #. #. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.buy_quantity #. @@ -23486,33 +23424,21 @@ msgstr "Your function should modify the `quantities` argument. It doesn't need t #. #. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.quantities #. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.quantity +#. #. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.test msgid "pages.CreatingKeyValuePairs.steps.buy_quantity_exercise.text" msgstr "" "That's exactly what we need. Whether the customer says they want 500 or 5 million dogs,\n" "we can just put that information directly into our dictionary. So as an exercise, let's make a generic version of that.\n" -"Write a function `buy_quantity(quantities)` which calls `input()` twice to get an item name and quantity from the user\n" -"and assigns them in the `quantities` dictionary. Here's some starting code:\n" +"Write a function `buy_quantity(quantities, item, quantity)` which adds a new key-value pair to the `quantities` dictionary.\n" +"Here's some starting code:\n" "\n" " __copyable__\n" "__code0__\n" "\n" -"and an example of how a session should look:\n" -"\n" -" Item:\n" -" dog\n" -" Quantity:\n" -" 500\n" -" {'dog': 500}\n" -" Item:\n" -" box\n" -" Quantity:\n" -" 2\n" -" {'dog': 500, 'box': 2}\n" -"\n" -"Note that `buy_quantity` should *modify* the dictionary that's passed in, and doesn't need to return anything.\n" -"You can assume that the user will enter a valid integer for the quantity.\n" -"You can also assume that the user won't enter an item that's already in `quantities`." +"Note that `buy_quantity` should *modify* the dictionary that's passed in, and doesn't need to `return` or `print` anything.\n" +"You can assume that `item` isn't already in `quantities`." #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.dict_assignment_valid msgid "pages.CreatingKeyValuePairs.steps.dict_assignment_valid.output_prediction_choices.0" diff --git a/translations/locales/en/LC_MESSAGES/futurecoder.mo b/translations/locales/en/LC_MESSAGES/futurecoder.mo index 8b13e2c3bcdd247941c5cd8e0d428ce8bb88ffdd..daf6c3805f6ca25125d5e9112d2749b2bbf3c4be 100644 GIT binary patch delta 27548 zcmYM+2ecH$x9{;jGeee~<2jOZPNL+TGYFD%&QZ}pB!hyIlLQqM1wjyypa>|aAW;!S z38MZ*Ob94JxZhvz{nmTy-Sw$mRb5qGT~*z4@ZJTRGp}2hIsSd7*rI^{wpMPPJAEL@Nrbb*D)I=3<-h^n8PiG%CCm$v9;&-#EitFQ0+~{LilQEJO~bv&;{2p zGu}lFB;8OO*rTY9tGLZjIZPfJ{h6O=g`VR__ zP{;kT7(RpP@D0?!wxh}qp=RnE)SdqBakAkS=SI~pkE&nC;|{2f`+5Fk)C@1gxDxM> z(48Feg0J1*JwN#fpK8=h6hqxX4b-!2jo~Bo{MlHO{8g9^zw`3zSe!UA(%LIEGKhyA z*C0b9ZiVTwkH=#$Bk@dBhs)hfsCxTR*PTG!$W<@D?{WH3mR|%jQeG1^pw?I!dyHcK zGm%(AhMwU@)Cdn^Y5W~Eb$LhgKUf7bV0$cu{ZI`rMAcjG`TJ1={2kTd1I&eK$CyP? zGg&uILKU7wUC`ZUjuvBP+=A-x5NfK=x__Vsnqr*g=R^ IC_GsPa~*>w9@T7U?%0%pjqP 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 O|3r7bI5;+a@c#jJ_LL9+ delta 28606 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 Date: Sat, 19 Jul 2025 18:16:11 +0200 Subject: [PATCH 07/16] tweaks --- core/chapters/c12_dictionaries.py | 47 +++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 11 deletions(-) diff --git a/core/chapters/c12_dictionaries.py b/core/chapters/c12_dictionaries.py index 52976934..48f5c73e 100644 --- a/core/chapters/c12_dictionaries.py +++ b/core/chapters/c12_dictionaries.py @@ -821,15 +821,9 @@ def wrapper(**kwargs): @classmethod def generate_inputs(cls): - quantities = generate_dict(str, int) - item = generate_string() - quantities.pop(item, None) - quantity = random.randint(1, 100) - return { - "quantities": quantities, - "item": item, - "quantity": quantity, - } + result = super().generate_inputs() + result["quantities"].pop(result["item"], None) # ensure item is not already in quantities + return result tests = [ ( @@ -866,11 +860,42 @@ def generate_inputs(cls): ), ] + class buy_quantity_input_test(VerbatimStep): + """ + Well done! Try it out interactively: + + __copyable__ + __program_indented__ + + Note the `int(input())` part, because `input()` returns a string, and `quantity` should be an integer + (a whole number). This'll break if you enter something that isn't a number, but that's OK for now. + """ + + def program(self): + def buy_quantity(quantities, item, quantity): + quantities[item] = quantity + + def test(): + quantities = {} + for _ in range(3): + print('What would you like to buy?') + item = input() + + print('How many?') + quantity = int(input()) + + buy_quantity(quantities, item, quantity) + + print("OK, here's your cart so far:") + print(quantities) + + test() + class total_cost_per_item_exercise(ExerciseStep): """ - Well done! + Thanks for shopping with us! Let's see how much you just spent on each item. - Next exercise: earlier we defined a function `total_cost(quantities, prices)` which returned a single number + Earlier we defined a function `total_cost(quantities, prices)` which returned a single number with a grand total of all the items in the cart. Now let's make a function `total_cost_per_item(quantities, prices)` which returns a new dictionary with the total cost for each item: From aea0632b219c00245530783333a36e7d995d026c Mon Sep 17 00:00:00 2001 From: Alex Hall Date: Sat, 19 Jul 2025 18:19:34 +0200 Subject: [PATCH 08/16] tweaks --- core/chapters/c12_dictionaries.py | 6 +- tests/golden_files/en/test_transcript.json | 106 +++++++++ translations/english.po | 210 +++++++++++++++++- .../locales/en/LC_MESSAGES/futurecoder.mo | Bin 315682 -> 316303 bytes 4 files changed, 318 insertions(+), 4 deletions(-) diff --git a/core/chapters/c12_dictionaries.py b/core/chapters/c12_dictionaries.py index 48f5c73e..d18608db 100644 --- a/core/chapters/c12_dictionaries.py +++ b/core/chapters/c12_dictionaries.py @@ -864,13 +864,15 @@ class buy_quantity_input_test(VerbatimStep): """ Well done! Try it out interactively: - __copyable__ - __program_indented__ + __copyable__ + __program_indented__ Note the `int(input())` part, because `input()` returns a string, and `quantity` should be an integer (a whole number). This'll break if you enter something that isn't a number, but that's OK for now. """ + stdin_input = ["apple", "3", "banana", "5", "cat", "2"] + def program(self): def buy_quantity(quantities, item, quantity): quantities[item] = quantity diff --git a/tests/golden_files/en/test_transcript.json b/tests/golden_files/en/test_transcript.json index f9ed18d1..3e130ecd 100644 --- a/tests/golden_files/en/test_transcript.json +++ b/tests/golden_files/en/test_transcript.json @@ -7414,6 +7414,112 @@ }, "step": "buy_quantity_exercise" }, + { + "get_solution": "program", + "page": "Creating Key-Value Pairs", + "program": [ + "def buy_quantity(quantities, item, quantity):", + " quantities[item] = quantity", + "", + "def test():", + " quantities = {}", + " for _ in range(3):", + " print('What would you like to buy?')", + " item = input()", + "", + " print('How many?')", + " quantity = int(input())", + "", + " buy_quantity(quantities, item, quantity)", + "", + " print(\"OK, here's your cart so far:\")", + " print(quantities)", + "", + "test()" + ], + "response": { + "passed": true, + "result": [ + { + "text": "What would you like to buy?\n", + "type": "stdout" + }, + { + "text": "", + "type": "input_prompt" + }, + { + "text": "\n", + "type": "stdout" + }, + { + "text": "How many?\n", + "type": "stdout" + }, + { + "text": "", + "type": "input_prompt" + }, + { + "text": "\n", + "type": "stdout" + }, + { + "text": "OK, here's your cart so far:\n{'apple': 3}\nWhat would you like to buy?\n", + "type": "stdout" + }, + { + "text": "", + "type": "input_prompt" + }, + { + "text": "\n", + "type": "stdout" + }, + { + "text": "How many?\n", + "type": "stdout" + }, + { + "text": "", + "type": "input_prompt" + }, + { + "text": "\n", + "type": "stdout" + }, + { + "text": "OK, here's your cart so far:\n{'apple': 3, 'banana': 5}\nWhat would you like to buy?\n", + "type": "stdout" + }, + { + "text": "", + "type": "input_prompt" + }, + { + "text": "\n", + "type": "stdout" + }, + { + "text": "How many?\n", + "type": "stdout" + }, + { + "text": "", + "type": "input_prompt" + }, + { + "text": "\n", + "type": "stdout" + }, + { + "text": "OK, here's your cart so far:\n{'apple': 3, 'banana': 5, 'cat': 2}\n", + "type": "stdout" + } + ] + }, + "step": "buy_quantity_input_test" + }, { "get_solution": "program", "page": "Creating Key-Value Pairs", diff --git a/translations/english.po b/translations/english.po index 9ad7d0e3..64b3ec13 100644 --- a/translations/english.po +++ b/translations/english.po @@ -1237,6 +1237,29 @@ msgstr "\"Nope!\"" msgid "code_bits.\"OK\"" msgstr "\"OK\"" +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_input_test +#. +#. def buy_quantity(quantities, item, quantity): +#. quantities[item] = quantity +#. +#. def test(): +#. quantities = {} +#. for _ in range(3): +#. print('What would you like to buy?') +#. item = input() +#. +#. print('How many?') +#. quantity = int(input()) +#. +#. buy_quantity(quantities, item, quantity) +#. +#. print("OK, here's your cart so far:") +#. print(quantities) +#. +#. test() +msgid "code_bits.\"OK, here's your cart so far:\"" +msgstr "\"OK, here's your cart so far:\"" + #. https://poeditor.com/projects/view_terms?id=490053&search=pages.StringMethodsUnderstandingMutation.steps.string_lower_upper #. #. sentence = "Python rocks!" @@ -2672,6 +2695,29 @@ msgstr "'Hello there'" msgid "code_bits.'Hello'" msgstr "'Hello'" +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_input_test +#. +#. def buy_quantity(quantities, item, quantity): +#. quantities[item] = quantity +#. +#. def test(): +#. quantities = {} +#. for _ in range(3): +#. print('What would you like to buy?') +#. item = input() +#. +#. print('How many?') +#. quantity = int(input()) +#. +#. buy_quantity(quantities, item, quantity) +#. +#. print("OK, here's your cart so far:") +#. print(quantities) +#. +#. test() +msgid "code_bits.'How many?'" +msgstr "'How many?'" + #. https://poeditor.com/projects/view_terms?id=490053&search=pages.IfAndElse.steps.first_if_else #. #. condition = True @@ -2863,6 +2909,29 @@ msgstr "'This'" msgid "code_bits.'Type your name, then press Enter:'" msgstr "'Type your name, then press Enter:'" +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_input_test +#. +#. def buy_quantity(quantities, item, quantity): +#. quantities[item] = quantity +#. +#. def test(): +#. quantities = {} +#. for _ in range(3): +#. print('What would you like to buy?') +#. item = input() +#. +#. print('How many?') +#. quantity = int(input()) +#. +#. buy_quantity(quantities, item, quantity) +#. +#. print("OK, here's your cart so far:") +#. print(quantities) +#. +#. test() +msgid "code_bits.'What would you like to buy?'" +msgstr "'What would you like to buy?'" + #. https://poeditor.com/projects/view_terms?id=490053&search=pages.BasicForLoopExercises.steps.loop_exercise_1 #. #. name = 'World' @@ -5076,6 +5145,12 @@ msgstr "___" #. #. ------ #. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_input_test.text +#. +#. __program_indented__ +#. +#. ------ +#. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.dict_assignment_valid.text #. #. __program_indented__ @@ -7295,6 +7370,29 @@ msgstr "board_size" #. assert_equal(quantities, {'dog': 500, 'box': 2}) #. #. test() +#. +#. ------ +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_input_test +#. +#. def buy_quantity(quantities, item, quantity): +#. quantities[item] = quantity +#. +#. def test(): +#. quantities = {} +#. for _ in range(3): +#. print('What would you like to buy?') +#. item = input() +#. +#. print('How many?') +#. quantity = int(input()) +#. +#. buy_quantity(quantities, item, quantity) +#. +#. print("OK, here's your cart so far:") +#. print(quantities) +#. +#. test() msgid "code_bits.buy_quantity" msgstr "buy_quantity" @@ -11992,6 +12090,29 @@ msgstr "is_valid_percentage" #. #. ------ #. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_input_test +#. +#. def buy_quantity(quantities, item, quantity): +#. quantities[item] = quantity +#. +#. def test(): +#. quantities = {} +#. for _ in range(3): +#. print('What would you like to buy?') +#. item = input() +#. +#. print('How many?') +#. quantity = int(input()) +#. +#. buy_quantity(quantities, item, quantity) +#. +#. print("OK, here's your cart so far:") +#. print(quantities) +#. +#. test() +#. +#. ------ +#. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.total_cost_per_item_exercise #. #. def total_cost_per_item(quantities, prices): @@ -16637,6 +16758,29 @@ msgstr "quadruple" #. #. ------ #. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_input_test +#. +#. def buy_quantity(quantities, item, quantity): +#. quantities[item] = quantity +#. +#. def test(): +#. quantities = {} +#. for _ in range(3): +#. print('What would you like to buy?') +#. item = input() +#. +#. print('How many?') +#. quantity = int(input()) +#. +#. buy_quantity(quantities, item, quantity) +#. +#. print("OK, here's your cart so far:") +#. print(quantities) +#. +#. test() +#. +#. ------ +#. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.dict_assignment_valid #. #. quantities = {} @@ -16806,6 +16950,29 @@ msgstr "quantities" #. #. ------ #. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_input_test +#. +#. def buy_quantity(quantities, item, quantity): +#. quantities[item] = quantity +#. +#. def test(): +#. quantities = {} +#. for _ in range(3): +#. print('What would you like to buy?') +#. item = input() +#. +#. print('How many?') +#. quantity = int(input()) +#. +#. buy_quantity(quantities, item, quantity) +#. +#. print("OK, here's your cart so far:") +#. print(quantities) +#. +#. test() +#. +#. ------ +#. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.DictionaryKeysAndValues.steps.cleanup_shopping_cart #. #. def total_cost(quantities, prices): @@ -19531,6 +19698,29 @@ msgstr "temp" #. #. ------ #. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_input_test +#. +#. def buy_quantity(quantities, item, quantity): +#. quantities[item] = quantity +#. +#. def test(): +#. quantities = {} +#. for _ in range(3): +#. print('What would you like to buy?') +#. item = input() +#. +#. print('How many?') +#. quantity = int(input()) +#. +#. buy_quantity(quantities, item, quantity) +#. +#. print("OK, here's your cart so far:") +#. print(quantities) +#. +#. test() +#. +#. ------ +#. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.MakingTheBoard.steps.final_text.text #. #. def make_board(size): @@ -23440,6 +23630,22 @@ msgstr "" "Note that `buy_quantity` should *modify* the dictionary that's passed in, and doesn't need to `return` or `print` anything.\n" "You can assume that `item` isn't already in `quantities`." +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. # __code0__: +#. __program_indented__ +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.__program_indented__ +msgid "pages.CreatingKeyValuePairs.steps.buy_quantity_input_test.text" +msgstr "" +"Well done! Try it out interactively:\n" +"\n" +" __copyable__\n" +"__code0__\n" +"\n" +"Note the `int(input())` part, because `input()` returns a string, and `quantity` should be an integer\n" +"(a whole number). This'll break if you enter something that isn't a number, but that's OK for now." + #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.dict_assignment_valid msgid "pages.CreatingKeyValuePairs.steps.dict_assignment_valid.output_prediction_choices.0" msgstr "{'dog': 500, 'box': 2}" @@ -23882,9 +24088,9 @@ msgstr "The function should return the `totals` dictionary after the loop finish #. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.totals msgid "pages.CreatingKeyValuePairs.steps.total_cost_per_item_exercise.text" msgstr "" -"Well done!\n" +"Thanks for shopping with us! Let's see how much you just spent on each item.\n" "\n" -"Next exercise: earlier we defined a function `total_cost(quantities, prices)` which returned a single number\n" +"Earlier we defined a function `total_cost(quantities, prices)` which returned a single number\n" "with a grand total of all the items in the cart. Now let's make a function `total_cost_per_item(quantities, prices)`\n" "which returns a new dictionary with the total cost for each item:\n" "\n" diff --git a/translations/locales/en/LC_MESSAGES/futurecoder.mo b/translations/locales/en/LC_MESSAGES/futurecoder.mo index daf6c3805f6ca25125d5e9112d2749b2bbf3c4be..30b812e910c7273efe42c228848fc9934649d18f 100644 GIT binary patch delta 27949 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�qv&>q_zdr;dn&0d>{ zfv9?WaRyd<*B;p()OB}p3eTwJdmK=7eE5*!b16Sb+)JvuOr?#s5ppMvCsL$}tSQ^uuiU!B95?;rDaR>hPnZ@f*M}wUV zaM|Z}5VbgCFQG|i*#GsYc$f^`@dIDlTdf%KV<>nWwOzV=ZAa`B)OoQL_0G6}tuf0v zo6_D`iuhI3qC17nvG6zc4LAaI9$Y+c*B8FP{vSj}=L>eG??Ww;-;qCj1>G;&r`Op_ zRxkVaHd9lvHuX-R&i-_ltzJDWO8hu>$91TI-bZ$1Q1*%)K%f7}LB+H9HBO=k6*B*3 z7gj<|c@OM_3$PAez$WkBJl+oZSO_HKNc6c&)bkY--HP?Fz-Jb@dB36a_X%|4X9dzIT3XZ>_pAT zuc$Ah(vesY<@#??*L@d_g>TW6SS&nA7a{fI!OJA{dcA;u<6o!~@%L1*;1%L&X=33W z7D^in{~A6BSCan^YSBKME*75cS5b?ye)?GW4q1a5$XVQn^E1T4#n~idESODPB~y$) zYO(+Jl6aJihMDaSCZHPLfodRCmROL;o$SN{#Ama{bXjm4PvOLDv7ikDZk9b3z7<#I zjOjlU531&h1%-4Yx$U~_d1K+XWJT0V?m4W=zdr|`koPl4Wwr$rc zv4B701pBcm@zUxH0MDToW62t^@JnY9wk4j0E$}qf$A@e3-#@k_(WhoCJo7hWIpQDi z18N&Hl@o^6)$&- zg&&d8?y>M}FN%4{Z-k$j~lHZ|MEZBe2NE)ghz(jObr@tC*VBnM!hRI8f%ZRbKotkO8f_Q#8M;K|Jv8nN#w^%SQ3L#_H0XG zeZpr^+wUwE!RY8%_|_|d+6BFF8!p9V*mz7#|DPlVU*jfxd2B40%s^X?v;BW)d@SG( zZ9(c3_J0x;f=PC^_rtn`cTgQwn{0RX80x!!8tV1D3D?nJ_9-^iJNb`!vXFli_1^y) z`%qry@mTo9v}l@b=atxw@=DX~z?(Cj{Xd6_$H~x_Px~1*1A|Z_e+Cy~t(msUk76=$ z>RGYyy*?c46R*Jr_#NtR#f4|vK~@*FTi!z5*d^5WLcu32ziXU?ruIqHqT7jj1m{o( zL~M?o^{r7S+#A>uZ=w#UdUInzUp$X$xX!#-_;oxUH52zy+qvz0J0H%V+D%+w=SX}A z3GLsFs5`le{aJh^p0w4zXfe-{XZ0Emp?t&=4jg9eEM~-;&&0yNphT9%!XF|(qi*C+ z)E(zuZYN<^)LMA~=hEIO9H;%?b)_8~$58`G{hY1RMyO}?xW^~4IdQ60c22a#i^MOX z1`>as-GPf&$AT;5?|vZ`e&xRSqJOyHdz4pO6AM3L|9VON#rbcxUbc>Up+>BZf`rbeL~*BN#heIj!GFmK=l)c4;hx6 zIDS-OzZA-sjyuw7S-t}q(+wFpI%RyH@yX-H&#rJ_SA_!!xzhiCJKELgc*69^|Mj$T z|H*{Q|DT?At@$M3!Ig!(CJ!H;IAGMs$b{tK zlUH6E5GfW{3D$0a5ujvGIA z$jCuu5|c&_NbEZ%C28dNA>$|aO&m8ky!C#`6ofquN*3RaAL~1f{Cq?bxE-C#7hfNPn8OLKA lO%I8qMkXdFkv(L5@`$qO(lwr!G%3RWi|$IA6#Jmt{{uY&|4IM= delta 27493 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 D`^ka| From 2d4fa45577b38ee46efe251b1ddda934693b1cac Mon Sep 17 00:00:00 2001 From: Alex Hall Date: Sat, 19 Jul 2025 18:38:13 +0200 Subject: [PATCH 09/16] hints --- core/chapters/c12_dictionaries.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/core/chapters/c12_dictionaries.py b/core/chapters/c12_dictionaries.py index d18608db..11178fd9 100644 --- a/core/chapters/c12_dictionaries.py +++ b/core/chapters/c12_dictionaries.py @@ -798,7 +798,19 @@ def test(): requirements = "Your function should modify the `quantities` argument. It doesn't need to `return` or `print` anything." hints = """ - TODO + The body of `buy_quantity` only needs one simple line of code. + It's similar to some of the lines in the previous step, but with variables instead of hardcoded values. + Be careful with quotes! + `'dog'` is an example of a value for `item`. + What would be an example of a value for `quantity`? + For `'dog'`, it was `500` above. + You're making a generic version of `quantities['dog'] = 500`. + The `quantities` part is fine as is. + Also keep the `[]` and `=`. + Remember that `item` is a variable, `'item'` is a string literal. + Replace `'dog'` with `item`. + Replace `500` with `quantity`. + Don't use `'item'` or `'quantity'`, use the variables `item` and `quantity` directly. """ no_returns_stdout = True # because the solution doesn't return anything, returning stdout would be assumed From cf7ed3824d877bf0f4088a692badba4b92b3845e Mon Sep 17 00:00:00 2001 From: Alex Hall Date: Sat, 19 Jul 2025 18:48:18 +0200 Subject: [PATCH 10/16] hints --- core/chapters/c12_dictionaries.py | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/core/chapters/c12_dictionaries.py b/core/chapters/c12_dictionaries.py index 11178fd9..73d674e0 100644 --- a/core/chapters/c12_dictionaries.py +++ b/core/chapters/c12_dictionaries.py @@ -931,14 +931,23 @@ def total_cost_per_item(quantities, prices): ) """ hints = """ - You need to iterate through the items in the `quantities` dictionary. - For each `item`, calculate the total cost for that item (quantity * price). - Store this calculated cost in the `totals` dictionary. - The key for the `totals` dictionary should be the `item` name. - Use the dictionary assignment syntax: `totals[item] = calculated_cost`. - Make sure this assignment happens *inside* the loop. - The function should return the `totals` dictionary after the loop finishes. - """ + You only need to fill in the `___` part. + But if you want, you could also just put a variable name there, and then add a new line below it. + Look at the tests with `assert_equal`. In the first example, the expected output is `{'apple': 6}`. Why? + Because the customer bought 2 apples, and each apple costs 3, so the total cost is `2 * 3 = 6`. + The `'box': 5` part is ignored because the customer didn't buy any boxes. It just means that the price of a box is 5. + You need to add a new key-value pair to a dictionary. + Identify the dictionary, the key, and the value. + They are all present in the given code already. + The value is the total cost for that item, which is the quantity multiplied by the price. + i.e. `quantities[item] * prices[item]`. + The dictionary is the thing that this function creates, builds, and returns. + i.e. `totals`. + Note how `'apple'` is a key in all three dictionaries in that test. + i.e. the dictionaries `quantities`, `prices`, and `totals`. + """ + + requirements = "Run the program above, but replace the `___` with the correct code." def solution(self): def total_cost_per_item(quantities: Dict[str, int], prices: Dict[str, int]): From e1fe17901613b3a574ae7bf01c94f78a8164ef17 Mon Sep 17 00:00:00 2001 From: Alex Hall Date: Sat, 19 Jul 2025 18:48:37 +0200 Subject: [PATCH 11/16] generate --- translations/english.po | 135 ++++++++++++++++-- .../locales/en/LC_MESSAGES/futurecoder.mo | Bin 316303 -> 319283 bytes 2 files changed, 127 insertions(+), 8 deletions(-) diff --git a/translations/english.po b/translations/english.po index 64b3ec13..ffb0afaa 100644 --- a/translations/english.po +++ b/translations/english.po @@ -23581,7 +23581,79 @@ msgstr "Copying Dictionaries" #. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise msgid "pages.CreatingKeyValuePairs.steps.buy_quantity_exercise.hints.0.text" -msgstr "TODO" +msgstr "The body of `buy_quantity` only needs one simple line of code." + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise +msgid "pages.CreatingKeyValuePairs.steps.buy_quantity_exercise.hints.1.text" +msgstr "It's similar to some of the lines in the previous step, but with variables instead of hardcoded values." + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise +msgid "pages.CreatingKeyValuePairs.steps.buy_quantity_exercise.hints.10.text" +msgstr "Replace `'dog'` with `item`." + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise +msgid "pages.CreatingKeyValuePairs.steps.buy_quantity_exercise.hints.11.text" +msgstr "Replace `500` with `quantity`." + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise +msgid "pages.CreatingKeyValuePairs.steps.buy_quantity_exercise.hints.12.text" +msgstr "Don't use `'item'` or `'quantity'`, use the variables `item` and `quantity` directly." + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise +msgid "pages.CreatingKeyValuePairs.steps.buy_quantity_exercise.hints.2.text" +msgstr "Be careful with quotes!" + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise +msgid "pages.CreatingKeyValuePairs.steps.buy_quantity_exercise.hints.3.text" +msgstr "`'dog'` is an example of a value for `item`." + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise +msgid "pages.CreatingKeyValuePairs.steps.buy_quantity_exercise.hints.4.text" +msgstr "What would be an example of a value for `quantity`?" + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise +msgid "pages.CreatingKeyValuePairs.steps.buy_quantity_exercise.hints.5.text" +msgstr "For `'dog'`, it was `500` above." + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise +msgid "pages.CreatingKeyValuePairs.steps.buy_quantity_exercise.hints.6.text" +msgstr "You're making a generic version of `quantities['dog'] = 500`." + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise +msgid "pages.CreatingKeyValuePairs.steps.buy_quantity_exercise.hints.7.text" +msgstr "The `quantities` part is fine as is." + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise +msgid "pages.CreatingKeyValuePairs.steps.buy_quantity_exercise.hints.8.text" +msgstr "Also keep the `[]` and `=`." + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise +msgid "pages.CreatingKeyValuePairs.steps.buy_quantity_exercise.hints.9.text" +msgstr "Remember that `item` is a variable, `'item'` is a string literal." #. https://futurecoder.io/course/#CreatingKeyValuePairs msgid "pages.CreatingKeyValuePairs.steps.buy_quantity_exercise.requirements" @@ -24010,43 +24082,90 @@ msgstr "" #. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.total_cost_per_item_exercise msgid "pages.CreatingKeyValuePairs.steps.total_cost_per_item_exercise.hints.0.text" -msgstr "You need to iterate through the items in the `quantities` dictionary." +msgstr "You only need to fill in the `___` part." #. https://futurecoder.io/course/#CreatingKeyValuePairs #. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.total_cost_per_item_exercise msgid "pages.CreatingKeyValuePairs.steps.total_cost_per_item_exercise.hints.1.text" -msgstr "For each `item`, calculate the total cost for that item (quantity * price)." +msgstr "But if you want, you could also just put a variable name there, and then add a new line below it." + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.total_cost_per_item_exercise +msgid "pages.CreatingKeyValuePairs.steps.total_cost_per_item_exercise.hints.10.text" +msgstr "The dictionary is the thing that this function creates, builds, and returns." + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.total_cost_per_item_exercise +msgid "pages.CreatingKeyValuePairs.steps.total_cost_per_item_exercise.hints.11.text" +msgstr "i.e. `totals`." + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.total_cost_per_item_exercise +msgid "pages.CreatingKeyValuePairs.steps.total_cost_per_item_exercise.hints.12.text" +msgstr "Note how `'apple'` is a key in all three dictionaries in that test." + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.total_cost_per_item_exercise +msgid "pages.CreatingKeyValuePairs.steps.total_cost_per_item_exercise.hints.13.text" +msgstr "i.e. the dictionaries `quantities`, `prices`, and `totals`." #. https://futurecoder.io/course/#CreatingKeyValuePairs #. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.total_cost_per_item_exercise msgid "pages.CreatingKeyValuePairs.steps.total_cost_per_item_exercise.hints.2.text" -msgstr "Store this calculated cost in the `totals` dictionary." +msgstr "Look at the tests with `assert_equal`. In the first example, the expected output is `{'apple': 6}`. Why?" #. https://futurecoder.io/course/#CreatingKeyValuePairs #. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.total_cost_per_item_exercise msgid "pages.CreatingKeyValuePairs.steps.total_cost_per_item_exercise.hints.3.text" -msgstr "The key for the `totals` dictionary should be the `item` name." +msgstr "Because the customer bought 2 apples, and each apple costs 3, so the total cost is `2 * 3 = 6`." #. https://futurecoder.io/course/#CreatingKeyValuePairs #. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.total_cost_per_item_exercise msgid "pages.CreatingKeyValuePairs.steps.total_cost_per_item_exercise.hints.4.text" -msgstr "Use the dictionary assignment syntax: `totals[item] = calculated_cost`." +msgstr "" +"The `'box': 5` part is ignored because the customer didn't buy any boxes. It just means that the price of a box is 5." #. https://futurecoder.io/course/#CreatingKeyValuePairs #. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.total_cost_per_item_exercise msgid "pages.CreatingKeyValuePairs.steps.total_cost_per_item_exercise.hints.5.text" -msgstr "Make sure this assignment happens *inside* the loop." +msgstr "You need to add a new key-value pair to a dictionary." #. https://futurecoder.io/course/#CreatingKeyValuePairs #. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.total_cost_per_item_exercise msgid "pages.CreatingKeyValuePairs.steps.total_cost_per_item_exercise.hints.6.text" -msgstr "The function should return the `totals` dictionary after the loop finishes." +msgstr "Identify the dictionary, the key, and the value." + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.total_cost_per_item_exercise +msgid "pages.CreatingKeyValuePairs.steps.total_cost_per_item_exercise.hints.7.text" +msgstr "They are all present in the given code already." + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.total_cost_per_item_exercise +msgid "pages.CreatingKeyValuePairs.steps.total_cost_per_item_exercise.hints.8.text" +msgstr "The value is the total cost for that item, which is the quantity multiplied by the price." + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.total_cost_per_item_exercise +msgid "pages.CreatingKeyValuePairs.steps.total_cost_per_item_exercise.hints.9.text" +msgstr "i.e. `quantities[item] * prices[item]`." + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +msgid "pages.CreatingKeyValuePairs.steps.total_cost_per_item_exercise.requirements" +msgstr "Run the program above, but replace the `___` with the correct code." #. https://futurecoder.io/course/#CreatingKeyValuePairs #. diff --git a/translations/locales/en/LC_MESSAGES/futurecoder.mo b/translations/locales/en/LC_MESSAGES/futurecoder.mo index 30b812e910c7273efe42c228848fc9934649d18f..10bc8134abfe1afbe0915cd862aad1f9c28d9ef7 100644 GIT binary patch delta 29709 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 E0e{tj^#A|> delta 27916 zcmY-13EWOq+xPK(o##pBc__qX%8)VhJkJ?2Pnn0z^E{j(B9stG87m?YAtK5gN+dJM zaM!Iu$q?21`|sm;-sgSa&*%Mo*Rj^xYpuQZT5Ip~%KdEmJmYJtGR7}vh`kZ;|K3d+ z1UayB8AUz=PX@VM9SJWMia%Xw@a#X{gpzdrxYM_@qe&pqu2L?eJ@(W-=EQ=aQ zXUstV!59*?a29F+$FLAy#Wa{^kPYxjRC!UP|tKbYG4;U{|~H2oOFoYNL^HU zD=duth6M4j!3AWbCu0?A#M>|}9`*PFrYF9Q>M%Og%z~;{2z6Zr)W92ic~6f=yK_+O ztVRuF`%vazQ+$k!vUmwIV3uL_Obek#S`&-m0Mrz|jZfkhOo!iLQM`uQEg6SfN0m_Z z8>7m5qXzs2s^9nGB(jnC#Qg>{5&sue;a}7RX-3$kN7jUOSQiswD!hWik8LCTSKK@L=01a(JMFeA1>b=VIz^%LC%sDXau@orSd zr&0a=WaaVT9tky&e3V^~1JzM6RK;qj@+My1)ys#W8hpvi=X?1ocbk_V_V^sCy$u z+cpno*8ZtDBWeJHPz}F?8o)ev8LIv|_X~W2_#~=>o2Z%j8z09s<7{RNxE0(+n4R+H z$1(p(j3GlKe*?8>-a`#&E2_b-uo#|09kD6K+jcF0*@!z~ZXAQ{a50v|KT(gYzyyoy zVq@absO$DmVE#*yxJ-tQ+{_d0B&&w`h`XUWei?J(7R-w$QS~2qeqP$iPFxc;@J^^3 z8iJa!NvIim1GC^tFW(*~5#AwcMCUxdi+U7~y=dh*Pz@G!tGJEb=TS2^z~i{buc2;a zIqI43M-AvAK8f+)N$6Rpn`9m4Laox$s1Y|r-BDXqy?&?xk41Gj(|yNX@8w^3d>l3K ztElVmcpRM^=EsAKmI(5qrnnU9&YPn~+8Yyb9IAo0Q3F`(@eb4g54#spH*nkI$EMg~ z%!Zo!QmA$tVrK3CPM$H`osPQmw^1FfLEY(Rr~w>BHFO@;@gJyqNnf&oXGIO52JRDNUB0K0oU7S;Y7 z)Ie6CW_Sz6!>J>ohA*Nj-b8hnFwJHnJ?es7s2M1YYN!_K`ZgZ-MO`-$Rqs{QqI<{7 zH>3JFgsOLTn!o@5ONKgr=%#+z;#_V?)BtLsI&6ztz5P6%f!aN9qdMN|?niZW5;c%( zr~&+q>MzZ7=3j}#>DKTws0-?#I&6jNs4wcm>8Pn)gsQi}-Hn?1V;)~e)xYaLHpAk_ z-9o5#D#l4@#LuA`?1DOS2fGv8S5Q;F5Y^FI_Y2QIg}KPTfm%B$U$I@255pTm<+t+u zfgZ# zZ`7m8Ju4h=Jg7`U1L%mVI1)8A(=id3qAuKx8rW6TQJZ46b?_9b!>XtObwsr{6jR|W zOpS{$C9XnUzbTaG{|yNpJU6^TidSufSuhXzC9wduL=9v-Y9Pz-DctY=in@VJuh~pI zsgc`kp`Qgrmi!p;W3yG7h!t*95s+*SRF55HOx6T2%f=C zSO;InDtHRZVCH#2P!1cR*2EN4Ka1zF|8>Wk$lgo z7SnpnfrqgW{)E~M85UanG?pZ8h2`;OcXymbeKH<+M$I?*E+Za?y0Z^a7w*TZc;79z z$i9F^qVm_dzqn7oW#xTQGrSy&;2zXKZ((_ir(SG{x^CS4)V=K%e%l7t9jkNUd{hG` z-8Ao5T+e+GbtBtQ9sd_|VAdskVPk15O8-F*5{<~1>t1vVFQpRsBe5Q?b^mZHEwlV7 z?qN6Ma?9`Fu0##w25NEUSYdVxjdSvO#&2%vm9~1vVmmJQ)Xng&#r?4+`TOxnO#U9n zHx_WmxQE>*-?#EX?ibjN`WaURK?C{^Mv^FtyRkOj!^&8BwK>M!;{M^5_`u2spk`_f z*2PO$6`xvT_H^HMub}$NvzGbS)VCuc-*a!fRX()*8CZ+*lUN_0SZ8*_>cneN<-fQk zKC*bY`zcnU{1HBd<=5MJ(0M)2zXll#$6R4iRgCAsOe5}cf0>$S?X2&%r@Kz)EvC$-gGPMu)})_YV~b#AG+0dTK-h`tDUS_ zRZRQ2*%B)gFT%$7y_;{B#Y0g8*^RmI9_sq6yUmWM>z89yyofFE$uGWcQ?7aIfW$!%Ecu8uf@$>@z#MAGyJP%Wv+!ixsIKze_?LmONm- z9zqQy$5*y&+q$dVyKbGsRzBa12Uk4fnIpE&C!sdxK{x$T zi`%;^-Cx`?U)#o=h>f^zmz(k%i`%#>-J5QuV=9mH{vx3re*$x3)^BaURB*?*+uR5L zQ-0j)jd8cR4^X?N!U-GL5O<^dhgr|7s-akdRZ|eQuI7mS4x6>h5!sob_^ds=E)% z(O!~sw#cfuquovJZ|9i*XQ)`{yd5|lu`cmg_X{`K1tVsS6 zkI%R{E?IeJRQU=lg%>Wx`T8f3{s%jpTc9e;My-j1SP4^IwryG;^Aby26i8&EU%6PBj`Apc!^Ika~_awGRFzqPvtb>Tm#fmOP1+ixP~C;l8Y zQ&&+pl=p!-(B0<7{<8e07+1x&JmZ>M;-OU-hixd|kF7E1BkOns)+hedP59g5hVDG~ zyqo_YD<9}?b%TGIe>K$LUwfu=u^I6RH(!tt#v|PQZq@|Lf5F}6rifU62lqo%`+s9G ztQ$=T54sUpgLrc^o)AveJu);CHDl&%_q3ZgNkTZ~15u0VWA}kuBdO)jaKFWB)O+Hw zgz&ZA4s}kiX;{62c#U zHLxskU(`%2cjL!MXi@!(rLl6#gzz`c5O;}t*uC%OPn8h<+H8*1xo(vEDQdtEPy=~7 zbwcL`9cdqO-+-0+MNIczbGz*bb)=q7v8;!f@- zr~#$OX*NL3&~((c`_#Sfmd|DRquo#4`?=WvT8-rs6N08V*xl`>%We5x+zoD!$MT!G z%iLR7op!3{)#BpsW2igcj#|8D-Te7%5e|-%P{*6xXnwn}1!@Lnxj$lE;_^?~9mi2q z`Z;R*{*HRq#S7S@8-RKwucIE}LDUTW>2dyowrJzcNoWnc=x%X;aq|?i^0pYRatv3w zdmlA`(uK_-?nmwox8T!O-qT%S#)C_qk)w!JXou=xfqUFdQ`GVsy3^b*-GAJQ#cXCq zVh-9_gZkt;fND2o@r3aAb-hsb-+a%w>=r9w6~?&--OME|zZ+`xuE%Ha4z|St&zLV_ zJK{4QmnvoXv)pTL)zakCf3Q#qyyZ41WAO@9M-NeNtLkMfp6niQQ?^kGh#FTK@Cyd+x7pnMzhZ!QF@2hN&yt3^hib zurHz(@pd<%3j1Fj)~{j>%t2K+?dGa#aW8kBd&jL*&B`achfwE2y6Oqx-v^qyi`*-y znJikvW^zys_P?h16VG_yR;_9IQ{01Y>ROiH++FCNM;)=bYbOMqa11uV)A&3VsAEn= z?UpOp7!%`lEiusD;ijl(`EA|z-8*j0`c^&%^>KO;^I*OPHs$qD`+h9yfLrBWa5p^t&WFaR4#%PDZ*s4>SsPn^12Z0s z^Ne-wCDeyQ`X=@=sf1cQy-^J=N1bdZPyTTHzwJn#U-lpH7+WXfn)GQ(V zYjg`NruY8<5+$hcHtLR!qK?X6@LA09oZVp`)DgQBTjK@KFWubE_`ay!^oqM5^{gW; z%xdm;2jE8Q8wpMWz>e+5a&Cm^0!#UcS9Z>uHEsxK-Pqer4w(dgrdpC0jD{t9>{jUb+ zk)gNXan!TT)6u4^9qP+wfqU2up0{US1`{doh8o}$)LZitH$^9lySQ6W{iW(`YpGFZ z_P^fC6Ua~l2T}X>fm^?e#S7i*sMTGjt93j8wb)+8M)-xBx|_xA-1pqus3W>cciX;` z;v}?xzd_AF<{owu_Cy^J>)eNKgPxYZ(7lGbzEm$8=ot5)o3*#)_i{J8u@@{q-og_r z+}o%lxOyL3{V%)Uxw-pV{y_IL)CrobpB=f4-G%OD_v!vtKEmB)#)ISote}Pa4(g2l z59&lKG|=|(v#7N(%KgZ_=H?h=nY+5d?8?9MpEwpB6I zfzl22jNkG6W2k||hT3APgn9&HF)!}+_^MlYn3WH9x44g__J7Ucw%w+qey#3z(~hvX zt-IX)uUl%QeQb_LEvlWU#hEb5@++Wr!&vv2`_yR5ACGZWIPMt*$JpYUh&-0 zSX-1W+{Nw{_vvv~J`8mpe1`h1_Yie{tlNC^K^ zV^`E88H;)ZYf*Q09o1mYiMIV(q8`l%)LL1My6!OQV0(mmG!@zA@SeRr zO+D2fMSFKOs{F27YnsJ#+zW2umo0ykyVp%W-5zNt)LL2T#{c7qr)OBfAa|2{&#m-| zmB-yZ?qf6UP8zu{qt?zI)SV}rWhY@n)Z$)%I)X1Dk1QVKoNdpx25Mwu+?{U1tCnBK zo#7sJ)4yf|XoY%LypCE+`%&MP|GM?&Sp1rMDwO?~>vdbTy-_1y<^F3k>Yee>ZSbbQE8J_S#a(KVEzU6**Bxvnp|{}gs0OOMWzKZZpe`)1*q-G8 z)SYZYePTu4wwWl3&lA7k?sxOOV=tS@sO|SH_Qc1Ru>X~qxWqE9x(%0Fyur<~%o-Sv z>hLgX5#2=%yv%Z&;uldJe1#ft`W5ywyA3M;Ez~#TWz-r;w~~WEi3Tg}BXhF5!@cX4 zc-PANqUyivUU0L#XZcOt>FyWqUv8=Q6T&~^_eTwISDb`StR$;!q-9Z$WDM&2{S%Kb zqrQT3thO(g)~Ewyy1Um6KCt}C?r79E;wPwI!#|;BF3B3-&b3K|4WYhz_jx ztsN+{Q3E)OxiHg*Ht^D@>wCJ(QM=}Xn{A!NZQS|pw`M#@^O03(HGhJXFRddI%@6Cb-#8~Y_jsY?qm%A1cQkT z?03}S%=n4@;HZjvv@c+8T!i}T*k`DN=|5OQ`@i^RJ3xlGo7_K9Q(kV1Ev_N%8uyBu zW2=?7a$j{1xWT73kP4_@P<=gq8{=AJM@gi|zpy%{+GhK_G3pK$p%&#=sPiGocC&@M z+`Z{m`OH@LOni>|-@18sSUkc#u!H@t3Qz2`4*H=EmiMtb-b77liO&FAHIT{f zPWQfBYL}G{bU$#fy18~+d3*Pb-En*U9wQ?Q4M)GQZI=!8GO6c|cRzNoyV<|Add*NX zITefIM%1JG!OgbE;+CjK@T$kVjjXWoxV^rXp^M$@Tv4YKfp9rlw#7Cc!DFiZeWa0dhg` zE@s4!JpK|>5+A{2cpBBtWlW1VF$4aKDKNufYxhY^s{LO$Oz@ufg7T;V)badA_!x0> zRD@!ry2i)UcegPlT{=ZHl4gQ82>E9lwJ7OK@!Wj7l zFees44WtpOqYkJ?(gQVsC726WqpmxM8sJecKY<$91&nKofA);Ks5o-eE=Y@NFtf+G zP#x#@{4%JiuI4sI%~S`EySqa?KaNQ$e;G9+uO4Op>kbx?p+&L+!zn}MA3%NYA4AMikjrTYP@{(6tMc)SC3Lwk@%73ZJbScex-Q-9sPgBoe%Tgy*@>iBU~ zhdEK@c~Jv?+T+rwjw_?;)$;QCUjCeyx5Fgb|6RO7FRw7j9Tiq!h#pTxH8|Vz=b}1# z)6187{wjB!y9uMz+lHBNC+fQ6m`wZsj92&(b%)nctN0hxv%Kpj9JfW63bjoi_c%Z5 zx{|2+<-EKmMu?lb&D~aRTa4?DI*^cEP!08T`=JIh1a$}FP$Q3{9@R82pO1P3OHcz? zg=%jjY5-f^?Wp#4x(AN4|FsytB|{xtMs;uvbt3+Pdd3gk=n0EcVtVp3y7^H9FX!b| zPy?!iYOe|A!&ayhb}VYU&OX8Z*Y?>?MpitGP4NmAz*67YGwXng2V*UK6LsBrEQG(J zj@+y#?I0_MdOJ2lb=(j2?C0PU_#UeMuDBOmLfz3F)X0;5Z+DayHD#GmGn5PU?DKkg z3Dg~yMGdHm$4yX=qLs&8P&3rq9pJ`?d14G|s^cEN?D1^WoxFj1<{MB0`W$tF9Yj6r z^QaClqfW+OPy@b?x}is?dPz>%fKwp-#e?*g;9slR0CIbULLQeujl4XnfvO(YavQi! zQB&LsHITljfsR0Z+Qm`VFF?)M;xK0atstQhu5ve^?qHk8`%sJVYt+aERzS@}HB|jts2OO2x}g?l{QdvDXY@i{IM^$WL@l~;UOofW(L7YWw>(~k>UfpA z-ref%LJi;mYQV=)i}&0a_P;W2lA-N$A2q_{XU#OIjxwSK@&sxC1yCIpbIYRIsfwy! z57l8~R7Y)5*Y!uu>@ZZl7vr9ohI%HmJbn{(!4mg9_d|CRs-f+u0Utm$cm#Fi9(PZ= zr%_XW4s|2fP}j%*Afb^4=MsWGkP`LFXN0>3HIPfFqxw4Pq`d2Kn)CMEpA*X_@bAV@ z*H5}&9d1G0*lyIKJc6b09MT@=|3&-DL@v}LsEpIGF}{i4qo#JyB`Y6|1?Xr7RwMu8 zA1wbi>P8}$?G968e&Xzyhx#?JD)#u%-T^DG=&xq%|1BgMQ1KF~fkId9PD`U!Z*9~R z*GEllV|)#pp*r{hZ(`DGR(=;XLk~~`Pk-GWO*T~hMARRx>tZ4L55|z_%E(rtE=cl| z{k%?tn(~fVg!2A4j*%?-*?tXY{>^?9Rz^L`-Z&YDqaN8k&;JK?BPnm%K+>Z6$&7Iw zjX6nZQItWwooac7=TUdk3$=JAqGn<`s)O06m)3mL;(H&{G0+cDzmRs`vL7sG@HX*% z)Ik1wJ0bWAf4j~8Z^Q-LekTKy+(`&Nqu|(|Obzj@y9vQA;w|?Qf;~9$z73?}gM{D* z;@YUimj5psSbNmhb7vfh6R;xQLH+Hh_(S_K+aJpjfAo<3ub)oW$!Ly=kL<%>80x}h zm=DjPo_X*$i;i2EgL;O?SP^S6nh*)&_4pR?kN5{ph(yAH42ed9*NJ~Zof~6gk?^H7 zIZi@TxCr%SvKBS6&rwr)7q!YC;aseoBof}qH>f*Ll{6CmiKYg2A|8ren7MCJ+wGZT zkzgFwz$Um8^@vj?j|B5E{uBxQH=xh(IZU5|2CzG>rlGy4pJoG6MS@y9^l7L8f0ZE; z{(<5=4ku2NF%te&YYM7^!>EB@L+!5onV13E8-z`X6S73~_Xhs{L!uEGFQOLX5v+w* za5one$QlVhy?%P!W+>egk>CXTFfT?Zzn47{9x#99h=jW!>64LgF=xc1w38ck1m8r> zNHk|8T)Y`Dh4%jwBy@-Q+$xxdxHT5RF}RbC-p4M)JreEC_F)y`B)KEuTB(JZh$mup z>d!;9yFO1O{1=c1Q3JV%OhWLxV)_pr%OBA=g6!A~7h_xe1{%x(7zsbo`V@+UyXPhBN_q9dHsBT5fjIhfB&dmE{AuB=M=SP zJGEFO7)rbqpT)w(Bf(f4g)!>?j_rx>m57A@E3oDz?OAU|b@VSb#+uJWf;l(`HM6-( z+04~06^RF{$(T$=QGB|zEyi}JHL)Hw@`u=)4%?K8g!_9}*+?*x{0n#&`;@bp=u$os z{D=693ReC>MH^U|N|9h9`ETMJrao)sNch*Z)m7t>;2{Mksz!pR>EN4ck?`&GuzDm& zOU2?fBHGKQa-e~?Usq|8>n}{hwe5^ zO}yXBzjJS3HEtx*!e%mFvt=ZhO~o$Q1AoJA*rJuK@-3*vc^3=d$kvg7g&!=zAvCnB zZ6tV`{F3b>!8`ahzJdKaM1tz-sADAj4-U1Sx5Ydewg0zaN$vmSo$Q3FgykvNic|3x z^7p7=a)OFk3gYGG* zsl85OH~xvbaLW+8;B)t=d)~d_{)L&TpM0p9%PoVW$Zv#=aSv+B(+`V;KUTY9b>f*A zSHTeyLomm1JIP+fq0Gb~)LX9dNZSR2Fp>B@ER6e6Xa8+1guO=DBbkGBh(8)_+xQOZ zAgeyc*1{;PN4#YW`@b}af5^~&FEy5ZO2={3(fQA~NcdXLI^GVTzNoj{R;-U%CfEQw zBa11Ri!E?3cE!ghMuLk`Ubm=i*=}+q{HI%6Q0=6i!v5C<{ij$%yHO4Ofju$*OOf!u zXwJmW#6RN)46wmeo7z97S^XL>N5b!fVeXr#6K^MK@im!lZ_Rcy?6uwx^+h!#PNEr! zaj3KX21`fop@Hwn7i*3sQW}*(9 zO|$J$CBACgJl>E*5en8Jk2^Sv`VeXQx(%osYK+L{F`>`Eh@1Z_IFQUGL9-)r- zEF0~S*2W9OFJQp>3+isNBe>pXJ{%}GiCOSAYB46;Vn=gDR6|QqC*@JRgh{vBN9T3i zO+4vS8&J({R_`=w8>ioH+q*VaCyrzMGKt+J{=gNVMS_Oh;es8us4nk}1k7TP@OdQs z!LV|-J-ZK)FZSRT=HG#>{ zdo*5%JLWxT=f)JQrF^W384pE*t=JlM^rrdBw(FCq50-v7 z68C?_{A*QLIUEVj;dV@h3y#=pb}6cXwU}Pz?h#DK%v{7Wid0EY3%rgom*?Ud1L@?nET$Lx3j2p2f4QDtN2|gn3 zeVVr-W;tV1*A_L^o3Ikz!EGHxG!milooP7ZuMh!4}J`!*k28~etow&%SoA&>G z5{JpS`GZ~X*=73%`~!86H2Bf(WI7IFVDDmU%yiZ2_q%4#b|vZ#Z(~kOcAc4{UIE+? z3xewZvE6g~hMk1De$m0i{+~snEf;)`-LUwt7SF{2#5YhszuWz0Z?$PR?GYS7-C6cq zk)R)TM{U<{ur4OtwwbJtdilKbyS+>P!oI|9|6sAwf3Syy&gi6f?8q(lCr2t%wGdVD z$US@emAlUu5%Ejd2cLUjN9t$zD{;2JY|$orXy1aFa0L0e@ft3~v^e1r1E;^)823~XUOu^E(eQV~EYu=D6N|S_n0up4bUDq={3J0i;bE4fkc4 z^wIF(7=%ZuP#{Az-1mQCH5Soh8KXh=D1YC}%AGRM?%AT@0X2`z4%FX{J7_OU4vSCZ zjE29Iis!N!D4l5e%iX`@o@kdl8ZM&E$gBpr^F)IoG?XuYG~E9S3PgjszYqT zgRikf5xeeR)NbillmT9cZa5N5fCO z+Q?do2Xjd18SciH81Y>!Ks=7Wvpj_>Q5}8d-bC&1Ox5jKmvY;n7Tq}1>vu7B#%-tr z?TH%E@RMs`&1m>(HyUed|6e3AmkPOS+3NnJb~OAcwHpU9pre?QhN{%F{06AS(;C;{ zW}J*&>PN$0LRV00oY2&s zKieZ3{?4C>HHf$13cQax2^aS?4`W{9hp5GytCua(s&Nv!laBZi zL!F9x-RltZa{ss9zcBq zJ~@D0M%)aw>*6N|+Wt&A$hKQk)EXFxT5Nl;FD4%x4S(|u$JE42u_vxWE!vDjtlkjR zC)#;j8sUH%YBzFhxScBnN7$oojnDD^309FP$^{Qb*#T2vv`uA0RQ@cii`y|9CX9)O z|B^8W>YS*6`XcIz>UaZI#@N_s_;-LBsDtbST#DVs+4Yg}+;|f9UoH~rp!=j~_&3@$ zn47rrWZMOua1Zh4SOX_dv4QQye~5p_@_75DXz&vjo@$RU;{qW*7o20xR?gMH@O89fW%A>M<{9%E|x-K5pK@h$7% zdz{6yEx0%ueqd~VCmNik{OKjp;14=Zx|Fvi@n6f>w!{^e+Yvr}MKt`A&N@s^`Pg^a z|LI7)^lmh`K*cvO7Y=*hMm}$qt?pI0o_c?v{_wbRwLR{zS+n`=TYf)dpKdxi{mmqPEjMuQ>N73+4C!eCGti*cT=TmSJ@n&p|cR&&mWR}62L}`#@84&;Icfq`ibjV|D87N8Ryb-`iX5DdfjcFdnsATA#5ab}Z^3+kkp!T*Sth?kqE^?bnG! zVSEp@=#F6n%zMth0SBPYgG(2zfxH*(WNU@bkiQePMs6X0_zK!xvQMv5m#tpLA8n?_ zVHN5fL7n|6uCV|08?HKu{5T%l;R@79A0az3D0bBjpcDV$pyFBliuou{`tFuY20VimG@p7aQ3EQUV2(na16vaK_fMLV zU&+{jPe)=wlm^bDF8m=H3tyunVzKZjorS8u4E1`wh=1Xqs1xy4l34IA@q}ct@DB4N zkA;7%?u`q{{~NVv-$)S)kM`?v5?YltQpUoU$P&~*PT@|Ro+=hD&bp~%!4%@MX=34D zwYH<4eXX=MppmGCKS5oeBwZ{>QQuU_bHu{!mm*gz{7<-vs1KMMi81?a zm^&7HOk58;;RDQrZS%ym*!kc8lF;J$+A@N_QLDXKUTa`JYWti*?TRG%V&UR!iaJ6k zxd%|~q|P4;za1-MH{xD+l(lsT=W}BVi`dK+DXvGroOCA9gge@f-7tB{Sorqq|4c0W zrIMmlET~RHtx>yUA-2NXsNa0`O2@)Kxvs=L!O!cVv6sDow=zKGvrZ){UG7VuY` zU>DZYGnrd~0pMBG;wn@z7JljU#-_xRu^}GE8u(--8(3%5nZFi`<28I6GgppgR>(C$$#`>78ZY=!t z>W&)NOw_=>$L08Vy;#ti4!2`JW;A^xYiGiHWm*XNYdCEXogz7b5RFH zttPSX?f4360Q>L^4r*#M)S#K|;~qGb{KZ&;j&na33x7K{Z)qKlLG70JurHoQ&2+6+ z?Ei`+Cbf!%XZ8-%V*3I0NYb>n2A;=U#4}Leav$IT{2uj)YPYc|osX(_rEM(yhK#n0 zg-3gSe1iODn23F`3Nte^PGUNVL+xY1b_$wzj0LMO_4786&8W}uE2wuwiB7TLB6dI> zKovX3f^GO5=Eam)+@t}8qI{{zDwp6@|gR#m0I|n|(a>T!53oJa)_Vq-}NqiX#VKB&^ZDFiI_y%hG zox*$=9UKeadIeFtpc8J?{+~-?9vO9p#Pok9F*t*3aM{pUFouyf8fN={-|$$#U)qAC zBVyqfP%zrg_HI~>`u9;Cl^J=I*KsCRo@A^1Aoe6qI@wOn z{#b)}3C3%Z_<=-r%sa(SvTCU9@)7FJE~7pea=&ExZBSGD3Tn}9K|O-AsPiE<)z13H zSdaKaY=n1E2UPWGv7ifHn8yBB!&P67g`da6Q8V!fwV#_#w*%%Rs^P>Lc98Tz?cdd? zJGqYCS$qXwvDH3nHjk1=^*;8Ye83zI9A@kkrp7z3$HKp$MCP&olT+d6d3Gm%pzb*9 zd^-u-pcc#9IE@C6;V|Mh3+>!Ej2cMNH*JyDMm?(W9v{U9#7P#}Infj^5idmzBp!c@ z?LlJp;#hE%f=}O$gm`~8S1iJx6(cOk%uSqnJ==^aFOGT{ zz5cO%fc%1b@8{oW*Y!hv#BM@8ikqk(Bte6;wypMfmR>VQ9zhD4~ znp}8cmo=QY+g?7sP&2U(%doi4p$?q%dpR!{XbIFiV(&h?F5`Y0ByNYgp+l(spZ$}~pLk-^Tm34wo_FqY#(6tV<(T){ms#dz|1ss<(^=+q*`IV% zeBaw?-uNLQ^}K(+%rURaiM;cc-AX;LsHGSFFpvTT>Av4QZ^MpM^NM|$c}kYkTeF-_ zNHs6ow06^ld@kkL`u%`NlT5h>_UzdsarmIbKErzs?K-??;_w%S4jR$>1?;K30mBw9 z?G#DO9@HH)G_hyb?k^;EQErzaiQT*Q?>?eGmn`fvHS%P)#DYUcbR9Un&+svcg%bx4 z?bE$yp<+Rc;e&>%$v(sWw|bAn?t_L6PwX==?4rx?LBqTDAJ!$YN1yJ)`wSY`b?BI4 zK}-7X*Kc>(hJSfSv<~ zCk`7kaCq0z6}^>V9dzaMiB Date: Sat, 19 Jul 2025 19:00:04 +0200 Subject: [PATCH 12/16] hints --- core/chapters/c12_dictionaries.py | 23 ++++-- translations/english.po | 69 ++++++++++++++++-- .../locales/en/LC_MESSAGES/futurecoder.mo | Bin 319283 -> 320889 bytes 3 files changed, 77 insertions(+), 15 deletions(-) diff --git a/core/chapters/c12_dictionaries.py b/core/chapters/c12_dictionaries.py index 73d674e0..d0f97293 100644 --- a/core/chapters/c12_dictionaries.py +++ b/core/chapters/c12_dictionaries.py @@ -993,13 +993,22 @@ def make_english_to_german(english_to_french, french_to_german): parsons_solution = True hints = """ - You need to create a new empty dictionary, let's call it `english_to_german`. - Iterate through the keys (English words) of the `english_to_french` dictionary. - Inside the loop, for each `english` word: - 1. Find the corresponding French word using `english_to_french`. - 2. Use that French word as a key to find the German word in `french_to_german`. - 3. Add the `english` word as a key and the `german` word as the value to your new `english_to_german` dictionary. - After the loop, return the `english_to_german` dictionary. + You need to create a new dictionary and fill it with key-value pairs depending on the two input dictionaries. + You've seen code that does this before. + Specifically the previous step. The overall structure you want is similar to `total_cost_per_item`. + Start by creating a new empty dictionary. + Return the dictionary at the end. Then fill in the code in between. + You need a `for` loop. + The line `totals[item] = quantities[item] * prices[item]` from the previous step is close to what you need. + You don't need to multiply anything with `*`, the names are different, and there's another difference in logic. + Think about what the keys and values of the new dictionary should be. + The keys should be English words, so they should come from the first dictionary. + The values should be German words, so they should come from the second dictionary. + Specifically the keys of your dictionary should be the keys of the first dictionary. + And the values of your dictionary should be the values of the second dictionary. + What about the values of the first dictionary and the keys of the second dictionary? They're important. + Look at the French words `'pomme'` and `'boite'` in the example test. + The values of the first input dictionary are the keys of the second input dictionary. """ def solution(self): diff --git a/translations/english.po b/translations/english.po index ffb0afaa..fcfecdf9 100644 --- a/translations/english.po +++ b/translations/english.po @@ -23925,44 +23925,97 @@ msgstr "" #. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise msgid "pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise.hints.0.text" -msgstr "You need to create a new empty dictionary, let's call it `english_to_german`." +msgstr "You need to create a new dictionary and fill it with key-value pairs depending on the two input dictionaries." #. https://futurecoder.io/course/#CreatingKeyValuePairs #. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise msgid "pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise.hints.1.text" -msgstr "Iterate through the keys (English words) of the `english_to_french` dictionary." +msgstr "You've seen code that does this before." + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise +msgid "pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise.hints.10.text" +msgstr "The values should be German words, so they should come from the second dictionary." + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise +msgid "pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise.hints.11.text" +msgstr "Specifically the keys of your dictionary should be the keys of the first dictionary." + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise +msgid "pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise.hints.12.text" +msgstr "And the values of your dictionary should be the values of the second dictionary." + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise +msgid "pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise.hints.13.text" +msgstr "What about the values of the first dictionary and the keys of the second dictionary? They're important." + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise +msgid "pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise.hints.14.text" +msgstr "Look at the French words `'pomme'` and `'boite'` in the example test." + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise +msgid "pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise.hints.15.text" +msgstr "The values of the first input dictionary are the keys of the second input dictionary." #. https://futurecoder.io/course/#CreatingKeyValuePairs #. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise msgid "pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise.hints.2.text" -msgstr "Inside the loop, for each `english` word:" +msgstr "Specifically the previous step. The overall structure you want is similar to `total_cost_per_item`." #. https://futurecoder.io/course/#CreatingKeyValuePairs #. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise msgid "pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise.hints.3.text" -msgstr "1. Find the corresponding French word using `english_to_french`." +msgstr "Start by creating a new empty dictionary." #. https://futurecoder.io/course/#CreatingKeyValuePairs #. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise msgid "pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise.hints.4.text" -msgstr "2. Use that French word as a key to find the German word in `french_to_german`." +msgstr "Return the dictionary at the end. Then fill in the code in between." #. https://futurecoder.io/course/#CreatingKeyValuePairs #. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise msgid "pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise.hints.5.text" -msgstr "" -"3. Add the `english` word as a key and the `german` word as the value to your new `english_to_german` dictionary." +msgstr "You need a `for` loop." #. https://futurecoder.io/course/#CreatingKeyValuePairs #. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise msgid "pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise.hints.6.text" -msgstr "After the loop, return the `english_to_german` dictionary." +msgstr "The line `totals[item] = quantities[item] * prices[item]` from the previous step is close to what you need." + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise +msgid "pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise.hints.7.text" +msgstr "You don't need to multiply anything with `*`, the names are different, and there's another difference in logic." + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise +msgid "pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise.hints.8.text" +msgstr "Think about what the keys and values of the new dictionary should be." + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise +msgid "pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise.hints.9.text" +msgstr "The keys should be English words, so they should come from the first dictionary." #. https://futurecoder.io/course/#CreatingKeyValuePairs #. diff --git a/translations/locales/en/LC_MESSAGES/futurecoder.mo b/translations/locales/en/LC_MESSAGES/futurecoder.mo index 10bc8134abfe1afbe0915cd862aad1f9c28d9ef7..990407d7c8df4720c5c103a679bacbe36e895258 100644 GIT binary patch delta 29196 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 Date: Sat, 19 Jul 2025 19:15:23 +0200 Subject: [PATCH 13/16] hints --- core/chapters/c12_dictionaries.py | 17 +++++----- translations/english.po | 29 +++++++++++++----- .../locales/en/LC_MESSAGES/futurecoder.mo | Bin 320889 -> 321457 bytes 3 files changed, 31 insertions(+), 15 deletions(-) diff --git a/core/chapters/c12_dictionaries.py b/core/chapters/c12_dictionaries.py index d0f97293..ea843df4 100644 --- a/core/chapters/c12_dictionaries.py +++ b/core/chapters/c12_dictionaries.py @@ -1040,7 +1040,8 @@ class swap_keys_values_exercise(ExerciseStep): Great job! Of course, language isn't so simple, and there are many ways that using a dictionary like this could go wrong. - So...let's do something even worse! Write a function which takes a dictionary and swaps the keys and values, + So...let's do something even worse! Let's use an English-to-French dictionary to create a French-to-English dictionary. + Write a function which takes a dictionary returns a new dictionary where the keys and values are swapped, so `a: b` becomes `b: a`. __copyable__ @@ -1053,12 +1054,14 @@ def swap_keys_values(d): ) """ hints = """ - Create a new empty dictionary to store the result. - Iterate through the keys of the input dictionary `d`. - Inside the loop, for each `key`: - 1. Get the corresponding `value` from `d`. - 2. Add an entry to the new dictionary where the *key* is the original `value` and the *value* is the original `key`. - Return the new dictionary after the loop. + Don't modify the input dictionary `d`. + You need to create a new dictionary and fill it with key-value pairs depending on the input dictionary. + You've done this in the previous exercise. The overall structure you want is similar to `make_english_to_german`. + It's actually even simpler, it just might feel weird. + Start by creating a new empty dictionary. Return the dictionary at the end. Put a `for` loop in between. + Think about what the keys and values of the new dictionary should be. + There's only one possible thing for you to loop over. + Use each key in the input dictionary `d` to get the corresponding value. """ def solution(self): diff --git a/translations/english.po b/translations/english.po index fcfecdf9..6f4ea8a6 100644 --- a/translations/english.po +++ b/translations/english.po @@ -24065,38 +24065,50 @@ msgstr "" #. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.swap_keys_values_exercise msgid "pages.CreatingKeyValuePairs.steps.swap_keys_values_exercise.hints.0.text" -msgstr "Create a new empty dictionary to store the result." +msgstr "Don't modify the input dictionary `d`." #. https://futurecoder.io/course/#CreatingKeyValuePairs #. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.swap_keys_values_exercise msgid "pages.CreatingKeyValuePairs.steps.swap_keys_values_exercise.hints.1.text" -msgstr "Iterate through the keys of the input dictionary `d`." +msgstr "You need to create a new dictionary and fill it with key-value pairs depending on the input dictionary." #. https://futurecoder.io/course/#CreatingKeyValuePairs #. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.swap_keys_values_exercise msgid "pages.CreatingKeyValuePairs.steps.swap_keys_values_exercise.hints.2.text" -msgstr "Inside the loop, for each `key`:" +msgstr "" +"You've done this in the previous exercise. The overall structure you want is similar to `make_english_to_german`." #. https://futurecoder.io/course/#CreatingKeyValuePairs #. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.swap_keys_values_exercise msgid "pages.CreatingKeyValuePairs.steps.swap_keys_values_exercise.hints.3.text" -msgstr "1. Get the corresponding `value` from `d`." +msgstr "It's actually even simpler, it just might feel weird." #. https://futurecoder.io/course/#CreatingKeyValuePairs #. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.swap_keys_values_exercise msgid "pages.CreatingKeyValuePairs.steps.swap_keys_values_exercise.hints.4.text" -msgstr "" -"2. Add an entry to the new dictionary where the *key* is the original `value` and the *value* is the original `key`." +msgstr "Start by creating a new empty dictionary. Return the dictionary at the end. Put a `for` loop in between." #. https://futurecoder.io/course/#CreatingKeyValuePairs #. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.swap_keys_values_exercise msgid "pages.CreatingKeyValuePairs.steps.swap_keys_values_exercise.hints.5.text" -msgstr "Return the new dictionary after the loop." +msgstr "Think about what the keys and values of the new dictionary should be." + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.swap_keys_values_exercise +msgid "pages.CreatingKeyValuePairs.steps.swap_keys_values_exercise.hints.6.text" +msgstr "There's only one possible thing for you to loop over." + +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.swap_keys_values_exercise +msgid "pages.CreatingKeyValuePairs.steps.swap_keys_values_exercise.hints.7.text" +msgstr "Use each key in the input dictionary `d` to get the corresponding value." #. https://futurecoder.io/course/#CreatingKeyValuePairs #. @@ -24125,7 +24137,8 @@ msgstr "" "Great job!\n" "\n" "Of course, language isn't so simple, and there are many ways that using a dictionary like this could go wrong.\n" -"So...let's do something even worse! Write a function which takes a dictionary and swaps the keys and values,\n" +"So...let's do something even worse! Let's use an English-to-French dictionary to create a French-to-English dictionary.\n" +"Write a function which takes a dictionary returns a new dictionary where the keys and values are swapped,\n" "so `a: b` becomes `b: a`.\n" "\n" " __copyable__\n" diff --git a/translations/locales/en/LC_MESSAGES/futurecoder.mo b/translations/locales/en/LC_MESSAGES/futurecoder.mo index 990407d7c8df4720c5c103a679bacbe36e895258..1d60b6fc3b4f2b6c778510637c070b4b4eaa2078 100644 GIT binary patch delta 28440 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 delta 28204 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 tdSv$E|E5Pu=2KfkM Date: Sat, 19 Jul 2025 19:35:25 +0200 Subject: [PATCH 14/16] avocado_or_lawyer --- core/chapters/c12_dictionaries.py | 25 +++- tests/golden_files/en/test_transcript.json | 24 +++ translations/english.po | 139 +++++++++++++++++- .../locales/en/LC_MESSAGES/futurecoder.mo | Bin 321457 -> 321938 bytes 4 files changed, 180 insertions(+), 8 deletions(-) diff --git a/core/chapters/c12_dictionaries.py b/core/chapters/c12_dictionaries.py index ea843df4..124d084b 100644 --- a/core/chapters/c12_dictionaries.py +++ b/core/chapters/c12_dictionaries.py @@ -1080,7 +1080,8 @@ def swap_keys_values(d: Dict[str, str]): (({},), {}), ] - final_text = """ + class avocado_or_lawyer(VerbatimStep): + """ Magnificent! Jokes aside, it's important to remember how exactly this can go wrong. Just like multiple items in the store @@ -1088,6 +1089,28 @@ def swap_keys_values(d: Dict[str, str]): has duplicate *values*, what happens when you try to swap keys and values? Since dictionary keys must be unique, some data will be lost. +For example, 'avocat' in French can mean either 'avocado' and 'lawyer'. So it's easy to translate +'avocado' from English to French, but it's not so clear how to translate 'avocat' back to English. +Try to guess what the following code will print: + + __copyable__ + __program_indented__ + """ + + def program(self): + def swap_keys_values(d): + new_dict = {} + for key in d: + new_dict[d[key]] = key + return new_dict + + print(swap_keys_values({'apple': 'pomme', 'avocado': 'avocat', 'lawyer': 'avocat'})) + print(swap_keys_values({'apple': 'pomme', 'lawyer': 'avocat', 'avocado': 'avocat'})) + + final_text = """ +The result depends on the order of the keys in the original dictionary! +If you're not sure why, try running the code with `snoop` or another debugger. + But there are many situations where you can be sure that the values in a dictionary *are* unique and that this 'inversion' makes sense. For example, we saw this code [earlier in the chapter](#UsingDictionaries): diff --git a/tests/golden_files/en/test_transcript.json b/tests/golden_files/en/test_transcript.json index 3e130ecd..b80e04aa 100644 --- a/tests/golden_files/en/test_transcript.json +++ b/tests/golden_files/en/test_transcript.json @@ -7571,6 +7571,30 @@ }, "step": "swap_keys_values_exercise" }, + { + "get_solution": "program", + "page": "Creating Key-Value Pairs", + "program": [ + "def swap_keys_values(d):", + " new_dict = {}", + " for key in d:", + " new_dict[d[key]] = key", + " return new_dict", + "", + "print(swap_keys_values({'apple': 'pomme', 'avocado': 'avocat', 'lawyer': 'avocat'}))", + "print(swap_keys_values({'apple': 'pomme', 'lawyer': 'avocat', 'avocado': 'avocat'}))" + ], + "response": { + "passed": true, + "result": [ + { + "text": "{'pomme': 'apple', 'avocat': 'lawyer'}\n{'pomme': 'apple', 'avocat': 'avocado'}\n", + "type": "stdout" + } + ] + }, + "step": "avocado_or_lawyer" + }, { "get_solution": "program", "page": "Copying Dictionaries", diff --git a/translations/english.po b/translations/english.po index 6f4ea8a6..95c6a454 100644 --- a/translations/english.po +++ b/translations/english.po @@ -3503,6 +3503,19 @@ msgstr "'apfel'" #. #. ------ #. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.avocado_or_lawyer +#. +#. def swap_keys_values(d): +#. new_dict = {} +#. for key in d: +#. new_dict[d[key]] = key +#. return new_dict +#. +#. print(swap_keys_values({'apple': 'pomme', 'avocado': 'avocat', 'lawyer': 'avocat'})) +#. print(swap_keys_values({'apple': 'pomme', 'lawyer': 'avocat', 'avocado': 'avocat'})) +#. +#. ------ +#. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise.text #. #. def make_english_to_german(english_to_french, french_to_german): @@ -3729,6 +3742,32 @@ msgstr "'apple'" msgid "code_bits.'are'" msgstr "'are'" +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.avocado_or_lawyer +#. +#. def swap_keys_values(d): +#. new_dict = {} +#. for key in d: +#. new_dict[d[key]] = key +#. return new_dict +#. +#. print(swap_keys_values({'apple': 'pomme', 'avocado': 'avocat', 'lawyer': 'avocat'})) +#. print(swap_keys_values({'apple': 'pomme', 'lawyer': 'avocat', 'avocado': 'avocat'})) +msgid "code_bits.'avocado'" +msgstr "'avocado'" + +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.avocado_or_lawyer +#. +#. def swap_keys_values(d): +#. new_dict = {} +#. for key in d: +#. new_dict[d[key]] = key +#. return new_dict +#. +#. print(swap_keys_values({'apple': 'pomme', 'avocado': 'avocat', 'lawyer': 'avocat'})) +#. print(swap_keys_values({'apple': 'pomme', 'lawyer': 'avocat', 'avocado': 'avocat'})) +msgid "code_bits.'avocat'" +msgstr "'avocat'" + #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.add_item_exercise.text #. #. def add_item(item, quantities): @@ -4775,6 +4814,19 @@ msgstr "'kasten'" msgid "code_bits.'kesha'" msgstr "'kesha'" +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.avocado_or_lawyer +#. +#. def swap_keys_values(d): +#. new_dict = {} +#. for key in d: +#. new_dict[d[key]] = key +#. return new_dict +#. +#. print(swap_keys_values({'apple': 'pomme', 'avocado': 'avocat', 'lawyer': 'avocat'})) +#. print(swap_keys_values({'apple': 'pomme', 'lawyer': 'avocat', 'avocado': 'avocat'})) +msgid "code_bits.'lawyer'" +msgstr "'lawyer'" + #. https://poeditor.com/projects/view_terms?id=490053&search=pages.IntroducingLists.steps.strings_sum #. #. words = ['This', 'is', 'a', 'list'] @@ -4932,6 +4984,19 @@ msgstr "'pen'" msgid "code_bits.'pencil'" msgstr "'pencil'" +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.avocado_or_lawyer +#. +#. def swap_keys_values(d): +#. new_dict = {} +#. for key in d: +#. new_dict[d[key]] = key +#. return new_dict +#. +#. print(swap_keys_values({'apple': 'pomme', 'avocado': 'avocat', 'lawyer': 'avocat'})) +#. print(swap_keys_values({'apple': 'pomme', 'lawyer': 'avocat', 'avocado': 'avocat'})) +#. +#. ------ +#. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.make_english_to_german_exercise.text #. #. def make_english_to_german(english_to_french, french_to_german): @@ -5145,6 +5210,12 @@ msgstr "___" #. #. ------ #. +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.avocado_or_lawyer.text +#. +#. __program_indented__ +#. +#. ------ +#. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_input_test.text #. #. __program_indented__ @@ -12356,6 +12427,19 @@ msgstr "joined_row" msgid "code_bits.joined_rows" msgstr "joined_rows" +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.avocado_or_lawyer +#. +#. def swap_keys_values(d): +#. new_dict = {} +#. for key in d: +#. new_dict[d[key]] = key +#. return new_dict +#. +#. print(swap_keys_values({'apple': 'pomme', 'avocado': 'avocat', 'lawyer': 'avocat'})) +#. print(swap_keys_values({'apple': 'pomme', 'lawyer': 'avocat', 'avocado': 'avocat'})) +#. +#. ------ +#. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.swap_keys_values_exercise #. #. def swap_keys_values(d): @@ -14004,6 +14088,19 @@ msgstr "middle" msgid "code_bits.name" msgstr "name" +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.avocado_or_lawyer +#. +#. def swap_keys_values(d): +#. new_dict = {} +#. for key in d: +#. new_dict[d[key]] = key +#. return new_dict +#. +#. print(swap_keys_values({'apple': 'pomme', 'avocado': 'avocat', 'lawyer': 'avocat'})) +#. print(swap_keys_values({'apple': 'pomme', 'lawyer': 'avocat', 'avocado': 'avocat'})) +#. +#. ------ +#. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.swap_keys_values_exercise #. #. def swap_keys_values(d): @@ -19639,6 +19736,19 @@ msgstr "super_secret_number" msgid "code_bits.surround" msgstr "surround" +#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.avocado_or_lawyer +#. +#. def swap_keys_values(d): +#. new_dict = {} +#. for key in d: +#. new_dict[d[key]] = key +#. return new_dict +#. +#. print(swap_keys_values({'apple': 'pomme', 'avocado': 'avocat', 'lawyer': 'avocat'})) +#. print(swap_keys_values({'apple': 'pomme', 'lawyer': 'avocat', 'avocado': 'avocat'})) +#. +#. ------ +#. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.final_text.text #. #. reverse = swap_keys_values(letters) @@ -23577,6 +23687,28 @@ msgstr "" msgid "pages.CopyingDictionaries.title" msgstr "Copying Dictionaries" +#. https://futurecoder.io/course/#CreatingKeyValuePairs +#. +#. # __code0__: +#. __program_indented__ +#. +#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.__program_indented__ +msgid "pages.CreatingKeyValuePairs.steps.avocado_or_lawyer.text" +msgstr "" +"Magnificent!\n" +"\n" +"Jokes aside, it's important to remember how exactly this can go wrong. Just like multiple items in the store\n" +"can have the same price, multiple words in English can have the same translation in French. If the original dictionary\n" +"has duplicate *values*, what happens when you try to swap keys and values? Since dictionary keys must be unique,\n" +"some data will be lost.\n" +"\n" +"For example, 'avocat' in French can mean either 'avocado' and 'lawyer'. So it's easy to translate\n" +"'avocado' from English to French, but it's not so clear how to translate 'avocat' back to English.\n" +"Try to guess what the following code will print:\n" +"\n" +" __copyable__\n" +"__code0__" + #. https://futurecoder.io/course/#CreatingKeyValuePairs #. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise @@ -23762,13 +23894,6 @@ msgstr "" #. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.swap_keys_values msgid "pages.CreatingKeyValuePairs.steps.final_text.text" msgstr "" -"Magnificent!\n" -"\n" -"Jokes aside, it's important to remember how exactly this can go wrong. Just like multiple items in the store\n" -"can have the same price, multiple words in English can have the same translation in French. If the original dictionary\n" -"has duplicate *values*, what happens when you try to swap keys and values? Since dictionary keys must be unique,\n" -"some data will be lost.\n" -"\n" "But there are many situations where you can be sure that the values in a dictionary *are* unique and that this\n" "'inversion' makes sense. For example, we saw this code [earlier in the chapter](#UsingDictionaries):\n" "\n" diff --git a/translations/locales/en/LC_MESSAGES/futurecoder.mo b/translations/locales/en/LC_MESSAGES/futurecoder.mo index 1d60b6fc3b4f2b6c778510637c070b4b4eaa2078..032176da608be415cf6ebdcc9adfa1437b3adddb 100644 GIT binary patch delta 28343 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 n89H>~z5$UU3*UGzR&Z;r~as&KMOdKJfnlb?0sY delta 28050 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

~g8wx1M+g+7flnGo!nf0{CXs*@7vyOg2|qxT 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 From eed00112d0e9eebbe87e1bd1669c6cbe4ad959cf Mon Sep 17 00:00:00 2001 From: Alex Hall Date: Sat, 19 Jul 2025 19:38:23 +0200 Subject: [PATCH 15/16] Remove CopyingDictionaries for now --- core/chapters/c12_dictionaries.py | 241 ----- tests/golden_files/en/test_transcript.json | 105 -- translations/english.po | 996 +----------------- .../locales/en/LC_MESSAGES/futurecoder.mo | Bin 321938 -> 315077 bytes 4 files changed, 3 insertions(+), 1339 deletions(-) diff --git a/core/chapters/c12_dictionaries.py b/core/chapters/c12_dictionaries.py index 124d084b..5e59507f 100644 --- a/core/chapters/c12_dictionaries.py +++ b/core/chapters/c12_dictionaries.py @@ -1137,244 +1137,3 @@ def substitute(string, d): Otherwise it would be impossible to decrypt messages properly. If both `'h'` and `'j'` got replaced with `'q'` during encryption, there would be no way to know whether `'qpeef'` means `'hello'` or `'jello'`! """ - - -class CopyingDictionaries(Page): - title = "Copying Dictionaries" - - class shared_references(VerbatimStep): - """ - Remember how assigning one list variable to another (`list2 = list1`) made both names point to the *same* list? Dictionaries work the same way because they are also *mutable* (can be changed). - - Predict what the following code will print, then run it to see: - - __copyable__ - __program_indented__ - """ - def program(self): - d1 = {'a': 1, 'b': 2} - d2 = d1 - - print("d1 before:", d1) - print("d2 before:", d2) - print("Are they the same object?", d1 is d2) - - d2['c'] = 3 # Modify via d2 - - print("d1 after:", d1) # Is d1 affected? - print("d2 after:", d2) - - predicted_output_choices = [ - # Incorrect prediction (d1 unaffected) - """d1 before: {'a': 1, 'b': 2} -d2 before: {'a': 1, 'b': 2} -Are they the same object? True -d1 after: {'a': 1, 'b': 2} -d2 after: {'a': 1, 'b': 2, 'c': 3}""", - - # Correct prediction - """d1 before: {'a': 1, 'b': 2} -d2 before: {'a': 1, 'b': 2} -Are they the same object? True -d1 after: {'a': 1, 'b': 2, 'c': 3} -d2 after: {'a': 1, 'b': 2, 'c': 3}""", - - # Incorrect prediction (is False) - """d1 before: {'a': 1, 'b': 2} -d2 before: {'a': 1, 'b': 2} -Are they the same object? False -d1 after: {'a': 1, 'b': 2} -d2 after: {'a': 1, 'b': 2, 'c': 3}""", - ] - - class making_copies(VerbatimStep): - """ - Because `d1` and `d2` referred to the exact same dictionary object (`d1 is d2` was `True`), changing it via `d2` also changed what `d1` saw. - - To get a *separate* dictionary with the same contents, use the `.copy()` method. - - Predict how using `.copy()` changes the outcome, then run this code: - - __copyable__ - __program_indented__ - """ - def program(self): - d1 = {'a': 1, 'b': 2} - d2 = d1.copy() # Create a separate copy - - print("d1 before:", d1) - print("d2 before:", d2) - print("Are they the same object?", d1 is d2) - - d2['c'] = 3 # Modify the copy - - print("d1 after:", d1) # Is d1 affected now? - print("d2 after:", d2) - - predicted_output_choices = [ - # Incorrect prediction (is True) - """d1 before: {'a': 1, 'b': 2} -d2 before: {'a': 1, 'b': 2} -Are they the same object? True -d1 after: {'a': 1, 'b': 2, 'c': 3} -d2 after: {'a': 1, 'b': 2, 'c': 3}""", - - # Incorrect prediction (d1 affected) - """d1 before: {'a': 1, 'b': 2} -d2 before: {'a': 1, 'b': 2} -Are they the same object? False -d1 after: {'a': 1, 'b': 2, 'c': 3} -d2 after: {'a': 1, 'b': 2, 'c': 3}""", - - # Correct prediction - """d1 before: {'a': 1, 'b': 2} -d2 before: {'a': 1, 'b': 2} -Are they the same object? False -d1 after: {'a': 1, 'b': 2} -d2 after: {'a': 1, 'b': 2, 'c': 3}""", - ] - - class positive_stock_exercise(ExerciseStep): - """ - Making an exact copy is useful, but often we want a *modified* copy. Let's practice creating a new dictionary based on an old one. - - Write a function `positive_stock(stock)` that takes a dictionary `stock` (mapping item names to integer quantities) and returns a *new* dictionary containing only the items from the original `stock` where the quantity is strictly greater than 0. The original `stock` dictionary should not be changed. - - __copyable__ - def positive_stock(stock): - # Your code here - ... - - assert_equal( - positive_stock({'apple': 10, 'banana': 0, 'pear': 5, 'orange': 0}), - {'apple': 10, 'pear': 5} - ) - assert_equal( - positive_stock({'pen': 0, 'pencil': 0}), - {} - ) - assert_equal( - positive_stock({'book': 1, 'paper': 5}), - {'book': 1, 'paper': 5} - ) - """ - hints = """ - Start by creating a new empty dictionary, e.g., `result = {}`. - Loop through the keys of the input `stock` dictionary. - Inside the loop, get the `quantity` for the current `item` using `stock[item]`. - Use an `if` statement to check if `quantity > 0`. - If the quantity is positive, add the `item` and its `quantity` to your `result` dictionary using `result[item] = quantity`. - After the loop finishes, return the `result` dictionary. - Make sure you don't modify the original `stock` dictionary passed into the function. Creating a new `result` dictionary ensures this. - """ - - def solution(self): - def positive_stock(stock: Dict[str, int]): - result = {} - for item in stock: - quantity = stock[item] - if quantity > 0: - result[item] = quantity - return result - return positive_stock - - tests = [ - (({'apple': 10, 'banana': 0, 'pear': 5, 'orange': 0},), {'apple': 10, 'pear': 5}), - (({'pen': 0, 'pencil': 0},), {}), - (({'book': 1, 'paper': 5},), {'book': 1, 'paper': 5}), - (({},), {}), # Empty input - (({'gadget': -5, 'widget': 3},), {'widget': 3}), # Negative values - ] - - @classmethod - def generate_inputs(cls): - # Generate a dictionary with some zero/negative and positive values - stock = {} - num_items = random.randint(3, 8) - for _ in range(num_items): - item = generate_string(random.randint(3, 6)) - # Ensure some variety in quantities - if random.random() < 0.4: - quantity = 0 - elif random.random() < 0.2: - quantity = random.randint(-5, -1) - else: - quantity = random.randint(1, 20) - stock[item] = quantity - # Ensure at least one positive if dict not empty - if stock and all(q <= 0 for q in stock.values()): - stock[generate_string(4)] = random.randint(1, 10) - return {"stock": stock} - - class add_item_exercise(ExerciseStep): - """ - Let's practice combining copying and modifying. Imagine we want to represent adding one unit of an item to our stock count. - - Write a function `add_item(item, quantities)` that takes an item name (`item`) and a dictionary `quantities`. You can assume the `item` *already exists* as a key in the `quantities` dictionary. - - The function should return a *new* dictionary which is a copy of `quantities`, but with the value associated with `item` increased by 1. The original `quantities` dictionary should not be changed. - - __copyable__ - def add_item(item, quantities): - # Your code here - ... - - stock = {'apple': 5, 'banana': 2} - new_stock = add_item('apple', stock) - assert_equal(stock, {'apple': 5, 'banana': 2}) # Original unchanged - assert_equal(new_stock, {'apple': 6, 'banana': 2}) # Copy has incremented value - - new_stock_2 = add_item('banana', new_stock) - assert_equal(new_stock, {'apple': 6, 'banana': 2}) # Previous copy unchanged - assert_equal(new_stock_2, {'apple': 6, 'banana': 3}) # New copy incremented - """ - hints = """ - First, create a *copy* of the input `quantities` dictionary using the `.copy()` method. Store this in a new variable, e.g., `new_quantities`. - Since we assume `item` is already a key, you don't need to check for its existence in this exercise. - Find the current quantity of the `item` in the `new_quantities` copy using `new_quantities[item]`. - Calculate the new quantity by adding 1 to the current quantity. - Update the value for `item` in the `new_quantities` copy with this new quantity using assignment: `new_quantities[item] = ...`. - Return the `new_quantities` dictionary. - """ - - def solution(self): - def add_item(item: str, quantities: Dict[str, int]): - new_quantities = quantities.copy() - new_quantities[item] = new_quantities[item] + 1 - return new_quantities - return add_item - - tests = [ - (('apple', {'apple': 5, 'banana': 2}), {'apple': 6, 'banana': 2}), - (('banana', {'apple': 6, 'banana': 2}), {'apple': 6, 'banana': 3}), - (('pen', {'pen': 1}), {'pen': 2}), - (('a', {'a': 0, 'b': 99}), {'a': 1, 'b': 99}), - ] - - @classmethod - def generate_inputs(cls): - quantities = generate_dict(str, int) - # Ensure the dictionary is not empty - if not quantities: - quantities[generate_string(4)] = random.randint(0, 10) - # Pick an existing item to increment - item = random.choice(list(quantities.keys())) - return {"item": item, "quantities": quantities} - - final_text = """ - Well done! Notice that the line where you increment the value: - - new_quantities[item] = new_quantities[item] + 1 - - can also be written more concisely using the `+=` operator, just like with numbers: - - new_quantities[item] += 1 - - This does the same thing: it reads the current value, adds 1, and assigns the result back. - """ - - final_text = """ - Great! You now know why copying dictionaries is important (because they are mutable) and how to do it using `.copy()`. You've also practiced creating modified copies, which is a common and safe way to work with data without accidentally changing things elsewhere in your program. - - Next, we'll see how to check if a key exists *before* trying to use it, to avoid errors. - """ diff --git a/tests/golden_files/en/test_transcript.json b/tests/golden_files/en/test_transcript.json index b80e04aa..fb3ddaa8 100644 --- a/tests/golden_files/en/test_transcript.json +++ b/tests/golden_files/en/test_transcript.json @@ -7594,110 +7594,5 @@ ] }, "step": "avocado_or_lawyer" - }, - { - "get_solution": "program", - "page": "Copying Dictionaries", - "program": [ - "d1 = {'a': 1, 'b': 2}", - "d2 = d1", - "", - "print(\"d1 before:\", d1)", - "print(\"d2 before:\", d2)", - "print(\"Are they the same object?\", d1 is d2)", - "", - "d2['c'] = 3 # Modify via d2", - "", - "print(\"d1 after:\", d1) # Is d1 affected?", - "print(\"d2 after:\", d2)" - ], - "response": { - "passed": true, - "prediction": { - "answer": "d1 before: {'a': 1, 'b': 2}\nd2 before: {'a': 1, 'b': 2}\nAre they the same object? True\nd1 after: {'a': 1, 'b': 2, 'c': 3}\nd2 after: {'a': 1, 'b': 2, 'c': 3}", - "choices": [ - "d1 before: {'a': 1, 'b': 2}\nd2 before: {'a': 1, 'b': 2}\nAre they the same object? True\nd1 after: {'a': 1, 'b': 2}\nd2 after: {'a': 1, 'b': 2, 'c': 3}", - "d1 before: {'a': 1, 'b': 2}\nd2 before: {'a': 1, 'b': 2}\nAre they the same object? True\nd1 after: {'a': 1, 'b': 2, 'c': 3}\nd2 after: {'a': 1, 'b': 2, 'c': 3}", - "d1 before: {'a': 1, 'b': 2}\nd2 before: {'a': 1, 'b': 2}\nAre they the same object? False\nd1 after: {'a': 1, 'b': 2}\nd2 after: {'a': 1, 'b': 2, 'c': 3}", - "Error" - ] - }, - "result": [ - { - "text": "d1 before: {'a': 1, 'b': 2}\nd2 before: {'a': 1, 'b': 2}\nAre they the same object? True\nd1 after: {'a': 1, 'b': 2, 'c': 3}\nd2 after: {'a': 1, 'b': 2, 'c': 3}\n", - "type": "stdout" - } - ] - }, - "step": "shared_references" - }, - { - "get_solution": "program", - "page": "Copying Dictionaries", - "program": [ - "d1 = {'a': 1, 'b': 2}", - "d2 = d1.copy() # Create a separate copy", - "", - "print(\"d1 before:\", d1)", - "print(\"d2 before:\", d2)", - "print(\"Are they the same object?\", d1 is d2)", - "", - "d2['c'] = 3 # Modify the copy", - "", - "print(\"d1 after:\", d1) # Is d1 affected now?", - "print(\"d2 after:\", d2)" - ], - "response": { - "passed": true, - "prediction": { - "answer": "d1 before: {'a': 1, 'b': 2}\nd2 before: {'a': 1, 'b': 2}\nAre they the same object? False\nd1 after: {'a': 1, 'b': 2}\nd2 after: {'a': 1, 'b': 2, 'c': 3}", - "choices": [ - "d1 before: {'a': 1, 'b': 2}\nd2 before: {'a': 1, 'b': 2}\nAre they the same object? True\nd1 after: {'a': 1, 'b': 2, 'c': 3}\nd2 after: {'a': 1, 'b': 2, 'c': 3}", - "d1 before: {'a': 1, 'b': 2}\nd2 before: {'a': 1, 'b': 2}\nAre they the same object? False\nd1 after: {'a': 1, 'b': 2, 'c': 3}\nd2 after: {'a': 1, 'b': 2, 'c': 3}", - "d1 before: {'a': 1, 'b': 2}\nd2 before: {'a': 1, 'b': 2}\nAre they the same object? False\nd1 after: {'a': 1, 'b': 2}\nd2 after: {'a': 1, 'b': 2, 'c': 3}", - "Error" - ] - }, - "result": [ - { - "text": "d1 before: {'a': 1, 'b': 2}\nd2 before: {'a': 1, 'b': 2}\nAre they the same object? False\nd1 after: {'a': 1, 'b': 2}\nd2 after: {'a': 1, 'b': 2, 'c': 3}\n", - "type": "stdout" - } - ] - }, - "step": "making_copies" - }, - { - "get_solution": "program", - "page": "Copying Dictionaries", - "program": [ - "def positive_stock(stock):", - " result = {}", - " for item in stock:", - " quantity = stock[item]", - " if quantity > 0:", - " result[item] = quantity", - " return result" - ], - "response": { - "passed": true, - "result": [] - }, - "step": "positive_stock_exercise" - }, - { - "get_solution": "program", - "page": "Copying Dictionaries", - "program": [ - "def add_item(item, quantities):", - " new_quantities = quantities.copy()", - " new_quantities[item] = new_quantities[item] + 1", - " return new_quantities" - ], - "response": { - "passed": true, - "result": [] - }, - "step": "add_item_exercise" } ] \ No newline at end of file diff --git a/translations/english.po b/translations/english.po index 95c6a454..da65d6e6 100644 --- a/translations/english.po +++ b/translations/english.po @@ -536,38 +536,6 @@ msgstr "\"Alice's Diner\"" msgid "code_bits.\"Amazing! Are you psychic?\"" msgstr "\"Amazing! Are you psychic?\"" -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.making_copies -#. -#. d1 = {'a': 1, 'b': 2} -#. d2 = d1.copy() # Create a separate copy -#. -#. print("d1 before:", d1) -#. print("d2 before:", d2) -#. print("Are they the same object?", d1 is d2) -#. -#. d2['c'] = 3 # Modify the copy -#. -#. print("d1 after:", d1) # Is d1 affected now? -#. print("d2 after:", d2) -#. -#. ------ -#. -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.shared_references -#. -#. d1 = {'a': 1, 'b': 2} -#. d2 = d1 -#. -#. print("d1 before:", d1) -#. print("d2 before:", d2) -#. print("Are they the same object?", d1 is d2) -#. -#. d2['c'] = 3 # Modify via d2 -#. -#. print("d1 after:", d1) # Is d1 affected? -#. print("d2 after:", d2) -msgid "code_bits.\"Are they the same object?\"" -msgstr "\"Are they the same object?\"" - #. https://poeditor.com/projects/view_terms?id=490053&search=pages.DefiningFunctions.steps.change_function_name #. #. def say_hello(name): @@ -1427,134 +1395,6 @@ msgstr "\"abc\"" msgid "code_bits.\"cat.jpg\"" msgstr "\"cat.jpg\"" -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.making_copies -#. -#. d1 = {'a': 1, 'b': 2} -#. d2 = d1.copy() # Create a separate copy -#. -#. print("d1 before:", d1) -#. print("d2 before:", d2) -#. print("Are they the same object?", d1 is d2) -#. -#. d2['c'] = 3 # Modify the copy -#. -#. print("d1 after:", d1) # Is d1 affected now? -#. print("d2 after:", d2) -#. -#. ------ -#. -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.shared_references -#. -#. d1 = {'a': 1, 'b': 2} -#. d2 = d1 -#. -#. print("d1 before:", d1) -#. print("d2 before:", d2) -#. print("Are they the same object?", d1 is d2) -#. -#. d2['c'] = 3 # Modify via d2 -#. -#. print("d1 after:", d1) # Is d1 affected? -#. print("d2 after:", d2) -msgid "code_bits.\"d1 after:\"" -msgstr "\"d1 after:\"" - -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.making_copies -#. -#. d1 = {'a': 1, 'b': 2} -#. d2 = d1.copy() # Create a separate copy -#. -#. print("d1 before:", d1) -#. print("d2 before:", d2) -#. print("Are they the same object?", d1 is d2) -#. -#. d2['c'] = 3 # Modify the copy -#. -#. print("d1 after:", d1) # Is d1 affected now? -#. print("d2 after:", d2) -#. -#. ------ -#. -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.shared_references -#. -#. d1 = {'a': 1, 'b': 2} -#. d2 = d1 -#. -#. print("d1 before:", d1) -#. print("d2 before:", d2) -#. print("Are they the same object?", d1 is d2) -#. -#. d2['c'] = 3 # Modify via d2 -#. -#. print("d1 after:", d1) # Is d1 affected? -#. print("d2 after:", d2) -msgid "code_bits.\"d1 before:\"" -msgstr "\"d1 before:\"" - -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.making_copies -#. -#. d1 = {'a': 1, 'b': 2} -#. d2 = d1.copy() # Create a separate copy -#. -#. print("d1 before:", d1) -#. print("d2 before:", d2) -#. print("Are they the same object?", d1 is d2) -#. -#. d2['c'] = 3 # Modify the copy -#. -#. print("d1 after:", d1) # Is d1 affected now? -#. print("d2 after:", d2) -#. -#. ------ -#. -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.shared_references -#. -#. d1 = {'a': 1, 'b': 2} -#. d2 = d1 -#. -#. print("d1 before:", d1) -#. print("d2 before:", d2) -#. print("Are they the same object?", d1 is d2) -#. -#. d2['c'] = 3 # Modify via d2 -#. -#. print("d1 after:", d1) # Is d1 affected? -#. print("d2 after:", d2) -msgid "code_bits.\"d2 after:\"" -msgstr "\"d2 after:\"" - -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.making_copies -#. -#. d1 = {'a': 1, 'b': 2} -#. d2 = d1.copy() # Create a separate copy -#. -#. print("d1 before:", d1) -#. print("d2 before:", d2) -#. print("Are they the same object?", d1 is d2) -#. -#. d2['c'] = 3 # Modify the copy -#. -#. print("d1 after:", d1) # Is d1 affected now? -#. print("d2 after:", d2) -#. -#. ------ -#. -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.shared_references -#. -#. d1 = {'a': 1, 'b': 2} -#. d2 = d1 -#. -#. print("d1 before:", d1) -#. print("d2 before:", d2) -#. print("Are they the same object?", d1 is d2) -#. -#. d2['c'] = 3 # Modify via d2 -#. -#. print("d1 after:", d1) # Is d1 affected? -#. print("d2 after:", d2) -msgid "code_bits.\"d2 before:\"" -msgstr "\"d2 before:\"" - #. https://poeditor.com/projects/view_terms?id=490053&search=pages.IntroducingNestedLists.steps.double_subscripting #. #. strings = ["abc", "def", "ghi"] @@ -3465,44 +3305,6 @@ msgstr "'aeiou'" msgid "code_bits.'apfel'" msgstr "'apfel'" -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.add_item_exercise.text -#. -#. def add_item(item, quantities): -#. # Your code here -#. ... -#. -#. stock = {'apple': 5, 'banana': 2} -#. new_stock = add_item('apple', stock) -#. assert_equal(stock, {'apple': 5, 'banana': 2}) # Original unchanged -#. assert_equal(new_stock, {'apple': 6, 'banana': 2}) # Copy has incremented value -#. -#. new_stock_2 = add_item('banana', new_stock) -#. assert_equal(new_stock, {'apple': 6, 'banana': 2}) # Previous copy unchanged -#. assert_equal(new_stock_2, {'apple': 6, 'banana': 3}) # New copy incremented -#. -#. ------ -#. -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.positive_stock_exercise.text -#. -#. def positive_stock(stock): -#. # Your code here -#. ... -#. -#. assert_equal( -#. positive_stock({'apple': 10, 'banana': 0, 'pear': 5, 'orange': 0}), -#. {'apple': 10, 'pear': 5} -#. ) -#. assert_equal( -#. positive_stock({'pen': 0, 'pencil': 0}), -#. {} -#. ) -#. assert_equal( -#. positive_stock({'book': 1, 'paper': 5}), -#. {'book': 1, 'paper': 5} -#. ) -#. -#. ------ -#. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.avocado_or_lawyer #. #. def swap_keys_values(d): @@ -3768,44 +3570,6 @@ msgstr "'avocado'" msgid "code_bits.'avocat'" msgstr "'avocat'" -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.add_item_exercise.text -#. -#. def add_item(item, quantities): -#. # Your code here -#. ... -#. -#. stock = {'apple': 5, 'banana': 2} -#. new_stock = add_item('apple', stock) -#. assert_equal(stock, {'apple': 5, 'banana': 2}) # Original unchanged -#. assert_equal(new_stock, {'apple': 6, 'banana': 2}) # Copy has incremented value -#. -#. new_stock_2 = add_item('banana', new_stock) -#. assert_equal(new_stock, {'apple': 6, 'banana': 2}) # Previous copy unchanged -#. assert_equal(new_stock_2, {'apple': 6, 'banana': 3}) # New copy incremented -#. -#. ------ -#. -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.positive_stock_exercise.text -#. -#. def positive_stock(stock): -#. # Your code here -#. ... -#. -#. assert_equal( -#. positive_stock({'apple': 10, 'banana': 0, 'pear': 5, 'orange': 0}), -#. {'apple': 10, 'pear': 5} -#. ) -#. assert_equal( -#. positive_stock({'pen': 0, 'pencil': 0}), -#. {} -#. ) -#. assert_equal( -#. positive_stock({'book': 1, 'paper': 5}), -#. {'book': 1, 'paper': 5} -#. ) -msgid "code_bits.'banana'" -msgstr "'banana'" - #. https://poeditor.com/projects/view_terms?id=490053&search=pages.TheEqualityOperator.steps.introducing_equality #. #. print(1 + 2 == 3) @@ -3892,27 +3656,6 @@ msgstr "'bc'" msgid "code_bits.'boite'" msgstr "'boite'" -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.positive_stock_exercise.text -#. -#. def positive_stock(stock): -#. # Your code here -#. ... -#. -#. assert_equal( -#. positive_stock({'apple': 10, 'banana': 0, 'pear': 5, 'orange': 0}), -#. {'apple': 10, 'pear': 5} -#. ) -#. assert_equal( -#. positive_stock({'pen': 0, 'pencil': 0}), -#. {} -#. ) -#. assert_equal( -#. positive_stock({'book': 1, 'paper': 5}), -#. {'book': 1, 'paper': 5} -#. ) -msgid "code_bits.'book'" -msgstr "'book'" - #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise.text #. #. def buy_quantity(quantities, item, quantity): @@ -4879,111 +4622,6 @@ msgstr "'list'" msgid "code_bits.'on'" msgstr "'on'" -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.positive_stock_exercise.text -#. -#. def positive_stock(stock): -#. # Your code here -#. ... -#. -#. assert_equal( -#. positive_stock({'apple': 10, 'banana': 0, 'pear': 5, 'orange': 0}), -#. {'apple': 10, 'pear': 5} -#. ) -#. assert_equal( -#. positive_stock({'pen': 0, 'pencil': 0}), -#. {} -#. ) -#. assert_equal( -#. positive_stock({'book': 1, 'paper': 5}), -#. {'book': 1, 'paper': 5} -#. ) -msgid "code_bits.'orange'" -msgstr "'orange'" - -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.positive_stock_exercise.text -#. -#. def positive_stock(stock): -#. # Your code here -#. ... -#. -#. assert_equal( -#. positive_stock({'apple': 10, 'banana': 0, 'pear': 5, 'orange': 0}), -#. {'apple': 10, 'pear': 5} -#. ) -#. assert_equal( -#. positive_stock({'pen': 0, 'pencil': 0}), -#. {} -#. ) -#. assert_equal( -#. positive_stock({'book': 1, 'paper': 5}), -#. {'book': 1, 'paper': 5} -#. ) -msgid "code_bits.'paper'" -msgstr "'paper'" - -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.positive_stock_exercise.text -#. -#. def positive_stock(stock): -#. # Your code here -#. ... -#. -#. assert_equal( -#. positive_stock({'apple': 10, 'banana': 0, 'pear': 5, 'orange': 0}), -#. {'apple': 10, 'pear': 5} -#. ) -#. assert_equal( -#. positive_stock({'pen': 0, 'pencil': 0}), -#. {} -#. ) -#. assert_equal( -#. positive_stock({'book': 1, 'paper': 5}), -#. {'book': 1, 'paper': 5} -#. ) -msgid "code_bits.'pear'" -msgstr "'pear'" - -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.positive_stock_exercise.text -#. -#. def positive_stock(stock): -#. # Your code here -#. ... -#. -#. assert_equal( -#. positive_stock({'apple': 10, 'banana': 0, 'pear': 5, 'orange': 0}), -#. {'apple': 10, 'pear': 5} -#. ) -#. assert_equal( -#. positive_stock({'pen': 0, 'pencil': 0}), -#. {} -#. ) -#. assert_equal( -#. positive_stock({'book': 1, 'paper': 5}), -#. {'book': 1, 'paper': 5} -#. ) -msgid "code_bits.'pen'" -msgstr "'pen'" - -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.positive_stock_exercise.text -#. -#. def positive_stock(stock): -#. # Your code here -#. ... -#. -#. assert_equal( -#. positive_stock({'apple': 10, 'banana': 0, 'pear': 5, 'orange': 0}), -#. {'apple': 10, 'pear': 5} -#. ) -#. assert_equal( -#. positive_stock({'pen': 0, 'pencil': 0}), -#. {} -#. ) -#. assert_equal( -#. positive_stock({'book': 1, 'paper': 5}), -#. {'book': 1, 'paper': 5} -#. ) -msgid "code_bits.'pencil'" -msgstr "'pencil'" - #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.avocado_or_lawyer #. #. def swap_keys_values(d): @@ -5198,18 +4836,6 @@ msgstr "Hello" msgid "code_bits.___" msgstr "___" -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.making_copies.text -#. -#. __program_indented__ -#. -#. ------ -#. -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.shared_references.text -#. -#. __program_indented__ -#. -#. ------ -#. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.avocado_or_lawyer.text #. #. __program_indented__ @@ -5532,32 +5158,6 @@ msgstr "__program_indented__" msgid "code_bits.actual" msgstr "actual" -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.add_item_exercise -#. -#. def add_item(item, quantities): -#. new_quantities = quantities.copy() -#. new_quantities[item] = new_quantities[item] + 1 -#. return new_quantities -#. -#. ------ -#. -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.add_item_exercise.text -#. -#. def add_item(item, quantities): -#. # Your code here -#. ... -#. -#. stock = {'apple': 5, 'banana': 2} -#. new_stock = add_item('apple', stock) -#. assert_equal(stock, {'apple': 5, 'banana': 2}) # Original unchanged -#. assert_equal(new_stock, {'apple': 6, 'banana': 2}) # Copy has incremented value -#. -#. new_stock_2 = add_item('banana', new_stock) -#. assert_equal(new_stock, {'apple': 6, 'banana': 2}) # Previous copy unchanged -#. assert_equal(new_stock_2, {'apple': 6, 'banana': 3}) # New copy incremented -msgid "code_bits.add_item" -msgstr "add_item" - #. https://poeditor.com/projects/view_terms?id=490053&search=pages.IntroducingFstrings.steps.basic_f_string_exercise #. #. name = "Alice" @@ -5755,44 +5355,6 @@ msgstr "all_numbers" #. #. ------ #. -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.add_item_exercise.text -#. -#. def add_item(item, quantities): -#. # Your code here -#. ... -#. -#. stock = {'apple': 5, 'banana': 2} -#. new_stock = add_item('apple', stock) -#. assert_equal(stock, {'apple': 5, 'banana': 2}) # Original unchanged -#. assert_equal(new_stock, {'apple': 6, 'banana': 2}) # Copy has incremented value -#. -#. new_stock_2 = add_item('banana', new_stock) -#. assert_equal(new_stock, {'apple': 6, 'banana': 2}) # Previous copy unchanged -#. assert_equal(new_stock_2, {'apple': 6, 'banana': 3}) # New copy incremented -#. -#. ------ -#. -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.positive_stock_exercise.text -#. -#. def positive_stock(stock): -#. # Your code here -#. ... -#. -#. assert_equal( -#. positive_stock({'apple': 10, 'banana': 0, 'pear': 5, 'orange': 0}), -#. {'apple': 10, 'pear': 5} -#. ) -#. assert_equal( -#. positive_stock({'pen': 0, 'pencil': 0}), -#. {} -#. ) -#. assert_equal( -#. positive_stock({'book': 1, 'paper': 5}), -#. {'book': 1, 'paper': 5} -#. ) -#. -#. ------ -#. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise.text #. #. def buy_quantity(quantities, item, quantity): @@ -8896,70 +8458,6 @@ msgstr "consonants" msgid "code_bits.cube" msgstr "cube" -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.making_copies -#. -#. d1 = {'a': 1, 'b': 2} -#. d2 = d1.copy() # Create a separate copy -#. -#. print("d1 before:", d1) -#. print("d2 before:", d2) -#. print("Are they the same object?", d1 is d2) -#. -#. d2['c'] = 3 # Modify the copy -#. -#. print("d1 after:", d1) # Is d1 affected now? -#. print("d2 after:", d2) -#. -#. ------ -#. -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.shared_references -#. -#. d1 = {'a': 1, 'b': 2} -#. d2 = d1 -#. -#. print("d1 before:", d1) -#. print("d2 before:", d2) -#. print("Are they the same object?", d1 is d2) -#. -#. d2['c'] = 3 # Modify via d2 -#. -#. print("d1 after:", d1) # Is d1 affected? -#. print("d2 after:", d2) -msgid "code_bits.d1" -msgstr "d1" - -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.making_copies -#. -#. d1 = {'a': 1, 'b': 2} -#. d2 = d1.copy() # Create a separate copy -#. -#. print("d1 before:", d1) -#. print("d2 before:", d2) -#. print("Are they the same object?", d1 is d2) -#. -#. d2['c'] = 3 # Modify the copy -#. -#. print("d1 after:", d1) # Is d1 affected now? -#. print("d2 after:", d2) -#. -#. ------ -#. -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.shared_references -#. -#. d1 = {'a': 1, 'b': 2} -#. d2 = d1 -#. -#. print("d1 before:", d1) -#. print("d2 before:", d2) -#. print("Are they the same object?", d1 is d2) -#. -#. d2['c'] = 3 # Modify via d2 -#. -#. print("d1 after:", d1) # Is d1 affected? -#. print("d2 after:", d2) -msgid "code_bits.d2" -msgstr "d2" - #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CombiningAndAndOr.steps.final_text.text #. #. diagonal1 = all_equal([board[0][0], board[1][1], board[2][2]]) @@ -12100,44 +11598,6 @@ msgstr "is_friend" msgid "code_bits.is_valid_percentage" msgstr "is_valid_percentage" -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.add_item_exercise -#. -#. def add_item(item, quantities): -#. new_quantities = quantities.copy() -#. new_quantities[item] = new_quantities[item] + 1 -#. return new_quantities -#. -#. ------ -#. -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.add_item_exercise.text -#. -#. def add_item(item, quantities): -#. # Your code here -#. ... -#. -#. stock = {'apple': 5, 'banana': 2} -#. new_stock = add_item('apple', stock) -#. assert_equal(stock, {'apple': 5, 'banana': 2}) # Original unchanged -#. assert_equal(new_stock, {'apple': 6, 'banana': 2}) # Copy has incremented value -#. -#. new_stock_2 = add_item('banana', new_stock) -#. assert_equal(new_stock, {'apple': 6, 'banana': 2}) # Previous copy unchanged -#. assert_equal(new_stock_2, {'apple': 6, 'banana': 3}) # New copy incremented -#. -#. ------ -#. -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.positive_stock_exercise -#. -#. def positive_stock(stock): -#. result = {} -#. for item in stock: -#. quantity = stock[item] -#. if quantity > 0: -#. result[item] = quantity -#. return result -#. -#. ------ -#. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise #. #. def buy_quantity(quantities, item, quantity): @@ -14164,15 +13624,6 @@ msgstr "new_numbers" msgid "code_bits.new_nums" msgstr "new_nums" -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.add_item_exercise -#. -#. def add_item(item, quantities): -#. new_quantities = quantities.copy() -#. new_quantities[item] = new_quantities[item] + 1 -#. return new_quantities -msgid "code_bits.new_quantities" -msgstr "new_quantities" - #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CombiningCompoundStatements.steps.final_text.text #. #. sentence = 'Hello World' @@ -14303,40 +13754,6 @@ msgstr "new_quantities" msgid "code_bits.new_sentence" msgstr "new_sentence" -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.add_item_exercise.text -#. -#. def add_item(item, quantities): -#. # Your code here -#. ... -#. -#. stock = {'apple': 5, 'banana': 2} -#. new_stock = add_item('apple', stock) -#. assert_equal(stock, {'apple': 5, 'banana': 2}) # Original unchanged -#. assert_equal(new_stock, {'apple': 6, 'banana': 2}) # Copy has incremented value -#. -#. new_stock_2 = add_item('banana', new_stock) -#. assert_equal(new_stock, {'apple': 6, 'banana': 2}) # Previous copy unchanged -#. assert_equal(new_stock_2, {'apple': 6, 'banana': 3}) # New copy incremented -msgid "code_bits.new_stock" -msgstr "new_stock" - -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.add_item_exercise.text -#. -#. def add_item(item, quantities): -#. # Your code here -#. ... -#. -#. stock = {'apple': 5, 'banana': 2} -#. new_stock = add_item('apple', stock) -#. assert_equal(stock, {'apple': 5, 'banana': 2}) # Original unchanged -#. assert_equal(new_stock, {'apple': 6, 'banana': 2}) # Copy has incremented value -#. -#. new_stock_2 = add_item('banana', new_stock) -#. assert_equal(new_stock, {'apple': 6, 'banana': 2}) # Previous copy unchanged -#. assert_equal(new_stock_2, {'apple': 6, 'banana': 3}) # New copy incremented -msgid "code_bits.new_stock_2" -msgstr "new_stock_2" - #. https://poeditor.com/projects/view_terms?id=490053&search=pages.FunctionsAndMethodsForLists.steps.subscript_assignment_predict.text #. #. some_list[index] = new_value @@ -15994,39 +15411,6 @@ msgstr "player2" msgid "code_bits.players" msgstr "players" -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.positive_stock_exercise -#. -#. def positive_stock(stock): -#. result = {} -#. for item in stock: -#. quantity = stock[item] -#. if quantity > 0: -#. result[item] = quantity -#. return result -#. -#. ------ -#. -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.positive_stock_exercise.text -#. -#. def positive_stock(stock): -#. # Your code here -#. ... -#. -#. assert_equal( -#. positive_stock({'apple': 10, 'banana': 0, 'pear': 5, 'orange': 0}), -#. {'apple': 10, 'pear': 5} -#. ) -#. assert_equal( -#. positive_stock({'pen': 0, 'pencil': 0}), -#. {} -#. ) -#. assert_equal( -#. positive_stock({'book': 1, 'paper': 5}), -#. {'book': 1, 'paper': 5} -#. ) -msgid "code_bits.positive_stock" -msgstr "positive_stock" - #. https://poeditor.com/projects/view_terms?id=490053&search=pages.LoopingOverNestedLists.steps.list_contains_word_exercise #. #. strings = [['hello there', 'how are you'], ['goodbye world', 'hello world']] @@ -16806,32 +16190,6 @@ msgstr "printed" msgid "code_bits.quadruple" msgstr "quadruple" -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.add_item_exercise -#. -#. def add_item(item, quantities): -#. new_quantities = quantities.copy() -#. new_quantities[item] = new_quantities[item] + 1 -#. return new_quantities -#. -#. ------ -#. -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.add_item_exercise.text -#. -#. def add_item(item, quantities): -#. # Your code here -#. ... -#. -#. stock = {'apple': 5, 'banana': 2} -#. new_stock = add_item('apple', stock) -#. assert_equal(stock, {'apple': 5, 'banana': 2}) # Original unchanged -#. assert_equal(new_stock, {'apple': 6, 'banana': 2}) # Copy has incremented value -#. -#. new_stock_2 = add_item('banana', new_stock) -#. assert_equal(new_stock, {'apple': 6, 'banana': 2}) # Previous copy unchanged -#. assert_equal(new_stock_2, {'apple': 6, 'banana': 3}) # New copy incremented -#. -#. ------ -#. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise #. #. def buy_quantity(quantities, item, quantity): @@ -17012,18 +16370,6 @@ msgstr "quadruple" msgid "code_bits.quantities" msgstr "quantities" -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.positive_stock_exercise -#. -#. def positive_stock(stock): -#. result = {} -#. for item in stock: -#. quantity = stock[item] -#. if quantity > 0: -#. result[item] = quantity -#. return result -#. -#. ------ -#. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.CreatingKeyValuePairs.steps.buy_quantity_exercise #. #. def buy_quantity(quantities, item, quantity): @@ -17135,18 +16481,6 @@ msgstr "quantities" msgid "code_bits.quantity" msgstr "quantity" -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.positive_stock_exercise -#. -#. def positive_stock(stock): -#. result = {} -#. for item in stock: -#. quantity = stock[item] -#. if quantity > 0: -#. result[item] = quantity -#. return result -#. -#. ------ -#. #. https://poeditor.com/projects/view_terms?id=490053&search=pages.DictionaryKeysAndValues.steps.cleanup_shopping_cart #. #. def total_cost(quantities, prices): @@ -18840,56 +18174,6 @@ msgstr "some_list" msgid "code_bits.spaces" msgstr "spaces" -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.add_item_exercise.text -#. -#. def add_item(item, quantities): -#. # Your code here -#. ... -#. -#. stock = {'apple': 5, 'banana': 2} -#. new_stock = add_item('apple', stock) -#. assert_equal(stock, {'apple': 5, 'banana': 2}) # Original unchanged -#. assert_equal(new_stock, {'apple': 6, 'banana': 2}) # Copy has incremented value -#. -#. new_stock_2 = add_item('banana', new_stock) -#. assert_equal(new_stock, {'apple': 6, 'banana': 2}) # Previous copy unchanged -#. assert_equal(new_stock_2, {'apple': 6, 'banana': 3}) # New copy incremented -#. -#. ------ -#. -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.positive_stock_exercise -#. -#. def positive_stock(stock): -#. result = {} -#. for item in stock: -#. quantity = stock[item] -#. if quantity > 0: -#. result[item] = quantity -#. return result -#. -#. ------ -#. -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.positive_stock_exercise.text -#. -#. def positive_stock(stock): -#. # Your code here -#. ... -#. -#. assert_equal( -#. positive_stock({'apple': 10, 'banana': 0, 'pear': 5, 'orange': 0}), -#. {'apple': 10, 'pear': 5} -#. ) -#. assert_equal( -#. positive_stock({'pen': 0, 'pencil': 0}), -#. {} -#. ) -#. assert_equal( -#. positive_stock({'book': 1, 'paper': 5}), -#. {'book': 1, 'paper': 5} -#. ) -msgid "code_bits.stock" -msgstr "stock" - #. https://poeditor.com/projects/view_terms?id=490053&search=pages.IntroducingNestedLists.steps.double_subscripting.text #. #. string = strings[1] @@ -23410,283 +22694,6 @@ msgstr "" msgid "pages.CombiningCompoundStatements.title" msgstr "Combining Compound Statements" -#. https://futurecoder.io/course/#CopyingDictionaries -#. -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.add_item_exercise -msgid "pages.CopyingDictionaries.steps.add_item_exercise.hints.0.text" -msgstr "" -"First, create a *copy* of the input `quantities` dictionary using the `.copy()` method. Store this in a new variable, " -"e.g., `new_quantities`." - -#. https://futurecoder.io/course/#CopyingDictionaries -#. -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.add_item_exercise -msgid "pages.CopyingDictionaries.steps.add_item_exercise.hints.1.text" -msgstr "Since we assume `item` is already a key, you don't need to check for its existence in this exercise." - -#. https://futurecoder.io/course/#CopyingDictionaries -#. -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.add_item_exercise -msgid "pages.CopyingDictionaries.steps.add_item_exercise.hints.2.text" -msgstr "Find the current quantity of the `item` in the `new_quantities` copy using `new_quantities[item]`." - -#. https://futurecoder.io/course/#CopyingDictionaries -#. -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.add_item_exercise -msgid "pages.CopyingDictionaries.steps.add_item_exercise.hints.3.text" -msgstr "Calculate the new quantity by adding 1 to the current quantity." - -#. https://futurecoder.io/course/#CopyingDictionaries -#. -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.add_item_exercise -msgid "pages.CopyingDictionaries.steps.add_item_exercise.hints.4.text" -msgstr "" -"Update the value for `item` in the `new_quantities` copy with this new quantity using assignment: " -"`new_quantities[item] = ...`." - -#. https://futurecoder.io/course/#CopyingDictionaries -#. -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.add_item_exercise -msgid "pages.CopyingDictionaries.steps.add_item_exercise.hints.5.text" -msgstr "Return the `new_quantities` dictionary." - -#. https://futurecoder.io/course/#CopyingDictionaries -#. -#. # __code0__: -#. def add_item(item, quantities): -#. # Your code here -#. ... -#. -#. stock = {'apple': 5, 'banana': 2} -#. new_stock = add_item('apple', stock) -#. assert_equal(stock, {'apple': 5, 'banana': 2}) # Original unchanged -#. assert_equal(new_stock, {'apple': 6, 'banana': 2}) # Copy has incremented value -#. -#. new_stock_2 = add_item('banana', new_stock) -#. assert_equal(new_stock, {'apple': 6, 'banana': 2}) # Previous copy unchanged -#. assert_equal(new_stock_2, {'apple': 6, 'banana': 3}) # New copy incremented -#. -#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.%27apple%27 -#. -#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.%27banana%27 -#. -#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.add_item -#. -#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.assert_equal -#. -#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.item -#. -#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.new_stock -#. -#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.new_stock_2 -#. -#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.quantities -#. -#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.stock -msgid "pages.CopyingDictionaries.steps.add_item_exercise.text" -msgstr "" -"Let's practice combining copying and modifying. Imagine we want to represent adding one unit of an item to our stock count.\n" -"\n" -"Write a function `add_item(item, quantities)` that takes an item name (`item`) and a dictionary `quantities`. You can assume the `item` *already exists* as a key in the `quantities` dictionary.\n" -"\n" -"The function should return a *new* dictionary which is a copy of `quantities`, but with the value associated with `item` increased by 1. The original `quantities` dictionary should not be changed.\n" -"\n" -" __copyable__\n" -"__code0__" - -#. https://futurecoder.io/course/#CopyingDictionaries -msgid "pages.CopyingDictionaries.steps.final_text.text" -msgstr "" -"Great! You now know why copying dictionaries is important (because they are mutable) and how to do it using `.copy()`. You've also practiced creating modified copies, which is a common and safe way to work with data without accidentally changing things elsewhere in your program.\n" -"\n" -"Next, we'll see how to check if a key exists *before* trying to use it, to avoid errors." - -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.making_copies -msgid "pages.CopyingDictionaries.steps.making_copies.output_prediction_choices.0" -msgstr "" -"d1 before: {'a': 1, 'b': 2}\n" -"d2 before: {'a': 1, 'b': 2}\n" -"Are they the same object? True\n" -"d1 after: {'a': 1, 'b': 2, 'c': 3}\n" -"d2 after: {'a': 1, 'b': 2, 'c': 3}" - -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.making_copies -msgid "pages.CopyingDictionaries.steps.making_copies.output_prediction_choices.1" -msgstr "" -"d1 before: {'a': 1, 'b': 2}\n" -"d2 before: {'a': 1, 'b': 2}\n" -"Are they the same object? False\n" -"d1 after: {'a': 1, 'b': 2, 'c': 3}\n" -"d2 after: {'a': 1, 'b': 2, 'c': 3}" - -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.making_copies -msgid "pages.CopyingDictionaries.steps.making_copies.output_prediction_choices.2" -msgstr "" -"d1 before: {'a': 1, 'b': 2}\n" -"d2 before: {'a': 1, 'b': 2}\n" -"Are they the same object? False\n" -"d1 after: {'a': 1, 'b': 2}\n" -"d2 after: {'a': 1, 'b': 2, 'c': 3}" - -#. https://futurecoder.io/course/#CopyingDictionaries -#. -#. # __code0__: -#. __program_indented__ -#. -#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.__program_indented__ -msgid "pages.CopyingDictionaries.steps.making_copies.text" -msgstr "" -"Because `d1` and `d2` referred to the exact same dictionary object (`d1 is d2` was `True`), changing it via `d2` also changed what `d1` saw.\n" -"\n" -"To get a *separate* dictionary with the same contents, use the `.copy()` method.\n" -"\n" -"Predict how using `.copy()` changes the outcome, then run this code:\n" -"\n" -" __copyable__\n" -"__code0__" - -#. https://futurecoder.io/course/#CopyingDictionaries -#. -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.positive_stock_exercise -msgid "pages.CopyingDictionaries.steps.positive_stock_exercise.hints.0.text" -msgstr "Start by creating a new empty dictionary, e.g., `result = {}`." - -#. https://futurecoder.io/course/#CopyingDictionaries -#. -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.positive_stock_exercise -msgid "pages.CopyingDictionaries.steps.positive_stock_exercise.hints.1.text" -msgstr "Loop through the keys of the input `stock` dictionary." - -#. https://futurecoder.io/course/#CopyingDictionaries -#. -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.positive_stock_exercise -msgid "pages.CopyingDictionaries.steps.positive_stock_exercise.hints.2.text" -msgstr "Inside the loop, get the `quantity` for the current `item` using `stock[item]`." - -#. https://futurecoder.io/course/#CopyingDictionaries -#. -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.positive_stock_exercise -msgid "pages.CopyingDictionaries.steps.positive_stock_exercise.hints.3.text" -msgstr "Use an `if` statement to check if `quantity > 0`." - -#. https://futurecoder.io/course/#CopyingDictionaries -#. -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.positive_stock_exercise -msgid "pages.CopyingDictionaries.steps.positive_stock_exercise.hints.4.text" -msgstr "" -"If the quantity is positive, add the `item` and its `quantity` to your `result` dictionary using `result[item] = " -"quantity`." - -#. https://futurecoder.io/course/#CopyingDictionaries -#. -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.positive_stock_exercise -msgid "pages.CopyingDictionaries.steps.positive_stock_exercise.hints.5.text" -msgstr "After the loop finishes, return the `result` dictionary." - -#. https://futurecoder.io/course/#CopyingDictionaries -#. -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.positive_stock_exercise -msgid "pages.CopyingDictionaries.steps.positive_stock_exercise.hints.6.text" -msgstr "" -"Make sure you don't modify the original `stock` dictionary passed into the function. Creating a new `result` " -"dictionary ensures this." - -#. https://futurecoder.io/course/#CopyingDictionaries -#. -#. # __code0__: -#. def positive_stock(stock): -#. # Your code here -#. ... -#. -#. assert_equal( -#. positive_stock({'apple': 10, 'banana': 0, 'pear': 5, 'orange': 0}), -#. {'apple': 10, 'pear': 5} -#. ) -#. assert_equal( -#. positive_stock({'pen': 0, 'pencil': 0}), -#. {} -#. ) -#. assert_equal( -#. positive_stock({'book': 1, 'paper': 5}), -#. {'book': 1, 'paper': 5} -#. ) -#. -#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.%27apple%27 -#. -#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.%27banana%27 -#. -#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.%27book%27 -#. -#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.%27orange%27 -#. -#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.%27paper%27 -#. -#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.%27pear%27 -#. -#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.%27pen%27 -#. -#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.%27pencil%27 -#. -#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.assert_equal -#. -#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.positive_stock -#. -#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.stock -msgid "pages.CopyingDictionaries.steps.positive_stock_exercise.text" -msgstr "" -"Making an exact copy is useful, but often we want a *modified* copy. Let's practice creating a new dictionary based on an old one.\n" -"\n" -"Write a function `positive_stock(stock)` that takes a dictionary `stock` (mapping item names to integer quantities) and returns a *new* dictionary containing only the items from the original `stock` where the quantity is strictly greater than 0. The original `stock` dictionary should not be changed.\n" -"\n" -" __copyable__\n" -"__code0__" - -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.shared_references -msgid "pages.CopyingDictionaries.steps.shared_references.output_prediction_choices.0" -msgstr "" -"d1 before: {'a': 1, 'b': 2}\n" -"d2 before: {'a': 1, 'b': 2}\n" -"Are they the same object? True\n" -"d1 after: {'a': 1, 'b': 2}\n" -"d2 after: {'a': 1, 'b': 2, 'c': 3}" - -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.shared_references -msgid "pages.CopyingDictionaries.steps.shared_references.output_prediction_choices.1" -msgstr "" -"d1 before: {'a': 1, 'b': 2}\n" -"d2 before: {'a': 1, 'b': 2}\n" -"Are they the same object? True\n" -"d1 after: {'a': 1, 'b': 2, 'c': 3}\n" -"d2 after: {'a': 1, 'b': 2, 'c': 3}" - -#. https://poeditor.com/projects/view_terms?id=490053&search=pages.CopyingDictionaries.steps.shared_references -msgid "pages.CopyingDictionaries.steps.shared_references.output_prediction_choices.2" -msgstr "" -"d1 before: {'a': 1, 'b': 2}\n" -"d2 before: {'a': 1, 'b': 2}\n" -"Are they the same object? False\n" -"d1 after: {'a': 1, 'b': 2}\n" -"d2 after: {'a': 1, 'b': 2, 'c': 3}" - -#. https://futurecoder.io/course/#CopyingDictionaries -#. -#. # __code0__: -#. __program_indented__ -#. -#. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.__program_indented__ -msgid "pages.CopyingDictionaries.steps.shared_references.text" -msgstr "" -"Remember how assigning one list variable to another (`list2 = list1`) made both names point to the *same* list? Dictionaries work the same way because they are also *mutable* (can be changed).\n" -"\n" -"Predict what the following code will print, then run it to see:\n" -"\n" -" __copyable__\n" -"__code0__" - -#. https://futurecoder.io/course/#CopyingDictionaries -msgid "pages.CopyingDictionaries.title" -msgstr "Copying Dictionaries" - #. https://futurecoder.io/course/#CreatingKeyValuePairs #. #. # __code0__: @@ -23894,6 +22901,9 @@ msgstr "" #. https://poeditor.com/projects/view_terms?id=490053&search=code_bits.swap_keys_values msgid "pages.CreatingKeyValuePairs.steps.final_text.text" msgstr "" +"The result depends on the order of the keys in the original dictionary!\n" +"If you're not sure why, try running the code with `snoop` or another debugger.\n" +"\n" "But there are many situations where you can be sure that the values in a dictionary *are* unique and that this\n" "'inversion' makes sense. For example, we saw this code [earlier in the chapter](#UsingDictionaries):\n" "\n" diff --git a/translations/locales/en/LC_MESSAGES/futurecoder.mo b/translations/locales/en/LC_MESSAGES/futurecoder.mo index 032176da608be415cf6ebdcc9adfa1437b3adddb..f6e8d8af386f36c032f50eb273c7c13f5d8a88f5 100644 GIT binary patch delta 27598 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 b*Z~8QMwLmEX6Dd|5&k#2bLhlak>URjc_y>O delta 33169 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 KOZ!Hy$oyZ0*V(}U From 8a2e1d45e95ff5b255bee7c51194ae4d7dfe5141 Mon Sep 17 00:00:00 2001 From: Alex Hall Date: Sat, 19 Jul 2025 19:39:05 +0200 Subject: [PATCH 16/16] CopyingDictionaries --- core/chapters/c12_dictionaries.py | 241 ++++++++++++++++++++++++++++++ 1 file changed, 241 insertions(+) diff --git a/core/chapters/c12_dictionaries.py b/core/chapters/c12_dictionaries.py index 5e59507f..124d084b 100644 --- a/core/chapters/c12_dictionaries.py +++ b/core/chapters/c12_dictionaries.py @@ -1137,3 +1137,244 @@ def substitute(string, d): Otherwise it would be impossible to decrypt messages properly. If both `'h'` and `'j'` got replaced with `'q'` during encryption, there would be no way to know whether `'qpeef'` means `'hello'` or `'jello'`! """ + + +class CopyingDictionaries(Page): + title = "Copying Dictionaries" + + class shared_references(VerbatimStep): + """ + Remember how assigning one list variable to another (`list2 = list1`) made both names point to the *same* list? Dictionaries work the same way because they are also *mutable* (can be changed). + + Predict what the following code will print, then run it to see: + + __copyable__ + __program_indented__ + """ + def program(self): + d1 = {'a': 1, 'b': 2} + d2 = d1 + + print("d1 before:", d1) + print("d2 before:", d2) + print("Are they the same object?", d1 is d2) + + d2['c'] = 3 # Modify via d2 + + print("d1 after:", d1) # Is d1 affected? + print("d2 after:", d2) + + predicted_output_choices = [ + # Incorrect prediction (d1 unaffected) + """d1 before: {'a': 1, 'b': 2} +d2 before: {'a': 1, 'b': 2} +Are they the same object? True +d1 after: {'a': 1, 'b': 2} +d2 after: {'a': 1, 'b': 2, 'c': 3}""", + + # Correct prediction + """d1 before: {'a': 1, 'b': 2} +d2 before: {'a': 1, 'b': 2} +Are they the same object? True +d1 after: {'a': 1, 'b': 2, 'c': 3} +d2 after: {'a': 1, 'b': 2, 'c': 3}""", + + # Incorrect prediction (is False) + """d1 before: {'a': 1, 'b': 2} +d2 before: {'a': 1, 'b': 2} +Are they the same object? False +d1 after: {'a': 1, 'b': 2} +d2 after: {'a': 1, 'b': 2, 'c': 3}""", + ] + + class making_copies(VerbatimStep): + """ + Because `d1` and `d2` referred to the exact same dictionary object (`d1 is d2` was `True`), changing it via `d2` also changed what `d1` saw. + + To get a *separate* dictionary with the same contents, use the `.copy()` method. + + Predict how using `.copy()` changes the outcome, then run this code: + + __copyable__ + __program_indented__ + """ + def program(self): + d1 = {'a': 1, 'b': 2} + d2 = d1.copy() # Create a separate copy + + print("d1 before:", d1) + print("d2 before:", d2) + print("Are they the same object?", d1 is d2) + + d2['c'] = 3 # Modify the copy + + print("d1 after:", d1) # Is d1 affected now? + print("d2 after:", d2) + + predicted_output_choices = [ + # Incorrect prediction (is True) + """d1 before: {'a': 1, 'b': 2} +d2 before: {'a': 1, 'b': 2} +Are they the same object? True +d1 after: {'a': 1, 'b': 2, 'c': 3} +d2 after: {'a': 1, 'b': 2, 'c': 3}""", + + # Incorrect prediction (d1 affected) + """d1 before: {'a': 1, 'b': 2} +d2 before: {'a': 1, 'b': 2} +Are they the same object? False +d1 after: {'a': 1, 'b': 2, 'c': 3} +d2 after: {'a': 1, 'b': 2, 'c': 3}""", + + # Correct prediction + """d1 before: {'a': 1, 'b': 2} +d2 before: {'a': 1, 'b': 2} +Are they the same object? False +d1 after: {'a': 1, 'b': 2} +d2 after: {'a': 1, 'b': 2, 'c': 3}""", + ] + + class positive_stock_exercise(ExerciseStep): + """ + Making an exact copy is useful, but often we want a *modified* copy. Let's practice creating a new dictionary based on an old one. + + Write a function `positive_stock(stock)` that takes a dictionary `stock` (mapping item names to integer quantities) and returns a *new* dictionary containing only the items from the original `stock` where the quantity is strictly greater than 0. The original `stock` dictionary should not be changed. + + __copyable__ + def positive_stock(stock): + # Your code here + ... + + assert_equal( + positive_stock({'apple': 10, 'banana': 0, 'pear': 5, 'orange': 0}), + {'apple': 10, 'pear': 5} + ) + assert_equal( + positive_stock({'pen': 0, 'pencil': 0}), + {} + ) + assert_equal( + positive_stock({'book': 1, 'paper': 5}), + {'book': 1, 'paper': 5} + ) + """ + hints = """ + Start by creating a new empty dictionary, e.g., `result = {}`. + Loop through the keys of the input `stock` dictionary. + Inside the loop, get the `quantity` for the current `item` using `stock[item]`. + Use an `if` statement to check if `quantity > 0`. + If the quantity is positive, add the `item` and its `quantity` to your `result` dictionary using `result[item] = quantity`. + After the loop finishes, return the `result` dictionary. + Make sure you don't modify the original `stock` dictionary passed into the function. Creating a new `result` dictionary ensures this. + """ + + def solution(self): + def positive_stock(stock: Dict[str, int]): + result = {} + for item in stock: + quantity = stock[item] + if quantity > 0: + result[item] = quantity + return result + return positive_stock + + tests = [ + (({'apple': 10, 'banana': 0, 'pear': 5, 'orange': 0},), {'apple': 10, 'pear': 5}), + (({'pen': 0, 'pencil': 0},), {}), + (({'book': 1, 'paper': 5},), {'book': 1, 'paper': 5}), + (({},), {}), # Empty input + (({'gadget': -5, 'widget': 3},), {'widget': 3}), # Negative values + ] + + @classmethod + def generate_inputs(cls): + # Generate a dictionary with some zero/negative and positive values + stock = {} + num_items = random.randint(3, 8) + for _ in range(num_items): + item = generate_string(random.randint(3, 6)) + # Ensure some variety in quantities + if random.random() < 0.4: + quantity = 0 + elif random.random() < 0.2: + quantity = random.randint(-5, -1) + else: + quantity = random.randint(1, 20) + stock[item] = quantity + # Ensure at least one positive if dict not empty + if stock and all(q <= 0 for q in stock.values()): + stock[generate_string(4)] = random.randint(1, 10) + return {"stock": stock} + + class add_item_exercise(ExerciseStep): + """ + Let's practice combining copying and modifying. Imagine we want to represent adding one unit of an item to our stock count. + + Write a function `add_item(item, quantities)` that takes an item name (`item`) and a dictionary `quantities`. You can assume the `item` *already exists* as a key in the `quantities` dictionary. + + The function should return a *new* dictionary which is a copy of `quantities`, but with the value associated with `item` increased by 1. The original `quantities` dictionary should not be changed. + + __copyable__ + def add_item(item, quantities): + # Your code here + ... + + stock = {'apple': 5, 'banana': 2} + new_stock = add_item('apple', stock) + assert_equal(stock, {'apple': 5, 'banana': 2}) # Original unchanged + assert_equal(new_stock, {'apple': 6, 'banana': 2}) # Copy has incremented value + + new_stock_2 = add_item('banana', new_stock) + assert_equal(new_stock, {'apple': 6, 'banana': 2}) # Previous copy unchanged + assert_equal(new_stock_2, {'apple': 6, 'banana': 3}) # New copy incremented + """ + hints = """ + First, create a *copy* of the input `quantities` dictionary using the `.copy()` method. Store this in a new variable, e.g., `new_quantities`. + Since we assume `item` is already a key, you don't need to check for its existence in this exercise. + Find the current quantity of the `item` in the `new_quantities` copy using `new_quantities[item]`. + Calculate the new quantity by adding 1 to the current quantity. + Update the value for `item` in the `new_quantities` copy with this new quantity using assignment: `new_quantities[item] = ...`. + Return the `new_quantities` dictionary. + """ + + def solution(self): + def add_item(item: str, quantities: Dict[str, int]): + new_quantities = quantities.copy() + new_quantities[item] = new_quantities[item] + 1 + return new_quantities + return add_item + + tests = [ + (('apple', {'apple': 5, 'banana': 2}), {'apple': 6, 'banana': 2}), + (('banana', {'apple': 6, 'banana': 2}), {'apple': 6, 'banana': 3}), + (('pen', {'pen': 1}), {'pen': 2}), + (('a', {'a': 0, 'b': 99}), {'a': 1, 'b': 99}), + ] + + @classmethod + def generate_inputs(cls): + quantities = generate_dict(str, int) + # Ensure the dictionary is not empty + if not quantities: + quantities[generate_string(4)] = random.randint(0, 10) + # Pick an existing item to increment + item = random.choice(list(quantities.keys())) + return {"item": item, "quantities": quantities} + + final_text = """ + Well done! Notice that the line where you increment the value: + + new_quantities[item] = new_quantities[item] + 1 + + can also be written more concisely using the `+=` operator, just like with numbers: + + new_quantities[item] += 1 + + This does the same thing: it reads the current value, adds 1, and assigns the result back. + """ + + final_text = """ + Great! You now know why copying dictionaries is important (because they are mutable) and how to do it using `.copy()`. You've also practiced creating modified copies, which is a common and safe way to work with data without accidentally changing things elsewhere in your program. + + Next, we'll see how to check if a key exists *before* trying to use it, to avoid errors. + """