Skip to content
Open
20 changes: 20 additions & 0 deletions 0_tutorial/14_google.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
Правильно искать информацию в сети – важно. Подберёшь неправильный запрос – не найдёшь нужной ссылки.
Иногда приходится делать много попыток, чтобы найти то, что надо. Тратишь полчаса на поиск решения проблемы,
а какой-нибудь Вася найдёт то же, но за один запрос.

В итоге правильное использование поиска не только позволяет экономить время, но и не чувствовать себя идиотом.


> Это же чёртов поиск, написал запрос – увидел результат. Чего сложного?

Сложно написать запрос правильно. Оказывается, Гугл умеет много вещей, которые очень помогают искать информацию.
Их надо знать и использовать.

Вот где о них можно узнать:

- [Мини-курс Power Searching With Google](https://coursebuilder.withgoogle.com/sample/course) (en). Да, у Гугла есть
онлайн-курс про то, как пользоваться Гуглом (даже два курса). Видео-лекции, домашние задания. Всё серьёзно.
Очень рекомендую: он короткий и очень подробный.
- [Google Tips & Tricks](https://www.google.com/intl/en_us/insidesearch/tipstricks/all.html) (en).
- [Как правильно искать в Google](https://habrahabr.ru/sandbox/46956/).
- [Google без секретов (операторы Гугла в практических примерах)](http://it2b.ru/blog/arhiv/761.html).
2 changes: 2 additions & 0 deletions 0_tutorial/29_english.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

Самый ад – названия переменных по-русски, транслитом. Таким людям положен Сименс М65 без русской раскладки, а не работа
программистом.
Отдельно про написание кода: вот встречаются в коде опечатки, неправильный перевод при названии переменной
или частые опечатки в документации – и всё, ощущение хорошего продукта улетучивается.

Хорошая новость в том, что никому не нужно, чтобы тебя путали с носителем языка. Достаточно базового знания грамматики,
чтобы правильно понимать смысл, и лексики, чтобы поменьше тыкать в переводчик.
Expand Down
16 changes: 16 additions & 0 deletions 0_tutorial/8_cli.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
Консоль – основной способ взаимодействия разработчика с системой. С ней надо уметь взаимодействовать
не хуже, чем с графическим интерфейсом.

А вот ресурсы, на которых есть план минимум и больше:

- [ШПАРГАЛКА. Команды Unix - Linux](http://forum.ubuntu.ru/index.php?topic=14535.15). Неожиданно полезная тема на форуме Убунту.
- [Цикл статей на linuxrussia](http://www.linuxrussia.com/2013/08/terminal-linux-1.html).
- [Unix shell: абсолютно первые шаги](https://habrahabr.ru/post/267825/).
- [Туториал от университета Суррей](http://www.ee.surrey.ac.uk/Teaching/Unix/index.html) (en).
- [Туториал от Райана](http://ryanstutorials.net/linuxtutorial/) (en). Есть [шпаргалка](http://ryanstutorials.net/linuxtutorial/cheatsheet.php).

Обрати внимание, что есть shell scripting – прямо в консоли можно городить циклы, условия и вообще писать вполне себе программы.
Лучше обойти это стороной прямо сейчас: это довольно специфичный навык, которые не каждому пригождается.

Мне в своё время очень помогла книга ["Linux. Необходимый код и команды. Карманный справочник"](https://www.ozon.ru/context/detail/id/3178480/).
Она компактная, подробная и понятная. Рекомендую.
4 changes: 3 additions & 1 deletion 0_tutorial/9_git.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,6 @@

Следующий шаг – [туториал на githowto.com](https://githowto.com/ru), он на русском и куда длиннее.

Гитхаб – это что-то типа Фейсбука для программистов. Код вместо постов, баги вместо котиков. Идиллия.
Гитхаб – это что-то типа Фейсбука для программистов. Код вместо постов, баги вместо котиков. Идиллия.
Чтобы познакомиться с ним ближе, рекомендую выполнить их [Hello World](https://guides.github.com/activities/hello-world/).
После можно пройти [остальные руководства от Гитхаба](https://guides.github.com/), это очень полезные навыки для разработчика.
15 changes: 15 additions & 0 deletions 1_python_basics/18_comments.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

Комментарии – способ прокомментировать код на ходу, на той же строке.

:::python
price = Column(BigInteger) # рубли * 100


Expand All @@ -13,6 +14,7 @@
Она нужна для документирования всей функции: описания входящих параметров, результата, логики, крайних случаев.
Заключается в тройные двойные кавычки. Вот так:

:::python
def tensorsolve(a, b, axes=None):
"""
Solve the tensor equation ``a x = b`` for x.
Expand Down Expand Up @@ -40,17 +42,20 @@
В таком случае комментарий не несёт дополнительной информации, а просто переводит соседний код
с Питона на русский/английский. Пример:

:::python
# загружаем данные из файла data.json
with open('users.json', 'r') as handler:
data = json.load(handler)

Вот как можно исправить:

:::python
with open('users.json', 'r') as handler:
data = json.load(handler)

А так – ещё лучше:

:::python
data = load_all_users_from_file()


Expand All @@ -59,6 +64,7 @@
Другая частая ошибка: не менять комментарии при изменении кода. В примере выше мы загружали данные из файла.
Через месяц взялись за голову и поселили данные в базе данных. Код стал таким:

:::python
# загружаем данные из файла data.json
data = db_session.query(User).all()

Expand All @@ -71,6 +77,7 @@
В таком состоянии всё поведение кажется понятным, поэтому разработчик может оставить комментарий самому себе.
Проблема в том, что когда он переключится на другую задачу и забудет про детали, комментарий может взорвать мозг:

:::python
inv(strain_tensor) - rigidity.T # правый случай

Правый, правда? Ну, теперь всё понятно.
Expand All @@ -94,3 +101,11 @@
или `FIXME: учитывать часовой пояс`.

Прежде чем написать комментарий, попробуй поселить его в коде, указав параметр или дав подходящее название переменной.


## Что изучать

- [Доклад Григория Петрова про комментирование исходников](https://www.youtube.com/watch?v=-SRUctRR_4s). Обязателен к просмотру.
- [PEP 257](https://www.python.org/dev/peps/pep-0257/). ПЕП про докстринги.
- [doctest](https://docs.python.org/3.5/library/doctest.html). Документация к модулю про доктесты.
- [What is the best comment in source code you have ever encountered?](http://stackoverflow.com/questions/184618/). Шутить в коде не стоит, а вот посмеяться с чужих шуток можно. Это ж не нам поддерживать.
5 changes: 5 additions & 0 deletions 1_python_basics/2_base_types.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

Числа – и в Африке числа. С ними можно производить арифметические действия. Всё просто:

:::python
2 + 2 # 4
3 + 2.5 # 5.5
6 / 2 # 3
Expand All @@ -19,6 +20,7 @@

Помимо чисел в Питоне есть строки с богатым набором встроенных функций. С ними просто и удобно работать:

:::python
'hello' # строковая константа
"hello" # тип кавычек не имеет значения
hello[1] # 'e'
Expand All @@ -27,6 +29,7 @@

У них много встроенных функций:

:::python
'hello '.strip() # 'hello'
'hello world'.upper() # 'HELLO WORLD'
len('hello') # 5
Expand All @@ -43,6 +46,7 @@
Элементы могут быть разных типов, даже другими списками. Выглядит он так:


:::python
[1, 2, 3] # в квадратных скобках, элементы через запятую
digits = [4, 5, 6] # переменная, в которой живёт список
digits[0] # 4 (нумерация с нуля)
Expand All @@ -52,6 +56,7 @@
Из списка надо часто получить подсписок: несколько первых элементов, последних, что-то из середины.
Это называется срезами и позволяет делать много чего. Вот самые простые срезы:

:::python
squares = [1, 4, 9, 16, 25, 36, 49]
squares[1:3] # [4, 9] (элементы со второго по третий)
squares[:4] # [1, 4, 9, 16] (элементы с начала до четвёртого)
Expand Down
99 changes: 99 additions & 0 deletions 1_python_basics/3_base_constructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
### Коротко о главных управляющих конструкциях

Сейчас мы совсем реактивно пройдёмся по самым основным управляющим конструкциям. Гет реди.


### if

Ну, вы все знаете условный оператор, так ведь?

:::python
if age < 18:
print('Никаких тебе сигарет. Ишь чего удумал!')
else:
print('Вам синий или красный?')


Есть ещё `elif`, их можно сделать много в одном операторе. Это такой аналог `which` из других языков.


### for

Цикл. Вместо сишного варианта с init, cond и loop выражениями, тут просто итерация по коллекции:

:::python
for user in users:
print user

Иногда надо не пройтись по списку, а выполнить одну и ту же операцию много раз. Тогда хорошо подходит функция
[range](https://docs.python.org/3.5/library/functions.html#func-range). Она возвращает целые числа в заданном промежутке,
поэтому в цикле её можно использовать так:

:::python
for level_num in range(10):
user.levelup() # пользователь получит десять уровней. Читер!

А вот `break` и `continue` делают то же, что в Паскале и Сях. `break` прерывает выполнение цикла,
`continue` завершает текущую итерацию и переходит к следующей.

Ещё у цикла есть `else`, но про него почти никто не знает. Как он работает можно посмотреть
[в официальной документации](https://docs.python.org/3.5/tutorial/controlflow.html#break-and-continue-statements-and-else-clauses-on-loops).


### def

Начало объявления функции. После него идёт название,
потом – аргументы функции в скобках, двоеточие и тело функции с отступом:

:::python
def get_square(value):
return value ** 2

То, что после `return` – это возвращаемое значение функции.

Функцию создали, вот как её теперь использовать:

:::python
print(get_square(2)) # 4
print(get_square(6)) # 36
print(get_square('ыыы')) # всё сломается

А вот пример посложнее, из исходников Девмана. Получает пользователя по айди в Слаке:

:::python
def _get_user_by_slack_id(slack_user_id):
user_email = get_slack_email_for_user(slack_user_id)
return User.objects.filter(email__iexact=user_email).first()

(вот почему емейл необходим)


### range

Функция очень полезная, поэтому про неё отдельно. `range` генерирует целые числа в заданном диапазоне. Например:

:::python
range(10) # 0..0
range(5, 10) # 5..9
range(5, 10, 2) # [5, 7, 9] (от пяти до девяти с шагом два)

Фишка этой функции заключается в том, что она не создаёт список со всеми числами.
Вместо этого он вернёт объект, который будет возвращать элементы как только они нужны, по одному.
Поэтому код `range(9999999999999)` не съест всю память.
Этот хитрый объект (Sequence ABC, но об этом потом) можно превратить в список явно:

:::python
list(range(9999999999999))

(не советую так делать)


### pass

Блок, который ничего не делает:

:::python
for i in range(20):
pass # 20 раз сделать ничего. Очень полезно!

Часто используется в начальном коде для заданий: в финальной версии вместо `pass` должен быть настоящий код.
16 changes: 16 additions & 0 deletions 1_python_basics/4_types.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

Ещё строки можно форматировать, причём несколькими способами. Вот один из них:

:::python
name = 'Пётр'
height = 1.865
print('Привет, %s! Твой рост – %.2f м.' % (name, height))
Expand All @@ -52,6 +53,7 @@
Часто бывает надо взять исходный список и сформировать из него новый, применив к каждому элементу исходного
какое-то преобразование и как-то отфильтровав. Например, так:

:::python
values = [1, 2, 3, 4, 5]
new_values = []
for value in values:
Expand All @@ -62,6 +64,7 @@

Эта операция настолько частая, что для неё есть отдельная конструкция – list comprehension. Выглядит она так:

:::python
values = [1, 2, 3, 4, 5]
new_values = [value ** 2 for value in values if value % 2]

Expand All @@ -72,12 +75,14 @@

Словарь – это отображение одних элементов в другие. Первые называют ключами, вторые – значениями.

:::python
user_info = {'name': 'Иван', 'level': 2}
print(user_info['name']) # Иван


Из словаря можно удалять, менять и добавлять в него элементы:

:::python
user_info = {'name': 'Иван', 'level': 2}
user_info['middle_name'] = 'Иванович'
user_info['name'] = 'Грирогий'
Expand All @@ -90,6 +95,7 @@
Ещё у словарей есть несколько важных методов: `keys`, `values` и `items`. Первый возвращает список только ключей,
второй – список только значений, третий – список пар из ключей и значений. Удобно при итерации по словарю:

:::python
user_info = {'name': 'Иван', 'level': 2}
for key, value in user_info.items():
print '%s: %s' % (key, value)
Expand All @@ -102,3 +108,13 @@
Кортеж выглядит как список, но не совсем. Это скорее структура из C++.
Отличаются от списков тем, что его элементы гетерогенные и тем, что он умеет упаковываться и распаковываться.
Подробнее, например, [в документации](https://docs.python.org/2/tutorial/datastructures.html#tuples-and-sequences).
### Множества

Множество – это математическое множество. В нём все элементы уникальные, можно считать пересечение,
проверять на вхождение и выполнять другие операции с множествами.

Один из частых случаев применения множеств – удаление дублей из списка:

:::python
l = [1, 2, 1, 3, 2]
print(list(set(l))) # [1, 2, 3]
5 changes: 5 additions & 0 deletions 1_python_basics/5_modules.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,14 @@
Важнее всего знать, как Питон выбирает файлы для импорта. Сначала он ищет подходящие файлы в рабочей директории,
рядом с `bars.py`. Если не находит, то проходит по папкам в `sys.path` и ищет нужный файл.

Иногда бывает так, что нужный модуль находится вне тех папок, которые обходит Питон. Один из вариантов побороть это
– вручную добавить нужный путь в `sys.path` (это список). Но это на крайний случай, обычно есть более красивые способы.
Например, упаковать код в модуль и установить его с помощью pip. Так что тсс, я вам ничего не говорил.

В памяти все загруженные модули хранятся в `sys.modules`. Иногда встречаются случаи, когда файла нет, а модуль есть.
Это не сложно устроить:

:::python
# mod.py
import sys
from types import ModuleType
Expand Down
Loading