0 added
0 removed
Original
2026-01-01
Modified
2026-02-21
1
<p><a>#Руководства</a></p>
1
<p><a>#Руководства</a></p>
2
<ul><li>13 ноя 2019</li>
2
<ul><li>13 ноя 2019</li>
3
<li>0</li>
3
<li>0</li>
4
</ul><p>Рассказываем, зачем учить Python и как это поможет при работе в Data Science. Идём пошагово: от установки дистрибутива до первых практических опытов.</p>
4
</ul><p>Рассказываем, зачем учить Python и как это поможет при работе в Data Science. Идём пошагово: от установки дистрибутива до первых практических опытов.</p>
5
<p> vlada_maestro / shutterstock</p>
5
<p> vlada_maestro / shutterstock</p>
6
<p>В бэкграунде - программирование, французский язык, академическое рисование, капоэйра. Сейчас учит финский. Любит путешествия и Балтийское море.</p>
6
<p>В бэкграунде - программирование, французский язык, академическое рисование, капоэйра. Сейчас учит финский. Любит путешествия и Балтийское море.</p>
7
<p>Python - высокоуровневый язык программирования, названный так в честь британского комедийного телешоу "Летающий цирк Монти Пайтона".</p>
7
<p>Python - высокоуровневый язык программирования, названный так в честь британского комедийного телешоу "Летающий цирк Монти Пайтона".</p>
8
<p>Почему именно Python? Причин много:</p>
8
<p>Почему именно Python? Причин много:</p>
9
<ul><li>благодаря простой структуре и синтаксису это один из лучших языков для начинающих;</li>
9
<ul><li>благодаря простой структуре и синтаксису это один из лучших языков для начинающих;</li>
10
<li>он быстро развивается;</li>
10
<li>он быстро развивается;</li>
11
<li>в Python простой и хорошо читаемый синтаксис;</li>
11
<li>в Python простой и хорошо читаемый синтаксис;</li>
12
<li>высокая востребованность разработчиков Python;</li>
12
<li>высокая востребованность разработчиков Python;</li>
13
<li>язык широко используется в веб-разработке, автоматизации и Data Science.</li>
13
<li>язык широко используется в веб-разработке, автоматизации и Data Science.</li>
14
</ul><p><strong>Data Science, или наука о данных,</strong>сочетает в себе математику, статистику, IT и знания о бизнесе. Python фактически стал отраслевым стандартом в Data Science: чаще всего разработка ведётся именно на нём. Специалисты в этой области занимаются анализом данных и работают над их визуализацией. Data Science сейчас быстро развивается, поэтому разработчики нужны компаниям всё чаще.</p>
14
</ul><p><strong>Data Science, или наука о данных,</strong>сочетает в себе математику, статистику, IT и знания о бизнесе. Python фактически стал отраслевым стандартом в Data Science: чаще всего разработка ведётся именно на нём. Специалисты в этой области занимаются анализом данных и работают над их визуализацией. Data Science сейчас быстро развивается, поэтому разработчики нужны компаниям всё чаще.</p>
15
<ul><li>минималистичный синтаксис;</li>
15
<ul><li>минималистичный синтаксис;</li>
16
<li>динамическая типизация (не надо писать тип переменной);</li>
16
<li>динамическая типизация (не надо писать тип переменной);</li>
17
<li>большое количество библиотек.</li>
17
<li>большое количество библиотек.</li>
18
</ul><ul><li>низкая скорость в базовом варианте;</li>
18
</ul><ul><li>низкая скорость в базовом варианте;</li>
19
<li>неточности в работе с числами.</li>
19
<li>неточности в работе с числами.</li>
20
</ul><p><strong>Важная особенность:</strong>в Python не указывается тип переменных. Это даёт большую гибкость, потому что в одну переменную можно записать сначала int<em>(целое число)</em>, а потом float<em>(число с плавающей точкой)</em>или str<em>(строка, текст)</em>, и <strong>тип поменяется сам</strong>. За эту гибкость, к сожалению, приходится расплачиваться скоростью.</p>
20
</ul><p><strong>Важная особенность:</strong>в Python не указывается тип переменных. Это даёт большую гибкость, потому что в одну переменную можно записать сначала int<em>(целое число)</em>, а потом float<em>(число с плавающей точкой)</em>или str<em>(строка, текст)</em>, и <strong>тип поменяется сам</strong>. За эту гибкость, к сожалению, приходится расплачиваться скоростью.</p>
21
<p>По Python много мануалов как на английском, так и на русском языке. Однако знание английского вам сильно поможет: во-первых, большинство команд переводится с английского буквально (если вы знаете язык, вам не придётся их зубрить), а во-вторых, подсказки к командам и описания ошибок выводятся тоже на английском.</p>
21
<p>По Python много мануалов как на английском, так и на русском языке. Однако знание английского вам сильно поможет: во-первых, большинство команд переводится с английского буквально (если вы знаете язык, вам не придётся их зубрить), а во-вторых, подсказки к командам и описания ошибок выводятся тоже на английском.</p>
22
<p>Чтобы начать программировать, нужно скачать и установить дистрибутив. Для новичков хорошо подойдёт<strong>Anaconda.</strong></p>
22
<p>Чтобы начать программировать, нужно скачать и установить дистрибутив. Для новичков хорошо подойдёт<strong>Anaconda.</strong></p>
23
<p>Чем он хорош: в нём есть всё, что понадобится в работе.</p>
23
<p>Чем он хорош: в нём есть всё, что понадобится в работе.</p>
24
<p>В <strong>Anaconda</strong>уже встроены:</p>
24
<p>В <strong>Anaconda</strong>уже встроены:</p>
25
<ul><li>все библиотеки машинного обучения и библиотеки для работы с данными (например,<strong>NumPy</strong>и <strong>Pandas</strong>);</li>
25
<ul><li>все библиотеки машинного обучения и библиотеки для работы с данными (например,<strong>NumPy</strong>и <strong>Pandas</strong>);</li>
26
<li>библиотека для визуализации (<strong>Matplotlib</strong>);</li>
26
<li>библиотека для визуализации (<strong>Matplotlib</strong>);</li>
27
<li>надстройка<strong>Jupyter</strong>, чтобы программировать прямо в браузере.</li>
27
<li>надстройка<strong>Jupyter</strong>, чтобы программировать прямо в браузере.</li>
28
</ul><p>После того как вы установили и открыли<strong>Anaconda</strong>, у вас появится вот такое окно:</p>
28
</ul><p>После того как вы установили и открыли<strong>Anaconda</strong>, у вас появится вот такое окно:</p>
29
<p>Кнопкой Launch запустим "тетрадку"<strong>Jupyter</strong>, которая откроет ваш дефолтный браузер. После этого ваше рабочее пространство будет выглядеть так:</p>
29
<p>Кнопкой Launch запустим "тетрадку"<strong>Jupyter</strong>, которая откроет ваш дефолтный браузер. После этого ваше рабочее пространство будет выглядеть так:</p>
30
<p>Или так:</p>
30
<p>Или так:</p>
31
<p>По функциональности они абсолютно одинаковые.</p>
31
<p>По функциональности они абсолютно одинаковые.</p>
32
<p><strong>Важная особенность:</strong>комментарии в Python делаются с помощью решетки, вот так:</p>
32
<p><strong>Важная особенность:</strong>комментарии в Python делаются с помощью решетки, вот так:</p>
33
<p>Комментарии - это часть кода, которая не будет выполняться. Для чего используется комментирование?</p>
33
<p>Комментарии - это часть кода, которая не будет выполняться. Для чего используется комментирование?</p>
34
<p>Во-первых, чтобы написать небольшое пояснение (например, к какой-то функции).</p>
34
<p>Во-первых, чтобы написать небольшое пояснение (например, к какой-то функции).</p>
35
<p>Во-вторых, можно закомментировать часть кода, чтобы посмотреть, как остальной код работает без этой части.</p>
35
<p>Во-вторых, можно закомментировать часть кода, чтобы посмотреть, как остальной код работает без этой части.</p>
36
<p><strong>Выполнение кода.</strong>Для этого используется<em>Shift+Enter, Ctrl+Enter</em>или значок<em>"Пуск"</em>.</p>
36
<p><strong>Выполнение кода.</strong>Для этого используется<em>Shift+Enter, Ctrl+Enter</em>или значок<em>"Пуск"</em>.</p>
37
<p>В чём разница?</p>
37
<p>В чём разница?</p>
38
<p>Если нажать<em>Shift+Enter,</em>то курсор перескочит на следующую ячейку.</p>
38
<p>Если нажать<em>Shift+Enter,</em>то курсор перескочит на следующую ячейку.</p>
39
<p>Если нажать<em>Ctrl+Enter</em> - останется в той, где вы работали.</p>
39
<p>Если нажать<em>Ctrl+Enter</em> - останется в той, где вы работали.</p>
40
<p>Если ячейка выполнилась, это значит, что выполнились все действия, которые были в ней записаны.</p>
40
<p>Если ячейка выполнилась, это значит, что выполнились все действия, которые были в ней записаны.</p>
41
<p>Разберём, как устроены базовые функции в Python.</p>
41
<p>Разберём, как устроены базовые функции в Python.</p>
42
<p>Чтобы записать в переменную V сумму 1 и 1, мы напишем так:</p>
42
<p>Чтобы записать в переменную V сумму 1 и 1, мы напишем так:</p>
43
<p>Если мы захотим напечатать переменную V, мы используем функцию:</p>
43
<p>Если мы захотим напечатать переменную V, мы используем функцию:</p>
44
<p><strong>Напоминаем</strong>, что в Python мы не пишем тип переменных.</p>
44
<p><strong>Напоминаем</strong>, что в Python мы не пишем тип переменных.</p>
45
<p>При спуске этот код выведет нам 2.</p>
45
<p>При спуске этот код выведет нам 2.</p>
46
<p>Если вы забыли, что делает функция, или нашли новую, вам поможет команда<em>help ()</em>: она выпишет основную информацию о функции. Если мы используем ее на функцию<em>print (),</em>это будет выглядеть так:</p>
46
<p>Если вы забыли, что делает функция, или нашли новую, вам поможет команда<em>help ()</em>: она выпишет основную информацию о функции. Если мы используем ее на функцию<em>print (),</em>это будет выглядеть так:</p>
47
<p>В программировании мы будем много работать с числами. Все основные математические операции записываются в Python привычным образом, примерно как в калькуляторе:</p>
47
<p>В программировании мы будем много работать с числами. Все основные математические операции записываются в Python привычным образом, примерно как в калькуляторе:</p>
48
A+B #А плюс В A-B #А минус В A*B #А умножить на В A/B #А разделить на В<p>Есть и операции поинтереснее, менее очевидные:</p>
48
A+B #А плюс В A-B #А минус В A*B #А умножить на В A/B #А разделить на В<p>Есть и операции поинтереснее, менее очевидные:</p>
49
A**B #А в степени В A//B #Деление без остатка A%B #Остаток при делении<p>Иногда в Python можно встретить артефакты вроде такого:</p>
49
A**B #А в степени В A//B #Деление без остатка A%B #Остаток при делении<p>Иногда в Python можно встретить артефакты вроде такого:</p>
50
1 - 1.3 = -0.30000000004.<p>В конце получившегося числа мы неожиданно видим<strong>4</strong>. Это просто особенность компьютерного представления данных, и бояться этого не стоит, в большинстве случаев это не имеет значения. Но не забывайте об этой особенности, если вам важны точные числа (как, например, в астрофизике).</p>
50
1 - 1.3 = -0.30000000004.<p>В конце получившегося числа мы неожиданно видим<strong>4</strong>. Это просто особенность компьютерного представления данных, и бояться этого не стоит, в большинстве случаев это не имеет значения. Но не забывайте об этой особенности, если вам важны точные числа (как, например, в астрофизике).</p>
51
<p><strong>Вывод текста</strong>. Уже сложилась традиция, что первые слова, которые человек выписывает кодом, это "Hello, World!". Сделаем это и мы.</p>
51
<p><strong>Вывод текста</strong>. Уже сложилась традиция, что первые слова, которые человек выписывает кодом, это "Hello, World!". Сделаем это и мы.</p>
52
<p>Мы уже выводили выше переменную, теперь выведем текст. Сделать это в Python очень просто:</p>
52
<p>Мы уже выводили выше переменную, теперь выведем текст. Сделать это в Python очень просто:</p>
53
<p>Иногда (например, в цикле) надо выводить одно и то же с небольшим изменением. Для этого используется<strong>форматированный вывод</strong>. Это делается так: заменим часть, которая будет меняться, фигурными скобками, а за фразой напишем<em>.format ()</em>. В скобки вставим переменную с нужным значением. Вот как это выглядит:</p>
53
<p>Иногда (например, в цикле) надо выводить одно и то же с небольшим изменением. Для этого используется<strong>форматированный вывод</strong>. Это делается так: заменим часть, которая будет меняться, фигурными скобками, а за фразой напишем<em>.format ()</em>. В скобки вставим переменную с нужным значением. Вот как это выглядит:</p>
54
name = “Valentin” print(“Hello, {}!”.format(name)) >>> Hello, Valentin!<p>В некоторых версиях Python можно сделать то же самое и другим способом:</p>
54
name = “Valentin” print(“Hello, {}!”.format(name)) >>> Hello, Valentin!<p>В некоторых версиях Python можно сделать то же самое и другим способом:</p>
55
<p>Результат будет один и тот же. Если у вас работают обе версии, то делайте так, как вам больше нравится.</p>
55
<p>Результат будет один и тот же. Если у вас работают обе версии, то делайте так, как вам больше нравится.</p>
56
<ol><li>Операции сравнения будут возвращать ответ в виде правда/неправда: True/False.</li>
56
<ol><li>Операции сравнения будут возвращать ответ в виде правда/неправда: True/False.</li>
57
<li>Для проверки на равенство используются два знака "равно".</li>
57
<li>Для проверки на равенство используются два знака "равно".</li>
58
<li>Для проверки на неравенство используется восклицательный знак (знак отрицания) со знаком "равно".</li>
58
<li>Для проверки на неравенство используется восклицательный знак (знак отрицания) со знаком "равно".</li>
59
</ol><p>Например:</p>
59
</ol><p>Например:</p>
60
A = 5 B = 10 A > B >>>False A < B >>>True A == B >>>False A != B >>>True A == 5 >>>True<p>Теперь посмотрим, как в Python устроены условия и циклы, которые позволяют направить вычисления в ту или иную сторону.</p>
60
A = 5 B = 10 A > B >>>False A < B >>>True A == B >>>False A != B >>>True A == 5 >>>True<p>Теперь посмотрим, как в Python устроены условия и циклы, которые позволяют направить вычисления в ту или иную сторону.</p>
61
<p>Для условий используются классические структуры<em>if - else</em>. Давайте с их помощью проверим число на чётность:</p>
61
<p>Для условий используются классические структуры<em>if - else</em>. Давайте с их помощью проверим число на чётность:</p>
62
num = 13 if num % 2 == 0: print(“Чётное”) else: print(“Нечётное”)<p><strong>Важная особенность синтаксиса</strong>(хорошо видна в примере выше): для создания иерархии в Python используется отступ, а не фигурные скобки, как в некоторых других языках. Сначала это непривычно, но не пугайтесь: вы быстро привыкнете.</p>
62
num = 13 if num % 2 == 0: print(“Чётное”) else: print(“Нечётное”)<p><strong>Важная особенность синтаксиса</strong>(хорошо видна в примере выше): для создания иерархии в Python используется отступ, а не фигурные скобки, как в некоторых других языках. Сначала это непривычно, но не пугайтесь: вы быстро привыкнете.</p>
63
<p>Циклы позволяют выполнять какое-то действие больше чем один раз. Виды циклов:</p>
63
<p>Циклы позволяют выполнять какое-то действие больше чем один раз. Виды циклов:</p>
64
<ul><li><strong>while:</strong>действие будет выполняться до тех пор, пока выполняется условие;</li>
64
<ul><li><strong>while:</strong>действие будет выполняться до тех пор, пока выполняется условие;</li>
65
<li><strong>for:</strong>действие будет выполнено определённое количество раз.</li>
65
<li><strong>for:</strong>действие будет выполнено определённое количество раз.</li>
66
</ul><p>Посмотрим на примерах, как это работает.</p>
66
</ul><p>Посмотрим на примерах, как это работает.</p>
67
<p><strong>ПРИМЕР 1</strong></p>
67
<p><strong>ПРИМЕР 1</strong></p>
68
i = 10 while i >= 0: print(i) i = i - 1<p>Такой код выведет нам последовательность чисел от 10 до 0, а потом остановится.</p>
68
i = 10 while i >= 0: print(i) i = i - 1<p>Такой код выведет нам последовательность чисел от 10 до 0, а потом остановится.</p>
69
<p><strong>ПРИМЕР 2</strong></p>
69
<p><strong>ПРИМЕР 2</strong></p>
70
i = 10 while i >= 0: if i == 0: print(“Hurray!”) else: print(i) i = i - 1<p>Здесь мы получим последовательность от 10 до 1 и напечатанное "Hurray!" в конце.</p>
70
i = 10 while i >= 0: if i == 0: print(“Hurray!”) else: print(i) i = i - 1<p>Здесь мы получим последовательность от 10 до 1 и напечатанное "Hurray!" в конце.</p>
71
<p>Перед работой с For-циклом надо узнать, что такое массив.</p>
71
<p>Перед работой с For-циклом надо узнать, что такое массив.</p>
72
<p><strong>Массив</strong>- это набор информации, который представляется так:</p>
72
<p><strong>Массив</strong>- это набор информации, который представляется так:</p>
73
array = [1, 2.4, -4.2, “5”]<p>В одном массиве можно хранить переменные разных типов. Например, в нашем массиве array хранится один<em>int</em>, два<em>float</em>и один<em>str</em>. Индексы в Python начинаются с нуля, поэтому чтобы получить информацию с первого места<em>(в нашем случае цифру 1)</em>, напишем вот так:</p>
73
array = [1, 2.4, -4.2, “5”]<p>В одном массиве можно хранить переменные разных типов. Например, в нашем массиве array хранится один<em>int</em>, два<em>float</em>и один<em>str</em>. Индексы в Python начинаются с нуля, поэтому чтобы получить информацию с первого места<em>(в нашем случае цифру 1)</em>, напишем вот так:</p>
74
<p>С элементом массива можно работать как с обычным числом, то есть если написать<em>array[0] +1</em>, мы получим 2.</p>
74
<p>С элементом массива можно работать как с обычным числом, то есть если написать<em>array[0] +1</em>, мы получим 2.</p>
75
<p>Напишем простенький цикл:</p>
75
<p>Напишем простенький цикл:</p>
76
<p>Он выведет нам все элементы нашего массива и остановится. В каждом витке цикла переменная v получает значение соответствующего элемента.</p>
76
<p>Он выведет нам все элементы нашего массива и остановится. В каждом витке цикла переменная v получает значение соответствующего элемента.</p>
77
<p>Дефолтных функций бывает недостаточно, и часто случается, что один и тот же набор операций надо выполнить много раз, причём с разными переменными. Чтобы сохранить время и избежать огромного кода, который сложно понять, мы можем создавать собственные функции.</p>
77
<p>Дефолтных функций бывает недостаточно, и часто случается, что один и тот же набор операций надо выполнить много раз, причём с разными переменными. Чтобы сохранить время и избежать огромного кода, который сложно понять, мы можем создавать собственные функции.</p>
78
<p>Давайте напишем функцию, которая увеличит значение числа, которое мы ей передадим, на единицу:</p>
78
<p>Давайте напишем функцию, которая увеличит значение числа, которое мы ей передадим, на единицу:</p>
79
def increase_by_1(x): return x + 1<p>Команда<em><strong>def</strong></em><em>(от англ. define - определить)</em>означает, что мы определяем собственную функцию,<em>increase_by_ 1</em> - это её название, а <em>x</em> - это переменная, с которой она работает.</p>
79
def increase_by_1(x): return x + 1<p>Команда<em><strong>def</strong></em><em>(от англ. define - определить)</em>означает, что мы определяем собственную функцию,<em>increase_by_ 1</em> - это её название, а <em>x</em> - это переменная, с которой она работает.</p>
80
increase_by_1(11) >>> 12 increase_by_1(0) >>>1<p>Иногда функция уже существует, но её нет в базовой версии Python. Тогда её можно импортировать из библиотеки. Например, чтобы работать с более сложными математическими функциями, чем те, о которых мы говорили, нам понадобится библиотека<em>math</em>. Подключить можно всю библиотеку или только одну-две команды, в зависимости от того, что вам нужно. Для этого используется функция<em>import</em>. Это выглядит так:</p>
80
increase_by_1(11) >>> 12 increase_by_1(0) >>>1<p>Иногда функция уже существует, но её нет в базовой версии Python. Тогда её можно импортировать из библиотеки. Например, чтобы работать с более сложными математическими функциями, чем те, о которых мы говорили, нам понадобится библиотека<em>math</em>. Подключить можно всю библиотеку или только одну-две команды, в зависимости от того, что вам нужно. Для этого используется функция<em>import</em>. Это выглядит так:</p>
81
import math #вся библиотека from math import sin #только функция синус<p><strong>Внимание!</strong></p>
81
import math #вся библиотека from math import sin #только функция синус<p><strong>Внимание!</strong></p>
82
<p><strong>Будьте осторожны с названиями функций! Если вы напишете свою функцию, а потом импортируете функцию с таким же названием, вы сможете использовать только импортированную.</strong></p>
82
<p><strong>Будьте осторожны с названиями функций! Если вы напишете свою функцию, а потом импортируете функцию с таким же названием, вы сможете использовать только импортированную.</strong></p>
83
<p>Приступим к последнему заданию - сделаем в Python график курса доллара с начала 2019 года.</p>
83
<p>Приступим к последнему заданию - сделаем в Python график курса доллара с начала 2019 года.</p>
84
<p>Для начала импортируем библиотеки<strong>Numpy</strong>(в ней удобно работать с массивами и матрицами),<strong>Pandas</strong>(работа с CSV-файлами) и <strong>Matplotlib</strong>(визуализация).</p>
84
<p>Для начала импортируем библиотеки<strong>Numpy</strong>(в ней удобно работать с массивами и матрицами),<strong>Pandas</strong>(работа с CSV-файлами) и <strong>Matplotlib</strong>(визуализация).</p>
85
<p>Вы можете дать библиотеке имя, которое будете использовать вместо настоящего названия, - это часто делается для экономии времени.</p>
85
<p>Вы можете дать библиотеке имя, которое будете использовать вместо настоящего названия, - это часто делается для экономии времени.</p>
86
import numpy as np import pandas as pd import matplotlib.pyplot as plt<p>На сайте Центрального Банка РФ <a>скачаем</a>CSV-файл с курсом от начала года.</p>
86
import numpy as np import pandas as pd import matplotlib.pyplot as plt<p>На сайте Центрального Банка РФ <a>скачаем</a>CSV-файл с курсом от начала года.</p>
87
<p>Записываем скачанный файл в переменную money:</p>
87
<p>Записываем скачанный файл в переменную money:</p>
88
money = pd.read_csv(“название файла.csv”, sep = “;”) #часть sep = “;” нужна, потому что вместо запятых в этом файле использованы знаки ";", у обычного csv это делать не нужно<p>Теперь если мы выведем money, то увидим таблицу с курсом.</p>
88
money = pd.read_csv(“название файла.csv”, sep = “;”) #часть sep = “;” нужна, потому что вместо запятых в этом файле использованы знаки ";", у обычного csv это делать не нужно<p>Теперь если мы выведем money, то увидим таблицу с курсом.</p>
89
<p>Вот такую:</p>
89
<p>Вот такую:</p>
90
<p>В России принято отделять десятичную часть запятой, поэтому перед созданием графика мы напишем маленькую функцию, которая заменит запятые точками.</p>
90
<p>В России принято отделять десятичную часть запятой, поэтому перед созданием графика мы напишем маленькую функцию, которая заменит запятые точками.</p>
91
def convert(str_money): return float(str_money.replace(“,”, “.”)) money[“curs”] = money[“curs”].apply(convert)<p>Теперь осталось только показать график командой:</p>
91
def convert(str_money): return float(str_money.replace(“,”, “.”)) money[“curs”] = money[“curs”].apply(convert)<p>Теперь осталось только показать график командой:</p>
92
<p>Если вы всё сделали правильно, то сейчас вы видите график курса доллара США, у нас получилось вот так:</p>
92
<p>Если вы всё сделали правильно, то сейчас вы видите график курса доллара США, у нас получилось вот так:</p>
93
<a><b>Бесплатный курс по Python ➞</b>Мини-курс для новичков и для опытных кодеров. 4 крутых проекта в портфолио, живое общение со спикером. Кликните и узнайте, чему можно научиться на курсе. Смотреть программу</a>
93
<a><b>Бесплатный курс по Python ➞</b>Мини-курс для новичков и для опытных кодеров. 4 крутых проекта в портфолио, живое общение со спикером. Кликните и узнайте, чему можно научиться на курсе. Смотреть программу</a>