PythiloLesson 13 of 15 · progress kept in this browser

One reason to change

A class or module should have one responsibility, which in practice means one reason to change. A report class that parses a file, applies business rules and formats text has to change whenever any of the three does, and testing its rules means building a file first.

class Invoice:
    def __init__(self, lines):
        self.lines = lines

    def total(self):
        total = 0
        for qty, price in self.lines:
            total += qty * price
        return total

def render(invoice):
    return f"Total: {invoice.total():.2f}"

print(render(Invoice([(2, 1.5), (1, 4.0)])))

Invoice knows the rules and render knows the layout. A new layout leaves Invoice alone.

Your task

Split SalesReport into parse_sales(csv_text) returning (region, amount) pairs, a class SalesTotals(rows) whose by_region() returns a dict of sums, and render_totals(totals) producing the old text. sales_report(csv_text) connects them and returns what SalesReport(csv_text).text() did.