import numpy as np
import pandas as pd

# Dane demonstracyjne. W realnym badaniu wczytaj surowy, niezmieniony plik.
dane = pd.DataFrame(
    {
        "id": range(1, 11),
        "sr1": [4, 3, 5, 2, 4, 1, 3, 5, 2, 4],
        "sr2": [4, 4, 5, 3, np.nan, 2, 3, 4, 2, 5],
        "sr3": [2, 2, 1, 4, 2, 5, 3, 1, 4, 2],  # pozycja odwrócona
        "sr4": [5, 4, 5, 2, 4, 1, 4, 5, 3, 4],
        "zajecia_planowane": [10, 10, 10, 10, 10, 10, 10, 10, 0, 10],
        "zajecia_obecne": [9, 8, 10, 6, 8, 4, 7, 9, 0, 11],
        "wynik_egzaminu": [88, 79, 95, 62, 82, 48, 73, 91, 67, 86],
    }
)

# 1. Kontrola zakresu pozycji przed utworzeniem wyniku.
pozycje = ["sr1", "sr2", "sr3", "sr4"]
poza_zakresem = ~dane[pozycje].isna() & ~dane[pozycje].isin(range(1, 6))
if poza_zakresem.any().any():
    raise ValueError("Pozycje skali zawierają wartości spoza zakresu 1–5.")

# 2. Rekodowanie zgodne z kluczem: dla skali 1–5 wynik odwrócony = 6 - wynik.
dane["sr3_r"] = 6 - dane["sr3"]
pozycje_po_kluczu = ["sr1", "sr2", "sr3_r", "sr4"]

# 3. Wynik jest średnią tylko wtedy, gdy dostępne są co najmniej 3 z 4 pozycji.
dane["liczba_waznych_pozycji"] = dane[pozycje_po_kluczu].notna().sum(axis=1)
dane["samoregulacja"] = dane[pozycje_po_kluczu].mean(axis=1)
dane.loc[dane["liczba_waznych_pozycji"] < 3, "samoregulacja"] = np.nan

# 4. Frekwencja ma sens tylko przy dodatnim mianowniku i liczniku 0...mianownik.
poprawna_frekwencja = (
    dane["zajecia_planowane"].gt(0)
    & dane["zajecia_obecne"].ge(0)
    & dane["zajecia_obecne"].le(dane["zajecia_planowane"])
)
dane["frekwencja"] = np.where(
    poprawna_frekwencja,
    dane["zajecia_obecne"] / dane["zajecia_planowane"],
    np.nan,
)
dane["blad_frekwencji"] = ~poprawna_frekwencja


def alfa_cronbacha(ramka: pd.DataFrame) -> float:
    """Alfa dla kompletnych wierszy; nie zastępuje oceny modelu pomiarowego."""
    x = ramka.dropna().astype(float)
    k = x.shape[1]
    return k / (k - 1) * (1 - x.var(ddof=1).sum() / x.sum(axis=1).var(ddof=1))


alpha = alfa_cronbacha(dane[pozycje_po_kluczu])

print(
    dane[
        [
            "id",
            "sr3",
            "sr3_r",
            "liczba_waznych_pozycji",
            "samoregulacja",
            "frekwencja",
            "blad_frekwencji",
        ]
    ].to_string(index=False)
)
print(f"\nAlfa Cronbacha (wiersze kompletne): {alpha:.3f}")
print("Liczba rekordów wymagających kontroli frekwencji:", int(dane["blad_frekwencji"].sum()))

