# Applied Programming/Modules and Classes/Python3

## classes.py

```"""This program demonstrates use of the Temperature class."""

from temperature import Temperature

temperature = Temperature(celsius=37)
print(temperature.fahrenheit)

temperature = Temperature(fahrenheit=98.6)
print(temperature.celsius)

temperature = Temperature()
temperature.celsius = 37
print(temperature.fahrenheit)

temperature = Temperature()
temperature.fahrenheit = 98.6
print(temperature.celsius)

temperature = Temperature()
print(temperature.to_celsius(98.6))
print(temperature.to_fahrenheit(37))
```

## temperature.py

```"""Temperature container / converter.

Examples:
from temperature import Temperature

temperature = Temperature(celsius=37)
print(temperature.fahrenheit)

temperature = Temperature(fahrenheit=98.6)
print(temperature.celsius)

temperature = Temperature()
temperature.celsius = 37
print(temperature.fahrenheit)

temperature = Temperature()
temperature.fahrenheit = 98.6
print(temperature.celsius)

temperature = Temperature()
print(temperature.to_celsius(98.6))
print(temperature.to_fahrenheit(37))

"""

class Temperature(object):
"""Supports Fahrenheit and Celius temperatures."""

def __init__(self, fahrenheit=None, celsius=None):
"""Creates a temperature object.

Args:
fahrenheit (float): Optional Fahrenheit temperature.
celius (float):     Optional Celius temperature.

Raises:
ValueError: If both fahrenheit and celsius are initialized.

"""

self._celsius = None
self._fahrenheit = None

if fahrenheit != None and celsius != None:
raise ValueError("Only initialize fahrenheit or celsius, not both.")

if fahrenheit != None:
self.fahrenheit = float(fahrenheit)

if celsius != None:
self.celsius = float(celsius)

@property
def celsius(self):
"""Gets Celsius temperature.

Returns:
float: Celsius temperature

"""
return self._celsius

@celsius.setter
def celsius(self, value):
"""Sets Celsius temperature.

Args:
value (float): Celsius temperature

"""
self._celsius = float(value)
self._fahrenheit = self.to_fahrenheit(self.celsius)

@property
def fahrenheit(self):
"""Gets Fahrenheit temperature.

Returns:
float: Fahrenheit temperature

"""
return self._fahrenheit

@fahrenheit.setter
def fahrenheit(self, value):
"""Sets Fahrenheit temperature.

Args:
value (float): Fahrenheit temperature

"""
self._fahrenheit = float(value)
self._celsius = self.to_celsius(self.fahrenheit)

def to_celsius(self, fahrenheit):
"""Converts Fahrenheit temperature to Celsius.

Args:
fahrenheit (float): Fahrenheit temperature to be converted

Returns:
float: Celsius temperature

"""
return (fahrenheit - 32) * 5 / 9

def to_fahrenheit(self, celsius):
"""Converts Celsius temperature to Fahrenheit.

Args:
celsius (float): Celsius temperature to be converted

Returns:
float: Fahrenheit temperature

"""
return celsius * 9 / 5 + 32

def test(self):
"""Tests all class properties and methods.

Returns:
True: If all tests successful.

Raises:
AssertionError: If a test fails.

"""
temperature = Temperature()
assert temperature.celsius == None
assert temperature.fahrenheit == None

temperature.fahrenheit = 98.6
assert temperature.celsius == 37

temperature.celsius = 37
assert temperature.fahrenheit == 98.6

temperature = Temperature(fahrenheit=98.6)
assert temperature.celsius == 37

temperature = Temperature(celsius=37)
assert temperature.fahrenheit == 98.6

assert temperature.to_celsius(98.6) == 37
assert temperature.to_fahrenheit(37) == 98.6

return True

if __name__ == "__main__":
"""Run tests if module is executed by name."""
temperature = Temperature()
if temperature.test():
print("All tests successful!")
```

## Try It

Copy and paste the code above into one of the following free online development environments or use your own Python3 compiler / interpreter / IDE.