Exercise 8: An Inventory Table — Possible Solution ==================================================================== stock = { "Widget": (120, 2.5), "Sprocket (large)": (8, 14.75), "Bolt": (5400, 0.05), } width = max(len(name) for name in stock) print(f"{'Item':<{width}} {'Qty':>7} {'Price':>8} {'Value':>10}") print("-" * (width + 31)) grand_total = 0 for name, (qty, price) in stock.items(): value = qty * price grand_total += value print(f"{name:<{width}} {qty:>7,} £{price:>7.2f} £{value:>9,.2f}") print("-" * (width + 31)) print(f"{'Total':<{width}} {'':>7} {'':>8} £{grand_total:>9,.2f}") Output: Item Qty Price Value ----------------------------------------------- Widget 120 £ 2.50 £ 300.00 Sprocket (large) 8 £ 14.75 £ 118.00 Bolt 5,400 £ 0.05 £ 270.00 ----------------------------------------------- Total £ 688.00 WHY THIS WORKS AS AN ANSWER ------------------------------ width is calculated from the data, so the table fits the longest name and nothing is hard-coded. {name:<{width}} nests one pair of braces inside the format spec, which is how a variable supplies the width. The separator line is width + 31 because the three number columns are 7, 8 and 10 characters wide and each is preceded by a 2-space gap: 2 + 7 + 2 + 8 + 2 + 10 = 31. {qty:>7,} right-aligns and adds thousands separators, and the pound sign sits in the literal text, with the numbers formatted inside the 8- and 10-character fields. The for target name, (qty, price) unpacks each value tuple on the way in.