zthunder.py

Created by steveg1cmz

Created on March 11, 2024

3.55 KB

Calculates the distance of a thunderstorm. Also measures the time interval. No liability accepted. (More timer interval functions are in ztimer)


"""Z Thunder.
Calculate thunder distance given sound-light interval and temperature (Or interval given distance etc).

The interval time can be entered or measured.

(The temperature is that of the propagating air. Light-time, pressure and frequency ignored).

This module aims to provide practical results -
see speed of sound for more general solutions.
"""

__version__="0.1"

from time import *

zth="Z Thunder "+__version__
crid=zth+"\n© 2024 SteveG1CMZ";

#customise
OK="[OK|EXE]" #platform-specific
#end custom

global thunderspeed_si
thunderspeede= 331.4 #m/s at 0_C (4sf)
toMI=1.60344 #MILES UK
toNM=1.852 #NAUTI

disclaimer="No liability accepted"  
stinterval="Interval_s:"
stmeasure="[0:measure]"
sttemp="Temperature_C:"
stthunder="Thunder:"
p0=OK+"[s]: start"
p1=OK+": stop"
hlpi="Thunder Interval: sound-light"
hlpt="EG TempC 0..20:Ground -57:Aircraft"
  
def about():
  """ Accuracy analysis: not better than:
  distance: 0.1m/s
  speed 0.1 m/s
  temp: 1C?
  time: tbd (likely 1s unless instrumented)
  Overall: no more than 4 sig figs, likely less
  
  The FAA expect a range resolution of 1NM.
  """
  print(disclaimer)
 
def C(temp,units):
  """convert a temp to C
  (unused, available for user)
  """
  if units=="C": return temp
  if units=="F": return (temp-32)*5/9
  if units=="K": return temp-273.15
  return float("NaN") #undefined unit
  
def measure_interval_s(prompt0,prompt1):
  """Measure an interval (s).
  Accessibility: Seconds can be entered.
  """
  x=input(prompt0)
  if x=="":
    t=monotonic()
    x=input(prompt1)
    t=monotonic()-t
    t=round(t,3) #round key io to ms
  else:
    t=eval(x) #numerical expression
  return t
  
def thunderspeed(temp_C):
  """ Calculate thunder speed at C.
  (Typical Earth values, normal range in air)
  """
  global thunderspeed_si
  global thunderspeede
  thunderspeed_si=thunderspeede+0.6*temp_C #m/s
  thunderspeed_si=round(thunderspeed_si,4)
  return round(thunderspeed_si,4) #m/s

def thunder_m(interval_s,temp_C):
  """Calculate thunder distance (m).
  Note: this is the thunder track, 
  not ground distance.
  
  [Other units are derived from this]
  """
  global interval
  interval=interval_s
  if interval_s==None or interval_s<=0:
    interval=measure_interval_s(p0,p1)
  thunderdist_m=interval*thunderspeed(temp_C)
  return round(thunderdist_m)
  
def thunder_km(interval_s,temp_C):
  d=thunder_m(interval_s,temp_C)/1000
  #>1 or >9 (avoid rounding to 0km)
  if d>9: return round(d)
  return round(d,3)

def thunder_mi(interval_s,temp_C):
  mi=thunder_km(interval_s,temp_C)/toMI
  if mi>9: return round(mi)
  return round(mi,3)
  
def thunder_NM(interval_s,temp_C):
  NM= thunder_km(interval_s,temp_C)/toNM
  if NM>9: return round(NM)
  return round(NM,3)
  
#additional (inverse) functions
def thunder_s(distance_m,temp_C):
  return round(distance_m/thunderspeed(temp_C))
def thunderspeed2(interval_s,distance_m):
  if interval_s==0: return 0 #guard
  return round(distance_m/interval_s) #m/s
def temperature_C(speed_si):
  global thunderspeede
  return round((speed_si-thunderspeede)/0.6)
  
def ask_thunderdistance():
  global thunderspeed_si
  print(hlpi)
  interval_s= eval(input(stinterval+ stmeasure))
  print(hlpt)
  temp_C=eval(input(sttemp))
  d=thunder_m(interval_s,temp_C)
  print(interval,"s",temp_C,"C")
  print(stthunder,d,"m","@",thunderspeed_si,"m/s")
  if True: #display more units
    print(thunder_NM(interval,temp_C),"NM", thunder_mi(interval,temp_C),"miles")
    
if __name__=="__main__" or True:
  print(crid)
  #about()
  ask_thunderdistance()
  if False:
    x=measure_interval_s(p0,p1)
    print(x,"s")