[{"data":1,"prerenderedAt":24983},["ShallowReactive",2],{"navigation_docs":3,"-python-advanced-modules-packages-venv":5492,"-python-advanced-modules-packages-venv-surround":24978},[4,1707,2220,2692,2873,3041,3248,3370,3420,3477,3511,3637,3714,3728,3867,4245,4322,5055,5230,5323,5376,5488],{"title":5,"icon":6,"path":7,"stem":8,"children":9},"C#","i-devicon-csharp","\u002Fcsharp","01.csharp",[10,13,60,90,120,202,219,253,379,404,457,650,1364,1654,1703],{"title":11,"path":7,"stem":12},"C# та .NET","01.csharp\u002Findex",{"title":14,"icon":15,"path":16,"stem":17,"children":18,"page":59},"Fundamentals","i-lucide-book-open","\u002Fcsharp\u002Ffundamentals","01.csharp\u002F01.fundamentals",[19,23,27,31,35,39,43,47,51,55],{"title":20,"path":21,"stem":22},"Вступ до екосистеми .NET","\u002Fcsharp\u002Ffundamentals\u002Fintroduction-to-ecosystem","01.csharp\u002F01.fundamentals\u002F01.introduction-to-ecosystem",{"title":24,"path":25,"stem":26},"Структура програми на C#","\u002Fcsharp\u002Ffundamentals\u002Fprogram-structure","01.csharp\u002F01.fundamentals\u002F02.program-structure",{"title":28,"path":29,"stem":30},"Змінні та Типи Даних","\u002Fcsharp\u002Ffundamentals\u002Fvariables-data-types","01.csharp\u002F01.fundamentals\u002F03.variables-data-types",{"title":32,"path":33,"stem":34},"Масиви","\u002Fcsharp\u002Ffundamentals\u002Farrays","01.csharp\u002F01.fundamentals\u002F04.arrays",{"title":36,"path":37,"stem":38},"Strings & Text Handling","\u002Fcsharp\u002Ffundamentals\u002Fstrings-text-handling","01.csharp\u002F01.fundamentals\u002F05.strings-text-handling",{"title":40,"path":41,"stem":42},"Дати і Час","\u002Fcsharp\u002Ffundamentals\u002Fdates-time-handling","01.csharp\u002F01.fundamentals\u002F06.dates-time-handling",{"title":44,"path":45,"stem":46},"Потік Керування","\u002Fcsharp\u002Ffundamentals\u002Fcontrol-flow","01.csharp\u002F01.fundamentals\u002F07.control-flow",{"title":48,"path":49,"stem":50},"Методи","\u002Fcsharp\u002Ffundamentals\u002Fmethods","01.csharp\u002F01.fundamentals\u002F08.methods",{"title":52,"path":53,"stem":54},"Основи Відлагодження","\u002Fcsharp\u002Ffundamentals\u002Fdebugging-basics","01.csharp\u002F01.fundamentals\u002F09.debugging-basics",{"title":56,"path":57,"stem":58},"Інтерактивна Консоль (Classic)","\u002Fcsharp\u002Ffundamentals\u002Finteractive-console","01.csharp\u002F01.fundamentals\u002F10.interactive-console",false,{"title":61,"icon":62,"path":63,"stem":64,"children":65,"page":59},"OOP","i-lucide-box","\u002Fcsharp\u002Foop","01.csharp\u002F02.oop",[66,70,74,78,82,86],{"title":67,"path":68,"stem":69},"Package Management (Управління Пакетами)","\u002Fcsharp\u002Foop\u002Fpackage-management","01.csharp\u002F02.oop\u002F01.package-management",{"title":71,"path":72,"stem":73},"Класи та Об'єкти","\u002Fcsharp\u002Foop\u002Fclasses-objects","01.csharp\u002F02.oop\u002F02.classes-objects",{"title":75,"path":76,"stem":77},"Властивості та Поля","\u002Fcsharp\u002Foop\u002Fproperties-fields","01.csharp\u002F02.oop\u002F03.properties-fields",{"title":79,"path":80,"stem":81},"Стовпи ООП","\u002Fcsharp\u002Foop\u002Foop-pillars","01.csharp\u002F02.oop\u002F04.oop-pillars",{"title":83,"path":84,"stem":85},"Advanced Types","\u002Fcsharp\u002Foop\u002Fadvanced-types","01.csharp\u002F02.oop\u002F05.advanced-types",{"title":87,"path":88,"stem":89},"Namespaces (Простори Імен)","\u002Fcsharp\u002Foop\u002Fnamespaces","01.csharp\u002F02.oop\u002F06.namespaces",{"title":91,"icon":92,"path":93,"stem":94,"children":95,"page":59},"Advanced Core","i-lucide-zap","\u002Fcsharp\u002Fadvanced-core","01.csharp\u002F03.advanced-core",[96,100,104,108,112,116],{"title":97,"path":98,"stem":99},"Generics (Узагальнення)","\u002Fcsharp\u002Fadvanced-core\u002Fgenerics","01.csharp\u002F03.advanced-core\u002F01.generics",{"title":101,"path":102,"stem":103},"Делегати, Події та Лямбда-вирази","\u002Fcsharp\u002Fadvanced-core\u002Fdelegates-events-lambdas","01.csharp\u002F03.advanced-core\u002F02.delegates-events-lambdas",{"title":105,"path":106,"stem":107},"Interfaces Deep Dive (Інтерфейси: Поглиблений Розгляд)","\u002Fcsharp\u002Fadvanced-core\u002Finterfaces-deep-dive","01.csharp\u002F03.advanced-core\u002F03.interfaces-deep-dive",{"title":109,"path":110,"stem":111},"Обробка Винятків","\u002Fcsharp\u002Fadvanced-core\u002Fexception-handling","01.csharp\u002F03.advanced-core\u002F04.exception-handling",{"title":113,"path":114,"stem":115},"Pattern Matching","\u002Fcsharp\u002Fadvanced-core\u002Fpattern-matching","01.csharp\u002F03.advanced-core\u002F05.pattern-matching",{"title":117,"path":118,"stem":119},"Додаткові Можливості C#","\u002Fcsharp\u002Fadvanced-core\u002Fadditional-features","01.csharp\u002F03.advanced-core\u002F06.additional-features",{"title":121,"icon":122,"path":123,"stem":124,"children":125,"page":59},"Architecture Best Practices","i-lucide-building-2","\u002Fcsharp\u002Farchitecture-best-practices","01.csharp\u002F04.architecture-best-practices",[126,130,149,153,157,161,165,169],{"title":127,"path":128,"stem":129},"Software Design Principles (Частина 1)","\u002Fcsharp\u002Farchitecture-best-practices\u002Fsoftware-design-principles","01.csharp\u002F04.architecture-best-practices\u002F01.software-design-principles",{"title":131,"icon":132,"path":133,"stem":134,"children":135,"page":59},"Design Patterns","i-lucide-folder","\u002Fcsharp\u002Farchitecture-best-practices\u002Fdesign-patterns","01.csharp\u002F04.architecture-best-practices\u002F02.design-patterns",[136],{"title":137,"icon":132,"path":138,"stem":139,"children":140,"page":59},"Creational","\u002Fcsharp\u002Farchitecture-best-practices\u002Fdesign-patterns\u002Fcreational","01.csharp\u002F04.architecture-best-practices\u002F02.design-patterns\u002Fcreational",[141,145],{"title":142,"path":143,"stem":144},"Singleton (Одинак)","\u002Fcsharp\u002Farchitecture-best-practices\u002Fdesign-patterns\u002Fcreational\u002Fsingleton","01.csharp\u002F04.architecture-best-practices\u002F02.design-patterns\u002Fcreational\u002F01.singleton",{"title":146,"path":147,"stem":148},"Builder (Будівельник)","\u002Fcsharp\u002Farchitecture-best-practices\u002Fdesign-patterns\u002Fcreational\u002Fbuilder","01.csharp\u002F04.architecture-best-practices\u002F02.design-patterns\u002Fcreational\u002F02.builder",{"title":150,"path":151,"stem":152},"Building Professional CLIs","\u002Fcsharp\u002Farchitecture-best-practices\u002Fbuilding-professional-clis","01.csharp\u002F04.architecture-best-practices\u002F03.building-professional-clis",{"title":154,"path":155,"stem":156},"Validation & Flow Control","\u002Fcsharp\u002Farchitecture-best-practices\u002Fvalidation-flow-control","01.csharp\u002F04.architecture-best-practices\u002F04.validation-flow-control",{"title":158,"path":159,"stem":160},"The Modern .NET Host (Microsoft.Extensions)","\u002Fcsharp\u002Farchitecture-best-practices\u002Fmodern-dotnet-host","01.csharp\u002F04.architecture-best-practices\u002F05.modern-dotnet-host",{"title":162,"path":163,"stem":164},"Data Mapper: Repository та DAO патерни (Частина 1)","\u002Fcsharp\u002Farchitecture-best-practices\u002Fdata-mapper-part1","01.csharp\u002F04.architecture-best-practices\u002F06.data-mapper-part1",{"title":166,"path":167,"stem":168},"Data Mapper: Repository та DAO патерни (Частина 2)","\u002Fcsharp\u002Farchitecture-best-practices\u002Fdata-mapper-part2","01.csharp\u002F04.architecture-best-practices\u002F07.data-mapper-part2",{"title":170,"icon":132,"path":171,"stem":172,"children":173,"page":59},"Di Ioc","\u002Fcsharp\u002Farchitecture-best-practices\u002Fdi-ioc","01.csharp\u002F04.architecture-best-practices\u002F08.di-ioc",[174,178,182,186,190,194,198],{"title":175,"path":176,"stem":177},"Проблема залежностей та Інверсія Контролю","\u002Fcsharp\u002Farchitecture-best-practices\u002Fdi-ioc\u002Fthe-dependency-problem","01.csharp\u002F04.architecture-best-practices\u002F08.di-ioc\u002F01.the-dependency-problem",{"title":179,"path":180,"stem":181},"Будуємо власний Service Container","\u002Fcsharp\u002Farchitecture-best-practices\u002Fdi-ioc\u002Fbuild-your-own-container","01.csharp\u002F04.architecture-best-practices\u002F08.di-ioc\u002F02.build-your-own-container",{"title":183,"path":184,"stem":185},"Service Locator: Паттерн та Анти-паттерн","\u002Fcsharp\u002Farchitecture-best-practices\u002Fdi-ioc\u002Fservice-locator-pattern","01.csharp\u002F04.architecture-best-practices\u002F08.di-ioc\u002F03.service-locator-pattern",{"title":187,"path":188,"stem":189},"Паттерни Dependency Injection","\u002Fcsharp\u002Farchitecture-best-practices\u002Fdi-ioc\u002Fdependency-injection-patterns","01.csharp\u002F04.architecture-best-practices\u002F08.di-ioc\u002F04.dependency-injection-patterns",{"title":191,"path":192,"stem":193},"Microsoft DI: IServiceCollection та IServiceProvider","\u002Fcsharp\u002Farchitecture-best-practices\u002Fdi-ioc\u002Fmicrosoft-di-deep-dive","01.csharp\u002F04.architecture-best-practices\u002F08.di-ioc\u002F05.microsoft-di-deep-dive",{"title":195,"path":196,"stem":197},"Service Lifetimes та Scopes","\u002Fcsharp\u002Farchitecture-best-practices\u002Fdi-ioc\u002Fservice-lifetimes-and-scopes","01.csharp\u002F04.architecture-best-practices\u002F08.di-ioc\u002F06.service-lifetimes-and-scopes",{"title":199,"path":200,"stem":201},"DI Анти-паттерни та Найкращі Практики","\u002Fcsharp\u002Farchitecture-best-practices\u002Fdi-ioc\u002Fdi-anti-patterns-and-best-practices","01.csharp\u002F04.architecture-best-practices\u002F08.di-ioc\u002F07.di-anti-patterns-and-best-practices",{"title":203,"icon":132,"path":204,"stem":205,"children":206,"page":59},"Standard Library","\u002Fcsharp\u002Fstandard-library","01.csharp\u002F05.standard-library",[207,211,215],{"title":208,"path":209,"stem":210},"Collections (Колекції)","\u002Fcsharp\u002Fstandard-library\u002Fcollections","01.csharp\u002F05.standard-library\u002F01.collections",{"title":212,"path":213,"stem":214},"High Performance Types (Високопродуктивні Типи)","\u002Fcsharp\u002Fstandard-library\u002Fhigh-performance-types","01.csharp\u002F05.standard-library\u002F02.high-performance-types",{"title":216,"path":217,"stem":218},"LINQ (Language Integrated Query)","\u002Fcsharp\u002Fstandard-library\u002Flinq","01.csharp\u002F05.standard-library\u002F03.linq",{"title":220,"icon":221,"path":222,"stem":223,"children":224,"page":59},"System Internals Concurrency","i-lucide-server","\u002Fcsharp\u002Fsystem-internals-concurrency","01.csharp\u002F06.system-internals-concurrency",[225,229,233,237,241,245,249],{"title":226,"path":227,"stem":228},"Memory Management","\u002Fcsharp\u002Fsystem-internals-concurrency\u002Fmemory-management","01.csharp\u002F06.system-internals-concurrency\u002F01.memory-management",{"title":230,"path":231,"stem":232},"Reflection API: System.Type та Метадані","\u002Fcsharp\u002Fsystem-internals-concurrency\u002Freflection-fundamentals","01.csharp\u002F06.system-internals-concurrency\u002F02.reflection-fundamentals",{"title":234,"path":235,"stem":236},"Attributes та Dynamic Language Runtime","\u002Fcsharp\u002Fsystem-internals-concurrency\u002Fattributes-dynamic","01.csharp\u002F06.system-internals-concurrency\u002F03.attributes-dynamic",{"title":238,"path":239,"stem":240},"Expression Trees: Швидка Альтернатива Рефлексії","\u002Fcsharp\u002Fsystem-internals-concurrency\u002Fexpression-trees-compiled","01.csharp\u002F06.system-internals-concurrency\u002F04.expression-trees-compiled",{"title":242,"path":243,"stem":244},"Source Generators: Compile-Time Code Generation","\u002Fcsharp\u002Fsystem-internals-concurrency\u002Fsource-generators","01.csharp\u002F06.system-internals-concurrency\u002F05.source-generators",{"title":246,"path":247,"stem":248},"Multithreading Fundamentals","\u002Fcsharp\u002Fsystem-internals-concurrency\u002Fmultithreading-fundamentals","01.csharp\u002F06.system-internals-concurrency\u002F06.multithreading-fundamentals",{"title":250,"path":251,"stem":252},"Synchronization Primitives","\u002Fcsharp\u002Fsystem-internals-concurrency\u002Fsynchronization-primitives","01.csharp\u002F06.system-internals-concurrency\u002F07.synchronization-primitives",{"title":254,"icon":255,"path":256,"stem":257,"children":258,"page":59},"System Programming Windows","i-lucide-cpu","\u002Fcsharp\u002Fsystem-programming-windows","01.csharp\u002F07.system-programming-windows",[259,263,267,271,275,279,283,287,291,295,299,303,307,311,315,319,323,327,331,335,339,343,347,351,355,359,363,367,371,375],{"title":260,"path":261,"stem":262},"Як Працює Операційна Система","\u002Fcsharp\u002Fsystem-programming-windows\u002Fhow-os-works","01.csharp\u002F07.system-programming-windows\u002F01.how-os-works",{"title":264,"path":265,"stem":266},"Процеси в .NET — API та Запуск","\u002Fcsharp\u002Fsystem-programming-windows\u002Fprocesses-in-dotnet","01.csharp\u002F07.system-programming-windows\u002F02.processes-in-dotnet",{"title":268,"path":269,"stem":270},"Процеси в .NET — IPC та Міжпроцесна Комунікація","\u002Fcsharp\u002Fsystem-programming-windows\u002F02a.processes-ipc","01.csharp\u002F07.system-programming-windows\u002F02a.processes-ipc",{"title":272,"path":273,"stem":274},"Application Domains та Збірки — AppDomain і AssemblyLoadContext","\u002Fcsharp\u002Fsystem-programming-windows\u002Fappdomains-assemblies","01.csharp\u002F07.system-programming-windows\u002F03.appdomains-assemblies",{"title":276,"path":277,"stem":278},"Application Domains та Збірки — Plug-in Система з Hot-Reload","\u002Fcsharp\u002Fsystem-programming-windows\u002F03a.appdomains-plugin-system","01.csharp\u002F07.system-programming-windows\u002F03a.appdomains-plugin-system",{"title":280,"path":281,"stem":282},"Потоки — Основи та API Thread","\u002Fcsharp\u002Fsystem-programming-windows\u002Fthread-fundamentals","01.csharp\u002F07.system-programming-windows\u002F04.thread-fundamentals",{"title":284,"path":285,"stem":286},"Потоки — Lifecycle, Пріоритети та Безпечне Завершення","\u002Fcsharp\u002Fsystem-programming-windows\u002F04a.thread-lifecycle-priorities","01.csharp\u002F07.system-programming-windows\u002F04a.thread-lifecycle-priorities",{"title":288,"path":289,"stem":290},"Проблеми Спільного Стану — Race Condition та Data Race","\u002Fcsharp\u002Fsystem-programming-windows\u002Fshared-state-problems","01.csharp\u002F07.system-programming-windows\u002F05.shared-state-problems",{"title":292,"path":293,"stem":294},"Проблеми Спільного Стану — Memory Model та volatile","\u002Fcsharp\u002Fsystem-programming-windows\u002F05a.shared-state-memory-model","01.csharp\u002F07.system-programming-windows\u002F05a.shared-state-memory-model",{"title":296,"path":297,"stem":298},"Синхронізація — Monitor, lock та еволюція примітивів","\u002Fcsharp\u002Fsystem-programming-windows\u002Fsynchronization-fundamentals","01.csharp\u002F07.system-programming-windows\u002F06.synchronization-fundamentals",{"title":300,"path":301,"stem":302},"Синхронізація — Наскрізний Приклад та Deadlock Detection","\u002Fcsharp\u002Fsystem-programming-windows\u002F06a.synchronization-walkthrough","01.csharp\u002F07.system-programming-windows\u002F06a.synchronization-walkthrough",{"title":304,"path":305,"stem":306},"Синхронізація — Mutex, Semaphore та Event-Based Primitives","\u002Fcsharp\u002Fsystem-programming-windows\u002Fsynchronization-advanced","01.csharp\u002F07.system-programming-windows\u002F07.synchronization-advanced",{"title":308,"path":309,"stem":310},"Синхронізація — Interlocked, Volatile та Lock-Free Структури","\u002Fcsharp\u002Fsystem-programming-windows\u002F07a.synchronization-advanced-walkthrough","01.csharp\u002F07.system-programming-windows\u002F07a.synchronization-advanced-walkthrough",{"title":312,"path":313,"stem":314},"Interlocked, CAS та Lock-Free Структури","\u002Fcsharp\u002Fsystem-programming-windows\u002Finterlocked-cas-lockfree","01.csharp\u002F07.system-programming-windows\u002F08.interlocked-cas-lockfree",{"title":316,"path":317,"stem":318},"Volatile, Memory Model та Spinning","\u002Fcsharp\u002Fsystem-programming-windows\u002F08a.volatile-memory-model","01.csharp\u002F07.system-programming-windows\u002F08a.volatile-memory-model",{"title":320,"path":321,"stem":322},"ThreadPool — Пул Потоків для Ефективного Виконання","\u002Fcsharp\u002Fsystem-programming-windows\u002Fthread-pool","01.csharp\u002F07.system-programming-windows\u002F09.thread-pool",{"title":324,"path":325,"stem":326},"ThreadPool — Просунуті Сценарії та Внутрішня Будова","\u002Fcsharp\u002Fsystem-programming-windows\u002F09a.thread-pool-advanced","01.csharp\u002F07.system-programming-windows\u002F09a.thread-pool-advanced",{"title":328,"path":329,"stem":330},"Concurrent та Immutable Collections","\u002Fcsharp\u002Fsystem-programming-windows\u002Fconcurrent-collections","01.csharp\u002F07.system-programming-windows\u002F10.concurrent-collections",{"title":332,"path":333,"stem":334},"TPL, Task та Композиція — Від Thread до Task","\u002Fcsharp\u002Fsystem-programming-windows\u002Ftpl-parallel-plinq","01.csharp\u002F07.system-programming-windows\u002F11.tpl-parallel-plinq",{"title":336,"path":337,"stem":338},"Parallel Class та PLINQ — Data Parallelism","\u002Fcsharp\u002Fsystem-programming-windows\u002F11a.tpl-parallel-plinq-advanced","01.csharp\u002F07.system-programming-windows\u002F11a.tpl-parallel-plinq-advanced",{"title":340,"path":341,"stem":342},"Async\u002FAwait — Фундамент Асинхронного Програмування","\u002Fcsharp\u002Fsystem-programming-windows\u002Fasync-fundamentals","01.csharp\u002F07.system-programming-windows\u002F12.async-fundamentals",{"title":344,"path":345,"stem":346},"SynchronizationContext та ConfigureAwait — Контекст Виконання","\u002Fcsharp\u002Fsystem-programming-windows\u002Fasync-context-configureawait","01.csharp\u002F07.system-programming-windows\u002F13.async-context-configureawait",{"title":348,"path":349,"stem":350},"Async — Просунуті Паттерни","\u002Fcsharp\u002Fsystem-programming-windows\u002Fasync-advanced","01.csharp\u002F07.system-programming-windows\u002F14.async-advanced",{"title":352,"path":353,"stem":354},"System.Threading.Channels — Async Producer-Consumer","\u002Fcsharp\u002Fsystem-programming-windows\u002Fchannels","01.csharp\u002F07.system-programming-windows\u002F15.channels",{"title":356,"path":357,"stem":358},"Асинхронна Синхронізація","\u002Fcsharp\u002Fsystem-programming-windows\u002Fasync-synchronization","01.csharp\u002F07.system-programming-windows\u002F16.async-synchronization",{"title":360,"path":361,"stem":362},"Unsafe Code та Вказівники","\u002Fcsharp\u002Fsystem-programming-windows\u002Funsafe-code","01.csharp\u002F07.system-programming-windows\u002F17.unsafe-code",{"title":364,"path":365,"stem":366},"P\u002FInvoke та Windows API — Міст між .NET та Native Code","\u002Fcsharp\u002Fsystem-programming-windows\u002Fpinvoke-winapi","01.csharp\u002F07.system-programming-windows\u002F18.pinvoke-winapi",{"title":368,"path":369,"stem":370},"Реєстр Windows — Центральна База Конфігурації Системи","\u002Fcsharp\u002Fsystem-programming-windows\u002Fwindows-registry","01.csharp\u002F07.system-programming-windows\u002F19.windows-registry",{"title":372,"path":373,"stem":374},"Windows Hooks, Hotkeys та Services — Глибока Інтеграція з ОС","\u002Fcsharp\u002Fsystem-programming-windows\u002Fwindows-hooks-services","01.csharp\u002F07.system-programming-windows\u002F20.windows-hooks-services",{"title":376,"path":377,"stem":378},"Системне Програмування C# (Windows) — 07.system-programming-windows","\u002Fcsharp\u002Fsystem-programming-windows\u002Fimplementation_plan","01.csharp\u002F07.system-programming-windows\u002Fimplementation_plan",{"title":380,"icon":132,"path":381,"stem":382,"children":383,"page":59},"Io","\u002Fcsharp\u002Fio","01.csharp\u002F08.io",[384,388,392,396,400],{"title":385,"path":386,"stem":387},"8.1.1. Основи роботи з файловою системою","\u002Fcsharp\u002Fio\u002Ffile-system-basics","01.csharp\u002F08.io\u002F01.file-system-basics",{"title":389,"path":390,"stem":391},"8.1.2. Потоки (Streams) та Серіалізація Даних","\u002Fcsharp\u002Fio\u002Fstreams-serialization","01.csharp\u002F08.io\u002F02.streams-serialization",{"title":393,"path":394,"stem":395},"8.2.1. JSON Serialization з System.Text.Json","\u002Fcsharp\u002Fio\u002Fjson-serialization","01.csharp\u002F08.io\u002F03.json-serialization",{"title":397,"path":398,"stem":399},"8.2.2. XML Serialization та LINQ to XML","\u002Fcsharp\u002Fio\u002Fxml-serialization","01.csharp\u002F08.io\u002F04.xml-serialization",{"title":401,"path":402,"stem":403},"8.2.3. Binary Serialization: MessagePack та Protocol Buffers","\u002Fcsharp\u002Fio\u002Fbinary-serialization","01.csharp\u002F08.io\u002F05.binary-serialization",{"title":405,"icon":132,"path":406,"stem":407,"children":408,"page":59},"Ado Net","\u002Fcsharp\u002Fado-net","01.csharp\u002F09.ado-net",[409,413,417,421,425,429,433,437,441,445,449,453],{"title":410,"path":411,"stem":412},"9.1. Введення в ADO.NET","\u002Fcsharp\u002Fado-net\u002Fintroduction-to-adonet","01.csharp\u002F09.ado-net\u002F01.introduction-to-adonet",{"title":414,"path":415,"stem":416},"9.2. Клас DbConnection — з'єднання з базою даних","\u002Fcsharp\u002Fado-net\u002Fconnection","01.csharp\u002F09.ado-net\u002F02.connection",{"title":418,"path":419,"stem":420},"9.3. Клас DbCommand — виконання SQL-запитів","\u002Fcsharp\u002Fado-net\u002Fcommand-and-queries","01.csharp\u002F09.ado-net\u002F03.command-and-queries",{"title":422,"path":423,"stem":424},"9.4. Клас DbDataReader — ефективне читання даних","\u002Fcsharp\u002Fado-net\u002Fdatareader","01.csharp\u002F09.ado-net\u002F04.datareader",{"title":426,"path":427,"stem":428},"9.5. Параметризовані запити та захист від SQL Injection","\u002Fcsharp\u002Fado-net\u002Fparameters-and-sql-injection","01.csharp\u002F09.ado-net\u002F05.parameters-and-sql-injection",{"title":430,"path":431,"stem":432},"9.6. Транзакції в ADO.NET","\u002Fcsharp\u002Fado-net\u002Ftransactions","01.csharp\u002F09.ado-net\u002F06.transactions",{"title":434,"path":435,"stem":436},"9.7. DbProviderFactory — провайдер-незалежний код","\u002Fcsharp\u002Fado-net\u002Fprovider-factory","01.csharp\u002F09.ado-net\u002F07.provider-factory",{"title":438,"path":439,"stem":440},"9.8. Асинхронний доступ до даних","\u002Fcsharp\u002Fado-net\u002Fasync-data-access","01.csharp\u002F09.ado-net\u002F08.async-data-access",{"title":442,"path":443,"stem":444},"9.9. Від'єднаний режим: DataSet, DataTable, DataRow","\u002Fcsharp\u002Fado-net\u002Fdisconnected-mode-dataset","01.csharp\u002F09.ado-net\u002F09.disconnected-mode-dataset",{"title":446,"path":447,"stem":448},"9.10. DataAdapter — міст між DataSet та базою даних","\u002Fcsharp\u002Fado-net\u002Fdata-adapter","01.csharp\u002F09.ado-net\u002F10.data-adapter",{"title":450,"path":451,"stem":452},"9.11. Data Mapper та Repository: Архітектура доступу до даних","\u002Fcsharp\u002Fado-net\u002Fdata-mapper-repository","01.csharp\u002F09.ado-net\u002F11.data-mapper-repository",{"title":454,"path":455,"stem":456},"9.12. Identity Map, Unit of Work та Specification Pattern","\u002Fcsharp\u002Fado-net\u002Fadvanced-patterns","01.csharp\u002F09.ado-net\u002F12.advanced-patterns",{"title":458,"icon":255,"path":459,"stem":460,"children":461,"page":59},"Ef Core","\u002Fcsharp\u002Fef-core","01.csharp\u002F10.ef-core",[462,466,470,474,478,482,486,490,494,498,502,506,510,514,518,522,526,532,538,542,546,550,554,558,562,566,570,574,578,582,586,590,594,598,602,606,610,614,618,622,626,630,634,638,642,646],{"title":463,"path":464,"stem":465},"Що таке ORM? Від SQL до об'єктів","\u002Fcsharp\u002Fef-core\u002Fwhat-is-orm","01.csharp\u002F10.ef-core\u002F01.what-is-orm",{"title":467,"path":468,"stem":469},"Перший проєкт — від нуля до CRUD","\u002Fcsharp\u002Fef-core\u002Ffirst-project","01.csharp\u002F10.ef-core\u002F02.first-project",{"title":471,"path":472,"stem":473},"DbContext — Серце EF Core","\u002Fcsharp\u002Fef-core\u002Fdbcontext-deep-dive","01.csharp\u002F10.ef-core\u002F03.dbcontext-deep-dive",{"title":475,"path":476,"stem":477},"Провайдери баз даних — Архітектура та Вибір СУБД","\u002Fcsharp\u002Fef-core\u002Fdatabase-providers","01.csharp\u002F10.ef-core\u002F04.database-providers",{"title":479,"path":480,"stem":481},"Конвенції EF Core — Магія без конфігурації","\u002Fcsharp\u002Fef-core\u002Fconventions","01.csharp\u002F10.ef-core\u002F05.conventions",{"title":483,"path":484,"stem":485},"Fluent API та Data Annotations — Явна конфігурація моделі","\u002Fcsharp\u002Fef-core\u002Ffluent-api-vs-annotations","01.csharp\u002F10.ef-core\u002F06.fluent-api-vs-annotations",{"title":487,"path":488,"stem":489},"Зв'язки — One-to-One та One-to-Many","\u002Fcsharp\u002Fef-core\u002Frelationships-basics","01.csharp\u002F10.ef-core\u002F07.relationships-basics",{"title":491,"path":492,"stem":493},"Зв'язки Advanced — Many-to-Many та Складні Сценарії","\u002Fcsharp\u002Fef-core\u002Frelationships-advanced","01.csharp\u002F10.ef-core\u002F08.relationships-advanced",{"title":495,"path":496,"stem":497},"Властивості — Типи, Конвертери, Компаратори (Частина 1)","\u002Fcsharp\u002Fef-core\u002Fproperty-configuration-part1","01.csharp\u002F10.ef-core\u002F09.property-configuration-part1",{"title":499,"path":500,"stem":501},"Властивості — Value Comparers, Generators, Shadow Properties (Частина 2)","\u002Fcsharp\u002Fef-core\u002Fproperty-configuration-part2","01.csharp\u002F10.ef-core\u002F09.property-configuration-part2",{"title":503,"path":504,"stem":505},"Складні типи — Owned Types та Complex Types (Частина 1)","\u002Fcsharp\u002Fef-core\u002Fcomplex-types-owned-part1","01.csharp\u002F10.ef-core\u002F10.complex-types-owned-part1",{"title":507,"path":508,"stem":509},"Складні типи — Complex Types, Keyless Entities, Порівняння (Частина 2)","\u002Fcsharp\u002Fef-core\u002Fcomplex-types-owned-part2","01.csharp\u002F10.ef-core\u002F10.complex-types-owned-part2",{"title":511,"path":512,"stem":513},"JSON Columns — Складні дані у JSON (Частина 1)","\u002Fcsharp\u002Fef-core\u002Fjson-columns-part1","01.csharp\u002F10.ef-core\u002F11.json-columns-part1",{"title":515,"path":516,"stem":517},"JSON Columns — Value Comparers, Індекси, Провайдери (Частина 2)","\u002Fcsharp\u002Fef-core\u002Fjson-columns-part2","01.csharp\u002F10.ef-core\u002F11.json-columns-part2",{"title":519,"path":520,"stem":521},"Успадкування — Абстрактні класи та TPH (Частина 1)","\u002Fcsharp\u002Fef-core\u002Finheritance-part1","01.csharp\u002F10.ef-core\u002F12.inheritance-part1",{"title":523,"path":524,"stem":525},"Успадкування — TPT, TPC та Порівняння Стратегій (Частина 2)","\u002Fcsharp\u002Fef-core\u002Finheritance-part2","01.csharp\u002F10.ef-core\u002F12.inheritance-part2",{"title":527,"path":528,"stem":529,"children":530},"Індекси, Обмеження та Схема (Частина 1)","\u002Fcsharp\u002Fef-core\u002Findexes-constraints-part1","01.csharp\u002F10.ef-core\u002F13.indexes-constraints-part1",[531],{"title":527,"path":528,"stem":529},{"title":533,"path":534,"stem":535,"children":536},"Індекси, Обмеження та Схема (Частина 2)","\u002Fcsharp\u002Fef-core\u002Findexes-constraints-part2","01.csharp\u002F10.ef-core\u002F13.indexes-constraints-part2",[537],{"title":533,"path":534,"stem":535},{"title":539,"path":540,"stem":541},"Seed Data — Початкові Дані (Частина 1)","\u002Fcsharp\u002Fef-core\u002Fseeding-part1","01.csharp\u002F10.ef-core\u002F14.seeding-part1",{"title":543,"path":544,"stem":545},"Seed Data — SQL-скрипти, Bogus та Стратегії (Частина 2)","\u002Fcsharp\u002Fef-core\u002Fseeding-part2","01.csharp\u002F10.ef-core\u002F14.seeding-part2",{"title":547,"path":548,"stem":549},"Global Query Filters — Глобальні Фільтри (Частина 1)","\u002Fcsharp\u002Fef-core\u002Fglobal-query-filters-part1","01.csharp\u002F10.ef-core\u002F15.global-query-filters-part1",{"title":551,"path":552,"stem":553},"Global Query Filters — Підводні камені та Інтеграція (Частина 2)","\u002Fcsharp\u002Fef-core\u002Fglobal-query-filters-part2","01.csharp\u002F10.ef-core\u002F15.global-query-filters-part2",{"title":555,"path":556,"stem":557},"LINQ-запити в EF Core (Частина 1)","\u002Fcsharp\u002Fef-core\u002Flinq-queries-part1","01.csharp\u002F10.ef-core\u002F16.linq-queries-part1",{"title":559,"path":560,"stem":561},"LINQ-запити в EF Core (Частина 2)","\u002Fcsharp\u002Fef-core\u002Flinq-queries-part2","01.csharp\u002F10.ef-core\u002F16.linq-queries-part2",{"title":563,"path":564,"stem":565},"Завантаження Пов'язаних Даних (Частина 1)","\u002Fcsharp\u002Fef-core\u002Floading-related-data-part1","01.csharp\u002F10.ef-core\u002F17.loading-related-data-part1",{"title":567,"path":568,"stem":569},"Завантаження Пов'язаних Даних (Частина 2)","\u002Fcsharp\u002Fef-core\u002Floading-related-data-part2","01.csharp\u002F10.ef-core\u002F17.loading-related-data-part2",{"title":571,"path":572,"stem":573},"Raw SQL, Views та Stored Procedures (Частина 1)","\u002Fcsharp\u002Fef-core\u002Fraw-sql-part1","01.csharp\u002F10.ef-core\u002F18.raw-sql-part1",{"title":575,"path":576,"stem":577},"Raw SQL — Stored Procedures, DbFunction та Bulk Operations (Частина 2)","\u002Fcsharp\u002Fef-core\u002Fraw-sql-part2","01.csharp\u002F10.ef-core\u002F18.raw-sql-part2",{"title":579,"path":580,"stem":581},"Продвинуті Запити — Compiled Queries, Bulk та Оптимізація (Частина 1)","\u002Fcsharp\u002Fef-core\u002Fadvanced-queries-part1","01.csharp\u002F10.ef-core\u002F19.advanced-queries-part1",{"title":583,"path":584,"stem":585},"Продвинуті Запити — Query Tags, Bulk та Interceptors (Частина 2)","\u002Fcsharp\u002Fef-core\u002Fadvanced-queries-part2","01.csharp\u002F10.ef-core\u002F19.advanced-queries-part2",{"title":587,"path":588,"stem":589},"Change Tracker — Відстеження Змін (Частина 1)","\u002Fcsharp\u002Fef-core\u002Fchange-tracking-part1","01.csharp\u002F10.ef-core\u002F20.change-tracking-part1",{"title":591,"path":592,"stem":593},"Change Tracker — Графи Об'єктів та Disconnected (Частина 2)","\u002Fcsharp\u002Fef-core\u002Fchange-tracking-part2","01.csharp\u002F10.ef-core\u002F20.change-tracking-part2",{"title":595,"path":596,"stem":597},"Збереження Даних та Транзакції (Частина 1)","\u002Fcsharp\u002Fef-core\u002Fsaving-data-part1","01.csharp\u002F10.ef-core\u002F21.saving-data-part1",{"title":599,"path":600,"stem":601},"Збереження Даних — Concurrency та Outbox (Частина 2)","\u002Fcsharp\u002Fef-core\u002Fsaving-data-part2","01.csharp\u002F10.ef-core\u002F21.saving-data-part2",{"title":603,"path":604,"stem":605},"Конкурентність та Блокування (Частина 1)","\u002Fcsharp\u002Fef-core\u002Fconcurrency-part1","01.csharp\u002F10.ef-core\u002F22.concurrency-part1",{"title":607,"path":608,"stem":609},"Конкурентність — Дедлоки та Queue Processing (Частина 2)","\u002Fcsharp\u002Fef-core\u002Fconcurrency-part2","01.csharp\u002F10.ef-core\u002F22.concurrency-part2",{"title":611,"path":612,"stem":613},"Міграції в EF Core — Основи (Частина 1)","\u002Fcsharp\u002Fef-core\u002Fmigrations-basics-part1","01.csharp\u002F10.ef-core\u002F23.migrations-basics-part1",{"title":615,"path":616,"stem":617},"Міграції в EF Core — Основи (Частина 2)","\u002Fcsharp\u002Fef-core\u002Fmigrations-basics-part2","01.csharp\u002F10.ef-core\u002F23.migrations-basics-part2",{"title":619,"path":620,"stem":621},"Міграції — Просунуті Сценарії (Частина 1)","\u002Fcsharp\u002Fef-core\u002Fmigrations-advanced-part1","01.csharp\u002F10.ef-core\u002F24.migrations-advanced-part1",{"title":623,"path":624,"stem":625},"Міграції — Просунуті Сценарії (Частина 2)","\u002Fcsharp\u002Fef-core\u002Fmigrations-advanced-part2","01.csharp\u002F10.ef-core\u002F24.migrations-advanced-part2",{"title":627,"path":628,"stem":629},"Управління Схемою та Database-First (Частина 1)","\u002Fcsharp\u002Fef-core\u002Fschema-management-part1","01.csharp\u002F10.ef-core\u002F25.schema-management-part1",{"title":631,"path":632,"stem":633},"Управління Схемою та Database-First (Частина 2)","\u002Fcsharp\u002Fef-core\u002Fschema-management-part2","01.csharp\u002F10.ef-core\u002F25.schema-management-part2",{"title":635,"path":636,"stem":637},"Продуктивність EF Core — Основи (Частина 1)","\u002Fcsharp\u002Fef-core\u002Fperformance-fundamentals-part1","01.csharp\u002F10.ef-core\u002F26.performance-fundamentals-part1",{"title":639,"path":640,"stem":641},"Interceptors в EF Core (Частина 1)","\u002Fcsharp\u002Fef-core\u002Finterceptors-part1","01.csharp\u002F10.ef-core\u002F29.interceptors-part1",{"title":643,"path":644,"stem":645},"Interceptors в EF Core — Connection, Transaction та Materialization (Частина 2)","\u002Fcsharp\u002Fef-core\u002Finterceptors-part2","01.csharp\u002F10.ef-core\u002F29.interceptors-part2",{"title":647,"path":648,"stem":649},"План вивчення Entity Framework Core — Повний курс","\u002Fcsharp\u002Fef-core\u002Fimplementation_plan","01.csharp\u002F10.ef-core\u002Fimplementation_plan",{"title":651,"icon":652,"path":653,"stem":654,"children":655,"page":59},"ASP.NET","i-devicon-dotnetcore","\u002Fcsharp\u002Faspnet","01.csharp\u002F11.aspnet",[656,730,791,869,927,941,967,1057,1111,1182,1212,1289,1346],{"title":657,"icon":658,"path":659,"stem":660,"children":661,"page":59},"Minimal API","i-lucide-network","\u002Fcsharp\u002Faspnet\u002Fminimal-api","01.csharp\u002F11.aspnet\u002F01.minimal-api",[662,666,670,674,678,682,686,690,694,698,702,706,710,714,718,722,726],{"title":663,"path":664,"stem":665},"Вступ до ASP.NET та еволюція фреймворку","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Fintroduction","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F01.introduction",{"title":667,"path":668,"stem":669},"Перший додаток на ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Ffirst-application","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F02.first-application",{"title":671,"path":672,"stem":673},"WebApplication, Builder та Dependency Injection","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Fwebapplication-builder","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F03.webapplication-builder",{"title":675,"path":676,"stem":677},"Конвеєр запитів та Middleware","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Frequest-pipeline-middleware","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F04.request-pipeline-middleware",{"title":679,"path":680,"stem":681},"Маршрутизація в ASP.NET Core: Основи","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Frouting-basics","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F05.routing-basics",{"title":683,"path":684,"stem":685},"Маршрутизація в ASP.NET Core: Розширені можливості","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Frouting-advanced","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F06.routing-advanced",{"title":687,"path":688,"stem":689},"Статичні файли в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Fstatic-files","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F07.static-files",{"title":691,"path":692,"stem":693},"Статичні Активи: MapStaticAssets (ASP.NET Core 9.0)","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Fstatic-assets","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F08.static-assets",{"title":695,"path":696,"stem":697},"Конфігурація в ASP.NET Core: Основи","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Fconfiguration-fundamentals","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F09.configuration-fundamentals",{"title":699,"path":700,"stem":701},"Конфігурація: Паттерн Options","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Fconfiguration-options","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F10.configuration-options",{"title":703,"path":704,"stem":705},"Логування в ASP.NET Core: Основи","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Flogging-basics","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F11.logging-basics",{"title":707,"path":708,"stem":709},"Логування: Serilog та Middleware","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Flogging-advanced","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F12.logging-advanced",{"title":711,"path":712,"stem":713},"Управління станом: HttpContext.Items та Cookies","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Fstate-management","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F13.state-management",{"title":715,"path":716,"stem":717},"Стан сесії: Sessions","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Fsession-state","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F14.session-state",{"title":719,"path":720,"stem":721},"Структура проєкту: від хаосу до архітектури","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Fproject-structure","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F15.project-structure",{"title":723,"path":724,"stem":725},"Scalar у Minimal API: повний проєкт і Fluent OpenAPI","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Fscalar-openapi-fluent","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F16.scalar-openapi-fluent",{"title":727,"path":728,"stem":729},"Swagger \u002F Swashbuckle у Minimal API: окремий класичний шлях","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Fswagger-swashbuckle","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F17.swagger-swashbuckle",{"title":731,"icon":658,"path":732,"stem":733,"children":734,"page":59},"API","\u002Fcsharp\u002Faspnet\u002Fapi","01.csharp\u002F11.aspnet\u002F02.api",[735,739,743,747,751,755,759,763,767,771,775,779,783,787],{"title":736,"path":737,"stem":738},"Що таке API. Клієнт-серверна архітектура","\u002Fcsharp\u002Faspnet\u002Fapi\u002Fwhat-is-api","01.csharp\u002F11.aspnet\u002F02.api\u002F01.what-is-api",{"title":740,"path":741,"stem":742},"Формати даних: JSON, XML, TOML та бінарні формати","\u002Fcsharp\u002Faspnet\u002Fapi\u002Fdata-formats","01.csharp\u002F11.aspnet\u002F02.api\u002F02.data-formats",{"title":744,"path":745,"stem":746},"Парадигми API та концепція REST","\u002Fcsharp\u002Faspnet\u002Fapi\u002Fapi-paradigms-rest","01.csharp\u002F11.aspnet\u002F02.api\u002F03.api-paradigms-rest",{"title":748,"path":749,"stem":750},"HTTP-методи, статус-коди та заголовки","\u002Fcsharp\u002Faspnet\u002Fapi\u002Fhttp-methods-status-codes","01.csharp\u002F11.aspnet\u002F02.api\u002F04.http-methods-status-codes",{"title":752,"path":753,"stem":754},"Організація HTTP API за принципами REST","\u002Fcsharp\u002Faspnet\u002Fapi\u002Frest-organizing","01.csharp\u002F11.aspnet\u002F02.api\u002F05.rest-organizing",{"title":756,"path":757,"stem":758},"Номенклатура URL та CRUD-операції","\u002Fcsharp\u002Faspnet\u002Fapi\u002Furl-nomenclature-crud","01.csharp\u002F11.aspnet\u002F02.api\u002F06.url-nomenclature-crud",{"title":760,"path":761,"stem":762},"Правила дизайну: іменування та стандарти","\u002Fcsharp\u002Faspnet\u002Fapi\u002Fapi-design-naming","01.csharp\u002F11.aspnet\u002F02.api\u002F07.api-design-naming",{"title":764,"path":765,"stem":766},"Валідація, ліміти та обробка помилок","\u002Fcsharp\u002Faspnet\u002Fapi\u002Fapi-design-validation","01.csharp\u002F11.aspnet\u002F02.api\u002F08.api-design-validation",{"title":768,"path":769,"stem":770},"Обробка помилок у Minimal API","\u002Fcsharp\u002Faspnet\u002Fapi\u002Ferror-handling-http","01.csharp\u002F11.aspnet\u002F02.api\u002F09.error-handling-http",{"title":772,"path":773,"stem":774},"Ідемпотентність та синхронізація стану","\u002Fcsharp\u002Faspnet\u002Fapi\u002Fidempotency-sync","01.csharp\u002F11.aspnet\u002F02.api\u002F10.idempotency-sync",{"title":776,"path":777,"stem":778},"Пагінація та організація списків","\u002Fcsharp\u002Faspnet\u002Fapi\u002Fpagination-lists","01.csharp\u002F11.aspnet\u002F02.api\u002F11.pagination-lists",{"title":780,"path":781,"stem":782},"Безпека API, кешування та інтернаціоналізація","\u002Fcsharp\u002Faspnet\u002Fapi\u002Fsecurity-auth","01.csharp\u002F11.aspnet\u002F02.api\u002F12.security-auth",{"title":784,"path":785,"stem":786},"Процес проєктування API та документування","\u002Fcsharp\u002Faspnet\u002Fapi\u002Fapi-design-process","01.csharp\u002F11.aspnet\u002F02.api\u002F13.api-design-process",{"title":788,"path":789,"stem":790},"OpenAPI: контракт, специфікація та документація API","\u002Fcsharp\u002Faspnet\u002Fapi\u002Fopenapi","01.csharp\u002F11.aspnet\u002F02.api\u002F14.openapi",{"title":792,"icon":793,"path":794,"stem":795,"children":796,"page":59},"Auth","i-lucide-shield-check","\u002Fcsharp\u002Faspnet\u002Fauth","01.csharp\u002F11.aspnet\u002F03.auth",[797,801,805,809,813,817,821,825,829,833,837,841,845,849,853,857,861,865],{"title":798,"path":799,"stem":800},"Основи аутентифікації та авторизації","\u002Fcsharp\u002Faspnet\u002Fauth\u002Fauth-fundamentals","01.csharp\u002F11.aspnet\u002F03.auth\u002F01.auth-fundamentals",{"title":802,"path":803,"stem":804},"JWT-аутентифікація","\u002Fcsharp\u002Faspnet\u002Fauth\u002Fjwt-authentication","01.csharp\u002F11.aspnet\u002F03.auth\u002F02.jwt-authentication",{"title":806,"path":807,"stem":808},"Авторизація: ролі, політики та resource-based доступ","\u002Fcsharp\u002Faspnet\u002Fauth\u002Fauthorization-policies","01.csharp\u002F11.aspnet\u002F03.auth\u002F03.authorization-policies",{"title":810,"path":811,"stem":812},"Cookie-аутентифікація та ASP.NET Core Identity","\u002Fcsharp\u002Faspnet\u002Fauth\u002Fcookie-auth-identity","01.csharp\u002F11.aspnet\u002F03.auth\u002F04.cookie-auth-identity",{"title":814,"path":815,"stem":816},"JWT + Refresh Tokens (HttpOnly Cookie)","\u002Fcsharp\u002Faspnet\u002Fauth\u002F04b.identity-auth-jwt","01.csharp\u002F11.aspnet\u002F03.auth\u002F04b.identity-auth-jwt",{"title":818,"path":819,"stem":820},"Identity: Підтвердження Email та Скидання Пароля","\u002Fcsharp\u002Faspnet\u002Fauth\u002Fidentity-email-confirmation","01.csharp\u002F11.aspnet\u002F03.auth\u002F05.identity-email-confirmation",{"title":822,"path":823,"stem":824},"Identity: Двофакторна Аутентифікація (2FA)","\u002Fcsharp\u002Faspnet\u002Fauth\u002Fidentity-two-factor","01.csharp\u002F11.aspnet\u002F03.auth\u002F06.identity-two-factor",{"title":826,"path":827,"stem":828},"Identity: Внутрішня Архітектура та Кастомізація","\u002Fcsharp\u002Faspnet\u002Fauth\u002Fidentity-internals","01.csharp\u002F11.aspnet\u002F03.auth\u002F07.identity-internals",{"title":830,"path":831,"stem":832},"OAuth 2.0 та зовнішні провайдери","\u002Fcsharp\u002Faspnet\u002Fauth\u002Foauth-external-providers","01.csharp\u002F11.aspnet\u002F03.auth\u002F08.oauth-external-providers",{"title":834,"path":835,"stem":836},"Безпека на практиці: CORS, HTTPS та захист від атак","\u002Fcsharp\u002Faspnet\u002Fauth\u002Fsecurity-hardening","01.csharp\u002F11.aspnet\u002F03.auth\u002F09.security-hardening",{"title":838,"path":839,"stem":840},"Теорія OAuth 2.0: Поняття, Аналогії та Флоу","\u002Fcsharp\u002Faspnet\u002Fauth\u002Foauth-theory","01.csharp\u002F11.aspnet\u002F03.auth\u002F10.oauth-theory",{"title":842,"path":843,"stem":844},"OIDC, OAuth 2.0 та Keycloak в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Fauth\u002Foidc-keycloak","01.csharp\u002F11.aspnet\u002F03.auth\u002F10.oidc-keycloak",{"title":846,"path":847,"stem":848},"API Keys аутентифікація в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Fauth\u002Fapi-keys","01.csharp\u002F11.aspnet\u002F03.auth\u002F11.api-keys",{"title":850,"path":851,"stem":852},"Rate Limiting та Throttling в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Fauth\u002Frate-limiting","01.csharp\u002F11.aspnet\u002F03.auth\u002F12.rate-limiting",{"title":854,"path":855,"stem":856},"Refresh Token Rotation в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Fauth\u002Frefresh-token-rotation","01.csharp\u002F11.aspnet\u002F03.auth\u002F13.refresh-token-rotation",{"title":858,"path":859,"stem":860},"Certificate Authentication та mTLS в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Fauth\u002Fcertificate-auth","01.csharp\u002F11.aspnet\u002F03.auth\u002F14.certificate-auth",{"title":862,"path":863,"stem":864},"RBAC, ABAC та ReBAC в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Fauth\u002Frbac-abac-rebac","01.csharp\u002F11.aspnet\u002F03.auth\u002F15.rbac-abac-rebac",{"title":866,"path":867,"stem":868},"Multi-tenancy та ізоляція даних в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Fauth\u002Fmulti-tenancy","01.csharp\u002F11.aspnet\u002F03.auth\u002F16.multi-tenancy",{"title":870,"icon":871,"path":872,"stem":873,"children":874,"page":59},"Нотифікації","i-lucide-bell","\u002Fcsharp\u002Faspnet\u002Fnotifications","01.csharp\u002F11.aspnet\u002F04.notifications",[875,879,883,887,891,895,899,903,907,911,915,919,923],{"title":876,"path":877,"stem":878},"In-App нотифікації через базу даних","\u002Fcsharp\u002Faspnet\u002Fnotifications\u002Fin-app-database-notifications","01.csharp\u002F11.aspnet\u002F04.notifications\u002F01.in-app-database-notifications",{"title":880,"path":881,"stem":882},"Polling: Регулярний запит оновлень","\u002Fcsharp\u002Faspnet\u002Fnotifications\u002Fpolling","01.csharp\u002F11.aspnet\u002F04.notifications\u002F02.polling",{"title":884,"path":885,"stem":886},"Server-Sent Events: Однострімовий push від сервера","\u002Fcsharp\u002Faspnet\u002Fnotifications\u002Fserver-sent-events","01.csharp\u002F11.aspnet\u002F04.notifications\u002F03.server-sent-events",{"title":888,"path":889,"stem":890},"WebSockets: Двостороннє з'єднання в реальному часі","\u002Fcsharp\u002Faspnet\u002Fnotifications\u002Fwebsockets","01.csharp\u002F11.aspnet\u002F04.notifications\u002F04.websockets",{"title":892,"path":893,"stem":894},"SignalR: Абстракція над транспортами реального часу","\u002Fcsharp\u002Faspnet\u002Fnotifications\u002Fsignalr","01.csharp\u002F11.aspnet\u002F04.notifications\u002F05.signalr",{"title":896,"path":897,"stem":898},"Background Services: Фонові задачі в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Fnotifications\u002Fbackground-services","01.csharp\u002F11.aspnet\u002F04.notifications\u002F06.background-services",{"title":900,"path":901,"stem":902},"Web Push нотифікації","\u002Fcsharp\u002Faspnet\u002Fnotifications\u002Fweb-push","01.csharp\u002F11.aspnet\u002F04.notifications\u002F07.web-push",{"title":904,"path":905,"stem":906},"Email нотифікації","\u002Fcsharp\u002Faspnet\u002Fnotifications\u002Femail-notifications","01.csharp\u002F11.aspnet\u002F04.notifications\u002F08.email-notifications",{"title":908,"path":909,"stem":910},"Порівняння підходів: Як вибрати правильну технологію нотифікацій","\u002Fcsharp\u002Faspnet\u002Fnotifications\u002Fchoosing-the-right-approach","01.csharp\u002F11.aspnet\u002F04.notifications\u002F09.choosing-the-right-approach",{"title":912,"path":913,"stem":914},"Hangfire: Надійне планування фонових задач","\u002Fcsharp\u002Faspnet\u002Fnotifications\u002Fhangfire","01.csharp\u002F11.aspnet\u002F04.notifications\u002F10.hangfire",{"title":916,"path":917,"stem":918},"Практика: Конвертація зображень у WebP через Hangfire","\u002Fcsharp\u002Faspnet\u002Fnotifications\u002Fhangfire-image-webp","01.csharp\u002F11.aspnet\u002F04.notifications\u002F11.hangfire-image-webp",{"title":920,"path":921,"stem":922},"Практика: Підготовка відео до HLS-стрімінгу через Hangfire","\u002Fcsharp\u002Faspnet\u002Fnotifications\u002Fhangfire-video-hls","01.csharp\u002F11.aspnet\u002F04.notifications\u002F12.hangfire-video-hls",{"title":924,"path":925,"stem":926},"Telegram-нотифікації: від одного повідомлення до масових розсилок і мульти-канального підходу","\u002Fcsharp\u002Faspnet\u002Fnotifications\u002Ftelegram-notifications","01.csharp\u002F11.aspnet\u002F04.notifications\u002F13.telegram-notifications",{"title":928,"icon":929,"path":930,"stem":931,"children":932,"page":59},"Інтернаціоналізація","i-lucide-languages","\u002Fcsharp\u002Faspnet\u002Fi18n","01.csharp\u002F11.aspnet\u002F05.i18n",[933,937],{"title":934,"path":935,"stem":936},"Інтернаціоналізація (i18n) у Minimal API: від A до Я","\u002Fcsharp\u002Faspnet\u002Fi18n\u002Finternationalization","01.csharp\u002F11.aspnet\u002F05.i18n\u002F01.internationalization",{"title":938,"path":939,"stem":940},"Humanizer: людиномовні рядки у .NET","\u002Fcsharp\u002Faspnet\u002Fi18n\u002Fhumanizer","01.csharp\u002F11.aspnet\u002F05.i18n\u002F02.humanizer",{"title":942,"icon":943,"path":944,"stem":945,"children":946,"page":59},"Кешування","i-lucide-layers","\u002Fcsharp\u002Faspnet\u002Fcaching","01.csharp\u002F11.aspnet\u002F06.caching",[947,951,955,959,963],{"title":948,"path":949,"stem":950},"Огляд кешування: чотири рівні і коли що обирати","\u002Fcsharp\u002Faspnet\u002Fcaching\u002Fcaching","01.csharp\u002F11.aspnet\u002F06.caching\u002F01.caching",{"title":952,"path":953,"stem":954},"IMemoryCache: кеш в оперативній пам'яті","\u002Fcsharp\u002Faspnet\u002Fcaching\u002Fmemory-cache","01.csharp\u002F11.aspnet\u002F06.caching\u002F02.memory-cache",{"title":956,"path":957,"stem":958},"IDistributedCache і Redis: розподілений кеш","\u002Fcsharp\u002Faspnet\u002Fcaching\u002Fdistributed-cache","01.csharp\u002F11.aspnet\u002F06.caching\u002F03.distributed-cache",{"title":960,"path":961,"stem":962},"Response Cache: HTTP-кешування через Cache-Control","\u002Fcsharp\u002Faspnet\u002Fcaching\u002Fresponse-cache","01.csharp\u002F11.aspnet\u002F06.caching\u002F04.response-cache",{"title":964,"path":965,"stem":966},"Output Cache: серверний кеш HTTP-відповідей (.NET 7+)","\u002Fcsharp\u002Faspnet\u002Fcaching\u002Foutput-cache","01.csharp\u002F11.aspnet\u002F06.caching\u002F05.output-cache",{"title":968,"icon":969,"path":970,"stem":971,"children":972,"page":59},"Тестування","i-lucide-test-tube","\u002Fcsharp\u002Faspnet\u002Ftesting","01.csharp\u002F11.aspnet\u002F07.testing",[973,977,981,985,989,993,997,1001,1005,1009,1013,1017,1021,1025,1029,1033,1037,1041,1045,1049,1053],{"title":974,"path":975,"stem":976},"Що таке тестування? Від інтуїції до науки","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Fwhat-is-testing","01.csharp\u002F11.aspnet\u002F07.testing\u002F01.what-is-testing",{"title":978,"path":979,"stem":980},"Піраміда тестування — Стратегія, а не Догма","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Ftesting-pyramid","01.csharp\u002F11.aspnet\u002F07.testing\u002F02.testing-pyramid",{"title":982,"path":983,"stem":984},"Дві Школи Тестування — Лондон проти Детройту","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Ftesting-schools","01.csharp\u002F11.aspnet\u002F07.testing\u002F03.testing-schools",{"title":986,"path":987,"stem":988},"TDD та BDD — Тести як Дизайн-інструмент","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Ftdd-and-bdd","01.csharp\u002F11.aspnet\u002F07.testing\u002F04.tdd-and-bdd",{"title":990,"path":991,"stem":992},"Що саме тестувати — Техніки аналізу та Циклomatична складність","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Fwhat-to-test","01.csharp\u002F11.aspnet\u002F07.testing\u002F05.what-to-test",{"title":994,"path":995,"stem":996},"Тестові Фреймворки — Навіщо вони і що всередині","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Ftest-frameworks","01.csharp\u002F11.aspnet\u002F07.testing\u002F06.test-frameworks",{"title":998,"path":999,"stem":1000},"xUnit — Факти, Теорії та Lifecycle тестів","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Fxunit-basics","01.csharp\u002F11.aspnet\u002F07.testing\u002F07.xunit-basics",{"title":1002,"path":1003,"stem":1004},"xUnit Advanced — Fixtures, Кастомізація та Розширення","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Fxunit-advanced","01.csharp\u002F11.aspnet\u002F07.testing\u002F08.xunit-advanced",{"title":1006,"path":1007,"stem":1008},"Moq — Глибоке занурення в мокування","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Fmocking-with-moq","01.csharp\u002F11.aspnet\u002F07.testing\u002F09.mocking-with-moq",{"title":1010,"path":1011,"stem":1012},"Тестування Баз Даних — EF Core, SQLite та Testcontainers","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Fdatabase-testing","01.csharp\u002F11.aspnet\u002F07.testing\u002F10.database-testing",{"title":1014,"path":1015,"stem":1016},"Integration Testing — Частина 1 [Теорія та WebApplicationFactory]","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Fintegration-testing","01.csharp\u002F11.aspnet\u002F07.testing\u002F11.integration-testing",{"title":1018,"path":1019,"stem":1020},"Інтеграційне тестування — Практика","\u002Fcsharp\u002Faspnet\u002Ftesting\u002F11a.integration-testing-practice","01.csharp\u002F11.aspnet\u002F07.testing\u002F11a.integration-testing-practice",{"title":1022,"path":1023,"stem":1024},"Integration Testing — Частина 2 [Просунуті Сценарії та Testcontainers]","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Fintegration-testing-advanced","01.csharp\u002F11.aspnet\u002F07.testing\u002F12.integration-testing-advanced",{"title":1026,"path":1027,"stem":1028},"Професійний Postman: Колекції, Змінні та GitHub Інтеграція","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Fpostman-professional","01.csharp\u002F11.aspnet\u002F07.testing\u002F13.postman-professional",{"title":1030,"path":1031,"stem":1032},"HttpClient у Тестах Частина 1: Архітектура та MockHttpMessageHandler","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Fhttpclient-testing","01.csharp\u002F11.aspnet\u002F07.testing\u002F14.httpclient-testing",{"title":1034,"path":1035,"stem":1036},"HttpClient у Тестах Частина 2: WireMock.Net та Resilience","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Fwiremock-net","01.csharp\u002F11.aspnet\u002F07.testing\u002F15.wiremock-net",{"title":1038,"path":1039,"stem":1040},"Патерни та Анти-патерни Тестування: Test Smells","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Ftesting-patterns","01.csharp\u002F11.aspnet\u002F07.testing\u002F16.testing-patterns",{"title":1042,"path":1043,"stem":1044},"Просунуті інструменти: Time, Snapshots та Властивості","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Fadvanced-testing-tools","01.csharp\u002F11.aspnet\u002F07.testing\u002F17.advanced-testing-tools",{"title":1046,"path":1047,"stem":1048},"Тестування Архітектури з NetArchTest","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Farchitecture-testing","01.csharp\u002F11.aspnet\u002F07.testing\u002F18.architecture-testing",{"title":1050,"path":1051,"stem":1052},"Тестування Продуктивності: BenchmarkDotNet, NBomber та k6","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Fperformance-testing","01.csharp\u002F11.aspnet\u002F07.testing\u002F19.performance-testing",{"title":1054,"path":1055,"stem":1056},"Залишок плану для курсу \"Тестування ASP.NET Minimal API\"","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Fremaining_plan","01.csharp\u002F11.aspnet\u002F07.testing\u002Fremaining_plan",{"title":1058,"icon":1059,"path":1060,"stem":1061,"children":1062,"page":59},"Платежі","i-lucide-credit-card","\u002Fcsharp\u002Faspnet\u002Fpayments","01.csharp\u002F11.aspnet\u002F08.payments",[1063,1067,1071,1075,1079,1083,1087,1091,1095,1099,1103,1107],{"title":1064,"path":1065,"stem":1066},"Основи платіжної інфраструктури","\u002Fcsharp\u002Faspnet\u002Fpayments\u002Fpayment-fundamentals","01.csharp\u002F11.aspnet\u002F08.payments\u002F01.payment-fundamentals",{"title":1068,"path":1069,"stem":1070},"Методи оплати в Україні","\u002Fcsharp\u002Faspnet\u002Fpayments\u002Fpayment-methods-ukraine","01.csharp\u002F11.aspnet\u002F08.payments\u002F02.payment-methods-ukraine",{"title":1072,"path":1073,"stem":1074},"PCI DSS та безпека платежів","\u002Fcsharp\u002Faspnet\u002Fpayments\u002Fpci-dss-security","01.csharp\u002F11.aspnet\u002F08.payments\u002F03.pci-dss-security",{"title":1076,"path":1077,"stem":1078},"Архітектура платіжної підсистеми","\u002Fcsharp\u002Faspnet\u002Fpayments\u002Fpayment-architecture","01.csharp\u002F11.aspnet\u002F08.payments\u002F04.payment-architecture",{"title":1080,"path":1081,"stem":1082},"Інтеграція LiqPay (ПриватБанк)","\u002Fcsharp\u002Faspnet\u002Fpayments\u002Fliqpay-integration","01.csharp\u002F11.aspnet\u002F08.payments\u002F05.liqpay-integration",{"title":1084,"path":1085,"stem":1086},"Інтеграція Monobank Acquiring API","\u002Fcsharp\u002Faspnet\u002Fpayments\u002Fmonobank-acquiring","01.csharp\u002F11.aspnet\u002F08.payments\u002F06.monobank-acquiring",{"title":1088,"path":1089,"stem":1090},"Інтеграція Stripe","\u002Fcsharp\u002Faspnet\u002Fpayments\u002Fstripe-integration","01.csharp\u002F11.aspnet\u002F08.payments\u002F07.stripe-integration",{"title":1092,"path":1093,"stem":1094},"Webhooks — глибоке занурення","\u002Fcsharp\u002Faspnet\u002Fpayments\u002Fwebhooks-deep-dive","01.csharp\u002F11.aspnet\u002F08.payments\u002F08.webhooks-deep-dive",{"title":1096,"path":1097,"stem":1098},"Підписки та рекурентні платежі","\u002Fcsharp\u002Faspnet\u002Fpayments\u002Fsubscriptions-recurring","01.csharp\u002F11.aspnet\u002F08.payments\u002F09.subscriptions-recurring",{"title":1100,"path":1101,"stem":1102},"Повернення коштів та диспути","\u002Fcsharp\u002Faspnet\u002Fpayments\u002Frefunds-disputes","01.csharp\u002F11.aspnet\u002F08.payments\u002F10.refunds-disputes",{"title":1104,"path":1105,"stem":1106},"Тестування платіжних інтеграцій","\u002Fcsharp\u002Faspnet\u002Fpayments\u002Ftesting-payments","01.csharp\u002F11.aspnet\u002F08.payments\u002F11.testing-payments",{"title":1108,"path":1109,"stem":1110},"Чекліст виходу в Production","\u002Fcsharp\u002Faspnet\u002Fpayments\u002Fproduction-checklist","01.csharp\u002F11.aspnet\u002F08.payments\u002F12.production-checklist",{"title":1112,"icon":1113,"items":1114,"path":1127,"stem":1128,"children":1129,"page":59},"Популярні бібліотеки","lucide:box",[1115,1116,1117,1118,1119,1120,1121,1122,1123,1124,1125,1126],"01.fluent-validation","02.mapster","03.erroror-result-pattern","04.serilog","05.mediatr","06.polly","07.health-checks","08.feature-management","09.fluent-email","10.quest-pdf","11.bogus","12.humanizer-guard","\u002Fcsharp\u002Faspnet\u002Flibraries","01.csharp\u002F11.aspnet\u002F09.libraries",[1130,1134,1138,1142,1146,1150,1154,1158,1162,1166,1170,1174,1178],{"title":1131,"path":1132,"stem":1133},"Валідація з FluentValidation в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Flibraries\u002Ffluent-validation","01.csharp\u002F11.aspnet\u002F09.libraries\u002F01.fluent-validation",{"title":1135,"path":1136,"stem":1137},"Маппінг об","\u002Fcsharp\u002Faspnet\u002Flibraries\u002Fmapster","01.csharp\u002F11.aspnet\u002F09.libraries\u002F02.mapster",{"title":1139,"path":1140,"stem":1141},"Обробка помилок з ErrorOr та Result Pattern в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Flibraries\u002Ferroror-result-pattern","01.csharp\u002F11.aspnet\u002F09.libraries\u002F03.erroror-result-pattern",{"title":1143,"path":1144,"stem":1145},"Структуроване логування з Serilog в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Flibraries\u002Fserilog","01.csharp\u002F11.aspnet\u002F09.libraries\u002F04.serilog",{"title":1147,"path":1148,"stem":1149},"CQRS та Mediator з MediatR в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Flibraries\u002Fmediatr","01.csharp\u002F11.aspnet\u002F09.libraries\u002F05.mediatr",{"title":1151,"path":1152,"stem":1153},"Відмовостійкість з Polly в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Flibraries\u002Fpolly","01.csharp\u002F11.aspnet\u002F09.libraries\u002F06.polly",{"title":1155,"path":1156,"stem":1157},"Health Checks в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Flibraries\u002Fhealth-checks","01.csharp\u002F11.aspnet\u002F09.libraries\u002F07.health-checks",{"title":1159,"path":1160,"stem":1161},"Feature Management та Feature Flags в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Flibraries\u002Ffeature-management","01.csharp\u002F11.aspnet\u002F09.libraries\u002F08.feature-management",{"title":1163,"path":1164,"stem":1165},"Відправка Email з FluentEmail в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Flibraries\u002Ffluent-email","01.csharp\u002F11.aspnet\u002F09.libraries\u002F09.fluent-email",{"title":1167,"path":1168,"stem":1169},"Генерація PDF з QuestPDF в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Flibraries\u002Fquest-pdf","01.csharp\u002F11.aspnet\u002F09.libraries\u002F10.quest-pdf",{"title":1171,"path":1172,"stem":1173},"Генерація тестових даних з Bogus в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Flibraries\u002Fbogus","01.csharp\u002F11.aspnet\u002F09.libraries\u002F11.bogus",{"title":1175,"path":1176,"stem":1177},"Humanizer та Guard Clauses в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Flibraries\u002Fhumanizer-guard","01.csharp\u002F11.aspnet\u002F09.libraries\u002F12.humanizer-guard",{"title":1179,"path":1180,"stem":1181},"План модуля 10.libraries — Популярні бібліотеки ASP.NET","\u002Fcsharp\u002Faspnet\u002Flibraries\u002Fplan","01.csharp\u002F11.aspnet\u002F09.libraries\u002Fplan",{"title":1183,"icon":1184,"path":1185,"stem":1186,"children":1187,"page":59},"Razor Pages","i-lucide-layout-template","\u002Fcsharp\u002Faspnet\u002Frazor-pages","01.csharp\u002F11.aspnet\u002F10.razor-pages",[1188,1192,1196,1200,1204,1208],{"title":1189,"path":1190,"stem":1191},"Від Minimal API до Razor Pages: концептуальний перехід","\u002Fcsharp\u002Faspnet\u002Frazor-pages\u002Ffrom-minimal-api","01.csharp\u002F11.aspnet\u002F10.razor-pages\u002F01.from-minimal-api",{"title":1193,"path":1194,"stem":1195},"PageModel: логіка сторінки Razor Pages","\u002Fcsharp\u002Faspnet\u002Frazor-pages\u002Fpage-model","01.csharp\u002F11.aspnet\u002F10.razor-pages\u002F02.page-model",{"title":1197,"path":1198,"stem":1199},"Razor синтаксис: шаблонізатор у .cshtml","\u002Fcsharp\u002Faspnet\u002Frazor-pages\u002Frazor-syntax","01.csharp\u002F11.aspnet\u002F10.razor-pages\u002F03.razor-syntax",{"title":1201,"path":1202,"stem":1203},"Tag Helpers: типізований HTML","\u002Fcsharp\u002Faspnet\u002Frazor-pages\u002Ftag-helpers","01.csharp\u002F11.aspnet\u002F10.razor-pages\u002F04.tag-helpers",{"title":1205,"path":1206,"stem":1207},"Форми і валідація: повний цикл обробки даних","\u002Fcsharp\u002Faspnet\u002Frazor-pages\u002Fforms-validation","01.csharp\u002F11.aspnet\u002F10.razor-pages\u002F05.forms-validation",{"title":1209,"path":1210,"stem":1211},"Практичний проєкт: TaskManager на Razor Pages","\u002Fcsharp\u002Faspnet\u002Frazor-pages\u002Fproject-task-manager","01.csharp\u002F11.aspnet\u002F10.razor-pages\u002F06.project-task-manager",{"title":1213,"path":1214,"stem":1215,"children":1216,"page":59},"ASP.NET Core MVC","\u002Fcsharp\u002Faspnet\u002Fmvc","01.csharp\u002F11.aspnet\u002F11.mvc",[1217,1221,1225,1229,1233,1237,1241,1245,1249,1253,1257,1261,1265,1269,1273,1277,1281,1285],{"title":1218,"path":1219,"stem":1220},"Патерн MVC: архітектура, що змінила веб","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Fmvc-pattern","01.csharp\u002F11.aspnet\u002F11.mvc\u002F01.mvc-pattern",{"title":1222,"path":1223,"stem":1224},"Від Razor Pages до MVC: концептуальний перехід","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Ffrom-razor-pages","01.csharp\u002F11.aspnet\u002F11.mvc\u002F02.from-razor-pages",{"title":1226,"path":1227,"stem":1228},"Controllers та Actions: серце MVC","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Fcontrollers-actions","01.csharp\u002F11.aspnet\u002F11.mvc\u002F03.controllers-actions",{"title":1230,"path":1231,"stem":1232},"Маршрутизація в MVC: Convention vs Attribute Routing","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Frouting-mvc","01.csharp\u002F11.aspnet\u002F11.mvc\u002F04.routing-mvc",{"title":1234,"path":1235,"stem":1236},"Model Binding: від HTTP до C#","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Fmodel-binding","01.csharp\u002F11.aspnet\u002F11.mvc\u002F05.model-binding",{"title":1238,"path":1239,"stem":1240},"Views, ViewData, ViewBag, TempData і ViewModel","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Fviews-viewdata-tempdata","01.csharp\u002F11.aspnet\u002F11.mvc\u002F06.views-viewdata-tempdata",{"title":1242,"path":1243,"stem":1244},"Filters: аспектно-орієнтоване програмування в MVC","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Ffilters","01.csharp\u002F11.aspnet\u002F11.mvc\u002F07.filters",{"title":1246,"path":1247,"stem":1248},"Areas: структурування великих застосунків","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Fareas","01.csharp\u002F11.aspnet\u002F11.mvc\u002F08.areas",{"title":1250,"path":1251,"stem":1252},"View Components: повторювані незалежні блоки UI","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Fview-components","01.csharp\u002F11.aspnet\u002F11.mvc\u002F09.view-components",{"title":1254,"path":1255,"stem":1256},"Display та Editor Templates","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Fdisplay-editor-templates","01.csharp\u002F11.aspnet\u002F11.mvc\u002F10.display-editor-templates",{"title":1258,"path":1259,"stem":1260},"Валідація: IValidatableObject та FluentValidation","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Fvalidation-advanced","01.csharp\u002F11.aspnet\u002F11.mvc\u002F11.validation-advanced",{"title":1262,"path":1263,"stem":1264},"HTMX: інтерактивність через HTML-атрибути","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Fhtmx","01.csharp\u002F11.aspnet\u002F11.mvc\u002F12.htmx",{"title":1266,"path":1267,"stem":1268},"HTMX у ASP.NET Core MVC: серверна інтеграція","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Fajax-htmx-mvc","01.csharp\u002F11.aspnet\u002F11.mvc\u002F13.ajax-htmx-mvc",{"title":1270,"path":1271,"stem":1272},"Практичний проєкт: Каталог товарів з HTMX","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Fhtmx-project","01.csharp\u002F11.aspnet\u002F11.mvc\u002F14.htmx-project",{"title":1274,"path":1275,"stem":1276},"Завантаження та обробка файлів","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Ffile-upload","01.csharp\u002F11.aspnet\u002F11.mvc\u002F15.file-upload",{"title":1278,"path":1279,"stem":1280},"Глобалізація та Локалізація MVC","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Fglobalization-localization","01.csharp\u002F11.aspnet\u002F11.mvc\u002F16.globalization-localization",{"title":1282,"path":1283,"stem":1284},"Підсумковий проєкт: Блог-платформа","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Fmvc-project","01.csharp\u002F11.aspnet\u002F11.mvc\u002F17.mvc-project",{"title":1286,"path":1287,"stem":1288},"План курсу: ASP.NET Core MVC","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Fplan","01.csharp\u002F11.aspnet\u002F11.mvc\u002Fplan",{"title":1290,"path":1291,"stem":1292,"children":1293,"page":59},"Web Api","\u002Fcsharp\u002Faspnet\u002Fweb-api","01.csharp\u002F11.aspnet\u002F12.web-api",[1294,1298,1302,1306,1310,1314,1318,1322,1326,1330,1334,1338,1342],{"title":1295,"path":1296,"stem":1297},"Від Minimal API до Controller-based API","\u002Fcsharp\u002Faspnet\u002Fweb-api\u002Ffrom-minimal-api-to-controllers","01.csharp\u002F11.aspnet\u002F12.web-api\u002F01.from-minimal-api-to-controllers",{"title":1299,"path":1300,"stem":1301},"ControllerBase, ActionResult\u003CT> та Response Types","\u002Fcsharp\u002Faspnet\u002Fweb-api\u002Fcontroller-base-actionresult","01.csharp\u002F11.aspnet\u002F12.web-api\u002F02.controller-base-actionresult",{"title":1303,"path":1304,"stem":1305},"Content Negotiation - JSON, XML та власні форматери","\u002Fcsharp\u002Faspnet\u002Fweb-api\u002Fcontent-negotiation","01.csharp\u002F11.aspnet\u002F12.web-api\u002F03.content-negotiation",{"title":1307,"path":1308,"stem":1309},"Версіонування API","\u002Fcsharp\u002Faspnet\u002Fweb-api\u002Fapi-versioning","01.csharp\u002F11.aspnet\u002F12.web-api\u002F04.api-versioning",{"title":1311,"path":1312,"stem":1313},"ProblemDetails та структурована обробка помилок","\u002Fcsharp\u002Faspnet\u002Fweb-api\u002Fproblemdetails-error-handling","01.csharp\u002F11.aspnet\u002F12.web-api\u002F05.problemdetails-error-handling",{"title":1315,"path":1316,"stem":1317},"Фільтри у Web API контексті","\u002Fcsharp\u002Faspnet\u002Fweb-api\u002Ffilters-for-api","01.csharp\u002F11.aspnet\u002F12.web-api\u002F06.filters-for-api",{"title":1319,"path":1320,"stem":1321},"Пагінація, фільтрація та сортування","\u002Fcsharp\u002Faspnet\u002Fweb-api\u002Fpagination-filtering-sorting","01.csharp\u002F11.aspnet\u002F12.web-api\u002F07.pagination-filtering-sorting",{"title":1323,"path":1324,"stem":1325},"HATEOAS та Resource Expansion","\u002Fcsharp\u002Faspnet\u002Fweb-api\u002Fhateoas-resource-expansion","01.csharp\u002F11.aspnet\u002F12.web-api\u002F08.hateoas-resource-expansion",{"title":1327,"path":1328,"stem":1329},"Гібридна архітектура - Minimal API + Controllers","\u002Fcsharp\u002Faspnet\u002Fweb-api\u002Fminimal-api-vs-controllers-hybrid","01.csharp\u002F11.aspnet\u002F12.web-api\u002F09.minimal-api-vs-controllers-hybrid",{"title":1331,"path":1332,"stem":1333},"Документація API - Swashbuckle, NSwag та генерація клієнтів","\u002Fcsharp\u002Faspnet\u002Fweb-api\u002Fapi-documentation-generation","01.csharp\u002F11.aspnet\u002F12.web-api\u002F10.api-documentation-generation",{"title":1335,"path":1336,"stem":1337},"Health Checks та моніторинг API","\u002Fcsharp\u002Faspnet\u002Fweb-api\u002Fhealth-checks-monitoring","01.csharp\u002F11.aspnet\u002F12.web-api\u002F11.health-checks-monitoring",{"title":1339,"path":1340,"stem":1341},"Підсумковий проєкт - Production-Ready REST API","\u002Fcsharp\u002Faspnet\u002Fweb-api\u002Fweb-api-project","01.csharp\u002F11.aspnet\u002F12.web-api\u002F12.web-api-project",{"title":1343,"path":1344,"stem":1345},"План курсу: ASP.NET Core Web API (Controllers)","\u002Fcsharp\u002Faspnet\u002Fweb-api\u002Fplan","01.csharp\u002F11.aspnet\u002F12.web-api\u002Fplan",{"title":1347,"icon":1348,"path":1349,"stem":1350,"children":1351,"page":59},"Моніторинг","i-lucide-activity","\u002Fcsharp\u002Faspnet\u002Fmonitoring","01.csharp\u002F11.aspnet\u002F13.monitoring",[1352,1356,1360],{"title":1353,"path":1354,"stem":1355},"Спостережуваність: від console.log до production-систем","\u002Fcsharp\u002Faspnet\u002Fmonitoring\u002Fobservability-intro","01.csharp\u002F11.aspnet\u002F13.monitoring\u002F01.observability-intro",{"title":1357,"path":1358,"stem":1359},"Health Checks: перший рівень observability","\u002Fcsharp\u002Faspnet\u002Fmonitoring\u002Fhealth-checks","01.csharp\u002F11.aspnet\u002F13.monitoring\u002F02.health-checks",{"title":1361,"path":1362,"stem":1363},"Вбудовані метрики .NET 10 та System.Diagnostics.Metrics","\u002Fcsharp\u002Faspnet\u002Fmonitoring\u002Fdotnet-metrics","01.csharp\u002F11.aspnet\u002F13.monitoring\u002F03.dotnet-metrics",{"title":1365,"icon":1366,"path":1367,"stem":1368,"children":1369,"page":59},"Desktop UI","i-lucide-app-window","\u002Fcsharp\u002Fdesktop-ui","01.csharp\u002F12.desktop-ui",[1370,1374,1378,1382,1386,1390,1394,1398,1402,1406,1410,1414,1418,1422,1426,1430,1434,1438,1442,1446,1450,1454,1458,1462,1466,1470,1474,1478,1482,1486,1490,1494,1498,1502,1506,1510,1514,1518,1522,1526,1530,1534,1538,1542,1546,1550,1554,1558,1562,1566,1570,1574,1578,1582,1586,1590,1594,1598,1602,1606,1610,1614,1618,1622,1626,1630,1634,1638,1642,1646,1650],{"title":1371,"path":1372,"stem":1373},"Що таке десктопна розробка?","\u002Fcsharp\u002Fdesktop-ui\u002Fwhat-is-desktop-dev","01.csharp\u002F12.desktop-ui\u002F01.what-is-desktop-dev",{"title":1375,"path":1376,"stem":1377},"Архітектура WPF — як влаштований графічний інтерфейс","\u002Fcsharp\u002Fdesktop-ui\u002Fwpf-architecture","01.csharp\u002F12.desktop-ui\u002F02.wpf-architecture",{"title":1379,"path":1380,"stem":1381},"Перший WPF-проєкт — від нуля до вікна","\u002Fcsharp\u002Fdesktop-ui\u002Ffirst-wpf-app","01.csharp\u002F12.desktop-ui\u002F03.first-wpf-app",{"title":1383,"path":1384,"stem":1385},"Перший Avalonia-проєкт: WPF для всіх платформ","\u002Fcsharp\u002Fdesktop-ui\u002F03a.first-avalonia-app","01.csharp\u002F12.desktop-ui\u002F03a.first-avalonia-app",{"title":1387,"path":1388,"stem":1389},"XAML: декларативний інтерфейс","\u002Fcsharp\u002Fdesktop-ui\u002Fxaml-basics","01.csharp\u002F12.desktop-ui\u002F04.xaml-basics",{"title":1391,"path":1392,"stem":1393},"Fluent UI у WPF — сучасний дизайн Windows 11","\u002Fcsharp\u002Fdesktop-ui\u002F04a.wpf-fluent-ui","01.csharp\u002F12.desktop-ui\u002F04a.wpf-fluent-ui",{"title":1395,"path":1396,"stem":1397},"WPF UI — сучасна бібліотека Fluent контролів","\u002Fcsharp\u002Fdesktop-ui\u002F04b.wpf-ui-library","01.csharp\u002F12.desktop-ui\u002F04b.wpf-ui-library",{"title":1399,"path":1400,"stem":1401},"HandyControl — велика бібліотека UI контролів для WPF","\u002Fcsharp\u002Fdesktop-ui\u002F04c.handycontrol-library","01.csharp\u002F12.desktop-ui\u002F04c.handycontrol-library",{"title":1403,"path":1404,"stem":1405},"Простори імен та ресурси XAML","\u002Fcsharp\u002Fdesktop-ui\u002Fxaml-namespaces-resources","01.csharp\u002F12.desktop-ui\u002F05.xaml-namespaces-resources",{"title":1407,"path":1408,"stem":1409},"XAML в Avalonia: ключові відмінності від WPF","\u002Fcsharp\u002Fdesktop-ui\u002F05a.avalonia-xaml-differences","01.csharp\u002F12.desktop-ui\u002F05a.avalonia-xaml-differences",{"title":1411,"path":1412,"stem":1413},"Розширення розмітки XAML (Markup Extensions)","\u002Fcsharp\u002Fdesktop-ui\u002Fxaml-markup-extensions","01.csharp\u002F12.desktop-ui\u002F06.xaml-markup-extensions",{"title":1415,"path":1416,"stem":1417},"Панелі Layout: StackPanel, WrapPanel, DockPanel","\u002Fcsharp\u002Fdesktop-ui\u002Flayout-panels-part1","01.csharp\u002F12.desktop-ui\u002F07.layout-panels-part1",{"title":1419,"path":1420,"stem":1421},"Grid, Canvas, UniformGrid","\u002Fcsharp\u002Fdesktop-ui\u002Flayout-panels-part2","01.csharp\u002F12.desktop-ui\u002F07.layout-panels-part2",{"title":1423,"path":1424,"stem":1425},"Просунуті техніки Layout","\u002Fcsharp\u002Fdesktop-ui\u002Flayout-advanced","01.csharp\u002F12.desktop-ui\u002F08.layout-advanced",{"title":1427,"path":1428,"stem":1429},"Адаптивний Layout та найкращі практики","\u002Fcsharp\u002Fdesktop-ui\u002Flayout-responsive","01.csharp\u002F12.desktop-ui\u002F09.layout-responsive",{"title":1431,"path":1432,"stem":1433},"Layout в Avalonia: відмінності та нові можливості","\u002Fcsharp\u002Fdesktop-ui\u002F09a.layout-avalonia","01.csharp\u002F12.desktop-ui\u002F09a.layout-avalonia",{"title":1435,"path":1436,"stem":1437},"Button, Image, ProgressBar та інші базові контроли","\u002Fcsharp\u002Fdesktop-ui\u002Fbasic-controls","01.csharp\u002F12.desktop-ui\u002F10.basic-controls",{"title":1439,"path":1440,"stem":1441},"Контроли в Avalonia: відмінності від WPF","\u002Fcsharp\u002Fdesktop-ui\u002F10a.controls-avalonia","01.csharp\u002F12.desktop-ui\u002F10a.controls-avalonia",{"title":1443,"path":1444,"stem":1445},"Текстові контроли — TextBlock, TextBox, RichTextBox","\u002Fcsharp\u002Fdesktop-ui\u002Ftext-controls","01.csharp\u002F12.desktop-ui\u002F11.text-controls",{"title":1447,"path":1448,"stem":1449},"Контроли вибору — CheckBox, RadioButton, ComboBox, ListBox, DatePicker","\u002Fcsharp\u002Fdesktop-ui\u002Fselection-controls","01.csharp\u002F12.desktop-ui\u002F12.selection-controls",{"title":1451,"path":1452,"stem":1453},"Content Model — GroupBox, Expander, TabControl, StatusBar","\u002Fcsharp\u002Fdesktop-ui\u002Fcontent-controls","01.csharp\u002F12.desktop-ui\u002F13.content-controls",{"title":1455,"path":1456,"stem":1457},"UI\u002FUX принципи десктопних застосунків","\u002Fcsharp\u002Fdesktop-ui\u002F13a.ui-ux-principles","01.csharp\u002F12.desktop-ui\u002F13a.ui-ux-principles",{"title":1459,"path":1460,"stem":1461},"Dependency Properties — Концепція та Value Resolution","\u002Fcsharp\u002Fdesktop-ui\u002Fdependency-properties-part1","01.csharp\u002F12.desktop-ui\u002F14.dependency-properties-part1",{"title":1463,"path":1464,"stem":1465},"Avalonia Property System — StyledProperty та DirectProperty","\u002Fcsharp\u002Fdesktop-ui\u002F14a.avalonia-property-system","01.csharp\u002F12.desktop-ui\u002F14a.avalonia-property-system",{"title":1467,"path":1468,"stem":1469},"Attached Properties — Властивості без меж","\u002Fcsharp\u002Fdesktop-ui\u002Fattached-properties","01.csharp\u002F12.desktop-ui\u002F15.attached-properties",{"title":1471,"path":1472,"stem":1473},"Routed Events — Маршрутизація подій у WPF","\u002Fcsharp\u002Fdesktop-ui\u002Frouted-events","01.csharp\u002F12.desktop-ui\u002F16.routed-events",{"title":1475,"path":1476,"stem":1477},"Data Binding — Від Code-Behind до Декларативності","\u002Fcsharp\u002Fdesktop-ui\u002Fdata-binding-basics-part1","01.csharp\u002F12.desktop-ui\u002F17.data-binding-basics-part1",{"title":1479,"path":1480,"stem":1481},"INotifyPropertyChanged — Живе оновлення UI","\u002Fcsharp\u002Fdesktop-ui\u002Fdata-binding-basics-part2","01.csharp\u002F12.desktop-ui\u002F17.data-binding-basics-part2",{"title":1483,"path":1484,"stem":1485},"Compiled Bindings в Avalonia — Безпека на етапі компіляції","\u002Fcsharp\u002Fdesktop-ui\u002F17a.avalonia-compiled-bindings","01.csharp\u002F12.desktop-ui\u002F17a.avalonia-compiled-bindings",{"title":1487,"path":1488,"stem":1489},"Просунутий Data Binding — ElementName, RelativeSource, MultiBinding","\u002Fcsharp\u002Fdesktop-ui\u002Fdata-binding-advanced","01.csharp\u002F12.desktop-ui\u002F18.data-binding-advanced",{"title":1491,"path":1492,"stem":1493},"Value Converters — Перетворення типів даних у Data Binding","\u002Fcsharp\u002Fdesktop-ui\u002Fvalue-converters","01.csharp\u002F12.desktop-ui\u002F19.value-converters",{"title":1495,"path":1496,"stem":1497},"Data Templates — Візуалізація об'єктів у WPF","\u002Fcsharp\u002Fdesktop-ui\u002Fdata-templates","01.csharp\u002F12.desktop-ui\u002F20.data-templates",{"title":1499,"path":1500,"stem":1501},"Collections Binding Part 1 — ObservableCollection та ItemsControl","\u002Fcsharp\u002Fdesktop-ui\u002Fcollections-binding-part1","01.csharp\u002F12.desktop-ui\u002F21.collections-binding-part1",{"title":1503,"path":1504,"stem":1505},"Collections Binding Part 2 — ICollectionView, Filtering, Sorting та Virtualization","\u002Fcsharp\u002Fdesktop-ui\u002Fcollections-binding-part2","01.csharp\u002F12.desktop-ui\u002F21.collections-binding-part2",{"title":1507,"path":1508,"stem":1509},"MVVM Pattern — Від Spaghetti Code до архітектури","\u002Fcsharp\u002Fdesktop-ui\u002Fmvvm-pattern","01.csharp\u002F12.desktop-ui\u002F22.mvvm-pattern",{"title":1511,"path":1512,"stem":1513},"ViewModel Implementation — Від BaseViewModel до валідації","\u002Fcsharp\u002Fdesktop-ui\u002Fviewmodel-implementation","01.csharp\u002F12.desktop-ui\u002F23.viewmodel-implementation",{"title":1515,"path":1516,"stem":1517},"Commands — Від event handlers до декларативних команд","\u002Fcsharp\u002Fdesktop-ui\u002Fcommands","01.csharp\u002F12.desktop-ui\u002F24.commands",{"title":1519,"path":1520,"stem":1521},"MVVM Toolkit — MVVM без boilerplate через Source Generators","\u002Fcsharp\u002Fdesktop-ui\u002Fmvvm-toolkit","01.csharp\u002F12.desktop-ui\u002F25.mvvm-toolkit",{"title":1523,"path":1524,"stem":1525},"Messenger Pattern — Комунікація між ViewModel без прямих посилань","\u002Fcsharp\u002Fdesktop-ui\u002Fmessenger-pattern","01.csharp\u002F12.desktop-ui\u002F26.messenger-pattern",{"title":1527,"path":1528,"stem":1529},"Стилі WPF — CSS для десктопу","\u002Fcsharp\u002Fdesktop-ui\u002Fstyles-basics","01.csharp\u002F12.desktop-ui\u002F27.styles-basics",{"title":1531,"path":1532,"stem":1533},"CSS-like стилі Avalonia","\u002Fcsharp\u002Fdesktop-ui\u002F27a.avalonia-css-styling","01.csharp\u002F12.desktop-ui\u002F27a.avalonia-css-styling",{"title":1535,"path":1536,"stem":1537},"Control Templates — Частина 1. Концепція та TemplateBinding","\u002Fcsharp\u002Fdesktop-ui\u002Fcontrol-templates-part1","01.csharp\u002F12.desktop-ui\u002F28.control-templates-part1",{"title":1539,"path":1540,"stem":1541},"Control Templates — Частина 2. Named Parts та ContentPresenter","\u002Fcsharp\u002Fdesktop-ui\u002Fcontrol-templates-part2","01.csharp\u002F12.desktop-ui\u002F28.control-templates-part2",{"title":1543,"path":1544,"stem":1545},"Control Themes в Avalonia — нова ера стилізації","\u002Fcsharp\u002Fdesktop-ui\u002F28a.avalonia-control-themes","01.csharp\u002F12.desktop-ui\u002F28a.avalonia-control-themes",{"title":1547,"path":1548,"stem":1549},"Triggers та Visual State Manager у WPF","\u002Fcsharp\u002Fdesktop-ui\u002Ftriggers-visual-states","01.csharp\u002F12.desktop-ui\u002F29.triggers-visual-states",{"title":1551,"path":1552,"stem":1553},"Pseudo-classes в Avalonia — замість WPF Triggers","\u002Fcsharp\u002Fdesktop-ui\u002F29a.avalonia-pseudo-classes","01.csharp\u002F12.desktop-ui\u002F29a.avalonia-pseudo-classes",{"title":1555,"path":1556,"stem":1557},"Теми та ресурсні словники у WPF","\u002Fcsharp\u002Fdesktop-ui\u002Fresources-themes","01.csharp\u002F12.desktop-ui\u002F30.resources-themes",{"title":1559,"path":1560,"stem":1561},"Avalonia Themes — Fluent Design та система тематизації","\u002Fcsharp\u002Fdesktop-ui\u002F30a.avalonia-themes-fluent","01.csharp\u002F12.desktop-ui\u002F30a.avalonia-themes-fluent",{"title":1563,"path":1564,"stem":1565},"Контроли колекцій — глибоке занурення","\u002Fcsharp\u002Fdesktop-ui\u002Fcollection-controls","01.csharp\u002F12.desktop-ui\u002F31.collection-controls",{"title":1567,"path":1568,"stem":1569},"DataGrid — колонки та базове відображення","\u002Fcsharp\u002Fdesktop-ui\u002Fdatagrid-part1","01.csharp\u002F12.desktop-ui\u002F32.datagrid-part1",{"title":1571,"path":1572,"stem":1573},"DataGrid — сортування, фільтрація, редагування","\u002Fcsharp\u002Fdesktop-ui\u002Fdatagrid-part2","01.csharp\u002F12.desktop-ui\u002F32.datagrid-part2",{"title":1575,"path":1576,"stem":1577},"TreeView та GridView","\u002Fcsharp\u002Fdesktop-ui\u002Ftreeview-listview","01.csharp\u002F12.desktop-ui\u002F33.treeview-listview",{"title":1579,"path":1580,"stem":1581},"Меню, Toolbar, ContextMenu, StatusBar","\u002Fcsharp\u002Fdesktop-ui\u002Fmenus-toolbars","01.csharp\u002F12.desktop-ui\u002F34.menus-toolbars",{"title":1583,"path":1584,"stem":1585},"Навігація та керування вікнами. Частина 1: вікна та сторінки","\u002Fcsharp\u002Fdesktop-ui\u002Fnavigation-windows-part1","01.csharp\u002F12.desktop-ui\u002F35.navigation-windows-part1",{"title":1587,"path":1588,"stem":1589},"Навігація та керування вікнами. Частина 2: MVVM-навігація","\u002Fcsharp\u002Fdesktop-ui\u002Fnavigation-windows-part2","01.csharp\u002F12.desktop-ui\u002F35.navigation-windows-part2",{"title":1591,"path":1592,"stem":1593},"Avalonia — Навігація та діалоги","\u002Fcsharp\u002Fdesktop-ui\u002F35a.avalonia-navigation-dialogs","01.csharp\u002F12.desktop-ui\u002F35a.avalonia-navigation-dialogs",{"title":1595,"path":1596,"stem":1597},"Діалоги та File Pickers у WPF","\u002Fcsharp\u002Fdesktop-ui\u002Fdialogs-file-pickers","01.csharp\u002F12.desktop-ui\u002F36.dialogs-file-pickers",{"title":1599,"path":1600,"stem":1601},"UserControl: компонентний підхід у WPF","\u002Fcsharp\u002Fdesktop-ui\u002Fuser-controls","01.csharp\u002F12.desktop-ui\u002F37.user-controls",{"title":1603,"path":1604,"stem":1605},"Custom Controls: Lookless Controls у WPF","\u002Fcsharp\u002Fdesktop-ui\u002Fcustom-controls","01.csharp\u002F12.desktop-ui\u002F38.custom-controls",{"title":1607,"path":1608,"stem":1609},"Avalonia TemplatedControl — Lookless Controls","\u002Fcsharp\u002Fdesktop-ui\u002F38a.avalonia-templated-controls","01.csharp\u002F12.desktop-ui\u002F38a.avalonia-templated-controls",{"title":1611,"path":1612,"stem":1613},"Анімації у WPF: Storyboard та Easing Functions","\u002Fcsharp\u002Fdesktop-ui\u002Fanimations-transitions","01.csharp\u002F12.desktop-ui\u002F39.animations-transitions",{"title":1615,"path":1616,"stem":1617},"Анімації в Avalonia","\u002Fcsharp\u002Fdesktop-ui\u002F39a.avalonia-animations","01.csharp\u002F12.desktop-ui\u002F39a.avalonia-animations",{"title":1619,"path":1620,"stem":1621},"2D Графіка та Мультимедіа у WPF","\u002Fcsharp\u002Fdesktop-ui\u002Fmedia-graphics","01.csharp\u002F12.desktop-ui\u002F40.media-graphics",{"title":1623,"path":1624,"stem":1625},"Dependency Injection у WPF та Avalonia","\u002Fcsharp\u002Fdesktop-ui\u002Fdi-integration","01.csharp\u002F12.desktop-ui\u002F41.di-integration",{"title":1627,"path":1628,"stem":1629},"SQLite та EF Core у десктопних додатках","\u002Fcsharp\u002Fdesktop-ui\u002Fdata-persistence-part1","01.csharp\u002F12.desktop-ui\u002F42.data-persistence-part1",{"title":1631,"path":1632,"stem":1633},"Repository Pattern та Unit of Work","\u002Fcsharp\u002Fdesktop-ui\u002Fdata-persistence-part2","01.csharp\u002F12.desktop-ui\u002F43.data-persistence-part2",{"title":1635,"path":1636,"stem":1637},"Тестування ViewModels","\u002Fcsharp\u002Fdesktop-ui\u002Fviewmodel-testing","01.csharp\u002F12.desktop-ui\u002F44.viewmodel-testing",{"title":1639,"path":1640,"stem":1641},"Avalonia Headless Testing — тестування UI без вікон","\u002Fcsharp\u002Fdesktop-ui\u002F44a.avalonia-headless-testing","01.csharp\u002F12.desktop-ui\u002F44a.avalonia-headless-testing",{"title":1643,"path":1644,"stem":1645},"Кросплатформна розробка з Avalonia","\u002Fcsharp\u002Fdesktop-ui\u002Favalonia-cross-platform","01.csharp\u002F12.desktop-ui\u002F45.avalonia-cross-platform",{"title":1647,"path":1648,"stem":1649},"Пакування та розгортання Avalonia додатків","\u002Fcsharp\u002Fdesktop-ui\u002Favalonia-packaging-deployment","01.csharp\u002F12.desktop-ui\u002F46.avalonia-packaging-deployment",{"title":1651,"path":1652,"stem":1653},"Розгортання WPF застосунків","\u002Fcsharp\u002Fdesktop-ui\u002Fwpf-packaging-deployment","01.csharp\u002F12.desktop-ui\u002F47.wpf-packaging-deployment",{"title":1655,"icon":658,"path":1656,"stem":1657,"children":1658,"page":59},"Network Programming","\u002Fcsharp\u002Fnetwork-programming","01.csharp\u002F13.network-programming",[1659,1663,1667,1671,1675,1679,1683,1687,1691,1695,1699],{"title":1660,"path":1661,"stem":1662},"Основи комп'ютерних мереж","\u002Fcsharp\u002Fnetwork-programming\u002Ffoundations","01.csharp\u002F13.network-programming\u002F01.foundations",{"title":1664,"path":1665,"stem":1666},"Модель OSI та стек TCP\u002FIP","\u002Fcsharp\u002Fnetwork-programming\u002Fosi-model","01.csharp\u002F13.network-programming\u002F02.osi-model",{"title":1668,"path":1669,"stem":1670},"IP-протокол та адресація","\u002Fcsharp\u002Fnetwork-programming\u002Fip-addressing","01.csharp\u002F13.network-programming\u002F03.ip-addressing",{"title":1672,"path":1673,"stem":1674},"UDP — протокол без з'єднання","\u002Fcsharp\u002Fnetwork-programming\u002Fudp","01.csharp\u002F13.network-programming\u002F05.udp",{"title":1676,"path":1677,"stem":1678},"UDP Broadcast та Multicast","\u002Fcsharp\u002Fnetwork-programming\u002Fudp-broadcast-multicast","01.csharp\u002F13.network-programming\u002F06.udp-broadcast-multicast",{"title":1680,"path":1681,"stem":1682},"HTTP — протокол вебу","\u002Fcsharp\u002Fnetwork-programming\u002Fhttp-fundamentals","01.csharp\u002F13.network-programming\u002F07.http-fundamentals",{"title":1684,"path":1685,"stem":1686},"HttpListener — вбудований HTTP-сервер .NET","\u002Fcsharp\u002Fnetwork-programming\u002F07a.http-listener","01.csharp\u002F13.network-programming\u002F07a.http-listener",{"title":1688,"path":1689,"stem":1690},"HTTP Advanced — cookies, аутентифікація та HTTPS","\u002Fcsharp\u002Fnetwork-programming\u002Fhttp-advanced","01.csharp\u002F13.network-programming\u002F08.http-advanced",{"title":1692,"path":1693,"stem":1694},"SMTP та протоколи електронної пошти","\u002Fcsharp\u002Fnetwork-programming\u002Fsmtp","01.csharp\u002F13.network-programming\u002F09.smtp",{"title":1696,"path":1697,"stem":1698},"WebSocket — повнодуплексний протокол реального часу","\u002Fcsharp\u002Fnetwork-programming\u002Fwebsockets","01.csharp\u002F13.network-programming\u002F10.websockets",{"title":1700,"path":1701,"stem":1702},"TLS\u002FSSL — криптографічний захист мережевих з'єднань","\u002Fcsharp\u002Fnetwork-programming\u002Ftls-ssl","01.csharp\u002F13.network-programming\u002F11.tls-ssl",{"title":1704,"path":1705,"stem":1706},"C# & .NET: The Ultimate Roadmap","\u002Fcsharp\u002Froadmap","01.csharp\u002Froadmap",{"title":1708,"icon":1709,"path":1710,"stem":1711,"children":1712,"page":59},"C++","i-devicon-cplusplus","\u002Fcpp","02.cpp",[1713,1717,1721,1725,1729,1733,1737,1741,1745,1748,1752,1756,1760,1764,1768,1772,1776,1780,1784,1788,1792,1796,1800,1804,1808,1812,1816,1820,1824,1828,1832,1836,1840,1844,1848,1852,1856,1860,1864,1868,1872,1876,1880,1884,1888,1892,1896,1900,1904,1908,1912,1916,1920,1924,1928,1932,1936,1940,1944,1948,1952,1956,1960,1964,1968,1972,1976,1980,1984,1988,1992,1996,2000,2004,2008,2012,2016,2020,2024,2028,2032,2036,2040,2044,2048,2052,2056,2060,2064,2068,2072,2076,2080,2084,2088,2092,2096,2100,2104,2108,2112,2116,2194],{"title":1714,"path":1715,"stem":1716},"Вступ у програмування та алгоритми","\u002Fcpp\u002Fintro-algorithms","02.cpp\u002F01.intro-algorithms",{"title":1718,"path":1719,"stem":1720},"Code Style: угоди про оформлення коду","\u002Fcpp\u002Fcode-style","02.cpp\u002F02.code-style",{"title":1722,"path":1723,"stem":1724},"Середовище розробки та перший проєкт","\u002Fcpp\u002Fide-setup","02.cpp\u002F03.ide-setup",{"title":1726,"path":1727,"stem":1728},"Вивід даних на екран","\u002Fcpp\u002Fdata-output","02.cpp\u002F04.data-output",{"title":1730,"path":1731,"stem":1732},"Типи даних, змінні та константи","\u002Fcpp\u002Fdata-types-variables","02.cpp\u002F05.data-types-variables",{"title":1734,"path":1735,"stem":1736},"Ввід даних з клавіатури","\u002Fcpp\u002Fdata-input","02.cpp\u002F06.data-input",{"title":1738,"path":1739,"stem":1740},"Оператори, перетворення типів та логічні операції","\u002Fcpp\u002Foperators-type-conversion","02.cpp\u002F07.operators-type-conversion",{"title":1742,"path":1743,"stem":1744},"Цикли","\u002Fcpp\u002Floops","02.cpp\u002F08.loops",{"title":32,"path":1746,"stem":1747},"\u002Fcpp\u002Farrays","02.cpp\u002F09.arrays",{"title":1749,"path":1750,"stem":1751},"Алгоритми сортування та аналіз складності","\u002Fcpp\u002Fsorting","02.cpp\u002F10.sorting",{"title":1753,"path":1754,"stem":1755},"Революція C++20: Ranges та Views","\u002Fcpp\u002Franges-views","02.cpp\u002F100.ranges-views",{"title":1757,"path":1758,"stem":1759},"Алгоритми пошуку","\u002Fcpp\u002Fsearching","02.cpp\u002F11.searching",{"title":1761,"path":1762,"stem":1763},"Функції: основи","\u002Fcpp\u002Ffunctions-basics","02.cpp\u002F12.functions-basics",{"title":1765,"path":1766,"stem":1767},"Функції: прототипи, область видимості та додаткові можливості","\u002Fcpp\u002Ffunctions-scope","02.cpp\u002F13.functions-scope",{"title":1769,"path":1770,"stem":1771},"Функції: перевантаження та шаблони","\u002Fcpp\u002Ffunctions-overloading-templates","02.cpp\u002F14.functions-overloading-templates",{"title":1773,"path":1774,"stem":1775},"Вказівники: основи","\u002Fcpp\u002Fpointers-basics","02.cpp\u002F15.pointers-basics",{"title":1777,"path":1778,"stem":1779},"Посилання (References)","\u002Fcpp\u002Freferences","02.cpp\u002F16.references",{"title":1781,"path":1782,"stem":1783},"Вказівники, const і масиви","\u002Fcpp\u002Fpointers-const-arrays","02.cpp\u002F17.pointers-const-arrays",{"title":1785,"path":1786,"stem":1787},"Адресна арифметика","\u002Fcpp\u002Fpointer-arithmetic","02.cpp\u002F18.pointer-arithmetic",{"title":1789,"path":1790,"stem":1791},"Динамічна пам'ять","\u002Fcpp\u002Fdynamic-memory","02.cpp\u002F19.dynamic-memory",{"title":1793,"path":1794,"stem":1795},"Вказівники типу void","\u002Fcpp\u002Fvoid-pointers","02.cpp\u002F20.void-pointers",{"title":1797,"path":1798,"stem":1799},"Вказівники на вказівники","\u002Fcpp\u002Fpointers-to-pointers","02.cpp\u002F21.pointers-to-pointers",{"title":1801,"path":1802,"stem":1803},"Оператор доступу до членів через вказівник (->)","\u002Fcpp\u002Fmember-access-operator","02.cpp\u002F22.member-access-operator",{"title":1805,"path":1806,"stem":1807},"Цикл for-each (Range-based for)","\u002Fcpp\u002Fforeach-loop","02.cpp\u002F23.foreach-loop",{"title":1809,"path":1810,"stem":1811},"Вказівники на функції","\u002Fcpp\u002Ffunction-pointers","02.cpp\u002F24.function-pointers",{"title":1813,"path":1814,"stem":1815},"Лямбда-вирази","\u002Fcpp\u002Flambdas","02.cpp\u002F25.lambdas",{"title":1817,"path":1818,"stem":1819},"Лямбда-захоплення","\u002Fcpp\u002Flambda-captures","02.cpp\u002F26.lambda-captures",{"title":1821,"path":1822,"stem":1823},"Еліпсис","\u002Fcpp\u002Fellipsis","02.cpp\u002F27.ellipsis",{"title":1825,"path":1826,"stem":1827},"Безпечні альтернативи еліпсису","\u002Fcpp\u002F27a.ellipsis","02.cpp\u002F27a.ellipsis",{"title":1829,"path":1830,"stem":1831},"Аргументи командного рядка","\u002Fcpp\u002Fcommand-line-arguments","02.cpp\u002F28.command-line-arguments",{"title":1833,"path":1834,"stem":1835},"Перерахування (enum)","\u002Fcpp\u002Fenum","02.cpp\u002F29.enum",{"title":1837,"path":1838,"stem":1839},"Класи-перерахування (enum class)","\u002Fcpp\u002Fenum-class","02.cpp\u002F30.enum-class",{"title":1841,"path":1842,"stem":1843},"Псевдоніми типів (typedef і using)","\u002Fcpp\u002Ftype-aliases","02.cpp\u002F31.type-aliases",{"title":1845,"path":1846,"stem":1847},"Системи числення та двійкова арифметика","\u002Fcpp\u002Fnumber-systems","02.cpp\u002F32.number-systems",{"title":1849,"path":1850,"stem":1851},"Структури (struct): агрегування даних","\u002Fcpp\u002Fstruct","02.cpp\u002F33.struct",{"title":1853,"path":1854,"stem":1855},"Структури у функціях","\u002Fcpp\u002Fstruct-functions","02.cpp\u002F34.struct-functions",{"title":1857,"path":1858,"stem":1859},"Масиви структур і вкладені структури","\u002Fcpp\u002Fstruct-arrays","02.cpp\u002F35.struct-arrays",{"title":1861,"path":1862,"stem":1863},"Патерни struct та межі застосування","\u002Fcpp\u002Fstruct-patterns","02.cpp\u002F36.struct-patterns",{"title":1865,"path":1866,"stem":1867},"Символи та таблиця ASCII","\u002Fcpp\u002Fascii-characters","02.cpp\u002F37.ascii-characters",{"title":1869,"path":1870,"stem":1871},"Unicode та кодування UTF","\u002Fcpp\u002Funicode-utf","02.cpp\u002F38.unicode-utf",{"title":1873,"path":1874,"stem":1875},"C-style рядки","\u002Fcpp\u002Fc-strings","02.cpp\u002F39.c-strings",{"title":1877,"path":1878,"stem":1879},"Вступ до std::string","\u002Fcpp\u002Fstd-string-intro","02.cpp\u002F40.std-string-intro",{"title":1881,"path":1882,"stem":1883},"Довжина, ємність та доступ до символів std::string","\u002Fcpp\u002Fstd-string-capacity-access","02.cpp\u002F41.std-string-capacity-access",{"title":1885,"path":1886,"stem":1887},"Модифікація std::string: присвоювання, додавання, вставка, видалення та заміна","\u002Fcpp\u002Fstd-string-modification","02.cpp\u002F42.std-string-modification",{"title":1889,"path":1890,"stem":1891},"Пошук у std::string: find, npos та практичні патерни","\u002Fcpp\u002Fstd-string-search","02.cpp\u002F43.std-string-search",{"title":1893,"path":1894,"stem":1895},"std::string_view: невласницький погляд на рядок без копіювання","\u002Fcpp\u002Fstd-string-view","02.cpp\u002F44.std-string-view",{"title":1897,"path":1898,"stem":1899},"Об'єднання (union): один блок пам'яті, кілька інтерпретацій","\u002Fcpp\u002Funion","02.cpp\u002F45.union",{"title":1901,"path":1902,"stem":1903},"Організація коду: файли, препроцесор, простори імен","\u002Fcpp\u002Fmultifile-programs","02.cpp\u002F46.multifile-programs",{"title":1905,"path":1906,"stem":1907},"Робота з файлами: C-стиль (stdio.h)","\u002Fcpp\u002Fc-style-files","02.cpp\u002F47.c-style-files",{"title":1909,"path":1910,"stem":1911},"Робота з файлами: C++-стиль (fstream)","\u002Fcpp\u002Fcpp-style-files","02.cpp\u002F48.cpp-style-files",{"title":1913,"path":1914,"stem":1915},"Введення в ООП: від процедур до об'єктів","\u002Fcpp\u002Foop-intro","02.cpp\u002F49.oop-intro",{"title":1917,"path":1918,"stem":1919},"Класи, об'єкти та методи","\u002Fcpp\u002Fclasses-objects-methods","02.cpp\u002F50.classes-objects-methods",{"title":1921,"path":1922,"stem":1923},"Специфікатори доступу та інкапсуляція","\u002Fcpp\u002Faccess-specifiers-encapsulation","02.cpp\u002F51.access-specifiers-encapsulation",{"title":1925,"path":1926,"stem":1927},"Конструктори: гарантована ініціалізація об'єктів","\u002Fcpp\u002Fconstructors","02.cpp\u002F52.constructors",{"title":1929,"path":1930,"stem":1931},"Списки ініціалізації та делегуючі конструктори","\u002Fcpp\u002Finit-lists-delegating","02.cpp\u002F53.init-lists-delegating",{"title":1933,"path":1934,"stem":1935},"Деструктори та ідіома RAII","\u002Fcpp\u002Fdestructors-raii","02.cpp\u002F54.destructors-raii",{"title":1937,"path":1938,"stem":1939},"Прихований покажчик this","\u002Fcpp\u002Fthis-pointer","02.cpp\u002F55.this-pointer",{"title":1941,"path":1942,"stem":1943},"Розподіл класу на заголовковий файл та файл реалізації","\u002Fcpp\u002Fclass-header-source","02.cpp\u002F56.class-header-source",{"title":1945,"path":1946,"stem":1947},"Класи та const","\u002Fcpp\u002Fconst-classes","02.cpp\u002F57.const-classes",{"title":1949,"path":1950,"stem":1951},"Статичні члени класу","\u002Fcpp\u002Fstatic-members","02.cpp\u002F58.static-members",{"title":1953,"path":1954,"stem":1955},"Конструктор копіювання та запобігання копіюванню","\u002Fcpp\u002Fcopy-constructor","02.cpp\u002F59.copy-constructor",{"title":1957,"path":1958,"stem":1959},"Дружні функції та класи","\u002Fcpp\u002Ffriend-functions-classes","02.cpp\u002F60.friend-functions-classes",{"title":1961,"path":1962,"stem":1963},"Анонімні об'єкти та вкладені типи","\u002Fcpp\u002Fanonymous-objects-nested-types","02.cpp\u002F61.anonymous-objects-nested-types",{"title":1965,"path":1966,"stem":1967},"Вимірювання часу виконання: RAII-таймер","\u002Fcpp\u002Ftiming-raii-timer","02.cpp\u002F62.timing-raii-timer",{"title":1969,"path":1970,"stem":1971},"Перевантаження операторів: основи та арифметика","\u002Fcpp\u002Foperator-overloading-basics","02.cpp\u002F63.operator-overloading-basics",{"title":1973,"path":1974,"stem":1975},"Перевантаження операторів: методи класу та спеціальні оператори","\u002Fcpp\u002Foperator-overloading-methods","02.cpp\u002F64.operator-overloading-methods",{"title":1977,"path":1978,"stem":1979},"Приведення типів, explicit та delete","\u002Fcpp\u002Ftypecast-explicit-delete","02.cpp\u002F65.typecast-explicit-delete",{"title":1981,"path":1982,"stem":1983},"Глибоке копіювання та оператор присвоювання","\u002Fcpp\u002Fdeep-copy-assignment","02.cpp\u002F66.deep-copy-assignment",{"title":1985,"path":1986,"stem":1987},"Зв'язки між об'єктами: композиція та агрегація","\u002Fcpp\u002Fcomposition-aggregation","02.cpp\u002F67.composition-aggregation",{"title":1989,"path":1990,"stem":1991},"Асоціація та залежність між об","\u002Fcpp\u002Fassociation-dependency","02.cpp\u002F68.association-dependency",{"title":1993,"path":1994,"stem":1995},"Контейнерні класи та `std::initializer_list`","\u002Fcpp\u002Fcontainer-classes-initializer-list","02.cpp\u002F69.container-classes-initializer-list",{"title":1997,"path":1998,"stem":1999},"Вступ до наслідування: базові поняття та відношення «is-a»","\u002Fcpp\u002Finheritance-intro","02.cpp\u002F70.inheritance-intro",{"title":2001,"path":2002,"stem":2003},"Конструктори, деструктори та порядок ініціалізації в ієрархіях","\u002Fcpp\u002Finheritance-constructors-destructors","02.cpp\u002F71.inheritance-constructors-destructors",{"title":2005,"path":2006,"stem":2007},"Специфікатор `protected` та види наслідування","\u002Fcpp\u002Finheritance-access-specifiers","02.cpp\u002F72.inheritance-access-specifiers",{"title":2009,"path":2010,"stem":2011},"Перевизначення методів та приховування імен","\u002Fcpp\u002Fmethod-overriding-hiding","02.cpp\u002F73.method-overriding-hiding",{"title":2013,"path":2014,"stem":2015},"Множинне наслідування та проблема ромба","\u002Fcpp\u002Fmultiple-inheritance-diamond","02.cpp\u002F74.multiple-inheritance-diamond",{"title":2017,"path":2018,"stem":2019},"Вказівники на базовий клас та віртуальні функції","\u002Fcpp\u002Fvirtual-functions-polymorphism","02.cpp\u002F75.virtual-functions-polymorphism",{"title":2021,"path":2022,"stem":2023},"Специфікатори override, final та віртуальні деструктори","\u002Fcpp\u002Foverride-final-virtual-destructors","02.cpp\u002F76.override-final-virtual-destructors",{"title":2025,"path":2026,"stem":2027},"Внутрішні механізми поліморфізму: vtable, vptr та зв'язування","\u002Fcpp\u002Fvirtual-table-binding","02.cpp\u002F77.virtual-table-binding",{"title":2029,"path":2030,"stem":2031},"Абстрактні класи та чисті віртуальні функції","\u002Fcpp\u002Fabstract-classes-interfaces","02.cpp\u002F78.abstract-classes-interfaces",{"title":2033,"path":2034,"stem":2035},"Зрізка об'єктів, віртуальне наслідування та поліморфний вивід","\u002Fcpp\u002Fslicing-virtual-base-io","02.cpp\u002F79.slicing-virtual-base-io",{"title":2037,"path":2038,"stem":2039},"Динамічне приведення типів (`dynamic_cast`) та RTTI","\u002Fcpp\u002Fdynamic-cast-rtti","02.cpp\u002F80.dynamic-cast-rtti",{"title":2041,"path":2042,"stem":2043},"Шаблони функцій: узагальнене програмування","\u002Fcpp\u002Ffunction-templates","02.cpp\u002F81.function-templates",{"title":2045,"path":2046,"stem":2047},"Шаблони класів та NTTP-параметри","\u002Fcpp\u002Fclass-templates-nttp","02.cpp\u002F82.class-templates-nttp",{"title":2049,"path":2050,"stem":2051},"Повна (явна) спеціалізація шаблонів","\u002Fcpp\u002Ffull-template-specialization","02.cpp\u002F83.full-template-specialization",{"title":2053,"path":2054,"stem":2055},"Часткова спеціалізація шаблонів класів","\u002Fcpp\u002Fpartial-template-specialization","02.cpp\u002F84.partial-template-specialization",{"title":2057,"path":2058,"stem":2059},"Механізм винятків: try, catch, throw та розкручування стеку","\u002Fcpp\u002Fexceptions-basics","02.cpp\u002F85.exceptions-basics",{"title":2061,"path":2062,"stem":2063},"Ієрархія std::exception та власні класи винятків","\u002Fcpp\u002Fexception-hierarchy-custom","02.cpp\u002F86.exception-hierarchy-custom",{"title":2065,"path":2066,"stem":2067},"Повторне генерування винятків та функціональний try-блок","\u002Fcpp\u002Frethrow-function-try","02.cpp\u002F87.rethrow-function-try",{"title":2069,"path":2070,"stem":2071},"Безпека винятків, noexcept та деструктори","\u002Fcpp\u002Fsafety-noexcept","02.cpp\u002F88.safety-noexcept",{"title":2073,"path":2074,"stem":2075},"Власні структури даних: стек та черга","\u002Fcpp\u002Fcustom-stack-queue","02.cpp\u002F89.custom-stack-queue",{"title":2077,"path":2078,"stem":2079},"Власні структури даних: однозв'язаний список","\u002Fcpp\u002Flinked-list","02.cpp\u002F90.linked-list",{"title":2081,"path":2082,"stem":2083},"Власні структури даних: бінарне дерево пошуку","\u002Fcpp\u002Fbinary-search-tree","02.cpp\u002F91.binary-search-tree",{"title":2085,"path":2086,"stem":2087},"Власні структури даних: хеш-таблиця","\u002Fcpp\u002Fhash-table","02.cpp\u002F92.hash-table",{"title":2089,"path":2090,"stem":2091},"Готові структури даних C++: послідовні контейнери STL","\u002Fcpp\u002Fstl-sequential-containers","02.cpp\u002F93.stl-sequential-containers",{"title":2093,"path":2094,"stem":2095},"Готові структури даних C++: асоціативні контейнери та адаптери","\u002Fcpp\u002Fstl-associative-adapters","02.cpp\u002F94.stl-associative-adapters",{"title":2097,"path":2098,"stem":2099},"Готові структури даних C++: ітератори та алгоритми STL","\u002Fcpp\u002Fstl-iterators-algorithms","02.cpp\u002F95.stl-iterators-algorithms",{"title":2101,"path":2102,"stem":2103},"R-value посилання та move-семантика","\u002Fcpp\u002Frvalue-references-move-semantics","02.cpp\u002F96.rvalue-references-move-semantics",{"title":2105,"path":2106,"stem":2107},"Move-конструктор, move-присвоювання та Правило п","\u002Fcpp\u002Fmove-constructors-rule-of-five","02.cpp\u002F97.move-constructors-rule-of-five",{"title":2109,"path":2110,"stem":2111},"Розумний покажчик std::unique_ptr","\u002Fcpp\u002Funique-ptr","02.cpp\u002F98.unique-ptr",{"title":2113,"path":2114,"stem":2115},"Спільне володіння: std::shared_ptr та std::weak_ptr","\u002Fcpp\u002Fshared-ptr-weak-ptr","02.cpp\u002F99.shared-ptr-weak-ptr",{"title":2117,"icon":2118,"path":2119,"stem":2120,"children":2121,"page":59},"CMake і vcpkg","i-devicon-cmake","\u002Fcpp\u002Fcmake","02.cpp\u002F990.cmake",[2122,2126,2130,2134,2138,2142,2146,2150,2154,2158,2162,2166,2170,2174,2178,2182,2186,2190],{"title":2123,"path":2124,"stem":2125},"CMake: навіщо він потрібен і як його встановити","\u002Fcpp\u002Fcmake\u002Fwhat-is-cmake","02.cpp\u002F990.cmake\u002F01.what-is-cmake",{"title":2127,"path":2128,"stem":2129},"Перший проєкт з CMake: конфігурація, збірка, запуск","\u002Fcpp\u002Fcmake\u002Ffirst-project","02.cpp\u002F990.cmake\u002F02.first-project",{"title":2131,"path":2132,"stem":2133},"Синтаксис CMakeLists.txt: команди, змінні, списки","\u002Fcpp\u002Fcmake\u002Fcmakelists-syntax","02.cpp\u002F990.cmake\u002F03.cmakelists-syntax",{"title":2135,"path":2136,"stem":2137},"Проєкт із кількома файлами: перелік джерел і file(GLOB)","\u002Fcpp\u002Fcmake\u002Fmultiple-files","02.cpp\u002F990.cmake\u002F04.multiple-files",{"title":2139,"path":2140,"stem":2141},"Бібліотеки в CMake: STATIC, SHARED, INTERFACE та видимість PUBLIC\u002FPRIVATE","\u002Fcpp\u002Fcmake\u002Flibraries","02.cpp\u002F990.cmake\u002F05.libraries",{"title":2143,"path":2144,"stem":2145},"Підключення зовнішніх бібліотек: find_package, add_subdirectory, FetchContent, pkg-config","\u002Fcpp\u002Fcmake\u002Fexternal-libraries","02.cpp\u002F990.cmake\u002F06.external-libraries",{"title":2147,"path":2148,"stem":2149},"Умови, опції, цикли та функції в CMake","\u002Fcpp\u002Fcmake\u002Fvariables-conditions","02.cpp\u002F990.cmake\u002F07.variables-conditions",{"title":2151,"path":2152,"stem":2153},"Конфігурації збірки: Debug, Release і вирази-генератори","\u002Fcpp\u002Fcmake\u002Fbuild-configurations","02.cpp\u002F990.cmake\u002F08.build-configurations",{"title":2155,"path":2156,"stem":2157},"Структура великого проєкту: підпапки, модулі CMake, PCH та install","\u002Fcpp\u002Fcmake\u002Fproject-structure","02.cpp\u002F990.cmake\u002F09.project-structure",{"title":2159,"path":2160,"stem":2161},"Тестування з CMake: CTest, Google Test, покриття коду","\u002Fcpp\u002Fcmake\u002Ftesting-ctest","02.cpp\u002F990.cmake\u002F10.testing-ctest",{"title":2163,"path":2164,"stem":2165},"Команди CMake, пресети, скрипти збірки та кращі практики","\u002Fcpp\u002Fcmake\u002Fcommands-best-practices","02.cpp\u002F990.cmake\u002F11.commands-best-practices",{"title":2167,"path":2168,"stem":2169},"Практичні проєкти: калькулятор, Qt-застосунок і кросплатформна збірка","\u002Fcpp\u002Fcmake\u002Freal-projects","02.cpp\u002F990.cmake\u002F12.real-projects",{"title":2171,"path":2172,"stem":2173},"Пакетні менеджери для C++: vcpkg, Conan, CPM та системні пакети","\u002Fcpp\u002Fcmake\u002Fpackage-managers","02.cpp\u002F990.cmake\u002F13.package-managers",{"title":2175,"path":2176,"stem":2177},"vcpkg: встановлення, основні команди та triplets","\u002Fcpp\u002Fcmake\u002Fvcpkg-basics","02.cpp\u002F990.cmake\u002F14.vcpkg-basics",{"title":2179,"path":2180,"stem":2181},"vcpkg і CMake: toolchain-файл, manifest vcpkg.json, IDE","\u002Fcpp\u002Fcmake\u002Fvcpkg-cmake","02.cpp\u002F990.cmake\u002F15.vcpkg-cmake",{"title":2183,"path":2184,"stem":2185},"vcpkg для досвідчених: версії, features, реєстри, власні порти, кеш і діагностика","\u002Fcpp\u002Fcmake\u002Fvcpkg-advanced","02.cpp\u002F990.cmake\u002F16.vcpkg-advanced",{"title":2187,"path":2188,"stem":2189},"Бібліотеки C++: fmt, spdlog і nlohmann\u002Fjson","\u002Fcpp\u002Fcmake\u002Flibraries-format-log-json","02.cpp\u002F990.cmake\u002F17.libraries-format-log-json",{"title":2191,"path":2192,"stem":2193},"Бібліотеки C++: cpp-httplib, cxxopts, CLI11, Google Test і Catch2","\u002Fcpp\u002Fcmake\u002Flibraries-network-cli-testing","02.cpp\u002F990.cmake\u002F18.libraries-network-cli-testing",{"title":2195,"icon":2196,"path":2197,"stem":2198,"children":2199,"page":59},"Реверс-інжиніринг і чіти","i-lucide-bug-play","\u002Fcpp\u002Freverse-engineering","02.cpp\u002F991.reverse-engineering",[2200,2204,2208,2212,2216],{"title":2201,"path":2202,"stem":2203},"Основи: пам'ять, процеси та інструменти","\u002Fcpp\u002Freverse-engineering\u002Ffoundations","02.cpp\u002F991.reverse-engineering\u002F01.foundations",{"title":2205,"path":2206,"stem":2207},"Пошук даних у пам'яті: сканування, структури, ланцюжки вказівників","\u002Fcpp\u002Freverse-engineering\u002Ffinding-data","02.cpp\u002F991.reverse-engineering\u002F02.finding-data",{"title":2209,"path":2210,"stem":2211},"Тренер і internal-модуль на C++","\u002Fcpp\u002Freverse-engineering\u002Ftrainer-and-injection","02.cpp\u002F991.reverse-engineering\u002F03.trainer-and-injection",{"title":2213,"path":2214,"stem":2215},"Аналіз коду: асемблер, налагоджувач, патчинг","\u002Fcpp\u002Freverse-engineering\u002Fcode-analysis","02.cpp\u002F991.reverse-engineering\u002F04.code-analysis",{"title":2217,"path":2218,"stem":2219},"AssaultCube і захист від чітів","\u002Fcpp\u002Freverse-engineering\u002Fassaultcube-and-defense","02.cpp\u002F991.reverse-engineering\u002F05.assaultcube-and-defense",{"title":2221,"icon":2222,"path":2223,"stem":2224,"children":2225,"page":59},"JavaScript","i-devicon-javascript","\u002Fjavascript","03.javascript",[2226,2252,2306,2328,2632,2670,2688],{"title":2227,"icon":2228,"path":2229,"stem":2230,"children":2231,"page":59},"Events","i-lucide-mouse-pointer-click","\u002Fjavascript\u002Fevents","03.javascript\u002F01.events",[2232,2236,2240,2244,2248],{"title":2233,"path":2234,"stem":2235},"Вступ до подій браузера","\u002Fjavascript\u002Fevents\u002Fintro","03.javascript\u002F01.events\u002F01.intro",{"title":2237,"path":2238,"stem":2239},"Бульбашковий механізм (Bubbling) та занурення (Capturing)","\u002Fjavascript\u002Fevents\u002Fbubbling-capturing","03.javascript\u002F01.events\u002F02.bubbling-capturing",{"title":2241,"path":2242,"stem":2243},"Делегування подій (Event Delegation)","\u002Fjavascript\u002Fevents\u002Fdelegate-events","03.javascript\u002F01.events\u002F03.delegate-events",{"title":2245,"path":2246,"stem":2247},"Типові дії браузера та preventDefault()","\u002Fjavascript\u002Fevents\u002Fprevent-default","03.javascript\u002F01.events\u002F04.prevent-default",{"title":2249,"path":2250,"stem":2251},"Запуск користувацьких подій (Custom Events)","\u002Fjavascript\u002Fevents\u002Fcustom-events","03.javascript\u002F01.events\u002F05.custom-events",{"title":2253,"icon":2254,"path":2255,"stem":2256,"children":2257,"page":59},"Network","i-lucide-globe","\u002Fjavascript\u002Fnetwork","03.javascript\u002F02.network",[2258,2262,2266,2270,2274,2278,2282,2286,2290,2294,2298,2302],{"title":2259,"path":2260,"stem":2261},"Fetch API - Сучасний підхід до HTTP-запитів","\u002Fjavascript\u002Fnetwork\u002F01-fetch-api","03.javascript\u002F02.network\u002F01-fetch-api",{"title":2263,"path":2264,"stem":2265},"FormData - Робота з формами та файлами","\u002Fjavascript\u002Fnetwork\u002F02-formdata","03.javascript\u002F02.network\u002F02-formdata",{"title":2267,"path":2268,"stem":2269},"Відстеження прогресу завантаження","\u002Fjavascript\u002Fnetwork\u002F03-download-progress","03.javascript\u002F02.network\u002F03-download-progress",{"title":2271,"path":2272,"stem":2273},"Переривання fetch-запитів","\u002Fjavascript\u002Fnetwork\u002F04-abort-requests","03.javascript\u002F02.network\u002F04-abort-requests",{"title":2275,"path":2276,"stem":2277},"CORS - Запити між різними джерелами","\u002Fjavascript\u002Fnetwork\u002F05-cors","03.javascript\u002F02.network\u002F05-cors",{"title":2279,"path":2280,"stem":2281},"Fetch API - Повний довідник опцій","\u002Fjavascript\u002Fnetwork\u002F06-fetch-options","03.javascript\u002F02.network\u002F06-fetch-options",{"title":2283,"path":2284,"stem":2285},"URL Objects - Робота з посиланнями","\u002Fjavascript\u002Fnetwork\u002F07-url-objects","03.javascript\u002F02.network\u002F07-url-objects",{"title":2287,"path":2288,"stem":2289},"XMLHttpRequest - AJAX та низькорівневі запити","\u002Fjavascript\u002Fnetwork\u002F08-xmlhttprequest","03.javascript\u002F02.network\u002F08-xmlhttprequest",{"title":2291,"path":2292,"stem":2293},"Відновлюване завантаження файлів","\u002Fjavascript\u002Fnetwork\u002F09-resumable-upload","03.javascript\u002F02.network\u002F09-resumable-upload",{"title":2295,"path":2296,"stem":2297},"Cookies, document.cookie та світ після \"Cookiepocalypse\"","\u002Fjavascript\u002Fnetwork\u002F10-cookies","03.javascript\u002F02.network\u002F10-cookies",{"title":2299,"path":2300,"stem":2301},"js-cookie: Керування Cookies без Болю","\u002Fjavascript\u002Fnetwork\u002F11-js-cookie","03.javascript\u002F02.network\u002F11-js-cookie",{"title":2303,"path":2304,"stem":2305},"Axios: Потужний HTTP-клієнт для JavaScript","\u002Fjavascript\u002Fnetwork\u002F12-axios","03.javascript\u002F02.network\u002F12-axios",{"title":2307,"icon":2308,"path":2309,"stem":2310,"children":2311,"page":59},"Bom","i-lucide-monitor","\u002Fjavascript\u002Fbom","03.javascript\u002F03.bom",[2312,2316,2320,2324],{"title":2313,"path":2314,"stem":2315},"LocalStorage, SessionStorage та patterns збереження даних","\u002Fjavascript\u002Fbom\u002F01-localstorage","03.javascript\u002F03.bom\u002F01-localstorage",{"title":2317,"path":2318,"stem":2319},"Location Object - Керування адресою сторінки","\u002Fjavascript\u002Fbom\u002F02-location-object","03.javascript\u002F03.bom\u002F02-location-object",{"title":2321,"path":2322,"stem":2323},"History API - Керування історією браузера","\u002Fjavascript\u002Fbom\u002F03-history-api","03.javascript\u002F03.bom\u002F03-history-api",{"title":2325,"path":2326,"stem":2327},"Navigator Object - Ідентифікація та Можливості Пристрою","\u002Fjavascript\u002Fbom\u002F04-navigator-object","03.javascript\u002F03.bom\u002F04-navigator-object",{"title":2329,"icon":2330,"path":2331,"stem":2332,"children":2333},"React","i-devicon-react","\u002Fjavascript\u002Freact","03.javascript\u002F04.react\u002Findex",[2334,2335,2339,2343,2347,2351,2414,2449,2601],{"title":2329,"path":2331,"stem":2332},{"title":2336,"path":2337,"stem":2338},"Робота з Формами в React","\u002Fjavascript\u002Freact\u002Freact-forms","03.javascript\u002F04.react\u002F01.react-forms",{"title":2340,"path":2341,"stem":2342},"React Hook Form: Професійна Робота з Формами","\u002Fjavascript\u002Freact\u002Freact-hook-form","03.javascript\u002F04.react\u002F02.react-hook-form",{"title":2344,"path":2345,"stem":2346},"React Hook Form: Глибоке Розуміння Архітектури та Оптимізації","\u002Fjavascript\u002Freact\u002Freact-hook-form-new","03.javascript\u002F04.react\u002F02.react-hook-form-new",{"title":2348,"path":2349,"stem":2350},"Axios та React: Професійна Архітектура Запитів","\u002Fjavascript\u002Freact\u002Fdata-fetching-axios","03.javascript\u002F04.react\u002F03.data-fetching-axios",{"title":2352,"icon":132,"path":2353,"stem":2354,"children":2355},"Tanstack Query","\u002Fjavascript\u002Freact\u002Ftanstack-query","03.javascript\u002F04.react\u002F04.tanstack-query\u002Findex",[2356,2358,2362,2366,2370,2374,2378,2382,2386,2390,2394,2398,2402,2406,2410],{"title":2357,"path":2353,"stem":2354},"TanStack Query: Майстерність Керування Станом Сервера",{"title":2359,"path":2360,"stem":2361},"Парадигма Server State: Чому useEffect недостатньо","\u002Fjavascript\u002Freact\u002Ftanstack-query\u002Fserver-state-paradigm","03.javascript\u002F04.react\u002F04.tanstack-query\u002F01.server-state-paradigm",{"title":2363,"path":2364,"stem":2365},"Встановлення та Налаштування: Фундамент","\u002Fjavascript\u002Freact\u002Ftanstack-query\u002Finstallation-and-devtools","03.javascript\u002F04.react\u002F04.tanstack-query\u002F02.installation-and-devtools",{"title":2367,"path":2368,"stem":2369},"Основи Запитів та Магія Ключів","\u002Fjavascript\u002Freact\u002Ftanstack-query\u002Fquery-basics-and-keys","03.javascript\u002F04.react\u002F04.tanstack-query\u002F03.query-basics-and-keys",{"title":2371,"path":2372,"stem":2373},"Синхронізація Даних: Життєвий Цикл Запиту","\u002Fjavascript\u002Freact\u002Ftanstack-query\u002Fdata-synchronization","03.javascript\u002F04.react\u002F04.tanstack-query\u002F04.data-synchronization",{"title":2375,"path":2376,"stem":2377},"Мутації та Інвалідація: Зміна Даних","\u002Fjavascript\u002Freact\u002Ftanstack-query\u002Fmutations-and-invalidation","03.javascript\u002F04.react\u002F04.tanstack-query\u002F05.mutations-and-invalidation",{"title":2379,"path":2380,"stem":2381},"Оптимістичні Оновлення: Швидше за Світло","\u002Fjavascript\u002Freact\u002Ftanstack-query\u002Foptimistic-updates","03.javascript\u002F04.react\u002F04.tanstack-query\u002F06.optimistic-updates",{"title":2383,"path":2384,"stem":2385},"Пагінація та Infinite Scroll","\u002Fjavascript\u002Freact\u002Ftanstack-query\u002Fpagination-and-load-more","03.javascript\u002F04.react\u002F04.tanstack-query\u002F07.pagination-and-load-more",{"title":2387,"path":2388,"stem":2389},"Просунуті Патерни та Оптимізація","\u002Fjavascript\u002Freact\u002Ftanstack-query\u002Fadvanced-patterns","03.javascript\u002F04.react\u002F04.tanstack-query\u002F08.advanced-patterns",{"title":2391,"path":2392,"stem":2393},"Архітектура та Best Practices","\u002Fjavascript\u002Freact\u002Ftanstack-query\u002Farchitecture-and-best-practices","03.javascript\u002F04.react\u002F04.tanstack-query\u002F09.architecture-and-best-practices",{"title":2395,"path":2396,"stem":2397},"Server-Side Rendering (SSR) та Гідратація","\u002Fjavascript\u002Freact\u002Ftanstack-query\u002Fserver-side-rendering","03.javascript\u002F04.react\u002F04.tanstack-query\u002F10.server-side-rendering",{"title":2399,"path":2400,"stem":2401},"Стратегії Тестування","\u002Fjavascript\u002Freact\u002Ftanstack-query\u002Ftesting-strategies","03.javascript\u002F04.react\u002F04.tanstack-query\u002F11.testing-strategies",{"title":2403,"path":2404,"stem":2405},"Аутентифікація та Обробка Помилок","\u002Fjavascript\u002Freact\u002Ftanstack-query\u002Fauthentication-and-errors","03.javascript\u002F04.react\u002F04.tanstack-query\u002F12.authentication-and-errors",{"title":2407,"path":2408,"stem":2409},"React Suspense та Майбутнє","\u002Fjavascript\u002Freact\u002Ftanstack-query\u002Freact-suspense","03.javascript\u002F04.react\u002F04.tanstack-query\u002F13.react-suspense",{"title":2411,"path":2412,"stem":2413},"Глибоке Занурення в Продуктивність","\u002Fjavascript\u002Freact\u002Ftanstack-query\u002Fperformance-deep-dive","03.javascript\u002F04.react\u002F04.tanstack-query\u002F14.performance-deep-dive",{"title":2415,"icon":2330,"path":2416,"stem":2417,"children":2418},"React Router","\u002Fjavascript\u002Freact\u002Freact-router","03.javascript\u002F04.react\u002F05.react-router\u002Findex",[2419,2421,2425,2429,2433,2437,2441,2445],{"title":2420,"path":2416,"stem":2417},"React Router: Навігаційна система сучасного вебу",{"title":2422,"path":2423,"stem":2424},"Налаштування та Базовий Роутинг","\u002Fjavascript\u002Freact\u002Freact-router\u002Fsetup-and-basic-routing","03.javascript\u002F04.react\u002F05.react-router\u002F01.setup-and-basic-routing",{"title":2426,"path":2427,"stem":2428},"Динамічна Навігація","\u002Fjavascript\u002Freact\u002Freact-router\u002Fnavigation-and-links","03.javascript\u002F04.react\u002F05.react-router\u002F02.navigation-and-links",{"title":2430,"path":2431,"stem":2432},"Вкладені Маршрути та Макети","\u002Fjavascript\u002Freact\u002Freact-router\u002Fnested-routes-and-layouts","03.javascript\u002F04.react\u002F05.react-router\u002F03.nested-routes-and-layouts",{"title":2434,"path":2435,"stem":2436},"Динамічні Маршрути та Параметри","\u002Fjavascript\u002Freact\u002Freact-router\u002Fdynamic-routing","03.javascript\u002F04.react\u002F05.react-router\u002F04.dynamic-routing",{"title":2438,"path":2439,"stem":2440},"Data APIs: Loaders та Actions","\u002Fjavascript\u002Freact\u002Freact-router\u002Fdata-loading","03.javascript\u002F04.react\u002F05.react-router\u002F05.data-loading",{"title":2442,"path":2443,"stem":2444},"Просунуті Патерни","\u002Fjavascript\u002Freact\u002Freact-router\u002Fadvanced-patterns","03.javascript\u002F04.react\u002F05.react-router\u002F06.advanced-patterns",{"title":2446,"path":2447,"stem":2448},"Legacy Routing: Компонентний підхід","\u002Fjavascript\u002Freact\u002Freact-router\u002Flegacy-routing","03.javascript\u002F04.react\u002F05.react-router\u002F07.legacy-routing",{"title":2450,"icon":132,"path":2451,"stem":2452,"children":2453},"Redux","\u002Fjavascript\u002Freact\u002Fredux","03.javascript\u002F04.react\u002F06.redux\u002Findex",[2454,2456,2472,2501,2510,2531,2547,2576],{"title":2455,"path":2451,"stem":2452},"Redux: Еволюція управління станом",{"title":14,"icon":15,"path":2457,"stem":2458,"children":2459,"page":59},"\u002Fjavascript\u002Freact\u002Fredux\u002Ffundamentals","03.javascript\u002F04.react\u002F06.redux\u002F01.fundamentals",[2460,2464,2468],{"title":2461,"path":2462,"stem":2463},"Вступ до State Management","\u002Fjavascript\u002Freact\u002Fredux\u002Ffundamentals\u002Fintro-state-management","03.javascript\u002F04.react\u002F06.redux\u002F01.fundamentals\u002F01.intro-state-management",{"title":2465,"path":2466,"stem":2467},"Філософія Redux та Три Принципи","\u002Fjavascript\u002Freact\u002Fredux\u002Ffundamentals\u002Fredux-philosophy","03.javascript\u002F04.react\u002F06.redux\u002F01.fundamentals\u002F02.redux-philosophy",{"title":2469,"path":2470,"stem":2471},"Чисті функції та Іммутабельність","\u002Fjavascript\u002Freact\u002Fredux\u002Ffundamentals\u002Fpure-functions-immutability","03.javascript\u002F04.react\u002F06.redux\u002F01.fundamentals\u002F03.pure-functions-immutability",{"title":2473,"icon":132,"path":2474,"stem":2475,"children":2476,"page":59},"Classic Redux","\u002Fjavascript\u002Freact\u002Fredux\u002Fclassic-redux","03.javascript\u002F04.react\u002F06.redux\u002F02.classic-redux",[2477,2481,2485,2489,2493,2497],{"title":2478,"path":2479,"stem":2480},"Створення Store (Classic Redux)","\u002Fjavascript\u002Freact\u002Fredux\u002Fclassic-redux\u002Fstore-setup","03.javascript\u002F04.react\u002F06.redux\u002F02.classic-redux\u002F01.store-setup",{"title":2482,"path":2483,"stem":2484},"Actions, Constants та Action Creators","\u002Fjavascript\u002Freact\u002Fredux\u002Fclassic-redux\u002Factions-constants","03.javascript\u002F04.react\u002F06.redux\u002F02.classic-redux\u002F02.actions-constants",{"title":2486,"path":2487,"stem":2488},"Логіка Reducers","\u002Fjavascript\u002Freact\u002Fredux\u002Fclassic-redux\u002Freducers","03.javascript\u002F04.react\u002F06.redux\u002F02.classic-redux\u002F03.reducers",{"title":2490,"path":2491,"stem":2492},"Комбінування Reducers (Root Reducer)","\u002Fjavascript\u002Freact\u002Fredux\u002Fclassic-redux\u002Fdata-flow","03.javascript\u002F04.react\u002F06.redux\u002F02.classic-redux\u002F04.data-flow",{"title":2494,"path":2495,"stem":2496},"Підключення до React (React-Redux)","\u002Fjavascript\u002Freact\u002Fredux\u002Fclassic-redux\u002Freact-redux-connection","03.javascript\u002F04.react\u002F06.redux\u002F02.classic-redux\u002F05.react-redux-connection",{"title":2498,"path":2499,"stem":2500},"Middleware та Асинхронність (Redux Thunk)","\u002Fjavascript\u002Freact\u002Fredux\u002Fclassic-redux\u002Fmiddleware-thunk","03.javascript\u002F04.react\u002F06.redux\u002F02.classic-redux\u002F06.middleware-thunk",{"title":2502,"icon":132,"path":2503,"stem":2504,"children":2505,"page":59},"Transition To Rtk","\u002Fjavascript\u002Freact\u002Fredux\u002Ftransition-to-rtk","03.javascript\u002F04.react\u002F06.redux\u002F03.transition-to-rtk",[2506],{"title":2507,"path":2508,"stem":2509},"Проблеми класичного Redux","\u002Fjavascript\u002Freact\u002Fredux\u002Ftransition-to-rtk\u002Fproblems-with-classic","03.javascript\u002F04.react\u002F06.redux\u002F03.transition-to-rtk\u002F01.problems-with-classic",{"title":2511,"icon":132,"path":2512,"stem":2513,"children":2514,"page":59},"Redux Toolkit","\u002Fjavascript\u002Freact\u002Fredux\u002Fredux-toolkit","03.javascript\u002F04.react\u002F06.redux\u002F04.redux-toolkit",[2515,2519,2523,2527],{"title":2516,"path":2517,"stem":2518},"Налаштування Store з configureStore","\u002Fjavascript\u002Freact\u002Fredux\u002Fredux-toolkit\u002Fconfigure-store","03.javascript\u002F04.react\u002F06.redux\u002F04.redux-toolkit\u002F01.configure-store",{"title":2520,"path":2521,"stem":2522},"createSlice: Революція в Redux","\u002Fjavascript\u002Freact\u002Fredux\u002Fredux-toolkit\u002Fcreate-slice","03.javascript\u002F04.react\u002F06.redux\u002F04.redux-toolkit\u002F02.create-slice",{"title":2524,"path":2525,"stem":2526},"Асинхронність з createAsyncThunk","\u002Fjavascript\u002Freact\u002Fredux\u002Fredux-toolkit\u002Fasync-thunks","03.javascript\u002F04.react\u002F06.redux\u002F04.redux-toolkit\u002F03.async-thunks",{"title":2528,"path":2529,"stem":2530},"04. Entity Adapter: Керування нормалізованим станом","\u002Fjavascript\u002Freact\u002Fredux\u002Fredux-toolkit\u002Fentity-adapter","03.javascript\u002F04.react\u002F06.redux\u002F04.redux-toolkit\u002F04.entity-adapter",{"title":2532,"icon":92,"path":2533,"stem":2534,"children":2535,"page":59},"Advanced","\u002Fjavascript\u002Freact\u002Fredux\u002Fadvanced","03.javascript\u002F04.react\u002F06.redux\u002F05.advanced",[2536,2540,2544],{"title":2537,"path":2538,"stem":2539},"Мемоізація та Селектори: Повний Гайд по Reselect","\u002Fjavascript\u002Freact\u002Fredux\u002Fadvanced\u002Fselectors-reselect","03.javascript\u002F04.react\u002F06.redux\u002F05.advanced\u002F01.selectors-reselect",{"title":2541,"path":2542,"stem":2543},"RTK Query: Архітектура Серверного Кешу","\u002Fjavascript\u002Freact\u002Fredux\u002Fadvanced\u002Frtk-query-intro","03.javascript\u002F04.react\u002F06.redux\u002F05.advanced\u002F02.rtk-query-intro",{"title":2391,"path":2545,"stem":2546},"\u002Fjavascript\u002Freact\u002Fredux\u002Fadvanced\u002Farchitecture-best-practices","03.javascript\u002F04.react\u002F06.redux\u002F05.advanced\u002F03.architecture-best-practices",{"title":2548,"icon":132,"path":2549,"stem":2550,"children":2551,"page":59},"Project Kanban","\u002Fjavascript\u002Freact\u002Fredux\u002Fproject-kanban","03.javascript\u002F04.react\u002F06.redux\u002F06.project-kanban",[2552,2556,2560,2564,2568,2572],{"title":2553,"path":2554,"stem":2555},"Проєкт: Kanban Board (Trello Clone)","\u002Fjavascript\u002Freact\u002Fredux\u002Fproject-kanban\u002Fproject-overview","03.javascript\u002F04.react\u002F06.redux\u002F06.project-kanban\u002F01.project-overview",{"title":2557,"path":2558,"stem":2559},"Налаштування та Типізація","\u002Fjavascript\u002Freact\u002Fredux\u002Fproject-kanban\u002Fsetup-and-types","03.javascript\u002F04.react\u002F06.redux\u002F06.project-kanban\u002F02.setup-and-types",{"title":2561,"path":2562,"stem":2563},"Board Slice: Серце Дошки","\u002Fjavascript\u002Freact\u002Fredux\u002Fproject-kanban\u002Fboard-slice","03.javascript\u002F04.react\u002F06.redux\u002F06.project-kanban\u002F03.board-slice",{"title":2565,"path":2566,"stem":2567},"Логіка Drag & Drop","\u002Fjavascript\u002Freact\u002Fredux\u002Fproject-kanban\u002Fdrag-and-drop-logic","03.javascript\u002F04.react\u002F06.redux\u002F06.project-kanban\u002F04.drag-and-drop-logic",{"title":2569,"path":2570,"stem":2571},"Інтеграція з RTK Query","\u002Fjavascript\u002Freact\u002Fredux\u002Fproject-kanban\u002Frtk-query-integration","03.javascript\u002F04.react\u002F06.redux\u002F06.project-kanban\u002F05.rtk-query-integration",{"title":2573,"path":2574,"stem":2575},"Optimistic Updates","\u002Fjavascript\u002Freact\u002Fredux\u002Fproject-kanban\u002Foptimistic-updates","03.javascript\u002F04.react\u002F06.redux\u002F06.project-kanban\u002F06.optimistic-updates",{"title":2577,"icon":132,"path":2578,"stem":2579,"children":2580,"page":59},"Testing","\u002Fjavascript\u002Freact\u002Fredux\u002Ftesting","03.javascript\u002F04.react\u002F06.redux\u002F07.testing",[2581,2585,2589,2593,2597],{"title":2582,"path":2583,"stem":2584},"Тестування Redux","\u002Fjavascript\u002Freact\u002Fredux\u002Ftesting\u002Fintro-testing","03.javascript\u002F04.react\u002F06.redux\u002F07.testing\u002F01.intro-testing",{"title":2586,"path":2587,"stem":2588},"Тестування Reducers","\u002Fjavascript\u002Freact\u002Fredux\u002Ftesting\u002Ftesting-reducers","03.javascript\u002F04.react\u002F06.redux\u002F07.testing\u002F02.testing-reducers",{"title":2590,"path":2591,"stem":2592},"Тестування Селекторів","\u002Fjavascript\u002Freact\u002Fredux\u002Ftesting\u002Ftesting-selectors","03.javascript\u002F04.react\u002F06.redux\u002F07.testing\u002F03.testing-selectors",{"title":2594,"path":2595,"stem":2596},"Тестування Компонентів (Integration)","\u002Fjavascript\u002Freact\u002Fredux\u002Ftesting\u002Ftesting-components","03.javascript\u002F04.react\u002F06.redux\u002F07.testing\u002F04.testing-components",{"title":2598,"path":2599,"stem":2600},"Тестування Async Thunks","\u002Fjavascript\u002Freact\u002Fredux\u002Ftesting\u002Ftesting-thunks","03.javascript\u002F04.react\u002F06.redux\u002F07.testing\u002F05.testing-thunks",{"title":2602,"icon":132,"path":2603,"stem":2604,"children":2605},"Ui Libraries","\u002Fjavascript\u002Freact\u002Fui-libraries","03.javascript\u002F04.react\u002F07.ui-libraries\u002Findex",[2606,2608,2612,2616,2620,2624,2628],{"title":2607,"path":2603,"stem":2604},"UI Бібліотеки в React",{"title":2609,"path":2610,"stem":2611},"Вступ до UI Бібліотек: Навіщо Винаходити Велосипед Двічі?","\u002Fjavascript\u002Freact\u002Fui-libraries\u002Fintroduction-to-ui-libraries","03.javascript\u002F04.react\u002F07.ui-libraries\u002F01.introduction-to-ui-libraries",{"title":2613,"path":2614,"stem":2615},"Філософія shadcn\u002Fui: \"Not a Component Library\"","\u002Fjavascript\u002Freact\u002Fui-libraries\u002Fshadcn-philosophy","03.javascript\u002F04.react\u002F07.ui-libraries\u002F02.shadcn-philosophy",{"title":2617,"path":2618,"stem":2619},"Установка та Налаштування shadcn\u002Fui","\u002Fjavascript\u002Freact\u002Fui-libraries\u002Fshadcn-installation","03.javascript\u002F04.react\u002F07.ui-libraries\u002F03.shadcn-installation",{"title":2621,"path":2622,"stem":2623},"Базові Компоненти shadcn\u002Fui: Фундамент Інтерфейсу","\u002Fjavascript\u002Freact\u002Fui-libraries\u002Fshadcn-components-basics","03.javascript\u002F04.react\u002F07.ui-libraries\u002F04.shadcn-components-basics",{"title":2625,"path":2626,"stem":2627},"Компоненти Форм: Побудова Інтерактивних Form","\u002Fjavascript\u002Freact\u002Fui-libraries\u002Fshadcn-components-forms","03.javascript\u002F04.react\u002F07.ui-libraries\u002F05.shadcn-components-forms",{"title":2629,"path":2630,"stem":2631},"Складні Компоненти: Dialog, Dropdown, Table та Command","\u002Fjavascript\u002Freact\u002Fui-libraries\u002Fshadcn-components-advanced","03.javascript\u002F04.react\u002F07.ui-libraries\u002F06.shadcn-components-advanced",{"title":2633,"icon":2634,"path":2635,"stem":2636,"children":2637,"page":59},"TypeScript","i-devicon-typescript","\u002Fjavascript\u002Ftypescript","03.javascript\u002F05.typescript",[2638,2642,2646,2650,2654,2658,2662,2666],{"title":2639,"path":2640,"stem":2641},"TypeScript: Броня для вашого коду","\u002Fjavascript\u002Ftypescript\u002Fintro-and-basic-types","03.javascript\u002F05.typescript\u002F01.intro-and-basic-types",{"title":2643,"path":2644,"stem":2645},"Майстерність Моделювання Даних: Інтерфейси та Просунуті Типи","\u002Fjavascript\u002Ftypescript\u002Finterfaces-and-advanced-types","03.javascript\u002F05.typescript\u002F02.interfaces-and-advanced-types",{"title":2647,"path":2648,"stem":2649},"Алхімія Типів: Generics та Utility Types","\u002Fjavascript\u002Ftypescript\u002Fgenerics-and-utilities","03.javascript\u002F05.typescript\u002F03.generics-and-utilities",{"title":2651,"path":2652,"stem":2653},"Архітектура та Шаблони: Класи в TypeScript","\u002Fjavascript\u002Ftypescript\u002Fclasses-and-oop","03.javascript\u002F05.typescript\u002F04.classes-and-oop",{"title":2655,"path":2656,"stem":2657},"Продакшн та Екосистема: Advanced Config & Workflow","\u002Fjavascript\u002Ftypescript\u002Fadvanced-patterns-and-config","03.javascript\u002F05.typescript\u002F05.advanced-patterns-and-config",{"title":2659,"path":2660,"stem":2661},"TypeScript у світі React","\u002Fjavascript\u002Ftypescript\u002Freact-basics","03.javascript\u002F05.typescript\u002F06.react-basics",{"title":2663,"path":2664,"stem":2665},"React + TypeScript: Продвинуті патерни","\u002Fjavascript\u002Ftypescript\u002Freact-advanced","03.javascript\u002F05.typescript\u002F07.react-advanced",{"title":2667,"path":2668,"stem":2669},"React + TypeScript: Екосистема та бібліотеки","\u002Fjavascript\u002Ftypescript\u002Freact-ecosystem","03.javascript\u002F05.typescript\u002F08.react-ecosystem",{"title":2671,"icon":2672,"path":2673,"stem":2674,"children":2675,"page":59},"Асинхронність","i-lucide-refresh-cw","\u002Fjavascript\u002Fasync-programming","03.javascript\u002F06.async-programming",[2676,2680,2684],{"title":2677,"path":2678,"stem":2679},"Event Loop: серце асинхронності в JavaScript","\u002Fjavascript\u002Fasync-programming\u002Fevent-loop-fundamentals","03.javascript\u002F06.async-programming\u002F01.event-loop-fundamentals",{"title":2681,"path":2682,"stem":2683},"Task Queue та Microtask Queue: пріоритети виконання","\u002Fjavascript\u002Fasync-programming\u002Ftask-queues","03.javascript\u002F06.async-programming\u002F02.task-queues",{"title":2685,"path":2686,"stem":2687},"Асинхронні патерни: від Callbacks до Async\u002FAwait","\u002Fjavascript\u002Fasync-programming\u002Fasync-patterns","03.javascript\u002F06.async-programming\u002F03.async-patterns",{"title":2689,"path":2690,"stem":2691},"Atomic Design","\u002Fjavascript\u002Fatomic-design","03.javascript\u002F2.atomic-design",{"title":2693,"icon":2694,"path":2695,"stem":2696,"children":2697,"page":59},"Java","i-devicon-java","\u002Fjava","04.java",[2698,2701,2704,2708,2712,2716,2720],{"title":162,"path":2699,"stem":2700},"\u002Fjava\u002Fdata-mapper-part1","04.java\u002F01.data-mapper-part1",{"title":166,"path":2702,"stem":2703},"\u002Fjava\u002Fdata-mapper-part2","04.java\u002F02.data-mapper-part2",{"title":2705,"path":2706,"stem":2707},"Service Layer: Організація бізнес-логіки","\u002Fjava\u002Fservice-layer","04.java\u002F03.service-layer",{"title":2709,"path":2710,"stem":2711},"Rich Domain Model та State Pattern","\u002Fjava\u002Frich-domain-model","04.java\u002F04.rich-domain-model",{"title":2713,"path":2714,"stem":2715},"Патерни для складної бізнес-логіки","\u002Fjava\u002Fbusiness-logic-patterns","04.java\u002F05.business-logic-patterns",{"title":2717,"path":2718,"stem":2719},"Обробка помилок та валідація","\u002Fjava\u002Ferror-handling-validation","04.java\u002F06.error-handling-validation",{"title":2721,"path":2722,"stem":2723,"children":2724,"page":59},"Проектування баз даних","\u002Fjava\u002Fpr2","04.java\u002Fpr2",[2725,2729,2733,2737,2741,2745,2749,2753,2757,2761,2765,2769,2773,2777,2781,2785,2789,2793,2797,2801,2805,2809,2813,2817,2821,2825,2829,2833,2837,2841,2845,2849,2853,2857,2861,2865,2869],{"title":2726,"path":2727,"stem":2728},"Концептуальне моделювання: Мистецтво розуміння предметної області","\u002Fjava\u002Fpr2\u002Fconceptual-modeling","04.java\u002Fpr2\u002F01.conceptual-modeling",{"title":2730,"path":2731,"stem":2732},"Логічне моделювання: Від бізнес-ідей до структур даних","\u002Fjava\u002Fpr2\u002Flogical-modeling","04.java\u002Fpr2\u002F02.logical-modeling",{"title":2734,"path":2735,"stem":2736},"Нормалізація: Гігієна даних та боротьба з аномаліями","\u002Fjava\u002Fpr2\u002Fnormalization","04.java\u002Fpr2\u002F03.normalization",{"title":2738,"path":2739,"stem":2740},"Фізична схема: Від абстракції до DDL","\u002Fjava\u002Fpr2\u002Fphysical-schema","04.java\u002Fpr2\u002F04.physical-schema",{"title":2742,"path":2743,"stem":2744},"Архітектурна класифікація таблиць","\u002Fjava\u002Fpr2\u002Ftable-classification","04.java\u002Fpr2\u002F05.table-classification",{"title":2746,"path":2747,"stem":2748},"Database Migrations: Версіонування схеми з Flyway","\u002Fjava\u002Fpr2\u002Fdatabase-migrations","04.java\u002Fpr2\u002F06.database-migrations",{"title":2750,"path":2751,"stem":2752},"А що, якби це була не реляційна БД?","\u002Fjava\u002Fpr2\u002Fbeyond-relational","04.java\u002Fpr2\u002F07.beyond-relational",{"title":2754,"path":2755,"stem":2756},"Object-Relational Impedance Mismatch: Два світи, що не хочуть дружити","\u002Fjava\u002Fpr2\u002Fimpedance-mismatch","04.java\u002Fpr2\u002F09.impedance-mismatch",{"title":2758,"path":2759,"stem":2760},"JDBC: Перший контакт із базою даних","\u002Fjava\u002Fpr2\u002Fjdbc-fundamentals","04.java\u002Fpr2\u002F10.jdbc-fundamentals",{"title":2762,"path":2763,"stem":2764},"Якість коду: Spotless, SpotBugs та SonarQube","\u002Fjava\u002Fpr2\u002F10a.code-quality","04.java\u002Fpr2\u002F10a.code-quality",{"title":2766,"path":2767,"stem":2768},"Connection Pool: Патерн Object Pool для JDBC-з'єднань","\u002Fjava\u002Fpr2\u002Fconnection-pool","04.java\u002Fpr2\u002F11.connection-pool",{"title":2770,"path":2771,"stem":2772},"Row Data Gateway: Об'єкт як обгортка рядка таблиці","\u002Fjava\u002Fpr2\u002Frow-data-gateway","04.java\u002Fpr2\u002F12.row-data-gateway",{"title":2774,"path":2775,"stem":2776},"Table Data Gateway: Фасад таблиці як архітектурний відступ","\u002Fjava\u002Fpr2\u002Ftable-data-gateway","04.java\u002Fpr2\u002F13.table-data-gateway",{"title":2778,"path":2779,"stem":2780},"Repository + Data Mapper: Правильна шарова архітектура з JDBC","\u002Fjava\u002Fpr2\u002Frepository-data-mapper","04.java\u002Fpr2\u002F14.repository-data-mapper",{"title":2782,"path":2783,"stem":2784},"Identity Map: Кешування сутностей у рамках сесії","\u002Fjava\u002Fpr2\u002Fidentity-map","04.java\u002Fpr2\u002F15.identity-map",{"title":2786,"path":2787,"stem":2788},"Unit of Work: Відстеження змін і координація JDBC-транзакцій","\u002Fjava\u002Fpr2\u002Funit-of-work","04.java\u002Fpr2\u002F16.unit-of-work",{"title":2790,"path":2791,"stem":2792},"Strategy: Замінювані SQL-стратегії для підтримки різних СУБД","\u002Fjava\u002Fpr2\u002Fstrategy-sql","04.java\u002Fpr2\u002F17.strategy-sql",{"title":2794,"path":2795,"stem":2796},"Proxy: Lazy Loading для One-To-Many колекцій","\u002Fjava\u002Fpr2\u002Fproxy-lazy-loading","04.java\u002Fpr2\u002F18.proxy-lazy-loading",{"title":2798,"path":2799,"stem":2800},"Generic Repository через Java Reflection: анотації та динамічний SQL","\u002Fjava\u002Fpr2\u002Fgeneric-repository-reflection","04.java\u002Fpr2\u002F19.generic-repository-reflection",{"title":2802,"path":2803,"stem":2804},"Specification Pattern: Композиція бізнес-правил для складних запитів","\u002Fjava\u002Fpr2\u002Fspecification-pattern","04.java\u002Fpr2\u002F20.specification-pattern",{"title":2806,"path":2807,"stem":2808},"Розширені можливості Specification Pattern: підзапити, агрегації та гібридний підхід","\u002Fjava\u002Fpr2\u002F20a.advanced-specifications","04.java\u002Fpr2\u002F20a.advanced-specifications",{"title":2810,"path":2811,"stem":2812},"Асинхронність у JDBC: Від блокуючих викликів до CompletableFuture","\u002Fjava\u002Fpr2\u002Fasynchronous-jdbc","04.java\u002Fpr2\u002F21.asynchronous-jdbc",{"title":2814,"path":2815,"stem":2816},"Інтеграційне тестування JDBC-репозиторіїв: Embedded H2 та патерн AAA","\u002Fjava\u002Fpr2\u002Fintegration-testing-h2","04.java\u002Fpr2\u002F22.integration-testing-h2",{"title":2818,"path":2819,"stem":2820},"Testcontainers: Тестування з реальною PostgreSQL у Docker-контейнерах","\u002Fjava\u002Fpr2\u002Fintegration-testing-testcontainers","04.java\u002Fpr2\u002F23.integration-testing-testcontainers",{"title":2822,"path":2823,"stem":2824},"Google Guice: Впровадження залежностей у JavaFX-проєкті","\u002Fjava\u002Fpr2\u002Fdependency-injection-guice","04.java\u002Fpr2\u002F24.dependency-injection-guice",{"title":2826,"path":2827,"stem":2828},"JavaFX: Основи побудови графічних інтерфейсів","\u002Fjava\u002Fpr2\u002Fjavafx-fundamentals","04.java\u002Fpr2\u002F25.javafx-fundamentals",{"title":2830,"path":2831,"stem":2832},"Properties та Bindings: Реактивність у JavaFX","\u002Fjava\u002Fpr2\u002Fjavafx-properties-bindings","04.java\u002Fpr2\u002F26.javafx-properties-bindings",{"title":2834,"path":2835,"stem":2836},"MVC vs MVP vs MVVM: Еволюція архітектурних патернів UI","\u002Fjava\u002Fpr2\u002Fui-architecture-patterns","04.java\u002Fpr2\u002F27.ui-architecture-patterns",{"title":2838,"path":2839,"stem":2840},"MVVM на практиці: Побудова ViewModel","\u002Fjava\u002Fpr2\u002Fmvvm-viewmodel-implementation","04.java\u002Fpr2\u002F28.mvvm-viewmodel-implementation",{"title":2842,"path":2843,"stem":2844},"View та Controller: Зв'язування з ViewModel через FXML","\u002Fjava\u002Fpr2\u002Fmvvm-view-controller","04.java\u002Fpr2\u002F29.mvvm-view-controller",{"title":2846,"path":2847,"stem":2848},"Інтеграція MVVM з Guice: Автоматична ін'єкція залежностей","\u002Fjava\u002Fpr2\u002Fmvvm-guice-integration","04.java\u002Fpr2\u002F30.mvvm-guice-integration",{"title":2850,"path":2851,"stem":2852},"Валідація та обробка помилок у MVVM","\u002Fjava\u002Fpr2\u002Fmvvm-validation-error-handling","04.java\u002Fpr2\u002F31.mvvm-validation-error-handling",{"title":2854,"path":2855,"stem":2856},"Навігація та управління екранами у JavaFX MVVM","\u002Fjava\u002Fpr2\u002Fmvvm-navigation-screen-management","04.java\u002Fpr2\u002F32.mvvm-navigation-screen-management",{"title":2858,"path":2859,"stem":2860},"Тестування JavaFX MVVM-додатків","\u002Fjava\u002Fpr2\u002Fmvvm-testing","04.java\u002Fpr2\u002F33.mvvm-testing",{"title":2862,"path":2863,"stem":2864},"Стилізація та теми у JavaFX: CSS та User Experience","\u002Fjava\u002Fpr2\u002Fjavafx-styling-themes","04.java\u002Fpr2\u002F34.javafx-styling-themes",{"title":2866,"path":2867,"stem":2868},"AtlantaFX: Сучасні теми для JavaFX додатків","\u002Fjava\u002Fpr2\u002Fatlantafx-modern-themes","04.java\u002Fpr2\u002F35.atlantafx-modern-themes",{"title":2870,"path":2871,"stem":2872},"Пакування та розповсюдження JavaFX-додатків","\u002Fjava\u002Fpr2\u002Fjar-packaging-distribution","04.java\u002Fpr2\u002F36.jar-packaging-distribution",{"title":2874,"icon":2875,"path":2876,"stem":2877,"children":2878,"page":59},"Python","i-devicon-python","\u002Fpython","05.python",[2879,2921,2980],{"title":2880,"icon":2881,"path":2882,"stem":2883,"children":2884,"page":59},"Python Core","i-lucide-code","\u002Fpython\u002Fcore","05.python\u002F01.core",[2885,2889,2893,2897,2901,2905,2909,2913,2917],{"title":2886,"path":2887,"stem":2888},"Як комп'ютер виконує програму","\u002Fpython\u002Fcore\u002Fhow-computers-run-programs","05.python\u002F01.core\u002F00.how-computers-run-programs",{"title":2890,"path":2891,"stem":2892},"Перша програма і функція print","\u002Fpython\u002Fcore\u002Ffirst-program-print","05.python\u002F01.core\u002F01.first-program-print",{"title":2894,"path":2895,"stem":2896},"Об'єкти, значення і типи","\u002Fpython\u002Fcore\u002Fobjects-values-types","05.python\u002F01.core\u002F02.objects-values-types",{"title":2898,"path":2899,"stem":2900},"Змінні — імена, посилання, ідентичність","\u002Fpython\u002Fcore\u002Fvariables-names-references","05.python\u002F01.core\u002F03.variables-names-references",{"title":2902,"path":2903,"stem":2904},"Вирази, оператори, введення і перетворення типів","\u002Fpython\u002Fcore\u002Fexpressions-input-types","05.python\u002F01.core\u002F04.expressions-input-types",{"title":2906,"path":2907,"stem":2908},"Логіка та розгалуження","\u002Fpython\u002Fcore\u002Flogic-branching","05.python\u002F01.core\u002F05.logic-branching",{"title":2910,"path":2911,"stem":2912},"Цикли та ітерація","\u002Fpython\u002Fcore\u002Floops-iteration","05.python\u002F01.core\u002F06.loops-iteration",{"title":2914,"path":2915,"stem":2916},"Налагодження (debugging)","\u002Fpython\u002Fcore\u002Fdebugging","05.python\u002F01.core\u002F07.debugging",{"title":2918,"path":2919,"stem":2920},"Рядки і текст","\u002Fpython\u002Fcore\u002Fstrings-text","05.python\u002F01.core\u002F08.strings-text",{"title":2532,"path":2922,"stem":2923,"children":2924,"page":59},"\u002Fpython\u002Fadvanced","05.python\u002F02.advanced",[2925,2929,2932,2936,2940,2944,2948,2952,2956,2960,2964,2968,2972,2976],{"title":2926,"path":2927,"stem":2928},"Модулі, Пакети та Віртуальні Середовища","\u002Fpython\u002Fadvanced\u002Fmodules-packages-venv","05.python\u002F02.advanced\u002F00.modules-packages-venv",{"title":71,"path":2930,"stem":2931},"\u002Fpython\u002Fadvanced\u002Fclasses-objects","05.python\u002F02.advanced\u002F01.classes-objects",{"title":2933,"path":2934,"stem":2935},"Інкапсуляція, Керування Доступом та Властивості","\u002Fpython\u002Fadvanced\u002Fencapsulation","05.python\u002F02.advanced\u002F02.encapsulation",{"title":2937,"path":2938,"stem":2939},"Наслідування, MRO та суперсила super()","\u002Fpython\u002Fadvanced\u002Finheritance-mro","05.python\u002F02.advanced\u002F03.inheritance-mro",{"title":2941,"path":2942,"stem":2943},"Абстракція — ABC проти Статичних Протоколів (PEP 544)","\u002Fpython\u002Fadvanced\u002Fabstraction-protocols","05.python\u002F02.advanced\u002F04.abstraction-protocols",{"title":2945,"path":2946,"stem":2947},"Магічні методи (Dunder) та Емуляція протоколів","\u002Fpython\u002Fadvanced\u002Fdunder-methods","05.python\u002F02.advanced\u002F05.dunder-methods",{"title":2949,"path":2950,"stem":2951},"Декоратори та Керування життєвим циклом методів","\u002Fpython\u002Fadvanced\u002Fdecorators-static-class","05.python\u002F02.advanced\u002F06.decorators-static-class",{"title":2953,"path":2954,"stem":2955},"Дескриптори — Магія доступу до атрибутів","\u002Fpython\u002Fadvanced\u002Fdescriptors","05.python\u002F02.advanced\u002F07.descriptors",{"title":2957,"path":2958,"stem":2959},"Метакласи — Динамічне створення класів під капотом CPython","\u002Fpython\u002Fadvanced\u002Fmetaclasses","05.python\u002F02.advanced\u002F08.metaclasses",{"title":2961,"path":2962,"stem":2963},"Dataclasses, NamedTuple та сучасні контейнери Python","\u002Fpython\u002Fadvanced\u002Fmodern-containers","05.python\u002F02.advanced\u002F09.modern-containers",{"title":2965,"path":2966,"stem":2967},"GIL та модель конкурентності CPython — фундамент перед потоками і процесами","\u002Fpython\u002Fadvanced\u002Fgil-concurrency-intro","05.python\u002F02.advanced\u002F11.gil-concurrency-intro",{"title":2969,"path":2970,"stem":2971},"Threading — конкурентність для I\u002FO-bound задач","\u002Fpython\u002Fadvanced\u002Fthreading","05.python\u002F02.advanced\u002F12.threading",{"title":2973,"path":2974,"stem":2975},"Multiprocessing — справжній паралелізм для CPU-bound задач","\u002Fpython\u002Fadvanced\u002Fmultiprocessing","05.python\u002F02.advanced\u002F13.multiprocessing",{"title":2977,"path":2978,"stem":2979},"asyncio — кооперативна конкурентність та event loop","\u002Fpython\u002Fadvanced\u002Fasyncio","05.python\u002F02.advanced\u002F14.asyncio",{"title":2981,"icon":92,"path":2982,"stem":2983,"children":2984,"page":59},"FastAPI","\u002Fpython\u002Ffastapi","05.python\u002F03.fastapi",[2985,2989,2993,2997,3001,3005,3009,3013,3017,3021,3025,3029,3033,3037],{"title":2986,"path":2987,"stem":2988},"Глибокий Typing та Pydantic v2 — від анотацій до валідації","\u002Fpython\u002Ffastapi\u002Ftyping-pydantic","05.python\u002F03.fastapi\u002F15.typing-pydantic",{"title":2990,"path":2991,"stem":2992},"WSGI, ASGI та Python Web-екосистема","\u002Fpython\u002Ffastapi\u002Fwsgi-asgi-ecosystem","05.python\u002F03.fastapi\u002F16.wsgi-asgi-ecosystem",{"title":2994,"path":2995,"stem":2996},"FastAPI: Перший додаток, Uvicorn та OpenAPI","\u002Fpython\u002Ffastapi\u002Ffastapi-intro","05.python\u002F03.fastapi\u002F17.fastapi-intro",{"title":2998,"path":2999,"stem":3000},"Маршрутизація, параметри запитів та APIRouter","\u002Fpython\u002Ffastapi\u002Ffastapi-routing-params","05.python\u002F03.fastapi\u002F18.fastapi-routing-params",{"title":3002,"path":3003,"stem":3004},"Pydantic v2 у FastAPI — схеми, валідація та серіалізація","\u002Fpython\u002Ffastapi\u002Ffastapi-pydantic-schemas","05.python\u002F03.fastapi\u002F19.fastapi-pydantic-schemas",{"title":3006,"path":3007,"stem":3008},"Dependency Injection — серце архітектури FastAPI","\u002Fpython\u002Ffastapi\u002Ffastapi-dependency-injection","05.python\u002F03.fastapi\u002F20.fastapi-dependency-injection",{"title":3010,"path":3011,"stem":3012},"Обробка помилок, Middleware та CORS у FastAPI","\u002Fpython\u002Ffastapi\u002Ffastapi-errors-middleware","05.python\u002F03.fastapi\u002F21.fastapi-errors-middleware",{"title":3014,"path":3015,"stem":3016},"SQLAlchemy 2.0 — ORM, Core та Async Engine","\u002Fpython\u002Ffastapi\u002Fsqlalchemy-orm","05.python\u002F03.fastapi\u002F22.sqlalchemy-orm",{"title":3018,"path":3019,"stem":3020},"Alembic — міграції бази даних","\u002Fpython\u002Ffastapi\u002Falembic-migrations","05.python\u002F03.fastapi\u002F23.alembic-migrations",{"title":3022,"path":3023,"stem":3024},"Repository Pattern та Clean Architecture у FastAPI","\u002Fpython\u002Ffastapi\u002Ffastapi-repository-clean-arch","05.python\u002F03.fastapi\u002F24.fastapi-repository-clean-arch",{"title":3026,"path":3027,"stem":3028},"Автентифікація та авторизація — JWT, OAuth2, RBAC","\u002Fpython\u002Ffastapi\u002Ffastapi-auth-security","05.python\u002F03.fastapi\u002F25.fastapi-auth-security",{"title":3030,"path":3031,"stem":3032},"Тестування FastAPI — pytest, httpx, fixtures","\u002Fpython\u002Ffastapi\u002Ffastapi-testing","05.python\u002F03.fastapi\u002F26.fastapi-testing",{"title":3034,"path":3035,"stem":3036},"Async на повну — Background Tasks, WebSockets, SSE та Celery","\u002Fpython\u002Ffastapi\u002Ffastapi-async-advanced","05.python\u002F03.fastapi\u002F27.fastapi-async-advanced",{"title":3038,"path":3039,"stem":3040},"Deployment — Docker, CI\u002FCD, Monitoring","\u002Fpython\u002Ffastapi\u002Ffastapi-deployment","05.python\u002F03.fastapi\u002F28.fastapi-deployment",{"title":3042,"icon":3043,"path":3044,"stem":3045,"children":3046,"page":59},"Бази даних","i-lucide-database","\u002Fdatabases","06.databases",[3047,3077,3100,3137,3166,3184,3218,3230,3239],{"title":3048,"icon":3049,"path":3050,"stem":3051,"children":3052,"page":59},"Intro","i-lucide-play","\u002Fdatabases\u002Fintro","06.databases\u002F01.intro",[3053,3057,3061,3065,3069,3073],{"title":3054,"path":3055,"stem":3056},"Введення в теорію баз даних","\u002Fdatabases\u002Fintro\u002Fintroduction-to-databases","06.databases\u002F01.intro\u002F01.introduction-to-databases",{"title":3058,"path":3059,"stem":3060},"Реляційна модель даних","\u002Fdatabases\u002Fintro\u002Frelational-model-theory","06.databases\u002F01.intro\u002F02.relational-model-theory",{"title":3062,"path":3063,"stem":3064},"ER-моделювання","\u002Fdatabases\u002Fintro\u002Fer-modeling","06.databases\u002F01.intro\u002F03.er-modeling",{"title":3066,"path":3067,"stem":3068},"Логічне проектування БД","\u002Fdatabases\u002Fintro\u002Flogical-schema","06.databases\u002F01.intro\u002F04.logical-schema",{"title":3070,"path":3071,"stem":3072},"Класифікація таблиць","\u002Fdatabases\u002Fintro\u002Ftable-classification","06.databases\u002F01.intro\u002F05.table-classification",{"title":3074,"path":3075,"stem":3076},"PlantUML для баз даних","\u002Fdatabases\u002Fintro\u002Fplantuml-diagrams","06.databases\u002F01.intro\u002F06.plantuml-diagrams",{"title":3078,"icon":3043,"path":3079,"stem":3080,"children":3081,"page":59},"MS SQL Server Start","\u002Fdatabases\u002Fms-sql-server-start","06.databases\u002F02.ms-sql-server-start",[3082,3086,3092,3096],{"title":3083,"path":3084,"stem":3085},"Типи даних у MS SQL Server","\u002Fdatabases\u002Fms-sql-server-start\u002Fdata-types","06.databases\u002F02.ms-sql-server-start\u002F01.data-types",{"title":3087,"path":3088,"stem":3089,"children":3090},"Індекси у MS SQL Server","\u002Fdatabases\u002Fms-sql-server-start\u002Fsql-indexes","06.databases\u002F02.ms-sql-server-start\u002F02.sql-indexes",[3091],{"title":3087,"path":3088,"stem":3089},{"title":3093,"path":3094,"stem":3095},"Системні бази даних MS SQL Server","\u002Fdatabases\u002Fms-sql-server-start\u002Fsystem-databases","06.databases\u002F02.ms-sql-server-start\u002F03.system-databases",{"title":3097,"path":3098,"stem":3099},"Огляд мови SQL та запитів","\u002Fdatabases\u002Fms-sql-server-start\u002Fsql-queries-overview","06.databases\u002F02.ms-sql-server-start\u002F04.sql-queries-overview",{"title":3101,"icon":3043,"path":3102,"stem":3103,"children":3104,"page":59},"SQL","\u002Fdatabases\u002Fsql","06.databases\u002F03.sql",[3105,3109,3113,3117,3121,3125,3129,3133],{"title":3106,"path":3107,"stem":3108},"Налаштування демонстраційної бази даних","\u002Fdatabases\u002Fsql\u002Fsample-database-setup","06.databases\u002F03.sql\u002F00.sample-database-setup",{"title":3110,"path":3111,"stem":3112},"DDL - Створення таблиць (CREATE TABLE)","\u002Fdatabases\u002Fsql\u002Fddl-create-table","06.databases\u002F03.sql\u002F01.ddl-create-table",{"title":3114,"path":3115,"stem":3116},"DDL - Зміна та видалення таблиць (ALTER, DROP)","\u002Fdatabases\u002Fsql\u002Fddl-alter-drop-table","06.databases\u002F03.sql\u002F02.ddl-alter-drop-table",{"title":3118,"path":3119,"stem":3120},"SELECT запити - Основи","\u002Fdatabases\u002Fsql\u002Fselect-queries-fundamentals","06.databases\u002F03.sql\u002F03.select-queries-fundamentals",{"title":3122,"path":3123,"stem":3124},"SELECT запити - Розширені можливості","\u002Fdatabases\u002Fsql\u002Fselect-queries-advanced","06.databases\u002F03.sql\u002F04.select-queries-advanced",{"title":3126,"path":3127,"stem":3128},"INSERT запити - Додавання даних","\u002Fdatabases\u002Fsql\u002Finsert-queries","06.databases\u002F03.sql\u002F05.insert-queries",{"title":3130,"path":3131,"stem":3132},"UPDATE та DELETE запити","\u002Fdatabases\u002Fsql\u002Fupdate-delete-queries","06.databases\u002F03.sql\u002F06.update-delete-queries",{"title":3134,"path":3135,"stem":3136},"Транзакції в SQL","\u002Fdatabases\u002Fsql\u002Ftransactions","06.databases\u002F03.sql\u002F07.transactions",{"title":3138,"icon":3043,"path":3139,"stem":3140,"children":3141,"page":59},"Multi Table Databases","\u002Fdatabases\u002Fmulti-table-databases","06.databases\u002F04.multi-table-databases",[3142,3146,3150,3154,3158,3162],{"title":3143,"path":3144,"stem":3145},"Зв'язки та нормалізація БД","\u002Fdatabases\u002Fmulti-table-databases\u002Frelationships-and-normalization","06.databases\u002F04.multi-table-databases\u002F00.relationships-and-normalization",{"title":3147,"path":3148,"stem":3149},"INNER JOIN - З'єднання таблиць","\u002Fdatabases\u002Fmulti-table-databases\u002Finner-join","06.databases\u002F04.multi-table-databases\u002F01.inner-join",{"title":3151,"path":3152,"stem":3153},"OUTER JOINs - LEFT, RIGHT, FULL","\u002Fdatabases\u002Fmulti-table-databases\u002Fouter-joins","06.databases\u002F04.multi-table-databases\u002F02.outer-joins",{"title":3155,"path":3156,"stem":3157},"CROSS та SELF JOINs","\u002Fdatabases\u002Fmulti-table-databases\u002Fcross-self-joins","06.databases\u002F04.multi-table-databases\u002F03.cross-self-joins",{"title":3159,"path":3160,"stem":3161},"Підзапити (Subqueries)","\u002Fdatabases\u002Fmulti-table-databases\u002Fsubqueries","06.databases\u002F04.multi-table-databases\u002F04.subqueries",{"title":3163,"path":3164,"stem":3165},"Агрегації з JOIN","\u002Fdatabases\u002Fmulti-table-databases\u002Faggregations-with-joins","06.databases\u002F04.multi-table-databases\u002F05.aggregations-with-joins",{"title":3167,"icon":3168,"path":3169,"stem":3170,"children":3171,"page":59},"Aggregate Functions","i-lucide-calculator","\u002Fdatabases\u002Faggregate-functions","06.databases\u002F05.aggregate-functions",[3172,3176,3180],{"title":3173,"path":3174,"stem":3175},"Функції агрегування в MS SQL Server","\u002Fdatabases\u002Faggregate-functions\u002Fintroduction-aggregate-functions","06.databases\u002F05.aggregate-functions\u002F01.introduction-aggregate-functions",{"title":3177,"path":3178,"stem":3179},"Групування даних в MS SQL Server","\u002Fdatabases\u002Faggregate-functions\u002Fgrouping-data","06.databases\u002F05.aggregate-functions\u002F02.grouping-data",{"title":3181,"path":3182,"stem":3183},"Підзапити з агрегатними функціями","\u002Fdatabases\u002Faggregate-functions\u002Fsubqueries-aggregates","06.databases\u002F05.aggregate-functions\u002F03.subqueries-aggregates",{"title":3185,"icon":3186,"path":3187,"stem":3188,"children":3189,"page":59},"Тригери та зберігаємі процедури","i-lucide-database-zap","\u002Fdatabases\u002Ftriggers-stored-procedures","06.databases\u002F07.triggers-stored-procedures",[3190,3194,3198,3202,3206,3210,3214],{"title":3191,"path":3192,"stem":3193},"DML-тригери","\u002Fdatabases\u002Ftriggers-stored-procedures\u002Fdml-triggers","06.databases\u002F07.triggers-stored-procedures\u002F01.dml-triggers",{"title":3195,"path":3196,"stem":3197},"DDL-тригери","\u002Fdatabases\u002Ftriggers-stored-procedures\u002Fddl-triggers","06.databases\u002F07.triggers-stored-procedures\u002F02.ddl-triggers",{"title":3199,"path":3200,"stem":3201},"Transact-SQL розширення","\u002Fdatabases\u002Ftriggers-stored-procedures\u002Ftransact-sql-extensions","06.databases\u002F07.triggers-stored-procedures\u002F03.transact-sql-extensions",{"title":3203,"path":3204,"stem":3205},"Транзакції","\u002Fdatabases\u002Ftriggers-stored-procedures\u002Ftransactions","06.databases\u002F07.triggers-stored-procedures\u002F04.transactions",{"title":3207,"path":3208,"stem":3209},"Зберігаємі процедури","\u002Fdatabases\u002Ftriggers-stored-procedures\u002Fstored-procedures","06.databases\u002F07.triggers-stored-procedures\u002F05.stored-procedures",{"title":3211,"path":3212,"stem":3213},"Користувацькі функції","\u002Fdatabases\u002Ftriggers-stored-procedures\u002Fuser-defined-functions","06.databases\u002F07.triggers-stored-procedures\u002F06.user-defined-functions",{"title":3215,"path":3216,"stem":3217},"Безпека баз даних","\u002Fdatabases\u002Ftriggers-stored-procedures\u002Fsecurity","06.databases\u002F07.triggers-stored-procedures\u002F08.security",{"title":3215,"icon":793,"path":3219,"stem":3220,"children":3221,"page":59},"\u002Fdatabases\u002Fsecurity","06.databases\u002F08.security",[3222,3226],{"title":3223,"path":3224,"stem":3225},"Вступ до безпеки баз даних","\u002Fdatabases\u002Fsecurity\u002Fintroduction","06.databases\u002F08.security\u002F01.introduction",{"title":3227,"path":3228,"stem":3229},"Системні представлення та метадані","\u002Fdatabases\u002Fsecurity\u002Fsystem-views","06.databases\u002F08.security\u002F02.system-views",{"title":3231,"icon":3232,"path":3233,"stem":3234,"children":3235,"page":59},"Резервне копіювання та відновлення","i-lucide-database-backup","\u002Fdatabases\u002Fbackup-recovery","06.databases\u002F09.backup-recovery",[3236],{"title":3231,"path":3237,"stem":3238},"\u002Fdatabases\u002Fbackup-recovery\u002Fbackup-restore","06.databases\u002F09.backup-recovery\u002F01.backup-restore",{"title":3240,"icon":3241,"path":3242,"stem":3243,"children":3244,"page":59},"Повнотекстовий пошук","i-lucide-search","\u002Fdatabases\u002Ffull-text-search","06.databases\u002F10.full-text-search",[3245],{"title":3240,"path":3246,"stem":3247},"\u002Fdatabases\u002Ffull-text-search\u002Ffull-text-search","06.databases\u002F10.full-text-search\u002F01.full-text-search",{"title":3249,"icon":3250,"path":3251,"stem":3252,"children":3253,"page":59},"Tools","i-lucide-wrench","\u002Ftools","07.tools",[3254,3330],{"title":3255,"icon":3256,"path":3257,"stem":3258,"children":3259},"Docker","i-simple-icons-docker","\u002Ftools\u002Fdocker","07.tools\u002F01.docker\u002Findex",[3260,3262,3266,3270,3274,3278,3282,3286,3290,3294,3298,3302,3306,3310,3314,3318,3322,3326],{"title":3261,"path":3257,"stem":3258},"Docker: від нуля до production",{"title":3263,"path":3264,"stem":3265},"Контейнеризація — від проблеми до рішення","\u002Ftools\u002Fdocker\u002Fcontainerization-concept","07.tools\u002F01.docker\u002F01.containerization-concept",{"title":3267,"path":3268,"stem":3269},"Docker — що це і навіщо?","\u002Ftools\u002Fdocker\u002Fdocker-what-and-why","07.tools\u002F01.docker\u002F02.docker-what-and-why",{"title":3271,"path":3272,"stem":3273},"Архітектура Docker Engine","\u002Ftools\u002Fdocker\u002Fdocker-architecture","07.tools\u002F01.docker\u002F03.docker-architecture",{"title":3275,"path":3276,"stem":3277},"Встановлення Docker","\u002Ftools\u002Fdocker\u002Finstallation","07.tools\u002F01.docker\u002F04.installation",{"title":3279,"path":3280,"stem":3281},"Перший контейнер — docker run","\u002Ftools\u002Fdocker\u002Ffirst-container","07.tools\u002F01.docker\u002F05.first-container",{"title":3283,"path":3284,"stem":3285},"Життєвий цикл контейнера","\u002Ftools\u002Fdocker\u002Fcontainer-lifecycle","07.tools\u002F01.docker\u002F06.container-lifecycle",{"title":3287,"path":3288,"stem":3289},"Docker Images — фундаментальні концепції","\u002Ftools\u002Fdocker\u002Fdocker-images-fundamentals","07.tools\u002F01.docker\u002F07.docker-images-fundamentals",{"title":3291,"path":3292,"stem":3293},"Dockerfile — основи","\u002Ftools\u002Fdocker\u002Fdockerfile-basics","07.tools\u002F01.docker\u002F08.dockerfile-basics",{"title":3295,"path":3296,"stem":3297},"Dockerfile — просунуті техніки","\u002Ftools\u002Fdocker\u002Fdockerfile-advanced","07.tools\u002F01.docker\u002F09.dockerfile-advanced",{"title":3299,"path":3300,"stem":3301},"Build Context та кешування шарів","\u002Ftools\u002Fdocker\u002Fbuild-context-and-cache","07.tools\u002F01.docker\u002F10.build-context-and-cache",{"title":3303,"path":3304,"stem":3305},"Реєстри Docker-образів","\u002Ftools\u002Fdocker\u002Fimage-registries","07.tools\u002F01.docker\u002F11.image-registries",{"title":3307,"path":3308,"stem":3309},"Контейнеризація .NET додатків","\u002Ftools\u002Fdocker\u002Fdotnet-containerization","07.tools\u002F01.docker\u002F12.dotnet-containerization",{"title":3311,"path":3312,"stem":3313},"Томи та збереження даних","\u002Ftools\u002Fdocker\u002Fvolumes-and-data","07.tools\u002F01.docker\u002F13.volumes-and-data",{"title":3315,"path":3316,"stem":3317},"Основи мережі в Docker","\u002Ftools\u002Fdocker\u002Fnetworking-basics","07.tools\u002F01.docker\u002F14.networking-basics",{"title":3319,"path":3320,"stem":3321},"Змінні оточення та конфігурація","\u002Ftools\u002Fdocker\u002Fenvironment-and-configuration","07.tools\u002F01.docker\u002F15.environment-and-configuration",{"title":3323,"path":3324,"stem":3325},"Docker Compose — оркестрація контейнерів","\u002Ftools\u002Fdocker\u002Fdocker-compose-basics","07.tools\u002F01.docker\u002F16.docker-compose-basics",{"title":3327,"path":3328,"stem":3329},"Docker Compose — Multi-Service застосунки","\u002Ftools\u002Fdocker\u002Fcompose-multi-service","07.tools\u002F01.docker\u002F17.compose-multi-service",{"title":3331,"icon":3332,"path":3333,"stem":3334,"children":3335},"Kubernetes","simple-icons:kubernetes","\u002Ftools\u002Fkubernetes","07.tools\u002F02.kubernetes\u002Findex",[3336,3338,3342,3346,3350,3354,3358,3362,3366],{"title":3337,"path":3333,"stem":3334},"Kubernetes: від розробки до production",{"title":3339,"path":3340,"stem":3341},"Kubernetes — коли Docker Compose більше не вистачає","\u002Ftools\u002Fkubernetes\u002Fwhy-kubernetes","07.tools\u002F02.kubernetes\u002F01.why-kubernetes",{"title":3343,"path":3344,"stem":3345},"Архітектура Kubernetes — анатомія кластера","\u002Ftools\u002Fkubernetes\u002Fkubernetes-architecture","07.tools\u002F02.kubernetes\u002F02.kubernetes-architecture",{"title":3347,"path":3348,"stem":3349},"Локальне середовище — minikube, kind та k3s","\u002Ftools\u002Fkubernetes\u002Flocal-environment","07.tools\u002F02.kubernetes\u002F03.local-environment",{"title":3351,"path":3352,"stem":3353},"Pod — атомарна одиниця Kubernetes","\u002Ftools\u002Fkubernetes\u002Fpods-and-containers","07.tools\u002F02.kubernetes\u002F04.pods-and-containers",{"title":3355,"path":3356,"stem":3357},"Патерни використання Pod","\u002Ftools\u002Fkubernetes\u002Fpod-patterns","07.tools\u002F02.kubernetes\u002F05.pod-patterns",{"title":3359,"path":3360,"stem":3361},"Deployment — декларативне управління Pod","\u002Ftools\u002Fkubernetes\u002Fdeployment-basics","07.tools\u002F02.kubernetes\u002F06.deployment-basics",{"title":3363,"path":3364,"stem":3365},"Rolling Updates та управління життєвим циклом Deployment","\u002Ftools\u002Fkubernetes\u002Fdeployment-rolling-updates","07.tools\u002F02.kubernetes\u002F07.deployment-rolling-updates",{"title":3367,"path":3368,"stem":3369},"Service — мережева абстракція для Pod","\u002Ftools\u002Fkubernetes\u002Fservices-networking","07.tools\u002F02.kubernetes\u002F08.services-networking",{"title":3371,"icon":3372,"path":3373,"stem":3374,"children":3375,"page":59},"Software Engineering","i-lucide-code-2","\u002Fsoftware-engineering","09.software-engineering",[3376,3380,3384,3388,3392,3396,3400,3404,3408,3412,3416],{"title":3377,"path":3378,"stem":3379},"1. Аналіз предметної області. Експертні знання та складність","\u002Fsoftware-engineering\u002Fintro-subdomains","09.software-engineering\u002F01.intro-subdomains",{"title":3381,"path":3382,"stem":3383},"2. Обмежені контексти. Інтеграція обмежених контекстів","\u002Fsoftware-engineering\u002Fintegrating-limited-contexts","09.software-engineering\u002F02.integrating-limited-contexts",{"title":3385,"path":3386,"stem":3387},"3. Реалізація простої бізнес-логіки","\u002Fsoftware-engineering\u002Fsimple","09.software-engineering\u002F03.simple",{"title":3389,"path":3390,"stem":3391},"4. Опрацювання складної бізнес-логіки","\u002Fsoftware-engineering\u002Fcomplex-business-logic","09.software-engineering\u002F04.complex-business-logic",{"title":3393,"path":3394,"stem":3395},"5. Моделювання фактора часу. Подієво-орієнтована архітектура.","\u002Fsoftware-engineering\u002Fmodelling-the-time-factor","09.software-engineering\u002F05.modelling-the-time-factor",{"title":3397,"path":3398,"stem":3399},"6. Архітектурні патерни","\u002Fsoftware-engineering\u002Farchitectural-patterns","09.software-engineering\u002F06.architectural-patterns",{"title":3401,"path":3402,"stem":3403},"Паттерни взаємодії","\u002Fsoftware-engineering\u002Fpatterns-of-interaction","09.software-engineering\u002F07.patterns-of-interaction",{"title":3405,"path":3406,"stem":3407},"Евристика проєктування","\u002Fsoftware-engineering\u002Fdesign-heuristics","09.software-engineering\u002F08.design-heuristics",{"title":3409,"path":3410,"stem":3411},"Еволюція проєктних рішень","\u002Fsoftware-engineering\u002Fevolution-of-design-solutions","09.software-engineering\u002F09.evolution-of-design-solutions",{"title":3413,"path":3414,"stem":3415},"EventStorming","\u002Fsoftware-engineering\u002Feventstorming","09.software-engineering\u002F10.eventstorming",{"title":3417,"path":3418,"stem":3419},"DDD на практиці","\u002Fsoftware-engineering\u002Fddd-in-practice","09.software-engineering\u002F11.ddd-in-practice",{"title":3421,"icon":943,"path":3422,"stem":3423,"children":3424,"page":59},"DDD","\u002Fddd","10.ddd",[3425,3429,3433,3437,3441,3445,3449,3453,3457,3461,3465,3469,3473],{"title":3426,"path":3427,"stem":3428},"Аналіз предметної області","\u002Fddd\u002Fdomain-analysis","10.ddd\u002F01.domain-analysis",{"title":3430,"path":3431,"stem":3432},"Експертні знання про предметну область","\u002Fddd\u002Fdomain-expert-knowledge","10.ddd\u002F02.domain-expert-knowledge",{"title":3434,"path":3435,"stem":3436},"Як осмислити складність предметної області","\u002Fddd\u002Fmanaging-domain-complexity","10.ddd\u002F03.managing-domain-complexity",{"title":3438,"path":3439,"stem":3440},"Інтеграція обмежених контекстів","\u002Fddd\u002Fbounded-context-integration","10.ddd\u002F04.bounded-context-integration",{"title":3442,"path":3443,"stem":3444},"Реалізація простої бізнес-логіки","\u002Fddd\u002Fsimple-business-logic","10.ddd\u002F05.simple-business-logic",{"title":3446,"path":3447,"stem":3448},"Обробка складної бізнес-логіки","\u002Fddd\u002Fcomplex-business-logic","10.ddd\u002F06.complex-business-logic",{"title":3450,"path":3451,"stem":3452},"Моделювання фактора часу","\u002Fddd\u002Ftime-modeling","10.ddd\u002F07.time-modeling",{"title":3454,"path":3455,"stem":3456},"Глава 8. Архітектурні Патерни","\u002Fddd\u002Farchitectural-patterns","10.ddd\u002F08.architectural-patterns",{"title":3458,"path":3459,"stem":3460},"Глава 9. Патерни Взаємодії","\u002Fddd\u002Finteraction-patterns","10.ddd\u002F09.interaction-patterns",{"title":3462,"path":3463,"stem":3464},"Глава 10. Проектні Евристики","\u002Fddd\u002Fdesign-heuristics","10.ddd\u002F10.design-heuristics",{"title":3466,"path":3467,"stem":3468},"Глава 11. Еволюція Проектних Рішень","\u002Fddd\u002Fevolution-of-design-decisions","10.ddd\u002F11.evolution-of-design-decisions",{"title":3470,"path":3471,"stem":3472},"Глава 12. EventStorming","\u002Fddd\u002Fevent-storming","10.ddd\u002F12.event-storming",{"title":3474,"path":3475,"stem":3476},"Глава 13. DDD на Практиці","\u002Fddd\u002Fddd-in-practice","10.ddd\u002F13.ddd-in-practice",{"title":3478,"icon":3479,"path":3480,"stem":3481,"children":3482,"page":59},"Media Streaming","i-lucide-video","\u002Fmedia-streaming","11.media-streaming",[3483,3487,3491,3495,3499,3503,3507],{"title":3484,"path":3485,"stem":3486},"01. Магія Стрімінгу: Що відбувається, коли ви натискаєте \"Play\"","\u002Fmedia-streaming\u002Fintroduction","11.media-streaming\u002F01.introduction",{"title":3488,"path":3489,"stem":3490},"02. Анатомія Медіа: Кодеки, Контейнери та Стиснення","\u002Fmedia-streaming\u002Faudio-video-anatomy","11.media-streaming\u002F02.audio-video-anatomy",{"title":3492,"path":3493,"stem":3494},"03. The Gym: FFmpeg Deep Dive","\u002Fmedia-streaming\u002Fffmpeg-gym","11.media-streaming\u002F03.ffmpeg-gym",{"title":3496,"path":3497,"stem":3498},"04. HLS Protocol: HTTP Live Streaming у Деталях","\u002Fmedia-streaming\u002Fhls-protocol","11.media-streaming\u002F04.hls-protocol",{"title":3500,"path":3501,"stem":3502},"05. DASH Protocol: Відкритий Стандарт","\u002Fmedia-streaming\u002Fdash-protocol","11.media-streaming\u002F05.dash-protocol",{"title":3504,"path":3505,"stem":3506},"06. Масштабування: CDN та Adaptive Bitrate","\u002Fmedia-streaming\u002Fcdn-and-adaptive-bitrate","11.media-streaming\u002F06.cdn-and-adaptive-bitrate",{"title":3508,"path":3509,"stem":3510},"07. Війна із Затримкою (Latency)","\u002Fmedia-streaming\u002Frealtime-latency","11.media-streaming\u002F07.realtime-latency",{"title":3512,"icon":3513,"path":3514,"stem":3515,"children":3516,"page":59},"HTML & CSS","i-devicon-html5","\u002Fhtml-css","12.html-css",[3517,3521,3525,3529,3533,3537,3541,3545,3549,3553,3557,3561,3565,3569,3573,3577,3581,3585,3589,3593,3597,3601,3605,3609,3613,3617,3621,3625,3629,3633],{"title":3518,"path":3519,"stem":3520},"Вступ до HTML. Структура документа","\u002Fhtml-css\u002Fintro-html-structure","12.html-css\u002F01.intro-html-structure",{"title":3522,"path":3523,"stem":3524},"Форматування тексту в HTML","\u002Fhtml-css\u002Fhtml-text-formatting","12.html-css\u002F02.html-text-formatting",{"title":3526,"path":3527,"stem":3528},"Посилання та зображення в HTML","\u002Fhtml-css\u002Fhtml-links-images","12.html-css\u002F03.html-links-images",{"title":3530,"path":3531,"stem":3532},"Списки та таблиці в HTML","\u002Fhtml-css\u002Fhtml-lists-tables","12.html-css\u002F04.html-lists-tables",{"title":3534,"path":3535,"stem":3536},"Форми в HTML","\u002Fhtml-css\u002Fhtml-forms","12.html-css\u002F05.html-forms",{"title":3538,"path":3539,"stem":3540},"Семантичні елементи HTML5","\u002Fhtml-css\u002Fhtml-semantic-elements","12.html-css\u002F06.html-semantic-elements",{"title":3542,"path":3543,"stem":3544},"Мультимедіа та розширені елементи HTML","\u002Fhtml-css\u002Fhtml-multimedia-advanced","12.html-css\u002F07.html-multimedia-advanced",{"title":3546,"path":3547,"stem":3548},"Мікророзмітка та SEO в HTML","\u002Fhtml-css\u002Fhtml-microdata-seo","12.html-css\u002F08.html-microdata-seo",{"title":3550,"path":3551,"stem":3552},"Вступ до CSS. Селектори та специфічність","\u002Fhtml-css\u002Fcss-intro-selectors","12.html-css\u002F09.css-intro-selectors",{"title":3554,"path":3555,"stem":3556},"Блокова модель CSS. Відступи. Box Sizing","\u002Fhtml-css\u002Fcss-box-model","12.html-css\u002F10.css-box-model",{"title":3558,"path":3559,"stem":3560},"Розміри у CSS: повний довідник одиниць і ключових слів","\u002Fhtml-css\u002F10a.css-sizing","12.html-css\u002F10a.css-sizing",{"title":3562,"path":3563,"stem":3564},"Типографіка в CSS. Шрифти та текст","\u002Fhtml-css\u002Fcss-typography","12.html-css\u002F11.css-typography",{"title":3566,"path":3567,"stem":3568},"Кольори та фони в CSS","\u002Fhtml-css\u002Fcss-colors-backgrounds","12.html-css\u002F12.css-colors-backgrounds",{"title":3570,"path":3571,"stem":3572},"Тіні та фільтри в CSS","\u002Fhtml-css\u002F12b.css-shadows-filters","12.html-css\u002F12b.css-shadows-filters",{"title":3574,"path":3575,"stem":3576},"CSS Flexbox: Фундамент гнучких макетів","\u002Fhtml-css\u002Fcss-flexbox-fundamentals","12.html-css\u002F13.css-flexbox-fundamentals",{"title":3578,"path":3579,"stem":3580},"CSS Flexbox: Вирівнювання та Позиціонування","\u002Fhtml-css\u002Fcss-flexbox-alignment-sizing-and-patterns","12.html-css\u002F14.css-flexbox-alignment-sizing-and-patterns",{"title":3582,"path":3583,"stem":3584},"CSS Grid. Двовимірний макет. Частина 1","\u002Fhtml-css\u002Fcss-layout-grid","12.html-css\u002F15.css-layout-grid",{"title":3586,"path":3587,"stem":3588},"CSS Grid. Двовимірний макет. Частина 2","\u002Fhtml-css\u002Fcss-layout-grid-advanced","12.html-css\u002F16.css-layout-grid-advanced",{"title":3590,"path":3591,"stem":3592},"Позиціонування в CSS. Z-index. Stacking Context","\u002Fhtml-css\u002Fcss-positioning","12.html-css\u002F17.css-positioning",{"title":3594,"path":3595,"stem":3596},"CSS Анімації та Переходи","\u002Fhtml-css\u002Fcss-animations-transitions","12.html-css\u002F18.css-animations-transitions",{"title":3598,"path":3599,"stem":3600},"Адаптивний дизайн. Media Queries. Частина 1","\u002Fhtml-css\u002Fcss-responsive-media-queries","12.html-css\u002F19.css-responsive-media-queries",{"title":3602,"path":3603,"stem":3604},"Адаптивний дизайн. Частина 2: clamp(), Container Queries, @layer","\u002Fhtml-css\u002Fcss-responsive-advanced","12.html-css\u002F20.css-responsive-advanced",{"title":3606,"path":3607,"stem":3608},"CSS Custom Properties. Методології. Сучасний CSS","\u002Fhtml-css\u002Fcss-variables-methodologies","12.html-css\u002F21.css-variables-methodologies",{"title":3610,"path":3611,"stem":3612},"Сучасний CSS 2023–2025: Нові можливості","\u002Fhtml-css\u002Fcss-modern-features","12.html-css\u002F22.css-modern-features",{"title":3614,"path":3615,"stem":3616},"CSS Nesting, @layer, @scope та @property: нативний препроцесор","\u002Fhtml-css\u002F22a.css-nesting-modern-syntax","12.html-css\u002F22a.css-nesting-modern-syntax",{"title":3618,"path":3619,"stem":3620},"CSS для форм та інтерактивних станів","\u002Fhtml-css\u002Fcss-forms-interactive-states","12.html-css\u002F23.css-forms-interactive-states",{"title":3622,"path":3623,"stem":3624},"Доступність у CSS (CSS Accessibility)","\u002Fhtml-css\u002Fcss-accessibility","12.html-css\u002F24.css-accessibility",{"title":3626,"path":3627,"stem":3628},"CSS-функції та сучасні sizing primitives","\u002Fhtml-css\u002Fcss-functions-sizing","12.html-css\u002F25.css-functions-sizing",{"title":3630,"path":3631,"stem":3632},"Rendering Pipeline і CSS Performance","\u002Fhtml-css\u002Fcss-rendering-performance","12.html-css\u002F26.css-rendering-performance",{"title":3634,"path":3635,"stem":3636},"CSS Best Practices: типові ситуації та правильні рішення","\u002Fhtml-css\u002Fcss-best-practices","12.html-css\u002F27.css-best-practices",{"title":3638,"path":3639,"stem":3640,"children":3641,"page":59},"AWS","\u002Faws","13.aws",[3642,3646,3650,3654,3658,3662,3666,3670,3674,3678,3682,3686,3690,3694,3698,3702,3706,3710],{"title":3643,"path":3644,"stem":3645},"Реєстрація AWS акаунту та студентські програми","\u002Faws\u002Faccount-registration","13.aws\u002F00.account-registration",{"title":3647,"path":3648,"stem":3649},"Вступ до хмарних обчислень та AWS","\u002Faws\u002Fintroduction-to-cloud","13.aws\u002F01.introduction-to-cloud",{"title":3651,"path":3652,"stem":3653},"AWS IAM — Identity and Access Management","\u002Faws\u002Fiam","13.aws\u002F02.iam",{"title":3655,"path":3656,"stem":3657},"AWS IAM CLI — Довідник команд","\u002Faws\u002F02a.iam-doc","13.aws\u002F02a.iam-doc",{"title":3659,"path":3660,"stem":3661},"Docker та контейнеризація в AWS — ECR, ECS та Fargate","\u002Faws\u002Fdocker-ecs","13.aws\u002F03.docker-ecs",{"title":3663,"path":3664,"stem":3665},"AWS ECR \u002F ECS CLI — Довідник команд","\u002Faws\u002F03a.docker-ecs-doc","13.aws\u002F03a.docker-ecs-doc",{"title":3667,"path":3668,"stem":3669},"Amazon EC2 — Elastic Compute Cloud","\u002Faws\u002Fec2","13.aws\u002F04.ec2",{"title":3671,"path":3672,"stem":3673},"AWS EC2 CLI — Довідник команд","\u002Faws\u002F04a.ec2-doc","13.aws\u002F04a.ec2-doc",{"title":3675,"path":3676,"stem":3677},"Elastic Load Balancing та Auto Scaling","\u002Faws\u002Falb-asg","13.aws\u002F05.alb-asg",{"title":3679,"path":3680,"stem":3681},"Amazon S3 — Simple Storage Service","\u002Faws\u002Fs3","13.aws\u002F06.s3",{"title":3683,"path":3684,"stem":3685},"Amazon CloudFront — Content Delivery Network","\u002Faws\u002Fcloudfront","13.aws\u002F07.cloudfront",{"title":3687,"path":3688,"stem":3689},"Amazon RDS — Relational Database Service","\u002Faws\u002Frds","13.aws\u002F08.rds",{"title":3691,"path":3692,"stem":3693},"Amazon DynamoDB — NoSQL Database","\u002Faws\u002Fdynamodb","13.aws\u002F09.dynamodb",{"title":3695,"path":3696,"stem":3697},"AWS Lambda та Serverless Compute","\u002Faws\u002Flambda","13.aws\u002F10.lambda",{"title":3699,"path":3700,"stem":3701},"Amazon Bedrock - Foundation Models, RAG та Agents","\u002Faws\u002Fbedrock","13.aws\u002F22.bedrock",{"title":3703,"path":3704,"stem":3705},"Amazon Rekognition - Комп'ютерний зір","\u002Faws\u002Frekognition","13.aws\u002F23.rekognition",{"title":3707,"path":3708,"stem":3709},"Amazon Textract - Інтелектуальний аналіз документів","\u002Faws\u002Ftextract","13.aws\u002F24.textract",{"title":3711,"path":3712,"stem":3713},"Amazon Polly, Transcribe, Comprehend та Translate","\u002Faws\u002Faudio-nlp-services","13.aws\u002F25.audio-nlp-services",{"title":3715,"path":3716,"stem":3717,"children":3718,"page":59},"Ai Development","\u002Fai-development","14.ai-development",[3719],{"title":3720,"path":3721,"stem":3722,"children":3723,"page":59},"Foundations","\u002Fai-development\u002Ffoundations","14.ai-development\u002F00.foundations",[3724],{"title":3725,"path":3726,"stem":3727},"Модуль 0.1. Що таке Large Language Model (LLM)","\u002Fai-development\u002Ffoundations\u002Fwhat-is-llm","14.ai-development\u002F00.foundations\u002F01.what-is-llm",{"title":3729,"path":3730,"stem":3731,"children":3732,"page":59},"React Native","\u002Freact-native","15.react-native",[3733,3754],{"title":3734,"path":3735,"stem":3736,"children":3737,"page":59},"Version1","\u002Freact-native\u002Fversion1","15.react-native\u002Fversion1",[3738,3742,3746,3750],{"title":3739,"path":3740,"stem":3741},"Що таке React Native","\u002Freact-native\u002Fversion1\u002Fwhat-is-react-native","15.react-native\u002Fversion1\u002F01.what-is-react-native",{"title":3743,"path":3744,"stem":3745},"Як влаштований React Native «під капотом»","\u002Freact-native\u002Fversion1\u002Freact-native-architecture","15.react-native\u002Fversion1\u002F02.react-native-architecture",{"title":3747,"path":3748,"stem":3749},"Від React до React Native: ключові відмінності","\u002Freact-native\u002Fversion1\u002Freact-native-vs-react","15.react-native\u002Fversion1\u002F03.react-native-vs-react",{"title":3751,"path":3752,"stem":3753},"View та Text — фундаментальні будівельні блоки","\u002Freact-native\u002Fversion1\u002Fview-and-text","15.react-native\u002Fversion1\u002F04.view-and-text",{"title":3755,"path":3756,"stem":3757,"children":3758,"page":59},"Version2","\u002Freact-native\u002Fversion2","15.react-native\u002Fversion2",[3759,3763,3767,3771,3775,3779,3783,3787,3791,3795,3799,3803,3807,3811,3815,3819,3823,3827,3831,3835,3839,3843,3847,3851,3855,3859,3863],{"title":3760,"path":3761,"stem":3762},"React Native — навіщо він потрібен","\u002Freact-native\u002Fversion2\u002Fwhy-react-native","15.react-native\u002Fversion2\u002F01.why-react-native",{"title":3764,"path":3765,"stem":3766},"Налаштування середовища розробки","\u002Freact-native\u002Fversion2\u002Fenvironment-setup","15.react-native\u002Fversion2\u002F02.environment-setup",{"title":3768,"path":3769,"stem":3770},"Expo і класичний React Native — два шляхи одного фреймворку","\u002Freact-native\u002Fversion2\u002Fexpo-vs-cli-landscape","15.react-native\u002Fversion2\u002F03.expo-vs-cli-landscape",{"title":3772,"path":3773,"stem":3774},"Середовище Expo — перший запуск","\u002Freact-native\u002Fversion2\u002Fexpo-setup-and-tooling","15.react-native\u002Fversion2\u002F04.expo-setup-and-tooling",{"title":3776,"path":3777,"stem":3778},"Структура проєкту та перші UI-примітиви","\u002Freact-native\u002Fversion2\u002Fproject-structure-and-conventions","15.react-native\u002Fversion2\u002F05.project-structure-and-conventions",{"title":3780,"path":3781,"stem":3782},"Базові компоненти React Native","\u002Freact-native\u002Fversion2\u002Fcore-components","15.react-native\u002Fversion2\u002F06.core-components",{"title":3784,"path":3785,"stem":3786},"Flexbox і layout у React Native","\u002Freact-native\u002Fversion2\u002Fflexbox-and-layout","15.react-native\u002Fversion2\u002F07.flexbox-and-layout",{"title":3788,"path":3789,"stem":3790},"StyleSheet і теми (light \u002F dark)","\u002Freact-native\u002Fversion2\u002Fstylesheet-and-theming","15.react-native\u002Fversion2\u002F08.stylesheet-and-theming",{"title":3792,"path":3793,"stem":3794},"Списки та віртуалізація","\u002Freact-native\u002Fversion2\u002Flists-and-virtualization","15.react-native\u002Fversion2\u002F09.lists-and-virtualization",{"title":3796,"path":3797,"stem":3798},"Форми, ввід і валідація","\u002Freact-native\u002Fversion2\u002Fforms-input-validation","15.react-native\u002Fversion2\u002F10.forms-input-validation",{"title":3800,"path":3801,"stem":3802},"Основи Expo Router","\u002Freact-native\u002Fversion2\u002Fexpo-router-basics","15.react-native\u002Fversion2\u002F11.expo-router-basics",{"title":3804,"path":3805,"stem":3806},"Вкладені навігатори та модалки","\u002Freact-native\u002Fversion2\u002Fnested-navigators-and-modals","15.react-native\u002Fversion2\u002F12.nested-navigators-and-modals",{"title":3808,"path":3809,"stem":3810},"Deep linking і параметри маршрутів","\u002Freact-native\u002Fversion2\u002Fdeep-linking-and-params","15.react-native\u002Fversion2\u002F13.deep-linking-and-params",{"title":3812,"path":3813,"stem":3814},"Робота з мережею та життєвий цикл застосунку","\u002Freact-native\u002Fversion2\u002Fnetworking-and-app-lifecycle","15.react-native\u002Fversion2\u002F14.networking-and-app-lifecycle",{"title":3816,"path":3817,"stem":3818},"Redux Toolkit на мобільних платформах","\u002Freact-native\u002Fversion2\u002Fredux-toolkit-on-mobile","15.react-native\u002Fversion2\u002F15.redux-toolkit-on-mobile",{"title":3820,"path":3821,"stem":3822},"RTK Query на мобільних платформах","\u002Freact-native\u002Fversion2\u002Frtk-query-mobile","15.react-native\u002Fversion2\u002F16.rtk-query-mobile",{"title":3824,"path":3825,"stem":3826},"Автентифікація та Безпечне Зберігання","\u002Freact-native\u002Fversion2\u002Fauth-secure-storage","15.react-native\u002Fversion2\u002F18.auth-secure-storage",{"title":3828,"path":3829,"stem":3830},"Локальне сховище — AsyncStorage, MMKV, SQLite","\u002Freact-native\u002Fversion2\u002Flocal-storage-mmkv-sqlite","15.react-native\u002Fversion2\u002F19.local-storage-mmkv-sqlite",{"title":3832,"path":3833,"stem":3834},"Офлайн-First і синхронізація","\u002Freact-native\u002Fversion2\u002Foffline-first-sync","15.react-native\u002Fversion2\u002F20.offline-first-sync",{"title":3836,"path":3837,"stem":3838},"Камера, медіа та файлова система","\u002Freact-native\u002Fversion2\u002Fcamera-media-filesystem","15.react-native\u002Fversion2\u002F21.camera-media-filesystem",{"title":3840,"path":3841,"stem":3842},"Карти та геолокація","\u002Freact-native\u002Fversion2\u002Fmaps-and-location","15.react-native\u002Fversion2\u002F22.maps-and-location",{"title":3844,"path":3845,"stem":3846},"Жести та дотики","\u002Freact-native\u002Fversion2\u002Fgestures-and-touch","15.react-native\u002Fversion2\u002F23.gestures-and-touch",{"title":3848,"path":3849,"stem":3850},"Анімації з Reanimated","\u002Freact-native\u002Fversion2\u002Freanimated-animations","15.react-native\u002Fversion2\u002F24.reanimated-animations",{"title":3852,"path":3853,"stem":3854},"Push і локальні сповіщення","\u002Freact-native\u002Fversion2\u002Fpush-and-local-notifications","15.react-native\u002Fversion2\u002F25.push-and-local-notifications",{"title":3856,"path":3857,"stem":3858},"Інтернаціоналізація та доступність","\u002Freact-native\u002Fversion2\u002Faccessibility-and-i18n","15.react-native\u002Fversion2\u002F26.accessibility-and-i18n",{"title":3860,"path":3861,"stem":3862},"EAS Build та профілі збірки","\u002Freact-native\u002Fversion2\u002Feas-build-and-profiles","15.react-native\u002Fversion2\u002F29.eas-build-and-profiles",{"title":3864,"path":3865,"stem":3866},"Публікація в App Store та Google Play","\u002Freact-native\u002Fversion2\u002Fapp-store-play-release","15.react-native\u002Fversion2\u002F30.app-store-play-release",{"title":3868,"path":3869,"stem":3870,"children":3871,"page":59},"Ai Python","\u002Fai-python","16.ai-python",[3872,3881,3890,3899,3928,3954,3979,4012,4029,4042,4051,4064,4073,4094,4107,4176],{"title":3873,"path":3874,"stem":3875,"children":3876,"page":59},"Intro To Ai","\u002Fai-python\u002Fintro-to-ai","16.ai-python\u002F01.intro-to-ai",[3877],{"title":3878,"path":3879,"stem":3880},"Вступ до штучного інтелекту та машинного навчання","\u002Fai-python\u002Fintro-to-ai\u002Fintro-to-ai","16.ai-python\u002F01.intro-to-ai\u002F01.intro-to-ai",{"title":3882,"path":3883,"stem":3884,"children":3885,"page":59},"Jupyter Notebook","\u002Fai-python\u002Fjupyter-notebook","16.ai-python\u002F02.jupyter-notebook",[3886],{"title":3887,"path":3888,"stem":3889},"Знайомство з Jupyter Notebook та JupyterLab","\u002Fai-python\u002Fjupyter-notebook\u002Fjupyter-notebook","16.ai-python\u002F02.jupyter-notebook\u002F02.jupyter-notebook",{"title":3891,"path":3892,"stem":3893,"children":3894,"page":59},"Numpy Pandas","\u002Fai-python\u002Fnumpy-pandas","16.ai-python\u002F03.numpy-pandas",[3895],{"title":3896,"path":3897,"stem":3898},"Робота з даними з використанням NumPy і pandas","\u002Fai-python\u002Fnumpy-pandas\u002Fnumpy-pandas","16.ai-python\u002F03.numpy-pandas\u002F03.numpy-pandas",{"title":3900,"path":3901,"stem":3902,"children":3903,"page":59},"Statistics Basics","\u002Fai-python\u002Fstatistics-basics","16.ai-python\u002F04.statistics-basics",[3904,3908,3912,3916,3920,3924],{"title":3905,"path":3906,"stem":3907},"Випадкові величини та їх типи","\u002Fai-python\u002Fstatistics-basics\u002Frandom-variables","16.ai-python\u002F04.statistics-basics\u002F01.random-variables",{"title":3909,"path":3910,"stem":3911},"Міри центральної тенденції","\u002Fai-python\u002Fstatistics-basics\u002Fcentral-tendency","16.ai-python\u002F04.statistics-basics\u002F02.central-tendency",{"title":3913,"path":3914,"stem":3915},"Міри варіації (розсіювання)","\u002Fai-python\u002Fstatistics-basics\u002Fvariability","16.ai-python\u002F04.statistics-basics\u002F03.variability",{"title":3917,"path":3918,"stem":3919},"Розподіли випадкових величин","\u002Fai-python\u002Fstatistics-basics\u002Fdistributions","16.ai-python\u002F04.statistics-basics\u002F04.distributions",{"title":3921,"path":3922,"stem":3923},"Кореляція та взаємозв'язки","\u002Fai-python\u002Fstatistics-basics\u002Fcorrelation","16.ai-python\u002F04.statistics-basics\u002F05.correlation",{"title":3925,"path":3926,"stem":3927},"Викиди та аномалії","\u002Fai-python\u002Fstatistics-basics\u002Foutliers","16.ai-python\u002F04.statistics-basics\u002F06.outliers",{"title":3929,"path":3930,"stem":3931,"children":3932},"Візуалізація даних за допомогою matplotlib","\u002Fai-python\u002Fdata-visualization","16.ai-python\u002F05.data-visualization\u002Findex",[3933,3934,3938,3942,3946,3950],{"title":3929,"path":3930,"stem":3931},{"title":3935,"path":3936,"stem":3937},"Основи matplotlib — Figure, Axes та перший графік","\u002Fai-python\u002Fdata-visualization\u002Fmatplotlib-basics","16.ai-python\u002F05.data-visualization\u002F01.matplotlib-basics",{"title":3939,"path":3940,"stem":3941},"Візуалізація розподілів — гістограми та box plots","\u002Fai-python\u002Fdata-visualization\u002Fdistributions","16.ai-python\u002F05.data-visualization\u002F02.distributions",{"title":3943,"path":3944,"stem":3945},"Візуалізація залежностей — scatter plots та кореляція","\u002Fai-python\u002Fdata-visualization\u002Frelationships","16.ai-python\u002F05.data-visualization\u002F03.relationships",{"title":3947,"path":3948,"stem":3949},"Візуалізація категоріальних даних — bar charts та pie charts","\u002Fai-python\u002Fdata-visualization\u002Fcategorical","16.ai-python\u002F05.data-visualization\u002F04.categorical",{"title":3951,"path":3952,"stem":3953},"Композиції та стилізація — subplots та багатопанельні дашборди","\u002Fai-python\u002Fdata-visualization\u002Fsubplots-styling","16.ai-python\u002F05.data-visualization\u002F05.subplots-styling",{"title":3955,"path":3956,"stem":3957,"children":3958,"page":59},"Linear Regression","\u002Fai-python\u002Flinear-regression","16.ai-python\u002F06.linear-regression",[3959,3963,3967,3971,3975],{"title":3960,"path":3961,"stem":3962},"Регресійна задача та лінійна регресія з однією змінною","\u002Fai-python\u002Flinear-regression\u002Fregression-task","16.ai-python\u002F06.linear-regression\u002F01.regression-task",{"title":3964,"path":3965,"stem":3966},"Метрики якості регресії — як оцінити модель","\u002Fai-python\u002Flinear-regression\u002Fquality-metrics","16.ai-python\u002F06.linear-regression\u002F02.quality-metrics",{"title":3968,"path":3969,"stem":3970},"Градієнтний спуск — як модель навчається","\u002Fai-python\u002Flinear-regression\u002Fgradient-descent","16.ai-python\u002F06.linear-regression\u002F03.gradient-descent",{"title":3972,"path":3973,"stem":3974},"Множинна лінійна регресія — модель з багатьма ознаками","\u002Fai-python\u002Flinear-regression\u002Fmultiple-regression","16.ai-python\u002F06.linear-regression\u002F04.multiple-regression",{"title":3976,"path":3977,"stem":3978},"Практичні завдання та резюме модуля","\u002Fai-python\u002Flinear-regression\u002Fpractice","16.ai-python\u002F06.linear-regression\u002F05.practice",{"title":3980,"path":3981,"stem":3982,"children":3983,"page":59},"Practical Regression","\u002Fai-python\u002Fpractical-regression","16.ai-python\u002F07.practical-regression",[3984,3988,3992,3996,4000,4004,4008],{"title":3985,"path":3986,"stem":3987},"Знайомство з scikit-learn","\u002Fai-python\u002Fpractical-regression\u002Fintro-scikit-learn","16.ai-python\u002F07.practical-regression\u002F01.intro-scikit-learn",{"title":3989,"path":3990,"stem":3991},"Exploratory Data Analysis датасету Housing Prices","\u002Fai-python\u002Fpractical-regression\u002Fhousing-dataset-eda","16.ai-python\u002F07.practical-regression\u002F02.housing-dataset-eda",{"title":3993,"path":3994,"stem":3995},"Попередня обробка даних (Data Preprocessing)","\u002Fai-python\u002Fpractical-regression\u002Fdata-preprocessing","16.ai-python\u002F07.practical-regression\u002F03.data-preprocessing",{"title":3997,"path":3998,"stem":3999},"Train\u002FTest Split та перша повноцінна модель","\u002Fai-python\u002Fpractical-regression\u002Ftrain-test-split","16.ai-python\u002F07.practical-regression\u002F04.train-test-split",{"title":4001,"path":4002,"stem":4003},"Перенавчання та недонавчання","\u002Fai-python\u002Fpractical-regression\u002Foverfitting-underfitting","16.ai-python\u002F07.practical-regression\u002F05.overfitting-underfitting",{"title":4005,"path":4006,"stem":4007},"Крос-валідація (Cross-Validation)","\u002Fai-python\u002Fpractical-regression\u002Fcross-validation","16.ai-python\u002F07.practical-regression\u002F06.cross-validation",{"title":4009,"path":4010,"stem":4011},"Гіперпараметри та їх оптимізація","\u002Fai-python\u002Fpractical-regression\u002Fhyperparameter-tuning","16.ai-python\u002F07.practical-regression\u002F07.hyperparameter-tuning",{"title":4013,"path":4014,"stem":4015,"children":4016,"page":59},"Polynomial Regression","\u002Fai-python\u002Fpolynomial-regression","16.ai-python\u002F08.polynomial-regression",[4017,4021,4025],{"title":4018,"path":4019,"stem":4020},"Нелінійні залежності та поліноміальна регресія","\u002Fai-python\u002Fpolynomial-regression\u002Fnonlinear-patterns","16.ai-python\u002F08.polynomial-regression\u002F01.nonlinear-patterns",{"title":4022,"path":4023,"stem":4024},"Регуляризація в регресії — Ridge та Lasso","\u002Fai-python\u002Fpolynomial-regression\u002Fregularization-methods","16.ai-python\u002F08.polynomial-regression\u002F02.regularization-methods",{"title":4026,"path":4027,"stem":4028},"Практика — поліноміальна регресія та регуляризація на Housing Prices","\u002Fai-python\u002Fpolynomial-regression\u002Fhousing-prices-practice","16.ai-python\u002F08.polynomial-regression\u002F03.housing-prices-practice",{"title":4030,"path":4031,"stem":4032,"children":4033,"page":59},"Decision Trees Random Forest","\u002Fai-python\u002Fdecision-trees-random-forest","16.ai-python\u002F09.decision-trees-random-forest",[4034,4038],{"title":4035,"path":4036,"stem":4037},"Дерева рішень — моделі з прозорою та зрозумілою логікою","\u002Fai-python\u002Fdecision-trees-random-forest\u002Fdecision-trees","16.ai-python\u002F09.decision-trees-random-forest\u002F01.decision-trees",{"title":4039,"path":4040,"stem":4041},"Random Forest — ансамблі дерев рішень","\u002Fai-python\u002Fdecision-trees-random-forest\u002Frandom-forest","16.ai-python\u002F09.decision-trees-random-forest\u002F02.random-forest",{"title":4043,"path":4044,"stem":4045,"children":4046,"page":59},"Gradient Boosting","\u002Fai-python\u002Fgradient-boosting","16.ai-python\u002F10.gradient-boosting",[4047],{"title":4048,"path":4049,"stem":4050},"Градієнтний бустинг та XGBoost — послідовне виправлення помилок","\u002Fai-python\u002Fgradient-boosting\u002Fgradient-boosting-xgboost","16.ai-python\u002F10.gradient-boosting\u002F01.gradient-boosting-xgboost",{"title":4052,"path":4053,"stem":4054,"children":4055,"page":59},"Logistic Regression Classification","\u002Fai-python\u002Flogistic-regression-classification","16.ai-python\u002F11.logistic-regression-classification",[4056,4060],{"title":4057,"path":4058,"stem":4059},"Основи класифікації та логістична регресія","\u002Fai-python\u002Flogistic-regression-classification\u002Fclassification-basics","16.ai-python\u002F11.logistic-regression-classification\u002F01.classification-basics",{"title":4061,"path":4062,"stem":4063},"Метрики якості класифікації","\u002Fai-python\u002Flogistic-regression-classification\u002Fclassification-metrics","16.ai-python\u002F11.logistic-regression-classification\u002F02.classification-metrics",{"title":4065,"path":4066,"stem":4067,"children":4068,"page":59},"Neural Networks Basics","\u002Fai-python\u002Fneural-networks-basics","16.ai-python\u002F12.neural-networks-basics",[4069],{"title":4070,"path":4071,"stem":4072},"Вступ до нейронних мереж — від персептрона до багатошарових мереж","\u002Fai-python\u002Fneural-networks-basics\u002Fperceptron-to-mlp","16.ai-python\u002F12.neural-networks-basics\u002F01.perceptron-to-mlp",{"title":4074,"path":4075,"stem":4076,"children":4077,"page":59},"Pytorch Intro","\u002Fai-python\u002Fpytorch-intro","16.ai-python\u002F13.pytorch-intro",[4078,4082,4086,4090],{"title":4079,"path":4080,"stem":4081},"Тензори та автоматичне диференціювання в PyTorch","\u002Fai-python\u002Fpytorch-intro\u002Ftensors-and-autograd","16.ai-python\u002F13.pytorch-intro\u002F01.tensors-and-autograd",{"title":4083,"path":4084,"stem":4085},"Побудова та тренування нейронних мереж у PyTorch","\u002Fai-python\u002Fpytorch-intro\u002Fbuilding-and-training","16.ai-python\u002F13.pytorch-intro\u002F02.building-and-training",{"title":4087,"path":4088,"stem":4089},"Робота з даними та регуляризація в PyTorch","\u002Fai-python\u002Fpytorch-intro\u002Fdata-and-regularization","16.ai-python\u002F13.pytorch-intro\u002F03.data-and-regularization",{"title":4091,"path":4092,"stem":4093},"Просунуті теми PyTorch — GPU, оптимізація та deployment","\u002Fai-python\u002Fpytorch-intro\u002Fadvanced-topics","16.ai-python\u002F13.pytorch-intro\u002F04.advanced-topics",{"title":4095,"path":4096,"stem":4097,"children":4098,"page":59},"Activation Functions Heart Disease","\u002Fai-python\u002Factivation-functions-heart-disease","16.ai-python\u002F14.activation-functions-heart-disease",[4099,4103],{"title":4100,"path":4101,"stem":4102},"Функції активації та побудова нейронної мережі для передбачення вад серця","\u002Fai-python\u002Factivation-functions-heart-disease\u002Fheart-disease-prediction","16.ai-python\u002F14.activation-functions-heart-disease\u002F01.heart-disease-prediction",{"title":4104,"path":4105,"stem":4106},"Бонус — Повний приклад Student Performance Prediction","\u002Fai-python\u002Factivation-functions-heart-disease\u002Fstudent-performance-bonus","16.ai-python\u002F14.activation-functions-heart-disease\u002F02.student-performance-bonus",{"title":4108,"path":4109,"stem":4110,"children":4111,"page":59},"Cnn Image Classification","\u002Fai-python\u002Fcnn-image-classification","16.ai-python\u002F15.cnn-image-classification",[4112,4116,4120,4124,4128,4132,4136,4140,4144,4148,4152,4156,4160,4164,4168,4172],{"title":4113,"path":4114,"stem":4115},"Вступ до комп'ютерного зору та проблеми Dense-мереж","\u002Fai-python\u002Fcnn-image-classification\u002Fintro-computer-vision","16.ai-python\u002F15.cnn-image-classification\u002F01.intro-computer-vision",{"title":4117,"path":4118,"stem":4119},"Навіщо потрібна згортка — від нейрона-шаблону до ковзного детектора","\u002Fai-python\u002Fcnn-image-classification\u002Fwhy-convolution","16.ai-python\u002F15.cnn-image-classification\u002F02.why-convolution",{"title":4121,"path":4122,"stem":4123},"Згортка крок за кроком — ядро, карта ознак і розмір результату","\u002Fai-python\u002Fcnn-image-classification\u002Fconvolution-step-by-step","16.ai-python\u002F15.cnn-image-classification\u002F03.convolution-step-by-step",{"title":4125,"path":4126,"stem":4127},"Що «бачить» ядро — читаємо карту ознак і класичні фільтри","\u002Fai-python\u002Fcnn-image-classification\u002Ffilters-what-kernel-sees","16.ai-python\u002F15.cnn-image-classification\u002F04.filters-what-kernel-sees",{"title":4129,"path":4130,"stem":4131},"Padding і stride — що робити з краями картинки та її розміром","\u002Fai-python\u002Fcnn-image-classification\u002Fpadding-and-stride","16.ai-python\u002F15.cnn-image-classification\u002F05.padding-and-stride",{"title":4133,"path":4134,"stem":4135},"Ядро, що навчається — від випадкових чисел до детектора країв","\u002Fai-python\u002Fcnn-image-classification\u002Flearnable-kernels","16.ai-python\u002F15.cnn-image-classification\u002F06.learnable-kernels",{"title":4137,"path":4138,"stem":4139},"Пулінг і поле зору — стискаємо карту ознак і дивимося ширше","\u002Fai-python\u002Fcnn-image-classification\u002Fpooling","16.ai-python\u002F15.cnn-image-classification\u002F07.pooling",{"title":4141,"path":4142,"stem":4143},"Багатоканальна згортка — ядро-куб, кольорове фото та підрахунок параметрів","\u002Fai-python\u002Fcnn-image-classification\u002Fmultichannel-convolution","16.ai-python\u002F15.cnn-image-classification\u002F08.multichannel-convolution",{"title":4145,"path":4146,"stem":4147},"Повна CNN для MNIST — збираємо, навчаємо, перевіряємо","\u002Fai-python\u002Fcnn-image-classification\u002Fcnn-mnist","16.ai-python\u002F15.cnn-image-classification\u002F09.cnn-mnist",{"title":4149,"path":4150,"stem":4151},"CNN для CIFAR-10 — коли задача справді складна","\u002Fai-python\u002Fcnn-image-classification\u002Fcnn-cifar10","16.ai-python\u002F15.cnn-image-classification\u002F10.cnn-cifar10",{"title":4153,"path":4154,"stem":4155},"Міні-батчі, DataLoader і швидкість навчання","\u002Fai-python\u002Fcnn-image-classification\u002Fmini-batch-learning-rate","16.ai-python\u002F15.cnn-image-classification\u002F11.mini-batch-learning-rate",{"title":4157,"path":4158,"stem":4159},"Ініціалізація ваг і Batch Normalization","\u002Fai-python\u002Fcnn-image-classification\u002Fweight-init-batchnorm","16.ai-python\u002F15.cnn-image-classification\u002F12.weight-init-batchnorm",{"title":4161,"path":4162,"stem":4163},"LayerNorm і обрізання градієнтів","\u002Fai-python\u002Fcnn-image-classification\u002Flayernorm-gradient-clipping","16.ai-python\u002F15.cnn-image-classification\u002F13.layernorm-gradient-clipping",{"title":4165,"path":4166,"stem":4167},"Аугментація даних","\u002Fai-python\u002Fcnn-image-classification\u002Fdata-augmentation","16.ai-python\u002F15.cnn-image-classification\u002F14.data-augmentation",{"title":4169,"path":4170,"stem":4171},"Глибокі мережі та ResNet","\u002Fai-python\u002Fcnn-image-classification\u002Fdeep-networks-resnet","16.ai-python\u002F15.cnn-image-classification\u002F15.deep-networks-resnet",{"title":4173,"path":4174,"stem":4175},"Пневмонія на рентгені - метрики, transfer learning, Grad-CAM","\u002Fai-python\u002Fcnn-image-classification\u002Fpneumonia-transfer-learning","16.ai-python\u002F15.cnn-image-classification\u002F16.pneumonia-transfer-learning",{"title":4177,"path":4178,"stem":4179,"children":4180,"page":59},"Natural Language Processing","\u002Fai-python\u002Fnatural-language-processing","16.ai-python\u002F16.natural-language-processing",[4181,4185,4189,4193,4197,4201,4205,4209,4213,4217,4221,4225,4229,4233,4237,4241],{"title":4182,"path":4183,"stem":4184},"Текст як дані — чому мова складна для комп'ютера","\u002Fai-python\u002Fnatural-language-processing\u002Ftext-as-data","16.ai-python\u002F16.natural-language-processing\u002F01.text-as-data",{"title":4186,"path":4187,"stem":4188},"Токенізація — розбиття тексту на слова й речення","\u002Fai-python\u002Fnatural-language-processing\u002Ftokenization","16.ai-python\u002F16.natural-language-processing\u002F02.tokenization",{"title":4190,"path":4191,"stem":4192},"Стеммінг, лемматизація та стоп-слова","\u002Fai-python\u002Fnatural-language-processing\u002Fstemming-lemmatization-stopwords","16.ai-python\u002F16.natural-language-processing\u002F03.stemming-lemmatization-stopwords",{"title":4194,"path":4195,"stem":4196},"Корпус та частоти слів","\u002Fai-python\u002Fnatural-language-processing\u002Fcorpus-and-frequency","16.ai-python\u002F16.natural-language-processing\u002F04.corpus-and-frequency",{"title":4198,"path":4199,"stem":4200},"Мішок слів — перше представлення тексту числами","\u002Fai-python\u002Fnatural-language-processing\u002Fbag-of-words","16.ai-python\u002F16.natural-language-processing\u002F05.bag-of-words",{"title":4202,"path":4203,"stem":4204},"Класифікація тексту — baseline на мішку слів","\u002Fai-python\u002Fnatural-language-processing\u002Ftext-classification-baseline","16.ai-python\u002F16.natural-language-processing\u002F06.text-classification-baseline",{"title":4206,"path":4207,"stem":4208},"Від one-hot до embeddings — щільні вектори слів","\u002Fai-python\u002Fnatural-language-processing\u002Ffrom-one-hot-to-embeddings","16.ai-python\u002F16.natural-language-processing\u002F07.from-one-hot-to-embeddings",{"title":4210,"path":4211,"stem":4212},"Word2Vec — навчання векторів слів з контексту","\u002Fai-python\u002Fnatural-language-processing\u002Fword2vec","16.ai-python\u002F16.natural-language-processing\u002F08.word2vec",{"title":4214,"path":4215,"stem":4216},"GloVe — глобальні вектори слів та попередньо навчені моделі","\u002Fai-python\u002Fnatural-language-processing\u002Fglove-pretrained-embeddings","16.ai-python\u002F16.natural-language-processing\u002F09.glove-pretrained-embeddings",{"title":4218,"path":4219,"stem":4220},"Embeddings для класифікації — від мішка слів до векторів","\u002Fai-python\u002Fnatural-language-processing\u002Fembeddings-for-classification","16.ai-python\u002F16.natural-language-processing\u002F10.embeddings-for-classification",{"title":4222,"path":4223,"stem":4224},"Мовні моделі та послідовності — від біграм до батчів","\u002Fai-python\u002Fnatural-language-processing\u002Flanguage-models-and-sequences","16.ai-python\u002F16.natural-language-processing\u002F11.language-models-and-sequences",{"title":4226,"path":4227,"stem":4228},"Рекурентні нейронні мережі (RNN)","\u002Fai-python\u002Fnatural-language-processing\u002Frnn","16.ai-python\u002F16.natural-language-processing\u002F12.rnn",{"title":4230,"path":4231,"stem":4232},"LSTM і GRU — рекурентні мережі з вентилями","\u002Fai-python\u002Fnatural-language-processing\u002Flstm-gru","16.ai-python\u002F16.natural-language-processing\u002F13.lstm-gru",{"title":4234,"path":4235,"stem":4236},"Seq2seq і механізм уваги","\u002Fai-python\u002Fnatural-language-processing\u002Fseq2seq-attention","16.ai-python\u002F16.natural-language-processing\u002F14.seq2seq-attention",{"title":4238,"path":4239,"stem":4240},"Transformer — self-attention замість рекурентності","\u002Fai-python\u002Fnatural-language-processing\u002Ftransformer","16.ai-python\u002F16.natural-language-processing\u002F15.transformer",{"title":4242,"path":4243,"stem":4244},"Готові моделі та Hugging Face — transfer learning","\u002Fai-python\u002Fnatural-language-processing\u002Fpretrained-models-sentiment","16.ai-python\u002F16.natural-language-processing\u002F16.pretrained-models-sentiment",{"title":4246,"icon":658,"path":4247,"stem":4248,"children":4249,"page":59},"Клієнт-серверна архітектура","\u002Fclient-server-architecture","17.client-server-architecture",[4250,4254,4258,4262,4266,4270,4274,4278,4282,4286,4290,4294,4298,4302,4306,4310,4314,4318],{"title":4251,"path":4252,"stem":4253},"Архітектура клієнт-серверних систем та основи Go","\u002Fclient-server-architecture\u002Fclient-server-architecture-and-go","17.client-server-architecture\u002F01.client-server-architecture-and-go",{"title":4255,"path":4256,"stem":4257},"Система типів та модель пам’яті мови Go","\u002Fclient-server-architecture\u002Ftype-system-and-memory-model","17.client-server-architecture\u002F02.type-system-and-memory-model",{"title":4259,"path":4260,"stem":4261},"Інтерфейси та модель конкурентності мови Go","\u002Fclient-server-architecture\u002Finterfaces-and-concurrency-model","17.client-server-architecture\u002F03.interfaces-and-concurrency-model",{"title":4263,"path":4264,"stem":4265},"Сокетне програмування та протокол TCP у Go","\u002Fclient-server-architecture\u002Ftcp-socket-programming","17.client-server-architecture\u002F04.tcp-socket-programming",{"title":4267,"path":4268,"stem":4269},"Протокол UDP та датаграмна передача даних","\u002Fclient-server-architecture\u002Fudp-datagram-transmission","17.client-server-architecture\u002F05.udp-datagram-transmission",{"title":4271,"path":4272,"stem":4273},"Криптографічний захист каналів зв","\u002Fclient-server-architecture\u002Ftls-cryptographic-channel-protection","17.client-server-architecture\u002F06.tls-cryptographic-channel-protection",{"title":4275,"path":4276,"stem":4277},"Прикладні мережеві протоколи DNS та SMTP","\u002Fclient-server-architecture\u002Fdns-smtp-application-protocols","17.client-server-architecture\u002F07.dns-smtp-application-protocols",{"title":4279,"path":4280,"stem":4281},"Протокол HTTP та стандартний вебсервер Go","\u002Fclient-server-architecture\u002Fhttp-protocol-and-web-server","17.client-server-architecture\u002F08.http-protocol-and-web-server",{"title":4283,"path":4284,"stem":4285},"Проєктування REST API та маршрутизація засобами Chi","\u002Fclient-server-architecture\u002Frest-api-design-and-chi-routing","17.client-server-architecture\u002F09.rest-api-design-and-chi-routing",{"title":4287,"path":4288,"stem":4289},"Лекція 10. Шарувата архітектура та конвеєри обробки запитів","\u002Fclient-server-architecture\u002Flayered-architecture-and-middleware-pipelines","17.client-server-architecture\u002F10.layered-architecture-and-middleware-pipelines",{"title":4291,"path":4292,"stem":4293},"Лекція 11. Архітектура та маршрутизація фреймворку Gin","\u002Fclient-server-architecture\u002Fgin-framework-architecture-and-routing","17.client-server-architecture\u002F11.gin-framework-architecture-and-routing",{"title":4295,"path":4296,"stem":4297},"Лекція 12. Валідація даних, безпека та документування у Gin","\u002Fclient-server-architecture\u002Fdata-validation-security-and-documentation-in-gin","17.client-server-architecture\u002F12.data-validation-security-and-documentation-in-gin",{"title":4299,"path":4300,"stem":4301},"Лекція 13. Взаємодія з реляційними СУБД та технології ORM","\u002Fclient-server-architecture\u002Frelational-databases-and-orm","17.client-server-architecture\u002F13.relational-databases-and-orm",{"title":4303,"path":4304,"stem":4305},"Потокова передача даних та протокол WebSocket","\u002Fclient-server-architecture\u002Fstreaming-data-and-websockets","17.client-server-architecture\u002F14.streaming-data-and-websockets",{"title":4307,"path":4308,"stem":4309},"Міжсервісна взаємодія на основі протоколу gRPC","\u002Fclient-server-architecture\u002Fgrpc-inter-service-communication","17.client-server-architecture\u002F15.grpc-inter-service-communication",{"title":4311,"path":4312,"stem":4313},"Асинхронний обмін повідомленнями та протоколи черг","\u002Fclient-server-architecture\u002Fasynchronous-message-exchange-and-queue-protocols","17.client-server-architecture\u002F16.asynchronous-message-exchange-and-queue-protocols",{"title":4315,"path":4316,"stem":4317},"Протоколи потокового медіа та технологія WebRTC","\u002Fclient-server-architecture\u002Fstreaming-media-protocols-and-webrtc","17.client-server-architecture\u002F17.streaming-media-protocols-and-webrtc",{"title":4319,"path":4320,"stem":4321},"Моніторинг, безпека та контейнеризація застосунків","\u002Fclient-server-architecture\u002Fmonitoring-security-and-containerization","17.client-server-architecture\u002F18.monitoring-security-and-containerization",{"title":4323,"icon":2254,"path":4324,"stem":4325,"children":4326,"page":59},"Розробка WEB-застосувань","\u002Fweb-development","18.web-development",[4327,4372,4410,4439,4468,4525,4575,4669,4735,4817,4850,4878,4920,4966,5009],{"title":4328,"icon":658,"path":4329,"stem":4330,"children":4331,"page":59},"Архітектура комп'ютерних мереж та мережеві протоколи","\u002Fweb-development\u002Fnetwork-architecture-and-protocols","18.web-development\u002F01.network-architecture-and-protocols",[4332,4336,4340,4344,4348,4352,4356,4360,4364,4368],{"title":4333,"path":4334,"stem":4335},"Еволюція веброзробки та модель клієнт-сервер","\u002Fweb-development\u002Fnetwork-architecture-and-protocols\u002Fweb-evolution-client-server","18.web-development\u002F01.network-architecture-and-protocols\u002F01.web-evolution-client-server",{"title":4337,"path":4338,"stem":4339},"Еталонна модель OSI","\u002Fweb-development\u002Fnetwork-architecture-and-protocols\u002Fosi-model","18.web-development\u002F01.network-architecture-and-protocols\u002F02.osi-model",{"title":4341,"path":4342,"stem":4343},"Стек протоколів TCP\u002FIP","\u002Fweb-development\u002Fnetwork-architecture-and-protocols\u002Ftcp-ip-stack","18.web-development\u002F01.network-architecture-and-protocols\u002F03.tcp-ip-stack",{"title":4345,"path":4346,"stem":4347},"IP-адресація, порти та сокети","\u002Fweb-development\u002Fnetwork-architecture-and-protocols\u002Fip-addressing-ports-sockets","18.web-development\u002F01.network-architecture-and-protocols\u002F04.ip-addressing-ports-sockets",{"title":4349,"path":4350,"stem":4351},"Протоколи TCP та UDP","\u002Fweb-development\u002Fnetwork-architecture-and-protocols\u002Ftcp-udp-protocols","18.web-development\u002F01.network-architecture-and-protocols\u002F05.tcp-udp-protocols",{"title":4353,"path":4354,"stem":4355},"Система доменних імен DNS","\u002Fweb-development\u002Fnetwork-architecture-and-protocols\u002Fdns-system","18.web-development\u002F01.network-architecture-and-protocols\u002F06.dns-system",{"title":4357,"path":4358,"stem":4359},"Протокол SMTP та поштові протоколи","\u002Fweb-development\u002Fnetwork-architecture-and-protocols\u002Fsmtp-email-protocols","18.web-development\u002F01.network-architecture-and-protocols\u002F07.smtp-email-protocols",{"title":4361,"path":4362,"stem":4363},"Протокол WebSocket","\u002Fweb-development\u002Fnetwork-architecture-and-protocols\u002Fwebsocket-protocol","18.web-development\u002F01.network-architecture-and-protocols\u002F08.websocket-protocol",{"title":4365,"path":4366,"stem":4367},"Протокол SSH","\u002Fweb-development\u002Fnetwork-architecture-and-protocols\u002Fssh-protocol","18.web-development\u002F01.network-architecture-and-protocols\u002F09.ssh-protocol",{"title":4369,"path":4370,"stem":4371},"Огляд сучасних серверних технологій","\u002Fweb-development\u002Fnetwork-architecture-and-protocols\u002Fmodern-backend-technologies","18.web-development\u002F01.network-architecture-and-protocols\u002F10.modern-backend-technologies",{"title":4373,"icon":4374,"path":4375,"stem":4376,"children":4377,"page":59},"Протокол HTTP та захищена передача даних HTTPS","i-lucide-lock","\u002Fweb-development\u002Fhttp-and-https","18.web-development\u002F02.http-and-https",[4378,4382,4386,4390,4394,4398,4402,4406],{"title":4379,"path":4380,"stem":4381},"Вступ до протоколу HTTP та еволюція веб-технологій","\u002Fweb-development\u002Fhttp-and-https\u002Fintroduction-and-evolution","18.web-development\u002F02.http-and-https\u002F01.introduction-and-evolution",{"title":4383,"path":4384,"stem":4385},"Анатомія HTTP-запиту","\u002Fweb-development\u002Fhttp-and-https\u002Fhttp-request-structure","18.web-development\u002F02.http-and-https\u002F02.http-request-structure",{"title":4387,"path":4388,"stem":4389},"Анатомія HTTP-відповіді","\u002Fweb-development\u002Fhttp-and-https\u002Fhttp-response-structure","18.web-development\u002F02.http-and-https\u002F03.http-response-structure",{"title":4391,"path":4392,"stem":4393},"Методи HTTP та їхня семантика","\u002Fweb-development\u002Fhttp-and-https\u002Fhttp-methods","18.web-development\u002F02.http-and-https\u002F04.http-methods",{"title":4395,"path":4396,"stem":4397},"Коди статусу HTTP та їхнє призначення","\u002Fweb-development\u002Fhttp-and-https\u002Fhttp-status-codes","18.web-development\u002F02.http-and-https\u002F05.http-status-codes",{"title":4399,"path":4400,"stem":4401},"HTTP-заголовки та їхнє призначення","\u002Fweb-development\u002Fhttp-and-https\u002Fhttp-headers","18.web-development\u002F02.http-and-https\u002F06.http-headers",{"title":4403,"path":4404,"stem":4405},"CORS та механізми безпеки HTTP","\u002Fweb-development\u002Fhttp-and-https\u002Fcors-and-security","18.web-development\u002F02.http-and-https\u002F07.cors-and-security",{"title":4407,"path":4408,"stem":4409},"HTTPS та криптографічні основи TLS","\u002Fweb-development\u002Fhttp-and-https\u002Fhttps-and-tls","18.web-development\u002F02.http-and-https\u002F08.https-and-tls",{"title":4411,"icon":2634,"path":4412,"stem":4413,"children":4414,"page":59},"Система типів мови TypeScript","\u002Fweb-development\u002Ftypescript-type-system","18.web-development\u002F03.typescript-type-system",[4415,4419,4423,4427,4431,4435],{"title":4416,"path":4417,"stem":4418},"Знайомство з TypeScript Compiler","\u002Fweb-development\u002Ftypescript-type-system\u002Fintroduction-compiler-config","18.web-development\u002F03.typescript-type-system\u002F01.introduction-compiler-config",{"title":4420,"path":4421,"stem":4422},"Примітивні типи даних: string, number, boolean","\u002Fweb-development\u002Ftypescript-type-system\u002Fprimitive-special-types","18.web-development\u002F03.typescript-type-system\u002F02.primitive-special-types",{"title":4424,"path":4425,"stem":4426},"Масиви, кортежі та об","\u002Fweb-development\u002Ftypescript-type-system\u002Farrays-tuples-objects","18.web-development\u002F03.typescript-type-system\u002F03.arrays-tuples-objects",{"title":4428,"path":4429,"stem":4430},"Псевдоніми типів, Union типи, Intersection типи та літеральні типи","\u002Fweb-development\u002Ftypescript-type-system\u002Funion-intersection-literals","18.web-development\u002F03.typescript-type-system\u002F04.union-intersection-literals",{"title":4432,"path":4433,"stem":4434},"Type Narrowing (звуження типів)","\u002Fweb-development\u002Ftypescript-type-system\u002Ftype-narrowing","18.web-development\u002F03.typescript-type-system\u002F05.type-narrowing",{"title":4436,"path":4437,"stem":4438},"Типізація функцій","\u002Fweb-development\u002Ftypescript-type-system\u002Ffunctions-typing","18.web-development\u002F03.typescript-type-system\u002F06.functions-typing",{"title":4440,"icon":2634,"path":4441,"stem":4442,"children":4443,"page":59},"Розширені засоби мови TypeScript","\u002Fweb-development\u002Ftypescript-advanced","18.web-development\u002F04.typescript-advanced",[4444,4448,4452,4456,4460,4464],{"title":4445,"path":4446,"stem":4447},"Interfaces та Classes","\u002Fweb-development\u002Ftypescript-advanced\u002Finterfaces-classes","18.web-development\u002F04.typescript-advanced\u002F01.interfaces-classes",{"title":4449,"path":4450,"stem":4451},"Основи Generic типів","\u002Fweb-development\u002Ftypescript-advanced\u002Fgenerics-fundamentals","18.web-development\u002F04.typescript-advanced\u002F02.generics-fundamentals",{"title":4453,"path":4454,"stem":4455},"Enums та Decorators","\u002Fweb-development\u002Ftypescript-advanced\u002Fenums-decorators","18.web-development\u002F04.typescript-advanced\u002F03.enums-decorators",{"title":4457,"path":4458,"stem":4459},"Utility Types","\u002Fweb-development\u002Ftypescript-advanced\u002Futility-types","18.web-development\u002F04.typescript-advanced\u002F04.utility-types",{"title":4461,"path":4462,"stem":4463},"Mapped та Conditional Types","\u002Fweb-development\u002Ftypescript-advanced\u002Fmapped-conditional-types","18.web-development\u002F04.typescript-advanced\u002F05.mapped-conditional-types",{"title":4465,"path":4466,"stem":4467},"Модулі та Strict Mode","\u002Fweb-development\u002Ftypescript-advanced\u002Fmodules-strict-mode","18.web-development\u002F04.typescript-advanced\u002F06.modules-strict-mode",{"title":4469,"icon":4470,"path":4471,"stem":4472,"children":4473,"page":59},"Платформа Node.js як середовище виконання","i-devicon-nodejs","\u002Fweb-development\u002Fnodejs-platform","18.web-development\u002F05.nodejs-platform",[4474,4478,4482,4486,4490,4494,4498,4502,4506,4510,4514,4517,4521],{"title":4475,"path":4476,"stem":4477},"Що таке Node.js та його архітектура","\u002Fweb-development\u002Fnodejs-platform\u002Fwhat-is-nodejs","18.web-development\u002F05.nodejs-platform\u002F01.what-is-nodejs",{"title":4479,"path":4480,"stem":4481},"Event Loop — серце Node.js","\u002Fweb-development\u002Fnodejs-platform\u002Fevent-loop","18.web-development\u002F05.nodejs-platform\u002F02.event-loop",{"title":4483,"path":4484,"stem":4485},"Модульні системи: CommonJS vs ES Modules","\u002Fweb-development\u002Fnodejs-platform\u002Fmodule-systems","18.web-development\u002F05.nodejs-platform\u002F03.module-systems",{"title":4487,"path":4488,"stem":4489},"npm та package.json","\u002Fweb-development\u002Fnodejs-platform\u002Fnpm-package-json","18.web-development\u002F05.nodejs-platform\u002F04.npm-package-json",{"title":4491,"path":4492,"stem":4493},"Глобальні об\\","\u002Fweb-development\u002Fnodejs-platform\u002Fglobal-objects","18.web-development\u002F05.nodejs-platform\u002F05.global-objects",{"title":4495,"path":4496,"stem":4497},"Вбудований модуль fs (File System)","\u002Fweb-development\u002Fnodejs-platform\u002Fbuilt-in-modules-fs","18.web-development\u002F05.nodejs-platform\u002F06.built-in-modules-fs",{"title":4499,"path":4500,"stem":4501},"Вбудований модуль path","\u002Fweb-development\u002Fnodejs-platform\u002Fbuilt-in-modules-path","18.web-development\u002F05.nodejs-platform\u002F07.built-in-modules-path",{"title":4503,"path":4504,"stem":4505},"Вбудований модуль http","\u002Fweb-development\u002Fnodejs-platform\u002Fbuilt-in-modules-http","18.web-development\u002F05.nodejs-platform\u002F08.built-in-modules-http",{"title":4507,"path":4508,"stem":4509},"Streams — потоки даних у Node.js","\u002Fweb-development\u002Fnodejs-platform\u002Fstreams","18.web-development\u002F05.nodejs-platform\u002F09.streams",{"title":4511,"path":4512,"stem":4513},"Вбудований модуль util (Utilities)","\u002Fweb-development\u002Fnodejs-platform\u002Fbuilt-in-modules-util","18.web-development\u002F05.nodejs-platform\u002F10.built-in-modules-util",{"title":3319,"path":4515,"stem":4516},"\u002Fweb-development\u002Fnodejs-platform\u002Fenvironment-variables","18.web-development\u002F05.nodejs-platform\u002F11.environment-variables",{"title":4518,"path":4519,"stem":4520},"Інструменти налагодження та розробки","\u002Fweb-development\u002Fnodejs-platform\u002Fdebugging-tools","18.web-development\u002F05.nodejs-platform\u002F12.debugging-tools",{"title":4522,"path":4523,"stem":4524},"Продуктивність та Best Practices","\u002Fweb-development\u002Fnodejs-platform\u002Fperformance-best-practices","18.web-development\u002F05.nodejs-platform\u002F13.performance-best-practices",{"title":4526,"icon":4527,"path":4528,"stem":4529,"children":4530,"page":59},"Асинхронне програмування у Node.js","i-lucide-clock","\u002Fweb-development\u002Fasync-programming-nodejs","18.web-development\u002F06.async-programming-nodejs",[4531,4535,4539,4543,4547,4551,4555,4559,4563,4567,4571],{"title":4532,"path":4533,"stem":4534},"Синхронний vs асинхронний код","\u002Fweb-development\u002Fasync-programming-nodejs\u002Fsync-vs-async","18.web-development\u002F06.async-programming-nodejs\u002F01.sync-vs-async",{"title":4536,"path":4537,"stem":4538},"Callbacks — перша парадигма асинхронності","\u002Fweb-development\u002Fasync-programming-nodejs\u002Fcallbacks","18.web-development\u002F06.async-programming-nodejs\u002F02.callbacks",{"title":4540,"path":4541,"stem":4542},"Promises — стандарт асинхронності","\u002Fweb-development\u002Fasync-programming-nodejs\u002Fpromises","18.web-development\u002F06.async-programming-nodejs\u002F03.promises",{"title":4544,"path":4545,"stem":4546},"Promise комбінатори","\u002Fweb-development\u002Fasync-programming-nodejs\u002Fpromise-combinators","18.web-development\u002F06.async-programming-nodejs\u002F04.promise-combinators",{"title":4548,"path":4549,"stem":4550},"Async\u002FAwait — синтаксичний цукор над Promises","\u002Fweb-development\u002Fasync-programming-nodejs\u002Fasync-await","18.web-development\u002F06.async-programming-nodejs\u002F05.async-await",{"title":4552,"path":4553,"stem":4554},"Паралельне vs послідовне виконання","\u002Fweb-development\u002Fasync-programming-nodejs\u002Fparallel-vs-sequential","18.web-development\u002F06.async-programming-nodejs\u002F06.parallel-vs-sequential",{"title":4556,"path":4557,"stem":4558},"EventEmitter — подієва модель Node.js","\u002Fweb-development\u002Fasync-programming-nodejs\u002Fevent-emitter","18.web-development\u002F06.async-programming-nodejs\u002F07.event-emitter",{"title":4560,"path":4561,"stem":4562},"Worker Threads — багатопотоковість у Node.js","\u002Fweb-development\u002Fasync-programming-nodejs\u002Fworker-threads","18.web-development\u002F06.async-programming-nodejs\u002F08.worker-threads",{"title":4564,"path":4565,"stem":4566},"Child Processes — запуск зовнішніх процесів","\u002Fweb-development\u002Fasync-programming-nodejs\u002Fchild-processes","18.web-development\u002F06.async-programming-nodejs\u002F09.child-processes",{"title":4568,"path":4569,"stem":4570},"Обробка помилок у асинхронному коді","\u002Fweb-development\u002Fasync-programming-nodejs\u002Ferror-handling","18.web-development\u002F06.async-programming-nodejs\u002F10.error-handling",{"title":4572,"path":4573,"stem":4574},"Порівняння Node.js фреймворків","\u002Fweb-development\u002Fasync-programming-nodejs\u002Fnodejs-frameworks","18.web-development\u002F06.async-programming-nodejs\u002F11.nodejs-frameworks",{"title":4576,"icon":4577,"path":4578,"stem":4579,"children":4580,"page":59},"Тема 7. Фреймворк NestJS. Контролери та маршрутизація","i-lucide-route","\u002Fweb-development\u002Fnestjs-controllers-routing","18.web-development\u002F07.nestjs-controllers-routing",[4581,4585,4589,4593,4597,4601,4605,4609,4613,4617,4621,4625,4629,4633,4637,4641,4645,4649,4653,4657,4661,4665],{"title":4582,"path":4583,"stem":4584},"Філософія та архітектура NestJS","\u002Fweb-development\u002Fnestjs-controllers-routing\u002Fnestjs-philosophy","18.web-development\u002F07.nestjs-controllers-routing\u002F01.nestjs-philosophy",{"title":4586,"path":4587,"stem":4588},"Три стовпи архітектури: модулі, контролери, провайдери","\u002Fweb-development\u002Fnestjs-controllers-routing\u002Fthree-pillars","18.web-development\u002F07.nestjs-controllers-routing\u002F02.three-pillars",{"title":4590,"path":4591,"stem":4592},"Інверсія керування (IoC) та ін","\u002Fweb-development\u002Fnestjs-controllers-routing\u002Fioc-and-di","18.web-development\u002F07.nestjs-controllers-routing\u002F03.ioc-and-di",{"title":4594,"path":4595,"stem":4596},"Встановлення NestJS CLI та створення проєкту","\u002Fweb-development\u002Fnestjs-controllers-routing\u002Fnestjs-cli-setup","18.web-development\u002F07.nestjs-controllers-routing\u002F04.nestjs-cli-setup",{"title":4598,"path":4599,"stem":4600},"Структура проєкту NestJS та конвенції","\u002Fweb-development\u002Fnestjs-controllers-routing\u002Fproject-structure","18.web-development\u002F07.nestjs-controllers-routing\u002F05.project-structure",{"title":4602,"path":4603,"stem":4604},"Контролери: основи маршрутизації","\u002Fweb-development\u002Fnestjs-controllers-routing\u002Fcontrollers-basics","18.web-development\u002F07.nestjs-controllers-routing\u002F06.controllers-basics",{"title":4606,"path":4607,"stem":4608},"Декоратори маршрутизації HTTP-методів","\u002Fweb-development\u002Fnestjs-controllers-routing\u002Froute-decorators","18.web-development\u002F07.nestjs-controllers-routing\u002F07.route-decorators",{"title":4610,"path":4611,"stem":4612},"Параметри маршруту та декоратор @Param","\u002Fweb-development\u002Fnestjs-controllers-routing\u002Froute-parameters","18.web-development\u002F07.nestjs-controllers-routing\u002F08.route-parameters",{"title":4614,"path":4615,"stem":4616},"Query-параметри та декоратор @Query","\u002Fweb-development\u002Fnestjs-controllers-routing\u002Fquery-parameters","18.web-development\u002F07.nestjs-controllers-routing\u002F09.query-parameters",{"title":4618,"path":4619,"stem":4620},"Тіло запиту та декоратор @Body","\u002Fweb-development\u002Fnestjs-controllers-routing\u002Frequest-body","18.web-development\u002F07.nestjs-controllers-routing\u002F10.request-body",{"title":4622,"path":4623,"stem":4624},"Робота з заголовками запиту та відповіді","\u002Fweb-development\u002Fnestjs-controllers-routing\u002Fheaders-decorators","18.web-development\u002F07.nestjs-controllers-routing\u002F11.headers-decorators",{"title":4626,"path":4627,"stem":4628},"Data Transfer Objects (DTO): визначення та призначення","\u002Fweb-development\u002Fnestjs-controllers-routing\u002Fdto-introduction","18.web-development\u002F07.nestjs-controllers-routing\u002F12.dto-introduction",{"title":4630,"path":4631,"stem":4632},"Об'єкти Request та Response","\u002Fweb-development\u002Fnestjs-controllers-routing\u002Frequest-response-objects","18.web-development\u002F07.nestjs-controllers-routing\u002F13.request-response-objects",{"title":4634,"path":4635,"stem":4636},"HTTP-статус коди та декоратор @HttpCode","\u002Fweb-development\u002Fnestjs-controllers-routing\u002Fhttp-status-codes","18.web-development\u002F07.nestjs-controllers-routing\u002F14.http-status-codes",{"title":4638,"path":4639,"stem":4640},"Перенаправлення (Redirects) та декоратор @Redirect","\u002Fweb-development\u002Fnestjs-controllers-routing\u002Fredirects","18.web-development\u002F07.nestjs-controllers-routing\u002F15.redirects",{"title":4642,"path":4643,"stem":4644},"Асинхронні обробники та Observables","\u002Fweb-development\u002Fnestjs-controllers-routing\u002Fasync-handlers","18.web-development\u002F07.nestjs-controllers-routing\u002F16.async-handlers",{"title":4646,"path":4647,"stem":4648},"Маршрутизація за піддоменами та версіонування API","\u002Fweb-development\u002Fnestjs-controllers-routing\u002Fsub-domain-routing","18.web-development\u002F07.nestjs-controllers-routing\u002F17.sub-domain-routing",{"title":4650,"path":4651,"stem":4652},"Області видимості контролерів (Scopes)","\u002Fweb-development\u002Fnestjs-controllers-routing\u002Fcontroller-scopes","18.web-development\u002F07.nestjs-controllers-routing\u002F18.controller-scopes",{"title":4654,"path":4655,"stem":4656},"Основні команди NestJS CLI","\u002Fweb-development\u002Fnestjs-controllers-routing\u002Fnestjs-cli-commands","18.web-development\u002F07.nestjs-controllers-routing\u002F19.nestjs-cli-commands",{"title":4658,"path":4659,"stem":4660},"Практичний приклад: створення CRUD-контролера","\u002Fweb-development\u002Fnestjs-controllers-routing\u002Fcrud-example","18.web-development\u002F07.nestjs-controllers-routing\u002F20.crud-example",{"title":4662,"path":4663,"stem":4664},"Тестування контролерів","\u002Fweb-development\u002Fnestjs-controllers-routing\u002Ftesting-controllers","18.web-development\u002F07.nestjs-controllers-routing\u002F21.testing-controllers",{"title":4666,"path":4667,"stem":4668},"Best Practices для контролерів та маршрутизації","\u002Fweb-development\u002Fnestjs-controllers-routing\u002Fbest-practices","18.web-development\u002F07.nestjs-controllers-routing\u002F22.best-practices",{"title":4670,"icon":4671,"path":4672,"stem":4673,"children":4674,"page":59},"Тема 8. Провайдери, сервіси та модульна система NestJS","i-lucide-package","\u002Fweb-development\u002Fnestjs-providers-modules","18.web-development\u002F08.nestjs-providers-modules",[4675,4679,4683,4687,4691,4695,4699,4703,4707,4711,4715,4719,4723,4727,4731],{"title":4676,"path":4677,"stem":4678},"Концепція провайдерів у NestJS","\u002Fweb-development\u002Fnestjs-providers-modules\u002Fproviders-concept","18.web-development\u002F08.nestjs-providers-modules\u002F01.providers-concept",{"title":4680,"path":4681,"stem":4682},"Сервіси: інкапсуляція бізнес-логіки","\u002Fweb-development\u002Fnestjs-providers-modules\u002Fservices-business-logic","18.web-development\u002F08.nestjs-providers-modules\u002F02.services-business-logic",{"title":4684,"path":4685,"stem":4686},"Практика ін","\u002Fweb-development\u002Fnestjs-providers-modules\u002Fdependency-injection-practice","18.web-development\u002F08.nestjs-providers-modules\u002F03.dependency-injection-practice",{"title":4688,"path":4689,"stem":4690},"Custom Providers: useValue, useClass, useFactory, useExisting","\u002Fweb-development\u002Fnestjs-providers-modules\u002Fcustom-providers","18.web-development\u002F08.nestjs-providers-modules\u002F04.custom-providers",{"title":4692,"path":4693,"stem":4694},"Injection Tokens: рядкові та символьні токени","\u002Fweb-development\u002Fnestjs-providers-modules\u002Finjection-tokens","18.web-development\u002F08.nestjs-providers-modules\u002F05.injection-tokens",{"title":4696,"path":4697,"stem":4698},"Опціональні провайдери та декоратор @Optional","\u002Fweb-development\u002Fnestjs-providers-modules\u002Foptional-providers","18.web-development\u002F08.nestjs-providers-modules\u002F07.optional-providers",{"title":4700,"path":4701,"stem":4702},"Структура модулів: imports, controllers, providers, exports","\u002Fweb-development\u002Fnestjs-providers-modules\u002Fmodules-structure","18.web-development\u002F08.nestjs-providers-modules\u002F08.modules-structure",{"title":4704,"path":4705,"stem":4706},"Feature Modules: ізоляція функціональності","\u002Fweb-development\u002Fnestjs-providers-modules\u002Ffeature-modules","18.web-development\u002F08.nestjs-providers-modules\u002F09.feature-modules",{"title":4708,"path":4709,"stem":4710},"Shared Modules: перевикористання провайдерів","\u002Fweb-development\u002Fnestjs-providers-modules\u002Fshared-modules","18.web-development\u002F08.nestjs-providers-modules\u002F10.shared-modules",{"title":4712,"path":4713,"stem":4714},"Global Modules та декоратор @Global","\u002Fweb-development\u002Fnestjs-providers-modules\u002Fglobal-modules","18.web-development\u002F08.nestjs-providers-modules\u002F11.global-modules",{"title":4716,"path":4717,"stem":4718},"Dynamic Modules: конфігурація під час виконання","\u002Fweb-development\u002Fnestjs-providers-modules\u002Fdynamic-modules","18.web-development\u002F08.nestjs-providers-modules\u002F12.dynamic-modules",{"title":4720,"path":4721,"stem":4722},"Циклічні залежності та forwardRef","\u002Fweb-development\u002Fnestjs-providers-modules\u002Fcircular-dependencies","18.web-development\u002F08.nestjs-providers-modules\u002F13.circular-dependencies",{"title":4724,"path":4725,"stem":4726},"Lifecycle Hooks: хуки життєвого циклу","\u002Fweb-development\u002Fnestjs-providers-modules\u002Flifecycle-hooks","18.web-development\u002F08.nestjs-providers-modules\u002F14.lifecycle-hooks",{"title":4728,"path":4729,"stem":4730},"ModuleRef: динамічний доступ до провайдерів","\u002Fweb-development\u002Fnestjs-providers-modules\u002Fmodule-reference","18.web-development\u002F08.nestjs-providers-modules\u002F15.module-reference",{"title":4732,"path":4733,"stem":4734},"Тестування сервісів та провайдерів","\u002Fweb-development\u002Fnestjs-providers-modules\u002Ftesting-services","18.web-development\u002F08.nestjs-providers-modules\u002F16.testing-services",{"title":4736,"icon":4737,"path":4738,"stem":4739,"children":4740,"page":59},"Тема 9. Валідація даних та конвеєр обробки запитів у NestJS","i-lucide-filter","\u002Fweb-development\u002Fnestjs-validation-pipeline","18.web-development\u002F09.nestjs-validation-pipeline",[4741,4745,4749,4753,4757,4761,4765,4769,4773,4777,4781,4785,4789,4793,4797,4801,4805,4809,4813],{"title":4742,"path":4743,"stem":4744},"Request Pipeline: конвеєр обробки запитів","\u002Fweb-development\u002Fnestjs-validation-pipeline\u002Frequest-pipeline","18.web-development\u002F09.nestjs-validation-pipeline\u002F01.request-pipeline",{"title":4746,"path":4747,"stem":4748},"Pipes: концепція трансформації та валідації","\u002Fweb-development\u002Fnestjs-validation-pipeline\u002Fpipes-concept","18.web-development\u002F09.nestjs-validation-pipeline\u002F02.pipes-concept",{"title":4750,"path":4751,"stem":4752},"Вбудовані pipes: ParseIntPipe, ParseBoolPipe, ParseUUIDPipe","\u002Fweb-development\u002Fnestjs-validation-pipeline\u002Fbuilt-in-pipes","18.web-development\u002F09.nestjs-validation-pipeline\u002F03.built-in-pipes",{"title":4754,"path":4755,"stem":4756},"ValidationPipe: автоматична валідація DTO","\u002Fweb-development\u002Fnestjs-validation-pipeline\u002Fvalidation-pipe","18.web-development\u002F09.nestjs-validation-pipeline\u002F04.validation-pipe",{"title":4758,"path":4759,"stem":4760},"Декоратори class-validator для DTO","\u002Fweb-development\u002Fnestjs-validation-pipeline\u002Fclass-validator-decorators","18.web-development\u002F09.nestjs-validation-pipeline\u002F05.class-validator-decorators",{"title":4762,"path":4763,"stem":4764},"Створення кастомних валідаторів","\u002Fweb-development\u002Fnestjs-validation-pipeline\u002Fcustom-validators","18.web-development\u002F09.nestjs-validation-pipeline\u002F06.custom-validators",{"title":4766,"path":4767,"stem":4768},"Створення власних Pipes","\u002Fweb-development\u002Fnestjs-validation-pipeline\u002Fcustom-pipes","18.web-development\u002F09.nestjs-validation-pipeline\u002F07.custom-pipes",{"title":4770,"path":4771,"stem":4772},"Основи Middleware","\u002Fweb-development\u002Fnestjs-validation-pipeline\u002Fmiddleware-basics","18.web-development\u002F09.nestjs-validation-pipeline\u002F08.middleware-basics",{"title":4774,"path":4775,"stem":4776},"Практичні приклади Middleware","\u002Fweb-development\u002Fnestjs-validation-pipeline\u002Fmiddleware-examples","18.web-development\u002F09.nestjs-validation-pipeline\u002F09.middleware-examples",{"title":4778,"path":4779,"stem":4780},"Guards: захисні перехоплювачі доступу","\u002Fweb-development\u002Fnestjs-validation-pipeline\u002Fguards-concept","18.web-development\u002F09.nestjs-validation-pipeline\u002F10.guards-concept",{"title":4782,"path":4783,"stem":4784},"Створення кастомних Guards","\u002Fweb-development\u002Fnestjs-validation-pipeline\u002Fcustom-guards","18.web-development\u002F09.nestjs-validation-pipeline\u002F11.custom-guards",{"title":4786,"path":4787,"stem":4788},"Interceptors: перехоплення та трансформація відповідей","\u002Fweb-development\u002Fnestjs-validation-pipeline\u002Finterceptors-concept","18.web-development\u002F09.nestjs-validation-pipeline\u002F12.interceptors-concept",{"title":4790,"path":4791,"stem":4792},"Практичні приклади Interceptors","\u002Fweb-development\u002Fnestjs-validation-pipeline\u002Finterceptor-examples","18.web-development\u002F09.nestjs-validation-pipeline\u002F13.interceptor-examples",{"title":4794,"path":4795,"stem":4796},"Exception Filters: обробка виключень","\u002Fweb-development\u002Fnestjs-validation-pipeline\u002Fexception-filters","18.web-development\u002F09.nestjs-validation-pipeline\u002F14.exception-filters",{"title":4798,"path":4799,"stem":4800},"Custom Exception Filters: спеціалізовані фільтри","\u002Fweb-development\u002Fnestjs-validation-pipeline\u002Fcustom-exception-filters","18.web-development\u002F09.nestjs-validation-pipeline\u002F15.custom-exception-filters",{"title":4802,"path":4803,"stem":4804},"Execution Context: контекст виконання","\u002Fweb-development\u002Fnestjs-validation-pipeline\u002Fexecution-context","18.web-development\u002F09.nestjs-validation-pipeline\u002F16.execution-context",{"title":4806,"path":4807,"stem":4808},"Custom Decorators: власні декоратори","\u002Fweb-development\u002Fnestjs-validation-pipeline\u002Fcustom-decorators","18.web-development\u002F09.nestjs-validation-pipeline\u002F17.custom-decorators",{"title":4810,"path":4811,"stem":4812},"Global Components: глобальні компоненти","\u002Fweb-development\u002Fnestjs-validation-pipeline\u002Fglobal-components","18.web-development\u002F09.nestjs-validation-pipeline\u002F18.global-components",{"title":4814,"path":4815,"stem":4816},"Pipeline Best Practices: найкращі практики","\u002Fweb-development\u002Fnestjs-validation-pipeline\u002Fpipeline-best-practices","18.web-development\u002F09.nestjs-validation-pipeline\u002F19.pipeline-best-practices",{"title":4818,"icon":3043,"path":4819,"stem":4820,"children":4821,"page":59},"Інтеграція реляційних баз даних засобами TypeORM","\u002Fweb-development\u002Ftypeorm-integration","18.web-development\u002F10.typeorm-integration",[4822,4826,4830,4834,4838,4842,4846],{"title":4823,"path":4824,"stem":4825},"Робота з базами даних у Node.js через нативні драйвери","\u002Fweb-development\u002Ftypeorm-integration\u002F01-nodejs-database-drivers","18.web-development\u002F10.typeorm-integration\u002F01-nodejs-database-drivers",{"title":4827,"path":4828,"stem":4829},"ORM та знайомство з TypeORM","\u002Fweb-development\u002Ftypeorm-integration\u002F02-orm-and-typeorm-intro","18.web-development\u002F10.typeorm-integration\u002F02-orm-and-typeorm-intro",{"title":4831,"path":4832,"stem":4833},"Налаштування TypeORM у NestJS проєкті","\u002Fweb-development\u002Ftypeorm-integration\u002F03-typeorm-setup-nestjs","18.web-development\u002F10.typeorm-integration\u002F03-typeorm-setup-nestjs",{"title":4835,"path":4836,"stem":4837},"Entity класи та декоратори TypeORM","\u002Fweb-development\u002Ftypeorm-integration\u002F04-entities-and-decorators","18.web-development\u002F10.typeorm-integration\u002F04-entities-and-decorators",{"title":4839,"path":4840,"stem":4841},"Repository Pattern та CRUD операції","\u002Fweb-development\u002Ftypeorm-integration\u002F05-repository-pattern-crud","18.web-development\u002F10.typeorm-integration\u002F05-repository-pattern-crud",{"title":4843,"path":4844,"stem":4845},"Пагінація та фільтрація даних","\u002Fweb-development\u002Ftypeorm-integration\u002F06-pagination-filtering","18.web-development\u002F10.typeorm-integration\u002F06-pagination-filtering",{"title":4847,"path":4848,"stem":4849},"QueryBuilder для складних запитів","\u002Fweb-development\u002Ftypeorm-integration\u002F07-query-builder","18.web-development\u002F10.typeorm-integration\u002F07-query-builder",{"title":4851,"icon":4852,"path":4853,"stem":4854,"children":4855,"page":59},"Зв'язки між сутностями, міграції та оптимізація запитів","i-lucide-git-branch","\u002Fweb-development\u002Fentity-relations-migrations","18.web-development\u002F11.entity-relations-migrations",[4856,4860,4864,4868,4872],{"title":4857,"path":4858,"stem":4859},"Зв'язки One-to-Many та Many-to-One","\u002Fweb-development\u002Fentity-relations-migrations\u002F01-one-to-many-many-to-one","18.web-development\u002F11.entity-relations-migrations\u002F01-one-to-many-many-to-one",{"title":4861,"path":4862,"stem":4863},"Зв'язки One-to-One та Many-to-Many","\u002Fweb-development\u002Fentity-relations-migrations\u002F02-one-to-one-many-to-many","18.web-development\u002F11.entity-relations-migrations\u002F02-one-to-one-many-to-many",{"title":4865,"path":4866,"stem":4867},"Керування міграціями бази даних","\u002Fweb-development\u002Fentity-relations-migrations\u002F03-migrations-management","18.web-development\u002F11.entity-relations-migrations\u002F03-migrations-management",{"title":4869,"path":4870,"stem":4871},"Транзакції у TypeORM","\u002Fweb-development\u002Fentity-relations-migrations\u002F04-transactions","18.web-development\u002F11.entity-relations-migrations\u002F04-transactions",{"title":4873,"path":4874,"stem":4875,"children":4876},"Індекси та оптимізація запитів","\u002Fweb-development\u002Fentity-relations-migrations\u002F05-indexes-optimization","18.web-development\u002F11.entity-relations-migrations\u002F05-indexes-optimization",[4877],{"title":4873,"path":4874,"stem":4875},{"title":4879,"icon":4880,"path":4881,"stem":4882,"children":4883,"page":59},"Механізми автентифікації у вебзастосунках","i-lucide-key","\u002Fweb-development\u002Fauthentication","18.web-development\u002F12.authentication",[4884,4888,4892,4896,4900,4904,4908,4912,4916],{"title":4885,"path":4886,"stem":4887},"Автентифікація vs Авторизація","\u002Fweb-development\u002Fauthentication\u002F01-authentication-vs-authorization","18.web-development\u002F12.authentication\u002F01-authentication-vs-authorization",{"title":4889,"path":4890,"stem":4891},"Стратегії автентифікації","\u002Fweb-development\u002Fauthentication\u002F02-authentication-strategies","18.web-development\u002F12.authentication\u002F02-authentication-strategies",{"title":4893,"path":4894,"stem":4895},"Автентифікація на основі сесій","\u002Fweb-development\u002Fauthentication\u002F03-session-based-authentication","18.web-development\u002F12.authentication\u002F03-session-based-authentication",{"title":4897,"path":4898,"stem":4899},"Структура JSON Web Token (JWT)","\u002Fweb-development\u002Fauthentication\u002F04-jwt-structure","18.web-development\u002F12.authentication\u002F04-jwt-structure",{"title":4901,"path":4902,"stem":4903},"Інтеграція JWT у NestJS","\u002Fweb-development\u002Fauthentication\u002F05-nestjs-jwt-integration","18.web-development\u002F12.authentication\u002F05-nestjs-jwt-integration",{"title":4905,"path":4906,"stem":4907},"Passport.js стратегії у NestJS","\u002Fweb-development\u002Fauthentication\u002F06-passport-strategies","18.web-development\u002F12.authentication\u002F06-passport-strategies",{"title":4909,"path":4910,"stem":4911},"Безпечне зберігання паролів: хешування та криптографічний захист","\u002Fweb-development\u002Fauthentication\u002F07-password-hashing","18.web-development\u002F12.authentication\u002F07-password-hashing",{"title":4913,"path":4914,"stem":4915},"Refresh Token та безпечне оновлення доступу","\u002Fweb-development\u002Fauthentication\u002F08-refresh-tokens","18.web-development\u002F12.authentication\u002F08-refresh-tokens",{"title":4917,"path":4918,"stem":4919},"OAuth 2.0 та OpenID Connect: делегована автентифікація","\u002Fweb-development\u002Fauthentication\u002F09-oauth2-openid","18.web-development\u002F12.authentication\u002F09-oauth2-openid",{"title":4921,"icon":4922,"path":4923,"stem":4924,"children":4925,"page":59},"Авторизація та безпека серверних застосунків","i-lucide-shield","\u002Fweb-development\u002Fauthorization-security","18.web-development\u002F13.authorization-security",[4926,4930,4934,4938,4942,4946,4950,4954,4958,4962],{"title":4927,"path":4928,"stem":4929},"Моделі авторизації","\u002Fweb-development\u002Fauthorization-security\u002F01-authorization-models","18.web-development\u002F13.authorization-security\u002F01-authorization-models",{"title":4931,"path":4932,"stem":4933},"Реалізація RBAC у NestJS","\u002Fweb-development\u002Fauthorization-security\u002F02-rbac-implementation","18.web-development\u002F13.authorization-security\u002F02-rbac-implementation",{"title":4935,"path":4936,"stem":4937},"Permission-Based Access Control","\u002Fweb-development\u002Fauthorization-security\u002F03-permission-based-access","18.web-development\u002F13.authorization-security\u002F03-permission-based-access",{"title":4939,"path":4940,"stem":4941},"ABAC та бібліотека CASL","\u002Fweb-development\u002Fauthorization-security\u002F04-abac-casl","18.web-development\u002F13.authorization-security\u002F04-abac-casl",{"title":4943,"path":4944,"stem":4945},"Кастомні декоратори та метадані","\u002Fweb-development\u002Fauthorization-security\u002F05-custom-decorators-metadata","18.web-development\u002F13.authorization-security\u002F05-custom-decorators-metadata",{"title":4947,"path":4948,"stem":4949},"Конфігурація CORS","\u002Fweb-development\u002Fauthorization-security\u002F06-cors-configuration","18.web-development\u002F13.authorization-security\u002F06-cors-configuration",{"title":4951,"path":4952,"stem":4953},"Захист через HTTP Security Headers (Helmet)","\u002Fweb-development\u002Fauthorization-security\u002F07-helmet-security-headers","18.web-development\u002F13.authorization-security\u002F07-helmet-security-headers",{"title":4955,"path":4956,"stem":4957},"Rate Limiting та Throttling","\u002Fweb-development\u002Fauthorization-security\u002F08-rate-limiting-throttling","18.web-development\u002F13.authorization-security\u002F08-rate-limiting-throttling",{"title":4959,"path":4960,"stem":4961},"Захист від поширених атак","\u002Fweb-development\u002Fauthorization-security\u002F09-common-attacks-protection","18.web-development\u002F13.authorization-security\u002F09-common-attacks-protection",{"title":4963,"path":4964,"stem":4965},"HTTPS у продакшені","\u002Fweb-development\u002Fauthorization-security\u002F10-https-production","18.web-development\u002F13.authorization-security\u002F10-https-production",{"title":4967,"icon":871,"path":4968,"stem":4969,"children":4970,"page":59},"Комунікація у реальному часі, нотифікації та фонові задачі","\u002Fweb-development\u002Frealtime-notifications-jobs","18.web-development\u002F14.realtime-notifications-jobs",[4971,4975,4979,4983,4987,4991,4994,4997,5001,5005],{"title":4972,"path":4973,"stem":4974},"Методи комунікації у реальному часі","\u002Fweb-development\u002Frealtime-notifications-jobs\u002F01-realtime-communication-methods","18.web-development\u002F14.realtime-notifications-jobs\u002F01-realtime-communication-methods",{"title":4976,"path":4977,"stem":4978},"WebSocket Gateway у NestJS","\u002Fweb-development\u002Frealtime-notifications-jobs\u002F02-websocket-gateway","18.web-development\u002F14.realtime-notifications-jobs\u002F02-websocket-gateway",{"title":4980,"path":4981,"stem":4982},"Lifecycle та Rooms у WebSocket","\u002Fweb-development\u002Frealtime-notifications-jobs\u002F03-websocket-lifecycle-rooms","18.web-development\u002F14.realtime-notifications-jobs\u002F03-websocket-lifecycle-rooms",{"title":4984,"path":4985,"stem":4986},"Server-Sent Events (SSE)","\u002Fweb-development\u002Frealtime-notifications-jobs\u002F04-server-sent-events","18.web-development\u002F14.realtime-notifications-jobs\u002F04-server-sent-events",{"title":4988,"path":4989,"stem":4990},"Архітектура системи нотифікацій","\u002Fweb-development\u002Frealtime-notifications-jobs\u002F05-notification-system","18.web-development\u002F14.realtime-notifications-jobs\u002F05-notification-system",{"title":904,"path":4992,"stem":4993},"\u002Fweb-development\u002Frealtime-notifications-jobs\u002F06-email-notifications","18.web-development\u002F14.realtime-notifications-jobs\u002F06-email-notifications",{"title":900,"path":4995,"stem":4996},"\u002Fweb-development\u002Frealtime-notifications-jobs\u002F07-web-push-notifications","18.web-development\u002F14.realtime-notifications-jobs\u002F07-web-push-notifications",{"title":4998,"path":4999,"stem":5000},"Фонові задачі та черги","\u002Fweb-development\u002Frealtime-notifications-jobs\u002F08-background-jobs-queues","18.web-development\u002F14.realtime-notifications-jobs\u002F08-background-jobs-queues",{"title":5002,"path":5003,"stem":5004},"Планувальники та Cron jobs","\u002Fweb-development\u002Frealtime-notifications-jobs\u002F09-schedulers-cron","18.web-development\u002F14.realtime-notifications-jobs\u002F09-schedulers-cron",{"title":5006,"path":5007,"stem":5008},"Практичні сценарії застосування","\u002Fweb-development\u002Frealtime-notifications-jobs\u002F10-practical-scenarios","18.web-development\u002F14.realtime-notifications-jobs\u002F10-practical-scenarios",{"title":5010,"icon":5011,"path":5012,"stem":5013,"children":5014,"page":59},"Тестування, документування та розгортання застосунків","i-lucide-rocket","\u002Fweb-development\u002Ftesting-documentation-deployment","18.web-development\u002F15.testing-documentation-deployment",[5015,5019,5023,5027,5031,5035,5039,5043,5047,5051],{"title":5016,"path":5017,"stem":5018},"Піраміда тестування та стратегія","\u002Fweb-development\u002Ftesting-documentation-deployment\u002F01-testing-pyramid-strategy","18.web-development\u002F15.testing-documentation-deployment\u002F01-testing-pyramid-strategy",{"title":5020,"path":5021,"stem":5022},"Основи Jest у NestJS","\u002Fweb-development\u002Ftesting-documentation-deployment\u002F02-jest-nestjs-basics","18.web-development\u002F15.testing-documentation-deployment\u002F02-jest-nestjs-basics",{"title":5024,"path":5025,"stem":5026},"Unit-тестування сервісів","\u002Fweb-development\u002Ftesting-documentation-deployment\u002F03-unit-testing-services","18.web-development\u002F15.testing-documentation-deployment\u002F03-unit-testing-services",{"title":5028,"path":5029,"stem":5030},"E2E тестування та покриття коду","\u002Fweb-development\u002Ftesting-documentation-deployment\u002F04-e2e-testing-coverage","18.web-development\u002F15.testing-documentation-deployment\u002F04-e2e-testing-coverage",{"title":5032,"path":5033,"stem":5034},"Swagger, OpenAPI, Scalar та Arazzo","\u002Fweb-development\u002Ftesting-documentation-deployment\u002F05-swagger-openapi","18.web-development\u002F15.testing-documentation-deployment\u002F05-swagger-openapi",{"title":5036,"path":5037,"stem":5038},"Керування конфігурацією","\u002Fweb-development\u002Ftesting-documentation-deployment\u002F06-configuration-management","18.web-development\u002F15.testing-documentation-deployment\u002F06-configuration-management",{"title":5040,"path":5041,"stem":5042},"Docker та контейнеризація","\u002Fweb-development\u002Ftesting-documentation-deployment\u002F07-docker-containerization","18.web-development\u002F15.testing-documentation-deployment\u002F07-docker-containerization",{"title":5044,"path":5045,"stem":5046},"CI\u002FCD Pipelines","\u002Fweb-development\u002Ftesting-documentation-deployment\u002F08-cicd-pipelines","18.web-development\u002F15.testing-documentation-deployment\u002F08-cicd-pipelines",{"title":5048,"path":5049,"stem":5050},"Логування та моніторинг","\u002Fweb-development\u002Ftesting-documentation-deployment\u002F09-logging-monitoring","18.web-development\u002F15.testing-documentation-deployment\u002F09-logging-monitoring",{"title":5052,"path":5053,"stem":5054},"Серіалізація та компресія","\u002Fweb-development\u002Ftesting-documentation-deployment\u002F10-serialization-compression","18.web-development\u002F15.testing-documentation-deployment\u002F10-serialization-compression",{"title":5056,"icon":5057,"path":5058,"stem":5059,"children":5060,"page":59},"AI Core: мислення AI","i-lucide-brain","\u002Fai-core","19.ai-core",[5061,5102,5151,5189],{"title":5062,"icon":5011,"path":5063,"stem":5064,"children":5065,"page":59},"Вхід у професію AI Native Developer","\u002Fai-core\u002Fai-native-developer","19.ai-core\u002F01.ai-native-developer",[5066,5070,5074,5078,5082,5086,5090,5094,5098],{"title":5067,"path":5068,"stem":5069},"Вступ до професії розробника цифрових продуктів","\u002Fai-core\u002Fai-native-developer\u002Fdigital-products","19.ai-core\u002F01.ai-native-developer\u002F01.digital-products",{"title":5071,"path":5072,"stem":5073},"Професія розробника програмного забезпечення","\u002Fai-core\u002Fai-native-developer\u002Fsoftware-developer","19.ai-core\u002F01.ai-native-developer\u002F02.software-developer",{"title":5075,"path":5076,"stem":5077},"Професія AI Native Developer","\u002Fai-core\u002Fai-native-developer\u002Fai-native-developer","19.ai-core\u002F01.ai-native-developer\u002F03.ai-native-developer",{"title":5079,"path":5080,"stem":5081},"Вплив AI на розробку програмного забезпечення","\u002Fai-core\u002Fai-native-developer\u002Fai-impact-on-development","19.ai-core\u002F01.ai-native-developer\u002F04.ai-impact-on-development",{"title":5083,"path":5084,"stem":5085},"Життєвий цикл цифрового продукту","\u002Fai-core\u002Fai-native-developer\u002Fproduct-lifecycle","19.ai-core\u002F01.ai-native-developer\u002F05.product-lifecycle",{"title":5087,"path":5088,"stem":5089},"Застосування AI на етапах створення цифрового продукту","\u002Fai-core\u002Fai-native-developer\u002Fai-in-product-creation","19.ai-core\u002F01.ai-native-developer\u002F06.ai-in-product-creation",{"title":5091,"path":5092,"stem":5093},"Розподіл завдань між людиною та AI","\u002Fai-core\u002Fai-native-developer\u002Fhuman-vs-ai-tasks","19.ai-core\u002F01.ai-native-developer\u002F07.human-vs-ai-tasks",{"title":5095,"path":5096,"stem":5097},"Компетенції AI Native Developer","\u002Fai-core\u002Fai-native-developer\u002Fcompetencies","19.ai-core\u002F01.ai-native-developer\u002F08.competencies",{"title":5099,"path":5100,"stem":5101},"Карта професійного розвитку AI Native Developer","\u002Fai-core\u002Fai-native-developer\u002Fcareer-roadmap","19.ai-core\u002F01.ai-native-developer\u002F09.career-roadmap",{"title":5103,"icon":255,"path":5104,"stem":5105,"children":5106,"page":59},"Штучний інтелект і машинне навчання","\u002Fai-core\u002Fai-and-machine-learning","19.ai-core\u002F02.ai-and-machine-learning",[5107,5111,5115,5119,5123,5127,5131,5135,5139,5143,5147],{"title":5108,"path":5109,"stem":5110},"Штучний інтелект","\u002Fai-core\u002Fai-and-machine-learning\u002Fwhat-is-ai","19.ai-core\u002F02.ai-and-machine-learning\u002F01.what-is-ai",{"title":5112,"path":5113,"stem":5114},"Відмінність AI від інших програмних систем","\u002Fai-core\u002Fai-and-machine-learning\u002Fai-vs-automation","19.ai-core\u002F02.ai-and-machine-learning\u002F02.ai-vs-automation",{"title":5116,"path":5117,"stem":5118},"Завдання штучного інтелекту","\u002Fai-core\u002Fai-and-machine-learning\u002Fai-tasks","19.ai-core\u002F02.ai-and-machine-learning\u002F03.ai-tasks",{"title":5120,"path":5121,"stem":5122},"Machine Learning","\u002Fai-core\u002Fai-and-machine-learning\u002Fmachine-learning","19.ai-core\u002F02.ai-and-machine-learning\u002F04.machine-learning",{"title":5124,"path":5125,"stem":5126},"Machine Learning Workflow","\u002Fai-core\u002Fai-and-machine-learning\u002Fml-workflow","19.ai-core\u002F02.ai-and-machine-learning\u002F05.ml-workflow",{"title":5128,"path":5129,"stem":5130},"Типи машинного навчання","\u002Fai-core\u002Fai-and-machine-learning\u002Fml-types","19.ai-core\u002F02.ai-and-machine-learning\u002F06.ml-types",{"title":5132,"path":5133,"stem":5134},"Generative AI","\u002Fai-core\u002Fai-and-machine-learning\u002Fgenerative-ai","19.ai-core\u002F02.ai-and-machine-learning\u002F07.generative-ai",{"title":5136,"path":5137,"stem":5138},"Типи контенту, створюваного AI","\u002Fai-core\u002Fai-and-machine-learning\u002Fai-content-types","19.ai-core\u002F02.ai-and-machine-learning\u002F08.ai-content-types",{"title":5140,"path":5141,"stem":5142},"Великі мовні моделі","\u002Fai-core\u002Fai-and-machine-learning\u002Flarge-language-models","19.ai-core\u002F02.ai-and-machine-learning\u002F09.large-language-models",{"title":5144,"path":5145,"stem":5146},"Можливості та обмеження Generative AI","\u002Fai-core\u002Fai-and-machine-learning\u002Fcapabilities-and-limitations","19.ai-core\u002F02.ai-and-machine-learning\u002F10.capabilities-and-limitations",{"title":5148,"path":5149,"stem":5150},"Сучасні AI-асистенти","\u002Fai-core\u002Fai-and-machine-learning\u002Fmodern-ai-assistants","19.ai-core\u002F02.ai-and-machine-learning\u002F11.modern-ai-assistants",{"title":5152,"icon":5153,"path":5154,"stem":5155,"children":5156,"page":59},"Постановка завдань для AI: принципи створення промптів","i-lucide-message-square-text","\u002Fai-core\u002Fprompt-engineering","19.ai-core\u002F03.prompt-engineering",[5157,5161,5165,5169,5173,5177,5181,5185],{"title":5158,"path":5159,"stem":5160},"Промпт як інструмент","\u002Fai-core\u002Fprompt-engineering\u002Fprompt-as-tool","19.ai-core\u002F03.prompt-engineering\u002F01.prompt-as-tool",{"title":5162,"path":5163,"stem":5164},"Принципи створення промптів","\u002Fai-core\u002Fprompt-engineering\u002Fprompt-principles","19.ai-core\u002F03.prompt-engineering\u002F02.prompt-principles",{"title":5166,"path":5167,"stem":5168},"Структура промпта","\u002Fai-core\u002Fprompt-engineering\u002Fprompt-structure","19.ai-core\u002F03.prompt-engineering\u002F03.prompt-structure",{"title":5170,"path":5171,"stem":5172},"Види промптів за типом задачі","\u002Fai-core\u002Fprompt-engineering\u002Fprompt-types","19.ai-core\u002F03.prompt-engineering\u002F04.prompt-types",{"title":5174,"path":5175,"stem":5176},"Прийоми посилення промпта","\u002Fai-core\u002Fprompt-engineering\u002Fprompt-enhancement","19.ai-core\u002F03.prompt-engineering\u002F05.prompt-enhancement",{"title":5178,"path":5179,"stem":5180},"Розбір і покращення промпта","\u002Fai-core\u002Fprompt-engineering\u002Fprompt-analysis","19.ai-core\u002F03.prompt-engineering\u002F06.prompt-analysis",{"title":5182,"path":5183,"stem":5184},"Типові помилки під час створення промптів","\u002Fai-core\u002Fprompt-engineering\u002Fcommon-mistakes","19.ai-core\u002F03.prompt-engineering\u002F07.common-mistakes",{"title":5186,"path":5187,"stem":5188},"Практикум: особиста бібліотека промптів","\u002Fai-core\u002Fprompt-engineering\u002Fprompt-library","19.ai-core\u002F03.prompt-engineering\u002F08.prompt-library",{"title":5190,"icon":793,"path":5191,"stem":5192,"children":5193,"page":59},"Перевірка результатів, безпека та AI Native Workflow","\u002Fai-core\u002Fverification-security-workflow","19.ai-core\u002F04.verification-security-workflow",[5194,5198,5202,5206,5210,5214,5218,5222,5226],{"title":5195,"path":5196,"stem":5197},"Межі можливостей AI","\u002Fai-core\u002Fverification-security-workflow\u002Fai-limitations","19.ai-core\u002F04.verification-security-workflow\u002F01.ai-limitations",{"title":5199,"path":5200,"stem":5201},"Галюцинації AI","\u002Fai-core\u002Fverification-security-workflow\u002Fai-hallucinations","19.ai-core\u002F04.verification-security-workflow\u002F02.ai-hallucinations",{"title":5203,"path":5204,"stem":5205},"Критичне мислення під час роботи з AI","\u002Fai-core\u002Fverification-security-workflow\u002Fcritical-thinking","19.ai-core\u002F04.verification-security-workflow\u002F03.critical-thinking",{"title":5207,"path":5208,"stem":5209},"Перевірка результатів роботи AI","\u002Fai-core\u002Fverification-security-workflow\u002Fresult-verification","19.ai-core\u002F04.verification-security-workflow\u002F04.result-verification",{"title":5211,"path":5212,"stem":5213},"Захист даних під час роботи з AI","\u002Fai-core\u002Fverification-security-workflow\u002Fdata-protection","19.ai-core\u002F04.verification-security-workflow\u002F05.data-protection",{"title":5215,"path":5216,"stem":5217},"Авторське право та навчальна доброчесність","\u002Fai-core\u002Fverification-security-workflow\u002Fcopyright-integrity","19.ai-core\u002F04.verification-security-workflow\u002F06.copyright-integrity",{"title":5219,"path":5220,"stem":5221},"Відповідальне використання AI","\u002Fai-core\u002Fverification-security-workflow\u002Fresponsible-use","19.ai-core\u002F04.verification-security-workflow\u002F07.responsible-use",{"title":5223,"path":5224,"stem":5225},"AI Native Workflow","\u002Fai-core\u002Fverification-security-workflow\u002Fai-native-workflow","19.ai-core\u002F04.verification-security-workflow\u002F08.ai-native-workflow",{"title":5227,"path":5228,"stem":5229},"Застосування AI Native Workflow під час створення цифрового продукту","\u002Fai-core\u002Fverification-security-workflow\u002Fworkflow-in-practice","19.ai-core\u002F04.verification-security-workflow\u002F09.workflow-in-practice",{"title":5231,"icon":5232,"path":5233,"stem":5234,"children":5235,"page":59},"AI Developer: Vibe Coding Sprint","i-lucide-code-xml","\u002Fai-developer","20.ai-developer",[5236,5262,5284,5305],{"title":5237,"icon":5238,"path":5239,"stem":5240,"children":5241,"page":59},"Проєктування і чорнова версія","i-lucide-pencil-ruler","\u002Fai-developer\u002Fdraft-creation","20.ai-developer\u002F01.draft-creation",[5242,5246,5250,5254,5258],{"title":5243,"path":5244,"stem":5245},"Парадигма Vibe Coding Workflow","\u002Fai-developer\u002Fdraft-creation\u002Fvibe-coding-workflow","20.ai-developer\u002F01.draft-creation\u002F01.vibe-coding-workflow",{"title":5247,"path":5248,"stem":5249},"AI-середовище швидкої розробки","\u002Fai-developer\u002Fdraft-creation\u002Fai-ide-environment","20.ai-developer\u002F01.draft-creation\u002F02.ai-ide-environment",{"title":5251,"path":5252,"stem":5253},"Користувацьке завдання та межі першої версії","\u002Fai-developer\u002Fdraft-creation\u002Fproduct-scope-and-mvp","20.ai-developer\u002F01.draft-creation\u002F03.product-scope-and-mvp",{"title":5255,"path":5256,"stem":5257},"Архітектура інтерфейсу та стани застосунку","\u002Fai-developer\u002Fdraft-creation\u002Fapplication-architecture-and-states","20.ai-developer\u002F01.draft-creation\u002F04.application-architecture-and-states",{"title":5259,"path":5260,"stem":5261},"Генерація та фіксація чорнової версії","\u002Fai-developer\u002Fdraft-creation\u002Fgenerating-draft-version","20.ai-developer\u002F01.draft-creation\u002F05.generating-draft-version",{"title":5263,"icon":5264,"path":5265,"stem":5266,"children":5267,"page":59},"Перша робоча версія","i-lucide-play-circle","\u002Fai-developer\u002Ffirst-working-version","20.ai-developer\u002F02.first-working-version",[5268,5272,5276,5280],{"title":5269,"path":5270,"stem":5271},"Уточнення контексту проєкту для AI","\u002Fai-developer\u002Ffirst-working-version\u002Frefining-project-context","20.ai-developer\u002F02.first-working-version\u002F01.refining-project-context",{"title":5273,"path":5274,"stem":5275},"Стратегія завдань для AI-розробки","\u002Fai-developer\u002Ffirst-working-version\u002Fai-prompting-strategy","20.ai-developer\u002F02.first-working-version\u002F02.ai-prompting-strategy",{"title":5277,"path":5278,"stem":5279},"Доопрацювання до першої робочої версії","\u002Fai-developer\u002Ffirst-working-version\u002Frefining-to-working-version","20.ai-developer\u002F02.first-working-version\u002F03.refining-to-working-version",{"title":5281,"path":5282,"stem":5283},"Перевірка першої робочої версії","\u002Fai-developer\u002Ffirst-working-version\u002Ftesting-first-working-version","20.ai-developer\u002F02.first-working-version\u002F04.testing-first-working-version",{"title":5285,"icon":3250,"path":5286,"stem":5287,"children":5288,"page":59},"Ітерації, дебагінг та відновлення","\u002Fai-developer\u002Fiteration-debugging-recovery","20.ai-developer\u002F03.iteration-debugging-recovery",[5289,5293,5297,5301],{"title":5290,"path":5291,"stem":5292},"Управління точковими змінами продукту","\u002Fai-developer\u002Fiteration-debugging-recovery\u002Fchange-management","20.ai-developer\u002F03.iteration-debugging-recovery\u002F01.change-management",{"title":5294,"path":5295,"stem":5296},"Надійність інтерфейсу та обробка помилок","\u002Fai-developer\u002Fiteration-debugging-recovery\u002Fscenario-reliability-and-errors","20.ai-developer\u002F03.iteration-debugging-recovery\u002F02.scenario-reliability-and-errors",{"title":5298,"path":5299,"stem":5300},"Керування контекстом і збереження версій","\u002Fai-developer\u002Fiteration-debugging-recovery\u002Fproject-context-and-versions","20.ai-developer\u002F03.iteration-debugging-recovery\u002F03.project-context-and-versions",{"title":5302,"path":5303,"stem":5304},"Збої AI-розробки, ліміти та аварійне відновлення","\u002Fai-developer\u002Fiteration-debugging-recovery\u002Fai-breakdowns-and-recovery","20.ai-developer\u002F03.iteration-debugging-recovery\u002F04.ai-breakdowns-and-recovery",{"title":5306,"icon":5307,"path":5308,"stem":5309,"children":5310,"page":59},"Перевірка та завершення продукту","i-lucide-check-check","\u002Fai-developer\u002Fverification-and-completion","20.ai-developer\u002F04.verification-and-completion",[5311,5315,5319],{"title":5312,"path":5313,"stem":5314},"Комплексний аудит та підсумкове тестування","\u002Fai-developer\u002Fverification-and-completion\u002Ffinal-product-testing","20.ai-developer\u002F04.verification-and-completion\u002F01.final-product-testing",{"title":5316,"path":5317,"stem":5318},"Підготовка підсумкової версії коду","\u002Fai-developer\u002Fverification-and-completion\u002Fpreparing-release-version","20.ai-developer\u002F04.verification-and-completion\u002F02.preparing-release-version",{"title":5320,"path":5321,"stem":5322},"Демонстрація, публікація та критерії оцінювання","\u002Fai-developer\u002Fverification-and-completion\u002Fproduct-showcase-and-publishing","20.ai-developer\u002F04.verification-and-completion\u002F03.product-showcase-and-publishing",{"title":5324,"path":5325,"stem":5326,"children":5327,"page":59},"Tailwind","\u002Ftailwind","21.tailwind",[5328,5332,5336,5340,5344,5348,5352,5356,5360,5364,5368,5372],{"title":5329,"path":5330,"stem":5331},"Що таке Tailwind CSS і навіщо він потрібен","\u002Ftailwind\u002Ftailwind-intro-philosophy","21.tailwind\u002F01.tailwind-intro-philosophy",{"title":5333,"path":5334,"stem":5335},"Встановлення та налаштування Tailwind CSS v4","\u002Ftailwind\u002Ftailwind-installation-setup","21.tailwind\u002F02.tailwind-installation-setup",{"title":5337,"path":5338,"stem":5339},"Utility-класи: основи та система Tailwind","\u002Ftailwind\u002Ftailwind-utility-classes-core","21.tailwind\u002F03.tailwind-utility-classes-core",{"title":5341,"path":5342,"stem":5343},"Layout: Flexbox та Grid через Tailwind","\u002Ftailwind\u002Ftailwind-flexbox-grid","21.tailwind\u002F04.tailwind-flexbox-grid",{"title":5345,"path":5346,"stem":5347},"Кастомізація теми через @theme у Tailwind v4","\u002Ftailwind\u002Ftailwind-theme-customization","21.tailwind\u002F05.tailwind-theme-customization",{"title":5349,"path":5350,"stem":5351},"Варіанти: hover, focus, responsive, dark mode та нові v4","\u002Ftailwind\u002Ftailwind-variants-states","21.tailwind\u002F06.tailwind-variants-states",{"title":5353,"path":5354,"stem":5355},"Типографіка та система кольорів у Tailwind v4","\u002Ftailwind\u002Ftailwind-typography-colors","21.tailwind\u002F07.tailwind-typography-colors",{"title":5357,"path":5358,"stem":5359},"Компоненти та повторюваність: @apply, @utility та патерни","\u002Ftailwind\u002Ftailwind-components-patterns","21.tailwind\u002F08.tailwind-components-patterns",{"title":5361,"path":5362,"stem":5363},"Темна тема та система дизайн-токенів у Tailwind v4","\u002Ftailwind\u002Ftailwind-dark-mode-theming","21.tailwind\u002F09.tailwind-dark-mode-theming",{"title":5365,"path":5366,"stem":5367},"Довільні значення та контейнерні запити у Tailwind v4","\u002Ftailwind\u002Ftailwind-arbitrary-container-queries","21.tailwind\u002F10.tailwind-arbitrary-container-queries",{"title":5369,"path":5370,"stem":5371},"Анімації, трансформації та 3D у Tailwind v4","\u002Ftailwind\u002Ftailwind-animations-transforms","21.tailwind\u002F11.tailwind-animations-transforms",{"title":5373,"path":5374,"stem":5375},"Tailwind CLI, PostCSS та інтеграція з фреймворками","\u002Ftailwind\u002Ftailwind-cli-tooling","21.tailwind\u002F12.tailwind-cli-tooling",{"title":5377,"path":5378,"stem":5379,"children":5380,"page":59},"React Typescript","\u002Freact-typescript","22.react-typescript",[5381,5406,5410,5414,5418,5422,5426,5430,5434,5438,5468,5472,5476,5480,5484],{"title":5382,"path":5383,"stem":5384,"children":5385,"page":59},"From Html To Project","\u002Freact-typescript\u002Ffrom-html-to-project","22.react-typescript\u002F01.from-html-to-project",[5386,5390,5394,5398,5402],{"title":5387,"path":5388,"stem":5389},"Від одного HTML-файлу до повноцінного проєкту","\u002Freact-typescript\u002Ffrom-html-to-project\u002Fevolution","22.react-typescript\u002F01.from-html-to-project\u002F01.evolution",{"title":5391,"path":5392,"stem":5393},"Що таке React","\u002Freact-typescript\u002Ffrom-html-to-project\u002Fwhat-is-react","22.react-typescript\u002F01.from-html-to-project\u002F02.what-is-react",{"title":5395,"path":5396,"stem":5397},"JSX та TSX — синтаксичний цукор, а не магія","\u002Freact-typescript\u002Ffrom-html-to-project\u002Fjsx-tsx-syntax","22.react-typescript\u002F01.from-html-to-project\u002F03.jsx-tsx-syntax",{"title":5399,"path":5400,"stem":5401},"Компоненти — будівельні блоки інтерфейсу","\u002Freact-typescript\u002Ffrom-html-to-project\u002Fcomponents","22.react-typescript\u002F01.from-html-to-project\u002F04.components",{"title":5403,"path":5404,"stem":5405},"JSX — розмітка всередині TypeScript","\u002Freact-typescript\u002Ffrom-html-to-project\u002Fjsx-expressions","22.react-typescript\u002F01.from-html-to-project\u002F05.jsx-expressions",{"title":5407,"path":5408,"stem":5409},"Хук useReducer: структуроване управління складним станом","\u002Freact-typescript\u002Fuse-reducer","22.react-typescript\u002F23.use-reducer",{"title":5411,"path":5412,"stem":5413},"Context API: передавання даних без «пропс-дрілінгу»","\u002Freact-typescript\u002Fcontext-api","22.react-typescript\u002F24.context-api",{"title":5415,"path":5416,"stem":5417},"Синхронізація з ефектами: хук useEffect та функції очищення","\u002Freact-typescript\u002Fuse-effect","22.react-typescript\u002F27.use-effect",{"title":5419,"path":5420,"stem":5421},"Можливо, вам не потрібен ефект: антипатерни та альтернативи","\u002Freact-typescript\u002Fyou-might-not-need-effect","22.react-typescript\u002F28.you-might-not-need-effect",{"title":5423,"path":5424,"stem":5425},"Життєвий цикл реактивних ефектів: мислення процесами синхронізації","\u002Freact-typescript\u002Flifecycle-of-reactive-effects","22.react-typescript\u002F29.lifecycle-of-reactive-effects",{"title":5427,"path":5428,"stem":5429},"Розділення подій та ефектів: реактивна проти нереактивної логіки","\u002Freact-typescript\u002Fseparating-events-from-effects","22.react-typescript\u002F30.separating-events-from-effects",{"title":5431,"path":5432,"stem":5433},"Видалення зайвих залежностей ефектів та оптимізація синхронізації","\u002Freact-typescript\u002Fremoving-effect-dependencies","22.react-typescript\u002F31.removing-effect-dependencies",{"title":5435,"path":5436,"stem":5437},"Кастомні хуки: повторне використання та композиція реактивної логіки","\u002Freact-typescript\u002Fcustom-hooks","22.react-typescript\u002F32.custom-hooks",{"title":5439,"path":5440,"stem":5441,"children":5442},"React Router v7: Маршрутизація в SPA","\u002Freact-typescript\u002Freact-router-v7","22.react-typescript\u002F33.react-router-v7\u002Findex",[5443,5444,5448,5452,5456,5460,5464],{"title":5439,"path":5440,"stem":5441},{"title":5445,"path":5446,"stem":5447},"Встановлення та базова конфігурація React Router v7","\u002Freact-typescript\u002Freact-router-v7\u002Finstallation-setup","22.react-typescript\u002F33.react-router-v7\u002F01.installation-setup",{"title":5449,"path":5450,"stem":5451},"Вкладені маршрути та Outlet: архітектура складних макетів","\u002Freact-typescript\u002Freact-router-v7\u002Fnested-routes-outlet","22.react-typescript\u002F33.react-router-v7\u002F02.nested-routes-outlet",{"title":5453,"path":5454,"stem":5455},"Динамічні маршрути та параметри URL","\u002Freact-typescript\u002Freact-router-v7\u002Fdynamic-routes-params","22.react-typescript\u002F33.react-router-v7\u002F03.dynamic-routes-params",{"title":5457,"path":5458,"stem":5459},"Навігація та корисні хуки React Router","\u002Freact-typescript\u002Freact-router-v7\u002Fnavigation-hooks","22.react-typescript\u002F33.react-router-v7\u002F04.navigation-hooks",{"title":5461,"path":5462,"stem":5463},"Обробка помилок та 404: ErrorBoundary і fallback-маршрути","\u002Freact-typescript\u002Freact-router-v7\u002Ferror-handling-404","22.react-typescript\u002F33.react-router-v7\u002F05.error-handling-404",{"title":5465,"path":5466,"stem":5467},"Data Router API: альтернативний синтаксис через createBrowserRouter","\u002Freact-typescript\u002Freact-router-v7\u002Fdata-router-api-examples","22.react-typescript\u002F33.react-router-v7\u002F06.data-router-api-examples",{"title":5469,"path":5470,"stem":5471},"Axios: HTTP-клієнт із розширеними можливостями","\u002Freact-typescript\u002Faxios","22.react-typescript\u002F34.axios",{"title":5473,"path":5474,"stem":5475},"Redux: класичний підхід до глобального стану","\u002Freact-typescript\u002Fredux-classic","22.react-typescript\u002F35.redux-classic",{"title":5477,"path":5478,"stem":5479},"Redux Toolkit: сучасний стандарт Redux","\u002Freact-typescript\u002Fredux-toolkit","22.react-typescript\u002F36.redux-toolkit",{"title":5481,"path":5482,"stem":5483},"RTK Query: запити до сервера без болю","\u002Freact-typescript\u002Frtk-query-tanstack-query","22.react-typescript\u002F38.rtk-query-tanstack-query",{"title":5485,"path":5486,"stem":5487},"React Hook Form + Zod: типобезпечна валідація форм","\u002Freact-typescript\u002Freact-hook-form-zod","22.react-typescript\u002F39.react-hook-form-zod",{"title":5489,"path":5490,"stem":5491},"Тестування компонентів діаграм та пісочниць","\u002Ftest-components","98.test-components",{"id":5493,"title":2926,"body":5494,"description":24972,"extension":24973,"links":24974,"meta":24975,"navigation":5689,"path":2927,"seo":24976,"stem":2928,"__hash__":24977},"docs\u002F05.python\u002F02.advanced\u002F00.modules-packages-venv.md",{"type":5495,"value":5496,"toc":24849},"minimark",[5497,5501,5506,5515,5523,5562,5573,5576,5580,5585,5610,5617,5660,5663,6144,6185,6189,6217,6357,6370,6374,6381,6399,6404,6411,6468,6471,6584,6588,6599,6796,6855,6862,6871,6880,6883,6930,6933,6937,6940,7268,7276,7293,7393,7400,7417,7419,7426,7432,7446,7677,7684,7803,7893,7902,7996,8003,8008,8081,8101,8121,8125,8138,8144,8214,8217,8224,8236,8248,8258,8273,8275,8282,8286,8300,8310,8527,8604,8610,8619,8803,8873,8885,8891,8901,9172,9193,9200,9206,9323,9349,9359,9361,9368,9372,9379,9407,9414,9628,9695,9703,9712,10210,10226,10233,10244,10310,10333,10335,10339,10343,10346,10513,10518,10645,10814,10818,10823,10826,10834,10839,10880,10894,10896,10900,10904,10907,10913,10923,10927,10930,12114,12121,12127,12143,12162,12171,12186,12230,12232,12236,12240,12249,12298,12305,12309,12315,12385,12398,12432,12438,12450,12575,12580,12601,12603,12607,12611,12614,12640,12655,12661,12791,12932,12939,12952,12967,12971,12974,12986,13033,13044,13109,13116,13140,13150,13154,13159,13223,13226,13232,13237,13251,13369,13374,13382,13482,13539,13544,13581,13588,13593,13601,13636,13683,13690,13737,13766,13768,13772,13782,13813,13827,13829,13835,13861,13919,13925,14014,14018,14077,14138,14147,14220,14224,14382,14471,14480,14580,14584,14590,14707,14721,14725,14733,14835,14883,14890,14899,14994,15005,15014,15024,15117,15175,15181,15750,15752,15758,15774,15821,15825,15916,15926,15930,15979,16054,16060,16069,16353,16356,16520,16612,16616,16622,16737,16742,17293,17295,17306,17313,17317,17320,17375,17385,17586,17596,17602,17768,17775,17787,17916,17923,18099,18101,18110,18132,18144,18148,18287,18293,18372,18441,18449,18597,18601,18935,18941,19003,19105,19112,19239,19244,19313,19317,19432,19446,19452,19547,19553,19775,19777,19791,19957,19973,19975,19979,19983,19990,19993,20012,20015,20017,20024,20033,20037,20251,20255,20376,20410,20412,20419,20435,20439,20606,20610,20747,20754,20757,20839,20845,20847,20853,20859,20863,20889,20893,21105,21109,21120,21269,21273,21286,21293,21409,21411,21422,21425,21433,21452,21458,21468,21807,21813,21912,21914,21921,21938,21945,21956,22120,22127,22139,22241,22248,22257,22422,22429,22446,22454,22562,22575,22577,22581,22584,22828,22840,22842,22846,22865,22869,22872,22902,22906,22909,24315,24317,24321,24616,24618,24622,24713,24715,24719,24768,24773,24845],[5498,5499,2926],"h1",{"id":5500},"модулі-пакети-та-віртуальні-середовища",[5502,5503,5505],"h2",{"id":5504},"проблема-монолітного-коду-навіщо-взагалі-ділити-програму","Проблема монолітного коду: навіщо взагалі ділити програму",[5507,5508,5509,5510,5514],"p",{},"Уявіть, що ви розробляєте платформу для онлайн-торгівлі. Перші кілька тижнів все ідеально: один файл ",[5511,5512,5513],"code",{},"main.py",", кілька функцій, чотири змінні. Але проходить місяць — і цей файл розростається до 2000 рядків. У ньому перемішані логіка авторизації, робота з базою даних, бізнес-правила знижок, генерація PDF-звітів та обробка платежів.",[5507,5516,5517,5518,5522],{},"Це явище має назву — ",[5519,5520,5521],"strong",{},"монолітний антипатерн",". Він не є проблемою теоретичною: він реально гальмує розробку, ламає командну роботу та перетворює підтримку коду на катування.",[5524,5525,5526,5540,5545,5557],"card-group",{},[5527,5528,5531,5532,5535,5536,5539],"card",{"icon":5529,"title":5530},"i-heroicons-eye-slash","Низька читабельність","Знайти функцію ",[5511,5533,5534],{},"calculate_vat"," серед 2000 рядків — це пригода. IDE допомагає, але лише до певної межі. Після неї — лише ",[5511,5537,5538],{},"Ctrl+F"," і терпіння.",[5527,5541,5544],{"icon":5542,"title":5543},"i-heroicons-users","Конфлікти у команді","Двоє розробників одночасно редагують один файл — це гарантований merge conflict у Git. Один файл = один потік змін.",[5527,5546,5549,5550,5553,5554,5556],{"icon":5547,"title":5548},"i-heroicons-arrow-path","Неможливість перевикористання","Ваша функція ",[5511,5551,5552],{},"send_email"," з ",[5511,5555,5513],{}," потрібна у новому проекті? Доведеться або копіювати, або тягнути весь монолітний файл разом із зайвим кодом.",[5527,5558,5561],{"icon":5559,"title":5560},"i-heroicons-beaker","Неможливість тестування","Як написати unit-тест для функції, що має десятки прихованих залежностей від глобального стану у тому ж файлі? Майже ніяк.",[5507,5563,5564,5565,5568,5569,5572],{},"Рішення, що пропонує Python, — це чотирирівнева система організації коду: ",[5519,5566,5567],{},"вирази → функції → модулі → пакети",". Ця стаття присвячена двом верхнім рівням і тому, як забезпечити їхню ізоляцію між проектами через ",[5519,5570,5571],{},"віртуальні середовища",".",[5574,5575],"hr",{},[5502,5577,5579],{"id":5578},"частина-i-модулі","Частина I: Модулі",[5581,5582,5584],"h3",{"id":5583},"що-таке-модуль-від-файлу-до-обєкта","Що таке модуль: від файлу до об'єкта",[5507,5586,5587,5588,5591,5592,5595,5596,5602,5603,5606,5607,5572],{},"З практичної точки зору, ",[5519,5589,5590],{},"модуль"," — це будь-який файл з розширенням ",[5511,5593,5594],{},".py",". Але це спрощення. З точки зору Python-рантайму, модуль — це ",[5519,5597,5598,5599],{},"об'єкт типу ",[5511,5600,5601],{},"types.ModuleType",", що має власний простір імен (",[5511,5604,5605],{},"namespace",") і зберігається у кеші ",[5511,5608,5609],{},"sys.modules",[5507,5611,5612,5613,5616],{},"Коли Python виконує ",[5511,5614,5615],{},"import calculator",", він не просто «підключає файл». Він:",[5618,5619,5620,5632,5638,5644,5647,5653],"ol",{},[5621,5622,5623,5624,5627,5628,5631],"li",{},"Знаходить файл ",[5511,5625,5626],{},"calculator.py"," (за алгоритмом ",[5511,5629,5630],{},"sys.path",")",[5621,5633,5634,5635,5631],{},"Компілює його у байткод (",[5511,5636,5637],{},"calculator.pyc",[5621,5639,5640,5641],{},"Створює новий об'єкт типу ",[5511,5642,5643],{},"module",[5621,5645,5646],{},"Виконує байткод у просторі імен цього об'єкта",[5621,5648,5649,5650],{},"Зберігає об'єкт у словнику ",[5511,5651,5652],{},"sys.modules['calculator']",[5621,5654,5655,5656,5659],{},"Прив'язує ім'я ",[5511,5657,5658],{},"calculator"," у поточному просторі імен",[5507,5661,5662],{},"Розглянемо цей процес на практичному прикладі. Побудуємо структуру реального mini-проекту:",[5664,5665,5666,6000],"code-tree",{},[5667,5668,5673],"pre",{"className":5669,"code":5670,"filename":5626,"language":5671,"meta":5672,"style":5672},"language-python shiki shiki-themes light-plus dark-plus dark-plus","# Модуль для математичних операцій\n\nPI = 3.1415926535  # Константа — публічний атрибут модуля\n\ndef add(a: float, b: float) -> float:\n    \"\"\"Повертає суму двох чисел.\"\"\"\n    return a + b\n\ndef subtract(a: float, b: float) -> float:\n    \"\"\"Повертає різницю двох чисел.\"\"\"\n    return a - b\n\ndef multiply(a: float, b: float) -> float:\n    \"\"\"Повертає добуток двох чисел.\"\"\"\n    return a * b\n\ndef circle_area(radius: float) -> float:\n    \"\"\"Обчислює площу кола через внутрішню константу PI.\"\"\"\n    return PI * radius ** 2\n\ndef _validate_numbers(*args) -> bool:\n    \"\"\"\n    Приватна функція за конвенцією (_prefix).\n    Не призначена для використання ззовні модуля.\n    \"\"\"\n    return all(isinstance(x, (int, float)) for x in args)\n","python","",[5511,5674,5675,5684,5691,5705,5710,5753,5760,5770,5775,5805,5811,5819,5824,5854,5860,5868,5873,5896,5902,5913,5918,5939,5945,5951,5957,5962],{"__ignoreMap":5672},[5676,5677,5680],"span",{"class":5678,"line":5679},"line",1,[5676,5681,5683],{"class":5682},"spJ8K","# Модуль для математичних операцій\n",[5676,5685,5687],{"class":5678,"line":5686},2,[5676,5688,5690],{"emptyLinePlaceholder":5689},true,"\n",[5676,5692,5694,5698,5702],{"class":5678,"line":5693},3,[5676,5695,5697],{"class":5696},"sHH4Y","PI = ",[5676,5699,5701],{"class":5700},"sJj4R","3.1415926535",[5676,5703,5704],{"class":5682},"  # Константа — публічний атрибут модуля\n",[5676,5706,5708],{"class":5678,"line":5707},4,[5676,5709,5690],{"emptyLinePlaceholder":5689},[5676,5711,5713,5717,5721,5724,5728,5731,5735,5738,5741,5743,5745,5748,5750],{"class":5678,"line":5712},5,[5676,5714,5716],{"class":5715},"su1O8","def",[5676,5718,5720],{"class":5719},"s8Opu"," add",[5676,5722,5723],{"class":5696},"(",[5676,5725,5727],{"class":5726},"siwwj","a",[5676,5729,5730],{"class":5696},": ",[5676,5732,5734],{"class":5733},"sN1BT","float",[5676,5736,5737],{"class":5696},", ",[5676,5739,5740],{"class":5726},"b",[5676,5742,5730],{"class":5696},[5676,5744,5734],{"class":5733},[5676,5746,5747],{"class":5696},") -> ",[5676,5749,5734],{"class":5733},[5676,5751,5752],{"class":5696},":\n",[5676,5754,5756],{"class":5678,"line":5755},6,[5676,5757,5759],{"class":5758},"sbdoH","    \"\"\"Повертає суму двох чисел.\"\"\"\n",[5676,5761,5763,5767],{"class":5678,"line":5762},7,[5676,5764,5766],{"class":5765},"s8xlr","    return",[5676,5768,5769],{"class":5696}," a + b\n",[5676,5771,5773],{"class":5678,"line":5772},8,[5676,5774,5690],{"emptyLinePlaceholder":5689},[5676,5776,5778,5780,5783,5785,5787,5789,5791,5793,5795,5797,5799,5801,5803],{"class":5678,"line":5777},9,[5676,5779,5716],{"class":5715},[5676,5781,5782],{"class":5719}," subtract",[5676,5784,5723],{"class":5696},[5676,5786,5727],{"class":5726},[5676,5788,5730],{"class":5696},[5676,5790,5734],{"class":5733},[5676,5792,5737],{"class":5696},[5676,5794,5740],{"class":5726},[5676,5796,5730],{"class":5696},[5676,5798,5734],{"class":5733},[5676,5800,5747],{"class":5696},[5676,5802,5734],{"class":5733},[5676,5804,5752],{"class":5696},[5676,5806,5808],{"class":5678,"line":5807},10,[5676,5809,5810],{"class":5758},"    \"\"\"Повертає різницю двох чисел.\"\"\"\n",[5676,5812,5814,5816],{"class":5678,"line":5813},11,[5676,5815,5766],{"class":5765},[5676,5817,5818],{"class":5696}," a - b\n",[5676,5820,5822],{"class":5678,"line":5821},12,[5676,5823,5690],{"emptyLinePlaceholder":5689},[5676,5825,5827,5829,5832,5834,5836,5838,5840,5842,5844,5846,5848,5850,5852],{"class":5678,"line":5826},13,[5676,5828,5716],{"class":5715},[5676,5830,5831],{"class":5719}," multiply",[5676,5833,5723],{"class":5696},[5676,5835,5727],{"class":5726},[5676,5837,5730],{"class":5696},[5676,5839,5734],{"class":5733},[5676,5841,5737],{"class":5696},[5676,5843,5740],{"class":5726},[5676,5845,5730],{"class":5696},[5676,5847,5734],{"class":5733},[5676,5849,5747],{"class":5696},[5676,5851,5734],{"class":5733},[5676,5853,5752],{"class":5696},[5676,5855,5857],{"class":5678,"line":5856},14,[5676,5858,5859],{"class":5758},"    \"\"\"Повертає добуток двох чисел.\"\"\"\n",[5676,5861,5863,5865],{"class":5678,"line":5862},15,[5676,5864,5766],{"class":5765},[5676,5866,5867],{"class":5696}," a * b\n",[5676,5869,5871],{"class":5678,"line":5870},16,[5676,5872,5690],{"emptyLinePlaceholder":5689},[5676,5874,5876,5878,5881,5883,5886,5888,5890,5892,5894],{"class":5678,"line":5875},17,[5676,5877,5716],{"class":5715},[5676,5879,5880],{"class":5719}," circle_area",[5676,5882,5723],{"class":5696},[5676,5884,5885],{"class":5726},"radius",[5676,5887,5730],{"class":5696},[5676,5889,5734],{"class":5733},[5676,5891,5747],{"class":5696},[5676,5893,5734],{"class":5733},[5676,5895,5752],{"class":5696},[5676,5897,5899],{"class":5678,"line":5898},18,[5676,5900,5901],{"class":5758},"    \"\"\"Обчислює площу кола через внутрішню константу PI.\"\"\"\n",[5676,5903,5905,5907,5910],{"class":5678,"line":5904},19,[5676,5906,5766],{"class":5765},[5676,5908,5909],{"class":5696}," PI * radius ** ",[5676,5911,5912],{"class":5700},"2\n",[5676,5914,5916],{"class":5678,"line":5915},20,[5676,5917,5690],{"emptyLinePlaceholder":5689},[5676,5919,5921,5923,5926,5929,5932,5934,5937],{"class":5678,"line":5920},21,[5676,5922,5716],{"class":5715},[5676,5924,5925],{"class":5719}," _validate_numbers",[5676,5927,5928],{"class":5696},"(*",[5676,5930,5931],{"class":5726},"args",[5676,5933,5747],{"class":5696},[5676,5935,5936],{"class":5733},"bool",[5676,5938,5752],{"class":5696},[5676,5940,5942],{"class":5678,"line":5941},22,[5676,5943,5944],{"class":5758},"    \"\"\"\n",[5676,5946,5948],{"class":5678,"line":5947},23,[5676,5949,5950],{"class":5758},"    Приватна функція за конвенцією (_prefix).\n",[5676,5952,5954],{"class":5678,"line":5953},24,[5676,5955,5956],{"class":5758},"    Не призначена для використання ззовні модуля.\n",[5676,5958,5960],{"class":5678,"line":5959},25,[5676,5961,5944],{"class":5758},[5676,5963,5965,5967,5970,5972,5975,5978,5981,5983,5985,5988,5991,5994,5997],{"class":5678,"line":5964},26,[5676,5966,5766],{"class":5765},[5676,5968,5969],{"class":5719}," all",[5676,5971,5723],{"class":5696},[5676,5973,5974],{"class":5719},"isinstance",[5676,5976,5977],{"class":5696},"(x, (",[5676,5979,5980],{"class":5733},"int",[5676,5982,5737],{"class":5696},[5676,5984,5734],{"class":5733},[5676,5986,5987],{"class":5696},")) ",[5676,5989,5990],{"class":5765},"for",[5676,5992,5993],{"class":5696}," x ",[5676,5995,5996],{"class":5765},"in",[5676,5998,5999],{"class":5696}," args)\n",[5667,6001,6003],{"className":5669,"code":6002,"filename":5513,"language":5671,"meta":5672,"style":5672},"# Головний скрипт, що використовує модуль calculator\n\nimport calculator  # Імпортуємо весь модуль\n\n# Доступ до атрибутів через ім'я модуля (крапкова нотація)\nresult = calculator.add(10, 5)\narea = calculator.circle_area(7.0)\n\nprint(f\"Сума: {result}\")              # 15\nprint(f\"Площа кола R=7: {area:.2f}\") # 153.94\nprint(f\"PI з модуля: {calculator.PI}\")\n",[5511,6004,6005,6010,6014,6025,6029,6034,6050,6060,6064,6095,6122],{"__ignoreMap":5672},[5676,6006,6007],{"class":5678,"line":5679},[5676,6008,6009],{"class":5682},"# Головний скрипт, що використовує модуль calculator\n",[5676,6011,6012],{"class":5678,"line":5686},[5676,6013,5690],{"emptyLinePlaceholder":5689},[5676,6015,6016,6019,6022],{"class":5678,"line":5693},[5676,6017,6018],{"class":5765},"import",[5676,6020,6021],{"class":5696}," calculator  ",[5676,6023,6024],{"class":5682},"# Імпортуємо весь модуль\n",[5676,6026,6027],{"class":5678,"line":5707},[5676,6028,5690],{"emptyLinePlaceholder":5689},[5676,6030,6031],{"class":5678,"line":5712},[5676,6032,6033],{"class":5682},"# Доступ до атрибутів через ім'я модуля (крапкова нотація)\n",[5676,6035,6036,6039,6042,6044,6047],{"class":5678,"line":5755},[5676,6037,6038],{"class":5696},"result = calculator.add(",[5676,6040,6041],{"class":5700},"10",[5676,6043,5737],{"class":5696},[5676,6045,6046],{"class":5700},"5",[5676,6048,6049],{"class":5696},")\n",[5676,6051,6052,6055,6058],{"class":5678,"line":5762},[5676,6053,6054],{"class":5696},"area = calculator.circle_area(",[5676,6056,6057],{"class":5700},"7.0",[5676,6059,6049],{"class":5696},[5676,6061,6062],{"class":5678,"line":5772},[5676,6063,5690],{"emptyLinePlaceholder":5689},[5676,6065,6066,6069,6071,6074,6077,6080,6083,6086,6089,6092],{"class":5678,"line":5777},[5676,6067,6068],{"class":5719},"print",[5676,6070,5723],{"class":5696},[5676,6072,6073],{"class":5715},"f",[5676,6075,6076],{"class":5758},"\"Сума: ",[5676,6078,6079],{"class":5715},"{",[5676,6081,6082],{"class":5696},"result",[5676,6084,6085],{"class":5715},"}",[5676,6087,6088],{"class":5758},"\"",[5676,6090,6091],{"class":5696},")              ",[5676,6093,6094],{"class":5682},"# 15\n",[5676,6096,6097,6099,6101,6103,6106,6108,6111,6114,6116,6119],{"class":5678,"line":5807},[5676,6098,6068],{"class":5719},[5676,6100,5723],{"class":5696},[5676,6102,6073],{"class":5715},[5676,6104,6105],{"class":5758},"\"Площа кола R=7: ",[5676,6107,6079],{"class":5715},[5676,6109,6110],{"class":5696},"area",[5676,6112,6113],{"class":5715},":.2f}",[5676,6115,6088],{"class":5758},[5676,6117,6118],{"class":5696},") ",[5676,6120,6121],{"class":5682},"# 153.94\n",[5676,6123,6124,6126,6128,6130,6133,6135,6138,6140,6142],{"class":5678,"line":5813},[5676,6125,6068],{"class":5719},[5676,6127,5723],{"class":5696},[5676,6129,6073],{"class":5715},[5676,6131,6132],{"class":5758},"\"PI з модуля: ",[5676,6134,6079],{"class":5715},[5676,6136,6137],{"class":5696},"calculator.PI",[5676,6139,6085],{"class":5715},[5676,6141,6088],{"class":5758},[5676,6143,6049],{"class":5696},[6145,6146,6148,6160,6169,6177],"terminal-preview",{"title":6147},"python main.py",[6149,6150,6152,6157,6158],"div",{"className":6151},[5678],[5676,6153,6156],{"className":6154},[6155],"opacity-40","$"," ",[5519,6159,6147],{},[6149,6161,6163,6164],{"className":6162},[5678],"Сума: ",[5676,6165,6168],{"className":6166},[6167],"text-green-400","15",[6149,6170,6172,6173],{"className":6171},[5678],"Площа кола R=7: ",[5676,6174,6176],{"className":6175},[6167],"153.94",[6149,6178,6180,6181],{"className":6179},[5678],"PI з модуля: ",[5676,6182,5701],{"className":6183},[6184],"text-blue-400",[5581,6186,6188],{"id":6187},"простір-імен-модуля-захист-від-конфліктів","Простір імен модуля: захист від конфліктів",[5507,6190,6191,6192,6194,6195,5737,6198,5737,6201,6204,6205,6209,6210,6212,6213,6216],{},"Коли ви пишете ",[5511,6193,5615],{},", Python не «вливає» імена ",[5511,6196,6197],{},"add",[5511,6199,6200],{},"subtract",[5511,6202,6203],{},"PI"," у поточний простір імен. Замість цього він створює ",[6206,6207,6208],"em",{},"одне"," ім'я ",[5511,6211,5658],{},", що вказує на об'єкт модуля. Доступ до вмісту — лише через крапку. Це і є ",[5519,6214,6215],{},"простір імен"," (namespace) — ізольований контейнер для імен.",[5667,6218,6220],{"className":5669,"code":6219,"language":5671,"meta":5672,"style":5672},"# main.py\nimport calculator\n\n# Наша власна функція add — для роботи з рядками\ndef add(text1: str, text2: str) -> str:\n    return text1 + \" \" + text2\n\n# Жодного конфлікту! Два різних простори імен:\nmy_text = add(\"Привіт\", \"Світ\")          # наша функція\ncalc_sum = calculator.add(2, 2)           # функція з модуля\n\nprint(my_text)    # \"Привіт Світ\"\nprint(calc_sum)   # 4\n",[5511,6221,6222,6227,6234,6238,6243,6274,6287,6291,6296,6315,6333,6337,6347],{"__ignoreMap":5672},[5676,6223,6224],{"class":5678,"line":5679},[5676,6225,6226],{"class":5682},"# main.py\n",[5676,6228,6229,6231],{"class":5678,"line":5686},[5676,6230,6018],{"class":5765},[5676,6232,6233],{"class":5696}," calculator\n",[5676,6235,6236],{"class":5678,"line":5693},[5676,6237,5690],{"emptyLinePlaceholder":5689},[5676,6239,6240],{"class":5678,"line":5707},[5676,6241,6242],{"class":5682},"# Наша власна функція add — для роботи з рядками\n",[5676,6244,6245,6247,6249,6251,6254,6256,6259,6261,6264,6266,6268,6270,6272],{"class":5678,"line":5712},[5676,6246,5716],{"class":5715},[5676,6248,5720],{"class":5719},[5676,6250,5723],{"class":5696},[5676,6252,6253],{"class":5726},"text1",[5676,6255,5730],{"class":5696},[5676,6257,6258],{"class":5733},"str",[5676,6260,5737],{"class":5696},[5676,6262,6263],{"class":5726},"text2",[5676,6265,5730],{"class":5696},[5676,6267,6258],{"class":5733},[5676,6269,5747],{"class":5696},[5676,6271,6258],{"class":5733},[5676,6273,5752],{"class":5696},[5676,6275,6276,6278,6281,6284],{"class":5678,"line":5755},[5676,6277,5766],{"class":5765},[5676,6279,6280],{"class":5696}," text1 + ",[5676,6282,6283],{"class":5758},"\" \"",[5676,6285,6286],{"class":5696}," + text2\n",[5676,6288,6289],{"class":5678,"line":5762},[5676,6290,5690],{"emptyLinePlaceholder":5689},[5676,6292,6293],{"class":5678,"line":5772},[5676,6294,6295],{"class":5682},"# Жодного конфлікту! Два різних простори імен:\n",[5676,6297,6298,6301,6304,6306,6309,6312],{"class":5678,"line":5777},[5676,6299,6300],{"class":5696},"my_text = add(",[5676,6302,6303],{"class":5758},"\"Привіт\"",[5676,6305,5737],{"class":5696},[5676,6307,6308],{"class":5758},"\"Світ\"",[5676,6310,6311],{"class":5696},")          ",[5676,6313,6314],{"class":5682},"# наша функція\n",[5676,6316,6317,6320,6323,6325,6327,6330],{"class":5678,"line":5807},[5676,6318,6319],{"class":5696},"calc_sum = calculator.add(",[5676,6321,6322],{"class":5700},"2",[5676,6324,5737],{"class":5696},[5676,6326,6322],{"class":5700},[5676,6328,6329],{"class":5696},")           ",[5676,6331,6332],{"class":5682},"# функція з модуля\n",[5676,6334,6335],{"class":5678,"line":5813},[5676,6336,5690],{"emptyLinePlaceholder":5689},[5676,6338,6339,6341,6344],{"class":5678,"line":5821},[5676,6340,6068],{"class":5719},[5676,6342,6343],{"class":5696},"(my_text)    ",[5676,6345,6346],{"class":5682},"# \"Привіт Світ\"\n",[5676,6348,6349,6351,6354],{"class":5678,"line":5826},[5676,6350,6068],{"class":5719},[5676,6352,6353],{"class":5696},"(calc_sum)   ",[5676,6355,6356],{"class":5682},"# 4\n",[5507,6358,6359,6360,6362,6363,6366,6367,5572],{},"Якби Python не використовував простори імен і замість ",[5511,6361,5615],{}," вставляв усі імена безпосередньо, виникала б катастрофа: будь-яка функція з будь-якого модуля могла б перезаписати будь-яку іншу. Саме тому ",[5511,6364,6365],{},"import module"," вважається більш безпечним підходом порівняно з ",[5511,6368,6369],{},"from module import *",[5581,6371,6373],{"id":6372},"поглиблене-розуміння-просторів-імен-namespaces-та-legb-правило","Поглиблене розуміння просторів імен (Namespaces) та LEGB-правило",[5507,6375,6376,6377,6380],{},"Щоб зрозуміти, як працює система імпорту та як уникнути помилок, пов'язаних із видимістю змінних, потрібно розібратися, що таке ",[5519,6378,6379],{},"простір імен (namespace)"," на низькому рівні.",[5507,6382,6383,6384,6390,6391,6394,6395,6398],{},"У Python простір імен — це ",[5519,6385,6386,6387,5631],{},"звичайний словник (",[5511,6388,6389],{},"dict",", де ключами є імена змінних (ідентифікатори), а значеннями — самі об'єкти, на які ці змінні посилаються. Коли ви пишете ",[5511,6392,6393],{},"x = 42",", Python просто додає запис ",[5511,6396,6397],{},"{\"x\": 42}"," у відповідний словник простору імен.",[6400,6401,6403],"h4",{"id":6402},"чотири-рівні-просторів-імен-та-legb-правило","Чотири рівні просторів імен та LEGB-правило",[5507,6405,6406,6407,6410],{},"Коли ви звертаєтеся до змінної, Python шукає її не скрізь, а в чітко визначеному порядку. Цей порядок описується ",[5519,6408,6409],{},"LEGB-правилом",":",[6412,6413,6414,6418,6428,6432,6435,6439,6442,6446],"steps",{},[5581,6415,6417],{"id":6416},"local-локальний","Local (Локальний)",[5507,6419,6420,6421,6423,6424,6427],{},"Змінні, визначені всередині поточної функції (через ",[5511,6422,5716],{}," або ",[5511,6425,6426],{},"lambda","). Вони створюються при виклику функції і знищуються при її завершенні.",[5581,6429,6431],{"id":6430},"enclosing-охоплюючий","Enclosing (Охоплюючий)",[5507,6433,6434],{},"Змінні у зовнішніх функціях (використовується при вкладених функціях або замиканнях).",[5581,6436,6438],{"id":6437},"global-глобальний","Global (Глобальний)",[5507,6440,6441],{},"Змінні, визначені на рівні модуля (файлу). Всі функції цього модуля мають доступ до цих змінних.",[5581,6443,6445],{"id":6444},"built-in-вбудований","Built-in (Вбудований)",[5507,6447,6448,6449,5737,6452,5737,6455,5737,6458,6460,6461,5737,6464,6467],{},"Назви, які автоматично завантажуються інтерпретатором при старті. Сюди входять вбудовані функції (",[5511,6450,6451],{},"print()",[5511,6453,6454],{},"len()",[5511,6456,6457],{},"range()",[5511,6459,6389],{},") та виключення (",[5511,6462,6463],{},"ValueError",[5511,6465,6466],{},"KeyError",").",[5507,6469,6470],{},"Схематично ієрархію пошуку імен можна зобразити у вигляді вкладених областей:",[6472,6473,6474],"plant-uml",{},[5667,6475,6479],{"className":6476,"code":6477,"language":6478,"meta":5672,"style":5672},"language-plantuml shiki shiki-themes light-plus dark-plus dark-plus","@startuml\nskinparam style plain\nskinparam backgroundColor #ffffff\nskinparam ArrowColor #6366f1\n\nnode \"Вбудований (Built-in)\\n[print(), len(), ValueError]\" as B #fee2e2 {\n    node \"Глобальний (Global)\\n[змінні та функції модуля]\" as G #dbeafe {\n        node \"Охоплюючий (Enclosing)\\n[зовнішня функція]\" as E #fef3c7 {\n            node \"Локальний (Local)\\n[поточна функція]\" as L #d1fae5 {\n            }\n        }\n    }\n}\n\nnote right of L\n  Пошук імені починається тут (L)\n  і йде назовні: L -> E -> G -> B.\n  Якщо ім'я не знайдено в жодному —\n  піднімається NameError.\nend note\n@enduml\n","plantuml",[5511,6480,6481,6486,6491,6496,6501,6505,6510,6515,6520,6525,6530,6535,6540,6545,6549,6554,6559,6564,6569,6574,6579],{"__ignoreMap":5672},[5676,6482,6483],{"class":5678,"line":5679},[5676,6484,6485],{},"@startuml\n",[5676,6487,6488],{"class":5678,"line":5686},[5676,6489,6490],{},"skinparam style plain\n",[5676,6492,6493],{"class":5678,"line":5693},[5676,6494,6495],{},"skinparam backgroundColor #ffffff\n",[5676,6497,6498],{"class":5678,"line":5707},[5676,6499,6500],{},"skinparam ArrowColor #6366f1\n",[5676,6502,6503],{"class":5678,"line":5712},[5676,6504,5690],{"emptyLinePlaceholder":5689},[5676,6506,6507],{"class":5678,"line":5755},[5676,6508,6509],{},"node \"Вбудований (Built-in)\\n[print(), len(), ValueError]\" as B #fee2e2 {\n",[5676,6511,6512],{"class":5678,"line":5762},[5676,6513,6514],{},"    node \"Глобальний (Global)\\n[змінні та функції модуля]\" as G #dbeafe {\n",[5676,6516,6517],{"class":5678,"line":5772},[5676,6518,6519],{},"        node \"Охоплюючий (Enclosing)\\n[зовнішня функція]\" as E #fef3c7 {\n",[5676,6521,6522],{"class":5678,"line":5777},[5676,6523,6524],{},"            node \"Локальний (Local)\\n[поточна функція]\" as L #d1fae5 {\n",[5676,6526,6527],{"class":5678,"line":5807},[5676,6528,6529],{},"            }\n",[5676,6531,6532],{"class":5678,"line":5813},[5676,6533,6534],{},"        }\n",[5676,6536,6537],{"class":5678,"line":5821},[5676,6538,6539],{},"    }\n",[5676,6541,6542],{"class":5678,"line":5826},[5676,6543,6544],{},"}\n",[5676,6546,6547],{"class":5678,"line":5856},[5676,6548,5690],{"emptyLinePlaceholder":5689},[5676,6550,6551],{"class":5678,"line":5862},[5676,6552,6553],{},"note right of L\n",[5676,6555,6556],{"class":5678,"line":5870},[5676,6557,6558],{},"  Пошук імені починається тут (L)\n",[5676,6560,6561],{"class":5678,"line":5875},[5676,6562,6563],{},"  і йде назовні: L -> E -> G -> B.\n",[5676,6565,6566],{"class":5678,"line":5898},[5676,6567,6568],{},"  Якщо ім'я не знайдено в жодному —\n",[5676,6570,6571],{"class":5678,"line":5904},[5676,6572,6573],{},"  піднімається NameError.\n",[5676,6575,6576],{"class":5678,"line":5915},[5676,6577,6578],{},"end note\n",[5676,6580,6581],{"class":5678,"line":5920},[5676,6582,6583],{},"@enduml\n",[6400,6585,6587],{"id":6586},"практичний-експеримент-дослідження-просторів-імен","Практичний експеримент: дослідження просторів імен",[5507,6589,6590,6591,6594,6595,6598],{},"Ми можемо дослідити поточні простори імен за допомогою вбудованих функцій ",[5511,6592,6593],{},"locals()"," та ",[5511,6596,6597],{},"globals()",", які повертають відповідні словники простору імен.",[5667,6600,6602],{"className":5669,"code":6601,"language":5671,"meta":5672,"style":5672},"# namespace_demo.py\nimport math\n\nglobal_var = \"Я глобальна змінна\"\n\ndef outer_function():\n    enclosing_var = \"Я охоплююча змінна\"\n\n    def inner_function():\n        local_var = \"Я локальна змінна\"\n\n        # Дивимося на локальний простір імен внутрішньої функції\n        print(\"--- Local Namespace inside inner_function() ---\")\n        print(locals())  # Виведе тільки {'local_var': 'Я локальна змінна'}\n\n        # Спробуємо знайти global_var та print (built-in)\n        # Python пройде шлях: inner_local -> outer_enclosing -> global -> built-in\n\n    inner_function()\n\nouter_function()\n\n# Глобальний простір імен модуля\nprint(\"\\n--- Global Namespace of module ---\")\n# globals() містить імпортований 'math', 'global_var', 'outer_function' та службові атрибути\nprint(list(globals().keys())[:10])  # покажемо перші 10 ключів\n",[5511,6603,6604,6609,6616,6620,6628,6632,6642,6650,6654,6664,6672,6676,6681,6693,6708,6712,6717,6722,6726,6731,6735,6740,6744,6749,6766,6771],{"__ignoreMap":5672},[5676,6605,6606],{"class":5678,"line":5679},[5676,6607,6608],{"class":5682},"# namespace_demo.py\n",[5676,6610,6611,6613],{"class":5678,"line":5686},[5676,6612,6018],{"class":5765},[5676,6614,6615],{"class":5696}," math\n",[5676,6617,6618],{"class":5678,"line":5693},[5676,6619,5690],{"emptyLinePlaceholder":5689},[5676,6621,6622,6625],{"class":5678,"line":5707},[5676,6623,6624],{"class":5696},"global_var = ",[5676,6626,6627],{"class":5758},"\"Я глобальна змінна\"\n",[5676,6629,6630],{"class":5678,"line":5712},[5676,6631,5690],{"emptyLinePlaceholder":5689},[5676,6633,6634,6636,6639],{"class":5678,"line":5755},[5676,6635,5716],{"class":5715},[5676,6637,6638],{"class":5719}," outer_function",[5676,6640,6641],{"class":5696},"():\n",[5676,6643,6644,6647],{"class":5678,"line":5762},[5676,6645,6646],{"class":5696},"    enclosing_var = ",[5676,6648,6649],{"class":5758},"\"Я охоплююча змінна\"\n",[5676,6651,6652],{"class":5678,"line":5772},[5676,6653,5690],{"emptyLinePlaceholder":5689},[5676,6655,6656,6659,6662],{"class":5678,"line":5777},[5676,6657,6658],{"class":5715},"    def",[5676,6660,6661],{"class":5719}," inner_function",[5676,6663,6641],{"class":5696},[5676,6665,6666,6669],{"class":5678,"line":5807},[5676,6667,6668],{"class":5696},"        local_var = ",[5676,6670,6671],{"class":5758},"\"Я локальна змінна\"\n",[5676,6673,6674],{"class":5678,"line":5813},[5676,6675,5690],{"emptyLinePlaceholder":5689},[5676,6677,6678],{"class":5678,"line":5821},[5676,6679,6680],{"class":5682},"        # Дивимося на локальний простір імен внутрішньої функції\n",[5676,6682,6683,6686,6688,6691],{"class":5678,"line":5826},[5676,6684,6685],{"class":5719},"        print",[5676,6687,5723],{"class":5696},[5676,6689,6690],{"class":5758},"\"--- Local Namespace inside inner_function() ---\"",[5676,6692,6049],{"class":5696},[5676,6694,6695,6697,6699,6702,6705],{"class":5678,"line":5856},[5676,6696,6685],{"class":5719},[5676,6698,5723],{"class":5696},[5676,6700,6701],{"class":5719},"locals",[5676,6703,6704],{"class":5696},"())  ",[5676,6706,6707],{"class":5682},"# Виведе тільки {'local_var': 'Я локальна змінна'}\n",[5676,6709,6710],{"class":5678,"line":5862},[5676,6711,5690],{"emptyLinePlaceholder":5689},[5676,6713,6714],{"class":5678,"line":5870},[5676,6715,6716],{"class":5682},"        # Спробуємо знайти global_var та print (built-in)\n",[5676,6718,6719],{"class":5678,"line":5875},[5676,6720,6721],{"class":5682},"        # Python пройде шлях: inner_local -> outer_enclosing -> global -> built-in\n",[5676,6723,6724],{"class":5678,"line":5898},[5676,6725,5690],{"emptyLinePlaceholder":5689},[5676,6727,6728],{"class":5678,"line":5904},[5676,6729,6730],{"class":5696},"    inner_function()\n",[5676,6732,6733],{"class":5678,"line":5915},[5676,6734,5690],{"emptyLinePlaceholder":5689},[5676,6736,6737],{"class":5678,"line":5920},[5676,6738,6739],{"class":5696},"outer_function()\n",[5676,6741,6742],{"class":5678,"line":5941},[5676,6743,5690],{"emptyLinePlaceholder":5689},[5676,6745,6746],{"class":5678,"line":5947},[5676,6747,6748],{"class":5682},"# Глобальний простір імен модуля\n",[5676,6750,6751,6753,6755,6757,6761,6764],{"class":5678,"line":5953},[5676,6752,6068],{"class":5719},[5676,6754,5723],{"class":5696},[5676,6756,6088],{"class":5758},[5676,6758,6760],{"class":6759},"sjcCO","\\n",[5676,6762,6763],{"class":5758},"--- Global Namespace of module ---\"",[5676,6765,6049],{"class":5696},[5676,6767,6768],{"class":5678,"line":5959},[5676,6769,6770],{"class":5682},"# globals() містить імпортований 'math', 'global_var', 'outer_function' та службові атрибути\n",[5676,6772,6773,6775,6777,6780,6782,6785,6788,6790,6793],{"class":5678,"line":5964},[5676,6774,6068],{"class":5719},[5676,6776,5723],{"class":5696},[5676,6778,6779],{"class":5733},"list",[5676,6781,5723],{"class":5696},[5676,6783,6784],{"class":5719},"globals",[5676,6786,6787],{"class":5696},"().keys())[:",[5676,6789,6041],{"class":5700},[5676,6791,6792],{"class":5696},"])  ",[5676,6794,6795],{"class":5682},"# покажемо перші 10 ключів\n",[6145,6797,6799,6807,6811,6819,6822,6826],{"title":6798},"python namespace_demo.py",[6149,6800,6802,6157,6805],{"className":6801},[5678],[5676,6803,6156],{"className":6804},[6155],[5519,6806,6798],{},[6149,6808,6810],{"className":6809},[5678],"--- Local Namespace inside inner_function() ---",[6149,6812,6814,6815,6085],{"className":6813},[5678],"{'local_var': ",[5676,6816,6818],{"className":6817},[6167],"'Я локальна змінна'",[6149,6820],{"className":6821},[5678],[6149,6823,6825],{"className":6824},[5678],"--- Global Namespace of module ---",[6149,6827,6829,6830,5737,6834,5737,6838,5737,6842,5737,6846,5737,6850,6854],{"className":6828},[5678],"[",[5676,6831,6833],{"className":6832},[6184],"'__name__'",[5676,6835,6837],{"className":6836},[6184],"'__doc__'",[5676,6839,6841],{"className":6840},[6184],"'__package__'",[5676,6843,6845],{"className":6844},[6184],"'math'",[5676,6847,6849],{"className":6848},[6184],"'global_var'",[5676,6851,6853],{"className":6852},[6184],"'outer_function'","]",[6400,6856,6858,6859],{"id":6857},"модуль-як-обєкт-та-його-атрибут-__dict__","Модуль як об'єкт та його атрибут ",[5511,6860,6861],{},"__dict__",[5507,6863,6864,6865,6867,6868,6870],{},"Оскільки кожен модуль після імпорту стає об'єктом типу ",[5511,6866,5643],{},", його простір імен зберігається в спеціальному атрибуті ",[5511,6869,6861],{},". Це звичайний словник.",[5507,6872,6191,6873,6876,6877],{},[5511,6874,6875],{},"calculator.add(5, 5)",", Python під капотом виконує:\n",[5511,6878,6879],{},"calculator.__dict__['add'](5, 5)",[5507,6881,6882],{},"Це означає, що ми можемо динамічно маніпулювати простором імен модуля навіть після його імпорту (хоча цим не варто зловживати):",[5667,6884,6886],{"className":5669,"code":6885,"language":5671,"meta":5672,"style":5672},"import calculator\n\n# Динамічно додаємо нове ім'я в простір імен модуля calculator\ncalculator.new_constant = 9.99\n\n# Тепер це ім'я доступне звичайним шляхом!\nprint(calculator.new_constant)  # 9.99\n",[5511,6887,6888,6894,6898,6903,6911,6915,6920],{"__ignoreMap":5672},[5676,6889,6890,6892],{"class":5678,"line":5679},[5676,6891,6018],{"class":5765},[5676,6893,6233],{"class":5696},[5676,6895,6896],{"class":5678,"line":5686},[5676,6897,5690],{"emptyLinePlaceholder":5689},[5676,6899,6900],{"class":5678,"line":5693},[5676,6901,6902],{"class":5682},"# Динамічно додаємо нове ім'я в простір імен модуля calculator\n",[5676,6904,6905,6908],{"class":5678,"line":5707},[5676,6906,6907],{"class":5696},"calculator.new_constant = ",[5676,6909,6910],{"class":5700},"9.99\n",[5676,6912,6913],{"class":5678,"line":5712},[5676,6914,5690],{"emptyLinePlaceholder":5689},[5676,6916,6917],{"class":5678,"line":5755},[5676,6918,6919],{"class":5682},"# Тепер це ім'я доступне звичайним шляхом!\n",[5676,6921,6922,6924,6927],{"class":5678,"line":5762},[5676,6923,6068],{"class":5719},[5676,6925,6926],{"class":5696},"(calculator.new_constant)  ",[5676,6928,6929],{"class":5682},"# 9.99\n",[5507,6931,6932],{},"Цей динамізм показує, що простір імен модулів у Python є відкритим і гнучким, на відміну від статичних просторів імен у таких мовах, як C++ або C#.",[5581,6934,6936],{"id":6935},"синтаксис-імпорту-вичерпний-огляд","Синтаксис імпорту: вичерпний огляд",[5507,6938,6939],{},"Python надає кілька синтаксичних форм для імпорту, кожна з яких має власну область застосування та компроміси.",[6941,6942,6943,7008,7088,7191],"tabs",{},[6944,6945,6946,7002],"tabs-item",{"label":6365},[5667,6947,6949],{"className":5669,"code":6948,"language":5671,"meta":5672,"style":5672},"import calculator\nimport os\nimport sys\n\n# Доступ лише через ім'я модуля — жодних конфліктів\nresult = calculator.add(10, 5)\ncwd = os.getcwd()\npaths = sys.path\n",[5511,6950,6951,6957,6964,6971,6975,6980,6992,6997],{"__ignoreMap":5672},[5676,6952,6953,6955],{"class":5678,"line":5679},[5676,6954,6018],{"class":5765},[5676,6956,6233],{"class":5696},[5676,6958,6959,6961],{"class":5678,"line":5686},[5676,6960,6018],{"class":5765},[5676,6962,6963],{"class":5696}," os\n",[5676,6965,6966,6968],{"class":5678,"line":5693},[5676,6967,6018],{"class":5765},[5676,6969,6970],{"class":5696}," sys\n",[5676,6972,6973],{"class":5678,"line":5707},[5676,6974,5690],{"emptyLinePlaceholder":5689},[5676,6976,6977],{"class":5678,"line":5712},[5676,6978,6979],{"class":5682},"# Доступ лише через ім'я модуля — жодних конфліктів\n",[5676,6981,6982,6984,6986,6988,6990],{"class":5678,"line":5755},[5676,6983,6038],{"class":5696},[5676,6985,6041],{"class":5700},[5676,6987,5737],{"class":5696},[5676,6989,6046],{"class":5700},[5676,6991,6049],{"class":5696},[5676,6993,6994],{"class":5678,"line":5762},[5676,6995,6996],{"class":5696},"cwd = os.getcwd()\n",[5676,6998,6999],{"class":5678,"line":5772},[5676,7000,7001],{"class":5696},"paths = sys.path\n",[5507,7003,7004,7007],{},[5519,7005,7006],{},"Коли використовувати:"," у більшості випадків. Максимальна чіткість: завжди видно, звідки прийшло ім'я.",[6944,7009,7011,7083],{"label":7010},"from module import name",[5667,7012,7014],{"className":5669,"code":7013,"language":5671,"meta":5672,"style":5672},"from calculator import add, PI\nfrom os.path import join, exists\n\n# Доступ безпосередньо\nresult = add(10, 5)\nfull_path = join(\"\u002Fhome\", \"user\", \"project\")\n",[5511,7015,7016,7029,7041,7045,7050,7063],{"__ignoreMap":5672},[5676,7017,7018,7021,7024,7026],{"class":5678,"line":5679},[5676,7019,7020],{"class":5765},"from",[5676,7022,7023],{"class":5696}," calculator ",[5676,7025,6018],{"class":5765},[5676,7027,7028],{"class":5696}," add, PI\n",[5676,7030,7031,7033,7036,7038],{"class":5678,"line":5686},[5676,7032,7020],{"class":5765},[5676,7034,7035],{"class":5696}," os.path ",[5676,7037,6018],{"class":5765},[5676,7039,7040],{"class":5696}," join, exists\n",[5676,7042,7043],{"class":5678,"line":5693},[5676,7044,5690],{"emptyLinePlaceholder":5689},[5676,7046,7047],{"class":5678,"line":5707},[5676,7048,7049],{"class":5682},"# Доступ безпосередньо\n",[5676,7051,7052,7055,7057,7059,7061],{"class":5678,"line":5712},[5676,7053,7054],{"class":5696},"result = add(",[5676,7056,6041],{"class":5700},[5676,7058,5737],{"class":5696},[5676,7060,6046],{"class":5700},[5676,7062,6049],{"class":5696},[5676,7064,7065,7068,7071,7073,7076,7078,7081],{"class":5678,"line":5755},[5676,7066,7067],{"class":5696},"full_path = join(",[5676,7069,7070],{"class":5758},"\"\u002Fhome\"",[5676,7072,5737],{"class":5696},[5676,7074,7075],{"class":5758},"\"user\"",[5676,7077,5737],{"class":5696},[5676,7079,7080],{"class":5758},"\"project\"",[5676,7082,6049],{"class":5696},[5507,7084,7085,7087],{},[5519,7086,7006],{}," якщо з великого модуля потрібні 1-3 конкретних об'єкти, і імена не конфліктують з локальними.",[6944,7089,7091,7186],{"label":7090},"import module as alias",[5667,7092,7094],{"className":5669,"code":7093,"language":5671,"meta":5672,"style":5672},"import calculator as calc\nimport numpy as np          # галузева конвенція\nimport matplotlib.pyplot as plt  # галузева конвенція\nimport pandas as pd\n\nresult = calc.add(2, 3)\narray = np.array([1, 2, 3])\n",[5511,7095,7096,7108,7123,7137,7149,7153,7167],{"__ignoreMap":5672},[5676,7097,7098,7100,7102,7105],{"class":5678,"line":5679},[5676,7099,6018],{"class":5765},[5676,7101,7023],{"class":5696},[5676,7103,7104],{"class":5765},"as",[5676,7106,7107],{"class":5696}," calc\n",[5676,7109,7110,7112,7115,7117,7120],{"class":5678,"line":5686},[5676,7111,6018],{"class":5765},[5676,7113,7114],{"class":5696}," numpy ",[5676,7116,7104],{"class":5765},[5676,7118,7119],{"class":5696}," np          ",[5676,7121,7122],{"class":5682},"# галузева конвенція\n",[5676,7124,7125,7127,7130,7132,7135],{"class":5678,"line":5693},[5676,7126,6018],{"class":5765},[5676,7128,7129],{"class":5696}," matplotlib.pyplot ",[5676,7131,7104],{"class":5765},[5676,7133,7134],{"class":5696}," plt  ",[5676,7136,7122],{"class":5682},[5676,7138,7139,7141,7144,7146],{"class":5678,"line":5707},[5676,7140,6018],{"class":5765},[5676,7142,7143],{"class":5696}," pandas ",[5676,7145,7104],{"class":5765},[5676,7147,7148],{"class":5696}," pd\n",[5676,7150,7151],{"class":5678,"line":5712},[5676,7152,5690],{"emptyLinePlaceholder":5689},[5676,7154,7155,7158,7160,7162,7165],{"class":5678,"line":5755},[5676,7156,7157],{"class":5696},"result = calc.add(",[5676,7159,6322],{"class":5700},[5676,7161,5737],{"class":5696},[5676,7163,7164],{"class":5700},"3",[5676,7166,6049],{"class":5696},[5676,7168,7169,7172,7175,7177,7179,7181,7183],{"class":5678,"line":5762},[5676,7170,7171],{"class":5696},"array = np.array([",[5676,7173,7174],{"class":5700},"1",[5676,7176,5737],{"class":5696},[5676,7178,6322],{"class":5700},[5676,7180,5737],{"class":5696},[5676,7182,7164],{"class":5700},[5676,7184,7185],{"class":5696},"])\n",[5507,7187,7188,7190],{},[5519,7189,7006],{}," якщо ім'я модуля довге або є загальноприйнятий псевдонім у спільноті.",[6944,7192,7194,7245,7250],{"label":7193},"⚠️ from module import \\*",[5667,7195,7197],{"className":5669,"code":7196,"language":5671,"meta":5672,"style":5672},"# ❌ НІКОЛИ НЕ РОБІТЬ ТАК У PRODUCTION-КОДІ\nfrom calculator import *\n\n# Тепер у просторі імен є: add, subtract, multiply, circle_area, PI\n# Але звідки вони взялися? Невідомо без читання calculator.py\nresult = add(5, 5)  # яка це функція? наша? із calculator? з іншого модуля?\n",[5511,7198,7199,7204,7215,7219,7224,7229],{"__ignoreMap":5672},[5676,7200,7201],{"class":5678,"line":5679},[5676,7202,7203],{"class":5682},"# ❌ НІКОЛИ НЕ РОБІТЬ ТАК У PRODUCTION-КОДІ\n",[5676,7205,7206,7208,7210,7212],{"class":5678,"line":5686},[5676,7207,7020],{"class":5765},[5676,7209,7023],{"class":5696},[5676,7211,6018],{"class":5765},[5676,7213,7214],{"class":5696}," *\n",[5676,7216,7217],{"class":5678,"line":5693},[5676,7218,5690],{"emptyLinePlaceholder":5689},[5676,7220,7221],{"class":5678,"line":5707},[5676,7222,7223],{"class":5682},"# Тепер у просторі імен є: add, subtract, multiply, circle_area, PI\n",[5676,7225,7226],{"class":5678,"line":5712},[5676,7227,7228],{"class":5682},"# Але звідки вони взялися? Невідомо без читання calculator.py\n",[5676,7230,7231,7233,7235,7237,7239,7242],{"class":5678,"line":5755},[5676,7232,7054],{"class":5696},[5676,7234,6046],{"class":5700},[5676,7236,5737],{"class":5696},[5676,7238,6046],{"class":5700},[5676,7240,7241],{"class":5696},")  ",[5676,7243,7244],{"class":5682},"# яка це функція? наша? із calculator? з іншого модуля?\n",[5507,7246,7247],{},[5519,7248,7249],{},"Чому це погано:",[7251,7252,7253,7256,7265],"ul",{},[5621,7254,7255],{},"Забруднює простір імен непередбачуваною кількістю імен",[5621,7257,7258,7259,7261,7262,7264],{},"Гарантовані приховані конфлікти: якщо ",[5511,7260,5658],{}," і ваш код мають функцію ",[5511,7263,6197],{},", одна мовчки перезапише іншу",[5621,7266,7267],{},"IDE та статичні аналізатори не можуть розібратися у таких імпортах",[5581,7269,7271,7272,7275],{"id":7270},"конвенція-_private-приватні-атрибути-модуля","Конвенція ",[5511,7273,7274],{},"_private",": приватні атрибути модуля",[5507,7277,7278,7279,6423,7282,7285,7286,5572],{},"У Python немає ключових слів ",[5511,7280,7281],{},"private",[5511,7283,7284],{},"protected",". Натомість існує конвенція: ",[5519,7287,7288,7289,7292],{},"ім'я, що починається з одного підкреслення (",[5511,7290,7291],{},"_name","), є сигналом «не призначене для публічного використання»",[5667,7294,7296],{"className":5669,"code":7295,"language":5671,"meta":5672,"style":5672},"# calculator.py\nPI = 3.14159          # публічний атрибут ✅\n_precision = 10       # «приватний» атрибут — для внутрішнього використання\n\ndef add(a, b):        # публічна функція ✅\n    return a + b\n\ndef _validate(x):     # «приватна» функція — деталь реалізації\n    return isinstance(x, (int, float))\n",[5511,7297,7298,7303,7313,7323,7327,7347,7353,7357,7375],{"__ignoreMap":5672},[5676,7299,7300],{"class":5678,"line":5679},[5676,7301,7302],{"class":5682},"# calculator.py\n",[5676,7304,7305,7307,7310],{"class":5678,"line":5686},[5676,7306,5697],{"class":5696},[5676,7308,7309],{"class":5700},"3.14159",[5676,7311,7312],{"class":5682},"          # публічний атрибут ✅\n",[5676,7314,7315,7318,7320],{"class":5678,"line":5693},[5676,7316,7317],{"class":5696},"_precision = ",[5676,7319,6041],{"class":5700},[5676,7321,7322],{"class":5682},"       # «приватний» атрибут — для внутрішнього використання\n",[5676,7324,7325],{"class":5678,"line":5707},[5676,7326,5690],{"emptyLinePlaceholder":5689},[5676,7328,7329,7331,7333,7335,7337,7339,7341,7344],{"class":5678,"line":5712},[5676,7330,5716],{"class":5715},[5676,7332,5720],{"class":5719},[5676,7334,5723],{"class":5696},[5676,7336,5727],{"class":5726},[5676,7338,5737],{"class":5696},[5676,7340,5740],{"class":5726},[5676,7342,7343],{"class":5696},"):        ",[5676,7345,7346],{"class":5682},"# публічна функція ✅\n",[5676,7348,7349,7351],{"class":5678,"line":5755},[5676,7350,5766],{"class":5765},[5676,7352,5769],{"class":5696},[5676,7354,7355],{"class":5678,"line":5762},[5676,7356,5690],{"emptyLinePlaceholder":5689},[5676,7358,7359,7361,7364,7366,7369,7372],{"class":5678,"line":5772},[5676,7360,5716],{"class":5715},[5676,7362,7363],{"class":5719}," _validate",[5676,7365,5723],{"class":5696},[5676,7367,7368],{"class":5726},"x",[5676,7370,7371],{"class":5696},"):     ",[5676,7373,7374],{"class":5682},"# «приватна» функція — деталь реалізації\n",[5676,7376,7377,7379,7382,7384,7386,7388,7390],{"class":5678,"line":5777},[5676,7378,5766],{"class":5765},[5676,7380,7381],{"class":5719}," isinstance",[5676,7383,5977],{"class":5696},[5676,7385,5980],{"class":5733},[5676,7387,5737],{"class":5696},[5676,7389,5734],{"class":5733},[5676,7391,7392],{"class":5696},"))\n",[5507,7394,7395,7396,7399],{},"Технічно ",[5511,7397,7398],{},"calculator._validate(5)"," спрацює без помилок — Python лише сигналізує, але не забороняє. Проте конвенція дотримується всією екосистемою: IDE підсвічують такий виклик, linter-и видають попередження, а рецензенти коду запитають: «Навіщо ти лізеш у внутрішності чужого модуля?»",[5507,7401,7402,7403,7405,7406,7409,7410,7413,7414,5572],{},"Ця конвенція також впливає на ",[5511,7404,6369],{},": якщо ваш модуль не визначає ",[5511,7407,7408],{},"__all__",", зірковий імпорт ",[5519,7411,7412],{},"пропускає"," всі імена з підкресленням — це одна з небагатьох корисних властивостей ",[5511,7415,7416],{},"import *",[5574,7418],{},[5502,7420,7422,7423,7425],{"id":7421},"система-пошуку-модулів-syspath-зсередини","Система пошуку модулів: ",[5511,7424,5630],{}," зсередини",[5581,7427,7429,7430],{"id":7428},"алгоритм-пошуку-import","Алгоритм пошуку ",[5511,7431,6018],{},[5507,7433,7434,7435,7438,7439,7442,7443,7445],{},"Коли Python зустрічає ",[5511,7436,7437],{},"import my_module",", він не шукає файл одразу по всій файловій системі. Він послідовно перевіряє ",[5519,7440,7441],{},"ієрархічний список директорій",", що зберігається у ",[5511,7444,5630],{}," — списку рядків, де кожен рядок є абсолютним шляхом до директорії.",[6472,7447,7448],{},[5667,7449,7451],{"className":6476,"code":7450,"language":6478,"meta":5672,"style":5672},"@startuml\nskinparam style plain\nskinparam backgroundColor #ffffff\nskinparam ArrowColor #6366f1\n\nstart\n\n:Python зустрічає: import my_module;\n\n:Перевірити sys.modules[\"my_module\"];\n\nif (знайдено у кеші?) then (Так)\n    :Повернути кешований об'єкт модуля;\n    stop\nelse (Ні)\n    :Ітерація по sys.path;\n    note right\n      sys.path — це список:\n      1. Директорія поточного скрипта\n      2. Шляхи з PYTHONPATH\n      3. Стандартна бібліотека\n      4. site-packages (pip)\n    end note\nendif\n\n:Для кожного шляху в sys.path:;\n\nif (my_module.py існує у шляху?) then (Так)\n    :Компілювати у байткод (.pyc);\n    :Створити об'єкт types.ModuleType;\n    :Виконати байткод у просторі імен модуля;\n    :Зберегти у sys.modules[\"my_module\"];\n    :Прив'язати ім'я my_module у поточному просторі;\n    stop\nelse (Ні)\n    :Перейти до наступного шляху;\n    if (Вичерпано усі шляхи?) then (Так)\n        :Підняти ModuleNotFoundError;\n        stop\n    else (Ні)\n        :Продовжити пошук;\n    endif\nendif\n@enduml\n",[5511,7452,7453,7457,7461,7465,7469,7473,7478,7482,7487,7491,7496,7500,7505,7510,7515,7520,7525,7530,7535,7540,7545,7550,7555,7560,7565,7569,7574,7579,7585,7591,7597,7603,7609,7615,7620,7625,7631,7637,7643,7649,7655,7661,7667,7672],{"__ignoreMap":5672},[5676,7454,7455],{"class":5678,"line":5679},[5676,7456,6485],{},[5676,7458,7459],{"class":5678,"line":5686},[5676,7460,6490],{},[5676,7462,7463],{"class":5678,"line":5693},[5676,7464,6495],{},[5676,7466,7467],{"class":5678,"line":5707},[5676,7468,6500],{},[5676,7470,7471],{"class":5678,"line":5712},[5676,7472,5690],{"emptyLinePlaceholder":5689},[5676,7474,7475],{"class":5678,"line":5755},[5676,7476,7477],{},"start\n",[5676,7479,7480],{"class":5678,"line":5762},[5676,7481,5690],{"emptyLinePlaceholder":5689},[5676,7483,7484],{"class":5678,"line":5772},[5676,7485,7486],{},":Python зустрічає: import my_module;\n",[5676,7488,7489],{"class":5678,"line":5777},[5676,7490,5690],{"emptyLinePlaceholder":5689},[5676,7492,7493],{"class":5678,"line":5807},[5676,7494,7495],{},":Перевірити sys.modules[\"my_module\"];\n",[5676,7497,7498],{"class":5678,"line":5813},[5676,7499,5690],{"emptyLinePlaceholder":5689},[5676,7501,7502],{"class":5678,"line":5821},[5676,7503,7504],{},"if (знайдено у кеші?) then (Так)\n",[5676,7506,7507],{"class":5678,"line":5826},[5676,7508,7509],{},"    :Повернути кешований об'єкт модуля;\n",[5676,7511,7512],{"class":5678,"line":5856},[5676,7513,7514],{},"    stop\n",[5676,7516,7517],{"class":5678,"line":5862},[5676,7518,7519],{},"else (Ні)\n",[5676,7521,7522],{"class":5678,"line":5870},[5676,7523,7524],{},"    :Ітерація по sys.path;\n",[5676,7526,7527],{"class":5678,"line":5875},[5676,7528,7529],{},"    note right\n",[5676,7531,7532],{"class":5678,"line":5898},[5676,7533,7534],{},"      sys.path — це список:\n",[5676,7536,7537],{"class":5678,"line":5904},[5676,7538,7539],{},"      1. Директорія поточного скрипта\n",[5676,7541,7542],{"class":5678,"line":5915},[5676,7543,7544],{},"      2. Шляхи з PYTHONPATH\n",[5676,7546,7547],{"class":5678,"line":5920},[5676,7548,7549],{},"      3. Стандартна бібліотека\n",[5676,7551,7552],{"class":5678,"line":5941},[5676,7553,7554],{},"      4. site-packages (pip)\n",[5676,7556,7557],{"class":5678,"line":5947},[5676,7558,7559],{},"    end note\n",[5676,7561,7562],{"class":5678,"line":5953},[5676,7563,7564],{},"endif\n",[5676,7566,7567],{"class":5678,"line":5959},[5676,7568,5690],{"emptyLinePlaceholder":5689},[5676,7570,7571],{"class":5678,"line":5964},[5676,7572,7573],{},":Для кожного шляху в sys.path:;\n",[5676,7575,7577],{"class":5678,"line":7576},27,[5676,7578,5690],{"emptyLinePlaceholder":5689},[5676,7580,7582],{"class":5678,"line":7581},28,[5676,7583,7584],{},"if (my_module.py існує у шляху?) then (Так)\n",[5676,7586,7588],{"class":5678,"line":7587},29,[5676,7589,7590],{},"    :Компілювати у байткод (.pyc);\n",[5676,7592,7594],{"class":5678,"line":7593},30,[5676,7595,7596],{},"    :Створити об'єкт types.ModuleType;\n",[5676,7598,7600],{"class":5678,"line":7599},31,[5676,7601,7602],{},"    :Виконати байткод у просторі імен модуля;\n",[5676,7604,7606],{"class":5678,"line":7605},32,[5676,7607,7608],{},"    :Зберегти у sys.modules[\"my_module\"];\n",[5676,7610,7612],{"class":5678,"line":7611},33,[5676,7613,7614],{},"    :Прив'язати ім'я my_module у поточному просторі;\n",[5676,7616,7618],{"class":5678,"line":7617},34,[5676,7619,7514],{},[5676,7621,7623],{"class":5678,"line":7622},35,[5676,7624,7519],{},[5676,7626,7628],{"class":5678,"line":7627},36,[5676,7629,7630],{},"    :Перейти до наступного шляху;\n",[5676,7632,7634],{"class":5678,"line":7633},37,[5676,7635,7636],{},"    if (Вичерпано усі шляхи?) then (Так)\n",[5676,7638,7640],{"class":5678,"line":7639},38,[5676,7641,7642],{},"        :Підняти ModuleNotFoundError;\n",[5676,7644,7646],{"class":5678,"line":7645},39,[5676,7647,7648],{},"        stop\n",[5676,7650,7652],{"class":5678,"line":7651},40,[5676,7653,7654],{},"    else (Ні)\n",[5676,7656,7658],{"class":5678,"line":7657},41,[5676,7659,7660],{},"        :Продовжити пошук;\n",[5676,7662,7664],{"class":5678,"line":7663},42,[5676,7665,7666],{},"    endif\n",[5676,7668,7670],{"class":5678,"line":7669},43,[5676,7671,7564],{},[5676,7673,7675],{"class":5678,"line":7674},44,[5676,7676,6583],{},[5581,7678,7680,7681,7683],{"id":7679},"анатомія-syspath-що-там-насправді","Анатомія ",[5511,7682,5630],{},": що там насправді",[5667,7685,7687],{"className":5669,"code":7686,"language":5671,"meta":5672,"style":5672},"import sys\n\nprint(f\"Тип sys.path: {type(sys.path)}\")  # \u003Cclass 'list'>\nprint(f\"Кількість шляхів: {len(sys.path)}\")\n\nfor i, path in enumerate(sys.path):\n    print(f\"  [{i}] {path}\")\n",[5511,7688,7689,7695,7699,7727,7751,7755,7770],{"__ignoreMap":5672},[5676,7690,7691,7693],{"class":5678,"line":5679},[5676,7692,6018],{"class":5765},[5676,7694,6970],{"class":5696},[5676,7696,7697],{"class":5678,"line":5686},[5676,7698,5690],{"emptyLinePlaceholder":5689},[5676,7700,7701,7703,7705,7707,7710,7712,7715,7718,7720,7722,7724],{"class":5678,"line":5693},[5676,7702,6068],{"class":5719},[5676,7704,5723],{"class":5696},[5676,7706,6073],{"class":5715},[5676,7708,7709],{"class":5758},"\"Тип sys.path: ",[5676,7711,6079],{"class":5715},[5676,7713,7714],{"class":5733},"type",[5676,7716,7717],{"class":5696},"(sys.path)",[5676,7719,6085],{"class":5715},[5676,7721,6088],{"class":5758},[5676,7723,7241],{"class":5696},[5676,7725,7726],{"class":5682},"# \u003Cclass 'list'>\n",[5676,7728,7729,7731,7733,7735,7738,7740,7743,7745,7747,7749],{"class":5678,"line":5707},[5676,7730,6068],{"class":5719},[5676,7732,5723],{"class":5696},[5676,7734,6073],{"class":5715},[5676,7736,7737],{"class":5758},"\"Кількість шляхів: ",[5676,7739,6079],{"class":5715},[5676,7741,7742],{"class":5719},"len",[5676,7744,7717],{"class":5696},[5676,7746,6085],{"class":5715},[5676,7748,6088],{"class":5758},[5676,7750,6049],{"class":5696},[5676,7752,7753],{"class":5678,"line":5712},[5676,7754,5690],{"emptyLinePlaceholder":5689},[5676,7756,7757,7759,7762,7764,7767],{"class":5678,"line":5755},[5676,7758,5990],{"class":5765},[5676,7760,7761],{"class":5696}," i, path ",[5676,7763,5996],{"class":5765},[5676,7765,7766],{"class":5719}," enumerate",[5676,7768,7769],{"class":5696},"(sys.path):\n",[5676,7771,7772,7775,7777,7779,7782,7784,7787,7789,7792,7794,7797,7799,7801],{"class":5678,"line":5762},[5676,7773,7774],{"class":5719},"    print",[5676,7776,5723],{"class":5696},[5676,7778,6073],{"class":5715},[5676,7780,7781],{"class":5758},"\"  [",[5676,7783,6079],{"class":5715},[5676,7785,7786],{"class":5696},"i",[5676,7788,6085],{"class":5715},[5676,7790,7791],{"class":5758},"] ",[5676,7793,6079],{"class":5715},[5676,7795,7796],{"class":5696},"path",[5676,7798,6085],{"class":5715},[5676,7800,6088],{"class":5758},[5676,7802,6049],{"class":5696},[6145,7804,7806,7814,7822,7831,7845,7853,7865,7873,7885],{"title":7805},"python inspect_path.py",[6149,7807,7809,6157,7812],{"className":7808},[5678],[5676,7810,6156],{"className":7811},[6155],[5519,7813,7805],{},[6149,7815,7817,7818],{"className":7816},[5678],"Тип sys.path: ",[5676,7819,7821],{"className":7820},[6184],"\u003Cclass 'list'>",[6149,7823,7825,7826],{"className":7824},[5678],"Кількість шляхів: ",[5676,7827,7830],{"className":7828},[7829],"text-yellow-400","6",[6149,7832,7834,7835,7839,7840],{"className":7833},[5678],"  [0] ",[5676,7836,7838],{"className":7837},[6167],"\u002Fhome\u002Fuser\u002Fmyproject","  ",[5676,7841,7844],{"className":7842},[7843],"text-gray-400","# директорія запущеного скрипта",[6149,7846,7848,7849],{"className":7847},[5678],"  [1] ",[5676,7850,7852],{"className":7851},[7843],"\u002Fusr\u002Flib\u002Fpython312.zip",[6149,7854,7856,7857,7839,7861],{"className":7855},[5678],"  [2] ",[5676,7858,7860],{"className":7859},[6184],"\u002Fusr\u002Flib\u002Fpython3.12",[5676,7862,7864],{"className":7863},[7843],"# стандартна бібліотека",[6149,7866,7868,7869],{"className":7867},[5678],"  [3] ",[5676,7870,7872],{"className":7871},[6184],"\u002Fusr\u002Flib\u002Fpython3.12\u002Flib-dynload",[6149,7874,7876,7877,7839,7881],{"className":7875},[5678],"  [4] ",[5676,7878,7880],{"className":7879},[6167],"\u002Fhome\u002Fuser\u002F.venv\u002Flib\u002Fpython3.12\u002Fsite-packages",[5676,7882,7884],{"className":7883},[7843],"# pip-пакети",[6149,7886,7888,7889],{"className":7887},[5678],"  [5] ",[5676,7890,7892],{"className":7891},[6184],"\u002Fusr\u002Flib\u002Fpython3\u002Fdist-packages",[5507,7894,7895,7901],{},[5519,7896,7897,7898,7900],{},"Звідки формується ",[5511,7899,5630],{},"?"," Це не магія — список складається з кількох джерел у визначеному порядку пріоритету:",[7903,7904,7905,7940,7952,7971],"field-group",{},[7906,7907,7910,7911,7914,7915,7918,7919,7921,7922,7924,7925,7927,7928,7931,7932,7935,7936,7939],"field",{"name":7908,"type":7909},"sys.path[0] — директорія скрипта","string","При запуску ",[5511,7912,7913],{},"python \u002Fhome\u002Fuser\u002Fproject\u002Fmain.py"," Python автоматично ставить на перше місце ",[5511,7916,7917],{},"\u002Fhome\u002Fuser\u002Fproject\u002F",". Саме тому ",[5511,7920,5615],{}," працює, якщо ",[5511,7923,5626],{}," лежить поруч з ",[5511,7926,5513],{},". При запуску через ",[5511,7929,7930],{},"-m"," або в інтерактивному режимі ",[5511,7933,7934],{},"sys.path[0]"," дорівнює ",[5511,7937,7938],{},"''"," (порожній рядок = поточна директорія shell).",[7906,7941,7944,7945,7948,7949,7951],{"name":7942,"type":7943},"PYTHONPATH — змінна середовища","list[str]","Якщо встановлена змінна середовища ",[5511,7946,7947],{},"PYTHONPATH=\u002Fmy\u002Flibs:\u002Fother\u002Flibs",", Python вставляє ці шляхи після ",[5511,7950,7934],{},". Це спосіб глобально зареєструвати власні бібліотеки без встановлення через pip. Рідко потрібен у сучасних проектах з venv.",[7906,7953,7955,7956,5737,7959,5737,7962,5737,7965,7968,7969,5572],{"name":7954,"type":7943},"Стандартна бібліотека","Шляхи до вбудованих модулів Python: ",[5511,7957,7958],{},"os",[5511,7960,7961],{},"sys",[5511,7963,7964],{},"json",[5511,7966,7967],{},"datetime"," тощо. Їхнє точне розташування залежить від ОС та версії Python, але вони завжди присутні у ",[5511,7970,5630],{},[7906,7972,7974,7975,7978,7979,7982,7983,7986,7987,5737,7990,5737,7993,5572],{"name":7973,"type":7943},"site-packages — pip-пакети","Директорія, куди ",[5511,7976,7977],{},"pip install"," встановлює сторонні пакети. Зазвичай знаходиться у ",[5511,7980,7981],{},"~\u002F.local\u002Flib\u002FpythonX.Y\u002Fsite-packages\u002F"," (глобально) або ",[5511,7984,7985],{},"venv\u002Flib\u002FpythonX.Y\u002Fsite-packages\u002F"," (у venv). Саме тут лежать ваші ",[5511,7988,7989],{},"requests",[5511,7991,7992],{},"Django",[5511,7994,7995],{},"numpy",[5581,7997,7999,8000,8002],{"id":7998},"маніпуляції-з-syspath-коли-і-як","Маніпуляції з ",[5511,8001,5630],{},": коли і як",[5507,8004,8005,8007],{},[5511,8006,5630],{}," — це звичайний Python-список, тому його можна змінювати в рантаймі. Це дає потужні (і небезпечні) можливості:",[5667,8009,8011],{"className":5669,"code":8010,"language":5671,"meta":5672,"style":5672},"import sys\n\n# Додати власний шлях перед усіма іншими (найвищий пріоритет)\nsys.path.insert(0, '\u002Fpath\u002Fto\u002Fmy\u002Fcustom\u002Flibs')\n\n# Або в кінець (найнижчий пріоритет)\nsys.path.append('\u002Fpath\u002Fto\u002Ffallback\u002Flibs')\n\n# Тепер Python шукатиме модулі і там\nimport my_custom_module  # знайде у \u002Fpath\u002Fto\u002Fmy\u002Fcustom\u002Flibs\n",[5511,8012,8013,8019,8023,8028,8043,8047,8052,8062,8066,8071],{"__ignoreMap":5672},[5676,8014,8015,8017],{"class":5678,"line":5679},[5676,8016,6018],{"class":5765},[5676,8018,6970],{"class":5696},[5676,8020,8021],{"class":5678,"line":5686},[5676,8022,5690],{"emptyLinePlaceholder":5689},[5676,8024,8025],{"class":5678,"line":5693},[5676,8026,8027],{"class":5682},"# Додати власний шлях перед усіма іншими (найвищий пріоритет)\n",[5676,8029,8030,8033,8036,8038,8041],{"class":5678,"line":5707},[5676,8031,8032],{"class":5696},"sys.path.insert(",[5676,8034,8035],{"class":5700},"0",[5676,8037,5737],{"class":5696},[5676,8039,8040],{"class":5758},"'\u002Fpath\u002Fto\u002Fmy\u002Fcustom\u002Flibs'",[5676,8042,6049],{"class":5696},[5676,8044,8045],{"class":5678,"line":5712},[5676,8046,5690],{"emptyLinePlaceholder":5689},[5676,8048,8049],{"class":5678,"line":5755},[5676,8050,8051],{"class":5682},"# Або в кінець (найнижчий пріоритет)\n",[5676,8053,8054,8057,8060],{"class":5678,"line":5762},[5676,8055,8056],{"class":5696},"sys.path.append(",[5676,8058,8059],{"class":5758},"'\u002Fpath\u002Fto\u002Ffallback\u002Flibs'",[5676,8061,6049],{"class":5696},[5676,8063,8064],{"class":5678,"line":5772},[5676,8065,5690],{"emptyLinePlaceholder":5689},[5676,8067,8068],{"class":5678,"line":5777},[5676,8069,8070],{"class":5682},"# Тепер Python шукатиме модулі і там\n",[5676,8072,8073,8075,8078],{"class":5678,"line":5807},[5676,8074,6018],{"class":5765},[5676,8076,8077],{"class":5696}," my_custom_module  ",[5676,8079,8080],{"class":5682},"# знайде у \u002Fpath\u002Fto\u002Fmy\u002Fcustom\u002Flibs\n",[8082,8083,8084,8089,8090,8092,8093,8096,8097,8100],"warning",{},[5519,8085,7999,8086,8088],{},[5511,8087,5630],{}," у production-коді — антипатерн."," Якщо ви додаєте шлях до ",[5511,8091,5630],{}," у своєму коді, це означає, що ваша структура проекту або система встановлення пакетів налаштована неправильно. Правильне рішення — використовувати ",[5511,8094,8095],{},"pip install -e ."," для локальної розробки або коректно структурований пакет. ",[5511,8098,8099],{},"sys.path.append(...)"," допустимий лише у тимчасових скриптах та скриптах налагодження.",[5507,8102,8103,8104,8107,8108,8111,8112,8114,8115,8117,8118,8120],{},"Альтернатива — файл ",[5511,8105,8106],{},".pth"," у директорії ",[5511,8109,8110],{},"site-packages",": Python автоматично читає всі ",[5511,8113,8106],{},"-файли при запуску та додає зазначені в них шляхи до ",[5511,8116,5630],{},". Команда ",[5511,8119,8095],{}," (editable install) використовує саме цей механізм.",[6400,8122,8124],{"id":8123},"як-влаштований-імпорт-під-капотом-finder-та-loader","Як влаштований імпорт під капотом: Finder та Loader",[5507,8126,8127,8128,8130,8131,6594,8134,8137],{},"Багато розробників думають, що ",[5511,8129,6018],{}," — це просто пошук файлу на диску. Насправді Python використовує складну, але дуже гнучку двохетапну систему імпорту, що базується на ",[5519,8132,8133],{},"пошуковцях (Finders)",[5519,8135,8136],{},"завантажувачах (Loaders)",". Ця система повністю документована у PEP 302.",[5507,8139,8140,8141,8143],{},"Коли ви викликаєте ",[5511,8142,7437],{},", виконуються такі кроки:",[5618,8145,8146,8188],{},[5621,8147,8148,8151,8152,8155,8156,8180,8183,8184,8187],{},[5519,8149,8150],{},"Пошук модуля (Find Phase)",":\nPython проходить по списку пошуковців, що зберігаються в ",[5511,8153,8154],{},"sys.meta_path",". Типово там містяться:",[7251,8157,8158,8166,8172],{},[5621,8159,8160,8163,8164,6467],{},[5511,8161,8162],{},"BuiltinImporter"," (для вбудованих модулів, наприклад, ",[5511,8165,7961],{},[5621,8167,8168,8171],{},[5511,8169,8170],{},"FrozenImporter"," (для \"заморожених\" модулів, написаних на C і скомпільованих у двійковий файл інтерпретатора).",[5621,8173,8174,8177,8178,6467],{},[5511,8175,8176],{},"PathFinder"," (шукає файли на диску за шляхами із ",[5511,8179,5630],{},[8181,8182],"br",{},"Кожен пошуковець намагається знайти модуль. Якщо знаходить, він повертає спеціальний об'єкт — специфікацію модуля (",[5511,8185,8186],{},"ModuleSpec","), яка містить метадані: ім'я модуля, посилання на завантажувач та шлях до файлу.",[5621,8189,8190,8193,8194,8196,8197,8200,8201],{},[5519,8191,8192],{},"Завантаження модуля (Load Phase)",":\nОтримавши ",[5511,8195,8186],{},", Python викликає відповідний завантажувач (",[5511,8198,8199],{},"Loader","). Завантажувач:",[7251,8202,8203,8206,8211],{},[5621,8204,8205],{},"Створює порожній об'єкт модуля.",[5621,8207,8208,8209,5572],{},"Записує його в ",[5511,8210,5609],{},[5621,8212,8213],{},"Виконує код файлу модуля в контексті цього об'єкта.",[5507,8215,8216],{},"Цей механізм дозволяє розробникам писати власні імпортери (import hooks). Наприклад, можна написати Finder\u002FLoader, який імпортує модулі безпосередньо з ZIP-архівів, бази даних або навіть завантажує їх через HTTP з віддаленого сервера!",[6400,8218,8220,8221,8223],{"id":8219},"що-таке-pth-файли","Що таке ",[5511,8222,8106],{},"-файли",[5507,8225,8226,8227,8229,8230,8232,8233,5572],{},"Файли з розширенням ",[5511,8228,8106],{}," (path configuration files) — це дуже простий і зручний спосіб додавання шляхів до ",[5511,8231,5630],{}," без ручного редагування коду або налаштування змінної ",[5511,8234,8235],{},"PYTHONPATH",[5507,8237,8238,8239,8242,8243,8245,8246,5572],{},"Якщо покласти файл ",[5511,8240,8241],{},"my_paths.pth"," у директорію ",[5511,8244,8110],{}," вашого віртуального середовища, Python під час ініціалізації прочитає його рядки і додасть усі вказані там шляхи до ",[5511,8247,5630],{},[5507,8249,8250,8251,8253,8254,8257],{},"Кожен рядок у ",[5511,8252,8106],{},"-файлі має містити один абсолютний або відносний шлях. Якщо рядок починається з ",[5511,8255,8256],{},"import ",", Python навіть виконає цей код (це використовується деякими складними бібліотеками для автоналаштування).",[5507,8259,8260,8261,8263,8264,5737,8266,8269,8270,8272],{},"Саме цей механізм використовується при встановленні локального пакета в \"режимі редагування\":\n",[5511,8262,8095],{},"\nЗамість того, щоб копіювати файли вашого проекту в ",[5511,8265,8110],{},[5511,8267,8268],{},"pip"," просто створює там ",[5511,8271,8106],{},"-файл, який містить шлях до вашої робочої директорії. Це дозволяє вам редагувати код, і зміни будуть миттєво видимі без повторного встановлення пакета.",[5574,8274],{},[5502,8276,8278,8279,8281],{"id":8277},"кешування-імпортів-sysmodules-та-singleton-поведінка","Кешування імпортів: ",[5511,8280,5609],{}," та Singleton-поведінка",[5581,8283,8285],{"id":8284},"чому-модуль-завантажується-лише-один-раз","Чому модуль завантажується лише один раз",[5507,8287,8288,8289,5737,8291,5737,8293,8295,8296,8299],{},"Python є мовою, де один і той самий модуль (",[5511,8290,7958],{},[5511,8292,7964],{},[5511,8294,7967],{},") може бути імпортований у десятках різних файлів одного проекту. Якби кожен ",[5511,8297,8298],{},"import os"," перечитував файл з диска та виконував байткод заново — продуктивність була б катастрофічною.",[5507,8301,8302,8303,8306,8307,8309],{},"Рішення — ",[5519,8304,8305],{},"кеш модулів",": словник ",[5511,8308,5609],{},", що зберігає всі вже завантажені модулі.",[5667,8311,8313],{"className":5669,"code":8312,"language":5671,"meta":5672,"style":5672},"# main.py — демонстрація кешування\nimport sys\n\nprint(\"=== Перший імпорт ===\")\nimport calculator  # \u003C— тут: файл читається, байткод виконується\n\nprint(\"\\n=== Другий імпорт ===\")\nimport calculator  # \u003C— тут: Python бачить 'calculator' у sys.modules → пропускає\n\nprint(\"\\n=== Третій імпорт ===\")\nimport calculator  # \u003C— те саме: кеш-хіт, нульова вартість\n\nprint(f\"\\n'calculator' у кеші? {'calculator' in sys.modules}\")\n\n# Отримати об'єкт модуля з кешу напряму\ncached = sys.modules['calculator']\nprint(f\"Той самий об'єкт? {calculator is cached}\")   # True\nprint(f\"Виклик через кеш: {cached.add(1, 2)}\")        # 3\n",[5511,8314,8315,8320,8326,8330,8341,8350,8354,8369,8378,8382,8397,8406,8410,8442,8446,8451,8461,8493],{"__ignoreMap":5672},[5676,8316,8317],{"class":5678,"line":5679},[5676,8318,8319],{"class":5682},"# main.py — демонстрація кешування\n",[5676,8321,8322,8324],{"class":5678,"line":5686},[5676,8323,6018],{"class":5765},[5676,8325,6970],{"class":5696},[5676,8327,8328],{"class":5678,"line":5693},[5676,8329,5690],{"emptyLinePlaceholder":5689},[5676,8331,8332,8334,8336,8339],{"class":5678,"line":5707},[5676,8333,6068],{"class":5719},[5676,8335,5723],{"class":5696},[5676,8337,8338],{"class":5758},"\"=== Перший імпорт ===\"",[5676,8340,6049],{"class":5696},[5676,8342,8343,8345,8347],{"class":5678,"line":5712},[5676,8344,6018],{"class":5765},[5676,8346,6021],{"class":5696},[5676,8348,8349],{"class":5682},"# \u003C— тут: файл читається, байткод виконується\n",[5676,8351,8352],{"class":5678,"line":5755},[5676,8353,5690],{"emptyLinePlaceholder":5689},[5676,8355,8356,8358,8360,8362,8364,8367],{"class":5678,"line":5762},[5676,8357,6068],{"class":5719},[5676,8359,5723],{"class":5696},[5676,8361,6088],{"class":5758},[5676,8363,6760],{"class":6759},[5676,8365,8366],{"class":5758},"=== Другий імпорт ===\"",[5676,8368,6049],{"class":5696},[5676,8370,8371,8373,8375],{"class":5678,"line":5772},[5676,8372,6018],{"class":5765},[5676,8374,6021],{"class":5696},[5676,8376,8377],{"class":5682},"# \u003C— тут: Python бачить 'calculator' у sys.modules → пропускає\n",[5676,8379,8380],{"class":5678,"line":5777},[5676,8381,5690],{"emptyLinePlaceholder":5689},[5676,8383,8384,8386,8388,8390,8392,8395],{"class":5678,"line":5807},[5676,8385,6068],{"class":5719},[5676,8387,5723],{"class":5696},[5676,8389,6088],{"class":5758},[5676,8391,6760],{"class":6759},[5676,8393,8394],{"class":5758},"=== Третій імпорт ===\"",[5676,8396,6049],{"class":5696},[5676,8398,8399,8401,8403],{"class":5678,"line":5813},[5676,8400,6018],{"class":5765},[5676,8402,6021],{"class":5696},[5676,8404,8405],{"class":5682},"# \u003C— те саме: кеш-хіт, нульова вартість\n",[5676,8407,8408],{"class":5678,"line":5821},[5676,8409,5690],{"emptyLinePlaceholder":5689},[5676,8411,8412,8414,8416,8418,8420,8422,8425,8427,8430,8433,8436,8438,8440],{"class":5678,"line":5826},[5676,8413,6068],{"class":5719},[5676,8415,5723],{"class":5696},[5676,8417,6073],{"class":5715},[5676,8419,6088],{"class":5758},[5676,8421,6760],{"class":6759},[5676,8423,8424],{"class":5758},"'calculator' у кеші? ",[5676,8426,6079],{"class":5715},[5676,8428,8429],{"class":5758},"'calculator'",[5676,8431,8432],{"class":5715}," in",[5676,8434,8435],{"class":5696}," sys.modules",[5676,8437,6085],{"class":5715},[5676,8439,6088],{"class":5758},[5676,8441,6049],{"class":5696},[5676,8443,8444],{"class":5678,"line":5856},[5676,8445,5690],{"emptyLinePlaceholder":5689},[5676,8447,8448],{"class":5678,"line":5862},[5676,8449,8450],{"class":5682},"# Отримати об'єкт модуля з кешу напряму\n",[5676,8452,8453,8456,8458],{"class":5678,"line":5870},[5676,8454,8455],{"class":5696},"cached = sys.modules[",[5676,8457,8429],{"class":5758},[5676,8459,8460],{"class":5696},"]\n",[5676,8462,8463,8465,8467,8469,8472,8474,8477,8480,8483,8485,8487,8490],{"class":5678,"line":5875},[5676,8464,6068],{"class":5719},[5676,8466,5723],{"class":5696},[5676,8468,6073],{"class":5715},[5676,8470,8471],{"class":5758},"\"Той самий об'єкт? ",[5676,8473,6079],{"class":5715},[5676,8475,8476],{"class":5696},"calculator ",[5676,8478,8479],{"class":5715},"is",[5676,8481,8482],{"class":5696}," cached",[5676,8484,6085],{"class":5715},[5676,8486,6088],{"class":5758},[5676,8488,8489],{"class":5696},")   ",[5676,8491,8492],{"class":5682},"# True\n",[5676,8494,8495,8497,8499,8501,8504,8506,8509,8511,8513,8515,8517,8519,8521,8524],{"class":5678,"line":5898},[5676,8496,6068],{"class":5719},[5676,8498,5723],{"class":5696},[5676,8500,6073],{"class":5715},[5676,8502,8503],{"class":5758},"\"Виклик через кеш: ",[5676,8505,6079],{"class":5715},[5676,8507,8508],{"class":5696},"cached.add(",[5676,8510,7174],{"class":5700},[5676,8512,5737],{"class":5696},[5676,8514,6322],{"class":5700},[5676,8516,5631],{"class":5696},[5676,8518,6085],{"class":5715},[5676,8520,6088],{"class":5758},[5676,8522,8523],{"class":5696},")        ",[5676,8525,8526],{"class":5682},"# 3\n",[6145,8528,8530,8538,8542,8553,8556,8560,8567,8570,8574,8580,8583,8590,8597],{"title":8529},"Кешування: модуль завантажується лише раз",[6149,8531,8533,6157,8536],{"className":8532},[5678],[5676,8534,6156],{"className":8535},[6155],[5519,8537,6147],{},[6149,8539,8541],{"className":8540},[5678],"=== Перший імпорт ===",[6149,8543,8545,7839,8549],{"className":8544},[5678],[5676,8546,8548],{"className":8547},[6184],"Модуль calculator завантажено!",[5676,8550,8552],{"className":8551},[7843],"# виводиться лише раз",[6149,8554],{"className":8555},[5678],[6149,8557,8559],{"className":8558},[5678],"=== Другий імпорт ===",[6149,8561,8563],{"className":8562},[5678],[5676,8564,8566],{"className":8565},[7843],"# нічого — кеш-хіт",[6149,8568],{"className":8569},[5678],[6149,8571,8573],{"className":8572},[5678],"=== Третій імпорт ===",[6149,8575,8577],{"className":8576},[5678],[5676,8578,8566],{"className":8579},[7843],[6149,8581],{"className":8582},[5678],[6149,8584,8424,8586],{"className":8585},[5678],[5676,8587,8589],{"className":8588},[6167],"True",[6149,8591,8593,8594],{"className":8592},[5678],"Той самий об'єкт? ",[5676,8595,8589],{"className":8596},[6167],[6149,8598,8600,8601],{"className":8599},[5678],"Виклик через кеш: ",[5676,8602,7164],{"className":8603},[7829],[6400,8605,8607,8608],{"id":8606},"експеримент-ручне-керування-кешем-у-sysmodules","Експеримент: ручне керування кешем у ",[5511,8609,5609],{},[5507,8611,8612,8613,8615,8616,8618],{},"Щоб краще зрозуміти роль ",[5511,8614,5609],{},", ми можемо втрутитися в його роботу безпосередньо. Якщо ми видалимо модуль із цього словника, Python \"забуде\", що він його колись імпортував, і при наступному ",[5511,8617,6018],{}," виконає код заново (так, ніби це перший імпорт).",[5667,8620,8622],{"className":5669,"code":8621,"language":5671,"meta":5672,"style":5672},"# sys_modules_experiment.py\nimport sys\n\nprint(\"--- Крок 1: Перший імпорт ---\")\nimport calculator  # Виведе повідомлення про завантаження\n\nprint(\"\\n--- Крок 2: Другий імпорт (кешований) ---\")\nimport calculator  # Нічого не виведе, оскільки calculator вже у sys.modules\n\n# Перевіряємо наявність у кеші\nprint(f\"\\ncalculator у sys.modules? {'calculator' in sys.modules}\")\n\nprint(\"\\n--- Крок 3: Видалення з sys.modules та повторний імпорт ---\")\n# Ручне видалення запису з кешу\ndel sys.modules['calculator']\n\nprint(f\"calculator у sys.modules після видалення? {'calculator' in sys.modules}\")\n\nimport calculator  # Python знову завантажує та виконує код модуля!\n",[5511,8623,8624,8629,8635,8639,8650,8659,8663,8678,8687,8691,8696,8725,8729,8744,8749,8761,8765,8790,8794],{"__ignoreMap":5672},[5676,8625,8626],{"class":5678,"line":5679},[5676,8627,8628],{"class":5682},"# sys_modules_experiment.py\n",[5676,8630,8631,8633],{"class":5678,"line":5686},[5676,8632,6018],{"class":5765},[5676,8634,6970],{"class":5696},[5676,8636,8637],{"class":5678,"line":5693},[5676,8638,5690],{"emptyLinePlaceholder":5689},[5676,8640,8641,8643,8645,8648],{"class":5678,"line":5707},[5676,8642,6068],{"class":5719},[5676,8644,5723],{"class":5696},[5676,8646,8647],{"class":5758},"\"--- Крок 1: Перший імпорт ---\"",[5676,8649,6049],{"class":5696},[5676,8651,8652,8654,8656],{"class":5678,"line":5712},[5676,8653,6018],{"class":5765},[5676,8655,6021],{"class":5696},[5676,8657,8658],{"class":5682},"# Виведе повідомлення про завантаження\n",[5676,8660,8661],{"class":5678,"line":5755},[5676,8662,5690],{"emptyLinePlaceholder":5689},[5676,8664,8665,8667,8669,8671,8673,8676],{"class":5678,"line":5762},[5676,8666,6068],{"class":5719},[5676,8668,5723],{"class":5696},[5676,8670,6088],{"class":5758},[5676,8672,6760],{"class":6759},[5676,8674,8675],{"class":5758},"--- Крок 2: Другий імпорт (кешований) ---\"",[5676,8677,6049],{"class":5696},[5676,8679,8680,8682,8684],{"class":5678,"line":5772},[5676,8681,6018],{"class":5765},[5676,8683,6021],{"class":5696},[5676,8685,8686],{"class":5682},"# Нічого не виведе, оскільки calculator вже у sys.modules\n",[5676,8688,8689],{"class":5678,"line":5777},[5676,8690,5690],{"emptyLinePlaceholder":5689},[5676,8692,8693],{"class":5678,"line":5807},[5676,8694,8695],{"class":5682},"# Перевіряємо наявність у кеші\n",[5676,8697,8698,8700,8702,8704,8706,8708,8711,8713,8715,8717,8719,8721,8723],{"class":5678,"line":5813},[5676,8699,6068],{"class":5719},[5676,8701,5723],{"class":5696},[5676,8703,6073],{"class":5715},[5676,8705,6088],{"class":5758},[5676,8707,6760],{"class":6759},[5676,8709,8710],{"class":5758},"calculator у sys.modules? ",[5676,8712,6079],{"class":5715},[5676,8714,8429],{"class":5758},[5676,8716,8432],{"class":5715},[5676,8718,8435],{"class":5696},[5676,8720,6085],{"class":5715},[5676,8722,6088],{"class":5758},[5676,8724,6049],{"class":5696},[5676,8726,8727],{"class":5678,"line":5821},[5676,8728,5690],{"emptyLinePlaceholder":5689},[5676,8730,8731,8733,8735,8737,8739,8742],{"class":5678,"line":5826},[5676,8732,6068],{"class":5719},[5676,8734,5723],{"class":5696},[5676,8736,6088],{"class":5758},[5676,8738,6760],{"class":6759},[5676,8740,8741],{"class":5758},"--- Крок 3: Видалення з sys.modules та повторний імпорт ---\"",[5676,8743,6049],{"class":5696},[5676,8745,8746],{"class":5678,"line":5856},[5676,8747,8748],{"class":5682},"# Ручне видалення запису з кешу\n",[5676,8750,8751,8754,8757,8759],{"class":5678,"line":5862},[5676,8752,8753],{"class":5765},"del",[5676,8755,8756],{"class":5696}," sys.modules[",[5676,8758,8429],{"class":5758},[5676,8760,8460],{"class":5696},[5676,8762,8763],{"class":5678,"line":5870},[5676,8764,5690],{"emptyLinePlaceholder":5689},[5676,8766,8767,8769,8771,8773,8776,8778,8780,8782,8784,8786,8788],{"class":5678,"line":5875},[5676,8768,6068],{"class":5719},[5676,8770,5723],{"class":5696},[5676,8772,6073],{"class":5715},[5676,8774,8775],{"class":5758},"\"calculator у sys.modules після видалення? ",[5676,8777,6079],{"class":5715},[5676,8779,8429],{"class":5758},[5676,8781,8432],{"class":5715},[5676,8783,8435],{"class":5696},[5676,8785,6085],{"class":5715},[5676,8787,6088],{"class":5758},[5676,8789,6049],{"class":5696},[5676,8791,8792],{"class":5678,"line":5898},[5676,8793,5690],{"emptyLinePlaceholder":5689},[5676,8795,8796,8798,8800],{"class":5678,"line":5904},[5676,8797,6018],{"class":5765},[5676,8799,6021],{"class":5696},[5676,8801,8802],{"class":5682},"# Python знову завантажує та виконує код модуля!\n",[6145,8804,8806,8814,8818,8824,8827,8831,8838,8841,8847,8850,8854,8863],{"title":8805},"python sys_modules_experiment.py",[6149,8807,8809,6157,8812],{"className":8808},[5678],[5676,8810,6156],{"className":8811},[6155],[5519,8813,8805],{},[6149,8815,8817],{"className":8816},[5678],"--- Крок 1: Перший імпорт ---",[6149,8819,8821],{"className":8820},[5678],[5676,8822,8548],{"className":8823},[6184],[6149,8825],{"className":8826},[5678],[6149,8828,8830],{"className":8829},[5678],"--- Крок 2: Другий імпорт (кешований) ---",[6149,8832,8834],{"className":8833},[5678],[5676,8835,8837],{"className":8836},[7843],"# Кеш-хіт: повторного виводу немає",[6149,8839],{"className":8840},[5678],[6149,8842,8710,8844],{"className":8843},[5678],[5676,8845,8589],{"className":8846},[6167],[6149,8848],{"className":8849},[5678],[6149,8851,8853],{"className":8852},[5678],"--- Крок 3: Видалення з sys.modules та повторний імпорт ---",[6149,8855,8857,8858],{"className":8856},[5678],"calculator у sys.modules після видалення? ",[5676,8859,8862],{"className":8860},[8861],"text-rose-400","False",[6149,8864,8866,7839,8869],{"className":8865},[5678],[5676,8867,8548],{"className":8868},[6184],[5676,8870,8872],{"className":8871},[7843],"# Код виконався знову!",[8082,8874,8875,8876,5737,8878,8884],{},"Хоча цей трюк демонструє роботу ",[5511,8877,5609],{},[5519,8879,8880,8881,8883],{},"ніколи не видаляйте модулі з ",[5511,8882,5609],{}," вручну в реальних проектах",". Це може зламати зв'язки між модулями та спричинити непередбачувані побічні ефекти (наприклад, якщо інші частини коду вже мають посилання на старий об'єкт модуля).",[5581,8886,8888,8890],{"id":8887},"sysmodules-як-singleton-реєстр-спільний-стан",[5511,8889,5609],{}," як Singleton-реєстр: спільний стан",[5507,8892,8893,8894,8897,8898,5572],{},"Той факт, що Python повертає ",[5519,8895,8896],{},"один і той самий об'єкт модуля"," всім імпортерам, породжує важливий архітектурний наслідок: ",[5519,8899,8900],{},"модуль з глобальними змінними веде себе як Singleton",[5667,8902,8904],{"className":5669,"code":8903,"language":5671,"meta":5672,"style":5672},"# state.py — модуль зі спільним станом\nprint(\"Ініціалізація state.py\")\nrequest_count = 0\nactive_connections = []\n\n# module_a.py — реєструє запити\nimport state\n\ndef handle_request(url: str) -> None:\n    state.request_count += 1\n    state.active_connections.append(url)\n    print(f\"[A] Запит #{state.request_count} до {url}\")\n\n# module_b.py — читає статистику\nimport state\n\ndef get_stats() -> dict:\n    return {\n        \"total\": state.request_count,\n        \"active\": len(state.active_connections)\n    }\n\n# main.py\nimport module_a\nimport module_b\n\nmodule_a.handle_request(\"\u002Fapi\u002Fusers\")\nmodule_a.handle_request(\"\u002Fapi\u002Fproducts\")\n\nstats = module_b.get_stats()\nprint(f\"Статистика: {stats}\")\n# {'total': 2, 'active': 2}\n# module_b бачить зміни, зроблені module_a!\n",[5511,8905,8906,8911,8922,8930,8935,8939,8944,8951,8955,8978,8986,8991,9022,9026,9031,9037,9041,9055,9062,9070,9082,9086,9090,9094,9101,9108,9112,9122,9131,9135,9140,9162,9167],{"__ignoreMap":5672},[5676,8907,8908],{"class":5678,"line":5679},[5676,8909,8910],{"class":5682},"# state.py — модуль зі спільним станом\n",[5676,8912,8913,8915,8917,8920],{"class":5678,"line":5686},[5676,8914,6068],{"class":5719},[5676,8916,5723],{"class":5696},[5676,8918,8919],{"class":5758},"\"Ініціалізація state.py\"",[5676,8921,6049],{"class":5696},[5676,8923,8924,8927],{"class":5678,"line":5693},[5676,8925,8926],{"class":5696},"request_count = ",[5676,8928,8929],{"class":5700},"0\n",[5676,8931,8932],{"class":5678,"line":5707},[5676,8933,8934],{"class":5696},"active_connections = []\n",[5676,8936,8937],{"class":5678,"line":5712},[5676,8938,5690],{"emptyLinePlaceholder":5689},[5676,8940,8941],{"class":5678,"line":5755},[5676,8942,8943],{"class":5682},"# module_a.py — реєструє запити\n",[5676,8945,8946,8948],{"class":5678,"line":5762},[5676,8947,6018],{"class":5765},[5676,8949,8950],{"class":5696}," state\n",[5676,8952,8953],{"class":5678,"line":5772},[5676,8954,5690],{"emptyLinePlaceholder":5689},[5676,8956,8957,8959,8962,8964,8967,8969,8971,8973,8976],{"class":5678,"line":5777},[5676,8958,5716],{"class":5715},[5676,8960,8961],{"class":5719}," handle_request",[5676,8963,5723],{"class":5696},[5676,8965,8966],{"class":5726},"url",[5676,8968,5730],{"class":5696},[5676,8970,6258],{"class":5733},[5676,8972,5747],{"class":5696},[5676,8974,8975],{"class":5715},"None",[5676,8977,5752],{"class":5696},[5676,8979,8980,8983],{"class":5678,"line":5807},[5676,8981,8982],{"class":5696},"    state.request_count += ",[5676,8984,8985],{"class":5700},"1\n",[5676,8987,8988],{"class":5678,"line":5813},[5676,8989,8990],{"class":5696},"    state.active_connections.append(url)\n",[5676,8992,8993,8995,8997,8999,9002,9004,9007,9009,9012,9014,9016,9018,9020],{"class":5678,"line":5821},[5676,8994,7774],{"class":5719},[5676,8996,5723],{"class":5696},[5676,8998,6073],{"class":5715},[5676,9000,9001],{"class":5758},"\"[A] Запит #",[5676,9003,6079],{"class":5715},[5676,9005,9006],{"class":5696},"state.request_count",[5676,9008,6085],{"class":5715},[5676,9010,9011],{"class":5758}," до ",[5676,9013,6079],{"class":5715},[5676,9015,8966],{"class":5696},[5676,9017,6085],{"class":5715},[5676,9019,6088],{"class":5758},[5676,9021,6049],{"class":5696},[5676,9023,9024],{"class":5678,"line":5826},[5676,9025,5690],{"emptyLinePlaceholder":5689},[5676,9027,9028],{"class":5678,"line":5856},[5676,9029,9030],{"class":5682},"# module_b.py — читає статистику\n",[5676,9032,9033,9035],{"class":5678,"line":5862},[5676,9034,6018],{"class":5765},[5676,9036,8950],{"class":5696},[5676,9038,9039],{"class":5678,"line":5870},[5676,9040,5690],{"emptyLinePlaceholder":5689},[5676,9042,9043,9045,9048,9051,9053],{"class":5678,"line":5875},[5676,9044,5716],{"class":5715},[5676,9046,9047],{"class":5719}," get_stats",[5676,9049,9050],{"class":5696},"() -> ",[5676,9052,6389],{"class":5733},[5676,9054,5752],{"class":5696},[5676,9056,9057,9059],{"class":5678,"line":5898},[5676,9058,5766],{"class":5765},[5676,9060,9061],{"class":5696}," {\n",[5676,9063,9064,9067],{"class":5678,"line":5904},[5676,9065,9066],{"class":5758},"        \"total\"",[5676,9068,9069],{"class":5696},": state.request_count,\n",[5676,9071,9072,9075,9077,9079],{"class":5678,"line":5915},[5676,9073,9074],{"class":5758},"        \"active\"",[5676,9076,5730],{"class":5696},[5676,9078,7742],{"class":5719},[5676,9080,9081],{"class":5696},"(state.active_connections)\n",[5676,9083,9084],{"class":5678,"line":5920},[5676,9085,6539],{"class":5696},[5676,9087,9088],{"class":5678,"line":5941},[5676,9089,5690],{"emptyLinePlaceholder":5689},[5676,9091,9092],{"class":5678,"line":5947},[5676,9093,6226],{"class":5682},[5676,9095,9096,9098],{"class":5678,"line":5953},[5676,9097,6018],{"class":5765},[5676,9099,9100],{"class":5696}," module_a\n",[5676,9102,9103,9105],{"class":5678,"line":5959},[5676,9104,6018],{"class":5765},[5676,9106,9107],{"class":5696}," module_b\n",[5676,9109,9110],{"class":5678,"line":5964},[5676,9111,5690],{"emptyLinePlaceholder":5689},[5676,9113,9114,9117,9120],{"class":5678,"line":7576},[5676,9115,9116],{"class":5696},"module_a.handle_request(",[5676,9118,9119],{"class":5758},"\"\u002Fapi\u002Fusers\"",[5676,9121,6049],{"class":5696},[5676,9123,9124,9126,9129],{"class":5678,"line":7581},[5676,9125,9116],{"class":5696},[5676,9127,9128],{"class":5758},"\"\u002Fapi\u002Fproducts\"",[5676,9130,6049],{"class":5696},[5676,9132,9133],{"class":5678,"line":7587},[5676,9134,5690],{"emptyLinePlaceholder":5689},[5676,9136,9137],{"class":5678,"line":7593},[5676,9138,9139],{"class":5696},"stats = module_b.get_stats()\n",[5676,9141,9142,9144,9146,9148,9151,9153,9156,9158,9160],{"class":5678,"line":7599},[5676,9143,6068],{"class":5719},[5676,9145,5723],{"class":5696},[5676,9147,6073],{"class":5715},[5676,9149,9150],{"class":5758},"\"Статистика: ",[5676,9152,6079],{"class":5715},[5676,9154,9155],{"class":5696},"stats",[5676,9157,6085],{"class":5715},[5676,9159,6088],{"class":5758},[5676,9161,6049],{"class":5696},[5676,9163,9164],{"class":5678,"line":7605},[5676,9165,9166],{"class":5682},"# {'total': 2, 'active': 2}\n",[5676,9168,9169],{"class":5678,"line":7611},[5676,9170,9171],{"class":5682},"# module_b бачить зміни, зроблені module_a!\n",[5507,9173,9174,9175,9178,9179,5553,9182,9184,9185,9188,9189,9192],{},"Обидва модулі отримали ",[5519,9176,9177],{},"одне й те саме посилання"," на об'єкт ",[5511,9180,9181],{},"state",[5511,9183,5609],{},". Зміни від ",[5511,9186,9187],{},"module_a"," одразу видимі у ",[5511,9190,9191],{},"module_b",". Це потужний механізм для глобальної конфігурації та стану, але він вимагає свідомого підходу — ненавмисні зміни глобальних змінних модуля є поширеним джерелом важко відтворюваних багів.",[5581,9194,9196,9197],{"id":9195},"перезавантаження-модуля-importlibreload","Перезавантаження модуля: ",[5511,9198,9199],{},"importlib.reload",[5507,9201,9202,9203,9205],{},"У нормальному виробничому коді кеш ",[5511,9204,5609],{}," є бажаною поведінкою. Але при інтерактивній розробці (Jupyter Notebook, REPL) виникає ситуація: ви змінили файл модуля, але Python все одно використовує стару закешовану версію.",[5667,9207,9209],{"className":5669,"code":9208,"language":5671,"meta":5672,"style":5672},"import importlib\nimport calculator\n\n# Поточна версія\nprint(calculator.add(1, 2))   # 3\n\n# ... ви зміни код calculator.py: add тепер повертає a + b + 100 ...\n\n# Звичайний import нічого не зробить:\nimport calculator\nprint(calculator.add(1, 2))   # все одно 3!\n\n# Примусово перезавантажити:\nimportlib.reload(calculator)\nprint(calculator.add(1, 2))   # тепер 103 ✅\n",[5511,9210,9211,9218,9224,9228,9233,9251,9255,9260,9264,9269,9275,9292,9296,9301,9306],{"__ignoreMap":5672},[5676,9212,9213,9215],{"class":5678,"line":5679},[5676,9214,6018],{"class":5765},[5676,9216,9217],{"class":5696}," importlib\n",[5676,9219,9220,9222],{"class":5678,"line":5686},[5676,9221,6018],{"class":5765},[5676,9223,6233],{"class":5696},[5676,9225,9226],{"class":5678,"line":5693},[5676,9227,5690],{"emptyLinePlaceholder":5689},[5676,9229,9230],{"class":5678,"line":5707},[5676,9231,9232],{"class":5682},"# Поточна версія\n",[5676,9234,9235,9237,9240,9242,9244,9246,9249],{"class":5678,"line":5712},[5676,9236,6068],{"class":5719},[5676,9238,9239],{"class":5696},"(calculator.add(",[5676,9241,7174],{"class":5700},[5676,9243,5737],{"class":5696},[5676,9245,6322],{"class":5700},[5676,9247,9248],{"class":5696},"))   ",[5676,9250,8526],{"class":5682},[5676,9252,9253],{"class":5678,"line":5755},[5676,9254,5690],{"emptyLinePlaceholder":5689},[5676,9256,9257],{"class":5678,"line":5762},[5676,9258,9259],{"class":5682},"# ... ви зміни код calculator.py: add тепер повертає a + b + 100 ...\n",[5676,9261,9262],{"class":5678,"line":5772},[5676,9263,5690],{"emptyLinePlaceholder":5689},[5676,9265,9266],{"class":5678,"line":5777},[5676,9267,9268],{"class":5682},"# Звичайний import нічого не зробить:\n",[5676,9270,9271,9273],{"class":5678,"line":5807},[5676,9272,6018],{"class":5765},[5676,9274,6233],{"class":5696},[5676,9276,9277,9279,9281,9283,9285,9287,9289],{"class":5678,"line":5813},[5676,9278,6068],{"class":5719},[5676,9280,9239],{"class":5696},[5676,9282,7174],{"class":5700},[5676,9284,5737],{"class":5696},[5676,9286,6322],{"class":5700},[5676,9288,9248],{"class":5696},[5676,9290,9291],{"class":5682},"# все одно 3!\n",[5676,9293,9294],{"class":5678,"line":5821},[5676,9295,5690],{"emptyLinePlaceholder":5689},[5676,9297,9298],{"class":5678,"line":5826},[5676,9299,9300],{"class":5682},"# Примусово перезавантажити:\n",[5676,9302,9303],{"class":5678,"line":5856},[5676,9304,9305],{"class":5696},"importlib.reload(calculator)\n",[5676,9307,9308,9310,9312,9314,9316,9318,9320],{"class":5678,"line":5862},[5676,9309,6068],{"class":5719},[5676,9311,9239],{"class":5696},[5676,9313,7174],{"class":5700},[5676,9315,5737],{"class":5696},[5676,9317,6322],{"class":5700},[5676,9319,9248],{"class":5696},[5676,9321,9322],{"class":5682},"# тепер 103 ✅\n",[5507,9324,9325,6157,9327,9330,9331,9333,9334,9337,9338,9341,9342,9345,9346,9348],{},[5511,9326,9199],{},[5519,9328,9329],{},"не видаляє"," об'єкт модуля з ",[5511,9332,5609],{}," — він повторно виконує код файлу в ",[5519,9335,9336],{},"тому ж самому"," об'єкті модуля, оновлюючи його атрибути. Це має важливе обмеження: якщо ви зробили ",[5511,9339,9340],{},"from calculator import add"," (імпорт із прив'язкою до локального імені), ",[5511,9343,9344],{},"reload(calculator)"," оновить модуль, але ваша локальна змінна ",[5511,9347,6197],{}," все одно вказуватиме на стару функцію.",[9350,9351,9352,9354,9355,9358],"caution",{},[5511,9353,9199],{}," — виключно ",[5519,9356,9357],{},"інструмент для розробки",". У production-коді перезавантаження модулів у рантаймі є джерелом важко передбачуваних помилок, пов'язаних із невідповідністю об'єктів, що були створені до і після reload. Не використовуйте його у фінальному коді.",[5574,9360],{},[5502,9362,9364,9365],{"id":9363},"подвійне-призначення-файлу-if-__name__-__main__","Подвійне призначення файлу: ",[5511,9366,9367],{},"if __name__ == \"__main__\"",[5581,9369,9371],{"id":9370},"як-python-визначає-хто-головний","Як Python визначає «хто головний»",[5507,9373,9374,9375,9378],{},"Кожен модуль Python несе атрибут ",[5511,9376,9377],{},"__name__",". Його значення залежить від того, в якому контексті виконується файл:",[7251,9380,9381,9395],{},[5621,9382,9383,9384,9387,9388,9391,9392],{},"Якщо файл ",[5519,9385,9386],{},"запускається напряму"," (",[5511,9389,9390],{},"python calculator.py","): ",[5511,9393,9394],{},"__name__ == \"__main__\"",[5621,9396,9383,9397,9400,9401,9404,9405,5631],{},[5519,9398,9399],{},"імпортується"," в інший модуль: ",[5511,9402,9403],{},"__name__ == \"calculator\""," (ім'я без ",[5511,9406,5594],{},[5507,9408,9409,9410,9413],{},"Це розмежування дозволяє одному файлу виконувати ",[5519,9411,9412],{},"дві різні ролі"," залежно від контексту: як самостійний скрипт із власною логікою запуску, і як бібліотека для інших модулів.",[5667,9415,9417],{"className":5669,"code":9416,"language":5671,"meta":5672,"style":5672},"# calculator.py\nPI = 3.14159\n\ndef add(a, b):\n    return a + b\n\ndef subtract(a, b):\n    return a - b\n\ndef _run_tests():\n    \"\"\"Вбудовані smoke-тести.\"\"\"\n    assert add(2, 3) == 5, \"add(2, 3) має дорівнювати 5\"\n    assert subtract(10, 3) == 7, \"subtract(10, 3) має дорівнювати 7\"\n    print(\"✅ Всі smoke-тести пройдено!\")\n\n# Цей блок виконується ЛИШЕ при запуску: python calculator.py\n# При import calculator — він повністю ігнорується\nif __name__ == \"__main__\":\n    print(f\"Запуск calculator.py як головного скрипта.\")\n    print(f\"Поточне __name__: {__name__}\")\n    _run_tests()\n",[5511,9418,9419,9423,9430,9434,9451,9457,9461,9477,9483,9487,9496,9501,9525,9548,9559,9563,9568,9573,9589,9602,9623],{"__ignoreMap":5672},[5676,9420,9421],{"class":5678,"line":5679},[5676,9422,7302],{"class":5682},[5676,9424,9425,9427],{"class":5678,"line":5686},[5676,9426,5697],{"class":5696},[5676,9428,9429],{"class":5700},"3.14159\n",[5676,9431,9432],{"class":5678,"line":5693},[5676,9433,5690],{"emptyLinePlaceholder":5689},[5676,9435,9436,9438,9440,9442,9444,9446,9448],{"class":5678,"line":5707},[5676,9437,5716],{"class":5715},[5676,9439,5720],{"class":5719},[5676,9441,5723],{"class":5696},[5676,9443,5727],{"class":5726},[5676,9445,5737],{"class":5696},[5676,9447,5740],{"class":5726},[5676,9449,9450],{"class":5696},"):\n",[5676,9452,9453,9455],{"class":5678,"line":5712},[5676,9454,5766],{"class":5765},[5676,9456,5769],{"class":5696},[5676,9458,9459],{"class":5678,"line":5755},[5676,9460,5690],{"emptyLinePlaceholder":5689},[5676,9462,9463,9465,9467,9469,9471,9473,9475],{"class":5678,"line":5762},[5676,9464,5716],{"class":5715},[5676,9466,5782],{"class":5719},[5676,9468,5723],{"class":5696},[5676,9470,5727],{"class":5726},[5676,9472,5737],{"class":5696},[5676,9474,5740],{"class":5726},[5676,9476,9450],{"class":5696},[5676,9478,9479,9481],{"class":5678,"line":5772},[5676,9480,5766],{"class":5765},[5676,9482,5818],{"class":5696},[5676,9484,9485],{"class":5678,"line":5777},[5676,9486,5690],{"emptyLinePlaceholder":5689},[5676,9488,9489,9491,9494],{"class":5678,"line":5807},[5676,9490,5716],{"class":5715},[5676,9492,9493],{"class":5719}," _run_tests",[5676,9495,6641],{"class":5696},[5676,9497,9498],{"class":5678,"line":5813},[5676,9499,9500],{"class":5758},"    \"\"\"Вбудовані smoke-тести.\"\"\"\n",[5676,9502,9503,9506,9509,9511,9513,9515,9518,9520,9522],{"class":5678,"line":5821},[5676,9504,9505],{"class":5765},"    assert",[5676,9507,9508],{"class":5696}," add(",[5676,9510,6322],{"class":5700},[5676,9512,5737],{"class":5696},[5676,9514,7164],{"class":5700},[5676,9516,9517],{"class":5696},") == ",[5676,9519,6046],{"class":5700},[5676,9521,5737],{"class":5696},[5676,9523,9524],{"class":5758},"\"add(2, 3) має дорівнювати 5\"\n",[5676,9526,9527,9529,9532,9534,9536,9538,9540,9543,9545],{"class":5678,"line":5826},[5676,9528,9505],{"class":5765},[5676,9530,9531],{"class":5696}," subtract(",[5676,9533,6041],{"class":5700},[5676,9535,5737],{"class":5696},[5676,9537,7164],{"class":5700},[5676,9539,9517],{"class":5696},[5676,9541,9542],{"class":5700},"7",[5676,9544,5737],{"class":5696},[5676,9546,9547],{"class":5758},"\"subtract(10, 3) має дорівнювати 7\"\n",[5676,9549,9550,9552,9554,9557],{"class":5678,"line":5856},[5676,9551,7774],{"class":5719},[5676,9553,5723],{"class":5696},[5676,9555,9556],{"class":5758},"\"✅ Всі smoke-тести пройдено!\"",[5676,9558,6049],{"class":5696},[5676,9560,9561],{"class":5678,"line":5862},[5676,9562,5690],{"emptyLinePlaceholder":5689},[5676,9564,9565],{"class":5678,"line":5870},[5676,9566,9567],{"class":5682},"# Цей блок виконується ЛИШЕ при запуску: python calculator.py\n",[5676,9569,9570],{"class":5678,"line":5875},[5676,9571,9572],{"class":5682},"# При import calculator — він повністю ігнорується\n",[5676,9574,9575,9578,9581,9584,9587],{"class":5678,"line":5898},[5676,9576,9577],{"class":5765},"if",[5676,9579,9580],{"class":5726}," __name__",[5676,9582,9583],{"class":5696}," == ",[5676,9585,9586],{"class":5758},"\"__main__\"",[5676,9588,5752],{"class":5696},[5676,9590,9591,9593,9595,9597,9600],{"class":5678,"line":5904},[5676,9592,7774],{"class":5719},[5676,9594,5723],{"class":5696},[5676,9596,6073],{"class":5715},[5676,9598,9599],{"class":5758},"\"Запуск calculator.py як головного скрипта.\"",[5676,9601,6049],{"class":5696},[5676,9603,9604,9606,9608,9610,9613,9615,9617,9619,9621],{"class":5678,"line":5915},[5676,9605,7774],{"class":5719},[5676,9607,5723],{"class":5696},[5676,9609,6073],{"class":5715},[5676,9611,9612],{"class":5758},"\"Поточне __name__: ",[5676,9614,6079],{"class":5715},[5676,9616,9377],{"class":5726},[5676,9618,6085],{"class":5715},[5676,9620,6088],{"class":5758},[5676,9622,6049],{"class":5696},[5676,9624,9625],{"class":5678,"line":5920},[5676,9626,9627],{"class":5696},"    _run_tests()\n",[6145,9629,9631,9643,9647,9655,9662,9665,9677,9684],{"title":9630},"Два контексти одного файлу",[6149,9632,9634,6157,9637,7839,9639],{"className":9633},[5678],[5676,9635,6156],{"className":9636},[6155],[5519,9638,9390],{},[5676,9640,9642],{"className":9641},[7843],"# запуск напряму",[6149,9644,9646],{"className":9645},[5678],"Запуск calculator.py як головного скрипта.",[6149,9648,9650,9651],{"className":9649},[5678],"Поточне __name__: ",[5676,9652,9654],{"className":9653},[6167],"__main__",[6149,9656,9658],{"className":9657},[5678],[5676,9659,9661],{"className":9660},[6167],"✅ Всі smoke-тести пройдено!",[6149,9663],{"className":9664},[5678],[6149,9666,9668,6157,9671,7839,9673],{"className":9667},[5678],[5676,9669,6156],{"className":9670},[6155],[5519,9672,6147],{},[5676,9674,9676],{"className":9675},[7843],"# main.py робить: import calculator",[6149,9678,9680],{"className":9679},[5678],[5676,9681,9683],{"className":9682},[7843],"# Нічого з if-блоку не виконується!",[6149,9685,9687,9688,7839,9691],{"className":9686},[5678],"calculator.__name__ == ",[5676,9689,8429],{"className":9690},[6184],[5676,9692,9694],{"className":9693},[7843],"# не __main__",[5581,9696,9698,9699,9702],{"id":9697},"патерн-main-структурований-точок-входу","Патерн ",[5511,9700,9701],{},"main()",": структурований точок входу",[5507,9704,9705,9706,9708,9709,9711],{},"Поєднання ",[5511,9707,9367],{}," зі спеціальною функцією ",[5511,9710,9701],{}," є галузевим стандартом для скриптів, що мають власну логіку виконання:",[5667,9713,9715],{"className":5669,"code":9714,"language":5671,"meta":5672,"style":5672},"# data_processor.py\nimport sys\nimport json\n\ndef load_data(filepath: str) -> dict:\n    \"\"\"Завантажує JSON з файлу.\"\"\"\n    with open(filepath) as f:\n        return json.load(f)\n\ndef process(data: dict) -> list:\n    \"\"\"Бізнес-логіка обробки даних.\"\"\"\n    return [item for item in data.get(\"items\", []) if item.get(\"active\")]\n\ndef save_results(results: list, output_path: str) -> None:\n    \"\"\"Зберігає результати.\"\"\"\n    with open(output_path, \"w\") as f:\n        json.dump(results, f, indent=2)\n\ndef main() -> int:\n    \"\"\"\n    Точка входу програми.\n    Повертає код завершення: 0 = успіх, 1 = помилка.\n    \"\"\"\n    if len(sys.argv) != 3:\n        print(f\"Використання: python {sys.argv[0]} \u003Cinput.json> \u003Coutput.json>\")\n        return 1\n\n    input_path = sys.argv[1]\n    output_path = sys.argv[2]\n\n    try:\n        data = load_data(input_path)\n        results = process(data)\n        save_results(results, output_path)\n        print(f\"✅ Оброблено {len(results)} записів → {output_path}\")\n        return 0\n    except FileNotFoundError as e:\n        print(f\"❌ Файл не знайдено: {e}\")\n        return 1\n    except json.JSONDecodeError as e:\n        print(f\"❌ Невалідний JSON: {e}\")\n        return 1\n\n\nif __name__ == \"__main__\":\n    sys.exit(main())  # sys.exit передає код завершення в оболонку\n",[5511,9716,9717,9722,9728,9735,9739,9761,9766,9782,9790,9794,9816,9821,9855,9859,9890,9895,9913,9928,9932,9945,9949,9954,9959,9963,9978,10005,10012,10016,10025,10034,10038,10045,10050,10055,10060,10093,10100,10114,10136,10142,10153,10174,10180,10184,10188,10201],{"__ignoreMap":5672},[5676,9718,9719],{"class":5678,"line":5679},[5676,9720,9721],{"class":5682},"# data_processor.py\n",[5676,9723,9724,9726],{"class":5678,"line":5686},[5676,9725,6018],{"class":5765},[5676,9727,6970],{"class":5696},[5676,9729,9730,9732],{"class":5678,"line":5693},[5676,9731,6018],{"class":5765},[5676,9733,9734],{"class":5696}," json\n",[5676,9736,9737],{"class":5678,"line":5707},[5676,9738,5690],{"emptyLinePlaceholder":5689},[5676,9740,9741,9743,9746,9748,9751,9753,9755,9757,9759],{"class":5678,"line":5712},[5676,9742,5716],{"class":5715},[5676,9744,9745],{"class":5719}," load_data",[5676,9747,5723],{"class":5696},[5676,9749,9750],{"class":5726},"filepath",[5676,9752,5730],{"class":5696},[5676,9754,6258],{"class":5733},[5676,9756,5747],{"class":5696},[5676,9758,6389],{"class":5733},[5676,9760,5752],{"class":5696},[5676,9762,9763],{"class":5678,"line":5755},[5676,9764,9765],{"class":5758},"    \"\"\"Завантажує JSON з файлу.\"\"\"\n",[5676,9767,9768,9771,9774,9777,9779],{"class":5678,"line":5762},[5676,9769,9770],{"class":5765},"    with",[5676,9772,9773],{"class":5719}," open",[5676,9775,9776],{"class":5696},"(filepath) ",[5676,9778,7104],{"class":5765},[5676,9780,9781],{"class":5696}," f:\n",[5676,9783,9784,9787],{"class":5678,"line":5772},[5676,9785,9786],{"class":5765},"        return",[5676,9788,9789],{"class":5696}," json.load(f)\n",[5676,9791,9792],{"class":5678,"line":5777},[5676,9793,5690],{"emptyLinePlaceholder":5689},[5676,9795,9796,9798,9801,9803,9806,9808,9810,9812,9814],{"class":5678,"line":5807},[5676,9797,5716],{"class":5715},[5676,9799,9800],{"class":5719}," process",[5676,9802,5723],{"class":5696},[5676,9804,9805],{"class":5726},"data",[5676,9807,5730],{"class":5696},[5676,9809,6389],{"class":5733},[5676,9811,5747],{"class":5696},[5676,9813,6779],{"class":5733},[5676,9815,5752],{"class":5696},[5676,9817,9818],{"class":5678,"line":5813},[5676,9819,9820],{"class":5758},"    \"\"\"Бізнес-логіка обробки даних.\"\"\"\n",[5676,9822,9823,9825,9828,9830,9833,9835,9838,9841,9844,9846,9849,9852],{"class":5678,"line":5821},[5676,9824,5766],{"class":5765},[5676,9826,9827],{"class":5696}," [item ",[5676,9829,5990],{"class":5765},[5676,9831,9832],{"class":5696}," item ",[5676,9834,5996],{"class":5765},[5676,9836,9837],{"class":5696}," data.get(",[5676,9839,9840],{"class":5758},"\"items\"",[5676,9842,9843],{"class":5696},", []) ",[5676,9845,9577],{"class":5765},[5676,9847,9848],{"class":5696}," item.get(",[5676,9850,9851],{"class":5758},"\"active\"",[5676,9853,9854],{"class":5696},")]\n",[5676,9856,9857],{"class":5678,"line":5826},[5676,9858,5690],{"emptyLinePlaceholder":5689},[5676,9860,9861,9863,9866,9868,9871,9873,9875,9877,9880,9882,9884,9886,9888],{"class":5678,"line":5856},[5676,9862,5716],{"class":5715},[5676,9864,9865],{"class":5719}," save_results",[5676,9867,5723],{"class":5696},[5676,9869,9870],{"class":5726},"results",[5676,9872,5730],{"class":5696},[5676,9874,6779],{"class":5733},[5676,9876,5737],{"class":5696},[5676,9878,9879],{"class":5726},"output_path",[5676,9881,5730],{"class":5696},[5676,9883,6258],{"class":5733},[5676,9885,5747],{"class":5696},[5676,9887,8975],{"class":5715},[5676,9889,5752],{"class":5696},[5676,9891,9892],{"class":5678,"line":5862},[5676,9893,9894],{"class":5758},"    \"\"\"Зберігає результати.\"\"\"\n",[5676,9896,9897,9899,9901,9904,9907,9909,9911],{"class":5678,"line":5870},[5676,9898,9770],{"class":5765},[5676,9900,9773],{"class":5719},[5676,9902,9903],{"class":5696},"(output_path, ",[5676,9905,9906],{"class":5758},"\"w\"",[5676,9908,6118],{"class":5696},[5676,9910,7104],{"class":5765},[5676,9912,9781],{"class":5696},[5676,9914,9915,9918,9921,9924,9926],{"class":5678,"line":5875},[5676,9916,9917],{"class":5696},"        json.dump(results, f, ",[5676,9919,9920],{"class":5726},"indent",[5676,9922,9923],{"class":5696},"=",[5676,9925,6322],{"class":5700},[5676,9927,6049],{"class":5696},[5676,9929,9930],{"class":5678,"line":5898},[5676,9931,5690],{"emptyLinePlaceholder":5689},[5676,9933,9934,9936,9939,9941,9943],{"class":5678,"line":5904},[5676,9935,5716],{"class":5715},[5676,9937,9938],{"class":5719}," main",[5676,9940,9050],{"class":5696},[5676,9942,5980],{"class":5733},[5676,9944,5752],{"class":5696},[5676,9946,9947],{"class":5678,"line":5915},[5676,9948,5944],{"class":5758},[5676,9950,9951],{"class":5678,"line":5920},[5676,9952,9953],{"class":5758},"    Точка входу програми.\n",[5676,9955,9956],{"class":5678,"line":5941},[5676,9957,9958],{"class":5758},"    Повертає код завершення: 0 = успіх, 1 = помилка.\n",[5676,9960,9961],{"class":5678,"line":5947},[5676,9962,5944],{"class":5758},[5676,9964,9965,9968,9971,9974,9976],{"class":5678,"line":5953},[5676,9966,9967],{"class":5765},"    if",[5676,9969,9970],{"class":5719}," len",[5676,9972,9973],{"class":5696},"(sys.argv) != ",[5676,9975,7164],{"class":5700},[5676,9977,5752],{"class":5696},[5676,9979,9980,9982,9984,9986,9989,9991,9994,9996,9998,10000,10003],{"class":5678,"line":5959},[5676,9981,6685],{"class":5719},[5676,9983,5723],{"class":5696},[5676,9985,6073],{"class":5715},[5676,9987,9988],{"class":5758},"\"Використання: python ",[5676,9990,6079],{"class":5715},[5676,9992,9993],{"class":5696},"sys.argv[",[5676,9995,8035],{"class":5700},[5676,9997,6854],{"class":5696},[5676,9999,6085],{"class":5715},[5676,10001,10002],{"class":5758}," \u003Cinput.json> \u003Coutput.json>\"",[5676,10004,6049],{"class":5696},[5676,10006,10007,10009],{"class":5678,"line":5964},[5676,10008,9786],{"class":5765},[5676,10010,10011],{"class":5700}," 1\n",[5676,10013,10014],{"class":5678,"line":7576},[5676,10015,5690],{"emptyLinePlaceholder":5689},[5676,10017,10018,10021,10023],{"class":5678,"line":7581},[5676,10019,10020],{"class":5696},"    input_path = sys.argv[",[5676,10022,7174],{"class":5700},[5676,10024,8460],{"class":5696},[5676,10026,10027,10030,10032],{"class":5678,"line":7587},[5676,10028,10029],{"class":5696},"    output_path = sys.argv[",[5676,10031,6322],{"class":5700},[5676,10033,8460],{"class":5696},[5676,10035,10036],{"class":5678,"line":7593},[5676,10037,5690],{"emptyLinePlaceholder":5689},[5676,10039,10040,10043],{"class":5678,"line":7599},[5676,10041,10042],{"class":5765},"    try",[5676,10044,5752],{"class":5696},[5676,10046,10047],{"class":5678,"line":7605},[5676,10048,10049],{"class":5696},"        data = load_data(input_path)\n",[5676,10051,10052],{"class":5678,"line":7611},[5676,10053,10054],{"class":5696},"        results = process(data)\n",[5676,10056,10057],{"class":5678,"line":7617},[5676,10058,10059],{"class":5696},"        save_results(results, output_path)\n",[5676,10061,10062,10064,10066,10068,10071,10073,10075,10078,10080,10083,10085,10087,10089,10091],{"class":5678,"line":7622},[5676,10063,6685],{"class":5719},[5676,10065,5723],{"class":5696},[5676,10067,6073],{"class":5715},[5676,10069,10070],{"class":5758},"\"✅ Оброблено ",[5676,10072,6079],{"class":5715},[5676,10074,7742],{"class":5719},[5676,10076,10077],{"class":5696},"(results)",[5676,10079,6085],{"class":5715},[5676,10081,10082],{"class":5758}," записів → ",[5676,10084,6079],{"class":5715},[5676,10086,9879],{"class":5696},[5676,10088,6085],{"class":5715},[5676,10090,6088],{"class":5758},[5676,10092,6049],{"class":5696},[5676,10094,10095,10097],{"class":5678,"line":7627},[5676,10096,9786],{"class":5765},[5676,10098,10099],{"class":5700}," 0\n",[5676,10101,10102,10105,10108,10111],{"class":5678,"line":7633},[5676,10103,10104],{"class":5765},"    except",[5676,10106,10107],{"class":5733}," FileNotFoundError",[5676,10109,10110],{"class":5765}," as",[5676,10112,10113],{"class":5696}," e:\n",[5676,10115,10116,10118,10120,10122,10125,10127,10130,10132,10134],{"class":5678,"line":7639},[5676,10117,6685],{"class":5719},[5676,10119,5723],{"class":5696},[5676,10121,6073],{"class":5715},[5676,10123,10124],{"class":5758},"\"❌ Файл не знайдено: ",[5676,10126,6079],{"class":5715},[5676,10128,10129],{"class":5696},"e",[5676,10131,6085],{"class":5715},[5676,10133,6088],{"class":5758},[5676,10135,6049],{"class":5696},[5676,10137,10138,10140],{"class":5678,"line":7645},[5676,10139,9786],{"class":5765},[5676,10141,10011],{"class":5700},[5676,10143,10144,10146,10149,10151],{"class":5678,"line":7651},[5676,10145,10104],{"class":5765},[5676,10147,10148],{"class":5696}," json.JSONDecodeError ",[5676,10150,7104],{"class":5765},[5676,10152,10113],{"class":5696},[5676,10154,10155,10157,10159,10161,10164,10166,10168,10170,10172],{"class":5678,"line":7657},[5676,10156,6685],{"class":5719},[5676,10158,5723],{"class":5696},[5676,10160,6073],{"class":5715},[5676,10162,10163],{"class":5758},"\"❌ Невалідний JSON: ",[5676,10165,6079],{"class":5715},[5676,10167,10129],{"class":5696},[5676,10169,6085],{"class":5715},[5676,10171,6088],{"class":5758},[5676,10173,6049],{"class":5696},[5676,10175,10176,10178],{"class":5678,"line":7663},[5676,10177,9786],{"class":5765},[5676,10179,10011],{"class":5700},[5676,10181,10182],{"class":5678,"line":7669},[5676,10183,5690],{"emptyLinePlaceholder":5689},[5676,10185,10186],{"class":5678,"line":7674},[5676,10187,5690],{"emptyLinePlaceholder":5689},[5676,10189,10191,10193,10195,10197,10199],{"class":5678,"line":10190},45,[5676,10192,9577],{"class":5765},[5676,10194,9580],{"class":5726},[5676,10196,9583],{"class":5696},[5676,10198,9586],{"class":5758},[5676,10200,5752],{"class":5696},[5676,10202,10204,10207],{"class":5678,"line":10203},46,[5676,10205,10206],{"class":5696},"    sys.exit(main())  ",[5676,10208,10209],{"class":5682},"# sys.exit передає код завершення в оболонку\n",[5507,10211,10212,10213,10215,10216,10219,10220,10223,10224,5572],{},"Цей підхід дає три переваги: ",[5511,10214,9701],{}," є звичайною функцією, яку можна легко тестувати; ",[5511,10217,10218],{},"return 1"," \u002F ",[5511,10221,10222],{},"return 0"," дозволяє коректно сигналізувати про помилки в bash-скриптах; модуль залишається повністю придатним для ",[5511,10225,6018],{},[5581,10227,10229,10232],{"id":10228},"python-m-запуск-модуля-як-скрипта",[5511,10230,10231],{},"python -m",": запуск модуля як скрипта",[5507,10234,10235,10236,10239,10240,10243],{},"Окрім ",[5511,10237,10238],{},"python script.py",", Python підтримує синтаксис ",[5511,10241,10242],{},"python -m module_name",". Різниця тонка, але важлива:",[10245,10246,10247,10264],"table",{},[10248,10249,10250],"thead",{},[10251,10252,10253,10257,10261],"tr",{},[10254,10255,10256],"th",{},"Команда",[10254,10258,10259],{},[5511,10260,7934],{},[10254,10262,10263],{},"Для чого",[10265,10266,10267,10281,10297],"tbody",{},[10251,10268,10269,10275,10278],{},[10270,10271,10272],"td",{},[5511,10273,10274],{},"python path\u002Fto\u002Fscript.py",[10270,10276,10277],{},"директорія скрипта",[10270,10279,10280],{},"прості скрипти",[10251,10282,10283,10288,10294],{},[10270,10284,10285],{},[5511,10286,10287],{},"python -m package.module",[10270,10289,10290,10293],{},[5519,10291,10292],{},"коренева"," директорія проекту",[10270,10295,10296],{},"модулі всередині пакетів",[10251,10298,10299,10304,10307],{},[10270,10300,10301],{},[5511,10302,10303],{},"python -m venv .venv",[10270,10305,10306],{},"—",[10270,10308,10309],{},"вбудовані інструменти",[5507,10311,10312,10313,10315,10316,10318,10319,10322,10323,10326,10327,10330,10331,5572],{},"Прапорець ",[5511,10314,7930],{}," каже Python знайти модуль за ",[5511,10317,5630],{}," і запустити його з ",[5511,10320,10321],{},"__name__ = \"__main__\"",". Це критично для пакетів, де відносні імпорти (",[5511,10324,10325],{},"from .utils import helper",") не працюють при прямому ",[5511,10328,10329],{},"python package\u002Fmodule.py",", але коректно розв'язуються при ",[5511,10332,10287],{},[5574,10334],{},[5502,10336,10338],{"id":10337},"циклічні-імпорти-архітектурний-антипатерн","Циклічні імпорти: архітектурний антипатерн",[5581,10340,10342],{"id":10341},"як-виникає-циклічний-імпорт","Як виникає циклічний імпорт",[5507,10344,10345],{},"Циклічний імпорт виникає, коли модуль A імпортує модуль B, а модуль B імпортує модуль A (прямо чи через ланцюг інших модулів). Python обробляє цей сценарій, але результат часто несподіваний.",[5667,10347,10349],{"className":5669,"code":10348,"language":5671,"meta":5672,"style":5672},"# a.py\nprint(\"Завантаження a.py...\")\nimport b  # Python призупиняє a.py і завантажує b.py\n\ndef func_a():\n    b.func_b()\n    print(\"func_a виконана\")\n\nprint(\"a.py завантажено.\")\n\n# b.py\nprint(\"Завантаження b.py...\")\nimport a  # Python бачить: a вже є у sys.modules (частково!)\n\ndef func_b():\n    print(\"func_b виконана\")\n\nprint(\"b.py завантажено.\")\n\n# main.py\nimport a\na.func_a()  # AttributeError: partially initialized module 'b'...\n",[5511,10350,10351,10356,10367,10377,10381,10390,10395,10406,10410,10421,10425,10430,10441,10451,10455,10464,10475,10479,10490,10494,10498,10505],{"__ignoreMap":5672},[5676,10352,10353],{"class":5678,"line":5679},[5676,10354,10355],{"class":5682},"# a.py\n",[5676,10357,10358,10360,10362,10365],{"class":5678,"line":5686},[5676,10359,6068],{"class":5719},[5676,10361,5723],{"class":5696},[5676,10363,10364],{"class":5758},"\"Завантаження a.py...\"",[5676,10366,6049],{"class":5696},[5676,10368,10369,10371,10374],{"class":5678,"line":5693},[5676,10370,6018],{"class":5765},[5676,10372,10373],{"class":5696}," b  ",[5676,10375,10376],{"class":5682},"# Python призупиняє a.py і завантажує b.py\n",[5676,10378,10379],{"class":5678,"line":5707},[5676,10380,5690],{"emptyLinePlaceholder":5689},[5676,10382,10383,10385,10388],{"class":5678,"line":5712},[5676,10384,5716],{"class":5715},[5676,10386,10387],{"class":5719}," func_a",[5676,10389,6641],{"class":5696},[5676,10391,10392],{"class":5678,"line":5755},[5676,10393,10394],{"class":5696},"    b.func_b()\n",[5676,10396,10397,10399,10401,10404],{"class":5678,"line":5762},[5676,10398,7774],{"class":5719},[5676,10400,5723],{"class":5696},[5676,10402,10403],{"class":5758},"\"func_a виконана\"",[5676,10405,6049],{"class":5696},[5676,10407,10408],{"class":5678,"line":5772},[5676,10409,5690],{"emptyLinePlaceholder":5689},[5676,10411,10412,10414,10416,10419],{"class":5678,"line":5777},[5676,10413,6068],{"class":5719},[5676,10415,5723],{"class":5696},[5676,10417,10418],{"class":5758},"\"a.py завантажено.\"",[5676,10420,6049],{"class":5696},[5676,10422,10423],{"class":5678,"line":5807},[5676,10424,5690],{"emptyLinePlaceholder":5689},[5676,10426,10427],{"class":5678,"line":5813},[5676,10428,10429],{"class":5682},"# b.py\n",[5676,10431,10432,10434,10436,10439],{"class":5678,"line":5821},[5676,10433,6068],{"class":5719},[5676,10435,5723],{"class":5696},[5676,10437,10438],{"class":5758},"\"Завантаження b.py...\"",[5676,10440,6049],{"class":5696},[5676,10442,10443,10445,10448],{"class":5678,"line":5826},[5676,10444,6018],{"class":5765},[5676,10446,10447],{"class":5696}," a  ",[5676,10449,10450],{"class":5682},"# Python бачить: a вже є у sys.modules (частково!)\n",[5676,10452,10453],{"class":5678,"line":5856},[5676,10454,5690],{"emptyLinePlaceholder":5689},[5676,10456,10457,10459,10462],{"class":5678,"line":5862},[5676,10458,5716],{"class":5715},[5676,10460,10461],{"class":5719}," func_b",[5676,10463,6641],{"class":5696},[5676,10465,10466,10468,10470,10473],{"class":5678,"line":5870},[5676,10467,7774],{"class":5719},[5676,10469,5723],{"class":5696},[5676,10471,10472],{"class":5758},"\"func_b виконана\"",[5676,10474,6049],{"class":5696},[5676,10476,10477],{"class":5678,"line":5875},[5676,10478,5690],{"emptyLinePlaceholder":5689},[5676,10480,10481,10483,10485,10488],{"class":5678,"line":5898},[5676,10482,6068],{"class":5719},[5676,10484,5723],{"class":5696},[5676,10486,10487],{"class":5758},"\"b.py завантажено.\"",[5676,10489,6049],{"class":5696},[5676,10491,10492],{"class":5678,"line":5904},[5676,10493,5690],{"emptyLinePlaceholder":5689},[5676,10495,10496],{"class":5678,"line":5915},[5676,10497,6226],{"class":5682},[5676,10499,10500,10502],{"class":5678,"line":5920},[5676,10501,6018],{"class":5765},[5676,10503,10504],{"class":5696}," a\n",[5676,10506,10507,10510],{"class":5678,"line":5941},[5676,10508,10509],{"class":5696},"a.func_a()  ",[5676,10511,10512],{"class":5682},"# AttributeError: partially initialized module 'b'...\n",[5507,10514,10515],{},[5519,10516,10517],{},"Що відбувається покроково:",[6412,10519,10520,10527,10538,10544,10552,10561,10593,10599,10609,10615,10625,10636],{},[5581,10521,10523,10524],{"id":10522},"python-починає-виконувати-apy","Python починає виконувати ",[5511,10525,10526],{},"a.py",[5507,10528,10529,10530,10533,10534,10537],{},"Виводить ",[5511,10531,10532],{},"Завантаження a.py...",". Бачить ",[5511,10535,10536],{},"import b"," — призупиняється.",[5581,10539,10523,10541],{"id":10540},"python-починає-виконувати-bpy",[5511,10542,10543],{},"b.py",[5507,10545,10529,10546,10533,10549,5572],{},[5511,10547,10548],{},"Завантаження b.py...",[5511,10550,10551],{},"import a",[5581,10553,10555,10556,10558,10559],{"id":10554},"python-виявляє-a-у-sysmodules","Python виявляє ",[5511,10557,5727],{}," у ",[5511,10560,5609],{},[5507,10562,10563,10564,10566,10567,10570,10571,10573,10574,10577,10578,10580,10581,10584,10585,10588,10589,10592],{},"Але ",[5511,10565,5727],{}," ще ",[5519,10568,10569],{},"не повністю завантажений"," — він призупинений на рядку ",[5511,10572,10536],{},". Python не падає в рекурсію, а повертає ",[5519,10575,10576],{},"частковий"," об'єкт ",[5511,10579,5727],{},". На момент повернення у ",[5511,10582,10583],{},"a.__dict__"," ще немає ",[5511,10586,10587],{},"func_a"," (оголошення ",[5511,10590,10591],{},"def func_a()"," ще не виконане!).",[5581,10594,10596,10598],{"id":10595},"bpy-успішно-завантажується",[5511,10597,10543],{}," успішно завантажується",[5507,10600,10601,10602,10605,10606],{},"Визначає ",[5511,10603,10604],{},"func_b",", виводить ",[5511,10607,10608],{},"b.py завантажено.",[5581,10610,10612,10613],{"id":10611},"виконання-повертається-до-apy","Виконання повертається до ",[5511,10614,10526],{},[5507,10616,10617,10619,10620,10605,10622],{},[5511,10618,10526],{}," продовжує: визначає ",[5511,10621,10587],{},[5511,10623,10624],{},"a.py завантажено.",[5581,10626,10628,10629,10632,10633],{"id":10627},"виклик-afunc_a-bfunc_b","Виклик ",[5511,10630,10631],{},"a.func_a()"," → ",[5511,10634,10635],{},"b.func_b()",[5507,10637,10638,10639,10641,10642,10644],{},"Якщо ",[5511,10640,10543],{}," намагається використати щось з ",[5511,10643,5727],{}," на рівні модуля (не всередині функції), воно буде недоступне.",[6472,10646,10647],{},[5667,10648,10650],{"className":6476,"code":10649,"language":6478,"meta":5672,"style":5672},"@startuml\nskinparam style plain\nskinparam backgroundColor #ffffff\nskinparam ArrowColor #6366f1\n\nparticipant \"Python\" as PY #f3f4f6\nparticipant \"a.py\\n(частково завантажений)\" as A #fef3c7\nparticipant \"b.py\" as B #d1fae5\nparticipant \"sys.modules\" as SM #e0e7ff\n\nPY -> A : Виконати a.py\nA -> SM : Зареєструвати a (частково)\nnote right of SM\n  sys.modules['a'] = \u003Cmodule a>\n  (але func_a ще не визначена!)\nend note\n\nA -> B : import b → виконати b.py\nB -> SM : Перевірити: 'a' у sys.modules?\nSM --> B : Так! Повернути частковий об'єкт a\nnote right of B\n  b.py отримує модуль a,\n  але у ньому немає func_a!\nend note\n\nB -> SM : Зареєструвати b (повністю)\nB --> A : import b завершено\nA -> SM : Оновити a (додати func_a)\n\nnote bottom of SM\n  Тепер a повний.\n  Але якщо b.py використовував a.func_a\n  на рівні модуля — вже пізно!\nend note\n@enduml\n",[5511,10651,10652,10656,10660,10664,10668,10672,10677,10682,10687,10692,10696,10701,10706,10711,10716,10721,10725,10729,10734,10739,10744,10749,10754,10759,10763,10767,10772,10777,10782,10786,10791,10796,10801,10806,10810],{"__ignoreMap":5672},[5676,10653,10654],{"class":5678,"line":5679},[5676,10655,6485],{},[5676,10657,10658],{"class":5678,"line":5686},[5676,10659,6490],{},[5676,10661,10662],{"class":5678,"line":5693},[5676,10663,6495],{},[5676,10665,10666],{"class":5678,"line":5707},[5676,10667,6500],{},[5676,10669,10670],{"class":5678,"line":5712},[5676,10671,5690],{"emptyLinePlaceholder":5689},[5676,10673,10674],{"class":5678,"line":5755},[5676,10675,10676],{},"participant \"Python\" as PY #f3f4f6\n",[5676,10678,10679],{"class":5678,"line":5762},[5676,10680,10681],{},"participant \"a.py\\n(частково завантажений)\" as A #fef3c7\n",[5676,10683,10684],{"class":5678,"line":5772},[5676,10685,10686],{},"participant \"b.py\" as B #d1fae5\n",[5676,10688,10689],{"class":5678,"line":5777},[5676,10690,10691],{},"participant \"sys.modules\" as SM #e0e7ff\n",[5676,10693,10694],{"class":5678,"line":5807},[5676,10695,5690],{"emptyLinePlaceholder":5689},[5676,10697,10698],{"class":5678,"line":5813},[5676,10699,10700],{},"PY -> A : Виконати a.py\n",[5676,10702,10703],{"class":5678,"line":5821},[5676,10704,10705],{},"A -> SM : Зареєструвати a (частково)\n",[5676,10707,10708],{"class":5678,"line":5826},[5676,10709,10710],{},"note right of SM\n",[5676,10712,10713],{"class":5678,"line":5856},[5676,10714,10715],{},"  sys.modules['a'] = \u003Cmodule a>\n",[5676,10717,10718],{"class":5678,"line":5862},[5676,10719,10720],{},"  (але func_a ще не визначена!)\n",[5676,10722,10723],{"class":5678,"line":5870},[5676,10724,6578],{},[5676,10726,10727],{"class":5678,"line":5875},[5676,10728,5690],{"emptyLinePlaceholder":5689},[5676,10730,10731],{"class":5678,"line":5898},[5676,10732,10733],{},"A -> B : import b → виконати b.py\n",[5676,10735,10736],{"class":5678,"line":5904},[5676,10737,10738],{},"B -> SM : Перевірити: 'a' у sys.modules?\n",[5676,10740,10741],{"class":5678,"line":5915},[5676,10742,10743],{},"SM --> B : Так! Повернути частковий об'єкт a\n",[5676,10745,10746],{"class":5678,"line":5920},[5676,10747,10748],{},"note right of B\n",[5676,10750,10751],{"class":5678,"line":5941},[5676,10752,10753],{},"  b.py отримує модуль a,\n",[5676,10755,10756],{"class":5678,"line":5947},[5676,10757,10758],{},"  але у ньому немає func_a!\n",[5676,10760,10761],{"class":5678,"line":5953},[5676,10762,6578],{},[5676,10764,10765],{"class":5678,"line":5959},[5676,10766,5690],{"emptyLinePlaceholder":5689},[5676,10768,10769],{"class":5678,"line":5964},[5676,10770,10771],{},"B -> SM : Зареєструвати b (повністю)\n",[5676,10773,10774],{"class":5678,"line":7576},[5676,10775,10776],{},"B --> A : import b завершено\n",[5676,10778,10779],{"class":5678,"line":7581},[5676,10780,10781],{},"A -> SM : Оновити a (додати func_a)\n",[5676,10783,10784],{"class":5678,"line":7587},[5676,10785,5690],{"emptyLinePlaceholder":5689},[5676,10787,10788],{"class":5678,"line":7593},[5676,10789,10790],{},"note bottom of SM\n",[5676,10792,10793],{"class":5678,"line":7599},[5676,10794,10795],{},"  Тепер a повний.\n",[5676,10797,10798],{"class":5678,"line":7605},[5676,10799,10800],{},"  Але якщо b.py використовував a.func_a\n",[5676,10802,10803],{"class":5678,"line":7611},[5676,10804,10805],{},"  на рівні модуля — вже пізно!\n",[5676,10807,10808],{"class":5678,"line":7617},[5676,10809,6578],{},[5676,10811,10812],{"class":5678,"line":7622},[5676,10813,6583],{},[5581,10815,10817],{"id":10816},"правильні-рішення","Правильні рішення",[5507,10819,10820],{},[5519,10821,10822],{},"Рішення 1 (найкраще): Рефакторинг — виділення спільного коду у третій модуль.",[5507,10824,10825],{},"Циклічний імпорт майже завжди є симптомом поганої архітектури: два модулі мають взаємні залежності, що означає, що вони не є незалежними одиницями. Правильне рішення — знайти спільний код і винести його у незалежний модуль.",[5667,10827,10832],{"className":10828,"code":10830,"language":10831},[10829],"language-text","❌ Погана архітектура:          ✅ Правильна архітектура:\n  a.py ←→ b.py                   shared.py (незалежний)\n                                  a.py → shared.py\n                                  b.py → shared.py, a.py\n","text",[5511,10833,10830],{"__ignoreMap":5672},[5507,10835,10836],{},[5519,10837,10838],{},"Рішення 2 (тимчасове): Локальний імпорт всередині функції.",[5667,10840,10842],{"className":5669,"code":10841,"language":5671,"meta":5672,"style":5672},"# a.py\ndef func_a():\n    import b  # ← імпорт всередині функції, відкладений до виклику\n    b.func_b()\n    print(\"func_a виконана\")\n",[5511,10843,10844,10848,10856,10866,10870],{"__ignoreMap":5672},[5676,10845,10846],{"class":5678,"line":5679},[5676,10847,10355],{"class":5682},[5676,10849,10850,10852,10854],{"class":5678,"line":5686},[5676,10851,5716],{"class":5715},[5676,10853,10387],{"class":5719},[5676,10855,6641],{"class":5696},[5676,10857,10858,10861,10863],{"class":5678,"line":5693},[5676,10859,10860],{"class":5765},"    import",[5676,10862,10373],{"class":5696},[5676,10864,10865],{"class":5682},"# ← імпорт всередині функції, відкладений до виклику\n",[5676,10867,10868],{"class":5678,"line":5707},[5676,10869,10394],{"class":5696},[5676,10871,10872,10874,10876,10878],{"class":5678,"line":5712},[5676,10873,7774],{"class":5719},[5676,10875,5723],{"class":5696},[5676,10877,10403],{"class":5758},[5676,10879,6049],{"class":5696},[5507,10881,10882,10883,10886,10887,10890,10891,10893],{},"Коли ",[5511,10884,10885],{},"func_a()"," буде викликана, обидва модулі вже будуть повністю завантажені, тому ",[5511,10888,10889],{},"b.func_b"," буде доступна. Але це «милиця» — вона ховає архітектурну проблему і уповільнює виклик функції (перевірка ",[5511,10892,5609],{}," при кожному виклику).",[5574,10895],{},[5502,10897,10899],{"id":10898},"частина-ii-пакети","Частина II: Пакети",[5581,10901,10903],{"id":10902},"від-модулів-до-ієрархії-навіщо-потрібні-пакети","Від модулів до ієрархії: навіщо потрібні пакети",[5507,10905,10906],{},"Коли проект виростає за межі кількох модулів, виникає нова проблема організації: навіть правильно розділений на модулі код перетворюється на хаотичний набір файлів, якщо всі вони лежать в одній директорії.",[5667,10908,10911],{"className":10909,"code":10910,"language":10831},[10829],"❌ Хаос без пакетів:          ✅ Структура з пакетами:\nmyproject\u002F                    myproject\u002F\n  main.py                       main.py\n  users.py                      users\u002F\n  user_auth.py                    __init__.py\n  user_profile.py                 auth.py\n  products.py                     profile.py\n  product_catalog.py            products\u002F\n  product_pricing.py              __init__.py\n  orders.py                       catalog.py\n  order_processing.py             pricing.py\n  order_notifications.py        orders\u002F\n  database.py                     __init__.py\n  api_client.py                   processing.py\n  utils.py                        notifications.py\n                                database.py\n                                utils.py\n",[5511,10912,10910],{"__ignoreMap":5672},[5507,10914,10915,10918,10919,10922],{},[5519,10916,10917],{},"Пакет"," — це директорія, що містить спеціальний файл ",[5511,10920,10921],{},"__init__.py",". Наявність цього файлу є сигналом для Python: «ця директорія — не просто папка, це модульна одиниця».",[5581,10924,10926],{"id":10925},"анатомія-пакета-реальний-проект-e-shop","Анатомія пакета: реальний проект e-shop",[5507,10928,10929],{},"Побудуємо повноцінний пакет для інтернет-магазину та дослідимо кожен його елемент:",[5664,10931,10932,11062,11465,11695,11718,11914],{},[5667,10933,10936],{"className":5669,"code":10934,"filename":10935,"language":5671,"meta":5672,"style":5672},"\"\"\"\nПакет 'shop' — ядро платформи інтернет-магазину.\nЦей файл виконується при першому import shop або import shop.anything.\n\"\"\"\nprint(\"Ініціалізація пакета shop...\")\n\n# Версія пакета — доступна як shop.__version__\n__version__ = \"1.0.0\"\n\n# Публічний API пакета: що буде доступно при 'from shop import *'\n__all__ = [\"get_product\", \"list_products\", \"get_customer\"]\n\n# \"Фасад\": імпортуємо ключові функції на рівень пакета\n# Тепер можна писати: import shop; shop.list_products()\n# замість: import shop.products; shop.products.list_products()\nfrom .products import list_products, get_product\nfrom .customers import get_customer\n","shop\u002F__init__.py",[5511,10937,10938,10943,10948,10953,10957,10968,10972,10977,10988,10992,10997,11019,11023,11028,11033,11038,11050],{"__ignoreMap":5672},[5676,10939,10940],{"class":5678,"line":5679},[5676,10941,10942],{"class":5758},"\"\"\"\n",[5676,10944,10945],{"class":5678,"line":5686},[5676,10946,10947],{"class":5758},"Пакет 'shop' — ядро платформи інтернет-магазину.\n",[5676,10949,10950],{"class":5678,"line":5693},[5676,10951,10952],{"class":5758},"Цей файл виконується при першому import shop або import shop.anything.\n",[5676,10954,10955],{"class":5678,"line":5707},[5676,10956,10942],{"class":5758},[5676,10958,10959,10961,10963,10966],{"class":5678,"line":5712},[5676,10960,6068],{"class":5719},[5676,10962,5723],{"class":5696},[5676,10964,10965],{"class":5758},"\"Ініціалізація пакета shop...\"",[5676,10967,6049],{"class":5696},[5676,10969,10970],{"class":5678,"line":5755},[5676,10971,5690],{"emptyLinePlaceholder":5689},[5676,10973,10974],{"class":5678,"line":5762},[5676,10975,10976],{"class":5682},"# Версія пакета — доступна як shop.__version__\n",[5676,10978,10979,10982,10985],{"class":5678,"line":5772},[5676,10980,10981],{"class":5726},"__version__",[5676,10983,10984],{"class":5696}," = ",[5676,10986,10987],{"class":5758},"\"1.0.0\"\n",[5676,10989,10990],{"class":5678,"line":5777},[5676,10991,5690],{"emptyLinePlaceholder":5689},[5676,10993,10994],{"class":5678,"line":5807},[5676,10995,10996],{"class":5682},"# Публічний API пакета: що буде доступно при 'from shop import *'\n",[5676,10998,10999,11001,11004,11007,11009,11012,11014,11017],{"class":5678,"line":5813},[5676,11000,7408],{"class":5726},[5676,11002,11003],{"class":5696}," = [",[5676,11005,11006],{"class":5758},"\"get_product\"",[5676,11008,5737],{"class":5696},[5676,11010,11011],{"class":5758},"\"list_products\"",[5676,11013,5737],{"class":5696},[5676,11015,11016],{"class":5758},"\"get_customer\"",[5676,11018,8460],{"class":5696},[5676,11020,11021],{"class":5678,"line":5821},[5676,11022,5690],{"emptyLinePlaceholder":5689},[5676,11024,11025],{"class":5678,"line":5826},[5676,11026,11027],{"class":5682},"# \"Фасад\": імпортуємо ключові функції на рівень пакета\n",[5676,11029,11030],{"class":5678,"line":5856},[5676,11031,11032],{"class":5682},"# Тепер можна писати: import shop; shop.list_products()\n",[5676,11034,11035],{"class":5678,"line":5862},[5676,11036,11037],{"class":5682},"# замість: import shop.products; shop.products.list_products()\n",[5676,11039,11040,11042,11045,11047],{"class":5678,"line":5870},[5676,11041,7020],{"class":5765},[5676,11043,11044],{"class":5696}," .products ",[5676,11046,6018],{"class":5765},[5676,11048,11049],{"class":5696}," list_products, get_product\n",[5676,11051,11052,11054,11057,11059],{"class":5678,"line":5875},[5676,11053,7020],{"class":5765},[5676,11055,11056],{"class":5696}," .customers ",[5676,11058,6018],{"class":5765},[5676,11060,11061],{"class":5696}," get_customer\n",[5667,11063,11066],{"className":5669,"code":11064,"filename":11065,"language":5671,"meta":5672,"style":5672},"\"\"\"Модуль для управління товарами.\"\"\"\n\n_products_db = [\n    {\"id\": 1, \"name\": \"Ноутбук\", \"price\": 35000, \"active\": True},\n    {\"id\": 2, \"name\": \"Миша\", \"price\": 850, \"active\": True},\n    {\"id\": 3, \"name\": \"Клавіатура\", \"price\": 2100, \"active\": False},\n]\n\ndef list_products(active_only: bool = True) -> list:\n    \"\"\"Повертає список товарів. За замовчуванням — тільки активні.\"\"\"\n    if active_only:\n        return [p for p in _products_db if p[\"active\"]]\n    return list(_products_db)\n\ndef get_product(product_id: int) -> dict | None:\n    \"\"\"Знаходить товар за ID або повертає None.\"\"\"\n    for product in _products_db:\n        if product[\"id\"] == product_id:\n            return product\n    return None\n\ndef calculate_price_with_vat(product_id: int, vat_rate: float = 0.20) -> float:\n    \"\"\"Розраховує ціну з ПДВ.\"\"\"\n    product = get_product(product_id)\n    if product is None:\n        raise ValueError(f\"Товар {product_id} не знайдено\")\n    return product[\"price\"] * (1 + vat_rate)\n","shop\u002Fproducts.py",[5511,11067,11068,11073,11077,11082,11125,11163,11201,11205,11209,11235,11240,11247,11274,11284,11288,11315,11320,11333,11346,11354,11361,11365,11400,11405,11410,11423,11449],{"__ignoreMap":5672},[5676,11069,11070],{"class":5678,"line":5679},[5676,11071,11072],{"class":5758},"\"\"\"Модуль для управління товарами.\"\"\"\n",[5676,11074,11075],{"class":5678,"line":5686},[5676,11076,5690],{"emptyLinePlaceholder":5689},[5676,11078,11079],{"class":5678,"line":5693},[5676,11080,11081],{"class":5696},"_products_db = [\n",[5676,11083,11084,11087,11090,11092,11094,11096,11099,11101,11104,11106,11109,11111,11114,11116,11118,11120,11122],{"class":5678,"line":5707},[5676,11085,11086],{"class":5696},"    {",[5676,11088,11089],{"class":5758},"\"id\"",[5676,11091,5730],{"class":5696},[5676,11093,7174],{"class":5700},[5676,11095,5737],{"class":5696},[5676,11097,11098],{"class":5758},"\"name\"",[5676,11100,5730],{"class":5696},[5676,11102,11103],{"class":5758},"\"Ноутбук\"",[5676,11105,5737],{"class":5696},[5676,11107,11108],{"class":5758},"\"price\"",[5676,11110,5730],{"class":5696},[5676,11112,11113],{"class":5700},"35000",[5676,11115,5737],{"class":5696},[5676,11117,9851],{"class":5758},[5676,11119,5730],{"class":5696},[5676,11121,8589],{"class":5715},[5676,11123,11124],{"class":5696},"},\n",[5676,11126,11127,11129,11131,11133,11135,11137,11139,11141,11144,11146,11148,11150,11153,11155,11157,11159,11161],{"class":5678,"line":5712},[5676,11128,11086],{"class":5696},[5676,11130,11089],{"class":5758},[5676,11132,5730],{"class":5696},[5676,11134,6322],{"class":5700},[5676,11136,5737],{"class":5696},[5676,11138,11098],{"class":5758},[5676,11140,5730],{"class":5696},[5676,11142,11143],{"class":5758},"\"Миша\"",[5676,11145,5737],{"class":5696},[5676,11147,11108],{"class":5758},[5676,11149,5730],{"class":5696},[5676,11151,11152],{"class":5700},"850",[5676,11154,5737],{"class":5696},[5676,11156,9851],{"class":5758},[5676,11158,5730],{"class":5696},[5676,11160,8589],{"class":5715},[5676,11162,11124],{"class":5696},[5676,11164,11165,11167,11169,11171,11173,11175,11177,11179,11182,11184,11186,11188,11191,11193,11195,11197,11199],{"class":5678,"line":5755},[5676,11166,11086],{"class":5696},[5676,11168,11089],{"class":5758},[5676,11170,5730],{"class":5696},[5676,11172,7164],{"class":5700},[5676,11174,5737],{"class":5696},[5676,11176,11098],{"class":5758},[5676,11178,5730],{"class":5696},[5676,11180,11181],{"class":5758},"\"Клавіатура\"",[5676,11183,5737],{"class":5696},[5676,11185,11108],{"class":5758},[5676,11187,5730],{"class":5696},[5676,11189,11190],{"class":5700},"2100",[5676,11192,5737],{"class":5696},[5676,11194,9851],{"class":5758},[5676,11196,5730],{"class":5696},[5676,11198,8862],{"class":5715},[5676,11200,11124],{"class":5696},[5676,11202,11203],{"class":5678,"line":5762},[5676,11204,8460],{"class":5696},[5676,11206,11207],{"class":5678,"line":5772},[5676,11208,5690],{"emptyLinePlaceholder":5689},[5676,11210,11211,11213,11216,11218,11221,11223,11225,11227,11229,11231,11233],{"class":5678,"line":5777},[5676,11212,5716],{"class":5715},[5676,11214,11215],{"class":5719}," list_products",[5676,11217,5723],{"class":5696},[5676,11219,11220],{"class":5726},"active_only",[5676,11222,5730],{"class":5696},[5676,11224,5936],{"class":5733},[5676,11226,10984],{"class":5696},[5676,11228,8589],{"class":5715},[5676,11230,5747],{"class":5696},[5676,11232,6779],{"class":5733},[5676,11234,5752],{"class":5696},[5676,11236,11237],{"class":5678,"line":5807},[5676,11238,11239],{"class":5758},"    \"\"\"Повертає список товарів. За замовчуванням — тільки активні.\"\"\"\n",[5676,11241,11242,11244],{"class":5678,"line":5813},[5676,11243,9967],{"class":5765},[5676,11245,11246],{"class":5696}," active_only:\n",[5676,11248,11249,11251,11254,11256,11259,11261,11264,11266,11269,11271],{"class":5678,"line":5821},[5676,11250,9786],{"class":5765},[5676,11252,11253],{"class":5696}," [p ",[5676,11255,5990],{"class":5765},[5676,11257,11258],{"class":5696}," p ",[5676,11260,5996],{"class":5765},[5676,11262,11263],{"class":5696}," _products_db ",[5676,11265,9577],{"class":5765},[5676,11267,11268],{"class":5696}," p[",[5676,11270,9851],{"class":5758},[5676,11272,11273],{"class":5696},"]]\n",[5676,11275,11276,11278,11281],{"class":5678,"line":5826},[5676,11277,5766],{"class":5765},[5676,11279,11280],{"class":5733}," list",[5676,11282,11283],{"class":5696},"(_products_db)\n",[5676,11285,11286],{"class":5678,"line":5856},[5676,11287,5690],{"emptyLinePlaceholder":5689},[5676,11289,11290,11292,11295,11297,11300,11302,11304,11306,11308,11311,11313],{"class":5678,"line":5862},[5676,11291,5716],{"class":5715},[5676,11293,11294],{"class":5719}," get_product",[5676,11296,5723],{"class":5696},[5676,11298,11299],{"class":5726},"product_id",[5676,11301,5730],{"class":5696},[5676,11303,5980],{"class":5733},[5676,11305,5747],{"class":5696},[5676,11307,6389],{"class":5733},[5676,11309,11310],{"class":5696}," | ",[5676,11312,8975],{"class":5715},[5676,11314,5752],{"class":5696},[5676,11316,11317],{"class":5678,"line":5870},[5676,11318,11319],{"class":5758},"    \"\"\"Знаходить товар за ID або повертає None.\"\"\"\n",[5676,11321,11322,11325,11328,11330],{"class":5678,"line":5875},[5676,11323,11324],{"class":5765},"    for",[5676,11326,11327],{"class":5696}," product ",[5676,11329,5996],{"class":5765},[5676,11331,11332],{"class":5696}," _products_db:\n",[5676,11334,11335,11338,11341,11343],{"class":5678,"line":5898},[5676,11336,11337],{"class":5765},"        if",[5676,11339,11340],{"class":5696}," product[",[5676,11342,11089],{"class":5758},[5676,11344,11345],{"class":5696},"] == product_id:\n",[5676,11347,11348,11351],{"class":5678,"line":5904},[5676,11349,11350],{"class":5765},"            return",[5676,11352,11353],{"class":5696}," product\n",[5676,11355,11356,11358],{"class":5678,"line":5915},[5676,11357,5766],{"class":5765},[5676,11359,11360],{"class":5715}," None\n",[5676,11362,11363],{"class":5678,"line":5920},[5676,11364,5690],{"emptyLinePlaceholder":5689},[5676,11366,11367,11369,11372,11374,11376,11378,11380,11382,11385,11387,11389,11391,11394,11396,11398],{"class":5678,"line":5941},[5676,11368,5716],{"class":5715},[5676,11370,11371],{"class":5719}," calculate_price_with_vat",[5676,11373,5723],{"class":5696},[5676,11375,11299],{"class":5726},[5676,11377,5730],{"class":5696},[5676,11379,5980],{"class":5733},[5676,11381,5737],{"class":5696},[5676,11383,11384],{"class":5726},"vat_rate",[5676,11386,5730],{"class":5696},[5676,11388,5734],{"class":5733},[5676,11390,10984],{"class":5696},[5676,11392,11393],{"class":5700},"0.20",[5676,11395,5747],{"class":5696},[5676,11397,5734],{"class":5733},[5676,11399,5752],{"class":5696},[5676,11401,11402],{"class":5678,"line":5947},[5676,11403,11404],{"class":5758},"    \"\"\"Розраховує ціну з ПДВ.\"\"\"\n",[5676,11406,11407],{"class":5678,"line":5953},[5676,11408,11409],{"class":5696},"    product = get_product(product_id)\n",[5676,11411,11412,11414,11416,11418,11421],{"class":5678,"line":5959},[5676,11413,9967],{"class":5765},[5676,11415,11327],{"class":5696},[5676,11417,8479],{"class":5715},[5676,11419,11420],{"class":5715}," None",[5676,11422,5752],{"class":5696},[5676,11424,11425,11428,11431,11433,11435,11438,11440,11442,11444,11447],{"class":5678,"line":5964},[5676,11426,11427],{"class":5765},"        raise",[5676,11429,11430],{"class":5733}," ValueError",[5676,11432,5723],{"class":5696},[5676,11434,6073],{"class":5715},[5676,11436,11437],{"class":5758},"\"Товар ",[5676,11439,6079],{"class":5715},[5676,11441,11299],{"class":5696},[5676,11443,6085],{"class":5715},[5676,11445,11446],{"class":5758}," не знайдено\"",[5676,11448,6049],{"class":5696},[5676,11450,11451,11453,11455,11457,11460,11462],{"class":5678,"line":7576},[5676,11452,5766],{"class":5765},[5676,11454,11340],{"class":5696},[5676,11456,11108],{"class":5758},[5676,11458,11459],{"class":5696},"] * (",[5676,11461,7174],{"class":5700},[5676,11463,11464],{"class":5696}," + vat_rate)\n",[5667,11466,11469],{"className":5669,"code":11467,"filename":11468,"language":5671,"meta":5672,"style":5672},"\"\"\"Модуль для управління клієнтами.\"\"\"\n\n_customers_db = {\n    \"CUST-001\": {\"name\": \"Олена Ковальчук\", \"email\": \"olena@example.com\"},\n    \"CUST-002\": {\"name\": \"Іван Мельник\",    \"email\": \"ivan@example.com\"},\n}\n\ndef get_customer(customer_id: str) -> dict | None:\n    \"\"\"Повертає дані клієнта або None.\"\"\"\n    return _customers_db.get(customer_id)\n\ndef register_customer(customer_id: str, name: str, email: str) -> dict:\n    \"\"\"Реєструє нового клієнта.\"\"\"\n    if customer_id in _customers_db:\n        raise ValueError(f\"Клієнт {customer_id} вже існує\")\n    customer = {\"name\": name, \"email\": email}\n    _customers_db[customer_id] = customer\n    return customer\n","shop\u002Fcustomers.py",[5511,11470,11471,11476,11480,11485,11512,11538,11542,11546,11572,11577,11584,11588,11627,11632,11644,11668,11683,11688],{"__ignoreMap":5672},[5676,11472,11473],{"class":5678,"line":5679},[5676,11474,11475],{"class":5758},"\"\"\"Модуль для управління клієнтами.\"\"\"\n",[5676,11477,11478],{"class":5678,"line":5686},[5676,11479,5690],{"emptyLinePlaceholder":5689},[5676,11481,11482],{"class":5678,"line":5693},[5676,11483,11484],{"class":5696},"_customers_db = {\n",[5676,11486,11487,11490,11493,11495,11497,11500,11502,11505,11507,11510],{"class":5678,"line":5707},[5676,11488,11489],{"class":5758},"    \"CUST-001\"",[5676,11491,11492],{"class":5696},": {",[5676,11494,11098],{"class":5758},[5676,11496,5730],{"class":5696},[5676,11498,11499],{"class":5758},"\"Олена Ковальчук\"",[5676,11501,5737],{"class":5696},[5676,11503,11504],{"class":5758},"\"email\"",[5676,11506,5730],{"class":5696},[5676,11508,11509],{"class":5758},"\"olena@example.com\"",[5676,11511,11124],{"class":5696},[5676,11513,11514,11517,11519,11521,11523,11526,11529,11531,11533,11536],{"class":5678,"line":5712},[5676,11515,11516],{"class":5758},"    \"CUST-002\"",[5676,11518,11492],{"class":5696},[5676,11520,11098],{"class":5758},[5676,11522,5730],{"class":5696},[5676,11524,11525],{"class":5758},"\"Іван Мельник\"",[5676,11527,11528],{"class":5696},",    ",[5676,11530,11504],{"class":5758},[5676,11532,5730],{"class":5696},[5676,11534,11535],{"class":5758},"\"ivan@example.com\"",[5676,11537,11124],{"class":5696},[5676,11539,11540],{"class":5678,"line":5755},[5676,11541,6544],{"class":5696},[5676,11543,11544],{"class":5678,"line":5762},[5676,11545,5690],{"emptyLinePlaceholder":5689},[5676,11547,11548,11550,11553,11555,11558,11560,11562,11564,11566,11568,11570],{"class":5678,"line":5772},[5676,11549,5716],{"class":5715},[5676,11551,11552],{"class":5719}," get_customer",[5676,11554,5723],{"class":5696},[5676,11556,11557],{"class":5726},"customer_id",[5676,11559,5730],{"class":5696},[5676,11561,6258],{"class":5733},[5676,11563,5747],{"class":5696},[5676,11565,6389],{"class":5733},[5676,11567,11310],{"class":5696},[5676,11569,8975],{"class":5715},[5676,11571,5752],{"class":5696},[5676,11573,11574],{"class":5678,"line":5777},[5676,11575,11576],{"class":5758},"    \"\"\"Повертає дані клієнта або None.\"\"\"\n",[5676,11578,11579,11581],{"class":5678,"line":5807},[5676,11580,5766],{"class":5765},[5676,11582,11583],{"class":5696}," _customers_db.get(customer_id)\n",[5676,11585,11586],{"class":5678,"line":5813},[5676,11587,5690],{"emptyLinePlaceholder":5689},[5676,11589,11590,11592,11595,11597,11599,11601,11603,11605,11608,11610,11612,11614,11617,11619,11621,11623,11625],{"class":5678,"line":5821},[5676,11591,5716],{"class":5715},[5676,11593,11594],{"class":5719}," register_customer",[5676,11596,5723],{"class":5696},[5676,11598,11557],{"class":5726},[5676,11600,5730],{"class":5696},[5676,11602,6258],{"class":5733},[5676,11604,5737],{"class":5696},[5676,11606,11607],{"class":5726},"name",[5676,11609,5730],{"class":5696},[5676,11611,6258],{"class":5733},[5676,11613,5737],{"class":5696},[5676,11615,11616],{"class":5726},"email",[5676,11618,5730],{"class":5696},[5676,11620,6258],{"class":5733},[5676,11622,5747],{"class":5696},[5676,11624,6389],{"class":5733},[5676,11626,5752],{"class":5696},[5676,11628,11629],{"class":5678,"line":5826},[5676,11630,11631],{"class":5758},"    \"\"\"Реєструє нового клієнта.\"\"\"\n",[5676,11633,11634,11636,11639,11641],{"class":5678,"line":5856},[5676,11635,9967],{"class":5765},[5676,11637,11638],{"class":5696}," customer_id ",[5676,11640,5996],{"class":5715},[5676,11642,11643],{"class":5696}," _customers_db:\n",[5676,11645,11646,11648,11650,11652,11654,11657,11659,11661,11663,11666],{"class":5678,"line":5862},[5676,11647,11427],{"class":5765},[5676,11649,11430],{"class":5733},[5676,11651,5723],{"class":5696},[5676,11653,6073],{"class":5715},[5676,11655,11656],{"class":5758},"\"Клієнт ",[5676,11658,6079],{"class":5715},[5676,11660,11557],{"class":5696},[5676,11662,6085],{"class":5715},[5676,11664,11665],{"class":5758}," вже існує\"",[5676,11667,6049],{"class":5696},[5676,11669,11670,11673,11675,11678,11680],{"class":5678,"line":5870},[5676,11671,11672],{"class":5696},"    customer = {",[5676,11674,11098],{"class":5758},[5676,11676,11677],{"class":5696},": name, ",[5676,11679,11504],{"class":5758},[5676,11681,11682],{"class":5696},": email}\n",[5676,11684,11685],{"class":5678,"line":5875},[5676,11686,11687],{"class":5696},"    _customers_db[customer_id] = customer\n",[5676,11689,11690,11692],{"class":5678,"line":5898},[5676,11691,5766],{"class":5765},[5676,11693,11694],{"class":5696}," customer\n",[5667,11696,11699],{"className":5669,"code":11697,"filename":11698,"language":5671,"meta":5672,"style":5672},"\"\"\"Підпакет для управління замовленнями.\"\"\"\nfrom .processing import create_order, get_order_status\n","shop\u002Forders\u002F__init__.py",[5511,11700,11701,11706],{"__ignoreMap":5672},[5676,11702,11703],{"class":5678,"line":5679},[5676,11704,11705],{"class":5758},"\"\"\"Підпакет для управління замовленнями.\"\"\"\n",[5676,11707,11708,11710,11713,11715],{"class":5678,"line":5686},[5676,11709,7020],{"class":5765},[5676,11711,11712],{"class":5696}," .processing ",[5676,11714,6018],{"class":5765},[5676,11716,11717],{"class":5696}," create_order, get_order_status\n",[5667,11719,11722],{"className":5669,"code":11720,"filename":11721,"language":5671,"meta":5672,"style":5672},"\"\"\"Модуль обробки замовлень.\"\"\"\n\n_orders = {}\n\ndef create_order(customer_id: str, product_ids: list) -> dict:\n    \"\"\"Створює нове замовлення.\"\"\"\n    order_id = f\"ORD-{len(_orders) + 1:04d}\"\n    order = {\n        \"id\": order_id,\n        \"customer_id\": customer_id,\n        \"product_ids\": product_ids,\n        \"status\": \"pending\"\n    }\n    _orders[order_id] = order\n    return order\n\ndef get_order_status(order_id: str) -> str | None:\n    order = _orders.get(order_id)\n    return order[\"status\"] if order else None\n","shop\u002Forders\u002Fprocessing.py",[5511,11723,11724,11729,11733,11738,11742,11772,11777,11802,11807,11815,11823,11831,11841,11845,11850,11857,11861,11887,11892],{"__ignoreMap":5672},[5676,11725,11726],{"class":5678,"line":5679},[5676,11727,11728],{"class":5758},"\"\"\"Модуль обробки замовлень.\"\"\"\n",[5676,11730,11731],{"class":5678,"line":5686},[5676,11732,5690],{"emptyLinePlaceholder":5689},[5676,11734,11735],{"class":5678,"line":5693},[5676,11736,11737],{"class":5696},"_orders = {}\n",[5676,11739,11740],{"class":5678,"line":5707},[5676,11741,5690],{"emptyLinePlaceholder":5689},[5676,11743,11744,11746,11749,11751,11753,11755,11757,11759,11762,11764,11766,11768,11770],{"class":5678,"line":5712},[5676,11745,5716],{"class":5715},[5676,11747,11748],{"class":5719}," create_order",[5676,11750,5723],{"class":5696},[5676,11752,11557],{"class":5726},[5676,11754,5730],{"class":5696},[5676,11756,6258],{"class":5733},[5676,11758,5737],{"class":5696},[5676,11760,11761],{"class":5726},"product_ids",[5676,11763,5730],{"class":5696},[5676,11765,6779],{"class":5733},[5676,11767,5747],{"class":5696},[5676,11769,6389],{"class":5733},[5676,11771,5752],{"class":5696},[5676,11773,11774],{"class":5678,"line":5755},[5676,11775,11776],{"class":5758},"    \"\"\"Створює нове замовлення.\"\"\"\n",[5676,11778,11779,11782,11784,11787,11789,11791,11794,11796,11799],{"class":5678,"line":5762},[5676,11780,11781],{"class":5696},"    order_id = ",[5676,11783,6073],{"class":5715},[5676,11785,11786],{"class":5758},"\"ORD-",[5676,11788,6079],{"class":5715},[5676,11790,7742],{"class":5719},[5676,11792,11793],{"class":5696},"(_orders) + ",[5676,11795,7174],{"class":5700},[5676,11797,11798],{"class":5715},":04d}",[5676,11800,11801],{"class":5758},"\"\n",[5676,11803,11804],{"class":5678,"line":5772},[5676,11805,11806],{"class":5696},"    order = {\n",[5676,11808,11809,11812],{"class":5678,"line":5777},[5676,11810,11811],{"class":5758},"        \"id\"",[5676,11813,11814],{"class":5696},": order_id,\n",[5676,11816,11817,11820],{"class":5678,"line":5807},[5676,11818,11819],{"class":5758},"        \"customer_id\"",[5676,11821,11822],{"class":5696},": customer_id,\n",[5676,11824,11825,11828],{"class":5678,"line":5813},[5676,11826,11827],{"class":5758},"        \"product_ids\"",[5676,11829,11830],{"class":5696},": product_ids,\n",[5676,11832,11833,11836,11838],{"class":5678,"line":5821},[5676,11834,11835],{"class":5758},"        \"status\"",[5676,11837,5730],{"class":5696},[5676,11839,11840],{"class":5758},"\"pending\"\n",[5676,11842,11843],{"class":5678,"line":5826},[5676,11844,6539],{"class":5696},[5676,11846,11847],{"class":5678,"line":5856},[5676,11848,11849],{"class":5696},"    _orders[order_id] = order\n",[5676,11851,11852,11854],{"class":5678,"line":5862},[5676,11853,5766],{"class":5765},[5676,11855,11856],{"class":5696}," order\n",[5676,11858,11859],{"class":5678,"line":5870},[5676,11860,5690],{"emptyLinePlaceholder":5689},[5676,11862,11863,11865,11868,11870,11873,11875,11877,11879,11881,11883,11885],{"class":5678,"line":5875},[5676,11864,5716],{"class":5715},[5676,11866,11867],{"class":5719}," get_order_status",[5676,11869,5723],{"class":5696},[5676,11871,11872],{"class":5726},"order_id",[5676,11874,5730],{"class":5696},[5676,11876,6258],{"class":5733},[5676,11878,5747],{"class":5696},[5676,11880,6258],{"class":5733},[5676,11882,11310],{"class":5696},[5676,11884,8975],{"class":5715},[5676,11886,5752],{"class":5696},[5676,11888,11889],{"class":5678,"line":5898},[5676,11890,11891],{"class":5696},"    order = _orders.get(order_id)\n",[5676,11893,11894,11896,11899,11902,11904,11906,11909,11912],{"class":5678,"line":5904},[5676,11895,5766],{"class":5765},[5676,11897,11898],{"class":5696}," order[",[5676,11900,11901],{"class":5758},"\"status\"",[5676,11903,7791],{"class":5696},[5676,11905,9577],{"class":5765},[5676,11907,11908],{"class":5696}," order ",[5676,11910,11911],{"class":5765},"else",[5676,11913,11360],{"class":5715},[5667,11915,11917],{"className":5669,"code":11916,"filename":5513,"language":5671,"meta":5672,"style":5672},"# main.py — використання пакета shop\n\n# Спосіб 1: через \"фасад\" __init__.py\nimport shop\nprint(f\"Версія: {shop.__version__}\")\nproducts = shop.list_products()\nprint(f\"Активних товарів: {len(products)}\")\n\n# Спосіб 2: прямий імпорт підмодуля\nfrom shop.products import calculate_price_with_vat\nprice = calculate_price_with_vat(1)\nprint(f\"Ноутбук з ПДВ: {price:.0f} грн\")\n\n# Спосіб 3: підпакет\nfrom shop.orders import create_order\norder = create_order(\"CUST-001\", [1, 2])\nprint(f\"Замовлення: {order['id']}\")\n",[5511,11918,11919,11924,11928,11933,11940,11964,11969,11993,11997,12002,12014,12023,12047,12051,12056,12068,12087],{"__ignoreMap":5672},[5676,11920,11921],{"class":5678,"line":5679},[5676,11922,11923],{"class":5682},"# main.py — використання пакета shop\n",[5676,11925,11926],{"class":5678,"line":5686},[5676,11927,5690],{"emptyLinePlaceholder":5689},[5676,11929,11930],{"class":5678,"line":5693},[5676,11931,11932],{"class":5682},"# Спосіб 1: через \"фасад\" __init__.py\n",[5676,11934,11935,11937],{"class":5678,"line":5707},[5676,11936,6018],{"class":5765},[5676,11938,11939],{"class":5696}," shop\n",[5676,11941,11942,11944,11946,11948,11951,11953,11956,11958,11960,11962],{"class":5678,"line":5712},[5676,11943,6068],{"class":5719},[5676,11945,5723],{"class":5696},[5676,11947,6073],{"class":5715},[5676,11949,11950],{"class":5758},"\"Версія: ",[5676,11952,6079],{"class":5715},[5676,11954,11955],{"class":5696},"shop.",[5676,11957,10981],{"class":5726},[5676,11959,6085],{"class":5715},[5676,11961,6088],{"class":5758},[5676,11963,6049],{"class":5696},[5676,11965,11966],{"class":5678,"line":5755},[5676,11967,11968],{"class":5696},"products = shop.list_products()\n",[5676,11970,11971,11973,11975,11977,11980,11982,11984,11987,11989,11991],{"class":5678,"line":5762},[5676,11972,6068],{"class":5719},[5676,11974,5723],{"class":5696},[5676,11976,6073],{"class":5715},[5676,11978,11979],{"class":5758},"\"Активних товарів: ",[5676,11981,6079],{"class":5715},[5676,11983,7742],{"class":5719},[5676,11985,11986],{"class":5696},"(products)",[5676,11988,6085],{"class":5715},[5676,11990,6088],{"class":5758},[5676,11992,6049],{"class":5696},[5676,11994,11995],{"class":5678,"line":5772},[5676,11996,5690],{"emptyLinePlaceholder":5689},[5676,11998,11999],{"class":5678,"line":5777},[5676,12000,12001],{"class":5682},"# Спосіб 2: прямий імпорт підмодуля\n",[5676,12003,12004,12006,12009,12011],{"class":5678,"line":5807},[5676,12005,7020],{"class":5765},[5676,12007,12008],{"class":5696}," shop.products ",[5676,12010,6018],{"class":5765},[5676,12012,12013],{"class":5696}," calculate_price_with_vat\n",[5676,12015,12016,12019,12021],{"class":5678,"line":5813},[5676,12017,12018],{"class":5696},"price = calculate_price_with_vat(",[5676,12020,7174],{"class":5700},[5676,12022,6049],{"class":5696},[5676,12024,12025,12027,12029,12031,12034,12036,12039,12042,12045],{"class":5678,"line":5821},[5676,12026,6068],{"class":5719},[5676,12028,5723],{"class":5696},[5676,12030,6073],{"class":5715},[5676,12032,12033],{"class":5758},"\"Ноутбук з ПДВ: ",[5676,12035,6079],{"class":5715},[5676,12037,12038],{"class":5696},"price",[5676,12040,12041],{"class":5715},":.0f}",[5676,12043,12044],{"class":5758}," грн\"",[5676,12046,6049],{"class":5696},[5676,12048,12049],{"class":5678,"line":5826},[5676,12050,5690],{"emptyLinePlaceholder":5689},[5676,12052,12053],{"class":5678,"line":5856},[5676,12054,12055],{"class":5682},"# Спосіб 3: підпакет\n",[5676,12057,12058,12060,12063,12065],{"class":5678,"line":5862},[5676,12059,7020],{"class":5765},[5676,12061,12062],{"class":5696}," shop.orders ",[5676,12064,6018],{"class":5765},[5676,12066,12067],{"class":5696}," create_order\n",[5676,12069,12070,12073,12076,12079,12081,12083,12085],{"class":5678,"line":5870},[5676,12071,12072],{"class":5696},"order = create_order(",[5676,12074,12075],{"class":5758},"\"CUST-001\"",[5676,12077,12078],{"class":5696},", [",[5676,12080,7174],{"class":5700},[5676,12082,5737],{"class":5696},[5676,12084,6322],{"class":5700},[5676,12086,7185],{"class":5696},[5676,12088,12089,12091,12093,12095,12098,12100,12103,12106,12108,12110,12112],{"class":5678,"line":5875},[5676,12090,6068],{"class":5719},[5676,12092,5723],{"class":5696},[5676,12094,6073],{"class":5715},[5676,12096,12097],{"class":5758},"\"Замовлення: ",[5676,12099,6079],{"class":5715},[5676,12101,12102],{"class":5696},"order[",[5676,12104,12105],{"class":5758},"'id'",[5676,12107,6854],{"class":5696},[5676,12109,6085],{"class":5715},[5676,12111,6088],{"class":5758},[5676,12113,6049],{"class":5696},[5581,12115,12117,12118,12120],{"id":12116},"роль-__init__py-ворота-пакета","Роль ",[5511,12119,10921],{},": ворота пакета",[5507,12122,12123,12124,12126],{},"Файл ",[5511,12125,10921],{}," виконує три ключові функції.",[5507,12128,12129,12132,12133,12135,12136,12139,12140,12142],{},[5519,12130,12131],{},"Функція 1: Позначення директорії як пакета."," Без ",[5511,12134,10921],{}," Python 3 усе одно ",[6206,12137,12138],{},"може"," знайти пакет (завдяки механізму «namespace packages»), але поведінка буде непередбачуваною. Явний ",[5511,12141,10921],{}," є гарантією.",[5507,12144,12145,12148,12149,12151,12152,6423,12155,12158,12159,12161],{},[5519,12146,12147],{},"Функція 2: Ініціалізаційний код."," Все, що у ",[5511,12150,10921],{},", виконується при першому ",[5511,12153,12154],{},"import shop",[5511,12156,12157],{},"import shop.products"," — але лише один раз (кеш ",[5511,12160,5609],{},"). Тут доречно: підключення до БД, завантаження конфігурації, ініціалізація глобального стану.",[5507,12163,12164,12167,12168,12170],{},[5519,12165,12166],{},"Функція 3: «Фасад» публічного API."," Це найважливіша архітектурна роль. Ре-експортуючи функції у ",[5511,12169,10921],{},", ви:",[7251,12172,12173,12183],{},[5621,12174,12175,12176,12179,12180],{},"Спрощуєте зовнішній API: ",[5511,12177,12178],{},"shop.list_products()"," замість ",[5511,12181,12182],{},"shop.products.list_products()",[5621,12184,12185],{},"Дозволяєте змінювати внутрішню структуру пакета без зламу зовнішнього коду",[5667,12187,12189],{"className":5669,"code":12188,"language":5671,"meta":5672,"style":5672},"# До рефакторингу: shop\u002Fproducts.py\n# Після рефакторингу: shop\u002Fcatalog\u002Fproducts.py\n\n# Але __init__.py залишається незмінним:\nfrom .catalog.products import list_products  # ← просто змінили шлях\n# Зовнішній код 'shop.list_products()' не сломається!\n",[5511,12190,12191,12196,12201,12205,12210,12225],{"__ignoreMap":5672},[5676,12192,12193],{"class":5678,"line":5679},[5676,12194,12195],{"class":5682},"# До рефакторингу: shop\u002Fproducts.py\n",[5676,12197,12198],{"class":5678,"line":5686},[5676,12199,12200],{"class":5682},"# Після рефакторингу: shop\u002Fcatalog\u002Fproducts.py\n",[5676,12202,12203],{"class":5678,"line":5693},[5676,12204,5690],{"emptyLinePlaceholder":5689},[5676,12206,12207],{"class":5678,"line":5707},[5676,12208,12209],{"class":5682},"# Але __init__.py залишається незмінним:\n",[5676,12211,12212,12214,12217,12219,12222],{"class":5678,"line":5712},[5676,12213,7020],{"class":5765},[5676,12215,12216],{"class":5696}," .catalog.products ",[5676,12218,6018],{"class":5765},[5676,12220,12221],{"class":5696}," list_products  ",[5676,12223,12224],{"class":5682},"# ← просто змінили шлях\n",[5676,12226,12227],{"class":5678,"line":5755},[5676,12228,12229],{"class":5682},"# Зовнішній код 'shop.list_products()' не сломається!\n",[5574,12231],{},[5502,12233,12235],{"id":12234},"абсолютний-та-відносний-імпорт","Абсолютний та відносний імпорт",[5581,12237,12239],{"id":12238},"абсолютний-імпорт-повний-шлях-від-кореня","Абсолютний імпорт: повний шлях від кореня",[5507,12241,12242,12245,12246,12248],{},[5519,12243,12244],{},"Абсолютний імпорт"," вказує повний шлях від кореня проекту (або від директорії у ",[5511,12247,5630],{},"):",[5667,12250,12252],{"className":5669,"code":12251,"language":5671,"meta":5672,"style":5672},"# Де б не знаходився цей файл у структурі проекту:\nimport shop.products                        # весь модуль\nfrom shop.products import list_products     # конкретна функція\nfrom shop.orders.processing import create_order  # з підпакета\n",[5511,12253,12254,12259,12269,12283],{"__ignoreMap":5672},[5676,12255,12256],{"class":5678,"line":5679},[5676,12257,12258],{"class":5682},"# Де б не знаходився цей файл у структурі проекту:\n",[5676,12260,12261,12263,12266],{"class":5678,"line":5686},[5676,12262,6018],{"class":5765},[5676,12264,12265],{"class":5696}," shop.products                        ",[5676,12267,12268],{"class":5682},"# весь модуль\n",[5676,12270,12271,12273,12275,12277,12280],{"class":5678,"line":5693},[5676,12272,7020],{"class":5765},[5676,12274,12008],{"class":5696},[5676,12276,6018],{"class":5765},[5676,12278,12279],{"class":5696}," list_products     ",[5676,12281,12282],{"class":5682},"# конкретна функція\n",[5676,12284,12285,12287,12290,12292,12295],{"class":5678,"line":5707},[5676,12286,7020],{"class":5765},[5676,12288,12289],{"class":5696}," shop.orders.processing ",[5676,12291,6018],{"class":5765},[5676,12293,12294],{"class":5696}," create_order  ",[5676,12296,12297],{"class":5682},"# з підпакета\n",[5507,12299,12300,12301,12304],{},"Абсолютні імпорти є однозначними: завжди зрозуміло, звідки береться модуль. ",[5519,12302,12303],{},"PEP 8 рекомендує абсолютний імпорт як основний"," для міжпакетних залежностей.",[5581,12306,12308],{"id":12307},"відносний-імпорт-шлях-відносно-поточного-модуля","Відносний імпорт: шлях відносно поточного модуля",[5507,12310,12311,12314],{},[5519,12312,12313],{},"Відносний імпорт"," використовує крапкову нотацію для вказівки шляху відносно поточного модуля:",[5667,12316,12318],{"className":5669,"code":12317,"language":5671,"meta":5672,"style":5672},"# Всередині shop\u002Forders\u002Fprocessing.py:\nfrom . import notifications       # . = поточний пакет (shop\u002Forders\u002F)\nfrom .notifications import send   # конкретна функція з сусіднього модуля\nfrom .. import products           # .. = батьківський пакет (shop\u002F)\nfrom ..customers import get_customer  # конкретна функція з батька\n",[5511,12319,12320,12325,12340,12355,12370],{"__ignoreMap":5672},[5676,12321,12322],{"class":5678,"line":5679},[5676,12323,12324],{"class":5682},"# Всередині shop\u002Forders\u002Fprocessing.py:\n",[5676,12326,12327,12329,12332,12334,12337],{"class":5678,"line":5686},[5676,12328,7020],{"class":5765},[5676,12330,12331],{"class":5696}," . ",[5676,12333,6018],{"class":5765},[5676,12335,12336],{"class":5696}," notifications       ",[5676,12338,12339],{"class":5682},"# . = поточний пакет (shop\u002Forders\u002F)\n",[5676,12341,12342,12344,12347,12349,12352],{"class":5678,"line":5693},[5676,12343,7020],{"class":5765},[5676,12345,12346],{"class":5696}," .notifications ",[5676,12348,6018],{"class":5765},[5676,12350,12351],{"class":5696}," send   ",[5676,12353,12354],{"class":5682},"# конкретна функція з сусіднього модуля\n",[5676,12356,12357,12359,12362,12364,12367],{"class":5678,"line":5707},[5676,12358,7020],{"class":5765},[5676,12360,12361],{"class":5696}," .. ",[5676,12363,6018],{"class":5765},[5676,12365,12366],{"class":5696}," products           ",[5676,12368,12369],{"class":5682},"# .. = батьківський пакет (shop\u002F)\n",[5676,12371,12372,12374,12377,12379,12382],{"class":5678,"line":5712},[5676,12373,7020],{"class":5765},[5676,12375,12376],{"class":5696}," ..customers ",[5676,12378,6018],{"class":5765},[5676,12380,12381],{"class":5696}," get_customer  ",[5676,12383,12384],{"class":5682},"# конкретна функція з батька\n",[5507,12386,12387,12388,12391,12392,12394,12395,12397],{},"Відносні імпорти мають суттєве обмеження: вони ",[5519,12389,12390],{},"не працюють"," у файлі, що виконується як головний скрипт (",[5511,12393,9394],{},"). Тому не використовуйте відносні імпорти у ",[5511,12396,5513],{}," або в будь-якому файлі, що планується запускати напряму.",[12399,12400,12401,12406],"tip",{},[5507,12402,12403],{},[5519,12404,12405],{},"Коли використовувати відносний vs абсолютний імпорт:",[7251,12407,12408,12417],{},[5621,12409,12410,12413,12414],{},[5519,12411,12412],{},"Абсолютний"," — для імпорту між різними пакетами: ",[5511,12415,12416],{},"from shop.products import ...",[5621,12418,12419,12422,12423,12425,12426,12429,12430],{},[5519,12420,12421],{},"Відносний"," — для зв'язків усередині одного пакета: ",[5511,12424,10325],{}," — гарантує, що пакет використовує свій власний ",[5511,12427,12428],{},"utils",", а не однойменний модуль з іншого місця у ",[5511,12431,5630],{},[5581,12433,12435,12437],{"id":12434},"__all__-контракт-публічного-api",[5511,12436,7408],{},": контракт публічного API",[5507,12439,12440,12441,10558,12443,12445,12446,12449],{},"Змінна ",[5511,12442,7408],{},[5511,12444,10921],{}," або у будь-якому модулі — це список рядків, що визначає, ",[5519,12447,12448],{},"які імена є публічним API"," цього модуля\u002Fпакета:",[5667,12451,12453],{"className":5669,"code":12452,"language":5671,"meta":5672,"style":5672},"# shop\u002Fproducts.py\n\n__all__ = [\"list_products\", \"get_product\", \"calculate_price_with_vat\"]\n# _products_db та будь-які внутрішні допоміжні функції\n# не включені в __all__ і не будуть імпортовані через 'from shop.products import *'\n\ndef list_products(active_only=True): ...\ndef get_product(product_id): ...\ndef calculate_price_with_vat(product_id, vat_rate=0.20): ...\ndef _validate_product(data): ...  # внутрішня, не у __all__\n\n_products_db = [...]              # приватні дані, не у __all__\n",[5511,12454,12455,12460,12464,12483,12488,12493,12497,12514,12526,12546,12563,12567],{"__ignoreMap":5672},[5676,12456,12457],{"class":5678,"line":5679},[5676,12458,12459],{"class":5682},"# shop\u002Fproducts.py\n",[5676,12461,12462],{"class":5678,"line":5686},[5676,12463,5690],{"emptyLinePlaceholder":5689},[5676,12465,12466,12468,12470,12472,12474,12476,12478,12481],{"class":5678,"line":5693},[5676,12467,7408],{"class":5726},[5676,12469,11003],{"class":5696},[5676,12471,11011],{"class":5758},[5676,12473,5737],{"class":5696},[5676,12475,11006],{"class":5758},[5676,12477,5737],{"class":5696},[5676,12479,12480],{"class":5758},"\"calculate_price_with_vat\"",[5676,12482,8460],{"class":5696},[5676,12484,12485],{"class":5678,"line":5707},[5676,12486,12487],{"class":5682},"# _products_db та будь-які внутрішні допоміжні функції\n",[5676,12489,12490],{"class":5678,"line":5712},[5676,12491,12492],{"class":5682},"# не включені в __all__ і не будуть імпортовані через 'from shop.products import *'\n",[5676,12494,12495],{"class":5678,"line":5755},[5676,12496,5690],{"emptyLinePlaceholder":5689},[5676,12498,12499,12501,12503,12505,12507,12509,12511],{"class":5678,"line":5762},[5676,12500,5716],{"class":5715},[5676,12502,11215],{"class":5719},[5676,12504,5723],{"class":5696},[5676,12506,11220],{"class":5726},[5676,12508,9923],{"class":5696},[5676,12510,8589],{"class":5715},[5676,12512,12513],{"class":5696},"): ...\n",[5676,12515,12516,12518,12520,12522,12524],{"class":5678,"line":5772},[5676,12517,5716],{"class":5715},[5676,12519,11294],{"class":5719},[5676,12521,5723],{"class":5696},[5676,12523,11299],{"class":5726},[5676,12525,12513],{"class":5696},[5676,12527,12528,12530,12532,12534,12536,12538,12540,12542,12544],{"class":5678,"line":5777},[5676,12529,5716],{"class":5715},[5676,12531,11371],{"class":5719},[5676,12533,5723],{"class":5696},[5676,12535,11299],{"class":5726},[5676,12537,5737],{"class":5696},[5676,12539,11384],{"class":5726},[5676,12541,9923],{"class":5696},[5676,12543,11393],{"class":5700},[5676,12545,12513],{"class":5696},[5676,12547,12548,12550,12553,12555,12557,12560],{"class":5678,"line":5807},[5676,12549,5716],{"class":5715},[5676,12551,12552],{"class":5719}," _validate_product",[5676,12554,5723],{"class":5696},[5676,12556,9805],{"class":5726},[5676,12558,12559],{"class":5696},"): ...  ",[5676,12561,12562],{"class":5682},"# внутрішня, не у __all__\n",[5676,12564,12565],{"class":5678,"line":5813},[5676,12566,5690],{"emptyLinePlaceholder":5689},[5676,12568,12569,12572],{"class":5678,"line":5821},[5676,12570,12571],{"class":5696},"_products_db = [...]              ",[5676,12573,12574],{"class":5682},"# приватні дані, не у __all__\n",[5507,12576,12577,12579],{},[5511,12578,7408],{}," виконує дві функції:",[5618,12581,12582,12588],{},[5621,12583,12584,12587],{},[5519,12585,12586],{},"Документація",": чітко сигналізує, які об'єкти є стабільним публічним API",[5621,12589,12590,12595,12596,12598,12599],{},[5519,12591,12592,12593],{},"Контроль ",[5511,12594,7416],{},": тільки імена з ",[5511,12597,7408],{}," потрапляють у простір імен при ",[5511,12600,6369],{},[5574,12602],{},[5502,12604,12606],{"id":12605},"частина-iii-віртуальні-середовища","Частина III: Віртуальні Середовища",[5581,12608,12610],{"id":12609},"проблема-глобального-python-пекло-залежностей","Проблема глобального Python: «пекло залежностей»",[5507,12612,12613],{},"Уявіть типову ситуацію: у вас на комп'ютері два Python-проекти.",[7251,12615,12616,12628],{},[5621,12617,12618,12621,12622,6594,12625],{},[5519,12619,12620],{},"Проект А"," (2019 рік): використовує ",[5511,12623,12624],{},"Django 2.2",[5511,12626,12627],{},"requests 2.20",[5621,12629,12630,12633,12634,6594,12637],{},[5519,12631,12632],{},"Проект Б"," (2024 рік): потребує ",[5511,12635,12636],{},"Django 4.2",[5511,12638,12639],{},"requests 2.31",[5507,12641,12642,12643,12646,12647,12650,12651,12654],{},"Якщо встановити обидва проекти у ",[5519,12644,12645],{},"глобальний"," Python (без ізоляції), виникає конфлікт: ",[5511,12648,12649],{},"pip install Django==4.2"," замінить ",[5511,12652,12653],{},"Django==2.2"," — і Проект А зламається. Встановити обидві версії одночасно у глобальний Python неможливо.",[5507,12656,12657,12658,5572],{},"Це явище називається ",[5519,12659,12660],{},"«пекло залежностей» (dependency hell)",[6472,12662,12663],{},[5667,12664,12666],{"className":6476,"code":12665,"language":6478,"meta":5672,"style":5672},"@startuml\nskinparam style plain\nskinparam backgroundColor #ffffff\nskinparam ArrowColor #e11d48\n\npackage \"Глобальний Python (❌ БЕЗ venv)\" {\n    object \"site-packages\" as SP #fee2e2 {\n        Django = ???  (2.2 або 4.2?)\n        requests = ???\n    }\n    note right of SP\n      Неможливо встановити\n      дві версії одночасно!\n    end note\n}\n\nobject \"Проект А\\n(Django 2.2)\" as PA #fef3c7\nobject \"Проект Б\\n(Django 4.2)\" as PB #fef3c7\n\nPA --> SP : потребує Django 2.2\nPB --> SP : потребує Django 4.2\n\nnote bottom\n  pip install django==4.2 знищить django==2.2\n  Проект А зламається!\nend note\n@enduml\n",[5511,12667,12668,12672,12676,12680,12685,12689,12694,12699,12704,12709,12713,12718,12723,12728,12732,12736,12740,12745,12750,12754,12759,12764,12768,12773,12778,12783,12787],{"__ignoreMap":5672},[5676,12669,12670],{"class":5678,"line":5679},[5676,12671,6485],{},[5676,12673,12674],{"class":5678,"line":5686},[5676,12675,6490],{},[5676,12677,12678],{"class":5678,"line":5693},[5676,12679,6495],{},[5676,12681,12682],{"class":5678,"line":5707},[5676,12683,12684],{},"skinparam ArrowColor #e11d48\n",[5676,12686,12687],{"class":5678,"line":5712},[5676,12688,5690],{"emptyLinePlaceholder":5689},[5676,12690,12691],{"class":5678,"line":5755},[5676,12692,12693],{},"package \"Глобальний Python (❌ БЕЗ venv)\" {\n",[5676,12695,12696],{"class":5678,"line":5762},[5676,12697,12698],{},"    object \"site-packages\" as SP #fee2e2 {\n",[5676,12700,12701],{"class":5678,"line":5772},[5676,12702,12703],{},"        Django = ???  (2.2 або 4.2?)\n",[5676,12705,12706],{"class":5678,"line":5777},[5676,12707,12708],{},"        requests = ???\n",[5676,12710,12711],{"class":5678,"line":5807},[5676,12712,6539],{},[5676,12714,12715],{"class":5678,"line":5813},[5676,12716,12717],{},"    note right of SP\n",[5676,12719,12720],{"class":5678,"line":5821},[5676,12721,12722],{},"      Неможливо встановити\n",[5676,12724,12725],{"class":5678,"line":5826},[5676,12726,12727],{},"      дві версії одночасно!\n",[5676,12729,12730],{"class":5678,"line":5856},[5676,12731,7559],{},[5676,12733,12734],{"class":5678,"line":5862},[5676,12735,6544],{},[5676,12737,12738],{"class":5678,"line":5870},[5676,12739,5690],{"emptyLinePlaceholder":5689},[5676,12741,12742],{"class":5678,"line":5875},[5676,12743,12744],{},"object \"Проект А\\n(Django 2.2)\" as PA #fef3c7\n",[5676,12746,12747],{"class":5678,"line":5898},[5676,12748,12749],{},"object \"Проект Б\\n(Django 4.2)\" as PB #fef3c7\n",[5676,12751,12752],{"class":5678,"line":5904},[5676,12753,5690],{"emptyLinePlaceholder":5689},[5676,12755,12756],{"class":5678,"line":5915},[5676,12757,12758],{},"PA --> SP : потребує Django 2.2\n",[5676,12760,12761],{"class":5678,"line":5920},[5676,12762,12763],{},"PB --> SP : потребує Django 4.2\n",[5676,12765,12766],{"class":5678,"line":5941},[5676,12767,5690],{"emptyLinePlaceholder":5689},[5676,12769,12770],{"class":5678,"line":5947},[5676,12771,12772],{},"note bottom\n",[5676,12774,12775],{"class":5678,"line":5953},[5676,12776,12777],{},"  pip install django==4.2 знищить django==2.2\n",[5676,12779,12780],{"class":5678,"line":5959},[5676,12781,12782],{},"  Проект А зламається!\n",[5676,12784,12785],{"class":5678,"line":5964},[5676,12786,6578],{},[5676,12788,12789],{"class":5678,"line":7576},[5676,12790,6583],{},[6472,12792,12793],{},[5667,12794,12796],{"className":6476,"code":12795,"language":6478,"meta":5672,"style":5672},"@startuml\nskinparam style plain\nskinparam backgroundColor #ffffff\nskinparam ArrowColor #6366f1\n\npackage \"venv_project_a\u002F\" #d1fae5 {\n    object \"site-packages A\" as SPA #d1fae5 {\n        Django = 2.2.28\n        requests = 2.20.0\n    }\n}\n\npackage \"venv_project_b\u002F\" #dbeafe {\n    object \"site-packages B\" as SPB #dbeafe {\n        Django = 4.2.7\n        requests = 2.31.0\n    }\n}\n\nobject \"Проект А\" as PA #fef3c7\nobject \"Проект Б\" as PB #fef3c7\n\nPA --> SPA : ізольоване середовище ✅\nPB --> SPB : ізольоване середовище ✅\n\nnote bottom\n  Обидва проекти незалежні.\n  Жодних конфліктів!\nend note\n@enduml\n",[5511,12797,12798,12802,12806,12810,12814,12818,12823,12828,12833,12838,12842,12846,12850,12855,12860,12865,12870,12874,12878,12882,12887,12892,12896,12901,12906,12910,12914,12919,12924,12928],{"__ignoreMap":5672},[5676,12799,12800],{"class":5678,"line":5679},[5676,12801,6485],{},[5676,12803,12804],{"class":5678,"line":5686},[5676,12805,6490],{},[5676,12807,12808],{"class":5678,"line":5693},[5676,12809,6495],{},[5676,12811,12812],{"class":5678,"line":5707},[5676,12813,6500],{},[5676,12815,12816],{"class":5678,"line":5712},[5676,12817,5690],{"emptyLinePlaceholder":5689},[5676,12819,12820],{"class":5678,"line":5755},[5676,12821,12822],{},"package \"venv_project_a\u002F\" #d1fae5 {\n",[5676,12824,12825],{"class":5678,"line":5762},[5676,12826,12827],{},"    object \"site-packages A\" as SPA #d1fae5 {\n",[5676,12829,12830],{"class":5678,"line":5772},[5676,12831,12832],{},"        Django = 2.2.28\n",[5676,12834,12835],{"class":5678,"line":5777},[5676,12836,12837],{},"        requests = 2.20.0\n",[5676,12839,12840],{"class":5678,"line":5807},[5676,12841,6539],{},[5676,12843,12844],{"class":5678,"line":5813},[5676,12845,6544],{},[5676,12847,12848],{"class":5678,"line":5821},[5676,12849,5690],{"emptyLinePlaceholder":5689},[5676,12851,12852],{"class":5678,"line":5826},[5676,12853,12854],{},"package \"venv_project_b\u002F\" #dbeafe {\n",[5676,12856,12857],{"class":5678,"line":5856},[5676,12858,12859],{},"    object \"site-packages B\" as SPB #dbeafe {\n",[5676,12861,12862],{"class":5678,"line":5862},[5676,12863,12864],{},"        Django = 4.2.7\n",[5676,12866,12867],{"class":5678,"line":5870},[5676,12868,12869],{},"        requests = 2.31.0\n",[5676,12871,12872],{"class":5678,"line":5875},[5676,12873,6539],{},[5676,12875,12876],{"class":5678,"line":5898},[5676,12877,6544],{},[5676,12879,12880],{"class":5678,"line":5904},[5676,12881,5690],{"emptyLinePlaceholder":5689},[5676,12883,12884],{"class":5678,"line":5915},[5676,12885,12886],{},"object \"Проект А\" as PA #fef3c7\n",[5676,12888,12889],{"class":5678,"line":5920},[5676,12890,12891],{},"object \"Проект Б\" as PB #fef3c7\n",[5676,12893,12894],{"class":5678,"line":5941},[5676,12895,5690],{"emptyLinePlaceholder":5689},[5676,12897,12898],{"class":5678,"line":5947},[5676,12899,12900],{},"PA --> SPA : ізольоване середовище ✅\n",[5676,12902,12903],{"class":5678,"line":5953},[5676,12904,12905],{},"PB --> SPB : ізольоване середовище ✅\n",[5676,12907,12908],{"class":5678,"line":5959},[5676,12909,5690],{"emptyLinePlaceholder":5689},[5676,12911,12912],{"class":5678,"line":5964},[5676,12913,12772],{},[5676,12915,12916],{"class":5678,"line":7576},[5676,12917,12918],{},"  Обидва проекти незалежні.\n",[5676,12920,12921],{"class":5678,"line":7581},[5676,12922,12923],{},"  Жодних конфліктів!\n",[5676,12925,12926],{"class":5678,"line":7587},[5676,12927,6578],{},[5676,12929,12930],{"class":5678,"line":7593},[5676,12931,6583],{},[5581,12933,8220,12935,12938],{"id":12934},"що-таке-venv-ізольований-python-від-стандартної-бібліотеки",[5511,12936,12937],{},"venv",": ізольований Python від стандартної бібліотеки",[5507,12940,12941,12945,12946,12949,12950,5572],{},[5519,12942,12943],{},[5511,12944,12937],{}," — це стандартний модуль Python (доступний без встановлення з Python 3.3+), що створює ",[5519,12947,12948],{},"ізольоване середовище виконання",". Технічно це директорія з окремою копією інтерпретатора Python та власною директорією ",[5511,12951,8110],{},[5507,12953,12954,12955,12958,12959,6594,12961,12963,12964,12966],{},"При ",[5519,12956,12957],{},"активації"," venv оболонка перенаправляє команди ",[5511,12960,5671],{},[5511,12962,8268],{}," на копії у середовищі. Будь-яка встановлена бібліотека потрапляє у ",[5511,12965,8110],{}," цього середовища — повністю ізольовано від глобального Python та інших середовищ.",[6400,12968,12970],{"id":12969},"як-venv-працює-під-капотом","Як venv працює під капотом",[5507,12972,12973],{},"Багато хто вважає, що віртуальне середовище — це повна копія інтерпретатора Python. Насправді це дуже легка структура, яка працює завдяки кільком системним конфігураціям та логіці пошуку шляхів самого Python.",[5507,12975,12976,12977,12979,12980,12985],{},"Ключовим елементом будь-якого ",[5511,12978,12937],{}," є файл ",[5519,12981,12982],{},[5511,12983,12984],{},"pyvenv.cfg",", який лежить у корені папки середовища. Його вміст виглядає приблизно так:",[5667,12987,12991],{"className":12988,"code":12989,"language":12990,"meta":5672,"style":5672},"language-ini shiki shiki-themes light-plus dark-plus dark-plus","home = \u002Fusr\u002Fbin\ninclude-system-site-packages = false\nversion = 3.12.2\nexecutable = \u002Fusr\u002Fbin\u002Fpython3.12\ncommand = \u002Fusr\u002Fbin\u002Fpython3 -m venv \u002Fhome\u002Fuser\u002Fmyproject\u002F.venv\n","ini",[5511,12992,12993,13001,13009,13017,13025],{"__ignoreMap":5672},[5676,12994,12995,12998],{"class":5678,"line":5679},[5676,12996,12997],{"class":5715},"home",[5676,12999,13000],{"class":5696}," = \u002Fusr\u002Fbin\n",[5676,13002,13003,13006],{"class":5678,"line":5686},[5676,13004,13005],{"class":5715},"include-system-site-packages",[5676,13007,13008],{"class":5696}," = false\n",[5676,13010,13011,13014],{"class":5678,"line":5693},[5676,13012,13013],{"class":5715},"version",[5676,13015,13016],{"class":5696}," = 3.12.2\n",[5676,13018,13019,13022],{"class":5678,"line":5707},[5676,13020,13021],{"class":5715},"executable",[5676,13023,13024],{"class":5696}," = \u002Fusr\u002Fbin\u002Fpython3.12\n",[5676,13026,13027,13030],{"class":5678,"line":5712},[5676,13028,13029],{"class":5715},"command",[5676,13031,13032],{"class":5696}," = \u002Fusr\u002Fbin\u002Fpython3 -m venv \u002Fhome\u002Fuser\u002Fmyproject\u002F.venv\n",[5507,13034,13035,13036,13039,13040,13043],{},"Коли ви запускаєте файл ",[5511,13037,13038],{},".venv\u002Fbin\u002Fpython"," (або ",[5511,13041,13042],{},".venv\u002FScripts\u002Fpython.exe"," на Windows), відбувається такий алгоритм:",[5618,13045,13046,13055,13089],{},[5621,13047,13048,13051,13052,13054],{},[5519,13049,13050],{},"Пошук конфігурації",":\nІнтерпретатор шукає файл ",[5511,13053,12984],{}," у своїй директорії або директорії на рівень вище.",[5621,13056,13057,6410,13060],{},[5519,13058,13059],{},"Встановлення префіксів",[7251,13061,13062,13067,13078],{},[5621,13063,9383,13064,13066],{},[5511,13065,12984],{}," знайдено, Python розуміє, що він запущений всередині віртуального середовища.",[5621,13068,12440,13069,13074,13075,13077],{},[5519,13070,13071],{},[5511,13072,13073],{},"sys.base_prefix"," встановлюється на шлях із параметра ",[5511,13076,12997],{}," (це глобальна установка Python, де лежить реальний виконуваний файл і стандартна бібліотека).",[5621,13079,12440,13080,13085,13086,13088],{},[5519,13081,13082],{},[5511,13083,13084],{},"sys.prefix"," встановлюється на директорію, де лежить ",[5511,13087,12984],{}," (тобто на ваше віртуальне середовище).",[5621,13090,13091,13096,13097,13099,13100,13102,13103,13106,13107,5572],{},[5519,13092,13093,13094],{},"Формування ",[5511,13095,5630],{},":\nПри формуванні шляхів пошуку модулів Python використовує значення ",[5511,13098,13084],{},". Завдяки цьому він підключає ",[5511,13101,8110],{}," із папки ",[5511,13104,13105],{},".venv\u002Flib\u002Fpython3.X\u002Fsite-packages\u002F"," замість глобального ",[5511,13108,8110],{},[5507,13110,13111,13112,13115],{},"Скрипт активації (",[5511,13113,13114],{},"source .venv\u002Fbin\u002Factivate",") насправді є дуже простим оболонковим (shell) скриптом, який робить лише дві речі:",[5618,13117,13118,13134],{},[5621,13119,13120,13121,13124,13125,13128,13129,6423,13131,13133],{},"Додає шлях до ",[5511,13122,13123],{},".venv\u002Fbin\u002F"," на самий початок змінної середовища вашої системи ",[5511,13126,13127],{},"PATH",". Завдяки цьому, коли ви вводите ",[5511,13130,5671],{},[5511,13132,8268],{},", викликаються саме файли з вашого середовища, а не глобальні.",[5621,13135,13136,13137,5572],{},"Тимчасово змінює промпт вашого терміналу, додаючи ",[5511,13138,13139],{},"(.venv) ",[13141,13142,13143,13144,13147,13148,5572],"note",{},"Активація через ",[5511,13145,13146],{},"source"," — це зручність для терміналу. Програми та IDE можуть працювати з venv без будь-якої активації — їм просто достатньо запускати інтерпретатор безпосередньо за шляхом ",[5511,13149,13038],{},[5581,13151,13153],{"id":13152},"повний-цикл-роботи-з-venv","Повний цикл роботи з venv",[5507,13155,13156],{},[5519,13157,13158],{},"Крок 1: Створення середовища",[5667,13160,13164],{"className":13161,"code":13162,"language":13163,"meta":5672,"style":5672},"language-bash shiki shiki-themes light-plus dark-plus dark-plus","# python -m venv \u003Cназва_директорії>\n# Конвенція: називати середовище 'venv' або '.venv'\n\npython -m venv venv        # звичайне середовище\npython -m venv .venv       # приховане (починається з крапки)\npython3.12 -m venv .venv   # явна версія Python\n","bash",[5511,13165,13166,13171,13176,13180,13195,13209],{"__ignoreMap":5672},[5676,13167,13168],{"class":5678,"line":5679},[5676,13169,13170],{"class":5682},"# python -m venv \u003Cназва_директорії>\n",[5676,13172,13173],{"class":5678,"line":5686},[5676,13174,13175],{"class":5682},"# Конвенція: називати середовище 'venv' або '.venv'\n",[5676,13177,13178],{"class":5678,"line":5693},[5676,13179,5690],{"emptyLinePlaceholder":5689},[5676,13181,13182,13184,13187,13190,13192],{"class":5678,"line":5707},[5676,13183,5671],{"class":5719},[5676,13185,13186],{"class":5715}," -m",[5676,13188,13189],{"class":5758}," venv",[5676,13191,13189],{"class":5758},[5676,13193,13194],{"class":5682},"        # звичайне середовище\n",[5676,13196,13197,13199,13201,13203,13206],{"class":5678,"line":5712},[5676,13198,5671],{"class":5719},[5676,13200,13186],{"class":5715},[5676,13202,13189],{"class":5758},[5676,13204,13205],{"class":5758}," .venv",[5676,13207,13208],{"class":5682},"       # приховане (починається з крапки)\n",[5676,13210,13211,13214,13216,13218,13220],{"class":5678,"line":5755},[5676,13212,13213],{"class":5719},"python3.12",[5676,13215,13186],{"class":5715},[5676,13217,13189],{"class":5758},[5676,13219,13205],{"class":5758},[5676,13221,13222],{"class":5682},"   # явна версія Python\n",[5507,13224,13225],{},"Після виконання команди Python створює таку структуру:",[5667,13227,13230],{"className":13228,"code":13229,"language":10831},[10829],".venv\u002F\n├── bin\u002F                    # (Linux\u002FmacOS)\n│   ├── python              # символічне посилання на інтерпретатор\n│   ├── python3\n│   ├── pip\n│   └── activate            # скрипт активації!\n├── lib\u002F\n│   └── python3.12\u002F\n│       └── site-packages\u002F  # сюди pip встановлює пакети\n└── pyvenv.cfg              # конфігурація середовища\n",[5511,13231,13229],{"__ignoreMap":5672},[5507,13233,13234],{},[5519,13235,13236],{},"Крок 2: Активація середовища",[5507,13238,13239,13240,5737,13242,13245,13246,6594,13248,13250],{},"Активація — це зміна змінних середовища оболонки (",[5511,13241,13127],{},[5511,13243,13244],{},"VIRTUAL_ENV",") так, щоб команди ",[5511,13247,5671],{},[5511,13249,8268],{}," вели до venv.",[6941,13252,13253,13307,13355],{},[6944,13254,13256],{"label":13255},"macOS \u002F Linux (bash\u002Fzsh)",[5667,13257,13259],{"className":13161,"code":13258,"language":13163,"meta":5672,"style":5672},"source .venv\u002Fbin\u002Factivate\n\n# Підтвердження активації: у промпті з'явиться назва середовища\n# (.venv) user@host:~\u002Fmyproject$\n\nwhich python  # \u002Fhome\u002Fuser\u002Fmyproject\u002F.venv\u002Fbin\u002Fpython\nwhich pip     # \u002Fhome\u002Fuser\u002Fmyproject\u002F.venv\u002Fbin\u002Fpip\n",[5511,13260,13261,13268,13272,13277,13282,13286,13297],{"__ignoreMap":5672},[5676,13262,13263,13265],{"class":5678,"line":5679},[5676,13264,13146],{"class":5719},[5676,13266,13267],{"class":5758}," .venv\u002Fbin\u002Factivate\n",[5676,13269,13270],{"class":5678,"line":5686},[5676,13271,5690],{"emptyLinePlaceholder":5689},[5676,13273,13274],{"class":5678,"line":5693},[5676,13275,13276],{"class":5682},"# Підтвердження активації: у промпті з'явиться назва середовища\n",[5676,13278,13279],{"class":5678,"line":5707},[5676,13280,13281],{"class":5682},"# (.venv) user@host:~\u002Fmyproject$\n",[5676,13283,13284],{"class":5678,"line":5712},[5676,13285,5690],{"emptyLinePlaceholder":5689},[5676,13287,13288,13291,13294],{"class":5678,"line":5755},[5676,13289,13290],{"class":5719},"which",[5676,13292,13293],{"class":5758}," python",[5676,13295,13296],{"class":5682},"  # \u002Fhome\u002Fuser\u002Fmyproject\u002F.venv\u002Fbin\u002Fpython\n",[5676,13298,13299,13301,13304],{"class":5678,"line":5762},[5676,13300,13290],{"class":5719},[5676,13302,13303],{"class":5758}," pip",[5676,13305,13306],{"class":5682},"     # \u002Fhome\u002Fuser\u002Fmyproject\u002F.venv\u002Fbin\u002Fpip\n",[6944,13308,13310],{"label":13309},"Windows (CMD)",[5667,13311,13315],{"className":13312,"code":13313,"language":13314,"meta":5672,"style":5672},"language-bat shiki shiki-themes light-plus dark-plus dark-plus",".venv\\Scripts\\activate.bat\n\n:: Або в PowerShell:\n.venv\\Scripts\\Activate.ps1\n\n:: Підтвердження: (.venv) C:\\myproject>\nwhere python\n:: C:\\myproject\\.venv\\Scripts\\python.exe\n","bat",[5511,13316,13317,13322,13326,13331,13336,13340,13345,13350],{"__ignoreMap":5672},[5676,13318,13319],{"class":5678,"line":5679},[5676,13320,13321],{},".venv\\Scripts\\activate.bat\n",[5676,13323,13324],{"class":5678,"line":5686},[5676,13325,5690],{"emptyLinePlaceholder":5689},[5676,13327,13328],{"class":5678,"line":5693},[5676,13329,13330],{},":: Або в PowerShell:\n",[5676,13332,13333],{"class":5678,"line":5707},[5676,13334,13335],{},".venv\\Scripts\\Activate.ps1\n",[5676,13337,13338],{"class":5678,"line":5712},[5676,13339,5690],{"emptyLinePlaceholder":5689},[5676,13341,13342],{"class":5678,"line":5755},[5676,13343,13344],{},":: Підтвердження: (.venv) C:\\myproject>\n",[5676,13346,13347],{"class":5678,"line":5762},[5676,13348,13349],{},"where python\n",[5676,13351,13352],{"class":5678,"line":5772},[5676,13353,13354],{},":: C:\\myproject\\.venv\\Scripts\\python.exe\n",[6944,13356,13358],{"label":13357},"Fish Shell",[5667,13359,13363],{"className":13360,"code":13361,"language":13362,"meta":5672,"style":5672},"language-fish shiki shiki-themes light-plus dark-plus dark-plus","source .venv\u002Fbin\u002Factivate.fish\n","fish",[5511,13364,13365],{"__ignoreMap":5672},[5676,13366,13367],{"class":5678,"line":5679},[5676,13368,13361],{},[5507,13370,13371],{},[5519,13372,13373],{},"Крок 3: Встановлення пакетів",[5507,13375,13376,13377,13379,13380,6410],{},"Після активації ",[5511,13378,7977],{}," встановлює пакети ізольовано у ",[5511,13381,13105],{},[5667,13383,13385],{"className":13161,"code":13384,"language":13163,"meta":5672,"style":5672},"# Встановлення з PyPI\npip install requests                   # остання версія\npip install requests==2.31.0           # конкретна версія\npip install \"requests>=2.28,\u003C3.0\"      # діапазон версій\npip install django djangorestframework  # кілька одразу\n\n# Список встановлених пакетів\npip list\n\n# Детальна інформація про пакет\npip show requests\n",[5511,13386,13387,13392,13405,13420,13432,13447,13451,13456,13463,13467,13472],{"__ignoreMap":5672},[5676,13388,13389],{"class":5678,"line":5679},[5676,13390,13391],{"class":5682},"# Встановлення з PyPI\n",[5676,13393,13394,13396,13399,13402],{"class":5678,"line":5686},[5676,13395,8268],{"class":5719},[5676,13397,13398],{"class":5758}," install",[5676,13400,13401],{"class":5758}," requests",[5676,13403,13404],{"class":5682},"                   # остання версія\n",[5676,13406,13407,13409,13411,13414,13417],{"class":5678,"line":5693},[5676,13408,8268],{"class":5719},[5676,13410,13398],{"class":5758},[5676,13412,13413],{"class":5758}," requests==",[5676,13415,13416],{"class":5700},"2.31.0",[5676,13418,13419],{"class":5682},"           # конкретна версія\n",[5676,13421,13422,13424,13426,13429],{"class":5678,"line":5707},[5676,13423,8268],{"class":5719},[5676,13425,13398],{"class":5758},[5676,13427,13428],{"class":5758}," \"requests>=2.28,\u003C3.0\"",[5676,13430,13431],{"class":5682},"      # діапазон версій\n",[5676,13433,13434,13436,13438,13441,13444],{"class":5678,"line":5712},[5676,13435,8268],{"class":5719},[5676,13437,13398],{"class":5758},[5676,13439,13440],{"class":5758}," django",[5676,13442,13443],{"class":5758}," djangorestframework",[5676,13445,13446],{"class":5682},"  # кілька одразу\n",[5676,13448,13449],{"class":5678,"line":5755},[5676,13450,5690],{"emptyLinePlaceholder":5689},[5676,13452,13453],{"class":5678,"line":5762},[5676,13454,13455],{"class":5682},"# Список встановлених пакетів\n",[5676,13457,13458,13460],{"class":5678,"line":5772},[5676,13459,8268],{"class":5719},[5676,13461,13462],{"class":5758}," list\n",[5676,13464,13465],{"class":5678,"line":5777},[5676,13466,5690],{"emptyLinePlaceholder":5689},[5676,13468,13469],{"class":5678,"line":5807},[5676,13470,13471],{"class":5682},"# Детальна інформація про пакет\n",[5676,13473,13474,13476,13479],{"class":5678,"line":5813},[5676,13475,8268],{"class":5719},[5676,13477,13478],{"class":5758}," show",[5676,13480,13481],{"class":5758}," requests\n",[6145,13483,13485,13498,13502,13506,13510,13514,13518,13522,13526,13530],{"title":13484},"Процес встановлення пакета у venv",[6149,13486,13488,6157,13492,6157,13495],{"className":13487},[5678],[5676,13489,13491],{"className":13490},[6167],"(.venv)",[5676,13493,6156],{"className":13494},[6155],[5519,13496,13497],{},"pip install requests",[6149,13499,13501],{"className":13500},[5678],"Collecting requests",[6149,13503,13505],{"className":13504},[5678],"  Downloading requests-2.31.0-py3-none-any.whl (62 kB)",[6149,13507,13509],{"className":13508},[5678],"     ━━━━━━━━━━━━━━━━━━━━━━ 62.6\u002F62.6 kB 1.2 MB\u002Fs eta 0:00:00",[6149,13511,13513],{"className":13512},[5678],"Collecting charset-normalizer\u003C4,>=2 (from requests)",[6149,13515,13517],{"className":13516},[5678],"Collecting idna\u003C4,>=2.5 (from requests)",[6149,13519,13521],{"className":13520},[5678],"Collecting urllib3\u003C3,>=1.21.1 (from requests)",[6149,13523,13525],{"className":13524},[5678],"Collecting certifi>=2017.4.17 (from requests)",[6149,13527,13529],{"className":13528},[5678],"Installing collected packages: urllib3, idna, certifi, charset-normalizer, requests",[6149,13531,13533,13534,13538],{"className":13532},[5678],"Successfully installed certifi-2024.2.2 charset-normalizer-3.3.2 idna-3.7 ",[5676,13535,13537],{"className":13536},[6167],"requests-2.31.0"," urllib3-2.2.1",[5507,13540,13541],{},[5519,13542,13543],{},"Крок 4: Деактивація",[5667,13545,13547],{"className":13161,"code":13546,"language":13163,"meta":5672,"style":5672},"deactivate\n\n# Промпт повернувся до нормального вигляду:\n# user@host:~\u002Fmyproject$\n\nwhich python  # \u002Fusr\u002Fbin\u002Fpython3  ← глобальний Python\n",[5511,13548,13549,13554,13558,13563,13568,13572],{"__ignoreMap":5672},[5676,13550,13551],{"class":5678,"line":5679},[5676,13552,13553],{"class":5719},"deactivate\n",[5676,13555,13556],{"class":5678,"line":5686},[5676,13557,5690],{"emptyLinePlaceholder":5689},[5676,13559,13560],{"class":5678,"line":5693},[5676,13561,13562],{"class":5682},"# Промпт повернувся до нормального вигляду:\n",[5676,13564,13565],{"class":5678,"line":5707},[5676,13566,13567],{"class":5682},"# user@host:~\u002Fmyproject$\n",[5676,13569,13570],{"class":5678,"line":5712},[5676,13571,5690],{"emptyLinePlaceholder":5689},[5676,13573,13574,13576,13578],{"class":5678,"line":5755},[5676,13575,13290],{"class":5719},[5676,13577,13293],{"class":5758},[5676,13579,13580],{"class":5682},"  # \u002Fusr\u002Fbin\u002Fpython3  ← глобальний Python\n",[5581,13582,13584,13587],{"id":13583},"requirementstxt-заморожування-залежностей",[5511,13585,13586],{},"requirements.txt",": заморожування залежностей",[5507,13589,12123,13590,13592],{},[5511,13591,13586],{}," — це текстовий маніфест точних версій усіх пакетів, потрібних вашому проекту. Він є стандартом відтворюваності Python-проектів.",[5507,13594,13595],{},[5519,13596,13597,13598,13600],{},"Генерація ",[5511,13599,13586],{}," з активного середовища:",[5667,13602,13604],{"className":13161,"code":13603,"language":13163,"meta":5672,"style":5672},"# pip freeze виводить всі встановлені пакети з точними версіями\npip freeze > requirements.txt\n\ncat requirements.txt\n",[5511,13605,13606,13611,13624,13628],{"__ignoreMap":5672},[5676,13607,13608],{"class":5678,"line":5679},[5676,13609,13610],{"class":5682},"# pip freeze виводить всі встановлені пакети з точними версіями\n",[5676,13612,13613,13615,13618,13621],{"class":5678,"line":5686},[5676,13614,8268],{"class":5719},[5676,13616,13617],{"class":5758}," freeze",[5676,13619,13620],{"class":5696}," > ",[5676,13622,13623],{"class":5758},"requirements.txt\n",[5676,13625,13626],{"class":5678,"line":5693},[5676,13627,5690],{"emptyLinePlaceholder":5689},[5676,13629,13630,13633],{"class":5678,"line":5707},[5676,13631,13632],{"class":5719},"cat",[5676,13634,13635],{"class":5758}," requirements.txt\n",[6145,13637,13639,13651,13660,13664,13668,13672,13679],{"title":13638},"requirements.txt: зафіксовані залежності",[6149,13640,13642,6157,13645,6157,13648],{"className":13641},[5678],[5676,13643,13491],{"className":13644},[6167],[5676,13646,6156],{"className":13647},[6155],[5519,13649,13650],{},"pip freeze > requirements.txt",[6149,13652,13654,6157,13657],{"className":13653},[5678],[5676,13655,6156],{"className":13656},[6155],[5519,13658,13659],{},"cat requirements.txt",[6149,13661,13663],{"className":13662},[5678],"certifi==2024.2.2",[6149,13665,13667],{"className":13666},[5678],"charset-normalizer==3.3.2",[6149,13669,13671],{"className":13670},[5678],"idna==3.7",[6149,13673,13675],{"className":13674},[5678],[5676,13676,13678],{"className":13677},[6184],"requests==2.31.0",[6149,13680,13682],{"className":13681},[5678],"urllib3==2.2.1",[5507,13684,13685],{},[5519,13686,13687,13688,6410],{},"Відтворення середовища з ",[5511,13689,13586],{},[5667,13691,13693],{"className":13161,"code":13692,"language":13163,"meta":5672,"style":5672},"# На іншій машині або у CI\u002FCD:\npython -m venv .venv\nsource .venv\u002Fbin\u002Factivate\n\npip install -r requirements.txt\n# pip встановить точно ті ж версії, що зафіксовані у файлі\n",[5511,13694,13695,13700,13711,13717,13721,13732],{"__ignoreMap":5672},[5676,13696,13697],{"class":5678,"line":5679},[5676,13698,13699],{"class":5682},"# На іншій машині або у CI\u002FCD:\n",[5676,13701,13702,13704,13706,13708],{"class":5678,"line":5686},[5676,13703,5671],{"class":5719},[5676,13705,13186],{"class":5715},[5676,13707,13189],{"class":5758},[5676,13709,13710],{"class":5758}," .venv\n",[5676,13712,13713,13715],{"class":5678,"line":5693},[5676,13714,13146],{"class":5719},[5676,13716,13267],{"class":5758},[5676,13718,13719],{"class":5678,"line":5707},[5676,13720,5690],{"emptyLinePlaceholder":5689},[5676,13722,13723,13725,13727,13730],{"class":5678,"line":5712},[5676,13724,8268],{"class":5719},[5676,13726,13398],{"class":5758},[5676,13728,13729],{"class":5715}," -r",[5676,13731,13635],{"class":5758},[5676,13733,13734],{"class":5678,"line":5755},[5676,13735,13736],{"class":5682},"# pip встановить точно ті ж версії, що зафіксовані у файлі\n",[12399,13738,13739,13742,13743,13746,13747,13749,13750,5737,13753,5737,13756,13759,13760,13762,13763,13765],{},[5519,13740,13741],{},"Сучасна альтернатива:"," Сьогодні у нових проектах часто використовують ",[5511,13744,13745],{},"pyproject.toml"," (стандарт PEP 517\u002F518) замість ",[5511,13748,13586],{},". Менеджери пакетів ",[5511,13751,13752],{},"poetry",[5511,13754,13755],{},"uv",[5511,13757,13758],{},"pdm"," — надають більш потужне управління залежностями. Але ",[5511,13761,13586],{}," + ",[5511,13764,12937],{}," залишаються базовим стандартом, який потрібно знати.",[5574,13767],{},[5502,13769,13771],{"id":13770},"частина-iv-сучасні-менеджери-пакетів","Частина IV: Сучасні менеджери пакетів",[5507,13773,13774,13775,13762,13777,13762,13779,13781],{},"Стандартний тандем ",[5511,13776,12937],{},[5511,13778,8268],{},[5511,13780,13586],{}," надійний і повсюдно підтримуваний. Але у виробничих проектах він має відомі недоліки:",[7251,13783,13784,13794,13801,13808],{},[5621,13785,13786,13789,13790,13793],{},[5511,13787,13788],{},"pip freeze"," включає ",[5519,13791,13792],{},"транзитивні"," залежності (ті, що потрібні вашим залежностям), а не лише прямі — файл стає важким до читання і крихким при оновленні.",[5621,13795,13796,13797,13800],{},"Немає ",[5519,13798,13799],{},"детермінованого lockfile"," зі сумами хешів для кожної платформи окремо.",[5621,13802,13803,13804,13807],{},"Немає вбудованого управління ",[5519,13805,13806],{},"версіями Python"," або запуску команд у ізольованому середовищі.",[5621,13809,13810,13812],{},[5511,13811,8268],{}," не вирішує конфлікти залежностей наперед — він просто встановлює і повідомляє про помилку вже після.",[5507,13814,13815,13816,13820,13821,13826],{},"Два найпопулярніші інструменти, що вирішують ці проблеми: ",[5519,13817,13818],{},[5511,13819,13755],{}," (наступне покоління, швидкість у 10–100 разів вища за pip) та ",[5519,13822,13823],{},[5511,13824,13825],{},"Poetry"," (зрілий, широко розповсюджений у промисловому середовищі).",[5574,13828],{},[5581,13830,13832,13834],{"id":13831},"uv-ультрашвидкий-менеджер-нового-покоління",[5511,13833,13755],{}," — ультрашвидкий менеджер нового покоління",[5507,13836,13837,13841,13842,13845,13846,5737,13848,5737,13851,5737,13854,13857,13858,13860],{},[5519,13838,13839],{},[5511,13840,13755],{}," — це інструмент від компанії Astral (автори лінтера ",[5511,13843,13844],{},"ruff","), написаний на Rust. Він замінює одразу кілька інструментів: ",[5511,13847,8268],{},[5511,13849,13850],{},"pip-tools",[5511,13852,13853],{},"virtualenv",[5511,13855,13856],{},"pyenv"," та частково ",[5511,13859,13752],{}," — з єдиного бінарного файлу.",[5524,13862,13863,13870,13891,13903],{},[5527,13864,13867,13869],{"icon":13865,"title":13866},"i-heroicons-bolt","10–100x швидше за pip",[5511,13868,13755],{}," використовує паралельне завантаження пакетів і оптимізований резолвер залежностей. Встановлення Django з усіма залежностями займає менше секунди проти 10–30 секунд у pip.",[5527,13871,13874,13875,13878,13879,13882,13883,13886,13887,13890],{"icon":13872,"title":13873},"i-heroicons-wrench-screwdriver","Єдиний інструмент","Управляє версіями Python (",[5511,13876,13877],{},"uv python install 3.12","), середовищами (",[5511,13880,13881],{},"uv venv","), залежностями (",[5511,13884,13885],{},"uv add\u002Fremove",") та інструментами CLI (",[5511,13888,13889],{},"uvx ruff","). Один бінарний файл замість п'яти.",[5527,13892,13895,13898,13899,13902],{"icon":13893,"title":13894},"i-heroicons-lock-closed","Детермінований lockfile",[5511,13896,13897],{},"uv.lock"," фіксує точні версії та хеші для всіх платформ. Синхронізація через ",[5511,13900,13901],{},"uv sync"," гарантує ідентичне середовище на будь-якій машині.",[5527,13904,13907,13908,13910,13911,13762,13913,13762,13916,5572],{"icon":13905,"title":13906},"i-heroicons-document-text","pyproject.toml (PEP 621)","Використовує стандарт ",[5511,13909,13745],{}," як єдину точку конфігурації замість ",[5511,13912,13586],{},[5511,13914,13915],{},"setup.py",[5511,13917,13918],{},"setup.cfg",[6400,13920,13922,13923],{"id":13921},"встановлення-uv","Встановлення ",[5511,13924,13755],{},[5667,13926,13928],{"className":13161,"code":13927,"language":13163,"meta":5672,"style":5672},"# macOS \u002F Linux\ncurl -LsSf https:\u002F\u002Fastral.sh\u002Fuv\u002Finstall.sh | sh\n\n# Windows (PowerShell)\npowershell -ExecutionPolicy ByPass -c \"irm https:\u002F\u002Fastral.sh\u002Fuv\u002Finstall.ps1 | iex\"\n\n# Також через pip (якщо вже є Python):\npip install uv\n\n# Перевірка встановлення\nuv --version  # uv 0.5.x (або новіше)\n",[5511,13929,13930,13935,13951,13955,13960,13977,13981,13986,13995,13999,14004],{"__ignoreMap":5672},[5676,13931,13932],{"class":5678,"line":5679},[5676,13933,13934],{"class":5682},"# macOS \u002F Linux\n",[5676,13936,13937,13940,13943,13946,13948],{"class":5678,"line":5686},[5676,13938,13939],{"class":5719},"curl",[5676,13941,13942],{"class":5715}," -LsSf",[5676,13944,13945],{"class":5758}," https:\u002F\u002Fastral.sh\u002Fuv\u002Finstall.sh",[5676,13947,11310],{"class":5696},[5676,13949,13950],{"class":5719},"sh\n",[5676,13952,13953],{"class":5678,"line":5693},[5676,13954,5690],{"emptyLinePlaceholder":5689},[5676,13956,13957],{"class":5678,"line":5707},[5676,13958,13959],{"class":5682},"# Windows (PowerShell)\n",[5676,13961,13962,13965,13968,13971,13974],{"class":5678,"line":5712},[5676,13963,13964],{"class":5719},"powershell",[5676,13966,13967],{"class":5715}," -ExecutionPolicy",[5676,13969,13970],{"class":5758}," ByPass",[5676,13972,13973],{"class":5715}," -c",[5676,13975,13976],{"class":5758}," \"irm https:\u002F\u002Fastral.sh\u002Fuv\u002Finstall.ps1 | iex\"\n",[5676,13978,13979],{"class":5678,"line":5755},[5676,13980,5690],{"emptyLinePlaceholder":5689},[5676,13982,13983],{"class":5678,"line":5762},[5676,13984,13985],{"class":5682},"# Також через pip (якщо вже є Python):\n",[5676,13987,13988,13990,13992],{"class":5678,"line":5772},[5676,13989,8268],{"class":5719},[5676,13991,13398],{"class":5758},[5676,13993,13994],{"class":5758}," uv\n",[5676,13996,13997],{"class":5678,"line":5777},[5676,13998,5690],{"emptyLinePlaceholder":5689},[5676,14000,14001],{"class":5678,"line":5807},[5676,14002,14003],{"class":5682},"# Перевірка встановлення\n",[5676,14005,14006,14008,14011],{"class":5678,"line":5813},[5676,14007,13755],{"class":5719},[5676,14009,14010],{"class":5715}," --version",[5676,14012,14013],{"class":5682},"  # uv 0.5.x (або новіше)\n",[6400,14015,14017],{"id":14016},"створення-нового-проекту-з-нуля","Створення нового проекту з нуля",[5667,14019,14021],{"className":13161,"code":14020,"language":13163,"meta":5672,"style":5672},"# Ініціалізація проекту — створює pyproject.toml і базову структуру\nuv init my-web-api\ncd my-web-api\n\n# Або ініціалізація у поточній директорії\nmkdir my-project && cd my-project\nuv init\n",[5511,14022,14023,14028,14038,14045,14049,14054,14070],{"__ignoreMap":5672},[5676,14024,14025],{"class":5678,"line":5679},[5676,14026,14027],{"class":5682},"# Ініціалізація проекту — створює pyproject.toml і базову структуру\n",[5676,14029,14030,14032,14035],{"class":5678,"line":5686},[5676,14031,13755],{"class":5719},[5676,14033,14034],{"class":5758}," init",[5676,14036,14037],{"class":5758}," my-web-api\n",[5676,14039,14040,14043],{"class":5678,"line":5693},[5676,14041,14042],{"class":5719},"cd",[5676,14044,14037],{"class":5758},[5676,14046,14047],{"class":5678,"line":5707},[5676,14048,5690],{"emptyLinePlaceholder":5689},[5676,14050,14051],{"class":5678,"line":5712},[5676,14052,14053],{"class":5682},"# Або ініціалізація у поточній директорії\n",[5676,14055,14056,14059,14062,14065,14067],{"class":5678,"line":5755},[5676,14057,14058],{"class":5719},"mkdir",[5676,14060,14061],{"class":5758}," my-project",[5676,14063,14064],{"class":5696}," && ",[5676,14066,14042],{"class":5719},[5676,14068,14069],{"class":5758}," my-project\n",[5676,14071,14072,14074],{"class":5678,"line":5762},[5676,14073,13755],{"class":5719},[5676,14075,14076],{"class":5758}," init\n",[6145,14078,14080,14089,14093,14102,14106,14115,14122,14129],{"title":14079},"uv init — структура нового проекту",[6149,14081,14083,6157,14086],{"className":14082},[5678],[5676,14084,6156],{"className":14085},[6155],[5519,14087,14088],{},"uv init my-web-api",[6149,14090,14092],{"className":14091},[5678],"Initialized project `my-web-api` at `\u002FUsers\u002Fuser\u002Fmy-web-api`",[6149,14094,14096,6157,14099],{"className":14095},[5678],[5676,14097,6156],{"className":14098},[6155],[5519,14100,14101],{},"tree my-web-api\u002F",[6149,14103,14105],{"className":14104},[5678],"my-web-api\u002F",[6149,14107,14109,14110,14114],{"className":14108},[5678],"├── ",[5676,14111,14113],{"className":14112},[6184],".python-version","   ← фіксована версія Python",[6149,14116,14109,14118,14121],{"className":14117},[5678],[5676,14119,13745],{"className":14120},[7829],"    ← конфігурація проекту",[6149,14123,14109,14125],{"className":14124},[5678],[5676,14126,14128],{"className":14127},[6167],"README.md",[6149,14130,14132,14133,14137],{"className":14131},[5678],"└── ",[5676,14134,14136],{"className":14135},[6184],"hello.py","          ← точка входу",[5507,14139,14140,14141,14144,14145,6410],{},"Після ",[5511,14142,14143],{},"uv init"," проект вже має ",[5511,14146,13745],{},[5667,14148,14152],{"className":14149,"code":14150,"language":14151,"meta":5672,"style":5672},"language-toml shiki shiki-themes light-plus dark-plus dark-plus","# pyproject.toml (генерується автоматично)\n[project]\nname = \"my-web-api\"\nversion = \"0.1.0\"\ndescription = \"Add your description here\"\nreadme = \"README.md\"\nrequires-python = \">=3.12\"\ndependencies = []\n","toml",[5511,14153,14154,14159,14164,14173,14182,14192,14202,14212],{"__ignoreMap":5672},[5676,14155,14156],{"class":5678,"line":5679},[5676,14157,14158],{"class":5682},"# pyproject.toml (генерується автоматично)\n",[5676,14160,14161],{"class":5678,"line":5686},[5676,14162,14163],{"class":5696},"[project]\n",[5676,14165,14166,14168,14170],{"class":5678,"line":5693},[5676,14167,11607],{"class":5726},[5676,14169,10984],{"class":5696},[5676,14171,14172],{"class":5758},"\"my-web-api\"\n",[5676,14174,14175,14177,14179],{"class":5678,"line":5707},[5676,14176,13013],{"class":5726},[5676,14178,10984],{"class":5696},[5676,14180,14181],{"class":5758},"\"0.1.0\"\n",[5676,14183,14184,14187,14189],{"class":5678,"line":5712},[5676,14185,14186],{"class":5726},"description",[5676,14188,10984],{"class":5696},[5676,14190,14191],{"class":5758},"\"Add your description here\"\n",[5676,14193,14194,14197,14199],{"class":5678,"line":5755},[5676,14195,14196],{"class":5726},"readme",[5676,14198,10984],{"class":5696},[5676,14200,14201],{"class":5758},"\"README.md\"\n",[5676,14203,14204,14207,14209],{"class":5678,"line":5762},[5676,14205,14206],{"class":5726},"requires-python",[5676,14208,10984],{"class":5696},[5676,14210,14211],{"class":5758},"\">=3.12\"\n",[5676,14213,14214,14217],{"class":5678,"line":5772},[5676,14215,14216],{"class":5726},"dependencies",[5676,14218,14219],{"class":5696}," = []\n",[6400,14221,14223],{"id":14222},"управління-залежностями","Управління залежностями",[5667,14225,14227],{"className":13161,"code":14226,"language":13163,"meta":5672,"style":5672},"# Додавання залежності — оновлює pyproject.toml і uv.lock автоматично\nuv add fastapi\nuv add \"sqlalchemy>=2.0\"\nuv add \"pydantic>=2.5,\u003C3.0\"\n\n# Кілька залежностей одразу\nuv add httpx aiohttp redis\n\n# Залежності лише для розробки (не потрапляють у production)\nuv add --dev pytest pytest-asyncio ruff mypy\nuv add --dev black isort\n\n# Видалення залежності\nuv remove redis\n\n# Синхронізація середовища з lockfile (аналог pip install -r requirements.txt)\nuv sync\n\n# Синхронізація без dev-залежностей (для production)\nuv sync --no-dev\n",[5511,14228,14229,14234,14243,14252,14261,14265,14270,14285,14289,14294,14315,14329,14333,14338,14347,14351,14356,14363,14367,14372],{"__ignoreMap":5672},[5676,14230,14231],{"class":5678,"line":5679},[5676,14232,14233],{"class":5682},"# Додавання залежності — оновлює pyproject.toml і uv.lock автоматично\n",[5676,14235,14236,14238,14240],{"class":5678,"line":5686},[5676,14237,13755],{"class":5719},[5676,14239,5720],{"class":5758},[5676,14241,14242],{"class":5758}," fastapi\n",[5676,14244,14245,14247,14249],{"class":5678,"line":5693},[5676,14246,13755],{"class":5719},[5676,14248,5720],{"class":5758},[5676,14250,14251],{"class":5758}," \"sqlalchemy>=2.0\"\n",[5676,14253,14254,14256,14258],{"class":5678,"line":5707},[5676,14255,13755],{"class":5719},[5676,14257,5720],{"class":5758},[5676,14259,14260],{"class":5758}," \"pydantic>=2.5,\u003C3.0\"\n",[5676,14262,14263],{"class":5678,"line":5712},[5676,14264,5690],{"emptyLinePlaceholder":5689},[5676,14266,14267],{"class":5678,"line":5755},[5676,14268,14269],{"class":5682},"# Кілька залежностей одразу\n",[5676,14271,14272,14274,14276,14279,14282],{"class":5678,"line":5762},[5676,14273,13755],{"class":5719},[5676,14275,5720],{"class":5758},[5676,14277,14278],{"class":5758}," httpx",[5676,14280,14281],{"class":5758}," aiohttp",[5676,14283,14284],{"class":5758}," redis\n",[5676,14286,14287],{"class":5678,"line":5772},[5676,14288,5690],{"emptyLinePlaceholder":5689},[5676,14290,14291],{"class":5678,"line":5777},[5676,14292,14293],{"class":5682},"# Залежності лише для розробки (не потрапляють у production)\n",[5676,14295,14296,14298,14300,14303,14306,14309,14312],{"class":5678,"line":5807},[5676,14297,13755],{"class":5719},[5676,14299,5720],{"class":5758},[5676,14301,14302],{"class":5715}," --dev",[5676,14304,14305],{"class":5758}," pytest",[5676,14307,14308],{"class":5758}," pytest-asyncio",[5676,14310,14311],{"class":5758}," ruff",[5676,14313,14314],{"class":5758}," mypy\n",[5676,14316,14317,14319,14321,14323,14326],{"class":5678,"line":5813},[5676,14318,13755],{"class":5719},[5676,14320,5720],{"class":5758},[5676,14322,14302],{"class":5715},[5676,14324,14325],{"class":5758}," black",[5676,14327,14328],{"class":5758}," isort\n",[5676,14330,14331],{"class":5678,"line":5821},[5676,14332,5690],{"emptyLinePlaceholder":5689},[5676,14334,14335],{"class":5678,"line":5826},[5676,14336,14337],{"class":5682},"# Видалення залежності\n",[5676,14339,14340,14342,14345],{"class":5678,"line":5856},[5676,14341,13755],{"class":5719},[5676,14343,14344],{"class":5758}," remove",[5676,14346,14284],{"class":5758},[5676,14348,14349],{"class":5678,"line":5862},[5676,14350,5690],{"emptyLinePlaceholder":5689},[5676,14352,14353],{"class":5678,"line":5870},[5676,14354,14355],{"class":5682},"# Синхронізація середовища з lockfile (аналог pip install -r requirements.txt)\n",[5676,14357,14358,14360],{"class":5678,"line":5875},[5676,14359,13755],{"class":5719},[5676,14361,14362],{"class":5758}," sync\n",[5676,14364,14365],{"class":5678,"line":5898},[5676,14366,5690],{"emptyLinePlaceholder":5689},[5676,14368,14369],{"class":5678,"line":5904},[5676,14370,14371],{"class":5682},"# Синхронізація без dev-залежностей (для production)\n",[5676,14373,14374,14376,14379],{"class":5678,"line":5915},[5676,14375,13755],{"class":5719},[5676,14377,14378],{"class":5758}," sync",[5676,14380,14381],{"class":5715}," --no-dev\n",[6145,14383,14385,14394,14406,14417,14421,14425,14432,14436,14440,14444,14448,14452,14456,14460,14464],{"title":14384},"uv add — швидке додавання залежності",[6149,14386,14388,6157,14391],{"className":14387},[5678],[5676,14389,6156],{"className":14390},[6155],[5519,14392,14393],{},"uv add fastapi uvicorn",[6149,14395,14397,14398,14401,14402],{"className":14396},[5678],"Resolved ",[5676,14399,6168],{"className":14400},[6184]," packages in ",[5676,14403,14405],{"className":14404},[6167],"287ms",[6149,14407,14409,14410,14401,14413],{"className":14408},[5678],"Installed ",[5676,14411,6168],{"className":14412},[6184],[5676,14414,14416],{"className":14415},[6167],"423ms",[6149,14418,14420],{"className":14419},[5678]," + annotated-types==0.7.0",[6149,14422,14424],{"className":14423},[5678]," + anyio==4.7.0",[6149,14426,13762,14428],{"className":14427},[5678],[5676,14429,14431],{"className":14430},[6167],"fastapi==0.115.6",[6149,14433,14435],{"className":14434},[5678]," + h11==0.14.0",[6149,14437,14439],{"className":14438},[5678]," + httpcore==1.0.7",[6149,14441,14443],{"className":14442},[5678]," + idna==3.10",[6149,14445,14447],{"className":14446},[5678]," + pydantic==2.10.3",[6149,14449,14451],{"className":14450},[5678]," + pydantic-core==2.27.1",[6149,14453,14455],{"className":14454},[5678]," + sniffio==1.3.1",[6149,14457,14459],{"className":14458},[5678]," + starlette==0.41.3",[6149,14461,14463],{"className":14462},[5678]," + typing-extensions==4.12.2",[6149,14465,13762,14467],{"className":14466},[5678],[5676,14468,14470],{"className":14469},[6167],"uvicorn==0.32.1",[5507,14472,14473,14474,6157,14477,14479],{},"Після виконання ",[5511,14475,14476],{},"uv add",[5511,14478,13745],{}," оновлюється автоматично:",[5667,14481,14483],{"className":14149,"code":14482,"language":14151,"meta":5672,"style":5672},"[project]\nname = \"my-web-api\"\nversion = \"0.1.0\"\nrequires-python = \">=3.12\"\ndependencies = [\n    \"fastapi>=0.115.6\",\n    \"uvicorn>=0.32.1\",\n]\n\n[dependency-groups]\ndev = [\n    \"pytest>=8.3.4\",\n    \"ruff>=0.8.4\",\n    \"mypy>=1.13.0\",\n]\n",[5511,14484,14485,14489,14497,14505,14513,14520,14528,14535,14539,14543,14548,14555,14562,14569,14576],{"__ignoreMap":5672},[5676,14486,14487],{"class":5678,"line":5679},[5676,14488,14163],{"class":5696},[5676,14490,14491,14493,14495],{"class":5678,"line":5686},[5676,14492,11607],{"class":5726},[5676,14494,10984],{"class":5696},[5676,14496,14172],{"class":5758},[5676,14498,14499,14501,14503],{"class":5678,"line":5693},[5676,14500,13013],{"class":5726},[5676,14502,10984],{"class":5696},[5676,14504,14181],{"class":5758},[5676,14506,14507,14509,14511],{"class":5678,"line":5707},[5676,14508,14206],{"class":5726},[5676,14510,10984],{"class":5696},[5676,14512,14211],{"class":5758},[5676,14514,14515,14517],{"class":5678,"line":5712},[5676,14516,14216],{"class":5726},[5676,14518,14519],{"class":5696}," = [\n",[5676,14521,14522,14525],{"class":5678,"line":5755},[5676,14523,14524],{"class":5758},"    \"fastapi>=0.115.6\"",[5676,14526,14527],{"class":5696},",\n",[5676,14529,14530,14533],{"class":5678,"line":5762},[5676,14531,14532],{"class":5758},"    \"uvicorn>=0.32.1\"",[5676,14534,14527],{"class":5696},[5676,14536,14537],{"class":5678,"line":5772},[5676,14538,8460],{"class":5696},[5676,14540,14541],{"class":5678,"line":5777},[5676,14542,5690],{"emptyLinePlaceholder":5689},[5676,14544,14545],{"class":5678,"line":5807},[5676,14546,14547],{"class":5696},"[dependency-groups]\n",[5676,14549,14550,14553],{"class":5678,"line":5813},[5676,14551,14552],{"class":5726},"dev",[5676,14554,14519],{"class":5696},[5676,14556,14557,14560],{"class":5678,"line":5821},[5676,14558,14559],{"class":5758},"    \"pytest>=8.3.4\"",[5676,14561,14527],{"class":5696},[5676,14563,14564,14567],{"class":5678,"line":5826},[5676,14565,14566],{"class":5758},"    \"ruff>=0.8.4\"",[5676,14568,14527],{"class":5696},[5676,14570,14571,14574],{"class":5678,"line":5856},[5676,14572,14573],{"class":5758},"    \"mypy>=1.13.0\"",[5676,14575,14527],{"class":5696},[5676,14577,14578],{"class":5678,"line":5862},[5676,14579,8460],{"class":5696},[6400,14581,14583],{"id":14582},"запуск-коду-та-команд","Запуск коду та команд",[5507,14585,14586,14589],{},[5511,14587,14588],{},"uv run"," запускає скрипт або команду у керованому середовищі проекту — без потреби вручну активувати середовище:",[5667,14591,14593],{"className":13161,"code":14592,"language":13163,"meta":5672,"style":5672},"# Запуск скрипта\nuv run python main.py\n\n# Запуск застосунку\nuv run uvicorn main:app --reload\n\n# Запуск тестів\nuv run pytest\n\n# Запуск лінтера\nuv run ruff check .\n\n# uv run також може виконувати скрипти без встановлення:\n# навіть якщо pytest не у залежностях — uv встановить тимчасово\nuv run --with pytest pytest tests\u002F\n",[5511,14594,14595,14600,14612,14616,14621,14636,14640,14645,14654,14658,14663,14677,14681,14686,14691],{"__ignoreMap":5672},[5676,14596,14597],{"class":5678,"line":5679},[5676,14598,14599],{"class":5682},"# Запуск скрипта\n",[5676,14601,14602,14604,14607,14609],{"class":5678,"line":5686},[5676,14603,13755],{"class":5719},[5676,14605,14606],{"class":5758}," run",[5676,14608,13293],{"class":5758},[5676,14610,14611],{"class":5758}," main.py\n",[5676,14613,14614],{"class":5678,"line":5693},[5676,14615,5690],{"emptyLinePlaceholder":5689},[5676,14617,14618],{"class":5678,"line":5707},[5676,14619,14620],{"class":5682},"# Запуск застосунку\n",[5676,14622,14623,14625,14627,14630,14633],{"class":5678,"line":5712},[5676,14624,13755],{"class":5719},[5676,14626,14606],{"class":5758},[5676,14628,14629],{"class":5758}," uvicorn",[5676,14631,14632],{"class":5758}," main:app",[5676,14634,14635],{"class":5715}," --reload\n",[5676,14637,14638],{"class":5678,"line":5755},[5676,14639,5690],{"emptyLinePlaceholder":5689},[5676,14641,14642],{"class":5678,"line":5762},[5676,14643,14644],{"class":5682},"# Запуск тестів\n",[5676,14646,14647,14649,14651],{"class":5678,"line":5772},[5676,14648,13755],{"class":5719},[5676,14650,14606],{"class":5758},[5676,14652,14653],{"class":5758}," pytest\n",[5676,14655,14656],{"class":5678,"line":5777},[5676,14657,5690],{"emptyLinePlaceholder":5689},[5676,14659,14660],{"class":5678,"line":5807},[5676,14661,14662],{"class":5682},"# Запуск лінтера\n",[5676,14664,14665,14667,14669,14671,14674],{"class":5678,"line":5813},[5676,14666,13755],{"class":5719},[5676,14668,14606],{"class":5758},[5676,14670,14311],{"class":5758},[5676,14672,14673],{"class":5758}," check",[5676,14675,14676],{"class":5758}," .\n",[5676,14678,14679],{"class":5678,"line":5821},[5676,14680,5690],{"emptyLinePlaceholder":5689},[5676,14682,14683],{"class":5678,"line":5826},[5676,14684,14685],{"class":5682},"# uv run також може виконувати скрипти без встановлення:\n",[5676,14687,14688],{"class":5678,"line":5856},[5676,14689,14690],{"class":5682},"# навіть якщо pytest не у залежностях — uv встановить тимчасово\n",[5676,14692,14693,14695,14697,14700,14702,14704],{"class":5678,"line":5862},[5676,14694,13755],{"class":5719},[5676,14696,14606],{"class":5758},[5676,14698,14699],{"class":5715}," --with",[5676,14701,14305],{"class":5758},[5676,14703,14305],{"class":5758},[5676,14705,14706],{"class":5758}," tests\u002F\n",[14708,14709,14710,14712,14713,14715,14716,6594,14719,5572],"important",{},[5511,14711,14588],{}," автоматично синхронізує середовище перед запуском, якщо ",[5511,14714,13897],{}," та встановлені пакети не відповідають одне одному. Це робить його ідеальним для CI\u002FCD: не потрібні окремі кроки ",[5511,14717,14718],{},"venv create",[5511,14720,7977],{},[6400,14722,14724],{"id":14723},"управління-версіями-python","Управління версіями Python",[5507,14726,14727,14728,14730,14731,12248],{},"Одна з найпотужніших функцій ",[5511,14729,13755],{}," — вбудоване управління версіями Python (аналог ",[5511,14732,13856],{},[5667,14734,14736],{"className":13161,"code":14735,"language":13163,"meta":5672,"style":5672},"# Встановлення конкретної версії Python\nuv python install 3.12\nuv python install 3.11 3.13  # кілька версій одразу\n\n# Перегляд доступних та встановлених версій\nuv python list\n\n# Прив'язка версії Python до проекту\nuv python pin 3.12  # записує у .python-version\n\n# Використання конкретної версії при ініціалізації проекту\nuv init --python 3.11 legacy-service\n",[5511,14737,14738,14743,14754,14771,14775,14780,14788,14792,14797,14812,14816,14821],{"__ignoreMap":5672},[5676,14739,14740],{"class":5678,"line":5679},[5676,14741,14742],{"class":5682},"# Встановлення конкретної версії Python\n",[5676,14744,14745,14747,14749,14751],{"class":5678,"line":5686},[5676,14746,13755],{"class":5719},[5676,14748,13293],{"class":5758},[5676,14750,13398],{"class":5758},[5676,14752,14753],{"class":5700}," 3.12\n",[5676,14755,14756,14758,14760,14762,14765,14768],{"class":5678,"line":5693},[5676,14757,13755],{"class":5719},[5676,14759,13293],{"class":5758},[5676,14761,13398],{"class":5758},[5676,14763,14764],{"class":5700}," 3.11",[5676,14766,14767],{"class":5700}," 3.13",[5676,14769,14770],{"class":5682},"  # кілька версій одразу\n",[5676,14772,14773],{"class":5678,"line":5707},[5676,14774,5690],{"emptyLinePlaceholder":5689},[5676,14776,14777],{"class":5678,"line":5712},[5676,14778,14779],{"class":5682},"# Перегляд доступних та встановлених версій\n",[5676,14781,14782,14784,14786],{"class":5678,"line":5755},[5676,14783,13755],{"class":5719},[5676,14785,13293],{"class":5758},[5676,14787,13462],{"class":5758},[5676,14789,14790],{"class":5678,"line":5762},[5676,14791,5690],{"emptyLinePlaceholder":5689},[5676,14793,14794],{"class":5678,"line":5772},[5676,14795,14796],{"class":5682},"# Прив'язка версії Python до проекту\n",[5676,14798,14799,14801,14803,14806,14809],{"class":5678,"line":5777},[5676,14800,13755],{"class":5719},[5676,14802,13293],{"class":5758},[5676,14804,14805],{"class":5758}," pin",[5676,14807,14808],{"class":5700}," 3.12",[5676,14810,14811],{"class":5682},"  # записує у .python-version\n",[5676,14813,14814],{"class":5678,"line":5807},[5676,14815,5690],{"emptyLinePlaceholder":5689},[5676,14817,14818],{"class":5678,"line":5813},[5676,14819,14820],{"class":5682},"# Використання конкретної версії при ініціалізації проекту\n",[5676,14822,14823,14825,14827,14830,14832],{"class":5678,"line":5821},[5676,14824,13755],{"class":5719},[5676,14826,14034],{"class":5758},[5676,14828,14829],{"class":5715}," --python",[5676,14831,14764],{"class":5700},[5676,14833,14834],{"class":5758}," legacy-service\n",[6145,14836,14838,14847,14855,14867,14875],{"title":14837},"uv python list — огляд версій",[6149,14839,14841,6157,14844],{"className":14840},[5678],[5676,14842,6156],{"className":14843},[6155],[5519,14845,14846],{},"uv python list",[6149,14848,14850,14851],{"className":14849},[5678],"cpython-3.13.1-macos-aarch64-none    ",[5676,14852,14854],{"className":14853},[6184],"\u002FUsers\u002Fuser\u002F.local\u002Fshare\u002Fuv\u002Fpython\u002Fcpython-3.13.1...",[6149,14856,14858,14859,6157,14863],{"className":14857},[5678],"cpython-3.12.8-macos-aarch64-none    ",[5676,14860,14862],{"className":14861},[6184],"\u002FUsers\u002Fuser\u002F.local\u002Fshare\u002Fuv\u002Fpython\u002Fcpython-3.12.8...",[5676,14864,14866],{"className":14865},[6167],"← активна",[6149,14868,14870,14871],{"className":14869},[5678],"cpython-3.11.11-macos-aarch64-none   ",[5676,14872,14874],{"className":14873},[6184],"\u002FUsers\u002Fuser\u002F.local\u002Fshare\u002Fuv\u002Fpython\u002Fcpython-3.11.11...",[6149,14876,14878,14879],{"className":14877},[5678],"cpython-3.10.16-macos-aarch64-none   ",[5676,14880,14882],{"className":14881},[6184],"\u002FUsers\u002Fuser\u002F.local\u002Fshare\u002Fuv\u002Fpython\u002Fcpython-3.10.16...",[6400,14884,14886,14887],{"id":14885},"запуск-cli-інструментів-через-uvx","Запуск CLI-інструментів через ",[5511,14888,14889],{},"uvx",[5507,14891,14892,14894,14895,14898],{},[5511,14893,14889],{}," — це аналог ",[5511,14896,14897],{},"npx"," з Node.js: запускає CLI-інструменти без встановлення у проект, у тимчасовому ізольованому середовищі:",[5667,14900,14902],{"className":13161,"code":14901,"language":13163,"meta":5672,"style":5672},"# Запуск без встановлення (uvx = uv tool run)\nuvx ruff check .          # запускає ruff для перевірки поточної директорії\nuvx black myfile.py        # форматує файл\nuvx httpie GET httpbin.org\u002Fget  # HTTP-клієнт для тестування API\n\n# Встановлення інструментів глобально (available everywhere)\nuv tool install ruff\nuv tool install black\nuv tool list               # список встановлених інструментів\n",[5511,14903,14904,14909,14923,14935,14951,14955,14960,14972,14983],{"__ignoreMap":5672},[5676,14905,14906],{"class":5678,"line":5679},[5676,14907,14908],{"class":5682},"# Запуск без встановлення (uvx = uv tool run)\n",[5676,14910,14911,14913,14915,14917,14920],{"class":5678,"line":5686},[5676,14912,14889],{"class":5719},[5676,14914,14311],{"class":5758},[5676,14916,14673],{"class":5758},[5676,14918,14919],{"class":5758}," .",[5676,14921,14922],{"class":5682},"          # запускає ruff для перевірки поточної директорії\n",[5676,14924,14925,14927,14929,14932],{"class":5678,"line":5693},[5676,14926,14889],{"class":5719},[5676,14928,14325],{"class":5758},[5676,14930,14931],{"class":5758}," myfile.py",[5676,14933,14934],{"class":5682},"        # форматує файл\n",[5676,14936,14937,14939,14942,14945,14948],{"class":5678,"line":5707},[5676,14938,14889],{"class":5719},[5676,14940,14941],{"class":5758}," httpie",[5676,14943,14944],{"class":5758}," GET",[5676,14946,14947],{"class":5758}," httpbin.org\u002Fget",[5676,14949,14950],{"class":5682},"  # HTTP-клієнт для тестування API\n",[5676,14952,14953],{"class":5678,"line":5712},[5676,14954,5690],{"emptyLinePlaceholder":5689},[5676,14956,14957],{"class":5678,"line":5755},[5676,14958,14959],{"class":5682},"# Встановлення інструментів глобально (available everywhere)\n",[5676,14961,14962,14964,14967,14969],{"class":5678,"line":5762},[5676,14963,13755],{"class":5719},[5676,14965,14966],{"class":5758}," tool",[5676,14968,13398],{"class":5758},[5676,14970,14971],{"class":5758}," ruff\n",[5676,14973,14974,14976,14978,14980],{"class":5678,"line":5772},[5676,14975,13755],{"class":5719},[5676,14977,14966],{"class":5758},[5676,14979,13398],{"class":5758},[5676,14981,14982],{"class":5758}," black\n",[5676,14984,14985,14987,14989,14991],{"class":5678,"line":5777},[5676,14986,13755],{"class":5719},[5676,14988,14966],{"class":5758},[5676,14990,11280],{"class":5758},[5676,14992,14993],{"class":5682},"               # список встановлених інструментів\n",[12399,14995,14996,14998,14999,12179,15002,5572],{},[5511,14997,14889],{}," особливо зручний у CI\u002FCD та скриптах, де не хочеться «забруднювати» залежності проекту інструментами розробки. ",[5511,15000,15001],{},"uvx ruff check .",[5511,15003,15004],{},"pip install ruff && ruff check .",[6400,15006,15008,15010,15011,15013],{"id":15007},"uv-як-замінник-pip-у-існуючих-проектах",[5511,15009,13755],{}," як замінник ",[5511,15012,8268],{}," у існуючих проектах",[5507,15015,15016,15017,5737,15019,15021,15022,6410],{},"Якщо у вас вже є проект з ",[5511,15018,13586],{},[5511,15020,13755],{}," можна підключити без переходу на ",[5511,15023,13745],{},[5667,15025,15027],{"className":13161,"code":15026,"language":13163,"meta":5672,"style":5672},"# uv як прямий замінник pip (набагато швидший)\nuv pip install requests\nuv pip install -r requirements.txt\nuv pip freeze > requirements.txt\n\n# Створення venv через uv\nuv venv .venv\nsource .venv\u002Fbin\u002Factivate\n\n# Компіляція requirements (аналог pip-tools)\nuv pip compile requirements.in -o requirements.txt\n",[5511,15028,15029,15034,15044,15056,15068,15072,15077,15085,15091,15095,15100],{"__ignoreMap":5672},[5676,15030,15031],{"class":5678,"line":5679},[5676,15032,15033],{"class":5682},"# uv як прямий замінник pip (набагато швидший)\n",[5676,15035,15036,15038,15040,15042],{"class":5678,"line":5686},[5676,15037,13755],{"class":5719},[5676,15039,13303],{"class":5758},[5676,15041,13398],{"class":5758},[5676,15043,13481],{"class":5758},[5676,15045,15046,15048,15050,15052,15054],{"class":5678,"line":5693},[5676,15047,13755],{"class":5719},[5676,15049,13303],{"class":5758},[5676,15051,13398],{"class":5758},[5676,15053,13729],{"class":5715},[5676,15055,13635],{"class":5758},[5676,15057,15058,15060,15062,15064,15066],{"class":5678,"line":5707},[5676,15059,13755],{"class":5719},[5676,15061,13303],{"class":5758},[5676,15063,13617],{"class":5758},[5676,15065,13620],{"class":5696},[5676,15067,13623],{"class":5758},[5676,15069,15070],{"class":5678,"line":5712},[5676,15071,5690],{"emptyLinePlaceholder":5689},[5676,15073,15074],{"class":5678,"line":5755},[5676,15075,15076],{"class":5682},"# Створення venv через uv\n",[5676,15078,15079,15081,15083],{"class":5678,"line":5762},[5676,15080,13755],{"class":5719},[5676,15082,13189],{"class":5758},[5676,15084,13710],{"class":5758},[5676,15086,15087,15089],{"class":5678,"line":5772},[5676,15088,13146],{"class":5719},[5676,15090,13267],{"class":5758},[5676,15092,15093],{"class":5678,"line":5777},[5676,15094,5690],{"emptyLinePlaceholder":5689},[5676,15096,15097],{"class":5678,"line":5807},[5676,15098,15099],{"class":5682},"# Компіляція requirements (аналог pip-tools)\n",[5676,15101,15102,15104,15106,15109,15112,15115],{"class":5678,"line":5813},[5676,15103,13755],{"class":5719},[5676,15105,13303],{"class":5758},[5676,15107,15108],{"class":5758}," compile",[5676,15110,15111],{"class":5758}," requirements.in",[5676,15113,15114],{"class":5715}," -o",[5676,15116,13635],{"class":5758},[6145,15118,15120,15129,15133,15140,15143,15152,15156,15164],{"title":15119},"Порівняння швидкості: pip vs uv",[6149,15121,15123,6157,15126],{"className":15122},[5678],[5676,15124,6156],{"className":15125},[6155],[5519,15127,15128],{},"time pip install django djangorestframework psycopg2-binary",[6149,15130,15132],{"className":15131},[5678],"Successfully installed django-5.1.4 djangorestframework-3.15.2 ...",[6149,15134,15136],{"className":15135},[5678],[5676,15137,15139],{"className":15138},[8861],"real  0m28.3s",[6149,15141],{"className":15142},[5678],[6149,15144,15146,6157,15149],{"className":15145},[5678],[5676,15147,6156],{"className":15148},[6155],[5519,15150,15151],{},"time uv pip install django djangorestframework psycopg2-binary",[6149,15153,15155],{"className":15154},[5678],"Resolved 8 packages in 143ms",[6149,15157,15159,15160],{"className":15158},[5678],"Installed 8 packages in ",[5676,15161,15163],{"className":15162},[6167],"614ms",[6149,15165,15167,7839,15171],{"className":15166},[5678],[5676,15168,15170],{"className":15169},[6167],"real  0m0.8s",[5676,15172,15174],{"className":15173},[6155],"← у 35 разів швидше!",[6400,15176,15178,15179],{"id":15177},"довідник-команд-uv","Довідник команд ",[5511,15180,13755],{},[7903,15182,15183,15236,15318,15369,15439,15505,15588,15683],{},[7906,15184,15186,15195],{"name":14143,"type":15185},"Ініціалізація проекту",[5507,15187,15188,15189,5737,15191,6594,15193,5572],{},"Створює новий проект у поточній директорії або у вказаній папці. Генерує ",[5511,15190,13745],{},[5511,15192,14128],{},[5511,15194,14113],{},[5667,15196,15198],{"className":13161,"code":15197,"language":13163,"meta":5672,"style":5672},"uv init                        # у поточній папці\nuv init my-project             # у новій папці my-project\u002F\nuv init --python 3.11 api      # з фіксованою версією Python\n",[5511,15199,15200,15209,15220],{"__ignoreMap":5672},[5676,15201,15202,15204,15206],{"class":5678,"line":5679},[5676,15203,13755],{"class":5719},[5676,15205,14034],{"class":5758},[5676,15207,15208],{"class":5682},"                        # у поточній папці\n",[5676,15210,15211,15213,15215,15217],{"class":5678,"line":5686},[5676,15212,13755],{"class":5719},[5676,15214,14034],{"class":5758},[5676,15216,14061],{"class":5758},[5676,15218,15219],{"class":5682},"             # у новій папці my-project\u002F\n",[5676,15221,15222,15224,15226,15228,15230,15233],{"class":5678,"line":5693},[5676,15223,13755],{"class":5719},[5676,15225,14034],{"class":5758},[5676,15227,14829],{"class":5715},[5676,15229,14764],{"class":5700},[5676,15231,15232],{"class":5758}," api",[5676,15234,15235],{"class":5682},"      # з фіксованою версією Python\n",[7906,15237,15239,15247],{"name":15238,"type":14223},"uv add \u002F uv remove",[5507,15240,15241,15242,6594,15244,15246],{},"Додає або видаляє залежності. Автоматично оновлює ",[5511,15243,13745],{},[5511,15245,13897],{},". Підтримує версійні обмеження, extras та групи.",[5667,15248,15250],{"className":13161,"code":15249,"language":13163,"meta":5672,"style":5672},"uv add fastapi                       # остання версія\nuv add \"sqlalchemy>=2.0,\u003C3\"         # з обмеженнями версій\nuv add uvicorn[standard]             # з extras\nuv add --dev pytest ruff mypy        # dev-залежності\nuv remove redis                      # видалення\n",[5511,15251,15252,15264,15276,15288,15306],{"__ignoreMap":5672},[5676,15253,15254,15256,15258,15261],{"class":5678,"line":5679},[5676,15255,13755],{"class":5719},[5676,15257,5720],{"class":5758},[5676,15259,15260],{"class":5758}," fastapi",[5676,15262,15263],{"class":5682},"                       # остання версія\n",[5676,15265,15266,15268,15270,15273],{"class":5678,"line":5686},[5676,15267,13755],{"class":5719},[5676,15269,5720],{"class":5758},[5676,15271,15272],{"class":5758}," \"sqlalchemy>=2.0,\u003C3\"",[5676,15274,15275],{"class":5682},"         # з обмеженнями версій\n",[5676,15277,15278,15280,15282,15285],{"class":5678,"line":5693},[5676,15279,13755],{"class":5719},[5676,15281,5720],{"class":5758},[5676,15283,15284],{"class":5758}," uvicorn[standard]",[5676,15286,15287],{"class":5682},"             # з extras\n",[5676,15289,15290,15292,15294,15296,15298,15300,15303],{"class":5678,"line":5707},[5676,15291,13755],{"class":5719},[5676,15293,5720],{"class":5758},[5676,15295,14302],{"class":5715},[5676,15297,14305],{"class":5758},[5676,15299,14311],{"class":5758},[5676,15301,15302],{"class":5758}," mypy",[5676,15304,15305],{"class":5682},"        # dev-залежності\n",[5676,15307,15308,15310,15312,15315],{"class":5678,"line":5712},[5676,15309,13755],{"class":5719},[5676,15311,14344],{"class":5758},[5676,15313,15314],{"class":5758}," redis",[5676,15316,15317],{"class":5682},"                      # видалення\n",[7906,15319,15321,15331],{"name":13901,"type":15320},"Синхронізація середовища",[5507,15322,15323,15324,15326,15327,15330],{},"Встановлює\u002Fоновлює пакети у середовищі відповідно до ",[5511,15325,13897],{},". Аналог ",[5511,15328,15329],{},"pip install -r requirements.txt",", але точний і детермінований.",[5667,15332,15334],{"className":13161,"code":15333,"language":13163,"meta":5672,"style":5672},"uv sync                  # встановити всі залежності\nuv sync --no-dev         # тільки production (без dev-групи)\nuv sync --frozen         # не оновлювати lockfile, лише встановити\n",[5511,15335,15336,15345,15357],{"__ignoreMap":5672},[5676,15337,15338,15340,15342],{"class":5678,"line":5679},[5676,15339,13755],{"class":5719},[5676,15341,14378],{"class":5758},[5676,15343,15344],{"class":5682},"                  # встановити всі залежності\n",[5676,15346,15347,15349,15351,15354],{"class":5678,"line":5686},[5676,15348,13755],{"class":5719},[5676,15350,14378],{"class":5758},[5676,15352,15353],{"class":5715}," --no-dev",[5676,15355,15356],{"class":5682},"         # тільки production (без dev-групи)\n",[5676,15358,15359,15361,15363,15366],{"class":5678,"line":5693},[5676,15360,13755],{"class":5719},[5676,15362,14378],{"class":5758},[5676,15364,15365],{"class":5715}," --frozen",[5676,15367,15368],{"class":5682},"         # не оновлювати lockfile, лише встановити\n",[7906,15370,15372,15375],{"name":14588,"type":15371},"Запуск команд у середовищі",[5507,15373,15374],{},"Виконує скрипт або команду у середовищі проекту без ручної активації venv. Перед запуском автоматично синхронізує середовище.",[5667,15376,15378],{"className":13161,"code":15377,"language":13163,"meta":5672,"style":5672},"uv run python main.py              # запуск скрипта\nuv run uvicorn app:app --reload    # запуск застосунку\nuv run pytest                      # тести\nuv run --with httpx python -c \"import httpx; print(httpx.__version__)\"\n",[5511,15379,15380,15394,15411,15422],{"__ignoreMap":5672},[5676,15381,15382,15384,15386,15388,15391],{"class":5678,"line":5679},[5676,15383,13755],{"class":5719},[5676,15385,14606],{"class":5758},[5676,15387,13293],{"class":5758},[5676,15389,15390],{"class":5758}," main.py",[5676,15392,15393],{"class":5682},"              # запуск скрипта\n",[5676,15395,15396,15398,15400,15402,15405,15408],{"class":5678,"line":5686},[5676,15397,13755],{"class":5719},[5676,15399,14606],{"class":5758},[5676,15401,14629],{"class":5758},[5676,15403,15404],{"class":5758}," app:app",[5676,15406,15407],{"class":5715}," --reload",[5676,15409,15410],{"class":5682},"    # запуск застосунку\n",[5676,15412,15413,15415,15417,15419],{"class":5678,"line":5693},[5676,15414,13755],{"class":5719},[5676,15416,14606],{"class":5758},[5676,15418,14305],{"class":5758},[5676,15420,15421],{"class":5682},"                      # тести\n",[5676,15423,15424,15426,15428,15430,15432,15434,15436],{"class":5678,"line":5707},[5676,15425,13755],{"class":5719},[5676,15427,14606],{"class":5758},[5676,15429,14699],{"class":5715},[5676,15431,14278],{"class":5758},[5676,15433,13293],{"class":5758},[5676,15435,13973],{"class":5715},[5676,15437,15438],{"class":5758}," \"import httpx; print(httpx.__version__)\"\n",[7906,15440,15442,15448],{"name":15441,"type":14724},"uv python",[5507,15443,15444,15445,15447],{},"Встановлює, перелічує та прив'язує версії Python до проекту. Замінює ",[5511,15446,13856],{}," для більшості сценаріїв.",[5667,15449,15451],{"className":13161,"code":15450,"language":13163,"meta":5672,"style":5672},"uv python install 3.12          # завантажити та встановити\nuv python install 3.11 3.13     # кілька версій одразу\nuv python list                  # переглянути всі доступні\nuv python pin 3.12              # зафіксувати у .python-version\n",[5511,15452,15453,15466,15481,15492],{"__ignoreMap":5672},[5676,15454,15455,15457,15459,15461,15463],{"class":5678,"line":5679},[5676,15456,13755],{"class":5719},[5676,15458,13293],{"class":5758},[5676,15460,13398],{"class":5758},[5676,15462,14808],{"class":5700},[5676,15464,15465],{"class":5682},"          # завантажити та встановити\n",[5676,15467,15468,15470,15472,15474,15476,15478],{"class":5678,"line":5686},[5676,15469,13755],{"class":5719},[5676,15471,13293],{"class":5758},[5676,15473,13398],{"class":5758},[5676,15475,14764],{"class":5700},[5676,15477,14767],{"class":5700},[5676,15479,15480],{"class":5682},"     # кілька версій одразу\n",[5676,15482,15483,15485,15487,15489],{"class":5678,"line":5693},[5676,15484,13755],{"class":5719},[5676,15486,13293],{"class":5758},[5676,15488,11280],{"class":5758},[5676,15490,15491],{"class":5682},"                  # переглянути всі доступні\n",[5676,15493,15494,15496,15498,15500,15502],{"class":5678,"line":5707},[5676,15495,13755],{"class":5719},[5676,15497,13293],{"class":5758},[5676,15499,14805],{"class":5758},[5676,15501,14808],{"class":5700},[5676,15503,15504],{"class":5682},"              # зафіксувати у .python-version\n",[7906,15506,15509,15517],{"name":15507,"type":15508},"uv pip","pip-сумісний режим",[5507,15510,15511,15512,15514,15515,5572],{},"Підмножина команд ",[5511,15513,8268],{}," з тим самим синтаксисом, але у рази швидша. Для інтеграції з існуючими проектами без переходу на ",[5511,15516,13745],{},[5667,15518,15520],{"className":13161,"code":15519,"language":13163,"meta":5672,"style":5672},"uv pip install requests             # встановлення пакета\nuv pip install -r requirements.txt  # з файлу\nuv pip freeze > requirements.txt    # збереження списку\nuv pip list                         # перелік встановлених\nuv venv .venv                       # створення середовища\n",[5511,15521,15522,15535,15551,15566,15577],{"__ignoreMap":5672},[5676,15523,15524,15526,15528,15530,15532],{"class":5678,"line":5679},[5676,15525,13755],{"class":5719},[5676,15527,13303],{"class":5758},[5676,15529,13398],{"class":5758},[5676,15531,13401],{"class":5758},[5676,15533,15534],{"class":5682},"             # встановлення пакета\n",[5676,15536,15537,15539,15541,15543,15545,15548],{"class":5678,"line":5686},[5676,15538,13755],{"class":5719},[5676,15540,13303],{"class":5758},[5676,15542,13398],{"class":5758},[5676,15544,13729],{"class":5715},[5676,15546,15547],{"class":5758}," requirements.txt",[5676,15549,15550],{"class":5682},"  # з файлу\n",[5676,15552,15553,15555,15557,15559,15561,15563],{"class":5678,"line":5693},[5676,15554,13755],{"class":5719},[5676,15556,13303],{"class":5758},[5676,15558,13617],{"class":5758},[5676,15560,13620],{"class":5696},[5676,15562,13586],{"class":5758},[5676,15564,15565],{"class":5682},"    # збереження списку\n",[5676,15567,15568,15570,15572,15574],{"class":5678,"line":5707},[5676,15569,13755],{"class":5719},[5676,15571,13303],{"class":5758},[5676,15573,11280],{"class":5758},[5676,15575,15576],{"class":5682},"                         # перелік встановлених\n",[5676,15578,15579,15581,15583,15585],{"class":5678,"line":5712},[5676,15580,13755],{"class":5719},[5676,15582,13189],{"class":5758},[5676,15584,13205],{"class":5758},[5676,15586,15587],{"class":5682},"                       # створення середовища\n",[7906,15589,15592,15601],{"name":15590,"type":15591},"uvx \u002F uv tool","Глобальні CLI-інструменти",[5507,15593,15594,15596,15597,15600],{},[5511,15595,14889],{}," запускає CLI-інструменти без встановлення у проект (у тимчасовому ізольованому середовищі). ",[5511,15598,15599],{},"uv tool install"," — встановлює глобально.",[5667,15602,15604],{"className":13161,"code":15603,"language":13163,"meta":5672,"style":5672},"uvx ruff check .               # запуск без встановлення\nuvx black myfile.py\nuvx --from httpie http GET httpbin.org\u002Fget\nuv tool install ruff            # встановити глобально\nuv tool list                    # список глобальних інструментів\nuv tool uninstall ruff          # видалити\n",[5511,15605,15606,15619,15628,15645,15658,15669],{"__ignoreMap":5672},[5676,15607,15608,15610,15612,15614,15616],{"class":5678,"line":5679},[5676,15609,14889],{"class":5719},[5676,15611,14311],{"class":5758},[5676,15613,14673],{"class":5758},[5676,15615,14919],{"class":5758},[5676,15617,15618],{"class":5682},"               # запуск без встановлення\n",[5676,15620,15621,15623,15625],{"class":5678,"line":5686},[5676,15622,14889],{"class":5719},[5676,15624,14325],{"class":5758},[5676,15626,15627],{"class":5758}," myfile.py\n",[5676,15629,15630,15632,15635,15637,15640,15642],{"class":5678,"line":5693},[5676,15631,14889],{"class":5719},[5676,15633,15634],{"class":5715}," --from",[5676,15636,14941],{"class":5758},[5676,15638,15639],{"class":5758}," http",[5676,15641,14944],{"class":5758},[5676,15643,15644],{"class":5758}," httpbin.org\u002Fget\n",[5676,15646,15647,15649,15651,15653,15655],{"class":5678,"line":5707},[5676,15648,13755],{"class":5719},[5676,15650,14966],{"class":5758},[5676,15652,13398],{"class":5758},[5676,15654,14311],{"class":5758},[5676,15656,15657],{"class":5682},"            # встановити глобально\n",[5676,15659,15660,15662,15664,15666],{"class":5678,"line":5712},[5676,15661,13755],{"class":5719},[5676,15663,14966],{"class":5758},[5676,15665,11280],{"class":5758},[5676,15667,15668],{"class":5682},"                    # список глобальних інструментів\n",[5676,15670,15671,15673,15675,15678,15680],{"class":5678,"line":5755},[5676,15672,13755],{"class":5719},[5676,15674,14966],{"class":5758},[5676,15676,15677],{"class":5758}," uninstall",[5676,15679,14311],{"class":5758},[5676,15681,15682],{"class":5682},"          # видалити\n",[7906,15684,15687,15698],{"name":15685,"type":15686},"uv lock \u002F uv export","Lockfile та сумісність",[5507,15688,15689,15690,15692,15693,15695,15696,5572],{},"Генерує або оновлює ",[5511,15691,13897],{},". Може експортувати залежності у формат ",[5511,15694,13586],{}," для інструментів, що не підтримують ",[5511,15697,13897],{},[5667,15699,15701],{"className":13161,"code":15700,"language":13163,"meta":5672,"style":5672},"uv lock                                          # оновити lockfile\nuv export -f requirements-txt > requirements.txt # експорт у pip-формат\nuv export --no-dev -f requirements-txt > req-prod.txt\n",[5511,15702,15703,15713,15733],{"__ignoreMap":5672},[5676,15704,15705,15707,15710],{"class":5678,"line":5679},[5676,15706,13755],{"class":5719},[5676,15708,15709],{"class":5758}," lock",[5676,15711,15712],{"class":5682},"                                          # оновити lockfile\n",[5676,15714,15715,15717,15720,15723,15726,15728,15730],{"class":5678,"line":5686},[5676,15716,13755],{"class":5719},[5676,15718,15719],{"class":5758}," export",[5676,15721,15722],{"class":5715}," -f",[5676,15724,15725],{"class":5758}," requirements-txt",[5676,15727,13620],{"class":5696},[5676,15729,13586],{"class":5758},[5676,15731,15732],{"class":5682}," # експорт у pip-формат\n",[5676,15734,15735,15737,15739,15741,15743,15745,15747],{"class":5678,"line":5693},[5676,15736,13755],{"class":5719},[5676,15738,15719],{"class":5758},[5676,15740,15353],{"class":5715},[5676,15742,15722],{"class":5715},[5676,15744,15725],{"class":5758},[5676,15746,13620],{"class":5696},[5676,15748,15749],{"class":5758},"req-prod.txt\n",[5574,15751],{},[5581,15753,15755,15757],{"id":15754},"poetry-зрілий-менеджер-для-складних-проектів",[5511,15756,13825],{}," — зрілий менеджер для складних проектів",[5507,15759,15760,15762,15763,15765,15766,15769,15770,15773],{},[5519,15761,13825],{}," — це інструмент, що вийшов у 2018 році і зараз широко використовується у виробничих проектах. Він вирішує ту саму проблему, що і ",[5511,15764,13755],{},", але з акцентом на управління ",[5519,15767,15768],{},"залежностями з групами"," і ",[5519,15771,15772],{},"публікацію пакетів"," на PyPI.",[5524,15775,15776,15788,15796,15804],{},[5527,15777,15780,15781,15784,15785,5572],{"icon":15778,"title":15779},"i-heroicons-cube","Автоматичне управління середовищем","Poetry автоматично створює та активує venv. Не потрібно ",[5511,15782,15783],{},"python -m venv .venv && source .venv\u002Fbin\u002Factivate"," — достатньо ",[5511,15786,15787],{},"poetry install",[5527,15789,15792,15793,15795],{"icon":15790,"title":15791},"i-heroicons-document-duplicate","poetry.lock — точне відтворення","Lockfile фіксує точні версії і хеші пакетів. ",[5511,15794,15787],{}," завжди відтворює ідентичне середовище на будь-якій машині або у CI.",[5527,15797,15800,15801,5572],{"icon":15798,"title":15799},"i-heroicons-tag","Групи залежностей","Окремі групи для dev, test, docs — залежності розробника не потрапляють у production-image при встановленні через ",[5511,15802,15803],{},"poetry install --without dev",[5527,15805,15808,15811,15812,5737,15815,15818,15819,5572],{"icon":15806,"title":15807},"i-heroicons-cloud-arrow-up","Публікація на PyPI",[5511,15809,15810],{},"poetry publish"," — єдина команда для збірки та публікації пакету. Замінює ",[5511,15813,15814],{},"setuptools",[5511,15816,15817],{},"twine"," і ручне редагування ",[5511,15820,13915],{},[6400,15822,15824],{"id":15823},"встановлення-poetry","Встановлення Poetry",[5667,15826,15828],{"className":13161,"code":15827,"language":13163,"meta":5672,"style":5672},"# Рекомендований спосіб (isolated installer)\ncurl -sSL https:\u002F\u002Finstall.python-poetry.org | python3 -\n\n# macOS через Homebrew\nbrew install poetry\n\n# Перевірка встановлення\npoetry --version  # Poetry (version 1.8.x)\n\n# Важливе налаштування: зберігати venv всередині проекту\n# (замість ~\u002F.cache\u002Fpypoetry\u002Fvirtualenvs\u002F)\npoetry config virtualenvs.in-project true\n",[5511,15829,15830,15835,15853,15857,15862,15872,15876,15880,15889,15893,15898,15903],{"__ignoreMap":5672},[5676,15831,15832],{"class":5678,"line":5679},[5676,15833,15834],{"class":5682},"# Рекомендований спосіб (isolated installer)\n",[5676,15836,15837,15839,15842,15845,15847,15850],{"class":5678,"line":5686},[5676,15838,13939],{"class":5719},[5676,15840,15841],{"class":5715}," -sSL",[5676,15843,15844],{"class":5758}," https:\u002F\u002Finstall.python-poetry.org",[5676,15846,11310],{"class":5696},[5676,15848,15849],{"class":5719},"python3",[5676,15851,15852],{"class":5758}," -\n",[5676,15854,15855],{"class":5678,"line":5693},[5676,15856,5690],{"emptyLinePlaceholder":5689},[5676,15858,15859],{"class":5678,"line":5707},[5676,15860,15861],{"class":5682},"# macOS через Homebrew\n",[5676,15863,15864,15867,15869],{"class":5678,"line":5712},[5676,15865,15866],{"class":5719},"brew",[5676,15868,13398],{"class":5758},[5676,15870,15871],{"class":5758}," poetry\n",[5676,15873,15874],{"class":5678,"line":5755},[5676,15875,5690],{"emptyLinePlaceholder":5689},[5676,15877,15878],{"class":5678,"line":5762},[5676,15879,14003],{"class":5682},[5676,15881,15882,15884,15886],{"class":5678,"line":5772},[5676,15883,13752],{"class":5719},[5676,15885,14010],{"class":5715},[5676,15887,15888],{"class":5682},"  # Poetry (version 1.8.x)\n",[5676,15890,15891],{"class":5678,"line":5777},[5676,15892,5690],{"emptyLinePlaceholder":5689},[5676,15894,15895],{"class":5678,"line":5807},[5676,15896,15897],{"class":5682},"# Важливе налаштування: зберігати venv всередині проекту\n",[5676,15899,15900],{"class":5678,"line":5813},[5676,15901,15902],{"class":5682},"# (замість ~\u002F.cache\u002Fpypoetry\u002Fvirtualenvs\u002F)\n",[5676,15904,15905,15907,15910,15913],{"class":5678,"line":5821},[5676,15906,13752],{"class":5719},[5676,15908,15909],{"class":5758}," config",[5676,15911,15912],{"class":5758}," virtualenvs.in-project",[5676,15914,15915],{"class":5715}," true\n",[12399,15917,15918,15921,15922,15925],{},[5511,15919,15920],{},"poetry config virtualenvs.in-project true"," — рекомендоване налаштування для більшості розробників. Середовище буде у ",[5511,15923,15924],{},".venv\u002F"," всередині вашого проекту, що зручно для IDE та Docker.",[6400,15927,15929],{"id":15928},"створення-нового-проекту","Створення нового проекту",[5667,15931,15933],{"className":13161,"code":15932,"language":13163,"meta":5672,"style":5672},"# Новий проект з повною структурою\npoetry new my-service\n\n# Або ініціалізація інтерактивно у поточній папці\nmkdir existing-project && cd existing-project\npoetry init\n",[5511,15934,15935,15940,15950,15954,15959,15973],{"__ignoreMap":5672},[5676,15936,15937],{"class":5678,"line":5679},[5676,15938,15939],{"class":5682},"# Новий проект з повною структурою\n",[5676,15941,15942,15944,15947],{"class":5678,"line":5686},[5676,15943,13752],{"class":5719},[5676,15945,15946],{"class":5758}," new",[5676,15948,15949],{"class":5758}," my-service\n",[5676,15951,15952],{"class":5678,"line":5693},[5676,15953,5690],{"emptyLinePlaceholder":5689},[5676,15955,15956],{"class":5678,"line":5707},[5676,15957,15958],{"class":5682},"# Або ініціалізація інтерактивно у поточній папці\n",[5676,15960,15961,15963,15966,15968,15970],{"class":5678,"line":5712},[5676,15962,14058],{"class":5719},[5676,15964,15965],{"class":5758}," existing-project",[5676,15967,14064],{"class":5696},[5676,15969,14042],{"class":5719},[5676,15971,15972],{"class":5758}," existing-project\n",[5676,15974,15975,15977],{"class":5678,"line":5755},[5676,15976,13752],{"class":5719},[5676,15978,14076],{"class":5758},[6145,15980,15982,15991,16000,16009,16013,16021,16028,16035,16041,16048],{"title":15981},"poetry new — структура нового проекту",[6149,15983,15985,6157,15988],{"className":15984},[5678],[5676,15986,6156],{"className":15987},[6155],[5519,15989,15990],{},"poetry new my-service",[6149,15992,15994,15995,15999],{"className":15993},[5678],"Created package ",[5676,15996,15998],{"className":15997},[6167],"my-service"," at `my-service`",[6149,16001,16003,6157,16006],{"className":16002},[5678],[5676,16004,6156],{"className":16005},[6155],[5519,16007,16008],{},"tree my-service\u002F",[6149,16010,16012],{"className":16011},[5678],"my-service\u002F",[6149,16014,14109,16016,16020],{"className":16015},[5678],[5676,16017,16019],{"className":16018},[6184],"my_service\u002F","         ← пакет Python",[6149,16022,16024,16025],{"className":16023},[5678],"│   └── ",[5676,16026,10921],{"className":16027},[6184],[6149,16029,14109,16031],{"className":16030},[5678],[5676,16032,16034],{"className":16033},[6184],"tests\u002F",[6149,16036,16024,16038],{"className":16037},[5678],[5676,16039,10921],{"className":16040},[6184],[6149,16042,14109,16044,16047],{"className":16043},[5678],[5676,16045,13745],{"className":16046},[7829],"      ← вся конфігурація тут",[6149,16049,14132,16051],{"className":16050},[5678],[5676,16052,14128],{"className":16053},[6167],[6400,16055,16057,16059],{"id":16056},"pyprojecttoml-у-poetry",[5511,16058,13745],{}," у Poetry",[5507,16061,16062,16063,16065,16066,6410],{},"Poetry використовує ",[5511,16064,13745],{}," — але зі своїми секціями ",[5511,16067,16068],{},"[tool.poetry.*]",[5667,16070,16072],{"className":14149,"code":16071,"language":14151,"meta":5672,"style":5672},"[tool.poetry]\nname = \"my-service\"\nversion = \"0.1.0\"\ndescription = \"Production-ready REST API\"\nauthors = [\"Developer \u003Cdev@example.com>\"]\nreadme = \"README.md\"\npackages = [{include = \"my_service\"}]\n\n[tool.poetry.dependencies]\npython = \"^3.12\"           # версія Python — обов'язкова\nfastapi = \">=0.115.0\"      # прямі залежності проекту\nsqlalchemy = \"^2.0\"\npydantic = \"^2.5\"\nuvicorn = {extras = [\"standard\"], version = \"^0.32\"}\n\n[tool.poetry.group.dev.dependencies]  # група dev — не у production\npytest = \"^8.0\"\npytest-asyncio = \"^0.24\"\nruff = \"^0.8\"\nmypy = \"^1.13\"\nblack = \"^24.0\"\n\n[tool.poetry.group.test.dependencies]  # окрема група для тестів\nhttpx = \"^0.28\"            # HTTP-клієнт для тестування FastAPI\nfactory-boy = \"^3.3\"\n\n[build-system]\nrequires = [\"poetry-core\"]\nbuild-backend = \"poetry.core.masonry.api\"\n",[5511,16073,16074,16079,16088,16096,16105,16117,16125,16144,16148,16153,16165,16178,16188,16198,16226,16230,16238,16248,16258,16267,16277,16287,16291,16299,16312,16322,16326,16331,16343],{"__ignoreMap":5672},[5676,16075,16076],{"class":5678,"line":5679},[5676,16077,16078],{"class":5696},"[tool.poetry]\n",[5676,16080,16081,16083,16085],{"class":5678,"line":5686},[5676,16082,11607],{"class":5726},[5676,16084,10984],{"class":5696},[5676,16086,16087],{"class":5758},"\"my-service\"\n",[5676,16089,16090,16092,16094],{"class":5678,"line":5693},[5676,16091,13013],{"class":5726},[5676,16093,10984],{"class":5696},[5676,16095,14181],{"class":5758},[5676,16097,16098,16100,16102],{"class":5678,"line":5707},[5676,16099,14186],{"class":5726},[5676,16101,10984],{"class":5696},[5676,16103,16104],{"class":5758},"\"Production-ready REST API\"\n",[5676,16106,16107,16110,16112,16115],{"class":5678,"line":5712},[5676,16108,16109],{"class":5726},"authors",[5676,16111,11003],{"class":5696},[5676,16113,16114],{"class":5758},"\"Developer \u003Cdev@example.com>\"",[5676,16116,8460],{"class":5696},[5676,16118,16119,16121,16123],{"class":5678,"line":5755},[5676,16120,14196],{"class":5726},[5676,16122,10984],{"class":5696},[5676,16124,14201],{"class":5758},[5676,16126,16127,16130,16133,16136,16138,16141],{"class":5678,"line":5762},[5676,16128,16129],{"class":5726},"packages",[5676,16131,16132],{"class":5696}," = [{",[5676,16134,16135],{"class":5726},"include",[5676,16137,10984],{"class":5696},[5676,16139,16140],{"class":5758},"\"my_service\"",[5676,16142,16143],{"class":5696},"}]\n",[5676,16145,16146],{"class":5678,"line":5772},[5676,16147,5690],{"emptyLinePlaceholder":5689},[5676,16149,16150],{"class":5678,"line":5777},[5676,16151,16152],{"class":5696},"[tool.poetry.dependencies]\n",[5676,16154,16155,16157,16159,16162],{"class":5678,"line":5807},[5676,16156,5671],{"class":5726},[5676,16158,10984],{"class":5696},[5676,16160,16161],{"class":5758},"\"^3.12\"",[5676,16163,16164],{"class":5682},"           # версія Python — обов'язкова\n",[5676,16166,16167,16170,16172,16175],{"class":5678,"line":5813},[5676,16168,16169],{"class":5726},"fastapi",[5676,16171,10984],{"class":5696},[5676,16173,16174],{"class":5758},"\">=0.115.0\"",[5676,16176,16177],{"class":5682},"      # прямі залежності проекту\n",[5676,16179,16180,16183,16185],{"class":5678,"line":5821},[5676,16181,16182],{"class":5726},"sqlalchemy",[5676,16184,10984],{"class":5696},[5676,16186,16187],{"class":5758},"\"^2.0\"\n",[5676,16189,16190,16193,16195],{"class":5678,"line":5826},[5676,16191,16192],{"class":5726},"pydantic",[5676,16194,10984],{"class":5696},[5676,16196,16197],{"class":5758},"\"^2.5\"\n",[5676,16199,16200,16203,16206,16209,16211,16214,16217,16219,16221,16224],{"class":5678,"line":5856},[5676,16201,16202],{"class":5726},"uvicorn",[5676,16204,16205],{"class":5696}," = {",[5676,16207,16208],{"class":5726},"extras",[5676,16210,11003],{"class":5696},[5676,16212,16213],{"class":5758},"\"standard\"",[5676,16215,16216],{"class":5696},"], ",[5676,16218,13013],{"class":5726},[5676,16220,10984],{"class":5696},[5676,16222,16223],{"class":5758},"\"^0.32\"",[5676,16225,6544],{"class":5696},[5676,16227,16228],{"class":5678,"line":5862},[5676,16229,5690],{"emptyLinePlaceholder":5689},[5676,16231,16232,16235],{"class":5678,"line":5870},[5676,16233,16234],{"class":5696},"[tool.poetry.group.dev.dependencies]  ",[5676,16236,16237],{"class":5682},"# група dev — не у production\n",[5676,16239,16240,16243,16245],{"class":5678,"line":5875},[5676,16241,16242],{"class":5726},"pytest",[5676,16244,10984],{"class":5696},[5676,16246,16247],{"class":5758},"\"^8.0\"\n",[5676,16249,16250,16253,16255],{"class":5678,"line":5898},[5676,16251,16252],{"class":5726},"pytest-asyncio",[5676,16254,10984],{"class":5696},[5676,16256,16257],{"class":5758},"\"^0.24\"\n",[5676,16259,16260,16262,16264],{"class":5678,"line":5904},[5676,16261,13844],{"class":5726},[5676,16263,10984],{"class":5696},[5676,16265,16266],{"class":5758},"\"^0.8\"\n",[5676,16268,16269,16272,16274],{"class":5678,"line":5915},[5676,16270,16271],{"class":5726},"mypy",[5676,16273,10984],{"class":5696},[5676,16275,16276],{"class":5758},"\"^1.13\"\n",[5676,16278,16279,16282,16284],{"class":5678,"line":5920},[5676,16280,16281],{"class":5726},"black",[5676,16283,10984],{"class":5696},[5676,16285,16286],{"class":5758},"\"^24.0\"\n",[5676,16288,16289],{"class":5678,"line":5941},[5676,16290,5690],{"emptyLinePlaceholder":5689},[5676,16292,16293,16296],{"class":5678,"line":5947},[5676,16294,16295],{"class":5696},"[tool.poetry.group.test.dependencies]  ",[5676,16297,16298],{"class":5682},"# окрема група для тестів\n",[5676,16300,16301,16304,16306,16309],{"class":5678,"line":5953},[5676,16302,16303],{"class":5726},"httpx",[5676,16305,10984],{"class":5696},[5676,16307,16308],{"class":5758},"\"^0.28\"",[5676,16310,16311],{"class":5682},"            # HTTP-клієнт для тестування FastAPI\n",[5676,16313,16314,16317,16319],{"class":5678,"line":5959},[5676,16315,16316],{"class":5726},"factory-boy",[5676,16318,10984],{"class":5696},[5676,16320,16321],{"class":5758},"\"^3.3\"\n",[5676,16323,16324],{"class":5678,"line":5964},[5676,16325,5690],{"emptyLinePlaceholder":5689},[5676,16327,16328],{"class":5678,"line":7576},[5676,16329,16330],{"class":5696},"[build-system]\n",[5676,16332,16333,16336,16338,16341],{"class":5678,"line":7581},[5676,16334,16335],{"class":5726},"requires",[5676,16337,11003],{"class":5696},[5676,16339,16340],{"class":5758},"\"poetry-core\"",[5676,16342,8460],{"class":5696},[5676,16344,16345,16348,16350],{"class":5678,"line":7587},[5676,16346,16347],{"class":5726},"build-backend",[5676,16349,10984],{"class":5696},[5676,16351,16352],{"class":5758},"\"poetry.core.masonry.api\"\n",[6400,16354,14223],{"id":16355},"управління-залежностями-1",[5667,16357,16359],{"className":13161,"code":16358,"language":13163,"meta":5672,"style":5672},"# Встановлення залежностей з pyproject.toml (також синхронізує lock)\npoetry install\n\n# Встановлення без dev-залежностей (для production)\npoetry install --without dev\n\n# Додавання нової залежності (оновлює pyproject.toml і lock автоматично)\npoetry add fastapi\npoetry add \"sqlalchemy>=2.0,\u003C3.0\"\npoetry add uvicorn[standard]          # з extras\n\n# Додавання dev-залежності\npoetry add --group dev pytest\npoetry add --group dev ruff black mypy\n\n# Видалення залежності\npoetry remove redis\n\n# Оновлення всіх залежностей (в межах версійних обмежень)\npoetry update\n\n# Оновлення конкретного пакету\npoetry update fastapi\n",[5511,16360,16361,16366,16373,16377,16382,16394,16398,16403,16411,16420,16431,16435,16440,16454,16470,16474,16478,16486,16490,16495,16502,16506,16511],{"__ignoreMap":5672},[5676,16362,16363],{"class":5678,"line":5679},[5676,16364,16365],{"class":5682},"# Встановлення залежностей з pyproject.toml (також синхронізує lock)\n",[5676,16367,16368,16370],{"class":5678,"line":5686},[5676,16369,13752],{"class":5719},[5676,16371,16372],{"class":5758}," install\n",[5676,16374,16375],{"class":5678,"line":5693},[5676,16376,5690],{"emptyLinePlaceholder":5689},[5676,16378,16379],{"class":5678,"line":5707},[5676,16380,16381],{"class":5682},"# Встановлення без dev-залежностей (для production)\n",[5676,16383,16384,16386,16388,16391],{"class":5678,"line":5712},[5676,16385,13752],{"class":5719},[5676,16387,13398],{"class":5758},[5676,16389,16390],{"class":5715}," --without",[5676,16392,16393],{"class":5758}," dev\n",[5676,16395,16396],{"class":5678,"line":5755},[5676,16397,5690],{"emptyLinePlaceholder":5689},[5676,16399,16400],{"class":5678,"line":5762},[5676,16401,16402],{"class":5682},"# Додавання нової залежності (оновлює pyproject.toml і lock автоматично)\n",[5676,16404,16405,16407,16409],{"class":5678,"line":5772},[5676,16406,13752],{"class":5719},[5676,16408,5720],{"class":5758},[5676,16410,14242],{"class":5758},[5676,16412,16413,16415,16417],{"class":5678,"line":5777},[5676,16414,13752],{"class":5719},[5676,16416,5720],{"class":5758},[5676,16418,16419],{"class":5758}," \"sqlalchemy>=2.0,\u003C3.0\"\n",[5676,16421,16422,16424,16426,16428],{"class":5678,"line":5807},[5676,16423,13752],{"class":5719},[5676,16425,5720],{"class":5758},[5676,16427,15284],{"class":5758},[5676,16429,16430],{"class":5682},"          # з extras\n",[5676,16432,16433],{"class":5678,"line":5813},[5676,16434,5690],{"emptyLinePlaceholder":5689},[5676,16436,16437],{"class":5678,"line":5821},[5676,16438,16439],{"class":5682},"# Додавання dev-залежності\n",[5676,16441,16442,16444,16446,16449,16452],{"class":5678,"line":5826},[5676,16443,13752],{"class":5719},[5676,16445,5720],{"class":5758},[5676,16447,16448],{"class":5715}," --group",[5676,16450,16451],{"class":5758}," dev",[5676,16453,14653],{"class":5758},[5676,16455,16456,16458,16460,16462,16464,16466,16468],{"class":5678,"line":5856},[5676,16457,13752],{"class":5719},[5676,16459,5720],{"class":5758},[5676,16461,16448],{"class":5715},[5676,16463,16451],{"class":5758},[5676,16465,14311],{"class":5758},[5676,16467,14325],{"class":5758},[5676,16469,14314],{"class":5758},[5676,16471,16472],{"class":5678,"line":5862},[5676,16473,5690],{"emptyLinePlaceholder":5689},[5676,16475,16476],{"class":5678,"line":5870},[5676,16477,14337],{"class":5682},[5676,16479,16480,16482,16484],{"class":5678,"line":5875},[5676,16481,13752],{"class":5719},[5676,16483,14344],{"class":5758},[5676,16485,14284],{"class":5758},[5676,16487,16488],{"class":5678,"line":5898},[5676,16489,5690],{"emptyLinePlaceholder":5689},[5676,16491,16492],{"class":5678,"line":5904},[5676,16493,16494],{"class":5682},"# Оновлення всіх залежностей (в межах версійних обмежень)\n",[5676,16496,16497,16499],{"class":5678,"line":5915},[5676,16498,13752],{"class":5719},[5676,16500,16501],{"class":5758}," update\n",[5676,16503,16504],{"class":5678,"line":5920},[5676,16505,5690],{"emptyLinePlaceholder":5689},[5676,16507,16508],{"class":5678,"line":5941},[5676,16509,16510],{"class":5682},"# Оновлення конкретного пакету\n",[5676,16512,16513,16515,16518],{"class":5678,"line":5947},[5676,16514,13752],{"class":5719},[5676,16516,16517],{"class":5758}," update",[5676,16519,14242],{"class":5758},[6145,16521,16523,16531,16535,16538,16555,16559,16563,16571,16575,16579,16586,16594,16601,16604],{"title":16522},"poetry install — встановлення та вирішення залежностей",[6149,16524,16526,6157,16529],{"className":16525},[5678],[5676,16527,6156],{"className":16528},[6155],[5519,16530,15787],{},[6149,16532,16534],{"className":16533},[5678],"Installing dependencies from lock file",[6149,16536],{"className":16537},[5678],[6149,16539,16541,16542,16546,16547,16550,16551,16554],{"className":16540},[5678],"Package operations: ",[5676,16543,16545],{"className":16544},[6184],"22"," installs, ",[5676,16548,8035],{"className":16549},[7829]," updates, ",[5676,16552,8035],{"className":16553},[8861]," removals",[6149,16556,16558],{"className":16557},[5678],"  • Installing annotated-types (0.7.0)",[6149,16560,16562],{"className":16561},[5678],"  • Installing anyio (4.7.0)",[6149,16564,16566,16567],{"className":16565},[5678],"  • ",[5676,16568,16570],{"className":16569},[6167],"Installing fastapi (0.115.6)",[6149,16572,16574],{"className":16573},[5678],"  • Installing pydantic (2.10.3)",[6149,16576,16578],{"className":16577},[5678],"  • Installing starlette (0.41.3)",[6149,16580,16566,16582],{"className":16581},[5678],[5676,16583,16585],{"className":16584},[6167],"Installing uvicorn (0.32.1)",[6149,16587,16589,16590],{"className":16588},[5678],"  • Installing pytest (8.3.4) ",[5676,16591,16593],{"className":16592},[6155],"(dev)",[6149,16595,16597,16598],{"className":16596},[5678],"  • Installing ruff (0.8.4) ",[5676,16599,16593],{"className":16600},[6155],[6149,16602],{"className":16603},[5678],[6149,16605,16607,16608],{"className":16606},[5678],"Installing the current project: ",[5676,16609,16611],{"className":16610},[6167],"my-service (0.1.0)",[6400,16613,16615],{"id":16614},"запуск-коду-у-середовищі-poetry","Запуск коду у середовищі Poetry",[5507,16617,16618,16619,6410],{},"Poetry не вимагає ручної активації середовища — використовуйте ",[5511,16620,16621],{},"poetry run",[5667,16623,16625],{"className":13161,"code":16624,"language":13163,"meta":5672,"style":5672},"# Запуск скрипта у середовищі проекту\npoetry run python main.py\n\n# Запуск застосунку\npoetry run uvicorn my_service.main:app --reload\n\n# Запуск тестів\npoetry run pytest\n\n# Запуск лінтера\npoetry run ruff check .\npoetry run mypy my_service\u002F\n\n# Або активувати середовище вручну (як у venv)\npoetry shell   # відкриває нову оболонку з активованим середовищем\nexit           # повернутись\n",[5511,16626,16627,16632,16642,16646,16650,16663,16667,16671,16679,16683,16687,16699,16710,16714,16719,16729],{"__ignoreMap":5672},[5676,16628,16629],{"class":5678,"line":5679},[5676,16630,16631],{"class":5682},"# Запуск скрипта у середовищі проекту\n",[5676,16633,16634,16636,16638,16640],{"class":5678,"line":5686},[5676,16635,13752],{"class":5719},[5676,16637,14606],{"class":5758},[5676,16639,13293],{"class":5758},[5676,16641,14611],{"class":5758},[5676,16643,16644],{"class":5678,"line":5693},[5676,16645,5690],{"emptyLinePlaceholder":5689},[5676,16647,16648],{"class":5678,"line":5707},[5676,16649,14620],{"class":5682},[5676,16651,16652,16654,16656,16658,16661],{"class":5678,"line":5712},[5676,16653,13752],{"class":5719},[5676,16655,14606],{"class":5758},[5676,16657,14629],{"class":5758},[5676,16659,16660],{"class":5758}," my_service.main:app",[5676,16662,14635],{"class":5715},[5676,16664,16665],{"class":5678,"line":5755},[5676,16666,5690],{"emptyLinePlaceholder":5689},[5676,16668,16669],{"class":5678,"line":5762},[5676,16670,14644],{"class":5682},[5676,16672,16673,16675,16677],{"class":5678,"line":5772},[5676,16674,13752],{"class":5719},[5676,16676,14606],{"class":5758},[5676,16678,14653],{"class":5758},[5676,16680,16681],{"class":5678,"line":5777},[5676,16682,5690],{"emptyLinePlaceholder":5689},[5676,16684,16685],{"class":5678,"line":5807},[5676,16686,14662],{"class":5682},[5676,16688,16689,16691,16693,16695,16697],{"class":5678,"line":5813},[5676,16690,13752],{"class":5719},[5676,16692,14606],{"class":5758},[5676,16694,14311],{"class":5758},[5676,16696,14673],{"class":5758},[5676,16698,14676],{"class":5758},[5676,16700,16701,16703,16705,16707],{"class":5678,"line":5821},[5676,16702,13752],{"class":5719},[5676,16704,14606],{"class":5758},[5676,16706,15302],{"class":5758},[5676,16708,16709],{"class":5758}," my_service\u002F\n",[5676,16711,16712],{"class":5678,"line":5826},[5676,16713,5690],{"emptyLinePlaceholder":5689},[5676,16715,16716],{"class":5678,"line":5856},[5676,16717,16718],{"class":5682},"# Або активувати середовище вручну (як у venv)\n",[5676,16720,16721,16723,16726],{"class":5678,"line":5862},[5676,16722,13752],{"class":5719},[5676,16724,16725],{"class":5758}," shell",[5676,16727,16728],{"class":5682},"   # відкриває нову оболонку з активованим середовищем\n",[5676,16730,16731,16734],{"class":5678,"line":5870},[5676,16732,16733],{"class":5719},"exit",[5676,16735,16736],{"class":5682},"           # повернутись\n",[6400,16738,15178,16740],{"id":16739},"довідник-команд-poetry",[5511,16741,13752],{},[7903,16743,16744,16786,16875,16936,17009,17058,17114,17177,17227],{},[7906,16745,16747,16760],{"name":16746,"type":15185},"poetry new \u002F poetry init",[5507,16748,16749,16752,16753,16756,16757,16759],{},[5511,16750,16751],{},"poetry new"," створює проект з готовою структурою папок. ",[5511,16754,16755],{},"poetry init"," — інтерактивно додає ",[5511,16758,13745],{}," до існуючої директорії.",[5667,16761,16763],{"className":13161,"code":16762,"language":13163,"meta":5672,"style":5672},"poetry new my-service         # новий проект зі структурою\npoetry init                   # додати poetry до існуючого проекту\n",[5511,16764,16765,16777],{"__ignoreMap":5672},[5676,16766,16767,16769,16771,16774],{"class":5678,"line":5679},[5676,16768,13752],{"class":5719},[5676,16770,15946],{"class":5758},[5676,16772,16773],{"class":5758}," my-service",[5676,16775,16776],{"class":5682},"         # новий проект зі структурою\n",[5676,16778,16779,16781,16783],{"class":5678,"line":5686},[5676,16780,13752],{"class":5719},[5676,16782,14034],{"class":5758},[5676,16784,16785],{"class":5682},"                   # додати poetry до існуючого проекту\n",[7906,16787,16789,16797],{"name":16788,"type":14223},"poetry add \u002F poetry remove",[5507,16790,15241,16791,6594,16793,16796],{},[5511,16792,13745],{},[5511,16794,16795],{},"poetry.lock",". Підтримує групи, extras та версійні обмеження.",[5667,16798,16800],{"className":13161,"code":16799,"language":13163,"meta":5672,"style":5672},"poetry add fastapi                       # остання версія\npoetry add \"sqlalchemy>=2.0,\u003C3\"         # з обмеженнями версій\npoetry add uvicorn[standard]             # з extras\npoetry add --group dev pytest ruff       # dev-група\npoetry add --group test httpx            # test-група\npoetry remove redis                      # видалення\n",[5511,16801,16802,16812,16822,16832,16849,16865],{"__ignoreMap":5672},[5676,16803,16804,16806,16808,16810],{"class":5678,"line":5679},[5676,16805,13752],{"class":5719},[5676,16807,5720],{"class":5758},[5676,16809,15260],{"class":5758},[5676,16811,15263],{"class":5682},[5676,16813,16814,16816,16818,16820],{"class":5678,"line":5686},[5676,16815,13752],{"class":5719},[5676,16817,5720],{"class":5758},[5676,16819,15272],{"class":5758},[5676,16821,15275],{"class":5682},[5676,16823,16824,16826,16828,16830],{"class":5678,"line":5693},[5676,16825,13752],{"class":5719},[5676,16827,5720],{"class":5758},[5676,16829,15284],{"class":5758},[5676,16831,15287],{"class":5682},[5676,16833,16834,16836,16838,16840,16842,16844,16846],{"class":5678,"line":5707},[5676,16835,13752],{"class":5719},[5676,16837,5720],{"class":5758},[5676,16839,16448],{"class":5715},[5676,16841,16451],{"class":5758},[5676,16843,14305],{"class":5758},[5676,16845,14311],{"class":5758},[5676,16847,16848],{"class":5682},"       # dev-група\n",[5676,16850,16851,16853,16855,16857,16860,16862],{"class":5678,"line":5712},[5676,16852,13752],{"class":5719},[5676,16854,5720],{"class":5758},[5676,16856,16448],{"class":5715},[5676,16858,16859],{"class":5758}," test",[5676,16861,14278],{"class":5758},[5676,16863,16864],{"class":5682},"            # test-група\n",[5676,16866,16867,16869,16871,16873],{"class":5678,"line":5755},[5676,16868,13752],{"class":5719},[5676,16870,14344],{"class":5758},[5676,16872,15314],{"class":5758},[5676,16874,15317],{"class":5682},[7906,16876,16878,16884],{"name":15787,"type":16877},"Встановлення залежностей",[5507,16879,16880,16881,16883],{},"Встановлює всі залежності з ",[5511,16882,16795],{},". Якщо lockfile відсутній — вирішує залежності і створює його.",[5667,16885,16887],{"className":13161,"code":16886,"language":13163,"meta":5672,"style":5672},"poetry install                  # встановити всі залежності\npoetry install --without dev    # тільки production\npoetry install --only test      # тільки вказана група\npoetry install --no-root        # без встановлення самого проекту\n",[5511,16888,16889,16897,16910,16924],{"__ignoreMap":5672},[5676,16890,16891,16893,16895],{"class":5678,"line":5679},[5676,16892,13752],{"class":5719},[5676,16894,13398],{"class":5758},[5676,16896,15344],{"class":5682},[5676,16898,16899,16901,16903,16905,16907],{"class":5678,"line":5686},[5676,16900,13752],{"class":5719},[5676,16902,13398],{"class":5758},[5676,16904,16390],{"class":5715},[5676,16906,16451],{"class":5758},[5676,16908,16909],{"class":5682},"    # тільки production\n",[5676,16911,16912,16914,16916,16919,16921],{"class":5678,"line":5693},[5676,16913,13752],{"class":5719},[5676,16915,13398],{"class":5758},[5676,16917,16918],{"class":5715}," --only",[5676,16920,16859],{"class":5758},[5676,16922,16923],{"class":5682},"      # тільки вказана група\n",[5676,16925,16926,16928,16930,16933],{"class":5678,"line":5707},[5676,16927,13752],{"class":5719},[5676,16929,13398],{"class":5758},[5676,16931,16932],{"class":5715}," --no-root",[5676,16934,16935],{"class":5682},"        # без встановлення самого проекту\n",[7906,16937,16938,16944],{"name":16621,"type":15371},[5507,16939,16940,16941,5572],{},"Виконує команду у середовищі проекту без ручної активації. Або відкрийте оболонку через ",[5511,16942,16943],{},"poetry shell",[5667,16945,16947],{"className":13161,"code":16946,"language":13163,"meta":5672,"style":5672},"poetry run python main.py              # запуск скрипта\npoetry run uvicorn app:app --reload    # запуск застосунку\npoetry run pytest                      # тести\npoetry run ruff check .                # лінтер\npoetry shell                           # активувати оболонку\n",[5511,16948,16949,16961,16975,16985,17000],{"__ignoreMap":5672},[5676,16950,16951,16953,16955,16957,16959],{"class":5678,"line":5679},[5676,16952,13752],{"class":5719},[5676,16954,14606],{"class":5758},[5676,16956,13293],{"class":5758},[5676,16958,15390],{"class":5758},[5676,16960,15393],{"class":5682},[5676,16962,16963,16965,16967,16969,16971,16973],{"class":5678,"line":5686},[5676,16964,13752],{"class":5719},[5676,16966,14606],{"class":5758},[5676,16968,14629],{"class":5758},[5676,16970,15404],{"class":5758},[5676,16972,15407],{"class":5715},[5676,16974,15410],{"class":5682},[5676,16976,16977,16979,16981,16983],{"class":5678,"line":5693},[5676,16978,13752],{"class":5719},[5676,16980,14606],{"class":5758},[5676,16982,14305],{"class":5758},[5676,16984,15421],{"class":5682},[5676,16986,16987,16989,16991,16993,16995,16997],{"class":5678,"line":5707},[5676,16988,13752],{"class":5719},[5676,16990,14606],{"class":5758},[5676,16992,14311],{"class":5758},[5676,16994,14673],{"class":5758},[5676,16996,14919],{"class":5758},[5676,16998,16999],{"class":5682},"                # лінтер\n",[5676,17001,17002,17004,17006],{"class":5678,"line":5712},[5676,17003,13752],{"class":5719},[5676,17005,16725],{"class":5758},[5676,17007,17008],{"class":5682},"                           # активувати оболонку\n",[7906,17010,17013,17021],{"name":17011,"type":17012},"poetry update","Оновлення залежностей",[5507,17014,17015,17016,17018,17019,5572],{},"Оновлює залежності до найновіших версій у межах обмежень з ",[5511,17017,13745],{},". Оновлює ",[5511,17020,16795],{},[5667,17022,17024],{"className":13161,"code":17023,"language":13163,"meta":5672,"style":5672},"poetry update              # оновити всі пакети\npoetry update fastapi      # оновити конкретний пакет\npoetry update --dry-run    # показати що зміниться (без застосування)\n",[5511,17025,17026,17035,17046],{"__ignoreMap":5672},[5676,17027,17028,17030,17032],{"class":5678,"line":5679},[5676,17029,13752],{"class":5719},[5676,17031,16517],{"class":5758},[5676,17033,17034],{"class":5682},"              # оновити всі пакети\n",[5676,17036,17037,17039,17041,17043],{"class":5678,"line":5686},[5676,17038,13752],{"class":5719},[5676,17040,16517],{"class":5758},[5676,17042,15260],{"class":5758},[5676,17044,17045],{"class":5682},"      # оновити конкретний пакет\n",[5676,17047,17048,17050,17052,17055],{"class":5678,"line":5693},[5676,17049,13752],{"class":5719},[5676,17051,16517],{"class":5758},[5676,17053,17054],{"class":5715}," --dry-run",[5676,17056,17057],{"class":5682},"    # показати що зміниться (без застосування)\n",[7906,17059,17062,17065],{"name":17060,"type":17061},"poetry show","Перегляд залежностей",[5507,17063,17064],{},"Відображає список встановлених пакетів або дерево залежностей з транзитивними пакетами.",[5667,17066,17068],{"className":13161,"code":17067,"language":13163,"meta":5672,"style":5672},"poetry show                # список всіх встановлених\npoetry show --tree         # дерево залежностей\npoetry show fastapi        # деталі конкретного пакету\npoetry show --outdated     # застарілі пакети\n",[5511,17069,17070,17079,17091,17102],{"__ignoreMap":5672},[5676,17071,17072,17074,17076],{"class":5678,"line":5679},[5676,17073,13752],{"class":5719},[5676,17075,13478],{"class":5758},[5676,17077,17078],{"class":5682},"                # список всіх встановлених\n",[5676,17080,17081,17083,17085,17088],{"class":5678,"line":5686},[5676,17082,13752],{"class":5719},[5676,17084,13478],{"class":5758},[5676,17086,17087],{"class":5715}," --tree",[5676,17089,17090],{"class":5682},"         # дерево залежностей\n",[5676,17092,17093,17095,17097,17099],{"class":5678,"line":5693},[5676,17094,13752],{"class":5719},[5676,17096,13478],{"class":5758},[5676,17098,15260],{"class":5758},[5676,17100,17101],{"class":5682},"        # деталі конкретного пакету\n",[5676,17103,17104,17106,17108,17111],{"class":5678,"line":5707},[5676,17105,13752],{"class":5719},[5676,17107,13478],{"class":5758},[5676,17109,17110],{"class":5715}," --outdated",[5676,17112,17113],{"class":5682},"     # застарілі пакети\n",[7906,17115,17118,17121],{"name":17116,"type":17117},"poetry env","Управління середовищем",[5507,17119,17120],{},"Переглядає та управляє віртуальними середовищами Poetry.",[5667,17122,17124],{"className":13161,"code":17123,"language":13163,"meta":5672,"style":5672},"poetry env info             # поточне середовище та Python\npoetry env list             # всі середовища проекту\npoetry env remove 3.12      # видалити середовище\npoetry env use 3.11         # перемкнути на іншу версію Python\n",[5511,17125,17126,17139,17150,17163],{"__ignoreMap":5672},[5676,17127,17128,17130,17133,17136],{"class":5678,"line":5679},[5676,17129,13752],{"class":5719},[5676,17131,17132],{"class":5758}," env",[5676,17134,17135],{"class":5758}," info",[5676,17137,17138],{"class":5682},"             # поточне середовище та Python\n",[5676,17140,17141,17143,17145,17147],{"class":5678,"line":5686},[5676,17142,13752],{"class":5719},[5676,17144,17132],{"class":5758},[5676,17146,11280],{"class":5758},[5676,17148,17149],{"class":5682},"             # всі середовища проекту\n",[5676,17151,17152,17154,17156,17158,17160],{"class":5678,"line":5693},[5676,17153,13752],{"class":5719},[5676,17155,17132],{"class":5758},[5676,17157,14344],{"class":5758},[5676,17159,14808],{"class":5700},[5676,17161,17162],{"class":5682},"      # видалити середовище\n",[5676,17164,17165,17167,17169,17172,17174],{"class":5678,"line":5707},[5676,17166,13752],{"class":5719},[5676,17168,17132],{"class":5758},[5676,17170,17171],{"class":5758}," use",[5676,17173,14764],{"class":5700},[5676,17175,17176],{"class":5682},"         # перемкнути на іншу версію Python\n",[7906,17178,17181,17188],{"name":17179,"type":17180},"poetry export","Сумісність з pip",[5507,17182,17183,17184,15695,17186,5572],{},"Експортує залежності у ",[5511,17185,13586],{},[5511,17187,13745],{},[5667,17189,17191],{"className":13161,"code":17190,"language":13163,"meta":5672,"style":5672},"poetry export -f requirements.txt --output requirements.txt\npoetry export -f requirements.txt --without dev --output req-prod.txt\n",[5511,17192,17193,17208],{"__ignoreMap":5672},[5676,17194,17195,17197,17199,17201,17203,17206],{"class":5678,"line":5679},[5676,17196,13752],{"class":5719},[5676,17198,15719],{"class":5758},[5676,17200,15722],{"class":5715},[5676,17202,15547],{"class":5758},[5676,17204,17205],{"class":5715}," --output",[5676,17207,13635],{"class":5758},[5676,17209,17210,17212,17214,17216,17218,17220,17222,17224],{"class":5678,"line":5686},[5676,17211,13752],{"class":5719},[5676,17213,15719],{"class":5758},[5676,17215,15722],{"class":5715},[5676,17217,15547],{"class":5758},[5676,17219,16390],{"class":5715},[5676,17221,16451],{"class":5758},[5676,17223,17205],{"class":5715},[5676,17225,17226],{"class":5758}," req-prod.txt\n",[7906,17228,17231,17241],{"name":17229,"type":17230},"poetry build \u002F poetry publish","Публікація пакету",[5507,17232,17233,17234,5737,17236,17238,17239,5572],{},"Збирає дистрибутив (wheel + sdist) та публікує на PyPI. Замінює ",[5511,17235,15814],{},[5511,17237,15817],{}," та ручне редагування ",[5511,17240,13915],{},[5667,17242,17244],{"className":13161,"code":17243,"language":13163,"meta":5672,"style":5672},"poetry build                  # зібрати dist\u002F (wheel + tar.gz)\npoetry publish                # опублікувати на PyPI\npoetry publish --build        # зібрати і опублікувати одразу\npoetry publish --repository testpypi  # на тестовий PyPI\n",[5511,17245,17246,17256,17266,17278],{"__ignoreMap":5672},[5676,17247,17248,17250,17253],{"class":5678,"line":5679},[5676,17249,13752],{"class":5719},[5676,17251,17252],{"class":5758}," build",[5676,17254,17255],{"class":5682},"                  # зібрати dist\u002F (wheel + tar.gz)\n",[5676,17257,17258,17260,17263],{"class":5678,"line":5686},[5676,17259,13752],{"class":5719},[5676,17261,17262],{"class":5758}," publish",[5676,17264,17265],{"class":5682},"                # опублікувати на PyPI\n",[5676,17267,17268,17270,17272,17275],{"class":5678,"line":5693},[5676,17269,13752],{"class":5719},[5676,17271,17262],{"class":5758},[5676,17273,17274],{"class":5715}," --build",[5676,17276,17277],{"class":5682},"        # зібрати і опублікувати одразу\n",[5676,17279,17280,17282,17284,17287,17290],{"class":5678,"line":5707},[5676,17281,13752],{"class":5719},[5676,17283,17262],{"class":5758},[5676,17285,17286],{"class":5715}," --repository",[5676,17288,17289],{"class":5758}," testpypi",[5676,17291,17292],{"class":5682},"  # на тестовий PyPI\n",[5574,17294],{},[5581,17296,17298,17299,17302,17303,7900],{"id":17297},"робота-з-git-що-робити-після-git-clone","Робота з ",[5511,17300,17301],{},"git",": що робити після ",[5511,17304,17305],{},"git clone",[5507,17307,17308,17309,17312],{},"Один із найпоширеніших питань початківців: ",[6206,17310,17311],{},"«Я склонував репозиторій. Що далі?»",". Відповідь залежить від того, яким менеджером пакетів користується проект.",[6400,17314,17316],{"id":17315},"як-розпізнати-менеджер-пакетів-проекту","Як розпізнати менеджер пакетів проекту",[5507,17318,17319],{},"Першим ділом — подивіться на файли у корені репозиторію:",[7903,17321,17322,17340,17358],{},[7906,17323,17326,17334],{"name":17324,"type":17325},"uv.lock + pyproject.toml","Проект на uv",[5507,17327,17328,17329,17331,17332,5572],{},"Є обидва файли — це ",[5511,17330,13755],{},"-проект. Команда для старту: ",[5511,17333,13901],{},[5667,17335,17338],{"className":17336,"code":17337,"language":10831},[10829],"my-project\u002F\n├── pyproject.toml   ← залежності та метадані\n├── uv.lock          ← детермінований lockfile\n├── .python-version  ← зафіксована версія Python\n└── src\u002F\n",[5511,17339,17337],{"__ignoreMap":5672},[7906,17341,17344,17352],{"name":17342,"type":17343},"poetry.lock + pyproject.toml","Проект на Poetry",[5507,17345,17346,17347,17349,17350,5572],{},"Є ",[5511,17348,16795],{}," — це Poetry-проект. Команда для старту: ",[5511,17351,15787],{},[5667,17353,17356],{"className":17354,"code":17355,"language":10831},[10829],"my-project\u002F\n├── pyproject.toml   ← залежності та метадані\n├── poetry.lock      ← детермінований lockfile\n└── src\u002F\n",[5511,17357,17355],{"__ignoreMap":5672},[7906,17359,17361,17369],{"name":13586,"type":17360},"Класичний pip-проект",[5507,17362,17363,17364,17366,17367,5572],{},"Тільки ",[5511,17365,13586],{}," — класичний підхід. Команда для старту: ",[5511,17368,15329],{},[5667,17370,17373],{"className":17371,"code":17372,"language":10831},[10829],"my-project\u002F\n├── requirements.txt ← список залежностей\n└── app.py\n",[5511,17374,17372],{"__ignoreMap":5672},[6400,17376,17378,17379,17381,17382,17384],{"id":17377},"флоу-після-git-clone-uv-проект","Флоу після ",[5511,17380,17305],{}," — ",[5511,17383,13755],{},"-проект",[6412,17386,17387,17391,17412,17416,17427,17453,17457,17468,17479,17538,17542],{},[5581,17388,17390],{"id":17389},"клонувати-та-перейти-у-директорію","Клонувати та перейти у директорію",[5667,17392,17394],{"className":13161,"code":17393,"language":13163,"meta":5672,"style":5672},"git clone https:\u002F\u002Fgithub.com\u002Forg\u002Fmy-project.git\ncd my-project\n",[5511,17395,17396,17406],{"__ignoreMap":5672},[5676,17397,17398,17400,17403],{"class":5678,"line":5679},[5676,17399,17301],{"class":5719},[5676,17401,17402],{"class":5758}," clone",[5676,17404,17405],{"class":5758}," https:\u002F\u002Fgithub.com\u002Forg\u002Fmy-project.git\n",[5676,17407,17408,17410],{"class":5678,"line":5686},[5676,17409,14042],{"class":5719},[5676,17411,14069],{"class":5758},[5581,17413,17415],{"id":17414},"перевірити-версію-python-опційно","Перевірити версію Python (опційно)",[5507,17417,17418,17420,17421,17423,17424,17426],{},[5511,17419,13755],{}," прочитає ",[5511,17422,14113],{}," автоматично. Якщо потрібна версія відсутня — ",[5511,17425,13755],{}," завантажить її сам:",[5667,17428,17430],{"className":13161,"code":17429,"language":13163,"meta":5672,"style":5672},"cat .python-version  # наприклад: 3.12\nuv python list       # перевірити що встановлено\n",[5511,17431,17432,17442],{"__ignoreMap":5672},[5676,17433,17434,17436,17439],{"class":5678,"line":5679},[5676,17435,13632],{"class":5719},[5676,17437,17438],{"class":5758}," .python-version",[5676,17440,17441],{"class":5682},"  # наприклад: 3.12\n",[5676,17443,17444,17446,17448,17450],{"class":5678,"line":5686},[5676,17445,13755],{"class":5719},[5676,17447,13293],{"class":5758},[5676,17449,11280],{"class":5758},[5676,17451,17452],{"class":5682},"       # перевірити що встановлено\n",[5581,17454,17456],{"id":17455},"синхронізувати-середовище","Синхронізувати середовище",[5507,17458,17459,17460,17462,17463,17465,17466,6410],{},"Одна команда — і все готово. ",[5511,17461,13755],{}," сам створить ",[5511,17464,15924],{}," і встановить точні версії з ",[5511,17467,13897],{},[5667,17469,17471],{"className":13161,"code":17470,"language":13163,"meta":5672,"style":5672},"uv sync\n",[5511,17472,17473],{"__ignoreMap":5672},[5676,17474,17475,17477],{"class":5678,"line":5679},[5676,17476,13755],{"class":5719},[5676,17478,14362],{"class":5758},[6145,17480,17482,17490,17494,17498,17509,17519,17523,17527,17531],{"title":17481},"uv sync після git clone",[6149,17483,17485,6157,17488],{"className":17484},[5678],[5676,17486,6156],{"className":17487},[6155],[5519,17489,13901],{},[6149,17491,17493],{"className":17492},[5678],"Using CPython 3.12.8 interpreter at: \u002FUsers\u002Fuser\u002F.local\u002Fshare\u002Fuv\u002Fpython\u002F...",[6149,17495,17497],{"className":17496},[5678],"Creating virtual environment at: .venv",[6149,17499,14397,17501,14401,17505],{"className":17500},[5678],[5676,17502,17504],{"className":17503},[6184],"42",[5676,17506,17508],{"className":17507},[6167],"183ms",[6149,17510,14409,17512,14401,17515],{"className":17511},[5678],[5676,17513,17504],{"className":17514},[6184],[5676,17516,17518],{"className":17517},[6167],"1.2s",[6149,17520,17522],{"className":17521},[5678]," + fastapi==0.115.6",[6149,17524,17526],{"className":17525},[5678]," + sqlalchemy==2.0.36",[6149,17528,17530],{"className":17529},[5678]," + ... та інші",[6149,17532,17534],{"className":17533},[5678],[5676,17535,17537],{"className":17536},[6167],"All dependencies are satisfied.",[5581,17539,17541],{"id":17540},"запустити-проект","Запустити проект",[5667,17543,17545],{"className":13161,"code":17544,"language":13163,"meta":5672,"style":5672},"uv run python main.py          # скрипт\nuv run uvicorn app:app --reload  # FastAPI\nuv run pytest                  # тести\n",[5511,17546,17547,17560,17575],{"__ignoreMap":5672},[5676,17548,17549,17551,17553,17555,17557],{"class":5678,"line":5679},[5676,17550,13755],{"class":5719},[5676,17552,14606],{"class":5758},[5676,17554,13293],{"class":5758},[5676,17556,15390],{"class":5758},[5676,17558,17559],{"class":5682},"          # скрипт\n",[5676,17561,17562,17564,17566,17568,17570,17572],{"class":5678,"line":5686},[5676,17563,13755],{"class":5719},[5676,17565,14606],{"class":5758},[5676,17567,14629],{"class":5758},[5676,17569,15404],{"class":5758},[5676,17571,15407],{"class":5715},[5676,17573,17574],{"class":5682},"  # FastAPI\n",[5676,17576,17577,17579,17581,17583],{"class":5678,"line":5693},[5676,17578,13755],{"class":5719},[5676,17580,14606],{"class":5758},[5676,17582,14305],{"class":5758},[5676,17584,17585],{"class":5682},"                  # тести\n",[13141,17587,17588,17589,17381,17591,17593,17594,5572],{},"Ніякого ",[5511,17590,13114],{},[5511,17592,14588],{}," все робить сам. Але якщо хочете активувати середовище явно для IDE або оболонки: ",[5511,17595,13114],{},[6400,17597,17378,17599,17601],{"id":17598},"флоу-після-git-clone-poetry-проект",[5511,17600,17305],{}," — Poetry-проект",[6412,17603,17604,17607,17625,17629,17649,17653,17659,17670,17730,17733],{},[5581,17605,17390],{"id":17606},"клонувати-та-перейти-у-директорію-1",[5667,17608,17609],{"className":13161,"code":17393,"language":13163,"meta":5672,"style":5672},[5511,17610,17611,17619],{"__ignoreMap":5672},[5676,17612,17613,17615,17617],{"class":5678,"line":5679},[5676,17614,17301],{"class":5719},[5676,17616,17402],{"class":5758},[5676,17618,17405],{"class":5758},[5676,17620,17621,17623],{"class":5678,"line":5686},[5676,17622,14042],{"class":5719},[5676,17624,14069],{"class":5758},[5581,17626,17628],{"id":17627},"перевірити-налаштування-poetry-один-раз","Перевірити налаштування Poetry (один раз)",[5667,17630,17632],{"className":13161,"code":17631,"language":13163,"meta":5672,"style":5672},"# Рекомендовано: зберігати venv всередині проекту\npoetry config virtualenvs.in-project true\n",[5511,17633,17634,17639],{"__ignoreMap":5672},[5676,17635,17636],{"class":5678,"line":5679},[5676,17637,17638],{"class":5682},"# Рекомендовано: зберігати venv всередині проекту\n",[5676,17640,17641,17643,17645,17647],{"class":5678,"line":5686},[5676,17642,13752],{"class":5719},[5676,17644,15909],{"class":5758},[5676,17646,15912],{"class":5758},[5676,17648,15915],{"class":5715},[5581,17650,17652],{"id":17651},"встановити-залежності","Встановити залежності",[5507,17654,17655,17656,17658],{},"Poetry прочитає ",[5511,17657,16795],{}," і встановить точні версії:",[5667,17660,17662],{"className":13161,"code":17661,"language":13163,"meta":5672,"style":5672},"poetry install\n",[5511,17663,17664],{"__ignoreMap":5672},[5676,17665,17666,17668],{"class":5678,"line":5679},[5676,17667,13752],{"class":5719},[5676,17669,16372],{"class":5758},[6145,17671,17673,17681,17684,17687,17700,17703,17709,17712,17716,17720,17723],{"title":17672},"poetry install після git clone",[6149,17674,17676,6157,17679],{"className":17675},[5678],[5676,17677,6156],{"className":17678},[6155],[5519,17680,15787],{},[6149,17682,16534],{"className":17683},[5678],[6149,17685],{"className":17686},[5678],[6149,17688,16541,17690,16546,17694,16550,17697,16554],{"className":17689},[5678],[5676,17691,17693],{"className":17692},[6184],"38",[5676,17695,8035],{"className":17696},[7829],[5676,17698,8035],{"className":17699},[8861],[6149,17701,16558],{"className":17702},[5678],[6149,17704,16566,17706],{"className":17705},[5678],[5676,17707,16570],{"className":17708},[6167],[6149,17710,16574],{"className":17711},[5678],[6149,17713,17715],{"className":17714},[5678],"  • Installing sqlalchemy (2.0.36)",[6149,17717,17719],{"className":17718},[5678],"  • ...",[6149,17721],{"className":17722},[5678],[6149,17724,16607,17726],{"className":17725},[5678],[5676,17727,17729],{"className":17728},[6167],"my-project (0.1.0)",[5581,17731,17541],{"id":17732},"запустити-проект-1",[5667,17734,17736],{"className":13161,"code":17735,"language":13163,"meta":5672,"style":5672},"poetry run python main.py\npoetry run uvicorn app:app --reload\npoetry run pytest\n",[5511,17737,17738,17748,17760],{"__ignoreMap":5672},[5676,17739,17740,17742,17744,17746],{"class":5678,"line":5679},[5676,17741,13752],{"class":5719},[5676,17743,14606],{"class":5758},[5676,17745,13293],{"class":5758},[5676,17747,14611],{"class":5758},[5676,17749,17750,17752,17754,17756,17758],{"class":5678,"line":5686},[5676,17751,13752],{"class":5719},[5676,17753,14606],{"class":5758},[5676,17755,14629],{"class":5758},[5676,17757,15404],{"class":5758},[5676,17759,14635],{"class":5715},[5676,17761,17762,17764,17766],{"class":5678,"line":5693},[5676,17763,13752],{"class":5719},[5676,17765,14606],{"class":5758},[5676,17767,14653],{"class":5758},[6400,17769,17771,17772,17774],{"id":17770},"що-комітити-у-git-таблиця","Що комітити у ",[5511,17773,17301],{},"? Таблиця",[5507,17776,17777,17778,5737,17781,17381,17784,5572],{},"Правило просте: ",[5519,17779,17780],{},"lockfile завжди комітити",[5511,17782,17783],{},".venv",[5519,17785,17786],{},"ніколи",[10245,17788,17789,17802],{},[10248,17790,17791],{},[10251,17792,17793,17796,17799],{},[10254,17794,17795],{},"Файл",[10254,17797,17798],{},"Комітити?",[10254,17800,17801],{},"Причина",[10265,17803,17804,17816,17827,17837,17848,17859,17874,17888,17902],{},[10251,17805,17806,17810,17813],{},[10270,17807,17808],{},[5511,17809,13745],{},[10270,17811,17812],{},"✅ Так",[10270,17814,17815],{},"Метадані та прямі залежності проекту",[10251,17817,17818,17822,17824],{},[10270,17819,17820],{},[5511,17821,13897],{},[10270,17823,17812],{},[10270,17825,17826],{},"Детермінований lockfile для відтворення",[10251,17828,17829,17833,17835],{},[10270,17830,17831],{},[5511,17832,16795],{},[10270,17834,17812],{},[10270,17836,17826],{},[10251,17838,17839,17843,17845],{},[10270,17840,17841],{},[5511,17842,13586],{},[10270,17844,17812],{},[10270,17846,17847],{},"Якщо проект класичний pip",[10251,17849,17850,17854,17856],{},[10270,17851,17852],{},[5511,17853,14113],{},[10270,17855,17812],{},[10270,17857,17858],{},"Фіксує версію Python для команди",[10251,17860,17861,17865,17868],{},[10270,17862,17863],{},[5511,17864,15924],{},[10270,17866,17867],{},"❌ Ні",[10270,17869,17870,17871],{},"Велика, специфічна для ОС — у ",[5511,17872,17873],{},".gitignore",[10251,17875,17876,17881,17883],{},[10270,17877,17878],{},[5511,17879,17880],{},"__pycache__\u002F",[10270,17882,17867],{},[10270,17884,17885,17886],{},"Кеш байткоду — у ",[5511,17887,17873],{},[10251,17889,17890,17895,17897],{},[10270,17891,17892],{},[5511,17893,17894],{},"*.pyc",[10270,17896,17867],{},[10270,17898,17899,17900],{},"Компільований байткод — у ",[5511,17901,17873],{},[10251,17903,17904,17909,17911],{},[10270,17905,17906],{},[5511,17907,17908],{},".env",[10270,17910,17867],{},[10270,17912,17913,17914],{},"Секрети та конфіги — у ",[5511,17915,17873],{},[6400,17917,17919,17920,17922],{"id":17918},"стандартний-gitignore-для-python-проекту","Стандартний ",[5511,17921,17873],{}," для Python-проекту",[5667,17924,17928],{"className":17925,"code":17926,"language":17927,"meta":5672,"style":5672},"language-gitignore shiki shiki-themes light-plus dark-plus dark-plus","# Віртуальні середовища\n.venv\u002F\nvenv\u002F\nenv\u002F\n\n# Байткод та кеш\n__pycache__\u002F\n*.py[cod]\n*$py.class\n*.pyo\n\n# Артефакти збірки\ndist\u002F\nbuild\u002F\n*.egg-info\u002F\n*.egg\n\n# Тести та покриття\n.pytest_cache\u002F\n.coverage\nhtmlcov\u002F\n\n# Типи та лінтери\n.mypy_cache\u002F\n.ruff_cache\u002F\n\n# Середовище та секрети\n.env\n.env.local\n*.env\n\n# IDE\n.idea\u002F\n.vscode\u002F\n*.swp\n","gitignore",[5511,17929,17930,17935,17940,17945,17950,17954,17959,17964,17969,17974,17979,17983,17988,17993,17998,18003,18008,18012,18017,18022,18027,18032,18036,18041,18046,18051,18055,18060,18065,18070,18075,18079,18084,18089,18094],{"__ignoreMap":5672},[5676,17931,17932],{"class":5678,"line":5679},[5676,17933,17934],{},"# Віртуальні середовища\n",[5676,17936,17937],{"class":5678,"line":5686},[5676,17938,17939],{},".venv\u002F\n",[5676,17941,17942],{"class":5678,"line":5693},[5676,17943,17944],{},"venv\u002F\n",[5676,17946,17947],{"class":5678,"line":5707},[5676,17948,17949],{},"env\u002F\n",[5676,17951,17952],{"class":5678,"line":5712},[5676,17953,5690],{"emptyLinePlaceholder":5689},[5676,17955,17956],{"class":5678,"line":5755},[5676,17957,17958],{},"# Байткод та кеш\n",[5676,17960,17961],{"class":5678,"line":5762},[5676,17962,17963],{},"__pycache__\u002F\n",[5676,17965,17966],{"class":5678,"line":5772},[5676,17967,17968],{},"*.py[cod]\n",[5676,17970,17971],{"class":5678,"line":5777},[5676,17972,17973],{},"*$py.class\n",[5676,17975,17976],{"class":5678,"line":5807},[5676,17977,17978],{},"*.pyo\n",[5676,17980,17981],{"class":5678,"line":5813},[5676,17982,5690],{"emptyLinePlaceholder":5689},[5676,17984,17985],{"class":5678,"line":5821},[5676,17986,17987],{},"# Артефакти збірки\n",[5676,17989,17990],{"class":5678,"line":5826},[5676,17991,17992],{},"dist\u002F\n",[5676,17994,17995],{"class":5678,"line":5856},[5676,17996,17997],{},"build\u002F\n",[5676,17999,18000],{"class":5678,"line":5862},[5676,18001,18002],{},"*.egg-info\u002F\n",[5676,18004,18005],{"class":5678,"line":5870},[5676,18006,18007],{},"*.egg\n",[5676,18009,18010],{"class":5678,"line":5875},[5676,18011,5690],{"emptyLinePlaceholder":5689},[5676,18013,18014],{"class":5678,"line":5898},[5676,18015,18016],{},"# Тести та покриття\n",[5676,18018,18019],{"class":5678,"line":5904},[5676,18020,18021],{},".pytest_cache\u002F\n",[5676,18023,18024],{"class":5678,"line":5915},[5676,18025,18026],{},".coverage\n",[5676,18028,18029],{"class":5678,"line":5920},[5676,18030,18031],{},"htmlcov\u002F\n",[5676,18033,18034],{"class":5678,"line":5941},[5676,18035,5690],{"emptyLinePlaceholder":5689},[5676,18037,18038],{"class":5678,"line":5947},[5676,18039,18040],{},"# Типи та лінтери\n",[5676,18042,18043],{"class":5678,"line":5953},[5676,18044,18045],{},".mypy_cache\u002F\n",[5676,18047,18048],{"class":5678,"line":5959},[5676,18049,18050],{},".ruff_cache\u002F\n",[5676,18052,18053],{"class":5678,"line":5964},[5676,18054,5690],{"emptyLinePlaceholder":5689},[5676,18056,18057],{"class":5678,"line":7576},[5676,18058,18059],{},"# Середовище та секрети\n",[5676,18061,18062],{"class":5678,"line":7581},[5676,18063,18064],{},".env\n",[5676,18066,18067],{"class":5678,"line":7587},[5676,18068,18069],{},".env.local\n",[5676,18071,18072],{"class":5678,"line":7593},[5676,18073,18074],{},"*.env\n",[5676,18076,18077],{"class":5678,"line":7599},[5676,18078,5690],{"emptyLinePlaceholder":5689},[5676,18080,18081],{"class":5678,"line":7605},[5676,18082,18083],{},"# IDE\n",[5676,18085,18086],{"class":5678,"line":7611},[5676,18087,18088],{},".idea\u002F\n",[5676,18090,18091],{"class":5678,"line":7617},[5676,18092,18093],{},".vscode\u002F\n",[5676,18095,18096],{"class":5678,"line":7622},[5676,18097,18098],{},"*.swp\n",[5574,18100],{},[5581,18102,18104,18105,6594,18107],{"id":18103},"статичний-аналіз-типів-mypy-та-pyright","Статичний аналіз типів: ",[5511,18106,16271],{},[5511,18108,18109],{},"Pyright",[5507,18111,18112,18113,18116,18117,9387,18120,18123,18124,18127,18128,18131],{},"Python — мова з ",[5519,18114,18115],{},"динамічною"," типізацією: типи перевіряються під час виконання. Але з Python 3.5+ з'явилися ",[5519,18118,18119],{},"анотації типів",[5511,18121,18122],{},"def foo(x: int) -> str:","), і на цій основі побудовані ",[5519,18125,18126],{},"статичні аналізатори"," — інструменти, що знаходять помилки типів ",[6206,18129,18130],{},"до"," запуску програми.",[5524,18133,18134,18138],{},[5527,18135,18137],{"icon":18136,"title":16271},"i-heroicons-check-badge","Офіційний статичний аналізатор від команди Python. Написаний на Python. Стандарт для більшості проектів, широко підтримується в CI\u002FCD та IDE.",[5527,18139,18140,18141,5572],{"icon":13865,"title":18109},"Написаний на TypeScript (!) від Microsoft. Значно швидший за mypy. Є основою для type-checking у Pylance (VSCode). Також доступний як CLI — ",[5511,18142,18143],{},"pyright",[6400,18145,18147],{"id":18146},"навіщо-потрібен-статичний-аналіз-типів","Навіщо потрібен статичний аналіз типів?",[5667,18149,18151],{"className":5669,"code":18150,"language":5671,"meta":5672,"style":5672},"# Без анотацій — помилка знайдеться лише під час виконання\ndef get_user_age(user):\n    return user[\"age\"] + 1  # KeyError? TypeError? Дізнаємось пізно\n\n# З анотаціями — mypy\u002FPyright знаходять помилки відразу\nfrom typing import TypedDict\n\nclass User(TypedDict):\n    name: str\n    age: int\n\ndef get_user_age(user: User) -> int:\n    return user[\"age\"] + 1  # mypy: OK\n    # return user[\"nme\"] + 1  # mypy: ERROR — key \"nme\" не існує у User\n",[5511,18152,18153,18158,18172,18190,18194,18199,18211,18215,18230,18238,18246,18250,18267,18282],{"__ignoreMap":5672},[5676,18154,18155],{"class":5678,"line":5679},[5676,18156,18157],{"class":5682},"# Без анотацій — помилка знайдеться лише під час виконання\n",[5676,18159,18160,18162,18165,18167,18170],{"class":5678,"line":5686},[5676,18161,5716],{"class":5715},[5676,18163,18164],{"class":5719}," get_user_age",[5676,18166,5723],{"class":5696},[5676,18168,18169],{"class":5726},"user",[5676,18171,9450],{"class":5696},[5676,18173,18174,18176,18179,18182,18185,18187],{"class":5678,"line":5693},[5676,18175,5766],{"class":5765},[5676,18177,18178],{"class":5696}," user[",[5676,18180,18181],{"class":5758},"\"age\"",[5676,18183,18184],{"class":5696},"] + ",[5676,18186,7174],{"class":5700},[5676,18188,18189],{"class":5682},"  # KeyError? TypeError? Дізнаємось пізно\n",[5676,18191,18192],{"class":5678,"line":5707},[5676,18193,5690],{"emptyLinePlaceholder":5689},[5676,18195,18196],{"class":5678,"line":5712},[5676,18197,18198],{"class":5682},"# З анотаціями — mypy\u002FPyright знаходять помилки відразу\n",[5676,18200,18201,18203,18206,18208],{"class":5678,"line":5755},[5676,18202,7020],{"class":5765},[5676,18204,18205],{"class":5696}," typing ",[5676,18207,6018],{"class":5765},[5676,18209,18210],{"class":5696}," TypedDict\n",[5676,18212,18213],{"class":5678,"line":5762},[5676,18214,5690],{"emptyLinePlaceholder":5689},[5676,18216,18217,18220,18223,18225,18228],{"class":5678,"line":5772},[5676,18218,18219],{"class":5715},"class",[5676,18221,18222],{"class":5733}," User",[5676,18224,5723],{"class":5696},[5676,18226,18227],{"class":5733},"TypedDict",[5676,18229,9450],{"class":5696},[5676,18231,18232,18235],{"class":5678,"line":5777},[5676,18233,18234],{"class":5696},"    name: ",[5676,18236,18237],{"class":5733},"str\n",[5676,18239,18240,18243],{"class":5678,"line":5807},[5676,18241,18242],{"class":5696},"    age: ",[5676,18244,18245],{"class":5733},"int\n",[5676,18247,18248],{"class":5678,"line":5813},[5676,18249,5690],{"emptyLinePlaceholder":5689},[5676,18251,18252,18254,18256,18258,18260,18263,18265],{"class":5678,"line":5821},[5676,18253,5716],{"class":5715},[5676,18255,18164],{"class":5719},[5676,18257,5723],{"class":5696},[5676,18259,18169],{"class":5726},[5676,18261,18262],{"class":5696},": User) -> ",[5676,18264,5980],{"class":5733},[5676,18266,5752],{"class":5696},[5676,18268,18269,18271,18273,18275,18277,18279],{"class":5678,"line":5826},[5676,18270,5766],{"class":5765},[5676,18272,18178],{"class":5696},[5676,18274,18181],{"class":5758},[5676,18276,18184],{"class":5696},[5676,18278,7174],{"class":5700},[5676,18280,18281],{"class":5682},"  # mypy: OK\n",[5676,18283,18284],{"class":5678,"line":5856},[5676,18285,18286],{"class":5682},"    # return user[\"nme\"] + 1  # mypy: ERROR — key \"nme\" не існує у User\n",[6400,18288,18290,18292],{"id":18289},"mypy-встановлення-та-базове-використання",[5511,18291,16271],{}," — встановлення та базове використання",[5667,18294,18296],{"className":13161,"code":18295,"language":13163,"meta":5672,"style":5672},"# Встановлення\nuv add --dev mypy\n# або\npip install mypy\n\n# Запуск для файлу\nmypy main.py\n\n# Запуск для всього проекту\nmypy .\n\n# Перевірка конкретного пакету\nmypy my_package\u002F\n",[5511,18297,18298,18303,18313,18318,18326,18330,18335,18341,18345,18350,18356,18360,18365],{"__ignoreMap":5672},[5676,18299,18300],{"class":5678,"line":5679},[5676,18301,18302],{"class":5682},"# Встановлення\n",[5676,18304,18305,18307,18309,18311],{"class":5678,"line":5686},[5676,18306,13755],{"class":5719},[5676,18308,5720],{"class":5758},[5676,18310,14302],{"class":5715},[5676,18312,14314],{"class":5758},[5676,18314,18315],{"class":5678,"line":5693},[5676,18316,18317],{"class":5682},"# або\n",[5676,18319,18320,18322,18324],{"class":5678,"line":5707},[5676,18321,8268],{"class":5719},[5676,18323,13398],{"class":5758},[5676,18325,14314],{"class":5758},[5676,18327,18328],{"class":5678,"line":5712},[5676,18329,5690],{"emptyLinePlaceholder":5689},[5676,18331,18332],{"class":5678,"line":5755},[5676,18333,18334],{"class":5682},"# Запуск для файлу\n",[5676,18336,18337,18339],{"class":5678,"line":5762},[5676,18338,16271],{"class":5719},[5676,18340,14611],{"class":5758},[5676,18342,18343],{"class":5678,"line":5772},[5676,18344,5690],{"emptyLinePlaceholder":5689},[5676,18346,18347],{"class":5678,"line":5777},[5676,18348,18349],{"class":5682},"# Запуск для всього проекту\n",[5676,18351,18352,18354],{"class":5678,"line":5807},[5676,18353,16271],{"class":5719},[5676,18355,14676],{"class":5758},[5676,18357,18358],{"class":5678,"line":5813},[5676,18359,5690],{"emptyLinePlaceholder":5689},[5676,18361,18362],{"class":5678,"line":5821},[5676,18363,18364],{"class":5682},"# Перевірка конкретного пакету\n",[5676,18366,18367,18369],{"class":5678,"line":5826},[5676,18368,16271],{"class":5719},[5676,18370,18371],{"class":5758}," my_package\u002F\n",[6145,18373,18375,18384,18403,18416,18432],{"title":18374},"mypy — знаходження помилок типів",[6149,18376,18378,6157,18381],{"className":18377},[5678],[5676,18379,6156],{"className":18380},[6155],[5519,18382,18383],{},"mypy main.py",[6149,18385,18387,18388,18392,18393,18397,18398,18402],{"className":18386},[5678],"main.py:",[5676,18389,18391],{"className":18390},[7829],"12",": error: Argument 1 to \"add\" has incompatible type ",[5676,18394,18396],{"className":18395},[8861],"\"str\"","; expected ",[5676,18399,18401],{"className":18400},[6167],"\"int\"","  [arg-type]",[6149,18404,18387,18406,18410,18411,18415],{"className":18405},[5678],[5676,18407,18409],{"className":18408},[7829],"18",": error: Item ",[5676,18412,18414],{"className":18413},[8861],"\"None\""," of \"Optional[str]\" has no attribute \"upper\"  [union-attr]",[6149,18417,18387,18419,18423,18424,18427,18428,18431],{"className":18418},[5678],[5676,18420,18422],{"className":18421},[7829],"25",": error: Return type declared as ",[5676,18425,18401],{"className":18426},[6167],", actual return type ",[5676,18429,18396],{"className":18430},[8861],"  [return-value]",[6149,18433,18435,18436,18440],{"className":18434},[5678],"Found ",[5676,18437,18439],{"className":18438},[8861],"3 errors"," in 1 file (checked 1 source file)",[6400,18442,18444,18445,10558,18447],{"id":18443},"конфігурація-mypy-у-pyprojecttoml","Конфігурація ",[5511,18446,16271],{},[5511,18448,13745],{},[5667,18450,18452],{"className":14149,"code":18451,"language":14151,"meta":5672,"style":5672},"[tool.mypy]\npython_version = \"3.12\"\nstrict = true              # найсуворіший режим — рекомендовано для нових проектів\n\n# Що перевіряти\ncheck_untyped_defs = true  # перевіряти навіть нетиповані функції\ndisallow_untyped_defs = true  # вимагати анотацій для всіх функцій\ndisallow_any_generics = true  # заборонити голі Generic (list замість list[str])\nwarn_return_any = true     # попереджати про return Any\n\n# Що ігнорувати\nignore_missing_imports = true  # якщо бібліотека не має стабів\n\n# Виключення конкретних модулів\n[[tool.mypy.overrides]]\nmodule = [\"tests.*\"]\ndisallow_untyped_defs = false  # у тестах дозволяємо без анотацій\n",[5511,18453,18454,18459,18469,18482,18486,18491,18503,18515,18527,18539,18543,18548,18560,18564,18569,18574,18585],{"__ignoreMap":5672},[5676,18455,18456],{"class":5678,"line":5679},[5676,18457,18458],{"class":5696},"[tool.mypy]\n",[5676,18460,18461,18464,18466],{"class":5678,"line":5686},[5676,18462,18463],{"class":5726},"python_version",[5676,18465,10984],{"class":5696},[5676,18467,18468],{"class":5758},"\"3.12\"\n",[5676,18470,18471,18474,18476,18479],{"class":5678,"line":5693},[5676,18472,18473],{"class":5726},"strict",[5676,18475,10984],{"class":5696},[5676,18477,18478],{"class":5715},"true",[5676,18480,18481],{"class":5682},"              # найсуворіший режим — рекомендовано для нових проектів\n",[5676,18483,18484],{"class":5678,"line":5707},[5676,18485,5690],{"emptyLinePlaceholder":5689},[5676,18487,18488],{"class":5678,"line":5712},[5676,18489,18490],{"class":5682},"# Що перевіряти\n",[5676,18492,18493,18496,18498,18500],{"class":5678,"line":5755},[5676,18494,18495],{"class":5726},"check_untyped_defs",[5676,18497,10984],{"class":5696},[5676,18499,18478],{"class":5715},[5676,18501,18502],{"class":5682},"  # перевіряти навіть нетиповані функції\n",[5676,18504,18505,18508,18510,18512],{"class":5678,"line":5762},[5676,18506,18507],{"class":5726},"disallow_untyped_defs",[5676,18509,10984],{"class":5696},[5676,18511,18478],{"class":5715},[5676,18513,18514],{"class":5682},"  # вимагати анотацій для всіх функцій\n",[5676,18516,18517,18520,18522,18524],{"class":5678,"line":5772},[5676,18518,18519],{"class":5726},"disallow_any_generics",[5676,18521,10984],{"class":5696},[5676,18523,18478],{"class":5715},[5676,18525,18526],{"class":5682},"  # заборонити голі Generic (list замість list[str])\n",[5676,18528,18529,18532,18534,18536],{"class":5678,"line":5777},[5676,18530,18531],{"class":5726},"warn_return_any",[5676,18533,10984],{"class":5696},[5676,18535,18478],{"class":5715},[5676,18537,18538],{"class":5682},"     # попереджати про return Any\n",[5676,18540,18541],{"class":5678,"line":5807},[5676,18542,5690],{"emptyLinePlaceholder":5689},[5676,18544,18545],{"class":5678,"line":5813},[5676,18546,18547],{"class":5682},"# Що ігнорувати\n",[5676,18549,18550,18553,18555,18557],{"class":5678,"line":5821},[5676,18551,18552],{"class":5726},"ignore_missing_imports",[5676,18554,10984],{"class":5696},[5676,18556,18478],{"class":5715},[5676,18558,18559],{"class":5682},"  # якщо бібліотека не має стабів\n",[5676,18561,18562],{"class":5678,"line":5826},[5676,18563,5690],{"emptyLinePlaceholder":5689},[5676,18565,18566],{"class":5678,"line":5856},[5676,18567,18568],{"class":5682},"# Виключення конкретних модулів\n",[5676,18570,18571],{"class":5678,"line":5862},[5676,18572,18573],{"class":5696},"[[tool.mypy.overrides]]\n",[5676,18575,18576,18578,18580,18583],{"class":5678,"line":5870},[5676,18577,5643],{"class":5726},[5676,18579,11003],{"class":5696},[5676,18581,18582],{"class":5758},"\"tests.*\"",[5676,18584,8460],{"class":5696},[5676,18586,18587,18589,18591,18594],{"class":5678,"line":5875},[5676,18588,18507],{"class":5726},[5676,18590,10984],{"class":5696},[5676,18592,18593],{"class":5715},"false",[5676,18595,18596],{"class":5682},"  # у тестах дозволяємо без анотацій\n",[6400,18598,18600],{"id":18599},"практичний-приклад-типовані-структури-даних","Практичний приклад: типовані структури даних",[5667,18602,18604],{"className":5669,"code":18603,"language":5671,"meta":5672,"style":5672},"from typing import Optional, Union\nfrom collections.abc import Sequence\n\n# TypedDict — словник зі строгою структурою\nfrom typing import TypedDict\n\nclass Address(TypedDict):\n    street: str\n    city: str\n    postal_code: str\n\nclass UserProfile(TypedDict, total=False):  # total=False — всі поля необов'язкові\n    bio: str\n    avatar_url: str\n\nclass User(TypedDict):\n    id: int\n    name: str\n    email: str\n    address: Address\n    profile: UserProfile  # вкладений TypedDict\n\n# Функція з повними анотаціями\ndef find_users_by_city(\n    users: Sequence[User],\n    city: str,\n    limit: Optional[int] = None,\n) -> list[User]:\n    \"\"\"Знаходить користувачів із зазначеного міста.\"\"\"\n    result = [u for u in users if u[\"address\"][\"city\"] == city]\n    if limit is not None:\n        result = result[:limit]\n    return result\n\n# mypy перевірить:\n# - що users є Sequence[User]\n# - що city є str\n# - що limit є Optional[int] (може бути None)\n# - що функція повертає list[User]\n",[5511,18605,18606,18617,18629,18633,18638,18648,18652,18665,18672,18679,18686,18690,18716,18723,18730,18734,18746,18755,18761,18768,18773,18781,18785,18790,18800,18808,18819,18836,18841,18846,18878,18894,18899,18906,18910,18915,18920,18925,18930],{"__ignoreMap":5672},[5676,18607,18608,18610,18612,18614],{"class":5678,"line":5679},[5676,18609,7020],{"class":5765},[5676,18611,18205],{"class":5696},[5676,18613,6018],{"class":5765},[5676,18615,18616],{"class":5696}," Optional, Union\n",[5676,18618,18619,18621,18624,18626],{"class":5678,"line":5686},[5676,18620,7020],{"class":5765},[5676,18622,18623],{"class":5696}," collections.abc ",[5676,18625,6018],{"class":5765},[5676,18627,18628],{"class":5696}," Sequence\n",[5676,18630,18631],{"class":5678,"line":5693},[5676,18632,5690],{"emptyLinePlaceholder":5689},[5676,18634,18635],{"class":5678,"line":5707},[5676,18636,18637],{"class":5682},"# TypedDict — словник зі строгою структурою\n",[5676,18639,18640,18642,18644,18646],{"class":5678,"line":5712},[5676,18641,7020],{"class":5765},[5676,18643,18205],{"class":5696},[5676,18645,6018],{"class":5765},[5676,18647,18210],{"class":5696},[5676,18649,18650],{"class":5678,"line":5755},[5676,18651,5690],{"emptyLinePlaceholder":5689},[5676,18653,18654,18656,18659,18661,18663],{"class":5678,"line":5762},[5676,18655,18219],{"class":5715},[5676,18657,18658],{"class":5733}," Address",[5676,18660,5723],{"class":5696},[5676,18662,18227],{"class":5733},[5676,18664,9450],{"class":5696},[5676,18666,18667,18670],{"class":5678,"line":5772},[5676,18668,18669],{"class":5696},"    street: ",[5676,18671,18237],{"class":5733},[5676,18673,18674,18677],{"class":5678,"line":5777},[5676,18675,18676],{"class":5696},"    city: ",[5676,18678,18237],{"class":5733},[5676,18680,18681,18684],{"class":5678,"line":5807},[5676,18682,18683],{"class":5696},"    postal_code: ",[5676,18685,18237],{"class":5733},[5676,18687,18688],{"class":5678,"line":5813},[5676,18689,5690],{"emptyLinePlaceholder":5689},[5676,18691,18692,18694,18697,18699,18701,18703,18706,18708,18710,18713],{"class":5678,"line":5821},[5676,18693,18219],{"class":5715},[5676,18695,18696],{"class":5733}," UserProfile",[5676,18698,5723],{"class":5696},[5676,18700,18227],{"class":5733},[5676,18702,5737],{"class":5696},[5676,18704,18705],{"class":5726},"total",[5676,18707,9923],{"class":5696},[5676,18709,8862],{"class":5715},[5676,18711,18712],{"class":5696},"):  ",[5676,18714,18715],{"class":5682},"# total=False — всі поля необов'язкові\n",[5676,18717,18718,18721],{"class":5678,"line":5826},[5676,18719,18720],{"class":5696},"    bio: ",[5676,18722,18237],{"class":5733},[5676,18724,18725,18728],{"class":5678,"line":5856},[5676,18726,18727],{"class":5696},"    avatar_url: ",[5676,18729,18237],{"class":5733},[5676,18731,18732],{"class":5678,"line":5862},[5676,18733,5690],{"emptyLinePlaceholder":5689},[5676,18735,18736,18738,18740,18742,18744],{"class":5678,"line":5870},[5676,18737,18219],{"class":5715},[5676,18739,18222],{"class":5733},[5676,18741,5723],{"class":5696},[5676,18743,18227],{"class":5733},[5676,18745,9450],{"class":5696},[5676,18747,18748,18751,18753],{"class":5678,"line":5875},[5676,18749,18750],{"class":5719},"    id",[5676,18752,5730],{"class":5696},[5676,18754,18245],{"class":5733},[5676,18756,18757,18759],{"class":5678,"line":5898},[5676,18758,18234],{"class":5696},[5676,18760,18237],{"class":5733},[5676,18762,18763,18766],{"class":5678,"line":5904},[5676,18764,18765],{"class":5696},"    email: ",[5676,18767,18237],{"class":5733},[5676,18769,18770],{"class":5678,"line":5915},[5676,18771,18772],{"class":5696},"    address: Address\n",[5676,18774,18775,18778],{"class":5678,"line":5920},[5676,18776,18777],{"class":5696},"    profile: UserProfile  ",[5676,18779,18780],{"class":5682},"# вкладений TypedDict\n",[5676,18782,18783],{"class":5678,"line":5941},[5676,18784,5690],{"emptyLinePlaceholder":5689},[5676,18786,18787],{"class":5678,"line":5947},[5676,18788,18789],{"class":5682},"# Функція з повними анотаціями\n",[5676,18791,18792,18794,18797],{"class":5678,"line":5953},[5676,18793,5716],{"class":5715},[5676,18795,18796],{"class":5719}," find_users_by_city",[5676,18798,18799],{"class":5696},"(\n",[5676,18801,18802,18805],{"class":5678,"line":5959},[5676,18803,18804],{"class":5726},"    users",[5676,18806,18807],{"class":5696},": Sequence[User],\n",[5676,18809,18810,18813,18815,18817],{"class":5678,"line":5964},[5676,18811,18812],{"class":5726},"    city",[5676,18814,5730],{"class":5696},[5676,18816,6258],{"class":5733},[5676,18818,14527],{"class":5696},[5676,18820,18821,18824,18827,18829,18832,18834],{"class":5678,"line":7576},[5676,18822,18823],{"class":5726},"    limit",[5676,18825,18826],{"class":5696},": Optional[",[5676,18828,5980],{"class":5733},[5676,18830,18831],{"class":5696},"] = ",[5676,18833,8975],{"class":5715},[5676,18835,14527],{"class":5696},[5676,18837,18838],{"class":5678,"line":7581},[5676,18839,18840],{"class":5696},") -> list[User]:\n",[5676,18842,18843],{"class":5678,"line":7587},[5676,18844,18845],{"class":5758},"    \"\"\"Знаходить користувачів із зазначеного міста.\"\"\"\n",[5676,18847,18848,18851,18853,18856,18858,18861,18863,18866,18869,18872,18875],{"class":5678,"line":7593},[5676,18849,18850],{"class":5696},"    result = [u ",[5676,18852,5990],{"class":5765},[5676,18854,18855],{"class":5696}," u ",[5676,18857,5996],{"class":5765},[5676,18859,18860],{"class":5696}," users ",[5676,18862,9577],{"class":5765},[5676,18864,18865],{"class":5696}," u[",[5676,18867,18868],{"class":5758},"\"address\"",[5676,18870,18871],{"class":5696},"][",[5676,18873,18874],{"class":5758},"\"city\"",[5676,18876,18877],{"class":5696},"] == city]\n",[5676,18879,18880,18882,18885,18887,18890,18892],{"class":5678,"line":7599},[5676,18881,9967],{"class":5765},[5676,18883,18884],{"class":5696}," limit ",[5676,18886,8479],{"class":5715},[5676,18888,18889],{"class":5715}," not",[5676,18891,11420],{"class":5715},[5676,18893,5752],{"class":5696},[5676,18895,18896],{"class":5678,"line":7605},[5676,18897,18898],{"class":5696},"        result = result[:limit]\n",[5676,18900,18901,18903],{"class":5678,"line":7611},[5676,18902,5766],{"class":5765},[5676,18904,18905],{"class":5696}," result\n",[5676,18907,18908],{"class":5678,"line":7617},[5676,18909,5690],{"emptyLinePlaceholder":5689},[5676,18911,18912],{"class":5678,"line":7622},[5676,18913,18914],{"class":5682},"# mypy перевірить:\n",[5676,18916,18917],{"class":5678,"line":7627},[5676,18918,18919],{"class":5682},"# - що users є Sequence[User]\n",[5676,18921,18922],{"class":5678,"line":7633},[5676,18923,18924],{"class":5682},"# - що city є str\n",[5676,18926,18927],{"class":5678,"line":7639},[5676,18928,18929],{"class":5682},"# - що limit є Optional[int] (може бути None)\n",[5676,18931,18932],{"class":5678,"line":7645},[5676,18933,18934],{"class":5682},"# - що функція повертає list[User]\n",[6400,18936,18938,18940],{"id":18937},"pyright-швидший-альтернативний-аналізатор",[5511,18939,18109],{}," — швидший альтернативний аналізатор",[5667,18942,18944],{"className":13161,"code":18943,"language":13163,"meta":5672,"style":5672},"# Встановлення через uv\nuv add --dev pyright\n# або глобально\nuvx pyright --version\n\n# Запуск\npyright .\npyright main.py --pythonversion 3.12\n",[5511,18945,18946,18951,18962,18967,18977,18981,18986,18992],{"__ignoreMap":5672},[5676,18947,18948],{"class":5678,"line":5679},[5676,18949,18950],{"class":5682},"# Встановлення через uv\n",[5676,18952,18953,18955,18957,18959],{"class":5678,"line":5686},[5676,18954,13755],{"class":5719},[5676,18956,5720],{"class":5758},[5676,18958,14302],{"class":5715},[5676,18960,18961],{"class":5758}," pyright\n",[5676,18963,18964],{"class":5678,"line":5693},[5676,18965,18966],{"class":5682},"# або глобально\n",[5676,18968,18969,18971,18974],{"class":5678,"line":5707},[5676,18970,14889],{"class":5719},[5676,18972,18973],{"class":5758}," pyright",[5676,18975,18976],{"class":5715}," --version\n",[5676,18978,18979],{"class":5678,"line":5712},[5676,18980,5690],{"emptyLinePlaceholder":5689},[5676,18982,18983],{"class":5678,"line":5755},[5676,18984,18985],{"class":5682},"# Запуск\n",[5676,18987,18988,18990],{"class":5678,"line":5762},[5676,18989,18143],{"class":5719},[5676,18991,14676],{"class":5758},[5676,18993,18994,18996,18998,19001],{"class":5678,"line":5772},[5676,18995,18143],{"class":5719},[5676,18997,15390],{"class":5758},[5676,18999,19000],{"class":5715}," --pythonversion",[5676,19002,14753],{"class":5700},[6145,19004,19006,19015,19019,19023,19026,19034,19059,19086,19089,19097],{"title":19005},"pyright — аналіз типів",[6149,19007,19009,6157,19012],{"className":19008},[5678],[5676,19010,6156],{"className":19011},[6155],[5519,19013,19014],{},"pyright .",[6149,19016,19018],{"className":19017},[5678],"Loading configuration file at \u002FUsers\u002Fuser\u002Fmy-project\u002Fpyrightconfig.json",[6149,19020,19022],{"className":19021},[5678],"pyright 1.1.391",[6149,19024],{"className":19025},[5678],[6149,19027,19029,19030],{"className":19028},[5678],"\u002F",[5676,19031,19033],{"className":19032},[6184],"my_project\u002Fservice.py",[6149,19035,19037,19038,6410,19041,6410,19045,19049,19050,19054,19055,19058],{"className":19036},[5678],"  \u002F",[5676,19039,19033],{"className":19040},[6184],[5676,19042,19044],{"className":19043},[7829],"34",[5676,19046,19048],{"className":19047},[7829],"16"," - error: Expression of type ",[5676,19051,19053],{"className":19052},[8861],"\"str | None\""," cannot be assigned to declared type ",[5676,19056,18396],{"className":19057},[6167]," (reportAssignmentType)",[6149,19060,19037,19062,6410,19065,6410,19069,19073,19074,19077,19078,19081,19082,19085],{"className":19061},[5678],[5676,19063,19033],{"className":19064},[6184],[5676,19066,19068],{"className":19067},[7829],"51",[5676,19070,19072],{"className":19071},[7829],"9"," - error: Argument of type ",[5676,19075,18401],{"className":19076},[8861]," cannot be assigned to parameter ",[5676,19079,11098],{"className":19080},[6167]," of type ",[5676,19083,18396],{"className":19084},[8861]," (reportArgumentType)",[6149,19087],{"className":19088},[5678],[6149,19090,19092,19096],{"className":19091},[5678],[5676,19093,19095],{"className":19094},[6184],"2 errors",", 0 warnings, 0 informations",[6149,19098,19100,19101],{"className":19099},[5678],"Completed in ",[5676,19102,19104],{"className":19103},[6167],"0.43s",[6400,19106,19108,19109],{"id":19107},"конфігурація-pyright-pyrightconfigjson","Конфігурація Pyright — ",[5511,19110,19111],{},"pyrightconfig.json",[5667,19113,19116],{"className":19114,"code":19115,"language":7964,"meta":5672,"style":5672},"language-json shiki shiki-themes light-plus dark-plus dark-plus","{\n    \"pythonVersion\": \"3.12\",\n    \"venvPath\": \".\",\n    \"venv\": \".venv\",\n    \"typeCheckingMode\": \"strict\",\n    \"include\": [\"src\", \"tests\"],\n    \"exclude\": [\"**\u002F__pycache__\"],\n    \"reportMissingImports\": true,\n    \"reportMissingTypeStubs\": false,\n    \"reportUnknownVariableType\": false\n}\n",[5511,19117,19118,19123,19136,19148,19160,19172,19191,19203,19214,19225,19235],{"__ignoreMap":5672},[5676,19119,19120],{"class":5678,"line":5679},[5676,19121,19122],{"class":5696},"{\n",[5676,19124,19125,19129,19131,19134],{"class":5678,"line":5686},[5676,19126,19128],{"class":19127},"sLwNe","    \"pythonVersion\"",[5676,19130,5730],{"class":5696},[5676,19132,19133],{"class":5758},"\"3.12\"",[5676,19135,14527],{"class":5696},[5676,19137,19138,19141,19143,19146],{"class":5678,"line":5693},[5676,19139,19140],{"class":19127},"    \"venvPath\"",[5676,19142,5730],{"class":5696},[5676,19144,19145],{"class":5758},"\".\"",[5676,19147,14527],{"class":5696},[5676,19149,19150,19153,19155,19158],{"class":5678,"line":5707},[5676,19151,19152],{"class":19127},"    \"venv\"",[5676,19154,5730],{"class":5696},[5676,19156,19157],{"class":5758},"\".venv\"",[5676,19159,14527],{"class":5696},[5676,19161,19162,19165,19167,19170],{"class":5678,"line":5712},[5676,19163,19164],{"class":19127},"    \"typeCheckingMode\"",[5676,19166,5730],{"class":5696},[5676,19168,19169],{"class":5758},"\"strict\"",[5676,19171,14527],{"class":5696},[5676,19173,19174,19177,19180,19183,19185,19188],{"class":5678,"line":5755},[5676,19175,19176],{"class":19127},"    \"include\"",[5676,19178,19179],{"class":5696},": [",[5676,19181,19182],{"class":5758},"\"src\"",[5676,19184,5737],{"class":5696},[5676,19186,19187],{"class":5758},"\"tests\"",[5676,19189,19190],{"class":5696},"],\n",[5676,19192,19193,19196,19198,19201],{"class":5678,"line":5762},[5676,19194,19195],{"class":19127},"    \"exclude\"",[5676,19197,19179],{"class":5696},[5676,19199,19200],{"class":5758},"\"**\u002F__pycache__\"",[5676,19202,19190],{"class":5696},[5676,19204,19205,19208,19210,19212],{"class":5678,"line":5772},[5676,19206,19207],{"class":19127},"    \"reportMissingImports\"",[5676,19209,5730],{"class":5696},[5676,19211,18478],{"class":5715},[5676,19213,14527],{"class":5696},[5676,19215,19216,19219,19221,19223],{"class":5678,"line":5777},[5676,19217,19218],{"class":19127},"    \"reportMissingTypeStubs\"",[5676,19220,5730],{"class":5696},[5676,19222,18593],{"class":5715},[5676,19224,14527],{"class":5696},[5676,19226,19227,19230,19232],{"class":5678,"line":5807},[5676,19228,19229],{"class":19127},"    \"reportUnknownVariableType\"",[5676,19231,5730],{"class":5696},[5676,19233,19234],{"class":5715},"false\n",[5676,19236,19237],{"class":5678,"line":5813},[5676,19238,6544],{"class":5696},[5507,19240,19241,19242,6410],{},"Або у ",[5511,19243,13745],{},[5667,19245,19247],{"className":14149,"code":19246,"language":14151,"meta":5672,"style":5672},"[tool.pyright]\npythonVersion = \"3.12\"\nvenvPath = \".\"\nvenv = \".venv\"\ntypeCheckingMode = \"strict\"\ninclude = [\"src\"]\nexclude = [\"**\u002F__pycache__\"]\n",[5511,19248,19249,19254,19263,19273,19282,19292,19302],{"__ignoreMap":5672},[5676,19250,19251],{"class":5678,"line":5679},[5676,19252,19253],{"class":5696},"[tool.pyright]\n",[5676,19255,19256,19259,19261],{"class":5678,"line":5686},[5676,19257,19258],{"class":5726},"pythonVersion",[5676,19260,10984],{"class":5696},[5676,19262,18468],{"class":5758},[5676,19264,19265,19268,19270],{"class":5678,"line":5693},[5676,19266,19267],{"class":5726},"venvPath",[5676,19269,10984],{"class":5696},[5676,19271,19272],{"class":5758},"\".\"\n",[5676,19274,19275,19277,19279],{"class":5678,"line":5707},[5676,19276,12937],{"class":5726},[5676,19278,10984],{"class":5696},[5676,19280,19281],{"class":5758},"\".venv\"\n",[5676,19283,19284,19287,19289],{"class":5678,"line":5712},[5676,19285,19286],{"class":5726},"typeCheckingMode",[5676,19288,10984],{"class":5696},[5676,19290,19291],{"class":5758},"\"strict\"\n",[5676,19293,19294,19296,19298,19300],{"class":5678,"line":5755},[5676,19295,16135],{"class":5726},[5676,19297,11003],{"class":5696},[5676,19299,19182],{"class":5758},[5676,19301,8460],{"class":5696},[5676,19303,19304,19307,19309,19311],{"class":5678,"line":5762},[5676,19305,19306],{"class":5726},"exclude",[5676,19308,11003],{"class":5696},[5676,19310,19200],{"class":5758},[5676,19312,8460],{"class":5696},[6400,19314,19316],{"id":19315},"порівняння-mypy-vs-pyright","Порівняння mypy vs Pyright",[10245,19318,19319,19330],{},[10248,19320,19321],{},[10251,19322,19323,19326,19328],{},[10254,19324,19325],{},"Характеристика",[10254,19327,16271],{},[10254,19329,18109],{},[10265,19331,19332,19343,19356,19368,19381,19393,19406,19419],{},[10251,19333,19334,19339,19341],{},[10270,19335,19336],{},[5519,19337,19338],{},"Мова реалізації",[10270,19340,2874],{},[10270,19342,2633],{},[10251,19344,19345,19350,19353],{},[10270,19346,19347],{},[5519,19348,19349],{},"Швидкість",[10270,19351,19352],{},"⚠️ Повільніший на великих проектах",[10270,19354,19355],{},"⚡ Значно швидший, інкрементальний",[10251,19357,19358,19363,19366],{},[10270,19359,19360],{},[5519,19361,19362],{},"Строгість",[10270,19364,19365],{},"✅ Налаштовувана",[10270,19367,19365],{},[10251,19369,19370,19375,19378],{},[10270,19371,19372],{},[5519,19373,19374],{},"IDE-інтеграція",[10270,19376,19377],{},"PyCharm, VSCode (mypy extension)",[10270,19379,19380],{},"VSCode (Pylance базується на Pyright)",[10251,19382,19383,19388,19391],{},[10270,19384,19385],{},[5519,19386,19387],{},"Підтримка стандартів",[10270,19389,19390],{},"✅ PEP 484, 526, 544...",[10270,19392,19390],{},[10251,19394,19395,19400,19403],{},[10270,19396,19397],{},[5519,19398,19399],{},"Plugins",[10270,19401,19402],{},"✅ Є (Django, SQLAlchemy)",[10270,19404,19405],{},"⚠️ Менше plugins",[10251,19407,19408,19413,19416],{},[10270,19409,19410],{},[5519,19411,19412],{},"CI\u002FCD",[10270,19414,19415],{},"✅ Стандарт де-факто",[10270,19417,19418],{},"✅ Зростає",[10251,19420,19421,19426,19429],{},[10270,19422,19423],{},[5519,19424,19425],{},"Рекомендація",[10270,19427,19428],{},"Зрілі проекти, Django, MLops",[10270,19430,19431],{},"FastAPI, нові проекти, VSCode-workflow",[12399,19433,19434,19436,19437,19439,19440,5737,19443,6467],{},[5519,19435,2981],{}," офіційно рекомендує Pyright (через Pylance у VSCode). ",[5519,19438,7992],{}," та більшість MLops-інструментів — mypy з відповідними plugin-ами (",[5511,19441,19442],{},"django-stubs",[5511,19444,19445],{},"sqlalchemy-stubs",[6400,19447,19449,19450],{"id":19448},"інтеграція-у-workflow-з-uv","Інтеграція у workflow з ",[5511,19451,13755],{},[5667,19453,19455],{"className":13161,"code":19454,"language":13163,"meta":5672,"style":5672},"# Додавання аналізаторів у dev-залежності\nuv add --dev mypy pyright\n\n# Запуск у CI\u002FCD або pre-commit\nuv run mypy .\nuv run pyright .\n\n# Часто використовують разом з ruff (лінтер)\nuv add --dev ruff\nuv run ruff check .\nuv run ruff format .\n",[5511,19456,19457,19462,19474,19478,19483,19493,19503,19507,19512,19522,19534],{"__ignoreMap":5672},[5676,19458,19459],{"class":5678,"line":5679},[5676,19460,19461],{"class":5682},"# Додавання аналізаторів у dev-залежності\n",[5676,19463,19464,19466,19468,19470,19472],{"class":5678,"line":5686},[5676,19465,13755],{"class":5719},[5676,19467,5720],{"class":5758},[5676,19469,14302],{"class":5715},[5676,19471,15302],{"class":5758},[5676,19473,18961],{"class":5758},[5676,19475,19476],{"class":5678,"line":5693},[5676,19477,5690],{"emptyLinePlaceholder":5689},[5676,19479,19480],{"class":5678,"line":5707},[5676,19481,19482],{"class":5682},"# Запуск у CI\u002FCD або pre-commit\n",[5676,19484,19485,19487,19489,19491],{"class":5678,"line":5712},[5676,19486,13755],{"class":5719},[5676,19488,14606],{"class":5758},[5676,19490,15302],{"class":5758},[5676,19492,14676],{"class":5758},[5676,19494,19495,19497,19499,19501],{"class":5678,"line":5755},[5676,19496,13755],{"class":5719},[5676,19498,14606],{"class":5758},[5676,19500,18973],{"class":5758},[5676,19502,14676],{"class":5758},[5676,19504,19505],{"class":5678,"line":5762},[5676,19506,5690],{"emptyLinePlaceholder":5689},[5676,19508,19509],{"class":5678,"line":5772},[5676,19510,19511],{"class":5682},"# Часто використовують разом з ruff (лінтер)\n",[5676,19513,19514,19516,19518,19520],{"class":5678,"line":5777},[5676,19515,13755],{"class":5719},[5676,19517,5720],{"class":5758},[5676,19519,14302],{"class":5715},[5676,19521,14971],{"class":5758},[5676,19523,19524,19526,19528,19530,19532],{"class":5678,"line":5807},[5676,19525,13755],{"class":5719},[5676,19527,14606],{"class":5758},[5676,19529,14311],{"class":5758},[5676,19531,14673],{"class":5758},[5676,19533,14676],{"class":5758},[5676,19535,19536,19538,19540,19542,19545],{"class":5678,"line":5813},[5676,19537,13755],{"class":5719},[5676,19539,14606],{"class":5758},[5676,19541,14311],{"class":5758},[5676,19543,19544],{"class":5758}," format",[5676,19546,14676],{"class":5758},[6400,19548,19550,19552],{"id":19549},"pyprojecttoml-повна-конфігурація-типового-проекту",[5511,19551,13745],{}," — повна конфігурація типового проекту",[5667,19554,19556],{"className":14149,"code":19555,"language":14151,"meta":5672,"style":5672},"[project]\nname = \"my-service\"\nversion = \"0.1.0\"\nrequires-python = \">=3.12\"\ndependencies = [\"fastapi>=0.115\", \"sqlalchemy>=2.0\"]\n\n[dependency-groups]\ndev = [\"mypy>=1.13\", \"pyright>=1.1\", \"ruff>=0.8\", \"pytest>=8.0\"]\n\n[tool.mypy]\npython_version = \"3.12\"\nstrict = true\nignore_missing_imports = true\n\n[tool.pyright]\npythonVersion = \"3.12\"\ntypeCheckingMode = \"basic\"\nvenvPath = \".\"\nvenv = \".venv\"\n\n[tool.ruff]\nline-length = 88\ntarget-version = \"py312\"\n\n[tool.ruff.lint]\nselect = [\"E\", \"F\", \"I\", \"UP\"]\n",[5511,19557,19558,19562,19570,19578,19586,19602,19606,19610,19636,19640,19644,19652,19661,19669,19673,19677,19685,19694,19702,19710,19714,19719,19729,19739,19743,19748],{"__ignoreMap":5672},[5676,19559,19560],{"class":5678,"line":5679},[5676,19561,14163],{"class":5696},[5676,19563,19564,19566,19568],{"class":5678,"line":5686},[5676,19565,11607],{"class":5726},[5676,19567,10984],{"class":5696},[5676,19569,16087],{"class":5758},[5676,19571,19572,19574,19576],{"class":5678,"line":5693},[5676,19573,13013],{"class":5726},[5676,19575,10984],{"class":5696},[5676,19577,14181],{"class":5758},[5676,19579,19580,19582,19584],{"class":5678,"line":5707},[5676,19581,14206],{"class":5726},[5676,19583,10984],{"class":5696},[5676,19585,14211],{"class":5758},[5676,19587,19588,19590,19592,19595,19597,19600],{"class":5678,"line":5712},[5676,19589,14216],{"class":5726},[5676,19591,11003],{"class":5696},[5676,19593,19594],{"class":5758},"\"fastapi>=0.115\"",[5676,19596,5737],{"class":5696},[5676,19598,19599],{"class":5758},"\"sqlalchemy>=2.0\"",[5676,19601,8460],{"class":5696},[5676,19603,19604],{"class":5678,"line":5755},[5676,19605,5690],{"emptyLinePlaceholder":5689},[5676,19607,19608],{"class":5678,"line":5762},[5676,19609,14547],{"class":5696},[5676,19611,19612,19614,19616,19619,19621,19624,19626,19629,19631,19634],{"class":5678,"line":5772},[5676,19613,14552],{"class":5726},[5676,19615,11003],{"class":5696},[5676,19617,19618],{"class":5758},"\"mypy>=1.13\"",[5676,19620,5737],{"class":5696},[5676,19622,19623],{"class":5758},"\"pyright>=1.1\"",[5676,19625,5737],{"class":5696},[5676,19627,19628],{"class":5758},"\"ruff>=0.8\"",[5676,19630,5737],{"class":5696},[5676,19632,19633],{"class":5758},"\"pytest>=8.0\"",[5676,19635,8460],{"class":5696},[5676,19637,19638],{"class":5678,"line":5777},[5676,19639,5690],{"emptyLinePlaceholder":5689},[5676,19641,19642],{"class":5678,"line":5807},[5676,19643,18458],{"class":5696},[5676,19645,19646,19648,19650],{"class":5678,"line":5813},[5676,19647,18463],{"class":5726},[5676,19649,10984],{"class":5696},[5676,19651,18468],{"class":5758},[5676,19653,19654,19656,19658],{"class":5678,"line":5821},[5676,19655,18473],{"class":5726},[5676,19657,10984],{"class":5696},[5676,19659,19660],{"class":5715},"true\n",[5676,19662,19663,19665,19667],{"class":5678,"line":5826},[5676,19664,18552],{"class":5726},[5676,19666,10984],{"class":5696},[5676,19668,19660],{"class":5715},[5676,19670,19671],{"class":5678,"line":5856},[5676,19672,5690],{"emptyLinePlaceholder":5689},[5676,19674,19675],{"class":5678,"line":5862},[5676,19676,19253],{"class":5696},[5676,19678,19679,19681,19683],{"class":5678,"line":5870},[5676,19680,19258],{"class":5726},[5676,19682,10984],{"class":5696},[5676,19684,18468],{"class":5758},[5676,19686,19687,19689,19691],{"class":5678,"line":5875},[5676,19688,19286],{"class":5726},[5676,19690,10984],{"class":5696},[5676,19692,19693],{"class":5758},"\"basic\"\n",[5676,19695,19696,19698,19700],{"class":5678,"line":5898},[5676,19697,19267],{"class":5726},[5676,19699,10984],{"class":5696},[5676,19701,19272],{"class":5758},[5676,19703,19704,19706,19708],{"class":5678,"line":5904},[5676,19705,12937],{"class":5726},[5676,19707,10984],{"class":5696},[5676,19709,19281],{"class":5758},[5676,19711,19712],{"class":5678,"line":5915},[5676,19713,5690],{"emptyLinePlaceholder":5689},[5676,19715,19716],{"class":5678,"line":5920},[5676,19717,19718],{"class":5696},"[tool.ruff]\n",[5676,19720,19721,19724,19726],{"class":5678,"line":5941},[5676,19722,19723],{"class":5726},"line-length",[5676,19725,10984],{"class":5696},[5676,19727,19728],{"class":5700},"88\n",[5676,19730,19731,19734,19736],{"class":5678,"line":5947},[5676,19732,19733],{"class":5726},"target-version",[5676,19735,10984],{"class":5696},[5676,19737,19738],{"class":5758},"\"py312\"\n",[5676,19740,19741],{"class":5678,"line":5953},[5676,19742,5690],{"emptyLinePlaceholder":5689},[5676,19744,19745],{"class":5678,"line":5959},[5676,19746,19747],{"class":5696},"[tool.ruff.lint]\n",[5676,19749,19750,19753,19755,19758,19760,19763,19765,19768,19770,19773],{"class":5678,"line":5964},[5676,19751,19752],{"class":5726},"select",[5676,19754,11003],{"class":5696},[5676,19756,19757],{"class":5758},"\"E\"",[5676,19759,5737],{"class":5696},[5676,19761,19762],{"class":5758},"\"F\"",[5676,19764,5737],{"class":5696},[5676,19766,19767],{"class":5758},"\"I\"",[5676,19769,5737],{"class":5696},[5676,19771,19772],{"class":5758},"\"UP\"",[5676,19774,8460],{"class":5696},[5574,19776],{},[5581,19778,19780,19781,19783,19784,19786,19787,19786,19789],{"id":19779},"порівняльна-таблиця-venvpip-vs-uv-vs-poetry","Порівняльна таблиця: ",[5511,19782,12937],{},"+",[5511,19785,8268],{}," vs ",[5511,19788,13755],{},[5511,19790,13825],{},[10245,19792,19793,19814],{},[10248,19794,19795],{},[10251,19796,19797,19800,19806,19810],{},[10254,19798,19799],{},"Можливість",[10254,19801,19802,13762,19804],{},[5511,19803,12937],{},[5511,19805,8268],{},[10254,19807,19808],{},[5511,19809,13755],{},[10254,19811,19812],{},[5511,19813,13825],{},[10265,19815,19816,19832,19851,19865,19879,19897,19911,19927,19942],{},[10251,19817,19818,19823,19826,19829],{},[10270,19819,19820],{},[5519,19821,19822],{},"Швидкість встановлення",[10270,19824,19825],{},"🐢 Базова",[10270,19827,19828],{},"⚡ 10–100x швидше",[10270,19830,19831],{},"🐇 Швидша за pip",[10251,19833,19834,19839,19842,19847],{},[10270,19835,19836],{},[5519,19837,19838],{},"Lockfile",[10270,19840,19841],{},"❌ Немає (лише freeze)",[10270,19843,19844,19845],{},"✅ ",[5511,19846,13897],{},[10270,19848,19844,19849],{},[5511,19850,16795],{},[10251,19852,19853,19857,19859,19862],{},[10270,19854,19855],{},[5519,19856,14724],{},[10270,19858,17867],{},[10270,19860,19861],{},"✅ Вбудовано",[10270,19863,19864],{},"❌ Потрібен pyenv",[10251,19866,19867,19871,19873,19876],{},[10270,19868,19869],{},[5519,19870,15799],{},[10270,19872,17867],{},[10270,19874,19875],{},"✅ dev groups",[10270,19877,19878],{},"✅ dev\u002Ftest\u002Fdocs groups",[10251,19880,19881,19886,19889,19893],{},[10270,19882,19883],{},[5519,19884,19885],{},"Автоматичне середовище",[10270,19887,19888],{},"❌ Вручну",[10270,19890,19844,19891],{},[5511,19892,14588],{},[10270,19894,19844,19895],{},[5511,19896,16621],{},[10251,19898,19899,19903,19906,19909],{},[10270,19900,19901],{},[5519,19902,15807],{},[10270,19904,19905],{},"❌ Потрібен twine",[10270,19907,19908],{},"❌ Не підтримується",[10270,19910,19861],{},[10251,19912,19913,19918,19921,19924],{},[10270,19914,19915],{},[5519,19916,19917],{},"Сумісність зі стандартами",[10270,19919,19920],{},"✅ Стандарт",[10270,19922,19923],{},"✅ PEP 621",[10270,19925,19926],{},"⚠️ Частково PEP 621",[10251,19928,19929,19934,19937,19939],{},[10270,19930,19931],{},[5519,19932,19933],{},"Навчальна крива",[10270,19935,19936],{},"✅ Проста",[10270,19938,19936],{},[10270,19940,19941],{},"⚠️ Середня",[10251,19943,19944,19949,19951,19954],{},[10270,19945,19946],{},[5519,19947,19948],{},"Зрілість і поширеність",[10270,19950,19920],{},[10270,19952,19953],{},"🆕 Активно зростає",[10270,19955,19956],{},"✅ Широко у production",[5524,19958,19959,19964,19968],{},[5527,19960,19963],{"icon":19961,"title":19962},"i-heroicons-academic-cap","Обирайте venv + pip","Для навчання, простих скриптів, проектів де важлива максимальна сумісність зі стандартними інструментами. Це базовий рівень, який треба знати всім.",[5527,19965,19967],{"icon":13865,"title":19966},"Обирайте uv","Для нових проектів будь-якого розміру. Особливо — для CI\u002FCD, де швидкість встановлення залежностей критична. Найкращий вибір для 2024+ проектів.",[5527,19969,19972],{"icon":19970,"title":19971},"i-heroicons-book-open","Обирайте Poetry","Для бібліотек, що публікуються на PyPI, або для команд що вже використовують Poetry і мають налагоджений workflow. Відмінна підтримка у більшості IDE.",[5574,19974],{},[5502,19976,19978],{"id":19977},"частина-v-стандартна-бібліотека-батарейки-у-комплекті","Частина V: Стандартна бібліотека — «Батарейки у комплекті»",[5581,19980,19982],{"id":19981},"філософія-batteries-included","Філософія \"Batteries Included\"",[5507,19984,19985,19986,19989],{},"Одна з найсильніших сторін Python — філософія ",[5519,19987,19988],{},"\"batteries included\" (батарейки у комплекті)",". Це означає, що разом з інтерпретатором ви отримуєте величезний набір готових, оптимізованих та протестованих модулів стандартної бібліотеки. Вони покривають більшість повсякденних завдань розробника: від математичних обчислень до мережевої взаємодії та роботи з файловою системою.",[5507,19991,19992],{},"Використання стандартної бібліотеки гарантує:",[7251,19994,19995,20001,20007],{},[5621,19996,19997,20000],{},[5519,19998,19999],{},"Портативність",": ваш код працюватиме на будь-якому комп'ютері, де встановлено Python, без необхідності встановлювати сторонні залежності.",[5621,20002,20003,20006],{},[5519,20004,20005],{},"Стабільність",": ці модулі підтримуються та оновлюються ядром команди розробників Python.",[5621,20008,20009,20011],{},[5519,20010,19349],{},": багато критичних частин стандартної бібліотеки написані на мові C для максимальної продуктивності.",[5507,20013,20014],{},"Розглянемо ключові модулі, які формують основу розробки на Python.",[5574,20016],{},[5581,20018,20020,20021],{"id":20019},"математичні-обчислення-модуль-math","Математичні обчислення: модуль ",[5511,20022,20023],{},"math",[5507,20025,20026,20027,20029,20030,6467],{},"Модуль ",[5511,20028,20023],{}," надає доступ до математичних функцій та констант, визначених стандартом мови C. Він працює виключно з дійсними числами (для комплексних чисел існує окремий модуль ",[5511,20031,20032],{},"cmath",[6400,20034,20036],{"id":20035},"константи-та-округлення","Константи та округлення",[5667,20038,20040],{"className":5669,"code":20039,"language":5671,"meta":5672,"style":5672},"import math\n\n# Ключові константи\nprint(f\"pi: {math.pi}\")      # 3.141592653589793\nprint(f\"e: {math.e}\")        # 2.718281828459045\nprint(f\"inf: {math.inf}\")    # Позитивна нескінченність\nprint(f\"nan: {math.nan}\")    # Not a Number (не число)\n\n# Стратегії округлення\nvalue = 5.67\nprint(f\"Округлення вгору (ceil): {math.ceil(value)}\")      # 6\nprint(f\"Округлення вниз (floor): {math.floor(value)}\")     # 5\nprint(f\"Відкидання дробової частини (trunc): {math.trunc(value)}\")  # 5\n",[5511,20041,20042,20048,20052,20057,20083,20108,20134,20159,20163,20168,20176,20201,20227],{"__ignoreMap":5672},[5676,20043,20044,20046],{"class":5678,"line":5679},[5676,20045,6018],{"class":5765},[5676,20047,6615],{"class":5696},[5676,20049,20050],{"class":5678,"line":5686},[5676,20051,5690],{"emptyLinePlaceholder":5689},[5676,20053,20054],{"class":5678,"line":5693},[5676,20055,20056],{"class":5682},"# Ключові константи\n",[5676,20058,20059,20061,20063,20065,20068,20070,20073,20075,20077,20080],{"class":5678,"line":5707},[5676,20060,6068],{"class":5719},[5676,20062,5723],{"class":5696},[5676,20064,6073],{"class":5715},[5676,20066,20067],{"class":5758},"\"pi: ",[5676,20069,6079],{"class":5715},[5676,20071,20072],{"class":5696},"math.pi",[5676,20074,6085],{"class":5715},[5676,20076,6088],{"class":5758},[5676,20078,20079],{"class":5696},")      ",[5676,20081,20082],{"class":5682},"# 3.141592653589793\n",[5676,20084,20085,20087,20089,20091,20094,20096,20099,20101,20103,20105],{"class":5678,"line":5712},[5676,20086,6068],{"class":5719},[5676,20088,5723],{"class":5696},[5676,20090,6073],{"class":5715},[5676,20092,20093],{"class":5758},"\"e: ",[5676,20095,6079],{"class":5715},[5676,20097,20098],{"class":5696},"math.e",[5676,20100,6085],{"class":5715},[5676,20102,6088],{"class":5758},[5676,20104,8523],{"class":5696},[5676,20106,20107],{"class":5682},"# 2.718281828459045\n",[5676,20109,20110,20112,20114,20116,20119,20121,20124,20126,20128,20131],{"class":5678,"line":5755},[5676,20111,6068],{"class":5719},[5676,20113,5723],{"class":5696},[5676,20115,6073],{"class":5715},[5676,20117,20118],{"class":5758},"\"inf: ",[5676,20120,6079],{"class":5715},[5676,20122,20123],{"class":5696},"math.inf",[5676,20125,6085],{"class":5715},[5676,20127,6088],{"class":5758},[5676,20129,20130],{"class":5696},")    ",[5676,20132,20133],{"class":5682},"# Позитивна нескінченність\n",[5676,20135,20136,20138,20140,20142,20145,20147,20150,20152,20154,20156],{"class":5678,"line":5762},[5676,20137,6068],{"class":5719},[5676,20139,5723],{"class":5696},[5676,20141,6073],{"class":5715},[5676,20143,20144],{"class":5758},"\"nan: ",[5676,20146,6079],{"class":5715},[5676,20148,20149],{"class":5696},"math.nan",[5676,20151,6085],{"class":5715},[5676,20153,6088],{"class":5758},[5676,20155,20130],{"class":5696},[5676,20157,20158],{"class":5682},"# Not a Number (не число)\n",[5676,20160,20161],{"class":5678,"line":5772},[5676,20162,5690],{"emptyLinePlaceholder":5689},[5676,20164,20165],{"class":5678,"line":5777},[5676,20166,20167],{"class":5682},"# Стратегії округлення\n",[5676,20169,20170,20173],{"class":5678,"line":5807},[5676,20171,20172],{"class":5696},"value = ",[5676,20174,20175],{"class":5700},"5.67\n",[5676,20177,20178,20180,20182,20184,20187,20189,20192,20194,20196,20198],{"class":5678,"line":5813},[5676,20179,6068],{"class":5719},[5676,20181,5723],{"class":5696},[5676,20183,6073],{"class":5715},[5676,20185,20186],{"class":5758},"\"Округлення вгору (ceil): ",[5676,20188,6079],{"class":5715},[5676,20190,20191],{"class":5696},"math.ceil(value)",[5676,20193,6085],{"class":5715},[5676,20195,6088],{"class":5758},[5676,20197,20079],{"class":5696},[5676,20199,20200],{"class":5682},"# 6\n",[5676,20202,20203,20205,20207,20209,20212,20214,20217,20219,20221,20224],{"class":5678,"line":5821},[5676,20204,6068],{"class":5719},[5676,20206,5723],{"class":5696},[5676,20208,6073],{"class":5715},[5676,20210,20211],{"class":5758},"\"Округлення вниз (floor): ",[5676,20213,6079],{"class":5715},[5676,20215,20216],{"class":5696},"math.floor(value)",[5676,20218,6085],{"class":5715},[5676,20220,6088],{"class":5758},[5676,20222,20223],{"class":5696},")     ",[5676,20225,20226],{"class":5682},"# 5\n",[5676,20228,20229,20231,20233,20235,20238,20240,20243,20245,20247,20249],{"class":5678,"line":5826},[5676,20230,6068],{"class":5719},[5676,20232,5723],{"class":5696},[5676,20234,6073],{"class":5715},[5676,20236,20237],{"class":5758},"\"Відкидання дробової частини (trunc): ",[5676,20239,6079],{"class":5715},[5676,20241,20242],{"class":5696},"math.trunc(value)",[5676,20244,6085],{"class":5715},[5676,20246,6088],{"class":5758},[5676,20248,7241],{"class":5696},[5676,20250,20226],{"class":5682},[6400,20252,20254],{"id":20253},"степені-корені-та-логарифми","Степені, корені та логарифми",[5667,20256,20258],{"className":5669,"code":20257,"language":5671,"meta":5672,"style":5672},"# Квадратний корінь\nprint(math.sqrt(25))  # 5.0 (завжди повертає float)\n\n# Найбільший спільний дільник (НСД) та найменше спільне кратне (НСК)\nprint(math.gcd(48, 64))  # 16\nprint(math.lcm(48, 64))  # 192 (доступно в Python 3.9+)\n\n# Логарифми\nprint(math.log(math.e))  # 1.0 (натуральний логарифм)\nprint(math.log2(1024))   # 10.0\nprint(math.log10(1000))  # 3.0\n",[5511,20259,20260,20265,20280,20284,20289,20309,20327,20331,20336,20346,20361],{"__ignoreMap":5672},[5676,20261,20262],{"class":5678,"line":5679},[5676,20263,20264],{"class":5682},"# Квадратний корінь\n",[5676,20266,20267,20269,20272,20274,20277],{"class":5678,"line":5686},[5676,20268,6068],{"class":5719},[5676,20270,20271],{"class":5696},"(math.sqrt(",[5676,20273,18422],{"class":5700},[5676,20275,20276],{"class":5696},"))  ",[5676,20278,20279],{"class":5682},"# 5.0 (завжди повертає float)\n",[5676,20281,20282],{"class":5678,"line":5693},[5676,20283,5690],{"emptyLinePlaceholder":5689},[5676,20285,20286],{"class":5678,"line":5707},[5676,20287,20288],{"class":5682},"# Найбільший спільний дільник (НСД) та найменше спільне кратне (НСК)\n",[5676,20290,20291,20293,20296,20299,20301,20304,20306],{"class":5678,"line":5712},[5676,20292,6068],{"class":5719},[5676,20294,20295],{"class":5696},"(math.gcd(",[5676,20297,20298],{"class":5700},"48",[5676,20300,5737],{"class":5696},[5676,20302,20303],{"class":5700},"64",[5676,20305,20276],{"class":5696},[5676,20307,20308],{"class":5682},"# 16\n",[5676,20310,20311,20313,20316,20318,20320,20322,20324],{"class":5678,"line":5755},[5676,20312,6068],{"class":5719},[5676,20314,20315],{"class":5696},"(math.lcm(",[5676,20317,20298],{"class":5700},[5676,20319,5737],{"class":5696},[5676,20321,20303],{"class":5700},[5676,20323,20276],{"class":5696},[5676,20325,20326],{"class":5682},"# 192 (доступно в Python 3.9+)\n",[5676,20328,20329],{"class":5678,"line":5762},[5676,20330,5690],{"emptyLinePlaceholder":5689},[5676,20332,20333],{"class":5678,"line":5772},[5676,20334,20335],{"class":5682},"# Логарифми\n",[5676,20337,20338,20340,20343],{"class":5678,"line":5777},[5676,20339,6068],{"class":5719},[5676,20341,20342],{"class":5696},"(math.log(math.e))  ",[5676,20344,20345],{"class":5682},"# 1.0 (натуральний логарифм)\n",[5676,20347,20348,20350,20353,20356,20358],{"class":5678,"line":5807},[5676,20349,6068],{"class":5719},[5676,20351,20352],{"class":5696},"(math.log2(",[5676,20354,20355],{"class":5700},"1024",[5676,20357,9248],{"class":5696},[5676,20359,20360],{"class":5682},"# 10.0\n",[5676,20362,20363,20365,20368,20371,20373],{"class":5678,"line":5813},[5676,20364,6068],{"class":5719},[5676,20366,20367],{"class":5696},"(math.log10(",[5676,20369,20370],{"class":5700},"1000",[5676,20372,20276],{"class":5696},[5676,20374,20375],{"class":5682},"# 3.0\n",[13141,20377,20378,20379,20382,20383,20385,20386,20388,20389,20392,20393,20396,20397,20400,20401,20403,20404,20400,20407,6467],{},"Для звичайного округлення до найближчого цілого використовуйте вбудовану функцію ",[5511,20380,20381],{},"round()",", яка не потребує імпорту ",[5511,20384,20023],{},". Але пам'ятайте, що ",[5511,20387,20381],{}," у Python використовує ",[5519,20390,20391],{},"банківське округлення"," (округлює до найближчого парного числа при закінченні на ",[5511,20394,20395],{},".5",", наприклад ",[5511,20398,20399],{},"round(2.5)"," буде ",[5511,20402,6322],{},", а ",[5511,20405,20406],{},"round(3.5)",[5511,20408,20409],{},"4",[5574,20411],{},[5581,20413,20415,20416],{"id":20414},"псевдовипадковість-модуль-random","Псевдовипадковість: модуль ",[5511,20417,20418],{},"random",[5507,20420,20026,20421,20423,20424,20427,20428,20431,20432,6467],{},[5511,20422,20418],{}," генерує псевдовипадкові числа за допомогою алгоритму ",[5519,20425,20426],{},"Вихру Мерсенна (Mersenne Twister)",". Він підходить для моделювання, симуляцій та ігор, але ",[5519,20429,20430],{},"не є безпечним для криптографії"," (для безпечних токенів або паролів використовуйте модуль ",[5511,20433,20434],{},"secrets",[6400,20436,20438],{"id":20437},"генерація-значень","Генерація значень",[5667,20440,20442],{"className":5669,"code":20441,"language":5671,"meta":5672,"style":5672},"import random\n\n# Дійсне число від 0.0 до 1.0\nprint(f\"random(): {random.random()}\")\n\n# Ціле число в діапазоні [1, 10] включно\nprint(f\"randint(1, 10): {random.randint(1, 10)}\")\n\n# Дійсне число в діапазоні [1.5, 9.5]\nprint(f\"uniform(1.5, 9.5): {random.uniform(1.5, 9.5)}\")\n\n# Випадкове парне число від 0 до 100\nprint(f\"randrange(0, 101, 2): {random.randrange(0, 101, 2)}\")\n",[5511,20443,20444,20451,20455,20460,20482,20486,20491,20521,20525,20530,20562,20566,20571],{"__ignoreMap":5672},[5676,20445,20446,20448],{"class":5678,"line":5679},[5676,20447,6018],{"class":5765},[5676,20449,20450],{"class":5696}," random\n",[5676,20452,20453],{"class":5678,"line":5686},[5676,20454,5690],{"emptyLinePlaceholder":5689},[5676,20456,20457],{"class":5678,"line":5693},[5676,20458,20459],{"class":5682},"# Дійсне число від 0.0 до 1.0\n",[5676,20461,20462,20464,20466,20468,20471,20473,20476,20478,20480],{"class":5678,"line":5707},[5676,20463,6068],{"class":5719},[5676,20465,5723],{"class":5696},[5676,20467,6073],{"class":5715},[5676,20469,20470],{"class":5758},"\"random(): ",[5676,20472,6079],{"class":5715},[5676,20474,20475],{"class":5696},"random.random()",[5676,20477,6085],{"class":5715},[5676,20479,6088],{"class":5758},[5676,20481,6049],{"class":5696},[5676,20483,20484],{"class":5678,"line":5712},[5676,20485,5690],{"emptyLinePlaceholder":5689},[5676,20487,20488],{"class":5678,"line":5755},[5676,20489,20490],{"class":5682},"# Ціле число в діапазоні [1, 10] включно\n",[5676,20492,20493,20495,20497,20499,20502,20504,20507,20509,20511,20513,20515,20517,20519],{"class":5678,"line":5762},[5676,20494,6068],{"class":5719},[5676,20496,5723],{"class":5696},[5676,20498,6073],{"class":5715},[5676,20500,20501],{"class":5758},"\"randint(1, 10): ",[5676,20503,6079],{"class":5715},[5676,20505,20506],{"class":5696},"random.randint(",[5676,20508,7174],{"class":5700},[5676,20510,5737],{"class":5696},[5676,20512,6041],{"class":5700},[5676,20514,5631],{"class":5696},[5676,20516,6085],{"class":5715},[5676,20518,6088],{"class":5758},[5676,20520,6049],{"class":5696},[5676,20522,20523],{"class":5678,"line":5772},[5676,20524,5690],{"emptyLinePlaceholder":5689},[5676,20526,20527],{"class":5678,"line":5777},[5676,20528,20529],{"class":5682},"# Дійсне число в діапазоні [1.5, 9.5]\n",[5676,20531,20532,20534,20536,20538,20541,20543,20546,20549,20551,20554,20556,20558,20560],{"class":5678,"line":5807},[5676,20533,6068],{"class":5719},[5676,20535,5723],{"class":5696},[5676,20537,6073],{"class":5715},[5676,20539,20540],{"class":5758},"\"uniform(1.5, 9.5): ",[5676,20542,6079],{"class":5715},[5676,20544,20545],{"class":5696},"random.uniform(",[5676,20547,20548],{"class":5700},"1.5",[5676,20550,5737],{"class":5696},[5676,20552,20553],{"class":5700},"9.5",[5676,20555,5631],{"class":5696},[5676,20557,6085],{"class":5715},[5676,20559,6088],{"class":5758},[5676,20561,6049],{"class":5696},[5676,20563,20564],{"class":5678,"line":5813},[5676,20565,5690],{"emptyLinePlaceholder":5689},[5676,20567,20568],{"class":5678,"line":5821},[5676,20569,20570],{"class":5682},"# Випадкове парне число від 0 до 100\n",[5676,20572,20573,20575,20577,20579,20582,20584,20587,20589,20591,20594,20596,20598,20600,20602,20604],{"class":5678,"line":5826},[5676,20574,6068],{"class":5719},[5676,20576,5723],{"class":5696},[5676,20578,6073],{"class":5715},[5676,20580,20581],{"class":5758},"\"randrange(0, 101, 2): ",[5676,20583,6079],{"class":5715},[5676,20585,20586],{"class":5696},"random.randrange(",[5676,20588,8035],{"class":5700},[5676,20590,5737],{"class":5696},[5676,20592,20593],{"class":5700},"101",[5676,20595,5737],{"class":5696},[5676,20597,6322],{"class":5700},[5676,20599,5631],{"class":5696},[5676,20601,6085],{"class":5715},[5676,20603,6088],{"class":5758},[5676,20605,6049],{"class":5696},[6400,20607,20609],{"id":20608},"робота-з-послідовностями","Робота з послідовностями",[5667,20611,20613],{"className":5669,"code":20612,"language":5671,"meta":5672,"style":5672},"cards = [\"Туз\", \"Король\", \"Дама\", \"Валет\", \"10\"]\n\n# Вибір одного випадкового елемента\nprint(f\"Випадкова карта: {random.choice(cards)}\")\n\n# Вибір кількох унікальних елементів (без повторень)\nprint(f\"Роздача на двох: {random.sample(cards, 2)}\")\n\n# Перемішування списку на місці (модифікує оригінал!)\nrandom.shuffle(cards)\nprint(f\"Перемішана колода: {cards}\")\n",[5511,20614,20615,20645,20649,20654,20676,20680,20685,20711,20715,20720,20725],{"__ignoreMap":5672},[5676,20616,20617,20620,20623,20625,20628,20630,20633,20635,20638,20640,20643],{"class":5678,"line":5679},[5676,20618,20619],{"class":5696},"cards = [",[5676,20621,20622],{"class":5758},"\"Туз\"",[5676,20624,5737],{"class":5696},[5676,20626,20627],{"class":5758},"\"Король\"",[5676,20629,5737],{"class":5696},[5676,20631,20632],{"class":5758},"\"Дама\"",[5676,20634,5737],{"class":5696},[5676,20636,20637],{"class":5758},"\"Валет\"",[5676,20639,5737],{"class":5696},[5676,20641,20642],{"class":5758},"\"10\"",[5676,20644,8460],{"class":5696},[5676,20646,20647],{"class":5678,"line":5686},[5676,20648,5690],{"emptyLinePlaceholder":5689},[5676,20650,20651],{"class":5678,"line":5693},[5676,20652,20653],{"class":5682},"# Вибір одного випадкового елемента\n",[5676,20655,20656,20658,20660,20662,20665,20667,20670,20672,20674],{"class":5678,"line":5707},[5676,20657,6068],{"class":5719},[5676,20659,5723],{"class":5696},[5676,20661,6073],{"class":5715},[5676,20663,20664],{"class":5758},"\"Випадкова карта: ",[5676,20666,6079],{"class":5715},[5676,20668,20669],{"class":5696},"random.choice(cards)",[5676,20671,6085],{"class":5715},[5676,20673,6088],{"class":5758},[5676,20675,6049],{"class":5696},[5676,20677,20678],{"class":5678,"line":5712},[5676,20679,5690],{"emptyLinePlaceholder":5689},[5676,20681,20682],{"class":5678,"line":5755},[5676,20683,20684],{"class":5682},"# Вибір кількох унікальних елементів (без повторень)\n",[5676,20686,20687,20689,20691,20693,20696,20698,20701,20703,20705,20707,20709],{"class":5678,"line":5762},[5676,20688,6068],{"class":5719},[5676,20690,5723],{"class":5696},[5676,20692,6073],{"class":5715},[5676,20694,20695],{"class":5758},"\"Роздача на двох: ",[5676,20697,6079],{"class":5715},[5676,20699,20700],{"class":5696},"random.sample(cards, ",[5676,20702,6322],{"class":5700},[5676,20704,5631],{"class":5696},[5676,20706,6085],{"class":5715},[5676,20708,6088],{"class":5758},[5676,20710,6049],{"class":5696},[5676,20712,20713],{"class":5678,"line":5772},[5676,20714,5690],{"emptyLinePlaceholder":5689},[5676,20716,20717],{"class":5678,"line":5777},[5676,20718,20719],{"class":5682},"# Перемішування списку на місці (модифікує оригінал!)\n",[5676,20721,20722],{"class":5678,"line":5807},[5676,20723,20724],{"class":5696},"random.shuffle(cards)\n",[5676,20726,20727,20729,20731,20733,20736,20738,20741,20743,20745],{"class":5678,"line":5813},[5676,20728,6068],{"class":5719},[5676,20730,5723],{"class":5696},[5676,20732,6073],{"class":5715},[5676,20734,20735],{"class":5758},"\"Перемішана колода: ",[5676,20737,6079],{"class":5715},[5676,20739,20740],{"class":5696},"cards",[5676,20742,6085],{"class":5715},[5676,20744,6088],{"class":5758},[5676,20746,6049],{"class":5696},[6400,20748,20750,20751],{"id":20749},"концепція-відтворюваності-randomseed","Концепція відтворюваності: ",[5511,20752,20753],{},"random.seed()",[5507,20755,20756],{},"Алгоритм генерації є математичним, тому якщо задати початкову точку (seed), послідовність \"випадкових\" чисел буде абсолютно ідентичною при кожному запуску.",[5667,20758,20760],{"className":5669,"code":20759,"language":5671,"meta":5672,"style":5672},"random.seed(100)\nprint(random.randint(1, 100))  # Завжди виведе 19\nprint(random.randint(1, 100))  # Завжди виведе 59\n\nrandom.seed(100)  # Скидаємо в ту саму початкову точку\nprint(random.randint(1, 100))  # Знову 19!\n",[5511,20761,20762,20772,20790,20807,20811,20822],{"__ignoreMap":5672},[5676,20763,20764,20767,20770],{"class":5678,"line":5679},[5676,20765,20766],{"class":5696},"random.seed(",[5676,20768,20769],{"class":5700},"100",[5676,20771,6049],{"class":5696},[5676,20773,20774,20776,20779,20781,20783,20785,20787],{"class":5678,"line":5686},[5676,20775,6068],{"class":5719},[5676,20777,20778],{"class":5696},"(random.randint(",[5676,20780,7174],{"class":5700},[5676,20782,5737],{"class":5696},[5676,20784,20769],{"class":5700},[5676,20786,20276],{"class":5696},[5676,20788,20789],{"class":5682},"# Завжди виведе 19\n",[5676,20791,20792,20794,20796,20798,20800,20802,20804],{"class":5678,"line":5693},[5676,20793,6068],{"class":5719},[5676,20795,20778],{"class":5696},[5676,20797,7174],{"class":5700},[5676,20799,5737],{"class":5696},[5676,20801,20769],{"class":5700},[5676,20803,20276],{"class":5696},[5676,20805,20806],{"class":5682},"# Завжди виведе 59\n",[5676,20808,20809],{"class":5678,"line":5707},[5676,20810,5690],{"emptyLinePlaceholder":5689},[5676,20812,20813,20815,20817,20819],{"class":5678,"line":5712},[5676,20814,20766],{"class":5696},[5676,20816,20769],{"class":5700},[5676,20818,7241],{"class":5696},[5676,20820,20821],{"class":5682},"# Скидаємо в ту саму початкову точку\n",[5676,20823,20824,20826,20828,20830,20832,20834,20836],{"class":5678,"line":5755},[5676,20825,6068],{"class":5719},[5676,20827,20778],{"class":5696},[5676,20829,7174],{"class":5700},[5676,20831,5737],{"class":5696},[5676,20833,20769],{"class":5700},[5676,20835,20276],{"class":5696},[5676,20837,20838],{"class":5682},"# Знову 19!\n",[12399,20840,20841,20842,20844],{},"Використовуйте ",[5511,20843,20753],{}," у модульних тестах, коли вам потрібно протестувати логіку, яка залежить від випадкових факторів, щоб забезпечити стабільні та передбачувані результати тестів.",[5574,20846],{},[5581,20848,20850,20851],{"id":20849},"робота-з-часом-модуль-datetime","Робота з часом: модуль ",[5511,20852,7967],{},[5507,20854,20855,20856,20858],{},"Час є однією з найскладніших концепцій у програмуванні через високосні роки, часові пояси та переходи на літній час. Модуль ",[5511,20857,7967],{}," надає класи для обробки дат і часу.",[6400,20860,20862],{"id":20861},"основні-класи","Основні класи",[7251,20864,20865,20871,20877,20883],{},[5621,20866,20867,20870],{},[5511,20868,20869],{},"datetime.date",": представлення дати (рік, місяць, день).",[5621,20872,20873,20876],{},[5511,20874,20875],{},"datetime.time",": представлення часу (година, хвилина, секунда, мікросекунда).",[5621,20878,20879,20882],{},[5511,20880,20881],{},"datetime.datetime",": комбінація дати та часу.",[5621,20884,20885,20888],{},[5511,20886,20887],{},"datetime.timedelta",": тривалість або різниця між двома датами\u002Fчасом.",[6400,20890,20892],{"id":20891},"створення-та-арифметика","Створення та арифметика",[5667,20894,20896],{"className":5669,"code":20895,"language":5671,"meta":5672,"style":5672},"import datetime\n\n# Поточні значення\nnow = datetime.datetime.now()\ntoday = datetime.date.today()\nprint(f\"Зараз: {now}\")\nprint(f\"Сьогодні: {today}\")\n\n# Створення конкретної дати\ndeadline = datetime.datetime(2026, 12, 31, 23, 59, 0)\n\n# Розрахунок різниці (timedelta)\ntime_left = deadline - now\nprint(f\"До дедлайну залишилося: {time_left.days} днів та {time_left.seconds \u002F\u002F 3600} годин\")\n\n# Додавання інтервалу часу\nfuture_date = today + datetime.timedelta(weeks=4)\nprint(f\"Через 4 тижні буде: {future_date}\")\n",[5511,20897,20898,20905,20909,20914,20919,20924,20946,20968,20972,20977,21010,21014,21019,21024,21060,21064,21069,21083],{"__ignoreMap":5672},[5676,20899,20900,20902],{"class":5678,"line":5679},[5676,20901,6018],{"class":5765},[5676,20903,20904],{"class":5696}," datetime\n",[5676,20906,20907],{"class":5678,"line":5686},[5676,20908,5690],{"emptyLinePlaceholder":5689},[5676,20910,20911],{"class":5678,"line":5693},[5676,20912,20913],{"class":5682},"# Поточні значення\n",[5676,20915,20916],{"class":5678,"line":5707},[5676,20917,20918],{"class":5696},"now = datetime.datetime.now()\n",[5676,20920,20921],{"class":5678,"line":5712},[5676,20922,20923],{"class":5696},"today = datetime.date.today()\n",[5676,20925,20926,20928,20930,20932,20935,20937,20940,20942,20944],{"class":5678,"line":5755},[5676,20927,6068],{"class":5719},[5676,20929,5723],{"class":5696},[5676,20931,6073],{"class":5715},[5676,20933,20934],{"class":5758},"\"Зараз: ",[5676,20936,6079],{"class":5715},[5676,20938,20939],{"class":5696},"now",[5676,20941,6085],{"class":5715},[5676,20943,6088],{"class":5758},[5676,20945,6049],{"class":5696},[5676,20947,20948,20950,20952,20954,20957,20959,20962,20964,20966],{"class":5678,"line":5762},[5676,20949,6068],{"class":5719},[5676,20951,5723],{"class":5696},[5676,20953,6073],{"class":5715},[5676,20955,20956],{"class":5758},"\"Сьогодні: ",[5676,20958,6079],{"class":5715},[5676,20960,20961],{"class":5696},"today",[5676,20963,6085],{"class":5715},[5676,20965,6088],{"class":5758},[5676,20967,6049],{"class":5696},[5676,20969,20970],{"class":5678,"line":5772},[5676,20971,5690],{"emptyLinePlaceholder":5689},[5676,20973,20974],{"class":5678,"line":5777},[5676,20975,20976],{"class":5682},"# Створення конкретної дати\n",[5676,20978,20979,20982,20985,20987,20989,20991,20994,20996,20999,21001,21004,21006,21008],{"class":5678,"line":5807},[5676,20980,20981],{"class":5696},"deadline = datetime.datetime(",[5676,20983,20984],{"class":5700},"2026",[5676,20986,5737],{"class":5696},[5676,20988,18391],{"class":5700},[5676,20990,5737],{"class":5696},[5676,20992,20993],{"class":5700},"31",[5676,20995,5737],{"class":5696},[5676,20997,20998],{"class":5700},"23",[5676,21000,5737],{"class":5696},[5676,21002,21003],{"class":5700},"59",[5676,21005,5737],{"class":5696},[5676,21007,8035],{"class":5700},[5676,21009,6049],{"class":5696},[5676,21011,21012],{"class":5678,"line":5813},[5676,21013,5690],{"emptyLinePlaceholder":5689},[5676,21015,21016],{"class":5678,"line":5821},[5676,21017,21018],{"class":5682},"# Розрахунок різниці (timedelta)\n",[5676,21020,21021],{"class":5678,"line":5826},[5676,21022,21023],{"class":5696},"time_left = deadline - now\n",[5676,21025,21026,21028,21030,21032,21035,21037,21040,21042,21045,21047,21050,21053,21055,21058],{"class":5678,"line":5856},[5676,21027,6068],{"class":5719},[5676,21029,5723],{"class":5696},[5676,21031,6073],{"class":5715},[5676,21033,21034],{"class":5758},"\"До дедлайну залишилося: ",[5676,21036,6079],{"class":5715},[5676,21038,21039],{"class":5696},"time_left.days",[5676,21041,6085],{"class":5715},[5676,21043,21044],{"class":5758}," днів та ",[5676,21046,6079],{"class":5715},[5676,21048,21049],{"class":5696},"time_left.seconds \u002F\u002F ",[5676,21051,21052],{"class":5700},"3600",[5676,21054,6085],{"class":5715},[5676,21056,21057],{"class":5758}," годин\"",[5676,21059,6049],{"class":5696},[5676,21061,21062],{"class":5678,"line":5862},[5676,21063,5690],{"emptyLinePlaceholder":5689},[5676,21065,21066],{"class":5678,"line":5870},[5676,21067,21068],{"class":5682},"# Додавання інтервалу часу\n",[5676,21070,21071,21074,21077,21079,21081],{"class":5678,"line":5875},[5676,21072,21073],{"class":5696},"future_date = today + datetime.timedelta(",[5676,21075,21076],{"class":5726},"weeks",[5676,21078,9923],{"class":5696},[5676,21080,20409],{"class":5700},[5676,21082,6049],{"class":5696},[5676,21084,21085,21087,21089,21091,21094,21096,21099,21101,21103],{"class":5678,"line":5898},[5676,21086,6068],{"class":5719},[5676,21088,5723],{"class":5696},[5676,21090,6073],{"class":5715},[5676,21092,21093],{"class":5758},"\"Через 4 тижні буде: ",[5676,21095,6079],{"class":5715},[5676,21097,21098],{"class":5696},"future_date",[5676,21100,6085],{"class":5715},[5676,21102,6088],{"class":5758},[5676,21104,6049],{"class":5696},[6400,21106,21108],{"id":21107},"форматування-та-парсинг","Форматування та парсинг",[5507,21110,21111,21112,21115,21116,21119],{},"Для перетворення часу в рядок використовується метод ",[5511,21113,21114],{},"strftime"," (format time), а для зворотного парсингу з рядка — ",[5511,21117,21118],{},"strptime"," (parse time).",[21121,21122,21123,21202],"code-group",{},[5667,21124,21127],{"className":5669,"code":21125,"filename":21126,"language":5671,"meta":5672,"style":5672},"import datetime\nnow = datetime.datetime.now()\n\n# Використовуємо спеціальні директиви (специфікатори)\nformatted = now.strftime(\"%Y-%m-%d %H:%M:%S\")\nprint(formatted)  # \"2026-06-13 20:30:15\"\n\nhuman_friendly = now.strftime(\"%d %B %Y, (%A)\")\nprint(human_friendly)  # \"13 June 2026, (Saturday)\"\n","Форматування (Time to String)",[5511,21128,21129,21135,21139,21143,21148,21164,21174,21178,21192],{"__ignoreMap":5672},[5676,21130,21131,21133],{"class":5678,"line":5679},[5676,21132,6018],{"class":5765},[5676,21134,20904],{"class":5696},[5676,21136,21137],{"class":5678,"line":5686},[5676,21138,20918],{"class":5696},[5676,21140,21141],{"class":5678,"line":5693},[5676,21142,5690],{"emptyLinePlaceholder":5689},[5676,21144,21145],{"class":5678,"line":5707},[5676,21146,21147],{"class":5682},"# Використовуємо спеціальні директиви (специфікатори)\n",[5676,21149,21150,21153,21156,21159,21162],{"class":5678,"line":5712},[5676,21151,21152],{"class":5696},"formatted = now.strftime(",[5676,21154,21155],{"class":5758},"\"%Y-%m-",[5676,21157,21158],{"class":5715},"%d",[5676,21160,21161],{"class":5758}," %H:%M:%S\"",[5676,21163,6049],{"class":5696},[5676,21165,21166,21168,21171],{"class":5678,"line":5755},[5676,21167,6068],{"class":5719},[5676,21169,21170],{"class":5696},"(formatted)  ",[5676,21172,21173],{"class":5682},"# \"2026-06-13 20:30:15\"\n",[5676,21175,21176],{"class":5678,"line":5762},[5676,21177,5690],{"emptyLinePlaceholder":5689},[5676,21179,21180,21183,21185,21187,21190],{"class":5678,"line":5772},[5676,21181,21182],{"class":5696},"human_friendly = now.strftime(",[5676,21184,6088],{"class":5758},[5676,21186,21158],{"class":5715},[5676,21188,21189],{"class":5758}," %B %Y, (%A)\"",[5676,21191,6049],{"class":5696},[5676,21193,21194,21196,21199],{"class":5678,"line":5777},[5676,21195,6068],{"class":5719},[5676,21197,21198],{"class":5696},"(human_friendly)  ",[5676,21200,21201],{"class":5682},"# \"13 June 2026, (Saturday)\"\n",[5667,21203,21206],{"className":5669,"code":21204,"filename":21205,"language":5671,"meta":5672,"style":5672},"import datetime\n\ndate_str = \"15\u002F09\u002F2025 18:45\"\n# Шаблон MUST точно збігатися з форматом рядка\nparsed = datetime.datetime.strptime(date_str, \"%d\u002F%m\u002F%Y %H:%M\")\nprint(parsed)  # 2025-09-15 18:45:00\nprint(type(parsed))  # \u003Cclass 'datetime.datetime'>\n","Парсинг (String to Time)",[5511,21207,21208,21214,21218,21226,21231,21245,21255],{"__ignoreMap":5672},[5676,21209,21210,21212],{"class":5678,"line":5679},[5676,21211,6018],{"class":5765},[5676,21213,20904],{"class":5696},[5676,21215,21216],{"class":5678,"line":5686},[5676,21217,5690],{"emptyLinePlaceholder":5689},[5676,21219,21220,21223],{"class":5678,"line":5693},[5676,21221,21222],{"class":5696},"date_str = ",[5676,21224,21225],{"class":5758},"\"15\u002F09\u002F2025 18:45\"\n",[5676,21227,21228],{"class":5678,"line":5707},[5676,21229,21230],{"class":5682},"# Шаблон MUST точно збігатися з форматом рядка\n",[5676,21232,21233,21236,21238,21240,21243],{"class":5678,"line":5712},[5676,21234,21235],{"class":5696},"parsed = datetime.datetime.strptime(date_str, ",[5676,21237,6088],{"class":5758},[5676,21239,21158],{"class":5715},[5676,21241,21242],{"class":5758},"\u002F%m\u002F%Y %H:%M\"",[5676,21244,6049],{"class":5696},[5676,21246,21247,21249,21252],{"class":5678,"line":5755},[5676,21248,6068],{"class":5719},[5676,21250,21251],{"class":5696},"(parsed)  ",[5676,21253,21254],{"class":5682},"# 2025-09-15 18:45:00\n",[5676,21256,21257,21259,21261,21263,21266],{"class":5678,"line":5762},[5676,21258,6068],{"class":5719},[5676,21260,5723],{"class":5696},[5676,21262,7714],{"class":5733},[5676,21264,21265],{"class":5696},"(parsed))  ",[5676,21267,21268],{"class":5682},"# \u003Cclass 'datetime.datetime'>\n",[6400,21270,21272],{"id":21271},"naive-vs-aware-обєкти-часу","Naive vs Aware об'єкти часу",[5507,21274,21275,21276,21278,21279,21282,21283,5572],{},"За замовчуванням об'єкти ",[5511,21277,7967],{}," є ",[5519,21280,21281],{},"naive (наївними)"," — вони не містять інформації про часовий пояс. Це небезпечно для серверних систем, де клієнти можуть бути з різних куточків світу. Об'єкти з інформацією про часовий пояс називаються ",[5519,21284,21285],{},"aware (усвідомленими)",[5507,21287,21288,21289,21292],{},"З Python 3.9 вбудовано модуль ",[5511,21290,21291],{},"zoneinfo"," для зручної роботи з базою даних часових поясів IANA:",[5667,21294,21296],{"className":5669,"code":21295,"language":5671,"meta":5672,"style":5672},"from datetime import datetime\nfrom zoneinfo import ZoneInfo\n\n# Створення часу в часовому поясі Києва\nkyiv_time = datetime.now(ZoneInfo(\"Europe\u002FKyiv\"))\nprint(f\"Київ: {kyiv_time}\")  # Наприкінці з'явиться зміщення UTC: +03:00 (або +02:00)\n\n# Конвертація в часовий пояс Нью-Йорка\nny_time = kyiv_time.astimezone(ZoneInfo(\"America\u002FNew_York\"))\nprint(f\"Нью-Йорк: {ny_time}\")  # Час автоматично перераховується\n",[5511,21297,21298,21309,21321,21325,21330,21340,21365,21369,21374,21384],{"__ignoreMap":5672},[5676,21299,21300,21302,21305,21307],{"class":5678,"line":5679},[5676,21301,7020],{"class":5765},[5676,21303,21304],{"class":5696}," datetime ",[5676,21306,6018],{"class":5765},[5676,21308,20904],{"class":5696},[5676,21310,21311,21313,21316,21318],{"class":5678,"line":5686},[5676,21312,7020],{"class":5765},[5676,21314,21315],{"class":5696}," zoneinfo ",[5676,21317,6018],{"class":5765},[5676,21319,21320],{"class":5696}," ZoneInfo\n",[5676,21322,21323],{"class":5678,"line":5693},[5676,21324,5690],{"emptyLinePlaceholder":5689},[5676,21326,21327],{"class":5678,"line":5707},[5676,21328,21329],{"class":5682},"# Створення часу в часовому поясі Києва\n",[5676,21331,21332,21335,21338],{"class":5678,"line":5712},[5676,21333,21334],{"class":5696},"kyiv_time = datetime.now(ZoneInfo(",[5676,21336,21337],{"class":5758},"\"Europe\u002FKyiv\"",[5676,21339,7392],{"class":5696},[5676,21341,21342,21344,21346,21348,21351,21353,21356,21358,21360,21362],{"class":5678,"line":5755},[5676,21343,6068],{"class":5719},[5676,21345,5723],{"class":5696},[5676,21347,6073],{"class":5715},[5676,21349,21350],{"class":5758},"\"Київ: ",[5676,21352,6079],{"class":5715},[5676,21354,21355],{"class":5696},"kyiv_time",[5676,21357,6085],{"class":5715},[5676,21359,6088],{"class":5758},[5676,21361,7241],{"class":5696},[5676,21363,21364],{"class":5682},"# Наприкінці з'явиться зміщення UTC: +03:00 (або +02:00)\n",[5676,21366,21367],{"class":5678,"line":5762},[5676,21368,5690],{"emptyLinePlaceholder":5689},[5676,21370,21371],{"class":5678,"line":5772},[5676,21372,21373],{"class":5682},"# Конвертація в часовий пояс Нью-Йорка\n",[5676,21375,21376,21379,21382],{"class":5678,"line":5777},[5676,21377,21378],{"class":5696},"ny_time = kyiv_time.astimezone(ZoneInfo(",[5676,21380,21381],{"class":5758},"\"America\u002FNew_York\"",[5676,21383,7392],{"class":5696},[5676,21385,21386,21388,21390,21392,21395,21397,21400,21402,21404,21406],{"class":5678,"line":5807},[5676,21387,6068],{"class":5719},[5676,21389,5723],{"class":5696},[5676,21391,6073],{"class":5715},[5676,21393,21394],{"class":5758},"\"Нью-Йорк: ",[5676,21396,6079],{"class":5715},[5676,21398,21399],{"class":5696},"ny_time",[5676,21401,6085],{"class":5715},[5676,21403,6088],{"class":5758},[5676,21405,7241],{"class":5696},[5676,21407,21408],{"class":5682},"# Час автоматично перераховується\n",[5574,21410],{},[5581,21412,21414,21415,19786,21417,19786,21419],{"id":21413},"системна-взаємодія-os-vs-sys-vs-pathlib","Системна взаємодія: ",[5511,21416,7958],{},[5511,21418,7961],{},[5511,21420,21421],{},"pathlib",[5507,21423,21424],{},"Ці модулі забезпечують взаємодію з операційною системою та інтерпретатором Python.",[6400,21426,21428,21429,6594,21431],{"id":21427},"порівняння-призначення-os-та-sys","Порівняння призначення ",[5511,21430,7958],{},[5511,21432,7961],{},[7251,21434,21435,21442],{},[5621,21436,21437,21441],{},[5519,21438,21439],{},[5511,21440,7958],{},": відповідає за роботу з операційною системою (робота з файлами на диску, створення папок, змінні оточення ОС, системні виклики).",[5621,21443,21444,21448,21449,21451],{},[5519,21445,21446],{},[5511,21447,7961],{},": відповідає за взаємодію з самим інтерпретатором Python (параметри запуску скрипта, керування шляхами імпорту ",[5511,21450,5630],{},", внутрішні налаштування пам'яті та лімітів рекурсії).",[6400,21453,21455,21457],{"id":21454},"pathlib-сучасний-стандарт-для-роботи-зі-шляхами",[5511,21456,21421],{}," — сучасний стандарт для роботи зі шляхами",[5507,21459,21460,21461,21464,21465,21467],{},"Раніше для роботи зі шляхами використовувався модуль ",[5511,21462,21463],{},"os.path",". Сьогодні рекомендованим є модуль ",[5511,21466,21421],{},", який надає об'єктно-орієнтований підхід до шляхів.",[21121,21469,21470,21651],{},[5667,21471,21474],{"className":5669,"code":21472,"filename":21473,"language":5671,"meta":5672,"style":5672},"from pathlib import Path\n\n# Створення об'єкта шляху\nproject_dir = Path(\"\u002Fhome\u002Fuser\u002Fproject\")\n\n# Об'єднання шляхів через оператор '\u002F' (дуже зручно!)\nfile_path = project_dir \u002F \"src\" \u002F \"config.json\"\nprint(file_path)  # \u002Fhome\u002Fuser\u002Fproject\u002Fsrc\u002Fconfig.json\n\n# Перевірки та операції\nprint(f\"Чи існує? {file_path.exists()}\")\nprint(f\"Розширення: {file_path.suffix}\")\nprint(f\"Ім'я файлу: {file_path.name}\")\n\n# Створення папки разом із батьківськими\nPath(\"new_folder\u002Fsub_folder\").mkdir(parents=True, exist_ok=True)\n","Сучасний підхід (pathlib)",[5511,21475,21476,21488,21492,21497,21507,21511,21516,21528,21538,21542,21547,21569,21591,21613,21617,21622],{"__ignoreMap":5672},[5676,21477,21478,21480,21483,21485],{"class":5678,"line":5679},[5676,21479,7020],{"class":5765},[5676,21481,21482],{"class":5696}," pathlib ",[5676,21484,6018],{"class":5765},[5676,21486,21487],{"class":5696}," Path\n",[5676,21489,21490],{"class":5678,"line":5686},[5676,21491,5690],{"emptyLinePlaceholder":5689},[5676,21493,21494],{"class":5678,"line":5693},[5676,21495,21496],{"class":5682},"# Створення об'єкта шляху\n",[5676,21498,21499,21502,21505],{"class":5678,"line":5707},[5676,21500,21501],{"class":5696},"project_dir = Path(",[5676,21503,21504],{"class":5758},"\"\u002Fhome\u002Fuser\u002Fproject\"",[5676,21506,6049],{"class":5696},[5676,21508,21509],{"class":5678,"line":5712},[5676,21510,5690],{"emptyLinePlaceholder":5689},[5676,21512,21513],{"class":5678,"line":5755},[5676,21514,21515],{"class":5682},"# Об'єднання шляхів через оператор '\u002F' (дуже зручно!)\n",[5676,21517,21518,21521,21523,21525],{"class":5678,"line":5762},[5676,21519,21520],{"class":5696},"file_path = project_dir \u002F ",[5676,21522,19182],{"class":5758},[5676,21524,10219],{"class":5696},[5676,21526,21527],{"class":5758},"\"config.json\"\n",[5676,21529,21530,21532,21535],{"class":5678,"line":5772},[5676,21531,6068],{"class":5719},[5676,21533,21534],{"class":5696},"(file_path)  ",[5676,21536,21537],{"class":5682},"# \u002Fhome\u002Fuser\u002Fproject\u002Fsrc\u002Fconfig.json\n",[5676,21539,21540],{"class":5678,"line":5777},[5676,21541,5690],{"emptyLinePlaceholder":5689},[5676,21543,21544],{"class":5678,"line":5807},[5676,21545,21546],{"class":5682},"# Перевірки та операції\n",[5676,21548,21549,21551,21553,21555,21558,21560,21563,21565,21567],{"class":5678,"line":5813},[5676,21550,6068],{"class":5719},[5676,21552,5723],{"class":5696},[5676,21554,6073],{"class":5715},[5676,21556,21557],{"class":5758},"\"Чи існує? ",[5676,21559,6079],{"class":5715},[5676,21561,21562],{"class":5696},"file_path.exists()",[5676,21564,6085],{"class":5715},[5676,21566,6088],{"class":5758},[5676,21568,6049],{"class":5696},[5676,21570,21571,21573,21575,21577,21580,21582,21585,21587,21589],{"class":5678,"line":5821},[5676,21572,6068],{"class":5719},[5676,21574,5723],{"class":5696},[5676,21576,6073],{"class":5715},[5676,21578,21579],{"class":5758},"\"Розширення: ",[5676,21581,6079],{"class":5715},[5676,21583,21584],{"class":5696},"file_path.suffix",[5676,21586,6085],{"class":5715},[5676,21588,6088],{"class":5758},[5676,21590,6049],{"class":5696},[5676,21592,21593,21595,21597,21599,21602,21604,21607,21609,21611],{"class":5678,"line":5826},[5676,21594,6068],{"class":5719},[5676,21596,5723],{"class":5696},[5676,21598,6073],{"class":5715},[5676,21600,21601],{"class":5758},"\"Ім'я файлу: ",[5676,21603,6079],{"class":5715},[5676,21605,21606],{"class":5696},"file_path.name",[5676,21608,6085],{"class":5715},[5676,21610,6088],{"class":5758},[5676,21612,6049],{"class":5696},[5676,21614,21615],{"class":5678,"line":5856},[5676,21616,5690],{"emptyLinePlaceholder":5689},[5676,21618,21619],{"class":5678,"line":5862},[5676,21620,21621],{"class":5682},"# Створення папки разом із батьківськими\n",[5676,21623,21624,21627,21630,21633,21636,21638,21640,21642,21645,21647,21649],{"class":5678,"line":5870},[5676,21625,21626],{"class":5696},"Path(",[5676,21628,21629],{"class":5758},"\"new_folder\u002Fsub_folder\"",[5676,21631,21632],{"class":5696},").mkdir(",[5676,21634,21635],{"class":5726},"parents",[5676,21637,9923],{"class":5696},[5676,21639,8589],{"class":5715},[5676,21641,5737],{"class":5696},[5676,21643,21644],{"class":5726},"exist_ok",[5676,21646,9923],{"class":5696},[5676,21648,8589],{"class":5715},[5676,21650,6049],{"class":5696},[5667,21652,21655],{"className":5669,"code":21653,"filename":21654,"language":5671,"meta":5672,"style":5672},"import os\n\nproject_dir = \"\u002Fhome\u002Fuser\u002Fproject\"\n\n# Об'єднання шляхів через os.path.join\nfile_path = os.path.join(project_dir, \"src\", \"config.json\")\nprint(file_path)  # \u002Fhome\u002Fuser\u002Fproject\u002Fsrc\u002Fconfig.json\n\n# Перевірки та операції\nprint(f\"Чи існує? {os.path.exists(file_path)}\")\nprint(f\"Розширення: {os.path.splitext(file_path)[1]}\")\nprint(f\"Ім'я файлу: {os.path.basename(file_path)}\")\n\n# Створення папки\nos.makedirs(\"new_folder\u002Fsub_folder\", exist_ok=True)\n","Старий підхід (os.path)",[5511,21656,21657,21663,21667,21675,21679,21684,21698,21706,21710,21714,21735,21760,21781,21785,21790],{"__ignoreMap":5672},[5676,21658,21659,21661],{"class":5678,"line":5679},[5676,21660,6018],{"class":5765},[5676,21662,6963],{"class":5696},[5676,21664,21665],{"class":5678,"line":5686},[5676,21666,5690],{"emptyLinePlaceholder":5689},[5676,21668,21669,21672],{"class":5678,"line":5693},[5676,21670,21671],{"class":5696},"project_dir = ",[5676,21673,21674],{"class":5758},"\"\u002Fhome\u002Fuser\u002Fproject\"\n",[5676,21676,21677],{"class":5678,"line":5707},[5676,21678,5690],{"emptyLinePlaceholder":5689},[5676,21680,21681],{"class":5678,"line":5712},[5676,21682,21683],{"class":5682},"# Об'єднання шляхів через os.path.join\n",[5676,21685,21686,21689,21691,21693,21696],{"class":5678,"line":5755},[5676,21687,21688],{"class":5696},"file_path = os.path.join(project_dir, ",[5676,21690,19182],{"class":5758},[5676,21692,5737],{"class":5696},[5676,21694,21695],{"class":5758},"\"config.json\"",[5676,21697,6049],{"class":5696},[5676,21699,21700,21702,21704],{"class":5678,"line":5762},[5676,21701,6068],{"class":5719},[5676,21703,21534],{"class":5696},[5676,21705,21537],{"class":5682},[5676,21707,21708],{"class":5678,"line":5772},[5676,21709,5690],{"emptyLinePlaceholder":5689},[5676,21711,21712],{"class":5678,"line":5777},[5676,21713,21546],{"class":5682},[5676,21715,21716,21718,21720,21722,21724,21726,21729,21731,21733],{"class":5678,"line":5807},[5676,21717,6068],{"class":5719},[5676,21719,5723],{"class":5696},[5676,21721,6073],{"class":5715},[5676,21723,21557],{"class":5758},[5676,21725,6079],{"class":5715},[5676,21727,21728],{"class":5696},"os.path.exists(file_path)",[5676,21730,6085],{"class":5715},[5676,21732,6088],{"class":5758},[5676,21734,6049],{"class":5696},[5676,21736,21737,21739,21741,21743,21745,21747,21750,21752,21754,21756,21758],{"class":5678,"line":5813},[5676,21738,6068],{"class":5719},[5676,21740,5723],{"class":5696},[5676,21742,6073],{"class":5715},[5676,21744,21579],{"class":5758},[5676,21746,6079],{"class":5715},[5676,21748,21749],{"class":5696},"os.path.splitext(file_path)[",[5676,21751,7174],{"class":5700},[5676,21753,6854],{"class":5696},[5676,21755,6085],{"class":5715},[5676,21757,6088],{"class":5758},[5676,21759,6049],{"class":5696},[5676,21761,21762,21764,21766,21768,21770,21772,21775,21777,21779],{"class":5678,"line":5821},[5676,21763,6068],{"class":5719},[5676,21765,5723],{"class":5696},[5676,21767,6073],{"class":5715},[5676,21769,21601],{"class":5758},[5676,21771,6079],{"class":5715},[5676,21773,21774],{"class":5696},"os.path.basename(file_path)",[5676,21776,6085],{"class":5715},[5676,21778,6088],{"class":5758},[5676,21780,6049],{"class":5696},[5676,21782,21783],{"class":5678,"line":5826},[5676,21784,5690],{"emptyLinePlaceholder":5689},[5676,21786,21787],{"class":5678,"line":5856},[5676,21788,21789],{"class":5682},"# Створення папки\n",[5676,21791,21792,21795,21797,21799,21801,21803,21805],{"class":5678,"line":5862},[5676,21793,21794],{"class":5696},"os.makedirs(",[5676,21796,21629],{"class":5758},[5676,21798,5737],{"class":5696},[5676,21800,21644],{"class":5726},[5676,21802,9923],{"class":5696},[5676,21804,8589],{"class":5715},[5676,21806,6049],{"class":5696},[6400,21808,21810,21811],{"id":21809},"ключові-можливості-sys","Ключові можливості ",[5511,21812,7961],{},[5667,21814,21816],{"className":5669,"code":21815,"language":5671,"meta":5672,"style":5672},"import sys\n\n# Аргументи командного рядка (наприклад: python main.py data.txt)\n# sys.argv[0] — це завжди ім'я самого скрипта\nprint(f\"Аргументи запуску: {sys.argv}\")\n\n# Платформа та версія\nprint(sys.platform)  # 'darwin' (macOS), 'win32' (Windows), 'linux' (Linux)\nprint(sys.version)   # Детальна версія інтерпретатора\n\n# Безпечне завершення роботи скрипта з кодом виходу\n# 0 = успіх, будь-яке інше число = помилка\nsys.exit(0)\n",[5511,21817,21818,21824,21828,21833,21838,21860,21864,21869,21879,21889,21893,21898,21903],{"__ignoreMap":5672},[5676,21819,21820,21822],{"class":5678,"line":5679},[5676,21821,6018],{"class":5765},[5676,21823,6970],{"class":5696},[5676,21825,21826],{"class":5678,"line":5686},[5676,21827,5690],{"emptyLinePlaceholder":5689},[5676,21829,21830],{"class":5678,"line":5693},[5676,21831,21832],{"class":5682},"# Аргументи командного рядка (наприклад: python main.py data.txt)\n",[5676,21834,21835],{"class":5678,"line":5707},[5676,21836,21837],{"class":5682},"# sys.argv[0] — це завжди ім'я самого скрипта\n",[5676,21839,21840,21842,21844,21846,21849,21851,21854,21856,21858],{"class":5678,"line":5712},[5676,21841,6068],{"class":5719},[5676,21843,5723],{"class":5696},[5676,21845,6073],{"class":5715},[5676,21847,21848],{"class":5758},"\"Аргументи запуску: ",[5676,21850,6079],{"class":5715},[5676,21852,21853],{"class":5696},"sys.argv",[5676,21855,6085],{"class":5715},[5676,21857,6088],{"class":5758},[5676,21859,6049],{"class":5696},[5676,21861,21862],{"class":5678,"line":5755},[5676,21863,5690],{"emptyLinePlaceholder":5689},[5676,21865,21866],{"class":5678,"line":5762},[5676,21867,21868],{"class":5682},"# Платформа та версія\n",[5676,21870,21871,21873,21876],{"class":5678,"line":5772},[5676,21872,6068],{"class":5719},[5676,21874,21875],{"class":5696},"(sys.platform)  ",[5676,21877,21878],{"class":5682},"# 'darwin' (macOS), 'win32' (Windows), 'linux' (Linux)\n",[5676,21880,21881,21883,21886],{"class":5678,"line":5777},[5676,21882,6068],{"class":5719},[5676,21884,21885],{"class":5696},"(sys.version)   ",[5676,21887,21888],{"class":5682},"# Детальна версія інтерпретатора\n",[5676,21890,21891],{"class":5678,"line":5807},[5676,21892,5690],{"emptyLinePlaceholder":5689},[5676,21894,21895],{"class":5678,"line":5813},[5676,21896,21897],{"class":5682},"# Безпечне завершення роботи скрипта з кодом виходу\n",[5676,21899,21900],{"class":5678,"line":5821},[5676,21901,21902],{"class":5682},"# 0 = успіх, будь-яке інше число = помилка\n",[5676,21904,21905,21908,21910],{"class":5678,"line":5826},[5676,21906,21907],{"class":5696},"sys.exit(",[5676,21909,8035],{"class":5700},[5676,21911,6049],{"class":5696},[5574,21913],{},[5581,21915,21917,21918],{"id":21916},"спеціалізовані-контейнери-модуль-collections","Спеціалізовані контейнери: модуль ",[5511,21919,21920],{},"collections",[5507,21922,21923,21924,5737,21926,5737,21928,6594,21931,21934,21935,21937],{},"Стандартні типи ",[5511,21925,6389],{},[5511,21927,6779],{},[5511,21929,21930],{},"set",[5511,21932,21933],{},"tuple"," чудово підходять для більшості завдань, але модуль ",[5511,21936,21920],{}," надає альтернативні контейнери з розширеною поведінкою.",[6400,21939,21941,21944],{"id":21940},"namedtuple-кортеж-з-іменованими-полями",[5511,21942,21943],{},"namedtuple"," — кортеж з іменованими полями",[5507,21946,21947,21948,21951,21952,21955],{},"Коли вам потрібен легковажний, незмінний об'єкт (наприклад, для представлення точки на карті чи запису користувача), писати повноцінний клас занадто довго. Звичайний кортеж ",[5511,21949,21950],{},"Point = (50.45, 30.52)"," змушує звертатися за індексами ",[5511,21953,21954],{},"Point[0]",", що шкодить читабельності.",[5667,21957,21959],{"className":5669,"code":21958,"language":5671,"meta":5672,"style":5672},"from collections import namedtuple\n\n# Створюємо тип (фабрику) Geopoint з полями latitude та longitude\nGeopoint = namedtuple(\"Geopoint\", [\"latitude\", \"longitude\"])\n\n# Створюємо екземпляр\nkyiv = Geopoint(latitude=50.4501, longitude=30.5234)\n\n# Звернення за іменами полів!\nprint(f\"Широта: {kyiv.latitude}, Довгота: {kyiv.longitude}\")\n\n# Але це все ще кортеж (сумісність збережена)\nprint(f\"Індекс 0: {kyiv[0]}\")\nlat, lon = kyiv  # Розпакування працює\n",[5511,21960,21961,21973,21977,21982,22002,22006,22011,22036,22040,22045,22077,22081,22086,22112],{"__ignoreMap":5672},[5676,21962,21963,21965,21968,21970],{"class":5678,"line":5679},[5676,21964,7020],{"class":5765},[5676,21966,21967],{"class":5696}," collections ",[5676,21969,6018],{"class":5765},[5676,21971,21972],{"class":5696}," namedtuple\n",[5676,21974,21975],{"class":5678,"line":5686},[5676,21976,5690],{"emptyLinePlaceholder":5689},[5676,21978,21979],{"class":5678,"line":5693},[5676,21980,21981],{"class":5682},"# Створюємо тип (фабрику) Geopoint з полями latitude та longitude\n",[5676,21983,21984,21987,21990,21992,21995,21997,22000],{"class":5678,"line":5707},[5676,21985,21986],{"class":5696},"Geopoint = namedtuple(",[5676,21988,21989],{"class":5758},"\"Geopoint\"",[5676,21991,12078],{"class":5696},[5676,21993,21994],{"class":5758},"\"latitude\"",[5676,21996,5737],{"class":5696},[5676,21998,21999],{"class":5758},"\"longitude\"",[5676,22001,7185],{"class":5696},[5676,22003,22004],{"class":5678,"line":5712},[5676,22005,5690],{"emptyLinePlaceholder":5689},[5676,22007,22008],{"class":5678,"line":5755},[5676,22009,22010],{"class":5682},"# Створюємо екземпляр\n",[5676,22012,22013,22016,22019,22021,22024,22026,22029,22031,22034],{"class":5678,"line":5762},[5676,22014,22015],{"class":5696},"kyiv = Geopoint(",[5676,22017,22018],{"class":5726},"latitude",[5676,22020,9923],{"class":5696},[5676,22022,22023],{"class":5700},"50.4501",[5676,22025,5737],{"class":5696},[5676,22027,22028],{"class":5726},"longitude",[5676,22030,9923],{"class":5696},[5676,22032,22033],{"class":5700},"30.5234",[5676,22035,6049],{"class":5696},[5676,22037,22038],{"class":5678,"line":5772},[5676,22039,5690],{"emptyLinePlaceholder":5689},[5676,22041,22042],{"class":5678,"line":5777},[5676,22043,22044],{"class":5682},"# Звернення за іменами полів!\n",[5676,22046,22047,22049,22051,22053,22056,22058,22061,22063,22066,22068,22071,22073,22075],{"class":5678,"line":5807},[5676,22048,6068],{"class":5719},[5676,22050,5723],{"class":5696},[5676,22052,6073],{"class":5715},[5676,22054,22055],{"class":5758},"\"Широта: ",[5676,22057,6079],{"class":5715},[5676,22059,22060],{"class":5696},"kyiv.latitude",[5676,22062,6085],{"class":5715},[5676,22064,22065],{"class":5758},", Довгота: ",[5676,22067,6079],{"class":5715},[5676,22069,22070],{"class":5696},"kyiv.longitude",[5676,22072,6085],{"class":5715},[5676,22074,6088],{"class":5758},[5676,22076,6049],{"class":5696},[5676,22078,22079],{"class":5678,"line":5813},[5676,22080,5690],{"emptyLinePlaceholder":5689},[5676,22082,22083],{"class":5678,"line":5821},[5676,22084,22085],{"class":5682},"# Але це все ще кортеж (сумісність збережена)\n",[5676,22087,22088,22090,22092,22094,22097,22099,22102,22104,22106,22108,22110],{"class":5678,"line":5826},[5676,22089,6068],{"class":5719},[5676,22091,5723],{"class":5696},[5676,22093,6073],{"class":5715},[5676,22095,22096],{"class":5758},"\"Індекс 0: ",[5676,22098,6079],{"class":5715},[5676,22100,22101],{"class":5696},"kyiv[",[5676,22103,8035],{"class":5700},[5676,22105,6854],{"class":5696},[5676,22107,6085],{"class":5715},[5676,22109,6088],{"class":5758},[5676,22111,6049],{"class":5696},[5676,22113,22114,22117],{"class":5678,"line":5856},[5676,22115,22116],{"class":5696},"lat, lon = kyiv  ",[5676,22118,22119],{"class":5682},"# Розпакування працює\n",[6400,22121,22123,22126],{"id":22122},"defaultdict-словник-зі-значенням-за-замовчуванням",[5511,22124,22125],{},"defaultdict"," — словник зі значенням за замовчуванням",[5507,22128,22129,22130,22132,22133,22135,22136,22138],{},"При роботі зі звичайним ",[5511,22131,6389],{}," звернення до неіснуючого ключа викликає ",[5511,22134,6466],{},". ",[5511,22137,22125],{}," автоматично створює значення за замовчуванням при першому зверненні до нового ключа.",[5667,22140,22142],{"className":5669,"code":22141,"language":5671,"meta":5672,"style":5672},"from collections import defaultdict\n\n# Словник, який за замовчуванням створює порожній список (list) для нових ключів\ngrouped_students = defaultdict(list)\n\n# Нам не потрібно перевіряти, чи є ключ \"Python\" у словнику!\ngrouped_students[\"Python\"].append(\"Олег\")\ngrouped_students[\"Python\"].append(\"Марія\")\ngrouped_students[\"Go\"].append(\"Іван\")\n\nprint(grouped_students)\n# defaultdict(\u003Cclass 'list'>, {'Python': ['Олег', 'Марія'], 'Go': ['Іван']})\n",[5511,22143,22144,22155,22159,22164,22173,22177,22182,22198,22211,22225,22229,22236],{"__ignoreMap":5672},[5676,22145,22146,22148,22150,22152],{"class":5678,"line":5679},[5676,22147,7020],{"class":5765},[5676,22149,21967],{"class":5696},[5676,22151,6018],{"class":5765},[5676,22153,22154],{"class":5696}," defaultdict\n",[5676,22156,22157],{"class":5678,"line":5686},[5676,22158,5690],{"emptyLinePlaceholder":5689},[5676,22160,22161],{"class":5678,"line":5693},[5676,22162,22163],{"class":5682},"# Словник, який за замовчуванням створює порожній список (list) для нових ключів\n",[5676,22165,22166,22169,22171],{"class":5678,"line":5707},[5676,22167,22168],{"class":5696},"grouped_students = defaultdict(",[5676,22170,6779],{"class":5733},[5676,22172,6049],{"class":5696},[5676,22174,22175],{"class":5678,"line":5712},[5676,22176,5690],{"emptyLinePlaceholder":5689},[5676,22178,22179],{"class":5678,"line":5755},[5676,22180,22181],{"class":5682},"# Нам не потрібно перевіряти, чи є ключ \"Python\" у словнику!\n",[5676,22183,22184,22187,22190,22193,22196],{"class":5678,"line":5762},[5676,22185,22186],{"class":5696},"grouped_students[",[5676,22188,22189],{"class":5758},"\"Python\"",[5676,22191,22192],{"class":5696},"].append(",[5676,22194,22195],{"class":5758},"\"Олег\"",[5676,22197,6049],{"class":5696},[5676,22199,22200,22202,22204,22206,22209],{"class":5678,"line":5772},[5676,22201,22186],{"class":5696},[5676,22203,22189],{"class":5758},[5676,22205,22192],{"class":5696},[5676,22207,22208],{"class":5758},"\"Марія\"",[5676,22210,6049],{"class":5696},[5676,22212,22213,22215,22218,22220,22223],{"class":5678,"line":5777},[5676,22214,22186],{"class":5696},[5676,22216,22217],{"class":5758},"\"Go\"",[5676,22219,22192],{"class":5696},[5676,22221,22222],{"class":5758},"\"Іван\"",[5676,22224,6049],{"class":5696},[5676,22226,22227],{"class":5678,"line":5807},[5676,22228,5690],{"emptyLinePlaceholder":5689},[5676,22230,22231,22233],{"class":5678,"line":5813},[5676,22232,6068],{"class":5719},[5676,22234,22235],{"class":5696},"(grouped_students)\n",[5676,22237,22238],{"class":5678,"line":5821},[5676,22239,22240],{"class":5682},"# defaultdict(\u003Cclass 'list'>, {'Python': ['Олег', 'Марія'], 'Go': ['Іван']})\n",[6400,22242,22244,22247],{"id":22243},"counter-зручний-лічильник-елементів",[5511,22245,22246],{},"Counter"," — зручний лічильник елементів",[5507,22249,22250,22251,22253,22254,22256],{},"Клас ",[5511,22252,22246],{}," призначений для швидкого підрахунку кількості об'єктів. Він є підкласом ",[5511,22255,6389],{},", тому успадковує всі його методи.",[5667,22258,22260],{"className":5669,"code":22259,"language":5671,"meta":5672,"style":5672},"from collections import Counter\n\nwords = [\"яблуко\", \"банан\", \"яблуко\", \"апельсин\", \"банан\", \"яблуко\"]\ncounter = Counter(words)\n\nprint(counter)  # Counter({'яблуко': 3, 'банан': 2, 'апельсин': 1})\nprint(f\"Кількість бананів: {counter['банан']}\")\nprint(f\"Кількість неіснуючих елементів: {counter['груша']}\")  # Повертає 0 замість KeyError!\n\n# Отримання топ-N найпопулярніших елементів\nprint(f\"Найпопулярніші: {counter.most_common(2)}\")  # [('яблуко', 3), ('банан', 2)]\n",[5511,22261,22262,22273,22277,22309,22314,22318,22328,22355,22384,22388,22393],{"__ignoreMap":5672},[5676,22263,22264,22266,22268,22270],{"class":5678,"line":5679},[5676,22265,7020],{"class":5765},[5676,22267,21967],{"class":5696},[5676,22269,6018],{"class":5765},[5676,22271,22272],{"class":5696}," Counter\n",[5676,22274,22275],{"class":5678,"line":5686},[5676,22276,5690],{"emptyLinePlaceholder":5689},[5676,22278,22279,22282,22285,22287,22290,22292,22294,22296,22299,22301,22303,22305,22307],{"class":5678,"line":5693},[5676,22280,22281],{"class":5696},"words = [",[5676,22283,22284],{"class":5758},"\"яблуко\"",[5676,22286,5737],{"class":5696},[5676,22288,22289],{"class":5758},"\"банан\"",[5676,22291,5737],{"class":5696},[5676,22293,22284],{"class":5758},[5676,22295,5737],{"class":5696},[5676,22297,22298],{"class":5758},"\"апельсин\"",[5676,22300,5737],{"class":5696},[5676,22302,22289],{"class":5758},[5676,22304,5737],{"class":5696},[5676,22306,22284],{"class":5758},[5676,22308,8460],{"class":5696},[5676,22310,22311],{"class":5678,"line":5707},[5676,22312,22313],{"class":5696},"counter = Counter(words)\n",[5676,22315,22316],{"class":5678,"line":5712},[5676,22317,5690],{"emptyLinePlaceholder":5689},[5676,22319,22320,22322,22325],{"class":5678,"line":5755},[5676,22321,6068],{"class":5719},[5676,22323,22324],{"class":5696},"(counter)  ",[5676,22326,22327],{"class":5682},"# Counter({'яблуко': 3, 'банан': 2, 'апельсин': 1})\n",[5676,22329,22330,22332,22334,22336,22339,22341,22344,22347,22349,22351,22353],{"class":5678,"line":5762},[5676,22331,6068],{"class":5719},[5676,22333,5723],{"class":5696},[5676,22335,6073],{"class":5715},[5676,22337,22338],{"class":5758},"\"Кількість бананів: ",[5676,22340,6079],{"class":5715},[5676,22342,22343],{"class":5696},"counter[",[5676,22345,22346],{"class":5758},"'банан'",[5676,22348,6854],{"class":5696},[5676,22350,6085],{"class":5715},[5676,22352,6088],{"class":5758},[5676,22354,6049],{"class":5696},[5676,22356,22357,22359,22361,22363,22366,22368,22370,22373,22375,22377,22379,22381],{"class":5678,"line":5772},[5676,22358,6068],{"class":5719},[5676,22360,5723],{"class":5696},[5676,22362,6073],{"class":5715},[5676,22364,22365],{"class":5758},"\"Кількість неіснуючих елементів: ",[5676,22367,6079],{"class":5715},[5676,22369,22343],{"class":5696},[5676,22371,22372],{"class":5758},"'груша'",[5676,22374,6854],{"class":5696},[5676,22376,6085],{"class":5715},[5676,22378,6088],{"class":5758},[5676,22380,7241],{"class":5696},[5676,22382,22383],{"class":5682},"# Повертає 0 замість KeyError!\n",[5676,22385,22386],{"class":5678,"line":5777},[5676,22387,5690],{"emptyLinePlaceholder":5689},[5676,22389,22390],{"class":5678,"line":5807},[5676,22391,22392],{"class":5682},"# Отримання топ-N найпопулярніших елементів\n",[5676,22394,22395,22397,22399,22401,22404,22406,22409,22411,22413,22415,22417,22419],{"class":5678,"line":5813},[5676,22396,6068],{"class":5719},[5676,22398,5723],{"class":5696},[5676,22400,6073],{"class":5715},[5676,22402,22403],{"class":5758},"\"Найпопулярніші: ",[5676,22405,6079],{"class":5715},[5676,22407,22408],{"class":5696},"counter.most_common(",[5676,22410,6322],{"class":5700},[5676,22412,5631],{"class":5696},[5676,22414,6085],{"class":5715},[5676,22416,6088],{"class":5758},[5676,22418,7241],{"class":5696},[5676,22420,22421],{"class":5682},"# [('яблуко', 3), ('банан', 2)]\n",[6400,22423,22425,22428],{"id":22424},"deque-оптимізована-двостороння-черга",[5511,22426,22427],{},"deque"," — оптимізована двостороння черга",[5507,22430,22431,22432,22434,22435,6423,22438,22441,22442,22445],{},"Звичайний список Python ",[5511,22433,6779],{}," оптимізований для операцій у кінці структури. Додавання або видалення елемента з початку списку (",[5511,22436,22437],{},"list.insert(0, val)",[5511,22439,22440],{},"list.pop(0)",") має складність ",[5519,22443,22444],{},"$O(N)$",", оскільки всі інші елементи в пам'яті мають зсунутися на один крок.",[5507,22447,22448,22450,22451,5572],{},[5511,22449,22427],{}," (double-ended queue) реалізований як двобічно зв'язаний список, що робить додавання та видалення елементів з обох кінців надзвичайно швидким — за ",[5519,22452,22453],{},"$O(1)$",[5667,22455,22457],{"className":5669,"code":22456,"language":5671,"meta":5672,"style":5672},"from collections import deque\n\nqueue = deque([\"Користувач 1\", \"Користувач 2\"])\n\n# Швидке додавання в кінець\nqueue.append(\"Користувач 3\")\n\n# Швидке додавання на початок\nqueue.appendleft(\"VIP Користувач\")\nprint(queue)  # deque(['VIP Користувач', 'Користувач 1', ...])\n\n# Видалення з обох кінців\nfirst_in = queue.popleft()  # 'VIP Користувач'\nlast_in = queue.pop()       # 'Користувач 3'\n",[5511,22458,22459,22470,22474,22489,22493,22498,22508,22512,22517,22527,22537,22541,22546,22554],{"__ignoreMap":5672},[5676,22460,22461,22463,22465,22467],{"class":5678,"line":5679},[5676,22462,7020],{"class":5765},[5676,22464,21967],{"class":5696},[5676,22466,6018],{"class":5765},[5676,22468,22469],{"class":5696}," deque\n",[5676,22471,22472],{"class":5678,"line":5686},[5676,22473,5690],{"emptyLinePlaceholder":5689},[5676,22475,22476,22479,22482,22484,22487],{"class":5678,"line":5693},[5676,22477,22478],{"class":5696},"queue = deque([",[5676,22480,22481],{"class":5758},"\"Користувач 1\"",[5676,22483,5737],{"class":5696},[5676,22485,22486],{"class":5758},"\"Користувач 2\"",[5676,22488,7185],{"class":5696},[5676,22490,22491],{"class":5678,"line":5707},[5676,22492,5690],{"emptyLinePlaceholder":5689},[5676,22494,22495],{"class":5678,"line":5712},[5676,22496,22497],{"class":5682},"# Швидке додавання в кінець\n",[5676,22499,22500,22503,22506],{"class":5678,"line":5755},[5676,22501,22502],{"class":5696},"queue.append(",[5676,22504,22505],{"class":5758},"\"Користувач 3\"",[5676,22507,6049],{"class":5696},[5676,22509,22510],{"class":5678,"line":5762},[5676,22511,5690],{"emptyLinePlaceholder":5689},[5676,22513,22514],{"class":5678,"line":5772},[5676,22515,22516],{"class":5682},"# Швидке додавання на початок\n",[5676,22518,22519,22522,22525],{"class":5678,"line":5777},[5676,22520,22521],{"class":5696},"queue.appendleft(",[5676,22523,22524],{"class":5758},"\"VIP Користувач\"",[5676,22526,6049],{"class":5696},[5676,22528,22529,22531,22534],{"class":5678,"line":5807},[5676,22530,6068],{"class":5719},[5676,22532,22533],{"class":5696},"(queue)  ",[5676,22535,22536],{"class":5682},"# deque(['VIP Користувач', 'Користувач 1', ...])\n",[5676,22538,22539],{"class":5678,"line":5813},[5676,22540,5690],{"emptyLinePlaceholder":5689},[5676,22542,22543],{"class":5678,"line":5821},[5676,22544,22545],{"class":5682},"# Видалення з обох кінців\n",[5676,22547,22548,22551],{"class":5678,"line":5826},[5676,22549,22550],{"class":5696},"first_in = queue.popleft()  ",[5676,22552,22553],{"class":5682},"# 'VIP Користувач'\n",[5676,22555,22556,22559],{"class":5678,"line":5856},[5676,22557,22558],{"class":5696},"last_in = queue.pop()       ",[5676,22560,22561],{"class":5682},"# 'Користувач 3'\n",[12399,22563,20841,22564,22566,22567,22570,22571,22574],{},[5511,22565,22427],{}," для реалізації стеків, черг завдань (FIFO\u002FLIFO) або для зберігання логів фіксованого розміру (задавши параметр ",[5511,22568,22569],{},"maxlen"," при створенні, наприклад ",[5511,22572,22573],{},"deque(maxlen=100)"," — при додаванні 101-го елемента перший автоматично видалиться).",[5574,22576],{},[5502,22578,22580],{"id":22579},"повний-цикл-роботи-від-нуля-до-готового-проекту","Повний цикл роботи: від нуля до готового проекту",[5507,22582,22583],{},"Це стандартна послідовність дій при створенні нового Python-проекту:",[5667,22585,22587],{"className":13161,"code":22586,"language":13163,"meta":5672,"style":5672},"# 1. Створити директорію проекту\nmkdir my-awesome-project\ncd my-awesome-project\n\n# 2. Ініціалізувати git-репозиторій (опціонально, але рекомендується)\ngit init\n\n# 3. Створити файл .gitignore — ОДРАЗУ, до будь-яких комітів\ncat > .gitignore \u003C\u003C 'EOF'\n# Віртуальне середовище — ніколи не комітимо!\n.venv\u002F\nvenv\u002F\n\n# Байткод Python\n__pycache__\u002F\n*.pyc\n*.pyo\n\n# Середовища та IDE\n.env\n.DS_Store\n.idea\u002F\n.vscode\u002F\nEOF\n\n# 4. Створити та активувати venv\npython -m venv .venv\nsource .venv\u002Fbin\u002Factivate  # (.venv) з'явиться у промпті\n\n# 5. Встановити залежності проекту\npip install requests django pytest\n\n# 6. Зафіксувати залежності\npip freeze > requirements.txt\n\n# 7. Написати код...\n\n# 8. Перед завершенням — оновити requirements.txt\npip freeze > requirements.txt\ngit add requirements.txt\ngit commit -m \"chore: update dependencies\"\n",[5511,22588,22589,22594,22601,22607,22611,22616,22622,22626,22631,22645,22650,22654,22658,22662,22667,22671,22676,22680,22684,22689,22693,22698,22702,22706,22711,22715,22720,22730,22740,22744,22749,22761,22765,22770,22780,22784,22789,22793,22798,22808,22816],{"__ignoreMap":5672},[5676,22590,22591],{"class":5678,"line":5679},[5676,22592,22593],{"class":5682},"# 1. Створити директорію проекту\n",[5676,22595,22596,22598],{"class":5678,"line":5686},[5676,22597,14058],{"class":5719},[5676,22599,22600],{"class":5758}," my-awesome-project\n",[5676,22602,22603,22605],{"class":5678,"line":5693},[5676,22604,14042],{"class":5719},[5676,22606,22600],{"class":5758},[5676,22608,22609],{"class":5678,"line":5707},[5676,22610,5690],{"emptyLinePlaceholder":5689},[5676,22612,22613],{"class":5678,"line":5712},[5676,22614,22615],{"class":5682},"# 2. Ініціалізувати git-репозиторій (опціонально, але рекомендується)\n",[5676,22617,22618,22620],{"class":5678,"line":5755},[5676,22619,17301],{"class":5719},[5676,22621,14076],{"class":5758},[5676,22623,22624],{"class":5678,"line":5762},[5676,22625,5690],{"emptyLinePlaceholder":5689},[5676,22627,22628],{"class":5678,"line":5772},[5676,22629,22630],{"class":5682},"# 3. Створити файл .gitignore — ОДРАЗУ, до будь-яких комітів\n",[5676,22632,22633,22635,22637,22639,22642],{"class":5678,"line":5777},[5676,22634,13632],{"class":5719},[5676,22636,13620],{"class":5696},[5676,22638,17873],{"class":5758},[5676,22640,22641],{"class":5696}," \u003C\u003C ",[5676,22643,22644],{"class":5696},"'EOF'\n",[5676,22646,22647],{"class":5678,"line":5807},[5676,22648,22649],{"class":5758},"# Віртуальне середовище — ніколи не комітимо!\n",[5676,22651,22652],{"class":5678,"line":5813},[5676,22653,17939],{"class":5758},[5676,22655,22656],{"class":5678,"line":5821},[5676,22657,17944],{"class":5758},[5676,22659,22660],{"class":5678,"line":5826},[5676,22661,5690],{"emptyLinePlaceholder":5689},[5676,22663,22664],{"class":5678,"line":5856},[5676,22665,22666],{"class":5758},"# Байткод Python\n",[5676,22668,22669],{"class":5678,"line":5862},[5676,22670,17963],{"class":5758},[5676,22672,22673],{"class":5678,"line":5870},[5676,22674,22675],{"class":5758},"*.pyc\n",[5676,22677,22678],{"class":5678,"line":5875},[5676,22679,17978],{"class":5758},[5676,22681,22682],{"class":5678,"line":5898},[5676,22683,5690],{"emptyLinePlaceholder":5689},[5676,22685,22686],{"class":5678,"line":5904},[5676,22687,22688],{"class":5758},"# Середовища та IDE\n",[5676,22690,22691],{"class":5678,"line":5915},[5676,22692,18064],{"class":5758},[5676,22694,22695],{"class":5678,"line":5920},[5676,22696,22697],{"class":5758},".DS_Store\n",[5676,22699,22700],{"class":5678,"line":5941},[5676,22701,18088],{"class":5758},[5676,22703,22704],{"class":5678,"line":5947},[5676,22705,18093],{"class":5758},[5676,22707,22708],{"class":5678,"line":5953},[5676,22709,22710],{"class":5696},"EOF\n",[5676,22712,22713],{"class":5678,"line":5959},[5676,22714,5690],{"emptyLinePlaceholder":5689},[5676,22716,22717],{"class":5678,"line":5964},[5676,22718,22719],{"class":5682},"# 4. Створити та активувати venv\n",[5676,22721,22722,22724,22726,22728],{"class":5678,"line":7576},[5676,22723,5671],{"class":5719},[5676,22725,13186],{"class":5715},[5676,22727,13189],{"class":5758},[5676,22729,13710],{"class":5758},[5676,22731,22732,22734,22737],{"class":5678,"line":7581},[5676,22733,13146],{"class":5719},[5676,22735,22736],{"class":5758}," .venv\u002Fbin\u002Factivate",[5676,22738,22739],{"class":5682},"  # (.venv) з'явиться у промпті\n",[5676,22741,22742],{"class":5678,"line":7587},[5676,22743,5690],{"emptyLinePlaceholder":5689},[5676,22745,22746],{"class":5678,"line":7593},[5676,22747,22748],{"class":5682},"# 5. Встановити залежності проекту\n",[5676,22750,22751,22753,22755,22757,22759],{"class":5678,"line":7599},[5676,22752,8268],{"class":5719},[5676,22754,13398],{"class":5758},[5676,22756,13401],{"class":5758},[5676,22758,13440],{"class":5758},[5676,22760,14653],{"class":5758},[5676,22762,22763],{"class":5678,"line":7605},[5676,22764,5690],{"emptyLinePlaceholder":5689},[5676,22766,22767],{"class":5678,"line":7611},[5676,22768,22769],{"class":5682},"# 6. Зафіксувати залежності\n",[5676,22771,22772,22774,22776,22778],{"class":5678,"line":7617},[5676,22773,8268],{"class":5719},[5676,22775,13617],{"class":5758},[5676,22777,13620],{"class":5696},[5676,22779,13623],{"class":5758},[5676,22781,22782],{"class":5678,"line":7622},[5676,22783,5690],{"emptyLinePlaceholder":5689},[5676,22785,22786],{"class":5678,"line":7627},[5676,22787,22788],{"class":5682},"# 7. Написати код...\n",[5676,22790,22791],{"class":5678,"line":7633},[5676,22792,5690],{"emptyLinePlaceholder":5689},[5676,22794,22795],{"class":5678,"line":7639},[5676,22796,22797],{"class":5682},"# 8. Перед завершенням — оновити requirements.txt\n",[5676,22799,22800,22802,22804,22806],{"class":5678,"line":7645},[5676,22801,8268],{"class":5719},[5676,22803,13617],{"class":5758},[5676,22805,13620],{"class":5696},[5676,22807,13623],{"class":5758},[5676,22809,22810,22812,22814],{"class":5678,"line":7651},[5676,22811,17301],{"class":5719},[5676,22813,5720],{"class":5758},[5676,22815,13635],{"class":5758},[5676,22817,22818,22820,22823,22825],{"class":5678,"line":7657},[5676,22819,17301],{"class":5719},[5676,22821,22822],{"class":5758}," commit",[5676,22824,13186],{"class":5715},[5676,22826,22827],{"class":5758}," \"chore: update dependencies\"\n",[8082,22829,22830,22833,22834,22836,22837,22839],{},[5519,22831,22832],{},"Критично важливо:"," ніколи не комітьте директорію ",[5511,22835,15924],{}," у Git-репозиторій. Вона містить сотні файлів і повністю залежить від конкретної машини та версії Python. Замість цього комітьте ",[5511,22838,13586],{}," — це єдине, що потрібно колезі або CI\u002FCD для відтворення вашого середовища.",[5574,22841],{},[5502,22843,22845],{"id":22844},"практичний-приклад-від-а-до-я-cli-інструмент-завантаження-та-оптимізації-зображень","Практичний приклад від А до Я: CLI-інструмент завантаження та оптимізації зображень",[5507,22847,22848,22849,5737,22851,5737,22853,5737,22855,5737,22857,6594,22859,22861,22862,5572],{},"Щоб об'єднати всі вивчені концепції (модулі, пакети, ",[5511,22850,12937],{},[5511,22852,5630],{},[5511,22854,5609],{},[5511,22856,21853],{},[5511,22858,22246],{},[5511,22860,21421],{},") в єдине ціле, створимо реальний виробничий інструмент командного рядка — ",[5519,22863,22864],{},"Image Processor CLI",[5581,22866,22868],{"id":22867},"постановка-задачі","Постановка задачі",[5507,22870,22871],{},"Нам потрібно написати утиліту, яка:",[5618,22873,22874,22877,22880,22885,22895],{},[5621,22875,22876],{},"Приймає текстовий файл зі списком URL-адрес зображень.",[5621,22878,22879],{},"Створює ізольовану вихідну директорію для збереження результатів.",[5621,22881,22882,22883,6467],{},"Завантажує зображення з мережі (потребує стороннього пакета ",[5511,22884,7989],{},[5621,22886,22887,22888,22891,22892,6467],{},"Змінює розмір зображень до заданої ширини та конвертує їх у сучасний оптимізований формат ",[5519,22889,22890],{},"WebP"," (потребує стороннього пакета ",[5511,22893,22894],{},"Pillow",[5621,22896,22897,22898,22901],{},"Збирає детальну статистику про хід виконання (успіх, помилка мережі, помилка обробки) за допомогою ",[5511,22899,22900],{},"collections.Counter"," та повертає відповідний код виходу в систему.",[5581,22903,22905],{"id":22904},"архітектура-проекту","Архітектура проекту",[5507,22907,22908],{},"Проект буде організований як повноцінний пакет Python з такою структурою директорій:",[5664,22910,22911,23210,23220,23366,23637,23647,23803],{},[5667,22912,22915],{"className":5669,"code":22913,"filename":22914,"language":5671,"meta":5672,"style":5672},"# Фасад пакета. Визначає версію та експортує головну функцію процесу.\n__version__ = \"1.0.0\"\n__all__ = [\"process_images\"]\n\nfrom .core.downloader import download_image\nfrom .core.converter import optimize_image\n\ndef process_images(urls: list, output_dir: str, width: int) -> dict:\n    \"\"\"Високорівнева функція-фасад для оркестрації завантаження та обробки.\"\"\"\n    from collections import Counter\n    from pathlib import Path\n\n    stats = Counter()\n    out_path = Path(output_dir)\n    out_path.mkdir(parents=True, exist_ok=True)\n\n    for i, url in enumerate(urls, 1):\n        try:\n            # Завантаження\n            img_bytes = download_image(url)\n            # Конвертація\n            dest_file = out_path \u002F f\"image_{i}.webp\"\n            optimize_image(img_bytes, dest_file, width)\n            stats[\"success\"] += 1\n        except ConnectionError:\n            stats[\"network_error\"] += 1\n        except Exception:\n            stats[\"processing_error\"] += 1\n\n    return dict(stats)\n","image_processor\u002F__init__.py",[5511,22916,22917,22922,22930,22941,22945,22957,22969,22973,23013,23018,23029,23039,23043,23048,23053,23074,23078,23096,23103,23108,23113,23118,23137,23142,23155,23165,23176,23185,23196,23200],{"__ignoreMap":5672},[5676,22918,22919],{"class":5678,"line":5679},[5676,22920,22921],{"class":5682},"# Фасад пакета. Визначає версію та експортує головну функцію процесу.\n",[5676,22923,22924,22926,22928],{"class":5678,"line":5686},[5676,22925,10981],{"class":5726},[5676,22927,10984],{"class":5696},[5676,22929,10987],{"class":5758},[5676,22931,22932,22934,22936,22939],{"class":5678,"line":5693},[5676,22933,7408],{"class":5726},[5676,22935,11003],{"class":5696},[5676,22937,22938],{"class":5758},"\"process_images\"",[5676,22940,8460],{"class":5696},[5676,22942,22943],{"class":5678,"line":5707},[5676,22944,5690],{"emptyLinePlaceholder":5689},[5676,22946,22947,22949,22952,22954],{"class":5678,"line":5712},[5676,22948,7020],{"class":5765},[5676,22950,22951],{"class":5696}," .core.downloader ",[5676,22953,6018],{"class":5765},[5676,22955,22956],{"class":5696}," download_image\n",[5676,22958,22959,22961,22964,22966],{"class":5678,"line":5755},[5676,22960,7020],{"class":5765},[5676,22962,22963],{"class":5696}," .core.converter ",[5676,22965,6018],{"class":5765},[5676,22967,22968],{"class":5696}," optimize_image\n",[5676,22970,22971],{"class":5678,"line":5762},[5676,22972,5690],{"emptyLinePlaceholder":5689},[5676,22974,22975,22977,22980,22982,22985,22987,22989,22991,22994,22996,22998,23000,23003,23005,23007,23009,23011],{"class":5678,"line":5772},[5676,22976,5716],{"class":5715},[5676,22978,22979],{"class":5719}," process_images",[5676,22981,5723],{"class":5696},[5676,22983,22984],{"class":5726},"urls",[5676,22986,5730],{"class":5696},[5676,22988,6779],{"class":5733},[5676,22990,5737],{"class":5696},[5676,22992,22993],{"class":5726},"output_dir",[5676,22995,5730],{"class":5696},[5676,22997,6258],{"class":5733},[5676,22999,5737],{"class":5696},[5676,23001,23002],{"class":5726},"width",[5676,23004,5730],{"class":5696},[5676,23006,5980],{"class":5733},[5676,23008,5747],{"class":5696},[5676,23010,6389],{"class":5733},[5676,23012,5752],{"class":5696},[5676,23014,23015],{"class":5678,"line":5777},[5676,23016,23017],{"class":5758},"    \"\"\"Високорівнева функція-фасад для оркестрації завантаження та обробки.\"\"\"\n",[5676,23019,23020,23023,23025,23027],{"class":5678,"line":5807},[5676,23021,23022],{"class":5765},"    from",[5676,23024,21967],{"class":5696},[5676,23026,6018],{"class":5765},[5676,23028,22272],{"class":5696},[5676,23030,23031,23033,23035,23037],{"class":5678,"line":5813},[5676,23032,23022],{"class":5765},[5676,23034,21482],{"class":5696},[5676,23036,6018],{"class":5765},[5676,23038,21487],{"class":5696},[5676,23040,23041],{"class":5678,"line":5821},[5676,23042,5690],{"emptyLinePlaceholder":5689},[5676,23044,23045],{"class":5678,"line":5826},[5676,23046,23047],{"class":5696},"    stats = Counter()\n",[5676,23049,23050],{"class":5678,"line":5856},[5676,23051,23052],{"class":5696},"    out_path = Path(output_dir)\n",[5676,23054,23055,23058,23060,23062,23064,23066,23068,23070,23072],{"class":5678,"line":5862},[5676,23056,23057],{"class":5696},"    out_path.mkdir(",[5676,23059,21635],{"class":5726},[5676,23061,9923],{"class":5696},[5676,23063,8589],{"class":5715},[5676,23065,5737],{"class":5696},[5676,23067,21644],{"class":5726},[5676,23069,9923],{"class":5696},[5676,23071,8589],{"class":5715},[5676,23073,6049],{"class":5696},[5676,23075,23076],{"class":5678,"line":5870},[5676,23077,5690],{"emptyLinePlaceholder":5689},[5676,23079,23080,23082,23085,23087,23089,23092,23094],{"class":5678,"line":5875},[5676,23081,11324],{"class":5765},[5676,23083,23084],{"class":5696}," i, url ",[5676,23086,5996],{"class":5765},[5676,23088,7766],{"class":5719},[5676,23090,23091],{"class":5696},"(urls, ",[5676,23093,7174],{"class":5700},[5676,23095,9450],{"class":5696},[5676,23097,23098,23101],{"class":5678,"line":5898},[5676,23099,23100],{"class":5765},"        try",[5676,23102,5752],{"class":5696},[5676,23104,23105],{"class":5678,"line":5904},[5676,23106,23107],{"class":5682},"            # Завантаження\n",[5676,23109,23110],{"class":5678,"line":5915},[5676,23111,23112],{"class":5696},"            img_bytes = download_image(url)\n",[5676,23114,23115],{"class":5678,"line":5920},[5676,23116,23117],{"class":5682},"            # Конвертація\n",[5676,23119,23120,23123,23125,23128,23130,23132,23134],{"class":5678,"line":5941},[5676,23121,23122],{"class":5696},"            dest_file = out_path \u002F ",[5676,23124,6073],{"class":5715},[5676,23126,23127],{"class":5758},"\"image_",[5676,23129,6079],{"class":5715},[5676,23131,7786],{"class":5696},[5676,23133,6085],{"class":5715},[5676,23135,23136],{"class":5758},".webp\"\n",[5676,23138,23139],{"class":5678,"line":5947},[5676,23140,23141],{"class":5696},"            optimize_image(img_bytes, dest_file, width)\n",[5676,23143,23144,23147,23150,23153],{"class":5678,"line":5953},[5676,23145,23146],{"class":5696},"            stats[",[5676,23148,23149],{"class":5758},"\"success\"",[5676,23151,23152],{"class":5696},"] += ",[5676,23154,8985],{"class":5700},[5676,23156,23157,23160,23163],{"class":5678,"line":5959},[5676,23158,23159],{"class":5765},"        except",[5676,23161,23162],{"class":5733}," ConnectionError",[5676,23164,5752],{"class":5696},[5676,23166,23167,23169,23172,23174],{"class":5678,"line":5964},[5676,23168,23146],{"class":5696},[5676,23170,23171],{"class":5758},"\"network_error\"",[5676,23173,23152],{"class":5696},[5676,23175,8985],{"class":5700},[5676,23177,23178,23180,23183],{"class":5678,"line":7576},[5676,23179,23159],{"class":5765},[5676,23181,23182],{"class":5733}," Exception",[5676,23184,5752],{"class":5696},[5676,23186,23187,23189,23192,23194],{"class":5678,"line":7581},[5676,23188,23146],{"class":5696},[5676,23190,23191],{"class":5758},"\"processing_error\"",[5676,23193,23152],{"class":5696},[5676,23195,8985],{"class":5700},[5676,23197,23198],{"class":5678,"line":7587},[5676,23199,5690],{"emptyLinePlaceholder":5689},[5676,23201,23202,23204,23207],{"class":5678,"line":7593},[5676,23203,5766],{"class":5765},[5676,23205,23206],{"class":5733}," dict",[5676,23208,23209],{"class":5696},"(stats)\n",[5667,23211,23214],{"className":5669,"code":23212,"filename":23213,"language":5671,"meta":5672,"style":5672},"# Ініціалізація підпакета core\n","image_processor\u002Fcore\u002F__init__.py",[5511,23215,23216],{"__ignoreMap":5672},[5676,23217,23218],{"class":5678,"line":5679},[5676,23219,23212],{"class":5682},[5667,23221,23224],{"className":5669,"code":23222,"filename":23223,"language":5671,"meta":5672,"style":5672},"import requests\n\ndef download_image(url: str) -> bytes:\n    \"\"\"Завантажує зображення за посиланням і повертає сирі байти.\"\"\"\n    try:\n        response = requests.get(url, timeout=10)\n        response.raise_for_status()  # підніме HTTPError при статус-кодах 4xx\u002F5xx\n        return response.content\n    except requests.RequestException as e:\n        # Логуємо помилку для налагодження\n        print(f\"Помилка мережі при завантаженні {url}: {e}\")\n        raise ConnectionError(f\"Не вдалося завантажити зображення: {e}\")\n","image_processor\u002Fcore\u002Fdownloader.py",[5511,23225,23226,23232,23236,23258,23263,23269,23283,23291,23298,23309,23314,23343],{"__ignoreMap":5672},[5676,23227,23228,23230],{"class":5678,"line":5679},[5676,23229,6018],{"class":5765},[5676,23231,13481],{"class":5696},[5676,23233,23234],{"class":5678,"line":5686},[5676,23235,5690],{"emptyLinePlaceholder":5689},[5676,23237,23238,23240,23243,23245,23247,23249,23251,23253,23256],{"class":5678,"line":5693},[5676,23239,5716],{"class":5715},[5676,23241,23242],{"class":5719}," download_image",[5676,23244,5723],{"class":5696},[5676,23246,8966],{"class":5726},[5676,23248,5730],{"class":5696},[5676,23250,6258],{"class":5733},[5676,23252,5747],{"class":5696},[5676,23254,23255],{"class":5733},"bytes",[5676,23257,5752],{"class":5696},[5676,23259,23260],{"class":5678,"line":5707},[5676,23261,23262],{"class":5758},"    \"\"\"Завантажує зображення за посиланням і повертає сирі байти.\"\"\"\n",[5676,23264,23265,23267],{"class":5678,"line":5712},[5676,23266,10042],{"class":5765},[5676,23268,5752],{"class":5696},[5676,23270,23271,23274,23277,23279,23281],{"class":5678,"line":5755},[5676,23272,23273],{"class":5696},"        response = requests.get(url, ",[5676,23275,23276],{"class":5726},"timeout",[5676,23278,9923],{"class":5696},[5676,23280,6041],{"class":5700},[5676,23282,6049],{"class":5696},[5676,23284,23285,23288],{"class":5678,"line":5762},[5676,23286,23287],{"class":5696},"        response.raise_for_status()  ",[5676,23289,23290],{"class":5682},"# підніме HTTPError при статус-кодах 4xx\u002F5xx\n",[5676,23292,23293,23295],{"class":5678,"line":5772},[5676,23294,9786],{"class":5765},[5676,23296,23297],{"class":5696}," response.content\n",[5676,23299,23300,23302,23305,23307],{"class":5678,"line":5777},[5676,23301,10104],{"class":5765},[5676,23303,23304],{"class":5696}," requests.RequestException ",[5676,23306,7104],{"class":5765},[5676,23308,10113],{"class":5696},[5676,23310,23311],{"class":5678,"line":5807},[5676,23312,23313],{"class":5682},"        # Логуємо помилку для налагодження\n",[5676,23315,23316,23318,23320,23322,23325,23327,23329,23331,23333,23335,23337,23339,23341],{"class":5678,"line":5813},[5676,23317,6685],{"class":5719},[5676,23319,5723],{"class":5696},[5676,23321,6073],{"class":5715},[5676,23323,23324],{"class":5758},"\"Помилка мережі при завантаженні ",[5676,23326,6079],{"class":5715},[5676,23328,8966],{"class":5696},[5676,23330,6085],{"class":5715},[5676,23332,5730],{"class":5758},[5676,23334,6079],{"class":5715},[5676,23336,10129],{"class":5696},[5676,23338,6085],{"class":5715},[5676,23340,6088],{"class":5758},[5676,23342,6049],{"class":5696},[5676,23344,23345,23347,23349,23351,23353,23356,23358,23360,23362,23364],{"class":5678,"line":5821},[5676,23346,11427],{"class":5765},[5676,23348,23162],{"class":5733},[5676,23350,5723],{"class":5696},[5676,23352,6073],{"class":5715},[5676,23354,23355],{"class":5758},"\"Не вдалося завантажити зображення: ",[5676,23357,6079],{"class":5715},[5676,23359,10129],{"class":5696},[5676,23361,6085],{"class":5715},[5676,23363,6088],{"class":5758},[5676,23365,6049],{"class":5696},[5667,23367,23370],{"className":5669,"code":23368,"filename":23369,"language":5671,"meta":5672,"style":5672},"import io\nfrom PIL import Image\nfrom pathlib import Path\n\ndef optimize_image(image_bytes: bytes, output_path: Path, target_width: int) -> None:\n    \"\"\"Змінює розмір зображення (зберігаючи пропорції) та конвертує в WebP.\"\"\"\n    try:\n        # Читаємо зображення з байтового потоку в пам'яті\n        with Image.open(io.BytesIO(image_bytes)) as img:\n            # Розрахунок нової висоти зі збереженням пропорцій\n            width_percent = target_width \u002F float(img.size[0])\n            target_height = int(float(img.size[1]) * float(width_percent))\n\n            # Зміна розміру\n            resized_img = img.resize((target_width, target_height), Image.Resampling.LANCZOS)\n\n            # Збереження у форматі WebP з оптимізацією якості\n            resized_img.save(output_path, format=\"WEBP\", quality=85)\n            print(f\"Збережено оптимізоване зображення: {output_path}\")\n    except Exception as e:\n        print(f\"Помилка обробки зображення: {e}\")\n        raise RuntimeError(f\"Не вдалося обробити зображення: {e}\")\n","image_processor\u002Fcore\u002Fconverter.py",[5511,23371,23372,23379,23391,23401,23405,23441,23446,23452,23457,23470,23475,23489,23512,23516,23521,23526,23530,23535,23560,23582,23592,23613],{"__ignoreMap":5672},[5676,23373,23374,23376],{"class":5678,"line":5679},[5676,23375,6018],{"class":5765},[5676,23377,23378],{"class":5696}," io\n",[5676,23380,23381,23383,23386,23388],{"class":5678,"line":5686},[5676,23382,7020],{"class":5765},[5676,23384,23385],{"class":5696}," PIL ",[5676,23387,6018],{"class":5765},[5676,23389,23390],{"class":5696}," Image\n",[5676,23392,23393,23395,23397,23399],{"class":5678,"line":5693},[5676,23394,7020],{"class":5765},[5676,23396,21482],{"class":5696},[5676,23398,6018],{"class":5765},[5676,23400,21487],{"class":5696},[5676,23402,23403],{"class":5678,"line":5707},[5676,23404,5690],{"emptyLinePlaceholder":5689},[5676,23406,23407,23409,23412,23414,23417,23419,23421,23423,23425,23428,23431,23433,23435,23437,23439],{"class":5678,"line":5712},[5676,23408,5716],{"class":5715},[5676,23410,23411],{"class":5719}," optimize_image",[5676,23413,5723],{"class":5696},[5676,23415,23416],{"class":5726},"image_bytes",[5676,23418,5730],{"class":5696},[5676,23420,23255],{"class":5733},[5676,23422,5737],{"class":5696},[5676,23424,9879],{"class":5726},[5676,23426,23427],{"class":5696},": Path, ",[5676,23429,23430],{"class":5726},"target_width",[5676,23432,5730],{"class":5696},[5676,23434,5980],{"class":5733},[5676,23436,5747],{"class":5696},[5676,23438,8975],{"class":5715},[5676,23440,5752],{"class":5696},[5676,23442,23443],{"class":5678,"line":5755},[5676,23444,23445],{"class":5758},"    \"\"\"Змінює розмір зображення (зберігаючи пропорції) та конвертує в WebP.\"\"\"\n",[5676,23447,23448,23450],{"class":5678,"line":5762},[5676,23449,10042],{"class":5765},[5676,23451,5752],{"class":5696},[5676,23453,23454],{"class":5678,"line":5772},[5676,23455,23456],{"class":5682},"        # Читаємо зображення з байтового потоку в пам'яті\n",[5676,23458,23459,23462,23465,23467],{"class":5678,"line":5777},[5676,23460,23461],{"class":5765},"        with",[5676,23463,23464],{"class":5696}," Image.open(io.BytesIO(image_bytes)) ",[5676,23466,7104],{"class":5765},[5676,23468,23469],{"class":5696}," img:\n",[5676,23471,23472],{"class":5678,"line":5807},[5676,23473,23474],{"class":5682},"            # Розрахунок нової висоти зі збереженням пропорцій\n",[5676,23476,23477,23480,23482,23485,23487],{"class":5678,"line":5813},[5676,23478,23479],{"class":5696},"            width_percent = target_width \u002F ",[5676,23481,5734],{"class":5733},[5676,23483,23484],{"class":5696},"(img.size[",[5676,23486,8035],{"class":5700},[5676,23488,7185],{"class":5696},[5676,23490,23491,23494,23496,23498,23500,23502,23504,23507,23509],{"class":5678,"line":5821},[5676,23492,23493],{"class":5696},"            target_height = ",[5676,23495,5980],{"class":5733},[5676,23497,5723],{"class":5696},[5676,23499,5734],{"class":5733},[5676,23501,23484],{"class":5696},[5676,23503,7174],{"class":5700},[5676,23505,23506],{"class":5696},"]) * ",[5676,23508,5734],{"class":5733},[5676,23510,23511],{"class":5696},"(width_percent))\n",[5676,23513,23514],{"class":5678,"line":5826},[5676,23515,5690],{"emptyLinePlaceholder":5689},[5676,23517,23518],{"class":5678,"line":5856},[5676,23519,23520],{"class":5682},"            # Зміна розміру\n",[5676,23522,23523],{"class":5678,"line":5862},[5676,23524,23525],{"class":5696},"            resized_img = img.resize((target_width, target_height), Image.Resampling.LANCZOS)\n",[5676,23527,23528],{"class":5678,"line":5870},[5676,23529,5690],{"emptyLinePlaceholder":5689},[5676,23531,23532],{"class":5678,"line":5875},[5676,23533,23534],{"class":5682},"            # Збереження у форматі WebP з оптимізацією якості\n",[5676,23536,23537,23540,23543,23545,23548,23550,23553,23555,23558],{"class":5678,"line":5898},[5676,23538,23539],{"class":5696},"            resized_img.save(output_path, ",[5676,23541,23542],{"class":5726},"format",[5676,23544,9923],{"class":5696},[5676,23546,23547],{"class":5758},"\"WEBP\"",[5676,23549,5737],{"class":5696},[5676,23551,23552],{"class":5726},"quality",[5676,23554,9923],{"class":5696},[5676,23556,23557],{"class":5700},"85",[5676,23559,6049],{"class":5696},[5676,23561,23562,23565,23567,23569,23572,23574,23576,23578,23580],{"class":5678,"line":5904},[5676,23563,23564],{"class":5719},"            print",[5676,23566,5723],{"class":5696},[5676,23568,6073],{"class":5715},[5676,23570,23571],{"class":5758},"\"Збережено оптимізоване зображення: ",[5676,23573,6079],{"class":5715},[5676,23575,9879],{"class":5696},[5676,23577,6085],{"class":5715},[5676,23579,6088],{"class":5758},[5676,23581,6049],{"class":5696},[5676,23583,23584,23586,23588,23590],{"class":5678,"line":5915},[5676,23585,10104],{"class":5765},[5676,23587,23182],{"class":5733},[5676,23589,10110],{"class":5765},[5676,23591,10113],{"class":5696},[5676,23593,23594,23596,23598,23600,23603,23605,23607,23609,23611],{"class":5678,"line":5920},[5676,23595,6685],{"class":5719},[5676,23597,5723],{"class":5696},[5676,23599,6073],{"class":5715},[5676,23601,23602],{"class":5758},"\"Помилка обробки зображення: ",[5676,23604,6079],{"class":5715},[5676,23606,10129],{"class":5696},[5676,23608,6085],{"class":5715},[5676,23610,6088],{"class":5758},[5676,23612,6049],{"class":5696},[5676,23614,23615,23617,23620,23622,23624,23627,23629,23631,23633,23635],{"class":5678,"line":5941},[5676,23616,11427],{"class":5765},[5676,23618,23619],{"class":5733}," RuntimeError",[5676,23621,5723],{"class":5696},[5676,23623,6073],{"class":5715},[5676,23625,23626],{"class":5758},"\"Не вдалося обробити зображення: ",[5676,23628,6079],{"class":5715},[5676,23630,10129],{"class":5696},[5676,23632,6085],{"class":5715},[5676,23634,6088],{"class":5758},[5676,23636,6049],{"class":5696},[5667,23638,23641],{"className":5669,"code":23639,"filename":23640,"language":5671,"meta":5672,"style":5672},"# Ініціалізація підпакета utils\n","image_processor\u002Futils\u002F__init__.py",[5511,23642,23643],{"__ignoreMap":5672},[5676,23644,23645],{"class":5678,"line":5679},[5676,23646,23639],{"class":5682},[5667,23648,23651],{"className":5669,"code":23649,"filename":23650,"language":5671,"meta":5672,"style":5672},"from pathlib import Path\n\ndef load_urls_from_file(file_path: str) -> list:\n    \"\"\"Читає список URL-адрес із текстового файлу, очищаючи порожні рядки.\"\"\"\n    path = Path(file_path)\n    if not path.is_file():\n        raise FileNotFoundError(f\"Файл конфігурації не знайдено за шляхом: {file_path}\")\n\n    with open(path, \"r\", encoding=\"utf-8\") as f:\n        # Читаємо рядки, прибираємо пробіли та фільтруємо порожні\n        return [line.strip() for line in f if line.strip() and not line.startswith(\"#\")]\n","image_processor\u002Futils\u002Fhelpers.py",[5511,23652,23653,23663,23667,23689,23694,23699,23708,23731,23735,23763,23768],{"__ignoreMap":5672},[5676,23654,23655,23657,23659,23661],{"class":5678,"line":5679},[5676,23656,7020],{"class":5765},[5676,23658,21482],{"class":5696},[5676,23660,6018],{"class":5765},[5676,23662,21487],{"class":5696},[5676,23664,23665],{"class":5678,"line":5686},[5676,23666,5690],{"emptyLinePlaceholder":5689},[5676,23668,23669,23671,23674,23676,23679,23681,23683,23685,23687],{"class":5678,"line":5693},[5676,23670,5716],{"class":5715},[5676,23672,23673],{"class":5719}," load_urls_from_file",[5676,23675,5723],{"class":5696},[5676,23677,23678],{"class":5726},"file_path",[5676,23680,5730],{"class":5696},[5676,23682,6258],{"class":5733},[5676,23684,5747],{"class":5696},[5676,23686,6779],{"class":5733},[5676,23688,5752],{"class":5696},[5676,23690,23691],{"class":5678,"line":5707},[5676,23692,23693],{"class":5758},"    \"\"\"Читає список URL-адрес із текстового файлу, очищаючи порожні рядки.\"\"\"\n",[5676,23695,23696],{"class":5678,"line":5712},[5676,23697,23698],{"class":5696},"    path = Path(file_path)\n",[5676,23700,23701,23703,23705],{"class":5678,"line":5755},[5676,23702,9967],{"class":5765},[5676,23704,18889],{"class":5715},[5676,23706,23707],{"class":5696}," path.is_file():\n",[5676,23709,23710,23712,23714,23716,23718,23721,23723,23725,23727,23729],{"class":5678,"line":5762},[5676,23711,11427],{"class":5765},[5676,23713,10107],{"class":5733},[5676,23715,5723],{"class":5696},[5676,23717,6073],{"class":5715},[5676,23719,23720],{"class":5758},"\"Файл конфігурації не знайдено за шляхом: ",[5676,23722,6079],{"class":5715},[5676,23724,23678],{"class":5696},[5676,23726,6085],{"class":5715},[5676,23728,6088],{"class":5758},[5676,23730,6049],{"class":5696},[5676,23732,23733],{"class":5678,"line":5772},[5676,23734,5690],{"emptyLinePlaceholder":5689},[5676,23736,23737,23739,23741,23744,23747,23749,23752,23754,23757,23759,23761],{"class":5678,"line":5777},[5676,23738,9770],{"class":5765},[5676,23740,9773],{"class":5719},[5676,23742,23743],{"class":5696},"(path, ",[5676,23745,23746],{"class":5758},"\"r\"",[5676,23748,5737],{"class":5696},[5676,23750,23751],{"class":5726},"encoding",[5676,23753,9923],{"class":5696},[5676,23755,23756],{"class":5758},"\"utf-8\"",[5676,23758,6118],{"class":5696},[5676,23760,7104],{"class":5765},[5676,23762,9781],{"class":5696},[5676,23764,23765],{"class":5678,"line":5807},[5676,23766,23767],{"class":5682},"        # Читаємо рядки, прибираємо пробіли та фільтруємо порожні\n",[5676,23769,23770,23772,23775,23777,23780,23782,23785,23787,23790,23793,23795,23798,23801],{"class":5678,"line":5813},[5676,23771,9786],{"class":5765},[5676,23773,23774],{"class":5696}," [line.strip() ",[5676,23776,5990],{"class":5765},[5676,23778,23779],{"class":5696}," line ",[5676,23781,5996],{"class":5765},[5676,23783,23784],{"class":5696}," f ",[5676,23786,9577],{"class":5765},[5676,23788,23789],{"class":5696}," line.strip() ",[5676,23791,23792],{"class":5715},"and",[5676,23794,18889],{"class":5715},[5676,23796,23797],{"class":5696}," line.startswith(",[5676,23799,23800],{"class":5758},"\"#\"",[5676,23802,9854],{"class":5696},[5667,23804,23807],{"className":5669,"code":23805,"filename":23806,"language":5671,"meta":5672,"style":5672},"import sys\nfrom pathlib import Path\nfrom image_processor.utils.helpers import load_urls_from_file\nfrom image_processor import process_images\n\ndef main() -> int:\n    \"\"\"\n    Головна точка входу.\n    Використання: python -m image_processor.main \u003Curls.txt> \u003Coutput_dir> [width]\n    Повертає 0 при успіху, 1 при загальній помилці конфігурації.\n    \"\"\"\n    if len(sys.argv) \u003C 3:\n        print(\"Помилка: Недостатньо аргументів!\")\n        print(f\"Використання: python -m {__package__}.main \u003Curls.txt> \u003Coutput_dir> [width]\")\n        return 1\n\n    urls_file = sys.argv[1]\n    output_dir = sys.argv[2]\n    # Опціональний параметр ширини, за замовчуванням 800px\n    target_width = int(sys.argv[3]) if len(sys.argv) > 3 else 800\n\n    try:\n        # Завантаження лінків через хелпер\n        urls = load_urls_from_file(urls_file)\n        if not urls:\n            print(f\"Попередження: Файл {urls_file} не містить URL для обробки.\")\n            return 0\n\n        print(f\"Знайдено {len(urls)} посилань. Починаємо обробку...\")\n\n        # Запуск оркестратора з фасаду\n        stats = process_images(urls, output_dir, target_width)\n\n        print(\"\\n=== Статистика обробки ===\")\n        print(f\"  Успішно оброблено: {stats.get('success', 0)}\")\n        print(f\"  Помилок мережі:    {stats.get('network_error', 0)}\")\n        print(f\"  Помилок обробки:   {stats.get('processing_error', 0)}\")\n\n        return 0\n\n    except FileNotFoundError as e:\n        print(f\"Помилка конфігурації: {e}\")\n        return 1\n    except ValueError:\n        print(\"Помилка: Параметр ширини має бути цілим числом!\")\n        return 1\n\nif __name__ == \"__main__\":\n    # Повертаємо статус-код оболонці\n    sys.exit(main())\n","image_processor\u002Fmain.py",[5511,23808,23809,23815,23825,23837,23849,23853,23865,23869,23874,23879,23884,23888,23901,23912,23935,23941,23945,23954,23963,23968,23998,24002,24008,24013,24018,24027,24050,24056,24060,24085,24089,24094,24099,24103,24118,24149,24179,24209,24213,24219,24223,24233,24254,24260,24268,24279,24285,24290,24303,24309],{"__ignoreMap":5672},[5676,23810,23811,23813],{"class":5678,"line":5679},[5676,23812,6018],{"class":5765},[5676,23814,6970],{"class":5696},[5676,23816,23817,23819,23821,23823],{"class":5678,"line":5686},[5676,23818,7020],{"class":5765},[5676,23820,21482],{"class":5696},[5676,23822,6018],{"class":5765},[5676,23824,21487],{"class":5696},[5676,23826,23827,23829,23832,23834],{"class":5678,"line":5693},[5676,23828,7020],{"class":5765},[5676,23830,23831],{"class":5696}," image_processor.utils.helpers ",[5676,23833,6018],{"class":5765},[5676,23835,23836],{"class":5696}," load_urls_from_file\n",[5676,23838,23839,23841,23844,23846],{"class":5678,"line":5707},[5676,23840,7020],{"class":5765},[5676,23842,23843],{"class":5696}," image_processor ",[5676,23845,6018],{"class":5765},[5676,23847,23848],{"class":5696}," process_images\n",[5676,23850,23851],{"class":5678,"line":5712},[5676,23852,5690],{"emptyLinePlaceholder":5689},[5676,23854,23855,23857,23859,23861,23863],{"class":5678,"line":5755},[5676,23856,5716],{"class":5715},[5676,23858,9938],{"class":5719},[5676,23860,9050],{"class":5696},[5676,23862,5980],{"class":5733},[5676,23864,5752],{"class":5696},[5676,23866,23867],{"class":5678,"line":5762},[5676,23868,5944],{"class":5758},[5676,23870,23871],{"class":5678,"line":5772},[5676,23872,23873],{"class":5758},"    Головна точка входу.\n",[5676,23875,23876],{"class":5678,"line":5777},[5676,23877,23878],{"class":5758},"    Використання: python -m image_processor.main \u003Curls.txt> \u003Coutput_dir> [width]\n",[5676,23880,23881],{"class":5678,"line":5807},[5676,23882,23883],{"class":5758},"    Повертає 0 при успіху, 1 при загальній помилці конфігурації.\n",[5676,23885,23886],{"class":5678,"line":5813},[5676,23887,5944],{"class":5758},[5676,23889,23890,23892,23894,23897,23899],{"class":5678,"line":5821},[5676,23891,9967],{"class":5765},[5676,23893,9970],{"class":5719},[5676,23895,23896],{"class":5696},"(sys.argv) \u003C ",[5676,23898,7164],{"class":5700},[5676,23900,5752],{"class":5696},[5676,23902,23903,23905,23907,23910],{"class":5678,"line":5826},[5676,23904,6685],{"class":5719},[5676,23906,5723],{"class":5696},[5676,23908,23909],{"class":5758},"\"Помилка: Недостатньо аргументів!\"",[5676,23911,6049],{"class":5696},[5676,23913,23914,23916,23918,23920,23923,23925,23928,23930,23933],{"class":5678,"line":5856},[5676,23915,6685],{"class":5719},[5676,23917,5723],{"class":5696},[5676,23919,6073],{"class":5715},[5676,23921,23922],{"class":5758},"\"Використання: python -m ",[5676,23924,6079],{"class":5715},[5676,23926,23927],{"class":5726},"__package__",[5676,23929,6085],{"class":5715},[5676,23931,23932],{"class":5758},".main \u003Curls.txt> \u003Coutput_dir> [width]\"",[5676,23934,6049],{"class":5696},[5676,23936,23937,23939],{"class":5678,"line":5862},[5676,23938,9786],{"class":5765},[5676,23940,10011],{"class":5700},[5676,23942,23943],{"class":5678,"line":5870},[5676,23944,5690],{"emptyLinePlaceholder":5689},[5676,23946,23947,23950,23952],{"class":5678,"line":5875},[5676,23948,23949],{"class":5696},"    urls_file = sys.argv[",[5676,23951,7174],{"class":5700},[5676,23953,8460],{"class":5696},[5676,23955,23956,23959,23961],{"class":5678,"line":5898},[5676,23957,23958],{"class":5696},"    output_dir = sys.argv[",[5676,23960,6322],{"class":5700},[5676,23962,8460],{"class":5696},[5676,23964,23965],{"class":5678,"line":5904},[5676,23966,23967],{"class":5682},"    # Опціональний параметр ширини, за замовчуванням 800px\n",[5676,23969,23970,23973,23975,23978,23980,23983,23985,23987,23990,23992,23995],{"class":5678,"line":5915},[5676,23971,23972],{"class":5696},"    target_width = ",[5676,23974,5980],{"class":5733},[5676,23976,23977],{"class":5696},"(sys.argv[",[5676,23979,7164],{"class":5700},[5676,23981,23982],{"class":5696},"]) ",[5676,23984,9577],{"class":5765},[5676,23986,9970],{"class":5719},[5676,23988,23989],{"class":5696},"(sys.argv) > ",[5676,23991,7164],{"class":5700},[5676,23993,23994],{"class":5765}," else",[5676,23996,23997],{"class":5700}," 800\n",[5676,23999,24000],{"class":5678,"line":5920},[5676,24001,5690],{"emptyLinePlaceholder":5689},[5676,24003,24004,24006],{"class":5678,"line":5941},[5676,24005,10042],{"class":5765},[5676,24007,5752],{"class":5696},[5676,24009,24010],{"class":5678,"line":5947},[5676,24011,24012],{"class":5682},"        # Завантаження лінків через хелпер\n",[5676,24014,24015],{"class":5678,"line":5953},[5676,24016,24017],{"class":5696},"        urls = load_urls_from_file(urls_file)\n",[5676,24019,24020,24022,24024],{"class":5678,"line":5959},[5676,24021,11337],{"class":5765},[5676,24023,18889],{"class":5715},[5676,24025,24026],{"class":5696}," urls:\n",[5676,24028,24029,24031,24033,24035,24038,24040,24043,24045,24048],{"class":5678,"line":5964},[5676,24030,23564],{"class":5719},[5676,24032,5723],{"class":5696},[5676,24034,6073],{"class":5715},[5676,24036,24037],{"class":5758},"\"Попередження: Файл ",[5676,24039,6079],{"class":5715},[5676,24041,24042],{"class":5696},"urls_file",[5676,24044,6085],{"class":5715},[5676,24046,24047],{"class":5758}," не містить URL для обробки.\"",[5676,24049,6049],{"class":5696},[5676,24051,24052,24054],{"class":5678,"line":7576},[5676,24053,11350],{"class":5765},[5676,24055,10099],{"class":5700},[5676,24057,24058],{"class":5678,"line":7581},[5676,24059,5690],{"emptyLinePlaceholder":5689},[5676,24061,24062,24064,24066,24068,24071,24073,24075,24078,24080,24083],{"class":5678,"line":7587},[5676,24063,6685],{"class":5719},[5676,24065,5723],{"class":5696},[5676,24067,6073],{"class":5715},[5676,24069,24070],{"class":5758},"\"Знайдено ",[5676,24072,6079],{"class":5715},[5676,24074,7742],{"class":5719},[5676,24076,24077],{"class":5696},"(urls)",[5676,24079,6085],{"class":5715},[5676,24081,24082],{"class":5758}," посилань. Починаємо обробку...\"",[5676,24084,6049],{"class":5696},[5676,24086,24087],{"class":5678,"line":7593},[5676,24088,5690],{"emptyLinePlaceholder":5689},[5676,24090,24091],{"class":5678,"line":7599},[5676,24092,24093],{"class":5682},"        # Запуск оркестратора з фасаду\n",[5676,24095,24096],{"class":5678,"line":7605},[5676,24097,24098],{"class":5696},"        stats = process_images(urls, output_dir, target_width)\n",[5676,24100,24101],{"class":5678,"line":7611},[5676,24102,5690],{"emptyLinePlaceholder":5689},[5676,24104,24105,24107,24109,24111,24113,24116],{"class":5678,"line":7617},[5676,24106,6685],{"class":5719},[5676,24108,5723],{"class":5696},[5676,24110,6088],{"class":5758},[5676,24112,6760],{"class":6759},[5676,24114,24115],{"class":5758},"=== Статистика обробки ===\"",[5676,24117,6049],{"class":5696},[5676,24119,24120,24122,24124,24126,24129,24131,24134,24137,24139,24141,24143,24145,24147],{"class":5678,"line":7622},[5676,24121,6685],{"class":5719},[5676,24123,5723],{"class":5696},[5676,24125,6073],{"class":5715},[5676,24127,24128],{"class":5758},"\"  Успішно оброблено: ",[5676,24130,6079],{"class":5715},[5676,24132,24133],{"class":5696},"stats.get(",[5676,24135,24136],{"class":5758},"'success'",[5676,24138,5737],{"class":5696},[5676,24140,8035],{"class":5700},[5676,24142,5631],{"class":5696},[5676,24144,6085],{"class":5715},[5676,24146,6088],{"class":5758},[5676,24148,6049],{"class":5696},[5676,24150,24151,24153,24155,24157,24160,24162,24164,24167,24169,24171,24173,24175,24177],{"class":5678,"line":7627},[5676,24152,6685],{"class":5719},[5676,24154,5723],{"class":5696},[5676,24156,6073],{"class":5715},[5676,24158,24159],{"class":5758},"\"  Помилок мережі:    ",[5676,24161,6079],{"class":5715},[5676,24163,24133],{"class":5696},[5676,24165,24166],{"class":5758},"'network_error'",[5676,24168,5737],{"class":5696},[5676,24170,8035],{"class":5700},[5676,24172,5631],{"class":5696},[5676,24174,6085],{"class":5715},[5676,24176,6088],{"class":5758},[5676,24178,6049],{"class":5696},[5676,24180,24181,24183,24185,24187,24190,24192,24194,24197,24199,24201,24203,24205,24207],{"class":5678,"line":7633},[5676,24182,6685],{"class":5719},[5676,24184,5723],{"class":5696},[5676,24186,6073],{"class":5715},[5676,24188,24189],{"class":5758},"\"  Помилок обробки:   ",[5676,24191,6079],{"class":5715},[5676,24193,24133],{"class":5696},[5676,24195,24196],{"class":5758},"'processing_error'",[5676,24198,5737],{"class":5696},[5676,24200,8035],{"class":5700},[5676,24202,5631],{"class":5696},[5676,24204,6085],{"class":5715},[5676,24206,6088],{"class":5758},[5676,24208,6049],{"class":5696},[5676,24210,24211],{"class":5678,"line":7639},[5676,24212,5690],{"emptyLinePlaceholder":5689},[5676,24214,24215,24217],{"class":5678,"line":7645},[5676,24216,9786],{"class":5765},[5676,24218,10099],{"class":5700},[5676,24220,24221],{"class":5678,"line":7651},[5676,24222,5690],{"emptyLinePlaceholder":5689},[5676,24224,24225,24227,24229,24231],{"class":5678,"line":7657},[5676,24226,10104],{"class":5765},[5676,24228,10107],{"class":5733},[5676,24230,10110],{"class":5765},[5676,24232,10113],{"class":5696},[5676,24234,24235,24237,24239,24241,24244,24246,24248,24250,24252],{"class":5678,"line":7663},[5676,24236,6685],{"class":5719},[5676,24238,5723],{"class":5696},[5676,24240,6073],{"class":5715},[5676,24242,24243],{"class":5758},"\"Помилка конфігурації: ",[5676,24245,6079],{"class":5715},[5676,24247,10129],{"class":5696},[5676,24249,6085],{"class":5715},[5676,24251,6088],{"class":5758},[5676,24253,6049],{"class":5696},[5676,24255,24256,24258],{"class":5678,"line":7669},[5676,24257,9786],{"class":5765},[5676,24259,10011],{"class":5700},[5676,24261,24262,24264,24266],{"class":5678,"line":7674},[5676,24263,10104],{"class":5765},[5676,24265,11430],{"class":5733},[5676,24267,5752],{"class":5696},[5676,24269,24270,24272,24274,24277],{"class":5678,"line":10190},[5676,24271,6685],{"class":5719},[5676,24273,5723],{"class":5696},[5676,24275,24276],{"class":5758},"\"Помилка: Параметр ширини має бути цілим числом!\"",[5676,24278,6049],{"class":5696},[5676,24280,24281,24283],{"class":5678,"line":10203},[5676,24282,9786],{"class":5765},[5676,24284,10011],{"class":5700},[5676,24286,24288],{"class":5678,"line":24287},47,[5676,24289,5690],{"emptyLinePlaceholder":5689},[5676,24291,24293,24295,24297,24299,24301],{"class":5678,"line":24292},48,[5676,24294,9577],{"class":5765},[5676,24296,9580],{"class":5726},[5676,24298,9583],{"class":5696},[5676,24300,9586],{"class":5758},[5676,24302,5752],{"class":5696},[5676,24304,24306],{"class":5678,"line":24305},49,[5676,24307,24308],{"class":5682},"    # Повертаємо статус-код оболонці\n",[5676,24310,24312],{"class":5678,"line":24311},50,[5676,24313,24314],{"class":5696},"    sys.exit(main())\n",[5574,24316],{},[5581,24318,24320],{"id":24319},"пакетна-реалізація-проекту-крок-за-кроком","Пакетна реалізація проекту крок за кроком",[6412,24322,24323,24327,24335,24389,24393,24401,24439,24443,24450,24471,24475,24486,24492,24496,24513,24572,24576,24585],{},[5581,24324,24326],{"id":24325},"налаштування-директорії-та-ізоляції-venv","Налаштування директорії та ізоляції (venv)",[5507,24328,24329,24330,6594,24332,24334],{},"Створимо структуру папок та ініціалізуємо ізольоване віртуальне середовище, щоб сторонні пакети ",[5511,24331,7989],{},[5511,24333,22894],{}," не конфліктували з іншими версіями у глобальній системі.",[6145,24336,24338,24347,24356,24365,24373,24385],{"title":24337},"Ініціалізація оточення",[6149,24339,24341,6157,24344],{"className":24340},[5678],[5676,24342,6156],{"className":24343},[6155],[5519,24345,24346],{},"mkdir -p my_project\u002Fimage_processor\u002Fcore my_project\u002Fimage_processor\u002Futils",[6149,24348,24350,6157,24353],{"className":24349},[5678],[5676,24351,6156],{"className":24352},[6155],[5519,24354,24355],{},"cd my_project",[6149,24357,24359,6157,24362],{"className":24358},[5678],[5676,24360,6156],{"className":24361},[6155],[5519,24363,24364],{},"python3.12 -m venv .venv",[6149,24366,24368,6157,24371],{"className":24367},[5678],[5676,24369,6156],{"className":24370},[6155],[5519,24372,13114],{},[6149,24374,24376,6157,24379,6157,24382],{"className":24375},[5678],[5676,24377,13491],{"className":24378},[6167],[5676,24380,6156],{"className":24381},[6155],[5519,24383,24384],{},"which python",[6149,24386,24388],{"className":24387},[5678],"\u002FUsers\u002Fuser\u002Fmy_project\u002F.venv\u002Fbin\u002Fpython",[5581,24390,24392],{"id":24391},"встановлення-та-фіксація-залежностей","Встановлення та фіксація залежностей",[5507,24394,24395,24396,24398,24399,5572],{},"Встановимо необхідні сторонні бібліотеки через ",[5511,24397,8268],{}," та запишемо їх у ",[5511,24400,13586],{},[6145,24402,24404,24416,24420,24424,24428],{"title":24403},"Встановлення залежностей через pip",[6149,24405,24407,6157,24410,6157,24413],{"className":24406},[5678],[5676,24408,13491],{"className":24409},[6167],[5676,24411,6156],{"className":24412},[6155],[5519,24414,24415],{},"pip install requests Pillow",[6149,24417,24419],{"className":24418},[5678],"Collecting requests...",[6149,24421,24423],{"className":24422},[5678],"Collecting Pillow...",[6149,24425,24427],{"className":24426},[5678],"Successfully installed requests-2.31.0 Pillow-10.2.0 ...",[6149,24429,24431,6157,24434,6157,24437],{"className":24430},[5678],[5676,24432,13491],{"className":24433},[6167],[5676,24435,6156],{"className":24436},[6155],[5519,24438,13650],{},[5581,24440,24442],{"id":24441},"створення-вихідних-файлів-коду","Створення вихідних файлів коду",[5507,24444,24445,24446,24449],{},"Запишіть код для кожного з файлів структури проекту ",[5511,24447,24448],{},"image_processor"," відповідно до архітектурного опису, наведеного вище.",[13141,24451,24452,24453,5752,24455,24458,24459,24461,24462,24465,24466,24468,24469,5572],{},"Зверніть увагу на відносні імпорти у файлі ",[5511,24454,22914],{},[5511,24456,24457],{},"from .core.downloader import download_image","\nЦе гарантує локальну цілісність пакета. Натомість у файлі ",[5511,24460,5513],{},", який виступає точкою запуску, використовуються абсолютні імпорти:\n",[5511,24463,24464],{},"from image_processor import process_images","\nоскільки при запуску через ",[5511,24467,10231],{}," точка входу має викликатися з кореня ",[5511,24470,5630],{},[5581,24472,24474],{"id":24473},"підготовка-тестових-даних","Підготовка тестових даних",[5507,24476,24477,24478,24481,24482,24485],{},"Створимо файл ",[5511,24479,24480],{},"urls.txt"," в корені проекту ",[5511,24483,24484],{},"my_project\u002F"," зі списком реальних тестових зображень для завантаження:",[5667,24487,24490],{"className":24488,"code":24489,"language":10831,"meta":5672},[10829],"# urls.txt\n# Список зображень для оптимізації\nhttps:\u002F\u002Fimages.unsplash.com\u002Fphoto-1579783900882-c0d3dad7b119?w=1200\nhttps:\u002F\u002Fimages.unsplash.com\u002Fphoto-1541701494587-cb58502866ab?w=1200\n# Невалідний URL для тестування стійкості до помилок:\nhttps:\u002F\u002Fnon-existent-domain-xyz.com\u002Fimage.jpg\n",[5511,24491,24489],{"__ignoreMap":5672},[5581,24493,24495],{"id":24494},"запуск-та-аналіз-роботи-cli","Запуск та аналіз роботи CLI",[5507,24497,24498,24499,24501,24502,24504,24505,24508,24509,24512],{},"Запустимо наш пакет із кореневої папки проекту за допомогою прапорця інтерпретатора ",[5511,24500,7930],{},". Ми вкажемо вхідний файл ",[5511,24503,24480],{},", папку збереження ",[5511,24506,24507],{},"optimized_images"," та бажану ширину ",[5511,24510,24511],{},"600"," пікселів.",[6145,24514,24516,24528,24532,24536,24540,24544,24547,24551,24558,24565],{"title":24515},"Запуск утиліти",[6149,24517,24519,6157,24522,6157,24525],{"className":24518},[5678],[5676,24520,13491],{"className":24521},[6167],[5676,24523,6156],{"className":24524},[6155],[5519,24526,24527],{},"python -m image_processor.main urls.txt .\u002Foptimized_images 600",[6149,24529,24531],{"className":24530},[5678],"Знайдено 2 посилань. Починаємо обробку...",[6149,24533,24535],{"className":24534},[5678],"Збережено оптимізоване зображення: optimized_images\u002Fimage_1.webp",[6149,24537,24539],{"className":24538},[5678],"Збережено оптимізоване зображення: optimized_images\u002Fimage_2.webp",[6149,24541,24543],{"className":24542},[5678],"Помилка мережі при завантаженні https:\u002F\u002Fnon-existent-domain-xyz.com\u002Fimage.jpg...",[6149,24545],{"className":24546},[5678],[6149,24548,24550],{"className":24549},[5678],"=== Статистика обробки ===",[6149,24552,24554,24555],{"className":24553},[5678],"  Успішно оброблено: ",[5676,24556,6322],{"className":24557},[6167],[6149,24559,24561,24562],{"className":24560},[5678],"  Помилок мережі:    ",[5676,24563,7174],{"className":24564},[8861],[6149,24566,24568,24569],{"className":24567},[5678],"  Помилок обробки:   ",[5676,24570,8035],{"className":24571},[8861],[5581,24573,24575],{"id":24574},"перевірка-результатів-на-диску","Перевірка результатів на диску",[5507,24577,24578,24579,24581,24582,24584],{},"Перевіримо вміст автоматично створеної директорії ",[5511,24580,24507],{}," за допомогою ",[5511,24583,21421],{},"-подібних команд або звичайної утиліти перегляду.",[6145,24586,24588,24600,24604,24608],{"title":24587},"Перевірка результатів",[6149,24589,24591,6157,24594,6157,24597],{"className":24590},[5678],[5676,24592,13491],{"className":24593},[6167],[5676,24595,6156],{"className":24596},[6155],[5519,24598,24599],{},"ls -l optimized_images\u002F",[6149,24601,24603],{"className":24602},[5678],"-rw-r--r--  1 user  staff  42104 Jun 13 20:45 image_1.webp",[6149,24605,24607],{"className":24606},[5678],"-rw-r--r--  1 user  staff  38942 Jun 13 20:45 image_2.webp",[6149,24609,24611],{"className":24610},[5678],[5676,24612,24615],{"className":24613},[6167,24614],"opacity-60","← Зображення успішно стиснені, зменшені та збережені у форматі WebP!",[5574,24617],{},[5502,24619,24621],{"id":24620},"порівняльна-таблиця-стратегії-імпорту","Порівняльна таблиця: стратегії імпорту",[10245,24623,24624,24642],{},[10248,24625,24626],{},[10251,24627,24628,24631,24634,24637,24640],{},[10254,24629,24630],{},"Синтаксис",[10254,24632,24633],{},"Простір імен",[10254,24635,24636],{},"Ризик конфлікту",[10254,24638,24639],{},"Читабельність",[10254,24641,19425],{},[10265,24643,24644,24662,24680,24696],{},[10251,24645,24646,24650,24653,24656,24659],{},[10270,24647,24648],{},[5511,24649,6365],{},[10270,24651,24652],{},"ізольований",[10270,24654,24655],{},"❌ мінімальний",[10270,24657,24658],{},"✅ висока",[10270,24660,24661],{},"✅ основний підхід",[10251,24663,24664,24668,24671,24674,24677],{},[10270,24665,24666],{},[5511,24667,7010],{},[10270,24669,24670],{},"поточний",[10270,24672,24673],{},"⚠️ є",[10270,24675,24676],{},"⚠️ середня",[10270,24678,24679],{},"✅ для 1-3 об'єктів",[10251,24681,24682,24686,24688,24690,24693],{},[10270,24683,24684],{},[5511,24685,7090],{},[10270,24687,24652],{},[10270,24689,24655],{},[10270,24691,24692],{},"✅ висока (якщо alias відомий)",[10270,24694,24695],{},"✅ для довгих імен",[10251,24697,24698,24702,24704,24707,24710],{},[10270,24699,24700],{},[5511,24701,6369],{},[10270,24703,24670],{},[10270,24705,24706],{},"❌❌ гарантований",[10270,24708,24709],{},"❌ низька",[10270,24711,24712],{},"❌ уникати завжди",[5574,24714],{},[5502,24716,24718],{"id":24717},"підсумки-та-найкращі-практики","Підсумки та найкращі практики",[5524,24720,24721,24734,24744,24758,24762,24765],{},[5527,24722,24724,24725,24727,24728,24730,24731,24733],{"icon":13905,"title":24723},"Модулі","Кожен ",[5511,24726,5594],{},"-файл — модуль. Ділить код на логічні одиниці. Завантажується один раз, кешується у ",[5511,24729,5609],{},". Пишіть ",[5511,24732,9367],{}," для двоїстих файлів.",[5527,24735,24738,24740,24741,24743],{"icon":24736,"title":24737},"i-heroicons-magnifying-glass","sys.path і sys.modules",[5511,24739,5630],{}," — список директорій для пошуку. ",[5511,24742,5609],{}," — кеш завантажених модулів. Розуміння цих двох структур пояснює більшість «магії» імпорту.",[5527,24745,24748,24749,24751,24752,24754,24755,24757],{"icon":24746,"title":24747},"i-heroicons-folder-open","Пакети","Директорія з ",[5511,24750,10921],{},". Організує модулі ієрархічно. ",[5511,24753,10921],{}," слугує фасадом публічного API. ",[5511,24756,7408],{}," документує контракт модуля.",[5527,24759,24761],{"icon":15778,"title":24760},"venv + pip","Базовий стандарт ізоляції, вбудований у Python. Вивчіть його першим — він підвалина для розуміння того, як працюють uv та Poetry.",[5527,24763,24764],{"icon":13865,"title":13755},"Рекомендований вибір для нових проектів. У 10–100 разів швидший за pip, управляє версіями Python, має lockfile та не потребує ручної активації mid venv.",[5527,24766,24767],{"icon":19970,"title":13825},"Ідеальний для публікації бібліотек на PyPI та для команд з розвиненим workflow. Чіткі групи залежностей (dev\u002Ftest\u002Fdocs) і зрілий tooling навколо.",[5507,24769,24770],{},[5519,24771,24772],{},"Золоті правила, що варто запам'ятати:",[5618,24774,24775,24786,24795,24807,24820,24832,24839,24842],{},[5621,24776,19844,24777,24780,24781,5737,24783,24785],{},[5519,24778,24779],{},"Завжди"," використовуйте ізольоване середовище для кожного проекту (",[5511,24782,12937],{},[5511,24784,13881],{}," або Poetry)",[5621,24787,19844,24788,24790,24791,10558,24793],{},[5519,24789,24779],{}," додавайте ",[5511,24792,15924],{},[5511,24794,17873],{},[5621,24796,19844,24797,24799,24800,24802,24803,10219,24805,5631],{},[5519,24798,24779],{}," фіксуйте залежності: ",[5511,24801,13650],{}," або через lockfile (",[5511,24804,13897],{},[5511,24806,16795],{},[5621,24808,24809,24810,24813,24814,24816,24817,24819],{},"✅ Для ",[5519,24811,24812],{},"нових проектів"," — обирайте ",[5511,24815,13755],{}," (швидкість + простота) або ",[5511,24818,13825],{}," (якщо плануєте публікацію на PyPI)",[5621,24821,24822,24823,6423,24825,5737,24827,6157,24830],{},"✅ Використовуйте ",[5511,24824,6365],{},[5511,24826,7010],{},[5519,24828,24829],{},"уникайте",[5511,24831,6369],{},[5621,24833,24834,24835,24838],{},"✅ Пишіть ",[5511,24836,24837],{},"if __name__ == \"__main__\":"," у кожному файлі, що може запускатися напряму",[5621,24840,24841],{},"✅ Структуруйте код у пакети при наявності більш ніж 5–7 модулів",[5621,24843,24844],{},"✅ Використовуйте абсолютні імпорти між пакетами, відносні — всередині одного пакета",[24846,24847,24848],"style",{},"html pre.shiki code .spJ8K, html code.shiki .spJ8K{--shiki-light:#008000;--shiki-default:#6A9955;--shiki-dark:#6A9955}html pre.shiki code .sHH4Y, html code.shiki .sHH4Y{--shiki-light:#000000;--shiki-default:#D4D4D4;--shiki-dark:#D4D4D4}html pre.shiki code .sJj4R, html code.shiki .sJj4R{--shiki-light:#098658;--shiki-default:#B5CEA8;--shiki-dark:#B5CEA8}html pre.shiki code .su1O8, html code.shiki .su1O8{--shiki-light:#0000FF;--shiki-default:#569CD6;--shiki-dark:#569CD6}html pre.shiki code .s8Opu, html code.shiki .s8Opu{--shiki-light:#795E26;--shiki-default:#DCDCAA;--shiki-dark:#DCDCAA}html pre.shiki code .siwwj, html code.shiki .siwwj{--shiki-light:#001080;--shiki-default:#9CDCFE;--shiki-dark:#9CDCFE}html pre.shiki code .sN1BT, html code.shiki .sN1BT{--shiki-light:#267F99;--shiki-default:#4EC9B0;--shiki-dark:#4EC9B0}html pre.shiki code .sbdoH, html code.shiki .sbdoH{--shiki-light:#A31515;--shiki-default:#CE9178;--shiki-dark:#CE9178}html pre.shiki code .s8xlr, html code.shiki .s8xlr{--shiki-light:#AF00DB;--shiki-default:#C586C0;--shiki-dark:#C586C0}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sjcCO, html code.shiki .sjcCO{--shiki-light:#EE0000;--shiki-default:#D7BA7D;--shiki-dark:#D7BA7D}html pre.shiki code .sLwNe, html code.shiki .sLwNe{--shiki-light:#0451A5;--shiki-default:#9CDCFE;--shiki-dark:#9CDCFE}",{"title":5672,"searchDepth":5686,"depth":5686,"links":24850},[24851,24852,24864,24873,24881,24889,24905,24911,24917,24925,24945,24958,24959,24970,24971],{"id":5504,"depth":5686,"text":5505},{"id":5578,"depth":5686,"text":5579,"children":24853},[24854,24855,24856,24857,24858,24859,24860,24861,24862],{"id":5583,"depth":5693,"text":5584},{"id":6187,"depth":5693,"text":6188},{"id":6372,"depth":5693,"text":6373},{"id":6416,"depth":5693,"text":6417},{"id":6430,"depth":5693,"text":6431},{"id":6437,"depth":5693,"text":6438},{"id":6444,"depth":5693,"text":6445},{"id":6935,"depth":5693,"text":6936},{"id":7270,"depth":5693,"text":24863},"Конвенція _private: приватні атрибути модуля",{"id":7421,"depth":5686,"text":24865,"children":24866},"Система пошуку модулів: sys.path зсередини",[24867,24869,24871],{"id":7428,"depth":5693,"text":24868},"Алгоритм пошуку import",{"id":7679,"depth":5693,"text":24870},"Анатомія sys.path: що там насправді",{"id":7998,"depth":5693,"text":24872},"Маніпуляції з sys.path: коли і як",{"id":8277,"depth":5686,"text":24874,"children":24875},"Кешування імпортів: sys.modules та Singleton-поведінка",[24876,24877,24879],{"id":8284,"depth":5693,"text":8285},{"id":8887,"depth":5693,"text":24878},"sys.modules як Singleton-реєстр: спільний стан",{"id":9195,"depth":5693,"text":24880},"Перезавантаження модуля: importlib.reload",{"id":9363,"depth":5686,"text":24882,"children":24883},"Подвійне призначення файлу: if __name__ == \"__main__\"",[24884,24885,24887],{"id":9370,"depth":5693,"text":9371},{"id":9697,"depth":5693,"text":24886},"Патерн main(): структурований точок входу",{"id":10228,"depth":5693,"text":24888},"python -m: запуск модуля як скрипта",{"id":10337,"depth":5686,"text":10338,"children":24890},[24891,24892,24894,24896,24898,24900,24902,24904],{"id":10341,"depth":5693,"text":10342},{"id":10522,"depth":5693,"text":24893},"Python починає виконувати a.py",{"id":10540,"depth":5693,"text":24895},"Python починає виконувати b.py",{"id":10554,"depth":5693,"text":24897},"Python виявляє a у sys.modules",{"id":10595,"depth":5693,"text":24899},"b.py успішно завантажується",{"id":10611,"depth":5693,"text":24901},"Виконання повертається до a.py",{"id":10627,"depth":5693,"text":24903},"Виклик a.func_a() → b.func_b()",{"id":10816,"depth":5693,"text":10817},{"id":10898,"depth":5686,"text":10899,"children":24906},[24907,24908,24909],{"id":10902,"depth":5693,"text":10903},{"id":10925,"depth":5693,"text":10926},{"id":12116,"depth":5693,"text":24910},"Роль __init__.py: ворота пакета",{"id":12234,"depth":5686,"text":12235,"children":24912},[24913,24914,24915],{"id":12238,"depth":5693,"text":12239},{"id":12307,"depth":5693,"text":12308},{"id":12434,"depth":5693,"text":24916},"__all__: контракт публічного API",{"id":12605,"depth":5686,"text":12606,"children":24918},[24919,24920,24922,24923],{"id":12609,"depth":5693,"text":12610},{"id":12934,"depth":5693,"text":24921},"Що таке venv: ізольований Python від стандартної бібліотеки",{"id":13152,"depth":5693,"text":13153},{"id":13583,"depth":5693,"text":24924},"requirements.txt: заморожування залежностей",{"id":13770,"depth":5686,"text":13771,"children":24926},[24927,24929,24931,24933,24934,24935,24936,24937,24938,24939,24940,24941,24943],{"id":13831,"depth":5693,"text":24928},"uv — ультрашвидкий менеджер нового покоління",{"id":15754,"depth":5693,"text":24930},"Poetry — зрілий менеджер для складних проектів",{"id":17297,"depth":5693,"text":24932},"Робота з git: що робити після git clone?",{"id":17389,"depth":5693,"text":17390},{"id":17414,"depth":5693,"text":17415},{"id":17455,"depth":5693,"text":17456},{"id":17540,"depth":5693,"text":17541},{"id":17606,"depth":5693,"text":17390},{"id":17627,"depth":5693,"text":17628},{"id":17651,"depth":5693,"text":17652},{"id":17732,"depth":5693,"text":17541},{"id":18103,"depth":5693,"text":24942},"Статичний аналіз типів: mypy та Pyright",{"id":19779,"depth":5693,"text":24944},"Порівняльна таблиця: venv+pip vs uv vs Poetry",{"id":19977,"depth":5686,"text":19978,"children":24946},[24947,24948,24950,24952,24954,24956],{"id":19981,"depth":5693,"text":19982},{"id":20019,"depth":5693,"text":24949},"Математичні обчислення: модуль math",{"id":20414,"depth":5693,"text":24951},"Псевдовипадковість: модуль random",{"id":20849,"depth":5693,"text":24953},"Робота з часом: модуль datetime",{"id":21413,"depth":5693,"text":24955},"Системна взаємодія: os vs sys vs pathlib",{"id":21916,"depth":5693,"text":24957},"Спеціалізовані контейнери: модуль collections",{"id":22579,"depth":5686,"text":22580},{"id":22844,"depth":5686,"text":22845,"children":24960},[24961,24962,24963,24964,24965,24966,24967,24968,24969],{"id":22867,"depth":5693,"text":22868},{"id":22904,"depth":5693,"text":22905},{"id":24319,"depth":5693,"text":24320},{"id":24325,"depth":5693,"text":24326},{"id":24391,"depth":5693,"text":24392},{"id":24441,"depth":5693,"text":24442},{"id":24473,"depth":5693,"text":24474},{"id":24494,"depth":5693,"text":24495},{"id":24574,"depth":5693,"text":24575},{"id":24620,"depth":5686,"text":24621},{"id":24717,"depth":5686,"text":24718},"Глибоке дослідження системи модулів Python — від механізмів пошуку файлів через sys.path до кешування імпортів у sys.modules, архітектури пакетів з __init__.py та ізоляції залежностей через venv. Фундамент для будь-якого серйозного Python-проекту.","md",null,{},{"title":2926,"description":24972},"-JBC0ndPjGLkRh5CjlKjcVN4tJeKKsL6Yblmt_RnkM4",[24979,24981],{"title":2918,"path":2919,"stem":2920,"description":24980,"children":-1},"Рядок як незмінна послідовність кодових точок Unicode, індекси й зрізи, функція len, методи split, join, strip, replace, find та інші, оператор in, f-рядки поглиблено, різниця між str і bytes, кодування та декодування, UTF-8.",{"title":71,"path":2930,"stem":2931,"description":24982,"children":-1},"Глибоке дослідження механізму класів і об'єктів у Python — від фундаментальних принципів інстанціювання до CPython internals, різниці між __init__ та __new__, оптимізації пам'яті через __slots__ та природи self як неявного першого аргументу.",1794581867681]