-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathglossary.html
More file actions
1500 lines (1265 loc) · 199 KB
/
Copy pathglossary.html
File metadata and controls
1500 lines (1265 loc) · 199 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!doctype html>
<html lang="uk">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Глосарій · Курс Python</title>
<meta name="description" content="Глосарій курсу Python: 130 статей із 40 тем — одне поняття, одна назва. Українською там, де відповідник усталений, англійською там, де перекладати нема чого.">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Unbounded:wght@400;600;800&family=Literata:ital,opsz,wght@0,7..72,400;0,7..72,600;1,7..72,400&family=JetBrains+Mono:wght@400;700&display=swap">
<style>
:root{
--paper:#edf0f3; --raise:#ffffff; --ink:#17212b; --soft:#5b6b7c; --hair:#d3dae1;
--rose:#c2185b; --teal:#0f766e; --amber:#c2620f; --rose-w:#c2185b22; --teal-w:#0f766e1a;
--shadow:0 1px 2px #17212b0d, 0 8px 24px #17212b0f;
}
@media (prefers-color-scheme: dark){
:root:not([data-theme="light"]){
--paper:#12171d; --raise:#1a2029; --ink:#e6ecf2; --soft:#93a3b4; --hair:#2b343f;
--rose:#f06292; --teal:#2dd4bf; --amber:#f5a524; --rose-w:#f0629222; --teal-w:#2dd4bf1a;
--shadow:0 1px 2px #0006, 0 8px 24px #0007;
}
}
:root[data-theme="dark"]{
--paper:#12171d; --raise:#1a2029; --ink:#e6ecf2; --soft:#93a3b4; --hair:#2b343f;
--rose:#f06292; --teal:#2dd4bf; --amber:#f5a524; --rose-w:#f0629222; --teal-w:#2dd4bf1a;
--shadow:0 1px 2px #0006, 0 8px 24px #0007;
}
*{box-sizing:border-box}
body{
margin:0; background:var(--paper); color:var(--ink);
font-family:Literata,Georgia,serif; font-size:18px; line-height:1.72;
-webkit-font-smoothing:antialiased;
}
.col{max-width:660px; margin:0 auto; padding:0 22px}
header{padding:64px 0 22px; border-bottom:1px solid var(--hair)}
.eyebrow{
font-family:"JetBrains Mono",monospace; font-size:11.5px; letter-spacing:.18em;
text-transform:uppercase; color:var(--soft); margin:0 0 18px;
}
h1{
font-family:Unbounded,system-ui,sans-serif; font-weight:800;
font-size:clamp(38px,7vw,66px); line-height:1.02; letter-spacing:-.025em;
margin:0 0 16px; text-wrap:balance;
}
.stand{font-size:20px; color:var(--soft); margin:0 0 26px; text-wrap:balance}
.meta{
display:flex; gap:18px; flex-wrap:wrap; font-family:"JetBrains Mono",monospace;
font-size:12px; color:var(--soft); padding-bottom:8px;
}
.meta b{color:var(--ink); font-weight:700}
/* зміст */
.toc{margin:34px 0 0; padding:20px 22px; background:var(--raise);
border:1px solid var(--hair); border-radius:12px}
.toc h4{font-family:Unbounded,sans-serif; font-size:12px; letter-spacing:.08em;
text-transform:uppercase; color:var(--soft); margin:0 0 12px; font-weight:600}
.toc ol{margin:0; padding-left:20px; columns:2; column-gap:26px; font-size:15px}
@media(max-width:620px){.toc ol{columns:1}}
.toc li{margin-bottom:5px; break-inside:avoid}
.toc a{color:var(--ink); text-decoration:none; border-bottom:1px solid transparent}
.toc a:hover{border-bottom-color:var(--rose); color:var(--rose)}
h2{
font-family:Unbounded,system-ui,sans-serif; font-weight:600;
font-size:clamp(24px,3.4vw,32px); line-height:1.15; letter-spacing:-.015em;
margin:66px 0 6px; text-wrap:balance; scroll-margin-top:20px;
}
h2 .num{
display:block; font-family:"JetBrains Mono",monospace; font-size:12px;
font-weight:400; letter-spacing:.16em; color:var(--rose); margin-bottom:10px;
}
h3{font-family:Unbounded,system-ui,sans-serif; font-weight:600; font-size:19px; margin:36px 0 4px}
p{margin:16px 0}
a{color:var(--teal)}
strong{font-weight:600}
ul,ol.steps{margin:16px 0; padding-left:22px}
li{margin:8px 0}
.lead::first-letter{
float:left; font-family:Unbounded,sans-serif; font-weight:800; font-size:64px;
line-height:.82; margin:6px 10px 0 0; color:var(--rose);
}
.eq{
font-family:"JetBrains Mono",monospace; font-size:16px; text-align:center;
background:var(--raise); border:1px solid var(--hair); border-radius:10px;
padding:16px 12px; margin:22px 0; overflow-x:auto; box-shadow:var(--shadow);
}
code{font-family:"JetBrains Mono",monospace; font-size:.88em; background:var(--rose-w); padding:1px 5px; border-radius:4px}
.sub{font-size:.75em; vertical-align:-.25em}
.sup{font-size:.75em; vertical-align:.42em}
/* покрокове виведення */
.derive{margin:26px 0; border-left:2px solid var(--hair); padding-left:20px}
.derive .step{margin:20px 0}
.derive .lbl{
font-family:"JetBrains Mono",monospace; font-size:11px; letter-spacing:.1em;
text-transform:uppercase; color:var(--rose); display:block; margin-bottom:6px;
}
.derive .eq{margin:10px 0; text-align:left; padding:12px 14px}
.derive p{margin:8px 0; font-size:16.5px}
.note{
border-left:3px solid var(--teal); background:var(--teal-w);
padding:14px 18px; margin:26px 0; border-radius:0 8px 8px 0; font-size:16.5px;
}
.note b{font-family:Unbounded,sans-serif; font-size:13px; letter-spacing:.02em}
.warn{border-left-color:var(--rose); background:var(--rose-w)}
figure{
width:min(1000px, calc(100vw - 40px));
margin:52px 0 52px 50%; transform:translateX(-50%);
background:var(--raise); border:1px solid var(--hair);
border-radius:14px; padding:22px; box-shadow:var(--shadow);
}
figcaption{
font-family:"JetBrains Mono",monospace; font-size:12px; color:var(--soft);
margin-top:14px; padding-top:12px; border-top:1px solid var(--hair); line-height:1.55;
}
figcaption b{color:var(--ink)}
.fig-head{
font-family:Unbounded,sans-serif; font-weight:600; font-size:15px;
margin:0 0 4px; display:flex; align-items:center; gap:9px;
}
.fig-head::before{content:""; width:9px; height:9px; border-radius:2px; background:var(--rose); flex:none}
.fig-sub{font-size:14px; color:var(--soft); margin:0 0 16px}
.panel{display:grid; grid-template-columns:1fr 250px; gap:20px; align-items:start}
@media(max-width:720px){.panel{grid-template-columns:1fr}}
canvas{width:100%; height:auto; display:block; border-radius:8px; touch-action:none}
.ctl{margin-bottom:15px}
.ctl label{
display:flex; justify-content:space-between; align-items:baseline; gap:10px;
font-family:"JetBrains Mono",monospace; font-size:11.5px; letter-spacing:.06em;
text-transform:uppercase; color:var(--soft); margin-bottom:7px;
}
.ctl label output{color:var(--rose); font-weight:700; font-size:14px; font-variant-numeric:tabular-nums}
.ctl label .raw{text-transform:none; font-size:13px; color:var(--ink)}
input[type=range]{width:100%; accent-color:var(--rose); cursor:pointer}
input[type=range]:focus-visible{outline:2px solid var(--teal); outline-offset:4px}
.readout{display:grid; grid-template-columns:1fr 1fr; gap:8px; margin-top:4px}
.readout.one{grid-template-columns:1fr}
.cellv{background:var(--paper); border:1px solid var(--hair); border-radius:8px; padding:8px 10px}
.cellv b{
display:block; font-family:"JetBrains Mono",monospace; font-size:10px;
letter-spacing:.1em; text-transform:uppercase; color:var(--soft); font-weight:400;
}
.cellv i{
font-style:normal; font-family:"JetBrains Mono",monospace; font-size:17px;
font-variant-numeric:tabular-nums; font-weight:700;
}
button{
width:100%; margin-top:12px; padding:9px 12px; cursor:pointer; border-radius:8px;
font-family:Unbounded,sans-serif; font-size:12px; font-weight:600;
border:1.5px solid var(--teal); background:transparent; color:var(--teal);
transition:background .15s,color .15s;
}
button:hover{background:var(--teal); color:var(--raise)}
button:focus-visible{outline:2px solid var(--rose); outline-offset:3px}
.seg{display:flex; margin-bottom:15px; border:1.5px solid var(--hair); border-radius:8px; overflow:hidden}
.seg button{
margin:0; border:0; border-radius:0; flex:1; font-size:11px; padding:8px 4px;
color:var(--soft); background:transparent; border-right:1px solid var(--hair);
}
.seg button:last-child{border-right:0}
.seg button[aria-pressed=true]{background:var(--rose); color:#fff}
.seg button:hover{background:var(--rose-w); color:var(--ink)}
.seg button[aria-pressed=true]:hover{background:var(--rose); color:#fff}
.verdict{margin-top:12px; font-size:13.5px; line-height:1.5; color:var(--soft); min-height:62px}
.tag{
display:inline-block; font-family:"JetBrains Mono",monospace; font-size:10px;
letter-spacing:.1em; padding:3px 8px; border-radius:20px; margin-bottom:6px; font-weight:700;
}
.t-ok{background:var(--teal-w); color:var(--teal)}
.t-no{background:var(--rose-w); color:var(--rose)}
.t-mid{background:#c2620f22; color:var(--amber)}
.chk{display:flex; align-items:center; gap:8px; font-family:"JetBrains Mono",monospace;
font-size:11.5px; color:var(--soft); margin-top:10px; cursor:pointer}
.chk input{accent-color:var(--teal); width:15px; height:15px; cursor:pointer}
table{width:100%; border-collapse:collapse; margin:24px 0; font-size:15.5px}
th,td{text-align:left; padding:10px 12px; border-bottom:1px solid var(--hair)}
th{
font-family:"JetBrains Mono",monospace; font-size:10.5px; letter-spacing:.1em;
text-transform:uppercase; color:var(--soft); font-weight:400;
}
td:first-child{font-family:"JetBrains Mono",monospace; font-size:13px; color:var(--rose); white-space:nowrap}
.scroll-x{overflow-x:auto}
footer{margin:80px 0 60px; padding-top:26px; border-top:1px solid var(--hair);
font-size:14px; color:var(--soft)}
footer a{color:var(--teal)}
@media (prefers-reduced-motion:reduce){*{animation:none !important; transition:none !important}}
/* Лігатури JetBrains Mono склеюють оператори: != малюється як ≠, <= як ⩽,
-> як →. У курсі програмування це вада — читач бачить символ, якого
немає на клавіатурі, і не може відтворити код. */
code, pre, kbd, samp, .mono, .eyebrow, .meta, h2 .num, .eq, .derive .lbl, figcaption, .ctl label, .cellv b, .cellv i, .tag, .chk, th, td:first-child, .ax, .alpha a, .gt .en, .gt .where, .back{font-variant-ligatures:none}
</style>
<style>
/* ── компоненти саме цієї сторінки ────────────────────────────── */
/* абетковий покажчик */
.ax{font-family:"JetBrains Mono",monospace; font-size:10.5px; letter-spacing:.1em;
text-transform:uppercase; color:var(--soft); margin:0 0 9px}
.ax + .alpha{margin-bottom:18px}
.alpha{display:flex; flex-wrap:wrap; gap:6px}
.alpha a{font-family:"JetBrains Mono",monospace; font-size:13px; font-weight:700;
min-width:34px; text-align:center; padding:6px 8px; border-radius:8px;
border:1px solid var(--hair); background:var(--paper); color:var(--teal);
text-decoration:none; line-height:1}
.alpha a:hover{border-color:var(--teal); background:var(--teal-w)}
.alpha a:focus-visible{outline:2px solid var(--rose); outline-offset:2px}
/* стаття про один термін */
.gt{background:var(--raise); border:1px solid var(--hair); border-radius:12px;
padding:17px 21px; margin:14px 0; box-shadow:var(--shadow); scroll-margin-top:20px}
.gt h3{margin:0; font-size:18px; line-height:1.3}
.gt .en{display:block; font-family:"JetBrains Mono",monospace; font-weight:400;
font-size:13px; color:var(--soft); margin-top:4px; overflow-wrap:anywhere}
.gt .en code{background:none; padding:0; font-size:1em; color:var(--soft)}
.gt p{margin:11px 0 0; font-size:16.5px}
.gt .gnote{border-left:2px solid var(--hair); padding-left:13px; color:var(--soft);
font-size:15.5px}
.gt .where{font-family:"JetBrains Mono",monospace; font-size:12px; color:var(--soft);
margin-top:13px; padding-top:11px; border-top:1px solid var(--hair); line-height:1.6}
/* довгі імена не мають розпирати сторінку на телефоні (грабля №10) */
code{overflow-wrap:anywhere}
/* ...але короткі імена в заголовках не ріжемо: self → sel/f */
h3 code, h2 code{overflow-wrap:normal; white-space:nowrap}
.back{display:inline-block; font-family:"JetBrains Mono",monospace; font-size:12px;
color:var(--teal); text-decoration:none; margin-top:8px}
.back:hover{text-decoration:underline}
</style>
</head>
<body>
<header>
<div class="col">
<p class="eyebrow">Python з нуля</p>
<h1>Глосарій</h1>
<p class="stand">Усі поняття курсу в одному місці: що воно означає, як зветься
англійською і в якій темі про нього розказано докладно.</p>
<a class="back" href="index.html">← до списку тем</a>
</div>
</header>
<main class="col">
<p class="lead">Цей словник розвʼязує одну задачу: <strong>одне поняття — одна назва</strong>.
Курс писався сорока темами поспіль, і термінологія в ньому складалась по ходу;
тут вона зведена до канону. Якщо в темі трапиться інше слово для того самого — правильним
вважається те, що стоїть тут заголовком.</p>
<p>Заголовок статті українською там, де український відповідник усталений і зрозумілий
(зріз, виняток, включення), і англійською там, де перекладати нема чого або переклад
вийшов би гіршим за оригінал (<code>dataclass</code>, f-рядок, traceback, MRO). Другий
варіант завжди поруч із першим, тому шукати можна будь-яким. Де переклад спірний —
у статті є окрема нотатка про те, які ще варіанти трапляються й чому обрано саме цей.
Усього тут 130 статей: 99 з українським заголовком і 31 з англійським.</p>
<div class="toc">
<h4>Абетковий покажчик</h4>
<p class="ax">Українською</p>
<nav class="alpha"><a href="#uk-1040">А</a><a href="#uk-1041">Б</a><a href="#uk-1042">В</a><a href="#uk-1043">Г</a><a href="#uk-1044">Д</a><a href="#uk-1045">Е</a><a href="#uk-1046">Ж</a><a href="#uk-1047">З</a><a href="#uk-1030">І</a><a href="#uk-1050">К</a><a href="#uk-1051">Л</a><a href="#uk-1052">М</a><a href="#uk-1053">Н</a><a href="#uk-1054">О</a><a href="#uk-1055">П</a><a href="#uk-1056">Р</a><a href="#uk-1057">С</a><a href="#uk-1058">Т</a><a href="#uk-1060">Ф</a><a href="#uk-1061">Х</a><a href="#uk-1062">Ц</a><a href="#uk-1063">Ч</a><a href="#uk-1064">Ш</a><a href="#uk-1071">Я</a></nav>
<p class="ax">Англійською</p>
<nav class="alpha"><a href="#en-65">A</a><a href="#en-67">C</a><a href="#en-68">D</a><a href="#en-69">E</a><a href="#en-70">F</a><a href="#en-71">G</a><a href="#en-72">H</a><a href="#en-74">J</a><a href="#en-76">L</a><a href="#en-77">M</a><a href="#en-78">N</a><a href="#en-80">P</a><a href="#en-82">R</a><a href="#en-83">S</a><a href="#en-84">T</a><a href="#en-89">Y</a></nav>
</div>
<h2 id="uk-1040"><span class="num">кирилиця</span>А</h2>
<article class="gt" id="agregatna-funkciya">
<h3>Агрегатна функція <span class="en">aggregate function</span></h3>
<p>Функція SQL, яка бере багато рядків і повертає один результат: <code>count(*)</code>, <code>sum</code>, <code>avg</code>, <code>min</code>, <code>max</code>. Разом із <code>group by</code> вона рахує не по всій таблиці, а окремо по кожній купці рядків з однаковим значенням стовпця.</p>
<p class="gnote">Різницю між <code>where</code> і <code>having</code> плутають постійно: <code>where</code> відсіює <b>рядки</b> до групування, <code>having</code> — уже готові <b>купки</b> після нього, і тільки в ньому можна згадувати <code>count(*)</code>. Виграш не в довжині запису: <code>group by</code> рахує там, де лежать дані, і повертає три числа замість двох мільйонів рядків.</p>
<p class="where">Вводиться: <a href="23-databases-sql/lecture.html">23. Бази даних і SQL</a></p>
</article>
<article class="gt" id="algorytm">
<h3>Алгоритм <span class="en">algorithm</span></h3>
<p>Скінченний перелік кроків, який із будь-яких допустимих вхідних даних дає потрібний результат. «Скінченний» тут важливе: рецепт, що не закінчується, алгоритмом не є.</p>
<p class="gnote">Будь-який алгоритм записується <b>трьома</b> способами поєднання кроків: одне за одним (послідовність), розвилка (розгалуження) і повторення. Мов програмування тисячі, а цих цеглин — три, і саме тому, вивчивши одну мову, другу вчиш уже швидше.</p>
</article>
<article class="gt" id="amortyzovana-skladnist">
<h3>Амортизована складність <span class="en">amortized complexity</span></h3>
<p>Середня ціна однієї операції, порахована <b>по довгій серії</b>, а не по найгіршому окремому випадку. Потрібна там, де більшість викликів дешеві, а зрідка трапляється дорогий.</p>
<p class="gnote">Класичний приклад — <code>append</code> у списку. Майже завжди він просто кладе елемент у готовий запас і коштує сталу кількість дій. Але коли запас вичерпався, список копіює себе на більше місце — і цей виклик дорогий. Оскільки запас щоразу беруть із випередженням, дорогі виклики трапляються дедалі рідше, і середня ціна <b>виходить на сталу межу</b>. Позначають <code>O(1)</code> амортизовано.
<b>Не плутай із середнім випадком:</b> середній випадок — про <i>розподіл даних</i> («якщо ключі лягли рівномірно»), амортизована складність — про <i>послідовність викликів</i>, і вона гарантована незалежно від даних.</p>
</article>
<article class="gt" id="anotaciya-typu">
<h3>Анотація типу <span class="en">type hint, annotation</span></h3>
<p>Примітка про очікуваний тип, записана двокрапкою після імені: <code>кількість: int</code>, а для результату функції — стрілкою <code>-> float</code>. Сам Python за нею нічого не перевіряє: це документація, записана так формально, що її може прочитати програма.</p>
<p class="gnote">Канонічна назва курсу — <b>анотація</b>, а не «підказка типу»: калька з <i>hint</i> натякає на необовʼязкову пораду, тоді як для <code>@dataclass</code> анотація — обовʼязкова розмітка, без якої рядок узагалі не стане полем.</p>
<p class="where">Вводиться: <a href="34-type-hints/lecture.html">34. Типи (type hints)</a> · <a href="33-dataclasses/lecture.html">33. Dataclass і сучасний стиль</a></p>
</article>
<article class="gt" id="asynchronnist">
<h3>Асинхронність <span class="en">asynchrony, async</span></h3>
<p>Спосіб зайняти корисною роботою той час, коли програма стоїть і чекає на відповідь ззовні — від мережі, диска чи бази даних. Потік при цьому один: асинхронність не рахує швидше, вона лише дозволяє почати друге очікування, не дочекавшись першого.</p>
<p class="gnote">Типова хибна надія — «додам <code>async</code>, і буде швидше». Там, де немає пауз, а процесор зайнятий обчисленнями, виграшу немає взагалі.</p>
<p class="where">Вводиться: <a href="37-async/lecture.html">37. Асинхронність — базово</a></p>
</article>
<article class="gt" id="atrybut">
<h3>Атрибут <span class="en">attribute</span></h3>
<p>Поле обʼєкта, до якого звертаються через крапку: <code>p.ціна</code>. У примірника атрибути лежать у звичайному словнику <code>p.__dict__</code>, і крапка — просто зручний запис для роботи з ним.</p>
<p class="gnote">Python не веде списку дозволених полів, тому одруківка не падає, а мовчки створює новий атрибут: після <code>p.кількіть = 7</code> сума рахуватиметься по старому значенні.</p>
<p class="where">Вводиться: <a href="30-classes/lecture.html">30. Класи й обʼєкти</a></p>
</article>
<h2 id="uk-1041"><span class="num">кирилиця</span>Б</h2>
<article class="gt" id="baza-danyh">
<h3>База даних <span class="en">database</span></h3>
<p>Програма, яка зберігає дані так, щоб їй можна було <b>ставити питання</b>, і сама стежить, щоб дані лишалися узгодженими. Перше дає швидкий пошук: база тримає не лише рядки, а й службові структури, які підказують, де шукати. Друге дає порядок при одночасному доступі: доки одна програма змінює дані, інша не побачить половину зміни.</p>
<p class="gnote">Обидві половини видно на числах. Знайти один рядок у CSV на 130 МБ — це прочитати всі 130 МБ (12 секунд), а в базі з <a href="#indeks-bazy">індексом</a> — 22 кроки. І два записувачі, які одночасно правлять той самий файл, мовчки затирають один одного: 365 рядків замість 600, без жодної помилки. Файл не має способу сказати «зачекай, я пишу» — база має.</p>
<p class="where">Вводиться: <a href="23-databases-sql/lecture.html">23. Бази даних і SQL</a></p>
</article>
<article class="gt" id="bajt-kod">
<h3>Байт-код <span class="en">bytecode</span></h3>
<p>Проміжна форма програми: не текст, який писала людина, і не команди процесора, а інструкції для <b>віртуальної машини</b> Python. Саме їх виконує інтерпретатор.</p>
<p class="gnote">Побачити його можна: <code>import dis; dis.dis('print(2 + 3)')</code>. Звідси й відповідь на питання «Python компільований чи інтерпретований?» — компіляція є, але не в машинний код, а в байт-код, і відбувається вона щоразу при запуску.</p>
</article>
<article class="gt" id="bezpechnyi-metod">
<h3>Безпечний і ідемпотентний метод <span class="en">safe / idempotent</span></h3>
<p><b>Безпечний</b> метод нічого не змінює на сервері: скільки не викликай, світ лишається тим самим. Безпечні тільки <code>GET</code>, <code>HEAD</code> і <code>OPTIONS</code>. <b>Ідемпотентний</b> метод змінювати може, але повтор лишає стан таким самим, як після першого разу: <code>PUT</code>, <code>DELETE</code>.</p>
<p class="gnote">Це два різні поняття, і їх постійно змішують. Видалення не безпечне — воно змінює світ, — зате ідемпотентне: видалити ту саму позицію двічі те саме, що видалити один раз, її просто вже немає. А <code>POST</code> ні те, ні те: натиснув «додати» двічі — отримав дві позиції й два списання. Саме звідси випливає, який запит вільно <a href="#eksponenciynyi-vidstup">повторювати</a> після збою, а який ні.</p>
<p class="where">Вводиться: <a href="27-http-requests/lecture.html">27. HTTP-запити</a> · <a href="28-working-with-api/lecture.html">28. Робота з API</a></p>
</article>
<article class="gt" id="bit-i-bajt">
<h3>Біт і байт <span class="en">bit and byte</span></h3>
<p><b>Біт</b> — комірка, у якій може стояти або 0, або 1; менше не буває. <b>Байт</b> — вісім таких комірок, тобто 256 різних станів. Уся памʼять компʼютера — це такі комірки, і будь-яке число, літера чи зображення врешті записані ними.</p>
<p class="gnote">Звідси беруться межі, які інакше здаються примхою: у <code>float</code> на дробову частину відведено 52 біти, тому 0.1 не записується точно; літера латиниці в UTF-8 займає один байт, а українська — два.</p>
</article>
<article class="gt" id="blokuvalnyi-vyklyk">
<h3>Блокувальний виклик <span class="en">blocking call</span></h3>
<p>Звичайний синхронний виклик, який чекає, не віддаючи керування: <code>time.sleep</code>, <code>requests.get</code>, <code>open().read()</code>. Усередині асинхронної програми він зупиняє єдиний потік, а разом із ним і цикл подій — усі задачі стоять.</p>
<p class="gnote">Програма від цього не падає, вона просто тихо перестає бути асинхронною. Рятує <code>asyncio.to_thread</code>, який віддає такий виклик окремому потоку.</p>
<p class="where">Вводиться: <a href="06-user-input/lecture.html">06. Діалог із користувачем</a> · <a href="37-async/lecture.html">37. Асинхронність — базово</a></p>
</article>
<h2 id="uk-1042"><span class="num">кирилиця</span>В</h2>
<article class="gt" id="vektoryzaciya">
<h3>Векторизація <span class="en">vectorization</span></h3>
<p>Запис, у якому операція застосовується одразу до всього масиву без жодного циклу: <code>масив * 1.2</code> множить кожен елемент і повертає новий масив.</p>
<p class="gnote">Цикл <code>for</code> по масиву не просто зайвий — він приблизно вдвічі повільніший за цикл по списку, бо кожен елемент доводиться загортати у свіжий обʼєкт Python.</p>
<p class="where">Вводиться: <a href="38-numpy/lecture.html">38. NumPy: масиви</a></p>
</article>
<article class="gt" id="vyglyad">
<h3>Вигляд (масиву) <span class="en">view</span></h3>
<p>Новий обʼєкт NumPy, який дивиться на ту саму памʼять, лише з іншого місця. Зріз масиву — саме вигляд, тому запис у зріз змінює оригінал.</p>
<p class="gnote">Протилежність зрізу списку, який був копією. Ліки — <code>.copy()</code>; перевірка — <code>np.shares_memory</code>. Не плутай з <a href="#predstavlennya">представленням</a> словника: обидва англійською <i>view</i>, але курс тримає для них різні слова навмисно.</p>
<p class="where">Вводиться: <a href="38-numpy/lecture.html">38. NumPy: масиви</a></p>
</article>
<article class="gt" id="vynyatok">
<h3>Виняток <span class="en">exception</span></h3>
<p>Обʼєкт, який програма кидає нагору, коли граматика коду бездоганна, програма вже працює, але конкретна дія саме зараз неможлива: файлу немає, ділять на нуль, ключа немає в словнику.</p>
<p class="gnote">Курс каже саме <b>виняток</b>, а не «виключення»: назва точна як «виняток із правила», і виняток не завжди чиясь провина — кінець файлу і Ctrl+C теж винятки.</p>
<p class="where">Вводиться: <a href="19-exceptions/lecture.html">19. Помилки та винятки</a></p>
</article>
<article class="gt" id="vyraz">
<h3>Вираз <span class="en">expression</span></h3>
<p>Шматок коду, який <b>обчислюється у значення</b>: <code>2 + 3</code>, <code>x</code>, <code>len(s) > 0</code>. Протилежність — <b>інструкція</b> (statement), яка щось <b>робить</b>: присвоєння, <code>if</code>, <code>for</code>.</p>
<p class="gnote">Різниця не буквоїдська: вираз можна підставити туди, де очікується значення, а інструкцію — ні. Тому <code>x = (y = 3)</code> в Python помилка, а <code>x = 3 if y else 4</code> — ні.</p>
</article>
<article class="gt" id="vidsotkove-koduvannya">
<h3>Відсоткове кодування <span class="en">percent-encoding</span></h3>
<p>Спосіб записати в адресі символ, якого там бути не може. Слово перетворюють на байти UTF-8, і кожен байт, який не є латинською літерою, цифрою чи одним із кількох безпечних знаків, пишуть як <code>%</code> і два шістнадцяткові знаки: українська «ч» стає <code>%D1%87</code>. Пробіл у рядку запиту традиційно пишуть як <code>+</code>.</p>
<p class="gnote">Робити це руками не треба, а склеювати адресу рядком не можна: пробіл її обірве, <code>&</code> обріже значення на півслові, <code>#</code> мовчки викине все, що після нього. Правильний спосіб один — віддати словник: <code>requests.get(url, params={...})</code>, а <code>r.url</code> покаже, що з цього вийшло насправді.</p>
<p class="where">Вводиться: <a href="27-http-requests/lecture.html">27. HTTP-запити</a></p>
</article>
<article class="gt" id="vidstup">
<h3>Відступ як синтаксис <span class="en">significant indentation</span></h3>
<p>У Python межі блоку задає <b>відступ</b>, а не дужки: рядки з однаковим відступом належать до одного блоку. Це не оформлення на смак, а частина граматики мови — зміниш відступ, зміниться зміст програми.</p>
<p class="gnote"><b>Чому це варте окремої статті.</b> У більшості мов відступи потрібні лише людині, і новачок, який прийшов звідти, довго не вірить, що пробіли щось вирішують. Помилку не видно оком: <code>IndentationError</code> і, гірше, мовчазна зміна логіки, коли рядок випадково вийшов із циклу. Правило одне: <b>чотири пробіли на рівень, ніколи не мішати з табуляцією</b> — саме тому редактори налаштовують під це автоматично.</p>
</article>
<article class="gt" id="virtualne-seredovyshche">
<h3>Віртуальне середовище <span class="en">virtual environment</span></h3>
<p>Звичайна тека (за домовленістю <code>.venv</code>) із власним набором бібліотек і власним <code>python</code>, щоб два проєкти з різними версіями однієї бібліотеки не воювали. Створюють командою <code>python3 -m venv .venv</code>.</p>
<p class="gnote">Це не віртуальна машина й не контейнер: ізолюється лише набір пакетів. Переносити чи перейменовувати теку не можна — усередині абсолютні шляхи, простіше створити заново.</p>
<p class="where">Вводиться: <a href="18-venv-pip/lecture.html">18. Віртуальні середовища і pip</a></p>
</article>
<article class="gt" id="vis">
<h3>Вісь <span class="en">axis</span></h3>
<p>Напрямок у масиві чи таблиці: вісь 0 іде вниз по рядках, вісь 1 — вправо по стовпцях, і саме в такому порядку вони записані у формі (<i>shape</i>) — кортежі довжин по кожному виміру.</p>
<p class="gnote">У згортках <code>axis=k</code> — це вісь, <b>уздовж</b> якої рухається підсумовування, і саме вона зникає з форми результату. «Сума по магазинах» — це <code>axis=1</code>, хоч інтуїція часто підказує нуль.</p>
<p class="where">Вводиться: <a href="38-numpy/lecture.html">38. NumPy: масиви</a></p>
</article>
<article class="gt" id="vklyuchennya">
<h3>Включення <span class="en">comprehension</span></h3>
<p>Однорядковий запис найчастішого циклу — того, що бере одну колекцію й будує з неї другу: <code>[ціна * 2 for ціна in цінник]</code>. Буває спискове, множинне й словникове, за виглядом дужок.</p>
<p class="gnote">Це канонічна назва курсу; англійською кажуть <i>list comprehension</i>, і в текстах трапляється калька «списковий вираз». Головне тут не економія рядків: включення описує <b>результат</b>, а цикл — процес, тому вираз стоїть попереду, ще до слова <code>for</code>.</p>
<p class="where">Вводиться: <a href="14-comprehensions/lecture.html">14. Спискові включення</a></p>
</article>
<article class="gt" id="vuzol">
<h3>Вузол <span class="en">node</span></h3>
<p>Будь-який елемент дерева сторінки: тег, його атрибути, текст усередині. Розбір <a href="#html">HTML</a> — це перетворення плаского тексту на дерево вузлів, після якого лишається тільки ходити по ньому: тег усередині іншого — <b>дитина</b> (<i>child</i>), зовнішній — <b>батько</b> (<i>parent</i>), усе, що лежить усередині на будь-якій глибині, — <b>нащадки</b> (<i>descendants</i>).</p>
<p class="gnote">Канонічна назва курсу — <b>вузол</b>, а не «нода»: слово українське, усталене й уже живе в мові дерев. Вузол — не рядок, а обʼєкт із власними дітьми, тому текст із нього дістають окремо (<code>.get_text(" ", strip=True)</code>), а атрибути окремо (<code>tag["href"]</code> падає, <code>tag.get("href")</code> віддає <code>None</code>).</p>
<p class="where">Вводиться: <a href="29-web-scraping/lecture.html">29. Скрапінг сторінок</a></p>
<p class="gnote"><b>Не плутай із хостом.</b> У темах про мережу «хост» — це машина, до якої йде запит (те, що стоїть у заголовку <code>Host:</code>). Вузол у цьому глосарії — елемент дерева сторінки. Слова різні, і в блоці про мережу вони трапляються поруч.</p>
</article>
<h2 id="uk-1043"><span class="num">кирилиця</span>Г</h2>
<article class="gt" id="generator">
<h3>Генератор <span class="en">generator</span></h3>
<p>Функція, у тілі якої є слово <code>yield</code>, і обʼєкт, який повертає її виклик. Значення вона віддає по одному, на вимогу, а не будує весь список одразу — це і називають <b>лінивими обчисленнями</b> (<i>lazy evaluation</i>).</p>
<p class="gnote">Генератор тримає один елемент за раз плюс свій кадр — близько 464 байтів незалежно від того, мільйон там значень чи мільярд. Плата: пройтись ним можна рівно один раз, <code>len()</code> і зрізів у нього немає. Лінь не робить роботу дешевшою — вона лише не робить зайвої, тому на малих обсягах список часто швидший.</p>
<p class="where">Вводиться: <a href="35-iterators-generators/lecture.html">35. Ітератори й генератори</a></p>
</article>
<article class="gt" id="generatornyi-vyraz">
<h3>Генераторний вираз <span class="en">generator expression</span></h3>
<p>Те саме включення, але в круглих дужках: воно нічого не будує одразу, а віддає значення по одному. Мільйон значень коштує 200 байтів проти восьми мегабайтів у списку.</p>
<p class="gnote">Усередині виклику функції власні дужки не потрібні: <code>sum(ціна * к for ціна, к in zip(...))</code> рахує суму, жодного разу не створивши проміжного списку.</p>
<p class="where">Вводиться: <a href="14-comprehensions/lecture.html">14. Спискові включення</a> · <a href="35-iterators-generators/lecture.html">35. Ітератори й генератори</a></p>
</article>
<h2 id="uk-1044"><span class="num">кирилиця</span>Д</h2>
<article class="gt" id="gistogramma">
<h3>Гістограма <span class="en">histogram</span></h3>
<p>Графік розподілу: вісь значень ділять на однакові кошики й показують, скільки спостережень у кожен потрапило. Відповідає не «скільки всього», а «як саме розкидано».</p>
<p class="gnote"><b>Кошики вирішують усе.</b> Той самий набір при десяти кошиках може виглядати одногорбим, а при пʼятдесяти — двогорбим. Тому гістограму не читають без питання «скільки тут кошиків і чому стільки»; і тому середнього недосить — воно однакове у розподілів геть різної форми.</p>
</article>
<article class="gt" id="dekorator">
<h3>Декоратор <span class="en">decorator</span></h3>
<p>Функція, яка приймає функцію й повертає нову функцію. Рядок <code>@таймер</code> над <code>def підсумок</code> — це буквально <code>підсумок = таймер(підсумок)</code>, виконане один раз при читанні файлу, а не при виклику.</p>
<p class="gnote">Внутрішню функцію декоратора називають <b>обгорткою</b> (<i>wrapper</i>). Найпоширеніша перша помилка — забути в ній <code>return результат</code>: функція раптом починає повертати <code>None</code>, і причину шукають не там.</p>
<p class="where">Вводиться: <a href="36-decorators/lecture.html">36. Декоратори</a></p>
</article>
<article class="gt" id="dynamichna-storinka">
<h3>Динамічна сторінка <span class="en">client-side rendering</span></h3>
<p>Сторінка, вміст якої домальовує JavaScript уже в браузері: сервер віддає порожній каркас, скрипт іде по дані окремим запитом і вставляє їх у контейнер. У тексті, який приїхав до <code>requests</code>, цього вмісту немає взагалі.</p>
<p class="gnote">Ознака впізнавана: у браузері вісім позицій, а <code>select(".name")</code> повертає порожній список — і код при цьому правильний. <code>requests</code> — завантажувач, а не браузер, JavaScript він не виконує. Перш ніж тягнутись по Playwright чи Selenium, знайди у вкладці «Мережа» той самий прихований запит: він майже завжди віддає <a href="#json">JSON</a> і робить <a href="#skraping">скрапінг</a> непотрібним.</p>
<p class="where">Вводиться: <a href="29-web-scraping/lecture.html">29. Скрапінг сторінок</a></p>
</article>
<article class="gt" id="dokstring">
<h3>Докстрінг <span class="en">docstring</span></h3>
<p>Рядок у потрійних лапках, що стоїть першим у тілі функції, класу чи модуля. Python зберігає його в самому обʼєкті, тому <code>help(функція)</code> і <code>функція.__doc__</code> показують саме його.</p>
<p class="gnote">Пиши в ньому те, чого з коду не видно — одиниці виміру, припущення, дивні випадки, — а не переказ самого коду.</p>
<p class="where">Вводиться: <a href="15-functions/lecture.html">15. Функції</a></p>
</article>
<h2 id="uk-1045"><span class="num">кирилиця</span>Е</h2>
<article class="gt" id="ekranuvannya">
<h3>Екранування <span class="en">escaping</span></h3>
<p>Спосіб сказати «наступний символ — звичайний, а не службовий». У Python і в регулярних виразах це зворотна скісна: <code>\n</code> — перехід рядка, <code>\.</code> — саме крапка, а не «будь-який символ».</p>
<p class="gnote"><b>Пастка — шари.</b> Той самий текст може проходити екранування двічі: спершу як літерал Python, потім як регулярний вираз, а часом ще й як значення в JSON чи в SQL. На кожному шарі скісних треба вдвічі більше, і саме тому вирази з <code>"\\\\"</code> виглядають лячно. Ліки — <b>сирий рядок</b> і звичка друкувати проміжний результат.</p>
</article>
<article class="gt" id="eksponenciynyi-vidstup">
<h3>Експоненційний відступ <span class="en">exponential backoff</span></h3>
<p>Правило пауз між повторами невдалого запиту: кожна наступна вдвічі довша за попередню — 1 секунда, 2, 4, 8. Повторюють тільки <code>5xx</code> («зараз не можу») і тільки <a href="#bezpechnyi-metod">ідемпотентні</a> методи.</p>
<p class="gnote">Пауза росте не з ввічливості, а з арифметики: <code>5xx</code> найчастіше означає перевантаження, і тисяча клієнтів, які грюкають раз на секунду, не дають серверу піднятись ніколи. Зростаюча пауза ще й перекриває довший збій тією самою кількістю спроб: пʼять подвоєнь — майже шістнадцять секунд, пʼять секундних — чотири. Якщо сервер надіслав <code>Retry-After</code>, бери число звідти, а не вигадуй своє.</p>
<p class="where">Вводиться: <a href="28-working-with-api/lecture.html">28. Робота з API</a></p>
</article>
<h2 id="uk-1046"><span class="num">кирилиця</span>Ж</h2>
<article class="gt" id="zhadibnist">
<h3>Жадібність <span class="en">greediness</span></h3>
<p>Поведінка квантифікаторів регулярного виразу за замовчуванням: вони беруть якнайбільше, тобто до кінця рядка, а потім віддають назад по одному символу, поки решта шаблону не складеться.</p>
<p class="gnote">Саме тому <code>r"<.+>"</code> повертає весь рядок замість одного тега. Знак питання (<code>.+?</code>) робить квантифікатор <b>лінивим</b>: він бере якнайменше.</p>
<p class="where">Вводиться: <a href="25-regex/lecture.html">25. Регулярні вирази</a></p>
</article>
<h2 id="uk-1047"><span class="num">кирилиця</span>З</h2>
<article class="gt" id="zagolovok">
<h3>Заголовок <span class="en">header</span></h3>
<p>Пара «назва: значення» у службовій частині запиту або відповіді HTTP — усе, що сторони кажуть одна одній <b>про</b> дані, а не самі дані. У <code>requests</code> заголовки відповіді лежать у <code>r.headers</code> і поводяться майже як словник, тільки регістр назви не має значення.</p>
<p class="gnote">Найважливіший — <code>Content-Type</code>: він відповідає одразу на два питання, що це за дані і в якому вони <a href="#koduvannya">кодуванні</a>. Якщо <code>charset</code> у ньому не названо, старий стандарт наказує вважати відповідь <code>ISO-8859-1</code>, де українських літер немає взагалі, — звідси й кракозябра в <code>r.text</code>. Кракозябра ніколи не означає «зіпсовані дані»: це правильні байти, зібрані за неправильним правилом, і <code>r.content</code> лишається цілим.</p>
<p class="where">Вводиться: <a href="27-http-requests/lecture.html">27. HTTP-запити</a></p>
</article>
<article class="gt" id="zamykannya">
<h3>Замикання <span class="en">closure</span></h3>
<p>Внутрішня функція разом із захопленими іменами зовнішньої: обгортка вже завершилась, а її памʼять живе, поки жива внутрішня функція.</p>
<p class="gnote">Це не виняток із правил області видимості, а їх наслідок: зникає кадр, а не обʼєкти, на які з нього хтось іще дивиться. Саме на замиканнях побудовані декоратори.</p>
<p class="where">Вводиться: <a href="16-arguments-scope/lecture.html">16. Аргументи й область видимості</a> · <a href="36-decorators/lecture.html">36. Декоратори</a></p>
</article>
<article class="gt" id="zatinennya">
<h3>Затінення <span class="en">shadowing</span></h3>
<p>Ситуація, коли імʼя у вужчій області видимості <b>затуляє</b> таке саме імʼя в ширшій. Локальна змінна <code>список</code> усередині функції ховає глобальну з тим самим імʼям, і зовнішня лишається недоторканою.</p>
<p class="gnote"><b>Найдорожчий випадок</b> — затінити вбудоване імʼя: назвати змінну <code>list</code>, <code>str</code> або <code>id</code>. Помилки не буде <i>там</i>, де ти це зробив — вона вилізе нижче, коли той самий код спробує викликати <code>list(...)</code> і дістане <code>TypeError: 'list' object is not callable</code>.</p>
</article>
<article class="gt" id="zahardkodzhene">
<h3>Захардкоджене значення <span class="en">hard-coded</span></h3>
<p>Значення, вписане просто в текст програми: <code>name = "Олена"</code>. Саме по собі це не гріх — константи на кшталт кількості секунд у годині вписують і мають вписувати. Гріхом воно стає тоді, коли всередині коду опиняються <b>дані</b>, тобто те, що змінюється від запуску до запуску.</p>
<p class="gnote">Курс каже <b>захардкоджене</b>, слідом за англійським <i>hard-coded</i> («твердо вшите»): український відповідник вийшов би описом на пів рядка. Ліки — брати дані ззовні, і курс показує чотири способи: спитати людину (<a href="06-user-input/lecture.html">06. Діалог із користувачем</a>), прочитати файл (<a href="21-files-pathlib/lecture.html">тема 21</a>), узяти з командного рядка (<a href="26-cli-scripts/lecture.html">тема 26</a>) або сходити по них у мережу (<a href="27-http-requests/lecture.html">тема 27</a>).</p>
<p class="where">Вводиться: <a href="06-user-input/lecture.html">06. Діалог із користувачем</a></p>
</article>
<article class="gt" id="zahysna-umova">
<h3>Захисна умова <code>__main__</code> <span class="en">main guard</span></h3>
<p>Рядок <code>if __name__ == "__main__":</code>, який читається як «якщо мене запустили головним, а не імпортували». У змінній <code>__name__</code> при прямому запуску лежить <code>"__main__"</code>, а при імпорті — справжнє імʼя модуля.</p>
<p class="gnote">Правило: на верхньому рівні файлу, який хтось може імпортувати, мають бути тільки означення, а все, що щось <i>робить</i>, ховається під цю умову.</p>
<p class="where">Вводиться: <a href="17-modules/lecture.html">17. Модулі й пакети</a></p>
</article>
<article class="gt" id="zyednannya">
<h3>Зʼєднання <span class="en">connection</span></h3>
<p>Встановлений канал між двома програмами через мережу. Щоб він зʼявився, сторони обмінюються трьома службовими пакетами — і лише після цього можна слати дані.</p>
<p class="gnote"><b>Чому це важливо на практиці.</b> Установлення коштує часу, тож слати сто запитів по сто нових зʼєднань — марнотратство. Тому HTTP уміє тримати зʼєднання відкритим і слати наступні запити ним же (<code>Session</code> у <code>requests</code>). Виграш заміряний, але залежить від налаштувань TCP на боці сервера — тому цитувати варто <b>напрямок</b>, а не множник.</p>
</article>
<article class="gt" id="zminna-seredovyshcha">
<h3>Змінна середовища <span class="en">environment variable</span></h3>
<p>Іменоване значення, яке операційна система передає кожній запущеній програмі. Ніби записка, яку система вкладає в кишеню програмі при старті: та може її прочитати, але писала не вона.</p>
<p class="gnote">Найвідоміша — <code>PATH</code>: перелік тек, у яких система шукає програму, коли ти набрав її імʼя без повного шляху. Саме тому «python не знайдено» майже завжди означає не «не встановлено», а «встановлено не туди, де система дивиться».</p>
</article>
<article class="gt" id="zminnyi-obyekt">
<h3>Змінюваний і незмінний обʼєкт <span class="en">mutable / immutable</span></h3>
<p>Незмінний обʼєкт (<code>int</code>, <code>float</code>, <code>str</code>, <code>tuple</code>, <code>bool</code>, <code>None</code>) після створення вже ніколи не зміниться; будь-яка «зміна» створює новий обʼєкт. Змінюваний (<code>list</code>, <code>dict</code>, <code>set</code>, більшість власних класів) редагують зсередини, не створюючи нового.</p>
<p class="gnote">Незмінність діє лише на один рівень: <code>дані[0] = [9]</code> у кортежі заборонено, а <code>дані[0].append(3)</code> працює — бо міняє не стрілку, а обʼєкт на її кінці.</p>
<p class="where">Вводиться: <a href="03-variables-and-objects/lecture.html">03. Змінні та обʼєкти</a> · <a href="08-tuples/lecture.html">08. Кортежі й розпакування</a></p>
</article>
<article class="gt" id="znachennya-za-zamovchuvannyam">
<h3>Значення за замовчуванням <span class="en">default value</span></h3>
<p>Значення, записане в рядку <code>def</code> через <code>=</code>, яке підставляється, якщо відповідного аргументу не передали. Обчислюється <b>один раз</b>, у момент виконання рядка <code>def</code>, а не на кожен виклик.</p>
<p class="gnote">Звідси найвідоміша пастка Python: <code>def додати(що, кошик=[])</code> отримує щоразу той самий список — уже з усім, що накидали попередні виклики. Ліки: ставити <code>None</code> і створювати список усередині функції.</p>
<p class="where">Вводиться: <a href="16-arguments-scope/lecture.html">16. Аргументи й область видимості</a></p>
</article>
<article class="gt" id="zriz">
<h3>Зріз <span class="en">slice</span></h3>
<p>Взяти не один елемент, а цілий діапазон: <code>послідовність[старт:стоп:крок]</code> — почни зі <i>старту</i>, зупинись <b>перед</b> <i>стопом</i>, крокуй по <i>кроку</i>. Будь-яке з трьох чисел можна пропустити.</p>
<p class="gnote">Верхня межа не входить — звідси дві зручності: довжина зрізу дорівнює <i>стоп − старт</i>, а <code>s[:5] + s[5:]</code> завжди дає вихідний рядок. Зріз ніколи не падає за межі, на відміну від індексу.</p>
<p class="where">Вводиться: <a href="05-strings/lecture.html">05. Рядки</a> · <a href="07-lists/lecture.html">07. Списки</a></p>
</article>
<h2 id="uk-1030"><span class="num">кирилиця</span>І</h2>
<article class="gt" id="identychnist">
<h3>Ідентичність <span class="en">identity</span></h3>
<p>Відповідь на питання «це той самий обʼєкт чи інший, просто схожий?». Її повертає <code>id(x)</code>, і саме про неї питає оператор <code>is</code>, тоді як <code>==</code> питає про значення.</p>
<p class="gnote">Правило: <code>is</code> бережи майже виключно для <code>None</code>. Для чисел і рядків він «працює» на маленьких значеннях і ламається на великих, бо CPython кешує лише цілі від −5 до 256 — це оптимізація, а не правило мови.</p>
<p class="where">Вводиться: <a href="03-variables-and-objects/lecture.html">03. Змінні та обʼєкти</a> · <a href="12-conditions/lecture.html">12. Умови</a></p>
</article>
<article class="gt" id="imya">
<h3>Імʼя <span class="en">name</span></h3>
<p>Ярлик, наклеєний на обʼєкт, а не коробка зі значенням. Знак <code>=</code> спершу обчислює вираз праворуч, і в памʼяті зʼявляється обʼєкт, а потім прикріплює до нього імʼя — цю дію звуть <b>звʼязуванням імені</b> (<i>name binding</i>). Тому <code>b = a</code> — не копіювання, а другий ярлик на той самий обʼєкт.</p>
<p class="gnote">Слово «змінна» лишилось за традицією, але точніше казати <b>імʼя</b>: так написано і в документації Python. Модель «коробки зі значенням» тут не працює: коробка вміщує значення, ярлик лише вказує на нього. Скористатися імʼям до присвоєння не вийде — буде <code>NameError</code>.</p>
<p class="where">Вводиться: <a href="03-variables-and-objects/lecture.html">03. Змінні та обʼєкти</a></p>
</article>
<article class="gt" id="indeks">
<h3>Індекс <span class="en">index</span></h3>
<p>Номер елемента в послідовності, що починається з нуля. Індекс — це не «котрий за рахунком», а <b>відстань від початку</b>, тому нульовий елемент стоїть на нульовій відстані; відʼємний індекс <code>-k</code> означає <code>len(x) - k</code>.</p>
<p class="gnote">У pandas тим самим словом (і тим самим англійським <i>index</i>) звуть інше: окремий обʼєкт із <b>міткою</b> для кожного рядка таблиці, і мітка не мусить збігатися з позицією. Звідси різниця <code>loc</code> (за міткою) і <code>iloc</code> (за позицією) у <a href="39-pandas/lecture.html">темі 39</a>. Третє значення того самого слова — <a href="#indeks-bazy">індекс бази даних</a>: там це вже не номер і не мітка, а окрема структура для швидкого пошуку.</p>
<p class="where">Вводиться: <a href="05-strings/lecture.html">05. Рядки</a> · <a href="07-lists/lecture.html">07. Списки</a></p>
</article>
<article class="gt" id="indeks-bazy">
<h3>Індекс бази даних <span class="en">database index</span></h3>
<p>Окрема структура, у якій значення стовпця лежать упорядковано, а поруч із кожним — вказівка, у якому рядку таблиці воно стоїть. Це покажчик у кінці книжки: пошук у впорядкованому переліку йде діленням навпіл, і на 2,5 млн рядків це 22 кроки замість 2 500 000, тобто 0,020 мс замість 277.</p>
<p class="gnote">Індекс не безкоштовний — саме тому база не створює його сама на кожен стовпець: на тих самих даних файл виріс на 78 %, а вставка 200 000 рядків уповільнилась у 1,7 раза. Створюй під конкретний частий запит, а користь перевіряй <a href="#plan-zapytu">планом запиту</a>. Не плутай із <a href="#indeks">індексом</a> у послідовності й з <i>index</i> у pandas: одне англійське слово, три різні речі.</p>
<p class="where">Вводиться: <a href="23-databases-sql/lecture.html">23. Бази даних і SQL</a></p>
</article>
<article class="gt" id="inicializator">
<h3>Ініціалізатор <span class="en">initializer, <code>__init__</code></span></h3>
<p>Метод <code>__init__</code>, який наповнює вже створений порожній примірник полями й перевіряє, що дані мають сенс. Коли він починає працювати, обʼєкт уже існує й уже має <code>id()</code>.</p>
<p class="gnote">Підручники називають його <b>конструктором</b> — слово прижилось, але неточне: власне створенням обʼєкта займається інший метод, <code>__new__</code>, якого ти майже ніколи не пишеш.</p>
<p class="where">Вводиться: <a href="30-classes/lecture.html">30. Класи й обʼєкти</a></p>
</article>
<article class="gt" id="interpretator">
<h3>Інтерпретатор <span class="en">interpreter</span></h3>
<p>Програма, яка виконує іншу програму. Ти запускаєш не свій файл, а інтерпретатор і даєш йому файл: <code>python hello.py</code>. Він читає твій текст і робить те, що там написано.</p>
<p class="gnote"><b>Не плутай із компілятором.</b> Компілятор перекладає програму заздалегідь і віддає готовий файл, який працює сам. Інтерпретатор потрібен щоразу — тому програму на Python не запустити там, де Python не встановлено.</p>
</article>
<article class="gt" id="istynnist">
<h3>Істинність <span class="en">truthiness</span></h3>
<p>Правило, за яким <code>if</code> питає «ти істина?» у будь-якого обʼєкта, а не лише в <code>bool</code>. Хибними вважаються <code>False</code>, <code>None</code>, нулі будь-якого числового типу й порожні колекції; усе інше істинне.</p>
<p class="gnote">Дві головні пастки — <code>"0"</code> і <code>[0]</code>: обидва істинні, бо непорожні, і Python не заглядає всередину. Пиши <code>if міста:</code>, а не <code>if len(міста) > 0:</code>.</p>
<p class="where">Вводиться: <a href="12-conditions/lecture.html">12. Умови</a> · <a href="32-magic-methods/lecture.html">32. Магічні методи</a></p>
</article>
<article class="gt" id="iterator">
<h3>Ітератор <span class="en">iterator</span></h3>
<p>Крихітний обʼєкт-обхідник, який уміє віддати наступний елемент і запамʼятати, де зупинився. Позиція в ньому тільки росте; повернутись на початок він не вміє принципово.</p>
<p class="gnote">Саме тому <code>zip</code>, <code>enumerate</code>, <code>map</code>, <code>filter</code> і відкритий файл одноразові: пройдені двічі, вдруге вони не зроблять жодного кроку — і навіть не впадуть. У лекціях трапляється синонім «обхідник».</p>
<p class="where">Вводиться: <a href="35-iterators-generators/lecture.html">35. Ітератори й генератори</a> · <a href="13-loops/lecture.html">13. Цикли</a></p>
</article>
<article class="gt" id="iterovanyi">
<h3>Ітерований обʼєкт <span class="en">iterable</span></h3>
<p>Джерело, у якого можна попросити ітератор: список, кортеж, рядок, словник, множина, <code>range</code>, файл. Сам він нічого не памʼятає — просто вміє на вимогу видати новий обхідник, який почне з початку.</p>
<p class="gnote">Питай себе не «чи це працює в <code>for</code>», а «це джерело чи вже обхід». Перевірка одним рядком: <code>iter(список) is iter(список)</code> дає <code>False</code>, а <code>iter(ітератор) is ітератор</code> — <code>True</code>.</p>
<p class="where">Вводиться: <a href="35-iterators-generators/lecture.html">35. Ітератори й генератори</a> · <a href="13-loops/lecture.html">13. Цикли</a></p>
</article>
<h2 id="uk-1050"><span class="num">кирилиця</span>К</h2>
<article class="gt" id="kachyna-typizaciya">
<h3>Качина типізація <span class="en">duck typing</span></h3>
<p>Підхід, у якому питають не про рід обʼєкта, а про його вміння: якщо щось ходить як качка й крякає як качка, для нашої задачі воно й є качка — просто клич потрібний метод.</p>
<p class="gnote"><code>isinstance</code> як спосіб «пустити чи не пустити» майже завжди зайвий. Формально те саме описує <code>Protocol</code> із теми 34: перевірювач звіряє не походження, а форму.</p>
<p class="where">Вводиться: <a href="31-inheritance/lecture.html">31. Наслідування й композиція</a> · <a href="34-type-hints/lecture.html">34. Типи (type hints)</a></p>
</article>
<article class="gt" id="kvantyfikator">
<h3>Квантифікатор <span class="en">quantifier</span></h3>
<p>Позначка в регулярному виразі, що каже, <b>скільки разів</b> повторюється те, що стоїть перед нею: <code>*</code> — нуль і більше, <code>+</code> — один і більше, <code>?</code> — нуль або один, <code>{2,5}</code> — від двох до пʼятьох.</p>
<p class="gnote">За замовчуванням квантифікатор <b>жадібний</b>: бере якнайбільше, а тоді віддає назад, поки решта виразу не зійдеться. Знак питання після нього (<code>+?</code>, <code>*?</code>) робить його ощадним — бере якнайменше. Різниця видна одразу, щойно у тексті трапляється друга така сама дужка чи лапка.</p>
</article>
<article class="gt" id="klas">
<h3>Клас <span class="en">class</span></h3>
<p>Спосіб сказати мові, що в програмі є новий тип даних: ось які поля в ньому обовʼязкові, ось за яких умов він має право існувати, ось що з ним можна робити. Клас — це опис, як креслення; жодного конкретного продажу в ньому немає.</p>
<p class="gnote">Клас потрібен там, де є <b>поведінка</b> — правила, перевірки, обчислення, які мають жити поруч із даними. Один метод і жодного стану — це просто функція.</p>
<p class="where">Вводиться: <a href="30-classes/lecture.html">30. Класи й обʼєкти</a></p>
</article>
<article class="gt" id="kliyent-i-server">
<h3>Клієнт і сервер <span class="en">client and server</span></h3>
<p>Дві ролі в обміні, а не два різні компʼютери. <b>Клієнт</b> питає, <b>сервер</b> відповідає. Та сама машина може бути і тим, і тим — і саме так влаштований навчальний сервер, який ти піднімаєш у себе.</p>
<p class="gnote"><b>Наслідок, який часто пропускають:</b> сервер ніколи не звертається першим. Тому «програма отримала дані з сайту» завжди означає «програма їх попросила» — і відповідальність за частоту прохань лежить на клієнті, тобто на тобі.</p>
</article>
<article class="gt" id="kod-vyhodu">
<h3>Код виходу <span class="en">exit code</span></h3>
<p>Ціле число, яке програма лишає системі, завершуючись: <b>0 — усе гаразд</b>, будь-що інше — щось пішло не так. Це єдине, що бачить про неї той, хто її запустив.</p>
<p class="gnote"><b>Навіщо, якщо є повідомлення.</b> Повідомлення читає людина, код виходу читає <i>інша програма</i>. Саме на ньому тримаються ланцюжки в оболонці (<code>перше && друге</code> запустить друге лише при нулі) і всі системи складання: вони не читають твій текст, вони дивляться число. <b>Не плутай із кодом стану HTTP</b> — то інше поняття й інша стаття.</p>
</article>
<article class="gt" id="kod-stanu">
<h3>Код стану <span class="en">status code</span></h3>
<p>Трицифрове число в першому рядку відповіді HTTP — те, за чим ухвалює рішення програма (слова поруч, <code>OK</code> чи <code>Not Found</code>, потрібні лише людині). Учити напамʼять нема чого, бо це не список, а система: значення несе <b>перша цифра</b>. <code>2xx</code> — зробив, що просив; <code>3xx</code> — воно за іншою адресою; <code>4xx</code> — запит поганий, винен клієнт; <code>5xx</code> — запит нормальний, зламався сервер.</p>
<p class="gnote">Найдорожча плутанина блоку: <code>404</code> — це <b>успішно доставлена відповідь</b>, а не помилка Python. Сервер тебе почув і відповів, тому жодного <a href="#vynyatok">винятку</a> не буде — його треба попросити самому через <code>r.raise_for_status()</code>. І навпаки, <code>ConnectionError</code> чи <code>Timeout</code> означають, що відповіді не було <b>зовсім</b>: коду стану не існує, бо його ніхто не надсилав, і читати нема чого. Практичний наслідок першої цифри: на <code>4xx</code> повтор дасть те саме, бо міняти треба запит; на <code>5xx</code> повтор може врятувати.</p>
<p class="where">Вводиться: <a href="27-http-requests/lecture.html">27. HTTP-запити</a> · <a href="28-working-with-api/lecture.html">28. Робота з API</a></p>
</article>
<article class="gt" id="koduvannya">
<h3>Кодування <span class="en">encoding</span></h3>
<p>Таблиця відповідності між байтами у файлі й символами тексту. Кодування в самому файлі не зберігається — його треба знати наперед і передавати явно: <code>open(..., encoding="utf-8")</code>. Стандарт де-факто — <b>UTF-8</b>, змінної довжини: латиниця займає 1 байт, кирилиця — 2, емодзі — 4.</p>
<p class="gnote">Без явного <code>encoding</code> Python бере налаштування системи, тому той самий код читає файл по-різному на Linux і на Windows. Тиха біда — мотлох на кшталт «РљРёС—РІ», гучна — <code>UnicodeDecodeError</code>. <code>len()</code> рахує символи, а не байти; файли з Excel часто починаються з мітки BOM, що ламає першу колонку, — це лікує <code>utf-8-sig</code>.</p>
<p class="where">Вводиться: <a href="05-strings/lecture.html">05. Рядки</a> · <a href="21-files-pathlib/lecture.html">21. Файли й pathlib</a></p>
</article>
<article class="gt" id="koliziya">
<h3>Колізія <span class="en">hash collision</span></h3>
<p>Ситуація, коли два різні ключі потрапляють в одну й ту саму комірку хеш-таблиці. Це не збій і не рідкість: комірок скінченна кількість, а ключів може бути скільки завгодно, тож збіги неминучі.</p>
<p class="gnote">Скільки їх насправді, підказує «парадокс днів народження»: уже пʼять ключів у восьми комірках дають колізію з імовірністю близько <b>80 %</b>. Тому словник не намагається колізій уникнути — він уміє їх <b>розвʼязувати</b>: шукає наступну вільну комірку за визначеним правилом. Саме через це видалення в словнику лишає позначку «тут було порожньо не завжди», а не просто звільняє комірку.</p>
</article>
<article class="gt" id="kompilyaciya">
<h3>Компіляція <span class="en">compilation</span></h3>
<p>Переклад програми з мови, якою пише людина, у форму, придатну до виконання, — <b>до</b> запуску, а не під час нього.</p>
<p class="gnote">Аналогія, яка тримає різницю в голові: компіляція — це <b>переклад книжки</b>, зроблений наперед і виданий окремим томом; інтерпретація — <b>синхронний перекладач</b>, який працює поруч щоразу. Python робить і те, і те: компілює твій текст у байт-код, а тоді інтерпретує байт-код.</p>
</article>
<article class="gt" id="kompoziciya">
<h3>Композиція <span class="en">composition</span></h3>
<p>Спосіб повторного використання коду, коли обʼєкт не успадковує поведінку, а тримає інший обʼєкт у своєму атрибуті й звертається до нього. Передавання роботи такому обʼєкту звуть <b>делегуванням</b>.</p>
<p class="gnote">Формула для памʼяті: наслідування — «Книга <b>є</b> різновидом Видання», композиція — «Книга <b>має</b> всередині Носій». Композицію варто писати за замовчуванням.</p>
<p class="where">Вводиться: <a href="31-inheritance/lecture.html">31. Наслідування й композиція</a></p>
</article>
<article class="gt" id="konveyer">
<h3>Конвеєр <span class="en">pipe, pipeline</span></h3>
<p>У командному рядку — вертикальна риска <code>|</code>, що зʼєднує вивід лівої програми з входом правої. У роботі з генераторами — кілька генераторів, зчеплених один з одним, де дані не течуть уперед, а їх тягнуть назад, по одному елементу.</p>
<p class="gnote">Ідея в обох випадках та сама: жодного проміжного файлу чи списку не існує ніде. У командному рядку конвеєр іноді називають «трубою».</p>
<p class="where">Вводиться: <a href="06-user-input/lecture.html">06. Діалог із користувачем</a> · <a href="26-cli-scripts/lecture.html">26. Скрипти командного рядка</a> · <a href="35-iterators-generators/lecture.html">35. Ітератори й генератори</a></p>
</article>
<article class="gt" id="kopiya">
<h3>Копія: поверхнева й глибока <span class="en">shallow / deep copy</span></h3>
<p>Поверхнева копія (<code>a[:]</code>, <code>list(a)</code>, <code>a.copy()</code>) — новий список із новими комірками, але комірки заповнені <b>тими самими</b> посиланнями. Глибока (<code>copy.deepcopy(a)</code>) обходить структуру рекурсивно й створює новий обʼєкт на кожному рівні вкладеності.</p>
<p class="gnote">Поки всередині лише рядки й числа, різниці не видно; щойно зʼявиться вкладений список — поверхнева копія «протікає». Правило: лише незмінні елементи — вистачить <code>a.copy()</code>, є вкладені змінювані — потрібен <code>deepcopy</code>.</p>
<p class="where">Вводиться: <a href="07-lists/lecture.html">07. Списки</a></p>
</article>
<article class="gt" id="korotke-zamykannya">
<h3>Коротке замикання <span class="en">short-circuit evaluation</span></h3>
<p><code>and</code> і <code>or</code> ліниві: обчислюють лівий операнд і, якщо його достатньо для відповіді, правий не обчислюють узагалі. Звідси головна ідіома захисту — <code>if вимірів != 0 and сума / вимірів > 15</code>.</p>
<p class="gnote">Вони повертають не <code>True</code>/<code>False</code>, а один із самих операндів — тому <code>введено or 10</code> тихо замінить чесний нуль на десятку. Якщо питання саме «значення не задали», пиши <code>is None</code>.</p>
<p class="where">Вводиться: <a href="12-conditions/lecture.html">12. Умови</a></p>
</article>
<article class="gt" id="kortezh">
<h3>Кортеж <span class="en">tuple</span></h3>
<p>Упорядкований набір значень, як список, але без жодної операції, що його змінює. Створює його <b>кома</b>, а не дужки: <code>(5)</code> — це число в дужках, а <code>(5,)</code> і <code>5,</code> — кортежі.</p>
<p class="gnote">Кортеж обирають не за швидкістю, а за змістом: «одна річ із кількох фіксованих полів», тоді як список — «багато однорідних штук, кількість плаває». Зайва кома в кінці рядка мовчки робить кортеж і вилазить чужим <code>TypeError</code>.</p>
<p class="where">Вводиться: <a href="08-tuples/lecture.html">08. Кортежі й розпакування</a></p>
</article>
<article class="gt" id="korutyna">
<h3>Корутина <span class="en">coroutine</span></h3>
<p>Обʼєкт, який повертає виклик функції, оголошеної через <code>async def</code>: усередині записано, що треба зробити, але ніхто ще не почав це робити. Рецепт, а не страва — виконання починається лише з <code>await</code>.</p>
<p class="gnote">Курс каже <b>корутина</b>; у <a href="35-iterators-generators/lecture.html">темі 35</a> той самий англійський <i>coroutine</i> перекладено як «співпрограма» — там ідеться про генератор, який уміє приймати значення через <code>send()</code>. Це той самий корінь, але різні механізми, і плутати їх не варто.</p>
<p class="where">Вводиться: <a href="37-async/lecture.html">37. Асинхронність — базово</a> · <a href="35-iterators-generators/lecture.html">35. Ітератори й генератори</a></p>
</article>
<article class="gt" id="krykhkyi-selektor">
<h3>Крихкий і стійкий селектор <span class="en">brittle / robust selector</span></h3>
<p>Крихкий селектор тримається за <b>форму</b> дерева: <code>div > div > div:nth-child(3)</code> означає «третій блок у другому блоці в першому» і працює рівно до першої зайвої обгортки. Стійкий тримається за <b>сенс</b>: клас <code>price</code> названий так тому, що там ціна, і при перемальовуванні картки його швидше збережуть, ніж вкладеність.</p>
<p class="gnote">Безсмертного селектора немає — питання лише в тому, чи дізнаєшся ти про поломку. Найгірший результат зламаного <a href="#skraping">скрапера</a> не помилка, а <b>мовчазний порожній список</b>: програма відпрацювала, файл записався, у ньому самий заголовок, і ніхто цього не читає до кінця кварталу. Тому в скрапер вбудовують дешеву перевірку — <code>if len(rows) < 3: raise ValueError(...)</code>, — яка перетворює тиху поломку на гучну.</p>
<p class="where">Вводиться: <a href="29-web-scraping/lecture.html">29. Скрапінг сторінок</a></p>
</article>
<h2 id="uk-1051"><span class="num">кирилиця</span>Л</h2>
<article class="gt" id="limit-chastoty">
<h3>Ліміт частоти <span class="en">rate limit</span></h3>
<p>Скільки запитів на хвилину або годину чужий сервіс дозволяє одному клієнтові. Перевищив — отримуєш <code>429 Too Many Requests</code>, а разом із ним зазвичай заголовок <code>Retry-After</code>: скільки секунд чекати.</p>
<p class="gnote"><code>Retry-After</code> — не порада, а пряма вказівка: сервер знає краще за тебе, коли твій ліміт відновиться, а ігнорувати його — найшвидший спосіб перетворити тимчасове обмеження на постійне блокування. Найдешевша ввічливість — <code>time.sleep(1.0)</code> у циклі: при ліміті 60 запитів на хвилину це рівно межа й жодної арифметики. Чимало сервісів показують залишок заздалегідь, у заголовку <code>X-RateLimit-Remaining</code>, — пригальмовувати по ньому акуратніше, ніж дочікуватись відмови.</p>
<p class="where">Вводиться: <a href="28-working-with-api/lecture.html">28. Робота з API</a></p>
</article>
<h2 id="uk-1052"><span class="num">кирилиця</span>М</h2>
<article class="gt" id="magichnyi-metod">
<h3>Магічний метод <span class="en">magic method, dunder method</span></h3>
<p>Метод із подвійними підкресленнями з обох боків імені (<code>__len__</code>, <code>__eq__</code>, <code>__enter__</code>), за яким стоїть домовленість із мовою: реалізуєш його — і твій обʼєкт починає працювати з <code>len</code>, <code>for</code>, <code>in</code>, <code>+</code> чи <code>with</code> як вбудований тип. Домовленість про те, як метод зветься, що приймає й що повертає, звуть <b>протоколом</b> (<i>protocol</i>).</p>
<p class="gnote">Ніякої магії немає: <code>len(x)</code> — це коротка форма запису <code>type(x).__len__(x)</code>. Шукаються такі методи в <b>класі</b>, а не в примірнику. Англійське <i>dunder</i> (від <i>double underscore</i>) у лекціях трапляється як «дандер-метод», але канонічна назва курсу — <b>магічний метод</b>.</p>
<p class="where">Вводиться: <a href="32-magic-methods/lecture.html">32. Магічні методи</a> · <a href="35-iterators-generators/lecture.html">35. Ітератори й генератори</a></p>
</article>
<article class="gt" id="masyv-ndarray">
<h3>Масив <span class="en">array, ndarray</span></h3>
<p>Суцільний блок памʼяті, у якому лежать <b>самі числа</b> одного типу, одне за одним. Не список посилань на розкидані обʼєкти, а рівна стрічка байтів із відомим кроком.</p>
<p class="gnote"><b>Звідси все інше.</b> Суцільність дає швидкість (процесор читає сусідні комірки наперед) і компактність: мільйон цілих у масиві <code>int64</code> — 7.63 МіБ проти 34.3 МіБ у списку, бо там до кожного числа ще й посилання. Ціна — <b>один тип на весь масив</b>: покласти поруч число й рядок не вийде.</p>
</article>
<article class="gt" id="maska">
<h3>Маска <span class="en">boolean mask</span></h3>
<p>Масив або стовпець зі значеннями <code>True</code>/<code>False</code>, який повертає порівняння: питання, задане масиву, приходить назад масивом відповідей. Такою маскою індексують — лишаються лише елементи, навпроти яких <code>True</code>.</p>
<p class="gnote">Умови поєднують <code>&</code>, <code>|</code>, <code>~</code> — не <code>and</code>/<code>or</code>/<code>not</code>, — і кожну обовʼязково беруть у власні дужки, бо <code>&</code> звʼязує сильніше за <code>></code>.</p>
<p class="where">Вводиться: <a href="38-numpy/lecture.html">38. NumPy: масиви</a> · <a href="39-pandas/lecture.html">39. Pandas: таблиці</a></p>
</article>
<article class="gt" id="menedzher-kontekstu">
<h3>Менеджер контексту <span class="en">context manager</span></h3>
<p>Обʼєкт, який уміє стояти після <code>with</code>: він знає, що зробити на вході в блок (<code>__enter__</code>) і що зробити на виході (<code>__exit__</code>), причому вихід відбувається <b>завжди</b> — хоч через кінець блоку, хоч через <code>return</code> чи виняток.</p>
<p class="gnote"><code>with</code> закриває, але не рятує: виняток, що стався всередині, летить далі вгору так само, як без <code>with</code>. Менеджер контексту гарантує прибирання, а не тишу.</p>
<p class="where">Вводиться: <a href="21-files-pathlib/lecture.html">21. Файли й pathlib</a> · <a href="32-magic-methods/lecture.html">32. Магічні методи</a> · <a href="19-exceptions/lecture.html">19. Помилки та винятки</a></p>
</article>
<article class="gt" id="metod">
<h3>Метод <span class="en">method</span></h3>
<p>Функція, означена в тілі класу й «приклеєна» до обʼєкта: пишеться через крапку після нього — <code>напій.upper()</code>. Відмінність від звичайної функції рівно одна: перший параметр <a href="#self"><code>self</code></a>.</p>
<p class="gnote">Найчастіша помилка новачка з методами рядка — викликати <code>напій.upper()</code> і нічого не записати: рядок незмінний, тож новий створено й тієї ж миті викинуто.</p>
<p class="where">Вводиться: <a href="05-strings/lecture.html">05. Рядки</a> · <a href="30-classes/lecture.html">30. Класи й обʼєкти</a></p>
</article>
<article class="gt" id="metod-http">
<h3>Метод HTTP <span class="en">HTTP method</span></h3>
<p>Перше слово запиту — те, що ми хочемо зробити з <a href="#resurs">ресурсом</a>: <code>GET</code> (дай мені це), <code>POST</code> (ось нові дані, прийми), <code>PUT</code> (хай за цією адресою буде ось це), <code>PATCH</code> (зміни цю частину), <code>DELETE</code> (прибери), <code>HEAD</code> (лише заголовки, без тіла). Різниця між ними не технічна, а смислова: це домовленість про наміри, якої дотримуються всі.</p>
<p class="gnote">Зі звичайним <a href="#metod">методом</a> обʼєкта спільне тут лише слово. Два питання, які вирішують усе про метод, — чи він <a href="#bezpechnyi-metod">безпечний і ідемпотентний</a>. У стилі <a href="#rest">REST</a> діє правило «іменник у шляху, дієслово в методі»: адреси на кшталт <code>/getMenu</code> теж трапляються, але там дієслово запхали в шлях, і метод перестає щось означати.</p>
<p class="where">Вводиться: <a href="27-http-requests/lecture.html">27. HTTP-запити</a> · <a href="28-working-with-api/lecture.html">28. Робота з API</a></p>
</article>
<article class="gt" id="mnozhyna">
<h3>Множина <span class="en">set</span></h3>
<p>Набір несхожих елементів без порядку — той самий словник, у якого забрали значення й лишили самі ключі. Той самий елемент не може лежати в ній двічі, а питання «що там перше» до неї не ставлять узагалі.</p>
<p class="gnote">Порожню множину не можна записати як <code>{}</code> — порожні фігурні дужки історично закріплені за словником; єдиний спосіб — <code>set()</code>. Незмінний різновид зветься <code>frozenset</code> і тому може бути ключем словника.</p>
<p class="where">Вводиться: <a href="10-sets/lecture.html">10. Множини</a></p>
</article>
<article class="gt" id="modul">
<h3>Модуль <span class="en">module</span></h3>
<p>Файл із розширенням <code>.py</code>; його імʼя — імʼя файлу без <code>.py</code>. Іншого означення немає: будь-який твій файл уже є модулем. Тека з модулями — це <b>пакет</b> (<i>package</i>).</p>
<p class="gnote">Кожен модуль має власний <b>простір імен</b> (<i>namespace</i>), тому однакові імена в різних файлах не заважають одне одному. Імпорт — це виконання файлу згори вниз, і рівно один раз за запуск: далі модуль беруть із кешу <code>sys.modules</code>.</p>
<p class="where">Вводиться: <a href="17-modules/lecture.html">17. Модулі й пакети</a></p>
</article>
<h2 id="uk-1053"><span class="num">кирилиця</span>Н</h2>
<article class="gt" id="naivnyi-chas">
<h3>Наївний і обізнаний час <span class="en">naive / aware datetime</span></h3>
<p>Наївний <code>datetime</code> має порожнє поле <code>tzinfo</code>: він знає, що написано на циферблаті, і не знає, чий це циферблат, тому не позначає жодної конкретної миті. Обізнаний знає ще й <b>часовий пояс</b> — і тому вказує на мить однозначно.</p>
<p class="gnote">Порівняння наївного з обізнаним через <code><</code> дає <code>TypeError</code>, а <code>==</code> тихо повертає <code>False</code> — перевірка мовчки не спрацює жодного разу. Правильне «зараз» — <code>datetime.now(timezone.utc)</code>.</p>
<p class="where">Вводиться: <a href="24-datetime/lecture.html">24. Дати й час</a></p>
</article>
<article class="gt" id="nasliduvannya">
<h3>Наслідування <span class="en">inheritance</span></h3>
<p>Спосіб оголосити один клас різновидом іншого: похідний клас автоматично отримує методи базового. Оголосити в похідному класі метод із тим самим імʼям — це <b>перевизначення</b> (<i>overriding</i>).</p>
<p class="gnote">Успадковуються методи, а не дані. Найпоширеніша пастка — написати свій <code>__init__</code> і не покликати в ньому <code>super().__init__(...)</code>: обʼєкт створиться без помилки, а впаде значно пізніше й в іншому місці.</p>
<p class="where">Вводиться: <a href="31-inheritance/lecture.html">31. Наслідування й композиція</a></p>
</article>
<h2 id="uk-1054"><span class="num">кирилиця</span>О</h2>
<article class="gt" id="oblast-vydymosti">
<h3>Область видимості <span class="en">scope</span></h3>
<p>Ділянка тексту програми, у якій імʼя видиме. Вона визначається <b>текстом</b>, а не ланцюжком викликів: вкладена функція бачить імена тієї функції, у чиє тіло вона записана, а не тієї, що її покликала.</p>
<p class="gnote">Локальність вирішується наперед: якщо десь у тілі функції є присвоєння імені, воно локальне від першого рядка — звідси <code>UnboundLocalError</code> при спробі спершу прочитати зовнішнє значення. Порядок пошуку описує <a href="#legb">LEGB</a>.</p>
<p class="where">Вводиться: <a href="16-arguments-scope/lecture.html">16. Аргументи й область видимості</a></p>
</article>
<article class="gt" id="obyekt">
<h3>Обʼєкт <span class="en">object</span></h3>
<p>Усе, що живе в памʼяті Python: число, рядок, список, функція й навіть сам тип. Кожен обʼєкт має рівно три речі — тип, значення й ідентичність.</p>
<p class="gnote">Це не фігура мови, а буквальне влаштування мови: саме тому функцію можна покласти в список, а клас — передати аргументом.</p>
<p class="where">Вводиться: <a href="03-variables-and-objects/lecture.html">03. Змінні та обʼєкти</a></p>
</article>
<h2 id="uk-1055"><span class="num">кирилиця</span>П</h2>
<article class="gt" id="paginaciya">
<h3>Пагінація <span class="en">pagination</span></h3>
<p>Домовленість віддавати довгий перелік не одним шматком, а сторінками. Разом із самими записами у відповіді приходять службові поля: скільки їх усього (<code>total</code>) і яка сторінка наступна (<code>next</code>). На останній сторінці <code>next</code> дорівнює <code>null</code>, тобто в Python — <code>None</code>: це і є сигнал зупинитись.</p>
<p class="gnote">Обхід — цикл «поки є <code>next</code>», і в нього обовʼязково вбудовують <b>стелю кроків</b>. Умову виходу тут визначає чужа програма, і помилка на її боці (<code>next</code> починає вказувати сам на себе) перетворює твій цикл на нескінченний, а дізнаєшся ти про це, коли сервіс тебе заблокує. Правило ширше за пагінацію: будь-який цикл, вихід з якого визначає чужа відповідь, має власний лічильник. Буває й пагінація <b>курсором</b> — сервер віддає непрозорий рядок замість номера сторінки; вона не збивається, коли в колекцію під час обходу щось додали.</p>
<p class="where">Вводиться: <a href="28-working-with-api/lecture.html">28. Робота з API</a></p>
</article>
<article class="gt" id="paket">
<h3>Пакет <span class="en">package</span></h3>
<p>Тека з модулями, яку Python імпортує як одне ціле: <code>from krama import zvit</code>. Тобто спосіб згрупувати кілька файлів під спільним іменем, коли одного модуля вже мало.</p>
<p class="gnote"><b>Слово має два значення, і їх плутають щодня.</b> Пакет <i>у мові</i> — це тека з модулями, про яку тут і йдеться. Пакет <i>у pip</i> — те, що ставлять командою <code>pip install</code>, тобто одиниця розповсюдження, і всередині неї може бути кілька мовних пакетів, один модуль або взагалі жодного. Ім’я в <code>pip install</code> і ім’я в <code>import</code> часто різні.</p>
</article>
<article class="gt" id="parametr">
<h3>Параметр і аргумент <span class="en">parameter / argument</span></h3>
<p>Параметр — імʼя в дужках у рядку <code>def</code>, «порожнє місце» на вході функції. Аргумент — конкретне значення, яке підставляють у момент виклику.</p>
<p class="gnote">Параметр один на всю функцію, аргументи різні на кожен виклик. Курс тримається цієї пари послідовно й не вживає «формальний / фактичний аргумент».</p>
<p class="where">Вводиться: <a href="15-functions/lecture.html">15. Функції</a> · <a href="16-arguments-scope/lecture.html">16. Аргументи й область видимості</a></p>
</article>
<article class="gt" id="parametryzovanyi-zapyt">
<h3>Параметризований запит <span class="en">parameterized query</span></h3>
<p>Єдиний правильний спосіб підставити значення в SQL: замість значення в тексті стоїть <code>?</code>, а саме значення їде окремим кортежем — <code>con.execute("select ... where login=?", (login,))</code>. Є й іменована форма для випадків, коли параметрів багато: <code>:cat</code> у запиті і словник <code>{"cat": "кава"}</code> поруч.</p>
<p class="gnote">Працює це не через «екранування»: текст запиту й дані база отримує <b>окремо</b> — структуру вона розбирає до того, як побачить значення, і далі вже нізащо не сприйме дані як команду. Звідси й межа: через <code>?</code> підставляють тільки значення, <code>select * from ?</code> не працює в принципі. Якщо назва стовпця приходить ззовні, її не «екранують», а звіряють зі списком дозволених і кидають <code>ValueError</code>.</p>
<p class="where">Вводиться: <a href="23-databases-sql/lecture.html">23. Бази даних і SQL</a></p>
</article>
<article class="gt" id="parser">
<h3>Парсер <span class="en">parser</span></h3>
<p>Програма, яка перетворює плаский текст на структуру: розмітку сторінки — на дерево <a href="#vuzol">вузлів</a>, текст <a href="#json">JSON</a> — на словники й списки. <code>BeautifulSoup</code> сама розбором не займається: вона зручна обгортка, а парсер їй передають другим аргументом — <code>"html.parser"</code> зі стандартної бібліотеки, <code>"lxml"</code> заради швидкості, <code>"html5lib"</code> для найкривішої розмітки.</p>
<p class="gnote">Канонічна назва курсу — <b>парсер</b>, а не «розбирач»: слово усталене, і читач зустріне його як значення аргументу в коді. Задавай парсер завжди явно: без другого аргументу бібліотека візьме, що знайде, і код мовчки залежатиме від того, які пакети стоять на конкретній машині. І головне правило теми: розмітку розбирає парсер, а не <a href="#regulyarnyi-vyraz">регулярний вираз</a>.</p>
<p class="where">Вводиться: <a href="29-web-scraping/lecture.html">29. Скрапінг сторінок</a></p>
</article>
<article class="gt" id="pervynnyi-klyuch">
<h3>Первинний і зовнішній ключ <span class="en">primary key / foreign key</span></h3>
<p><b>Первинний ключ</b> — стовпець із унікальним значенням, яким рядок називають: другий рядок із тим самим <code>id</code> дасть помилку, а не мовчазний дублікат. <b>Зовнішній ключ</b> (<code>references drinks(id)</code>) — стовпець, який мусить указувати на наявний рядок іншої таблиці. Разом вони й дають головне правило розкладання даних по таблицях: кожен факт живе рівно в одному місці, а решта на нього посилається.</p>
<p class="gnote">Дві місцеві дрібниці SQLite. <code>integer primary key</code> вона розуміє особливо: такий стовпець стає внутрішнім номером рядка, і при вставці база сама підставить наступне вільне число (дізнатись його — <code>cur.lastrowid</code>). А перевірку зовнішніх ключів за замовчуванням <b>вимкнено</b>: оголошення в <code>create table</code> є, перевірки немає, і замовлення на неіснуючий напій пройде мовчки. Умикає її <code>pragma foreign_keys = on</code> — і робити це треба на кожному зʼєднанні заново, бо налаштування не зберігається у файлі бази.</p>
<p class="where">Вводиться: <a href="23-databases-sql/lecture.html">23. Бази даних і SQL</a></p>
</article>
<article class="gt" id="perenapravlennya">
<h3>Перенаправлення <span class="en">redirect</span></h3>
<p>Відповідь класу <code>3xx</code>: «того, що ти просиш, за цією адресою немає, але я знаю, де воно» — і заголовок <code>Location</code> із новою адресою. <code>requests</code> іде за ним сам, доки не дійде до відповіді без <code>Location</code>, тому в звичайному коді <code>301</code> навіть не видно.</p>
<p class="gnote">Слід при цьому не зникає: <code>r.url</code> — адреса, за якою відповідь отримано <b>насправді</b>, а не та, яку ти просив; <code>r.history</code> — список проміжних відповідей; <code>allow_redirects=False</code> зупиняє похід і віддає сам <code>301</code>. Різниця між кодами не косметична: <code>301</code>, <code>302</code> і <code>303</code> дозволяють змінити метод (<code>POST</code> може стати <code>GET</code>), а <code>307</code> і <code>308</code> — ні.</p>
<p class="where">Вводиться: <a href="27-http-requests/lecture.html">27. HTTP-запити</a></p>
</article>
<article class="gt" id="pidkazka">
<h3>Підказка <span class="en">prompt</span></h3>
<p>Текст у дужках <code>input("Скільки зошитів? ")</code> — те, що програма друкує перед тим, як зупинитись і чекати. Технічно це рівно <code>print(підказка, end="")</code>, тому курсор лишається в тому самому рядку, і людина друкує відповідь одразу після знака питання.</p>
<p class="gnote">Підказка — не просто повідомлення, яке програма показує принагідно: це <b>вся документація</b> твоєї програми, іншої в неї немає, бо людина не читатиме код. Звідси чотири правила: пробіл у кінці; одиниці виміру в дужках («Ціна за штуку (грн): »); приклад формату замість опису («Дата (2026-09-01): »); перелік допустимих відповідей, якщо їх мало («Продовжити? (так/ні): »). Погана підказка не просто незручна — вона породжує помилки, які потім доводиться ловити.</p>
<p class="where">Вводиться: <a href="06-user-input/lecture.html">06. Діалог із користувачем</a></p>
</article>
<article class="gt" id="plan-zapytu">
<h3>План запиту <span class="en">query plan</span></h3>
<p>Відповідь бази на питання «як ти збираєшся це виконувати». Показує її <code>explain query plan</code>, який самого запиту не виконує; текст плану лежить у четвертому полі рядка (<code>row[3]</code>). Два слова, заради яких у нього й дивляться: <code>SCAN</code> — «перегляну всю таблицю», <code>SEARCH ... USING INDEX ...</code> — «піду через <a href="#indeks-bazy">індекс</a>».</p>
<p class="gnote">Це єдиний чесний доказ, що індекс справді працює: час залежить від машини й навантаження, а слово в плані — ні. SQL декларативний, ти пишеш <i>що</i> хочеш отримати, а <i>як</i> це шукати вирішує планувальник усередині бази — план і є тим місцем, де його рішення видно.</p>
<p class="where">Вводиться: <a href="23-databases-sql/lecture.html">23. Бази даних і SQL</a></p>
</article>
<article class="gt" id="pozyciynyi-argument">
<h3>Позиційний і іменований аргумент <span class="en">positional / keyword argument</span></h3>
<p>Позиційний передають без імені, і все вирішує порядок. Іменований передають із явною вказівкою параметра — <code>оформити(товар="мед", кількість=3)</code>, — і порядок йому байдужий.</p>
<p class="gnote">Усі позиційні мають стояти перед усіма іменованими, інакше <code>SyntaxError</code>. Переставлені позиційні аргументи часто дають не помилку, а мовчки неправильну відповідь, тому булеві прапорці й числа-налаштування варто іменувати завжди.</p>
<p class="where">Вводиться: <a href="16-arguments-scope/lecture.html">16. Аргументи й область видимості</a></p>
</article>
<article class="gt" id="polimorfizm">
<h3>Поліморфізм <span class="en">polymorphism</span></h3>
<p>Один і той самий виклик працює з різними типами, і кожен відповідає по-своєму. <code>len()</code> однаково питає довжину в рядка, списку й словника, хоча всередині вони влаштовані зовсім різно.</p>
<p class="gnote"><b>У Python це не про наслідування.</b> У багатьох мовах поліморфізм вимагає спільного предка; тут достатньо, щоб обʼєкт мав потрібний метод. Тому два класи, не повʼязані нічим, однаково лягають у <code>sorted()</code>, якщо обидва вміють <code>__lt__</code>.</p>
</article>
<article class="gt" id="port">
<h3>Порт <span class="en">port</span></h3>
<p>Число від 0 до 65535, що каже, <b>яка саме програма</b> на машині має отримати дані. Адреса вказує на компʼютер, порт — на службу всередині нього.</p>
<p class="gnote">Аналогія, яка тримається: адреса — це будинок, порт — номер квартири. Тому в <code>127.0.0.1:8000</code> перше — «куди», друге — «до кого». Типові номери (80 для HTTP, 443 для HTTPS) браузер підставляє сам, і саме тому в звичайних посиланнях порту не видно.</p>
</article>
<article class="gt" id="predstavlennya">
<h3>Представлення словника <span class="en">dict view</span></h3>
<p>Те, що повертають <code>.keys()</code>, <code>.values()</code> і <code>.items()</code> — не списки й не копії, а живі вікна в той самий словник: змінити через них нічого не можна, зате вони самі оновлюються разом зі словником.</p>
<p class="gnote">Англійською це теж <i>view</i>, як і <a href="#vyglyad">вигляд</a> масиву NumPy, але поводяться вони по-різному: представлення тільки читає, а у вигляд можна писати — і запис дійде до оригіналу. Щоб отримати застиглу копію, пиши <code>list(книга.keys())</code>.</p>
<p class="where">Вводиться: <a href="09-dictionaries/lecture.html">09. Словники</a></p>
</article>
<article class="gt" id="prymirnyk">
<h3>Примірник <span class="en">instance</span></h3>
<p>Конкретний обʼєкт, зроблений за описом класу. Щоб його отримати, клас викликають, як функцію: <code>Продаж("кава", 3, 90.0)</code>. Один клас — скільки завгодно примірників, кожен зі своїми даними, але з одним спільним набором правил.</p>
<p class="gnote">Канонічна назва курсу — <b>примірник</b>; «екземпляр» та «інстанс» трапляються в інших текстах, але тут їх не вживають.</p>
<p class="where">Вводиться: <a href="30-classes/lecture.html">30. Класи й обʼєкти</a></p>
</article>
<h2 id="uk-1056"><span class="num">кирилиця</span>Р</h2>
<article class="gt" id="prostir-imen">
<h3>Простір імен <span class="en">namespace</span></h3>
<p>Набір імен, доступних у певному місці програми, разом із тим, на що вони вказують. Кожен модуль має свій; тому <code>math.pi</code> і <code>numpy.pi</code> мирно співіснують, не переплутавшись.</p>
<p class="gnote"><b>Не плутай з областю видимості.</b> Простір імен — це <i>сховище</i> «ім’я → об’єкт». Область видимості — <i>правило пошуку</i>, у яких сховищах і в якому порядку шукати ім’я, написане в коді. Перше відповідає на «що там лежить», друге — на «де шукати».</p>
</article>
<article class="gt" id="protokol">
<h3>Протокол <span class="en">protocol</span></h3>
<p>Домовленість про те, <b>які методи</b> має обʼєкт, щоб із ним працювала певна вбудована можливість мови. Є <code>__len__</code> — працює <code>len()</code>; є <code>__iter__</code> — працює <code>for</code>; є <code>__lt__</code> — працює <code>sorted()</code>.</p>
<p class="gnote"><b>Протокол ніде не оголошують.</b> Немає рядка «цей клас підтримує ітерацію» — є лише наявність методу. Тому Python і не питає, від кого клас успадкований: він питає, що клас <i>уміє</i>. Це та сама якісна типізація, тільки з боку мови, а не з боку твого коду.</p>
</article>
<article class="gt" id="regresiya">
<h3>Регресія <span class="en">regression</span></h3>
<p>Поломка того, що вчора працювало, як побічний ефект сьогоднішньої зміни: ти правиш одну функцію, а ламається сусідня, яка її викликає.</p>
<p class="gnote">Ручна перевірка тут не рятає з простої причини: ти перевіряєш те, що правив, а ламається те, чого не чіпав. Знайшов баг — спершу відтвори його тестом, і тільки потім лагодь.</p>
<p class="where">Вводиться: <a href="20-testing/lecture.html">20. Тестування з pytest</a></p>
</article>
<article class="gt" id="regulyarnyi-vyraz">
<h3>Регулярний вираз <span class="en">regular expression</span></h3>
<p>Крихітна мова, якою описують <b>форму</b> тексту, а не сам текст. Потрібна тоді, коли перелічити всі варіанти неможливо: «усі числа», «дата у трьох форматах», «правильний телефон».</p>
<p class="gnote">Шаблон завжди пишуть <b>сирим рядком</b> (<i>raw string</i>) — <code>r"\d+"</code>, — щоб зворотні скісні дійшли до модуля <code>re</code> недоторканими. Вкладені структури (HTML, JSON, дужки) регулярний вираз не описує принципово. У розмові кажуть «регулярка».</p>
<p class="where">Вводиться: <a href="25-regex/lecture.html">25. Регулярні вирази</a></p>
</article>
<article class="gt" id="resurs">
<h3>Ресурс <span class="en">resource</span></h3>
<p>Річ, яку називає адреса в API: <code>/menu</code> — усе меню, <code>/menu/2</code> — друга позиція, <code>/orders/4417/items</code> — позиції замовлення 4417. А що з цією річчю робити, каже не адреса, а <a href="#metod-http">метод</a>.</p>
<p class="gnote">Дві дрібниці, які видають правильно зроблений сервіс. Створення нового ресурсу він підтверджує кодом <code>201 Created</code>, а не <code>200 OK</code>: обидва означають успіх, але <code>201</code> каже більше. І адресу новоствореного кладе в заголовок <code>Location</code> — бо <code>id</code> вигадує сервер, а не ти, і це офіційний спосіб його дізнатися.</p>
<p class="where">Вводиться: <a href="28-working-with-api/lecture.html">28. Робота з API</a></p>
</article>
<article class="gt" id="refaktoryng">
<h3>Рефакторинг <span class="en">refactoring</span></h3>
<p>Переписування коду <b>без зміни його поведінки</b>: розбити довгу функцію, дати зрозуміліші імена, прибрати повтор. Ззовні нічого не змінилось — усередині стало легше читати й правити.</p>
<p class="gnote"><b>Чому це поруч із тестами.</b> «Без зміни поведінки» — обіцянка, яку треба чимось підкріпити, інакше рефакторинг не відрізнити від внесення помилок. Тести і є тим підкріпленням: зелені до правки, зелені після — поведінка збереглася. Саме тому в циклі «червоне → зелене → рефакторинг» третій крок стоїть <b>після</b> зеленого, а не до нього.</p>
</article>
<article class="gt" id="rozpakuvannya">
<h3>Розпакування <span class="en">unpacking</span></h3>
<p>Кілька імен ліворуч від <code>=</code> отримують елементи послідовності по порядку: <code>широта, довгота = точка</code>. Зворотна дія, коли значення через кому самі збираються в кортеж, зветься <b>пакуванням</b>.</p>
<p class="gnote">Кількості мусять збігтися, і Python перевіряє це наперед — після невдалого розпакування жодне імʼя не встигає отримати значення. Імʼя із зірочкою (<code>*середина</code>) забирає решту й завжди у список.</p>
<p class="where">Вводиться: <a href="08-tuples/lecture.html">08. Кортежі й розпакування</a> · <a href="16-arguments-scope/lecture.html">16. Аргументи й область видимості</a></p>
</article>
<article class="gt" id="ryadok">
<h3>Рядок <span class="en">string, <code>str</code></span></h3>
<p>Впорядкована незмінна послідовність символів у лапках. Одинарні й подвійні лапки не відрізняються нічим — два варіанти існують, щоб класти всередину лапки іншого виду.</p>
<p class="gnote">Незмінність тут не дрібниця: жодного способу відредагувати рядок на місці немає, і всі методи повертають новий обʼєкт.</p>
<p class="where">Вводиться: <a href="05-strings/lecture.html">05. Рядки</a></p>
</article>
<h2 id="uk-1057"><span class="num">кирилиця</span>С</h2>
<article class="gt" id="serializaciya">
<h3>Серіалізація <span class="en">serialization</span></h3>
<p>Перетворення обʼєкта Python на текст, який можна покласти у файл чи послати мережею, і назад. У модулі <code>json</code> це чотири функції: <code>dumps</code>/<code>loads</code> працюють із рядком у памʼяті, <code>dump</code>/<code>load</code> — із відкритим файлом.</p>
<p class="gnote">Перетворення не взаємно однозначне: кортеж стає списком, а числові ключі словника стають рядками — мовчки й без помилки. Множина й дата не серіалізуються взагалі.</p>
<p class="where">Вводиться: <a href="22-csv-json/lecture.html">22. CSV і JSON</a></p>
</article>
<article class="gt" id="syryj-ryadok">
<h3>Сирий рядок <span class="en">raw string</span></h3>