procedural programming

Object-oriented programming

Class : blueprint for objects outlining possible states and behaviors

Class is an abstract template describing the general sates and behaviors, while objects are particular representations following that abstract template.

state ↔ attributes ↔ variables

behavior ↔ methods ↔ function()

Constructor __init__() method is called every time an object is created.

from math import sqrt

# Write the class Point as outlined in the instructions
class Point():
		""" A point on a 2D plane
    
    Attributes
    ----------
    x : float, default 0.0. The x coordinate of the point        
    y : float, default 0.0. The y coordinate of the point
    """
    def __init__(self, x=0.0, y=0.0):
        self.x = x
        self.y = y

    def distance_to_origin(self):
				"""Calculate distance from the point to the origin (0,0)"""
        return sqrt((self.x **2 + self.y**2))
    
    def reflect(self, axis):
				"""Reflect the point with respect to x or y axis."""
        if axis=='x':
            self.y = -self.y
        elif axis=='y':
            self.x = -self.x
        else:
            print("The argument axis only accepts values 'x' and 'y'!")

pt = Point(x=3.0)
pt.reflect("y")
print((pt.x, pt.y))
pt.y = 4.0
print(pt.distance_to_origin())

instance data

class-level data

class Player:
    MAX_POSITION = 10                                                
    
    def __init__(self):
        self.position = 0

    # Add a move() method with steps parameter     
    def move(self, steps):
        if self.position + steps < Player.MAX_POSITION:
           self.position = self.position + steps 
        else:
           self.position = Player.MAX_POSITION
    
    # This method provides a rudimentary visualization in the console    
    def draw(self):
        drawing = "-" * self.position + "|" +"-"*(Player.MAX_POSITION - self.position)
        print(drawing)

p = Player(); p.draw()
p.move(4); p.draw()
p.move(5); p.draw()
p.move(3); p.draw()

You want to have a constructor that creates BetterDateobjects given the values for year, month, and day, but you also want to be able to create BetterDate objects from strings like 2020-04-30 .

class BetterDate:  
		# Class attributes
		_MAX_DAYS = 30
    _MAX_MONTH = 12
  
    # Constructor
    def __init__(self, year, month, day):
      # Recall that Python allows multiple variable assignments in one line
      self.year, self.month, self.day = year, month, day
    
    # Define a class method from_str
    @classmethod                                   
    def from_str(cls, datestr):
        # Split the string at "-" and convert each part to integer
        parts = datestr.split("-")
        year, month, day = int(parts[0]), int(parts[1]), int(parts[2])
				# or 
				# year, month, day = map(int, datestr.split("-"))

        # Return the class instance
        return cls(year, month, day)

		@classmethod
    def from_datetime(cls, datetime):
      year, month, day = datetime.year, datetime.month,datetime.day
      return cls(year, month, day)

		def _is_valid(self):
        return self.day <= BetterDate._MAX_DAYS 
					and self.month <= BetterDate._MAX_MONTH
        
bd = BetterDate.from_str('2020-04-30')   
today = datetime.today()     
bd = BetterDate.from_datetime(today)
print(bd.year)
print(bd.month)
print(bd.day)