diff --git a/modules/10-basics/10-hello-world/ru/EXERCISE.md b/modules/10-basics/10-hello-world/ru/EXERCISE.md index 655fe0b..16f353f 100644 --- a/modules/10-basics/10-hello-world/ru/EXERCISE.md +++ b/modules/10-basics/10-hello-world/ru/EXERCISE.md @@ -4,4 +4,4 @@ print('Hello, World!') ``` -Внимание: если вы напишете `heLLo, woRld!` вместо `Hello, World!`, то это будет считаться другим текстом, потому что заглавные и строчные буквы — это разные символы, отличающиеся _регистром_. В программировании регистр практически всегда имеет значение, поэтому привыкайте всегда обращать на него внимание! +Обратите внимание: если вы напишете `heLLo, woRld!` вместо `Hello, World!`, то это будет считаться другим текстом, потому что заглавные и строчные буквы — это разные символы, отличающиеся _регистром_. В программировании регистр практически всегда имеет значение. diff --git a/modules/10-basics/10-hello-world/ru/data.yml b/modules/10-basics/10-hello-world/ru/data.yml index 44a8a39..a8ab7ad 100644 --- a/modules/10-basics/10-hello-world/ru/data.yml +++ b/modules/10-basics/10-hello-world/ru/data.yml @@ -1,7 +1,6 @@ --- - name: Привет, Мир! tips: - > [Немного о 'Hello, - World!'](https://ru.hexlet.io/blog/posts/moy-chelovek-menya-ponimaet-istoriya-frazy-hello-world-i-ee-analogov) + World!'](https://ru.hexlet.io/blog/posts/moy-chelovek-menya-ponimaet-istoriya-frazy-hello-world-i-ee-analogov?utm_source=code-basics&utm_medium=referral&utm_campaign=blog&utm_content=lesson) diff --git a/modules/10-basics/20-comments/ru/EXERCISE.md b/modules/10-basics/20-comments/ru/EXERCISE.md index fd980da..244a978 100644 --- a/modules/10-basics/20-comments/ru/EXERCISE.md +++ b/modules/10-basics/20-comments/ru/EXERCISE.md @@ -1,2 +1 @@ - -Создайте однострочный комментарий с текстом: `You know nothing, Jon Snow!` +Создайте комментарий с текстом: `You know nothing, Jon Snow!` diff --git a/modules/10-basics/20-comments/ru/README.md b/modules/10-basics/20-comments/ru/README.md index 98a48fb..11711b3 100644 --- a/modules/10-basics/20-comments/ru/README.md +++ b/modules/10-basics/20-comments/ru/README.md @@ -1,22 +1,33 @@ - -Практически все языки программирования позволяют оставлять в коде комментарии. Они никак не используются интерпретатором. Они нужны исключительно для людей, чтобы программист оставлял пометки для себя и для других программистов. - -С их помощью добавляют пояснения, как работает код, какие ошибки нужно поправить или не забыть что-то добавить позже: +Кроме самого кода, в исходных файлах часто можно встретить комментарии — это строки, которые не обрабатываются интерпретатором. Они нужны для программистов: чтобы пояснить, как работает код, отметить, где есть ошибки, или напомнить себе и другим, что нужно доделать. ```python # Удалить строку ниже после реализации задачи по регистрации print(10) ``` -Комментарии в Python начинаются со знака `#` и могут появляться в любом месте программы. Они могут занимать всю строку. Если одной строки мало, то создается несколько комментариев: +В Python все комментарии — однострочные. Они начинаются со специального символа #, после которого может идти любой текст. Всё, что написано после #, интерпретатор игнорирует. + +Комментарий может занимать всю строку: ```python # For Winterfell! # For Lanisters! ``` -Комментарий может находиться на строке после кода: +Или стоять в конце строки с кодом: ```python print('I am the King') # For Lannisters! ``` + +Если нужно оставить длинное пояснение, используют несколько строк с #: + +```python +# The night is dark and +# full of terrors. +print('I am the King') +``` + +Они не влияют на выполнение программы, но делают код понятнее. Комментарии помогают команде быстрее разобраться в чужом коде и не забыть важные детали в собственном. + +> 📌 Хорошее правило: пишите код так, чтобы он был понятен без комментариев, но если что-то требует пояснения — не стесняйтесь комментировать. diff --git a/modules/10-basics/20-comments/ru/data.yml b/modules/10-basics/20-comments/ru/data.yml index c083262..502acfc 100644 --- a/modules/10-basics/20-comments/ru/data.yml +++ b/modules/10-basics/20-comments/ru/data.yml @@ -1,5 +1,4 @@ --- - name: Комментарии tips: - > diff --git a/modules/10-basics/30-instructions/ru/README.md b/modules/10-basics/30-instructions/ru/README.md index 278c9b5..0a1ffa9 100644 --- a/modules/10-basics/30-instructions/ru/README.md +++ b/modules/10-basics/30-instructions/ru/README.md @@ -1,28 +1,50 @@ -Когда мы готовим блюдо, то четко следуем рецепту. Иначе еда окажется не такой, как ожидали. Это же правило действует и в программировании. +Когда мы готовим блюдо, то следуем рецепту шаг за шагом. Пропустим этап — и результат будет отличаться от ожидаемого. В программировании работает тот же принцип: чёткий порядок инструкций определяет, как работает программа. -Чтобы увидеть на экране ожидаемый результат, нужно дать компьютеру четкие и пошаговые указания. Это можно сделать с помощью инструкций. Инструкция — это команда для компьютера, единица выполнения. Код на Python в этом случае — это набор инструкций. Его можно представить в виде пошагового рецепта. +Инструкция (или оператор) — это команда для компьютера. Она говорит: «сделай что-то прямо сейчас». -Код на Python запускает **интерпретатор** — программу, которая выполняет инструкции строго по очереди. Как и шаги в рецепте, набор инструкций для интерпретатора пишутся по порядку и отделяются друг от друга переходом на следующую строку. +В Python программа состоит из инструкций — отдельных команд, которые выполняются компьютером. Это как пошаговый рецепт: одна строка — один шаг. -Разработчики должны понимать порядок действий в коде и уметь мысленно разделять программу на независимые части, удобные для анализа. +Интерпретатор Python (специальная программа, которая понимает и выполняет код) выполняет код сверху вниз, по строкам. Он обрабатывает каждую инструкцию по очереди, как если бы читал рецепт по шагам. -Посмотрим на пример кода с двумя инструкциями. При его запуске на экран последовательно выводятся два предложения: +Вот пример кода с двумя инструкциями: -```python -print('Mother of Dragons.') -print('Dracarys!') -# => Mother of Dragons. -# => Dracarys! +```Python +print('Mother of Dragons.') # Первая инструкция +print('Dracarys!') # Вторая инструкция ``` -https://replit.com/@hexlet/python-basics-instructions +💡 Эти строки говорят компьютеру: «Выведи фразу на экран». + +Результат выполнения: -Выше мы говорили, что инструкции отделяются друг от друга переходом на новую строку. Но есть и другой способ: их можно разделить точкой с запятой — `;`: +
+  Mother of Dragons.
+  Dracarys!
+
-```python -print('Mother of Dragons.'); print('Drakarys!') +## Порядок имеет значение + +Интерпретатор Python исполняет код в строгом порядке — как вы его написали. +Если поменять местами строки: + +```Python +print('Dracarys!') +print('Mother of Dragons.') ``` -Технической разницы между первым и вторым вариантом нет — интерпретатор поймет инструкции одинаково. Разница только в том, что человеку будет неудобно читать второй вариант. +то и на экране они поменяются: + +
+  Mother of Dragons.
+  Dracarys!
+
+ +## Альтернативная форма записи + +Обычно инструкции пишутся на отдельных строках, но Python допускает объединение нескольких инструкций в одну строку с помощью ;: + +```Python +print('Mother of Dragons.'); print('Dracarys!') +``` -Лучше инструкции располагать друг под другом. Так коллегам будет удобнее читать ваш код, обслуживать его и вносить изменения. +Обе версии работают одинаково, но второй вариант хуже читается. В реальных проектах принято писать инструкции построчно — это повышает читаемость и упрощает поддержку кода. diff --git a/modules/10-basics/30-instructions/ru/data.yml b/modules/10-basics/30-instructions/ru/data.yml index f9cd8af..7fd4690 100644 --- a/modules/10-basics/30-instructions/ru/data.yml +++ b/modules/10-basics/30-instructions/ru/data.yml @@ -1,5 +1,4 @@ --- - name: Инструкции (Statements) tips: - | diff --git a/modules/10-basics/40-testing/ru/EXERCISE.md b/modules/10-basics/40-testing/ru/EXERCISE.md index f2b2063..28ac612 100644 --- a/modules/10-basics/40-testing/ru/EXERCISE.md +++ b/modules/10-basics/40-testing/ru/EXERCISE.md @@ -1 +1 @@ -Выведите на экран `9780262531962`. +Выведите на экран `9780262531962` используя `print()`. diff --git a/modules/10-basics/40-testing/ru/README.md b/modules/10-basics/40-testing/ru/README.md index 62b47a7..5706bfc 100644 --- a/modules/10-basics/40-testing/ru/README.md +++ b/modules/10-basics/40-testing/ru/README.md @@ -1,4 +1,3 @@ - Наш сайт автоматически проверяет ваши решения. Как это работает? В самом простом случае система просто запускает ваш код и смотрит на то, что вывелось на экран. А потом сверяет с тем, что мы «ожидали» по заданию. @@ -17,10 +16,12 @@ Самое главное начинается после двоеточия: «значение "10" не равно ожидаемому значению "35"». То есть правильная функция должна была выдать 35, но текущее решение работает неправильно и выдаёт 10. -Ещё стоит отметить, что если вы видите, что в редакторе уже присутствует какой-то код, а вместе с ним комментарии `BEGIN` и `END`, то обычно это подразумевает, что вам нужно писать ваш код между этими самыми BEGIN и END! Код, данный вам заранее, трогать не стоит: это может повлиять на проверку правильности решения. Проще говоря: видите строчки с комментариями `BEGIN` и `END` — пишите свой код между ними! +Если в редакторе уже есть какой-то код, окружённый комментариями *BEGIN* и *END*, это означает, что свой код нужно писать строго между ними. Код за пределами этих комментариев менять не стоит — это может повлиять на корректность проверки. + +Проще говоря: видите *BEGIN* и *END* — пишите между ними, остальное не трогайте. ---- +## Мой ошибка или нет? Иногда в процессе решения будет казаться, что вы сделали все правильно, но система "капризничает" и не принимает решение. Подобное поведение практически исключено. Нерабочие тесты просто не могут попасть на сайт, они автоматически запускаются после каждого изменения. В подавляющем большинстве таких случаев, (а все наши проекты в сумме провели миллионы проверок за много лет), ошибка содержится в коде решения. Она может быть очень незаметной, вместо английской буквы случайно ввели русскую, вместо верхнего регистра использовали нижний или забыли вывести запятую. Другие случаи сложнее. Возможно ваше решение работает для одного набора входных данных, но не работает для другого. Поэтому всегда внимательно читайте условие задачи и вывод тестов. Там почти наверняка есть указание на ошибку. -Однако, если вы уверены в ошибке или нашли какую-то неточность, то вы всегда можете указать на нее. В конце каждой теории есть ссылка на содержимое урока на гитхабе (этот проект полностью открытый!). Перейдя туда, вы можете написать issue, посмотреть содержимое тестов (там видно, как вызывается ваш код) и даже отправить pullrequest. Если для вас это пока темный лес, то подключитесь в наше [сообщество в Telegram](https://t.me/hexletcommunity/3), там в канале *'Обратная связь'* мы всегда поможем. +Однако, если вы уверены в ошибке или нашли какую-то неточность, то вы всегда можете указать на нее в нашем [сообществе](https://ttttt.me/HexletLearningBot), там в канале _'Обратная связь'_ мы всегда поможем. diff --git a/modules/10-basics/40-testing/ru/data.yml b/modules/10-basics/40-testing/ru/data.yml index eca116f..4f1c436 100644 --- a/modules/10-basics/40-testing/ru/data.yml +++ b/modules/10-basics/40-testing/ru/data.yml @@ -1,5 +1,4 @@ --- - name: Как мы проверяем ваши решения definitions: - name: Тесты diff --git a/modules/10-basics/50-syntax-errors/ru/EXERCISE.md b/modules/10-basics/50-syntax-errors/ru/EXERCISE.md index ce6357e..ffdac86 100644 --- a/modules/10-basics/50-syntax-errors/ru/EXERCISE.md +++ b/modules/10-basics/50-syntax-errors/ru/EXERCISE.md @@ -1,4 +1,3 @@ - Это задание не связано с уроком напрямую. Но будет полезным потренироваться с выводом на экран. Выведите на экран: diff --git a/modules/10-basics/50-syntax-errors/ru/README.md b/modules/10-basics/50-syntax-errors/ru/README.md index e2fb9ea..96ea5fe 100644 --- a/modules/10-basics/50-syntax-errors/ru/README.md +++ b/modules/10-basics/50-syntax-errors/ru/README.md @@ -1,17 +1,22 @@ +Если программа на Python написана с нарушением правил, интерпретатор остановит выполнение и выведет сообщение об ошибке. В этом сообщении указывается: -Если программа на Python написана синтаксически некорректно, то интерпретатор выводит на экран соответствующее сообщение. Также он указывает на файл и строчку, где произошла ошибка. +- Тип ошибки, +- строка, в которой она произошла, +- и (часто) точка, где интерпретатор «споткнулся». -**Синтаксическая ошибка** возникает в том случае, когда код записали с нарушением грамматических правил. В естественных языках грамматика важна, но текст с ошибками обычно можно понять и прочитать. В программировании все строго. Мельчайшее нарушение — и программа даже не запустится. Примером может быть забытая `;`, неправильно расставленные скобки и другие детали. +## Что такое синтаксическая ошибка? -Вот пример кода с синтаксической ошибкой: +Синтаксическая ошибка (SyntaxError) — это нарушение грамматических правил языка программирования. Такие ошибки возникают, если код написан с отклонением от ожидаемого формата: не закрыта строка, пропущена скобка, нарушен порядок символов и т.д. + +В отличие от естественных языков, где текст с ошибками можно понять по контексту, в программировании правила строги: даже малейшее отклонение делает код неработоспособным. + +Рассмотрим простой пример: ```python print('Hodor) ``` -https://replit.com/@hexlet/python-basics-syntax-errors - -Если запустить код выше, то мы увидим следующее сообщение: +В этом коде не закрыта кавычка, и Python не может завершить строку. Попробуем запустить программу: ```bash $ python index.py @@ -21,4 +26,23 @@ File "index.py", line 1 SyntaxError: EOL while scanning string literal ``` -С одной стороны, ошибки синтаксиса — самые простые, потому что они связаны с грамматическими правилами написания кода, а не со смыслом кода. Их легко исправить: нужно лишь найти нарушение в записи. С другой стороны, интерпретатор не всегда может четко указать на это нарушение. Поэтому бывает, что забытую скобку нужно поставить не туда, куда указывает сообщение об ошибке. +Интерпретатор сообщает, что строка закончилась, но строковый литерал не завершён — EOL while scanning string literal. + +## Почему такие ошибки считаются простыми? + +Синтаксические ошибки: + +- легко заметить — код часто подсвечивается в редакторе; +- легко исправить — достаточно вернуть пропущенный символ или поправить структуру. + +Но есть и нюансы: + +🧠 Интерпретатор не всегда указывает точно то место, где допущена ошибка. +Иногда проблема находится несколькими строками выше. Например, открытая, но не закрытая скобка на одной строке может «сломать» весь следующий код. + +## Что делать при синтаксической ошибке? + +- Читай сообщение об ошибке. Оно почти всегда содержит полезную информацию. +- Проверь строку, указанную в сообщении. +- Проверь строку до неё. Иногда ошибка «спрятана» чуть раньше. +- Используй редактор с подсветкой синтаксиса — он поможет сразу заметить проблемы (например, незакрытые кавычки или скобки). diff --git a/modules/10-basics/50-syntax-errors/ru/data.yml b/modules/10-basics/50-syntax-errors/ru/data.yml index 0670141..f1321d0 100644 --- a/modules/10-basics/50-syntax-errors/ru/data.yml +++ b/modules/10-basics/50-syntax-errors/ru/data.yml @@ -1,5 +1,4 @@ --- - name: Синтаксические ошибки tips: - > diff --git a/modules/20-arithmetics/20-basic/ru/EXERCISE.md b/modules/20-arithmetics/20-basic/ru/EXERCISE.md index c6e757d..5dfef63 100644 --- a/modules/20-arithmetics/20-basic/ru/EXERCISE.md +++ b/modules/20-arithmetics/20-basic/ru/EXERCISE.md @@ -1,2 +1 @@ - Выведите на экран результат деления числа `81` на `9`. diff --git a/modules/20-arithmetics/20-basic/ru/README.md b/modules/20-arithmetics/20-basic/ru/README.md index 92944ca..33cc678 100644 --- a/modules/20-arithmetics/20-basic/ru/README.md +++ b/modules/20-arithmetics/20-basic/ru/README.md @@ -1,49 +1,81 @@ -На базовом уровне компьютеры оперируют только числами. Даже в прикладных программах на высокоуровневых языках внутри много чисел и операций над ними. Но для старта достаточно знать обычную арифметику — с нее и начнем. +На базовом уровне компьютеры работают только с числами. Даже если вы пишете сложное приложение на современном языке программирования, внутри него всегда происходят многочисленные вычисления: сложение, вычитание, деление и т.д. -Например, для сложения двух чисел в математике мы пишем: `3 + 4`. В программировании — то же самое. Вот программа, которая складывает два числа: +К счастью, чтобы начать программировать, достаточно знать обычную школьную арифметику. С неё мы и начнём. -```python +## Сложение в Python + +В математике для сложения мы пишем 3 + 4. В Python — всё точно так же: + +```Python 3 + 4 ``` -Арифметика в программировании практически не отличается от школьной арифметики. +Этот код действительно можно запустить — интерпретатор выполнит вычисление. +Но... он не сделает с результатом ничего. То есть 7 получится, но вы его не увидите. -Строчка кода `3 + 4` заставит интерпретатор сложить числа и узнать результат. Эта программа будет работать, но в ней нет смысла. По сути, мы не даем команду интерпретатору, мы просто говорим ему: «смотри, сумма трех и четырех». В реальной работе недостаточно сообщать интерпретатору о математическом выражении. +## Чтобы увидеть результат, нужно его вывести -Например, если создавать интернет-магазин, недостаточно просить интерпретатор посчитать стоимость товаров в корзине. Нужно просить посчитать стоимость **И** показать цену покупателю. +В реальной программе просто посчитать значение — недостаточно. Нужно сделать что-то с результатом, например, показать его пользователю. -Нам нужно попросить интерпретатор сложить `3 + 4` **И** дать команду сделать что-то с результатом. Например, вывести его на экран: +Для этого используем функцию `print()`: -```python -# Сначала вычисляется сумма, -# затем она передается в функцию печати +```Python print(3 + 4) ``` -После запуска на экране появится результат: +💡 Здесь сначала вычисляется сумма, затем она передаётся в функцию печати. + +Результат выполнения: + +
 7 
-
-7
-
+## 🧮 Другие арифметические операции -Кроме сложения доступны следующие операции: +Python поддерживает все привычные операции: -* `-` — вычитание -* `*` — умножение -* `**` — возведение в степень -* `/` — деление -* `//` — [целочисленное деление](https://ru.wikipedia.org/wiki/Деление_с_остатком#В_программировании) -* `%` — [остаток от деления](https://ru.wikipedia.org/wiki/Деление_с_остатком) +| Операция | Символ | Пример | Результат | +|------------------------|--------|--------------|-----------| +| Сложение | `+` | `2 + 3` | `5` | +| Вычитание | `-` | `7 - 2` | `5` | +| Умножение | `*` | `4 * 3` | `12` | +| Деление | `/` | `8 / 2` | `4.0` | +| Возведение в степень | `**` | `3 ** 2` | `9` | +| Целочисленное деление | `//` | `7 // 3` | `2` | +| Остаток от деления | `%` | `7 % 3` | `1` | -Теперь выведем на экран результат деления, а потом результат возведения в степень: +🔍 Обратите внимание: В результате деления `/` мы получаем **число с точкой** (`4.0`), даже если на вид оно целое. Мы разберёмся с этим подробнее в уроках про **типы данных**. -```python -print(8 / 2) # => 4.0 (При делении двух чисел получается тип данных float) -print(3 ** 2) # => 9 +Вот как можно вывести результат деления и возведения в степень: + +```Python +print(8 / 2) # => 4.0 +print(3 ** 2) # => 9 ``` -https://replit.com/@hexlet/python-basics-arithmetics-basics +## ℹ️ Что такое остаток от деления (`%`) + +Эта операция называется **взятие остатка от деления**. Она показывает, **что «остаётся»**, когда одно число делится на другое *не полностью*. Пример: + +```Python +print(7 % 3) # => 1 +``` + +📘 Почему результат — 1? + + - 7 делится на 3 дважды: 3 * 2 = 6 + - До 7 остаётся 1 — это и есть остаток. + +Другие примеры: + +```Python +print(10 % 4) # => 2 (10 делится на 4 дважды: 4 * 2 = 8, остаток 2) +print(15 % 5) # => 0 (делится без остатка) +``` + + +Операция % часто используется в программировании, например: -Иногда для удобства мы будем показывать в комментариях результат запуска строчек кода вот так: `=> РЕЗУЛЬТАТ`. Например, `# => 4`. + - чтобы проверить, делится ли число нацело (если остаток 0) + - чтобы выполнять циклические действия, например, поведение по чётным/нечётным индексам -Первая инструкция выведет на экран `4` (потому что 8 / 2 равно 4), а вторая инструкция выведет на экран 9 (потому что 32 равно 9). +Мы ещё неоднократно встретим % в задачах и разберём его применение на практике. diff --git a/modules/20-arithmetics/20-basic/ru/data.yml b/modules/20-arithmetics/20-basic/ru/data.yml index 00ae989..933cd4f 100644 --- a/modules/20-arithmetics/20-basic/ru/data.yml +++ b/modules/20-arithmetics/20-basic/ru/data.yml @@ -1,5 +1,4 @@ --- - name: Арифметические операции tips: - > diff --git a/modules/20-arithmetics/25-operator/ru/EXERCISE.md b/modules/20-arithmetics/25-operator/ru/EXERCISE.md index 06cfd47..003cfc9 100644 --- a/modules/20-arithmetics/25-operator/ru/EXERCISE.md +++ b/modules/20-arithmetics/25-operator/ru/EXERCISE.md @@ -1,2 +1 @@ - Напишите программу, которая посчитает разность между числами `6` и `-81` и выведет ответ на экран. diff --git a/modules/20-arithmetics/25-operator/ru/README.md b/modules/20-arithmetics/25-operator/ru/README.md index 859aff7..97eff4c 100644 --- a/modules/20-arithmetics/25-operator/ru/README.md +++ b/modules/20-arithmetics/25-operator/ru/README.md @@ -1,20 +1,40 @@ +В математике и программировании мы часто используем знаки операций, такие как `+`, `-`, `*` и другие. В программировании такие знаки называются операторами. -Знак операции, такой как `+`, называют **оператором**. Операторы выполняют операции над определенными значениями, которые называются **операндами**. Сами операторы — это обычно один или несколько символов. Реже — слово. Подавляющее большинство операторов соответствуют математическим операциям. +- Оператор — это символ или слово, которое обозначает действие. +- Операнды — это значения, к которым применяется оператор. + +Пример: ```python print(8 + 2) ``` -https://replit.com/@hexlet/python-basics-arithmetics-operators +Здесь: + +- `-` — это оператор +- `8` и `2` — это операнды +- результат — `10` + +## Бинарные операторы -В этом примере `+` — это оператор, а числа `8` и `2` — это **операнды**. +Большинство операторов в Python — бинарные, то есть они работают с двумя операндами: один слева, второй справа. Если вы напишете выражение с одним операндом, например `3 +`, то получите синтаксическую ошибку. Оператор не может работать без всех нужных данных. -Когда мы складываем, у нас есть два операнда: один слева, другой справа от знака `+`. Операции, которые требуют наличия двух операндов, называются **бинарными**. Если пропустить хотя бы один операнд, например, `3 +`, то программа завершится с синтаксической ошибкой. +## Унарные операторы -Операции бывают не только бинарными, но и унарными — с одним операндом, и тернарными — с тремя операндами. Причем операторы могут выглядеть одинаково, но обозначать разные операции. Символы `+` и `-` используются не только как операторы. Когда речь идет про отрицательные числа, то знак минуса становится частью числа: +Существуют и унарные операции — они работают с одним операндом. Пример: ```python print(-3) # => -3 ``` -Выше пример применения унарной операции к числу `3`. Оператор минус перед тройкой говорит интерпретатору взять число `3` и найти противоположное, то есть `-3`. Это может сбить с толку, потому что `-3` — это одновременно и число само по себе, и оператор с операндом. Но у языков программирования такая структура. +В этом случае `-` — унарный оператор, а `3` — операнд. Интерпретатор получает команду: «возьми число 3 и измени его знак». Важно понимать: `-3` — это не "отрицательное число как единое целое", а выражение, где `-` — оператор, а `3` — значение. + +## Ошибки при вычислениях и парсинге + +Если воспринимать `-3` как единое число, можно не заметить, что `-` — это активный оператор. Например: + +```python +print(-3**2) +``` + +Кажется, что (-3) в квадрате даст 9, но результат будет `-9`. Почему? Потому что `-3**2 = -(3**2) = -9`, а не `(-3)**2`. Понимание того, что - — это отдельная операция, помогает избежать таких ошибок. diff --git a/modules/20-arithmetics/25-operator/ru/data.yml b/modules/20-arithmetics/25-operator/ru/data.yml index 3152196..9784d4e 100644 --- a/modules/20-arithmetics/25-operator/ru/data.yml +++ b/modules/20-arithmetics/25-operator/ru/data.yml @@ -1,5 +1,4 @@ --- - name: Операторы tips: - >- diff --git a/modules/20-arithmetics/27-commutativity/ru/EXERCISE.md b/modules/20-arithmetics/27-commutativity/ru/EXERCISE.md index 2daa554..d788bb7 100644 --- a/modules/20-arithmetics/27-commutativity/ru/EXERCISE.md +++ b/modules/20-arithmetics/27-commutativity/ru/EXERCISE.md @@ -1,2 +1 @@ - Напишите программу, которая считает и выводит на экран последовательно (по одному значению в каждой строчке) значения следующих математических выражений: «3 в степени 5» и «-8 разделить на -4». diff --git a/modules/20-arithmetics/27-commutativity/ru/README.md b/modules/20-arithmetics/27-commutativity/ru/README.md index 9d67fc8..66e08df 100644 --- a/modules/20-arithmetics/27-commutativity/ru/README.md +++ b/modules/20-arithmetics/27-commutativity/ru/README.md @@ -1,3 +1,37 @@ -«От перемены мест слагаемых сумма не меняется» — это один из базовых законов арифметики, который также называется **коммутативным законом**. Бинарная операция считается коммутативной, если вы получаете тот же самый результат, поменяв местами операнды. В этом случае сложение — это коммутативная операция: `3 + 2 = 2 + 3`. +Фраза «от перемены мест слагаемых сумма не меняется» знакома каждому со школы. Этот принцип называется коммутативным законом и является одним из основных законов арифметики. -Но вычитание — это не коммутативная операция: `2 - 3 ≠ 3 - 2`. В программировании этот закон работает точно так же, как в арифметике. Более того, большинство операций, с которыми мы сталкиваемся в реальной жизни, не являются коммутативными. Отсюда вывод: всегда обращайте внимание на порядок того, с чем работаете. +## Что такое коммутативность + +Операция называется коммутативной, если порядок операндов не влияет на результат. То есть, поменяв местами значения, вы получите тот же ответ. Пример с коммутативной операцией — сложением: + +```python +print(3 + 2) # => 5 +print(2 + 3) # => 5 +``` + +Результат одинаковый — значит, операция коммутативна. + +## Некоммутативные операции + +Но не все операции обладают таким свойством. Например, вычитание — уже не коммутативная операция: + +```python +print(2 - 3) # => -1 +print(3 - 2) # => 1 +``` + +Поменяли операнды — и получили другой результат. + +## 🤖 В программировании — всё то же самое + +Коммутативность в программировании работает точно так же, как в арифметике. Python строго следует математическим правилам. + +Другие некоммутативные операции: + +- Деление: _8 / 2 ≠ 2 / 8_ +- Возведение в степень: _2 ** 3 ≠ 3 ** 2_ + +Поэтому: + +- Всегда внимательно проверяйте порядок аргументов, особенно при работе с незнакомыми операциями; +- не предполагаете коммутативность «по умолчанию» — лучше убедиться экспериментально. diff --git a/modules/20-arithmetics/27-commutativity/ru/data.yml b/modules/20-arithmetics/27-commutativity/ru/data.yml index a98be89..6f2f163 100644 --- a/modules/20-arithmetics/27-commutativity/ru/data.yml +++ b/modules/20-arithmetics/27-commutativity/ru/data.yml @@ -1,5 +1,4 @@ --- - name: Коммутативная операция tips: - > diff --git a/modules/20-arithmetics/30-composition/ru/EXERCISE.md b/modules/20-arithmetics/30-composition/ru/EXERCISE.md index a12d8c8..83f7ab1 100644 --- a/modules/20-arithmetics/30-composition/ru/EXERCISE.md +++ b/modules/20-arithmetics/30-composition/ru/EXERCISE.md @@ -1,4 +1,3 @@ - Реализуйте программу, которая вычисляет и выводит на экран значение выражения: ``` diff --git a/modules/20-arithmetics/30-composition/ru/README.md b/modules/20-arithmetics/30-composition/ru/README.md index 0c85baa..c55f8b9 100644 --- a/modules/20-arithmetics/30-composition/ru/README.md +++ b/modules/20-arithmetics/30-composition/ru/README.md @@ -1,15 +1,34 @@ +В Python (и в программировании вообще) можно объединять несколько операций в одну строку. Такие выражения интерпретатор обрабатывает шаг за шагом, по определённым правилам. + Рассмотрим пример: -```python +```Python print(2 * 4 * 5 * 10) ``` -https://replit.com/@hexlet/python-basics-arithmetics-composition +Этот код состоит из нескольких операций умножения, объединённых в одно выражение. Python умеет последовательно выполнять такие вычисления. Чтобы понять, как интерпретатор выполняет выражение, разберём его по этапам: + +- Сначала вычисляется `2 * 4`: `8 * 5 * 10` +- Затем `8 * 5`: `40 * 10` +- И наконец `40 * 10`: `400` + +Итоговый результат — `400`. + +## А если разные операции? + +Всё просто, пока используются одинаковые операторы. Но что произойдёт, если объединить, например, умножение и сложение? + +```Python +print(2 + 3 * 4) +``` + +Получится ли `20` или `14`? Ответ: `14`. -Операции можно соединять друг с другом и вычислять все более сложные составные выражения. Чтобы представить, как происходят вычисления внутри интерпретатора, разберем пример: `2 * 4 * 5 * 10`. +🔑 Почему? Потому что в Python, как и в математике, у операций есть приоритет. +Умножение выполняется раньше сложения, если не использовать скобки. Мы разберём это подробнее в следующем уроке. -1. Сначала вычисляется `2 * 4` и получается выражение `8 * 5 * 10` -2. Затем `8 * 5`. В итоге имеем `40 * 10` -3. В итоге происходит последнее умножение, и получается результат `400` +## 🧠 Что нужно запомнить -Операции могут содержать разные операторы, из-за чего появляется вопрос об их приоритете. +- Выражения могут состоять из нескольких операций. +- Python вычисляет их поэтапно — слева направо, соблюдая приоритет операций. +- Скобки можно использовать, чтобы явно указать порядок вычислений. diff --git a/modules/20-arithmetics/30-composition/ru/data.yml b/modules/20-arithmetics/30-composition/ru/data.yml index eccb04d..72350aa 100644 --- a/modules/20-arithmetics/30-composition/ru/data.yml +++ b/modules/20-arithmetics/30-composition/ru/data.yml @@ -1,5 +1,4 @@ --- - name: Композиция операций tips: [] definitions: diff --git a/modules/20-arithmetics/40-priority/ru/EXERCISE.md b/modules/20-arithmetics/40-priority/ru/EXERCISE.md index 65a9b8e..615f07d 100644 --- a/modules/20-arithmetics/40-priority/ru/EXERCISE.md +++ b/modules/20-arithmetics/40-priority/ru/EXERCISE.md @@ -1,4 +1,3 @@ - Дано вычисление `70 * 3 + 4 / 8 + 2`. Расставьте скобки так, чтобы оба сложения (`3 + 4`) и (`8 + 2`) высчитывались в первую очередь. Выведите на экран результат. diff --git a/modules/20-arithmetics/40-priority/ru/README.md b/modules/20-arithmetics/40-priority/ru/README.md index 6311a04..83727e2 100644 --- a/modules/20-arithmetics/40-priority/ru/README.md +++ b/modules/20-arithmetics/40-priority/ru/README.md @@ -1,21 +1,42 @@ -Представим, что нужно вычислить такое выражение: `2 + 2 * 2`. Именно так и запишем: +Рассмотрим простое выражение: ```python print(2 + 2 * 2) # => 6 ``` -В школьной математике есть понятие «приоритет операции». Приоритет определяет, в какой последовательности должны выполняться операции. Умножение и деление имеют больший приоритет, чем сложение и вычитание, а приоритет возведения в степень выше всех остальных арифметических операций. Например: `2 ** 3 * 2` вычислится в `16`. +Результат — 6, а не 8. Почему? В математике и программировании есть понятие приоритет операций. Он определяет порядок, в котором выполняются действия: -Но нередко вычисления должны происходить в порядке, отличном от стандартного приоритета. Тогда приоритет нужно задавать круглыми скобками. Так было и в школе, например: `(2 + 2) * 2`. Скобки можно ставить вокруг любой операции. Они могут вкладываться друг в друга сколько угодно раз. Вот примеры: +- Умножение и деление выполняются раньше сложения и вычитания. +- Возведение в степень (**) — ещё выше по приоритету. + +Например: + +```python +print(2 ** 3 * 2) # => 16, потому что сначала 2 ** 3 = 8, затем 8 * 2 = 16 +``` + +## Управление порядком действий + +Иногда нужно изменить порядок вычислений. Для этого используются круглые скобки. Они позволяют задать, какие действия нужно выполнить в первую очередь: + +```python +print((2 + 2) * 2) # => 8 +``` + +Скобки можно ставить вокруг любой части выражения и вкладывать их друг в друга: ```python print(3 ** (4 - 2)) # => 9 print(7 * 3 + (4 / 2) - (8 + (2 - 1))) # => 14 ``` -Главное при этом соблюдать парность — закрывать скобки в правильном порядке. Это часто становится причиной ошибок не только у новичков, но и у опытных программистов. Для удобства ставьте сразу открывающую и закрывающую скобку, а потом пишите внутреннюю часть. Редактор на нашем сайте (и большинство других редакторов кода) делают это автоматически: вы пишете `(`, а редактор сразу добавляет `)`. Это касается и других парных символов, например, кавычек. О них поговорим в будущих уроках. +Главное — всегда закрывайте скобки. Непарные скобки вызывают ошибки, причём не только у новичков — даже опытные программисты иногда забывают про закрывающую скобку. -Иногда выражение сложно воспринимать визуально. Тогда можно расставить скобки, не повлияв на приоритет: +> Пишите скобки сразу парой. Например, вводите () и потом заполняйте внутреннюю часть. Большинство редакторов кода (в том числе наш) автоматически добавляют закрывающую скобку, как только вы пишете открывающую. + +## Повышаем читаемость + +Иногда выражение работает правильно, но выглядит запутанно. В таких случаях скобки можно добавить просто для наглядности — они не изменят результат, но улучшат восприятие: ```python # Было @@ -25,6 +46,4 @@ print(8 / 2 + 5 - -3 / 2) # => 10.5 print(((8 / 2) + 5) - (-3 / 2)) # => 10.5 ``` -https://replit.com/@hexlet/python-basics-arithmetics-priority - -Важно запомнить: код пишется для людей. Код будут читать люди, а машины будут только исполнять его. Для машин код — корректный или некорректный. Для них нет «более» понятного или «менее» понятного кода. +Программы пишут люди, и читают их тоже люди. Компьютеру всё равно, насколько понятно написан код — главное, чтобы он был синтаксически правильным. Но для человека понятный и аккуратный код — это залог удобства, особенно при работе в команде или разборе ошибок. diff --git a/modules/20-arithmetics/40-priority/ru/data.yml b/modules/20-arithmetics/40-priority/ru/data.yml index a329aee..208b3ab 100644 --- a/modules/20-arithmetics/40-priority/ru/data.yml +++ b/modules/20-arithmetics/40-priority/ru/data.yml @@ -1,5 +1,4 @@ --- - name: Приоритет tips: [] definitions: diff --git a/modules/20-arithmetics/43-float/ru/EXERCISE.md b/modules/20-arithmetics/43-float/ru/EXERCISE.md index 6b472cb..d6140b1 100644 --- a/modules/20-arithmetics/43-float/ru/EXERCISE.md +++ b/modules/20-arithmetics/43-float/ru/EXERCISE.md @@ -1,2 +1 @@ - -Вычислите и выведите на экран произведение двух чисел: *0.39* и *0.22* +Вычислите и выведите на экран произведение двух чисел: _0.39_ и _0.22_ diff --git a/modules/20-arithmetics/43-float/ru/README.md b/modules/20-arithmetics/43-float/ru/README.md index bb0520c..86625d8 100644 --- a/modules/20-arithmetics/43-float/ru/README.md +++ b/modules/20-arithmetics/43-float/ru/README.md @@ -1,12 +1,40 @@ +В математике есть разные типы чисел. Например: -В математике существуют разные виды чисел, например, натуральные - это целые числа от одного и больше, или рациональные - это числа с точкой, например 0.5. С точки зрения устройства компьютеров, между этими видами чисел пропасть. Попробуйте ответить на простой вопрос, сколько будет *0.2 + 0.1*? А теперь посмотрим, что на это скажет Python: +- Натуральные — целые положительные числа: 1, 2, 3 и т.д. +- Рациональные — дробные числа, которые можно представить в виде деления, например: 0.5, 1.75, 3.14. -```python -0.2 + 0.1 # 0.30000000000000004 +С точки зрения математики — всё просто. Но с точки зрения компьютера между этими типами чисел — настоящая пропасть. Попробуйте мысленно решить: Сколько будет `0.2` + `0.1`? Очевидно, `0.3`. А вот что скажет Python: + +```Python +print(0.2 + 0.1) # => 0.30000000000000004 +``` + +❗Вместо привычных 0.3 мы получаем 0.30000000000000004. + +## Почему так происходит? + +Это не ошибка Python. Такое поведение можно наблюдать и в JavaScript, и в C++, и в большинстве языков программирования. + +Причина в устройстве компьютера. Компьютер работает с ограниченной памятью, а рациональные числа — бесконечно точные. Между 0.1 и 0.2 можно поместить бесконечно много других чисел. Но компьютер не может хранить бесконечность. Он приближает число, стараясь уместить его в доступное количество бит. + +Такие приближённые значения называются числами с плавающей точкой (floating point numbers). Хранение и вычисления с ними подчиняются строгим правилам. Эти правила описаны в специальном стандарте IEEE 754 — именно на него ориентируются большинство языков программирования. + +## Когда появляются такие числа + +Числа с плавающей точкой появляются в программах чаще, чем может показаться. Вот основные случаи: + +- Когда вы явно пишете дробное число — например, 0.1, 2.5, 3.14. +- Когда выполняете деление — даже если делите два целых числа: + +```Python +print(1 / 2) # => 0.5 +print(2 / 3) # => 0.6666666666666666 ``` -Операция сложения двух рациональных чисел внезапно привела к неточному вычислению результата. Тот же самый результат выдадут и другие языки программирования. Такое поведение обуславливается ограничениями вычислительных мощностей. Объём памяти, в отличие от чисел, конечен (бесконечное количество чисел требует бесконечного количества памяти для своего хранения). +Даже если результат кажется "красивым", внутри он всё равно представлен в виде приближённого значения. Некоторые дроби, такие как 1 / 3, вообще не могут быть точно представлены в двоичной системе, поэтому их точность всегда ограничена. -Рациональные числа не выстроены в непрерывную цепочку, между *0.1* и *0.2* бесконечное множество чисел. Соответственно возникает серьезная проблема, а как хранить рациональные числа? Это интересный вопрос сам по себе. В интернете множество статей, посвященных организации памяти в таких случаях. Более того, существует стандарт, в котором описано, как это делать правильно, и подавляющее число языков на него опирается. +## Что нужно запомнить -Для нас, как для разработчиков, важно понимать, что операции с плавающими числами неточны (эту точность можно регулировать), а значит при решении задач, связанных с подобными числами, необходимо прибегать к специальным трюкам, которые позволяют добиться необходимой точности. +- Операции с числами с плавающей точкой не всегда точны. Это нормально. Это не баг, а особенность архитектуры. +- Точность можно контролировать. Например, с помощью округления или сравнения чисел с заданной погрешностью. +- Будьте осторожны, если работаете с деньгами, точными измерениями или научными расчётами — в таких случаях лучше использовать специальные типы данных, которые обеспечивают контроль над точностью. diff --git a/modules/20-arithmetics/43-float/ru/data.yml b/modules/20-arithmetics/43-float/ru/data.yml index e701a9a..5886c55 100644 --- a/modules/20-arithmetics/43-float/ru/data.yml +++ b/modules/20-arithmetics/43-float/ru/data.yml @@ -1,5 +1,4 @@ --- - name: Числа с плавающей точкой tips: - > diff --git a/modules/20-arithmetics/45-linting/ru/EXERCISE.md b/modules/20-arithmetics/45-linting/ru/EXERCISE.md index 5ed000b..953edd5 100644 --- a/modules/20-arithmetics/45-linting/ru/EXERCISE.md +++ b/modules/20-arithmetics/45-linting/ru/EXERCISE.md @@ -1,2 +1 @@ - Выведите на экран результат следующего вычисления: «разница между пятью в квадрате и произведением трёх и семи». Напишите код так, чтобы каждый оператор отделялся от операндов пробелами. diff --git a/modules/20-arithmetics/45-linting/ru/README.md b/modules/20-arithmetics/45-linting/ru/README.md index 4d492e4..874484e 100644 --- a/modules/20-arithmetics/45-linting/ru/README.md +++ b/modules/20-arithmetics/45-linting/ru/README.md @@ -1,17 +1,55 @@ -Мы уже научились писать простые программы, и поэтому можно немного поговорить о том, как писать их правильно. +Вы уже умеете писать простые программы. Теперь стоит разобраться с тем, как писать код, чтобы его было легко читать и поддерживать. Это важный навык, особенно если вы работаете не в одиночку. -Код нужно оформлять определенным образом, чтобы он был понятным и простым в поддержке. Существуют специальные наборы правил, которые описывают различные аспекты написания кода — их называют **стандартами кодирования**. В Python стандарт один — [PEP8](https://peps.python.org/pep-0008/). Он отвечает практически на все вопросы о том, как оформлять ту или иную часть кода. Этот документ содержит все правила, которых нужно придерживаться. Новичкам мы советуем завести привычку заглядывать в стандарт PEP8 и писать код по нему. +Когда разные разработчики пишут в разном стиле, код становится трудночитаемым: где-то пробел лишний, где-то отступы разные, а где-то переменные называются непонятно. Чтобы избежать хаоса, программисты договорились соблюдать единый стиль кодирования. Это свод правил, которые описывают, как должен выглядеть код — от расстановки пробелов до оформления функций и названий переменных. -Сегодня не нужно помнить все правила из стандарта, потому что существуют специальные программы, которые проверяют код автоматически и сообщают о нарушениях. Такие программы называются **линтерами**. Они проверяют код на соответствие стандартам. В Python их достаточно много, и наиболее популярный из них — [flake8](https://flake8.pycqa.org/en/latest/). +Придерживаться единого стиля — значит писать код, который одинаково понятен всем членам команды, независимо от того, кто его написал. Это экономит время, снижает количество ошибок и упрощает совместную работу. -Взгляните на пример: +## Стандарты кодирования -```python +В языке Python есть официальный стиль кодирования — это документ PEP8. Он подробно описывает, как оформлять код: какие отступы использовать, как расставлять пробелы, какой длины должны быть строки, как называть переменные и многое другое. + +Этот стандарт знают и используют все Python-разработчики. Новичкам полезно время от времени заглядывать в него и вырабатывать правильные привычки с самого начала. Однако запомнить всё сразу невозможно — да и не нужно. + +## Линтеры: автоматическая проверка кода + +Запоминать все правила вручную не нужно. Существуют специальные программы, которые делают это за вас. Они называются линтеры. + +🔍 Линтер — это инструмент, который анализирует ваш код и сообщает о нарушениях стандартов. +Он помогает: + +- Избавиться от лишних пробелов +- Не забыть отступы +- Писать читаемые выражения +- И просто делать код красивее + +## Современный линтер: Ruff + +На сегодняшний день самым быстрым и популярным линтером в мире Python считается Ruff. Он объединяет в себе правила из многих других инструментов: flake8, isort, pylint, black и других. Ruff быстро работает, поддерживает современный синтаксис и активно развивается. + +Рассмотрим пример: + +```Python result = 1+ 3 ``` -Линтер будет ругаться на нарушение правила: *E225 missing whitespace around operator*. По стандарту, оператор `+` всегда должен отделяться пробелами от операндов. +Такой код выглядит неаккуратно, и линтер справедливо укажет на ошибку: + +``` +E225: missing whitespace around operator +``` + +Это значит, что перед и после + не хватает пробелов. Согласно стандарту, должно быть так: + +```Python +result = 1 + 3 +``` + +## Правила и их смысл + +Каждое сообщение линтера связано с конкретным правилом. Например, E225 касается пробелов, E302 — пустых строк перед функциями, а E501 — длины строк. Когда вы только начинаете, такие мелочи могут казаться неважными. Но со временем становится понятно, что именно они формируют единый, читаемый стиль. + +С полным списком правил Ruff можно ознакомиться в [официальной документации](https://docs.astral.sh/ruff/rules/). -Выше мы увидели правило [E225](https://pep8.readthedocs.io/en/release-1.7.x/intro.html#error-codes) — это одно из большого количества правил. Другие правила описывают отступы, названия, скобки, математические операции, длину строчек и множество иных аспектов. Каждое отдельное правило кажется неважным и мелким, но вместе они составляют основу хорошего кода. Список всех правил flake8 доступен [в этой документации](https://flake8.pycqa.org/en/latest/user/error-codes.html). +## Использование линтера в своих проектах -Вы уже знакомы с линтером, потому что в практических заданиях платформа Хекслета проверяет ваш код с помощью него. Скоро вы начнете использовать его и за пределами Хекслета, когда будете реализовывать учебные проекты. Вы настроите линтер, и он будет проверять код уже в реальной разработке и сообщать вам о нарушениях. +Когда вы начнёте писать собственные проекты за пределами учебной платформы, линтер будет незаменимым помощником. Его можно настроить в любом редакторе кода, запустить в терминале или подключить к сборке проекта. Он не только показывает ошибки, но и умеет их исправлять автоматически. diff --git a/modules/20-arithmetics/45-linting/ru/data.yml b/modules/20-arithmetics/45-linting/ru/data.yml index b3b7467..a785773 100644 --- a/modules/20-arithmetics/45-linting/ru/data.yml +++ b/modules/20-arithmetics/45-linting/ru/data.yml @@ -1,5 +1,4 @@ --- - name: Линтер tips: - | diff --git a/modules/25-strings/10-quotes/ru/EXERCISE.md b/modules/25-strings/10-quotes/ru/EXERCISE.md index b503a4f..10fbe5b 100644 --- a/modules/25-strings/10-quotes/ru/EXERCISE.md +++ b/modules/25-strings/10-quotes/ru/EXERCISE.md @@ -1,4 +1,3 @@ - Напишите программу, которая выведет на экран: ``` diff --git a/modules/25-strings/10-quotes/ru/README.md b/modules/25-strings/10-quotes/ru/README.md index bfd8b17..91df309 100644 --- a/modules/25-strings/10-quotes/ru/README.md +++ b/modules/25-strings/10-quotes/ru/README.md @@ -1,7 +1,6 @@ +В этом уроке разберёмся, что такое строка и какую роль играют кавычки в коде. -В этом уроке мы разберемся, что такое строка и какую роль в коде играют кавычки. - -Определить строку довольно просто — это некий набор символов. Представим, что у нас есть такие записи: +Строка — это просто набор символов, заключённый в кавычки. Посмотрим на примеры: ```python 'Hello' @@ -11,59 +10,79 @@ '' ``` -Какие из этих вариантов — строки? На самом деле, все пять вариантов подходят: +Все эти варианты — строки. + +- `'Hello'` и `'Goodbye'` — это строки из нескольких символов. +- `'G'` — строка из одного символа. +- `' '` — строка, состоящая из одного пробела. +- `''` — пустая строка, в ней нет ни одного символа. -* С `'Hello'` и `'Goodbye'` все очевидно — мы уже работали с подобными конструкциями и называли их строками -* `'G'` и `' '` — тоже строки, просто в них всего по одному символу -* `''` — это пустая строка, потому в ней ноль символов +То есть всё, что находится внутри кавычек, считается строкой: даже если там только пробел или вообще ничего нет. -Строкой мы считаем все, что находится внутри кавычек: даже если это пробел, один символ или вообще отсутствие символов. +## Одинарные и двойные кавычки -Выше мы записывали строки в одинарных кавычках, но это не единственный способ. Можно использовать и двойные: +В Python строки можно записывать как в одинарных, так и в двойных кавычках: ```python -print("Dracarys!") +print('Hello') +print("Hello") ``` -Теперь представьте, что вы хотите напечатать строчку *Dragon's mother*. Апостроф перед буквой **s** — это такой же символ, как одинарная кавычка. Попробуем: +Оба варианта работают одинаково. Главное — использовать один и тот же тип кавычек в начале и в конце строки. + +Хотя Python поддерживает оба варианта, по умолчанию принято использовать одинарные кавычки `'`, если внутри строки не требуется двойных. Этого стиля придерживается официальный стандарт _PEP8_ и линтер _Ruff_, который мы используем на платформе. Он может автоматически заменить двойные кавычки на одинарные там, где это возможно. + +## Проблема с кавычками внутри строки + +Представьте, что вы хотите напечатать строку _Dragon's mother_. В ней есть апостроф (_'s_) — это тот же символ, что и одинарная кавычка. Попробуем так: ```python print('Dragon's mother') # SyntaxError: invalid syntax ``` -Такая программа не будет работать. С точки зрения Python строчка началась с одинарной кавычки, а потом закончилась после слова **dragon**. Дальше были символы `s mother` без кавычек — значит, это не строка. А потом была одна открывающая строку кавычка, которая так и не закрылась: `')`. Этот код содержит синтаксическую ошибку — это видно даже по тому, как подсвечен код. - -Чтобы избежать этой ошибки, мы используем двойные кавычки. Такой вариант программы сработает верно: +Python решит, что строка заканчивается после слова 'Dragon', а остальное не распознает как валидный код — возникнет синтаксическая ошибка. Чтобы избежать этого, обернём строку в двойные кавычки: ```python print("Dragon's mother") ``` -Теперь интерпретатор знает, что строка началась с двойной кавычки и закончиться должна тоже на двойной кавычке. А одинарная кавычка внутри стала частью строки. +Теперь Python понимает, что одинарная кавычка внутри строки — это обычный символ, а сама строка начинается и заканчивается двойными кавычками. + +Если внутри строки нужны двойные кавычки, а снаружи — одинарные, проблем тоже не будет: -Верно и обратное. Если внутри строки мы хотим использовать двойные кавычки, то саму строку надо делать в одинарных. Причем количество кавычек внутри самой строки неважно. +```python +print('He said "No"') +``` -Теперь представим, что мы хотим создать такую строку: +Иногда в строке встречаются оба типа кавычек: ```python Dragon's mother said "No" ``` -В ней есть и одинарные, и двойные кавычки. Нам нужно каким-то образом указать интерпретатору, что кавычки — это один из символов внутри строки, а не начало или конец строки. - -Для этого используют **символ экранирования**: `\` — обратный слэш. Если мы поставим `\` перед кавычкой (одинарной или двойной), то интерпретатор распознает кавычку как обычный символ внутри строки, а не начало или конец строки: +В этом случае, чтобы Python не спутал кавычки внутри строки с внешними, используют символ экранирования — обратный слэш `\`. Он говорит интерпретатору: следующий за ним символ — часть строки, а не управляющий символ. ```python -# Экранируем кавычки вокруг No, чтобы интерпретатор -# распознал их как часть строки print("Dragon's mother said \"No\"") # => Dragon's mother said "No" ``` -Обратите внимание, что в примере выше нам не пришлось экранировать одинарную кавычку (апостроф 's), потому что сама строка создана с двойными кавычками. Если бы строка создавалась с одинарными кавычками, то символ экранирования нужен был бы перед апострофом, но не перед двойными кавычками. +В этом примере мы экранируем двойные кавычки внутри строки, заключённой в двойные кавычки. + +Обратите внимание: Python воспринимает `\"` как один символ — кавычку, а не два символа. +То же самое касается `\'`, `\\`, `\n` и других управляющих последовательностей — они выглядят как два символа в коде, но в строке считаются за один. + +То же самое работает и в обратном случае: + +```python +print('Dragon\'s mother said "No"') +# => Dragon's mother said "No" +``` + +## Как вывести обратный слэш -Если нужно вывести сам обратный слеш, то работает такое же правило. Как и любой другой специальный символ, его надо экранировать: +Чтобы вывести сам обратный слэш, его тоже нужно экранировать: ```python print("\\") diff --git a/modules/25-strings/10-quotes/ru/data.yml b/modules/25-strings/10-quotes/ru/data.yml index c05d541..db56e69 100644 --- a/modules/25-strings/10-quotes/ru/data.yml +++ b/modules/25-strings/10-quotes/ru/data.yml @@ -1,5 +1,4 @@ --- - name: Кавычки tips: - > diff --git a/modules/25-strings/15-escape-characters/ru/README.md b/modules/25-strings/15-escape-characters/ru/README.md index 3b77342..6374203 100644 --- a/modules/25-strings/15-escape-characters/ru/README.md +++ b/modules/25-strings/15-escape-characters/ru/README.md @@ -1,29 +1,37 @@ +Допустим, мы хотим вывести диалог: -Мы хотим показать вот такой диалог: - -``` +```bash - Are you hungry? - Aaaarrrgh! ``` -Попробуем вывести на экран строку с таким текстом: +Попробуем записать его как одну строку: ```python print("- Are you hungry?- Aaaarrrgh!") # => - Are you hungry?- Aaaarrrgh! ``` -Как видите, результат получился не такой, как мы хотели. Строки расположились друг за другом, а не одна ниже другой. Нам нужно как-то сказать интерпретатору «нажать на Enter» — сделать перевод строки после вопросительного знака. Это можно сделать с помощью символа `\n`: +Получилось не то что нужно: обе реплики слились в одну строку. Чтобы каждая из них начиналась с новой строки, нужно указать Python'у сделать перевод строки — то есть «нажать Enter». + +Для этого используется специальный управляющий символ `\n`: ```python print("- Are you hungry?\n- Aaaarrrgh!") -# => - Are you hungry? -# => - Aaaarrrgh! ``` -`\n` — это пример **экранированной последовательности** (escape sequence). Такие последовательности еще называют управляющими конструкциями. Их нельзя увидеть в том же виде, в котором их набрали. +Результат: -Набирая текст в Word, вы нажимаете на Enter в конце строчки. Редактор при этом ставит в конец строчки специальный невидимый символ, который называется LINE FEED (LF, перевод строчки). В некоторых редакторах можно даже включить отображение невидимых символов. Тогда текст будет выглядеть примерно так: +```python +- Are you hungry? +- Aaaarrrgh! +``` + +## Что такое `\n`? + +Символ `\n` — это экранированная последовательность, или управляющий символ. Он обозначает перевод строки, но не отображается напрямую. Вы не увидите `\n` в выводе программы — он влияет только на расположение текста. + +В текстовых редакторах при нажатии Enter добавляется невидимый символ — LF (Line Feed). Именно его и означает `\n`. Иногда такие символы можно увидеть, если включить отображение спецсимволов: ``` - Привет!¶ @@ -31,20 +39,23 @@ print("- Are you hungry?\n- Aaaarrrgh!") - Как дела? ``` -Устройство, которое выводит соответствующий текст, учитывает этот символ. Например, принтер при встрече с LF протаскивает бумагу вверх на одну строку, а текстовый редактор переносит весь последующий текст ниже, также на одну строку. +Принтеры, редакторы и интерпретаторы Python понимают `\n` как команду начать строку с новой строки. -Существует несколько десятков таких невидимых символов, но в программировании часто встречаются всего несколько. Кроме перевода строки, к таким символам относятся: +## Другие управляющие символы -* табуляция `\t` — разрыв, который получается при нажатии на кнопку Tab -* возврат каретки `\r` — работает только в Windows +Кроме `\n`, в Python есть и другие специальные последовательности: -Распознать такую управляющую конструкцию в тексте можно по символу `\`. Программисты часто используют перевод строки `\n`, чтобы правильно форматировать текст. Например, напишем такой код: +- `\t` — табуляция (эквивалент клавиши Tab) +- `\r` — возврат каретки (используется в Windows, но редко применяется в Python-коде) +- В программировании чаще всего используют именно \n — его достаточно для большинства задач. + +## Примеры использования `\n` ```python print("Gregor Clegane\nDunsen\nPolliver\nChiswyck") ``` -Тогда на экран выведется: +Результат: ``` Gregor Clegane @@ -53,38 +64,30 @@ Polliver Chiswyck ``` -Когда работаете с символом перевода, учитывайте следующие моменты: +Вы также можете вставлять `\n` в любую часть строки — до, после или даже использовать его отдельно: -1. Не важно, что стоит перед или после `\n`: символ или пустая строка. Перевод обнаружится и выполнится в любом случае +```python +print("First line") +print("\n") # Просто пустая строка +print("Second line") +``` -2. Строка может содержать только `\n`: +Результат: - ```python - print('Gregor Clegane') # Строка с текстом - print("\n") # Строка с невидимым символом перевода строки - print('Dunsen') # Строка с текстом - ``` +``` +First line - Программа выведет на экран: +Second line +``` - ``` - Gregor Clegane +## Важные детали +- '\n' — один символ, несмотря на то, что в коде он записан как два (\ и n). +- Если вы хотите вывести символы \n буквально (как текст), используйте двойной обратный слэш `\\n`: - Dunsen + ```python + print("Joffrey loves using \\n") + # => Joffrey loves using \n ``` -3. В коде последовательность `\n` выглядит как два символа, но с точки зрения интерпретатора — это один специальный символ - -4. Если нужно вывести `\n` как текст (два отдельных печатных символа), то можно воспользоваться экранированием — добавить еще один `\` в начале. Последовательность `\\n` отобразится как символы `\` и `n`, которые идут друг за другом: - -```python -print("Joffrey loves using \\n") -# => Joffrey loves using \n -``` - -В Windows для перевода строк по умолчанию используется `\r\n`. Такая комбинация хорошо работает только в Windows, но создает проблемы при переносе в другие системы. Например, когда в команде разработчиков есть пользователи Linux. - -Дело в том, что последовательность `\r\n` имеет разную трактовку в зависимости от выбранной кодировки, о чем мы поговорим позже. По этой причине в среде разработчиков принято всегда использовать `\n` без `\r`. - -В таком случае перевод строки всегда трактуется одинаково и отлично работает в любой системе. Не забудьте настроить ваш редактор на использование `\n`. +- На Windows по умолчанию используется комбинация \r\n, но в Python (и вообще в кроссплатформенной разработке) принято использовать только \n, чтобы избежать проблем при переносе кода между системами. diff --git a/modules/25-strings/15-escape-characters/ru/data.yml b/modules/25-strings/15-escape-characters/ru/data.yml index 60f0fa8..372e3bc 100644 --- a/modules/25-strings/15-escape-characters/ru/data.yml +++ b/modules/25-strings/15-escape-characters/ru/data.yml @@ -1,5 +1,4 @@ --- - name: Экранированные последовательности definitions: - name: Экранированная последовательность @@ -7,9 +6,6 @@ definitions: специальная комбинация символов в тексте. Например, \n — это перевод строки. tips: - - >- - Обязательно поэкспериментируйте с выводом разных строк на сайте - [https://replit.com/languages/python3](https://replit.com/languages/python3) - >- [История перевода строки](https://ru.wikipedia.org/wiki/Перевод_строки#История) diff --git a/modules/25-strings/20-string-concatenation/ru/EXERCISE.md b/modules/25-strings/20-string-concatenation/ru/EXERCISE.md index 7a956dd..881aa75 100644 --- a/modules/25-strings/20-string-concatenation/ru/EXERCISE.md +++ b/modules/25-strings/20-string-concatenation/ru/EXERCISE.md @@ -1,8 +1,6 @@ - -Выведите на экран +Выведите на экран фразу используя конкатенацию слов. ```text Winter came for the House of Frey. ``` -используя конкатенацию слов. diff --git a/modules/25-strings/20-string-concatenation/ru/README.md b/modules/25-strings/20-string-concatenation/ru/README.md index f7d63f6..9f1c0ae 100644 --- a/modules/25-strings/20-string-concatenation/ru/README.md +++ b/modules/25-strings/20-string-concatenation/ru/README.md @@ -1,32 +1,43 @@ +В программировании строки используются повсюду: в сообщениях, логах, заголовках, ошибках, интерфейсах, путях к файлам и в данных, приходящих из внешних систем. Часто строки нужно собирать из нескольких частей — например, объединить имя и фамилию, добавить единицу измерения или составить текст из шаблона. Для этого используется операция конкатенации — склеивания строк. -В веб-разработке программы постоянно оперируют строками. Все, что мы видим на сайтах, так или иначе представлено в виде текста. Этот текст чаще всего динамический — то есть он получается из разных частей, которые соединяются вместе. +## Как объединять строки -Чтобы соединить строки, нужно выполнить **конкатенацию**: +В Python строки объединяются с помощью оператора +. Несмотря на то что этот оператор используется и для сложения чисел, в случае строк он означает объединение — склеивание содержимого: -```python -# Оператор такой же, как и при сложении чисел, -# но здесь он имеет другой смысл (семантику) -print('Dragon' + 'stone') # => Dragonstone +```Python +print('Dragon' + 'stone') +# => Dragonstone ``` -Склеивание строк всегда происходит в том же порядке, в котором записаны операнды. Левый операнд становится левой частью строки, а правый — правой. Вот еще несколько примеров: +Порядок имеет значение. Сначала идёт левая часть ('Dragon'), потом правая ('stone'). Результат получается в том порядке, в котором указаны операнды. -```python -print('Kings' + 'wood') # => Kingswood -print('Kings' + 'road') # => Kingsroad -print("King's" + 'Landing') # => King'sLanding +Примеры: + +```Python +print('Kings' + 'wood') # => Kingswood +print('Kings' + 'road') # => Kingsroad +print("King's" + 'Landing') # => King'sLanding ``` -Как видите, строки можно склеивать, даже если их записали с разными кавычками. +Python позволяет объединять строки, даже если они записаны в разных кавычках — главное, чтобы обе части были строками. + +## Пробел — тоже символ -Пробел — такой же символ, как и другие, поэтому сколько пробелов поставите в строке, столько и получится в итоговой строке: +При объединении Python не вставляет пробелы автоматически. Если между частями должен быть пробел, его нужно указать вручную: -```python -# Ставим пробел в левой части +```Python +# Пробел в конце первой строки print("King's " + 'Landing') # => King's Landing -# Ставим пробел в правой части +# Пробел в начале второй строки print("King's" + ' Landing') # => King's Landing ``` -https://replit.com/@hexlet/python-basics-string-concatenation +Результат будет одинаковый. Но если пробел не добавить, то слова склеятся. + +## Заключение + +- Конкатенация — это объединение строк через + +- Склеивание происходит строго в порядке слева направо +- Пробелы не добавляются автоматически — их нужно включать в строки вручную +- Строки можно объединять независимо от типа кавычек diff --git a/modules/25-strings/20-string-concatenation/ru/data.yml b/modules/25-strings/20-string-concatenation/ru/data.yml index 2b7d96e..dd9b456 100644 --- a/modules/25-strings/20-string-concatenation/ru/data.yml +++ b/modules/25-strings/20-string-concatenation/ru/data.yml @@ -1,5 +1,4 @@ --- - name: Конкатенация tips: - > diff --git a/modules/25-strings/30-encoding/ru/EXERCISE.md b/modules/25-strings/30-encoding/ru/EXERCISE.md index 991e7de..94e7347 100644 --- a/modules/25-strings/30-encoding/ru/EXERCISE.md +++ b/modules/25-strings/30-encoding/ru/EXERCISE.md @@ -1,16 +1,40 @@ +Внутри компьютера каждый символ — это просто число. Например, A, ?, % или даже пробел — всё это закодировано числами. Такой список называется таблицей ASCII. Именно эту таблицу используют программы, чтобы превращать текст в «понятные» компьютеру числа и обратно. -В Python можно «запросить» и вывести на экран любой символ из кодировки ASCII. Для этого используется функция `chr()`. Например: +В Python есть специальная команда chr(число), которая показывает, какой символ стоит за этим числом. Например: -```python +```Python print(chr(63)) ``` -https://replit.com/@hexlet/python-basics-string-encoding +Эта команда напечатает на экран: -На экран выведется символ с номером 63 — вопросительный знак `?`. Таким способом можно выводить любой символ. +``` +? +``` + +Почему именно ?? Потому что в таблице ASCII символ вопроса ? имеет номер 63. + +Теперь задание: + +1. Перейдите в таблицу кодов ASCII +1. Найдите номера (в колонке Decimal) для следующих символов: -Воспользуйтесь [таблицей кодов ASCII](https://www.cs.cmu.edu/~pattis/15-1XX/common/handouts/ascii.html). В этой таблице нас интересует десятичный код (*dec* или *decimal*), которыми кодируются символы. + - ~ (тильда) + - ^ (крышка/каретка) + - % (знак процента) + +1. Напишите код, который по этим номерам выведет нужные символы с помощью chr(...) + +Каждый символ должен выводиться на своей строке, как в примере выше. + +## ✅ Примерный шаблон + +```Python +print(chr(...)) # какой-то символ +print(chr(...)) # ещё один +print(chr(...)) # и третий +``` -Используя пример выше и таблицу, выведите на экран (каждый на своей собственной строке) `~`, `^` и `%`. +🙃 Конечно, можно просто написать print('~'), но это не так интересно. Гораздо полезнее понять, как компьютер понимает текст, и поиграться с этим напрямую. -(Конечно, можно «обмануть» тесты и просто сделать `print('~')` и т.д., но так будет совсем неинтересно :) +Готовы? Тогда ищите нужные номера и пробуйте! diff --git a/modules/25-strings/30-encoding/ru/README.md b/modules/25-strings/30-encoding/ru/README.md index d4e4856..1a7a07c 100644 --- a/modules/25-strings/30-encoding/ru/README.md +++ b/modules/25-strings/30-encoding/ru/README.md @@ -1,37 +1,92 @@ +На самом базовом уровне компьютер работает только с нулями и единицами — это так называемый двоичный код. Каждую единицу или ноль называют битом (от binary digit — «двоичная цифра»). -На самом глубоком уровне компьютер оперирует исключительно цифрами `0` и `1`. Это так называемый [двоичный код](https://ru.wikipedia.org/wiki/Двоичный_код), а единички и нули называются битами, от "binary digit" — «двоичная цифра». +Любые данные — изображения, музыка, текст — в компьютере представлены просто как последовательность битов. -Обычные, привычные нам числа в десятичной системе исчисления, закодированы с помощью двоичных чисел: +Например, привычные нам числа из десятичной системы можно представить в двоичной форме: -- 0 ← 0 -- 1 ← 1 -- 2 ← 10 -- 3 ← 11 -- 4 ← 100 -- 5 ← 101 +- 0 → `0` +- 1 → `1` +- 2 → `10` +- 3 → `11` +- 4 → `100` +- 5 → `101` -Но как быть с текстом? Компьютер на самом деле не знает ничего о буквах, знаках пунктуации и прочих текстовых символах. Все эти символы так же закодированы числами. +## Как закодировать текст? -Можно взять английский алфавит и дать каждой букве число, начиная с единицы по порядку: +Компьютер не «понимает» текст. Чтобы работать с буквами и другими символами, их тоже нужно превратить в числа. Это делают с помощью кодировок — таблиц, в которых каждому символу соответствует определённое число. -- a ← 1 -- b ← 2 -- c ← 3 -- d ← 4 +Самый простой способ — пронумеровать буквы, начиная с 1: + +- `a` → `1` +- `b` → `2` +- `c` → `3` - ... -- z ← 26 +- `z` → `26` + +Теперь мы можем представить слово hello как набор чисел: + +``` +h e l l o +↓ ↓ ↓ ↓ ↓ +8 5 12 12 15 +``` + + +А *good* превращается в: + +``` +g o o d +↓ ↓ ↓ ↓ +7 15 15 4 +``` + +Программа не знает, что это слово. Она просто видит: «нужно отобразить символ с кодом 8, потом с кодом 5 и т.д.» + +## ASCII: первая массовая кодировка + +Первые компьютеры работали в основном с английским языком. Для него в 1960-х годах придумали таблицу ASCII — она включала 128 символов: латинский алфавит, цифры, знаки препинания, спецсимволы (@, #, !, \n) и управляющие коды. + +Этого хватало для первых программ, но не для всего мира. + +Когда компьютеры начали использовать в других странах, возникла проблема: в ASCII нет кириллицы, иероглифов, арабского письма, ударений, валютных символов и т. д. + +Каждая страна или компания начала делать свою кодировку на основе ASCII: + +- Windows придумала Windows-1251 для русского +- Apple — Mac Roman +- IBM — свои версии +- Страны Восточной Европы, Азии и Ближнего Востока — свои + +Все эти кодировки были несовместимы между собой. Код 226 в одной мог быть буквой é, в другой — и, в третьей — вообще техническим символом. Это приводило к настоящему хаосу. + +## Как выглядели проблемы с кодировками + +Если вы видите в тексте вот это: + +``` +Привет! +``` + +или + +``` +���� �������� ������ +``` + +— значит, программа неправильно определила кодировку текста. Она получила последовательность байтов, но прочитала их не той таблицей. -В этом заключается суть **кодировок**. +Это было нормой в 1990–2000-х. Одна программа писала текст в Windows-1251, другая читала его как ISO-8859-1, и в результате получался мусор. -Во время своей работы, программы используют кодировки для преобразования чисел в символы и наоборот. Причём сама программа не имеет представления о смысле этих символов. +## Unicode и UTF-8: конец бардака -- `hello` → `8` `5` `12` `12` `15` -- `7` `15` `15` `4` → `good` +Чтобы всё починить, в 1990-х начали создавать универсальную таблицу Unicode, которая содержит символы всех письменных систем мира — от латинского и кириллицы до китайского, арабского, математических знаков, древнеегипетских и даже эмодзи. -Подобные таблицы, в которых сопоставляются буквы и числа, называются кодировками. Кроме букв алфавита, в таблицы кодировок входят знаки препинания и другие полезные символы. Вы наверняка сталкивались с кодировками, например, [ASCII](https://ru.wikipedia.org/wiki/ASCII) или [UTF-8](https://ru.wikipedia.org/wiki/UTF-8). +Внутри Unicode есть несколько форматов хранения. Самый распространённый — UTF-8. Он компактно кодирует английские символы, но может расширяться под любые другие. -Разные кодировки содержат разное количество символов. Изначально небольших таблиц вроде ASCII было достаточно для большинства задач. Но в ней только латинские буквы, несколько простых символов вроде `%` и `?` и специальные управляющие символы типа перевода строки. +Сегодня UTF-8 — это стандарт по умолчанию в интернете, Python, Linux, базах данных и редакторах кода. -С распространением компьютеров, разным странам понадобились свои, более широкие таблицы. В том числе для кириллических букв, восточных иероглифов, арабской вязи, дополнительных математических и типографских символов, а впоследствии даже для эмодзи-смайликов. +## Зачем это знать программисту? -Сегодня в большинстве случаев используется один из вариантов [юникода](https://ru.wikipedia.org/wiki/Юникод), включающий в себя знаки почти всех письменных языков мира. +- Вы будете работать с текстом: ошибки кодировки по-прежнему случаются, особенно при чтении файлов, обработке данных, взаимодействии с API и базами данных. +- Python по умолчанию использует UTF-8, но иногда приходится явно указывать кодировку при чтении файлов: +- Нужно уметь диагностировать проблемы. Например, если видите «кракозябры», это почти наверняка ошибка кодировки. diff --git a/modules/25-strings/30-encoding/ru/data.yml b/modules/25-strings/30-encoding/ru/data.yml index 370e317..4064fcf 100644 --- a/modules/25-strings/30-encoding/ru/data.yml +++ b/modules/25-strings/30-encoding/ru/data.yml @@ -1,5 +1,4 @@ --- - name: Кодировка tips: - | diff --git a/modules/30-variables/10-definition/ru/EXERCISE.md b/modules/30-variables/10-definition/ru/EXERCISE.md index a112dab..751f8a7 100644 --- a/modules/30-variables/10-definition/ru/EXERCISE.md +++ b/modules/30-variables/10-definition/ru/EXERCISE.md @@ -1,2 +1 @@ - Создайте переменную с именем `motto` и содержимым `What Is Dead May Never Die!`. Распечатайте содержимое переменной. diff --git a/modules/30-variables/10-definition/ru/README.md b/modules/30-variables/10-definition/ru/README.md index 03730ed..9cdff24 100644 --- a/modules/30-variables/10-definition/ru/README.md +++ b/modules/30-variables/10-definition/ru/README.md @@ -1,31 +1,73 @@ - -Представьте, что нам нужно напечатать на экран фразу *Father!* два раза. Эту задачу можно решить так: +Представьте, что нужно напечатать фразу Father! два раза: ```python print('Father!') print('Father!') ``` -В простейшем случае так и стоит поступить. Но если фраза *Father!* будет использоваться чаще двух раз, да еще и в разных частях программы, то придется ее везде повторять — это неудобно. Проблемы с таким подходом начнутся, когда понадобится изменить фразу, а такое происходит довольно часто. Нам придется найти все места с этой фразой и выполнить необходимую замену. +Такой способ вполне подойдёт, если фраза встречается всего пару раз. Но что, если она будет использоваться часто, в разных частях программы? Тогда придётся копировать одно и то же выражение снова и снова. + +А что будет, если фразу нужно изменить — например, заменить _Father!_ на _Mother!_? Придётся искать и исправлять все вхождения вручную. Это неудобно и приводит к ошибкам. + +## Что делать вместо копирования -А можно поступить по-другому. Чтобы не копировать выражение, достаточно создать с ней переменную: +Чтобы не дублировать одну и ту же строку, её можно сохранить в переменной: ```python -# greeting - переводится как приветствие greeting = 'Father!' print(greeting) print(greeting) -# => Father! -# => Father! ``` -В строчке `greeting = 'Father!'` мы берем переменную с именем `greeting` и присваиваем ей значение `'Father!'`. Переменная указывает на данные, которые в нее записали. Благодаря этому, данные можно использовать многократно и не дублировать их постоянно. +Результат: + +```python +Father! +Father! +``` + +Мы создали переменную с именем `greeting` и записали в неё строку _Father!_. Теперь вместо текста можно использовать имя переменной. Программа подставляет значение переменной туда, где она используется. + +## Что такое переменная + +Переменная — это имя, за которым прячутся данные. Она нужна, чтобы: + +- Использовать одни и те же данные несколько раз; +- удобно обновлять значение в одном месте; +- сделать код понятнее. + +Когда интерпретатор доходит до строки `print(greeting)`, он сначала подставляет содержимое переменной, а потом выполняет вывод. + +## Имена переменных + +Имена переменных придумывает сам программист. В Python можно использовать: + +- Латинские буквы (a–z, A–Z), +- цифры (но не в начале), +- нижнее подчёркивание _. + +Примеры допустимых имён: `greeting`, `name1`, `hello_world`. + +🔠 Важно: Python различает строчные и заглавные буквы. Переменные `greeting`, `Greeting` и `GREETING` — это три разные переменные. + +### 💡 Рекомендации по именованию + +Python-разработчики придерживаются определённых соглашений по стилю — стандарта PEP8: + +- Используйте строчные буквы с подчёркиванием между словами: + + ✅ `user_name`, `error_message`, `greeting_text` + +- Имена должны быть понятными — не a или x, а name, message, counter. +- Не используйте русские слова, даже если они записаны латиницей: + + 🚫 `privet`, `mama`, `stroka` -Когда переменная создана, можно ее использовать. Она подставляется в те места, где раньше стояла наша фраза. Когда код выполняется, интерпретатор доходит до строчки `print(greeting)` и подставляет содержимое переменной, а затем выполняет код. + ✅ `greeting`, `text`, `title` -Для имени переменной используется любой набор допустимых символов, к которым относятся буквы английского алфавита, цифры и знак `_`. При этом цифру нельзя ставить в начале. Имена переменных регистрозависимы, то есть имя `hello` и имя `HELLO` — это два разных имени для двух разных переменных. Регистр в Python имеет важное значение, никогда не забывайте про него. +## Несколько переменных в программе -Количество создаваемых переменных неограниченно. Большие программы содержат десятки и сотни тысяч имен переменных. Вот как выглядят две переменные внутри одной программы: +В одной программе можно создать сколько угодно переменных. Каждая хранит свои данные и не мешает другим: ```python greeting1 = 'Father!' @@ -37,6 +79,6 @@ print(greeting2) print(greeting2) ``` -https://replit.com/@hexlet/python-basics-variables-definition +## Где создавать переменные -Чтобы программу было удобно читать, среди программистов принято создавать переменные как можно ближе к тому месту, где они используются. Теперь нужно разобраться, как их изменять. +Программисты стараются создавать переменные ближе к месту, где они используются. Это делает код более читаемым. Особенно важно это в больших программах, где переменных может быть десятки и сотни тысяч. diff --git a/modules/30-variables/10-definition/ru/data.yml b/modules/30-variables/10-definition/ru/data.yml index bde387a..783a00b 100644 --- a/modules/30-variables/10-definition/ru/data.yml +++ b/modules/30-variables/10-definition/ru/data.yml @@ -1,10 +1,9 @@ --- - name: Что такое переменная tips: - > [Именование в - программировании](https://ru.hexlet.io/blog/posts/naming-in-programming) + программировании](https://ru.hexlet.io/blog/posts/naming-in-programming?utm_source=code-basics&utm_medium=referral&utm_campaign=blog&utm_content=lesson) definitions: - name: Переменная description: >- diff --git a/modules/30-variables/12-change/ru/EXERCISE.md b/modules/30-variables/12-change/ru/EXERCISE.md index cd8aa89..b47c8b2 100644 --- a/modules/30-variables/12-change/ru/EXERCISE.md +++ b/modules/30-variables/12-change/ru/EXERCISE.md @@ -1,4 +1,3 @@ - В упражнении определена переменная, внутри которой содержится строка. Переопределите значение этой переменной и присвойте ей строку, в которой расположите символы первоначальной строки в обратном порядке. -Обратите внимание: в данном задании вам предстоит писать код между строчками с комментариями `# BEGIN` и `# END` (об этом говорилось ранее, но это первый раз, когда вы встречаетесь с таким форматом). +Обратите внимание: в данном задании вам предстоит писать код между строчками с комментариями `# BEGIN` и `# END` diff --git a/modules/30-variables/12-change/ru/README.md b/modules/30-variables/12-change/ru/README.md index d0dec8e..d6024a8 100644 --- a/modules/30-variables/12-change/ru/README.md +++ b/modules/30-variables/12-change/ru/README.md @@ -1,10 +1,9 @@ +Само слово «переменная» подсказывает, что её значение может меняться. Это одна из главных причин, почему переменные вообще существуют. -Само слово «переменная» подсказывает, что ее можно менять. И действительно, со временем внутри программы значения переменных могут изменяться. - -Например: +Вот простой пример: ```python -# greeting - переводится как приветствие +# greeting — переводится как приветствие greeting = 'Father!' print(greeting) # => Father! @@ -12,8 +11,46 @@ greeting = 'Mother!' print(greeting) # => Mother! ``` -https://replit.com/@hexlet/python-basics-variables-change +Здесь мы сначала записали в переменную одну строку (_Father!_), потом — другую (_Mother!_). Имя переменной не изменилось, но значение внутри стало другим. + +## Зачем вообще менять значение? + +В реальных программах переменные меняются постоянно. Вот несколько причин: + +- Программа реагирует на действия пользователя. Например, пока вы вводите какие-то данные, в формы на сайте, они, в этот момент, вполне вероятно, постоянно меняют переменные, которые эти данные содержат +- Промежуточные результаты. Часто данные проходят через серию преобразований — на каждом этапе переменная обновляется новым значением. Подобный механизм даже есть в калькуляторах, когда промежуточные значения сохраняются с помощью клавиш `m+` или `m-`. +- Хранение состояния. Если вы пишете игру, то положение персонажа, его здоровье, счёт, текущий уровень — всё это переменные, которые постоянно меняются. + +## Переменные создаются по мере использования + +В Python переменную не нужно «объявлять заранее» — она появляется в момент, когда вы впервые записываете в неё значение: + +```python +name = 'Arya' # переменная создаётся здесь +``` + +Если потом вы снова напишете name = ..., это перезапишет старое значение. Так работает большинство современных языков программирования. + +⚠️ Но важно помнить: переменную нельзя использовать раньше, чем она создана. + +```python +print(name) # Ошибка! Переменная ещё не создана +name = 'Arya' +``` + +Python не знает, что такое name, потому что вы ещё ничего туда не записали. При запуске программа остановится и покажет сообщение об ошибке. + +✅ Правильный порядок: + +```python +name = 'Arya' # Сначала создаём +print(name) # Потом используем +``` + +## Почему это важно + +Переменные — это гибкий способ хранить данные, которые могут изменяться в процессе выполнения программы. Благодаря этому можно писать программы, которые ведут себя по-разному в зависимости от условий, действий пользователя или результатов вычислений. -Имя осталось тем же, но внутри появились другие данные. Отметим, что переменные в Python не требуют специального объявления. Вместо этого переменная объявляется, когда ее впервые используют в программе. +Но у гибкости есть и обратная сторона. Иногда сложно сразу понять, что именно записано в переменную в тот или иной момент времени. Разработчику приходится отслеживать, где и как она изменилась — особенно если код длинный. -Переменные — мощная и в то же время рисковая вещь. Нельзя сразу с уверенностью сказать, что внутри нее записано — сначала надо проанализировать код, который находится перед переменной. Именно этим занимаются разработчики во время отладки, когда пытаются разобраться, почему программа работает не так, как задумано. +Именно это делают во время отладки — когда пытаются разобраться, почему программа работает не так, как задумано. Проверяют значения переменных, отслеживают порядок выполнения кода, ищут, где что-то пошло не так. diff --git a/modules/30-variables/12-change/ru/data.yml b/modules/30-variables/12-change/ru/data.yml index 4db0909..15da5a7 100644 --- a/modules/30-variables/12-change/ru/data.yml +++ b/modules/30-variables/12-change/ru/data.yml @@ -1,5 +1,4 @@ --- - name: Изменение переменной tips: [] definitions: diff --git a/modules/30-variables/13-variables-naming/ru/README.md b/modules/30-variables/13-variables-naming/ru/README.md index 09b616e..c55522c 100644 --- a/modules/30-variables/13-variables-naming/ru/README.md +++ b/modules/30-variables/13-variables-naming/ru/README.md @@ -1,23 +1,40 @@ - -Представьте, что мы задали следующую программу: +Представьте, что у нас есть такая программа: ```python x = 'Father!' print(x) ``` -С подобной программой мы уже работали, но сейчас в ней изменилось имя переменной на `x`. +С технической точки зрения — всё работает. Мы уже видели похожие примеры, но здесь используется переменная с названием `x`. Плохие имена мешают читать и понимать код. Вот несколько примеров неудачных переменных: + +```python +a = "John" +n = 42 +ddr = "New York" +``` + +Что это за переменные? Что в них хранится? Чтобы это понять, нужно читать весь остальной код и догадываться по контексту. -Компьютеру без разницы, как мы именуем ту или иную переменную. Названия важны только людям. Обычно программисты гораздо чаще читают чужой код, чем пишут свой. Чтобы коллеги смогли с легкостью прочитать и проанализировать ваш код, нужно понятно называть переменные. +Компьютеру всё равно, как называется переменная. Для него `x`, `abc`, `message` или `elephant_in_the_room` — просто метки для хранения данных. Но людям — не всё равно. Программисты читают код гораздо чаще, чем пишут. Поэтому имена переменных — это не просто мелочь, а важная часть общения через код. + +## ✅ Хорошие примеры + +```python +user_name = "Arya Stark" +unpaid_orders_count = 3 +max_attempts = 5 +email_verified = False +``` -Важно придумать понятное название, которое отражает смысл переменной. При этом важно давать такие имена, которые будут понимать без контекста, без изучения окружающего кода. +Хорошее имя переменной помогает понять, что делает программа, не вчитываясь в каждую строчку. +Особенно важно давать такие имена, смысл которых понятен без контекста — без необходимости читать весь код вокруг. -Существует общепринятое правило: не используйте транслит для имен — только английский язык. Если вы испытываете сложности с английским, то пользуйтесь переводчиком. Со временем, копаясь в чужом коде, вы научитесь правильно именовать переменные. +Вот несколько советов: -Среди разработчиков есть шутка: «Названия переменных — это одна из самых сложных вещей в программировании». Придумывать названия и правда сложно. Например, сложно назвать переменную, в которой хранится _количество неоплаченных заказов от клиентов с задолженностью в предыдущем квартале._ +- Используйте английский язык. Это международный стандарт. Не стоит писать `kolvo_zakazov` — лучше `orders_count`. Если с английским пока сложно — используйте переводчик, это нормально. Со временем станет проще. +- Старайтесь, чтобы имя отражало смысл переменной. Пусть оно будет чуть длиннее, но понятное. +- Не бойтесь тратить время на подбор хорошего названия. Это инвестиция в читаемость и поддержку кода. -Чтобы проверить себя, попробуйте сделать такое задание: +Среди программистов даже есть шутка: «Одни из самых трудных задач в программировании — это кэширование и придумывание имён переменным.» Иногда придумать имя — действительно сложно. Вот пример: как бы вы назвали переменную, в которой хранится количество неоплаченных заказов от клиентов с задолженностью за предыдущий квартал? -> Придумайте название для переменной, в которой будет храниться *«количество братьев и сестер короля»*. -> -> Запишите его в блокноте или отправьте себе на почту. Не указывайте там ничего, кроме названия переменной. А через несколько уроков мы вернемся к этой теме. +А теперь — небольшое упражнение: Придумайте название для переменной, в которой будет храниться «количество братьев и сестер короля». Запишите его в блокноте или отправьте себе на почту. Только название, без объяснений. Мы вернемся к этому заданию через несколько уроков. diff --git a/modules/30-variables/13-variables-naming/ru/data.yml b/modules/30-variables/13-variables-naming/ru/data.yml index a9a55ff..b19c1c4 100644 --- a/modules/30-variables/13-variables-naming/ru/data.yml +++ b/modules/30-variables/13-variables-naming/ru/data.yml @@ -1,13 +1,12 @@ --- - name: Выбор имени переменной tips: - > [Именование в - программировании](https://ru.hexlet.io/blog/posts/naming-in-programming) + программировании](https://ru.hexlet.io/blog/posts/naming-in-programming?utm_source=code-basics&utm_medium=referral&utm_campaign=blog&utm_content=lesson) - > [Ошибки в именовании - переменных](https://ru.hexlet.io/blog/posts/naming-errors-1) + переменных](https://ru.hexlet.io/blog/posts/naming-errors-1?utm_source=code-basics&utm_medium=referral&utm_campaign=blog&utm_content=lesson) definitions: - name: Переменная description: >- diff --git a/modules/30-variables/14-errors/ru/EXERCISE.md b/modules/30-variables/14-errors/ru/EXERCISE.md index 3b94393..ceacef9 100644 --- a/modules/30-variables/14-errors/ru/EXERCISE.md +++ b/modules/30-variables/14-errors/ru/EXERCISE.md @@ -1,5 +1,4 @@ - -Найдите в программе необъявленную переменную и объявите ее, присвоив ей значение 'Dragon'. +Найдите в программе необъявленную переменную и объявите ее, присвоив ей значение _Dragon_. После выполнения программы результат на экране должен выглядеть так: diff --git a/modules/30-variables/14-errors/ru/data.yml b/modules/30-variables/14-errors/ru/data.yml index 7c32031..fee8b6e 100644 --- a/modules/30-variables/14-errors/ru/data.yml +++ b/modules/30-variables/14-errors/ru/data.yml @@ -1,5 +1,4 @@ --- - name: Ошибки при работе с переменными tips: - > diff --git a/modules/30-variables/15-variables-expressions/ru/EXERCISE.md b/modules/30-variables/15-variables-expressions/ru/EXERCISE.md index be35154..be9259d 100644 --- a/modules/30-variables/15-variables-expressions/ru/EXERCISE.md +++ b/modules/30-variables/15-variables-expressions/ru/EXERCISE.md @@ -1,11 +1,10 @@ - Напишите программу, которая берет исходное количество евро, записанное в переменную `euros_count`, переводит евро в доллары и выводит на экран. Затем полученное значение переводит в юани и выводит на новой строчке. Пример вывода для 100 евро: ``` 125.0 -7500.0 +863.75 ``` Считаем, что: diff --git a/modules/30-variables/15-variables-expressions/ru/README.md b/modules/30-variables/15-variables-expressions/ru/README.md index bb8c02d..b03ccb4 100644 --- a/modules/30-variables/15-variables-expressions/ru/README.md +++ b/modules/30-variables/15-variables-expressions/ru/README.md @@ -1,20 +1,38 @@ +Мы уже знаем, что переменные позволяют хранить и переиспользовать данные. Но они также помогают упрощать вычисления — как математические, так и строковые. Рассмотрим это на примерах. -Мы уже разобрались, как работать с переменными, чтобы хранить и переиспользовать информацию. Но еще они помогают упрощать сложные вычисления. Например, конвертация валюты или составление нового слова. Рассмотрим, как это делать на практике. +## 💱 Конвертация валют через промежуточную валюту -Представим, что нам нужно перевести евро в юани через доллары. Подобные конвертации через промежуточную валюту часто делают банки при покупках за рубежом. +Представим, что нужно перевести евро в юани, но напрямую такой курс нам недоступен. Тогда сделаем это в два шага: **евро → доллары → юани**. Так часто работают банки при оплате покупок за рубежом. -Для начала переведем 50 евро в доллары. Допустим, что один евро — 1.25 долларов: +## Шаг 1. Евро → Доллары + +Допустим, курс: 1 евро = 1.25 доллара. Хотим перевести 50 евро: ```python dollars_count = 50 * 1.25 print(dollars_count) # => 62.5 ``` -Здесь в переменную `dollars_count = 50 * 1.25` справа от знака «равно» мы записываем **выражение**. Интерпретатор вычислит результат (`62.5`) и запишет его в переменную. Интерпретатору не важно, в каком виде записаны данные: `62.5` или `50 * 1.25`. Для него оба варианта — выражения, которые надо вычислить. Он проводит вычисления и приходит к одному и тому же значению — `62.5`. +В этой строке 50 \* 1.25 — это выражение, а dollars_count — переменная, в которую записывается результат. Python сначала вычисляет выражение, а уже потом сохраняет результат в переменную. + +Интерпретатору всё равно, как записано выражение: + +```python +dollars_count = 62.5 +``` + +или + +```python +dollars_count = 50 * 1.25 +``` + +Результат будет один и тот же. -Любая строка — выражение. Конкатенация строк (склеивание значений переменных) — это тоже выражение. Когда интерпретатор видит выражение, он обрабатывает его и генерирует результат — **значение выражения**. +## 📘 Что такое выражение? -Вот несколько примеров выражения. В комментариях справа от каждого выражения записаны итоговые значения: +Выражение — это комбинация данных и операций, из которой можно получить значение. +Примеры: ```python 62.5 # 62.5 @@ -26,42 +44,37 @@ int('100') # 100 'Good' + 'will' # Goodwill ``` -В тех местах, где ожидается выражение, можно поставить любое вычисление. Оно может быть не только математическим, но и строковым — как конкатенация. Программа все равно останется работоспособной. +Обратите внимание: строки — это тоже выражения. А операция + со строками называется конкатенацией — она "склеивает" строки в одну. -Программы состоят из множества комбинаций выражений. Основываясь на сказанном выше, подумайте, сработает ли такой код: +Если вы понимаете, что перед вами выражение, вы знаете: Python сначала его вычислит, а уже потом продолжит выполнение программы. Это особенно важно, когда выражения становятся сложными и включают переменные, функции и даже другие выражения внутри. + +## ✨ Пример со строками + +Подумайте, сработает ли такой код: ```python who = "dragon's " + 'mother' print(who) ``` -Такой код выведет на экран строку `dragon's mother`. Если хотите проверить самостоятельно, запустите код на [repl.it](https://replit.com/languages/python3) и поэкспериментируйте. - -С помощью переменных можно записывать еще более сложные вычисления. Вернемся к нашей валютной программе. Запишем стоимость доллара в юанях, как отдельную переменную. Вычислим цену 50 евро в долларах, умножив их на `1.25`. Допустим, что 1 доллар — 6.91 юаней: - -```python -yuans_per_dollar = 6.91 -dollars_count = 50 * 1.25 # 62.5 -yuans_count = dollars_count * yuans_per_dollar # 431.875 +Ответ: да, всё отлично сработает. На экран выведется строка: _dragon's mother_ -print(yuans_count) -``` +## Шаг 2. Доллары → Юани -Теперь добавим к выводу текст с помощью конкатенации: +Теперь переведем доллары в юани. Допустим, курс: 1 доллар = 6.91 юаней. ```python yuans_per_dollar = 6.91 -dollars_count = 50 * 1.25 # 62.5 +dollars_count = 50 * 1.25 # 62.5 yuans_count = dollars_count * yuans_per_dollar # 431.875 -# Функция str() превращает число в строку. -# О таких превращениях будет отдельный урок. -print('The price is ' + str(yuans_count) + ' yuans') -# => The price is 431.875 yuans +print(yuans_count) ``` -Любая переменная может быть частью любого выражения. В момент вычисления вместо имени переменной подставляется ее значение. +Переменные можно использовать внутри других выражений. Когда Python видит переменную, он подставляет её значение, а затем выполняет вычисления. -Интерпретатор вычисляет значение `dollars_count` до того, как эта переменная начнет использоваться в других выражениях. Когда подходит момент использования переменной, Python уже знает значение, потому что вычислил его. +## 📌 Что нужно запомнить -С помощью переменных можно проводить сложные вычисления, а также делать подробный вывод с получившимся значением. Но еще можно получать новые выражения посредством склеивания двух и более значений переменных. За это отвечает конкатенация. +- Выражения могут быть числовыми, строковыми и даже смешанными (если правильно использовать преобразования). +- Переменные можно использовать внутри других выражений. Python подставит их значения и выполнит нужные вычисления. +- Все программы состоят из комбинаций выражений — именно они дают результат. diff --git a/modules/30-variables/15-variables-expressions/ru/data.yml b/modules/30-variables/15-variables-expressions/ru/data.yml index 783ed1d..416a682 100644 --- a/modules/30-variables/15-variables-expressions/ru/data.yml +++ b/modules/30-variables/15-variables-expressions/ru/data.yml @@ -1,5 +1,4 @@ --- - name: Выражения в определениях tips: - | diff --git a/modules/30-variables/18-variable-concatenation/ru/EXERCISE.md b/modules/30-variables/18-variable-concatenation/ru/EXERCISE.md index 0397907..344900e 100644 --- a/modules/30-variables/18-variable-concatenation/ru/EXERCISE.md +++ b/modules/30-variables/18-variable-concatenation/ru/EXERCISE.md @@ -1,4 +1,3 @@ - Сайты постоянно посылают письма своим пользователям. Типичная задача — сделать автоматическую отправку персонального письма, где в заголовке будет имя пользователя. Если где-то в базе сайта хранится имя человека в виде строки, то задача генерации заголовка сводится к конкатенации: например, нужно склеить строку `Здравствуйте` со строкой, где записано имя. Напишите программу, которая будет генерировать заголовок и тело письма, используя уже готовые переменные, и выводить получившиеся строки на экран. diff --git a/modules/30-variables/18-variable-concatenation/ru/README.md b/modules/30-variables/18-variable-concatenation/ru/README.md index 25ce64e..6deafa0 100644 --- a/modules/30-variables/18-variable-concatenation/ru/README.md +++ b/modules/30-variables/18-variable-concatenation/ru/README.md @@ -1,30 +1,65 @@ +Ранее мы уже склеивали строки напрямую. Теперь попробуем использовать переменные при конкатенации. Хорошая новость: синтаксис остаётся тем же. Просто подставляются значения переменных. -Попробуем использовать переменные с конкатенацией, при этом синтаксически ничего не поменяется. Мы умеем конкатенировать две строки: +## 🧪 Склеиваем две строки напрямую ```python what = "Kings" + "road" print(what) # => Kingsroad ``` -Значит, мы сумеем склеить строку и одну переменную, в которой записана строка: +Здесь всё просто: две строки соединяются в одну. Так работает конкатенация — оператор + складывает строки, создавая новую строку. + +## 🧩 Склеиваем строку и переменную + +Если в переменной first лежит строка "Kings", мы можем спокойно склеить её с другой строкой: ```python first = "Kings" what = first + "road" - print(what) # => Kingsroad ``` -А еще можно конкатенировать две переменные, в которых записаны строки: +Python подставит значение переменной, выполнит операцию и создаст итоговую строку. + +## 🧱 Склеиваем две переменные + +Точно так же можно объединить значения двух переменных, если обе содержат строки: ```python first = "Kings" -last = 'road' - +last = "road" what = first + last print(what) # => Kingsroad ``` -https://replit.com/@hexlet/python-basics-variables-concatenation +Можно добавлять и пробелы: + +```python +full = first + " " + last +print(full) # => Kings road +``` + +## ⚠️ А что если переменная — число? + +Попробуем так: + +```python +age = 42 +# print("Age: " + age) # ❌ Ошибка! +``` + +Программа выдаст ошибку: нельзя складывать строку и число. Чтобы склеить строку с числом, нужно преобразовать число в строку: + +```python +age = 42 +print("Age: " + str(age)) # ✅ Age: 42 +``` + +То же самое касается переменных с результатами вычислений: + +```python +price = 50 * 1.25 * 6.91 # => 431.875 +print("Price in yuans: " + str(price)) # ✅ +``` -Переменные — важный инструмент в программировании. Они упрощают сложные вычисления и таким образом облегчают разработку. Но чтобы успешно работать с переменными, надо не только правильно использовать их, но и правильно называть. Об этом поговорим уже в следующем уроке. +Функция `str()` превращает любое значение (число, результат вычисления, булево и т.д.) в строку. Подробнее про функции мы поговорим в будущих уроках. diff --git a/modules/30-variables/18-variable-concatenation/ru/data.yml b/modules/30-variables/18-variable-concatenation/ru/data.yml index 73a6e6a..70a2fc0 100644 --- a/modules/30-variables/18-variable-concatenation/ru/data.yml +++ b/modules/30-variables/18-variable-concatenation/ru/data.yml @@ -1,5 +1,4 @@ --- - name: Переменные и конкатенация tips: - > diff --git a/modules/30-variables/19-naming-style/ru/EXERCISE.md b/modules/30-variables/19-naming-style/ru/EXERCISE.md index a7f94e3..4b5b244 100644 --- a/modules/30-variables/19-naming-style/ru/EXERCISE.md +++ b/modules/30-variables/19-naming-style/ru/EXERCISE.md @@ -1,4 +1,3 @@ - Создайте две переменные с именами «первое число» и «второе число» на английском языке используя snake_case. Запишите в первую переменную число `20`, во вторую — `-100`. Выведите на экран произведение чисел, записанных в получившиеся переменные. Код будет работать с любыми названиями, а наша система всегда проверяет только результат на экране, поэтому выполнение этого задания — под вашу ответственность. diff --git a/modules/30-variables/19-naming-style/ru/README.md b/modules/30-variables/19-naming-style/ru/README.md index ea0b670..562a24c 100644 --- a/modules/30-variables/19-naming-style/ru/README.md +++ b/modules/30-variables/19-naming-style/ru/README.md @@ -1,14 +1,34 @@ +`greeting` — пример простого и понятного имени переменной. Но часто имён вроде `name`, `email` или `price` оказывается недостаточно. Например, нужно описать имя пользователя, общее количество заказов, максимальную длину сообщения — такие имена уже состоят из нескольких слов. -`greeting` — пример простого имени, но не все имена так просты. Часто они включают в себя несколько слов: например, «имя пользователя». В разных языках применяются разные стили кодирования, и имя переменной будет отличаться. +В разных языках программирования используются разные стили именования. От этого зависит, как будет выглядеть имя переменной из нескольких слов. -В именовании переменных можно выделить три основных подхода, которые иногда комбинируют друг с другом. Все эти подходы проявляют себя, когда имя переменной состоит из нескольких слов: +## ✍️ Основные стили -* **kebab-case** — составные части переменной разделяются дефисом (`my-super-var`) -* **snake\_case** — для разделения используется подчеркивание (`my_super_var`) -* **CamelCase** — каждое слово в переменной пишется с заглавной буквы (`MySuperVar`) +Вот три популярных подхода к написанию составных имён: -Переменные в Python именуются в стиле `snake_case`: слова записываются строчными буквами и разделяются символом подчеркивания `_`. Чтобы разобраться подробнее, можете изучить раздел [«Как называть переменные»](https://peps.python.org/pep-0008/#naming-conventions) в стандарте PEP8. +- kebab-case — слова разделяются дефисом: my-super-var -На [Хекслете](https://ru.hexlet.io/) мы начинаем работать с линтерами почти с самого начала. + ❌ В Python не работает — дефис (-) воспринимается как оператор вычитания. -Далее посмотрим пример плохих практик и разберем, почему их стоит избегать. +- snake_case — слова разделяются подчёркиванием: my_super_var + + ✅ Это стандарт для Python. + +- CamelCase (или UpperCamelCase) — каждое слово с заглавной буквы, без разделителей: MySuperVar + + Обычно используется для имён классов, но не переменных. + +## Как правильно в Python + +```Python +user_name = "Daenerys" +max_length = 280 +total_orders = 17 +``` + +- Все буквы строчные +- Слова разделяются символом подчёркивания + +## 🛠 Линтеры и стиль кода + +На Хекслете мы учим использовать линтеры — инструменты, которые автоматически проверяют стиль кода и подсказывают, если что-то не соответствует стандарту. Это помогает с самого начала привыкать к хорошим практикам. diff --git a/modules/30-variables/19-naming-style/ru/data.yml b/modules/30-variables/19-naming-style/ru/data.yml index be25d5e..e6f5e00 100644 --- a/modules/30-variables/19-naming-style/ru/data.yml +++ b/modules/30-variables/19-naming-style/ru/data.yml @@ -1,5 +1,4 @@ --- - name: Именование переменных tips: - | diff --git a/modules/30-variables/20-magic-numbers/index.py b/modules/30-variables/20-magic-numbers/index.py index 3f9be33..cf8d8b5 100644 --- a/modules/30-variables/20-magic-numbers/index.py +++ b/modules/30-variables/20-magic-numbers/index.py @@ -1,4 +1,4 @@ -king = "Rooms in King Balon's Castle:" +king = "Rooms in King Balon's Castles:" # BEGIN number_of_castles = 6 diff --git a/modules/30-variables/20-magic-numbers/ru/EXERCISE.md b/modules/30-variables/20-magic-numbers/ru/EXERCISE.md index f9c47d4..3a5930e 100644 --- a/modules/30-variables/20-magic-numbers/ru/EXERCISE.md +++ b/modules/30-variables/20-magic-numbers/ru/EXERCISE.md @@ -1,8 +1,7 @@ - Вы столкнулись с таким кодом, который выводит на экран общее количество комнат во владении нынешнего короля: ```python -king = "Rooms in King Balon's Castle:" +king = "Rooms in King Balon's Castles:" print(king) print(6 * 17) ``` @@ -16,7 +15,7 @@ print(6 * 17) Получится так:
-Rooms in King Balon's Castle:
+Rooms in King Balon's Castles:
 102
 
diff --git a/modules/30-variables/20-magic-numbers/ru/README.md b/modules/30-variables/20-magic-numbers/ru/README.md index 352466c..00eecac 100644 --- a/modules/30-variables/20-magic-numbers/ru/README.md +++ b/modules/30-variables/20-magic-numbers/ru/README.md @@ -1,5 +1,4 @@ - -Возьмем пример программы, которая считает курс валют: +Рассмотрим пример программы, которая выполняет конвертацию валют: ```python euros_count = 1000 @@ -9,33 +8,39 @@ rubles_count = dollars_count * 60 # 75000.0 print(rubles_count) ``` -С точки зрения профессиональной разработки, такой код не соответствует «лучшим практикам» — best practices. +С технической точки зрения — всё работает. Но с точки зрения профессиональной разработки такой код считается плохой практикой. + +## 🤨 В чём проблема? + +В выражениях использованы непонятные числа: __1.25__ и __60__. Что это за значения? Курс валют? Откуда они взялись? Через месяц или год вы, скорее всего, не вспомните, что именно означают эти числа. А если код откроет другой разработчик, он просто не поймёт, откуда всё берётся. -В этом примере сложно понять, что значат числа `60` и `1.25`. Представьте, что вам придется разбираться в этом коде через месяц или через год — это будет сложно. Также сложно будет программисту, который не видел код ранее. +## 🔍 Такие значения называют «магическими числами» -В нашем примере контекст легко восстановить, потому что переменные названы грамотно. Но в реальных проектах код значительно сложнее, поэтому догадаться до смысла чисел зачастую невозможно. +Магические числа (magic numbers) — это числовые значения, смысл которых не ясен из кода. Чтобы понять их назначение, приходится вникать в контекст или читать дополнительную документацию. Магические числа затрудняют чтение, понимание и поддержку кода. -Проблема кроется в «магических числах» — magic numbers. Это числа, происхождение которых невозможно понять с первого взгляда — приходится глубоко вникать в то, что происходит в коде. +## ✅ Как избежать магии -Чтобы предотвратить проблему, нужно создавать переменные с правильными именами. Так все встанет на свои места: +Самый простой способ — вынести такие значения в переменные с понятными именами. Тогда смысл станет очевиден: ```python dollars_per_euro = 1.25 rubles_per_dollar = 60 euros_count = 1000 -dollars_count = euros_count * dollars_per_euro # 1250.0 -rubles_count = dollars_count * rubles_per_dollar # 75000.0 +dollars_count = euros_count * dollars_per_euro # 1250.0 +rubles_count = dollars_count * rubles_per_dollar # 75000.0 print(rubles_count) ``` -В этой программе: +## 📌 Что изменилось? -* Используется именование snake_case -* Две новые переменные отделяются от последующих вычислений пустой строчкой. Эти переменные имеют смысл и без вычислений, поэтому такое отделение уместно, потому что повышает читаемость -* Получился хорошо именованный и структурированный код, но он длиннее прошлой версии. Так часто бывает — это нормально, ведь код должен быть читабельным +- Значения вынесены в отдельные переменные с осмысленными именами. +- Используется snake_case — стандарт стиля в Python. +- Отделили данные от логики: сначала определили курсы, потом сделали вычисления. +- Добавили пустую строку между «исходными данными» и вычислениями — это повышает читаемость. +- Программа стала немного длиннее, но понятнее. И это — норма. -Магические числа и непонятные именования переменных не ломают код, но делают его менее читабельным. +💬 Вывод -Нужно понимать, что компьютер в любом случае выполнит заданное вычисление. Однако другой программист будет читать код и ничего не поймет — это усложнит работу. Правильное именование переменных — половина успеха анализа кода. +Магические числа делают код непонятным и трудным для поддержки. Чтобы избежать этой проблемы, нужно заменять такие числа переменными с осмысленными именами. Это делает код более читаемым, особенно в долгосрочной перспективе. Не стоит бояться того, что программа станет чуть длиннее — понятный код всегда важнее компактности. diff --git a/modules/30-variables/20-magic-numbers/ru/data.yml b/modules/30-variables/20-magic-numbers/ru/data.yml index b836d24..6204a85 100644 --- a/modules/30-variables/20-magic-numbers/ru/data.yml +++ b/modules/30-variables/20-magic-numbers/ru/data.yml @@ -1,5 +1,4 @@ --- - name: Магические числа tips: - > diff --git a/modules/30-variables/20-magic-numbers/test_code.py b/modules/30-variables/20-magic-numbers/test_code.py index f9a5f69..17e9f41 100644 --- a/modules/30-variables/20-magic-numbers/test_code.py +++ b/modules/30-variables/20-magic-numbers/test_code.py @@ -2,5 +2,5 @@ def test(capsys): - expected = "Rooms in King Balon's Castle:\n102" + expected = "Rooms in King Balon's Castles:\n102" expect_output(capsys, expected) diff --git a/modules/30-variables/23-constants/ru/EXERCISE.md b/modules/30-variables/23-constants/ru/EXERCISE.md index 3588046..4768f44 100644 --- a/modules/30-variables/23-constants/ru/EXERCISE.md +++ b/modules/30-variables/23-constants/ru/EXERCISE.md @@ -1,2 +1 @@ - Создайте константу `DRAGONS_BORN_COUNT` и запишите в неё число 3 — это количество драконов, родившихся у Дайенерис. diff --git a/modules/30-variables/23-constants/ru/README.md b/modules/30-variables/23-constants/ru/README.md index f586928..096d79e 100644 --- a/modules/30-variables/23-constants/ru/README.md +++ b/modules/30-variables/23-constants/ru/README.md @@ -1,9 +1,45 @@ +Иногда в программе встречаются значения, которые никогда не должны меняться. Например: -Некоторые данные никогда не меняются — например, математические постоянные. Возьмем для примера число π. Оно всегда равно 3.14 и не может измениться. Чтобы обратиться к подобным данным, в Python используют константы: +- математическая константа π (пи), +- курс доллара на определённую дату, +- фиксированная комиссия сервиса. + +Такие значения называются константами и обычно записываются немного по другому. + +## 🔢 Пример: число π ```python PI = 3.14 print(PI) # => 3.14 ``` -Константа создается так же, как переменная. Разница только в том, что константы принято именовать заглавными буквами и с `_` в качестве разделителя между словами. Константа, как и переменная, может использоваться в любом выражении. +Здесь PI — это константа, которая хранит значение числа π. +Смысл константы в том, что её значение не должно меняться в ходе работы программы. + +## 🧱 Чем отличается константа от переменной? + +С технической точки зрения — ничем. +Константа создаётся так же, как обычная переменная. Python не запрещает менять её значение: + +```python +PI = 3.14 +PI = 3.14159 # ❌ Технически возможно, но так делать не принято +``` + +Но по соглашению, если переменная названа заглавными буквами, значит — это константа, и менять её нельзя. + +## ✍️ Как оформляются константы + +- Все буквы заглавные +- Слова разделяются символом подчёркивания `_` +- Стиль называется SCREAMING_SNAKE_CASE + +```python +PI = 3.14 +MAX_USERS = 100 +DEFAULT_TIMEOUT = 30 +``` + +## 🧠 Зачем нужны константы? + +Константы делают код понятнее и безопаснее. Они помогают сразу увидеть, какие значения в программе считаются фиксированными и не должны меняться. Это особенно важно при работе с такими данными, как математические и физические постоянные, настройки по умолчанию или фиксированные лимиты. Использование констант снижает риск ошибок — программист не изменит значение случайно, просто потому что по имени будет понятно: это константа. Кроме того, если значение всё же нужно будет изменить (например, в настройках), его достаточно поменять в одном месте — и это изменение автоматически подхватится во всей программе. diff --git a/modules/30-variables/23-constants/ru/data.yml b/modules/30-variables/23-constants/ru/data.yml index c2c836b..c4a1647 100644 --- a/modules/30-variables/23-constants/ru/data.yml +++ b/modules/30-variables/23-constants/ru/data.yml @@ -1,5 +1,4 @@ --- - name: Константы tips: [] definitions: diff --git a/modules/31-advanced-strings/25-interpolation/ru/EXERCISE.md b/modules/31-advanced-strings/25-interpolation/ru/EXERCISE.md index f8b2eb4..c43079a 100644 --- a/modules/31-advanced-strings/25-interpolation/ru/EXERCISE.md +++ b/modules/31-advanced-strings/25-interpolation/ru/EXERCISE.md @@ -1,4 +1,3 @@ - Выведите на экран строку `Do you want to eat, ?`. Где вместо `` должна использоваться переменная `stark`. Вывод должен получиться таким:
diff --git a/modules/31-advanced-strings/25-interpolation/ru/README.md b/modules/31-advanced-strings/25-interpolation/ru/README.md
index 96a87d0..6bc2443 100644
--- a/modules/31-advanced-strings/25-interpolation/ru/README.md
+++ b/modules/31-advanced-strings/25-interpolation/ru/README.md
@@ -1,7 +1,4 @@
-
-Вы уже знаете, как перенести строку или «слепить» несколько строк, чтобы получить новое выражение. Но в программировании есть альтернативы этих операций. Они повышают читаемость кода и делают его проще в поддержке.
-
-Базовый способ соединения строк — **конкатенация**. С помощью конкатенации строки «суммируются» друг с другом, как в примере ниже:
+Конкатенация работает просто и понятно: строки складываются с помощью +.
 
 ```python
 first_name = 'Joffrey'
@@ -11,7 +8,11 @@ print(greeting + ", " + first_name + "!")
 # => Hello, Joffrey!
 ```
 
-Конкатенация работает просто, но выглядит не всегда наглядно. Из-за кавычек сложно разглядеть то, каким будет конечный результат. И чем сложнее устроена строка, тем запутаннее она начнет выглядеть. У конкатенации есть альтернатива — **интерполяция**. Вот как это выглядит:
+Но при этом в сложных выражениях становится трудно сразу увидеть, какой текст получится на выходе. Особенно если в строке используются пробелы, запятые или кавычки — они начинают мешать восприятию.
+
+## 💡 Альтернатива — интерполяция
+
+Интерполяция — это способ встраивать значения переменных прямо внутрь строки. В Python для этого используются f-строки (или format-строки). Вот так:
 
 ```python
 first_name = 'Joffrey'
@@ -21,9 +22,9 @@ print(f'{greeting}, {first_name}!')
 # => Hello, Joffrey!
 ```
 
-Буква `f` указывает на то, что мы создаем **f-строку** — шаблон, в который с помощью фигурных скобок подставляются значения переменных. На выходе получается обычная строка.
+Буква f перед кавычками указывает, что внутри строки можно использовать переменные. Их имена записываются в фигурных скобках, и Python автоматически подставляет нужные значения.
 
-Рассмотрим такой пример:
+## 🔍 Пример
 
 ```python
 school = 'Hexlet'
@@ -32,8 +33,12 @@ what_is_it = f'{school} - online courses'
 print(what_is_it)  # => Hexlet - online courses
 ```
 
-https://replit.com/@hexlet/python-basics-advanced-strings-interpolation
+Такая запись легко читается: пробелы, дефисы, символы — всё видно сразу. Строка выглядит именно так, как она появится в выводе. Это делает код понятным и удобным в поддержке.
+
+## 📌 Почему это важно
 
-Почти во всех языках для объединения строк интерполяция предпочтительнее конкатенации. Строка при этом получается склеенная, и внутри нее хорошо просматриваются пробелы и другие символы.
+Интерполяция предпочтительнее конкатенации почти во всех современных языках программирования. Она:
 
-Интерполяция помогает сделать код более понятным для разработчиков. Но это не единственная полезная альтернатива, о которой мы хотели рассказать. Далее в курсе мы разберемся, как объявлять многострочную строку и не использовать `\n`.
+- Упрощает структуру строк.
+- Улучшает читаемость кода.
+- Снижает количество ошибок при работе с пробелами и знаками препинания.
diff --git a/modules/31-advanced-strings/25-interpolation/ru/data.yml b/modules/31-advanced-strings/25-interpolation/ru/data.yml
index e465d9b..e026e73 100644
--- a/modules/31-advanced-strings/25-interpolation/ru/data.yml
+++ b/modules/31-advanced-strings/25-interpolation/ru/data.yml
@@ -1,5 +1,4 @@
 ---
-
 name: Интерполяция
 tips:
   - >
diff --git a/modules/31-advanced-strings/30-symbols/ru/EXERCISE.md b/modules/31-advanced-strings/30-symbols/ru/EXERCISE.md
index a60b46a..033c1d9 100644
--- a/modules/31-advanced-strings/30-symbols/ru/EXERCISE.md
+++ b/modules/31-advanced-strings/30-symbols/ru/EXERCISE.md
@@ -1,2 +1 @@
-
 Выведите на экран последний символ строки, находящейся в переменной `name`
diff --git a/modules/31-advanced-strings/30-symbols/ru/README.md b/modules/31-advanced-strings/30-symbols/ru/README.md
index 90fa271..60e1af0 100644
--- a/modules/31-advanced-strings/30-symbols/ru/README.md
+++ b/modules/31-advanced-strings/30-symbols/ru/README.md
@@ -1,52 +1,88 @@
+Иногда нужно получить один символ из строки. Например, если сайт знает имя и фамилию пользователя и нужно вывести их в сокращённом формате — A. Ivanov. Для этого потребуется взять первую букву имени.
 
-Иногда нужно получить один символ из строки. Например, если сайт знает имя и фамилию пользователя, и в какой-то момент требуется вывести эту информацию в формате *A. Ivanov*. Для этого компьютеру потребуется взять первый символ из имени. В Python есть подходящая операция, которую мы изучим сегодня.
+В Python для таких задач есть специальный механизм — индексация.
 
-Представим, что из имени Alexander нужно вывести на экран только первую букву. Это выглядит так:
+## 🔢 Индексация: как это работает
 
-```python
+Представим, что у нас есть строка:
+
+```Python
 first_name = 'Alexander'
+```
 
+Чтобы получить первую букву, указываем её позицию (индекс) в квадратных скобках:
+
+```Python
 print(first_name[0])  # => A
 ```
 
-Операция с квадратными скобками с цифрой извлекает элемент по **индексу** — позицией символа внутри строки. Индексы начинаются с 0 почти во всех языках программирования. Поэтому, чтобы получить первый символ, нужно указать индекс `0`. Индекс последнего элемента равен длине строки минус единица. Обращение к индексу за пределами строки приведет к ошибке:
+Индексы в Python (и во многих языках) начинаются с нуля:
 
-```python
-# Длина строки 9, поэтому последний индекс — это 8
-first_name = 'Alexander'
+```
+Символ	A	l	e	x	a	n	d	e	r
+Индекс	0	1	2	3	4	5	6	7	8
+```
 
-print(first_name[8])  # => r
+Чтобы получить, например, последний символ, можно написать:
 
-print(first_name[9])
-IndexError: string index out of range
+```Python
+print(first_name[8])  # => r
 ```
 
-Чтобы лучше закрепить новые знания, посмотрите на код ниже и подумайте, что он выдаст:
+А если выйти за границы строки:
 
-```python
-magic = '\nyou'
-print(magic[1])  # => ?
+```Python
+print(first_name[9])
 ```
 
-Бывают и нестандартные ситуации. Например, нужно вывести элемент из конца, причем из выражения с большим количеством символов. В этом случае можно воспользоваться отрицательным индексом, который облегчит работу программиста.
+IndexError: string index out of range
 
-Допустимо использовать отрицательные индексы. В этом случае идет обращение к символам, начиная с конца строки. `-1` — индекс последнего символа, `-2` — предпоследнего и так далее. В отличие от прямой индексации, обратный отсчет идет от `-1`:
+## 📍 Укороченное извлечение с конца
 
-```python
-first_name = 'Alexander'
+Часто нужно получить последний символ строки, но заранее неизвестна её длина. В этом случае можно использовать отрицательные индексы:
 
+```Python
 print(first_name[-1])  # => r
+print(first_name[-2])  # => e
 ```
 
-Индексом может быть не только конкретное число, но и значение переменной. Посмотрите на пример ниже. Здесь мы записали индекс внутри квадратных скобок не числом, а переменной. Такой код приведет к тому же результату — выводу на экран символа *A*:
 
-```python
-first_name = 'Alexander'
-index = 0
+Отрицательные индексы работают так:
+
+- -1 — последний символ
+- -2 — предпоследний
+- и так далее
+
+Это удобно, когда не хочется считать длину строки вручную.
+
+🧠 Индекс — это не только число
 
+Индекс можно хранить в переменной, а не записывать прямо:
+
+```Python
+index = 0
 print(first_name[index])  # => A
 ```
 
-https://replit.com/@hexlet/python-basics-advanced-strings-symbols
+Такой подход полезен, когда индекс вычисляется где-то в коде, а потом используется для доступа к нужному символу.
+
+## 💡 Подумайте: что выведет этот код?
+
+```Python
+magic = '\nyou'
+print(magic[1])  # => ?
+```
+
+В строке '\nyou' первый символ — это \n (перенос строки), а под индексом 1 — буква y.
+Вывод будет:
+
+```
+y
+```
+
+🔁 Закрепим
 
-Чтобы выводить из выражения лишь некоторые символы, не нужно писать большое количество строк кода — достаточно извлечь элемент с помощью индекса. Также можно пользоваться отрицательным индексом, чтобы легче выводить символы с конца выражения. Далее разберемся, как с помощью этих знаний можно извлекать подстроки из строки.
+- Строки можно индексировать — получать символы по номеру.
+- Отсчёт с начала идёт с 0, с конца — с -1.
+- Можно использовать как числа, так и переменные в качестве индексов.
+- Если индекс выходит за пределы строки — будет ошибка.
diff --git a/modules/31-advanced-strings/30-symbols/ru/data.yml b/modules/31-advanced-strings/30-symbols/ru/data.yml
index 5442257..b16dee9 100644
--- a/modules/31-advanced-strings/30-symbols/ru/data.yml
+++ b/modules/31-advanced-strings/30-symbols/ru/data.yml
@@ -1,5 +1,4 @@
 ---
-
 name: Извлечение символов из строки
 tips: []
 definitions:
diff --git a/modules/31-advanced-strings/70-slices/ru/EXERCISE.md b/modules/31-advanced-strings/70-slices/ru/EXERCISE.md
index f016b2e..9c608a9 100644
--- a/modules/31-advanced-strings/70-slices/ru/EXERCISE.md
+++ b/modules/31-advanced-strings/70-slices/ru/EXERCISE.md
@@ -1,2 +1 @@
-
 В переменной `value` лежит значение `Hexlet`. Извлеките из него и выведите на экран срез, который получит подстроку `xle`. Это задание можно сделать разными способами.
diff --git a/modules/31-advanced-strings/70-slices/ru/README.md b/modules/31-advanced-strings/70-slices/ru/README.md
index 702d9bd..48fe0cd 100644
--- a/modules/31-advanced-strings/70-slices/ru/README.md
+++ b/modules/31-advanced-strings/70-slices/ru/README.md
@@ -1,118 +1,147 @@
+Работая со строками, мы часто сталкиваемся с задачей: извлечь часть строки. Например, получить год из даты, имя из полного ФИО или первые несколько символов из адреса электронной почты. Для таких случаев в Python существует мощный и удобный инструмент — срезы (или slices).
 
-Когда мы работаем со строками в программировании, из них регулярно приходится извлекать некую часть. Например, нам нужно выяснить, присутствует ли меньшая строка внутри большей. В этом уроке мы разберемся, как это сделать.
+## 📍 Что такое подстрока?
 
-**Подстрока** — это некоторая часть строки, которую нужно найти и извлечь.
+Подстрока — это часть строки. То, что входит внутрь другой строки. Например, в строке '12-08-2034' подстрокой может быть '2034', '12' или даже '-'. Всё зависит от того, какую информацию нам нужно извлечь.
 
-Представим, что у нас есть дата в таком формате: *12-08-2034*. Нам нужно извлечь из нее подстроку, в которую входит только год.
+Допустим, у нас есть строка с датой '12-08-2034'. Мы хотим получить из неё только год — '2034'. В этой строке каждый символ имеет индекс (позицию), начиная с нуля:
 
-Если подумать логически, то нужно посчитать индекс символа, с которого начинается год, и затем извлечь четыре символа. Индексы в строке начинаются с нуля, значит, первый символ года доступен по индексу 6, а последний символ — по индексу 9. Проверим:
-
-```python
-value = '12-08-2034'
-
-print(value[6])  # => 2
-print(value[9])  # => 4
+```
+'1' '2' '-' '0' '8' '-' '2' '0' '3' '4'
+ 0   1   2   3   4   5   6   7   8   9
 ```
 
-Зная эти индексы, мы можем воспользоваться срезами и получить нужную подстроку:
+Получается, год начинается с индекса 6 и заканчивается на 9. Чтобы извлечь его, мы используем срез:
 
-```python
+```Python
 value = '12-08-2034'
-
 year = value[6:10]
 print(year)  # => 2034
 ```
 
-**Срезы для строк** в Python — это механизм, с помощью которого извлекается подстрока по указанным параметрам. В примере выше мы взяли подстроку с 6 индекса по 10 индекс, не включая, то есть с 6 по 9 включительно. Формула выглядит так:
+Срез `value[6:10]` берёт символы с индекса 6 по 9 включительно. Формат среза:
+
+```Python
+строка[начало:конец]
+```
+
+Важно: символ с индексом, указанным как "конец", не включается.
 
-```python
-str[начальный индекс:конечный индекс]
+## 📘 Срез — это тоже строка
 
-# Пара примеров
+```Python
 value = '01-12-9873'
 
-# Срез строки это всегда строка,
-# даже если внутри строки было число.
-value[1:2]  # '1'
-value[3:5]  # '12'
+value[1:2]   # => '1'
+value[3:5]   # => '12'
 ```
 
-Срезы — механизм с большим количеством вариаций. Например, если не указать вторую границу, то извлечение произойдет до конца строки. То же самое с первой границей — началом строки:
+Срез всегда возвращает строку, даже если в ней только цифры. Это значит, что результат можно использовать, как обычную строку: конкатенировать, печатать, передавать в функции и так далее.
 
-```python
+## ⬅️ Срез до конца или с начала
+
+Иногда нужно взять часть строки до конца или от начала — такие ситуации тоже легко обрабатываются срезами:
+
+```Python
 value = 'Hexlet'
-value[3:]  # 'let'
-value[:3]  # 'Hex'
+
+value[3:]   # => 'let'     # С 3 символа до конца
+value[:3]   # => 'Hex'     # От начала до 3 символа
 ```
 
-Можно указать даже отрицательные индексы. В таком случае отсчет идет с обратной стороны:
+Если не указать границу, Python сам подставит нужное значение: начало строки или её конец.
+
+## ↩️ Срезы с отрицательными индексами
 
-```python
+Python позволяет считать не только слева направо, но и с конца строки. Для этого используются отрицательные индексы:
+
+```Python
 value = 'Hexlet'
-# Правая граница отрицательная. Считаем -1 от конца строки
-value[3:-1]  # 'le'
-# Левая граница отрицательная. Считаем -5 от конца строки
-value[-5:3]  # 'ex'
+
+value[-1]      # => 't'      # Последний символ
+value[3:-1]    # => 'le'     # От 3 до предпоследнего
+value[-5:3]    # => 'ex'     # С 1 до 3 включительно
 ```
 
-У срезов два обязательных параметра, но иногда используется и третий.
+Это удобно, когда заранее неизвестна длина строки, но нужно взять «хвост» или «середину» строки относительно конца.
 
-У срезов есть третий необязательный параметр — **шаг извлечения**. По умолчанию он равен единице, но мы можем его изменить:
+## ⏩ Шаг в срезах
 
-```python
+У среза есть третий параметр — шаг. По умолчанию шаг равен 1, то есть символы идут подряд. Но шаг можно изменить, например, взять каждый второй символ:
+
+```Python
 value = 'Hexlet'
-value[1:5:2]  # el
-# 1:5 это 'exle'
-# шаг 2 это каждый второй, то есть 'e' и 'l'
+
+value[1:5:2]   # => 'el'
+# Индексы 1, 3 → символы 'e', 'l'
 ```
 
-Все это можно комбинировать с открытыми границами, то есть без указания начала или конца:
+В этом примере:
 
-```python
-value = 'Hexlet'
-value[:5:2]  # 'Hxe'
-value[1::2]  # 'elt'
+- 1:5 — это срез 'exle'
+- шаг 2 — означает, что мы берём через один символ: 'e' и 'l'
+
+Можно комбинировать с открытыми границами:
+
+```Python
+value[:5:2]    # => 'Hxe'
+value[1::2]    # => 'elt'
 ```
 
-Шаг может быть отрицательным, в таком случае он берется с конца. Из этого вытекает самый популярный способ использования шага — **переворот строки**:
+## 🔄 Переворот строки
+
+Одна из самых популярных «фишек» с шагом — реверс строки. Для этого используют отрицательный шаг:
 
-```python
+```Python
 value = 'Hexlet'
-# Пропускаем обе границы
-value[::-1]  # 'telxeH'
+
+value[::-1]    # => 'telxeH'
 ```
 
-Если используется отрицательный шаг, и элементы среза извлекаются в обратном порядке — тогда и границы среза тоже нужно указывать в обратном порядке. Первой указывается правая граница среза, второй — левая:
+Это полностью переворачивает строку — с конца к началу. Очень удобно и лаконично.
+
+## ⚠️ Срезы с отрицательным шагом
 
-```python
+Если вы используете отрицательный шаг, помните: индексы тоже нужно указывать в обратном порядке. Иначе срез не сработает (возвратит пустую строку):
+
+```Python
 value = 'Hexlet'
-# Символ с индексом 1 не будет включен в подстроку
-value[4:1:-1]  # 'elx'
+
+value[4:1:-1]  # => 'elx'
+# Индексы: 4, 3, 2 → 'e', 'l', 'x'
 ```
 
-Срезы можно указывать не только через числа, но и с использованием переменных:
+Python начнёт с индекса 4 и пойдёт влево до индекса 2 включительно. Индекс 1 — не включается.
 
-```python
-value = 'Hexlet'
+## 📦 Срез с переменными
+
+Срезы не обязаны быть жёстко зафиксированы числами. Можно использовать переменные:
+
+```Python
 start = 1
 end = 5
-value[start:end]  # 'exle'
+
+value = 'Hexlet'
+print(value[start:end])  # => 'exle'
 ```
 
-https://replit.com/@hexlet/python-basics-advanced-strings-slices
+Это особенно полезно, когда границы вычисляются во время работы программы.
 
-Соберем все вместе:
+## 🧪 Быстрая шпаргалка
 
-```python
+```Python
 value = 'Hexlet'
-value[::] = 'Hexlet'  # Вся строка
-value[:] = 'Hexlet'  # Вся строка
-value[::2] = 'Hxe'  # Четные по порядку символы
-value[1::2] = 'elt'  # Нечетные по порядку символы
-value[::-1] = 'telxeH'  # Вся строка в обратном порядке
-value[5:] = 't'  # Строка, начиная с шестого символа
-value[:5] = 'Hexle'  # Строка до шестого символа
-value[-2:1:-1] = 'elx'  # Все символы с предпоследнего до третьего в обратном порядке. Во всех случаях выборки от большего индекса к меньшему нужно указывать шаг
+
+value[::]       # 'Hexlet'  — вся строка
+value[:]        # 'Hexlet'
+value[::2]      # 'Hxe'     — чётные символы
+value[1::2]     # 'elt'     — нечётные символы
+value[::-1]     # 'telxeH'  — строка в обратном порядке
+value[5:]       # 't'
+value[:5]       # 'Hexle'
+value[-2:1:-1]  # 'elx'     — с предпоследнего до третьего
 ```
 
-Как видите, срезы способны на многое. Не переживайте, если прямо сейчас не запомните все эти комбинации — это нормально. Со временем вы научитесь их использовать, не подглядывая в документацию.
+Когда делаете срез от большего индекса к меньшему, не забудьте задать отрицательный шаг — иначе срез не сработает.
+
+Не переживайте, если сейчас не запомните все комбинации — вы быстро начнёте использовать их на практике. Главное — понимать, как работает базовая структура `строка[начало:конец:шаг]`.
diff --git a/modules/31-advanced-strings/70-slices/ru/data.yml b/modules/31-advanced-strings/70-slices/ru/data.yml
index 185afec..3496b38 100644
--- a/modules/31-advanced-strings/70-slices/ru/data.yml
+++ b/modules/31-advanced-strings/70-slices/ru/data.yml
@@ -1,5 +1,4 @@
 ---
-
 name: Срезы строк
 tips:
   - >
diff --git a/modules/31-advanced-strings/90-multiline-strings/ru/EXERCISE.md b/modules/31-advanced-strings/90-multiline-strings/ru/EXERCISE.md
index 2e658ad..dbb7687 100644
--- a/modules/31-advanced-strings/90-multiline-strings/ru/EXERCISE.md
+++ b/modules/31-advanced-strings/90-multiline-strings/ru/EXERCISE.md
@@ -1,4 +1,3 @@
-
 Запишите в переменную `text` текст, который приведен ниже. Используйте тройные кавычки.
 
 ```
diff --git a/modules/31-advanced-strings/90-multiline-strings/ru/README.md b/modules/31-advanced-strings/90-multiline-strings/ru/README.md
index a89f973..172b25a 100644
--- a/modules/31-advanced-strings/90-multiline-strings/ru/README.md
+++ b/modules/31-advanced-strings/90-multiline-strings/ru/README.md
@@ -1,70 +1,98 @@
+Иногда текст в программе должен состоять из нескольких строк. Например, при генерации письма, создании шаблона, форматировании сообщения об ошибке или просто работе с длинными текстами.
 
-Представьте, что нам нужно определить строку, которая состоит из нескольких строчек — то есть внутри есть переводы строки `\n`. Например, она будет выглядеть так:
+Конечно, можно использовать символ перевода строки `\n`, как мы делали раньше:
 
 ```python
 text = 'Пример текста,\nсостоящего из\nнескольких строк'
 ```
 
-На печати строка примет совсем другой вид:
+На печати строка будет выглядеть вот так:
 
-```bash
+```
 Пример текста,
 состоящего из
 нескольких строк
 ```
 
-Для таких ситуаций в Python есть еще один способ создания строк, который называется **multi-line строки**. Чтобы описать такую «многострочную строку», нужно заключить ее в тройные кавычки — `"""` или `'''`. Внутри multi-line строки можно переносить текст и не использовать перевод строки `\n`:
+Но такой способ становится неудобным, особенно если строка длинная или нужно часто добавлять новые переносы. Каждый `\n` приходится вставлять вручную, и это ухудшает читаемость кода.
+
+## ✨ Альтернатива — многострочные строки (multi-line)
+
+В Python есть более удобный способ записывать текст в несколько строк — многострочные строки (multi-line strings).
+
+Чтобы создать такую строку, нужно заключить текст в тройные кавычки — `'''` или `"""`:
 
 ```python
 text = '''Пример текста,
 состоящего из
-нескольких строк
-'''
+нескольких строк'''
 ```
 
-```bash
+Теперь в коде всё выглядит так же, как и при выводе:
+
+```python
 Пример текста,
 состоящего из
 нескольких строк
-
 ```
 
-Обратите внимание, что в конце текста есть пустая строка. Она появилась в тексте потому, что мы поставили закрывающие кавычки `'''` на новой строке. Если не переносить закрывающие кавычки на новую строку, то пустая строка в тексте не появится:
+## ⚠️ Осторожно с пустой строкой в конце
+
+Если вы закрываете тройные кавычки на новой строке, Python включает и эту строку в результат:
 
 ```python
 text = '''Пример текста,
 состоящего из
-нескольких строк'''
+нескольких строк
+'''
 ```
 
-```bash
+Вывод:
+
+```python
 Пример текста,
 состоящего из
 нескольких строк
+
 ```
 
-Из-за тройных кавычек multi-line строки позволяют не экранировать кавычки внутри строки:
+Обратите внимание: появляется пустая строка в конце. Чтобы её избежать — не переносите закрывающие кавычки на новую строку:
 
-```bash
-Здесь не нужно экранировать 'одинарные' и "двойные" кавычки
+```python
+text = '''Пример текста,
+состоящего из
+нескольких строк'''
+```
+
+✅ Преимущества multi-line строк
+
+- Читаемость кода — текст в коде выглядит почти как на экране.
+- Удобство при редактировании — легко добавлять, удалять и менять строки.
+- Не нужно экранировать кавычки:
+
+```python
+quote = '''Здесь не нужно экранировать 'одинарные' и "двойные" кавычки'''
 ```
 
-Еще multi-line строки могут становиться f-строками для интерполяции:
+## 🔀 Интерполяция внутри многострочной строки
+
+Многострочные строки можно сочетать с f-строками, чтобы подставлять значения переменных:
 
 ```python
-a = 'A'
+a = 'А'
 b = 'B'
 
-# Слева добавился f
 text = f'''{a} и {b}
-сидели на трубе
-'''
+сидели на трубе'''
 ```
 
-```bash
+```
 А и B
 сидели на трубе
-
 ```
 
-Для компьютера неважно, какие способы соединения и переноса строк вы будете использовать. Он все равно произведет вычисления и выдаст нужный результат. Интерполяция и multi-line строки используются для удобства разработчиков, чтобы им было проще читать код.
+Это особенно удобно для шаблонов, писем, сообщений об ошибках и многострочных описаний.
+
+## 🤖 Компьютеру всё равно, а человеку — нет
+
+Python может обработать и строки с `\n`, и многострочные строки. Для интерпретатора это одно и то же. Но для человека, читающего код, multi-line строки намного удобнее и нагляднее.
diff --git a/modules/31-advanced-strings/90-multiline-strings/ru/data.yml b/modules/31-advanced-strings/90-multiline-strings/ru/data.yml
index c5884c7..df51046 100644
--- a/modules/31-advanced-strings/90-multiline-strings/ru/data.yml
+++ b/modules/31-advanced-strings/90-multiline-strings/ru/data.yml
@@ -1,5 +1,4 @@
 ---
-
 name: Multi-line строки
 definitions: []
 tips:
diff --git a/modules/33-data-types/40-primitive-data-types/ru/README.md b/modules/33-data-types/40-primitive-data-types/ru/README.md
index f4208f9..aa9c439 100644
--- a/modules/33-data-types/40-primitive-data-types/ru/README.md
+++ b/modules/33-data-types/40-primitive-data-types/ru/README.md
@@ -1,24 +1,97 @@
+Программы работают с разной информацией: текст, числа, даты, списки, булевы значения. У каждого фрагмента данных в программе есть тип — его “категория”.
 
-Бывают разные способы представлять данные в программах. Есть **строки** — наборы символов в кавычках вроде `"Hello, World!"`. Есть **целые числа** — например, `7`, `-198`, `0`. Это две разные категории информации — два разных **типа данных**. Операция умножения имеет смысл для категории «целые числа», но не для категории «строки»: нет смысла умножать слово «мама» на слово «блокнот».
+Например:
 
-Тип данных определяет, что можно делать с элементами конкретного множества информации. В этом уроке мы изучим типы данных и узнаем, как работает типизация в Python.
+- "Hello, World!" — это строка (набор символов)
+- 7, -198, 0 — это целые числа
+- 3.14, -0.01, 1.0 — это рациональные числа (или числа с плавающей точкой)
 
-Язык программирования распознает типы данных, поэтому Python не позволит нам умножать строку на строку — нельзя умножать текст на текст. При этом можно умножать целое число на другое целое число. Наличие типов и таких ограничений в языке защищает программы от случайных ошибок.
+## 🔍 Что такое тип данных?
 
-В отличие от строк, числа оборачивать в кавычки не нужно. Чтобы напечатать число 5, достаточно написать:
+Тип данных определяет:
+
+- как интерпретировать значение;
+- какие операции с ним можно делать.
+
+Например, числа можно складывать, делить и умножать. А вот строки складываются по-другому — при помощи конкатенации (склеивания). Но умножать строку на строку нельзя — это бессмысленно:
+
+```python
+# Нельзя: 'мама' * 'блокнот'  ❌
+```
+
+## 🧮 Числа и строки — разные типы
+
+Пример вывода числа:
 
 ```python
 print(5)  # => 5
 ```
 
-Число `5` и строка `'5'` — совершенно разные вещи, хотя вывод у `print()` для этих данных идентичный. Целые числа (`1`, `34`, `-19` и т.д.) и рациональные числа (`1.3`, `1.0`, `-14.324` и т.д.) — это два отдельных **типа данных**. Такое разделение связано с особенностями устройства компьютеров. Есть и другие типы, с ними мы познакомимся позже.
+Пример вывода строки:
+
+```python
+print('5')  # => 5
+```
+
+На экране результат выглядит одинаково, но внутри программы это совершенно разные вещи:
+
+| Значение | Тип данных       |
+|----------|------------------|
+| `5`      | `int` (целое число) |
+| `'5'`    | `str` (строка)    |
+
+Строку '5' нельзя сложить с числом 5, как и '10' / 2 не даст числа 5.0.
+Python будет ругаться, если вы попытаетесь смешать несовместимые типы без явного преобразования.
+
+## 🔢 Целые и рациональные числа
+
+Python различает два вида чисел:
+
+- int — целые числа: -3, 0, 7, 100000
+- float — вещественные (рациональные) числа: 1.0, -3.14, 2.718
 
-Вот еще один пример, но уже с рациональным числом:
+Пример:
 
 ```python
 print(10.234)  # => 10.234
 ```
 
-Типы данных «строка», «целое число» и «рациональное число» — это *примитивные типы*, то есть они встроены в сам язык Python. В язык встроены также и некоторые составные типы, но пока мы будем работать только с примитивными. Программисты также могут создавать собственные типы данных.
+Числа с точкой Python воспринимает как float — с ними можно делать арифметику с десятичной точностью.
+
+## ⚙️ Почему типы вообще нужны?
+
+Типы помогают компьютеру понимать, как обрабатывать данные. Они:
+
+- определяют набор допустимых операций;
+- влияют на поведение функций и выражений;
+- позволяют языку выявлять ошибки ещё до выполнения программы.
+
+Например, если вы случайно попытаетесь сложить строку с числом, Python остановит программу и покажет ошибку — именно благодаря строгой типизации.
+
+🧱 Примитивные типы
+
+Типы вроде:
+
+- str (строка),
+- int (целое число),
+- float (рациональное число)
+
+называются примитивными — они встроены прямо в язык. Существуют и составные типы: списки, словари, кортежи и другие. С ними мы познакомимся позже. Более того, в Python можно создавать и свои собственные типы (например, классы), но для начала важно хорошо разобраться с примитивами.
+
+## 📚 Терминология: строка или строчка?
+
+В программировании есть терминологическая ловушка:
+
+- строка (string) — это тип данных, например 'hello'
+- строчка (line) — это строка текста в файле или в коде
+
+Например, в коде ниже есть строчка, но не строка:
+
+```python
+print(5)
+```
+
+Чтобы избежать путаницы, в этом курсе мы будем использовать:
 
-По-английски строки в программировании называются strings, а строчки текстовых файлов — lines. Например, в коде кода выше есть строчка (line), но нет никаких строк (strings). В русском иногда может быть путаница, поэтому во всех уроках мы будем говорить **строка** для обозначения типа данных «строка», и **строчка** для обозначения строчек кода (lines) в файлах.
+- строка — когда говорим о данных типа str;
+- строчка — когда речь идёт о строках кода (lines).
diff --git a/modules/33-data-types/40-primitive-data-types/ru/data.yml b/modules/33-data-types/40-primitive-data-types/ru/data.yml
index 7fe3a22..79e5736 100644
--- a/modules/33-data-types/40-primitive-data-types/ru/data.yml
+++ b/modules/33-data-types/40-primitive-data-types/ru/data.yml
@@ -1,5 +1,4 @@
 ---
-
 name: Типы данных
 tips:
   - >
diff --git a/modules/33-data-types/50-strong-typing/ru/EXERCISE.md b/modules/33-data-types/50-strong-typing/ru/EXERCISE.md
index d5e2d6b..954c6ae 100644
--- a/modules/33-data-types/50-strong-typing/ru/EXERCISE.md
+++ b/modules/33-data-types/50-strong-typing/ru/EXERCISE.md
@@ -1,2 +1 @@
-
 Выведите на экран результат выражения: `7 - (-8 - -2)`. Попробуйте сделать число 7 не числом, а строкой. Сработает ли такой код? Поэкспериментируйте с другими числами тоже.
diff --git a/modules/33-data-types/50-strong-typing/ru/README.md b/modules/33-data-types/50-strong-typing/ru/README.md
index 469046d..56814c2 100644
--- a/modules/33-data-types/50-strong-typing/ru/README.md
+++ b/modules/33-data-types/50-strong-typing/ru/README.md
@@ -1,22 +1,50 @@
+Python относится к типам данных очень серьёзно. Если вы попытаетесь выполнить операцию между несовместимыми типами — программа выдаст ошибку. Всё дело в том, что Python — язык со строгой (или сильной) типизацией.
 
-Python — один из языков, который строго относится к типам данных. Поэтому на любую несовместимость типов он ответит ошибкой. Все дело в сильной типизации.
+## 🧮 Что это значит на практике?
 
-Нам известно про два разных типа данных: числа и строки. Например, мы могли складывать числа, потому что операция сложения — это операция для типа «числа». А что, если применить эту операцию не к двум числам, а к числу и строке?
+Допустим, вы складываете два числа:
 
-```python
-print(1 + '7')  # TypeError: unsupported operand type(s)...
+```Python
+print(1 + 7)  # => 8
 ```
 
-Python не разрешит сложить число `1` и строку `'7'`, потому что это значения разных типов. Нужно сначала либо сделать строку числом, либо число строкой. Как это сделать, мы поговорим позже.
+Всё отлично. Операция сложения допустима для чисел.
+А что будет, если попробовать сложить число и строку?
 
-Такое педантичное отношение к совместимости типов называется **строгой типизацией** или **сильной типизацией**. Python — язык со строгой типизацией.
+```Python
+print(1 + '7')  
+# TypeError: unsupported operand type(s) for +: 'int' and 'str'
+```
+
+Python сообщает, что не может сложить int и str. Это ошибка типов: значения принадлежат к разным категориям, и программа отказывается продолжать.
+
+## 🔎 Почему так строго?
+
+Python защищает вас от неочевидных и опасных ошибок. Он требует, чтобы вы явно указали, как вы хотите преобразовать данные:
+
+- либо сделать строку числом (`int('7')`);
+- либо число строкой (`str(1)`).
+
+Мы научимся делать это чуть позже.
 
-Не все языки так делают. Например, PHP — это язык со **слабой типизацией**. Он знает о существовании разных типов, но относится к их использованию не очень строго. PHP пытается преобразовывать информацию, когда это кажется разумным. То же самое относится к JavaScript:
+## 🔁 А как в других языках?
 
-```javascript
-// Как тебе такое, Илон Маск?
-// Число 1 + Строка 7 = Строка 17
-1 + '7'; // '17'
+Не все языки такие. Например, PHP и JavaScript используют слабую типизацию — они автоматически преобразуют типы, когда считают это «разумным»:
+
+```Python
+1 + '7';  // => '17'
 ```
 
-С одной стороны, автоматическое неявное преобразование типов и правда кажется удобным. Но на практике это свойство языка создает множество ошибок и проблем, которые трудно найти. Код может иногда работать, а иногда не работать — в зависимости от того, «повезло» ли с автоматическим преобразованием. Программист это заметит не сразу и потратит много времени на отладку.
+В этом примере число 1 неявно превращается в строку '1', и результатом становится '17'.
+
+Сначала может показаться, что слабая типизация — это удобно. Меньше кода, всё "просто работает". Но на практике это приводит к:
+
+- Неявным преобразованиям, о которых программист даже не подозревает.
+- Непредсказуемому поведению кода.
+- Трудным для отладки ошибкам, которые появляются в самых неожиданных местах.
+
+Такие ошибки особенно сложно поймать, потому что программа может «иногда работать, иногда нет» — в зависимости от типа данных, которые в неё попали.
+
+## 📌 Вывод
+
+Python — язык со строгой типизацией. Он не позволяет выполнять операции между несовместимыми типами без явного преобразования. Это делает программы надёжнее и понятнее. Мы ещё научимся преобразовывать данные из одного типа в другой — и делать это всегда сознательно.
diff --git a/modules/33-data-types/50-strong-typing/ru/data.yml b/modules/33-data-types/50-strong-typing/ru/data.yml
index 299fe45..a14cb97 100644
--- a/modules/33-data-types/50-strong-typing/ru/data.yml
+++ b/modules/33-data-types/50-strong-typing/ru/data.yml
@@ -1,5 +1,4 @@
 ---
-
 name: Сильная (или Строгая) типизация
 tips:
   - |
diff --git a/modules/33-data-types/52-data-types-immutability/ru/README.md b/modules/33-data-types/52-data-types-immutability/ru/README.md
index c4f360a..4b128ed 100644
--- a/modules/33-data-types/52-data-types-immutability/ru/README.md
+++ b/modules/33-data-types/52-data-types-immutability/ru/README.md
@@ -1,20 +1,48 @@
-
-Представим, что нам нужно изменить символ в строке. Вот, что из этого выйдет:
+Представим, что у нас есть строка, и мы хотим заменить в ней один символ — например, первую букву имени:
 
 ```python
 first_name = 'Alexander'
-first_name[0] = 'B'
-# Ошибка: TypeError: 'str' object does not support item assignment
+first_name[0] = 'B'  # ❌
+```
+
+Python сразу выдаст ошибку:
+
 ```
+TypeError: 'str' object does not support item assignment
+```
+
+Что это значит? Строки в Python нельзя изменять по частям. Как только они созданы — всё, они неизменяемы (или, как говорят программисты, иммутабельны).
+
+## 🧱 Почему строки неизменяемые?
+
+Python устроен так, что примитивные типы (строки, числа, булевы значения и т. д.) нельзя менять. Это даёт важные преимущества:
 
-Такое происходит из-за неизменяемости примитивных типов в Python — язык не дает никакой физической возможности поменять строку. Неизменяемость примитивных типов важна по многим причинам. Ключевая причина — производительность.
+- 🔐 Безопасность: значения не изменятся случайно
+- ⚡️ Производительность: с неизменяемыми объектами проще работать внутри интерпретатора
+- 🧠 Предсказуемость: меньше неожиданных эффектов при передаче данных в функции
 
-Но иногда нам нужно изменить строку. Для этого и существуют переменные:
+## 🔁 А как тогда изменить строку?
+
+Если нужно "изменить" строку — мы не редактируем её, а создаём новую строку и сохраняем в ту же переменную:
 
 ```python
 first_name = 'Alexander'
 first_name = 'Blexander'
+
 print(first_name)  # => Blexander
 ```
 
-Есть большая разница между *изменением значения переменной* и *изменением самого значения*. Примитивные типы в Python поменять нельзя, а составные — можно. Также можно без проблем заменить значение переменной.
+Переменная first_name теперь просто указывает на другую строку. Это не изменение самой строки, а замена значения переменной.
+
+## 🔄 В чём разница?
+
+Важно различать два действия:
+
+| Действие                       | Можно? | Пример                         |
+|-------------------------------|--------|--------------------------------|
+| Изменить содержимое строки    | ❌ Нет | `first_name[0] = 'B'` — ошибка |
+| Заменить значение переменной  | ✅ Да  | `first_name = 'Blexander'`     |
+
+## 📌 Вывод
+
+Примитивные типы данных в Python — такие как строки (str), целые числа (int), вещественные числа (float) и логические значения (bool) — являются неизменяемыми (immutable). Это означает, что после создания их внутреннее значение изменить нельзя. Вы не можете поменять один символ в строке или один разряд в числе — любые "изменения" происходят путём создания нового значения и переопределения переменной.
diff --git a/modules/33-data-types/52-data-types-immutability/ru/data.yml b/modules/33-data-types/52-data-types-immutability/ru/data.yml
index 3210c29..e0a8b6b 100644
--- a/modules/33-data-types/52-data-types-immutability/ru/data.yml
+++ b/modules/33-data-types/52-data-types-immutability/ru/data.yml
@@ -1,5 +1,4 @@
 ---
-
 name: |
   Неизменяемость примитивных типов
 tips: []
diff --git a/modules/33-data-types/55-data-types-casting/ru/EXERCISE.md b/modules/33-data-types/55-data-types-casting/ru/EXERCISE.md
index 3d66cb8..7e8dd14 100644
--- a/modules/33-data-types/55-data-types-casting/ru/EXERCISE.md
+++ b/modules/33-data-types/55-data-types-casting/ru/EXERCISE.md
@@ -1,4 +1,3 @@
-
 Выведите на экран строку `2 times`, полученную из числа 2.9 (хранится в переменной `value`) и строки `times`, используя преобразования типов и конкатенацию. Для этого нужно выполнить два преобразования: сначала в целое число, а затем в строку
 
 
diff --git a/modules/33-data-types/55-data-types-casting/ru/README.md b/modules/33-data-types/55-data-types-casting/ru/README.md
index acfc594..38c1934 100644
--- a/modules/33-data-types/55-data-types-casting/ru/README.md
+++ b/modules/33-data-types/55-data-types-casting/ru/README.md
@@ -1,55 +1,61 @@
+В реальных программах часто возникает ситуация, когда данные одного типа нужно превратить в другой. Это особенно актуально, например, при обработке ввода пользователя или данных из веб-форм. Там всё приходит в виде строк, даже если вы ввели число.
 
-В программировании регулярно встречаются задачи, когда один тип данных нужно преобразовать в другой — например, при работе с формами на сайтах. Данные формы всегда приходят в текстовом виде, даже если значение — число. Вот как его можно преобразовать:
+Чтобы работать с такими значениями, их нужно явно преобразовать в нужный тип. Python предоставляет для этого простые и понятные инструменты.
 
-```python
-# str станет int
+## 🔢 Преобразование строки в число
+
+Представим, что мы получили из формы строку '345', а нам нужно сложить это число с другим:
+
+```Python
 number = int('345')
-print(number)  # => 345
+print(number + 5)  # => 350
 ```
 
-`int()` — это функция, в которую передается значение, чтобы его преобразовать. Функция ведет себя подобно арифметическим операциям, но делает особые действия. Вот еще несколько примеров:
+Функция `int()` получает строку и превращает её в целое число.
+Такая функция называется функцией приведения типа (casting function).
 
-```python
+```Python
 value = '0'
-# Внутри скобок можно указывать переменную
 converted_value = int(value)
 print(converted_value)  # => 0
 
-# Или конкретное значение
-converted_value2 = int('10')
-print(converted_value2)  # => 10
+print(int('10'))        # => 10
+print(int(3.5))         # => 3  (дробная часть отбрасывается)
+```
 
-converted_value3 = int(False)
-print(converted_value3)  # => 0
+## 🧵 Преобразование в строку — str()
 
-converted_value4 = int(True)
-print(converted_value4)  # => 1
+Если нужно превратить число или логическое значение в строку, используйте функцию `str()`:
 
-# Если преобразуется число с плавающей точкой
-# то отбрасывается вся дробная часть
-converted_value5 = int(3.5)
-print(converted_value5)  # => 3
+```Python
+print(str(10))      # => '10'
+print(str(True))    # => 'True'
+print(str(3.5))     # => '3.5'
 ```
 
-https://replit.com/@hexlet/python-basics-data-types-casting
+Это полезно, например, при формировании текстов, сообщений и вывода:
 
-Точно так же можно преобразовать данные в строки `str()` и число с плавающей точкой `float()`:
+```Python
+age = 42
+print("Age: " + str(age))  # => Age: 42
+```
 
-```python
-value = str(10)
-print(value)  # '10'
+## 🌊 Преобразование в число с плавающей точкой — float()
 
-value2 = str(True)
-print(value2)  # 'True'
+Если нужно число с десятичной точкой, используйте `float()`:
 
-value3 = float(5)
-print(value3)  # 5.0
+```Python
+print(float(5))     # => 5.0
+print(float('2.7')) # => 2.7
 ```
 
-Некоторые преобразования Python выполняет автоматически. Например, в операциях, где встречается одновременно целое число и число с плавающей точкой. Python автоматически все приводит к **float** — числу с плавающей точкой:
+## 🤖 Python иногда сам преобразует типы
+
+В некоторых выражениях Python делает автоматическое приведение типов. Например, при сложении int и float он преобразует всё в float:
 
-```python
-# Неявно выполняется код float(3) + 1.2
-value = 3 + 1.2
-print(value)  # => 4.2
+```Python
+value = 3 + 1.2  # неявно выполняется float(3) + 1.2
+print(value)     # => 4.2
 ```
+
+Это удобно, но важно помнить: автоматические преобразования происходят только в ограниченных, строго определённых ситуациях. В большинстве случаев Python потребует явного преобразования — особенно при работе со строками.
diff --git a/modules/33-data-types/55-data-types-casting/ru/data.yml b/modules/33-data-types/55-data-types-casting/ru/data.yml
index ee96f5a..de286cc 100644
--- a/modules/33-data-types/55-data-types-casting/ru/data.yml
+++ b/modules/33-data-types/55-data-types-casting/ru/data.yml
@@ -1,5 +1,4 @@
 ---
-
 name: Явное преобразование типов
 tips:
   - |
diff --git a/modules/35-calling-functions/100-call/ru/data.yml b/modules/35-calling-functions/100-call/ru/data.yml
index ebcb46a..a01a8ea 100644
--- a/modules/35-calling-functions/100-call/ru/data.yml
+++ b/modules/35-calling-functions/100-call/ru/data.yml
@@ -1,5 +1,4 @@
 ---
-
 name: Функции и их вызов
 tips: []
 definitions:
diff --git a/modules/35-calling-functions/120-function-signature/ru/data.yml b/modules/35-calling-functions/120-function-signature/ru/data.yml
index eca0084..64933d3 100644
--- a/modules/35-calling-functions/120-function-signature/ru/data.yml
+++ b/modules/35-calling-functions/120-function-signature/ru/data.yml
@@ -1,5 +1,4 @@
 ---
-
 name: Сигнатура функции
 tips:
   - >
diff --git a/modules/35-calling-functions/135-calling-functions-default-arguments/ru/data.yml b/modules/35-calling-functions/135-calling-functions-default-arguments/ru/data.yml
index 3cc6cbc..5b5e439 100644
--- a/modules/35-calling-functions/135-calling-functions-default-arguments/ru/data.yml
+++ b/modules/35-calling-functions/135-calling-functions-default-arguments/ru/data.yml
@@ -1,5 +1,4 @@
 ---
-
 name: Аргументы по умолчанию
 tips: []
 definitions:
diff --git a/modules/35-calling-functions/150-calling-funcitons-expression/ru/data.yml b/modules/35-calling-functions/150-calling-funcitons-expression/ru/data.yml
index dfcfc52..3fb7edf 100644
--- a/modules/35-calling-functions/150-calling-funcitons-expression/ru/data.yml
+++ b/modules/35-calling-functions/150-calling-funcitons-expression/ru/data.yml
@@ -1,5 +1,4 @@
 ---
-
 name: Вызов функции — выражение
 definitions:
   - name: Выражение
diff --git a/modules/35-calling-functions/180-variadic-parameters/ru/data.yml b/modules/35-calling-functions/180-variadic-parameters/ru/data.yml
index 54d44af..5388dab 100644
--- a/modules/35-calling-functions/180-variadic-parameters/ru/data.yml
+++ b/modules/35-calling-functions/180-variadic-parameters/ru/data.yml
@@ -1,5 +1,4 @@
 ---
-
 name: Функции с переменным числом параметров
 tips:
   - >
diff --git a/modules/35-calling-functions/270-deterministic/ru/data.yml b/modules/35-calling-functions/270-deterministic/ru/data.yml
index 4015039..1e05afa 100644
--- a/modules/35-calling-functions/270-deterministic/ru/data.yml
+++ b/modules/35-calling-functions/270-deterministic/ru/data.yml
@@ -1,5 +1,4 @@
 ---
-
 name: Детерминированность
 tips:
   - >
diff --git a/modules/35-calling-functions/900-stdlib/ru/data.yml b/modules/35-calling-functions/900-stdlib/ru/data.yml
index 408d400..59558cb 100644
--- a/modules/35-calling-functions/900-stdlib/ru/data.yml
+++ b/modules/35-calling-functions/900-stdlib/ru/data.yml
@@ -1,5 +1,4 @@
 ---
-
 name: Стандартная библиотека
 tips:
   - |
diff --git a/modules/38-objects/100-objects/ru/data.yml b/modules/38-objects/100-objects/ru/data.yml
index a4baa17..f9cf203 100644
--- a/modules/38-objects/100-objects/ru/data.yml
+++ b/modules/38-objects/100-objects/ru/data.yml
@@ -1,5 +1,4 @@
 ---
-
 name: Объекты
 tips:
   - >
diff --git a/modules/38-objects/200-methods-immutability/ru/README.md b/modules/38-objects/200-methods-immutability/ru/README.md
index 0e1c241..3121aa0 100644
--- a/modules/38-objects/200-methods-immutability/ru/README.md
+++ b/modules/38-objects/200-methods-immutability/ru/README.md
@@ -17,5 +17,3 @@ name = 'Tirion'
 name = name.upper()
 print(name)  # => TIRION
 ```
-
-https://replit.com/@hexlet/python-basics-objects-methods-immutability
diff --git a/modules/38-objects/200-methods-immutability/ru/data.yml b/modules/38-objects/200-methods-immutability/ru/data.yml
index 1803927..8636e09 100644
--- a/modules/38-objects/200-methods-immutability/ru/data.yml
+++ b/modules/38-objects/200-methods-immutability/ru/data.yml
@@ -1,5 +1,4 @@
 ---
-
 name: Неизменяемость
 definitions:
   - name: Метод
diff --git a/modules/38-objects/300-method-expressions/ru/README.md b/modules/38-objects/300-method-expressions/ru/README.md
index a9cb0c9..d6867c5 100644
--- a/modules/38-objects/300-method-expressions/ru/README.md
+++ b/modules/38-objects/300-method-expressions/ru/README.md
@@ -18,5 +18,3 @@ num2 = 30
 # bit_length() — вычисляет количество бит, необходимых для представления числа в двоичном виде
 print(num1.bit_length() + num2.bit_length())  # => 8
 ```
-
-https://replit.com/@hexlet/python-basics-objects-method-expression
diff --git a/modules/38-objects/300-method-expressions/ru/data.yml b/modules/38-objects/300-method-expressions/ru/data.yml
index fe009d7..ad9313e 100644
--- a/modules/38-objects/300-method-expressions/ru/data.yml
+++ b/modules/38-objects/300-method-expressions/ru/data.yml
@@ -1,5 +1,4 @@
 ---
-
 name: Методы как выражения
 definitions:
   - name: Метод
diff --git a/modules/38-objects/500-method-chain/ru/data.yml b/modules/38-objects/500-method-chain/ru/data.yml
index 7360791..2266558 100644
--- a/modules/38-objects/500-method-chain/ru/data.yml
+++ b/modules/38-objects/500-method-chain/ru/data.yml
@@ -1,5 +1,4 @@
 ---
-
 name: Цепочка вызовов
 definitions:
   - name: Метод
diff --git a/modules/40-define-functions/100-define-function/ru/data.yml b/modules/40-define-functions/100-define-function/ru/data.yml
index 21bbde1..e93d548 100644
--- a/modules/40-define-functions/100-define-function/ru/data.yml
+++ b/modules/40-define-functions/100-define-function/ru/data.yml
@@ -1,7 +1,6 @@
 ---
-
 name: Создание (определение) функций
 tips:
   - >
     [Именование в
-    программировании](https://ru.hexlet.io/blog/posts/naming-in-programming)
+    программировании](https://ru.hexlet.io/blog/posts/naming-in-programming?utm_source=code-basics&utm_medium=referral&utm_campaign=blog&utm_content=lesson)
diff --git a/modules/40-define-functions/200-return/ru/README.md b/modules/40-define-functions/200-return/ru/README.md
index 3c2d2d5..2eaaac7 100644
--- a/modules/40-define-functions/200-return/ru/README.md
+++ b/modules/40-define-functions/200-return/ru/README.md
@@ -103,5 +103,3 @@ def run():
 # Что будет выведено на экран?
 print(run())
 ```
-
-https://replit.com/@hexlet/python-basics-define-functions-return
diff --git a/modules/40-define-functions/200-return/ru/data.yml b/modules/40-define-functions/200-return/ru/data.yml
index 37429f7..a3a748f 100644
--- a/modules/40-define-functions/200-return/ru/data.yml
+++ b/modules/40-define-functions/200-return/ru/data.yml
@@ -1,5 +1,4 @@
 ---
-
 name: Возврат значений
 tips:
   - |
diff --git a/modules/40-define-functions/300-parameters/ru/README.md b/modules/40-define-functions/300-parameters/ru/README.md
index 9034331..7158deb 100644
--- a/modules/40-define-functions/300-parameters/ru/README.md
+++ b/modules/40-define-functions/300-parameters/ru/README.md
@@ -63,7 +63,6 @@ text = 'Winter is coming'
 get_last_char(text)  # g
 ```
 
-https://replit.com/@hexlet/python-basics-define-functions-parameters
 
 Параметр нужно обязательно указывать. Если вызвать функцию без него, то интерпретатор выдаст ошибку:
 
diff --git a/modules/40-define-functions/300-parameters/ru/data.yml b/modules/40-define-functions/300-parameters/ru/data.yml
index ad85e61..cb0a7d8 100644
--- a/modules/40-define-functions/300-parameters/ru/data.yml
+++ b/modules/40-define-functions/300-parameters/ru/data.yml
@@ -1,5 +1,4 @@
 ---
-
 name: Параметры функций
 tips:
   - >
diff --git a/modules/40-define-functions/400-default-parameters/ru/data.yml b/modules/40-define-functions/400-default-parameters/ru/data.yml
index 480e016..152d32d 100644
--- a/modules/40-define-functions/400-default-parameters/ru/data.yml
+++ b/modules/40-define-functions/400-default-parameters/ru/data.yml
@@ -1,5 +1,4 @@
 ---
-
 name: Необязательные параметры функций
 tips:
   - >
diff --git a/modules/40-define-functions/500-named-arguments/index.py b/modules/40-define-functions/500-named-arguments/index.py
index 0a57f78..ba6ad44 100644
--- a/modules/40-define-functions/500-named-arguments/index.py
+++ b/modules/40-define-functions/500-named-arguments/index.py
@@ -1,2 +1,2 @@
 def trim_and_repeat(text, offset=0, repetitions=1):
-    return f"{text[offset:] * repetitions}"
+    return text[offset:] * repetitions
diff --git a/modules/40-define-functions/500-named-arguments/ru/README.md b/modules/40-define-functions/500-named-arguments/ru/README.md
index 18d081b..a54f2ef 100644
--- a/modules/40-define-functions/500-named-arguments/ru/README.md
+++ b/modules/40-define-functions/500-named-arguments/ru/README.md
@@ -32,7 +32,7 @@ truncate(length=3, text='My Text')
 Последнее полезно, если у функции много необязательных параметров. Посмотрим на примере:
 
 ```python
-def f(a=1, b=2, c=None, d=4):
+def print_params(a=1, b=2, c=None, d=4):
     print(a, b, c, d)
 
 # Нужно передать только d, но приходится передавать все
diff --git a/modules/40-define-functions/500-named-arguments/ru/data.yml b/modules/40-define-functions/500-named-arguments/ru/data.yml
index 3570268..4ed9c18 100644
--- a/modules/40-define-functions/500-named-arguments/ru/data.yml
+++ b/modules/40-define-functions/500-named-arguments/ru/data.yml
@@ -1,3 +1,2 @@
 ---
-
 name: Именованные аргументы
diff --git a/modules/40-define-functions/600-type-annotations/ru/data.yml b/modules/40-define-functions/600-type-annotations/ru/data.yml
index 3874e23..2b0fe5e 100644
--- a/modules/40-define-functions/600-type-annotations/ru/data.yml
+++ b/modules/40-define-functions/600-type-annotations/ru/data.yml
@@ -1,3 +1,2 @@
 ---
-
 name: Аннотации типов
diff --git a/modules/45-logic/10-bool-type/ru/data.yml b/modules/45-logic/10-bool-type/ru/data.yml
index bce7b78..8d155aa 100644
--- a/modules/45-logic/10-bool-type/ru/data.yml
+++ b/modules/45-logic/10-bool-type/ru/data.yml
@@ -1,5 +1,4 @@
 ---
-
 name: Логический тип
 tips:
   - >
diff --git a/modules/45-logic/15-predicates/ru/data.yml b/modules/45-logic/15-predicates/ru/data.yml
index df4b1b3..18ecbd6 100644
--- a/modules/45-logic/15-predicates/ru/data.yml
+++ b/modules/45-logic/15-predicates/ru/data.yml
@@ -1,10 +1,9 @@
 ---
-
 name: Предикаты
 tips:
   - >
     [Именование в
-    программировании](https://ru.hexlet.io/blog/posts/naming-in-programming)
+    программировании](https://ru.hexlet.io/blog/posts/naming-in-programming?utm_source=code-basics&utm_medium=referral&utm_campaign=blog&utm_content=lesson)
 definitions:
   - name: Предикат
     description: выражение, отвечающее на вопрос «да» или «нет» с помощью типа bool.
diff --git a/modules/45-logic/20-logic-combine-expressions/ru/EXERCISE.md b/modules/45-logic/20-logic-combine-expressions/ru/EXERCISE.md
index f67e136..d05cdb8 100644
--- a/modules/45-logic/20-logic-combine-expressions/ru/EXERCISE.md
+++ b/modules/45-logic/20-logic-combine-expressions/ru/EXERCISE.md
@@ -1,5 +1,5 @@
 
-Реализуйте функцию `is_international_phone()`, которая проверяет формат указанного телефона. Если телефон начинается с *+*, значит это международный формат.
+Реализуйте функцию `is_international_phone()`, которая принимает на вход строку - номер телефона и проверяет его формат. Если телефон начинается с *+*, значит это международный формат.
 
 ```python
 is_international_phone('89602223423')  # False
diff --git a/modules/45-logic/20-logic-combine-expressions/ru/data.yml b/modules/45-logic/20-logic-combine-expressions/ru/data.yml
index 3f4ac90..c01f64c 100644
--- a/modules/45-logic/20-logic-combine-expressions/ru/data.yml
+++ b/modules/45-logic/20-logic-combine-expressions/ru/data.yml
@@ -1,5 +1,4 @@
 ---
-
 name: Комбинирование операций и функций
 tips:
   - |
diff --git a/modules/45-logic/25-logical-operators/ru/EXERCISE.md b/modules/45-logic/25-logical-operators/ru/EXERCISE.md
index 7c82bf3..db562ae 100644
--- a/modules/45-logic/25-logical-operators/ru/EXERCISE.md
+++ b/modules/45-logic/25-logical-operators/ru/EXERCISE.md
@@ -1,5 +1,5 @@
 
-Реализуйте метод `is_leap_year()`, который определяет является ли год високосным или нет. Год будет високосным, если он кратен (то есть делится без остатка) 400 или он одновременно кратен 4 и не кратен 100. Как видите, в определении уже заложена вся необходимая логика, осталось только переложить её на код:
+Реализуйте функцию `is_leap_year()`, которая принимает год в форме числа и определяет является ли он високосным или нет. Год будет високосным, если он кратен (то есть делится без остатка) 400 или он одновременно кратен 4 и не кратен 100. Как видите, в определении уже заложена вся необходимая логика, осталось только переложить её на код:
 
 ```python
 is_leap_year(2018) # false
diff --git a/modules/45-logic/25-logical-operators/ru/README.md b/modules/45-logic/25-logical-operators/ru/README.md
index 179190f..ff78f07 100644
--- a/modules/45-logic/25-logical-operators/ru/README.md
+++ b/modules/45-logic/25-logical-operators/ru/README.md
@@ -5,7 +5,7 @@
 
 > Пароль длиннее 8 символов **И** пароль содержит хотя бы одну заглавную букву
 
-Вот функция, которая принимает пароль и говорит, соответствует ли он условиям (`True`) или не соответствует (`False`):  
+Вот функция, которая принимает пароль и говорит, соответствует ли он условиям (`True`) или не соответствует (`False`):
 
 ```python
 def has_capital_letter(string):
@@ -24,12 +24,11 @@ print(is_correct_password('qwerty1234'))               # => False
 
 Кроме `and` часто используется оператор `or` — «ИЛИ» (дизъюнкция). Он означает «или то, или другое, или оба». Выражение `a or b` считается истинным, если хотя бы один из операндов или одновременно все — истинные. В другом случае выражение ложное.
 
-Операторы можно комбинировать в любом количестве и любой последовательности. Если в коде одновременно встречаются `and` и `or`, то приоритет задают скобками. Ниже пример расширенной функции, которая определяет корректность пароля:
+Операторы можно комбинировать в любом количестве и любой последовательности. Если в коде одновременно встречаются `and` и `or`, то приоритет лучше задавать скобками. Ниже пример расширенной функции, которая определяет корректность пароля:
 
 ```python
 def has_capital_letter(string):
     # Проверяет наличие хотя бы одной заглавной буквы в строке
-
 def has_special_chars(string):
     # Проверяет содержание специальных символов в строке
 
@@ -56,7 +55,6 @@ print(is_good_apartment(120, 'Main Street'))    # => True
 print(is_good_apartment(80, 'Main Street'))     # => True
 ```
 
-https://replit.com/@hexlet/python-basics-logic-logical-operators
 
 Область математики, в которой изучаются логические операторы, называется булевой алгеброй. Ниже увидите **таблицы истинности** — по ним можно определить, каким будет результат, если применить оператора:
 
diff --git a/modules/45-logic/25-logical-operators/ru/data.yml b/modules/45-logic/25-logical-operators/ru/data.yml
index 3c85e64..104d635 100644
--- a/modules/45-logic/25-logical-operators/ru/data.yml
+++ b/modules/45-logic/25-logical-operators/ru/data.yml
@@ -1,5 +1,4 @@
 ---
-
 name: Логические операторы
 tips:
   - |
diff --git a/modules/45-logic/28-logical-negation/ru/EXERCISE.md b/modules/45-logic/28-logical-negation/ru/EXERCISE.md
index 787f3ac..c1ac703 100644
--- a/modules/45-logic/28-logical-negation/ru/EXERCISE.md
+++ b/modules/45-logic/28-logical-negation/ru/EXERCISE.md
@@ -1,5 +1,5 @@
 
-В этом уроке вам нужно будет реализовать две функции `is_palindrome()` и `is_not_palindrome()`
+В этом уроке вам нужно будет реализовать две функции `is_palindrome()` и `is_not_palindrome()`, принимающие строку на вход
 
 1. Реализуйте функцию `is_palindrome()`, которая определяет, является ли слово палиндромом или нет. Палиндром - это слово, которое читается одинаково в обоих направлениях. Слова в функцию могут быть переданы в любом регистре, поэтому сначала нужно привести слово к нижнему регистру: `word.lower()`.
 
diff --git a/modules/45-logic/28-logical-negation/ru/README.md b/modules/45-logic/28-logical-negation/ru/README.md
index 65bcac2..c30eae2 100644
--- a/modules/45-logic/28-logical-negation/ru/README.md
+++ b/modules/45-logic/28-logical-negation/ru/README.md
@@ -26,7 +26,6 @@ print(not is_even(10))  # => False
 print(not not is_even(10))  # => True
 ```
 
-https://replit.com/@hexlet/python-basics-logic-logical-negation
 
 В логике двойное отрицание — это отсутствие отрицания:
 
diff --git a/modules/45-logic/28-logical-negation/ru/data.yml b/modules/45-logic/28-logical-negation/ru/data.yml
index 198f264..b823220 100644
--- a/modules/45-logic/28-logical-negation/ru/data.yml
+++ b/modules/45-logic/28-logical-negation/ru/data.yml
@@ -1,5 +1,4 @@
 ---
-
 name: Отрицание
 tips:
   - |
diff --git a/modules/45-logic/90-logical-expressions/ru/EXERCISE.md b/modules/45-logic/90-logical-expressions/ru/EXERCISE.md
index 27ee259..bd21905 100644
--- a/modules/45-logic/90-logical-expressions/ru/EXERCISE.md
+++ b/modules/45-logic/90-logical-expressions/ru/EXERCISE.md
@@ -14,5 +14,3 @@ string_or_not(False) # 'no'
 isinstance(3, str) # False
 isinstance('Hexlet', str) # True
 ```
-
-Поэкспериментируйте с кодом в интерактивном репле https://replit.com/@hexlet/python-basics-logical-expressions
diff --git a/modules/45-logic/90-logical-expressions/ru/README.md b/modules/45-logic/90-logical-expressions/ru/README.md
index d742c88..f43124d 100644
--- a/modules/45-logic/90-logical-expressions/ru/README.md
+++ b/modules/45-logic/90-logical-expressions/ru/README.md
@@ -28,7 +28,7 @@ print(0 or False or '' or [] or 42 or "Hello")  ## 42
 - Число `42` эквивалентно `True`
 - Строка `"Hello"` также эквивалентна `True`
 
-Оператор **ИЛИ** будет проверять значения слева направо, и возвращает первый аргумент, который может быть преобразован в `True`. В данном примере это число `42`. 
+Оператор **ИЛИ** будет проверять значения слева направо, и возвращает первый аргумент, который может быть преобразован в `True`. В данном примере это число `42`.
 
 Пример с оператором **И**:
 
@@ -104,7 +104,7 @@ print(11 % 2 == 0 and 'yes' or 'no') # => 'no'
 # 1 шаг
 10 % 2 == 0 # True
 # 2 шаг
-True and 'yes' # Результат — истина
+True and 'yes' # Результат — 'yes'
 # Проверка на or выполняется, но правая часть не исполняется, так как сразу возвращается 'yes'
 
 # Для нечетного
@@ -122,8 +122,6 @@ False or 'no' # Выбирается и возвращается 'no'
 print(somefunc() and 'yes' or 'no')
 ```
 
-Можете проверить себя и поэкспериментировать с кодом в [Replit](https://replit.com/@hexlet/python-basics-logical-expressions).
-
 ## Двойное отрицание
 
 Напомним, как выглядит операция отрицания:
diff --git a/modules/45-logic/90-logical-expressions/ru/data.yml b/modules/45-logic/90-logical-expressions/ru/data.yml
index ac3d5af..fb64557 100644
--- a/modules/45-logic/90-logical-expressions/ru/data.yml
+++ b/modules/45-logic/90-logical-expressions/ru/data.yml
@@ -1,5 +1,4 @@
 ---
-
 name: Результат логических выражений
 tips:
   - |
diff --git a/modules/48-conditionals/30-if/ru/README.md b/modules/48-conditionals/30-if/ru/README.md
index 891800f..e2a0cd0 100644
--- a/modules/48-conditionals/30-if/ru/README.md
+++ b/modules/48-conditionals/30-if/ru/README.md
@@ -16,13 +16,13 @@ print(get_type_of_sentence('Hodor?'))  # => question
 
 https://replit.com/@hexlet/python-basics-conditionals-if
 
-`if` — конструкция языка, которая управляет порядком выполнения инструкций. После слова `if` ей передается выражение-предикат, и в конце ставится двоеточие. После этого с новой строки и после отступа в 4 пробела описывается блок кода. Он выполнится, если предикат — истина.
+`if` — конструкция языка, которая управляет порядком выполнения инструкций. После слова `if` ей передается выражение-предикат, и в конце ставится двоеточие. После этого описывается блок кода. Он выполнится, если предикат — истина.
 
 Если предикат — ложь, то блок кода пропускается, и функция продолжает свое выполнение дальше. В нашем случае следующая строчка кода — `return 'normal'` — заставит функцию вернуть строку и завершиться.
 
 `return` может находиться в любом месте функции — даже внутри блока кода с условием.
 
-Обратите внимание, на отступы. В python, в отличие от других языков, блоки кода принято выделять не скобками, а новой строкой с отступом. Отступы обычно состоят из 4 пробелов или одного символа табуляции, который нужно настроить в редакторе на использование пробелов. Все строки в одном блоке должны иметь одинаковый отступ. Увеличение отступа означает начало нового блока, а уменьшение отступа означает конец блока.
+Обратите внимание, на отступы. В Python, в отличие от других языков, блоки кода принято выделять не скобками, а новой строкой с отступом. Отступы обычно состоят из 4 пробелов или одного символа табуляции, который нужно настроить в редакторе на использование пробелов. Все строки в одном блоке должны иметь одинаковый отступ. Увеличение отступа означает начало нового блока, а уменьшение отступа означает конец блока.
 
 ```python
     if a == 42:
diff --git a/modules/48-conditionals/30-if/ru/data.yml b/modules/48-conditionals/30-if/ru/data.yml
index ef71b51..8708e90 100644
--- a/modules/48-conditionals/30-if/ru/data.yml
+++ b/modules/48-conditionals/30-if/ru/data.yml
@@ -1,5 +1,4 @@
 ---
-
 name: Условная конструкция (if)
 tips: []
 definitions:
diff --git a/modules/48-conditionals/40-if-else/ru/data.yml b/modules/48-conditionals/40-if-else/ru/data.yml
index 4378ac3..c1d3fdc 100644
--- a/modules/48-conditionals/40-if-else/ru/data.yml
+++ b/modules/48-conditionals/40-if-else/ru/data.yml
@@ -1,5 +1,4 @@
 ---
-
 name: Условная конструкция else
 tips: []
 definitions:
diff --git a/modules/48-conditionals/50-else-if/ru/data.yml b/modules/48-conditionals/50-else-if/ru/data.yml
index c1c35a4..2dadb52 100644
--- a/modules/48-conditionals/50-else-if/ru/data.yml
+++ b/modules/48-conditionals/50-else-if/ru/data.yml
@@ -1,5 +1,4 @@
 ---
-
 name: Конструкция else + if = elif
 tips: []
 definitions:
diff --git a/modules/48-conditionals/60-ternary-operator/ru/data.yml b/modules/48-conditionals/60-ternary-operator/ru/data.yml
index 26b130a..c3495e5 100644
--- a/modules/48-conditionals/60-ternary-operator/ru/data.yml
+++ b/modules/48-conditionals/60-ternary-operator/ru/data.yml
@@ -1,5 +1,4 @@
 ---
-
 name: Тернарный оператор
 tips: []
 definitions:
diff --git a/modules/48-conditionals/65-match/ru/data.yml b/modules/48-conditionals/65-match/ru/data.yml
index 09d92e8..70f53a2 100644
--- a/modules/48-conditionals/65-match/ru/data.yml
+++ b/modules/48-conditionals/65-match/ru/data.yml
@@ -1,5 +1,4 @@
 ---
-
 name: Оператор Match
 tips:
   - >
diff --git a/modules/50-loops/10-while/ru/README.md b/modules/50-loops/10-while/ru/README.md
index c5228dd..38c6123 100644
--- a/modules/50-loops/10-while/ru/README.md
+++ b/modules/50-loops/10-while/ru/README.md
@@ -52,7 +52,6 @@ print_numbers(3)
 # => finished!
 ```
 
-https://replit.com/@hexlet/python-basics-loops-while
 
 Цикл `while` состоит из трех элементов:
 
diff --git a/modules/50-loops/10-while/ru/data.yml b/modules/50-loops/10-while/ru/data.yml
index d400bc2..53c07ee 100644
--- a/modules/50-loops/10-while/ru/data.yml
+++ b/modules/50-loops/10-while/ru/data.yml
@@ -1,5 +1,4 @@
 ---
-
 name: Цикл While
 tips:
   - |
diff --git a/modules/50-loops/20-aggregation-numbers/ru/EXERCISE.md b/modules/50-loops/20-aggregation-numbers/ru/EXERCISE.md
index 931cd67..a140b17 100644
--- a/modules/50-loops/20-aggregation-numbers/ru/EXERCISE.md
+++ b/modules/50-loops/20-aggregation-numbers/ru/EXERCISE.md
@@ -1,5 +1,5 @@
 
-Реализуйте функцию `multiply_numbers_from_range()`, которая перемножает числа в указанном диапазоне включая границы диапазона. Пример вызова:
+Реализуйте функцию `multiply_numbers_from_range()`, которая принимает два числа, границы диапазона, и перемножает числа в нем, включая границы диапазона. Пример вызова:
 
 ```python
 multiply_numbers_from_range(1, 5)  # 1 * 2 * 3 * 4 * 5 = 120
diff --git a/modules/50-loops/20-aggregation-numbers/ru/README.md b/modules/50-loops/20-aggregation-numbers/ru/README.md
index 3430c8c..d9e211c 100644
--- a/modules/50-loops/20-aggregation-numbers/ru/README.md
+++ b/modules/50-loops/20-aggregation-numbers/ru/README.md
@@ -37,7 +37,6 @@ def sum_numbers_from_range(start, finish):
     return sum
 ```
 
-https://replit.com/@hexlet/python-basics-loops-aggregation-numbers
 
 Структура цикла здесь стандартная: есть счетчик, который инициализируется начальным значением диапазона, цикл с условием остановки при достижении конца диапазона и изменение счетчика в конце тела цикла. Количество итераций в таком цикле равно `finish - start + 1`. Для диапазона [5, 7] — это 7 - 5 + 1, то есть три итерации.
 
diff --git a/modules/50-loops/20-aggregation-numbers/ru/data.yml b/modules/50-loops/20-aggregation-numbers/ru/data.yml
index e889745..2a6fabb 100644
--- a/modules/50-loops/20-aggregation-numbers/ru/data.yml
+++ b/modules/50-loops/20-aggregation-numbers/ru/data.yml
@@ -1,5 +1,4 @@
 ---
-
 name: Агрегация данных (Числа)
 tips:
   - |
diff --git a/modules/50-loops/20-aggregation-numbers/test_code.py b/modules/50-loops/20-aggregation-numbers/test_code.py
index 61630e8..06ad392 100644
--- a/modules/50-loops/20-aggregation-numbers/test_code.py
+++ b/modules/50-loops/20-aggregation-numbers/test_code.py
@@ -5,3 +5,4 @@ def test1():
     assert index.multiply_numbers_from_range(2, 2) == 2
     assert index.multiply_numbers_from_range(1, 3) == 6
     assert index.multiply_numbers_from_range(1, 5) == 120
+    assert index.multiply_numbers_from_range(6, 6) == 6
diff --git a/modules/50-loops/23-aggregation-strings/ru/EXERCISE.md b/modules/50-loops/23-aggregation-strings/ru/EXERCISE.md
index 00bbc44..b0eeb2b 100644
--- a/modules/50-loops/23-aggregation-strings/ru/EXERCISE.md
+++ b/modules/50-loops/23-aggregation-strings/ru/EXERCISE.md
@@ -1,5 +1,5 @@
 
-Реализуйте функцию `join_numbers_from_range()`, которая объединяет все числа из диапазона в строку:
+Реализуйте функцию `join_numbers_from_range()`, которая объединяет все числа из переданного диапазона в строку:
 
 ```python
 join_numbers_from_range(1, 1)   # '1'
diff --git a/modules/50-loops/23-aggregation-strings/ru/README.md b/modules/50-loops/23-aggregation-strings/ru/README.md
index be61f38..b56cae5 100644
--- a/modules/50-loops/23-aggregation-strings/ru/README.md
+++ b/modules/50-loops/23-aggregation-strings/ru/README.md
@@ -23,7 +23,6 @@ def repeat(text, times):
     return result
 ```
 
-https://replit.com/@hexlet/python-basics-loops-aggregation-strings
 
 Распишем выполнение этого кода по шагам:
 
diff --git a/modules/50-loops/23-aggregation-strings/ru/data.yml b/modules/50-loops/23-aggregation-strings/ru/data.yml
index ddb569c..8b66212 100644
--- a/modules/50-loops/23-aggregation-strings/ru/data.yml
+++ b/modules/50-loops/23-aggregation-strings/ru/data.yml
@@ -1,5 +1,4 @@
 ---
-
 name: Агрегация данных (Строки)
 tips:
   - |
diff --git a/modules/50-loops/25-iteration-over-string/ru/README.md b/modules/50-loops/25-iteration-over-string/ru/README.md
index 821e409..2bc666a 100644
--- a/modules/50-loops/25-iteration-over-string/ru/README.md
+++ b/modules/50-loops/25-iteration-over-string/ru/README.md
@@ -21,6 +21,5 @@ print_name_by_symbol(name)
 # => 'a'
 ```
 
-https://replit.com/@hexlet/python-basics-loops-iteration-over-string
 
 Главное в этом коде — поставить правильное условие в `while`. Это можно сделать двумя способами: `i < len(name)` или `i <= len(name) - 1` — они приведут к одному результату.
diff --git a/modules/50-loops/25-iteration-over-string/ru/data.yml b/modules/50-loops/25-iteration-over-string/ru/data.yml
index 512b81b..365a7f6 100644
--- a/modules/50-loops/25-iteration-over-string/ru/data.yml
+++ b/modules/50-loops/25-iteration-over-string/ru/data.yml
@@ -1,5 +1,4 @@
 ---
-
 name: Обход строк
 tips:
   - |
diff --git a/modules/50-loops/26-conditions-inside-loops/ru/README.md b/modules/50-loops/26-conditions-inside-loops/ru/README.md
index 6095f45..24e1d8e 100644
--- a/modules/50-loops/26-conditions-inside-loops/ru/README.md
+++ b/modules/50-loops/26-conditions-inside-loops/ru/README.md
@@ -27,7 +27,6 @@ def count_chars(string, char):
     return count
 ```
 
-https://replit.com/@hexlet/python-basics-loops-conditions-inside-loops
 
 Это агрегирующая задача. Несмотря на то, что она считает не все символы, чтобы подсчитать сумму, приходится анализировать каждый символ. Ключевое отличие этого цикла от рассмотренных — внутри тела есть условие.
 
diff --git a/modules/50-loops/26-conditions-inside-loops/ru/data.yml b/modules/50-loops/26-conditions-inside-loops/ru/data.yml
index caa103c..bfc9409 100644
--- a/modules/50-loops/26-conditions-inside-loops/ru/data.yml
+++ b/modules/50-loops/26-conditions-inside-loops/ru/data.yml
@@ -1,4 +1,3 @@
 ---
-
 name: Условия внутри тела цикла
 tips: []
diff --git a/modules/50-loops/28-build-string/ru/EXERCISE.md b/modules/50-loops/28-build-string/ru/EXERCISE.md
index a1b8582..02a0bd1 100644
--- a/modules/50-loops/28-build-string/ru/EXERCISE.md
+++ b/modules/50-loops/28-build-string/ru/EXERCISE.md
@@ -1,5 +1,5 @@
 
-Реализуйте функцию `my_substr()`, которая извлекает из строки подстроку указанной длины. Она принимает на вход два аргумента: строку и длину, и возвращает подстроку, начиная с первого символа:
+Реализуйте функцию `my_substr()`, которая извлекает из переданной строки подстроку указанной длины. Она принимает на вход два аргумента: строку и длину, и возвращает подстроку, начиная с первого символа:
 
 Пример вызова:
 
diff --git a/modules/50-loops/28-build-string/ru/README.md b/modules/50-loops/28-build-string/ru/README.md
index 22820ca..e9fc9c4 100644
--- a/modules/50-loops/28-build-string/ru/README.md
+++ b/modules/50-loops/28-build-string/ru/README.md
@@ -38,8 +38,6 @@ reverse_string('')  # ''
 * `index = index - 1` — обновляем счетчик
 * `return reversed_string` — когда цикл завершился, возвращаем строку-результат
 
-Советуем скопировать эту функцию в [https://replit.com/languages/python3](https://replit.com/languages/python3) и поэкспериментировать с ней.
-
 Работая со строками, программисты часто допускают ошибку — выходят за границы строки. Если неправильно подобрать начальное значение счетчика или допустить ошибку в предикате цикла, функция может обращаться к несуществующему символу.
 
 Особенно часто забывают, что индекс последнего элемента всегда меньше на единицу размера строки. В строках начальный индекс равен `0`, значит, индекс последнего элемента — `len(str) - 1`.
diff --git a/modules/50-loops/28-build-string/ru/data.yml b/modules/50-loops/28-build-string/ru/data.yml
index eda369e..7781ba3 100644
--- a/modules/50-loops/28-build-string/ru/data.yml
+++ b/modules/50-loops/28-build-string/ru/data.yml
@@ -1,5 +1,4 @@
 ---
-
 name: Формирование строк в циклах
 tips:
   - |
diff --git a/modules/50-loops/29-edge-cases/ru/data.yml b/modules/50-loops/29-edge-cases/ru/data.yml
index e7f9e9d..272c161 100644
--- a/modules/50-loops/29-edge-cases/ru/data.yml
+++ b/modules/50-loops/29-edge-cases/ru/data.yml
@@ -1,4 +1,3 @@
 ---
-
 name: Пограничные случаи
 tips: []
diff --git a/modules/50-loops/30-syntactic-sugar/ru/data.yml b/modules/50-loops/30-syntactic-sugar/ru/data.yml
index 5caaae5..cebb736 100644
--- a/modules/50-loops/30-syntactic-sugar/ru/data.yml
+++ b/modules/50-loops/30-syntactic-sugar/ru/data.yml
@@ -1,5 +1,4 @@
 ---
-
 name: Синтаксический сахар
 tips:
   - |
diff --git a/modules/50-loops/30-syntactic-sugar/test_code.py b/modules/50-loops/30-syntactic-sugar/test_code.py
index 3641afc..1504c4a 100644
--- a/modules/50-loops/30-syntactic-sugar/test_code.py
+++ b/modules/50-loops/30-syntactic-sugar/test_code.py
@@ -6,4 +6,3 @@ def test1():
     assert index.filter_string(text, "w") == "If I look back I am lost"
     assert index.filter_string(text, "I") == "f  look back  am lost"
     assert index.filter_string("zz zorro", "z") == " orro"
-    assert index.filter_string(text, "i") == text
diff --git a/modules/50-loops/55-return-from-loops/ru/EXERCISE.md b/modules/50-loops/55-return-from-loops/ru/EXERCISE.md
index 64bd8b6..bec62bd 100644
--- a/modules/50-loops/55-return-from-loops/ru/EXERCISE.md
+++ b/modules/50-loops/55-return-from-loops/ru/EXERCISE.md
@@ -1,5 +1,5 @@
 
-Реализуйте функцию `is_contains_char()`, которая проверяет с учётом регистра, содержит ли строка указанную букву. Функция принимает два параметра:
+Реализуйте функцию `is_contains_char()`, которая проверяет с учётом регистра, содержит ли переданная строка указанную букву. Функция принимает два параметра:
 
 * Строка
 * Буква для поиска
diff --git a/modules/50-loops/55-return-from-loops/ru/README.md b/modules/50-loops/55-return-from-loops/ru/README.md
index 35921d9..2d530e0 100644
--- a/modules/50-loops/55-return-from-loops/ru/README.md
+++ b/modules/50-loops/55-return-from-loops/ru/README.md
@@ -29,7 +29,6 @@ print(is_prime(3))  # => True
 print(is_prime(4))  # => False
 ```
 
-https://replit.com/@hexlet/python-basics-loops-return-from-loops
 
 *Если быть честными до конца, то для решения задачи хватит проверки чисел до значения квадратного корня `number`, но в нашем случае важно сосредоточиться на понимании работы с условиями внутри цикла*
 
diff --git a/modules/50-loops/55-return-from-loops/ru/data.yml b/modules/50-loops/55-return-from-loops/ru/data.yml
index c8e33a8..5588c99 100644
--- a/modules/50-loops/55-return-from-loops/ru/data.yml
+++ b/modules/50-loops/55-return-from-loops/ru/data.yml
@@ -1,5 +1,4 @@
 ---
-
 name: Возврат из циклов
 tips:
   - '[Список простых чисел](https://ru.wikipedia.org/wiki/Список_простых_чисел)'
diff --git a/modules/50-loops/70-for/ru/README.md b/modules/50-loops/70-for/ru/README.md
index 025e4a3..6f4c8fc 100644
--- a/modules/50-loops/70-for/ru/README.md
+++ b/modules/50-loops/70-for/ru/README.md
@@ -41,7 +41,7 @@ reverse_string('go!')  # => '!og'
 
 1. В первой итерации в цикле `result` равен пустой строке, `char` равен первому символу 'g'. Поэтому в `result` присваивается символ 'g' плюс пустая строка, в итоге сохраняется только символ 'g'
 2. На второй итерации `result` уже хранит символ 'g', а `char` равен следующему символу 'o'. В `result` записывается `char + result`, то есть `'o' + 'g'`
-3. На последней итерации в `result` хранится строка 'og', а `char` равен последнему символу '!'. В `result` теперь сохраняется `'og' + '!'`
+3. На последней итерации в `result` хранится строка 'og', а `char` равен последнему символу '!'. В `result` теперь сохраняется `'!' + 'og'`
 
 Теперь посчитаем количество упоминаний символа в строке без учета регистра:
 
@@ -65,5 +65,3 @@ chars_count('hExlet!', 'E')  # 2
 
 chars_count('hexlet!', 'a')  # 0
 ```
-
-Советуем поэкспериментировать с примерами выше в интерактивном [Replit](https://replit.com/@hexlet/python-basics-for-loop#main.py).
diff --git a/modules/50-loops/70-for/ru/data.yml b/modules/50-loops/70-for/ru/data.yml
index ff4a469..4ed8bb5 100644
--- a/modules/50-loops/70-for/ru/data.yml
+++ b/modules/50-loops/70-for/ru/data.yml
@@ -1,5 +1,4 @@
 ---
-
 name: Цикл For
 tips: []
 definitions:
diff --git a/modules/50-loops/80-for-in-range/ru/EXERCISE.md b/modules/50-loops/80-for-in-range/ru/EXERCISE.md
index 99c3124..0d7e357 100644
--- a/modules/50-loops/80-for-in-range/ru/EXERCISE.md
+++ b/modules/50-loops/80-for-in-range/ru/EXERCISE.md
@@ -1,4 +1,3 @@
-
 Реализуйте функцию `print_table_of_squares(first, last)`, которая печатает на экран квадраты чисел. Она первое `first` и последнее `last` число печатает строку `square of <число> is <результат>`
 
 Примеры вызова:
diff --git a/modules/50-loops/80-for-in-range/ru/README.md b/modules/50-loops/80-for-in-range/ru/README.md
index c83087f..ae101e4 100644
--- a/modules/50-loops/80-for-in-range/ru/README.md
+++ b/modules/50-loops/80-for-in-range/ru/README.md
@@ -27,7 +27,6 @@ print(sum) # => 45
 
 Первый пример использует `while`, который продолжает работать пока `i < 10`. Второй использует `for` и выполняет итерацию от 0 до 9 с помощью функции `range()`. Оба выполняют одно и то же: складывают числа от 0 до 9 в переменную `sum`, но используют разные способы выполнения итераций.
 
-
 ## Функция `range()`
 
 Функция range в Python является встроенной функцией, которая создает последовательность чисел внутри определенного диапазона. Ее можно использовать в цикле for для контроля количества итераций.
diff --git a/modules/50-loops/80-for-in-range/ru/data.yml b/modules/50-loops/80-for-in-range/ru/data.yml
index 86231e7..0125cf0 100644
--- a/modules/50-loops/80-for-in-range/ru/data.yml
+++ b/modules/50-loops/80-for-in-range/ru/data.yml
@@ -1,5 +1,4 @@
 ---
-
 name: Цикл for и функция range
 tips: []
 definitions: []
diff --git a/modules/50-loops/80-for-in-range/test_code.py b/modules/50-loops/80-for-in-range/test_code.py
index 7f38301..7135b5e 100644
--- a/modules/50-loops/80-for-in-range/test_code.py
+++ b/modules/50-loops/80-for-in-range/test_code.py
@@ -1,5 +1,4 @@
 from index import print_table_of_squares
-
 from hexlet.test import expect_output