{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Getting Started with TimeDataModel\n",
    "\n",
    "TimeDataModel is a lightweight Python data model for time series data. It gives you structured, metadata-rich time series objects with seamless bridges to pandas, numpy, and polars. This notebook walks you through the basics: creating a `TimeSeriesList`, inspecting it, and converting it."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Installation\n",
    "\n",
    "```bash\n",
    "pip install timedatamodel\n",
    "\n",
    "# With optional extras\n",
    "pip install timedatamodel[polars]   # polars support\n",
    "pip install timedatamodel[geo]      # GeoArea support via shapely\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Creating your first TimeSeriesList\n",
    "\n",
    "A `TimeSeriesList` needs a frequency, timestamps, and values. You can optionally attach metadata like a name, unit, and data type."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-03-04T19:11:00.202454Z",
     "iopub.status.busy": "2026-03-04T19:11:00.202174Z",
     "iopub.status.idle": "2026-03-04T19:11:00.244927Z",
     "shell.execute_reply": "2026-03-04T19:11:00.244556Z"
    }
   },
   "outputs": [],
   "source": [
    "from datetime import datetime, timedelta, timezone\n",
    "\n",
    "import timedatamodel as tdm\n",
    "\n",
    "base = datetime(2024, 1, 15, tzinfo=timezone.utc)\n",
    "timestamps = [base + timedelta(hours=i) for i in range(24)]\n",
    "values = [\n",
    "    120.0, 115.0, 108.0, 105.0, 102.0, 100.0,\n",
    "    110.0, 135.0, 160.0, 175.0, 180.0, 178.0,\n",
    "    172.0, 170.0, 168.0, 165.0, 175.0, 190.0,\n",
    "    200.0, 195.0, 180.0, 165.0, 145.0, 130.0,\n",
    "]\n",
    "\n",
    "ts = tdm.TimeSeriesList(\n",
    "    tdm.Frequency.PT1H,\n",
    "    timezone=\"UTC\",\n",
    "    timestamps=timestamps,\n",
    "    values=values,\n",
    "    name=\"power\",\n",
    "    unit=\"MW\",\n",
    "    description=\"Hourly power output from wind farm Alpha\",\n",
    "    data_type=tdm.DataType.OBSERVATION,\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Rich notebook display\n",
    "\n",
    "Simply evaluate a `TimeSeriesList` in a cell to see its HTML representation — metadata and a data preview with head/tail rows."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-03-04T19:11:00.246611Z",
     "iopub.status.busy": "2026-03-04T19:11:00.246490Z",
     "iopub.status.idle": "2026-03-04T19:11:00.249814Z",
     "shell.execute_reply": "2026-03-04T19:11:00.249429Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<style>\n",
       ".ts-repr { font-family: monospace; font-size: 13px; max-width: 640px; display: inline-grid; }\n",
       ".ts-repr .ts-header {\n",
       "  font-weight: bold; font-size: 14px;\n",
       "  padding: 6px 10px; border-bottom: 2px solid #4a4a4a;\n",
       "  background: #f0f0f0; color: #1a1a1a;\n",
       "}\n",
       ".ts-repr .ts-meta { padding: 6px 10px; background: #fafafa; overflow: hidden; min-width: 0; }\n",
       ".ts-repr .ts-meta table { border-collapse: collapse; width: 100%; table-layout: fixed; }\n",
       ".ts-repr .ts-meta td { padding: 1px 8px 1px 0; white-space: nowrap; }\n",
       ".ts-repr .ts-meta td:first-child { color: #475569; font-weight: 600; width: 90px; }\n",
       ".ts-repr .ts-meta td:last-child { color: #1a1a1a; overflow: hidden; text-overflow: ellipsis; }\n",
       ".ts-repr .ts-data { padding: 6px 10px; }\n",
       ".ts-repr .ts-data table {\n",
       "  border-collapse: collapse; text-align: right;\n",
       "}\n",
       ".ts-repr .ts-data th {\n",
       "  text-align: right; padding: 3px 10px; border-bottom: 1px solid #ccc;\n",
       "  color: #555; font-weight: 600;\n",
       "}\n",
       ".ts-repr .ts-data th.ts-idx { text-align: left; }\n",
       ".ts-repr .ts-data td { padding: 2px 10px; }\n",
       ".ts-repr .ts-data tr:hover { background: #f5f5f5; }\n",
       ".ts-repr .ts-data td:first-child { text-align: left; color: #1e293b; }\n",
       ".ts-repr .ts-data td.ts-idx { text-align: left; color: #1e293b; }\n",
       ".ts-repr .ts-ellipsis { text-align: center !important; color: #999; }\n",
       "@media (prefers-color-scheme: dark) {\n",
       "  .ts-repr .ts-header { background: #1e293b; color: #e2e8f0; border-color: #475569; }\n",
       "  .ts-repr .ts-meta { background: #0f172a; }\n",
       "  .ts-repr .ts-meta td:first-child { color: #94a3b8; }\n",
       "  .ts-repr .ts-meta td:last-child { color: #e2e8f0; }\n",
       "  .ts-repr .ts-data th { color: #94a3b8; border-color: #334155; }\n",
       "  .ts-repr .ts-data td { color: #e2e8f0; }\n",
       "  .ts-repr .ts-data td:first-child { color: #cbd5e1; }\n",
       "  .ts-repr .ts-data td.ts-idx { color: #cbd5e1; }\n",
       "  .ts-repr .ts-data tr:hover { background: #1e293b; }\n",
       "  .ts-repr .ts-ellipsis { color: #64748b; }\n",
       "}\n",
       "</style>\n",
       "<div class=\"ts-repr\">\n",
       "<div class=\"ts-header\">TimeSeriesList</div>\n",
       "<div class=\"ts-meta\"><table>\n",
       "<tr><td>Name</td><td>power</td></tr>\n",
       "<tr><td>Length</td><td>24</td></tr>\n",
       "<tr><td>Frequency</td><td>PT1H</td></tr>\n",
       "<tr><td>Timezone</td><td>UTC (+00:00)</td></tr>\n",
       "<tr><td>Unit</td><td>MW</td></tr>\n",
       "<tr><td>Data type</td><td>OBSERVATION</td></tr>\n",
       "<tr><td>Description</td><td>Hourly power output from wind farm Alpha</td></tr>\n",
       "</table></div>\n",
       "<div class=\"ts-data\"><table>\n",
       "<tr><th class=\"ts-idx\">timestamp</th><th>power</th></tr>\n",
       "<tr><td>2024-01-15 00:00</td><td>120.0</td></tr>\n",
       "<tr><td>2024-01-15 01:00</td><td>115.0</td></tr>\n",
       "<tr><td>2024-01-15 02:00</td><td>108.0</td></tr>\n",
       "<tr><td class=\"ts-ellipsis\">&hellip;</td><td class=\"ts-ellipsis\">&hellip;</td></tr>\n",
       "<tr><td>2024-01-15 21:00</td><td>165.0</td></tr>\n",
       "<tr><td>2024-01-15 22:00</td><td>145.0</td></tr>\n",
       "<tr><td>2024-01-15 23:00</td><td>130.0</td></tr>\n",
       "</table></div>\n",
       "</div>"
      ],
      "text/plain": [
       "TimeSeriesList\n",
       "┌──────────────────────────────────────────────────────────────┐\n",
       "│  Name:             power                                     │\n",
       "│  Length:           24                                        │\n",
       "│  Frequency:        PT1H                                      │\n",
       "│  Timezone:         UTC (+00:00)                              │\n",
       "│  Unit:             MW                                        │\n",
       "│  Data type:        OBSERVATION                               │\n",
       "│  Description:      Hourly power output from wind farm Alpha  │\n",
       "├──────────────────────────────────────────────────────────────┤\n",
       "│  2024-01-15 00:00  120.0                                     │\n",
       "│  2024-01-15 01:00  115.0                                     │\n",
       "│  2024-01-15 02:00  108.0                                     │\n",
       "│  ...                 ...                                     │\n",
       "│  2024-01-15 21:00  165.0                                     │\n",
       "│  2024-01-15 22:00  145.0                                     │\n",
       "│  2024-01-15 23:00  130.0                                     │\n",
       "└──────────────────────────────────────────────────────────────┘"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ts"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## DataPoints and iteration\n",
    "\n",
    "Each element in a `TimeSeriesList` is a `DataPoint` — a named tuple of `(timestamp, value)`. You can index, slice, and iterate."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-03-04T19:11:00.250913Z",
     "iopub.status.busy": "2026-03-04T19:11:00.250848Z",
     "iopub.status.idle": "2026-03-04T19:11:00.252570Z",
     "shell.execute_reply": "2026-03-04T19:11:00.252269Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "First point: DataPoint\n",
      "┌────────────────────────────────┐\n",
      "│  Timestamp:  2024-01-15 00:00  │\n",
      "│  Timezone:   UTC (+00:00)      │\n",
      "│  Value:      120.0             │\n",
      "└────────────────────────────────┘\n",
      "  timestamp = 2024-01-15 00:00:00+00:00\n",
      "  value     = 120.0\n"
     ]
    }
   ],
   "source": [
    "dp = ts[0]\n",
    "print(f\"First point: {dp}\")\n",
    "print(f\"  timestamp = {dp.timestamp}\")\n",
    "print(f\"  value     = {dp.value}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-03-04T19:11:00.253495Z",
     "iopub.status.busy": "2026-03-04T19:11:00.253436Z",
     "iopub.status.idle": "2026-03-04T19:11:00.255383Z",
     "shell.execute_reply": "2026-03-04T19:11:00.255001Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[DataPoint\n",
       " ┌────────────────────────────────┐\n",
       " │  Timestamp:  2024-01-15 00:00  │\n",
       " │  Timezone:   UTC (+00:00)      │\n",
       " │  Value:      120.0             │\n",
       " └────────────────────────────────┘,\n",
       " DataPoint\n",
       " ┌────────────────────────────────┐\n",
       " │  Timestamp:  2024-01-15 01:00  │\n",
       " │  Timezone:   UTC (+00:00)      │\n",
       " │  Value:      115.0             │\n",
       " └────────────────────────────────┘,\n",
       " DataPoint\n",
       " ┌────────────────────────────────┐\n",
       " │  Timestamp:  2024-01-15 02:00  │\n",
       " │  Timezone:   UTC (+00:00)      │\n",
       " │  Value:      108.0             │\n",
       " └────────────────────────────────┘]"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ts[:3]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-03-04T19:11:00.256278Z",
     "iopub.status.busy": "2026-03-04T19:11:00.256219Z",
     "iopub.status.idle": "2026-03-04T19:11:00.257779Z",
     "shell.execute_reply": "2026-03-04T19:11:00.257488Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "00:00   120.0 MW\n",
      "01:00   115.0 MW\n",
      "02:00   108.0 MW\n",
      "03:00   105.0 MW\n"
     ]
    }
   ],
   "source": [
    "for dp in ts.head(4):\n",
    "    print(f\"{dp.timestamp:%H:%M}  {dp.value:>6.1f} MW\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Inspecting properties\n",
    "\n",
    "A `TimeSeriesList` exposes handy properties for quick inspection."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-03-04T19:11:00.258760Z",
     "iopub.status.busy": "2026-03-04T19:11:00.258689Z",
     "iopub.status.idle": "2026-03-04T19:11:00.260380Z",
     "shell.execute_reply": "2026-03-04T19:11:00.260100Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Length:      24 points\n",
      "Begin:       2024-01-15 00:00:00+00:00\n",
      "End:         2024-01-15 23:00:00+00:00\n",
      "Duration:    23:00:00\n",
      "Has missing: False\n"
     ]
    }
   ],
   "source": [
    "print(f\"Length:      {len(ts)} points\")\n",
    "print(f\"Begin:       {ts.begin}\")\n",
    "print(f\"End:         {ts.end}\")\n",
    "print(f\"Duration:    {ts.duration}\")\n",
    "print(f\"Has missing: {ts.has_missing}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Creating from DataPoints\n",
    "\n",
    "You can also construct a `TimeSeriesList` from a list of `DataPoint` objects."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-03-04T19:11:00.261429Z",
     "iopub.status.busy": "2026-03-04T19:11:00.261378Z",
     "iopub.status.idle": "2026-03-04T19:11:00.263527Z",
     "shell.execute_reply": "2026-03-04T19:11:00.263223Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<style>\n",
       ".ts-repr { font-family: monospace; font-size: 13px; max-width: 640px; display: inline-grid; }\n",
       ".ts-repr .ts-header {\n",
       "  font-weight: bold; font-size: 14px;\n",
       "  padding: 6px 10px; border-bottom: 2px solid #4a4a4a;\n",
       "  background: #f0f0f0; color: #1a1a1a;\n",
       "}\n",
       ".ts-repr .ts-meta { padding: 6px 10px; background: #fafafa; overflow: hidden; min-width: 0; }\n",
       ".ts-repr .ts-meta table { border-collapse: collapse; width: 100%; table-layout: fixed; }\n",
       ".ts-repr .ts-meta td { padding: 1px 8px 1px 0; white-space: nowrap; }\n",
       ".ts-repr .ts-meta td:first-child { color: #475569; font-weight: 600; width: 90px; }\n",
       ".ts-repr .ts-meta td:last-child { color: #1a1a1a; overflow: hidden; text-overflow: ellipsis; }\n",
       ".ts-repr .ts-data { padding: 6px 10px; }\n",
       ".ts-repr .ts-data table {\n",
       "  border-collapse: collapse; text-align: right;\n",
       "}\n",
       ".ts-repr .ts-data th {\n",
       "  text-align: right; padding: 3px 10px; border-bottom: 1px solid #ccc;\n",
       "  color: #555; font-weight: 600;\n",
       "}\n",
       ".ts-repr .ts-data th.ts-idx { text-align: left; }\n",
       ".ts-repr .ts-data td { padding: 2px 10px; }\n",
       ".ts-repr .ts-data tr:hover { background: #f5f5f5; }\n",
       ".ts-repr .ts-data td:first-child { text-align: left; color: #1e293b; }\n",
       ".ts-repr .ts-data td.ts-idx { text-align: left; color: #1e293b; }\n",
       ".ts-repr .ts-ellipsis { text-align: center !important; color: #999; }\n",
       "@media (prefers-color-scheme: dark) {\n",
       "  .ts-repr .ts-header { background: #1e293b; color: #e2e8f0; border-color: #475569; }\n",
       "  .ts-repr .ts-meta { background: #0f172a; }\n",
       "  .ts-repr .ts-meta td:first-child { color: #94a3b8; }\n",
       "  .ts-repr .ts-meta td:last-child { color: #e2e8f0; }\n",
       "  .ts-repr .ts-data th { color: #94a3b8; border-color: #334155; }\n",
       "  .ts-repr .ts-data td { color: #e2e8f0; }\n",
       "  .ts-repr .ts-data td:first-child { color: #cbd5e1; }\n",
       "  .ts-repr .ts-data td.ts-idx { color: #cbd5e1; }\n",
       "  .ts-repr .ts-data tr:hover { background: #1e293b; }\n",
       "  .ts-repr .ts-ellipsis { color: #64748b; }\n",
       "}\n",
       "</style>\n",
       "<div class=\"ts-repr\">\n",
       "<div class=\"ts-header\">TimeSeriesList</div>\n",
       "<div class=\"ts-meta\"><table>\n",
       "<tr><td>Name</td><td>temperature</td></tr>\n",
       "<tr><td>Length</td><td>4</td></tr>\n",
       "<tr><td>Frequency</td><td>PT1H</td></tr>\n",
       "<tr><td>Timezone</td><td>UTC (+00:00)</td></tr>\n",
       "<tr><td>Unit</td><td>°C</td></tr>\n",
       "</table></div>\n",
       "<div class=\"ts-data\"><table>\n",
       "<tr><th class=\"ts-idx\">timestamp</th><th>temperature</th></tr>\n",
       "<tr><td>2024-01-15 00:00</td><td>5.2</td></tr>\n",
       "<tr><td>2024-01-15 01:00</td><td>5.8</td></tr>\n",
       "<tr><td>2024-01-15 02:00</td><td>6.1</td></tr>\n",
       "</table></div>\n",
       "</div>"
      ],
      "text/plain": [
       "TimeSeriesList\n",
       "┌──────────────────────────────────┐\n",
       "│  Name:             temperature   │\n",
       "│  Length:           4             │\n",
       "│  Frequency:        PT1H          │\n",
       "│  Timezone:         UTC (+00:00)  │\n",
       "│  Unit:             °C            │\n",
       "├──────────────────────────────────┤\n",
       "│  2024-01-15 00:00  5.2           │\n",
       "│  2024-01-15 01:00  5.8           │\n",
       "│  2024-01-15 02:00  6.1           │\n",
       "│  2024-01-15 03:00  5.5           │\n",
       "└──────────────────────────────────┘"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data = [\n",
    "    tdm.DataPoint(datetime(2024, 1, 15, h, tzinfo=timezone.utc), v)\n",
    "    for h, v in [(0, 5.2), (1, 5.8), (2, 6.1), (3, 5.5)]\n",
    "]\n",
    "\n",
    "ts_temp = tdm.TimeSeriesList(\n",
    "    tdm.Frequency.PT1H,\n",
    "    data=data,\n",
    "    name=\"temperature\",\n",
    "    unit=\"°C\",\n",
    ")\n",
    "ts_temp"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Summary\n",
    "\n",
    "In this notebook you learned how to:\n",
    "\n",
    "- Create a `TimeSeriesList` with metadata (name, unit, data type)\n",
    "- View its rich display in a notebook\n",
    "- Access individual `DataPoint` elements via indexing, slicing, and iteration\n",
    "- Inspect basic properties: `begin`, `end`, `duration`, `has_missing`\n",
    "\n",
    "Next up: **nb_02** shows how to use numpy and pandas to transform time series data."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": ".venv",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.14.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
