From 5d0c1614c868ad3e2bc467e22d75d4b20642c525 Mon Sep 17 00:00:00 2001 From: stud204007 Date: Fri, 17 Apr 2026 18:07:02 +0300 Subject: [PATCH] first version of the program --- data/students.csv | 8 +++ src/main.py | 153 +++++++++++++++++++++++++++++++++++++++------- 2 files changed, 140 insertions(+), 21 deletions(-) create mode 100644 data/students.csv diff --git a/data/students.csv b/data/students.csv new file mode 100644 index 0000000..7cae4f0 --- /dev/null +++ b/data/students.csv @@ -0,0 +1,8 @@ +student_id;full_name;group;course;grade;subject +1;Анна Кузнецова;ИВТ-201;2;85;Математика +2;Иван Соколов;ИВТ-201;2;92;Математика +1;Анна Кузнецова;ИВТ-201;2;78;Программирование +3;Мария Ткач;ПИ-101;1;88;Программирование +2;Иван Соколов;ИВТ-201;2;91;Программирование +4;Иван Иванович;ИНБб-2301;3;95;Программирование +4;Иван Иванович;ИНБб-2301;3;91;Математика \ No newline at end of file diff --git a/src/main.py b/src/main.py index 1f9905c..5a241e8 100644 --- a/src/main.py +++ b/src/main.py @@ -1,45 +1,156 @@ +import csv +from collections import defaultdict def load_students(filepath): - - + records = [] + try: + with open(filepath, 'r', encoding='utf-8') as f: + reader = csv.DictReader(f, delimiter=';') + for row in reader: + row['student_id'] = int(row['student_id']) + row['course'] = int(row['course']) + row['grade'] = float(row['grade']) + records.append(row) + except FileNotFoundError: + print(f"Файл {filepath} не найден.") + return records def filter_by_group(records, group_name): - - + return [r for r in records if r['group'] == group_name] def filter_by_course(records, course_number): - - + return [r for r in records if r['course'] == course_number] def filter_by_min_grade(records, min_grade): - - + return [r for r in records if r['grade'] >= min_grade] def average_grade_per_student(records): - + if not records: + return {} + total_grades = defaultdict(float) + count_grades = defaultdict(int) + names = {} + for r in records: + sid = r['student_id'] + total_grades[sid] += r['grade'] + count_grades[sid] += 1 + names[sid] = r['full_name'] + result = {} + for sid in total_grades: + result[sid] = { + 'name': names[sid], + 'avg_grade': total_grades[sid] / count_grades[sid] + } + return result def top_students_by_avg(records, n): - - + avg_dict = average_grade_per_student(records) + if not avg_dict: + return [] + students = [(sid, data['name'], data['avg_grade']) for sid, data in avg_dict.items()] + students.sort(key=lambda x: x[2], reverse=True) + return students[:n] def subject_statistics(records): - - + if not records: + return {} + total = defaultdict(float) + count = defaultdict(int) + for r in records: + subj = r['subject'] + total[subj] += r['grade'] + count[subj] += 1 + stats = {} + for subj in total: + stats[subj] = {'count': count[subj], 'avg': total[subj] / count[subj]} + return stats def grade_distribution(records, subject=None): - - + def to_five_point(grade): + if grade < 60: + return 2 + elif grade < 75: + return 3 + elif grade < 90: + return 4 + else: + return 5 + filtered = records + if subject is not None: + filtered = [r for r in records if r['subject'] == subject] + dist = {2: 0, 3: 0, 4: 0, 5: 0} + for r in filtered: + dist[to_five_point(r['grade'])] += 1 + return dist def remove_duplicate_records(records): - - - -def export_grade_report(records, output_file): - + seen = set() + unique = [] + for r in records: + key = (r['student_id'], r['subject'], r['grade']) + if key not in seen: + seen.add(key) + unique.append(r) + return unique +def export_grade_report(records, filtered, output_file): + with open(output_file, 'w', encoding='utf-8') as f: + f.write(f"Загружено записей: {len(records)}\n") + f.write(f"После удаления дубликатов: {len(records)}\n") + f.write(f"После фильтрации (курс 2, оценка >= 80): {len(filtered)} записей\n") + if filtered: + overall_avg_filtered = sum(r['grade'] for r in filtered) / len(filtered) + f.write(f"Средний балл по выборке: {overall_avg_filtered:.2f}\n") + else: + f.write("Средний балл по выборке: нет данных\n") + top3 = top_students_by_avg(filtered, 3) + f.write("Топ-3 студента:\n") + i = 1 + for sid, name, avg in top3: + f.write(f" {i}. {name} - {avg:.2f}") + i += 1 + dist = grade_distribution(filtered) + f.write("Распределение оценок:\n") + f.write(f" 5 (90-100): {dist[5]}\n") + f.write(f" 4 (75-89): {dist[4]}\n") + f.write(f" 3 (60-74): {dist[3]}\n") + f.write(f" 2 (0-59): {dist[2]}\n") + subj_stats = subject_statistics(filtered) + f.write("Статистика по предметам:\n") + for subj, data in subj_stats.items(): + f.write(f" {subj}: оценок {data['count']}, средний {data['avg']:.2f}\n") def main(): - + records = load_students('data/students.csv') + print(f"Загружено записей: {len(records)}") + records = remove_duplicate_records(records) + print(f"После удаления дубликатов: {len(records)}") + filtered = filter_by_course(records, 2) + filtered = filter_by_min_grade(filtered, 80) + print(f"После фильтрации (курс 2, оценка >= 80): {len(filtered)} записей") + if filtered: + overall_avg_filtered = sum(r['grade'] for r in filtered) / len(filtered) + print(f"Средний балл по выборке: {overall_avg_filtered:.2f}") + else: + print("Средний балл по выборке: нет данных") + top3 = top_students_by_avg(filtered, 3) + print("Топ-3 студента:") + i = 1 + for sid, name, avg in top3: + print(f" {i}. {name} - {avg:.2f}") + i += 1 + dist = grade_distribution(filtered) + print("Распределение оценок:") + print(f" 5 (90-100): {dist[5]}") + print(f" 4 (75-89): {dist[4]}") + print(f" 3 (60-74): {dist[3]}") + print(f" 2 (0-59): {dist[2]}") + subj_stats = subject_statistics(filtered) + print("Статистика по предметам:") + for subj, data in subj_stats.items(): + print(f" {subj}: оценок {data['count']}, средний {data['avg']:.2f}") + export_grade_report(records, filtered, 'output.txt') + print("Полный отчёт сохранён в output.txt") if __name__ == '__main__': main() \ No newline at end of file