Applied Programming/Testing/Python3
test_temperature.py
edit"""This file tests the Fahrenheit temperature conversion program using PyTest.
Run "pytest" in this folder to automatically run these tests.
Expected output:
8 passed in 0.xx seconds
References:
* https://realpython.com/python-testing/
* http://docs.pytest.org/en/latest/getting-started.html
"""
import pytest
import temperature
def test_get_fahrenheit_returns_valid_input():
input_values = ['100']
def input(prompt=None):
return input_values.pop(0)
temperature.input = input
assert temperature.get_fahrenheit() == 100
def test_get_fahrenheit_ignores_below_absolute_zero():
input_values = ['-500', '0']
def input(prompt=None):
return input_values.pop(0)
temperature.input = input
assert temperature.get_fahrenheit() == 0
def test_get_fahrenheit_ignores_string_value():
input_values = ['error', '0']
def input(prompt=None):
return input_values.pop(0)
temperature.input = input
assert temperature.get_fahrenheit() == 0
def test_get_fahrenheit_empty_string_returns_none():
input_values = ['']
def input(prompt=None):
return input_values.pop(0)
temperature.input = input
assert temperature.get_fahrenheit() == None
def test_fahrenheit_to_celsius_returns_celsius():
assert temperature.fahrenheit_to_celsius(98.6) == 37
assert temperature.fahrenheit_to_celsius(32) == 0
assert temperature.fahrenheit_to_celsius(-40) == -40
assert round(temperature.fahrenheit_to_celsius(-459.67), 2) == -273.15
def test_fahrenheit_to_celsius_raises_value_error_on_non_numeric_value():
with pytest.raises(ValueError):
temperature.fahrenheit_to_celsius(float("X"))
def test_fahrenheit_to_celsius_raises_value_error_below_absolute_zero():
with pytest.raises(ValueError):
temperature.fahrenheit_to_celsius(-459.68)
def test_display_results_displays_results(capsys):
temperature.display_results(32, 0)
captured = capsys.readouterr()
assert captured.out == "32.0° Fahrenheit is 0.0° Celsius\n\n"
def test_display_results_raises_assertion_error_fahrenheit():
with pytest.raises(AssertionError):
temperature.display_results("X", 0)
def test_display_results_raises_assertion_error_celsius():
with pytest.raises(AssertionError):
temperature.display_results(0, "X")
temperature.py
edit"""This program converts a Fahrenheit temperature to Celsius.
Input:
Fahrenheit temperature
Output:
Fahrenheit temperature
Celsius temperature
Example:
Enter Fahrenheit temperature or press <Enter> to quit:
100
100.0° Fahrenheit is 37.8° Celsius
Enter Fahrenheit temperature or press <Enter> to quit:
...
References:
* http://sphinxcontrib-napoleon.readthedocs.io/en/latest/example_google.html
* https://wiki.python.org/moin/UsingAssertionsEffectively
* https://stackoverflow.com/questions/1278705/python-when-i-catch-an-exception-how-do-i-get-the-type-file-and-line-number
* http://www.mathsisfun.com/temperature-conversion.html
"""
import os
import sys
ABSOLUTE_ZERO = -459.67
def get_fahrenheit():
"""Gets Fahrenheit temperature.
Args:
None
Returns:
float: Fahrenheit temperature or None if no temperature entered.
"""
while True:
fahrenheit = input()
try:
print("Enter Fahrenheit temperature or press <Enter> to quit:")
fahrenheit = float(fahrenheit)
if fahrenheit < ABSOLUTE_ZERO:
print("Fahrenheit temperature cannot be below absolute zero.")
print("ValueError: '%f' is invalid.\n" % fahrenheit)
else:
return fahrenheit
except ValueError:
if fahrenheit == '':
return None
else:
print("Fahrenheit temperature must be a floating point value.")
print("ValueError: '%s' is invalid.\n" % fahrenheit)
def fahrenheit_to_celsius(fahrenheit):
"""Converts Fahrenheit temperature to Celsius.
Args:
fahrenheit (float): Fahrenheit temperature to be converted
Returns:
float: Celsius temperature
Raises:
ValueError: If Fahrenheit temperature is not a valid float.
ValueError: If Fahrenheit temperature is below absolute zero.
"""
try:
fahrenheit = float(fahrenheit)
except ValueError:
raise ValueError("fahrenheit must be a float. Received '" + str(fahrenheit) + "'")
except:
raise
if fahrenheit < ABSOLUTE_ZERO:
raise ValueError(
"fahrenheit must not be below absolute zero. Received %f" % fahrenheit)
temperature_difference = 32
temperature_ratio = 5 / 9
celsius = (fahrenheit - temperature_difference) * temperature_ratio
return celsius
def display_results(fahrenheit, celsius):
"""Displays Fahrenheit and Celsius temperatures.
Args:
fahrenheit (float): Fahrenheit temperature
celsuis (float): Celsius temperature
Returns:
None
Raises:
AssertionError: If Fahrenheit temperature is not a valid float.
AssertionError: If Celsius temperature is not a valid float.
"""
assert isinstance(fahrenheit, float) or isinstance(fahrenheit, int), \
"fahrenheit must be a float. Received %s" % type(fahrenheit)
assert isinstance(celsius, float) or isinstance(celsius, int), \
"celsius must be a float. Received %s" % type(celsius)
print("%.1f° Fahrenheit is %.1f° Celsius\n" % (fahrenheit, celsius))
def display_table(fahrenheit):
"""Displays nearest multiples of 10 Fahrenheit and Celsius temperatures.
Args:
fahrenheit (float): Fahrenheit temperature
Returns:
None
Raises:
AssertionError: If Fahrenheit temperature is not a valid float.
"""
assert isinstance(fahrenheit, float) or isinstance(fahrenheit, int), \
"fahrenheit must be a float. Received %s" % type(fahrenheit)
print("F\tC")
start = int(fahrenheit / 10) * 10
for fahrenheit in range(start, start + 11):
print("%.1f" % fahrenheit, end="\t")
print("%.1f" % fahrenheit_to_celsius(fahrenheit))
print()
def main(): # pragma: no cover
"""Runs the main program logic."""
while True:
try:
fahrenheit = get_fahrenheit()
if fahrenheit == None:
break
celsius = fahrenheit_to_celsius(fahrenheit)
display_results(fahrenheit, celsius)
display_table(fahrenheit)
except:
print("Unexpected error.")
print("Error:", sys.exc_info()[1])
print("File: ", sys.exc_info()[2].tb_frame.f_code.co_filename)
print("Line: ", sys.exc_info()[2].tb_lineno)
if __name__ == "__main__": # pragma: no cover
main()
Try It
editCopy and paste the code above into one of the following free online development environments or use your own Python3 compiler / interpreter / IDE.