from pathlib import Path
import json,csv
p=Path('crime-research')
series={
'murder':[5.7,5.7,5.4,5.0,4.8,4.7,4.8,4.5,4.4,4.9,5.4,5.3,5.0,5.0,6.6,6.5,6.6,6.0,5.1,4.1],
'rape':[29.8,28.6,27.9,27.8,27.7,26.8,26.9,36.5,36.9,38.8,40.6,42.0,44.2,43.7,40.1,43.6,43.1,40.8,39.2,36.1],
'robbery':[150.1,148.5,145.9,133.3,119.1,113.8,112.9,108.9,101.1,101.2,102.7,95.2,83.8,78.4,71.2,56.3,67.2,67.4,61.0,49.4],
'assault':[291.7,287.1,276.9,264.3,253.0,241.3,242.3,229.0,229.3,237.2,248.0,244.0,241.7,241.5,271.3,264.2,272.6,267.4,257.6,238.0],
'burglary':[731.7,724.6,731.9,717.0,699.7,700.0,670.0,608.5,536.3,489.2,467.3,424.9,373.0,331.1,306.0,263.4,272.6,253.2,231.0,193.6],
'larceny':[2203.6,2177.9,2157.1,2054.5,1993.2,1964.4,1947.9,1896.9,1814.6,1760.6,1739.4,1680.0,1585.1,1535.0,1379.3,1276.5,1414.8,1364.4,1274.1,1144.1],
'vehicles':[399.4,364.3,315.2,259.0,238.6,229.7,229.8,221.0,215.0,220.0,236.8,234.6,227.3,216.0,243.8,241.6,284.0,321.9,256.0,197.0]}
rows=[]
for i,y in enumerate(range(2006,2026)):
 r={'year':y,**{k:v[i] for k,v in series.items()}};r['violent']=round(sum(r[k] for k in ['murder','rape','robbery','assault']),1);r['property']=round(sum(r[k] for k in ['burglary','larceny','vehicles']),1);rows.append(r)
# Preserve original displayed values separately; chart gaps exclude non-comparable 2021.
(p/'fbi-rates-transcription.json').write_text(json.dumps(rows,indent=2))
for r in rows:
 if r['year']==2021:
  for k in series:r[k]=None
  r['violent']=r['property']=None
 if r['year']<2013:r['violent']=None
r=rows[-1];r['violent']=327.6;r['property']=1534.8
rows[-2]['violent']=362.9;rows[-2]['property']=1761.1
ncvs=[]
vals=[(2008,25.3,22.21,28.49),(2009,22.3,19.74,24.88),(2010,19.3,16.46,22.11),(2011,22.6,19.86,25.28),(2012,26.1,23.77,28.46),(2013,23.2,20,26.34),(2014,20.1,17.70,22.50),(2015,18.6,16.31,20.85),(2016,19.7,17.8,21.54),(2017,20.6,18.59,22.61),(2018,23.2,20.64,25.75),(2019,21,18.74,23.25),(2020,16.4,14.64,18.15),(2021,16.5,14.86,18.08),(2022,23.5,21.59,25.34),(2023,22.5,20.38,24.69),(2024,23.3,19.8,26.79)]
for y,v,l,h in vals:ncvs.append({'year':y,'rate':v,'low':l,'high':h,'error':[round(v-l,2),round(h-v,2)]})
fbi='https://cde.ucr.cjis.gov/LATEST/resources/reports/UCR_Summary_of_Reported_Crimes_in_the_Nation_2025.pdf'
data={'checked':'2026-09-28','fbiSource':fbi,'annual':rows,'ncvs':ncvs,'national2025':{'population':341784857,'violentCount':1119768,'violentRate':327.6,'propertyCount':5245768,'propertyRate':1534.8,'violentCountChange':-9.3,'violentRateChange':-9.7,'murderCountChange':-18.1,'murderRateChange':-18.5},'latest':[{'name':'Violent crime','prior':299114,'current':283106},{'name':'Murder','prior':4027,'current':3369},{'name':'Rape','prior':25905,'current':24638},{'name':'Robbery','prior':59413,'current':51518},{'name':'Aggravated assault','prior':209769,'current':203581},{'name':'Property crime','prior':1313523,'current':1190352},{'name':'Burglary','prior':162231,'current':138523},{'name':'Larceny / theft','prior':938091,'current':878639},{'name':'Motor vehicle theft','prior':213201,'current':173190}], 'dc':[{'name':'Homicide','prior':107,'current':75},{'name':'Assault with a dangerous weapon','prior':678,'current':954},{'name':'Violent crime total','prior':1906,'current':2082},{'name':'Property crime total','prior':16936,'current':13969}]}
(p/'crime-data.json').write_text(json.dumps(data,indent=2))
with (p/'national-rates.csv').open('w',newline='') as f:
 w=csv.DictWriter(f,fieldnames=list(rows[0]));w.writeheader();w.writerows(rows)
print('Data generated; term homicide changes',[(b,e,round((next(r for r in rows if r['year']==e)['murder']/next(r for r in rows if r['year']==b)['murder']-1)*100,1)) for b,e in [(2008,2012),(2012,2016),(2008,2016),(2016,2020),(2020,2024),(2024,2025)]])
