Facebook SDK

Tuesday, April 1, 2014

Beginning Python Tutorial (Part 12)

Getting Classier

The last time we met I told you some of the basics about using Python classes and object-oriented programming. Today we will delve more into classes and see how they make programming life better.

Inheritance

First off, classes allow you to modify a program without really making changes to it. To elaborate, by subclassing a class, you can change the behavior of the program by simply adding new components to it rather than rewriting the existing components.
As we’ve seen, an instance of a class inherits the attributes of that class. However, classes can also inherit attributes from other classes. Hence, a subclass inherits from a superclass allowing you to make a generic superclass that is specialized via subclasses. The subclasses can override the logic in a superclass, allowing you to change the behavior of your classes without changing the superclass at all.
Let’s make a simple example. First make a class:
Generic Code Example:
>>>class FirstClass:           #define the superclass
… def setdata(self, value):    #define methods
…  self.data = value    #’self’ refers to an instance
… def display(self):  
…  print self.data
…
Then we make a subclass:
Generic Code Example:
>>>class SecondClass(FirstClass): #inherits from FirstClass
… def display(self):  #redefines ‘display’
…  print “Current value = ‘%s’” % self.data
…
As you can see, SecondClass “overwrites” the display method. When a FirstClass instance is created, all of its actions will be taken from the methods defined in FirstClass. When a SecondClass instance is created, it will use the inherited setdata method from FirstClass but the display method will be the one from SecondClass.
To make this easier to understand, here are some examples in practice.
Generic Code Example:
>>>x=FirstClass() #instance of FirstClass
>>>y=SecondClass() #instance of SecondClass
>>>x.setdata(“The boy called Brian.”)
>>>y.setdata(42)
>>>x.display()
The boy called Brian.
>>>y.display()
Current value = ‘42’
Both instances (x and y) use the same setdata method from FirstClass; x uses it because it’s an instance of FirstClass while y uses it because SecondClass inherits setdata from FirstClass. However, when the display method is called, x uses the definition from FirstClass but y uses the definition from SecondClass, where display is overridden.
Because changes to program logic can be made via subclasses, the use of classes generally supports code reuse and extension better than traditional functions do. Functions have to be rewritten to change how they work whereas classes can just be subclassed to redefine methods.
On a final note, you can use multiple inheritance (adding more than one superclass within the parenthesis) if you need a class that belongs to different groups. In theory this is good because it should cut down on extra work. For example, a person could be a chef, a musician, a store owner, and a programmer; the person could inherit the properties from all of those roles. But in reality it can be a real pain to manage the multiple inheritance sets. You have to ask yourself, “Is it really necessary that this class inherit from all of these others?”; more often than not the answer is, “No”.
Using multiple inheritance is considered an “advanced technique” and therefore I won’t discuss it. Actually, I don’t use it; if I encounter a situation where I could use it, I will try and rethink the program’s structure to avoid using it. It’s kind of like normalizing databases; you keep breaking it down until it’s as simple as you can get it. If you still need multiple inheritance, then I recommend getting a book

Operator Overloads

Operator overloading simply means that objects that you create from classes can respond to actions (operations) that are already defined within Python, such as addition, slicing, printing, etc. Even though these actions can be implemented via class methods, using overloading ties the behavior closer to Python’s object model and the object interfaces are more consistent to Python’s built-in objects, hence overloading is easier to learn and use.
User-made classes can override nearly all of Python’s built-in operation methods. These methods are identified by having two underlines before and after the method name, like this: __add__. These methods are automatically called when Python evaluates operators; if a user class overloads the __add__ method, then when an expression has “+” in it, the user’s method will be used instead of Python’s built-in method.
Using an example from Learning Python, here is how operator overloading would work in practice:
Generic Code Example:
>>>class ThirdClass(SecondClass): #is-a SecondClass
… def __init__(self, value): #on “ThirdClass(value)”
…  self.data = value
… def __add__(self, other): # on “self + other”
…  return ThirdClass(self.data + other)
… def __mul__(self, other): #on “self * other”
…  self.data = self.data * other
…
>>>a = ThirdClass(“abc”) #new __init__ called
>>>a.display()   #inherited method
Current value = ‘abc’
>>>b = a + “xyz”  #new __add__ called: makes a new instance
>>>b.display()
Current value = ‘abcxyz’
>>>a*3   #new __mul__ called: changes instance in-place
>>>a.display()
Current value = ‘abcabcabc’
ThirdClass is technically a subclass of SecondClass but it doesn’t override any of SecondClass’ methods. If you wanted, you could put the methods from ThirdClass in SecondClass and go from there. However, creating a new subclass allows you flexibility in your program.
When a new instance of ThirdClass is made, the __init__ method takes the instance-creation argument and assigns it to self.data.ThirdClass also overrides the “+” and “*” operators; when one of these is encountered in an expression, the instance object on the left of the operator is passed to the self argument and the object on the right is passed to other. These methods are different from the normal way Python deals with “+” and “*” but they only apply to instances of ThirdClass. Instances of other classes still use the built-in Python methods.
One final thing to mention about operator overloading is that you can make your custom methods do whatever you want. However, common practice is to follow the structure of the built-in methods. That is, if a built-in method creates a new object when called, your overriding method should too. This reduces confusion when other people are using your code. Regarding the example above, the built-in method for resolving “*” expressions creates a new object (just like how the “+” method does), therefore the overriding method we created should probably create a new object too, rather than changing the value in place as it currently does. You’re not obligated to “follow the rules” but it does make life easier when things work as expected.

Class Methods

Instance methods (which is what we’ve been using so far) and class methods are the two ways to call Python methods. As a matter of fact, instance methods are automatically converted into class methods by Python.
Here’s what I’m talking about. Say you have a class:
Generic Code Example:
class PrintClass:
 def printMethod(self, input):
  print input
Now we’ll call the class’ method using the normal instance method and the “new” class method:
Generic Code Example:
>>>x = PrintClass()
>>>x.printMethod(“Try spam!”) #instance method
Try spam!
>>>PrintClass.printMethod(x, “Buy more spam!”) #class method
Buy more spam!
So, what is the benefit of using class methods? Well, when using inheritance you can extend, rather than replace, inherited behavior by calling a method via the class rather than the instance.
Here’s a generic example:
Generic Code Example:
>>>class Super:
… def method(self):
…  print “now in Super.method”
…
>>>class Subclass(Super):
… def method(self):    #override method
…  print “starting Subclass.method”    #new actions
…  Super.method(self)    #default action
…  print “ending Subclass.method”
…
>>>x = Super() #make a Super instance
>>>x.method() #run Super.method
now in Super.method
>>>x = Subclass() #make a Subclass instance
>>>x.method()  #run Subclass.method which calls Super.method
starting Subclass.method
now in Super.method
ending Subclass.method
Using class methods this way, you can have a subclass extend the default method actions by having specialized subclass actions yet still call the original default behavior via the superclass. Personally, I haven’t used this yet but it is nice to know that it’s available if needed.

Have you seen my class?

There is more to classes than I have covered here but I think I’ve covered most of the basics. Hopefully you have enough knowledge to use them; the more you work with them the easier they are to figure out. I may have mentioned it before, but it took me almost six months to get my head around using classes. Objects were a new area for me and I couldn’t figure out how everything worked. It didn’t help that my first exposure to them was Java and C++; my two textbooks just jumped right into using objects and classes without explaining the how's and why's of them. I hope I did better explaining them than my text books did.

There are several “gotchas” when using classes, such as learning the difference between “is-a” and “has-a” relationships, but most of them are pretty obvious, especially when you get error messages. If you really get stumped, don’t be afraid to ask questions. Remember, we were all beginners once and so many of us have encountered the same problem before.

Beginning Python Tutorial (Part 11)

Learning Python Classes

The class is the most basic component of object-oriented programming. Previously, you learned how to use functions to make your program do something. Now will move into the big, scary world of Object-Oriented Programming (OOP).
To be honest, it took me several months to get a handle on objects. When I first learned C and C++, I did great; functions just made sense for me. Having messed around with BASIC in the early '90s, I realized functions were just like subroutines so there wasn't much new to learn. However, when my C++ course started talking about objects, classes, and all the new features of OOP, my grades definitely suffered.
Once you learn OOP, you'll realize that it's actually a pretty powerful tool. Plus many Python libraries and APIs use classes, so you should at least be able to understand what the code is doing.
One thing to note about Python and OOP: it's not mandatory to use objects in your code. As you've already seen, Python can do just fine with functions. Unlike languages such as Java, you aren't tied down to a single way of doing things; you can mix functions and classes as necessary in the same program. This lets you build the code in a way that works best; maybe you don't need to have a full-blown class with initialization code and methods to just return a calculation. With Python, you can get as technical as you want.

How are classes better?

Imagine you have a program that calculates the velocity of a car in a two-dimensional plane using functions. If you want to make a new program that calculates the velocity of an airplane in three dimensions, you can use the concepts of your car functions to make the airplane model work, but you'll have to rewrite the many of the functions to make them work. You may be lucky and can copy and paste some of them, but for the most part you'll have to redo much of the work.
Classes let you define an object once, then reuse it multiple times. You can give it a base function (called amethod in OOP parlance) then build upon that method to redefine it as necessary. It also lets you model real-world objects much better than using functions.
For example, you could make a tire class that defines the size of the tire, how much pressure it holds, what it's made of, etc. then make methods to determine how quickly it wears down based on certain conditions. You can then use this tire class to make a car class, a bicycle class, or whatever. Each use of the tire class (calledinstances) would use different properties of the base tire object. If the base tire object said it was just made of rubber, perhaps the car class would "enhance" the tire by saying it had steel bands or maybe the bike class would say it has an internal air bladder. This will make more sense later.

Improving Your Class Standing

Several concepts of classes are important to know. First, classes have a definite namespace, just like modules. Trying to call a class method from a different class will give you an error unless you qualify it, e.g.fooClass.barMethod().
Second, classes support multiple copies. This is because classes have two different objects: class objects and instance objects. Class objects give the default behavior and are used to create instance objects. Instance objects are the objects that actually do the work in your program. You can have as many instance objects of the same class object as you need.
Third, each instance object has its on namespace but also inherits from the base class object. This means each instance has the same default namespace components as the class object, but additionally each instance can make new namespace objects just for itself.
Finally, classes can define objects that respond to the same operations as built-in types. So class objects can be sliced, indexed, concatenated, etc. just like strings, lists, and other standard Python types. This is because everything in Python is actually a class object; we aren't actually doing anything new with classes, we're just learning how to better use the inherent nature of the Python language.
Here's a brief list of Python OOP:
  • The class statement creates a class object and gives it a name. This creates a new namespace.
  • Assignments within the class create class attributes. These attributes are accessed by qualifying the name: object.name.
  • Class attributes export the state of an object and its associated behavior. These attributes are shared by all instances of a class.
  • Calling a class (just like a function) creates a new instance of the class. This is where the multiple copies part comes in.
  • Each instance gets ("inherits") the default class attributes and gets its own namespace. This prevents instance objects from overlapping and confusing the program.
  • Using the term self identifies a particular instance, allowing for per-instance attributes. This allows items such as variables to be associated with a particular instance.

So What Does a Class Look Like?

Before we leave this particular tutorial, I'll give you some quick examples to explain what I've talked about so far. Assuming your using the Python interactive interpreter, here's how a simple class would look like.
Python Code Example:
>>> class Hero: #define a class object
...        def setName(self, value): #define class methods
...            self.name = value #self identifies a particular instance
...        def display(self):
...            print self.name  #print the data for a particular instance
Notice a few things with this example.
  1. When the class object is defined, there are no parenthesis at the end; parenthesis are only used for functions and methods.
  2. The first argument for a class method must be self. This is used to identify the instance calling the method. The Python interpreter handles the calls internally. All you have to do is make sure self is where it's supposed to be so you don't get an error.
  3. When you are assigning variables, like self.name, the variable must be qualified with the "self" title. Again, this is used to identify a particular instance.
So, lets make a few instances to see how this works:
Python Code Example:
>>> x = Hero()
>>> y = Hero()
>>> z = Hero()
Here you'll notice that parenthesis make an appearance. This is to signify that these are instance objects created from the Hero class. Each one of these instances has the exact same attributes, derived from the Hero class. (Later on I'll show you how to customize an instance to do more than the base class).
Now, lets add some information.
Python Code Example:
>>> x.setName("Arthur, King of the Britons")
>>> y.setName("Sir Lancelot, the Brave")
>>> z.setName("Sir Robin, the Not-Quite-So-Brave-As-Sir-Lancelot")
These call the setName() method that sits in the Hero class. However, as you know by now, each one is for a different instance meaning not only do x, y, and z each have a different value, but the original value in Hero is left untouched.
If you now call the display() method for each instance, you should see the name of each hero.
Python Code Example:
>>> x.display()
Arthur, King of the Britons
>>> y.display()
Sir Lancelot, the Brave
>>> z.display()
Sir Robin, the Not-Quite-So-Brave-As-Sir-Lancelot
You can change instance attributes "on the fly" simply by assigning to self in methods inside the class object or via explicitly assigning to instance objects.
Python Code Example:
>>> x.name = "Sir Galahad, the Pure"
>>> x.display()
Sir Galahad, the Pure
That's probably enough for this lesson. I'll cover the rest of classes in a later tutorial but this is hopefully enough to give you an idea of how useful classes and OOP in general can be when programming. The vast majority of languages in current use implement OOP to one extent or another, so learning how to use classes and objects will help you out as you gain knowledge. Thankfully Python implements OOP in a reasonable way, so it's relatively painless to learn in Python rather than something like C++, at least in my experience.

Y'all come back now, ya hear? :P

Beginning Python Tutorial (Part 10)

Welcome back

Well, it's been quite some time since my last Python tutorial. I got sidetracked by actually trying to make some programs using Python. Some worked well, some not so well. But I learned from my mistakes and have a better grasp of how to use Python.
After having used it for almost two years now, I've come to find that Python is an extremely capable language, equal in power to C++, Java, et al. If you don't need the "finesse" the major languages provide, I highly recommend learning Python or another dynamic language like Ruby. You'll program faster with fewer errors (like memory management) and can harness the power of a built-in GUI for rapid prototyping of applications. You can also use these languages for quick scripts to speed repetitive tasks. Plus, they are inherently cross-platform so you can easily switch between OSes or find a larger market for your programs. Heck, Python is used extensively by Google, NASA, and many game publishers, so it can't be that bad.
One of the biggest complaints people have is the forced use of white space and indentation. But if you think about it, that's considered a "good coding practice"; it makes it easier to follow the flow of the program and reduces the chance of errors. Plus, since brackets are required, you don't have to worry about your program not working because you forgot to close a nested if statement. After a few days of using Python, you won't even notice, though I imagine you'll notice how "sloppy" other languages look.
Now, on with the show...

Making Python Do Something

So far I've talked about how Python is structured and how it differs from other languages. Now it's time to make some real programs. (Of course, if you've perused GIDForums' Python section, you've seen several programs I wrote already; good or bad, they are good at showing how Python works).
Python programs are comprised of functions, classes, modules, and packages.
  1. Functions are programmer created code blocks that do a specific task.
  2. Classes are object-oriented structures that I'll talk about later; suffice to say they are pretty powerful structures that can make programming life easier, though they can be difficult to learn and wield well.
  3. Modules are generally considered normal program files, i.e. a file comprised of functions/classes, loops, control statements, etc.
  4. Packages are programs made up of many different modules.
In reality, I consider modules and packages to be "programs". It just depends on how many separate files are required to make the program run. Yes, it is possible to have a single, monolithic file that controls the entire program but it's usually better to have different parts in different files. It's actually easier to keep track of what's going on and you can cluster bits of code that have common goals, e.g. have a file that holds library functions, one that handles the GUI, and one that processes data entry.
An important module to know is the Python standard library. The library is a collection of common code blocks that you can call when needed. This means you don't have to "rebuild the wheel" every time you want to do something, such as calculate the tangent of a function. All you have to do is import the portion of the standard library you need, e.g. the math block, and then use it like regular Python code. Knowing what's in the standard library separates the good programmers from the great ones, at least in my book.
That being said, let's make a simple Python program.
Python Code Example:
def square(x): #define the function
 return x * x #pass back to caller the square of a number

for y in range(1, 11): #cycle through a list of numbers
 print square(x) #print the square of a number
This is about as simple as it gets. First we define the function called square and tell it that the argument calledx will be used for processing. Then we actually define what the function will do; in this case, it will multiply xtimes itself to produce a square. By using the keyword return, the square value will be given back to whatever actually called the function (the print statement).
Next we create a for loop that prints the squared value of each number as it increases from 1 to 11. This should be fairly easy to follow, especially with the comments off to the side. Please realize that most programs you'll see aren't commented this much; quite often, the programs aren't commented at all. I like to think that I have a sufficient amount of documentation in my code (see GIDForums) that it's pretty easy for even new programmers to figure out what's going on.

Scope

What? you didn't know snakes got bad breath? (I know, bad joke.) Seriously though, scope describes the area of a program where an identifier (a name for something, like a variable) can access the it's associated value. Scope ties in with namespaces because namespaces pretty much define where an identifier's scope is.
In simple terms, namespaces store information about an identifier and it's value. Python has three namespaces:localglobal, and built-in. When an identifier is first accessed, Python looks for it's value locally, i.e. it's surrounding code block. In the example above, x is defined within the function square. Every function is assigned its own local namespace. Functions can't use identifiers defined in other functions; they're simply not seen. If a function tries to call a variable defined in another function, you'll get an error. If a function tried to define a previously defined variable, you'll just get a brand new variable that happens to have the same name but a different value.
However, if an identifier isn't defined locally, Python will check if it's in the global namespace. The global namespace is different from the local one in that global identifiers can be used by other functions. So if you made global variable cars_in_shop = 2, all functions in the program can access that variable and use it as needed. So you can define a variable in one location and have it used in multiple places without having to make it over and over.
The built-in namespace is set aside for Python's built-in functions. (Kinda convenient, huh?) So keywords and standard function calls like range() are already defined when the Python interpreter starts up and you can use them "out of the box".
As you may have figured out, namespaces are nested:
Generic Code Example:
built-in
    |--global
            |--local
If an identifier isn't found locally, Python will check the global namespace. If it's not there Python will check the built-in namespace. If it still can't find it, it coughs up and error and dies.
One thing to consider (and I touched on slightly) is that you can hide identifiers as you go down the namespace tree. If you have cars_in_shop = 2 defined globally, you can make a function that has the exact same name with a different value, e.g. cars_in_shop = 15. When the function calls this variable, it will use the value of 15 vs. 2 to calculate the result. This can cause problems if you don't have good variable names since you may forget which variable you're actually using.

Default Arguments

When you create a function, you can set it up to use default values for it's arguments, just in case the item calling it doesn't have any arguments. For example:
Python Code Example:
def perimeter(length = 1, width = 1): 
 return length * width
If you want to call this particular function, you can supply it with the necessary measurements (perimeter(15, 25) ) or you can supply one ( perimeter(7) ) or you can just use the defaults (perimeter() ). Each argument is matched to the passed in values, in order, so if you're going to do this make sure you know which arguments are going to be matched.
You can also use keyword arguments, which match arguments based on a corresponding keyword. This way, you don't have to worry about the order they are given. See the examples in the comments thread.
That's about it for programming with functions. Their pretty simple and the more examples you see, the more they'll make sense. Python is cool since you can mix functions and classes (with methods) in the same module without worrying about errors. This way you aren't constrained to one way of programming; if a short function will work, you don't have to take the time to make a full-blown class with a method to do the same thing.
If you don't want to deal with object-oriented programming, you can stick with functions and have a good time. However, I'll start to cover OOP in later tutorials to show you why it's good to know and use. And with Python, it's not as scary as OOP implementation in other languages.
Thanks for reading.

Beginning Python Tutorial (Part 9)

Documenting Python Code

Some of this information is borrowed from Dive Into Python, a free Python programming book for experienced programmers. Other info is from the Python Style Guide.
You can document a Python function by giving it a doc string.
Python Code Example:
def buildConnectionString(params):
    """Build a connection string from a dictionary of parameters.

    Returns string."""
As noted previously, triple quotes signify a multi-line string. Everything between the start and end quotes is part of a single string, including carriage returns and other quote characters. You'll see them most often used when defining a doc string.
Everything between the triple quotes is the function's doc string, which documents what the function does. A doc string, if it exists, must be the first thing defined in a function (that is, the first thing after the colon).
You don't technically need to give your function a doc string, but you always should; the doc string is available at runtime as an attribute of the function. Many Python IDEs use the doc string to provide context-sensitive documentation, so that when you type a function name, its doc string appears as a tooltip.
From the Python Style Guide:
The doc string of a script should be usable as its "usage" message, printed when the script is invoked with incorrect or missing arguments (or perhaps with a "-h" option, for "help"). Such a doc string should document the script's function and command line syntax, environment variables, and files. Usage messages can be fairly elaborate (several screenfuls) and should be sufficient for a new user to use the command properly, as well as a complete quick reference to all options and arguments for the sophisticated user.
There are two forms of doc strings: one-liners and multi-line doc strings. One-liners are exactly that: information that doesn't need a lot of descriptive text to explain what's going on. Triple quotes are used even though the string fits on one line to make it easy to later expand it. The closing quotes are on the same line as the opening quotes, since it looks better. There's no blank line either before or after the doc string. The doc string is a phrase ending in a period. It prescribes the function's effect as a command ("Do this", "Return that"), not as a description: e.g. don't write "Returns the pathname ..."
Example:
Python Code Example:
def kos_root():
    """Return the pathname of the KOS root directory."""
    global _kos_root
    if _kos_root: return _kos_root
    #...
Multi-line doc strings start out just like a single line doc string. The first line is a summary but is then followed by a blank line. After the blank line more descriptive discussion can be made. The blank line is used to seperate the summary from descriptive info for automatic indexing tools. They will use the one-line summary to create a documentation index, allowing the programmer to do less work.
When continuing your doc string after the blank line, make sure to follow the indentation rules for Python, i.e. after the blank line all of your doc string info is indented as far as the initial triple-quote.
More info from the Python Style Guide:
The doc string for a module should generally list the classes, exceptions and functions (and any other objects) that are exported by the module, with a one-line summary of each. (These summaries generally give less detail than the summary line in the object's doc string.)
The doc string for a function or method should summarize its behavior and document its arguments, return value(s), side effects, exceptions raised, and restrictions on when it can be called (all if applicable). Optional arguments should be indicated. It should be documented whether keyword arguments are part of the interface.
The doc string for a class should summarize its behavior and list the public methods and instance variables. If the class is intended to be subclassed, and has an additional interface for subclasses, this interface should be listed separately (in the doc string). The class constructor should be documented in the doc string for its __init__ method. Individual methods should be documented by their own doc string.
If a class subclasses another class and its behavior is mostly inherited from that class, its doc string should mention this and summarize the differences. Use the verb "override" to indicate that a subclass method replaces a superclass method and does not call the superclass method; use the verb "extend" to indicate that a subclass method calls the superclass method (in addition to its own behavior).
Python is case sensitive and the argument names can be used for keyword arguments, so the doc string should document the correct argument names. It is best to list each argument on a separate line, with two dashes separating the name from the description
If you've made it this far, I'll help you out and summarize what you just learned. Python has a documentation feature called doc string that allows you to use comments to create self-documenting source code. Several Python IDE's, such as SPE, can use these doc strings to create a listing of your source code structures, such as classes and modules. This makes it easier on the programmer since less work is required when you create your help files and other program documentation. Documentation indexers can pull the doc strings out of your code and make a listing for you, or you could even make your own script to create it for you.
However, the only way to harness the power of doc strings is to follow the style rules Python expects, meaning you have to use triple-quotes, separate your summary line from the full-blown description, etc. You can document your Python code without following these rules but then it's up to you to create a help file or whatever.

Not only will it make your life easier when you finish your project, but it also makes your code easier to read and follow. (Wish the people at my work could learn how to document their code. Even just a few comments explaining what a function does would help. :) )