Showing posts with label python programming. Show all posts

how to Tuples, Lists, and Dictionaries in python

Your brain still hurting from the last lesson? Never worry, this one will require a little less thought. We're going back to something simple - variables - but a little more in depth.
Think about it - variables store one bit of information. They may regurgitate (just not on the carpet...) that information at any point, and their bit of information can be changed at any time. Variables are great at what they do - storing a piece of information that may change over time.
But what if you need to store a long list of information, which doesn't change over time? Say, for example, the names of the months of the year. Or maybe a long list of information, that does change over time? Say, for example, the names of all your cats. You might get new cats, some may die, some may become your dinner (we should trade recipies!). What about a phone book? For that you need to do a bit of referencing - you would have a list of names, and attached to each of those names, a phone number. How would you do that?

The Solution - Lists, Tuples, and Dictionaries

For these three problems, Python uses three different solutions - Tuples, lists, and dictionaries:
  • Lists are what they seem - a list of values. Each one of them is numbered, starting from zero - the first one is numbered zero, the second 1, the third 2, etc. You can remove values from the list, and add new values to the end. Example: Your many cats' names.
  • Tuples are just like lists, but you can't change their values. The values that you give it first up, are the values that you are stuck with for the rest of the program. Again, each value is numbered starting from zero, for easy reference. Example: the names of the months of the year.
  • Dictionaries are similar to what their name suggests - a dictionary. In a dictionary, you have an 'index' of words, and for each of them a definition. In python, the word is called a 'key', and the definition a 'value'. The values in a dictionary aren't numbered - tare similar to what their name suggests - a dictionary. In a dictionary, you have an 'index' of words, and for each of them a definition. In python, the word is called a 'key', and the definition a 'value'. The values in a dictionary aren't numbered - they aren't in any specific order, either - the key does the same thing. You can add, remove, and modify the values in dictionaries. Example: telephone book.

Tuples

Tuples are pretty easy to make. You give your tuple a name, then after that the list of values it will carry. For example, the months of the year:
Code Example 1 - creating a tuple
months = ('January','February','March','April','May','June',\
'July','August','September','October','November','  December')
  • Note that the '\' thingy at the end of sthurlow.comthe first line carries over that line of code to the next line. It is usefull way of making big lines more readable.
  • Technically you don't have to put those parentheses there (the '(' and ')' thingies) but it stops python from getting things confused.
  • You may have spaces after the commas if you feel it necessary - it doesn't really matter.
Python then organises those values in a handy, numbered index - starting from zero, in the order that you entered them in. It would be organised like this:
Table 1 - tuple indicies
Index Value
0 January
1 Feb
2 Mar
3 Apr
4 May
5 Jun
6 Jul
7 Aug
8 Sep
9 Oct
10 Nov
11 Dec

And that is tuples! Really easy...

Lists

Lists are extremely similar to tuples. Lists are modifiable (or 'mutable', as a programmer may say), so their values can be changed. Most of the time we use lists, not tuples, because we want to easily change the values of things if we need to.
Lists are defined very similarly to tuples. Say you have FIVE cats, called Tom, Snappy, Kitty, Jessie and Chester. To put them in a list, you would do this:
Code Example 2 - Creating a List
cats = ['Tom', 'Snappy', 'Kitty', 'Jessie', 'Chester']
As you see, the code is exactly the same as a tuple, EXCEPT that all the values are put between square brackets, not parentheses. Again, you don't have to have spaces after the comma.
You recall values from lists exactly the same as you do with tuples. For example, to print the name of your 3rd cat you would do this:
Code Example 3 - Recalling items from a list
print cats[2]
You can also recall a range of examples, like above, for example - cats[0:2] would recall your 1st and 2nd cats.
Where lists come into their own is how they can be modified. To add a value to a list, you use the 'append()' function. Let's say you got a new cat called Catherine. To add her to the list you'd do this:
Code Example 4 - Adding items to a list
cats.append('Catherine')
That's a little weird, isn't it? I'll explain. That function is in a funny spot - after a period (the '.' kind of period, not otherwise), after the list name. You'll get to see those things more in a later lesson. For the meanwhile, this is the form of the function that adds a new value to a list:
Code Example 5 - Using the append function
#add a new value to the end of a list:
list_name.append(value-to-add)

#e.g. to add the number 5038 to the list 'numbers':
numbers.append(5038)
Clears things up? Good!
Now to a sad situation - Snappy was shot by a neighbour, and eaten for their dinner (good on 'em!). You need to remove him (or her) from the list. Removing that sorry cat is an easy task, thankfully, so you have to wallow in sadness for as short a time as possible:
Code Example 6 - Deleting an item
#Remove your 2nd cat, Snappy. Woe is you.
del cats[1]
You've just removed the 2nd cat in your list - poor old Snappy.
And with that morbid message, lets move on to...

Dictionaries

Ok, so there is more to life than the names of your cats. You need to call your sister, mother, son, the fruit man, and anyone else who needs to know that their favourite cat is dead. For that you need a telephone book.
Now, the lists we've used above aren't really suitable for a telephone book. You need to know a number based on someone's name - not the other way around, like what we did with the cats. In the examples of months and cats, we gave the computer a number, and it gave us a name. This time we want to give the computer a name, and it give us a number. For this we need Dictionaries.
So how do we make a dictionary? Put away your binding equipment, it isn't that advanced.
Remember, dictionaries have keys, and values. In a phone book, you have people's names, then their numbers. See a similarity?
When you initially create a dictionary, it is very much like making a tuple or list. Tuples have ( and ) things, lists have [ and ] things. Guess what! dictionaries have { and } things - curly braces. Here is an example below, showing a dictionary with four phone numbers in it:
Code Example 7 - Creating a dictionary
#Make the phone book:
phonebook = {'Andrew Parson':8806336, \
'Emily Everett':6784346, 'Peter Power':7658344, \
'Lewis Lame':1122345}
the program would then print Lewis Lame's number onscreen. Notice how instead of identifying the value by a number, like in the cats and months examples, we identify the value, using another value - in this case the person's name.
Ok, you've created a new phone book. Now you want to add new numbers to the book. What do you do? A very simple line of code:
Code Example 8 - Adding entries to a dictionary
#Add the person 'Gingerbread Man' to the phonebook:

phonebook['Gingerbread Man'] = 1234567

# Didn't think I would give you
# my real number now, would I?
All that line is saying is that there is a person called Gingerbread Man in the phone book, and his number is 1234567. In other words - the key is 'Gingerbread Man', and the value is 1234567.
You delete entries in a dictionary just like in a list. Let's say Andrew Parson is your neighbour, and shot your cat. You never want to talk to him again, and therefore don't need his number. Just like in a list, you'd do this:
Code Example 9 - Removing entries from a dictionary
del phonebook['Andrew Parson']
Again, very easy. the 'del' operator deletes any function, variable, or entry in a list or dictionary (An entry in a dictionary is just a variable with a number or text string as a name. This comes in handy later on.)
remember that append function that we used with the list? Well, there are quite a few of those that can be used with dictionaries. Below, I will write you a program, and it will incorporate some of those functions in. It will have comments along the way explaining what it does.
Type this program into Python IDLE (you can skip the comments). Experiment as much as you like with it. Type it where you see the lines beginning with >>>
Code Example 10 - Functions of dictionaries
#A few examples of a dictionary

#First we define the dictionary
#it will have nothing in it this time
ages = {}

#Add a couple of names to the dictionary
ages['Sue'] = 23
ages['Peter'] = 19
ages['Andrew'] = 78
ages['Karren'] = 45

#Use the function has_key() - 
#This function takes this form:
#function_name.has_key(key-name)
#It returns TRUE
#if the dictionary has key-name in it
#but returns FALSE if it doesn't.
#Remember - this is how 'if' statements work -
#they run if something is true
#and they don't when something is false.
if ages.has_key('Sue'):
    print "Sue is in the dictionary. She is", \
ages['Sue'], "years old"

else:
    print "Sue is not in the dictionary"

#Use the function keys() - 
#This function returns a list
#of all the names of the keys.
#E.g.
print "The following people are in the dictionary:"
print ages.keys()

#You could use this function to
#put all the key names in a list:
keys = ages.keys()

#You can also get a list
#of all the values in a dictionary.
#You use the values() function:
print "People are aged the following:", \
ages.values()

#Put it in a list:
values = ages.values()

#You can sort lists, with the sort() function
#It will sort all values in a list
#alphabetically, numerically, etc...
#You can't sort dictionaries - 
#they are in no particular order
print keys
keys.sort()
print keys

print values
values.sort()
print values

#You can find the number of entries
#with the len() function:
print "The dictionary has", \
len(ages), "entries in it"

Conclusion

There are many other functions you can use to work with lists and dictionaries - too many to go through right now. We'll leave the lesson at this point - you have learnt enough for one lesson.

Programs in a file, and variables Using Python

Introduction

Well, we can make one-liner programs. So What? You want to send programs to other people, so that they can use them, without knowing how to write them.

Editing in Notepad

Writing programs in python to a file is VERY easy. Python programs are simply text documents - you can open them up in notepad, and have a look at them, just like that. So, go and open notepad. Type the following:
Code Example 1 - mary.py
#A simple program.
print "Mary had a little lamb,"
print "it's fleece was white as snow;"
print "and everywhere that Mary went",
print "her lamb was sure to go."
Keep this exactly the same, down to where the commas are placed. Save the file as 'mary.py' - and make sure notepad doesn't add .txt to the end of the filename - You will have to tell it to save as any file, to avoid this. Turn off 'Hide known file extensions' in Windows Explorer, if it makes it easier.

Using the IDLE Environment

Now, open up the Python IDLE program (should be in your start menu). Click 'File > Open' and find mary.py and open it. if you cant find mary.py, set the open dialogue to 'Files of type: All Files (*)'. A new window will open, showing the program you just wrote. To run your program, click 'Run>Run Module' (or just press F5). Your program will now run in the main Python screen (Titled *Python Shell*) and will look like this:
Code Example 2 - mary.py output
Mary had a little lamb,
it's fleece was white as snow;
and everywhere that Mary went her lamb was sure to go.
You can also use IDLE to create Python programs, like what you did in notepad. Simply click 'File > New'. We will be writing all of our programs now in the python IDLE program - the notepad thing is just a demonstration to tell you that a .py file is just a simple text file, which anyone can see.
There are a couple of things to notice here:
  • First of all, the comment wasn't shown. That is good, because remember - comments aren't compiled. (try compiling it after removing the # - it comes out messy)
  • Second, is that the 3rd and 4th line got joined. This is because there is a comma just outside the inverted commas that surround the text. In the 'print' command, this stops the program from starting a new line on the screen when showing text.
  • You can also run the program from your command line program (e.g. MSDOS) - Open the prompt up, type 'cd path\to\your\file' then type 'python mary.py'. Your program will now execute in the command line.

Variables

Now lets start introducing variables. Variables store a value, that can be looked at or changed at a later time. Let's make a program that uses variables. Open up IDLE, click 'File>New Window' - a new window now appears, and it is easy to type in programs. Type the following (or just copy and paste - just read very carefully, and compare the code to the output that the program will make):
Code Example 3 - Variables
#variables demonstrated
print "This program is a demo of variables"
v = 1
print "The value of v is now", v
v = v + 1
print "v now equals itself plus one, making it worth", v
v = 51
print "v can store any numerical value, to be used elsewhere."
print "for example, in a sentence. v is now worth", v
print "v times 5 equals", v*5
print "but v still only remains", v
print "to make v five times bigger, you would have to type v = v * 5"
v = v * 5
print "there you go, now v equals", v, "and not", v / 5

Strings

As you can see, variables store values, for use at a later time. You can change them at any time. You can put in more than numbers, though. Variables can hold things like text. A variable that holds text is called a string. Try this program:
Code Example 4 - Strings
#giving variables text, and adding text.
word1 = "Good"
word2 = "Morning"
word3 = "to you too!"
print word1, word2
sentence = word1 + " " + word2 + " " +word3
print sentence
The output will be:
Code Example 5 - String output
Good Morning
Good Morning to you too!
As you see, the variables above were holding text. Variable names can also be longer than one letter - here, we had word1, word2, and word3. As you can also see, strings can be added together to make longer words or sentences. However, it doesn't add spaces in between the words - hence me putting in the " " things (there is one space between those).

Conclusion

Well done! We now understand longer programs, and know the use of variables. Next lesson, we look at functions, what they are, and how to use them.
Thanks to all,

How To Learn Python: Programming by Hacking

Python is exploding. And there’s a reason for that. It’s awesome! It seems everyone is learning it, teaching it, and hacking with it. Folks are even making python puppets and writing poetry in Python. While Python is easy to learn, it’s not necessarily easy to learn.
The following are the amazing resources I discovered and the hard-won lessons I learned on my adventure into programming.

Hack Through the Thicket

The best way to learn Python is with a project. Think of a (simple) problem you want to solve and start writing the program to get to the solution. I got sucked in with Twitter bots. I have a love/hate thing for Twitter. It’s like watching a river… a river full of garbage. But it’s a great place to learn Python. It’s so much fun to hack Twitter. It’s an incredible game of strategy: how much can you get away with before your account gets suspended? The best part is seeing immediate results. I was hooked when I wrote my first Twitter bot and saw the status update appear on my time line. “Hello, World!” on your Twitter account is much cooler than “Hello, World!” on your IDLE prompt. I’m currently writing a series of tutorials, intended for beginners, on how to hack the social media giant.
I understand that it t can be difficult for a beginner to think of a project when he or she doesn’t know what the language is capable of doing. Here’s a starter project that you, knowing nothing about Python at the outset, could easily accomplish in a day:
write a password generator.
You will utilize all the basics, and then some, in writing a program that produces the perfect password. It’s a very simple script, but you can geek-out and get crazy complex with it.

Hit the Books

Before you start or hack an existing project, you need to know the basics. There are a lot of Python books out there. While all of them will teach you what you need to know, some are better than others. These are my favorites, in order of accessibility:

1. Think Python

Downey gets you thinking like a programmer, which is more important than knowing or learning what every damn little thing does. Don’t fill your brain with with this stuff. That’s what Google is for.
Each chapter is loaded with exercises that ask you to use what you just learned to solve interesting, more or less practical, problems.
It’s free online.

2. python.org

Seriously, what better place to learn Python than from the source. The tutorials are actually good. It’s like they really want you to learn this stuff. It’s technically not a book, but what’s a book anymore?

3. Practical Programming

This book is very good at not only explaining how Python works, but how your computer works as well, and why it’s important to know as a programmer. The authors also run a MOOC on Coursera, but the book is so much better. Buy it on Amazon.

4. Real Python for the Web

The Real Python ebook package is amazing. You will go from noob to (almost) pro in an amazingly short amount of time. As the title suggests, it’s catered to those wanting to use Python for web development. If that’s you, throw down the money and get the bundle. It’s worth every penny.
The three gentlemen behind Real Python are approachable, knowledgeable, and witty. They sporadically post tutorials on their blog that range from beginner to advanced. Start with Lyricize: A Flask app to create lyrics using Markov chains. You will not only learn Python, you’ll be introduced to Flask and Markov chains while creating an app that is pretty cool.

5. Writing Idiomatic Python

Jeff Knupp knows his stuff. Much of what he covers in his book is advanced, but what better time to learn best practices than when you’re just starting out. The examples are easy to follow and understand and you will be setting yourself up for the future. His blog, Everything I Know About Python…, is specifically focused on web developers using Django or Flask, but he often writes about Python in general. Starting a Python Project the Right Way is an excellent introductory post.

Non-trivial Pursuit

StackExchange

Search for solutions to your problem. I don’t mean that in some metaphysical, philosophical way. I mean use a search engine. When you do, go to any Stack link first. There are a lot of content farms and dead end links out there. Your time is precious, especially when you’re learning Pythion in your free time. Go to Stack Exchange and you will find more than one answer and often an interesting debate about best practices.
Caveat: StackExcahnge can be frustrating for beginners because you have to earn reputation points. It makes sense, but it also makes it seem impenetrable. Pay your dues. It’s worth it. Also, it’s not just for programming. It’s massive.

GitHub

GitHub is a great resource for beginners because so many beginners create repositories for their early projects. These simple programs will demonstrate how to practically implement the concepts you are learning elsewhere. I found countless Twitter bot scripts on GitHub that I downloaded, hacked, and modified. When you define the problem you want to solve, search GitHub. Chances are someone else already wrote a solution. Clone or fork their repo and see how they solved your problem. Then proceed to tear it apart until it does exactly what you want. To get started with GitHub, create an account and check out their bootcamp.
If you take this approach you’ll begin to get comfortable with Git and Github. If you want to get serious, and you’re also a Linux enthusiast, you should learn both. A lot of Pythonistas swear by Mercurial and Bitbucket. I’ve only used them cursorily, so I can’t say anything one way or another. I started with Git. It works for me. I’ll stick with Git.

Lists & Newsletters

Tutor

Sign up for the Python Tutor list. I learned, and still learn, so much from it. But, be warned. The temperament of the list changes seasonally. It will swing from compassionate to cruel. When it turns sour, I usually unsubscribe for a few months, and I’ll resubsrcibe when I need help with a problem and stick with it until it gets bad.
Also, your Inbox will quickly fill up with mail from the list. You should read every email and follow the discussions as they evolve, even if you don’t grok.

Python Weekly

Sign up for Python Weekly. While most of it will be over your head in the beginning, you will receive an excellent recap of the goings-on in the Python community for the past seven days. Read through ALL of the headlines, but only click on those that you understand. After a few months, you’ll be opening every link and frustrated because you don’t have enough time to read and work through all of the posts.

The Stuff That’s Really Popular

You may have noticed that there are a number of obvious omissions from my lists above.
Everyone cites Zed Shaw’s Learn Python the Hard Way. It’s an excellent overview, but it’s not beginner-friendly. It was one of the first resources I encountered, but I could not stick with it. Now that I know the basics and I work back through Zed’s tutorials, I am able to see that it’s very good, but better suited for someone with programming experience making a transition to Python.
Some people love Codecademy, but I felt like they were holding my hand through the lessons and when they let go at the end, I was completely lost. Also, programming in a browser based shell doesn’t feel right. If you really want to learn Python, do it locally, with IDLE or your shell.
My last employer was a lynda.com subscriber, so I took advantage of the opportunity and, well, slept through the Python courses they offered. I find screencasts very hard to watch.
And then there’s the MOOCs: Coursera, edX, and Udacity. I’ve started and never finished courses in each. I find the pace of MOOCs frustratingly slow and unless you’re taking the course in real time, you can’t access the faculty or community for help when you hit a wall. If you have A LOT of time to kill, take these courses. Otherwise, carve your own path. You’ll learn much more and arrive at the same destination much faster.

Conclusion

I hope these suggestions are useful and helpful. At the end of the day, you are your best resource. You drive the learning, don’t let the learning drive you. In the spirit of the origins of the language, the best way to learn Python is with a sense of humor. Now get hacking!

Python Classes and Object Oriented Programming



The class is a fundamental building block in Python. It is the underpinning for not only many popular programs and libraries, but the Python standard library as well. Understanding what classes are, when to use them, and how the can be useful is essential, and the goal of this article. In the process, we'll explore what the term Object-Oriented Programming means and how it ties together with Python classes.

Everything Is An Object...

What is the class keyword used for, exactly? Like its function-based cousin def, it concerns the definitionof things. While def is used to define a function, class is used to define a class. And what is a class? Simply a logical grouping of data and functions (the latter of which are frequently referred to as "methods" when defined within a class).
What do we mean by "logical grouping"? Well, a class can contain any data we'd like it to, and can have any functions (methods) attached to it that we please. Rather than just throwing random things together under the name "class", we try to create classes where there is a logical connection between things. Many times, classes are based on objects in the real world (like Customer or Product). Other times, classes are based on concepts in our system, like HTTPRequest or Owner.
Regardless, classes are a modeling technique; a way of thinking about programs. When you think about and implement your system in this way, you're said to be performing Object-Oriented Programming. "Classes" and "objects" are words that are often used interchangeably, but they're not really the same thing. Understanding what makes them different is the key to understanding what they are and how they work.

..So Everything Has A Class?

Classes can be thought of as blueprints for creating objects. When I define a Customer class using theclass keyword, I haven't actually created a customer. Instead, what I've created is a sort of instruction manual for constructing "customer" objects. Let's look at the following example code:
class Customer(object):
    """A customer of ABC Bank with a checking account. Customers have the
    following properties:

    Attributes:
        name: A string representing the customer's name.
        balance: A float tracking the current balance of the customer's account.
    """

    def __init__(self, name, balance=0.0):
        """Return a Customer object whose name is *name* and starting
        balance is *balance*."""
        self.name = name
        self.balance = balance

    def withdraw(self, amount):
        """Return the balance remaining after withdrawing *amount*
        dollars."""
        if amount > self.balance:
            raise RuntimeError('Amount greater than available balance.')
        self.balance -= amount
        return self.balance

    def deposit(self, amount):
        """Return the balance remaining after depositing *amount*
        dollars."""
        self.balance += amount
        return self.balance
The class Customer(object) line does not create a new customer. That is, just because we've defined aCustomer doesn't mean we've created one; we've merely outlined the blueprint to create a Customer object. To do so, we call the class's __init__ method with the proper number of arguments (minus self, which we'll get to in a moment).
So, to use the "blueprint" that we created by defining the class Customer (which is used to create Customerobjects), we call the class name almost as if it were a function: jeff = Customer('Jeff Knupp', 1000.0). This line simply says "use the Customer blueprint to create me a new object, which I'll refer to as jeff."
The jeff object, known as an instance, is the realized version of the Customer class. Before we calledCustomer(), no Customer object existed. We can, of course, create as many Customer objects as we'd like. There is still, however, only one Customer class, regardless of how many instances of the class we create.

self?

So what's with that self parameter to all of the Customer methods? What is it? Why, it's the instance, of course! Put another way, a method like withdraw defines the instructions for withdrawing money fromsome abstract customer's account. Calling jeff.withdraw(100.0) puts those instructions to use on thejeff instance.
So when we say def withdraw(self, amount):, we're saying, "here's how you withdraw money from a Customer object (which we'll call self) and a dollar figure (which we'll call amount). self is the instance of the Customer that withdraw is being called on. That's not me making analogies, either.jeff.withdraw(100.0) is just shorthand for Customer.withdraw(jeff, 100.0), which is perfectly valid (if not often seen) code.

__init__

self may make sense for other methods, but what about __init__? When we call __init__, we're in the process of creating an object, so how can there already be a self? Python allows us to extend the selfpattern to when objects are constructed as well, even though it doesn't exactly fit. Just imagine that jeff = Customer('Jeff Knupp', 1000.0) is the same as calling jeff = Customer(jeff, 'Jeff Knupp', 1000.0); the jeff that's passed in is also made the result.
This is why when we call __init__, we initialize objects by saying things like self.name = name. Remember, since self is the instance, this is equivalent to saying jeff.name = name, which is the same asjeff.name = 'Jeff Knupp. Similarly, self.balance = balance is the same as jeff.balance = 1000.0. After these two lines, we consider the Customer object "initialized" and ready for use.

Be careful what you __init__

After __init__ has finished, the caller can rightly assume that the object is ready to use. That is, after jeff = Customer('Jeff Knupp', 1000.0), we can start making deposit and withdraw calls on jeffjeff is afully-initialized object.
Imagine for a moment we had defined the Customer class slightly differently:
class Customer(object):
    """A customer of ABC Bank with a checking account. Customers have the
    following properties:

    Attributes:
        name: A string representing the customer's name.
        balance: A float tracking the current balance of the customer's account.
    """

    def __init__(self, name):
        """Return a Customer object whose name is *name* and starting
        balance is 0."""
        self.name = name
        self.balance = 0.0

    def set_balance(self, balance=0.0):
        """Set the customer's starting balance."""
        self.balance = balance

    def withdraw(self, amount):
        """Return the balance remaining after withdrawing *amount*
        dollars."""
        if amount > self.balance:
            raise RuntimeError('Amount greater than available balance.')
        self.balance -= amount
        return self.balance

    def deposit(self, amount):
        """Return the balance remaining after depositing *amount*
        dollars."""
        self.balance += amount
        return self.balance
This may look like a reasonable alternative; we simply need to call set_balance before we begin using the instance. There's no way, however, to communicate this to the caller. Even if we document it extensively, we can't force the caller to call jeff.set_balance(1000.0) before calling jeff.withdraw(100.0). Since thejeff instance doesn't even have a balance attribute until jeff.set_balance is called, this means that the object hasn't been "fully" initialized.
The rule of thumb is, don't introduce a new attribute outside of the __init__ method, otherwise you've given the caller an object that isn't fully initialized. There are exceptions, of course, but it's a good principle to keep in mind. This is part of a larger concept of object consistency: there shouldn't be any series of method calls that can result in the object entering a state that doesn't make sense.
Invariants (like, "balance should always be a non-negative number") should hold both when a method is entered and when it is exited. It should be impossible for an object to get into an invalid state just by calling its methods. It goes without saying, then, that an object should start in a valid state as well, which is why it's important to initialize everything in the __init__ method.

Instance Attributes and Methods

An function defined in a class is called a "method". Methods have access to all the data contained on the instance of the object; they can access and modify anything previously set on self. Because they useself, they require an instance of the class in order to be used. For this reason, they're often referred to as "instance methods".
If there are "instance methods", then surely there are other types of methods as well, right? Yes, there are, but these methods are a bit more esoteric. We'll cover them briefly here, but feel free to research these topics in more depth.

Static Methods

Class attributes are attributes that are set at the class-level, as opposed to the instance-level. Normal attributes are introduced in the __init__ method, but some attributes of a class hold for all instances in all cases. For example, consider the following definition of a Car object:
class Car(object):

    wheels = 4

    def __init__(self, make, model):
        self.make = make
        self.model = model

mustang = Car('Ford', 'Mustang')
print mustang.wheels
# 4
print Car.wheels
# 4
Car always has four wheels, regardless of the make or model. Instance methods can access these attributes in the same way they access regular attributes: through self (i.e. self.wheels).
There is a class of methods, though, called static methods, that don't have access to self. Just like class attributes, they are methods that work without requiring an instance to be present. Since instances are always referenced through self, static methods have no self parameter.
The following would be a valid static method on the Car class:
class Car(object):
    ...
    def make_car_sound():
        print 'VRooooommmm!'
No matter what kind of car we have, it always makes the same sound (or so I tell my ten month old daughter). To make it clear that this method should not receive the instance as the first parameter (i.e. selfon "normal" methods), the @staticmethod decorator is used, turning our definition into:
class Car(object):
    ...
    @staticmethod
    def make_car_sound():
        print 'VRooooommmm!'

Class Methods

A variant of the static method is the class method. Instead of receiving the instance as the first parameter, it is passed the class. It, too, is defined using a decorator:
class Vehicle(object):
    ...
    @classmethod
    def is_motorcycle(cls):
        return cls.wheels == 2
Class methods may not make much sense right now, but that's because they're used most often in connection with our next topic: inheritance.

Inheritance

While Object-oriented Programming is useful as a modeling tool, it truly gains power when the concept ofinheritance is introduced. Inherticance is the process by which a "child" class derives the data and behavior of a "parent" class. An example will definitely help us here.
Imagine we run a car dealership. We sell all types of vehicles, from motorcycles to trucks. We set ourselves apart from the competition by our prices. Specifically, how we determine the price of a vehicle on our lot: $5,000 x number of wheels a vehicle has. We love buying back our vehicles as well. We offer a flat rate - 10% of the miles driven on the vehicle. For trucks, that rate is $10,000. For cars, $8,000. For motorcycles, $4,000.
If we wanted to create a sales system for our dealership using Object-oriented techniques, how would we do so? What would the objects be? We might have a Sale class, a Customer class, an Inventory class, and so forth, but we'd almost certainly have a CarTruck, and Motorcycle class.
What would these classes look like? Using what we've learned, here's a possible implementation of the Carclass:
class Car(object):
    """A car for sale by Jeffco Car Dealership.

    Attributes:
        wheels: An integer representing the number of wheels the car has.
        miles: The integral number of miles driven on the car.
        make: The make of the car as a string.
        model: The model of the car as a string.
        year: The integral year the car was built.
        sold_on: The date the vehicle was sold.
    """

    def __init__(self, wheels, miles, make, model, year, sold_on):
        """Return a new Car object."""
        self.wheels = wheels
        self.miles = miles
        self.make = make
        self.model = model
        self.year = year
        self.sold_on = sold_on

    def sale_price(self):
        """Return the sale price for this car as a float amount."""
        if self.sold_on is not None:
            return 0.0  # Already sold
        return 5000.0 * self.wheels

    def purchase_price(self):
        """Return the price for which we would pay to purchase the car."""
        if self.sold_on is None:
            return 0.0  # Not yet sold
        return 8000 - (.10 * self.miles)

    ...
OK, that looks pretty reasonable. Of course, we would likely have a number of other methods on the class, but I've shown two of particular interest to us: sale_price and purchase_price. We'll see why these are important in a bit.
Now that we've got the Car class, perhaps we should crate a Truck class? Let's follow the same pattern we did for car:
class Truck(object):
    """A truck for sale by Jeffco Car Dealership.

    Attributes:
        wheels: An integer representing the number of wheels the truck has.
        miles: The integral number of miles driven on the truck.
        make: The make of the truck as a string.
        model: The model of the truck as a string.
        year: The integral year the truck was built.
        sold_on: The date the vehicle was sold.
    """

    def __init__(self, wheels, miles, make, model, year, sold_on):
        """Return a new Truck object."""
        self.wheels = wheels
        self.miles = miles
        self.make = make
        self.model = model
        self.year = year
        self.sold_on = sold_on

    def sale_price(self):
        """Return the sale price for this truck as a float amount."""
        if self.sold_on is not None:
            return 0.0  # Already sold
        return 5000.0 * self.wheels

    def purchase_price(self):
        """Return the price for which we would pay to purchase the truck."""
        if self.sold_on is None:
            return 0.0  # Not yet sold
        return 10000 - (.10 * self.miles)

    ...
Wow. That's almost identical to the car class. One of the most important rules of programming (in general, not just when dealing with objects) is "DRY" or "Don't Repeat Yourself. We've definitely repeated ourselves here. In fact, the Car and Truck classes differ only by a single character (aside from comments).
So what gives? Where did we go wrong? Our main problem is that we raced straight to the concrete: Cars and Trucks are real things, tangible objects that make intuitive sense as classes. However, they share so much data and functionality in common that it seems there must be an abstraction we can introduce here. Indeed there is: the notion of Vehicles.

Abstract Classes

Vehicle is not a real-world object. Rather, it is a concept that some real-world objects (like cars, trucks, and motorcycles) embody. We would like to use the fact that each of these objects can be considered a vehicle to remove repeated code. We can do that by creating a Vehicle class:
class Vehicle(object):
    """A vehicle for sale by Jeffco Car Dealership.

    Attributes:
        wheels: An integer representing the number of wheels the vehicle has.
        miles: The integral number of miles driven on the vehicle.
        make: The make of the vehicle as a string.
        model: The model of the vehicle as a string.
        year: The integral year the vehicle was built.
        sold_on: The date the vehicle was sold.
    """

    base_sale_price = 0

    def __init__(self, wheels, miles, make, model, year, sold_on):
        """Return a new Vehicle object."""
        self.wheels = wheels
        self.miles = miles
        self.make = make
        self.model = model
        self.year = year
        self.sold_on = sold_on


    def sale_price(self):
        """Return the sale price for this vehicle as a float amount."""
        if self.sold_on is not None:
            return 0.0  # Already sold
        return 5000.0 * self.wheels

    def purchase_price(self):
        """Return the price for which we would pay to purchase the vehicle."""
        if self.sold_on is None:
            return 0.0  # Not yet sold
        return self.base_sale_price - (.10 * self.miles)
Now we can make the Car and Truck class inherit from the Vehicle class by replacing object in the lineclass Car(object). The class in parenthesis is the class that is inherited from (object essentially means "no inheritance". We'll discuss exactly why we write that in a bit).
We can now define Car and Truck in a very straightforward way:
class Car(Vehicle):

    def __init__(self, wheels, miles, make, model, year, sold_on):
        """Return a new Car object."""
        self.wheels = wheels
        self.miles = miles
        self.make = make
        self.model = model
        self.year = year
        self.sold_on = sold_on
        self.base_sale_price = 8000


class Truck(Vehicle):

    def __init__(self, wheels, miles, make, model, year, sold_on):
        """Return a new Truck object."""
        self.wheels = wheels
        self.miles = miles
        self.make = make
        self.model = model
        self.year = year
        self.sold_on = sold_on
        self.base_sale_price = 10000
This works, but has a few problems. First, we're still repeating a lot of code. We'd ultimately like to get rid ofall repetition. Second, and more problematically, we've introduced the Vehicle class, but should we really allow people to create Vehicle objects (as opposed to Cars or Trucks)? A Vehicle is just a concept, not a real thing, so what does it mean to say the following:
v = Vehicle(4, 0, 'Honda', 'Accord', 2014, None)
print v.purchase_price()
Vehicle doesn't have a base_sale_price, only the individual child classes like Car and Truck do. The issue is that Vehicle should really be an Abstract Base Class. Abstract Base Classes are classes that are only meant to be inherited from; you can't create instance of an ABC. That means that, if Vehicle is an ABC, the following is illegal:
v = Vehicle(4, 0, 'Honda', 'Accord', 2014, None)
It makes sense to disallow this, as we never meant for vehicles to be used directly. We just wanted to use it to abstract away some common data and behavior. So how do we make a class an ABC? Simple! The abcmodule contains a metaclass called ABCMeta (metaclasses are a bit outside the scope of this article). Setting a class's metaclass to ABCMeta and making one of its methods virtual makes it an ABC. A virtualmethod is one that the ABC says must exist in child classes, but doesn't necessarily actually implement. For example, the Vehicle class may be defined as follows:
from abc import ABCMeta, abstractmethod
class Vehicle(object):
    """A vehicle for sale by Jeffco Car Dealership.


    Attributes:
        wheels: An integer representing the number of wheels the vehicle has.
        miles: The integral number of miles driven on the vehicle.
        make: The make of the vehicle as a string.
        model: The model of the vehicle as a string.
        year: The integral year the vehicle was built.
        sold_on: The date the vehicle was sold.
    """

    __metaclass__ = ABCMeta

    base_sale_price = 0

    def sale_price(self):
        """Return the sale price for this vehicle as a float amount."""
        if self.sold_on is not None:
            return 0.0  # Already sold
        return 5000.0 * self.wheels

    def purchase_price(self):
        """Return the price for which we would pay to purchase the vehicle."""
        if self.sold_on is None:
            return 0.0  # Not yet sold
        return self.base_sale_price - (.10 * self.miles)

    @abstractmethod
    def vehicle_type():
        """"Return a string representing the type of vehicle this is."""
        pass
Now, since vehicle_type is an abstractmethod, we can't directly create an instance of Vehicle. As long as Car and Truck inherit from Vehicle and define vehicle_type, we can instantiate those classes just fine.
Returning to the repetition in our Car and Truck classes, let see if we can't remove that by hoisting up common functionality to the base class, Vehicle:
from abc import ABCMeta, abstractmethod
class Vehicle(object):
    """A vehicle for sale by Jeffco Car Dealership.


    Attributes:
        wheels: An integer representing the number of wheels the vehicle has.
        miles: The integral number of miles driven on the vehicle.
        make: The make of the vehicle as a string.
        model: The model of the vehicle as a string.
        year: The integral year the vehicle was built.
        sold_on: The date the vehicle was sold.
    """

    __metaclass__ = ABCMeta

    base_sale_price = 0
    wheels = 0

    def __init__(self, miles, make, model, year, sold_on):
        self.miles = miles
        self.make = make
        self.model = model
        self.year = year
        self.sold_on = sold_on

    def sale_price(self):
        """Return the sale price for this vehicle as a float amount."""
        if self.sold_on is not None:
            return 0.0  # Already sold
        return 5000.0 * self.wheels

    def purchase_price(self):
        """Return the price for which we would pay to purchase the vehicle."""
        if self.sold_on is None:
            return 0.0  # Not yet sold
        return self.base_sale_price - (.10 * self.miles)

    @abstractmethod
    def vehicle_type(self):
        """"Return a string representing the type of vehicle this is."""
        pass
Now the Car and Truck classes become:
class Car(Vehicle):
    """A car for sale by Jeffco Car Dealership."""

    base_sale_price = 8000
    wheels = 4

    def vehicle_type(self):
        """"Return a string representing the type of vehicle this is."""
        return 'car'

class Truck(Vehicle):
    """A truck for sale by Jeffco Car Dealership."""

    base_sale_price = 10000
    wheels = 4

    def vehicle_type(self):
        """"Return a string representing the type of vehicle this is."""
        return 'truck'
This fits perfectly with our intuition: as far as our system is concerned, the only difference between a car and truck is the base sale price. Defining a Motorcycle class, then, is similarly simple:
class Motorcycle(Vehicle):
    """A motorcycle for sale by Jeffco Car Dealership."""

    base_sale_price = 4000
    wheels = 2

    def vehicle_type(self):
        """"Return a string representing the type of vehicle this is."""
        return 'motorcycle'

Inheritance and the LSP

Even though it seems like we used inheritance to get rid of duplication, what we were really doing was simply providing the proper level of abstraction. And abstraction is the key to understanding inheritance. We've seen how one side-effect of using inheritance is that we reduce duplicated code, but what about from the caller's perspective. How does using inheritance change that code?
Quite a bit, it turns out. Imagine we have two classes, Dog and Person, and we want to write a function that takes either type of object and prints out whether or not the instance in question can speak (a dog can't, a person can). We might write code like the following:
def can_speak(animal):
    if isinstance(animal, Person):
        return True
    elif isinstance(animal, Dog):
        return False
    else:
        raise RuntimeError('Unknown animal!')
That works when we only have two types of animals, but what if we have twenty, or two hundred? Thatif...elif chain is going to get quite long.
The key insight here is that can_speak shouldn't care what type of animal it's dealing with, the animal class itself should tell us if it can speak. By introducing a common base class, Animal, that defines can_speak, we relieve the function of it's type-checking burden. Now, as long as it knows it was an Animal that was passed in, determining if it can speak is trivial:
def can_speak(animal):
    return animal.can_speak()
This works because Person and Dog (and whatever other classes we crate to derive from Animal) follow the Liskov Substitution Principle. This states that we should be able to use a child class (like Person or Dog) wherever a parent class (Animal) is expected an everything will work fine. This sounds simple, but it is the basis for a powerful concept we'll discuss in a future article: interfaces.

Summary

Hopefully, you've learned a lot about what Python classes are, why they're useful, and how to use them. The topic of classes and Object-oriented Programming are insanely deep. Indeed, they reach to the core of computer science. This article is not meant to be an exhaustive study of classes, nor should it be your only reference. There are literally thousands of explanations of OOP and classes available online, so if you didn't find this one suitable, certainly a bit of searching will reveal one better suited to you.