# Правила оформления Python файлов для конвертации в Jupyter

Этот документ содержит правила форматирования Python файлов, которые гарантируют корректную конвертацию в Jupyter ноутбуки с помощью инструмента `py2jupyter`.

## Основные принципы

### 1. Структурирование файла

- **Начинайте с заголовка файла**: Используйте специальный формат заголовков для обозначения начала разделов
- **Группируйте связанный код**: Логически связанные блоки кода должны быть вместе
- **Используйте пустые строки**: Разделяйте логические блоки пустыми строками (но не в начале/конце функций)

### 2. Заголовки и разделы

#### Формат заголовков разделов
```python
""" # Заголовок раздела # """
```

**Правила:**
- Заключен в тройные кавычки с пробелами: `""" # текст # """`
- Можно использовать префикс `r` если нужен: `r""" # текст # """`
- Становится markdown ячейкой с заголовком `# Заголовок раздела #`
- Используется для четкого структурирования больших скриптов
- **Важно**: обычные Python комментарии `# текст` остаются комментариями!

#### Примеры:
```python
""" # Численные методы решения ОДУ на примере затухающего гармонического осциллятора # """

"""
На этом занятии мы реализуем и сравним ряд численных методов интегрирования:
- Метод Leapfrog-Verlet
- Метод Рунге-Кутты
- Метод Адамса-Бэшфорта
- Метод Адамса-Моултона
"""

""" ## Уравнение гармонического осциллятора ## """
```

### 3. Многострочные комментарии и описания

#### Markdown комментарии
```python
r"""
Формула: $E = \frac{1}{2}mv^2 + \frac{1}{2}kx^2$
Интеграл: $\int_0^1 x dx = \frac{1}{2}$
"""

"""
Обычное описание без специальных символов.
Может содержать списки, жирный текст и другие элементы markdown.
"""
```

**Правила:**
- Поддерживаются как `r"""..."""`, так и `"""..."""`
- При обратной конвертации префикс `r` **автоматически добавляется** при наличии `\` символов
- Тройные кавычки на отдельных строках
- Становится markdown ячейкой
- Поддерживает полный синтаксис Markdown и LaTeX

### 4. Структура кода

#### Импорты
```python
import numpy as np
import matplotlib.pyplot as plt
from math import pi
import matplotlib.animation as animation
from scipy.optimize import fsolve

from oscillator_plots import plots
```

**Правила:**
- Группируйте импорты в начале файла
- Разделяйте стандартные библиотеки, сторонние пакеты и локальные модули
- Импорты автоматически попадут в отдельную code ячейку

#### Глобальные переменные и константы
```python
""" Физические параметры гармонического осциллятора """

m = 1.0   # масса, кг
b = 0.01  # коэффициент трения, кг/с
k = 4.0   # жесткость пружины, Н/м

""" Начальные условия """

u0 = 0.5   # начальное смещение, м
v0 = 0.0   # начальная скорость, м/с
```

**Правила:**
- Предваряйте группы констант заголовком раздела
- Добавляйте комментарии к каждой переменной
- Группируйте логически связанные константы

#### Функции и классы

```python
def energy(u, v):
    """
    Расчет полной энергии гармонического осциллятора

    Args:
        x: смещение, м
        v: скорость, м/с

    Returns:
        E: полная энергия, Дж
    """
    # Потенциальная энергия
    U = 0.5 * k * u**2
    # Кинетическая энергия
    K = 0.5 * m * v**2
    return U + K
```

**Правила:**
- **Каждая функция верхнего уровня → отдельная code ячейка**
- **Docstring'и внутри функций/классов остаются частью кода** (важно!)
- Вложенные функции остаются в одной ячейке с родительской
- Функции должны иметь понятные имена и подробные docstring'и

### 5. Комментарии в коде

#### Magic команды Jupyter
```python
#%matplotlib inline

#%config InlineBackend.figure_format = 'retina'

#%time
```

**Правила:**
- **Magic команды** начинаются с `#%` в Python файле
- Становятся **отдельными code ячейками** в Jupyter ноутбуке
- При обратной конвертации **одиночные magic ячейки** становятся комментариями `#%command`
- Поддерживают все стандартные magic команды Jupyter (`%matplotlib`, `%time`, `%config` и т.д.)

#### Shell команды Jupyter
```python
#! pip install seaborn

#! pip install --upgrade numpy matplotlib

#! ls -la
```

**Правила:**
- **Shell команды** начинаются с `#!` в Python файле
- Становятся **отдельными code ячейками** в Jupyter ноутбуке
- При обратной конвертации **одиночные shell ячейки** становятся комментариями `#!command`
- Поддерживают все shell команды (`pip install`, `ls`, `cd`, `mkdir` и т.д.)

#### Обычные комментарии
```python
# Параметры затухающего осциллятора
omega = np.sqrt(k / m)  # собственная частота
gamma = b / (2 * m)      # коэффициент затухания

# Определяем тип колебаний
discriminant = gamma**2 - omega**2
```

**Правила:**
- **Обычные комментарии `# текст` остаются Python комментариями**
- Используйте их для пояснения сложной логики
- Не переусердствуйте - код должен быть самодокументируемым

#### Разница между типами комментариев
```python
# Это КОММЕНТАРИЙ - станет частью code ячейки
"""
Это markdown блок - станет отдельной markdown ячейкой
"""

def my_function():
    """Это DOCSTRING - останется в коде функции"""
    return "result"
```

### 6. Логическое разделение кода

#### Императивный Jupyter-like стиль
```python
""" ## 1. Решаем задачу аналитическим методом ## """

def analytical_method(u0, v0, dt, n_steps):
    """Реализация аналитического метода"""
    # код функции
    return u_result, v_result

# Выполнение и вывод результатов
u_analytic, v_analytic = analytical_method(u0, v0, dt, n_steps)
energy_analytic = energy(u_analytic, v_analytic)
print(f"Аналитическое решение: энергия = {energy_analytic:.4f}")


""" ## 2. Решаем задачу методом Leapfrog ## """

def leapfrog_method(u0, v0, dt, n_steps):
    """Реализация метода Leapfrog"""
    # код функции
    return u_result, v_result

# Выполнение и вывод результатов
u_leapfrog, v_leapfrog = leapfrog_method(u0, v0, dt, n_steps)
energy_leapfrog = energy(u_leapfrog, v_leapfrog)
print(f"Метод Leapfrog: энергия = {energy_leapfrog:.4f}")


""" ## 3. Решаем задачу методом Рунге-Кутты ## """

def rk4_method(u0, v0, dt, n_steps):
    """Реализация метода Рунге-Кутты"""
    # код функции
    return u_result, v_result

# Выполнение и вывод результатов
u_rk4, v_rk4 = rk4_method(u0, v0, dt, n_steps)
energy_rk4 = energy(u_rk4, v_rk4)
print(f"Метод Рунге-Кутты: энергия = {energy_rk4:.4f}")
```

**Правила:**
- **Строго императивный стиль**: комментарий в тройных кавычках → определение функции → немедленное выполнение с выводом результатов
- **Не используйте функцию main()** - весь исполняемый код должен быть на верхнем уровне
- **Каждая логическая задача** оформляется как: объяснение → функция → выполнение → вывод
- **Функции определяются непосредственно перед их использованием**
- **Две пустые строки подряд** на уровне нулевого отступа разделяют код на отдельные ячейки


### 7. Финальные замечания и выводы

```python
""" ## Выводы ## """

"""
На основе проведенного сравнения методов интегрирования...

### По точности решения:
1. **Методы Рунге-Кутты (RK4)** - наиболее точный одношаговый метод
2. **Методы Адамса-Моултона (неявные)** - самые точные для жестких систем

### Рекомендации по применению:
- **Для высокой точности на коротких интервалах**: RK4
- **Для длинных расчетов с умеренной точностью**: Leapfrog
"""
```

**Правила:**
- Завершайте файл разделом с выводами или заключением
- Используйте markdown для структурирования текста
- Добавляйте списки, таблицы и формулы LaTeX

## Шаблон правильно оформленного файла

```python
""" # Название проекта/задачи # """

"""
Краткое описание проекта, цели, используемые методы.
"""

# Импорты
import numpy as np
import matplotlib.pyplot as plt

# Глобальные константы
""" ## Параметры системы ## """

param1 = 1.0
param2 = 2.0


""" ## 1. Первая задача - подготовка данных ## """

def prepare_data(input_file):
    """Подготовка данных из файла"""
    # код функции
    return processed_data

# Выполнение и проверка
data = prepare_data('input.txt')
print(f"Загружено {len(data)} записей")


""" ## 2. Вторая задача - обработка данных ## """

def process_data(data, params):
    """Обработка данных с заданными параметрами"""
    # код функции
    return result

# Выполнение и вывод результатов
result = process_data(data, param1)
print(f"Результат обработки: {result}")


""" ## 3. Третья задача - визуализация ## """

def create_plot(result, output_file):
    """Создание графика результатов"""
    # код функции
    plt.savefig(output_file)

# Выполнение и сохранение
create_plot(result, 'output.png')
print("График сохранен в output.png")


""" ## Выводы ## """

"""
Анализ полученных результатов...
Рекомендации...
"""
```

## Важные напоминания

1. **Не используйте пустые строки в начале/конце функций** - они будут автоматически удалены при конвертации
2. **Docstring'и должны быть внутри функций**, а не перед ними
3. **Markdown блоки должны быть отдельными** от кода функций
4. **Тестируйте конвертацию** - всегда проверяйте цикл py → ipynb → py
5. **Используйте описательные имена** для функций и переменных
6. **Добавляйте LaTeX формулы** в `r"""` блоках для математических выражений
