/
CW3
/
The_Project
Обзор
Документация
Войти
/
CW3
/
The_Project
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
scripts/analyze_student.py
210 строк
9 KB
CW3
Initial project setup with structure and CI/CD
28 дек 2025, 12:40
28 дек 2025, 12:40
5cacb7a
Код
Авторство
О чём код?
#!/usr/bin/env python3 """ Скрипт для анализа конкретного студента """ import argparse import sys import os sys.path.append('.') import pandas as pd import matplotlib.pyplot as plt from datetime import datetime from pathlib import Path from src.data.log_parser import LMSLogParser from src.analysis.activity_analyzer import ActivityAnalyzer def create_simple_visualization(student_logs: pd.DataFrame, student_id: int, report_dir: Path) -> str: """ Создание простой визуализации активности студента Returns: Путь к сохраненному файлу """ try: fig, axes = plt.subplots(2, 2, figsize=(12, 10)) # 1. Распределение по типам событий event_counts = student_logs['event_type'].value_counts() if not event_counts.empty: axes[0, 0].bar(event_counts.index, event_counts.values, color=['skyblue', 'lightcoral', 'lightgreen', 'gold', 'violet']) axes[0, 0].set_xlabel('Тип события') axes[0, 0].set_ylabel('Количество') axes[0, 0].set_title('Типы активности') axes[0, 0].tick_params(axis='x', rotation=45) # 2. Распределение по курсам course_counts = student_logs['course_id'].value_counts() if not course_counts.empty: axes[0, 1].bar(course_counts.index, course_counts.values, color='orange') axes[0, 1].set_xlabel('Курс') axes[0, 1].set_ylabel('Количество') axes[0, 1].set_title('Активность по курсам') axes[0, 1].tick_params(axis='x', rotation=45) # 3. Временная шкала (упрощенная) if 'timestamp' in student_logs.columns: student_logs['timestamp'] = pd.to_datetime(student_logs['timestamp']) student_logs['date'] = student_logs['timestamp'].dt.date daily_activity = student_logs.groupby('date').size() if not daily_activity.empty: axes[1, 0].plot(range(len(daily_activity)), daily_activity.values, marker='o', linestyle='-', color='green') axes[1, 0].set_xlabel('Дни') axes[1, 0].set_ylabel('Событий в день') axes[1, 0].set_title('Активность по дням') axes[1, 0].grid(True, alpha=0.3) # 4. Распределение по часам if 'timestamp' in student_logs.columns: student_logs['hour'] = student_logs['timestamp'].dt.hour hour_counts = student_logs['hour'].value_counts().sort_index() if not hour_counts.empty: axes[1, 1].bar(hour_counts.index, hour_counts.values, color='lightblue') axes[1, 1].set_xlabel('Час дня') axes[1, 1].set_ylabel('Количество событий') axes[1, 1].set_title('Активность по времени суток') axes[1, 1].set_xticks(range(0, 24, 3)) plt.suptitle(f'Анализ активности студента {student_id}', fontsize=16, fontweight='bold') plt.tight_layout() # Сохраняем график plot_path = report_dir / f"activity_{datetime.now().strftime('%Y%m%d')}.png" plt.savefig(plot_path, dpi=150, bbox_inches='tight') plt.close() return str(plot_path) except Exception as e: print(f"⚠️ Не удалось создать визуализацию: {e}") return None def analyze_student(student_id: int, logs_file: str = 'data/sample_logs.csv'): """ Анализ пути обучения конкретного студента Args: student_id: ID студента для анализа logs_file: Путь к файлу логов """ print(f"🎓 Анализ студента {student_id}") # Создаем директорию для отчетов report_dir = Path(f"reports/students/{student_id}") report_dir.mkdir(parents=True, exist_ok=True) # 1. Загрузка данных parser = LMSLogParser(logs_file) logs_df = parser.load_logs() # Проверяем, существует ли студент if student_id not in logs_df['student_id'].values: print(f"❌ Студент {student_id} не найден в логах") print(f"Доступные студенты: {sorted(logs_df['student_id'].unique())[:10]}...") return False # 2. Получение данных студента student_logs = parser.get_student_activity(student_id) print(f"📊 Найдено {len(student_logs)} записей для студента {student_id}") # 3. Анализ активности analyzer = ActivityAnalyzer(student_logs) student_metrics = analyzer.calculate_activity_metrics() if len(student_metrics) > 0: student_data = student_metrics.iloc[0] print(f"\n📈 МЕТРИКИ СТУДЕНТА {student_id}:") print(f"• Всего событий: {student_data['total_events']}") print(f"• Активных дней: {student_data['active_days']}") print(f"• Среднее событий в день: {student_data['avg_events_per_day']:.1f}") print(f"• Предпочтительный курс: {student_data['preferred_course']}") # Распределение по типам событий print(f"\n📋 РАСПРЕДЕЛЕНИЕ СОБЫТИЙ:") for event_type, count in student_data['event_distribution'].items(): print(f" {event_type}: {count}") # 4. Идентификация паттерна обучения patterns_df = analyzer.identify_learning_patterns() if len(patterns_df) > 0: pattern = patterns_df.iloc[0]['learning_pattern'] print(f"\n🔍 ПАТТЕРН ОБУЧЕНИЯ: {pattern}") # 5. Создаем визуализацию plot_path = create_simple_visualization(student_logs, student_id, report_dir) if plot_path: print(f"📊 Визуализация сохранена: {plot_path}") # 6. Сохранение отчета report_path = report_dir / f"report_{datetime.now().strftime('%Y%m%d')}.txt" with open(report_path, 'w', encoding='utf-8') as f: f.write(f"ОТЧЕТ ПО СТУДЕНТУ {student_id}\n") f.write(f"Дата анализа: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n") f.write("=" * 50 + "\n\n") if len(student_metrics) > 0: student_data = student_metrics.iloc[0] f.write("МЕТРИКИ АКТИВНОСТИ:\n") f.write(f"- Всего событий: {student_data['total_events']}\n") f.write(f"- Активных дней: {student_data['active_days']}\n") f.write(f"- Среднее событий в день: {student_data['avg_events_per_day']:.1f}\n") f.write(f"- Предпочтительный курс: {student_data['preferred_course']}\n\n") f.write("РАСПРЕДЕЛЕНИЕ СОБЫТИЙ:\n") for event_type, count in student_data['event_distribution'].items(): f.write(f" {event_type}: {count}\n") f.write(f"\nПАТТЕРН ОБУЧЕНИЯ: {pattern}\n") f.write(f"\nРЕКОМЕНДАЦИИ:\n") f.write("- Увеличьте разнообразие учебной активности\n") f.write("- Регулярно проверяйте новые материалы\n") f.write("- Участвуйте в обсуждениях на форуме\n") f.write("- Своевременно сдавайте задания\n") if plot_path: f.write(f"\nВИЗУАЛИЗАЦИИ:\n") f.write(f"- График активности: {plot_path}\n") print(f"\n✅ Отчет сохранен: {report_path}") return True def main(): """Основная функция скрипта""" parser = argparse.ArgumentParser(description='Анализ пути обучения студента') parser.add_argument('--student-id', type=int, required=True, help='ID студента для анализа') parser.add_argument('--logs-file', type=str, default='data/sample_logs.csv', help='Путь к файлу логов (по умолчанию: data/sample_logs.csv)') args = parser.parse_args() # Проверяем существование файла логов if not os.path.exists(args.logs_file): print(f"⚠️ Файл логов {args.logs_file} не найден") print("Создаем примерные данные...") from src.data.log_parser import generate_sample_logs_csv generate_sample_logs_csv(args.logs_file, 1000) # Запускаем анализ success = analyze_student(args.student_id, args.logs_file) if success: print("\n🎉 Анализ завершен успешно!") else: print("\n❌ Анализ завершен с ошибками") sys.exit(1) if __name__ == "__main__": main()