Skip to main content
added 1435 characters in body
Source Link
Reinderien
  • 65.3k
  • 5
  • 69
  • 187

Use argparse.

Note that all of your conversions are linear in one dimension. That means that you don't need two lambdas per conversion: just store a coefficient and offset from Kelvin for each temperature unit.

names should be a settuple.

Instead of dataclass, NamedTuple is a simpler alternative that is still frozen.

Later on I'll post example code demonstratingI should mention, I like that you've taken function bindings from your converter instances prior to the aboveloop.

Suggested

Only some of the conversions shown, for demonstration:

#!/usr/bin/python3

import argparse
from typing import NamedTuple


class TemperatureConverter(NamedTuple):
    offset: float
    coefficient: float
    names: tuple[str, ...]

    def to_kelvin(self, temp: float) -> float:
        return self.coefficient*temp + self.offset

    def from_kelvin(self, temp: float) -> float:
        return (temp - self.offset)/self.coefficient


CELSIUS    = TemperatureConverter(  273.15,    1, ("°c", "c"))
KELVIN     = TemperatureConverter(    0.00,    1, ("k",))
FAHRENHEIT = TemperatureConverter(45967/180, 5/9, ("°f", "f"))

CONVERTERS = {
    name: converter
    for converter in (CELSIUS, KELVIN, FAHRENHEIT)
    for name in converter.names
}


def main() -> None:
    parser = argparse.ArgumentParser()
    parser.add_argument('input_unit')
    parser.add_argument('output_unit')
    parser.add_argument('temperatures', type=float, nargs='+')
    args = parser.parse_args()

    convert_input = CONVERTERS[args.input_unit.lower()].to_kelvin
    convert_output = CONVERTERS[args.output_unit.lower()].from_kelvin

    for temperature in args.temperatures:
        output_temp = convert_output(convert_input(temperature))
        print(f'{output_temp:.2f}')


if __name__ == '__main__':
    main()

Use argparse.

Note that all of your conversions are linear in one dimension. That means that you don't need two lambdas per conversion: just store a coefficient and offset from Kelvin for each temperature unit.

names should be a set.

Instead of dataclass, NamedTuple is a simpler alternative that is still frozen.

Later on I'll post example code demonstrating the above.

Use argparse.

Note that all of your conversions are linear in one dimension. That means that you don't need two lambdas per conversion: just store a coefficient and offset from Kelvin for each temperature unit.

names should be a tuple.

Instead of dataclass, NamedTuple is a simpler alternative that is still frozen.

I should mention, I like that you've taken function bindings from your converter instances prior to the loop.

Suggested

Only some of the conversions shown, for demonstration:

#!/usr/bin/python3

import argparse
from typing import NamedTuple


class TemperatureConverter(NamedTuple):
    offset: float
    coefficient: float
    names: tuple[str, ...]

    def to_kelvin(self, temp: float) -> float:
        return self.coefficient*temp + self.offset

    def from_kelvin(self, temp: float) -> float:
        return (temp - self.offset)/self.coefficient


CELSIUS    = TemperatureConverter(  273.15,    1, ("°c", "c"))
KELVIN     = TemperatureConverter(    0.00,    1, ("k",))
FAHRENHEIT = TemperatureConverter(45967/180, 5/9, ("°f", "f"))

CONVERTERS = {
    name: converter
    for converter in (CELSIUS, KELVIN, FAHRENHEIT)
    for name in converter.names
}


def main() -> None:
    parser = argparse.ArgumentParser()
    parser.add_argument('input_unit')
    parser.add_argument('output_unit')
    parser.add_argument('temperatures', type=float, nargs='+')
    args = parser.parse_args()

    convert_input = CONVERTERS[args.input_unit.lower()].to_kelvin
    convert_output = CONVERTERS[args.output_unit.lower()].from_kelvin

    for temperature in args.temperatures:
        output_temp = convert_output(convert_input(temperature))
        print(f'{output_temp:.2f}')


if __name__ == '__main__':
    main()
Source Link
Reinderien
  • 65.3k
  • 5
  • 69
  • 187

Use argparse.

Note that all of your conversions are linear in one dimension. That means that you don't need two lambdas per conversion: just store a coefficient and offset from Kelvin for each temperature unit.

names should be a set.

Instead of dataclass, NamedTuple is a simpler alternative that is still frozen.

Later on I'll post example code demonstrating the above.