The csv module can turn text rows into dictionaries, so a small report can filter and summarize records without manual splitting.

CSV dictionary rows `csv.DictReader` reads the header row and gives each later row named fields.

CSV Inventory Report

min_stock
csv_inventory_report.py
Replay: real traced execution (multi-file project)
import csv
from io import StringIO

csv_text = """sku,name,stock
A1,notebook,6
B2,pencil,3
C3,folder,12
"""

min_stock = 5

reader = csv.DictReader(StringIO(csv_text))
included = []
for row in reader:
    stock = int(row["stock"])
    if stock < min_stock:
        continue
    included.append(row["name"] + ":" + str(stock))

print("included=" + ",".join(included))
print("count=" + str(len(included)))
import csv
from io import StringIO

csv_text = """sku,name,stock
A1,notebook,6
B2,pencil,3
C3,folder,12
"""

min_stock = 3

reader = csv.DictReader(StringIO(csv_text))
included = []
for row in reader:
    stock = int(row["stock"])
    if stock < min_stock:
        continue
    included.append(row["name"] + ":" + str(stock))

print("included=" + ",".join(included))
print("count=" + str(len(included)))
import csv
from io import StringIO

csv_text = """sku,name,stock
A1,notebook,6
B2,pencil,3
C3,folder,12
"""

min_stock = 10

reader = csv.DictReader(StringIO(csv_text))
included = []
for row in reader:
    stock = int(row["stock"])
    if stock < min_stock:
        continue
    included.append(row["name"] + ":" + str(stock))

print("included=" + ",".join(included))
print("count=" + str(len(included)))
  1. csv_text ← sku,name,stock A1,notebook,6 B2,pencil,3 C3,folder,12

    4csv_text→ sku,name,stock
    A1,notebook,6
    B2,pencil,3
    C3,folder,12
     = """sku,name,stock5A1,notebook,66B2,pencil,37C3,folder,128"""910min_stock→ 5 = 5  #@min_stock=3, 101112reader→ ⟨DictReader A⟩ = csv<module 'csv' from '/usr/local/lib/python3.12/csv.py'>.DictReader(StringIO(csv_textsku,name,stock
    A1,notebook,6
    B2,pencil,3
    C3,folder,12
    ))13included→ [] = []14for row in reader:
  2. stock ← 6, included ← ['notebook:6']

    pass 1 of 3
    13included = []14for row{'sku': 'A1', 'name': 'notebook', 'stock': '6'} in reader⟨DictReader A⟩:15    stock→ 6 = int(row["stock"]6)16    if stock < min_stock:17        continue18    included→ ['notebook:6'].append(row["name"]notebook + ":" + str(stock6))
    All 3 passes — pass 1 is the card above
    passrowrow[”stock”]row[”name”]min_stockstockincluded
    1{'sku': 'A1', 'name': 'notebook', 'stock': '6'}6notebook6[] ['notebook:6']
    2{'sku': 'B2', 'name': 'pencil', 'stock': '3'}353
    3{'sku': 'C3', 'name': 'folder', 'stock': '12'}12folder12['notebook:6'] ['notebook:6', 'folder:12']
  3. if stock < min_stock:

    15stock = int(row["stock"])16if stock3 < min_stock5:17    continue18included.append(row["name"] + ":" + str(stock))
  4. print("included=" + ",".join(included))

    20print("included=" + ",".join(included['notebook:6', 'folder:12']))21print("count=" + str(len(included['notebook:6', 'folder:12'])))
    outputincluded=notebook:6,folder:12
    count=2
  1. csv_text ← sku,name,stock A1,notebook,6 B2,pencil,3 C3,folder,12

    4csv_text→ sku,name,stock
    A1,notebook,6
    B2,pencil,3
    C3,folder,12
     = """sku,name,stock5A1,notebook,66B2,pencil,37C3,folder,128"""910min_stock→ 3 = 31112reader→ ⟨DictReader A⟩ = csv<module 'csv' from '/usr/local/lib/python3.12/csv.py'>.DictReader(StringIO(csv_textsku,name,stock
    A1,notebook,6
    B2,pencil,3
    C3,folder,12
    ))13included→ [] = []14for row in reader:
  2. stock ← 6, included ← ['notebook:6']

    pass 1 of 3
    13included = []14for row{'sku': 'A1', 'name': 'notebook', 'stock': '6'} in reader⟨DictReader A⟩:15    stock→ 6 = int(row["stock"]6)16    if stock < min_stock:17        continue18    included→ ['notebook:6'].append(row["name"]notebook + ":" + str(stock6))
    All 3 passes — pass 1 is the card above
    passrowrow[”stock”]row[”name”]stockincluded
    1{'sku': 'A1', 'name': 'notebook', 'stock': '6'}6notebook6[] ['notebook:6']
    2{'sku': 'B2', 'name': 'pencil', 'stock': '3'}3pencil3['notebook:6'] ['notebook:6', 'pencil:3']
    3{'sku': 'C3', 'name': 'folder', 'stock': '12'}12folder12['notebook:6', 'pencil:3'] ['notebook:6', 'pencil:3', 'folder:12']
  3. print("included=" + ",".join(included))

    20print("included=" + ",".join(included['notebook:6', 'pencil:3', 'folder:12']))21print("count=" + str(len(included['notebook:6', 'pencil:3', 'folder:12'])))
    outputincluded=notebook:6,pencil:3,folder:12
    count=3
  1. csv_text ← sku,name,stock A1,notebook,6 B2,pencil,3 C3,folder,12

    4csv_text→ sku,name,stock
    A1,notebook,6
    B2,pencil,3
    C3,folder,12
     = """sku,name,stock5A1,notebook,66B2,pencil,37C3,folder,128"""910min_stock→ 10 = 101112reader→ ⟨DictReader A⟩ = csv<module 'csv' from '/usr/local/lib/python3.12/csv.py'>.DictReader(StringIO(csv_textsku,name,stock
    A1,notebook,6
    B2,pencil,3
    C3,folder,12
    ))13included→ [] = []14for row in reader:
  2. stock ← 6

    pass 1 of 3
    13included = []14for row{'sku': 'A1', 'name': 'notebook', 'stock': '6'} in reader⟨DictReader A⟩:15    stock→ 6 = int(row["stock"]6)16    if stock < min_stock:
    All 3 passes — pass 1 is the card above
    passrowrow[”stock”]min_stockrow[”name”]stockincluded
    1{'sku': 'A1', 'name': 'notebook', 'stock': '6'}6106
    2{'sku': 'B2', 'name': 'pencil', 'stock': '3'}3103
    3{'sku': 'C3', 'name': 'folder', 'stock': '12'}12folder12[] ['folder:12']
  3. if stock < min_stock:

    pass 1 of 2
    15stock = int(row["stock"])16if stock6 < min_stock10:17    continue18included.append(row["name"] + ":" + str(stock))
  4. if stock < min_stock:

    pass 2 of 2
    15stock = int(row["stock"])16if stock3 < min_stock10:17    continue18included.append(row["name"] + ":" + str(stock))
  5. print("included=" + ",".join(included))

    20print("included=" + ",".join(included['folder:12']))21print("count=" + str(len(included['folder:12'])))
    outputincluded=folder:12
    count=1

See the CSV Read State

The report reads one row at a time, converts the stock text to an integer, and keeps only rows with stock at least min_stock = 5.

CSV text becomes named row dictionariesCSV text becomes named row dictionariescsv_textDictReaderA1 notebook 6B2 pencil 3C3 folder 12
`csv.DictReader` uses the header `sku,name,stock` to label each later row before the report checks stock.
Rows kept by min_stock = 5Rows kept by min_stock = 5rowstockdecisionincluded listA1 notebook6keepnotebook:6B2 pencil3skipnotebook:6C3 folder12keepnotebook:6, folder:12
`notebook:6` and `folder:12` are included. `pencil:3` is skipped because 3 is below the minimum stock of 5.