Advanced Python
In-Class Exercises, Session 6
Notes if you are using Jupyter Notebook: to call exit() from a notebook, please use sys.exit() (requires import sys). If a strange error occurs, it may be because Jupyter retains variables from all executed cells. To reset the notebook, click 'Restart Kernel' (the circular arrow) -- this will not undo any changes made. |
|
CLASSES - INSTANCES AND METHODS |
|
Ex. 6.1 | Define a class. |
Use the class statement with name MyClass (or you may substitute a name of your own choice). To fill the otherwise empty block, use the pass statement. Initialize an instance of the class and print its type to show that it is an instance of the class. |
|
Expected Output:
<class '__main__.MyClass'> |
|
Ex. 6.2 | Create an 'instance' method. |
Add to the class Hola below a new method, saludar(), that prints "bienvenidos a todos" (or whatever greeting you'd prefer) when it is called. |
|
class Hola:
""" una clase que is amigable """
# your code here
yo = Hola()
yo.saludar() # should print the greeting
|
|
Expected Output:
bienvenidos a todos |
|
Ex. 6.3 | Add argument and return value to method. |
Add the method doubleit() below, that doubles the value passed to it. |
|
Numbers:
""" various number methods """
num = Numbers()
val = num.doubleit(5)
print(val) # 10
val2 = num.doubleit(100)
print(val2) # 200
|
|
Expected Output:
10 200 |
|
LAB 1 |
|
Ex. 6.4 | Create a class Time that has a method get_time() that returns the current time. Call as shown. |
(A string showing the current time can be obtained from the time module using time.ctime().) |
|
import time
# your code here
obj = Time()
print(obj.get_time()) # should show the current time
|
|
Expected Output:
Sat Oct 17 18:41:34 2020 (as your specific date and time) |
|
Ex. 6.5 | Create a class Random that has a method get_rand(val) that returns a random number from 1 to the specified value. Call as shown. |
(A random number can be generated with random.randint(x, y) where x and y are the minimum and maximum values.) |
|
import random
# your code here
obj = Random()
val = obj.get_rand(5) # random number from 1-5
print(val)
val2 = obj.get_rand(18) # random number from 1-18
print(val2)
|
|
Expected Output:
4 3 |
|
Ex. 6.6 | Create a class Math with method add() that takes two integer arguments and returns the values summed. |
# your code here
obj = Math()
mysum = obj.add(5, 10) # 15
print(mysum)
mysum2 = obj.add(100, 150) # 250
print(mysum2)
|
|
Expected Output:
15 250 |
|
CLASSES - CONSTRUCTOR, CLASS ATTRIBUTES AND METHODS |
|
Ex. 6.7 | Demonstration: note the unique identifier of self and an instance from a class. |
At the bottom of the code below, print obj, then call obj.something(), noting that this method prints self. Compare the hex codes that identify the instance. Use a print() statement to create a blank line. Next, print obj2 and call obj2.something(), and note the output, particularly the hex codes. |
|
class Do:
def something(self):
print(self)
obj = Do()
obj2 = Do()
# your code here
|
|
Expected Output:
<__main__.Do object at 0x10d648350> <__main__.Do object at 0x10d648350> <__main__.Do object at 0x10d648390> <__main__.Do object at 0x10d648390> |
|
Ex. 6.8 | Create an __init__() method. |
Add a method to the below class, __init__(self) that inside the function announces and prints the argument self, i.e. print(f'self: {self}'). Construct 2 new instances, and then print each instance. Put a blank line between each instance. |
|
class Be:
""" this class is something! """
obj1 = Be()
print(f'object: {obj1}')
print()
obj2 = Be()
print(f'object: {obj2}')
|
|
Expected Output:
self: <__main__.Be object at 0x10d648250> object: <__main__.Be object at 0x10d648250> object: <__main__.Be object at 0x10d648a50> self: <__main__.Be object at 0x10d648a50> |
|
(Note that the above 0x hex codes will not be the same as mine, but the values in each pair should match.) |
|
Ex. 6.9 | Set an instance attribute in __init__(). |
Create a method __init__(self, num) that sets numin self as a .value attribute. At bottom, print obj.value to see the value. |
|
class Live:
""" a class that just wants to live """
# your __init__() code here
obj = Live(5)
# print obj.value here
|
|
Expected Output:
5 |
|
Ex. 6.10 | Create a "getter" method. |
Create a method get_value() that returns the .value attribute from the instance. |
|
class Say:
def __init__(self, val):
self.thisval = val
# your code here
obj = Say(100)
vl = obj.get_value()
print(vl) # 100
|
|
Expected Output:
100 |
|
Ex. 6.11 | Demonstrate class attributes. |
In the class below, set a class variable cvar to value 1000. Print the value of cvar in three places: 1) instance a (a.cvar); 2) instance b (b.cvar); 3) the class itself (Something.cvar) Also print the .attr attribute from each of the two instances. |
|
class Something:
# your class variable here
def __init__(self, xx):
self.attr = xx
a = Something('hi')
b = Something('there')
# print cvar in 3 places here
# print .attr from each of the two instances here
|
|
Expected Output:
1000 1000 1000 hi there |
|
Ex. 6.12 | Create a class method. |
Add a class method classincrement(cls) that uses its cls argument to increment the cattr class variable (cattr will be found to be an attribute of cls. Call classincrement() through the instance obj as well as through the class MyClass. The values printed below should both be 1. Before this can work as shown, however, you must decorate classincrement() with @classmethod. |
|
class MyClass:
cattr = 0
# your classincrement(cls) method here
obj = MyClass()
obj.classincrement()
print(obj.cattr) # should be 1
print(MyClass.cattr) # should be 1
|
|
Expected Output:
1 1 |
|
Ex. 6.13 | Create a static method. |
To the below class add the static method ftoc(temp) which converts a temperature in Fahrenheit to Celsius. The formula is (temp - 32) * 5 / 9 To be a static method, the method must not take self as an argument, and must be decorated with @staticmethod. |
|
class Forecast:
def __init__(self, forecast, high=0, low=0):
self.text = forecast
self.hightemp = high
self.lowtemp = low
# your ftoc(temp) static methood here
t = Forecast('Light rain', high=62, low=48)
print(t.ftoc(32)) # 0.0
print(t.ftoc(212)) # 100.0
|
|
Expected Output:
0.0 100.0 |
|
LAB 2 |
|
Ex. 6.14 | Create a class Name that allows you to store a person's first and last name: |
n = Name('David', 'Blaikie')
print(n.first) # 'David'
print(n.last) # 'Blaikie'
|
|
The class only needs to define an __init__() method, which besides 'self' must accept the 2 additional arguments (first name and last name). In __init__(), store the two values in attributes .first and .last. Use the above code as a test to see that the attributes have been successfully stored. |
|
Ex. 6.15 | Continuing the Name class, add a method .get_name() that returns the full name as 'first name last name'. |
Finally, add another method .get_rname() that returns the name in reverse order (last, first). |
|
n = Name('David', 'Blaikie')
print(n.get_name()) # David Blaikie
print(n.get_rname()) # Blaikie, David
|
|
Ex. 6.16 | Continuing the Name class, set a class variable 'label' that refers to a string 'Name: ' -- this will serve as the label to be printed along with a person's name |
n = Name('David', 'Blaikie')
print(n.get_name()) # Name: David Blaikie
print(n.get_rname()) # Name: Blaikie, David
n2 = Name('Marie', 'Sanchez')
print(n2.get_name()) # Name: Marie Sanchez
print(n2.get_rname()) # Name: Sanchez, Marie
|
|
MODULES |
|
Ex. 6.17 | Create a module that holds a function. |
Create a new file, temputils.py, that has the below functions def ctof() and def ftoc(). Place this file in the same folder as this exercise file (inclass_exercises if this is a .py file; notebooks_inclass_challege if this is a Jupyter notebook). |
|
Contents of temputils.py:
def ctof(temp): """ function to convert celsius to fahrenheit """ if not isinstance(temp, (int,float)): raise TypeError('must be an int or float') return (temp * 9 / 5) + 32 def ftoc(temp): """ function to convert fahrenheit to celsius """ if not isinstance(temp, (int,float)): raise TypeError('must be an int or float') return (temp - 32) * 5 / 9 |
|
import temputils as tu
val = tu.ftoc(212)
print(val) # 100.0
val2 = tu.ctof(0)
print(val2) # 32.0
|
|
Expected Output:
100.0 32.0 |
|
Ex. 6.18 | Set PYTHONPATH environment variable to make utils.py importable from any directory. |
Move (don't copy) temputils.py to your Desktop. This can be done through the PyCharm file view or your Finder or Windows Explorer windows. If you are using Jupyter Notebook, for this exercise you must first restart the kernel. Click the circular arrow in the menu bar, or Kernel -> Restart (no outputs will be cleared from your notebook). Run the below exercise and note the ModuleNotFoundError, which indicates that the module can no longer be located. This is because it is not in the same directory as this exercise file. |
|
import temputils as tu
val = tu.ftoc(212)
print(val) # 100.0
val2 = tu.ctof(0)
print(val2) # 32.0
|
|
Now follow the directions under the slide Setting the PYTHONPATH Environment Variable to set or add your Desktop path there: The most common locations for Desktop are: Windows: C:\Users\username\Desktop Mac: /Users/username/Desktop Where username is the name of your home directory. Finally, run the code again and see that the module was found in its new location. |
|
Expected Output:
100.0 32.0 |
|
Ex. 6.19 | Create a module that holds a class. |
Add the below class to temputils.py. |
|
class TempConvert: def __init__(self, temp, scale='F'): self.itemp = temp self.scale = scale def as_fahrenheit(self): """ function to convert celsius to fahrenheit """ if self.scale == 'F': return self.itemp return (self.itemp * 9 / 5) + 32 def as_celsius(self): """ function to convert fahrenheit to celsius """ if self.scale == 'C': return self.itemp return (self.itemp - 32) * 5 / 9 |
|
Then import the class and use it as indicated below. |
|
import temputils as tu
# construct a TempConvert object as 32 degrees Fahrenheit
# call .as_celsius() to see the value 0
# construct a Tempconvert object as 100 degrees Celsius
# call .as_fahrenheit() to see the value 212
|
|
Expected Output:
0.0 212.0 |
|