"""Lesson 3: errors, try/except and logging - process a file with bad rows without crashing."""
import csv, logging, datetime as dt
from pathlib import Path
HERE = Path(__file__).resolve().parent
logging.basicConfig(level=logging.INFO, format="%(levelname)s %(message)s",
                    handlers=[logging.StreamHandler(__import__("sys").stdout)])
log = logging.getLogger("sales")

good, bad = [], []
for line_no, r in enumerate(csv.DictReader(open(HERE / "sales.csv", encoding="utf-8")), start=2):
    try:
        r["qty"] = int(r["qty"])
        r["date"] = dt.date.fromisoformat(r["date"])
        good.append(r)
    except ValueError as e:
        bad.append(line_no)
        log.warning("line %d skipped (%s): %s", line_no, r["invoice"], e)
log.info("loaded %d rows, skipped %d", len(good), len(bad))

def safe_div(a, b):
    try:
        return a / b
    except ZeroDivisionError:
        return 0.0
    finally:
        pass   # runs either way: close files, release connections
print("safe_div(10, 0) =", safe_div(10, 0))
