<class 'list'>
True
False
January 29, 2024
<class 'list'>
True
False
mylist = []
creates an empty listtype(mylist)
returns the type of the listisinstance
returns True
or False
for provided typeisinstance(mylist, list)
checks if mylist
is a list
def generator_example(n):
for i in range(n):
yield i
print(type(generator_example))
print(type(generator_example(5)))
<class 'function'>
<class 'generator'>
type
shows that functions and generators have their own typesreturn
and yield
influence a function’s behavior?u = (3,4)
v = (3,6)
def add(a, b):
return (a[0] + b[0], a[1] + b[1])
def subtract(a,b):
return (a[0] - b[0], a[1] - b[1])
def dot(a, b):
return (a[0] * b[0] + a[1] * b[1])
def norm(a):
return (a[0] * a[0] + a[1] * a[1]) ** 0.5
def isvertical(a):
return a[0] == 0
print(norm(u))
print(add(u,v))
print(u + v)
print(isvertical(subtract(v, u)))
5.0
(6, 10)
(3, 4, 3, 6)
True
class Vector:
def __init__(self, x, y):
try:
self.x = float(x)
self.y = float(y)
except ValueError:
self.x = 0.0
self.y = 0.0
def norm(self):
return (self.x ** 2 + self.y ** 2) ** 0.5
def __add__(self, other):
newx = self.x + other.x
newy = self.y + other.y
return Vector(newx, newy)
def __str__(self):
return "(%f, %f)" %(self.x, self.y)
u = Vector(3,4)
v = Vector(3,6)
print(u + v)
(6.000000, 10.000000)
Triangle
Triangle
object have?Triangle
object?Square
Square
object have?Square
object?Square
and a Triangle
?Polygon
class is a superclass of Triangle
and Square
Triangle
and Square
classes are subclasses of Polygon
Polygon
class is a generalization of Triangle
and Square
Triangle
and Square
to the Polygon
SuperclassTriangle
and Polygon
and also Square
and Polygon
Python is a dynamically typed language
Python uses duck typing to determine types
Remember the silly adage of “If it walks like a duck and quacks like a duck, then it must be a duck”
Inheritance is not only way to create an “is-a” relationship!
Yet, inheritance makes the “is-a” relationship explicit
Let’s explore an example of duck typing in Python!
Triangle
and Square
to the Polygon
Superclasspolygon
parameter can be any object with a sides
methodclass MyLimitedList:
def __init__(self):
self._L = []
def append(self, item):
self._L.append(item)
def __getitem__(self, index):
return self._L[index]
limited = MyLimitedList()
limited.append(1)
limited.append(10)
limited.append(100)
print(limited[2])
100
MyLimitedList
class is composed of a list called _L
import timeit, f
n = int(1e6)
num_exec = 1
for func in filter(lambda f: f.startswith('loop'), sorted(dir(f))):
print('====== Timing function called:', func)
print(getattr(f, func).__doc__)
t = timeit.timeit(stmt='f.%s(n)' % func,
number=num_exec, globals=globals())
per_loop = round(t / n * 1e9)
print('Time: %ins, Theoretical max bandwidth: %.2fMB/s' %
(per_loop, 1000 / per_loop))
====== Timing function called: loop_0_empty
Run empty loop n times.
Time: 13ns, Theoretical max bandwidth: 76.92MB/s
====== Timing function called: loop_1_f
Run loop with empty function n times.
Time: 49ns, Theoretical max bandwidth: 20.41MB/s
====== Timing function called: loop_2_f_twice
Run loop calling empty function twice per loop, n times.
Time: 84ns, Theoretical max bandwidth: 11.90MB/s
import timeit, g
n = int(1e6)
num_exec = 1
for func in filter(lambda g: g.startswith('loop'), sorted(dir(g))):
print('====== Timing function called:', func)
print(getattr(g, func).__doc__)
t = timeit.timeit(stmt='g.%s(n)' % func,
number=num_exec, globals=globals())
per_loop = round(t / n * 1e9)
print('Time: %ins, Theoretical max bandwidth: %.2fMB/s' %
(per_loop, 1000 / per_loop))
====== Timing function called: loop_3_g
Run loop with empty function taking args, n times.
Time: 64ns, Theoretical max bandwidth: 15.62MB/s
====== Timing function called: loop_5_g_arg
Run loop with empty function passing an arg, n times.
Time: 77ns, Theoretical max bandwidth: 12.99MB/s
====== Timing function called: loop_6_g_kwarg
Run loop with empty function passing a kwarg, n times.
Time: 104ns, Theoretical max bandwidth: 9.62MB/s
function-calls
timer.py
and observe the resultsf.py
and g.py
Algorithmology