59 lines
2.7 KiB
Python
59 lines
2.7 KiB
Python
import streamlit as st
|
|
import pandas as pd
|
|
import altair as alt
|
|
|
|
from backend.db import Session
|
|
|
|
|
|
def stats_ui(session: Session, grades_table: pd.DataFrame, grades: list):
|
|
with st.expander('Statistiken'):
|
|
number_students = len(session.points_df)
|
|
number_participants = len(session.points_df[session.points_df['Punkte'].notna()])
|
|
|
|
if number_participants > 0:
|
|
# Convert from categorical strings to numerical values
|
|
points_table = session.points_df.reset_index()[['Punkte', 'Note']].copy().dropna()
|
|
points_table['Note'] = points_table['Note'].apply(lambda x: float(f'{x}'.replace(',', '.')))
|
|
grades_tab = grades_table['Note'].apply(lambda x: float(f'{x}'.replace(',', '.')))
|
|
|
|
score_hist = pd.DataFrame({'Anzahl': [0] * len(grades_tab)}, index=grades_tab)
|
|
counts = pd.DataFrame(points_table['Note'].value_counts().rename('Anzahl'))
|
|
score_hist.update(counts)
|
|
score_hist.reset_index(inplace=True)
|
|
|
|
hist = alt.Chart(score_hist).mark_bar().encode(
|
|
x=alt.X('Anzahl:Q', axis=alt.Axis(title='Anzahl', tickCount=score_hist['Anzahl'].max()+1, grid=True)),
|
|
y=alt.Y('Note:O', bin=alt.Bin(binned=True), axis=alt.Axis(title='Note', grid=True))
|
|
)
|
|
|
|
median = alt.Chart(points_table).mark_rule(color='blue', opacity=0.5).encode(
|
|
y = 'median(Note):O',
|
|
size=alt.value(5),
|
|
)
|
|
|
|
mean = alt.Chart(points_table).mark_rule(color='orange', opacity=0.5, strokeDash=[5,5]).encode(
|
|
y = 'mean(Note):O',
|
|
size=alt.value(5),
|
|
)
|
|
|
|
chart = (hist + median + mean)
|
|
|
|
st.altair_chart(chart, use_container_width=True)
|
|
|
|
passed = 1-score_hist.iloc[-1]["Anzahl"]/number_participants
|
|
1-score_hist.iloc[-1]["Anzahl"]/number_participants
|
|
left, mid, right, rightmost = st.columns(4)
|
|
with left:
|
|
st.write(f'Anzahl Anmeldungen: {number_students}')
|
|
st.write(f'Anzahl Teilnehmer: {number_participants}')
|
|
with mid:
|
|
st.write(f'Bestanden: :green[{passed*100:.2f} %]')
|
|
st.write(f'Durchgefallen: :red[{100-passed*100:.2f}%]')
|
|
with right:
|
|
st.write(f'Punkteuntergrenzen: :gray[(1,0)] {session.grade_1_0:.2f}% / :gray[(4,0)] {session.grade_4_0:.2f}%')
|
|
st.write(f'Maximalpunktzahl: {session.max_points}')
|
|
with rightmost:
|
|
st.write(f':orange[Durchschnitt:] {points_table["Note"].mean():.2f}')
|
|
st.write(f':blue[Median:] {points_table["Note"].median():.2f}')
|
|
else:
|
|
st.write(':orange[Keine Teilnehmer]') |