%%file bank0.py
balance = 0
def withdraw(amount):
global balance
balance -= amount
def deposit(amount):
global balance
balance += amount
def get_balance():
return balance
if __name__ == "__main__":
pass
Overwriting bank0.py
import bank0
bank0.get_balance()
0
bank0.deposit(10000)
bank0.get_balance()
10000
bank0.withdraw(2000)
bank0.get_balance()
8000
%%file bank1.py
def make_account(balance):
return {"balance":balance}
def get_balance(account): # first argument is account, instance
return account['balance']
def withdraw(account, amount): # first argument is account, instance
account['balance'] -= amount
def deposit(account, amount): # first argument is account, instance
account['balance'] += amount
Overwriting bank1.py
import bank1
a1 = bank1.make_account(1000)
a2 = bank1.make_account(3000)
bank1.get_balance(a1)
1000
bank1.get_balance(a2)
3000
bank1.deposit(a1, 20000)
bank1.get_balance(a1)
21000
bank1.get_balance(a2)
3000
bank1.withdraw(a1, 200)
bank1.get_balance(a1)
20800
class BankAccount:
def __init__(self, balance): # strong convention that it should be names self
self.balance = balance
# this is something like constructor main method to create instance
def get_balance(self):
return self.balance
def withdraw(self, amount):
self.balance -= amount
def deposit(self, amount):
self.balance += amount
BankAccount
__main__.BankAccount
b1 = BankAccount(5000) # when you call a class like a function ... it actually invokes __init__ method
b1.get_balance()
5000
b1.deposit(1232)
b1.withdraw(232)
b1.get_balance()
6000
class Foo:
def method():
print("Hello")
f = Foo()
f.method()
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-33-05dc94509d19> in <module> ----> 1 f.method() TypeError: method() takes 0 positional arguments but 1 was given
Foo.method()
Hello
BankAccount
__main__.BankAccount
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
p1 = Point(3, 4)
import math
class Vector:
def __init__(self, point1, point2):
self.start = point1 # this is instance of point passed
self.end = point2
def magnitude(self):
xoffset = self.end.x - self.start.x
yoffset = self.end.y - self.start.y
return math.sqrt(xoffset**2+yoffset**2)
origin = Point(0, 0)
x1 = Point(1, 0)
xunit = Vector(origin, x1)
xunit.magnitude()
1.0
origin
<__main__.Point at 0x7efd9a07d610>
x1
<__main__.Point at 0x7efd9a07d550>
origin.x # these are called as attributes
0
origin.y
0
class Foo:
def __init__(self, a, b):
self.a = a # convention is anything that does not start with _ is public
self.b = b
f = Foo(5, 6)
f.a
5
f.b
6
class FooBar:
def __init__(self, a, b):
self.a = a # convention is anything that does not start with _ is public
self.b = b
self._c = a+b
def mehtod(self):
print(self._c) # private attributes are only for class members.
fb = FooBar(34 , 42)
fb.a
34
fb.b
42
fb._c # python does not put any restriction as public or private. but by convetion I wil not access it because it starts with _
76
a1
{'balance': 20800}
b1
<__main__.BankAccount at 0x7efd99e46eb0>
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
p = Point(1, 2)
p
<__main__.Point at 0x7efd9a41bca0>
type(p)
__main__.Point
type(2)
int
int() # we were thinking as a function is nothing but constructor of a class int!
0
x = [1, 2, 3, 4]
x
[1, 2, 3, 4]
p
<__main__.Point at 0x7efd9a41bca0>
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __repr__(self):
return f"{self.x},{self.y}"
Point(2, 3)
2,3
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __repr__(self):
return f"Point<{self.x},{self.y}>"
p = Point(45, 2)
p
Point<45,2>
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __repr__(self):
return f"Point<{self.x},{self.y}>"
def __str__(self):
return f"<{self.x},{self.y}>"
p = Point(34, 45)
p # __repr__
Point<34,45>
print(p) #__str__
<34,45>
problem
k = 0
for i in range(10000000):
k = k + i**2
print(k)
333333283333335000000