HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonModerate

Temperature conversion code

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
codeconversiontemperature

Problem

I am currently creating a program that can convert different units of measurement for temperature. It includes conversions for Celsius, Fahrenheit, kelvin and gas mark. Can someone tell me how I could make my code simpler so I can add more units of temperature measurement (e.g. Rankine). Also, is there any way to stop having to use big spaces in my input quotes to get them line by line?

```
print ("Welcome to the temperature converter, please choose which measurement you want to convert TO")
print (" ")
which = input("If you want to convert TO a fahrenheit value, press f. If you want to convert TO a celcius value, press c. If you want to convert TO a kelvin value, press k. If you want to convert TO a gas mark value, press g.")
if which == "f":
print (" ")
print ("Now choose the measurement you are converting FROM")
fwhich = input("If you want to convert FROM a celcius value, press c. If you want to convert FROM a kelvin value press k. If you want to convert FROM a gas mark value, press g.")
if fwhich == "c":
print (" ")
celcius = float(input("Input the celcius value: "))
fahrenheit = (celcius*(9/5)+32)
print ("In fahrenheit, this is " , fahrenheit)
elif fwhich == "k":
print (" ")
kelvin = float(input("Input the kelvin value: "))
fahrenheit = (1.8 * (kelvin - 273) + 32)
print ("In fahrenheit, this is " , fahrenheit)
elif fwhich == "g":
print (" ")
gasmark = float(input("Input the gas mark value: "))
fahrenheit = 250 + (gasmark * 25)
print ("In fahrenheit, this is " , fahrenheit)
else:
print (" ")
print ("Error, you didn't enter any of the specified keys")
elif which == "c":
print (" ")
print ("Now choose the measurement you are converting FROM")
cwhich = input("If you want to convert FROM a fahrenheit value, press f. If you want

Solution

The biggest problem with your code is the amount of repetition. You can reduce this by defining a Unit class:

class Unit(object):
    "A temperature unit that can be linearly converted to or from Kelvins."
    def __init__(self, name, slope, intercept):
        self.name = name
        self.slope = slope
        self.intercept = intercept

    def to_kelvins(self, t):
        return self.intercept + t / self.slope

    def from_kelvins(self, k):
        return (k - self.intercept) * self.slope


We can now create a dictionary of units, keyed by the single letter that the user will select them by:

all_units = {
    "k": Unit("kelvins", 1.0, 0.0),
    "c": Unit("Celsius", 1.0, 273.15),
    "r": Unit("rankin", 9.0/5, 0.0),
    "f": Unit("Fahrenheit", 9.0/5, 255.37),
    "g": Unit("Gas Mark", 9.0/125, 255.37+250*5.0/9),
}


Let's make a quick test of the above:

if __name__ == '__main__':
    for i in [0, 255.37, 273.15, 373.15, 473.15]:
        for unit in all_units.values():
            print("%.2f K is %.2f %s" % (i, unit.from_kelvins(i), unit.name))
        print()


This produces the output we expect:

0.00 K is 0.00 kelvins
0.00 K is -273.15 Celsius
0.00 K is 0.00 rankin
0.00 K is -28.39 Gas Mark
0.00 K is -459.67 Fahrenheit

255.37 K is 255.37 kelvins
255.37 K is -17.78 Celsius
255.37 K is 459.67 rankin
255.37 K is -10.00 Gas Mark
255.37 K is 0.00 Fahrenheit

273.15 K is 273.15 kelvins
273.15 K is 0.00 Celsius
273.15 K is 491.67 rankin
273.15 K is -8.72 Gas Mark
273.15 K is 32.00 Fahrenheit

373.15 K is 373.15 kelvins
373.15 K is 100.00 Celsius
373.15 K is 671.67 rankin
373.15 K is -1.52 Gas Mark
373.15 K is 212.00 Fahrenheit

473.15 K is 473.15 kelvins
473.15 K is 200.00 Celsius
473.15 K is 851.67 rankin
473.15 K is 5.68 Gas Mark
473.15 K is 392.00 Fahrenheit


Now we can work on the input and output. This needs to choose an input unit and value. Given that, we can compute the (Kelvin) temperature in question using input_unit.to_kelvin(). When the user chooses an output unit, we can use output_unit.from_kelvin() to calculate the result:

if __name__ == '__main__':
     # N.B. all error-checking is left as an exercise
    input_unit = all_units[input("From which unit? ")]
    input_value = float(input("What temperature, in %s? " % input_unit.name))
    kelvin_temp = input_unit.to_kelvins(input_value)
    output_unit = all_units[input("To which unit? ")]
    output_value = output_unit.from_kelvins(kelvin_temp)
    print("%.2f %s is %.2f %s" % (input_value, input_unit.name, output_value, output_unit.name))

Code Snippets

class Unit(object):
    "A temperature unit that can be linearly converted to or from Kelvins."
    def __init__(self, name, slope, intercept):
        self.name = name
        self.slope = slope
        self.intercept = intercept

    def to_kelvins(self, t):
        return self.intercept + t / self.slope

    def from_kelvins(self, k):
        return (k - self.intercept) * self.slope
all_units = {
    "k": Unit("kelvins", 1.0, 0.0),
    "c": Unit("Celsius", 1.0, 273.15),
    "r": Unit("rankin", 9.0/5, 0.0),
    "f": Unit("Fahrenheit", 9.0/5, 255.37),
    "g": Unit("Gas Mark", 9.0/125, 255.37+250*5.0/9),
}
if __name__ == '__main__':
    for i in [0, 255.37, 273.15, 373.15, 473.15]:
        for unit in all_units.values():
            print("%.2f K is %.2f %s" % (i, unit.from_kelvins(i), unit.name))
        print()
if __name__ == '__main__':
     # N.B. all error-checking is left as an exercise
    input_unit = all_units[input("From which unit? ")]
    input_value = float(input("What temperature, in %s? " % input_unit.name))
    kelvin_temp = input_unit.to_kelvins(input_value)
    output_unit = all_units[input("To which unit? ")]
    output_value = output_unit.from_kelvins(kelvin_temp)
    print("%.2f %s is %.2f %s" % (input_value, input_unit.name, output_value, output_unit.name))

Context

StackExchange Code Review Q#159259, answer score: 17

Revisions (0)

No revisions yet.