6
\$\begingroup\$

This is my first program to convert temperatures. I have a very basic knowledge of Python and I tried using only what I already knew to make the program. What are some improvements I can make, or how can I re-create this in an easier way?

temp_string = raw_input("What is the Temperature: ")

x = int(temp_string)

print x

temp_type = raw_input("Would you like to convert to Celsius or Fahrenheit?: ")

input_type = str(temp_type)

def convert_fahrenheit(x):
    x = (x - 32) * 0.556
    print x

def convert_celsius(x):
    x = (x * 1.8) + 32
    print x

if input_type == str("c"):
    convert_fahrenheit(x)
elif input_type == str("celsius"):
    convert_fahrenheit(x)
elif input_type == str("Celsius"):
    convert_fahrenheit(x)
elif input_type == str("C"):
    convert_celsius(x)
elif input_type == str("f"):
    convert_celsius(x)
elif input_type == str("fahrenheit"):
    convert_celsius(x)
elif input_type == str("Fahrenheit"):
    convert_celsius(x)
elif input_type == str("F"):
    convert_celsius(x)
else:
    print "You have not entered a valid conversion"   
\$\endgroup\$
10
\$\begingroup\$

Overall I think the most important thing to improve here is code clarity.

You have some code like this:

if input_type == str("c"):

"c" is already a string so doing str("c") is redundant. It's definitely easier and clearer to just write:

if input_type == "c":

There is also a lot of boilerplate to call the required functions with that big if-else block. Instead I would use a dictionary here to do this:

temp_input = int(raw_input("What is the Temperature: "))

input_type = str(raw_input("Would you like to convert to Celsius or Fahrenheit?: "))

conversion_dispatcher = {
    "c": convert_fahrenheit,
    "C": convert_fahrenheit,
    "celsius": convert_fahrenheit,
    "Celsius": convert_fahrenheit,
    "f": convert_celsius,
    "F": convert_celsius,
    "fahrenheit": convert_celsius,
    "Fahrenheit": convert_celsius,
}

try:
    conversion_dispatcher[input_type](temp_input)
except KeyError:
    print("You have not entered a valid conversion")

This way you end up with a lot less boilerplate overall and it's much easier to make changes if you find a problem.

Also I would change the conversion functions to return a value and I would print that value afterwards:

def convert_fahrenheit(x):
    x = (x - 32) * 0.556
    return x

def convert_celsius(x):
    x = (x * 1.8) + 32
    return x

try:
    new_value = conversion_dispatcher[input_type](temp_input)
    print(new_value)
except KeyError:
    print("You have not entered a valid conversion")

The reason for this is because it more clearly separates out the logic from the display code. The makes those conversion functions more reusable as you can now use them in situations where you don't just want to print to the console.

You might also have noticed that I have changed your print syntax to the new print function syntax. This is because the old print statement is going away in newer version of python (python 3.x) and you might as well get used to writing it the other way now. If this causes an error in your version of python you might need to use from __future__ import print_function at the top of your file.

Now that we are done with the Python related stuff it's probably good to improve some other elements of the code. Given the function name isn't completely unambiguous a docstring explaining which way the units conversion is being applied in the conversion functions would help future readers of your code understand what's going on better. This is especially the case because your printout at the beginning suggests different behavior to the code you wrote.

For example:

def convert_to_celsius(x):
    """Converts a temperature in Celsius to Fahrenheit"""
    x = (x * 1.8) + 32
    return x
\$\endgroup\$
  • \$\begingroup\$ Welcome to Code Review! Congratulations, you just passed the First Post review queue with flying colors! :) \$\endgroup\$ – Mathieu Guindon Dec 2 '14 at 0:26
  • \$\begingroup\$ @shuttle87, Tthank you for the suggestions. Everything you wrote makes perfect sense! The dictionary was something I thought about doing but just could not remember how to do it in the moment, so I went with what I did. The only question I have is what exactly the "try" function does? \$\endgroup\$ – Vikash Loomba Dec 2 '14 at 0:28
  • \$\begingroup\$ @shuttle87 I think there is a small error in your documentation. def convert_celsius(x) appears to take a Fahrenheit value and convert to Celsius based on conversion_dispatcher, but you documented the other way around. Maybe I'm reading it wrong, but if not, it would be good to edit your answer :) \$\endgroup\$ – Phrancis Dec 2 '14 at 0:50
  • \$\begingroup\$ @VikashLoomba, when you try to look up a value that's not in a dictionary a KeyError exception occurs, if you don't explicitly catch it then your program will crash and your print "You have not entered a valid conversion" will never get executed. \$\endgroup\$ – shuttle87 Dec 2 '14 at 1:07
  • \$\begingroup\$ Good answer ! I'd also take this chance to remove use return straightaway in the conversion functions as using x as a temp variable does not help in any way. \$\endgroup\$ – Josay Dec 2 '14 at 10:04
1
\$\begingroup\$

To expand upon shuttle87's answer, you could eliminate some of the redundancy by formatting input as it arrives. This approach converts all inputs to be lowercase and contain no leading/ trailing whitespace characters. This allows for inputs with weird casing such as "CelSiUS". It also shortens the code.

temp_input = int(raw_input("What is the Temperature: "))

input_type = str(raw_input("Would you like to convert to Celsius or Fahrenheit?: "))
input_type = input_type.lower().strip()

conversion_dispatcher = {
    "c": convert_fahrenheit,
    "celsius": convert_fahrenheit,
    "f": convert_celsius,
    "fahrenheit": convert_celsius,
}

try:
    conversion_dispatcher[input_type](temp_input)
except KeyError:
    print("You have not entered a valid conversion")
\$\endgroup\$
  • \$\begingroup\$ This is a good suggestion! \$\endgroup\$ – shuttle87 Jun 21 '15 at 1:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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