Plain text, not perfect data
Each line should look like name|quantity|price. Some lines will be blank, malformed, or contain a number that cannot be converted.
Connect strings, lists, dictionaries, loops, functions, errors, and JSON in one small program. The input is messy on purpose; the output should be predictable.
Each line should look like name|quantity|price. Some lines will be blank, malformed, or contain a number that cannot be converted.
Return items, a grand total, and a list of errors. Printing is only a view of that result, not the result itself.
Use Python's built-in strings, lists, dictionaries, functions, exceptions, and json module. No packages, files, network, or input().
Split the receipt into lines. Strip whitespace and skip empty lines, but keep the line number so an error message can point to the right row.
Split each line on the pipe character. Require exactly three fields, convert quantity to int and price to float, and reject empty names.
A quantity must be positive and a price cannot be negative. Collect an error and continue; one bad row should not destroy the whole receipt.
Build an item dictionary with a rounded line_total. Sum the line totals once, at the end, so the grand total cannot drift from the rows.
Return a dictionary with items, total, and errors. Format a readable report in a separate function, then print a JSON summary for inspection.
A predictable structure is easier to test than a pile of printed text.
{
"items": [
{"name": "Latte", "qty": 2, "price": 4.5, "line_total": 9.0}
],
"total": 18.75,
"errors": []
}The starter runs and returns an empty result. Fill in the TODO, then run it. The solution includes the valid receipt and a malformed receipt as a self-check.
Accept an optional discount rate, validate it, and apply it to the grand total. Keep the original total visible in the result.
When the csv module is comfortable, replace the pipe-separated fixture with a small CSV file and reuse the same validation.
Turn the three acceptance cases into assert statements. Run them after every change before you touch the formatting.