{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "98e281d1",
   "metadata": {},
   "source": [
    "# Moduł 2: Wymiary jakości danych w praktyce\n",
    "\n",
    "**Wersja:** uczestnika  \n",
    "**Cel:** obliczyć podstawowe metryki jakości i przypisać wynik do konkretnego rodzaju problemu  \n",
    "**Czas orientacyjny:** 35–45 min  \n",
    "**Dane:** customer360_train.csv  \n",
    "**Artefakt końcowy:** tabela metryk jakości + interpretacja\n",
    "\n",
    "Notebook jest częścią wspólnego case'u **Customer 360**. Dane są syntetyczne i służą wyłącznie ćwiczeniu."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d0289f7d",
   "metadata": {},
   "source": [
    "## Jak pracować\n",
    "\n",
    "1. Uruchamiaj komórki od góry do dołu.\n",
    "2. Najpierw zapisz obserwację z danych. Dopiero później formułuj hipotezę o przyczynie.\n",
    "3. W rekomendacji wskaż dowód, właściciela działania i warunek ponownej oceny.\n",
    "4. Wynik statystyczny jest sygnałem diagnostycznym. Sam nie przesądza o zatrzymaniu modelu, zmianie progu ani retrainingu."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c0c4487d",
   "metadata": {},
   "source": [
    "## Granice interpretacji\n",
    "\n",
    "- Validity oznacza zgodność z regułą lub domeną, a accuracy - zgodność z rzeczywistością; accuracy często wymaga źródła referencyjnego.\n",
    "- Świeżość i terminowość trzeba interpretować względem momentu użycia i uzgodnionego czasu dostarczenia.\n",
    "- Porównanie rozkładów w M2 ma charakter podstawowy; pełna diagnostyka driftu pojawia się w M6 i M8."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5561774c",
   "metadata": {},
   "source": [
    "## Reguła operacyjna laboratorium\n",
    "Metryka opisuje stan danych względem jawnej reguły i mianownika. Nie zamieniaj jej automatycznie w decyzję o akceptacji danych. Jeżeli wykryjesz problem, wskaż również miejsce powstania, właściciela i sposób kontroli po naprawie."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "afd61c7b",
   "metadata": {},
   "source": [
    "## Dane wejściowe i manifest\n",
    "Dane: `customer360_train.csv`.  \n",
    "Opis kolumn i reguł laboratoryjnych: `manifests/M02_data_manifest.csv` w paczce zbiorczej albo `data_manifest.csv` w paczce modułowej."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ae63f7e1",
   "metadata": {
    "tags": [
     "setup"
    ]
   },
   "outputs": [],
   "source": [
    "from pathlib import Path\n",
    "import sys\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "\n",
    "DATA_DIR = Path('data')\n",
    "if not DATA_DIR.exists():\n",
    "    DATA_DIR = Path('..') / 'data'\n",
    "assert DATA_DIR.exists(), 'Nie znaleziono katalogu data. Uruchom notebook z katalogu paczki lub zachowaj strukturę ZIP.'\n",
    "print('Python:', sys.version.split()[0])\n",
    "print('pandas:', pd.__version__)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5100122a",
   "metadata": {},
   "source": [
    "## 1. Profilowanie\n",
    "\n",
    "Policz kompletność, unikalność identyfikatora i zgodność wieku z regułą 18–110."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ab007341",
   "metadata": {
    "tags": [
     "exercise"
    ]
   },
   "outputs": [],
   "source": [
    "df = pd.read_csv(DATA_DIR/'customer360_train.csv')\n",
    "# TODO: oblicz completeness_income, uniqueness_id, validity_age"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d1dc4d22",
   "metadata": {},
   "source": [
    "## 2. Spójność dwóch źródeł\n",
    "\n",
    "Dla sald przyjmij w ćwiczeniu tolerancję 100 zł i policz odsetek rekordów, w których CRM i billing mieszczą się w tej tolerancji. Tolerancja jest założeniem ćwiczenia, a nie normą branżową."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1a9f7cb3",
   "metadata": {
    "tags": [
     "exercise"
    ]
   },
   "outputs": [],
   "source": [
    "# TODO: policz consistency_balance przy tolerancji 100\n",
    "consistency_balance = np.nan"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "eaa9a03b",
   "metadata": {},
   "source": [
    "## 3. Tabela diagnostyczna\n",
    "\n",
    "Połącz metryki z nazwą problemu i krótką interpretacją. Nie nazywaj każdej różnicy błędem bez sprawdzenia definicji."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a7c2d6e7",
   "metadata": {
    "tags": [
     "exercise"
    ]
   },
   "outputs": [],
   "source": [
    "dq_report = pd.DataFrame(columns=['metric','value','interpretation'])\n",
    "display(dq_report)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "452dfaee",
   "metadata": {},
   "source": [
    "## Zadanie rozszerzające\n",
    "\n",
    "Dodaj metrykę dla wybranego pola i zapisz, czy mierzy validity, completeness, consistency czy inną własność."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8bd6b577",
   "metadata": {},
   "source": [
    "## Kryteria akceptacji ćwiczenia\n",
    "- metryki są liczone jawnie i mają zdefiniowany mianownik\n",
    "- validity age używa laboratoryjnej reguły 18–110\n",
    "- tolerancja 100 zł jest oznaczona jako założenie ćwiczenia, nie norma\n",
    "\n",
    "Przed oddaniem wykonaj **Restart Kernel and Run All**. Notebook nie powinien zależeć od ręcznie ustawionego stanu poprzednich komórek."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "708d854d",
   "metadata": {},
   "source": [
    "## Co oddajesz\n",
    "\n",
    "Zachowaj tabelę lub wykres będący wynikiem ćwiczenia oraz krótki komentarz: **obserwacja → hipoteza → potrzebny dowód → rekomendacja / dalszy krok**. Jeżeli nie da się rozstrzygnąć przyczyny na podstawie danych z notebooka, oznacz ją jako hipotezę i wskaż brakujący artefakt."
   ]
  }
 ],
 "metadata": {
  "course": {
   "generated": "2026-08-28",
   "module": 2,
   "variant": "participant"
  },
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "name": "python",
   "version": "3.x"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
