Комментарии 15
Метод прикольный, но как по мне вести его в тетрадке неудобно, как минимум потому что даты дедлайнов будут нечитабельны при большом объеме заданий -> было бы прикольно дополнить статью удобными сервисами для этого метода
Я бы лично не пользовался этим методом, так как на протяжении 2.5 лет обучения в университете получается держать все задания и дедлайны по ним в голове + даже никогда не задумывался о переносе этих данных куда-нибудь из головы
import datetime
import json
import os
class StudyTracker:
def __init__(self, filename="study_tracker.json"):
"""Инициализация трекера учебных задач"""
self.filename = filename
self.subjects = {}
self.current_sprint = 1
self.sprint_duration = 30 # дней
self.load_data()
def add_subject(self, subject_name, tasks):
"""
Добавление предмета с задачами
Args:
subject_name (str): Название предмета
tasks (list): Список задач в формате [{'name': 'ЛР1', 'deadline': '2026-02-15'}, ...]
"""
self.subjects[subject_name] = {
'tasks': tasks,
'closed': False,
'progress': 0
}
self.save_data()
def complete_task(self, subject_name, task_index):
"""Отметка задачи как выполненной"""
if subject_name in self.subjects:
tasks = self.subjects[subject_name]['tasks']
if 0 <= task_index < len(tasks):
tasks[task_index]['completed'] = True
tasks[task_index]['completed_date'] = datetime.datetime.now().strftime('%Y-%m-%d')
# Обновление прогресса
completed_count = sum(1 for task in tasks if task.get('completed', False))
total_count = len(tasks)
self.subjects[subject_name]['progress'] = int((completed_count / total_count) * 100)
# Проверка, все ли задачи выполнены
if completed_count == total_count:
self.subjects[subject_name]['closed'] = True
self.save_data()
return True
return False
def get_priority_tasks(self):
"""Получение задач, отсортированных по дедлайну"""
all_tasks = []
for subject_name, subject_data in self.subjects.items():
if not subject_data['closed']:
for i, task in enumerate(subject_data['tasks']):
if not task.get('completed', False):
all_tasks.append({
'subject': subject_name,
'task': task['name'],
'deadline': task.get('deadline', 'Нет дедлайна'),
'index': i,
'progress': subject_data['progress']
})
# Сортировка по дедлайну
def get_date(task):
deadline = task['deadline']
if deadline == 'Нет дедлайна':
return datetime.date.max
try:
return datetime.datetime.strptime(deadline, '%Y-%m-%d').date()
except:
return datetime.date.max
return sorted(all_tasks, key=get_date)
def start_new_sprint(self):
"""Начало нового спринта"""
self.current_sprint += 1
print(f"🎯 Начинаем спринт #{self.current_sprint}")
self.save_data()
def display_progress(self):
"""Отображение прогресса по всем предметам"""
print("\n" + "="*50)
print(f"📊 ПРОГРЕСС УЧЕБЫ (Спринт #{self.current_sprint})")
print("="*50)
for subject_name, subject_data in self.subjects.items():
status = "✅ ЗАКРЫТ" if subject_data['closed'] else "📚 АКТИВЕН"
print(f"\n{subject_name} - {status}")
print(f" Прогресс: {subject_data['progress']}%")
for i, task in enumerate(subject_data['tasks']):
status_icon = "✓" if task.get('completed', False) else "○"
deadline = task.get('deadline', 'Нет дедлайна')
print(f" {status_icon} {task['name']} - {deadline}")
# Показ приоритетных задач
priority_tasks = self.get_priority_tasks()[:5]
if priority_tasks:
print(f"\n🔥 БЛИЖАЙШИЕ ЗАДАЧИ:")
for task in priority_tasks:
print(f" • {task['subject']}: {task['task']} (до {task['deadline']})")
def calculate_semester_end(self, start_date, semester_months=5):
"""Расчет конца семестра"""
start = datetime.datetime.strptime(start_date, '%Y-%m-%d')
end = start + datetime.timedelta(days=semester_months * 30)
return end.strftime('%Y-%m-%d')
def save_data(self):
"""Сохранение данных в файл"""
data = {
'subjects': self.subjects,
'current_sprint': self.current_sprint,
'last_updated': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
}
with open(self.filename, 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=2)
def load_data(self):
"""Загрузка данных из файла"""
if os.path.exists(self.filename):
with open(self.filename, 'r', encoding='utf-8') as f:
data = json.load(f)
self.subjects = data.get('subjects', {})
self.current_sprint = data.get('current_sprint', 1)
def create_sample_semester():
"""Создание примера учебного семестра"""
tracker = StudyTracker()
# Предмет: Программирование
programming_tasks = [
{'name': 'ЛР1: Основы Python', 'deadline': '2026-02-10'},
{'name': 'ЛР2: ООП', 'deadline': '2026-02-24'},
{'name': 'РУБ1: Контрольная 1', 'deadline': '2026-03-10'},
{'name': 'ЛР3: Базы данных', 'deadline': '2026-03-24'},
{'name': 'ЛР4: Веб-приложение', 'deadline': '2026-04-07'},
{'name': 'РУБ2: Контрольная 2', 'deadline': '2026-04-21'},
{'name': 'ЭКЗ: Экзамен', 'deadline': '2026-05-15'}
]
# Предмет: Математика
math_tasks = [
{'name': 'ДЗ1: Линейная алгебра', 'deadline': '2026-02-05'},
{'name': 'ДЗ2: Математический анализ', 'deadline': '2026-02-19'},
{'name': 'КОНТР: Контрольная работа', 'deadline': '2026-03-05'},
{'name': 'ДЗ3: Диффуры', 'deadline': '2026-03-19'},
{'name': 'ЭКЗ: Экзамен', 'deadline': '2026-05-10'}
]
# Предмет: Физика
physics_tasks = [
{'name': 'ЛАБ1: Механика', 'deadline': '2026-02-15'},
{'name': 'ЛАБ2: Электричество', 'deadline': '2026-03-01'},
{'name': 'ОТЧЕТ: Отчет по практике', 'deadline': '2026-03-15'},
{'name': 'ЭКЗ: Экзамен', 'deadline': '2026-05-05'}
]
tracker.add_subject("Программирование", programming_tasks)
tracker.add_subject("Математика", math_tasks)
tracker.add_subject("Физика", physics_tasks)
return tracker
def main():
"""Основная функция программы"""
print("🎓 ГЕЙМИФИКАЦИЯ УЧЁБЫ В УНИВЕРСИТЕТЕ")
print("="*45)
print("Система планирования учебных задач")
print("Аналогично методике из статьи на Habr")
print("="*45)
# Создаем или загружаем трекер
tracker = StudyTracker()
if not tracker.subjects:
print("\nСоздаем пример учебного семестра...")
tracker = create_sample_semester()
print("✅ Пример создан! Можете начать работу.")
else:
print(f"\n✅ Загружены сохраненные данные ({len(tracker.subjects)} предметов)")
while True:
print("\n" + "="*45)
print("МЕНЮ:")
print("1. 📊 Показать прогресс")
print("2. ✅ Отметить выполненную задачу")
print("3. 🎯 Начать новый спринт")
print("4. 🔥 Показать ближайшие задачи")
print("5. 📝 Добавить новый предмет")
print("6. 💾 Сохранить и выйти")
print("="*45)
choice = input("\nВыберите действие (1-6): ").strip()
if choice == "1":
tracker.display_progress()
# Показываем статистику
total_subjects = len(tracker.subjects)
closed_subjects = sum(1 for s in tracker.subjects.values() if s['closed'])
print(f"\n📈 СТАТИСТИКА: {closed_subjects}/{total_subjects} предметов закрыто")
elif choice == "2":
tracker.display_progress()
print("\n--- Отметка выполненной задачи ---")
# Получаем активные предметы
active_subjects = [name for name, data in tracker.subjects.items() if not data['closed']]
if not active_subjects:
print("Все предметы уже закрыты! 🎉")
continue
print("\nАктивные предметы:")
for i, subject in enumerate(active_subjects, 1):
print(f"{i}. {subject}")
try:
subject_idx = int(input("\nНомер предмета: ")) - 1
if 0 <= subject_idx < len(active_subjects):
subject_name = active_subjects[subject_idx]
# Показываем задачи этого предмета
tasks = tracker.subjects[subject_name]['tasks']
print(f"\nЗадачи по предмету '{subject_name}':")
for i, task in enumerate(tasks):
status = "✓" if task.get('completed', False) else "○"
print(f"{i+1}. {status} {task['name']}")
task_idx = int(input("\nНомер задачи для отметки: ")) - 1
if tracker.complete_task(subject_name, task_idx):
print("✅ Задача отмечена как выполненная!")
else:
print("❌ Ошибка при отметке задачи")
else:
print("❌ Неверный номер предмета")
except ValueError:
print("❌ Пожалуйста, введите число")
elif choice == "3":
tracker.start_new_sprint()
tracker.display_progress()
elif choice == "4":
priority_tasks = tracker.get_priority_tasks()
if priority_tasks:
print("\n🔥 ПРИОРИТЕТНЫЕ ЗАДАЧИ (по дедлайну):")
for i, task in enumerate(priority_tasks[:10], 1):
print(f"{i}. {task['subject']}: {task['task']}")
print(f" 📅 Дедлайн: {task['deadline']}")
print(f" 📊 Прогресс предмета: {task['progress']}%")
print()
else:
print("🎉 Нет активных задач! Все выполнены.")
elif choice == "5":
print("\n--- Добавление нового предмета ---")
subject_name = input("Название предмета: ").strip()
tasks = []
print("\nДобавление задач (для завершения введите 'готово'):")
while True:
task_name = input("Название задачи (например, 'ЛР1'): ").strip()
if task_name.lower() == 'готово':
break
deadline = input("Дедлайн (ГГГГ-ММ-ДД или оставьте пустым): ").strip()
if not deadline:
deadline = "Нет дедлайна"
tasks.append({
'name': task_name,
'deadline': deadline,
'completed': False
})
print(f"✅ Задача '{task_name}' добавлена")
if tasks:
tracker.add_subject(subject_name, tasks)
print(f"✅ Предмет '{subject_name}' с {len(tasks)} задачами добавлен!")
else:
print("❌ Не добавлено ни одной задачи")
elif choice == "6":
tracker.save_data()
print("💾 Данные сохранены. До свидания!")
break
else:
print("❌ Неверный выбор. Попробуйте снова.")
if __name__ == "__main__":
main()Улучшенная версия :)
используете какой-то радикально другой способ планирования задач
Берешь задачу, которую тебе действительно очень важно сделать. Отбрасываешь все остальные. Делаешь эту задачу до тех пор, пока можешь физически и ментально. Сделал - научился, причем лучше, чем 99% людей. Не сделал - походу, не особо важная была задача, корректируем целеполагание.
Вот я именно так всю жизнь привык делать дела. В принципе, даже очень эффективным бываю.
Но, к сожалению, если в жизни много задач, а не одна, то этот метод становится максимально неэффективным. Потому, что фокусируясь на одной задаче, в остальных постоянно провалы и критические.
Вот тут-то мы и подбираемся к сути. Оказывается, можно отмодерировать свою жизнь так, чтобы всегда была одна и только одна действительно важная задача.
Социальный статус, семья, дети, ожидания родственников, религия - всё это и многое другое идёт по боку (в моем случае). Нахрен отправляется всё, что не связано с текущей задачей, и выполняется исключительно по остаточному принципу, если выполнение основной задачи в данный момент невозможно / нерационально.
Об этом любопытно размышлять. Вспоминая свою жизнь я понимаю, что всё важное, что было мною сделано, было сделано именно так. А масса казавшихся "очень важными" сопутствующих задач со временем вообще испарились из памяти.
А если копнуть ещё глубже, то оказывается, что это ещё и основное отличие меня от других людей: все "обычные" люди не держат по-настоящему фокус на том, что делают, и именно поэтому катастрофически отстают от меня во всем, чем я хоть раз занимался всерьез.
Возможно, это звучит как бахвальство, но на самом деле это довольно амбивалентное положение: сложно быть лучшим. Сложно находить социальные связи, поскольку интересно только с такими же людьми, а их мало; требования к любому партнерству растут. Исчезает "легкость" общения, и возможно, сужается кругозор (но это не точно). Ну и ментально это тоже непросто, гиперфокус опасен для психики, и, вероятно, провоцирует легкое биполярное расстройство (или наоборот?). Поэтому стабильно возникают и неприятные депрессивные эпизоды.
Не считаю бахвальством, потому что фокус и моя сильная сторона. И это действительно даёт мне очень сильное преимущество. Я правда многих обходил, и с большим отрывом.
Но, в момент фокуса у меня плохо с переключением задач. И страдает режим дня, быт, питание. Я превращаюсь в бытового инвалида.
А если сосредотаяиваюсь на быте, питании, готовке - хорошо выходит. Но, на рабочие задачи внимание минимальное. И результаты такие же.
Поэтому и ищу всю жизнь какую-то систему, которая позволяла бы переключать фокус, не теряя эффективность. Пока получается с перекосами. 🤷
Я пробую не бороться, а принять и подстроиться. Фокус переключать редко - несколько дней гиперпогружения в задачу, потом неделя или сколько понадобится отдыха на восстановление.
К моменту следующего погружения быт должен быть максимально отлажен - порядок и чистота, запас хороших продуктов на несколько дней, отдохнувшая голова, заправленный мотоцикл. В период гиперфокуса на задаче, кроме неё в жизни остается только спорт, мотоцикл и Black Label по вечерам.
Мультиварку советую купить. Простая в обращении и реально многофункциональная. Каши с овощами, всякие запеканки, тушение, варение и иногда жарка в одном удобном устройстве. Моё питание поменялось на до и после после покупки мультиварки и блендера.
Геймификация? Была у меня когда-то идея для олдскульной геймификации: организовать планирование задач а-ля Дюна 2

Очень упрощенная схема. Больше подходит к сдаче тестов в муддле:)
То что у Вас абсолютно правильно - это сводный анализ предметов сразу в начале "сезона".
Но в нем не отражены ни типы аттестаций, ни важность дедлайнов, ни желательная оценка, ни тип сдачи, ни особенности преподавателя.
Разница между предметом где в конце экзамен и зачет радикальная, первое лучше сдавать сразу, а второе можно и в долги задвинуть. Разница между курсовой и лабораторной тоже радикальная, курсовая это долго но в свое время, а лабораторная это быстро но в строгое время и обычно в группе с кем-то. По некоторым предметам достаточно из 5 лабораторных сдать 3 и посещать все занятия или можно сдать все лабы но не ходить ни на одну лекцию, тоже нюанс важный. И так далее.
Вообще когда начали читать топик - ожидали чего-то такого :)
картинка

Как по мне это просто линейное расписание, в моём понимании геймификация это нечто другое, где главный смысл в системе прокачки, тут ведь даже понятно, что лабораторки дают по 1-2 экспы, а курсач что-то вроде 15)

Геймификация учёбы в университете и мой опыт планирования