• Stars
    star
    486
  • Rank 87,734 (Top 2 %)
  • Language
    Jupyter Notebook
  • License
    Other
  • Created almost 2 years ago
  • Updated 3 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Python Extended Cheatsheet. I'm using this repository to chronicle my journey through Python.

Π―Π΄Ρ€ΠΎ ΠΏΠ»Π°Π½Π΅Ρ‚Ρ‹ Python

ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, ΠΏΠΎΠΊΠ° ΠΌΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π» находится Π² статусС Ρ‡Π΅Ρ€Π½ΠΎΠ²ΠΈΠΊΠ°. Π§Π΅ΠΌ дальшС Π²Ρ‹ ΠΏΡ€ΠΎΠ΄Π²ΠΈΠ½Π΅Ρ‚Π΅ΡΡŒ Π²Π³Π»ΡƒΠ±ΡŒ тСкста, Ρ‚Π΅ΠΌ большС нСувязок, косноязычия ΠΈ ошибок Π²Ρ‹ Ρ‚Π°ΠΌ ΡƒΠ²ΠΈΠ΄ΠΈΡ‚Π΅, Π° Π³Π΄Π΅-Ρ‚ΠΎ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½ΠΎ Π² Ρ€Π°ΠΉΠΎΠ½Π΅ сСрСдины ΡΡ‚Π°Ρ‚ΡŒΠΈ ΠΎΠΊΠΎΠ½Ρ‡Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ ΠΏΠΎΠΏΠ°Π΄Ρ‘Ρ‚Π΅ Π² ΠΎΠ±Π»Π°ΡΡ‚ΡŒ Ρ€Π°Π·Ρ€ΠΎΠ·Π½Π΅Π½Π½Ρ‹Ρ… Π·Π°ΠΌΠ΅Ρ‚ΠΎΠΊ, нСвнятных ΠΏΠΎΡ‡Π΅Ρ€ΠΊΡƒΡˆΠ΅ΠΊ ΠΈ псоголовых Π²ΠΎΠΈΠ½ΠΎΠ², Π²ΠΎΡŽΡŽΡ‰ΠΈΡ… с Π΄Ρ€Π°ΠΊΠΎΠ½Π°ΠΌΠΈ. ΠŸΠΎΠΆΠ°Π»ΡƒΠΉΡΡ‚Π°, Π½Π΅ судитС строго, ΠΌΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π» Ρ…ΠΎΡ‚ΡŒ ΠΈ нСбыстро, Π½ΠΎ ΡƒΠΏΠΎΡ€Π½ΠΎ коррСктируСтся, ΠΌΠ΅Π΄Π»Π΅Π½Π½ΠΎ дрСйфуя Π² сторону большСй читаСмости.

Core of the planet Python

Π’Π²Π΅Π΄Π΅Π½ΠΈΠ΅

Π”ΠΎΠ±Ρ€Ρ‹ΠΉ дСнь! МСня Π·ΠΎΠ²ΡƒΡ‚ ΠœΠΈΡ…Π°ΠΈΠ» Π•ΠΌΠ΅Π»ΡŒΡΠ½ΠΎΠ², ΠΏΠΎ профСссии я программист ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌ, Π° эту Π½Π΅Π±ΠΎΠ»ΡŒΡˆΡƒΡŽ памятку ΠΏΠΎ Π±Π°Π·ΠΎΠ²Ρ‹ΠΌ возмоТностям языка Python мСня сподвиг Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ довольно сущСствСнный, Π½Π° ΠΌΠΎΠΉ взгляд, Ρ€Π°Π·Ρ€Ρ‹Π² ΠΌΠ΅ΠΆΠ΄Ρƒ Π΄Π΅ΠΊΠ»Π°Ρ€ΠΈΡ€ΡƒΠ΅ΠΌΡ‹ΠΌΠΈ объСмами всСвозмоТных курсов программирования ΠΈ трСбованиями Ρ€Π΅Π°Π»ΡŒΠ½Ρ‹Ρ…, Π΄Π°ΠΆΠ΅ достаточно скромнооплачиваСых вакансий.

ΠŸΠΎΠ»ΡŒΠ·ΡƒΡΡΡŒ аналогиями ΠΈΠ· ΠΈΠ³Ρ€ΠΎΠ²ΠΎΠ³ΠΎ ΠΌΠΈΡ€Π°, ΠΌΠΎΠΆΠ½ΠΎ ΡΠΊΠ°Π·Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ Π½Π°Ρ‡ΠΈΠ½Π°ΡŽΡ‰ΠΈΠΉ программист Π·Π°Ρ‡Π°ΡΡ‚ΡƒΡŽ стоит Π½Π° Π±Π΅Ρ€Π΅Π³Ρƒ ΠΎΠ·Π΅Ρ€Π° кипящСй Π»Π°Π²Ρ‹, Π² Ρ†Π΅Π½Ρ‚Ρ€Π΅ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ находится остров со ΡΡ‚ΠΎΠ»ΡŒ Π²ΠΎΠΆΠ΄Π΅Π»Π΅Π½Π½Ρ‹ΠΌΠΈ вакансиями, Π° ΠΏΡ€ΠΎΠΌΠ΅ΠΆΡƒΡ‚ΠΎΡ‡Π½Ρ‹Π΅ островки, ΠΏΠΎ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ Π½Π°Π΄ΠΎ ΠΏΠ΅Ρ€Π΅ΠΏΡ€Ρ‹Π³ΠΈΠ²Π°Ρ‚ΡŒ, постСпСнно наращивая свои Π½Π°Π²Ρ‹ΠΊΠΈ Π² ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… ΠΌΠΈΠ½ΠΈ-квСстах, Π»ΠΈΠ±ΠΎ ΠΎΡ‚ΡΡƒΡ‚ΡΡ‚Π²ΡƒΡŽΡ‚, Π»ΠΈΠ±ΠΎ располоТСны нСсистСмно ΠΈ Ρ…Π°ΠΎΡ‚ΠΈΡ‡Π½ΠΎ, Π»ΠΈΠ±ΠΎ достаточно ровная ΠΈΡ… ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ обрываСтся, Ρ‚Π°ΠΊ ΠΈ Π½Π΅ успСв ΠΏΠΎΠΌΠΎΡ‡ΡŒ ΠΎΡ‚ΠΎΠΉΡ‚ΠΈ сколько-Π½ΠΈΠ±ΡƒΠ΄ΡŒ Π΄Π°Π»Π΅ΠΊΠΎ ΠΎΡ‚ Π±Π΅Ρ€Π΅Π³Π°. Π”Π°Π²Π°ΠΉΡ‚Π΅ ΠΏΠΎΠΏΡ€ΠΎΠ±ΡƒΠ΅ΠΌ ΠΏΠΎΡΡ‚Ρ€ΠΎΠΈΡ‚ΡŒ Π΄ΠΎΡ€ΠΎΠΆΠΊΡƒ островков-подсказок, ряд ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ…, Ρ…ΠΎΡ‚ΡŒ ΠΈ Π½Π΅ Π±Π΅Π· усилий, ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈΡ‚-Ρ‚Π°ΠΊΠΈ Π½Π°ΠΌ Π΄ΠΎΡΡ‚ΠΈΡ‡ΡŒ Ρ†Π΅Π»ΠΈ.

Π’ этой ΡΡ‚Π°Ρ‚ΡŒΠ΅ 100 % Π΅ΡΡ‚ΡŒ ошибки ΠΈ нСточности самых Ρ€Π°Π·Π½Ρ‹Ρ… ΠΊΠ°Π»ΠΈΠ±Ρ€ΠΎΠ², Ρ‚Π°ΠΊ Ρ‡Ρ‚ΠΎ, Ссли Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ углядитС, Π½Π΅ ΡΡ‚Π΅ΡΠ½ΡΠΉΡ‚Π΅ΡΡŒ Π²Ρ‹Ρ€Π°ΠΆΠ°Ρ‚ΡŒΡΡ Π² Π»ΠΈΡ‡ΠΊΡƒ, Π² коммСнтариях, Π½Π° ΠΏΠΎΡ‡Ρ‚Ρƒ [email protected], всС исправлСния ΠΈ дополнСния Π±ΡƒΡ€Π½ΠΎ ΠΏΡ€ΠΈΠ²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‚ΡΡ.

ΠŸΠΎΠ³Ρ€ΡƒΠΆΠ°ΡΡΡŒ Π² Python, Π½Π΅ Π·Π°Π±Ρ‹Π²Π°ΠΉΡ‚Π΅ ΠΏΡ€ΠΎ ΠΏΡ€Π΅ΠΊΡ€Π°ΡΠ½ΡƒΡŽ ΠΎΡ„ΠΈΡ†ΠΈΠ°Π»ΡŒΠ½ΡƒΡŽ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡŽ docs.python.org. Π˜Π·ΡƒΡ‡ΠΈΠ² Π΅Ρ‘, хотя Π±Ρ‹ ΠΏΠΎ Π΄ΠΈΠ°Π³ΠΎΠ½Π°Π»ΠΈ, ΠΈ постСпСнно ΡƒΠ³Π»ΡƒΠ±Π»ΡΡΡΡŒ Π² Π½ΡƒΠΆΠ½Ρ‹Π΅ Ρ€Π°Π·Π΄Π΅Π»Ρ‹, Π²Ρ‹ смоТСтС ΡƒΠ±Π΅Π΄ΠΈΡ‚ΡŒΡΡ, Ρ‡Ρ‚ΠΎ ΠΌΠ½ΠΎΠ³ΠΈΠ΅ Β«Ρ…Π°ΠΊΠΈΒ», «открытия» ΠΈ ΠΏΡ€ΠΎΡ‡ΠΈΠ΅ Π½Π΅ΠΎΡ‡Π΅Π²ΠΈΠ΄Π½Ρ‹Π΅ Π²Π΅Ρ‰ΠΈ ΡƒΠΆΠ΅ Π΄Π°Π²Π½ΠΎ Ρ€Π°Π·ΠΆΠ΅Π²Π°Π½Ρ‹, описаны ΠΈ ΠΈΠΌΠ΅ΡŽΡ‚ ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½Ρ‹Π΅ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ примСнСния.

Π’Π°ΠΊΠΆΠ΅ я Π±Ρ‹ Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄ΠΎΠ²Π°Π» для изучСния Π±Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ синтаксиса Python Π½Π° ΠΏΠΎΠ»Π½ΡƒΡŽ ΠΊΠ°Ρ‚ΡƒΡˆΠΊΡƒ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ leetcode.com. Если ΠΎΡ‚Ρ„ΠΈΠ»ΡŒΡ‚Ρ€ΠΎΠ²Π°Ρ‚ΡŒ Π·Π°Π΄Π°Ρ‡ΠΈ ΠΏΠΎ ΡƒΡ€ΠΎΠ²Π½ΡŽ Β«EasyΒ», Π° ΠΏΠΎΡ‚ΠΎΠΌ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΡƒΡŽ сортировку ΠΏΠΎ столбцу Β«AcceptanceΒ», Ρ‚ΠΎ ΠΏΠ΅Ρ€Π΅Π΄ Π²Π°ΠΌΠΈ прСдстанСт Π½Π΅ Π²ΠΎΠ»Ρ‡ΠΈΠΉ оскал ΡΠΎΡ€Π΅Π²Π½ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠΉ ΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΡ‹, Π° Π²Π°Π½ΠΈΠ»ΡŒΠ½Ρ‹ΠΉ Π±ΡƒΠΊΠ²Π°Ρ€ΡŒ с ΠΏΠ»Π°Π²Π½ΠΎ Π½Π°Ρ€Π°ΡΡ‚Π°ΡŽΡ‰ΠΈΠΌ ΡƒΡ€ΠΎΠ²Π½Π΅ΠΌ Π·Π°Π΄Π°Ρ‡Π΅ΠΊ.

Π§Ρ‚ΠΎ ΠΆ, ΠΏΠΎΠΆΠ°Π»ΡƒΠΉ, довольно Π·Π°ΠΏΡ€ΡΠ³Π°Ρ‚ΡŒ. Погнали!

ОглавлСниС

НиТС Π²Ρ‹ Π²ΠΈΠ΄ΠΈΡ‚Π΅ ΠΎΠ³Π»Π°Π²Π»Π΅Π½ΠΈΠ΅, сдСланноС для Π»ΡƒΡ‡ΡˆΠ΅Π³ΠΎ усвоСния Π½Π΅ плоским, Π° Π² Π²ΠΈΠ΄Π΅ Π΄ΠΈΠ°Π³Ρ€Π°ΠΌΠΌΡ‹-путСводитСля.

ΠŸΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ ΠΏΡƒΡ‚Π΅Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»Π΅ΠΌ ΠΎΡ‡Π΅Π½ΡŒ просто. Как Π² ΠΎΠ±Ρ‹Ρ‡Π½ΠΎΠΌ тСкстС, ΠΈΠ΄ΠΈΡ‚Π΅ слСва Π½Π°ΠΏΡ€Π°Π²ΠΎ ΠΈ свСрху Π²Π½ΠΈΠ·. Если Π²Ρ‹ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π½Π°Ρ‡ΠΈΠ½Π°Π΅Ρ‚Π΅ ΠΈΠ·ΡƒΡ‡Π°Ρ‚ΡŒ Python, Ρ‚ΠΎ ΠΈΠ΄ΠΈΡ‚Π΅ ΠΏΠΎ Π·Π΅Π»Π΅Π½Ρ‹ΠΌ ΠΏΡƒΠ½ΠΊΡ‚Π°ΠΌ путСводитСля. Если Π½Π°ΠΊΠΎΠΏΠ»Π΅Π½Π½Ρ‹ΠΉ ΠΎΠΏΡ‹Ρ‚, Π»ΡŽΠ±ΠΎΠΏΡ‹Ρ‚ΡΡ‚Π²ΠΎ ΠΈΠ»ΠΈ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎΡΡ‚ΡŒ Ρ‚ΠΎΠ»ΠΊΠ°ΡŽΡ‚ вас Π³Π»ΡƒΠ±ΠΆΠ΅, Π½Π°Ρ‡Π½ΠΈΡ‚Π΅ ΠΈΠ·ΡƒΡ‡Π°Ρ‚ΡŒ Ρ€Π°Π·Π΄Π΅Π»Ρ‹, ΠΏΠΎΠΌΠ΅Ρ‡Π΅Π½Π½Ρ‹Π΅ сСрым. ΠžΡ€Π°Π½ΠΆΠ΅Π²Ρ‹ΠΌ ΠΏΠΎΠΌΠ΅Ρ‡Π΅Π½Ρ‹ Ρ‚Π΅ΠΌΡ‹, Ρ‚Ρ€Π΅Π±ΡƒΡŽΡ‰ΠΈΠ΅ ΡƒΠ³Π»ΡƒΠ±Π»Π΅Π½Π½ΠΎΠ³ΠΎ изучСния, ΠΈΠΌΠΈ Π»ΡƒΡ‡ΡˆΠ΅ Π·Π°Π½ΡΡ‚ΡŒΡΡ (хотя Π±Ρ‹ ΠΈ Π½Π΅ копая, для Π½Π°Ρ‡Π°Π»Π°, особСнно Π³Π»ΡƒΠ±ΠΎΠΊΠΎ) Π² Ρ‚Ρ€Π΅Ρ‚ΠΈΠΉ ΠΏΡ€ΠΎΡ…ΠΎΠ΄. Π”Π°ΠΆΠ΅ Ссли Π²Ρ‹ Π½Π΅ ΡΠΎΠ±ΠΈΡ€Π°Π΅Ρ‚Π΅ΡΡŒ ΠΏΠ»ΠΎΡ‚Π½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π½Π° ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠ΅ ΠΊΠ°ΠΊΠΈΠ΅-Ρ‚ΠΎ ΠΈΠ· ΠΎΡ€Π°Π½ΠΆΠ΅Π²Ρ‹Ρ… Ρ‚Π΅ΠΌ, рассмотритС ΠΈΡ… хотя Π±Ρ‹ повСрхностно, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Ρ‡Ρ‘Ρ‚ΠΊΠΎ ΠΏΠΎΠ½ΠΈΠΌΠ°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ это, для Ρ‡Π΅Π³ΠΎ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ, ΠΏΠ»ΡŽΡΡ‹ ΠΈ минусы; Π΄Π΅Ρ€ΠΆΠ°Ρ‚ΡŒ, Ρ‚Π°ΠΊ ΡΠΊΠ°Π·Π°Ρ‚ΡŒ, Π² «горячСм Ρ€Π΅Π·Π΅Ρ€Π²Π΅Β».

Full table of contents

1. Π‘Ρ‚Ρ€ΡƒΠΊΡ‚ΡƒΡ€Ρ‹ Π΄Π°Π½Π½Ρ‹Ρ…

«На востокС располоТСн Π Π°ΠΉ; мСсто это ΠΏΡ€Π΅ΠΎΠ±ΠΈΠ»ΡŒΠ½ΠΎΠ΅ ΠΈ извСстно своими наслаТдСниями, Π½ΠΎ для людСй нСдоступно. ΠœΠ΅ΡΡ‚ΠΎ это ΠΎΠ³Ρ€Π°ΠΆΠ΄Π΅Π½ΠΎ ΠΎΠ³Π½Π΅Π½Π½ΠΎΠΉ стСной Π΄ΠΎ самого Π½Π΅Π±Π°Β».

Эбсторфская ΠΊΠ°Ρ€Ρ‚Π°.

Data structures

Как извСстно, ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ = структуры Π΄Π°Π½Π½Ρ‹Ρ… + Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΡ‹ (Ρƒ Никлауса Π’ΠΈΡ€Ρ‚Π° Π΄Π°ΠΆΠ΅ ΠΊΠ½ΠΈΠΆΠΊΠ° такая Π΅ΡΡ‚ΡŒ). НачнСм с Π΄Π°Π½Π½Ρ‹Ρ…, Π° ΠΏΠΎΡ‚ΠΎΠΌ плавнСнько ΠΏΠ΅Ρ€Π΅ΠΉΠ΄Π΅ΠΌ ΠΊ ΠΌΠ΅Ρ‚ΠΎΠ΄Π°ΠΌ ΠΈΡ… ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ.

Бписок (list)

Бписок β€” самая ΡƒΠ½ΠΈΠ²Π΅Ρ€ΡΠ°Π»ΡŒΠ½Π°Ρ ΠΈ популярная структура Π΄Π°Π½Π½Ρ‹Ρ… Π² Python. Если Π²Ρ‹ ΠΏΠΎΠΊΠ° Ρ‚ΠΎΡ‡Π½ΠΎ Π½Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΠ»ΠΈΡΡŒ, какая структура понадобится Π² вашСм ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π΅, просто Π²ΠΎΠ·ΡŒΠΌΠΈΡ‚Π΅ список, с Π½Π΅Π³ΠΎ достаточно просто ΠΌΠΈΠ³Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π½Π° Ρ‡Ρ‚ΠΎ-Π½ΠΈΠ±ΡƒΠ΄ΡŒ Π±ΠΎΠ»Π΅Π΅ спСциализированноС.
Бписок прСдставляСт собой ΡƒΠΏΠΎΡ€ΡΠ΄ΠΎΡ‡Π΅Π½Π½ΡƒΡŽ ΠΈΠ·ΠΌΠ΅Π½ΡΠ΅ΠΌΡƒΡŽ ΠΊΠΎΠ»Π»Π΅ΠΊΡ†ΠΈΡŽ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»ΡŒΠ½Ρ‹Ρ… Ρ‚ΠΈΠΏΠΎΠ². Π’Π½ΡƒΡ‚Ρ€Π΅Π½Π½Π΅Π΅ строСниС списка - массив (Ρ‚ΠΎΡ‡Π½Π΅Π΅, vector) ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΉ, Ρ‚. Π΅. список являСтся динамичСским массивом.

a = []  # Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ пустой список

a: list[int] = [10, 20]
b: list[int] = [30, 40]
a.append(50)  # ДобавляСм Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π² ΠΊΠΎΠ½Π΅Ρ† списка
b.insert(2, 60)  # ВставляСм Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΠΎ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠΌΡƒ индСксу
print(a, b)

a += b
print(f"Add: {a}")

a.reverse()
b = list(reversed(a))  # reversed() Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€, Π° Π½Π΅ список
print(f"Reverse: {a}, {b}")

b = sorted(a)  # Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Π½ΠΎΠ²Ρ‹ΠΉ отсортированный список
a.sort()  # ΠœΠΎΠ΄ΠΈΡ„ΠΈΡ†ΠΈΡ€ΡƒΠ΅Ρ‚ исходный список ΠΈ Π½Π΅ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Π½ΠΈΡ‡Π΅Π³ΠΎ
print(f"Sort: {a}, {b}")

s: str = "A whole string"
list_of_chars: list = list(s)
print(list_of_chars)
list_of_words: list = s.split()
print(list_of_words)

i: int = list_of_chars.index("w")  # Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ индСкс ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ вхоТдСния искомого элСмСнта ΠΈΠ»ΠΈ Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ValueError
print(i)
list_of_chars.remove("w")  # УдаляСт ΠΏΠ΅Ρ€Π²ΠΎΠ΅ Π²Ρ…ΠΎΠΆΠ΄Π΅Π½ΠΈΠ΅ искомого элСмСнта ΠΈΠ»ΠΈ Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ValueError
e = list_of_chars.pop(9)  # УдаляСт ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, располоТСнноС ΠΏΠΎ индСксу. pop() (Π±Π΅Π· Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π°) ΡƒΠ΄Π°Π»ΠΈΡ‚ ΠΈ Π²Π΅Ρ€Π½Π΅Ρ‚ послСдний элСмСнт списка
print(list_of_chars, e)
a.clear()  # ΠžΡ‡ΠΈΡΡ‚ΠΊΠ° списка
[10, 20, 50] [30, 40, 60]
Add: [10, 20, 50, 30, 40, 60]
Reverse: [60, 40, 30, 50, 20, 10], [10, 20, 50, 30, 40, 60]
Sort: [10, 20, 30, 40, 50, 60], [10, 20, 30, 40, 50, 60]
['A', ' ', 'w', 'h', 'o', 'l', 'e', ' ', 's', 't', 'r', 'i', 'n', 'g']
['A', 'whole', 'string']
2
['A', ' ', 'h', 'o', 'l', 'e', ' ', 's', 't', 'i', 'n', 'g'] r

ΠšΠΎΡ€Ρ‚Π΅ΠΆ (tuple)

ΠšΠΎΡ€Ρ‚Π΅ΠΆ β€” Ρ‚ΠΎΠΆΠ΅ список, Ρ‚ΠΎΠ»ΡŒΠΊΠΎ нСизмСняСмый (immutable) ΠΈ Ρ…ΡΡˆΠΈΡ€ΡƒΠ΅ΠΌΡ‹ΠΉ (hashable). ΠšΠΎΡ€Ρ‚Π΅ΠΆ, содСрТащий Ρ‚Π΅ ΠΆΠ΅ Π΄Π°Π½Π½Ρ‹Π΅, Ρ‡Ρ‚ΠΎ ΠΈ список, Π·Π°Π½ΠΈΠΌΠ°Π΅Ρ‚ мСньшС мСста:

a = [2, 3, "Boson", "Higgs", 1.56e-22]
b = (2, 3, "Boson", "Higgs", 1.56e-22)

print(f"List: {a.__sizeof__()} bytes")
print(f"Tuple: {b.__sizeof__()} bytes")
List: 104 bytes
Tuple: 64 bytes

Π˜ΠΌΠ΅Π½ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ ΠΊΠΎΡ€Ρ‚Π΅ΠΆ (named tuple)

Π’ соотвСтствии с Π½Π°Π·Π²Π°Π½ΠΈΠ΅ΠΌ, ΠΈΠΌΠ΅Π΅Ρ‚ ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½Π½Ρ‹Π΅ поля. Π£Π΄ΠΎΠ±Π½ΠΎ!

from collections import namedtuple

rectangle = namedtuple('rectangle', 'length width')
r = rectangle(length = 1, width = 2)

print(r)
print(r.length)
print(r.width)
print(r._fields)
rectangle(length=1, width=2)
1
2
('length', 'width')

Π‘Π»ΠΎΠ²Π°Ρ€ΡŒ (dict)

Π‘Π»ΠΎΠ²Π°Ρ€ΡŒ β€” вторая ΠΏΠΎ частотС использования структура Π΄Π°Π½Π½Ρ‹Ρ… Π² Python. dict - рСализация Ρ…Π΅Ρˆ-Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹, поэтому Π² качСствС ΠΊΠ»ΡŽΡ‡Π° нСльзя Π±Ρ€Π°Ρ‚ΡŒ Π½Π΅Ρ…Π΅ΡˆΠΈΡ€ΡƒΠ΅ΠΌΡ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, список (Ρ‚ΡƒΡ‚-Ρ‚ΠΎ Π½Π°ΠΌ ΠΈ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΡ€ΠΈΠ³ΠΎΠ΄ΠΈΡ‚ΡŒΡΡ ΠΊΠΎΡ€Ρ‚Π΅ΠΆ). ΠšΠ»ΡŽΡ‡ΠΎΠΌ словаря ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ любой нСизмСняСмый ΠΎΠ±ΡŠΠ΅ΠΊΡ‚: число, строка, datetime ΠΈ Π΄Π°ΠΆΠ΅ функция. Π’Π°ΠΊΠΈΠ΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ ΠΈΠΌΠ΅ΡŽΡ‚ ΠΌΠ΅Ρ‚ΠΎΠ΄ __hash__(), ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΎΠ΄Π½ΠΎΠ·Π½Π°Ρ‡Π½ΠΎ сопоставляСт ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ с Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ числом. По этому числу ΡΠ»ΠΎΠ²Π°Ρ€ΡŒ ΠΈΡ‰Π΅Ρ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ для ΠΊΠ»ΡŽΡ‡Π°.

Бписки, словари ΠΈ мноТСства (ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΡ‹ рассмотрим Ρ‡ΡƒΡ‚ΡŒ Π½ΠΈΠΆΠ΅) измСняСмы ΠΈ Π½Π΅ ΠΈΠΌΠ΅ΡŽΡ‚ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° Ρ…Π΅ΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡ, ΠΏΡ€ΠΈ ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΠ΅ ΠΏΠΎΠ΄ΡΡ‚Π°Π²ΠΈΡ‚ΡŒ ΠΈΡ… Π² ΡΠ»ΠΎΠ²Π°Ρ€ΡŒ Π²ΠΎΠ·Π½ΠΈΠΊΠ½Π΅Ρ‚ ошибка.

d = {}  # Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ пустой ΡΠ»ΠΎΠ²Π°Ρ€ΡŒ

d: dict[str, str] = {"Italy": "Pizza", "US": "Hot-Dog", "China": "Dim Sum"}  # НСпосрСдствСнноС созданиС словаря

k = ["Italy", "US", "China"]
v = ["Pizza", "Hot-Dog", "Dim Sum"]
d = dict(zip(k, v))  # Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ словаря ΠΈΠ· Π΄Π²ΡƒΡ… ΠΊΠΎΠ»Π»Π΅ΠΊΡ†ΠΈΠΉ ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ zip

k = d.keys()  # ΠšΠΎΠ»Π»Π΅ΠΊΡ†ΠΈΡ ΠΊΠ»ΡŽΡ‡Π΅ΠΉ. ΠžΡ‚Ρ€Π°ΠΆΠ°Π΅Ρ‚ измСнСния Π² основном словарС
v = d.values()  # ΠšΠΎΠ»Π»Π΅ΠΊΡ†ΠΈΡ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ. Π’ΠΎΠΆΠ΅ ΠΎΡ‚Ρ€Π°ΠΆΠ°Π΅Ρ‚ измСнСния Π² основном словарС
k_v = d.items()  # ΠšΠΎΡ€Ρ‚Π΅ΠΆΠΈ ΠΊΠ»ΡŽΡ‡-Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Ρ‚ΠΎΠΆΠ΅ ΠΎΡ‚Ρ€Π°ΠΆΠ°ΡŽΡ‚ измСнСния Π² основном словарС

print(d)
print(k)
print(v)
print(k_v)

print(f"Mapping: {k.mapping['Italy']}")

d.update({"China": "Dumplings"})  # Π”ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅. ΠŸΡ€ΠΈ совпадСнии ΠΊΠ»ΡŽΡ‡Π° староС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π±ΡƒΠ΄Π΅Ρ‚ пСрСзаписано
print(f"Replace item: {d}")

c = d["China"]  # Π§ΠΈΡ‚Π°Π΅ΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅
print(f"Read item: {c}")

try:
    v = d.pop("Spain")  # УдаляСт Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΈΠ»ΠΈ Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ KeyError
except KeyError:
    print("Dictionary key doesn't exist")

# ΠŸΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ dict comprehension (Π±ΠΎΠ»Π΅Π΅ ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎ comprehension Π±ΡƒΠ΄Π΅Ρ‚ рассмотрСно Π½ΠΈΠΆΠ΅)
b = {k: v for k, v in d.items() if "a" in k}  # Π’Π΅Ρ€Π½Π΅Ρ‚ Π½ΠΎΠ²Ρ‹ΠΉ ΡΠ»ΠΎΠ²Π°Ρ€ΡŒ, ΠΎΡ‚Ρ„ΠΈΠ»ΡŒΡ‚Ρ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ ΠΏΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ ΠΊΠ»ΡŽΡ‡Π°
print(b)

c = {k: v for k, v in d.items() if len(v) >= 7}  # Π’Π΅Ρ€Π½Π΅Ρ‚ Π½ΠΎΠ²Ρ‹ΠΉ ΡΠ»ΠΎΠ²Π°Ρ€ΡŒ, ΠΎΡ‚Ρ„ΠΈΠ»ΡŒΡ‚Ρ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ ΠΏΠΎ Π΄Π»ΠΈΠ½Π΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ
print(c)

d.clear() # ΠžΡ‡ΠΈΡΡ‚ΠΊΠ° словаря
{'Italy': 'Pizza', 'US': 'Hot-Dog', 'China': 'Dim Sum'}
dict_keys(['Italy', 'US', 'China'])
dict_values(['Pizza', 'Hot-Dog', 'Dim Sum'])
dict_items([('Italy', 'Pizza'), ('US', 'Hot-Dog'), ('China', 'Dim Sum')])
Mapping: Pizza
Replace item: {'Italy': 'Pizza', 'US': 'Hot-Dog', 'China': 'Dumplings'}
Read item: Dumplings
Dictionary key doesn't exist
{'Italy': 'Pizza', 'China': 'Dumplings'}
{'US': 'Hot-Dog', 'China': 'Dumplings'}

РСшСниС ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹ вычислСния Ρ…Π΅ΡˆΠ° ΠΏΡ€ΠΈ Ρ€Π°Π±ΠΎΡ‚Π΅ со словарСм

Π›ΡŽΠ±Π°Ρ Ρ…Π΅Ρˆ-Ρ‚Π°Π±Π»ΠΈΡ†Π°, Π² Ρ‚ΠΎΠΌ числС ΠΈ питоновский ΡΠ»ΠΎΠ²Π°Ρ€ΡŒ, Π΄ΠΎΠ»ΠΆΠ½Π° ΡƒΠΌΠ΅Ρ‚ΡŒ Ρ€Π΅ΡˆΠ°Ρ‚ΡŒ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡƒ вычислСния Ρ…Π΅ΡˆΠ°. Для этого ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ Ρ‚Π΅Ρ…Π½ΠΈΠΊΠΈ open addressing ΠΈΠ»ΠΈ chaining. Python ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ open addressing.

Новый ΡΠ»ΠΎΠ²Π°Ρ€ΡŒ инициализируСтся с 8 пустыми слотами.

Π˜Π½Ρ‚Π΅Ρ€ΠΏΡ€Π΅Ρ‚Π°Ρ‚ΠΎΡ€ сначала пытаСтся Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Π½ΠΎΠ²ΡƒΡŽ запись ΠΏΠΎ адрСсу, зависящСму ΠΎΡ‚ Ρ…Π΅ΡˆΠ° ΠΊΠ»ΡŽΡ‡Π°.

addr = hash(key) & mask,

Π³Π΄Π΅

mask = PyDictMINSIZE - 1

Если этот адрСс занят, Ρ‚ΠΎ ΠΈΠ½Ρ‚Π΅Ρ€ΠΏΡ€Π΅Ρ‚Π°Ρ‚ΠΎΡ€ провСряСт (ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ ==) Ρ…Π΅Ρˆ ΠΈ ΠΊΠ»ΡŽΡ‡. Если ΠΎΠ±Π° ΡΠΎΠ²ΠΏΠ°Π΄Π°ΡŽΡ‚, Ρ‚ΠΎ, Π·Π½Π°Ρ‡ΠΈΡ‚, запись ΡƒΠΆΠ΅ сущСствуСт. Π’ΠΎΠ³Π΄Π° начинаСтся Π·ΠΎΠ½Π΄ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ свободных слотов, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ ΠΈΠ΄Π΅Ρ‚ Π² псСвдослучайном порядкС (порядок зависит ΠΎΡ‚ значСния ΠΊΠ»ΡŽΡ‡Π°). Новая запись Π±ΡƒΠ΄Π΅Ρ‚ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½Π° ΠΏΠΎ ΠΏΠ΅Ρ€Π²ΠΎΠΌΡƒ свободному адрСсу.

Π§Ρ‚Π΅Π½ΠΈΠ΅ ΠΈΠ· словаря происходит Π°Π½Π°Π»ΠΎΠ³ΠΈΡ‡Π½ΠΎ, ΠΈΠ½Ρ‚Π΅Ρ€ΠΏΡ€Π΅Ρ‚Π°Ρ‚ΠΎΡ€ Π½Π°Ρ‡ΠΈΠ½Π°Π΅Ρ‚ поиск с ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ addr ΠΈ ΠΈΠ΄Π΅Ρ‚ ΠΏΠΎ Ρ‚ΠΎΠΌΡƒ ΠΆΠ΅ псСвдослучайному ΠΏΡƒΡ‚ΠΈ, ΠΏΠΎΠΊΠ° Π½Π΅ ΠΏΡ€ΠΎΡ‡ΠΈΡ‚Π°Π΅Ρ‚ Π½ΡƒΠΆΠ½ΡƒΡŽ запись.

Defaultdict

Если ΠΏΠΎΠΏΡ‹Ρ‚Π°Ρ‚ΡŒΡΡ ΠΏΡ€ΠΎΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ ΠΈΠ· ΠΎΠ±Ρ‹Ρ‡Π½ΠΎΠ³ΠΎ словаря Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΊΠ»ΡŽΡ‡Π°, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ Ρ‚Π°ΠΌ Π½Π΅Ρ‚, Ρ‚ΠΎ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹Π±Ρ€ΠΎΡˆΠ΅Π½ΠΎ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ KeyError (ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ Π±ΡƒΠ΄ΡƒΡ‚ рассмотрСны Π½ΠΈΠΆΠ΅). Defaultdict позволяСт Π½Π΅ ΠΏΠΈΡΠ°Ρ‚ΡŒ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΉ, Π° просто воспринимаСт Ρ‡Ρ‚Π΅Π½ΠΈΠ΅ Π½Π΅ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰Π΅Π³ΠΎ ΠΊΠ»ΡŽΡ‡Π° ΠΊΠ°ΠΊ ΠΊΠΎΠΌΠ°Π½Π΄Ρƒ Π·Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ Π² этот ΠΊΠ»ΡŽΡ‡ ΠΈ Π²Π΅Ρ€Π½ΡƒΡ‚ΡŒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ; Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, defaultdict(int) Π²Π΅Ρ€Π½Π΅Ρ‚ 0.

from collections import defaultdict

dd = defaultdict(int)
print(dd[10])  # ΠŸΠ΅Ρ‡Π°Ρ‚ΡŒ int, Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹Π²Π΅Π΄Π΅Π½ ноль, Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ

dd = {}  # "ΠžΠ±Ρ‹Ρ‡Π½Ρ‹ΠΉ" пустой ΡΠ»ΠΎΠ²Π°Ρ€ΡŒ
# print(dd[10])  # Π²Ρ‹Π·ΠΎΠ²Π΅Ρ‚ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ KeyError
0

Π‘Ρ‡Π΅Ρ‚Ρ‡ΠΈΠΊ (counter)

Π‘Ρ‡Π΅Ρ‚Ρ‡ΠΈΠΊ подсчитываСт ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Π΅ΠΌΡ‹Π΅ Π΅ΠΌΡƒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹. Иногда ΠΎΡ‡Π΅Π½ΡŒ ΡƒΠ΄ΠΎΠ±Π½ΠΎ просто Π±ΡƒΡ…Π½ΡƒΡ‚ΡŒ Π² счСтчик ΠΊΠ°ΠΊΠΎΠΉ-Π½ΠΈΠ±ΡƒΠ΄ΡŒ список ΠΈ сразу ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ структуру Π΄Π°Π½Π½Ρ‹Ρ… с подсчитанными элСмСнтами.

from collections import Counter

shirts_colors = ["red", "white", "blue", "white", "white", "black", "black"]
c = Counter(shirts_colors)
print(c)

c["blue"] += 1
print(f"After shopping: {c}")
Counter({'white': 3, 'black': 2, 'red': 1, 'blue': 1})
After shopping: Counter({'white': 3, 'blue': 2, 'black': 2, 'red': 1})

ОбъяснСниС Ρ€Π°Π±ΠΎΡ‚Ρ‹ Counter() ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ defaultdict():

from collections import defaultdict

shirts_colors = ["red", "white", "blue", "white", "white", "black", "black"]

d = defaultdict(int)
for shirt in shirts_colors:
    d[shirt] += 1

print(d)
defaultdict(<class 'int'>, {'red': 1, 'white': 3, 'blue': 1, 'black': 2})

ΠœΠ½ΠΎΠΆΠ΅ΡΡ‚Π²ΠΎ (set)

Π’Ρ€Π΅Ρ‚ΡŒΡ ΠΏΠΎ распространСнности питоновская структура Π΄Π°Π½Π½Ρ‹Ρ…. Когда-Ρ‚ΠΎ, ΠΊΠΎΠ³Π΄Π° Python Π±Ρ‹Π» ΠΌΠΎΠ»ΠΎΠ΄, мноТСства прСдставляли собой нСсколько Ρ€Π΅Π΄ΡƒΡ†ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Π΅ словари, Π½ΠΎ со Π²Ρ€Π΅ΠΌΠ΅Π½Π΅ΠΌ ΠΈΡ… ΡΡƒΠ΄ΡŒΠ±Ρ‹ (ΠΈ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ) стали Ρ€Π°ΡΡ…ΠΎΠ΄ΠΈΡ‚ΡŒΡΡ. Однако, мноТСство всё-Ρ‚Π°ΠΊΠΈ являСтся Ρ…Π΅Ρˆ-Ρ‚Π°Π±Π»ΠΈΡ†Π΅ΠΉ с ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΌ быстродСйствиСм Π½Π° Ρ€Π°Π·Π½Ρ‹Ρ… Ρ‚ΠΈΠΏΠ°Ρ… ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ.

big_cities: set["str"] = {"New-York", "Los Angeles", "Ottawa"}
american_cities: set["str"] = {"Chicago", "New-York", "Los Angeles"}

big_cities |= {"Sydney"}  # Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ (ΠΈΠ»ΠΈ add())
american_cities |= {"Salt Lake City", "Seattle"}  # Π‘Π»ΠΎΠΆΠΈΡ‚ΡŒ мноТСства (ΠΈΠ»ΠΈ update())

print(big_cities, american_cities)

union_cities: set["str"] = big_cities | american_cities  # Или union()
intersected_cities: set["str"] = big_cities & american_cities  # Или intersection()
dif_cities: set["str"] = big_cities - american_cities  # Или difference()
symdif_cities: set["str"] = big_cities ^ american_cities  # Или symmetric_difference()

issub: bool = big_cities <= union_cities  # Или issubset()
issuper: bool = american_cities >= dif_cities  # Или issuperset()

print(union_cities)
print(intersected_cities)
print(dif_cities)
print(symdif_cities)

print(issub, issuper)

big_cities.add("London")

big_cities.remove("Ottawa")  # УдаляСт Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, Ссли ΠΎΠ½ΠΎ имССтся ΠΈΠ»ΠΈ выбрасываСт KeyError
big_cities.discard("Los Angeles")  # УдаляСт Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π±Π΅Π· выбрасывания KeyError
big_cities.pop()  # Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΈ удаляСт случайноС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ (порядок Π² set Π½Π΅ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½) ΠΈΠ»ΠΈ выбрасываСт KeyError
big_cities.clear()  # ΠžΡ‡ΠΈΡ‰Π°Π΅Ρ‚ мноТСство
{'New-York', 'Los Angeles', 'Sydney', 'Ottawa'} {'New-York', 'Seattle', 'Chicago', 'Los Angeles', 'Salt Lake City'}
{'Ottawa', 'Salt Lake City', 'Chicago', 'New-York', 'Seattle', 'Sydney', 'Los Angeles'}
{'New-York', 'Los Angeles'}
{'Ottawa', 'Sydney'}
{'Seattle', 'Ottawa', 'Chicago', 'Salt Lake City', 'Sydney'}
True False

Π˜ΠΌΠΌΡƒΡ‚Π°Π±Π΅Π»ΡŒΠ½ΠΎΠ΅ мноТСство (frozen set)

Frozen set β€” Ρ‚ΠΎ ΠΆΠ΅ мноТСство, Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΈΠΌΠΌΡƒΡ‚Π°Π±Π΅Π»ΡŒΠ½ΠΎΠ΅ ΠΈ Ρ…Π΅ΡˆΠΈΡ€ΡƒΠ΅ΠΌΠΎΠ΅. НапоминаСт Ρ€Π°Π·Π½ΠΈΡ†Ρƒ ΠΌΠ΅ΠΆΠ΄Ρƒ списком ΠΈ ΠΊΠΎΡ€Ρ‚Π΅ΠΆΠ΅ΠΌ, Π½Π΅ ΠΏΡ€Π°Π²Π΄Π° Π»ΠΈ?

a = frozenset({"New-York", "Los Angeles", "Ottawa"})

Массив (array, bytes, bytearray)

Π― ΠΏΠ΅Ρ€Π΅ΡˆΠ΅Π» Π½Π° Python с языков, Π±ΠΎΠ»Π΅Π΅ ΠΏΡ€ΠΈΠ±Π»ΠΈΠΆΠ΅Π½Π½Ρ‹Ρ… ΠΊ Β«ΠΆΠ΅Π»Π΅Π·ΡƒΒ» (C, C#, Π΄Π°ΠΆΠ΅ Π½Π° ассСмблСрС ΠΊΠΎΠ³Π΄Π°-Ρ‚ΠΎ писал Π·Π° дСньги :) ΠΈ сначала Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ удивлялся, Ρ‡Ρ‚ΠΎ ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹ΠΉ массив, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ всё Ρ‚Π°ΠΊ ΡƒΠ΄ΠΎΠ±Π½ΠΎ Π»Π΅ΠΆΠΈΡ‚ Π½Π° своих мСстах, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Ρ€Π΅Π΄ΠΊΠΎ. Массив Π² Python Π½Π΅ являСтся структурой Π΄Π°Π½Π½Ρ‹Ρ…, Π²Ρ‹Π±ΠΈΡ€Π°Π΅ΠΌΠΎΠΉ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π² случаях, ΠΊΠΎΠ³Π΄Π° Ρ€Π΅ΡˆΠ°ΡŽΡ‰ΡƒΡŽ Ρ€ΠΎΠ»ΡŒ Π½Π°Ρ‡ΠΈΠ½Π°ΡŽΡ‚ ΠΈΠ³Ρ€Π°Ρ‚ΡŒ Ρ€Π°Π·ΠΌΠ΅Ρ€ структуры ΠΈ ΡΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ Π΅Ρ‘ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ. Но, с Π΄Ρ€ΡƒΠ³ΠΎΠΉ стороны, Ссли Π²Ρ‹ смотритС Π² сторону NumPy ΠΈ Pandas (Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ Π·Π°Ρ‚Ρ€ΠΎΠ½ΡƒΡ‚Ρ‹ Π½ΠΈΠΆΠ΅), Ρ‚ΠΎ массивы β€” вашС всё.

Массив Ρ…Ρ€Π°Π½ΠΈΡ‚ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ°, поэтому, Π² ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ ΠΎΡ‚ списка, Π½Π΅ Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ создания Π½ΠΎΠ²ΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° для ΠΊΠ°ΠΆΠ΄ΠΎΠΉ Π½ΠΎΠ²ΠΎΠΉ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ ΠΈ Π²Ρ‹ΠΈΠ³Ρ€Ρ‹Π²Π°Π΅Ρ‚ Ρƒ списка Π² Ρ€Π°Π·ΠΌΠ΅Ρ€Π°Ρ… ΠΈ скорости доступа. МоТно ΡΠΊΠ°Π·Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ это тонкая ΠΎΠ±Ρ‘Ρ€Ρ‚ΠΊΠ° Π½Π°Π΄ Π‘ΠΈ-массивами.

Π‘Π»Π΅Π΄ΡƒΠ΅Ρ‚ Ρ€Π°Π·Π»ΠΈΡ‡Π°Ρ‚ΡŒ array («просто» массив), bytes (ΠΈΠΌΠΌΡƒΡ‚Π°Π±Π΅Π»ΡŒΠ½Ρ‹ΠΉ массив, содСрТащий Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π±Π°ΠΉΡ‚Ρ‹, наслСдиС str ΠΈΠ· Python 2) ΠΈ bytearray (ΠΌΡƒΡ‚Π°Π±Π΅Π»ΡŒΠ½Ρ‹ΠΉ Π±Π°ΠΉΡ‚ΠΎΠ²Ρ‹ΠΉ массив).

from array import array

a1 = array("l", [1, 2, 3, -4])
a2 = array("b", b"1234567890")
b = bytes(a2)

print(a1)
print(a2[0])
print(b)

print(a1.index(-4))  # Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ индСкс элСмСнты ΠΈΠ»ΠΈ выбрасываСт ValueError
array('l', [1, 2, 3, -4])
49
b'1234567890'
3
# Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅

b1 = bytes([1, 2, 3, 4])  # Π¦Π΅Π»Ρ‹Π΅ числа Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ Π² Π΄ΠΈΠ°ΠΏΠ°Π·ΠΎΠ½Π΅ ΠΎΡ‚ 0 to 255
b2 = "The String".encode('utf-8')
b3 = (-1024).to_bytes(4, byteorder='big', signed=True)  # byteorder = "big"/"little"/"sys.byteorder", signed = False/True
b4 = bytes.fromhex('FEADCA')  # Для большСй читаСмости hex-значСния ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ Ρ€Π°Π·Π΄Π΅Π»Π΅Π½Ρ‹ ΠΏΡ€ΠΎΠ±Π΅Π»Π°ΠΌΠΈ
b5 = bytes(range(10,30,2))

print(b1, b2, b3, b4, b5)

# ΠŸΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΠ΅

c: list = list(b"\xfc\x00\x00\x00\x00\x01")
s: str = b'The String'.decode("utf-8")
b: int = int.from_bytes(b"\xfc\x00", byteorder='big', signed=False)  # byteorder = "big"/"little"/"sys.byteorder", signed = False/True
s2: str = b"\xfc\x00\x00\x00\x00\x01".hex(" ")

print(c, s, b, s2)

with open("1.bin", "wb") as file:  # Байтовая запись Π² Ρ„Π°ΠΉΠ»
    file.write(b1)

with open("1.bin", "rb") as file:  # Π§Ρ‚Π΅Π½ΠΈΠ΅ ΠΈΠ· Ρ„Π°ΠΉΠ»Π°
    b6 = file.read()

print(b6)
b'\x01\x02\x03\x04' b'The String' b'\xff\xff\xfc\x00' b'\xfe\xad\xca' b'\n\x0c\x0e\x10\x12\x14\x16\x18\x1a\x1c'
[252, 0, 0, 0, 0, 1] The String 64512 fc 00 00 00 00 01
b'\x01\x02\x03\x04'

ΠžΠ΄Π½ΠΎΡΠ²ΡΠ·Π½Ρ‹ΠΉ список

ΠžΠ΄Π½ΠΎΡΠ²ΡΠ·Π½Ρ‹ΠΉ список прСдставляСт Π½Π°Π±ΠΎΡ€ связанных ΡƒΠ·Π»ΠΎΠ², ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΈΠ· ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Ρ…Ρ€Π°Π½ΠΈΡ‚ собствСнныС Π΄Π°Π½Π½Ρ‹Π΅ ΠΈ ссылку Π½Π° ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ ΡƒΠ·Π΅Π». Π’ ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠ΅ ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΠΌ Ρ€Π΅Π΄ΠΊΠΎ, Π½ΠΎ Π΅Π³ΠΎ Π»ΡŽΠ±ΡΡ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΈΠ½Ρ‚Π΅Ρ€Π²ΡŒΡŽΠ΅Ρ€Ρ‹ Π½Π° собСсСдованиях, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΊΠ°Π½Π΄ΠΈΠ΄Π°Ρ‚ ΠΌΠΎΠ³ Π±Π»Π΅ΡΠ½ΡƒΡ‚ΡŒ своими алгоритмичСскими знаниями. Π’ Python встроСнной Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ Π½Π΅ ΠΈΠΌΠ΅Π΅Ρ‚, ΠΌΠΎΠΆΠ½ΠΎ ΠΈΠ»ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ deque (Π² основС ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ Π»Π΅ΠΆΠΈΡ‚ двусвязный список), ΠΈΠ»ΠΈ Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ свою Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ.

Двусвязный список (Deque)

Бсылки Π² ΠΊΠ°ΠΆΠ΄ΠΎΠΌ ΡƒΠ·Π»Π΅ двусвязного списка ΡƒΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‚ Π½Π° ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰ΠΈΠΉ ΠΈ Π½Π° ΠΏΠΎΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ ΡƒΠ·Π΅Π» Π² спискС. МоТно ΠΈΠ»ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ deque, ΠΈΠ»ΠΈ Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ свою Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ.

from collections import deque
d = deque([1, 2, 3, 4], maxlen=1000)

d.append(5)  # Add element to the right side of the deque
d.appendleft(0)  # Add element to the left side of the deque by appending elements from iterable

d.extend([6, 7])  # Extend the right side of the deque
d.extendleft([-1, -2])  # Extend the left side of the deque
print(d)

a = d.pop()  # Remove and return an element from the right side of the deque. Can raise an IndexError
b = d.popleft()  # Remove and return an element from the left side of the deque. Can raise an IndexError
print(a, b)
print(d)
deque([-2, -1, 0, 1, 2, 3, 4, 5, 6, 7], maxlen=1000)
7 -2
deque([-1, 0, 1, 2, 3, 4, 5, 6], maxlen=1000)

Queue

Queue Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΠ΅Ρ‚ FIFO со мноТСствСнными поставщиками Π΄Π°Π½Π½Ρ‹Ρ… ΠΈ мноТСствСнными потрСбитСлями. ΠœΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ особСнно ΠΏΠΎΠ»Π΅Π·Π΅Π½ ΠΏΡ€ΠΈ многопоточности, позволяя ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎ ΠΎΠ±ΠΌΠ΅Π½ΠΈΠ²Π°Ρ‚ΡŒΡΡ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠ΅ΠΉ ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌΠΈ. Π’Π°ΠΊΠΆΠ΅ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‚ LifoQueue для Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ LIFO ΠΈ PriorityQueue для Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ с ΠΏΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚ΠΎΠΌ.

from queue import Queue
q = Queue(maxsize=1000)

q.put("eat", block=True, timeout=10)
q.put("sleep")  # По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ block=True, timeout=None
q.put("code")
q.put_nowait("repeat")  # Π­ΠΊΠ²ΠΈΠ²Π°Π»Π΅Π½Ρ‚ put("repeat", block=False). Если свободный слот Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ прСдоставлСн Π½Π΅ΠΌΠ΅Π΄Π»Π΅Π½Π½ΠΎ, Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹Π·Π²Π°Π½ΠΎ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ queue.Full
print(q.queue)

a = q.get(block=True, timeout=10)  # Π£Π΄Π°Π»ΠΈΡ‚ΡŒ ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‚ΠΈΡ‚ΡŒ элСмСнт ΠΈΠ· FIFO
b = q.get()  # По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ block=True, timeout=None
c = q.get_nowait()  # Π­ΠΊΠ²ΠΈΠ²Π°Π»Π΅Π½Ρ‚ get(False)
print(a, b, c, q.queue)
deque(['eat', 'sleep', 'code', 'repeat'])
eat sleep code deque(['repeat'])

Π‘ΠΈΠ½Π°Ρ€Π½ΠΎΠ΅ Π΄Π΅Ρ€Π΅Π²ΠΎ (binary tree)

Π˜Π΅Ρ€Π°Ρ€Ρ…ΠΈΡ‡Π΅ΡΠΊΠ°Ρ структура Π΄Π°Π½Π½Ρ‹Ρ…, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΡƒΠ·Π΅Π» ΠΈΠΌΠ΅Π΅Ρ‚ Π½Π΅ Π±ΠΎΠ»Π΅Π΅ Π΄Π²ΡƒΡ… ΠΏΠΎΡ‚ΠΎΠΌΠΊΠΎΠ². ВстроСнной Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ Π½Π΅ ΠΈΠΌΠ΅Π΅Ρ‚, Π½ΡƒΠΆΠ½ΠΎ ΠΏΠΈΡΠ°Ρ‚ΡŒ свою. Как ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ Π΄Π΅Ρ€Π΅Π²ΡŒΡ с Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌΠΈ свойствами, рассмотрСнныС Π½ΠΈΠΆΠ΅.

ΠšΡƒΡ‡Π° (heap)

Π‘ΠΈΠ½Π°Ρ€Π½ΠΎΠ΅ Π΄Π΅Ρ€Π΅Π²ΠΎ, ΡƒΠ΄ΠΎΠ²Π»Π΅Ρ‚Π²ΠΎΡ€ΡΡŽΡ‰Π΅Π΅ свойство ΠΊΡƒΡ‡ΠΈ: Ссли B являСтся ΡƒΠ·Π»ΠΎΠΌ-ΠΏΠΎΡ‚ΠΎΠΌΠΊΠΎΠΌ ΡƒΠ·Π»Π° A, Ρ‚ΠΎ ΠΊΠ»ΡŽΡ‡(A) β‰₯ ΠΊΠ»ΡŽΡ‡(B). ΠšΡƒΡ‡Π° являСтся максимально эффСктивной Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠ΅ΠΉ абстрактного Ρ‚ΠΈΠΏΠ° Π΄Π°Π½Π½Ρ‹Ρ…, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ называСтся ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒΡŽ с ΠΏΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚ΠΎΠΌ ΠΈ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‰Π΅Π³ΠΎ Π΄Π²Π΅ ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ β€” Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ элСмСнт ΠΈ ΠΈΠ·Π²Π»Π΅Ρ‡ΡŒ ΠΌΠΈΠ½ΠΈΠΌΡƒΠΌ (ΠΈΠ»ΠΈ максимум, Π² зависимости ΠΎΡ‚ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ).

Π’ Python min-ΠΊΡƒΡ‡Π° (наимСньшСС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ всСгда Π»Π΅ΠΆΠΈΡ‚ Π² ΠΊΠΎΡ€Π½Π΅) Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π° Π½Π° Π±Π°Π·Π΅ списка ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ встроСнного модуля heapq. Если Π²Π°ΠΌ Π½ΡƒΠΆΠ½Π° max-ΠΊΡƒΡ‡Π°, с ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ Π² ΠΊΠΎΡ€Π½Π΅, ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π²ΠΎΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ совСтами со Stackoverflow.

import heapq

h = [211, 1, 43, 79, 12, 5, -10, 0]
heapq.heapify(h)  # ΠŸΡ€Π΅Π²Ρ€Π°Ρ‰Π°Π΅ΠΌ список Π² ΠΊΡƒΡ‡Ρƒ
print(h)

heapq.heappush(h, 2)  # ДобавляСм элСмСнт
print(h)

m = heapq.heappop(h)  # ИзвлСкаСм ΠΌΠΈΠ½ΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΉ элСмСнт
print(h, m)
[-10, 0, 5, 1, 12, 211, 43, 79]
[-10, 0, 5, 1, 12, 211, 43, 79, 2]
[0, 1, 5, 2, 12, 211, 43, 79] -10

ΠŸΡ€ΠΎΠ±Π΅ΠΆΠΈΠΌΡΡ ΠΊΠΎΡ€ΠΎΡ‚Π΅Π½ΡŒΠΊΠΎ ΠΏΠΎ ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹ΠΌ структурам Π΄Π°Π½Π½Ρ‹Ρ…, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π² Python Π½Π΅ ΠΈΠΌΠ΅ΡŽΡ‚ встроСнной Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ, Π½ΠΎ, Ρ‚Π΅ΠΌ Π½Π΅ ΠΌΠ΅Π½Π΅Π΅, ΠΌΠΎΠ³ΡƒΡ‚ вСсьма ΠΏΡ€ΠΈΠ³ΠΎΠ΄ΠΈΡ‚ΡŒΡΡ Π² Ρ€Π΅Π°Π»ΡŒΠ½ΠΎΠΌ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π΅.

Π‘ΠΈ-Π΄Π΅Ρ€Π΅Π²ΠΎ (B-tree)

БбалансированноС Π΄Π΅Ρ€Π΅Π²ΠΎ, ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ΅ для доступа ΠΊ ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΠΌΠ΅Π΄Π»Π΅Π½Π½Ρ‹ΠΌ элСмСнтам памяти (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, дисковым структурам ΠΈΠ»ΠΈ индСксам Π±Π°Π· Π΄Π°Π½Π½Ρ‹Ρ…); ΠΊΠ°ΠΊ Π²Π΅Ρ‚Π²ΠΈ, Ρ‚Π°ΠΊ ΠΈ Π»ΠΈΡΡ‚ΡŒΡ ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²Π»ΡΡŽΡ‚ собой списки (для Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΌΠΎΠΆΠ½ΠΎ Π±Ρ‹Π»ΠΎ ΡΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ Ρ‚Π°ΠΊΠΎΠΉ список Π² ΠΎΠ΄ΠΈΠ½ ΠΏΡ€ΠΎΡ…ΠΎΠ΄ для дальнСйшСго быстрого Ρ€Π°Π·Π±ΠΎΡ€Π° Π² ΠžΠ—Π£). НуТно ΠΏΠΈΡΠ°Ρ‚ΡŒ свою Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ. Π›ΠΈΠ±ΠΎ β€” Π²ΠΎΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ встроСнной Π² Python ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΎΠΉ Π±Π°Π·Ρ‹ Π΄Π°Π½Π½Ρ‹Ρ… sqlite3, эта Π‘Π” ΠΊΠ°ΠΊ Ρ€Π°Π· Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π° Π½Π° Π±ΠΈ-Π΄Π΅Ρ€Π΅Π²Π΅.

ΠšΡ€Π°ΡΠ½ΠΎ-Ρ‡Π΅Ρ€Π½ΠΎΠ΅ Π΄Π΅Ρ€Π΅Π²ΠΎ

Π‘Π°ΠΌΠΎΠ±Π°Π»Π°Π½ΡΠΈΡ€ΡƒΡŽΡ‰Π΅Π΅ΡΡ Π΄Π²ΠΎΠΈΡ‡Π½ΠΎΠ΅ Π΄Π΅Ρ€Π΅Π²ΠΎ поиска, ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‰Π΅Π΅ быстро Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒ основныС ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ: Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅, ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠ΅ ΠΈ поиск ΡƒΠ·Π»Π°. Π‘Π±Π°Π»Π°Π½ΡΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΡΡ‚ΡŒ достигаСтся Π·Π° счёт ввСдСния Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ ΠΏΡ€ΠΈΠ·Π½Π°ΠΊΠ° ΡƒΠ·Π»Π° Π΄Π΅Ρ€Π΅Π²Π° β€” Β«Ρ†Π²Π΅Ρ‚Π°Β». Π­Ρ‚ΠΎΡ‚ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Ρ‚ΡŒ ΠΎΠ΄Π½ΠΎ ΠΈΠ· Π΄Π²ΡƒΡ… Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Ρ… Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ β€” Β«Ρ‡Ρ‘Ρ€Π½Ρ‹ΠΉΒ» ΠΈΠ»ΠΈ «красный». ЛистовыС ΡƒΠ·Π»Ρ‹ КЧ Π΄Π΅Ρ€Π΅Π²ΡŒΠ΅Π² Π½Π΅ содСрТат Π΄Π°Π½Π½Ρ‹Ρ…, поэтому Π½Π΅ Ρ‚Ρ€Π΅Π±ΡƒΡŽΡ‚ выдСлСния памяти β€” достаточно просто Π·Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ Π² ΡƒΠ·Π»Π΅-ΠΏΡ€Π΅Π΄ΠΊΠ΅ Π½ΡƒΠ»Π΅Π²ΠΎΠΉ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° ΠΏΠΎΡ‚ΠΎΠΌΠΊΠ°. НуТно ΠΏΠΈΡΠ°Ρ‚ΡŒ свою Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ.
Π’ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, Π²Ρ‹ Ρ‡ΠΈΡ‚Π°Π»ΠΈ ΠΎ Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΈ собСсСдовании Π² FAANG ΠΏΡ€Π΅Ρ‚Π΅Π½Π΄Π΅Π½Ρ‚ΠΎΠ² Β«Π·Π°ΡΡ‚Π°Π²Π»ΡΡŽΡ‚ ΠΊΡ€ΡƒΡ‚ΠΈΡ‚ΡŒ красно-Ρ‡Π΅Ρ€Π½ΠΎΠ΅ Π΄Π΅Ρ€Π΅Π²ΠΎ Π½Π° доскС». Π­Ρ‚ΠΎ Β«ΠΊΡ€ΡƒΠΆΠ΅Π½ΠΈΠ΅Β» ΠΈ Π΅ΡΡ‚ΡŒ балансировка, послС ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ вставки ΠΈΠ»ΠΈ удалСния элСмСнта Π΄Π΅Ρ€Π΅Π²ΠΎ Π½ΡƒΠΆΠ½ΠΎ ΠΎΡ‚Π±Π°Π»Π°Π½ΡΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ, с ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½Ρ‹ΠΌ объСмом ΠΊΠΎΠ΄Π° Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΎΠ·Π½Π°ΠΊΠΎΠΌΠΈΡ‚ΡŒΡΡ здСсь ΠΈΠ»ΠΈ здСсь.

АВЛ-Π΄Π΅Ρ€Π΅Π²ΠΎ

Π’ АВЛ-Π΄Π΅Ρ€Π΅Π²ΡŒΡΡ… ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ вставки ΠΈ удалСния Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‚ ΠΌΠ΅Π΄Π»Π΅Π½Π½Π΅Π΅, Ρ‡Π΅ΠΌ Π² красно-Ρ‡Π΅Ρ€Π½Ρ‹Ρ… Π΄Π΅Ρ€Π΅Π²ΡŒΡΡ… (ΠΏΡ€ΠΈ Ρ‚ΠΎΠΌ ΠΆΠ΅ количСствС Π»ΠΈΡΡ‚ΡŒΠ΅Π² красно-Ρ‡Ρ‘Ρ€Π½ΠΎΠ΅ Π΄Π΅Ρ€Π΅Π²ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Π²Ρ‹ΡˆΠ΅ АВЛ-Π΄Π΅Ρ€Π΅Π²Π°, Π½ΠΎ Π½Π΅ Π±ΠΎΠ»Π΅Π΅ Ρ‡Π΅ΠΌ Π² 1,388 Ρ€Π°Π·Π°). Поиск ΠΆΠ΅ Π² АВЛ-Π΄Π΅Ρ€Π΅Π²Π΅ выполняСтся быстрСС (максимальная Ρ€Π°Π·Π½ΠΈΡ†Π° Π² скорости поиска составляСт 39 %). НуТно ΠΏΠΈΡΠ°Ρ‚ΡŒ свою Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ.

ΠŸΡ€Π΅Ρ„ΠΈΠΊΡΠ½ΠΎΠ΅ Π΄Π΅Ρ€Π΅Π²ΠΎ

ΠŸΡ€Π΅Ρ„ΠΈΠΊΡΠ½ΠΎΠ΅ Π΄Π΅Ρ€Π΅Π²ΠΎ (ΠΈΠ»ΠΈ trie) β€” структура Π΄Π°Π½Π½Ρ‹Ρ…, ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‰Π°Ρ Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒ ассоциативный массив, ΠΊΠ»ΡŽΡ‡Π°ΠΌΠΈ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ ΡΠ²Π»ΡΡŽΡ‚ΡΡ строки. НуТно ΠΏΠΈΡΠ°Ρ‚ΡŒ свою Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ.

Π’Π°Π±Π»ΠΈΡ†Π° Π²Ρ‹Π±ΠΎΡ€Π° структуры Π΄Π°Π½Π½Ρ‹Ρ…

Π’ ΠΊΠ²Π°Π΄Ρ€Π°Ρ‚Π½Ρ‹Ρ… скобках ΠΏΠΎΠΊΠ°Π·Π°Π½ Ρ…ΡƒΠ΄ΡˆΠΈΠΉ случай.

Π‘Ρ‚Ρ€ΡƒΠΊΡ‚ΡƒΡ€Π° РСализация ΠŸΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ Π˜Π½Π΄Π΅ΠΊΡΠ°Ρ†ΠΈΡ Поиск Вставка Π£Π΄Π°Π»Π΅Π½ΠΈΠ΅ ΠŸΠ°ΠΌΡΡ‚ΡŒ
ДинамичСский массив list 1 n n n n
Π₯эш Ρ‚Π°Π±Π»ΠΈΡ†Π° dict, set 1
[n]
1
[n]
1
[n]
n
Массив array, bytes, bytearray Для хранСния ΠΎΠ΄Π½ΠΎΡ‚ΠΈΠΏΠ½Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ… 1 n n n n
ΠžΠ΄Π½ΠΎΡΠ²ΡΠ·Π½Ρ‹ΠΉ список - (~deque) n n 1 1 n
Двусвязный список deque FIFO, LIFO n n 1 1 n
Π‘ΠΈΠ½Π°Ρ€Π½ΠΎΠ΅ Π΄Π΅Ρ€Π΅Π²ΠΎ - logn
[n]
logn
[n]
logn
[n]
logn
[n]
n
ΠšΡƒΡ‡Π° heapq ΠžΡ‡Π΅Ρ€Π΅Π΄ΡŒ с ΠΏΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚ΠΎΠΌ 1
(find min)
logn logn
(del min)
n
B-tree (Π‘ΠΈ-Π΄Π΅Ρ€Π΅Π²ΠΎ) ~sqlite Для памяти с ΠΌΠ΅Π΄Π»Π΅Π½Π½Ρ‹ΠΌ доступом logn logn logn logn n
КЧ Π΄Π΅Ρ€Π΅Π²ΠΎ - logn logn logn logn n
АВЛ Π΄Π΅Ρ€Π΅Π²ΠΎ - logn logn logn logn n
ΠŸΡ€Π΅Ρ„ΠΈΠΊΡΠ½ΠΎΠ΅ Π΄Π΅Ρ€Π΅Π²ΠΎ - T9,
Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ ΠΡ…ΠΎβ€“ΠšΠΎΡ€Π°ΡΠΈΠΊ,
Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ LZW
key key key

ΠŸΠ΅Ρ€Π΅Ρ‡ΠΈΡΠ»Π΅Π½ΠΈΠ΅ (Enum, IntEnum)

Π£Π΄ΠΎΠ±Π½Ρ‹Π΅ конструкции для опрСдСлСния Π·Π°Ρ€Π°Π½Π΅Π΅ извСстных пСрСчислСний.

from enum import Enum, auto
import random

class Currency(Enum):
    euro = 1
    us_dollar = 2
    yuan = auto()

local_currency = Currency.us_dollar
print(local_currency)

local_currency = Currency["us_dollar"]  # ΠœΠΎΠΆΠ΅Ρ‚ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ KeyError
print(local_currency)

local_currency = Currency(2)  # ΠœΠΎΠΆΠ΅Ρ‚ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ValueError
print(local_currency)

print(local_currency.name)
print(local_currency.value)

list_of_members = list(Currency)
member_names    = [e.name for e in Currency]
member_values   = [e.value for e in Currency]
random_member   = random.choice(list(Currency))

print(list_of_members, "\n",
      member_names, "\n",
      member_values, "\n",
      random_member)
Currency.us_dollar
Currency.us_dollar
Currency.us_dollar
us_dollar
2
[<Currency.euro: 1>, <Currency.us_dollar: 2>, <Currency.yuan: 3>] 
 ['euro', 'us_dollar', 'yuan'] 
 [1, 2, 3] 
 Currency.euro

ЦСлочислСнный Π΄ΠΈΠ°ΠΏΠ°Π·ΠΎΠ½ (range)

range() Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΈΠΌΠΌΡƒΡ‚Π°Π±Π΅Π»ΡŒΠ½ΡƒΡŽ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ чисСл, которая часто ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ ΠΊΠ°ΠΊ Π·Π°Π΄Π°Ρ‚Ρ‡ΠΈΠΊ Π΄ΠΈΠ°ΠΏΠ°Π·ΠΎΠ½Π° для Ρ†ΠΈΠΊΠ»Π° for.

r1: range = range(11)  # Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ чисСл ΠΎΡ‚ 0 Π΄ΠΎ 10
r2: range = range(5, 21) # Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ чисСл ΠΎΡ‚ 5 Π΄ΠΎ 20
r3: range = range(20, 9, -2)  # Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ чисСл ΠΎΡ‚ 20 Π΄ΠΎ 10 с шагом 2

print("To exclusive: ", end="")
for i in r1:
  print(f"{i} ", end="")

print("\nFrom inclusive to exclusive: ", end="")
for i in r2:
  print(f"{i} ", end="")

print("\nFrom inclusive to exclusive with step: ", end="")
for i in r3:
  print(f"{i} ", end="")

print(f"\nFrom = {r3.start}")
print(f"To = {r3.stop}")
To exclusive: 0 1 2 3 4 5 6 7 8 9 10 
From inclusive to exclusive: 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 
From inclusive to exclusive with step: 20 18 16 14 12 10 
From = 20
To = 9

ΠšΠ»Π°ΡΡΡ‹ Π΄Π°Π½Π½Ρ‹Ρ… (dataclass)

Π”Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€, автоматичСски ΡΠΎΠ·Π΄Π°ΡŽΡ‰ΠΈΠΉ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ init(), repr() ΠΈ eq(). НуТСн для создания классов, Π³Π»Π°Π²Π½ΠΎΠΉ Π·Π°Π΄Π°Ρ‡Π΅ΠΉ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… являСтся Ρ…Ρ€Π°Π½Π΅Π½ΠΈΠ΅ Π΄Π°Π½Π½Ρ‹Ρ…. Аннотации Ρ‚ΠΈΠΏΠΎΠ² ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹. БущСствуСт Π±ΠΎΠ»Π΅Π΅ продвинутая Π°Π»ΡŒΡ‚Π΅Ρ€Π½Π°Ρ‚ΠΈΠ²Π° ΠΏΠΎΠ΄ Π½Π°Π·Π²Π°Π½ΠΈΠ΅ΠΌ attrs.

from dataclasses import dataclass
from decimal import *
from datetime import datetime

@dataclass
class Transaction:
    value: Decimal
    issuer: str = "Default Bank"
    dt: datetime = datetime.now()

t1 = Transaction(value=1000_000, issuer="Deutsche Bank", dt = datetime(2022, 1, 1, 12))
t2 = Transaction(1000)

print(t1)
print(t2)
Transaction(value=1000000, issuer='Deutsche Bank', dt=datetime.datetime(2022, 1, 1, 12, 0))
Transaction(value=1000, issuer='Default Bank', dt=datetime.datetime(2022, 9, 6, 17, 50, 36, 162897))

Dataclass ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ сдСлан ΠΈΠΌΠΌΡƒΡ‚Π°Π±Π΅Π»ΡŒΠ½Ρ‹ΠΌ с Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΈΠ²ΠΎΠΉ frozen=True.

from dataclasses import dataclass

@dataclass(frozen=True)
class User:
    name: str
    account: int

Бинарная Π·Π°ΠΏΠ°ΠΊΠΎΠ²ΠΊΠ° (struct)

Π—Π°ΠΏΠ°ΠΊΠΎΠ²ΠΊΠ° (ΠΈ распаковка, разумССтся) Π΄Π°Π½Π½Ρ‹Ρ… Π² Π±Π°ΠΉΡ‚ΠΎΠ²Ρ‹Π΅ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ с ΠΏΡ€Π΅Π΄ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹ΠΌΠΈ Ρ€Π°Π·ΠΌΠ΅Ρ€Π°ΠΌΠΈ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ элСмСнта Π΄Π°Π½Π½Ρ‹Ρ…, ΠΈΡ… порядка Π² структурС, Π° Ρ‚Π°ΠΊΠΆΠ΅ порядка Π±Π°ΠΉΡ‚ для ΠΌΠ½ΠΎΠ³ΠΎΠ±Π°ΠΉΡ‚ΠΎΠ²Ρ‹Ρ… Ρ‚ΠΈΠΏΠΎΠ² Π΄Π°Π½Π½Ρ‹Ρ…. ΠŸΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ‚ ΠΏΡ€Π΅Π²Ρ€Π°Ρ‰Π°Ρ‚ΡŒ Python-овский int Π², Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, short int ΠΈΠ»ΠΈ long int (подробности ΠΏΡ€ΠΎ систСму Ρ‚ΠΈΠΏΠΎΠ² языка Π‘ΠΈ).
ΠŸΡ€ΠΈ Ρ€Π°Π±ΠΎΡ‚Π΅ со структурами Π²Π°ΠΌ Π½ΡƒΠΆΠ½ΠΎ Π±ΡƒΠ΄Π΅Ρ‚ Π·Π½Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠ΅ little-endian ΠΈ big-endian, Π° Ρ‚Π°ΠΊΠΆΠ΅ Π½Π΅ Π·Π°Π±Ρ‹Π²Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ Ρ€Π°Π·ΠΌΠ΅Ρ€ Ρ‚ΠΈΠΏΠ° Π΄Π°Π½Π½Ρ‹Ρ… Π² Π‘ΠΈ Π±Ρ‹Π²Π°Π΅Ρ‚ Ρ€Π°Π·Π½Ρ‹ΠΌ.

from struct import pack, unpack, iter_unpack

b = pack(">hhll", 1, 2, 3, 4)
print(b)

t = unpack(">hhll", b)
print(t)

i = pack("ii", 1, 2) * 5
print(i)

print(list(iter_unpack('ii', i)))
b'\x00\x01\x00\x02\x00\x00\x00\x03\x00\x00\x00\x04'
(1, 2, 3, 4)
b'\x01\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00'
[(1, 2), (1, 2), (1, 2), (1, 2), (1, 2)]

Π‘Ρ‚Ρ€ΠΎΠΊΠ° (string)

Π‘Ρ‚Ρ€ΠΎΠΊΠΈ Π² Python 3 β€” ΠΈΠΌΠΌΡƒΡ‚Π°Π±Π΅Π»ΡŒΠ½Ρ‹Π΅ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰ΠΈΠ΅ ΠΊΠΎΠ΄ΠΈΡ€ΠΎΠ²ΠΊΡƒ Unicode.

se: str = ""  # ΠŸΡƒΡΡ‚Π°Ρ строка
si: str = str(12345)  # Π‘ΠΎΠ·Π΄Π°Π΅Ρ‚ строку ΠΈΠ· числа
sj: str = " ".join(["Follow", "the", "white", "rabbit"])  # Π‘ΠΎΠ±ΠΈΡ€Π°Π΅Ρ‚ строку ΠΈΠ· кусочков, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ ΡƒΠΊΠ°Π·Π°Π½Π½Ρ‹ΠΉ сСпаратор
print(f"Joined string: {sj}")

is_contains: bool = "rabbit" in sj  # ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° наличия подстроки
is_startswith = sj.startswith("Foll")
is_endswith = sj.endswith("bbit")
print(f"is_contains = {is_contains}, is_startswith = {is_startswith}, is_endswith = {is_endswith}")

sr: str  = sj.replace("rabbit", "sheep")  # Π—Π°ΠΌΠ΅Π½Π° подстроки. МоТно ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ количСство Π·Π°ΠΌΠ΅Π½: sr: str  = sj.replace("rabbit", "sheep", times)
print(f"After replace: {sr}")

i1 = sr.find("rabbit")  # Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ стартовый индСкс ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ вхоТдСния ΠΈΠ»ΠΈ -1. Π•ΡΡ‚ΡŒ Π΅Ρ‰Π΅ rfind(), Π½Π°Ρ‡ΠΈΠ½Π°ΡŽΡ‰ΠΈΠΉ ΠΈΡΠΊΠ°Ρ‚ΡŒ с ΠΊΠΎΠ½Ρ†Π° строки
i2 = sr.index("sheep")  #  Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ стартовый индСкс ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ вхоТдСния ΠΈΠ»ΠΈ Π²Ρ‹ΠΊΠΈΠ΄Ρ‹Π²Π°Π΅Ρ‚ ValueError. Π•ΡΡ‚ΡŒ Π΅Ρ‰Π΅ rindex(), Π½Π°Ρ‡ΠΈΠ½Π°ΡŽΡ‰ΠΈΠΉ ΠΈΡΠΊΠ°Ρ‚ΡŒ с ΠΊΠΎΠ½Ρ†Π° строки
print(f"Start index of 'rabbit' is {i1}, start index of 'sheep' is {i2}")

d = str.maketrans({"a" : "x", "b" : "y", "c" : "z"})
st  = "abc".translate(d)
print(f"Translate string: {st}")

sr = sj[::-1]  # РСвСрс Ρ‡Π΅Ρ€Π΅Π· slice с ΠΎΡ‚Ρ€ΠΈΡ†Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ шагом
print(f"Reverse string: {sr}")
Joined string: Follow the white rabbit
is_contains = True, is_startswith = True, is_endswith = True
After replace: Follow the white sheep
Start index of 'rabbit' is -1, start index of 'sheep' is 17
Translate string: xyz
Reverse string: tibbar etihw eht wolloF

Datetime

Для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с Π΄Π°Ρ‚Π°ΠΌΠΈ ΠΈ Π²Ρ€Π΅ΠΌΠ΅Π½Π΅ΠΌ Π² datetime Π΅ΡΡ‚ΡŒ Ρ‚ΠΈΠΏΡ‹ date, time, datetime ΠΈ timedelta. ВсС ΠΎΠ½ΠΈ Ρ…Π΅ΡˆΠΈΡ€ΡƒΠ΅ΠΌΡ‹ ΠΈ ΠΈΠΌΠΌΡƒΡ‚Π°Π±Π΅Π»ΡŒΠ½Ρ‹.

ΠšΠΎΠ½ΡΡ‚Ρ€ΡƒΠΊΡ‚ΠΎΡ€Ρ‹

from datetime import date, time, datetime, timedelta

d: date = date(year=1964, month=9, day=2)
t: time  = time(hour=12, minute=30, second=0, microsecond=0, tzinfo=None, fold=0)
dt: datetime = datetime(year=1964, month=9, day=2, hour=10, minute=30, second=0)
td: timedelta = timedelta(weeks=1, days=1, hours=12, minutes=13, seconds=14)

print (f"{d}\n {t}\n {dt}\n {td}")
1964-09-02
 12:30:00
 1964-09-02 10:30:00
 8 days, 12:13:14

Now

ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ Π΄Π°Ρ‚Ρ‹ ΠΈΠ»ΠΈ Π΄Π°Ρ‚Ρ‹/Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ.

from datetime import date, datetime
import pytz
import time

d: date  = date.today()
dt1: datetime = datetime.today()
dt2: datetime = datetime.utcnow()
dt3: datetime = datetime.now(pytz.timezone('US/Pacific'))

t1 = time.time()  # Π­ΠΏΠΎΡ…Π° Unix
t2 = time.ctime()

print (f"{d}\n {dt1}\n {dt2}\n {dt3}\n {t1}\n {t2}")
2022-09-27
 2022-09-27 09:47:02.430474
 2022-09-27 04:47:02.430474
 2022-09-26 21:47:02.430474-07:00
 1664254022.4304743
 Tue Sep 27 09:47:02 2022

Timezone

ЧасовыС пояса.

from datetime import date, time, datetime, timedelta, tzinfo
from dateutil.tz import UTC, tzlocal, gettz, datetime_exists, resolve_imaginary

tz1: tzinfo = UTC  # Часовой пояс UTC

tz2: tzinfo = tzlocal()  # ΠœΠ΅ΡΡ‚Π½Ρ‹ΠΉ часовой пояс
tz3: tzinfo = gettz()  # ΠœΠ΅ΡΡ‚Π½Ρ‹ΠΉ часовой пояс

tz4: tzinfo = gettz("America/Chicago")  # Или, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, "Asia/Kolkata". ΠŸΠΎΠ»Π½Ρ‹ΠΉ список: en.wikipedia.org/wiki/List_of_tz_database_time_zones

local_dt = datetime.today()
utc_dt = local_dt.astimezone(UTC)  # ΠšΠΎΠ½Π²Π΅Ρ€Ρ‚Π°Ρ†ΠΈΡ мСстного часового пояса Π² часовой пояс UTC

print (f"{tz1}\n {tz2}\n {tz3}\n {tz4}\n {local_dt}\n {utc_dt}")
tzutc()
 tzlocal()
 tzlocal()
 tzfile('US/Central')
 2022-09-27 09:19:35.399362
 2022-09-27 04:19:35.399362+00:00

НСбольшоС отступлСниС

Позволю сСбС ΠΊΡ€ΠΎΡˆΠ΅Ρ‡Π½ΡƒΡŽ Ρ€Π΅ΠΌΠ°Ρ€ΠΊΡƒ, которая Π±Ρ‹Π»Π° Π±Ρ‹ нСсколько нСумСстна Π½ΠΈ Π² Π½Π°Ρ‡Π°Π»Π΅ ΡΡ‚Π°Ρ‚ΡŒΠΈ (ΠΊΠΎΠ³Π΄Π° Π²Ρ‹ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ взвСшивали Π΅Ρ‘ ΠΏΠΎΠ»Π΅Π·Π½ΠΎΡΡ‚ΡŒ) Π½ΠΈ, Ρ‚Π΅ΠΌ Π±ΠΎΠ»Π΅Π΅, Π² ΠΊΠΎΠ½Ρ†Π΅ (Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π½Π΅ ΠΏΠΎΡ€Ρ‚ΠΈΡ‚ΡŒ послСвкусия). Π Π°Π· ΡƒΠΆ Π²Ρ‹, ΠΏΡ€ΠΎΡ‡ΠΈΡ‚Π°Π² довольно Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ кусок этого ΠΌΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π»Π°, нСвольно Π²Π΅Ρ€ΠΈΡ„ΠΈΡ†ΠΈΡ€ΠΎΠ²Π°Π»ΠΈ сСбя ΠΊΠ°ΠΊ ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²ΠΈΡ‚Π΅Π»ΡŒ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½ΠΎΠΉ индустрии, ΠΏΡ€ΠΈΡ‡Ρ‘ΠΌ, ΠΊΠ°ΠΊ спСциалиста, нСпосрСдствСнно Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‰Π΅Π³ΠΎ с ΠΊΠΎΠ΄ΠΎΠΌ, Ρ‚ΠΎ, ΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ, Π΅ΡΡ‚ΡŒ нСкоторая нСнулСвая Π²Π΅Ρ€ΠΎΡΡ‚Π½ΠΎΡΡ‚ΡŒ Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ Π²Ρ‹ ΠΈΡ‰Π΅Ρ‚Π΅ Π½ΠΎΠ²ΠΎΠ³ΠΎ сотрудника. Π”Π΅Π»ΠΎ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ я, Π°Π²Ρ‚ΠΎΡ€ этой ΡΡ‚Π°Ρ‚ΡŒΠΈ, ΠΈΡ‰Ρƒ Π½ΠΎΠ²ΡƒΡŽ Ρ€Π°Π±ΠΎΡ‚Ρƒ, ΠΈ Ссли Π²Π°ΠΌ Π½ΡƒΠΆΠ΅Π½ middle backend Python-программист, Ρ‚ΠΎ, Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, вас заинтСрСсуСт моя ΠΊΠ°Π½Π΄ΠΈΠ΄Π°Ρ‚ΡƒΡ€Π°.

Π‘ΠΎΠ»ΡŒΡˆΡƒΡŽ Ρ‡Π°ΡΡ‚ΡŒ своСй осмыслСнной ΠΆΠΈΠ·Π½ΠΈ я Ρ€Π°Π·Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π» встроСнныС устройства Π½Π° Π±Π°Π·Π΅ ΠΌΠΈΠΊΡ€ΠΎΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€ΠΎΠ², 50/50 занимаясь схСмотСхникой ΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ. МоСй послСднСй «ТСлСзячной» Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΎΠΉ стал двадцатипятигигабитный ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚ΠΈΠ·Π°Ρ‚ΠΎΡ€ Π½Π° Π±Π°Π·Π΅ ΡˆΠ΅ΡΡ‚Π½Π°Π΄Ρ†Π°Ρ‚ΠΈΡΠ΄Π΅Ρ€Π½ΠΎΠ³ΠΎ процСссора (Π·Π²ΡƒΡ‡ΠΈΡ‚ ΠΊΠ°ΠΊ Π·Π°ΠΊΠ»ΠΈΠ½Π°Π½ΠΈΠ΅ ΠΈΠ· Β«Π“Π°Ρ€Ρ€ΠΈ ΠŸΠΎΡ‚Ρ‚Π΅Ρ€Π°Β» :), Ρ‡Ρ‚ΠΎ ΠΏΠΎ слоТности ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½ΠΎ соотвСтствуСт матСринской ΠΏΠ»Π°Ρ‚Π΅ ΠΏΠ΅Ρ€ΡΠΎΠ½Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ ΠΊΠΎΠΌΠΏΡŒΡŽΡ‚Π΅Ρ€Π°, послС Ρ‡Π΅Π³ΠΎ я ΠΏΠ΅Ρ€Π΅ΡˆΠ΅Π» Π² чистыС программисты. Π”ΠΎ этого Π² основном Ρ€Π°Π±ΠΎΡ‚Π°Π» с ассСмблСром, C ΠΈ C#, Π° Π½Π° Π±Π°Π·Π΅ своих Π·Π°ΠΌΠ΅Ρ‚ΠΎΠΊ ΠΏΠΎ вновь ΠΈΠ·ΡƒΡ‡Π°Π΅ΠΌΠΎΠΌΡƒ Python я ΠΈ написал эту ΡΡ‚Π°Ρ‚ΡŒΡŽ. На ΠΌΠΎΠΉ взгляд, достаточно Π»ΠΎΠ³ΠΈΡ‡Π½ΠΎ сразу ΠΎΠ·Π²ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΏΠΎΡ‚Π΅Π½Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎΠΌΡƒ Ρ€Π°Π±ΠΎΡ‚ΠΎΠ΄Π°Ρ‚Π΅Π»ΡŽ свой ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½Ρ‹ΠΉ ΠΏΡ€ΠΎΡ„Π΅ΡΡΠΈΠΎΠ½Π°Π»ΡŒΠ½Ρ‹ΠΉ ΡƒΡ€ΠΎΠ²Π΅Π½ΡŒ; Π·Π°Π²Π°Π»ΠΈΡ‚ΡŒ собСсСдованиС я Π½Π΅ боюсь (всё Ρ€Π°Π²Π½ΠΎ ΠΏΡ€ΠΎΡ„ΠΈΡ‚, ΠΏΠΎΠΎΠ±Ρ‰Π°ΡŽΡΡŒ с ΡƒΠΌΠ½Ρ‹ΠΌΠΈ людьми), Π° Π²ΠΎΡ‚ понимания своСго нСсоотвСтствия Π·Π°Π½ΠΈΠΌΠ°Π΅ΠΌΠΎΠΉ долТности, выявлСнного Π² Ρ‚Π΅Ρ‡Π΅Π½ΠΈΠΈ ΠΈΡΠΏΡ‹Ρ‚Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ срока, Ρ…ΠΎΡ‚Π΅Π»ΠΎΡΡŒ Π±Ρ‹ ΠΈΠ·Π±Π΅ΠΆΠ°Ρ‚ΡŒ.

БобствСнно, Π²ΠΎΡ‚ всё, Ρ‡Ρ‚ΠΎ я Ρ…ΠΎΡ‚Π΅Π» Π±Ρ‹ Π²Π°ΠΌ ΡΠΎΠΎΠ±Ρ‰ΠΈΡ‚ΡŒ: ΠΌΠΎΡ‘ Ρ€Π΅Π·ΡŽΠΌΠ΅, Github, Π΅ΠΌΠ΅ΠΉΠ» [email protected] ΠΈ Ρ‚Π΅Π»Π΅Ρ„ΠΎΠ½ 8 917 809-89-81 (Π»ΡƒΡ‡ΡˆΠ΅ ΠΏΠΈΡˆΠΈΡ‚Π΅ Π² Telegram ΠΈΠ»ΠΈ WhatsApp).

А Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ Π΄Π°Π²Π°ΠΉΡ‚Π΅ вСрнёмся Π² основноС русло нашСго повСствования.

2. ΠžΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Π΄Π°Π½Π½Ρ‹Ρ…

Β«ΠžΠ³Π½Π΅Π½Π½Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ, ΠΏΠΎΠ΄Π½ΠΈΠΌΠ°ΡŽΡ‰ΠΈΠΉΡΡ ΠΏΠΎΠ΄ΠΎΠ±Π½ΠΎ ΠΏΠ»Π°ΠΌΠ΅Π½ΠΈ ΠΎΡ‚ Π·Π΅ΠΌΠ»ΠΈ Π΄ΠΎ Π½Π΅Π±Π°, опоясывал пространство Π²Π΅Π»ΠΈΡ‡ΠΈΠ½ΠΎΡŽ с малСнький остров».

Β«Π˜ΡΡ‚ΠΎΡ€ΠΈΡ ΠΎ Π΄ΠΎΠΊΡ‚ΠΎΡ€Π΅ ИоганнС ЀаустС, Π·Π½Π°ΠΌΠ΅Π½ΠΈΡ‚ΠΎΠΌ Ρ‡Π°Ρ€ΠΎΠ΄Π΅Π΅ ΠΈ Ρ‡Π΅Ρ€Π½ΠΎΠΊΠ½ΠΈΠΆΠ½ΠΈΠΊΠ΅Β».

Data management

Π‘Ρ€Π΅Π· (slice)

Π‘Π°ΠΌΡ‹ΠΉ простой ΠΌΠ΅Ρ‚ΠΎΠ΄ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ Π΄Π°Π½Π½Ρ‹Ρ…, просто Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Ρ‚Ρƒ Ρ‡Π°ΡΡ‚ΡŒ Π΄Π°Π½Π½Ρ‹Ρ…, мСстополоТСниС ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ (индСксы) удовлСтворяСт ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹ΠΌ условиям.

a:str = "Pack my box with five dozen liquor jugs"

start, stop = 8, 21

b:str = a[start:stop]  # ЗначСния ΠΎΡ‚ start Π΄ΠΎ stop-1
c:str = a[start:]  # ЗначСния ΠΎΡ‚ start Π΄ΠΎ ΠΊΠΎΠ½Ρ†Π° структуры
d:str = a[:stop]  # ЗначСния ΠΎΡ‚ Π½Π°Ρ‡Π°Π»Π° Π΄ΠΎ stop-1
e:str = a[:]  # Полная копия структуры

print(b, "\n",
      c, "\n",
      d, "\n",
      e, "\n")
box with five 
 box with five dozen liquor jugs 
 Pack my box with five 
 Pack my box with five dozen liquor jugs 

ЗначСния start ΠΈ stop ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ ΠΎΡ‚Ρ€ΠΈΡ†Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌΠΈ, это Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΠ·Π½Π°Ρ‡Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ отсчСт вСдСтся ΠΎΡ‚ ΠΊΠΎΠ½Ρ†Π° структуры. МоТно Ρ‚Π°ΠΊΠΆΠ΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ step, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π½Π° Π²Ρ‹Ρ…ΠΎΠ΄ срСза ΠΏΠΎΠΏΠ°Π»ΠΈ Π½Π΅ всС подряд Π΄Π°Π½Π½Ρ‹Π΅ ΠΈΠ· Π²Ρ…ΠΎΠ΄Π½ΠΎΠΉ структуры.

a:str = "Step on no pets"

b:str = a[-4:]  # Β«Π₯востик»
c:str = a[::-1]  # РСвСрс Π²Ρ…ΠΎΠ΄Π½ΠΎΠΉ строки
d:str = a[4::-1]  # ΠŸΠ΅Ρ€Π²Ρ‹Π΅ Ρ‡Π΅Ρ‚Ρ‹Ρ€Π΅ значСния, рСвСрсированы
e:str = a[::2]  # ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ Π²Ρ‚ΠΎΡ€ΠΎΠΉ символ

print(b, "\n",
      c, "\n",
      d, "\n",
      e, "\n")
pets 
 step on no petS 
  petS 
 Se nn es 

Π‘ΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²ΠΊΠ° (sort, sorted)

Π’ сортировкС всё самоС интСрСсноС спрятано ΠΏΠΎΠ΄ ΠΊΠ°ΠΏΠΎΡ‚ΠΎΠΌ (ΠΌΡ‹ Π½Π΅Π½Π°Π΄ΠΎΠ»Π³ΠΎ вСрнСмся ΠΊ этой Ρ‚Π΅ΠΌΠ΅ Ρ‡ΡƒΡ‚ΡŒ Π½ΠΈΠΆΠ΅, Π² Ρ€Π°Π·Π΄Π΅Π»Π΅ «Алгоритмы»), ΠΏΠΎΠΊΠ° рассмотрим Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Python-спСцифичный синтаксис.
Надо Ρ€Π°Π·Π»ΠΈΡ‡Π°Ρ‚ΡŒ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ sort() ΠΈ sorted(), ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ сортируСт Π΄Π°Π½Π½Ρ‹Π΅ in-place, Π²Ρ‚ΠΎΡ€ΠΎΠΉ ΠΏΠΎΡ€ΠΎΠΆΠ΄Π°Π΅Ρ‚ Π½ΠΎΠ²ΡƒΡŽ структуру.

a: list = [5, 2, 3, 1, 4]

b: list = sorted(a)
print(a, b)

a.sort()
print(a)
[5, 2, 3, 1, 4] [1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]

И sort(), ΠΈ sorted() ΠΈΠΌΠ΅ΡŽΡ‚ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ key для указания Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, которая Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒΡΡ Π½Π° ΠΊΠ°ΠΆΠ΄ΠΎΠΌ элСмСнтС. Если Π²Π°ΠΌ большС ΠΏΠΎ Π½Ρ€Π°Π²Ρƒ сортировка ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°ΡŽΡ‰Π΅ΠΉ Π΄Π²Π° Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π° (ΠΈΠ»ΠΈ Π²Ρ‹ ΠΏΡ€ΠΈΠ²Ρ‹ΠΊΠ»ΠΈ ΠΊ cmp Π² Python 2), ΠΏΡ€ΠΈΡΠΌΠΎΡ‚Ρ€ΠΈΡ‚Π΅ΡΡŒ ΠΊ functools.cmp_to_key().

# РСгистрозависимоС сравнСниС строк

dinos: str = "Dinosaurs were Big and small"
a = sorted(dinos.split())
print(a)

# РСгистронСзависимоС сравнСниС строк

dinos: str = "Dinosaurs were Big and small"
b = sorted(dinos.split(), key=str.lower)
print(b)
['Big', 'Dinosaurs', 'and', 'small', 'were']
['and', 'Big', 'Dinosaurs', 'small', 'were']

БлоТносочинСнныС структуры Π΄Π°Π½Π½Ρ‹Ρ… ΠΌΠΎΠΆΠ½ΠΎ ΡΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΠΎ key=lambda el: el[1] ΠΈΠ»ΠΈ Π΄Π°ΠΆΠ΅, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΏΠΎ key=lambda el: (el[1], el[0]).

Comprehension

Comprehension, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ пСрСводится Ρ‚ΠΎ ΠΊΠ°ΠΊ Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ Π² список, Ρ‚ΠΎ ΠΊΠ°ΠΊ абстракция списков (ВикипСдия), Ρ‚ΠΎ Π²ΠΎΠΎΠ±Ρ‰Π΅ Π½ΠΈΠΊΠ°ΠΊ Π½Π΅ пСрСводится β€” способ ΠΊΠΎΠΌΠΏΠ°ΠΊΡ‚Π½ΠΎΠ³ΠΎ описания ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ списков (Π° ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΠΊ Python β€” Π΅Ρ‰Π΅ ΠΈ словарСй, ΠΈ мноТСств).

ΠŸΡ€ΠΎΡ‰Π΅ говоря, Ссли Π²Π°ΠΌ Π½ΡƒΠΆΠ½ΠΎ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΈΠ· списка Π΄Ρ€ΡƒΠ³ΠΎΠΉ список, Π²ΠΊΠ»ΡŽΡ‡Π°ΡŽΡ‰ΠΈΠΉ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‚Π΅ значСния, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΡƒΠ΄ΠΎΠ²Π»Π΅Ρ‚Π²ΠΎΡ€ΡΡŽΡ‚ ΠΊΠ°ΠΊΠΎΠΌΡƒ-Ρ‚ΠΎ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠΌΡƒ ΡƒΡΠ»ΠΎΠ²ΠΈΡŽ, ΠΈΠ»ΠΈ вычисляСмыС ΠΈΠ· ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ списка ΠΏΠΎ ΠΊΠ°ΠΊΠΈΠΌ-Ρ‚ΠΎ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹ΠΌ ΠΏΡ€Π°Π²ΠΈΠ»Π°ΠΌ, Ρ‚ΠΎ comprehension β€” ΠΏΡ€Π΅Ρ‚Π΅Π½Π΄Π΅Π½Ρ‚ Π½Π° Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ этой Π·Π°Π΄Π°Ρ‡ΠΈ β„– 1.

# ΠŸΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ Comprehension

a = [i+1 for i in range(10)]  # list
b  = {i for i in range(10) if i > 5}  # set
c = (2*i+5 for i in range(10))  # iter
d = {i: i**2 for i in range(10)}  # dict

print(a,"\n", b, "\n", list(c), "\n", d)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 
 {8, 9, 6, 7} 
 [5, 7, 9, 11, 13, 15, 17, 19, 21, 23] 
 {0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}

Π’ΡƒΡ‚ Π³Π»Π°Π²Π½ΠΎΠ΅ Π½Π΅ ΠΏΠ΅Ρ€Π΅Π³Π½ΡƒΡ‚ΡŒ ΠΏΠ°Π»ΠΊΡƒ. Если запись comprehension становится слишком слоТной ΠΈ Π½Π΅Ρ‡ΠΈΡ‚Π°Π΅ΠΌΠΎΠΉ, Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, стоит Ρ€Π°Π·Π²Π΅Ρ€Π½ΡƒΡ‚ΡŒ Π»ΠΎΠ³ΠΈΠΊΡƒ Π² Β«Π½ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΉΒ» Ρ†ΠΈΠΊΠ» ΠΈΠ»ΠΈ Π² Π΄Ρ€ΡƒΠ³ΠΎΠΉ Π±ΠΎΠ»Π΅Π΅ ΡƒΠ΄ΠΎΠ±ΠΎΡ‡ΠΈΡ‚Π°Π΅ΠΌΡ‹ΠΉ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ. Comprehension соблазняСт Π·Π°ΠΏΠΈΡΡ‹Π²Π°Ρ‚ΡŒ «однострочниками» достаточно слоТныС выраТСния, Π½ΠΎ Π½Π΅ Π·Π°Π±Ρ‹Π²Π°ΠΉΡ‚Π΅, Ρ‡Ρ‚ΠΎ программист ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½ΠΎ 90 % Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ Ρ‡ΠΈΡ‚Π°Π΅Ρ‚ ΠΊΠΎΠ΄, ΠΈ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ 10 % ΠΏΠΈΡˆΠ΅Ρ‚, Ρ‚Π°ΠΊ Ρ‡Ρ‚ΠΎ Ссли Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΠ»ΠΎΡ…ΠΎΡ‡ΠΈΡ‚Π°Π΅ΠΌΡ‹ΠΌ, Π²Ρ‹ услоТнитС Тизнь ΠΈ сСбС, ΠΈ свои ΠΊΠΎΠ»Π»Π΅Π³Π°ΠΌ.

Π•ΡΡ‚ΡŒ Π±ΠΎΠ»Π΅Π΅-ΠΌΠ΅Π½Π΅Π΅ ΡƒΠ΄Π°Ρ‡Π½Ρ‹Π΅ «однострочники», Π΅ΡΡ‚ΡŒ быстрыС, Π½ΠΎ ΠΏΠ»ΠΎΡ…ΠΎΡ‡ΠΈΡ‚Π°Π΅ΠΌΡ‹Π΅, написанныС ΠΈΠ· спортивного интСрСса (это ссылки Π½Π° Ρ€Π΅ΡˆΠ΅Π½Π½Ρ‹Π΅ ΠΌΠ½ΠΎΠΉ Π·Π°Π΄Π°Ρ‡ΠΊΠΈ Π½Π° leetcode), ΠΆΠ΅Π»Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ comprehension Π² ΠΌΠ΅Ρ€Ρƒ; Π»ΡƒΡ‡ΡˆΠ΅ Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ понятный Ρ€Π°Π·Π²Π΅Ρ€Π½ΡƒΡ‚Ρ‹ΠΉ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ, Ρ‡Π΅ΠΌ нСпонятный, Π½ΠΎ ΠΎΠ±Π»ΠΎΠΆΠ΅Π½Π½Ρ‹ΠΉ пояснСниями (Ссли Π½Π΅Ρ‚ особых Ρ‚Ρ€Π΅Π±ΠΎΠ²Π°Π½ΠΈΠΉ ΠΊ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ, само собой).

Π•Ρ‰Π΅ Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ ΠΏΡ€ΠΎ list comprehension:

# new_list = [expression for member in iterable (if conditional)]

fruits: list = ["Lemon", "Apple", "Banana", "Kiwi", "Watermelon", "Pear"]

e_fruits = [fruit for fruit in fruits if "e" in fruit]
#                                     ☝ условиС
print(e_fruits)

upper_fruits = [fruit.upper() for fruit in fruits]
#                     ☝ Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅
print(upper_fruits)

# ΠŸΡ€ΠΈΠΌΠ΅Ρ€ разбиСния списка Π½Π° Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚Ρ‹ ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²ΠΎΠΉ Π΄Π»ΠΈΠ½Ρ‹
chunk_len = 2
chunk_fruits = [fruits[i:i + chunk_len] for i in range(0, len(fruits), chunk_len)]
print(chunk_fruits)
['Lemon', 'Apple', 'Watermelon', 'Pear']
['LEMON', 'APPLE', 'BANANA', 'KIWI', 'WATERMELON', 'PEAR']
[['Lemon', 'Apple'], ['Banana', 'Kiwi'], ['Watermelon', 'Pear']]

Dict comprehension, Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ Π² ΡΠ»ΠΎΠ²Π°Ρ€ΡŒ:

# new_dict = {expression for member in iterable (if conditional)}

d: dict = {"Italy": "Pizza", "US": "Hot-Dog", "China": "Dim Sum", "South Korea": "Kimchi"}
print(d)

a: dict = {k: v for k, v in d.items() if "i" in v}  # Π’Π΅Ρ€Π½Π΅Ρ‚ Π½ΠΎΠ²Ρ‹ΠΉ ΡΠ»ΠΎΠ²Π°Ρ€ΡŒ, ΠΎΡ‚Ρ„ΠΈΠ»ΡŒΡ‚Ρ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ ΠΏΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ
print(a)

b: dict = {k: v for k, v in d.items() if "i" in k}  # Π’Π΅Ρ€Π½Π΅Ρ‚ Π½ΠΎΠ²Ρ‹ΠΉ ΡΠ»ΠΎΠ²Π°Ρ€ΡŒ, ΠΎΡ‚Ρ„ΠΈΠ»ΡŒΡ‚Ρ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ ΠΏΠΎ ΠΊΠ»ΡŽΡ‡Ρƒ
print(b)

c: dict = {k: v for k, v in d.items() if len(v) >= 7}  # Π’Π΅Ρ€Π½Π΅Ρ‚ Π½ΠΎΠ²Ρ‹ΠΉ ΡΠ»ΠΎΠ²Π°Ρ€ΡŒ, ΠΎΡ‚Ρ„ΠΈΠ»ΡŒΡ‚Ρ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ ΠΏΠΎ Π΄Π»ΠΈΠ½Π΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ
print(c)
{'Italy': 'Pizza', 'US': 'Hot-Dog', 'China': 'Dim Sum', 'South Korea': 'Kimchi'}
{'Italy': 'Pizza', 'China': 'Dim Sum', 'South Korea': 'Kimchi'}
{'China': 'Dim Sum'}
{'US': 'Hot-Dog', 'China': 'Dim Sum'}

ΠŸΠΎΠΏΡ€ΠΎΠ±ΡƒΠΉΡ‚Π΅ ΡΠ°ΠΌΠΎΡΡ‚ΠΎΡΡ‚Π΅Π»ΡŒΠ½ΠΎ ΠΏΠΎΠΈΠ³Ρ€Π°Ρ‚ΡŒΡΡ с set comprehension. НС Π·Π°Π±Ρ‹Π²Π°ΠΉΡ‚Π΅, Ρ‡Ρ‚ΠΎ set Β«ΠΏΠ΅Ρ€Π΅Π²Π°Ρ€ΠΈΠ²Π°Π΅Ρ‚Β» Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΡƒΠ½ΠΈΠΊΠ°Π»ΡŒΠ½Ρ‹Π΅ значСния, поэтому Π² Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ Π½Π΅ совсСм Ρ‚ΠΎ, Π½Π° Ρ‡Ρ‚ΠΎ рассчитывали.

ΠŸΠΎΠΏΡ€ΠΎΠ±ΡƒΠΉΡ‚Π΅ Ρ‚Π°ΠΊΠΆΠ΅ ΠΎΡΠ²ΠΎΠΈΡ‚ΡŒ nested (Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹ΠΉ) comprehension, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ конструкции Π²ΠΈΠ΄Π° [[func(y) for y in x] for x in n]. Для ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° создайтС Π΄Π²ΡƒΠΌΠ΅Ρ€Π½Ρ‹ΠΉ массив, содСрТащий случайныС значСния, срСднСС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… ΠΏΠ»Π°Π²Π½ΠΎ нарастаСт Π±Π»ΠΈΠΆΠ΅ ΠΊ ΠΏΡ€Π°Π²ΠΎΠΌΡƒ Π½ΠΈΠΆΠ½Π΅ΠΌΡƒ ΡƒΠ³Π»Ρƒ (Ссли Π½Π΅ получится, Π³ΠΎΡ‚ΠΎΠ²Ρ‹ΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Π΅ΡΡ‚ΡŒ Ρ‡ΡƒΡ‚ΡŒ Π½ΠΈΠΆΠ΅, Π² ΠΊΠΎΠ΄Π΅, ΠΈΠ»Π»ΡŽΡΡ‚Ρ€ΠΈΡ€ΡƒΡŽΡ‰Π΅ΠΌ ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ matplotlib).

ΠžΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ Π½Π°Π΄ строками. lower(), upper(), capitalize() ΠΈ title()

s: str = "camelCase string"

print(s.lower())
print(s.upper())
print(s.capitalize())
print(s.title())
camelcase string
CAMELCASE STRING
Camelcase string
Camelcase String

strip()

s: str = "  ~~##A big blahblahblah##~~  "

s = s.strip()  # Strips all whitespace characters from both ends
print(s)

s = s.strip("~#")  # Strips all passed characters from both ends
print(s)

s = s.lstrip(" A")  # Strips all passed characters from left end
print(s)

s = s.rstrip("habl")  # Strips all passed characters from right end
print(s)
~~##A big blahblahblah##~~
A big blahblahblah
big blahblahblah
big 

split()

s1: str = "Follow the white rabbit, Neo"

c1 = s1.split()  # Splits on one or more whitespace characters
print(c1)

c2 = s1.split(sep=", ", maxsplit=1)  # Splits on "sep" str at most "maxsplit" times
print(c2)

s2: str = "Beware the Jabberwock, my son!\n The jaws that bite, the claws that catch!"

c3 = s2.splitlines(keepends=False)  # On [\n\r\f\v\x1c-\x1e\x85\u2028\u2029] and \r\n.
print(c3)

# split() vs rsplit()

c4 = s2.split(maxsplit=2)
c5 = s2.rsplit(maxsplit=2)

print(c4, c5)
['Follow', 'the', 'white', 'rabbit,', 'Neo']
['Follow the white rabbit', 'Neo']
['Beware the Jabberwock, my son!', ' The jaws that bite, the claws that catch!']
['Beware', 'the', 'Jabberwock, my son!\n The jaws that bite, the claws that catch!'] ['Beware the Jabberwock, my son!\n The jaws that bite, the claws', 'that', 'catch!']

ord(), chr()

s1: str = "abcABC!"

for ch in s1:
    print(f"{ch} -> {ord(ch)}")  # Returns an integer representing the Unicode character

nums = [72, 101, 108, 108, 111, 33]

for num in nums:
    print(f"{num} -> {chr(num)}")
a -> 97
b -> 98
c -> 99
A -> 65
B -> 66
C -> 67
! -> 33
72 -> H
101 -> e
108 -> l
108 -> l
111 -> o
33 -> !

Regex

РСгулярныС выраТСния β€” ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Π°Ρ ΠΎΠ±Π»Π°ΡΡ‚ΡŒ Π·Π½Π°Π½ΠΈΠΉ, ΠΈ вСсьма-вСсьма нСпростая ΠΎΠ±Π»Π°ΡΡ‚ΡŒ. Π’ΡƒΡ‚, ΠΏΠΎΠΆΠ°Π»ΡƒΠΉ, самоС врСмя для Π±ΠΎΡ€ΠΎΠ΄Π°Ρ‚ΠΎΠΉ ΡˆΡƒΡ‚ΠΊΠΈ ΠΏΡ€ΠΎ Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ Ссли Π²Ρ‹ Ρ€Π΅ΡˆΠΈΠ»ΠΈ свою ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡƒ ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ рСгулярных Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ β€” Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ Ρƒ вас Π΄Π²Π΅ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹.

РСгулярки ΠΏΠΎΡ…ΠΎΠΆΠΈ Π½Π° Π²Ρ…ΠΎΠΆΠ΄Π΅Π½ΠΈΠ΅ Π² Π²ΠΎΠ΄Ρƒ Π½Π° пляТС острова Π“ΡƒΠ°ΠΌ Π² сторону ΠœΠ°Ρ€ΠΈΠ°Π½ΡΠΊΠΎΠΉ Π²ΠΏΠ°Π΄ΠΈΠ½Ρ‹ β€” Π΄Π°ΠΆΠ΅ ΠΊΠΎΠ³Π΄Π° Π²Ρ‹ Π΄ΡƒΠΌΠ°Π΅Ρ‚Π΅, Ρ‡Ρ‚ΠΎ ΠΏΠΎΠ³Ρ€ΡƒΠ·ΠΈΠ»ΠΈΡΡŒ Ρ€Π΅Π°Π»ΡŒΠ½ΠΎ Π³Π»ΡƒΠ±ΠΎΠΊΠΎ, Ρ‚ΠΎ, скорСС всСго, Π²Ρ‹ просто Π½Π΅ Π²ΠΈΠ΄ΠΈΡ‚Π΅ Π²ΠΏΠ΅Ρ€Π΅Π΄ΠΈΠ»Π΅ΠΆΠ°Ρ‰Π΅ΠΉ Π±Π΅Π·Π΄Π½Ρ‹. Но β€” Π·Π½Π°Ρ‚ΡŒ рСгулярныС выраТСния, хотя Π±Ρ‹ Π½Π° Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎΠΌ ΡƒΡ€ΠΎΠ²Π½Π΅, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ для Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ Ρ†Π΅Π»ΠΎΠ³ΠΎ класса Π·Π°Π΄Π°Ρ‡, Π° Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ Π²Ρ‘Ρ€Ρ‚ΠΊΠΈΠ΅ рСгулярки пСриодичСски ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°ΡŽΡ‚ΡΡ ΠΊ Π²Π°ΠΌ своими, ΠΊΡ…ΠΌ... Π½ΠΎΠ²Ρ‹ΠΌΠΈ гранями, придСтся ΠΏΡ€ΠΎΡΡ‚ΠΈΡ‚ΡŒ, ΠΏΠ΅Ρ€Π΅Π²Π°Ρ€ΠΈΡ‚ΡŒ ΠΈ ΠΏΡ€ΠΈΠ½ΡΡ‚ΡŒ.

Π’ΠΎΡ‚ здСсь Π΅ΡΡ‚ΡŒ Π³Ρ€Π°ΠΌΠΎΡ‚Π½ΠΎΠ΅ ΠΈ мСтодичСски Π²Ρ‹Π΄Π΅Ρ€ΠΆΠ°Π½Π½ΠΎΠ΅ Π²Π²Π΅Π΄Π΅Π½ΠΈΠ΅ Π² Ρ‚Π΅ΠΌΡƒ, ΠΏΠΎΠΊΠ° ΠΆΠ΅ ΠΎΠΊΠΈΠ½Π΅ΠΌ взглядом основныС возмоТности рСгулярных Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ:

import re

s1: str = "123 abc ABC 456"

m1 = re.search("[aA]", s1)  # Π˜Ρ‰Π΅Ρ‚ ΠΏΠ΅Ρ€Π²ΠΎΠ΅ Π²Ρ…ΠΎΠΆΠ΄Π΅Π½ΠΈΠ΅ ΠΏΠ°Ρ‚Ρ‚Π΅Ρ€Π½Π°, ΠΏΡ€ΠΈ Π½Π΅ΡƒΠ΄Π°Ρ‡Π΅ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ None
print(m1, m1.group(0))

m2 = re.fullmatch("[aA]", s1)  # ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ°, ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΈΡ‚ Π»ΠΈ строка ΠΏΠΎΠ΄ шаблон
print(m2)

c1: list = re.findall("[aA]", s1)  # Найти Π² строкС всС Π½Π΅ΠΏΠ΅Ρ€Π΅ΡΠ΅ΠΊΠ°ΡŽΡ‰ΠΈΠ΅ΡΡ ΡˆΠ°Π±Π»ΠΎΠ½Ρ‹
print(c1)

def replacer(s):
    return chr(ord(s[0]) + 1)  # Π‘Π»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ символ ΠΈΠ· Π°Π»Ρ„Π°Π²ΠΈΡ‚Π°

s2 = re.sub("\w", replacer, s1)  # Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ вмСсто шаблона
print(s2)

c2 = re.split("\d", s1)
print(c2)

iter = re.finditer("\D", s1)  # Π˜Ρ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€ ΠΏΠΎ Π½Π΅ΠΏΠ΅Ρ€Π΅ΡΠ΅ΠΊΠ°ΡŽΡ‰ΠΈΠΌΡΡ шаблонам

for ch in iter:
    print(ch.group(0), end= "")
<re.Match object; span=(4, 5), match='a'> a
None
['a', 'A']
234 bcd BCD 567
['', '', '', ' abc ABC ', '', '', '']
 abc ABC 

Match Object

import re

m3 = re.match(r"(\w+) (\w+)", "John Connor, leader of the Resistance")

s3: str = m3.group(0)  # Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΏΠΎΠ»Π½ΠΎΠ΅ совпадСниС
s4: str = m3.group(1)  # Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Ρ‡Π°ΡΡ‚ΡŒ Π² ΠΏΠ΅Ρ€Π²Ρ‹Ρ… скобках
t1: tuple = m3.groups()
start: int = m3.start()  # Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Π½Π°Ρ‡Π°Π»ΡŒΠ½Ρ‹ΠΉ индСкс совпадСния
end: int = m3.end()  # Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΊΠΎΠ½Π΅Ρ‡Π½Ρ‹ΠΉ индСкс совпадСния
t2: tuple[int, int] = m3.span()  # ΠšΠΎΡ€Ρ‚Π΅ΠΆ (start, end)

print (f"{s3}\n {s4}\n {t1}\n {start}\n {end}\n {t2}\n")
John Connor
 John
 ('John', 'Connor')
 0
 11
 (0, 11)

Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… datetime

Python ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ Unix Epoch: "1970-01-01 00:00 UTC"

from datetime import datetime
from dateutil.tz import tzlocal

dt1: datetime = datetime.fromisoformat("2021-10-04 00:05:23.555+00:00")  # ΠœΠΎΠΆΠ΅Ρ‚ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ ValueError
dt2: datetime = datetime.strptime("21/10/04 17:30", "%d/%m/%y %H:%M")   # ΠŸΠΎΠ΄Ρ€ΠΎΠ±Π½Π΅Π΅ ΠΏΡ€ΠΎ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Ρ‹ - https://docs.python.org/3/library/datetime.html#strftime-and-strptime-format-codes
dt3: datetime = datetime.fromordinal(100_000)  # 100000-ΠΉ дСнь ΠΎΡ‚ 1.1.0001
dt4: datetime = datetime.fromtimestamp(20_000_000.01)  # ВрСмя Π² сСкундах с Π½Π°Ρ‡Π°Π»Π° Unix Epoch

tz = tzlocal()
dt5: datetime = datetime.fromtimestamp(20_000_000.01, tz)  # Π‘ ΡƒΡ‡Π΅Ρ‚ΠΎΠΌ часового пояса

print (f"{dt1}\n {dt2}\n {dt3}\n {dt4}\n {dt5}")
2021-10-04 00:05:23.555000+00:00
 2004-10-21 17:30:00
 0274-10-16 00:00:00
 1970-08-20 16:33:20.010000
 1970-08-20 16:33:20.010000+05:00

ΠŸΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… datetime

from datetime import datetime

dt1: datetime = datetime.today()

s1: str = dt1.isoformat()
s2: str = dt1.strftime("%d/%m/%y %H:%M")  # https://docs.python.org/3/library/datetime.html#strftime-and-strptime-format-codes
i: int = dt1.toordinal()
a: float = dt1.timestamp()  # Π‘Π΅ΠΊΡƒΠ½Π΄Ρ‹ с Π½Π°Ρ‡Π°Π»Π° Unix Epoch

print (f"{dt1}\n {s1}\n {s2}\n {i}\n {a}")
2022-09-06 17:50:38.041159
 2022-09-06T17:50:38.041159
 06/09/22 17:50
 738404
 1662468638.041159

АрифмСтика datetime

from datetime import date, time, datetime, timedelta
from dateutil.tz import UTC, tzlocal, gettz, datetime_exists, resolve_imaginary

d: date  = date.today()
dt1: datetime = datetime.today()
dt2: datetime = datetime(year=1981, month=12, day=2)
td1: timedelta = timedelta(days=5)
td2: timedelta = timedelta(days=1)

d = d + td1  # date = date Β± timedelta
dt3 = dt1 - td1  # datetime = datetime Β± timedelta

td3 = dt1 - dt2  # timedelta = datetime - datetime

td4 = 10 * td1  # timedelta = const * timedelta
c: float = td1/td2  # timedelta/timedelta

print (f"{d}\n {dt3}\n {td3}\n {td4}\n {c}")
2022-09-11
 2022-09-01 17:50:38.132916
 14888 days, 17:50:38.132916
 50 days, 0:00:00
 5.0

bisect ΠΈ Π±ΠΈΠ½Π°Ρ€Π½Ρ‹ΠΉ поиск

Π‘ΠΈΠ½Π°Ρ€Π½Ρ‹ΠΉ поиск сущСствСнно быстрСС, Ρ‡Π΅ΠΌ ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹ΠΉ (см. Ρ€Π°Π·Π΄Π΅Π» «Алгоритмы»), Π½ΠΎ Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ ΠΏΡ€Π΅Π΄Π²Π°Ρ€ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠΉ сортировки ΠΊΠΎΠ»Π»Π΅ΠΊΡ†ΠΈΠΈ, ΠΏΠΎ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ осущСствляСтся поиск.

import bisect

a: list[int] = [12, 6, 8, 19, 1, 33]

a.sort()
print(f"Sorted: {a}")

print(bisect.bisect(a, 20))  # Найти индСкс для ΠΏΠΎΡ‚Π΅Π½Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎΠΉ вставки

bisect.insort(a, 15)  # Вставка значСния Π² ΠΎΡ‚ΡΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½Π½ΡƒΡŽ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ
print(a)

# Π‘ΠΈΠ½Π°Ρ€Π½Ρ‹ΠΉ поиск

def binary_search(a, x, lo=0, hi=None):
    if hi is None:
        hi = len(a)

    pos = bisect.bisect_left(a, x, lo, hi)
    return pos if pos != hi and a[pos] == x else -1

print(binary_search(a, 15))
Sorted: [1, 6, 8, 12, 19, 33]
5
[1, 6, 8, 12, 15, 19, 33]
4

Π€ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΠ΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ (Map, Filter, Reduce, Partial)

На случай, Ссли начиная с этого ΠΌΠΎΠΌΠ΅Π½Ρ‚Π° ΠΈ Π΄ΠΎ ΠΊΠΎΠ½Ρ†Π° Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π³ΠΎ ΠΆΠΈΠ·Π½Π΅Π½Π½ΠΎΠ³ΠΎ Ρ†ΠΈΠΊΠ»Π° Π²Ρ‹ ΡΠΎΠ±ΠΈΡ€Π°Π΅Ρ‚Π΅ΡΡŒ ΠΊ мСсту ΠΈ Π½Π΅ мСсту ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΡ€ΠΈΡ‘ΠΌΡ‹ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ программирования, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ свой ΠΊΠΎΠ΄ «воистину ΠΊΡ€ΡƒΡ‚Ρ‹ΠΌΒ», просто ΠΏΡ€ΠΎΡ†ΠΈΡ‚ΠΈΡ€ΡƒΡŽ Π²Π°ΠΌ ДТоэля Граса, Π°Π²Ρ‚ΠΎΡ€Π° ΠΊΠ½ΠΈΠ³ΠΈ Β«Data Science: Наука ΠΎ Π΄Π°Π½Π½Ρ‹Ρ… с нуля»: Β«Π’ ΠΏΠ΅Ρ€Π²ΠΎΠΌ ΠΈΠ·Π΄Π°Π½ΠΈΠΈ этой ΠΊΠ½ΠΈΠ³ΠΈ Π±Ρ‹Π»ΠΈ прСдставлСны Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ partial, map, reduce ΠΈ filter языка Python. На своСм ΠΏΡƒΡ‚ΠΈ ΠΊ ΠΏΡ€ΠΎΡΠ²Π΅Ρ‚Π»Π΅Π½ΠΈΡŽ я понял, Ρ‡Ρ‚ΠΎ этих Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ Π»ΡƒΡ‡ΡˆΠ΅ ΠΈΠ·Π±Π΅Π³Π°Ρ‚ΡŒ, ΠΈ ΠΈΡ… использованиС Π² ΠΊΠ½ΠΈΠ³Π΅ Π±Ρ‹Π»ΠΎ Π·Π°ΠΌΠ΅Π½Π΅Π½ΠΎ Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡΠΌΠΈ Π² список, Ρ†ΠΈΠΊΠ»Π°ΠΌΠΈ ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠΌΠΈ, Π±ΠΎΠ»Π΅Π΅ Python'овскими конструкциями». Π’Π°ΠΊΠΈΠ΅ Π΄Π΅Π»Π°...

import functools

# ΠŸΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΡƒΠ΅Ρ‚ всС входящиС значСния ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ
iter1 = map(lambda x: x + 1, range(10))
print(list(iter1))

# ΠŸΠ΅Ρ€Π΅Π΄Π°Π΅Ρ‚ Π² Π²Ρ‹Ρ…ΠΎΠ΄Π½ΠΎΠΉ ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ значСния, ΡƒΠ΄ΠΎΠ²Π»Π΅Ρ‚Π²ΠΎΡ€ΡΡŽΡ‰ΠΈΠ΅ ΡƒΡΠ»ΠΎΠ²ΠΈΡŽ
iter2 = filter(lambda x: x > 5, range(10))
print(list(iter2))

# ΠŸΡ€ΠΈΠΌΠ΅Π½ΡΠ΅Ρ‚ ΡƒΠΊΠ°Π·Π°Π½Π½ΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ ΠΊΠΎ всСй ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ Π²Ρ…ΠΎΠ΄Π½Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ…, сводя ΠΈΡ… ΠΊ СдинствСнному Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ
a = functools.reduce(lambda out, x: out + x, range(10))
print(a)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[6, 7, 8, 9]
45
import functools

def sum(a,b):
    return a + b

add_const = functools.partial(sum, 10)

print(add_const(5))
15

Если Π²Π°ΠΌ Π½Π΅ сразу станСт понятно, ΠΊΠ°ΠΊ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ функция partial (ΠΈ Π·Π°Ρ‡Π΅ΠΌ ΠΎΠ½Π° Π½ΡƒΠΆΠ½Π°), Π½Π΅ Ρ€Π°ΡΡΡ‚Ρ€Π°ΠΈΠ²Π°ΠΉΡ‚Π΅ΡΡŒ, Π²Ρ‹ Π½Π΅ ΠΎΠ΄ΠΈΠ½ΠΎΠΊΠΈ :). Π’ΠΎΡ‚, поТалуйста, Ρ‚Π΅ΠΌΠ° Π½Π° Stackoverflow: Β«I am not able to get my head on how the partial worksΒ». Π’Π°ΠΌ, кстати, Π΅ΡΡ‚ΡŒ совСт, ΠΊΠ°ΠΊ partial ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ ΠΏΠΎΠ»Π΅Π·Π½Ρ‹ ΠΏΡ€ΠΈ ΠΎΡ€Π³Π°Π½ΠΈΠ·Π°Ρ†ΠΈΠΈ pipe с Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ, ΠΈΠΌΠ΅ΡŽΡ‰ΠΈΡ… Ρ€Π°Π·Π½ΠΎΠ΅ количСство Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ².

Any, All

any() Π²Π΅Ρ€Π½Π΅Ρ‚ True, Ссли хотя Π±Ρ‹ ΠΎΠ΄ΠΈΠ½ элСмСнт ΠΈΡ‚Π΅Ρ€ΠΈΡ€ΡƒΠ΅ΠΌΠΎΠΉ ΠΊΠΎΠ»Π»Π΅ΠΊΡ†ΠΈΠΈ истинСн, all() Π²Π΅Ρ€Π½Π΅Ρ‚ True Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π² случаС истинности всСх элСмСнтов ΠΊΠΎΠ»Π»Π΅ΠΊΡ†ΠΈΠΈ.

animals = ["Squirrel", "Beaver", "Fox"]
sentence = "Bison likes squirrels and beavers"

any_animal: bool = any(animal.lower() in sentence.lower() for animal in animals)
print(any_animal)

all_animal: bool = all(animal.lower() in sentence.lower() for animal in animals)
print(all_animal)
True
False

Π€Π°ΠΉΠ»Ρ‹

Π€Π°ΠΉΠ»ΠΎΠ²Ρ‹Π΅ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ стоят Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ особняком ΠΎΡ‚ ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Ρ… ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ Π΄Π°Π½Π½Ρ‹Ρ…, ΠΊΠ°ΠΊ ΠΏΠΎΠ΄Ρ€Π°Π·ΡƒΠΌΠ΅Π²Π°ΡŽΡ‰ΠΈΠ΅ Π½Π΅ ΡΠΈΡŽΠΌΠΈΠ½ΡƒΡ‚Π½ΡƒΡŽ Ρ‚ΠΎΡ€ΠΎΠΏΠ»ΠΈΠ²ΡƒΡŽ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΡƒ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ, Π° взаимодСйствиС с Π½Π΅ΠΊΠΈΠΌ постоянным энСргонСзависимым Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π΅ΠΌ Π΄Π°Π½Π½Ρ‹Ρ…. Π’Π°ΠΊ Ρ‡Ρ‚ΠΎ Ссли Π²Π°ΠΌ Π½ΡƒΠΆΠ½ΠΎ ΡΠΎΡ…Ρ€Π°Π½ΠΈΡ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅ Π½Π° Π·Π°Π²Ρ‚Ρ€Π°, ΠΈΠ»ΠΈ, Π½Π°ΠΎΠ±ΠΎΡ€ΠΎΡ‚, Π½ΡƒΠΆΠ½ΠΎ ΠΏΡ€ΠΎΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π²Π°ΠΌ прСдоставили нСдСлю Π½Π°Π·Π°Π΄, Ρ‚ΠΎ Π²Π°ΠΌ, ΠΎΡ‡Π΅Π²ΠΈΠ΄Π½ΠΎ, Π½ΡƒΠΆΠ½ΠΎ Π±ΡƒΠ΄Π΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ с Ρ„Π°ΠΉΠ»Π°ΠΌΠΈ. Π’ Ρ„Π°ΠΉΠ»Π°Ρ… ΠΆΠ΅ осядСт информация, ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ ΠΌΡ‹ ΠΏΠ΅Ρ€Π΅Π΄Π°Π΅ΠΌ Π±Π°Π·Π°ΠΌ Π΄Π°Π½Π½Ρ‹Ρ…, Π½ΠΎ эту Ρ‚Π΅ΠΌΡƒ ΠΌΡ‹ рассмотри Π½ΠΈΠΆΠ΅.

f = open("f.txt", mode='r', encoding="utf-8", newline=None)

print(f.read())
Hello from file!

На всякий случай, Ссли Π²Ρ‹ испытываСтС программистский Π·ΡƒΠ΄ Π΄Π°ΠΆΠ΅ нСбольшой стСпСни выраТСнности, напоминаю β€” ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ прогоняйтС Π² IDE всС нСпонятныС куски ΠΊΠΎΠ΄Π°, Π½Π΅ Π½Π°Π΄ΠΎ Π½Π° Π½ΠΈΡ… ΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ, ΠΈΡ… Π½Π°Π΄ΠΎ Π²ΠΈΠ΄ΠΎΠΈΠ·ΠΌΠ΅Π½ΡΡ‚ΡŒ, ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ, Π΄ΠΎΡ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Ρ‚ΡŒ; Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΊΠΎΠ³Π΄Π° ΠΊΠΎΠ½Ρ†Ρ‹ свяТутся, Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΊΠΎΠ³Π΄Π° Π²Ρ‹ ΠΏΠΎΠΉΠΌΠ΅Ρ‚Π΅, ΠΊΠ°ΠΊ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½ΠΈΡ€ΡƒΠ΅Ρ‚ этот кусочСк ΠΊΠΎΠ΄Π°, Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‚ΠΎΠ³Π΄Π° ΠΏΡ€ΠΎΠΌΠ΅Π»ΡŒΠΊΠ½Ρ‘Ρ‚ малСнькая искорка ΠΈ ваша квалификация ΠΊΠ°ΠΊ программиста Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ подрастёт.

Π Π΅ΠΆΠΈΠΌΡ‹ (mode):
"r" β€” Ρ‡Ρ‚Π΅Π½ΠΈΠ΅ (ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ)
"w" β€” запись (информация, Ρ€Π°Π½Π΅Π΅ ΠΏΡ€ΠΈΡΡƒΡ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π°Ρ Π² Ρ„Π°ΠΉΠ»Π΅, Π±ΡƒΠ΄Π΅Ρ‚ стёрта)
"x" β€” эксклюзивноС созданиС ΠΈ запись; Ссли Ρ„Π°ΠΉΠ» ΡƒΠΆΠ΅ сущСствуСт, Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹Π±Ρ€ΠΎΡˆΠ΅Π½ΠΎ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ FileExistsError
"a" β€” ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΈΠ΅ с ΠΏΠΎΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ΠΌ Π² ΠΊΠΎΠ½Π΅Ρ† Ρ„Π°ΠΉΠ»Π°
"w+" β€” Ρ‡Ρ‚Π΅Π½ΠΈΠ΅ ΠΈ запись
"r+" β€” Ρ‡Ρ‚Π΅Π½ΠΈΠ΅ ΠΈ запись с Π½Π°Ρ‡Π°Π»Π° Ρ„Π°ΠΉΠ»Π°
"a+" β€” Ρ‡Ρ‚Π΅Π½ΠΈΠ΅ ΠΈ запись с ΠΊΠΎΠ½Ρ†Π° Ρ„Π°ΠΉΠ»Π°
"t" β€” тСкстовый Ρ€Π΅ΠΆΠΈΠΌ ("rt", "wt" ΠΈ Ρ‚. Π΄.; ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ)
"b" β€” Π΄Π²ΠΎΠΈΡ‡Π½Ρ‹ΠΉ Ρ€Π΅ΠΆΠΈΠΌ ("rb", "wb", "xb" ΠΈ Ρ‚. Π΄.)

encoding=None β€” Π±ΡƒΠ΄Π΅Ρ‚ использована ΠΊΠΎΠ΄ΠΈΡ€ΠΎΠ²ΠΊΠ° ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ (зависит ΠΎΡ‚ систСмы, см. getpreferredencoding()). Если Π½Π΅Ρ‚ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½Ρ‹Ρ… Ρ‚Ρ€Π΅Π±ΠΎΠ²Π°Π½ΠΈΠΉ, просто ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ Π²Π΅Π·Π΄Π΅ encoding="utf-8"; Π±Π΅Π· этого, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, русский тСкст Π·Π°ΠΏΠΈΡˆΠ΅Ρ‚ΡΡ Π² тСкстовый Ρ„Π°ΠΉΠ» Π² Π²ΠΈΠ΄Π΅ Ρ‡Π΅Π»ΠΎΠ²Π΅ΠΊΠΎΠ½Π΅Ρ‡ΠΈΡ‚Π°Π΅ΠΌΠΎΠΉ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ.

newline=None β€” ΠΏΡ€ΠΈ Ρ‡Ρ‚Π΅Π½ΠΈΠΈ систСмныС символы ΠΊΠΎΠ½Ρ†Π° строки Π±ΡƒΠ΄ΡƒΡ‚ ΠΊΠΎΠ½Π²Π΅Ρ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½Ρ‹ Π² "\n"; ΠΏΡ€ΠΈ записи, Π½Π°ΠΎΠ±ΠΎΡ€ΠΎΡ‚, "\n" Π±ΡƒΠ΄ΡƒΡ‚ ΠΊΠΎΠ½Π²Π΅Ρ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½Ρ‹ Π² систСмныС символы ΠΊΠΎΠ½Ρ†Π° строки.

Π’ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Π΅ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ ΠΏΡ€ΠΈ Ρ€Π°Π±ΠΎΡ‚Π΅ с Ρ„Π°ΠΉΠ»Π°ΠΌΠΈ:
FileNotFoundError ΠΏΡ€ΠΈ Ρ‡Ρ‚Π΅Π½ΠΈΠΈ Π² Ρ€Π΅ΠΆΠΈΠΌΠ΅ "r" ΠΈΠ»ΠΈ "r+".
FileExistsError ΠΏΡ€ΠΈ записи Π² Ρ€Π΅ΠΆΠΈΠΌΠ΅ "x".
IsADirectoryError, PermissionError β€” Π² любом Ρ€Π΅ΠΆΠΈΠΌΠ΅.

Π§Ρ‚Π΅Π½ΠΈΠ΅ ΠΈΠ· Ρ„Π°ΠΉΠ»Π°

ΠžΡ‚ΠΊΡ€Ρ‹Π²Π°Π΅Ρ‚ Ρ„Π°ΠΉΠ» ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Ρ„Π°ΠΉΠ»ΠΎΠ²Ρ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚.
Для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с Ρ„Π°ΠΉΠ»Π°ΠΌΠΈ Π»ΡƒΡ‡ΡˆΠ΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ€Ρ‹ контСкста (рассмотрСны Π½ΠΈΠΆΠ΅), Ρ‚. Π΅. конструкции Π²ΠΈΠ΄Π° "with open...". Π”Π°ΠΆΠ΅ Ссли Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ ΠΏΠΎΠΉΠ΄Π΅Ρ‚ Π½Π΅ Ρ‚Π°ΠΊ, ΠΊΠ°ΠΊ Π·Π°Π΄ΡƒΠΌΠ°Π½ΠΎ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π²Ρ‹ Π½Π΅ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚Π΅ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ Π²ΠΎ врСмя Ρ€Π°Π±ΠΎΡ‚Ρ‹ с Ρ„Π°ΠΉΠ»ΠΎΠΌ), ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ€ контСкста «зачистит хвосты», ΠΈ ваша ΠΎΠΏΠ»ΠΎΡˆΠ½ΠΎΡΡ‚ΡŒ Π½Π΅ отразится, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π½Π° Ρ„Π°ΠΉΠ»ΠΎΠ²ΠΎΠΉ систСмС.

with open("f.txt", encoding="utf-8") as f:
    chars = f.read(5)  # Reads chars/bytes or until EOF
    print(chars)

    f.seek(0)  # Moves to the start of the file. Also seek(offset) and seek(Β±offset, anchor), where anchor is 0 for start, 1 for current position and 2 for end

    lines: list[str] = f.readlines()  # Also readline()
    print(lines)
Hello
['Hello from file!']

Π—Π°ΠΏΠΈΡΡŒ Π² Ρ„Π°ΠΉΠ»

with open("f.txt", "w", encoding="utf-8") as f:
    f.write("Hello from file!")  # Или f.writelines(<collection>)

JSON

Π§Π΅Π»ΠΎΠ²Π΅ΠΊΠΎΡ‡ΠΈΡ‚Π°Π΅ΠΌΡ‹ΠΉ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ для хранСния ΠΈ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ Π΄Π°Π½Π½Ρ‹Ρ….

import json

d: dict = {1: "Lemon", 2: "Apple", 3: "Banana!"}

object_as_string: str = json.dumps(d, indent=2)
print(object_as_string)

restored_object = json.loads(object_as_string)

# Write object to JSON file
with open("1.json", 'w', encoding='utf-8') as file:
    json.dump(d, file, indent=2)

# Read object from JSON file
with open("1.json", encoding='utf-8') as file:
    restored_from_file = json.load(file)
    
print(restored_from_file)
{
  "1": "Lemon",
  "2": "Apple",
  "3": "Banana!"
}
{'1': 'Lemon', '2': 'Apple', '3': 'Banana!'}

Pickle

Π‘ΠΈΠ½Π°Ρ€Π½Ρ‹ΠΉ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ для хранСния ΠΈ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ Π΄Π°Π½Π½Ρ‹Ρ….

import pickle

d: dict = {1: "Lemon", 2: "Apple", 3: "Banana!"}

# Π—Π°ΠΏΠΈΡΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° Π² Π±ΠΈΠ½Π°Ρ€Π½Ρ‹ΠΉ Ρ„Π°ΠΉΠ»
with open("1.bin", "wb") as file:
    pickle.dump(d, file)

# Π§Ρ‚Π΅Π½ΠΈΠ΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° ΠΈΠ· Ρ„Π°ΠΉΠ»Π°
with open("1.bin", "rb") as file:
    restored_from_file = pickle.load(file)

print(restored_from_file)
{1: 'Lemon', 2: 'Apple', 3: 'Banana!'}

Protocol Buffers

Если Π²Ρ‹ Ρ…ΠΎΡ‚ΠΈΡ‚Π΅ ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Ρ‚ΡŒ ΠΈ Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ ΡƒΠ½ΠΈΠ²Π΅Ρ€ΡΠ°Π»ΡŒΠ½ΡƒΡŽ структуру, ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²ΠΎ Ρ…ΠΎΡ€ΠΎΡˆΠΎ ΠΏΠΎΠ½ΠΈΠΌΠ°Π΅ΠΌΡƒΡŽ всСми языками программирования (ΠΊΠ°ΠΊ JSON) ΠΈ Π·Π°Π½ΠΈΠΌΠ°ΡŽΡ‰ΡƒΡŽ ΠΌΠ°Π»ΠΎ мСста (ΠΊΠ°ΠΊ Pickle), Ρ‚ΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Π² сторону Protocol Buffers (Wikipedia, ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ для Python). Π•ΡΡ‚ΡŒ Π΅Ρ‰Π΅ Π°Π»ΡŒΡ‚Π΅Ρ€Π½Π°Ρ‚ΠΈΠ²Ρ‹, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, FlatBuffers, Apache Avro ΠΈΠ»ΠΈ Thrift.

ΠŸΡƒΡ‚ΠΈ (Paths)

ΠŸΡ€ΠΈ Ρ€Π°Π±ΠΎΡ‚Π΅ с Ρ„Π°ΠΉΠ»Π°ΠΌΠΈ Π½Π΅ ΠΎΠ±ΠΎΠΉΡ‚ΠΈΡΡŒ Π±Π΅Π· манипулирования Ρ„Π°ΠΉΠ»ΠΎΠ²Ρ‹ΠΌΠΈ путями.

from os import getcwd, path, listdir
from pathlib import Path

s1: str = getcwd()  # Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Ρ‚Π΅ΠΊΡƒΡ‰ΡƒΡŽ Ρ€Π°Π±ΠΎΡ‡ΡƒΡŽ Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΡ€ΠΈΡŽ
print(s1)

s2: str = path.abspath("f.txt")  # Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΏΠΎΠ»Π½Ρ‹ΠΉ ΠΏΡƒΡ‚ΡŒ
print(s2)

s3: str = path.basename(s2)  # Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ имя Ρ„Π°ΠΉΠ»Π°
s4: str = path.dirname(s2)  # Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΏΡƒΡ‚ΡŒ Π±Π΅Π· Ρ„Π°ΠΉΠ»Π°
t1: tuple = path.splitext(s2)  # Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΊΠΎΡ€Ρ‚Π΅ΠΆ ΠΈΠ· ΠΏΡƒΡ‚ΠΈ ΠΈ ΠΈΠΌΠ΅Π½ΠΈ Ρ„Π°ΠΉΠ»Π°
print(s3, s4, t1)

p = Path(s2)
st = p.stat()
print(st)

b1: bool = p.exists()
b2: bool = p.is_file()
b3: bool = p.is_dir()
print(b1, b2, b3)

c: list = listdir(path=s1)  # Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ список ΠΈΠΌΠ΅Π½ Ρ„Π°ΠΉΠ»ΠΎΠ², находящихся ΠΏΠΎ ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠΌΡƒ ΠΏΡƒΡ‚ΠΈ
print(c)

s5: str = p.stem  # Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ имя Ρ„Π°ΠΉΠ»Π° Π±Π΅Π· Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡ
s6: str  = p.suffix  # Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΠ΅ Ρ„Π°ΠΉΠ»Π°
t2: tuple = p.parts  # Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ всС элСмСнты ΠΏΡƒΡ‚ΠΈ ΠΊΠ°ΠΊ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Π΅ строки
print(s5, s6, t2)
c:\Works\amaargiru\pycore
c:\Works\amaargiru\pycore\f.txt
f.txt c:\Works\amaargiru\pycore ('c:\\Works\\amaargiru\\pycore\\f', '.txt')
os.stat_result(st_mode=33206, st_ino=2251799814917120, st_dev=3628794147, st_nlink=1, st_uid=0, st_gid=0, st_size=16, st_atime=1662468638, st_mtime=1662468638, st_ctime=1661089564)
True True False
['.git', '.gitignore', '.pytest_cache', '01_python.ipynb', '01_python.md', '02_postgre.md', '03_architecture.md', '04_algorithms.ipynb', '04_algorithms.md', '05_admin_devops.md', '06_pytest_mock.ipynb', '06_pytest_mock.md', '07_fastapi.md', '08_flask.md', '1.bin', '1.json', 'compose_readme.bat', 'coupling_vs_cohesion.svg', 'f.txt', 'gitflow.svg', 'graph_for_dfs.jpg', 'pycallgraph3.png', 'readme.md']
f .txt ('c:\\', 'Works', 'amaargiru', 'pycore', 'f.txt')

ΠŸΡ€ΠΎΡΡ‚Π΅ΠΉΡˆΠΈΠ΅ вычислСния β€” Sum, Count, Min, Max

a: list[int] = [1, 2, 3, 4, 5, 2, 2]

s = sum(a)
print(s)

c = a.count(2)  # Π’Π΅Ρ€Π½Π΅Ρ‚ количСство Π²Ρ…ΠΎΠΆΠ΄Π΅Π½ΠΈΠΉ
print(c)

mn = min(a)
print(mn)

mx = max(a)
print(mx)
19
3
1
5

ΠŸΡ€ΠΈΡΠΌΠΎΡ‚Ρ€ΠΈΡ‚Π΅ΡΡŒ ΠΊ встроСнным функциям, Ρ‚Π°ΠΌ Π΅ΡΡ‚ΡŒ Π΅Ρ‰Π΅ ΠΊΠΎΠ΅-Ρ‡Ρ‚ΠΎ, ΠΊΠ°ΡΠ°ΡŽΡ‰Π΅Π΅ΡΡ элСмСнтарной ΠΌΠ°Ρ‚Π΅ΠΌΠ°Ρ‚ΠΈΠΊΠΈ.

Базовая ΠΌΠ°Ρ‚Π΅ΠΌΠ°Ρ‚ΠΈΠΊΠ°

from math import pi

a: float = pi ** 2  # Or pow(pi, 2)
print(f"Power: {a}")

b: float = round(pi, 2)
print(f"Round: {b}")

c: int = round(256, -2)
print(f"Int round: {c}")

d: float = abs(-pi)
print(f"Abs: {d}")

e: float = abs(10+10j)  # Or e: float = abs(complex(real=10, imag=10))
print(f"Complex abs: {e}")
Power: 9.869604401089358
Round: 3.14
Int round: 300
Abs: 3.141592653589793
Complex abs: 14.142135623730951

ΠŸΠΎΠ±ΠΈΡ‚ΠΎΠ²Ρ‹Π΅ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ

a: int = 0b01010101
b: int = 0b10101010

print(f"And: 0b{a&b:08b}")
print(f"Or: 0b{a|b:08b}")
print(f"Xor: 0b{a^b:08b}")
print(f"Left shift: 0b{a << 4:08b}")
print(f"Right shift: 0b{b >> 4:08b}")
print(f"Not: 0b{~a:08b}")
And: 0b00000000
Or: 0b11111111
Xor: 0b11111111
Left shift: 0b10101010000
Right shift: 0b00001010
Not: 0b-1010110

ΠŸΠΎΠ΄ΡΡ‡Π΅Ρ‚ Π±ΠΈΡ‚ΠΎΠ²

a: int = 4242
print(f"{a} in binary format: 0b{a:b}")

c = a.bit_count()  # Returns the number of ones in the binary representation of the absolute value of the integer
print(f"Bit count: {c}")
4242 in binary format: 0b1000010010010
Bit count: 4

Fractions

from fractions import Fraction

f = Fraction("0.2").as_integer_ratio()

print(f)
(1, 5)

Π•Π²ΠΊΠ»ΠΈΠ΄ΠΎΠ²ΠΎ расстояниС ΠΌΠ΅ΠΆΠ΄Ρƒ двумя Ρ‚ΠΎΡ‡ΠΊΠ°ΠΌΠΈ

import math

p1 = (0.22, 1, 12)
p2 = (-0.12, 3, 7)

print(math.dist(p1, p2))
5.39588732276722

NumPy

Мини-язык для манипулирования массивами. На ΡƒΠ΄Π°Ρ‡Π½Ρ‹Ρ… сцСнариях Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Π² сотни Ρ€Π°Π· быстрСС встроСнных Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ. Π•Ρ‰Π΅ Π±ΠΎΠ»Π΅Π΅ быстрая Π°Π»ΡŒΡ‚Π΅Ρ€Π½Π°Ρ‚ΠΈΠ²Π° Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Π½Π° GPU, называСтся CuPy ΠΈ ΠΎΠΏΡΡ‚ΡŒ-Ρ‚Π°ΠΊΠΈ ΠΎΠ±Π΅Ρ‰Π°Π΅Ρ‚ стократный прирост ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ, Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΡƒΠΆΠ΅ ΠΏΠΎ ΡΡ€Π°Π²Π½Π΅Π½ΠΈΡŽ с NumPy. Π’Π°ΠΊ Ρ‡Ρ‚ΠΎ Ссли Π²Π°ΠΌ Π½ΡƒΠΆΠ΅Π½ ΠΊΠ°ΠΊΠΎΠΉ-Π½ΠΈΠ±ΡƒΠ΄ΡŒ быстрый FFT ΠΈΠ»ΠΈ Π΅Ρ‰Π΅ ΠΊΠ°ΠΊΠΎΠΉ числогрыз, Ρ‚ΠΎ Π²Ρ‹ Π·Π½Π°Π΅Ρ‚Π΅, Ρ‡Ρ‚ΠΎ Π΄Π΅Π»Π°Ρ‚ΡŒ. Если Π²Ρ‹ Π΄Ρ€ΡƒΠΆΠΈΡ‚Π΅ с английским, Ρ‚ΠΎ ΠΈΠ·ΡƒΡ‡Π°ΠΉΡ‚Π΅ ΠΎΡ„ΠΈΡ†ΠΈΠ°Π»ΡŒΠ½Ρ‹ΠΉ ΠΌΠ°Π½ΡƒΠ°Π», Ссли Π½Π΅Ρ‚ β€” Π½Π° Β«Π₯Π°Π±Ρ€Π΅Β» Π΅ΡΡ‚ΡŒ ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄ (ΠΊΠ°ΠΊ всСгда, Ρ‡ΠΈΡ‚Π°ΠΉΡ‚Π΅ ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΈ, Ρ‚Π°ΠΌ Π½Π΅ΠΌΠ°Π»ΠΎ ΠΏΠΎΠ»Π΅Π·Π½ΠΎΠ³ΠΎ).

НСбольшоС отступлСниС.

Π’ΠΎ-ΠΏΠ΅Ρ€Π²Ρ‹Ρ…, Ρ‚ΡƒΡ‚ ΠΌΡ‹ ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ΠΈΠΌ Π³Ρ€Π°Π½ΠΈΡ†Ρƒ ΠΌΠ΅ΠΆΠ΄Ρƒ встроСнной Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ языка ΠΈ внСшними Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°ΠΌΠΈ. Надо ΠΏΠΎΠ½ΠΈΠΌΠ°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ успСх Python Π²ΠΎ ΠΌΠ½ΠΎΠ³ΠΎΠΌ основан ΠΈΠΌΠ΅Π½Π½ΠΎ Π½Π° богатствС Π΅Π³ΠΎ экосистСмы (хотя, Π²ΠΏΡ€ΠΎΡ‡Π΅ΠΌ, Ρ‚ΠΎ ΠΆΠ΅ самоС ΠΌΠΎΠΆΠ½ΠΎ ΡΠΊΠ°Π·Π°Ρ‚ΡŒ ΠΈ ΠΏΡ€ΠΎ JavaScript, ΠΈ ΠΏΡ€ΠΎ C#); сам язык прСдоставляСт Π±ΠΎΠ³Π°Ρ‚ΡƒΡŽ, Π½ΠΎ всё ΠΆΠ΅ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½Π½ΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ, Π² Ρ‚ΠΎ врСмя ΠΊΠ°ΠΊ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π» Π²Π½Π΅ΡˆΠ½ΠΈΡ… Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊ практичСски Π±Π΅Π·Π³Ρ€Π°Π½ΠΈΡ‡Π΅Π½; это ΠΊΠ°ΠΊ бСсконСчно Ρ€Π°Π·Π½ΠΎΠΎΠ±Ρ€Π°Π·Π½Ρ‹Π΅ ΠΊΡƒΠ±ΠΈΠΊΠΈ Π›Π΅Π³ΠΎ. БоотвСтствСнно, ΠΎΡ‡Π΅Π½ΡŒ часто для Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ Π·Π°Π΄Π°Ρ‡ΠΈ Π½Π΅ Π½ΡƒΠΆΠ½ΠΎ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Ρ‹Π²Π°Ρ‚ΡŒ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ с нуля Π½Π° чистом Python'Π΅, достаточно ΠΏΠΎΠ΄ΠΎΠ±Ρ€Π°Ρ‚ΡŒ Π½ΡƒΠΆΠ½ΡƒΡŽ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΡƒ.

Π’ΠΎ-Π²Ρ‚ΠΎΡ€Ρ‹Ρ…, ΠΏΠΎΠΏΡƒΠ»ΡΡ€Π½ΠΎΡΡ‚ΡŒ Ρ€Π°Π·Π½Ρ‹Ρ… Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊ Python (Π² Ρ‚ΠΎΠΌ числС ΠΈ ΠΊΠΎΠ½ΠΊΡƒΡ€ΠΈΡ€ΡƒΡŽΡ‰ΠΈΡ…) сильно разнится. НапримСр, NumPy β€” ΠΎΡ‡Π΅Π½ΡŒ популярная Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°, Π½ΠΎ Π² ΠΌΠΈΡ€Π΅ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‚ Π±ΡƒΠΊΠ²Π°Π»ΡŒΠ½ΠΎ ΠΌΠΈΠ»Π»ΠΈΠΎΠ½Ρ‹ Python-Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΎΠ², ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ Ρ€Π°Π±ΠΎΡ‚Π°Π»ΠΈ с NumPy, просто Π² силу своСго ΠΊΡ€ΡƒΠ³Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½Ρ‹Ρ… обязанностСй.

Для Π½Π°Ρ‡ΠΈΠ½Π°ΡŽΡ‰Π΅Π³ΠΎ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ° это прСдставляСт собой довольно Π½Π΅ΡˆΡƒΡ‚ΠΎΡ‡Π½ΡƒΡŽ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡƒ β€” ΠΊΠ°ΠΊ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎ Π΄Π²ΠΈΠ³Π°Ρ‚ΡŒΡΡ Π²ΠΏΠ΅Ρ€Π΅Π΄, ΠΊΠ°ΠΊΠΈΠ΅ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ ΠΈΠ·ΡƒΡ‡Π°Ρ‚ΡŒ, вСдь знания чистого Python, ΠΊΠ°ΠΊ ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ, нСдостаточно для формирования Π°ΠΊΡ‚ΡƒΠ°Π»ΡŒΠ½ΠΎΠ³ΠΎ Ρ€Π΅Π·ΡŽΠΌΠ΅.

Π”Π°ΠΌ Π²Π°ΠΌ нСбольшой совСт. Π•ΠΆΠ΅Π³ΠΎΠ΄Π½ΠΎ компания JetBrains (Π΄Π΅Π»Π°ΡŽΡ‰Π°Ρ срСди ΠΏΡ€ΠΎΡ‡Π΅Π³ΠΎ ΠΎΡ‡Π΅Π½ΡŒ ΠΊΠ»Π°ΡΡΠ½ΡƒΡŽ IDE PyCharm) ΠΏΡ€ΠΎΠ²ΠΎΠ΄ΠΈΡ‚ всСмирный опрос Python-Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΎΠ², Π° ΠΏΠΎΡ‚ΠΎΠΌ Π²Ρ‹ΠΊΠ»Π°Π΄Ρ‹Π²Π°Π΅Ρ‚ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½Ρ‹Π΅ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹ Π² Π²ΠΈΠ΄Π΅ Ρ‚Π°ΠΊ Π½Π°Π·Ρ‹Π²Π°Π΅ΠΌΠΎΠ³ΠΎ Python Developers Survey Results. НапримСр, Ссли Π²Ρ‹ ΠΏΠΎΡ‡ΠΈΡ‚Π°Π΅Ρ‚Π΅ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹ послСднСго исслСдования, Ρ‚ΠΎ Π½Π°ΠΉΠ΄Π΅Ρ‚Π΅ Ρ‚Π°ΠΌ довольно Ρ‡Ρ‘Ρ‚ΠΊΠΈΠ΅ ΠΎΡ€ΠΈΠ΅Π½Ρ‚ΠΈΡ€Ρ‹: скаТСм, Π² Ρ€Π°Π·Π΄Π΅Π»Π΅ Β«Data science frameworks and librariesΒ» Π² Ρ‚ΠΎΠΏΠ΅ находятся NumPy, Pandas (рассмотрСн Π½ΠΈΠΆΠ΅) ΠΈ Matplotlib; Π² тСстировании с большим ΠΎΡ‚Ρ€Ρ‹Π²ΠΎΠΌ Π»ΠΈΠ΄ΠΈΡ€ΡƒΠ΅Ρ‚ pytest (смотри Π½ΠΈΠΆΠ΅), Π² Π΄Ρ€ΡƒΠ³ΠΈΡ… областях Π²ΠΏΠ΅Ρ€Π΅Π΄ Π²Ρ‹Ρ€Ρ‹Π²Π°ΡŽΡ‚ΡΡ Flask (Django Π½Π° Π²Ρ‚ΠΎΡ€ΠΎΠΌ мСстС с ΠΊΡ€ΠΎΡˆΠ΅Ρ‡Π½Ρ‹ΠΌ ΠΎΡ‚Ρ€Ρ‹Π²ΠΎΠΌ), SQLAlchemy (vs Django ORM) ΠΈ PostgreSQL (vs SQLite), ΠΏΡ€ΠΎ Π½ΠΈΡ… ΠΌΡ‹ Ρ‚ΠΎΠΆΠ΅ Π΅Ρ‰Π΅ ΠΏΠΎΠ³ΠΎΠ²ΠΎΡ€ΠΈΠΌ. Π’Π°ΠΊ Ρ‡Ρ‚ΠΎ Π² Ρ†Π΅Π»ΠΎΠΌ, ΠΎΠ±Ρ‰Π΅Π΅ Π½Π°ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ развития ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ ΠΌΠΎΠΆΠ½ΠΎ.

Однако, вСрнСмся ΠΊ NumPy. НС Π·Π°Π±Ρ‹Π²Π°ΠΉΡ‚Π΅, Ρ‡Ρ‚ΠΎ Π² основС NumPy Π»Π΅ΠΆΠ°Ρ‚ массивы, Π° всС Π΄Π°Π½Π½Ρ‹Π΅ Π² массивС Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²ΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ° (просто Π½Π° случай, Ссли Π²Ρ‹ ΡƒΠΆΠ΅ ΠΏΠΎΠ·Π½Π°Π»ΠΈ ΠΏΡ€-Ρ€-Ρ€Π΅Π»-Π»-Π»Π΅ΡΡ‚ΡŒ списков Python). Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ массивов:

import numpy as np

a1 = np.array([1, 2, 3, 4, 5], float)  # ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ массива ΠΈΠ· списка
print(a1[0:2])

a2 = np.zeros(5)  # Массив, Π·Π°ΠΏΠΎΠ»Π½Π΅Π½Π½Ρ‹ΠΉ нулями
print(a2)

a3 = np.arange(0, 6, 1)  # ИспользованиС диапазона, np.arange(from_inclusive, to_exclusive, step_size)
print(a3)

a4 = np.random.randint(6, size=10)  # Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ массива, содСрТащСго случайныС значСния, np.random.randint(low_inclusive, high_exclusive=None, size=None, dtype=int)
print(a4)

a5 = np.random.randint(6, size=(2, 5))  # Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΌΠ½ΠΎΠ³ΠΎΠΌΠ΅Ρ€Π½ΠΎΠ³ΠΎ массива, содСрТащСго случайныС значСния
print(a5)

print(a5.shape)  # Число строк ΠΈ столбцов Π² массивС

print(a5.dtype)  # Π’ΠΈΠΏ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ…

print(1 in a5)  # ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° наличия элСмСнта
[1. 2.]
[0. 0. 0. 0. 0.]
[0 1 2 3 4 5]
[2 2 4 0 0 0 0 4 0 5]
[[1 0 3 5 0]
 [3 1 4 2 2]]
(2, 5)
int32
True

Π‘Π°Π·ΠΎΠ²Ρ‹Π΅ матСматичСскиС ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ (ΠΏΠΎΠ»Π½Ρ‹ΠΉ список):

import numpy as np

a1 = np.array([1, 2, 3, 4, 5])
a2 = np.array([6, 7, 8, 9, 10])

a3 = a1 + 1
print(a3)

a4 = a1 + a2
print(a4)

a5 = a1 ** 3
print(a5)

a6 = a1 ** a2
print(a6)
[2 3 4 5 6]
[ 7  9 11 13 15]
[  1   8  27  64 125]
[      1     128    6561  262144 9765625]

Π’ΠΎΠΎΠ±Ρ‰Π΅, ΠΌΠΎΠΆΠ½ΠΎ ΡΠΊΠ°Π·Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ быстрыС матСматичСскиС ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ Π½Π°Π΄ ΠΌΠ½ΠΎΠ³ΠΎΠΌΠ΅Ρ€Π½Ρ‹ΠΌΠΈ массивами β€” это главная Β«Ρ„ΠΈΡˆΠΊΠ°Β» NumPy. Π’Ρ‹ просто Π³ΠΎΠ²ΠΎΡ€ΠΈΡ‚Π΅: возьми Ρ‚Π°ΠΊΠΈΠ΅-Ρ‚ΠΎ массивы ΠΈ ΠΏΡ€ΠΎΠ΄Π΅Π»Π°ΠΉ Π½Π°Π΄ Π½ΠΈΠΌΠΈ Ρ‚Π°ΠΊΡƒΡŽ-Ρ‚ΠΎ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΡŽ. Π”Π°Π»Π΅Π΅ всС эти Π΄Π°Π½Π½Ρ‹Π΅ Β«ΠΏΡ€ΠΎΠ²Π°Π»ΠΈΠ²Π°ΡŽΡ‚ΡΡΒ» Π² высокоскоростноС ядро NumPy, Π³Π΄Π΅ ΠΊ Π½ΠΈΠΌ ΡƒΠΆΠ΅ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΡ‚ΡŒ всю ΠΌΠΎΡ‰ΡŒ вашСго процСссора, которая Ρ€Π°Π½ΡŒΡˆΠ΅ Π±Ρ‹Π»Π° Π²Π°ΠΌ нСдоступна (Π½Ρƒ, ΠΈΠ»ΠΈ доступна Π½Π΅ ΠΏΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ) ΠΈΠ·-Π·Π° ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠΉ Python-ΠΈΠ½Ρ‚Π΅Ρ€ΠΏΡ€Π΅Ρ‚Π°Ρ‚ΠΎΡ€Π°. Π’Π°ΠΊ Ρ‡Ρ‚ΠΎ, Ссли Π²Ρ‹ ΠΏΡ‹Ρ‚Π°Π΅Ρ‚Π΅ΡΡŒ Π² Ρ†ΠΈΠΊΠ»Π΅ ΠΈΡ‚Π΅Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ массив NumPy, ΠΏΠΎ Ρ„Π°ΠΊΡ‚Ρƒ пСрСдавая Π΄Π°Π½Π½Ρ‹Π΅ Π½Π° Π½ΠΈΠΆΠ½ΠΈΠΉ ΡƒΡ€ΠΎΠ²Π΅Π½ΡŒ нСбольшими порциями (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°ΠΌΠΈ row), Ρ‚ΠΎ ΠΈΠΌΠ΅ΠΉΡ‚Π΅ Π² Π²ΠΈΠ΄Ρƒ, Ρ‡Ρ‚ΠΎ Ρ‚Π΅ΠΌ самым ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚Π΅ возмоТности NumPy нСдостаточно эффСктивно; ΠΏΠΎΠΏΡ€ΠΎΠ±ΡƒΠΉΡ‚Π΅ Ρ€Π΅ΡˆΠΈΡ‚ΡŒ Π·Π°Π΄Π°Ρ‡Ρƒ Π±Π΅Π· итСрирования.

Sum, Min, Max

import numpy as np

a1 = np.random.randint(6, size=(2, 10))  # NumPy ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ нСсколько дСсятков Π²ΠΈΠ΄ΠΎΠ² распрСдСлСний, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠŸΡƒΠ°ΡΡΠΎΠ½Π° ΠΈ Π‘Ρ‚ΡŒΡŽΠ΄Π΅Π½Ρ‚Π°
print(a1)

s = np.sum(a1)  # Π‘ΡƒΠΌΠΌΠ° всСх элСмСнтов
print(s)

mn = a1.min(axis=0)  # НаимСньшиС числа Π² ΠΊΠ°ΠΆΠ΄ΠΎΠΌ столбцС
print(mn)

mx = a1.max(axis=1)  # НаибольшиС числа Π² ΠΊΠ°ΠΆΠ΄ΠΎΠΉ строкС
print(mx)

amin = a1.argmin(axis=0)  # Π˜Π½Π΄Π΅ΠΊΡΡ‹ ΠΌΠΈΠ½ΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹Ρ… элСмСнтов Π² ΠΊΠ°ΠΆΠ΄ΠΎΠΌ столбцС
print(amin)

amax = a1.argmax(axis=1)  # Π˜Π½Π΄Π΅ΠΊΡΡ‹ ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹Ρ… элСмСнтов Π² ΠΊΠ°ΠΆΠ΄ΠΎΠΉ строкС
print(amax)

uniq = np.unique(a1)  # Π˜Π·Π²Π»Π΅Ρ‡Π΅Π½ΠΈΠ΅ ΡƒΠ½ΠΈΠΊΠ°Π»ΡŒΠ½Ρ‹Ρ… элСмСнтов
print(uniq)
[[3 0 4 1 0 5 4 0 1 3]
 [0 3 4 0 0 1 4 0 5 4]]
42
[0 0 4 0 0 1 4 0 1 3]
[5 5]
[1 0 0 1 0 1 0 0 0 0]
[5 8]
[0 1 3 4 5]

Π’ качСствС домашнСго задания ΠΏΠΎΠΏΡ€ΠΎΠ±ΡƒΠΉΡ‚Π΅ ΡΠ°ΠΌΠΎΡΡ‚ΠΎΡΡ‚Π΅Π»ΡŒΠ½ΠΎ ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΡ‚ΡŒ prod(), mean(), var(), std(), median(), cov() ΠΈ corrcoef().

Π€ΠΎΡ€ΠΌΠ°Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ массивов:

import numpy as np

a = np.random.randint(6, size=(3, 5))
print(a)

a1 = a.reshape((5, 3))  # Π€ΠΎΡ€ΠΌΠ°Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅. Если Π΅ΡΡ‚ΡŒ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ, создаСтся Π½ΠΎΠ²Ρ‹ΠΉ view Π½Π° Ρ‚Π΅ ΠΆΠ΅ самыС Π΄Π°Π½Π½Ρ‹Π΅
print(a1)

a.shape = (5, 3)  # Π€ΠΎΡ€ΠΌΠ°Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ in-place
print(a)

print(a.shape)
a = a[:, :, np.newaxis]  # Π£Π²Π΅Π»ΠΈΡ‡Π΅Π½ΠΈΠ΅ размСрности массива с 2 Π΄ΠΎ 3
print(a)
print(a.shape)

a = a.flatten()  # ΠšΠΎΠ½Π²Π΅Ρ€Ρ‚Π°Ρ†ΠΈΡ Π² ΠΎΠ΄Π½ΠΎΠΌΠ΅Ρ€Π½Ρ‹ΠΉ массив
print(a)
print(a.shape)
[[5 5 5 1 1]
 [0 2 0 5 5]
 [0 2 5 4 5]]
[[5 5 5]
 [1 1 0]
 [2 0 5]
 [5 0 2]
 [5 4 5]]
[[5 5 5]
 [1 1 0]
 [2 0 5]
 [5 0 2]
 [5 4 5]]
(5, 3)
[[[5]
  [5]
  [5]]

 [[1]
  [1]
  [0]]

 [[2]
  [0]
  [5]]

 [[5]
  [0]
  [2]]

 [[5]
  [4]
  [5]]]
(5, 3, 1)
[5 5 5 1 1 0 2 0 5 5 0 2 5 4 5]
(15,)

ΠšΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ массивов:

import numpy as np
import copy

a = np.random.randint(10, size=(4, 4))
print(a)

# НСглубокая (shallow) копия
a1 = np.copy(a)

# Глубокая (deep) копия
a2 = copy.deepcopy(a)

# ΠšΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ссылки
a3 = a

a[0, 0] = 10
print(a[0, 0] == a1[0, 0])
print(a[0, 0] == a2[0, 0])
print(a[0, 0] == a3[0, 0])
[[5 3 1 4]
 [0 8 7 0]
 [1 7 4 7]
 [5 3 5 2]]
False
False
True

NumPy ΠΎΡ‡Π΅Π½ΡŒ ΠΌΠΎΡ‰Π½Ρ‹ΠΉ инструмСнт, Π½Π΅ зря ΠΆΠ΅ ΠΎΠ½ стоит Π½Π° ΠΏΠ΅Ρ€Π²ΠΎΠΌ мСстС Π² спискС Β«Data science frameworks and librariesΒ» ΠΎΠ±Π·ΠΎΡ€Π°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΌΡ‹ ΡƒΠΏΠΎΠΌΠΈΠ½Π°Π»ΠΈ Ρ‡ΡƒΡ‚ΡŒ Π²Ρ‹ΡˆΠ΅. Но ΡƒΠ³Π»ΡƒΠ±Π»ΡΡ‚ΡŒΡΡ Π² эту Ρ‚Π΅ΠΌΡƒ ΠΎΡ‡Π΅Π½ΡŒ ΡƒΠΆ Π³Π»ΡƒΠ±ΠΎΠΊΠΎ Π² Ρ€Π°ΠΌΠΊΠ°Ρ… нашСго достаточно повСрхностного ΠΎΡ‡Π΅Ρ€ΠΊΠ°, ΠΏΠΎΠΆΠ°Π»ΡƒΠΉ, Π½Π΅ стоит; вряд Π»ΠΈ прямо сСйчас Π²Π°ΠΌ ΠΊΡ€ΠΎΠ²ΡŒ ΠΈΠ· носу Π½ΡƒΠΆΠ½ΠΎ ΠΎΡΠ²ΠΎΠΈΡ‚ΡŒ скалярноС, Ρ‚Π΅Π½Π·ΠΎΡ€Π½ΠΎΠ΅ ΠΈ внСшнСС ΠΏΡ€ΠΎΠΈΠ·Π²Π΅Π΄Π΅Π½ΠΈΠ΅ ΠΌΠ°Ρ‚Ρ€ΠΈΡ† ΠΈΠ»ΠΈ ΠΏΠΎΠ·Π½Π°Ρ‚ΡŒ (Π²ΡΠΏΠΎΠΌΠ½ΠΈΡ‚ΡŒ?) спСцифику Π»ΠΈΠ½Π΅ΠΉΠ½ΠΎΠΉ Π°Π»Π³Π΅Π±Ρ€Ρ‹. Π”ΡƒΠΌΠ°ΡŽ, Π΄Π°ΠΆΠ΅ Ссли ΠΌΡ‹ сСйчас Π½Π°Ρ‡Π½Π΅ΠΌ ΠΎΠΏΠΈΡΡ‹Π²Π°Ρ‚ΡŒ транспонированиС ΠΈΠ»ΠΈ Π²Ρ‹Π±ΠΎΡ€ оси, ΠΏΠΎ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΡ€ΠΎΠΈΠ·Π²Π΅Π΄Π΅Π½Π° конкатСнация массивов, Ρ‚ΠΎ это ΡƒΠΆΠ΅ Π±ΡƒΠ΄Π΅Ρ‚, Ρ‡Ρ‚ΠΎ называСтся, Β«Π½Π΅ Π² коня ΠΊΠΎΡ€ΠΌΒ».
К Ρ‚ΠΎΠΌΡƒ ΠΆΠ΅, изучая тонкости употрСблСния NumPy, Π½Π°Ρ‡ΠΈΠ½Π°Π΅Ρ‚ ΠΏΠΎΡΠ²Π»ΡΡ‚ΡŒΡΡ соблазн упоминания SciPy, ΠΏΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²Π»ΡΡŽΡ‰Π΅Π³ΠΎ Π΅Ρ‰Π΅ Π±ΠΎΠ»Π΅Π΅ ΡˆΠΈΡ€ΠΎΠΊΠΈΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π», Π° послС ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ "import scipy" Ρƒ нас начнётся ΡƒΠΆΠ΅ ΠΏΠΎΠ»Π½ΠΎΠ΅ нСпотрСбство. Π”Π°Π²Π°ΠΉΡ‚Π΅ ΠΏΠΎΠΊΠ° ΠΏΡ€ΠΎΠΉΠ΄Π΅ΠΌ ΠΌΠΈΠΌΠΎ этой ΠΊΡ€ΠΎΠ»ΠΈΡ‡ΡŒΠ΅ΠΉ Π½ΠΎΡ€Ρ‹, для ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ знакомства ΠΎΠ½Π° слишком Π³Π»ΡƒΠ±ΠΎΠΊΠ°.

ЕдинствСнноС, Ρ‡Ρ‚ΠΎ Π΅Ρ‰Π΅ ΠΌΠΎΠΆΠ½ΠΎ ΠΎΡΠ²ΠΎΠΈΡ‚ΡŒ Π² ΠΊΠΎΠ½Ρ†Π΅ ΠΎΠ·Π½Π°ΠΊΠΎΠΌΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ курса NumPy β€” взаимодСйствиС с внСшним ΠΌΠΈΡ€ΠΎΠΌ. Π˜Π·ΡƒΡ‡ΠΈΡ‚Π΅ для Π½Π°Ρ‡Π°Π»Π° load/save/savez (Π±ΠΈΠ½Π°Ρ€Π½ΠΈΠΊΠΈ) ΠΈ loadtxt/savetxt (Ρ‡Π΅Π»ΠΎΠ²Π΅ΠΊΠΎΡ‡ΠΈΡ‚Π°Π΅ΠΌΡ‹ΠΉ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚).

Pandas

Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ ΠΈ Π°Π½Π°Π»ΠΈΠ·Π° Π΄Π°Π½Π½Ρ‹Ρ…. Π Π°Π±ΠΎΡ‚Π° с Π΄Π°Π½Π½Ρ‹ΠΌΠΈ строится ΠΏΠΎΠ²Π΅Ρ€Ρ… Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ NumPy.
Π’ ΠΏΠ΅Ρ€Π²ΠΎΠΌ, Π³Ρ€ΡƒΠ±ΠΎΠΌ ΠΏΡ€ΠΈΠ±Π»ΠΈΠΆΠ΅Π½ΠΈΠΈ pandas ΠΌΠΎΠΆΠ½ΠΎ Π²ΠΎΡΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Ρ‚ΡŒ ΠΊΠ°ΠΊ связку Β«Excel + VisualBasic-скрипты», Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π±ΠΎΠ»Π΅Π΅ Π³ΠΈΠ±ΠΊΡƒΡŽ ΠΈ ΡƒΠ΄ΠΎΠ±Π½ΡƒΡŽ. Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° создаСт своСобразный мостик ΠΌΠ΅ΠΆΠ΄Ρƒ профСссиями Python-программиста, Π΄Π°Ρ‚Π°-сайСнтиста ΠΈ Π°Π½Π°Π»ΠΈΡ‚ΠΈΠΊΠ°, позволяя ΡΠΎΡΡ€Π΅Π΄ΠΎΡ‚ΠΎΡ‡ΠΈΡ‚ΡŒΡΡ Π² большСй стСпСни ΠΈΠΌΠ΅Π½Π½ΠΎ Π½Π° очисткС ΠΈ Π°Π½Π°Π»ΠΈΠ·Π΅ Π΄Π°Π½Π½Ρ‹Ρ…, Π½Π° Ρ‡ΠΈΡ‚Π°Π±Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ ΠΎΡ‚Ρ‡Π΅Ρ‚ΠΎΠ², Π° Π½Π΅ Π½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠΈ. Pandas Ρ‚Π°ΠΊΠΆΠ΅ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ ΡˆΠΈΡ€ΠΎΠΊΠΈΠΉ спСктр «красивостСй» ΠΏΡ€ΠΈ Π²Ρ‹Π²ΠΎΠ΄Π΅ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ, позволяя, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π΄ΠΎΠ±Π°Π²Π»ΡΡ‚ΡŒ Π² Π²Ρ‹Π²ΠΎΠ΄ΠΈΠΌΡ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅ Π³Ρ€Π°Π΄ΠΈΠ΅Π½Ρ‚Π½ΡƒΡŽ подсвСтку (heatmap) ΠΈΠ»ΠΈ Π²ΠΈΠ·ΡƒΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΡ‚ΠΊΠ»ΠΎΠ½Π΅Π½ΠΈΠ΅ ΠΎΡ‚ срСднСго (bar chart).

Для Ρ‚ΠΎΠ³ΠΎ Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΊΠ°ΠΊ слСдуСт Β«Ρ€Π°ΡΠΏΡ€ΠΎΠ±ΠΎΠ²Π°Ρ‚ΡŒΒ» pandas, ΠΏΠΎ-Ρ…ΠΎΡ€ΠΎΡˆΠ΅ΠΌΡƒ Π½Π°Π΄ΠΎ Π·Π°Π³Ρ€ΡƒΠ·ΠΈΡ‚ΡŒ ΠΊΠ°ΠΊΠΎΠΉ-Π½ΠΈΠ±ΡƒΠ΄ΡŒ развСсистый Π½Π°Π±ΠΎΡ€ Π΄Π°Π½Π½Ρ‹Ρ…, Π½ΠΎ ΠΌΡ‹, ΠΏΠΎΠΆΠ°Π»ΡƒΠΉ, Π½Π΅ Π±ΡƒΠ΄Π΅ΠΌ ΠΏΠΎΠ³Ρ€ΡƒΠΆΠ°Ρ‚ΡŒΡΡ Π² Π³Π»ΡƒΠ±ΠΈΠ½Ρ‹ Π³Π»ΡƒΠ±ΠΈΠ½, просто ΠΏΠΎΠΈΠ³Ρ€Π°Π΅ΠΌ нСбольшим ΡΠ°ΠΌΠΎΠ΄Π΅Π»ΡŒΠ½Ρ‹ΠΌ датасСтом.

import pandas as pd

s = pd.Series([0, 1, 4, 7, 8, 10, 12])
print(s)
print(s[2])
0     0
1     1
2     4
3     7
4     8
5    10
6    12
dtype: int64
4

Series β€” базовая структура Π΄Π°Π½Π½Ρ‹Ρ… pandas. Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π²ΠΎΡΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Ρ‚ΡŒ Π΅Ρ‘ ΠΊΠ°ΠΊ упорядочСнный ΡΠ»ΠΎΠ²Π°Ρ€ΡŒ ΠΈΠ»ΠΈ ΠΊΠ°ΠΊ строку Excel, смотря ΠΏΠΎ Ρ‚ΠΎΠΌΡƒ, какая аналогия Π²Π°ΠΌ Π±Π»ΠΈΠΆΠ΅.

import pandas as pd

s = pd.Series([0, 1, 4, 7, 8, 10, 12], index=["a", "b", "c", "d", "x", "y", "z"])  # Π˜Π½Π΄Π΅ΠΊΡΡ‹ Series ΠΌΠΎΠΆΠ½ΠΎ Π·Π°Π΄Π°Π²Π°Ρ‚ΡŒ Π²Ρ€ΡƒΡ‡Π½ΡƒΡŽ

print(s)
print(s["x"])
print(s[["x", "y", "z"]])  # Π’Ρ‹Π±ΠΎΡ€ΠΊΠ°
print(s[s > 5])  # Π€ΠΈΠ»ΡŒΡ‚Ρ€Π°Ρ†ΠΈΡ

print(s.max())  # ΠœΠ°Ρ‚Π΅ΠΌΠ°Ρ‚ΠΈΠΊΠ°, ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½ΠΎ ΠΊΠ°ΠΊ Π² NumPy
print(s.sum())
a     0
b     1
c     4
d     7
x     8
y    10
z    12
dtype: int64
8
x     8
y    10
z    12
dtype: int64
d     7
x     8
y    10
z    12
dtype: int64
12
42

ΠŸΡ€ΠΈ объСдинСнии Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… Series получаСтся DataFrame, вторая базовая структура Π΄Π°Π½Π½Ρ‹Ρ… pandas, ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ Π² ΠΏΠ΅Ρ€Π²ΠΎΠΌ ΠΏΡ€ΠΈΠ±Π»ΠΈΠΆΠ΅Π½ΠΈΠΈ ΠΌΠΎΠΆΠ½ΠΎ Ρ€Π°ΡΡΠΌΠ°Ρ‚Ρ€ΠΈΠ²Π°Ρ‚ΡŒ ΠΊΠ°ΠΊ лист Excel.

import pandas as pd
from pandas import DataFrame

s1 = pd.Series([0, 1, 4, 7, 8, 10, 12])
s2 = pd.Series([0, 100, 200, 300, 600, 900, 1200])

df = pd.DataFrame([s1, s2])
print(df)
print(df[1])
print(df[2][0])
print(df.iloc[0][2:4])
   0    1    2    3    4    5     6
0  0    1    4    7    8   10    12
1  0  100  200  300  600  900  1200
0      1
1    100
Name: 1, dtype: int64
4
2    4
3    7
Name: 0, dtype: int64

Π”Π°Π²Π°ΠΉΡ‚Π΅ сдСлаСм Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ Π±ΠΎΠ»Π΅Π΅ ΠΏΠΎΡ…ΠΎΠΆΠ΅Π΅ Π½Π° Ρ€Π΅Π°Π»ΡŒΠ½Ρ‹ΠΉ Π°Π½Π°Π»ΠΈΠ· Π΄Π°Π½Π½Ρ‹Ρ…. ΠŸΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ Ρ„ΠΎΡ€ΠΌΡƒΠ»Ρ‹ ИМВ выясним, ΠΊΡ‚ΠΎ ΠΈΠ· знамСнитостСй Π½Π΅ слСдит Π·Π° собой ΠΈ обзавСлся лишним вСсом:

from pandas import DataFrame
import matplotlib.pyplot as plt


def bmi(row):
    return row["weight"] / row["height"] ** 2


if __name__ == '__main__':
    celebs: dict = {"Britney Spears": {"height": 1.63, "weight": 57},
                    "Melanie Griffith": {"height": 1.73, "weight": 63},
                    "Kylie Minogue": {"height": 1.52, "weight": 46},
                    "Hulk Hogan": {"height": 1.98, "weight": 137}}

    df = DataFrame(celebs)  # Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ DataFrame
    df.loc["bmi"] = df.apply(lambda row: bmi(row), axis=0)  # Π”ΠΎΠ±Π°Π²Π»Π΅ΠΌ Π½ΠΎΠ²ΡƒΡŽ строку с ИМВ
    df = df.sort_values(by="bmi", ascending=True, axis=1)  # Π‘ΠΎΡ€Ρ‚ΠΈΡ€ΡƒΠ΅ΠΌ

    print(df)

    df.loc["bmi"].plot.bar()  # Визуализация
    plt.show()
        Kylie Minogue  Melanie Griffith  Britney Spears  Hulk Hogan
height       1.520000          1.730000        1.630000    1.980000
weight      46.000000         63.000000       57.000000  137.000000
bmi         19.909972         21.049818       21.453574   34.945414

png

На самом Π΄Π΅Π»Π΅ Π₯Π°Π»ΠΊ, ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎ, Π½Π΅ толстяк, Π° ΠΏΡ€ΠΎΡ„Π΅ΡΡΠΈΠΎΠ½Π°Π»ΡŒΠ½Ρ‹ΠΉ спортсмСн, ΠΊ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ Ρ„ΠΎΡ€ΠΌΡƒΠ»Π° ИМВ ΠΌΠ°Π»ΠΎΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΠΌΠ°, Π½ΠΎ ΠΊΡ€ΠΎΡˆΠΊΠ° Кайли Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ вырываСтся Π²ΠΏΠ΅Ρ€Π΅Π΄, Π΄Π°ΠΆΠ΅ с ΡƒΡ‡Π΅Ρ‚ΠΎΠΌ своСго нСбольшого роста.

Matplotlib/Seaborn

Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΡƒ Π²ΠΈΠ·ΡƒΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ matplotlib ΠΌΡ‹ ΡƒΠΆΠ΅ слСгка задСйствовали Π² ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ Π²Ρ‹ΡˆΠ΅. ΠŸΡ€ΡΠΌΠΎ здСсь ΠΈ прямо сСйчас Π³Π»ΡƒΠ±ΠΎΠΊΠΎ ΠΏΠΎΠ³Ρ€ΡƒΠΆΠ°Ρ‚ΡŒΡΡ Π² Ρ€Π°Π·Π±ΠΎΡ€ возмоТностСй matplotlib/seaborn, Π½Π°Π²Π΅Ρ€Π½ΠΎΠ΅, особого смысла Π½Π΅ ΠΈΠΌΠ΅Π΅Ρ‚; всС Π²Ρ‹ Π²ΠΈΠ΄Π΅Π»ΠΈ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ ΠΈΠ»Π»ΡŽΡΡ‚Ρ€Π°Ρ†ΠΈΠΉ Π² Π½Π°ΡƒΡ‡Π½ΠΎΠΉ ΠΈ бизнСс-Π»ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΡƒΡ€Π΅ ΠΈ, разумССтся, всС эти Π³Ρ€Π°Ρ„ΠΈΠΊΠΈ ΠΈ ΠΈΠ»Π»ΡŽΡΡ‚Ρ€Π°Ρ†ΠΈΠΈ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠ²Ρ‚ΠΎΡ€ΠΈΡ‚ΡŒ ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ рассматриваСмых Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊ.

Π”Π°Π²Π°ΠΉΡ‚Π΅ просто для Π·Π°Ρ‚Ρ€Π°Π²ΠΊΠΈ нарисуСм ΠΏΠ°Ρ€Ρƒ симпатичных Π²ΠΈΠ·ΡƒΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΉ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ наглядно ΠΏΠΎΠΊΠ°Π·Π°Ρ‚ΡŒ ΠΏΠΎΠ»Π΅Π·Π½ΠΎΡΡ‚ΡŒ качСствСнного оформлСния Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠ² ΠΏΡ€ΠΎΠ΄Π΅Π»Π°Π½Π½ΠΎΠΉ Ρ€Π°Π±ΠΎΡ‚Ρ‹.

ВСпловая ΠΊΠ°Ρ€Ρ‚Π° (heatmap), наглядно ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‰Π°Ρ достиТСния ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Ρ… Ρ‡Π»Π΅Π½ΠΎΠ² ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹:

from random import randrange

import numpy as np
import matplotlib.pyplot as plt
import uuid

targets = ["authorities", "humans", "parrots", "cars", "motorcycles", "buildings", "warehouses"]
robots = ["Terminator #" + str(uuid.uuid4())[:5] for _ in range(7)]
harvest = np.array([[randrange(i * j) for i in range(10, 80, 10)] for j in range(1, 8)])

fig, ax = plt.subplots()
im = ax.imshow(harvest)

ax.set_xticks(np.arange(len(robots)), labels=robots)
ax.set_yticks(np.arange(len(targets)), labels=targets)
plt.setp(ax.get_xticklabels(), rotation=60, ha="right", rotation_mode="anchor")

for i in range(len(targets)):
    for j in range(len(robots)):
        text = ax.text(j, i, harvest[i, j], ha="center", va="center", color="w")

ax.set_title("Targets destroyed")
fig.tight_layout()

plt.rcParams['figure.figsize'] = [4, 4]
plt.rcParams['figure.dpi'] = 200
plt.show()

png

Аналогичная тСпловая ΠΊΠ°Ρ€Ρ‚Π°, визуализированная ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ seaborn:

from random import randrange

import numpy as np
import matplotlib.pyplot as plt
import uuid

import seaborn as sns

sns.set_theme()

targets = ["authorities", "humans", "parrots", "cars", "motorcycles", "buildings", "warehouses"]
robots = ["Terminator #" + str(uuid.uuid4())[:5] for _ in range(7)]
harvest = np.array([[randrange(i * j) for i in range(10, 80, 10)] for j in range(1, 8)])

fig, ax = plt.subplots()
im = ax.imshow(harvest)

ax.set_title("Targets destroyed")
plt.rcParams['figure.figsize'] = [4, 4]
sns.heatmap(harvest, annot=True, fmt="d", linewidths=.5, ax=ax, xticklabels=robots, yticklabels=targets)
plt.setp(ax.get_xticklabels(), rotation=60, ha="right", rotation_mode="anchor")
plt.xticks(rotation=60)
plt.show()

png

А Π²ΠΎΡ‚ Ρ‚Π°ΠΊ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹Π³Π»ΡΠ΄Π΅Ρ‚ΡŒ «Доска ΠΏΠΎΡ‡Ρ‘Ρ‚Π°Β» ΠΏΡ€ΠΈ отрисовкС Π² 3D:

import uuid
from random import randrange

import matplotlib.cm as cm
import matplotlib.colors as colors
import matplotlib.pyplot as plt
import numpy as np

targets = ["authorities", "humans", "parrots", "cars", "motorcycles", "buildings", "warehouses"]
robots = ["Terminator #" + str(uuid.uuid4())[:5] for _ in range(7)]
harvest = np.array([[randrange(i * j) for i in range(10, 80, 10)] for j in range(1, 8)])

fig = plt.figure(figsize=(5, 5))
ax = fig.add_subplot(projection='3d')
ax.set_xticks(np.arange(len(robots)), labels=robots)
ax.set_yticks(np.arange(len(targets)), labels=targets)
plt.setp(ax.get_xticklabels(), rotation=45, ha="right", rotation_mode="anchor")
plt.setp(ax.get_yticklabels(), ha="left", rotation_mode="anchor")
ax.set_title("Our team")

xx, yy = np.meshgrid(range(len(targets)), range(len(robots)))
x1d, y1d = xx.ravel(), yy.ravel()
harvest1d = harvest.ravel()

# Setup color scheme
offset = harvest1d + np.abs(harvest1d.min())
fracs = offset.astype(float) / offset.max()
norm = colors.Normalize(fracs.min(), fracs.max())
colors = cm.jet(norm(fracs))

ax.bar3d(x1d, y1d, np.zeros_like(x1d + y1d), 0.7, 0.7, harvest1d, color=colors)

plt.show()

png

НСйронныС сСти

Π£Π³Π»ΡƒΠ±ΠΈΡ‚ΡŒΡΡ достаточно Π³Π»ΡƒΠ±ΠΎΠΊΠΎ Π² Ρ‚Π΅ΠΌΠ°Ρ‚ΠΈΠΊΡƒ Π³Π»ΡƒΠ±ΠΎΠΊΠΎΠ³ΠΎ обучСния Π² Ρ€Π°ΠΌΠΊΠ°Ρ… нашСго нСсколько Π½Π΅Π³Π»ΡƒΠ±ΠΎΠΊΠΎΠ³ΠΎ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π°, ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎ, Π½Π΅ получится (ΠΊΠ°ΠΊΠΈΠΌ-Π½ΠΈΠ±ΡƒΠ΄ΡŒ Ρ‚ΠΎΠΌΠΎΠΌ Β«Π’Π²Π΅Π΄Π΅Π½ΠΈΠ΅ Π² Deep LearningΒ» Π²ΠΏΠΎΠ»Π½Π΅ ΠΌΠΎΠΆΠ½ΠΎ нанСсти сСбС сущСствСнныС Ρ‚Ρ€Π°Π²ΠΌΡ‹, Ссли Π½Π΅ΡƒΠ΄Π°Ρ‡Π½ΠΎ ΡƒΡ€ΠΎΠ½ΠΈΡ‚ΡŒ со стола), Ρ‚Π°ΠΊ Ρ‡Ρ‚ΠΎ ΡΠΊΠΎΠ»ΡŒΠ·Π½Ρ‘ΠΌ Π±ΡƒΠΊΠ²Π°Π»ΡŒΠ½ΠΎ ΠΏΠΎ Π²Π΅Ρ€Ρ…ΡƒΡˆΠΊΠ°ΠΌ, рассмотрСв основныС понятия.

Глубинная нСйронная ΡΠ΅Ρ‚ΡŒ (deep neural network) β€” это, Ρ„ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½ΠΎ Π²Ρ‹Ρ€Π°ΠΆΠ°ΡΡΡŒ, многослойная искусствСнная нСйронная ΡΠ΅Ρ‚ΡŒ, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰Π°Ρ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΡ‹ машинного обучСния для модСлирования высокоуровнСвых абстракций с ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ΠΌ Π½Π΅Π»ΠΈΠ½Π΅ΠΉΠ½Ρ‹Ρ… ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΠΉ. Π’ Ρ…ΠΎΠ΄Ρƒ Π΅ΡΡ‚ΡŒ Π΅Ρ‰Π΅ Ρ‚Π°ΠΊΠΈΠ΅ Ρ‚Π΅Ρ€ΠΌΠΈΠ½Ρ‹, ΠΊΠ°ΠΊ «повСрхностноС машинноС ΠΎΠ±ΡƒΡ‡Π΅Π½ΠΈΠ΅Β», «слабый ИИ», Β«ΡΠΈΠ»ΡŒΠ½Ρ‹ΠΉ ИИ»; сущСствуСт классификация понятий Β«Π³Π»ΡƒΠ±ΠΎΠΊΠΎΠ΅ ΠΎΠ±ΡƒΡ‡Π΅Π½ΠΈΠ΅Β», «машинноС ΠΎΠ±ΡƒΡ‡Π΅Π½ΠΈΠ΅Β» ΠΈ «искусствСнный ΠΈΠ½Ρ‚Π΅Π»Π»Π΅ΠΊΡ‚Β» (Π²ΠΎΡ‚, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ ΠΎΡ‚ Microsoft, Ρ‚Π°ΠΊΡƒΡŽ ΠΆΠ΅ структуру-ΠΌΠ°Ρ‚Ρ€Ρ‘ΡˆΠΊΡƒ дСмонстрируСт Ѐрансуа Π¨ΠΎΠ»Π»Π΅ Π² своСй ΠΊΠ½ΠΈΠ³Π΅ Β«Π“Π»ΡƒΠ±ΠΎΠΊΠΎΠ΅ ΠΎΠ±ΡƒΡ‡Π΅Π½ΠΈΠ΅ Π½Π° PythonΒ»), Π½ΠΎ сСйчас, ΠΏΠΎ ΠΊΡ€Π°ΠΉΠ½Π΅ΠΉ ΠΌΠ΅Ρ€Π΅ ΠΏΡ€ΠΈ Π½Π΅Ρ„ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½ΠΎΠΌ ΠΎΠ±Ρ‰Π΅Π½ΠΈΠΈ, всё Ρ‡Π°Ρ‰Π΅ ставится Π·Π½Π°ΠΊ равСнства ΠΌΠ΅ΠΆΠ΄Ρƒ Β«ΠΌΠ°ΡˆΠΈΠ½Π½Ρ‹ΠΌ ΠΎΠ±ΡƒΡ‡Π΅Π½ΠΈΠ΅ΠΌΒ» ΠΈ «искусствСнным ΠΈΠ½Ρ‚Π΅Π»Π»Π΅ΠΊΡ‚ΠΎΠΌΒ»; ΠΏΡ€ΠΈΡ‡Ρ‘ΠΌ Π² Ρ€Π°Π±ΠΎΡ‚Π΅, ΠΊΠ°ΠΊ ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ «машинноС ΠΎΠ±ΡƒΡ‡Π΅Π½ΠΈΠ΅Β», Π° ΠΏΡ€ΠΈ ΠΏΠΎΠ΄Π³ΠΎΡ‚ΠΎΠ²ΠΊΠ΅ ΠΏΡ€Π΅Π·Π΅Π½Ρ‚Π°Ρ†ΠΈΠΉ β€” «искусствСнный ΠΈΠ½Ρ‚Π΅Π»Π»Π΅ΠΊΡ‚Β» :) Π”Π΅Π»ΠΎ, ΠΏΠΎ всСй видимости, Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ Π³Π»ΡƒΠ±ΠΎΠΊΠΎΠ΅ ΠΎΠ±ΡƒΡ‡Π΅Π½ΠΈΠ΅ стало самой ΠΌΠ½ΠΎΠ³ΠΎΠΎΠ±Π΅Ρ‰Π°ΡŽΡ‰Π΅ΠΉ ΠΈ Π΄ΠΈΠ½Π°ΠΌΠΈΡ‡Π½ΠΎ Ρ€Π°Π·Π²ΠΈΠ²Π°ΡŽΡ‰Π΅ΠΉΡΡ ΠΎΠ±Π»Π°ΡΡ‚ΡŒΡŽ машинного обучСния, Π° искусствСнным ΠΈΠ½Ρ‚Π΅Π»Π»Π΅ΠΊΡ‚ΠΎΠΌ ΡƒΠΆΠ΅ Π΄Π°Π²Π½ΠΎ ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π»ΠΈ всю эту ΠΎΠ±Π»Π°ΡΡ‚ΡŒ Π·Π½Π°Π½ΠΈΠΉ ΠΊΠ°ΠΊ популяризаторы Π½Π°ΡƒΠΊΠΈ, Ρ‚Π°ΠΊ ΠΈ Турналисты.

Π’ ΠΎΠ±Ρ‰Π΅ΠΌ, ΠΏΡ€ΠΈ ΠΏΠ΅Ρ€Π²ΠΎΠ½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎΠΌ знакомствС с TensorFlow ΠΈΠ»ΠΈ PyTorch ΠΌΠΎΠΆΠ΅Ρ‚Π΅ смСло всСм Π³ΠΎΠ²ΠΎΡ€ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ Π·Π°Π½ΠΈΠΌΠ°Π΅Ρ‚Π΅ΡΡŒ AI, Π° Ссли Π·Π°Ρ…ΠΎΡ‚ΠΈΡ‚Π΅ ΡƒΠ³Π»ΡƒΠ±ΠΈΡ‚ΡŒΡΡ β€” ΡƒΠΆ Ρ‚Π΅Ρ€ΠΌΠΈΠ½ΠΎΠ»ΠΎΠ³ΠΈΠ΅ΠΉ-Ρ‚ΠΎ ΠΎΠ²Π»Π°Π΄Π΅Π΅Ρ‚Π΅.
Π§Ρ‚ΠΎ касаСтся сути Ρ€Π°Π±ΠΎΡ‚Ρ‹ Π½Π΅ΠΉΡ€ΠΎΠ½Π½Ρ‹Ρ… сСтСй, Ρ‚ΠΎ здСсь ΠΌΠΎΠΆΠ½ΠΎ Π²Ρ‹Π΄Π΅Π»ΠΈΡ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ основныС понятия:

ДатасСт β€” ΠΌΠ°Ρ€ΠΊΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹Π΅ для обучСния сСти ΠΈ для ΠΏΠΎΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ качСства этого обучСния. Π’Π°Ρ€ΠΈΠ°Π½Ρ‚ простого датасСта β€” коллСкция ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²ΠΎΠ³ΠΎ Ρ€Π°Π·ΠΌΠ΅Ρ€Π° с рукописными Ρ†ΠΈΡ„Ρ€Π°ΠΌΠΈ ΠΈ Π±ΡƒΠΊΠ²Π°ΠΌΠΈ, Π³Π΄Π΅ ΠΏΡ€ΠΎ ΠΊΠ°ΠΆΠ΄ΠΎΠ΅ ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ Ρ‚ΠΎΡ‡Π½ΠΎ извСстно, ΠΊΠ°ΠΊΠ°ΠΉ ΠΈΠΌΠ΅Π½Π½ΠΎ символ Π² Π½Ρ‘ΠΌ содСрТится; Ρ‚Π°ΠΊΠΎΠΉ датасСт Π½ΡƒΠΆΠ΅Π½ для Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ систСм распознавания рукописного тСкста (handwritten text recognition, HTR). Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ качСствСнных датасСтов β€” большая, тяТСлая Ρ€Π°Π±ΠΎΡ‚Π°, поэтому сСйчас ΠΈΠ΄Π΅Ρ‚ активная Ρ€Π°Π±ΠΎΡ‚Π° ΠΏΠΎ созданию ΠΌΠΎΠ΄Π΅Π»Π΅ΠΉ, способных Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ с большими ΠΎΠ±ΡŠΡ‘ΠΌΠ°ΠΌΠΈ Π½Π΅ΠΌΠ°Ρ€ΠΊΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ…. Как ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ, датасСт разбиваСтся Π½Π° Π΄Π²Π΅ части β€” для обучСния сСти ΠΈ для ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ качСства ΠΏΡ€ΠΎΠ²Π΅Π΄Π΅Π½Π½ΠΎΠ³ΠΎ обучСния.

Π˜ΡΠΊΡƒΡΡΡ‚Π²Π΅Π½Π½Π°Ρ нСйронная ΡΠ΅Ρ‚ΡŒ β€” ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½Ρ‹ΠΉ ΠΈΠ»ΠΈ Π°ΠΏΠΏΠ°Ρ€Π°Ρ‚Π½Ρ‹ΠΉ Π°Π½Π°Π»ΠΎΠ³ биологичСской Π½Π΅ΠΉΡ€ΠΎΠ½Π½ΠΎΠΉ сСти; Π² самом простом Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Π΅, Π² сСти прямого распространСния, это ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ соСдинСнныС слои Π½Π΅ΠΉΡ€ΠΎΠ½ΠΎΠ². ΠŸΠ΅Ρ€Π²Ρ‹Π΅ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ Π½Π΅ΠΉΡ€ΠΎΠ½Π½Ρ‹Ρ… сСтСй ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠ»ΠΈ практичСскоС Π²ΠΎΠΏΠ»ΠΎΡ‰Π΅Π½ΠΈΠ΅ Π΅Ρ‰Π΅ Π² 60-Ρ… Π³ΠΎΠ΄Π°Ρ… XX Π²Π΅ΠΊΠ°, хотя сущСствСнный прогрСсс ΠΈ практичСскоС Π²Π½Π΅Π΄Ρ€Π΅Π½ΠΈΠ΅ приходятся ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½ΠΎ Π½Π° послСдниС Π»Π΅Ρ‚ ΠΏΡΡ‚Π½Π°Π΄Ρ†Π°Ρ‚ΡŒ.

АрхитСктура искусствСнной Π½Π΅ΠΉΡ€ΠΎΠ½Π½ΠΎΠΉ сСти β€” опрСдСляСт ΠΎΠ±Ρ‰ΠΈΠ΅ ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΡ‹ Π΅Ρ‘ построСния, Π²ΠΎΡ‚ здСсь Π΅ΡΡ‚ΡŒ Ρ…ΠΎΡ€ΠΎΡˆΠ΅Π΅ Π²Π²Π΅Π΄Π΅Π½ΠΈΠ΅ Π² Ρ‚Π΅ΠΌΡƒ, наглядно ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ, Ρ‡Π΅ΠΌ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, GAN отличаСтся ΠΎΡ‚ LSTM.

ΠžΠ±ΡƒΡ‡Π΅Π½ΠΈΠ΅ Π½Π΅ΠΉΡ€ΠΎΠ½Π½ΠΎΠΉ сСти β€” Ссли Π² Π΄Π²ΡƒΡ… словах, Ρ‚ΠΎ это Π½Π°Ρ…ΠΎΠΆΠ΄Π΅Π½ΠΈΠ΅ коэффициСнтов связи ΠΌΠ΅ΠΆΠ΄Ρƒ Π½Π΅ΠΉΡ€ΠΎΠ½Π°ΠΌΠΈ. ΠŸΡ€ΠΈΠΌΠ΅Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΠΊ ΠΌΠ°ΡˆΠΈΠ½Π½ΠΎΠΌΡƒ ΠΎΠ±ΡƒΡ‡Π΅Π½ΠΈΡŽ замСняСт процСсс собствСнно программирования. Когда ΠΌΡ‹ Π³ΠΎΠ²ΠΎΡ€ΠΈΠΌ ΠΎ DALL-E 2, способном ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ изобраТСния ΠΏΠΎ тСкстовым описаниям ΠΈΠ»ΠΈ ΠΎΠ± AlphaGo, ΠΎΠ±Ρ‹Π³Ρ€Ρ‹Π²Π°ΡŽΡ‰Π΅ΠΌ ΠΏΡ€ΠΎΡ„Π΅ΡΡΠΈΠΎΠ½Π°Π»ΡŒΠ½Ρ‹Ρ… ΠΈΠ³Ρ€ΠΎΠΊΠΎΠ² Π² Π³ΠΎ β€” ΠΌΡ‹ Π³ΠΎΠ²ΠΎΡ€ΠΈΠΌ Π² ΠΏΠ΅Ρ€Π²ΡƒΡŽ ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ ΠΎΠ± ΠΎΠ±ΡƒΡ‡Π΅Π½Π½Ρ‹Ρ… Π½Π΅ΠΉΡ€ΠΎΠ½Π½Ρ‹Ρ… сСтях, создатСли ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… проявили Π±Π΅Π·Π΄Π½Ρƒ ΠΈΠ·ΠΎΠ±Ρ€Π΅Ρ‚Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ всС коэффициСнты связи Π±Ρ‹Π»ΠΈ Π½Π° своём мСстС. Π”ΠΎΠΎΠ±ΡƒΡ‡Π΅Π½ΠΈΠ΅ β€” частичная ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚ΠΈΡ€ΠΎΠ²ΠΊΠ° коэффициСнтов связи ΠΌΠ΅ΠΆΠ΄Ρƒ Π½Π΅ΠΉΡ€ΠΎΠ½Π°ΠΌΠΈ ΠΏΡ€ΠΈ ΠΌΠΎΠ΄ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ старого ΠΈΠ»ΠΈ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠΈ Π½ΠΎΠ²ΠΎΠ³ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»Π°.

Π—Π°Ρ‡Π΅ΠΌ Π½ΡƒΠΆΠ½ΠΎ машинноС ΠΎΠ±ΡƒΡ‡Π΅Π½ΠΈΠ΅? Π‘ΠΈΠ»ΡŒΠ½Ρ‹ΠΉ ИИ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π±ΡƒΠ΄Π΅Ρ‚ (скрСстим ΠΏΠ°Π»ΡŒΡ†Ρ‹) Ρ€Π΅ΡˆΠ°Ρ‚ΡŒ всС наши ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹ Π² Ρ€Π΅ΠΆΠΈΠΌΠ΅ Ρ€Π΅Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ, Π΅Ρ‰Π΅ Π·Π° Π³ΠΎΡ€ΠΈΠ·ΠΎΠ½Ρ‚ΠΎΠΌ; Π½ΠΎ ΡƒΠΆΠ΅ прямо сСйчас Π½Π΅ΠΉΡ€ΠΎΠ½Π½Ρ‹Π΅ сСти Ρ€Π΅ΡˆΠ°ΡŽΡ‚ Π·Π°Π΄Π°Ρ‡ΠΈ, Π½Π΅ΠΏΠΎΠ΄ΡŠΠ΅ΠΌΠ½Ρ‹Π΅ для классичСских Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΠΎΠ². МоТно Π»ΠΈ ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ Β«ΠΎΠ±Ρ‹Ρ‡Π½ΠΎΠ³ΠΎΒ» программирования Ρ€Π΅ΡˆΠΈΡ‚ΡŒ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π·Π°Π΄Π°Ρ‡Ρƒ распознавания отсканированного тСкста ΠΈΠ»ΠΈ ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄Π° с ΠΎΠ΄Π½ΠΎΠ³ΠΎ языка Π½Π° Π΄Ρ€ΡƒΠ³ΠΎΠΉ? Π”Π°, ΠΌΠΎΠΆΠ½ΠΎ, ΠΈ Ρ‚Π°ΠΊΠΈΠ΅ Π½Π΅Π±Π΅Π·ΡƒΡΠΏΠ΅ΡˆΠ½Ρ‹Π΅ ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΠΈ Π½Π΅ΠΎΠ΄Π½ΠΎΠΊΡ€Π°Ρ‚Π½ΠΎ ΠΏΡ€Π΅Π΄ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π»ΠΈΡΡŒ. Но, учитывая ΠΏΡ€ΠΎΡ€Ρ‹Π² Π² Ρ€Π°Π·Π²ΠΈΡ‚ΠΈΠΈ матСматичСской Π±Π°Π·Ρ‹ машинного обучСния, Π½Π°ΠΌΠ΅Ρ‚ΠΈΠ²ΡˆΠΈΠΉΡΡ Π² послСдниС 10-15 Π»Π΅Ρ‚, ΠΏΠΎΠΌΠ½ΠΎΠΆΠ΅Π½Π½Ρ‹ΠΉ Π½Π° гигантский прирост ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ Π΄Π°ΠΆΠ΅ ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹Ρ… повсСднСвных Π²Ρ‹Ρ‡ΠΈΡΠ»ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… устройств, Π²Ρ€ΠΎΠ΄Π΅ смартфонов, фактичСски ΠΈ распознаваниС, ΠΈ ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄ сСйчас Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΡŽΡ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ машинного обучСния. Для Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… ΠΆΠ΅ классов Π·Π°Π΄Π°Ρ‡, Ρ‚Π°ΠΊΠΈΡ… ΠΊΠ°ΠΊ распознаваниС ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ ΠΈ Π²ΠΈΠ΄Π΅ΠΎ с ΠΏΠΎΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ классификациСй ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² ΠΈΠ»ΠΈ бСспилотная транспортировка, Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ Π½Π° Π±Π°Π·Π΅ классичСских Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΠΎΠ² Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ Π·Π°Ρ…ΠΎΠ΄ΠΈΠ»ΠΈ дальшС вялотСкущих ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ‚ΠΎΠ².

Мало-ΠΏΠΎΠΌΠ°Π»Ρƒ машинноС ΠΎΠ±ΡƒΡ‡Π΅Π½ΠΈΠ΅ Π΄Π΅Π»Π°Π΅Ρ‚ Π½Π°ΡˆΡƒ Тизнь Π»ΡƒΡ‡ΡˆΠ΅. Π‘ΠΎ Π²Ρ€Π΅ΠΌΠ΅Π½Π΅ΠΌ, надСюсь, ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΈΠ· нас смоТСт Π²ΠΎΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ ΠΏΠ»ΠΎΠ΄Π°ΠΌΠΈ Ρ€Π°Π±ΠΎΡ‚Ρ‹ искусствСнного ΠΈΠ½Ρ‚Π΅Π»Π»Π΅ΠΊΡ‚Π°, Ρ…ΠΎΡ‚ΡŒ ΠΌΡ‹ ΠΈ Π²Π΅Π»ΠΈΡ‡Π°Π΅ΠΌ Π΅Π³ΠΎ «слабым». И Ρ€Π΅Ρ‡ΡŒ ΠΈΠ΄Π΅Ρ‚ Π½Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎ Π³Ρ€ΠΎΠΌΠΊΠΈΡ… ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°Ρ…, Π²Ρ€ΠΎΠ΄Π΅ Π°Π²Ρ‚ΠΎΠΏΠΈΠ»ΠΎΡ‚Π° «ВСслы» (хотя ΠΈ это ΠΊΡ€Π°ΠΉΠ½Π΅ Π½Π΅ΠΌΠ°Π»ΠΎΠ²Π°ΠΆΠ½ΠΎ), Π½ΠΎ Π² ΠΏΠ΅Ρ€Π²ΡƒΡŽ ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ ΠΎ постоянном сканировании эксабайтных ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ, ΠΏΠΎΡ€ΠΎΠΆΠ΄Π°Π΅ΠΌΡ‹Ρ… соврСмСнной Ρ†ΠΈΡ„Ρ€ΠΎΠ²ΠΎΠΉ Ρ†ΠΈΠ²ΠΈΠ»ΠΈΠ·Π°Ρ†ΠΈΠ΅ΠΉ β€” Π²ΠΈΠ΄Π΅ΠΎ с ΡƒΠ»ΠΈΡ‡Π½Ρ‹Ρ… ΠΊΠ°ΠΌΠ΅Ρ€, сканов МРВ ΠΈ КВ, Ρ‚Π΅Π»Π΅ΠΌΠ΅Ρ‚Ρ€ΠΈΠΈ с фитнСс-браслСтов, ΠΎΡ‚Ρ‡Π΅Ρ‚ΠΎΠ² ΠΎΠ± исслСдовании лСкарствСнных срСдств ΠΈ ΠΏΠΈΡ‰Π΅Π²Ρ‹Ρ… Π΄ΠΎΠ±Π°Π²ΠΎΠΊ. И Ссли всё это ΠΏΡ€ΠΎΠΉΠ΄Π΅Ρ‚ ΠΏΠ΅Ρ€Π΅Π΄, ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ, ΠΏΠΎΠΊΠ° Π½Π΅ ΠΎΡ‡Π΅Π½ΡŒ ΡƒΠΌΠ½Ρ‹ΠΌΠΈ, Π½ΠΎ Π·Π°Ρ‚ΠΎ нСустанными Π³Π»Π°Π·Π°ΠΌΠΈ ΠΏΡ€Π΅Π΄Π²Π°Ρ€ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ ΠΎΠ±ΡƒΡ‡Π΅Π½Π½ΠΎΠΉ Π½Π΅ΠΉΡ€ΠΎΠ½Π½ΠΎΠΉ сСти, Ρ‚ΠΎ ΠΊΡ€Π°Ρ‚Π½ΠΎ ΡƒΠΌΠ΅Π½ΡŒΡˆΠΈΡ‚ΡΡ Π½Π΅Π²Π΅Ρ€Π½Ρ‹Ρ… Π΄ΠΈΠ°Π³Π½ΠΎΠ·ΠΎΠ², людСй, ΡƒΠΌΠ΅Ρ€ΡˆΠΈΡ… ΠΎΡ‚ ΠΈΠ½ΡΡƒΠ»ΡŒΡ‚ΠΎΠ² ΠΈΠ»ΠΈ Π·Π°ΠΌΠ΅Ρ€Π·ΡˆΠΈΡ… Π½Π° ΡƒΠ»ΠΈΡ†Π°Ρ…, Π° Ρ‚Π°ΠΊΠΆΠ΅ лСкарств с тяТСлыми ΠΏΠΎΠ±ΠΎΡ‡Π½Ρ‹ΠΌΠΈ эффСктами.

Но ΠΏΠΎΠΌΠ½ΠΈΡ‚Π΅, ΠΎΠ΄Π½Π°ΠΊΠΎ β€” Π΄Π°ΠΆΠ΅ Ссли Π²Ρ‹ ΠΏΠΎΠ»Π½Ρ‹ энтузиазма ΠΈ Π³ΠΎΡ‚ΠΎΠ²Ρ‹ Ρ…ΠΎΡ‚ΡŒ прямо сСйчас Π½Ρ‹Ρ€Π½ΡƒΡ‚ΡŒ Π²ΠΎ всС эти ΠΌΠΎΠ΄Π½Ρ‹Π΅, интСрСсныС ΠΈ Π°ΠΊΡ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹Π΅ сущности Π²Ρ€ΠΎΠ΄Π΅ Π±ΠΈΠ³Π΄Π°Ρ‚Ρ‹ ΠΈΠ»ΠΈ ИИ β€” Ρ‡Π΅ΠΌ дальшС Π²Ρ‹ Π±ΡƒΠ΄Π΅Ρ‚Π΅ ΡƒΠ³Π»ΡƒΠ±Π»ΡΡ‚ΡŒΡΡ Π² эту Ρ‚Π΅ΠΌΠ°Ρ‚ΠΈΠΊΡƒ, Ρ‚Π΅ΠΌ мСньшС Π² вас Π±ΡƒΠ΄Π΅Ρ‚ программиста, Ρ‚Π΅ΠΌ большС исслСдоватСля, ΡƒΡ‡Ρ‘Π½ΠΎΠ³ΠΎ, ΠΌΠ°Ρ‚Π΅ΠΌΠ°Ρ‚ΠΈΠΊΠ°. Π“Π΄Π΅-Ρ‚ΠΎ Π² самом ΠΊΠΎΠ½Ρ†Π΅ этого Π΄Π»ΠΈΠ½Π½ΠΎΠ³ΠΎ-ΠΏΡ€Π΅Π΄Π»ΠΈΠ½Π½ΠΎΠ³ΠΎ ΠΊΠΎΡ€ΠΈΠ΄ΠΎΡ€Π° сидит вовсС Π½Π΅ НСо ΠΈΠ· Β«ΠœΠ°Ρ‚Ρ€ΠΈΡ†Ρ‹Β», Π° эдакий сСбС Π“Ρ€ΠΈΠ³ΠΎΡ€ΠΈΠΉ ΠŸΠ΅Ρ€Π΅Π»ΡŒΠΌΠ°Π½, ΡƒΡΡ‚Π°Π²ΡˆΠΈΠΉ Ρ‡Π΅Π»ΠΎΠ²Π΅ΠΊ с Ρ€ΡƒΡ‡ΠΊΠΎΠΉ ΠΈ листом Π±ΡƒΠΌΠ°Π³ΠΈ, ΠΈΠ½ΠΎΠ³Π΄Π° этой Ρ€ΡƒΡ‡ΠΊΠΎΠΉ Π½Π° этой Π±ΡƒΠΌΠ°Π³Π΅ ΠΏΠΈΡˆΡƒΡ‰ΠΈΠΉ Π²Π΅Ρ‰ΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΏΠΎΡ‚ΠΎΠΌ приходится Π΄Π²Π° Π³ΠΎΠ΄Π° Ρ€Π°Π·ΠΆΠ΅Π²Ρ‹Π²Π°Ρ‚ΡŒ Π»ΡƒΡ‡ΡˆΠΈΠΌ ΠΌΠ°Ρ‚Π΅ΠΌΠ°Ρ‚ΠΈΠΊΠ°ΠΌ ΠΌΠΈΡ€Π°. ΠšΡ€Π΅ΠΏΠΊΠΎ ΠΏΠΎΠ΄ΡƒΠΌΠ°ΠΉΡ‚Π΅, ΠΊΠ°ΠΊ Π³Π»ΡƒΠ±ΠΎΠΊΠΎ Π²Ρ‹ Ρ…ΠΎΡ‚ΠΈΡ‚Π΅ ΠΈ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π·Π°ΠΉΡ‚ΠΈ, Π²Π·Π²Π΅ΡΡŒΡ‚Π΅ свои силы.

3. ΠŸΠΎΡ‚ΠΎΠΊΠΈ Π΄Π°Π½Π½Ρ‹Ρ…

«И Π½Π΅ Π²ΠΈΠ΄Π΅Π»ΠΈ ΠΌΡ‹ Π½ΠΈ ΠΎΠ΄Π½ΠΎΠΉ Ρ‚Ρ€Π°Π²Ρ‹, которая Π½Π΅ Ρ†Π²Π΅Π»Π° Π±Ρ‹, ΠΈ Π½ΠΈ ΠΎΠ΄Π½ΠΎΠ³ΠΎ Π΄Π΅Ρ€Π΅Π²Π°, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π½Π΅ плодоносило Π±Ρ‹. Камни ΠΆΠ΅ Ρ‚Π°ΠΌ β€” Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π΄Ρ€Π°Π³ΠΎΡ†Π΅Π½Π½Ρ‹Π΅Β».

«ПлаваниС святого Π‘Ρ€Π΅Π½Π΄Π°Π½Π°Β».

Data Flows

Itertools

ΠœΠ΅Ρ‚ΠΎΠ΄Ρ‹ модуля itertools Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‚ ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹.

Π˜Ρ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€ β€” ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ поэлСмСнтного ΠΎΠ±Ρ…ΠΎΠ΄Π° Π΄Π°Π½Π½Ρ‹Ρ…, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ ΠΌΠ΅Ρ‚ΠΎΠ΄ next() для получСния ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π³ΠΎ значСния ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ. ΠŸΠΎΠ΄Ρ€ΠΎΠ±Π½Π΅Π΅ созданиС ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠ² Π±ΡƒΠ΄Π΅Ρ‚ рассмотрСно Π½ΠΈΠΆΠ΅, Π² Ρ€Π°Π·Π΄Π΅Π»Π΅ «ООП / Утиная типизация». Π’ Β«Π½ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½Ρ‹Π΅Β» Π΄Π°Π½Π½Ρ‹Π΅ ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹ ΠΏΠ΅Ρ€Π΅Π³ΠΎΠ½ΡΡŽΡ‚ΡΡ ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ for, next ΠΈΠ»ΠΈ list().

Itertools содСрТит мноТСство Π³ΠΎΡ‚ΠΎΠ²Ρ‹Ρ… ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠ², ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ бСсконСчными (ΠΏΠΎΡ€ΠΎΠΆΠ΄Π°ΡŽΡ‚ΡΡ ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ count, cycle ΠΈΠ»ΠΈ repeat), ΠΊΠΎΠ½Π΅Ρ‡Π½Ρ‹ΠΌΠΈ (accumulate, chain, takewhile ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠ΅) ΠΈ ΠΊΠΎΠΌΠ±ΠΈΠ½Π°Ρ‚ΠΎΡ€Π½Ρ‹ΠΌΠΈ (product, combinations, combinations_with_replacement, permutations). Π›ΡƒΡ‡ΡˆΠ΅ ΠΈΠ·ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΈΡ… всС, хотя Π±Ρ‹ повСрхностно, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ Π΄Π°ΠΆΠ΅ ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Ρ€Π΅Π΄ΠΊΠΎ употрСбляСмый ΠΌΠ΅Ρ‚ΠΎΠ΄, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΊΠ°ΠΊΠΎΠΉ-Π½ΠΈΠ±ΡƒΠ΄ΡŒ zip_longest(), ΠΈΠ½ΠΎΠ³Π΄Π° вСсьма ΠΈ вСсьма пригоТдаСтся, идСально лоТась Π½Π° ΠΏΠΎΡΡ‚Π°Π²Π»Π΅Π½Π½ΡƒΡŽ Π·Π°Π΄Π°Ρ‡Ρƒ.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ Ρ€Π°Π±ΠΎΡ‚Ρ‹ с бСсконСчными ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€Π°ΠΌΠΈ:

from itertools import count, repeat, cycle

# Π˜Ρ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€, Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‰ΠΈΠΉ Ρ€Π°Π²Π½ΠΎΠΌΠ΅Ρ€Π½ΠΎ распрСдСлСнныС значСния
i1 = count(start=0, step=.1)
print(next(i1))
print(next(i1))
print(next(i1))

# Π˜Ρ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€, Ρ†ΠΈΠΊΠ»ΠΈΡ‡Π½ΠΎ ΠΈ бСсконСчно Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‰ΠΈΠΉ элСмСнты ΠΈΡ‚Π΅Ρ€ΠΈΡ€ΡƒΠ΅ΠΌΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°
i2 = cycle([1, 2])
print(next(i2))
print(next(i2))
print(next(i2))

# Π˜Ρ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€, Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‰ΠΈΠΉ ΠΎΠ΄ΠΈΠ½ ΠΈ Ρ‚ΠΎΡ‚ ΠΆΠ΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ бСсконСчно, Ссли Π½Π΅ ΡƒΠΊΠ°Π·Π°Π½ΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π° times
i3 = repeat("Wow!", times=3)
print(list(i3))
0
0.1
0.2
1
2
1
['Wow!', 'Wow!', 'Wow!']

ΠŸΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… ΠΊΠΎΠ½Π΅Ρ‡Π½Ρ‹Ρ… ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠ²:

from itertools import accumulate, chain, compress, dropwhile, takewhile, pairwise
import operator

# Π˜Ρ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€, Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‰ΠΈΠΉ Π½Π°ΠΊΠΎΠΏΠ»Π΅Π½Π½Ρ‹ΠΉ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ выполнСния ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ (ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ β€” слоТСниС)

i1 = accumulate([1, 2, 3, 4])
i2 = accumulate([1, 2, 3, 4], initial=10)
print(list(i1), list(i2))

i3 = accumulate([ -3, -2, -1, 1, 2, 3, 4], operator.mul)
print(list(i3))

# МоТно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ свою Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ
def myfunc(accumulated, current):
    return accumulated + 2 * current

i4 = accumulate([1, 2, 3, 4], func=myfunc)
print(list(i4))

# МоТно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ лямбду (ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½Π΅Π΅ рассмотрСны Π½ΠΈΠΆΠ΅)
i5 = accumulate([1, 2, 3, 4], lambda accumulated, current: accumulated + 2 * current)
print(list(i5))

# Π˜Ρ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€, Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‰ΠΈΠΉ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‚Π΅ элСмСнты Π²Ρ…ΠΎΠ΄Π½ΠΎΠΉ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ,
# ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΈΠΌΠ΅ΡŽΡ‚ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ элСмСнт, Ρ€Π°Π²Π½Ρ‹ΠΉ True ΠΈΠ»ΠΈ 1 Π² ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ selectors
i6 = compress("ABCDEF", [1, 1, 1, 0, 0, 1])
print(list(i6))

# Π˜Ρ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€, ΠΎΡ‚Π±Ρ€Π°ΡΡ‹Π²Π°ΡŽΡ‰ΠΈΠΉ элСмСнты Π²Ρ…ΠΎΠ΄Π½ΠΎΠΉ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ, Ссли Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ выполнСния Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Ρ€Π°Π²Π΅Π½ True.
# Как Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΡ€Π΅Π΄ΠΈΠΊΠ°Ρ‚ становится False, Ρ‚ΠΎ отбрасываниС прСкращаСтся (ΠΏΡ€Π΅Π΄ΠΈΠΊΠ°Ρ‚ большС Π½Π΅ примСняСтся)
i7 = dropwhile(lambda x: x<5, [1, 4, 6, 4, 1, 1, 1, 0])
print(list(i7))

# takewhile, Π² ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ ΠΎΡ‚ dropwhile, Π½Π°ΠΎΠ±ΠΎΡ€ΠΎΡ‚, Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ элСмСнты Π²Ρ…ΠΎΠ΄Π½ΠΎΠΉ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ,
# Ссли Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ выполнСния Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Ρ€Π°Π²Π΅Π½ True
i8 = takewhile(lambda x: x<5, [1, 4, 6, 0, 4, 1, 2, 1])
print(list(i8))

# Π˜Ρ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€, Ρ„ΠΎΡ€ΠΌΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ ΠΈΠ· Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… Π²Ρ…ΠΎΠ΄Π½Ρ‹Ρ… ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚Π΅ΠΉ ΠΎΠ΄Π½Ρƒ ΠΎΠ±Ρ‰ΡƒΡŽ
i2 = chain(["A", "B", "C"],["D", "E", "F"],["G", "H", "I"])
print(list(i2))
# ΠšΡΡ‚Π°Ρ‚ΠΈ, Ρ‚Π°ΠΊΠΎΠΉ ΠΆΠ΅ Ρ‚Ρ€ΡŽΠΊ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡ€ΠΎΠ²Π΅Ρ€Π½ΡƒΡ‚ΡŒ ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎΠΉ sum(), Π·Π°Π΄Π°Π² Π΅ΠΉ Π½Π°Ρ‡Π°Π»ΡŒΠ½Ρ‹ΠΉ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ [] (Ρ‚. Π΅. пустой список)
a = sum([["A", "B", "C"],["D", "E", "F"],["G", "H", "I"]], [])
print(a)

# Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ элСмСнты Π²Ρ…ΠΎΠ΄Π½ΠΎΠΉ ΠΊΠΎΠ»Π»Π΅ΠΊΡ†ΠΈΠΈ ΠΏΠΎΠΏΠ°Ρ€Π½ΠΎ
i6 = pairwise([1, 2, 3, 4, 5])
print(list(i6))
[1, 3, 6, 10] [10, 11, 13, 16, 20]
[-3, 6, -6, -6, -12, -36, -144]
[1, 5, 11, 19]
[1, 5, 11, 19]
['A', 'B', 'C', 'F']
[6, 4, 1, 1, 1, 0]
[1, 4]
['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I']
['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I']
[(1, 2), (2, 3), (3, 4), (4, 5)]

ΠšΠΎΠΌΠ±ΠΈΠ½Π°Ρ‚ΠΎΡ€ΠΈΠΊΠ°

from itertools import product, combinations, combinations_with_replacement, permutations

# Π‘ΠΎΠ·Π΄Π°Π΅Ρ‚ мноТСство, содСрТащСС всС упорядочСнныС ΠΏΠ°Ρ€Ρ‹ элСмСнтов ΠΈΠ· Π²Ρ…ΠΎΠ΄Π½Ρ‹Ρ… мноТСств
a = product("abc", "xyz")
print(list(a))

b = product([0, 1], repeat=3)
print(list(b))

# Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΏΠΎΠ΄ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ Π΄Π»ΠΈΠ½Ρ‹ r ΠΈΠ· элСмСнтов Π²Ρ…ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΈΡ‚Π΅Ρ€ΠΈΡ€ΡƒΠ΅ΠΌΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°, ΠΏΠΎΠ²Ρ‚ΠΎΡ€ΡΡŽΡ‰ΠΈΠ΅ΡΡ элСмСнты Π½Π΅ Π΄ΠΎΠΏΡƒΡΠΊΠ°ΡŽΡ‚ΡΡ
c = combinations("abc", r=2)
print(list(c))

# Π’Ρ‹Π΄Π°Π΅Ρ‚ пСрСстановки элСмСнтов ΠΈΡ‚Π΅Ρ€ΠΈΡ€ΡƒΠ΅ΠΌΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°
d = permutations("abc", r=2)
print(list(d))

# Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΏΠΎΠ΄ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ Π΄Π»ΠΈΠ½Ρ‹ r ΠΈΠ· элСмСнтов Π²Ρ…ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΈΡ‚Π΅Ρ€ΠΈΡ€ΡƒΠ΅ΠΌΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°, ΠΏΠΎΠ²Ρ‚ΠΎΡ€ΡΡŽΡ‰ΠΈΠ΅ΡΡ элСмСнты допустимы
e = combinations_with_replacement("abc", r=2)
print(list(e))
[('a', 'x'), ('a', 'y'), ('a', 'z'), ('b', 'x'), ('b', 'y'), ('b', 'z'), ('c', 'x'), ('c', 'y'), ('c', 'z')]
[(0, 0, 0), (0, 0, 1), (0, 1, 0), (0, 1, 1), (1, 0, 0), (1, 0, 1), (1, 1, 0), (1, 1, 1)]
[('a', 'b'), ('a', 'c'), ('b', 'c')]
[('a', 'b'), ('a', 'c'), ('b', 'a'), ('b', 'c'), ('c', 'a'), ('c', 'b')]
[('a', 'a'), ('a', 'b'), ('a', 'c'), ('b', 'b'), ('b', 'c'), ('c', 'c')]

Enumerate

Иногда, ΠΏΡ€ΠΈ ΠΏΠ΅Ρ€Π΅Π±ΠΎΡ€Π΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² Π² Ρ†ΠΈΠΊΠ»Π΅ for, Π½ΡƒΠΆΠ½ΠΎ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ Π½Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ сам ΠΎΠ±ΡŠΠ΅ΠΊΡ‚, Π½ΠΎ ΠΈ Π΅Π³ΠΎ порядковый Π½ΠΎΠΌΠ΅Ρ€. РазумССтся, это ΠΌΠΎΠΆΠ½ΠΎ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ, создав Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΡƒΡŽ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ, которая Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΠ½ΠΊΡ€Π΅ΠΌΠ΅Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒΡΡ Π½Π° ΠΊΠ°ΠΆΠ΄ΠΎΠΌ шагС Ρ†ΠΈΠΊΠ»Π°. Однако, Π³ΠΎΡ€Π°Π·Π΄ΠΎ ΡƒΠ΄ΠΎΠ±Π½Π΅Π΅ это Π΄Π΅Π»Π°Ρ‚ΡŒ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€Π° enumerate, Π²Π²Π΅Π΄Π΅Π½Π½Ρ‹ΠΌ Π² PEP-279. Enumerate β€” синтаксичСский сахар (Β«introduces ... to simplify a commonly used looping idiomΒ»), ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‰ΠΈΠΉ ΠΏΡ€ΠΎΡ‰Π΅ ΠΈ нагляднСС Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ с ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°ΠΌΠΈ, ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‰ΠΈΠΌΠΈ ΠΈΡ‚Π΅Ρ€Π°Ρ†ΠΈΡŽ. ΠœΠ΅Ρ‚ΠΎΠ΄ __next__() enumerate Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΊΠΎΡ€Ρ‚Π΅ΠΆ, содСрТащий Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ индСкса ΠΈ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅Π΅ этому индСксу Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅.

Π’ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ Ρ€Π°Π±ΠΎΡ‚Π° enumerate ΡƒΠΏΡ€ΠΎΡ‰Π΅Π½Π½ΠΎ ΠΎΠ±ΡŠΡΡΠ½ΡΠ΅Ρ‚ΡΡ Ρ‡Π΅Ρ€Π΅Π· Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€:

def enumerate(sequence, start=0):
    n = start
    for elem in sequence:
        yield n, elem
        n += 1

На самом Π΄Π΅Π»Π΅ enumerate β€” Π½Π΅ Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€, Π° ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€:

import collections
import types

e = enumerate("abcdef")
print(isinstance(e, enumerate))
print(isinstance(e, collections.Iterable))
print(isinstance(e, collections.Iterator))
print(isinstance(e, types.GeneratorType))
True
True
True
False

Enumerate Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½ Π½Π΅ Π½Π° Python, Π° Π½Π° C, ΠΈ Π² Π΅Π³ΠΎ исходном ΠΊΠΎΠ΄Π΅, разумССтся, Π½Π΅Ρ‚ ΠΊΠ»ΡŽΡ‡Π΅Π²ΠΎΠ³ΠΎ слова yield.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ использования enumerate:

values = ["a", "b", "c", "d"]

for count, value in enumerate(values):
    print(count, value)

print("\n")

for count, value in enumerate(values, start=10 ):
    print(count, value)
0 a
1 b
2 c
3 d


10 a
11 b
12 c
13 d

Π“Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€ (generator)

Π›ΡŽΠ±Π°Ρ функция, содСрТащая ΠΊΠ»ΡŽΡ‡Π΅Π²ΠΎΠ΅ слово yield, Π²Π΅Ρ€Π½Π΅Ρ‚ Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€. Π“Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€ Π½Π΅ Ρ…Ρ€Π°Π½ΠΈΡ‚ Π² памяти всС Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Π΅ элСмСнты, Π° просто содСрТит ΠΌΠ΅Ρ‚ΠΎΠ΄ для вычислСния ΠΎΡ‡Π΅Ρ€Π΅Π΄Π½ΠΎΠ³ΠΎ элСмСнта; Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ ΠΌΠΎΠΆΠ΅Ρ‚ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒΡΡ Π½Π° основС матСматичСского Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΠ° ΠΈΠ»ΠΈ Π±Ρ€Π°Ρ‚ΡŒ элСмСнты ΠΈΠ· Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ источника Π΄Π°Π½Π½Ρ‹Ρ… (коллСкция, Ρ„Π°ΠΉΠ», сСтСвоС ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΠΈ Ρ‚. Π΄.), ΠΏΡ€ΠΈ нСобходимости модифицируя ΠΈΡ….

ΠŸΡ€ΠΎΠΉΡ‚ΠΈ Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€ Π² Ρ†ΠΈΠΊΠ»Π΅ ΠΌΠΎΠΆΠ½ΠΎ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄ΠΈΠ½ Ρ€Π°Π·, Π½Π° ΠΊΠ°ΠΆΠ΄ΠΎΠΌ шагС Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ Π²Ρ‹Ρ‡ΠΈΡΠ»ΠΈΡ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ элСмСнт, Π½ΠΎ Π½Π΅ ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰ΠΈΠΉ. Π­Π»Π΅ΠΌΠ΅Π½Ρ‚ Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€Π° нСльзя ΠΈΠ·Π²Π»Π΅Ρ‡ΡŒ ΠΏΠΎ индСксу, Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹Π±Ρ€ΠΎΡˆΠ΅Π½Π° ошибка, Ρ‚. ΠΊ. Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€ Π½Π΅ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ ΠΌΠ΅Ρ‚ΠΎΠ΄ __getitem__().

БСсконСчный Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€:

def count(start, step):
    current = start
    while True:
        yield current
        current += step

c = count(100, 10)

print(next(c))
print(next(c))
print(next(c))
100
110
120

ΠšΠΎΠ½Π΅Ρ‡Π½Ρ‹ΠΉ Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€. Π’Π°ΠΊΠΆΠ΅, ΠΊΠ°ΠΊ ΠΈ ΠΊΠΎΠ½Π΅Ρ‡Π½Ρ‹ΠΉ ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€, ΠΊΠΎΠ½Π΅Ρ‡Π½Ρ‹ΠΉ Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡ€Π΅Π²Ρ€Π°Ρ‚ΠΈΡ‚ΡŒ Π² список ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ list() (Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΏΠΎΠΏΡ€ΠΎΠ±ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΡ€Π΅Π²Ρ€Π°Ρ‚ΠΈΡ‚ΡŒ Π² list ΠΈ бСсконСчный Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€, Π½ΠΎ процСсс рискуСт нСсколько Π·Π°Ρ‚ΡΠ½ΡƒΡ‚ΡŒΡΡ :):

def count(start, stop, step):
    current = start
    while current <= stop:
        yield current
        current += step

c = count(100, 200, 10)

print(next(c))
print(next(c))
print(next(c))
print(list(c))
100
110
120
[130, 140, 150, 160, 170, 180, 190, 200]

Π‘Π»Π΅Π΄ΡƒΠ΅Ρ‚ Ρ€Π°Π·Π΄Π΅Π»ΡΡ‚ΡŒ ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹ ΠΈ Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹. Π˜Ρ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€ β€” ΠΎΠ±ΡŠΠ΅ΠΊΡ‚, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ ΠΌΠ΅Ρ‚ΠΎΠ΄ __next__() для получСния ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π³ΠΎ значСния ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ. Π“Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€ β€” функция, которая позволяСт ΠΎΡ‚Π»ΠΎΠΆΠ΅Π½ΠΎ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ ΠΏΡ€ΠΈ ΠΈΡ‚Π΅Ρ€Π°Ρ†ΠΈΠΈ.

ОбъявлСниС Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€Π°

ΠžΠ±ΡŠΡΠ²ΠΈΡ‚ΡŒ Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€ ΠΌΠΎΠΆΠ½ΠΎ нСсколькими ΠΌΠ΅Ρ‚ΠΎΠ΄Π°ΠΌΠΈ. ΠŸΠ΅Ρ€Π²Ρ‹ΠΉ ΠΌΠ΅Ρ‚ΠΎΠ΄ β€” ΠΎΠ±ΡŠΡΠ²ΠΈΡ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ с yield, ΠΊΠ°ΠΊ Π±Ρ‹Π»ΠΎ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ Π²Ρ‹ΡˆΠ΅.
Π’Ρ‚ΠΎΡ€ΠΎΠΉ ΠΌΠ΅Ρ‚ΠΎΠ΄ β€” ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€Π½ΠΎΠ΅ Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ (generator expression):

r = range(1, 11)
squares = (n**2 for n in r)

print(list(squares))
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

МоТно ΠΎΠ±ΡŠΠ΅Π΄ΠΈΠ½ΠΈΡ‚ΡŒ Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹ ΠΈΠ»ΠΈ Π΄Π΅Π»Π΅Π³ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Ρ‡Π°ΡΡ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»Π° Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€Π° Π΄Ρ€ΡƒΠ³ΠΎΠΌΡƒ Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€Ρƒ ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ конструкции yield from:

def subg():
    yield 'World'

def generator():
    yield 'Hello'
    yield from subg()
    yield '!'

for i in generator():
    print(i, end = ' ')
Hello World ! 

Π”ΠΎ ΡˆΠΈΡ€ΠΎΠΊΠΎΠ³ΠΎ распространСния asyncio конструкция yield from использовалась для создания ΠΊΠΎΡ€ΡƒΡ‚ΠΈΠ½ Π½Π° Π±Π°Π·Π΅ Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠ².

Π”Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€Ρ‹

Π§Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠ΅ Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€Ρ‹?

Π”Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ Π² ΡˆΠΈΡ€ΠΎΠΊΠΎΠΌ смыслС – ΠΏΠ°Ρ‚Ρ‚Π΅Ρ€Π½ проСктирования, ΠΊΠΎΠ³Π΄Π° ΠΎΠ΄ΠΈΠ½ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ измСняСт ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ. Π”Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€Ρ‹ β€” это, ΠΏΠΎ сути, своСобразныС Β«ΠΎΠ±Ρ‘Ρ€Ρ‚ΠΊΠΈΒ», ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π΄Π°ΡŽΡ‚ Π½Π°ΠΌ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ Π΄Π΅Π»Π°Ρ‚ΡŒ Ρ‡Ρ‚ΠΎ-Π»ΠΈΠ±ΠΎ Π΄ΠΎ ΠΈΠ»ΠΈ послС Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ сдСлаСт дСкорируСмая функция, Π½Π΅ измСняя Π΅Ρ‘. МоТно ΡΠΊΠ°Π·Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ являСтся просто синтаксичСским сахаром для конструкции Π²ΠΈΠ΄Π°:

my_function = my_decorator(my_function)
def makebold(fn):
    def wrapped():
        return "<b>" + fn() + "</b>"

    return wrapped


def makeitalic(fn):
    def wrapped():
        return "<i>" + fn() + "</i>"

    return wrapped

# РазумССтся, ΠΏΡ€ΠΈ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠΌ ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠΈ Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ΠΎΠ² ΠΈΠ³Ρ€Π°Π΅Ρ‚ Ρ€ΠΎΠ»ΡŒ порядок дСкорирования.
@makebold
@makeitalic
def hello():
    return "Hello, world!"

print(hello())
<b><i>Hello, world!</i></b>

Π”Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€, ΠΏΠΎΠ΄ΡΡ‡ΠΈΡ‚Ρ‹Π²Π°ΡŽΡ‰ΠΈΠΉ врСмя Ρ€Π°Π±ΠΎΡ‚Ρ‹ ΠΎΠ±ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌΠΎΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ:

import time

def perf_counter(function):
    def counted(*args):
        start_time = time.perf_counter_ns()
        res = function(*args)
        print(f"{time.perf_counter_ns() - start_time} ns")
        return res

    return counted


@perf_counter
def slow_sum(x, y):
    time.sleep(1)
    return x + y


print(slow_sum(1, 2))
1002478400 ns
3

LRU Cache

Π”Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€, ΠΊΠ΅ΡˆΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ значСния, Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΡ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ. ВсС Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Ρ‹ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ Ρ…ΡΡˆΠΈΡ€ΡƒΠ΅ΠΌΡ‹.

import functools


def recursion_sum(n):
    if n == 1:
        return n
    print(n, end=" ")
    return n + recursion_sum(n - 1)


recursion_sum(5)
print("\n")
recursion_sum(9)
print("\n")


@functools.lru_cache
def recursion_sum2(n):
    if n == 1:
        return n
    print(n, end=" ")
    return n + recursion_sum2(n - 1)


recursion_sum2(5)
print("\n")
recursion_sum2(9)
5 4 3 2 

9 8 7 6 5 4 3 2 

5 4 3 2 

9 8 7 6 




45

Π Π°Π·ΠΌΠ΅Ρ€ кСша ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ 128 Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ. ΠžΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ½ΠΎ ΠΎΡ‚ΠΌΠ΅Π½ΠΈΡ‚ΡŒ ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ 'maxsize=None'.

Пока ΠΌΡ‹ Π½Π΅ ΡƒΡˆΠ»ΠΈ Π΄Π°Π»Π΅ΠΊΠΎ ΠΎΡ‚ Ρ‚Π΅ΠΌΡ‹ кСша, ΠΏΠΎΠ³ΡƒΠ³Π»ΠΈΡ‚Π΅ Π·Π°ΠΎΠ΄Π½ΠΎ ΠΌΠΎΠ΄ΡƒΠ»ΡŒ weakref ΠΈ WeakValueDictionary, ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‰ΠΈΠ΅ ΠΎΡ€Π³Π°Π½ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π±ΠΎΠ»Π΅Π΅ Π³ΠΈΠ±ΠΊΡƒΡŽ Ρ€Π°Π±ΠΎΡ‚Ρƒ с кСшСм.

ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈΠ·ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€

Π’ Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ ΠΈ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΎΠ½Π½Ρ‹Π΅, ΠΈ ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½Π½Ρ‹Π΅ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Ρ‹ β€” args ΠΈ kwargs соотвСтствСнно. Бинтаксис Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ΠΎΠ² с Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π°ΠΌΠΈ Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ отличаСтся β€” Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ с Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π°ΠΌΠΈ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ, которая ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Π΄Ρ€ΡƒΠ³ΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ:

def text_wrapper(wrap_text):
    def wrapped(function):
        def wrapper(*args, **kwargs):
            result = function(*args, **kwargs)
            return f"{wrap_text}\n{result}\n{wrap_text}"

        return wrapper

    return wrapped


@text_wrapper('============')
def my_decorated_function(text):
    return text


print(my_decorated_function('Hello, world!'))
============
Hello, world!
============

ΠšΠΎΠ½Ρ‚Π΅ΠΊΡΡ‚Π½Ρ‹ΠΉ ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ€

Код, Ρ€Π°Π·ΠΌΠ΅Ρ‰Π΅Π½Π½Ρ‹ΠΉ Π²Π½ΡƒΡ‚Ρ€ΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π° with выполняСтся с ΠΎΡΠΎΠ±Π΅Π½Π½ΠΎΡΡ‚ΡŒΡŽ: ΠΊΠ°ΠΊ Π΄ΠΎ, Ρ‚Π°ΠΊ ΠΈ послС ΡΡ€Π°Π±Π°Ρ‚Ρ‹Π²Π°ΡŽΡ‚ события Π²Ρ…ΠΎΠ΄Π° Π² Π±Π»ΠΎΠΊ with ΠΈ Π²Ρ‹Ρ…ΠΎΠ΄Π° ΠΈΠ· Π½Π΅Π³ΠΎ. ΠžΠ±ΡŠΠ΅ΠΊΡ‚, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ опрСдСляСт Π»ΠΎΠ³ΠΈΠΊΡƒ событий, называСтся контСкстным ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ€ΠΎΠΌ.

На ΡƒΡ€ΠΎΠ²Π½Π΅ класса события ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Ρ‹ ΠΌΠ΅Ρ‚ΠΎΠ΄Π°ΠΌΠΈ __enter__ ΠΈ __exit__.
__enter__ срабатываСт Π² Ρ‚ΠΎΡ‚ ΠΌΠΎΠΌΠ΅Π½Ρ‚, ΠΊΠΎΠ³Π΄Π° Ρ…ΠΎΠ΄ исполнСния ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ΠΈΡ‚ Π²Π½ΡƒΡ‚Ρ€ΡŒ with. ΠœΠ΅Ρ‚ΠΎΠ΄ ΠΌΠΎΠΆΠ΅Ρ‚ Π²Π΅Ρ€Π½ΡƒΡ‚ΡŒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅. Оно Π±ΡƒΠ΄Π΅Ρ‚ доступно располоТСнному Π²Π½ΡƒΡ‚Ρ€ΠΈ Π±Π»ΠΎΠΊΠ° with ΠΊΠΎΠ΄Ρƒ.
__exit__ срабатываСт Π² ΠΌΠΎΠΌΠ΅Π½Ρ‚ Π²Ρ‹Ρ…ΠΎΠ΄Π° Π±Π»ΠΎΠΊΠ°, Π² Ρ‚.Ρ‡. ΠΈ Π² случаС ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ. Π’ этом случаС Π² ΠΌΠ΅Ρ‚ΠΎΠ΄ Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π° Ρ‚Ρ€ΠΎΠΉΠΊΠ° Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ (exc_class, exc_instance, traceback).

Π‘Π°ΠΌΡ‹ΠΉ распространённый контСкстный ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ€ – класс, ΠΏΠΎΡ€ΠΎΠΆΠ΄Π΅Π½Π½Ρ‹ΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ open. Он Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΡƒΠ΅Ρ‚, Ρ‡Ρ‚ΠΎ Ρ„Π°ΠΉΠ» Π±ΡƒΠ΄Π΅Ρ‚ Π·Π°ΠΊΡ€Ρ‹Ρ‚ Π΄Π°ΠΆΠ΅ Π² Ρ‚ΠΎΠΌ случаС, Ссли Π²Π½ΡƒΡ‚Ρ€ΠΈ Π±Π»ΠΎΠΊΠ° Π²ΠΎΠ·Π½ΠΈΠΊΠ½Π΅Ρ‚ ошибка.

Π–Π΅Π»Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ побыстрСС Π²Ρ‹Ρ…ΠΎΠ΄ΠΈΡ‚ΡŒ ΠΈΠ· контСкстного ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ€Π°, освобоТдая контСкст ΠΈ рСсурсы.

with open('file.txt') as f:
    data = f.read()

process_data(data)

Π’ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ Π²Ρ‹ΡˆΠ΅ ΠΌΡ‹ Π²Ρ‹ΡˆΠ»ΠΈ ΠΈΠ· Π±Π»ΠΎΠΊΠ° with сразу ΠΆΠ΅ послС прочтСния Ρ„Π°ΠΉΠ»Π°. ΠžΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Π΄Π°Π½Π½Ρ‹Ρ… происходит Π² основном Π±Π»ΠΎΠΊΠ΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹.

ΠšΠΎΠ½Ρ‚Π΅ΠΊΡΡ‚Π½Ρ‹Π΅ ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ€Ρ‹ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ для Π²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ Π·Π°ΠΌΠ΅Π½Ρ‹ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ², ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… окруТСния, Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΉ Π‘Π”.

НапишСм свой контСкстный ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ€ для ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ ΠΊ Π‘Π” SQLite:

import sqlite3


class db_conn:

    def __init__(self, db_name):
        self.db_name = db_name

    # ΠžΡ‚ΠΊΡ€Ρ‹Π²Π°Π΅ΠΌ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΠΊ Π‘Π”
    def __enter__(self):
        self.conn = sqlite3.connect(self.db_name)
        return self.conn

    # Π—Π°ΠΊΡ€Ρ‹Π²Π°Π΅ΠΌ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΠΊ Π‘Π”
    def __exit__(self, exc_type, exc_value, exc_traceback):
        self.conn.close()
        if exc_value:
            raise


if __name__ == "__main__":
    db = "test_context_connect.db"

    with db_conn(db) as conn:
        cursor = conn.cursor()

ΠšΠΎΠ½Ρ‚Π΅ΠΊΡΡ‚Π½Ρ‹ΠΉ ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ€ Π½Π° Π±Π°Π·Π΅ contextlib

ΠŸΠ΅Ρ€Π΅ΠΏΠΈΡˆΠ΅ΠΌ наш контСкстный ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ€ для ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ ΠΊ Π‘Π” SQLite ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ contextlib:

import sqlite3
from contextlib import contextmanager


# Π‘Ρ…Π΅ΠΌΠ° конструирования ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π°Ρ: всё, Ρ‡Ρ‚ΠΎ написано Π΄ΠΎ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π° yield - вызываСтся Π² Ρ€Π°ΠΌΠΊΠ°Ρ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ __enter__,
# всё Ρ‡Ρ‚ΠΎ послС – Π² Ρ€Π°ΠΌΠΊΠ°Ρ… __exit__.
@contextmanager
def db_conn(db_name):
    # ΠžΡ‚ΠΊΡ€Ρ‹Π²Π°Π΅ΠΌ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΠΊ Π‘Π”
    conn = sqlite3.connect(db_name)

    yield conn

    # Π—Π°ΠΊΡ€Ρ‹Π²Π°Π΅ΠΌ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΠΊ Π‘Π”
    conn.close()


if __name__ == "__main__":
    db = "test_contextlib_connect.db"

    with db_conn(db) as conn:
        cursor = conn.cursor()

4. ООП

Β«ΠœΠ΅ΡΡ‚ΠΎ Ρ‚ΠΎ нСсказанно прСкрасно Π²ΠΈΠ΄ΠΎΠΌ: всякоС Π΄Π΅Ρ€Π΅Π²ΠΎ Π±Π»Π°Π³ΠΎΡ†Π²Π΅Ρ‚Π½ΠΎ, ΠΈ всякий ΠΏΠ»ΠΎΠ΄ Π·Ρ€Π΅Π», ΠΈ всСвозмоТныС яства ΠΈΠ·ΠΎΠ±ΠΈΠ»ΡƒΡŽΡ‚, всякоС Π΄ΡƒΠ½ΠΎΠ²Π΅Π½ΠΈΠ΅ Π±Π»Π°Π³ΠΎΠ²ΠΎΠ½Π½ΠΎΒ».

«Блавянская ΠΊΠ½ΠΈΠ³Π° Π•Π½ΠΎΡ…Π°Β».

OOP

ΠšΠ»Π°ΡΡΡ‹ ΠΈ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹

Π’ΡƒΡ‚, ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎ, Π±Ρ‹Π»ΠΎ Π±Ρ‹ ΠΊ мСсту ΠΊΡ€Π°Ρ‚Π΅Π½ΡŒΠΊΠΎΠ΅, ΠΌΠΈΠ½ΡƒΡ‚ Π½Π° сорок, Π²Π²Π΅Π΄Π΅Π½ΡŒΠΈΡ†Π΅ Π² Ρ‚Π΅ΠΌΡƒ классов ΠΈ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ², Π½ΠΎ Π² наш Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΉ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ такая мощная Π²Ρ€Π΅Π·ΠΊΠ° Π½Π΅ совсСм укладываСтся. Объясню максимально просто, Π½Π° доступных ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°Ρ… ΠΈΠ· киновсСлСнной Β«Π§ΡƒΠΆΠΈΡ…Β»:
ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ β€” это ΠΎΠ΄ΠΈΠ½ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½Ρ‹ΠΉ ксСноморф;
класс β€” это ΠšΠΎΡ€ΠΎΠ»Π΅Π²Π° ксСноморфов. Класс Π»ΠΈΠ±ΠΎ Ρ€ΠΎΠΆΠ°Π΅Ρ‚ ксСноморфа, Π»ΠΈΠ±ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚ Π²ΡΡ‚ΡƒΠΏΠΈΡ‚ΡŒ Π² Π±ΠΎΠΉ сам (@staticmethod);
ΠΌΠ΅Ρ‚Π°ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ β€” это такая Π‘ΡƒΠΏΠ΅Ρ€-ΠšΠΎΡ€ΠΎΠ»Π΅Π²Π°, Ρ€Π°Π·ΠΌΠ΅Ρ€ΠΎΠΌ с Β«Π‘ΡƒΠ»Π°ΠΊΠΎΒ», которая Ρ€ΠΎΠΆΠ°Π΅Ρ‚ Π΄Ρ€ΡƒΠ³ΠΈΡ… ΠšΠΎΡ€ΠΎΠ»Π΅Π²;
наслСдованиС β€” это ксСноморф ΠΈΠ· Β«Π’ΠΎΡΠΊΡ€Π΅ΡˆΠ΅Π½ΠΈΡΒ», ΠΏΠΎΠΌΠ½ΠΈΡ‚Π΅, милСнький Ρ‚Π°ΠΊΠΎΠΉ, взявший Π»ΡƒΡ‡ΡˆΠ΅Π΅ ΠΈ ΠΎΡ‚ собствСнной гСнСтичСской ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ ΠΈ ΠΎΡ‚ Π³Π΅Π½ΠΎΠ² Π ΠΈΠΏΠ»ΠΈ.

ΠœΡ‹ ΠΏΠΎΠΏΡ€ΠΎΠ±ΡƒΠ΅ΠΌ Π²Π΅Ρ€Π½ΡƒΡ‚ΡŒΡΡ ΠΊ Ρ‚Π΅ΠΌΠ΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² с Ρ‡ΡƒΡ‚ΡŒ Π±ΠΎΠ»Π΅Π΅ ΡΠ΅Ρ€ΡŒΠ΅Π·Π½Ρ‹ΠΌ настроСниСм ΠΏΠΎΠ·ΠΆΠ΅, Π² Π³Π»Π°Π²Π΅ «АрхитСктура», Π½ΠΎ, Π²ΠΎΠΎΠ±Ρ‰Π΅, Π² ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π½ΠΎ-ΠΎΡ€ΠΈΠ΅Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠΌ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠΈ Π½Π΅Ρ‚ Π½ΠΈΡ‡Π΅Π³ΠΎ особо слоТного; просто Π΄ΠΎ Π½Π΅Π³ΠΎ Π»ΡƒΡ‡ΡˆΠ΅ Π΄ΠΎΠΉΡ‚ΠΈ, ΠΏΡ€Π΅Π΄Π²Π°Ρ€ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ погрязнув Π² ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ΅ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎΠ³ΠΎ ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Π½ΠΎΠ³ΠΎ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄Π°, ΠΊΠΎΠ³Π΄Π° Π·Π°Ρ‡Π°ΡΡ‚ΡƒΡŽ стоит Π²Ρ‹Π±ΠΎΡ€ β€” ΠΏΠΎΠΏΡ€ΠΎΠ±ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΠΎΠ΄Π»Π΅Ρ‡ΠΈΡ‚ΡŒ этот кусок ΠΊΠΎΠ΄Π° ΠΈΠ»ΠΈ ΡƒΠΆΠ΅ ΡƒΡΡ‹ΠΏΠΈΡ‚ΡŒ ΠΈ ΠΏΠ΅Ρ€Π΅ΠΏΠΈΡΠ°Ρ‚ΡŒ всё ΠΏΠΎ Π½ΠΎΠ²ΠΎΠΉ? Когда-Ρ‚ΠΎ Π΄Π°Π²Π½ΠΎ, ΠΊΠΎΠ³Π΄Π° я писал ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ нСслоТныС ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ Π½Π° ассСмблСрС для ΠΌΠΈΠΊΡ€ΠΎΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€ΠΎΠ², Ρ‚ΠΎ читая Бтрауструпа, слСгка Π½Π΅Π΄ΠΎΡƒΠΌΠ΅Π²Π°Π» β€” Π·Π°Ρ‡Π΅ΠΌ всё это? Π§Ρ‚ΠΎΠ±Ρ‹ ΠΎΡΠΎΠ·Π½Π°Ρ‚ΡŒ ΠΏΠΎΡ‚Ρ€Π΅Π±Π½ΠΎΡΡ‚ΡŒ Π² ΠΎΠ±ΡƒΠ²ΠΈ, Π½Π°Π΄ΠΎ ΠΏΠΎΡ…ΠΎΠ΄ΠΈΡ‚ΡŒ босиком.

ΠœΠ°Π³ΠΈΡ‡Π΅ΡΠΊΠΈΠ΅ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹

Π‘ΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½Ρ‹Π΅ (Π½Π°Π·Ρ‹Π²Π°Π΅ΠΌΡ‹Π΅ Ρ‚Π°ΠΊΠΆΠ΅ magic ΠΈΠ»ΠΈ dunder) ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ класса - ΠΏΠ΅Ρ€Π΅Π³Ρ€ΡƒΠ·ΠΊΠ°, ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‰Π°Ρ классам ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡ‚ΡŒ собствСнноС ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ ΠΏΠΎ ΠΎΡ‚Π½ΠΎΡˆΠ΅Π½ΠΈΡŽ ΠΊ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π°ΠΌ языка.
ΠœΠ°Π³ΠΈΡ‡Π΅ΡΠΊΠΈΠ΅ ΠΎΠ½ΠΈ ΠΏΠΎΡ‚ΠΎΠΌΡƒ, Ρ‡Ρ‚ΠΎ ΠΏΠΎΡ‡Ρ‚ΠΈ Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‚ΡΡ явно. Π˜Ρ… Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‚ встроСнныС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΈΠ»ΠΈ синтаксичСскиС конструкции. НапримСр, функция len() Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ ΠΌΠ΅Ρ‚ΠΎΠ΄ __len__() ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½ΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°. ΠœΠ΅Ρ‚ΠΎΠ΄ __add__(self, other) вызываСтся автоматичСски ΠΏΡ€ΠΈ слоТСнии ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠΌ +.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ магичСских ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹:

__init__: конструктор класса
__add__: слоТСниС с Π΄Ρ€ΡƒΠ³ΠΈΠΌ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠΌ
__eq__: ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° Π½Π° равСнство с Π΄Ρ€ΡƒΠ³ΠΈΠΌ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠΌ
__cmp__: сравнСниС (большС, мСньшС, Ρ€Π°Π²Π½ΠΎ)
__iter__: ΠΏΡ€ΠΈ подстановкС ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° Π² Ρ†ΠΈΠΊΠ»

print(dir(int), "\n")


class A:  # An empty class
    ...


a = A()
print(dir(a), "\n")
print(repr(a), "\n")
print(str(a))
['__abs__', '__add__', '__and__', '__bool__', '__ceil__', '__class__', '__delattr__', '__dir__', '__divmod__', '__doc__', '__eq__', '__float__', '__floor__', '__floordiv__', '__format__', '__ge__', '__getattribute__', '__getnewargs__', '__gt__', '__hash__', '__index__', '__init__', '__init_subclass__', '__int__', '__invert__', '__le__', '__lshift__', '__lt__', '__mod__', '__mul__', '__ne__', '__neg__', '__new__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__round__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__', 'as_integer_ratio', 'bit_count', 'bit_length', 'conjugate', 'denominator', 'from_bytes', 'imag', 'numerator', 'real', 'to_bytes'] 

['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__'] 

<__main__.A object at 0x000001A1FFF3AF20> 

<__main__.A object at 0x000001A1FFF3AF20>

ΠžΡΠΎΠ±Π΅Π½Π½ΠΎΡΡ‚ΡŒΡŽ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° __init__ являСтся Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ ΠΎΠ½ Π½Π΅ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π½ΠΈΡ‡Π΅Π³ΠΎ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Ρ‚ΡŒ. ΠŸΡ€ΠΈ ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΠ΅ Π²ΠΎΠ·Π²Ρ€Π°Ρ‚Π° Π΄Π°Π½Π½Ρ‹Ρ… Π±ΡƒΠ΄Π΅Ρ‚ сгСнСрировано ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅.
__repr__ (representation) Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Π±ΠΎΠ»Π΅Π΅-ΠΌΠ΅Π½Π΅Π΅ машино-Ρ‡ΠΈΡ‚Π°Π΅ΠΌΠΎΠ΅ прСдставлСниС ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°, ΠΏΠΎΠ»Π΅Π·Π½ΠΎΠ΅ для ΠΎΡ‚Π»Π°Π΄ΠΊΠΈ.
Иногда repr ΠΌΠΎΠΆΠ΅Ρ‚ ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Ρ‚ΡŒ достаточно ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ для восстановлСния ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°.
__str__ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Ρ‡Π΅Π»ΠΎΠ²Π΅ΠΊΠΎ-Ρ‡ΠΈΡ‚Π°Π΅ΠΌΠΎΠ΅ сообщСниС. Если __str__ Π½Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Ρ‘Π½, Ρ‚ΠΎ str ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ repr.

class Person:  # A simple class with init, repr and str methods
    def __init__(self, name: str):
        self.name: str = name

    def __repr__(self):
        return f"Person '{self.name}'"

    def __str__(self):
        return f"{self.name}"

    def say_hi(self):
        print("Hi, my name is", self.name)


p = Person("Charlie")
p.say_hi()
print(repr(p))
print(str(p))
Hi, my name is Charlie
Person 'Charlie'
Charlie

@property

Π”Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ @property ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для опрСдСлСния ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ², доступных ΠΊΠ°ΠΊ поля. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ чтСния/записи поля ΠΌΠΎΠΆΠ½ΠΎ ΠΎΠ±Ρ€Π°ΠΌΠΈΡ‚ΡŒ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠΉ Π»ΠΎΠ³ΠΈΠΊΠΎΠΉ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΎΠΉ допустимых Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ Π²Ρ…ΠΎΠ΄Π½ΠΎΠ³ΠΎ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π°.

import math

class Circle:
    def __init__(self, radius, max_radius):
        self._radius = radius
        self.max_radius = max_radius

    @property
    def radius(self):
        return self._radius

    @radius.setter
    def radius(self, value):
        if value <= self.max_radius:
            self._radius = value
        else:
            raise ValueError

    @property
    def area(self):
        return 2 * self.radius * math.pi


circle = Circle(10, 100)
circle.radius = 20  # OK
# circle.radius = 101  # Raises ValueError
print(circle.area)
125.66370614359172

@staticmethod

ΠžΠ±Ρ‹Ρ‡Π½Ρ‹ΠΉ ΠΌΠ΅Ρ‚ΠΎΠ΄ (Ρ‚. Π΅. Π½Π΅ ΠΏΠΎΠΌΠ΅Ρ‡Π΅Π½Π½Ρ‹ΠΉ Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€Π°ΠΌΠΈ @staticmethod ΠΈΠ»ΠΈ @classmethod) ΠΈΠΌΠ΅Π΅Ρ‚ доступ ΠΊ свойствам ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠ³ΠΎ экзСмпляра класса.

@staticmethod β€” ΠΌΠ΅Ρ‚ΠΎΠ΄, ΠΏΡ€ΠΈΠ½Π°Π΄Π»Π΅ΠΆΠ°Ρ‰ΠΈΠΉ классу, Π° Π½Π΅ экзСмпляру класса. МоТно Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ Π±Π΅Π· создания экзСмпляра, Ρ‚. ΠΊ. ΠΌΠ΅Ρ‚ΠΎΠ΄ Π½Π΅ ΠΈΠΌΠ΅Π΅Ρ‚ доступа ΠΊ свойствам экзСмпляра. ΠŸΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ @staticmethod ΠΏΠΎΠΌΠ΅Ρ‡Π°ΡŽΡ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π», логичСски связанный с классом, Π½ΠΎ Π½Π΅ Ρ‚Ρ€Π΅Π±ΡƒΡŽΡ‰ΠΈΠΉ доступа ΠΊ свойствам экзСмпляра.

@classmethod, cls, self

Если ΠΌΠ΅Ρ‚ΠΎΠ΄ Π½Π΅ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΈΠΌΠ΅Ρ‚ΡŒ доступа ΠΊ свойствам ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠ³ΠΎ экзСмпляра класса (ΠΊΠ°ΠΊ @staticmethod), Π½ΠΎ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΈΠΌΠ΅Ρ‚ΡŒ доступ ΠΊ Π΄Ρ€ΡƒΠ³ΠΈΠΌ ΠΌΠ΅Ρ‚ΠΎΠ΄Π°ΠΌ ΠΈ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΌ класса, Ρ‚ΠΎ слСдуСт ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ @classmethod.

class B(object):
    def foo(self, x):
        print(f"Run foo({self}, {x})")

    @classmethod
    def class_foo(cls, x):
        print(f"Run class_foo({cls}, {x})")

    @staticmethod
    def static_foo(x):
        print(f"Run static_foo({x})")


b = B()
b.foo(1)
b.class_foo(1)
b.static_foo(1)
Run foo(<__main__.B object at 0x000001A1FFF3A980>, 1)
Run class_foo(<class '__main__.B'>, 1)
Run static_foo(1)

Π£ @classmethod ΠΏΠ΅Ρ€Π²Ρ‹ΠΌ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠΌ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ cls (класс), Π° Ρƒ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎΠ³ΠΎ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° - self (экзСмпляр класса).
Для @staticmethod Π½Π΅ трСбуСтся Π½ΠΈ cls, Π½ΠΈ self.

__dict__

ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ класс ΠΈ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΈΠΌΠ΅Π΅Ρ‚ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ __dict__. Π­Ρ‚ΠΎ «систСмный», ΠΎΠΏΡ€Π΅Π΄Π΅Π»Ρ‘Π½Π½Ρ‹ΠΉ ΠΈΠ½Ρ‚Π΅Ρ€ΠΏΡ€Π΅Ρ‚Π°Ρ‚ΠΎΡ€ΠΎΠΌ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚, Π΅Π³ΠΎ Π½Π΅ Π½ΡƒΠΆΠ½ΠΎ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ Π²Ρ€ΡƒΡ‡Π½ΡƒΡŽ. __dict__ β€” ΡΠ»ΠΎΠ²Π°Ρ€ΡŒ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Ρ…Ρ€Π°Π½ΠΈΡ‚ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΠ΅ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Ρ‹; Π² Π½Ρ‘ΠΌ ΠΊΠ»ΡŽΡ‡ΠΎΠΌ являСтся имя Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Π°, Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ, соотвСтствСнно, Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Π°.

class Supercriminal:
    publisher = 'DC Comics'

Riddler = Supercriminal()
print(Supercriminal.__dict__)
print(Riddler.__dict__)

Riddler.name = 'Edward Nygma'
print(Riddler.__dict__)  # Values from object __dict__

print(Riddler.publisher)  # Value from class __dict__
{'__module__': '__main__', 'publisher': 'DC Comics', '__dict__': <attribute '__dict__' of 'Supercriminal' objects>, '__weakref__': <attribute '__weakref__' of 'Supercriminal' objects>, '__doc__': None}
{}
{'name': 'Edward Nygma'}
DC Comics

ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ Ρ€Π°Π· ΠΏΡ€ΠΈ запросС ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΎΠ³ΠΎ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Π° Python ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ обыскиваСт сам ΠΎΠ±ΡŠΠ΅ΠΊΡ‚, класс ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° ΠΈ классы, ΠΎΡ‚ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… унасалСдован класс ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°.

__slots__

Если Π²Ρ‹ ΠΏΡ€ΠΈΠΏΠΎΠΌΠ½ΠΈΡ‚Π΅ Ρ€Π°Π·Π½ΠΈΡ†Ρƒ ΠΌΠ΅ΠΆΠ΄Ρƒ списком ΠΈ ΠΊΠΎΡ€Ρ‚Π΅ΠΆΠ΅ΠΌ, Π° Ρ‚Π°ΠΊΠΆΠ΅ ΠΌΠ΅ΠΆΠ΄Ρƒ мноТСством ΠΈ ΠΈΠΈΠΌΡƒΡ‚Π°Π±Π΅Π»ΡŒΠ½Ρ‹ΠΌ мноТСством, Ρ‚ΠΎ Π·Π°ΠΌΠ΅Ρ‚ΠΈΡ‚Π΅, Ρ‡Ρ‚ΠΎ создатСли Python ΠΏΡ‹Ρ‚Π°ΡŽΡ‚ΡΡ ΠΏΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²Π»ΡΡ‚ΡŒ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ°ΠΌ Π²Ρ‹Π±ΠΎΡ€ ΠΌΠ΅ΠΆΠ΄Ρƒ удобством ΠΈ ΡΠΊΠΎΡ€ΠΎΡΡ‚ΡŒΡŽ (Ρ‚ΡƒΡ‚ Π‘ΠΈ с ассСмблСрными вставками слСгка напрягаСтся, Π½ΠΎ ΠΏΠΎΡ‚ΠΎΠΌ ΠΎΠΏΠ°Π΄Π°Π΅Ρ‚, ΠΊΠ°ΠΊ Π±ΡƒΠ΄Ρ‚ΠΎ Ρ…ΠΎΡ‚Π΅Π» Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ ΡΠΊΠ°Π·Π°Ρ‚ΡŒ, Π½ΠΎ Π±Π»Π°Π³ΠΎΡ€Π°Π·ΡƒΠΌΠ½ΠΎ ΠΏΠ΅Ρ€Π΅Π΄ΡƒΠΌΠ°Π»). К списку Ρ‚Π°ΠΊΠΈΡ… ΠΆΠ΅ особСнностСй языка, Π·Π°Ρ‚ΠΎΡ‡Π΅Π½Π½Ρ‹Ρ… Π½Π° ΡƒΠ²Π΅Π»ΠΈΡ‡Π΅Π½ΠΈΠ΅ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ ΠΈ ΡƒΠΌΠ΅Π½ΡŒΡˆΠ΅Π½ΠΈΠ΅ Π·Π°Π½ΠΈΠΌΠ°Π΅ΠΌΠΎΠΉ памяти, относится ΠΈ __slots__.

Π’ΠΎΡ‚ ΠΎΡ„ΠΈΡ†ΠΈΠ°Π»ΡŒΠ½Π°Ρ докумСнтация ΠΏΠΎ __slots__, Π° Π²ΠΎΡ‚ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ Ρ€Π°Π·ΡŠΡΡΠ½Π΅Π½ΠΈΡ ΠΎΡ‚ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΈΠ· Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΎΠ² ΠΎΡ„ΠΈΡ†ΠΈΠ°Π»ΡŒΠ½ΠΎΠΉ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ. ΠŸΡ€ΠΈ Π²Ρ‹Π±ΠΎΡ€Π΅ Β«slots ΠΈΠ»ΠΈ Π½Π΅ slotsΒ» ΠΏΠΎΠΌΠ½ΠΈΡ‚Π΅ ΠΏΡ€ΠΎ сущСствованиС PEP 412 – Key-Sharing Dictionary, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ внёс Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Ρ€Π°Π·Π΄Ρ€Π°ΠΉ Π² Π½Π΅ΠΊΠΎΠ³Π΄Π° ΠΎΠ΄Π½ΠΎΠ·Π½Π°Ρ‡Π½ΠΎΠ΅ ΠΎΡ‚Π½ΠΎΡˆΠ΅Π½ΠΈΠ΅ ΠΊ __slots__.

__dict__, рассмотрСнный Ρ‡ΡƒΡ‚ΡŒ Π²Ρ‹ΡˆΠ΅ – измСняСмая структура, ΠΈ Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π½Π° Π»Π΅Ρ‚Ρƒ Π΄ΠΎΠ±Π°Π²Π»ΡΡ‚ΡŒ ΠΈ ΡƒΠ΄Π°Π»ΡΡ‚ΡŒ поля ΠΈΠ· класса, Ρ‡Ρ‚ΠΎ ΡƒΠ΄ΠΎΠ±Π½ΠΎ, Π½ΠΎ ΠΏΠΎΡ€ΠΎΠΉ ΠΌΠ΅Π΄Π»Π΅Π½Π½ΠΎ. Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Ρ€Π°Π·ΠΌΠ΅Π½ΡΡ‚ΡŒ удобство Π½Π° ΡΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ ΠΈ Ρ€Π°Π·ΠΌΠ΅Ρ€ Π·Π°Π½ΠΈΠΌΠ°Π΅ΠΌΠΎΠΉ памяти, создав __slots__ β€” ТСстко Π·Π°Π΄Π°Π½Π½Ρ‹ΠΉ список ΠΏΡ€Π΅Π΄ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹Ρ… Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ΠΎΠ², Ρ€Π΅Π·Π΅Ρ€Π²ΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ ΠΏΠ°ΠΌΡΡ‚ΡŒ, созданиС ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ Π·Π°ΠΏΡ€Π΅Ρ‰Π°Π΅Ρ‚ дальнСйшСС созданиС __dict__ ΠΈ __weakref__. Π‘Π»ΠΎΡ‚Ρ‹ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ, ΠΊΠΎΠ³Π΄Π° Ρƒ класса ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΎΡ‡Π΅Π½ΡŒ ΠΌΠ½ΠΎΠ³ΠΎ ΠΏΠΎΠ»Π΅ΠΉ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π² ORM, Π»ΠΈΠ±ΠΎ ΠΊΠΎΠ³Π΄Π° ΠΊΡ€ΠΈΡ‚ΠΈΡ‡Π½Π° ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ доступ ΠΊ списку Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ быстрСС, Ρ‡Π΅ΠΌ поиск Π² словарС.

class Clan:
    __slots__ = ["first", "second"]

clan = Clan()
clan.first = "Joker"
clan.second = "Lex Luthor"
# clan.third = "Green Goblin"  # Raises AttributeError
# print(clan.__dict__)  # Raises AttributeError

Π‘Π»ΠΎΡ‚Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ, скаТСм, Π² Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°Ρ… requests (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, __slots__ = ["url", "netloc", "simple_url", "pypi_url", "file_storage_domain"]) ΠΈΠ»ΠΈ ORM peewee (__slots__ = ('stack', '_sql', '_values', 'alias_manager', 'state')).

НаслСдованиС __slots__ ΠΈΠΌΠ΅Π΅Ρ‚ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΡƒΡŽ спСцифику ΠΈ Π±ΡƒΠ΄Π΅Ρ‚ рассмотрСно Π½ΠΈΠΆΠ΅.

Π§Ρ‚ΠΎΠ±Ρ‹ Π±Ρ‹Π»ΠΎ понятно, ΠΎ ΠΊΠ°ΠΊΠΎΠΌ приростС ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ ΠΈ сниТСнии потрСблСния памяти ΠΈΠ΄Ρ‘Ρ‚ Ρ€Π΅Ρ‡ΡŒ, сдСлаСм простоС сравнСниС:

import timeit
import pympler.asizeof  # Π’ нашСм случаС sys.getsizeof - Π½Π΅ Π»ΡƒΡ‡ΡˆΠΈΠΉ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚, Π±Π΅Ρ€Π΅ΠΌ стороннСС Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅


class NotSlotted():
    pass


class Slotted():
    __slots__ = 'foo'


not_slotted = NotSlotted()
slotted = Slotted()


def get_set_delete_fn(obj):
    def get_set_delete():
        obj.foo = "Never Ending Song of Love"
        del obj.foo

    return get_set_delete


ns = min(timeit.repeat(get_set_delete_fn(not_slotted)))
s = min((timeit.repeat(get_set_delete_fn(slotted))))

print(ns, s, f'{(ns - s) / s * 100} %')

print(pympler.asizeof.asizeof(not_slotted), 'bytes')
print(pympler.asizeof.asizeof(slotted), 'bytes')
0.10838449979200959 0.08712740009650588 24.39772066187959 %
280 bytes
40 bytes

Π― Π² Python 3.10 Π² Windows Π²ΠΈΠΆΡƒ 24 % Ρ€Π°Π·Π½ΠΈΡ†Ρ‹.

На всякий случай напоминаю Π΅Ρ‰Π΅ Ρ€Π°Π· β€” прогняйтС всС нСпонятныС ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ ΠΊΠΎΠ΄Π° Π² IDE, ΠΈΡ… ΠΌΠΎΠΆΠ½ΠΎ ΠΈ Π½ΡƒΠΆΠ½ΠΎ Π°Π½Π°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ, ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΈ Π²ΠΈΠ΄ΠΎΠΈΠ·ΠΌΠ΅Π½ΡΡ‚ΡŒ. ΠŸΠΎΠΏΡ€ΠΎΠ±ΡƒΠΉΡ‚Π΅, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΡΠ°ΠΌΠΎΡΡ‚ΠΎΡΡ‚Π΅Π»ΡŒΠ½ΠΎ ΠΏΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ ΠΏΠΎΡ‚Ρ€Π΅Π±Π»Π΅Π½ΠΈΠ΅ памяти ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² с __dict__ ΠΈ __slots__. А Π·Π°ΠΎΠ΄Π½ΠΎ Π½Π° ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠ΅ испытайтС Π΄Π°Π²Π½ΠΎ Π½Π°ΠΏΡ€Π°ΡˆΠΈΠ²Π°ΡŽΡ‰ΠΈΠΉΡΡ, ΠΈ Π½Π°ΠΊΠΎΠ½Π΅Ρ† появившийся Π² Python 3.10 симбиоз ΠΌΠ΅ΠΆΠ΄Ρƒ __slots__ ΠΈ dataclass.

Утиная типизация

Утиная типизация (duck types) - постулированиС Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ интСрфСйса классом Π½Π΅ Ρ‡Π΅Ρ€Π΅Π· явноС объявлСниС, Π° Ρ‡Π΅Ρ€Π΅Π· Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² интСрфСйса. Π’Π°ΠΊ, ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ класс, Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΡŽΡ‰ΠΈΠΉ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ __next__() ΠΈ __iter__(), автоматичСски становится ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠΌ, нСсмотря Π½Π° отсутствиС явного объявлСния (Ρ‡Ρ‚ΠΎ-Π½ΠΈΠ±ΡƒΠ΄ΡŒ Π²Ρ€ΠΎΠ΄Π΅ @iterator) ΠΈΠ»ΠΈ, скаТСм, наслСдования ΠΎΡ‚ класса Iterator.

Iterator

Π˜Ρ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€ - класс, Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΡŽΡ‰ΠΈΠΉ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ __next__() ΠΈ __iter__().
ΠœΠ΅Ρ‚ΠΎΠ΄ __next__() Π΄ΠΎΠ»ΠΆΠ΅Π½ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Ρ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€Π° ΠΈΠ»ΠΈ Π²Ρ‹ΠΊΠΈΠ΄Ρ‹Π²Π°Ρ‚ΡŒ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ StopIteration, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡΠΈΠ³Π½Π°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΎ Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€ исчСрпал доступныС значСния. ΠœΠ΅Ρ‚ΠΎΠ΄ __iter__() Π΄ΠΎΠ»ΠΆΠ΅Π½ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Ρ‚ΡŒ "self".

class LimitCounter:
    def __init__(self, max_value: int):
        self.count = 0
        self.max_value = max_value

    def __next__(self):
        self.count += 1

        if self.count <= self.max_value:
            return self.count
        else:
            raise StopIteration

    def __iter__(self):
        return self


limit_counter = LimitCounter(2)
print(next(limit_counter))
print(next(limit_counter))


# print(next(limit_counter))  # Raises StopIteration
1
2

Comparable

Начиная с Python 3.4, для Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ экзСмпляры ΠΌΠ΅Ρ‚ΠΎΠ΄Π° ΠΌΠΎΠΆΠ½ΠΎ Π±Ρ‹Π»ΠΎ ΡΡ€Π°Π²Π½ΠΈΠ²Π°Ρ‚ΡŒ ΠΌΠ΅ΠΆΠ΄Ρƒ собой, достаточно ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ __lt__ (мСньшС) ΠΈ __eq__ (Ρ€Π°Π²Π½ΠΎ), Π° Ρ‚Π°ΠΊΠΆΠ΅ Π·Π°Π΄Π΅ΠΉΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ @functools.total_ordering.

from functools import total_ordering

@total_ordering
class Person:
    def __init__(self, firstname: str, lastname: str):
        self.firstname: str = firstname
        self.lastname: str = lastname

    def _is_valid_operand(self, other):
        return hasattr(other, "lastname") and hasattr(other, "firstname")

    def __eq__(self, other):
        if not self._is_valid_operand(other):
            return NotImplemented
        return (self.lastname, self.firstname) == (other.lastname, other.firstname)

    def __lt__(self, other):
        if not self._is_valid_operand(other):
            return NotImplemented
        return (self.lastname, self.firstname) < (other.lastname, other.firstname)


Finn = Person("Finn", "the Human")
Jake = Person("Jake", "the Dog")

print(Finn != Jake)
True

Hashable

Π₯Π΅ΡˆΠΈΡ€ΡƒΠ΅ΠΌΡ‹Π΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Ρ‹Π²Π°Ρ‚ΡŒ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ __hash__() ΠΈ __eq__(). Π₯Сш ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ Π½Π΅ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ Π² Ρ‚Π΅Ρ‡Π΅Π½ΠΈΠΈ всСго ΠΆΠΈΠ·Π½Π΅Π½Π½ΠΎΠ³ΠΎ Ρ†ΠΈΠΊΠ»Π°. Π₯Π΅ΡˆΠΈΡ€ΡƒΠ΅ΠΌΡ‹Π΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠ°ΠΊ ΠΊΠ»ΡŽΡ‡ΠΈ Π² словарях ΠΈ ΠΊΠ°ΠΊ элСмСнты мноТСств, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ эти структуры ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ Ρ…Π΅Ρˆ-Ρ‚Π°Π±Π»ΠΈΡ†Ρƒ для Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½Π΅Π³ΠΎ прСдставлСния Π΄Π°Π½Π½Ρ‹Ρ….

Hashable objects that compare equal must have the same hash value, meaning default hash() that returns 'id(self)' will not do. That is why Python automatically makes classes unhashable if you only implement eq().

class Hero:
    def __init__(self, name: str, level: int):
        self.name: str = name
        self.level: int = level

    def _is_valid_operand(self, other):
        return hasattr(other, "name") and hasattr(other, "level")

    def __eq__(self, other):
        if not self._is_valid_operand(other):
            return NotImplemented
        return (self.name, self.level) == (other.name, other.level)

    def __hash__(self):
        return hash((self.name, self.level))


Finn = Hero("Finn the Human", 10_000)
Jake = Hero("Jake the Dog", 10_000)

print(hash(Finn))
print(hash(Jake))
-8707075988359731747
-2276052447712954388

Sortable

Для возмоТности примСнСния ΠΊ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡΠΌ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² Ρ‚Π°ΠΊΠΈΡ… ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² ΠΊΠ°ΠΊ sort() ΠΈΠ»ΠΈ max() Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ, ΠΊΠ°ΠΊ ΠΈ Π² случаС Comparable, ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ __lt__ (мСньшС) ΠΈ __eq__ (Ρ€Π°Π²Π½ΠΎ), Π° Ρ‚Π°ΠΊΠΆΠ΅ Π·Π°Π΄Π΅ΠΉΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ @functools.total_ordering.

Для Π±ΠΎΠ»Π΅Π΅ прСдсказумого повСдСния ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° Π² условиях Ρ€Π°Π·Π»ΠΈΡ‡Π½ΠΎΠ³ΠΎ контСкста Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ ΠΏΠΎΠ»Π½ΠΎΠ΅ мноТСство Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ сравнСния (__lt()__, __gt()__, __le__() ΠΈ __ge__()).

Для ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° создадим класс студСнтов, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… ΠΌΠΎΠΆΠ½ΠΎ Π±ΡƒΠ΄Π΅Ρ‚ ΡΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π½Π΅ ΠΏΠΎ ΠΈΠΌΠ΅Π½ΠΈ, Π° ΠΏΠΎ срСднСму Π±Π°Π»Π»Ρƒ.

from functools import total_ordering
from statistics import mean


@total_ordering
class Student:
    def __init__(self, name: str, grades: list[int]):
        self.name: str = name
        self.grades: list[int] = grades

    def _is_valid_operand(self, other):
        return hasattr(other, "name") and hasattr(other, "grades")

    def __eq__(self, other):
        if not self._is_valid_operand(other):
            return NotImplemented
        return mean(self.grades) == mean(other.grades)

    def __lt__(self, other):
        if not self._is_valid_operand(other):
            return NotImplemented
        return mean(self.grades) < mean(other.grades)

    # ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΠΌ str для Ρ‡Π΅Π»ΠΎΠ²Π΅ΠΊΠΎ-Ρ‡ΠΈΡ‚Π°Π΅ΠΌΠΎΠΉ Ρ€Π΅ΠΏΡ€Π΅Π·Π΅Π½Ρ‚Π°Ρ†ΠΈΠΈ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°
    def __str__(self):
        return self.name + " " + str(mean(self.grades))


Melissa = Student("Melissa Andrew", [4, 3, 4, 5, 4])
Peter = Student("Peter Shining Jr.", [3, 3, 4, 5, 3])
Joe = Student("Just Joe", [5, 5, 4, 5, 5])

print([str(stud) for stud in sorted([Peter, Melissa, Joe], reverse=True)])
['Just Joe 4.8', 'Melissa Andrew 4', 'Peter Shining Jr. 3.6']

Callable

Для возмоТности Π²Ρ‹Π·ΠΎΠ²Π° ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° Π² качСствС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΌΠ΅Ρ‚ΠΎΠ΄ __call__. Π’ΠΈΠΏΡ‹, ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‰ΠΈΠ΅ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΠΈΡ… Π²Ρ‹Π·ΠΎΠ²Π° Π² качСствС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, ΠΌΠΎΠ³ΡƒΡ‚ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Ρ‚ΡŒ Π½Π°Π±ΠΎΡ€ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ².

class Counter:
    def __init__(self):
        self.i = 0
    def __call__(self):
        self.i += 1
        return self.i
 
counter = Counter()

print(counter())
print(counter())
print(counter())
1
2
3

@classmethod нСльзя Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ Π² качСствС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ:

class Check():
    @classmethod 
    def class_method(cls):
        pass 

    @staticmethod
    def static_method():
        pass

    def instance_method(self):
        pass 

for attr, val in vars(Check).items():
    if not attr.startswith("__"):
        print (attr, f"{'is' if callable(val) else 'is NOT'} callable")
class_method is NOT callable
static_method is callable
instance_method is callable

ΠšΠΎΠ½Ρ‚Π΅ΠΊΡΡ‚Π½Ρ‹Π΅ ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ€Ρ‹, описанныС Π² ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅ΠΉ Π³Π»Π°Π²Π΅, Ρ‚ΠΎΠΆΠ΅, ΠΊΠ°ΠΊ ΠΌΡ‹ Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ Π²ΠΈΠ΄ΠΈΠΌ, ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡŽΡ‚ΡΡ Ρ‡Π΅Ρ€Π΅Π· ΡƒΡ‚ΠΈΠ½ΡƒΡŽ Ρ‚ΠΈΠΏΠΈΠ·Π°Ρ†ΠΈΡŽ ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² __enter__ ΠΈ __exit__.

Утиная типизация ΠΈΡ‚Π΅Ρ€ΠΈΡ€ΡƒΠ΅ΠΌΡ‹Ρ… ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ²

Iterable

Iterable β€” ΠΎΠ±ΡŠΠ΅ΠΊΡ‚, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ для прСдоставлСния возмоТности ΠΏΠΎΠΎΡ‡Π΅Ρ€Ρ‘Π΄Π½ΠΎΠ³ΠΎ ΠΏΡ€ΠΎΡ…ΠΎΠ΄Π° ΠΏΠΎ всСм своим элСмСнтам Π΄ΠΎΠ»ΠΆΠ΅Π½ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Ρ‹Π²Π°Ρ‚ΡŒ ΠΌΠ΅Ρ‚ΠΎΠ΄ __iter__(), Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‰ΠΈΠΉ ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€. Π£ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° с ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠΌ __iter__() автоматичСски Π½Π°Ρ‡ΠΈΠ½Π°Π΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ ΠΌΠ΅Ρ‚ΠΎΠ΄ __contains__().

class MyIterable:
    def __init__(self, *args):
        self.a = list(args)

    def __iter__(self):
        return iter(self.a)


mi = MyIterable(1, 2, 3, 4)
print([el for el in mi])
print(1 in mi)  # __contains__()
[1, 2, 3, 4]
True

Collection

Collection β€” ΠΎΠ±ΡŠΠ΅ΠΊΡ‚, ΠΏΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²Π»ΡΡŽΡ‰ΠΈΠΉ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΠΏΠΎΠΎΡ‡Π΅Ρ€Ρ‘Π΄Π½ΠΎΠ³ΠΎ ΠΏΡ€ΠΎΡ…ΠΎΠ΄Π° ΠΏΠΎ всСм своим элСмСнтам ΠΈ ΠΎΠ±Π»Π°Π΄Π°ΡŽΡ‰ΠΈΠΉ ΠΊΠΎΠ½Π΅Ρ‡Π½Ρ‹ΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ΠΎΠΌ.
Π’ Π΄ΠΎΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΊ iter() Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½ ΠΌΠ΅Ρ‚ΠΎΠ΄ len(), Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‰ΠΈΠΉ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΊΠΎΠ»Π»Π΅ΠΊΡ†ΠΈΠΈ.

class MyCollection:
    def __init__(self, *args):
        self.a = list(args)

    def __iter__(self):
        return iter(self.a)

    def __len__(self):
        return len(self.a)


mc = MyCollection(1, 2, 3, 4)
print([el for el in mc])
print(1 in mc)
print(len(mc))
[1, 2, 3, 4]
True
4

Sequence

Π’Ρ€Π΅Π±ΡƒΠ΅Ρ‚ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ len() and getitem(). getitem() Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΎΡ‚Π΄Π°Π²Π°Ρ‚ΡŒ элСмСнт с Ρ‚Ρ€Π΅Π±ΡƒΠ΅ΠΌΡ‹ΠΌ индСксом ΠΈΠ»ΠΈ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ IndexError.
АвтоматичСски Π±ΡƒΠ΄ΡƒΡ‚ ΠΏΠΎΡ€ΠΎΠΆΠ΄Π΅Π½Ρ‹ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ iter(), reversed() ΠΈ contains().

class MySequence:
    def __init__(self, a):
        self.a = a
    def __len__(self):
        return len(self.a)
    def __getitem__(self, i):
        return self.a[i]

ABC Sequence

ΠšΠΎΠ»Π»Π΅ΠΊΡ†ΠΈΡ Sequence ΠΈΠ· Abstract Base Classes for Containers прСдоставляСт Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½Π½Ρ‹ΠΉ интСрфСйс ΠΏΠΎ ΡΡ€Π°Π²Π½Π΅Π½ΠΈΡŽ с ΠΎΠ±Ρ‹Ρ‡Π½ΠΎΠΉ Sequence.
Всё Ρ‚Π°ΠΊ ΠΆΠ΅ трСбуя __getitem__ ΠΈ __len__, прСдоставляСт __contains__, __iter__, __reversed__, index ΠΈ count.

from collections import abc

class MyAbcSequence(abc.Sequence):
    def __init__(self, a):
        self.a = a
    def __len__(self):
        return len(self.a)
    def __getitem__(self, i):
        return self.a[i]

Π’Π°Π±Π»ΠΈΡ†Π° Ρ‚Ρ€Π΅Π±ΡƒΠ΅ΠΌΡ‹Ρ… ΠΈ доступных ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ²:

+------------+------------+------------+------------+--------------+
|            |  Iterable  | Collection |  Sequence  | ABC Sequence |
+------------+------------+------------+------------+--------------+
| iter()     |   Π½ΡƒΠΆΠ΅Π½    |   Π½ΡƒΠΆΠ΅Π½    |     +      |      +       |
| contains() |     +      |     +      |     +      |      +       |
| len()      |            |   Π½ΡƒΠΆΠ΅Π½    |   Π½ΡƒΠΆΠ΅Π½    |    Π½ΡƒΠΆΠ΅Π½     |
| getitem()  |            |            |   Π½ΡƒΠΆΠ΅Π½    |    Π½ΡƒΠΆΠ΅Π½     |
| reversed() |            |            |     +      |      +       |
| index()    |            |            |            |      +       |
| count()    |            |            |            |      +       |
+------------+------------+------------+------------+--------------+

И Π²ΠΎΠΎΠ±Ρ‰Π΅, ΠΏΠΎΡ‚Ρ‰Π°Ρ‚Π΅Π»ΡŒΠ½Π΅Π΅ ΠΏΡ€ΠΈΡΠΌΠΎΡ‚Ρ€ΠΈΡ‚Π΅ΡΡŒ с collections.abc, Ρ‚Π°ΠΌ Π΅ΡΡ‚ΡŒ мноТСство Π·Π°Π³ΠΎΡ‚ΠΎΠ²ΠΎΠΊ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΏΠΎΠΌΠΎΠ³ΡƒΡ‚ Π²Π°ΠΌ ΡΡΠΊΠΎΠ½ΠΎΠΌΠΈΡ‚ΡŒ Π½Π΅ΠΌΠ°Π»ΠΎ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ. НапримСр, Ссли ΠΊ упомянутым ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ABC Sequence __getitem__ ΠΈ __len__ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ __setitem__, __delitem__ ΠΈ insert, Ρ‚ΠΎ Π² ΠΎΡ‚Π²Π΅Ρ‚ Π²Ρ‹ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚Π΅ ΠΊΠΎΠ»Π»Π΅ΠΊΡ†ΠΈΡŽ MutableSequence, которая, ΠΊΡ€ΠΎΠΌΠ΅ возмоТностСй Sequence, ΠΈΠΌΠ΅Π΅Ρ‚ Π΅Ρ‰Π΅ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ append, reverse, extend, pop, remove ΠΈ __iadd__.

ΠšΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ²

Π’ Python ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ присваивания (=) Π½Π΅ ΠΊΠΎΠΏΠΈΡ€ΡƒΠ΅Ρ‚ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹. ВмСсто этого ΠΎΠ½ создаСт связь ΠΌΠ΅ΠΆΠ΄Ρƒ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠΌ ΠΈ ΠΈΠΌΠ΅Π½Π΅ΠΌ Ρ†Π΅Π»Π΅Π²ΠΎΠΉ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ. Π§Ρ‚ΠΎΠ±Ρ‹ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ ΠΊΠΎΠΏΠΈΠΈ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° Π² Python, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΌΠΎΠ΄ΡƒΠ»ΡŒ copy. Π‘ΠΎΠ»Π΅Π΅ Ρ‚ΠΎΠ³ΠΎ, сущСствуСт Π΄Π²Π° способа создания ΠΊΠΎΠΏΠΈΠΉ для Π΄Π°Π½Π½ΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ модуля copy.

Shallow Copy – это побитовая копия ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°. Π‘ΠΎΠ·Π΄Π°Π½Π½Ρ‹ΠΉ скопированный ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΈΠΌΠ΅Π΅Ρ‚ Ρ‚ΠΎΡ‡Π½ΡƒΡŽ копию Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ Π² исходном ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π΅. Если ΠΎΠ΄Π½ΠΎ ΠΈΠ· Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ являСтся ссылкой Π½Π° Π΄Ρ€ΡƒΠ³ΠΈΠ΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹, ΠΊΠΎΠΏΠΈΡ€ΡƒΡŽΡ‚ΡΡ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ адрСса ссылок Π½Π° Π½ΠΈΡ….

Deep Copy – рСкурсивно ΠΊΠΎΠΏΠΈΡ€ΡƒΠ΅Ρ‚ всС значСния ΠΎΡ‚ исходного ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° ΠΊ Ρ†Π΅Π»Π΅Π²ΠΎΠΌΡƒ, Ρ‚. Π΅. Π΄ΡƒΠ±Π»ΠΈΡ€ΡƒΠ΅Ρ‚ Π΄Π°ΠΆΠ΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ссылаСтся исходный ΠΎΠ±ΡŠΠ΅ΠΊΡ‚.

from copy import copy, deepcopy


class A:
    def __init__(self, val: list):
        self.val = val

    def change_val(self, val: list):
        self.val = val


a = A(list("one"))

# ΠŸΡ€ΠΎΡΡ‚ΠΎ ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ссылки Π½Π° ΠΎΠ±ΡŠΠ΅ΠΊΡ‚
b = a  # Assignment

# Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ Π½ΠΎΠ²ΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° ΠΈ ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ссылок Π½Π° ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹, Π½Π°ΠΉΠ΄Π΅Π½Π½Ρ‹Π΅ Π² ΠΈΠ·Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎΠΌ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π΅
c = copy(a)  # Shallow copy

# Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ Π½ΠΎΠ²ΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° с ΠΏΠΎΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ рСкурсивным ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ содСрТащихся Π²Π½ΡƒΡ‚Ρ€ΠΈ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ²
d = deepcopy(a)  # Deep Copy

b.change_val(list("two"))
c.change_val(list("three"))
d.change_val(list("four"))

print(a.val, b.val, c.val, d.val)
print(id(a), id(b), id(c), id(d))
print(id(a.val[1]), id(c.val[1]))
['t', 'w', 'o'] ['t', 'w', 'o'] ['t', 'h', 'r', 'e', 'e'] ['f', 'o', 'u', 'r']
1795295519472 1795295519472 1793149281968 1793149273808
1795217224688 1795217321264

НаслСдованиС

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age


class Employee(Person):
    def __init__(self, name, age, staff_num, email):
        super().__init__(name, age)
        self.staff_num = staff_num
        self.email = email

ΠœΠ½ΠΎΠΆΠ΅ΡΡ‚Π²Π΅Π½Π½ΠΎΠ΅ наслСдованиС

ΠŸΡ€ΠΈ мноТСствСнном наслСдовании порядок Ρ€Π°Π·Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² (method resolution order, MRO) позволяСт ΠŸΠΈΡ‚ΠΎΠ½Ρƒ Π²Ρ‹ΡΡΠ½ΠΈΡ‚ΡŒ, ΠΈΠ· ΠΊΠ°ΠΊΠΎΠ³ΠΎ класса-ΠΏΡ€Π΅Π΄ΠΊΠ° Π½ΡƒΠΆΠ½ΠΎ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ ΠΌΠ΅Ρ‚ΠΎΠ΄, Ссли ΠΎΠ½ Π½Π΅ ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠ΅Π½ нСпосрСдствСнно Π² классС-ΠΏΠΎΡ‚ΠΎΠΌΠΊΠ΅.

class PrivateStaffData:
    def __init__(self, private_email):
        self.private_email = private_email


class PublicStaffData:
    def __init__(self, work_email):
        self.work_email = work_email


class StaffData(PrivateStaffData, PublicStaffData):
    def __init__(self, private_email, work_email):
        super().__init__()

print(StaffData.mro())
[<class '__main__.StaffData'>, <class '__main__.PrivateStaffData'>, <class '__main__.PublicStaffData'>, <class 'object'>]

MRO строит ΠΈΠ΅Ρ€Π°Ρ€Ρ…ΠΈΡŽ наслСдования Ρ‚Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π±ΠΎΠ»Π΅Π΅ спСцифичныС ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ класса-ΠΏΠΎΡ‚ΠΎΠΌΠΊΠ° ΠΏΠ΅Ρ€Π΅ΠΊΡ€Ρ‹Π²Π°Π»ΠΈ ΠΌΠ΅Π½Π΅Π΅ спСцифичныС ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ класса-ΠΏΡ€Π΅Π΄ΠΊΠ°. MRO строит упорядочСнный список классов, Π² ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚ΡŒΡΡ поиск ΠΌΠ΅Ρ‚ΠΎΠ΄Π° слСва Π½Π°ΠΏΡ€Π°Π²ΠΎ (линСаризация класса).

Для Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹ Ρ€ΠΎΠΌΠ±ΠΎΠ²ΠΈΠ΄Π½ΠΎΠΉ структуры (которая нСявно присутствуСт Π΄Π°ΠΆΠ΅ Π² ΠΏΡ€ΠΎΡΡ‚Π΅ΠΉΡˆΠ΅ΠΌ случаС, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ всС классы Π½Π°ΡΠ»Π΅Π΄ΡƒΡŽΡ‚ΡΡ ΠΎΡ‚ object) линСаризация Π΄ΠΎΠ»ΠΆΠ½Π° Π±Ρ‹Ρ‚ΡŒ ΠΌΠΎΠ½ΠΎΡ‚ΠΎΠ½Π½ΠΎΠΉ. ΠœΠΎΠ½ΠΎΡ‚ΠΎΠ½Π½ΠΎΡΡ‚ΡŒ β€” свойство, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ соблюдСния Π² Π»ΠΈΠ½Π΅Π°Ρ€ΠΈΠ·Π°Ρ†ΠΈΠΈ класса-ΠΏΠΎΡ‚ΠΎΠΌΠΊΠ° Ρ‚ΠΎΠ³ΠΎ ΠΆΠ΅ порядка слСдования классов-ΠΏΡ€Π°Ρ€ΠΎΠ΄ΠΈΡ‚Π΅Π»Π΅ΠΉ, Ρ‡Ρ‚ΠΎ ΠΈ Π² Π»ΠΈΠ½Π΅Π°Ρ€ΠΈΠ·Π°Ρ†ΠΈΠΈ класса-родитСля. ЛинСаризация ΠΏΠΎ сути являСтся топологичСской сортировкой. Π’ Ρ€Π°Π½Π½ΠΈΡ… вСрсиях Python использовался Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ DLR, сСйчас Π² Ρ…ΠΎΠ΄Ρƒ C3-линСаризация.

Если послС удовлСтворСния свойства монотонности остаётся большС ΠΎΠ΄Π½ΠΎΠ³ΠΎ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Π° Π»ΠΈΠ½Π΅Π°Ρ€ΠΈΠ·Π°Ρ†ΠΈΠΈ, Ρ‚ΠΎ примСняСтся порядок локального ΡΡ‚Π°Ρ€ΡˆΠΈΠ½ΡΡ‚Π²Π° (local precedence ordering), Ρ‚. Π΅. порядок соблюдСния для классов-Ρ€ΠΎΠ΄ΠΈΡ‚Π΅Π»Π΅ΠΉ Π² Π»ΠΈΠ½Π΅Π°Ρ€ΠΈΠ·Π°Ρ†ΠΈΠΈ класса-ΠΏΠΎΡ‚ΠΎΠΌΠΊΠ° Ρ‚ΠΎΠ³ΠΎ ΠΆΠ΅ порядка, Ρ‡Ρ‚ΠΎ ΠΈ ΠΏΡ€ΠΈ Π΅Π³ΠΎ объявлСнии. НапримСр, Ссли класс объявлСн ΠΊΠ°ΠΊ D(A, B, C), Ρ‚ΠΎ Π² Π»ΠΈΠ½Π΅Π°Ρ€ΠΈΠ·Π°Ρ†ΠΈΠΈ D класс A Π΄ΠΎΠ»ΠΆΠ΅Π½ ΡΡ‚ΠΎΡΡ‚ΡŒ Ρ€Π°Π½ΡŒΡˆΠ΅ B, Π° класс B β€” Ρ€Π°Π½ΡŒΡˆΠ΅ C.

Если Ρ€Π°Π·Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ всСх ΠΊΠΎΠ½Ρ„Π»ΠΈΠΊΡ‚ΠΎΠ² ΠΏΡ€ΠΈ Π»ΠΈΠ½Π΅Π°Ρ€ΠΈΠ·Π°Ρ†ΠΈΠΈ Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, Ρ‚ΠΎ остаСтся Ρ‚Ρ€ΠΈ ΠΏΡƒΡ‚ΠΈ:
1 - ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½ΠΎΠΉ мСст классов-ΠΏΡ€Π΅Π΄ΠΊΠΎΠ² Π² объявлСнии класса-ΠΏΠΎΡ‚ΠΎΠΌΠΊΠ° (Π½ΠΎ это ΠΏΠΎΠΌΠΎΠ³Π°Π΅Ρ‚ Π΄Π°Π»Π΅ΠΊΠΎ Π½Π΅ всСгда);
2 - пСрСсмотр ΠΈΠ΅Ρ€Π°Ρ€Ρ…ΠΈΠΈ наслСдования;
3 - ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ своСй собствСнной Π»ΠΈΠ½Π΅Π°Ρ€ΠΈΠ·Π°Ρ†ΠΈΠΈ Ρ‡Π΅Ρ€Π΅Π· мСтаклассы ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° mro(cls). Но ΠΏΡ€ΠΈ Π΄Π°Π½Π½ΠΎΠΌ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄Π΅ Π½Π°Π΄ΠΎ Π±Ρ‹Ρ‚ΡŒ Π³ΠΎΡ‚ΠΎΠ²Ρ‹ΠΌ ΠΊ Ρ‚ΠΎΠΌΡƒ, Ρ‡Ρ‚ΠΎ Π±ΡƒΠ΄Π΅Ρ‚ использован ΠΌΠ΅Π½Π΅Π΅ спСцифичный ΠΌΠ΅Ρ‚ΠΎΠ΄ класса-родитСля вмСсто Π±ΠΎΠ»Π΅Π΅ спСцифичного ΠΌΠ΅Ρ‚ΠΎΠ΄Π° класса-ΠΏΠΎΡ‚ΠΎΠΌΠΊΠ°.

ΠŸΡ€ΠΈ Π·Π°Π΄Π°Π½ΠΈΠΈ своСй собствСнной Π»ΠΈΠ½Π΅Π°Ρ€ΠΈΠ·Π°Ρ†ΠΈΠΈ Python ΠΎΡ‚ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ встроСнныС ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ.

НаслСдованиС классов со __slots__

ΠŸΡ€ΠΈ ΠΎΠ΄ΠΈΠ½ΠΎΡ‡Π½ΠΎΠΌ наслСдовании __slots__ Π½ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½ΠΎ наслСдуСтся, Π½ΠΎ это Π½Π΅ ΠΏΡ€Π΅Π΄ΠΎΡ‚Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ созданиС __dict__:

class SlotsClass:
  __slots__ = 'foo', 'bar'

  
class ChildSlotsClass(SlotsClass):
  ...


obj = ChildSlotsClass()
print(obj.__slots__)

obj.something_new = "underwater stones"
print(obj.__dict__)
('foo', 'bar')
{'something_new': 'underwater stones'}

Для ограничСния Π΄ΠΎΡ‡Π΅Ρ€Π½Π΅Π³ΠΎ класса слотами Π½ΡƒΠΆΠ½ΠΎ Π² Π½Ρ‘ΠΌ снова ΠΏΡ€ΠΈΡΠ²ΠΎΠΈΡ‚ΡŒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Ρƒ __slots__, Ρ€ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΡΠΊΠΈΠ΅ поля Π΄ΡƒΠ±Π»ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π½Π΅ Π½ΡƒΠΆΠ½ΠΎ.

class SlotsClass:
  __slots__ = 'foo', 'bar'

  
class ChildSlotsClass(SlotsClass):
  __slots__ = 'baz'


obj = ChildSlotsClass()
# obj.something_new = "underwater stones"  # Raises AttributeError: 'ChildSlotsClass' object has no attribute 'something_new'

ΠœΠ½ΠΎΠΆΠ΅ΡΡ‚Π²Π΅Π½Π½ΠΎΠ΅ ΠΆΠ΅ наслСдованиС классов с нСпустыми __slots__ Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ.

ΠœΠ΅Ρ‚Π°ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅

Π§Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠ΅ класс? Π­Ρ‚ΠΎ, Π² ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΠ΅, просто кусок ΠΊΠΎΠ΄Π°, ΠΎΠΏΠΈΡΡ‹Π²Π°ΡŽΡ‰ΠΈΠΉ, ΠΊΠ°ΠΊ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚. Но Π² Python класс β€” это Π½Π΅Ρ‡Ρ‚ΠΎ большСС, классы Ρ‚Π°ΠΊΠΆΠ΅ ΡΠ²Π»ΡΡŽΡ‚ΡΡ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°ΠΌΠΈ; ΠΊΠ°ΠΊ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ ΠΊΠ»ΡŽΡ‡Π΅Π²ΠΎΠ΅ слово class, Python исполняСт ΠΊΠΎΠΌΠ°Π½Π΄Ρƒ ΠΈ создаёт ΠΎΠ±ΡŠΠ΅ΠΊΡ‚:

class A:
    ...

Π’ памяти Π±ΡƒΠ΄Π΅Ρ‚ создан ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ с ΠΈΠΌΠ΅Π½Π΅ΠΌ A.

ΠšΠ»Π°ΡΡΡ‹, ΠΊΠ°ΠΊ ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹, ΠΌΠΎΠΆΠ½ΠΎ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ Π½Π° Ρ…ΠΎΠ΄Ρƒ:

def custom_class(name):
    if name == "foo":
        class Foo:
            ...

        return Foo  # Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΈΠΌΠ΅Π½Π½ΠΎ класс, Π° Π½Π΅ экзСмпляр
    else:
        class Bar:
            ...

        return Bar


MyClass = custom_class("foo")
print(MyClass)  # Ѐункция Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ класс, Π° Π½Π΅ экзСмпляр
print(my_class := MyClass())  # МоТно ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ экзСмпляр класса
<class '__main__.custom_class.<locals>.Foo'>
<__main__.custom_class.<locals>.Foo object at 0x000001F0ECF97610>

Но это Π½Π΅ ΠΎΡ‡Π΅Π½ΡŒ ΡƒΠ΄ΠΎΠ±Π½ΠΎ, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ Π½Π°ΠΌ Π΄ΠΎ сих ΠΏΠΎΡ€ приходится ΠΏΠΈΡΠ°Ρ‚ΡŒ вСсь ΠΊΠΎΠ΄ класса.

Основная Ρ†Π΅Π»ΡŒ мСтаклассов β€” автоматичСски ΠΈΠ·ΠΌΠ΅Π½ΡΡ‚ΡŒ класс Π² ΠΌΠΎΠΌΠ΅Π½Ρ‚ создания, гСнСрируя классы Π² соотвСтствии с Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΌ контСкстом.
Π‘Π°ΠΌΠΈ ΠΏΠΎ сСбС мСтаклассы достаточно просты ΠΈ Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‚ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½ΠΎ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ:
ΠΏΠ΅Ρ€Π΅Ρ…Π²Π°Ρ‚Ρ‹Π²Π°ΡŽΡ‚ созданиС класса,
ΠΈΠ·ΠΌΠ΅Π½ΡΡŽΡ‚ класс,
Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‚ ΠΌΠΎΠ΄ΠΈΡ„ΠΈΡ†ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ класс.

Но ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ Π»ΠΎΠ³ΠΈΠΊΡƒ Ρ€Π°Π±ΠΎΡ‚Ρ‹ мСтаклассов Π½Π°ΡΡ‹Ρ‰Π°ΡŽΡ‚ Π²Π΅Ρ‰Π°ΠΌΠΈ Π²Ρ€ΠΎΠ΄Π΅ интроспСкции ΠΈΠ»ΠΈ манипуляциСй наслСдованиСм, поэтому ΠΊΠΎΠ½Π΅Ρ‡Π½Ρ‹ΠΉ ΠΊΠΎΠ΄ выглядит достаточно Π³Ρ€ΠΎΠΌΠΎΠ·Π΄ΠΊΠΎ.

Π—Π΄Π΅ΡΡŒ Π½Π΅ΠΏΠ»ΠΎΡ…ΠΎ Π±Ρ‹Π»ΠΎ Π±Ρ‹ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Π΅Ρ‰Π΅ ΠΏΠ°Ρ€Ρƒ страниц ΠΏΡ€ΠΎ Π½ΡŒΡŽΠ°Π½ΡΡ‹ создания ΠΈ Ρ€Π°Π±ΠΎΡ‚Ρ‹ мСтаклассов, Π½ΠΎ ΠΏΠΎΠ·Π²ΠΎΠ»ΡŒΡ‚Π΅ ΠΏΠ΅Ρ€Π΅Π°Π΄Ρ€Π΅ΡΠΎΠ²Π°Ρ‚ΡŒ вас Π½Π° Π²ΠΎΡ‚ эту ΠΏΡ€Π΅ΠΊΡ€Π°ΡΠ½ΡƒΡŽ ΡΡ‚Π°Ρ‚ΡŒΡŽ.

ΠŸΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ мСтаклассов Ρ…ΠΎΡ€ΠΎΡˆΠΎ Ρ€Π΅ΡˆΠ°ΡŽΡ‚ΡΡ Π·Π°Π΄Π°Ρ‡ΠΈ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ классов для ORM. Π‘ΠΊΠ°ΠΆΠ΅ΠΌ, для

class Person(models.Model):
    name = models.CharField(max_length=30)
    age = models.IntegerField()

ΠΊΠΎΠ΄

keanu = Person(name="Keanu Reeves", age=58)
print(keanu.age)

распСчатаСт число, взятоС ΠΈΠ· Π‘Π”, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ models.Model опрСдСляСт __metaclass__, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ сотворит Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ магию ΠΈ ΠΏΡ€Π΅Π²Ρ€Π°Ρ‚ΠΈΡ‚ класс Person, ΠΎΠΏΡ€Π΅Π΄Π΅Π»Ρ‘Π½Π½Ρ‹ΠΉ достаточно простым Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ΠΌ, Π² ΡΠ»ΠΎΠΆΠ½ΡƒΡŽ привязку ΠΊ Π±Π°Π·Π΅ Π΄Π°Π½Π½Ρ‹Ρ….

Если Π²Ρ‹ всё Π΅Ρ‰Π΅ Π»ΠΎΠΌΠ°Π΅Ρ‚Π΅ Π³ΠΎΠ»ΠΎΠ²Ρƒ, Π³Π΄Π΅ Π±Ρ‹ Π²Π°ΠΌ ΠΏΡ€ΠΈΡˆΠΈΡ‚ΡŒ ΠΌΠ΅Ρ‚Π°ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π² своём Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΌ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π΅, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΡ‚ΠΎΠΌ ΡƒΠΏΠΎΠΌΡΠ½ΡƒΡ‚ΡŒ ΠΎΠ± этом Π² Ρ€Π΅Π·ΡŽΠΌΠ΅, Ρ‚ΠΎ Π²ΠΎΡ‚ Π²Π°ΠΌ Π½Π° 147 % умСстная Ρ†ΠΈΡ‚Π°Ρ‚Π° ΠΈΠ· Π’ΠΈΠΌΠ° ΠŸΠΈΡ‚Π΅Ρ€ΡΠ°: Β«[Metaclasses] are deeper magic than 99% of users should ever worry about. If you wonder whether you need them, you don’t (the people who actually need them know with certainty that they need them, and don’t need an explanation about why)Β», Ρ‡Ρ‚ΠΎ Π² вольном ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄Π΅ ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚ Β«ΠœΠ΅Ρ‚Π°ΠΊΠ»Π°ΡΡΡ‹ Π½ΡƒΠΆΠ½Ρ‹ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΡƒΠ²Π΅Ρ€Π΅Π½Π½Ρ‹ΠΌ Π² сСбС людям, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Ρ‚ΠΎΡ‡Π½ΠΎ Π·Π½Π°ΡŽΡ‚, Ρ‡Π΅Π³ΠΎ хотят ΠΎΡ‚ ΠΆΠΈΠ·Π½ΠΈ, Π° вовсС Π½Π΅ Ρ‚Π΅Π±Π΅Β».

@abstractmethod

Абстрактный класс Π² Python - Π°Π½Π°Π»ΠΎΠ³ интСрфСйса Π² Π΄Ρ€ΡƒΠ³ΠΈΡ… языках (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π² C#) - класс, содСрТащий Ρ‚ΠΎΠ»ΡŒΠΊΠΎ сигнатуры ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ², Π±Π΅Π· Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ. РСализация ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² ΠΏΠ΅Ρ€Π΅Π»ΠΎΠΆΠ΅Π½Π° Π½Π° классы-ΠΏΠΎΡ‚ΠΎΠΌΠΊΠΈ. Π—Π°Π΄Π°Ρ‡Π° абстрактного класса соотвСтствуСт Π·Π°Π΄Π°Ρ‡Π΅ интСрфСйса - ΠΎΠ±ΡΠ·Π°Ρ‚ΡŒ классы-ΠΏΠΎΡ‚ΠΎΠΌΠΊΠΈ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Ρ‹Π²Π°Ρ‚ΡŒ всС ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹, Π·Π°Π»ΠΎΠΆΠ΅Π½Π½Ρ‹Π΅ Π² классС-Ρ€ΠΎΠ΄ΠΈΡ‚Π΅Π»Π΅.

import abc


class AbstractClass(metaclass=abc.ABCMeta):

    @abc.abstractmethod
    def return_anything(self):
        return


class ConcreteClass(AbstractClass):

    def return_anything(self):
        return 42


c = ConcreteClass()
print(c.return_anything())
42

Если Π½Π΅ ΡΠΏΠ΅Ρ†ΠΈΡ„ΠΈΡ†ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ return_anything() Π² ConcreteClass, ΠΏΡ€ΠΈ ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΠ΅ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ c.return_anything() Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹Π±Ρ€ΠΎΡˆΠ΅Π½ΠΎ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ TypeError: Can't instantiate abstract class ConcreteClass with abstract method return_anything.

5. ВнутрСнности языка

Β«Π­Ρ‚Π° стСна тянСтся с юга Π½Π° сСвСр, ΠΈ Π² Π½Π΅ΠΉ Π΅ΡΡ‚ΡŒ лишь ΠΎΠ΄ΠΈΠ½ ΠΏΡ€ΠΎΡ…ΠΎΠ΄, скрываСмый ΠΏΡ‹Π»Π°ΡŽΡ‰ΠΈΠΌ ΠΏΠ»Π°ΠΌΠ΅Π½Π΅ΠΌ, Ρ‚Π°ΠΊ Ρ‡Ρ‚ΠΎ Π½ΠΈ ΠΎΠ΄ΠΈΠ½ смСртный Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ Ρ‚ΡƒΠ΄Π° ΠΏΡ€ΠΎΠ½ΠΈΠΊΠ½ΡƒΡ‚ΡŒ.Β»

Β«ΠŸΡ€ΠΈΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ сэра Π”ΠΆΠΎΠ½Π° МандСвиля».

Language skeleton

Π‘Π±ΠΎΡ€Ρ‰ΠΈΠΊ мусора

Π‘Ρ‚Π°Π½Π΄Π°Ρ€Ρ‚Π½Ρ‹ΠΉ ΠΈΠ½Ρ‚Π΅Ρ€ΠΏΡ€Π΅Ρ‚Π°Ρ‚ΠΎΡ€ Python (CPython) ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ для сборки мусора Π΄Π²Π° Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΠ°: подсчСт ссылок (reference counting, Π½Π΅ΠΎΡ‚ΠΊΠ»ΡŽΡ‡Π°Π΅ΠΌΡ‹ΠΉ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ) ΠΈ garbage collector (стандартный ΠΌΠΎΠ΄ΡƒΠ»ΡŒ gc ΠΈΠ· Python, ΠΎΡ‚ΠΊΠ»ΡŽΡ‡Π°Π΅ΠΌΡ‹ΠΉ). Алгоритм подсчСта ссылок Π½Π΅ ΡƒΠΌΠ΅Π΅Ρ‚ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡ‚ΡŒ цикличСскиС ссылки.

ЦикличСскиС ссылки ΠΌΠΎΠ³ΡƒΡ‚ Π½Π°Ρ…ΠΎΠ΄ΠΈΡ‚ΡŒΡΡ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π² β€œΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π½Ρ‹Ρ…β€ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°Ρ…, Ρ‚.Π΅. Π² ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°Ρ…, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠΎΠ³ΡƒΡ‚ Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Π² списках, словарях, классах ΠΈ ΠΊΠΎΡ€Ρ‚Π΅ΠΆΠ°Ρ…. GC Π½Π΅ слСдит Π·Π° простыми ΠΈ нСизмСняСмыми Ρ‚ΠΈΠΏΠ°ΠΌΠΈ, Π·Π° ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ΠΌ ΠΊΠΎΡ€Ρ‚Π΅ΠΆΠ΅ΠΉ. НСкоторыС ΠΊΠΎΡ€Ρ‚Π΅ΠΆΠΈ ΠΈ словари Ρ‚Π°ΠΊΠΆΠ΅ ΠΈΡΠΊΠ»ΡŽΡ‡Π°ΡŽΡ‚ΡΡ ΠΈΠ· списка слСТки ΠΏΡ€ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹Ρ… условий. Π‘ΠΎ всСми ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹ΠΌΠΈ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°ΠΌΠΈ Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎ справляСтся Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ подсчСта ссылок.

Π’ ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ ΠΎΡ‚ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΠ° подсчСта ссылок, цикличСский GC Π½Π΅ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ постоянно, Π° запускаСтся пСриодичСски. GC раздСляСт всС ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ Π½Π° 3 поколСния. НовыС ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ ΠΏΠΎΠΏΠ°Π΄Π°ΡŽΡ‚ Π² ΠΏΠ΅Ρ€Π²ΠΎΠ΅ ΠΏΠΎΠΊΠΎΠ»Π΅Π½ΠΈΠ΅. Если Π½ΠΎΠ²Ρ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Π²Ρ‹ΠΆΠΈΠ²Π°Π΅Ρ‚ процСсс сборки мусора, Ρ‚ΠΎ ΠΎΠ½ пСрСмСщаСтся Π² ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π΅ ΠΏΠΎΠΊΠΎΠ»Π΅Π½ΠΈΠ΅. Π§Π΅ΠΌ Π²Ρ‹ΡˆΠ΅ ΠΏΠΎΠΊΠΎΠ»Π΅Π½ΠΈΠ΅, Ρ‚Π΅ΠΌ Ρ€Π΅ΠΆΠ΅ ΠΎΠ½ΠΎ сканируСтся. Π’Π°ΠΊ ΠΊΠ°ΠΊ Π½ΠΎΠ²Ρ‹Π΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ Π·Π°Ρ‡Π°ΡΡ‚ΡƒΡŽ ΠΈΠΌΠ΅ΡŽΡ‚ ΠΎΡ‡Π΅Π½ΡŒ малСнький срок ΠΆΠΈΠ·Π½ΠΈ (ΡΠ²Π»ΡΡŽΡ‚ΡΡ Π²Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΌΠΈ), Ρ‚ΠΎ ΠΈΠΌΠ΅Π΅Ρ‚ смысл ΠΎΠΏΡ€Π°ΡˆΠΈΠ²Π°Ρ‚ΡŒ ΠΈΡ… Ρ‡Π°Ρ‰Π΅, Ρ‡Π΅ΠΌ Ρ‚Π΅, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΡƒΠΆΠ΅ ΠΏΡ€ΠΎΡˆΠ»ΠΈ Ρ‡Π΅Ρ€Π΅Π· нСсколько этапов сборки мусора.
Π’ ΠΊΠ°ΠΆΠ΄ΠΎΠΌ ΠΏΠΎΠΊΠΎΠ»Π΅Π½Π½ Π΅ΡΡ‚ΡŒ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½Ρ‹ΠΉ счСтчик ΠΈ ΠΏΠΎΡ€ΠΎΠ³ срабатывания, ΠΏΡ€ΠΈ достиТСнии ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ начинаСтся процСсс сборки мусора. Как Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π² Python создаСтся ΠΊΠ°ΠΊΠΎΠΉ-Π»ΠΈΠ±ΠΎ ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π½Ρ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚, ΠΎΠ½ провСряСт эти ΠΏΠΎΡ€ΠΎΠ³ΠΈ. Если условия ΡΡ€Π°Π±Π°Ρ‚Ρ‹Π²Π°ΡŽΡ‚, Ρ‚ΠΎ начинаСтся процСсс сборки мусора.
Π‘Ρ‚Π°Π½Π΄Π°Ρ€Ρ‚Π½Ρ‹Π΅ ΠΏΠΎΡ€ΠΎΠ³ΠΈ срабатывания для ΠΏΠΎΠΊΠΎΠ»Π΅Π½ΠΈΠΉ установлСны Π½Π° 700, 10 ΠΈ 10 соотвСтствСнно, Π½ΠΎ всСгда ΠΌΠΎΠΆΠ½ΠΎ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ ΠΈΡ… с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ gc.get_threshold ΠΈ gc.set_threshold.

Алгоритм поиска цикличСских ссылок: говоря ΠΊΡ€Π°Ρ‚ΠΊΠΎ, GC ΠΏΡ€ΠΎΡ…ΠΎΠ΄ΠΈΡ‚ ΠΏΠΎ всСм ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°ΠΌ ΠΈΠ· Π²Ρ‹Π±Ρ€Π°Π½Π½ΠΎΠ³ΠΎ поколСния ΠΈ Π²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ удаляСт всС ссылки ΠΎΡ‚ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°. ВсС ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹, Ρƒ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… послС этого счСтчик ссылок мСньшС Π΄Π²ΡƒΡ…, ΡΡ‡ΠΈΡ‚Π°ΡŽΡ‚ΡΡ нСдоступными ΠΈ ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ ΡƒΠ΄Π°Π»Π΅Π½Ρ‹.

Π ΡƒΡ‡Π½ΠΎΠΉ ΠΎΡ‚Π»ΠΎΠ² цикличСских ссылок Π²ΠΎΠ·ΠΌΠΎΠΆΠ΅Π½ благодаря Π½Π°Π»ΠΈΡ‡ΠΈΡŽ Ρƒ GC ΠΎΡ‚Π»Π°Π΄ΠΎΡ‡Π½ΠΎΠΌΡƒ Ρ„Π»Π°Π³Ρƒ DEBUG_SAVEALL, с ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ всС нСдоступныС ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ Π±ΡƒΠ΄ΡƒΡ‚ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½Ρ‹ Π² список gc.garbage:

gc.set_debug(gc.DEBUG_SAVEALL)

Бписок gc.garbage, Π² свою ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ, ΠΌΠΎΠΆΠ½ΠΎ Π²ΠΈΠ·ΡƒΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ objgraph:

Π’ Π΄Ρ€ΡƒΠ³ΠΈΡ… ΠΈΠ½Ρ‚Π΅Ρ€ΠΏΡ€Π΅Ρ‚Π°Ρ‚ΠΎΡ€Π°Ρ… Python ΠΈΠΌΠ΅ΡŽΡ‚ΡΡ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΡ‹ сборки мусора, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π² ΠΈΠ½Ρ‚Π΅Ρ€ΠΏΡ€Π΅Ρ‚Π°Ρ‚ΠΎΡ€Π΅ PyPy отсутствуСт Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ постоянного подсчСта ссылок. Из-Π·Π° этого, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, содСрТимоС Ρ„Π°ΠΉΠ»Π° ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΎ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ послС ΠΏΡ€ΠΎΡ…ΠΎΠ΄Π° GC, Π° Π½Π΅ Ρ‚ΠΎΠ³Π΄Π°, ΠΊΠΎΠ³Π΄Π° Ρ„Π°ΠΉΠ» Π±Ρ‹Π» Π·Π°ΠΊΡ€Ρ‹Ρ‚ Π² ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅.

Если Π² процСссС Ρ€Π°Π±ΠΎΡ‚Ρ‹ Π²Ρ‹ строитС Π±ΠΎΠ»ΡŒΡˆΡƒΡŽ структуру Π΄Π°Π½Π½Ρ‹Ρ…, которая Π²Π°ΠΌ Ρ‚ΠΎΡ‡Π½ΠΎ Π½Π΅ Π½ΡƒΠΆΠ½Π° сразу послС использования, Ρ‚ΠΎ ΠΈΠΌΠ΅Π΅Ρ‚ смысл Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ сборщик мусора Π² Ρ€ΡƒΡ‡Π½ΠΎΠΌ Ρ€Π΅ΠΆΠΈΠΌΠ΅ для ΡƒΠΌΠ΅Π½ΡŒΡˆΠ΅Π½ΠΈΡ Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ памяти:

import gc

del my_big_object
gc.collect()

На Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎΡΡ‚ΡŒ Ρ€ΡƒΡ‡Π½ΠΎΠ³ΠΎ Π²Ρ‹Π·ΠΎΠ²Π° сборщика мусора Π΅ΡΡ‚ΡŒ Ρ€Π°Π·Π½Ρ‹Π΅ Ρ‚ΠΎΡ‡ΠΊΠΈ зрСния, Π½ΠΎ Π² Ρ†Π΅Π»ΠΎΠΌ такая ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Π° признаётся ΠΏΠΎΠ»Π΅Π·Π½ΠΎΠΉ (обсуТдСниС, смотритС ΠΎΠΆΠΈΠ²Π»Ρ‘Π½Π½Ρ‹Π΅ ΠΊΠΎΠΌΠΌΠ΅Ρ‚Π°Ρ€ΠΈΠΈ ΠΊ ΠΏΠ΅Ρ€Π²ΠΎΠΌΡƒ ΠΎΡ‚Π²Π΅Ρ‚Ρƒ).

Arguments

Inside Function Call

(<positional_args>) # f(0, 0) (<keyword_args>) # f(x=0, y=0) (<positional_args>, <keyword_args>) # f(0, y=0)

Inside Function Definition

def f(<nondefault_args>): # def f(x, y): def f(<default_args>): # def f(x=0, y=0): def f(<nondefault_args>, <default_args>): # def f(x, y=0):

A function has its default values evaluated when it's first encountered in the scope. Any changes to default values that are mutable will persist between invocations.

Splat Operator

Inside Function Call

Splat expands a collection into positional arguments, while splatty-splat expands a dictionary into keyword arguments.

args = (1, 2) kwargs = {'x': 3, 'y': 4, 'z': 5} func(*args, **kwargs)

Is the same as:

func(1, 2, x=3, y=4, z=5)

Inside Function Definition

Splat combines zero or more positional arguments into a tuple, while splatty-splat combines zero or more keyword arguments into a dictionary.

def add(*a): return sum(a)

add(1, 2, 3) 6

Legal argument combinations:

def f(*, x, y, z): # f(x=1, y=2, z=3) def f(x, *, y, z): # f(x=1, y=2, z=3) | f(1, y=2, z=3) def f(x, y, *, z): # f(x=1, y=2, z=3) | f(1, y=2, z=3) | f(1, 2, z=3)

def f(*args): # f(1, 2, 3) def f(x, *args): # f(1, 2, 3) def f(*args, z): # f(1, 2, z=3)

def f(**kwargs): # f(x=1, y=2, z=3) def f(x, **kwargs): # f(x=1, y=2, z=3) | f(1, y=2, z=3) def f(*, x, **kwargs): # f(x=1, y=2, z=3)

def f(*args, **kwargs): # f(x=1, y=2, z=3) | f(1, y=2, z=3) | f(1, 2, z=3) | f(1, 2, 3) def f(x, *args, **kwargs): # f(x=1, y=2, z=3) | f(1, y=2, z=3) | f(1, 2, z=3) | f(1, 2, 3) def f(*args, y, **kwargs): # f(x=1, y=2, z=3) | f(1, y=2, z=3)

Other Uses

= [ [, ...]] = { [, ...]} = (*, [...]) = {** [, ...]}

head, *body, tail =

Как ΠΏΠ΅Ρ€Π΅Π΄Π°ΡŽΡ‚ΡΡ значСния Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² Π² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ ΠΈΠ»ΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄? Как ΠΏΠ΅Ρ€Π΅Π΄Π°ΡŽΡ‚ΡΡ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Ρ‹ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ Π² Python (by value or reference)?

lambda-Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ

Π­Ρ‚ΠΎ Π°Π½ΠΎΠ½ΠΈΠΌΠ½Ρ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ. Они Π½Π΅ Ρ€Π΅Π·Π΅Ρ€Π²ΠΈΡ€ΡƒΡŽΡ‚ ΠΈΠΌΠ΅Π½ΠΈ Π² пространствС ΠΈΠΌΠ΅Π½. Лямбды часто ΠΏΠ΅Ρ€Π΅Π΄Π°ΡŽΡ‚ Π² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ map, reduce, filter.

Лямбды Π² ΠŸΠΈΡ‚ΠΎΠ½Π΅ ΠΌΠΎΠ³ΡƒΡ‚ ΡΠΎΡΡ‚ΠΎΡΡ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΈΠ· ΠΎΠ΄Π½ΠΎΠ³ΠΎ выраТСния. Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ синтаксис скобок, ΠΌΠΎΠΆΠ½ΠΎ ΠΎΡ„ΠΎΡ€ΠΌΠΈΡ‚ΡŒ Ρ‚Π΅Π»ΠΎ лямбды Π² нСсколько строк.

Допустимы Π»ΠΈ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ выраТСния?

nope = lambda: pass riser = lambda x: raise Exception(x) НСт, ΠΏΡ€ΠΈ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠ΅ модуля выскочит ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ SyntaxError. Π’ Ρ‚Π΅Π»Π΅ лямбды ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅. pass ΠΈ raise ΡΠ²Π»ΡΡŽΡ‚ΡΡ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π°ΠΌΠΈ.

Lambda

= lambda: <return_value> = lambda <arg_1>, <arg_2>: <return_value>

Conditional Expression

<obj> = <exp_if_true> if <condition> else <exp_if_false>
 
>>> [a if a else 'zero' for a in (0, 1, 2, 3)]
['zero', 1, 2, 3]

Closure

We have/get a closure in Python when: A nested function references a value of its enclosing function and then the enclosing function returns the nested function.

def get_multiplier(a):
    def out(b):
        return a * b
    return out
>>> multiply_by_3 = get_multiplier(3)
>>> multiply_by_3(10)
30

If multiple nested functions within enclosing function reference the same value, that value gets shared. To dynamically access function's first free variable use '<function>.__closure__[0].cell_contents'.

Π˜ΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ (Exceptions)

ΠŸΠ΅Ρ€Π΅Ρ…Π²Π°Ρ‚ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΉ

ΠŸΡ€ΠΎΡΡ‚ΠΎΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€:

a: float = 0
b: float = 0

try:
    b: float = 1/a
except ZeroDivisionError as e:
    print(f"Error: {e}")
Error: division by zero

Π‘ΠΎΠ»Π΅Π΅ слоТный ΠΏΡ€ΠΈΠΌΠ΅Ρ€.
Код Π² Π±Π»ΠΎΠΊΠ΅ else исполняСтся Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π² случаС отсутствия ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ.
Код Π² Π±Π»ΠΎΠΊΠ΅ finally исполнится Π² любом случаС, Π±Ρ‹Π»ΠΎ Π»ΠΈ Π²Ρ‹Π·Π²Π°Π½ΠΎ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΠΈΠ»ΠΈ Π½Π΅Ρ‚.

import traceback

a: float = 0
b: float = 0

try:
    b: float = 1/a
except ZeroDivisionError as e:
    print(f"Error: {e}")
except ArithmeticError as e:
    print(f"We have a bit more complicated problem: {e}")
except Exception as serious_problem:  # Catch all exceptions
    print(f"I don't really know what is going on: {traceback.print_exception(serious_problem)}")
else:
    print("No errors!")
finally:
    print("This part is always called")
Error: division by zero
This part is always called

ВстроСнныС ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ

Π‘ΠΎΠΊΡ€Π°Ρ‰Π΅Π½Π½ΠΎΠ΅ иСрархичСскоС Π΄Π΅Ρ€Π΅Π²ΠΎ встроСнных ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΉ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ Π½ΠΈΠΆΠ΅:

BaseException
 +-- SystemExit                   # Raised by the sys.exit() function
 +-- KeyboardInterrupt            # Raised when the user press the interrupt key (ctrl-c)
 +-- Exception                    # User-defined exceptions should be derived from this class
      +-- ArithmeticError         # Base class for arithmetic errors
      |    +-- ZeroDivisionError  # Dividing by zero
      +-- AttributeError          # Attribute is missing
      +-- EOFError                # Raised by input() when it hits end-of-file condition
      +-- LookupError             # Raised when a look-up on a collection fails
      |    +-- IndexError         # A sequence index is out of range
      |    +-- KeyError           # A dictionary key or set element is missing
      +-- NameError               # An object is missing
      +-- OSError                 # Errors such as β€œfile not found”
      |    +-- FileNotFoundError  # File or directory is requested but doesn't exist
      +-- RuntimeError            # Error that don't fall into other categories
      |    +-- RecursionError     # Maximum recursion depth is exceeded
      +-- StopIteration           # Raised by next() when run on an empty iterator
      +-- TypeError               # An argument is of wrong type
      +-- ValueError              # When an argument is of right type but inappropriate value
           +-- UnicodeError       # Encoding/decoding strings to/from bytes fails

ПолноС Π΄Π΅Ρ€Π΅Π²ΠΎ доступно здСсь.

Π’Ρ‹Π·ΠΎΠ² ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΉ

from decimal import *

def div(a: Decimal, b: Decimal) -> Decimal:
    if b == 0:
        raise ValueError("Second argument must be non-zero")
    return a/b

try:
    c: Decimal = div(1, 0)
except ValueError as ve:
    print(f"{ve}. We have ValueError, as a planned!")
    # raise # We can re-raise exception
Second argument must be non-zero. We have ValueError, as a planned!

Π’Ρ‹Ρ…ΠΎΠ΄ ΠΈΠ· ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ Π²Ρ‹Π·ΠΎΠ²Π° ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ SystemExit

import sys

# sys.exit()  # Exits with exit code 0 (success)
# sys.exit(8)  # Exits with passed exit code

Π˜ΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ, опрСдСляСмыС ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΌ

class MyException(Exception):
    pass

raise MyException("My car is broken")
---------------------------------------------------------------------------

MyException                               Traceback (most recent call last)

c:\Works\amaargiru\pycore\05_language_skeleton.ipynb Cell 18 in <cell line: 4>()
      <a href='vscode-notebook-cell:/c%3A/Works/amaargiru/pycore/05_language_skeleton.ipynb#X23sZmlsZQ%3D%3D?line=0'>1</a> class MyException(Exception):
      <a href='vscode-notebook-cell:/c%3A/Works/amaargiru/pycore/05_language_skeleton.ipynb#X23sZmlsZQ%3D%3D?line=1'>2</a>     pass
----> <a href='vscode-notebook-cell:/c%3A/Works/amaargiru/pycore/05_language_skeleton.ipynb#X23sZmlsZQ%3D%3D?line=3'>4</a> raise MyException("My car is broken")


MyException: My car is broken

Π”ΠΎΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΉ

Начиная с Python 3.11 ΠΎΡ‚Π»Π°Π²Π»ΠΈΠ²Π°Π΅ΠΌΡ‹Π΅ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ ΠΌΠΎΠΆΠ½ΠΎ ΠΎΠ±ΠΎΠ³Π°Ρ‰Π°Ρ‚ΡŒ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠΉ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠ΅ΠΉ:

try:
    raise TypeError('Bad type')
except Exception as e:
    e.add_note('We are powerless, we rely on a higher authority')
    raise

Π˜ΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ β€” Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ спорная Ρ‚Π΅ΠΌΠ°, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ систСматизация ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ ошибок сильно пСрСсСкаСтся с Ρ‚Π΅ΠΌΠΎΠΉ ΠΎΠ±Ρ‰Π΅ΠΉ Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Ρ‹ прилоТСния. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ ΠΊΡ‚ΠΎ-Ρ‚ΠΎ ΠΏΡ€Π΅Π΄Π»Π°Π³Π°Π΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΠ±Ρ‘Ρ€Ρ‚ΠΊΠΈ Success/Failure, ΠΊΡ‚ΠΎ-Ρ‚ΠΎ создаёт свои классы ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΉ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΈΠΌΠ΅ΡŽΡ‚ Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½Π½Ρ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ логгирования ΠΈ сильно ΠΎΠ±Π»Π΅Π³Ρ‡Π°Π΅Ρ‚ ΠΎΡ‚Π»Π°Π΄ΠΊΡƒ.

Π›ΠΈΡ‡Π½ΠΎ я ΠΏΡ€Π΅Π΄ΠΏΠΎΡ‡ΠΈΡ‚Π°ΡŽ ΠΏΡƒΡ‚ΡŒ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ, Π½Π° ΠΌΠΎΠΉ взгляд, ΠΌΠΎΠΆΠ½ΠΎ Π½Π°Π·Π²Π°Ρ‚ΡŒ «классичСским»:
ΠΌΠ½ΠΎΠ³ΠΎ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΉ Π½Π° этапС ΠΎΡ‚Π»Π°Π΄ΠΊΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΏΠΎΠΌΠΎΠ³Π°ΡŽΡ‚ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π±ΠΎΠ»Π΅Π΅ ΡΡ‚Π°Π±ΠΈΠ»ΡŒΠ½Ρ‹ΠΌΠΈ;
ΠΊΠ°ΠΆΠ΄ΠΎΠ΅ ΠΎΠΆΠΈΠ΄Π°Π΅ΠΌΠΎΠ΅ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π±Ρ‹Ρ‚ΡŒ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π°Π½ΠΎ ΠΊΠ°ΠΊ ΠΌΠΎΠΆΠ½ΠΎ Ρ€Π°Π½ΡŒΡˆΠ΅;
Π½Π° самый Π²Π΅Ρ€Ρ… Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΏΡ€ΠΎΠ½ΠΈΠΊΠ½ΡƒΡ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π½Π΅ΠΎΠΆΠΈΠ΄Π°Π½Π½Ρ‹Π΅ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ (ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅, Π² Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅, ΠΏΠΎΠΏΠ°Π΄ΡƒΡ‚ ΠΈΠ»ΠΈ Π² ΠΎΡ‚Ρ‡Π΅Ρ‚ тСстировщика ΠΈΠ»ΠΈ Π² Π±Π°Π³-Ρ€Π΅ΠΏΠΎΡ€Ρ‚ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ ΠΈ Ρ‚ΠΎΠΆΠ΅ Π±ΡƒΠ΄ΡƒΡ‚ ΠΊΡƒΠΏΠΈΡ€ΠΎΠ²Π°Π½Ρ‹).

ΠžΠ΄ΠΈΠ½Π°Ρ€Π½ΠΎΠ΅ (_) ΠΈ Π΄Π²ΠΎΠΉΠ½ΠΎΠ΅ (__) подчСркивания. Name mangling.

Python Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ спСцификаторы доступа, Ρ‚Π°ΠΊΠΈΠ΅ ΠΊΠ°ΠΊ private, public, protected ΠΈ Ρ‚. Π΄. Однако, Π² Π½Π΅ΠΌ Π΅ΡΡ‚ΡŒ ΠΈΠΌΠΈΡ‚Π°Ρ†ΠΈΠΈ повСдСния ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… ΠΏΡƒΡ‚Π΅ΠΌ использования ΠΎΠ΄ΠΈΠ½Π°Ρ€Π½ΠΎΠ³ΠΎ ΠΈΠ»ΠΈ Π΄Π²ΠΎΠΉΠ½ΠΎΠ³ΠΎ подчСркивания Π² качСствС прСфикса ΠΊ ΠΈΠΌΠ΅Π½Π°ΠΌ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ…. По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ Π±Π΅Π· подчСркивания ΡΠ²Π»ΡΡŽΡ‚ΡΡ общСдоступными.

ПолС класса с ΠΎΠ΄Π½ΠΈΠΌ Π»ΠΈΠ΄ΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΌ ΠΏΠΎΠ΄Ρ‡Π΅Ρ€ΠΊΠΈΠ²Π°Π½ΠΈΠ΅ΠΌ Π³ΠΎΠ²ΠΎΡ€ΠΈΡ‚ ΠΎ Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π²Π½ΡƒΡ‚Ρ€ΠΈ класса. ΠŸΡ€ΠΈ этом ΠΎΠ½ доступСн для обращСния ΠΈΠ·Π²Π½Π΅.

class Foo(object):
    def __init__(self):
        self._bar = 42

Foo()._bar
42

Π‘ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ IDE Π²Ρ€ΠΎΠ΄Π΅ PyCharm ΠΏΠΎΠ΄ΡΠ²Π΅Ρ‡ΠΈΠ²Π°ΡŽΡ‚ ΠΎΠ±Ρ€Π°Ρ‰Π΅Π½ΠΈΠ΅ ΠΊ полю с ΠΏΠΎΠ΄Ρ‡Π΅Ρ€ΠΊΠΈΠ²Π°Π½ΠΈΠ΅ΠΌ, Π½ΠΎ ошибки Π² процСссС исполнСния Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚.

Поля с Π΄Π²ΠΎΠΉΠ½Ρ‹ΠΌ ΠΏΠΎΠ΄Ρ‡Π΅Ρ€ΠΊΠΈΠ²Π°Π½ΠΈΠ΅ΠΌ доступны Π²Π½ΡƒΡ‚Ρ€ΠΈ класса, Π½ΠΎ ΠΈΠ·Π²Π½Π΅ доступны Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΡ€ΠΈ ΠΎΠ±Ρ€Π°Ρ‰Π΅Π½ΠΈΠΈ ΠΊ полю Π²ΠΈΠ΄Π° ___ (name mangling). Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ скрытого поля Π²Π½Π΅ класса ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΌΠΎΠΆΠ½ΠΎ, Π½ΠΎ это смотрится ΡƒΡ€ΠΎΠ΄Π»ΠΈΠ²ΠΎ.

class Foo(object):
    def __init__(self):
        self.__bar = 42

Foo().__bar
  AttributeError: 'Foo' object has no attribute '__bar'

Foo()._Foo__bar
42

Π’ Ρ†Π΅Π»ΠΎΠΌ, Π΄ΠΆΠ΅Π½Ρ‚Π΅Π»ΡŒΠΌΠ΅Π½ΡΠΊΠΎΠ΅ соглашСниС ΠΏΠ°ΠΉΡ‚ΠΎΠ½-программистов ΠΏΠΎΠ΄Ρ€Π°Π·ΡƒΠΌΠ΅Π²Π°Π΅Ρ‚ (простоС ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½ΠΈΠ΅ для ΠΏΡ€ΠΈΠ²Π°Ρ‚Π½Ρ‹Ρ… ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… ΠΈΠ»ΠΈ использованиС ΠΎΠ΄ΠΈΠ½Π°Ρ€Π½ΠΎΠ³ΠΎ подчСркивания для ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ…, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΎΡ‡Π΅Π½ΡŒ Π½Π΅ΠΆΠ΅Π»Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ Π²Ρ‹Ρ‚Π°ΡΠΊΠΈΠ²Π°Ρ‚ΡŒ Π·Π° ΠΏΡ€Π΅Π΄Π΅Π»Ρ‹ класса) + использованиС ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² для доступа ΠΊ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΌ

class Stack(object):

    def __init__(self):
        self._storage = []

    def push(self, value):
        self._storage.append(value)

Π˜Π½Ρ‚Ρ€ΠΎΡΠΏΠ΅ΠΊΡ†ΠΈΡ

Анализ ΠΌΠ΅Ρ‚Π°Π΄Π°Π½Π½Ρ‹Ρ… классов Π²ΠΎ врСмя выполнСния.

ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅

ΠŸΡ€ΠΈ Π²Ρ‹Π·ΠΎΠ²Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ dir() Π±Π΅Π· Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² ΠΎΠ½Π° Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ список Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ΠΎΠ² (Π²ΠΊΠ»ΡŽΡ‡Π°Ρ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ), доступных Π² локальной области видимости.

local_variables: list = dir()

locals() Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΡΠ»ΠΎΠ²Π°Ρ€ΡŒ Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ локальной Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ символов (Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ __dict__). locals() эквивалСнтна vars() Π±Π΅Π· Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π°.

local_vars: dict = locals()

globals() Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΡΠ»ΠΎΠ²Π°Ρ€ΡŒ глобальной Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ символов

global_variables: dict = globals()

print(local_variables)
print(local_vars)
print(global_variables)
['In', 'Out', '_', '__', '___', '__annotations__', '__builtin__', '__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', '__vsc_ipynb_file__', '_dh', '_i', '_i1', '_ih', '_ii', '_iii', '_oh', 'exit', 'get_ipython', 'quit']
{'__name__': '__main__', '__doc__': 'Automatically created module for IPython interactive environment', '__package__': None, '__loader__': None, '__spec__': None, '__builtin__': <module 'builtins' (built-in)>, '__builtins__': <module 'builtins' (built-in)>, '_ih': ['', 'local_variables: list = dir()', 'local_vars: dict = locals()', 'global_variables: dict = globals()\n\nprint(local_variables)\nprint(local_vars)\nprint(global_variables)'], '_oh': {}, '_dh': [WindowsPath('c:/Works/amaargiru/pycore')], 'In': ['', 'local_variables: list = dir()', 'local_vars: dict = locals()', 'global_variables: dict = globals()\n\nprint(local_variables)\nprint(local_vars)\nprint(global_variables)'], 'Out': {}, 'get_ipython': <bound method InteractiveShell.get_ipython of <ipykernel.zmqshell.ZMQInteractiveShell object at 0x000002B22DC22260>>, 'exit': <IPython.core.autocall.ZMQExitAutocall object at 0x000002B22DC22D10>, 'quit': <IPython.core.autocall.ZMQExitAutocall object at 0x000002B22DC22D10>, '_': '', '__': '', '___': '', '__vsc_ipynb_file__': 'c:\\Works\\amaargiru\\pycore\\05_language_skeleton.ipynb', '_i': 'local_vars: dict = locals()', '_ii': 'local_variables: list = dir()', '_iii': '', '_i1': 'local_variables: list = dir()', '__annotations__': {'local_variables': <class 'list'>, 'local_vars': <class 'dict'>, 'global_variables': <class 'dict'>}, 'local_variables': ['In', 'Out', '_', '__', '___', '__annotations__', '__builtin__', '__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', '__vsc_ipynb_file__', '_dh', '_i', '_i1', '_ih', '_ii', '_iii', '_oh', 'exit', 'get_ipython', 'quit'], '_i2': 'local_vars: dict = locals()', 'local_vars': {...}, '_i3': 'global_variables: dict = globals()\n\nprint(local_variables)\nprint(local_vars)\nprint(global_variables)', 'global_variables': {...}}
{'__name__': '__main__', '__doc__': 'Automatically created module for IPython interactive environment', '__package__': None, '__loader__': None, '__spec__': None, '__builtin__': <module 'builtins' (built-in)>, '__builtins__': <module 'builtins' (built-in)>, '_ih': ['', 'local_variables: list = dir()', 'local_vars: dict = locals()', 'global_variables: dict = globals()\n\nprint(local_variables)\nprint(local_vars)\nprint(global_variables)'], '_oh': {}, '_dh': [WindowsPath('c:/Works/amaargiru/pycore')], 'In': ['', 'local_variables: list = dir()', 'local_vars: dict = locals()', 'global_variables: dict = globals()\n\nprint(local_variables)\nprint(local_vars)\nprint(global_variables)'], 'Out': {}, 'get_ipython': <bound method InteractiveShell.get_ipython of <ipykernel.zmqshell.ZMQInteractiveShell object at 0x000002B22DC22260>>, 'exit': <IPython.core.autocall.ZMQExitAutocall object at 0x000002B22DC22D10>, 'quit': <IPython.core.autocall.ZMQExitAutocall object at 0x000002B22DC22D10>, '_': '', '__': '', '___': '', '__vsc_ipynb_file__': 'c:\\Works\\amaargiru\\pycore\\05_language_skeleton.ipynb', '_i': 'local_vars: dict = locals()', '_ii': 'local_variables: list = dir()', '_iii': '', '_i1': 'local_variables: list = dir()', '__annotations__': {'local_variables': <class 'list'>, 'local_vars': <class 'dict'>, 'global_variables': <class 'dict'>}, 'local_variables': ['In', 'Out', '_', '__', '___', '__annotations__', '__builtin__', '__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', '__vsc_ipynb_file__', '_dh', '_i', '_i1', '_ih', '_ii', '_iii', '_oh', 'exit', 'get_ipython', 'quit'], '_i2': 'local_vars: dict = locals()', 'local_vars': {...}, '_i3': 'global_variables: dict = globals()\n\nprint(local_variables)\nprint(local_vars)\nprint(global_variables)', 'global_variables': {...}}

Π”Π°Π±Ρ‹ Π½Π΅ углублятся Π² Π΄Π΅Π±Ρ€ΠΈ интроспСкции особо Π³Π»ΡƒΠ±ΠΎΠΊΠΎ (ΡΡƒΡ‚ΡŒ, Π΄ΡƒΠΌΠ°ΡŽ, Π²Ρ‹ ΡƒΠΆΠ΅ ΡƒΠ»ΠΎΠ²ΠΈΠ»ΠΈ), Π΄Π°Π²Π°ΠΉΡ‚Π΅ просто пСрСчислим возмоТности, прСдоставляСмыС Сю ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ΠΎΠ² ΠΈ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ².

Атрибуты

l: list = dir(object)                      # ИмСна Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ΠΎΠ² ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° (Π²ΠΊΠ»ΡŽΡ‡Π°Ρ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹)  
d: dict = vars(object)                    # Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ object.__dict__.  
value  = getattr(object, 'attr_name')  # Raises AttributeError if attribute is missing.  
b: bool = hasattr(object, 'attr_name')  # Checks if getattr() raises an AttributeError.  
setattr(object, 'attr_name', value)    # Only works on objects with '__dict__' attribute.  
delattr(object, 'attr_name')           # Same. Also `del <object>.<attr_name>`.  

Parameters

= inspect.signature() # Function's Signature object.
= .parameters # Dict of Parameter objects.
= .kind # Member of ParameterKind enum.
= .default # Default value or .empty.
= .annotation # Type or .empty.

GIL

Global Interpreter Lock - ΡΠΎΠ±Π΅Π½Π½ΠΎΡΡ‚ΡŒ ΠΈΠ½Ρ‚Π΅Ρ€ΠΏΡ€Π΅Ρ‚Π°Ρ‚ΠΎΡ€Π°, ΠΊΠΎΠ³Π΄Π° ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΡΠΏΠΎΠ»Π½ΡΡ‚ΡŒΡΡ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄ΠΈΠ½ Ρ‚Ρ€Π΅Π΄, ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Π΅ Ρ‚Ρ€Π΅Π΄Ρ‹ Π² это врСмя ΠΏΡ€ΠΎΡΡ‚Π°ΠΈΠ²Π°ΡŽΡ‚.

GIL позволяСт бСзопасно ΡΠΎΠ³Π»Π°ΡΠΎΠ²Ρ‹Π²Π°Ρ‚ΡŒ измСнСния Π΄Π°Π½Π½Ρ‹Ρ…. Π‘Π΅Π· этого, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Ссли ΠΎΠ΄ΠΈΠ½ Ρ‚Ρ€Π΅Π΄ ΡƒΠ΄Π°Π»ΠΈΡ‚ всС элСмСны ΠΈΠ· списка, Π° Π²Ρ‚ΠΎΡ€ΠΎΠΉ Π½Π°Ρ‡Π½Π΅Ρ‚ ΠΈΡ‚Π΅Ρ€Π°Ρ†ΠΈΡŽ ΠΏΠΎ Π½Π΅ΠΌΡƒ, ΠΏΡ€ΠΎΠΈΠ·ΠΎΠΉΠ΄Π΅Ρ‚ ошибка. Аналогично, сборщик мусора ΠΌΠΎΠΆΠ΅Ρ‚ Π½Π°Ρ‡Π°Ρ‚ΡŒ Π½Π΅ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎ ΠΏΠΎΠ΄ΡΡ‡ΠΈΡ‚Ρ‹Π²Π°Ρ‚ΡŒ ссылки. ΠŸΡ€ΠΎΠ±Π»Π΅ΠΌΡƒ ΠΌΠΎΠΆΠ½ΠΎ Ρ€Π΅ΡˆΠΈΡ‚ΡŒ, установив Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ Π½Π° всС раздСляСмыС структуры Π΄Π°Π½Π½Ρ‹Ρ…, Π½ΠΎ это привнСсло Π±Ρ‹ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ слоТности: ΠΎΠ²Π΅Ρ€Ρ…Π΅Π΄ ΠΏΠΎ ΠΊΠΎΠ΄Ρƒ, ΠΏΠΎΡ‚Π΅Ρ€ΡŽ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ, Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Π΅ deadlocks. GIL позволяСт ΠΎΡΡƒΡ‰Π΅ΡΡ‚Π²Π»ΡΡ‚ΡŒ ΠΏΡ€ΠΎΡΡ‚ΡƒΡŽ ΠΈΠ½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΡŽ C-Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π·Π°Ρ‡Π°ΡΡ‚ΡƒΡŽ Ρ‚ΠΎΠΆΠ΅ Π½Π΅ потокобСзопасны, Π° Ρ‚Π°ΠΊΠΆΠ΅ обСспСчиваСт Π±Ρ‹ΡΡ‚Ρ€ΡƒΡŽ Ρ€Π°Π±ΠΎΡ‚Ρƒ ΠΎΠ΄Π½ΠΎΠΏΠΎΡ‚ΠΎΡ‡Π½Ρ‹Ρ… скриптов.

GIL Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Ρ‚Π°ΠΊ: Π½Π° ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ Ρ‚Ρ€Π΅Π΄ выдСляСтся Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΊΠ²Π°Π½Ρ‚ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ. Он измСряСтся Π² ΠΌΠ°ΡˆΠΈΠ½Π½Ρ‹Ρ… Π΅Π΄ΠΈΠ½ΠΈΡ†Π°Ρ… β€œΡ‚ΠΈΠΊΠ°Ρ…β€ ΠΈ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ Ρ€Π°Π²Π΅Π½ 100. Как Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π½Π° Ρ‚Ρ€Π΅Π΄ Π±Ρ‹Π»ΠΎ ΠΏΠΎΡ‚Ρ€Π°Ρ‡Π΅Π½ΠΎ 100 Ρ‚ΠΈΠΊΠΎΠ², ΠΈΠ½Ρ‚Π΅Ρ€ΠΏΡ€Π΅Ρ‚Π°Ρ‚ΠΎΡ€ бросаСт этот Ρ‚Ρ€Π΅Π΄ ΠΈ ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π½Π° Π²Ρ‚ΠΎΡ€ΠΎΠΉ, Ρ‚Ρ€Π°Ρ‚ΠΈΡ‚ 100 Ρ‚Π°ΠΊΡ‚ΠΎΠ² Π½Π° Π½Π΅Π³ΠΎ, Π·Π°Ρ‚Π΅ΠΌ Ρ‚Ρ€Π΅Ρ‚ΠΈΠΉ, ΠΈ Ρ‚Π°ΠΊ ΠΏΠΎ ΠΊΡ€ΡƒΠ³Ρƒ. Π­Ρ‚ΠΎΡ‚ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ Π³Π°Ρ€Π°Π½ΠΈΡ‚Ρ€ΡƒΠ΅Ρ‚, Ρ‡Ρ‚ΠΎ всСм Ρ‚Ρ€Π΅Π΄Π°ΠΌ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹Π΄Π΅Π»Π΅Π½ΠΎ рСсурсов ΠΏΠΎΡ€ΠΎΠ²Π½Ρƒ.

ΠŸΡ€ΠΎΠ±Π»Π΅ΠΌΠ° Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ΠΈΠ·-Π·Π° GIL Π΄Π°Π»Π΅ΠΊΠΎ Π½Π΅ всС Π·Π°Π΄Π°Ρ‡ΠΈ ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ Ρ€Π΅ΡˆΠ΅Π½Ρ‹ Π² Ρ‚Ρ€Π΅Π΄Π°Ρ…. Напротив, ΠΈΡ… использованиС Ρ‡Π°Ρ‰Π΅ всСго сниТаСт быстродСйствиС ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹. Π‘ использованиСм Ρ‚Ρ€Π΅Π΄ΠΎΠ² трСбуСтся ΡΠ»Π΅Π΄ΠΈΡ‚ΡŒ Π·Π° доступом ΠΊ ΠΎΠ±Ρ‰ΠΈΠΌ рСсурсам: словарям, Ρ„Π°ΠΉΠ»Π°ΠΌ, соСдинСниСм ΠΊ Π‘Π”.

Как ΠΎΠ±ΠΎΠΉΡ‚ΠΈ ограничСния, Π½Π°ΠΊΠ»Π°Π΄Ρ‹Π²Π°Π΅ΠΌΡ‹Π΅ GIL?
Π’Π°Ρ€ΠΈΠ°Π½Ρ‚ 1 - ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π°Π»ΡŒΡ‚Π΅Ρ€Π½Π°Ρ‚ΠΈΠ²Π½Ρ‹Π΅ ΠΈΠ½Ρ‚Π΅Ρ€ΠΏΡ€Π΅Ρ‚Π°Ρ‚ΠΎΡ€Ρ‹ Python, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ PyPy.
Π’Π°Ρ€ΠΈΠ°Π½Ρ‚ 2 - ΡƒΡ…ΠΎΠ΄ ΠΎΡ‚ многопоточности Π² сторону ΠΌΡƒΠ»ΡŒΡ‚ΠΈΠΏΡ€ΠΎΡ†Π΅ΡΡΠ½ΠΎΡΡ‚ΠΈ, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ ΠΌΠΎΠ΄ΡƒΠ»ΡŒ multiprocessing. ПослСдний Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎ Ρ€Π°Π·ΠΎΠ±Ρ€Π°Π½ Π½ΠΈΠΆΠ΅.

*args, **kwargs, *

ВыраТСния *args ΠΈ **kwargs ΠΎΠ±ΡŠΡΠ²Π»ΡΡŽΡ‚ Π² сигнатурС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ. Они ΠΎΠ·Π½Π°Ρ‡Π°ΡŽΡ‚, Ρ‡Ρ‚ΠΎ Π²Π½ΡƒΡ‚Ρ€ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π±ΡƒΠ΄ΡƒΡ‚ доступны ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ с ΠΈΠΌΠ΅Π½Π°ΠΌΠΈ args ΠΈ kwargs (Π±Π΅Π· Π·Π²Π΅Π·Π΄ΠΎΡ‡Π΅ΠΊ).

args – это ΠΊΠΎΡ€Ρ‚Π΅ΠΆ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π½Π°ΠΊΠ°ΠΏΠ»ΠΈΠ²Π°Π΅Ρ‚ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΎΠ½Π½Ρ‹Π΅ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Ρ‹. kwargs – ΡΠ»ΠΎΠ²Π°Ρ€ΡŒ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΎΠ½Π½Ρ‹Ρ… Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ², Π³Π΄Π΅ ΠΊΠ»ΡŽΡ‡ – имя ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°, Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ – Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°. ВмСсто args ΠΈ kwargs ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ ΠΈΠΌΠ΅Π½Π° (функция всё Ρ€Π°Π²Π½ΠΎ Β«ΠΏΠΎΠΉΠΌΡ‘Ρ‚Β», Ρ‡Ρ‚ΠΎ ΠΎΡ‚ Π½Π΅Ρ‘ хотят, благодаря Π·Π²Π΅Π·Π΄ΠΎΡ‡ΠΊΠ΅ ΠΈ Π΄Π²ΠΎΠΉΠ½ΠΎΠΉ Π·Π²Π΅Π·Π΄ΠΎΡ‡ΠΊΠ΅), Π½ΠΎ эта ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠ° ΠΌΠ°Π»ΠΎ распространСна.

Π’Π°ΠΆΠ½ΠΎ: Ссли Π² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ Π½Π΅ ΠΏΠ΅Ρ€Π΅Π΄Π°Π½ΠΎ Π½ΠΈΠΊΠ°ΠΊΠΈΡ… ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ², ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ Π±ΡƒΠ΄ΡƒΡ‚ соотвСтствСнно Ρ€Π°Π²Π½Ρ‹ пустому ΠΊΠΎΡ€Ρ‚Π΅ΠΆΡƒ ΠΈ пустому ΡΠ»ΠΎΠ²Π°Ρ€ΡŽ, Π° Π½Π΅ None.

Operator

Module of functions that provide the functionality of operators.

import operator as op  
<el>      = op.add/sub/mul/truediv/floordiv/mod(<el>, <el>)  # +, -, *, /, //, %  
<int/set> = op.and_/or_/xor(<int/set>, <int/set>)            # &, |, ^  
<bool>    = op.eq/ne/lt/le/gt/ge(<sortable>, <sortable>)     # ==, !=, <, <=, >, >=  
<func>    = op.itemgetter/attrgetter/methodcaller(<obj>)     # [index/key], .name, .name()  

elementwise_sum  = map(op.add, list_a, list_b)  
sorted_by_second = sorted(<collection>, key=op.itemgetter(1))  
sorted_by_both   = sorted(<collection>, key=op.itemgetter(1, 0))  
product_of_elems = functools.reduce(op.mul, <collection>)  
union_of_sets    = functools.reduce(op.or_, <coll_of_sets>)  
first_element    = op.methodcaller('pop', 0)(<list>)  
 
Binary operators require objects to have and(), or(), xor() and invert() special methods, unlike logical operators that work on all types of objects.  
Also: `'<bool> = <bool> &|^ <bool>'` and `'<int> = <bool> &|^ <int>'`.

6. ΠœΠ½ΠΎΠ³ΠΎΠΏΠΎΡ‚ΠΎΡ‡Π½ΠΎΡΡ‚ΡŒ ΠΈ ΠΌΠ½ΠΎΠ³ΠΎΠ·Π°Π΄Π°Ρ‡Π½ΠΎΡΡ‚ΡŒ

«И Π΄ΠΎΠ»Π³ΠΎ ΠΎΡΡ‚Π°Π²Π°Π»ΠΈΡΡŒ Π½Π° мСстС Ρ‚Π°ΠΌ, Π° солнца Π½Π΅ Π²ΠΈΠ΄Π΅Π»ΠΈ, Π½ΠΎ свСт Π±Ρ‹Π» ΠΌΠ½ΠΎΠ³ΠΎΠΎΠ±Ρ€Π°Π·Π½ΠΎ свСтящийся, ΡΠΈΡΡŽΡ‰ΠΈΠΉ ярчС солнца. А Π½Π° Π³ΠΎΡ€Π°Ρ… Ρ‚Π΅Ρ… ΡΠ»Ρ‹ΡˆΠ°Π»ΠΈ ΠΎΠ½ΠΈ ΠΏΠ΅Π½ΠΈΠ΅, ликованья ΠΈ вСсСлья исполнСнноС.Β»

Василий, архиСпископ Новгородский.

Multithreading & Multiprocessing

ΠœΠ½ΠΎΠ³ΠΎΠΏΠΎΡ‚ΠΎΡ‡Π½ΠΎΡΡ‚ΡŒ

ΠœΠ½ΠΎΠ³ΠΎΠΏΠΎΡ‚ΠΎΡ‡Π½ΠΎΡΡ‚ΡŒ рСализуСтся ΠΌΠΎΠ΄ΡƒΠ»Π΅ΠΌ Threading. Π­Ρ‚ΠΎ Π½Π°Ρ‚ΠΈΠ²Π½Ρ‹Π΅ Posix-Ρ‚Ρ€Π΅Π΄Ρ‹, Ρ‚Π°ΠΊΠΈΠ΅ Ρ‚Ρ€Π΅Π΄Ρ‹ ΠΈΡΠΏΠΎΠ»Π½ΡΡŽΡ‚ΡΡ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΎΠ½Π½ΠΎΠΉ систСмой, Π° Π½Π΅ Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»ΡŒΠ½ΠΎΠΉ машиной.

Π’ Ρ‡Π΅ΠΌ ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ Ρ‚Ρ€Π΅Π΄ΠΎΠ² ΠΎΡ‚ ΠΌΡƒΠ»ΡŒΡ‚ΠΈΠΏΡ€ΠΎΡ†Π΅ΡΡΠΈΠ½Π³Π°?

Π“Π»Π°Π²Π½ΠΎΠ΅ ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ Π² Ρ€Π°Π·Π΄Π΅Π»Π΅Π½ΠΈΠΈ памяти. ΠŸΡ€ΠΎΡ†Π΅ΡΡΡ‹ нСзависимы Π΄Ρ€ΡƒΠ³ ΠΎΡ‚ Π΄Ρ€ΡƒΠ³Π°, ΠΈΠΌΠ΅ΡŽΡ‚ Ρ€Π°Π·Π΄Π΅Π»ΡŒΠ½Ρ‹Π΅ адрСсныС пространства, ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€Ρ‹, рСсурсы. Π’Ρ€Π΅Π΄Ρ‹ ΠΈΡΠΏΠΎΠ»Π½ΡΡŽΡ‚ΡΡ Π² совмСстном адрСсном пространствС, ΠΈΠΌΠ΅ΡŽΡ‚ ΠΎΠ±Ρ‰ΠΈΠΉ доступ ΠΊ памяти, ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΌ, Π·Π°Π³Ρ€ΡƒΠΆΠ΅Π½Π½Ρ‹ΠΌ модулям.

КакиС Π·Π°Π΄Π°Ρ‡ΠΈ Ρ…ΠΎΡ€ΠΎΡˆΠΎ параллСлятся, ΠΊΠ°ΠΊΠΈΠ΅ ΠΏΠ»ΠΎΡ…ΠΎ?

Π’Π΅ Π·Π°Π΄Π°Ρ‡ΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΏΠΎΡ€ΠΎΠΆΠ΄Π°ΡŽΡ‚ Π΄ΠΎΠ»Π³ΠΈΠΉ IO. Когда Ρ‚Ρ€Π΅Π΄ упираСтся Π² ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΠ΅ сокСта ΠΈΠ»ΠΈ диска, ΠΈΠ½Ρ‚Π΅Ρ€ΠΏΡ€Π΅Ρ‚Π°Ρ‚ΠΎΡ€ бросаСт этот Ρ‚Ρ€Π΅Π΄ ΠΈ стартуСт ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ. Π­Ρ‚ΠΎ Π·Π½Π°Ρ‡ΠΈΡ‚, Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ простоя ΠΈΠ·-Π·Π° оТидания. Наоборот, Ссли Ρ…ΠΎΠ΄ΠΈΡ‚ΡŒ Π² ΡΠ΅Ρ‚ΡŒ Π² ΠΎΠ΄Π½ΠΎΠΌ Ρ‚Ρ€Π΅Π΄Π΅ (Π² Ρ†ΠΈΠΊΠ»Π΅), Ρ‚ΠΎ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ Ρ€Π°Π· придСтся ΠΆΠ΄Π°Ρ‚ΡŒ ΠΎΡ‚Π²Π΅Ρ‚Π°.

Однако, Ссли Π·Π°Ρ‚Π΅ΠΌ Π² Ρ‚Ρ€Π΅Π΄Π΅ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅Ρ‚ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅, Ρ‚ΠΎ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒΡΡ Π±ΡƒΠ΄Π΅Ρ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ½ ΠΎΠ΄ΠΈΠ½. Π­Ρ‚ΠΎ Π½Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π½Π΅ даст прироста Π² скорости, Π½ΠΎ ΠΈ Π·Π°ΠΌΠ΅Π΄Π»ΠΈΡ‚ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ ΠΈΠ·-Π·Π° ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ Π½Π° Π΄Ρ€ΡƒΠ³ΠΈΠ΅ Ρ‚Ρ€Π΅Π΄Ρ‹.

ΠšΠΎΡ€ΠΎΡ‚ΠΊΠΈΠΉ ΠΎΡ‚Π²Π΅Ρ‚: Ρ…ΠΎΡ€ΠΎΡˆΠΎ лоТатся Π½Π° Ρ‚Ρ€Π΅Π΄Ρ‹ Π·Π°Π΄Π°Ρ‡ΠΈ ΠΏΠΎ Ρ€Π°Π±ΠΎΡ‚Π΅ с ΡΠ΅Ρ‚ΡŒΡŽ. НапримСр, Π²Ρ‹ΠΊΠ°Ρ‡Π°Ρ‚ΡŒ сто ΡƒΡ€Π»ΠΎΠ². ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½Π½Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°ΠΉΡ‚Π΅ Π²Π½Π΅ Ρ‚Ρ€Π΅Π΄ΠΎΠ².

НуТно ΠΏΠΎΡΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ 100 ΡƒΡ€Π°Π²Π½Π΅Π½ΠΈΠΉ. Π”Π΅Π»Π°Ρ‚ΡŒ это Π² Ρ‚Ρ€Π΅Π΄Π°Ρ… ΠΈΠ»ΠΈ Π½Π΅Ρ‚?

НСт, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ Π² этой Π·Π°Π΄Π°Ρ‡Π΅ Π½Π΅Ρ‚ Π²Π²ΠΎΠ΄Π°-Π²Ρ‹Π²ΠΎΠ΄Π°. Π˜Π½Ρ‚Π΅Ρ€ΠΏΡ€Π΅Ρ‚Π°Ρ‚ΠΎΡ€ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π±ΡƒΠ΄Π΅Ρ‚ Ρ‚Ρ€Π°Ρ‚ΠΈΡ‚ΡŒ лишнСС врСмя Π½Π° ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ Ρ‚Ρ€Π΅Π΄ΠΎΠ². Π‘Π»ΠΎΠΆΠ½Ρ‹Π΅ матСматичСскиС Π·Π°Π΄Π°Ρ‡ΠΈ Π»ΡƒΡ‡ΡˆΠ΅ Π²Ρ‹Π½ΠΎΡΠΈΡ‚ΡŒ Π² ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Π΅ процСссы, Π»ΠΈΠ±ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊ для распрСдСлСнных Π·Π°Π΄Π°Ρ‡ Celery, Π»ΠΈΠ±ΠΎ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π°Ρ‚ΡŒ ΠΊΠ°ΠΊ C-Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ.

ПониманиС Ρ‡Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠ΅ heap dump ΠΈ thread dump.

ПониманиС многопоточности, способов Π΅ΠΉ ΡƒΠΏΡ€Π°Π²Π»ΡΡ‚ΡŒ ΠΈ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ, с этим связанных (синхронизации, Π»ΠΎΠΊΠΈ, race condition ΠΈ Ρ‚.Π΄.);

  1. ΠœΠ½ΠΎΠ³ΠΎΠΏΠΎΡ‚ΠΎΡ‡Π½ΠΎΡΡ‚ΡŒ - Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ вычислСний, ΠΏΡ€ΠΈ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ для Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ ΠΏΡ€ΠΈΠΊΠ»Π°Π΄Π½ΠΎΠΉ Π·Π°Π΄Π°Ρ‡ΠΈ Π·Π°ΠΏΡƒΡΠΊΠ°ΡŽΡ‚ΡΡ ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‚ΡΡ нСсколько нСзависимых ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² вычислСний, ΠΏΡ€ΠΈΡ‡Ρ‘ΠΌ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ происходит ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ ΠΈΠ»ΠΈ псСвдоодноврСмСнно. Π’ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹Ρ… систСмах, Π³Π΄Π΅ Ρ‚Π΅Ρ€ΠΌΠΈΠ½Ρ‹ "ΠΏΠΎΡ‚ΠΎΠΊ" ΠΈ "процСсс" Ρ€Π°Π·Π»ΠΈΡ‡Π°ΡŽΡ‚ΡΡ, ΠΏΠΎΠ΄ "ΠΏΠΎΡ‚ΠΎΠΊΠΎΠΌ" ΠΏΠΎΠ½ΠΈΠΌΠ°ΡŽΡ‚ ΠΈΠΌΠ΅Π½Π½ΠΎ ΠΏΠΎΡ‚ΠΎΠΊ выполнСния (рСсурсами ΠΆΠ΅ Π²Π»Π°Π΄Π΅Π΅Ρ‚ ΡΡƒΡ‰Π½ΠΎΡΡ‚ΡŒ, называСмая "процСссом"). ΠžΠ±Ρ‹Ρ‡Π½ΠΎ примСняСтся для распараллСливания вычислСний Π½Π° нСсколько вычислитСлСй (процСссоров ΠΈ ядСр процСссора).

  2. ΠœΠ½ΠΎΠ³ΠΎΠΏΡ€ΠΎΡ†Π΅ΡΡΠ½ΠΎΡΡ‚ΡŒ - Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ вычислСний, ΠΊΠΎΠ³Π΄Π° для Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ ΠΏΡ€ΠΈΠΊΠ»Π°Π΄Π½ΠΎΠΉ Π·Π°Π΄Π°Ρ‡ΠΈ запускаСтся нСсколько нСзависимых процСссов. Π’ систСмах, Π³Π΄Π΅ ΠΏΠΎΠ΄ процСссом понимаСтся ΡΡƒΡ‰Π½ΠΎΡΡ‚ΡŒ, Π²Π»Π°Π΄Π΅ΡŽΡ‰Π°Ρ рСсурсами (ΠΏΠ°ΠΌΡΡ‚ΡŒΡŽ, ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹ΠΌΠΈ Ρ„Π°ΠΉΠ»Π°ΠΌΠΈ, сСтСвыми ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡΠΌΠΈ), нСсколько процСссов Π·Π°ΠΏΡƒΡΠΊΠ°ΡŽΡ‚ΡΡ с Ρ†Π΅Π»ΡŒΡŽ ΠΏΠΎΠ²Ρ‹ΡˆΠ΅Π½ΠΈΡ отказоустойчивости прилоТСния, Π° Ρ‚Π°ΠΊΠΆΠ΅ с Ρ†Π΅Π»ΡŒΡŽ ΠΏΠΎΠ²Ρ‹ΡˆΠ΅Π½ΠΈΡ бСзопасности. Π’.ΠΊ. ОБ выполняСт Ρ€Π°Π·Π΄Π΅Π»Π΅Π½ΠΈΠ΅ памяти ΠΈ ΠΏΡ€ΠΎΡ‡ΠΈΡ… рСсурсов ΠΈΠΌΠ΅Π½Π½ΠΎ ΠΌΠ΅ΠΆΠ΄Ρƒ процСссами (Π² Ρ‚ΠΎ врСмя ΠΊΠ°ΠΊ ΠΏΠΎΡ‚ΠΎΠΊΠΈ Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‚ Π² Π΅Π΄ΠΈΠ½ΠΎΠΌ адрСсном пространствС), Ρ‚ΠΎ Π°) Π²Π½Π΅Π·Π°ΠΏΠ½ΠΎ ΡƒΠΏΠ°Π²ΡˆΠΈΠΉ (Ρ‡ΠΈΡ‚Π°ΠΉ - ΡƒΠ±ΠΈΡ‚Ρ‹ΠΉ ОБ) процСсс Π½Π΅ ΡƒΡ€ΠΎΠ½ΠΈΡ‚ ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Π΅; Π±) Ссли Π² процСссС Π½Π°Ρ‡Π°Π» Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒΡΡ Ρ‡ΡƒΠΆΠ΅Ρ€ΠΎΠ΄Π½Ρ‹ΠΉ ΠΊΠΎΠ΄ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΈΠ·-Π·Π° RCE уязвимости), Ρ‚ΠΎ ΠΎΠ½ Π½Π΅ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ доступ ΠΊ содСрТимому памяти Π² Π΄Ρ€ΡƒΠ³ΠΈΡ… процСссах. ΠœΠ½ΠΎΠ³ΠΎΠΏΡ€ΠΎΡ†Π΅ΡΡΠ½ΠΎΡΡ‚ΡŒ сСгодня ΠΌΠΎΠΆΠ½ΠΎ ΡƒΠ²ΠΈΠ΄Π΅Ρ‚ΡŒ Π² Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π°Ρ…, ΠΊΠΎΠ³Π΄Π° ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Π΅ Π²ΠΊΠ»Π°Π΄ΠΊΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‚ΡΡ Π² Ρ€Π°Π·Π½Ρ‹Ρ… процСссах, ΠΈ ΡƒΠΏΠ°Π²ΡˆΠ°Ρ Π²ΠΊΠ»Π°Π΄ΠΊΠ° (ΠΈΠ·-Π·Π° js ΠΈΠ»ΠΈ ΠΈΠ·-Π·Π° ΠΊΡ€ΠΈΠ²ΠΎΠ³ΠΎ ΠΏΠ»Π°Π³ΠΈΠ½Π°) тянСт Π·Π° собой Π½Π΅ вСсь Π±Ρ€Π°ΡƒΠ·Π΅Ρ€, Π° Ρ‚ΠΎΠ»ΡŒΠΊΠΎ сСбя ΠΈΠ»ΠΈ Π΅Ρ‰Π΅ ΠΏΠ°Ρ€Ρƒ Π²ΠΊΠ»Π°Π΄ΠΎΠΊ.

# ΠžΠ΄Π½ΠΎΠΏΠΎΡ‚ΠΎΡ‡Π½ΠΎΠ΅ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅
import time

COUNT = 100_000_000

def countdown(n):
    while n > 0:
        n -= 1

start = time.time()
countdown(COUNT)    
end = time.time()

print("Count time", end - start)
Count time 3.81453800201416
# ΠœΠ½ΠΎΠ³ΠΎΠΏΠΎΡ‚ΠΎΡ‡Π½ΠΎΠ΅ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅, врСмя выполнСния Π±ΡƒΠ΄Π΅Ρ‚ большС, Ρ‡Π΅ΠΌ Ρƒ ΠΎΠ΄Π½ΠΎΠΏΠΎΡ‚ΠΎΡ‡Π½ΠΎΠ³ΠΎ, Ρ‚. ΠΊ. добавятся Π²Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ Π·Π°Ρ‚Ρ€Π°Ρ‚Ρ‹ Π½Π° ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²
import time
from threading import Thread

COUNT = 100_000_000

def countdown(n):
    while n > 0:
        n -= 1

t1 = Thread(target=countdown, args=(COUNT//2,))
t2 = Thread(target=countdown, args=(COUNT//2,))

start = time.time()
t1.start()
t2.start()
t1.join()
t2.join()
end = time.time()

print("Count time", end - start)
Count time 3.8378489017486572
# ΠœΠ½ΠΎΠ³ΠΎΠΏΡ€ΠΎΡ†Π΅ΡΡΠΎΡ€Π½ΠΎΠ΅ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅
import time
import multiprocessing as mp

COUNT = 100_000_000


def countdown(n):
    while n > 0:
        n -= 1

if __name__ ==  '__main__':
    pool = mp.Pool()
    start = time.time()
    pool.apply_async(countdown, args=(COUNT // 2,))
    pool.apply_async(countdown, args=(COUNT // 2,))
    pool.close()
    pool.join()
    end = time.time()
    print("Count time", end - start)

Count time 2.0029137134552

Threading

CPython interpreter can only run a single thread at a time. That is why using multiple threads won't result in a faster execution, unless at least one of the threads contains an I/O operation.

from threading import Thread, RLock, Semaphore, Event, Barrier
from concurrent.futures import ThreadPoolExecutor

Thread

<Thread> = Thread(target=<function>)           # Use `args=<collection>` to set the arguments.
<Thread>.start()                               # Starts the thread.
<bool> = <Thread>.is_alive()                   # Checks if the thread has finished executing.
<Thread>.join()                                # Waits for the thread to finish.

Use 'kwargs=<dict>' to pass keyword arguments to the function. Use 'daemon=True', or the program will not be able to exit while the thread is alive.**

Lock

<lock> = RLock()                               # Lock that can only be released by the owner.
<lock>.acquire()                               # Waits for the lock to be available.
<lock>.release()                               # Makes the lock available again.

Or:

with <lock>:                                   # Enters the block by calling acquire(),
    ...                                        # and exits it with release().

Semaphore, Event, Barrier

<Semaphore> = Semaphore(value=1)               # Lock that can be acquired by 'value' threads.
<Event>     = Event()                          # Method wait() blocks until set() is called.
<Barrier>   = Barrier(n_times)                 # Wait() blocks until it's called n_times.

Thread Pool Executor

Object that manages thread execution. An object with the same interface called ProcessPoolExecutor provides true parallelism by running a separate interpreter in each process. All arguments must be pickable.

<Exec> = ThreadPoolExecutor(max_workers=None)  # Or: `with ThreadPoolExecutor() as <name>: …`
<Exec>.shutdown(wait=True)                     # Blocks until all threads finish executing.
<iter> = <Exec>.map(<func>, <args_1>, ...)     # A multithreaded and non-lazy map().
<Futr> = <Exec>.submit(<func>, <arg_1>, ...)   # Starts a thread and returns its Future object.
<bool> = <Futr>.done()                         # Checks if the thread has finished executing.
<obj>  = <Futr>.result()                       # Waits for thread to finish and returns result.

asyncio

https://realpython.com/async-io-python/

Π’ JavaScript async / await сдСланы ΠΆΠ°Π΄Π½Ρ‹ΠΌΠΈ ΠΊΠ°ΠΊ Promise. ΠŸΡ€ΠΈ Π²Ρ‹Π·ΠΎΠ²Π΅ async Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ автоматичСски создаСтся Π·Π°Π΄Π°Ρ‡Π° ΠΈ отправляСтся Π² ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ Π½Π° исполнСниС Π² event loop. await, Π² свою ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ, просто ΠΆΠ΄Ρ‘Ρ‚ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚.

Π’ ΠΏΠΈΡ‚ΠΎΠ½Π΅ асинхронщину Π·Π°Π΄ΠΈΠ·Π°ΠΉΠ½ΠΈΠ»ΠΈ ΠΈΠ½Π°Ρ‡Π΅ - Π»Π΅Π½ΠΈΠ²ΠΎ.

Π’Ρ‹Π·ΠΎΠ² async Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ β€” ΠΊΠΎΡ€ΡƒΡ‚ΠΈΠ½Ρƒ, β€” которая Π½ΠΈ Ρ‡Π΅Π³ΠΎ Π½Π΅ Π΄Π΅Π»Π°Π΅Ρ‚.

asyncio.run() создаёт event loop, запускаСт (ΠΊΠΎΡ€Π½Π΅Π²ΡƒΡŽ) ΠΊΠΎΡ€ΡƒΡ‚ΠΈΠ½Ρƒ ΠΈ Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅Ρ‚ ΠΏΠΎΡ‚ΠΎΠΊ Π΄ΠΎ получСния Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π°.

await запускаСт ΠΊΠΎΡ€ΡƒΡ‚ΠΈΠ½Ρƒ ΠΈΠ·Π½ΡƒΡ‚Ρ€ΠΈ Π΄Ρ€ΡƒΠ³ΠΎΠΉ ΠΊΠΎΡ€ΡƒΡ‚ΠΈΠ½Ρ‹ Π² Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΌ event loop ΠΈ ΠΆΠ΄Ρ‘Ρ‚ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚.

Для запуска ΠΊΠΎΡ€ΡƒΡ‚ΠΈΠ½Ρ‹ Π±Π΅Π· оТидания (ΠΊΠ°ΠΊ это Π΄Π΅Π»Π°Π΅Ρ‚ Promise) ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ asyncio.create_task(coro). Π›ΠΈΠ±ΠΎ asyncio.gather(*aws), Ссли Π½Π°Π΄ΠΎ Π·Π°ΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ сразу нСсколько. НуТно Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΡΠ»Π΅Π΄ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ссылка Π½Π° Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΡΠΎΡ…Ρ€Π°Π½ΡΠ»Π°ΡΡŒ Π΄ΠΎ ΠΊΠΎΠ½Ρ†Π° вычислСния, ΠΈΠ½Π°Ρ‡Π΅ Π΅Π³ΠΎ ΠΏΠΎΠΆΡ€Π΅Ρ‚ GC ΠΈ всС оборвСтся Π½Π° самом интСрСсном мСстС (промис Π±Ρ‹ ΠΎΡ‚Ρ€Π°Π±ΠΎΡ‚Π°Π» Π΄ΠΎ ΠΊΠΎΠ½Ρ†Π° Π½Π΅ смотря Π½ΠΈ Π½Π° Ρ‡Ρ‚ΠΎ).

Π’ JS Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄ΠΈΠ½ event loop, поэтому Π±Ρ‹Π»ΠΎ Π²ΠΏΠΎΠ»Π½Π΅ Ρ€Π°Π·ΡƒΠΌΠ½ΠΎ Π·Π°ΠΊΠΎΠΏΠ°Ρ‚ΡŒ Π΅Π³ΠΎ Π²Π½ΡƒΡ‚Ρ€ΡŒ promise / async / await ΠΊΠ°ΠΊ Π΄Π΅Ρ‚Π°Π»ΡŒ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ, упростив Ρ€Π°Π±ΠΎΡ‚Ρƒ ΠΏΡ€ΠΈΠΊΠ»Π°Π΄Π½ΠΎΠΌΡƒ программисту. Π’ ΠΏΠΈΡ‚ΠΎΠ½Π΅ ΠΎΡ‚Π·Π΅Ρ€ΠΊΠ°Π»ΠΈΠ»ΠΈ Π±ΠΎΠ»Π΅Π΅ Ρ€Π°Π½Π½ΠΈΠΉ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ ΠΊΠΎΡ€ΡƒΡ‚ΠΈΠ½ Π½Π° Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€Π°Ρ…, Π΄Π°Π»ΠΈ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ€Π°Π·Π½Ρ‹Π΅ event loop ΠΈ выставили всС кишки Π½Π°Ρ€ΡƒΠΆΡƒ.

ΠŸΡ€ΠΎΡΡ‚Π΅ΠΉΡˆΠΈΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΉ запуск Π΄Π²ΡƒΡ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ, ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠ΅ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Π² "синхронном" ΠΌΠΈΡ€Π΅ заняло Π±Ρ‹ 2 сСкунды, Π½ΠΎ Π² "асинхронном" ΠΌΠΈΡ€Π΅ ΠΎΠ½ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‚ΡΡ ΠΏΡ€ΠΈΠ±Π»ΠΈΠ·ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Π·Π° 1 сСкунду.

Π‘Π΅Π· asyncio, просто Π΄Π²Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ с ΠΈΠΌΠΈΡ‚Π°Ρ†ΠΈΠ΅ΠΉ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ ΠΏΠΎΠ»Π΅Π·Π½ΠΎΠ³ΠΎ вычислСния ΠΈ ΠΏΠΎΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π³ΠΎ оТидания:

import time
from time import perf_counter

def fun1():
    sumi: int = 0

    for i in range(1000_000):
        sumi += i

    time.sleep(1)

    print(f'Sum: {sumi}')


def fun2():
    producti: int = 1

    for i in range(1, 25):
        producti = i * producti

    time.sleep(1)

    print(f'Product: {producti}')


start_time = perf_counter()

fun1()
fun2()

duration = perf_counter() - start_time
print(f'Total duration: {duration} seconds')
Sum: 499999500000
Product: 620448401733239439360000
Total duration: 2.047113300068304 seconds

Π‘ asyncio (синтаксис Π²Ρ‹Π·ΠΎΠ²Π° amain() ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ Π² связи с Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌΠΈ особСнностями использования asyncio Π² Jupiter Notebook):

import asyncio
from time import perf_counter

async def afun1():
    sumi: int = 0

    for i in range(1000_000):
        sumi += i

    await asyncio.sleep(1)

    print(f'Sum: {sumi}')


async def afun2():
    producti: int = 1

    for i in range(1, 25):
        producti = i * producti

    await asyncio.sleep(1)

    print(f'Product: {producti}')


async def amain():
    task1 = asyncio.create_task(afun1())
    task2 = asyncio.create_task(afun2())

    await task1
    await task2


start_time = perf_counter()

# asyncio.run(amain())
await amain()

duration = perf_counter() - start_time
print(f'Total duration: {duration} seconds')
Sum: 499999500000
Product: 620448401733239439360000
Total duration: 1.0792618000414222 seconds

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ запуска Π½Π° исполнСниС Π΄Π²ΡƒΡ… асинхронных пСриодичСских Π·Π°Π΄Π°Ρ‡:

import asyncio
from datetime import datetime

async def periodic_fun1(a, b):
    while True:
        await asyncio.sleep(1)
        print(f'periodic_fun1 complete with result {a + b}')


async def periodic_fun2(a, b):
    while True:
        await asyncio.sleep(0.5)
        print(f'periodic_fun2 complete with result {a - b}')


async def main():
    start_time = datetime.now()

    task1 = asyncio.create_task(periodic_fun1(3, 2))
    task2 = asyncio.create_task(periodic_fun2(3, 2))

    await asyncio.sleep(10)

    task1.cancel()
    task2.cancel()

    duration_time = datetime.now() - start_time
    print(f'Total duration time: {duration_time}')


if __name__ == '__main__':
    # asyncio.run(main())
    await amain()  # https://stackoverflow.com/questions/55409641/asyncio-run-cannot-be-called-from-a-running-event-loop-when-using-jupyter-no
Sum: 499999500000
Product: 620448401733239439360000

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ накоплСния Π΄Π°Π½Π½Ρ‹Ρ… ΠΎΡ‚ Π΄Π²ΡƒΡ… асинхронных пСриодичСских Π·Π°Π΄Π°Ρ‡ Π² ΠΎΠ΄Π½ΠΎΠΉ раздСляСмой структурС Π΄Π°Π½Π½Ρ‹Ρ… asyncio.Queue():

import asyncio
import random
from datetime import datetime

# ΠŸΡ€ΠΈΠΌΠ΅Ρ€ накоплСния Π΄Π°Π½Π½Ρ‹Ρ… ΠΎΡ‚ Π΄Π²ΡƒΡ… асинхронных пСриодичСских Π·Π°Π΄Π°Ρ‡ Π² ΠΎΠ΄Π½ΠΎΠΉ раздСляСмой структурС Π΄Π°Π½Π½Ρ‹Ρ… asyncio.Queue().

async def produce_small_random(queue):
    while True:
        await asyncio.sleep(0.5)
        r: int = random.randint(1, 9)
        print(f'Small random produced {r}')
        await queue.put(r)


async def produce_big_random(queue):
    while True:
        await asyncio.sleep(1)
        r: int = random.randint(100, 999)
        print(f'Big random produced {r}')
        await queue.put(r)


async def main():
    q = asyncio.Queue()
    start_time = datetime.now()

    small_random_task = asyncio.create_task(produce_small_random(q))
    big_random_task = asyncio.create_task(produce_big_random(q))

    await asyncio.sleep(10)

    small_random_task.cancel()
    big_random_task.cancel()

    # Dumping asyncio.queue into list
    randl: list[int] = []
    while q.qsize() > 0:
        randl.append(await q.get())
        q.task_done()

    duration_time = datetime.now() - start_time

    print(f'Total queue = {randl}')
    print(f'Total duration time: {duration_time}')


if __name__ == '__main__':
    # asyncio.run(main())
    await main()  # https://stackoverflow.com/questions/55409641/asyncio-run-cannot-be-called-from-a-running-event-loop-when-using-jupyter-no
Small random produced 1
Big random produced 929
Small random produced 4
Small random produced 3
Big random produced 967
Small random produced 8
Small random produced 1
Big random produced 622
Small random produced 9
Small random produced 7
Big random produced 891
Small random produced 5
Small random produced 5
Big random produced 820
Small random produced 8
Small random produced 5
Big random produced 771
Small random produced 5
Small random produced 6
Big random produced 289
Small random produced 6
Small random produced 8
Big random produced 873
Small random produced 8
Small random produced 3
Big random produced 127
Small random produced 6
Small random produced 3
Total queue = [1, 929, 4, 3, 967, 8, 1, 622, 9, 7, 891, 5, 5, 820, 8, 5, 771, 5, 6, 289, 6, 8, 873, 8, 3, 127, 6, 3]
Total duration time: 0:00:10.001941

7. ΠŸΠΎΠΏΡƒΠ»ΡΡ€Π½Ρ‹Π΅ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ

Β«ΠšΡ€Π°ΡΠΎΡ‚Π° ΠΈ Π±Π»Π°Π³ΠΎΠ»Π΅ΠΏΠΈΠ΅ этого Π³ΠΎΡ€ΠΎΠ΄Π° Ρ‚Π°ΠΊΠΎΠ²Ρ‹, ΠΊΠ°ΠΊΠΎΠ²Ρ‹Ρ… Π³Π»Π°Π· чСловСчСский Π½Π΅ Π²ΠΈΠ΄Π΅Π», ΠΈ ΡƒΡ…ΠΎ Π½Π΅ ΡΠ»Ρ‹ΡˆΠ°Π»ΠΎ, ΠΈ ΠΌΡ‹ΡΠ»ΡŒ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²ΠΈΡ‚ΡŒ, ΠΈ ΡƒΠΌ Π½Π΅ Π² состоянии ΠΏΠΎΡΡ‚ΠΈΠ³Π½ΡƒΡ‚ΡŒ β€” Π½ΠΈ чСловСчСский, Π½ΠΈ ангСльский.Β»

Инок Π“Ρ€ΠΈΠ³ΠΎΡ€ΠΈΠΉ, Β«Π’ΠΈΠ΄Π΅Π½ΠΈΠ΅ ΡΡ‚Ρ€Π°ΡˆΠ½ΠΎΠ³ΠΎ суда».

Common practice

Π›ΠΎΠ³Π³ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅

import pathlib
import sys
import logging
from logging.handlers import RotatingFileHandler
from colorlog import ColoredFormatter

class TestLogger:

    @staticmethod
    def get_logger(path_to_log_file: str, max_file_size: int, max_file_count: int) -> logging.Logger:
        logger = logging.getLogger("sample_logger")
        logger.setLevel(logging.DEBUG)

        # Π€ΠΎΡ€ΠΌΠ°Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΏΡ€ΠΈ Π²Ρ‹Π²ΠΎΠ΄Π΅ Π² Ρ„Π°ΠΉΠ»
        flog_formatter = logging.Formatter("%(asctime)s.%(msecs)03d %(filename)-24s %(levelname)-8s  %(message)s",
                                           datefmt="%a, %d %b %Y %H:%M:%S")
        file_handler = RotatingFileHandler(filename=path_to_log_file, mode="a", maxBytes=max_file_size,
                                           backupCount=max_file_count, encoding="utf-8", delay=False)
        file_handler.setFormatter(flog_formatter)
        logger.addHandler(file_handler)

        # Π€ΠΎΡ€ΠΌΠ°Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΏΡ€ΠΈ Π²Ρ‹Π²ΠΎΠ΄Π΅ Π² консоль
        clog_formatter = ColoredFormatter("%(asctime)s.%(msecs)03d  %(filename)-24s :%(lineno)4d  "
                                          "%(log_color)s%(levelname)-8s %(message)s%(reset)s",
                                          datefmt="%a, %d %b %Y %H:%M:%S")
        console_handler = logging.StreamHandler(sys.stdout)
        console_handler.setFormatter(clog_formatter)
        logger.addHandler(console_handler)

        return logger

log_file_max_size: int = 25 * 1024 ** 2  # ΠœΠ°ΠΊΡΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΉ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΎΠ΄Π½ΠΎΠ³ΠΎ Ρ„Π°ΠΉΠ»Π° Π»ΠΎΠ³ΠΎΠ²
log_file_max_count: int = 10  # МаксимальноС количСство Ρ„Π°ΠΉΠ»ΠΎΠ² Π»ΠΎΠ³ΠΎΠ²
log_file_path: str = "logs/sample_logger.log"

try:
    path = pathlib.Path(log_file_path)  # Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ ΠΏΡƒΡ‚ΡŒ ΠΊ Ρ„Π°ΠΉΠ»Ρƒ Π»ΠΎΠ³ΠΎΠ², Ссли ΠΎΠ½ Π½Π΅ сущСствуСт
    path.parent.mkdir(parents=True, exist_ok=True)
    logger = TestLogger.get_logger(log_file_path, log_file_max_size, log_file_max_count)
except Exception as err:
    print(f"Ошибка ΠΏΡ€ΠΈ ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΠ΅ создания Ρ„Π°ΠΉΠ»Π° Π»ΠΎΠ³Π°: {str(err)}")
    sys.exit()  # Аварийный Π²Ρ‹Ρ…ΠΎΠ΄

logger.debug("Debug message")
logger.info("Hello, world!")
logger.error("Error!")
Thu, 15 Sep 2022 17:37:36.754  1628851721.py            :  44  οΏ½[37mDEBUG    Debug messageοΏ½[0m
Thu, 15 Sep 2022 17:37:36.755  1628851721.py            :  45  οΏ½[32mINFO     Hello, world!οΏ½[0m
Thu, 15 Sep 2022 17:37:36.756  1628851721.py            :  46  οΏ½[31mERROR    Error!οΏ½[0m

ΠŸΡ€ΠΎΡ„ΠΈΠ»ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅

Stopwatch

from time import time
start_time = time()

j: int = 0
for i in range(10_000_000):  # Long operation
    j = i ** 2

duration = time() - start_time
print(f"{duration} seconds")
2.2923033237457275 seconds

High performance

from time import perf_counter
start_time = perf_counter()

j: int = 0
for i in range(10_000_000):  # Long operation
    j = i ** 2

duration = perf_counter() - start_time
print(f"{duration} seconds")
2.2668115999549627 seconds

timeit

Try to avoid a number of common traps for measuring execution times

from timeit import timeit

def long_pow():
    j: int = 0
    for i in range(1_000_000):  # Long operation
        j = i ** 2

timeit("long_pow()", number=10, globals=globals(), setup='pass')
1.8498943001031876

Call Graph

Π‘ΠΎΠ·Π΄Π°Π΅Ρ‚ PNG ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ Π³Ρ€Π°Ρ„Π° Π²Ρ‹Π·ΠΎΠ²ΠΎΠ² с подсвСчСнными ΡƒΠ·ΠΊΠΈΠΌΠΈ мСстами

from pycallgraph3 import PyCallGraph
from pycallgraph3.output import GraphvizOutput

def long_pow():
    j: int = 0
    for i in range(1000_000):  # Long operation
        j = i ** 2

def short_pow():
    j: int = 0
    for i in range(1000):  # Short operation
        j = i ** 2

with PyCallGraph(output=GraphvizOutput()):
    # Code to be profiled
    long_pow()
    short_pow()
    # This will generate a file called pycallgraph3.png

Random

import random

rf: float = random.random()  # A float inside [0, 1)
print(f"Single float random: {rf}")

ri: int = random.randint(1, 10)  # An int inside [from, to]
print(f"Single int random: {ri}")

rb = random.randbytes(10)
print(f"Random bytes: {rb}")

rc: str = random.choice(["Alice", "Bob", "Maggie", "Madhuri Dixit"])
print(f"Random choice: {rc}")

rs: str = random.sample([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 5)
print(f"Random list without duplicates: {rs}")

a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
print(f"List before shuffle: {a}")
random.shuffle(a)
print(f"List after shuffle: {a}")
Single float random: 0.9024807633898538
Single int random: 7
Random bytes: b'>\xe0^\x16PX\xf8E\xf8\x98'
Random choice: Bob
Random list without duplicates: [5, 10, 3, 6, 1]
List before shuffle: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
List after shuffle: [10, 4, 6, 5, 1, 8, 3, 9, 7, 2]

Input

Reads a line from user input or pipe if present.

= input(prompt=None)

Trailing newline gets stripped. Prompt string is printed to the standard output before reading input. Raises EOFError when user hits EOF (ctrl-d/ctrl-z⏎) or input stream gets exhausted.

Command Line Arguments

import sys
scripts_path = sys.argv[0]
arguments    = sys.argv[1:]

Argument Parser

from argparse import ArgumentParser, FileType
p = ArgumentParser(description=<str>)
p.add_argument('-<short_name>', '--<name>', action='store_true')  # Flag.
p.add_argument('-<short_name>', '--<name>', type=<type>)          # Option.
p.add_argument('<name>', type=<type>, nargs=1)                    # First argument.
p.add_argument('<name>', type=<type>, nargs='+')                  # Remaining arguments.
p.add_argument('<name>', type=<type>, nargs='*')                  # Optional arguments.
args  = p.parse_args()                                            # Exits on error.
value = args.<name>
Use `'help=<str>'` to set argument description.
Use `'default=<el>'` to set the default value.
Use `'type=FileType(<mode>)'` for files.

Print

print(<el_1>, ..., sep=' ', end='\n', file=sys.stdout, flush=False)
 
Use `'file=sys.stderr'` for messages about errors.
Use `'flush=True'` to forcibly flush the stream.

Pretty Print

from pprint import pprint
pprint(<collection>, width=80, depth=None, compact=False, sort_dicts=True)

Levels deeper than 'depth' get replaced by '...'.

Π¨ΠΈΡ„Ρ€ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΈ Π΄Π΅ΡˆΠΈΡ„Ρ€ΠΎΠ²Π°Π½ΠΈΠ΅

# pip install pycryptodomex
import hashlib

from Cryptodome import Random
from Cryptodome.Cipher import AES
from Cryptodome.Util.Padding import pad
from Cryptodome.Util.Padding import unpad

def encrypt_data(password: str, raw_data: bytes) -> bytes:
    res = bytes()
    try:
        key = hashlib.sha256(password.encode()).digest()
        align_raw = pad(raw_data, AES.block_size)
        iv = Random.new().read(AES.block_size)
        cipher = AES.new(key, AES.MODE_CBC, iv)
        ciphered_data = cipher.encrypt(align_raw)
        res = iv + ciphered_data
    except Exception as e:
        print(f"Encrypt error: {str(e)}")
    return res

def decrypt_data(password: str, encrypted_data: bytes) -> bytes:
    res = bytes()
    try:
        key = hashlib.sha256(password.encode()).digest()
        iv = encrypted_data[:AES.block_size]
        ciphered_data = encrypted_data[AES.block_size:]
        cipher = AES.new(key, AES.MODE_CBC, iv)
        decrypt_data = cipher.decrypt(ciphered_data)
        res = unpad(decrypt_data, AES.block_size)
    except Exception as e:
        print(f"Decrypt error: {str(e)}")
    return res

def encrypt_file(src_file: str, dst_file: str, password: str) -> bool:
    try:
        with open(src_file, "rb") as reader, open(dst_file, "wb") as writer:
            data = reader.read()
            data_enc = encrypt_data(password, data)
            writer.write(data_enc)
            writer.flush()
            print(f"{src_file} encrypted into {dst_file}")
        return True
    except Exception as e:
        print(f"Encrypt_file error: {str(e)}")
        return False

def decrypt_file(src_file: str, dst_file: str, password: str) -> bool:
    try:
        with open(src_file, "rb") as reader, open(dst_file, "wb") as writer:
            data = reader.read()
            data_decrypt = decrypt_data(password, data)
            writer.write(data_decrypt)
            writer.flush()
            print(f"{src_file} decrypted into {dst_file}")
        return True
    except Exception as e:
        print(f"Decrypt file error: {str(e)}")
        return False

if __name__ == '__main__':
    mes: bytes = bytes("A am the Message", "utf-8")
    passw: str = "h3AC3TsU8TECvyCqd5Q5WUag5uXLjct2"
    print(f"Original message: {mes}")

    # Encrypt message
    enc: bytes = encrypt_data(passw, mes)
    print(f"Encrypted message: {enc}")

    # Decrypt message
    dec: bytes = decrypt_data(passw, enc)
    print(f"Decrypted message: {dec}")
Original message: b'A am the Message'
Encrypted message: b' E\x92\xbeH\x87\xdde\t\xd3\x9ap\x0cO\xc3\xf8\x84\xc7~\x1c\x90\xcd\x9a\xd3\x1bNd\xccDt\x1b\xfcZ\x91\xb5\xd78\x85\x91R\x1e]3\x9c\xec\xcbC\xd8'
Decrypted message: b'A am the Message'

ВСстированиС, pytest

Для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с pytest Π²Π½ΡƒΡ‚Ρ€ΠΈ Jupiter notebook Π²ΠΎΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡΡ инструмСнтом ipytest

# pip install -U ipytest
import ipytest

ipytest.autoconfig()
%%ipytest

import ipytest

def test_my_func():
    assert my_func(0) == 0
    assert my_func(1) == 0
    assert my_func(2) == 2
    assert my_func(3) == 2
    
    
def my_func(x):
    return x // 2 * 2 
οΏ½[32m.οΏ½[0mοΏ½[32m                                                                                            [100%]οΏ½[0m
οΏ½[32mοΏ½[32mοΏ½[1m1 passedοΏ½[0mοΏ½[32m in 0.01sοΏ½[0mοΏ½[0m
%%ipytest

import pytest

@pytest.mark.parametrize('input,expected', [
    (0, 0),
    (1, 0),
    (2, 2),
    (3, 2),
])
def test_parametrized(input, expected):
    assert my_func(input) == expected
    
@pytest.fixture
def my_fixture():
    return 42

def test_fixture(my_fixture):
    assert my_fixture == 42
οΏ½[32m.οΏ½[0mοΏ½[32m.οΏ½[0mοΏ½[32m.οΏ½[0mοΏ½[32m.οΏ½[0mοΏ½[32m.οΏ½[0mοΏ½[32m                                                                                        [100%]οΏ½[0m
οΏ½[32mοΏ½[32mοΏ½[1m5 passedοΏ½[0mοΏ½[32m in 0.01sοΏ½[0mοΏ½[0m

Моки, стабы

ВСстовый Π΄Π²ΠΎΠΉΠ½ΠΈΠΊ - Ρ‚Π΅Ρ€ΠΌΠΈΠ½, ΠΎΠΏΠΈΡΡ‹Π²Π°ΡŽΡ‰ΠΈΠΉ всС Π²ΠΈΠ΄Ρ‹ Ρ„Π°Π»ΡŒΡˆΠΈΠ²Ρ‹Ρ… (fake) зависимостСй, Π½Π΅ΠΏΡ€ΠΈΠ³ΠΎΠ΄Π½Ρ‹Ρ… ΠΊ использованию Π² ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎΠΌ ΠΏΡ€ΠΎΠ΄ΡƒΠΊΡ‚Π΅ (non-production-ready). Вакая Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡ‚ΡŒ выглядит ΠΈ Π²Π΅Π΄Π΅Ρ‚ сСбя ΠΊΠ°ΠΊ Π΅Π΅ Π°Π½Π°Π»ΠΎΠ³, ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½Π½Ρ‹ΠΉ для production, Π½ΠΎ Π½Π° самом Π΄Π΅Π»Π΅ являСтся ΡƒΠΏΡ€ΠΎΡ‰Π΅Π½Π½ΠΎΠΉ вСрсиСй, которая сниТаСт ΡΠ»ΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΠΈ ΠΎΠ±Π»Π΅Π³Ρ‡Π°Π΅Ρ‚ тСстированиС. Зависимости Π±Ρ‹Π²Π°ΡŽΡ‚ пяти Ρ‚ΠΈΠΏΠΎΠ², Π½ΠΎ для простоты ΠΌΠΎΠΆΠ½ΠΎ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡ΠΈΡ‚ΡŒΡΡ двумя: ΠΌΠΎΠΊΠΈ (mock) ΠΈ стабы (stub).
Моки ΠΏΠΎΠΌΠΎΠ³Π°ΡŽΡ‚ ΠΈΠΌΠΈΡ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΈ ΠΈΠ·ΡƒΡ‡Π°Ρ‚ΡŒ исходящиС (outcoming) взаимодСйствия. Π’ΠΎ Π΅ΡΡ‚ΡŒ Π²Ρ‹Π·ΠΎΠ²Ρ‹, ΡΠΎΠ²Π΅Ρ€ΡˆΠ°Π΅ΠΌΡ‹Π΅ тСстируСмой систСмой (SUT) ΠΊ Π΅Π΅ зависимостям для измСнСния ΠΈΡ… состояния.
Π‘Ρ‚Π°Π±Ρ‹ ΠΏΠΎΠΌΠΎΠ³Π°ΡŽΡ‚ ΠΈΠΌΠΈΡ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ входящиС (incoming) взаимодСйствия. Π’ΠΎ Π΅ΡΡ‚ΡŒ Π²Ρ‹Π·ΠΎΠ²Ρ‹, ΡΠΎΠ²Π΅Ρ€ΡˆΠ°Π΅ΠΌΡ‹Π΅ SUT ΠΊ Π΅Π΅ зависимостям для получСния Π²Ρ…ΠΎΠ΄Π½Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ….

ΠŸΠΎΠ½ΡΡ‚ΠΈΠ΅ ΠΌΠΎΠΊΠΎΠ² ΠΈ стабов связано с ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΠΎΠΌ command-query separation (CQS). ΠŸΡ€ΠΈΠ½Ρ†ΠΈΠΏ CQS гласит, Ρ‡Ρ‚ΠΎ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΌΠ΅Ρ‚ΠΎΠ΄ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ Π»ΠΈΠ±ΠΎ ΠΊΠΎΠΌΠ°Π½Π΄ΠΎΠΉ, Π»ΠΈΠ±ΠΎ запросом, Π½ΠΎ Π½Π΅ ΠΎΠ±ΠΎΠΈΠΌΠΈ.
ΠšΠΎΠΌΠ°Π½Π΄Ρ‹ - это ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‚ ΠΏΠΎΠ±ΠΎΡ‡Π½Ρ‹Π΅ эффСкты ΠΈ Π½Π΅ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‚ Π½ΠΈΠΊΠ°ΠΊΠΎΠ³ΠΎ значСния. ΠŸΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ ΠΏΠΎΠ±ΠΎΡ‡Π½Ρ‹Ρ… эффСктов Π²ΠΊΠ»ΡŽΡ‡Π°ΡŽΡ‚ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ состояния ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°, ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ Ρ„Π°ΠΉΠ»Π° Π² Ρ„Π°ΠΉΠ»ΠΎΠ²ΠΎΠΉ систСмС ΠΈ Ρ‚. Π΄.
Запросы, Π½Π°ΠΎΠ±ΠΎΡ€ΠΎΡ‚, Π½Π΅ ΠΈΠΌΠ΅ΡŽΡ‚ ΠΏΠΎΠ±ΠΎΡ‡Π½Ρ‹Ρ… эффСктов ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅.
Π”Ρ€ΡƒΠ³ΠΈΠΌΠΈ словами, задавая вопрос, Π²Ρ‹ Π½Π΅ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΌΠ΅Π½ΡΡ‚ΡŒ ΠΎΡ‚Π²Π΅Ρ‚. Код, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ Ρ‚Π°ΠΊΠΎΠ΅ Ρ‡Π΅Ρ‚ΠΊΠΎΠ΅ Ρ€Π°Π·Π΄Π΅Π»Π΅Π½ΠΈΠ΅, становится Π»Π΅Π³Ρ‡Π΅ для чтСния. ВСстовыС Π΄Π²ΠΎΠΉΠ½ΠΈΠΊΠΈ, Π·Π°ΠΌΠ΅Π½ΡΡŽΡ‰ΠΈΠ΅ ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹, становятся ΠΌΠΎΠΊΠ°ΠΌΠΈ, ΠΈ, соотвСтствСнно, тСстовыС Π΄Π²ΠΎΠΉΠ½ΠΈΠΊΠΈ, Π·Π°ΠΌΠ΅Π½ΡΡŽΡ‰ΠΈΠ΅ запросы, становятся стабами.

НС Π½ΡƒΠΆΠ½ΠΎ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡΡ‚ΡŒ взаимодСйствия со стабами

Как ΡƒΠΆΠ΅ ΡƒΠΏΠΎΠΌΠΈΠ½Π°Π»ΠΎΡΡŒ, стабы ΠΏΠΎΠΌΠΎΠ³Π°ΡŽΡ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΡΠΌΡƒΠ»ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ входящиС взаимодСйствия, Π° Π½Π΅ ΠΈΠ·ΡƒΡ‡Π°Ρ‚ΡŒ ΠΈΡ…. Из этого слСдуСт, Ρ‡Ρ‚ΠΎ Π²Ρ‹ Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡΡ‚ΡŒ взаимодСйствиС со стабами. Π’Ρ‹Π·ΠΎΠ² ΠΎΡ‚ SUT ΠΊ стабу Π½Π΅ являСтся Ρ‡Π°ΡΡ‚ΡŒΡŽ ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎΠ³ΠΎ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π²Ρ‹Π΄Π°Π΅Ρ‚ SUT. Π’Π°ΠΊΠΎΠΉ Π²Ρ‹Π·ΠΎΠ² - это всСго лишь срСдство для получСния ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎΠ³ΠΎ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π°; это Π΄Π΅Ρ‚Π°Π»ΡŒ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ. ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° взаимодСйствий со стабами являСтся распространСнным Π°Π½Ρ‚ΠΈ-ΠΏΠ°Ρ‚Ρ‚Π΅Ρ€Π½ΠΎΠΌ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΏΡ€ΠΈΠ²ΠΎΠ΄ΠΈΡ‚ ΠΊ Ρ…Ρ€ΡƒΠΏΠΊΠΈΠΌ тСстам. ЕдинствСнный способ ΠΈΠ·Π±Π΅ΠΆΠ°Ρ‚ΡŒ хрупкости тСстов - это Π·Π°ΡΡ‚Π°Π²ΠΈΡ‚ΡŒ эти тСсты ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡΡ‚ΡŒ ΠΊΠΎΠ½Π΅Ρ‡Π½Ρ‹ΠΉ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ (ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π² ΠΈΠ΄Π΅Π°Π»Π΅ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΈΠΌΠ΅Ρ‚ΡŒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ для спСциалиста Π² ΠΏΡ€Π΅Π΄ΠΌΠ΅Ρ‚Π½ΠΎΠΉ области, Π° Π½Π΅ для программиста), Π° Π½Π΅ Π΄Π΅Ρ‚Π°Π»ΠΈ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ.

Π‘Π°ΠΌΠΎΠ΄ΠΎΡΡ‚Π°Ρ‚ΠΎΡ‡Π½ΠΎΡΡ‚ΡŒ тСстов

К тСстам Π½ΡƒΠΆΠ½ΠΎ ΠΎΡ‚Π½ΠΎΡΠΈΡ‚ΡŒΡΡ ΠΊΠ°ΠΊ ΠΊ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΠΌΡƒ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡŽ: ΠΏΡ€ΠΈ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠ΅ ΠΎΠ΄Π½ΠΈΡ… ΠΈ Ρ‚Π΅Ρ… ΠΆΠ΅ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ², ΠΌΡ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΏΠΎΠ»ΡƒΡ‡Π°Ρ‚ΡŒ Ρ€ΠΎΠ²Π½ΠΎ Ρ‚ΠΎΡ‚ ΠΆΠ΅ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚. ВСсты Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ самодостаточны, нСльзя ΠΎΠ±ΡƒΡΠ»Π°Π²Π»ΠΈΠ²Π°Ρ‚ΡŒ Π²Ρ‹Π·ΠΎΠ² Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ тСста ΠΏΡ€Π΅Π΄Π²Π°Ρ€ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ Π²Ρ‹Π·ΠΎΠ²ΠΎΠΌ ΠΊΠ°ΠΊΠΎΠ³ΠΎ-Ρ‚ΠΎ Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ тСста.

8. Алгоритмы

Β«Π‘Ρ‚ΠΎΠ»ΡŒ ΡΠΈΠ»ΡŒΠ½Ρ‹ΠΌ Π±Ρ‹Π» Π°Ρ€ΠΎΠΌΠ°Ρ‚ Ρ†Π²Π΅Ρ‚ΠΎΠ², Ρ‡Ρ‚ΠΎ ΠΎΠ½ доносился ΠΎΡ‚Ρ‚ΡƒΠ΄Π° Π΄Π°ΠΆΠ΅ Π΄ΠΎ нас. Π–ΠΈΡ‚Π΅Π»ΠΈ Ρ‚ΠΎΠ³ΠΎ мСста Π±Ρ‹Π»ΠΈ ΠΎΠ±Π»Π°Ρ‡Π΅Π½Ρ‹ Π² свСтящиСся ангСльскиС ΠΎΠ΄Π΅ΠΆΠ΄Ρ‹, ΠΈ ΠΎΠ΄Π΅ΠΆΠ΄Π° ΠΈΡ… Π±Ρ‹Π»Π° ΠΏΠΎΠ΄ΠΎΠ±Π½Π° мСсту, Π³Π΄Π΅ ΠΏΡ€Π΅Π±Ρ‹Π²Π°Π»ΠΈ ΠΎΠ½ΠΈΒ».

Β«ΠžΡ‚ΠΊΡ€ΠΎΠ²Π΅Π½ΠΈΠ΅ ΠŸΠ΅Ρ‚Ρ€Π°Β».

Algorithms

FizzBuzz

ΠΠ°ΠΏΠΈΡˆΠΈΡ‚Π΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ, которая Π²Ρ‹Π²ΠΎΠ΄ΠΈΡ‚ Π½Π° экран числа ΠΎΡ‚ 1 Π΄ΠΎ 100. ВмСсто чисСл, ΠΊΡ€Π°Ρ‚Π½Ρ‹Ρ… Ρ‚Ρ€Π΅ΠΌ, ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Π΄ΠΎΠ»ΠΆΠ½Π° Π²Ρ‹Π²ΠΎΠ΄ΠΈΡ‚ΡŒ слово Β«FizzΒ», Π° вмСсто чисСл, ΠΊΡ€Π°Ρ‚Π½Ρ‹Ρ… пяти β€” слово Β«BuzzΒ». Если число ΠΊΡ€Π°Ρ‚Π½ΠΎ ΠΈ 3, ΠΈ 5, Ρ‚ΠΎ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Π΄ΠΎΠ»ΠΆΠ½Π° Π²Ρ‹Π²ΠΎΠ΄ΠΈΡ‚ΡŒ слово Β«FizzBuzzΒ».

n: int = 100

for i in range(1, n + 1):
    if i % 15 == 0:
        item = "FizzBuzz"
    elif i % 5 == 0:
        item = "Buzz"
    elif i % 3 == 0:
        item = "Fizz"
    else:
        item = i

    print(item, end=" ")
1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzz 16 17 Fizz 19 Buzz Fizz 22 23 Fizz Buzz 26 Fizz 28 29 FizzBuzz 31 32 Fizz 34 Buzz Fizz 37 38 Fizz Buzz 41 Fizz 43 44 FizzBuzz 46 47 Fizz 49 Buzz Fizz 52 53 Fizz Buzz 56 Fizz 58 59 FizzBuzz 61 62 Fizz 64 Buzz Fizz 67 68 Fizz Buzz 71 Fizz 73 74 FizzBuzz 76 77 Fizz 79 Buzz Fizz 82 83 Fizz Buzz 86 Fizz 88 89 FizzBuzz 91 92 Fizz 94 Buzz Fizz 97 98 Fizz Buzz 

О-ΠΎ-ΠΎ! Π‘ΠΎΠ»ΡŒΡˆΠΎΠ΅!

Нотация O - характСристика асимптотичСской слоТности Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΠ° Π±Π΅Π· ΡƒΡ‡Π΅Ρ‚Π° константы.

n! >> 2^n >> n^3 >> n^2 >> nlogn >> n >> logn >> 1

ΠŸΡƒΠ·Ρ‹Ρ€ΡŒΠΊΠΎΠ²Π°Ρ сортировка (BubbleSort)

ΠŸΡ€ΠΎΡΡ‚Π΅ΠΉΡˆΠΈΠΉ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ сортировки, состоит ΠΈΠ· ΠΏΠΎΠ²Ρ‚ΠΎΡ€ΡΡŽΡ‰ΠΈΡ…ΡΡ ΠΏΡ€ΠΎΡ…ΠΎΠ΄ΠΎΠ² ΠΏΠΎ сортируСмому массиву. Π’ процСссС ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΏΡ€ΠΎΡ…ΠΎΠ΄Π° элСмСнты массива ΡΡ€Π°Π²Π½ΠΈΠ²Π°ΡŽΡ‚ΡΡ ΠΏΠΎΠΏΠ°Ρ€Π½ΠΎ; элСмСнты, Π½Π΅ ΡƒΠ΄ΠΎΠ²Π»Π΅Ρ‚Π²ΠΎΡ€ΡΡŽΡ‰ΠΈΠ΅ ΡƒΡΠ»ΠΎΠ²ΠΈΡŽ сортировки, ΠΌΠ΅Π½ΡΡŽΡ‚ΡΡ мСстами.

def bubblesort(arr):
    for i in range(len(arr)):
        for j in range(len(arr) - 1):
            if arr[j] > arr[j+1]:
                arr[j], arr[j+1] = arr[j+1], arr[j]

    return arr

arr: list = [28, 64, 2, 1, 13, 0]
print(bubblesort(arr))
[0, 1, 2, 13, 28, 64]

Быстрая сортировка (QuickSort)

ИдСя Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΠ° ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π°Ρ:

  1. ВыбираСтся ΠΎΠΏΠΎΡ€Π½Ρ‹ΠΉ элСмСнт, это Π² ΠΏΠ΅Ρ€Π²ΠΎΠΌ ΠΏΡ€ΠΈΠ±Π»ΠΈΠΆΠ΅Π½ΠΈΠΈ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ любой ΠΈΠ· элСмСнтов массива, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΈΠ· сСрСдины массива.
  2. ВсС элСмСнты массива ΡΡ€Π°Π²Π½ΠΈΠ²Π°ΡŽΡ‚ΡΡ с ΠΎΠΏΠΎΡ€Π½Ρ‹ΠΌ ΠΈ ΠΏΠ΅Ρ€Π΅ΡΡ‚Π°Π²Π»ΡΡŽΡ‚ΡΡ Ρ‚Π°ΠΊ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Ρ‚ΡŒ Π½ΠΎΠ²Ρ‹ΠΉ массив, состоящий ΠΈΠ· Π΄Π²ΡƒΡ… ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… сСгмСнтов - элСмСнты мСньшиС ΠΎΠΏΠΎΡ€Π½ΠΎΠ³ΠΎ, Ρ€Π°Π²Π½Ρ‹Π΅ ΠΎΠΏΠΎΡ€Π½ΠΎΠΌΡƒ + большиС ΠΎΠΏΠΎΡ€Π½ΠΎΠ³ΠΎ.
  3. Если Π΄Π»ΠΈΠ½Π° сСгмСнтов большС 1, Ρ‚ΠΎ рСкурсивно Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ сортировку ΠΈ для Π½ΠΈΡ… Ρ‚ΠΎΠΆΠ΅.
def quicksort(arr):
    less = []
    equal = []
    greater = []

    if len(arr) > 1:
        pivot = arr[0]
        for x in arr:
            if x < pivot:
                less.append(x)
            elif x == pivot:
                equal.append(x)
            elif x > pivot:
                greater.append(x)
        return quicksort(less) + equal + quicksort(greater)
    else:
        return arr

arr: list = [28, 64, 2, 1, 13, 0]
print(quicksort(arr))
[0, 1, 2, 13, 28, 64]

Π‘ΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²ΠΊΠ° слияниСм (MergeSort)

ΠšΠ»ΡŽΡ‡Π΅Π²Ρ‹ΠΌ ΠΌΠΎΠΌΠ΅Π½Ρ‚ΠΎΠΌ сортировки слияниСм являСтся (ΠΊΠ°ΠΊ Π½ΠΈ странно :) слияниС Π΄Π²ΡƒΡ… массивов. ΠŸΡ€ΠΈ слиянии массивы ΡΡ€Π°Π²Π½ΠΈΠ²Π°ΡŽΡ‚ΡΡ поэлСмСнто ΠΈ мСньший элСмСнт записываСтся Π² Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚ΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ массив; послС Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ достигнут ΠΊΠΎΠ½Π΅Ρ† ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΈΠ· массивов, Π² Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚ΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ массив пСрСписываСтся "хвост" ΠΎΡΡ‚Π°Π²ΡˆΠ΅Π³ΠΎΡΡ массива.
БовмСстно со слияниСм Π΄Π²ΡƒΡ… массивов ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ рСкурсивноС Ρ€Π°Π·Π±ΠΈΠ΅Π½ΠΈΠ΅ сортируСмого массива Π½Π° сСгмСнты мСньшСго Ρ€Π°Π·ΠΌΠ΅Ρ€Π°.

def mergesort(arr):
    if len(arr) < 2:
        return arr

    result, mid = [], int(len(arr)//2)

    y = mergesort(arr[:mid])
    z = mergesort(arr[mid:])

    while (len(y) > 0) and (len(z) > 0):
       if y[0] > z[0]:
        result.append(z.pop(0))   
       else:
        result.append(y.pop(0))

    return result + y + z

arr: list = [28, 64, 2, 1, 13, 0]
print(mergesort(arr))
[0, 1, 2, 13, 28, 64]

ΠŸΠΈΡ€Π°ΠΌΠΈΠ΄Π°Π»ΡŒΠ½Π°Ρ сортировка (HeapSort)

ΠŸΡ€Π΅Π²Ρ€Π°Ρ‰Π°Π΅ΠΌ массив Π² Π΄Π²ΠΎΠΈΡ‡Π½ΠΎΠ΅ Π΄Π΅Ρ€Π΅Π²ΠΎ Π·Π° О(n) ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ.
Π Π°Π· Π·Π° Ρ€Π°Π·ΠΎΠΌ прСобразуя Π΄Π΅Ρ€Π΅Π²ΠΎ, ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠΌ отсортированный массив.

def heap_sort():     
    end = len(arr)   
    start = end // 2 - 1
    for i in range(start, -1, -1):   
        heapify(end, i)   
    for i in range(end-1, 0, -1):   
        swap(i, 0)   
        heapify(i, 0)

def heapify(end,i):   
    l = 2 * i + 1  
    r = 2 * (i + 1)   
    max = i   
    if l < end and arr[i] < arr[l]:   
        max = l   
    if r < end and arr[max] < arr[r]:   
        max = r   
    if max != i:   
        swap(i, max)   
        heapify(end, max) 

def swap(i, j):                    
    arr[i], arr[j] = arr[j], arr[i] 

arr: list = [28, 64, 2, 1, 13, 0]
heap_sort()
print(arr)
[0, 1, 2, 13, 28, 64]

Π‘ΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²ΠΊΠ° вставками (InsertionSort)

ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ Π½ΠΎΠ²Ρ‹ΠΉ элСмСнт заносится Π² Π²Ρ‹Ρ…ΠΎΠ΄Π½ΡƒΡŽ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ "ΠΈΠ½Π΄ΠΈΠ²ΠΈΠ΄ΡƒΠ°Π»ΡŒΠ½ΠΎ", Ρ‚. Π΅. ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ Ρ€Π°Π· для добавлСния Π½ΠΎΠ²ΠΎΠ³ΠΎ элСмСнта приходится ΡΠ΄Π²ΠΈΠ³Π°Ρ‚ΡŒ Ρ‡Π°ΡΡ‚ΡŒ массива. Алгоритм ΠΌΠ΅Π΄Π»Π΅Π½Π½Ρ‹ΠΉ, для ускорСния вставки ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π±ΠΈΠ½Π°Ρ€Π½Ρ‹ΠΉ поиск.

def insertionsort(arr):
    for index in range(1, len(arr)):

        currentvalue = arr[index]
        position = index

        while position > 0 and arr[position - 1] > currentvalue:
            arr[position] = arr[position - 1]
            position = position - 1

        arr[position] = currentvalue


arr: list = [28, 64, 2, 1, 13, 0]
insertionsort(arr)
print(arr)
[0, 1, 2, 13, 28, 64]

Timsort

ΠšΠΎΠΌΠ±ΠΈΠ½ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ сортировки, ΡΠΎΡ‡Π΅Ρ‚Π°ΡŽΡ‰ΠΈΠΉ сортировку вставками, сортировку слияниСм ΠΈ ΠΏΡ€Π΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅, Ρ‡Ρ‚ΠΎ Π² Ρ€Π΅Π°Π»ΡŒΠ½ΠΎΠΌ ΠΌΠΈΡ€Π΅ Π΄Π°Π½Π½Ρ‹Π΅ часто ΡƒΠΆΠ΅ частично упорядочСны (поиск упорядочСнных подмассивов). Π‘Ρ‚Π°Π½Π΄Π°Ρ€Ρ‚ для Python, Java, Swift.

Introsort

ΠšΠΎΠΌΠ±ΠΈΠ½ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ сортировки, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ Π±Ρ‹ΡΡ‚Ρ€ΡƒΡŽ сортировку, плюс, ΠΏΡ€ΠΈ ΠΏΡ€Π΅Π²Ρ‹ΡˆΠ΅Π½ΠΈΠΈ Π³Π»ΡƒΠ±ΠΈΠ½Ρ‹ рСкурсии Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ Π²Π΅Π»ΠΈΡ‡ΠΈΠ½Ρ‹ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π»ΠΎΠ³Π°Ρ€ΠΈΡ„ΠΌΠ° ΠΎΡ‚ числа сортируСмых элСмСнтов), ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π½Π° ΠΏΠΈΡ€Π°ΠΌΠΈΠ΄Π°Π»ΡŒΠ½ΡƒΡŽ сортировку. Π‘Ρ‚Π°Π½Π΄Π°Ρ€Ρ‚ для .NET.

ΠŸΠΎΡ€Π°Π·Ρ€ΡΠ΄Π½Π°Ρ сортировка (RadixSort)

Π‘ΠΎΡ€Ρ‚ΠΈΡ€ΡƒΠ΅Ρ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ сущности, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠΎΠΆΠ½ΠΎ Ρ€Π°Π·Π±ΠΈΡ‚ΡŒ Π½Π° "разряды", ΠΈΠΌΠ΅ΡŽΡ‰ΠΈΠ΅ Ρ€Π°Π·Π½Ρ‹ΠΉ вСс. Π­Ρ‚ΠΎ ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Ρ†Π΅Π»Ρ‹Π΅ числа ΠΈΠ»ΠΈ строки. БоотвСтсвСнно, элСмСнты ΡΠΎΡ€Ρ‚ΠΈΡ€ΡƒΡŽΡ‚ΡΡ поразрядно, начиная с разряда, ΠΈΠΌΠ΅ΡŽΡ‰Π΅Π³ΠΎ ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΉ вСс.

def radixsort(arr: list):
    n = len(str(max(arr)))

    for k in range(n):
        bucket_list=[[] for i in range(10)]
        for i in arr:
            bucket_list[i // (10**k) % 10].append(i)
        arr = sum(bucket_list, [])  # Flattening a list of lists to a list
    return arr

arr: list = [28, 64, 2, 1, 13, 0]
print(radixsort(arr))
[0, 1, 2, 13, 28, 64]

Π’Π°Π±Π»ΠΈΡ†Π° сравнСния ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² сортировки

Β Β 

<style> table th:first-of-type { width: 35%; } table th:nth-of-type(2) { width: 35%; } table th:nth-of-type(3) { width: 5%; } table th:nth-of-type(4) { width: 5%; } table th:nth-of-type(5) { width: 5%; } table th:nth-of-type(6) { width: 5%; } table th:nth-of-type(7) { width: 5%; } table th:nth-of-type(8) { width: 5%; } </style>
Π‘ΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²ΠΊΠ° ΠŸΡ€Π΅ΠΈΠΌΡƒΡ‰Π΅ΡΡ‚Π²ΠΎ Best Avg Worst Mem Stable Paral
ΠŸΡƒΠ·Ρ‹Ρ€ΡŒΠΊΠΎΠ²Π°Ρ
(Bubble)
ΠŸΡ€ΠΎΡΡ‚Π΅ΠΉΡˆΠ°Ρ рСализация n n^2 n^2 1 + +
Быстрая
(Quick)
Π₯ΠΎΡ€ΠΎΡˆΠ΅Π΅ быстродСйствиС Π² срСднСм случаС n*logn n*logn n^2 logn +/-
(depends)
+
БлияниСм
(Merge)
ΠœΠΎΠΆΠ΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ со структурами, ΠΊ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ Π²ΠΎΠ·ΠΌΠΎΠΆΠ΅Π½ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ доступ n*logn n*logn n*logn n
(depends)
+ +
ΠŸΠΈΡ€Π°ΠΌΠΈΠ΄Π°Π»ΡŒΠ½Π°Ρ
(Heap)
ΠŸΡ€Π΅Π΄ΡΠΊΠ°Π·ΡƒΠ΅ΠΌΠ°Ρ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ Π² Π½Π°ΠΈΡ…ΡƒΠ΄ΡˆΠ΅ΠΌ случаС, рСкомСдуСтся для ΠΏΠΎΡ‡Ρ‚ΠΈ отсортированных Π΄Π°Π½Π½Ρ‹Ρ… n*logn n*logn n*logn 1 - -
Вставками
(Insertion)
РСкомСдуСтся для ΠΏΠΎΡ‡Ρ‚ΠΈ отсортированных Π΄Π°Π½Π½Ρ‹Ρ… ΠΈΠ»ΠΈ для ΠΌΠ°Π»ΠΎΠ³ΠΎ количСства элСмСнтов n n^2 n^2 1 + -
Timsort ΠšΠΎΠΌΠ±ΠΈΠ½ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ. Π‘Ρ‚Π°Π½Π΄Π°Ρ€Ρ‚ для Python, Java, Swift n*logn n*logn n*logn logn - -
Introsort ΠšΠΎΠΌΠ±ΠΈΠ½ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ. Π‘Ρ‚Π°Π½Π΄Π°Ρ€Ρ‚ для .Net n*logn n*logn n*logn logn - -
ΠŸΠΎΡ€Π°Π·Ρ€ΡΠ΄Π½Π°Ρ
(Radix)
Быстрая сортировка для Ρ†Π΅Π»Ρ‹Ρ… чисСл ΠΈ строк n*w n*w n*w n+w +/-
(depends)
+

Π›ΠΈΠ½Π΅ΠΉΠ½Ρ‹ΠΉ поиск

ΠŸΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ поиск элСмСнта Π² нСосортированном массивС

def linear_search(arr, x):
    for i in range(len(arr)):
        if arr[i] == x:
            return i

    return None

arr: list = [28, 64, 2, 1, 13, 0]
print(linear_search(arr, 64))
1

Π‘ΠΈΠ½Π°Ρ€Π½Ρ‹ΠΉ поиск

Π Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ с отсортированными массивами. БСрСтся Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΈΠ· сСрСдины массива ΠΈ сравниваСтся с искомой Π²Π΅Π»ΠΈΡ‡ΠΈΠ½ΠΎΠΉ. Π’ зависимости ΠΎΡ‚ сравнСния дальнСйший рСкурсивный поиск продолТаСтся Π² сСрСдинС Π»ΠΈΠ±ΠΎ Π»Π΅Π²ΠΎΠ³ΠΎ, Π»ΠΈΠ±ΠΎ ΠΏΡ€Π°Π²ΠΎΠ³ΠΎ подмассива.

def binary_search(arr, x):
    left, right = 0, len(arr) - 1

    while left <= right:
        middle = (left + right) // 2

        if arr[middle] == x:
            return middle

        if arr[middle] < x:
            left = middle + 1
        elif arr[middle] > x:
            right = middle - 1

arr: list = [0, 24, 64, 222, 1300, 2048]
print(binary_search(arr, 64))
2

Поиск Π² Π³Π»ΡƒΠ±ΠΈΠ½Ρƒ (DFS)

ΠœΠ΅Ρ‚ΠΎΠ΄ ΠΎΠ±Ρ…ΠΎΠ΄Π° Π³Ρ€Π°Ρ„Π°. Depth-first search (DFS) ΠΌΠΎΠΆΠ½ΠΎ Ρ‡ΡƒΡ‚ΡŒ Ρ‚ΠΎΡ‡Π½Π΅Π΅ пСрСвСсти ΠΊΠ°ΠΊ "поиск Π² ΠΏΠ΅Ρ€Π²ΡƒΡŽ ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ Π² Π³Π»ΡƒΠ±ΠΈΠ½Ρƒ". БоотвСтствСнно, рСкурсивный Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ поиска ΠΈΠ΄Π΅Ρ‚ Β«Π²Π³Π»ΡƒΠ±ΡŒΒ» Π³Ρ€Π°Ρ„Π°, насколько это Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ. Π•ΡΡ‚ΡŒ нСрСкурсивныС Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Ρ‹ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΠ°, Ρ€Π°Π·Π³Ρ€ΡƒΠΆΠ°ΡŽΡ‰ΠΈΠ΅ стСк Π²Ρ‹Π·ΠΎΠ²ΠΎΠ².

# Using a Python dictionary to act as an adjacency list
graph = {
  '5' : ['3','7'],
  '3' : ['2', '4'],
  '7' : ['8'],
  '2' : [],
  '4' : ['8'],
  '8' : []
}

visited = set() # Set to keep track of visited nodes of graph

def dfs(visited, graph, node):  # Function for DFS
    if node not in visited:
        print (node)
        visited.add(node)
        for neighbour in graph[node]:
            dfs(visited, graph, neighbour)

dfs(visited, graph, '5')
5
3
2
4
8
7

Поиск Π² ΡˆΠΈΡ€ΠΈΠ½Ρƒ (BFS)

Π’ ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ ΠΎΡ‚ ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅Π³ΠΎ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Π° Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ Breadth-first search (BFS) ΠΏΠ΅Ρ€Π΅Π±ΠΈΡ€Π°Π΅Ρ‚ Π² ΠΏΠ΅Ρ€Π²ΡƒΡŽ ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ Π²Π΅Ρ€ΡˆΠΈΠ½Ρ‹ с ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²Ρ‹ΠΌ расстояниСм ΠΎΡ‚ корня, ΠΈ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΠΎΡ‚ΠΎΠΌ ΠΈΠ΄Π΅Ρ‚ Β«Π²Π³Π»ΡƒΠ±ΡŒΒ».

# https://codereview.stackexchange.com/questions/135156/bfs-implementation-in-python-3
import collections


def breadth_first_search(graph, root): 
    visited, queue = set(), collections.deque([root])
    while queue: 
        vertex = queue.popleft()
        for neighbour in graph[vertex]: 
            if neighbour not in visited: 
                visited.add(neighbour) 
                queue.append(neighbour)

if __name__ == '__main__':
    graph = {0: [1, 2], 1: [2], 2: []} 
    breadth_first_search(graph, 0)
deque([])

Алгоритм ДСйкстры

Находит ΠΊΡ€Π°Ρ‚Ρ‡Π°ΠΉΡˆΠΈΠ΅ ΠΏΡƒΡ‚ΠΈ ΠΎΡ‚ ΠΎΠ΄Π½ΠΎΠΉ ΠΈΠ· Π²Π΅Ρ€ΡˆΠΈΠ½ Π³Ρ€Π°Ρ„Π° Π΄ΠΎ всСх ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Ρ…. Алгоритм Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для Π³Ρ€Π°Ρ„ΠΎΠ² Π±Π΅Π· ΠΎΡ‚Ρ€ΠΈΡ†Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… Ρ€Ρ‘Π±Π΅Ρ€.

# https://stackoverflow.com/questions/22897209/dijkstras-algorithm-in-python
nodes = ('A', 'B', 'C', 'D', 'E', 'F', 'G')
distances = {
    'B': {'A': 5, 'D': 1, 'G': 2},
    'A': {'B': 5, 'D': 3, 'E': 12, 'F' :5},
    'D': {'B': 1, 'G': 1, 'E': 1, 'A': 3},
    'G': {'B': 2, 'D': 1, 'C': 2},
    'C': {'G': 2, 'E': 1, 'F': 16},
    'E': {'A': 12, 'D': 1, 'C': 1, 'F': 2},
    'F': {'A': 5, 'E': 2, 'C': 16}}

unvisited = {node: None for node in nodes} #using None as +inf
visited = {}
current = 'B'
currentDistance = 0
unvisited[current] = currentDistance

while True:
    for neighbour, distance in distances[current].items():
        if neighbour not in unvisited: continue
        newDistance = currentDistance + distance
        if unvisited[neighbour] is None or unvisited[neighbour] > newDistance:
            unvisited[neighbour] = newDistance
    visited[current] = currentDistance
    del unvisited[current]
    if not unvisited: break
    candidates = [node for node in unvisited.items() if node[1]]
    current, currentDistance = sorted(candidates, key = lambda x: x[1])[0]

print(visited)
{'B': 0, 'D': 1, 'E': 2, 'G': 2, 'C': 3, 'A': 4, 'F': 4}

Алгоритм Π‘Π΅Π»Π»ΠΌΠ°Π½Π°-Π€ΠΎΡ€Π΄Π°

Как ΠΈ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ ДСйкстры, Π½Π°Ρ…ΠΎΠ΄ΠΈΡ‚ ΠΊΡ€Π°Ρ‚Ρ‡Π°ΠΉΡˆΠΈΠ΅ ΠΏΡƒΡ‚ΠΈ ΠΎΡ‚ ΠΎΠ΄Π½ΠΎΠΉ ΠΈΠ· Π²Π΅Ρ€ΡˆΠΈΠ½ Π³Ρ€Π°Ρ„Π° Π΄ΠΎ всСх ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Ρ…, Π½ΠΎ, Π² ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ ΠΎΡ‚ ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ, позволяСт Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ с Π³Ρ€Π°Ρ„Π°ΠΌΠΈ с Ρ€Π΅Π±Ρ€Π°ΠΌΠΈ, ΠΈΠΌΠ΅ΡŽΡ‰ΠΈΠΌΠΈ ΠΎΡ‚Ρ€ΠΈΡ†Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ вСс.

Π’Π°Π±Π»ΠΈΡ†Π° сравнСния ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² поиска

Π’ΠΈΠ΄ поиска Π‘Ρ‚Ρ€ΡƒΠΊΡ‚ΡƒΡ€Π° Π΄Π°Π½Π½Ρ‹Ρ… Avg Worst Mem
Π›ΠΈΠ½Π΅ΠΉΠ½Ρ‹ΠΉ поиск Массив n n 1
Π‘ΠΈΠ½Π°Ρ€Π½Ρ‹ΠΉ поиск ΠžΡ‚ΡΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ массив logn n 1
Поиск Π² Π³Π»ΡƒΠ±ΠΈΠ½Ρƒ (DFS) Π“Ρ€Π°Ρ„ V+E V
Поиск Π² ΡˆΠΈΡ€ΠΈΠ½Ρƒ (BFS) Π“Ρ€Π°Ρ„ V+E V
Алгоритм ДСйкстры Π“Ρ€Π°Ρ„ (V+E)logV (V+E)logV V
Алгоритм Π‘Π΅Π»Π»ΠΌΠ°Π½Π°-Π€ΠΎΡ€Π΄Π° Π“Ρ€Π°Ρ„ V*E V*E V

ΠœΠ°Ρ‚Ρ€ΠΈΡ†Π° смСТности

ΠšΠ²Π°Π΄Ρ€Π°Ρ‚Π½Π°Ρ цСлочислСнная ΠΌΠ°Ρ‚Ρ€ΠΈΡ†Π° Ρ€Π°Π·ΠΌΠ΅Ρ€Π° V*V, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ элСмСнта a{i, j} Ρ€Π°Π²Π½ΠΎ числу Ρ€Ρ‘Π±Π΅Ρ€ ΠΈΠ· i-ΠΉ Π²Π΅Ρ€ΡˆΠΈΠ½Ρ‹ Π² j-ю Π²Π΅Ρ€ΡˆΠΈΠ½Ρƒ.
ΠœΠ°Ρ‚Ρ€ΠΈΡ†Π° смСТности простого Π³Ρ€Π°Ρ„Π° (Π½Π΅ содСрТащСго ΠΏΠ΅Ρ‚Π΅Π»ΡŒ ΠΈ ΠΊΡ€Π°Ρ‚Π½Ρ‹Ρ… Ρ€Ρ‘Π±Π΅Ρ€) являСтся Π±ΠΈΠ½Π°Ρ€Π½ΠΎΠΉ ΠΌΠ°Ρ‚Ρ€ΠΈΡ†Π΅ΠΉ ΠΈ содСрТит Π½ΡƒΠ»ΠΈ Π½Π° Π³Π»Π°Π²Π½ΠΎΠΉ Π΄ΠΈΠ°Π³ΠΎΠ½Π°Π»ΠΈ.

ΠœΠ°Ρ‚Ρ€ΠΈΡ†Π° инцидСнтности

Бпособ прСдставлСния Π³Ρ€Π°Ρ„Π°, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ ΡƒΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‚ΡΡ связи ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΈΠ½Ρ†ΠΈΠ΄Π΅Π½Ρ‚Π½Ρ‹ΠΌΠΈ элСмСнтами Π³Ρ€Π°Ρ„Π° (Ρ€Π΅Π±Ρ€Π°ΠΌΠΈ ΠΈ Π²Π΅Ρ€ΡˆΠΈΠ½Π°ΠΌΠΈ). Π‘Ρ‚ΠΎΠ»Π±Ρ†Ρ‹ ΠΌΠ°Ρ‚Ρ€ΠΈΡ†Ρ‹ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‚ Ρ€Π΅Π±Ρ€Π°ΠΌ, строки β€” Π²Π΅Ρ€ΡˆΠΈΠ½Π°ΠΌ. НСнулСвоС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π² ячСйкС ΠΌΠ°Ρ‚Ρ€ΠΈΡ†Ρ‹ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ связь ΠΌΠ΅ΠΆΠ΄Ρƒ Π²Π΅Ρ€ΡˆΠΈΠ½ΠΎΠΉ ΠΈ Ρ€Π΅Π±Ρ€ΠΎΠΌ (ΠΈΡ… ΠΈΠ½Ρ†ΠΈΠ΄Π΅Π½Ρ‚Π½ΠΎΡΡ‚ΡŒ). Если связи ΠΌΠ΅ΠΆΠ΄Ρƒ Π²Π΅Ρ€ΡˆΠΈΠ½ΠΎΠΉ ΠΈ Ρ€Π΅Π±Ρ€ΠΎΠΌ Π½Π΅Ρ‚, Ρ‚ΠΎ Π² ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΡƒΡŽ ячСйку ставится Β«0Β».
Π’ случаС ΠΎΡ€ΠΈΠ΅Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ Π³Ρ€Π°Ρ„Π° ΠΊΠ°ΠΆΠ΄ΠΎΠΉ Π΄ΡƒΠ³Π΅ ставится Π² ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅ΠΌ столбцС: 1 Π² строкС Π²Π΅Ρ€ΡˆΠΈΠ½Ρ‹ x ΠΈ -1 Π² строкС Π²Π΅Ρ€ΡˆΠΈΠ½Ρ‹ y.

Бписок смСТности

Π‘Π°ΠΌΡ‹ΠΉ распространСнный Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ хранСния Π³Ρ€Π°Ρ„Π°. Бпособ прСдставлСния Π³Ρ€Π°Ρ„Π° Π² Π²ΠΈΠ΄Π΅ ΠΊΠΎΠ»Π»Π΅ΠΊΡ†ΠΈΠΈ списков Π²Π΅Ρ€ΡˆΠΈΠ½. КаТдой Π²Π΅Ρ€ΡˆΠΈΠ½Π΅ Π³Ρ€Π°Ρ„Π° соотвСтствуСт список, состоящий ΠΈΠ· «сосСдСй» этой Π²Π΅Ρ€ΡˆΠΈΠ½Ρ‹.
Π’Π°Ρ€ΠΈΠ°Π½Ρ‚Ρ‹:
β€’ использованиС Ρ…Π΅Ρˆ-Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ для ассоциации ΠΊΠ°ΠΆΠ΄ΠΎΠΉ Π²Π΅Ρ€ΡˆΠΈΠ½Ρ‹ со списком смСТных Π²Π΅Ρ€ΡˆΠΈΠ½; β€’ Π²Π΅Ρ€ΡˆΠΈΠ½Ρ‹ прСдставлСны числовым индСксом Π² массивС, каТдая ячСйка массива ссылаСтся Π½Π° ΠΎΠ΄Π½ΠΎΠ½Π°ΠΏΡ€Π°Π²Π»Π΅Π½Π½Ρ‹ΠΉ связанный список сосСдних Π²Π΅Ρ€ΡˆΠΈΠ½;
β€’ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½Ρ‹Π΅ классы Π²Π΅Ρ€ΡˆΠΈΠ½ ΠΈ Ρ€Ρ‘Π±Π΅Ρ€, ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Π²Π΅Ρ€ΡˆΠΈΠ½Ρ‹ содСрТит ссылку Π½Π° ΠΊΠΎΠ»Π»Π΅ΠΊΡ†ΠΈΡŽ Ρ€Ρ‘Π±Π΅Ρ€, ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Ρ€Π΅Π±Ρ€Π° содСрТит ссылки Π½Π° ΠΈΡΡ…ΠΎΠ΄ΡΡ‰ΡƒΡŽ ΠΈ Π²Ρ…ΠΎΠ΄ΡΡ‰ΡƒΡŽ Π²Π΅Ρ€ΡˆΠΈΠ½Ρ‹.

Бписок инцидСнтности

Бписок инцидСнтности ΠΏΠΎΡ…ΠΎΠΆ Π½Π° список смСТности, Ρ‚ΠΎΠ»ΡŒΠΊΠΎ с Ρ‚ΠΎΠΉ Ρ€Π°Π·Π½ΠΈΡ†Π΅ΠΉ, Ρ‡Ρ‚ΠΎ Π² i-ΠΎΠΉ строкС Π·Π°ΠΏΠΈΡΡ‹Π²Π°ΡŽΡ‚ΡΡ Π½ΠΎΠΌΠ΅Ρ€Π° Ρ€Π΅Π±Π΅Ρ€, ΠΈΠ½Ρ†ΠΈΠ΄Π΅Π½Ρ‚Π½Ρ‹Ρ… Π΄Π°Π½Π½ΠΎΠΉ i-ΠΎΠΉ Π²Π΅Ρ€ΡˆΠΈΠ½Π΅.

Π‘Ρ€Π°Π²Π½Π΅Π½ΠΈΠ΅ структур прСдставлСния Π³Ρ€Π°Ρ„ΠΎΠ²

ΠœΠ΅Ρ‚ΠΎΠ΄ Mem Add V Add E Remove V Remove E ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° смСТн. V
ΠœΠ°Ρ‚Ρ€ΠΈΡ†Π° смСТности
(Adjacency matrix)
V^2 V^2 1 V^2 1 1
ΠœΠ°Ρ‚Ρ€ΠΈΡ†Π° инцидСнтности
(Incidence matrix)
V*E V*E V*E V*E V*E E
Бписок смСТности
(Adjacency list)
V+E 1 1 V+E E V
Бписок инцидСнтности
(Incidence list)
V+E 1 1 E E E

P vs NP

Π—Π°Π΄Π°Ρ‡ΠΈ класса P β€” Ρ€Π΅Π°Π»ΡŒΠ½ΠΎ вычислимыС Π·Π°Π΄Π°Ρ‡ΠΈ (тСзис Кобэма), Ρ€Π΅ΡˆΠ°ΡŽΡ‚ΡΡ Π·Π° полиномиальноС врСмя.
NP-ΠΏΠΎΠ»Π½Ρ‹Π΅ Π·Π°Π΄Π°Ρ‡ΠΈ β€” Π½Π΅ Ρ€Π°Π·Ρ€Π΅ΡˆΠΈΠΌΡ‹ Π·Π° полиномиальноС врСмя, Π½ΠΎ ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ свСдСны ΠΊ Π·Π°Π΄Π°Ρ‡Π°ΠΌ Ρ€Π°Π·Ρ€Π΅ΡˆΠΈΠΌΠΎΡΡ‚ΠΈ (Π΄Π°/Π½Π΅Ρ‚), ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅, Π² свою ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ, Ρ€Π΅ΡˆΠ°ΡŽΡ‚ΡΡ Π·Π° полиномиальноС врСмя.

РаздСляй ΠΈ властвуй

РаздСляй ΠΈ властвуй (divide and conquer) β€” способ Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ слоТных Π·Π°Π΄Π°Ρ‡ ΠΏΡƒΡ‚Ρ‘ΠΌ рСкурсивного разбиСния Ρ€Π΅ΡˆΠ°Π΅ΠΌΠΎΠΉ Π·Π°Π΄Π°Ρ‡ΠΈ Π½Π° Π΄Π²Π΅ ΠΈΠ»ΠΈ Π±ΠΎΠ»Π΅Π΅ ΠΏΠΎΠ΄Π·Π°Π΄Π°Ρ‡ΠΈ Ρ‚ΠΎΠ³ΠΎ ΠΆΠ΅ Ρ‚ΠΈΠΏΠ°, Π½ΠΎ мСньшСго Ρ€Π°Π·ΠΌΠ΅Ρ€Π°, ΠΈ ΠΊΠΎΠΌΠ±ΠΈΠ½ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠΈ ΠΈΡ… Ρ€Π΅ΡˆΠ΅Π½ΠΈΠΉ для получСния ΠΎΡ‚Π²Π΅Ρ‚Π° ΠΊ исходной Π·Π°Π΄Π°Ρ‡Π΅; разбиСния Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‚ΡΡ Π΄ΠΎ Ρ‚Π΅Ρ… ΠΏΠΎΡ€, ΠΏΠΎΠΊΠ° всС ΠΏΠΎΠ΄Π·Π°Π΄Π°Ρ‡ΠΈ Π½Π΅ окаТутся элСмСнтарными.

ДинамичСскоС ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅

ДинамичСскоС ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ β€” способ Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ слоТных Π·Π°Π΄Π°Ρ‡ ΠΏΡƒΡ‚Ρ‘ΠΌ разбиСния ΠΈΡ… Π½Π° Π±ΠΎΠ»Π΅Π΅ простыС ΠΏΠΎΠ΄Π·Π°Π΄Π°Ρ‡ΠΈ. Он ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΠΌ ΠΊ Π·Π°Π΄Π°Ρ‡Π°ΠΌ со структурой, выглядящСй ΠΊΠ°ΠΊ Π½Π°Π±ΠΎΡ€ ΠΏΠ΅Ρ€Π΅ΠΊΡ€Ρ‹Π²Π°ΡŽΡ‰ΠΈΡ…ΡΡ ΠΏΠΎΠ΄Π·Π°Π΄Π°Ρ‡, ΡΠ»ΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… мСньшС исходной. ΠšΠ»ΡŽΡ‡Π΅Π²Π°Ρ идСя: ΠΊΠ°ΠΊ ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Ρ€Π΅ΡˆΠΈΡ‚ΡŒ ΠΏΠΎΡΡ‚Π°Π²Π»Π΅Π½Π½ΡƒΡŽ Π·Π°Π΄Π°Ρ‡Ρƒ, трСбуСтся Ρ€Π΅ΡˆΠΈΡ‚ΡŒ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Π΅ части Π·Π°Π΄Π°Ρ‡ΠΈ (ΠΏΠΎΠ΄Π·Π°Π΄Π°Ρ‡ΠΈ), послС Ρ‡Π΅Π³ΠΎ ΠΎΠ±ΡŠΠ΅Π΄ΠΈΠ½ΠΈΡ‚ΡŒ Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ ΠΏΠΎΠ΄Π·Π°Π΄Π°Ρ‡ Π² ΠΎΠ΄Π½ΠΎ ΠΎΠ±Ρ‰Π΅Π΅ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅. Часто ΠΌΠ½ΠΎΠ³ΠΈΠ΅ ΠΈΠ· этих ΠΏΠΎΠ΄Π·Π°Π΄Π°Ρ‡ ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²Ρ‹. ΠŸΠΎΠ΄Ρ…ΠΎΠ΄ динамичСского программирования состоит Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Ρ€Π΅ΡˆΠΈΡ‚ΡŒ ΠΊΠ°ΠΆΠ΄ΡƒΡŽ ΠΏΠΎΠ΄Π·Π°Π΄Π°Ρ‡Ρƒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄ΠΈΠ½ Ρ€Π°Π·, сократив Ρ‚Π΅ΠΌ самым количСство вычислСний. Π­Ρ‚ΠΎ особСнно ΠΏΠΎΠ»Π΅Π·Π½ΠΎ Π² случаях, ΠΊΠΎΠ³Π΄Π° число ΠΏΠΎΠ²Ρ‚ΠΎΡ€ΡΡŽΡ‰ΠΈΡ…ΡΡ ΠΏΠΎΠ΄Π·Π°Π΄Π°Ρ‡ ΡΠΊΡΠΏΠΎΠ½Π΅Π½Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎ Π²Π΅Π»ΠΈΠΊΠΎ.Ρ‹

Π–Π°Π΄Π½Ρ‹Π΅ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΡ‹

Π–Π°Π΄Π½Ρ‹ΠΉ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ (greedy algorithm) β€” Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π½Π° ΠΊΠ°ΠΆΠ΄ΠΎΠΌ ΡˆΠ°Π³Ρƒ Π΄Π΅Π»Π°Π΅Ρ‚ локально Π½Π°ΠΈΠ»ΡƒΡ‡ΡˆΠΈΠΉ Π²Ρ‹Π±ΠΎΡ€ Π² Π½Π°Π΄Π΅ΠΆΠ΄Π΅, Ρ‡Ρ‚ΠΎ ΠΈΡ‚ΠΎΠ³ΠΎΠ²ΠΎΠ΅ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΠΏΡ‚ΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΌ.

Как ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ, даст Π»ΠΈ ΠΆΠ°Π΄Π½Ρ‹ΠΉ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ ΠΎΠΏΡ‚ΠΈΠΌΠ°Π»ΡŒΠ½ΠΎΠ΅ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅? Π’ соотвСтствии с Ρ‚Π΅ΠΎΡ€Π΅ΠΌΠΎΠΉ Π Π°Π΄ΠΎ-Эдмондса, Ссли систСма являСтся ΠΌΠ°Ρ‚Ρ€ΠΎΠΈΠ΄ΠΎΠΌ, Ρ‚ΠΎ для ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»ΡŒΠ½ΠΎΠΉ вСсовой Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π³Ρ€Π°Π΄ΠΈΠ΅Π½Ρ‚Π½Ρ‹ΠΉ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ всСгда Π½Π°Ρ…ΠΎΠ΄ΠΈΡ‚ Ρ‚ΠΎΡ‡Π½ΠΎΠ΅ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ Π·Π°Π΄Π°Ρ‡ΠΈ. Π‘Π»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ, Ссли Π΄ΠΎΠΊΠ°Π·Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ являСтся ΠΌΠ°Ρ‚Ρ€ΠΎΠΈΠ΄ΠΎΠΌ, Ρ‚ΠΎ ΠΆΠ°Π΄Π½Ρ‹ΠΉ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹Π΄Π°Π²Π°Ρ‚ΡŒ ΠΎΠΏΡ‚ΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΉ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚.

Π–Π°Π΄Π½Ρ‹Π΅ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΡ‹ ΠΏΡ€ΠΎΡ‰Π΅ ΠΈ быстрСС Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΠΎΠ² Π½Π° Π±Π°Π·Π΅ динамичСского программирования.

Π Π°Π·Π»ΠΈΡ‡ΠΈΠ΅ ΠΌΠ΅ΠΆΠ΄Π΅ ΠΆΠ°Π΄Π½Ρ‹ΠΌΠΈ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΠ°ΠΌΠΈ ΠΈ динамичСским ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΡΡΠ½ΠΈΡ‚ΡŒ Ρ‚Π°ΠΊ: Π½Π° ΠΊΠ°ΠΆΠ΄ΠΎΠΌ шагС ΠΆΠ°Π΄Π½Ρ‹ΠΉ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ Π±Π΅Ρ€Π΅Ρ‚ "самый ΠΆΠΈΡ€Π½Ρ‹ΠΉ кусок", Π° ΠΏΠΎΡ‚ΠΎΠΌ ΡƒΠΆΠ΅ пытаСтся ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Π½Π°ΠΈΠ»ΡƒΡ‡ΡˆΠΈΠΉ Π²Ρ‹Π±ΠΎΡ€ срСди ΠΎΡΡ‚Π°Π²ΡˆΠΈΡ…ΡΡ, ΠΊΠ°ΠΊΠΎΠ²Ρ‹ Π±Ρ‹ ΠΎΠ½ΠΈ Π½ΠΈ Π±Ρ‹Π»ΠΈ; Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ динамичСского программирования ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅, просчитав Π·Π°Ρ€Π°Π½Π΅Π΅ послСдствия для всСх Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ΠΎΠ².

РСкурсия

РСкурсия – ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Ρ‡Π΅Ρ€Π΅Π· саму сСбя. Π›ΠΎΠ³ΠΈΠΊΠ° рСкурсивной Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΊΠ°ΠΊ ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ состоит ΠΈΠ· Π΄Π²ΡƒΡ… Π²Π΅Ρ‚Π²Π΅ΠΉ. Длинная Π²Π΅Ρ‚Π²ΡŒ Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ эту ΠΆΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ с Π΄Ρ€ΡƒΠ³ΠΈΠΌΠΈ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°ΠΌΠΈ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π½Π°ΠΊΠΎΠΏΠΈΡ‚ΡŒ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚. ΠšΠΎΡ€ΠΎΡ‚ΠΊΠ°Ρ Π²Π΅Ρ‚Π²ΡŒ опрСдСляСт ΠΊΡ€ΠΈΡ‚Π΅Ρ€ΠΈΠΉ Π²Ρ‹Ρ…ΠΎΠ΄Π° ΠΈΠ· рСкурсии.

РСкурсия ΡƒΠΏΡ€ΠΎΡ‰Π°Π΅Ρ‚ ΠΊΠΎΠ΄ ΠΈ Π΄Π΅Π»Π°Π΅Ρ‚ Π΅Π³ΠΎ Π΄Π΅ΠΊΠ»Π°Ρ€Π°Ρ‚ΠΈΠ²Π½Ρ‹ΠΌ. РСкурсия поощряСт ΠΌΡ‹ΡΠ»ΠΈΡ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎ ΠΈ ΠΈΠ·Π±Π΅Π³Π°Ρ‚ΡŒ ΠΏΠΎΠ±ΠΎΡ‡Π½Ρ‹Ρ… эффСктов.

НСоптимизированная рСкурсия ΠΏΡ€ΠΈΠ²ΠΎΠ΄ΠΈΡ‚ ΠΊ Π½Π°ΠΊΠ»Π°Π΄Π½Ρ‹ΠΌ расходам рСсурсов. ΠŸΡ€ΠΈ большом количСствС ΠΈΡ‚Π΅Ρ€Π°Ρ†ΠΈΠΉ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡ€Π΅Π²Ρ‹ΡΠΈΡ‚ΡŒ Π»ΠΈΠΌΠΈΡ‚ Π½Π° число рСкурсивных Π²Ρ‹Π·ΠΎΠ²ΠΎΠ² (recursion depth limit reached).

Π₯востовая рСкурсия

ΠžΡΠΎΠ±Ρ‹ΠΉ Π²ΠΈΠ΄ рСкурсии, ΠΊΠΎΠ³Π΄Π° функция заканчиваСтся Π²Ρ‹Π·ΠΎΠ²ΠΎΠΌ самой сСбя Π±Π΅Π· Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠ². Когда это условиС выполняСтся, компилятор Ρ€Π°Π·Π²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅Ρ‚ Ρ€Π΅ΠΊΡƒΡ€ΡΠΈΡŽ Π² Ρ†ΠΈΠΊΠ» с ΠΎΠ΄Π½ΠΈΠΌ стСк-Ρ„Ρ€Π΅ΠΉΠΌΠΎΠΌ, просто мСняя Π»ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹Π΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ ΠΎΡ‚ ΠΈΡ‚Π΅Ρ€Π°Ρ†ΠΈΠΈ ΠΊ ΠΈΡ‚Π΅Ρ€Π°Ρ†ΠΈΠΈ.

Π’Π°ΠΊ, классичСскоС ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ рСкурсивного Ρ„Π°ΠΊΡ‚ΠΎΡ€ΠΈΠ°Π»Π° return N * fact(N - 1) Π½Π΅ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ Ρ…Π²ΠΎΡΡ‚ΠΎΠ²ΡƒΡŽ Ρ€Π΅ΠΊΡƒΡ€ΡΠΈΡŽ, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ стСк-Ρ„Ρ€Π΅ΠΉΠΌΠ° придСтся Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒ Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ N.

Π§Ρ‚ΠΎΠ±Ρ‹ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ рСкурсии хвостовой, Π΄ΠΎΠ±Π°Π²Π»ΡΡŽΡ‚ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹-аккумуляторы. Благодаря ΠΈΠΌ функция Π·Π½Π°Π΅Ρ‚ ΠΎ своСм Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΌ состоянии. ΠŸΡƒΡΡ‚ΡŒ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ acc ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ Ρ€Π°Π²Π΅Π½ 1. Π’ΠΎΠ³Π΄Π° запись с хвостовой рСкурсиСй Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹Π³Π»ΡΠ΄Π΅Ρ‚ΡŒ Ρ‚Π°ΠΊ:

def fact(N, acc=1):
    if N == 1:
        return acc
    else:
        return fact(N - 1, acc * N)

Π‘Π°ΠΌΡ‹Π΅ распространСнныС ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ Π·Π°Π΄Π°Ρ‡ Leetcode

  1. ΠœΠ΅Ρ‚ΠΎΠ΄ ΡΠΊΠΎΠ»ΡŒΠ·ΡΡ‰Π΅Π³ΠΎ ΠΎΠΊΠ½Π° (Sliding Window)
  2. ΠœΠ΅Ρ‚ΠΎΠ΄ Π΄Π²ΡƒΡ… ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΉ (Two Pointers)
  3. НахоТдСниС Ρ†ΠΈΠΊΠ»Π° (Fast & Slow Pointers)
  4. Π˜Π½Ρ‚Π΅Ρ€Π²Π°Π»ΡŒΠ½ΠΎΠ΅ слияниС (Merge Intervals)
  5. Цикличная сортировка (Cyclic Sort)
  6. In-place Reversal для LinkedList (In-place Reversal of a LinkedList)
  7. Поиск Π² ΡˆΠΈΡ€ΠΈΠ½Ρƒ (Tree Breadth-First Search)
  8. Поиск Π² Π³Π»ΡƒΠ±ΠΈΠ½Ρƒ (Tree Depth First Search)
  9. Π”Π²Π΅ ΠΊΡƒΡ‡ΠΈ (Two Heaps)
  10. ΠŸΠΎΠ΄ΠΌΠ½ΠΎΠΆΠ΅ΡΡ‚Π²Π° (Subsets)
  11. ΠœΠΎΠ΄ΠΈΡ„ΠΈΡ†ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ Π±ΠΈΠ½Π°Ρ€Π½Ρ‹ΠΉ поиск (Modified Binary Search)
  12. ΠŸΠΎΠ±ΠΈΡ‚ΠΎΠ²ΠΎΠ΅ ΠΈΡΠΊΠ»ΡŽΡ‡Π°ΡŽΡ‰Π΅Π΅ Π˜Π›Π˜ (Bitwise XOR)
  13. НаибольшиС K элСмСнтов (Top K Elements)
  14. K-ΠΎΠ±Ρ€Π°Π·Π½ΠΎΠ΅ слияниС (K-way Merge)
  15. Π—Π°Π΄Π°Ρ‡Π° ΠΎ Ρ€ΡŽΠΊΠ·Π°ΠΊΠ΅ 0-1 (0/1 Knapsack)
  16. Π—Π°Π΄Π°Ρ‡Π° ΠΎ Π½Π΅ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½Π½ΠΎΠΌ Ρ€ΡŽΠΊΠ·Π°ΠΊΠ΅ (Unbounded Knapsack)
  17. Числа Π€ΠΈΠ±ΠΎΠ½Π°Ρ‡Ρ‡ΠΈ (Fibonacci Numbers)
  18. Наибольшая ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ-ΠΏΠ°Π»ΠΈΠ½Π΄Ρ€ΠΎΠΌ (Palindromic Subsequence)
  19. Наибольшая общая подстрока (Longest Common Substring)
  20. ВопологичСская сортировка (Topological Sort)
  21. Π§Ρ‚Π΅Π½ΠΈΠ΅ прСфиксного Π΄Π΅Ρ€Π΅Π²Π° (Trie Traversal)
  22. ΠšΠΎΠ»ΠΈΡ‡Π΅ΡΡ‚Π²ΠΎ островов Π² ΠΌΠ°Ρ‚Ρ€ΠΈΡ†Π΅ (Number of Island)
  23. ΠœΠ΅Ρ‚ΠΎΠ΄ ΠΏΡ€ΠΎΠ± ΠΈ ошибок (Trial & Error)
  24. БистСма Π½Π΅ΠΏΠ΅Ρ€Π΅ΡΠ΅ΠΊΠ°ΡŽΡ‰ΠΈΡ…ΡΡ мноТСств (Union Find)
  25. Π—Π°Π΄Π°Ρ‡Π°: Π½Π°ΠΉΡ‚ΠΈ ΡƒΠ½ΠΈΠΊΠ°Π»ΡŒΠ½Ρ‹Π΅ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Ρ‹ (Unique Paths)

9. Π‘Π°Π·Ρ‹ Π΄Π°Π½Π½Ρ‹Ρ…

Β«Π—Π΄Π΅ΡΡŒ Π±Ρ‹Π» большой Ρ‚Ρ€Π°ΠΏΠ΅Π·Π½Ρ‹ΠΉ стол, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ стояли Π·ΠΎΠ»ΠΎΡ‚Ρ‹Π΅ сосуды, вСсьма Π΄ΠΎΡ€ΠΎΠ³ΠΈΠ΅. Π’ сосудах этих Π½Π°Ρ…ΠΎΠ΄ΠΈΠ»ΠΈΡΡŒ ΠΎΠ²ΠΎΡ‰ΠΈ Ρ€Π°Π·Π½Ρ‹Ρ… сортов, ΠΎΡ‚ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… исходили Ρ‡ΡƒΠ΄Π½Ρ‹Π΅ благоухания».

Β«Π’ΠΈΠ΄Π΅Π½ΠΈΠ΅ Григория».

Database

РСляционная модСль Π΄Π°Π½Π½Ρ‹Ρ…

РСляционная модСль Π΄Π°Π½Π½Ρ‹Ρ… (Π ΠœΠ”) основана Π½Π° матСматичСском понятии ΠΎΡ‚Π½ΠΎΡˆΠ΅Π½ΠΈΡ (relation), ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π½Π΅Ρ„ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½ΠΎ ΠΌΠΎΠΆΠ½ΠΎ Ρ‚ΠΎΠ»ΠΊΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠ°ΠΊ "Ρ‚Π°Π±Π»ΠΈΡ†Π°". БоотвСтствСнно, Ρ€Π΅Π»ΡΡ†ΠΈΠΎΠ½Π½ΡƒΡŽ модСль Π΄Π°Π½Π½Ρ‹Ρ… ΠΌΠΎΠΆΠ½ΠΎ ΡƒΠΏΡ€ΠΎΡ‰Π΅Π½Π½ΠΎ Π²ΠΎΡΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Ρ‚ΡŒ ΠΊΠ°ΠΊ "Ρ‚Π°Π±Π»ΠΈΡ‡Π½ΡƒΡŽ модСль Π΄Π°Π½Π½Ρ‹Ρ…", Ρ‚. Π΅. ΠΏΠΎΡΡ‚Ρ€ΠΎΠ΅Π½Π½ΡƒΡŽ Π½Π° основС Π΄Π²ΡƒΠΌΠ΅Ρ€Π½Ρ‹Ρ… Ρ‚Π°Π±Π»ΠΈΡ†, состоящих ΠΈΠ· строк ΠΈ столбцов.

Работая с рСляционной Π‘Π”, программисту Π½Π΅ Π½ΡƒΠΆΠ½ΠΎ Π·Π°Π±ΠΎΡ‚ΠΈΡ‚ΡŒΡΡ ΠΎ Π½ΠΈΠ·ΠΊΠΎΡƒΡ€ΠΎΠ²Π½Π΅Π²ΠΎΠΌ доступС ΠΊ Π΄Π°Π½Π½Ρ‹ΠΌ, достаточно ΠΎΠΏΠΈΡΠ°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ Π½ΡƒΠΆΠ½ΠΎ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ, Π° ΠΊΠ°ΠΊ ΠΈΠΌΠ΅Π½Π½ΠΎ β€” ΠΎΠΏΠΈΡΡ‹Π²Π°Ρ‚ΡŒ Π½Π΅ Π½ΡƒΠΆΠ½ΠΎ, эту Ρ€Π°Π±ΠΎΡ‚Ρƒ Π±Π΅Ρ€Π΅Ρ‚ Π½Π° сСбя Π‘Π”.

ΠžΡ‚ΡΡƒΡ‚ΡΡ‚Π²ΠΈΠ΅ Π½ΠΈΠ·ΠΊΠΎΡƒΡ€ΠΎΠ²Π½Π΅Π²ΠΎΠ³ΠΎ доступа β€” сильноС ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠ΅, ΠΏΠΎΡ€ΠΎΠΆΠ΄Π°ΡŽΡ‰Π΅Π΅ удобство использования Π‘Π” (ΠΎ ΠΏΠ»ΡŽΡΠ°Ρ… ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠΉ ΠΌΡ‹ ΠΏΠΎΠ³ΠΎΠ²ΠΎΡ€ΠΈΠΌ Ρ‡ΡƒΡ‚ΡŒ ΠΏΠΎΠ·ΠΆΠ΅, Π² Ρ€Π°Π·Π΄Π΅Π»Π΅ «АрхитСктура»). Но это ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠ΅ Π±ΡƒΠΊΠ²Π°Π»ΡŒΠ½ΠΎ Β«Π»ΠΎΠΌΠ°Π΅Ρ‚ ΠΌΠΎΠ·Π³Β» программисту, Π½Π΅ ΠΈΠΌΠ΅Π²ΡˆΠ΅ΠΌΡƒ Π΄ΠΎ этого Π΄Π΅Π»Π° с Π΄Π΅ΠΊΠ»Π°Ρ€Π°Ρ‚ΠΈΠ²Π½Ρ‹ΠΌΠΈ языками программирования.

Когда программист, Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‰ΠΈΠΉ Π² ΠΈΠΌΠΏΠ΅Ρ€Π°Ρ‚ΠΈΠ²Π½ΠΎΠΉ ΠΏΠ°Ρ€Π°Π΄ΠΈΠ³ΠΌΠ΅, пытаСтся Ρ€Π΅ΡˆΠΈΡ‚ΡŒ SQL-Π·Π°Π΄Π°Ρ‡Ρƒ, Ρ€ΡƒΠΊΠΈ сами тянутся ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΡ‚ΡŒ ΠΏΡ€ΠΈΠ²Ρ‹Ρ‡Π½Ρ‹ΠΉ Π½Π°Π±ΠΎΡ€ инструмСнтов. Β«Π’Π°ΠΊ, проходимся ΠΏΠΎ Ρ‚Π°Π±Π»ΠΈΡ†Π΅ Π² Ρ†ΠΈΠΊΠ»Π΅, отсСянныС значСния складываСм Π²ΠΎ Π²Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ, ΠΏΠΎΡ‚ΠΎΠΌ Ρ„ΠΎΡ€ΠΌΠΈΡ€ΡƒΠ΅ΠΌ ΠΎΡ‚Π²Π΅Ρ‚Β», Π½ΠΎ β€” SQL ΠΏΡ€Π΅Π΄Π»Π°Π³Π°Π΅Ρ‚ совсСм Π΄Ρ€ΡƒΠ³ΠΎΠΉ, Π½Π΅ΠΏΡ€ΠΈΠ²Ρ‹Ρ‡Π½Ρ‹ΠΉ Π½Π°Π±ΠΎΡ€ инструмСнтов: Β«Π‘ΠΊΠ°ΠΆΠΈ, Ρ‡Ρ‚ΠΎ Ρ‚Ρ‹ Ρ…ΠΎΡ‡Π΅ΡˆΡŒ, Π° ΠΎ дСталях я ΠΏΠΎΠ·Π°Π±ΠΎΡ‡ΡƒΡΡŒ сам».

Если Ρ‚Π°ΠΊΠΎΠΉ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ для вас Π²Π½ΠΎΠ²Π΅, Π½Π΅ ΠΎΡ‚Ρ‡Π°ΠΈΠ²Π°ΠΉΡ‚Π΅ΡΡŒ; Π”ΠΆΠΎ Π‘Π΅Π»ΠΊΠΎ Π² своСй ΠΊΠ½ΠΈΠ³Π΅ Β«Thinking in SetsΒ» сразу Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡƒΠ΅Ρ‚ Π³ΠΎΡ‚ΠΎΠ²ΠΈΡ‚ΡŒΡΡ ΠΊ Π΄Π»ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠΉ пСрСстройкС процСсса ΠΌΡ‹ΡˆΠ»Π΅Π½ΠΈΡ: Β«Π― ΠΎΡ€ΠΈΠ΅Π½Ρ‚ΠΈΡ€ΡƒΡŽ студСнтов Π½Π° срок ΠΎΠΊΠΎΠ»ΠΎ Π³ΠΎΠ΄Π°, ΠΏΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ посвящСнного ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡŽ Π½Π° SQL, Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‚ΠΎΠ³Π΄Π° вас ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΡΠ΅Ρ‚ΠΈΡ‚ΡŒ ΠΏΡ€ΠΎΠ·Ρ€Π΅Π½ΠΈΠ΅ ΠΈ Π²Ρ‹ Π½Π°Ρ‡Π½Π΅Ρ‚Π΅ Π΄ΡƒΠΌΠ°Ρ‚ΡŒ Π½Π° языкС SQLΒ» (Β«I have been telling students that you need about one year of full-time SQL programming before you have an epiphany and start thinking in SQLΒ»).

Π’Π°ΠΊ Ρ‡Ρ‚ΠΎ ΠΏΠΎΡ‚ΠΈΡ…ΠΎΠ½ΡŒΠΊΡƒ ΠΈΠ·Π±Π°Π²Π»ΡΠΉΡ‚Π΅ΡΡŒ ΠΎΡ‚ своСго (ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ°ΡŽ Ρ†ΠΈΡ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠ½ΠΈΠ³Ρƒ Π‘Π΅Π»ΠΊΠΎ) Β«procedural programming mindsetΒ», ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΏΡ€ΠΈΠ²ΠΎΠ΄ΠΈΡ‚ ΠΊ Β«overly complex and inefficient codeΒ», ΠΈ Β«change the way you think about the problems you solve with SQL programsΒ». Или, ΠΏΠΎ простому, ΠΊΠ°ΠΊ ΡΠΎΠ²Π΅Ρ‚ΡƒΡŽΡ‚ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΠΈ Stackoverflow Π² этом Ρ‚ΠΎΠΏΠΈΠΊΠ΅, Β«ΠΏΡ€Π΅ΠΊΡ€Π°Ρ‚ΠΈΡ‚Π΅ Π΄ΡƒΠΌΠ°Ρ‚ΡŒ ΠΎ построчной ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ΅, ΠΏΠΎΠ΄ΡƒΠΌΠ°ΠΉΡ‚Π΅ Π½Π°Π΄ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ΠΌ Π·Π°Π΄Π°Ρ‡ΠΈ, основанном Π½Π° Ρ€Π°Π±ΠΎΡ‚Π΅ со мноТСствами».

The key thing is you're manipulating SETS & elements of sets; and relating different sets (and corresponding elements) together. That's really the heart of it, imho. That's why every table should have a primary key; why you see set operators in the language; and why set operators like UNION won't (by defualt) return duplicate rows.
Of course in practice, the rules of sets are bent or broken but it's not that hard to see when this is necessary (otherwise, SQL would be TOO limited). Imho, just crack open your discrete math book and reacquaint yourself with some set exercises.

Вранзакция

Вранзакция β€” нСдСлимая ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ дСйствий (атомарная опСрация, Π³Ρ€ΡƒΠΏΠΏΠ° ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‚ΡΡ ΠΊΠ°ΠΊ Π΅Π΄ΠΈΠ½ΠΎΠ΅ Ρ†Π΅Π»ΠΎΠ΅), обСспСчиваСт Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ Π»ΠΈΠ±ΠΎ всСх дСйствий ΠΈΠ· ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ, Π»ΠΈΠ±ΠΎ Π½ΠΈ ΠΎΠ΄Π½ΠΎΠ³ΠΎ. Если Π² Ρ…ΠΎΠ΄Π΅ выполнСния Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ ΠΏΡ€ΠΎΠΈΠ·ΠΎΡˆΠ΅Π» сбой, состояниС систСмы Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π±Ρ‹Ρ‚ΡŒ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π΅Π½ΠΎ ΠΊ исходному, ΡƒΠΆΠ΅ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½Π½Ρ‹Π΅ дСйствия Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ ΠΎΡ‚ΠΌΠ΅Π½Π΅Π½Ρ‹.

ΠšΠ°Π½ΠΎΠ½ΠΈΡ‡Π΅ΡΠΊΠΈΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ β€” списываниС Π΄Π΅Π½Π΅Π³ с ΠΎΠ΄Π½ΠΎΠ³ΠΎ счСта ΠΈ зачислСниС Π½Π° Π΄Ρ€ΡƒΠ³ΠΎΠΉ, для Ρ‡Π΅Π³ΠΎ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹ Π΄Π²Π° процСсса провСдСния ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒΡΡ ΠΈΠ»ΠΈ Π½Π΅ Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒΡΡ вмСстС.

Π’ частном случаС Π² Π³Ρ€ΡƒΠΏΠΏΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΎΠ΄Π½Π° опСрация.

Вранзакция начинаСтся с ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ BEGIN ΠΈ заканчиваСтся ΠΊΠΎΠΌΠ°Π½Π΄ΠΎΠΉ COMMIT Π»ΠΈΠ±ΠΎ отмСняСтся ΠΊΠΎΠΌΠ°Π½Π΄ΠΎΠΉ ROLLBACK (здСсь ΠΈ Π΄Π°Π»Π΅Π΅, Ссли Π½Π΅ ΡƒΠΊΠ°Π·Π°Π½ΠΎ ΠΈΠ½ΠΎΠ΅, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ синтаксис PostgreSQL).

ACID

Π’Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΎΠ±Π»Π°Π΄Π°Ρ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌΠΈ свойствами:

  1. ΠΡ‚ΠΎΠΌΠ°Ρ€Π½ΠΎΡΡ‚ΡŒ (atomicity). Π­Ρ‚ΠΎ свойство ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ Π»ΠΈΠ±ΠΎ транзакция Π±ΡƒΠ΄Π΅Ρ‚ зафиксирована Π² Π±Π°Π·Π΅ Π΄Π°Π½Π½Ρ‹Ρ… ΠΏΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ, Ρ‚. Π΅. Π±ΡƒΠ΄ΡƒΡ‚ зафиксированы Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹ выполнСния всСх Π΅Π΅ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ, Π»ΠΈΠ±ΠΎ Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ зафиксирована Π½ΠΈ ΠΎΠ΄Π½Π° опСрация Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ.

  2. Π‘ΠΎΠ³Π»Π°ΡΠΎΠ²Π°Π½Π½ΠΎΡΡ‚ΡŒ (consistency). Π­Ρ‚ΠΎ свойство прСдписываСт, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π² Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎΠ³ΠΎ выполнСния Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ Π±Π°Π·Π° Π΄Π°Π½Π½Ρ‹Ρ… Π±Ρ‹Π»Π° ΠΏΠ΅Ρ€Π΅Π²Π΅Π΄Π΅Π½Π° ΠΈΠ· ΠΎΠ΄Π½ΠΎΠ³ΠΎ консистСнтного состояния Π² Π΄Ρ€ΡƒΠ³ΠΎΠ΅ консистСнтноС состояниС.

  3. Π˜Π·ΠΎΠ»ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΡΡ‚ΡŒ (isolation). Π’ΠΎ врСмя выполнСния Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΎΠΊΠ°Π·Ρ‹Π²Π°Ρ‚ΡŒ ΠΏΠΎ возмоТности минимальноС влияниС Π½Π° Π½Π΅Π΅.

  4. Π”ΠΎΠ»Π³ΠΎΠ²Π΅Ρ‡Π½ΠΎΡΡ‚ΡŒ (durability). ПослС ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎΠΉ фиксации Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ ΡƒΠ²Π΅Ρ€Π΅Π½, Ρ‡Ρ‚ΠΎ Π΄Π°Π½Π½Ρ‹Π΅ Π½Π°Π΄Π΅ΠΆΠ½ΠΎ сохранСны Π² Π±Π°Π·Π΅ Π΄Π°Π½Π½Ρ‹Ρ… ΠΈ впослСдствии ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ ΠΈΠ·Π²Π»Π΅Ρ‡Π΅Π½Ρ‹ ΠΈΠ· Π½Π΅Π΅, нСзависимо ΠΎΡ‚ ΠΏΠΎΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΡ… Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Ρ… сбоСв Π² Ρ€Π°Π±ΠΎΡ‚Π΅ систСмы.

Для обозначСния всСх этих Ρ‡Π΅Ρ‚Ρ‹Ρ€Π΅Ρ… свойств ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ Π°Π±Π±Ρ€Π΅Π²ΠΈΠ°Ρ‚ΡƒΡ€Π° ACID.

ΠŸΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹ ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ доступа с использованиСм Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΉ

Π’Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»Π½ΡΡ‚ΡŒ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ ΠΈΠ»ΠΈ ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½ΠΎ. И Ссли Π² ΠΏΠ΅Ρ€Π²ΠΎΠΌ случаС всС понятно ΠΈ прСдсказуСмо, Ρ‚ΠΎ Π² случаС ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ исполнСния Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΉ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹:

Π€Π°Π½Ρ‚ΠΎΠΌΠ½ΠΎΠ΅ Ρ‡Ρ‚Π΅Π½ΠΈΠ΅ (phantom reads) β€” ΠΎΠ΄Π½Π° транзакция Π² Ρ…ΠΎΠ΄Π΅ своСго выполнСния нСсколько Ρ€Π°Π· Π²Ρ‹Π±ΠΈΡ€Π°Π΅Ρ‚ мноТСство строк ΠΏΠΎ ΠΎΠ΄Π½ΠΈΠΌ ΠΈ Ρ‚Π΅ΠΌ ΠΆΠ΅ критСриям. Другая транзакция Π² ΠΈΠ½Ρ‚Π΅Ρ€Π²Π°Π»Π°Ρ… ΠΌΠ΅ΠΆΠ΄Ρƒ этими Π²Ρ‹Π±ΠΎΡ€ΠΊΠ°ΠΌΠΈ добавляСт строки ΠΈΠ»ΠΈ измСняСт столбцы Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… строк, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹Ρ… Π² критСриях Π²Ρ‹Π±ΠΎΡ€ΠΊΠΈ ΠΏΠ΅Ρ€Π²ΠΎΠΉ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ, ΠΈ ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ заканчиваСтся. Π’ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ получится, Ρ‡Ρ‚ΠΎ ΠΎΠ΄Π½ΠΈ ΠΈ Ρ‚Π΅ ΠΆΠ΅ Π²Ρ‹Π±ΠΎΡ€ΠΊΠΈ Π² ΠΏΠ΅Ρ€Π²ΠΎΠΉ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ Π΄Π°ΡŽΡ‚ Ρ€Π°Π·Π½Ρ‹Π΅ мноТСства строк.

ΠΠ΅ΠΏΠΎΠ²Ρ‚ΠΎΡ€ΡΡŽΡ‰Π΅Π΅ΡΡ Ρ‡Ρ‚Π΅Π½ΠΈΠ΅ (non-repeatable read) β€” ΠΏΡ€ΠΈ ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎΠΌ Ρ‡Ρ‚Π΅Π½ΠΈΠΈ Π² Ρ€Π°ΠΌΠΊΠ°Ρ… ΠΎΠ΄Π½ΠΎΠΉ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ Ρ€Π°Π½Π΅Π΅ ΠΏΡ€ΠΎΡ‡ΠΈΡ‚Π°Π½Π½Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅ ΠΎΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‚ΡΡ ΠΈΠ·ΠΌΠ΅Π½Ρ‘Π½Π½Ρ‹ΠΌΠΈ.

«ГрязноС» Ρ‡Ρ‚Π΅Π½ΠΈΠ΅ (dirty read) β€” Ρ‡Ρ‚Π΅Π½ΠΈΠ΅ Π΄Π°Π½Π½Ρ‹Ρ…, Π΄ΠΎΠ±Π°Π²Π»Π΅Π½Π½Ρ‹Ρ… ΠΈΠ»ΠΈ ΠΈΠ·ΠΌΠ΅Π½Ρ‘Π½Π½Ρ‹Ρ… Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠ΅ΠΉ, которая впослСдствии Π½Π΅ подтвСрдится (откатится);

ΠŸΠΎΡ‚Π΅Ρ€ΡΠ½Π½ΠΎΠ΅ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅ (lost update) β€” ΠΏΡ€ΠΈ ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΌ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΈ ΠΎΠ΄Π½ΠΎΠ³ΠΎ Π±Π»ΠΎΠΊΠ° Π΄Π°Π½Π½Ρ‹Ρ… Ρ€Π°Π·Π½Ρ‹ΠΌΠΈ транзакциями Ρ‚Π΅Ρ€ΡΡŽΡ‚ΡΡ всС измСнСния, ΠΊΡ€ΠΎΠΌΠ΅ послСднСго.

Аномалия сСриализации (serialization anomaly) β€” Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ фиксации Π³Ρ€ΡƒΠΏΠΏΡ‹ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΉ, Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‰ΠΈΡ…ΡΡ ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½ΠΎ, Π½Π΅ совпадаСт с Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠΌ Π½ΠΈ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΈΠ· Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Ρ… Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ΠΎΠ² упорядочСния этих Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΉ, Ссли Π±Ρ‹ ΠΎΠ½ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΠ»ΠΈΡΡŒ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ.

  1. Π§Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠ΅ аномалия сСриализации? Для Π΄Π²ΡƒΡ… Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΉ, скаТСм, A ΠΈ B, Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π΄Π²Π° Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Π° упорядочСния ΠΏΡ€ΠΈ ΠΈΡ… ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠΌ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ:

1️. сначала A, Π·Π°Ρ‚Π΅ΠΌ B.

2️. сначала B, Π·Π°Ρ‚Π΅ΠΌ A.

ΠŸΡ€ΠΈΡ‡Π΅ΠΌ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ Π΄Π²ΡƒΡ… Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ΠΎΠ² ΠΌΠΎΠ³ΡƒΡ‚ Π² ΠΎΠ±Ρ‰Π΅ΠΌ случаС Π½Π΅ ΡΠΎΠ²ΠΏΠ°Π΄Π°Ρ‚ΡŒ.

НапримСр, ΠΏΡ€ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ Π΄Π²ΡƒΡ… банковских ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ β€” внСсСния Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ суммы Π΄Π΅Π½Π΅Π³ Π½Π° счСт ΠΈ начислСния ΠΏΡ€ΠΎΡ†Π΅Π½Ρ‚ΠΎΠ² ΠΏΠΎ этому счСту β€” Π²Π°ΠΆΠ΅Π½ порядок выполнСния ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ.

Если ΠΈΠ·Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎ Π½Π° счСтС Π±Ρ‹Π»ΠΎ $1000 ΠΈ ΠΏΠ΅Ρ€Π²ΠΎΠΉ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠ΅ΠΉ Π±ΡƒΠ΄Π΅Ρ‚ ΡƒΠ²Π΅Π»ΠΈΡ‡Π΅Π½ΠΈΠ΅ суммы Π½Π° $1000, Π° Π²Ρ‚ΠΎΡ€ΠΎΠΉ β€” начислСниС ΠΏΡ€ΠΎΡ†Π΅Π½Ρ‚ΠΎΠ² (10%), Ρ‚ΠΎ Ρ‚ΠΎΠ³Π΄Π° итоговая сумма Π±ΡƒΠ΄Π΅Ρ‚ большС ($2200), Ρ‡Π΅ΠΌ ΠΏΡ€ΠΈ ΠΏΡ€ΠΎΡ‚ΠΈΠ²ΠΎΠΏΠΎΠ»ΠΎΠΆΠ½ΠΎΠΌ порядкС выполнСния этих ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ ($2100).

Если описанныС ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‚ΡΡ Π² Ρ€Π°ΠΌΠΊΠ°Ρ… Π΄Π²ΡƒΡ… Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Ρ… Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΉ, Ρ‚ΠΎ ΠΎΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‚ΡΡ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹ΠΌΠΈ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Π΅ ΠΈΡ‚ΠΎΠ³ΠΎΠ²Ρ‹Π΅ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹, зависящиС ΠΎΡ‚ порядка ΠΈΡ… выполнСния.

БСриализация Π΄Π²ΡƒΡ… Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΉ ΠΏΡ€ΠΈ ΠΈΡ… ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½ΠΎΠΌ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½Ρ‹ΠΉ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ Π±ΡƒΠ΄Π΅Ρ‚ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΠ΄Π½ΠΎΠΌΡƒ ΠΈΠ· Π΄Π²ΡƒΡ… Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Ρ… Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ΠΎΠ² упорядочСния Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΉ ΠΏΡ€ΠΈ ΠΈΡ… ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠΌ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ. Π’ΠΎ Π΅ΡΡ‚ΡŒ ΠΌΡ‹ Π·Π½Π°Π΅ΠΌ, Ρ‡Ρ‚ΠΎ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Π»ΠΈΠ±ΠΎ $2100 Π»ΠΈΠ±ΠΎ $2200 - ΠΈ Π½ΠΈΠΊΠ°ΠΊ ΠΈΠ½Π°Ρ‡Π΅. БоотвСтствСнно, аномалия сСриализации β€” отсутствиС соотвСтствия Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π° Π½ΠΈ ΠΎΠ΄Π½ΠΎΠΌΡƒ ΠΈΠ· Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Ρ… Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ΠΎΠ².

ΠŸΡ€ΠΈ этом нСльзя ΡΠΊΠ°Π·Π°Ρ‚ΡŒ Ρ‚ΠΎΡ‡Π½ΠΎ, ΠΊΠ°ΠΊΠΎΠΉ ΠΈΠ· Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ΠΎΠ² Π±ΡƒΠ΄Π΅Ρ‚ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½.

Если Ρ€Π°ΡΠΏΡ€ΠΎΡΡ‚Ρ€Π°Π½ΠΈΡ‚ΡŒ эти рассуТдСния Π½Π° случай, ΠΊΠΎΠ³Π΄Π° ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½ΠΎ выполняСтся Π±ΠΎΠ»Π΅Π΅ Π΄Π²ΡƒΡ… Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΉ, Ρ‚ΠΎΠ³Π΄Π° Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ ΠΈΡ… ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ выполнСния Ρ‚Π°ΠΊΠΆΠ΅ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ Ρ‚Π°ΠΊΠΈΠΌ, ΠΊΠ°ΠΊΠΈΠΌ ΠΎΠ½ Π±Ρ‹Π» Π±Ρ‹ Π² случаС Π²Ρ‹Π±ΠΎΡ€Π° Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Π° упорядочСния Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΉ, Ссли Π±Ρ‹ ΠΎΠ½ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΠ»ΠΈΡΡŒ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ, ΠΎΠ΄Π½Π° Π·Π° Π΄Ρ€ΡƒΠ³ΠΎΠΉ.

ΠšΠΎΠ½Π΅Ρ‡Π½ΠΎ, Ρ‡Π΅ΠΌ большС Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΉ, Ρ‚Π΅ΠΌ большС Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ΠΎΠ² ΠΈΡ… упорядочСния. ΠšΠΎΠ½Ρ†Π΅ΠΏΡ†ΠΈΡ сСриализации Π½Π΅ прСдписываСт Π²Ρ‹Π±ΠΎΡ€Π° ΠΊΠ°ΠΊΠΎΠ³ΠΎ-Ρ‚ΠΎ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠ³ΠΎ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Π°. Π Π΅Ρ‡ΡŒ ΠΈΠ΄Ρ‘Ρ‚ лишь ΠΎΠ± ΠΎΠ΄Π½ΠΎΠΌ ΠΈΠ· Π½ΠΈΡ….

Π£Ρ€ΠΎΠ²Π½ΠΈ изоляции Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΉ

Для Π±ΠΎΡ€ΡŒΠ±Ρ‹ с ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ°ΠΌΠΈ, ΠΏΠΎΡ€ΠΎΠΆΠ΄Π°Π΅ΠΌΡ‹ΠΌΠΈ ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½Ρ‹ΠΌ исполнСниСм Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΉ Ρƒ нас Π΅ΡΡ‚ΡŒ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ инструмСнт β€” ΡƒΡ€ΠΎΠ²Π½ΠΈ изоляции Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΉ - фактичСски, Π²Ρ‹Π±ΠΎΡ€ ΠΌΠ΅ΠΆΠ΄Ρƒ ΡΠΊΠΎΡ€ΠΎΡΡ‚ΡŒΡŽ Ρ€Π°Π±ΠΎΡ‚Ρ‹ ΠΈ обСспСчСниСм согласованности Π΄Π°Π½Π½Ρ‹Ρ…, Ρ‚. ΠΊ. ΠΏΡ€ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½Ρ‹Ρ… Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΉ Π² Π‘Π£Π‘Π” всСгда допускаСтся ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ нСсогласованных Π΄Π°Π½Π½Ρ‹Ρ…, ΠΈ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π½Π°ΠΉΡ‚ΠΈ баланс ΠΌΠ΅ΠΆΠ΄Ρƒ количСством ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½Ρ‹Ρ… Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΉ ΠΈ ΡΠΎΠ³Π»Π°ΡΠΎΠ²Π°Π½Π½ΠΎΡΡ‚ΡŒΡŽ Π΄Π°Π½Π½Ρ‹Ρ….

Π‘Ρ‚Π°Π½Π΄Π°Ρ€Ρ‚ SQL-92 опрСдСляСт ΡˆΠΊΠ°Π»Ρƒ ΠΈΠ· Ρ‡Π΅Ρ‚Ρ‹Ρ€Ρ‘Ρ… ΡƒΡ€ΠΎΠ²Π½Π΅ΠΉ изоляции: Read uncommitted, Read committed, Repeatable read, Serializable. ΠŸΠ΅Ρ€Π²Ρ‹ΠΉ ΠΈΠ· Π½ΠΈΡ… являСтся самым слабым, послСдний β€” самым ΡΠΈΠ»ΡŒΠ½Ρ‹ΠΌ, ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΏΠΎΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ Π²ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ Π² сСбя всС ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰ΠΈΠ΅.

Read uncommitted (Ρ‡Ρ‚Π΅Π½ΠΈΠ΅ нСзафиксированных Π΄Π°Π½Π½Ρ‹Ρ…)

Низший (ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ) ΡƒΡ€ΠΎΠ²Π΅Π½ΡŒ изоляции. Если нСсколько ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½Ρ‹Ρ… Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΉ ΠΏΡ‹Ρ‚Π°ΡŽΡ‚ΡΡ ΠΈΠ·ΠΌΠ΅Π½ΡΡ‚ΡŒ ΠΎΠ΄Π½Ρƒ ΠΈ Ρ‚Ρƒ ΠΆΠ΅ строку Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹, Ρ‚ΠΎ Π² ΠΎΠΊΠΎΠ½Ρ‡Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠΌ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Π΅ строка Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΠΌΠ΅Ρ‚ΡŒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠ΅ всСм Π½Π°Π±ΠΎΡ€ΠΎΠΌ ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½Π½Ρ‹Ρ… Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΉ. ΠŸΡ€ΠΈ этом Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ считываниС Π½Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ логичСски нСсогласованных Π΄Π°Π½Π½Ρ‹Ρ…, Π½ΠΎ ΠΈ Π΄Π°Π½Π½Ρ‹Ρ…, измСнСния ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Π΅Ρ‰Ρ‘ Π½Π΅ зафиксированы, Ρ‚. ΠΊ. Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ, Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‰ΠΈΠ΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‡Ρ‚Π΅Π½ΠΈΠ΅, ΠΏΡ€ΠΈ Π΄Π°Π½Π½ΠΎΠΌ ΡƒΡ€ΠΎΠ²Π½Π΅ изоляции Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‚ΡΡ. Π”Π°Π½Π½Ρ‹Π΅ Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‚ΡΡ Π½Π° врСмя выполнСния ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ записи, Ρ‡Ρ‚ΠΎ Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΡƒΠ΅Ρ‚, Ρ‡Ρ‚ΠΎ ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ измСнСния ΠΎΠ΄Π½ΠΈΡ… ΠΈ Ρ‚Π΅Ρ… ΠΆΠ΅ строк, Π·Π°ΠΏΡƒΡ‰Π΅Π½Π½Ρ‹Π΅ ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½ΠΎ, фактичСски выполнятся ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ, ΠΈ Π½ΠΈ ΠΎΠ΄Π½ΠΎ ΠΈΠ· ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ Π½Π΅ потСряСтся.

Read committed (Ρ‡Ρ‚Π΅Π½ΠΈΠ΅ фиксированных Π΄Π°Π½Π½Ρ‹Ρ…)

Π‘ΠΎΠ»ΡŒΡˆΠΈΠ½ΡΡ‚Π²ΠΎ Π‘Π£Π‘Π”, Π² частности, Microsoft SQL Server, PostgreSQL ΠΈ Oracle, ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ ΠΈΠΌΠ΅Π½Π½ΠΎ этот ΡƒΡ€ΠΎΠ²Π΅Π½ΡŒ. На этом ΡƒΡ€ΠΎΠ²Π½Π΅ обСспСчиваСтся Π·Π°Ρ‰ΠΈΡ‚Π° ΠΎΡ‚ чтСния ΠΏΡ€ΠΎΠΌΠ΅ΠΆΡƒΡ‚ΠΎΡ‡Π½Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ…, Ρ‚Π΅ΠΌ Π½Π΅ ΠΌΠ΅Π½Π΅Π΅, Π² процСссС Ρ€Π°Π±ΠΎΡ‚Ρ‹ ΠΎΠ΄Π½ΠΎΠΉ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ другая ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½Π° ΠΈ сдСланныС Сю измСнСния зафиксированы. Π’ ΠΈΡ‚ΠΎΠ³Π΅ пСрвая транзакция Π±ΡƒΠ΄Π΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ с Π΄Ρ€ΡƒΠ³ΠΈΠΌ Π½Π°Π±ΠΎΡ€ΠΎΠΌ Π΄Π°Π½Π½Ρ‹Ρ….
ΠœΠ΅Ρ‚ΠΎΠ΄ read committed рСализуСтся Π»ΠΈΠ±ΠΎ ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ Π΄Π°Π½Π½Ρ‹Ρ… Π½Π° Ρ‡Ρ‚Π΅Π½ΠΈΠ΅ Π²ΠΎ врСмя записи (тСряСм врСмя), Π»ΠΈΠ±ΠΎ Π½Π° Ρ…Ρ€Π°Π½Π΅Π½ΠΈΠΈ ΠΊΠΎΠΏΠΈΠΈ Π΄Π°Π½Π½Ρ‹Ρ…, снятой Π΄ΠΎ Π½Π°Ρ‡Π°Π»Π° записи (тСряСм ΠžΠ—Π£).

Repeatable read (ΠΏΠΎΠ²Ρ‚ΠΎΡ€ΡΡŽΡ‰Π΅Π΅ΡΡ Ρ‡Ρ‚Π΅Π½ΠΈΠ΅)

Π£Ρ€ΠΎΠ²Π΅Π½ΡŒ, ΠΏΡ€ΠΈ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ Ρ‡ΠΈΡ‚Π°ΡŽΡ‰Π°Ρ транзакция Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅Ρ‚ измСнСния Π΄Π°Π½Π½Ρ‹Ρ…, ΠΏΡ€ΠΎΡ‡ΠΈΡ‚Π°Π½Π½Ρ‹Ρ… Сю Ρ€Π°Π½Π΅Π΅. ΠŸΡ€ΠΈ этом никакая другая транзакция Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΠ·ΠΌΠ΅Π½ΡΡ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅, Ρ‡ΠΈΡ‚Π°Π΅ΠΌΡ‹Π΅ Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠ΅ΠΉ, ΠΏΠΎΠΊΠ° Ρ‚Π° Π½Π΅ ΠΎΠΊΠΎΠ½Ρ‡Π΅Π½Π°.

Serializable (упорядочиваниС)

Π‘Π°ΠΌΡ‹ΠΉ высокий ΡƒΡ€ΠΎΠ²Π΅Π½ΡŒ изолированности; Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ ΠΏΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ ΠΈΠ·ΠΎΠ»ΠΈΡ€ΡƒΡŽΡ‚ΡΡ Π΄Ρ€ΡƒΠ³ ΠΎΡ‚ Π΄Ρ€ΡƒΠ³Π°, каТдая выполняСтся Ρ‚Π°ΠΊ, ΠΊΠ°ΠΊ Π±ΡƒΠ΄Ρ‚ΠΎ ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½Ρ‹Ρ… Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΉ Π½Π΅ сущСствуСт. Волько Π½Π° этом ΡƒΡ€ΠΎΠ²Π½Π΅ ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½Ρ‹Π΅ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ Π½Π΅ ΠΏΠΎΠ΄Π²Π΅Ρ€ΠΆΠ΅Π½Ρ‹ эффСкту Β«Ρ„Π°Π½Ρ‚ΠΎΠΌΠ½ΠΎΠ³ΠΎ чтСния».

<style> table th:first-of-type { width: 20%; } table th:nth-of-type(2) { width: 20%; } table th:nth-of-type(3) { width: 20%; } table th:nth-of-type(4) { width: 20%; } table th:nth-of-type(5) { width: 20%; } </style>
Π£Ρ€ΠΎΠ²Π΅Π½ΡŒ изоляции Π€Π°Π½Ρ‚ΠΎΠΌΠ½ΠΎΠ΅ Ρ‡Ρ‚Π΅Π½ΠΈΠ΅ ΠΠ΅ΠΏΠΎΠ²Ρ‚ΠΎΡ€ΡΡŽΡ‰Π΅Π΅ΡΡ Ρ‡Ρ‚Π΅Π½ΠΈΠ΅ «ГрязноС» Ρ‡Ρ‚Π΅Π½ΠΈΠ΅ ΠŸΠΎΡ‚Π΅Ρ€ΡΠ½Π½ΠΎΠ΅ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅
ΠžΡ‚ΡΡƒΡ‚ΡΡ‚Π²ΠΈΠ΅ изоляции + + + +
Read uncommitted + + + -
Read committed + + - -
Repeatable read + - - -
Serializable - - - -
  1. Π‘Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ ΠšΡ€ΠΎΠΌΠ΅ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ ΡƒΡ€ΠΎΠ²Π½Π΅ΠΉ изоляции Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΉ, ΠΌΠ½ΠΎΠ³ΠΈΠ΅ Π‘Π£Π‘Π” ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‚ Ρ‚Π°ΠΊΠΆΠ΅ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ Π΄Π°Π½Π½Ρ‹Ρ… ΠΊΠ°ΠΊ Π½Π° ΡƒΡ€ΠΎΠ²Π½Π΅ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Ρ… строк, Ρ‚Π°ΠΊ ΠΈ Π½Π° ΡƒΡ€ΠΎΠ²Π½Π΅ Ρ†Π΅Π»Ρ‹Ρ… Ρ‚Π°Π±Π»ΠΈΡ†.

Команда SELECT ΠΈΠΌΠ΅Π΅Ρ‚ ΠΏΡ€Π΅Π΄Π»ΠΎΠΆΠ΅Π½ΠΈΠ΅ FOR UPDATE, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ позволяСт Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Π΅ строки Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ с Ρ†Π΅Π»ΡŒΡŽ ΠΈΡ… ΠΏΠΎΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π³ΠΎ обновлСния.

Если ΠΎΠ΄Π½Π° транзакция Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π»Π° строки с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ этой ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹, Ρ‚ΠΎΠ³Π΄Π° ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½Ρ‹Π΅ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ Π½Π΅ смогут Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ эти ΠΆΠ΅ строки Π΄ΠΎ Ρ‚Π΅Ρ… ΠΏΠΎΡ€, ΠΏΠΎΠΊΠ° пСрвая транзакция Π½Π΅ Π·Π°Π²Π΅Ρ€ΡˆΠΈΡ‚ΡΡ, ΠΈ Ρ‚Π΅ΠΌ самым Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ снята.

Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ Ссли Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒ Π΄Π°Π½Π½ΡƒΡŽ ΠΊΠΎΠΌΠ°Π½Π΄Ρƒ:

SELECT * FROM table_tame WHERE column_name ~ 'some text' FOR UPDATE; Π½Π° Π΄Π²ΡƒΡ… Ρ‚Π΅Ρ€ΠΌΠΈΠ½Π°Π»Π°Ρ… β€” сначала Π½Π° ΠΎΠ΄Π½ΠΎΠΌ β€” Π° Π·Π°Ρ‚Π΅ΠΌ Π½Π° Π²Ρ‚ΠΎΡ€ΠΎΠΌ (с ΡƒΡ‡Π΅Ρ‚ΠΎΠΌ Π½Π°Ρ‡Π°Π»Π° Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ BEGIN)

Π’ΠΎ ΠΌΠΎΠΆΠ½ΠΎ Π·Π°ΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ Π½Π° Π²Ρ‚ΠΎΡ€ΠΎΠΌ Ρ‚Π΅Ρ€ΠΌΠΈΠ½Π°Π»Π΅ приостановится Π΄ΠΎ Ρ‚Π΅Ρ… ΠΏΠΎΡ€ ΠΏΠΎΠΊΠ° Π½Π΅ Π·Π°Π²Π΅Ρ€ΡˆΠΈΡ‚ΡΡ транзакция ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ Ρ‚Π΅Ρ€ΠΌΠΈΠ½Π°Π»Π°

ΠŸΡ€ΠΈ этом Ссли Π½Π° ΠΏΠ΅Ρ€Π²ΠΎΠΌ Ρ‚Π΅Ρ€ΠΌΠΈΠ½Π°Π»Π΅ Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ ΠΊΠ°ΠΊΡƒΡŽ-Π½ΠΈΠ±ΡƒΠ΄ΡŒ Π΄Ρ€ΡƒΠ³ΡƒΡŽ ΠΊΠΎΠΌΠ°Π½Π΄Ρƒ:

UPDATE table_name SET column_name = 'kek' WHERE column_value = 404; Π’ΠΎ, пСрСйдя Π½Π° Π²Ρ‚ΠΎΡ€ΠΎΠΉ Ρ‚Π΅Ρ€ΠΌΠΈΠ½Π°Π» станСт Π²ΠΈΠ΄Π½ΠΎ, Ρ‡Ρ‚ΠΎ Ρ‚Π°ΠΌ Π±Ρ‹Π»Π°, Π½Π°ΠΊΠΎΠ½Π΅Ρ†, Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½Π° Π²Ρ‹Π±ΠΎΡ€ΠΊΠ°, которая ΠΏΠΎΠΊΠ°ΠΆΠ΅Ρ‚ ΡƒΠΆΠ΅ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½Π½Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅ с ΡƒΡ‡Π΅Ρ‚ΠΎΠΌ Π΄Π°Π½Π½ΠΎΠΉ UPDATE-ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹.

ΠŸΡ€ΠΎΠ±Π»Π΅ΠΌΠ° N + 1

SQL-ΠΈΠ½ΡŠΠ΅ΠΊΡ†ΠΈΠΈ

NoSQL

Π‘Π°ΠΌΠΎΠ΅ Π³Π»Π°Π²Π½ΠΎΠ΅ Π½Π΅ Π΄ΠΎΠ±Π°Π²ΠΈΠ»ΠΈ - ΡˆΠ°Ρ€Π΄ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅. Π­Ρ‚ΠΎ основноС прСимущСство NoSQL ΠΏΠ΅Ρ€Π΅Π΄ рСляционными DB.

Π¨Π°Ρ€Π΄ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΏΡ€Π΅Π΄ΠΏΠΎΠ»Π°Π³Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ ваши Π΄Π°Π½Π½Ρ‹Π΅ ΠΌΠΎΠΆΠ½ΠΎ ΡΠ³Ρ€ΡƒΠΏΠΏΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π² Π½Π΅ΠΏΠ΅Ρ€Π΅ΡΠ΅ΠΊΠ°ΡŽΡ‰ΠΈΠ΅ΡΡ ΠΌΠ΅ΠΆΠ΄Ρƒ собой мноТСства, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π·Π°Ρ‚Π΅ΠΌ ΠΌΠΎΠΆΠ½ΠΎ Ρ€Π°Π·Π»ΠΎΠΆΠΈΡ‚ΡŒ ΠΏΠΎ Ρ€Π°Π·Π½Ρ‹ΠΌ ΡƒΠ·Π»Π°ΠΌ, Ссли Π½Π°Π΄ΠΎ. Для NoSQL это СстСствСнно - Ρ‚Π°ΠΌ связСй ΠΌΠ΅ΠΆΠ΄Ρƒ Ρ‚Π°Π±Π»ΠΈΡ†Π°ΠΌΠΈ Π½Π΅Ρ‚, ΠΊΠ°ΠΆΠ΄ΡƒΡŽ Ρ‚Π°Π±Π»ΠΈΡ†Ρƒ условно ΠΌΠΎΠΆΠ½ΠΎ Ρ€Π°Π·Π΄Π΅Ρ€ΠΈΠ±Π°Π½ΠΈΡ‚ΡŒ Π³ΠΎΡ€ΠΈΠ·ΠΎΠ½Ρ‚Π°Π»ΡŒΠ½ΠΎ ΠΏΠΎ Π»ΡŽΠ±ΠΎΠΌΡƒ Π½Π°Π±ΠΎΡ€Ρƒ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ΠΎΠ², ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π²Π°ΠΌ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΈΡ‚, ΠΈ Ρ€Π°Π·Π±Ρ€ΠΎΡΠ°Ρ‚ΡŒ нСзависимо ΠΏΠΎ Π½ΡƒΠΆΠ½ΠΎΠΌΡƒ количСсту ΡƒΠ·Π»ΠΎΠ². Π£ рСляционок ΠΆΠ΅ Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ связаны ΠΌΠ΅ΠΆΠ΄Ρƒ собой, ΠΈ Ссли Π²Ρ‹ ΠΊΠ°ΠΊΡƒΡŽ-Ρ‚ΠΎ ΠΎΡΠ½ΠΎΠ²Π½ΡƒΡŽ Ρ‚Π°Π±Π»ΠΈΡ†Ρƒ Π΄Π°Π½Π½Ρ‹Ρ… ΠΈ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Ρ€Π°Π·Π΄Π΅Π»ΠΈΡ‚ΡŒ, Ρ‚ΠΎ всС Π΅Ρ‘ "ΡˆΠ°Ρ€Π΄Ρ‹" всё Ρ€Π°Π²Π½ΠΎ Π±ΡƒΠ΄ΡƒΡ‚ ΡΡΡ‹Π»Π°Ρ‚ΡŒΡΡ Π½Π° ΠΎΠ΄Π½ΠΈ ΠΈ Ρ‚Π΅ ΠΆΠ΅ справочники, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ ΠΏΠΎ нСзависимым Π½ΠΎΠ΄Π°ΠΌ Ρ‚Π°ΠΊΡƒΡŽ структуру Ρ€Π°ΡΠΊΠΈΠ΄Π°Ρ‚ΡŒ Π½Π΅ получится... Π½Ρƒ Π° Ρ€Π°Π· Ρ‚Π°ΠΊ, Π½Π°Π·Ρ‹Π²Π°Ρ‚ΡŒ ΠΌΡ‹ это Π±ΡƒΠ΄Π΅ΠΌ Π½Π΅ ΡˆΠ°Ρ€Π΄ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ, Π° ΠΏΠ°Ρ€Ρ‚ΠΈΡ†ΠΈΠΎΠ½ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ.

Π―Π·Ρ‹ΠΊ SQL

SQL - Π΄Π΅ΠΊΠ»Π°Ρ€Π°Ρ‚ΠΈΠ²Π½Ρ‹ΠΉ (ΠΎΠΏΠΈΡΠ°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ, Π½Π΅ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Π½Ρ‹ΠΉ) язык, стандарт для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с Π΄Π°Π½Π½Ρ‹ΠΌΠΈ Π²ΠΎ всСх рСляционных Π‘Π£Π‘Π”.
ΠžΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹ SQL Ρ‚Ρ€Π°Π΄ΠΈΡ†ΠΈΠΎΠ½Π½ΠΎ дСлят Π½Π°:
ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹ опрСдСлСния Π΄Π°Π½Π½Ρ‹Ρ… (data definition language, DDL),
ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹ манипулирования Π΄Π°Π½Π½Ρ‹ΠΌΠΈ (data manipulation language, DML),
ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹ управлСния привилСгиями доступа (data control language, DCL) ΠΈ
ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹ управлСния транзакциями (transaction control language, TCL).

DDL

CREATE, созданиС Π½ΠΎΠ²ΠΎΠΉ Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹

Constraints (ограничСния)

Constraints ΡƒΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‚ΡΡ ΠΏΡ€ΠΈ создании ΠΈΠ»ΠΈ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΈ Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹. Π­Ρ‚ΠΈ ΠΏΡ€Π°Π²ΠΈΠ»Π° ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡ΠΈΠ²Π°ΡŽΡ‚ Ρ‚ΠΈΠΏ Π΄Π°Π½Π½Ρ‹Ρ…, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠΎΠ³ΡƒΡ‚ Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒΡΡ Π² Ρ‚Π°Π±Π»ΠΈΡ†Π΅. ΠŸΡ€ΠΈ Π½Π°Ρ€ΡƒΡˆΠ΅Π½ΠΈΠΈ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠΉ дСйствия с Π΄Π°Π½Π½Ρ‹ΠΌΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½Ρ‹ Π½Π΅ Π±ΡƒΠ΄ΡƒΡ‚.

UNIQUE β€” Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΡƒΠ΅Ρ‚ ΡƒΠ½ΠΈΠΊΠ°Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ Π² столбцС;
NOT NULL β€” Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ NULL;
INDEX β€” создаёт индСксы Π² Ρ‚Π°Π±Π»ΠΈΡ†Π΅ для быстрого поиска/запросов;
CHECK β€” значСния столбца Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ Π·Π°Π΄Π°Π½Π½Ρ‹ΠΌ условиям;
DEFAULT β€” Π½Π°Π·Π½Π°Ρ‡Π°Π΅Ρ‚ столбцу Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ.

ALTER, ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ структуры Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹

RENAME

DROP, ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠ΅ Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹

PRIMARY KEY, ΠΏΠ΅Ρ€Π²ΠΈΡ‡Π½Ρ‹ΠΉ ΠΊΠ»ΡŽΡ‡

ΠŸΠ΅Ρ€Π²ΠΈΡ‡Π½Ρ‹ΠΉ ΠΊΠ»ΡŽΡ‡ ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½ для ΠΎΠ΄Π½ΠΎΠ·Π½Π°Ρ‡Π½ΠΎΠΉ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ ΠΊΠ°ΠΆΠ΄ΠΎΠΉ записи Π² Ρ‚Π°Π±Π»ΠΈΡ†Π΅ ΠΈ являСтся строго ΡƒΠ½ΠΈΠΊΠ°Π»ΡŒΠ½Ρ‹ΠΌ, Π΄Π²Π΅ записи Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ Π½Π΅ ΠΌΠΎΠ³ΡƒΡ‚ ΠΈΠΌΠ΅Ρ‚ΡŒ ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²Ρ‹Π΅ значСния ΠΏΠ΅Ρ€Π²ΠΈΡ‡Π½ΠΎΠ³ΠΎ ΠΊΠ»ΡŽΡ‡Π°. НулСвыС значСния (NULL) Π² PRIMARY KEY Π½Π΅ Π΄ΠΎΠΏΡƒΡΠΊΠ°ΡŽΡ‚ΡΡ. Если Π² качСствС PRIMARY KEY ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ нСсколько ΠΏΠΎΠ»Π΅ΠΉ, ΠΈΡ… Π½Π°Π·Ρ‹Π²Π°ΡŽΡ‚ составным ΠΊΠ»ΡŽΡ‡ΠΎΠΌ.

CREATE TABLE USERS (
  id INT NOT NULL,
  name VARCHAR (40) NOT NULL,
  PRIMARY KEY (id)
);

FOREIGN KEY, внСшний ΠΊΠ»ΡŽΡ‡

TRUNCATE

DML

WHERE ΠΈ HAVING ΠΌΠΎΠ³ΡƒΡ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ Π² ΠΎΠ΄Π½ΠΎΠΌ запросС, ΠΏΡ€ΠΈ этом Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΡƒΡ‡ΠΈΡ‚Ρ‹Π²Π°Ρ‚ΡŒ порядок исполнСния SQL запроса:

  1. FROM
  2. ON
  3. JOIN
  4. WHERE
  5. GROUP BY
  6. WITH CUBE / WITH ROLLUP
  7. HAVING
  8. ΠžΠΊΠΎΠ½Π½Ρ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ
  9. SELECT
  10. DISTINCT
  11. UNION / UNION ALL / INTERSECT / EXCEPT
  12. ORDER BY
  13. TOP / LIMIT / OFFSET

Π‘Π½Π°Ρ‡Π°Π»Π° опрСдСляСтся Ρ‚Π°Π±Π»ΠΈΡ†Π°, ΠΈΠ· ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ Π²Ρ‹Π±ΠΈΡ€Π°ΡŽΡ‚ΡΡ Π΄Π°Π½Π½Ρ‹Π΅ (FROM); Π·Π°Ρ‚Π΅ΠΌ ΠΈΠ· этой Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ ΠΎΡ‚Π±ΠΈΡ€Π°ΡŽΡ‚ΡΡ записи Π² соотвСтствии с условиСм WHERE; Π²Ρ‹Π±Ρ€Π°Π½Π½Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅ Π°Π³Ρ€Π΅Π³ΠΈΡ€ΡƒΡŽΡ‚ΡΡ (GROUP BY); ΠΈΠ· Π°Π³Ρ€Π΅Π³ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Ρ… записСй Π²Ρ‹Π±ΠΈΡ€Π°ΡŽΡ‚ΡΡ Ρ‚Π΅, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΡƒΠ΄ΠΎΠ²Π»Π΅Ρ‚Π²ΠΎΡ€ΡΡŽΡ‚ ΡƒΡΠ»ΠΎΠ²ΠΈΡŽ послС HAVING. Волько ΠΏΠΎΡ‚ΠΎΠΌ Ρ„ΠΎΡ€ΠΌΠΈΡ€ΡƒΡŽΡ‚ΡΡ Π΄Π°Π½Π½Ρ‹Π΅ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚ΠΈΡ€ΡƒΡŽΡ‰Π΅ΠΉ Π²Ρ‹Π±ΠΎΡ€ΠΊΠΈ, ΠΊΠ°ΠΊ это ΡƒΠΊΠ°Π·Π°Π½ΠΎ послС SELECT (Π²Ρ‹Ρ‡ΠΈΡΠ»ΡΡŽΡ‚ΡΡ выраТСния, ΠΏΡ€ΠΈΡΠ²Π°ΠΈΠ²Π°ΡŽΡ‚ΡΡ ΠΈΠΌΠ΅Π½Π° ΠΈ ΠΏΡ€.). Π Π΅Π·ΡƒΠ»ΡŒΡ‚ΠΈΡ€ΡƒΡŽΡ‰Π°Ρ Π²Ρ‹Π±ΠΎΡ€ΠΊΠ° сортируСтся Π² соотвСтствии с условиСм, ΡƒΠΊΠ°Π·Π°Π½Π½Ρ‹ΠΌ послС ORDER BY.

Π—Π½Π°Π½ΠΈΠ΅ порядка исполнСния SQL запроса Π²Π°ΠΆΠ½ΠΎ для Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠ½ΡΡ‚ΡŒ, ΠΏΠΎΡ‡Π΅ΠΌΡƒ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π²Π½ΡƒΡ‚Ρ€ΠΈ WHERE Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΈΠΌΠ΅Π½Π° Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ ΠΈΠ· SELECT; просто SELECT выполняСтся компилятором ΠΏΠΎΠ·ΠΆΠ΅, Ρ‡Π΅ΠΌ WHERE, поэтому Π΅ΠΌΡƒ нСизвСстно, ΠΊΠ°ΠΊΠΎΠ΅ Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ Ρ‚Π°ΠΌ описано.

SELECT, FROM, WHERE

Команда SELECT ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ записи ΠΈΠ· Π±Π°Π·Ρ‹ Π΄Π°Π½Π½Ρ‹Ρ… ΠΏΠΎ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠΌΡƒ ΡƒΡΠ»ΠΎΠ²ΠΈΡŽ, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ задаСтся с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ WHERE.

Бинтаксис:
SELECT * FROM имя_Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹;
SELECT * FROM имя_Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ WHERE условиС;
SELECT ΠΏΠΎΠ»Π΅1, ΠΏΠΎΠ»Π΅2... FROM имя_Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ WHERE условиС;

ΠŸΠΎΠ»Π½Ρ‹ΠΉ синтаксис ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ SELECT:
SELECT
[STRAIGHT_JOIN] [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]
[SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS] [HIGH_PRIORITY]
[DISTINCT | DISTINCTROW | ALL]
select_expression,...
[INTO {OUTFILE | DUMPFILE} 'file_name' export_options]
[FROM table_references
[WHERE where_definition]
[GROUP BY {unsigned_integer | col_name | formula} [ASC | DESC], ...]
[HAVING where_definition]
[ORDER BY {unsigned_integer | col_name | formula} [ASC | DESC], ...]
[LIMIT [offset,] rows | rows OFFSET offset]
[PROCEDURE procedure_name(argument_list)]
[FOR UPDATE | LOCK IN SHARE MODE]]

LIKE

ORDER BY

Π‘ΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²ΠΊΠ° Π΄Π°Π½Π½Ρ‹Ρ… Π² порядкС возрастания (ASC) ΠΈΠ»ΠΈ убывания (DESC).

SELECT * FROM user ORDER BY name DESC;

COUNT, SUM, AVG, MAX, MIN, Π°Π³Ρ€Π΅Π³ΠΈΡ€ΡƒΡŽΡ‰ΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ

GROUP BY, HAVING, Π³Ρ€ΡƒΠΏΠΏΠΈΡ€ΠΎΠ²ΠΊΠ° ΠΈ Ρ„ΠΈΠ»ΡŒΡ‚Ρ€Π°Ρ†ΠΈΡ Π΄Π°Π½Π½Ρ‹Ρ…

JOIN, объСдинСниС Π΄Π°Π½Π½Ρ‹Ρ… ΠΈΠ· Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… Ρ‚Π°Π±Π»ΠΈΡ†

INNER JOIN

Если совсСм ΠΊΡ€Π°Ρ‚ΠΊΠΎ, Ρ‚ΠΎ INNER JOIN Π½Π΅ пСрСсСчСниС мноТСств, ΠΊΠ°ΠΊ нарисовано, Π°, скорСС, ΠΏΠ΅Ρ€Π΅ΠΌΠ½ΠΎΠΆΠ΅Π½ΠΈΠ΅ с условиСм.

FULL OUTER JOIN

LEFT JOIN

RIGHT JOIN

CROSS JOIN, пСрСкрСстноС соСдинСниС

Π‘ΠΎΠ·Π΄Π°Π΅Ρ‚ Π½Π°Π±ΠΎΡ€ строк, Π³Π΄Π΅ каТдая строка ΠΈΠ· ΠΎΠ΄Π½ΠΎΠΉ Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ соСдиняСтся с ΠΊΠ°ΠΆΠ΄ΠΎΠΉ строкой ΠΈΠ· Π²Ρ‚ΠΎΡ€ΠΎΠΉ Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹.

Self join

Π’Π°ΠΊΠΎΠΉ вопрос Ρ‚ΠΎΠΆΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΡ€ΠΎΠ·Π²ΡƒΡ‡Π°Ρ‚ΡŒ Π½Π° собСсСдовании ΠΏΠΎ SQL. Π­Ρ‚ΠΎ Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Ρ‚Π°Π±Π»ΠΈΡ†Π° объСдинилась сама с собой, словно это Π΄Π²Π΅ Ρ€Π°Π·Π½Ρ‹Π΅ Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹. Π§Ρ‚ΠΎΠ±Ρ‹ Ρ‚Π°ΠΊΠΎΠ΅ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ, ΠΎΠ΄Π½Π° ΠΈΠ· Ρ‚Π°ΠΊΠΈΡ… Β«Ρ‚Π°Π±Π»ΠΈΡ†Β» Π²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ пСрСимСновываСтся.

НапримСр, ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ SQL-запрос ΠΎΠ±ΡŠΠ΅Π΄ΠΈΠ½ΡΠ΅Ρ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ² ΠΈΠ· ΠΎΠ΄Π½ΠΎΠ³ΠΎ Π³ΠΎΡ€ΠΎΠ΄Π°:

SELECT A.CustomerName AS CustomerName1, B.CustomerName AS CustomerName2, A.City
FROM Customers A, Customers B
WHERE A.CustomerID <> B.CustomerID
AND A.City = B.City
ORDER BY A.City;

INSERT, Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ Π½ΠΎΠ²Ρ‹Ρ… строк

UPDATE, ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΡ… строк

DELETE, ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠ΅ строк

ΠžΠΏΠ΅Ρ€Π°Ρ†ΠΈΡ, которая удаляСт записи ΠΈΠ· Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹, ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠ΅ Π·Π°Π΄Π°Π½Π½ΠΎΠΌΡƒ ΡƒΡΠ»ΠΎΠ²ΠΈΡŽ. ΠŸΡ€ΠΈ этом ΡΠΎΠ·Π΄Π°ΡŽΡ‚ΡΡ Π»ΠΎΠ³ΠΈ удалСния, Ρ‚ΠΎ Π΅ΡΡ‚ΡŒ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΡŽ ΠΌΠΎΠΆΠ½ΠΎ ΠΎΡ‚ΠΌΠ΅Π½ΠΈΡ‚ΡŒ.

DELETE FROM table_name WHERE condition;

FROM

SET

Π’Π»ΠΎΠΆΠ΅Π½Π½Ρ‹Π΅ запросы

SQL позволяСт ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹Π΅ запросы. Π’Π»ΠΎΠΆΠ΅Π½Π½Ρ‹ΠΉ запрос – это запрос, Ρ€Π°Π·ΠΌΠ΅Ρ‰Π΅Π½Π½Ρ‹ΠΉ Π²Π½ΡƒΡ‚Ρ€ΠΈ Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ запроса SQL.

Π’Π»ΠΎΠΆΠ΅Π½Π½Ρ‹ΠΉ запрос ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для Π²Ρ‹Π±ΠΎΡ€ΠΊΠΈ Π΄Π°Π½Π½Ρ‹Ρ…, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π±ΡƒΠ΄ΡƒΡ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ Π² условии ΠΎΡ‚Π±ΠΎΡ€Π° записСй основного запроса. Π•Π³ΠΎ ΠΏΡ€ΠΈΠΌΠ΅Π½ΡΡŽΡ‚ для:
сравнСния выраТСния с Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠΌ Π²Π»ΠΎΠΆΠ΅Π½Π½ΠΎΠ³ΠΎ запроса;
опрСдСлСния Ρ‚ΠΎΠ³ΠΎ, Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΎ Π»ΠΈ Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ Π² Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹ Π²Π»ΠΎΠΆΠ΅Π½Π½ΠΎΠ³ΠΎ запроса;
ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ Ρ‚ΠΎΠ³ΠΎ, Π²Ρ‹Π±ΠΈΡ€Π°Π΅Ρ‚ Π»ΠΈ запрос ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹Π΅ строки.

Π’Π»ΠΎΠΆΠ΅Π½Π½Ρ‹ΠΉ запрос ΠΈΠΌΠ΅Π΅Ρ‚ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹:
ΠΊΠ»ΡŽΡ‡Π΅Π²ΠΎΠ΅ слово SELECT, послС ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ ΡƒΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‚ΡΡ ΠΈΠΌΠ΅Π½Π° столбцов ΠΈΠ»ΠΈ выраТСния (Ρ‡Π°Ρ‰Π΅ всСго список содСрТит ΠΎΠ΄ΠΈΠ½ элСмСнт),
ΠΊΠ»ΡŽΡ‡Π΅Π²ΠΎΠ΅ слово FROM ΠΈ имя Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹, ΠΈΠ· ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ Π²Ρ‹Π±ΠΈΡ€Π°ΡŽΡ‚ΡΡ Π΄Π°Π½Π½Ρ‹Π΅,
Π½Π΅ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠ΅ ΠΏΡ€Π΅Π΄Π»ΠΎΠΆΠ΅Π½ΠΈΠ΅ WHERE,
Π½Π΅ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠ΅ ΠΏΡ€Π΅Π΄Π»ΠΎΠΆΠ΅Π½ΠΈΠ΅ GROUP BY,
Π½Π΅ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠ΅ ΠΏΡ€Π΅Π΄Π»ΠΎΠΆΠ΅Π½ΠΈΠ΅ HAVING.

Π Π°Π±ΠΎΡ‚Π° с индСксами ΠΈ ограничСниями

Π˜Π½Π΄Π΅ΠΊΡΡ‹ ИндСкс – ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½Π°Ρ структура Π΄Π°Π½Π½Ρ‹Ρ…, которая связана с Ρ‚Π°Π±Π»ΠΈΡ†Π΅ΠΉ ΠΈ создаётся Π½Π° основС Π΅Ρ‘ Π΄Π°Π½Π½Ρ‹Ρ…. Π˜Π½Π΄Π΅ΠΊΡΡ‹ ΡΠΎΠ·Π΄Π°ΡŽΡ‚ΡΡ для ΠΏΠΎΠ²Ρ‹ΡˆΠ΅Π½ΠΈΡ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ функционирования Π±Π°Π·Ρ‹ Π΄Π°Π½Π½Ρ‹Ρ….

КакиС Π±Ρ‹Π²Π°ΡŽΡ‚ индСксы?

Π’-Π΄Π΅Ρ€Π΅Π²ΠΎ

Ρ…Π΅Ρˆ

GiST

SP-GiST

GIN

BRIN

По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ ΠΊΠΎΠΌΠ°Π½Π΄Π° CREATE INDEX создаёт индСксы Ρ‚ΠΈΠΏΠ° Π’-Π΄Π΅Ρ€Π΅Π²ΠΎ (эффСктивны Π² Π±ΠΎΠ»ΡŒΡˆΠΈΠ½ΡΡ‚Π²Π΅ случаСв)

Как ΠΌΠΎΠΆΠ½ΠΎ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ индСксы?

πŸ”Ή ИндСкс ΠΏΠΎ столбцу (это чистая классика)

πŸ”Ή ИндСкс ΠΏΠΎ нСскольким столбцам

πŸ”Ή Π£Π½ΠΈΠΊΠ°Π»ΡŒΠ½Ρ‹ΠΉ индСкс

πŸ”Ή ИндСкс Π½Π° основС выраТСния

πŸ”Ή Частичный индСкс

Для создания индСкса ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½ΠΎ Ρ‚Π°ΠΊΠΎΠΉ синтаксис:

CREATE [UNIQUE] INDEX <index_name> ON <table_name> ( <column_name>, ... ) [STATEMENT] ; ΠŸΡ€ΠΈ этом:

для создания ΡƒΠ½ΠΈΠΊΠ°Π»ΡŒΠ½ΠΎΠ³ΠΎ индСкса ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ слово UNIQUE

для создания выраТСния Π΅Π³ΠΎ Π·Π°ΠΏΠΈΡΡ‹Π²Π°ΡŽΡ‚ Π² скобках, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ для создания выраТСния ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ индСкса Π½Π° Π½ΠΈΠΆΠ½ΠΈΠΉ рСгистр ΠΌΠΎΠΆΠ½ΠΎ Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ Ρ‚Π°ΠΊ:

. . . ( lower( <column_name> ) ) ; для создания частичного индСкса послС скобок запись продолТаСтся, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ для ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ Π½Π° Π²Π΅Π»ΠΈΡ‡ΠΈΠ½Ρƒ ΠΌΠΎΠΆΠ½ΠΎ Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ Ρ‚Π°ΠΊ:

. . . ( . . . ) WHERE <column_name> > 1000 ;

опросы Π½Π° собСсСдованиях ΠΎΡ‡Π΅Π½ΡŒ часто бСссистСмныС, ΠΎΠ½ΠΈ ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ просто ΠΎ Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ Π²ΠΎΠΏΡ€ΠΎΡˆΠ°ΡŽΡ‰Π΅ΠΌΡƒ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎ сСйчас ΠΏΡ€ΠΈΡˆΠ»ΠΎ Π² Π³ΠΎΠ»ΠΎΠ²Ρƒ, ΠΈ ΠΎΠ½ Π²ΠΎΠΎΠ±Ρ‰Π΅ Π½Π΅ Ρ„Π°ΠΊΡ‚, Ρ‡Ρ‚ΠΎ сам ΡƒΠΌΠ΅Π΅Ρ‚ ΡΠΏΡ€Π°ΡˆΠΈΠ²Π°Ρ‚ΡŒ ΠΎ Π³Π»Π°Π²Π½ΠΎΠΌ, Π° Π½Π΅ второстСпСнном. ΠŸΡ€ΠΈΠ²Π΅Π΄Ρƒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄ΠΈΠ½ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Ρƒ вас - ΠΏΡ€ΠΎ индСксы. Вас, Π²ΠΈΠ΄ΠΈΠΌΠΎ, ΡΠΏΡ€Π°ΡˆΠΈΠ²Π°Π»ΠΈ ΠΎ Ρ‚ΠΎΠΌ, ΠΊΠ°ΠΊΠΈΠ΅ ΠΎΠ½ΠΈ Π±Ρ‹Π²Π°ΡŽΡ‚ ΠΈ ΠΊΠ°ΠΊΠΈΠΌ синтаксисом ΡΠΎΠ·Π΄Π°ΡŽΡ‚ΡΡ. Но ΠΏΠΎΠ²Π΅Ρ€ΡŒΡ‚Π΅, это совсСм Π½Π΅ самоС Π³Π»Π°Π²Π½ΠΎΠ΅ ΠΈΠ· Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ стоит Π·Π½Π°Ρ‚ΡŒ ΠΏΡ€ΠΎ индСксы. Π“ΠΎΡ€Π°Π·Π΄ΠΎ Π²Π°ΠΆΠ½Π΅Π΅ ΠΏΠΎΠ½ΠΈΠΌΠ°Ρ‚ΡŒ ΠΈΡ… ΡΡƒΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ ΠΎΠ½ΠΈ ΠΈΠ· сСбя ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²Π»ΡΡŽΡ‚ Π²Π½ΡƒΡ‚Ρ€ΠΈ - Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠ½ΠΈΠΌΠ°Ρ‚ΡŒ, ΠΏΠΎΡ‡Π΅ΠΌΡƒ ΠΊΠ°ΠΊΠΎΠΉ-Ρ‚ΠΎ запрос индСксом ускоряСтся, Π° ΠΊΠ°ΠΊΠΎΠΉ-Ρ‚ΠΎ Π½Π΅Ρ‚.

Π˜Π·ΡƒΡ‡Π΅Π½ΠΈΠ΅ индСксов для ускорСния поиска Π΄Π°Π½Π½Ρ‹Ρ… Π² Ρ‚Π°Π±Π»ΠΈΡ†Π΅
Π˜Π·ΡƒΡ‡Π΅Π½ΠΈΠ΅ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠΉ для Π·Π°Ρ‰ΠΈΡ‚Ρ‹ Π΄Π°Π½Π½Ρ‹Ρ… ΠΈ обСспСчСния цСлостности Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹

Π Π°Π±ΠΎΡ‚Π° с прСдставлСниями ΠΈ Ρ…Ρ€Π°Π½ΠΈΠΌΡ‹ΠΌΠΈ ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Π°ΠΌΠΈ
Π˜Π·ΡƒΡ‡Π΅Π½ΠΈΠ΅ прСдставлСний для создания Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹Ρ… Ρ‚Π°Π±Π»ΠΈΡ† Π½Π° основС запросов
Π˜Π·ΡƒΡ‡Π΅Π½ΠΈΠ΅ Ρ…Ρ€Π°Π½ΠΈΠΌΡ‹Ρ… ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€ для создания ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΡ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ ΠΈ процСссов

ΠŸΡ€ΠΎΠ΄Π²ΠΈΠ½ΡƒΡ‚Ρ‹Π΅ SQL скиллы:
MVCC ΠžΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΡ запросов - Π·Π½Π°Π½ΠΈΠ΅ структуры Ρ‚Π°Π±Π»ΠΈΡ† ΠΈ индСксов, Π° Ρ‚Π°ΠΊΠΆΠ΅ понимания Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ запросы для ΡƒΠ»ΡƒΡ‡ΡˆΠ΅Π½ΠΈΡ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ.
Π Π°Π±ΠΎΡ‚Π° с большими объСмами Π΄Π°Π½Π½Ρ‹Ρ… - ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ ΠΏΠ°Ρ€Ρ‚ΠΈΡ†ΠΈΠΎΠ½ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ, кластСризациСй ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠΌΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄Π°ΠΌΠΈ для ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ ΠΈ Π°Π½Π°Π»ΠΈΠ·Π° Π±ΠΎΠ»ΡŒΡˆΠΈΡ… объСмов Π΄Π°Π½Π½Ρ‹Ρ….
ИспользованиС аналитичСских Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ - использованиС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ, Ρ‚Π°ΠΊΠΈΡ… ΠΊΠ°ΠΊ RANK, ROW_NUMBER, LAG ΠΈ LEAD, для выполнСния слоТных аналитичСских запросов.
Π Π°Π±ΠΎΡ‚Π° с Π²Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΌΠΈ рядами Π΄Π°Π½Π½Ρ‹Ρ… - использованиС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ Π²Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… рядов, Ρ‚Π°ΠΊΠΈΡ… ΠΊΠ°ΠΊ DATE_TRUNC, DATE_PART ΠΈ WINDOW Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ, для Π°Π½Π°Π»ΠΈΠ·Π° ΠΈ управлСния Π²Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΌΠΈ рядами Π΄Π°Π½Π½Ρ‹Ρ….
Π Π°Π±ΠΎΡ‚Π° с гСографичСскими Π΄Π°Π½Π½Ρ‹ΠΌΠΈ - использованиС ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½Ρ‹Ρ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ, Ρ‚Π°ΠΊΠΈΡ… ΠΊΠ°ΠΊ ST_Distance, ST_Within ΠΈ ST_Intersection, для Π°Π½Π°Π»ΠΈΠ·Π° ΠΈ управлСния гСографичСскими Π΄Π°Π½Π½Ρ‹ΠΌΠΈ.
Π Π°Π±ΠΎΡ‚Π° с Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π°ΠΌΠΈ Π΄Π°Π½Π½Ρ‹Ρ… - использованиС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ ETL (Extract, Transform, Load) для извлСчСния, прСобразования ΠΈ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ Π΄Π°Π½Π½Ρ‹Ρ… Π² Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π° Π΄Π°Π½Π½Ρ‹Ρ….
Π Π°Π±ΠΎΡ‚Π° с ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Π°ΠΌΠΈ ΠΈ Ρ‚Ρ€ΠΈΠ³Π³Π΅Ρ€Π°ΠΌΠΈ - созданиС ΠΈ ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Π°ΠΌΠΈ ΠΈ Ρ‚Ρ€ΠΈΠ³Π³Π΅Ρ€Π°ΠΌΠΈ для Π°Π²Ρ‚ΠΎΠΌΠ°Ρ‚ΠΈΠ·Π°Ρ†ΠΈΠΈ Π·Π°Π΄Π°Ρ‡ ΠΈ обСспСчСния цСлостности Π΄Π°Π½Π½Ρ‹Ρ….
Π Π°Π±ΠΎΡ‚Π° с рСляционной Π°Π»Π³Π΅Π±Ρ€ΠΎΠΉ - использованиС Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Ρ… ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠ², Ρ‚Π°ΠΊΠΈΡ… ΠΊΠ°ΠΊ JOIN, UNION, INTERSECT ΠΈ EXCEPT, для выполнСния слоТных запросов.
Π Π°Π±ΠΎΡ‚Π° с индСксами - созданиС ΠΈ ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ индСксами для ΡƒΠ»ΡƒΡ‡ΡˆΠ΅Π½ΠΈΡ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ запросов.
Π Π°Π±ΠΎΡ‚Π° с Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡ‚ΡŒΡŽ Π΄Π°Π½Π½Ρ‹Ρ… - ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ доступом ΠΊ Π΄Π°Π½Π½Ρ‹ΠΌ ΠΈ Π·Π°Ρ‰ΠΈΡ‚Ρƒ Π΄Π°Π½Π½Ρ‹Ρ… ΠΎΡ‚ нСсанкционированного доступа.

ΠžΠΊΠΎΠ½Π½Ρ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ

SQLite

Small. Fast. Reliable. Choose any three.

https://sqlite.org/index.html
https://github.com/sqlite/sqlite
https://habr.com/ru/post/149356/
https://github.com/sqlitebrowser/sqlitebrowser

Syntax Diagrams https://www.sqlite.org/syntaxdiagrams.html

Server-less database engine that stores each database into a separate file.

### Connect
**Opens a connection to the database file. Creates a new file if path doesn't exist.**
 
import sqlite3
<conn> = sqlite3.connect(<path>)                # Also ':memory:'.
<conn>.close()                                  # Closes the connection.

### Read
**Returned values can be of type str, int, float, bytes or None.**
 
<cursor> = <conn>.execute('<query>')            # Can raise a subclass of sqlite3.Error.
<tuple>  = <cursor>.fetchone()                  # Returns next row. Also next(<cursor>).
<list>   = <cursor>.fetchall()                  # Returns remaining rows. Also list(<cursor>).
 
### Write
 
<conn>.execute('<query>')                       # Can raise a subclass of sqlite3.Error.
<conn>.commit()                                 # Saves all changes since the last commit.
<conn>.rollback()                               # Discards all changes since the last commit.

#### Or:
 
with <conn>:                                    # Exits the block with commit() or rollback(),
    <conn>.execute('<query>')                   # depending on whether any exception occurred.
 
### Placeholders
* **Passed values can be of type str, int, float, bytes, None, bool, datetime.date or datetime.datetime.**
* **Bools will be stored and returned as ints and dates as [ISO formatted strings](#encode).**
 
<conn>.execute('<query>', <list/tuple>)         # Replaces '?'s in query with values.
<conn>.execute('<query>', <dict/namedtuple>)    # Replaces ':<key>'s with values.
<conn>.executemany('<query>', <coll_of_above>)  # Runs execute() multiple times.
 
### Example
**Values are not actually saved in this example because `'conn.commit()'` is omitted!**
 
>>> conn = sqlite3.connect('test.db')
>>> conn.execute('CREATE TABLE person (person_id INTEGER PRIMARY KEY, name, height)')
>>> conn.execute('INSERT INTO person VALUES (NULL, ?, ?)', ('Jean-Luc', 187)).lastrowid
1
>>> conn.execute('SELECT * FROM person').fetchall()
[(1, 'Jean-Luc', 187)]

MySQL

Has a very similar interface, with differences listed below.

# $ pip3 install mysql-connector
from mysql import connector
<conn>   = connector.connect(host=<str>, …)     # `user=<str>, password=<str>, database=<str>`.
<cursor> = <conn>.cursor()                      # Only cursor has execute() method.
<cursor>.execute('<query>')                     # Can raise a subclass of connector.Error.
<cursor>.execute('<query>', <list/tuple>)       # Replaces '%s's in query with values.
<cursor>.execute('<query>', <dict/namedtuple>)  # Replaces '%(<key>)s's with values.

Memory View
-----------
* **A sequence object that points to the memory of another object.**
* **Each element can reference a single or multiple consecutive bytes, depending on format.**
* **Order and number of elements can be changed with slicing.**
* **Casting only works between char and other types and uses system's sizes and byte order.**

 
<mview> = memoryview(<bytes/bytearray/array>)  # Immutable if bytes, else mutable.
<real>  = <mview>[<index>]                     # Returns an int or a float.
<mview> = <mview>[<slice>]                     # Mview with rearranged elements.
<mview> = <mview>.cast('<typecode>')           # Casts memoryview to the new format.
<mview>.release()                              # Releases the object's memory buffer.

PostgreSQL

ВозмоТности PostgreSQL, ΠΎΡ‚ΡΡƒΡ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠ΅ Π² Π΄Ρ€ΡƒΠ³ΠΈΡ… Π‘Π”

ΠšΠ°ΡΠΊΠ°Π΄Π½Ρ‹Π΅ Ρ‚Ρ€ΠΈΠ³Π³Π΅Ρ€Ρ‹. Если триггСрная функция выполняСт ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ SQL, эти ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ ΠΌΠΎΠ³ΡƒΡ‚ Π·Π°Π½ΠΎΠ²ΠΎ Π·Π°ΠΏΡƒΡΠΊΠ°Ρ‚ΡŒ Ρ‚Ρ€ΠΈΠ³Π³Π΅Ρ€Ρ‹.

hstore. Π’ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ ΠΈ ΠΌΠ°Π½ΠΈΠΏΡƒΠ»ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π΄Π°Π½Π½Ρ‹ΠΌΠΈ с Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΡΡ‚ΡŒΡŽ словаря (dictionary).

JSONB. ΠŸΠ°Ρ€ΡΠΈΠ½Π³ JSON осущСствляСтся ΠΎΠ΄Π½ΠΎΠΊΡ€Π°Ρ‚Π½ΠΎ, Π²ΠΎ врСмя записи. Π‘ΠΎΠ»Π΅Π΅ мСдлСнная однократная запись, Π½ΠΎ Π±ΠΎΠ»Π΅Π΅ быстрыС ΠΌΠ½ΠΎΠ³ΠΎΠΊΡ€Π°Ρ‚Π½Ρ‹Π΅ чтСния. По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ рСкомСндуСтся ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ JSONB, Π° Π½Π΅ JSON.

Range Types. Никаких большС ΠΊΠΎΠ»ΠΎΠ½ΠΎΠΊ planned_worktime_start ΠΈ planned_worktime_end ΠΈ пляски с ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π°ΠΌΠΈ сравнСния для нахоТдСния Π΄Ρ€ΡƒΠ³ΠΈΡ… строк, Ρƒ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… ΠΈΠ½Ρ‚Π΅Ρ€Π²Π°Π», Π·Π°Π΄Π°Π²Π°Π΅ΠΌΡ‹ΠΉ этими ΠΊΠΎΠ»ΠΎΠ½ΠΊΠ°ΠΌΠΈ пСрСсСкаСтся с этой строкой.

ΠŸΡ€ΠΎΡ‡ΠΈΠ΅ Π½Π°Ρ‚ΠΈΠ²Π½Ρ‹Π΅ Ρ‚ΠΈΠΏΡ‹: interval, cidr ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠ΅, со встроСнными ΠΌΠ΅Ρ‚ΠΎΠ΄Π°ΠΌΠΈ Ρ€Π°Π±ΠΎΡ‚Ρ‹ с Π½ΠΈΠΌΠΈ.

ΠœΠ°ΡΡΠΈΠ²Ρ‹ β€” Π½Π°Ρ€ΡƒΡˆΠ΅Π½ΠΈΠ΅ 1-ΠΉ Π½ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½ΠΎΠΉ Ρ„ΠΎΡ€ΠΌΡ‹, Π½ΠΎ ΠΊΠΎΠ³Π΄Π° всё, Ρ‡Ρ‚ΠΎ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ β€” это ΡΠΎΡ…Ρ€Π°Π½ΠΈΡ‚ΡŒ нСсколько строчСк, Ρ‚ΠΎ Π³ΠΎΡ€ΠΎΠΆΠ΄Π΅Π½ΠΈΠ΅ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎΠΉ Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ с пСрспСктивой JOIN'Π° с Π½Π΅ΠΉ выглядит совсСм Π½Π΅ΠΏΡ€ΠΈΠ²Π»Π΅ΠΊΠ°Ρ‚Π΅Π»ΡŒΠ½ΠΎ.

Π£ PostgreSQL ΠΏΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΎΠ½Π½Ρ‹ΠΉ DDL, Ρ‚.Π΅. ΠΌΠΎΠΆΠ½ΠΎ Π² транзакциях ΠΌΠ΅Π½ΡΡ‚ΡŒ схСму Π΄Π°Π½Π½Ρ‹Ρ…, ΠΈ эти измСнСния Π±ΡƒΠ΄Ρƒ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΎΠ½Π½Ρ‹ΠΌΠΈ. БоотвСтствСнно, Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹ ΠΌΠΈΠ³Ρ€Π°Ρ†ΠΈΠΈ Π±Π΅Π· остановки записи.

PostGIS. БСсплатноС Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΠ΅ для PostgreSQL с ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹ΠΌ исходным ΠΊΠΎΠ΄ΠΎΠΌ для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с гСографичСскими ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°ΠΌΠΈ, Π΄ΠΎΠΏΠΎΠ»Π½ΡΡŽΡ‰Π΅Π΅ встроСнныС возмоТности Π‘Π” (point, gist). Π Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ с Ρ‚ΠΎΡ‡ΠΊΠ°ΠΌΠΈ, Π»ΠΎΠΌΠ°Π½Ρ‹ΠΌΠΈ линиями, ΠΏΠΎΠ»ΠΈΠ³ΠΎΠ½Π°ΠΌΠΈ, растрами, Π° Ρ‚Π°ΠΊΠΆΠ΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ ΠΈΡ… для Ρ€Π°Π·Π½Ρ‹Ρ… ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, поиска.

PL/pgSQL. ΠŸΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Π½Ρ‹ΠΉ язык для PostgreSQL. Π€ΡƒΠ½ΠΊΡ†ΠΈΠΈ PL/pgSQL ΠΌΠΎΠ³ΡƒΡ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ Π²Π΅Π·Π΄Π΅, Π³Π΄Π΅ допустимы встроСнныС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ. НапримСр, ΠΌΠΎΠΆΠ½ΠΎ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ со слоТными вычислСниями ΠΈ условной Π»ΠΎΠ³ΠΈΠΊΠΎΠΉ, Π° Π·Π°Ρ‚Π΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΈΡ… ΠΏΡ€ΠΈ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠ² ΠΈΠ»ΠΈ Π² индСксных выраТСниях.

Полная SQL-ΡΠΎΠ²ΠΌΠ΅ΡΡ‚ΠΈΠΌΠΎΡΡ‚ΡŒ.

Π’Π»ΠΎΠΆΠ΅Π½Π½Ρ‹Π΅ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ

ΠœΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ нСявно задСйствован ΠΏΡ€ΠΈ создании Ρ‚ΠΎΡ‡Π΅ΠΊ сохранСния ΠΈ ΠΏΡ€ΠΈ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ΅ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΉ.

Π§Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠ΅ курсор ΠΈ Π·Π°Ρ‡Π΅ΠΌ ΠΎΠ½ Π½ΡƒΠΆΠ΅Π½?
Π§Ρ‚ΠΎ Π΄Π΅Π»Π°Π΅Ρ‚ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ JOIN, ΠΊΠ°ΠΊΠΈΠ΅ Π²ΠΈΠ΄Ρ‹ Π±Ρ‹Π²Π°ΡŽΡ‚?
Π§Ρ‚ΠΎ Π΄Π΅Π»Π°Π΅Ρ‚ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ HAVING, ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρ‹?
Π’ ΠΊΠ°ΠΊΠΈΡ… случаях Π²Ρ‹ Π±Ρ‹ ΠΏΡ€Π΅Π΄ΠΏΠΎΡ‡Π»ΠΈ Π½Π΅Ρ€Π΅Π»ΡΡ†ΠΈΠΎΠ½Π½ΡƒΡŽ Π‘Π”?
Π§Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½Ρ‹ΠΉ индСкс?

VACUUM

Команда VACUUM высвобоТдаСт пространство, Π·Π°Π½ΠΈΠΌΠ°Π΅ΠΌΠΎΠ΅ Β«ΠΌΠ΅Ρ€Ρ‚Π²Ρ‹ΠΌΠΈΒ» ΠΊΠΎΡ€Ρ‚Π΅ΠΆΠ°ΠΌΠΈ, Ρ‡Ρ‚ΠΎ Π°ΠΊΡ‚ΡƒΠ°Π»ΡŒΠ½ΠΎ для часто ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹Ρ… Ρ‚Π°Π±Π»ΠΈΡ†. ΠŸΡ€ΠΈ ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹Ρ… опСрациях Π² Postgres ΠΊΠΎΡ€Ρ‚Π΅ΠΆΠΈ, ΡƒΠ΄Π°Π»Π΅Π½Π½Ρ‹Π΅ ΠΈΠ»ΠΈ ΡƒΡΡ‚Π°Ρ€Π΅Π²ΡˆΠΈΠ΅ Π² Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹ обновлСния, физичСски Π½Π΅ ΡƒΠ΄Π°Π»ΡΡŽΡ‚ΡΡ, Π° ΡΠΎΡ…Ρ€Π°Π½ΡΡŽΡ‚ΡΡ Π² Ρ‚Π°Π±Π»ΠΈΡ†Π΅ Π΄ΠΎ очистки.

EXPLAIN, EXPLAIN ANALYZE

EXPLAIN ANALYZE – Π² ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ ΠΎΡ‚ просто EXPLAIN Π½Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ ΠΏΠ»Π°Π½ выполнСния запроса, Π½ΠΎ ΠΈ нСпосрСдствСнно выполняСт запрос ΠΈ ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ Ρ€Π΅Π°Π»ΡŒΠ½ΠΎΠ΅ врСмя выполнСния.

Server side cursor

Бпособ Ρ€Π°Π±ΠΎΡ‚Ρ‹ с Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠΌ запроса Π² Π±Π°Π·Ρƒ Π΄Π°Π½Π½Ρ‹Ρ…, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ позволяСт Π½Π΅ Π·Π°Π³Ρ€ΡƒΠΆΠ°Ρ‚ΡŒ вСсь объСм Π΄Π°Π½Π½Ρ‹Ρ… Π² ΠΏΠ°ΠΌΡΡ‚ΡŒ, позволяСт Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ с большими объСмами Π΄Π°Π½Π½Ρ‹Ρ…. Π”ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΡƒΠ³Π»ΡƒΠ±Π»Π΅Π½Π½ΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠ³ΠΎΠ²ΠΎΡ€ΠΈΡ‚ΡŒ ΠΏΡ€ΠΎ особСнности Ρ€Π°Π±ΠΎΡ‚Ρ‹ Π² связкС с pgbouncer.

Π­Ρ‚ΠΎ Π»ΡŽΠ±ΠΈΡ‚Π΅Π»ΠΈ mysql принСсли 8 Π³Π»Π°Π²Ρƒ своСй Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ, Π³Π΄Π΅ эта ΡˆΡ‚ΡƒΠΊΠ° Ρƒ Π½ΠΈΡ… называСтся optimizer ΠΈ состоит ΠΈΠ· Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… частСй (query planner, собствСнно query optimizer ΠΈ Ρ‚.Π΄.)

Π’ postgresql (ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΡ… Π±Π°Π·Π°Ρ…) это Π½Π°Π·Ρ‹Π²Π°ΡŽΡ‚ planner ΠΈ Π² русскоязычном IT Π² аспСктС Π‘Π” (Π½Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ postgres) принято слово ΠΈΠΌΠ΅Π½Π½ΠΎ Ρ‡Ρ‚ΠΎ "ΠΏΠ»Π°Π½ΠΈΡ€ΠΎΠ²Ρ‰ΠΈΠΊ". Ну Π° Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π»ΡŽΠ±ΠΈΡ‚Π΅Π»ΠΈ mysql словом "ΠΏΠ»Π°Π½ΠΈΡ€ΠΎΠ²Ρ‰ΠΈΠΊ" с Π΄Π°Π²Π½ΠΈΡ… ΠΏΠΎΡ€ Π½Π°Π·Ρ‹Π²Π°ΡŽΡ‚ ΠΏΠΎΡ‡Π΅ΠΌΡƒ-Ρ‚ΠΎ event/job scheduler, вас Π² ΠΎΠ±Ρ‰Π΅ΠΌ случаС Π²ΠΎΠ»Π½ΠΎΠ²Π°Ρ‚ΡŒ Π½Π΅ Π΄ΠΎΠ»ΠΆΠ½ΠΎ, это Ρƒ Π½ΠΈΡ… Ρ‚Π°ΠΌ своя атмосфСра.

НСт, это всё ΠΈΠ·Π΄Π΅Ρ€ΠΆΠΊΠΈ пСрСноса англоязычной Ρ‚Π΅Ρ€ΠΌΠΈΠ½ΠΎΠ»ΠΎΠ³ΠΈΠΈ Π½Π° русский язык. Каким ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ Ρ‚Π°ΠΊ ΡΠ»ΡƒΡ‡ΠΈΠ»ΠΎΡΡŒ, Ρ‡Ρ‚ΠΎ Π² русском scheduler стал ΠΏΠ»Π°Π½ΠΈΡ€ΠΎΠ²Ρ‰ΠΈΠΊΠΎΠΌ, я внятно ΠΎΠ±ΡŠΡΡΠ½ΠΈΡ‚ΡŒ Π½Π΅ ΠΌΠΎΠ³Ρƒ.

Schedule β€” это Π²ΠΎΠΎΠ±Ρ‰Π΅-Ρ‚ΠΎ Π³Ρ€Π°Ρ„ΠΈΠΊ (дСТурств), расписаниС (дСйствий). ΠŸΠ»Π°Π½ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΊΠ°ΠΊ составлСниС ΠΏΠ»Π°Π½Π° дСйствий, здСсь отсутствуСт, расписаниС β€” ΠΏΡ€ΠΎΠ΄ΡƒΠΊΡ‚ планирования, Π° Π½Π΅ процСсс. И scheduler Π² этом смыслС β€” это ΠΈΡΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒ расписания, Π° Π½Π΅ Π΅Π³ΠΎ ΡΠΎΡΡ‚Π°Π²ΠΈΡ‚Π΅Π»ΡŒ.

Plan β€” это Π² Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ смыслС Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ, ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ шагов ΠΏΡ€ΠΈ исполнСнии ΠΊΠ°ΠΊΠΎΠ³ΠΎ-Π»ΠΈΠ±ΠΎ дСйствия (ΠΈΠ·, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, расписания).

Optimize β€” Π² ΠΎΠ±Ρ‰Π΅ΠΌ случаС ΡƒΠ»ΡƒΡ‡ΡˆΠ΅Π½ΠΈΠ΅ этого самого Plan.

ΠŸΠΎΠ΄Ρ‹Ρ‚ΠΎΠΆΠΈΠΌ:

scheduler β€” Ρ…Ρ€Π°Π½ΠΈΡ‚ Ρ‚Π°Π±Π»ΠΈΡ†Ρƒ, расписаниС выполнСния Π·Π°Π΄Π°Ρ‡, ΠΈ обСспСчиваСт ΠΈΡ… запуск ΠΏΠΎ этому Ρ€Π°ΡΠΏΠΈΡΠ°Π½ΠΈΡŽ;

planner β€” составляСт ΠΏΠ»Π°Π½ дСйствий для исполнСния ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠ³ΠΎ запроса (Π° EXPLAIN Π΅Π³ΠΎ, этот ΠΏΠ»Π°Π½, ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚);

optimizer β€” Ρ‡Π°ΡΡ‚ΡŒ planner'Π° (ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈ ΠΎΡ‚ΡΡƒΡ‚ΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ). НапримСр, пСрСупорядочиваСт дСйствия, ΠΈΡΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½Ρ‹Π΅ дСйствия, ΠΈ Ρ‚.ΠΏ.

Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ получаСтся, Ρ‡Ρ‚ΠΎ ΠΈΠΌΠ΅Π½Π½ΠΎ Π² PostgreSQL всё ΠΊΠ°ΠΊ Ρ€Π°Π· Ρ‚Π°ΠΊΠΈ ΠΈ называСтся ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎ:

Π˜ΡΡ‚ΠΎΡ‡Π½ΠΈΠΊΠΈ

Π•. П. ΠœΠΎΡ€Π³ΡƒΠ½ΠΎΠ². PostgreSQL. ΠžΡΠ½ΠΎΠ²Ρ‹ языка SQL.

10. Π‘Π΅Ρ‚Π΅Π²Ρ‹Π΅ возмоТности

«Из Π²Ρ€Π°Ρ‚ этого Π³ΠΎΡ€ΠΎΠ΄Π° исходил ΠΈΠ·ΡƒΠΌΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ Π°Ρ€ΠΎΠΌΠ°Ρ‚, ΠΈ Ρ‚ΠΎΡ‚, ΠΊΡ‚ΠΎ Π΅Π³ΠΎ Π²Π΄Ρ‹Ρ…Π°Π», избавлялся ΠΎΡ‚ горСсти ΠΈ усталости».

Π―ΠΊΠΎΠ² Ворагинский, «Золотая Π»Π΅Π³Π΅Π½Π΄Π°Β».

Net

REST, Restfull

HTTP. КакиС Ρƒ Π½Π΅Π³ΠΎ Π΅ΡΡ‚ΡŒ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹? КакиС ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ Π² HTTP ΠΈΠ΄Π΅ΠΌΠΏΠΎΡ‚Π΅Π½Ρ‚Π½Ρ‹Π΅, Π° ΠΊΠ°ΠΊΠΈΠ΅ β€” Π½Π΅Ρ‚?

HTTP ΠΈ HTTPS

CSRF-token

44 Авторизация ΠΈ аутСнтификация

ΠžΡΠ½ΠΎΠ²Ρ‹ Ρ€Π°Π±ΠΎΡ‚Ρ‹ ΠΈΠ½Ρ‚Π΅Ρ€Π½Π΅Ρ‚Π°. ПониманиС основных ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»ΠΎΠ², ΠΌΠΎΠ΄Π΅Π»Π΅ΠΉ OSI/TCP IP. Π§Π°Ρ‰Π΅ всСго ΠΌΠΎΠΆΠ½ΠΎ Π·Π°Π΄Π°Ρ‚ΡŒ «простой» вопрос β€” Ρ‡Ρ‚ΠΎ происходит Β«Π·Π° ΡˆΠΈΡ€ΠΌΠΎΠΉΒ», ΠΊΠΎΠ³Π΄Π° Π² поискС вбиваСшь Google.com.

Π§Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠ΅ REST?

REST (Representational state transfer) – соглашСниС ΠΎ Ρ‚ΠΎΠΌ, ΠΊΠ°ΠΊ Π²Ρ‹ΡΡ‚Ρ€Π°ΠΈΠ²Π°Ρ‚ΡŒ сСрвисы. Под REST часто ΠΈΠΌΠ΅ΡŽΡ‚ Π² Π²ΠΈΠ΄Ρƒ Ρ‚.Π½ HTTP REST API. Как ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ, это Π²Π΅Π±-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ с Π½Π°Π±ΠΎΡ€ΠΎΠΌ ΡƒΡ€Π»ΠΎΠ² – ΠΊΠΎΠ½Π΅Ρ‡Π½Ρ‹Ρ… Ρ‚ΠΎΡ‡Π΅ΠΊ. Π£Ρ€Π»Ρ‹ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°ΡŽΡ‚ ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‚ Π΄Π°Π½Π½Ρ‹Π΅ Π² Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π΅ JSON. Π’ΠΈΠΏ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ Π·Π°Π΄Π°ΡŽΡ‚ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠΌ HTTP-запроса, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€:

GET – ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΈΠ»ΠΈ список ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² POST – ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ PUT – ΠΎΠ±Π½ΠΎΠ²ΠΈΡ‚ΡŒ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ DELETE – ΡƒΠ΄Π°Π»ΠΈΡ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ HEAD – ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΌΠ΅Ρ‚Π°Π΄Π°Π½Π½Ρ‹Π΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° REST-Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π° Π°ΠΊΡ‚ΠΈΠ²Π½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ возмоТности ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Π° HTTP, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΠ·Π±Π΅ΠΆΠ°Ρ‚ΡŒ Ρ‚.Π½. β€œΠ²Π΅Π»ΠΎΡΠΈΠΏΠ΅Π΄ΠΎΠ²β€ – собствСнных Ρ€Π΅ΡˆΠ΅Π½ΠΈΠΉ. НапримСр, ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ ΠΊΠ΅ΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡ ΠΏΠ΅Ρ€Π΅Π΄Π°ΡŽΡ‚ΡΡ стандартными Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ°ΠΌΠΈ Cache, If-Modified-Since, ETag. Авторизациция – Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΎΠΌ Authentication.

Π§Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠ΅ CSRF?

Cross Site Request Forgery (мСТсайтовая ΠΏΠΎΠ΄Π΄Π΅Π»ΠΊΠ° запроса). Π’ΠΈΠ΄ уязвимости, ΠΊΠΎΠ³Π΄Π° сайт А Π²Ρ‹Π½ΡƒΠΆΠ΄Π°Π΅Ρ‚ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ запрос Π½Π° сайт Π‘. Π­Ρ‚ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Ρ‚Π΅Π³ img ΠΈΠ»ΠΈ script для GET-запроса, ΠΈΠ»ΠΈ Ρ„ΠΎΡ€ΠΌΠ° со ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½Ρ‹ΠΌ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ΠΎΠΌ target.

Π§Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€Π΅Π΄ΠΎΡ‚Π²Ρ€Π°Ρ‚ΠΈΡ‚ΡŒ ΡƒΡΠ·Π²ΠΈΠΌΠΎΡΡ‚ΡŒ, сайт Π‘ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΡƒΠ±Π΅Π΄ΠΈΡ‚ΡŒΡΡ, Ρ‡Ρ‚ΠΎ запрос ΠΏΡ€ΠΈΡˆΠ΅Π» ΠΈΠΌΠ΅Π½Π½ΠΎ с Π΅Π³ΠΎ страницы.

НапримСр, ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π·Π°ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ Ρ„ΠΎΡ€ΠΌΡƒ. Π’ Π½Π΅Π΅ ΠΏΠΎΠΌΠ΅Ρ‰Π°ΡŽΡ‚ скрытоС ΠΏΠΎΠ»Π΅ token – ΠΎΠ΄Π½ΠΎΡ€Π°Π·ΠΎΠ²ΡƒΡŽ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ символов. Π­Ρ‚ΠΎΡ‚ ΠΆΠ΅ Ρ‚ΠΎΠΊΠ΅Π½ ΡΠΎΡ…Ρ€Π°Π½ΡΡŽΡ‚ Π² ΠΊΡƒΠΊΠΈ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ. ΠŸΡ€ΠΈ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠ΅ Ρ„ΠΎΡ€ΠΌΡ‹ ΠΏΠΎΠ»Π΅ ΠΈ ΠΊΡƒΠΊΠΈ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΡΠΎΠ²ΠΏΠ°ΡΡ‚ΡŒ. Бпособ Π½Π΅ являСтся Π½Π°Π΄Π΅ΠΆΠ½Ρ‹ΠΌ ΠΈ обходится скриптом.

HTTP Как устроСн ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ» HTTP?

HTTP – тСкстовый ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ», Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‰ΠΈΠΉ ΠΏΠΎΠ²Π΅Ρ€Ρ… TCP/IP. HTTP состоит ΠΈΠ· запроса ΠΈ ΠΎΡ‚Π²Π΅Ρ‚Π°. Π˜Ρ… структуры ΠΏΠΎΡ…ΠΎΠΆΠΈ: стартовая строка, Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ, Ρ‚Π΅Π»ΠΎ ΠΎΡ‚Π²Π΅Ρ‚Π°.

Бтартовая строка запроса состоит ΠΈΠ· ΠΌΠ΅Ρ‚ΠΎΠ΄Π°, ΠΏΡƒΡ‚ΠΈ ΠΈ вСрсии ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Π°:

GET /index.html HTTP/1.1 Бтартовая строка ΠΎΡ‚Π²Π΅Ρ‚Π° состоит ΠΈΠ· вСрсии ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Π°, ΠΊΠΎΠ΄Π° ΠΎΡ‚Π²Π΅Ρ‚Π° ΠΈ тСкстовой Ρ€Π°ΡΡˆΠΈΡ„Ρ€ΠΎΠ²ΠΊΠ΅ ΠΎΡ‚Π²Π΅Ρ‚Π°.

HTTP/1.1 200 OK Π—Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ – это Π½Π°Π±ΠΎΡ€ ΠΏΠ°Ρ€ ΠΊΠ»ΡŽΡ‡-Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, User-Agent, Content-Type. Π’ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ°Ρ… ΠΏΠ΅Ρ€Π΅Π΄Π°ΡŽΡ‚ ΠΌΠ΅Ρ‚Π°Π΄Π°Π½Π½Ρ‹Π΅ запроса: язык ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ, Π°Π²Ρ‚ΠΎΡ€ΠΈΠ·Π°Ρ†ΠΈΡŽ, ΠΏΠ΅Ρ€Π΅Π½Π°ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅. Π—Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ Host Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ Π² запросС всСгда.

Π’Π΅Π»ΠΎ ΠΎΡ‚Π²Π΅Ρ‚Π° ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ пустым, Π»ΠΈΠ±ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Ρ‚ΡŒ ΠΏΠ°Ρ€Ρ‹ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ…, Ρ„Π°ΠΉΠ»Ρ‹, Π±ΠΈΠ½Π°Ρ€Π½Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅. Π’Π΅Π»ΠΎ отдСляСтся ΠΎΡ‚ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΎΠ² пустой строкой.

ΠΠ°ΠΏΠΈΡΠ°Ρ‚ΡŒ raw запрос Π³Π»Π°Π²Π½ΠΎΠΉ ЯндСкса

GET / HTTP/1.1 Host: ya.ru

Как ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ ΠΏΠΎΠ½ΡΡ‚ΡŒ, удался запрос ΠΈΠ»ΠΈ Π½Π΅Ρ‚?

ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ статус ΠΎΡ‚Π²Π΅Ρ‚Π°. ΠžΡ‚Π²Π΅Ρ‚Ρ‹ Ρ€Π°Π·Π΄Π΅Π»Π΅Π½Ρ‹ ΠΏΠΎ ΡΡ‚Π°Ρ€ΡˆΠ΅ΠΌΡƒ разряду. ИмССм ΠΏΡΡ‚ΡŒ Π³Ρ€ΡƒΠΏΠΏ со ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ сСмантикой:

1xx: ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ ΠΊΡ€Π°ΠΉΠ½Π΅ Ρ€Π΅Π΄ΠΊΠΎ. Π’ этой Π³Ρ€ΡƒΠΏΠΏΠ΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄ΠΈΠ½ статус 100 Continue. 2xx: запрос ΠΏΡ€ΠΎΡˆΠ΅Π» ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ (Π΄Π°Π½Π½Ρ‹Π΅ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Ρ‹ ΠΈΠ»ΠΈ созданы) 3xx: ΠΏΠ΅Ρ€Π΅Π½Π°ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ Π½Π° Π΄Ρ€ΡƒΠ³ΠΎΠΉ рСсурс 4xx: ошибка ΠΏΠΎ Π²ΠΈΠ½Π΅ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ (Π½Π΅Ρ‚ Ρ‚Π°ΠΊΠΎΠΉ страницы, Π½Π΅Ρ‚ ΠΏΡ€Π°Π² Π½Π° доступ) 5xx: ошибка ΠΏΠΎ Π²ΠΈΠ½Π΅ сСрвСра (ошибка Π² ΠΊΠΎΠ΄Π΅, сСти, ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ) Π§Ρ‚ΠΎ Π½ΡƒΠΆΠ½ΠΎ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Ρƒ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠ΅Ρ€Π΅Π½Π°ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ Π½Π° Π΄Ρ€ΡƒΠ³ΡƒΡŽ страницу?

ΠœΠΈΠ½ΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΉ ΠΎΡ‚Π²Π΅Ρ‚ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΈΠΌΠ΅Ρ‚ΡŒ статус 301 ΠΈΠ»ΠΈ 302. Π—Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ Location ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ адрСс рСсурса, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ слСдуСт ΠΏΠ΅Ρ€Π΅ΠΉΡ‚ΠΈ.

Π’ Ρ‚Π΅Π»Π΅ ΠΎΡ‚Π²Π΅Ρ‚Π° ΠΌΠΎΠΆΠ½ΠΎ Ρ€Π°Π·ΠΌΠ΅ΡΡ‚ΠΈΡ‚ΡŒ HTML со ссылкой Π½Π° Π½ΠΎΠ²Ρ‹ΠΉ рСсурс. Π’ΠΎΠ³Π΄Π° ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΠΈ старых Π±Ρ€Π°ΡƒΠ·Π΅Ρ€ΠΎΠ² смогут ΠΏΠ΅Ρ€Π΅ΠΉΡ‚ΠΈ Π²Ρ€ΡƒΡ‡Π½ΡƒΡŽ.

Как ΡƒΠΏΡ€Π°Π²Π»ΡΡ‚ΡŒ ΠΊΠ΅ΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ Π² HTTP?

Π‘ΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‚ нСсколько способов ΠΊΠ΅ΡˆΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅ Π½Π° ΡƒΡ€ΠΎΠ²Π½Π΅ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Π°.

Π—Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ Cache ΠΈ Cache-Control Ρ€Π΅Π³ΡƒΠ»ΠΈΡ€ΡƒΡŽΡ‚ сразу нСсколько ΠΊΡ€ΠΈΡ‚Π΅Ρ€ΠΈΠ΅Π² кСша: врСмя ΠΆΠΈΠ·Π½ΠΈ, ΠΏΠΎΠ»ΠΈΡ‚ΠΈΠΊΡƒ обновлСния, ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ прокси-сСрвСра, Ρ‚ΠΈΠΏ Π΄Π°Π½Π½Ρ‹Ρ… (ΠΏΡƒΠ±Π»ΠΈΡ‡Π½Ρ‹Π΅, ΠΏΡ€ΠΈΠ²Π°Ρ‚Π½Ρ‹Π΅). Π—Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ Last-Modified ΠΈ If-Modified-Since Π·Π°Π΄Π°ΡŽΡ‚ ΠΊΠ΅ΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π² зависимости ΠΎΡ‚ Π΄Π°Ρ‚Ρ‹ обновлСния Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°. Π—Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ Etag ΠΊΠ΅ΡˆΠΈΡ€ΡƒΠ΅Ρ‚ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚ ΠΏΠΎ Π΅Π³ΠΎ ΡƒΠ½ΠΈΠΊΠ°Π»ΡŒΠ½ΠΎΠΌΡƒ Ρ…Π΅ΡˆΡƒ. Как ΠΊΡΡˆΠΈΡ€ΡƒΡŽΡ‚ΡΡ Ρ„Π°ΠΉΠ»Ρ‹ Π½Π° ΡƒΡ€ΠΎΠ²Π½Π΅ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Π°?

Когда Nginx ΠΎΡ‚Π΄Π°Π΅Ρ‚ статичный Ρ„Π°ΠΉΠ», ΠΎΠ½ добавляСт Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ Etag – MD5-Ρ…Π΅Ρˆ Ρ„Π°ΠΉΠ»Π°. ΠšΠ»ΠΈΠ΅Π½Ρ‚ Π·Π°ΠΏΠΎΠΌΠΈΠ½Π°Π΅Ρ‚ этот Ρ…Π΅Ρˆ. Π’ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ Ρ€Π°Π· ΠΏΡ€ΠΈ запросС Ρ„Π°ΠΉΠ»Π° ΠΊΠ»ΠΈΠ΅Π½Ρ‚ посылаСт Ρ…Π΅Ρˆ. Π‘Π΅Ρ€Π²Π΅Ρ€ провСряСт Ρ…Π΅Ρˆ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° для этого Ρ„Π°ΠΉΠ»Π°. Если Ρ…Π΅Ρˆ Π½Π΅ совпадаСт (Ρ„Π°ΠΉΠ» ΠΎΠ±Π½ΠΎΠ²ΠΈΠ»ΠΈ), сСрвСр ΠΎΡ‚Π²Π΅Ρ‡Π°Π΅Ρ‚ с ΠΊΠΎΠ΄ΠΎΠΌ 200 ΠΈ Π²Ρ‹Π³Ρ€ΡƒΠΆΠ°Π΅Ρ‚ Π°ΠΊΡ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹ΠΉ Ρ„Π°ΠΉΠ» с Π½ΠΎΠ²Ρ‹ΠΌ Ρ…Π΅ΡˆΠ΅ΠΌ. Если Ρ…Π΅ΡˆΠΈ Ρ€Π°Π²Π½Ρ‹, сСрвСр ΠΎΡ‚Π²Π΅Ρ‡Π°Π΅Ρ‚ с ΠΊΠΎΠ΄ΠΎΠΌ 304 Not Modified с пустым Ρ‚Π΅Π»ΠΎΠΌ. Π’ этом случаС Π±Ρ€Π°ΡƒΠ·Π΅Ρ€ подставляСт Π»ΠΎΠΊΠ°Π»ΡŒΠ½ΡƒΡŽ копию Ρ„Π°ΠΉΠ»Π°.

nginx vs Apache

Всё просто β€” Π½ΡƒΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ nginx всСгда, ΠΊΠΎΠ³Π΄Π° Π΅ΡΡ‚ΡŒ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ. Apache β€” для ΡˆΠ°Ρ€Π΅Π΄ хостингов, Π½ΠΎ Π΄Π°ΠΆΠ΅ Π½Π° ΡˆΠ°Ρ€Π΅Π΄ хостингах часто Ρ„Ρ€ΠΎΠ½Ρ‚Π΅Π½Π΄ΠΎΠΌ стоит nginx (Π±Π΅Π· возмоТности настройки), Π° ΡƒΠΆΠ΅ Π·Π° Π½ΠΈΠΌ β€” настраиваСмый Apache ΠΈ настраиваСмый PHP.

АрхитСктура: Apache слздаСт ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ соСдинСния, nginx Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ ΠΏΠΎ асинхронной ΠΌΠΎΠ΄Π΅Π»ΠΈ. БтатичСский ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚: nginx Π² 2 Ρ€Π°Π·Π° быстрСС Apache. ДинамичСский ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚: Π½ΠΈΡ‡ΡŒΡ. Π€ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»: Apache Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Π°Π½ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΊΠ°ΠΊ Π²Π΅Π±-сСрвСр, nginx ΠΌΠΎΠΆΠ΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ ΠΈ ΠΊΠ°ΠΊ Π²Π΅Π±-сСрвСр, Ρ‚Π°ΠΊ ΠΈ ΠΊΠ°ΠΊ прокси-сСрвСр. Настройка: nginx ΠΏΡ€ΠΎΡ‰Π΅ Π² настройкС.

11. АрхитСктура ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½ΠΎΠ³ΠΎ обСспСчСния

Β«Π’ Π·Π°Π»Π΅ ΠΊΠ»ΡƒΠ±ΠΈΠ»ΠΈΡΡŒ ΠΌΠ½ΠΎΠ³ΠΎΡ†Π²Π΅Ρ‚Π½Ρ‹Π΅ ΠΎΠ±Π»Π°ΠΊΠ° β€” символы ΡΡ‡Π°ΡΡ‚ΡŒΡ, Π²ΠΎΠ·Π΄ΡƒΡ… Π±Ρ‹Π» Π½Π°ΠΏΠΎΠ΅Π½ нСТнСйшим Π°Ρ€ΠΎΠΌΠ°Ρ‚ΠΎΠΌ. ΠŸΠ»Ρ‹Π»ΠΈ Ρ‚ΠΈΡ…ΠΈΠ΅ Π·Π²ΡƒΠΊΠΈ, ΠΈ Π² Ρ‚ΠΎ ΠΆΠ΅ врСмя Π²ΠΎΠΊΡ€ΡƒΠ³ Ρ†Π°Ρ€ΠΈΠ»ΠΎ Π±Π΅Π·ΠΌΠΎΠ»Π²ΠΈΠ΅Β».

Π›ΠΈΠ½ ΠœΡΠ½Π³Ρƒ, Β«ΠŸΡƒΡ‚ΡŒ ΠΊ Π·Π°ΠΎΠ±Π»Π°Ρ‡Π½Ρ‹ΠΌ Π²Ρ€Π°Ρ‚Π°ΠΌΒ».

Architecture

Π§Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠ΅ Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π°

SOLID

ИспользованиС ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΠΎΠ² SOLID ΠΏΠΎΠΌΠΎΠ³Π°Π΅Ρ‚ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ Ρ€Π°ΡΡˆΠΈΡ€ΡΠ΅ΠΌΡ‹Π΅ ΠΈ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅ΠΌΡ‹Π΅ систСмы. ΠŸΡ€ΠΈΠ½Ρ†ΠΈΠΏΡ‹ SOLID Ρ‚Π°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π² качСствС ΠΎΡ€ΠΈΠ΅Π½Ρ‚ΠΈΡ€ΠΎΠ² Π² процСссС Ρ€Π΅Ρ„Π°ΠΊΡ‚ΠΎΡ€ΠΈΠ½Π³Π° ΠΊΠΎΠ΄Π°.

SRP

Single-responsibility principle, ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏ СдинствСнной отвСтствСнности. ΠŸΡ€Π΅Π΄ΠΏΠΎΠ»Π°Π³Π°Π΅Ρ‚ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ классов, ΠΈΠΌΠ΅ΡŽΡ‰ΠΈΡ… Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄Π½Ρƒ ΠΏΡ€ΠΈΡ‡ΠΈΠ½Ρƒ для измСнСния, позволяСт вСсти ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π² Π½Π°ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠΈ, ΠΏΡ€ΠΎΡ‚ΠΈΠ²ΠΎΠΏΠΎΠ»ΠΎΠΆΠ½ΠΎΠΌ созданию «БоТСствСнных ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ²Β». Класс Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΎΡ‚Π²Π΅Ρ‡Π°Ρ‚ΡŒ Π·Π° ΡƒΠ΄ΠΎΠ²Π»Π΅Ρ‚Π²ΠΎΡ€Π΅Π½ΠΈΠ΅ запросов Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄Π½ΠΎΠΉ Π³Ρ€ΡƒΠΏΠΏΡ‹ Π»ΠΈΡ†.

OCP

Open–closed principle, ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏ открытости/закрытости. ΠšΠ»Π°ΡΡΡ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ Π·Π°ΠΊΡ€Ρ‹Ρ‚Ρ‹ ΠΎΡ‚ измСнСния (Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΊΠΎΠ΄, ΠΎΠΏΠΈΡ€Π°ΡŽΡ‰ΠΈΠΉΡΡ Π½Π° эти классы, Π½Π΅ нуТдался Π² ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠΈ), Π½ΠΎ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹ для Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡ (классу ΠΌΠΎΠΆΠ½ΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Π½ΠΎΠ²ΠΎΠ΅ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅). Π’ΠΊΡ€Π°Ρ‚Ρ†Π΅ β€” Ρ…ΠΎΡ‡Π΅ΡˆΡŒ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ класса β€” ΠΎΡΡ‚Π°Π²ΡŒ Π² нСприкосновСнности старый ΠΊΠΎΠ΄ (Π½Π΅ считая Ρ€Π΅Ρ„Π°ΠΊΡ‚ΠΎΡ€ΠΈΠ½Π³Π°, Ρ‚. Π΅. ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ Π±Π΅Π· измСнСния внСшнСго повСдСния), добавь Π½ΠΎΠ²Ρ‹ΠΉ. Если Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΠ΅ Ρ‚Ρ€Π΅Π±ΠΎΠ²Π°Π½ΠΈΠΉ Π²Π΅Π΄Π΅Ρ‚ ΠΊ Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ измСнСниям Π² ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰Π΅ΠΌ ΠΊΠΎΠ΄Π΅, Π·Π½Π°Ρ‡ΠΈΡ‚, Π±Ρ‹Π»ΠΈ Π΄ΠΎΠΏΡƒΡ‰Π΅Π½Ρ‹ Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π½Ρ‹Π΅ ошибки.

LSP

Liskov substitution principle, ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏ подстановки Π‘Π°Ρ€Π±Π°Ρ€Ρ‹ Лисков: ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ Π½Π°ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΡ… классов Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π±Ρ‹Ρ‚ΡŒ ΠΎΠΆΠΈΠ΄Π°Π΅ΠΌΡ‹ΠΌ для ΠΊΠΎΠ΄Π°, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰Π΅Π³ΠΎ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ Π±Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ класса. Или, Π΄Ρ€ΡƒΠ³ΠΈΠΌΠΈ словами, подкласс Π½Π΅ Π΄ΠΎΠ»ΠΆΠ΅Π½ Ρ‚Ρ€Π΅Π±ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΡ‚ Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‰Π΅Π³ΠΎ ΠΊΠΎΠ΄Π° большС, Ρ‡Π΅ΠΌ Π±Π°Π·ΠΎΠ²Ρ‹ΠΉ класс, ΠΈ Π½Π΅ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΏΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²Π»ΡΡ‚ΡŒ Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‰Π΅ΠΌΡƒ ΠΊΠΎΠ΄Ρƒ мСньшС, Ρ‡Π΅ΠΌ Π±Π°Π·ΠΎΠ²Ρ‹ΠΉ класс.

ISP

Interface segregation principle, ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏ раздСлСния интСрфСйса. ΠšΠ»ΠΈΠ΅Π½Ρ‚ интСрфСйса Π½Π΅ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π·Π°Π²ΠΈΡΠ΅Ρ‚ΡŒ ΠΎΡ‚ Π½Π΅ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹Ρ… ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ². Π’ соотвСтствии с ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΠΎΠΌ ISP рСкомСндуСтся ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ минималистичныС интСрфСйсы, содСрТащиС минимальноС количСство спСцифичных ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ². Если ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ интСрфСйса Π½Π΅ ΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ ΠΊΠ°ΠΊΠΈΠΌ-Π»ΠΈΠ±ΠΎ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠΌ интСрфСйса, Ρ‚ΠΎ Π»ΡƒΡ‡ΡˆΠ΅ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ Π½ΠΎΠ²Ρ‹ΠΉ интСрфСйс, Π±Π΅Π· этого ΠΌΠ΅Ρ‚ΠΎΠ΄Π°.

DIP

Dependency inversion principle, ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏ инвСрсии зависимостСй. ΠœΠΎΠ΄ΡƒΠ»ΠΈ Π²Π΅Ρ€Ρ…Π½Π΅Π³ΠΎ уровня Π½Π΅ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΎΠ±Ρ€Π°Ρ‰Π°Ρ‚ΡŒΡΡ ΠΊ модулям Π½ΠΈΠΆΠ½Π΅Π³ΠΎ уровня Π½Π°ΠΏΡ€ΡΠΌΡƒΡŽ, ΠΌΠ΅ΠΆΠ΄Ρƒ Π½ΠΈΠΌΠΈ Π΄ΠΎΠ»ΠΆΠ½Π° Π±Ρ‹Ρ‚ΡŒ Β«ΠΏΡ€ΠΎΠΊΠ»Π°Π΄ΠΊΠ°Β» ΠΈΠ· абстракций (Ρ‚. Π΅. интСрфСйсов). ΠŸΡ€ΠΈΡ‡Π΅ΠΌ абстракции Π½Π΅ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π·Π°Π²ΠΈΡΠ΅Ρ‚ΡŒ ΠΎΡ‚ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΉ, Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π·Π°Π²ΠΈΡΠ΅Ρ‚ΡŒ ΠΎΡ‚ абстракций.

KISS

Keep it simple, stupid β€” ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏ проСктирования ПО, Π² соотвтствии с ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ простота систСмы дСклариуСтся ΠΊΠ°ΠΊ ΠΎΠ΄Π½Π° ΠΈΠ· ΠΎΡΠ½ΠΎΠ²ΠΎΠΏΠΎΠ»Π°Π³Π°ΡŽΡ‰ΠΈΡ… цСнностСй (ΠΈΠ½ΠΎΠ³Π΄Π° Π΄Π°ΠΆΠ΅ простота ΠΎΠ±ΡŠΡΠ²Π»ΡΠ΅Ρ‚ΡΡ Π±ΠΎΠ»Π΅Π΅ Π²Π°ΠΆΠ½ΠΎΠΉ, Ρ‡Π΅ΠΌ Π»ΡŽΠ±Ρ‹Π΅ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ свойства систСмы, см. Worse is Better Π ΠΈΡ‡Π°Ρ€Π΄Π° ГэбриСла), ΠΎΠ΄Π½ΠΎ ΠΈΠ· практичСских ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ Β«Π‘Ρ€ΠΈΡ‚Π²Ρ‹ Оккама» β€” Π½Π΅ создавай Π½ΠΎΠ²Ρ‹Ρ… сущностСй Π±Π΅Π· ΠΊΡ€Π°ΠΉΠ½Π΅ΠΉ нСобходимости.

DRY

Don’t repeat yourself (Π½Π΅ повторяйся) β€” ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏ, Π² соотвСтствии с ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ любого элСмСнта систСмы Π½Π΅ Π΄ΠΎΠ»ΠΆΠ½ΠΎ Ρ‚Ρ€Π΅Π±ΠΎΠ²Π°Ρ‚ΡŒ внСсСния ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ Π² Π΄Ρ€ΡƒΠ³ΠΈΠ΅, логичСски Π½Π΅ связанныС элСмСнты. ЛогичСски ΠΆΠ΅ связанныС элСмСнты ΠΈΠ·ΠΌΠ΅Π½ΡΡŽΡ‚ΡΡ прСдсказуСмо ΠΈ Π΅Π΄ΠΈΠ½ΠΎΠΎΠ±Ρ€Π°Π·Π½ΠΎ.

YAGNI

You aren't gonna need it (Π²Π°ΠΌ это Π½Π΅ понадобится) β€” Ссли Π² ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»Π΅ Π½Π΅Ρ‚ потрСбности прямо здСсь ΠΈ прямо сСйчас β€” Π½Π΅ добавляй Π΅Π³ΠΎ. Π­Ρ‚ΠΈΠΌ Ρ‚Ρ‹ Π½Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΡ‚Π½ΠΈΠΌΠ΅ΡˆΡŒ врСмя, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎΠ΅ Π½Π° Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΡƒ ΠΈ тСстированиС Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»Π°, Π½ΠΎ ΠΈ моТСшь ΠΏΠΎΠ΄Π»ΠΎΠΆΠΈΡ‚ΡŒ сСбС ΠΌΠΈΠ½Ρƒ Π·Π°ΠΌΠ΅Π΄Π»Π΅Π½Π½ΠΎΠ³ΠΎ дСйствия Π½Π° Π±ΡƒΠ΄ΡƒΡ‰Π΅Π΅, ΠΊΠΎΠ³Π΄Π° ΠΊΠΎΠ½Ρ‚ΡƒΡ€Ρ‹ развития систСмы станут Π±ΠΎΠ»Π΅Π΅ Ρ‡Π΅Ρ‚ΠΊΠΈΠΌΠΈ.

Π‘Π²ΡΠ·Π½ΠΎΡΡ‚ΡŒ ΠΊΠΎΠ΄Π° ΠΈ code coupling

Π‘Π²ΡΠ·Π½ΠΎΡΡ‚ΡŒ ΠΊΠΎΠ΄Π° (cohesion) Ρ…Π°Ρ€Π°ΠΊΡ‚Π΅Ρ€ΠΈΠ·ΡƒΠ΅Ρ‚ Ρ†Π΅Π»ΠΎΡΡ‚Π½ΠΎΡΡ‚ΡŒ ΠΈΠ»ΠΈ «фокусировку» ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½ΠΎΠ³ΠΎ модуля, Ρ‚.Π΅. Ρ‚ΠΎ, насколько Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½ΠΈΠ΅ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ модуля логичСски связанны Π΄Ρ€ΡƒΠ³ с Π΄Ρ€ΡƒΠ³ΠΎΠΌ.

Π‘Ρ†Π΅ΠΏΠ»Π΅Π½ΠΈΠ΅ ΠΌΠΎΠ΄ΡƒΠ»Π΅ΠΉ (coupling) β€” ΡΡ‚Π΅ΠΏΠ΅Π½ΡŒ Π²Π·Π°ΠΈΠΌΠ½ΠΎΠΉ зависимости Ρ€Π°Π·Π½Ρ‹Ρ… ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½Ρ‹Ρ… ΠΌΠΎΠ΄ΡƒΠ»Π΅ΠΉ. БильноС Π·Π°Ρ†Π΅ΠΏΠ»Π΅Π½ΠΈΠ΅ β€” ΡΠ΅Ρ€ΡŒΡ‘Π·Π½Π°Ρ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ°, Ρ‚. ΠΊ. затрудняСт ΠΏΠ΅Ρ€Π΅ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Π½ΠΈΠ΅, Π°Π²Ρ‚ΠΎΠ½ΠΎΠΌΠ½ΠΎΠ΅ тСстированиС, ΠΈ Π΄Π°ΠΆΠ΅ просто ΠΌΠΎΠ΄ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΡŽ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Ρ… ΠΌΠΎΠ΄ΡƒΠ»Π΅ΠΉ. ЀактичСски, Π² условиях сильного зацСплСния приходится Ρ€Π°ΡΡΠΌΠ°Ρ‚Ρ€ΠΈΠ²Π°Ρ‚ΡŒ всю ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ΠΈΡ€ΡƒΠ΅ΠΌΡƒΡŽ систСму ΠΊΠ°ΠΊ ΠΎΠ΄ΠΈΠ½ ΠΌΠΎΠ΄ΡƒΠ»ΡŒ, Ρ‡Ρ‚ΠΎ, СстСствСнно Π²Π΅Π΄Π΅Ρ‚ ΠΊ росту ΠΊΠΎΠ³Π½ΠΈΡ‚ΠΈΠ²Π½ΠΎΠΉ Π½Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ, падСнию ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ ΠΈ росту количСства ошибок.

Π₯ΠΎΡ€ΠΎΡˆΠΎ спроСктированная систСма характСризуСтся высокой ΡΠ²ΡΠ·Π½ΠΎΡΡ‚ΡŒΡŽ ΠΈ Π½ΠΈΠ·ΠΊΠΈΠΌ сцСплСниСм.

ΠŸΠ°Ρ€Π°Π΄ΠΈΠ³ΠΌΡ‹ программирования

https://en.wikipedia.org/wiki/Programming_paradigm

ΠŸΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Π½ΠΎΠ΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅

ΠœΠ΅Ρ‚ΠΎΠ΄ΠΈΠΊΠ°, Π² соотвСтствии с ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ выполняСмыС ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹ ΡΠΎΠ±ΠΈΡ€Π°ΡŽΡ‚ Π² ΠΏΠΎΠ΄ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹, Ρ‚ΠΎ Π΅ΡΡ‚ΡŒ Π±ΠΎΠ»Π΅Π΅ ΠΊΡ€ΡƒΠΏΠ½Ρ‹Π΅ цСлостныС Π΅Π΄ΠΈΠ½ΠΈΡ†Ρ‹ ΠΊΠΎΠ΄Π°

Π‘Ρ‚Ρ€ΡƒΠΊΡ‚ΡƒΡ€Π½ΠΎΠ΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅

ПониманиС Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ ΠΎΠΏΡ€Π΅Π°Ρ‚ΠΎΡ€ goto ΠΈ ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²ΠΈΡ‚ΡŒ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ Π² Π²ΠΈΠ΄Π΅ иСрархичСской структуры Π±Π»ΠΎΠΊΠΎΠ² (ΠΈΠ· Ρ‚Ρ€Ρ‘Ρ… Π±Π°Π·ΠΎΠ²Ρ‹Ρ… ΡƒΠΏΡ€Π°Π²Π»ΡΡŽΡ‰ΠΈΡ… конструкций: ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ, Π²Π΅Ρ‚Π²Π»Π΅Π½ΠΈΠ΅, Ρ†ΠΈΠΊΠ»).

ΠšΠΎΠ½Ρ†Π΅ΠΏΡ†ΠΈΡ структурного ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠ»Π° ΡˆΠΈΡ€ΠΎΠΊΠΎΠ΅ распространСниС ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½ΠΎ Π² 1970-Ρ…, ΠΊΠΎΠ³Π΄Π° Π±Ρ‹Π»ΠΎ строго матСматичСски Π΄ΠΎΠΊΠ°Π·Π°Π°Π½ΠΎ, Ρ‡Ρ‚ΠΎ Π½Π° Π±Π°Π·Π΅ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ, вСтвлСния ΠΈ Ρ†ΠΈΠΊΠ»Π° ΠΌΠΎΠΆΠ½ΠΎ Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ Π»ΡŽΠ±ΡƒΡŽ, сколь ΡƒΠ³ΠΎΠ΄Π½ΠΎ ΡΠ»ΠΎΠΆΠ½ΡƒΡŽ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ, Π° ЭдсгСр ДСйкстра Π΄Π°ΠΆΠ΅ написал Π² 1968 ΡΡ‚Π°Ρ‚ΡŒΡŽ «О Π²Ρ€Π΅Π΄Π΅ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π° gotoΒ» (Β«A Case against the GO TO StatementΒ»).

На всякий случай, Ссли Π²Ρ‹ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΡƒΠ΅Ρ‚Π΅ Π½Π° языкС ассСмблСра ΠΈ ΡˆΠΈΡ€ΠΎΠΊΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚Π΅ условныС ΠΈ бСзусловныС ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄Ρ‹, это ΡΠΎΠ²Π΅Ρ€ΡˆΠ΅Π½Π½ΠΎ Π½ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½ΠΎ. Goto ΠΈ jmp соотносятся ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½ΠΎ Π½ΠΈΠΊΠ°ΠΊ.
jmp β€” благородная ассСмблСрная инструкция, вСтвящая исполнСниС ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹.
goto β€” ΠΊΠΎΡΡ‚Ρ‹Π»ΡŒ, ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‰ΠΈΠΉ Π½Π°Ρ‡ΠΈΠ½Π°ΡŽΡ‰Π΅ΠΌΡƒ программисту Π²Π½Π΅Π·Π°ΠΏΠ½ΠΎ Ρ‚Π΅Π»Π΅ΠΏΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒΡΡ Π² Π΄Ρ€ΡƒΠ³ΠΎΠ΅ мСсто ΠΊΠΎΠ΄Π°.
ΠžΠ±ΡŠΠ΅Π΄ΠΈΠ½ΡΠ΅Ρ‚ ΠΈΡ… Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ goto послС компиляции прСвращаСтся Π² jmp, Π½Ρƒ Ρ‚Π°ΠΊ ΠΈ for, ΠΈ if Ρ‚ΠΎΠΆΠ΅ ΠΏΡ€Π΅Π²Ρ€Π°Ρ‰Π°ΡŽΡ‚ΡΡ Π² jmp.

ΠžΠ±ΡŠΠ΅ΠΊΡ‚Π½ΠΎ-ΠΎΡ€ΠΈΠ΅Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅

ΠœΠ΅Ρ‚ΠΎΠ΄ΠΎΠ»ΠΎΠ³ΠΈΡ, основанная Π½Π° прСдставлСнии ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ Π² Π²ΠΈΠ΄Π΅ совокупности Π²Π·Π°ΠΈΠΌΠΎΠ΄Π΅ΠΉΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΡ… ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ², ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΈΠ· ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… являСтся экзСмпляром ΠΎΠΏΡ€Π΅Π΄Π΅Π»Ρ‘Π½Π½ΠΎΠ³ΠΎ класса, Π° классы ΠΎΠ±Ρ€Π°Π·ΡƒΡŽΡ‚ ΠΈΠ΅Ρ€Π°Ρ€Ρ…ΠΈΡŽ наслСдования.

Π€ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΠ΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅

ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π½Π° Π±Π°Π·Π΅ матСматичСских Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ. ΠœΠ°Ρ‚Π΅ΠΌΠ°Ρ‚ΠΈΡ‡Π΅ΡΠΊΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π½Π΅ ΡΠ²Π»ΡΡŽΡ‚ΡΡ ΠΌΠ΅Ρ‚ΠΎΠ΄Π°ΠΌΠΈ Π² ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½ΠΎΠΌ смыслС, ΠΈΡ… Π»ΡƒΡ‡ΡˆΠ΅ всСго Ρ€Π°ΡΡΠΌΠ°Ρ‚Ρ€ΠΈΠ²Π°Ρ‚ΡŒ ΠΊΠ°ΠΊ ΠΊΠ°Π½Π°Π» (pipe), ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΡƒΡŽΡ‰ΠΈΠΉ любоС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ ΠΌΡ‹ ΠΏΠ΅Ρ€Π΅Π΄Π°Π΅ΠΌ, Π² Π΄Ρ€ΡƒΠ³ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅.
ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½Ρ‹ΠΉ ΠΌΠ΅Ρ‚ΠΎΠ΄ становится матСматичСской Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ послС выполнСия Π΄Π²ΡƒΡ… Ρ‚Ρ€Π΅Π±ΠΎΠ²Π°Π½ΠΈΠΉ:

  1. Он Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ ссылочно ΠΏΡ€ΠΎΠ·Ρ€Π°Ρ‡Π½Ρ‹ΠΌ (referentially transparent). Бсылочно прозрачная функция всСгда Π΄Π°Π΅Ρ‚ ΠΎΠ΄ΠΈΠ½ ΠΈ Ρ‚ΠΎΡ‚ ΠΆΠ΅ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚, Ссли Π²Ρ‹ прСдоставляСтС Π΅ΠΉ ΠΎΠ΄Π½ΠΈ ΠΈ Ρ‚Π΅ ΠΆΠ΅ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Ρ‹; Π­Ρ‚ΠΎ ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ такая функция Π΄ΠΎΠ»ΠΆΠ½Π° Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ со значСниями, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΡ‹ ΠΏΠ΅Ρ€Π΅Π΄Π°Π΅ΠΌ, ΠΎΠ½Π° Π½Π΅ Π΄ΠΎΠ»ΠΆΠ½Π° ΡΡΡ‹Π»Π°Ρ‚ΡŒΡΡ Π½ΠΈ Π½Π° ΠΊΠ°ΠΊΠΈΠ΅ Π³Π»ΠΎΠ±Π°Π»ΡŒΠ½ΠΎΡ‹Π΅ состояния.
  2. Π‘ΠΈΠ³Π½Π°Ρ‚ΡƒΡ€Π° ΠΌΠ΅Ρ‚ΠΎΠ΄Π° Π΄ΠΎΠ»ΠΆΠ½Π° ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Ρ‚ΡŒ всю ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Ρ… ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅ΠΌΡ‹Ρ… Π²Ρ…ΠΎΠ΄Π½Ρ‹Ρ… значСниях, ΠΈ ΠΎ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Ρ… Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π°Ρ…, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΎΠ½ Π²Ρ‹Π΄Π°Π΅Ρ‚.

ΠŸΡ€Π΅ΠΈΠΌΡƒΡ‰Π΅ΡΡ‚Π²ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ программирования β€” ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½Π°Ρ простота, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΌΠ΅Ρ‚ΠΎΠ΄, Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‰ΠΈΠΉ Π΄Π²Π° трСбования, ΡƒΠΊΠ°Π·Π°Π½Π½Ρ‹Ρ… Π²Ρ‹ΡˆΠ΅, ΠΌΠΎΠΆΠ½ΠΎ Ρ€Π°ΡΡΠΌΠ°Ρ‚Ρ€ΠΈΠ²Π°Ρ‚ΡŒ ΠΈ ΠΎΡ‚Π»Π°ΠΆΠΈΠ²Π°Ρ‚ΡŒ Π² условиях ΠΏΠΎΠ»Π½ΠΎΠΉ изоляции ΠΎΡ‚ ΠΎΡΡ‚Π°Π»ΡŒΠ½ΠΎΠΉ ΠΊΠΎΠ΄ΠΎΠ²ΠΎΠΉ Π±Π°Π·Ρ‹. Плюс, ΠΈΠΌΠΌΡƒΡ‚Π°Π±Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ позволяСт компилятору ΠΏΡ€ΠΈΠΌΠ΅Π½ΡΡ‚ΡŒ Π±ΠΎΠ»Π΅Π΅ агрСссивныС ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΠΈ.

ΠžΡΠ½ΠΎΠ²Π½Ρ‹Π΅ ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΡ‹ ООП

НаслСдованиС

Π‘ΠΏΠΎΡΠΎΠ±Π½ΠΎΡΡ‚ΡŒ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π° Π±Π°Π·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒΡΡ Π½Π° Π΄Ρ€ΡƒΠ³ΠΎΠΌ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π΅. МоТно ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ ΠΎΠ±Ρ‰ΠΈΠΉ класс, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡ‚ΡŒ характСристики ΠΈ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅, свойствСнныС Π½Π°Π±ΠΎΡ€Ρƒ связанных ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ².

Π˜Π½ΠΊΠ°ΠΏΡΡƒΠ»ΡΡ†ΠΈΡ

Π‘ΠΎΠΊΡ€Ρ‹Ρ‚ΠΈΠ΅ Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½ΠΈΡ… Π΄Π°Π½Π½Ρ‹Ρ… ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π° ΠΈ Π΄Π΅Ρ‚Π°Π»Π΅ΠΉ Π΅Π³ΠΎ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΎΡ‚ Π΄Ρ€ΡƒΠ³ΠΈΡ… ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ² прилоТСния ΠΈ прСдоставлСниС Π½Π°Π±ΠΎΡ€Π° ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² для взаимодСйствия с Π½ΠΈΠΌ (API).

ΠŸΠΎΠ»ΠΈΠΌΠΎΡ€Ρ„ΠΈΠ·ΠΌ

Π‘ΠΏΠΎΡΠΎΠ±Π½ΠΎΡΡ‚ΡŒ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π° Π²Ρ‹Π±ΠΈΡ€Π°Ρ‚ΡŒ Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½ΡŽΡŽ ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Ρƒ (ΠΌΠ΅Ρ‚ΠΎΠ΄) исходя ΠΈΠ· Ρ‚ΠΈΠΏΠ° Π΄Π°Π½Π½Ρ‹Ρ…, принятых Π² сообщСнии.

Абстракция

ΠŸΡ€Π΅Π΄ΡΡ‚Π°Π²Π»Π΅Π½ΠΈΠ΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° ΠΌΠΈΠ½ΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΌ Π½Π°Π±ΠΎΡ€ΠΎΠΌ Π΄Π°Π½Π½Ρ‹Ρ… ΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² с Ρ‚ΠΎΡ‡Π½ΠΎΡΡ‚ΡŒΡŽ, достаточной для Ρ€Π΅ΡˆΠ°Π΅ΠΌΠΎΠΉ Π·Π°Π΄Π°Ρ‡ΠΈ.

ΠŸΡ€Π°ΠΊΡ‚ΠΈΠΊΠΈ

Agile

Scrum

Kanban

КакиС Π΅ΡΡ‚ΡŒ сСмь этапов Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ ΠΏΡ€ΠΎΠ΄ΡƒΠΊΡ‚Π° Π² Software Development lifecycle

ΠžΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ Ρ‚Ρ€Π΅Π±ΠΎΠ²Π°Π½ΠΈΠΉ ΠŸΡ€ΠΎΠ΅ΠΊΡ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ΠšΠΎΠ½ΡΡ‚Ρ€ΡƒΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ (Ρ‚Π°ΠΊΠΆΠ΅ «рСализация» Π»ΠΈΠ±ΠΎ Β«ΠΊΠΎΠ΄ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅Β») Π’ΠΎΠΏΠ»ΠΎΡ‰Π΅Π½ΠΈΠ΅ ВСстированиС ΠΈ ΠΎΡ‚Π»Π°Π΄ΠΊΠ° (Ρ‚Π°ΠΊΠΆΠ΅ «вСрификация») Π˜Π½ΡΡ‚Π°Π»Π»ΡΡ†ΠΈΡ ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ°

ΠœΠΈΠΊΡ€ΠΎΡΠ΅Ρ€Π²ΠΈΡΡ‹
https://habr.com/ru/post/249183/

Messaging

RabbitMQ Apache Kafka NATS

https://habr.com/ru/company/innotech/blog/698838/

Π¦ΠΈΡ‚Π°Ρ‚Π° ΠΈΠ· ΡΡ‚Π°Ρ‚ΡŒΠΈ:

Выбирая ΠΌΠ΅ΠΆΠ΄Ρƒ Kafka ΠΈ RabbitMQ На самом Π΄Π΅Π»Π΅, ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΡ‡Π½ΠΎ ΡΡ€Π°Π²Π½ΠΈΠ²Π°Ρ‚ΡŒ Π±Ρ€ΠΎΠΊΠ΅Ρ€Ρ‹ сообщСний ΠΎΡ‡Π΅Π½ΡŒ слоТно. Π£ всСх ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‚ свои Π·Π°Π΄Π°Ρ‡ΠΈ ΠΈ области примСнСния. Π’ случаС с Apache Kafka ΠΈ RabbitMQ это Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ Ρ€Π°Π·Π½Ρ‹ΠΉ ΡƒΡ€ΠΎΠ²Π΅Π½ΡŒ, Π³Π΄Π΅ Π»ΡƒΡ‡ΡˆΠ΅Π³ΠΎ Π½Π΅ сущСствуСт.

Kafka ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ Π±ΠΎΠ»ΡŒΡˆΠΈΡ… ΠΎΠ±ΡŠΡ‘ΠΌΠΎΠ² Π΄Π°Π½Π½Ρ‹Ρ…, сотСн тысяч сообщСний Π² сСкунду, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΏΠΎΠ΄ΠΎΠ»Π³Ρƒ хранятся Π½Π° дискС ΠΈ ΠΌΠ½ΠΎΠ³ΠΎ Ρ€Π°Π· Ρ‡ΠΈΡ‚Π°ΡŽΡ‚ΡΡ сотнями ΠΈΠ»ΠΈ Π΄Π°ΠΆΠ΅ тысячами подписчиков. Kafka β€” это Π»Π΅Π³ΠΊΠΎ ΠΌΠ°ΡΡˆΡ‚Π°Π±ΠΈΡ€ΡƒΠ΅ΠΌΠ°Ρ систСма, ΠΎΠ±Π»Π°Π΄Π°ΡŽΡ‰Π°Ρ ΠΏΠΎΠ²Ρ‹ΡˆΠ΅Π½Π½ΠΎΠΉ ΠΎΡ‚ΠΊΠ°Π·ΠΎΡƒΡΡ‚ΠΎΠΉΡ‡ΠΈΠ²ΠΎΡΡ‚ΡŒΡŽ, Ρ‡Ρ‚ΠΎ ΠΎΡ‡Π΅Π½ΡŒ Π²Π°ΠΆΠ½ΠΎ Π² ΠΊΡ€ΡƒΠΏΠ½Ρ‹Ρ… ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°Ρ….

RabbitMQ Π±ΠΎΠ»Π΅Π΅ простой Π² установкС ΠΈ настройкС, ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ справляСтся с асинхронным ΠΎΠ±ΠΌΠ΅Π½ΠΎΠΌ Π΄Π°Π½Π½Ρ‹ΠΌΠΈ Π² микросСрвисной Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π΅. НС Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ² ΠΈ Π·Π°Ρ‚Ρ€Π°Ρ‚ Π½Π° дисковыС рСсурсы, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ всС сообщСния послС чтСния ΠΈΠ· ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ ΡƒΠ΄Π°Π»ΡΡŽΡ‚ΡΡ. По ΡΡ€Π°Π²Π½Π΅Π½ΠΈΡŽ с Kafka ΠΎΠ±Π»Π°Π΄Π°Π΅Ρ‚ большими возмоТностями ΠΏΠΎ настройкС шаблонов ΠΎΠ±ΠΌΠ΅Π½Π° сообщСниями. ΠžΡ‚Π»ΠΈΡ‡Π½Ρ‹ΠΉ Π²Ρ‹Π±ΠΎΡ€, Ссли Π½Π΅Ρ‚ Π·Π°Π²Ρ‹ΡˆΠ΅Π½Π½Ρ‹Ρ… Ρ‚Ρ€Π΅Π±ΠΎΠ²Π°Π½ΠΈΠΉ ΠΊ отказоустойчивости ΠΈ пропускной способности.

12. АдминистрированиС/DevOps

«О Π£Π½Π½Π΅Ρ„Π΅Ρ€, Π΄Π°ΠΉ этому Ρ‡Π΅Π»ΠΎΠ²Π΅ΠΊΡƒ Π² Ρ‚Π²ΠΎΠ΅ΠΌ ЦарствС тысячу Ρ…Π»Π΅Π±ΠΎΠ², тысячу Π±Ρ‹ΠΊΠΎΠ², тысячу сосудов ΠΏΠΈΠ²Π°Β».

ΠžΠ±Ρ€Π°Ρ‰Π΅Π½ΠΈΠ΅ ΠΊ ΠžΡΠΈΡ€ΠΈΡΡƒ, ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄ М. Π­. ΠœΠ°Ρ‚ΡŒΠ΅.

DevOps

Π Π°Π±ΠΎΡ‚Π° с git

git config --global core.editor "'C:/Program Files/Notepad++/notepad++.exe' -multiInst -notabbar -nosession -noPlugin"

Π‘ΠΎΠ·Π΄Π°Ρ‚ΡŒ Π½ΠΎΠ²Ρ‹ΠΉ Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚Π°Ρ€ΠΈΠΉ: git init
Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Ρ„Π°ΠΉΠ»Ρ‹: git add --all

git commit
ДобавляСм Π² тСкстовом Ρ„Π°ΠΉΠ»Π΅ ΠΏΠ΅Ρ€Π²ΠΎΠΉ строкой англоязычный Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ ΠΊΠΎΠΌΠΌΠΈΡ‚Π°, Π²Ρ‚ΠΎΡ€ΠΎΠΉ ΠΈ Π΄Π°Π»Π΅Π΅ строками ΠΌΠΎΠΆΠ½ΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ русскоязычноС описаниС. БохраняСм, Π·Π°ΠΊΡ€Ρ‹Π²Π°Π΅ΠΌ.

Бписок Π²Π΅Ρ‚ΠΎΠΊ: git branch --list
Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ Π½ΠΎΠ²ΡƒΡŽ Π²Π΅Ρ‚ΠΊΡƒ, ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ Π½Π° Π²Π΅Ρ‚ΠΊΡƒ Π½Π΅ выполняСтся: git branch small-update
ΠŸΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ Π½Π° вновь ΡΠΎΠ·Π΄Π°Π½Π½ΡƒΡŽ Π²Π΅Ρ‚ΠΊΡƒ: git checkout small-update
ΠŸΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ Π½Π° Π²Π΅Ρ‚ΠΊΡƒ master: git checkout master
БлияниС Π²Π΅Ρ‚ΠΎΠΊ: git merge small-update
git log --graph --full-history --all --color --pretty=format:"%x1b[31m%h%x09%x1b[32m%d%x1b[0m%x20%s"

БлияниС ΠΊΠΎΠΌΠΌΠΈΡ‚ΠΎΠ²:
git rebase
squash

ΠŸΠΎΠΏΡ‹Ρ‚ΠΊΠ° пСрСнСсти ΠΎΠ΄ΠΈΠ½ΠΎΡ‡Π½Ρ‹ΠΉ ΠΊΠΎΠΌΠΌΠΈΡ‚ ΠΈΠ· Π²Π΅Ρ‚ΠΊΠΈ Π² Π²Π΅Ρ‚ΠΊΡƒ: cherry pick
ΠŸΡ€Π°Π²ΠΊΠ° истории git с риском Π·Π°Ρ‚Π΅Ρ€Π΅Ρ‚ΡŒ Ρ‡ΡƒΠΆΠΈΠ΅ ΠΊΠΎΠΌΠΌΠΈΡ‚Ρ‹: git push origin master --force-with-lease (форсированный push)

Precommit check

Π₯ΡƒΠΊΠΈ (скрипты Π½Π° shell'Π°Ρ… ΠΈΠ»ΠΈ Python), ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‰ΠΈΠ΅: Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΡƒ отправляСмого Π² Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΉ ΠΊΠΎΠ΄Π° Π½Π° Π²Π°Π»ΠΈΠ΄Π½ΠΎΡΡ‚ΡŒ (PEP8, докумСнтация ΠΈ Ρ‚. Π΄.); Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒ комплСксноС тСстированиС ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°; ΠΏΡ€Π΅Ρ€Ρ‹Π²Π°Ρ‚ΡŒ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΡŽ commit'Π° Π² случаС обнаруТСния ошибок ΠΈ ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°Ρ‚ΡŒ ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½Ρ‹ΠΉ ΠΆΡƒΡ€Π½Π°Π» ошибок.

Π‘Π°Π·ΠΎΠ²Ρ‹Π΅ знания Linux ΠΈ Ρ€Π°Π±ΠΎΡ‚Π° Π² консоли

РазумССтся, администрированиС ΠΏΠΎΠ΄Ρ€Π°Π·ΡƒΠΌΠ΅Π²Π°Π΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Ρƒ Π² консоли. НичСго слоТного Π² этом Π½Π΅Ρ‚, Π² ΠΊΠΎΠ½Ρ†Π΅ ΠΊΠΎΠ½Ρ†ΠΎΠ², АндТСлина Π”ΠΆΠΎΠ»ΠΈ Π² Β«Π₯Π°ΠΊΠ΅Ρ€Π°Ρ…Β» ΠΈ ΠšΡΡ€Ρ€ΠΈ-Π­Π½Π½ Мосс Π² Β«ΠœΠ°Ρ‚Ρ€ΠΈΡ†Π΅Β» прСкрасно ΡΠΏΡ€Π°Π²ΠΈΠ»ΠΈΡΡŒ!

CI/CD

Continuous testing GitHub Actions Jenkins

Containers

Docker Kubernetes

Git-flow

Π’ Ρ†Π΅Π»ΠΎΠΌ, Π² настоящСС врСмя модСль git-flow ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ ΡΡ€Π°Π²Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Ρ€Π΅Π΄ΠΊΠΎ. Π­Ρ‚Π° модСль вСтвлСния основана Π½Π° прСдсказуСмом, долгосрочном Ρ†ΠΈΠΊΠ»Π΅ Ρ€Π΅Π»ΠΈΠ·Π° Π½ΠΎΠ²Ρ‹Ρ… вСрсий, Π° Π½Π΅ Π½Π° выпускС Π½ΠΎΠ²ΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π° ΠΊΠ°ΠΆΠ΄Ρ‹Π΅ нСсколько часов. Git-flow сильно услоТняСт continuous delivery, ΠΊΠΎΠ³Π΄Π° Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ Π²Ρ‹ΠΏΡƒΡΠΊΠ°ΡŽΡ‚ частыС обновлСния ΠΏΡƒΡ‚Π΅ΠΌ слияния с мастСром (фактичСски, нСпосрСдствСнно Π² production) ΠΈ ΠΏΠ»ΠΎΡ…ΠΎ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΈΡ‚ для ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ΠΎΠ², Ρ€Π°Π·Π±ΠΈΡ‚Ρ‹Ρ… Π½Π° сСрвисы.
ЕдинствСнный Π²Π°Ρ€ΠΈΠ°Π½Ρ‚, Π½Π΅ΠΏΠ»ΠΎΡ…ΠΎ подходящий ΠΏΠΎΠ΄ git-flow β€” большая ΠΊΠΎΠΌΠ°Π½Π΄Π° (20+ Ρ‡Π΅Π»ΠΎΠ²Π΅ΠΊ), ΠΏΠ»Π°Π½ΠΎΠΌΠ΅Ρ€Π½ΠΎ Π²Ρ‹ΠΏΡƒΡΠΊΠ°ΡŽΡ‰Π°Ρ нСсколько ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½Ρ‹Ρ… Ρ€Π΅Π»ΠΈΠ·ΠΎΠ² ΠΈΠ»ΠΈ Π·Π°Π½ΠΈΠΌΠ°ΡŽΡ‰Π°ΡΡΡ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΎΠΉ Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… вСрсий прилоТСния ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½ΠΎ. Π’ Ρ‚Π°ΠΊΠΎΠΌ случаС git-flow Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΠΌΠΎΡ‡ΡŒ навСсти порядок.

ΠœΠ°Π³ΠΈΡΡ‚Ρ€Π°Π»ΡŒΠ½Π°Ρ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ°

ΠœΠ°Π³ΠΈΡΡ‚Ρ€Π°Π»ΡŒΠ½Π°Ρ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° (trunk-based development) фактичСски являСтся ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠΉ ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠΎΠΉ CI/CD ΠΈ ΠΏΡ€Π΅Π΄ΠΏΠΎΠ»Π°Π³Π°Π΅Ρ‚ нСбольшиС частыС обновлСния Π³Π»Π°Π²Π½ΠΎΠΉ Π²Π΅Ρ‚ΠΊΠΈ. ΠŸΠΎΠ΄Ρ€Π°Π·ΡƒΠΌΠ΅Π²Π°Π΅Ρ‚ Π΅ΠΆΠ΅Π΄Π½Π΅Π²Π½Ρ‹Π΅ ΠΊΠΎΠΌΠΌΠΈΡ‚Ρ‹, ΠΌΠ½ΠΎΠ³ΠΎΡƒΡ€ΠΎΠ²Π½Π΅Π²ΠΎΠ΅ автоматичСскоС тСстированиС ΠΈ Π±Ρ‹ΡΡ‚Ρ€ΡƒΡŽ ΠΊΠ΅ΡˆΠΈΡ€ΡƒΡŽΡ‰ΡƒΡŽ сборку.

Π˜ΡΡ‚ΠΎΡ‡Π½ΠΈΠΊΠΈ

Python

ΠžΡ„ΠΈΡ†ΠΈΠ°Π»ΡŒΠ½Π°Ρ докумСнтация Python docs.python.org, Π²ΠΊΠ»ΡŽΡ‡Π°ΡŽΡ‰Π°Ρ The Python Standard Library.
Π’Π΅ΡΡŒΠΌΠ° ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎΠ΅ руководство (совсСм ΡƒΠΆ Π±Π°Π·ΠΎΠ²Ρ‹ΠΉ синтаксис Π½Π΅ Π²ΠΊΠ»ΡŽΡ‡Π΅Π½): Comprehensive Python Cheatsheet.
Руководство с Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ΠΌ Π±Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ синтаксиса: Python Cheatsheet. Π’ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ практичСскиС Jupiter Notebooks.
Бипсок Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊ ΠΈ Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊΠΎΠ²: Awesome Python.
Около-питоновскиС практичСскиС совСты (pip, virtualenv, pyInstaller ΠΈ Ρ‚. Π΄.): "The Hitchhiker’s Guide to Python".
ΠœΠ°Π½ΡƒΠ°Π» для Π½Π°Ρ‡ΠΈΠ½Π°ΡŽΡ‰ΠΈΡ… Π΄Π°Ρ‚Π°-сайСнтистов: Joel Grus, "Data Science from Scratch".
Руководство для Π½Π°Ρ‡ΠΈΠ½Π°ΡŽΡ‰ΠΈΡ…: "Python Notes for Professionals".
Руководство для ΠΎΠΏΡ‹Ρ‚Π½Ρ‹Ρ… программистов: "Python 3 Patterns, Recipes and Idioms".
АрхитСктурныС ΠΏΠ°Ρ‚Ρ‚Π΅Ρ€Π½Ρ‹: Harry Percival & Bob Gregory, "Architecture Patterns with Python".

Git

Π‘Ρ‚Π°Ρ‚ΡŒΡ 2010 Π³ΠΎΠ΄Π°, полоТившая Π½Π°Ρ‡Π°Π»ΠΎ распростанСния git-flow. Π‘Π°ΠΌ Π°Π²Ρ‚ΠΎΡ€ сдСлал Π² 2020 Π΄ΠΎΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΊ ΡΡ‚Π°Ρ‚ΡŒΠ΅, Π³Π΄Π΅ Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡƒΠ΅Ρ‚ ΠΊΠΎΠΌΠ°Π½Π΄Π°ΠΌ, ΠΏΡ€ΠΈΠ΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‰ΠΈΡ…ΡΡ continuous delivery, ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ΠΈΡ‚ΡŒ Π½Π° GitHub flow: A successful Git branching model.
git-flow (компания Atlassian ΠΈΠ·ΠΌΠ΅Π½ΠΈΠ»Π° тСкст страницы, Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ Ρ‚Π°ΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ‰Π΅Π½Ρ‹ Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°Ρ†ΠΈΠΈ ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄Π° Π½Π° ΠΌΠ°Π³ΠΈΡΡ‚Ρ€Π°Π»ΡŒΠ½ΡƒΡŽ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΡƒ): git-flow.
ΠšΡ€ΠΈΡ‚ΠΈΠΊΠ° git-flow.
GitHub flow.

Π’Ρ‹Π²Π΅Π΄Π΅Π½ΠΈΠ΅

Ну Ρ‡Ρ‚ΠΎ ΠΆ, Π΄ΠΎΡ€ΠΎΠ³ΠΈΠ΅ Ρ‡ΠΈΡ‚Π°Ρ‚Π΅Π»ΠΈ, Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ, послС прочтСния этого ΠΊΡ€Π°Ρ‚ΠΊΠΎΠ³ΠΎ путСводитСля ΠΏΠΎ языку программирования Python ΠΈ связанной с Π½ΠΈΠΌ инфраструктурС, надСюсь, Ρ‡Ρ‚ΠΎ Π²Ρ‹ Π·Π°ΠΊΡ€Ρ‹Π»ΠΈ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π»Π°ΠΊΡƒΠ½Ρ‹ Π² своих знаниях, Π΄Π°ΠΆΠ΅ Ссли Π΄ΠΎ этого ΠΎΠ±Π»Π°Π΄Π°Π»ΠΈ ΠΎΠΊΠΎΠ»ΠΎΠ½ΡƒΠ»Π΅Π²Ρ‹ΠΌ ΠΎΠΏΡ‹Ρ‚ΠΎΠΌ программирования. Π•Ρ‰Π΅ большС надСюсь, Ρ‡Ρ‚ΠΎ Ρƒ вас появилась масса Π΄Ρ€ΡƒΠ³ΠΈΡ… вопросов, ΡƒΠΆΠ΅ Π±ΠΎΠ»Π΅Π΅ ΠΎΡ„ΠΎΡ€ΠΌΠΈΠ²ΡˆΠΈΡ…ΡΡ ΠΈ структурированных, Π° ΠΆΠ΅Π»Π°Π½ΠΈΠ΅ Π½Π΅ΠΌΠ΅Π΄Π»Π΅Π½Π½ΠΎ ΡΠ΅ΡΡ‚ΡŒ ΠΈ Ρ‡Ρ‚ΠΎ-Π½ΠΈΠ±ΡƒΠ΄ΡŒ эдакоС Π·Π°ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ возросло.

РазумССтся, ΠΈΠ·ΡƒΡ‡Π΅Π½ΠΈΠ΅ ΠΊΡ€Π°Ρ‚ΠΊΠΈΡ… спСцификаций ΡΡ‚Ρ€ΠΎΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… Π±Π»ΠΎΠΊΠΎΠ² являСтся Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΠ΅Ρ€Π²Ρ‹ΠΌ этапом любого процСсса созидания, Π½ΠΎ Π·Π° Π³ΠΎΠ΄-ΠΏΠΎΠ»Ρ‚ΠΎΡ€Π° постоянной ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠΈ Π²Ρ‹ Π²ΠΏΠΎΠ»Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π·Π°Π»ΠΎΠΆΠΈΡ‚ΡŒ Π½Π΅ просто Ρ„ΡƒΠ½Π΄Π°ΠΌΠ΅Π½Ρ‚, Π° Π΄ΠΎΠΉΡ‚ΠΈ, скаТСм Ρ‚Π°ΠΊ, Π΄ΠΎ уровня ΠΏΠΎΠ»Π°. И ΠΊΠΎΠ³Π΄Π° Π²Π°ΠΌ ΠΏΠΎ Ρ€Π°Π±ΠΎΡ‡Π΅ΠΉ надобности ΠΈΠ»ΠΈ просто Π² тСкстС вакансии Π±ΡƒΠ΄Π΅Ρ‚ Π²ΡΡ‚Ρ€Π΅Ρ‡Π°Ρ‚ΡŒΡΡ какая-Ρ‚ΠΎ нСизвСстная Π°Π±Π±Ρ€Π΅Π²ΠΈΠ°Ρ‚ΡƒΡ€Π°, Π²Ρ€ΠΎΠ΄Π΅ RabbitMQ, ELK Stack ΠΈΠ»ΠΈ Kubernetes, Π²Ρ‹, ΠΏΠΎΠ»ΡŒΠ·ΡƒΡΡΡŒ Π½Π°ΠΊΠΎΠΏΠ»Π΅Π½Π½Ρ‹ΠΌ Π±Π°Π³Π°ΠΆΠΎΠΌ, Π±ΡƒΠ΄Π΅Ρ‚Π΅ Π² силах ΡΠ°ΠΌΠΎΡΡ‚ΠΎΡΡ‚Π΅Π»ΡŒΠ½ΠΎ Ρ€Π°Π·ΠΎΠ±Ρ€Π°Ρ‚ΡŒΡΡ Π² ΠΈΡ… ΠΏΠ»ΡŽΡΠ°Ρ…, минусах ΠΈ особСнностях примСнСния, ΠΈΠ»ΠΈ, говоря словами классика, «Какой с ΠΎΡ‚Π±ΠΈΡ‚Ρ‹ΠΌ ΡƒΠ³Π»ΠΎΠΌ, с помятым Ρ€Π΅Π±Ρ€ΠΎΠΌ ΠΈΠ»ΠΈ с ΠΏΡ€ΠΈΠ»ΠΈΠ²ΠΎΠΌ β€” сразу Π¨ΡƒΡ…ΠΎΠ² это Π²ΠΈΠ΄ΠΈΡ‚, ΠΈ Π²ΠΈΠ΄ΠΈΡ‚, ΠΊΠ°ΠΊΠΎΠΉ стороной этот шлакоблок Π»Π΅Ρ‡ΡŒ Ρ…ΠΎΡ‡Π΅Ρ‚, ΠΈ Π²ΠΈΠ΄ΠΈΡ‚ Ρ‚ΠΎ мСсто Π½Π° стСнС, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ этого шлакоблока ΠΆΠ΄Π΅Ρ‚Β», ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ ΠΌΡƒΡ‚Π½Ρ‹Π΅ Π±Π°Π·Π·Π²ΠΎΡ€Π΄Ρ‹ прСвратятся для вас Π²ΠΎ Π²ΠΏΠΎΠ»Π½Π΅ ΠΊΠΎΠ½ΠΊΡ€Π΅ΠΊΡ‚Π½Ρ‹Π΅, ΠΆΠΈΠ²Ρ‹Π΅ Ρ‚Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΠΈ.

Π§Ρ‚ΠΎ ΠΆ, самообразованиС всСгда даётся нСпросто, Π½ΠΎ, Π·Π°ΠΏΠ»Π°Ρ‚ΠΈΠ² Ρ‚Ρ€ΡƒΠ΄ΠΎΠΌ ΠΈ Π»ΠΈΡ‡Π½Ρ‹ΠΌ Π²Ρ€Π΅ΠΌΠ΅Π½Π΅ΠΌ сСгодня, Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΏΡ€ΠΎΡ†Π΅Π½Ρ‚Ρ‹ Π² Π²ΠΈΠ΄Π΅ личностного роста, свободы ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Ρ‹ мСст ΠΈ фиинансовой нСзависимости Π·Π°Π²Ρ‚Ρ€Π°, Ρ‚Π°ΠΊ Ρ‡Ρ‚ΠΎ сСйчас самоС врСмя ΠΏΠ΅Ρ€Π΅ΡΡ‚Π°Ρ‚ΡŒ ΡΠΈΠ΄Π΅Ρ‚ΡŒ Π½Π° ΠΏΠΎΠΏΠ΅ Ρ€ΠΎΠ²Π½ΠΎ, ощущая, ΠΊΠ°ΠΊ литосфСрныС ΠΏΠ»ΠΈΡ‚Ρ‹ своим Π½Π΅Ρ‚ΠΎΡ€ΠΎΠΏΠ»ΠΈΠ²Ρ‹ΠΌ Π΄Ρ€Π΅ΠΉΡ„ΠΎΠΌ Π΄Π΅Π»Π°ΡŽΡ‚ Π²Π°ΠΌ нСнавязчивый массаТ.

ΠŸΠΎΠΏΡ€ΠΎΠ±ΡƒΠΉΡ‚Π΅ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ свою ΡΡƒΠ΄ΡŒΠ±Ρƒ, Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π½Π΅ ΡΠΌΠΎΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½Ρ‹ΠΌΠΈ поступками ΠΈ всякими Ρ€Π΅Π·ΠΊΠΈΠΌΠΈ тСлодвиТСниями, Π½ΠΎ, Π½Π°ΠΏΡ€ΠΎΡ‚ΠΈΠ², Π΅ΠΆΠ΅Π΄Π½Π΅Π²Π½ΠΎΠΉ ΠΊΡ€ΠΎΠΏΠΎΡ‚Π»ΠΈΠ²ΠΎΠΉ Ρ€Π°Π±ΠΎΡ‚ΠΎΠΉ, ΠΏΠΎΠ·Π½Π°Π½ΠΈΠ΅ΠΌ Π½ΠΎΠ²ΠΎΠ³ΠΎ, Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΠ΅ΠΌ Π³Ρ€Π°Π½ΠΈΡ† своих Π·Π½Π°Π½ΠΈΠΉ. ΠŸΡ€ΠΈΠ²Ρ‹ΠΊΠ°ΠΉΡ‚Π΅ Ρ‚ΡΠ½ΡƒΡ‚ΡŒ эту Ρ‚ΡΠΆΠ΅Π»ΡƒΡŽ ΡΠ΅Ρ‚ΡŒ, хотя Π±Ρ‹ ΠΈ Π² ΡƒΡ‡Π΅Π±Π½Ρ‹Ρ… цСлях, ΠΈ Ρ€Π°Π½ΠΎ ΠΈΠ»ΠΈ ΠΏΠΎΠ·Π΄Π½ΠΎ Π² Π½Π΅ΠΉ Π·Π°Π±ΡŠΠ΅Ρ‚ΡΡ Тивая Ρ€Ρ‹Π±Π°. οΏ½