NA446A Python for data you can trust

Sample exam, Python part

Twenty questions in the format of the real exam. Answer without AI and without running code, then check.

Work without a computer, as in the exam hall: read the code and predict. Give yourself 45 minutes. Every question has one correct answer; a wrong answer costs nothing, so answer them all. The real exam is in WISEflow and also covers Part I (MATLAB).

1. Why does the course use paths like ROOT / "data" / "raw" instead of C:/Users/anna/Desktop/project/data/raw?

A. It makes the code run faster B. Windows cannot read long paths C. The project then runs on any computer where the folder is copied D. pandas only accepts paths that start with the project folder’s name on every computer

2. In Bastani et al. (2025), which design avoided most of the harm to learning?

A. An AI tutor that gave teacher-designed hints, not answers B. A plain chatbot interface like standard ChatGPT C. Letting students use the AI in the exam as well D. Giving students more practice problems to solve with the plain AI before the exam

3. What does the last line print?

a = "20"
b = "24"
print(a + b)

A. An error B. 44 C. 20 24 D. 2024

4. What does the last line print?

x = [3, 1]
x.append(2)
print(x[-1] + len(x))

A. 3 B. 5 C. 6 D. 4

5. What does the last line print?

years = [2019, 2020, 2021, 2022, 2023]
print(years[1:3])

A. [2020, 2021] B. [2021, 2022] C. [2020, 2021, 2022] D. [2019, 2020, 2021]

6. What is the first value of top?

import pandas as pd
df = pd.DataFrame({"firm": ["A", "B", "C"], "sales": [120, 300, 90]})
top = df.sort_values("sales", ascending=False)["firm"]

A. 300 B. B C. A D. C

7. What is the last value of df["wage_k"]?

import pandas as pd
df = pd.DataFrame({"wage": [25000, 31000, 40000]})
df["wage_k"] = df["wage"] / 1000

A. 4.0 B. 40000 C. 40.0 D. An error

8. What does the last line print?

import pandas as pd
origin = pd.Series([1, 3, 2])
names = {1: "US", 2: "Europe", 3: "Japan"}
region = origin.map(names)
print(region.iloc[1])

A. Europe B. 3 C. US D. Japan

9. A CSV column holds values like 12, 15 and “****” (a missing-value code). What type does pandas give the column when it reads the file?

import io
import pandas as pd
df = pd.read_csv(io.StringIO("id,income\n1,12\n2,15\n3,****\n"))
kind = "text" if df["income"].dtype.kind in "OUT" else "number"

A. date B. category C. number D. text

10. How many rows does df have after the last line?

import pandas as pd
df = pd.DataFrame({"region": ["N", "N", "S"], "wage": [100, 200, 90]})
df["mean_wage"] = df.groupby("region")["wage"].transform("mean")

A. 2 B. 6 C. 3 D. 1

11. A panel has one row per person and year. What does df.groupby("pid")["year"].nunique().max() tell you?

A. The largest number of years any one person is observed B. The number of persons who are observed in every year of the panel C. The number of rows D. The last year in the data

12. According to Gentzkow and Shapiro (2014), what must be true of a table’s key?

A. It is a number, never text B. It uniquely identifies each row and is never missing C. It is the first column of the table D. It is the same variable, with the same name, in every table of the project

13. How many rows does long have?

import pandas as pd
wide = pd.DataFrame({"pid": [1, 2, 3], "wage2023": [100, 110, 90], "wage2024": [105, 112, 95]})
long = wide.melt(id_vars="pid", var_name="year", value_name="wage")

A. 3 B. 2 C. 9 D. 6

14. What does the last line print?

import pandas as pd
persons = pd.DataFrame({"id": ["P1", "P1", "P2", "P2", "P3"],
                        "country": ["SE", "SE", "SE", "NO", "SE"]})
a = persons.duplicated("id").sum()
b = persons.duplicated().sum()
print(a, b)

A. 4 2 B. 2 2 C. 2 1 D. 1 2

15. Why does this merge find no matches?

import pandas as pd
a = pd.DataFrame({"pid": [1, 2, 3]})
b = pd.DataFrame({"pid": ["1", "2", "3"], "wage": [100, 110, 90]})
try:
    m = a.merge(b, on="pid", how="left")
    res = "ran"
except ValueError:
    res = "pandas refuses: the key is a number in one table and text in the other"

A. ran B. pandas refuses: the key is a number in one table and text in the other C. The keys have different names in the two tables, so pandas cannot match them D. b has too few rows

16. What is the test that a project is reproducible?

A. Delete all outputs, run the run-all script once, and get the same tables and figures B. Open every output file and check by eye that each table and each figure looks as it did before C. Ask a classmate to read the code D. Save the data in two formats

17. What does the last line print?

def clean(x):
    return x.strip().lower()

names = [" Lund", "UMEÅ ", "Malmö"]
print([clean(n) for n in names])

A. [‘lund’, ‘umeå’, ‘malmö’] B. [’ Lund’, ‘UMEÅ’, ‘Malmö’] C. An error D. [‘Lund’, ‘Umeå’, ‘Malmö’]

18. Why does the script call r.raise_for_status() right after r = requests.get(URL, timeout=30)?

A. To make the download from the server faster B. To stop with an error if the server did not send the data C. To turn the server’s answer into a DataFrame with one row per month D. To save the server’s answer in data/raw/

19. What does the last line print?

def double(x):
    y = 2 * x

print(double(4))

A. 4 B. 8 C. None D. An error

20. Quarterly GDP is 100 in 2023Q1 and 103 in 2024Q1. Which line gives year-on-year growth in per cent for quarterly data?

A. 100 * gdp.pct_change(1) B. 100 * gdp.diff(4) C. gdp.pct_change(12) D. 100 * gdp.pct_change(4)

Answers and why

Show the answers (try first)
  1. C. An absolute path works on one computer only; a path from the project root travels with the project.
  2. A. GPT Tutor, with prompts that safeguard learning, largely removed the drop in exam grades seen with GPT Base.
  3. D. + joins strings; convert with int() first if you want arithmetic.
  4. B. append adds 2 at the end; x[-1] is the last element (2) and the list has 3 elements.
  5. A. A slice includes the start position and stops before the end position: positions 1 and 2.
  6. B. ascending=False puts the largest sales first (Stata: gsort -sales).
  7. C. A new column is computed for every row at once (Stata: gen wage_k = wage/1000).
  8. D. map looks up each code in the dictionary; iloc[1] is the second row (counting from 0), code 3.
  9. D. One non-numeric entry makes the whole column text; replace the code with missing and convert with pd.to_numeric.
  10. C. transform keeps every row and adds the group mean to each (Stata: bysort region: egen), unlike agg, which collapses.
  11. A. nunique counts distinct years within each person; max gives the longest observed history.
  12. B. Their rule A in the Keys chapter: store cleaned data in tables with unique, non-missing keys.
  13. D. Wide to long gives one row per person and year: 3 x 2 = 6 (Stata: reshape long).
  14. C. Two rows repeat an id; only one of them repeats every column. P2 is a real conflict (SE or NO), not a copy: drop_duplicates() would not remove it.
  15. B. The same id stored as 1 and as “1” is not the same key; make the types equal (e.g. astype(int)) before merging.
  16. A. If every output can be rebuilt from raw data by one script, the project is reproducible.
  17. A. One function applied to every element: strip removes spaces, lower changes the case (Swedish letters included).
  18. B. A failed request still returns an answer (an error page); raise_for_status turns it into an error instead of letting bad data flow on.
  19. C. Without return, a function gives back None; computing y inside is not enough.
  20. D. Year on year compares with the same quarter a year earlier: four quarters back.