"""Authored cold-user data-state routing and first-positive-history transition; no real recommendation users."""
import math,json
CATALOG={'K1':{'features':[1.,0.],'popularity':10,'active':True},'K2':{'features':[0.,1.],'popularity':8,'active':True},'K3':{'features':[1.,1.],'popularity':6,'active':False},'K4':{'features':[0.,1.],'popularity':0,'active':True}}
def cosine(a,b):
    na=math.sqrt(sum(v*v for v in a));nb=math.sqrt(sum(v*v for v in b))
    if not na or not nb:raise ValueError('nonzero profile required')
    return sum(x*y for x,y in zip(a,b))/(na*nb)
def recommend(history_state,history,voluntary_preference=None):
    if history_state!='fetched_successfully':return {'mode':'history_unavailable','ranked':[],'personalization_claimed':False}
    if history:
        if any(k not in CATALOG for k in history):return {'mode':'history_source_missing','ranked':[],'personalization_claimed':False}
        profile=[sum(CATALOG[k]['features'][i] for k in history)/len(history) for i in range(2)];mode='from_observed_positive_history'
    elif voluntary_preference is not None:profile=voluntary_preference;mode='from_explicit_voluntary_preference'
    else:profile=None;mode='nonpersonalized_popularity_fallback'
    candidates=[k for k,v in CATALOG.items() if v['active'] and k not in history]
    ranked=[{'item':k,'score':cosine(profile,CATALOG[k]['features']) if profile is not None else CATALOG[k]['popularity']} for k in candidates]
    ranked.sort(key=lambda r:(-r['score'],-CATALOG[r['item']]['popularity'],r['item']))
    return {'mode':mode,'ranked':ranked,'profile':profile,'personalization_claimed':profile is not None,'inactive_K3_filtered':True,'previous_positive_items_excluded':list(history)}
def demo():
    scenarios={
        'genuinely_empty_fetched_history':recommend('fetched_successfully',[]),
        'empty_with_voluntary_preference':recommend('fetched_successfully',[],[0.,1.]),
        'failed_fetch_empty_buffer':recommend('fetch_failed',[]),
        'after_first_authored_like_K2':recommend('fetched_successfully',['K2']),
        'history_id_missing_from_catalog':recommend('fetched_successfully',['K-missing'])}
    assert scenarios['genuinely_empty_fetched_history']['ranked'][0]['item']=='K1'
    assert not scenarios['genuinely_empty_fetched_history']['personalization_claimed']
    assert scenarios['empty_with_voluntary_preference']['ranked'][0]['item']=='K2'
    assert scenarios['failed_fetch_empty_buffer']['ranked']==[]
    assert scenarios['after_first_authored_like_K2']['ranked'][0]['item']=='K4'
    assert not scenarios['history_id_missing_from_catalog']['ranked']
    return {'authored_catalog':CATALOG,'scenarios':scenarios,'actual_transition':'successful empty history -> author adds one positive K2 event -> recompute from history; not a real user event','preference_or_popularity_are_authored_not_inferred_user_traits':True,'missing_data_not_converted_to_empty_history':True,'cold_item_feature_example_already_covered_elsewhere':True,'actual_user_tracking_training_or_recommendation_service_used':False}
if __name__=='__main__':print(json.dumps(demo(),ensure_ascii=False,indent=2))
