{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "BJF5QC6r0MjZ",
   "metadata": {
    "id": "BJF5QC6r0MjZ"
   },
   "source": [
    "# Wprowadzenie do programowania w Pythonie — notatnik edukacyjny\n",
    "\n",
    "*Wersja notatnika: 2025-08-30*\n",
    "\n",
    "Przygotowanie skryptu: dr inż. Szczepan Górtowski<br/>\n",
    "\n",
    "> Cel: w praktyce przejść przez podstawy Pythona — komentarze, zmienne, operatory, funkcje, różnicę `print` vs `return`,\n",
    "zasady estetyki kodu — oraz wykonać mini‑zadania kontrolne z automatycznym sprawdzaniem.\n",
    "\n",
    "### Jak korzystać\n",
    "1. Uruchamiaj komórki po kolei (skrót: `Ctrl/Cmd + Enter`).\n",
    "2. W sekcji **Zadania** edytuj wskazane komórki i uruchom testy w komórce z napisem **Sprawdź**.\n",
    "3. Jeśli test nie przechodzi, popraw kod i uruchom test ponownie."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "KFg51nyT0Mjl",
   "metadata": {
    "id": "KFg51nyT0Mjl"
   },
   "source": [
    "## Spis treści\n",
    "1. [Komentarze w Pythonie](#komentarze)\n",
    "2. [Zmienne i typy](#zmienne)\n",
    "3. [Stałe (konwencja)](#stale)\n",
    "4. [Operatory — część 1](#operatory1)\n",
    "5. [Operatory — część 2 i instrukcje warunkowe](#operatory2)\n",
    "6. [Funkcje](#funkcje)\n",
    "7. [`print` vs `return`](#print-vs-return)\n",
    "8. [Estetyka i styl](#estetyka)\n",
    "9. [Zadanie 0 — „Hello World!”](#zadanie0)\n",
    "10. [Zadanie 1 — proste funkcje geometryczne](#zadanie1)\n",
    "11. [Podsumowanie i co dalej](#podsumowanie)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2O3dg2Ex0Mjn",
   "metadata": {
    "id": "2O3dg2Ex0Mjn"
   },
   "source": [
    "## 1. Komentarze w Pythonie <a name='komentarze'></a>\n",
    "\n",
    "Komentarze pomagają wyjaśniać kod innym (i sobie samemu w przyszłości).\n",
    "- `#` — komentarz jednolinijkowy\n",
    "- potrójne cudzysłowy `\"\"\" ... \"\"\"` — wygodne do dłuższych bloków tekstu\n",
    "\n",
    "W projektach biznesowych unika się „węży” — bardzo długich linii. Lepiej łamać tekst na krótsze wiersze.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "DAr82jvm0Mjp",
   "metadata": {
    "id": "DAr82jvm0Mjp"
   },
   "outputs": [],
   "source": [
    "# Komentarz jednolinijkowy\n",
    "PI = 3.14  # liczba pi — komentarz na końcu linii\n",
    "\n",
    "\"\"\"\n",
    "Blok komentarza (technicznie: łańcuch znaków), wygodny dla długich objaśnień,\n",
    "list TODO itp.\n",
    "\"\"\"\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "_WNkNCnv0Mjt",
   "metadata": {
    "id": "_WNkNCnv0Mjt"
   },
   "source": [
    "## 2. Zmienne i typy <a name='zmienne'></a>\n",
    "\n",
    "Python jest **dynamicznie typowany** — nie trzeba deklarować typu z góry.\n",
    "Poniżej przykłady najczęściej używanych typów prostych i złożonych.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "JTufic160Mju",
   "metadata": {
    "id": "JTufic160Mju"
   },
   "outputs": [],
   "source": [
    "imie = \"Ola\"\n",
    "a = 2\n",
    "b = \"Ola\"\n",
    "c = 3.14  # liczby zmiennoprzecinkowe zapisujemy z kropką\n",
    "d = True\n",
    "e = None\n",
    "\n",
    "lista = [2, 4, 6, 0, [2, 4], \"Ola\"]\n",
    "slownik = {\"imie\": \"Ola\", \"funkcja\": \"nauczyciel\"}\n",
    "\n",
    "for nazwa, wartosc in {\n",
    "    'imie': imie, 'a': a, 'b': b, 'c': c, 'd': d, 'e': e,\n",
    "    'lista': lista, 'slownik': slownik\n",
    "}.items():\n",
    "    print(f\"{nazwa:<8} -> {wartosc!r:<20} | typ: {type(wartosc).__name__}\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "o4JlzNIF0Mjv",
   "metadata": {
    "id": "o4JlzNIF0Mjv"
   },
   "source": [
    "## 3. Stałe (konwencja) <a name='stale'></a>\n",
    "\n",
    "Zmienne, których nie zamierzamy nadpisywać, zapisujemy WIELKIMI LITERAMI.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "pcYXHCBO0Mjw",
   "metadata": {
    "id": "pcYXHCBO0Mjw"
   },
   "outputs": [],
   "source": [
    "MAX_ILOSC_ZAMOWIEN = 120  # konwencja: traktuj jak stałą\n",
    "print(\"MAX_ILOSC_ZAMOWIEN =\", MAX_ILOSC_ZAMOWIEN)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "MGVwXvcf0Mjx",
   "metadata": {
    "id": "MGVwXvcf0Mjx"
   },
   "source": [
    "## 4. Operatory — część 1 <a name='operatory1'></a>\n",
    "\n",
    "- Porównania: `<`, `<=`, `>`, `>=`, `==`, `!=`\n",
    "- Arytmetyka: `+`, `-`, `*`, `/` (dzielenie zmiennoprzecinkowe)\n",
    "- Modulo: `%` (reszta z dzielenia)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "v1Y28w4X0Mjy",
   "metadata": {
    "id": "v1Y28w4X0Mjy"
   },
   "outputs": [],
   "source": [
    "print(\"1 < 2 ->\", 1 < 2)\n",
    "print(\"2 < 1 ->\", 2 < 1)\n",
    "print(\"1 + 1 =\", 1 + 1)\n",
    "print(\"3 - 1 =\", 3 - 1)\n",
    "print(\"2 * 7 =\", 2 * 7)\n",
    "print(\"121 / 11 =\", 121 / 11)\n",
    "print(\"121 // 12 =\", 121 // 12)\n",
    "print(\"10 % 3 =\", 10 % 3)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cwsBKwTY0Mj0",
   "metadata": {
    "id": "cwsBKwTY0Mj0"
   },
   "source": [
    "## 5. Operatory — część 2 i instrukcje warunkowe <a name='operatory2'></a>\n",
    "\n",
    "- Potęgowanie: `**`\n",
    "- Inkrementacja: `n = n + 1` lub skrót `n += 1`\n",
    "- Instrukcja warunkowa: `if` / `elif` / `else`\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "Zc3IQBeG0Mj1",
   "metadata": {
    "id": "Zc3IQBeG0Mj1"
   },
   "outputs": [],
   "source": [
    "print(\"2 ** 4 =\", 2 ** 4)\n",
    "\n",
    "n = 2\n",
    "n = n + 1\n",
    "n += 1\n",
    "print(\"n po dwóch inkrementacjach:\", n)\n",
    "\n",
    "if n < 1:\n",
    "    print(\"n jest mniejsze od 1\")\n",
    "elif n == 1:\n",
    "    print(\"n równe 1\")\n",
    "else:\n",
    "    print(\"n większe od 1\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "S4pZ9WKX0Mj1",
   "metadata": {
    "id": "S4pZ9WKX0Mj1"
   },
   "source": [
    "## 6. Funkcje <a name='funkcje'></a>\n",
    "\n",
    "Funkcja to fragment kodu, który można wielokrotnie wywoływać.\n",
    "Poniżej prosta funkcja zwiększająca argument o 1 i zwracająca wynik.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a4xbcWo30Mj2",
   "metadata": {
    "id": "a4xbcWo30Mj2"
   },
   "outputs": [],
   "source": [
    "def add_one(n):\n",
    "    \"\"\"Zwraca n + 1.\"\"\"\n",
    "    n = n + 1\n",
    "    return n\n",
    "\n",
    "print(\"add_one(5) ->\", add_one(5))\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "X4QrYFqb0Mj3",
   "metadata": {
    "id": "X4QrYFqb0Mj3"
   },
   "source": [
    "## 7. `print` vs `return` <a name='print-vs-return'></a>\n",
    "\n",
    "- `print(...)` — **wyświetla** informację na standardowym wyjściu (podgląd w notatniku/terminalu).\n",
    "- `return ...` — **zwraca** wartość z funkcji do dalszych obliczeń (nie wyświetla automatycznie).\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1mlsEQoJ0Mj3",
   "metadata": {
    "id": "1mlsEQoJ0Mj3"
   },
   "outputs": [],
   "source": [
    "def add_one_silent(n):\n",
    "    return n + 1  # nic nie drukuje\n",
    "\n",
    "def add_one_and_print(n):\n",
    "    wynik = n + 1\n",
    "    print(\"Wynik:\", wynik)\n",
    "    return wynik\n",
    "\n",
    "# Wywołania:\n",
    "x = add_one_silent(5)      # tu nic się nie wyświetli\n",
    "print(\"Zmienna x zawiera:\", x)\n",
    "add_one_and_print(5)       # tu zobaczymy linijkę \"Wynik: 6\"\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1vF6SFD_0Mj3",
   "metadata": {
    "id": "1vF6SFD_0Mj3"
   },
   "source": [
    "## 8. Estetyka i styl <a name='estetyka'></a>\n",
    "\n",
    "- W projektach produkcyjnych dominują **angielskie nazwy** (zmienne, funkcje, komentarze).\n",
    "- W Pythonie przyjęty jest styl **snake_case**: `imie_nazwisko`. W wielu innych językach popularny jest **camelCase**.\n",
    "- Konsekwencja w odstępach: `x = 2` (po jednej spacji wokół `=`) jest czytelniejsze niż `x=2`.\n",
    "- Unikaj polskich znaków w nazwach zmiennych/funkcji.\n",
    "- Zapoznaj się z PEP8 https://peps.python.org/pep-0008/\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "RBdYJi4_0Mj4",
   "metadata": {
    "id": "RBdYJi4_0Mj4"
   },
   "outputs": [],
   "source": [
    "# gorsza czytelność:\n",
    "x=2\n",
    "x= 2\n",
    "imieNazwisko = \"Jan Kowalski\"  # camelCase — nie jest błędem, ale w Pythonie wolimy snake_case\n",
    "\n",
    "# lepsza czytelność:\n",
    "x = 2\n",
    "imie_nazwisko = \"Jan Kowalski\"\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7Aclniat0Mj4",
   "metadata": {
    "id": "7Aclniat0Mj4"
   },
   "source": [
    "## 9. Zadanie 0 — „Hello World!” <a name='zadanie0'></a>\n",
    "\n",
    "**Cel:** napisz funkcję, która **wyświetla** dokładnie `Hello World!` (z wielką literą H i W oraz z wykrzyknikiem).\n",
    "\n",
    "Uzupełnij komórkę poniżej i uruchom test w komórce **Sprawdź**.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "emQgyV6x0Mj5",
   "metadata": {
    "id": "emQgyV6x0Mj5"
   },
   "outputs": [],
   "source": [
    "def zadanie_0():\n",
    "    \"\"\"Wydrukuj na standardowe wyjście: Hello World! (dokładnie w tej postaci).\"\"\"\n",
    "    # TODO: dopisz polecenie print poniżej\n",
    "    pass\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "GLM2s4m80Mj5",
   "metadata": {
    "id": "GLM2s4m80Mj5"
   },
   "outputs": [],
   "source": [
    "# Sprawdź\n",
    "from io import StringIO\n",
    "import contextlib\n",
    "\n",
    "buf = StringIO()\n",
    "try:\n",
    "    with contextlib.redirect_stdout(buf):\n",
    "        zadanie_0()\n",
    "    out = buf.getvalue().strip()\n",
    "    assert out == \"Hello World!\", f\"Oczekiwano 'Hello World!', otrzymano: {out!r}\"\n",
    "    print(\"✅ Test zaliczony: poprawne 'Hello World!'\")\n",
    "except NameError:\n",
    "    print(\"❌ Nie znaleziono funkcji 'zadanie_0'. Upewnij się, że komórka z definicją została uruchomiona.\")\n",
    "except AssertionError as e:\n",
    "    print(\"❌\", e)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "pu4mWoS80Mj5",
   "metadata": {
    "id": "pu4mWoS80Mj5"
   },
   "source": [
    "## 10. Zadanie 1 — proste funkcje geometryczne <a name='zadanie1'></a>\n",
    "\n",
    "**Cel:** uzupełnij implementacje funkcji zgodnie z opisem.\n",
    "\n",
    "Wskazówki:\n",
    "- Przyjmij, że argumenty powinny być nieujemne (jeśli są ujemne, podnieś `ValueError`).\n",
    "- Pisz krótkie, czytelne funkcje i dodaj `docstring`.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "zxgBX9yQ0Mj6",
   "metadata": {
    "id": "zxgBX9yQ0Mj6"
   },
   "outputs": [],
   "source": [
    "def pole_kwadratu(a: float) -> float:\n",
    "    \"\"\"Zwróć pole kwadratu o boku a.\"\"\"\n",
    "    # TODO: zwróć właściwą wartość; dodaj walidację wejścia\n",
    "    raise NotImplementedError\n",
    "\n",
    "def obwod_kwadratu(a: float) -> float:\n",
    "    \"\"\"Zwróć obwód kwadratu o boku a.\"\"\"\n",
    "    # TODO\n",
    "    raise NotImplementedError\n",
    "\n",
    "def pole_prostokata(a: float, b: float) -> float:\n",
    "    \"\"\"Zwróć pole prostokąta o bokach a i b.\"\"\"\n",
    "    # TODO\n",
    "    raise NotImplementedError\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "xoN1qxgD0Mj6",
   "metadata": {
    "id": "xoN1qxgD0Mj6"
   },
   "outputs": [],
   "source": [
    "# Sprawdź\n",
    "def _nieujemne(*args):\n",
    "    return all((isinstance(x, (int, float)) and x >= 0) for x in args)\n",
    "\n",
    "def _check_negative(fn, *args):\n",
    "    try:\n",
    "        fn(*args)\n",
    "    except ValueError:\n",
    "        return True\n",
    "    except NotImplementedError:\n",
    "        print(\"❌ Wygląda na to, że implementacja nie została ukończona.\")\n",
    "        return False\n",
    "    else:\n",
    "        return False\n",
    "\n",
    "OK = True\n",
    "try:\n",
    "    # Testy poprawnych wartości\n",
    "    assert abs(pole_kwadratu(5) - 25) < 1e-9\n",
    "    assert abs(obwod_kwadratu(5) - 20) < 1e-9\n",
    "    assert abs(pole_prostokata(3, 4) - 12) < 1e-9\n",
    "    # Testy walidacji\n",
    "    assert _check_negative(pole_kwadratu, -1)\n",
    "    assert _check_negative(obwod_kwadratu, -2)\n",
    "    assert _check_negative(pole_prostokata, 3, -4)\n",
    "except NameError as e:\n",
    "    OK = False\n",
    "    print(\"❌ Brakuje jednej z funkcji:\", e)\n",
    "except AssertionError:\n",
    "    OK = False\n",
    "    print(\"❌ Testy nie przeszły. Sprawdź implementację i walidację danych wejściowych.\")\n",
    "else:\n",
    "    print(\"✅ Wszystkie testy zaliczone!\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d6lR4Fvk0Mj6",
   "metadata": {
    "id": "d6lR4Fvk0Mj6"
   },
   "source": [
    "## 11. Podsumowanie i co dalej <a name='podsumowanie'></a>\n",
    "\n",
    "W tym notatniku poznałeś(-aś) podstawy Pythona: komentarze, zmienne, operatory,\n",
    "funkcje, różnicę `print` vs `return` oraz konwencje stylu.\n",
    "\n",
    "**Co dalej?**\n",
    "- Dodaj kolejne funkcje geometryczne (np. `obwod_prostokata`, `pole_kola`).\n",
    "- Przećwicz instrukcje warunkowe i pętle (`for`, `while`).\n",
    "- Zainteresuj się narzędziami do formatowania kodu: `black`, `ruff`/`flake8`.\n",
    "\n",
    "**Zalecane do obejrzenia**\n",
    "\n",
    "BASE:https://www.youtube.com/watch?v=Hwckt4J96dI\n",
    "\n",
    "PRO: https://www.youtube.com/watch?v=wf-BqAjZb8M\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "g1JGMsVG38Eb",
   "metadata": {
    "id": "g1JGMsVG38Eb"
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "colab": {
   "provenance": []
  },
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "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.12.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
