Showing posts with label +. Show all posts
Showing posts with label +. Show all posts

Saturday, 16 April 2016

Classes 5: Inheritance

The key defining feature of any object orientated programming language is the concept of inheritance. Just as you and I can inherit property, cash or genetic traits from our parents, grandparents and other ancestors. Python objects like classes can inherit attributes, properties and methods from their ancestors. Which also includes any built in object.

The following examples will show how the basic mechanics of inheritance currently work in Python 3.x.x. The first example simply shows a child class inheriting a method from a parent class. The critical lesson to learn here is the manner in which we tell the Python interpreter that we want the child class to inherit this method in the first place.

Note that the syntax, the manner in which we write the code, is exactly the same as when we define a parameter Python should expect to be passed to a function or method. So there is nothing especially new or difficult to get to grips with here. When it comes time to call the inherited method however. We don't reference the parent. We only ever reference the child as though the method was defined as part of the child class from the get go.

#!/usr/bin/env python3

__project__= "Python Classes: Inheritance"
__author__ = "Kevin Lynch"
__version__ = "$Revision: 1 $"
__date__ = "$Date: 2016/04/14 22:06:00 $"
__copyright__ = "Copyright (c) 2016 Kevin Lynch"
__license__ = "GPLv3"

# Define the parent class. It contains 1 method.
class parentClass():
        def parentMessage(self,text):
                print(text)
                
# Define the child class. It contains no methods, attributes or properties.
class childClass(parentClass):
        pass

# Main Program and Global Variables.
child = childClass()
child.parentMessage("Text is printing from parent.")

Most people however have 2 parents. And in Python our child class can also have 2 parents. In fact it can have a lot more than 2. The second example shows this concept of inheritance from multiple parent classes.

#!/usr/bin/env python3

__project__= "Python Classes: Inheritance"
__author__ = "Kevin Lynch"
__version__ = "$Revision: 2 $"
__date__ = "$Date: 2016/04/14 22:06:00 $"
__copyright__ = "Copyright (c) 2016 Kevin Lynch"
__license__ = "GPLv3"

# Define the parent classes. They contain 1 method each.
class fatherClass():
        def fatherMessage(self,text):
                print(text)

class motherClass():
        def motherMessage(self,text):
                print(text)
                
# Define the child class. It contains no methods, attributes or properties.
class childClass(fatherClass,motherClass):
        pass

# Main Program and Global Variables.
child = childClass()
child.fatherMessage("Text is printing from father.")
child.motherMessage("Text is printing from mother.")

Just as in real life. This ancestral linage of our child class does not stop with it's parent classes. If the father class inherits a method, attribute or property from a grandfather class. Then so too will the child class. As is shown in example 3.

#!/usr/bin/env python3

__project__= "Python Classes: Inheritance"
__author__ = "Kevin Lynch"
__version__ = "$Revision: 3 $"
__date__ = "$Date: 2016/04/14 22:06:00 $"
__copyright__ = "Copyright (c) 2016 Kevin Lynch"
__license__ = "GPLv3"

# Define the ancestor classes. They contain 1 method each.
class grandfatherClass():
        def grandfatherMessage(self):
                print("This text is printing from grandfatherMessage().")

class fatherClass(grandfatherClass):
        def fatherMessage(self):
                print("This text is printing from fatherMessage().")
                
# Define the child class. It contains no methods, attributes or properties.
class childClass(fatherClass):
        pass

# Main Program and Global Variables.
grandfather = grandfatherClass()
father = fatherClass()
child = childClass()

print("\ngrandfather:")
grandfather.grandfatherMessage()

print("\nfather:")
father.grandfatherMessage()
father.fatherMessage()

print("\nchild:")
child.grandfatherMessage()
child.fatherMessage()

There are however occasions when inherited features need to be overridden. Creating a new class based on an existing class can save us a lot of time and code. This makes our program more efficient since we get to reuse code in much the same way we can reuse functions. However we might need to override an inherited method because it doesn't do exactly what we need it to do.

Python allows us to do this simply by redefining the method at the point in the ancestral lineage where we wish the new version of the method to take effect. In the fourth example below. We override the method we inherited from the grandfatherClass within the childClass.

By doing this we don't need to redefine the entire grandfatherClass. Which means the fatherClass and any objects based on it alone will be unaffected as will any objects based on the grandfatherClass.

#!/usr/bin/env python3

__project__= "Python Classes: Inheritance"
__author__ = "Kevin Lynch"
__version__ = "$Revision: 4 $"
__date__ = "$Date: 2016/04/14 22:06:00 $"
__copyright__ = "Copyright (c) 2016 Kevin Lynch"
__license__ = "GPLv3"

# Define the ancestor classes. They contain 1 method each.
class grandfatherClass():
        def grandfatherMessage(self):
                print("This text is printing from grandfatherMessage().")

class fatherClass(grandfatherClass):
        def fatherMessage(self):
                print("This text is printing from fatherMessage().")
                
# Define the child class. It has 1 method to override grandfatherMessage(self).
class childClass(fatherClass):
        def grandfatherMessage(self):
                print("The child has overridden the grandfather!!!")

# Main Program and Global Variables.
grandfather = grandfatherClass()
father = fatherClass()
child = childClass()

print("\ngrandfather:")
grandfather.grandfatherMessage()

print("\nfather:")
father.grandfatherMessage()
father.fatherMessage()

print("\nchild:")
child.grandfatherMessage()
child.fatherMessage()

Inheritance and the ability to override things presents us with a problem however. There is nothing stopping us from defining attributes, properties or methods with the same name in each of the classes we create. This means the names of inherited class members can come into conflict. Many developers assign common names to common functions. But the code within will all be written slightly differently to produce different outcomes. To make sure our programs behave as we expect them to, Python has a set of rules. These rules dictate how Python searches through the ancestral lineage to find the inherited class member.

It should become clear from the next two examples that Python will search top to bottom and left to right. In other words Python will search through the entire lineage of the left-most parent class stated in our child class definition before moving onto the next parent.

In the case of our example that means searching the lineage of fatherClass for the parentMessage() method before moving onto motherClass. And since it will find this method in the grandfatherClass, it will use this version of the method.

Another interesting point to note here is that grandfatherClass is an ancestor of fatherClass. But not motherClass.

#!/usr/bin/env python3

__project__= "Python Classes: Inheritance"
__author__ = "Kevin Lynch"
__version__ = "$Revision: 5 $"
__date__ = "$Date: 2016/04/14 22:06:00 $"
__copyright__ = "Copyright (c) 2016 Kevin Lynch"
__license__ = "GPLv3"

# Define the ancestor classes. They contain 1 method each.
class grandfatherClass():
        def grandfatherMessage(self):
                print("This text is printing from grandfatherMessage().")

class fatherClass(grandfatherClass):
        def parentMessage(self):
                print("From fatherClass():")
                print("This text is printing from parentMessage().")

class motherClass():
        def parentMessage(self):
                print("From motherClass():")
                print("This text is printing from parentMessage().")
                                
# Define the child classes. They contain no methods, attributes or properties.
class child1Class(fatherClass,motherClass):
        pass

class child2Class(motherClass,fatherClass):
        pass

# Main Program and Global Variables.
grandfather = grandfatherClass()
father = fatherClass()
mother = motherClass()
child1 = child1Class()
child2 = child2Class()

print("\ngrandfather:")
grandfather.grandfatherMessage()

print("\nfather:")
father.grandfatherMessage()
father.parentMessage()

print("\nmother:")
mother.parentMessage()

print("\nchild1:")
child1.grandfatherMessage()
child1.parentMessage()

print("\nchild2:")
child2.grandfatherMessage()
child2.parentMessage()

If we switch the order fatherClass and motherClass are passed to childClass. We can see that Python will now search for the parentMessage() method in motherClass first. And therefore use the motherClass version of that method.

#!/usr/bin/env python3

__project__= "Python Classes: Inheritance"
__author__ = "Kevin Lynch"
__version__ = "$Revision: 6 $"
__date__ = "$Date: 2016/04/14 22:06:00 $"
__copyright__ = "Copyright (c) 2016 Kevin Lynch"
__license__ = "GPLv3"

# Define the ancestor classes. They contain 1 method each. Except for
# fatherClass(). It inherits everything from grandfatherClass().
class grandfatherClass():
        def grandfatherMessage(self):
                print("This text is printing from grandfatherMessage().")

        def parentMessage(self):
                print("From grandfatherClass():")
                print("This text is printing from parentMessage().")

class fatherClass(grandfatherClass):
        pass
        
class motherClass():
        def parentMessage(self):
                print("From motherClass():")
                print("This text is printing from parentMessage().")
                                
# Define the child classes. They contain no methods, attributes or properties.
class child1Class(fatherClass,motherClass):
        pass

class child2Class(motherClass,fatherClass):
        pass

# Main Program and Global Variables.
grandfather = grandfatherClass()
father = fatherClass()
mother = motherClass()
child1 = child1Class()
child2 = child2Class()

print("\ngrandfather:")
grandfather.grandfatherMessage()
grandfather.parentMessage()

print("\nfather:")
father.grandfatherMessage()
father.parentMessage()

print("\nmother:")
mother.parentMessage()

print("\nchild1:")
child1.grandfatherMessage()
child1.parentMessage()

print("\nchild2:")
child2.grandfatherMessage()
child2.parentMessage()

Sunday, 10 April 2016

Classes 4: Encapsulation

Encapsulation can be a bit of a sticky subject. Many people have strong views on the subject and others just don't care. But what is it? Basically it is two distinct but related concepts. We can make class members like attributes private or protected. This stops anything outwith the class from accessing those members directly. We can also bundle data with its associated method. Which we did in Classes 3: Properties.

When we decide to make a class member like an attribute private. We have basically made the decision that it must be protected from the outside world. And this I think is the biggest problem with the whole concept when we have direct access to the source code. Nothing is really protected because with direct access to the source code. We can change whatever we want.

For this reason it is better to think in terms of a compiled program or library that might be shared with many people outside your organisation. Normally an outsider would access your class using the documented API. An analogy might be a customer at a bank.

A bank is a class of business. An attribute of a bank is that it holds customer accounts. Each account has a value. The amount of cash associated with the account. Account attributes of bank classes are however private. The method we use to access the account's value is the clerk. The clerk is the getter. If we give the clerk the correct information, which is different for every customer account and thus variable, the clerk will return the value of the account. We get our money.

We can put this analogy into action with the following example. After we create accounts for Bob and Sue with the bank class, the only way to access those accounts is through clerk method. All of the attributes are private.

#!/usr/bin/env python3

__project__= "Python Classes: The Bank Example"
__author__ = "Kevin Lynch"
__version__ = "$Revision: 1 $"
__date__ = "$Date: 2016/04/11 15:23:00 $"
__copyright__ = "Copyright (c) 2016 Kevin Lynch"
__license__ = "GPLv3"

# Create the bank class.
class bank:
        # Initialise bank with custom attributes.
        def __init__(self,account,pin,cash):
                # This is a bank. So all attributes are private.
                self.__account = account
                self.__pin = pin
                self.__cash = cash
                
        # Create the getter method.
        def clerk(self,account,pin):
                if account == self.__account:
                        if pin == self.__pin:
                                return str(self.__cash) # We get our money.
                        else:
                                return "CALLED THE COPS!!!" # Wrong pin code.
                else:
                        return "no such account" # Wrong account number.

# Global variables
bobsAccount = bank(12345678,9990,500)
suesAccount = bank(87654321,2204,5)

# We can ask the clerk how much money Bob and Sue have.
print("Bob has " + bobsAccount.clerk(12345678,9990) + " in the bank.\n\n")
print("Sue has " + suesAccount.clerk(87654321,2204) + " in the bank.\n\n")

# Sue forgot her pin code and used Bob's instead.
print("Sue has " + suesAccount.clerk(87654321,9990) + " in the bank.\n\n")

# Bob can't remember his account number.
print("Bob has " + bobsAccount.clerk(12945070,9990) + " in the bank.\n\n")

# Uncomment the following code to prove the attributes are private.
# print("Bob has " + str(bobsAccount.__cash) + " in the bank.\n\n")

The Big Lie
Uncommenting the last line of code in the example seems to prove the attributes of bank are indeed private. But this is not actually the case. Everything in Python is public. We just need to know where to look.

Every Python object has a number of built-in attributes and methods that are added automatically. The method __init__() is one such example. This method runs automatically every time an instance of a class is created. When we define __init__() in our code, we are overriding the default. And this allows us to add a degree of flexibility to the attributes, properties and methods we have add to the class.

All of the attributes within a class are contained within a dictionary object called __dict__. As we've seen in the Electronic Point Of Sale project. Dictionary objects can be accessed in much the same way as lists. And this means a determined developer would have no real problem in finding and interrogating private attributes within a class.

To get around this problem, supposedly, we can override the built in getters and setters that all Python classes have. These are called __getattr__ and __setattr__ respectively. However I've never seen this working and don't seem to be able to make it work. So, so far as I'm concerned for the time being. It doesn't work (at least not without crashing your program) and everything is public. Even when it's private.

Reading The Dictionary

#!/usr/bin/env python3

__project__= "Python Classes: The Bank Example"
__author__ = "Kevin Lynch"
__version__ = "$Revision: 2 $"
__date__ = "$Date: 2016/04/11 20:27:00 $"
__copyright__ = "Copyright (c) 2016 Kevin Lynch"
__license__ = "GPLv3"

# Create the bank class.
class bank:
        # Initialise bank with custom attributes.
        def __init__(self,account,pin,cash):
                # This is a bank. So all attributes are private.
                self.__account = account
                self.__pin = pin
                self.__cash = cash
             
# Global variable. Bob creates his account with the bank.
bobsAccount = bank(12345678,9990,500)

# Lets look at the dictionary.
print("\n\nReading the whole dictionary")
print(bobsAccount.__dict__)

# Now lets search for the cash.
d = bobsAccount.__dict__ # This will make the dictionary easier to work with.
for key in d.keys():
        # Search for the keyword cash and do something.
        if "cash" in key:
                print("\n\nCash found in " + key)
                print(key + " = " + str(d[key]))
             
                # We can even edit the value of the attribute.
                print("\n\nLets give Bob more cash!!!")
                d[key] = 1000
                print(key + " = " + str(d[key]))              
                break
        else:
                print("\nCash not found in " + key)
             
# Now lets prove we actually altered Bob's account.
# Since we know the name of the attribute. We can access it directly.
print("\n\nCash in Bob's account = " + str(bobsAccount._bank__cash))

Why Bother Then?
There are a few reasons. The straw man is that it's what developers from the likes of Java or C++ backgrounds have been taught to do. So it's considered "good practice". However it would also be good practice if people just read the API reference, used the class properly and saved other programmers from having to write countless lines of extra code.

A much better reason is that it ensures there is one and only one obvious means of accessing and altering class members. Which in turn helps to bolster the integrity of those class members and the stability of the program overall. By using encapsulation with getters and setters, we can validate data being passed around the program. Everything in theory happens in an orderly and predictable way.

Clearly this isn't a massive problem with very small and simple examples. But when a program runs into hundreds, thousands or even millions of lines of code, passes through the hands of dozens of programmers. It becomes a problem.

Saturday, 9 April 2016

Classes 3: Properties

Properties are the Pythonic way of implementing class members with associated getters and setters. In other object oriented languages like Java this is done from the beginning. In Python, the convention is to use getters and setters only when they are actually needed. For example when exception handling is required or when it becomes desirable to make a class member private. Otherwise the convention is to use the simplest implementation.

We can see the use of properties, getters and setters in action by modifying our bicycle example as follows.
#!/usr/bin/env python3

__project__= "Python Classes: The Bicycle Example"
__author__ = "Kevin Lynch"
__version__ = "$Revision: 3a $"
__date__ = "$Date: 2016/04/10 01:48:00 $"
__copyright__ = "Copyright (c) 2016 Kevin Lynch"
__license__ = "GPLv3"

class bicycle: # Defines the bicycle class.
        # Initialise bicycle with custom attributes.
        def __init__(self,frame,wheels):
                self.frameSet = frame
                self.wheelSet = wheels
                
        @property # Property decorator.
        def frameSet(self):
                return self.__frameSet

        @frameSet.setter # Setter method for the property frameSet.
        def frameSet(self,frame):
                if frame == "carbon":
                        self.__frameSet = frame
                elif frame == "steel":
                        self.__frameSet = frame
                else:
                        self.__frameSet = "wood"

        @property # Property decorator.
        def wheelSet(self):
                return self.__wheelSet

        @wheelSet.setter # Setter method for the property wheelSet.
        def wheelSet(self,wheels):
                if wheels == "carbon":
                        self.__wheelSet = wheels
                elif wheels == "alloy":
                        self.__wheelSet = wheels
                else:
                        self.__wheelSet = "wood"

# Global variables. Both reference the bicycle class.
bobsBike = bicycle("carbon","carbon")
suesBike = bicycle("steel","alloy")

print("Bob's Bike:\nFrame Set: " + bobsBike.frameSet + "\nWheel Set: " + bobsBike.wheelSet)
print("\n\nSue's Bike:\nFrame Set: " + suesBike.frameSet + "\nWheel Set: " + suesBike.wheelSet)

# We can still change things as before.
suesBike.frameSet = "plastic"

print("\n\nSue's Bike:\nFrame Set: " + suesBike.frameSet + "\nWheel Set: " + suesBike.wheelSet)

The only thing we have had to change in our bicycle example is the implementation of the bicycle class. In particular we have added our getters and setters. The getter method is decorated with the @property decorator and the setter method is decorated with the @<property name>.setter decorator. The rest of the program is unchanged.

This means that when we implement an attribute within a class in the simplest way possible. We can then change that implementation later without breaking the whole program. We use the same syntax to access properties as we do when accessing attributes or methods.

Classes 2: __init__(self)

The code from Classes: Part 1 is just a simple introduction to classes. While the code does work, it could be more flexible and better defined. For example it would be more efficient if we could add the individual specifications for both Bob and Sue's bikes when the object instances are created. To do this we use the __init__(self) method to initialise the object instance with the correct values for each attribute.

We can see how this works with the following code.

#!/usr/bin/env python3

__project__= "Python Classes: The Bicycle Example"
__author__ = "Kevin Lynch"
__version__ = "$Revision: 2 $"
__date__ = "$Date: 2015/11/21 21:19:00 $"
__copyright__ = "Copyright (c) 2015 Kevin Lynch"
__license__ = "GPLv3"

class bicycle: # Defines the bicycle class.
        # Initialise bicycle with custom attributes.
        def __init__(self,frame,wheels):
                self.frameSet = frame
                self.wheelSet = wheels

# Global variables. Both reference the bicycle class.
bobsBike = bicycle("carbon","carbon")
suesBike = bicycle("steel","alloy")

print("Bob's Bike:\nFrame Set: " + bobsBike.frameSet + "\nWheel Set: " + bobsBike.wheelSet)
print("\n\nSue's Bike:\nFrame Set: " + suesBike.frameSet + "\nWheel Set: " + suesBike.wheelSet)

# We can still change things as before.
suesBike.frameSet = "plastic"

print("\n\nSue's Bike:\nFrame Set: " + suesBike.frameSet + "\nWheel Set: " + suesBike.wheelSet)

For such a small program __init__(self) may seem redundant. However getting to grips with this basic concept will make working with objects and classes much easier in larger programs.

Friday, 8 April 2016

Classes 1: A Very Simple Introduction

#!/usr/bin/env python3

__project__= "Python Classes: The Bicycle Example"
__author__ = "Kevin Lynch"
__version__ = "$Revision: 1 $"
__date__ = "$Date: 2015/11/21 21:19:00 $"
__copyright__ = "Copyright (c) 2015 Kevin Lynch"
__license__ = "GPLv3"

class bicycle: # Defines the bicycle class.
frameSet = "carbon"
wheelSet = "alloy"

# Global variables. Both reference the bicycle class.
bobsBike = bicycle()
suesBike = bicycle()

print("Bob's Bike:\nFrame Set: " + bobsBike.frameSet + "\nWheel Set: " + bobsBike.wheelSet)
print("\n\nSue's Bike:\nFrame Set: " + suesBike.frameSet + "\nWheel Set: " + suesBike.wheelSet)

# Sue's bike is defferent from Bob's. So we can change it.
suesBike.frameSet = "steel"

print("\n\nSue's Bike:\nFrame Set: " + suesBike.frameSet + "\nWheel Set: " + suesBike.wheelSet)

Wednesday, 29 July 2015

Electronic Point of Sale


Since I was getting bored with strings and the basics. I decided to take a fun little project. The challenge is to write a program that works like an electronic point of sale. In simpler terms a cash register.

The code gets a little messy because I was getting tired and frustrated and I'm not a programmer of any level of skill. Although I have Python 3.4 installed on my PC. Python 2.7 is used by default. Which it turns out is terrible at handling unicode characters. All I wanted it to print was the £ sign in a raw_input() prompt. The answer was to explicitly use Python 3.x.

With the unicode problem sorted and the program re-factored for Python 3.x I decided to call it a day with what I have for now. Back to basics again I think.


  • The program assumes a terminal with of 80 columns. Which used to be the norm.
  • The database of goods is a simple dictionary. Which actually works quite well for this application.
  • To select an item from the inventory simply type it in.
  • Only one item can be selected at a time. But you can allow the program to loop several times to build up a list of items.
  • An item can appear more than once in your list.
  • When you select "P" to pay. The program will ask how much you are paying and then calculate your change. If you don't give enough, you'll be told to come back when you can pay.
  • The program will pause for a few seconds to allow you to read the receipt. And then it moves on to the next customer.
  • Press "Q" to quit.


#!/usr/bin/env python3

# Project       : Electronic Point of Sale
# Author        : Kevin Lynch
# Created      : 29.07.2015

# Brief: Create a program that will hold a database of goods matched against
#        their prices which can then be used to tally up the cost of a shoppers
#        order.

# Function definitions.
def wait(t):
        for i in range(0,t):
                i = i + 0
                
def orderScreen(s): # Show goods for sale with prices.
        welcome = " Welcome to Python General Stores "
        instruct = "[P = Pay] [Q = Quit] | Please select an item."
        print("{:*^80}".format(welcome))
        
        for key in s.keys():
                print(u"{: >39} \xA3{: <39.2f}".format(key,s[key]))
                
        print("{:*^80}".format(""))
        print("{: ^80}".format(instruct))
        print("{:*^80}".format(""))

def acceptPayment(o,s):
        import time
        header = " Sale "
        prompt = u"{: >40}\xA3".format("Amount Given: ")
        total = 0.00
        given = 0.00
        change = 0.00
        
        for i in range(0,len(o)): # Calculate total due.
                for key in s.keys():
                        if o[i] == key:
                                total = total + s[key]
        
        print("{:*^80}".format(header)) # Print order and amount due.
        
        for i in range(0,len(o)):
                print(u"{: >39} \xA3{: <39.2f}".format(o[i],s[o[i]]))
                
        print(u"{: >40}\xA3{: <39.2f}".format("Amount Due: ",total))
        given = float(input(prompt)) # Amount given.
        if given >= total: # Calculate change due.
                change = given - total
                print(u"{: >40}\xA3{: <39.2f}".format("Change Due: ",change))
        else:
                print("{: ^80}".format("Please come back when you can pay."))
        time.sleep(3)

def takeOrder(s): # Get the customers order.
        kbd = ""
        order = []
        while str.upper(kbd) != "P": # Loop until customer decides to pay.
                if str.upper(kbd) == "Q": # Break loop to quit.
                        break 
                orderScreen(stock)
                kbd = input("::")

                for key in s.keys():
                        if key == str.capitalize(kbd):
                                order.append(str.capitalize(kbd))
                        
        if str.upper(kbd) == "P":
                acceptPayment(order,stock) # Call acceptPayment
                
        return kbd # Return to main program.

# Global variables.
stock = {"Apple":0.50,"Banana":0.50,"Milk":1.00,"Bread":1.50,"Bacon":5.60}

# Main Program
kbd = ""
while str.upper(kbd) != "Q":
        kbd = takeOrder(stock)

Tuesday, 28 July 2015

Arithmetic Operators

#!/usr/bin/env python

# Like most languages Python supports some basic arethmetic operators.
# + Addition
# - Subtration
# * Multiplication
# / Division
# // Explicite "floor/integer division"

# % Calculates the remainder of a division.
# ** Calculates powers
# () Brackets are also supported for grouping. Think BODMAS theory.

number = 0 # Set number to 0.
print number

number = number + 10 # number is now 10.
print number

number = number - 3 # number is now 7.
print number

number = number * 3 # number is now 21.
print number

number = number / 7 # number is now 3.
print number

number = number // 2 # number is now 1.
print number

number = number % 2 # number is now 1.
print number

number = 0
number = (((((number + 10) - 3) * 3) / 7) // 2) % 2 # number is now 1.
print number

number = 0
number = number + 10 - 3 * 3 / 7 // 2 % 2 # number is now 10.
print number

number = number ** 2 # number is now 100.
print number

Functions

#!/usr/bin/env python

# Functions allow us to include code in our programs that will only run when
# explicitly called and can be reused.

# Simple function example.
def allStars(n):
        for i in range(0,n):
                print "*"

# Main Program
run = True              
while run:
        x = raw_input("How many stars should I print? ")
        if str.isdigit(x):
                allStars(int(x))
                x = raw_input("Do you want another go? Press Y or N")
                if str.upper(x) == "N":
                        run = False
        else:
                print "%s is not a number." % x

Flow Control 2: while, while-else

#!/usr/bin/env python

# Simple while loop example.
i = 0
while i != 10:
        i = i + 1
        print i
       
# while-else
while i != 10:
        i = i +1
        print i
else:
        print "We're all done here!"

Flow Control 1: for, for-else

#!/usr/bin/env python

# Simple for loop example.
for i in range(0,11):
        print "The value of i is %d." % i

# for-else example.
# This is taken directly from the Python documentation. The else statement
# looks as though it's in the wrong place. It's not. Python for loops can have
# else statements.
for n in range(2, 10):
        for x in range(2, n):
                if n % x == 0:
                        print n, 'equals', x, '*', n/x
                        break
        else:
                # loop fell through without finding a factor
                print n, 'is a prime number'

Strings 2

#!/usr/bin/env python

# Python has an unhealthy string obsession. There are many ways of converting
# and formatting strings.

A = "hello world"

# More formatting.
# https://docs.python.org/2.7/library/string.html#string-formatting
print "The first character of A is %s." % A[0] # Old method.
print "The first character of A is {!s}.".format(A[0]) # New method, Python 3.

# Some useful built in string methods.
# https://docs.python.org/2.7/library/stdtypes.html#string-methods

# Check and convert a string to all caps.
print(str.upper(A))

if str.isupper(A):
        print(A)
else:
        print(str.upper(A) + " : Converted with str.upper().")
        print(str.swapcase(A) + " : Converted with str.swapcase().")
        print(A + " : Original remains intact. Strings are immutable!")

# Check and convert a string to all lower case.
B = "HELLO WORLD"
print(str.lower(B))

if str.islower(B):
        print(B)
else:
        print(str.upper(B) + " : Converted with str.lower().")
        print(str.swapcase(B) + " : Converted with str.swapcase().")
        print(B + " : Original remains intact. Strings are immutable!")

# Be careful with str.swapcase()
print(str.swapcase("str.swapcase Literally swAps eACH CHARACTER'S case."))

# Capitalise the first letter only.
print(str.capitalize(A))
print(str.capitalize(B))

# Find a substring within a string.
stringToFind = "lo"
i = A.find(stringToFind)
print(A[i:i + len(stringToFind)] + " found at position %d") % i

# The last example uses a technique called slicing with the print statment.
# This is used to print a sub string and can infact be used on most list
# style objects with indices. The axample below is a bit simpler.

print(A[0:5])

# The first value in the square brackets is the index position to begin at.
# The second value is the number of positions we want to include in the slice.
# It is NOT an index value.

# So if we imagine our string "Hello World" is a row of boxes. What we're
# telling Python to do is start at index 0 and print only the next 5 boxes.
# The index value for the "o" in "Hello" will of course be 4 and not 5. This is
# because the indices in lists and strings begin at 0 and not 1.

Strings 1

#!/usr/bin/env python

# The first thing to note about strings is that they are basically lists of
# characters. This means all elements of a string can be accessed directly
# using their indices.

# Python strings effectively have two indices. The first starts at 0 for the
# first character on wards. The second starts at -1 from the last character.

A = "Hello World"
print "The first character of A is \"%s\"." % A[0]
print "The last charachter of A is \"%s\"." % A[-1]

# The code above looks very simple. And it is. However a number of thing are
# happening that would normally require a lot more code in Java or C.

# 1. A is declaired and it's value set as the string "Hello World".
# 2. Python is told to print the first and last characters.
# 3. ASCII escape characters are used to enclose the first and last characters
#    in double quotes. Getting to grips with these will save a lot of code.
# 4. We perform a substitution instead of concatinating multiple strings.

# Concatinated version.
print ('The first character of A is ' + '"' + A[0] + '".')
print ('The first character of A is ' + '"' + A[-1] + '".')

# Slightly more complex examples.
B = ["first","second","third","fourth","last","second last"]
print ("The %s character of A is \"%s\".") % (B[0],A[0])
print ("The %s character of A is \"%s\".") % (B[1],A[1])
print ("The %s character of A is \"%s\".") % (B[4],A[-1])
print ("The %s character of A is \"%s\".") % (B[5],A[-2])

print ('The ' + B[0] + ' character of A is ' + '"' + A[0] + '".')
print ('The ' + B[1] + ' character of A is ' + '"' + A[1] + '".')
print ('The ' + B[4] + ' character of A is ' + '"' + A[-1] + '".')
print ('The ' + B[5] + ' character of A is ' + '"' + A[-2] + '".')

# Integer substition example.
print ("The %s character of A is \"%s\". A is %d characters long.") % (B[4],
        A[-2],len(A))
       
print ('The ' + B[4] + ' character of A is ' + '"' + A[-1] + '". A is '
        + str(len(A)) + ' characters long.')

# Note that to substitute in an integer %d is used instead of %s. Conversion of
# the integer happens automatically. However in the concatination version the
# conversion must be done manually. Which isn't a problem in this example. But
# it would make larger programs harder to read and maintain.

# More information on string formatting can be found here,
# https://docs.python.org/2/library/stdtypes.html#string-formatting-operations

Monday, 27 July 2015

Making Decisions: if-elif-else

#!/usr/bin/env python

# Programs normally execute one line after the other from top to bottom.
# But sometimes we need to make a decision while the program is running.
# Some of these decisions will send the program down one path or the other.

# To do this in Python we use the if-elif-else statements.

# The first thing to note is Python uses indentation to define code blocks
# rather than the {} notation found in C or Java. This means in Python
# indentation of code blocks is manditory. We also don't actually
# type "then" as in "if condition is true then do somemthing". Instead we use
# a colon ":". Because why not?

# Basic if statement.
A = 0 # Integer.
if A == 0: print A

# A more complex example with indentation defining a code block.

A = [1,2,3,4,5] # List of integers.
if A[0] != 0:
        print ("A at index 0 is equal to %d.") % A[0]
        print ("A at index 0 is equal to %d.") % A[1]
        print ("A at index 0 is equal to %d.") % A[2]
        print ("A at index 0 is equal to %d.") % A[3]
        print ("A at index 0 is equal to %d.") % A[4]      

# Both the examples above will only print the value of A if the condition is
# met. But often we need alternative actions to be taken when the condition
# has not been met. For this we add the else statement.

A = 1
if A == 0:
        print A
else:
        print ("A is not 0.")
       
# By adding additional if statements we can test for multiple possibilities.
# We do this in Python by using elif.

A = 2
if A == 0:
        print A
elif A == 1:
        print A
elif A == 2:
        print A
elif A == 3:
        print A
else:
        print ("The value of A does not match the test.")

Variables and Data Types

#!/usr/bin/env python

# Python Variables and Data Types
# The first thing to know about a variable is that it is just a place in the
# computer's memory where data is held. Think of them as boxes.

# Variables have names to make them easier to work with. In most programming
# languages variable names can be made up of numbers and letters. And they
# normally must start with a letter or underscore character "_". Python in this
# respect is like any other programming language. A variable name is called an
# "identifier". Identifiers are case sensitive. Python keywords cannot be used
# as identifiers.

# Python variables are loosely typed. The interpreter assumes the variable type
# based on the content of the variable. Variables can be integers, long integers
# octal literals (base 8), hexadecimal literals (base 16), floating-point
# numbers and complex numbers.

# Python also supports some complex data structures. These are strings, lists,
# tupels, dictionaries and sets. A list is like an array in Java or C. Except a
# list in Python can consist of mixed types. Tupels, dictionaries and sets are
# similar to lists. But they have different uses, attributes and methods of
# access.

# Examples of numbers.
a = 1 # Integer.
b = 42000000000000000000L # Long integer.
c = 010 # Octal literal.
d = 0xA1F # Hexadecimal literal.
e = 0XA1F # Hexadecimal literal.
f = 45.33 # Floating-point number.
g = 9.5541e-10 # Floating-point number.
h = 4 + 4j # Complex number.

print a
print b
print c
print d
print e
print f
print g
print h

# Examples of strings.
i = "Hello World" # String with double quotes "
j = 'Hello World' # String with single quotes '

k = '''Hello World can extend over multiple lines
and contain 'single quotes' and "double quotes"
 which is crazy.''' # String with triple quotes '''

l = '\"Hello World\"' # String with single quotes, printing double quotes.
m = "\'Hello World\'" # String with double quotes, printing single quotes.

print i
print j
print k
print l
print m

# Example of a list.
n = ["H","e","l","l","0"] # A simple list.
o = [["W","o","r","l","d"],2,3.45,0xA1F] # A list composed of multiple types.

print n
print o
print n[0]
print n[1]
print n[2]
print n[3]
print n[4]
print o[0][0]
print o[0][1]
print o[0][2]
print o[0][3]
print o[0][4]
print o[1]
print o[2]
print o[3]

# Example of a tuple.
p = ("Tuples","are","immutable","lists")
print p
print p[0]
print p[1]
print p[2]
print p[3]

# Example of a dictionary.
q = {"Name" : "Bob","Age" : 20}
print q
print q["Name"]
print q["Age"]

# Example of a set.
r = set(("Hello World",i))
s = {"Hello World",i}
print r
print s
# Why doesn't "Hello World" print twice for each set as we would expect?
# Sets contain non-repeating data only. Since "Hello World" and "i" are the same,
# one is discarded.

Sunday, 7 June 2015

Hello World

Python is a very friendly language as programming languages go. It's speciality is parsing text or formatting output to a display screen. But it is rapidly being developed to do a whole lot more.

In this blog I will be posting some very simple examples of Python code. Since there are a number of different Python interpreters available today. I will not cover how to get the finished code to run. Follow the instructions for your particular interpreter.

Hello World Code

#!/usr/bin/env python
print 'Hello World'
The first line in the code example tells POSIX compliant OS's using the Bash command interpreter where the Python command interpreter is. So far as I know this is not strictly speaking Python code and likely won't work in Windows or other non-POSIX environments.

The second line of code is Python code. This is as simple as a Python program gets.