PythiloLesson 10 of 15 · progress kept in this browser

Prefer immutable values

A function that changes the list or dict it was given surprises its caller, who may still be using it. Code that changes shared objects can only be understood by following it in time order.

Prefer to return new values:

  • sorted(items) instead of items.sort()
  • {**prices, "tea": 3} instead of prices["tea"] = 3
  • tuples and frozensets for collections that should not change
  • frozen dataclasses with dataclasses.replace for records
from dataclasses import dataclass, replace

@dataclass(frozen=True)
class Settings:
    theme: str = "light"
    size: int = 14

base = Settings()
big = replace(base, size=18)
print(base)
print(big)

replace builds a copy with some fields changed. base is untouched, so anything holding it still sees what it saw before.

Changing an object your function created itself is fine. The rule is about values that other code can see.

Your task

Make add_item(cart, name, qty=1) return a new dict and normalized(names) return a new sorted list of stripped, lower-case names, both leaving their arguments untouched. Turn Config into a frozen dataclass with host and port, and add with_port(port) returning a changed copy.