first version of the program
This commit is contained in:
parent
bfd01ad04b
commit
5d0c1614c8
8
data/students.csv
Normal file
8
data/students.csv
Normal file
@ -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;Математика
|
||||||
|
153
src/main.py
153
src/main.py
@ -1,45 +1,156 @@
|
|||||||
|
import csv
|
||||||
|
from collections import defaultdict
|
||||||
|
|
||||||
def load_students(filepath):
|
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):
|
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):
|
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):
|
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):
|
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):
|
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):
|
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 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 remove_duplicate_records(records):
|
||||||
|
seen = set()
|
||||||
|
unique = []
|
||||||
|
for r in records:
|
||||||
def export_grade_report(records, output_file):
|
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():
|
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__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
Loading…
Reference in New Issue
Block a user