Sunday, October 11, 2009

Python: Converting from one temperature scale to another is easy, but what about eight?

In just about any class or set of tutorials involving beginning programming, there's usually a problem or set of problems having to do with converting temperatures. Just about everyone has had to write a wee bit of code to convert Fahrenheit to Celsius or vice versa. That's not much of a chore. However, there are eight major temperature scales available (though some are around now only for their historical value), according to wikipedia. What if you had to write a program that let a user convert a temperature from any of these scales to any of these scales?

Do you have any idea how many if statements you'd have to write? On the previously referenced wikipedia page, there are eight tables (one for each temperature scale) so converting from any of scales to any of scales would, in theory, require 8 times 7 or 56 if statements (it wouldn't be 8 times 8 because you wouldn't convert from a scale to itself). That's an awful lot of coding and there's got to be an easier way.

Actually, there's more than one way to make it easier, but this is a tutorial that is, or should be, within the grasp of a relative newbie to Python. I took a stab at it and came up with what I think is a pretty straightforward bit of programming that doesn't require a lot of typing.

Oh. I forgot. There is a specific requirement for the solution to the problem. The code must convert from the source scale temp to central or canonical scale, such as Celsius, and then must convert that value from Celsius (for example) to the target scale temp. Here's what I came up with. I don't claim this is the best possible solution, but I don't think there's anything fundamentally wrong with it, either (I checked with a higher power to be sure). See what you think. Here it is:

t = float(raw_input("Please enter the temp: "))
source = raw_input("Please enter the source temp scale: ")
target = raw_input("Please enter the target temp scale: ")

if t < 1000000.0:
    if source == "k":
        cel = t -273.15
    elif source == "c":
        cel = t
    elif source == "f":
        cel = (t - 32) * 5.0 / 9.0
    elif source == "r":
        cel = (t - 491.67) * 5.0 / 9.0
    elif source == "d":
        cel = 100.0 - t * 2.0 / 3.0
    elif source == "n":
        cel = t * 100.0 / 33.0
    elif source == "re":
        cel = t * 5.0 / 4.0
    elif source == "ro":
        cel = (t - 7.5) * 40.0 / 21.0
    if target == "k":
        answer = cel + 273.15
    elif target == "c":
        answer = cel
    elif target == "f":
        answer = cel * 9.0 / 5.0 + 32.0
    elif target == "r":
        answer = (cel + 273.15) * 9.0 / 5.0
    elif target == "d":
        answer = (100.0 - cel) * 3.0 / 2.0
    elif target == "n":
        answer = cel *  33.0 / 100.0
    elif target == "re":
        answer = cel * 4.0 / 5.0
    elif target == "ro":
        answer = cel * 21.0 / 40.0 + 7.5

print answer
I found all of the formulas for conversions at wikipedia, too. You can copy this code into a text editor and save it as something like, then run it to see how it works for you. Share/Bookmark


  1. How about
    cel = (t - 32) * 5.0 / 9.0
    instead of
    cel = (t - 32) + 5.0 / 9.0

    Personally, I also think that if you want to teach a problem of this scale (to & from 8 temperatures) to a newbie, then you're not primarily giving him/her a python excercise, but a programming excercise. That is a good occasion to teach them not to do it using a large, long-to-type, hard-to debug, etc. list of copy-paste-edited if/then/else, but using lookup in table. The code then collapses to only a few lines (excluding I/O), and adding another temperature scale only adds one single line to the table, while the code remains unchanged (assuming the scale is linear)

  2. A pointless exercise in simple programming - just as pointless most of those temperature scales have become.

  3. Helpful comments are welcome. Snarky comments are still tolerated because I'm such a nice guy. ;-)


Please make comments.