Saturday, November 8, 2008

Simple Python Syntax

Start interpreter and print out something then exit
ActivePython (ActiveState Software Inc.) based on
Python 2.5.2 (r252:60911, Mar 27 2008, 17:57:18) [MSC v.1310 32 bit (Intel)] on
Type "help", "copyright", "credits" or "license" for more information.
>>> print 'hello world'
hello world
>>> print 1+2+3
>>> exit()
Run a script in the interpreter
To run a script within Python interpreter use execfile(path), it is useful for people who use Jython, because startup time of JVM is horrible . e.g
Create string from a template
This is one of my most frequently used statement, Python follow style of C printf function
>>> "my name is %s, my age is %d" % ("Goto",30)
'my name is Goto, my age is 30'
Ruby has the same function
irb(main):004:0> "my name is %s, my age is %d" % ["Goto",30]
=> "my name is Goto, my age is 30"
but there is nicer way to do it
irb(main):005:0> name,age = "Goto",31
=> ["Goto", 31]
irb(main):006:0> "my name is #{name}, my age is #{age}"
=> "my name is Goto, my age is 31"
Create a substring from a string
Python has nice methods get a substring from string
>>> s='hello world'
>>> s[0]
>>> s[0:10] #substring from a position(inclusive) until other (non inclusive)
'hello worl'
>>> s[2:] #substring to end of string
'llo world'
>>> s[:2] #substring from start until other (non inclusive)
>>> s[-2:] #negative position indicates position from end of the string
The equivalent in Ruby would be
$ irb
>> s="hello world"
=> "hello world"
>> s[0]
=> 104
>> s[0..0]
=> "h"
>> s[0..(10-1)] #unlike Python, Ruby includes the end position
=> "hello worl"
>> s[2..-1] # -1 indicate relative position from end
=> "llo world"
>> s[0..(2-1)]
=> "he"
>> s[-2..-1]
=> "ld"
Unlike Ruby, Python still throw out of range exception for single indice operation
>>> s[20]
Traceback (most recent call last):
  File "", line 1, in 
IndexError: string index out of range
>>> s[20:30] # this is OK as it consider as slice operation
String is immutable
Unlike Ruby, Python string can not be changed directly
>>> s[0:5]
>>> s[0:5]="bye"
Traceback (most recent call last):
  File "", line 1, in 
TypeError: 'str' object does not support item assignment
>>> s1 = "bye" + s[5:] # to achieve the same goal we need create string from other string 
>>> print s1
bye world
In Ruby we can do
>> s[0..4]="bye"
=> "bye"
>> print s
bye world=> nil
As string is considered value object, create new string instead of changing an existing express that concept more clearly.
List and tuple
Python has tuple and list for representation of variable size array of items. Tuple is immutable array while list is mutable. People think that list is intended for homogeneous while tuple is for non-homogeneous, but this is convention only is not enforced by the language. However some api accept only tuple as argument e.g. String format %, that sometime lead to a confusion. In contras Ruby has only Array.
example of tuple
>>> y=('a',2)
>>> y[1]=1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>> y
('a', 2)
example of list
>>> x=['a',2]
>>> x[1]=1
>>> x
['a', 1]
iterate over list or tuple
>>> items = ('a','b',2)
>>> for e in items:
...   print e
Hash aka dictionary
Python has hash structure called dictionary
>>> h = {1:'a',2:'b',3:'c'}
>>> h.__class__
<type 'dict'>
>>> h[3] = 'z'
>>> h
{1: 'a', 2: 'b', 3: 'z'}
iterate over dictionary
>>> for k,v in h.iteritems():
...   print "%d=>%s" % (k,v)
h.items() also works well
Class, Object, method
Class is defined using class keyword, name of a class can start lower case or upper case character, which is different from Ruby. Ruby requires name of class start with upper case character.
However the convention is that, name of built-in class as string, unicode, list, tuple start with lower case character while user-defined class starts with upper case.
example of built-in class
>>> y = ('a',2)
>>> y.__class__
<type 'tuple'>
>>> y.__class__ == tuple
>>> z = tuple(y)
>>> z
('a', 2)
example of user defined class
>>> class Foo:
...   def m(self):
...     print self.__class__
>>> Foo().m()
Every Python script store in a file is a module, the name of the file is module name.
$ cat
def say(whom):
  return "hello %s" % whom
To use method defined in a module, just import the module and call the function preceding by the module name plus '.'
>>> import hello
>>> hello.say('world')
'hello world'
It is also common to mix module methods into current name space, so we can call method without typing module name
>>> from hello import *
>>> say('moon')
'hello moon'
Beside normal position based parameters, Python has two extra forms of passing parameters to a function *params and **params.
The first form is argument list, in which caller pass a list parameters and calling function receives them in form of an array.
 def foo(*numbers):
      return sum(numbers)
print foo(23, 42)        # prints: 65
The second form is name based, in which caller pass a list name,value pairs and calling function receives then as a hash map.
def bar(**options):
  if "verbose" in options and options["verbose"]:
     print "verbose is ON"
     print "verbose is OFF"

bar(verbose=True) # print: "verbose is ON"
bar(verbose=False) # print: "verbose is OFF"
bar(force=True) # print: "verbose is OFF"

Python closures

No comments: