diff --git a/.github/workflows/on-pr-close.yml b/.github/workflows/on-pr-close.yml index cd70cdd9c..40b1e8377 100644 --- a/.github/workflows/on-pr-close.yml +++ b/.github/workflows/on-pr-close.yml @@ -18,6 +18,15 @@ on: - closed jobs: + label_pr_closed: + runs-on: ubuntu-latest + steps: + - name: Add in progress label + uses: andymckay/labeler@master + with: + add-labels: "status: closed" + remove-labels: "status: inprogress" + tag-version: name: Push Version Tag runs-on: ubuntu-latest diff --git a/Makefile b/Makefile index 4e1b3571d..94021cfa0 100644 --- a/Makefile +++ b/Makefile @@ -264,7 +264,7 @@ coverage: clean-test # This target is for use with IDE integration. format: @echo -e "\n\t\033[1;32mAutoformatting $(SRCFILE) ...\033[0m\n" - $(BLACK) $(SRCFILE) + $(BLACK) --fast $(SRCFILE) $(ISORT) $(ISORT_ARGS) $(SRCFILE) $(DOCFORMATTER) $(DOCFORMATTER_ARGS) $(SRCFILE) diff --git a/data/RAMSTK.toml b/data/RAMSTK.toml index 624fdeefd..2d8c406d2 100644 --- a/data/RAMSTK.toml +++ b/data/RAMSTK.toml @@ -67,13 +67,376 @@ validationbg = "#FFFFFF" validationfg = "#000000" [stress] -integratedcircuit = [ 0.8, 0.9, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 125.0, 125.0,] -semiconductor = [ 1.0, 1.0, 0.7, 0.9, 1.0, 1.0, 0.0, 0.0, 125.0, 125.0,] -resistor = [ 1.0, 1.0, 0.5, 0.9, 1.0, 1.0, 0.0, 0.0, 125.0, 125.0,] -capacitor = [ 1.0, 1.0, 1.0, 1.0, 0.6, 0.9, 10.0, 0.0, 125.0, 125.0,] -inductor = [ 0.6, 0.9, 1.0, 1.0, 0.5, 0.9, 15.0, 0.0, 125.0, 125.0,] -relay = [ 0.75, 0.9, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 125.0, 125.0,] -switch = [ 0.75, 0.9, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 125.0, 125.0,] -connection = [ 0.7, 0.9, 1.0, 1.0, 0.7, 0.9, 25.0, 0.0, 125.0, 125.0,] -meter = [ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 125.0, 125.0,] -miscellaneous = [ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 125.0, 125.0,] + # Derating values for hermetically packaged ICs. + [stress.integrated_circuit.digital.mos.hermetic] + current = [0.9, 0.85, 0.8] # Output current. + fanout = [1.0, 0.9, 0.9] # Percent of gates that can be driven. + frequency = [0.9, 0.9, 0.9] # Clocking frequency. + temperature = [125.0, 110.0, 100.0] # Junction temperature + # Derating values for heat dissipating plastic packaged ICs. + [stress.integrated_circuit.digital.mos.plastic1] + current = [0.9, 0.8, 0.0] + fanout = [1.0, 0.9, 0.0] + frequency = [0.9, 0.8, 0.0] + temperature = [90.0, 85.0, 0.0] + # Derating values for non-heat dissipating plastic packaged ICs. + [stress.integrated_circuit.digital.mos.plastic2] + current = [0.7, 0.0, 0.0] + fanout = [0.8, 0.0, 0.0] + frequency = [0.8, 0.0, 0.0] + temperature = [70.0, 0.0, 0.0] + [stress.integrated_circuit.digital.bipolar.hermetic] + current = [0.9, 0.85, 0.8] + fanout = [0.9, 0.85, 0.8] + frequency = [1.0, 0.9, 0.85] + temperature = [125.0, 110.0, 100.0] + [stress.integrated_circuit.digital.bipolar.plastic1] + current = [0.9, 0.8, 0.0] + fanout = [0.9, 0.8, 0.0] + frequency = [1.0, 0.9, 0.0] + temperature = [90.0, 85.0, 0.0] + [stress.integrated_circuit.digital.bipolar.plastic2] + current = [0.7, 0.0, 0.0] + fanout = [0.7, 0.0, 0.0] + frequency = [0.75, 0.0, 0.0] + temperature = [70.0, 0.0, 0.0] + [stress.integrated_circuit.linear.mos.hermetic] + current = [0.9, 0.85, 0.8] + fanout = [1.0, 0.9, 0.9] + frequency = [0.9, 0.9, 0.9] + temperature = [125.0, 110.0, 100.0] + voltage = [0.8, 0.8, 0.7] # Input voltage. + [stress.integrated_circuit.linear.mos.plastic1] + current = [0.9, 0.8, 0.0] + fanout = [1.0, 0.9, 0.0] + frequency = [0.9, 0.8, 0.0] + temperature = [90.0, 85.0, 0.0] + voltage = [0.8, 0.7, 0.0] + [stress.integrated_circuit.linear.mos.plastic2] + current = [0.7, 0.0, 0.0] + fanout = [0.8, 0.0, 0.0] + frequency = [0.8, 0.0, 0.0] + temperature = [70.0, 0.0, 0.0] + voltage = [0.6, 0.0, 0.0] + [stress.integrated_circuit.linear.bipolar.hermetic] + current = [0.9, 0.85, 0.8] + fanout = [0.9, 0.85, 0.8] + frequency = [1.0, 0.9, 0.85] + temperature = [125.0, 110.0, 100.0] + voltage =[0.8, 0.8, 0.7] + [stress.integrated_circuit.linear.bipolar.plastic1] + current = [0.9, 0.8, 0.0] + fanout = [0.9, 0.8, 0.0] + frequency = [1.0, 0.9, 0.0] + temperature = [90.0, 85.0, 0.0] + voltage =[0.8, 0.7, 0.0] + [stress.integrated_circuit.linear.bipolar.plastic2] + current = [0.7, 0.0, 0.0] + fanout = [0.7, 0.0, 0.0] + frequency = [0.75, 0.0, 0.0] + temperature = [70.0, 0.0, 0.0] + voltage =[0.6, 0.0, 0.0] + [stress.integrated_circuit.microprocessor.mos.hermetic] + current = [0.9, 0.85, 0.8] + fanout = [1.0, 0.9, 0.9] + frequency = [0.9, 0.9, 0.9] + temperature = [125.0, 110.0, 100.0] + [stress.integrated_circuit.microprocessor.mos.plastic1] + current = [0.9, 0.8, 0.0] + fanout = [1.0, 0.85, 0.0] + frequency = [0.9, 0.8, 0.0] + temperature = [85.0, 75.0, 0.0] + [stress.integrated_circuit.microprocessor.mos.plastic2] + current = [0.7, 0.0, 0.0] + fanout = [0.8, 0.0, 0.0] + frequency = [0.8, 0.0, 0.0] + temperature = [70.0, 0.0, 0.0] + [stress.integrated_circuit.microprocessor.bipolar.hermetic] + current = [0.8, 0.75, 0.7] + fanout = [0.8, 0.75, 0.7] + frequency = [0.9, 0.8, 0.75] + temperature = [125.0, 110.0, 100.0] + [stress.integrated_circuit.microprocessor.bipolar.plastic1] + current = [0.8, 0.75, 0.0] + fanout = [0.8, 0.75, 0.0] + frequency = [0.9, 0.8, 0.0] + temperature = [85.0, 75.0, 0.0] + [stress.integrated_circuit.microprocessor.bipolar.plastic2] + current = [0.7, 0.0, 0.0] + fanout = [0.7, 0.0, 0.0] + frequency = [0.75, 0.0, 0.0] + temperature = [70.0, 0.0, 0.0] + [stress.integrated_circuit.memory.mos.hermetic] + current = [0.9, 0.85, 0.8] + frequency = [1.0, 0.9, 0.9] + temperature = [125.0, 110.0, 100.0] + [stress.integrated_circuit.memory.mos.plastic1] + current = [0.9, 0.8, 0.0] + frequency = [1.0, 0.9, 0.0] + temperature = [90.0, 85.0, 0.0] + [stress.integrated_circuit.memory.mos.plastic2] + current = [0.7, 0.0, 0.0] + frequency = [0.8, 0.0, 0.0] + temperature = [70.0, 0.0, 0.0] + [stress.integrated_circuit.memory.bipolar.hermetic] + current = [0.9, 0.85, 0.8] + frequency = [1.0, 1.0, 0.9] + temperature = [125.0, 110.0, 100.0] + [stress.integrated_circuit.memory.bipolar.plastic1] + current = [0.9, 0.8, 0.0] + frequency = [1.0, 0.95, 0.0] + temperature = [90.0, 85.0, 0.0] + [stress.integrated_circuit.memory.bipolar.plastic2] + current = [0.7, 0.0, 0.0] + frequency = [0.8, 0.0, 0.0] + temperature = [70.0, 0.0, 0.0] + [stress.semiconductor.diode.general_purpose.jantx] + current = [1.0, 1.0, 1.0] # Forward current. + surge_current = [1.0, 0.9, 0.8] + voltage = [0.95, 0.9, 0.85] # Reverse voltage. + temperature = [150.0, 125.0, 125.0] # Junction temperature, maximum. + [stress.semiconductor.diode.general_purpose.military] + current = [0.9, 0.9, 0.7] + surge_current = [0.8, 0.8, 0.5] + voltage = [0.8, 0.75, 0.5] + temperature = [100.0, 85.0, 70.0] + [stress.semiconductor.diode.general_purpose.commercial] + current = [0.75, 0.7, 0.0] + surge_current = [0.6, 0.3, 0.0] + voltage = [0.7, 0.6, 0.0] + temperature = [70.0, 35.0, 0.0] + [stress.semiconductor.diode.power_rectifier.jantx] + current = [1.0, 1.0, 1.0] # Forward current. + voltage = [0.95, 0.9, 0.85] # Reverse voltage. + temperature = [150.0, 125.0, 125.0] # Junction temperature, maximum. + [stress.semiconductor.diode.power_rectifier.military] + current = [0.9, 0.85, 0.6] + voltage = [0.8, 0.75, 0.3] + temperature = [100.0, 85.0, 70.0] + [stress.semiconductor.diode.power_rectifier.commercial] + current = [0.6, 0.5, 0.0] + voltage = [0.5, 0.3, 0.0] + temperature = [70.0, 35.0, 0.0] + [stress.semiconductor.diode.schottky.jantx] + power = [1.0, 1.0, 0.9] + voltage = [0.95, 0.9, 0.85] # Reverse voltage. + temperature = [150.0, 125.0, 125.0] # Junction temperature, maximum. + [stress.semiconductor.diode.schottky.military] + power = [0.9, 0.9, 0.5] + voltage = [0.8, 0.8, 0.25] + temperature = [100.0, 85.0, 70.0] + [stress.semiconductor.diode.schottky.commercial] + power = [0.75, 0.75, 0.0] + voltage = [0.5, 0.3, 0.0] + temperature = [70.0, 35.0, 0.0] + [stress.semiconductor.diode.regulator.jantx] + power = [1.0, 1.0, 0.9] + temperature = [150.0, 125.0, 125.0] # Junction temperature, maximum. + [stress.semiconductor.diode.regulator.military] + power = [0.9, 0.8, 0.5] + temperature = [100.0, 85.0, 70.0] + [stress.semiconductor.diode.regulator.commercial] + power = [0.5, 0.5, 0.0] + temperature = [70.0, 35.0, 0.0] + [stress.semiconductor.diode.suppressor.jantx] + current = [1.0, 1.0, 0.9] # Average current. + power = [1.0, 1.0, 0.9] + temperature = [150.0, 125.0, 125.0] # Junction temperature, maximum. + [stress.semiconductor.diode.suppressor.military] + current = [0.8, 0.8, 0.5] + power = [0.8, 0.8, 0.5] + temperature = [100.0, 85.0, 70.0] + [stress.semiconductor.diode.suppressor.commercial] + current = [0.75, 0.5, 0.0] + power = [0.75, 0.5, 0.0] + temperature = [70.0, 35.0, 0.0] + [stress.semiconductor.thyristor.jantx] + current = [1.0, 1.0, 0.9] # On-state current. + temperature = [150.0, 125.0, 125.0] # Junction temperature, maximum. + voltage = [1.0, 1.0, 0.9] # Off-state voltage. + [stress.semiconductor.thyristor.military] + current = [0.9, 0.8, 0.5] + temperature = [100.0, 85.0, 70.0] + voltage = [0.9, 0.8, 0.5] + [stress.semiconductor.thyristor.commercial] + current = [0.6, 0.5, 0.0] + temperature = [70.0, 35.0, 0.0] + voltage = [0.6, 0.5, 0.0] + [stress.semiconductor.transistor.bjt.jantx] + current = [1.0, 0.9, 0.9] # Collector current. + power = [1.0, 1.0, 0.9] + temperature = [150.0, 125.0, 125.0] # Junction temperature, maximum. + voltage = [1.0, 0.9, 0.8] # Breakdown voltage. + [stress.semiconductor.transistor.bjt.military] + current = [0.9, 0.8, 0.6] + power = [0.9, 0.8, 0.6] + temperature = [100.0, 85.0, 70.0] + voltage = [0.8, 0.75, 0.3] + [stress.semiconductor.transistor.bjt.commercial] + current = [0.5, 0.5, 0.0] + power = [0.5, 0.5, 0.0] + temperature = [70.0, 35.0, 0.0] + voltage = [0.25, 0.25, 0.0] + [stress.semiconductor.transistor.fet.jantx] + power = [1.0, 1.0, 0.9] + temperature = [150.0, 125.0, 125.0] # Junction temperature, maximum. + voltage = [1.0, 0.95, 0.9] # Breakdown voltage. + [stress.semiconductor.transistor.fet.military] + power = [0.9, 0.8, 0.5] + temperature = [100.0, 85.0, 70.0] + voltage = [0.8, 0.75, 0.5] + [stress.semiconductor.transistor.fet.commercial] + power = [0.5, 0.5, 0.0] + temperature = [70.0, 35.0, 0.0] + voltage = [0.25, 0.25, 0.0] + [stress.resistor.fixed.film.chip.low_power] + power = [0.7, 0.7, 0.7] + temperature = [0.7, 0.7, 0.7] + [stress.resistor.fixed.film.chip.high_power] + power = [0.55, 0.55, 0.55] + temperature = [0.55, 0.55, 0.55] + [stress.resistor.fixed.film.general.low_power] + power = [0.65, 0.65, 0.65] + temperature = [0.65, 0.65, 0.65] + voltage = [0.7, 0.7, 0.7] + [stress.resistor.fixed.film.general.high_power] + power = [0.55, 0.55, 0.55] + temperature = [0.55, 0.55, 0.55] + voltage = [0.7, 0.7, 0.7] + [stress.resistor.fixed.film.power] + power = [0.55, 0.55, 0.55] + temperature = [0.55, 0.55, 0.55] + [stress.resistor.fixed.film.network] + power = [0.55, 0.55, 0.55] + temperature = [0.55, 0.55, 0.55] + voltage = [0.7, 0.7, 0.7] + [stress.resistor.fixed.wirewound.accurate.low_power] + power = [0.7, 0.7, 0.7] + temperature = [1.0, 1.0, 1.0] + voltage = [0.7, 0.7, 0.7] + [stress.resistor.fixed.wirewound.accurate.high_power] + power = [0.5, 0.5, 0.5] + temperature = [1.0, 1.0, 1.0] + voltage = [0.7, 0.7, 0.7] + [stress.resistor.fixed.wirewound.power] + power = [0.6, 0.6, 0.6] + temperature = [0.6, 0.6, 0.6] + voltage = [0.7, 0.7, 0.7] + [stress.resistor.fixed.wirewound.chassis] + power = [0.5, 0.5, 0.5] + temperature = [0.5, 0.5, 0.5] + voltage = [0.7, 0.7, 0.7] + [stress.resistor.variable.wirewound.general] + power = [0.55, 0.55, 0.55] + temperature = [0.55, 0.55, 0.55] + [stress.resistor.variable.wirewound.precision] + power = [0.55, 0.55, 0.55] + temperature = [0.55, 0.55, 0.55] + [stress.resistor.variable.wirewound.power] + power = [0.55, 0.55, 0.55] + temperature = [110.0, 110.0, 110.0] + [stress.resistor.variable.composition] + power = [0.5, 0.5, 0.5] + temperature = [0.5, 0.5, 0.5] + [stress.resistor.variable.film] + power = [0.5, 0.5, 0.5] + temperature = [0.5, 0.5, 0.5] + [stress.resistor.variable.precision] + power = [0.55, 0.55, 0.55] + temperature = [0.55, 0.55, 0.55] + [stress.capacitor.fixed.paper] + temperature = [10.0, 10.0, 10.0] + voltage = [0.55, 0.55, 0.55] # % maximum rated. + [stress.capacitor.fixed.plastic] + temperature = [10.0, 10.0, 10.0] + voltage = [0.55, 0.55, 0.55] + [stress.capacitor.fixed.metallized] + temperature = [10.0, 10.0, 10.0] + voltage = [0.55, 0.55, 0.55] + [stress.capacitor.fixed.mica] + temperature = [25.0, 25.0, 25.0] + voltage = [0.7, 0.7, 0.7] + [stress.capacitor.fixed.mica_button] + temperature = [10.0, 10.0, 10.0] + voltage = [0.55, 0.55, 0.55] + [stress.capacitor.fixed.glass] + temperature = [15.0, 15.0, 15.0] + voltage = [0.6, 0.6, 0.6] + [stress.capacitor.fixed.ceramic] + temperature = [15.0, 15.0, 15.0] + voltage = [0.6, 0.6, 0.6] + [stress.capacitor.fixed.temp_comp_ceramic] + temperature = [10.0, 10.0, 10.0] + voltage = [0.6, 0.6, 0.6] + [stress.capacitor.fixed.ceramic_chip] + temperature = [10.0, 10.0, 10.0] + voltage = [0.6, 0.6, 0.6] + [stress.capacitor.fixed.tantalum_chip] + temperature = [10.0, 10.0, 10.0] + voltage = [0.6, 0.6, 0.6] + [stress.capacitor.fixed.tantalum_solid] + reverse_voltage = [0.02, 0.02, 0.02] + temperature = [10.0, 10.0, 10.0] + voltage = [0.6, 0.6, 0.6] + [stress.capacitor.fixed.tantalum_wet] + reverse_voltage = [0.02, 0.02, 0.02] + temperature = [10.0, 10.0, 10.0] + voltage = [0.6, 0.6, 0.6] + [stress.capacitor.fixed.aluminum] + temperature = [10.0, 10.0, 10.0] + voltage = [0.7, 0.7, 0.7] + [stress.capacitor.fixed.aluminum_dry] + temperature = [10.0, 10.0, 10.0] + voltage = [0.7, 0.7, 0.7] + [stress.capacitor.variable.ceramic] + temperature = [10.0, 10.0, 10.0] + voltage = [0.6, 0.6, 0.6] + [stress.capacitor.variable.piston] + temperature = [15.0, 15.0, 15.0] + voltage = [0.6, 0.6, 0.6] + [stress.capacitor.variable.trimmer] + temperature = [10.0, 10.0, 10.0] + voltage = [0.6, 0.6, 0.6] + [stress.capacitor.variable.vacuum] + temperature = [10.0, 10.0, 10.0] + voltage = [0.6, 0.6, 0.6] + [stress.inductor.low_frequency] + current = [0.7, 0.7, 0.6] # Continuous current. + surge_current = [0.9, 0.9, 0.8] # Surge current. + surge_voltage = [0.9, 0.9, 0.8] # Surge voltage. + temperature = [30.0, 30.0, 30.0] # Hot spot temperature. + voltage = [0.7, 0.7, 0.6] # Continuous voltage. + [stress.inductor.high_frequency] + current = [0.9, 0.9, 0.8] + temperature = [30.0, 30.0, 30.0] + [stress.relay.capacitive_load] + current = [0.7, 0.6, 0.5] # Continuous current. + drop_out = [0.9, 0.9, 0.9] # Coil dropout voltage. + pick_up = [1.1, 1.1, 1.1] # Coil pickup voltage. + temperature = [10.0, 20.0, 30.0] # Maximum ambient temperature. + [stress.relay.inductive_load] + current = [0.5, 0.4, 0.3] + drop_out = [0.9, 0.9, 0.9] + pick_up = [1.1, 1.1, 1.1] + temperature = [10.0, 20.0, 30.0] + [stress.relay.resistive_load] + current = [0.7, 0.6, 0.5] + drop_out = [0.9, 0.9, 0.9] + pick_up = [1.1, 1.1, 1.1] + temperature = [10.0, 20.0, 30.0] + [stress.switch.capacitive_load] + current = [0.7, 0.6, 0.5] # Continous contact current. + power = [0.7, 0.6, 0.5] # Contact power. + surge_current = [0.8, 0.8, 0.8] # Surge contact current. + [stress.switch.inductive_load] + current = [0.5, 0.4, 0.3] + power = [0.7, 0.6, 0.5] + surge_current = [0.8, 0.8, 0.8] + [stress.switch.resistitive_load] + current = [0.7, 0.6, 0.5] + power = [0.7, 0.6, 0.5] + surge_current = [0.8, 0.8, 0.8] + [stress.connection] + current = [1.0, 1.0, 1.0] # Contact current. + [stress.miscellaneous.lamp] + current = [0.2, 0.1, 0.1] # Continuous current. diff --git a/poetry.lock b/poetry.lock index e8fd568c9..d920f4dde 100644 --- a/poetry.lock +++ b/poetry.lock @@ -63,7 +63,7 @@ tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (> [[package]] name = "autograd" -version = "1.3" +version = "1.4" description = "Efficiently computes derivatives of numpy code." category = "main" optional = false @@ -140,17 +140,20 @@ uvloop = ["uvloop (>=0.15.2)"] [[package]] name = "bleach" -version = "4.1.0" +version = "5.0.0" description = "An easy safelist-based HTML-sanitizing tool." category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [package.dependencies] -packaging = "*" six = ">=1.9.0" webencodings = "*" +[package.extras] +css = ["tinycss2 (>=1.1.0)"] +dev = ["pip-tools (==6.5.1)", "pytest (==7.1.1)", "flake8 (==4.0.1)", "tox (==3.24.5)", "sphinx (==4.3.2)", "twine (==4.0.0)", "wheel (==0.37.1)", "hashin (==0.17.0)", "black (==22.3.0)", "mypy (==0.942)"] + [[package]] name = "cached-property" version = "1.5.2" @@ -353,7 +356,7 @@ testing = ["covdefaults (>=1.2.0)", "coverage (>=4)", "pytest (>=4)", "pytest-co [[package]] name = "fonttools" -version = "4.31.2" +version = "4.32.0" description = "Tools to manipulate font files" category = "main" optional = false @@ -374,26 +377,25 @@ woff = ["zopfli (>=0.1.4)", "brotlicffi (>=0.8.0)", "brotli (>=1.0.1)"] [[package]] name = "formulaic" -version = "0.2.4" +version = "0.3.2" description = "An implementation of Wilkinson formulas." category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [package.dependencies] -astor = "*" +astor = ">=0.7.0" interface-meta = ">=1.2" -numpy = "*" -pandas = "*" -scipy = "*" -wrapt = "*" +numpy = ">=1.3" +pandas = ">=1.2" +scipy = ">=1.6" +wrapt = ">=1.0" [package.extras] -arrow = ["pyarrow"] +arrow = ["pyarrow (>=1)"] benchmarks = ["patsy", "rpy2", "uncertainties"] -calculus = ["sympy"] -docs = ["mkdocs-material", "pymdown-extensions", "pygments"] -test = ["flake8", "pytest", "pytest-cov"] +calculus = ["sympy (>=1.3,<1.10)"] +test = ["black (==22.1.0)", "flake8 (==4.0.1)", "pytest (==6.2.5)", "pytest-cov (==3.0.0)"] [[package]] name = "future" @@ -439,7 +441,7 @@ docs = ["sphinx"] [[package]] name = "icdiff" -version = "2.0.4" +version = "2.0.5" description = "improved colored diff" category = "dev" optional = false @@ -499,11 +501,11 @@ python-versions = "*" [[package]] name = "interface-meta" -version = "1.2.5" -description = "InterfaceMeta" +version = "1.3.0" +description = "`interface_meta` provides a convenient way to expose an extensible API with enforced method signatures and consistent documentation." category = "main" optional = false -python-versions = ">=3.4" +python-versions = ">=3.7,<4.0" [[package]] name = "isort" @@ -521,14 +523,14 @@ plugins = ["setuptools"] [[package]] name = "jeepney" -version = "0.7.1" +version = "0.8.0" description = "Low-level, pure Python DBus protocol wrapper." category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [package.extras] -test = ["pytest", "pytest-trio", "pytest-asyncio", "testpath", "trio", "async-timeout"] +test = ["pytest", "pytest-trio", "pytest-asyncio (>=0.17)", "testpath", "trio", "async-timeout"] trio = ["trio", "async-generator"] [[package]] @@ -584,19 +586,19 @@ python-versions = ">=3.6" [[package]] name = "lifelines" -version = "0.26.4" +version = "0.27.0" description = "Survival analysis in Python, including Kaplan Meier, Nelson Aalen and regression" category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [package.dependencies] autograd = ">=1.3" autograd-gamma = ">=0.3" -formulaic = ">=0.2.2,<0.3" +formulaic = ">=0.2.2" matplotlib = ">=3.0" numpy = ">=1.14.0" -pandas = ">=0.23.0" +pandas = ">=1.0.0" scipy = ">=1.2.0" [[package]] @@ -642,11 +644,11 @@ setuptools_scm = ">=4" [[package]] name = "mccabe" -version = "0.6.1" +version = "0.7.0" description = "McCabe checker, plugin for flake8" category = "dev" optional = false -python-versions = "*" +python-versions = ">=3.6" [[package]] name = "mock" @@ -675,7 +677,7 @@ tests = ["pytest (>=4.6)"] [[package]] name = "mypy" -version = "0.931" +version = "0.942" description = "Optional static typing for Python" category = "dev" optional = false @@ -690,6 +692,7 @@ typing-extensions = ">=3.10" [package.extras] dmypy = ["psutil (>=4.0)"] python2 = ["typed-ast (>=1.4.0,<2)"] +reports = ["lxml"] [[package]] name = "mypy-extensions" @@ -799,12 +802,16 @@ python-versions = "*" [[package]] name = "pillow" -version = "9.0.1" +version = "9.1.0" description = "Python Imaging Library (Fork)" category = "main" optional = false python-versions = ">=3.7" +[package.extras] +docs = ["olefile", "sphinx (>=2.4)", "sphinx-copybutton", "sphinx-issues (>=3.0.1)", "sphinx-removed-in", "sphinx-rtd-theme (>=1.0)", "sphinxext-opengraph"] +tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"] + [[package]] name = "pkginfo" version = "1.8.2" @@ -853,11 +860,11 @@ python-versions = "*" [[package]] name = "pre-commit" -version = "2.17.0" +version = "2.18.1" description = "A framework for managing and maintaining multi-language pre-commit hooks." category = "dev" optional = false -python-versions = ">=3.6.1" +python-versions = ">=3.7" [package.dependencies] cfgv = ">=2.0.0" @@ -870,11 +877,11 @@ virtualenv = ">=20.0.8" [[package]] name = "pre-commit-hooks" -version = "4.1.0" +version = "4.2.0" description = "Some out-of-the-box hooks for pre-commit." category = "dev" optional = false -python-versions = ">=3.6.1" +python-versions = ">=3.7" [package.dependencies] "ruamel.yaml" = ">=0.15" @@ -963,7 +970,7 @@ pycairo = ">=1.16,<2.0" [[package]] name = "pylint" -version = "2.13.4" +version = "2.13.5" description = "python code static checker" category = "dev" optional = false @@ -984,14 +991,14 @@ testutil = ["gitpython (>3)"] [[package]] name = "pyparsing" -version = "3.0.7" -description = "Python parsing module" +version = "3.0.8" +description = "pyparsing module - Classes and methods to define and execute parsing grammars" category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.6.8" [package.extras] -diagrams = ["jinja2", "railroad-diagrams"] +diagrams = ["railroad-diagrams", "jinja2"] [[package]] name = "pypubsub" @@ -1197,6 +1204,33 @@ python-versions = ">=3.7" [package.extras] idna2008 = ["idna"] +[[package]] +name = "rich" +version = "12.2.0" +description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" +category = "dev" +optional = false +python-versions = ">=3.6.3,<4.0.0" + +[package.dependencies] +commonmark = ">=0.9.0,<0.10.0" +pygments = ">=2.6.0,<3.0.0" +typing-extensions = {version = ">=4.0.0,<5.0", markers = "python_version < \"3.9\""} + +[package.extras] +jupyter = ["ipywidgets (>=7.5.1,<8.0.0)"] + +[[package]] +name = "rstcheck" +version = "3.4.0" +description = "Checks syntax of reStructuredText and code blocks nested within it" +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +docutils = ">=0.7" + [[package]] name = "ruamel.yaml" version = "0.17.21" @@ -1443,7 +1477,7 @@ test = ["pytest", "pytest-cov", "coverage (>=4.0,!=4.4)"] [[package]] name = "sqlalchemy" -version = "1.4.34" +version = "1.4.35" description = "Database Abstraction Library" category = "main" optional = false @@ -1567,22 +1601,6 @@ category = "main" optional = false python-versions = ">=3.7" -[[package]] -name = "tqdm" -version = "4.63.1" -description = "Fast, Extensible Progress Meter" -category = "dev" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" - -[package.dependencies] -colorama = {version = "*", markers = "platform_system == \"Windows\""} - -[package.extras] -dev = ["py-make (>=0.1.0)", "twine", "wheel"] -notebook = ["ipywidgets (>=6)"] -telegram = ["requests"] - [[package]] name = "treelib" version = "1.6.1" @@ -1596,14 +1614,13 @@ future = "*" [[package]] name = "twine" -version = "3.8.0" +version = "4.0.0" description = "Collection of utilities for publishing packages on PyPI" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [package.dependencies] -colorama = ">=0.4.3" importlib-metadata = ">=3.6" keyring = ">=15.1" pkginfo = ">=1.8.1" @@ -1611,7 +1628,7 @@ readme-renderer = ">=21.0" requests = ">=2.20" requests-toolbelt = ">=0.8.0,<0.9.0 || >0.9.0" rfc3986 = ">=1.4.0" -tqdm = ">=4.14" +rich = ">=12.0.0" urllib3 = ">=1.26.0" [[package]] @@ -1653,7 +1670,7 @@ socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] [[package]] name = "virtualenv" -version = "20.14.0" +version = "20.14.1" description = "Virtual Python Environment builder" category = "dev" optional = false @@ -1717,20 +1734,20 @@ python-versions = "*" [[package]] name = "zipp" -version = "3.7.0" +version = "3.8.0" description = "Backport of pathlib-compatible object wrapper for zip files" category = "main" optional = false python-versions = ">=3.7" [package.extras] -docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] -testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy"] +docs = ["sphinx", "jaraco.packaging (>=9)", "rst.linker (>=1.9)"] +testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy (>=0.9.1)"] [metadata] lock-version = "1.1" python-versions = "^3.7,<4.0" -content-hash = "b0ac06c2949c022ec9476a46480486d9868edf5ae17d43546d4add45bfa5abdb" +content-hash = "ab2ba87703e354b4337fa7548689cdd5db3d7aafe1379778e769c6c9521da511" [metadata.files] alabaster = [ @@ -1758,7 +1775,8 @@ attrs = [ {file = "attrs-21.4.0.tar.gz", hash = "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd"}, ] autograd = [ - {file = "autograd-1.3.tar.gz", hash = "sha256:a15d147577e10de037de3740ca93bfa3b5a7cdfbc34cfb9105429c3580a33ec4"}, + {file = "autograd-1.4-py3-none-any.whl", hash = "sha256:5cd6051bf1440643bf8f1104c933b2dedefb7610b951091768c1c680b1e0ceda"}, + {file = "autograd-1.4.tar.gz", hash = "sha256:383de0f537ef2e38b85ff9692593b0cfae8958c9b3bd451b52c255fd9171ffce"}, ] autograd-gamma = [ {file = "autograd-gamma-0.5.0.tar.gz", hash = "sha256:f27abb7b8bb9cffc8badcbf59f3fe44a9db39e124ecacf1992b6d952934ac9c4"}, @@ -1797,8 +1815,8 @@ black = [ {file = "black-22.3.0.tar.gz", hash = "sha256:35020b8886c022ced9282b51b5a875b6d1ab0c387b31a065b84db7c33085ca79"}, ] bleach = [ - {file = "bleach-4.1.0-py2.py3-none-any.whl", hash = "sha256:4d2651ab93271d1129ac9cbc679f524565cc8a1b791909c4a51eac4446a15994"}, - {file = "bleach-4.1.0.tar.gz", hash = "sha256:0900d8b37eba61a802ee40ac0061f8c2b5dee29c1927dd1d233e075ebf5a71da"}, + {file = "bleach-5.0.0-py3-none-any.whl", hash = "sha256:08a1fe86d253b5c88c92cc3d810fd8048a16d15762e1e5b74d502256e5926aa1"}, + {file = "bleach-5.0.0.tar.gz", hash = "sha256:c6d6cc054bdc9c83b48b8083e236e5f00f238428666d2ce2e083eaa5fd568565"}, ] cached-property = [ {file = "cached-property-1.5.2.tar.gz", hash = "sha256:9fa5755838eecbb2d234c3aa390bd80fbd3ac6b6869109bfc1b499f7bd89a130"}, @@ -1980,12 +1998,12 @@ filelock = [ {file = "filelock-3.6.0.tar.gz", hash = "sha256:9cd540a9352e432c7246a48fe4e8712b10acb1df2ad1f30e8c070b82ae1fed85"}, ] fonttools = [ - {file = "fonttools-4.31.2-py3-none-any.whl", hash = "sha256:2df636a3f402ef14593c6811dac0609563b8c374bd7850e76919eb51ea205426"}, - {file = "fonttools-4.31.2.zip", hash = "sha256:236b29aee6b113e8f7bee28779c1230a86ad2aac9a74a31b0aedf57e7dfb62a4"}, + {file = "fonttools-4.32.0-py3-none-any.whl", hash = "sha256:b038d1a0dee0079de7ade57071e2e2aced6e35bd697de244ac62938b2b1628c1"}, + {file = "fonttools-4.32.0.zip", hash = "sha256:59a90de72149893167e3d552ae2402c6874e006b9adc3feaf5f6d706fe20d392"}, ] formulaic = [ - {file = "formulaic-0.2.4-py3-none-any.whl", hash = "sha256:775620d93f24f01b33a17aa2cf65a04112003c5112f12015368e4e4605a5013b"}, - {file = "formulaic-0.2.4.tar.gz", hash = "sha256:15b71ea8972fb451f80684203cddd49620fc9ed5c2e35f31e0874e9c41910d1a"}, + {file = "formulaic-0.3.2-py3-none-any.whl", hash = "sha256:d64f69c6865864ac2b27e4e1ff2d246f0425af13655be0ffc5a7b4b43610e962"}, + {file = "formulaic-0.3.2.tar.gz", hash = "sha256:3e16262562147acbdeda1178d778ac189a93bd63e2348261bd8b5d303f173f6d"}, ] future = [ {file = "future-0.18.2.tar.gz", hash = "sha256:b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d"}, @@ -2056,7 +2074,7 @@ greenlet = [ {file = "greenlet-1.1.2.tar.gz", hash = "sha256:e30f5ea4ae2346e62cedde8794a56858a67b878dd79f7df76a0767e356b1744a"}, ] icdiff = [ - {file = "icdiff-2.0.4.tar.gz", hash = "sha256:c72572e5ce087bc7a7748af2664764d4a805897caeefb665bdc12677fefb2212"}, + {file = "icdiff-2.0.5.tar.gz", hash = "sha256:35d24b728e48b7e0a12bdb69386d3bfc7eef4fe922d0ac1cd70d6e5c11630bae"}, ] identify = [ {file = "identify-2.4.12-py2.py3-none-any.whl", hash = "sha256:5f06b14366bd1facb88b00540a1de05b69b310cbc2654db3c7e07fa3a4339323"}, @@ -2079,16 +2097,16 @@ iniconfig = [ {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, ] interface-meta = [ - {file = "interface_meta-1.2.5-py2.py3-none-any.whl", hash = "sha256:18a220f5db197e8a7f548bca74a860c7859b7cd9638a640c46035d88410e1dd3"}, - {file = "interface_meta-1.2.5.tar.gz", hash = "sha256:0c81910ac200a343794db13062775592e4c96cc9f0d55ea5385cdc388945b17d"}, + {file = "interface_meta-1.3.0-py3-none-any.whl", hash = "sha256:de35dc5241431886e709e20a14d6597ed07c9f1e8b4bfcffde2190ca5b700ee8"}, + {file = "interface_meta-1.3.0.tar.gz", hash = "sha256:8a4493f8bdb73fb9655dcd5115bc897e207319e36c8835f39c516a2d7e9d79a1"}, ] isort = [ {file = "isort-5.10.1-py3-none-any.whl", hash = "sha256:6f62d78e2f89b4500b080fe3a81690850cd254227f27f75c3a0c491a1f351ba7"}, {file = "isort-5.10.1.tar.gz", hash = "sha256:e8443a5e7a020e9d7f97f1d7d9cd17c88bcb3bc7e218bf9cf5095fe550be2951"}, ] jeepney = [ - {file = "jeepney-0.7.1-py3-none-any.whl", hash = "sha256:1b5a0ea5c0e7b166b2f5895b91a08c14de8915afda4407fb5022a195224958ac"}, - {file = "jeepney-0.7.1.tar.gz", hash = "sha256:fa9e232dfa0c498bd0b8a3a73b8d8a31978304dcef0515adc859d4e096f96f4f"}, + {file = "jeepney-0.8.0-py3-none-any.whl", hash = "sha256:c0a454ad016ca575060802ee4d590dd912e35c122fa04e70306de3d076cce755"}, + {file = "jeepney-0.8.0.tar.gz", hash = "sha256:5efe48d255973902f6badc3ce55e2aa6c5c3b3bc642059ef3a91247bcfcc5806"}, ] jinja2 = [ {file = "Jinja2-3.1.1-py3-none-any.whl", hash = "sha256:539835f51a74a69f41b848a9645dbdc35b4f20a3b601e2d9a7e22947b15ff119"}, @@ -2183,8 +2201,8 @@ lazy-object-proxy = [ {file = "lazy_object_proxy-1.7.1-pp37.pp38-none-any.whl", hash = "sha256:d66906d5785da8e0be7360912e99c9188b70f52c422f9fc18223347235691a84"}, ] lifelines = [ - {file = "lifelines-0.26.4-py3-none-any.whl", hash = "sha256:51a0a5f585281f92dc0c1ef89493141df69e766b014ad0d2ae631d1acc18d696"}, - {file = "lifelines-0.26.4.tar.gz", hash = "sha256:997bb06c8ef535286e2c21ba2f71c34bb571b314e7cd375348f63c1fdd30e1eb"}, + {file = "lifelines-0.27.0-py3-none-any.whl", hash = "sha256:afa890dd2a49a55453502accc9ecf825b88fb0decb536306e369df7d574f049c"}, + {file = "lifelines-0.27.0.tar.gz", hash = "sha256:55386b0edc607d4316ed96f9e815abfe83120f0ec34ddffa6b4329ee3a55e5fd"}, ] mando = [ {file = "mando-0.6.4-py2.py3-none-any.whl", hash = "sha256:4ce09faec7e5192ffc3c57830e26acba0fd6cd11e1ee81af0d4df0657463bd1c"}, @@ -2270,8 +2288,8 @@ matplotlib = [ {file = "matplotlib-3.5.1.tar.gz", hash = "sha256:b2e9810e09c3a47b73ce9cab5a72243a1258f61e7900969097a817232246ce1c"}, ] mccabe = [ - {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"}, - {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, + {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"}, + {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, ] mock = [ {file = "mock-4.0.3-py3-none-any.whl", hash = "sha256:122fcb64ee37cfad5b3f48d7a7d51875d7031aaf3d8be7c42e2bee25044eee62"}, @@ -2282,26 +2300,29 @@ mpmath = [ {file = "mpmath-1.2.1.tar.gz", hash = "sha256:79ffb45cf9f4b101a807595bcb3e72e0396202e0b1d25d689134b48c4216a81a"}, ] mypy = [ - {file = "mypy-0.931-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3c5b42d0815e15518b1f0990cff7a705805961613e701db60387e6fb663fe78a"}, - {file = "mypy-0.931-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c89702cac5b302f0c5d33b172d2b55b5df2bede3344a2fbed99ff96bddb2cf00"}, - {file = "mypy-0.931-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:300717a07ad09525401a508ef5d105e6b56646f7942eb92715a1c8d610149714"}, - {file = "mypy-0.931-cp310-cp310-win_amd64.whl", hash = "sha256:7b3f6f557ba4afc7f2ce6d3215d5db279bcf120b3cfd0add20a5d4f4abdae5bc"}, - {file = "mypy-0.931-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:1bf752559797c897cdd2c65f7b60c2b6969ffe458417b8d947b8340cc9cec08d"}, - {file = "mypy-0.931-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4365c60266b95a3f216a3047f1d8e3f895da6c7402e9e1ddfab96393122cc58d"}, - {file = "mypy-0.931-cp36-cp36m-win_amd64.whl", hash = "sha256:1b65714dc296a7991000b6ee59a35b3f550e0073411ac9d3202f6516621ba66c"}, - {file = "mypy-0.931-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:e839191b8da5b4e5d805f940537efcaa13ea5dd98418f06dc585d2891d228cf0"}, - {file = "mypy-0.931-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:50c7346a46dc76a4ed88f3277d4959de8a2bd0a0fa47fa87a4cde36fe247ac05"}, - {file = "mypy-0.931-cp37-cp37m-win_amd64.whl", hash = "sha256:d8f1ff62f7a879c9fe5917b3f9eb93a79b78aad47b533911b853a757223f72e7"}, - {file = "mypy-0.931-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f9fe20d0872b26c4bba1c1be02c5340de1019530302cf2dcc85c7f9fc3252ae0"}, - {file = "mypy-0.931-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:1b06268df7eb53a8feea99cbfff77a6e2b205e70bf31743e786678ef87ee8069"}, - {file = "mypy-0.931-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:8c11003aaeaf7cc2d0f1bc101c1cc9454ec4cc9cb825aef3cafff8a5fdf4c799"}, - {file = "mypy-0.931-cp38-cp38-win_amd64.whl", hash = "sha256:d9d2b84b2007cea426e327d2483238f040c49405a6bf4074f605f0156c91a47a"}, - {file = "mypy-0.931-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ff3bf387c14c805ab1388185dd22d6b210824e164d4bb324b195ff34e322d166"}, - {file = "mypy-0.931-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5b56154f8c09427bae082b32275a21f500b24d93c88d69a5e82f3978018a0266"}, - {file = "mypy-0.931-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:8ca7f8c4b1584d63c9a0f827c37ba7a47226c19a23a753d52e5b5eddb201afcd"}, - {file = "mypy-0.931-cp39-cp39-win_amd64.whl", hash = "sha256:74f7eccbfd436abe9c352ad9fb65872cc0f1f0a868e9d9c44db0893440f0c697"}, - {file = "mypy-0.931-py3-none-any.whl", hash = "sha256:1171f2e0859cfff2d366da2c7092b06130f232c636a3f7301e3feb8b41f6377d"}, - {file = "mypy-0.931.tar.gz", hash = "sha256:0038b21890867793581e4cb0d810829f5fd4441aa75796b53033af3aa30430ce"}, + {file = "mypy-0.942-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:5bf44840fb43ac4074636fd47ee476d73f0039f4f54e86d7265077dc199be24d"}, + {file = "mypy-0.942-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:dcd955f36e0180258a96f880348fbca54ce092b40fbb4b37372ae3b25a0b0a46"}, + {file = "mypy-0.942-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6776e5fa22381cc761df53e7496a805801c1a751b27b99a9ff2f0ca848c7eca0"}, + {file = "mypy-0.942-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:edf7237137a1a9330046dbb14796963d734dd740a98d5e144a3eb1d267f5f9ee"}, + {file = "mypy-0.942-cp310-cp310-win_amd64.whl", hash = "sha256:64235137edc16bee6f095aba73be5334677d6f6bdb7fa03cfab90164fa294a17"}, + {file = "mypy-0.942-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:b840cfe89c4ab6386c40300689cd8645fc8d2d5f20101c7f8bd23d15fca14904"}, + {file = "mypy-0.942-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2b184db8c618c43c3a31b32ff00cd28195d39e9c24e7c3b401f3db7f6e5767f5"}, + {file = "mypy-0.942-cp36-cp36m-win_amd64.whl", hash = "sha256:1a0459c333f00e6a11cbf6b468b870c2b99a906cb72d6eadf3d1d95d38c9352c"}, + {file = "mypy-0.942-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4c3e497588afccfa4334a9986b56f703e75793133c4be3a02d06a3df16b67a58"}, + {file = "mypy-0.942-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6f6ad963172152e112b87cc7ec103ba0f2db2f1cd8997237827c052a3903eaa6"}, + {file = "mypy-0.942-cp37-cp37m-win_amd64.whl", hash = "sha256:0e2dd88410937423fba18e57147dd07cd8381291b93d5b1984626f173a26543e"}, + {file = "mypy-0.942-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:246e1aa127d5b78488a4a0594bd95f6d6fb9d63cf08a66dafbff8595d8891f67"}, + {file = "mypy-0.942-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d8d3ba77e56b84cd47a8ee45b62c84b6d80d32383928fe2548c9a124ea0a725c"}, + {file = "mypy-0.942-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2bc249409a7168d37c658e062e1ab5173300984a2dada2589638568ddc1db02b"}, + {file = "mypy-0.942-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:9521c1265ccaaa1791d2c13582f06facf815f426cd8b07c3a485f486a8ffc1f3"}, + {file = "mypy-0.942-cp38-cp38-win_amd64.whl", hash = "sha256:e865fec858d75b78b4d63266c9aff770ecb6a39dfb6d6b56c47f7f8aba6baba8"}, + {file = "mypy-0.942-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:6ce34a118d1a898f47def970a2042b8af6bdcc01546454726c7dd2171aa6dfca"}, + {file = "mypy-0.942-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:10daab80bc40f84e3f087d896cdb53dc811a9f04eae4b3f95779c26edee89d16"}, + {file = "mypy-0.942-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3841b5433ff936bff2f4dc8d54cf2cdbfea5d8e88cedfac45c161368e5770ba6"}, + {file = "mypy-0.942-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6f7106cbf9cc2f403693bf50ed7c9fa5bb3dfa9007b240db3c910929abe2a322"}, + {file = "mypy-0.942-cp39-cp39-win_amd64.whl", hash = "sha256:7742d2c4e46bb5017b51c810283a6a389296cda03df805a4f7869a6f41246534"}, + {file = "mypy-0.942-py3-none-any.whl", hash = "sha256:a1b383fe99678d7402754fe90448d4037f9512ce70c21f8aee3b8bf48ffc51db"}, + {file = "mypy-0.942.tar.gz", hash = "sha256:17e44649fec92e9f82102b48a3bf7b4a5510ad0cd22fa21a104826b5db4903e2"}, ] mypy-extensions = [ {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, @@ -2393,41 +2414,44 @@ pep8 = [ {file = "pep8-1.7.1.tar.gz", hash = "sha256:fe249b52e20498e59e0b5c5256aa52ee99fc295b26ec9eaa85776ffdb9fe6374"}, ] pillow = [ - {file = "Pillow-9.0.1-1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a5d24e1d674dd9d72c66ad3ea9131322819ff86250b30dc5821cbafcfa0b96b4"}, - {file = "Pillow-9.0.1-1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2632d0f846b7c7600edf53c48f8f9f1e13e62f66a6dbc15191029d950bfed976"}, - {file = "Pillow-9.0.1-1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b9618823bd237c0d2575283f2939655f54d51b4527ec3972907a927acbcc5bfc"}, - {file = "Pillow-9.0.1-cp310-cp310-macosx_10_10_universal2.whl", hash = "sha256:9bfdb82cdfeccec50aad441afc332faf8606dfa5e8efd18a6692b5d6e79f00fd"}, - {file = "Pillow-9.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5100b45a4638e3c00e4d2320d3193bdabb2d75e79793af7c3eb139e4f569f16f"}, - {file = "Pillow-9.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:528a2a692c65dd5cafc130de286030af251d2ee0483a5bf50c9348aefe834e8a"}, - {file = "Pillow-9.0.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0f29d831e2151e0b7b39981756d201f7108d3d215896212ffe2e992d06bfe049"}, - {file = "Pillow-9.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:855c583f268edde09474b081e3ddcd5cf3b20c12f26e0d434e1386cc5d318e7a"}, - {file = "Pillow-9.0.1-cp310-cp310-win32.whl", hash = "sha256:d9d7942b624b04b895cb95af03a23407f17646815495ce4547f0e60e0b06f58e"}, - {file = "Pillow-9.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:81c4b81611e3a3cb30e59b0cf05b888c675f97e3adb2c8672c3154047980726b"}, - {file = "Pillow-9.0.1-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:413ce0bbf9fc6278b2d63309dfeefe452835e1c78398efb431bab0672fe9274e"}, - {file = "Pillow-9.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:80fe64a6deb6fcfdf7b8386f2cf216d329be6f2781f7d90304351811fb591360"}, - {file = "Pillow-9.0.1-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cef9c85ccbe9bee00909758936ea841ef12035296c748aaceee535969e27d31b"}, - {file = "Pillow-9.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1d19397351f73a88904ad1aee421e800fe4bbcd1aeee6435fb62d0a05ccd1030"}, - {file = "Pillow-9.0.1-cp37-cp37m-win32.whl", hash = "sha256:d21237d0cd37acded35154e29aec853e945950321dd2ffd1a7d86fe686814669"}, - {file = "Pillow-9.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:ede5af4a2702444a832a800b8eb7f0a7a1c0eed55b644642e049c98d589e5092"}, - {file = "Pillow-9.0.1-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:b5b3f092fe345c03bca1e0b687dfbb39364b21ebb8ba90e3fa707374b7915204"}, - {file = "Pillow-9.0.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:335ace1a22325395c4ea88e00ba3dc89ca029bd66bd5a3c382d53e44f0ccd77e"}, - {file = "Pillow-9.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:db6d9fac65bd08cea7f3540b899977c6dee9edad959fa4eaf305940d9cbd861c"}, - {file = "Pillow-9.0.1-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f154d173286a5d1863637a7dcd8c3437bb557520b01bddb0be0258dcb72696b5"}, - {file = "Pillow-9.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:14d4b1341ac07ae07eb2cc682f459bec932a380c3b122f5540432d8977e64eae"}, - {file = "Pillow-9.0.1-cp38-cp38-win32.whl", hash = "sha256:effb7749713d5317478bb3acb3f81d9d7c7f86726d41c1facca068a04cf5bb4c"}, - {file = "Pillow-9.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:7f7609a718b177bf171ac93cea9fd2ddc0e03e84d8fa4e887bdfc39671d46b00"}, - {file = "Pillow-9.0.1-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:80ca33961ced9c63358056bd08403ff866512038883e74f3a4bf88ad3eb66838"}, - {file = "Pillow-9.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1c3c33ac69cf059bbb9d1a71eeaba76781b450bc307e2291f8a4764d779a6b28"}, - {file = "Pillow-9.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:12875d118f21cf35604176872447cdb57b07126750a33748bac15e77f90f1f9c"}, - {file = "Pillow-9.0.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:514ceac913076feefbeaf89771fd6febde78b0c4c1b23aaeab082c41c694e81b"}, - {file = "Pillow-9.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3c5c79ab7dfce6d88f1ba639b77e77a17ea33a01b07b99840d6ed08031cb2a7"}, - {file = "Pillow-9.0.1-cp39-cp39-win32.whl", hash = "sha256:718856856ba31f14f13ba885ff13874be7fefc53984d2832458f12c38205f7f7"}, - {file = "Pillow-9.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:f25ed6e28ddf50de7e7ea99d7a976d6a9c415f03adcaac9c41ff6ff41b6d86ac"}, - {file = "Pillow-9.0.1-pp37-pypy37_pp73-macosx_10_10_x86_64.whl", hash = "sha256:011233e0c42a4a7836498e98c1acf5e744c96a67dd5032a6f666cc1fb97eab97"}, - {file = "Pillow-9.0.1-pp37-pypy37_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:253e8a302a96df6927310a9d44e6103055e8fb96a6822f8b7f514bb7ef77de56"}, - {file = "Pillow-9.0.1-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6295f6763749b89c994fcb6d8a7f7ce03c3992e695f89f00b741b4580b199b7e"}, - {file = "Pillow-9.0.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:a9f44cd7e162ac6191491d7249cceb02b8116b0f7e847ee33f739d7cb1ea1f70"}, - {file = "Pillow-9.0.1.tar.gz", hash = "sha256:6c8bc8238a7dfdaf7a75f5ec5a663f4173f8c367e5a39f87e720495e1eed75fa"}, + {file = "Pillow-9.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:af79d3fde1fc2e33561166d62e3b63f0cc3e47b5a3a2e5fea40d4917754734ea"}, + {file = "Pillow-9.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:55dd1cf09a1fd7c7b78425967aacae9b0d70125f7d3ab973fadc7b5abc3de652"}, + {file = "Pillow-9.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:66822d01e82506a19407d1afc104c3fcea3b81d5eb11485e593ad6b8492f995a"}, + {file = "Pillow-9.1.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a5eaf3b42df2bcda61c53a742ee2c6e63f777d0e085bbc6b2ab7ed57deb13db7"}, + {file = "Pillow-9.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:01ce45deec9df310cbbee11104bae1a2a43308dd9c317f99235b6d3080ddd66e"}, + {file = "Pillow-9.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:aea7ce61328e15943d7b9eaca87e81f7c62ff90f669116f857262e9da4057ba3"}, + {file = "Pillow-9.1.0-cp310-cp310-win32.whl", hash = "sha256:7a053bd4d65a3294b153bdd7724dce864a1d548416a5ef61f6d03bf149205160"}, + {file = "Pillow-9.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:97bda660702a856c2c9e12ec26fc6d187631ddfd896ff685814ab21ef0597033"}, + {file = "Pillow-9.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:21dee8466b42912335151d24c1665fcf44dc2ee47e021d233a40c3ca5adae59c"}, + {file = "Pillow-9.1.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b6d4050b208c8ff886fd3db6690bf04f9a48749d78b41b7a5bf24c236ab0165"}, + {file = "Pillow-9.1.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5cfca31ab4c13552a0f354c87fbd7f162a4fafd25e6b521bba93a57fe6a3700a"}, + {file = "Pillow-9.1.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed742214068efa95e9844c2d9129e209ed63f61baa4d54dbf4cf8b5e2d30ccf2"}, + {file = "Pillow-9.1.0-cp37-cp37m-win32.whl", hash = "sha256:c9efef876c21788366ea1f50ecb39d5d6f65febe25ad1d4c0b8dff98843ac244"}, + {file = "Pillow-9.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:de344bcf6e2463bb25179d74d6e7989e375f906bcec8cb86edb8b12acbc7dfef"}, + {file = "Pillow-9.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:17869489de2fce6c36690a0c721bd3db176194af5f39249c1ac56d0bb0fcc512"}, + {file = "Pillow-9.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:25023a6209a4d7c42154073144608c9a71d3512b648a2f5d4465182cb93d3477"}, + {file = "Pillow-9.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8782189c796eff29dbb37dd87afa4ad4d40fc90b2742704f94812851b725964b"}, + {file = "Pillow-9.1.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:463acf531f5d0925ca55904fa668bb3461c3ef6bc779e1d6d8a488092bdee378"}, + {file = "Pillow-9.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f42364485bfdab19c1373b5cd62f7c5ab7cc052e19644862ec8f15bb8af289e"}, + {file = "Pillow-9.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:3fddcdb619ba04491e8f771636583a7cc5a5051cd193ff1aa1ee8616d2a692c5"}, + {file = "Pillow-9.1.0-cp38-cp38-win32.whl", hash = "sha256:4fe29a070de394e449fd88ebe1624d1e2d7ddeed4c12e0b31624561b58948d9a"}, + {file = "Pillow-9.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:c24f718f9dd73bb2b31a6201e6db5ea4a61fdd1d1c200f43ee585fc6dcd21b34"}, + {file = "Pillow-9.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fb89397013cf302f282f0fc998bb7abf11d49dcff72c8ecb320f76ea6e2c5717"}, + {file = "Pillow-9.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c870193cce4b76713a2b29be5d8327c8ccbe0d4a49bc22968aa1e680930f5581"}, + {file = "Pillow-9.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69e5ddc609230d4408277af135c5b5c8fe7a54b2bdb8ad7c5100b86b3aab04c6"}, + {file = "Pillow-9.1.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:35be4a9f65441d9982240e6966c1eaa1c654c4e5e931eaf580130409e31804d4"}, + {file = "Pillow-9.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82283af99c1c3a5ba1da44c67296d5aad19f11c535b551a5ae55328a317ce331"}, + {file = "Pillow-9.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a325ac71914c5c043fa50441b36606e64a10cd262de12f7a179620f579752ff8"}, + {file = "Pillow-9.1.0-cp39-cp39-win32.whl", hash = "sha256:a598d8830f6ef5501002ae85c7dbfcd9c27cc4efc02a1989369303ba85573e58"}, + {file = "Pillow-9.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:0c51cb9edac8a5abd069fd0758ac0a8bfe52c261ee0e330f363548aca6893595"}, + {file = "Pillow-9.1.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a336a4f74baf67e26f3acc4d61c913e378e931817cd1e2ef4dfb79d3e051b481"}, + {file = "Pillow-9.1.0-pp37-pypy37_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb1b89b11256b5b6cad5e7593f9061ac4624f7651f7a8eb4dfa37caa1dfaa4d0"}, + {file = "Pillow-9.1.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:255c9d69754a4c90b0ee484967fc8818c7ff8311c6dddcc43a4340e10cd1636a"}, + {file = "Pillow-9.1.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:5a3ecc026ea0e14d0ad7cd990ea7f48bfcb3eb4271034657dc9d06933c6629a7"}, + {file = "Pillow-9.1.0-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c5b0ff59785d93b3437c3703e3c64c178aabada51dea2a7f2c5eccf1bcf565a3"}, + {file = "Pillow-9.1.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c7110ec1701b0bf8df569a7592a196c9d07c764a0a74f65471ea56816f10e2c8"}, + {file = "Pillow-9.1.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:8d79c6f468215d1a8415aa53d9868a6b40c4682165b8cb62a221b1baa47db458"}, + {file = "Pillow-9.1.0.tar.gz", hash = "sha256:f401ed2bbb155e1ade150ccc63db1a4f6c1909d3d378f7d1235a44e90d75fb97"}, ] pkginfo = [ {file = "pkginfo-1.8.2-py2.py3-none-any.whl", hash = "sha256:c24c487c6a7f72c66e816ab1796b96ac6c3d14d49338293d2141664330b55ffc"}, @@ -2446,12 +2470,12 @@ pprintpp = [ {file = "pprintpp-0.4.0.tar.gz", hash = "sha256:ea826108e2c7f49dc6d66c752973c3fc9749142a798d6b254e1e301cfdbc6403"}, ] pre-commit = [ - {file = "pre_commit-2.17.0-py2.py3-none-any.whl", hash = "sha256:725fa7459782d7bec5ead072810e47351de01709be838c2ce1726b9591dad616"}, - {file = "pre_commit-2.17.0.tar.gz", hash = "sha256:c1a8040ff15ad3d648c70cc3e55b93e4d2d5b687320955505587fd79bbaed06a"}, + {file = "pre_commit-2.18.1-py2.py3-none-any.whl", hash = "sha256:02226e69564ebca1a070bd1f046af866aa1c318dbc430027c50ab832ed2b73f2"}, + {file = "pre_commit-2.18.1.tar.gz", hash = "sha256:5d445ee1fa8738d506881c5d84f83c62bb5be6b2838e32207433647e8e5ebe10"}, ] pre-commit-hooks = [ - {file = "pre_commit_hooks-4.1.0-py2.py3-none-any.whl", hash = "sha256:ba95316b79038e56ce998cdacb1ce922831ac0e41744c77bcc2b9677bf183206"}, - {file = "pre_commit_hooks-4.1.0.tar.gz", hash = "sha256:b6361865d1877c5da5ac3a944aab19ce6bd749a534d2ede28e683d07194a57e1"}, + {file = "pre_commit_hooks-4.2.0-py2.py3-none-any.whl", hash = "sha256:b3a3066c5ecd5fdda9abdc932bd064bd21785ea041659676403e6fc5d964afed"}, + {file = "pre_commit_hooks-4.2.0.tar.gz", hash = "sha256:9726420c7a071e8cb233a066d36bc074b593a40f0b1b491d1b75aafa55390703"}, ] psycopg2 = [ {file = "psycopg2-2.9.3-cp310-cp310-win32.whl", hash = "sha256:083707a696e5e1c330af2508d8fab36f9700b26621ccbcb538abe22e15485362"}, @@ -2507,12 +2531,12 @@ pygobject = [ {file = "PyGObject-3.42.0.tar.gz", hash = "sha256:b9803991ec0b0b4175e81fee0ad46090fa7af438fe169348a9b18ae53447afcd"}, ] pylint = [ - {file = "pylint-2.13.4-py3-none-any.whl", hash = "sha256:8672cf7441b81410f5de7defdf56e2d559c956fd0579652f2e0a0a35bea2d546"}, - {file = "pylint-2.13.4.tar.gz", hash = "sha256:7cc6d0c4f61dff440f9ed8b657f4ecd615dcfe35345953eb7b1dc74afe901d7a"}, + {file = "pylint-2.13.5-py3-none-any.whl", hash = "sha256:c149694cfdeaee1aa2465e6eaab84c87a881a7d55e6e93e09466be7164764d1e"}, + {file = "pylint-2.13.5.tar.gz", hash = "sha256:dab221658368c7a05242e673c275c488670144123f4bd262b2777249c1c0de9b"}, ] pyparsing = [ - {file = "pyparsing-3.0.7-py3-none-any.whl", hash = "sha256:a6c06a88f252e6c322f65faf8f418b16213b51bdfaece0524c1c1bc30c63c484"}, - {file = "pyparsing-3.0.7.tar.gz", hash = "sha256:18ee9022775d270c55187733956460083db60b37d0d0fb357445f3094eed3eea"}, + {file = "pyparsing-3.0.8-py3-none-any.whl", hash = "sha256:ef7b523f6356f763771559412c0d7134753f037822dad1b16945b7b846f7ad06"}, + {file = "pyparsing-3.0.8.tar.gz", hash = "sha256:7bf433498c016c4314268d95df76c81b842a4cb2b276fa3312cfb1e1d85f6954"}, ] pypubsub = [ {file = "Pypubsub-4.0.3-py3-none-any.whl", hash = "sha256:7f716bae9388afe01ff82b264ba8a96a8ae78b42bb1f114f2716ca8f9e404e2a"}, @@ -2606,6 +2630,14 @@ rfc3986 = [ {file = "rfc3986-2.0.0-py2.py3-none-any.whl", hash = "sha256:50b1502b60e289cb37883f3dfd34532b8873c7de9f49bb546641ce9cbd256ebd"}, {file = "rfc3986-2.0.0.tar.gz", hash = "sha256:97aacf9dbd4bfd829baad6e6309fa6573aaf1be3f6fa735c8ab05e46cecb261c"}, ] +rich = [ + {file = "rich-12.2.0-py3-none-any.whl", hash = "sha256:c50f3d253bc6a9bb9c79d61a26d510d74abdf1b16881260fab5edfc3edfb082f"}, + {file = "rich-12.2.0.tar.gz", hash = "sha256:ea74bc9dad9589d8eea3e3fd0b136d8bf6e428888955f215824c2894f0da8b47"}, +] +rstcheck = [ + {file = "rstcheck-3.4.0-py3-none-any.whl", hash = "sha256:64fa26f06758a30254ce1a81ca5916fa68b65756cda453a7b54b440dcf4f1c86"}, + {file = "rstcheck-3.4.0.tar.gz", hash = "sha256:a142f780bcfa5d17407f1729c66a45ddbbb979789dafda16b19aa347ea8a2d4c"}, +] "ruamel.yaml" = [ {file = "ruamel.yaml-0.17.21-py3-none-any.whl", hash = "sha256:742b35d3d665023981bd6d16b3d24248ce5df75fdb4e2924e93a05c1f8b61ca7"}, {file = "ruamel.yaml-0.17.21.tar.gz", hash = "sha256:8b7ce697a2f212752a35c1ac414471dc16c424c9573be4926b56ff3f5d23b7af"}, @@ -2736,37 +2768,11 @@ sphinxcontrib-spelling = [ {file = "sphinxcontrib_spelling-7.3.2-py3-none-any.whl", hash = "sha256:1b99cdb1a30271c7080ec5b968dfc243c2540a960afdc4c052cd59dfe8d94c54"}, ] sqlalchemy = [ - {file = "SQLAlchemy-1.4.34-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:c025d45318b73c0601cca451532556cbab532b2742839ebb8cb58f9ebf06811e"}, - {file = "SQLAlchemy-1.4.34-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:cd5cffd1dd753828f1069f33062f3896e51c990acd957c264f40e051b3e19887"}, - {file = "SQLAlchemy-1.4.34-cp27-cp27m-win32.whl", hash = "sha256:a47bf6b7ca6c28e4f4e262fabcf5be6b907af81be36de77839c9eeda2cdf3bb3"}, - {file = "SQLAlchemy-1.4.34-cp27-cp27m-win_amd64.whl", hash = "sha256:c9218e3519398129e364121e0d89823e6ba2a2b77c28bfc661face0829c41433"}, - {file = "SQLAlchemy-1.4.34-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:7ee14a7f9f76d1ef9d5e5b760c9252617c839b87eee04d1ce8325ac66ae155c4"}, - {file = "SQLAlchemy-1.4.34-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:4414ace6e3a5e39523e55a5d9f3b215699b2ead4ff91fca98f1b659b7ab2d92a"}, - {file = "SQLAlchemy-1.4.34-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:27a42894a2751e438eaed12fc0dcfe741ff2f66c14760d081222c5adc5460064"}, - {file = "SQLAlchemy-1.4.34-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:671f61c3db4595b0e86cc4b30f675a7c0206d9ce99f041b4f6761c7ddd1e0074"}, - {file = "SQLAlchemy-1.4.34-cp310-cp310-win32.whl", hash = "sha256:3ebb97ed96f4506e2f212e1fcf0ec07a103bb194938627660a5acb4d9feae49c"}, - {file = "SQLAlchemy-1.4.34-cp310-cp310-win_amd64.whl", hash = "sha256:d8efcaa709ea8e7c08c3d3e7639c39b36083f5a995f397f9e6eedf5f5e4e4946"}, - {file = "SQLAlchemy-1.4.34-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:a4fb5c6ee84a6bba4ff6f9f5379f0b3a0ffe9de7ba5a0945659b3da8d519709b"}, - {file = "SQLAlchemy-1.4.34-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:67c1c27c48875afc950bee5ee24582794f20b545e64e4f9ca94071a9b514d6ed"}, - {file = "SQLAlchemy-1.4.34-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:954ea8c527c4322afb6885944904714893af81fe9167e421273770991bf08a4a"}, - {file = "SQLAlchemy-1.4.34-cp36-cp36m-win32.whl", hash = "sha256:2a3e4dc7c452ba3c0f3175ad5a8e0ba49c2b0570a8d07272cf50844c8d78e74f"}, - {file = "SQLAlchemy-1.4.34-cp36-cp36m-win_amd64.whl", hash = "sha256:f47996b1810894f766c9ee689607077c6c0e0fd6761e04c12ba13efb56d50c1d"}, - {file = "SQLAlchemy-1.4.34-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:b34bbc683789559f1bc9bb685fc162e0956dbbdfbe2fbd6755a9f5982c113610"}, - {file = "SQLAlchemy-1.4.34-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f197c66663ed0f9e1178d51141d864688fb244a83f6b17f667d521e482537b2e"}, - {file = "SQLAlchemy-1.4.34-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:08aaad905aba8940f27aeb9f1f851bf63f18ef97b0062ca41f64afc4b64e0e8c"}, - {file = "SQLAlchemy-1.4.34-cp37-cp37m-win32.whl", hash = "sha256:345306707bb0e51e7cd6e7573adafbce018894ee5e3b9c31134545f704936db0"}, - {file = "SQLAlchemy-1.4.34-cp37-cp37m-win_amd64.whl", hash = "sha256:50174e173d03209c34e07e7b57cca48d0082ac2390edf927aafc706c111da11e"}, - {file = "SQLAlchemy-1.4.34-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:878c7beaafa365602762c19f638282e1885454fed1aed86f8fae038933c7c671"}, - {file = "SQLAlchemy-1.4.34-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:621d3f6c0ba2407bb97e82b649be5ca7d5b6c201dcfb964ce13f517bf1cb6305"}, - {file = "SQLAlchemy-1.4.34-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:045d6a26c262929af0b9cb25441aae675ac04db4ea8bd2446b355617cd6b6b7d"}, - {file = "SQLAlchemy-1.4.34-cp38-cp38-win32.whl", hash = "sha256:e297a5cc625e3f1367a82deedf2d48ee4d2b2bd263b8b8d2efbaaf5608b5229e"}, - {file = "SQLAlchemy-1.4.34-cp38-cp38-win_amd64.whl", hash = "sha256:36f08d94670315ca04c8139bd80b3e02b9dd9cc66fc11bcb96fd10ad51a051ab"}, - {file = "SQLAlchemy-1.4.34-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:40b995d7aeeb6f88a1927ce6692c0f626b59d8effd3e1d597f125e141707b37c"}, - {file = "SQLAlchemy-1.4.34-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e67278ceb63270cdac0a7b89fc3c29a56f7dac9616a7ee48e7ad6b52e3b631e5"}, - {file = "SQLAlchemy-1.4.34-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:50107d8183da3fbe5715957aa3954cd9d82aed555c5b4d3fd37fac861af422fa"}, - {file = "SQLAlchemy-1.4.34-cp39-cp39-win32.whl", hash = "sha256:c3ad7f5b61ba014f5045912aea15b03c473bb02b1c07fd92c9d2c794fa183276"}, - {file = "SQLAlchemy-1.4.34-cp39-cp39-win_amd64.whl", hash = "sha256:5e88912bf192e7b5739c446d2276e1cba74cfa6c1c93eea2b2534404f6be1dbd"}, - {file = "SQLAlchemy-1.4.34.tar.gz", hash = "sha256:623bac2d6bdca3f3e61cf1e1c466c5fb9f5cf08735736ee1111187b7a4108891"}, + {file = "SQLAlchemy-1.4.35-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:c6fb6b9ed1d0be7fa2c90be8ad2442c14cbf84eb0709dd1afeeff1e511550041"}, + {file = "SQLAlchemy-1.4.35-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:48036698f20080462e981b18d77d574631a3d1fc2c33b416c6df299ec1d10b99"}, + {file = "SQLAlchemy-1.4.35-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a5dbdbb39c1b100df4d182c78949158073ca46ba2850c64fe02ffb1eb5b70903"}, + {file = "SQLAlchemy-1.4.35-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cfd8e4c64c30a5219032e64404d468c425bdbc13b397da906fc9bee6591fc0dd"}, + {file = "SQLAlchemy-1.4.35.tar.gz", hash = "sha256:2ffc813b01dc6473990f5e575f210ca5ac2f5465ace3908b78ffd6d20058aab5"}, ] sqlalchemy-utils = [ {file = "SQLAlchemy-Utils-0.38.2.tar.gz", hash = "sha256:9e01d6d3fb52d3926fcd4ea4a13f3540701b751aced0316bff78264402c2ceb4"}, @@ -2816,17 +2822,13 @@ tomli = [ {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, ] -tqdm = [ - {file = "tqdm-4.63.1-py2.py3-none-any.whl", hash = "sha256:6461b009d6792008d0000e1b0c7ca50195ec78c0e808a3a6b668a56a3236c3a5"}, - {file = "tqdm-4.63.1.tar.gz", hash = "sha256:4230a49119a416c88cc47d0d2d32d5d90f1a282d5e497d49801950704e49863d"}, -] treelib = [ {file = "treelib-1.6.1-py3.7.egg", hash = "sha256:8065064e5b92f59400295c221226b65905fd219c6ea43971fa0676b9e7780095"}, {file = "treelib-1.6.1.tar.gz", hash = "sha256:1cbfffb2d2b75ccac27d0200cee0507b6fbb0726e0afb9fae017ade5d2ce8788"}, ] twine = [ - {file = "twine-3.8.0-py3-none-any.whl", hash = "sha256:d0550fca9dc19f3d5e8eadfce0c227294df0a2a951251a4385797c8a6198b7c8"}, - {file = "twine-3.8.0.tar.gz", hash = "sha256:8efa52658e0ae770686a13b675569328f1fba9837e5de1867bfe5f46a9aefe19"}, + {file = "twine-4.0.0-py3-none-any.whl", hash = "sha256:6f7496cf14a3a8903474552d5271c79c71916519edb42554f23f42a8563498a9"}, + {file = "twine-4.0.0.tar.gz", hash = "sha256:817aa0c0bdc02a5ebe32051e168e23c71a0608334e624c793011f120dbbc05b7"}, ] typed-ast = [ {file = "typed_ast-1.5.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:183b183b7771a508395d2cbffd6db67d6ad52958a5fdc99f450d954003900266"}, @@ -2866,8 +2868,8 @@ urllib3 = [ {file = "urllib3-1.26.9.tar.gz", hash = "sha256:aabaf16477806a5e1dd19aa41f8c2b7950dd3c746362d7e3223dbe6de6ac448e"}, ] virtualenv = [ - {file = "virtualenv-20.14.0-py2.py3-none-any.whl", hash = "sha256:1e8588f35e8b42c6ec6841a13c5e88239de1e6e4e4cedfd3916b306dc826ec66"}, - {file = "virtualenv-20.14.0.tar.gz", hash = "sha256:8e5b402037287126e81ccde9432b95a8be5b19d36584f64957060a3488c11ca8"}, + {file = "virtualenv-20.14.1-py2.py3-none-any.whl", hash = "sha256:e617f16e25b42eb4f6e74096b9c9e37713cf10bf30168fb4a739f3fa8f898a3a"}, + {file = "virtualenv-20.14.1.tar.gz", hash = "sha256:ef589a79795589aada0c1c5b319486797c03b67ac3984c48c669c0e4f50df3a5"}, ] webencodings = [ {file = "webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78"}, @@ -2952,6 +2954,6 @@ xlwt = [ {file = "xlwt-1.3.0.tar.gz", hash = "sha256:c59912717a9b28f1a3c2a98fd60741014b06b043936dcecbc113eaaada156c88"}, ] zipp = [ - {file = "zipp-3.7.0-py3-none-any.whl", hash = "sha256:b47250dd24f92b7dd6a0a8fc5244da14608f3ca90a5efcd37a3b1642fac9a375"}, - {file = "zipp-3.7.0.tar.gz", hash = "sha256:9f50f446828eb9d45b267433fd3e9da8d801f614129124863f9c51ebceafb87d"}, + {file = "zipp-3.8.0-py3-none-any.whl", hash = "sha256:c4f6e5bbf48e74f7a38e7cc5b0480ff42b0ae5178957d564d18932525d5cf099"}, + {file = "zipp-3.8.0.tar.gz", hash = "sha256:56bf8aadb83c24db6c4b577e13de374ccfb67da2078beba1d037c17980bf43ad"}, ] diff --git a/pyproject.toml b/pyproject.toml index b58b6d6ac..0cb76e915 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -34,7 +34,7 @@ include = [ [tool.poetry.dependencies] python = "^3.7,<4.0" -lifelines = "^0.26.3" +lifelines = "^0.27.0" matplotlib = "^3.3.4" numpy = [ { version = "^1.21", python = "^3.7" }] @@ -67,11 +67,11 @@ coveralls = "^3.0.0" coverage = {extras = ["toml"], version = "^6.2"} docformatter = "^1.4" isort = "^5.7.0" -mccabe = "^0.6.1" +mccabe = "^0.7.0" mock = "^4.0.3" -mypy = "^0.931" +mypy = "^0.942" pep8 = "^1.7.1" -pre-commit = "^2.10.1" +pre-commit = "^2.18.0" pre-commit-hooks = "^4.0.1" pycodestyle = "^2.7.0" pydocstyle = "^6.1.1" @@ -83,12 +83,13 @@ pytest-icdiff = "^0.5" pytest-sugar = "^0.9.4" radon = "^5.1.0" recommonmark = "^0.7.1" +rstcheck = "^3.3.0" seed-isort-config = "^2.2.0" Sphinx = "^4.4.0" sphinx_py3doc_enhanced_theme = "^2.4.0" sphinxcontrib-issuetracker = "^0.11" sphinxcontrib-spelling = "^7.1.0" -twine = "^3.3.0" +twine = "^4.0.0" pillow = [ { version = "^9.0.0" , python = "^3.7" } ] diff --git a/src/ramstk/analyses/__init__.py b/src/ramstk/analyses/__init__.py index 0e6edf1af..ca75bab88 100644 --- a/src/ramstk/analyses/__init__.py +++ b/src/ramstk/analyses/__init__.py @@ -5,7 +5,6 @@ from . import ( allocation, criticality, - derating, dormancy, fha, improvementfactor, diff --git a/src/ramstk/analyses/derating.py b/src/ramstk/analyses/derating.py deleted file mode 100644 index 3da061795..000000000 --- a/src/ramstk/analyses/derating.py +++ /dev/null @@ -1,73 +0,0 @@ -# -*- coding: utf-8 -*- -# -# ramstk.analyses.derating.py is part of the RAMSTK Project -# -# All rights reserved. -# Copyright since 2007 Doyle "weibullguy" Rowland doyle.rowland reliaqual com -"""Component Derating Calculations Module.""" - - -def check_overstress(op_stress, limits): - """Check if an operating condition results in an overstressed condition. - - Checks if the operating stress is less than the lower limit or greater than - the upper limit. Limits and operating stresses may be integers or floats. - - >>> check_overstress(0.625, {'mild': [0.0, 0.9], 'harsh': [0.0, 0.75]}) - {'mild': [False, False], 'harsh': [False, False]} - >>> check_overstress(-0.625, {'mild': [0.0, 0.9], 'harsh': [0.0, 0.75]}) - {'mild': [True, False], 'harsh': [True, False]} - >>> check_overstress(0.825, {'mild': [0.0, 0.9], 'harsh': [0.0, 0.75]}) - {'mild': [False, False], 'harsh': [False, True]} - >>> check_overstress(0.825, {'mild': [0, 0.9], 'harsh': [0, 0.75]}) - {'mild': [False, False], 'harsh': [False, True]} - >>> check_overstress(1, {'mild': [0, 0.9], 'harsh': [0, 0.75]}) - {'mild': [False, True], 'harsh': [False, True]} - - Limits must be lists: - >>> check_overstress(0.825, {'mild': 0.9, 'harsh': 0.75}) - Traceback (most recent call last): - ... - TypeError: 'float' object is not subscriptable - - And those lists must contain a lower and upper limit: - check_overstress(0.825, {'mild': [0.9], 'harsh': [0.75]}) - Traceback (most recent call last): - ... - IndexError: list index out of range - - Limit values must not be strings: - check_overstress(0.825, {'mild': [0.0, '0.9'], 'harsh': [0.0, 0.75]}) - Traceback (most recent call last): - ... - TypeError: '>' not supported between instances of 'float' and 'str' - - The programmer must ensure the operating stress and limits are provided in - the proper format. For example: - - op_stress = (operating current / rated current) with limits provided as - decimals. - op_stress = (operating temperature - maximum junction temperature) with - limits provided as a delta T. - - :param op_stress: the level of the operating stress. - :param limits: a dict containing the stress limits. Key is the name - of the environment (mild, harsh, protected, etc.) and the value is a - list of [lower limit, upper limit]. - :return: _overstress; dict of indicators whether or not an overstress - condition exists. Key is the environment type (mild, harsh, protected, - etc.) and the value is a list of booleans for each limit. - :rtype: dict - :raise: IndexError if a limit value has too few items in the list. - :raise: TypeError if a limit value is not a list of numericals. - """ - _overstress = {} - - for key in limits: - _overstress[key] = [False, False] - if op_stress < limits[key][0]: - _overstress[key][0] = True - if op_stress > limits[key][1]: - _overstress[key][1] = True - - return _overstress diff --git a/src/ramstk/analyses/derating.pyi b/src/ramstk/analyses/derating.pyi deleted file mode 100644 index f309decd4..000000000 --- a/src/ramstk/analyses/derating.pyi +++ /dev/null @@ -1,4 +0,0 @@ -# Standard Library Imports -from typing import Any - -def check_overstress(op_stress: Any, limits: Any): ... diff --git a/src/ramstk/analyses/derating/__init__.py b/src/ramstk/analyses/derating/__init__.py new file mode 100644 index 000000000..e2aef80a6 --- /dev/null +++ b/src/ramstk/analyses/derating/__init__.py @@ -0,0 +1,16 @@ +# pylint: disable=unused-import +"""The Derating Analyses Package.""" + +# RAMSTK Local Imports +from . import derating +from .models import ( + capacitor, + connection, + inductor, + integratedcircuit, + lamp, + relay, + resistor, + semiconductor, + switch, +) diff --git a/src/ramstk/analyses/derating/derating.py b/src/ramstk/analyses/derating/derating.py new file mode 100644 index 000000000..42f2ed1a6 --- /dev/null +++ b/src/ramstk/analyses/derating/derating.py @@ -0,0 +1,154 @@ +# -*- coding: utf-8 -*- +# +# ramstk.analyses.derating.derating.py is part of the RAMSTK Project +# +# All rights reserved. +# Copyright since 2007 Doyle "weibullguy" Rowland doyle.rowland reliaqual com +"""Component Derating Calculations Module.""" + +# Standard Library Imports +from typing import Dict, List, Tuple + +# RAMSTK Local Imports +from .models import ( + capacitor, + connection, + inductor, + integratedcircuit, + lamp, + relay, + resistor, + semiconductor, + switch, +) + + +def do_check_overstress( + category: str, + environment_id: int, + subcategory_id: int, + stress_limits: Dict[str, Dict[str, Dict[str, Dict[str, List[float]]]]], + **kwargs, +) -> Tuple[int, str]: + """Perform a derating analysis. + + :param category: + :param environment_id: + :param subcategory_id: + :param stress_limits: + :return: _overstress, _reason + :rtype: tuple + :raise: KeyError if an unknown environment ID is passed. + :raise: KeyError if an unknown subcategory ID, quality ID, or type ID are passed. + :raise: TypeError if a non-numeric value is passed for the current ratio, + power ratio, junction temperature, or voltage ratio. + """ + _overstress: int = 0 + _reason: str = "" + + _environment: int = { + 1: 0, + 2: 1, + 3: 2, + 4: 0, + 5: 2, + 6: 1, + 7: 1, + 8: 2, + 9: 2, + 10: 1, + 11: 0, + 12: 1, + 13: 2, + }[environment_id] + + if category == "capacitor": + _overstress, _reason = capacitor.do_derating_analysis( + _environment, + subcategory_id, + stress_limits, + specification_id=kwargs.get("specification_id", 0), + temperature_case=kwargs.get("temperature_case", 30.0), + temperature_rated_max=kwargs.get("temperature_rated_max", 70.0), + voltage_ratio=kwargs.get("voltage_ratio", 0.0), + ) + elif category == "connection": + _overstress, _reason = connection.do_derating_analysis( + _environment, + stress_limits, + current_ratio=kwargs.get("current_ratio", 0.0), + temperature_hot_spot=kwargs.get("temperature_hot_spot", 30.0), + temperature_rated_max=kwargs.get("temperature_rated_max", 70.0), + voltage_ratio=kwargs.get("voltage_ratio", 0.0), + ) + elif category == "inductor": + _overstress, _reason = inductor.do_derating_analysis( + _environment, + subcategory_id, + stress_limits, + current_ratio=kwargs.get("current_ratio", 0.0), + family_id=kwargs.get("family_id", 0), + temperature_hot_spot=kwargs.get("temperature_hot_spot", 30.0), + temperature_rated_max=kwargs.get("temperature_rated_max", 70.0), + voltage_ratio=kwargs.get("voltage_ratio", 0.0), + ) + elif category == "integrated_circuit": + _overstress, _reason = integratedcircuit.do_derating_analysis( + _environment, + subcategory_id, + stress_limits, + current_ratio=kwargs.get("current_ratio", 0.0), + package_id=kwargs.get("package_id", 0), + technology_id=kwargs.get("technology_id", 0), + temperature_junction=kwargs.get("temperature_junction", 70.0), + ) + elif category == "miscellaneous": + _overstress, _reason = lamp.do_derating_analysis( + _environment, + subcategory_id, + stress_limits, + current_ratio=kwargs.get("current_ratio", 0.0), + ) + elif category == "relay": + _overstress, _reason = relay.do_derating_analysis( + _environment, + stress_limits, + current_ratio=kwargs.get("current_ratio", 0.0), + temperature_active=kwargs.get("temperature_active", 30.0), + temperature_rated_max=kwargs.get("temperature_rated_max", 85.0), + type_id=kwargs.get("type_id", 0), + ) + elif category == "resistor": + _overstress, _reason = resistor.do_derating_analysis( + _environment, + subcategory_id, + stress_limits, + power_rated=kwargs.get("power_rated", 0.0), + power_ratio=kwargs.get("power_ratio", 0.0), + temperature_case=kwargs.get("temperature_case", 30.0), + temperature_knee=kwargs.get("temperature_knee", 70.0), + temperature_rated_max=kwargs.get("temperature_rated_max", 150.0), + voltage_ratio=kwargs.get("voltage_ratio", 0.0), + ) + elif category == "semiconductor": + _overstress, _reason = semiconductor.do_derating_analysis( + _environment, + subcategory_id, + stress_limits, + current_ratio=kwargs.get("current_ratio", 0.0), + power_ratio=kwargs.get("power_ratio", 0.0), + quality_id=kwargs.get("quality_id", 1), + temperature_junction=kwargs.get("temperature_junction", 70.0), + type_id=kwargs.get("type_id", 0), + voltage_ratio=kwargs.get("voltage_ratio", 0.0), + ) + elif category == "switch": + _overstress, _reason = switch.do_derating_analysis( + _environment, + stress_limits, + application_id=kwargs.get("application_id", 0), + current_ratio=kwargs.get("current_ratio", 0.0), + power_ratio=kwargs.get("power_ratio", 0.0), + ) + + return _overstress, _reason diff --git a/src/ramstk/analyses/derating/derating.pyi b/src/ramstk/analyses/derating/derating.pyi new file mode 100644 index 000000000..69b8e0861 --- /dev/null +++ b/src/ramstk/analyses/derating/derating.pyi @@ -0,0 +1,21 @@ +# Standard Library Imports +from typing import Dict, List, Tuple + +# RAMSTK Local Imports +from .models import capacitor as capacitor +from .models import connection as connection +from .models import inductor as inductor +from .models import integratedcircuit as integratedcircuit +from .models import lamp as lamp +from .models import relay as relay +from .models import resistor as resistor +from .models import semiconductor as semiconductor +from .models import switch as switch + +def do_check_overstress( + category: str, + environment_id: int, + subcategory_id: int, + stress_limits: Dict[str, Dict[str, Dict[str, Dict[str, List[float]]]]], + **kwargs, +) -> Tuple[int, str]: ... diff --git a/src/ramstk/analyses/derating/models/__init__.py b/src/ramstk/analyses/derating/models/__init__.py new file mode 100644 index 000000000..a6650ca90 --- /dev/null +++ b/src/ramstk/analyses/derating/models/__init__.py @@ -0,0 +1,2 @@ +# pylint: disable=unused-import +"""The RAMSTK Derating Analyses Models Package.""" diff --git a/src/ramstk/analyses/derating/models/capacitor.py b/src/ramstk/analyses/derating/models/capacitor.py new file mode 100644 index 000000000..75b85fe3c --- /dev/null +++ b/src/ramstk/analyses/derating/models/capacitor.py @@ -0,0 +1,125 @@ +# -*- coding: utf-8 -*- +# +# ramstk.analyses.derating.models.capacitor.py is part of the RAMSTK Project +# +# All rights reserved. +# Copyright since 2017 Doyle "weibullguy" Rowland doyle.rowland reliaqual com +"""Capacitor derating analysis functions.""" + +# Standard Library Imports +from typing import Dict, List, Tuple + + +def do_derating_analysis( + environment_id: int, + subcategory_id: int, + stress_limits: Dict[str, Dict[str, List[float]]], + **kwargs, +) -> Tuple[int, str]: + """Check actual stresses against derating criteria for capacitors. + + :param environment_id: the index for the environment the capacitor + is operating in; 0=protected, 1=normal, 2=severe. + :param subcategory_id: the subcategory ID of the capacitor to check + derating. + :param stress_limits: the dict containing the stress derating limits for + capacitors. + :return: _overstress, _reason + :rtype: tuple + :raise: IndexError if an unknown environment ID is passed. + :raise: KeyError if an unknown subcategory ID, quality ID, or type ID are passed. + :raise: TypeError if a non-numeric value is passed for the current ratio, + power ratio, junction temperature, or voltage ratio. + """ + _overstress: int = 0 + _reason: str = "" + + _subcategory = { + 1: "paper", + 2: "paper", + 3: "plastic", + 4: "metallized", + 5: "metallized", + 6: "metallized", + 7: "mica", + 8: "mica_button", + 9: "glass", + 10: "ceramic_fixed", + 11: { + 1: "temp_comp_ceramic", + 2: "ceramic_chip", + }, + 12: { + 1: "tantalum_solid", + 2: "tantalum_chip", + }, + 13: "tantalum_wet", + 14: "aluminum", + 15: "aluminum_dry", + 16: "ceramic_variable", + 17: "piston", + 18: "trimmer", + 19: "vacuum", + }[subcategory_id] + if isinstance(_subcategory, dict): + _subcategory = _subcategory[kwargs["specification_id"]] + + _overstress, _reason = _do_check_temperature_limit( + kwargs["temperature_case"], + kwargs["temperature_rated_max"], + stress_limits[_subcategory]["temperature"][environment_id], + ) + + _ostress, _rsn = _do_check_voltage_limit( + kwargs["voltage_ratio"], + stress_limits[_subcategory]["voltage"][environment_id], + ) + _overstress = _overstress or _ostress + _reason += _rsn + + return _overstress, _reason + + +def _do_check_temperature_limit( + case_temperature: float, + max_rated_temperature: float, + temperature_limit: float, +) -> Tuple[int, str]: + """Check if the case temperature exceeds the limit. + + :param case_temperature: + :param max_rated_temperature: + :param temperature_limit: + :return: _overstress, _reason + :rtype: tuple + """ + if case_temperature <= (max_rated_temperature - temperature_limit): + return 0, "" + + return ( + 1, + f"Case temperature of {case_temperature}C exceeds the derated maximum " + f"temperature of {temperature_limit}C less than maximum rated temperature " + f"of {max_rated_temperature}C.\n", + ) + + +def _do_check_voltage_limit( + voltage_ratio: float, + voltage_limit: float, +) -> Tuple[int, str]: + """Check if the voltage ratio exceeds the limit. + + :param voltage_ratio: + :param voltage_limit: + :return: _overstress, _reason + :rtype: tuple + """ + if voltage_ratio <= voltage_limit: + return 0, "" + + return ( + 1, + f"Voltage ratio of {voltage_ratio} exceeds the allowable limit of " + f"{voltage_limit}.\n", + ) diff --git a/src/ramstk/analyses/derating/models/capacitor.pyi b/src/ramstk/analyses/derating/models/capacitor.pyi new file mode 100644 index 000000000..38dd0b410 --- /dev/null +++ b/src/ramstk/analyses/derating/models/capacitor.pyi @@ -0,0 +1,15 @@ +# Standard Library Imports +from typing import Dict, List, Tuple + +def do_derating_analysis( + environment_id: int, + subcategory_id: int, + stress_limits: Dict[str, Dict[str, List[float]]], + **kwargs, +) -> Tuple[int, str]: ... +def _do_check_temperature_limit( + case_temperature: float, max_rated_temperature: float, temperature_limit: float +) -> Tuple[int, str]: ... +def _do_check_voltage_limit( + voltage_ratio: float, voltage_limit: float +) -> Tuple[int, str]: ... diff --git a/src/ramstk/analyses/derating/models/connection.py b/src/ramstk/analyses/derating/models/connection.py new file mode 100644 index 000000000..d75d220c2 --- /dev/null +++ b/src/ramstk/analyses/derating/models/connection.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# +# ramstk.analyses.derating.models.connection.py is part of the RAMSTK Project +# +# All rights reserved. +# Copyright since 2017 Doyle "weibullguy" Rowland doyle.rowland reliaqual com +"""Connection derating analysis functions.""" + +# Standard Library Imports +from typing import Dict, List, Tuple + + +def do_derating_analysis( + environment_id: int, + stress_limits: Dict[str, List[float]], + **kwargs, +) -> Tuple[int, str]: + """Check actual stresses against derating criteria for connections. + + :param environment_id: the index for the environment the connection + is operating in; 0=protected, 1=normal, 2=severe. + :param stress_limits: the dict containing the stress derating limits for + connections. + :return: _overstress, _reason + :rtype: tuple + :raise: IndexError if an unknown environment ID is passed. + :raise: TypeError if a non-numeric value is passed for the current ratio. + """ + return _do_check_current_limit( + kwargs["current_ratio"], + stress_limits["current"][environment_id], + ) + + +def _do_check_current_limit( + current_ratio: float, + current_limit: float, +) -> Tuple[int, str]: + """Check if the current ratio exceeds the limit. + + :param current_ratio: + :param current_limit: + :return: _overstress, _reason + :rtype: tuple + """ + if current_ratio <= current_limit: + return 0, "" + + return ( + 1, + f"Current ratio of {current_ratio} exceeds the allowable limit of " + f"{current_limit}.\n", + ) diff --git a/src/ramstk/analyses/derating/models/connection.pyi b/src/ramstk/analyses/derating/models/connection.pyi new file mode 100644 index 000000000..131ed8c5d --- /dev/null +++ b/src/ramstk/analyses/derating/models/connection.pyi @@ -0,0 +1,9 @@ +# Standard Library Imports +from typing import Dict, List, Tuple + +def do_derating_analysis( + environment_id: int, stress_limits: Dict[str, List[float]], **kwargs +) -> Tuple[int, str]: ... +def _do_check_current_limit( + current_ratio: float, current_limit: float +) -> Tuple[int, str]: ... diff --git a/src/ramstk/analyses/derating/models/inductor.py b/src/ramstk/analyses/derating/models/inductor.py new file mode 100644 index 000000000..3f39311e7 --- /dev/null +++ b/src/ramstk/analyses/derating/models/inductor.py @@ -0,0 +1,134 @@ +# -*- coding: utf-8 -*- +# +# ramstk.analyses.derating.models.inductor.py is part of the RAMSTK Project +# +# All rights reserved. +# Copyright since 2017 Doyle "weibullguy" Rowland doyle.rowland reliaqual com +"""Inductor derating analysis functions.""" + +# Standard Library Imports +from typing import Dict, List, Tuple + + +def do_derating_analysis( + environment_id: int, + subcategory_id: int, + stress_limits: Dict[str, Dict[str, List[float]]], + **kwargs, +) -> Tuple[int, str]: + """Check actual stresses against derating criteria for inductors. + + :param environment_id: the index for the environment the inductor is operating + in; 0=protected, 1=normal, 2=severe. + :param subcategory_id: the subcategory ID of the indcutor to check derating. + :param stress_limits: the dict containing the stress derating limits for inductors. + :return: _overstress, _reason + :rtype: tuple + :raise: IndexError if an unknown environment ID is passed. + :raise: KeyError if an unknown family ID is passed. + :raise: TypeError if a non-numeric value is passed for the current ratio, hot spot + temperature, or voltage ratio. + """ + _overstress: int = 0 + _reason: str = "" + + _frequency = { + 1: { + 1: "low_frequency", + 2: "low_frequency", + 3: "low_frequency", + 4: "high_frequency", + }, + 2: "high_frequency", + }[subcategory_id] + if isinstance(_frequency, dict): + _frequency = _frequency[kwargs["family_id"]] + + _overstress, _reason = _do_check_current_limit( + kwargs["current_ratio"], + stress_limits[_frequency]["current"][environment_id], + ) + + _ostress, _rsn = _do_check_temperature_limit( + kwargs["temperature_hot_spot"], + kwargs["temperature_rated_max"], + stress_limits[_frequency]["temperature"][environment_id], + ) + _overstress = _overstress or _ostress + _reason += _rsn + + if _frequency == "low_frequency": + _ostress, _rsn = _do_check_voltage_limit( + kwargs["voltage_ratio"], + stress_limits[_frequency]["voltage"][environment_id], + ) + _overstress = _overstress or _ostress + _reason += _rsn + + return _overstress, _reason + + +def _do_check_current_limit( + current_ratio: float, + current_limit: float, +) -> Tuple[int, str]: + """Check if the current ratio exceeds the limit. + + :param current_ratio: + :param current_limit: + :return: _overstress, _reason + :rtype: tuple + """ + if current_ratio <= current_limit: + return 0, "" + + return ( + 1, + f"Current ratio of {current_ratio} exceeds the allowable limit of " + f"{current_limit}.\n", + ) + + +def _do_check_temperature_limit( + hot_spot_temperature: float, + max_rated_temperature: float, + temperature_limit: float, +) -> Tuple[int, str]: + """Check if the hot spot temperature exceeds the limit. + + :param hot_spot_temperature: + :param max_rated_temperature: + :param temperature_limit: + :return: _overstress, _reason + :rtype: tuple + """ + if hot_spot_temperature <= (max_rated_temperature - temperature_limit): + return 0, "" + + return ( + 1, + f"Hot spot temperature of {hot_spot_temperature}C exceeds the derated " + f"maximum hot spot temperature of {temperature_limit}C less than maximum " + f"rated hot spot temperature of {max_rated_temperature}C.\n", + ) + + +def _do_check_voltage_limit( + voltage_ratio: float, + voltage_limit: float, +) -> Tuple[int, str]: + """Check if the voltage ratio exceeds the limit. + + :param voltage_ratio: + :param voltage_limit: + :return: _overstress, _reason + :rtype: tuple + """ + if voltage_ratio <= voltage_limit: + return 0, "" + + return ( + 1, + f"Voltage ratio of {voltage_ratio} exceeds the allowable limit of " + f"{voltage_limit}.\n", + ) diff --git a/src/ramstk/analyses/derating/models/inductor.pyi b/src/ramstk/analyses/derating/models/inductor.pyi new file mode 100644 index 000000000..c98ad3239 --- /dev/null +++ b/src/ramstk/analyses/derating/models/inductor.pyi @@ -0,0 +1,18 @@ +# Standard Library Imports +from typing import Dict, List, Tuple + +def do_derating_analysis( + environment_id: int, + subcategory_id: int, + stress_limits: Dict[str, Dict[str, List[float]]], + **kwargs, +) -> Tuple[int, str]: ... +def _do_check_current_limit( + current_ratio: float, current_limit: float +) -> Tuple[int, str]: ... +def _do_check_temperature_limit( + hot_spot_temperature: float, max_rated_temperature: float, temperature_limit: float +) -> Tuple[int, str]: ... +def _do_check_voltage_limit( + voltage_ratio: float, voltage_limit: float +) -> Tuple[int, str]: ... diff --git a/src/ramstk/analyses/derating/models/integratedcircuit.py b/src/ramstk/analyses/derating/models/integratedcircuit.py new file mode 100644 index 000000000..af2f7c79e --- /dev/null +++ b/src/ramstk/analyses/derating/models/integratedcircuit.py @@ -0,0 +1,117 @@ +# -*- coding: utf-8 -*- +# +# ramstk.analyses.derating.models.integratedcircuit.py is part of the RAMSTK +# Project +# +# All rights reserved. +# Copyright since 2017 Doyle "weibullguy" Rowland doyle.rowland reliaqual com +"""Integrated Circuit derating analysis functions.""" + +# Standard Library Imports +from typing import Dict, List, Tuple + + +def do_derating_analysis( + environment_id: int, + subcategory_id: int, + stress_limits: Dict[str, Dict[str, Dict[str, Dict[str, List[float]]]]], + **kwargs, +) -> Tuple[int, str]: + """Check actual stresses against derating criteria for integrated circuits. + + :param environment_id: the index for the environment the integrated circuit + is operating in; 0=protected, 1=normal, 2=severe. + :param subcategory_id: the subcategory ID of the integrated circuit to check + derating. + :param stress_limits: the dict containing the stress derating limits for + integrated circuits. + :return: _overstress, _reason + :rtype: tuple + :raise: IndexError if an unknown environment ID is passed. + :raise: KeyError if an unknown subcategory ID, package ID, or technology ID are + passed. + :raise: TypeError if a non-numeric value is passed for the current ratio or junction + temperature. + """ + _overstress: int = 0 + _reason: str = "" + + _subcategory = { + 1: "digital", + 2: "linear", + 3: "microprocessor", + 4: "memory", + }[subcategory_id] + _technology = { + 1: "bipolar", + 2: "mos", + }[kwargs["technology_id"]] + _package = { + 1: "hermetic", + 2: "hermetic", + 3: "hermetic", + 4: "plastic1", + 5: "plastic1", + 6: "plastic1", + 7: "plastic2", + 8: "plastic2", + 9: "plastic2", + }[kwargs["package_id"]] + + _overstress, _reason = _do_check_current_limit( + kwargs["current_ratio"], + stress_limits[_subcategory][_technology][_package]["current"][environment_id], + ) + + _ostress, _rsn = _do_check_temperature_limit( + kwargs["temperature_junction"], + stress_limits[_subcategory][_technology][_package]["temperature"][ + environment_id + ], + ) + _overstress = _overstress or _ostress + _reason += _rsn + + return _overstress, _reason + + +def _do_check_current_limit( + current_ratio: float, + current_limit: float, +) -> Tuple[int, str]: + """Check if the current ratio exceeds the limit. + + :param current_ratio: + :param current_limit: + :return: _overstress, _reason + :rtype: tuple + """ + if current_ratio <= current_limit: + return 0, "" + + return ( + 1, + f"Current ratio of {current_ratio} exceeds the allowable limit of " + f"{current_limit}.\n", + ) + + +def _do_check_temperature_limit( + junction_temperature: float, + temperature_limit: float, +) -> Tuple[int, str]: + """Check if the junction temperature exceeds the limit. + + :param junction_temperature: + :param temperature_limit: + :return: _overstress, _reason + :rtype: tuple + """ + if junction_temperature <= temperature_limit: + return 0, "" + + return ( + 1, + f"Junction temperature of {junction_temperature}C exceeds the allowable " + f"limit of {temperature_limit}C.\n", + ) diff --git a/src/ramstk/analyses/derating/models/integratedcircuit.pyi b/src/ramstk/analyses/derating/models/integratedcircuit.pyi new file mode 100644 index 000000000..0884e6528 --- /dev/null +++ b/src/ramstk/analyses/derating/models/integratedcircuit.pyi @@ -0,0 +1,15 @@ +# Standard Library Imports +from typing import Dict, List, Tuple + +def do_derating_analysis( + environment_id: int, + subcategory_id: int, + stress_limits: Dict[str, Dict[str, Dict[str, Dict[str, List[float]]]]], + **kwargs, +) -> Tuple[int, str]: ... +def _do_check_current_limit( + current_ratio: float, current_limit: float +) -> Tuple[int, str]: ... +def _do_check_temperature_limit( + junction_temperature: float, temperature_limit: float +) -> Tuple[int, str]: ... diff --git a/src/ramstk/analyses/derating/models/lamp.py b/src/ramstk/analyses/derating/models/lamp.py new file mode 100644 index 000000000..74ea226c1 --- /dev/null +++ b/src/ramstk/analyses/derating/models/lamp.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +# +# ramstk.analyses.derating.models.lamp.py is part of the RAMSTK Project +# +# All rights reserved. +# Copyright since 2017 Doyle "weibullguy" Rowland doyle.rowland reliaqual com +"""Capacitor derating analysis functions.""" + +# Standard Library Imports +from typing import Dict, List, Tuple + + +def do_derating_analysis( + environment_id: int, + subcategory_id: int, + stress_limits: Dict[str, Dict[str, List[float]]], + **kwargs, +) -> Tuple[int, str]: + """Check actual stresses against derating criteria for lamps. + + :param environment_id: the index for the environment the lamp + is operating in; 0=protected, 1=normal, 2=severe. + :param subcategory_id: the subcategory ID of the lamp to check + derating. + :param stress_limits: the dict containing the stress derating limits for + lamps. + :return: _overstress, _reason + :rtype: tuple + :raise: IndexError if an unknown environment ID is passed. + :raise: KeyError if an unknown subcategory ID is passed. + :raise: TypeError if a non-numeric value is passed for the current ratio. + """ + _subcategory = { + 4: "lamp", + }[subcategory_id] + + return _do_check_current_limit( + kwargs["current_ratio"], + stress_limits[_subcategory]["current"][environment_id], + ) + + +def _do_check_current_limit( + current_ratio: float, + current_limit: float, +) -> Tuple[int, str]: + """Check if the current ratio exceeds the limit. + + :param current_ratio: + :param current_limit: + :return: _overstress, _reason + :rtype: tuple + """ + if current_ratio <= current_limit: + return 0, "" + + return ( + 1, + f"Current ratio of {current_ratio} exceeds the allowable limit of " + f"{current_limit}.\n", + ) diff --git a/src/ramstk/analyses/derating/models/lamp.pyi b/src/ramstk/analyses/derating/models/lamp.pyi new file mode 100644 index 000000000..fbbe581bc --- /dev/null +++ b/src/ramstk/analyses/derating/models/lamp.pyi @@ -0,0 +1,12 @@ +# Standard Library Imports +from typing import Dict, List, Tuple + +def do_derating_analysis( + environment_id: int, + subcategory_id: int, + stress_limits: Dict[str, Dict[str, List[float]]], + **kwargs, +) -> Tuple[int, str]: ... +def _do_check_current_limit( + current_ratio: float, current_limit: float +) -> Tuple[int, str]: ... diff --git a/src/ramstk/analyses/derating/models/relay.py b/src/ramstk/analyses/derating/models/relay.py new file mode 100644 index 000000000..fa0111455 --- /dev/null +++ b/src/ramstk/analyses/derating/models/relay.py @@ -0,0 +1,97 @@ +# -*- coding: utf-8 -*- +# +# ramstk.analyses.derating.models.relay.py is part of the RAMSTK Project +# +# All rights reserved. +# Copyright since 2017 Doyle "weibullguy" Rowland doyle.rowland reliaqual com +"""Capacitor derating analysis functions.""" + +# Standard Library Imports +from typing import Dict, List, Tuple + + +def do_derating_analysis( + environment_id: int, + stress_limits: Dict[str, Dict[str, List[float]]], + **kwargs, +) -> Tuple[int, str]: + """Check actual stresses against derating criteria for relays. + + :param environment_id: the index for the environment the relay + is operating in; 0=protected, 1=normal, 2=severe. + :param stress_limits: the dict containing the stress derating limits for + relays. + :return: _overstress, _reason + :rtype: tuple + :raise: IndexError if an unknown environment ID is passed. + :raise: KeyError if an unknown type ID is passed. + :raise: TypeError if a non-numeric value is passed for the current ratio. + """ + _overstress: int = 0 + _reason: str = "" + + _type = { + 1: "resistive_load", + 2: "inductive_load", + 3: "capacitive_load", + }[kwargs["type_id"]] + + _overstress, _reason = _do_check_current_limit( + kwargs["current_ratio"], + stress_limits[_type]["current"][environment_id], + ) + + _ostress, _rsn = _do_check_temperature_limit( + kwargs["temperature_active"], + kwargs["temperature_rated_max"], + stress_limits[_type]["temperature"][environment_id], + ) + _overstress = _overstress or _ostress + _reason += _rsn + + return _overstress, _reason + + +def _do_check_current_limit( + current_ratio: float, + current_limit: float, +) -> Tuple[int, str]: + """Check if the current ratio exceeds the limit. + + :param current_ratio: + :param current_limit: + :return: _overstress, _reason + :rtype: tuple + """ + if current_ratio <= current_limit: + return 0, "" + + return ( + 1, + f"Current ratio of {current_ratio} exceeds the allowable limit of " + f"{current_limit}.\n", + ) + + +def _do_check_temperature_limit( + active_temperature: float, + max_rated_temperature: float, + temperature_limit: float, +) -> Tuple[int, str]: + """Check if the relay temperature exceeds the limit. + + :param active_temperature: + :param max_rated_temperature: + :param temperature_limit: + :return: _overstress, _reason + :rtype: tuple + """ + if active_temperature <= (max_rated_temperature - temperature_limit): + return 0, "" + + return ( + 1, + f"Ambient temperature of {active_temperature}C exceeds the derated maximum " + f"temperature of {temperature_limit}C less than maximum rated temperature " + f"of {max_rated_temperature}C.\n", + ) diff --git a/src/ramstk/analyses/derating/models/relay.pyi b/src/ramstk/analyses/derating/models/relay.pyi new file mode 100644 index 000000000..1240a79c3 --- /dev/null +++ b/src/ramstk/analyses/derating/models/relay.pyi @@ -0,0 +1,12 @@ +# Standard Library Imports +from typing import Dict, List, Tuple + +def do_derating_analysis( + environment_id: int, stress_limits: Dict[str, Dict[str, List[float]]], **kwargs +) -> Tuple[int, str]: ... +def _do_check_current_limit( + current_ratio: float, current_limit: float +) -> Tuple[int, str]: ... +def _do_check_temperature_limit( + active_temperature: float, max_rated_temperature: float, temperature_limit: float +) -> Tuple[int, str]: ... diff --git a/src/ramstk/analyses/derating/models/resistor.py b/src/ramstk/analyses/derating/models/resistor.py new file mode 100644 index 000000000..197b890a8 --- /dev/null +++ b/src/ramstk/analyses/derating/models/resistor.py @@ -0,0 +1,240 @@ +# -*- coding: utf-8 -*- +# +# ramstk.analyses.derating.models.resistor.py is part of the RAMSTK Project +# +# All rights reserved. +# Copyright since 2017 Doyle "weibullguy" Rowland doyle.rowland reliaqual com +"""Capacitor derating analysis functions.""" + +# Standard Library Imports +from typing import Dict, List, Tuple + + +def do_derating_analysis( + environment_id: int, + subcategory_id: int, + stress_limits: Dict[str, Dict[str, Dict[str, List[float]]]], + **kwargs, +) -> Tuple[int, str]: + """Check actual stresses against derating criteria for resistors. + + :param environment_id: the index for the environment the resistor + is operating in; 0=protected, 1=normal, 2=severe. + :param subcategory_id: the subcategory ID of the resistor to check + derating. + :param stress_limits: the dict containing the stress derating limits for + resistors. + :return: _overstress, _reason + :rtype: tuple + :raise: IndexError if an unknown environment ID is passed. + :raise: KeyError if an unknown subcategory ID is passed. + :raise: TypeError if a non-numeric value is passed for the power ratio, rated power, + case temperature, knee temperature, rated temperature, or voltage ratio. + """ + _overstress: int = 0 + _reason: str = "" + + _subcategory = { + 1: "fixed_composition", + 2: "fixed_film", + 3: "fixed_film_power", + 4: "ixed_film_network", + 5: "fixed_wirewound", + 6: "fixed_wirewound_power", + 7: "fixed_wirewound_chassis", + 8: "thermistor", + 9: "variable_wirewound", + 10: "variable_wirewound_precision", + 11: "variable_wirewound", + 12: "variable_wirewound_power", + 13: "variable_non_wirewound", + 14: "variable_composition", + 15: "variable_film", + }[subcategory_id] + + _power_limit = _do_get_power_limit( + _subcategory, + environment_id, + kwargs["power_rated"], + stress_limits, + ) + _overstress, _reason = _do_check_power_limit( + kwargs["power_ratio"], + _power_limit, + ) + + _temperature_limit = _do_get_temperature_limit( + _subcategory, + environment_id, + kwargs["power_rated"], + stress_limits, + ) + _ostress, _rsn = _do_check_temperature_limit( + kwargs["temperature_case"], + kwargs["temperature_knee"], + kwargs["temperature_rated_max"], + _temperature_limit, + ) + _overstress = _overstress or _ostress + _reason += _rsn + + if subcategory_id in {2, 4, 5, 6, 7}: + _voltage_limit = _do_get_voltage_limit( + _subcategory, + environment_id, + kwargs["power_rated"], + stress_limits, + ) + _ostress, _rsn = _do_check_voltage_limit( + kwargs["voltage_ratio"], + _voltage_limit, + ) + _overstress = _overstress or _ostress + _reason += _rsn + + return _overstress, _reason + + +def _do_check_power_limit( + power_ratio: float, + power_limit: float, +) -> Tuple[int, str]: + """Check if the power ratio exceeds the limit. + + :param power_ratio: + :param power_limit: + :return: _overstress, _reason + :rtype: tuple + """ + if power_ratio <= power_limit: + return 0, "" + + return ( + 1, + f"Power ratio of {power_ratio} exceeds the allowable limit of " + f"{power_limit}.\n", + ) + + +def _do_check_temperature_limit( + case_temperature: float, + knee_temperature: float, + max_rated_temperature: float, + temperature_limit: float, +) -> Tuple[int, str]: + """Check if the case temperature exceeds the limit. + + :param case_temperature: + :param max_rated_temperature: + :param temperature_limit: + :return: _overstress, _reason + :rtype: tuple + """ + _max_temperature: float = knee_temperature + temperature_limit * ( + max_rated_temperature - knee_temperature + ) + + if case_temperature <= _max_temperature: + return 0, "" + + return ( + 1, + f"Case temperature of {case_temperature}C exceeds the derated maximum " + f"temperature of {_max_temperature}C.\n", + ) + + +def _do_check_voltage_limit( + voltage_ratio: float, + voltage_limit: float, +) -> Tuple[int, str]: + """Check if the voltage ratio exceeds the limit. + + :param voltage_ratio: + :param voltage_limit: + :return: _overstress, _reason + :rtype: tuple + """ + if voltage_ratio <= voltage_limit: + return 0, "" + + return ( + 1, + f"Voltage ratio of {voltage_ratio} exceeds the allowable limit of " + f"{voltage_limit}.\n", + ) + + +def _do_get_power_limit( + subcategory: str, + environment_id: int, + rated_power: float, + stress_limits: Dict[str, Dict[str, Dict[str, List[float]]]], +) -> float: + """Retrieve the power limits. + + :param subcategory: + :param environment_id: + :param rated_power: + :param stress_limits: + :return: _power_limit + :rtype: float + """ + if subcategory in {"fixed_composition", "fixed_film", "fixed_wirewound"}: + return ( + stress_limits[subcategory]["high_power"]["power"][environment_id] + if rated_power >= 0.5 + else stress_limits[subcategory]["low_power"]["power"][environment_id] + ) + + return stress_limits[subcategory]["power"][environment_id] + + +def _do_get_temperature_limit( + subcategory: str, + environment_id: int, + rated_power: float, + stress_limits: Dict[str, Dict[str, Dict[str, List[float]]]], +) -> float: + """Retrieve the power limits. + + :param subcategory: + :param environment_id: + :param rated_power: + :param stress_limits: + :return: _temperature_limit + :rtype: float + """ + if subcategory in {"fixed_composition", "fixed_film", "fixed_wirewound"}: + return ( + stress_limits[subcategory]["high_power"]["temperature"][environment_id] + if rated_power >= 0.5 + else stress_limits[subcategory]["low_power"]["temperature"][environment_id] + ) + + return stress_limits[subcategory]["temperature"][environment_id] + + +def _do_get_voltage_limit( + subcategory: str, + environment_id: int, + rated_power: float, + stress_limits: Dict[str, Dict[str, Dict[str, List[float]]]], +) -> float: + """Retrieve the power limits. + + :param subcategory: + :param environment_id: + :param rated_power: + :param stress_limits: + :return: _voltage_limit + :rtype: float + """ + if subcategory in {"fixed_composition", "fixed_film", "fixed_wirewound"}: + return ( + stress_limits[subcategory]["high_power"]["voltage"][environment_id] + if rated_power >= 0.5 + else stress_limits[subcategory]["low_power"]["voltage"][environment_id] + ) + + return stress_limits[subcategory]["voltage"][environment_id] diff --git a/src/ramstk/analyses/derating/models/resistor.pyi b/src/ramstk/analyses/derating/models/resistor.pyi new file mode 100644 index 000000000..562f270ea --- /dev/null +++ b/src/ramstk/analyses/derating/models/resistor.pyi @@ -0,0 +1,39 @@ +# Standard Library Imports +from typing import Dict, List, Tuple + +def do_derating_analysis( + environment_id: int, + subcategory_id: int, + stress_limits: Dict[str, Dict[str, Dict[str, List[float]]]], + **kwargs, +) -> Tuple[int, str]: ... +def _do_check_power_limit( + power_ratio: float, power_limit: float +) -> Tuple[int, str]: ... +def _do_check_temperature_limit( + case_temperature: float, + knee_temperature: float, + max_rated_temperature: float, + temperature_limit: float, +) -> Tuple[int, str]: ... +def _do_check_voltage_limit( + voltage_ratio: float, voltage_limit: float +) -> Tuple[int, str]: ... +def _do_get_power_limit( + subcategory: str, + environment_id: int, + rated_power: float, + stress_limits: Dict[str, Dict[str, Dict[str, List[float]]]], +) -> float: ... +def _do_get_temperature_limit( + subcategory: str, + environment_id: int, + rated_power: float, + stress_limits: Dict[str, Dict[str, Dict[str, List[float]]]], +) -> float: ... +def _do_get_voltage_limit( + subcategory: str, + environment_id: int, + rated_power: float, + stress_limits: Dict[str, Dict[str, Dict[str, List[float]]]], +) -> float: ... diff --git a/src/ramstk/analyses/derating/models/semiconductor.py b/src/ramstk/analyses/derating/models/semiconductor.py new file mode 100644 index 000000000..81cee4b1d --- /dev/null +++ b/src/ramstk/analyses/derating/models/semiconductor.py @@ -0,0 +1,188 @@ +# -*- coding: utf-8 -*- +# +# ramstk.analyses.derating.models.semiconductor.py is part of the RAMSTK Project +# +# All rights reserved. +# Copyright since 2017 Doyle "weibullguy" Rowland doyle.rowland reliaqual com +"""Semiconductor derating analysis functions.""" + +# Standard Library Imports +from typing import Dict, List, Tuple + + +def do_derating_analysis( + environment_id: int, + subcategory_id: int, + stress_limits: Dict[str, Dict[str, Dict[str, Dict[str, List[float]]]]], + **kwargs, +) -> Tuple[int, str]: + """Check actual stresses against derating criteria for semiconductors. + + :param environment_id: the index for the environment the semiconductor + is operating in; 0=protected, 1=normal, 2=severe. + :param subcategory_id: the subcategory ID of the semiconductor to check + derating. + :param stress_limits: the dict containing the stress derating limits for + semiconductors. + :return: _overstress, _reason + :rtype: tuple + :raise: IndexError if an unknown environment ID is passed. + :raise: KeyError if an unknown subcategory ID, quality ID, or type ID are passed. + :raise: TypeError if a non-numeric value is passed for the current ratio, + power ratio, junction temperature, or voltage ratio. + """ + _overstress: int = 0 + _reason: str = "" + + _subcategory = { + 1: "diode", + 3: "transistor", + 4: "transistor", + 6: "transistor", + 7: "transistor", + 8: "transistor", + 9: "transistor", + 10: "thyristor", + }[subcategory_id] + _type = { + 1: { + 1: "general_purpose", + 2: "general_purpose", + 3: "power_rectifier", + 4: "schottky", + 5: "power_rectifier", + 6: "suppressor", + 7: "regulator", + 8: "regulator", + }, + 3: "bjt", + 4: "fet", + 6: "bjt", + 7: "bjt", + 9: "fet", + }[subcategory_id] + if isinstance(_type, dict): + _type = _type[kwargs["type_id"]] + + _quality = { + 1: "jantx", + 2: "jantx", + 3: "military", + 4: "commercial", + 5: "commercial", + }[kwargs["quality_id"]] + + _overstress, _reason = _do_check_current_limit( + kwargs["current_ratio"], + stress_limits[_subcategory][_type][_quality]["current"][environment_id], + ) + + if ( + _subcategory == "diode" and _type in ["schottky,", "regulator", "suppressor"] + ) or _subcategory == "transistor": + _ostress, _rsn = _do_check_power_limit( + kwargs["power_ratio"], + stress_limits[_subcategory][_type][_quality]["power"][environment_id], + ) + _overstress = _overstress or _ostress + _reason += _rsn + + _ostress, _rsn = _do_check_temperature_limit( + kwargs["temperature_junction"], + stress_limits[_subcategory][_type][_quality]["temperature"][environment_id], + ) + _overstress = _overstress or _ostress + _reason += _rsn + + _ostress, _rsn = _do_check_voltage_limit( + kwargs["voltage_ratio"], + stress_limits[_subcategory][_type][_quality]["voltage"][environment_id], + ) + _overstress = _overstress or _ostress + _reason += _rsn + + return _overstress, _reason + + +def _do_check_current_limit( + current_ratio: float, + current_limit: float, +) -> Tuple[int, str]: + """Check if the current ratio exceeds the limit. + + :param current_ratio: + :param current_limit: + :return: _overstress, _reason + :rtype: tuple + """ + if current_ratio <= current_limit: + return 0, "" + + return ( + 1, + f"Current ratio of {current_ratio} exceeds the allowable limit of " + f"{current_limit}.\n", + ) + + +def _do_check_power_limit( + power_ratio: float, + power_limit: float, +) -> Tuple[int, str]: + """Check if the power ratio exceeds the limit. + + :param power_ratio: + :param power_limit: + :return: _overstress, _reason + :rtype: tuple + """ + if power_ratio <= power_limit: + return 0, "" + + return ( + 1, + f"Power ratio of {power_ratio} exceeds the allowable limit of " + f"{power_limit}.\n", + ) + + +def _do_check_temperature_limit( + junction_temperature: float, + temperature_limit: float, +) -> Tuple[int, str]: + """Check if the junction temperature exceeds the limit. + + :param junction_temperature: + :param temperature_limit: + :return: _overstress, _reason + :rtype: tuple + """ + if junction_temperature <= temperature_limit: + return 0, "" + + return ( + 1, + f"Junction temperature of {junction_temperature}C exceeds the allowable " + f"limit of {temperature_limit}C.\n", + ) + + +def _do_check_voltage_limit( + voltage_ratio: float, + voltage_limit: float, +) -> Tuple[int, str]: + """Check if the voltage ratio exceeds the limit. + + :param voltage_ratio: + :param voltage_limit: + :return: _overstress, _reason + :rtype: tuple + """ + if voltage_ratio <= voltage_limit: + return 0, "" + + return ( + 1, + f"Voltage ratio of {voltage_ratio} exceeds the allowable limit of " + f"{voltage_limit}.\n", + ) diff --git a/src/ramstk/analyses/derating/models/semiconductor.pyi b/src/ramstk/analyses/derating/models/semiconductor.pyi new file mode 100644 index 000000000..4d0d42d0d --- /dev/null +++ b/src/ramstk/analyses/derating/models/semiconductor.pyi @@ -0,0 +1,21 @@ +# Standard Library Imports +from typing import Dict, List, Tuple + +def do_derating_analysis( + environment_id: int, + subcategory_id: int, + stress_limits: Dict[str, Dict[str, Dict[str, Dict[str, List[float]]]]], + **kwargs, +) -> Tuple[int, str]: ... +def _do_check_current_limit( + current_ratio: float, current_limit: float +) -> Tuple[int, str]: ... +def _do_check_power_limit( + power_ratio: float, power_limit: float +) -> Tuple[int, str]: ... +def _do_check_temperature_limit( + junction_temperature: float, temperature_limit: float +) -> Tuple[int, str]: ... +def _do_check_voltage_limit( + voltage_ratio: float, voltage_limit: float +) -> Tuple[int, str]: ... diff --git a/src/ramstk/analyses/derating/models/switch.py b/src/ramstk/analyses/derating/models/switch.py new file mode 100644 index 000000000..e144ede32 --- /dev/null +++ b/src/ramstk/analyses/derating/models/switch.py @@ -0,0 +1,94 @@ +# -*- coding: utf-8 -*- +# +# ramstk.analyses.derating.models.switch.py is part of the RAMSTK Project +# +# All rights reserved. +# Copyright since 2017 Doyle "weibullguy" Rowland doyle.rowland reliaqual com +"""Capacitor derating analysis functions.""" + +# Standard Library Imports +from typing import Dict, List, Tuple + + +def do_derating_analysis( + environment_id: int, + stress_limits: Dict[str, Dict[str, List[float]]], + **kwargs, +) -> Tuple[int, str]: + """Check actual stresses against derating criteria for switchs. + + :param environment_id: the index for the environment the switch + is operating in; 0=protected, 1=normal, 2=severe. + :param stress_limits: the dict containing the stress derating limits for + switchs. + :return: _overstress, _reason + :rtype: tuple + :raise: IndexError if an unknown environment ID is passed. + :raise: KeyError if an unknown application ID is passed. + :raise: TypeError if a non-numeric value is passed for the current ratio or power + ratio. + """ + _overstress: int = 0 + _reason: str = "" + + _application = { + 1: "resistive_load", + 2: "inductive_load", + 3: "lamp_load", + }[kwargs["application_id"]] + + _overstress, _reason = _do_check_current_limit( + kwargs["current_ratio"], + stress_limits[_application]["current"][environment_id], + ) + + _ostress, _rsn = _do_check_power_limit( + kwargs["power_ratio"], + stress_limits[_application]["power"][environment_id], + ) + _overstress = _overstress or _ostress + _reason += _rsn + + return _overstress, _reason + + +def _do_check_current_limit( + current_ratio: float, + current_limit: float, +) -> Tuple[int, str]: + """Check if the current ratio exceeds the limit. + + :param current_ratio: + :param current_limit: + :return: _overstress, _reason + :rtype: tuple + """ + if current_ratio <= current_limit: + return 0, "" + + return ( + 1, + f"Current ratio of {current_ratio} exceeds the allowable limit of " + f"{current_limit}.\n", + ) + + +def _do_check_power_limit( + power_ratio: float, + power_limit: float, +) -> Tuple[int, str]: + """Check if the power ratio exceeds the limit. + + :param power_ratio: + :param power_limit: + :return: _overstress, _reason + :rtype: tuple + """ + if power_ratio <= power_limit: + return 0, "" + + return ( + 1, + f"Power ratio of {power_ratio} exceeds the allowable limit of " + f"{power_limit}.\n", + ) diff --git a/src/ramstk/analyses/derating/models/switch.pyi b/src/ramstk/analyses/derating/models/switch.pyi new file mode 100644 index 000000000..596e17c8c --- /dev/null +++ b/src/ramstk/analyses/derating/models/switch.pyi @@ -0,0 +1,12 @@ +# Standard Library Imports +from typing import Dict, List, Tuple + +def do_derating_analysis( + environment_id: int, stress_limits: Dict[str, Dict[str, List[float]]], **kwargs +) -> Tuple[int, str]: ... +def _do_check_current_limit( + current_ratio: float, current_limit: float +) -> Tuple[int, str]: ... +def _do_check_power_limit( + power_ratio: float, power_limit: float +) -> Tuple[int, str]: ... diff --git a/src/ramstk/analyses/milhdbk217f/milhdbk217f.py b/src/ramstk/analyses/milhdbk217f/milhdbk217f.py index 3560020aa..d35f113b2 100644 --- a/src/ramstk/analyses/milhdbk217f/milhdbk217f.py +++ b/src/ramstk/analyses/milhdbk217f/milhdbk217f.py @@ -1,10 +1,10 @@ # type: ignore # -*- coding: utf-8 -*- # -# ramstk.analyses.milhdbk217f.py is part of the RAMSTK Project +# ramstk.analyses.milhdbk217f.milhdbk217f.py is part of the RAMSTK Project # # All rights reserved. -# Copyright 2019 Doyle Rowland doyle.rowland reliaqual com +# Copyright since 2017 Doyle "weibullguy" Rowland doyle.rowland reliaqual com """milhdbk217f Calculations Class.""" # Standard Library Imports @@ -269,10 +269,10 @@ def _get_environment_factor( return _pi_e_lists[category_id][subcategory_id][quality_id][ environment_active_id - 1 ] - elif category_id in {2, 3, 5, 7, 9, 10, 8}: + if category_id in {2, 3, 5, 7, 9, 10, 8}: return _pi_e_lists[category_id][subcategory_id][environment_active_id - 1] - else: - return _pi_e_lists[category_id][environment_active_id - 1] + + return _pi_e_lists[category_id][environment_active_id - 1] def _get_part_count_quality_factor( @@ -309,12 +309,14 @@ def _get_part_count_quality_factor( if category_id in {6, 7, 9}: return _pi_q_lists[category_id][subcategory_id][quality_id - 1] - elif category_id == 10 and subcategory_id in {1, 2}: + + if category_id == 10 and subcategory_id in {1, 2}: return _pi_q_lists[category_id][subcategory_id][quality_id - 1] - elif category_id == 10 and subcategory_id in {3, 4}: + + if category_id == 10 and subcategory_id in {3, 4}: return 1.0 - else: - return _pi_q_lists[category_id][quality_id - 1] + + return _pi_q_lists[category_id][quality_id - 1] # pylint: disable=too-many-return-statements @@ -346,19 +348,24 @@ def _get_part_stress_quality_factor( if category_id == 1: return _pi_q_lists[category_id][quality_id - 1] - elif ( + + if ( category_id == 8 and subcategory_id in {4, 5} or (category_id == 7 and subcategory_id == 5) ): return _pi_q_lists[category_id][subcategory_id][quality_id - 1] - elif category_id == 7: + + if category_id == 7: return 0.0 - elif category_id == 8: + + if category_id == 8: return 0.0 - elif category_id == 9 and subcategory_id == 1: + + if category_id == 9 and subcategory_id == 1: return 0.0 - elif category_id == 10 and subcategory_id in {3, 4}: + + if category_id == 10 and subcategory_id in {3, 4}: return 0.0 - else: - return _pi_q_lists[category_id][subcategory_id][quality_id - 1] + + return _pi_q_lists[category_id][subcategory_id][quality_id - 1] diff --git a/src/ramstk/configuration.py b/src/ramstk/configuration.py index ef4825ff0..d05b23d37 100644 --- a/src/ramstk/configuration.py +++ b/src/ramstk/configuration.py @@ -550,21 +550,7 @@ def __init__(self) -> None: self.RAMSTK_RPN_SEVERITY: Dict[int, str] = {} # User. self.RAMSTK_SEVERITY: Dict[str, Tuple[str, str, str, str]] = {} # Admin self.RAMSTK_STAKEHOLDERS: Dict[int, str] = {} # User. - self.RAMSTK_STRESS_LIMITS: Dict[ - int, - Tuple[ - float, - float, - float, - float, - float, - float, - float, - float, - float, - float, - ], - ] = {} # User. + self.RAMSTK_STRESS_LIMITS: Dict = {} # User. self.RAMSTK_SUBCATEGORIES: Dict[int, Dict[str, str]] = {} # Static. self.RAMSTK_USERS: Dict[int, Tuple[str, str, str, str, str]] = {} # Admin. self.RAMSTK_VALIDATION_TYPE: Dict[int, Tuple[str, str, str]] = {} # Admin. @@ -635,108 +621,6 @@ def __init__(self) -> None: self.loaded = False - def _do_make_configuration_dir(self) -> None: - """Create the user configuration directory. - - :return: None - :rtype: None - """ - self.RAMSTK_CONF_DIR = f"{self.RAMSTK_HOME_DIR}/.config/RAMSTK" - if not dir_exists(self.RAMSTK_CONF_DIR): - try: - makedirs(self.RAMSTK_CONF_DIR) - self.RAMSTK_PROG_CONF = f"{self.RAMSTK_CONF_DIR}/RAMSTK.toml" - except OSError: - _error_msg = ( - f"User's configuration directory {self.RAMSTK_CONF_DIR} does not " - f"exist and could not be created when attempting to create a new " - f"user configuration file." - ) - pub.sendMessage( - "fail_create_user_configuration", error_message=_error_msg - ) - - def _do_make_data_dir(self) -> None: - """Create the user data directory. - - :return: None - :rtype: None - """ - self.RAMSTK_DATA_DIR = self.RAMSTK_CONF_DIR + self._data_sub_dir - if not dir_exists(self.RAMSTK_DATA_DIR): - try: - makedirs(self.RAMSTK_DATA_DIR) - except OSError: - _error_msg = ( - f"User's data directory {self.RAMSTK_DATA_DIR} does not exist and " - f"could not be created when attempting to create a new user " - f"configuration file." - ) - pub.sendMessage( - "fail_create_user_configuration", error_message=_error_msg - ) - - def _do_make_icon_dir(self) -> None: - """Create the user icon directory. - - :return: None - :rtype: None - """ - self.RAMSTK_ICON_DIR = self.RAMSTK_CONF_DIR + self._icon_sub_dir - - if not dir_exists(self.RAMSTK_ICON_DIR): - try: - makedirs(self.RAMSTK_ICON_DIR) - except OSError: - _error_msg = ( - f"User's icon directory {self.RAMSTK_ICON_DIR} does not exist and " - f"could not be created when attempting to create a new user " - f"configuration file." - ) - pub.sendMessage( - "fail_create_user_configuration", error_message=_error_msg - ) - - def _do_make_log_dir(self) -> None: - """Create the user log directory. - - :return: None - :rtype: None - """ - self.RAMSTK_LOG_DIR = self.RAMSTK_CONF_DIR + self._logs_sub_dir - - if not dir_exists(self.RAMSTK_LOG_DIR): - try: - makedirs(self.RAMSTK_LOG_DIR) - except OSError: - _error_msg = ( - f"User's log directory {self.RAMSTK_LOG_DIR} does not exist and " - f"could not be created when attempting to create a new user " - f"configuration file." - ) - pub.sendMessage( - "fail_create_user_configuration", error_message=_error_msg - ) - - def _do_make_program_dir(self) -> None: - """Create the user program directory. - - :return: None - :rtype: None - """ - if not dir_exists(self.RAMSTK_PROG_DIR): - try: - makedirs(self.RAMSTK_PROG_DIR) - except OSError: - _error_msg = ( - f"Program directory {self.RAMSTK_PROG_DIR} does not exist and " - f"could not be created when attempting to create a new user " - f"configuration file." - ) - pub.sendMessage( - "fail_create_user_configuration", error_message=_error_msg - ) - def do_create_user_configuration(self) -> None: """Create the default user configuration file. @@ -844,126 +728,15 @@ def do_create_user_configuration(self) -> None: "validationfg": "#000000", }, "stress": { - "integratedcircuit": [ - 0.8, - 0.9, - 1.0, - 1.0, - 1.0, - 1.0, - 0.0, - 0.0, - 125.0, - 125.0, - ], - "semiconductor": [ - 1.0, - 1.0, - 0.7, - 0.9, - 1.0, - 1.0, - 0.0, - 0.0, - 125.0, - 125.0, - ], - "resistor": [ - 1.0, - 1.0, - 0.5, - 0.9, - 1.0, - 1.0, - 0.0, - 0.0, - 125.0, - 125.0, - ], - "capacitor": [ - 1.0, - 1.0, - 1.0, - 1.0, - 0.6, - 0.9, - 10.0, - 0.0, - 125.0, - 125.0, - ], - "inductor": [ - 0.6, - 0.9, - 1.0, - 1.0, - 0.5, - 0.9, - 15.0, - 0.0, - 125.0, - 125.0, - ], - "relay": [ - 0.75, - 0.9, - 1.0, - 1.0, - 1.0, - 1.0, - 0.0, - 0.0, - 125.0, - 125.0, - ], - "switch": [ - 0.75, - 0.9, - 1.0, - 1.0, - 1.0, - 1.0, - 0.0, - 0.0, - 125.0, - 125.0, - ], - "connection": [ - 0.7, - 0.9, - 1.0, - 1.0, - 0.7, - 0.9, - 25.0, - 0.0, - 125.0, - 125.0, - ], - "meter": [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0, - 1.0, - 0.0, - 0.0, - 125.0, - 125.0, - ], - "miscellaneous": [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0, - 1.0, - 0.0, - 0.0, - 125.0, - 125.0, - ], + "integrated_circuit": {}, + "semiconductor": {}, + "resistor": {}, + "capacitor": {}, + "inductor": {}, + "relay": {}, + "switch": {}, + "connection": {}, + "miscellaneous": {}, }, } @@ -995,13 +768,7 @@ def get_user_configuration(self) -> None: for _file in self._lst_format_files: self.RAMSTK_FORMAT_FILE[_file] = _config["layouts"][_file] - # Hardware categories are stored as integers, but configuration - # file keys are human-readable nouns. This converts the noun key - # to the equivalent integer key. - for _category in enumerate(self._lst_categories): - self.RAMSTK_STRESS_LIMITS[_category[0] + 1] = _config["stress"][ - _category[1] - ] + self.RAMSTK_STRESS_LIMITS = _config["stress"] self.RAMSTK_BACKEND = _config["backend"]["dialect"] self.RAMSTK_PROG_INFO["dialect"] = _config["backend"]["dialect"] @@ -1025,6 +792,7 @@ def get_user_configuration(self) -> None: self.RAMSTK_TABPOS["modulebook"] = _config["general"]["moduletabpos"] self.RAMSTK_TABPOS["workbook"] = _config["general"]["worktabpos"] self.RAMSTK_LOGLEVEL = _config["general"]["loglevel"] + if self.RAMSTK_LOG_DIR == "": self.RAMSTK_USER_LOG = "./ramstk_run.log" self.RAMSTK_IMPORT_LOG = "./ramstk_import.log" @@ -1113,16 +881,15 @@ def set_user_configuration(self) -> None: "validationfg": self.RAMSTK_COLORS["validationfg"], }, "stress": { - "integratedcircuit": self.RAMSTK_STRESS_LIMITS[1], - "semiconductor": self.RAMSTK_STRESS_LIMITS[2], - "resistor": self.RAMSTK_STRESS_LIMITS[3], - "capacitor": self.RAMSTK_STRESS_LIMITS[4], - "inductor": self.RAMSTK_STRESS_LIMITS[5], - "relay": self.RAMSTK_STRESS_LIMITS[6], - "switch": self.RAMSTK_STRESS_LIMITS[7], - "connection": self.RAMSTK_STRESS_LIMITS[8], - "meter": self.RAMSTK_STRESS_LIMITS[9], - "miscellaneous": self.RAMSTK_STRESS_LIMITS[10], + "integratedcircuit": self.RAMSTK_STRESS_LIMITS["integrated_circuit"], + "semiconductor": self.RAMSTK_STRESS_LIMITS["semiconductor"], + "resistor": self.RAMSTK_STRESS_LIMITS["resistor"], + "capacitor": self.RAMSTK_STRESS_LIMITS["capacitor"], + "inductor": self.RAMSTK_STRESS_LIMITS["inductor"], + "relay": self.RAMSTK_STRESS_LIMITS["relay"], + "switch": self.RAMSTK_STRESS_LIMITS["switch"], + "connection": self.RAMSTK_STRESS_LIMITS["connection"], + "miscellaneous": self.RAMSTK_STRESS_LIMITS["miscellaneous"], }, } @@ -1163,3 +930,105 @@ def set_user_directories(self) -> None: self.RAMSTK_PROG_DIR = f"{self.RAMSTK_HOME_DIR}/analyses/ramstk" else: self.RAMSTK_PROG_DIR = self.RAMSTK_HOME_DIR + + def _do_make_configuration_dir(self) -> None: + """Create the user configuration directory. + + :return: None + :rtype: None + """ + self.RAMSTK_CONF_DIR = f"{self.RAMSTK_HOME_DIR}/.config/RAMSTK" + if not dir_exists(self.RAMSTK_CONF_DIR): + try: + makedirs(self.RAMSTK_CONF_DIR) + self.RAMSTK_PROG_CONF = f"{self.RAMSTK_CONF_DIR}/RAMSTK.toml" + except OSError: + _error_msg = ( + f"User's configuration directory {self.RAMSTK_CONF_DIR} does not " + f"exist and could not be created when attempting to create a new " + f"user configuration file." + ) + pub.sendMessage( + "fail_create_user_configuration", error_message=_error_msg + ) + + def _do_make_data_dir(self) -> None: + """Create the user data directory. + + :return: None + :rtype: None + """ + self.RAMSTK_DATA_DIR = self.RAMSTK_CONF_DIR + self._data_sub_dir + if not dir_exists(self.RAMSTK_DATA_DIR): + try: + makedirs(self.RAMSTK_DATA_DIR) + except OSError: + _error_msg = ( + f"User's data directory {self.RAMSTK_DATA_DIR} does not exist and " + f"could not be created when attempting to create a new user " + f"configuration file." + ) + pub.sendMessage( + "fail_create_user_configuration", error_message=_error_msg + ) + + def _do_make_icon_dir(self) -> None: + """Create the user icon directory. + + :return: None + :rtype: None + """ + self.RAMSTK_ICON_DIR = self.RAMSTK_CONF_DIR + self._icon_sub_dir + + if not dir_exists(self.RAMSTK_ICON_DIR): + try: + makedirs(self.RAMSTK_ICON_DIR) + except OSError: + _error_msg = ( + f"User's icon directory {self.RAMSTK_ICON_DIR} does not exist and " + f"could not be created when attempting to create a new user " + f"configuration file." + ) + pub.sendMessage( + "fail_create_user_configuration", error_message=_error_msg + ) + + def _do_make_log_dir(self) -> None: + """Create the user log directory. + + :return: None + :rtype: None + """ + self.RAMSTK_LOG_DIR = self.RAMSTK_CONF_DIR + self._logs_sub_dir + + if not dir_exists(self.RAMSTK_LOG_DIR): + try: + makedirs(self.RAMSTK_LOG_DIR) + except OSError: + _error_msg = ( + f"User's log directory {self.RAMSTK_LOG_DIR} does not exist and " + f"could not be created when attempting to create a new user " + f"configuration file." + ) + pub.sendMessage( + "fail_create_user_configuration", error_message=_error_msg + ) + + def _do_make_program_dir(self) -> None: + """Create the user program directory. + + :return: None + :rtype: None + """ + if not dir_exists(self.RAMSTK_PROG_DIR): + try: + makedirs(self.RAMSTK_PROG_DIR) + except OSError: + _error_msg = ( + f"Program directory {self.RAMSTK_PROG_DIR} does not exist and " + f"could not be created when attempting to create a new user " + f"configuration file." + ) + pub.sendMessage( + "fail_create_user_configuration", error_message=_error_msg + ) diff --git a/src/ramstk/models/dbrecords/programdb_design_electric_record.py b/src/ramstk/models/dbrecords/programdb_design_electric_record.py index 924b72043..7b968df1b 100644 --- a/src/ramstk/models/dbrecords/programdb_design_electric_record.py +++ b/src/ramstk/models/dbrecords/programdb_design_electric_record.py @@ -9,14 +9,15 @@ """RAMSTKDesignElectric Record Model.""" # Standard Library Imports -from typing import Dict, List, Tuple, Union +from typing import Dict, List, Union # Third Party Imports from pubsub import pub from sqlalchemy import Column, Float, ForeignKey, Integer, String # RAMSTK Package Imports -from ramstk.analyses import derating, stress +from ramstk.analyses import stress +from ramstk.analyses.derating import derating from ramstk.views.gtk3 import _ # RAMSTK Local Imports @@ -24,48 +25,6 @@ from .baserecord import RAMSTKBaseRecord -def do_check_overstress( - overstress: Dict[str, List[float]], stress_type: str, limits: Dict[str, List[float]] -) -> Tuple[int, str]: - """Check the over stress condition and build a reason message. - - :param overstress: the dict containing the results of the - over stress analysis. - :param stress_type: the over stress type being checked. - :return: (_overstress, _reason); whether a component is overstressed and the reason. - :rtype: tuple - """ - _overstress = 0 - _reason = "" - - if overstress["harsh"][0]: - _overstress = 1 - _reason = _reason + ( - f"Operating {stress_type} ratio is less than the harsh environment limit " - f"of {limits['harsh'][0]}.\n" - ) - if overstress["harsh"][1]: - _overstress = 1 - _reason = _reason + ( - f"Operating {stress_type} ratio is greater than the harsh environment " - f"limit of {limits['harsh'][1]}.\n" - ) - if overstress["mild"][0]: - _overstress = 1 - _reason = _reason + ( - f"Operating {stress_type} ratio is less than the mild environment limit of " - f"{limits['mild'][0]}.\n" - ) - if overstress["mild"][1]: - _overstress = 1 - _reason = _reason + ( - f"Operating {stress_type} ratio is greater than the mild environment limit " - f"of {limits['mild'][1]}.\n" - ) - - return _overstress, _reason - - # pylint: disable=R0902 class RAMSTKDesignElectricRecord(RAMSTK_BASE, RAMSTKBaseRecord): # type: ignore """Represent ramstk_design_electric table in the RAMSTK Program database. @@ -463,52 +422,62 @@ def do_calculate_voltage_ratio(self) -> None: ), ) - def do_derating_analysis(self, stress_limits: List[float]) -> None: + def do_derating_analysis( + self, + category_id: int, + subcategory_id: int, + quality_id: int, + stress_limits: Dict[ + str, Dict[str, Dict[str, Dict[str, Dict[str, List[float]]]]] + ], + ) -> None: """Perform a derating analysis. + :param category_id: the category ID of the component to derate. + :param subcategory_id: the subcategory ID of the component to derate. + :param quality_id: the quality ID of the component to derate. :param stress_limits: the list of stress limits for the selected record. :return: None :rtype: None """ - _overstress = 0 - _reason = "" - - _current_limits = { - "harsh": [0.0, stress_limits[0]], - "mild": [0.0, stress_limits[1]], - } - _power_limits = { - "harsh": [0.0, stress_limits[2]], - "mild": [0.0, stress_limits[3]], - } - _voltage_limits = { - "harsh": [0.0, stress_limits[4]], - "mild": [0.0, stress_limits[5]], - } - - _ostress, _rsn = do_check_overstress( - derating.check_overstress(self.current_ratio, _current_limits), - "current", - _current_limits, - ) - _overstress = _overstress or _ostress - _reason += _rsn - - _ostress, _rsn = do_check_overstress( - derating.check_overstress(self.power_ratio, _power_limits), - "power", - _power_limits, - ) - _overstress = _overstress or _ostress - _reason += _rsn - - _ostress, _rsn = do_check_overstress( - derating.check_overstress(self.voltage_ratio, _voltage_limits), - "voltage", - _voltage_limits, + self.overstress = 0 + self.reason = "" + + _category = { + 1: "integrated_circuit", + 2: "semiconductor", + 3: "resistor", + 4: "capacitor", + 5: "inductor", + 6: "relay", + 7: "switch", + 8: "connection", + 10: "miscellaneous", + }[category_id] + + self.overstress, self.reason = derating.do_check_overstress( + _category, + self.environment_active_id, + subcategory_id, + stress_limits[_category], + application_id=self.application_id, + current_ratio=self.current_ratio, + family_id=self.family_id, + package_id=self.package_id, + power_rated=self.power_rated, + power_ratio=self.power_ratio, + quality_id=quality_id, + specification_id=self.specification_id, + technology_id=self.technology_id, + temperature_active=self.temperature_active, + temperature_case=self.temperature_case, + temperature_hot_spot=self.temperature_hot_spot, + temperature_junction=self.temperature_junction, + temperature_knee=self.temperature_knee, + temperature_rated_max=self.temperature_rated_max, + type_id=self.type_id, + voltage_ratio=self.voltage_ratio, ) - self.overstress = _overstress or _ostress - self.reason = _reason + _rsn def do_stress_analysis(self, category_id: int) -> None: """Perform a stress analysis. diff --git a/src/ramstk/models/dbrecords/programdb_design_electric_record.pyi b/src/ramstk/models/dbrecords/programdb_design_electric_record.pyi new file mode 100644 index 000000000..f18599374 --- /dev/null +++ b/src/ramstk/models/dbrecords/programdb_design_electric_record.pyi @@ -0,0 +1,86 @@ +# Standard Library Imports +from typing import Any, Dict, List, Union + +# RAMSTK Package Imports +from ramstk.analyses import stress as stress +from ramstk.analyses.derating import derating as derating +from ramstk.views.gtk3 import _ as _ + +# RAMSTK Local Imports +from .. import RAMSTK_BASE as RAMSTK_BASE +from .baserecord import RAMSTKBaseRecord as RAMSTKBaseRecord + +class RAMSTKDesignElectricRecord(RAMSTK_BASE, RAMSTKBaseRecord): + __defaults__: Dict[str, Union[float, int, str]] + __tablename__: str + __table_args__: Dict[str, bool] + revision_id: int + hardware_id: int + application_id: int + area: float + capacitance: float + configuration_id: int + construction_id: int + contact_form_id: int + contact_gauge: float + contact_rating_id: int + current_operating: float + current_rated: float + current_ratio: float + environment_active_id: int + environment_dormant_id: int + family_id: int + feature_size: float + frequency_operating: float + insert_id: int + insulation_id: int + manufacturing_id: int + matching_id: int + n_active_pins: int + n_circuit_planes: int + n_cycles: int + n_elements: int + n_hand_soldered: int + n_wave_soldered: int + operating_life: float + overstress: int + package_id: int + power_operating: float + power_rated: float + power_ratio: float + reason: str + resistance: float + specification_id: int + technology_id: int + temperature_active: float + temperature_case: float + temperature_dormant: float + temperature_hot_spot: float + temperature_junction: float + temperature_knee: float + temperature_rated_max: float + temperature_rated_min: float + temperature_rise: float + theta_jc: float + type_id: int + voltage_ac_operating: float + voltage_dc_operating: float + voltage_esd: float + voltage_rated: float + voltage_ratio: float + weight: float + years_in_production: int + def get_attributes(self) -> Dict[str, Union[float, int, str]]: ... + def do_calculate_current_ratio(self) -> None: ... + def do_calculate_power_ratio(self) -> None: ... + def do_calculate_voltage_ratio(self) -> None: ... + def do_derating_analysis( + self, + category_id: int, + subcategory_id: int, + quality_id: int, + stress_limits: Dict[ + str, Dict[str, Dict[str, Dict[str, Dict[str, List[float]]]]] + ], + ) -> None: ... + def do_stress_analysis(self, category_id: int) -> None: ... diff --git a/src/ramstk/models/dbviews/programdb_hardware_view.py b/src/ramstk/models/dbviews/programdb_hardware_view.py index 92d914b84..46c69fa9f 100644 --- a/src/ramstk/models/dbviews/programdb_hardware_view.py +++ b/src/ramstk/models/dbviews/programdb_hardware_view.py @@ -7,7 +7,7 @@ """Hardware BoM View Model.""" # Standard Library Imports -from typing import Dict, List, Union +from typing import Dict, Union # Third Party Imports from pubsub import pub @@ -52,89 +52,18 @@ def __init__(self, **kwargs: Dict[str, Union[float, int, str]]) -> None: "nswc": self._do_load_nswc, "reliability": self._do_load_reliability, } - self._dic_stress_limits: Dict[int, List[float]] = kwargs.get( # type: ignore + self._dic_stress_limits = kwargs.get( "stress_limits", { - 1: [ - 0.8, - 0.9, - 1.0, - 1.0, - 1.0, - 1.0, - ], - 2: [ - 1.0, - 1.0, - 0.7, - 0.9, - 1.0, - 1.0, - ], - 3: [ - 1.0, - 1.0, - 0.5, - 0.9, - 1.0, - 1.0, - ], - 4: [ - 1.0, - 1.0, - 1.0, - 1.0, - 0.6, - 0.9, - ], - 5: [ - 0.6, - 0.9, - 1.0, - 1.0, - 0.5, - 0.9, - ], - 6: [ - 0.75, - 0.9, - 1.0, - 1.0, - 1.0, - 1.0, - ], - 7: [ - 0.75, - 0.9, - 1.0, - 1.0, - 1.0, - 1.0, - ], - 8: [ - 0.7, - 0.9, - 1.0, - 1.0, - 0.7, - 0.9, - ], - 9: [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0, - 1.0, - ], - 10: [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0, - 1.0, - ], + "integrated_circuit": {}, + "semiconductor": {}, + "resistor": {}, + "capacitor": {}, + "inductor": {}, + "relay": {}, + "switch": {}, + "connection": {}, + "miscellaneous": {}, }, ) self._dic_trees = { @@ -355,12 +284,17 @@ def do_calculate_part_stress(self, node_id: int) -> None: """ _record = self.tree.get_node(node_id) - _record.data["design_electric"].do_stress_analysis( - _record.data["hardware"].category_id - ) - _record.data["design_electric"].do_derating_analysis( - self._dic_stress_limits[_record.data["hardware"].category_id] - ) + if _record.data["hardware"].category_id != 9: + _record.data["design_electric"].do_stress_analysis( + _record.data["hardware"].category_id + ) + + _record.data["design_electric"].do_derating_analysis( + _record.data["hardware"].category_id, + _record.data["hardware"].subcategory_id, + _record.data["reliability"].quality_id, + self._dic_stress_limits, + ) def do_calculate_power_dissipation(self, node_id: int) -> float: """Calculate the total power dissipation of a hardware item. diff --git a/src/ramstk/models/dbviews/programdb_hardware_view.pyi b/src/ramstk/models/dbviews/programdb_hardware_view.pyi index 3758ffe7b..350cc82cb 100644 --- a/src/ramstk/models/dbviews/programdb_hardware_view.pyi +++ b/src/ramstk/models/dbviews/programdb_hardware_view.pyi @@ -10,7 +10,9 @@ from .baseview import RAMSTKBaseView as RAMSTKBaseView class RAMSTKHardwareBoMView(RAMSTKBaseView): _tag: str _dic_load_functions: Dict[str, Callable[..., object]] - _dic_stress_limits: Dict[int, List[float]] + _dic_stress_limits: Dict[ + str, Dict[str, Dict[str, Dict[str, Dict[str, List[float]]]]] + ] _dic_trees: Dict[str, treelib.Tree] _lst_modules: List[str] _hr_multiplier: float diff --git a/src/ramstk/views/gtk3/design_electric/components/capacitor.py b/src/ramstk/views/gtk3/design_electric/components/capacitor.py index b461ba250..d248beeeb 100644 --- a/src/ramstk/views/gtk3/design_electric/components/capacitor.py +++ b/src/ramstk/views/gtk3/design_electric/components/capacitor.py @@ -154,7 +154,7 @@ class CapacitorDesignElectricInputPanel(RAMSTKFixedPanel): 9: [["MIL-C-11272"], ["MIL-C-23269"]], 10: [["MIL-C-11015"], ["MIL-C-39014"]], 11: [["MIL-C-20"], ["MIL-C-55681"]], - 12: [["MIL-C-39003"]], + 12: [["MIL-C-39003"], ["MIL-C-55365"]], 13: [["MIL-C-3965"], ["MIL-C-39006"]], 14: [["MIL-C-39018"]], 15: [["MIL-C-62"]], diff --git a/src/ramstk/views/gtk3/design_electric/components/resistor.py b/src/ramstk/views/gtk3/design_electric/components/resistor.py index 7142051d7..b4ccc8fc9 100644 --- a/src/ramstk/views/gtk3/design_electric/components/resistor.py +++ b/src/ramstk/views/gtk3/design_electric/components/resistor.py @@ -536,17 +536,19 @@ def __do_set_type_combo_sensitive(self) -> None: :return: None :rtype: None """ - if self._hazard_rate_method_id == 1 and self.subcategory_id in [ - 1, - 2, - 5, - 6, - 7, - 9, - 11, - 13, - 15, - ]: - self.cmbType.set_sensitive(True) - elif self._hazard_rate_method_id == 2 and self.subcategory_id == 8: + if ( + self._hazard_rate_method_id == 1 + and self.subcategory_id + in [ + 1, + 2, + 5, + 6, + 7, + 9, + 11, + 13, + 15, + ] + ) or (self._hazard_rate_method_id == 2 and self.subcategory_id == 8): self.cmbType.set_sensitive(True) diff --git a/tests/analyses/derating/derating_unit_test.py b/tests/analyses/derating/derating_unit_test.py new file mode 100644 index 000000000..e07dc6126 --- /dev/null +++ b/tests/analyses/derating/derating_unit_test.py @@ -0,0 +1,201 @@ +# pylint: skip-file +# type: ignore +# -*- coding: utf-8 -*- +# +# tests.analyses.derating.derating_unit_test.py is part of The RAMSTK Project +# +# All rights reserved. +# Copyright since 2007 Doyle "weibullguy" Rowland doyle.rowland reliaqual com +"""Test class for the stress derating module.""" + +# Third Party Imports +import pytest + +# RAMSTK Package Imports +from ramstk.analyses.derating import derating + + +@pytest.mark.unit +@pytest.mark.parametrize( + "category", + [ + "capacitor", + "connection", + "inductor", + "integrated_circuit", + "miscellaneous", + "relay", + "resistor", + "semiconductor", + "switch", + ], +) +def test_check_overstress(test_stress_limits, category): + """should determine the component is not execeeding any limit.""" + if category == "miscellaneous": + _subcategory_id = 4 + else: + _subcategory_id = 1 + + _overstress, _reason = derating.do_check_overstress( + category, + 3, + _subcategory_id, + test_stress_limits[category], + application_id=1, + current_ratio=0.05, + family_id=1, + package_id=2, + power_rated=0.125, + power_ratio=0.15, + quality_id=1, + specification_id=1, + technology_id=1, + temperature_active=30.0, + temperature_case=38.4, + temperature_hot_spot=48.2, + temperature_junction=70.0, + temperature_knee=70.0, + temperature_rated_max=85.0, + type_id=1, + voltage_ratio=0.2, + ) + + assert _overstress == 0 + assert _reason == "" + + +@pytest.mark.unit +def test_check_overstress_over_limit_protected(test_stress_limits): + """should determine a component is exceeding a limit in a protected environment.""" + _overstress, _reason = derating.do_check_overstress( + "capacitor", + 1, + 10, + test_stress_limits["capacitor"], + specification_id=1, + temperature_case=78.4, + temperature_rated_max=85.0, + voltage_ratio=0.7, + ) + + assert _overstress == 1 + assert ( + _reason == "Case temperature of 78.4C exceeds the derated maximum " + "temperature of 15.0C less than maximum rated temperature of 85.0C.\nVoltage " + "ratio of 0.7 exceeds the allowable limit of 0.6.\n" + ) + + +@pytest.mark.unit +def test_check_overstress_over_limit_normal(test_stress_limits): + """should determine a component is exceeding a limit in a normal environment.""" + _overstress, _reason = derating.do_check_overstress( + "capacitor", + 2, + 10, + test_stress_limits["capacitor"], + specification_id=1, + temperature_case=78.4, + temperature_rated_max=85.0, + voltage_ratio=0.7, + ) + + assert _overstress == 1 + assert ( + _reason == "Case temperature of 78.4C exceeds the derated maximum " + "temperature of 15.0C less than maximum rated temperature of 85.0C.\nVoltage " + "ratio of 0.7 exceeds the allowable limit of 0.6.\n" + ) + + +@pytest.mark.unit +def test_check_overstress_over_limit_harsh(test_stress_limits): + """should determine a component is exceeding a limit in a harsh environment.""" + _overstress, _reason = derating.do_check_overstress( + "capacitor", + 3, + 10, + test_stress_limits["capacitor"], + specification_id=1, + temperature_case=78.4, + temperature_rated_max=85.0, + voltage_ratio=0.7, + ) + + assert _overstress == 1 + assert ( + _reason == "Case temperature of 78.4C exceeds the derated maximum " + "temperature of 15.0C less than maximum rated temperature of 85.0C.\nVoltage " + "ratio of 0.7 exceeds the allowable limit of 0.6.\n" + ) + + +@pytest.mark.unit +def test_check_overstress_unknown_environment(test_stress_limits): + """should raise an KeyError when passed an unknown environment.""" + with pytest.raises(KeyError): + derating.do_check_overstress( + "capacitor", + 15, + 10, + test_stress_limits["capacitor"], + specification_id=2, + temperature_case=46.3, + temperature_rated_max=70.0, + voltage_ratio=0.2, + ) + + +@pytest.mark.unit +def test_check_overstress_unknown_subcategory(test_stress_limits): + """should raise an KeyError when passed an unknown subcategory.""" + with pytest.raises(KeyError): + derating.do_check_overstress( + "capacitor", + 5, + 20, + test_stress_limits["capacitor"], + specification_id=2, + temperature_case=46.3, + temperature_rated_max=70.0, + voltage_ratio=0.2, + ) + + +@pytest.mark.unit +def test_check_overstress_unknown_category(test_stress_limits): + """should return (0, "") when passed an unknown component category.""" + _overstress, _reason = derating.do_check_overstress( + "meter", + 5, + 10, + test_stress_limits["capacitor"], + specification_id=2, + temperature_case=46.3, + temperature_rated_max=70.0, + voltage_ratio=0.2, + ) + + assert _overstress == 0 + assert _reason == "" + + +@pytest.mark.unit +@pytest.mark.parametrize("case_temperature", ["128.3", None]) +def test_check_overstress_non_numeric_input( + case_temperature, + test_stress_limits, +): + """should raise am TypeError when passed a non-numeric value.""" + with pytest.raises(TypeError): + derating.do_check_overstress( + "capacitor", + 1, + 1, + test_stress_limits["capacitor"], + specification_id=2, + temperature_case=case_temperature, + temperature_rated_max=70.0, + voltage_ratio=0.2, + ) diff --git a/tests/analyses/derating/models/capacitor_derating_unit_test.py b/tests/analyses/derating/models/capacitor_derating_unit_test.py new file mode 100644 index 000000000..c5065e0f7 --- /dev/null +++ b/tests/analyses/derating/models/capacitor_derating_unit_test.py @@ -0,0 +1,174 @@ +# pylint: skip-file +# type: ignore +# -*- coding: utf-8 -*- +# +# tests.analyses.derating.models.capacitor_unit_test.py is part of The +# RAMSTK Project +# +# All rights reserved. +# Copyright since 2007 Doyle "weibullguy" Rowland doyle.rowland reliaqual com +"""Test class for the capacitor derating module.""" + +# Third Party Imports +import pytest + +# RAMSTK Package Imports +from ramstk.analyses.derating import capacitor + + +@pytest.mark.unit +def test_do_derating_analysis_no_stresses(test_stress_limits): + """should determine the capacitor is not execeeding any limit.""" + _overstress, _reason = capacitor.do_derating_analysis( + 1, + 11, + test_stress_limits["capacitor"], + specification_id=2, + temperature_case=46.3, + temperature_rated_max=70.0, + voltage_ratio=0.2, + ) + + assert _overstress == 0 + assert _reason == "" + + +@pytest.mark.unit +def test_do_derating_analysis_case_temperature(test_stress_limits): + """should determine the capacitor is exceeding the case temperature limit.""" + _overstress, _reason = capacitor.do_derating_analysis( + 1, + 11, + test_stress_limits["capacitor"], + specification_id=2, + temperature_case=79.3, + temperature_rated_max=85.0, + voltage_ratio=0.2, + ) + + assert _overstress == 1 + assert ( + _reason == "Case temperature of 79.3C exceeds the derated maximum temperature " + "of 10.0C less than maximum rated temperature of 85.0C.\n" + ) + + +@pytest.mark.unit +def test_do_derating_analysis_voltage(test_stress_limits): + """should determine the capacitor is execeeding the voltage limit.""" + _overstress, _reason = capacitor.do_derating_analysis( + 1, + 11, + test_stress_limits["capacitor"], + specification_id=2, + temperature_case=59.3, + temperature_rated_max=85.0, + voltage_ratio=0.95, + ) + + assert _overstress == 1 + assert _reason == "Voltage ratio of 0.95 exceeds the allowable limit of 0.6.\n" + + +@pytest.mark.unit +def test_do_derating_analysis_all_stresses(test_stress_limits): + """should determine the capacitor is execeeding both limits.""" + _overstress, _reason = capacitor.do_derating_analysis( + 1, + 11, + test_stress_limits["capacitor"], + specification_id=2, + temperature_case=79.3, + temperature_rated_max=85.0, + voltage_ratio=0.95, + ) + + assert _overstress == 1 + assert ( + _reason == "Case temperature of 79.3C exceeds the derated maximum temperature " + "of 10.0C less than maximum rated temperature of 85.0C.\nVoltage ratio of 0.95 " + "exceeds the allowable limit of 0.6.\n" + ) + + +@pytest.mark.unit +def test_do_derating_analysis_unknown_environment(test_stress_limits): + """should raise am IndexError when passed an unknown environment.""" + with pytest.raises(IndexError): + capacitor.do_derating_analysis( + 5, + 10, + test_stress_limits["capacitor"], + specification_id=2, + temperature_case=46.3, + temperature_rated_max=70.0, + voltage_ratio=0.2, + ) + + +@pytest.mark.unit +def test_do_derating_analysis_unknown_subcategory(test_stress_limits): + """should raise am KeyError when passed an unknown subcategory.""" + with pytest.raises(KeyError): + capacitor.do_derating_analysis( + 1, + 21, + test_stress_limits["capacitor"], + specification_id=2, + temperature_case=46.3, + temperature_rated_max=70.0, + voltage_ratio=0.2, + ) + + +@pytest.mark.unit +def test_do_derating_analysis_unknown_specification(test_stress_limits): + """should raise am KeyError when passed an unknown type ID.""" + with pytest.raises(KeyError): + capacitor.do_derating_analysis( + 1, + 11, + test_stress_limits["capacitor"], + specification_id=22, + temperature_case=46.3, + temperature_rated_max=70.0, + voltage_ratio=0.2, + ) + + +@pytest.mark.unit +@pytest.mark.parametrize("case_temperature", ["128.3", None]) +def test_do_derating_analysis_non_numeric_temperature( + case_temperature, + test_stress_limits, +): + """should raise am TypeError when passed a non-numeric case temperature.""" + with pytest.raises(TypeError): + capacitor.do_derating_analysis( + 1, + 1, + test_stress_limits["capacitor"], + specification_id=2, + temperature_case=case_temperature, + temperature_rated_max=70.0, + voltage_ratio=0.2, + ) + + +@pytest.mark.unit +@pytest.mark.parametrize("voltage_ratio", ["0.9", None]) +def test_do_derating_analysis_non_numeric_voltage_ratio( + voltage_ratio, + test_stress_limits, +): + """should raise am TypeError when passed a non-numeric voltage ratio.""" + with pytest.raises(TypeError): + capacitor.do_derating_analysis( + 1, + 11, + test_stress_limits["capacitor"], + specification_id=2, + temperature_case=46.3, + temperature_rated_max=70.0, + voltage_ratio=voltage_ratio, + ) diff --git a/tests/analyses/derating/models/connection_derating_unit_test.py b/tests/analyses/derating/models/connection_derating_unit_test.py new file mode 100644 index 000000000..55937429a --- /dev/null +++ b/tests/analyses/derating/models/connection_derating_unit_test.py @@ -0,0 +1,68 @@ +# pylint: skip-file +# type: ignore +# -*- coding: utf-8 -*- +# +# tests.analyses.derating.models.connection_unit_test.py is part of The +# RAMSTK Project +# +# All rights reserved. +# Copyright since 2007 Doyle "weibullguy" Rowland doyle.rowland reliaqual com +"""Test class for the connection derating module.""" + +# Third Party Imports +import pytest + +# RAMSTK Package Imports +from ramstk.analyses.derating import connection + + +@pytest.mark.unit +def test_do_derating_analysis_no_stresses(test_stress_limits): + """should determine the connection is not execeeding any limit.""" + _overstress, _reason = connection.do_derating_analysis( + 1, + test_stress_limits["connection"], + current_ratio=0.5, + ) + + assert _overstress == 0 + assert _reason == "" + + +@pytest.mark.unit +def test_do_derating_analysis_current(test_stress_limits): + """should determine the connection is execeeding the voltage limit.""" + _overstress, _reason = connection.do_derating_analysis( + 1, + test_stress_limits["connection"], + current_ratio=1.5, + ) + + assert _overstress == 1 + assert _reason == "Current ratio of 1.5 exceeds the allowable limit of 1.0.\n" + + +@pytest.mark.unit +def test_do_derating_analysis_unknown_environment(test_stress_limits): + """should raise am IndexError when passed an unknown environment.""" + with pytest.raises(IndexError): + connection.do_derating_analysis( + 5, + test_stress_limits["connection"], + current_ratio=0.9, + ) + + +@pytest.mark.unit +@pytest.mark.parametrize("current_ratio", ["0.9", None]) +def test_do_derating_analysis_non_numeric_current_ratio( + current_ratio, + test_stress_limits, +): + """should raise am TypeError when passed a non-numeric voltage ratio.""" + with pytest.raises(TypeError): + connection.do_derating_analysis( + 1, + test_stress_limits["connection"], + current_ratio=current_ratio, + ) diff --git a/tests/analyses/derating/models/inductor_derating_unit_test.py b/tests/analyses/derating/models/inductor_derating_unit_test.py new file mode 100644 index 000000000..0fe1d5cac --- /dev/null +++ b/tests/analyses/derating/models/inductor_derating_unit_test.py @@ -0,0 +1,241 @@ +# pylint: skip-file +# type: ignore +# -*- coding: utf-8 -*- +# +# tests.analyses.derating.models.inductor_unit_test.py is part of The +# RAMSTK Project +# +# All rights reserved. +# Copyright since 2007 Doyle "weibullguy" Rowland doyle.rowland reliaqual com +"""Test class for the inductor derating module.""" + +# Third Party Imports +import pytest + +# RAMSTK Package Imports +from ramstk.analyses.derating import inductor + + +@pytest.mark.unit +def test_do_derating_analysis_no_stresses_coil(test_stress_limits): + """should determine the inductor is not execeeding any limit.""" + _overstress, _reason = inductor.do_derating_analysis( + 1, + 1, + test_stress_limits["inductor"], + current_ratio=0.2, + family_id=2, + temperature_hot_spot=51.3, + temperature_rated_max=130.0, + voltage_ratio=0.2, + ) + + assert _overstress == 0 + assert _reason == "" + + +@pytest.mark.unit +def test_do_derating_analysis_no_stresses_transformer(test_stress_limits): + """should determine the transformer is not execeeding any limit.""" + _overstress, _reason = inductor.do_derating_analysis( + 1, + 2, + test_stress_limits["inductor"], + current_ratio=0.2, + family_id=2, + temperature_hot_spot=51.3, + temperature_rated_max=130.0, + voltage_ratio=0.2, + ) + + assert _overstress == 0 + assert _reason == "" + + +@pytest.mark.unit +def test_do_derating_analysis_current(test_stress_limits): + """should determine the inductor is execeeding the voltage limit.""" + _overstress, _reason = inductor.do_derating_analysis( + 1, + 1, + test_stress_limits["inductor"], + current_ratio=0.863, + family_id=2, + temperature_hot_spot=59.3, + temperature_rated_max=130.0, + voltage_ratio=0.2, + ) + + assert _overstress == 1 + assert _reason == "Current ratio of 0.863 exceeds the allowable limit of 0.7.\n" + + +@pytest.mark.unit +def test_do_derating_analysis_hot_spot_temperature(test_stress_limits): + """should determine the inductor is exceeding the hot spot temperature limit.""" + _overstress, _reason = inductor.do_derating_analysis( + 1, + 1, + test_stress_limits["inductor"], + current_ratio=0.2, + family_id=2, + temperature_hot_spot=111.3, + temperature_rated_max=130.0, + voltage_ratio=0.2, + ) + + assert _overstress == 1 + assert ( + _reason == "Hot spot temperature of 111.3C exceeds the derated maximum hot " + "spot temperature of 30.0C less than maximum rated hot spot temperature of " + "130.0C.\n" + ) + + +@pytest.mark.unit +def test_do_derating_analysis_voltage(test_stress_limits): + """should determine the inductor is execeeding the voltage limit.""" + _overstress, _reason = inductor.do_derating_analysis( + 1, + 1, + test_stress_limits["inductor"], + current_ratio=0.2, + family_id=2, + temperature_hot_spot=59.3, + temperature_rated_max=130.0, + voltage_ratio=0.863, + ) + + assert _overstress == 1 + assert _reason == "Voltage ratio of 0.863 exceeds the allowable limit of 0.7.\n" + + +@pytest.mark.unit +def test_do_derating_analysis_all_stresses(test_stress_limits): + """should determine the inductor is execeeding both limits.""" + _overstress, _reason = inductor.do_derating_analysis( + 1, + 1, + test_stress_limits["inductor"], + current_ratio=0.81, + family_id=2, + temperature_hot_spot=109.3, + temperature_rated_max=130.0, + voltage_ratio=0.863, + ) + + assert _overstress == 1 + assert ( + _reason == "Current ratio of 0.81 exceeds the allowable limit of 0.7.\nHot " + "spot temperature of 109.3C exceeds the derated maximum hot spot temperature " + "of 30.0C less than maximum rated hot spot temperature of 130.0C.\nVoltage " + "ratio of 0.863 exceeds the allowable limit of 0.7.\n" + ) + + +@pytest.mark.unit +def test_do_derating_analysis_unknown_environment(test_stress_limits): + """should raise am IndexError when passed an unknown environment.""" + with pytest.raises(IndexError): + inductor.do_derating_analysis( + 5, + 1, + test_stress_limits["inductor"], + current_ratio=0.81, + family_id=2, + temperature_hot_spot=109.3, + temperature_rated_max=130.0, + voltage_ratio=0.863, + ) + + +@pytest.mark.unit +def test_do_derating_analysis_unknown_subcategory(test_stress_limits): + """should raise am KeyError when passed an unknown subcategory.""" + with pytest.raises(KeyError): + inductor.do_derating_analysis( + 1, + 21, + test_stress_limits["inductor"], + current_ratio=0.81, + family_id=2, + temperature_hot_spot=109.3, + temperature_rated_max=130.0, + voltage_ratio=0.863, + ) + + +@pytest.mark.unit +def test_do_derating_analysis_unknown_family(test_stress_limits): + """should raise am KeyError when passed an unknown type ID.""" + with pytest.raises(KeyError): + inductor.do_derating_analysis( + 1, + 1, + test_stress_limits["inductor"], + current_ratio=0.81, + family_id=21, + temperature_hot_spot=109.3, + temperature_rated_max=130.0, + voltage_ratio=0.863, + ) + + +@pytest.mark.unit +@pytest.mark.parametrize("current_ratio", ["0.9", None]) +def test_do_derating_analysis_non_numeric_current_ratio( + current_ratio, + test_stress_limits, +): + """should raise am TypeError when passed a non-numeric current ratio.""" + with pytest.raises(TypeError): + inductor.do_derating_analysis( + 1, + 1, + test_stress_limits["inductor"], + current_ratio=current_ratio, + family_id=2, + temperature_hot_spot=51.3, + temperature_rated_max=130.0, + voltage_ratio=0.3, + ) + + +@pytest.mark.unit +@pytest.mark.parametrize("hot_spot_temperature", ["128.3", None]) +def test_do_derating_analysis_non_numeric_temperature( + hot_spot_temperature, + test_stress_limits, +): + """should raise am TypeError when passed a non-numeric current ratio.""" + with pytest.raises(TypeError): + inductor.do_derating_analysis( + 1, + 1, + test_stress_limits["inductor"], + current_ratio=0.1, + family_id=2, + temperature_hot_spot=hot_spot_temperature, + temperature_rated_max=130.0, + voltage_ratio=0.3, + ) + + +@pytest.mark.unit +@pytest.mark.parametrize("voltage_ratio", ["0.9", None]) +def test_do_derating_analysis_non_numeric_voltage_ratio( + voltage_ratio, + test_stress_limits, +): + """should raise am TypeError when passed a non-numeric voltage ratio.""" + with pytest.raises(TypeError): + inductor.do_derating_analysis( + 1, + 1, + test_stress_limits["inductor"], + current_ratio=0.1, + family_id=2, + temperature_hot_spot=51.3, + temperature_rated_max=130.0, + voltage_ratio=voltage_ratio, + ) diff --git a/tests/analyses/derating/models/integrated_circuit_derating_unit_test.py b/tests/analyses/derating/models/integrated_circuit_derating_unit_test.py new file mode 100644 index 000000000..002497a98 --- /dev/null +++ b/tests/analyses/derating/models/integrated_circuit_derating_unit_test.py @@ -0,0 +1,190 @@ +# pylint: skip-file +# type: ignore +# -*- coding: utf-8 -*- +# +# tests.analyses.derating.models.integrated_circuit_unit_test.py is part of The +# RAMSTK Project +# +# All rights reserved. +# Copyright since 2007 Doyle "weibullguy" Rowland doyle.rowland reliaqual com +"""Test class for the integrated circuit derating module.""" + +# Third Party Imports +import pytest + +# RAMSTK Package Imports +from ramstk.analyses.derating import integratedcircuit + + +@pytest.mark.unit +def test_do_derating_analysis_no_stresses(test_stress_limits): + """should determine the integrated circuit is not execeeding any limit.""" + _overstress, _reason = integratedcircuit.do_derating_analysis( + 1, + 1, + test_stress_limits["integrated_circuit"], + current_ratio=0.5, + package_id=3, + technology_id=2, + temperature_junction=78.3, + ) + + assert _overstress == 0 + assert _reason == "" + + +@pytest.mark.unit +def test_do_derating_analysis_current(test_stress_limits): + """should determine the integrated circuit is execeeding the current limit.""" + _overstress, _reason = integratedcircuit.do_derating_analysis( + 1, + 1, + test_stress_limits["integrated_circuit"], + current_ratio=0.87, + package_id=3, + technology_id=2, + temperature_junction=78.3, + ) + + assert _overstress == 1 + assert _reason == "Current ratio of 0.87 exceeds the allowable limit of 0.85.\n" + + +@pytest.mark.unit +def test_do_derating_analysis_junction_temperature(test_stress_limits): + """should determine the integrated circuit is execeeding the junction temperature + limit.""" + _overstress, _reason = integratedcircuit.do_derating_analysis( + 1, + 1, + test_stress_limits["integrated_circuit"], + current_ratio=0.8, + package_id=3, + technology_id=2, + temperature_junction=118.3, + ) + + assert _overstress == 1 + assert ( + _reason == "Junction temperature of 118.3C exceeds the allowable limit of " + "110.0C.\n" + ) + + +@pytest.mark.unit +def test_do_derating_analysis_all_stresses(test_stress_limits): + """should determine the integrated circuit is execeeding both limits.""" + _overstress, _reason = integratedcircuit.do_derating_analysis( + 1, + 1, + test_stress_limits["integrated_circuit"], + current_ratio=0.9, + package_id=3, + technology_id=2, + temperature_junction=128.3, + ) + + assert _overstress == 1 + assert ( + _reason == "Current ratio of 0.9 exceeds the allowable limit of " + "0.85.\nJunction temperature of 128.3C exceeds the allowable limit " + "of 110.0C.\n" + ) + + +@pytest.mark.unit +def test_do_derating_analysis_unknown_environment(test_stress_limits): + """should raise am IndexError when passed an unknown environment.""" + with pytest.raises(IndexError): + integratedcircuit.do_derating_analysis( + 5, + 1, + test_stress_limits["integrated_circuit"], + current_ratio=0.9, + package_id=3, + technology_id=2, + temperature_junction=128.3, + ) + + +@pytest.mark.unit +def test_do_derating_analysis_unknown_subcategory(test_stress_limits): + """should raise am KeyError when passed an unknown subcategory.""" + with pytest.raises(KeyError): + integratedcircuit.do_derating_analysis( + 1, + 21, + test_stress_limits["integrated_circuit"], + current_ratio=0.9, + package_id=3, + technology_id=2, + temperature_junction=128.3, + ) + + +@pytest.mark.unit +def test_do_derating_analysis_unknown_package(test_stress_limits): + """should raise am KeyError when passed an unknown package ID.""" + with pytest.raises(KeyError): + integratedcircuit.do_derating_analysis( + 1, + 1, + test_stress_limits["integrated_circuit"], + current_ratio=0.9, + package_id=31, + technology_id=2, + temperature_junction=128.3, + ) + + +@pytest.mark.unit +def test_do_derating_analysis_unknown_technology(test_stress_limits): + """should raise am KeyError when passed an unknown technology ID.""" + with pytest.raises(KeyError): + integratedcircuit.do_derating_analysis( + 1, + 1, + test_stress_limits["integrated_circuit"], + current_ratio=0.9, + package_id=3, + technology_id=21, + temperature_junction=128.3, + ) + + +@pytest.mark.unit +@pytest.mark.parametrize("current_ratio", ["0.9", None]) +def test_do_derating_analysis_non_numeric_current_ratio( + current_ratio, + test_stress_limits, +): + """should raise am TypeError when passed a non-numeric current ratio.""" + with pytest.raises(TypeError): + integratedcircuit.do_derating_analysis( + 1, + 1, + test_stress_limits["integrated_circuit"], + current_ratio=current_ratio, + package_id=3, + technology_id=2, + temperature_junction=128.3, + ) + + +@pytest.mark.unit +@pytest.mark.parametrize("junction_temperature", ["128.3", None]) +def test_do_derating_analysis_non_numeric_temperature( + junction_temperature, + test_stress_limits, +): + """should raise am TypeError when passed a non-numeric current ratio.""" + with pytest.raises(TypeError): + integratedcircuit.do_derating_analysis( + 1, + 1, + test_stress_limits["integrated_circuit"], + current_ratio=0.9, + package_id=3, + technology_id=2, + temperature_junction=junction_temperature, + ) diff --git a/tests/analyses/derating/models/lamp_derating_unit_test.py b/tests/analyses/derating/models/lamp_derating_unit_test.py new file mode 100644 index 000000000..aaecb5afc --- /dev/null +++ b/tests/analyses/derating/models/lamp_derating_unit_test.py @@ -0,0 +1,84 @@ +# pylint: skip-file +# type: ignore +# -*- coding: utf-8 -*- +# +# tests.analyses.derating.models.lamp_unit_test.py is part of The +# RAMSTK Project +# +# All rights reserved. +# Copyright since 2007 Doyle "weibullguy" Rowland doyle.rowland reliaqual com +"""Test class for the lamp derating module.""" + +# Third Party Imports +import pytest + +# RAMSTK Package Imports +from ramstk.analyses.derating import lamp + + +@pytest.mark.unit +def test_do_derating_analysis_no_stresses(test_stress_limits): + """should determine the lamp is not execeeding any limit.""" + _overstress, _reason = lamp.do_derating_analysis( + 1, + 4, + test_stress_limits["miscellaneous"], + current_ratio=0.05, + ) + + assert _overstress == 0 + assert _reason == "" + + +@pytest.mark.unit +def test_do_derating_analysis_current(test_stress_limits): + """should determine the lamp is execeeding the current limit.""" + _overstress, _reason = lamp.do_derating_analysis( + 1, + 4, + test_stress_limits["miscellaneous"], + current_ratio=0.95, + ) + + assert _overstress == 1 + assert _reason == "Current ratio of 0.95 exceeds the allowable limit of 0.1.\n" + + +@pytest.mark.unit +def test_do_derating_analysis_unknown_environment(test_stress_limits): + """should raise am IndexError when passed an unknown environment.""" + with pytest.raises(IndexError): + lamp.do_derating_analysis( + 5, + 4, + test_stress_limits["miscellaneous"], + current_ratio=0.02, + ) + + +@pytest.mark.unit +def test_do_derating_analysis_unknown_subcategory(test_stress_limits): + """should raise am KeyError when passed an unknown subcategory.""" + with pytest.raises(KeyError): + lamp.do_derating_analysis( + 1, + 21, + test_stress_limits["miscellaneous"], + current_ratio=0.025, + ) + + +@pytest.mark.unit +@pytest.mark.parametrize("current_ratio", ["0.9", None]) +def test_do_derating_analysis_non_numeric_current_ratio( + current_ratio, + test_stress_limits, +): + """should raise am TypeError when passed a non-numeric current ratio.""" + with pytest.raises(TypeError): + lamp.do_derating_analysis( + 1, + 4, + test_stress_limits["miscellaneous"], + current_ratio=current_ratio, + ) diff --git a/tests/analyses/derating/models/relay_derating_unit_test.py b/tests/analyses/derating/models/relay_derating_unit_test.py new file mode 100644 index 000000000..4eda81a4e --- /dev/null +++ b/tests/analyses/derating/models/relay_derating_unit_test.py @@ -0,0 +1,151 @@ +# pylint: skip-file +# type: ignore +# -*- coding: utf-8 -*- +# +# tests.analyses.derating.models.relay_unit_test.py is part of The +# RAMSTK Project +# +# All rights reserved. +# Copyright since 2007 Doyle "weibullguy" Rowland doyle.rowland reliaqual com +"""Test class for the relay derating module.""" + +# Third Party Imports +import pytest + +# RAMSTK Package Imports +from ramstk.analyses.derating import relay + + +@pytest.mark.unit +def test_do_derating_analysis_no_stresses(test_stress_limits): + """should determine the relay is not execeeding any limit.""" + _overstress, _reason = relay.do_derating_analysis( + 1, + test_stress_limits["relay"], + current_ratio=0.2, + temperature_active=46.3, + temperature_rated_max=85.0, + type_id=1, + ) + + assert _overstress == 0 + assert _reason == "" + + +@pytest.mark.unit +def test_do_derating_analysis_active_temperature(test_stress_limits): + """should determine the relay is exceeding the active ambient temperature limit.""" + _overstress, _reason = relay.do_derating_analysis( + 1, + test_stress_limits["relay"], + current_ratio=0.2, + temperature_active=76.3, + temperature_rated_max=85.0, + type_id=1, + ) + + assert _overstress == 1 + assert ( + _reason == "Ambient temperature of 76.3C exceeds the derated maximum " + "temperature of 20.0C less than maximum rated temperature of 85.0C.\n" + ) + + +@pytest.mark.unit +def test_do_derating_analysis_current(test_stress_limits): + """should determine the relay is execeeding the current limit.""" + _overstress, _reason = relay.do_derating_analysis( + 1, + test_stress_limits["relay"], + current_ratio=0.8, + temperature_active=46.3, + temperature_rated_max=85.0, + type_id=1, + ) + + assert _overstress == 1 + assert _reason == "Current ratio of 0.8 exceeds the allowable limit of 0.6.\n" + + +@pytest.mark.unit +def test_do_derating_analysis_all_stresses(test_stress_limits): + """should determine the relay is execeeding both limits.""" + _overstress, _reason = relay.do_derating_analysis( + 1, + test_stress_limits["relay"], + current_ratio=0.8, + temperature_active=66.3, + temperature_rated_max=85.0, + type_id=1, + ) + + assert _overstress == 1 + assert ( + _reason == "Current ratio of 0.8 exceeds the allowable limit of 0.6.\nAmbient " + "temperature of 66.3C exceeds the derated maximum temperature of 20.0C less " + "than maximum rated temperature of 85.0C.\n" + ) + + +@pytest.mark.unit +def test_do_derating_analysis_unknown_environment(test_stress_limits): + """should raise am IndexError when passed an unknown environment.""" + with pytest.raises(IndexError): + relay.do_derating_analysis( + 5, + test_stress_limits["relay"], + current_ratio=0.2, + temperature_active=46.3, + temperature_rated_max=85.0, + type_id=1, + ) + + +@pytest.mark.unit +def test_do_derating_analysis_unknown_type(test_stress_limits): + """should raise am KeyError when passed an unknown type ID.""" + with pytest.raises(KeyError): + relay.do_derating_analysis( + 1, + test_stress_limits["relay"], + current_ratio=0.2, + temperature_active=46.3, + temperature_rated_max=85.0, + type_id=11, + ) + + +@pytest.mark.unit +@pytest.mark.parametrize("active_temperature", ["128.3", None]) +def test_do_derating_analysis_non_numeric_temperature( + active_temperature, + test_stress_limits, +): + """should raise am TypeError when passed a non-numeric current ratio.""" + with pytest.raises(TypeError): + relay.do_derating_analysis( + 1, + test_stress_limits["relay"], + current_ratio=0.2, + temperature_active=active_temperature, + temperature_rated_max=85.0, + type_id=1, + ) + + +@pytest.mark.unit +@pytest.mark.parametrize("current_ratio", ["0.9", None]) +def test_do_derating_analysis_non_numeric_current_ratio( + current_ratio, + test_stress_limits, +): + """should raise am TypeError when passed a non-numeric current ratio.""" + with pytest.raises(TypeError): + relay.do_derating_analysis( + 1, + test_stress_limits["relay"], + current_ratio=current_ratio, + temperature_active=46.3, + temperature_rated_max=85.0, + type_id=1, + ) diff --git a/tests/analyses/derating/models/resistor_derating_unit_test.py b/tests/analyses/derating/models/resistor_derating_unit_test.py new file mode 100644 index 000000000..e24a452ea --- /dev/null +++ b/tests/analyses/derating/models/resistor_derating_unit_test.py @@ -0,0 +1,225 @@ +# pylint: skip-file +# type: ignore +# -*- coding: utf-8 -*- +# +# tests.analyses.derating.models.resistor_unit_test.py is part of The +# RAMSTK Project +# +# All rights reserved. +# Copyright since 2007 Doyle "weibullguy" Rowland doyle.rowland reliaqual com +"""Test class for the resistor derating module.""" + +# Third Party Imports +import pytest + +# RAMSTK Package Imports +from ramstk.analyses.derating import resistor + + +@pytest.mark.unit +def test_do_derating_analysis_no_stresses(test_stress_limits): + """should determine the resistor is not execeeding any limit.""" + _overstress, _reason = resistor.do_derating_analysis( + 1, + 2, + test_stress_limits["resistor"], + power_rated=0.125, + power_ratio=0.25, + specification_id=2, + temperature_case=46.3, + temperature_knee=70.0, + temperature_rated_max=150.0, + voltage_ratio=0.2, + ) + + assert _overstress == 0 + assert _reason == "" + + +@pytest.mark.unit +def test_do_derating_analysis_power(test_stress_limits): + """should determine the resistor is execeeding the power limit.""" + _overstress, _reason = resistor.do_derating_analysis( + 1, + 2, + test_stress_limits["resistor"], + power_rated=0.125, + power_ratio=0.75, + specification_id=2, + temperature_case=46.3, + temperature_knee=70.0, + temperature_rated_max=150.0, + voltage_ratio=0.2, + ) + + assert _overstress == 1 + assert _reason == "Power ratio of 0.75 exceeds the allowable limit of 0.65.\n" + + +@pytest.mark.unit +def test_do_derating_analysis_case_temperature(test_stress_limits): + """should determine the resistor is exceeding the case temperature limit.""" + _overstress, _reason = resistor.do_derating_analysis( + 1, + 2, + test_stress_limits["resistor"], + power_rated=0.125, + power_ratio=0.25, + specification_id=2, + temperature_case=126.3, + temperature_knee=70.0, + temperature_rated_max=150.0, + voltage_ratio=0.2, + ) + + assert _overstress == 1 + assert ( + _reason == "Case temperature of 126.3C exceeds the derated maximum temperature " + "of 122.0C.\n" + ) + + +@pytest.mark.unit +def test_do_derating_analysis_voltage(test_stress_limits): + """should determine the resistor is execeeding the voltage limit.""" + _overstress, _reason = resistor.do_derating_analysis( + 1, + 2, + test_stress_limits["resistor"], + power_rated=0.125, + power_ratio=0.25, + specification_id=2, + temperature_case=56.3, + temperature_knee=70.0, + temperature_rated_max=150.0, + voltage_ratio=0.8, + ) + + assert _overstress == 1 + assert _reason == "Voltage ratio of 0.8 exceeds the allowable limit of 0.7.\n" + + +@pytest.mark.unit +def test_do_derating_analysis_all_stresses(test_stress_limits): + """should determine the resistor is execeeding both limits.""" + _overstress, _reason = resistor.do_derating_analysis( + 1, + 6, + test_stress_limits["resistor"], + power_rated=0.125, + power_ratio=0.75, + specification_id=2, + temperature_case=128.4, + temperature_knee=70.0, + temperature_rated_max=150.0, + voltage_ratio=0.8, + ) + + assert _overstress == 1 + assert ( + _reason == "Power ratio of 0.75 exceeds the allowable limit of 0.6.\nCase " + "temperature of 128.4C exceeds the derated maximum temperature of " + "118.0C.\nVoltage ratio of 0.8 exceeds the allowable limit of 0.7.\n" + ) + + +@pytest.mark.unit +def test_do_derating_analysis_unknown_environment(test_stress_limits): + """should raise am IndexError when passed an unknown environment.""" + with pytest.raises(IndexError): + resistor.do_derating_analysis( + 5, + 2, + test_stress_limits["resistor"], + power_rated=0.125, + power_ratio=0.25, + specification_id=2, + temperature_case=68.4, + temperature_knee=70.0, + temperature_rated_max=150.0, + voltage_ratio=0.28, + ) + + +@pytest.mark.unit +def test_do_derating_analysis_unknown_subcategory(test_stress_limits): + """should raise am KeyError when passed an unknown subcategory.""" + with pytest.raises(KeyError): + resistor.do_derating_analysis( + 1, + 21, + test_stress_limits["resistor"], + power_rated=0.125, + power_ratio=0.25, + specification_id=2, + temperature_case=68.4, + temperature_knee=70.0, + temperature_rated_max=150.0, + voltage_ratio=0.28, + ) + + +@pytest.mark.unit +@pytest.mark.parametrize("power_ratio", ["0.9", None]) +def test_do_derating_analysis_non_numeric_power_ratio( + power_ratio, + test_stress_limits, +): + """should raise am TypeError when passed a non-numeric voltage ratio.""" + with pytest.raises(TypeError): + resistor.do_derating_analysis( + 1, + 2, + test_stress_limits["resistor"], + power_rated=0.125, + power_ratio=power_ratio, + specification_id=2, + temperature_case=68.4, + temperature_knee=70.0, + temperature_rated_max=150.0, + voltage_ratio=0.2, + ) + + +@pytest.mark.unit +@pytest.mark.parametrize("case_temperature", ["128.3", None]) +def test_do_derating_analysis_non_numeric_temperature( + case_temperature, + test_stress_limits, +): + """should raise am TypeError when passed a non-numeric current ratio.""" + with pytest.raises(TypeError): + resistor.do_derating_analysis( + 1, + 2, + test_stress_limits["resistor"], + power_rated=0.125, + power_ratio=0.25, + specification_id=2, + temperature_case=case_temperature, + temperature_knee=70.0, + temperature_rated_max=150.0, + voltage_ratio=0.28, + ) + + +@pytest.mark.unit +@pytest.mark.parametrize("voltage_ratio", ["0.9", None]) +def test_do_derating_analysis_non_numeric_voltage_ratio( + voltage_ratio, + test_stress_limits, +): + """should raise am TypeError when passed a non-numeric voltage ratio.""" + with pytest.raises(TypeError): + resistor.do_derating_analysis( + 1, + 2, + test_stress_limits["resistor"], + power_rated=0.125, + power_ratio=0.25, + specification_id=2, + temperature_case=68.4, + temperature_knee=70.0, + temperature_rated_max=150.0, + voltage_ratio=voltage_ratio, + ) diff --git a/tests/analyses/derating/models/semiconductor_derating_unit_test.py b/tests/analyses/derating/models/semiconductor_derating_unit_test.py new file mode 100644 index 000000000..8369bf72e --- /dev/null +++ b/tests/analyses/derating/models/semiconductor_derating_unit_test.py @@ -0,0 +1,292 @@ +# pylint: skip-file +# type: ignore +# -*- coding: utf-8 -*- +# +# tests.analyses.derating.models.semiconductor_unit_test.py is part of The +# RAMSTK Project +# +# All rights reserved. +# Copyright since 2007 Doyle "weibullguy" Rowland doyle.rowland reliaqual com +"""Test class for the semiconductor derating module.""" + +# Third Party Imports +import pytest + +# RAMSTK Package Imports +from ramstk.analyses.derating import semiconductor + + +@pytest.mark.unit +def test_do_derating_analysis_no_stresses(test_stress_limits): + """should determine the semiconductor is not execeeding any limit.""" + _overstress, _reason = semiconductor.do_derating_analysis( + 1, + 3, + test_stress_limits["semiconductor"], + current_ratio=0.5, + power_ratio=0.3, + quality_id=3, + type_id=3, + temperature_junction=78.3, + voltage_ratio=0.2, + ) + + assert _overstress == 0 + assert _reason == "" + + +@pytest.mark.unit +def test_do_derating_analysis_current(test_stress_limits): + """should determine the semiconductor is execeeding the current limit.""" + _overstress, _reason = semiconductor.do_derating_analysis( + 1, + 3, + test_stress_limits["semiconductor"], + current_ratio=0.82, + power_ratio=0.3, + quality_id=3, + type_id=3, + temperature_junction=78.3, + voltage_ratio=0.2, + ) + + assert _overstress == 1 + assert _reason == "Current ratio of 0.82 exceeds the allowable limit of 0.8.\n" + + +@pytest.mark.unit +def test_do_derating_analysis_power(test_stress_limits): + """should determine the semiconductor is execeeding the power limit.""" + _overstress, _reason = semiconductor.do_derating_analysis( + 1, + 3, + test_stress_limits["semiconductor"], + current_ratio=0.72, + power_ratio=0.9, + quality_id=3, + type_id=3, + temperature_junction=78.3, + voltage_ratio=0.2, + ) + + assert _overstress == 1 + assert _reason == "Power ratio of 0.9 exceeds the allowable limit of 0.8.\n" + + +@pytest.mark.unit +def test_do_derating_analysis_junction_temperature(test_stress_limits): + """should determine the semiconductor is execeeding the junction temperature + limit.""" + _overstress, _reason = semiconductor.do_derating_analysis( + 1, + 3, + test_stress_limits["semiconductor"], + current_ratio=0.72, + power_ratio=0.53, + quality_id=3, + type_id=3, + temperature_junction=118.3, + voltage_ratio=0.2, + ) + + assert _overstress == 1 + assert ( + _reason == "Junction temperature of 118.3C exceeds the allowable limit of " + "85.0C.\n" + ) + + +@pytest.mark.unit +def test_do_derating_analysis_voltage(test_stress_limits): + """should determine the semiconductor is execeeding the voltage limit.""" + _overstress, _reason = semiconductor.do_derating_analysis( + 1, + 3, + test_stress_limits["semiconductor"], + current_ratio=0.72, + power_ratio=0.53, + quality_id=3, + type_id=3, + temperature_junction=78.3, + voltage_ratio=0.92, + ) + + assert _overstress == 1 + assert _reason == "Voltage ratio of 0.92 exceeds the allowable limit of 0.75.\n" + + +@pytest.mark.unit +def test_do_derating_analysis_all_stresses(test_stress_limits): + """should determine the semiconductor is execeeding both limits.""" + _overstress, _reason = semiconductor.do_derating_analysis( + 1, + 3, + test_stress_limits["semiconductor"], + current_ratio=0.92, + power_ratio=0.93, + quality_id=3, + type_id=3, + temperature_junction=128.3, + voltage_ratio=0.92, + ) + + assert _overstress == 1 + assert ( + _reason == "Current ratio of 0.92 exceeds the allowable limit of 0.8.\nPower " + "ratio of 0.93 exceeds the allowable limit of 0.8.\nJunction " + "temperature of 128.3C exceeds the allowable limit of " + "85.0C.\nVoltage ratio of 0.92 exceeds the allowable limit of " + "0.75.\n" + ) + + +@pytest.mark.unit +def test_do_derating_analysis_unknown_environment(test_stress_limits): + """should raise am IndexError when passed an unknown environment.""" + with pytest.raises(IndexError): + semiconductor.do_derating_analysis( + 5, + 3, + test_stress_limits["semiconductor"], + current_ratio=0.2, + power_ratio=0.3, + quality_id=3, + type_id=3, + temperature_junction=68.3, + voltage_ratio=0.2, + ) + + +@pytest.mark.unit +def test_do_derating_analysis_unknown_subcategory(test_stress_limits): + """should raise am KeyError when passed an unknown subcategory.""" + with pytest.raises(KeyError): + semiconductor.do_derating_analysis( + 1, + 21, + test_stress_limits["semiconductor"], + current_ratio=0.2, + power_ratio=0.3, + quality_id=3, + type_id=3, + temperature_junction=68.3, + voltage_ratio=0.2, + ) + + +@pytest.mark.unit +def test_do_derating_analysis_unknown_quality(test_stress_limits): + """should raise am KeyError when passed an unknown quality ID.""" + with pytest.raises(KeyError): + semiconductor.do_derating_analysis( + 1, + 3, + test_stress_limits["semiconductor"], + current_ratio=0.2, + power_ratio=0.3, + quality_id=31, + type_id=3, + temperature_junction=68.3, + voltage_ratio=0.2, + ) + + +@pytest.mark.unit +def test_do_derating_analysis_unknown_type(test_stress_limits): + """should raise am KeyError when passed an unknown type ID.""" + with pytest.raises(KeyError): + semiconductor.do_derating_analysis( + 1, + 1, + test_stress_limits["semiconductor"], + current_ratio=0.2, + power_ratio=0.3, + quality_id=3, + type_id=31, + temperature_junction=68.3, + voltage_ratio=0.2, + ) + + +@pytest.mark.unit +@pytest.mark.parametrize("current_ratio", ["0.9", None]) +def test_do_derating_analysis_non_numeric_current_ratio( + current_ratio, + test_stress_limits, +): + """should raise am TypeError when passed a non-numeric current ratio.""" + with pytest.raises(TypeError): + semiconductor.do_derating_analysis( + 1, + 3, + test_stress_limits["semiconductor"], + current_ratio=current_ratio, + power_ratio=0.3, + quality_id=3, + type_id=3, + temperature_junction=68.3, + voltage_ratio=0.2, + ) + + +@pytest.mark.unit +@pytest.mark.parametrize("power_ratio", ["0.9", None]) +def test_do_derating_analysis_non_numeric_power_ratio( + power_ratio, + test_stress_limits, +): + """should raise am TypeError when passed a non-numeric power ratio.""" + with pytest.raises(TypeError): + semiconductor.do_derating_analysis( + 1, + 3, + test_stress_limits["semiconductor"], + current_ratio=0.3, + power_ratio=power_ratio, + quality_id=3, + type_id=3, + temperature_junction=68.3, + voltage_ratio=0.2, + ) + + +@pytest.mark.unit +@pytest.mark.parametrize("junction_temperature", ["128.3", None]) +def test_do_derating_analysis_non_numeric_temperature( + junction_temperature, + test_stress_limits, +): + """should raise am TypeError when passed a non-numeric current ratio.""" + with pytest.raises(TypeError): + semiconductor.do_derating_analysis( + 1, + 1, + test_stress_limits["semiconductor"], + current_ratio=0.9, + power_ratio=0.3, + quality_id=3, + type_id=3, + temperature_junction=junction_temperature, + voltage_ratio=0.2, + ) + + +@pytest.mark.unit +@pytest.mark.parametrize("voltage_ratio", ["0.9", None]) +def test_do_derating_analysis_non_numeric_voltage_ratio( + voltage_ratio, + test_stress_limits, +): + """should raise am TypeError when passed a non-numeric voltage ratio.""" + with pytest.raises(TypeError): + semiconductor.do_derating_analysis( + 1, + 3, + test_stress_limits["semiconductor"], + current_ratio=0.3, + power_ratio=0.3, + quality_id=3, + type_id=3, + temperature_junction=68.3, + voltage_ratio=voltage_ratio, + ) diff --git a/tests/analyses/derating/models/switch_derating_unit_test.py b/tests/analyses/derating/models/switch_derating_unit_test.py new file mode 100644 index 000000000..82719bf96 --- /dev/null +++ b/tests/analyses/derating/models/switch_derating_unit_test.py @@ -0,0 +1,139 @@ +# pylint: skip-file +# type: ignore +# -*- coding: utf-8 -*- +# +# tests.analyses.derating.models.switch_unit_test.py is part of The +# RAMSTK Project +# +# All rights reserved. +# Copyright since 2007 Doyle "weibullguy" Rowland doyle.rowland reliaqual com +"""Test class for the switch derating module.""" + +# Third Party Imports +import pytest + +# RAMSTK Package Imports +from ramstk.analyses.derating import switch + + +@pytest.mark.unit +def test_do_derating_analysis_no_stresses(test_stress_limits): + """should determine the switch is not execeeding any limit.""" + _overstress, _reason = switch.do_derating_analysis( + 1, + test_stress_limits["switch"], + application_id=2, + current_ratio=0.3, + power_ratio=0.2, + ) + + assert _overstress == 0 + assert _reason == "" + + +@pytest.mark.unit +def test_do_derating_analysis_current(test_stress_limits): + """should determine the switch is execeeding the current limit.""" + _overstress, _reason = switch.do_derating_analysis( + 1, + test_stress_limits["switch"], + application_id=2, + current_ratio=0.86, + power_ratio=0.2, + ) + + assert _overstress == 1 + assert _reason == "Current ratio of 0.86 exceeds the allowable limit of 0.4.\n" + + +@pytest.mark.unit +def test_do_derating_analysis_power(test_stress_limits): + """should determine the switch is execeeding the power limit.""" + _overstress, _reason = switch.do_derating_analysis( + 1, + test_stress_limits["switch"], + application_id=2, + current_ratio=0.1, + power_ratio=0.92, + ) + + assert _overstress == 1 + assert _reason == "Power ratio of 0.92 exceeds the allowable limit of 0.6.\n" + + +@pytest.mark.unit +def test_do_derating_analysis_all_stresses(test_stress_limits): + """should determine the switch is execeeding both limits.""" + _overstress, _reason = switch.do_derating_analysis( + 1, + test_stress_limits["switch"], + application_id=2, + current_ratio=0.86, + power_ratio=0.92, + ) + + assert _overstress == 1 + assert ( + _reason == "Current ratio of 0.86 exceeds the allowable limit of 0.4.\nPower " + "ratio of 0.92 exceeds the allowable limit of 0.6.\n" + ) + + +@pytest.mark.unit +def test_do_derating_analysis_unknown_environment(test_stress_limits): + """should raise am IndexError when passed an unknown environment.""" + with pytest.raises(IndexError): + switch.do_derating_analysis( + 5, + test_stress_limits["switch"], + application_id=2, + current_ratio=0.1, + power_ratio=0.2, + ) + + +@pytest.mark.unit +def test_do_derating_analysis_unknown_application(test_stress_limits): + """should raise am KeyError when passed an unknown application ID.""" + with pytest.raises(KeyError): + switch.do_derating_analysis( + 1, + test_stress_limits["switch"], + application_id=21, + current_ratio=0.1, + power_ratio=0.2, + ) + + +@pytest.mark.unit +@pytest.mark.parametrize("current_ratio", ["0.9", None]) +def test_do_derating_analysis_non_numeric_current_ratio( + current_ratio, + test_stress_limits, +): + """should raise am TypeError when passed a non-numeric current ratio.""" + with pytest.raises(TypeError): + switch.do_derating_analysis( + 1, + test_stress_limits["switch"], + application_id=2, + current_ratio=current_ratio, + power_ratio=0.2, + ) + + +@pytest.mark.unit +@pytest.mark.parametrize("power_ratio", ["0.9", None]) +def test_do_derating_analysis_non_numeric_power_ratio( + power_ratio, + test_stress_limits, +): + """should raise am TypeError when passed a non-numeric power ratio.""" + with pytest.raises(TypeError): + switch.do_derating_analysis( + 1, + test_stress_limits["switch"], + application_id=2, + current_ratio=0.1, + power_ratio=power_ratio, + ) diff --git a/tests/analyses/test_derating.py b/tests/analyses/test_derating.py deleted file mode 100644 index c1d365f9f..000000000 --- a/tests/analyses/test_derating.py +++ /dev/null @@ -1,154 +0,0 @@ -# pylint: skip-file -# type: ignore -# -*- coding: utf-8 -*- -# -# tests.analyses.test_derating.py is part of The RAMSTK Project -# -# All rights reserved. -# Copyright 2019 Doyle Rowland doyle.rowland reliaqual com -"""Test class for the stress derating module.""" - -# Third Party Imports -import pytest - -# RAMSTK Package Imports -from ramstk.analyses import derating - - -@pytest.mark.unit -@pytest.mark.calculation -def test_check_overstress(): - """check_overstress() should return a dict of environ:condition pairs on success.""" - _overstress = derating.check_overstress( - 0.625, - { - "mild": [0.0, 0.9], - "harsh": [0.0, 0.75], - }, - ) - - assert _overstress["mild"] == [False, False] - assert _overstress["harsh"] == [False, False] - - -@pytest.mark.unit -@pytest.mark.calculation -def test_check_overstress_under_limit(): - """check_overstress() should return a dict of environ:condition pairs on success with the below lower limit set to True.""" - _overstress = derating.check_overstress( - -0.625, - { - "mild": [0.0, 0.9], - "harsh": [0.0, 0.75], - }, - ) - - assert _overstress["mild"] == [True, False] - assert _overstress["harsh"] == [True, False] - - -@pytest.mark.unit -@pytest.mark.calculation -def test_check_overstress_over_limit_harsh(): - """check_overstress() should return a dict of environ:condition pairs on success with the above upper limit set to True for a harsh environment.""" - _overstress = derating.check_overstress( - 0.825, - { - "mild": [0.0, 0.9], - "harsh": [0.0, 0.75], - }, - ) - - assert _overstress["mild"] == [False, False] - assert _overstress["harsh"] == [False, True] - - -@pytest.mark.unit -@pytest.mark.calculation -def test_check_overstress_over_limit_harsh_mild(): - """check_overstress() should return a dict of environ:condition pairs on success with the above upper limit set to True for both mild and harsh environments.""" - _overstress = derating.check_overstress( - 0.925, - { - "mild": [0.0, 0.9], - "harsh": [0.0, 0.75], - }, - ) - - assert _overstress["mild"] == [False, True] - assert _overstress["harsh"] == [False, True] - - -@pytest.mark.unit -@pytest.mark.calculation -def test_check_overstress_limits_not_lists(): - """check_overstress() should raise a TypeError if the limits passed are not a list.""" - with pytest.raises(TypeError): - _overstress = derating.check_overstress( - 0.625, - { - "mild": 0.9, - "harsh": 0.75, - }, - ) - - -@pytest.mark.unit -@pytest.mark.calculation -def test_check_overstress_only_one_limit(): - """check_overstress() should raise an IndexError if only one limit is passed in the list.""" - with pytest.raises(IndexError): - _overstress = derating.check_overstress( - 0.625, - { - "mild": [ - 0.9, - ], - "harsh": [ - 0.75, - ], - }, - ) - - -@pytest.mark.unit -@pytest.mark.calculation -def test_check_overstress_string_input(): - """check_overstress() should raise an TypeError if a limit or stress is passed as string.""" - with pytest.raises(TypeError): - _overstress = derating.check_overstress( - 0.625, - { - "mild": [0.0, "0.9"], - "harsh": [0.0, 0.75], - }, - ) - - with pytest.raises(TypeError): - _overstress = derating.check_overstress( - "0.625", - { - "mild": [0.0, 0.9], - "harsh": [0.0, 0.75], - }, - ) - - -@pytest.mark.unit -@pytest.mark.calculation -def test_check_overstress_more_than_two_environs(): - """check_overstress() should work with any number of environments passed.""" - _overstress = derating.check_overstress( - 0.625, - { - "mild": [0.0, 0.9], - "harsh": [0.0, 0.75], - "protected": [0.5, 0.8], - "daddy_doyle": [0.25, 0.75], - }, - ) - - assert _overstress["mild"] == [False, False] - assert _overstress["harsh"] == [False, False] - assert _overstress["protected"] == [False, False] - assert _overstress["daddy_doyle"] == [False, False] diff --git a/tests/conftest.py b/tests/conftest.py index a78b521aa..81f39256e 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -52,18 +52,18 @@ sys.exit(1) SRC_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) -CONF_DIR = VIRTUAL_ENV + "/share/RAMSTK" -DATA_DIR = CONF_DIR + "/layouts" -ICON_DIR = CONF_DIR + "/icons" -TMP_DIR = VIRTUAL_ENV + "/tmp" -LOG_DIR = TMP_DIR + "/logs" -TEST_PROGRAM_DB_PATH = TMP_DIR + "/TestProgramDB.ramstk" -TEST_COMMON_DB_PATH = TEMPDIR + "/TestCommonDB.ramstk" -TEST_COMMON_DB_URI = "sqlite:///" + TEST_COMMON_DB_PATH - -DEBUG_LOG = LOG_DIR + "/RAMSTK_debug.log" -USER_LOG = LOG_DIR + "/RAMSTK_user.log" -IMPORT_LOG = LOG_DIR + "/RAMSTK_import.log" +CONF_DIR = f"{VIRTUAL_ENV}/share/RAMSTK" +DATA_DIR = f"{CONF_DIR}/layouts" +ICON_DIR = f"{CONF_DIR}/icons" +TMP_DIR = f"{VIRTUAL_ENV}/tmp" +LOG_DIR = f"{TMP_DIR}/logs" +TEST_PROGRAM_DB_PATH = f"{TMP_DIR}/TestProgramDB.ramstk" +TEST_COMMON_DB_PATH = f"{TEMPDIR}/TestCommonDB.ramstk" +TEST_COMMON_DB_URI = f"sqlite:///{TEST_COMMON_DB_PATH}" + +DEBUG_LOG = f"{LOG_DIR}/RAMSTK_debug.log" +USER_LOG = f"{LOG_DIR}/RAMSTK_user.log" +IMPORT_LOG = f"{LOG_DIR}/RAMSTK_import.log" HEADERS = { "Function": [ @@ -396,8 +396,8 @@ def setup_test_directory(test_dir) -> None: def populate_test_directory(test_dir) -> None: - dir_util.copy_tree(os.getcwd() + "/data/icons/", test_dir + "/icons/") - dir_util.copy_tree(os.getcwd() + "/data/layouts/", test_dir + "/layouts/") + dir_util.copy_tree(f"{os.getcwd()}/data/icons/", f"{test_dir}/icons/") + dir_util.copy_tree(f"{os.getcwd()}/data/layouts/", f"{test_dir}/layouts/") def teardown_test_directory(test_dir) -> None: @@ -504,7 +504,7 @@ def test_config_dir(): allow testing certain functions/methods that look for a user configuration directory otherwise defaulting to the site-wide configuration directory. """ - _config_dir = VIRTUAL_ENV + "/share/RAMSTK" + _config_dir = f"{VIRTUAL_ENV}/share/RAMSTK" # Set up the test configuration directories. setup_test_directory(test_dir=_config_dir) @@ -520,7 +520,7 @@ def test_import_dir(): """Create a directory for export testing.""" # This simply creates the base name of the file and directory to create it # in. A test would need to add the appropriate file extension. - _import_dir = TMP_DIR + "/test_imports" + _import_dir = f"{TMP_DIR}/test_imports" # Set up the test import directory. setup_test_directory(test_dir=_import_dir) @@ -536,7 +536,7 @@ def test_export_dir(): """Create a directory for export testing.""" # This simply creates the base name of the file and directory to create it # in. A test would need to add the appropriate file extension. - _export_dir = TMP_DIR + "/test_exports/" + _export_dir = f"{TMP_DIR}/test_exports/" # Set up the test export directory. setup_test_directory(test_dir=_export_dir) @@ -550,24 +550,24 @@ def test_export_dir(): @pytest.fixture(scope="session") def make_home_config_dir(): """Create a configuration directory to mimic a user's configuration directory.""" - _config_dir = VIRTUAL_ENV + "/tmp/.config/RAMSTK" + _config_dir = f"{VIRTUAL_ENV}/tmp/.config/RAMSTK" # Set up the test home configuration directory. setup_test_directory(_config_dir) - setup_test_directory(_config_dir + "/layouts") - setup_test_directory(_config_dir + "/icons") - setup_test_directory(_config_dir + "/log") + setup_test_directory(f"{_config_dir}/layouts") + setup_test_directory(f"{_config_dir}/icons") + setup_test_directory(f"{_config_dir}/log") # Set up the test analyses directory. - _analyses_dir = "{0}/tmp/analyses/ramstk".format(VIRTUAL_ENV) + _analyses_dir = f"{VIRTUAL_ENV}/tmp/analyses/ramstk" setup_test_directory(_analyses_dir) shutil.copyfile( - "./data/sqlite_program_db.sql", _config_dir + "/sqlite_program_db.sql" + "./data/sqlite_program_db.sql", f"{_config_dir}/sqlite_program_db.sql" ) shutil.copyfile( "./data/postgres_program_db.sql", - _config_dir + "/postgres_program_db.sql", + f"{_config_dir}/postgres_program_db.sql", ) yield _config_dir @@ -604,7 +604,7 @@ def test_common_dao(): "password": "postgres", "host": "localhost", "port": "5432", - "database": "test_common_db_{}".format(db_name), + "database": f"test_common_db_{db_name}", } # Set up the test database. @@ -643,7 +643,7 @@ def test_program_dao(): "password": "postgres", "host": "localhost", "port": "5432", - "database": "test_program_db_{}".format(db_name), + "database": f"test_program_db_{db_name}", } # Set up the test database. @@ -685,7 +685,7 @@ def test_simple_database(): "password": "postgres", "host": "localhost", "port": "5432", - "database": "test_simple_db_{}".format(db_name), + "database": f"test_simple_db_{db_name}", } # Set up the test database. @@ -723,7 +723,7 @@ def test_simple_program_database(): "password": "postgres", "host": "localhost", "port": "5432", - "database": "test_simple_program_db_{}".format(db_name), + "database": f"test_simple_program_db_{db_name}", } # Set up the test database. @@ -745,7 +745,7 @@ def test_simple_program_database(): def test_license_file(): """Create a license key file for testing.""" _cwd = os.getcwd() - with open(_cwd + "/license.key", "w") as _license_file: + with open(f"{_cwd}/license.key", "w") as _license_file: _license_file.write("0\n") _license_file.write("apowdigfb3rh9214839qu\n") _license_file.write("2019-08-07\n") @@ -769,13 +769,13 @@ def test_license_file(): _license_file.write("ReliaQual Test Site") yield _license_file - os.remove(_cwd + "/license.key") + os.remove(f"{_cwd}/license.key") @pytest.fixture def test_log_file(): """Create a log file.""" - _test_file = TMP_DIR + "/test_file.log" + _test_file = f"{TMP_DIR}/test_file.log" Path(_test_file).touch() yield _test_file @@ -787,14 +787,14 @@ def test_log_file(): def test_toml_site_configuration(test_config_dir): """Create a toml site configuration file.""" _site_config = RAMSTKSiteConfiguration() - _site_config.RAMSTK_SITE_CONF = VIRTUAL_ENV + "/share/RAMSTK/Site.toml" + _site_config.RAMSTK_SITE_CONF = f"{VIRTUAL_ENV}/share/RAMSTK/Site.toml" _dic_site_configuration = { "title": "RAMSTK Site Configuration", "backend": { "dialect": "sqlite", "host": "localhost", "port": "3306", - "database": VIRTUAL_ENV + "/share/RAMSTK/ramstk_common.ramstk", + "database": f"{VIRTUAL_ENV}/share/RAMSTK/ramstk_common.ramstk", "user": "johnny.tester", "password": "clear.text.password", }, @@ -810,13 +810,13 @@ def test_toml_user_configuration(make_home_config_dir): """Create a toml user configuration file.""" _user_config = RAMSTKUserConfiguration() _user_config._INSTALL_PREFIX = VIRTUAL_ENV - _user_config.RAMSTK_HOME_DIR = VIRTUAL_ENV + "/tmp" - _user_config.RAMSTK_CONF_DIR = VIRTUAL_ENV + "/tmp/.config/RAMSTK" - _user_config.RAMSTK_PROG_CONF = _user_config.RAMSTK_CONF_DIR + "/RAMSTK.toml" - _user_config.RAMSTK_DATA_DIR = _user_config.RAMSTK_CONF_DIR + "/layouts" - _user_config.RAMSTK_ICON_DIR = _user_config.RAMSTK_CONF_DIR + "/icons" - _user_config.RAMSTK_LOG_DIR = _user_config.RAMSTK_CONF_DIR + "/logs" - _user_config.RAMSTK_PROG_DIR = VIRTUAL_ENV + "/tmp/analyses/ramstk" + _user_config.RAMSTK_HOME_DIR = f"{VIRTUAL_ENV}/tmp" + _user_config.RAMSTK_CONF_DIR = f"{VIRTUAL_ENV}/tmp/.config/RAMSTK" + _user_config.RAMSTK_PROG_CONF = f"{_user_config.RAMSTK_CONF_DIR}/RAMSTK.toml" + _user_config.RAMSTK_DATA_DIR = f"{_user_config.RAMSTK_CONF_DIR}/layouts" + _user_config.RAMSTK_ICON_DIR = f"{_user_config.RAMSTK_CONF_DIR}/icons" + _user_config.RAMSTK_LOG_DIR = f"{_user_config.RAMSTK_CONF_DIR}/logs" + _user_config.RAMSTK_PROG_DIR = f"{VIRTUAL_ENV}/tmp/analyses/ramstk" _dic_user_configuration = { "title": "RAMSTK User Configuration", "general": { @@ -887,82 +887,537 @@ def test_toml_user_configuration(make_home_config_dir): "validationfg": "#000000", }, "stress": { - "integratedcircuit": [ - 0.8, - 0.9, - 1.0, - 1.0, - 1.0, - 1.0, - 0.0, - 0.0, - 125.0, - 125.0, - ], - "semiconductor": [ - 1.0, - 1.0, - 0.7, - 0.9, - 1.0, - 1.0, - 0.0, - 0.0, - 125.0, - 125.0, - ], - "resistor": [1.0, 1.0, 0.5, 0.9, 1.0, 1.0, 0.0, 0.0, 125.0, 125.0], - "capacitor": [ - 1.0, - 1.0, - 1.0, - 1.0, - 0.6, - 0.9, - 10.0, - 0.0, - 125.0, - 125.0, - ], - "inductor": [ - 0.6, - 0.9, - 1.0, - 1.0, - 0.5, - 0.9, - 15.0, - 0.0, - 125.0, - 125.0, - ], - "relay": [0.75, 0.9, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 125.0, 125.0], - "switch": [0.75, 0.9, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 125.0, 125.0], - "connection": [ - 0.7, - 0.9, - 1.0, - 1.0, - 0.7, - 0.9, - 25.0, - 0.0, - 125.0, - 125.0, - ], - "meter": [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 125.0, 125.0], - "miscellaneous": [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0, - 1.0, - 0.0, - 0.0, - 125.0, - 125.0, - ], + "integrated_circuit": { + "digital": { + "mos": { + "hermetic": { + "current": [0.9, 0.85, 0.8], + "fanout": [1.0, 0.9, 0.9], + "frequency": [0.9, 0.9, 0.9], + "temperature": [125.0, 110.0, 100.0], + }, + "plastic1": { + "current": [0.9, 0.8, 0.0], + "fanout": [1.0, 0.9, 0.0], + "frequency": [0.9, 0.8, 0.0], + "temperature": [90.0, 85.0, 0.0], + }, + "plastic2": { + "current": [0.7, 0.0, 0.0], + "fanout": [0.8, 0.0, 0.0], + "frequency": [0.8, 0.0, 0.0], + "temperature": [70.0, 0.0, 0.0], + }, + }, + "bipolar": { + "hermetic": { + "current": [0.9, 0.85, 0.8], + "fanout": [0.9, 0.85, 0.8], + "frequency": [1.0, 0.9, 0.85], + "temperature": [125.0, 110.0, 100.0], + }, + "plastic1": { + "current": [0.9, 0.8, 0.0], + "fanout": [0.9, 0.8, 0.0], + "frequency": [1.0, 0.9, 0.0], + "temperature": [90.0, 85.0, 0.0], + }, + "plastic2": { + "current": [0.7, 0.0, 0.0], + "fanout": [0.7, 0.0, 0.0], + "frequency": [0.75, 0.0, 0.0], + "temperature": [70.0, 0.0, 0.0], + }, + }, + }, + "linear": { + "mos": { + "hermetic": { + "current": [0.9, 0.85, 0.8], + "fanout": [1.0, 0.9, 0.9], + "frequency": [0.9, 0.9, 0.9], + "temperature": [125.0, 110.0, 100.0], + "voltage": [0.8, 0.8, 0.7], + }, + "plastic1": { + "current": [0.9, 0.8, 0.0], + "fanout": [1.0, 0.9, 0.0], + "frequency": [0.9, 0.8, 0.0], + "temperature": [90.0, 85.0, 0.0], + "voltage": [0.8, 0.7, 0.0], + }, + "plastic2": { + "current": [0.7, 0.0, 0.0], + "fanout": [0.8, 0.0, 0.0], + "frequency": [0.8, 0.0, 0.0], + "temperature": [70.0, 0.0, 0.0], + "voltage": [0.6, 0.0, 0.0], + }, + }, + "bipolar": { + "hermetic": { + "current": [0.9, 0.85, 0.8], + "fanout": [0.9, 0.85, 0.8], + "frequency": [1.0, 0.9, 0.85], + "temperature": [125.0, 110.0, 100.0], + "voltage": [0.8, 0.8, 0.7], + }, + "plastic1": { + "current": [0.9, 0.8, 0.0], + "fanout": [0.9, 0.8, 0.0], + "frequency": [1.0, 0.9, 0.0], + "temperature": [90.0, 85.0, 0.0], + "voltage": [0.8, 0.7, 0.0], + }, + "plastic2": { + "current": [0.7, 0.0, 0.0], + "fanout": [0.7, 0.0, 0.0], + "frequency": [0.75, 0.0, 0.0], + "temperature": [70.0, 0.0, 0.0], + "voltage": [0.6, 0.0, 0.0], + }, + }, + }, + "microprocessor": { + "mos": { + "hermetic": { + "current": [0.9, 0.85, 0.8], + "fanout": [1.0, 0.9, 0.9], + "frequency": [0.9, 0.9, 0.9], + "temperature": [125.0, 110.0, 100.0], + }, + "plastic1": { + "current": [0.9, 0.8, 0.0], + "fanout": [1.0, 0.85, 0.0], + "frequency": [0.9, 0.8, 0.0], + "temperature": [85.0, 75.0, 0.0], + }, + "plastic2": { + "current": [0.7, 0.0, 0.0], + "fanout": [0.8, 0.0, 0.0], + "frequency": [0.8, 0.0, 0.0], + "temperature": [70.0, 0.0, 0.0], + }, + }, + "bipolar": { + "hermetic": { + "current": [0.8, 0.75, 0.7], + "fanout": [0.8, 0.75, 0.7], + "frequency": [0.9, 0.8, 0.75], + "temperature": [125.0, 110.0, 100.0], + }, + "plastic1": { + "current": [0.8, 0.75, 0.0], + "fanout": [0.8, 0.75, 0.0], + "frequency": [0.9, 0.8, 0.0], + "temperature": [85.0, 75.0, 0.0], + }, + "plastic2": { + "current": [0.7, 0.0, 0.0], + "fanout": [0.7, 0.0, 0.0], + "frequency": [0.75, 0.0, 0.0], + "temperature": [70.0, 0.0, 0.0], + }, + }, + }, + "memory": { + "mos": { + "hermetic": { + "current": [0.9, 0.85, 0.8], + "frequency": [1.0, 0.9, 0.9], + "temperature": [125.0, 110.0, 100.0], + }, + "plastic1": { + "current": [0.9, 0.8, 0.0], + "frequency": [1.0, 0.9, 0.0], + "temperature": [90.0, 85.0, 0.0], + }, + "plastic2": { + "current": [0.7, 0.0, 0.0], + "frequency": [0.8, 0.0, 0.0], + "temperature": [70.0, 0.0, 0.0], + }, + }, + "bipolar": { + "hermetic": { + "current": [0.9, 0.85, 0.8], + "frequency": [1.0, 1.0, 0.9], + "temperature": [125.0, 110.0, 100.0], + }, + "plastic1": { + "current": [0.9, 0.8, 0.0], + "frequency": [1.0, 0.95, 0.0], + "temperature": [90.0, 85.0, 0.0], + }, + "plastic2": { + "current": [0.7, 0.0, 0.0], + "frequency": [0.8, 0.0, 0.0], + "temperature": [70.0, 0.0, 0.0], + }, + }, + }, + }, + "semiconductor": { + "diode": { + "general_purpose": { + "jantx": { + "current": [1.0, 1.0, 1.0], + "surge_current": [1.0, 0.9, 0.8], + "voltage": [0.95, 0.9, 0.85], + "temperature": [150.0, 125.0, 125.0], + }, + "military": { + "current": [0.9, 0.9, 0.7], + "surge_current": [0.8, 0.8, 0.5], + "voltage": [0.8, 0.75, 0.5], + "temperature": [100.0, 85.0, 70.0], + }, + "commercial": { + "current": [0.75, 0.7, 0.0], + "surge_current": [0.6, 0.3, 0.0], + "voltage": [0.7, 0.6, 0.0], + "temperature": [70.0, 35.0, 0.0], + }, + }, + "power_rectifier": { + "jantx": { + "current": [1.0, 1.0, 1.0], + "voltage": [0.95, 0.9, 0.85], + "temperature": [150.0, 125.0, 125.0], + }, + "military": { + "current": [0.9, 0.85, 0.6], + "voltage": [0.8, 0.75, 0.3], + "temperature": [100.0, 85.0, 70.0], + }, + "commercial": { + "current": [0.6, 0.5, 0.0], + "voltage": [0.5, 0.3, 0.0], + "temperature": [70.0, 35.0, 0.0], + }, + }, + "schottky": { + "jantx": { + "power": [1.0, 1.0, 0.9], + "voltage": [0.95, 0.9, 0.85], + "temperature": [150.0, 125.0, 125.0], + }, + "military": { + "power": [0.9, 0.9, 0.5], + "voltage": [0.8, 0.8, 0.25], + "temperature": [100.0, 85.0, 70.0], + }, + "commercial": { + "power": [0.75, 0.75, 0.0], + "voltage": [0.5, 0.3, 0.0], + "temperature": [70.0, 35.0, 0.0], + }, + }, + "regulator": { + "jantx": { + "power": [1.0, 1.0, 0.9], + "temperature": [150.0, 125.0, 125.0], + }, + "military": { + "power": [0.9, 0.8, 0.5], + "temperature": [100.0, 85.0, 70.0], + }, + "commercial": { + "power": [0.5, 0.5, 0.0], + "temperature": [70.0, 35.0, 0.0], + }, + }, + "suppressor": { + "jantx": { + "current": [1.0, 1.0, 0.9], + "power": [1.0, 1.0, 0.9], + "temperature": [150.0, 125.0, 125.0], + }, + "military": { + "current": [0.8, 0.8, 0.5], + "power": [0.8, 0.8, 0.5], + "temperature": [100.0, 85.0, 70.0], + }, + "commercial": { + "current": [0.75, 0.5, 0.0], + "power": [0.75, 0.5, 0.0], + "temperature": [70.0, 35.0, 0.0], + }, + }, + }, + "thyristor": { + "jantx": { + "current": [1.0, 1.0, 0.9], + "temperature": [150.0, 125.0, 125.0], + "voltage": [1.0, 1.0, 0.9], + }, + "military": { + "current": [0.9, 0.8, 0.5], + "temperature": [100.0, 85.0, 70.0], + "voltage": [0.9, 0.8, 0.5], + }, + "commercial": { + "current": [0.6, 0.5, 0.0], + "temperature": [70.0, 35.0, 0.0], + "voltage": [0.6, 0.5, 0.0], + }, + }, + "transistor": { + "bjt": { + "jantx": { + "current": [1.0, 0.9, 0.9], + "power": [1.0, 1.0, 0.9], + "temperature": [150.0, 125.0, 125.0], + "voltage": [1.0, 0.9, 0.8], + }, + "military": { + "current": [0.9, 0.8, 0.6], + "power": [0.9, 0.8, 0.6], + "temperature": [100.0, 85.0, 70.0], + "voltage": [0.8, 0.75, 0.3], + }, + "commercial": { + "current": [0.5, 0.5, 0.0], + "power": [0.5, 0.5, 0.0], + "temperature": [70.0, 35.0, 0.0], + "voltage": [0.25, 0.25, 0.0], + }, + }, + "fet": { + "jantx": { + "power": [1.0, 1.0, 0.9], + "temperature": [150.0, 125.0, 125.0], + "voltage": [1.0, 0.95, 0.9], + }, + "military": { + "power": [0.9, 0.8, 0.5], + "temperature": [100.0, 85.0, 70.0], + "voltage": [0.8, 0.75, 0.5], + }, + "commercial": { + "power": [0.5, 0.5, 0.0], + "temperature": [70.0, 35.0, 0.0], + "voltage": [0.25, 0.25, 0.0], + }, + }, + }, + }, + "resistor": { + "fixed_composition": { + "low_power": { + "power": [0.65, 0.65, 0.65], + "temperature": [0.65, 0.65, 0.65], + "voltage": [0.7, 0.7, 0.7], + }, + "high_power": { + "power": [0.55, 0.55, 0.55], + "temperature": [0.55, 0.55, 0.55], + "voltage": [0.7, 0.7, 0.7], + }, + }, + "fixed_chip": { + "low_power": { + "power": [0.7, 0.7, 0.7], + "temperature": [0.7, 0.7, 0.7], + }, + "high_power": { + "power": [0.55, 0.55, 0.55], + "temperature": [0.55, 0.55, 0.55], + }, + }, + "fixed_film": { + "low_power": { + "power": [0.65, 0.65, 0.65], + "temperature": [0.65, 0.65, 0.65], + "voltage": [0.7, 0.7, 0.7], + }, + "high_power": { + "power": [0.55, 0.55, 0.55], + "temperature": [0.55, 0.55, 0.55], + "voltage": [0.7, 0.7, 0.7], + }, + }, + "fixed_film_power": { + "power": [0.55, 0.55, 0.55], + "temperature": [0.55, 0.55, 0.55], + }, + "fixed_film_network": { + "power": [0.55, 0.55, 0.55], + "temperature": [0.55, 0.55, 0.55], + "voltage": [0.7, 0.7, 0.7], + }, + "fixed_wirewound": { + "low_power": { + "power": [0.7, 0.7, 0.7], + "temperature": [1.0, 1.0, 1.0], + "voltage": [0.7, 0.7, 0.7], + }, + "high_power": { + "power": [0.5, 0.5, 0.5], + "temperature": [1.0, 1.0, 1.0], + "voltage": [0.7, 0.7, 0.7], + }, + }, + "fixed_wirewound_power": { + "power": [0.6, 0.6, 0.6], + "temperature": [0.6, 0.6, 0.6], + "voltage": [0.7, 0.7, 0.7], + }, + "fixed_wirewound_chassis": { + "power": [0.5, 0.5, 0.5], + "temperature": [0.5, 0.5, 0.5], + "voltage": [0.7, 0.7, 0.7], + }, + "variable_wirewound": { + "power": [0.55, 0.55, 0.55], + "temperature": [0.55, 0.55, 0.55], + }, + "variable_wirewound_precision": { + "power": [0.55, 0.55, 0.55], + "temperature": [0.55, 0.55, 0.55], + }, + "variable_wirewound_power": { + "power": [0.55, 0.55, 0.55], + "temperature": [110.0, 110.0, 110.0], + }, + "variable_composition": { + "power": [0.5, 0.5, 0.5], + "temperature": [0.5, 0.5, 0.5], + }, + "variable_film": { + "power": [0.5, 0.5, 0.5], + "temperature": [0.5, 0.5, 0.5], + }, + "variable_non_wirewound": { + "power": [0.55, 0.55, 0.55], + "temperature": [0.55, 0.55, 0.55], + }, + }, + "capacitor": { + "paper": { + "temperature": [10.0, 10.0, 10.0], + "voltage": [0.55, 0.55, 0.55], + }, + "plastic": { + "temperature": [10.0, 10.0, 10.0], + "voltage": [0.55, 0.55, 0.55], + }, + "metallized": { + "temperature": [10.0, 10.0, 10.0], + "voltage": [0.55, 0.55, 0.55], + }, + "mica": {"temperature": [25.0, 25.0, 25.0], "voltage": [0.7, 0.7, 0.7]}, + "mica_button": { + "temperature": [10.0, 10.0, 10.0], + "voltage": [0.55, 0.55, 0.55], + }, + "glass": { + "temperature": [15.0, 15.0, 15.0], + "voltage": [0.6, 0.6, 0.6], + }, + "ceramic_fixed": { + "temperature": [15.0, 15.0, 15.0], + "voltage": [0.6, 0.6, 0.6], + }, + "temp_comp_ceramic": { + "temperature": [10.0, 10.0, 10.0], + "voltage": [0.6, 0.6, 0.6], + }, + "ceramic_chip": { + "temperature": [10.0, 10.0, 10.0], + "voltage": [0.6, 0.6, 0.6], + }, + "tantalum_chip": { + "temperature": [10.0, 10.0, 10.0], + "voltage": [0.6, 0.6, 0.6], + }, + "tantalum_solid": { + "reverse_voltage": [0.02, 0.02, 0.02], + "temperature": [10.0, 10.0, 10.0], + "voltage": [0.6, 0.6, 0.6], + }, + "tantalum_wet": { + "reverse_voltage": [0.02, 0.02, 0.02], + "temperature": [10.0, 10.0, 10.0], + "voltage": [0.6, 0.6, 0.6], + }, + "aluminum": { + "temperature": [10.0, 10.0, 10.0], + "voltage": [0.7, 0.7, 0.7], + }, + "aluminum_dry": { + "temperature": [10.0, 10.0, 10.0], + "voltage": [0.7, 0.7, 0.7], + }, + "ceramic_variable": { + "temperature": [10.0, 10.0, 10.0], + "voltage": [0.6, 0.6, 0.6], + }, + "piston": { + "temperature": [15.0, 15.0, 15.0], + "voltage": [0.6, 0.6, 0.6], + }, + "trimmer": { + "temperature": [10.0, 10.0, 10.0], + "voltage": [0.6, 0.6, 0.6], + }, + "vacuum": { + "temperature": [10.0, 10.0, 10.0], + "voltage": [0.6, 0.6, 0.6], + }, + }, + "inductor": { + "low_frequency": { + "current": [0.7, 0.7, 0.6], + "surge_current": [0.9, 0.9, 0.8], + "surge_voltage": [0.9, 0.9, 0.8], + "temperature": [30.0, 30.0, 30.0], + "voltage": [0.7, 0.7, 0.6], + }, + "high_frequency": { + "current": [0.9, 0.9, 0.8], + "temperature": [30.0, 30.0, 30.0], + }, + }, + "relay": { + "capacitive_load": { + "current": [0.7, 0.6, 0.5], + "drop_out": [0.9, 0.9, 0.9], + "pick_up": [1.1, 1.1, 1.1], + "temperature": [10.0, 20.0, 30.0], + }, + "inductive_load": { + "current": [0.5, 0.4, 0.3], + "drop_out": [0.9, 0.9, 0.9], + "pick_up": [1.1, 1.1, 1.1], + "temperature": [10.0, 20.0, 30.0], + }, + "resistive_load": { + "current": [0.7, 0.6, 0.5], + "drop_out": [0.9, 0.9, 0.9], + "pick_up": [1.1, 1.1, 1.1], + "temperature": [10.0, 20.0, 30.0], + }, + }, + "switch": { + "lamp_load": { + "current": [0.2, 0.1, 0.1], + "power": [0.7, 0.6, 0.5], + "surge_current": [0.8, 0.8, 0.8], + }, + "inductive_load": { + "current": [0.5, 0.4, 0.3], + "power": [0.7, 0.6, 0.5], + "surge_current": [0.8, 0.8, 0.8], + }, + "resistive_load": { + "current": [0.7, 0.6, 0.5], + "power": [0.7, 0.6, 0.5], + "surge_current": [0.8, 0.8, 0.8], + }, + }, + "connection": {"current": [1.0, 1.0, 1.0]}, + "miscellaneous": {"lamp": {"current": [0.2, 0.1, 0.1]}}, }, } @@ -975,7 +1430,7 @@ def test_toml_user_configuration(make_home_config_dir): @pytest.fixture def test_csv_file_function(test_import_dir): """Create and populate a *.csv file for testing Function imports.""" - _test_file = TMP_DIR + "/test_inputs_functions.csv" + _test_file = f"{TMP_DIR}/test_inputs_functions.csv" with open(_test_file, "w", newline="") as _csv_file: filewriter = csv.writer( @@ -991,7 +1446,7 @@ def test_csv_file_function(test_import_dir): @pytest.fixture def test_text_file_function(test_import_dir): """Create and populate a *.txt file for testing Function imports.""" - _test_file = TMP_DIR + "/test_inputs_functions.txt" + _test_file = f"{TMP_DIR}/test_inputs_functions.txt" with open(_test_file, "w") as _csv_file: filewriter = csv.writer( @@ -1007,7 +1462,7 @@ def test_text_file_function(test_import_dir): @pytest.fixture def test_csv_file_requirement(test_import_dir): """Create and populate a *.csv file for testing Requirement import mapping.""" - _test_file = TMP_DIR + "/test_inputs_requirements.csv" + _test_file = f"{TMP_DIR}/test_inputs_requirements.csv" with open(_test_file, "w") as _csv_file: filewriter = csv.writer( @@ -1022,7 +1477,7 @@ def test_csv_file_requirement(test_import_dir): @pytest.fixture def test_csv_file_hardware(test_import_dir): """Create and populate a *.csv file for testing Hardware import mapping.""" - _test_file = TMP_DIR + "/test_inputs_hardware.csv" + _test_file = f"{TMP_DIR}/test_inputs_hardware.csv" with open(_test_file, "w") as _csv_file: filewriter = csv.writer( @@ -1037,7 +1492,7 @@ def test_csv_file_hardware(test_import_dir): @pytest.fixture def test_csv_file_validation(test_import_dir): """Create and populate a *.csv file for testing Validation import mapping.""" - _test_file = TMP_DIR + "/test_inputs_validation.csv" + _test_file = f"{TMP_DIR}/test_inputs_validation.csv" with open(_test_file, "w") as _csv_file: filewriter = csv.writer( @@ -1052,7 +1507,7 @@ def test_csv_file_validation(test_import_dir): @pytest.fixture def test_excel_file(): """Create and populate a *.xls file for tests.""" - _test_file = TMP_DIR + "/test_inputs.xls" + _test_file = f"{TMP_DIR}/test_inputs.xls" _book = xlwt.Workbook() _sheet = _book.add_sheet("Sheet 1", cell_overwrite_ok=True) @@ -1072,7 +1527,7 @@ def test_excel_file(): @pytest.fixture def test_format_file(): """Create and populate a RAMSTK layout format file.""" - _test_file = TMP_DIR + "/Test.xml" + _test_file = f"{TMP_DIR}/Test.xml" _root = ET.Element("root") _tree = ET.SubElement(_root, "tree", name="Test") @@ -1101,3 +1556,540 @@ def test_format_file(): _layout.write(_test_file) yield _test_file + + +@pytest.fixture(scope="function") +def test_stress_limits(): + yield { + "integrated_circuit": { + "digital": { + "mos": { + "hermetic": { + "current": [0.9, 0.85, 0.8], + "fanout": [1.0, 0.9, 0.9], + "frequency": [0.9, 0.9, 0.9], + "temperature": [125.0, 110.0, 100.0], + }, + "plastic1": { + "current": [0.9, 0.8, 0.0], + "fanout": [1.0, 0.9, 0.0], + "frequency": [0.9, 0.8, 0.0], + "temperature": [90.0, 85.0, 0.0], + }, + "plastic2": { + "current": [0.7, 0.0, 0.0], + "fanout": [0.8, 0.0, 0.0], + "frequency": [0.8, 0.0, 0.0], + "temperature": [70.0, 0.0, 0.0], + }, + }, + "bipolar": { + "hermetic": { + "current": [0.9, 0.85, 0.8], + "fanout": [0.9, 0.85, 0.8], + "frequency": [1.0, 0.9, 0.85], + "temperature": [125.0, 110.0, 100.0], + }, + "plastic1": { + "current": [0.9, 0.8, 0.0], + "fanout": [0.9, 0.8, 0.0], + "frequency": [1.0, 0.9, 0.0], + "temperature": [90.0, 85.0, 0.0], + }, + "plastic2": { + "current": [0.7, 0.0, 0.0], + "fanout": [0.7, 0.0, 0.0], + "frequency": [0.75, 0.0, 0.0], + "temperature": [70.0, 0.0, 0.0], + }, + }, + }, + "linear": { + "mos": { + "hermetic": { + "current": [0.9, 0.85, 0.8], + "fanout": [1.0, 0.9, 0.9], + "frequency": [0.9, 0.9, 0.9], + "temperature": [125.0, 110.0, 100.0], + "voltage": [0.8, 0.8, 0.7], + }, + "plastic1": { + "current": [0.9, 0.8, 0.0], + "fanout": [1.0, 0.9, 0.0], + "frequency": [0.9, 0.8, 0.0], + "temperature": [90.0, 85.0, 0.0], + "voltage": [0.8, 0.7, 0.0], + }, + "plastic2": { + "current": [0.7, 0.0, 0.0], + "fanout": [0.8, 0.0, 0.0], + "frequency": [0.8, 0.0, 0.0], + "temperature": [70.0, 0.0, 0.0], + "voltage": [0.6, 0.0, 0.0], + }, + }, + "bipolar": { + "hermetic": { + "current": [0.9, 0.85, 0.8], + "fanout": [0.9, 0.85, 0.8], + "frequency": [1.0, 0.9, 0.85], + "temperature": [125.0, 110.0, 100.0], + "voltage": [0.8, 0.8, 0.7], + }, + "plastic1": { + "current": [0.9, 0.8, 0.0], + "fanout": [0.9, 0.8, 0.0], + "frequency": [1.0, 0.9, 0.0], + "temperature": [90.0, 85.0, 0.0], + "voltage": [0.8, 0.7, 0.0], + }, + "plastic2": { + "current": [0.7, 0.0, 0.0], + "fanout": [0.7, 0.0, 0.0], + "frequency": [0.75, 0.0, 0.0], + "temperature": [70.0, 0.0, 0.0], + "voltage": [0.6, 0.0, 0.0], + }, + }, + }, + "microprocessor": { + "mos": { + "hermetic": { + "current": [0.9, 0.85, 0.8], + "fanout": [1.0, 0.9, 0.9], + "frequency": [0.9, 0.9, 0.9], + "temperature": [125.0, 110.0, 100.0], + }, + "plastic1": { + "current": [0.9, 0.8, 0.0], + "fanout": [1.0, 0.85, 0.0], + "frequency": [0.9, 0.8, 0.0], + "temperature": [85.0, 75.0, 0.0], + }, + "plastic2": { + "current": [0.7, 0.0, 0.0], + "fanout": [0.8, 0.0, 0.0], + "frequency": [0.8, 0.0, 0.0], + "temperature": [70.0, 0.0, 0.0], + }, + }, + "bipolar": { + "hermetic": { + "current": [0.8, 0.75, 0.7], + "fanout": [0.8, 0.75, 0.7], + "frequency": [0.9, 0.8, 0.75], + "temperature": [125.0, 110.0, 100.0], + }, + "plastic1": { + "current": [0.8, 0.75, 0.0], + "fanout": [0.8, 0.75, 0.0], + "frequency": [0.9, 0.8, 0.0], + "temperature": [85.0, 75.0, 0.0], + }, + "plastic2": { + "current": [0.7, 0.0, 0.0], + "fanout": [0.7, 0.0, 0.0], + "frequency": [0.75, 0.0, 0.0], + "temperature": [70.0, 0.0, 0.0], + }, + }, + }, + "memory": { + "mos": { + "hermetic": { + "current": [0.9, 0.85, 0.8], + "frequency": [1.0, 0.9, 0.9], + "temperature": [125.0, 110.0, 100.0], + }, + "plastic1": { + "current": [0.9, 0.8, 0.0], + "frequency": [1.0, 0.9, 0.0], + "temperature": [90.0, 85.0, 0.0], + }, + "plastic2": { + "current": [0.7, 0.0, 0.0], + "frequency": [0.8, 0.0, 0.0], + "temperature": [70.0, 0.0, 0.0], + }, + }, + "bipolar": { + "hermetic": { + "current": [0.9, 0.85, 0.8], + "frequency": [1.0, 1.0, 0.9], + "temperature": [125.0, 110.0, 100.0], + }, + "plastic1": { + "current": [0.9, 0.8, 0.0], + "frequency": [1.0, 0.95, 0.0], + "temperature": [90.0, 85.0, 0.0], + }, + "plastic2": { + "current": [0.7, 0.0, 0.0], + "frequency": [0.8, 0.0, 0.0], + "temperature": [70.0, 0.0, 0.0], + }, + }, + }, + }, + "semiconductor": { + "diode": { + "general_purpose": { + "jantx": { + "current": [1.0, 1.0, 1.0], + "surge_current": [1.0, 0.9, 0.8], + "voltage": [0.95, 0.9, 0.85], + "temperature": [150.0, 125.0, 125.0], + }, + "military": { + "current": [0.9, 0.9, 0.7], + "surge_current": [0.8, 0.8, 0.5], + "voltage": [0.8, 0.75, 0.5], + "temperature": [100.0, 85.0, 70.0], + }, + "commercial": { + "current": [0.75, 0.7, 0.0], + "surge_current": [0.6, 0.3, 0.0], + "voltage": [0.7, 0.6, 0.0], + "temperature": [70.0, 35.0, 0.0], + }, + }, + "power_rectifier": { + "jantx": { + "current": [1.0, 1.0, 1.0], + "voltage": [0.95, 0.9, 0.85], + "temperature": [150.0, 125.0, 125.0], + }, + "military": { + "current": [0.9, 0.85, 0.6], + "voltage": [0.8, 0.75, 0.3], + "temperature": [100.0, 85.0, 70.0], + }, + "commercial": { + "current": [0.6, 0.5, 0.0], + "voltage": [0.5, 0.3, 0.0], + "temperature": [70.0, 35.0, 0.0], + }, + }, + "schottky": { + "jantx": { + "power": [1.0, 1.0, 0.9], + "voltage": [0.95, 0.9, 0.85], + "temperature": [150.0, 125.0, 125.0], + }, + "military": { + "power": [0.9, 0.9, 0.5], + "voltage": [0.8, 0.8, 0.25], + "temperature": [100.0, 85.0, 70.0], + }, + "commercial": { + "power": [0.75, 0.75, 0.0], + "voltage": [0.5, 0.3, 0.0], + "temperature": [70.0, 35.0, 0.0], + }, + }, + "regulator": { + "jantx": { + "power": [1.0, 1.0, 0.9], + "temperature": [150.0, 125.0, 125.0], + }, + "military": { + "power": [0.9, 0.8, 0.5], + "temperature": [100.0, 85.0, 70.0], + }, + "commercial": { + "power": [0.5, 0.5, 0.0], + "temperature": [70.0, 35.0, 0.0], + }, + }, + "suppressor": { + "jantx": { + "current": [1.0, 1.0, 0.9], + "power": [1.0, 1.0, 0.9], + "temperature": [150.0, 125.0, 125.0], + }, + "military": { + "current": [0.8, 0.8, 0.5], + "power": [0.8, 0.8, 0.5], + "temperature": [100.0, 85.0, 70.0], + }, + "commercial": { + "current": [0.75, 0.5, 0.0], + "power": [0.75, 0.5, 0.0], + "temperature": [70.0, 35.0, 0.0], + }, + }, + }, + "thyristor": { + "jantx": { + "current": [1.0, 1.0, 0.9], + "temperature": [150.0, 125.0, 125.0], + "voltage": [1.0, 1.0, 0.9], + }, + "military": { + "current": [0.9, 0.8, 0.5], + "temperature": [100.0, 85.0, 70.0], + "voltage": [0.9, 0.8, 0.5], + }, + "commercial": { + "current": [0.6, 0.5, 0.0], + "temperature": [70.0, 35.0, 0.0], + "voltage": [0.6, 0.5, 0.0], + }, + }, + "transistor": { + "bjt": { + "jantx": { + "current": [1.0, 0.9, 0.9], + "power": [1.0, 1.0, 0.9], + "temperature": [150.0, 125.0, 125.0], + "voltage": [1.0, 0.9, 0.8], + }, + "military": { + "current": [0.9, 0.8, 0.6], + "power": [0.9, 0.8, 0.6], + "temperature": [100.0, 85.0, 70.0], + "voltage": [0.8, 0.75, 0.3], + }, + "commercial": { + "current": [0.5, 0.5, 0.0], + "power": [0.5, 0.5, 0.0], + "temperature": [70.0, 35.0, 0.0], + "voltage": [0.25, 0.25, 0.0], + }, + }, + "fet": { + "jantx": { + "power": [1.0, 1.0, 0.9], + "temperature": [150.0, 125.0, 125.0], + "voltage": [1.0, 0.95, 0.9], + }, + "military": { + "power": [0.9, 0.8, 0.5], + "temperature": [100.0, 85.0, 70.0], + "voltage": [0.8, 0.75, 0.5], + }, + "commercial": { + "power": [0.5, 0.5, 0.0], + "temperature": [70.0, 35.0, 0.0], + "voltage": [0.25, 0.25, 0.0], + }, + }, + }, + }, + "resistor": { + "fixed_composition": { + "low_power": { + "power": [0.65, 0.65, 0.65], + "temperature": [0.65, 0.65, 0.65], + "voltage": [0.7, 0.7, 0.7], + }, + "high_power": { + "power": [0.55, 0.55, 0.55], + "temperature": [0.55, 0.55, 0.55], + "voltage": [0.7, 0.7, 0.7], + }, + }, + "fixed_chip": { + "low_power": { + "power": [0.7, 0.7, 0.7], + "temperature": [0.7, 0.7, 0.7], + }, + "high_power": { + "power": [0.55, 0.55, 0.55], + "temperature": [0.55, 0.55, 0.55], + }, + }, + "fixed_film": { + "low_power": { + "power": [0.65, 0.65, 0.65], + "temperature": [0.65, 0.65, 0.65], + "voltage": [0.7, 0.7, 0.7], + }, + "high_power": { + "power": [0.55, 0.55, 0.55], + "temperature": [0.55, 0.55, 0.55], + "voltage": [0.7, 0.7, 0.7], + }, + }, + "fixed_film_power": { + "power": [0.55, 0.55, 0.55], + "temperature": [0.55, 0.55, 0.55], + }, + "fixed_film_network": { + "power": [0.55, 0.55, 0.55], + "temperature": [0.55, 0.55, 0.55], + "voltage": [0.7, 0.7, 0.7], + }, + "fixed_wirewound": { + "low_power": { + "power": [0.7, 0.7, 0.7], + "temperature": [1.0, 1.0, 1.0], + "voltage": [0.7, 0.7, 0.7], + }, + "high_power": { + "power": [0.5, 0.5, 0.5], + "temperature": [1.0, 1.0, 1.0], + "voltage": [0.7, 0.7, 0.7], + }, + }, + "fixed_wirewound_power": { + "power": [0.6, 0.6, 0.6], + "temperature": [0.6, 0.6, 0.6], + "voltage": [0.7, 0.7, 0.7], + }, + "fixed_wirewound_chassis": { + "power": [0.5, 0.5, 0.5], + "temperature": [0.5, 0.5, 0.5], + "voltage": [0.7, 0.7, 0.7], + }, + "variable_wirewound": { + "power": [0.55, 0.55, 0.55], + "temperature": [0.55, 0.55, 0.55], + }, + "variable_wirewound_precision": { + "power": [0.55, 0.55, 0.55], + "temperature": [0.55, 0.55, 0.55], + }, + "variable_wirewound_power": { + "power": [0.55, 0.55, 0.55], + "temperature": [110.0, 110.0, 110.0], + }, + "variable_composition": { + "power": [0.5, 0.5, 0.5], + "temperature": [0.5, 0.5, 0.5], + }, + "variable_film": { + "power": [0.5, 0.5, 0.5], + "temperature": [0.5, 0.5, 0.5], + }, + "variable_non_wirewound": { + "power": [0.55, 0.55, 0.55], + "temperature": [0.55, 0.55, 0.55], + }, + }, + "capacitor": { + "paper": { + "temperature": [10.0, 10.0, 10.0], + "voltage": [0.55, 0.55, 0.55], + }, + "plastic": { + "temperature": [10.0, 10.0, 10.0], + "voltage": [0.55, 0.55, 0.55], + }, + "metallized": { + "temperature": [10.0, 10.0, 10.0], + "voltage": [0.55, 0.55, 0.55], + }, + "mica": {"temperature": [25.0, 25.0, 25.0], "voltage": [0.7, 0.7, 0.7]}, + "mica_button": { + "temperature": [10.0, 10.0, 10.0], + "voltage": [0.55, 0.55, 0.55], + }, + "glass": { + "temperature": [15.0, 15.0, 15.0], + "voltage": [0.6, 0.6, 0.6], + }, + "ceramic_fixed": { + "temperature": [15.0, 15.0, 15.0], + "voltage": [0.6, 0.6, 0.6], + }, + "temp_comp_ceramic": { + "temperature": [10.0, 10.0, 10.0], + "voltage": [0.6, 0.6, 0.6], + }, + "ceramic_chip": { + "temperature": [10.0, 10.0, 10.0], + "voltage": [0.6, 0.6, 0.6], + }, + "tantalum_chip": { + "temperature": [10.0, 10.0, 10.0], + "voltage": [0.6, 0.6, 0.6], + }, + "tantalum_solid": { + "reverse_voltage": [0.02, 0.02, 0.02], + "temperature": [10.0, 10.0, 10.0], + "voltage": [0.6, 0.6, 0.6], + }, + "tantalum_wet": { + "reverse_voltage": [0.02, 0.02, 0.02], + "temperature": [10.0, 10.0, 10.0], + "voltage": [0.6, 0.6, 0.6], + }, + "aluminum": { + "temperature": [10.0, 10.0, 10.0], + "voltage": [0.7, 0.7, 0.7], + }, + "aluminum_dry": { + "temperature": [10.0, 10.0, 10.0], + "voltage": [0.7, 0.7, 0.7], + }, + "ceramic_variable": { + "temperature": [10.0, 10.0, 10.0], + "voltage": [0.6, 0.6, 0.6], + }, + "piston": { + "temperature": [15.0, 15.0, 15.0], + "voltage": [0.6, 0.6, 0.6], + }, + "trimmer": { + "temperature": [10.0, 10.0, 10.0], + "voltage": [0.6, 0.6, 0.6], + }, + "vacuum": { + "temperature": [10.0, 10.0, 10.0], + "voltage": [0.6, 0.6, 0.6], + }, + }, + "inductor": { + "low_frequency": { + "current": [0.7, 0.7, 0.6], + "surge_current": [0.9, 0.9, 0.8], + "surge_voltage": [0.9, 0.9, 0.8], + "temperature": [30.0, 30.0, 30.0], + "voltage": [0.7, 0.7, 0.6], + }, + "high_frequency": { + "current": [0.9, 0.9, 0.8], + "temperature": [30.0, 30.0, 30.0], + }, + }, + "relay": { + "capacitive_load": { + "current": [0.7, 0.6, 0.5], + "drop_out": [0.9, 0.9, 0.9], + "pick_up": [1.1, 1.1, 1.1], + "temperature": [10.0, 20.0, 30.0], + }, + "inductive_load": { + "current": [0.5, 0.4, 0.3], + "drop_out": [0.9, 0.9, 0.9], + "pick_up": [1.1, 1.1, 1.1], + "temperature": [10.0, 20.0, 30.0], + }, + "resistive_load": { + "current": [0.7, 0.6, 0.5], + "drop_out": [0.9, 0.9, 0.9], + "pick_up": [1.1, 1.1, 1.1], + "temperature": [10.0, 20.0, 30.0], + }, + }, + "switch": { + "lamp_load": { + "current": [0.2, 0.1, 0.1], + "power": [0.7, 0.6, 0.5], + "surge_current": [0.8, 0.8, 0.8], + }, + "inductive_load": { + "current": [0.5, 0.4, 0.3], + "power": [0.7, 0.6, 0.5], + "surge_current": [0.8, 0.8, 0.8], + }, + "resistive_load": { + "current": [0.7, 0.6, 0.5], + "power": [0.7, 0.6, 0.5], + "surge_current": [0.8, 0.8, 0.8], + }, + }, + "connection": {"current": [1.0, 1.0, 1.0]}, + "miscellaneous": {"lamp": {"current": [0.2, 0.1, 0.1]}}, + } diff --git a/tests/models/programdb/design_electric/design_electric_unit_test.py b/tests/models/programdb/design_electric/design_electric_unit_test.py index c7a7157af..d99797d9c 100644 --- a/tests/models/programdb/design_electric/design_electric_unit_test.py +++ b/tests/models/programdb/design_electric/design_electric_unit_test.py @@ -354,7 +354,10 @@ def test_set_record_model_attributes_unknown_attributes( @pytest.mark.usefixtures( - "test_attributes", "test_tablemodel", "test_toml_user_configuration" + "test_attributes", + "test_tablemodel", + "test_toml_user_configuration", + "test_stress_limits", ) class TestAnalysisMethods: """Class for testing analytical methods.""" @@ -406,95 +409,35 @@ def test_do_calculate_voltage_ratio(self, test_attributes, test_tablemodel): assert _attributes["voltage_ratio"] == pytest.approx(0.0661) @pytest.mark.unit - def test_do_derating_analysis_over_limit( - self, test_attributes, test_tablemodel, test_toml_user_configuration + def test_do_derating_analysis( + self, + test_attributes, + test_tablemodel, + test_toml_user_configuration, + test_stress_limits, ): """should determine if a component is overstressed and the reason.""" test_tablemodel.do_select_all(attributes=test_attributes) _design_electric = test_tablemodel.do_select(1) - test_tablemodel._dic_stress_limits = ( - test_toml_user_configuration.RAMSTK_STRESS_LIMITS - ) _design_electric.hardware_id = 1 - _design_electric.current_ratio = 1.62 - _design_electric.power_ratio = 0.55 + _design_electric.environment_active_id = 2 + _design_electric.specification_id = 1 + _design_electric.temperature_case = 78.2 + _design_electric.temperature_rated_max = 85.0 _design_electric.voltage_ratio = 0.58 _design_electric.do_derating_analysis( - [ - 1.0, - 1.0, - 0.5, - 0.9, - 1.0, - 1.0, - ] - ) - assert _design_electric.overstress - assert ( - _design_electric.reason - == "Operating current ratio is greater than the harsh environment limit " - "of 1.0.\nOperating current ratio is greater than the mild environment " - "limit of 1.0.\nOperating power ratio is greater than the harsh " - "environment limit of 0.5.\n" - ) - - _design_electric.do_derating_analysis( - [ - 0.6, - 0.9, - 1.0, - 1.0, - 0.5, - 0.9, - ] - ) - assert _design_electric.overstress - assert ( - _design_electric.reason - == "Operating current ratio is greater than the harsh environment limit " - "of 0.6.\nOperating current ratio is greater than the mild environment " - "limit of 0.9.\nOperating voltage ratio is greater than the harsh " - "environment limit of 0.5.\n" - ) - - @pytest.mark.unit - def test_do_derating_analysis_under_limit( - self, test_attributes, test_tablemodel, test_toml_user_configuration - ): - """should determine if a component is overstressed and the reason.""" - test_tablemodel.do_select_all(attributes=test_attributes) - - _design_electric = test_tablemodel.do_select(1) - test_tablemodel._dic_stress_limits = ( - test_toml_user_configuration.RAMSTK_STRESS_LIMITS - ) - _design_electric.hardware_id = 1 - _design_electric.current_ratio = -0.62 - _design_electric.power_ratio = -0.55 - _design_electric.voltage_ratio = -0.58 - - _design_electric.do_derating_analysis( - [ - 1.0, - 1.0, - 0.5, - 0.9, - 1.0, - 1.0, - ] + 4, + 10, + 2, + test_stress_limits, ) - assert _design_electric.overstress + assert _design_electric.overstress == 1 assert ( - _design_electric.reason - == "Operating current ratio is less than the harsh environment limit of " - "0.0.\nOperating current ratio is less than the mild environment limit " - "of 0.0.\nOperating power ratio is less than the harsh environment " - "limit of 0.0.\nOperating power ratio is less than the mild " - "environment limit of 0.0.\nOperating voltage ratio is less than the " - "harsh environment limit of 0.0.\nOperating voltage ratio is less than " - "the mild environment limit of 0.0.\n" + _design_electric.reason == "Case temperature of 78.2C exceeds the derated " + "maximum temperature of 15.0C less than maximum rated temperature of " + "85.0C.\n" ) @pytest.mark.unit diff --git a/tests/models/programdb/hardware/hardware_integration_test.py b/tests/models/programdb/hardware/hardware_integration_test.py index 600ae658e..bbb816800 100644 --- a/tests/models/programdb/hardware/hardware_integration_test.py +++ b/tests/models/programdb/hardware/hardware_integration_test.py @@ -102,7 +102,7 @@ class TestSelectMethods: def on_succeed_select_all(self, tree): assert isinstance(tree, Tree) assert isinstance(tree.get_node(1).data["hardware"], RAMSTKHardwareRecord) - print("\033[36m\nsucceed_retrieve_hardware topic was broadcast.") + print("\033[36m\n\tsucceed_retrieve_hardware topic was broadcast.") def on_succeed_on_select_all(self, tree): assert isinstance(tree, Tree) @@ -118,7 +118,7 @@ def on_succeed_on_select_all(self, tree): assert isinstance(tree.get_node(1).data["milhdbk217f"], RAMSTKMilHdbk217FRecord) assert isinstance(tree.get_node(1).data["nswc"], RAMSTKNSWCRecord) assert isinstance(tree.get_node(1).data["reliability"], RAMSTKReliabilityRecord) - print("\033[36m\nsucceed_retrieve_hardware_bom topic was broadcast.") + print("\033[36m\n\tsucceed_retrieve_hardware_bom topic was broadcast.") @pytest.mark.integration def test_do_select_all_populated_tree(self, test_attributes, test_tablemodel): @@ -315,7 +315,7 @@ def on_succeed_insert_sibling(self, tree): assert isinstance(tree, Tree) assert isinstance(tree.get_node(9).data["hardware"], RAMSTKHardwareRecord) assert tree.get_node(9).data["hardware"].hardware_id == 9 - print("\033[36m\nsucceed_insert_hardware topic was broadcast.") + print("\033[36m\n\tsucceed_insert_hardware topic was broadcast.") def on_fail_insert_no_revision(self, error_message): assert error_message == ( @@ -323,13 +323,13 @@ def on_fail_insert_no_revision(self, error_message): "returned:\n\tKey (fld_revision_id)=(9) is not present in table " '"ramstk_revision".' ) - print("\033[35m\nfail_insert_hardware topic was broadcast on no hardware.") + print("\033[35m\n\tfail_insert_hardware topic was broadcast on no hardware.") def on_succeed_insert_hardware(self, tree): assert isinstance(tree, Tree) assert tree.contains(10) print( - "\033[36m\nsucceed_insert_hardware topic was broadcast on hardware " + "\033[36m\n\tsucceed_insert_hardware topic was broadcast on hardware " "insert." ) @@ -423,21 +423,25 @@ class TestDeleteMethods: def on_succeed_delete(self, tree): assert isinstance(tree, Tree) - print("\033[36m\nsucceed_delete_hardware topic was broadcast.") + print("\033[36m\n\tsucceed_delete_hardware topic was broadcast.") def on_fail_delete_non_existent_id(self, error_message): assert error_message == ("Attempted to delete non-existent Hardware ID 300.") - print("\033[35m\nfail_delete_hardware topic was broadcast on non-existent ID.") + print( + "\033[35m\n\tfail_delete_hardware topic was broadcast on non-existent ID." + ) def on_fail_delete_no_data_package(self, error_message): assert error_message == ("Attempted to delete non-existent Hardware ID 2.") - print("\033[35m\nfail_delete_hardware topic was broadcast on no data package.") + print( + "\033[35m\n\tfail_delete_hardware topic was broadcast on no data package." + ) def on_succeed_delete_hardware(self, tree): assert isinstance(tree, Tree) assert not tree.contains(5) print( - "\033[36m\nsucceed_retrieve_hardware_bom topic was broadcast on hardware " + "\033[36m\n\tsucceed_retrieve_hardware_bom topic was broadcast on hardware " "delete." ) @@ -522,31 +526,37 @@ def on_succeed_update(self, tree): tree.get_node(2).data["hardware"].specification_number == "Big Specification" ) - print("\033[36m\nsucceed_update_hardware topic was broadcast.") + print("\033[36m\n\tsucceed_update_hardware topic was broadcast.") def on_succeed_update_all(self): - print("\033[36m\nsucceed_update_all topic was broadcast for Hardware.") + print("\033[36m\n\tsucceed_update_all topic was broadcast for Hardware.") def on_fail_update_wrong_data_type(self, error_message): assert error_message == ( "do_update: The value for one or more attributes for hardware ID 1 was the " "wrong type." ) - print("\033[35m\nfail_update_hardware topic was broadcast on wrong data type.") + print( + "\033[35m\n\tfail_update_hardware topic was broadcast on wrong data type." + ) def on_fail_update_root_node_wrong_data_type(self, error_message): assert error_message == ("do_update: Attempting to update the root node 0.") - print("\033[35m\nfail_update_hardware topic was broadcast on root node.") + print("\033[35m\n\tfail_update_hardware topic was broadcast on root node.") def on_fail_update_non_existent_id(self, error_message): assert error_message == ( "do_update: Attempted to save non-existent hardware with hardware ID 100." ) - print("\033[35m\nfail_update_hardware topic was broadcast on non-existent ID.") + print( + "\033[35m\n\tfail_update_hardware topic was broadcast on non-existent ID." + ) def on_fail_update_no_data_package(self, error_message): assert error_message == ("do_update: No data package found for hardware ID 1.") - print("\033[35m\nfail_update_hardware topic was broadcast on no data package.") + print( + "\033[35m\n\tfail_update_hardware topic was broadcast on no data package." + ) @pytest.mark.integration def test_do_update(self, test_tablemodel): @@ -681,17 +691,17 @@ def on_succeed_get_attributes(self, attributes): assert attributes["total_part_count"] == 0 assert attributes["total_power_dissipation"] == 0.0 assert attributes["year_of_manufacture"] == 2019 - print("\033[36m\nsucceed_get_hardware_attributes topic was broadcast.") + print("\033[36m\n\tsucceed_get_hardware_attributes topic was broadcast.") def on_succeed_get_data_manager_tree(self, tree): assert isinstance(tree, Tree) assert isinstance(tree.get_node(1).data["hardware"], RAMSTKHardwareRecord) - print("\033[36m\nsucceed_get_hardware_tree topic was broadcast.") + print("\033[36m\n\tsucceed_get_hardware_tree topic was broadcast.") def on_succeed_set_attributes(self, tree): assert isinstance(tree, Tree) assert tree.get_node(2).data["hardware"].cage_code == "DE34T1" - print("\033[36m\nsucceed_get_hardware_tree topic was broadcast") + print("\033[36m\n\tsucceed_get_hardware_tree topic was broadcast") @pytest.mark.integration def test_do_get_attributes(self, test_tablemodel): @@ -815,6 +825,94 @@ def test_do_calculate_power_dissipation_assembly( assert _attributes["total_power_dissipation"] == 0.00885 + @pytest.mark.integration + def test_do_calculate_part_stress( + self, + test_attributes, + test_tablemodel, + test_viewmodel, + test_design_electric, + test_design_mechanic, + test_milhdbk217f, + test_nswc, + test_reliability, + test_stress_limits, + ): + """calculate part stress ratios and check derating limits.""" + test_tablemodel.do_select_all(attributes={"revision_id": 1}) + test_design_electric.do_select_all(attributes={"revision_id": 1}) + test_design_mechanic.do_select_all(attributes={"revision_id": 1}) + test_milhdbk217f.do_select_all(attributes={"revision_id": 1}) + test_nswc.do_select_all(attributes={"revision_id": 1}) + test_reliability.do_select_all(attributes={"revision_id": 1}) + + _hardware = test_tablemodel.do_select(8) + _hardware.category_id = 3 + _hardware.subcategory_id = 2 + + _hardware = test_reliability.do_select(8) + _hardware.quality_id = 3 + + _hardware = test_design_electric.do_select(8) + _hardware.environment_active_id = 3 + _hardware.power_operating = 0.03 + _hardware.power_rated = 0.1 + _hardware.temperature_case = 46.9 + _hardware.temperature_knee = 85.0 + _hardware.temperature_rated_max = 150.0 + _hardware.voltage_operating = 3.3 + _hardware.voltage_rated = 5.0 + + test_viewmodel._dic_stress_limits = test_stress_limits + test_viewmodel.do_calculate_part_stress(8) + + assert _hardware.overstress == 0 + assert _hardware.reason == "" + + @pytest.mark.integration + def test_do_calculate_part_stress_meter( + self, + test_attributes, + test_tablemodel, + test_viewmodel, + test_design_electric, + test_design_mechanic, + test_milhdbk217f, + test_nswc, + test_reliability, + test_stress_limits, + ): + """calculate part stress ratios for meters.""" + test_tablemodel.do_select_all(attributes={"revision_id": 1}) + test_design_electric.do_select_all(attributes={"revision_id": 1}) + test_design_mechanic.do_select_all(attributes={"revision_id": 1}) + test_milhdbk217f.do_select_all(attributes={"revision_id": 1}) + test_nswc.do_select_all(attributes={"revision_id": 1}) + test_reliability.do_select_all(attributes={"revision_id": 1}) + + _hardware = test_tablemodel.do_select(8) + _hardware.category_id = 9 + _hardware.subcategory_id = 2 + + _hardware = test_reliability.do_select(8) + _hardware.quality_id = 3 + + _hardware = test_design_electric.do_select(8) + _hardware.environment_active_id = 3 + _hardware.power_operating = 0.03 + _hardware.power_rated = 0.1 + _hardware.temperature_case = 46.9 + _hardware.temperature_knee = 85.0 + _hardware.temperature_rated_max = 150.0 + _hardware.voltage_operating = 3.3 + _hardware.voltage_rated = 5.0 + + test_viewmodel._dic_stress_limits = test_stress_limits + test_viewmodel.do_calculate_part_stress(8) + + assert _hardware.overstress == 0 + assert _hardware.reason == "" + @pytest.mark.integration def test_do_predict_hazard_rate_active_part_mil_hdbk_217f( self, @@ -826,6 +924,7 @@ def test_do_predict_hazard_rate_active_part_mil_hdbk_217f( test_milhdbk217f, test_nswc, test_reliability, + test_stress_limits, ): """predict the active hazard of a part using MIL-HDBK-217F.""" test_tablemodel.do_select_all(attributes={"revision_id": 1}) @@ -851,10 +950,11 @@ def test_do_predict_hazard_rate_active_part_mil_hdbk_217f( _hardware.hazard_rate_method_id = 2 _hardware.quality_id = 3 + test_viewmodel._dic_stress_limits = test_stress_limits test_viewmodel.do_calculate_hardware(8) _attributes = test_reliability.do_select(8).get_attributes() - assert _attributes["hazard_rate_active"] == pytest.approx(0.005820122) + assert _attributes["hazard_rate_active"] == pytest.approx(0.003995836) @pytest.mark.integration def test_do_predict_hazard_rate_active_part_specified_hazard_rate( diff --git a/tests/models/programdb/hardware/hardware_unit_test.py b/tests/models/programdb/hardware/hardware_unit_test.py index f5f406ae3..5ae5c3aab 100644 --- a/tests/models/programdb/hardware/hardware_unit_test.py +++ b/tests/models/programdb/hardware/hardware_unit_test.py @@ -145,86 +145,15 @@ def test_view_model_create(self, test_viewmodel): "reliability": test_viewmodel._do_load_reliability, } assert test_viewmodel._dic_stress_limits == { - 1: [ - 0.8, - 0.9, - 1.0, - 1.0, - 1.0, - 1.0, - ], - 2: [ - 1.0, - 1.0, - 0.7, - 0.9, - 1.0, - 1.0, - ], - 3: [ - 1.0, - 1.0, - 0.5, - 0.9, - 1.0, - 1.0, - ], - 4: [ - 1.0, - 1.0, - 1.0, - 1.0, - 0.6, - 0.9, - ], - 5: [ - 0.6, - 0.9, - 1.0, - 1.0, - 0.5, - 0.9, - ], - 6: [ - 0.75, - 0.9, - 1.0, - 1.0, - 1.0, - 1.0, - ], - 7: [ - 0.75, - 0.9, - 1.0, - 1.0, - 1.0, - 1.0, - ], - 8: [ - 0.7, - 0.9, - 1.0, - 1.0, - 0.7, - 0.9, - ], - 9: [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0, - 1.0, - ], - 10: [ - 1.0, - 1.0, - 1.0, - 1.0, - 1.0, - 1.0, - ], + "integrated_circuit": {}, + "semiconductor": {}, + "resistor": {}, + "capacitor": {}, + "inductor": {}, + "relay": {}, + "switch": {}, + "connection": {}, + "miscellaneous": {}, } assert isinstance(test_viewmodel._dic_trees["hardware"], Tree) assert isinstance(test_viewmodel._dic_trees["design_electric"], Tree) diff --git a/tests/test_configuration.py b/tests/test_configuration.py index f6ca946e9..7519e04af 100644 --- a/tests/test_configuration.py +++ b/tests/test_configuration.py @@ -231,24 +231,31 @@ class TestCreateConfiguration: """Class for testing the site configuration module.""" def on_create_site_configuration(self): - print("\033[36m\nsucceed_create_site_configuration topic was broadcast.") + print("\033[36m\n\tsucceed_create_site_configuration topic was broadcast.") def on_fail_site_configuration_no_config_file(self, error_message): assert error_message == ( - "Failed to write site configuration file " "/biboly/RAMSTK/RAMSTK.toml." + "Failed to write site configuration file /biboly/RAMSTK/RAMSTK.toml." ) - print("\033[35m\nfail_create_site_configuration topic was " "broadcast.") + print("\033[35m\n\tfail_create_site_configuration topic was broadcast.") def on_create_user_configuration(self): - print("\033[36m\nsucceed_create_user_configuration topic was broadcast.") + print("\033[36m\n\tsucceed_create_user_configuration topic was broadcast.") def on_fail_user_configuration_no_conf_file(self, error_message): assert error_message == ("User configuration file None is not a file.") print( - "\033[35m\nfail_create_user_configuration topic was broadcast; no " + "\033[35m\n\tfail_create_user_configuration topic was broadcast; no " "configuration file." ) + def on_fail_user_configuration_no_icon_dir(self, error_message): + assert error_message[:118] == ( + "Attempt to copy RAMSTK icons from site-wide icon directory " + "/tmp/shibiboly/share/RAMSTK/icons/ to user's icon directory" + ) + print("\033[35m\n\tfail_create_site_configuration topic was broadcast.") + def on_fail_create_user_configuration(self, error_message): assert error_message == ( "User's configuration directory " @@ -257,7 +264,7 @@ def on_fail_create_user_configuration(self, error_message): "create a new user configuration file." ) print( - "\033[35m\nfail_create_user_configuration topic was broadcast; no " + "\033[35m\n\tfail_create_user_configuration topic was broadcast; no " "configuration directory." ) @@ -270,7 +277,7 @@ def on_fail_create_data_dir(self, error_message): "configuration file." ) print( - "\033[35m\nfail_create_user_configuration topic was broadcast; no " + "\033[35m\n\tfail_create_user_configuration topic was broadcast; no " "data directory." ) @@ -283,7 +290,7 @@ def on_fail_create_icon_dir(self, error_message): "configuration file." ) print( - "\033[35m\nfail_create_user_configuration topic was broadcast; no " + "\033[35m\n\tfail_create_user_configuration topic was broadcast; no " "icon directory." ) @@ -296,7 +303,7 @@ def on_fail_create_log_dir(self, error_message): "configuration file." ) print( - "\033[35m\nfail_create_user_configuration topic was broadcast; no " + "\033[35m\n\tfail_create_user_configuration topic was broadcast; no " "log directory." ) @@ -308,7 +315,7 @@ def on_fail_create_program_dir(self, error_message): "configuration file." ) print( - "\033[35m\nfail_create_user_configuration topic was broadcast; no " + "\033[35m\n\tfail_create_user_configuration topic was broadcast; no " "program directory." ) @@ -328,11 +335,11 @@ def test_initialize_site_configuration(self): # real_prefix attribute. In this case, skip these tests. if hasattr(sys, "real_prefix"): if sys.platform in ["linux", "linux2"]: - assert DUT.RAMSTK_SITE_DIR == VIRTUAL_ENV + "/share/RAMSTK" + assert DUT.RAMSTK_SITE_DIR == f"{VIRTUAL_ENV}/share/RAMSTK" elif sys.platform == "win32": - assert DUT.RAMSTK_SITE_DIR == VIRTUAL_ENV + "/RAMSTK" + assert DUT.RAMSTK_SITE_DIR == f"{VIRTUAL_ENV}/RAMSTK" - assert DUT.RAMSTK_SITE_CONF == DUT.RAMSTK_SITE_DIR + "/Site.toml" + assert DUT.RAMSTK_SITE_CONF == f"{DUT.RAMSTK_SITE_DIR}/Site.toml" @pytest.mark.unit def test_initialize_user_configuration(self): @@ -383,21 +390,21 @@ def test_initialize_user_configuration(self): assert DUT.RAMSTK_OS == "Linux" assert DUT.RAMSTK_HOME_DIR == os.environ["HOME"] if hasattr(sys, "real_prefix"): - assert DUT.RAMSTK_CONF_DIR == DUT._INSTALL_PREFIX + "/share/RAMSTK" + assert DUT.RAMSTK_CONF_DIR == f"{DUT._INSTALL_PREFIX}/share/RAMSTK" elif sys.platform == "win32": assert DUT.RAMSTK_OS == "Windows" assert DUT.RAMSTK_HOME_DIR == os.environ["USERPROFILE"] if hasattr(sys, "real_prefix"): - assert DUT.RAMSTK_CONF_DIR == os.environ["PYTHONPATH"] + "/RAMSTK" + assert DUT.RAMSTK_CONF_DIR == f"{os.environ['PYTHONPATH']}/RAMSTK" - assert DUT.RAMSTK_DATA_DIR == DUT.RAMSTK_CONF_DIR + "/layouts" - assert DUT.RAMSTK_ICON_DIR == DUT.RAMSTK_CONF_DIR + "/icons" - assert DUT.RAMSTK_LOG_DIR == DUT.RAMSTK_CONF_DIR + "/logs" - assert DUT.RAMSTK_PROG_DIR == DUT.RAMSTK_HOME_DIR + "/analyses/ramstk/" + assert DUT.RAMSTK_DATA_DIR == f"{DUT.RAMSTK_CONF_DIR}/layouts" + assert DUT.RAMSTK_ICON_DIR == f"{DUT.RAMSTK_CONF_DIR}/icons" + assert DUT.RAMSTK_LOG_DIR == f"{DUT.RAMSTK_CONF_DIR}/logs" + assert DUT.RAMSTK_PROG_DIR == f"{DUT.RAMSTK_HOME_DIR}/analyses/ramstk/" - assert DUT.RAMSTK_PROG_CONF == DUT.RAMSTK_CONF_DIR + "/RAMSTK.toml" - assert DUT.RAMSTK_USER_LOG == DUT.RAMSTK_LOG_DIR + "/ramstk_run.log" - assert DUT.RAMSTK_IMPORT_LOG == (DUT.RAMSTK_LOG_DIR + "/ramstk_import.log") + assert DUT.RAMSTK_PROG_CONF == f"{DUT.RAMSTK_CONF_DIR}/RAMSTK.toml" + assert DUT.RAMSTK_USER_LOG == f"{DUT.RAMSTK_LOG_DIR}/ramstk_run.log" + assert DUT.RAMSTK_IMPORT_LOG == f"{DUT.RAMSTK_LOG_DIR}/ramstk_import.log" assert DUT.RAMSTK_ACTION_CATEGORY == {} assert DUT.RAMSTK_ACTION_STATUS == {} assert DUT.RAMSTK_AFFINITY_GROUPS == {} @@ -436,8 +443,8 @@ def test_create_site_configuration(self): DUT = RAMSTKSiteConfiguration() - DUT.RAMSTK_SITE_DIR = VIRTUAL_ENV + "/share/RAMSTK" - DUT.RAMSTK_SITE_CONF = DUT.RAMSTK_SITE_DIR + "/RAMSTK.toml" + DUT.RAMSTK_SITE_DIR = f"{VIRTUAL_ENV}/share/RAMSTK" + DUT.RAMSTK_SITE_CONF = f"{DUT.RAMSTK_SITE_DIR}/RAMSTK.toml" assert DUT.do_create_site_configuration() is None @@ -457,7 +464,7 @@ def test_create_site_configuration_no_config_file(self): DUT = RAMSTKSiteConfiguration() DUT.RAMSTK_SITE_DIR = "/biboly/RAMSTK" - DUT.RAMSTK_SITE_CONF = DUT.RAMSTK_SITE_DIR + "/RAMSTK.toml" + DUT.RAMSTK_SITE_CONF = f"{DUT.RAMSTK_SITE_DIR}/RAMSTK.toml" assert DUT.do_create_site_configuration() is None @@ -475,8 +482,8 @@ def test_do_create_user_configuration(self, make_home_config_dir): DUT = RAMSTKUserConfiguration() DUT._INSTALL_PREFIX = VIRTUAL_ENV - DUT.RAMSTK_HOME_DIR = VIRTUAL_ENV + "/tmp" - DUT.RAMSTK_PROG_CONF = VIRTUAL_ENV + "/RAMSTK.toml" + DUT.RAMSTK_HOME_DIR = f"{VIRTUAL_ENV}/tmp" + DUT.RAMSTK_PROG_CONF = f"{VIRTUAL_ENV}/RAMSTK.toml" assert DUT.do_create_user_configuration() is None assert os.path.isdir(make_home_config_dir + "/icons") @@ -514,7 +521,7 @@ def test_do_create_user_configuration_no_conf_file(self): DUT = RAMSTKUserConfiguration() DUT._INSTALL_PREFIX = VIRTUAL_ENV - DUT.RAMSTK_HOME_DIR = VIRTUAL_ENV + "/tmp" + DUT.RAMSTK_HOME_DIR = f"{VIRTUAL_ENV}/tmp" DUT.RAMSTK_PROG_CONF = None DUT.do_create_user_configuration() @@ -523,18 +530,37 @@ def test_do_create_user_configuration_no_conf_file(self): "fail_create_user_configuration", ) + @pytest.mark.unit + def test_do_create_user_configuration_no_icon_dir(self): + """do_create_user_configuration() should return None on success.""" + pub.subscribe( + self.on_fail_user_configuration_no_icon_dir, + "fail_copy_icons_to_user", + ) + + DUT = RAMSTKUserConfiguration() + DUT._INSTALL_PREFIX = "/tmp/shibiboly" + DUT.RAMSTK_HOME_DIR = f"{VIRTUAL_ENV}/tmp" + DUT.RAMSTK_PROG_CONF = None + DUT.do_create_user_configuration() + + pub.unsubscribe( + self.on_fail_user_configuration_no_icon_dir, + "fail_copy_icons_to_user", + ) + @pytest.mark.unit def test_do_make_configuration_dir(self): """_do_make_configuration_dir() should create a configuration directory and set the RAMSTK_PROG_CONF file os.path.""" - _temp_dir = VIRTUAL_ENV + "/tmp/" + tempfile.mkdtemp() + _temp_dir = f"{VIRTUAL_ENV}/tmp/{tempfile.mkdtemp()}" DUT = RAMSTKUserConfiguration() DUT._INSTALL_PREFIX = VIRTUAL_ENV DUT.RAMSTK_HOME_DIR = _temp_dir assert DUT._do_make_configuration_dir() is None - assert DUT.RAMSTK_CONF_DIR == _temp_dir + "/.config/RAMSTK" - assert DUT.RAMSTK_PROG_CONF == _temp_dir + "/.config/RAMSTK/RAMSTK.toml" + assert DUT.RAMSTK_CONF_DIR == f"{_temp_dir}/.config/RAMSTK" + assert DUT.RAMSTK_PROG_CONF == f"{_temp_dir}/.config/RAMSTK/RAMSTK.toml" shutil.rmtree(_temp_dir) @@ -613,6 +639,7 @@ def test_do_create_user_configuration_no_user_program_dir(self): @pytest.mark.usefixtures( "test_toml_site_configuration", "test_toml_user_configuration", + "test_stress_limits", "make_shibboly", "test_config_dir", ) @@ -623,25 +650,25 @@ def on_fail_get_site_configuration(self, error_message): assert error_message == ( "Failed to read Site configuration file " "{0:s}/share/RAMSTK/BigSite.toml." ).format(VIRTUAL_ENV) - print("\033[35m\nfail_get_site_configuration topic was broadcast.") + print("\033[35m\n\tfail_get_site_configuration topic was broadcast.") def on_succeed_set_site_configuration(self, configuration): assert isinstance(configuration, str) - print("\033[36m\nsucceed_set_site_configuration topic was broadcast.") + print("\033[36m\n\tsucceed_set_site_configuration topic was broadcast.") def on_fail_get_user_configuration(self, error_message): assert error_message == ( "Failed to read User configuration file " "{0:s}/tmp/.config/RAMSTK/BigUser.toml." ).format(VIRTUAL_ENV) - print("\033[35m\nfail_get_user_configuration topic was broadcast.") + print("\033[35m\n\tfail_get_user_configuration topic was broadcast.") @pytest.mark.unit def test_get_site_configuration(self): """get_site_configuration() should broadcast the succcess message on success.""" DUT = RAMSTKSiteConfiguration() - DUT.RAMSTK_SITE_CONF = VIRTUAL_ENV + "/share/RAMSTK/Site.toml" + DUT.RAMSTK_SITE_CONF = f"{VIRTUAL_ENV}/share/RAMSTK/Site.toml" assert DUT.get_site_configuration() is None assert DUT.RAMSTK_COM_BACKEND == "sqlite" @@ -649,7 +676,7 @@ def test_get_site_configuration(self): assert DUT.RAMSTK_COM_INFO["host"] == "localhost" assert DUT.RAMSTK_COM_INFO["port"] == "3306" assert DUT.RAMSTK_COM_INFO["database"] == ( - VIRTUAL_ENV + "/share/RAMSTK/ramstk_common.ramstk" + f"{VIRTUAL_ENV}/share/RAMSTK/ramstk_common.ramstk" ) assert DUT.RAMSTK_COM_INFO["user"] == "johnny.tester" assert DUT.RAMSTK_COM_INFO["password"] == "clear.text.password" @@ -663,7 +690,7 @@ def test_get_site_configuration_no_conf_file(self): ) DUT = RAMSTKSiteConfiguration() - DUT.RAMSTK_SITE_CONF = VIRTUAL_ENV + "/share/RAMSTK/BigSite.toml" + DUT.RAMSTK_SITE_CONF = f"{VIRTUAL_ENV}/share/RAMSTK/BigSite.toml" assert DUT.get_site_configuration() is None @@ -678,8 +705,8 @@ def test_set_site_directories(self): DUT._INSTALL_PREFIX = VIRTUAL_ENV assert DUT.set_site_directories() is None - assert DUT.RAMSTK_SITE_DIR == DUT._INSTALL_PREFIX + "/share/RAMSTK" - assert DUT.RAMSTK_SITE_CONF == DUT.RAMSTK_SITE_DIR + "/Site.toml" + assert DUT.RAMSTK_SITE_DIR == f"{DUT._INSTALL_PREFIX}/share/RAMSTK" + assert DUT.RAMSTK_SITE_CONF == f"{DUT.RAMSTK_SITE_DIR}/Site.toml" @pytest.mark.unit def test_set_site_directories_no_site_conf_file(self): @@ -688,12 +715,12 @@ def test_set_site_directories_no_site_conf_file(self): _temp_dir = tempfile.mkdtemp() DUT = RAMSTKSiteConfiguration() DUT._INSTALL_PREFIX = _temp_dir - os.makedirs(_temp_dir + "/share/RAMSTK") + os.makedirs(f"{_temp_dir}/share/RAMSTK") assert DUT.set_site_directories() is None - assert os.path.isfile(_temp_dir + "/share/RAMSTK/Site.toml") - assert DUT.RAMSTK_SITE_DIR == _temp_dir + "/share/RAMSTK" - assert DUT.RAMSTK_SITE_CONF == _temp_dir + "/share/RAMSTK/Site.toml" + assert os.path.isfile(f"{_temp_dir}/share/RAMSTK/Site.toml") + assert DUT.RAMSTK_SITE_DIR == f"{_temp_dir}/share/RAMSTK" + assert DUT.RAMSTK_SITE_CONF == f"{_temp_dir}/share/RAMSTK/Site.toml" shutil.rmtree(_temp_dir) @@ -704,9 +731,9 @@ def test_set_site_configuration(self): _temp_dir = tempfile.mkdtemp() DUT = RAMSTKSiteConfiguration() DUT._INSTALL_PREFIX = _temp_dir - os.makedirs(_temp_dir + "/share/RAMSTK") + os.makedirs(f"{_temp_dir}/share/RAMSTK") - DUT.RAMSTK_SITE_CONF = _temp_dir + "/share/RAMSTK/Site.toml" + DUT.RAMSTK_SITE_CONF = f"{_temp_dir}/share/RAMSTK/Site.toml" DUT.RAMSTK_COM_INFO = { "dialect": "mine", "host": "here", @@ -717,9 +744,9 @@ def test_set_site_configuration(self): } assert DUT.set_site_configuration() is None - assert os.path.isfile(_temp_dir + "/share/RAMSTK/Site.toml") + assert os.path.isfile(f"{_temp_dir}/share/RAMSTK/Site.toml") - _config = toml.load(_temp_dir + "/share/RAMSTK/Site.toml") + _config = toml.load(f"{_temp_dir}/share/RAMSTK/Site.toml") assert _config["title"] == "RAMSTK Site Configuration" assert _config["backend"]["dialect"] == "mine" @@ -732,7 +759,11 @@ def test_set_site_configuration(self): shutil.rmtree(_temp_dir) @pytest.mark.unit - def test_get_user_configuration(self, test_toml_user_configuration): + def test_get_user_configuration( + self, + test_toml_user_configuration, + test_stress_limits, + ): """get_user_configuration() should return None on success.""" DUT = test_toml_user_configuration @@ -778,18 +809,7 @@ def test_get_user_configuration(self, test_toml_user_configuration): "usage_profile": "usage_profile.toml", "validation": "validation.toml", } - assert DUT.RAMSTK_STRESS_LIMITS == { - 1: [0.8, 0.9, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 125.0, 125.0], - 2: [1.0, 1.0, 0.7, 0.9, 1.0, 1.0, 0.0, 0.0, 125.0, 125.0], - 3: [1.0, 1.0, 0.5, 0.9, 1.0, 1.0, 0.0, 0.0, 125.0, 125.0], - 4: [1.0, 1.0, 1.0, 1.0, 0.6, 0.9, 10.0, 0.0, 125.0, 125.0], - 5: [0.6, 0.9, 1.0, 1.0, 0.5, 0.9, 15.0, 0.0, 125.0, 125.0], - 6: [0.75, 0.9, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 125.0, 125.0], - 7: [0.75, 0.9, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 125.0, 125.0], - 8: [0.7, 0.9, 1.0, 1.0, 0.7, 0.9, 25.0, 0.0, 125.0, 125.0], - 9: [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 125.0, 125.0], - 10: [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 125.0, 125.0], - } + assert DUT.RAMSTK_STRESS_LIMITS == test_stress_limits assert DUT.RAMSTK_BACKEND == "sqlite" assert DUT.RAMSTK_PROG_INFO["dialect"] == "sqlite" assert DUT.RAMSTK_PROG_INFO["host"] == "localhost" @@ -797,10 +817,10 @@ def test_get_user_configuration(self, test_toml_user_configuration): assert DUT.RAMSTK_PROG_INFO["database"] == "" assert DUT.RAMSTK_PROG_INFO["user"] == "" assert DUT.RAMSTK_PROG_INFO["password"] == "" - assert DUT.RAMSTK_DATA_DIR == DUT.RAMSTK_CONF_DIR + "/layouts" - assert DUT.RAMSTK_ICON_DIR == DUT.RAMSTK_CONF_DIR + "/icons" - assert DUT.RAMSTK_LOG_DIR == DUT.RAMSTK_CONF_DIR + "/logs" - assert DUT.RAMSTK_PROG_DIR == DUT.RAMSTK_HOME_DIR + "/analyses/ramstk" + assert DUT.RAMSTK_DATA_DIR == f"{DUT.RAMSTK_CONF_DIR}/layouts" + assert DUT.RAMSTK_ICON_DIR == f"{DUT.RAMSTK_CONF_DIR}/icons" + assert DUT.RAMSTK_LOG_DIR == f"{DUT.RAMSTK_CONF_DIR}/logs" + assert DUT.RAMSTK_PROG_DIR == f"{DUT.RAMSTK_HOME_DIR}/analyses/ramstk" assert DUT.RAMSTK_REPORT_SIZE == "letter" assert DUT.RAMSTK_HR_MULTIPLIER == 1000000.0 assert DUT.RAMSTK_DEC_PLACES == 6 @@ -809,8 +829,8 @@ def test_get_user_configuration(self, test_toml_user_configuration): assert DUT.RAMSTK_TABPOS["listbook"] == "bottom" assert DUT.RAMSTK_TABPOS["modulebook"] == "top" assert DUT.RAMSTK_TABPOS["workbook"] == "bottom" - assert DUT.RAMSTK_USER_LOG == (DUT.RAMSTK_LOG_DIR + "/ramstk_run.log") - assert DUT.RAMSTK_IMPORT_LOG == (DUT.RAMSTK_LOG_DIR + "/ramstk_import.log") + assert DUT.RAMSTK_USER_LOG == f"{DUT.RAMSTK_LOG_DIR}/ramstk_run.log" + assert DUT.RAMSTK_IMPORT_LOG == f"{DUT.RAMSTK_LOG_DIR}/ramstk_import.log" @pytest.mark.unit def test_get_user_configuration_no_conf_file(self): @@ -821,7 +841,7 @@ def test_get_user_configuration_no_conf_file(self): ) DUT = RAMSTKUserConfiguration() - DUT.RAMSTK_PROG_CONF = VIRTUAL_ENV + "/tmp/.config/RAMSTK/BigUser.toml" + DUT.RAMSTK_PROG_CONF = f"{VIRTUAL_ENV}/tmp/.config/RAMSTK/BigUser.toml" assert DUT.get_user_configuration() is None @@ -833,18 +853,25 @@ def test_get_user_configuration_no_conf_file(self): def test_get_user_configuration_no_log_dir(self, test_toml_user_configuration): """get_user_configuration() should set the log files relative to the current directory when RAMSTK_LOG_DIR is an empty string.""" - print(test_toml_user_configuration.RAMSTK_PROG_CONF) + # There is no way to set the log directory to an empty string without + # creating a test configuration file that does just that. DUT = test_toml_user_configuration assert DUT.get_user_configuration() is None - assert DUT.RAMSTK_USER_LOG == "./ramstk_run.log" - assert DUT.RAMSTK_IMPORT_LOG == "./ramstk_import.log" + assert ( + DUT.RAMSTK_USER_LOG + == f"{VIRTUAL_ENV}/tmp/.config/RAMSTK/logs/ramstk_run.log" + ) + assert ( + DUT.RAMSTK_IMPORT_LOG + == f"{VIRTUAL_ENV}/tmp/.config/RAMSTK/logs/ramstk_import.log" + ) @pytest.mark.unit def test_set_user_configuration(self): """set_user_configuration() should return None on success.""" DUT = RAMSTKUserConfiguration() - DUT.RAMSTK_PROG_CONF = VIRTUAL_ENV + "/tmp/.config/RAMSTK/RAMSTK.toml" + DUT.RAMSTK_PROG_CONF = f"{VIRTUAL_ENV}/tmp/.config/RAMSTK/RAMSTK.toml" # Create a default user configuration file and then read it. DUT.do_create_user_configuration() @@ -887,18 +914,18 @@ def test_set_user_directories(self): """set_user_variables() should return None on success when configuration directory structure exists in user's $HOME.""" DUT = RAMSTKUserConfiguration() - DUT.RAMSTK_HOME_DIR = VIRTUAL_ENV + "/tmp" + DUT.RAMSTK_HOME_DIR = f"{VIRTUAL_ENV}/tmp" assert DUT.set_user_directories() is None - assert DUT.RAMSTK_CONF_DIR == DUT.RAMSTK_HOME_DIR + "/.config/RAMSTK" + assert DUT.RAMSTK_CONF_DIR == f"{DUT.RAMSTK_HOME_DIR}/.config/RAMSTK" assert ( - DUT.RAMSTK_PROG_CONF == DUT.RAMSTK_HOME_DIR + "/.config/RAMSTK/RAMSTK.toml" + DUT.RAMSTK_PROG_CONF == f"{DUT.RAMSTK_HOME_DIR}/.config/RAMSTK/RAMSTK.toml" ) - assert DUT.RAMSTK_DATA_DIR == DUT.RAMSTK_CONF_DIR + "/layouts" - assert DUT.RAMSTK_ICON_DIR == DUT.RAMSTK_CONF_DIR + "/icons" - assert DUT.RAMSTK_LOG_DIR == DUT.RAMSTK_CONF_DIR + "/logs" - assert DUT.RAMSTK_PROG_DIR == DUT.RAMSTK_HOME_DIR + "/analyses/ramstk" + assert DUT.RAMSTK_DATA_DIR == f"{DUT.RAMSTK_CONF_DIR}/layouts" + assert DUT.RAMSTK_ICON_DIR == f"{DUT.RAMSTK_CONF_DIR}/icons" + assert DUT.RAMSTK_LOG_DIR == f"{DUT.RAMSTK_CONF_DIR}/logs" + assert DUT.RAMSTK_PROG_DIR == f"{DUT.RAMSTK_HOME_DIR}/analyses/ramstk" @pytest.mark.unit def test_set_user_directories_no_home(self): @@ -906,15 +933,15 @@ def test_set_user_directories_no_home(self): directory structure does NOT exist in user's $HOME.""" DUT = RAMSTKUserConfiguration() DUT._INSTALL_PREFIX = VIRTUAL_ENV - DUT.RAMSTK_HOME_DIR = VIRTUAL_ENV + "/home" + DUT.RAMSTK_HOME_DIR = f"{VIRTUAL_ENV}/home" assert DUT.set_user_directories() is None - assert DUT.RAMSTK_CONF_DIR == VIRTUAL_ENV + "/share/RAMSTK" - assert DUT.RAMSTK_PROG_CONF == VIRTUAL_ENV + "/share/RAMSTK/RAMSTK.toml" - assert DUT.RAMSTK_DATA_DIR == DUT.RAMSTK_CONF_DIR + "/layouts" - assert DUT.RAMSTK_ICON_DIR == DUT.RAMSTK_CONF_DIR + "/icons" - assert DUT.RAMSTK_LOG_DIR == DUT.RAMSTK_CONF_DIR + "/logs" + assert DUT.RAMSTK_CONF_DIR == f"{VIRTUAL_ENV}/share/RAMSTK" + assert DUT.RAMSTK_PROG_CONF == f"{VIRTUAL_ENV}/share/RAMSTK/RAMSTK.toml" + assert DUT.RAMSTK_DATA_DIR == f"{DUT.RAMSTK_CONF_DIR}/layouts" + assert DUT.RAMSTK_ICON_DIR == f"{DUT.RAMSTK_CONF_DIR}/icons" + assert DUT.RAMSTK_LOG_DIR == f"{DUT.RAMSTK_CONF_DIR}/logs" assert DUT.RAMSTK_PROG_DIR == DUT.RAMSTK_HOME_DIR @pytest.mark.unit @@ -925,11 +952,12 @@ def test_set_user_directories_no_user_conf_sub_dirs(self): DUT = RAMSTKUserConfiguration() DUT._INSTALL_PREFIX = VIRTUAL_ENV DUT.RAMSTK_HOME_DIR = _temp_dir + os.makedirs(f"{_temp_dir}/.config/RAMSTK", exist_ok=True) assert DUT.set_user_directories() is None - assert DUT.RAMSTK_CONF_DIR == VIRTUAL_ENV + "/share/RAMSTK" - assert DUT.RAMSTK_DATA_DIR == VIRTUAL_ENV + "/share/RAMSTK/layouts" - assert DUT.RAMSTK_ICON_DIR == VIRTUAL_ENV + "/share/RAMSTK/icons" - assert DUT.RAMSTK_LOG_DIR == VIRTUAL_ENV + "/share/RAMSTK/logs" + assert DUT.RAMSTK_CONF_DIR == f"{_temp_dir}/.config/RAMSTK" + assert DUT.RAMSTK_DATA_DIR == f"{VIRTUAL_ENV}/share/RAMSTK/layouts" + assert DUT.RAMSTK_ICON_DIR == f"{VIRTUAL_ENV}/share/RAMSTK/icons" + assert DUT.RAMSTK_LOG_DIR == f"{VIRTUAL_ENV}/share/RAMSTK/logs" assert DUT.RAMSTK_PROG_DIR == DUT.RAMSTK_HOME_DIR