9 categories (length, mass, temp, volume, speed, area, pressure, energy, time), shows both result and conversion factor
# Unit Converter - NumWorks # Created by Alvar Laigna - https://alvarlaigna.com # Arrows:select OK:choose Back:back from kandinsky import fill_rect as F, draw_string as D from ion import keydown as K from time import sleep as Z SW,SH=320,222 BK=(0,)*3;WH=(255,)*3 BL=(50,110,230);TL=(0,190,190) YL=(220,200,60);GN=(60,190,60) DG=(120,)*3 okv=1 if K(4)or K(52) else 0 def okd(): return K(4)or K(52) def okp(): global okv d=okd() if d and not okv: okv=1 return True if not d:okv=0 return False def wup(): while okd():Z(0.02) Z(0.12) def menu(title,items,sub=False): sel=0;n=len(items) while True: F(0,0,SW,SH,BK) D(title,SW//2-len(title)*5,6,TL,BK) F(0,24,SW,2,(40,)*3) for i in range(n): y=34+i*22 if i==sel: F(8,y,SW-16,20,BL) D("> "+items[i],14,y+2,WH,BL) else: D(" "+items[i],14,y+2,DG,BK) if sub:D("Back=return",100,SH-16,(60,)*3,BK) else:D("Back=quit",115,SH-16,(60,)*3,BK) while True: if K(1):sel=(sel-1)%n;Z(0.15);break if K(2):sel=(sel+1)%n;Z(0.15);break if okp():wup();return sel if K(17):return-1 Z(0.04) def inp(prompt): try:return float(input(prompt)) except:return None def show(lines): F(0,0,SW,SH,BK) D("RESULT",130,6,TL,BK) F(0,24,SW,2,(40,)*3) for i,ln in enumerate(lines): c=YL if i==len(lines)-1 else WH D(str(ln),14,34+i*20,c,BK) D("OK=back",130,SH-16,DG,BK) while True: if okp()or K(17):wup();return Z(0.04) # Categories: (name, [(unit_name, factor_to_base)]) # Length base=m LEN=("Length",[ ("mm",0.001),("cm",0.01),("m",1.0), ("km",1000.0),("in",0.0254),("ft",0.3048), ("yd",0.9144),("mi",1609.344)]) # Mass base=kg MAS=("Mass",[ ("mg",0.000001),("g",0.001),("kg",1.0), ("oz",0.028349523125),("lb",0.45359237)]) # Volume base=L VOL=("Volume",[ ("mL",0.001),("L",1.0),("gal(US)",3.785411784), ("fl oz",0.0295735296),("cup",0.2365882368)]) # Speed base=m/s SPD=("Speed",[ ("m/s",1.0),("km/h",0.27777778), ("mph",0.44704),("knots",0.51444444)]) # Area base=m2 ARE=("Area",[ ("mm2",0.000001),("cm2",0.0001),("m2",1.0), ("km2",1000000.0),("in2",0.00064516), ("ft2",0.09290304),("acre",4046.8564224)]) # Pressure base=Pa PRS=("Pressure",[ ("Pa",1.0),("kPa",1000.0),("atm",101325.0), ("bar",100000.0),("psi",6894.757293168), ("mmHg",133.322387415)]) # Energy base=J ENR=("Energy",[ ("J",1.0),("kJ",1000.0),("cal",4.184), ("kcal",4184.0),("Wh",3600.0), ("kWh",3600000.0),("eV",1.602176634e-19)]) # Time base=s TIM=("Time",[ ("s",1.0),("min",60.0),("h",3600.0), ("day",86400.0),("week",604800.0), ("year",31557600.0)]) CATS=[LEN,MAS,VOL,SPD,ARE,PRS,ENR,TIM] TEMP_NAMES=["C","F","K"] def fmt(v): if abs(v)<0.0001 and v!=0: return "%.6e" % v if abs(v)>=1000000: return "%.6e" % v if v==int(v) and abs(v)<1e15: return str(int(v)) s="%.6f" % v s=s.rstrip("0").rstrip(".") return s def to_c(v,u): if u==0:return v if u==1:return (v-32)*5.0/9.0 return v-273.15 def from_c(v,u): if u==0:return v if u==1:return v*9.0/5.0+32 return v+273.15 def conv_temp(fi,ti,val): c=to_c(val,fi) return from_c(c,ti) def do_temp(): while True: fi=menu("Temp: From?",TEMP_NAMES,True) if fi<0:return ti=menu("Temp: To?",TEMP_NAMES,True) if ti<0:continue while True: v=inp("Value in "+TEMP_NAMES[fi]+": ") if v is None:break r=conv_temp(fi,ti,v) r1=conv_temp(fi,ti,1.0) fn=TEMP_NAMES[fi];tn=TEMP_NAMES[ti] lines=[ "Temperature", "", fmt(v)+" "+fn+" = "+fmt(r)+" "+tn, "", "1 "+fn+" = "+fmt(r1)+" "+tn ] show(lines) def do_cat(cat): name,units=cat unames=[u[0] for u in units] while True: fi=menu(name+": From?",unames,True) if fi<0:return ti=menu(name+": To?",unames,True) if ti<0:continue while True: fn=units[fi][0];tn=units[ti][0] v=inp("Value in "+fn+": ") if v is None:break ff=units[fi][1];tf=units[ti][1] r=v*ff/tf r1=ff/tf lines=[ name, "", fmt(v)+" "+fn+" = "+fmt(r)+" "+tn, "", "1 "+fn+" = "+fmt(r1)+" "+tn ] show(lines) def run(): cats=["Length","Mass","Temperature", "Volume","Speed","Area", "Pressure","Energy","Time"] while True: s=menu("Unit Converter",cats) if s<0:return if s==2: do_temp() else: idx=s if s<2 else s-1 do_cat(CATS[idx]) run()