From 3539b2f8fb8a8d8cba6b037e62cb9b2636a6c0fa Mon Sep 17 00:00:00 2001 From: Daniel Rojas Date: Tue, 16 Apr 2024 14:51:28 +0200 Subject: [PATCH] Move `parse_number_and_unit()` and `NumberAndUnit` definition to `wv_utils.py` --- src/wireviz/wv_dataclasses.py | 56 +++++++++++++---------------------- src/wireviz/wv_utils.py | 29 ++++++++++++++++++ 2 files changed, 49 insertions(+), 36 deletions(-) diff --git a/src/wireviz/wv_dataclasses.py b/src/wireviz/wv_dataclasses.py index dc79daf..725b9ea 100644 --- a/src/wireviz/wv_dataclasses.py +++ b/src/wireviz/wv_dataclasses.py @@ -20,7 +20,14 @@ from wireviz.wv_colors import ( SingleColor, get_color_by_colorcode_index, ) -from wireviz.wv_utils import aspect_ratio, awg_equiv, mm2_equiv, remove_links +from wireviz.wv_utils import ( + NumberAndUnit, + awg_equiv, + aspect_ratio, + mm2_equiv, + parse_number_and_unit, + remove_links, +) # Each type alias have their legal values described in comments # - validation might be implemented in the future @@ -54,7 +61,6 @@ MetadataKeys = PlainText # Literal['title', 'description', 'notes', ...] Side = Enum("Side", "LEFT RIGHT") ArrowDirection = Enum("ArrowDirection", "NONE BACK FORWARD BOTH") ArrowWeight = Enum("ArrowWeight", "SINGLE DOUBLE") -NumberAndUnit = namedtuple("NumberAndUnit", "number unit") AUTOGENERATED_PREFIX = "AUTOGENERATED_" @@ -196,34 +202,8 @@ class Component: partnos = tuple(partnos) self.partnumbers = PartNumberInfo(*partnos) - self.qty = self.parse_number_and_unit(self.qty, None) - self.amount = self.parse_number_and_unit(self.amount, None) - - def parse_number_and_unit( - self, - inp: Optional[Union[NumberAndUnit, float, int, str]], - default_unit: Optional[str] = None, - ) -> Optional[NumberAndUnit]: - if inp is None: - return None - elif isinstance(inp, NumberAndUnit): - return inp - elif isinstance(inp, float) or isinstance(inp, int): - return NumberAndUnit(float(inp), default_unit) - elif isinstance(inp, str): - if " " in inp: - number, unit = inp.split(" ", 1) - else: - number, unit = inp, default_unit - try: - number = float(number) - except ValueError: - raise Exception( - f"{inp} is not a valid number and unit.\n" - "It must be a number, or a number and unit separated by a space." - ) - else: - return NumberAndUnit(number, unit) + self.qty = parse_number_and_unit(self.qty, None) + self.amount = parse_number_and_unit(self.amount, None) @property def bom_hash(self) -> BomHash: @@ -451,7 +431,9 @@ class Connector(TopLevelGraphicalComponent): raise Exception("Loops must be between exactly two pins!") for pin in loop: if pin not in self.pins: - raise Exception(f'Unknown loop pin "{pin}" for connector "{self.name}"!') + raise Exception( + f'Unknown loop pin "{pin}" for connector "{self.name}"!' + ) # Make sure loop connected pins are not hidden. # side=None, determine side to show loops during rendering self.activate_pin(pin, side=None, is_connection=True) @@ -675,8 +657,8 @@ class Cable(TopLevelGraphicalComponent): # allow gauge, length, and other fields to be lists too (like part numbers), # and assign them the same way to bundles. - self.gauge = self.parse_number_and_unit(self.gauge, "mm2") - self.length = self.parse_number_and_unit(self.length, "m") + self.gauge = parse_number_and_unit(self.gauge, "mm2") + self.length = parse_number_and_unit(self.length, "m") self.amount = self.length # for BOM if self.wirecount: # number of wires explicitly defined @@ -753,9 +735,11 @@ class Cable(TopLevelGraphicalComponent): index=index_offset, id=id, label="Shield", - color=MultiColor(self.shield) - if isinstance(self.shield, str) - else MultiColor(None), + color=( + MultiColor(self.shield) + if isinstance(self.shield, str) + else MultiColor(None) + ), parent=self.designator, ) diff --git a/src/wireviz/wv_utils.py b/src/wireviz/wv_utils.py index 10b5068..31ebd83 100644 --- a/src/wireviz/wv_utils.py +++ b/src/wireviz/wv_utils.py @@ -1,9 +1,12 @@ # -*- coding: utf-8 -*- import re +from collections import namedtuple from pathlib import Path from typing import List, Optional, Union +NumberAndUnit = namedtuple("NumberAndUnit", "number unit") + awg_equiv_table = { "0.09": "28", "0.14": "26", @@ -76,6 +79,32 @@ def get_single_key_and_value(d: dict): return next(iter(d.items())) +def parse_number_and_unit( + inp: Optional[Union[NumberAndUnit, float, int, str]], + default_unit: Optional[str] = None, +) -> Optional[NumberAndUnit]: + if inp is None: + return None + elif isinstance(inp, NumberAndUnit): + return inp + elif isinstance(inp, float) or isinstance(inp, int): + return NumberAndUnit(float(inp), default_unit) + elif isinstance(inp, str): + if " " in inp: + number, unit = inp.split(" ", 1) + else: + number, unit = inp, default_unit + try: + number = float(number) + except ValueError: + raise Exception( + f"{inp} is not a valid number and unit.\n" + "It must be a number, or a number and unit separated by a space." + ) + else: + return NumberAndUnit(number, unit) + + def int2tuple(inp): if isinstance(inp, tuple): output = inp