Package: engfmt
Noteengfmthas been deprecated and replaced byQuantiPhy.A light-weight package used to read and write numbers in engineering format. In
engineering format a number generally includes the units if available and uses
SI scale factors to indicate the magnitude of the number. For example:1ns1.4204GHzA quantity is the pairing of a real number and units, though the units may be
empty. This package is designed to convert quantities between the various ways
in which they are represented.  Those ways are:As a tuple:For example, 1ns would be represented as (1e-9, ‘s’).
Notice that the scale factor is not included in the units. This is always
true.As a string in conventional formats:For example, 1ns would be represented as ‘1e-9 s’ or as ‘0.000000001s’. This
form is often difficult to read for people and soengfmttreats it more as
a format meant for machines rather than people.As a string in engineering format:For example, 1ns would be represented as ‘1ns’.  This form is often
difficult to read for machines and soengfmttreats it more as a human
readable format.TheQuantityclass is provided for converting between these various forms. It
takes one or two arguments. The first is taken to be the value, and the second,
if given, is taken to be the units.  The value may be given as a float or as
a string. The string may be in floating point notation, in scientific notation,
or in engineering format and may include the units. By engineering notation, it
is meant that the number can use the SI scale factors. For example, any of the
following ways can be used to specify 1ns:>>>fromengfmtimportQuantity>>>period=Quantity(1e-9,'s')>>>print(period)1ns>>>period=Quantity('0.000000001 s')>>>print(period)1ns>>>period=Quantity('1e-9s')>>>print(period)1ns>>>period=Quantity('1ns')>>>print(period)1nsIn all cases, the giving the units is optional.From a quantity object, you can generate any representation:>>>h_line=Quantity('1420.405751786 MHz')>>>h_line.to_tuple()(1420405751.786,'Hz')>>>h_line.to_eng()'1.4204GHz'>>>h_line.to_str()'1420.405751786e6Hz'You can also access the value without the units:>>> h_line.to_float()
1420405751.786

>>> h_line.to_unitless_eng()
'1.4204G'

>>> h_line.to_unitless_str()
'1420.405751786e6'Or you can access just the units:>>> h_line.units
'Hz'The output of theto_engandto_unitless_engmethods is always rounded to
the desired precision, which can be specified as an argument.  This differs from
theto_strandto_unitless_strmethods. They attempt to retain the original
format of the number if it is specified as a string. In this way it retains its
original precision. The underlying assumption behind this difference is that
engineering notation is generally used when communicating with people, whereas
floating point notation is used when communicating with machines. People benefit
from having a limited number of digits in the numbers, whereas machines benefit
from have full precision numbers.Quantities As RealsYou can use a quantity in the same way that you can use a real number, meaning
that you can use it in expressions and it will evaluate to its real value:>>> period = Quantity('1us')
>>> print(period)
1us

>>> frequency = 1/period
>>> print(frequency)
1000000.0Notice that when performing arithmetic operations on quantities the units are
completely ignored.Shortcut FunctionsGenerally one uses the shortcut functions to convert numbers to and from
engineering format. All of these functions take the value and units in the same
ways that they are specified to Quantity.  In particular, the value may be
a string or a real number.  If it is a string it may be given in traditional
format or in engineering format, and it may include the units.  For example:>>>fromengfmtimportquant_to_tuple>>>quant_to_tuple('1.4204GHz')(1420400000.0,'Hz')>>>fromengfmtimportquant_to_eng>>>quant_to_eng(1420400000.0,'Hz')'1.4204GHz'>>>fromengfmtimportquant_to_sci>>>quant_to_sci('1.4204GHz',prec=4)'1.4204×10⁰⁹Hz'>>>fromengfmtimportquant_to_str>>>quant_to_str(1420400000.0,'Hz')'1.4204e+09Hz'>>>fromengfmtimportquant_to_float>>>quant_to_float('1.4204GHz')1420400000.0>>>fromengfmtimportquant_to_unitless_str>>>quant_to_unitless_str('1.4204GHz')'1.4204e9'>>>fromengfmtimportquant_to_unitless_eng>>>quant_to_unitless_eng('1.4204e9Hz')'1.4204G'>>>fromengfmtimportquant_strip>>>quant_strip('1.4204GHz')'1.4204G'>>>quant_strip('1.4204e9Hz')'1.4204e9'PreferencesYou can adjust some of the behavior of these functions on a global basis usingset_preferences:>>>fromengfmtimportset_preferences,quant_to_eng,quant_to_sci>>>set_preferences(hprec=2,spacer=' ')>>>quant_to_eng('1.4204GHz')'1.42 GHz'>>>quant_to_eng('1.4204GHz',prec=4)'1.4204 GHz'>>>quant_to_sci('1.4204GHz',prec=4)'1.4204×10⁰⁹ Hz'Specifyinghprec(human precision) to be 4 gives 5 digits of precision (you
get one more digit than the number you specify for precision). Thus, the valid
range forprecis from 0 to around 12 to 14 for double precision numbers.PassingNoneas a value inset_preferencesreturns that preference to its
default value:>>>set_preferences(hprec=None,spacer=None)>>>quant_to_eng('1.4204GHz')'1.4204GHz'The available preferences are:hprec (int):Human precision in digits where 0 corresponds to 1 digit, must
be nonnegative. This precision is used when generating engineering
format.mprec (int):Machine precision in digits where 0 corresponds to 1 digit.
Must be nonnegative. This precision is used when not generating
engineering format.spacer (str):May be ‘’ or ‘ ‘, use the latter if you prefer a space between
the number and the units. Generally using ‘ ‘ makes numbers easier to
read, particularly with complex units, and using ‘’ is easier to parse.unity (str):The output scale factor for unity, generally ‘’ or ‘_’.output (str):Which scale factors to output, generally one would only use familiar scale
factors.ignore_sf (bool):Whether scale factors should be ignored by default.assign_fmt (str):Format string for an assignment. Will be passed through string format
method.  Format string takes three possible arguments named n,
q, and d for the name, value and description.  The default is ‘{n} = {v}’assign_rec (str):Regular expression used to recognize an assignment. Used in
add_to_namespace(). Default recognizes the form:“Temp = 300_K – Temperature”.Quantity ClassThough rarely used directly, the Quantity class forms the foundation of theengfmtpackage. It is more flexible than the shortcut functions:>>>fromengfmtimportQuantity>>>h_line=Quantity('1420.405751786 MHz')>>>str(h_line)'1.4204GHz'>>>float(h_line)1420405751.786>>>h_line.to_tuple()(1420405751.786,'Hz')>>>h_line.to_eng(7)'1.4204058GHz'>>>h_line.to_sci()'1.4204×10⁰⁹Hz'>>>h_line.to_str()'1420.405751786e6Hz'>>>h_line.to_float()1420405751.786>>>h_line.to_unitless_eng(4)'1.4204G'>>>h_line.to_unitless_str()'1420.405751786e6'>>>h_line.strip()'1420.405751786M'>>>h_line.units'Hz'>>>h_line.add_name('Fhy')>>>h_line.name'Fhy'>>>h_line.add_desc('frequency of hydrogen line')>>>h_line.desc'frequency of hydrogen line'>>>h_line.is_infinite()False>>>h_line.is_nan()FalsePhysical ConstantsThe Quantity class also supports a small number of physical constants.Plank’s constant:>>>plank=Quantity('h')>>>print(plank)662.61e-36J-sBoltzmann’s constant:>>>boltz=Quantity('k')>>>print(boltz)13.806e-24J/KElementary charge:>>>q=Quantity('q')>>>print(q)160.22e-21CSpeed of light:>>>c=Quantity('c')>>>print(c)299.79Mm/sZero degrees Celsius in Kelvin:>>>zeroC=Quantity('C0')>>>print(zeroC)273.15Kengfmtuseskrather thanKto represent kilo so that you can distinguish
between kilo and Kelvin.Permittivity of free space:>>>eps0=Quantity('eps0')>>>print(eps0)8.8542pF/mPermeability of free space:>>>mu0=Quantity('mu0')>>>print(mu0)1.2566uH/mCharacteristic impedance of free space:>>>Z0=Quantity('Z0')>>>print(Z0)376.73OhmsYou can add additional constants by adding them to the CONSTANTS dictionary:>>>fromengfmtimportQuantity,CONSTANTS>>>CONSTANTS['h_line']=(1.420405751786e9,'Hz')>>>h_line=Quantity('h_line')>>>print(h_line)1.4204GHzString FormattingQuantities can be passed into the stringformatmethod:>>>print('{}'.format(h_line))1.4204GHzYou can specify the precision as part of the format specification>>>print('{:.6}'.format(h_line))1.420406GHzThe ‘q’ type specifier can be used to explicitly indicate that both the number
and the units are desired:>>>print('{:.6q}'.format(h_line))1.420406GHzAlternately, ‘r’ can be used to indicate just the number is desired:>>>print('{:r}'.format(h_line))1.4204GUse ‘u’ to indicate that only the units are desired:>>>print('{:u}'.format(h_line))HzYou can also use the string and floating point format type specifiers:>>>print('{:f}'.format(h_line))1420405751.786000>>>print('{:e}'.format(h_line))1.420406e+09>>>print('{:g}'.format(h_line))1.42041e+09>>>print('{:s}'.format(h_line))1.4204GHzIt is also possible to add a name and perhaps a description to the quantity, and
access those with special format codes as well:>>>h_line.add_name('Fhy')>>>h_line.add_desc('frequency of hydrogen line')>>>print('{:n}'.format(h_line))Fhy>>>print('{:d}'.format(h_line))frequencyofhydrogenline>>>print('{:Q}'.format(h_line))Fhy=1.4204GHz>>>print('{:R}'.format(h_line))Fhy=1.4204G>>>print('{0:Q} ({0:d})'.format(h_line))Fhy=1.4204GHz(frequencyofhydrogenline)ExceptionsA ValueError is raised if engfmt is passed a string it cannot convert into
a number:>>>try:...value,units=quant_to_tuple('xxx')...exceptValueErroraserr:...print(err)xxx:notavalidnumber.Text ProcessingTwo functions are available for converting quantities embedded within text to
and from engineering notation:>>>fromengfmtimportall_to_eng_fmt,all_from_eng_fmt>>>all_to_eng_fmt('The frequency of the hydrogen line is 1420405751.786Hz.')'The frequency of the hydrogen line is 1.4204GHz.'>>>all_from_eng_fmt('The frequency of the hydrogen line is 1.4204GHz.')'The frequency of the hydrogen line is 1.4204e9Hz.'Add to NamespaceIt is possible to put a collection of quantities in a text string and then use
theadd_to_namespacefunction to parse the quantities and add them to the
Python namespace. For example:>>>fromengfmtimportadd_to_namespace>>>design_parameters='''
...     Fref = 156 MHz  -- Reference frequency
...     Kdet = 88.3 uA  -- Gain of phase detector (Imax)
...     Kvco = 9.07 GHz/V  -- Gain of VCO
... '''>>>add_to_namespace(design_parameters)>>>print(Fref,Kdet,Kvco,sep='\n')156MHz88.3uA9.07GHz/VAny number of quantities may be given, with each quantity given on its own line.
The identifier given to the left ‘=’ is the name of the variable in the local
namespace that is used to hold the quantity. The text after the ‘–’ is used as
a description of the quantity.Scale Factors and UnitsBy default,engfmttreats both the scale factor and the units as being
optional. With the scale factor being optional, the meaning of some
specifications can be ambiguous. For example, ‘1m’ may represent 1 milli or it
may represent 1 meter.  Similarly, ‘1meter’ my represent 1 meter or
1 milli-eter. To allow you to avoid this ambiguity,engfmtaccepts ‘_’ as the
unity scale factor. In this way ‘1_m’ is unambiguously 1 meter. You can instructengfmtto output ‘_’ as the unity scale factor by specifying theunityargument toset_preferences:>>>fromengfmtimportset_preferences,Quantity>>>set_preferences(unity='_')>>>l=Quantity(1,'m')>>>print(l)1_mIf you need to interpret numbers that have units and are known not to have scale
factors, you can specify theignore_sfpreference:>>>set_preferences(ignore_sf=True,unity='')>>>l=Quantity('1000m')>>>l.to_tuple()(1000.0,'m')>>>print(l)1kmInstallationUse ‘pip install engfmt’ to install. Requires Python2.7 or Python3.3 or better.Be aware thatengfmthas been deprecated in favor ofquantiphy.TestingRun ‘py.test’ to run the tests.