Введение

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

Но правда в том, что для решения 80% повседневных задач — будь то автоматизация рутины, написание парсера, простой анализ данных или скрипт для Raspberry Pi — вам не нужно объектно-ориентированное программирование. Вам не нужны сложные иерархии классов, инкапсуляция и полиморфизм. Вам нужно просто писать код, который работает.

Эта статья — концентрат синтаксиса Python.
Мы намеренно выносим за скобки ООП. Здесь не будет ключевого слова class, self и __init__. Мы сосредоточимся на процедурном стиле: переменных, логике, циклах, функциях и работе с данными.

Для кого этот материал:

  • Для полных новичков, которые хотят написать первую программу «сегодня вечером», а не через месяц теории.

  • Для разработчиков на C++/Java/C#, которым нужно быстро «въехать» в синтаксис Python, чтобы написать скрипт для CI/CD или тестов.

  • Для тех, кому нужна шпаргалка, чтобы освежить память.

Инструментарий:
Чтобы повторять примеры из статьи, вам понадобится интерпретатор.

  1. Если хотите локально: скачайте Python с официального сайта и поставьте любую удобную IDE (VS Code, PyCharm Community или простой Thonny).

  2. Если лень что-то ставить: откройте любой онлайн-компилятор прямо в браузере.

Блок 1: Фундамент

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

Как создать и запустить скрипт

Программы на Python — это обычные текстовые файлы с расширением .py.

  1. Создайте файл с любым названием, например main.py.

  2. Откройте его в редакторе кода (VS Code, Notepad++, PyCharm).

  3. Напишите первую команду:

    print("Hello, Habr!")
    
  4. Сохраните файл.

Запуск:
Откройте терминал (консоль), перейдите в папку с файлом и выполните команду:
python main.py
(На macOS/Linux иногда требуется писать python3 main.py).

Если вы видите вывод в консоли — среда настроена верно.

Синтаксис: Отступы и комментарии

В Python структура кода определяется отступами, а не фигурными скобками {}. Это строгое правило интерпретатора.

  • Стандарт (PEP 8) требует использовать 4 пробела для одного уровня отступа.

  • Символ # используется для однострочных комментариев (интерпретатор их игнорирует).

# Это комментарий
x = 10
if x > 5:
    # Этот код выполнится, только если условие верно,
    # потому что здесь есть отступ в 4 пробела
    print("x больше 5")
print("Этот код выполнится в любом случае")

Переменные и динамическая типизация

Python — язык с динамической типизацией. Вам не нужно указывать тип переменной при создании. Тип определяется автоматически в момент присваивания значения.

var = 10          # var теперь int (целое число)
var = "Text"      # var теперь str (строка) — так можно, но не рекомендуется

Базовые типы данных

1. Числа (Numbers)

Основные числовые типы: int (целые) и float (дробные).
Арифметические операции:

x = 10
y = 3

print(x + y)   # 13 (сложение)
print(x - y)   # 7 (вычитание)
print(x * y)   # 30 (умножение)
print(x / y)   # 3.333... (обычное деление — всегда возвращает float)
print(x // y)  # 3 (целочисленное деление — отбрасывает дробную часть)
print(x % y)   # 1 (остаток от деления)
print(x ** y)  # 1000 (возведение в степень)

2. Строки (Strings)

Строки заключаются в одинарные ' или двойные " кавычки.

f-строки (Форматирование):
Самый современный способ вставки переменных в строку. Перед кавычками ставится f, переменные пишутся в {}.

name = "User"
score = 150
print(f"Игрок {name} набрал {score} очков.")
# Вывод: Игрок User набрал 150 очков.

Срезы (Slicing):
Позволяют получить часть строки.
Синтаксис: строка[старт : стоп : шаг].
Важно: Индексация начинается с 0. Верхняя граница (стоп) не включается в результат.

s = "Python"
print(s[0])     # 'P' (первый символ)
print(s[-1])    # 'n' (последний символ)
print(s[0:2])   # 'Py' (символы с индексами 0 и 1)
print(s[::-1])  # 'nohtyP' (строка задом наперед)

3. Логический тип (Bool)

Имеет всего два значения: True (Истина) и False (Ложь). Обязательно писать с большой буквы.
Также существует тип None — аналог null, обозначающий «ничего».

Строгая типизация и приведение типов

Python не позволяет неявное сложение разных типов (например, числа и строки). Это вызовет ошибку TypeError. Типы нужно приводить явно.

Функции приведения:

  • int() — преобразует в целое число.

  • float() — преобразует в дробное число.

  • str() — преобразует в строку.

a = "10"    # Это строка
b = 5       # Это число

# print(a + b) -> Ошибка!

# Правильно:
print(int(a) + b)  # 15 (результат число)
print(a + str(b))  # "105" (результат строка, конкатенация)

Блок 2: Управление потоком (Условия)

Линейное выполнение кода подходит только для простейших скриптов. Чтобы программа могла принимать решения в зависимости от входных данных, используются условные операторы.

Операторы сравнения

Результатом работы этих операторов всегда является bool (True или False).

  • == — равно (важно: не путать с оператором присваивания =).

  • != — не равно.

  • >, <, >=, <= — стандартные математические сравнения.

  • in — проверка вхождения элемента в последовательность (очень удобный оператор Python).

print(10 == 10)       # True
print(5 != 5)         # False
print("a" in "table") # True (буква 'a' есть в строке 'table')

Конструкция if / elif / else

Синтаксис условий в Python предельно лаконичен. Ключевые моменты:

  1. Условие заканчивается двоеточием (:).

  2. Блок кода, который должен выполниться, пишется с отступом (4 пробела).

  3. Скобки вокруг условия if (x > 5) не нужны, хотя и не запрещены.

Пример: Проверка доступа по возрасту

age = 17

if age >= 18:
    print("Полный доступ разрешен")
    print("Добро пожаловать")
elif age >= 14:
    # Выполнится, если первое условие False, а это — True
    print("Доступ с ограничениями")
else:
    # Выполнится, если ни одно из условий выше не подошло
    print("Доступ запрещен")

print("Проверка завершена") # Эта строка выполнится в любом случае (нет отступа)

Обратите внимание: Как только Python находит первое истинное условие, он выполняет его блок и пропускает остальные elif/else.

Логические операторы

Позволяют создавать сложные условия. В Python они пишутся словами, что улучшает читаемость.

  • and — И (оба условия должны быть True).

  • or — ИЛИ (хотя бы одно условие True).

  • not — НЕ (инвертирует значение: True превращает в False и наоборот).

Пример: Проверка логина и пароля

username = "admin"
password = "123"
is_banned = False

# Проверяем: верны ли данные И не забанен ли пользователь
if username == "admin" and password == "123":
    if not is_banned:
        print("Вход в систему")
    else:
        print("Аккаунт заблокирован")
else:
    print("Неверный логин или пароль")

Частая ошибка новичков

При сравнении переменной с несколькими значениями нельзя писать так:
if code == 1 or 2 or 3: (это всегда будет True, так как 2 интерпретируется как истина).

Правильный вариант:
if code == 1 or code == 2 or code == 3:

Или «питонический» вариант с использованием in:
if code in [1, 2, 3]:

Блок 3: Циклы (Повторение действий)

Циклы позволяют выполнять блок кода многократно. В Python существует два основных типа циклов: for (для перебора последовательностей) и while (пока выполняется условие).

Цикл for

В отличие от многих C-подобных языков, цикл for в Python — это скорее foreach. Он перебирает элементы объекта (строки, списка, диапазона чисел) по одному.

1. Генерация чисел с range()
Если нужно выполнить действие фиксированное количество раз, используется функция range().
Синтаксис: range(старт, стоп, шаг). Как и в срезах, правая граница не включается.

# Выведет числа от 0 до 4
for i in range(5):
    print(f"Итерация {i}")

# От 1 до 9 с шагом 2 (1, 3, 5, 7, 9)
for number in range(1, 10, 2):
    print(number)

2. Итерация по строке
Строка — это последовательность символов, поэтому её можно перебрать в цикле без дополнительных ухищрений.

text = "Hi!"
for char in text:
    print(char)
# Вывод:
# H
# i
# !

Цикл while

Выполняет блок кода до тех пор, пока условие остается истинным (True). Используется, когда заранее неизвестно, сколько повторений потребуется (например, работа до ввода команды «выход»).

n = 3
while n > 0:
    print(n)
    n = n - 1  # Важно: нужно менять условие внутри цикла, иначе он станет вечным
print("Пуск!")

Бесконечные циклы
Иногда цикл нужно сделать бесконечным намеренно (например, главный цикл работы бота или сервера). Для этого используют условие True.

while True:
    user_input = input("Введите команду: ")
    if user_input == "stop":
        break  # Ручной выход из цикла

Совет: Если вы случайно запустили бесконечный цикл в консоли и программа «зависла», нажмите Ctrl+C, чтобы принудительно остановить выполнение (KeyboardInterrupt).

Управление циклом: break и continue

Эти операторы позволяют менять стандартное поведение цикла.

  • break — досрочно прерывает цикл полностью.

  • continue — прерывает текущую итерацию и переходит к следующей (возвращается в начало цикла).

Пример: Поиск числа и пропуск нежелательных значений

# Ищем первое число, которое делится на 5, но пропускаем нечетные
for num in range(1, 20):
    if num % 2 != 0:
        continue  # Пропускаем нечетные числа (код ниже не выполнится)
    
    print(f"Проверяем число: {num}")
    
    if num % 5 == 0:
        print(f"Найдено подходящее число: {num}")
        break  # Останавливаем цикл, дальше искать нет смысла

print("Цикл завершен")

Результат: Цикл проверит 2, 4, 6, 8, а на 10 сработает break и перебор прекратится.

Блок 4: Структуры данных (Контейнеры)

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

1. Списки (Lists)

Аналог массивов в других языках, но с суперсилой: они изменяемые и могут хранить разные типы данных одновременно (хотя обычно хранят один).

  • Создание: квадратные скобки [].

  • Доступ: по индексу (начинается с 0).

# Создаем список
todo_list = ["Купить хлеб", "Помыть кота", 42]

# Доступ к элементам
print(todo_list[0])  # "Купить хлеб"
todo_list[1] = "Покормить кота" # Изменение элемента (списки изменяемы!)

# Добавление элементов
todo_list.append("Выучить Python")  # Добавляет в КОНЕЦ списка

# Удаление элементов
todo_list.pop()      # Удаляет и возвращает ПОСЛЕДНИЙ элемент
todo_list.pop(0)     # Удаляет элемент по ИНДЕКСУ 0
todo_list.remove(42) # Удаляет элемент по ЗНАЧЕНИЮ (первое совпадение)

Срезы списков
Работают так же, как и в строках. Это самый быстрый способ скопировать список или взять его часть.

numbers = [0, 1, 2, 3, 4, 5]
print(numbers[:3])  # [0, 1, 2] — первые три элемента
print(numbers[::-1]) # [5, 4, 3, 2, 1, 0] — разворот списка

2. Словари (Dictionaries)

Самая мощная структура данных в Python. Это «Хеш-таблица» или «Ассоциативный массив». Данные хранятся парами Ключ: Значение.
Ключи должны быть уникальными.

  • Создание: фигурные скобки {}.

  • Доступ: по ключу (очень быстрый поиск, не зависящий от размера словаря).

user = {
    "login": "neo",
    "role": "admin",
    "level": 80
}

# Получение значения
print(user["login"])  # neo

# Изменение и добавление
user["level"] = 81          # Изменили значение существующего ключа
user["is_active"] = True    # Если ключа не было — он создастся

Безопасное получение данных (.get)
Если вы попробуете обратиться к несуществующему ключу user["age"], программа упадет с ошибкой KeyError.
Чтобы этого избежать, используйте метод .get().

# print(user["age"]) -> ОШИБКА

print(user.get("age"))        # Вернет None, ошибка не возникнет
print(user.get("age", 18))    # Вернет 18 (значение по умолчанию), если ключа нет

3. Кортежи (Tuples)

Это неизменяемые списки. Записываются в круглых скобках ().
Зачем они нужны, если есть списки?

  1. Защита от дурака: Вы гарантируете, что данные внутри не будут изменены случайно.

  2. Скорость: Работают чуть быстрее списков и занимают меньше памяти.

coordinates = (10, 20)
print(coordinates[0]) # 10

# coordinates[0] = 15 -> ОШИБКА TypeError: tuple object does not support item assignment

4. Множества (Sets)

Контейнер, который хранит только уникальные элементы. Порядок элементов не гарантируется (в отличие от списков).
Записываются в фигурных скобках {}, как словари, но без двоеточий.

Главный кейс использования: быстро убрать дубликаты из списка.

my_list = [1, 1, 2, 2, 3, 3, 3]
unique_set = set(my_list) # Превращаем в множество
print(unique_set)         # {1, 2, 3}

# Проверка вхождения (работает мгновенно, быстрее чем в списке)
if 3 in unique_set:
    print("Тройка есть!")

Блок 5: Функции (Структурируем код)

Копипаст — главный враг программиста. Если вы заметили, что копируете один и тот же кусок кода в нескольких местах, значит, пора создать функцию. В Python это делается максимально просто.

Создание функции: def

Используется ключевое слово def (от define — определить). Правила те же: название, круглые скобки, двоеточие и отступ для тела функции.

def say_hello():
    print("Привет, Хабр!")

# Вызов функции (обязательно со скобками)
say_hello()

Аргументы

Функции становятся полезными, когда умеют работать с разными данными.

  1. Позиционные аргументы: Важен порядок передачи.

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

  3. Значения по умолчанию: Если аргумент не передан, используется дефолтное значение.

def greet(name, shout=False):
    if shout:
        print(f"ПРИВЕТ, {name.upper()}!")
    else:
        print(f"Привет, {name}.")

greet("Анна")                  # Используется False по умолчанию
greet("Борис", True)           # Позиционная передача
greet(shout=True, name="Иван") # Именованная передача (порядок не важен)

Возврат значения: return

Функция может не просто печатать что-то в консоль, а возвращать результат, который можно сохранить в переменную. Для этого используется return.
Важно: return немедленно завершает работу функции.

def square(x):
    return x ** 2

result = square(5) # result теперь равен 25
print(result + 5)  # 30

Ловушка с None:
Если в функции нет return (или он пустой), Python неявно возвращает специальный объект None.
Это частая ошибка новичков: присвоить результат функции, которая только печатает, а не возвращает.

def wrong_math(a, b):
    print(a + b) # Мы печатаем, но не возвращаем!

x = wrong_math(2, 2)
# print(x + 1) -> Ошибка! Потому что x равен None, а к None нельзя прибавить число.

Область видимости (Scope)

Переменные, созданные внутри функции, называются локальными. Они невидимы снаружи и умирают, как только функция завершается.
Переменные, созданные вне функций, — глобальные.

hero_name = "Batman" # Глобальная

def change_hero():
    hero_name = "Superman" # Это НОВАЯ локальная переменная, глобальная не изменилась
    print(f"Внутри: {hero_name}")

change_hero() # Выведет Superman
print(f"Снаружи: {hero_name}") # Выведет Batman

Про global:
В Python есть ключевое слово global, позволяющее менять глобальные переменные изнутри функции.
Совет: Забудьте о нем. Использование global делает код запутанным и непредсказуемым. Если функции нужны данные — передайте их как аргументы. Если нужно вернуть результат — используйте return.

Бонус: Аннотация типов (Type Hinting)

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

Синтаксис: аргумент: тип и -> тип_возврата.

# Мы явно говорим: a и b должны быть int, и вернется int
def add_numbers(a: int, b: int) -> int:
    return a + b

# IDE теперь подскажет ошибку, если вы попытаетесь передать строку,
# хотя программа все равно запустится.

Использование тайп-хинтинга сразу поднимает ваш код в глазах коллег с уровня «новичок» до «джун, который заботится о читаемости».

Блок 6: Работа с внешним миром

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

Консольный Ввод/Вывод

С функцией print() мы уже знакомы. Для получения данных от пользователя используется input().

Важное правило: input() всегда возвращает строку (str). Даже если пользователь ввел цифры.

name = input("Введите ваше имя: ") # Программа остановится и будет ждать ввода
age = input("Введите возраст: ")   # Допустим, ввели "25"

# print(age + 5) -> Ошибка TypeError! Строку нельзя сложить с числом.

# Нужно явное преобразование:
real_age = int(age) 
print(f"Через год вам будет {real_age + 1}")

Работа с файлами

В Python работа с файлами реализована гениально просто. Но есть нюанс, который отличает код новичка от кода профи: конструкция with.

Запись в файл

Чтобы записать данные, файл нужно открыть в режиме записи ('w' — write).
Обратите внимание: encoding='utf-8' — обязательный параметр, если вы пишете на русском языке (особенно в Windows), иначе получите «кракозябры».

# Конструкция with ... as ... — это "Контекстный менеджер"
# Она гарантирует, что файл закроется сам, даже если внутри произойдет ошибка.

data = ["Строка 1", "Строка 2", "Строка 3"]

with open("my_data.txt", "w", encoding="utf-8") as file:
    file.write("Заголовок\n") # \n нужен для переноса строки (write этого не делает)
    for line in data:
        file.write(f"{line}\n")

print("Запись завершена") 
# Здесь файл уже закрыт автоматически.

Режимы открытия:

  • 'w' (Write) — Создает новый файл. Если файл был — полностью стирает его содержимое.

  • 'a' (Append) — Дописывает данные в конец существующего файла.

  • 'r' (Read) — Только чтение (режим по умолчанию).

Чтение из файла

Читать файл можно целиком или построчно (что лучше для экономии памяти).

# Чтение файла целиком
with open("my_data.txt", "r", encoding="utf-8") as file:
    content = file.read()
    print(content)

# Чтение построчно (лучший способ для больших файлов)
with open("my_data.txt", "r", encoding="utf-8") as file:
    for line in file:
        # line.strip() убирает лишние пробелы и \n по краям
        print(f"Прочитано: {line.strip()}")

Почему именно with?

Вы можете открыть файл старым способом: f = open(...) и потом закрыть f.close().
Но если между открытием и закрытием произойдет ошибка (программа упадет), метод close() не сработает. Файл останется «висеть» в оперативной памяти, блокируя доступ другим программам.
Конструкция with работает как доводчик двери: она закроет файл («дверь») в любом случае, вышли вы нормально или вылетели через окно.

Блок 7: Обработка ошибок (Чтобы не падало)

По умолчанию Python работает по принципу «всё или ничего». Если на 100-й строке кода возникнет ошибка, программа немедленно остановится и выведет красное полотно текста (Traceback). Пользователь при этом потеряет все несохраненные данные.

Чтобы этого избежать, используется конструкция try...except.

Конструкция try/except

Смысл прост: мы «оборачиваем» опасный участок кода в блок try. Если внутри происходит сбой, Python не падает, а переходит в блок except.

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

  1. Пользователь введёт буквы вместо цифр.

  2. Пользователь попытается поделить на ноль.

try:
    num1 = int(input("Введите первое число: "))
    num2 = int(input("Введите второе число: "))
    
    result = num1 / num2
    print(f"Результат: {result}")

except ValueError:
    # Сработает, если int() не сможет превратить строку в число
    print("Ошибка: Вы ввели не число!")

except ZeroDivisionError:
    # Сработает, если num2 будет равен 0
    print("Ошибка: Делить на ноль нельзя!")

print("Программа продолжает работу...")

В этом примере, даже если пользователь ошибется, программа корректно сообщит о проблеме и продолжит выполнение кода после блока except.

Почему нельзя писать просто except:

Новички часто ленятся искать название ошибки и пишут так:

# ПЛОХОЙ ПРИМЕР, НЕ ДЕЛАЙТЕ ТАК
try:
    # ... куча кода ...
except:
    print("Что-то пошло не так")

Это называется «bare except» (голый эксепт), и за это бьют по рукам.
Почему это плохо?

  1. Скрывает баги: Вы не знаете, что именно сломалось — опечатка в имени переменной, ошибка сети или логическая ошибка. Вы просто гасите все сигналы бедствия.

  2. Перехватывает системные сигналы: Такой блок перехватит даже попытку закрыть программу через Ctrl+C (KeyboardInterrupt), и ваша программа станет «неубиваемой».

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

Блок 8: Модули (Батарейки в комплекте)

Сила Python не столько в синтаксисе, сколько в его экосистеме. Философия языка называется «Batteries Included»: всё необходимое для старта уже есть внутри. Вам не нужно писать сложные алгоритмы сортировки или математические формулы с нуля — достаточно подключить готовый модуль.

Как работает import

Чтобы использовать код из другого файла (модуля), используется команда import.

  1. Импорт целиком: Вы подключаете весь модуль и обращаетесь к функциям через точку.

    import math
    print(math.pi) # 3.1415...
    
  2. Импорт конкретной функции: Если вам нужна только одна функция и вы не хотите везде писать math..

    from math import sqrt
    print(sqrt(25)) # 5.0
    
  3. Импорт с псевдонимом: Если название модуля слишком длинное.

    import random as rnd
    print(rnd.randint(1, 10))
    

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

1. math (Математика)

Базовые операторы (+, *) просты, но для серьезных вычислений нужен модуль math.

import math

# Округление
print(math.ceil(4.2))   # 5 (в потолок)
print(math.floor(4.9))  # 4 (в пол)

# Степени и корни
print(math.sqrt(16))    # 4.0 (Квадратный корень)
print(math.pow(2, 5))   # 32.0 (Возведение в степень, аналог 2**5)

# Константы
print(math.pi)          # Число Пи

2. random (Случайные числа)

Незаменим для игр, тестов и генерации паролей. Компьютеры не умеют генерировать по-настоящему случайные числа, но этот модуль отлично имитирует случайность.

import random

# Случайное целое число от 1 до 10 (включая обе границы!)
dice = random.randint(1, 6)
print(f"На кубике выпало: {dice}")

# Выбор случайного элемента из списка
fruits = ["Яблоко", "Банан", "Груша"]
winner = random.choice(fruits)
print(f"Победитель: {winner}")

# Перемешивание списка (меняет сам список!)
cards = [10, "J", "Q", "K", "A"]
random.shuffle(cards)
print(cards)

3. time (Время и задержки)

Чаще всего этот модуль используют для двух вещей: замедлить выполнение программы или засечь время выполнения.

import time

print("Запуск ракеты...")

# Обратный отсчет с задержкой
for i in range(3, 0, -1):
    print(i)
    time.sleep(1) # Программа "засыпает" на 1 секунду

print("Поехали!")

Лайфхак: time.sleep() часто используют в парсерах, чтобы не «дудосить» сервер частыми запросами и не получить бан.

Блок 9: Практика (Финальный босс)

Теория без практики мертва. Мы изучили переменные, условия, циклы, функции, импорты и обработку ошибок. Теперь давайте соберем из этих деталей рабочий механизм.

Наша задача — написать консольную игру «Угадай число».
ТЗ (Техническое задание):

  1. Компьютер загадывает число от 1 до 100.

  2. Игрок пытается его угадать.

  3. Если число меньше загаданного — программа пишет «Мало».

  4. Если больше — «Много».

  5. Если угадал — поздравляет и показывает количество попыток.

  6. Программа не должна ломаться, если ввести текст вместо цифр.

Код программы

Создайте файл game.py и перепишите (или скопируйте) этот код. Читайте комментарии, они объясняют логику сборки.

import random  # 1. Импортируем модуль для генерации случайности

def start_game():
    """Основная функция игры"""
    print("=== ИГРА: УГАДАЙ ЧИСЛО ===")
    print("Я загадал число от 1 до 100. Попробуй отгадать!")

    # 2. Генерируем случайное число
    secret_number = random.randint(1, 100)
    attempts = 0  # Счетчик попыток

    # 3. Запускаем бесконечный цикл игры
    while True:
        user_input = input("Введите ваше число: ")

        # 4. Проверка на выход (пасхалка для нетерпеливых)
        if user_input == "exit":
            print(f"Сдаешься? Число было: {secret_number}")
            break

        # 5. Обработка ошибок (защита от ввода букв)
        try:
            guess = int(user_input)
        except ValueError:
            print("Ошибка! Вводите только целые числа.")
            continue  # Возвращаемся в начало цикла, не засчитывая попытку

        # Если мы здесь, значит введено число. Увеличиваем счетчик.
        attempts = attempts + 1  # Или просто attempts += 1

        # 6. Логика сравнения
        if guess == secret_number:
            print(f"🎉 Победа! Вы угадали число {secret_number} с {attempts}-й попытки!")
            break  # Выход из цикла (и завершение игры)
            
        elif guess < secret_number:
            print("Мало! Берите выше.")
            
        else:
            print("Много! Берите ниже.")

# Запуск функции, только если файл запущен напрямую
if __name__ == "__main__":
    start_game()

Разбор полетов

Что мы использовали в этом коде?

  1. import random: Взяли «батарейку» для генерации загадки.

  2. def start_game():: Упаковали логику в функцию. Это позволяет в будущем легко расширить игру (например, добавить меню).

  3. while True:: Игровой цикл. Мы не знаем, сколько попыток понадобится игроку, поэтому крутимся вечно, пока не сработает break.

  4. try...except:: Самая важная часть для UX. Если пользователь промахнется по клавише и введет "12w", программа вежливо попросит повторить, а не вылетит с красным текстом.

  5. if/elif/else:: «Мозг» программы, который направляет игрока.

  6. F-строки: Красивый вывод результата с подстановкой переменных.

Домашнее задание (Challenge)

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

  • Добавьте лимит попыток (например, всего 7 жизней).

  • Сделайте так, чтобы после победы игра спрашивала: «Хотите сыграть еще? (да/нет)».

  • Сохраняйте лучший результат (рекорд попыток) в файл record.txt.

Заключение: Куда расти дальше?

Поздравляю, вы добрались до конца. Если вы проработали примеры из статьи, то сейчас вы знаете Python лучше, чем 90% людей, которые годами «планируют начать».

Мы намеренно оставили за бортом Объектно-Ориентированное Программирование (ООП). И вот почему: процедурного стиля достаточно для решения большинства прикладных задач.
Чтобы написать парсер сайтов, телеграм-бота, скрипт для сортировки файлов или анализа Excel-таблиц, вам не нужны классы. Вам нужны функции, циклы и умение гуглить библиотеки.

Анонсы новых статей, полезные материалы, а так же если в процессе у вас возникнут сложности, обсудить их или задать вопрос по этой статье можно в моём Telegram-сообществе. Смело заходите, если что-то пойдет не так, — постараемся разобраться вместе.

Главный совет: Не попадайте в «ловушку туториалов» (когда вы смотрите уроки, но сами ничего не пишете). Открывайте редактор и пишите код. Ломайте его, чините, получайте ошибки — это единственный способ стать программистом.

Удачи в коде! print("Good luck!")