Variable usage
Assign cmdargs
once, and get it right the first time. Put a more insightful comment there. Rename it to cmd_args
for readability.
# Skip argv[0], which is the name of this program
cmd_args = sys.argv[1:]
The total
variable is never used.
The variable name case
is not descriptive enough. Naming a variable temp
is almost always a bad idea as well. I suggest names like arg_len
and decoded_value
, respectively.
tolerances
is a constant, and should be named TOLERANCES
by convention. Format it using one entry per line for readability.
Decoding technique
It is good practice to separate your calculations from your output routines. Start by defining a function decode_capacitance(code)
:
def decode_capacitance(code):
'''
Decodes the capacitance as a (value, tolerance) pair.
The value is a float representing the nominal number of picofarads.
The tolerance is a free-form string, and may be None.
'''
code_length = len(code)
if code_length == 2:
return float(code), None
elif code_length == 3:
return float(code[:2]) * 10 ** int(arg[2:]), None
elif code_length == 4:
return float(code[:2]) * 10 ** int(arg[2:3]), TOLERANCES[code[3:].upper()]
In Python, it is idiomatic to write if
conditions without parentheses.
However, there is a lot of redundancy there, and not much insight either. An improvement would be:
def decode_capacitance(code):
'''(Same docstring)'''
base_pF, scale, tol = float(code[0:2]), int(code[2:3] or 0), code[3:4]
multiplier = 10 ** scale
return base_pF * multiplier, TOLERANCES.get(tol.upper())
You fail to interpret the third digit properly. If the third digit is 8
or 9
, it is supposed to be interpreted as a multiplier of 0.01 or 0.1, respectively. To fix that, change the middle line to:
multiplier = 10 ** (scale if scale <= 5 else scale - 10)
As @vnp noted, you have no validation or error handling (and I haven't added any for you).
Formatting technique
Define another function to display the capacitance and tolerance in the desired format.
It would be nice, I think, to automatically select the most natural units.
The standard symbol for the farad is F
— a capital letter.
Putting it all together
With the appropriate functions defined, the main loop is quite simple. Print results as you go; there's no need to store results
.
import sys
TOLERANCES = {
'B': '.10%',
'C': '.25%',
'D': '.5%',
'E': '.5%',
'F': '1%',
'G': '2%',
'H': '3%',
'J': '5%',
'K': '10%',
'M': '20%',
'N': '.05%',
'P': '+100% to 0%',
'Z': '+80% to -20%',
}
def decode_capacitance(code):
'''
Decodes the capacitance as a (value, tolerance) pair.
The value is a float representing the nominal number of picofarads.
The tolerance is a free-form string, and may be None.
'''
base_pF, scale, tol = float(code[0:2]), int(code[2:3] or 0), code[3:4]
multiplier = 10 ** int(scale if scale <= 5 else scale - 10)
return base_pF * multiplier, TOLERANCES.get(tol.upper())
def format_capacitance(pF, tolerance):
if pF > 1000000:
mantissa, unit = pF / 1000000, 'uF'
else:
mantissa, unit = pF, 'pF'
output = '{} {}'.format(mantissa, unit)
if tolerance is not None:
output += ', ' + tolerance + ' tolerance'
return output
# Skip argv[0], which is the name of this program
cmd_args = sys.argv[1:]
# Cycle through passed arguments and decode each capacitor
for arg in cmd_args:
print('{} = {}'.format(arg, format_capacitance(*decode_capacitance(arg))))