"""Reproduce KI-indeksen from its published, rounded aggregate time series. No microdata, arbitrary code execution, or bootstrap estimation in this pilot. """ import hashlib import json from pathlib import Path from statistics import mean DATA = Path(__file__).with_name('dashboard.json') DB = json.loads(DATA.read_text()) SHA = hashlib.sha256(DATA.read_bytes()).hexdigest() OPTIONS = {'age': ['all', '21-30', '31-40', '41-50', '51-60'], 'epoch': ['chatgpt', 'claudecode'], 'measure': ['eloundou', 'mouchel'], 'sector': ['private', 'public'], 'adjustment': ['sa', 'raw', 'percap_sa', 'percap']} DEFAULTS = dict(age='all', epoch='claudecode', measure='eloundou', sector='private', adjustment='sa') def analyze(**params): if set(params) - set(OPTIONS): raise ValueError('Ukjente analysevalg.') p = {**DEFAULTS, **params} if any(v not in OPTIONS[k] for k, v in p.items()): raise ValueError('Dette delutvalget er ikke tilgjengelig.') if p['sector'] == 'public' and p['measure'] == 'mouchel': raise ValueError('Mouchel er ikke publisert for offentlig sektor.') prefix = ('public_' if p['sector'] == 'public' else '') + ('mouchel_' if p['measure'] == 'mouchel' else '') pkg = prefix + ('by_exposure' if p['age'] == 'all' else 'age_by_exposure') d = DB['packages'][pkg] s = d['series'][p['adjustment']] ref = '2022-10-01' if p['epoch'] == 'chatgpt' else '2025-01-01' idx = d['dates'].index(ref) if idx < 2: raise ValueError('Referanseperioden mangler.') series, growth, levels = [], [], [] cols = DB['packages']['by_exposure']['value_cols'] for q in cols: v = s['_'][q] if p['age'] == 'all' else s[q][p['age']] if len(v) != len(d['dates']) or any(x is None or x <= 0 for x in v): raise ValueError('Manglende eller ugyldige observasjoner. Beregningen er stoppet.') before, after = mean(v[idx-2:idx+1]), mean(v[-3:]) growth.append(100 * (after / before - 1)) levels.append({'quintile':q, 'before':before, 'after':after}) series.append([None if i < 2 else 100*mean(v[i-2:i+1])/before for i in range(len(v))]) index = 100 * ((1 + growth[4]/100)/(1 + growth[0]/100)-1) ci = None if p['sector'] == 'private' and p['age'] in ['all','21-30'] and p['adjustment'] == 'sa': key = 'headline_uncertainty' + ('_young' if p['age']=='21-30' else '') + ('_claudecode' if p['epoch']=='claudecode' else '') + '_by_measure' ci = DB.get(key, {}).get(p['measure']) return dict(parameters=p, index=index, growth=growth, levels=levels, dates=d['dates'], series=series, baseline=d['dates'][idx-2:idx+1], latest=d['dates'][-3:], published_uncertainty=ci, release=DB['release'], dataset_sha256=SHA, package=pkg, formula='100 × ((Q5_after / Q5_before) / (Q1_after / Q1_before) − 1)', note='Deskriptiv relativ vekst, ikke en identifisert årsakseffekt. Beregnet fra publiserte serier med to desimaler. Eventuelle bootstrap-intervaller er hentet fra utgiver, ikke estimert på nytt.') if __name__ == '__main__': import argparse ap = argparse.ArgumentParser() for k, choices in OPTIONS.items(): ap.add_argument('--'+k, choices=choices, default=DEFAULTS[k]) print(json.dumps(analyze(**vars(ap.parse_args())), ensure_ascii=False, indent=2))