o
    9j                     @  sP  U d Z ddlmZ ddlZddlmZ ejd d Zejd d Zd	d
ddg dddddd	ddddg dddddd	ddddg dddddd	ddddg dd d!d"dd	d#dd$dg dd%d"ddd	gZ	d&d' Z
e
 \ZZZh d(ZdCd-d.ZdCd/d0Zi Zd1ed2< eD ]
Zeeee qdDd3d4ZdEdFd7d8ZdGd:d;Z	dHdIdAdBZdS )Ju  Lehrplan: frequenz-getakteter, alters-gestaffelter serbischer Kernwortschatz.

Datensatz + Alters-Bänder stammen aus der Forschungs-Spec `plappi-learning-engine`
(210 Wörter Tier 1–6 + Satz-Bausteine, `curriculum_data.json` / `learning_spec.json`).
Dieses Modul ist rein (keine DB): es liefert die alters-adaptive Fokus-Wort-Auswahl
für die Lern-Engine. „WAS gelehrt wird" — das „WIE" macht die Persona (profile.py).
    )annotationsN   )configbackendzcurriculum_data.jsonzlearning_spec.jsontoddlerg      ?   )greetingnounpronounfunctionnumberuU   Benenn-Spiel, Lieder, Tiergeräusche; ein serbisches Wort pro Turn, stark wiederholt.      F)	nameage_minage_maxmax_tierfocus_typesmethodnew_words_per_sessionreview_words_per_sessionsentence_building	preschool   )
r	   verb	adjectiver
   r   questionr   feelingphraseadverbzHEinfache Fragen, Lieder + kurze Geschichten, 2-4-Wort-Phrasen, implizit.   Tschool
   )r   r	   r   r   r   r   r   uR   Konversation: beschreiben, Mini-Geschichten, eigene Fragen; volle einfache Sätze.   teen   )r   r	   r   r   r   abstractzAThemen vom Kind; erste explizite Grammatik-Muster leicht benannt.      young_adultc   z@Konversationspartner + Tutor: freie Themen, Grammatik on demand.c               
   C  s   g g g } }}zt tjdd}|dg |dg } }W n ty> } ztdt d| dd W Y d }~nd }~ww zt tjddd	g }W n tyY   g }Y nw | ||p_tfS )
Nzutf-8)encodingitemssentence_framesz[curriculum] konnte z nicht laden: T)flush	age_bands)	jsonloads_DATA	read_textget	Exceptionprint_SPEC_FALLBACK_BANDS)r,   framesbandsde r=   6/home/nk/hobo-godmode/plappi-mvp/backend/curriculum.py_load*   s   $r?   >      grün   weißrotblaubuntgelbgraulilarosabraungruenweissorangeschwarzviolettitemdictreturnstrc                 C  s    |  dp|  dpd  S )Nlemmasr )r4   striplower)rO   r=   r=   r>   lemma_of>   s    rX   c                   s^   |  dpd}|dkrdS |dkrdS |  dpd  |dkr-t fdd	tD r-d
S |S )uM   Grobes semantisches Cluster fürs Interleaving (Farben/Tiere/Zahlen trennen).typemiscr   r   derU   r   c                 3  s    | ]}| v V  qd S Nr=   ).0cr[   r=   r>   	<genexpr>J   s    zcluster_of.<locals>.<genexpr>color)r4   rW   any	_COLOR_DE)rO   tr=   r_   r>   
cluster_ofB   s   re   zdict[str, dict]BY_LEMMAc                 C  s2   | pd} t d }t D ]}|dd| kr|}q
|S )u   Bänder sind nach age_min aufsteigend; an einer Grenze (z.B. exakt 3 J.)
    gewinnt das HÖHERE Band (mehr Wörter, Satzbau) — nimm das letzte mit age_min<=age.r   r   r   )	AGE_BANDSr4   )agechosenbr=   r=   r>   age_bandT   s   rk   limit
int | Nonec                 C  s(   | rt d|  nt }ddd |D S )u?   `lemma = glosse [tX]`-Liste für den Transkript-Analyse-Prompt.N
c                 s  s8    | ]}t | d |dd d|d dV  qdS )z = r[   rU   z [ttier]NrX   r4   r]   ir=   r=   r>   r`   b   s   6 z#target_vocab_str.<locals>.<genexpr>)ITEMSjoin)rl   itsr=   r=   r>   target_vocab_str_   s   rw   
list[dict]c                   s(   t  }|dd fddtD S )Nr   r   c                   s4   g | ]}| d dkr| dd pdkr|qS )ro   r   r   r   r   r4   )r]   frh   mtr=   r>   
<listcomp>h   s   4 zframes_for.<locals>.<listcomp>)rk   r4   FRAMES)rh   rj   r=   r{   r>   
frames_fore   s   r   r=   mastery_rows
today_daysintmax_tier_unlockedc              
     s  t  }|dd|rt|t|dg |dd}|dd}dd	 |D fd
dfdd|D }|jfddd |d| }	 fddtD }
|
jdd d g t|}}tj}|
D ]"}t	||kru nt
|}||| d v rqk|| || qkt	||k r|
D ]}t	||kr n
||vr|| qg }|	D ]!}t|d }|r||d |dd|d d|dd q|D ]}||d |ddt|dd q||dd |D |drt dS g dS ) u   Fokus-Set dieser Sitzung: Wiederholungen zuerst (fällig), dann neue Wörter.
    Schließt gemeisterte/zurückgezogene Wörter aus. Tier/Typ/Alter-gegated, Cluster-interleaved.
    r   r   r   r   r#   r   r   c                 S  s   h | ]}|d  qS )rS   r=   r]   mr=   r=   r>   	<setcomp>w       zselect_focus.<locals>.<setcomp>c                   s   |  d}|d ur | S dS )Nnext_due_daysr   ry   )r   ndr   r=   r>   overduez   s   
zselect_focus.<locals>.overduec                   s8   g | ]}| d dv r| ddu s|d  kr|qS )state)	receptive
practising
productiver   Nry   r   r   r=   r>   r}   }   s
    z select_focus.<locals>.<listcomp>c                   s    |  |  ddfS )Nboxr   ry   )r   )r   r=   r>   <lambda>   s    zselect_focus.<locals>.<lambda>)keyNc                   sV   g | ]'}t |vr)|d dkr)r|dv r)n	 |dd p%dkr|qS )ro   r*   rY   Tr   r   r   rq   rr   )rh   ftypesr   trackedr=   r>   r}      s    c                 S  s   |  dd|  ddfS )Nro   	   priorityi  ry   )rs   r=   r=   r>   r      s    rS   rT   r[   rU   reviewr   )rT   r[   rS   kindr   new)rT   r[   rS   r   c                 S  s   g | ]}t |qS r=   )re   rr   r=   r=   r>   r}      r   r   )bandfocusnew_clustersr9   )rk   r4   maxsetsortrt   listr   MIN_GAP_SAME_CLUSTER_NEWlenre   appendrf   rX   r   )rh   r   r   recent_new_clustersr   rj   n_revn_newr   
review_selnew_poolri   usedgaprs   clr   r   itr=   )rh   r   r   r   r   r   r>   select_focusk   s\   



&r   )rO   rP   rQ   rR   )rQ   rP   r\   )rl   rm   rQ   rR   )rQ   rx   )r=   N)r   rx   r   r   r   rm   rQ   rP   )__doc__
__future__r   r0   rU   r   BASE_DIRr2   r7   r8   r?   rt   r~   rg   rc   rX   re   rf   __annotations___it
setdefaultrk   rw   r   r   r=   r=   r=   r>   <module>   sZ    



