Clean code communicates its intent.
A program can give the right answer and still be difficult to understand. Clean code favors understandable names, consistency, and simple structure instead of a fixed list of absolute rules.
def f(x, y):
return x - x * y / 100
def cena_sa_popustom(cena: float, popust: float) -> float:
return cena - cena * popust / 100Both functions use the same algorithm. The second name tells us what the result means, and its parameters and type hints show what values belong there.
Readable code is not about making every line longer. It is about helping the next reader understand the important idea with less guessing.
A practical question: Could a classmate understand this function tomorrow without first asking you what each short name means?
def cena_sa_popustom(cena: float, popust: float) -> float:
"""Izračunava cenu nakon procentualnog popusta."""
return cena - cena * popust / 100
print(cena_sa_popustom.__doc__)
help(cena_sa_popustom)A docstring is a string literal at the beginning of a function, class, or module body. It explains purpose and use. Python stores it in __doc__, and help() can display it.
def cena_sa_popustom(cena: float, popust: float) -> float:
"""Izračunava cenu nakon popusta.
Args:
cena: Početna cena proizvoda.
popust: Procenat popusta.
Returns:
Cena nakon primenjenog popusta.
"""
return cena - cena * popust / 100Args and Returns are common documentation headings, not special Python keywords. A one-line docstring is often enough for a small, obvious function; use more detail when it helps a reader use the code correctly.
# The supplier price changes every Monday.
cena = ucitaj_cenu()
def prikazi_cenu(iznos: float) -> None:
"""Prints a formatted product price."""
print(f"{iznos:.2f} RSD")Use a comment to explain a reason or important decision in the source code. Use a docstring to document a function, class, or module. A comment should not merely repeat an obvious Python statement.
def izracunaj_porez(iznos: float, stopa: float) -> float:
"""Vraća iznos poreza za zadatu procentualnu stopu."""
return iznos * stopa / 100Type hints describe the values a function expects and returns. A docstring explains what the function does and how to use it. Clear names communicate intent directly in the code.
Five practical habits for readable code
- 1. Choose clear namesPrefer
ukupna_cenaandizracunaj_popustoverxandfwhen the longer names reveal the purpose. - 2. Give each function one understandable responsibilityIf one function reads input, calculates a total, prints a report, and saves a file, consider separating those jobs into small named functions.
- 3. Avoid needless repetitionWhen the same calculation appears in several places, a small helper function can give that calculation one name and one place to update.
- 4. Simplify conditions when possibleUse direct, readable conditions and avoid deep nesting when an early return or a clearly named boolean would make the decision easier to follow.
- 5. Comment the why, not the obvious whatA useful comment explains why a choice matters.
broj += 1usually does not need a comment that only says it adds one.
Refactor without changing the promise
- Refactoring is not a new featureRefactoring improves the internal structure of code while intentionally preserving its visible behavior and expected results.
- Check behavior after a changeRun the same examples before and after a refactor. Later lessons will show how tests can make this check more reliable.
