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
- Give meaningful names.
compute_biomassbeatsh. Follow PEP 8 and letruffcheck it (Chapter 19). - One function, one job, and never use an empty list as a default value (see the example below) (Chapter 10).
- Open files with
withand writeencoding="utf-8"explicitly (Chapter 13). - One environment per project, with its dependencies recorded (Chapter 17).
- Write tests for what matters, for the success path and the failure path (Chapter 18).
- Use type hints and validate incoming data with Pydantic (Chapters 33, 34).
- Catch specific errors, never a bare
except:, and record them withlogging(Chapter 12). - Keep secrets in environment variables, not in code; put secret files in
.gitignore(Chapters 20, 49). - Use parameters in SQL commands, never glue user text in (Chapters 24, 49).
- 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.
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.
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.
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.