Temperature Converter
Abstract
Converting between temperature scales is one of the cleanest beginner projects: the math is simple, the use case is real, and there is plenty of room to grow the program. In this tutorial you will build a command-line temperature converter that handles Celsius and Fahrenheit at first, then extend it to Kelvin and Rankine, validate user input, and finish with a refactor that uses a dictionary-driven design — the same pattern professional codebases use to keep menus maintainable.
By the end you will understand:
- The four major temperature scales and how they relate.
- Why
floatfloatis preferred overintintfor measurements. - How to organize a script with small, single-purpose functions.
- How to validate input so the program never crashes.
- How a dispatch table replaces growing
ifif/elifelifchains.
The Math
| From → To | Formula |
|---|---|
| Celsius → Fahrenheit | F = C × 9/5 + 32F = C × 9/5 + 32 |
| Fahrenheit → Celsius | C = (F − 32) × 5/9C = (F − 32) × 5/9 |
| Celsius → Kelvin | K = C + 273.15K = C + 273.15 |
| Kelvin → Celsius | C = K − 273.15C = K − 273.15 |
| Fahrenheit → Kelvin | K = (F − 32) × 5/9 + 273.15K = (F − 32) × 5/9 + 273.15 |
| Kelvin → Rankine | R = K × 9/5R = K × 9/5 |
| Rankine → Fahrenheit | F = R − 459.67F = R − 459.67 |
Reference points:
- Water freezes at 0 °C / 32 °F / 273.15 K.
- Water boils at 100 °C / 212 °F / 373.15 K.
- Absolute zero is 0 K / −273.15 °C / −459.67 °F / 0 °R.
Prerequisites
- Python 3.6 or above.
- A text editor or IDE (VS Code recommended).
- Comfort running a Python file from the terminal (see Hello World).
- Basic understanding of functions (see Simple Calculator if you need a refresher).
Getting Started
Create the project
- Create a folder named
tempconvertertempconverter. - Inside, create
tempconverter.pytempconverter.py. - Open the folder in your code editor.
Write the code
Add this to tempconverter.pytempconverter.py:
Temperature Converter
Source# Temperature Converter
# Function to convert Celsius to Fahrenheit
def celsius_to_fahrenheit(celsius):
fahrenheit = (celsius * 9/5) + 32
return fahrenheit
# Function to convert Fahrenheit to Celsius
def fahrenheit_to_celsius(fahrenheit):
celsius = (fahrenheit - 32) * 5/9
return celsius
# Main function
def main():
print("Temperature Converter")
print("1. Celsius to Fahrenheit")
print("2. Fahrenheit to Celsius")
choice = int(input("Enter your choice: "))
if choice == 1:
celsius = float(input("Enter temperature in Celsius: "))
fahrenheit = celsius_to_fahrenheit(celsius)
print("Temperature in Fahrenheit: ", fahrenheit)
elif choice == 2:
fahrenheit = float(input("Enter temperature in Fahrenheit: "))
celsius = fahrenheit_to_celsius(fahrenheit)
print("Temperature in Celsius: ", celsius)
else:
print("Invalid choice!")
# Call main function
main()
# Temperature Converter
# Function to convert Celsius to Fahrenheit
def celsius_to_fahrenheit(celsius):
fahrenheit = (celsius * 9/5) + 32
return fahrenheit
# Function to convert Fahrenheit to Celsius
def fahrenheit_to_celsius(fahrenheit):
celsius = (fahrenheit - 32) * 5/9
return celsius
# Main function
def main():
print("Temperature Converter")
print("1. Celsius to Fahrenheit")
print("2. Fahrenheit to Celsius")
choice = int(input("Enter your choice: "))
if choice == 1:
celsius = float(input("Enter temperature in Celsius: "))
fahrenheit = celsius_to_fahrenheit(celsius)
print("Temperature in Fahrenheit: ", fahrenheit)
elif choice == 2:
fahrenheit = float(input("Enter temperature in Fahrenheit: "))
celsius = fahrenheit_to_celsius(fahrenheit)
print("Temperature in Celsius: ", celsius)
else:
print("Invalid choice!")
# Call main function
main()
Save the file, open a terminal, and run:
C:\Users\username\Documents\tempconverter> python tempconverter.py
Temperature Converter
1. Celsius to Fahrenheit
2. Fahrenheit to Celsius
Enter your choice: 1
Enter temperature in Celsius: 35
Temperature in Fahrenheit: 95.0C:\Users\username\Documents\tempconverter> python tempconverter.py
Temperature Converter
1. Celsius to Fahrenheit
2. Fahrenheit to Celsius
Enter your choice: 1
Enter temperature in Celsius: 35
Temperature in Fahrenheit: 95.0Step-by-Step Explanation
1. Define each conversion as a function
def celsius_to_fahrenheit(c):
return c * 9/5 + 32
def fahrenheit_to_celsius(f):
return (f - 32) * 5/9def celsius_to_fahrenheit(c):
return c * 9/5 + 32
def fahrenheit_to_celsius(f):
return (f - 32) * 5/9Each function does one thing. The body is the formula directly. Naming functions after what they do makes the program readable without comments.
2. The main()main() menu
def main():
print("Temperature Converter")
print("1. Celsius to Fahrenheit")
print("2. Fahrenheit to Celsius")
choice = input("Enter your choice: ")
if choice == "1":
c = float(input("Enter temperature in Celsius: "))
print("Temperature in Fahrenheit:", celsius_to_fahrenheit(c))
elif choice == "2":
f = float(input("Enter temperature in Fahrenheit: "))
print("Temperature in Celsius:", fahrenheit_to_celsius(f))
else:
print("Invalid choice.")def main():
print("Temperature Converter")
print("1. Celsius to Fahrenheit")
print("2. Fahrenheit to Celsius")
choice = input("Enter your choice: ")
if choice == "1":
c = float(input("Enter temperature in Celsius: "))
print("Temperature in Fahrenheit:", celsius_to_fahrenheit(c))
elif choice == "2":
f = float(input("Enter temperature in Fahrenheit: "))
print("Temperature in Celsius:", fahrenheit_to_celsius(f))
else:
print("Invalid choice.")input()input()always returns a string.float()float()turns that string into a number with a decimal — important because temperatures are rarely whole numbers.
3. Run the program
main()main()Calling main()main() at the bottom of the file kicks the program off when you run python tempconverter.pypython tempconverter.py.
Why floatfloat, Not intint?
Try replacing float(...)float(...) with int(...)int(...):
int(input("Enter Celsius: ")) # user enters 36.6 → ValueErrorint(input("Enter Celsius: ")) # user enters 36.6 → ValueErrorint()int() refuses fractional input. Real temperatures (body temperature 36.6 °C, room temperature 22.5 °C) are not whole numbers. float()float() accepts both 3636 and 36.636.6.
Robust Input
The naive version crashes when the user types "hot""hot" instead of a number. Add a helper:
def ask_number(prompt):
while True:
raw = input(prompt)
try:
return float(raw)
except ValueError:
print(f"'{raw}' is not a valid number. Try again.")def ask_number(prompt):
while True:
raw = input(prompt)
try:
return float(raw)
except ValueError:
print(f"'{raw}' is not a valid number. Try again.")Use it everywhere you would have written float(input(...))float(input(...)):
c = ask_number("Enter temperature in Celsius: ")c = ask_number("Enter temperature in Celsius: ")You can also reject obvious physics nonsense — no temperature below absolute zero:
def celsius_to_kelvin(c):
if c < -273.15:
raise ValueError("Temperature below absolute zero is impossible.")
return c + 273.15def celsius_to_kelvin(c):
if c < -273.15:
raise ValueError("Temperature below absolute zero is impossible.")
return c + 273.15Refactor: Dispatch Table
When you support seven or eight conversions, a long ifif/elifelif chain becomes painful. Replace it with a dictionary that maps menu labels to conversion functions:
def c_to_f(c): return c * 9/5 + 32
def f_to_c(f): return (f - 32) * 5/9
def c_to_k(c): return c + 273.15
def k_to_c(k): return k - 273.15
def f_to_k(f): return c_to_k(f_to_c(f))
def k_to_f(k): return c_to_f(k_to_c(k))
CONVERSIONS = {
"1": ("Celsius → Fahrenheit", c_to_f, "°C", "°F"),
"2": ("Fahrenheit → Celsius", f_to_c, "°F", "°C"),
"3": ("Celsius → Kelvin", c_to_k, "°C", "K"),
"4": ("Kelvin → Celsius", k_to_c, "K", "°C"),
"5": ("Fahrenheit → Kelvin", f_to_k, "°F", "K"),
"6": ("Kelvin → Fahrenheit", k_to_f, "K", "°F"),
}
def main():
while True:
print("\nTemperature Converter")
for key, (label, _, _, _) in CONVERSIONS.items():
print(f" {key}. {label}")
print(" Q. Quit")
choice = input("Choice: ").strip()
if choice.lower() == "q":
break
if choice not in CONVERSIONS:
print("Invalid choice.")
continue
label, func, in_unit, out_unit = CONVERSIONS[choice]
value = float(input(f"Enter temperature ({in_unit}): "))
print(f"{value} {in_unit} = {func(value):.2f} {out_unit}")
main()def c_to_f(c): return c * 9/5 + 32
def f_to_c(f): return (f - 32) * 5/9
def c_to_k(c): return c + 273.15
def k_to_c(k): return k - 273.15
def f_to_k(f): return c_to_k(f_to_c(f))
def k_to_f(k): return c_to_f(k_to_c(k))
CONVERSIONS = {
"1": ("Celsius → Fahrenheit", c_to_f, "°C", "°F"),
"2": ("Fahrenheit → Celsius", f_to_c, "°F", "°C"),
"3": ("Celsius → Kelvin", c_to_k, "°C", "K"),
"4": ("Kelvin → Celsius", k_to_c, "K", "°C"),
"5": ("Fahrenheit → Kelvin", f_to_k, "°F", "K"),
"6": ("Kelvin → Fahrenheit", k_to_f, "K", "°F"),
}
def main():
while True:
print("\nTemperature Converter")
for key, (label, _, _, _) in CONVERSIONS.items():
print(f" {key}. {label}")
print(" Q. Quit")
choice = input("Choice: ").strip()
if choice.lower() == "q":
break
if choice not in CONVERSIONS:
print("Invalid choice.")
continue
label, func, in_unit, out_unit = CONVERSIONS[choice]
value = float(input(f"Enter temperature ({in_unit}): "))
print(f"{value} {in_unit} = {func(value):.2f} {out_unit}")
main()Notice how easy it is to add a new conversion — one entry in the dictionary, one helper function. No menu logic has to change.
Output Formatting
print(c_to_f(35))print(c_to_f(35)) prints 95.095.0. For two decimal places:
print(f"{c_to_f(35):.2f}") # 95.00print(f"{c_to_f(35):.2f}") # 95.00The :.2f:.2f inside the f-string means “format as a float with two digits after the decimal point.”
Common Mistakes
| Problem | Cause | Fix |
|---|---|---|
TypeError: unsupported operand type(s) for *: 'str' and 'float'TypeError: unsupported operand type(s) for *: 'str' and 'float' | Forgot to convert input()input() with float()float() | Wrap input in float(input(...))float(input(...)) |
Wrong result like 0 + 32 = 320 + 32 = 32 for 0 °C → F (looks right but for 100 °C you get 132) | Used c + 9/5 + 32c + 9/5 + 32 instead of c * 9/5 + 32c * 9/5 + 32 | Watch operator precedence; parenthesize when unsure |
ValueError: could not convert string to float: ''ValueError: could not convert string to float: '' | User pressed Enter without typing | Validate rawraw before converting |
| Off-by-273 for Kelvin | Used 273 instead of 273.15 | Use the more accurate constant |
Variations to Try
1. Convert multiple values at once
Accept a comma-separated list:
raw = input("Celsius values, comma separated: ")
for piece in raw.split(","):
c = float(piece.strip())
print(f"{c} °C = {c_to_f(c):.2f} °F")raw = input("Celsius values, comma separated: ")
for piece in raw.split(","):
c = float(piece.strip())
print(f"{c} °C = {c_to_f(c):.2f} °F")2. CLI flags with argparse
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("value", type=float)
parser.add_argument("--from", dest="src", choices=["c","f","k"], required=True)
parser.add_argument("--to", dest="dst", choices=["c","f","k"], required=True)
args = parser.parse_args()
# dispatch by (args.src, args.dst)import argparse
parser = argparse.ArgumentParser()
parser.add_argument("value", type=float)
parser.add_argument("--from", dest="src", choices=["c","f","k"], required=True)
parser.add_argument("--to", dest="dst", choices=["c","f","k"], required=True)
args = parser.parse_args()
# dispatch by (args.src, args.dst)Now python tempconverter.py 100 --from c --to fpython tempconverter.py 100 --from c --to f returns 212.0212.0.
3. GUI version
Use Tkinter:
import tkinter as tk
root = tk.Tk()
entry = tk.Entry(root); entry.pack()
result = tk.Label(root); result.pack()
def convert():
c = float(entry.get())
result.config(text=f"{c_to_f(c):.2f} °F")
tk.Button(root, text="Convert", command=convert).pack()
root.mainloop()import tkinter as tk
root = tk.Tk()
entry = tk.Entry(root); entry.pack()
result = tk.Label(root); result.pack()
def convert():
c = float(entry.get())
result.config(text=f"{c_to_f(c):.2f} °F")
tk.Button(root, text="Convert", command=convert).pack()
root.mainloop()4. Weather-API integration
Use requestsrequests to fetch the current temperature for a city from an API like OpenWeatherMap, then convert and display.
5. Unit tests
import unittest
class TestConv(unittest.TestCase):
def test_freezing(self):
self.assertEqual(c_to_f(0), 32)
def test_boiling(self):
self.assertEqual(c_to_f(100), 212)
unittest.main()import unittest
class TestConv(unittest.TestCase):
def test_freezing(self):
self.assertEqual(c_to_f(0), 32)
def test_boiling(self):
self.assertEqual(c_to_f(100), 212)
unittest.main()Run with python test_conv.pypython test_conv.py.
Real-World Applications
- Weather and forecasting tools.
- Cooking apps that swap between °C and °F for international recipes.
- Industrial monitoring dashboards that use Kelvin internally and display in °C.
- Scientific instruments that report in Kelvin or Rankine.
- Education — building physical intuition for the scales.
Best Practices Demonstrated
- Single-purpose functions — each conversion has its own function with a clear name.
- Input validation at the boundary — convert and verify once, trust the value everywhere else.
- Dispatch table over
ifif/elifelifladders — easier to maintain. - Format output explicitly —
:.2f:.2fproduces predictable, readable numbers.
Next Steps
- Add Rankine support so the converter handles all four standard scales.
- Build a GUI with Tkinter for a nicer experience.
- Add a “smart” mode that auto-detects the unit by suffix (
100C100C,212F212F,300K300K). - Publish it as a PyPI package called
tempconvtempconv. - Pair it with a weather API for live-temperature conversion of any city.
Conclusion
Temperature conversion is the perfect playground for practicing functions, math operators, user input, validation, and code refactoring. You started with a 10-line script and finished with a dispatch-table design that scales cleanly. The same dictionary-of-functions pattern shows up in unit converters, command-line tools, and event handlers throughout real-world Python projects. The full source is on GitHub. Find more beginner projects on Python Central Hub — and if you have questions, reach out at ravikishan.me/contact.
If this helped you, consider buying me a coffee ☕
Buy me a coffeeWas this page helpful?
Let us know how we did
