{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "e7f34da7",
   "metadata": {},
   "source": [
    "# 20-24 · Dźwięk i muzyka\n",
    "\n",
    "Praktyka do sekcji [„Dźwięk i muzyka”"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "de0c1134",
   "metadata": {},
   "source": [
    "## Cel\n",
    "\n",
    "Załaduj dźwięk raz i upewnij się, że powtarzane odtwarzanie nie wymaga restartu z płyty."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c94a3482",
   "metadata": {},
   "source": [
    "## Sprawa robocza"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "5db43595",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-09-03T10:12:21.438652Z",
     "iopub.status.busy": "2026-09-03T10:12:21.438442Z",
     "iopub.status.idle": "2026-09-03T10:12:21.628303Z",
     "shell.execute_reply": "2026-09-03T10:12:21.627635Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "pygame-ce 2.5.8 (SDL 2.32.10, Python 3.14.6)\n",
      "5 воспроизведений уже загруженного звука заняли (сек): 0.0001\n"
     ]
    }
   ],
   "source": [
    "import time\n",
    "from pathlib import Path\n",
    "\n",
    "import pygame\n",
    "\n",
    "pygame.init()\n",
    "pygame.mixer.init()\n",
    "screen = pygame.display.set_mode((600, 400))\n",
    "\n",
    "# Ścieżkę do zasobu tworzymy od ustalonego katalogu, a nie za pomocą łańcuch znaków „../../...”\n",
    "# w laptopie aktualny katalog to katalog samego laptopa, a w zwykłym folderze\n",
    "# .W pliku py- tutaj byłby Path(__file__).resolve().parent (rozdział 20.19).\n",
    "BASE_DIR = Path.cwd()\n",
    "put_k_zvuku = BASE_DIR.parents[1] / \"projects\" / \"pygame\" / \"bouncing-ball\" / \"assets\" / \"otskok.wav\"\n",
    "zvuk_otskoka = pygame.mixer.Sound(str(put_k_zvuku))   # загружаем ОДИН раз\n",
    "\n",
    "nachalo = time.perf_counter()\n",
    "for _ in range(5):\n",
    "    zvuk_otskoka.play()   # только воспроизводим уже загруженный звук\n",
    "vremya_pyati_vosproizvedenij = time.perf_counter() - nachalo\n",
    "\n",
    "print(\"5 воспроизведений уже загруженного звука заняли (сек):\", round(vremya_pyati_vosproizvedenij, 4))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "55658a84",
   "metadata": {},
   "source": [
    "## Sprawdzenie wyniku"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "fd0dbe78",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-09-03T10:12:21.630830Z",
     "iopub.status.busy": "2026-09-03T10:12:21.630606Z",
     "iopub.status.idle": "2026-09-03T10:12:21.633961Z",
     "shell.execute_reply": "2026-09-03T10:12:21.633270Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Верно: звук был загружен один раз, а не при каждом play().\n"
     ]
    }
   ],
   "source": [
    "assert isinstance(zvuk_otskoka, pygame.mixer.Sound)\n",
    "# odtwarzanie już pobranego nagrania nie jest odczytem dysku,\n",
    "# dlatego pięć połączeń powinno play() zmieścić się w ułamku sekundy.\n",
    "assert vremya_pyati_vosproizvedenij < 1.0\n",
    "print(\"Верно: звук был загружен один раз, а не при каждом play().\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1e93dacd",
   "metadata": {},
   "source": [
    "## Podstawowa praktyka zadań ★\n",
    "\n",
    "Załaduj dźwięk ponownie do osobnej zmiennej i upewnij się, że to NIE jest to ten sam obiekt Python w pamięci, mimo że oba wskazują na ten sam plik — tzn. dysk był faktycznie używany dwukrotnie."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "c3b6aa9f",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-09-03T10:12:21.635036Z",
     "iopub.status.busy": "2026-09-03T10:12:21.634917Z",
     "iopub.status.idle": "2026-09-03T10:12:21.637627Z",
     "shell.execute_reply": "2026-09-03T10:12:21.637180Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Верно: это два отдельных объекта — именно поэтому загрузку выносят из цикла заранее.\n"
     ]
    }
   ],
   "source": [
    "zvuk_otskoka_2 = pygame.mixer.Sound(put_k_zvuku)\n",
    "assert zvuk_otskoka_2 is not zvuk_otskoka\n",
    "print(\"Верно: это два отдельных объекта — именно поэтому загрузку выносят из цикла заранее.\")"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Cartesian Python 3.14",
   "language": "python",
   "name": "cartesian-python314"
  },
  "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.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
