Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I made this temperature converter when I first started getting into Python. After a year of regular programming on my own I decide it was time to revisit my old program. Now that I finished my first semester of computer science I took my old code and made it more efficient.

New:

# Declares the variables need for the converter function.
def declare_var():
    # Prompt user to select the initial temperature type.
    print("Enter a number to declare the initial temperature type?")
    print("[1] Celsius [2] Fahrenheit [3] Kelvin  [4] Rankine\n"
          "[5] Delisle [6] Newton     [7] Reaumer [8] Romer")
    initial_temp = int(eval(input('')))

    # Select the conversion equation within the list selected.
    print("Enter a number to specify the temperature for conversion?")
    print("[1] Celsius [2] Fahrenheit [3] Kelvin  [4] Rankine\n"
          "[5] Delisle [6] Newton     [7] Reaumer [8] Romer")
    conversion_temp = int(eval(input('')))

    # Gets input of temperature degrees.
    temp_degree = eval(input('''Enter the temperature degrees\n'''))

    return initial_temp, conversion_temp, temp_degree


# Calculates the temperature conversion based on
# returned variables from the declare_vars function.
def converter(function):
    # Assigned returned values variable names for readability.
    initial_temp = function[0]
    conversion_temp = function[1]
    temp = function[2]

    # The order of the conversion equations go in this order:
    # Celsius, Fahrenheit, Kelvin, Rankine, Delisle, Newton, Réaumur, Rømer.
    temp_equations = {"Celsius": [temp,  # Celsius
                                  temp * 9.0 / 5.0 + 32.0,  # Fahrenheit
                                  temp + 273.15,  # Kelvin
                                  temp + 273.15 * 9.0 / 5.0,  # Rankine
                                  (100 - temp) * 3.0 / 2.0,  # Delisle
                                  temp * 33.0 / 100.0,  # Newton
                                  temp * 4.0 / 5.0,  # Réaumur
                                  temp * 21.0 / 40.0 + 7.5],  # Rømer
                      "Fahrenheit": [(temp - 32.0) * 5.0 / 9.0,  # Celsius
                                     temp,  # Fahrenheit
                                     (temp + 459.67) * 5.0 / 9.0,  # Kelvin
                                     temp + 459.67,  # Rankine
                                     (212.0 - temp) * 5.0 / 6.0,  # Delisle
                                     (temp - 32) * 11.0 / 60.0,  # Newton
                                     (temp - 32) * 4.0 / 9.0,  # Réaumur
                                     (temp - 32) * 7.0 / 24.0],  # Rømer
                      "Kelvin": [temp - 273.15,  # Celsius
                                 temp * 9.0 / 5.0 + 459.67,  # Fahrenheit
                                 temp,  # Kelvin
                                 temp * 9.0 / 5.0,  # Rankine
                                 (373.15 - temp) * 3.0 / 2.0,  # Delisle
                                 (temp - 273.15) * 33.0 / 100.0,  # Newton
                                 (temp - 273.15) * 4.0 / 5.0,  # Réaumur
                                 (temp - 273.15) * 21.0 / 40.0 + 7.5],  # Rømer
                      "Rankine": [(temp - 491.67) * 5.0 / 9.0,  # Celsius
                                  temp - 459.67,  # Fahrenheit
                                  temp * 5.0 / 9.0,  # Kelvin
                                  temp,  # Rankine
                                  (671.67 - temp) * 5.0 / 6.0,  # Delisle
                                  (temp - 491.67) * 11.0 / 60.0,  # Newton
                                  (temp - 491.67) * 4.0 / 9.0,  # Réaumur
                                  (temp - 491.67) * 7.0 / 24.0 + 7.5],  # Rømer
                      "Delisle": [100.0 - temp * 2.0 / 3.0,  # Celsius
                                  212.0 - temp * 6.0 / 5.0,  # Fahrenheit
                                  375.15 - temp * 2.0 / 3.0,  # Kelvin
                                  671.67 - temp * 6.0 / 5.0,  # Rankine
                                  temp,  # Delisle
                                  33.0 - temp * 11.0 / 50.0,  # Newton
                                  80.0 - temp * 8.0 / 15.0,  # Réaumur
                                  60 - temp * 7.0 / 20.0],  # Rømer
                      "Newton": [temp * 100.0 / 33.0,  # Celsius
                                 temp * 60.0 / 11.0 + 32.0,  # Fahrenheit
                                 temp * 100.0 / 33.0 + 273.15,  # Kelvin
                                 temp * 60.0 / 11.0 + 491.67,  # Rankine
                                 (33 - temp) * 50.0 / 11.0,  # Delisle
                                 temp,  # Newton
                                 temp * 80.0 / 33.0,  # Réaumur
                                 temp * 35.0 / 22.0 + 7.5],  # Rømer
                      "Reaumer": [temp * 5.0 / 4.0,  # Celsius
                                  temp * 9.0 / 4.0 + 32.0,  # Fahrenheit
                                  temp * 5.0 / 4.0 + 273.15,  # Kelvin
                                  temp * 9.0 / 4.0 + 491.67,  # Rankine
                                  (80 - temp) * 15.0 / 8.0,  # Delisle
                                  temp * 33.0 / 80.0,  # Newton
                                  temp,  # Réaumur
                                  temp * 21.0 / 32.0 + 7.5],  # Rømer
                      "Romer": [(temp - 7.5) * 40.0 / 21.0,  # Celsius
                                (temp - 7.5) * 24.0 / 7.0 + 32.0,  # Fahrenheit
                                (temp - 7.5) * 40.0 / 21.0 + 273.15,  # Kelvin
                                (temp - 7.5) * 24.0 / 7.0 + 491.67,  # Rankine
                                (60 - temp) * 20.0 / 7.0,  # Delisle
                                (temp - 7.5) * 22.0 / 35.0,  # Newton
                                (temp - 7.5) * 32.0 / 21.0,  # Réaumur
                                temp]  # Rømer
                      }
    # List of temperature names.
    temp_list = ["Celsius", "Fahrenheit", "Kelvin", "Rankine",
                 "Delisle", "Newton", "Reaumer", "Romer"]

    # Sets the initial temperature type.
    select_temp = temp_list[initial_temp - 1]

    # Selected the list of equations matched with the dictionary key.
    select_equation = temp_equations[select_temp]

    # Selects the calculated equation for the selected conversion
    temp_conversion = (select_equation[conversion_temp - 1])

    # Print output of temperature conversion. Ex: Celsius -> Romer = 165
    a = "%s -> %s = %f" % (select_temp, temp_list[conversion_temp - 1],     temp_conversion)
    print(a)

    return temp_conversion

def main():
    converter(declare_var())


if __name__ == '__main__':
    main()

Old:

#Lets user know what values to enter for the conversion type
def convertor():
    print("What temperature are you converting from?")
    print("Enter 1 for Celcius\nEnter 2 for Fahrenheit\nEnter 3 for Kelvin\nEnter 4 for Rankine")
    print("Enter 5 for Delisle\nEnter 6 for Newton\nEnter 7 for Reaumer\nEnter 8 for Romer")
    #Gets user input for conversion type
    user_input = input('''''')

    #If 1 is selected it starts conversion from Celcius
    if user_input == ("1"):
            def celsius():
                    print("\nWhat temperature are you converting too?")
                    print("Enter 1 for Celcius\nEnter 2 for Fahrenheit\nEnter 3 for Kelvin\nEnter 4 for Rankine")
                    print("Enter 5 for Delisle\nEnter 6 for Newton\nEnter 7 for Reaumer\nEnter 8 for Romer")                
                    #Gets user input for converting
                    type = input('''''')
                    #COnverts to celcius
                    if type == ("1"):
                            temp = int(input('''\nType the value for conversion.\n'''))
                            print("\nThe conversion calculated")
                            print(temp)
                    #Converts to fahrenheit
                    elif type == ("2"):
                            temp = int(input('''\nType the value for conversion.\n'''))
                            fahrenheit = temp * (9.0/5.0) + 32
                            print("\nThe conversion calculated")
                            print(fahrenheit)
                    #Converts to Kelvin
                    elif type == ("3"):
                            temp = int(input('''\nType the value for conversion.\n'''))
                            kelvin = temp + 273.15
                            print("\nThe conversion calculated")
                            print(kelvin)
                    #Converts to Rankine
                    elif type == ("4"):
                            temp = int(input('''\nType the value for conversion.\n'''))
                            rankine = (temp + 273.15) * (9.0/5.0) 
                            print("\nThe conversion calculated")
                            print(rankine)
                    #Converts to Delisle
                    elif type == ("5"):
                            temp = int(input('''\nType the value for conversion.\n'''))
                            delisle = (100 - temp) * (3.0/2.0) 
                            print("\nThe conversion calculated")
                            print(delisle)
                    #Converts to Newton
                    elif type == ("6"):
                            temp = int(input('''\nType the value for conversion.\n'''))
                            newton = temp * (33.0/100.0) 
                            print("\nThe conversion calculated")
                            print(newton)
                    #Converts to Reaumur
                    elif type == ("7"):
                            temp = int(input('''\nType the value for conversion.\n'''))
                            reaumur = temp * (4.0/5.0) 
                            print("\nThe conversion calculated")
                            print(reaumur)
                    #Converts to Romer
                    elif type == ("8"):
                            temp = int(input('''\nType the value for conversion.\n'''))
                            romer = temp * (9.0/5.0) + 7.5
                            print("\nThe conversion calculated")
                            print(romer)
            celsius()

    #If 2 is selected it starts conversion from Fahrenheit
    if user_input == ("2"):
            def fahrenheit():
                    print("\nWhat temperature are you converting too?")
                    print("Enter 1 for Celcius\nEnter 2 for Fahrenheit\nEnter 3 for Kelvin\nEnter 4 for Rankine")
                    print("Enter 5 for Delisle\nEnter 6 for Newton\nEnter 7 for Reaumer\nEnter 8 for Romer")                
                    #Gets user input for converting
                    fahrenheit_type = input('''''')
                    #Converts to celcius
                    if fahrenheit_type == ("1"):
                            temp = int(input('''\nType the value for conversion.\n'''))
                            fahrenheit = (temp - 32) * (5.0/9.0)
                            print("\nThe conversion calculated")
                            print(fahrenheit)
                    #Converts to fahrenheit
                    elif fahrenheit_type == ("2"):
                            temp = int(input('''\nType the value for conversion.\n'''))
                            print("\nThe conversion calculated")
                            print(temp)
                    #Converts to Kelvin
                    elif fahrenheit_type == ("3"):
                            temp = int(input('''\nType the value for conversion.\n'''))
                            fahrneheit = (temp + 459.67) * (5.0/9.0)
                            print("\nThe conversion calculated")
                            print(fahrenheit)
                    #Converts to Rankine
                    elif fahrenheit_type == ("4"):
                            temp = int(input('''\nType the value for conversion.\n'''))
                            fahrenheit = temp + 459.67 
                            print("\nThe conversion calculated")
                            print(fahrenheit)
                    #Converts to Delisle
                    elif fahrenheit_type == ("5"):
                            temp = int(input('''\nType the value for conversion.\n'''))
                            fahrenheit = (212 - temp) * (5.0/6.0) 
                            print("\nThe conversion calculated")
                            print(fahrenheit)
                    #Converts to Newton
                    elif fahrenheit_type == ("6"):
                            temp = int(input('''\nType the value for conversion.\n'''))
                            fahrenheit = (temp - 32) * (11.0/60.0) 
                            print("\nThe conversion calculated")
                            print(fahrenheit)
                    #Converts to Reaumur
                    elif fahrenheit_type == ("7"):
                            temp = int(input('''\nType the value for conversion.\n'''))
                            fahrenheit = (temp -32) * (4.0/9.0) 
                            print("\nThe conversion calculated")
                            print(fahrenheit)
                    #Converts to Romer
                    elif fahrenheit_type == ("8"):
                            temp = int(input('''\nType the value for conversion.\n'''))
                            fahrenheit = (temp + 32) * (7.0/24.0) + 32 
                            print("\nThe conversion calculated")
                            print(fahrenheit)    
            fahrenheit()

    #If 3 is selected it starts conversion from kelvin
    if user_input == ("3"):
            def kelvin():
                    print("\nWhat temperature are you converting too?")
                    print("Enter 1 for Celcius\nEnter 2 for Fahrenheit\nEnter 3 for Kelvin\nEnter 4 for Rankine")
                    print("Enter 5 for Delisle\nEnter 6 for Newton\nEnter 7 for Reaumer\nEnter 8 for Romer")                
                    #Gets user input for converting
                    kelvin_type = input('''''')
                    #Converts to celcius
                    if kelvin_type == ("1"):
                            temp = int(input('''\nType the value for conversion.\n'''))
                            kelvin = temp - 273.15 
                            print("\nThe conversion calculated")
                            print(kelvin)
                    #Converts to fahrenheit
                    if kelvin_type == ("2"):
                            temp = int(input('''\nType the value for conversion.\n'''))
                            kelvin = temp * (9.0/5.0) - 489.67
                            print("\nThe conversion calculated")
                            print(fahrenheit)
                    #Converts to Kelvin
                    elif kelvin_type == ("3"):
                            kelvin = int(input('''\nType the value for conversion.\n'''))
                            print("\nThe conversion calculated\n")
                            print(kelvin)
                    #Converts to Rankine
                    elif kelvin_type == ("4"):
                            temp = int(input('''\nType the value for conversion.\n'''))
                            kelvin = temp * (9.0/5.0) 
                            print("\nThe conversion calculated")
                            print(kelvin)
                    #Converts to Delisle
                    elif kelvin_type == ("5"):
                            temp = int(input('''\nType the value for conversion.\n'''))
                            kelvin = (375.15 - temp) * (3.0/2.0) 
                            print("\nThe conversion calculated")
                            print(kelvin)
                    #Converts to Newton
                    elif kelvin_type == ("6"):
                            temp = int(input('''\nType the value for conversion.\n'''))
                            kelvin = (temp - 273.15) * (33.0/100.0) 
                            print("\nThe conversion calculated")
                            print(kelvin)
                    #Converts to Reaumur
                    elif kelvin_type == ("7"):
                            temp = int(input('''\nType the value for conversion.\n'''))
                            kelvin = (temp - 273.15) * (4.0/5.0) 
                            print("\nThe conversion calculated")
                            print(kelvin)
                    #Converts to Romer
                    elif kelvin_type == ("8"):
                            temp = int(input('''\nType the value for conversion.\n'''))
                            kelvin = (temp - 273.15) * (21.0/40.0) + 7.5 
                            print("\nThe conversion calculated")
                            print(romer)    
            kelvin()

    #If 4 is selected it starts conversion from Rankine
    if user_input == ("4"):
            def rankine():
                    print("\nWhat temperature are you converting too?")
                    print("Enter 1 for Celcius\nEnter 2 for Fahrenheit\nEnter 3 for Kelvin\nEnter 4 for Rankine")
                    print("Enter 5 for Delisle\nEnter 6 for Newton\nEnter 7 for Reaumer\nEnter 8 for Romer")                
                    #Gets user input for converting
                    celcius_type = input('''''')
                    #COnverts to celcius
                    if celcius_type == ("1"):
                            temp = int(input('''\nType the value for conversion.\n'''))
                            print("\nThe conversion calculated")
                            print(temp)
                    #Converts to fahrenheit
                    elif celcius_type == ("2"):
                            temp = int(input('''\nType the value for conversion.\n'''))
                            fahrenheit = temp * (9.0/5.0) + 32
                            print("\nThe conversion calculated")
                            print(fahrenheit)
                    #Converts to Kelvin
                    elif celcius_type == ("3"):
                            temp = int(input('''\nType the value for conversion.\n'''))
                            kelvin = temp + 273.15
                            print("\nThe conversion calculated")
                            print(kelvin)
                    #Converts to Rankine
                    elif celcius_type == ("4"):
                            temp = int(input('''\nType the value for conversion.\n'''))
                            rankine = (temp + 273.15) * (9.0/5.0) 
                            print("\nThe conversion calculated")
                            print(rankine)
                    #Converts to Delisle
                    elif celcius_type == ("5"):
                            temp = int(input('''\nType the value for conversion.\n'''))
                            delisle = (temp + 273.15) * (9.0/5.0) 
                            print("\nThe conversion calculated")
                            print(delisle)
                    #Converts to Newton
                    elif celcius_type == ("6"):
                            temp = int(input('''\nType the value for conversion.\n'''))
                            newton = (temp + 273.15) * (9.0/5.0) 
                            print("\nThe conversion calculated")
                            print(newton)
                    #Converts to Reaumur
                    elif celcius_type == ("7"):
                            temp = int(input('''\nType the value for conversion.\n'''))
                            reaumur = (temp + 273.15) * (9.0/5.0) 
                            print("\nThe conversion calculated")
                            print(reaumur)
                    #Converts to Romer
                    elif celcius_type == ("8"):
                            temp = int(input('''\nType the value for conversion.\n'''))
                            romer = (temp + 273.15) * (9.0/5.0) 
                            print("\nThe conversion calculated")
                            print(romer)    
            rankine()

    #If 5 is selected it starts conversion from Delisle
    if user_input == ("5"):
            def delisle():
                    print("\nWhat temperature are you converting too?")
                    print("Enter 1 for Celcius\nEnter 2 for Fahrenheit\nEnter 3 for Kelvin\nEnter 4 for Rankine")
                    print("Enter 5 for Delisle\nEnter 6 for Newton\nEnter 7 for Reaumer\nEnter 8 for Romer")                
                    #Gets user input for converting
                    celcius_type = input('''''')
                    #COnverts to celcius
                    if celcius_type == ("1"):
                            temp = int(input('''\nType the value for conversion.\n'''))
                            print("\nThe conversion calculated")
                            print(temp)
                    #Converts to fahrenheit
                    if celcius_type == ("2"):
                            temp = int(input('''\nType the value for conversion.\n'''))
                            fahrenheit = temp * (9.0/5.0) + 32
                            print("\nThe conversion calculated")
                            print(fahrenheit)
                    #Converts to Kelvin
                    elif celcius_type == ("3"):
                            temp = int(input('''\nType the value for conversion.\n'''))
                            kelvin = temp + 273.15
                            print("\nThe conversion calculated")
                            print(kelvin)
                    #Converts to Rankine
                    elif celcius_type == ("4"):
                            temp = int(input('''\nType the value for conversion.\n'''))
                            rankine = (temp + 273.15) * (9.0/5.0) 
                            print("\nThe conversion calculated")
                            print(rankine)
                    #Converts to Delisle
                    elif celcius_type == ("5"):
                            temp = int(input('''\nType the value for conversion.\n'''))
                            delisle = (temp + 273.15) * (9.0/5.0) 
                            print("\nThe conversion calculated")
                            print(delisle)
                    #Converts to Newton
                    elif celcius_type == ("6"):
                            temp = int(input('''\nType the value for conversion.\n'''))
                            newton = (temp + 273.15) * (9.0/5.0) 
                            print("\nThe conversion calculated")
                            print(newton)
                    #Converts to Reaumur
                    elif celcius_type == ("7"):
                            temp = int(input('''\nType the value for conversion.\n'''))
                            reaumur = (temp + 273.15) * (9.0/5.0) 
                            print("\nThe conversion calculated")
                            print(reaumur)
                    #Converts to Romer
                    elif celcius_type == ("8"):
                            temp = int(input('''\nType the value for conversion.\n'''))
                            romer = (temp + 273.15) * (9.0/5.0) 
                            print("\nThe conversion calculated")
                            print(romer)    
            delisle()

    #If 6 is selected it starts conversion from newton
    if user_input == ("6"):
            def newton():
                    print("\nWhat temperature are you converting too?")
                    print("Enter 1 for Celcius\nEnter 2 for Fahrenheit\nEnter 3 for Kelvin\nEnter 4 for Rankine")
                    print("Enter 5 for Delisle\nEnter 6 for Newton\nEnter 7 for Reaumer\nEnter 8 for Romer")                
                    #Gets user input for converting
                    celcius_type = input('''''')
                    #COnverts to celcius
                    if celcius_type == ("1"):
                            temp = int(input('''\nType the value for conversion.\n'''))
                            print("\nThe conversion calculated")
                            print(temp)
                    #Converts to fahrenheit
                    if celcius_type == ("2"):
                            temp = int(input('''\nType the value for conversion.\n'''))
                            fahrenheit = temp * (9.0/5.0) + 32
                            print("\nThe conversion calculated")
                            print(fahrenheit)
                    #Converts to Kelvin
                    elif celcius_type == ("3"):
                            temp = int(input('''\nType the value for conversion.\n'''))
                            kelvin = temp + 273.15
                            print("\nThe conversion calculated")
                            print(kelvin)
                    #Converts to Rankine
                    elif celcius_type == ("4"):
                            temp = int(input('''\nType the value for conversion.\n'''))
                            rankine = (temp + 273.15) * (9.0/5.0) 
                            print("\nThe conversion calculated")
                            print(rankine)
                    #Converts to Delisle
                    elif celcius_type == ("5"):
                            temp = int(input('''\nType the value for conversion.\n'''))
                            delisle = (temp + 273.15) * (9.0/5.0) 
                            print("\nThe conversion calculated")
                            print(delisle)
                    #Converts to Newton
                    elif celcius_type == ("6"):
                            temp = int(input('''\nType the value for conversion.\n'''))
                            newton = (temp + 273.15) * (9.0/5.0) 
                            print("\nThe conversion calculated")
                            print(newton)
                    #Converts to Reaumur
                    elif celcius_type == ("7"):
                            temp = int(input('''\nType the value for conversion.\n'''))
                            reaumur = (temp + 273.15) * (9.0/5.0) 
                            print("\nThe conversion calculated")
                            print(reaumur)
                    #Converts to Romer
                    elif celcius_type == ("8"):
                            temp = int(input('''\nType the value for conversion.\n'''))
                            romer = (temp + 273.15) * (9.0/5.0) 
                            print("\nThe conversion calculated")
                            print(romer)    
            newton()

    #If 7 is selected it starts conversion from Fahrenheit
    if user_input == ("7"):
            def reaumur():
                    print("\nWhat temperature are you converting too?")
                    print("Enter 1 for Celcius\nEnter 2 for Fahrenheit\nEnter 3 for Kelvin\nEnter 4 for Rankine")
                    print("Enter 5 for Delisle\nEnter 6 for Newton\nEnter 7 for Reaumer\nEnter 8 for Romer")                
                    #Gets user input for converting
                    celcius_type = input('''''')
                    #COnverts to celcius
                    if celcius_type == ("1"):
                            temp = int(input('''\nType the value for conversion.\n'''))
                            print("\nThe conversion calculated")
                            print(temp)
                    #Converts to fahrenheit
                    if celcius_type == ("2"):
                            temp = int(input('''\nType the value for conversion.\n'''))
                            fahrenheit = temp * (9.0/5.0) + 32
                            print("\nThe conversion calculated")
                            print(fahrenheit)
                    #Converts to Kelvin
                    elif celcius_type == ("3"):
                            temp = int(input('''\nType the value for conversion.\n'''))
                            kelvin = temp + 273.15
                            print("\nThe conversion calculated")
                            print(kelvin)
                    #Converts to Rankine
                    elif celcius_type == ("4"):
                            temp = int(input('''\nType the value for conversion.\n'''))
                            rankine = (temp + 273.15) * (9.0/5.0) 
                            print("\nThe conversion calculated")
                            print(rankine)
                    #Converts to Delisle
                    elif celcius_type == ("5"):
                            temp = int(input('''\nType the value for conversion.\n'''))
                            delisle = (temp + 273.15) * (9.0/5.0) 
                            print("\nThe conversion calculated")
                            print(delisle)
                    #Converts to Newton
                    elif celcius_type == ("6"):
                            temp = int(input('''\nType the value for conversion.\n'''))
                            newton = (temp + 273.15) * (9.0/5.0) 
                            print("\nThe conversion calculated")
                            print(newton)
                    #Converts to Reaumur
                    elif celcius_type == ("7"):
                            temp = int(input('''\nType the value for conversion.\n'''))
                            reaumur = (temp + 273.15) * (9.0/5.0) 
                            print("\nThe conversion calculated")
                            print(reaumur)
                    #Converts to Romer
                    elif celcius_type == ("8"):
                            temp = int(input('''\nType the value for conversion.\n'''))
                            romer = (temp + 273.15) * (9.0/5.0) 
                            print("\nThe conversion calculated")
                            print(romer)    
            reaumur()

    #If 8 is selected it starts conversion from Fahrenheit
    if user_input == ("8"):
            def romer():
                    print("\nWhat temperature are you converting too?")
                    print("Enter 1 for Celcius\nEnter 2 for Fahrenheit\nEnter 3 for Kelvin\nEnter 4 for Rankine")
                    print("Enter 5 for Delisle\nEnter 6 for Newton\nEnter 7 for Reaumer\nEnter 8 for Romer")                
                    #Gets user input for converting
                    celcius_type = input('''''')
                    #COnverts to celcius
                    if celcius_type == ("1"):
                            temp = int(input('''\nType the value for conversion.\n'''))
                            print("\nThe conversion calculated")
                            print(temp)
                    #Converts to fahrenheit
                    if celcius_type == ("2"):
                            temp = int(input('''\nType the value for conversion.\n'''))
                            fahrenheit = temp * (9.0/5.0) + 32
                            print("\nThe conversion calculated")
                            print(fahrenheit)
                    #Converts to Kelvin
                    elif celcius_type == ("3"):
                            temp = int(input('''\nType the value for conversion.\n'''))
                            kelvin = temp + 273.15
                            print("\nThe conversion calculated")
                            print(kelvin)
                    #Converts to Rankine
                    elif celcius_type == ("4"):
                            temp = int(input('''\nType the value for conversion.\n'''))
                            rankine = (temp + 273.15) * (9.0/5.0) 
                            print("\nThe conversion calculated")
                            print(rankine)
                    #Converts to Delisle
                    elif celcius_type == ("5"):
                            temp = int(input('''\nType the value for conversion.\n'''))
                            delisle = (temp + 273.15) * (9.0/5.0) 
                            print("\nThe conversion calculated")
                            print(delisle)
                    #Converts to Newton
                    elif celcius_type == ("6"):
                            temp = int(input('''\nType the value for conversion.\n'''))
                            newton = (temp + 273.15) * (9.0/5.0) 
                            print("\nThe conversion calculated")
                            print(newton)
                    #Converts to Reaumur
                    elif celcius_type == ("7"):
                            temp = int(input('''\nType the value for conversion.\n'''))
                            reaumur = (temp + 273.15) * (9.0/5.0) 
                            print("\nThe conversion calculated")
                            print(reaumur)
                    #Converts to Romer
                    elif celcius_type == ("8"):
                            temp = int(input('''\nType the value for conversion.\n'''))
                            romer = (temp + 273.15) * (9.0/5.0) 
                            print("\nThe conversion calculated")
                            print(romer)    
            romer()

    #Performs a loop asking if we want to restart the progam
    def loop():
            restartprgm = input("\nType yes to make another conversion. Type no to exit the program\n")
            while restartprgm == ("Yes") or ("yes") or ("YES") or ("Y") or ("y"):
                    print()
                    return convertor()
            else:
                    while restartprgm == ("No\n") or ("no\n") or ("NO\n") or ("N\n") or ("n\n"):
                            print("See you later!")
                            exit()
    loop()

convertor()
share|improve this question
    
What's the point of def something(): ...stuff here... immediately followed by something()? – immibis Jan 14 at 23:11
    
Thanks for the detailed responses everyone. It's good to know that I still have a lot to learn. Now I'll research how to properly implement code so I don't make the same mistakes in the future. – Zak Jan 15 at 6:15
up vote 32 down vote accepted

Your second solution is basically a brute-force if-else tree, with lots of repetitive code, and not particularly interesting to review. I'll just focus on the first solution.


Your terminology is confusing, as exemplified by this line near the end of converter():

# Selects the calculated equation for the selected conversion
temp_conversion = (select_equation[conversion_temp - 1])

What does temp_conversion mean? What does conversion_temp mean?

I recommend changing the terminology this way:

  • initial_tempfrom_scale
  • conversion_tempto_scale
  • tempfrom_temp
  • temp_conversiontemp or result

The way converter() accepts its parameters is rather weird:

def converter(function):
    # Assigned returned values variable names for readability.
    initial_temp = function[0]
    conversion_temp = function[1]
    temp = function[2]

What function are you talking about? A more conventional way to write that would be

def converter(from_scale, to_scale, from_temp):
    …

… which you can call using a "splat":

def main():
    converter(*declare_var())

I like that you made a declare_var() function as the input routine. However, that leaves converter() to do the calculation and print the output. A better division of labour would be to have a function that does just the calculation, and a second function to serve as the input/output front-end. If you were to develop a GUI, then the calculation function would be reusable, and you would replace the input/output front-end.


You have a combinatorial problem: with 8 temperature scales, you need to define 8 × 8 = 64 conversion formulas. Not only do you have a lot of formulas, it's also hard to maintain them all correctly. I hope that your # Celsius, # Fahrenheit, # Kelvin, # Rankine, # Delisle, # Réaumur, and # Rømer comments are all in the right place!

Note that when you write…

temp_equations = {"Celsius": [temp,  # Celsius
                              temp * 9.0 / 5.0 + 32.0,  # Fahrenheit
                              temp + 273.15,  # Kelvin
                              temp + 273.15 * 9.0 / 5.0,  # Rankine
                              (100 - temp) * 3.0 / 2.0,  # Delisle
                              temp * 33.0 / 100.0,  # Newton
                              temp * 4.0 / 5.0,  # Réaumur
                              temp * 21.0 / 40.0 + 7.5],  # Rømer

… you aren't defining eight equations. You are actually performing eight conversions. In other words, your converter performs 64 conversions, and discards the result of 63 of those calculations. If you want to define formulas rather than values, then they need to be functions — ideally written using lambda.

A better design would be to define conversion formulas for each temperature scale with just one canonical scale (say Kelvin).


The way that the "equations" are written places a burden on you of maintaining consistency. The values of temp_equations must appear in the same order as in temp_list, which must list the scales in the same order as they appear in the menu. If you ever want to change the menu order, good luck to you.

You could eliminate temp_list by using an OrderedDict. You can also generate the text menu from that dictionary, though the code to do so is a bit tricky.


Pay attention to spelling. You wrote "Reaumer" in temp_list, temp_equations, and the menu, despite having spelled it correctly in the comments. You also wrote "Celcius" and "What temperature are you converting too?" in the brute-force solution.


From a human-factors point of view, I think it's confusing to ask for the source scale, then the destination scale, and then the input temperature in source scale units. For coherence, it would be better to ask for the input temperature before asking for the destination scale.

To avoid all ambiguity, instead of asking "Enter the temperature degrees" or "Type the value for conversion", ask "Enter the temperature in Réaumur".


Suggested solution

from collections import OrderedDict

TEMP_SCALES = OrderedDict([
    ('Celsius', {
        'from_K': lambda k: k - 273.15,
        'to_K':   lambda c: c + 273.15
    }),
    ('Fahrenheit', {
        'from_K': lambda k: 1.8 * k + 459.67,
        'to_K':   lambda f: (f + 459.67) / 1.8,
    }),
    ('Kelvin', {
        'from_K': lambda k: k,
        'to_K':   lambda k: k
    }),
    ('Rankine', {
        'from_K': lambda k: 1.8 * k,
        'to_K':   lambda r: r / 1.8
    }),
    ('Delisle', {
        'from_K': lambda k: 1.5 * (373.15 - k),
        'to_K':   lambda d: 373.15 - (2/3) * d
    }),
    ('Newton', {
        'from_K': lambda k: 0.33 * (k - 273.15),
        'to_K':   lambda n: (100 / 33) * n + 273.15
    }),
    ('Réaumur', {
        'from_K': lambda k: 0.8 * (k - 273.15),
        'to_K':   lambda r: 1.25 * r + 273.15
    }),
    ('Rømer', {
        'from_K': lambda k: (21 / 40) * (k - 273.15) + 7.5,
        'to_K':   lambda r: (40 / 21) * (r - 7.5) + 273.15
    }),
])

def convert(from_temp, from_scale, to_scale):
    """
    Convert temperature from one scale to another.
    from_scale and to_scale should each be a key of TEMP_SCALES.
    """
    temp_k = TEMP_SCALES[from_scale]['to_K'](from_temp)
    if temp_k < 0:
        raise ValueError('Temperature is below absolute zero')
    return TEMP_SCALES[to_scale]['from_K'](temp_k)

def prompt_and_convert():
    """
    Ask the user for input and perform one temperature conversion.
    """
    longest_scale = max(len(name) for name in TEMP_SCALES.keys())
    menu = ''.join([
        '[{}] '.format(i) + name.ljust(longest_scale + 1)
        for i, name in enumerate(TEMP_SCALES.keys(), 1)
    ])
    print(menu[: len(menu) // 2])       # First line of menu
    print(menu[len(menu) // 2 :])       # Second line of menu

    def ask_scale(prompt):
        while True:
            try:
                choice = int(input(prompt))
                return list(TEMP_SCALES.keys())[choice - 1]
            except (ValueError, IndexError):
                print('Invalid choice')

    from_scale = ask_scale('Enter temperature scale to convert from: ')
    from_temp = float(input('Enter temperature in {}: '.format(from_scale)))
    to_scale = ask_scale('Enter temperature scale to convert to: ')
    result = convert(from_temp, from_scale, to_scale)
    print('{} in {} is {} in {}'.format(from_temp, from_scale, result, to_scale))

if __name__ == '__main__':
    prompt_and_convert()
share|improve this answer
3  
Excellent answer. Just an additional comment if I may : the definition of the different conversion functions is in conflict with the "don't repeat yourself" principle as you have the same coefficients defined in different places. Because most (all?) conversions correspond to linar function (with a non-null coefficient), it might be worth writing a function defining both the "conversion from" and the "conversion to" function for the 2 parameters. – Josay Jan 14 at 13:33

eval() is considered harmful and should not be used - especially so with user input strings:

  • It allows users of your code to execute arbitrary code, including to drop to REPL.
  • You may use ast.literal_eval(), or simply int() or float() instead.

The conversions performed here are all simple 1D linear transformations (translation and scaling). Therefore, you don't have to define the specific formula for each pair of scales for each direction.

If you know two matching points on each scale, you can use the same generic formula to compute the conversion in each direction. This way you need to define a lot less magical numbers in your code and make it thus more maintainable.

In this example I have used (i.e., arbitrarily picked) different scales' values for 0 and 100 degree of Celsius to give an idea how this might simplify your code:

# values for 0 and 100 deg Celsius on each supported scale
scale_factors = {
    "Celsius":    {"lower":   0.00, "upper": 100.00},
    "Fahrenheit": {"lower":  32.00, "upper": 212.00},
    "Kelvin":     {"lower": 273.15, "upper": 373.15},
    "Rankine":    {"lower": 491.67, "upper": 671.67},
    "Delisle":    {"lower": 150.00, "upper":   0.00},
    "Newton":     {"lower":   0.00, "upper":  33.00},
    "Réaumur":    {"lower":   0.00, "upper":  80.00},
    "Rømer":      {"lower":   7.50, "upper":  60.00},
}

# generic function to do the conversion
def convert_scale(src_temp, src_scale, dst_scale, scale_factors=scale_factors):
    # define variables for readability
    src_lower = scale_factors[src_scale]["lower"]
    src_range = scale_factors[src_scale]["upper"] - src_lower
    dst_lower = scale_factors[dst_scale]["lower"]
    dst_range = scale_factors[dst_scale]["upper"] - dst_lower
    # perform the actual conversion
    return (src_temp - src_lower) / src_range * dst_range + dst_lower

# input temperature
src_temp = 50.
src_scale = "Celsius"

# conversions and output
for dst_scale in scale_factors:
    dst_temp = convert_scale(src_temp, src_scale, dst_scale)
    print("src: {:6.2f} {} - dst: {:6.2f} {} ".format(src_temp, src_scale, 
                                                      dst_temp, dst_scale))

The output is:

$ python3 test.py
src:  50.00 Celsius - dst: 122.00 Fahrenheit 
src:  50.00 Celsius - dst:  16.50 Newton 
src:  50.00 Celsius - dst:  75.00 Delisle 
src:  50.00 Celsius - dst: 323.15 Kelvin 
src:  50.00 Celsius - dst:  33.75 Rømer 
src:  50.00 Celsius - dst: 581.67 Rankine 
src:  50.00 Celsius - dst:  50.00 Celsius 
src:  50.00 Celsius - dst:  40.00 Réaumur 

For reference:


You should consider the hints given in this post, about how to ask the user for input until they give a valid response:

  • Encapsulate the input prompt and input validation in a generic function, that loops until valid user input is available.
  • Such function is separately testable and later code can rely on receiving valid data.
share|improve this answer
    
That's beautiful! – Jaime Jan 14 at 14:16
    
please expand your last two points that are based on Stack Links. a little more explanation would be nice. – Malachi Jan 14 at 14:30
    
I noticed and up voted, thank you. – Malachi Jan 14 at 14:46
    
Insightful observation and very elegant solution. I suggest renaming "lower" and "upper" to "freezing" and "boiling", if those are the reference points you want to pick. – 200_success Jan 15 at 7:30

Use proper docstrings instead of comments

You use

# Declares the variables need for the converter function.
def declare_var():
    ...

# Calculates the temperature conversion based on
# returned variables from the declare_vars function.
def converter(function):
    ...

but these comments are intended to serve as documentation. Time to turn them into docstrings:

def declare_var():
    """Declares the variables needed for the converter function"""
    ...

def converter(function):
    """Calculates the temperature conversion based on
    returned variables from the declare_vars function.
    """
    ...

The advantage being that, when using an interactive session, one can import your module and use the help function to figure out how to use it.

share|improve this answer
    
Or access the docstrings from the command line with the pydoc utility. – mkrieger1 Jan 14 at 15:35

I don’t have time to do a review of every line, but here are some high-level comments:

  • There are a lot of magic numbers in both programs – I assume these are conversion-related numbers? It would be good to have as few of these as possible, pull them into constants, and stick them at the top of the file with some comments explaining what they mean. Right now they’re very hard to understand or change.

  • There aren’t any docstrings on your functions, which makes it hard to know how to use these functions. And the numbers returned by declare_var() are meaningless on their own – if they returned strings telling you what the units were, that would be more useful.

  • I’d break declare_var() down into more functions rather than returning a three-part tuple whose meaning may not be obvious.

  • You say that the new code is “more efficient”, but you seem to be doing 32 sums to populate the temp_equations dictionary – this is an O(n^2) approach to the number of unit conversions, but you only every use one results. This is a very inefficient approach.

    A better approach might be to pick a base unit, like Kelvin, and define two functions for every unit:

    celsius_to_kelvin()
    kelvin_to_celsius()
    

    and you can then do compound conversions like:

    def fahrenheit_to_celsius(t):
        kelvin_to_celsius(fahrenheit_to_kelvin(t))
    
  • Your converter() function should either print a string or return a value, but not both. If I want to use it as part of a bigger program, I’m always going to have the string you’ve printed as part of the output. It would be better if it just returned a numeric value, and the printing was done in the main() function.

  • You don’t do any input validation to check whether I’ve entered a valid choice for temperature type. But if I enter a bad value, it may not be noticed until later in the program. For example:

    $ python temp.py
    Enter a number to declare the initial temperature type?
    [1] Celsius [2] Fahrenheit [3] Kelvin  [4] Rankine
    [5] Delisle [6] Newton     [7] Reaumer [8] Romer
    9
    Enter a number to specify the temperature for conversion?
    [1] Celsius [2] Fahrenheit [3] Kelvin  [4] Rankine
    [5] Delisle [6] Newton     [7] Reaumer [8] Romer
    9
    Enter the temperature degrees
    67
    Traceback (most recent call last):
      File "temp.py", line 120, in <module>
        main()
      File "temp.py", line 116, in main
        converter(declare_var())
      File "temp.py", line 101, in converter
        select_temp = temp_list[initial_temp - 1]
    IndexError: list index out of range
    

    or:

    $ python temp.py
    Enter a number to declare the initial temperature type?
    [1] Celsius [2] Fahrenheit [3] Kelvin  [4] Rankine
    [5] Delisle [6] Newton     [7] Reaumer [8] Romer
    fish
    Traceback (most recent call last):
      File "temp.py", line 120, in <module>
        main()
      File "temp.py", line 116, in main
        converter(declare_var())
      File "temp.py", line 7, in declare_var
        initial_temp = int(eval(input('')))
      File "<string>", line 1, in <module>
    NameError: name 'fish' is not defined
    

    That second error occurs because you’re eval()'ing the string from the user, and I’m not sure why. Just calling int(input('')) would get the same outcome, but calling eval() on user input is quite dangerous because it lets them execute arbitrary Python code midway through your program.

    Here I was able to force your program to exit midway through:

    $ python temp.py
    Enter a number to declare the initial temperature type?
    [1] Celsius [2] Fahrenheit [3] Kelvin  [4] Rankine
    [5] Delisle [6] Newton     [7] Reaumer [8] Romer
    exit(1)
    
    $ echo $?
    1
    

    The key point: don’t trust user input. Make sure they entered something sensible, and don’t use eval() unless you really need it. The old code was actually safer in this regard.

share|improve this answer

It may not be the best way to go about this, but I would consider converting any input temperature into 1 given scale (I would choose Kelvins), and then converting back for any desired scale. Yes, this would increase CPU workload a little, but would really help readability

This would enable creating a class called "Temperature", with a read/write property, one for each scale.. On the "set" method, you convert to Kelvins, on the "get" you convert from kelvins, and you'd end up with something like the following

temp t;
t.Celcius = 100;
float r;
r = t.Rankine;

You can still use all the suggestions that 200_success and others mentioned. You're going to have a bunch of "magic numbers" anyhow... If you want less magic number, it'll cost memory (a pair of magic numbers for each combination of conversions), or cost CPU cycles by doing 2 conversions like I suggest (but only need 1 pair of magic numbers for each scale)

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.