fulvia/modules/resistor.py

167 lines
3.7 KiB
Python
Executable File

#!/usr/bin/env python3
"""
Resistor color band codes.
"""
import re
import argparse
from module import commands, example
suffix = {"k": 1000, "m": 10000000}
sigfig = {"black": 0,
"brown": 1,
"red": 2,
"orange": 3,
"yellow": 4,
"green": 5,
"blue": 6,
"violet": 7,
"grey": 8,
"white": 9}
sigfig_inverse = {val: key for key, val in sigfig.items()}
multiplier = {"black": 1,
"brown": 10,
"red": 100,
"orange": 1000,
"yellow": 10000,
"green": 100000,
"blue": 1000000,
"violet": 10000000,
"grey": 100000000,
"white": 1000000000,
"gold": 0.1,
"silver": 0.01}
multiplier_inverse = {val: key for key, val in multiplier.items()}
tolerance = {"brown": "±1%",
"red": "±2%",
"green": "±0.5%",
"blue": "±0.25%",
"violet": "±0.1%",
"grey": "±0.05%",
"gold": "±5%",
"silver": "±10%",
"none": "±20%"}
temp_coeff = {"black": "250 ppm",
"brown": "100 ppm",
"red": "50 ppm",
"orange": "15 ppm",
"yellow": "25 ppm",
"blue": "10 ppm",
"violet": "5 ppm"}
@commands("resist")
@example(".resist 10k", "brown black orange gold")
def resist(bot, trigger):
"""
Displays the color band code of a resistor for the given resistance.
"""
if not trigger.group(2):
return bot.msg("Please specify a value")
parser = argparse.ArgumentParser()
parser.add_argument("value", nargs="+")
parser.add_argument("-r", "--reverse", action="store_true")
parser.add_argument("-n", "--num_bands", type=int, choices=[3,4,5,6], default=4)
args = parser.parse_args(trigger.group(2).split())
if args.reverse: # bands-to-value
bot.msg(bands_to_value(" ".join(args.value)))
else: # value-to-band
if len(args.value) > 1:
return bot.msg("Too many values.")
value = args.value[0].lower()
mul = 1
if value[-1] in ["k", "m"]:
mul = suffix[value[-1]]
value = value[:-1]
try:
value = float(value) * mul
except ValueError:
return bot.msg("Invalid input.")
return bot.msg(value_to_band(value, args.num_bands))
def value_to_band(value, num_bands=4):
"""
Converts a given resistance value to a color band code.
"""
if value < 1:
return "Value too small. Maybe this will be fixed in the future."
else:
if num_bands > 4:
value = float(format(value, ".3g"))
else:
value = float(format(value, ".2g"))
value = re.sub("\.0$", "", str(value))
bands = []
mul = ""
if "." in value:
if value[-2] == ".":
mul = 0.1
elif value[-3] == ".":
mul = 0.01
else:
return "Error with sigfigs."
value = value.replace(".", "")
val1 = int(value[0])
val2 = int(value[1])
bands.append(sigfig_inverse[val1])
bands.append(sigfig_inverse[val2])
if num_bands > 4:
value = value.ljust(4,"0")
val3 = int(value[2])
bands.append(sigfig_inverse[val3])
if not mul:
mul = 10**(len(value) - len(value.rstrip("0")))
bands.append(multiplier_inverse[mul])
# TODO: better tolerance
bands.append("gold")
if num_bands == 3:
return " ".join(bands)
# TODO: better temp coeff
if num_bands == 6:
bands.append("red")
return " ".join(bands)
def bands_to_value(bands):
"""
Converts the given color band code into a resistance value.
"""
bands = bands.lower().split()
ret = []
if len(bands) > 4:
value = bands[:3]
bands = bands[3:]
else:
value = bands[:2]
bands = bands[2:]
value = [sigfig[v] for v in value]
prod = ""
for x in value:
prod += str(x)
prod = float(prod) * multiplier[bands[0]]
if len(bands) == 1:
return " ".join([str(prod), tolerance["none"]])
if len(bands) == 2:
return " ".join([str(prod), tolerance[bands[1]]])
if len(bands) == 3:
return " ".join([str(prod), tolerance[bands[1]], temp_coeff[bands[2]]])