From a39eb6d870f97ff422fd625eb792932b6445f1e8 Mon Sep 17 00:00:00 2001 From: Luke Date: Sun, 16 Jul 2023 10:40:15 -0700 Subject: [PATCH] initial commit, draft --- .gitignore | 4 ++ calc_lib.py | 158 +++++++++++++++++++++++++++++++++++++++++++++ design-pycalc.md | 10 +++ lib/reliability.py | 19 ++++++ requirements.txt | 4 ++ 5 files changed, 195 insertions(+) create mode 100755 .gitignore create mode 100755 calc_lib.py create mode 100755 design-pycalc.md create mode 100755 lib/reliability.py create mode 100755 requirements.txt diff --git a/.gitignore b/.gitignore new file mode 100755 index 0000000..6eef204 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.vscode +~$* +venv +__pycache__ \ No newline at end of file diff --git a/calc_lib.py b/calc_lib.py new file mode 100755 index 0000000..f98a530 --- /dev/null +++ b/calc_lib.py @@ -0,0 +1,158 @@ +#!/usr/bin/env python3 + +# requires pyreadline3, numpy, scipy + +import numpy as np +import struct +from numpy import pi, exp +from numpy import cos, sin, tan, sqrt +import os +import sys +from lib import reliability +sys.ps1 = 'CALC > ' +sys.ps2 = '..... ' + +from scipy.special import erf, erfc, erfcinv, erfinv +from scipy import constants as scicon + +if sys.platform == 'win32': + def _calcopen(): + os.system('explorer.exe {}'.format(sys.path[0])) + if False: + def _calcedit(editor): + os.system('explorer.exe .') +else: + def _calcopen(): + os.system('xdg-open .') + if False: + def _calcedit(editor): + os.system('explorer.exe .') + +def iswrsig(gamma): + """Convert reflection coefficent to VSWR""" + return (1+gamma)/(1-gamma) +def iswr(retlos): + """Convert return loss in dB to VSWR""" + if retlos > 0: + retlos = -retlos + print(' assuming {:.2f} dB input.'.format(retlos)) + gamma = idbsig(retlos) + return (1+gamma)/(1-gamma) +def swrsig(vswr): + """Convert VSWR to a reflection coefficent""" + return (vswr-1)/(vswr+1) +def swr(vswr): + """Convert a VSWR to a return loss in dB""" + return 20*np.log10((vswr-1)/(vswr+1)) + +def db(x): + return 10*np.log10(x) +db.doc_str=""" +""" +dB = db +def db20(x): + return 20*np.log10(x) +def idb(x): + return np.power(10,x/10) +def idbsig(x): + return np.power(10,x/20) + +def cosd(x): + return np.cos(x*np.pi/180) +def sind(x): + return np.sin(x*np.pi/180) +def tand(x): + return np.tan(x*np.pi/180) + +def ebno2perr(ebno_db): + """Compute BPSK P(Error) from Eb/N0 in dB""" + print('BPSK from %.1f dB'.format(ebno_db)) + ebno_lin = idb(ebno_db) + return erfc(sqrt(ebno_lin))/2 + +def perr2ebno(perr): + """Compute BPSK Eb/N0 in dB required to hit a specific P(Error).""" + print('BPSK (dB) from %.1e P_err'.format(perr)) + return db(erfcinv(2*perr)**2) + +dBk=db(scicon.Boltzmann) +dbk = dBk + +class rpr: + """Wrappers to convert an aribtrary assigned data value to a formated binary representation""" + __doc_s__=__doc__ + def __init__(self, v): + self.v = v + + @classmethod + def _print(cls, b_list, cbytes=0): + b = iter(b_list) + b_str = '0x' + b_merge = [] + if b.__length_hint__() % 2 != 0: + b_merge.append('{:02x}'.format(b.__next__())) + while b.__length_hint__() > 0: + b_merge.append(''.join([ + '{:02x}'.format(b.__next__()) for _ in range(2) + ])) + return b_str + '_'.join(b_merge) + + def __repr__(self): + return "{}\t\t{}".format(type(self.v), self.v) + + @property + def f64(self): return self._print(struct.pack('!d', self.v)) + @property + def f32(self): return self._print(struct.pack('!f', self.v)) + + @property + def i16(self): return self._print(struct.pack('!h', self.v)) + @property + def u16(self): return self._print(struct.pack('!H', self.v)) + @property + def i32(self): return self._print(struct.pack('!i', self.v)) + @property + def u32(self): return self._print(struct.pack('!I', self.v)) + @property + def i64(self): return self._print(struct.pack('!l', self.v)) + @property + def u64(self): return self._print(struct.pack('!L', self.v)) + + + +if False: + import code + local_part=locals().copy() + rm_locals = [ + 'code', + ] + for key in local_part.keys(): + if key[0] == '_': + rm_locals.append(key) + for key in rm_locals: + del local_part[key] + + print(local_part.keys()) + c=code.InteractiveConsole(locals=local_part) + #c.runsource('locals()') + c.interact() + +def __lpr__fixreadline__(): + import os + import atexit + import readline + + readline_history_file = os.path.join(os.path.expanduser('~'), '.pycalc_history') + readline.read_history_file(readline_history_file) + + atexit.register(readline.write_history_file, readline_history_file) + +if False: + __lpr__fixreadline__() + +__tmp_global_keys__=list(locals().keys()) +for name in __tmp_global_keys__: + handle=locals()[name] + if hasattr(handle, '__doc_s__'): + print("{0:10s} {1:s}".format(handle.__name__, handle.__doc_s__)) +del __tmp_global_keys__ \ No newline at end of file diff --git a/design-pycalc.md b/design-pycalc.md new file mode 100755 index 0000000..c888e7e --- /dev/null +++ b/design-pycalc.md @@ -0,0 +1,10 @@ +# Design Target +## Curses Stack based calculator + +* platform layer event loop +* use ncurses +* React to single keypress events @ a fixed interval. +* operations are based on single letter keys +* Write input to a prompt +* display the stack every cycle +* display shortcuts at the bottom diff --git a/lib/reliability.py b/lib/reliability.py new file mode 100755 index 0000000..c617401 --- /dev/null +++ b/lib/reliability.py @@ -0,0 +1,19 @@ +#!/usr/bin/env python3 +import numpy as _np + +C_YEARS_TO_BLN_HOURS = (365.24 * 24) / 1_000_000_000 + +def to_fits(reliability, time_yrs=5): + time_hrs = time_yrs*C_YEARS_TO_BLN_HOURS + return _np.log(reliability)/-time_hrs + +def to_rel(FITs, time_yrs=5): + time_hrs = time_yrs*C_YEARS_TO_BLN_HOURS + return _np.exp(-time_hrs * FITs) + +def to_urel(FITs, time_yrs=5): + time_hrs = time_yrs*C_YEARS_TO_BLN_HOURS + return 1-_np.exp(-time_hrs * FITs) + +from_fits=to_rel +from_rel=to_fits \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100755 index 0000000..78d5f8d --- /dev/null +++ b/requirements.txt @@ -0,0 +1,4 @@ +numpy>=1.22.3 +pyreadline3>=3.4.1 +scipy>=1.8.0 +sympy>=1.11.1