import pandas as pd import matplotlib.pyplot as plt import seaborn as sns from django.shortcuts import render from .forms import CSVUploadForm import io import base64 def get_plot_image(): buffer = io.BytesIO() plt.savefig(buffer, format='png', bbox_inches='tight') buffer.seek(0) image_png = buffer.getvalue() buffer.close() return base64.b64encode(image_png).decode('utf-8') def upload_csv(request): charts = [] if request.method == "POST" and request.FILES.get("csv_file"): form = CSVUploadForm(request.POST, request.FILES) if form.is_valid(): csv_file = request.FILES["csv_file"] df = pd.read_csv(csv_file) df.columns = df.columns.str.strip() # Remove any spaces in headers # Validate required columns required_columns = ['Semester', 'Geschlecht', 'Fakultät', 'Wie hast du von diesem Kurs erfahren?'] missing = [col for col in required_columns if col not in df.columns] if missing: print('test') return render(request, 'reports/upload.html', { 'form': form, 'error': f'Missing required columns: {", ".join(missing)}' }) sns.set_theme(style="whitegrid") # 1. Semester Distribution semester_counts = df['Semester'].value_counts().sort_index() plt.figure(figsize=(8, 4)) sns.lineplot(x=semester_counts.index, y=semester_counts.values, marker="o") plt.title("Semester Distribution") plt.xlabel("Semester") plt.ylabel("Number of Students") charts.append(get_plot_image()) plt.close() # 2. Gender Distribution gender_counts = df['Geschlecht'].value_counts() plt.figure(figsize=(6, 4)) ax = sns.barplot(x=gender_counts.index, y=gender_counts.values, palette="pastel", hue=gender_counts.index, legend=False) for i, v in enumerate(gender_counts.values): ax.text(i, v + 0.2, str(v), color='black', ha='center', fontweight='bold') plt.title("Gender Distribution") plt.xlabel("Gender") plt.ylabel("Number of Students") charts.append(get_plot_image()) plt.close() # 3. Faculty Distribution df['Fakultät'] = df['Fakultät'].replace({ 'B (Biotechnologie)': 'B', 'N (Informationstechnik)': 'N', 'M (Maschinenbau)': 'M', 'I (Informatik)': 'I', 'E (Elektrotechnik)': 'E', }) faculty_counts = df['Fakultät'].value_counts() plt.figure(figsize=(6, 4)) ax = sns.barplot(x=faculty_counts.index, y=faculty_counts.values, palette="muted", hue=faculty_counts.index, legend=False) for i, v in enumerate(faculty_counts.values): ax.text(i, v + 0.2, str(v), color='black', ha='center', fontweight='bold') plt.title("Faculty Distribution") plt.xlabel("Faculty") plt.ylabel("Number of Students") charts.append(get_plot_image()) plt.close() print('test2') # 4. Course Discovery (Pie Chart) course_source_counts = df['Wie hast du von diesem Kurs erfahren?'].value_counts() plt.figure(figsize=(6, 6)) plt.pie(course_source_counts, labels=course_source_counts.index, autopct='%1.1f%%', startangle=140) plt.title("How Did Students Hear About the Course?") charts.append(get_plot_image()) plt.close() return render(request, 'reports/upload.html', { 'form': form, 'charts': charts }) else: form = CSVUploadForm() return render(request, 'reports/upload.html', {'form': form})