Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 88 additions & 0 deletions solutions/python/resistor-color-expert/4/resistor_color_expert.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
"""
Resistor Color Expert.

In this exercise you will need to add tolerance to the mix.
Tolerance is the maximum amount that a value can be above or
below the main value. For example, if the last band is green,
the maximum tolerance will be ±0.5%.
"""

# Mapping of resistor color names to their corresponding digit values.
# pylint: disable=R0801
COLOR_VALUES: dict[str, int] = {
"black": 0,
"brown": 1,
"red": 2,
"orange": 3,
"yellow": 4,
"green": 5,
"blue": 6,
"violet": 7,
"grey": 8,
"white": 9,
}

# Mapping of tolerance band color names to their maximum tolerance suffix.
MAX_TOLERANCE: dict[str, str] = {
"grey": " ±0.05%",
"violet": " ±0.1%",
"blue": " ±0.25%",
"green": " ±0.5%",
"brown": " ±1%",
"red": " ±2%",
"gold": " ±5%",
"silver": " ±10%",
}


def resistor_label(colors: list[str]) -> str:
"""
Return a human-readable resistor label from band colors.

Scales to the largest whole unit (ohms, kiloohms, megaohms, gigaohms)
and appends maximum tolerance if present.

:param colors: Band colors in order. Lengths:
1 (value only);
4 (two digits, multiplier, tolerance);
5 (three digits, multiplier, tolerance).
:type colors: list[str]
:returns: Scaled value with units and optional tolerance (e.g., '4.7 kiloohms ±5%').
:rtype: str
:raises KeyError: If an unknown color is provided.
"""
prefix: str = ""
postfix: str = ""
max_tolerance: str = ""

if len(colors) == 1:
prefix: str = f"{COLOR_VALUES[colors[0]]}"

if len(colors) == 4:
prefix: str = f"{COLOR_VALUES[colors[0]]}{COLOR_VALUES[colors[1]]}"
postfix = f"{'0' * COLOR_VALUES[colors[2]]}"
max_tolerance = MAX_TOLERANCE[colors[3]]

if len(colors) == 5:
prefix = (
f"{COLOR_VALUES[colors[0]]}"
f"{COLOR_VALUES[colors[1]]}"
f"{COLOR_VALUES[colors[2]]}"
)
postfix = f"{'0' * COLOR_VALUES[colors[3]]}"
max_tolerance = MAX_TOLERANCE[colors[4]]

int_val: int = int(prefix + postfix)

# Scale to the largest whole unit
# (ohms, kiloohms, megaohms, gigaohms) for readability
if 1000 <= int_val < 1000000:
return f"{float(int_val / 1000)}".rstrip(".0") + f" kiloohms{max_tolerance}"

if 1000000 <= int_val < 1000000000:
return f"{float(int_val / 1000000)}".rstrip(".0") + f" megaohms{max_tolerance}"

if 1000000000 <= int_val:
return f"{int_val / 1000000000}".rstrip(".0") + f" gigaohms{max_tolerance}"

return f"{int_val} ohms{max_tolerance}"