Hello World!

Изучение нового языка программирования традиционно начинается с 'Hello, World!'. Это простая программа, которая выводит приветствие на экран и заодно знакомит с новым языком — его синтаксисом.

Этой традиции уже больше сорока пяти лет, поэтому и мы не будем нарушать ее. Напишем программу Hello, World!. Чтобы сделать это, нужно дать компьютеру специальную команду на вывод. В языке Python это — print():

print('Hello, World!')
# => Hello, World!

Как работают комментарии

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

С их помощью добавляют пояснения, как работает код, какие ошибки нужно поправить или не забыть что-то добавить позже:

# Удалить строку ниже после реализации задачи по регистрации
print("Сделайте регистрацию")

Комментарии в Python начинаются со знака # и могут появляться в любом месте программы. Они могут занимать всю строку. Если одной строки мало, то создается несколько комментариев:

# Это первый комментарий!
# Это второй комментарий!

Комментарий может находиться на строке после кода:

print('Hello World!')  # Подробности тут: https://ru.wikipedia.org/wiki/Hello,_world!

Инструкции

Когда мы оплачиваем покупки в магазине, то четко следуем инструкции по оплате. Иначе нам не продадут товар или услугу. Также и в программировании важно соблюдать инструкции.

Чтобы увидеть на экране ожидаемый результат, нужно дать компьютеру четкие и пошаговые указания. Это можно сделать с помощью инструкций. Инструкция — это команда для компьютера, единица выполнения. Код на Python в этом случае — это набор инструкций. Его можно представить в виде пошагового алгоритма действий компьютера.

Код на Python запускает интерпретатор — программу, которая выполняет инструкции строго по очереди. Как и шаги в рецепте, наборы инструкций для интерпретатора пишутся по порядку и отделяются друг от друга переходом на следующую строку.

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

Посмотрим на пример кода с двумя инструкциями. При его запуске на экран последовательно выводятся два предложения:

print('Выводи это сообщение первым.')
print('А это выводи вторым на экран!')
# => Выводи это сообщение первым.
# => А это выводи вторым на экран!

Выше мы говорили, что инструкции отделяются друг от друга переходом на новую строку. Но есть и другой способ: их можно разделить точкой с запятой — ;:

print('Выводи это сообщение первым.'); print('Подробнее об интерпретаторах тут: https://ru.wikipedia.org/wiki/Интерпретатор')
# => Выводи это сообщение первым.
# => Подробнее об интерпретаторах тут: https://ru.wikipedia.org/wiki/Интерпретатор

Технической разницы между первым и вторым вариантом нет — интерпретатор поймет инструкции одинаково. Разница только в том, что человеку будет неудобно читать второй вариант.

Лучше инструкции располагать друг под другом. Так всем будет удобнее читать код, обслуживать его и вносить изменения.

Арифметические операции

На базовом уровне компьютеры оперируют только числами. Даже в прикладных программах на высокоуровневых языках внутри много чисел и операций над ними. Но для старта достаточно знать обычную арифметику — с нее и начнем.

Например, для сложения двух чисел в математике мы пишем: 2 + 2. В программировании — то же самое. Вот программа, которая складывает два числа:

2 + 2

Арифметика в программировании практически не отличается от школьной арифметики.

Строчка кода 2 + 2 заставит интерпретатор сложить числа и узнать результат. Эта программа будет работать, но в ней нет смысла. По сути, мы не даем команду интерпретатору, мы просто говорим ему: «Смотри, сумма два и два». В реальной работе недостаточно сообщать интерпретатору о математическом выражении.

Например, если создавать интернет-магазин, недостаточно просить интерпретатор посчитать стоимость товаров в корзине. Нужно просить посчитать стоимость и показать цену покупателю.

Нам нужно попросить интерпретатор сложить 2 + 2 и дать команду сделать что-то с результатом. Например, вывести его на экран:

# Сначала вычисляется сумма, затем она передается в функцию печати
2 + 2  # => 4

Кроме сложения, доступны следующие операции:

    • — вычитание
    • — умножение
  • ** — возведение в степень
  • / — деление
  • // — целочисленное деление
  • % — остаток от деления

Теперь выведем на экран результат деления, результат возведения в степень и результат получения остатка от деления:

print(6 / 2)   # => 3.0 (При делении двух чисел получается тип данных float)
print(4 ** 2)  # => 16
print(7 % 2)   # => 1

Операторы и операнды

Знак операции, такой как +, называют оператором. Операторы выполняют операции над определенными значениями, которые называются операндами. Сами операторы — это обычно один или несколько символов. Реже — слово. Подавляющее большинство операторов соответствуют математическим операциям.

print(2 + 2)

В этом примере + — это оператор, а числа 2 и 2 — это операнды.

Когда мы складываем, у нас есть два операнда: один слева, другой справа от знака +. Операции, которые требуют наличия двух операндов, называются бинарными. Если пропустить хотя бы один операнд, например, 2 +, то программа завершится с синтаксической ошибкой.

Операции бывают не только бинарными, но и унарными — с одним операндом, и тернарными — с тремя операндами. Причем операторы могут выглядеть одинаково, но обозначать разные операции. Символы + и - используются не только как операторы. Когда речь идет про отрицательные числа, то знак минуса становится частью числа:

print(-5)  # => -5

Выше пример применения унарной операции к числу 5. Оператор минус перед тройкой говорит интерпретатору взять число 5 и найти противоположное, то есть -5. Это может сбить с толку, потому что -5 — это одновременно и число само по себе, и оператор с операндом. Но у языков программирования такая структура.

Коммутативная операция

«От перемены мест слагаемых сумма не меняется» — это один из базовых законов арифметики, который также называется коммутативным законом. Бинарная операция считается коммутативной, если вы получаете тот же самый результат, поменяв местами операнды. В этом случае сложение — это коммутативная операция: 3 + 2 = 2 + 3.

Но вычитание — это не коммутативная операция: 2 - 3 ≠ 3 - 2. В программировании этот закон работает точно так же, как в арифметике. Более того, большинство операций, с которыми мы сталкиваемся в реальной жизни, не являются коммутативными. Отсюда вывод: всегда обращайте внимание на порядок того, с чем работаете.

Композиция операций

Рассмотрим пример:

print(2 * 3 * 4 * 5)

Операции можно соединять друг с другом и вычислять все более сложные составные выражения. Чтобы представить, как происходят вычисления внутри интерпретатора, разберем пример: 2 * 3 * 3 * 5.

Сначала вычисляется 2 * 3 и получается выражение 6 * 4 * 5 Затем 6 * 4. В итоге имеем 24 * 5 В итоге происходит последнее умножение, и получается результат 120 Операции могут содержать разные операторы, из-за чего появляется вопрос об их приоритете.

Приоритет операций

Представим, что нужно вычислить такое выражение: 2 + 2 * 2. Именно так и запишем:

print(2 + 2 * 2)  # => 6

В школьной математике есть понятие «приоритет операции». Приоритет определяет, в какой последовательности должны выполняться операции. Умножение и деление имеют больший приоритет, чем сложение и вычитание, а приоритет возведения в степень выше всех остальных арифметических операций. Например: 2 ** 3 * 2 вычислится в 16.

Но нередко вычисления должны происходить в порядке, отличном от стандартного приоритета. Тогда приоритет нужно задавать круглыми скобками. Так и в школе, например: (2 + 2) * 2. В скобки можно заключать любую операцию. Они могут вкладываться друг в друга сколько угодно раз. Вот примеры:

print(3 ** (4 - 2))  # => 9
print(7 * 3 + (4 / 2) - (8 + (2 - 1)))  # => 14.0

Главное при этом соблюдать парность — закрывать скобки в правильном порядке. Это часто становится причиной ошибок не только у новичков, но и у опытных программистов.

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

# Было
print(8 / 2 + 5 - -3 / 2)  # => 10.5
# Стало
print(((8 / 2) + 5) - (-3 / 2))  # => 10.5

Важно запомнить: код пишется для людей. Код будут читать люди, а машины будут только исполнять его. Для машин код — корректный или некорректный. Для них нет «более» понятного или «менее» понятного кода.

Ошибки оформления кода

Если программа на Python написана синтаксически некорректно, то интерпретатор выводит на экран соответствующее сообщение. Также он указывает на файл и строчку, где произошла ошибка.

Синтаксическая ошибка возникает в том случае, когда код записали с нарушением грамматических правил. В естественных языках грамматика важна, но текст с ошибками обычно можно понять и прочитать. В программировании все строго. Мельчайшее нарушение — и программа даже не запустится. Примером может быть забытое двоеточие(:) неправильно расставленные скобки и другие детали.

Вот пример кода с синтаксической ошибкой:

print('Привет)

Если запустить код выше, то мы увидим следующее сообщение: SyntaxError: EOL while scanning string literal

С одной стороны, ошибки синтаксиса — самые простые, потому что они связаны с грамматическими правилами написания кода, а не со смыслом кода. Их легко исправить: нужно лишь найти нарушение в записи. С другой стороны, интерпретатор не всегда может четко указать на это нарушение. Поэтому бывает, что забытую скобку нужно поставить не туда, куда указывает сообщение об ошибке.

Ошибки линтера

Код нужно оформлять определенным образом, чтобы он был понятным и простым в поддержке. Существуют специальные наборы правил, которые описывают различные аспекты написания кода — их называют стандартами кодирования. В Python стандарт один — PEP8. Он отвечает практически на все вопросы о том, как оформлять ту или иную часть кода. Этот документ содержит все правила, которых нужно придерживаться. Новичкам мы советуем завести привычку заглядывать в стандарт PEP8 и писать код по нему.

Сегодня не нужно помнить все правила из стандарта, потому что существуют специальные программы, которые проверяют код автоматически и сообщают о нарушениях. Такие программы называются линтерами. Они проверяют код на соответствие стандартам. В Python их достаточно много, и наиболее популярный из них — flake8.

Взгляните на пример:

x =1+ 3

Линтер будет предупреждать на нарушение правила: E225 missing whitespace around operator. По стандарту, все операторы всегда должны отделяться пробелами от операндов.

Выше мы увидели правило E225 — это одно из большого количества правил. Другие правила описывают отступы, названия, скобки, математические операции, длину строчек и множество иных аспектов. Каждое отдельное правило кажется неважным и мелким, но вместе они составляют основу хорошего кода. Список всех правил PEP8 доступен в документации на сайте: https://peps.python.org/pep-0008/

Немного про строки

Определить строку довольно просто — это некий набор символов. Представим, что у нас есть такие записи:

'Hello'
'Goodbye'
'G'
' '
''

Какие из этих вариантов — строки? На самом деле, все пять вариантов подходят:

  • С 'Hello' и 'Goodbye' все очевидно — мы уже работали с подобными конструкциями и называли их строками
  • 'G' и ' ' — тоже строки, просто в них всего по одному символу
  • '' — это пустая строка, потому что в ней ноль символов

Кавычки

Строкой мы считаем все, что находится внутри кавычек: даже если это пробел, один символ или вообще отсутствие символов.

Выше мы записывали строки в одинарных кавычках, но это не единственный способ. Можно использовать и двойные:

print("Это строка!")

Теперь представьте, что вы хотите напечатать строчку Python's. Апостроф перед буквой s — это такой же символ, как одинарная кавычка. Попробуем:

print('Python's')
# SyntaxError: invalid syntax

Такая программа не будет работать. С точки зрения Python, строчка началась с одинарной кавычки, а потом закончилась после слова Python. Дальше были символы s без кавычек — значит, это не строка. А потом была одна открывающая строку кавычка, которая так и не закрылась: '). Этот код содержит синтаксическую ошибку — это видно даже по тому, как подсвечен код.

Чтобы избежать этой ошибки, мы используем двойные кавычки. Такой вариант программы сработает верно:

print("Python's")

Теперь интерпретатор знает, что строка началась с двойной кавычки и закончиться должна тоже на двойной кавычке. А одинарная кавычка внутри стала частью строки.

Верно и обратное. Если внутри строки мы хотим использовать двойные кавычки, то саму строку нужно заключать в одинарные. Причем количество кавычек внутри самой строки неважно.

Теперь представим, что мы хотим создать такую строку: Python's mother said "No". В ней есть и одинарные, и двойные кавычки. Нам нужно каким-то образом указать интерпретатору, что кавычки — это символы внутри строки, а не начало или конец строки.

Для этого используют символ экранирования: ** — обратный слэш. Если мы поставим \ перед кавычкой (одинарной или двойной), то интерпретатор распознает кавычку как обычный символ внутри строки, а не начало или конец строки:

# Экранируем кавычки вокруг No, чтобы интерпретатор распознал их как часть строки
print("Python's mother said \"No\"")
# => Python's mother said "No"

Обратите внимание, что в примере выше нам не пришлось экранировать одинарную кавычку (апостроф 's), потому что сама строка создана с двойными кавычками. Если бы строка создавалась с одинарными кавычками, то символ экранирования нужен был бы перед апострофом, но не перед двойными кавычками.

Если нужно вывести сам обратный слеш, то работает такое же правило. Как и любой другой специальный символ, его надо экранировать:

print("\\")
# => \

Экранированные последовательности

Мы хотим показать вот такой диалог:

- Ты изучаешь Python?
- Дааааа!

Попробуем вывести на экран строку с таким текстом:

print("- Ты изучаешь Python? - Дааааа!")
# => - Ты изучаешь Python? - Дааааа!

Результат получился не такой, как мы хотели. Строки расположились друг за другом, а не одна ниже другой. Нам нужно как-то сказать интерпретатору «нажать на Enter» — сделать перевод строки после вопросительного знака. Это можно сделать с помощью символа \n:

\n — это пример экранированной последовательности(escape sequence). Такие последовательности еще называют управляющими конструкциями. Их нельзя увидеть в том же виде, в котором их набрали.

Набирая текст в Word, вы нажимаете на Enter в конце строчки. Редактор при этом ставит в конец строчки специальный невидимый символ, который называется LINE FEED (LF, перевод строчки). В некоторых редакторах можно даже включить отображение невидимых символов. Тогда текст будет выглядеть примерно так:

- Привет!¶
- Добрый день сэр!¶
- Как дела?

Устройство, которое выводит соответствующий текст, учитывает этот символ. Например, принтер при встрече с LF протаскивает бумагу вверх на одну строку, а текстовый редактор переносит весь последующий текст ниже, также на одну строку.

Существует несколько десятков таких невидимых символов, но в программировании часто встречаются всего несколько. Кроме перевода строки, к таким символам относятся:

Табуляция \t — разрыв, который получается при нажатии на кнопку Tab
Возврат каретки \r — работает только в Windows

Распознать такую управляющую конструкцию в тексте можно по символу . Программисты часто используют перевод строки \n, чтобы правильно форматировать текст. Например, напишем такой код:

print("Математика\nИнформатика\nФизика\nХимия")

Тогда на экран выведется:

Математика
Информатика
Физика
Химия

Когда работаете с символом перевода, учитывайте следующие моменты:

  1. Не важно, что стоит перед или после \n: символ или пустая строка. Перевод обнаружится и выполнится в любом случае.
  2. Строка может содержать только \n:
print('Привет') # Строка с текстом
print("\n") # Строка с невидимыми символами перевода строки
print('Мир!') # Строка с текстом

Программа выведет на экран:

Привет

Мир!
  1. В коде последовательность \n выглядит как два символа, но с точки зрения интерпретатора — это один специальный символ
  2. Если нужно вывести \n как текст (два отдельных печатных символа), то можно воспользоваться экранированием — добавить еще один \ в начале. Последовательность \n отобразится как символы \ и n, которые идут друг за другом:
print("Привет мир! \\n")
# => Привет мир! \n

В Windows для перевода строк по умолчанию используется \r\n. Такая комбинация хорошо работает только в Windows, но создает проблемы при переносе в другие системы. Например, когда в команде разработчиков есть пользователи Linux. Дело в том, что последовательность \r\n имеет разную трактовку в зависимости от выбранной кодировки. По этой причине в среде разработчиков принято всегда использовать \n без \r. В таком случае перевод строки всегда трактуется одинаково и отлично работает в любой системе.

Конкатенация

В веб-разработке программы постоянно оперируют строками. Все, что мы видим на сайтах, так или иначе представлено в виде текста. Этот текст чаще всего динамический — то есть он получается из разных частей, которые соединяются вместе.

Чтобы соединить строки, нужно выполнить конкатенацию:

# Оператор такой же, как и при сложении чисел, но здесь он имеет другой смысл
print('При' + 'вет')  # => Привет

Склеивание строк всегда происходит в том же порядке, в котором записаны операнды. Левый операнд становится левой частью строки, а правый — правой. Вот еще несколько примеров:

print('Pyt' + 'hon')  # => Python
print("Pyt" + 'hon')  # => Python

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

Пробел — такой же символ, как и другие, поэтому сколько пробелов поставите в строке, столько и получится в итоговой строке:

# Ставим пробел в левой части
print("Привет " + 'мир!')  # => Привет мир!
# Ставим пробел в правой части
print('Hello' + ' World!')  # => Hello World!

Попробуйте сами запустить код в окне ниже с интерпретатором Python и повторите примеры из статьи чтобы самим увидеть и понять как всё это работает. Для этого в ячейке с кодом нажмите клавиши на клавиатуре Shift+Enter или запустите код через кнопку Run по значку ▶.