Clean it with a log, and see what it cost to trust the file
This is src/data/clean.js with its exports removed and a demo underneath. The 2025-03-32 row is dropped, not read as 25 March: the log says why.
Real exports have blanks, "n/a", numbers with commas, impossible dates and outliers. Look first, then fix only what is certain, flag what is missing, drop what cannot be placed, never invent values, and keep a log of every change.
Change the code and press Run (Ctrl+Enter). Predict what will happen first, then break it on purpose and read what changes. Your edits are saved and match the lesson page.
Ready for more? This phase has 5 hands-on exercises with automatic checks.
Practice questions
Write the code in the editor, run it, then open the model answer to compare.
Add a rule to cleanDaily that flags temp_c below −30 or above 45 as null with a reason. Run it on daily.csv and report how many notes it writes.
Write missingDays(rows, from, to) returning the YYYY-MM-DD texts of days between two dates that have no row.
Explain it without notes
Why is null better than 0 for a missing day?
Name three actions a cleaner can take on a bad row, with an example of each.
Why does the cleaner refuse to read 2025-03-32 as 25 March?
Preview
Console
Nothing logged yet.Expected console output
Rows in the file: 32 | rows kept: 30
FLAGGED 2025-03-04 rides "" -> null (no usable number, kept as missing)
FLAGGED 2025-03-08 temp_c "n/a" -> null (no usable number, kept as missing)
FIXED 2025-03-11 rides "2,016" -> 2016 (comma was a thousands separator)
FIXED 13/03/2025 date "13/03/2025" -> "2025-03-13" (day-first date: 13 cannot be a month)
FLAGGED 2025-03-16 rain_mm "-1" -> null (-1 is a sensor code for no reading, not rain)
FIXED 2025-03-19 weekday "wed" -> "Wed" (taken from the date)
DROPPED 2025-03-21 row "2025-03-21" -> null (exact duplicate of an earlier row)
DROPPED 2025-03-32 date "2025-03-32" -> null (not a real calendar day, so it cannot be placed on the chart)
FLAGGED 2025-03-27 avg_minutes "1240" -> null (an average ride cannot last more than 3 hours)
Total rides if you just use +rides: 59415
Total rides after cleaning: 56930
March days with no row: [ '2025-03-25' ]
Rows whose rides is null (kept as gaps): [ '2025-03-04' ]