Python: A Cool Thing

Download Report

Transcript Python: A Cool Thing

Python Foundations
by Chris Gahan
(( In Stereo where Available ))
TRICK #1

Don’t Repeat Yourself

If everything is defined once, then radically
changing the behaviour of your program is
trivial.
TRICK #2

Get your program running on real data as
soon as possible
TRICK #3

Test it!


Even if you don’t have fancy test cases, make some
little bit of code at the end of the program to test its
functionality as you’re developing it.
I like to break my programs into a bunch of modules
with tests in the ‘if __name__ == “__main__”:’ block


when you execute the file, the tests run
when you import it as a module, the tests are ignored
TRICK #4

Use as much of Python’s libraries and
built-in functionality as you can



Python’s built-in stuff is a solid foundation
There are solutions to many many problems
in the standard library
Use lists and dicts for as much as you can

writing custom classes when you can use a list or
dict will overcomplicate your code
TRICK #5

The Zen of Python

Execute “import this” in the interpreter
Things you should know

Exceptions are awesome


Decorators are cool


But don’t over-use them
But you rarely need them
List comprehensions and Generators are wicked


Use them as much as possible!
Rethinking your problems as a series of generators or
list transformations is an excellent habit to get into
More things you should know
(about performance)

Appending strings is slow


Searching lists is slow


Use sets!
List comprehensions are fast!


Use sets or dicts!
Comparing lists is slow


Use lists and ‘’.join(list) them!
Use them as much as possible
If your program still isn’t fast enough, use Psyco or
Pyrex!


Psyco optimizes code automatically (faster)
Pyrex generates C code which can be compiled (fastest)
Everything is an object







Lists are objects
Functions are objects
Classes are objects
Types are objects (IntType, ClassType,
TypeType, etc.)
Dicts are objects
Objects are objects
Internally, all Objects are secretly Dicts!
Lists

This is your bread and butter in Python. Lists are everything:


list = [1,2,3,4,Ninja(),”rumplestiltskin”]
Handy methods:

list.append(5)


list.extend([5,6,7])


Reverse the list
list.sort()


Yank off an element from the list and hand it to you. If you don’t specify the
position, it pops off the last element.
list.reverse()


Append the contents of [5,6,7] to the list
list.pop(position)


Stick 5 on the end of the list
Sort the list
list.index(item)

Return the position of item in the list
Slicing

Lets you grab chunks from a list or a string.

list[5:9]


list[-3:-1]


Grabs elements 0,1,2,3
list[6:]


Negative indexes mean “from the end”, -1 being first from the end,
-2 being second from the end, etc.. So this would grab two
elements: the 3rd and 2nd from the end.
list[:4]


Grabs elements 5,6,7,8
Start at element 6 and grab all the rest of the elements until the
end
list[:]

Grab all elements (make a copy of the entire thing)
Note: The off-by-one thing (where it ignores the last element in the slice) is
there for a good reason – it makes slice math super easy! (It’s the same reason
that range(a,b) ignores the last element ‘b’)
Slicing Strings


Since strings are also technically lists of
characters, they can also be sliced
To copy a string, take a slice that’s the
entire string:

newString = oldString[:]
Trivia

Did you know that slices are actually
OBJECTS? It’s TRUE!

You can make an object that returns its own
custom slice objects which return anything
you want

SQLObject does this when you slice a database
query result – it uses “LIMIT” and “OFFSET” to get
the chunk of the slice, resulting in mad speed!
Stupid Tuple Tricks

Tuples are like lists, but static


once you define a tuple, you can’t modify it
Whenever you use a comma in Python, a
tuple is secretly created. For example:




a = 1, 2, 3
Internally, function
parameters are tuples.
open(“file.txt”, “r”)
person1, person2 = “Muhammed”, “Shareef”
a, b = b, a
A clever way to swap
two variables
Assigning two
values at once
Kinds of Strings

Different kinds of strings:

Raw strings ignore escape codes (\n, \x, etc)

Great for regexes – you don’t have to go: \\t, \\w, \\s, etc..
String operations

s.replace(‘victim’, ‘replacement’)


s.strip([chars])


Remove leading/trailing whitespace and newlines (or,
remove leading/trailing [chars])
s.split([delimiter])


Replace all occurrences of victim
Break a string up into pieces and return them as a list
of strings. The delimiter is whitespace by default.
You want more? Hit TAB in ipython!
Formatting Text for Output

Want to format text for output?


If you have a bunch of elements you want to
print nicely, use “, “.join(list)
If you want to print strings, instead of:


…you can do:


“hi “ + name + “, how are you?”
“hi %s, how are you?” % name
Or

“hi %(name)s, how are you?” % locals()
String Interpolation

String interpolation lets you substitute
placeholders (%s, %d, etc.) in a string (just like
printf in C)
Why string interpolation?

Because when you have lots of variables in the output, it
becomes annoying to keep track of where your quotes
end. (Also, typing “++“ requires hitting shift a lot – it’s
easy to mess it up).

“name: “+name+”, age: “+age+”, city: “+city+”, province:
“+province+”, IP: “+ip+”, favorite colour: “+favorite_colour


“name: %s, age: %s, city: %s, province: %s, IP: %s, favorite
colour: %s” % (name, age, city, province, ip, favorite_colour)



…is harder to read than:
…which is harder to read than:
“name: %(name)s, age: %(age)s, city: %(city)s, province:
%(province)s, IP: %(ip)s, favorite colour: %(favorite_colour)s”
% locals()
Of course, Ruby has the prettiest string interpolation:

“name: #{name}, age: #{age}, city: #{city}, etc..” 
Files

Files are great in python

f = open(“filename.txt”)
Making lists pretty

Even though Python usually cares about
indentation, lists don’t… so get creative!
Note: You can have an extra comma on the last item to make
cutting and pasting and shifting lines around easier!
Making dicts pretty
Dicts let you use that extra comma too…
Making function calls pretty

Sometimes you need a huge number of function
parameters. There’s a couple ways to make this
readable:
There’s that extra comma again!
Functions


Standard function
You can set the default value for a parameter (in this case, None).

These are called keyword arguments
“if” statements

You can do some neat tricks in “if” statements.

Compare identity with the “is” and “is not” operators:



if theSocket is not None:
if hand.contents() is None:
Checking if stuff is empty:




if
if
if
if
[]:
“”:
None:
0:
=>
=>
=>
=>
false
false
false
false
“if” statements

There’s also the handy “elif” construct:
(That’s right, Python has no switch statement!)
Functions

Inline functions are kinda gross and very
limited (they can only execute one
statement, and it’s returned by default),
but they’re sometimes handy.

It’s usually better to just “def” a function.
(List comprehensions are better for this, by the way…)
Capturing Function Parameters

You can capture all the parameters passed to a
function in a list by naming one parameter
*args:
Capturing Function Parameters

You can also get a dictionary of all the
keyword arguments
Using the “Apply” method

Apply lets you call a function and pass the
parameters in as a list. For example, using the
“cmp” (compare) function (which returns -1 for
less than, 0 for equal, 1 for greater than):
But you don’t actually need apply…

You can actually do the same thing by
putting the parameters in a list and
“dereferencing” it with *list:
And it works for dicts too!

Dictionaries can be dereferenced by doing
**dict:
Regexes

Regexes can be executed on a string directly:


OR, they can be compiled first for extra speed:



match = re.match(‘expression’, ‘string’)
compiled_regex = re.compile(‘expression’)
match = compiled_regex.match(‘string’)
When you do a .match() or a .search():


No match returns None
A match returns a re match object, which contains:



groups()
group([group number])
groupdict() (if you used named groups: “(?<name>expression)”)
Decorators

Decorators let you add wrapper code
around methods and classes
The New Way
The Old Way
Require Integer Decorator
Pre/Postconditions Decorator
Automatic
Thread
Locking
Decorator
Static Methods / Class Methods

Oh yeah, I forgot to mention…

Static methods are methods that you can call
on an instance or the class itself


They don’t take “self” as a parameter, so they can’t
operate on the object. They’re just helper
methods.
Class methods are called on classes only and
receive the class as the first argument
(instead of “self”)

Useful when you have a big class hierarchy and
you want the parent class to do things to the child
classes.
Docstrings, PyDoc, iPython

Docstrings rule.


It’s why everything in ipython has help for it
Whoever invented them was a genius,
because they’re elegant and powerful:
(It’s common to use triple-quotes because they let you write multi-line
docstrings, and they kinda look nicer, but “regular strings” work too.)
List Comprehensions

List comprehensions make it simpler to do a really
common task: computing something for every element
in a list and putting the result in another list.

Check out that SAVINGS!
List Comprehensions


They can also work as filters.
Here’s how you filter a list of numbers and
return only the even numbers:
Generators

Generators are special objects that spit
out values one at a time as requested by
the caller.


They can result in huge memory savings
when processing large batches of data
They’re also great for implementing things
like pipes, or procedurally generated
sequences
Generators




To make your function a generator, just
use “yield <value>” instead of “return
<value>”
Calling a generator returns a generator
object
Generator objects have a .next() method
that returns the next value in the
sequence
Generators maintain their state between
calls to .next()
Generators

Example:
Generators

Another example:
Generator Expressions

Identical to list comprehensions, except
that the result is a generator instead of a
list.

for square in ( num**2 for num in numbers ):

print “you got yourself a square! => ”, square
More tips…
Making programs flexible



It makes it much easier to write code when you
can change it easily
I constantly modify my programs as I’m going,
and as such, I’ve developed some good tricks to
make that easier.
Writing your program as if it’s an API that you
can call from the interpreter is an easy way of
testing it

see altavista.py