patternpythonMinor
Command-line-based capacitance decoding
Viewed 0 times
linebaseddecodingcommandcapacitance
Problem
I am an amateur programmer and have just written a simple Capacitor Identifier mostly to practice. I have not had many people review my coding and thought this would be a good time to start. It is completed and works. Is there a better way I should have went about it? What should I look at in what and how I am writing that might improve my approach?
#!/usr/bin/env python3
import sys
# Get the arguments list
cmdargs = sys.argv
cmdargs = cmdargs[1:]
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%'}
# Get the total number of args passed
total = len(cmdargs)
# Templete String for output
capTemp = '{} = {}'
# output container
result = []
# cycle through passed arguments and decode each capacitor
for arg in cmdargs:
case = len(arg)
if(case == 2):
temp = arg + ' pf, ' + str(float(arg) / 1000000) + 'uf'
result.append(capTemp.format(arg, temp))
elif(case == 3):
cap = int(arg[:2]) * 10**int(arg[2:])
temp = str(cap) + ' pf, ' + str(float(cap) / 1000000) + 'uf'
result.append(capTemp.format(arg, temp))
elif(case == 4):
cap = int(arg[:2]) * 10**int(arg[2:3])
temp = str(cap) + ' pf, ' + str(float(cap) / 1000000) + 'uf, ' + tolerances[arg[3:].upper()] + ' tolerance'
result.append(capTemp.format(arg, temp))
# print the decoded capacitor values
for i in result:
print(i)Solution
Variable usage
Assign
The
The variable name
Decoding technique
It is good practice to separate your calculations from your output routines. Start by defining a function
In Python, it is idiomatic to write
However, there is a lot of redundancy there, and not much insight either. An improvement would be:
You fail to interpret the third digit properly. If the third digit is
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
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
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 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))))Code Snippets
# Skip argv[0], which is the name of this program
cmd_args = sys.argv[1:]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()]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())multiplier = 10 ** (scale if scale <= 5 else scale - 10)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))))Context
StackExchange Code Review Q#66707, answer score: 6
Revisions (0)
No revisions yet.