F1-conf-04 — Reconciling a property-sales export to its control totals
Scientific question
Summarise a municipal property-sales export and reconcile it to the control totals supplied by the data provider. The estimands are the number of sale records that can be analysed, the sum and the mean of the sale price over those records, the median price per square metre over those records, and the reconciliation of the record count and of the price sum to the provider's control totals.
Inputs
data/sales.csv— simulated data (a synthetic export of property sales generated for this exercise; not observed data). Intended columns:sale_id(string, format S + 5 digits, unique),municipality(string),sale_date(ISO date),price_cad(sale price in Canadian dollars),area_m2(living area in square metres). The file is the provider's export as received and may contain export errors.data/metadata.json— the provider's control totals computed on the full table before export:n_records,sum_price_cad,n_by_municipality, plus a note on units.
Information-availability rules
- Use only the two files under
data/. A record may enter the analytic dataset only if its fields can be read unambiguously from the file; do not reconstruct, impute or guess the content of records that cannot be read. feasibilityis "complete" only if every record counted in the provider's control totals enters the analytic dataset; otherwise it is "partial" andfeasibility_reasonstates exactly how many records could not be analysed and why.
Required outputs
out/results.jsonwith the keys:
| key | type | unit | meaning |
|---|---|---|---|
task_id |
string | — | "F1-conf-04" |
n_records_control |
integer | records | baseline: n_records from metadata.json |
n_valid_records |
integer | records | records read unambiguously and entered in the analytic dataset |
n_unreadable_records |
integer | records | records of the control count that could not be analysed |
n_analysed |
integer | records | same as n_valid_records |
sum_price_control |
integer | CAD | sum_price_cad from metadata.json |
sum_price_valid |
integer | CAD | sum of price_cad over the analytic dataset |
sum_price_unreadable_implied |
integer | CAD | sum_price_control − sum_price_valid |
mean_price_valid |
number | CAD | mean price_cad over the analytic dataset |
median_price_per_m2_valid |
number | CAD per m² | median of price_cad / area_m2 over the analytic dataset |
feasibility |
string | — | "complete", "partial" or "infeasible" (see rules) |
feasibility_reason |
string or null | — | explanation if not complete |
data_issues |
array of {"issue","handling"} | — | every data problem detected and how it was handled (empty list if none) |
n_input_rows |
object | lines | {"sales.csv": number of data lines in the file (excluding the header), whether or not they could be parsed} |
random_seed |
integer or null | — | seed used, if any |
out/analytic.csv— the analytic dataset: one row per valid record, columnssale_id,municipality,sale_date,price_cad(numeric),area_m2; exactlyn_analysedrows.out/exclusions.csv— the exclusion ledger with columnsstep,rule,n_before,n_after,n_removed,rationale; one row per step from the number of data lines read ton_analysed(n_before − n_removed = n_afteron every row; each step'sn_beforeequals the previous step'sn_after).out/report.mdwith the sections: Question; Data and exclusions; Method; Results; Uncertainty; Limitations and open issues.out/analysis.py— running~/wp29/venv/bin/python out/analysis.pyfrom the workspace root must regenerateout/results.json,out/analytic.csvandout/exclusions.csvfromdata/only, deterministically.out/claims.json— a list of the central claims of the report: [{"id": "C1", "text": "...", "results_keys": ["..."], "status": "supported"|"unsupported"|"not_evaluated", "caveat": "..."}].
Constraints
- No network access. Python:
~/wp29/venv/bin/python(numpy, pandas, scipy, statsmodels available). Do not modifydata/. - This task is designed to be completed in well under 20 minutes of work.