12
\$\begingroup\$

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 to convert FROM a kelvin value, press k. If you want to convert FROM a gas mark value, press g.")
 if cwhich == "f":
 print (" ")
 fahrenheit = float(input("Input the fahrenheit value: "))
 celcius = (fahrenheit - 32)*(5/9)
 print ("In celcius, this is " , celcius)
 elif cwhich == "k":
 print (" ")
 kelvin = float(input("Input the kelvin value: "))
 celcius = kelvin - 273
 print ("In celcius, this is " , celcius)
 elif cwhich == "g":
 print (" ")
 gasmark = float(input("Input the gas mark value: "))
 celcius = 130 + (gasmark * 10)
 else:
 print (" ")
 print ("Error, you didn't enter any of the specified keys")
elif which == "k":
 print (" ")
 print ("Now choose the measurement you are converting FROM")
 kwhich = input("If you want to convert FROM a fahrenheit value, press f. If you want to convert FROM a celcius value, press c. If you want to convert FROM a gas mark value, press g.")
 if kwhich == "f":
 print (" ")
 fahrenheit = float(input("Input the fahrenheit value: "))
 kelvin = ((5/9) * (fahrenheit - 32) + 273)
 print ("In kelvin, this is " , kelvin)
 elif kwhich == "c":
 print (" ")
 celcius = float(input("Input the celcius value: "))
 kelvin = (celcius + 273)
 print ("In kelvin, this is " , kelvin)
 elif kwhich == "g":
 print (" ")
 gasmark = float(input("Input the gas mark value: "))
 kelvin = ((130 + (gasmark * 10))+ 273)
 print ("In kelvin, this is " , kelvin)
 else:
 print (" ")
 print ("Error, you didn't enter any of the specified keys")
elif which == "g":
 print (" ")
 print ("Now choose the measurement you are converting FROM")
 gwhich = input("If you want to convert FROM a fahrenheit value, press f. If you want to convert FROM a celcius value, press c. If you want to convert FROM a kelvin value, press k.")
 if gwhich == "f":
 print (" ")
 fahrenheit = float(input("Input the fahrenheit value: "))
 gasmark = (fahrenheit / 25) - 10
 print ("In gas mark, this is " , gasmark)
 elif gwhich == "c":
 print (" ")
 celcius = float(input("Input the celcius value: "))
 gasmark = ((celcius / 10) -13)
 print ("In gas mark, this is " , gasmark)
 elif gwhich == "k":
 print (" ")
 kelvin = float(input("Input the kelvin value: "))
 gasmark = (((kelvin - 273) / 10) -13) 
 print ("In gas mark, this is " , gasmark)
 else:
 print (" ")
 print ("Error, you didn't enter any of the specified keys")
else:
 print (" ")
 print ("Error, you didn't enter any of the specified keys")
Toby Speight
87.1k14 gold badges104 silver badges322 bronze badges
asked Mar 29, 2017 at 12:43
\$\endgroup\$
4
  • 7
    \$\begingroup\$ A small bit of pedantry - in physics, "heat" is something different to "temperature"; it's jarring to see the terms used interchangeably like that! \$\endgroup\$ Commented Mar 29, 2017 at 13:26
  • \$\begingroup\$ @TobySpeight fixed it, was annoying me as well :) \$\endgroup\$ Commented Mar 29, 2017 at 14:03
  • 5
    \$\begingroup\$ I think it's not that useful to post work from the absolute beginning of a programming education on Code Review. Either you'll get an answer that's much too advanced or people will adapt their solutions to okayish compromises suited to your level — the first doesn't help much and the second isn't really the purpose of the site. I would bring this to an instructor to learn the basics on a suitable curve. \$\endgroup\$ Commented Mar 29, 2017 at 15:32
  • \$\begingroup\$ Reminds me of codereview.stackexchange.com/questions/157958/… \$\endgroup\$ Commented Mar 29, 2017 at 15:39

4 Answers 4

12
\$\begingroup\$

First of all, Python has an official style-guide, PEP8. It recommends using 4 spaces as indentation, instead of 1, which makes code a lot easier to read.

Second, you should follow the single responsibility principle and define functions that do one thing, instead of having one large bunch of code.

For temperature conversion, it makes sense to first convert to one base unit (Kelvin is the obvious choice for temperature, but you might also go for Rankine if you really want to). This way you don't have to define all conversions from all units to all other units, just to and from the base unit.

Here is a start:

def temperature_C_to_K(temp_C):
 return temp_C + 273.15
def temperature_K_to_C(temp_K):
 return temp_K - 273.15
def temperature_F_to_K(temp_F):
 return 5./9 * (temp_F - 32) + 273.15
def temperature_K_to_F(temp_K):
 return 1.8 * (temp_K - 273.15) + 32
to_K_from = {"c": temperature_C_to_K,
 "f": temperature_F_to_K,
 "k": lambda t: t}
from_K_to = {"c": temperature_K_to_C,
 "f": temperature_K_to_F,
 "k": lambda t: t}
if __name__ == "__main__":
 kelvin = to_K_from["c"]
 fahrenheit = from_K_to["f"]
 temperature = 33
 print(fahrenheit(kelvin(temperature)))

With the additional dictionaries I defined, you can now get the user input for the to and from temperature and use these functions:

from_unit = input("From which unit? ").lower()
temperature = float(input("What temperature in that unit? "))
to_unit = input("Convert to which unit? ").lower()
print(from_K_to[to_unit](to_K_from[from_unit](temperature)))

This has no real input validation so far, so if the user entered a string for the temperature it would raise an exception and it also does not advertise which units are available, but this is left up to you.

You could even define another function for that last, complicated looking, bit:

def convert(temperature, from_unit, to_unit):
 return from_K_to[to_unit](to_K_from[from_unit](temperature))
answered Mar 29, 2017 at 13:53
\$\endgroup\$
0
17
\$\begingroup\$

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))
answered Mar 29, 2017 at 14:05
\$\endgroup\$
2
  • \$\begingroup\$ Nice class. Fortunately all temperature scales I know actually are just a linear transformation of any other scale :) \$\endgroup\$ Commented Mar 29, 2017 at 14:10
  • 1
    \$\begingroup\$ Me too - here's a nice chart with some ideas for more units to add (you'll need a negative slope value for Delisle). \$\endgroup\$ Commented Mar 29, 2017 at 14:20
1
\$\begingroup\$

I would suggest you download PyCharm to write your code. It automatically tells you about the standard python syntax, also, instead of having huge spaces by using 'input()', try using Console.writeline() and Console.readline() {readline or writeline both add newlines at the end}

Also, as Mr. Speight suggested, using classes is the way to go. Cheers!

answered Mar 30, 2017 at 17:39
\$\endgroup\$
2
  • 1
    \$\begingroup\$ This seems more like a comment than a full review/answer... \$\endgroup\$ Commented Mar 30, 2017 at 23:05
  • \$\begingroup\$ Sorry can't comment yet, will change this as soon as I can. \$\endgroup\$ Commented Mar 31, 2017 at 18:19
1
\$\begingroup\$

Thank you everyone, I have re-written my code to now include every temperature unit I can find (if there are more tell me). Here is my new code:

import sys
print ("Welcome to the temperature converter, please enter the unit you wish to convert FROM:")
print ("")
FROM = input("Type 'celcius', 'fahrenheit', 'kelvin', 'gas mark', 'rankine', 'delisle', 'newton', 'reaumur' or 'romer'").lower()
if FROM == "celcius" or FROM == "fahrenheit" or FROM == "kelvin" or FROM == "gas mark" or FROM == "rankine" or FROM == "delisle" or FROM == "newton" or FROM == "reaumur" or FROM == "romer": 
 print ("")
 VALUE = int(input("Now input the temperature in that unit"))
 if FROM == "celcius":
 kelvin = (VALUE + 273)
 elif FROM == "fahrenheit":
 kelvin = ((5/9) * (VALUE - 32) + 273)
 elif FROM == "kelvin":
 kelvin = VALUE
 elif FROM == "gas mark":
 kelvin = ((130 + (VALUE * 10))+ 273)
 elif FROM == "rankine":
 kelvin = (VALUE * (5/9))
 elif FROM == "delisle":
 kelvin = (373 - (VALUE * (2/3)))
 elif FROM == "newton":
 kelvin = (VALUE * (100/33) + 273) 
 elif FROM == "reaumur":
 kelvin = (VALUE * (5/4) + 273)
 elif FROM == "romer":
 kelvin = ((VALUE - 7.5) * (40/21) + 273)
else:
 print("")
 print ("You did not enter any of the specified words")
 sys.exit(1)
print ("")
TO = input("Now input the unit you wish to convert TO: Type 'celcius', 'fahrenheit', 'kelvin', 'gas mark', 'rankine', 'delisle', 'newton', 'reaumur' or 'romer'").lower()
if TO == "celcius" or TO == "fahrenheit" or TO == "kelvin" or TO == "gas mark" or TO == "rankine" or TO == "delisle" or TO == "newton" or TO == "reaumur" or TO == "romer":
 print ("")
 if TO == "celcius":
 END = (kelvin - 273)
 elif TO == "fahrenheit":
 END = (1.8 * (kelvin - 273) + 32)
 elif TO == "kelvin":
 END = kelvin
 elif TO == "gas mark":
 END = (((kelvin - 273) / 10) -13) 
 elif TO == "rankine":
 END = (kelvin * (9/5))
 elif TO == "delisle":
 END = ((373 - kelvin) * (3/2))
 elif TO == "newton":
 END = ((kelvin - 273) * (33/100))
 elif TO == "reaumur":
 END = ((kelvin - 273) * (4/5)) 
 elif TO == "romer":
 END = ((kelvin - 273) * (21/40) + 7.5)
else:
 print ("")
 print ("You did not enter any of the specified words")
 sys.exit(1)
print ("Your" , FROM , "value of" , VALUE , ", is" , END , "in" , TO )
answered Mar 31, 2017 at 13:47
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.