from pathlib import Path
import pandas as pd,numpy as np,json,hashlib
R=Path(__file__).resolve().parent
g=pd.read_parquet(R.parent/'fable-verification-2026-09-06/games.parquet')
pop=g[g.valid&~g.free&~g.explicit&g.year.between(2019,2026)&g.reviews.ge(100)&((g.year<2026)|g.month.le(8))].copy()
pop['period']=pd.cut(pop.year,[2018,2022,2025,2026],labels=['2019-22','2023-25','2026JanAug']).astype(str)
pop['review_band']=pd.cut(pop.reviews,[99,499,1999,9999,np.inf],labels=['100-499','500-1999','2000-9999','10000+']).astype(str)
pop['stratum']=pop.period+' / '+pop.review_band
parts=[];strata=[]
for i,(label,d) in enumerate(pop.groupby('stratum',sort=True)):
    x=d.sort_values('appid').sample(n=min(40,len(d)),random_state=76007+i).copy()
    x['sample_order_in_stratum']=np.arange(len(x));x['population_n']=len(d);x['sample_n']=len(x);x['weight']=len(d)/len(x)
    parts.append(x);strata.append(dict(stratum=label,population_n=len(d),sample_n=len(x)))
s=pd.concat(parts).sort_values(['sample_order_in_stratum','stratum']).reset_index(drop=True)
s['sample_order']=np.arange(len(s));s.to_parquet(R/'sample.parquet',index=False);s.drop(columns=['desc']).to_csv(R/'sample.csv',index=False)
pd.DataFrame(strata).to_csv(R/'sampling_strata.csv',index=False)
pop[['appid','period','review_band','stratum']].to_parquet(R/'population_membership.parquet',index=False)
spec={'scope':'Paid non-explicit released games 2019-August2026 with >=100 snapshot filtered reviews','population_n':len(pop),'sample_n':len(s),'selection':'40 games without replacement per release-period x review-count stratum; no language/name/description selection','weight':'population_n/sample_n per stratum','seed_base':76007,'pilot':'first 24 targets, two per stratum','request_cap_total_including_four_probes':1400,'minimum_interval_seconds':2,'retries':0,'bulk_catalog_network_policy_unchanged':True,'primary_question':'Non-English review attention and its relationship to English support; review language is not nationality','english_share_thresholds':[.1,.25,.5],'sources':['../fable-verification-2026-09-06/games.parquet','../2026-09-05/exports/games.parquet'],'snapshot_date':'2026-09-05','sample_sha256':hashlib.sha256((R/'sample.csv').read_bytes()).hexdigest()}
(R/'study_spec.json').write_text(json.dumps(spec,indent=2));print(json.dumps(spec,indent=2))
