{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "cell-23-08-00",
   "metadata": {},
   "source": [
    "# 23-08 · Operacje z Path\n",
    "\n",
    "Praktyka do sekcji [„pathlib: praca ze ścieżkami i katalogami” `projects/python/safesort/src/safesort/models.py`."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cell-23-08-01",
   "metadata": {},
   "source": [
    "## Cel\n",
    "\n",
    "Ćwiczyć operacje na `Path` — Operator `/`, `.name`, `.suffix`, `.parent` — i zbudować niezmienny model `FileInfo`, na którym opiera się cały SafeSort. model danych"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cell-23-08-02",
   "metadata": {},
   "source": [
    "## Example"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cell-23-08-03",
   "metadata": {},
   "outputs": [],
   "source": [
    "from pathlib import Path\n",
    "\n",
    "koren = Path(\"/home/anna/Downloads\")\n",
    "fajl = koren / \"otchet.pdf\"\n",
    "\n",
    "print(fajl.name)\n",
    "print(fajl.suffix)\n",
    "print(fajl.parent)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cell-23-08-04",
   "metadata": {},
   "source": [
    "## Sprawdzenie wyniku"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cell-23-08-05",
   "metadata": {},
   "outputs": [],
   "source": [
    "assert fajl.name == \"otchet.pdf\"\n",
    "assert fajl.suffix == \".pdf\"\n",
    "assert fajl.parent == koren\n",
    "assert (koren / \"podkatalog\" / \"vlozhennyj.txt\").parent.name == \"podkatalog\"\n",
    "print(\"Верно: оператор / и атрибуты name/suffix/parent работают как ожидается.\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cell-23-08-06",
   "metadata": {},
   "source": [
    "## FileInfo jest niezmiennym modelem danych"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cell-23-08-07",
   "metadata": {},
   "outputs": [],
   "source": [
    "from dataclasses import dataclass, FrozenInstanceError\n",
    "\n",
    "\n",
    "@dataclass(frozen=True)\n",
    "class FileInfo:\n",
    "    path: Path\n",
    "    size: int\n",
    "    extension: str\n",
    "\n",
    "\n",
    "primer = FileInfo(path=fajl, size=204800, extension=fajl.suffix.lower())\n",
    "print(primer)\n",
    "\n",
    "try:\n",
    "    primer.size = 0\n",
    "except FrozenInstanceError as oshibka:\n",
    "    print(\"Изменить поле нельзя:\", oshibka)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cell-23-08-08",
   "metadata": {},
   "source": [
    "## Starter\n",
    "\n",
    "Wypełnij zaznaczone miejsce. Niezmieniony starter nie przechodzi tests."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "task-23-08",
   "metadata": {
    "tags": [
     "exercise",
     "starter"
    ]
   },
   "outputs": [],
   "source": [
    "def opisat_fajl(path: Path, size: int) -> FileInfo:\n",
    "    # TODO: construct and return FileInfo.\n",
    "    raise NotImplementedError\n",
    "\n",
    "\n",
    "zadanie_info = opisat_fajl(koren / \"photo.JPG\", 2048)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cell-23-08-10",
   "metadata": {},
   "source": [
    "## Task\n",
    "\n",
    "Write `opisat_fajl(path, size)`to tworzy `FileInfo` z lower-case suffix."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cell-23-08-11",
   "metadata": {},
   "source": [
    "## Tests\n",
    "\n",
    "Run After task cell: jest podstawowy przykład i przynajmniej jeden skrajny przypadek."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "tests-23-08",
   "metadata": {
    "tags": [
     "exercise-tests"
    ]
   },
   "outputs": [],
   "source": [
    "assert zadanie_info.extension == \".jpg\"\n",
    "assert zadanie_info.size == 2048\n",
    "assert zadanie_info.path.name == \"photo.JPG\"\n",
    "assert opisat_fajl(Path(\"README\"), 10).extension == \"\"\n",
    "print(\"Tests passed\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cell-23-08-13",
   "metadata": {},
   "source": [
    "## Hint\n",
    "\n",
    "Przedłużenie znajduje się w `path.suffix`; Aplikuj `.lower()`."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cell-23-08-14",
   "metadata": {},
   "source": [
    "## Solution\n",
    "\n",
    "Pokaż rozwiązanie po własnej próbie</summary>\n",
    "\n",
    "```python\n",
    "def opisat_fajl(path: Path, size: int) -> FileInfo:\n",
    "    return FileInfo(path=path, size=size, extension=path.suffix.lower())\n",
    "\n",
    "\n",
    "zadanie_info = opisat_fajl(koren / \"photo.JPG\", 2048)\n",
    "```\n",
    "\n",
    "</details>"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Cartesian Python 3.14",
   "language": "python",
   "name": "cartesian-python314"
  },
  "language_info": {
   "name": "python",
   "version": "3.14.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
