From 47fc7fd786ed6c971867bbb7efd4b67bf782d444 Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Mon, 4 Dec 2023 18:53:53 +0100 Subject: [PATCH 01/40] project metadata defined in project.toml --- pyproject.toml | 154 +++++++++++++++++++++++++++++++++++++++++++++++++ setup.cfg | 87 ---------------------------- setup.py | 27 --------- 3 files changed, 154 insertions(+), 114 deletions(-) delete mode 100644 setup.cfg delete mode 100644 setup.py diff --git a/pyproject.toml b/pyproject.toml index 700c95d..5c15b0b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,3 +1,56 @@ +[project] +name = "weldx_widgets" +dynamic = [ # see: https://setuptools.pypa.io/en/latest/userguide/pyproject_config.html#dynamic-metadata + "version", # version gets derived from git by setuptools_scm. +] +authors = [ + {name="Martin K. Scherer", email="martin.scherer@bam.de"}, + {name="Cagtay Fabry", email="cagtay.fabry@bam.de"} +] +description="Python based widgets for the weldx core package" +readme = "README.md" +license = {file = "LICENSE", name="BSD License"} +keywords = [ + "weldx", + "ipywidgets", + "widgets", +] +classifiers = [ + "Development Status :: 3 - Alpha", + "Intended Audience :: Science/Research", + "License :: OSI Approved :: BSD License", + "Operating System :: OS Independent", + "Natural Language :: English", + "Programming Language :: Python", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Topic :: Scientific/Engineering :: Physics", +] + +# Dependencies +requires-python = ">=3.9" +dependencies = [ + "weldx >=0.6", + "ipywidgets", + "k3d >=2.12", + "ipympl", + "bidict", + "ipyfilechooser", + "tqdm", +] +[project.optional-dependencies] +test = [ + "pytest-cov", + "pytest-xdist" +] + +[project.urls] +documentation = "https://weldx.readthedocs.io" +repository = "https://github.com/BAMweldx/weldx-widgets" +bug_tracker = "https://github.com/BAMweldx/weldx-widgets/issues" +changelog = "https://github.com/BAMweldx/weldx-widgets/blob/master/CHANGELOG.md" + [build-system] requires = ["setuptools>=45", "wheel", @@ -5,5 +58,106 @@ requires = ["setuptools>=45", "babel", ] +# Tool configs [tool.setuptools_scm] write_to = "weldx_widgets/_version.py" +write_to_template = '__version__ = "{version}"' + +[tool.setuptools.packages.find] +where = ["."] + +[tool.pytest.ini_options] +addopts = "--tb=short --color=yes -rsw --cov=weldx --cov-report=term-missing:skip-covered --doctest-modules" +testpaths = "weldx_widgets/tests" +norecursedirs = [ + ".ipynb_checkpoints", +] +filterwarnings = [ + "ignore::DeprecationWarning:traittypes.*:", + "ignore:Passing method to :FutureWarning:xarray.*:", + "error::pint.UnitStrippedWarning", +] + +[tool.coverage.run] +source = ["weldx_widgets"] + +[tool.coverage.report] +omit = [ + "weldx_widgets/_version.py", + "weldx_widgets/tests/*", +] +exclude_lines = [ +# Have to re-enable the standard pragma + "pragma: no cover", +] + +[tool.flake8] +# see weldx formatting +ignore = "W503,W504,E203" +max-line-length = 88 +select = "C,E,F,W,B,B950" # black formatting options +exclude = [ + "__init__.py", +] + +[tool.ruff] +target-version = "py38" # designated Python version +exclude = [ + "__init__.py", + "doc/src/conf.py", +] +# TODO: should be the following list, but Ruff does not yet impl all of them. +# W503,W504 +# E203 +# C408 +ignore = [ + "C408", + #"E203", + "E402", + #"W503", + #"W504", + "D203", "D211", "D213" +] +line-length = 88 +select = [ + "B", # flake8-bugbear + "C", # flake8-comprehensions + #"D", # note: all relevant D's will be set by setting pydocstyle.convention=numpy! + "E", # pycodestyles + "F", # pyflakes + "W", # pycodestyle warnings + "UP", # pyupgrade + "T2", # flake8-print + "I001", # isort + "ICN", # import conventions, e.g. import numpy as np + #"B950", # not yet implemented by Ruff. + "RUF100", # ensure 'noqa' declarations are still valid. +] + +# Allow pydocstyle violations in certain areas. +per-file-ignores."**/{tests,tags,asdf,devtools}/**" = ["D"] +per-file-ignores."conftest.py" = ["D"] +per-file-ignores."doc/src/tutorials/*" = ["D"] +per-file-ignores."doc/src/conf.py" = ["E501", # ignore long lines. + "RUF100", # do no check if 'noqa' is needed (circular import workaround) +] +# Allow prints in certain areas. +per-file-ignores."**/{cli,tests,tutorials,devtools}/**/*{.py,ipynb}" = ["T2"] + +external = ["B950"] +pydocstyle = {convention = "numpy"} +pyupgrade = {keep-runtime-typing = true} + +mccabe = {max-complexity = 15} # max branches inside a function. + +[tool.ruff.isort] +known-first-party = ["weldx"] +required-imports = ["from __future__ import annotations"] + +[tool.ruff.flake8-import-conventions] +extend-aliases = {xarray = "xr"} + +[tool.nbqa.addopts] +ruff = [ + "--extend-ignore=B018" +] diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 4a4ac63..0000000 --- a/setup.cfg +++ /dev/null @@ -1,87 +0,0 @@ -[metadata] -name = weldx_widgets -author = "Martin K. Scherer , Cagtay Fabry " -author_email = "martin.scherer@bam.de" -home_page = https://www.bam.de/weldx -description = Python based widgets for the weldx core package -long_description = file: README.md -long_description_content_type = text/markdown -license = BSD License -license_file = LICENSE -platform = any -keywords = - welding - weldx - bam -classifiers = - Development Status :: 3 - Alpha - Intended Audience :: Science/Research - License :: OSI Approved :: BSD License - Operating System :: OS Independent - Natural Language :: English - Programming Language :: Python - Programming Language :: Python :: 3 :: Only - Programming Language :: Python :: 3.9 - Programming Language :: Python :: 3.10 - Programming Language :: Python :: 3.11 - Topic :: Scientific/Engineering :: Physics -project_urls = - Documentation = https://weldx.readthedocs.io - Source Code = https://github.com/BAMweldx/weldx-widgets - Bug Tracker = https://github.com/BAMweldx/weldx-widgets/issues -# Changelog = https://github.com/BAMweldx/weldx/blob/master/CHANGELOG.md - -[options] -packages = find: -python_requires = >=3.9 -setup_requires = - setuptools >=38.3.0 - setuptools_scm -install_requires = - weldx >=0.6 - ipywidgets - k3d >=2.12 - ipympl - bidict - ipyfilechooser - tqdm - #jpy_video @ git+https://github.com/Who8MyLunch/Jupyter_Video_Widget@462f875 - -[compile_catalog] -directory = weldx_widgets/locale -domain = base -use-fuzzy = True -statistics = True - -[extract_messages] -keywords = _ - -[options.extras_require] -test = - pytest - pytest-cov - pytest-xdist - -[flake8] -# see weldx formatting -ignore = W503,W504,E203 -max-line-length = 88 -select = C,E,F,W,B,B950 # black formatting options -exclude = - __init__.py, - -[pydocstyle] -# convention numpy is currently equivalent to ignoring 'D107', 'D203', 'D212', 'D213', 'D402', 'D413' -convention = numpy -match = (?!__)(?!_version)(?!conftest).*\.py -match_dir = [^\.][^\docs].* - -[isort] -profile = black -default_section = THIRDPARTY -known_first_party = weldx,weldx_widgets -sections = FUTURE,STDLIB,THIRDPARTY,FIRSTPARTY,LOCALFOLDER - - -[tool:pytest] -addopts = --tb=short --color=yes -rsw --cov=weldx_widgets --cov-report=term-missing:skip-covered diff --git a/setup.py b/setup.py deleted file mode 100644 index 0f6e146..0000000 --- a/setup.py +++ /dev/null @@ -1,27 +0,0 @@ -"""Setup for weldx-widgets.""" -import setuptools -from setuptools.command.egg_info import egg_info - - -class InstallWithCompile(egg_info): - """Build messages catalog (.mo files) during egg_info.""" - - def run(self): - """Run it.""" - from babel.messages.frontend import compile_catalog - - compiler = compile_catalog(self.distribution) - option_dict = self.distribution.get_option_dict("compile_catalog") - compiler.domain = [option_dict["domain"][1]] - compiler.directory = option_dict["directory"][1] - compiler.use_fuzzy = True # fixme: this should not be mandatory! - compiler.run() - - super().run() - - -if __name__ == "__main__": - setuptools.setup( - cmdclass=dict(egg_info=InstallWithCompile), - package_data={"": ["locale/*/*/*.mo", "locale/*/*/*.po"]}, - ) From da672d5d47f28956e67430f1e12c5537ccc05dd1 Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Mon, 4 Dec 2023 19:10:06 +0100 Subject: [PATCH 02/40] remove i18n base class --- weldx_widgets/generic.py | 27 +++++++++------------- weldx_widgets/widget_base.py | 43 +++++------------------------------- 2 files changed, 17 insertions(+), 53 deletions(-) diff --git a/weldx_widgets/generic.py b/weldx_widgets/generic.py index 3783ce5..b21fc8a 100644 --- a/weldx_widgets/generic.py +++ b/weldx_widgets/generic.py @@ -5,18 +5,15 @@ from functools import partial from typing import Callable, Optional +import weldx from ipyfilechooser import FileChooser from IPython import get_ipython from ipywidgets import HTML, Button, HBox, Label -import weldx -from weldx_widgets.translation_utils import _i18n as _ -from weldx_widgets.widget_base import WeldxImportExport, WidgetMyHBox, WidgetMyVBox -from weldx_widgets.widget_factory import ( - WidgetLabeledTextInput, - copy_layout, - textbox_layout, -) +from weldx_widgets.widget_base import (WeldxImportExport, WidgetMyHBox, + WidgetMyVBox) +from weldx_widgets.widget_factory import (WidgetLabeledTextInput, copy_layout, + textbox_layout) __all__ = [ "WidgetSaveButton", @@ -59,14 +56,12 @@ def __init__( filename=filename, filter_pattern=filter_pattern, select_default=select_default, - select_desc=_("Select"), - change_desc=_("Change"), + select_desc="Select", + change_desc="Change", ) - self.button = Button(description=_(desc), layout=button_layout) + self.button = Button(description=desc, layout=button_layout) - super(WidgetSaveButton, self).__init__( - children=(self.file_chooser, self.button) - ) + super().__init__(children=(self.file_chooser, self.button)) def set_handler(self, handler: Callable): """Set action handler on save button click.""" @@ -121,7 +116,7 @@ def __init__( ] if title: children.insert(0, Label(title)) - super(WidgetTimeSeries, self).__init__(children=children) + super().__init__(children=children) def to_tree(self) -> dict: """Get mapping of input fields.""" @@ -153,7 +148,7 @@ def download_button( button_description: str, html_instance: Optional[HTML] = None, ) -> HTML: - """Load data from buffer into base64 payload embedded into a HTML button. + """Load data from buffer into base64 payload embedded into an HTML button. Parameters ---------- diff --git a/weldx_widgets/widget_base.py b/weldx_widgets/widget_base.py index 8ee3e61..54cd3e0 100644 --- a/weldx_widgets/widget_base.py +++ b/weldx_widgets/widget_base.py @@ -4,41 +4,10 @@ from pathlib import Path from ipywidgets import HBox, Layout, Output, VBox - from weldx.asdf.util import get_schema_path -from weldx_widgets.translation_utils import set_trans_from_env - - -def metaclass_resolver(*classes): - """Merge multiple meta classes.""" - # Does something like this: - # https://coderedirect.com/questions/163000/multiple-inheritance-metaclass-conflict - metaclass = tuple(set(type(cls) for cls in classes)) - - def cls_name(classes): - return "_".join(mcls.__name__ for mcls in classes) - - metaclass = ( - metaclass[0] - if len(metaclass) == 1 - else type(cls_name(metaclass), metaclass, {}) - ) # class M_C - return metaclass(cls_name(classes), classes, {}) # class C - - -class _TranslationUtil: - """Ensures upon instantiation of the class we have the proper translation.""" - - def __new__(cls, *args, **kwargs): - set_trans_from_env() - return super().__new__(cls) - - -class _merged_meta(type(abc.ABC), type(_TranslationUtil)): # avoid metaclass conflict. - pass -class WidgetBase(abc.ABC, _TranslationUtil, metaclass=_merged_meta): +class WidgetBase: """Base class for weldx widgets.""" def copy(self): @@ -71,7 +40,7 @@ def _ipython_display_(self): margin = "" # "10px" -class WidgetMyHBox(metaclass_resolver(HBox, WidgetBase)): +class WidgetMyHBox(HBox, WidgetBase): """Wrap around a HBox sharing a common layout.""" def __init__(self, *args, **kwargs): @@ -83,10 +52,10 @@ def __init__(self, *args, **kwargs): layout.border = border_debug_style layout.margin = margin - super(WidgetMyHBox, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) -class WidgetMyVBox(metaclass_resolver(VBox, WidgetBase)): +class WidgetMyVBox(VBox, WidgetBase): """Wrap around a VBox sharing a common layout.""" def __init__(self, *args, **kwargs): @@ -98,7 +67,7 @@ def __init__(self, *args, **kwargs): layout.border = border_debug_style layout.margin = margin - super(WidgetMyVBox, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) class WidgetSimpleOutput(WidgetMyHBox): @@ -120,7 +89,7 @@ def __init__(self, out=None, height=None, width=None): else: layout = out.layout self.out = out - super(WidgetSimpleOutput, self).__init__(children=[self.out], layout=layout) + super().__init__(children=[self.out], layout=layout) def __enter__(self): """Enter.""" From 9672c0f5e3d80d38210c1d3a9c3ea050ba0634e3 Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Mon, 4 Dec 2023 19:10:22 +0100 Subject: [PATCH 03/40] remove i18n base class --- weldx_widgets/widget_factory.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/weldx_widgets/widget_factory.py b/weldx_widgets/widget_factory.py index 3141e1e..326053f 100644 --- a/weldx_widgets/widget_factory.py +++ b/weldx_widgets/widget_factory.py @@ -137,6 +137,4 @@ def as_time_series(self) -> TimeSeries: def make_title(text, heading_level=3): """Return an HTML formatted heading.""" - from weldx_widgets.translation_utils import _i18n as _ - - return HTML(f"{_(text)}") + return HTML(f"{text}") From 2ab890120a64a0d4bc5d740bbda8aec204e6b3bf Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Mon, 4 Dec 2023 19:10:41 +0100 Subject: [PATCH 04/40] remove i18n base class --- weldx_widgets/widget_gas.py | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/weldx_widgets/widget_gas.py b/weldx_widgets/widget_gas.py index fd354c4..6a61cb7 100644 --- a/weldx_widgets/widget_gas.py +++ b/weldx_widgets/widget_gas.py @@ -6,7 +6,6 @@ from weldx import Q_ from weldx.tags.aws import GasComponent, ShieldingGasForProcedure, ShieldingGasType -from weldx_widgets.translation_utils import _i18n as _ from weldx_widgets.widget_base import WidgetMyVBox from weldx_widgets.widget_factory import ( FloatWithUnit, @@ -38,18 +37,15 @@ def __init__(self, index=0, percentage=100): ) ) - button_add = Button(description=_("Add gas component")) + button_add = Button(description="Add gas component") button_add.on_click(self._add_gas_comp) - super(WidgetSimpleGasSelection, self).__init__(children=[button_add, gas]) + super().__init__(children=[button_add, gas]) def _set_gas_list(self): - self.gas_list = ["Argon", "CO2", "Helium", _("Hydrogen"), _("Oxygen")] + self.gas_list = ["Argon", "CO2", "Helium", "Hydrogen", "Oxygen"] self._mapping = bidict( - { - gui_name: _asdf_name - for gui_name, _asdf_name in zip(self.gas_list, self._asdf_gas_names) - } + dict(zip(self.gas_list, self._asdf_gas_names)) ) def _clear(self): @@ -66,13 +62,13 @@ def _create_gas_dropdown(self, index=0, percentage=100): ) percentage = IntSlider( - start=0, end=100, value=percentage, description=_("percentage") + start=0, end=100, value=percentage, description="percentage" ) percentage.observe(self._check, type="change") self.gas_selection = gas_dropdown - button_del = Button(description=_("delete"), layout=button_layout) + button_del = Button(description="delete", layout=button_layout) box = HBox((gas_dropdown, percentage, button_del)) @@ -109,7 +105,7 @@ def _check(self, value): if not sum(g.gas_percentage for g in gas_components) == 100: with self.out: print( - _("Check percentages, all components should sum up to 100!") + "Check percentages, all components should sum up to 100!" ) # , file=sys.stderr) else: # remove output, if everything is alright. @@ -148,11 +144,11 @@ class WidgetShieldingGas(WidgetMyVBox): # TODO: this could in principle be used multiple times for all positions # e.g. torch, trailing, backing def __init__(self, position="torch"): - self.flowrate = FloatWithUnit(_("Flow rate"), "l/min", value=20) + self.flowrate = FloatWithUnit("Flow rate", "l/min", value=20) self.gas_components = WidgetSimpleGasSelection() children = [self.gas_components, self.flowrate] - super(WidgetShieldingGas, self).__init__(children=children) + super().__init__(children=children) def to_tree(self) -> dict: """Return weldx objects describing the shielding gas.""" From ce1409e89e6e3068dd4f6d08cf78794ebfd4f654 Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Mon, 4 Dec 2023 19:15:20 +0100 Subject: [PATCH 05/40] remove i18n base class --- weldx_widgets/widget_gmaw.py | 67 ++++++++++++++++++------------------ 1 file changed, 33 insertions(+), 34 deletions(-) diff --git a/weldx_widgets/widget_gmaw.py b/weldx_widgets/widget_gmaw.py index 9047552..d250e72 100644 --- a/weldx_widgets/widget_gmaw.py +++ b/weldx_widgets/widget_gmaw.py @@ -9,7 +9,6 @@ from weldx import Q_, GmawProcess, Time, TimeSeries from weldx_widgets import WidgetShieldingGas from weldx_widgets.generic import WidgetTimeSeries -from weldx_widgets.translation_utils import _i18n as _ from weldx_widgets.widget_base import WeldxImportExport, WidgetMyVBox from weldx_widgets.widget_factory import ( FloatWithUnit, @@ -39,7 +38,7 @@ def plot_gmaw(gmaw, t): fig, ax = plt.subplots(nrows=n, sharex="all", figsize=(_DEFAULT_FIGWIDTH, 2 * n)) for i, k in enumerate(pars): parplot(pars[k], t, k, ax[i]) - ax[-1].set_xlabel(_("time") + " / s") + ax[-1].set_xlabel("time") + " / s" ax[0].set_title(title, loc="left") # ipympl_style(fig) @@ -59,17 +58,17 @@ def __init__(self, tag: str, meta=None): self.tag = tag self.meta = meta - self.manufacturer = WidgetLabeledTextInput(_("Manufacturer"), "Fronius") - self.power_source = WidgetLabeledTextInput(_("Power source"), "TPS 500i") + self.manufacturer = WidgetLabeledTextInput("Manufacturer"), "Fronius" + self.power_source = WidgetLabeledTextInput("Power source", "TPS 500i") self.wire_feedrate = FloatWithUnit( - text=_("Wire feed rate"), value=10, min=0, unit="m/min" + text="Wire feed rate", value=10, min=0, unit="m/min" ) children = [ self.manufacturer, self.power_source, self.wire_feedrate, ] - super(BaseProcess, self).__init__(children=children) + super().__init__(children=children) def to_tree(self): """Return base process parameters.""" @@ -99,34 +98,34 @@ class ProcessPulsed(WidgetMyVBox): """Widget for pulsed processes.""" def __init__(self, kind="UI"): - self.pulse_duration = FloatWithUnit(_("Pulse duration"), value=5.0, unit="ms") + self.pulse_duration = FloatWithUnit("Pulse duration", value=5.0, unit="ms") self.pulse_frequency = FloatWithUnit( - _("Pulse frequency"), value=100.0, unit="Hz" + "Pulse frequency", value=100.0, unit="Hz" ) - self.base_current = FloatWithUnit(_("Base current"), value=60.0, unit="A") + self.base_current = FloatWithUnit("Base current", value=60.0, unit="A") if kind == "UI": - self.pulsed_dim = FloatWithUnit(_("Pulse voltage"), "V", 40) + self.pulsed_dim = FloatWithUnit("Pulse voltage", "V", 40) elif kind == "II": - self.pulsed_dim = FloatWithUnit(_("Pulse current"), "A", 300) + self.pulsed_dim = FloatWithUnit("Pulse current", "A", 300) else: raise ValueError(f"unknown kind: {kind}") self.kind = kind self.base_process = BaseProcess("CLOOS/pulse", {"modulation": self.kind}) if self.kind == "UI": - desc = _("voltage/current") + desc = "voltage/current" else: - desc = _("current") + desc = "current" children = [ - make_title(_("Pulsed") + f" {desc} " + _("process parameters")), + make_title(f"Pulsed {desc} process parameters"), self.base_process, self.pulse_duration, self.pulse_frequency, self.base_current, self.pulsed_dim, ] - super(ProcessPulsed, self).__init__(children=children) + super().__init__(children=children) def to_tree(self): """Return pulsed process parameters.""" @@ -182,12 +181,12 @@ def __init__(self): self.voltage = WidgetTimeSeries( base_data="40.0, 20.0", base_unit="V", time_data="0.0, 10.0", time_unit="s" ) - self.impedance = FloatWithUnit(text=_("Impedance"), value=10, unit="percent") - self.characteristic = FloatWithUnit(_("Characteristic"), value=5, unit="V/A") + self.impedance = FloatWithUnit(text="Impedance", value=10, unit="percent") + self.characteristic = FloatWithUnit("Characteristic", value=5, unit="V/A") - super(ProcessSpray, self).__init__( + super().__init__( children=[ - make_title(_("Spray process parameters")), + make_title("Spray process parameters"), self.base_process, self.voltage, self.impedance, @@ -230,18 +229,18 @@ class WidgetWire(WidgetMyVBox): heading_level = 4 def __init__(self): - self.diameter = FloatWithUnit(_("Diameter"), unit="mm", min=0, value=1.2) - self.wire_class = WidgetLabeledTextInput(_("Class"), "G 42 2 C/M G4Si1") + self.diameter = FloatWithUnit("Diameter", unit="mm", min=0, value=1.2) + self.wire_class = WidgetLabeledTextInput("Class", "G 42 2 C/M G4Si1") # TODO: consider a tree like editing widget for metadata. - self.metadata = WidgetLabeledTextInput(_("Metadata"), "") + self.metadata = WidgetLabeledTextInput("Metadata", "") children = [ - make_title(_("Wire parameters"), heading_level=WidgetWire.heading_level), + make_title("Wire parameters", heading_level=WidgetWire.heading_level), self.diameter, self.wire_class, self.metadata, ] - super(WidgetWire, self).__init__(children=children) + super().__init__(children=children) def to_tree(self): """Return welding wire parameters.""" @@ -266,9 +265,9 @@ class WidgetGMAW(WidgetMyVBox, WeldxImportExport): def _set_gui_mapping(self): self.translate = bidict( { - _("Spray"): "spray", - _("Pulsed") + " (UI)": "UI", - _("Pulsed") + " (II)": "II", + ("Spray"): "spray", + ("Pulsed") + " (UI)": "UI", + ("Pulsed") + " (II)": "II", # _("CMT"): NotImplemented, } ) @@ -284,7 +283,7 @@ def __init__(self, process_type="spray"): self.process_type = Dropdown( options=list(self.translate.keys()), index=index, - description=_("Process type"), + description=("Process type"), ) self.process_type.observe(self._create_process_widgets, names="value") self.gas = WidgetShieldingGas() @@ -292,8 +291,8 @@ def __init__(self, process_type="spray"): self.welding_wire = WidgetWire() children = [ - make_title(_("GMAW process parameters")), - make_title(_("Shielding gas"), 4), + make_title(("GMAW process parameters")), + make_title(("Shielding gas"), 4), self.gas, self.welding_wire, # self.weld_speed, # TODO: speed is given by feedrate and groove! @@ -301,7 +300,7 @@ def __init__(self, process_type="spray"): self.process_type, self._welding_process, ] - super(WidgetGMAW, self).__init__(children=children) + super().__init__(children=children) # initially create the selected process type self._create_process_widgets(dict(new=self.process_type.value)) @@ -332,12 +331,12 @@ def from_tree(self, tree: dict): # set the right welding process widget if welding_process.base_process == "pulse": kind = welding_process.meta["modulation"] - process_type = _("Pulsed") + f" ({kind})" + process_type = f"Pulsed ({kind})" elif welding_process.base_process == "spray": - process_type = _("Spray") + process_type = ("Spray") else: raise NotImplementedError( - _("unknown process type") + f"{welding_process.base_process}" + f"unknown process type: {welding_process.base_process}" ) self.process_type.value = process_type From b014b8bc54f00db245db72a72d4976192020b9ad Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Mon, 4 Dec 2023 19:16:14 +0100 Subject: [PATCH 06/40] remove i18n base class --- weldx_widgets/widget_evaluate.py | 39 ++++++++++++++++---------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/weldx_widgets/widget_evaluate.py b/weldx_widgets/widget_evaluate.py index e941d0e..f55256d 100644 --- a/weldx_widgets/widget_evaluate.py +++ b/weldx_widgets/widget_evaluate.py @@ -26,8 +26,7 @@ Trace, WeldxFile, ) -from weldx_widgets.translation_utils import _i18n as _ -from weldx_widgets.widget_base import WidgetBase, WidgetSimpleOutput, metaclass_resolver +from weldx_widgets.widget_base import WidgetBase, WidgetSimpleOutput from weldx_widgets.widget_factory import make_title from weldx_widgets.widget_measurement import WidgetMeasurement, WidgetMeasurementChain @@ -36,9 +35,9 @@ class WidgetProcessInfo(WidgetSimpleOutput): """Plot GMAW process parameter into output widget.""" def __init__(self, gmaw_process: GmawProcess, t, out=None): - super(WidgetProcessInfo, self).__init__(out=out) + super().__init__(out=out) - children = [make_title(_("Process parameters")), self.out] + children = [make_title("Process parameters"), self.out] self.children = children with self: @@ -86,7 +85,7 @@ def dims_as_coords(arr): data.coordinates = filtered -class WidgetEvaluateSinglePassWeld(metaclass_resolver(Tab, WidgetBase)): +class WidgetEvaluateSinglePassWeld(Tab, WidgetBase): """Aggregate info of passed file in several tabs.""" def __init__(self, file: WeldxFile): @@ -98,27 +97,27 @@ def make_output(): tabs = defaultdict(make_output) - with tabs[_("ASDF-header")]: + with tabs["ASDF-header"]: display(file.header(False)) # start and end time of experiment t = (file["TCP"].time[[0, -1]]).as_timedelta() WidgetProcessInfo( - file["process"]["welding_process"], t, out=tabs[_("Process parameters")] + file["process"]["welding_process"], t, out=tabs["Process parameters"] ) groove = file["workpiece"]["geometry"]["groove_shape"] - with tabs[_("Specimen")]: - print("Material") - print(file["workpiece"]["base_metal"]["common_name"]) - print(file["workpiece"]["base_metal"]["standard"]) + with tabs["Specimen"]: + print("Material") # noqa: T201 + print(file["workpiece"]["base_metal"]["common_name"]) # noqa: T201 + print(file["workpiece"]["base_metal"]["standard"]) # noqa: T201 groove.plot() plt.show() seam_length = file["workpiece"]["geometry"]["seam_length"] - print(_("Seam length") + ":", seam_length) + print("Seam length:", seam_length) # noqa: T201 # 3D Geometry geometry = self._create_geometry(groove, seam_length, Q_(10, "mm")) @@ -158,7 +157,7 @@ def make_output(): spatial_data_geo_reduced, "workpiece geometry (reduced)", "workpiece" ) - with tabs[_("CSM-Subsystems")]: + with tabs[("CSM-Subsystems")]: csm.plot_graph() plt.show() self._show_csm_subsystems(csm) @@ -219,7 +218,7 @@ def make_output(): self._compare_design_tcp(csm) plt.show() - super(WidgetEvaluateSinglePassWeld, self).__init__( + super().__init__( children=tuple(tabs.values()) ) for i, key in enumerate(tabs.keys()): @@ -252,18 +251,18 @@ def _compare_design_tcp(csm): # difference in welding speed fig, ax = plt.subplots(1, 2) ax[0].plot(time.m, tcp_diff.data[:, 0]) - ax[0].set_title(_("Difference in welding speed")) - ax[0].set_xlabel(_("time in s")) - ax[0].set_ylabel(_("diff in mm")) + ax[0].set_title(("Difference in welding speed")) + ax[0].set_xlabel(("time in s")) + ax[0].set_ylabel(("diff in mm")) # diffs depend on how well the user frame matches - ax[1].set_title(_("User frame deviation")) + ax[1].set_title(("User frame deviation")) ax[1].plot(time.m, tcp_diff.data[:, 1], label="y") ax[1].plot(time.m, tcp_diff.data[:, 2], label="z") ax[1].legend() - ax[1].set_xlabel(_("time in s")) - ax[1].set_ylabel(_("diff in mm")) + ax[1].set_xlabel(("time in s")) + ax[1].set_ylabel(("diff in mm")) @staticmethod def _welding_wire_geo_data(radius, length, cross_section_resolution=8): From 3cafa8ee50e1a62a08abc99ae0af091eee8c464e Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Mon, 4 Dec 2023 19:19:26 +0100 Subject: [PATCH 07/40] remove i18n base class --- weldx_widgets/widget_groove_sel.py | 47 ++++++++++++++--------------- weldx_widgets/widget_measurement.py | 13 ++++---- 2 files changed, 29 insertions(+), 31 deletions(-) diff --git a/weldx_widgets/widget_groove_sel.py b/weldx_widgets/widget_groove_sel.py index ccb37eb..2d18773 100644 --- a/weldx_widgets/widget_groove_sel.py +++ b/weldx_widgets/widget_groove_sel.py @@ -23,7 +23,6 @@ get_groove, ) from weldx_widgets.generic import download_button -from weldx_widgets.translation_utils import _i18n as _ from weldx_widgets.widget_base import WeldxImportExport, WidgetMyHBox, WidgetMyVBox from weldx_widgets.widget_factory import ( FloatWithUnit, @@ -69,7 +68,7 @@ class WidgetCADExport(WidgetMyVBox): """ def __init__(self): - title = make_title(_("Export geometry to CAD file [optional]"), heading_level=4) + title = make_title(("Export geometry to CAD file [optional]"), heading_level=4) # if the format changes, we have to update the file_pattern mask # of the chooser of the save widget. @@ -77,9 +76,9 @@ def __init__(self): self.format = Dropdown( options=WidgetCADExport.data_formats, index=default_format_index, - description=_("Data format"), + description=("Data format"), ) - self.create_btn = Button(description=_("Create program")) + self.create_btn = Button(description=("Create program")) self.geometry = None # disable button initially, because we first need to have a geometry self.create_btn.disabled = True @@ -90,13 +89,13 @@ def __init__(self): self._html_dl_button = HTML() self.profile_raster_width = FloatWithUnit( - _("Profile raster width"), + ("Profile raster width"), value=2, unit="mm", # tooltip="Target distance between the individual points of a profile", ) self.trace_raster_width = FloatWithUnit( - _("Trace raster width"), + ("Trace raster width"), value=30, unit="mm", # tooltip="Target distance between the individual profiles on the trace", @@ -143,7 +142,7 @@ def _on_export_geometry(self, *args): # read and embed in HTML button. ntf.seek(0) download_button( - button_description=_("Download program"), + button_description=("Download program"), filename=f"specimen{ext}", html_instance=self._html_dl_button, content=ntf.read(), @@ -154,11 +153,11 @@ class WidgetMetal(WidgetMyVBox): """Widget to select metal type and parameters.""" def __init__(self): - self.common_name = WidgetLabeledTextInput(_("Common name"), "S355J2+N") - self.standard = WidgetLabeledTextInput(_("Standard"), "DIN EN 10225-2:2011") - self.thickness = FloatWithUnit(_("Thickness"), value=30, unit="mm") + self.common_name = WidgetLabeledTextInput(("Common name"), "S355J2+N") + self.standard = WidgetLabeledTextInput(("Standard"), "DIN EN 10225-2:2011") + self.thickness = FloatWithUnit(("Thickness"), value=30, unit="mm") children = [ - make_title(_("Base metal"), heading_level=4), + make_title(("Base metal"), heading_level=4), self.common_name, self.standard, self.thickness, @@ -219,7 +218,7 @@ def __init__(self): [ WidgetMyHBox( [ - Label(_("Groove type"), layout=description_layout), + Label(("Groove type"), layout=description_layout), self.groove_type_dropdown, ] ), @@ -232,9 +231,9 @@ def __init__(self): self.output_tabs = Tab() self.output_tabs.layout = Layout(width="70%") self.output_tabs.children = [self.out] - self.output_tabs.set_title(0, "2D " + _("profile")) + self.output_tabs.set_title(0, "2D " + ("profile")) children = [ - make_title(_("ISO 9692-1 Groove selection"), 3), + make_title(("ISO 9692-1 Groove selection"), 3), WidgetMyHBox(children=[self.groove_selection, self.output_tabs]), ] @@ -259,7 +258,7 @@ def groove_obj(self, value: IsoBaseGroove): gui_params = self.groove_params_dropdowns # inhibit notifications during updating the parameters (or we would call the - # _update_plot method for every setting! + # _update_plot method for every setting!) with contextlib.ExitStack() as stack: for k, v in self.groove_obj.parameters().items(): mapped_k = self._groove_obj._mapping[k] @@ -320,18 +319,18 @@ def _create_groove_dropdown(self): layout=description_layout, ) param_widgets[item] = HBox( - [Label(_("Code number"), layout=description_layout), dropdown] + [Label(("Code number"), layout=description_layout), dropdown] ) else: # replace underscores with spaces, first letter uppercase, translate. t = f"{(item[0].upper() + item[1:]).replace('_', ' ')}" matches = re.match("(.*)([0-9]+)", t) if matches: - t = _(matches.group(1)) + t = (matches.group(1)) number = matches.group(2) text = f"{t} {number}" else: - text = _(t) + text = (t) if "angle" in item: param_widgets[item] = FloatWithUnit(text=text, unit="°", value=45) elif "workpiece_thickness" in item: @@ -369,7 +368,7 @@ def _update_plot(self, *args): groove_params = dict(groove_type=groove_type) for child in self.groove_params.children: param_key = child.mapping - if param_key == _("code_number"): + if param_key == ("code_number"): groove_params[param_key] = child.children[1].value else: magnitude = child.children[1].value @@ -412,7 +411,7 @@ def __init__(self): self.last_plot: Optional[CoordinateSystemManagerVisualizerK3D] = None self.groove_sel = WidgetGrooveSelection() - self.seam_length = FloatWithUnit(_("Seam length"), value=300, min=0, unit="mm") + self.seam_length = FloatWithUnit(("Seam length"), value=300, min=0, unit="mm") self.seam_length.observe_float_value(self.create_csm_and_plot) self.seam_length.observe_unit(self.create_csm_and_plot) @@ -420,11 +419,11 @@ def __init__(self): self.tcp_z = FloatWithUnit("TCP-z", unit="mm") # TODO: compute weld speed accordingly to chosen groove area! # TODO: consider setting it read-only?? - self.weld_speed = FloatWithUnit(_("weld speed"), value=6, unit="mm/s") + self.weld_speed = FloatWithUnit(("weld speed"), value=6, unit="mm/s") self.base_metal = WidgetMetal() self.geometry_export = WidgetCADExport() self.additional_params = ( - make_title(_("Welding parameters"), 4), + make_title(("Welding parameters"), 4), self.seam_length, self.weld_speed, self.tcp_y, @@ -437,7 +436,7 @@ def __init__(self): # add 3d plot and CAD export to groove_sel output tab self.out = Output() self.groove_sel.output_tabs.children += (self.out, self.geometry_export) - self.groove_sel.output_tabs.set_title(1, "3D " + _("profile")) + self.groove_sel.output_tabs.set_title(1, "3D " + ("profile")) self.groove_sel.output_tabs.set_title(2, "CAD export") self.groove_sel.output_tabs.observe( @@ -452,7 +451,7 @@ def __init__(self): self.groove_sel, ] - super(WidgetGrooveSelectionTCPMovement, self).__init__( + super().__init__( children=children, layout=Layout(width="100%") ) diff --git a/weldx_widgets/widget_measurement.py b/weldx_widgets/widget_measurement.py index f2d9c1d..d79c80a 100644 --- a/weldx_widgets/widget_measurement.py +++ b/weldx_widgets/widget_measurement.py @@ -5,7 +5,6 @@ import weldx from weldx.constants import WELDX_UNIT_REGISTRY as ureg -from weldx_widgets.translation_utils import _i18n as _ from weldx_widgets.widget_base import WidgetSimpleOutput from weldx_widgets.widget_factory import make_title @@ -34,7 +33,7 @@ def plot_signal(signal: weldx.measurement.Signal, name, limits=None, ax=None): ax.plot(time.m, data.data.m) ax.set_ylabel(f"{name} / {ureg.Unit(signal.units):~}") - ax.set_xlabel(_("time") + " / s") + ax.set_xlabel(("time") + " / s") ax.grid() if limits is not None: @@ -54,8 +53,8 @@ def plot_measurements( plot_signal(last_signal, measurement.name, ax=axes[i], limits=limits) axes[i].set_xlabel(None) - axes[-1].set_xlabel(_("time") + " / s") - axes[0].set_title(_("Measurements")) + axes[-1].set_xlabel(("time") + " / s") + axes[0].set_title(("Measurements")) return axes @@ -63,7 +62,7 @@ class WidgetMeasurement(WidgetSimpleOutput): """Widget to wrap around a measurement.""" def __init__(self, measurements: List["weldx.measurement.Measurement"], out=None): - super(WidgetMeasurement, self).__init__(out=out) + super().__init__(out=out) n = len(measurements) @@ -83,7 +82,7 @@ class WidgetMeasurementChain(WidgetSimpleOutput): """Plot measurement chains into output widget.""" def __init__(self, measurements, out=None): - super(WidgetMeasurementChain, self).__init__(out=out) + super().__init__(out=out) with self: fig, ax = plt.subplots( nrows=len(measurements), figsize=(_DEFAULT_FIGWIDTH, 18) @@ -93,4 +92,4 @@ def __init__(self, measurements, out=None): plt.tight_layout() plt.show() - self.children = [make_title(_("Measurement chain")), self.out] + self.children = [make_title(("Measurement chain")), self.out] From 52cb45482b8d31e61879834224ae42f99b24ebf0 Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Mon, 4 Dec 2023 19:21:03 +0100 Subject: [PATCH 08/40] ruff --- weldx_widgets/generic.py | 12 +++++++----- weldx_widgets/tests/test_save.py | 4 ++-- weldx_widgets/widget_base.py | 1 + weldx_widgets/widget_evaluate.py | 12 ++++++------ weldx_widgets/widget_factory.py | 4 ++-- weldx_widgets/widget_gmaw.py | 2 +- weldx_widgets/widget_measurement.py | 8 ++++---- 7 files changed, 23 insertions(+), 20 deletions(-) diff --git a/weldx_widgets/generic.py b/weldx_widgets/generic.py index b21fc8a..9dc7749 100644 --- a/weldx_widgets/generic.py +++ b/weldx_widgets/generic.py @@ -5,15 +5,17 @@ from functools import partial from typing import Callable, Optional -import weldx from ipyfilechooser import FileChooser from IPython import get_ipython from ipywidgets import HTML, Button, HBox, Label -from weldx_widgets.widget_base import (WeldxImportExport, WidgetMyHBox, - WidgetMyVBox) -from weldx_widgets.widget_factory import (WidgetLabeledTextInput, copy_layout, - textbox_layout) +import weldx +from weldx_widgets.widget_base import WeldxImportExport, WidgetMyHBox, WidgetMyVBox +from weldx_widgets.widget_factory import ( + WidgetLabeledTextInput, + copy_layout, + textbox_layout, +) __all__ = [ "WidgetSaveButton", diff --git a/weldx_widgets/tests/test_save.py b/weldx_widgets/tests/test_save.py index e14d356..35a2285 100644 --- a/weldx_widgets/tests/test_save.py +++ b/weldx_widgets/tests/test_save.py @@ -17,7 +17,7 @@ def to_tree(self): """Get data.""" return {"data": self.data} - def from_tree(self, tree: dict): # noqa + def from_tree(self, tree: dict): """Set data.""" self.data = tree["data"] @@ -40,7 +40,7 @@ def test_on_save_update(tmpdir, change): if change: # fake a change of the initial file choice. new_file = out_file + "_2" shutil.copy(out_file, new_file) - setattr(SaveAndNext, "filename", new_file) + SaveAndNext.filename = new_file w.on_save(None) out_file = new_file else: diff --git a/weldx_widgets/widget_base.py b/weldx_widgets/widget_base.py index 54cd3e0..200968b 100644 --- a/weldx_widgets/widget_base.py +++ b/weldx_widgets/widget_base.py @@ -4,6 +4,7 @@ from pathlib import Path from ipywidgets import HBox, Layout, Output, VBox + from weldx.asdf.util import get_schema_path diff --git a/weldx_widgets/widget_evaluate.py b/weldx_widgets/widget_evaluate.py index f55256d..883429d 100644 --- a/weldx_widgets/widget_evaluate.py +++ b/weldx_widgets/widget_evaluate.py @@ -251,18 +251,18 @@ def _compare_design_tcp(csm): # difference in welding speed fig, ax = plt.subplots(1, 2) ax[0].plot(time.m, tcp_diff.data[:, 0]) - ax[0].set_title(("Difference in welding speed")) - ax[0].set_xlabel(("time in s")) - ax[0].set_ylabel(("diff in mm")) + ax[0].set_title("Difference in welding speed") + ax[0].set_xlabel("time in s") + ax[0].set_ylabel("diff in mm") # diffs depend on how well the user frame matches - ax[1].set_title(("User frame deviation")) + ax[1].set_title("User frame deviation") ax[1].plot(time.m, tcp_diff.data[:, 1], label="y") ax[1].plot(time.m, tcp_diff.data[:, 2], label="z") ax[1].legend() - ax[1].set_xlabel(("time in s")) - ax[1].set_ylabel(("diff in mm")) + ax[1].set_xlabel("time in s") + ax[1].set_ylabel("diff in mm") @staticmethod def _welding_wire_geo_data(radius, length, cross_section_resolution=8): diff --git a/weldx_widgets/widget_factory.py b/weldx_widgets/widget_factory.py index 326053f..65b3bd9 100644 --- a/weldx_widgets/widget_factory.py +++ b/weldx_widgets/widget_factory.py @@ -75,12 +75,12 @@ def __init__(self, text, unit, value: float = 0.0, min=0): children=[self._label, self._float, self._unit], ) - def observe_float_value(self, handler, names=All, type="change"): # noqa + def observe_float_value(self, handler, names=All, type="change"): self._float.observe(handler, names, type) observe_float_value.__doc__ = HasTraits.observe.__doc__ - def observe_unit(self, handler, names=All, type="change"): # noqa + def observe_unit(self, handler, names=All, type="change"): self._unit.observe(handler, names, type) observe_unit.__doc__ = HasTraits.observe.__doc__ diff --git a/weldx_widgets/widget_gmaw.py b/weldx_widgets/widget_gmaw.py index d250e72..b1e0c00 100644 --- a/weldx_widgets/widget_gmaw.py +++ b/weldx_widgets/widget_gmaw.py @@ -291,7 +291,7 @@ def __init__(self, process_type="spray"): self.welding_wire = WidgetWire() children = [ - make_title(("GMAW process parameters")), + make_title("GMAW process parameters"), make_title(("Shielding gas"), 4), self.gas, self.welding_wire, diff --git a/weldx_widgets/widget_measurement.py b/weldx_widgets/widget_measurement.py index d79c80a..68cb1ea 100644 --- a/weldx_widgets/widget_measurement.py +++ b/weldx_widgets/widget_measurement.py @@ -33,7 +33,7 @@ def plot_signal(signal: weldx.measurement.Signal, name, limits=None, ax=None): ax.plot(time.m, data.data.m) ax.set_ylabel(f"{name} / {ureg.Unit(signal.units):~}") - ax.set_xlabel(("time") + " / s") + ax.set_xlabel("time / s") ax.grid() if limits is not None: @@ -53,8 +53,8 @@ def plot_measurements( plot_signal(last_signal, measurement.name, ax=axes[i], limits=limits) axes[i].set_xlabel(None) - axes[-1].set_xlabel(("time") + " / s") - axes[0].set_title(("Measurements")) + axes[-1].set_xlabel("time / s") + axes[0].set_title("Measurements") return axes @@ -92,4 +92,4 @@ def __init__(self, measurements, out=None): plt.tight_layout() plt.show() - self.children = [make_title(("Measurement chain")), self.out] + self.children = [make_title("Measurement chain"), self.out] From 6ac619cbfc95d1bff8d680a3f96b3f54457c4cbe Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Mon, 4 Dec 2023 19:21:53 +0100 Subject: [PATCH 09/40] ruff2 --- weldx_widgets/kisa/save.py | 2 +- weldx_widgets/kisa/widget_robot_program.py | 2 +- weldx_widgets/kisa/widget_scans.py | 2 +- weldx_widgets/tests/conftest.py | 4 ++-- weldx_widgets/tests/test_gas.py | 2 +- weldx_widgets/widget_factory.py | 4 ++-- weldx_widgets/widget_groove_sel.py | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/weldx_widgets/kisa/save.py b/weldx_widgets/kisa/save.py index 818e793..345cfd0 100644 --- a/weldx_widgets/kisa/save.py +++ b/weldx_widgets/kisa/save.py @@ -197,7 +197,7 @@ def __init__( self.save_button, self.out, ] - super(SaveAndNext, self).__init__(children=children) + super().__init__(children=children) @property def filename(self): diff --git a/weldx_widgets/kisa/widget_robot_program.py b/weldx_widgets/kisa/widget_robot_program.py index e5188f0..a7ea574 100644 --- a/weldx_widgets/kisa/widget_robot_program.py +++ b/weldx_widgets/kisa/widget_robot_program.py @@ -77,7 +77,7 @@ def __init__( w.observe(self._invalidate_dl_button) self.jobname.observe(self._invalidate_dl_button) - super(WidgetLinearWeldYaskawa, self).__init__( + super().__init__( children=[ make_title(_("Create Yaskawa program (linear seam)")), self.uf_to_workpiece, diff --git a/weldx_widgets/kisa/widget_scans.py b/weldx_widgets/kisa/widget_scans.py index face352..283158e 100644 --- a/weldx_widgets/kisa/widget_scans.py +++ b/weldx_widgets/kisa/widget_scans.py @@ -35,7 +35,7 @@ class WidgetScans(WidgetSimpleOutput): def __init__( self, mh24_file, tool_file, scans_dir, single_weld=False, max_scans=None ): - super(WidgetScans, self).__init__(width="100%", height="800 px") + super().__init__(width="100%", height="800 px") self.mh24_file = Path(mh24_file) self.tool_file = Path(tool_file) diff --git a/weldx_widgets/tests/conftest.py b/weldx_widgets/tests/conftest.py index 227b32c..0529201 100644 --- a/weldx_widgets/tests/conftest.py +++ b/weldx_widgets/tests/conftest.py @@ -5,8 +5,8 @@ @pytest.fixture(scope="session", autouse=True) def setup_and_teardown_package(): """Set up testing package.""" - import matplotlib + import matplotlib as mpl """Set Agg matplotlib backend for this module.""" - matplotlib.use("Agg", force=True) + mpl.use("Agg", force=True) yield diff --git a/weldx_widgets/tests/test_gas.py b/weldx_widgets/tests/test_gas.py index b7df33f..fb220f1 100644 --- a/weldx_widgets/tests/test_gas.py +++ b/weldx_widgets/tests/test_gas.py @@ -15,7 +15,7 @@ def test_import_export(write_file): w.gas_components.gas_selection.index = 3 w.gas_components._add_gas_comp(None) percentages = (80, 20) - for i, (name, box) in enumerate(w.gas_components.components.items()): + for i, (_name, box) in enumerate(w.gas_components.components.items()): box.children[1].value = percentages[i] tree = w.to_tree() if write_file: diff --git a/weldx_widgets/widget_factory.py b/weldx_widgets/widget_factory.py index 65b3bd9..88718e4 100644 --- a/weldx_widgets/widget_factory.py +++ b/weldx_widgets/widget_factory.py @@ -49,7 +49,7 @@ def __init__(self, label_text, prefilled_text=None): self.label = Label(label_text, layout=description_layout) self.text = Text(value=prefilled_text, layout=textbox_layout) children = [self.label, self.text] - super(WidgetLabeledTextInput, self).__init__(children=children) + super().__init__(children=children) @property def text_value(self) -> str: @@ -71,7 +71,7 @@ def __init__(self, text, unit, value: float = 0.0, min=0): ) self._unit = Text(value=unit, placeholder="unit", layout=textbox_layout) - super(FloatWithUnit, self).__init__( + super().__init__( children=[self._label, self._float, self._unit], ) diff --git a/weldx_widgets/widget_groove_sel.py b/weldx_widgets/widget_groove_sel.py index 2d18773..af0e7a0 100644 --- a/weldx_widgets/widget_groove_sel.py +++ b/weldx_widgets/widget_groove_sel.py @@ -356,7 +356,7 @@ def _create_groove_dropdown(self): def add_parameter_observer(self, observer: Callable): """Add observers to groove parameters.""" - for key, box in self.groove_params_dropdowns.items(): + for _key, box in self.groove_params_dropdowns.items(): box.children[1].observe(observer, "value") # if key != "code_number": # box.children[2].observe(observer, "value") From e0b7a85567ec3442a007869690f31acfc3fdae57 Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Mon, 4 Dec 2023 19:25:11 +0100 Subject: [PATCH 10/40] removed i18n --- weldx_widgets/kisa/save.py | 11 +- weldx_widgets/kisa/widget_robot_program.py | 9 +- weldx_widgets/locale/de/LC_MESSAGES/base.po | 320 -------------------- weldx_widgets/locale/en/LC_MESSAGES/base.po | 18 -- weldx_widgets/translation_utils.py | 56 ---- 5 files changed, 9 insertions(+), 405 deletions(-) delete mode 100644 weldx_widgets/locale/de/LC_MESSAGES/base.po delete mode 100644 weldx_widgets/locale/en/LC_MESSAGES/base.po delete mode 100644 weldx_widgets/translation_utils.py diff --git a/weldx_widgets/kisa/save.py b/weldx_widgets/kisa/save.py index 345cfd0..ea09681 100644 --- a/weldx_widgets/kisa/save.py +++ b/weldx_widgets/kisa/save.py @@ -11,7 +11,6 @@ import weldx_widgets import weldx_widgets.widget_base import weldx_widgets.widget_factory -from weldx_widgets.translation_utils import _i18n as _ from weldx_widgets.widget_factory import button_layout __all__ = [ @@ -50,7 +49,7 @@ def get_param_from_env(name, default=None) -> str: raise RuntimeError( f"parameter '{name}' unset and no default provided." f" Given parameters: {parameters}" - ) + ) from None return value @@ -170,7 +169,7 @@ def __init__( if not disable_next_button: self.btn_next = w.Button( - description=_(next_notebook_desc), layout=button_layout + description=next_notebook_desc, layout=button_layout ) if next_notebook_params is None: next_notebook_params = dict() @@ -183,7 +182,7 @@ def __init__( path = str(fn_path.parent) fn = str(fn_path.name) self.save_button = weldx_widgets.WidgetSaveButton( - desc="1." + _("Save") if not disable_next_button else _("Save"), + desc="1. Save" if not disable_next_button else "Save", filename=fn, path=path, select_default=True, @@ -225,8 +224,8 @@ def show_header(handle): # open (existing) file and update it. if pathlib.Path(self.filename).stem.endswith("_r"): with self.out: - print("Refusing to save a read-only (template) file!") - print("Please choose another name with the '_r' suffix.") + print("Refusing to save a read-only (template) file!") # noqa: T201 + print("Please choose another name with the '_r' suffix.") # noqa: T201 return if self.filename != self._initial_file: # we want to save the previous file under a different name, so load contents diff --git a/weldx_widgets/kisa/widget_robot_program.py b/weldx_widgets/kisa/widget_robot_program.py index a7ea574..65b493e 100644 --- a/weldx_widgets/kisa/widget_robot_program.py +++ b/weldx_widgets/kisa/widget_robot_program.py @@ -12,7 +12,6 @@ from weldx import Q_, WeldxFile from weldx.tags.core.file import ExternalFile from weldx_widgets.generic import download_button -from weldx_widgets.translation_utils import _i18n as _ from weldx_widgets.widget_base import WidgetMyVBox from weldx_widgets.widget_factory import FloatWithUnit, make_title @@ -64,10 +63,10 @@ def __init__( *xyz, ] ) - self.jobname = widgets.Text(description=_("Jobname"), value="MAIN_LINEAR_NEW") + self.jobname = widgets.Text(description="Jobname", value="MAIN_LINEAR_NEW") self.button_create = Button( - description=_("Create program"), + description="Create program", ) self.button_create.on_click(self.create_linear_program) @@ -79,7 +78,7 @@ def __init__( super().__init__( children=[ - make_title(_("Create Yaskawa program (linear seam)")), + make_title("Create Yaskawa program (linear seam)"), self.uf_to_workpiece, self.jobname, self.button_create, @@ -110,7 +109,7 @@ def create_linear_program(self, button): download_button( output, filename=f"{self.jobname.value}.JBI", - button_description=_("Download program"), + button_description="Download program", html_instance=dl_button, ) diff --git a/weldx_widgets/locale/de/LC_MESSAGES/base.po b/weldx_widgets/locale/de/LC_MESSAGES/base.po deleted file mode 100644 index def95ca..0000000 --- a/weldx_widgets/locale/de/LC_MESSAGES/base.po +++ /dev/null @@ -1,320 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-12-21 10:30+0100\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"Language: de\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: UTF-8\n" -"charset=utf8" - -#: widget_gas.py:47 -msgid "Hydrogen" -msgstr "Wasserstoff" - -#: widget_gas.py:47 -msgid "Oxygen" -msgstr "Sauerstoff" - -#: widget_gas.py:41 -msgid "Add gas component" -msgstr "Gas hinzufügen" - -#: widget_gas.py:69 -msgid "percentage" -msgstr "Prozent" - -#: widget_gas.py:75 -msgid "delete" -msgstr "löschen" - -#: widget_gas.py:151 -msgid "Flow rate" -msgstr "Flußrate" - -#: widget_gas.py:112 -msgid "Check percentages, all components should sum up to 100!" -msgstr "" - -#: widget_measurement.py:57 widget_gmaw.py:42 -msgid "time" -msgstr "Zeit" - -#: widget_gmaw.py:62 -msgid "Manufacturer" -msgstr "Hersteller" - -#: widget_gmaw.py:63 -msgid "Power source" -msgstr "Stromquelle" - -#: widget_gmaw.py:65 -msgid "Wire feed rate" -msgstr "Drahtvorschubrate" - -#: widget_gmaw.py:102 -msgid "Pulse duration" -msgstr "Pulsdauer" - -#: widget_gmaw.py:104 -msgid "Pulse frequency" -msgstr "Pulsfrequenz" - -#: widget_gmaw.py:106 -msgid "Base current" -msgstr "Grundstromstärke" - -#: widget_gmaw.py:109 -msgid "Pulse voltage" -msgstr "Pulsspannung" - -#: widget_gmaw.py:111 -msgid "Pulse current" -msgstr "Pulsstromstärke" - -#: widget_gmaw.py:122 widget_gmaw.py:270 widget_gmaw.py:271 widget_gmaw.py:335 -msgid "Pulsed" -msgstr "Gepulst" - -#: widget_gmaw.py:122 -msgid "process parameters" -msgstr "Prozessparameter" - -#: widget_gmaw.py:185 -msgid "Impedance" -msgstr "Impedanz" - -#: widget_gmaw.py:186 -msgid "Characteristic" -msgstr "Charakteristisch" - -#: widget_gmaw.py:190 -msgid "Spray process parameters" -msgstr "Sprühlichtbogen Parameter" - -#: widget_gmaw.py:233 -msgid "Diameter" -msgstr "Durchmesser" - -#: widget_gmaw.py:234 -msgid "Class" -msgstr "Klasse" - -#: widget_gmaw.py:237 -msgid "Metadata" -msgstr "Metadaten" - -#: widget_gmaw.py:239 -msgid "Wire parameters" -msgstr "Drahtparameter" - -#: widget_gmaw.py:269 widget_gmaw.py:337 -msgid "Spray" -msgstr "Sprüh" - -msgid "CMT" -msgstr "" - -#: widget_gmaw.py:287 -msgid "Process type" -msgstr "Prozesstyp" - -#: widget_gmaw.py:295 -msgid "GMAW process parameters" -msgstr "GMAW Prozessparameter" - -#: widget_gmaw.py:296 -msgid "Shielding gas" -msgstr "Schutzgas" - -#: widget_gmaw.py:340 -msgid "unknown process type" -msgstr "Unbekannter Prozesstyp" - -#: widget_gmaw.py:118 -msgid "voltage/current" -msgstr "Spannung/Stromstärke" - -#: widget_gmaw.py:120 -msgid "current" -msgstr "Stromstärke" - -msgid "invoke next step" -msgstr "Nächster Schritt" - -msgid "Save results" -msgstr "Speichern" - -#: kisa/save.py:169 -msgid "Save" -msgstr "Speichern" - -#: generic.py:62 -msgid "Select" -msgstr "Auswählen" - -#: generic.py:63 -msgid "Change" -msgstr "Ändern" - -#: widget_groove_sel.py:67 -msgid "Export geometry to CAD file [optional]" -msgstr "CAD-Export [optional]" - -#: widget_groove_sel.py:75 -msgid "Data format" -msgstr "Datenformat" - -#: widget_groove_sel.py:77 -msgid "Create program" -msgstr "Programm erstellen" - -#: widget_groove_sel.py:88 -msgid "Profile raster width" -msgstr "Breite Profilraster" - -#: widget_groove_sel.py:94 -msgid "Trace raster width" -msgstr "Breite Spurraster" - -#: widget_groove_sel.py:141 -msgid "Download program" -msgstr "Lade Program" - -#: widget_groove_sel.py:152 -msgid "Common name" -msgstr "Allgemeiner Name" - -#: widget_groove_sel.py:153 -msgid "Standard" -msgstr "Standard" - -#: widget_groove_sel.py:154 -msgid "Thickness" -msgstr "Dicke" - -#: widget_groove_sel.py:156 -msgid "Base metal" -msgstr "Grundmetal" - -#: widget_groove_sel.py:217 -msgid "Groove type" -msgstr "Fugentyp" - -#: widget_groove_sel.py:230 widget_groove_sel.py:422 -msgid "profile" -msgstr "Profil" - -#: widget_groove_sel.py:232 -msgid "ISO 9692-1 Groove selection" -msgstr "ISO 9692-1 Fugenauswahl" - -#: widget_groove_sel.py:320 -msgid "Code number" -msgstr "Kodenummer" - -#: widget_groove_sel.py:324 -msgid "angle" -msgstr "Winkel" - -#: widget_groove_sel.py:326 -msgid "workpiece_thickness" -msgstr "Werkstückdicke" - -#: widget_groove_sel.py:314 widget_groove_sel.py:347 widget_groove_sel.py:359 -msgid "code_number" -msgstr "Kodenummer" - -#: widget_groove_sel.py:400 widget_evaluate.py:121 -msgid "Seam length" -msgstr "Nahtlänge" - -#: widget_groove_sel.py:405 -msgid "weld speed" -msgstr "Schweißgeschwindigkeit" - -#: widget_groove_sel.py:409 -msgid "Welding parameters" -msgstr "Schweißparameter" - -#: widget_measurement.py:58 -msgid "Measurements" -msgstr "Messungen" - -#: widget_measurement.py:96 -msgid "Measurement chain" -msgstr "Messkette" - -#: widget_evaluate.py:41 widget_evaluate.py:108 -msgid "Process parameters" -msgstr "Prozessparameter" - -#: widget_evaluate.py:101 -msgid "ASDF-header" -msgstr "ASDF-Dateikopf" - -#: widget_evaluate.py:112 -msgid "Specimen" -msgstr "Werkstück" - -#: widget_evaluate.py:161 -msgid "CSM-Subsystems" -msgstr "" - -#: widget_evaluate.py:271 -msgid "Difference in welding speed" -msgstr "Unterschied Schweißgeschwindigkeit" - -#: widget_evaluate.py:272 widget_evaluate.py:281 -msgid "time in s" -msgstr "Zeit in s" - -#: widget_evaluate.py:273 widget_evaluate.py:282 -msgid "diff in mm" -msgstr "Unterschied in mm" - -#: widget_evaluate.py:276 -msgid "User frame deviation" -msgstr "Abweichung Nutzerrahmen" - -# groove types -msgid "Groove angle" -msgstr "Fugenwinkel" - -msgid "Workpiece thickness" -msgstr "Dicke Werkstück" - -msgid "Root face" -msgstr "Wurzelzone" - -msgid "Root gap" -msgstr "Wurzellücke" - -msgid "Bevel angle" -msgstr "Keilwinkel" - -msgid "Bevel radius" -msgstr "Keilradius" - -msgid "Special depth" -msgstr "Spezialtiefe" - -# workpiece.ipynb heading -msgid "Choose a groove and your linear weld seam parameters." -msgstr "Wähle Fugen- und lineare Schweißbewegungsparameter." - -msgid "Here you can choose from various shielding gases and spray and pulsed MIG processes and its parameters." -msgstr "Hier können Sie verschiedene Prozessparameter, wie Schutzgase und Sprüh/Pulslichtbogenparameter einstellen." - -msgid "Welding process type and parameters" -msgstr "Schweißprozessparameter" diff --git a/weldx_widgets/locale/en/LC_MESSAGES/base.po b/weldx_widgets/locale/en/LC_MESSAGES/base.po deleted file mode 100644 index 864452e..0000000 --- a/weldx_widgets/locale/en/LC_MESSAGES/base.po +++ /dev/null @@ -1,18 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-12-16 16:02+0100\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"Language: en\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" -"Content-Transfer-Encoding: utf-8\n" diff --git a/weldx_widgets/translation_utils.py b/weldx_widgets/translation_utils.py deleted file mode 100644 index 99749fe..0000000 --- a/weldx_widgets/translation_utils.py +++ /dev/null @@ -1,56 +0,0 @@ -"""Translation related utilities.""" -import gettext -import os -from pathlib import Path - -__all__ = [ - "gettext", - "set_trans_from_env", - "_i18n", - "_", -] - -_translations = dict() - - -def set_trans_from_env(): - """Set locale from env.QUERY_STRING (if available, defaults to english).""" - from weldx_widgets.kisa.save import get_param_from_env - - lang = get_param_from_env("LANG", default="en") - os.environ["LANG"] = lang - get_trans(lang) - - -def get_trans(lang_="en") -> gettext.GNUTranslations: - """Get translation object for given lang string.""" - trans = _translations.get(lang_) - if not trans: - # Set up message catalog access - if lang_ not in ("en", "de"): - raise ValueError(f"Unsupported language: {lang_}") - - base_dir = Path(__file__).parent / "locale" - if not base_dir.exists() and base_dir.is_dir(): - raise RuntimeError("could not set locale dir (non-existent or not a dir).") - - trans = gettext.translation("base", localedir=str(base_dir), languages=[lang_]) - _translations[lang_] = trans - - assert trans - return trans - - -def _i18n(message: str) -> str: - """Translate given message. Uses os.environ['LANG'] as target language.""" - lang = os.environ.get("LANG", "en")[:2] - if lang.startswith("C"): - lang = "en" - trans_ = get_trans(lang) - if not trans_: - return message - - return trans_.gettext(message) - - -_ = _i18n # alias From e70ef7c4aa6794e8f2953083e9e5feaecc2720e0 Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Mon, 4 Dec 2023 19:29:22 +0100 Subject: [PATCH 11/40] do not run cov per default with pytest --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 5c15b0b..47b8018 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -67,7 +67,7 @@ write_to_template = '__version__ = "{version}"' where = ["."] [tool.pytest.ini_options] -addopts = "--tb=short --color=yes -rsw --cov=weldx --cov-report=term-missing:skip-covered --doctest-modules" +addopts = "--tb=short --color=yes -rsw --doctest-modules" testpaths = "weldx_widgets/tests" norecursedirs = [ ".ipynb_checkpoints", From 38be7a4fb98923282eb35bb2431ea3f0b431482f Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Mon, 4 Dec 2023 19:43:39 +0100 Subject: [PATCH 12/40] wip --- weldx_widgets/tests/test_gas.py | 9 --------- weldx_widgets/widget_base.py | 25 ++++++++++++++++++++++--- weldx_widgets/widget_evaluate.py | 4 ++-- weldx_widgets/widget_gmaw.py | 2 +- 4 files changed, 25 insertions(+), 15 deletions(-) diff --git a/weldx_widgets/tests/test_gas.py b/weldx_widgets/tests/test_gas.py index fb220f1..e241a58 100644 --- a/weldx_widgets/tests/test_gas.py +++ b/weldx_widgets/tests/test_gas.py @@ -3,8 +3,6 @@ from weldx import WeldxFile from weldx_widgets import WidgetShieldingGas -from weldx_widgets.tests.util import voila_language -from weldx_widgets.widget_gas import WidgetSimpleGasSelection @pytest.mark.parametrize("write_file", (True, False)) @@ -28,10 +26,3 @@ def test_import_export(write_file): w2 = WidgetShieldingGas() w2.from_tree(tree) assert w2.to_tree() == tree - - -def test_lang(): - """Test translation.""" - with voila_language(lang="de"): - w = WidgetSimpleGasSelection() - assert "Sauerstoff" in w.gas_list diff --git a/weldx_widgets/widget_base.py b/weldx_widgets/widget_base.py index 200968b..7df366d 100644 --- a/weldx_widgets/widget_base.py +++ b/weldx_widgets/widget_base.py @@ -7,8 +7,27 @@ from weldx.asdf.util import get_schema_path +def metaclass_resolver(*classes): + """Merge multiple meta classes.""" + # Does something like this: + # https://coderedirect.com/questions/163000/multiple-inheritance-metaclass-conflict + metaclass = tuple(set(type(cls) for cls in classes)) -class WidgetBase: + def cls_name(classes): + return "_".join(mcls.__name__ for mcls in classes) + + metaclass = ( + metaclass[0] + if len(metaclass) == 1 + else type(cls_name(metaclass), metaclass, {}) + ) # class M_C + return metaclass(cls_name(classes), classes, {}) # class C + +class _merged_meta(type(abc.ABC)): # avoid metaclass conflict. + pass + + +class WidgetBase(abc.ABC, metaclass=_merged_meta): """Base class for weldx widgets.""" def copy(self): @@ -41,7 +60,7 @@ def _ipython_display_(self): margin = "" # "10px" -class WidgetMyHBox(HBox, WidgetBase): +class WidgetMyHBox(metaclass_resolver(HBox, WidgetBase)): """Wrap around a HBox sharing a common layout.""" def __init__(self, *args, **kwargs): @@ -56,7 +75,7 @@ def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) -class WidgetMyVBox(VBox, WidgetBase): +class WidgetMyVBox(metaclass_resolver(VBox, WidgetBase)): """Wrap around a VBox sharing a common layout.""" def __init__(self, *args, **kwargs): diff --git a/weldx_widgets/widget_evaluate.py b/weldx_widgets/widget_evaluate.py index 883429d..92265df 100644 --- a/weldx_widgets/widget_evaluate.py +++ b/weldx_widgets/widget_evaluate.py @@ -26,7 +26,7 @@ Trace, WeldxFile, ) -from weldx_widgets.widget_base import WidgetBase, WidgetSimpleOutput +from weldx_widgets.widget_base import WidgetBase, WidgetSimpleOutput, metaclass_resolver from weldx_widgets.widget_factory import make_title from weldx_widgets.widget_measurement import WidgetMeasurement, WidgetMeasurementChain @@ -85,7 +85,7 @@ def dims_as_coords(arr): data.coordinates = filtered -class WidgetEvaluateSinglePassWeld(Tab, WidgetBase): +class WidgetEvaluateSinglePassWeld(metaclass_resolver(Tab, WidgetBase)): """Aggregate info of passed file in several tabs.""" def __init__(self, file: WeldxFile): diff --git a/weldx_widgets/widget_gmaw.py b/weldx_widgets/widget_gmaw.py index b1e0c00..b18a486 100644 --- a/weldx_widgets/widget_gmaw.py +++ b/weldx_widgets/widget_gmaw.py @@ -38,7 +38,7 @@ def plot_gmaw(gmaw, t): fig, ax = plt.subplots(nrows=n, sharex="all", figsize=(_DEFAULT_FIGWIDTH, 2 * n)) for i, k in enumerate(pars): parplot(pars[k], t, k, ax[i]) - ax[-1].set_xlabel("time") + " / s" + ax[-1].set_xlabel("time / s") ax[0].set_title(title, loc="left") # ipympl_style(fig) From df028b16aea4273f653b1fd4821ed364cb8d5432 Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Mon, 4 Dec 2023 19:45:23 +0100 Subject: [PATCH 13/40] black --- weldx_widgets/tests/test_process.py | 8 -------- weldx_widgets/widget_base.py | 2 ++ weldx_widgets/widget_evaluate.py | 4 +--- weldx_widgets/widget_gas.py | 4 +--- weldx_widgets/widget_gmaw.py | 6 ++---- weldx_widgets/widget_groove_sel.py | 8 +++----- 6 files changed, 9 insertions(+), 23 deletions(-) diff --git a/weldx_widgets/tests/test_process.py b/weldx_widgets/tests/test_process.py index 65fd9ee..c2937fa 100644 --- a/weldx_widgets/tests/test_process.py +++ b/weldx_widgets/tests/test_process.py @@ -4,7 +4,6 @@ import weldx from weldx import Q_ from weldx_widgets import WidgetGMAW -from weldx_widgets.tests.util import voila_language @pytest.mark.parametrize( @@ -44,10 +43,3 @@ def test_import_export(kind, write_file): w2.from_tree(tree) assert w2.to_tree() == tree - - -def test_lang(): - """Test translation.""" - with voila_language(lang="de"): - w = WidgetGMAW(process_type="spray") - assert w.welding_wire.diameter.text == "Durchmesser" diff --git a/weldx_widgets/widget_base.py b/weldx_widgets/widget_base.py index 7df366d..48b92ef 100644 --- a/weldx_widgets/widget_base.py +++ b/weldx_widgets/widget_base.py @@ -7,6 +7,7 @@ from weldx.asdf.util import get_schema_path + def metaclass_resolver(*classes): """Merge multiple meta classes.""" # Does something like this: @@ -23,6 +24,7 @@ def cls_name(classes): ) # class M_C return metaclass(cls_name(classes), classes, {}) # class C + class _merged_meta(type(abc.ABC)): # avoid metaclass conflict. pass diff --git a/weldx_widgets/widget_evaluate.py b/weldx_widgets/widget_evaluate.py index 92265df..22835c3 100644 --- a/weldx_widgets/widget_evaluate.py +++ b/weldx_widgets/widget_evaluate.py @@ -218,9 +218,7 @@ def make_output(): self._compare_design_tcp(csm) plt.show() - super().__init__( - children=tuple(tabs.values()) - ) + super().__init__(children=tuple(tabs.values())) for i, key in enumerate(tabs.keys()): self.set_title(i, key) self.tabs = tabs diff --git a/weldx_widgets/widget_gas.py b/weldx_widgets/widget_gas.py index 6a61cb7..eeeef15 100644 --- a/weldx_widgets/widget_gas.py +++ b/weldx_widgets/widget_gas.py @@ -44,9 +44,7 @@ def __init__(self, index=0, percentage=100): def _set_gas_list(self): self.gas_list = ["Argon", "CO2", "Helium", "Hydrogen", "Oxygen"] - self._mapping = bidict( - dict(zip(self.gas_list, self._asdf_gas_names)) - ) + self._mapping = bidict(dict(zip(self.gas_list, self._asdf_gas_names))) def _clear(self): self.children = [self.children[0]] diff --git a/weldx_widgets/widget_gmaw.py b/weldx_widgets/widget_gmaw.py index b18a486..561d242 100644 --- a/weldx_widgets/widget_gmaw.py +++ b/weldx_widgets/widget_gmaw.py @@ -99,9 +99,7 @@ class ProcessPulsed(WidgetMyVBox): def __init__(self, kind="UI"): self.pulse_duration = FloatWithUnit("Pulse duration", value=5.0, unit="ms") - self.pulse_frequency = FloatWithUnit( - "Pulse frequency", value=100.0, unit="Hz" - ) + self.pulse_frequency = FloatWithUnit("Pulse frequency", value=100.0, unit="Hz") self.base_current = FloatWithUnit("Base current", value=60.0, unit="A") if kind == "UI": @@ -333,7 +331,7 @@ def from_tree(self, tree: dict): kind = welding_process.meta["modulation"] process_type = f"Pulsed ({kind})" elif welding_process.base_process == "spray": - process_type = ("Spray") + process_type = "Spray" else: raise NotImplementedError( f"unknown process type: {welding_process.base_process}" diff --git a/weldx_widgets/widget_groove_sel.py b/weldx_widgets/widget_groove_sel.py index af0e7a0..35c5c7e 100644 --- a/weldx_widgets/widget_groove_sel.py +++ b/weldx_widgets/widget_groove_sel.py @@ -326,11 +326,11 @@ def _create_groove_dropdown(self): t = f"{(item[0].upper() + item[1:]).replace('_', ' ')}" matches = re.match("(.*)([0-9]+)", t) if matches: - t = (matches.group(1)) + t = matches.group(1) number = matches.group(2) text = f"{t} {number}" else: - text = (t) + text = t if "angle" in item: param_widgets[item] = FloatWithUnit(text=text, unit="°", value=45) elif "workpiece_thickness" in item: @@ -451,9 +451,7 @@ def __init__(self): self.groove_sel, ] - super().__init__( - children=children, layout=Layout(width="100%") - ) + super().__init__(children=children, layout=Layout(width="100%")) def create_csm_and_plot(self, change=None, plot=True, **kwargs): """Create coordinates system manager containing TCP movement.""" From 2ab6da898212931c4585a5495a95a0dd96ea1bfd Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Thu, 7 Dec 2023 16:39:23 +0100 Subject: [PATCH 14/40] fix --- weldx_widgets/widget_gmaw.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/weldx_widgets/widget_gmaw.py b/weldx_widgets/widget_gmaw.py index 561d242..4b5ca18 100644 --- a/weldx_widgets/widget_gmaw.py +++ b/weldx_widgets/widget_gmaw.py @@ -58,7 +58,7 @@ def __init__(self, tag: str, meta=None): self.tag = tag self.meta = meta - self.manufacturer = WidgetLabeledTextInput("Manufacturer"), "Fronius" + self.manufacturer = WidgetLabeledTextInput("Manufacturer", "Fronius") self.power_source = WidgetLabeledTextInput("Power source", "TPS 500i") self.wire_feedrate = FloatWithUnit( text="Wire feed rate", value=10, min=0, unit="m/min" @@ -263,9 +263,9 @@ class WidgetGMAW(WidgetMyVBox, WeldxImportExport): def _set_gui_mapping(self): self.translate = bidict( { - ("Spray"): "spray", - ("Pulsed") + " (UI)": "UI", - ("Pulsed") + " (II)": "II", + "Spray": "spray", + "Pulsed (UI)": "UI", + "Pulsed (II)": "II", # _("CMT"): NotImplemented, } ) @@ -281,7 +281,7 @@ def __init__(self, process_type="spray"): self.process_type = Dropdown( options=list(self.translate.keys()), index=index, - description=("Process type"), + description="Process type", ) self.process_type.observe(self._create_process_widgets, names="value") self.gas = WidgetShieldingGas() @@ -290,7 +290,7 @@ def __init__(self, process_type="spray"): children = [ make_title("GMAW process parameters"), - make_title(("Shielding gas"), 4), + make_title("Shielding gas", 4), self.gas, self.welding_wire, # self.weld_speed, # TODO: speed is given by feedrate and groove! From 6bb1b7ae7e32b66ee5c99be01204db4daad951f2 Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Thu, 7 Dec 2023 16:39:35 +0100 Subject: [PATCH 15/40] minor --- weldx_widgets/widget_factory.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/weldx_widgets/widget_factory.py b/weldx_widgets/widget_factory.py index 88718e4..217f0fd 100644 --- a/weldx_widgets/widget_factory.py +++ b/weldx_widgets/widget_factory.py @@ -1,8 +1,7 @@ """Factory for commonly used widget elements.""" import contextlib -import ipywidgets as widgets -from ipywidgets import HTML, Label, Layout, Text +from ipywidgets import HTML, BoundedFloatText, Label, Layout, Text from traitlets import All, HasTraits from weldx import Q_, TimeSeries @@ -66,7 +65,7 @@ class FloatWithUnit(WidgetMyHBox): def __init__(self, text, unit, value: float = 0.0, min=0): self._label = Label(text, layout=description_layout) - self._float = widgets.BoundedFloatText( + self._float = BoundedFloatText( value=value, min=min, max=2**32, layout=textbox_layout ) self._unit = Text(value=unit, placeholder="unit", layout=textbox_layout) From 700280b293ae361b409c6367cdcfd8af8a28ebf6 Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Thu, 7 Dec 2023 16:40:12 +0100 Subject: [PATCH 16/40] minor --- weldx_widgets/tests/test_k3d.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/weldx_widgets/tests/test_k3d.py b/weldx_widgets/tests/test_k3d.py index 13267be..f4e3467 100644 --- a/weldx_widgets/tests/test_k3d.py +++ b/weldx_widgets/tests/test_k3d.py @@ -1,4 +1,5 @@ """Test k3d implementations.""" +import pytest import weldx from weldx import U_, CoordinateSystemManager, Time, get_groove @@ -24,7 +25,7 @@ def test_k3d_csm_vis(): root_face="1 mm", ) - spatial = weldx.Geometry(groove, "10mm").spatial_data("1 mm", "1 mm") + spatial = weldx.Geometry(groove, "10 mm").spatial_data("1 mm", "1 mm") csm.assign_data(spatial, "workpiece", "A") plot = CoordinateSystemManagerVisualizerK3D(csm=csm) From e7e6bb83a2b8da694d7c00e821832dd13e0458e4 Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Thu, 7 Dec 2023 16:40:29 +0100 Subject: [PATCH 17/40] removed tautological argument --- weldx_widgets/tests/test_process.py | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/weldx_widgets/tests/test_process.py b/weldx_widgets/tests/test_process.py index c2937fa..6463cf0 100644 --- a/weldx_widgets/tests/test_process.py +++ b/weldx_widgets/tests/test_process.py @@ -7,14 +7,14 @@ @pytest.mark.parametrize( - ("kind", "write_file"), + "kind", ( - ("spray", True), - ("UI", True), - ("II", True), + "spray", + "UI", + "II", ), ) -def test_import_export(kind, write_file): +def test_import_export(kind): """Ensure import and exports of Widgets works.""" w = WidgetGMAW(process_type=kind) proc = w.welding_process @@ -32,12 +32,11 @@ def test_import_export(kind, write_file): tree = w.to_tree() - if write_file: - tree = { - key: value - for key, value in weldx.WeldxFile(tree=tree, mode="rw").items() - if key not in ("asdf_library", "history") - } + tree = { + key: value + for key, value in weldx.WeldxFile(tree=tree, mode="rw").items() + if key not in ("asdf_library", "history") + } w2 = WidgetGMAW() w2.from_tree(tree) From 08c8546ded86f79a31199072e5c9478598d04913 Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Thu, 7 Dec 2023 16:40:42 +0100 Subject: [PATCH 18/40] format --- weldx_widgets/widget_base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/weldx_widgets/widget_base.py b/weldx_widgets/widget_base.py index 48b92ef..46fb499 100644 --- a/weldx_widgets/widget_base.py +++ b/weldx_widgets/widget_base.py @@ -12,7 +12,7 @@ def metaclass_resolver(*classes): """Merge multiple meta classes.""" # Does something like this: # https://coderedirect.com/questions/163000/multiple-inheritance-metaclass-conflict - metaclass = tuple(set(type(cls) for cls in classes)) + metaclass = tuple({type(cls) for cls in classes}) def cls_name(classes): return "_".join(mcls.__name__ for mcls in classes) From 8b5f6dfc3d88be807edf26bf677bee0b11ada57f Mon Sep 17 00:00:00 2001 From: Cagtay Fabry <43667554+CagtayFabry@users.noreply.github.com> Date: Mon, 11 Dec 2023 21:20:15 +0100 Subject: [PATCH 19/40] fix k3d test --- weldx_widgets/visualization/csm_k3d.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/weldx_widgets/visualization/csm_k3d.py b/weldx_widgets/visualization/csm_k3d.py index a6b86b4..87575f3 100644 --- a/weldx_widgets/visualization/csm_k3d.py +++ b/weldx_widgets/visualization/csm_k3d.py @@ -198,7 +198,7 @@ def _update_positions(self, coordinates: pint.Quantity, orientation: np.ndarray) orientation : The new orientation """ - self._vectors.origins = [coordinates for _ in range(3)] + self._vectors.origins = [coordinates.to(_DL).m for _ in range(3)] self._vectors.vectors = orientation.transpose() * self._vector_scale self.origin.model_matrix = _create_model_matrix(coordinates, orientation) if self._label is not None: From fbf66c369c254e504a232736bd2dfbb521c965a7 Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Wed, 13 Dec 2023 13:06:03 +0100 Subject: [PATCH 20/40] fix unit stripped in min/max reduction --- weldx_widgets/visualization/csm_k3d.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/weldx_widgets/visualization/csm_k3d.py b/weldx_widgets/visualization/csm_k3d.py index 87575f3..5e121a7 100644 --- a/weldx_widgets/visualization/csm_k3d.py +++ b/weldx_widgets/visualization/csm_k3d.py @@ -2,6 +2,7 @@ from __future__ import annotations +import warnings from typing import TYPE_CHECKING, Union import k3d @@ -275,17 +276,21 @@ def update_time_index(self, index: int): def limits(self): lcs = self._lcs dims = [d for d in lcs.coordinates.dims if d != "c"] - if dims: - mins = lcs.coordinates.min(dim=dims).data - maxs = lcs.coordinates.max(dim=dims).data - return np.vstack([mins, maxs]) + with warnings.catch_warnings(): + warnings.filterwarnings("ignore", category=pint.errors.UnitStrippedWarning) + if dims: + # unit gets stripped during min/max reduction, so restore it. + unit = lcs.coordinates.data.u + mins = lcs.coordinates.min(dim=dims).data + maxs = lcs.coordinates.max(dim=dims).data + return np.vstack([mins, maxs]) * unit return np.vstack([lcs.coordinates.data, lcs.coordinates.data]) class SpatialDataVisualizer: """Visualizes spatial data.""" - visualization_methods = ["auto", "point", "mesh", "both"] + visualization_methods = ("auto", "point", "mesh", "both") def __init__( self, From a95ea8b71f884ea56997f5b41f6dfe9b06097ffe Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Wed, 13 Dec 2023 13:25:02 +0100 Subject: [PATCH 21/40] added ruff --- .pre-commit-config.yaml | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index cd4232f..cebdba4 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -5,7 +5,7 @@ ci: for more information, see https://pre-commit.ci autofix_prs: false autoupdate_commit_msg: '[pre-commit.ci] pre-commit autoupdate' - autoupdate_schedule: weekly + autoupdate_schedule: monthly skip: [] submodules: false repos: @@ -16,20 +16,16 @@ repos: args: [--markdown-linebreak-ext=md] - id: end-of-file-fixer - id: check-yaml - exclude: devtools/conda.recipe/meta.yaml # doesn't play nice with jinja -# - id: no-commit-to-branch # only makes sense for local pre-commit hooks -- repo: https://github.com/psf/black - rev: 23.11.0 - hooks: - - id: black -- repo: https://github.com/PyCQA/isort - rev: 5.12.0 - hooks: - - id: isort -- repo: https://github.com/PyCQA/flake8 - rev: 6.1.0 - hooks: - - id: flake8 + +- repo: https://github.com/astral-sh/ruff-pre-commit + # Ruff version. + rev: v0.1.7 + hooks: + # Run the linter. + - id: ruff + # Run the formatter. + - id: ruff-format + - repo: https://github.com/PyCQA/pydocstyle rev: 6.3.0 hooks: From 78ca8b1c13211395d515db1fd7f5d52549713165 Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Wed, 13 Dec 2023 13:25:22 +0100 Subject: [PATCH 22/40] removed kisa submod --- weldx_widgets/kisa/__init__.py | 1 - weldx_widgets/kisa/load.py | 35 --- weldx_widgets/kisa/save.py | 253 -------------------- weldx_widgets/kisa/widget_robot_program.py | 129 ----------- weldx_widgets/kisa/widget_scans.py | 258 --------------------- 5 files changed, 676 deletions(-) delete mode 100644 weldx_widgets/kisa/__init__.py delete mode 100644 weldx_widgets/kisa/load.py delete mode 100644 weldx_widgets/kisa/save.py delete mode 100644 weldx_widgets/kisa/widget_robot_program.py delete mode 100644 weldx_widgets/kisa/widget_scans.py diff --git a/weldx_widgets/kisa/__init__.py b/weldx_widgets/kisa/__init__.py deleted file mode 100644 index bd362ff..0000000 --- a/weldx_widgets/kisa/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""Widgets solely belonging to the KISA project.""" diff --git a/weldx_widgets/kisa/load.py b/weldx_widgets/kisa/load.py deleted file mode 100644 index 14c08bd..0000000 --- a/weldx_widgets/kisa/load.py +++ /dev/null @@ -1,35 +0,0 @@ -"""Utility functions to set widget state from a given file.""" -from pathlib import Path -from typing import Iterable, Union - -import weldx -from weldx_widgets.kisa.save import get_param_from_env -from weldx_widgets.widget_base import WeldxImportExport - - -def set_state_from_file( - widget: Union[WeldxImportExport, Iterable[WeldxImportExport]], file=None -): - """Set the state of given widgets from weldx file tree.""" - if not file: - file = get_param_from_env("file") - - if not isinstance(widget, Iterable): - widget = [widget] - - if isinstance(file, (str, Path)): - file = Path(file) - if file.exists() and file.stat().st_size > 0: - try: - with weldx.WeldxFile(file, mode="r") as wx: - for w in widget: - try: - w.from_tree(wx) - except KeyError as ke: - print(f"Key not found in given file. Details: {ke}") - except Exception as e: - print(f"Error during reading {file}: {e}") - except Exception as e: - print(f"Error during reading {file}: {e}") - else: - print(f"Unknown input file type: {type(file)}") diff --git a/weldx_widgets/kisa/save.py b/weldx_widgets/kisa/save.py deleted file mode 100644 index ea09681..0000000 --- a/weldx_widgets/kisa/save.py +++ /dev/null @@ -1,253 +0,0 @@ -"""Widget to save the state of a WeldxFile and invoke the next step in the pipeline.""" -import pathlib -import typing -from os import environ as env -from typing import Any, Dict, Mapping, TypeVar -from urllib.parse import parse_qs, urlencode - -import ipywidgets as w - -import weldx -import weldx_widgets -import weldx_widgets.widget_base -import weldx_widgets.widget_factory -from weldx_widgets.widget_factory import button_layout - -__all__ = [ - "SaveAndNext", - "build_url", - "get_param_from_env", - "invoke_url", -] - - -def get_param_from_env(name, default=None) -> str: - """Extract parameter from env.QUERY_STRING. - - Parameters - ---------- - name : - name of the parameter to extract. - - default : - optional default value, if parameter is not set. - - Returns - ------- - str : - value of the requested parameter. - - """ - query_string = env.get("QUERY_STRING", "") - parameters = parse_qs(query_string) - try: - value = parameters[name][0] - except KeyError: # TODO: this can also raise something else, right? - if default: - return default - else: - raise RuntimeError( - f"parameter '{name}' unset and no default provided." - f" Given parameters: {parameters}" - ) from None - return value - - -def build_url(board: str, parameters: dict = None, invoke=True, out=None) -> str: - """Build an URL with given parameters. - - Parameters - ---------- - board : - dash board to invoke next. May contain a relative path. - parameters : - optional parameters to encode. - invoke : - should the url be invoked in a web browser? - - Returns - ------- - str : - the built url. - """ - if invoke and not out: - raise ValueError("need output to invoke Javascript.") - - server = env.get("SERVER_NAME", "localhost") - protocol = env.get("SERVER_PROTOCOL", "HTTP") - if "HTTPS" in protocol: - url = "https://" - else: - url = "http://" - url += server - - # TODO: this only works from voila! - port = env.get("SERVER_PORT", "8888") - - if port: - url += f":{port}/" - else: - url += "/" - voila = "voila" in env.get("SERVER_SOFTWARE", "") - prefix = "voila/render" if voila else "" - - url += f"{prefix}/{board}" - - if parameters: - params_encoded = urlencode(parameters) - url += f"?{params_encoded}" - - if invoke: - invoke_url(url, out) - return url - - -def invoke_url(url, out): - """Invoke url in new browser tab. - - We cannot use python stdlib webbrowser here, because this code will be executed - on the server. So we impl this via Javascript. - """ - from IPython.display import Javascript, clear_output, display - - with out: - clear_output() - js = Javascript(f'window.open("{url}");') - display(js) - - -_KeyType = TypeVar("KeyType") - - -def _deep_update_inplace( - mapping: Dict[_KeyType, Any], *updating_mappings: Dict[_KeyType, Any] -) -> Dict[_KeyType, Any]: - for updating_mapping in updating_mappings: - for k, v in updating_mapping.items(): - if k in mapping and isinstance(mapping[k], dict) and isinstance(v, Mapping): - mapping[k] = _deep_update_inplace(mapping[k], v) - else: - mapping[k] = v - return mapping - - -class SaveAndNext(weldx_widgets.widget_base.WidgetMyVBox): - """Collect all the data from passed import/output widget list and stores it. - - Parameters - ---------- - filename: - output file name. - next_notebook: - next dashboard/notebook to invoke. - status : - the file update will contain the new status. - collect_data_from : - a list of widgets to build a tree from. - next_notebook_params : - optional parameters for next dashboard. - - Notes - ----- - The passed status will be set into the wx_user["kisa"]["status"] dict. - """ - - def __init__( - self, - filename, - next_notebook: str, - status: str, - collect_data_from: typing.List[weldx_widgets.widget_base.WeldxImportExport], - next_notebook_desc: str = "Invoke next step", - next_notebook_params=None, - title="Save results", - disable_next_button=True, - ): - self.status = status - self.collect_data_from = collect_data_from - self.out = w.Output() - - if not disable_next_button: - self.btn_next = w.Button( - description=next_notebook_desc, layout=button_layout - ) - if next_notebook_params is None: - next_notebook_params = dict() - self.next_notebook_params = next_notebook_params - self.next_notebook = next_notebook - self.btn_next.on_click(self.on_next) - - self._initial_file = filename # remember initial choice of file. - fn_path = pathlib.Path(filename) - path = str(fn_path.parent) - fn = str(fn_path.name) - self.save_button = weldx_widgets.WidgetSaveButton( - desc="1. Save" if not disable_next_button else "Save", - filename=fn, - path=path, - select_default=True, - ) - self.save_button.set_handler(self.on_save) - if not disable_next_button: - self.save_button.children += (self.btn_next,) - - children = [ - weldx_widgets.widget_factory.make_title(title), - self.save_button, - self.out, - ] - super().__init__(children=children) - - @property - def filename(self): - """Return output file name.""" - return self.save_button.path - - def on_save(self, _): - """Handle saving data to file.""" - from IPython.display import clear_output, display - - clear_output() - - result = dict() - for widget in self.collect_data_from: - _deep_update_inplace(result, widget.to_tree()) - - # set status - result["wx_user"] = {"KISA": {"status": self.status}} - - def show_header(handle): - with self.out: - clear_output() - display(handle.header(False, True)) - - # open (existing) file and update it. - if pathlib.Path(self.filename).stem.endswith("_r"): - with self.out: - print("Refusing to save a read-only (template) file!") # noqa: T201 - print("Please choose another name with the '_r' suffix.") # noqa: T201 - return - if self.filename != self._initial_file: - # we want to save the previous file under a different name, so load contents - with weldx.WeldxFile(self._initial_file, mode="r") as fh: - _deep_update_inplace(fh, result) - if not pathlib.Path(self.filename).exists(): - fh.write_to(self.filename) - show_header(fh) - else: - with weldx.WeldxFile(self.filename, mode="rw") as fh2: - _deep_update_inplace(fh2, fh) - show_header(fh2) - else: - with weldx.WeldxFile(self.filename, mode="rw", sync=True) as fh: - _deep_update_inplace(fh, result) - show_header(fh) - - def on_next(self, _): - """Invoke next notebook.""" - build_url( - board=self.next_notebook, - parameters=dict(file=self.filename, **self.next_notebook_params), - invoke=True, - out=self.out, - ) diff --git a/weldx_widgets/kisa/widget_robot_program.py b/weldx_widgets/kisa/widget_robot_program.py deleted file mode 100644 index 65b493e..0000000 --- a/weldx_widgets/kisa/widget_robot_program.py +++ /dev/null @@ -1,129 +0,0 @@ -"""Widget to create a robot program.""" -import tempfile -from io import BytesIO -from pathlib import Path -from typing import Callable, Optional, Union - -import ipywidgets as widgets -import numpy as np -import pint -from ipywidgets import HTML, Button, Label, Layout - -from weldx import Q_, WeldxFile -from weldx.tags.core.file import ExternalFile -from weldx_widgets.generic import download_button -from weldx_widgets.widget_base import WidgetMyVBox -from weldx_widgets.widget_factory import FloatWithUnit, make_title - -__all__ = [ - "WidgetLinearWeldYaskawa", -] - - -class WidgetLinearWeldYaskawa(WidgetMyVBox): - """After process parameters and groove shape selection, generate a program. - - The program is created with one button, then downloaded with another. - Another side-effect of saving this widget into a weldx file is, that the content - of the robot program is stored in the weldx file. - - Parameters - ---------- - wx_file : - Weldx input file name, has to contain geometry and welding seam information. - program_func : - Callable to create to actual robot program. - """ - - def __init__( - self, - wx_file: str, - program_func: Callable[ - [Union[str, Path, WeldxFile], pint.Quantity, str, bool], Union[Path, bytes] - ], - ): - self.temp_dir = tempfile.TemporaryDirectory() # outputs will be stored here. - self.output: Optional[bytes] = None # binary contents of robot program. - self.wx_file = wx_file - self.program_func = program_func - # The translation from the user frame (UF) to the - # workpiece coordinate system (WCS). - # The vector points UF -> WCS. - xyz = ( - FloatWithUnit(text="x", unit="mm", value=-20, min=-999999), - FloatWithUnit(text="y", unit="mm", value=115.8, min=-999999), - FloatWithUnit(text="z [optional]", unit="mm", value=0, min=-999999), - ) - - self.uf_to_workpiece = WidgetMyVBox( - children=[ - Label( - "Translation vector from user frame to workpiece coordinate system", - ), - *xyz, - ] - ) - self.jobname = widgets.Text(description="Jobname", value="MAIN_LINEAR_NEW") - - self.button_create = Button( - description="Create program", - ) - self.button_create.on_click(self.create_linear_program) - - # changes to x, y, z or job name invalidate the download button - for elem in xyz: - for w in elem.children[1:]: - w.observe(self._invalidate_dl_button) - self.jobname.observe(self._invalidate_dl_button) - - super().__init__( - children=[ - make_title("Create Yaskawa program (linear seam)"), - self.uf_to_workpiece, - self.jobname, - self.button_create, - HTML(), - ], - layout=Layout(width="500px"), - ) - - def _invalidate_dl_button(self, button): - self.children[-1].value = "" - - def create_linear_program(self, button): - """Invoke self.program_func with form parameters and create download button.""" - base_unit = self.uf_to_workpiece.children[1].unit - uf_to_workpiece = Q_(np.array([None, None, None]), base_unit) - uf_to_workpiece[0] = self.uf_to_workpiece.children[1].quantity.to(base_unit) - uf_to_workpiece[1] = self.uf_to_workpiece.children[2].quantity.to(base_unit) - if self.uf_to_workpiece.children[3].float_value != 0: - uf_to_workpiece[2] = self.uf_to_workpiece.children[3].quantity.to(base_unit) - else: - uf_to_workpiece = uf_to_workpiece[:2] - assert len(uf_to_workpiece) == 2 - - with WeldxFile(self.wx_file, mode="r") as wx_input: - temp: BytesIO = wx_input.write_to(None) - output: bytes = self.program_func(temp, uf_to_workpiece, write_file=False) - dl_button = self.children[-1] - download_button( - output, - filename=f"{self.jobname.value}.JBI", - button_description="Download program", - html_instance=dl_button, - ) - - self.output = output - - def to_tree(self) -> dict: - """Export state.""" - if not self.output: - return {} - fn = Path(self.jobname.value) - with open(self.temp_dir.name / fn, mode="wb") as fh: - fh.write(self.output) - external_file = ExternalFile(fh.name, asdf_save_content=True) - return dict(robot_program=external_file) - - def from_tree(self, tree): - """Set state. Is currently a dummy.""" diff --git a/weldx_widgets/kisa/widget_scans.py b/weldx_widgets/kisa/widget_scans.py deleted file mode 100644 index 283158e..0000000 --- a/weldx_widgets/kisa/widget_scans.py +++ /dev/null @@ -1,258 +0,0 @@ -"""Widget showing scanner results.""" -from pathlib import Path -from typing import Tuple - -import numpy as np -import xarray as xr -from tqdm.autonotebook import tqdm - -import weldx -from weldx_widgets.widget_base import WidgetSimpleOutput - -__all__ = ["WidgetScans"] - - -# TODO: import/use this from libo lib! -# TODO: handle both cases, parameterstudie (mehrere schweißungen auf einem werkstück) -# und einzel schweißung! -class WidgetScans(WidgetSimpleOutput): - """Extracts triggers and scan data from given files and visualizes it. - - Parameters - ---------- - mh24_file : - path to twincat main file. - tool_file : - path to yaskawa tool file. - scans_dir : - path to scan directory. - single_weld : - Just one scan, or multiple? - max_scans : - limit for scans to read in/visualize. - """ - - def __init__( - self, mh24_file, tool_file, scans_dir, single_weld=False, max_scans=None - ): - super().__init__(width="100%", height="800 px") - - self.mh24_file = Path(mh24_file) - self.tool_file = Path(tool_file) - self.scans_dir = Path(scans_dir) - assert self.scans_dir.exists() - assert self.mh24_file.exists() - assert self.tool_file.exists() - - self.max_scans = max_scans - self.single_weld = single_weld - - from cached_io import read_cached_txt - - mh24_ds = read_cached_txt(mh24_file) - from libo.utils import split_by_trigger - - mh_scan_list = split_by_trigger(mh24_ds, "trigScan1_prog") - mh_schweiss_list = split_by_trigger(mh24_ds, "trigSchweissen") - - self.csm = weldx.CoordinateSystemManager("user_frame") - - self._create_csm(mh_schweiss_list) - self._vorher_nachher_scans_an_csm(mh_scan_list) - - def _create_csm(self, mh_schweiss_list): - for mh_schweiss in mh_schweiss_list[: self.max_scans]: - coords = mh_schweiss[["UF_X", "UF_Y", "UF_Z"]].dropna(dim="time") - coords = ( - coords.to_array(dim="c") - .assign_coords(dict(c=["x", "y", "z"])) - .astype("float32") - ) - coords_start = coords.isel(time=0).drop("time") - tcp_start = weldx.LocalCoordinateSystem(coordinates=coords_start) - tpc_in_uf = weldx.LocalCoordinateSystem(coordinates=coords - coords_start) - naht_NR = int(mh_schweiss.naht_NR.max().values) - self.csm.add_cs(f"n_start{naht_NR}", "user_frame", tcp_start) - self.csm.add_cs(f"n{naht_NR}", f"n_start{naht_NR}", tpc_in_uf) - - def _vorher_nachher_scans_an_csm(self, mh_scan_list): - scans = [] - # TODO: handle self.single_weld (different pattern needed). - if self.single_weld: - _slice = slice(1, self.max_scans, 2) - n = len(mh_scan_list[_slice]) - mh_scan_list_i = iter(mh_scan_list[_slice]) - else: - _slice = slice(1, self.max_scans) - mh_scan_list_i = iter(mh_scan_list[_slice]) - n = len(mh_scan_list[_slice]) - self._max_heights = [] - with self.out: - for mh_scan in tqdm(mh_scan_list_i, total=n, desc="process scan data"): - naht_nr = int(mh_scan.naht_NR.max().values) - schw_nr = int(mh_scan.schw_NR.max().values) - pattern = f"LLT1_WID*_N{naht_nr:03d}_L001_R001_S{schw_nr}_*.nc" - scans_list = list(self.scans_dir.glob(pattern)) - assert len(scans_list) == 1 - - SCAN_file = scans_list[0] - scan = xr.load_dataset(SCAN_file) - - res = self._build_scan_data(mh_scan, scan) - scan_name = f"scan_N{naht_nr}_S{schw_nr}" - scans.append(scan_name) - res = self.csm.transform_data(res, "user_frame", f"n_start{naht_nr}") - # determine max value and store it for later display - # TODO: max should return use only z-dimension - max_height = res.coordinates.max(dim="n") - print(max_height) - self._max_heights.append(max_height[2]) - self.csm.assign_data(res, scan_name, f"n_start{naht_nr}") - self.csm.assign_data( - max_height, scan_name + "max_h", f"n_start{naht_nr}" - ) - self.scans = scans - - def display(self): - """Render all pairs of scans and tcp movements.""" - scans = [ - f"n{x}" - for x in range(1, self.max_scans - 1 if self.max_scans else len(self.scans)) - ] - self.out.clear_output() - with self.out: - self.csm.plot( - backend="k3d", - coordinate_systems=["user_frame"] + scans, - data_sets=self.scans, - axes_equal=True, - ) - # from matplotlib.pylab import plot - - # plot(self._max_heights) - # TODO: add maximum height points and descriptions - # import k3d - - # for i, max_ in enumerate(self._max_heights): - # max_heights = k3d.points( - # positions=max_.T, point_size=3, name="max height %i" % i - # ) - # vis.plot += max_heights - - def _build_scan_data( - self, - mh_scan, - scan: xr.Dataset, - ) -> weldx.SpatialData: - """Create transformed scan SpatialData from robot movement and LLT scan data. - - Parameters - ---------- - mh_scan: - The pre sliced trigger information - create by e.g. ``split_by_trigger(mh24, "trigScan1_prog")`` - scan: - The scan data as loaded xr.Dataset - - Returns - ------- - weldx.SpatialData - The scan data transformed into default user_frame - """ - from libo.io.yaskawa import create_csm - from libo.utils import get_data_transformation - - # load tool CSM -------------------------------------------------------------- - csm_tool = create_csm(self.tool_file) - csm_tool.relabel({"STANDARD": "TCP"}) - csm_tool.add_cs( - "LLT_1_data", - "LLT_1", - lcs=weldx.LocalCoordinateSystem( - coordinates=[0, 0, -260], - orientation=weldx.WXRotation.from_euler("z", -90, degrees=True), - ), - ) - - lcs = get_data_transformation(mh_scan) - - # build and reshape scan data ------------------------------------------------- - data, triangle_indices = self._reshape_scan_data(scan, lcs) - - data[(data[:, 2] < -250), 2] = np.nan # simple outliner removal - data[(data[:, 2] > 50), 2] = np.nan # simple outliner removal - sd = weldx.SpatialData( - coordinates=data.astype("float32"), - triangles=triangle_indices.astype("uint32"), - ) - - return sd - - def _reshape_scan_data( - self, - ds: xr.Dataset, - lcs: weldx.LocalCoordinateSystem, - ) -> Tuple[np.ndarray, np.ndarray]: - """Transform data gathered by LLT Dashboard into userframe coordinates. - - Parameters - ---------- - ds: - scan-dataset produced by LLT Dashboard - lcs: - LocalCoordinateSystem that describes the movement of - the LLT Scanner during scan. - - Returns - ------- - xyz-Data and default triangulation of profile-scan - - """ - nx = ds.n.shape[0] - ny = ds.p.shape[0] - - ds["y"] = (("p", "n"), np.zeros((ny, nx))) - - data_arr = ds[["x", "y", "z"]].to_array("c") - - transformed = weldx.util.xr_matmul( - lcs.orientation, data_arr, dims_a=["c", "v"], dims_b=["c"], dims_out=["c"] - ) - # TODO: input param! - n_slice = slice(450, 800) - transformed = transformed + lcs.coordinates.rename({"time": "p"}) - transformed = transformed.isel(n=n_slice) - - ds = transformed.to_dataset(dim="c") - - nx = ds.n.shape[0] - ny = ds.p.shape[0] - - data = np.zeros((nx * ny, 3)) - data[:, 0] = ds.x.data.flatten() - data[:, 1] = ds.y.data.flatten() - data[:, 2] = ds.z.data.flatten() - - triangle_indices = np.empty((ny - 1, nx - 1, 2, 3), dtype=int) - r = np.arange(nx * ny).reshape(ny, nx) - triangle_indices[:, :, 0, 0] = r[:-1, :-1] - triangle_indices[:, :, 1, 0] = r[:-1, 1:] - triangle_indices[:, :, 0, 1] = r[:-1, 1:] - - triangle_indices[:, :, 1, 1] = r[1:, 1:] - triangle_indices[:, :, :, 2] = r[1:, :-1, None] - triangle_indices.shape = (-1, 3) - - return data, triangle_indices - - -if __name__ == "__main__": - from kisa_config import p_base - - WID = 432 - base = p_base / f"WID{WID}" - - TOOL_file = p_base / "MH24_TOOL.CND" - MH24_file = list((base / "MAIN").glob("*_MH24_MAIN_AutoSave.txt.gz"))[0] - - WidgetScans(MH24_file, TOOL_file, base / "SCAN", max_scans=4).display() From 86487406ec0e4c5ba3b1b6af89fb2378629db0fe Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Wed, 13 Dec 2023 13:26:31 +0100 Subject: [PATCH 23/40] fix b017, raise specific exception --- weldx_widgets/tests/test_visualization.py | 2 +- weldx_widgets/visualization/csm_mpl.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/weldx_widgets/tests/test_visualization.py b/weldx_widgets/tests/test_visualization.py index 3678acc..b781891 100644 --- a/weldx_widgets/tests/test_visualization.py +++ b/weldx_widgets/tests/test_visualization.py @@ -36,7 +36,7 @@ def test_plot_coordinate_system(): # exceptions ------------------------------------------ # label without color - with pytest.raises(Exception): + with pytest.raises(ValueError): vs.draw_coordinate_system_matplotlib(lcs_constant, ax, label="label") diff --git a/weldx_widgets/visualization/csm_mpl.py b/weldx_widgets/visualization/csm_mpl.py index 08e5b1a..470d093 100644 --- a/weldx_widgets/visualization/csm_mpl.py +++ b/weldx_widgets/visualization/csm_mpl.py @@ -177,7 +177,7 @@ def draw_coordinate_system_matplotlib( if show_origin: axes.plot([p_0[0]], [p_0[1]], [p_0[2]], "o", color=color, label=label) elif label is not None: - raise Exception("Labels can only be assigned if a color was specified") + raise ValueError("Labels can only be assigned if a color was specified") def plot_local_coordinate_system_matplotlib( From b3fe01ae64c800944ca298aa6ed295319efe6853 Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Wed, 13 Dec 2023 13:35:52 +0100 Subject: [PATCH 24/40] removed obsolete test file --- weldx_widgets/tests/test_save.py | 52 -------------------------------- 1 file changed, 52 deletions(-) delete mode 100644 weldx_widgets/tests/test_save.py diff --git a/weldx_widgets/tests/test_save.py b/weldx_widgets/tests/test_save.py deleted file mode 100644 index 35a2285..0000000 --- a/weldx_widgets/tests/test_save.py +++ /dev/null @@ -1,52 +0,0 @@ -"""Tests for save widget.""" -import shutil - -import pytest - -import weldx -from weldx_widgets.kisa.save import SaveAndNext - - -class SimpleIO: - """Implements serialization protocol for weldx widgets.""" - - def __init__(self): - self.data = 42 - - def to_tree(self): - """Get data.""" - return {"data": self.data} - - def from_tree(self, tree: dict): - """Set data.""" - self.data = tree["data"] - - -@pytest.mark.parametrize("change", [False, True]) -def test_on_save_update(tmpdir, change): - """Ensure data from input widget get serialized to desired output file. - - Also ensure existing data is preserved, if not being changed by the update. - """ - out_file = str(tmpdir / "out") - - with weldx.WeldxFile(out_file, mode="rw") as fh: - fh["wx_user"] = {"some": "data"} - - status = "test" - w = SaveAndNext( - out_file, next_notebook="no", collect_data_from=[SimpleIO()], status=status - ) - if change: # fake a change of the initial file choice. - new_file = out_file + "_2" - shutil.copy(out_file, new_file) - SaveAndNext.filename = new_file - w.on_save(None) - out_file = new_file - else: - w.on_save(None) - # verify output - with weldx.WeldxFile(out_file) as wx: - assert wx["data"] == 42 - assert "some" in wx["wx_user"] - assert wx["wx_user"]["KISA"]["status"] == status From cbf0ffb60e155b47595f085ae1850bfbafbf025e Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Wed, 13 Dec 2023 13:36:09 +0100 Subject: [PATCH 25/40] fix bugbear os.environ assignment --- weldx_widgets/tests/util.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/weldx_widgets/tests/util.py b/weldx_widgets/tests/util.py index a18c295..6be1644 100644 --- a/weldx_widgets/tests/util.py +++ b/weldx_widgets/tests/util.py @@ -11,7 +11,8 @@ def temp_env(**kw): yield - os.environ = old + os.environ.clear() + os.environ.update(old) @contextlib.contextmanager From db9b96c758a5bbddb433d7947464ae77d955e9a8 Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Wed, 13 Dec 2023 13:36:22 +0100 Subject: [PATCH 26/40] fix bugbear exception chaining --- weldx_widgets/visualization/colors.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/weldx_widgets/visualization/colors.py b/weldx_widgets/visualization/colors.py index 9618ff2..f7e7c89 100644 --- a/weldx_widgets/visualization/colors.py +++ b/weldx_widgets/visualization/colors.py @@ -50,7 +50,7 @@ def _color_int_to_rgb(integer: int) -> Tuple[int, int, int]: def _color_rgb_to_rgb_normalized( - rgb: Tuple[int, int, int] + rgb: Tuple[int, int, int], ) -> Tuple[float, float, float]: """Normalize an RGB color tuple with the range (0-255) to the range (0.0-1.0). @@ -69,7 +69,7 @@ def _color_rgb_to_rgb_normalized( def _color_rgb_normalized_to_rgb( - rgb: Tuple[float, float, float] + rgb: Tuple[float, float, float], ) -> Tuple[int, int, int]: """Normalize an RGB color tuple with the range (0.0-1.0) to the range (0-255). @@ -143,7 +143,7 @@ def _shuffled_tab20_colors() -> List[int]: def color_to_rgb_normalized( - color: Union[int, Tuple[int, int, int], Tuple[float, float, float]] + color: Union[int, Tuple[int, int, int], Tuple[float, float, float]], ) -> Tuple[float, float, float]: """Convert an arbitrary RGB color representation into a normalized RGB triplet. @@ -228,5 +228,5 @@ def get_color( return _color_rgb_to_int(value) try: return next(color_generator) - except StopIteration: - raise RuntimeError(f"given generator {color_generator} exhausted.") + except StopIteration as si: + raise RuntimeError(f"given generator {color_generator} exhausted.") from si From da29b4ab10ee90e3384e97daa263403a4abeee36 Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Wed, 13 Dec 2023 13:37:06 +0100 Subject: [PATCH 27/40] fix bugbear caching of class instance --- weldx_widgets/widget_base.py | 10 +++++++--- weldx_widgets/widget_gmaw.py | 5 +++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/weldx_widgets/widget_base.py b/weldx_widgets/widget_base.py index 46fb499..13b6311 100644 --- a/weldx_widgets/widget_base.py +++ b/weldx_widgets/widget_base.py @@ -131,15 +131,19 @@ def schema(self) -> str: """Return a schema name is used to validate input and output.""" pass + @staticmethod @functools.lru_cache - def get_schema_path(self) -> Path: + def _get_schema_path(schema) -> Path: """Resolve a schema name to path.""" - return get_schema_path(self.schema) + return get_schema_path(schema) + + def get_schema_path(self) -> Path: + return WeldxImportExport._get_schema_path(self.schema) def validate(self, tree): """Validate given tree against schema of this class.""" # should be implemented such that we can validate both input and output. - pass + return @abc.abstractmethod def from_tree(self, tree: dict): diff --git a/weldx_widgets/widget_gmaw.py b/weldx_widgets/widget_gmaw.py index 4b5ca18..8b1fac0 100644 --- a/weldx_widgets/widget_gmaw.py +++ b/weldx_widgets/widget_gmaw.py @@ -306,7 +306,7 @@ def __init__(self, process_type="spray"): def _create_process_widgets(self, change): new = change["new"] arg = self.translate[new] - box = self._cached_process_widgets(arg) + box = WidgetGMAW._cached_process_widgets(arg) self._welding_process.children = (box,) @property @@ -314,8 +314,9 @@ def welding_process(self) -> Union[ProcessSpray, ProcessPulsed]: """Return welding process widget.""" return self._welding_process.children[0] + @staticmethod @lru_cache(None) - def _cached_process_widgets(self, process): + def _cached_process_widgets(process): if process == "spray": return ProcessSpray() From dfbb8eaf94281a9c14b7366a6032b9fd998ba1e9 Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Wed, 13 Dec 2023 13:37:27 +0100 Subject: [PATCH 28/40] format --- weldx_widgets/tests/test_k3d.py | 1 - weldx_widgets/widget_groove_sel.py | 8 +++----- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/weldx_widgets/tests/test_k3d.py b/weldx_widgets/tests/test_k3d.py index f4e3467..fe62dca 100644 --- a/weldx_widgets/tests/test_k3d.py +++ b/weldx_widgets/tests/test_k3d.py @@ -1,5 +1,4 @@ """Test k3d implementations.""" -import pytest import weldx from weldx import U_, CoordinateSystemManager, Time, get_groove diff --git a/weldx_widgets/widget_groove_sel.py b/weldx_widgets/widget_groove_sel.py index 35c5c7e..a27f6b5 100644 --- a/weldx_widgets/widget_groove_sel.py +++ b/weldx_widgets/widget_groove_sel.py @@ -51,11 +51,9 @@ class WidgetCADExport(WidgetMyVBox): does nothing. """ - data_formats = ( - [ # ".stl", # FIXME: for some reason there is a div by zero error in meshio - ".ply" - ] - ) # same groove is fine in ply format... + data_formats = [ # ".stl", # FIXME: for some reason there is a div by zero error in meshio + ".ply" + ] # same groove is fine in ply format... """ example trace for a simple vgroove: meshio/stl/_stl.py in write(filename, mesh, binary) 203 normals = np.cross(pts[:, 1] - pts[:, 0], pts[:, 2] - pts[:, 0]) From c7bd6fd380821549b76e6670170e2c1757ae0df9 Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Wed, 13 Dec 2023 13:58:19 +0100 Subject: [PATCH 29/40] fix docstring --- weldx_widgets/widget_base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/weldx_widgets/widget_base.py b/weldx_widgets/widget_base.py index 13b6311..de415ea 100644 --- a/weldx_widgets/widget_base.py +++ b/weldx_widgets/widget_base.py @@ -134,10 +134,10 @@ def schema(self) -> str: @staticmethod @functools.lru_cache def _get_schema_path(schema) -> Path: - """Resolve a schema name to path.""" return get_schema_path(schema) def get_schema_path(self) -> Path: + """Resolve the actual schema to a path.""" return WeldxImportExport._get_schema_path(self.schema) def validate(self, tree): From b27c7c40e59d54fb4f6f43cde1a2532c803a3bc8 Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Wed, 13 Dec 2023 13:58:35 +0100 Subject: [PATCH 30/40] remove flake8 settings (moved to ruff) --- pyproject.toml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 47b8018..57eec8a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -91,15 +91,6 @@ exclude_lines = [ "pragma: no cover", ] -[tool.flake8] -# see weldx formatting -ignore = "W503,W504,E203" -max-line-length = 88 -select = "C,E,F,W,B,B950" # black formatting options -exclude = [ - "__init__.py", -] - [tool.ruff] target-version = "py38" # designated Python version exclude = [ From d45e1c7fd5e358ccb77dbf958ccef1f048bcb7fb Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Wed, 13 Dec 2023 14:00:11 +0100 Subject: [PATCH 31/40] remove pydocstyle precommit (moved to ruff) --- .pre-commit-config.yaml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index cebdba4..aa28a6f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -25,8 +25,3 @@ repos: - id: ruff # Run the formatter. - id: ruff-format - -- repo: https://github.com/PyCQA/pydocstyle - rev: 6.3.0 - hooks: - - id: pydocstyle From 5362d91a300334c85e0034dca7b3f78c655af353 Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Wed, 13 Dec 2023 14:05:11 +0100 Subject: [PATCH 32/40] remove redundant parentheses around strings --- weldx_widgets/widget_evaluate.py | 4 +-- weldx_widgets/widget_gas.py | 4 +-- weldx_widgets/widget_groove_sel.py | 45 +++++++++++++++--------------- 3 files changed, 26 insertions(+), 27 deletions(-) diff --git a/weldx_widgets/widget_evaluate.py b/weldx_widgets/widget_evaluate.py index 22835c3..e04328c 100644 --- a/weldx_widgets/widget_evaluate.py +++ b/weldx_widgets/widget_evaluate.py @@ -157,7 +157,7 @@ def make_output(): spatial_data_geo_reduced, "workpiece geometry (reduced)", "workpiece" ) - with tabs[("CSM-Subsystems")]: + with tabs["CSM-Subsystems"]: csm.plot_graph() plt.show() self._show_csm_subsystems(csm) @@ -228,7 +228,7 @@ def _show_csm_subsystems(csm): subsystems = csm.subsystems if not subsystems: return - print(csm.subsystem_names) + print(csm.subsystem_names) # noqa: T201 fig, ax = plt.subplots(ncols=len(subsystems)) for i, subsystem in enumerate(subsystems): subsystem.plot_graph(ax=ax[i]) diff --git a/weldx_widgets/widget_gas.py b/weldx_widgets/widget_gas.py index eeeef15..a9533b4 100644 --- a/weldx_widgets/widget_gas.py +++ b/weldx_widgets/widget_gas.py @@ -102,9 +102,7 @@ def _check(self, value): gas_components = self.to_tree()["gas_component"] if not sum(g.gas_percentage for g in gas_components) == 100: with self.out: - print( - "Check percentages, all components should sum up to 100!" - ) # , file=sys.stderr) + print("Check percentages, all components should sum up to 100!") # noqa: T201 else: # remove output, if everything is alright. self.out.clear_output() diff --git a/weldx_widgets/widget_groove_sel.py b/weldx_widgets/widget_groove_sel.py index a27f6b5..56904d3 100644 --- a/weldx_widgets/widget_groove_sel.py +++ b/weldx_widgets/widget_groove_sel.py @@ -51,8 +51,9 @@ class WidgetCADExport(WidgetMyVBox): does nothing. """ - data_formats = [ # ".stl", # FIXME: for some reason there is a div by zero error in meshio - ".ply" + data_formats = [ + ".ply", + # ".stl", # FIXME: for some reason there is a div by zero error in meshio ] # same groove is fine in ply format... """ example trace for a simple vgroove: meshio/stl/_stl.py in write(filename, mesh, binary) @@ -66,7 +67,7 @@ class WidgetCADExport(WidgetMyVBox): """ def __init__(self): - title = make_title(("Export geometry to CAD file [optional]"), heading_level=4) + title = make_title("Export geometry to CAD file [optional]", heading_level=4) # if the format changes, we have to update the file_pattern mask # of the chooser of the save widget. @@ -74,9 +75,9 @@ def __init__(self): self.format = Dropdown( options=WidgetCADExport.data_formats, index=default_format_index, - description=("Data format"), + description="Data format", ) - self.create_btn = Button(description=("Create program")) + self.create_btn = Button(description="Create program") self.geometry = None # disable button initially, because we first need to have a geometry self.create_btn.disabled = True @@ -87,13 +88,13 @@ def __init__(self): self._html_dl_button = HTML() self.profile_raster_width = FloatWithUnit( - ("Profile raster width"), + "Profile raster width", value=2, unit="mm", # tooltip="Target distance between the individual points of a profile", ) self.trace_raster_width = FloatWithUnit( - ("Trace raster width"), + "Trace raster width", value=30, unit="mm", # tooltip="Target distance between the individual profiles on the trace", @@ -120,7 +121,7 @@ def geometry(self, value): if value is not None: self.create_btn.disabled = False - def _on_export_geometry(self, *args): + def _on_export_geometry(self, *_): if self.geometry is None: return ext = self.format.value @@ -140,7 +141,7 @@ def _on_export_geometry(self, *args): # read and embed in HTML button. ntf.seek(0) download_button( - button_description=("Download program"), + button_description="Download program", filename=f"specimen{ext}", html_instance=self._html_dl_button, content=ntf.read(), @@ -151,11 +152,11 @@ class WidgetMetal(WidgetMyVBox): """Widget to select metal type and parameters.""" def __init__(self): - self.common_name = WidgetLabeledTextInput(("Common name"), "S355J2+N") - self.standard = WidgetLabeledTextInput(("Standard"), "DIN EN 10225-2:2011") - self.thickness = FloatWithUnit(("Thickness"), value=30, unit="mm") + self.common_name = WidgetLabeledTextInput("Common name", "S355J2+N") + self.standard = WidgetLabeledTextInput("Standard", "DIN EN 10225-2:2011") + self.thickness = FloatWithUnit("Thickness", value=30, unit="mm") children = [ - make_title(("Base metal"), heading_level=4), + make_title("Base metal", heading_level=4), self.common_name, self.standard, self.thickness, @@ -216,7 +217,7 @@ def __init__(self): [ WidgetMyHBox( [ - Label(("Groove type"), layout=description_layout), + Label("Groove type", layout=description_layout), self.groove_type_dropdown, ] ), @@ -229,9 +230,9 @@ def __init__(self): self.output_tabs = Tab() self.output_tabs.layout = Layout(width="70%") self.output_tabs.children = [self.out] - self.output_tabs.set_title(0, "2D " + ("profile")) + self.output_tabs.set_title(0, "2D profile") children = [ - make_title(("ISO 9692-1 Groove selection"), 3), + make_title("ISO 9692-1 Groove selection", 3), WidgetMyHBox(children=[self.groove_selection, self.output_tabs]), ] @@ -317,7 +318,7 @@ def _create_groove_dropdown(self): layout=description_layout, ) param_widgets[item] = HBox( - [Label(("Code number"), layout=description_layout), dropdown] + [Label("Code number", layout=description_layout), dropdown] ) else: # replace underscores with spaces, first letter uppercase, translate. @@ -366,7 +367,7 @@ def _update_plot(self, *args): groove_params = dict(groove_type=groove_type) for child in self.groove_params.children: param_key = child.mapping - if param_key == ("code_number"): + if param_key == "code_number": groove_params[param_key] = child.children[1].value else: magnitude = child.children[1].value @@ -409,7 +410,7 @@ def __init__(self): self.last_plot: Optional[CoordinateSystemManagerVisualizerK3D] = None self.groove_sel = WidgetGrooveSelection() - self.seam_length = FloatWithUnit(("Seam length"), value=300, min=0, unit="mm") + self.seam_length = FloatWithUnit("Seam length", value=300, min=0, unit="mm") self.seam_length.observe_float_value(self.create_csm_and_plot) self.seam_length.observe_unit(self.create_csm_and_plot) @@ -417,11 +418,11 @@ def __init__(self): self.tcp_z = FloatWithUnit("TCP-z", unit="mm") # TODO: compute weld speed accordingly to chosen groove area! # TODO: consider setting it read-only?? - self.weld_speed = FloatWithUnit(("weld speed"), value=6, unit="mm/s") + self.weld_speed = FloatWithUnit("weld speed", value=6, unit="mm/s") self.base_metal = WidgetMetal() self.geometry_export = WidgetCADExport() self.additional_params = ( - make_title(("Welding parameters"), 4), + make_title("Welding parameters", 4), self.seam_length, self.weld_speed, self.tcp_y, @@ -434,7 +435,7 @@ def __init__(self): # add 3d plot and CAD export to groove_sel output tab self.out = Output() self.groove_sel.output_tabs.children += (self.out, self.geometry_export) - self.groove_sel.output_tabs.set_title(1, "3D " + ("profile")) + self.groove_sel.output_tabs.set_title(1, "3D profile") self.groove_sel.output_tabs.set_title(2, "CAD export") self.groove_sel.output_tabs.observe( From 4f79c642023a3165546e1c29257ff9edf92ef69c Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Thu, 14 Dec 2023 11:01:51 +0100 Subject: [PATCH 33/40] [pytest] re-enable coverage recording --- pyproject.toml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 57eec8a..95a4063 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -67,11 +67,8 @@ write_to_template = '__version__ = "{version}"' where = ["."] [tool.pytest.ini_options] -addopts = "--tb=short --color=yes -rsw --doctest-modules" +addopts = "--tb=short --color=yes -rsw --doctest-modules --cov=weldx_widgets" testpaths = "weldx_widgets/tests" -norecursedirs = [ - ".ipynb_checkpoints", -] filterwarnings = [ "ignore::DeprecationWarning:traittypes.*:", "ignore:Passing method to :FutureWarning:xarray.*:", From ed80ef5e818e882f6cb2a72f02783cc6c41e7b08 Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Thu, 14 Dec 2023 11:12:28 +0100 Subject: [PATCH 34/40] avoid attaching unit twice --- weldx_widgets/visualization/csm_k3d.py | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/weldx_widgets/visualization/csm_k3d.py b/weldx_widgets/visualization/csm_k3d.py index 5e121a7..6b1c7ad 100644 --- a/weldx_widgets/visualization/csm_k3d.py +++ b/weldx_widgets/visualization/csm_k3d.py @@ -276,14 +276,10 @@ def update_time_index(self, index: int): def limits(self): lcs = self._lcs dims = [d for d in lcs.coordinates.dims if d != "c"] - with warnings.catch_warnings(): - warnings.filterwarnings("ignore", category=pint.errors.UnitStrippedWarning) - if dims: - # unit gets stripped during min/max reduction, so restore it. - unit = lcs.coordinates.data.u - mins = lcs.coordinates.min(dim=dims).data - maxs = lcs.coordinates.max(dim=dims).data - return np.vstack([mins, maxs]) * unit + if dims: + mins = lcs.coordinates.min(dim=dims).data + maxs = lcs.coordinates.max(dim=dims).data + return np.vstack([mins, maxs]) return np.vstack([lcs.coordinates.data, lcs.coordinates.data]) @@ -688,6 +684,15 @@ def _get_limits_spatial(self): """Get the limits of all spatial data.""" if not self._data_vis: return None + # + # def get_lim(x): + # with warnings.catch_warnings(): + # warnings.simplefilter("ignore", category=pint.errors.UnitStrippedWarning) + # u = getattr(x, "unit", 1) + # return x.limits() * u + # + # limits = np.stack([get_lim(s.data) for s in self._data_vis.values()]) + limits = np.stack([s.data.limits() for s in self._data_vis.values()]) return _get_limits_from_stack(limits) From 31e2fb46baf56d94c964b9c30006bcfa1aebeee1 Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Thu, 14 Dec 2023 11:21:30 +0100 Subject: [PATCH 35/40] f --- weldx_widgets/visualization/csm_k3d.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/weldx_widgets/visualization/csm_k3d.py b/weldx_widgets/visualization/csm_k3d.py index 6b1c7ad..0f59eb6 100644 --- a/weldx_widgets/visualization/csm_k3d.py +++ b/weldx_widgets/visualization/csm_k3d.py @@ -2,7 +2,6 @@ from __future__ import annotations -import warnings from typing import TYPE_CHECKING, Union import k3d @@ -684,14 +683,6 @@ def _get_limits_spatial(self): """Get the limits of all spatial data.""" if not self._data_vis: return None - # - # def get_lim(x): - # with warnings.catch_warnings(): - # warnings.simplefilter("ignore", category=pint.errors.UnitStrippedWarning) - # u = getattr(x, "unit", 1) - # return x.limits() * u - # - # limits = np.stack([get_lim(s.data) for s in self._data_vis.values()]) limits = np.stack([s.data.limits() for s in self._data_vis.values()]) return _get_limits_from_stack(limits) From a743378d6a49e40d2856ce661063d667dd541d9f Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Thu, 14 Dec 2023 11:27:00 +0100 Subject: [PATCH 36/40] removed unused abstract methods in import/export interface --- weldx_widgets/generic.py | 5 ----- weldx_widgets/widget_base.py | 13 ------------- weldx_widgets/widget_gmaw.py | 5 ----- weldx_widgets/widget_groove_sel.py | 5 ----- 4 files changed, 28 deletions(-) diff --git a/weldx_widgets/generic.py b/weldx_widgets/generic.py index 9dc7749..a548fe0 100644 --- a/weldx_widgets/generic.py +++ b/weldx_widgets/generic.py @@ -88,11 +88,6 @@ def path(self): class WidgetTimeSeries(WidgetMyVBox, WeldxImportExport): """Preliminary time series editing widget.""" - @property - def schema(self) -> str: - """Return schema to validate data against.""" - return "time_series" - # TODO: handle math-expr def __init__( self, base_unit, time_unit="s", base_data="0", time_data="0", title="" diff --git a/weldx_widgets/widget_base.py b/weldx_widgets/widget_base.py index de415ea..f3eb608 100644 --- a/weldx_widgets/widget_base.py +++ b/weldx_widgets/widget_base.py @@ -125,12 +125,6 @@ def __exit__(self, exc_type, exc_val, exc_tb): class WeldxImportExport(abc.ABC): """Abstract import and export interfaces for weldx data exchange.""" - @property - @abc.abstractmethod - def schema(self) -> str: - """Return a schema name is used to validate input and output.""" - pass - @staticmethod @functools.lru_cache def _get_schema_path(schema) -> Path: @@ -140,17 +134,10 @@ def get_schema_path(self) -> Path: """Resolve the actual schema to a path.""" return WeldxImportExport._get_schema_path(self.schema) - def validate(self, tree): - """Validate given tree against schema of this class.""" - # should be implemented such that we can validate both input and output. - return - @abc.abstractmethod def from_tree(self, tree: dict): """Fill the widget with given state dictionary.""" - pass @abc.abstractmethod def to_tree(self) -> dict: """Return a dict containing data from widget.""" - pass diff --git a/weldx_widgets/widget_gmaw.py b/weldx_widgets/widget_gmaw.py index 8b1fac0..d6199aa 100644 --- a/weldx_widgets/widget_gmaw.py +++ b/weldx_widgets/widget_gmaw.py @@ -270,11 +270,6 @@ def _set_gui_mapping(self): } ) - @property - def schema(self) -> str: - """Return schema.""" - raise - def __init__(self, process_type="spray"): self._set_gui_mapping() # set up translation mapping. index = list(self.translate.values()).index(process_type) diff --git a/weldx_widgets/widget_groove_sel.py b/weldx_widgets/widget_groove_sel.py index 56904d3..ffc18c4 100644 --- a/weldx_widgets/widget_groove_sel.py +++ b/weldx_widgets/widget_groove_sel.py @@ -266,11 +266,6 @@ def groove_obj(self, value: IsoBaseGroove): widget.quantity = v - @property - def schema(self) -> str: - """Return schema.""" - raise NotImplementedError - def from_tree(self, tree: dict): """Fill widget from tree.""" self.groove_obj = tree["groove_shape"] From ed1d0f3ee1da07c2c5ba6f456dab443de864eb99 Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Thu, 14 Dec 2023 11:34:39 +0100 Subject: [PATCH 37/40] renamed FloatWithUnit -> WidgetFloatWithUnit --- weldx_widgets/__init__.py | 4 ++-- weldx_widgets/widget_base.py | 9 --------- weldx_widgets/widget_factory.py | 2 +- weldx_widgets/widget_gas.py | 4 ++-- weldx_widgets/widget_gmaw.py | 20 ++++++++++---------- weldx_widgets/widget_groove_sel.py | 24 ++++++++++++------------ 6 files changed, 27 insertions(+), 36 deletions(-) diff --git a/weldx_widgets/__init__.py b/weldx_widgets/__init__.py index 13f5c2e..80ef810 100644 --- a/weldx_widgets/__init__.py +++ b/weldx_widgets/__init__.py @@ -1,6 +1,6 @@ """Weldx widgets.""" from .generic import WidgetSaveButton, WidgetTimeSeries -from .widget_factory import FloatWithUnit, WidgetLabeledTextInput +from .widget_factory import WidgetFloatWithUnit, WidgetLabeledTextInput from .widget_gas import WidgetShieldingGas from .widget_gmaw import WidgetGMAW from .widget_groove_sel import WidgetGrooveSelection, WidgetGrooveSelectionTCPMovement @@ -13,7 +13,7 @@ WidgetLabeledTextInput, WidgetSaveButton, WidgetGMAW, - FloatWithUnit, # TODO: rename + WidgetFloatWithUnit, ] __all__ = map(str, (x.__name__ for x in __all__)) diff --git a/weldx_widgets/widget_base.py b/weldx_widgets/widget_base.py index f3eb608..168693f 100644 --- a/weldx_widgets/widget_base.py +++ b/weldx_widgets/widget_base.py @@ -125,15 +125,6 @@ def __exit__(self, exc_type, exc_val, exc_tb): class WeldxImportExport(abc.ABC): """Abstract import and export interfaces for weldx data exchange.""" - @staticmethod - @functools.lru_cache - def _get_schema_path(schema) -> Path: - return get_schema_path(schema) - - def get_schema_path(self) -> Path: - """Resolve the actual schema to a path.""" - return WeldxImportExport._get_schema_path(self.schema) - @abc.abstractmethod def from_tree(self, tree: dict): """Fill the widget with given state dictionary.""" diff --git a/weldx_widgets/widget_factory.py b/weldx_widgets/widget_factory.py index 217f0fd..8ed3224 100644 --- a/weldx_widgets/widget_factory.py +++ b/weldx_widgets/widget_factory.py @@ -60,7 +60,7 @@ def text_value(self, value): self.text.value = value -class FloatWithUnit(WidgetMyHBox): +class WidgetFloatWithUnit(WidgetMyHBox): """Widget grouping a float with unit.""" def __init__(self, text, unit, value: float = 0.0, min=0): diff --git a/weldx_widgets/widget_gas.py b/weldx_widgets/widget_gas.py index a9533b4..b6ef176 100644 --- a/weldx_widgets/widget_gas.py +++ b/weldx_widgets/widget_gas.py @@ -8,7 +8,7 @@ from weldx.tags.aws import GasComponent, ShieldingGasForProcedure, ShieldingGasType from weldx_widgets.widget_base import WidgetMyVBox from weldx_widgets.widget_factory import ( - FloatWithUnit, + WidgetFloatWithUnit, button_layout, description_layout, ) @@ -140,7 +140,7 @@ class WidgetShieldingGas(WidgetMyVBox): # TODO: this could in principle be used multiple times for all positions # e.g. torch, trailing, backing def __init__(self, position="torch"): - self.flowrate = FloatWithUnit("Flow rate", "l/min", value=20) + self.flowrate = WidgetFloatWithUnit("Flow rate", "l/min", value=20) self.gas_components = WidgetSimpleGasSelection() children = [self.gas_components, self.flowrate] diff --git a/weldx_widgets/widget_gmaw.py b/weldx_widgets/widget_gmaw.py index d6199aa..95f8617 100644 --- a/weldx_widgets/widget_gmaw.py +++ b/weldx_widgets/widget_gmaw.py @@ -11,7 +11,7 @@ from weldx_widgets.generic import WidgetTimeSeries from weldx_widgets.widget_base import WeldxImportExport, WidgetMyVBox from weldx_widgets.widget_factory import ( - FloatWithUnit, + WidgetFloatWithUnit, WidgetLabeledTextInput, make_title, ) @@ -60,7 +60,7 @@ def __init__(self, tag: str, meta=None): self.manufacturer = WidgetLabeledTextInput("Manufacturer", "Fronius") self.power_source = WidgetLabeledTextInput("Power source", "TPS 500i") - self.wire_feedrate = FloatWithUnit( + self.wire_feedrate = WidgetFloatWithUnit( text="Wire feed rate", value=10, min=0, unit="m/min" ) children = [ @@ -98,14 +98,14 @@ class ProcessPulsed(WidgetMyVBox): """Widget for pulsed processes.""" def __init__(self, kind="UI"): - self.pulse_duration = FloatWithUnit("Pulse duration", value=5.0, unit="ms") - self.pulse_frequency = FloatWithUnit("Pulse frequency", value=100.0, unit="Hz") - self.base_current = FloatWithUnit("Base current", value=60.0, unit="A") + self.pulse_duration = WidgetFloatWithUnit("Pulse duration", value=5.0, unit="ms") + self.pulse_frequency = WidgetFloatWithUnit("Pulse frequency", value=100.0, unit="Hz") + self.base_current = WidgetFloatWithUnit("Base current", value=60.0, unit="A") if kind == "UI": - self.pulsed_dim = FloatWithUnit("Pulse voltage", "V", 40) + self.pulsed_dim = WidgetFloatWithUnit("Pulse voltage", "V", 40) elif kind == "II": - self.pulsed_dim = FloatWithUnit("Pulse current", "A", 300) + self.pulsed_dim = WidgetFloatWithUnit("Pulse current", "A", 300) else: raise ValueError(f"unknown kind: {kind}") self.kind = kind @@ -179,8 +179,8 @@ def __init__(self): self.voltage = WidgetTimeSeries( base_data="40.0, 20.0", base_unit="V", time_data="0.0, 10.0", time_unit="s" ) - self.impedance = FloatWithUnit(text="Impedance", value=10, unit="percent") - self.characteristic = FloatWithUnit("Characteristic", value=5, unit="V/A") + self.impedance = WidgetFloatWithUnit(text="Impedance", value=10, unit="percent") + self.characteristic = WidgetFloatWithUnit("Characteristic", value=5, unit="V/A") super().__init__( children=[ @@ -227,7 +227,7 @@ class WidgetWire(WidgetMyVBox): heading_level = 4 def __init__(self): - self.diameter = FloatWithUnit("Diameter", unit="mm", min=0, value=1.2) + self.diameter = WidgetFloatWithUnit("Diameter", unit="mm", min=0, value=1.2) self.wire_class = WidgetLabeledTextInput("Class", "G 42 2 C/M G4Si1") # TODO: consider a tree like editing widget for metadata. diff --git a/weldx_widgets/widget_groove_sel.py b/weldx_widgets/widget_groove_sel.py index ffc18c4..ed5af80 100644 --- a/weldx_widgets/widget_groove_sel.py +++ b/weldx_widgets/widget_groove_sel.py @@ -25,7 +25,7 @@ from weldx_widgets.generic import download_button from weldx_widgets.widget_base import WeldxImportExport, WidgetMyHBox, WidgetMyVBox from weldx_widgets.widget_factory import ( - FloatWithUnit, + WidgetFloatWithUnit, WidgetLabeledTextInput, description_layout, make_title, @@ -87,13 +87,13 @@ def __init__(self): # program directly to his/her computer. self._html_dl_button = HTML() - self.profile_raster_width = FloatWithUnit( + self.profile_raster_width = WidgetFloatWithUnit( "Profile raster width", value=2, unit="mm", # tooltip="Target distance between the individual points of a profile", ) - self.trace_raster_width = FloatWithUnit( + self.trace_raster_width = WidgetFloatWithUnit( "Trace raster width", value=30, unit="mm", @@ -154,7 +154,7 @@ class WidgetMetal(WidgetMyVBox): def __init__(self): self.common_name = WidgetLabeledTextInput("Common name", "S355J2+N") self.standard = WidgetLabeledTextInput("Standard", "DIN EN 10225-2:2011") - self.thickness = FloatWithUnit("Thickness", value=30, unit="mm") + self.thickness = WidgetFloatWithUnit("Thickness", value=30, unit="mm") children = [ make_title("Base metal", heading_level=4), self.common_name, @@ -261,7 +261,7 @@ def groove_obj(self, value: IsoBaseGroove): with contextlib.ExitStack() as stack: for k, v in self.groove_obj.parameters().items(): mapped_k = self._groove_obj._mapping[k] - widget: FloatWithUnit = gui_params[mapped_k] + widget: WidgetFloatWithUnit = gui_params[mapped_k] stack.enter_context(widget.silence_events()) widget.quantity = v @@ -326,11 +326,11 @@ def _create_groove_dropdown(self): else: text = t if "angle" in item: - param_widgets[item] = FloatWithUnit(text=text, unit="°", value=45) + param_widgets[item] = WidgetFloatWithUnit(text=text, unit="°", value=45) elif "workpiece_thickness" in item: - param_widgets[item] = FloatWithUnit(text=text, unit="mm", value=15) + param_widgets[item] = WidgetFloatWithUnit(text=text, unit="mm", value=15) else: - param_widgets[item] = FloatWithUnit(text=text, unit="mm", value=5) + param_widgets[item] = WidgetFloatWithUnit(text=text, unit="mm", value=5) param_widgets[item].mapping = item groove_list = list(_groove_name_to_type.keys()) @@ -405,15 +405,15 @@ def __init__(self): self.last_plot: Optional[CoordinateSystemManagerVisualizerK3D] = None self.groove_sel = WidgetGrooveSelection() - self.seam_length = FloatWithUnit("Seam length", value=300, min=0, unit="mm") + self.seam_length = WidgetFloatWithUnit("Seam length", value=300, min=0, unit="mm") self.seam_length.observe_float_value(self.create_csm_and_plot) self.seam_length.observe_unit(self.create_csm_and_plot) - self.tcp_y = FloatWithUnit("TCP-y", unit="mm") - self.tcp_z = FloatWithUnit("TCP-z", unit="mm") + self.tcp_y = WidgetFloatWithUnit("TCP-y", unit="mm") + self.tcp_z = WidgetFloatWithUnit("TCP-z", unit="mm") # TODO: compute weld speed accordingly to chosen groove area! # TODO: consider setting it read-only?? - self.weld_speed = FloatWithUnit("weld speed", value=6, unit="mm/s") + self.weld_speed = WidgetFloatWithUnit("weld speed", value=6, unit="mm/s") self.base_metal = WidgetMetal() self.geometry_export = WidgetCADExport() self.additional_params = ( From 313a17b58a195b219a6c3ad7b0440d7ea6233279 Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Thu, 14 Dec 2023 11:39:49 +0100 Subject: [PATCH 38/40] reformat --- weldx_widgets/widget_base.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/weldx_widgets/widget_base.py b/weldx_widgets/widget_base.py index 168693f..b9f4572 100644 --- a/weldx_widgets/widget_base.py +++ b/weldx_widgets/widget_base.py @@ -1,12 +1,8 @@ """Base classes for widgets.""" import abc -import functools -from pathlib import Path from ipywidgets import HBox, Layout, Output, VBox -from weldx.asdf.util import get_schema_path - def metaclass_resolver(*classes): """Merge multiple meta classes.""" From 1b5188ebf16cdce6e11ff4b5036710e5ec26fd87 Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Thu, 14 Dec 2023 11:40:09 +0100 Subject: [PATCH 39/40] format --- weldx_widgets/widget_gas.py | 4 +++- weldx_widgets/widget_gmaw.py | 8 ++++++-- weldx_widgets/widget_groove_sel.py | 16 ++++++++++++---- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/weldx_widgets/widget_gas.py b/weldx_widgets/widget_gas.py index b6ef176..7b686b3 100644 --- a/weldx_widgets/widget_gas.py +++ b/weldx_widgets/widget_gas.py @@ -102,7 +102,9 @@ def _check(self, value): gas_components = self.to_tree()["gas_component"] if not sum(g.gas_percentage for g in gas_components) == 100: with self.out: - print("Check percentages, all components should sum up to 100!") # noqa: T201 + print( + "Check percentages, all components should sum up to 100!" + ) # noqa: T201 else: # remove output, if everything is alright. self.out.clear_output() diff --git a/weldx_widgets/widget_gmaw.py b/weldx_widgets/widget_gmaw.py index 95f8617..663d694 100644 --- a/weldx_widgets/widget_gmaw.py +++ b/weldx_widgets/widget_gmaw.py @@ -98,8 +98,12 @@ class ProcessPulsed(WidgetMyVBox): """Widget for pulsed processes.""" def __init__(self, kind="UI"): - self.pulse_duration = WidgetFloatWithUnit("Pulse duration", value=5.0, unit="ms") - self.pulse_frequency = WidgetFloatWithUnit("Pulse frequency", value=100.0, unit="Hz") + self.pulse_duration = WidgetFloatWithUnit( + "Pulse duration", value=5.0, unit="ms" + ) + self.pulse_frequency = WidgetFloatWithUnit( + "Pulse frequency", value=100.0, unit="Hz" + ) self.base_current = WidgetFloatWithUnit("Base current", value=60.0, unit="A") if kind == "UI": diff --git a/weldx_widgets/widget_groove_sel.py b/weldx_widgets/widget_groove_sel.py index ed5af80..8d91631 100644 --- a/weldx_widgets/widget_groove_sel.py +++ b/weldx_widgets/widget_groove_sel.py @@ -326,11 +326,17 @@ def _create_groove_dropdown(self): else: text = t if "angle" in item: - param_widgets[item] = WidgetFloatWithUnit(text=text, unit="°", value=45) + param_widgets[item] = WidgetFloatWithUnit( + text=text, unit="°", value=45 + ) elif "workpiece_thickness" in item: - param_widgets[item] = WidgetFloatWithUnit(text=text, unit="mm", value=15) + param_widgets[item] = WidgetFloatWithUnit( + text=text, unit="mm", value=15 + ) else: - param_widgets[item] = WidgetFloatWithUnit(text=text, unit="mm", value=5) + param_widgets[item] = WidgetFloatWithUnit( + text=text, unit="mm", value=5 + ) param_widgets[item].mapping = item groove_list = list(_groove_name_to_type.keys()) @@ -405,7 +411,9 @@ def __init__(self): self.last_plot: Optional[CoordinateSystemManagerVisualizerK3D] = None self.groove_sel = WidgetGrooveSelection() - self.seam_length = WidgetFloatWithUnit("Seam length", value=300, min=0, unit="mm") + self.seam_length = WidgetFloatWithUnit( + "Seam length", value=300, min=0, unit="mm" + ) self.seam_length.observe_float_value(self.create_csm_and_plot) self.seam_length.observe_unit(self.create_csm_and_plot) From 1efcc7d67c5977935fa88f37543632ea65324c24 Mon Sep 17 00:00:00 2001 From: "Martin K. Scherer" Date: Thu, 14 Dec 2023 11:41:13 +0100 Subject: [PATCH 40/40] ff --- weldx_widgets/widget_gas.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/weldx_widgets/widget_gas.py b/weldx_widgets/widget_gas.py index 7b686b3..b6ef176 100644 --- a/weldx_widgets/widget_gas.py +++ b/weldx_widgets/widget_gas.py @@ -102,9 +102,7 @@ def _check(self, value): gas_components = self.to_tree()["gas_component"] if not sum(g.gas_percentage for g in gas_components) == 100: with self.out: - print( - "Check percentages, all components should sum up to 100!" - ) # noqa: T201 + print("Check percentages, all components should sum up to 100!") # noqa: T201 else: # remove output, if everything is alright. self.out.clear_output()