97 lines
3.8 KiB
Python
97 lines
3.8 KiB
Python
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})
|