📦 Репозиторий занятия 08

Урок 08. Операторы ветвления

Как работать с репозиторием

Каждая карточка говорит, о чём файл, что он выводит и что в нём искать. Код виден прямо здесь: его можно скопировать одной кнопкой, скачать файл или открыть его целиком.

Маршрут изучения

  1. Прочитайте описание: по нему уже понятно, о чём файл и что он выведет.
  2. Предскажите вывод: сравните своё предположение со строкой «Что выводит».
  3. Запустите: скачайте файл или скопируйте код кнопкой и выполните его у себя.
  4. Измените: поменяйте одно условие или значение и объясните новый результат.

Файлы: рекомендуемый порядок

1
MarkdownРазбор концепции93 строк

if - elif - else: ветвление и разница с несколькими независимыми if

less_05__if_elif_else__match_case/theory_01__if_elif_case.md

Базовый синтаксис if-elif-else с пояснением, что срабатывает ровно один блок — проверка идёт сверху вниз до первого истинного условия. Ключевой контраст файла: несколько отдельных независимых if друг от друга не зависят и могут сработать все сразу, в отличие от цепочки elif, где сработает только один. В конце — напоминание, что if/elif/else — ключевые слова и не могут быть именами переменных.

  • if x > 15: / elif x > 5: / else: — срабатывает только один блок
  • Несколько отдельных if — могут сработать все сразу
  • elif необязателен и может повторяться много раз
  • if/elif/else — зарезервированные ключевые слова
Показать начало файла (93 строк всего)
## Конструкция `if - elif - else`

В Python конструкция `if - elif - else` используется для ветвления кода.  
То есть определяет выполнения разных блоков в зависимости от условий.  
Отсюда и название - **условные операторы** (*condition statement*)

Базовый синтаксис:

```python
if условие1:
    # Блок кода, если условие1 истинно
elif условие2:
    # Блок кода, если условие1 ложно, но условие2 истинно
elif условие3:
    # Блок кода, если выше все ложные, но условие3 истинно
else:
    # Блок кода, если все условия выше ложные
```

### Пример:

```python
x = 10

if x > 15:
    print("x больше 15")
elif x > 5:
    print("x больше 5, но не больше 15")
else:
    print("x меньше или равно 5")

# результат ВСЕГДА будет ТОЛЬКО один!
# 
# В данном случае: 
# x больше 5, но не больше 15
```


### Особенности:

1. `elif` можно использовать несколько раз или не использовать совсем;
2. Для нескольких `elif`:
   1. Проверка идёт сверху вниз, 
   2. выполняется первый блок, условие которого истинно. 
   3. Остальные блоки игнорируются.
3. В `else` попадает всё, что не выполнилось выше (необязательный оператор!)
4. Условия могут быть любыми объектами, которые возвращают `True` или `False`.


В Python можно использовать несколько отдельных `if`, и они НЕ ЗАВИСЯТ друг от друга.  

* `if - elif - else`, 
  * срабатывает ТОЛЬКО ОДИН блок  
* несколько независимых `if` 
  * могут сработать все, если их условия истинны.

## Несколько отдельных блоков `if`:

Предыдущий пример мы можем записать с помощью нескольких `if`:

…
Проверьте себя: Почему в примере с тремя независимыми if результатом могут быть сразу три строки print, а в if-elif-else — только одна?
2
MarkdownРазбор концепции107 строк

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

less_05__if_elif_else__match_case/theory_02__ternary_operator.md

Синтаксис <значение_если_True> if <условие> else <значение_если_False> с пояснением, что он подходит только для простых конструкций и проигрывает блочному if в читабельности. Показаны вложенные тернарные операторы (несколько else if подряд) и их использование как аргумента print(). Отдельный раздел — как вручную развернуть длинный нечитаемый тернарный оператор обратно в if-elif-else «слева направо».

  • result = "Положительное" if x > 0 else "Отрицательное"
  • Вложенный тернарный: ... if x > 0 else ... if x < 0 else "Ноль"
  • Тернарный оператор как аргумент print()
  • max_val = a if a > b else b
  • Правило обратного разбора длинного тернарного в if/elif/else
Показать начало файла (107 строк всего)
В Python тернарный оператор — это способ записать условную конструкцию в одну строку.  
Подходит ТОЛЬКО для простых конструкций.  
Но даже в этом случае проигрывает классическому блочному оператору в читабельности.

Синтаксис:

```python
<значение_если_True> if <условие> else <значение_если_False>
```

### Пример 1: простое условие

```python
x = 10
result = "Положительное" if x > 0 else "Отрицательное"
print(result)  # Положительное
```

Эквивалентно:

```python
if x > 0:
    result = "Положительное"
else:
    result = "Отрицательное"
```

---

### Пример 2: вложенный тернарный оператор

```python
x = 0
result = "Положительное" if x > 0 else "Отрицательное" if x < 0 else "Ноль"
print(result)  # Ноль
```

Используется КРАЙНЕ редко, т.к. плохо читается.

---

### Пример 3: с функциями

```python
x = 0
print("Положительное") if x > 0 else print("Отрицательное") if x < 0 else print("Ноль")
```

Или ещё короче: весь тернарный оператор использовать в качестве аргумента функции.

```python
x = 5
print("Положительное" if x > 0 else "Отрицательное" if x < 0 else "Ноль")
```
---

### Пример 4: с числами

```python
a, b = 5, 10
…
Проверьте себя: Как правильно развернуть print("A") if x>100 else print("B") if x>0 else print("C") в блочный if-elif-else, следуя правилу файла «слева направо»?
3
MarkdownРазбор концепции135 строк

Вложенные if и замена их логическими операторами

less_05__if_elif_else__match_case/theory_03__nested_if.md

Показывает вложенные if (один if внутри другого) на примерах проверки чётности положительного числа и трёхуровневой классификации по диапазону. Главная идея файла — та же логика короче и читабельнее записывается через and/or и цепные сравнения (18 <= age <= 60 вместо двух вложенных if), с параллельным сравнением «вложенный вариант / вариант с логическим оператором» для трёх задач подряд.

  • if x > 0: if x % 2 == 0: — простая вложенность
  • Вложенный if-elif-else на три диапазона
  • if x > 0 and x % 2 == 0: — замена вложенности через and
  • if 18 <= age <= 60: — цепное сравнение вместо двух if
  • Проверка выхода за границы: вложенный if vs if/elif с and
Показать начало файла (135 строк всего)
## Вложенные условные конструкции

В Python вложенные конструкции `if` — это когда один блок `if` находится внутри другого.  
Это используется, когда нужно проверить несколько условий поэтапно.

---

### Базовый синтаксис

```python
if условие1:
    # код выполняется, если условие1 истинно
    if условие2:
        # код выполняется, если оба условия истинны
    else:
        # код выполняется, если условие1 истинно, но условие2 ложно
else:
    # код выполняется, если условие1 ложно
```

---

### Пример 1: простая вложенность

```python
x = 10
if x > 0:
    if x % 2 == 0:
        print("Положительное чётное число")
    else:
        print("Положительное нечётное число")
else:
    print("Отрицательное или ноль")
```

---

### Пример 2: вложенные `if-elif-else`

```python
x = 15
if x > 0:
    if x < 10:
        print("Маленькое положительное число")
    elif x < 20:
        print("Среднее положительное число")
    else:
        print("Большое положительное число")
else:
    print("Не положительное число")
```

---

## Альтернатива вложенным конструкциям: условия с логическими операторами

Альтернатива вложенным `if` в Python — использовать **логические операторы** `and`, `or`, `not`.  
Они позволяют объединять условия и записывать проверки короче и читаемее.

---
…
Проверьте себя: В примере проверки границ диапазона (x < -10000) — почему вариант с and и elif подряд эквивалентен вложенному if/else, а не создаёт лишнюю ветку?
4
MarkdownРазбор концепции89 строк

Приведение произвольных типов к bool внутри if

less_05__if_elif_else__match_case/theory_04__boolean_value_for_non_boolean_data_types.md

Объясняет, что if всегда неявно вызывает bool() над условием, и даёт сводную таблицу falsy/truthy значений для None, bool, чисел, строк, коллекций и пользовательских объектов. Отдельно показан менее очевидный случай: класс с методом __bool__, возвращающим False, — экземпляр такого класса в if ведёт себя как пустое значение, хотя формально не None и не 0.

  • if x: — эквивалент if bool(x):
  • Таблица falsy/truthy по типам: None, int/float, str, list/tuple/set/dict
  • if s: для непустой строки — срабатывает True-ветка
  • if items: для пустого списка — срабатывает False-ветка
  • class MyClass с __bool__(self) -> False — объект ведёт себя как False в if
Показать начало файла (89 строк всего)
В Python в конструкции `if` любое значение приводится к булевому типу по правилам языка.  
Фактически срабатывает функция `bool()`, которая возвращает `True` или `False`.

---

## Как это работает

* Если значение приводится к `True`, условие выполняется.
* Если значение приводится к `False`, условие не выполняется.

---

## Булевы значения для разных типов данных

| Тип данных                     | Когда `False`                                                               | Когда `True`                               |
| ------------------------------ | --------------------------------------------------------------------------- | ------------------------------------------ |
| `None`                         | Всегда `False`                                                              | —                                          |
| `bool`                         | `False`                                                                     | `True`                                     |
| `int`, `float`                 | `0`, `0.0`                                                                  | Любое ненулевое число                      |
| `str`                          | Пустая строка `""`                                                          | Любая непустая строка                      |
| `list`, `tuple`, `set`, `dict` | Пустые коллекции `[]`, `()`, `{}`, `set()`                                  | Любые непустые коллекции                   |
| Пользовательские объекты       | Если определён метод `__bool__` или `__len__`, возвращающий `0` или `False` | Если метод возвращает ненулевое или `True` |

---

## Примеры

### Числа

```python
x = 0
if x:
    print("Ненулевое число")
else:
    print("Ноль или False")  # сработает
```

---

### Строки

```python
s = "Привет"
if s:
    print("Строка не пустая")  # сработает
else:
    print("Пустая строка")
```

---

### Списки

```python
items = []
if items:
    print("Список не пустой")
else:
    print("Список пустой")  # сработает
```
…
Проверьте себя: Если у класса нет __bool__, но есть __len__, вернувший 0, — как поведёт себя if obj: для его экземпляра?
5
MarkdownРазбор концепции171 строк

match-case: паттерн-матчинг Python 3.10+

less_05__if_elif_else__match_case/theory_05__match_case.md

Вводит match-case как более мощный аналог switch-case с поддержкой паттерн-матчинга структур данных. Прогрессия примеров: простая замена if-elif-else, объединение значений через |, сопоставление по типу (case int():), деструктуризация кортежей с автоматическим захватом переменных ((x, 0) на оси X), захват строки с условием (case cmd if cmd.startswith(...)) и guard-условие (case n if n > 5:) с объяснением, почему нельзя писать case number > 5 напрямую. Завершается сводной таблицей всех видов паттернов.

  • match x: / case 1: / case _: — базовый синтаксис
  • case 1 | 2 | 3: — объединение значений через |
  • case int(): / case list(): — сопоставление по типу
  • case (x, 0): / case (0, y): — деструктуризация кортежа с автозахватом
  • case cmd if cmd.startswith("up"): — захват + guard-условие
  • case n if n > 5: против case _ if number > 5: — почему первый вариант надёжнее
  • Итоговая таблица шаблонов: литерал, захват, список/тюпл, словарь, класс, guard, OR, wildcard
Показать начало файла (171 строк всего)
## Конструкция `match-case`

`match-case`** в Python — это новый способ организации условной логики, появившийся в Python 3.10.  
Он похож на `switch-case` из других языков, но гораздо более мощный и интеллектуальный.  
Поддерживает **паттерн-матчинг**, включая структуры данных и проверки значений.

---

### 1. Синтаксис

```python
match <выражение>:
    case <паттерн_1>:
        # код, если совпал паттерн_1
    case <паттерн_2>:
        # код, если совпал паттерн_2
    case _:
        # "default", если ничего не совпало
```

* `match <выражение>:` — выражение, которое проверяется.
* `case  <паттерн_1>:` — паттерн, с которым сравнивается выражение.
* `_` — универсальный паттерн, аналог `else`.


---

### 2. Простейший пример (замена `if-elif-else`)

```python
x = 2

match x:
    case 1:
        print("Один")
    case 2:
        print("Два")  # сработает
    case 3:
        print("Три")
    case _:
        print("Другое число")
```

---

### 3. Несколько значений в одном `case` через знак `|`

```python
x = 5

match x:
    case 1 | 2 | 3:
        print("Малое число")
    case 4 | 5 | 6:
        print("Среднее число")  # сработает
    case _:
        print("Другое число")
```

`|` означает "или" — если выражение совпадает с любым значением, паттерн срабатывает.
…
Проверьте себя: Почему case number > 5: — синтаксическая ошибка, а case n if n > 5: — рабочий код, ведь оба выглядят как «проверка условия»?