Part Ten: Six Lists of Ten

You have reached the end of the journey, and here is a small reward: six short lists, each with exactly ten items, easy to reread any time, even while your coffee goes cold. Nothing here is new in concept; it is all picked from earlier chapters, with chapter numbers so you can go back to the full explanation.

All scripts in this part are in the folder kode/ch70/. In the web version you can also download them all at once (zip).

List 1: Ten beginner Python mistakes, and how to avoid them

All of them are real traps from Chapters 4 to 13. The script below deliberately makes each mistake in turn and catches the error, so you see the real message without the program stopping.

01_beginner_mistakes.py
# Part Ten - Ten beginner mistakes, caught so the messages are visible
def attempt(number, action):
    try:
        result = action()
        print(f"{number:>2}. no error, result = {result!r}")
    except Exception as e:
        print(f"{number:>2}. {type(e).__name__}: {e}")


def add_without_return(morning_kg, evening_kg):
    morning_kg + evening_kg


def sum_up():
    total_kg = 1 + 2


weight_text = "500"                     # like the result of input(): always text
tree = {"species": "Teak", "diameter_cm": 32.5}

attempt(1, lambda: prnt("hello"))                                                # Ch 4
attempt(2, lambda: weight_text + 10)                                             # Ch 5
attempt(3, lambda: compile("if weight = 500:\n    pass", "<example>", "exec"))   # Ch 6
attempt(4, lambda: 0.1 + 0.2 == 0.3)                                             # Ch 6
attempt(5, lambda: compile("if True:\nprint('x')", "<example>", "exec"))         # Ch 7
attempt(6, lambda: list(range(0, 1.5)))                                          # Ch 8
attempt(7, lambda: tree["height_m"])                                             # Ch 9
attempt(8, lambda: add_without_return(10, 5))                                    # Ch 10
attempt(9, lambda: (sum_up(), total_kg))                                         # Ch 10
attempt(10, lambda: open("missing_data.txt", encoding="utf-8"))                  # Ch 13
 1. NameError: name 'prnt' is not defined
 2. TypeError: can only concatenate str (not "int") to str
 3. SyntaxError: invalid syntax. Maybe you meant '==' or ':=' instead of '='? (<example>, line 1)
 4. no error, result = False
 5. IndentationError: expected an indented block after 'if' statement on line 1 (<example>, line 2)
 6. TypeError: 'float' object cannot be interpreted as an integer
 7. KeyError: 'height_m'
 8. no error, result = None
 9. NameError: name 'total_kg' is not defined
10. FileNotFoundError: [Errno 2] No such file or directory: 'missing_data.txt'
No Mistake What appears How to avoid it Ch
1 Mistyping a name (prnt) NameError check the spelling; a full traceback often suggests a similar name 4, 5
2 Assuming input() gives a number TypeError (text + number) convert with int() or float() 5
3 Using = when you meant == SyntaxError = stores, == compares 6
4 Comparing decimals with == False for 0.1 + 0.2 == 0.3 compare with a tolerance or round 6
5 Forgetting to indent after if IndentationError indent four spaces, consistently 7
6 range() with a decimal number TypeError range takes whole numbers only 8
7 Asking a dict for a label that is not there KeyError check with in first or use .get() 9
8 Forgetting return silently gives None ask: does the function return a value? 10
9 Using a local variable from outside the function NameError return the result and catch it outside 10
10 Opening a file that does not exist FileNotFoundError check the path with pathlib, handle with try 13

Two rows deserve a close look: numbers 4 and 8 produce no error at all, and that is exactly why they are the slipperiest. Python stays quiet and hands you a wrong answer.

List 2: Ten habits that keep your code tidy and safe

  1. Give meaningful names. compute_biomass beats h. Follow PEP 8 and let ruff check it (Chapter 19).
  2. One function, one job, and never use an empty list as a default value (see the example below) (Chapter 10).
  3. Open files with with and write encoding="utf-8" explicitly (Chapter 13).
  4. One environment per project, with its dependencies recorded (Chapter 17).
  5. Write tests for what matters, for the success path and the failure path (Chapter 18).
  6. Use type hints and validate incoming data with Pydantic (Chapters 33, 34).
  7. Catch specific errors, never a bare except:, and record them with logging (Chapter 12).
  8. Keep secrets in environment variables, not in code; put secret files in .gitignore (Chapters 20, 49).
  9. Use parameters in SQL commands, never glue user text in (Chapters 24, 49).
  10. Commit small with a clear message, and reread before sending (Chapter 20).

Three of them (items 2, 8, 9) can be proven with a short script:

02_three_habits.py
# Part Ten - Three safe habits, proven with examples
import os
import sqlite3

# 1. Never glue user text into an SQL command; use a parameter (?).
db = sqlite3.connect(":memory:")
db.execute("CREATE TABLE staff (name TEXT, role TEXT)")
db.executemany("INSERT INTO staff VALUES (?, ?)", [("Sari", "admin"), ("Budi", "guest")])
user_input = "x' OR '1'='1"              # a mischievous entry
unsafe = db.execute(f"SELECT * FROM staff WHERE name = '{user_input}'").fetchall()
safe = db.execute("SELECT * FROM staff WHERE name = ?", (user_input,)).fetchall()
print("glued in directly ->", len(unsafe), "rows leaked")
print("with a parameter  ->", len(safe), "rows leaked")


# 2. Never use an empty list as a default value.
def add_bad(item, items=[]):
    items.append(item)
    return items


def add_good(item, items=None):
    items = [] if items is None else items
    items.append(item)
    return items


add_bad("A")
print("bad, second call:", add_bad("B"))
add_good("A")
print("good, second call:", add_good("B"))

# 3. Read secrets from an environment variable; never write them in the code.
key = os.environ.get("EXAMPLE_API_KEY")
print("key is set:", "yes (not shown)" if key else "no; stop with a clear message")
glued in directly -> 2 rows leaked
with a parameter  -> 0 rows leaked
bad, second call: ['A', 'B']
good, second call: ['B']
key is set: no; stop with a clear message

In the first part, the mischievous text x' OR '1'='1 leaks 2 rows when glued directly into SQL, but 0 rows when passed as a parameter. In the second part, add_bad remembers the contents of earlier calls (['A', 'B']) because the default empty list is created only once; add_good always starts fresh. In the third part, the key is not in this computer’s environment, and the script says so plainly without displaying anything.

WarningWARNING

Never paste an API key, password, or token into code, examples, or messages. If one has already been uploaded to a repository, treat that key as leaked and replace it (Chapter 49).

List 3: Ten Python libraries worth knowing

Chosen from those used in this book. The script below checks whether all ten are installed on the computer that built the book.

03_installed_libraries.py
# Part Ten - Ten libraries worth knowing: are they installed here?
from importlib.util import find_spec

LIBRARIES = [
    ("numpy", "numpy", 23),
    ("pandas", "pandas", 23),
    ("matplotlib", "matplotlib", 25),
    ("requests", "requests", 21),
    ("SQLAlchemy", "sqlalchemy", 24),
    ("pytest", "pytest", 18),
    ("Pydantic", "pydantic", 34),
    ("FastAPI", "fastapi", 36),
    ("GeoPandas", "geopandas", 38),
    ("scikit-learn", "sklearn", 25),
]
for name, module, chapter in LIBRARIES:
    found = find_spec(module) is not None
    print(f"{name:<13} (Ch {chapter}): {'installed' if found else 'NOT installed'}")
numpy         (Ch 23): installed
pandas        (Ch 23): installed
matplotlib    (Ch 25): installed
requests      (Ch 21): installed
SQLAlchemy    (Ch 24): installed
pytest        (Ch 18): installed
Pydantic      (Ch 34): installed
FastAPI       (Ch 36): installed
GeoPandas     (Ch 38): installed
scikit-learn  (Ch 25): installed
No Library Short purpose Home chapter
1 numpy number arrays and fast calculation 23
2 pandas data tables (DataFrame), read/write, aggregation 23
3 matplotlib charts 25
4 requests fetching data over HTTP/APIs 21
5 SQLAlchemy talking to databases from Python 24
6 pytest automatic tests 18
7 Pydantic data validation and settings 34
8 FastAPI building web APIs 36
9 GeoPandas spatial (map) data in a pandas style 38
10 scikit-learn classic machine learning 25, 54

Candidates for number eleven that are also worth knowing: Polars and DuckDB (Chapter 50), Rasterio (Chapter 39), and PyTorch (Chapter 55).

List 4: Ten free data sources for forestry, agriculture, fisheries, and livestock

How we checked. On 10 October 2026 we opened each source’s official page, noted what was written there, and where the page mentions terms or a licence we copied the gist. The script 04_check_links.py also confirms that each address answers “200” (it exists). Sources we could not open or read were left out.

== Data sources ==
 200  FAOSTAT
 200  FAO database terms of use
 200  Global Forest Watch (data portal)
 200  NASA FIRMS (active fires)
 200  NASA POWER (weather and climate)
 200  SoilGrids (soil)
 200  Copernicus Data Space (Sentinel)
 200  CHIRPS (rainfall)
 200  Global Fishing Watch (API)
 200  FAO Gridded Livestock of the World
 200  Satu Data Indonesia (national data portal)
 200  BMKG Data Online
12 of 12 answered 200 (exist)

== Learning sources ==
 200  Official Python tutorial
 200  python.org beginner's guide
 200  Exercism: Python track
 200  Official Python HOWTOs
 200  What's New in Python
 200  Python downloads
 200  pandas user guide
 200  scikit-learn user guide
 200  FastAPI tutorial
 200  GeoPandas documentation
 200  Python forum (Discourse)
 200  Python Discord
 200  PyCon ID 2026
 200  PyCon conference list
 200  PyVideo
 200  Planet Python
16 of 16 answered 200 (exist)

The output above was captured once (the script needs the internet and was not re-run when the book was built), and it shows 12 data-source addresses, including one FAO terms page and the extra BMKG item below the table.

No Source and address What it provides (per its page, read 2026-10-10) Terms or licence
1 FAOSTAT, https://www.fao.org/faostat/ food and agriculture statistics (page title; the data domains could not be read from the front page, check on the site) FAO’s database terms page states CC BY 4.0, unless stated otherwise for specific data or third-party data
2 Global Forest Watch (open data portal), https://data.globalforestwatch.org/ open forest data portal (only the page title could be read; browse its datasets yourself) each dataset has its own licence (service terms at globalnaturewatch.org/terms/)
3 NASA FIRMS, https://firms.modaps.eosdis.nasa.gov/ active fires and thermal anomalies from MODIS and VIIRS; global data arrive within about 3 hours; downloads in SHP, KML, TXT and a WMS service; archive available the front page states no licence; it links to “Acknowledgements & Citation” and “Disclaimer”, which you should read
4 NASA POWER, https://power.larc.nasa.gov/ more than 300 solar and meteorological parameters; an API and direct data access the front page states no terms of use or citation; read the POWER documentation
5 SoilGrids (ISRIC), https://isric.org/explore/soilgrids global soil-property maps at 250 m, six depths, with per-pixel uncertainty CC BY 4.0; note: its REST API was paused when read
6 Copernicus Data Space Ecosystem, https://dataspace.copernicus.eu/ free access to Sentinel mission data and other Copernicus data; browsable through the Copernicus Browser without signing up, an account adds more features terms are at the “Terms and conditions” link on its site
7 CHIRPS (rainfall), https://www.chc.ucsb.edu/data/chirps rainfall combining satellites and stations, 50°S to 50°N, 0.05° resolution, 1981 to near present the creator waived copyright (public domain, Creative Commons); version 2 production ends after December 2026, version 3 is available
8 Global Fishing Watch (API), https://globalfishingwatch.org/our-apis/ fishing effort, vessel identity, events (encounters, loitering, port visits), vessel and offshore-infrastructure detections free API key through an account; you must accept the terms and credit Global Fishing Watch; the page states no commercial ban, but read the full terms
9 FAO Gridded Livestock of the World, https://www.fao.org/livestock-systems/global-distributions/en/ global livestock distribution maps: buffaloes, cattle, chickens, ducks, horses, goats, pigs, sheep; fourth version, and a new 2024 set aligned with FAOSTAT 2020 data the page states no licence; it links to FAO’s “Terms and Conditions”
10 Satu Data Indonesia, https://data.go.id/ the official government data portal; 716,929 datasets from ministries and local governments were listed when read the front page states no licence; datasets are labelled “Terbuka” (open) or “Terbatas” (limited); check each dataset

One extra open and verified item: BMKG Data Online (https://data.bmkg.go.id/) offers village/ward-level weather forecasts for three days, earthquake data, and weather early warnings; the page states neither technical formats nor a licence.

NoteREMEMBER

Free does not mean free to use for anything. Many front pages carry no licence; the terms sit on another page or per dataset. Record the source, access date, and licence (Chapter 63) before using data in a report or product. This book does not download large data from these sources; its examples use mock data.

What we dropped. FAO FishStat (fao.org/fishery/en/fishstat) could not be opened when we tried (a temporary server error), so it is unverified and left out. Some other sites (for example BPS and GBIF) refused our automatic checker with a 403 code; that does not prove the sites are broken, but since we could not read them we did not list them. Try opening them yourself in a browser.

List 5: Ten follow-up project ideas from the running project

All of them can start from the Chapter 69 skeleton. Pick one, shrink its scope, finish it, and only then take the next.

No Idea Material from the book
1 A map of fire hotspots and forest cover for one district Chapters 38, 40, 51
2 A model of harvest yield against rainfall Chapters 27, 54
3 An early warning for pond water quality from sensor data Chapters 52, 58
4 Livestock growth curves and a cost-saving ration suggestion Chapters 27, 57, 59
5 Detecting and counting trees from drone photos Chapters 56, 59
6 A question-answering assistant for technical guidance (RAG) Chapters 60, 62
7 A cross-sector dashboard for extension officers Chapters 42, 43
8 A scheduled daily pipeline: fetch, validate, store, report Chapters 41, 50
9 A distributed worker service for thousands of photos Chapters 66, 67
10 Publish the package as a library and a portfolio showcase Chapters 45, 68

List 6: Ten ways to keep learning Python after this book

Every resource below was opened and checked on 10 October 2026 (see the output of the script 04_check_links.py above, under “Learning sources”). What we say about their contents comes from the page itself when marked “(read)”; otherwise they are only proven to exist, and we have not studied the contents one by one.

No Way Address Note
1 Read the official Python tutorial https://docs.python.org/3/tutorial/ an introduction for people who already program, from basics to the standard library (read)
2 Browse the python.org beginner’s guide https://www.python.org/about/gettingstarted/ how to install, and a list of learning resources, libraries, and ways to contribute (read)
3 Practise problems on Exercism https://exercism.org/tracks/python a free Python track with automatic feedback and mentoring (read: 146 exercises in 17 concepts)
4 Study the official HOWTOs by topic https://docs.python.org/3/howto/ the page exists; contents not studied
5 Get friendly with the documentation of your chosen libraries pandas: https://pandas.pydata.org/docs/user_guide/; scikit-learn: https://scikit-learn.org/stable/user_guide.html; FastAPI: https://fastapi.tiangolo.com/tutorial/; GeoPandas: https://geopandas.org/en/stable/ the pages exist; contents not studied
6 Ask on the official Python forum https://discuss.python.org/ a community forum with categories including Python Help and Packaging (read)
7 Join Python Discord https://www.pythondiscord.com/ an online community that welcomes beginners, with help channels and events (read)
8 Attend PyCon Indonesia and see the world list of PyCons https://2026.pycon.id/ and https://pycon.org/ PyCon ID 2026 ran 8-9 August 2026 in Jakarta (read), so it is already over; check the next edition
9 Watch conference recordings on PyVideo https://pyvideo.org/ an index of Python conference videos; when read it listed about 21,700 talks from 542 events
10 Follow the news through Planet Python and What’s New https://planetpython.org/ and https://docs.python.org/3/whatsnew/ an aggregator of Python blogs (read); release notes for each version

A bonus outside the list, and the most powerful one, needs no address: build something you need yourself, however small, and improve it bit by bit.

TipTIP

Web pages change, move, and sometimes vanish. If a link in this part is dead when you open it, search for the source’s name and enter through its official site. If anything contradicts this book, trust the latest official documentation and check your version number.

Happy onward journey. Your garden has only just begun.