Gentle Introduction to Python

Right, let’s dig into my favorite language. Python. It’s super easy to read & learn, it’s concise and one of the hot languages in Silicon Valley. In fact, Python is also one of the easiest languages to grasp if you want to learn to code on mobile.

The following assumes you understand basic software engineering concepts.

A bit about Python

  • Design philosophy emphasizes on code readability. Important because software engineers spend most of their time trying to understand code. (Ref Coding Horror)
  • Has a nice MVT open-source web framework called Django. Django emphasizes reusability and pluggability of components, rapid development, and the principle of DRY (Don’t Repeat Yourself).
  • It features a fully dynamic type system with late binding (duck typing) and automatic memory management, similar to that of Scheme, Ruby, Perl, and Tcl. More here.
  • Runs on LAMP, where the P = Python. Here’s how to set it up.
  • Currently one of the hottes languages (alongside Ruby/Ruby on Rails) in Silicon Valley especially among startups.

Sample of popular sites build in Python

Google, Dropbox, Reddit, Disqus, FriendFeed (Sold to Facebook to drive their News Feeds), YouTube, Quora (rising star), Douban. Comprehensive list here.

Python

  • Uses whitespace indentation, rather than curly braces or keywords, to show & delimit block structure. I prefer 4 spaces.
  • Everything is an object (first class) and everything has a namespace accessed by dot-notation.
  • Naming convention UpperCamelCase for class names, CAPITALIZED_WITH_UNDERSCORES for constants, and lowercase_separated_by_underscores for other names. See Python style guide and The Zen of Python for guiding principles for Python’s design into 20 aphorisms. Basically write self-documenting code by chosing explicit naming convention.
  • A comment starts with a hash character (#). For longer then a line (and as Doc strings) use triple quotes: ”’ xyz ”’.
  • Variable names have to start with a letter or underscore, and can contain numbers but no spaces or other symbols.
  • File extension is always .py. If you see .pyc this is source code compiled into bytecode for execution by a Python VM (virtual machine).
  • Use command line python shell to test assumptions by getting immediate results.
  • No case/switch statements. Switch is better solved with polymorphism (object that has more than one form) instead. Good example here.
  • Data types
    • Immutable (can’t be updated or changed): strings, tuple, int, float, complex, bool
    • Mutable (can be updated or changed): list, dictionary (dict) & mutable except for it’s keys
  • Editors I use: IDLE (for basic shell work & comes with Python.org install), PyCharm (with Django support) and Sublime Text 2 (lightweight TextMate replacement).

Basics

Arithmetic Boolean
2 > 3 → False
2 == 3 → False
2 The opposite of == is != (“not equals”):
2 != 3 → True
You can chain together comparison operators:
2 < 3 < 4 → True
Equality works on things besides numbers:
“moose” == “squirrel” → False
True and True → True
True and False → False
True or False → True
not False → True
(2 < 3) and (6 > 2) → True
Under the hood,
True is equal to 1,
and False is equal to 0.
Booleans are a subtype of integers.

Operators

== Equal to
!= Not Equal to
is Identical
and Boolean and
or Boolean or
& Bitwise and
| Bitwise or
not Boolean not (not the !)

Built in functions that are always available

len(s) Return the length of an object. Can also be a sequence (string, tuple or list) or a mapping (dictionary).
print(obj) Print object(s) to the stream file.
help(list) See basic help on any object.
dir(list) Return a list of valid attributes for that object.
type(list) Return the type of an object

More built in functions here: http://docs.python.org/library/functions.html

Functions

Always starts with a “def” and ends with “:”.

# define a new function with 1 default argument. Can also have no arguments.
def function_purpose(arg1=1):
     ''' This is a doc string '''
     print 'Python code'
     return (arg1, arg1+7,) # returns 2 values as a tuple (note the comma), else None
# call the function, returns a tuple that we assign to 2 variables
item1, item2 = function_purpose(1)

If you want to assign a value to a variable outside the function within a function you must prepend the variable with “global”.

Calling methods on objects

Just like calling functions, but put the name of the object first, with a dot

words = 'some monkeys here'
e = words.count('e')
# returns 4

Strings

Are a sequence of characters.

# creation
name = 'Ernest Semerda'

# accessing, returns 's'
name[4]

# splitting, returns a list ['Ernest', 'Semerda']
the_string.split(' ')

Strings can be subscripted/sliced like the list (see lists in Data Structures below).

# selected range returns 'nest '
name[2:5]

# get first two characters returns 'Er'
name[:2]

# get everything except the first two characters returns 'nest Semerda'
name[2:]

Sample of  some string methods. They come with 8-bit & Unicode support.

name.capitalize() # changes to 'ERNEST SEMERDA'
name.find(sub[, start[, end]])
name.lower()
name.split([sep[, maxsplit]]) and new_name.join(list)

More string methods: http://docs.python.org/library/stdtypes.html#string-methods

Data Typing

Python is strongly typed which won’t allow you to automatically converted from one type to another.

Python also has a strong tradition of duck-typing (dynamic typing) in which an object’s current set of methods and properties determines the valid semantics. Trusting that those methods will be there and raising an exception if they aren’t. Be judicious in checking for ABCs and only do it where it’s absolutely necessary.

An important feature of Python is dynamic name resolution (late binding), which binds method and variable names during program execution.

# fails because (str + int + str) != str
'There are ' + 8 + ' aliens.'
# perfect, str() = type conversion
'There are ' + str(8) + ' aliens.'

To achieve Reflection, a process by which a computer program can observe and modify its own structure and behavior, use the built-in functions. I.e. getattr

Over a “sys” module’s method “path”:

path = getattr(sys, "path")

Over a function1 with sample input:

result = getattr(sys.modules[__name__], "function1")("abc")

And/or use the Reflection Utilities API for deeper execution frame, execution model, class/obj inspection for methods & attributes etc… See: http://docs.python.org/c-api/reflection.html

Data Structures

Dictionary

Set of key:value pairs. Keys in a dictionary must be unique. Values Mutable.

# creation, empty dictionary
peopleDict = {}

# creation, with defaults
aliensDict = {'a':'ET', 'b':'Paul', 'c':42}

# accessing, returns 'ET'
aliensDict['a']

# deleting, 'Paul' is removed from dictionary
del alientsDict['b']

# finding, returns False (note capital F)
aliensDict.has_key('e')

# finding, returns ['a', 'c']
aliensDict.keys()

# finding, returns [('a', 'ET'), ('c', 42)]
aliensDict.items()

# finding, returns True
'c' in aliensDict

Lists

Lists can carry any items ordered by an index. Lists are Mutable.

# creation, empty list
peopleList = []

# creation, with defaults of any type
codesList = [5, 3, 'p', 9, 'e']

# accessing, returns 5
codesList[0]

# slicing, returns [3, 'p']
codesList[1:3]

# finding, returns ['p', 9, 'e']
codesList[2:]

# finding, returns [5, 3]
codesList[:2]

# returns ['p', 9]
codesList[2:-1]

# length, returns 5
len(codesList)

# sort, no return value
codesList.sort()

# add
codesList.append(37)

# return, returns 37
codesList.pop()

# remove, returns 5
codesList.pop(1)

# insert
codesList.insert(2, 'z')

# remove
codesList.remove(‘e’)

# delete
del codesList[0]

# concatenation, returns ['z', 9, 'p', 0]
codesList + [0]

# finding, returns True
9 in codesList

Apply set(list) and it becomes a set – an unordered collection with no duplicate elements. Also support mathematical operations like union, intersection, difference, and symmetric difference.

Tuples

Tuples are similar to lists: they can carry items of any type & useful for ordered pairs and returning several values from a function. Tuples are Immutable.

# creation, empty tuple
emptyTuple = ()

# note the comma! = tuple identifier
singleItemTuple = ('spam',)

# creation, with defaults of any type
codesTuple = 12, 89, 'a'
codestuple = (12, 89, ‘a’)

# accessing, returns 1
codesTuple[0]

More on data structures here: http://docs.python.org/tutorial/datastructures.html

Control & Flow

For loop

# Collection iterator over dictionary w/ tuple string formatting
people = {"Ernest Semerda":21, "Urszula Semerda":20}
for name, age in people:
    print "%s is %d years young" % (name, age)

To loop over two or more sequences at the same time, the entries can be paired with the zip() function.

More on string formatting operations here: http://docs.python.org/library/stdtypes.html#string-formatting-operations

For loop with if else

# Iterate over a sequence (list) of numbers (1 to 10) with if/else Conditionals. The range function makes lists of integers.
 for x in range(1, 10):
     if x == 8:
         print "Bingo!"
     elif x == 10:
         print "The End"
     else:
         print x

While loop

# using request to ask user for input from interactive mode
request = "Gimme cookie please: "
while raw_input(request) != "cookie":
    print "But me want cookie!"

Switch-statements do not exist. In OO they are irrelevant & better solved with polymorphism instead. Examples here.

More control flow tools here: http://docs.python.org/tutorial/controlflow.html

Golfing!

Chaining into few lines.

[x * x for x in [1, 2, 3, 4, 5]]
# returns [1, 4, 9, 16, 25]

Can get messy & complicated to read.

print [x * x for x in range(50) if (x % 2 ==0)]
def is_palindrome(word):
    word = re.compile(r'[!? ]').sub("", word.lower())
    return True if word == word[::-1] else False

Files

# open, defaults to read-only + note single forward slash
contents = open('data/file.txt')

# accessing, reads entire file into one string
contents.read()

# accessing, reads one line of a file
contents.readline()

# accessing, reads entire file into a list of strings, one per line
contents.readlines()

# accessing, steps through lines in a file
for line in contents:
    print line

More on IO: http://docs.python.org/tutorial/inputoutput.html

Classes

All methods (but not functions) are closures – see “self” below. A closure is data attached to code. All variables are public, private variables are established by convention only.

# SuperHero inherits from Person class - also supports multiple inheritance using comma
class SuperHero(Person):
    # constructor
    def __init__(self, name):
        self._name = name

    # method
    def shout(self):
        print "I'm %s!" % self._name

The __name__ below allows Python files to act as either reusable modules, or as standalone programs. Also think Unit Tests benefits!

if __name__ == '__main__':
    # instantiate the class
    batman = SuperHero('Batman')

    # call to method in class, returns "I'm Batman!"
    batman.shout()

    # returns "I'm Batman!"
    SuperHero.shout(batman)

More on Classes in Python here: http://docs.python.org/tutorial/classes.html

Modules

Modules are Libraries that hold common definitions and statements. They can be combined into an importable module.
More on modules here: http://docs.python.org/tutorial/modules.html

To use a module, use the import statement:

import math

# returns 1.0
math.sin(math.pi / 2)

Some commonly used modules

  • math – trigonometry, the constants e and pi, logarithms, powers, and the like.
  • random – random number generation and probability distribution functions.
  • os – tools for talking to your OS, including filesystem tools in os.path.
  • sys – various system information, as well as the handy sys.exit() for exiting the program.
  • urllib2 – tools for accessing Web resources.

Useful modules: http://wiki.python.org/moin/UsefulModules

Error & exception handling

import sys
try:
    f = open('myfile.txt')
    s = f.readline()
    i = int(s.strip())
except IOError as (errno, strerror):
    print "I/O error({0}): {1}".format(errno, strerror)
except ValueError:
    print "Could not convert data to an integer."
except:
    print "Unexpected error:", sys.exc_info()[0]
    raise

More: http://docs.python.org/tutorial/errors.html

Fun – easter egg; The antigravity module

Released in Google App Engine on April 7, 2008. The antigravity module (http://xkcd.com/353/) can be enabled like this:

import antigravity

def main():
    antigravity.fly()

if __name__ == '__main__':
    main()

Speed – always a common topic

Classic computer programs had two modes of runtime operation = interpreted (as code runs) or static (ahead-of-time) compilation.

Just-In-Time compilation (JIT), also known as dynamic translation is a new hybrid approach. It caches translated code (bytecode into native machine code) to minimize performance degradation. Used in .NET, Java & Python via PyPy.

PyPy is a fast, compliant alternative implementation of the Python language. It has several advantages and distinct features like Speed (Just-in-Time JIT compiler), Memory usage (better then CPython), Compatibility (works with twisted & django frameworks), Sandboxing (run untrusted code), Stackless (providing micro-threads for massive concurrency). Check it out: http://pypy.org/

Recommended

Books

Websites/following

Finally, it is important that you have a network of like minded people around you whom you can regularly work on Python with, bounce ideas & question and support (help) each other out.

Happy Learning and if you have any questions please contact me. Always happy to help.

~ Ernest