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/
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
- Python for Software Design – How to Think Like a Computer Scientist.
- Learn Python the Hard Way By popular & well known author Zed A. Shaw.
- Dive into Python 3 – Great reference.
- Snake Wrangling For Kids – for children 8 years and older, who would like to learn computer programming
Websites/following
- Tweeter feed of the latest Python tagged questions appearing in StackOverflow – A language-independent collaboratively edited question and answer site for programmers.
- Python Programming Language – Official Website
- The Zen of Python
- Google Python Style Guide
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