"""Bounded GBP/JPY representation converter, not a payment API or currency catalogue."""
import json,re
from decimal import Decimal,localcontext
SCALES={'GBP':2,'JPY':0}
def minor(text,currency):
 if currency not in SCALES:raise ValueError('unsupported currency contract')
 if len(text)>24:raise ValueError('input too long for this bounded converter')
 if not re.fullmatch(r'-?(?:0|[1-9][0-9]*)(?:\.[0-9]+)?',text):raise ValueError('invalid major-unit spelling')
 scale=SCALES[currency]
 with localcontext() as context:
  context.prec=40
  value=Decimal(text)*(10**scale)
 if value!=value.to_integral_value():raise ValueError('fraction of a minor unit: no rounding policy')
 return {'currency':currency,'unit':'minor','scale':scale,'value':int(value),'source':{'text':text,'unit':'major'}}
rows=[]
for text,c in [('12.50','GBP'),('0','GBP'),('-12.50','GBP'),('500','JPY'),('12.501','GBP'),('1.5','JPY'),('5','ISK')]:
 try:r=minor(text,c)
 except ValueError as e:r={'error':str(e)}
 rows.append({'input':text,'currency':c,'result':r})
assert rows[0]['result']['value']==1250 and rows[2]['result']['value']==-1250 and rows[3]['result']['value']==500
assert all('error' in r['result'] for r in rows[4:])
report={'cases':rows,'ambiguous1250':{'GBP_minor':'GBP12.50','GBP_major':'GBP1250.00'},'scope':'Conversion tests only. Negative conversion does not mean an endpoint accepts a negative charge.'}
if __name__=='__main__':print(json.dumps(report,indent=2))
