Store and Return the Expense
Exit

Store and Return the Expense

Assign an identifier, store the expense, and return it to the client

💻

Writing code and entering commands is only available on desktop. Open this page on a larger screen to complete this chapter.

The global keyword

You defined counter = 0 at the top of your file, outside any function. This makes it a module-level variable — it exists for the entire program, not just inside one function.

Python functions can read module-level variables without any special syntax. But when you try to modify one with counter += 1, Python assumes you mean a local variable that was never defined and raises an UnboundLocalError.

The global keyword fixes this. It tells Python: "don't create a new local variable — use the existing module-level one."

def create_expense(expense: Expense):
    global counter
    counter += 1  # modifies the module-level counter

You only need global when you reassign the variable. Reading expenses[counter] works fine without it because you are modifying the dictionary's contents, not replacing the variable itself.

Convert a Pydantic model to a dictionary

The model_dump() method converts a Pydantic model into a plain Python dictionary:

expense.model_dump()
# {"description": "Lunch", "amount": 12.5, "category": "food", "date": None}

This gives you a regular dictionary you can modify freely. The Pydantic model's job is done after validation.

Add the identifier with the spread operator

The ** spread operator unpacks a dictionary into key-value pairs. You can use it to create a new dictionary that combines existing fields with new ones:

{"id": counter, **expense.model_dump()}
# {"id": 1, "description": "Lunch", "amount": 12.5, "category": "food", "date": None}

This creates a single dictionary with the id field first, followed by all the expense fields. Storing this in expenses[counter] lets you look up any expense by its identifier later.

Instructions

Fill in the create_expense function body to assign an identifier, store the expense, and return it.

  1. Add global counter to access the module-level counter.
  2. Increment counter by 1.
  3. Store the expense in the dictionary with expenses[counter] = {"id": counter, **expense.model_dump()}.
  4. Return expenses[counter].