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
Entra número deseado: """))
if elegir_magnitud == 1 :
unidad_temperatura = int(input(
"""
------------------Elige la unidad de temperatura a ser convertida:---------------
1 = Celsius
2 = Farhengei o como se escriba
3 = Kelvin
Entra número deseado: """))
cantidad_temperatura = float(input(
"""
Entra la cántidad de esa unidad deseada: """))
#ELEGIR UNIDAD DE TEMPERATURA A CONVERTIR
unidad_a_convertir = int(input(
"""
--------------------Elige la unidad de temperatura a convertir:-----------------
1 = Celsius
2 = Farhengei o como se escriba
3 = Kelvin
Entra número deseado: """))
if unidad_temperatura == unidad_a_convertir:
print("Por qué quieres convertir a la misma unidad?")
if unidad_temperatura == 1 and unidad_a_convertir == 3:
print("""El resultado de la conversion es: \n""",float(cantidad_temperatura - 273),"oK")
if unidad_temperatura == 1 and unidad_a_convertir == 2:
print("""El resultado de la conversion es: \n""",float(cantidad_temperatura * 9%5 +32),"oF")
if unidad_temperatura == 3 and unidad_a_convertir == 1:
print("""El resultado de la conversion es: \n""",float(cantidad_temperatura + 273),"oC")
if unidad_temperatura == 3 and unidad_a_convertir == 2:
print("""El resultado de la conversion es: \n""",float((cantidad_temperatura -273) * 9 % 5 + 32),"oF")
if unidad_temperatura == 2 and unidad_a_convertir == 3:
print("""El resultado de la conversion es: \n""",float((cantidad_temperatura - 32) % 9 * 5 - 273),"oK")
if unidad_temperatura == 2 and unidad_a_convertir == 1:
print("""El resultado de la conversion es: \n""",float(cantidad_temperatura % 9*5 -32),"oC")
1 Answer 1
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
Consider refactoring your code to:
- 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 directint
andfloat
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',
'Centígrada',
'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
Entra número deseado: 1
Elija la unidad de temperatura fuente para convertir:
1 = Kelvin
2 = Centígrada
3 = Fahrenheit
Entra número deseado: 3
Elija la unidad de temperatura de destino para convertir:
1 = Kelvin
2 = Centígrada
3 = Fahrenheit
Entra número deseado: 2
Proporcionar la temperatura de la fuente: 81
El resultado de la conversión es: 27,2