0

For the following code I would like to use a structure in order to not have to give 2 values for each element min and max and also I would like to have a container if exists to can give one value and the other one to remain None. For instance power to have only min element. So for power to have a container with 2 elements (for min and max) and same for temperature. How is that possible in python ? please help, thanks!

def result_final(
    power_min,
    power_max,
    temperature_min,
    temperature_max
) -> str:
    def _result_min(value) -> str:
        return "<min>" "<value>" + str(value) + "</value>" + "</min>"

    def _result_max(value) -> str:
        return "<max>" "<value>" + str(value) + "</value>" +" </max>"

    def _measure_result(unit_id, min_value, max_value) -> str:
        return (
            "<measure_result>"
            "<unit-id>" + str(unit_id) + "</unit-id>"
            "" + _result_min(min_value) + ""
            "" + _result_max(max_value) + ""
            "</measure_result>"
        )

    def _stats(object, min_value, max_value) -> str:
        return (
            "<stats>"
            "<object>" + object + "</object>"
            "" + _measure_result(0, min_value, max_value) + ""
            "" + _measure_result(1, min_value, max_value) + ""
            "</stats>"
        )

    content = (
        '<result-stats>'
        "" + _stats("POWER", power_min, power_max) + ""
         "" + _stats("TEMPERATURE", temperature_min, temperature_max) + ""
        "</result-stats>"
    )
    return content

x = result_final(power_min = 12, power_max = 125, temperature_min = 12, temperature_max = 12)
print(x)

2 Answers2

1

I'd suggest just using tuples for each min/max pair:

from typing import Optional, Tuple

Stats = Tuple[Optional[int], Optional[int]]  # min, max


def result_final(power: Stats, temperature: Stats) -> str:
    def _result_min(value: Optional[int]) -> str:
        return "" if value is None else f"<min><value>{value}</value></min>"

    def _result_max(value: Optional[int]) -> str:
        return "" if value is None else f"<max><value>{value}</value></max>"

    def _measure_result(unit_id: int, value: Stats) -> str:
        min_value, max_value = value
        return (
            "<measure_result>"
            f"<unit-id>{unit_id}</unit-id>"
            f"{_result_min(min_value)}"
            f"{_result_max(max_value)}"
            "</measure_result>"
        )

    def _stats(obj: str, value: Stats) -> str:
        return (
            "<stats>"
            f"<object>{object}</object>"
            f"{_measure_result(0, value)}"
            f"{_measure_result(1, value)}"
            "</stats>"
        )

    return (
        "<result-stats>"
        f"{_stats('POWER', power)}"
        f"{_stats('TEMPERATURE', temperature)}"
        "</result-stats>"
    )


print(result_final((12, 125), (12, 12)))
Samwise
  • 68,105
  • 3
  • 30
  • 44
  • is any way to can run result_final somehow to contain power.min ? like print(result_final((power.min = 12, power.max = None), (12, 12))) –  Dec 13 '21 at 19:40
  • You could use dataclasses or NamedTuples instead of regular tuples if you want each item to have a name. If `Stats` were defined as a `NamedTuple` of `min` and `max` then you could call `result_final` as `result_final(power=Stats(min=12, max=None), temperature=Stats(min=12, max=12))`. This doesn't make any difference to the generated output. With the regular tuple form you can also say `result_final(power=(12, None), temperature=(12, 12))` if you want to. – Samwise Dec 13 '21 at 19:41
  • Thank you so much, Samwise –  Dec 13 '21 at 19:45
0

I suggest you take a look at Python dataclasses.

from dataclasses import dataclass

@dataclass
class MyContainer:
    power_min: int = None
    power_max: int = None
    temperature_min: int = None
    temperature_max: int = None

The dataclass wrapper provides a convenient way to define a class that just stores some data. dataclasses is in the standard library (i.e., you do not need to install anything). The class I defined, by default, uses None for all attributes. Or you can specify values for the attributes you need.

a_container = MyContainer(power_max=5, temperature_min=3)

I also suggest to choose a better name than MyContainer: I used that because I did not know what you were trying to achieve! You can also decide to define two separate classes for TemperatureExtremes and PowerExtremes, if that makes more sense for you!

Enrico Gandini
  • 855
  • 5
  • 29