{
  "nbformat": 4,
  "nbformat_minor": 5,
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    }
  },
  "cells": [
    {
      "id": "scope",
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "# Read a Canadian grocery observation sample\n",
        "Download observations.csv alongside this notebook from https://vynn.ai/data.\n",
        "Historical selected series, July 20\u2013August 17, 2026; not a representative basket.\n",
        "We count observed dates and report each series\u2019 price range. Missing dates stay missing.\n",
        "Read the accompanying README.md for selection, field definitions, and terms."
      ]
    },
    {
      "id": "analysis",
      "cell_type": "code",
      "execution_count": null,
      "outputs": [],
      "metadata": {},
      "source": [
        "\"\"\"Reproduce the sample readout. Python standard library only.\"\"\"\n",
        "import csv\n",
        "from collections import defaultdict\n",
        "from decimal import Decimal\n",
        "from pathlib import Path\n",
        "import sys\n",
        "\n",
        "\n",
        "def summarise(path):\n",
        "    groups = defaultdict(list)\n",
        "    with Path(path).open(encoding='utf-8', newline='') as source:\n",
        "        for row in csv.DictReader(source):\n",
        "            groups[row['series_id']].append(row)\n",
        "    for series, rows in sorted(groups.items()):\n",
        "        prices = [Decimal(row['observed_price']) for row in rows]\n",
        "        dates = {row['observed_date'] for row in rows}\n",
        "        yield (series, rows[0]['product_name'], rows[0]['province'], len(dates), min(prices), max(prices))\n",
        "\n",
        "\n",
        "\n",
        "for row in summarise('observations.csv'):\n",
        "    print(row)\n"
      ]
    }
  ]
}
