Перейти к содержимому
k03

k03. Python intensive: синтаксис, типы, ввод-вывод

k03. Python intensive: синтаксис, типы, ввод-вывод

UAV Python Pro · Конспект K03 · Модуль M1. Python intensive: синтаксис, типы, ввод-вывод · Редакция 2.0 (ZOO-safe) · После CHECKPOINT-G0

С этого урока начинается ускоренный, но подробный Python «с нуля» внутри вашего проекта PyCharm. Мы не учим язык «вообще для сайтов», а сразу привязываем примеры к телеметрии, порогам безопасности и простым решениям. Сегодня: числа, строки, логические значения, печать и ввод, сравнения и первые ветвления. Всё выполняется в виртуальном окружении из K01.

Компьютер хранит данные разных типов: целые метры, дробные вольты, текст режима полёта, флаги «связь есть» или «связи нет». Пока тип и смысл перепутаны, скрипт «если высота меньше минимума — предупреди» будет врать. Навык урока: уверенно создавать переменные, понимать тип, печатать, сравнивать и принимать простое решение через if.

Содержание

1. Цели урока

После этого урока вы будете уметь:

  • создавать переменные и выбирать понятные имена в стиле инженерного кода;
  • различать типы int, float, str, bool и значение None;
  • выполнять арифметику и склейку строк, понимать разницу деления / и //;
  • печатать данные через print и f-строки;
  • читать ввод пользователя и преобразовывать строку в число;
  • сравнивать значения и писать ветки if / elif / else;
  • собрать маленький учебный скрипт решения «можно ли продолжать сценарий» по высоте и батарее (ещё без MAVLink).
Зачем это дронам: почти каждая проверка безопасности — это сравнение чисел и флагов. Пока сравнения пишутся уверенно, MAVLink и SITL не превратятся в магию копипаста.
↑ К оглавлению

2. Словарь урока

ТерминПростыми словами
Переменная Имя, к которому прикреплено значение. Как подписанная ячейка: altitude_m = 12.5
Тип данных Род значения: целое, дробное, текст, да/нет. От типа зависят допустимые операции.
Присваивание Операция «=»: сделай так, чтобы имя ссылалось на это значение.
Выражение Фрагмент кода с результатом, например 3 + 4 или сравнение напряжения с порогом.
f-строка Строка с буквой f перед кавычками; внутрь в фигурных скобках можно вставлять значения переменных.
Приведение типа Явное превращение, например float("12.3") — из текста в число.
Ветвление Выбор разных действий в зависимости от условия (if).
Отступ Пробелы в начале строки. В Python отступ обязателен: он показывает, какой код входит внутрь if.
None Специальное значение «ничего / ещё не получено». Не путать с нулём и пустой строкой.
↑ К оглавлению

3. Как работаем в PyCharm на M1

  1. Откройте проект курса из K01 (там, где есть .venv).
  2. Убедитесь, что интерпретатор — venv проекта.
  3. Создайте папку code/M01_python/ (или скопируйте готовые .py из материалов курса).
  4. Каждое задание — отдельный файл, например k03_task1_telemetry_line.py.
  5. Запускайте через Run в PyCharm.
  6. После стабильного куска — commit в Git, например: K03: types and if basics.
Стиль кода курса: имена переменных — английские, snake_case (battery_voltage_v). Сообщения print для учёбы можно на русском.
# code/M01_python/k03_sandbox.py
print("M1 started")
↑ К оглавлению

4. Переменные и имена

Переменная создаётся присваиванием. Тип в Python обычно не пишут слева — он определяется значением. Это удобно, но требует дисциплины: сам программист помнит смысл имени.

altitude_m = 25.0          # высота, метры
satellites = 12            # число спутников GPS
flight_mode = "LOITER"     # режим полёта текстом
link_ok = True             # связь с GCS есть?

Позже можно переприсвоить другое значение:

altitude_m = 30.5
flight_mode = "RTL"
Знак «=» — это не «равно» из математики. В Python один знак «=» значит «присвоить». Проверка «равно ли?» пишется двумя знаками: «==». Путаница — классика первой недели.

Правила имён:

  • Можно буквы, цифры, подчёркивание; нельзя начинать с цифры.
  • Регистр важен: Alt и alt — разные имена.
  • Не занимайте слова языка: if, class, print — плохие имена переменных.
  • Имя должно говорить о смысле и единице: speed_m_s, voltage_v, timeout_s.
ПлохоЛучшеПочему
a = 14.2 battery_voltage_v = 14.2 Через неделю непонятно, что такое a
list = 3 waypoint_count = 3 list — встроенное имя
Altitude = "10" altitude_m = 10.0 Единицы и правильный тип числа
↑ К оглавлению

5. Основные типы данных

Целые числа — int

Счётчики, число спутников, номер точки миссии, system id.

satellites = 14
wp_index = 0
sysid = 1
print(type(satellites))
# на экране будет что-то вроде: class int

Дробные числа — float

Высота в метрах, напряжение, скорость, широта и долгота (пока как обычные float; гео-детали — в M2).

altitude_m = 12.5
voltage_v = 15.82
lat = 60.1699
print(type(altitude_m))
Целое можно писать как float, если смысл дробный: altitude_m = 10.0. Так вы напоминаете, что единица допускает доли метра.
Точность float: в двоичной арифметике иногда бывает «хвост», например 0.1 + 0.2 не выглядит как идеальные 0.3. Для телеметрии обычно сравнивают с порогом (больше или равно), а не требуют побитового совпадения. Подробнее — позже.
print(0.1 + 0.2)
# часто увидите 0.30000000000000004 — это норма для float

Строки — str

Текст: режим полёта, путь к файлу, сообщение оператору.

mode = "GUIDED"
port_name = "COM7"
message = "PreArm: need 3D fix"
print(type(mode))
print(len(mode))   # длина строки GUIDED = 6

Одинарные и двойные кавычки равноправны. Главное — закрыть тем же видом. Многострочный текст — тройные кавычки.

help_text = """K03 practice
Run inside project venv.
"""

Логический тип — bool

Только два значения: True и False (с большой буквы).

armed = False
link_ok = True
altitude_m = 5.0
in_air = altitude_m > 1.0   # в PyCharm: altitude_m > 1.0 обычным знаком
print(in_air, type(in_air))
В автопилотной логике bool везде: «есть ли heartbeat», «разрешён ли arm», «сработала ли геозона». Называйте флаги ясно: is_armed, has_gps_fix, battery_critical.

Пустое значение — None

None значит «значения нет». Это не ноль и не пустая строка.

last_heartbeat_time = None   # ещё ни разу не получали

if last_heartbeat_time is None:
    print("No heartbeat yet")
С None сравнивайте через is / is not, а не через ==. Для None это принятый стиль Python.

Узнать тип любого значения:

value = "14.7"
print(type(value))              # str
print(float(value))             # 14.7
print(type(float(value)))       # float
↑ К оглавлению

6. Арифметика и строки

a = 10
b = 3
print(a + b)   # 13
print(a - b)   # 7
print(a * b)   # 30
print(a / b)   # 3.333...  в Python 3 всегда float
print(a // b)  # 3         целочисленное деление
print(a % b)   # 1         остаток
print(a ** b)  # 1000      степень
ОперацияСмыслПример в теме дронов
/ Обычное деление Средняя скорость = путь / время
// Сколько раз уместилось целиком Индексы, разбиение логов
% Остаток Каждый 10-й сэмпл: i % 10 == 0
** Степень Реже на старте; в формулах позже
wp_index = 0
wp_index += 1      # то же, что wp_index = wp_index + 1
voltage_v = 15.0
voltage_v -= 0.05

Операции со строками:

prefix = "mode="
mode = "AUTO"
print(prefix + mode)      # mode=AUTO
print("COM" + str(3))     # число в строку через str(...)
Нельзя сложить строку и число напрямую. Выражение вида "высота " + 10 упадёт с TypeError. Нужно str(10) или f-строка.
↑ К оглавлению

7. print, input, f-строки

altitude_m = 18.25
mode = "LOITER"
voltage_v = 15.1

print("alt=", altitude_m, "mode=", mode)

# f-строка — основной стиль курса
print(f"alt={altitude_m:.1f} m | mode={mode} | batt={voltage_v:.2f} V")

В f-строке запись altitude_m:.1f значит: показать число с одним знаком после запятой. Удобно для «приборной» печати.

print(
    f"status: mode={mode}\n"
    f"alt_m={altitude_m:.2f}\n"
    f"voltage_v={voltage_v:.2f}"
)

Функция input всегда возвращает строку, даже если человек ввёл цифры.

raw = input("Введите минимальную высоту, м: ")
print(raw, type(raw))       # например '10' и str

min_alt_m = float(raw)      # превращаем в число
print(min_alt_m, type(min_alt_m))
n = int(input("Сколько точек миссии? "))
print(n * 2)
Если ввести текст «десять» в float(...), программа упадёт с ValueError. На K03 достаточно понимать причину. Аккуратный try/except будет в K08. Пока вводите корректные числа.
Инженерный приём: сырой ввод держите в raw_..., а после преобразования — в имени с единицей (..._m, ..._v).
↑ К оглавлению

8. Сравнения и if

Оператор в PythonСмыслПример
== равно mode == "RTL"
!= не равно mode != "AUTO"
<   <=   >   >= меньше / больше (и «или равно») voltage_v < 14.0
and и (оба истинны) link_ok and has_fix
or или critical or failsafe
not отрицание not armed
voltage_v = 13.9
mode = "LOITER"
print(voltage_v < 14.0)   # True   (в PyCharm: voltage_v < 14.0 обычным <)
print(mode == "LOITER" and voltage_v > 13.0)  # True
print(not False)          # True

После условия — двоеточие. Тело ветки пишется с отступом (в PyCharm обычно 4 пробела).

altitude_m = 0.4

if altitude_m < 1.0:
    print("На земле или очень низко")
elif altitude_m < 10.0:
    print("Низкая высота")
else:
    print("Рабочая высота")
link_ok = True
has_gps_fix = False

if not link_ok:
    print("Нет связи")

if not has_gps_fix:
    print("Нет GPS fix")

Учебный пример: decision gate

Это не настоящий prearm автопилота и не команда моторам. Это тренировка логики. Готовый файл: code/M01_python/k03_mission_gate.py

# k03_mission_gate.py — учебный фильтр (НЕ arm)

MIN_VOLTAGE_V = 14.0
MIN_SATS = 8
MAX_WIND_M_S = 12.0

battery_voltage_v = 14.6
satellites = 10
wind_m_s = 5.0
operator_ack = True

battery_ok = battery_voltage_v >= MIN_VOLTAGE_V
gps_ok = satellites >= MIN_SATS
wind_ok = wind_m_s <= MAX_WIND_M_S

if not operator_ack:
    decision = "STOP: нет подтверждения оператора"
elif battery_ok and gps_ok and wind_ok:
    decision = "GO: условия учебного сценария выполнены"
else:
    decision = "STOP: условия не выполнены"
    if not battery_ok:
        decision += " | battery"
    if not gps_ok:
        decision += " | gps"
    if not wind_ok:
        decision += " | wind"

print(f"batt={battery_voltage_v}V sats={satellites} wind={wind_m_s}m/s")
print(decision)
Разбор: пороги вынесены в ИМЕНА_ЗАГЛАВНЫМИ. Флаги battery_ok читаются как короткие утверждения. Итог — одна строка решения. Так же позже собирают state machine.
Безопасность курса: этот скрипт ничего не армит и не связан с моторами. Настоящий arm — только по процедуре после нужных гейтов.
↑ К оглавлению

9. Типичные ошибки новичка

ОшибкаЧто видитеКак думать
В условии написали = вместо == SyntaxError или странная логика В условии только сравнение
Смешали Tab и пробелы IndentationError В PyCharm — 4 spaces
Складываете "высота " и число 10 TypeError Сначала str(10) или f-строка
int("3.5") ValueError Для "3.5" используйте float
True/False с маленькой буквы NameError Только True и False
Путаете None, 0 и "" Тихие логические баги Нет данных / ноль / пустой текст — разное
# Правильно:
print("alt " + str(10))
print(f"alt {10}")
↑ К оглавлению

10. Практика

Все файлы — в code/M01_python/. Можно набрать вручную или скопировать готовые .py из материалов курса (там обычные знаки сравнения Python).

Задача 3.1. Визитка телеметрии

Файл k03_task1_telemetry_line.py — переменные высоты, режима, спутников, напряжения, флага связи; одна f-строка на печать.

altitude_m = 42.0
mode = "AUTO"
satellites = 13
voltage_v = 15.55
link_ok = True

print(
    f"mode={mode} alt={altitude_m:.1f}m "
    f"sats={satellites} V={voltage_v:.2f} link={link_ok}"
)

Задача 3.2. Сантиметры в метры

Файл k03_task2_units.py — в MAVLink высота часто в сантиметрах (int). Переведите в метры.

alt_cm = 1530
alt_m = alt_cm / 100.0
print(f"alt_cm={alt_cm} -> alt_m={alt_m}")

Задача 3.3. Классификатор напряжения

Файл k03_task3_battery_class.py. Пороги учебные: OK если ≥ 14.8; LOW если ≥ 14.2; иначе CRITICAL.

voltage_v = 14.35

if voltage_v >= 14.8:
    level = "OK"
elif voltage_v >= 14.2:
    level = "LOW"
else:
    level = "CRITICAL"

print(f"{voltage_v} V -> {level}")

Задача 3.4. Ввод порога высоты

Файл k03_task4_input_alt.py. Спросите минимальную высоту, сравните с altitude_m = 7.5.

altitude_m = 7.5
raw = input("Минимальная высота, м: ")
min_alt_m = float(raw)

if altitude_m < min_alt_m:
    print(f"Ниже порога: {altitude_m} < {min_alt_m}")
else:
    print(f"Порог выдержан: {altitude_m} >= {min_alt_m}")

Задача 3.5. Decision gate

Запустите k03_mission_gate.py. Затем поменяйте satellites так, чтобы получить STOP с причиной gps. В комментарии вверху файла напишите, какие значения подставили.

Задача 3.6. Git commit

git add code/M01_python
git commit -m "K03: types, print/input, if practice"
↑ К оглавлению

11. Проверьте себя

  1. Чем один знак «=» отличается от «==»?
  2. Почему input всегда даёт str?
  3. Чем / отличается от // ?
  4. Когда использовать None, а когда 0?
  5. Как f-строка помогает печатать телеметрию?
  6. Зачем отдельные флаги вроде battery_ok?
  7. Что такое отступ в Python и почему без него нельзя?
  8. Почему учебный decision gate не является командой arm?
↑ К оглавлению

12. Чек-лист самопроверки

  • Работаю в venv проекта K01
  • Уверенно создаю int/float/str/bool и понимаю None
  • Умею type(...) и приведение int/float/str
  • Печатаю f-строки с округлением .1f / .2f
  • Читаю input и понимаю, зачем float/int после ввода
  • Пишу if/elif/else с правильными отступами
  • Собираю условия через and/or/not
  • Выполнил задачи 3.1–3.5 у себя в PyCharm
  • Сделал git commit по K03
  • Понимаю: на сайте знаки <> в коде — для ZOO; в Python — обычные клавиши
Результат: чек-лист закрыт — напишите K03 чек-лист закрыт. Далее K04 · Коллекции (list, tuple, dict, set).
↑ К оглавлению

13. Что дальше

  • Модуль M0 и гейт G0 закрыты
  • Сейчас: M1 Python intensive
  • Следующий конспект: K04 · Коллекции
  • Горизонт модуля: K12 мини-проект CLI и гейт G1
История правок K03: 1.0 — первая версия; 1.1 — HTML-entities &lt; (ZOO всё равно ломал индекс); 2.0 — полноширинные <> в code + отдельные .py файлы (FIX-20260810-06).
↑ К оглавлению

 

 

Вторник, 11 августа 2026
k03. Python intensive: синтаксис, типы, ввод-вывод