# Temperature unit converter in Python

I am starting to learn python and this has been my first project but I am not entirely happy, I think it could be done better. Could you help me? The strings are in Spanish but I think it does not harm understanding.

    elegir_magnitud = int(input(
"""1 = Temperatura
2 = Longitud
3 = Masa
4 = Volumen
5 = Tiempo
6 = Divisa
if elegir_magnitud == 1 :
"""

------------------Elige la unidad de temperatura a ser convertida:---------------
1 = Celsius
2 = Farhengei o como se escriba
3 = Kelvin
"""

#ELEGIR UNIDAD DE TEMPERATURA A CONVERTIR
"""

--------------------Elige la unidad de temperatura a convertir:-----------------
1 = Celsius
2 = Farhengei o como se escriba
3 = Kelvin
print("Por qué quieres convertir a la misma unidad?")
print("""El resultado de la conversion es: \n""",float((cantidad_temperatura -273) * 9 % 5 + 32),"ºF")
print("""El resultado de la conversion es: \n""",float((cantidad_temperatura - 32) % 9 * 5 - 273),"ºK")


## Localisation

The strings are in Spanish

Great! However, that's not the only thing in Spanish: your variables (elegir_magnitud, unidad_temperatura, etc.) are as well.

This is non-ideal for at least a couple of reasons:

• Python, being a language whose syntax is written in English, conflicts with your code that is then a mixture of English and Spanish. This is inconsistent.
• For better or worse, the de-facto language of software development is English. Particularly for international collaboration or online open-source development, it is important to use a language that is accessible to more people.

It's a wonderful thing to apply internationalization (i18n) to your strings, but it should be to your strings only, and not the code.

## Factor out common code

• Have only one method that asks for units, called twice (once for source unit and once for destination unit)
• Make a tuple of coefficient-offset pairs. These represent the linear function from the given unit to Kelvin and back. This will only need two unit conversion formulae, rather than (worst-case) 2^n with the current strategy.

## Bug?

Are you sure that this works?

cantidad_temperatura % 9*5 -32


I doubt that modulus is the right thing to do here. You should be using division /.

## Example code

Notes:

• This does a rough i18n, with some strings from Google Translate (so my apologies for the likely poor Spanish).
• Only English and Spanish are implemented but any other language can be added.
• This assumes that your operating system is set to the correct locale
• For these purposes, only the ISO639-1 language without country code is considered
• Enums are used for stricter type assurance
• Type hints are used for better static analysis and documentation
• I have not bothered to add the complexity of input validation, so if input is invalid, there will be an exception thrown
• Note the use of locale methods rather than direct int and float construction and formatting

strings.py

from locale import getlocale, getdefaultlocale

# For testing only
# from locale import setlocale, LC_ALL
# setlocale(LC_ALL, 'es_ES.UTF8')

def get_lang() -> str:
lang, _ = getlocale()
def_lang, _ = getdefaultlocale()
return (lang or def_lang)[:2]

LANG = get_lang()

if LANG == 'en':
DIMENSIONS = (
'Temperature',
'Length',
'Mass',
'Volume',
'Time',
'Currency',
)
TEMP_UNITS = (
'Kelvin',
'Celsius',
'Fahrenheit',
)
ENTER_NUMBER = 'Enter the desired number: '
CHOOSE_TEMP_SOURCE = 'Choose the source temperature unit to convert: '
CHOOSE_TEMP_DEST = 'Choose the destination temperature unit to convert: '
PROVIDE_TEMP = 'Provide the source temperature: '
RESULT = 'The result of the conversion is:'

elif LANG == 'es':
DIMENSIONS = (
'Temperatura',
'Longitud',
'Masa',
'Volumen',
'Tiempo',
'Divisa'
)
TEMP_UNITS = (
'Kelvin',
'Fahrenheit'
)
ENTER_NUMBER = 'Entra número deseado: '
CHOOSE_TEMP_SOURCE = 'Elija la unidad de temperatura fuente para convertir: '
CHOOSE_TEMP_DEST = 'Elija la unidad de temperatura de destino para convertir: '
PROVIDE_TEMP = 'Proporcionar la temperatura de la fuente: '
RESULT = 'El resultado de la conversión es:'


convert.py

from enum import Enum
from locale import format_string, atof, atoi
from typing import TypeVar, Type, Iterable

from strings import *

class Dimension(Enum):
TEMPERATURE = 1
LONGITUDE = 2
MASS = 3
VOLUME = 4
TIME = 5
CURRENCY = 6

class TempUnit(Enum):
KELVIN = 1
CELSIUS = 2
FAHRENHEIT = 3

# To get from this unit to Kelvin:
# kelvin = m * this_unit + b
TEMP_PARAMETERS = {
# This unit       m  b
TempUnit.KELVIN: (1, 0),
TempUnit.CELSIUS: (1, 273.16),
TempUnit.FAHRENHEIT: (5/9, 273.16 - 5/9*32),
}

InputEnum = TypeVar('InputEnum', bound=Enum)

def enum_from_input(t_enum: Type[InputEnum], labels: Iterable[str]) -> InputEnum:
print(
'\n'.join(
format_string('%d = %s', (enum.value, label))
for enum, label in zip(t_enum, labels)
)
)
result = t_enum(atoi(input(ENTER_NUMBER)))
print()
return result

def main():
dimension = enum_from_input(Dimension, DIMENSIONS)
if dimension != Dimension.TEMPERATURE:
raise NotImplementedError()

print(CHOOSE_TEMP_SOURCE)
source = enum_from_input(TempUnit, TEMP_UNITS)
print(CHOOSE_TEMP_DEST)
dest = enum_from_input(TempUnit, TEMP_UNITS)

temp1 = atof(input(PROVIDE_TEMP))

# Use a simple linear transformation where y = mx + b; first convert to
# the base unit (Kelvin)
m, b = TEMP_PARAMETERS[source]
kelvin = m*temp1 + b

# Now calculate inverse to the destination unit
m, b = TEMP_PARAMETERS[dest]
temp2 = (kelvin - b)/m

print(format_string('%s %.1f', (RESULT, temp2)))

if __name__ == '__main__':
main()


Example output

1 = Temperatura
2 = Longitud
3 = Masa
4 = Volumen
5 = Tiempo
6 = Divisa

Elija la unidad de temperatura fuente para convertir:
1 = Kelvin