Temperature conversion program with a lot of repetition My son (9) is learning Python and wrote this temperature conversion program. He can see that there is a lot of repetition in it and would like to get feedback on ways to make it shorter.

def get_temperature():
    print "What is your temperature?"
    while True:
        temperature = raw_input()
        try:
            return float(temperature)
        except ValueError:
            print "Not a valid temperature. Could you please do this again?"    

print "This program tells you the different temperatures."
temperature = get_temperature()

print "This is what it would be if it was Fahrenheit:"
Celsius = (temperature - 32)/1.8
print Celsius, "degrees Celsius"
Kelvin = Celsius + 273.15
print Kelvin, "Kelvin"

print "This is what it would be if it was Celsius."    
Fahrenheit = temperature * 9 / 5 + 32
print Fahrenheit, "degrees Fahrenheit"
Kelvin = temperature + 273.15
print Kelvin, "Kelvin"

print "This is what it would be if it was Kelvin"    
Celsius = temperature - 273.15
print Celsius, "degrees Celsius"
Fahrenheit = Celsius * 9 / 5 + 32
print Fahrenheit, "degrees Fahrenheit"
The easiest way to remove repetition here is with nested for loops, going through all the combinations of units. In the code below I also use the fact that you can convert between any two scales in the following way:


subtract something then divide by something to get back to Celsius, then
multiply by something then add something to get to the desired unit


The "something"s can be stored in a single tuple (list of values), making the conversions simpler.

scales = ('Celsius', 'degrees ', 1, 0), ('Farenheit', 'degrees ', 1.8, 32), ('Kelvin', '', 1, 273.15)
value = get_temperature()
for from_unit, _, slope1, intercept1 in scales:
    print "This is what it would be if it was", from_unit
    celsius = (value - intercept1) / slope1
    for to_unit, prefix, slope2, intercept2 in scales:
        if to_unit != from_unit:
            print '{0} {1}{2}'.format(intercept2 + slope2 * celsius, degrees, to_unit)


Dividing code into functions is of course a good idea in general, but not that useful in this case. If he's interested in performing other operations on temperatures it might be interesting to go a step further and make a simple class like the following.

scales = {
            'Celsius': ('degrees ', 1, 0),
            'Farenheit': ('degrees ', 1.8, 32),
            'Kelvin': ('', 1, 273.15)
        }
class Temperature:    
    def __init__(self, value, unit = 'Celsius'):
        self.original_unit = unit
        _, slope, intercept = scales[unit]
        self.celsius = (value - intercept) / slope
    def to_unit(self, unit):
        _, slope, intercept = scales[unit]
        return slope * self.celsius + intercept
    def print_hypothetical(self):
        print "This is what it would be if it was", self.original_unit
        for unit, (prefix, _, _) in scales.iteritems():
            if unit != self.original_unit:
                print "{0} {1}{2}".format(self.to_unit(unit), prefix, unit)
value = get_temperature()
for unit in scales:
    m = Temperature(value, unit)
    m.print_hypothetical()