Python Objects (or a Bike and a Wheel)

This entry is part 7 of 8 in the series Python

When I first tried to teach myself programming, I bought a Java book that started teaching object-oriented programming (OOP) by describing an object (a bicycle), which had properties (wheels, pedals, etc), and state (moving or stopped).  I said whaah?!  Why am I learning about a bike and whether it’s moving or not.

Needless to say, I was completely befuddled and had no idea what I was doing or how to relate this bike concept.  Funny enough, a handful of years later a co-worker of mine described programming in almost exactly the same way.  It made as much of no sense as it did the first time.

The point in this initial ramble of mine is to promise you I won’t try to explain programming and OOP by using your first grade tricycle.

I like to think of OOP as a useful way to combine similar sets of code/logic so you can use it over and over without rewriting it.  From How To Become A Hacker (not the breaking into things type, but hacker as in building killer software), Eric S. Raymond writes:

Hackers (and creative people in general) should never be bored or have to drudge at stupid repetitive work, because when this happens it means they aren’t doing what only they can do — solve new problems. This wastefulness hurts everybody. Therefore boredom and drudgery are not just unpleasant but actually evil.



To behave like a hacker, you have to believe this enough to want to automate away the boring bits as much as possible, not just for yourself but for everybody else (especially other hackers).

OOP is useful so you don’t have to write the same thing, over and over again.  The example I like to use is writing a banking application.  First I’ll briefly explain a core part of DRY (Don’t Repeat Yourself) as functions.  If you have a for loop where you perform the same logic over a list, you can separate that logic into a function so you only write it once, but you can call it as many times as you need.

"""We're going to print abreviated titles
from a list of titles
def short_title(title):
    new_title = ''
    if len(title) > 20: 
        new_title = title[:21]+'...'
        new_title = title

    return new_title

titles = [ 
    'Here is Title 1',
    'Title 2', 
    "A longer title that won't fit.",
    'Something a bit longer than we want'

for title in titles:
    print short_title(title)

To declare a function, we use the keyword def to declare (or define) a function.  title in def short_title(title): is a parameter that is passed into this function, which we use later to create a short title.  The gist of short_title is to return an abbreviated title if it’s longer than 20 characters.  Don’t worry too much about the details, just try to understand that the short_title function allows us to repeat creating an abbreviated title and use it anywhere else we need it.

The output, in case you were curious:

$ python 
Here is Title 1
Title 2
A longer title that w...
Something a bit longe...

Next lesson we’ll go over the following code about the rich, poor, and greedy:

class Person(object):
    """This is the base class that represents
    a Person
    def __init__(self, first_name, last_name, age):
        self.first_name = first_name
        self.last_name = last_name
        self.age = age

    def get_full_name(self):
        return self.first_name +' '+ self.last_name

class Employee(Person):
    """Since an employee is a Person, we indicate
    that we are a Person by declaring
    class Employee(Person):
    The item inside of () shows we inherit from
    def __init__(self, fname, lname, age, salary, manager):
        Person.__init__(self, first_name=fname, last_name=lname, age=age)
        self.salary = salary
        self.manager = manager

    def get_manager_salary(self):
        return self.manager.salary

    def is_owner(self):
        return True if self.manager is not None else False

class Customer(Person):
    """A Customer is also a Person
    which means we also have a first and last name
    as well as an age
    def __init__(self, first_name, last_name, age, bank_account):
        Person.__init__(self, first_name, last_name, age=age)
        self.bank_account = bank_account

    def get_account_balance(self):
        return self.bank_account.balance

    def deposit(self, amount):
        # We return the new account balance
        return self.bank_account.increase_cash(amount)

    def spend(self, amount):
        return self.bank_account.decrease_cash(amount)

class BankAccount(object):
    """A class that represents a bank
    def __init__(self, balance, manager):
        self.balance = balance
        self.manager = manager

    def decrease_cash(self, spent_money):
        self.balance -= spent_money
        return self.balance

    def increase_cash(self, money):
        self.balance += money
        return self.balance

bank_manager = Employee('Scrooge', 'McMuffins', salary=1000000, age=99, manager=None)
rich_bank_account = BankAccount(1000, bank_manager)
rich_customer = Customer('Rich', 'Person', age=205, bank_account=rich_bank_account)

print 'The bank manager for your bank is %s'%(bank_manager.get_full_name())
print 'Your account has $%d in it'%(rich_bank_account.balance)

interest_payment = 2500
print '%s\'s account earns $%d of interest'%(rich_customer.get_full_name(), interest_payment)
new_balance = rich_bank_account.increase_cash(interest_payment)
print '%s\'s new balance is $%d'%(rich_customer.get_full_name(), new_balance)
print '%s\'s age is %d years old'%(rich_customer.get_full_name(), rich_customer.age)

print '%s spends a little money'%(rich_customer.get_full_name())
print '%s now has $%d'%(rich_customer.get_full_name(), rich_customer.get_account_balance())

# He has the same mean bank manager as the rich person!
poor_account = BankAccount(10, manager=bank_manager)
poor_customer = Customer('Poor', 'Person', 105, poor_account)

print '%s starts with $%d'%(poor_customer.get_full_name(), poor_account.balance)
print '%s steals money from %s'%(bank_manager.get_full_name(), poor_customer.get_full_name())
print '%s now only has $%d'%(poor_customer.get_full_name(), poor_customer.get_account_balance())

The output for this code is below:

$ python 
The bank manager for your bank is Scrooge McMuffins
Your account has $1000 in it
Rich Person's account earns $2500 of interest
Rich Person's new balance is $3500
Rich Person's age is 205 years old
Rich Person spends a little money
Rich Person now has $3400
Poor Person starts with $10
Scrooge McMuffins steals money from Poor Person
Poor Person now only has $5

Can you piece it together before we talk about it?  Comment below with any thoughts….


Series Navigation<< Becoming a Python Grown-Up
Python Classes and OOP >>