Лекция 1

Язык программирования Python.

Рейтинг языков программирования и почему Python.

In [ ]:

In [24]:
import warnings
warnings.filterwarnings("ignore", category=FutureWarning)
In [2]:
!pip install -q tiobeindexpy
In [75]:
# Чтобы посмотреть рейтинги языков программирования

from tiobeindexpy import tiobeindexpy as tbpy

columns = ['Aug 2025', 'Aug 2024', 'Programming Language.1',	'Ratings', 'Change.1']
table = tbpy.top_20()[columns]
table['Ratings'] = table['Ratings'].str.replace('%', '').astype(float)
table['Change.1'] = table['Change.1'].str.replace('%', '').astype(float)
table
Out[75]:
Aug 2025 Aug 2024 Programming Language.1 Ratings Change.1
0 1 1 Python 26.14 +8.10%
1 2 2 C++ 9.18 -0.86%
2 3 3 C 9.03 -0.15%
3 4 4 Java 8.59 -0.58%
4 5 5 C# 5.52 -0.87%
5 6 6 JavaScript 3.15 -0.76%
6 7 8 Visual Basic 2.33 +0.15%
7 8 9 Go 2.11 +0.08%
8 9 25 Perl 2.08 +1.17%
9 10 12 Delphi/Object Pascal 1.82 +0.19%
10 11 10 Fortran 1.75 -0.03%
11 12 7 SQL 1.72 -0.49%
12 13 30 Ada 1.52 +0.91%
13 14 19 R 1.37 +0.26%
14 15 13 PHP 1.27 -0.19%
15 16 11 MATLAB 1.19 -0.53%
16 17 20 Scratch 1.15 +0.06%
17 18 14 Rust 1.13 -0.15%
18 19 18 Kotlin 1.10 -0.04%
19 20 17 Assembly language 1.03 -0.19%
In [72]:
import seaborn as sns
import matplotlib.pyplot as plt
In [82]:
sns.barplot(x="Ratings", y="Programming Language.1", data=table, orient='h')

plt.title('TIOBE Index Top 20 (August 2025)', fontsize=16)
plt.xlabel('Ratings (%)')
plt.ylabel('Programming Language')
plt.grid(axis='x', alpha=0.3)
plt.tight_layout()
plt.show()
In [86]:
sns.barplot(x="Change.1", y="Programming Language.1", data=table, orient='h')

plt.title('TIOBE Index Top 20 (August 2025)', fontsize=16)
plt.xlabel('Change.1 (%)')
plt.ylabel('Programming Language')
plt.grid(axis='x', alpha=0.3)
plt.tight_layout()
plt.show()

Дополнительную информацию можно прочитать тут: источник.

А также здесь: TIOBE Index.

Основы Python и Integrated Development Environment (IDE).

Официальный сайт питона: Python.

Официальный сайт Jupyter.

Гайд по Google Colab.

Python можно использовать как калькулятор :)

In [87]:
2 + 2
Out[87]:
4
In [88]:
7 - 5
Out[88]:
2
In [106]:
21 * 2
Out[106]:
42
In [104]:
import math

print(math.pi)

print(math.sqrt(math.pow(3, 2) + math.pow(4, 2)))

print(math.log2(1024))

print(math.exp(0))

print(math.cos(3.14))
print(round(math.cos(3.14)))
print(math.cos(math.pi))
3.141592653589793
5.0
10.0
1.0
-0.9999987317275395
-1
-1.0

Про библиотеку math можно прочитать тут и тут.

Вариант math для комплесных чисел.

Даже такое есть: Hypercomplex.

In [122]:
# это однострочный комментарий
# это другой однострочный комментарий
In [123]:
# и это всё однострочные комментарии
# и это всё однострочные комментарии
# и это всё однострочные комментарии
In [124]:
'''
это многострочный комментарий,
только это не совсем классический комментарий,
это многострочная строка :)
'''
Out[124]:
'\nэто многострочный комментарий,\nтолько это не совсем классический комментарий,\nэто многострочная строка :)\n'
In [125]:
'''
это многострочный комментарий,
только это не совсем классический комментарий,
это многострочная строка :)
''';
In [126]:
'''
это многострочный комментарий,
только это не совсем классический комментарий,
это многострочная строка :)
'''
None
In [128]:
# можно
# делать
# такой
# многострочный
# комментарий
#
# ╰( ͡° ͜ʖ ͡° )つ──☆*:・゚

Если кому-то стало скучно на лекции: ʕ•ᴥ•ʔ.

Рекомендуем прочитать про PEP8.

Арифметические операции и типы данных. Переменные.

In [107]:
11 + 2
Out[107]:
13
In [108]:
11 - 2
Out[108]:
9
In [109]:
11 * 2
Out[109]:
22
In [110]:
11 / 2
Out[110]:
5.5
In [111]:
11 // 2
Out[111]:
5
In [112]:
11 % 2
Out[112]:
1
In [113]:
11 ** 2
Out[113]:
121
In [ ]:

In [114]:
var = 123
In [115]:
var = 123
var
Out[115]:
123
In [116]:
var = 123
print(var)
123
In [117]:
var = 123
var
var = 456
print(var)
456
In [118]:
var = 123
print(var)
var = 456
print(var)
123
456

Какие могут быть проблемы с тем, что уже было создано много переменных с одинаковым именем?

In [137]:
var = 9
print(var, type(var))
9 <class 'int'>
In [138]:
var = 9
type(var)
Out[138]:
int
In [120]:
var = 9.4
type(var)
Out[120]:
float
In [140]:
var = 9.4 + 7j
print(var)
type(var)
(9.4+7j)
Out[140]:
complex
In [141]:
var = 9.4 + 7j
var
Out[141]:
(9.4+7j)
In [121]:
var = '9.4'
type(var)
Out[121]:
str
In [142]:
var = '9.4'
var
Out[142]:
'9.4'
In [143]:
var = "9.4"
var
Out[143]:
'9.4'
In [144]:
var = "9.4"
var, type(var)
Out[144]:
('9.4', str)
In [188]:
var = True
var
Out[188]:
True
In [189]:
var = False
var
Out[189]:
False
In [190]:
var = True
type(var)
Out[190]:
bool
In [158]:
my_list = [1, 2, 3, 4, 5]
my_list
Out[158]:
[1, 2, 3, 4, 5]
In [159]:
my_list = [1, 2, 3, 4, 5, [6, 7, 8, 9]]
type(my_list)
Out[159]:
list
In [146]:
my_tuple = (1, 2, 3, 4, 5)
type(my_tuple)
Out[146]:
tuple
In [160]:
my_tuple = (1, 2, 3, 4, 5)
my_tuple
Out[160]:
(1, 2, 3, 4, 5)
In [161]:
my_set = {1, 2, 3, 4, 5}
type(my_set)
Out[161]:
set
In [151]:
my_set = {1, 2, 3, 4, 5}
my_set
Out[151]:
{1, 2, 3, 4, 5}
In [162]:
my_set = {1, 2, 3, 4, 5, 5}
my_set
Out[162]:
{1, 2, 3, 4, 5}
In [192]:
my_frozenset = frozenset((1, 2, 3, 4, 5))
my_frozenset
Out[192]:
frozenset({1, 2, 3, 4, 5})
In [196]:
my_frozenset = frozenset((1, 2, 3, 4, 5))
type(my_frozenset)
Out[196]:
frozenset
In [163]:
my_dict = {1: 2, 3: 4, 5: 6}
type(my_dict)
Out[163]:
dict
In [164]:
my_dict = {1:2, 3:4, 5:6}
my_dict
Out[164]:
{1: 2, 3: 4, 5: 6}
In [165]:
my_dict = {1: '2', 3: '4', 5: 'qwerty'}
my_dict
Out[165]:
{1: '2', 3: '4', 5: 'qwerty'}
In [166]:
my_dict = {'1': '2', 3: '4', '5': 'qwerty'}
my_dict
Out[166]:
{'1': '2', 3: '4', '5': 'qwerty'}
In [197]:
var = None
var
In [199]:
var = None
print(var)
None
In [198]:
var = None
type(var)
Out[198]:
NoneType
In [ ]:

In [177]:
list = [3, 'not qwerty', 1 - 9j]
list
Out[177]:
[3, 'not qwerty', (1-9j)]
In [178]:
my_tuple = ('a', 'b', 'c', 'd', 'e')
my_list = list(my_tuple)
my_list
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/tmp/ipython-input-963557822.py in <cell line: 0>()
      1 my_tuple = ('a', 'b', 'c', 'd', 'e')
----> 2 my_list = list(my_tuple)
      3 my_list

TypeError: 'list' object is not callable
In [179]:
# Почему выше произошла ошибка? О чём она говорит?
# Вы умеете почитать сообщения Python? Это важно ;)

# Как исправить проблему? И нужно ли? :)
In [ ]:

In [186]:
set_ = {1, 2, 3}
type(set_)
Out[186]:
set
In [187]:
set_ = {}
type(set_)
Out[187]:
dict
In [184]:
# Было бы круто сделать пустое множество, но вышел словарь,
# ну как так-то...
In [182]:
set_ = set()
type(set_)
Out[182]:
set
In [183]:
dict_ = dict()
type(dict_)
Out[183]:
dict
In [ ]:

In [369]:
var = 3
print(var)
3
In [370]:
print(var:=3)
3

Официальная документация про это.

Тут можно почитать историю, как из-за "моржового" оператора (:=, PEP-572) Гвидо Ван Россум ушёл из комитета по Питону.

Ввод / вывод информации и базовые конструкции.

Про функцию print() можно прочитать тут и тут.

Список встроенных функций в Python: тык.

In [200]:
print(5)
5
In [201]:
print('hello world :)')
hello world :)
In [202]:
print()

In [203]:
print('')

In [205]:
print(3, 8, 1, -4, 1)
3 8 1 -4 1
In [206]:
print(3, 8, 1, -4, 1, sep='')
381-41
In [207]:
print(3, 8, 1, -4, 1, sep=' ')
3 8 1 -4 1
In [209]:
print(3, 8, 1, -4, 1, sep='\n')
3
8
1
-4
1
In [210]:
print(3, 8, 1, -4, 1, sep='\t')
3	8	1	-4	1
In [211]:
print(3, 8, 1, -4, 1, sep='\r')
1
In [239]:
print('hello\rworld')
world
In [240]:
print('helloworld\r')
helloworld
In [241]:
print('helloworld\rqwerty')
qwerty
In [243]:
import time
import sys

for i in range(11): # кто-то знает, почему 11? ;-)
    sys.stdout.write(f'\rProgress: {i*10}%')
#    sys.stdout.flush()
    time.sleep(0.5)
print()
Progress: 100%
In [244]:
print(3, 8, 1, -4, 1)
3 8 1 -4 1
In [245]:
print(3, 8, 1, -4, 1, end='')
3 8 1 -4 1
In [246]:
print(3, 8, 1, -4, 1)
print('йцукен')
3 8 1 -4 1
йцукен
In [247]:
print(3, 8, 1, -4, 1, end='')
print('йцукен')
3 8 1 -4 1йцукен
In [248]:
print(3, 8, 1, -4, 1, end='\n')
print('йцукен')
3 8 1 -4 1
йцукен
In [250]:
print(3, 8, 1, -4, 1, end='___')
print('йцукен')
3 8 1 -4 1___йцукен
In [251]:
print(3, 8, 1, -4, 1)
print(3, 8, 1, -4, 1, sep=' ', end='\n')
3 8 1 -4 1
3 8 1 -4 1
In [252]:
!ls
sample_data
In [253]:
print(3, 8, 1, -4, 1, file=sys.stdout)
3 8 1 -4 1
In [271]:
!ls
output.txt  sample_data
In [273]:
our_file = open('output.txt','a+')

print(3, 8, 1, -4, 1, file=our_file)
In [274]:
!ls
output.txt  sample_data
In [275]:
our_file.close()
In [276]:
!cat output.txt
3 8 1 -4 1
In [281]:
file = open('print.txt','a+')

def value(items):
    for item in items:
        print(item, file=file)
    file.close()

value([1,2,3,4,5,6,7,8,9,10])
In [282]:
!cat print.txt
1
2
3
4
5
6
7
8
9
10
In [ ]:
# Важно: следующие ячейки луычше всего демонстрировать в терминале !!!
In [229]:
import time

print("Начинаем загрузку...", end='', flush=False)
time.sleep(5)  # типа что-то делаем...
print(" Готово!")
Начинаем загрузку... Готово!
In [230]:
import time

print("Начинаем загрузку...", end='', flush=True)
time.sleep(5)  # типа что-то делаем...
print(" Готово!")
Начинаем загрузку... Готово!
In [ ]:
import sys
import time

print('Вы хотите продолжить (Д/н): ', end='')
sys.stdout.flush()
#time.sleep(5)
print()

Также можно почитать тут.

In [ ]:

In [286]:
number_pi = 3.14

print('Наше число это: {}'.format(number_pi))
print('Наши числа это: {} и {}'.format(number_pi, number_pi*3))

print(f'Наше число это: {number_pi}')
print('Наше число это: {number_pi}')
Наше число это: 3.14
Наши числа это: 3.14 и 9.42
Наше число это: 3.14
Наше число это: {number_pi}
In [ ]:

In [287]:
print('hello, world!')
hello, world!
In [292]:
print(''hello, world!'') # почему это ошибка? Как это исправить?
  File "/tmp/ipython-input-2473372427.py", line 1
    print(''hello, world!'') # почему это ошибка? Как это исправить?
          ^
SyntaxError: invalid syntax. Perhaps you forgot a comma?
In [ ]:

In [289]:
print("hello, world!")
hello, world!
In [290]:
print('''hello, world!''')
print("""hello, world!""")
hello, world!
hello, world!
In [291]:
print("""Это многострочный
    текст, который
    будет выведен на экран""")
Это многострочный
    текст, который
    будет выведен на экран
In [ ]:

Про функцию input() можно прочитать тут.

In [293]:
input() # hello
hello
Out[293]:
'hello'
In [294]:
input('Введите что-нибудь') # hello
Введите что-нибудьhello
Out[294]:
'hello'
In [295]:
input('Введите что-нибудь ещё ') # hello
Введите что-нибудь ещё hello
Out[295]:
'hello'
In [296]:
input('Введите что-нибудь ещё\n') # hello
Введите что-нибудь ещё
hello
Out[296]:
'hello'
In [298]:
input_var = input() # 1 2 3 4 5
print(input_var, type(input_var))

# Что мы здесь видим?
# Как работать именно с числами, а не со строчками?
1 2 3 4 5
1 2 3 4 5 <class 'str'>
In [ ]:

In [299]:
temp_var = 5

if temp_var > 3:
  print('yes')
else:
  print('no')
yes
In [300]:
temp_var = 5

if temp_var > 3:
    print('yes')
else:
    print('no')
yes
In [301]:
temp_var = 5

if temp_var > 3:
            print('yes')
else:
            print('no')
yes
In [303]:
temp_var = 5

if temp_var > 7:
  print('yes')
elif temp_var == 5:
  print('exactly 5 :)')
else:
  print('no')
exactly 5 :)
In [304]:
temp_var = 5

if temp_var > 3:
  print('yes')
elif temp_var == 5:
  print('exactly 5 :)')
else:
  print('no')
yes
In [306]:
temp_var = 5

if temp_var > 3:
  print('yes')
elif temp_var == 5:
  print('exactly 5 :)')
elif temp_var == 7:
  print('exactly 7 :)')
else:
  print('no')
yes
In [308]:
temp_var = 5

if temp_var > 7:
  print('yes')
elif temp_var == 5:
  print('exactly 5 :)')
else:
  print('no')
exactly 5 :)
In [310]:
temp_var = 5

if temp_var > 7:
  print('yes')
if temp_var == 5:
  print('exactly 5 :)')
else:
  print('no')
exactly 5 :)
In [313]:
temp_var = -5

if temp_var > 7:
  print('yes')
if temp_var == 5: # лучше сделать elif :)
  print('exactly 5 :)')
else:
  print('no')
no
In [320]:
temp_var = -5

if temp_var > 7:
  print('yes')
else:
  if temp_var == 5: # лучше сделать elif :)
    print('exactly 5 :)')
else:
  print('no')

# так будет ошибка :(
  File "/tmp/ipython-input-3538152619.py", line 8
    else:
    ^
SyntaxError: invalid syntax
In [322]:
temp_var = -5

if temp_var > 7:
  print('yes')
else:
  if temp_var == 5: # лучше сделать elif :)
    print('exactly 5 :)')
  else:
    print('no')

# а так всё ок, но предпочтительнее делать код более читаемые ;)
no
In [325]:
temp_var = -5

if temp_var > 7:
  print('yes')
elif temp_var == 5:
  print('exactly 5 :)')
else:
  print('no')

# как-то так :)
no
In [327]:
temp_var = -5

if temp_var > 7:
  print('yes')
elif temp_var == 5:
    print('exactly 5 :)')
else:
      print('no')

# лучше так тоже не делать :)
no
In [ ]:

In [328]:
for elem in range(1, 11):
  print(elem)
1
2
3
4
5
6
7
8
9
10
In [329]:
for elem in range(1, 11):
  print(elem)
  print(elem)
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
9
9
10
10
In [330]:
for elem in range(1, 11):
  print(elem)
  if elem == 5:
    break
  print(elem)
1
1
2
2
3
3
4
4
5
In [331]:
for elem in range(1, 11):
  print(elem)
  if elem == 5:
    continue
  print(elem)
1
1
2
2
3
3
4
4
5
6
6
7
7
8
8
9
9
10
10
In [332]:
for elem in range(1, 11):
  print(elem)
  if elem == 5:
    pass # что делает эта штука? :)
  print(elem)
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
9
9
10
10
In [333]:
summa = 0

while summa <= 10:
  print('-' * 30)
  print(summa)
  summa = summa + 1 # тоже самое можно переписать через summa += 1
  print(summa)
  print('-' * 30)
------------------------------
0
1
------------------------------
------------------------------
1
2
------------------------------
------------------------------
2
3
------------------------------
------------------------------
3
4
------------------------------
------------------------------
4
5
------------------------------
------------------------------
5
6
------------------------------
------------------------------
6
7
------------------------------
------------------------------
7
8
------------------------------
------------------------------
8
9
------------------------------
------------------------------
9
10
------------------------------
------------------------------
10
11
------------------------------
In [334]:
while True:
  pass

# страшна вырубай
---------------------------------------------------------------------------
KeyboardInterrupt                         Traceback (most recent call last)
/tmp/ipython-input-1016045001.py in <cell line: 0>()
----> 1 while True:
      2   pass

KeyboardInterrupt: 
In [336]:
while 1:
  pass

# тоже самое...
---------------------------------------------------------------------------
KeyboardInterrupt                         Traceback (most recent call last)
/tmp/ipython-input-2192650309.py in <cell line: 0>()
----> 1 while 1:
      2   pass
      3 
      4 # тоже самое...

KeyboardInterrupt: 
In [337]:
while 5 > 3:
  pass

# ну и опять...
---------------------------------------------------------------------------
KeyboardInterrupt                         Traceback (most recent call last)
/tmp/ipython-input-4045593716.py in <cell line: 0>()
----> 1 while 5 > 3:
      2   pass
      3 
      4 # ну и опять...

KeyboardInterrupt: 
In [339]:
def print_hello(language): # пока не будем на это обращать внимания ;)
    match language:
        case "russian":
            print("Привет")
        case "english":
            print("Hello")
        case "german":
            print("Hallo")

print_hello("english")
print_hello("german")
print_hello("russian")
Hello
Hallo
Привет

Про конструкцию match можно прочитать тут.

In [ ]:

Можно сделать даже такое: тык сюда.

In [341]:
for num in range(5):
  print(num)
else:
  print("Числа закончились")
0
1
2
3
4
Числа закончились
In [342]:
for num in range(5):
  if num == 3:
    break
  print(num)
else:
  print("Числа закончились")
0
1
2
In [343]:
for num in range(5):
  if num == 3:
    continue
  print(num)
else:
  print("Числа закончились")
0
1
2
4
Числа закончились
In [344]:
for num in range(5):
  if num == 3:
    pass
  print(num)
else:
  print("Числа закончились")
0
1
2
3
4
Числа закончились
In [348]:
# Ответ LLM:

'''

Конструкция for-else в Python используется для выполнения блока кода,
если цикл for завершился нормально (без break), а не был досрочно прерван.

Это полезно для сценариев, где нужно отреагировать на полное прохождение цикла,
например, при поиске элемента в последовательности, и выполнить определенные действия,
если элемент так и не был найден.

''';
In [349]:
i = 0
while i < 5:
  print(i)
  i += 1
else:
  print("Конец")
0
1
2
3
4
Конец
In [350]:
i = 0
while i < 5:
  if i == 3:
    break
  print(i)
  i += 1
else:
  print("Конец")
0
1
2
In [356]:
i = 0
while i < 5:
  if i == 3:
    continue
  print(i)
  i += 1
else:
  print("Конец")

# Почему образовался бесконечный цикл?
# Как это можно исправить?
0
1
2
---------------------------------------------------------------------------
KeyboardInterrupt                         Traceback (most recent call last)
/tmp/ipython-input-4134837119.py in <cell line: 0>()
      2 while i < 5:
      3   if i == 3:
----> 4     continue
      5   print(i)
      6   i += 1

KeyboardInterrupt: 
In [358]:
i = 0
while i < 5:
  if i == 3:
    pass
  print(i)
  i += 1
else:
  print("Конец")
0
1
2
3
4
Конец

Знакомство с NumPy и Matplotlib.

Очень рекомендуем зайти сюда.

  • зашли - сдали сессию :)
  • не зашли - ну, как повезёт ;)

А также сюда.

In [372]:
# Что-то совсем простое от LLM :)

import numpy as np

# Create a sample text file
with open("data.txt", "w") as f:
    f.write("1.0 2.0 3.0\n")
    f.write("4.0 5.0 6.0\n")

# Load data from the text file
data = np.loadtxt("data.txt")

print(data)

# Create the plot
plt.plot(x, y)
[[1. 2. 3.]
 [4. 5. 6.]]
Out[372]:
[<matplotlib.lines.Line2D at 0x7e38da2cf440>]
In [368]:
# Что-то совсем простое от LLM :)

import matplotlib.pyplot as plt
import numpy as np

# Prepare data using NumPy
x = np.linspace(0, 10, 100)
y = 2 * x + 5

# Create the plot
plt.plot(x, y)

# Add labels and title
plt.xlabel("X-axis Label")
plt.ylabel("Y-axis Label")
plt.title("Linear Plot Example")

# Display the plot
plt.show()
In [360]:
# Пусть LLM поработает за нас :)
# 1. Легкий уровень: Траектория броска тела под углом

import numpy as np
import matplotlib.pyplot as plt

# Параметры броска
g = 9.81  # ускорение свободного падения
v0 = 20   # начальная скорость, м/с
theta = np.radians(45)  # угол броска в радианах

# Время полета
t_max = 2 * v0 * np.sin(theta) / g
t = np.linspace(0, t_max, 100)

# Координаты
x = v0 * np.cos(theta) * t
y = v0 * np.sin(theta) * t - 0.5 * g * t**2

# Построение
plt.figure(figsize=(10, 6))
plt.plot(x, y, 'b-', linewidth=2, label='Траектория')
plt.scatter(x[::10], y[::10], color='red', s=50, alpha=0.7, label='Точки измерения')
plt.xlabel('Расстояние, м')
plt.ylabel('Высота, м')
plt.title('Траектория броска тела под углом 45°')
plt.grid(True, alpha=0.3)
plt.legend()
plt.axis('equal')
plt.show()
In [361]:
# Пусть LLM поработает за нас :)
# 2. Средний уровень: Интерференция волн от двух источников

# Параметры волн
wavelength = 1.0  # длина волны
k = 2 * np.pi / wavelength  # волновое число

# Координатная сетка
x = np.linspace(-5, 5, 500)
y = np.linspace(-5, 5, 500)
X, Y = np.meshgrid(x, y)

# Положения источников
source1 = np.array([-2, 0])
source2 = np.array([2, 0])

# Расстояния до источников
r1 = np.sqrt((X - source1[0])**2 + (Y - source1[1])**2)
r2 = np.sqrt((X - source2[0])**2 + (Y - source2[1])**2)

# Интерференционная картина
amplitude = np.cos(k * r1) + np.cos(k * r2)

# Построение
plt.figure(figsize=(12, 8))
plt.imshow(amplitude, extent=[-5, 5, -5, 5], cmap='RdBu', origin='lower', alpha=0.8)
plt.scatter([source1[0], source2[0]], [source1[1], source2[1]], color='red', s=100, label='Источники')
plt.colorbar(label='Амплитуда')
plt.xlabel('x, м')
plt.ylabel('y, м')
plt.title('Интерференция волн от двух источников')
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()
In [362]:
# Пусть LLM поработает за нас :)
# 3. Сложный уровень: Фазовый портрет маятника с затуханием

from scipy.integrate import odeint

# Параметры маятника
g = 9.81
L = 1.0    # длина маятника
b = 0.1    # коэффициент затухания

# Уравнение маятника
def pendulum(y, t):
    theta, omega = y
    dtheta_dt = omega
    domega_dt = -b * omega - (g/L) * np.sin(theta)
    return [dtheta_dt, domega_dt]

# Начальные условия для нескольких траекторий
initial_conditions = [
    [np.radians(10), 0],   # малый угол
    [np.radians(90), 0],   # большой угол
    [np.radians(170), 0],  # почти перевернутый
    [np.radians(30), 2],   # с начальной скоростью
]

# Время
t = np.linspace(0, 20, 1000)

# Решаем и строим
plt.figure(figsize=(14, 10))

colors = ['blue', 'red', 'green', 'purple']
labels = ['Малый угол', 'Большой угол', 'Почти перевернутый', 'С начальной скоростью']

for i, (y0, color, label) in enumerate(zip(initial_conditions, colors, labels)):
    # Решение уравнения
    solution = odeint(pendulum, y0, t)
    theta, omega = solution.T

    # Фазовый портрет
    plt.plot(theta, omega, color=color, linewidth=2, label=label, alpha=0.8)
    plt.scatter(theta[::50], omega[::50], color=color, s=30, alpha=0.6)

plt.xlabel('Угол θ, рад')
plt.ylabel('Угловая скорость ω, рад/с')
plt.title('Фазовый портрет маятника с затуханием')
plt.grid(True, alpha=0.3)
plt.legend()
plt.axhline(0, color='black', linestyle='--', alpha=0.5)
plt.axvline(0, color='black', linestyle='--', alpha=0.5)
plt.xlim(-np.pi, np.pi)
plt.show()
In [364]:
# LLM решил ешё что-то нарисовать :)
# Бонус: Анимация броска тела (интерактивная демонстрация)

from matplotlib.animation import FuncAnimation
from IPython.display import HTML
import numpy as np
import matplotlib.pyplot as plt

# Параметры броска
g = 9.81
v0 = 20
theta = np.radians(45)
t_max = 2 * v0 * np.sin(theta) / g
t = np.linspace(0, t_max, 50)
x = v0 * np.cos(theta) * t
y = v0 * np.sin(theta) * t - 0.5 * g * t**2

# Создаем анимацию
fig, ax = plt.subplots(figsize=(10, 6))
ax.set_xlim(0, max(x) + 5)
ax.set_ylim(0, max(y) + 5)
ax.set_xlabel('Расстояние, м')
ax.set_ylabel('Высота, м')
ax.set_title('Анимация движения тела')
ax.grid(True, alpha=0.3)

trajectory, = ax.plot([], [], 'b-', linewidth=2)
point, = ax.plot([], [], 'ro', markersize=8)

def animate(i):
    trajectory.set_data(x[:i+1], y[:i+1])
    point.set_data([x[i]], [y[i]])
    return trajectory, point

ani = FuncAnimation(fig, animate, frames=len(t), interval=100, blit=True)
plt.close()

# Для отображения в Jupyter
HTML(ani.to_jshtml())
Out[364]:
In [365]:
# Короче, LLM стало скучно :)))
# Более плавная анимация с большим количеством кадров

t_smooth = np.linspace(0, t_max, 200)
x_smooth = v0 * np.cos(theta) * t_smooth
y_smooth = v0 * np.sin(theta) * t_smooth - 0.5 * g * t_smooth**2

fig, ax = plt.subplots(figsize=(10, 6))
ax.set_xlim(0, max(x_smooth) + 5)
ax.set_ylim(0, max(y_smooth) + 5)
ax.set_xlabel('Расстояние, м')
ax.set_ylabel('Высота, м')
ax.set_title('Плавная анимация движения тела')
ax.grid(True, alpha=0.3)

trajectory, = ax.plot([], [], 'b-', linewidth=2, alpha=0.7)
point, = ax.plot([], [], 'ro', markersize=10)
info_text = ax.text(0.02, 0.95, '', transform=ax.transAxes)

def animate_smooth(i):
    trajectory.set_data(x_smooth[:i+1], y_smooth[:i+1])
    point.set_data([x_smooth[i]], [y_smooth[i]])

    # Добавляем информацию о времени и координатах
    info_text.set_text(f'Время: {t_smooth[i]:.2f} с\n'
                      f'x = {x_smooth[i]:.2f} м\n'
                      f'y = {y_smooth[i]:.2f} м\n'
                      f'Скорость: {np.sqrt((v0*np.cos(theta))**2 + (v0*np.sin(theta) - g*t_smooth[i])**2):.2f} м/с')

    return trajectory, point, info_text

ani_smooth = FuncAnimation(fig, animate_smooth, frames=len(t_smooth), interval=50, blit=True)
plt.close()

HTML(ani_smooth.to_jshtml())
Output hidden; open in https://colab.research.google.com to view.
In [366]:
# Ну и ещё один пример от LLM :)
# Движение по эллиптической орбите

t_orbit = np.linspace(0, 2*np.pi, 100)
a, b = 5, 3  # полуоси эллипса
x_orbit = a * np.cos(t_orbit)
y_orbit = b * np.sin(t_orbit)

fig, ax = plt.subplots(figsize=(8, 8))
ax.set_xlim(-6, 6)
ax.set_ylim(-4, 4)
ax.set_aspect('equal')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_title('Движение по эллиптической орбите')
ax.grid(True, alpha=0.3)

orbit, = ax.plot([], [], 'b-', linewidth=1, alpha=0.5)
planet, = ax.plot([], [], 'ro', markersize=15)
center = ax.plot(0, 0, 'yo', markersize=10, label='Центр')[0]

def animate_orbit(i):
    orbit.set_data(x_orbit[:i+1], y_orbit[:i+1])
    planet.set_data([x_orbit[i]], [y_orbit[i]])
    return orbit, planet

ani_orbit = FuncAnimation(fig, animate_orbit, frames=len(t_orbit), interval=100, blit=True)
plt.legend()
plt.close()

HTML(ani_orbit.to_jshtml())
Output hidden; open in https://colab.research.google.com to view.

Обзор Latex.

Предполагается, что код ниже лектор будет тестировать у себя в Overleaf.com .

Коды ниже нужно просто скопировать и запустить у себя в Overleaf.

По крайней мере, коды тестировались именно в Overleaf.

In [ ]:
# 1. Базовый документ с формулами (легкий уровень)

'''



\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage[russian]{babel}
\usepackage{amsmath}
\usepackage{amssymb}

\title{Введение в \LaTeX\ для физиков}
\author{Ваше Имя}
\date{\today}

\begin{document}

\maketitle

\section{Основные математические формулы}

\subsection{Уравнения механики}

Второй закон Ньютона:
\[
\vec{F} = m\vec{a}
\]

Кинетическая энергия:
\[
E_k = \frac{mv^2}{2}
\]

\subsection{Уравнения электродинамики}

Уравнения Максвелла в вакууме:

\begin{align*}
\nabla \cdot \mathbf{E} &= \frac{\rho}{\varepsilon_0} \\
\nabla \cdot \mathbf{B} &= 0 \\
\nabla \times \mathbf{E} &= -\frac{\partial \mathbf{B}}{\partial t} \\
\nabla \times \mathbf{B} &= \mu_0\mathbf{J} + \mu_0\varepsilon_0\frac{\partial \mathbf{E}}{\partial t}
\end{align*}

\end{document}



''';
In [373]:
# Для второго примеры выполните код ниже.

!wget https://cs10.pikabu.ru/post_img/2018/07/10/4/1531199339121474094.jpg
!mv 1531199339121474094.jpg graph.jpg
!ls

# Хотя лучше использовать .png, но тут чисто для красоты :)
# Нужно загрузить к себе в Overleaf файл graph.jpg,
# либо скачать по ссылке выше (только не забудьте переименовать на graph.jpg).
--2025-09-04 00:14:26--  https://cs10.pikabu.ru/post_img/2018/07/10/4/1531199339121474094.jpg
Resolving cs10.pikabu.ru (cs10.pikabu.ru)... 185.178.210.193
Connecting to cs10.pikabu.ru (cs10.pikabu.ru)|185.178.210.193|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 129992 (127K) [image/jpeg]
Saving to: ‘1531199339121474094.jpg’

1531199339121474094 100%[===================>] 126.95K   648KB/s    in 0.2s    

2025-09-04 00:14:27 (648 KB/s) - ‘1531199339121474094.jpg’ saved [129992/129992]

data.txt  graph.jpg  output.txt  print.txt  sample_data
In [ ]:
# 2. Документ с графиками и таблицами (средний уровень)

'''



\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage[russian]{babel}
\usepackage{amsmath}
\usepackage{graphicx}
\usepackage{booktabs}
\usepackage{caption}

\title{Лабораторная работа: Изучение колебаний}
\author{Студент: Иванов И.И.}

\begin{document}

\maketitle

\section{Экспериментальные данные}

Результаты измерений периода колебаний маятника:

\begin{table}[h!]
\centering
\caption{Зависимость периода от длины маятника}
\begin{tabular}{ccc}
\toprule
Длина, м & Период, с & Погрешность, с \\
\midrule
0.5 & 1.42 & 0.05 \\
1.0 & 2.01 & 0.03 \\
1.5 & 2.46 & 0.04 \\
2.0 & 2.83 & 0.02 \\
\bottomrule
\end{tabular}
\end{table}

\section{Теоретический анализ}

Формула периода математического маятника:
\[
T = 2\pi\sqrt{\frac{L}{g}}
\]

где $L$ -- длина маятника, $g$ -- ускорение свободного падения.

\section{Графики}

\begin{figure}[h!]
\centering
\includegraphics[width=1.1\textwidth]{graph.jpg}
\caption{График зависимости периода от длины маятника}
\label{fig:graph}
\end{figure}

\end{document}



''';
In [ ]:
# 3. Сложный документ с физическими вычислениями

'''



\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage[russian]{babel}
\usepackage{amsmath}
\usepackage{physics}
\usepackage{siunitx}
\usepackage{tikz}
\usetikzlibrary{arrows.meta}

\title{Квантовая механика: Частица в ящике}
\author{Проф. Петров П.П.}

\begin{document}

\maketitle

\section{Волновые функции и энергетические уровни}

Рассмотрим частицу массы $m$ в одномерном ящике шириной $L$.

\subsection{Стационарное уравнение Шрёдингера}

\[
-\frac{\hbar^2}{2m}\dv[2]{\psi}{x} = E\psi
\]

с граничными условиями: $\psi(0) = \psi(L) = 0$.

\subsection{Решение}

Волновые функции:
\[
\psi_n(x) = \sqrt{\frac{2}{L}}\sin\left(\frac{n\pi x}{L}\right)
\]

Энергетические уровни:
\[
E_n = \frac{n^2\pi^2\hbar^2}{2mL^2}
\]

\subsection{Пример вычислений}

Для электрона ($m = \SI{9.1e-31}{kg}$) в ящике шириной \SI{1}{nm}:

\begin{align*}
E_1 &= \frac{(1)^2\pi^2(\SI{1.05e-34}{J\cdot s})^2}{2\times\SI{9.1e-31}{kg}\times(\SI{1e-9}{m})^2} \\
&= \SI{6.02e-20}{J} = \SI{0.376}{eV}
\end{align*}

\section{Визуализация волновых функций}

\begin{figure}[h!]
\centering
\begin{tikzpicture}[scale=1.2]
% Оси
\draw[->] (0,0) -- (5,0) node[right] {$x$};
\draw[->] (0,-2) -- (0,2) node[above] {$\psi_n(x)$};

% Ящик
\draw[thick] (0,0) -- (0,-0.1) node[below] {0};
\draw[thick] (4,0) -- (4,-0.1) node[below] {$L$};
\draw[thick] (0,0) -- (4,0);

% Волновые функции
\draw[blue, thick, domain=0:4, samples=100]
    plot (\x, {1.5*sin(pi*\x r)});
\draw[red, thick, domain=0:4, samples=100]
    plot (\x, {1.2*sin(2*pi*\x r)});
\draw[green, thick, domain=0:4, samples=100]
    plot (\x, {0.9*sin(3*pi*\x r)});

% Подписи
\node[blue, right] at (4.2, 1.5) {$\psi_1$};
\node[red, right] at (4.2, 1.2) {$\psi_2$};
\node[green, right] at (4.2, 0.9) {$\psi_3$};
\end{tikzpicture}
\caption{Первые три волновые функции частицы в ящике}
\end{figure}

\end{document}



''';
In [ ]:
# 4. Презентация с Beamer (для лекций)

'''



\documentclass{beamer}
\usepackage[utf8]{inputenc}
\usepackage[russian]{babel}
\usepackage{amsmath}
\usepackage{graphicx}

\usetheme{Madrid}
\title{Введение в специальную теорию относительности}
\author{Доцент Сидоров С.С.}
\date{2025}

\begin{document}

\frame{\titlepage}

\begin{frame}
\frametitle{Постулаты СТО}
\begin{block}{Первый постулат (принцип относительности)}
Законы физики одинаковы во всех инерциальных системах отсчета
\end{block}

\begin{block}{Второй постулат}
Скорость света в вакууме постоянна и не зависит от движения источника
\end{block}

\[
c = \SI{3e8}{m/s}
\]
\end{frame}

\begin{frame}
\frametitle{Преобразования Лоренца}

\begin{align*}
t' &= \gamma\left(t - \frac{vx}{c^2}\right) \\
x' &= \gamma(x - vt) \\
y' &= y \\
z' &= z
\end{align*}

где $\gamma = \dfrac{1}{\sqrt{1 - \frac{v^2}{c^2}}}$ -- лоренц-фактор
\end{frame}

\begin{frame}
\frametitle{Релятивистские эффекты}

\begin{itemize}
\item<1-> \textbf{Сокращение длин}
\[
L = L_0\sqrt{1 - \frac{v^2}{c^2}}
\]

\item<2-> \textbf{Замедление времени}
\[
\Delta t = \frac{\Delta t_0}{\sqrt{1 - \frac{v^2}{c^2}}}
\]

\item<3-> \textbf{Релятивистский импульс}
\[
p = \frac{mv}{\sqrt{1 - \frac{v^2}{c^2}}}
\]
\end{itemize}
\end{frame}

\end{document}



''';
In [ ]:
# 5. Лабораторный журнал с экспериментами

'''



\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage[russian]{babel}
\usepackage{amsmath}
\usepackage{graphicx}
\usepackage{mhchem}
\usepackage{siunitx}

\title{Лабораторный журнал по физике}
\author{Группа Ф-01}

\begin{document}

\maketitle

\section{Эксперимент 1: Определение ускорения свободного падения}

\subsection{Цель работы}
Определить значение $g$ с помощью математического маятника.

\subsection{Оборудование}
\begin{itemize}
\item Маятник с регулируемой длиной
\item Секундомер
\item Линейка
\end{itemize}

\subsection{Ход работы}

Измеряем период колебаний для разных длин:

\[
T = 2\pi\sqrt{\frac{L}{g}} \Rightarrow g = \frac{4\pi^2 L}{T^2}
\]

\subsection{Результаты}

\begin{table}[h!]
\centering
\begin{tabular}{|c|c|c|}
\hline
$L$ (м) & $T$ (с) & $g$ (м/с²) \\
\hline
0.50 & 1.42 & 9.78 \\
1.00 & 2.01 & 9.76 \\
1.50 & 2.46 & 9.80 \\
2.00 & 2.83 & 9.86 \\
\hline
\end{tabular}
\end{table}

\subsection{Вывод}
Среднее значение: $g = \SI{9.80 \pm 0.04}{m/s^2}$

\end{document}



''';

Примеры Overleaf шаблонов также можно посмортеть тут.

Бонус: округление чисел в Python.

In [392]:
print(round(0.6))
print(round(0.5))
print(round(1.6))
print(round(1.5))

# Почему так идёт округление?
1
0
2
2
In [394]:
# Потому что тут используется round half to even или banker's rounding,
# то есть банковское округление или округление банкира.

# А не математическое округление, к которому вы могли привыкнуть.

Это написано тут. IEEE Standard for Floating-Point Arithmetic (IEEE 754)

Ссылка на Вики про это.

In [395]:
print("Банковское округление (round half to even):")
numbers = [0.5, 1.5, 2.5, 3.5, 4.5, 5.5]

for num in numbers:
    print(f"round({num}) = {round(num)}")
Банковское округление (round half to even):
round(0.5) = 0
round(1.5) = 2
round(2.5) = 2
round(3.5) = 4
round(4.5) = 4
round(5.5) = 6
In [396]:
# Сравнение с школьным округлением:

def school_round(x):
    """Школьное округление (всегда вверх от 0.5)"""
    return int(x + 0.5) if x >= 0 else int(x - 0.5)

print("\nСравнение методов округления:")
print("Число | Банковское | Школьное")
print("-" * 30)

test_numbers = [0.5, 1.5, 2.5, 3.5, -0.5, -1.5, -2.5]

for num in test_numbers:
    bank = round(num)
    school = school_round(num)
    print(f"{num:5.1f} | {bank:10} | {school:9}")
Сравнение методов округления:
Число | Банковское | Школьное
------------------------------
  0.5 |          0 |         1
  1.5 |          2 |         2
  2.5 |          2 |         3
  3.5 |          4 |         4
 -0.5 |          0 |        -1
 -1.5 |         -2 |        -2
 -2.5 |         -2 |        -3
In [397]:
# Округление до N знаков:

print("\nОкругление до знаков после запятой:")
numbers = [3.14159, 2.71828, 1.23456789]

for num in numbers:
    for digits in range(4):
        print(f"round({num}, {digits}) = {round(num, digits)}")
    print()
Округление до знаков после запятой:
round(3.14159, 0) = 3.0
round(3.14159, 1) = 3.1
round(3.14159, 2) = 3.14
round(3.14159, 3) = 3.142

round(2.71828, 0) = 3.0
round(2.71828, 1) = 2.7
round(2.71828, 2) = 2.72
round(2.71828, 3) = 2.718

round(1.23456789, 0) = 1.0
round(1.23456789, 1) = 1.2
round(1.23456789, 2) = 1.23
round(1.23456789, 3) = 1.235

In [399]:
# Почему банковское округление лучше?

# Статистическое преимущество:
# при большом количестве операций ошибки округления
# компенсируются (половина округляется вверх, половина - вниз).
In [398]:
# Если нужно школьное округление:

import math

def always_up_round(x):
    """Всегда округляет 0.5 вверх"""
    return math.floor(x + 0.5)

print("Школьное округление (всегда вверх):")
for num in [0.5, 1.5, 2.5, 3.5]:
    print(f"always_up_round({num}) = {always_up_round(num)}")
Школьное округление (всегда вверх):
always_up_round(0.5) = 1
always_up_round(1.5) = 2
always_up_round(2.5) = 3
always_up_round(3.5) = 4
In [400]:
# Особые случаи:

print("\nОсобые случаи:")
print(f"round(2.675, 2) = {round(2.675, 2)}")  # 2.67, а не 2.68!
print("Из-за двоичного представления 2.675 ≈ 2.6749999999999998")
Особые случаи:
round(2.675, 2) = 2.67
Из-за двоичного представления 2.675 ≈ 2.6749999999999998

Бонус: проблемы представления чисел в компьютере.

In [375]:
# Вещественные числа (float) - приближенное представление

# Вещественные числа (IEEE 754 double precision)
x = 0.1
y = 0.2
z = x + y

print("Вещественные числа:")
print(f"x = 0.1, представление: {x}")
print(f"y = 0.2, представление: {y}")
print(f"z = x + y = {z}")
print(f"0.1 + 0.2 == 0.3? {z == 0.3}")
print(f"Точное значение z: {z:.20f}")
print()

# Проблема точности
print("Проблема точности вещественных чисел:")
for i in [0.1, 0.2, 0.3, 0.4, 0.5, 0.6]:
    print(f"{i} = {i:.20f}")
print()
Вещественные числа:
x = 0.1, представление: 0.1
y = 0.2, представление: 0.2
z = x + y = 0.30000000000000004
0.1 + 0.2 == 0.3? False
Точное значение z: 0.30000000000000004441

Проблема точности вещественных чисел:
0.1 = 0.10000000000000000555
0.2 = 0.20000000000000001110
0.3 = 0.29999999999999998890
0.4 = 0.40000000000000002220
0.5 = 0.50000000000000000000
0.6 = 0.59999999999999997780

In [378]:
# Сравнение целых и вещественных чисел

print("Сравнение целых и вещественных чисел:")
print(f"Целое 1: {1}, тип: {type(1)}")
print(f"Вещественное 1.0: {1.0}, тип: {type(1.0)}")
print(f"1 == 1.0: {1 == 1.0}")
print(f"1 is 1.0: {1 is 1.0}")  # Разные объекты!
print()

# Преобразование типов
print("Преобразование типов:")
print(f"int(3.14) = {int(3.14)}")
print(f"float(42) = {float(42)}")
print(f"int('123') = {int('123')}")
print(f"float('3.14') = {float('3.14')}")
print()
Сравнение целых и вещественных чисел:
Целое 1: 1, тип: <class 'int'>
Вещественное 1.0: 1.0, тип: <class 'float'>
1 == 1.0: True
1 is 1.0: False

Преобразование типов:
int(3.14) = 3
float(42) = 42.0
int('123') = 123
float('3.14') = 3.14

<>:5: SyntaxWarning: "is" with 'int' literal. Did you mean "=="?
<>:5: SyntaxWarning: "is" with 'int' literal. Did you mean "=="?
/tmp/ipython-input-2879459328.py:5: SyntaxWarning: "is" with 'int' literal. Did you mean "=="?
  print(f"1 is 1.0: {1 is 1.0}")  # Разные объекты!
In [379]:
# Особые значения вещественных чисел

import math

print("Особые значения float:")
print(f"Бесконечность: {math.inf}, тип: {type(math.inf)}")
print(f"Отрицательная бесконечность: {-math.inf}")
print(f"Не число (NaN): {math.nan}")
print(f"NaN == NaN: {math.nan == math.nan}")  # False!
print(f"math.isnan(math.nan): {math.isnan(math.nan)}")  # True
print()

# Проверка на особые значения
values = [1.0, 0.0, -0.0, math.inf, -math.inf, math.nan]
for val in values:
    print(f"{val:8}: inf={math.isinf(val)}, nan={math.isnan(val)}, finite={math.isfinite(val)}")
print()
Особые значения float:
Бесконечность: inf, тип: <class 'float'>
Отрицательная бесконечность: -inf
Не число (NaN): nan
NaN == NaN: False
math.isnan(math.nan): True

     1.0: inf=False, nan=False, finite=True
     0.0: inf=False, nan=False, finite=True
    -0.0: inf=False, nan=False, finite=True
     inf: inf=True, nan=False, finite=False
    -inf: inf=True, nan=False, finite=False
     nan: inf=False, nan=True, finite=False

In [382]:
# Машинная эпсилон и точность

# Машинная эпсилон (наименьшее число такое, что 1.0 + eps != 1.0)
machine_epsilon = 1.0
while 1.0 + machine_epsilon != 1.0:
    machine_epsilon /= 2
machine_epsilon *= 2

print("Точность представления:")
print(f"Машинная эпсилон: {machine_epsilon}")
print(f"1.0 + машинная эпсилон: {1.0 + machine_epsilon}")
print(f"1.0 + машинная эпсилон/2: {1.0 + machine_epsilon/2}")
print()

# Потеря точности при сложении чисел разного масштаба
big = 1e15
small = 1e-15
result = big + small - big

print("Потеря точности:")
print(f"big = {big}")
print(f"small = {small}")
print(f"big + small - big = {result}")
print(f"Ожидалось: {small}")
print()
Точность представления:
Машинная эпсилон: 2.220446049250313e-16
1.0 + машинная эпсилон: 1.0000000000000002
1.0 + машинная эпсилон/2: 1.0

Потеря точности:
big = 1000000000000000.0
small = 1e-15
big + small - big = 0.0
Ожидалось: 1e-15

In [385]:
# Практические примеры проблем

print("Практические проблемы вещественных чисел:")

# Накопление ошибки
total = 0.0
for i in range(1000):
    total += 0.1

print(f"Сумма 1000 раз по 0.1: {total}")
print(f"Ожидалось: 100.0")
print(f"Разница: {total - 100.0}")

# Сравнение вещественных чисел
print("\nПравильное сравнение вещественных чисел:")
a = 0.1 + 0.2
b = 0.3
tolerance = 1e-10

print(f"a == b: {a == b}")
print(f"abs(a - b) < tolerance: {abs(a - b) < tolerance}")
print(f"math.isclose(a, b): {math.isclose(a, b)}")
Практические проблемы вещественных чисел:
Сумма 1000 раз по 0.1: 99.9999999999986
Ожидалось: 100.0
Разница: -1.4068746168049984e-12

Правильное сравнение вещественных чисел:
a == b: False
abs(a - b) < tolerance: True
math.isclose(a, b): True
In [ ]:

Спасибо и успехов :)

In [ ]: