Кажется, только вчера мы поднимали бокалы за наступление 2025-го, гадая, останется ли наша профессия актуальной или git push за нас окончательно начнет делать какой-нибудь GPT-5. И вот, календарь неумолимо показывает конец декабря.
Год был насыщенным. Мы пережили очередные релизы фреймворков, которые обещали «упростить всё», а на деле добавили еще три конфиг-файла. Мы наблюдали, как AI-ассистенты из забавных игрушек превратились в назойливых коллег, которые вечно норовят отрефакторить наш идеальный «костыль». Мы закрывали таски, тушили прод в пятницу вечером и пытались найти баланс между work и life, хотя life часто проигрывал деплою.
Сейчас, когда до 2026 года остаются считанные дни (или часы), а менеджеры наконец-то перестали назначать встречи после 18:00, хочется выдохнуть. Хочется на полчаса забыть про микросервисы, Kubernetes, KPI и OKR.
Хочется чего-то лампового. Чего-то бесполезного для бизнеса, но приятного для души.
Поэтому давайте отложим JIRA в сторону. Сегодня мы не будем спасать мир или оптимизировать high-load. Сегодня мы сделаем CLI-утилиту. Потому что нет ничего более новогоднего, чем красивая елочка и таймер обратного отсчета, мигающие прямо в любимом терминале.
Подготовка окружения: Собираем инструменты
Прежде чем начать рисовать ASCII-елки, нам нужно подготовить верстак. Поскольку мы договорились, что проект будет Fast & Fun, мы не будем разворачивать здесь микросервисную архитектуру или настраивать Kubernetes-кластер (хотя руки помнят).
Нам понадобится Python (версии 3.9+, чтобы работали все современные тайп-хинтинги) и пара библиотек, которые сделают всю магию за нас.
1. Создаем проект
Никакой магии, старая добрая классика в терминале:
mkdir ny2026-cli
cd ny2026-cli
python -m venv venv
Активируем виртуальное окружение (вы же не ставите пакеты в глобальный интерпретатор в 2025-м, правда?):
Linux/macOS:
source venv/bin/activateWindows:
venv\Scripts\activate
2. Главные герои: Rich и Typer
Чтобы наш CLI не выглядел как привет из 90-х (хотя в этом есть свой шарм), мы используем современные инструменты.
Устанавливаем зависимости:
pip install rich typer
Зачем они нам?
Rich: Это наш главный художник. Он умеет выводить в терминал цветной текст, таблицы, прогресс-бары, Markdown и даже Emoji. Без него терминал — это просто грустная черная бездна.
Typer: Младший брат FastAPI для CLI. Позволяет писать консольные утилиты с красивой справкой и валидацией аргументов, используя нативные подсказки типов Python. Если вы захотите потом добавить флаги (например,
--no-bugs), Typer сделает это в одну строчку.
3. Структура проекта
Мы придерживаемся принципа KISS (Keep It Simple, Stupid). Весь код поместится в один файл.
ny2026-cli/
├── venv/ # Виртуальное окружение
├── main.py # Тут будет вся магия
└── README.md # (Опционально) Чтобы не забыть, как это запускать в 2027
Создайте файл main.py и откройте его в любимой IDE (VS Code, PyCharm или, если вы чувствуете себя особенно олдскульно перед Новым годом, — Vim).
Погнали писать код!
Реализация: Магия в 100 строк кода
Наш main.py будет состоять из трех основных частей:
Данные и Арт: ASCII-графика и список шуточных предсказаний.
Логика: Подсчет времени до «Часа Х» (00:00 01.01.2026).
Рендеринг: Сборка макета (Layout) и живое обновление (Live).
Открываем main.py и поехали.
1. Импорты и настройка
Нам понадобятся стандартные модули времени и рандома, а также тяжелая артиллерия из rich.
import time
import random
from datetime import datetime
import typer
from rich.console import Console
from rich.panel import Panel
from rich.layout import Layout
from rich.live import Live
from rich.align import Align
from rich.text import Text
app = typer.Typer()
console = Console()
2. Генератор предсказаний
Какой Новый год без гаданий? Создадим список, который будет рандомно выдавать «пророчество» при каждом запуске. Это отличный способ поднять настроение коллегам.
PREDICTIONS = [
"🐍 В 2026 твой код перепишет AI, но добавит туда багов.",
"🐳 Твои Docker-образы похудеют на 500 Мб (чудо!).",
"☕ Ты наконец поймешь, зачем нужны монады (но это не точно).",
"🚀 Твой пет-проект внезапно попадет в топ Hacker News.",
"🔥 Прод упадет ровно в 23:59 31 декабря, но ты будешь спать.",
"💰 Рекрутеры перестанут предлагать 'интересные проекты' за еду.",
"🤖 Скайнет откладывается: нейросеть научится только центрировать div.",
]
Совет: предложите в комментариях читателям накидать своих вариантов — это повысит вовлеченность.
3. Рисуем елку и считаем время
Rich позволяет стилизовать текст тегами, похожими на BBCode. Мы сделаем функцию, которая возвращает красивый объект Text.
def generate_tree():
"""Возвращает ASCII-елку как объект Rich Text"""
tree_art = """
🌟
/ \\
/ 🎄 \\
/ ✨ \\
/ 💾 \\
/ 🐍 🐛 \\
/____________\\
||||
"""
# Красим елку в зеленый, выравниваем по центру
return Text(tree_art, style="bold green justify_center")
def get_time_left():
"""Считает разницу между сейчас и НГ 2026"""
now = datetime.now()
target = datetime(2026, 1, 1, 0, 0, 0)
diff = target - now
if diff.total_seconds() <= 0:
return "🎉 С НОВЫМ 2026 ГОДОМ! 🎉"
# Математика времени
days = diff.days
hours, remainder = divmod(diff.seconds, 3600)
minutes, seconds = divmod(remainder, 60)
return f"{days}д {hours:02}ч {minutes:02}м {seconds:02}с"
4. Собираем всё вместе (Main Loop)
Самое интересное здесь — использование Layout. Мы делим экран на три части (Header, Body, Footer) и обновляем их внутри контекстного менеджера Live. Это позволяет избежать мерцания экрана, которое бывает при обычном cls / clear.
@app.command()
def start():
"""Запуск новогоднего CLI"""
console.clear()
# 1. Создаем макет
layout = Layout()
layout.split_column(
Layout(name="header", size=3),
Layout(name="body", ratio=1),
Layout(name="footer", size=3)
)
# 2. Инициализируем статику (заголовок и предсказание)
prediction = random.choice(PREDICTIONS)
layout["header"].update(
Panel(Align.center("[bold magenta]🎄 NY 2026 COUNTDOWN 🎄[/]"), style="blue")
)
layout["footer"].update(
Panel(Align.center(f"[italic yellow]Oracle says: {prediction}[/]"),
title="🔮 Предсказание на 2026", style="purple")
)
# 3. Запускаем живой цикл
# refresh_per_second=4 дает плавность, но не грузит CPU
with Live(layout, refresh_per_second=4, screen=True):
while True:
time_left = get_time_left()
# Если наступил праздник — меняем стиль
if "С НОВЫМ" in time_left:
final_text = Text("\n\n" + time_left, style="bold red blink", justify="center")
layout["body"].update(final_text)
time.sleep(10) # Даем насладиться моментом
break
# Собираем контент центральной части
content = Text()
content.append(generate_tree())
content.append("\n\n")
content.append("До 2026 года осталось:\n", style="bold white justify_center")
content.append(time_left, style="bold cyan justify_center")
# Центрируем всё по вертикали и горизонтали
layout["body"].update(Align.center(content, vertical="middle"))
time.sleep(0.1) # Небольшая пауза для цикла
if __name__ == "__main__":
app()
Запускаем и наслаждаемся:
python main.py
В результате вы должны увидеть аккуратный интерфейс, который обновляется каждую секунду, не дергается и выглядит так, будто вы хакер из киберпанк-фильма, только добрый и праздничный.

Как упаковать: Делимся праздником (даже с HR)
Код работает у вас локально — это прекрасно. Но если вы скинете файл .py менеджеру или другу-дизайнеру, они вряд ли оценят необходимость устанавливать Python и виртуальное окружение.
Давайте соберем из этого полноценный бинарный файл (.exe для Windows или исполняемый файл для Linux/macOS).
1. Ставим сборщик
Нам понадобится PyInstaller. Он умеет анализировать импорты и запихивать всё необходимое в один файл.
pip install pyinstaller
2. Собираем «экзешник»
Чтобы получить один удобный файл (а не папку с кучей библиотек), используем флаг --onefile. А чтобы файл назывался красиво, добавим --name.
Выполняем в терминале:
pyinstaller --onefile --name "NY2026" main.py
После того как в консоли пробегут сотни строк логов (выглядит очень хакерски), у вас появятся две папки: build и dist.
Наш драгоценный файл лежит в папке dist/.
Windows:
dist\NY2026.exeLinux/Mac:
dist/NY2026
3. Совет для перфекционистов (Иконка)
Если вы хотите, чтобы приложение выглядело совсем как "настоящее", найдите любую иконку в формате .ico (например, елку) и положите рядом.
Команда сборки немного изменится:
pyinstaller --onefile --icon=tree.ico --name "NY2026" main.py
Теперь файл будет с красивой иконкой, и его не стыдно скинуть в рабочий чат с подписью: "Коллеги, важный апдейт по планам на 2026 год, срочно запустите!".
Важно: Прежде чем отправлять .exe коллегам, убедитесь, что служба безопасности вашей компании не примет это за фишинговую атаку. Не нарушайте корпоративные правила ИБ, лучше скиньте ссылку на репозиторий или покажите на своем экране
Важное примечание про кросс-платформенность
PyInstaller собирает бинарник под ту операционную систему, на которой запущен.
Хотите
.exeдля Windows? Запускайте сборку на Windows.Хотите бинарник для macOS? Собирайте на маке.
Если у вас Linux, а другу с Windows хочется отправить подарок — проще всего воспользоваться CI/CD (GitHub Actions), но это уже тема для отдельной, не такой праздничной статьи. Либо просто найдите друга с виндой.
Заключение: Встречаем 2026-й во всеоружии
Ну что, теперь у вас есть собственный карманный генератор новогоднего настроения. Да, это не стартап, но именно такие маленькие проекты напоминают нам, почему мы вообще когда-то полюбили программирование. Это возможн��сть создать что-то из ничего, нарисовать елку символами и заставить компьютер поздравлять нас.
Не бойтесь модифицировать код: добавьте музыку (через простые библиотеки звука), поменяйте цвета на корпоративные или перепишите предсказания под реалии вашей команды.
Исходный код и вопросы
Весь код из статьи можно использовать свободно. Если же у вас возникнут трудности с запуском, PyInstaller выдаст непонятную ошибку или вы захотите предложить свою версию «айтишных предсказаний» — заглядывайте в мой Telegram-блог.
Там мы обсуждаем этот проект, я отвечаю на вопросы, и если что-то пойдет не так при сборке — помогу разобраться.
С наступающим Новым 2026 годом, Хабр! 🎄
Пусть в новом году ваш аптайм будет 99.99%, легаси переписывается само, а все баги оказываются фичами.
Увидимся в будущем!