In [1]:
#########################################################
## Video 1
# Classes and Instances
#### 
# 
# Group data and functions.
#   Data and functitions > Attributes and methods

class Employee:
    pass
In [3]:
# Difference between classes and instances 
#
# Class : Blue Print for cleating instances

class Employee:
    pass

emp1 = Employee() # Each unique instance
emp2 = Employee() # Each unique instance
# Each of them is a unique instance of the employee class
# Inatance variables <---> class variables

print(emp1)
print(emp2)
<__main__.Employee instance at 0x00000000058A62C8>
<__main__.Employee instance at 0x00000000058A60C8>
In [5]:
class Employee:
    pass

emp1 = Employee() # Each unique instance
emp2 = Employee() # Each unique instance
# Each of them is a unique instance of the employee class
# Inatance variables <---> class variables

print(emp1)
print(emp2)

emp1.fast = "Tats"
emp1.last = "SH"
emp1.email = "[email protected]"
emp1.pay = 50000

emp2.fast = "Test"
emp2.last = "User"
emp2.email = "[email protected]"
emp2.pay = 60000

# Each of these instances has attributes which unique to it. 

print(emp1.email)
print(emp2.email)
<__main__.Employee instance at 0x00000000058A6408>
<__main__.Employee instance at 0x00000000058A62C8>
[email protected]
[email protected]
In [9]:
### init method
# Initialization or constructor (if you are familiar with another language)

class Employee:
    def __init__(self, first, last, pay):
        # It receives the instance as a first argument automatically. 
        # By convention, it is called self. 
        # After the self, you should input other arguments you want to accept.
        
        # self is instance
        # Set all instance variables
        self.first = first
        self.last = last
        self.pay = pay
        self.email = first + '.' + last + '@company.com'

emp1 = Employee("Tats", "SH", 50000) # This is going to set all attributes 
emp2 = Employee("Test","User",60000) # This is going to set all attributes 

print(emp1.email)
print(emp2.email)

# first, last, pay and email are all attributes of the class. 

print('{} {}'.format(emp1.first, emp1.last))
# This is too much work. It is good idea to put this method into a class. 
In [112]:
# Method in the class
class Employee:
    def __init__(self, first, last, pay):
        # It receives the instance as a first argument automatically. 
        # By convention, it is called self. 
        # After the self, you should input other arguments you want to accept.
        
        # self is instance
        # Set all instance variables
        self.first = first
        self.last = last
        self.pay = pay
        self.email = first + '.' + last + '@company.com'
    
    def fullname(self):
        # It always calls the instance as a first argument. 
        # That is all you need. 
        return '{} {}'.format(self.first, self.last)

emp1 = Employee("Tats", "SH", 50000) # This is going to set all attributes 
emp2 = Employee("Test","User",60000) # This is going to set all attributes 

print(emp1.email)
print(emp2.email)

print(emp1.fullname()) # You need () here because this is a method instead of an attribute. 
print(emp2.fullname()) # You need () here because this is a method instead of an attribute. 

print(emp1.fullname) # This prints the method instead of the return value of the method. 
print(emp2.fullname) # This prints the method instead of the return value of the method. 
[email protected]
[email protected]
Tats SH
Test User
<bound method Employee.fullname of <__main__.Employee instance at 0x0000000004052BC8>>
<bound method Employee.fullname of <__main__.Employee instance at 0x00000000059F9088>>
In [14]:
# self is important
class Employee:
    def __init__(self, first, last, pay):
        # It receives the instance as a first argument automatically. 
        # By convention, it is called self. 
        # After the self, you should input other arguments you want to accept.
        
        # self is instance
        # Set all instance variables
        self.first = first
        self.last = last
        self.pay = pay
        self.email = first + '.' + last + '@company.com'
    
    def fullname(): ########################### Watch out!
        # It always calls the instance as a first argument. 
        # That is all you need. 
        return '{} {}'.format(self.first, self.last)

emp1 = Employee("Tats", "SH", 50000) # This is going to set all attributes 
emp2 = Employee("Test","User",60000) # This is going to set all attributes 

# This actually runs. 
In [15]:
# self is important
class Employee:
    def __init__(self, first, last, pay):
        # It receives the instance as a first argument automatically. 
        # By convention, it is called self. 
        # After the self, you should input other arguments you want to accept.
        
        # self is instance
        # Set all instance variables
        self.first = first
        self.last = last
        self.pay = pay
        self.email = first + '.' + last + '@company.com'
    
    def fullname(): ########################### Watch out!
        # It always calls the instance as a first argument. 
        # That is all you need. 
        return '{} {}'.format(self.first, self.last)

emp1 = Employee("Tats", "SH", 50000) # This is going to set all attributes 
emp2 = Employee("Test","User",60000) # This is going to set all attributes 

# Error
print(emp1.fullname()) # You need () here because this is a method instead of an attribute. 
TypeErrorTraceback (most recent call last)
<ipython-input-15-2126033b44b6> in <module>()
     22 
     23 # Error
---> 24 print(emp1.fullname()) # You need () here because this is a method instead of an attribute.

TypeError: fullname() takes no arguments (1 given)
In [16]:
# Alternative way
class Employee:
    def __init__(self, first, last, pay):
        # It receives the instance as a first argument automatically. 
        # By convention, it is called self. 
        # After the self, you should input other arguments you want to accept.
        
        # self is instance
        # Set all instance variables
        self.first = first
        self.last = last
        self.pay = pay
        self.email = first + '.' + last + '@company.com'
    
    def fullname(self): 
        # It always calls the instance as a first argument. 
        # That is all you need. 
        return '{} {}'.format(self.first, self.last)

emp1 = Employee("Tats", "SH", 50000) # This is going to set all attributes 
emp2 = Employee("Test","User",60000) # This is going to set all attributes 

## These two lines do exactly the same thing. 
print(emp1.fullname()) 
# Instance calles the method. You don't need to pass in "self". 
print(Employee.fullname(emp1)) 
# When you call the method of the class, it does not know what inctance is. You need to pass instance. 
Tats SH
Tats SH
In [19]:
#########################################################
## Video 2
# Class Variables
#### 
# Class variables are shared among all instances on the class while instance variables are unique in each instance. 

class Employee:
    def __init__(self, first, last, pay):
        self.first = first
        self.last = last
        self.pay = pay
        self.email = first + '.' + last + '@company.com'
    
    def fullname(self): 
        return '{} {}'.format(self.first, self.last)

    def apply_raise(self): 
        self.pay = int(self.pay * 1.04)
    
emp_1 = Employee("Tats", "SH", 50000) # This is going to set all attributes 
emp_2 = Employee("Test","User",60000) # This is going to set all attributes 

print(emp_1.pay)
emp_1.apply_raise
print(emp_1.pay)
emp_1.apply_raise() # Do not forget ()!
print(emp_1.pay)

### Raise amount "4%" is hidden in the class. 
50000
50000
52000
In [20]:
class Employee:
    
    raise_amount = 1.04
    
    def __init__(self, first, last, pay):
        self.first = first
        self.last = last
        self.pay = pay
        self.email = first + '.' + last + '@company.com'
    
    def fullname(self): 
        return '{} {}'.format(self.first, self.last)

    def apply_raise(self): 
        self.pay = int(self.pay * raise_amount)
    
emp_1 = Employee("Tats", "SH", 50000) # This is going to set all attributes 
emp_2 = Employee("Test","User",60000) # This is going to set all attributes 

print(emp_1.pay)
emp_1.apply_raise() # Do not forget ()!
print(emp_1.pay)

### This gives an error.
50000
50000
NameErrorTraceback (most recent call last)
<ipython-input-20-b80fd97042ba> in <module>()
     21 emp_1.apply_raise
     22 print(emp_1.pay)
---> 23 emp_1.apply_raise() # Do not forget ()!
     24 print(emp_1.pay)

<ipython-input-20-b80fd97042ba> in apply_raise(self)
     13 
     14     def apply_raise(self):
---> 15         self.pay = int(self.pay * raise_amount)
     16 
     17 emp_1 = Employee("Tats", "SH", 50000) # This is going to set all attributes

NameError: global name 'raise_amount' is not defined