units.py

Created by laigna

Created on March 14, 2026

4.12 KB

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()

During your visit to our site, NumWorks needs to install "cookies" or use other technologies to collect data about you in order to:

With the exception of Cookies essential to the operation of the site, NumWorks leaves you the choice: you can accept Cookies for audience measurement by clicking on the "Accept and continue" button, or refuse these Cookies by clicking on the "Continue without accepting" button or by continuing your browsing. You can update your choice at any time by clicking on the link "Manage my cookies" at the bottom of the page. For more information, please consult our cookies policy.