Choose a Python first book and build a program you can test
The useful first milestone is a small program whose behavior you can explain, change and test—not a long list of syntax you have seen. Choose one main book and carry a single data-summary task through prediction, functions, collections, files and tests. The other books become targeted references rather than competing reading schedules.
Course topic: Introduction to Programming
Study route and exercise: University Reading List editorial project. How we curate · Sources checked:
Scope and responsibility
For new programmers comfortable with basic arithmetic and using files. References follow Think Python 3e, Python Crash Course 3e and Guttag’s Introduction to Computation and Programming Using Python 3e. These are site-created study activities. The numerical dataset and function are invented for this guide, not copied book exercises or a production monitoring system.
Choose your starting point
I want a free, explanation-led first route
Use the author’s Think Python webbook and run its notebooks or your own small local files. Keep a prediction log: write what a line will do before running it. Free online access does not mean the printed book is free.
I learn best by building a visible project
Use Python Crash Course Part I, then choose one Part II project. Finish a small tested core before adding graphics or a website; three simultaneous library stacks obscure whether a bug is in your own logic.
I want computational models and data analysis
Use Guttag, beginning with its early programming chapters and testing. It can be a first text for a mathematically comfortable beginner, but its later simulations and data methods are a longer route than learning basic syntax.
Compare the three books
Think Python: How to Think Like a Computer Scientist
Allen B. Downey · Edition: 3 · 2024
Free conceptual starting point
- Choose it when
- You want small runnable examples, explicit vocabulary and incremental explanation before building a large application.
- Use another route when
- You need an assigned project stack or a full course in statistical modeling immediately.
- Selected reading
- Use chapters 1–3, 5–7 and 9–10 for this route; chapter 8 helps with text and 13 with files. Objects in 14–17 can wait.
- Limits and trade-offs
- The third edition reorders material and uses notebooks. An old second-edition chapter number may point elsewhere. The author provides a free web version; Colab is an optional third-party execution service, not a course certificate.
Try before choosing
After Think Python’s list/dictionary chapters, trace a function on[("A",0),("A",None),("A",6)] without running it. Draw the total and count after each row.
Check your work: The final pair is total 6,count 2 and mean 3.0. None adds no count; zero does. You can explain the state changes rather than only repeat the final output.
Python Crash Course: A Hands-On, Project-Based Introduction to Programming
Eric Matthes · Edition: 3 · 2022
Guided project path
- Choose it when
- You want a concrete game, data-visualization or web-app outcome, and can work through language basics first.
- Use another route when
- You are still unable to trace a short loop or function; starting with a whole web framework may hide that gap.
- Selected reading
- Part I chapters 1–8, 10–11 support this route. The larger projects are 12–14, 15–17 and 18–20; choose one after your small program works.
- Limits and trade-offs
- No Starch lists the third edition as December 2022. Check the author’s corrections and updated deployment instructions instead of assuming a printed service name or dependency version remains current.
Try before choosing
After Python Crash Course chapters 10–11, separate the calculation from file/input handling and write three small tests for empty, zero-only and all-missing data.
Check your work: The calculation accepts rows and returns a result without opening a file. The three cases have distinct expected contracts, and a test can fail without manually interacting with a project.
Introduction to Computation and Programming Using Python
John V. Guttag · Edition: 3 · 2021
Computational problem-solving extension
- Choose it when
- You want to connect programs to algorithms, simulation and interpretation of data, with explicit mathematical assumptions.
- Use another route when
- Your only immediate goal is a small first Python script, or you need a deployment tutorial rather than a computation course.
- Selected reading
- Start with 1–5 and 7–9. Chapters 11–12 extend algorithms; 16–22 address simulation and statistics, and 23 introduces pandas.
- Limits and trade-offs
- The selected third edition was published in 2021 and includes a Python 3.8 reference. It is not a promise that every historical library example runs unchanged today; isolate dependencies and consult the book’s code and errata.
Try before choosing
Using Guttag’s early functions/testing route, state the accepted data contract and a loop invariant linking accumulated totals and counts to processed rows.
Check your work: The invariant covers only accepted rows seen so far; it distinguishes missingness from magnitude. Explain one input outside the contract and one numerical limit not established by ordinary unit tests.
Check your preparation
Is the string "12" the same object value as the number 12?
No. They have different types and support different operations. Convert input deliberately and decide what an invalid value should do before relying on arithmetic.
Are zero and missing data interchangeable?
No. Zero can be a valid observation; None marks missing data in the case below. Both are false in a truth test, so the filter must express the data rule explicitly.
What should a function promise before you implement it?
Specify accepted input, returned output and edge behavior. Here sites with no valid readings are omitted, the caller’s rows are preserved, and no valid reading means no computed mean—not a fabricated zero.
Six steps with a concrete output
Outputs marked ready: 0 / 6
These are your own study marks, not an assessment. They are not sent to this site.
-
1. Predict short expressions and inspect their types
Selected reading: Think Python 1–2; Crash Course 1–2; Guttag 1–2.
Make this: Create a tiny notebook or script with six expressions involving numbers, strings, comparison and division. Write a predicted value and type before each run, then explain any disagreement.
Check your work: A displayed result is not accepted without an explanation. You can distinguish a number, its printed text and the string received from input.
-
2. Translate a data rule into a condition
Selected reading: Think Python 5 and 7; Crash Course 4–5 and 7; Guttag 2.3–2.6.
Make this: Trace the original rows below by hand. Mark which records count, including a zero and a missing value, then write a loop that visits each row once.
Check your work: The zero is retained and only None is skipped. Changing the order does not change which observations count; the loop does not remove items from the collection it is traversing.
-
3. Give the calculation a contract
Selected reading: Think Python 3 and 6; Crash Course 8; Guttag 4.
Make this: Write a function specification naming its input, output and empty-input behavior. Separate returning the computed value from printing a friendly report.
Check your work: Another person can call the function without typing at a prompt. A caller can use the returned result, and the original input remains unchanged.
-
4. Accumulate by key, then compute
Selected reading: Think Python 9–10; Crash Course 3–4 and 6; Guttag 5.
Make this: Implement the worked example with separate total and count dictionaries. Add one new site and trace how its first valid reading creates its entries.
Check your work: Each valid row increments exactly one count and adds once to its site total. Never divide by the number of sites or by rows containing missing values.
-
5. Make files and failures visible
Selected reading: Think Python 8 and 13; Crash Course 10; Guttag 7 and 9.
Make this: Save a small local fixture and write a separate loader. Document how blank, malformed or nonnumeric fields are handled; keep those choices outside the already specified mean function.
Check your work: A failed file load is reported, not silently replaced with an empty successful result. Test input contains invented data and does not require personal or production records.
-
6. Deliver a small reproducible project
Selected reading: Revisit Think Python 7 and 9; Crash Course 11; Guttag 8.
Make this: Submit the function, fixture, tests and a README stating how to run them. Test the baseline, empty input, all-missing input, zero-only input, unchanged input and reordering or duplication.
Check your work: The expected values were calculated independently, not copied from the program output. A reader can rerun your case and identify unsupported inputs; a passing tiny case is not a claim of production readiness.
Worked exercise
Zero is a reading; None is not
For rows [("A", 12), ("B", None), ("A", 0), ("B", 8), ("A", 18)], return the mean of valid readings for each site. Keep zero, skip None, omit sites with no valid reading and leave the input rows unchanged.
Assumptions
Each row has a string site and either a finite integer/float or None; booleans, malformed rows and NaN are outside this exercise’s accepted input. All readings use the same arbitrary unit. Empty or entirely missing input returns an empty dictionary. This is an invented teaching dataset. Reading magnitudes and row counts must also keep each running total finite; this simple floating-point calculation does not handle overflow or promise exact arithmetic for all finite inputs.
- Inspect the rows before coding: A has 12, 0 and 18, totaling 30 across three readings. B has one valid reading, 8; its None contributes neither a value nor a count.
- Initialize separate total and count dictionaries. For each row, use value is None to decide whether to skip; do not use if value as the validity rule.
- For a valid row, add its value to that site’s total and increment that site’s count. After the loop, divide each recorded total by its corresponding count.
- A returns 30 / 3 = 10.0 and B returns 8 / 1 = 8.0. Sites never given a valid observation have no total/count entry and are omitted, so no zero denominator is created.
- A truthiness filter would wrongly drop A’s zero and report (12 + 18) / 2 = 15.0. That program can run without an exception while still answering the wrong question.
Answer and interpretation
The result is {"A": 10.0, "B": 8.0}. The complete function below expresses the stated data rule; it returns results without changing the input or coupling the calculation to a file, notebook or user prompt.
def means_by_site(rows):
totals = {}
counts = {}
for site, value in rows:
if value is None:
continue
totals[site] = totals.get(site, 0) + value
counts[site] = counts.get(site, 0) + 1
means = {}
for site in totals:
means[site] = totals[site] / counts[site]
return means
Test the result
Check [] → {}, [("A", None)] → {} and [("A", 0)] → {"A": 0.0}. For the supplied small integers, reordering rows or duplicating every valid row preserves the means. General floating-point inputs need separate rounding analysis; do not promise exact order invariance. A row such as ("A", "bad") needs an explicit validation policy outside this limited contract.
Change an assumption
Combining batches needs counts, not just means
Split the original invented rows into batch1=[("A",12),("A",0),("B",None)] and batch2=[("A",18),("B",8)]. Retain the accepted input and missing-data rules. Find per-site means after combining batch summaries without retaining raw rows; decide whether an unweighted mean of the batch means is sufficient. Use these small exactly representable integers.
- Batch1 gives A:(total 12,count 2) and no valid B summary. Batch2 gives A:(18,1), B:(8,1). An absent summary is not a measured zero.
- Combine each site’s totals and counts: A:(30,3), B:(8,1). Dividing once gives A10.0 and B8.0, as processing all original rows together does.
- A’s batch means are 6 and 18. Their unweighted mean is 12, wrong because the batch counts differ. Weighted mean(2×6+1×18)/(2+1)=10 reproduces the combined result.
Answer and interpretation
Retain a(total,count) pair for each site in each batch, add those pairs componentwise, then divide. A mean without its count cannot generally recover the pooled mean; the shown batches return{"A":10.0,"B":8.0}.
Test the result
Move one row between batches and recompute: the pooled result for these small integers is unchanged, while unweighted batch means may change. For general floating-point inputs, mathematical regrouping does not guarantee bit-for-bit equality; assess rounding and a justified error bound separately.
Common mistakes
A plausible output is not a verified program
The wrong answer A = 15.0 looks ordinary. Keep a hand-calculated example that distinguishes your intended rule from a tempting but incorrect implementation.
Confusing a book version with a software environment
Book chapter maps stay edition-specific while project dependencies and hosting instructions evolve. Record your actual Python and library versions, and read the author’s updates before following old deployment steps.
Adding libraries before isolating the logic
The mean function needs only Python’s built-ins. Test it independently before attaching plotting, CSV loading or a web interface; otherwise environment errors and logic errors become harder to separate.
Before moving on
- You can select a conceptual, project-led or modeling-oriented main book and explain which later topics you are postponing.
- You can trace the worked function, justify the treatment of zero and None, and state what happens when a site has no valid readings.
- Your small project includes independently expected outputs, edge checks and run instructions, with no claim that a few passing examples prove universal correctness.
Sources and edition checks
Sources checked:
- Allen B. Downey — free third-edition webbook and contents
The author’s third-edition webbook confirms the free text, notebook route and chapter order. Optional hosted notebooks are distinct from reading the text; this guide does not reproduce the book’s exercises.
- O’Reilly — third-edition publication and copyright details
The publisher’s copyright page records the 2024 third edition and its release history. Its online-product ISBN and errata reference differ; the existing print ISBN is not replaced merely because a platform uses another identifier.
- No Starch Press — third-edition ISBN, date and contents
The publisher supplies the third-edition ISBN, December 2022 release and twenty-chapter map. Project choices and this guide’s data-summary task are independent study suggestions.
- Eric Matthes — third-edition corrections and project updates
The author maintains printing-specific corrections and separate deployment updates. Do not use a changing web page’s old introductory sentence as evidence of today’s exact printing count.
- MIT Press — Guttag third edition and format-specific ISBNs
MIT Press identifies the 2021 third-edition paperback ISBN 9780262542364 and a separate ebook ISBN/date. It describes computation and data modeling, not a guarantee of current dependency compatibility.
- MIT Press — third-edition table of contents
The official PDF verifies the selected third-edition chapters: functions 4, structured types 5, files 7, testing 8, exceptions 9 and pandas 23. Later modeling topics are optional extensions here.
- Python documentation — truth values, including zero and None
Python’s own type documentation confirms that zero and None both test false. The function, values, error counterexample and checks in this guide were created and independently executed for this site.
- Python documentation — floating-point representation and accumulation limits
The official numerical tutorial explains representation and accumulation error. The small integer examples here permit exact checks, but a general floating-point contract does not guarantee identical results under regrouping.
These are proposed study activities, not official course assignments or a claim that every book has been read cover to cover.