introduction to python basics. hello world print “hello world!” #2.x print(“hello world!”)...
TRANSCRIPT
Hello Worldprint “Hello World!” #2.xprint(“Hello World!”) #3.x# comments start with ## final ; is optional (and rare)
print “Hello”, “World!”; # spaces inserted (in 2.x, only if no space there)print(“Hello”,”World!”, sep=“ “) # this is the default separator
print “Hello World!”, # no new lineprint(“Hello World!”, end=“ “) # 3.x
print >>sys.stderr, “fatal error”print(“fatal error”, file=sys.stderr) #after import sys
Use 2to3 for automatic conversion!
Python
• Scripting Language• ~ Interpreted (compiled at first call)
– .py or .pyw .pyo or .pyc• Launch the interpreter with: “python”• Integrated development,… edit, debug:
– idle (simple, based on TKinter)• (or python /usr/lib/python2.5/idlelib/idle.py)
– eric4 (based on Qt)– pyCrust (based on wx)
• You need good cooperation between IDE and GUI lib: idle event loop will conflict with wx lib
Libraries vs programs
• Any source file can be used as a library.import mylib // for mylib.pyfrom mylib.submodule import * //nested modulesmylib.fun(0,1) //call function fun in module mylibmylib.submodule.func(1) or simply func(1)
• To know whether the current file is used as a library, or launched as a main program, one can inspect the ‘__name__’ variable.– It will have value “__main__” if in the main prg
• Example:– from PyQt4.QtCore import *– import sys– Lib path added with: sys.path.append(“/Path/dir”)
Code
• Variables:– Variables are references to values/objects– Compare values with ‘x == y’, ‘x<y’– Compare addresses with ‘x is y’, ‘x is not y’– Special object ‘None’ (unique, can be checked by ‘is’)– Types are dynamic, not declared: find with type(x)– Integers and strings are immutable
• Assigning to the variable creates a new object always
• Statements:– Delimitation based on indentation (no ‘;’ for termination)– Each statement is on a separate line– Spaces at the beginning are forbidden, or define sub-blocks (for,
if, while, etc.)
Language elements
• Functions– Subroutine, as usual– May or may not return a value (procedures)
• Methods– Function found to an object
• Operators– Common: +,-,< (assignment =, *=, +=),
(comparison ==, <=, <)– Statements: del, print– newline ending, except in sequences, (), []. {}
Keywords
• and, as, assert, break, class, continue, def, del, elif, else, except, [exec,2x] finally, for, from, global, if, import, in, is, lambda, not, or, pass, print, raise, return, try, while, with, yield
• Assignment ‘=‘ creates new reference. Need copy() for copying object!
Types• Integer: help(int), help(long), help(float), help(complex)
– bool: {True, False} or {1, 0}– int: (typical int, promoted to a long if overflow)
• n.bit_length()size bin(n) # v3.1 only• sys.maxsize (size of a native integer)
– long: (a BigInteger) #in 2.x, int=long in 3.x• 7L (is a long at compilation, or printing)• 0x7 hexa long 7 #0x7L in v2.x• 0b0111 binary 7 bin(7) # only v3.x• 0o7 octal long 7 #07L in v2.x
• / produces truncated int if both operators are int in 2.x, float in 3.x• // real division, always returns truncated
– switch behavior with: from __future__ import division # in 2.x• float
– 5.7 is actually 5.7000000000000002 #3.1 would print 5.7– Decimal (import decimal)
• X=decimal.Decimal(‘5.7’)• F=float(X)
• complex– c=1.2+3.1j
Stringshelp(str), help(bytes) #immutable v3.x help(bytearray) #mutable in 3.xhelp(str), help(unicode) # v2.x• str (byte strings): “latin 1”• unicode: u”Unicode”, u”\N{euro sign}”• binary: bytes.fromhex(‘B9 01EF’) b’\xb9\x01\xef’• rawstrings: r’\u20ac’ ->\\u20ac # verbatim strings• Convert:str.encode() strbytes; str.decode() bytesstr;
bytes(s,encoding=“UTF-8”)• Multiline strings with triple quotes: ‘’’ bla ‘’’
– Escape newline with a slash at the end– Other escapes: bell:\a, backspace:\b, formfeed:\f, verticaltab:\v, unicode:\uhhhh \
Uhhhhhhhh, octal \ooo• Cannot concatenate text and bytes• At concatenation, unicode+str returns a unicode v2.x• A character is a str of length 1
– mystring = chr(13) // a string length 1– unistr = unichr(65535) $v2.x– ord(euro) -> 8364
Strings as sequences
• S=“Therefore”• S[0],S[2],S[-2] -> ‘T’,’e’,’r’• Slicing
– S[:3] -> ‘The’ – S[-3:]->’ore’– S[1:-1:2]->’hrfr’ # sets a step of 2
• Cannot assign a char in a string! S[1]=‘w’– Rather: S[:1]+’w’+S[2:] or ‘w’.join((S[:1],S[2:]))
• Mutable string classes: cStringIO, QString– io.StringIO, io.BytesIO #v3.x
String methods
• [r]find() -> -1, [r]index() -> exception on failure• title() -> capitalize, lower(), upper(), split(x),
replace(x,y),count(x),strip(),startswith(x),isalpha• no printf() but: sys.stdout.write() or
• “The %i %s cost %f dollars” % (3, “fish”, 17.49)
• x in s -> true if x is substring of s• x not in s -> true if x is not substring of s• x + s -> concatenation• s*i -> i times concatenation of s• len(s) -> bytecount for str and chars for unicode• ‘Go {} fast by {}’.format(‘home’,’train’) // v3.1
QString for Qt
mutable, because Qt (C++) has no unicodefrom PyQt4.QtCore import *a = QString(“applet”)b = unicode(“baker”) //2.xprint a + b -> QString “appletbaker”
// Qt returns only QStrings// convert QString to unicode asap, except if the
data will only be feed back to PyQt
Collections• Immutable: tuple, frozenset
• Mutable: list, dict, set
• Tuples:– empty=() one=(1,) two=(1, 3)– three=1, 2, 3 //parentheses optional– len(three) -> 3– three[:-1] // slicing (1,2) – tuple(“Alo”) -> (‘A’,’l’,’o’)– Ex: filename.endswith((“.png”,”.jpg”))
Collections• Lists: like tuples, but mutable, created with square
brackets. Sequences/str can be automatically made lists. Copy with newlist = my_list[:].– For nested collections, use deepcopy() in the ‘copy’ module– mylist.insert(4, “element”) or mylist[4:4]=[“element”]– del mylist[4] or mylist[4:5]=[]– remove(x) # removes the leftmost occurrence of x– x in L – x not in L – L+m // concatenation or l.extend(m)– sort([key=]), pop(i), reverse(), append(x), count(x), index(x),
pop() //pops rightmost, – zip(x,y) aggregates corresponding elems in x and y; zip(*a)
unzips– (a,*rest,b) = range(5) a=0, rest=[1,2,3], b=4
More Collections• Dictionary, like HashMap:
– insects = {“Dragonfly”:500, “Beetle”:2000}– insects[“Beetle”]=200– del insects[“Beetle”] or insects.pop(“Beetle”)– vitamins=dict(B12=100, B6=250, A=38)
//only if the key is not number or keyword!– x in d, x not in d, len(d)– Methods:
• clear(), copy()->shallow copy,• keys(), values(), items() list of tuples (key,value) in 2
– views in 3.x (type->dict_keys)!» use sorted(d.keys()) instead !d.keys().sort()
• get(k,default_if_x_not_inside), setdefault(k,x_if_k_not_inside)
• update(dict(a=3)) //updates by changing/adding key/value pairs
Sets
• Like Dictionaries without values
• Like lists (created from a sequence):– unicorn = set((“Narwahl”, “Oryx”, “Eland”))– frozenset() immutable– “Goat” in unicorn– Methods: add(x), remove(x), union(t),
intersection(t), difference(t), discard(x), clear(), copy(), issubset(t), issuperset(t)
Built-insSequences:
– all(q), any(q), x [not] in q, len(q), max(q), min(q), sum(q)help(cmd), dir(x) // lists all attributes, e.g. of a modulehasattr(x,a) // x has attribute aid(x) // hashisinstance(x,C) // accounts for inheritancetype(x)eval(s)open(f,m) // open file f in mode m: “w” “r”, “wb”, “rb”, “r+b”
filehandle.read()//read entire file. filehandle.readline(read a line) //write(),seek(),close()import pickle // pickle.dump(x,file) x=pickle.load(f)
serializationrange(i) range(start,end,step) // [0..i-1], //lazy since 3.xMath: abs(n), divmod(i,j) (i/j,i%j), hex(i), oct(i), float(x),
int(x), long(x), pow(x, y[, m]), round(x,n)//n decimals
Tests
• False=0,False,None, PyQt obj with isNull()
• Check objects with bool(QDate())
if 1 <= x <= 10:
pass
:?
Instead of test?x:y
x if test else y
and-or tricks:test and x or y # works only if bool(x)==True
(test and [x] or [y])[0]
For
for var in iteratable: //xrange() for lazy eval in 2.xblockbreak/continue
else:branch
# may not change iteratable while looping# if have to change, create copy....! E.g keys()#for var in sorted(dict): //list of sorted keys# iterkeys(), itervalues(), iteritems() //2.x only: do not provide
copies and are faster... do not modify underlying dict!#iteratables have a next() and raise StopIteration exception# for key, val in dictionary:
enumerate
• enumerate(string)– returns a tuple(index, character)
• Example:
for i, char in enumerate(“10 km”):
list comprehension & generators
• List comprehension– [x for x in range(50) if x % 5 == 0]
– [(key,dictionary[key]) for key in sorted_keys]
– [ x for x in (1 , 2, 3)] # v3.x
• Generator (lazy evaluation):– (x for x in range(50) if x % 5 == 0)
• Dictionary comprehension:– {k: chr(65+k) for k in range(4)}
Functions, Methods, Lambda
# functions must be defined before usagedef funName(params):
“””docstring“””blockyield val // existence of yield make the function a generatorreturn val // without explicit return, returns None//function end without return raises StopIteration for generators
# parameter are by ref (for immutable types)# functions defined in functions are local# providing a default value: def frange(arg0, arg1=None,arg2=None) gen=frange(5,arg2=“Blah”) # positional & named gen.next() # may call next on obj returned by generator function# Lambda: // cannot contain loops, branches, or return statements cube = lambda x: pow(x, 3) # can use and-or trick (:?)# reduce applies a function of 2 parameters on a list, reducing it to a value
reduce(lambda x, y: x+y, [1,2,3,4,5]) #calculates (((((1+2)+3)+4)+5)map(lambda x, y: x+y, [1,2,3,4,5],[1,1,1,1,1]) #calculates [2,3,4,5,6]
#variable list of arguments with: def fun( *args) # -> args will be a tuple with all argumentsdef fun( * arg1, arg2) # possible in 3.x, all arguments after * must be specified with keywords
Partial Function Application
import functools
def myfun(a, b):
return a+b
parfun = functools.partial(myfun, 2)
parfun(3) -> 5
Exception Handling
class SimpleException(Exception): passfilehandle=Nonetry:
block // e.g. filehandle = open(“file”)if wrong: raise SimpleException, “Troubles”
except exceptions_tuple: passexcept: pass //catches any exceptionelse:
print “No exception happened!”finally:
fin // e.g.: if filehandle: filehandle.close()
#exceptions are useful to break out of deeply nested loops
Assert
• Rather than exceptions, may use assert:
def fun(a, b):assert a or b // raises AssertionError
Classes and ModulesChap 3
• support– operators– collection types (in, len())– inheritance: root is “object”– all methods are public– instances names with leading _ are private
• the names not imported with: from xxxx import *– names with _ _ are “very private” (if no ending _ _)
• the names are mangled on import:– class MyClass method _ _ method becomes: _myClass_ _method
class myclass(base_class):“”” my first class “””def __init__(self): passdef meth1(self):pass
Build Objects
methods starting & ending with _ _ are special:
__new__() allocates the object… rarely used__init__() initializes the created object__del__() called on garbage collection
Guarantee cleanup trigger with try…finallyAll methods have first parameter “self” (name can
be changed!)Create attributes as: self.attr=1
Properties
class Rectangle(object):def _ _init_ _(self, width, height):
self._ _width = widthself.height = height
def _area(self):return self._ _width * self.height # ‘self.’ is required!
area = property(fget=_area) # redefines field as method
def _width(self): return self._ _widthdef _setWidth(self, width): self._ _width = widthwidth = property(fget=_width, fset=_setWidth) # get & set
Special Methods
__init__ x=X()__call__ x()__eq__ x==y__ne__ x!=y <>__le__ x<=y__lt__ x<y__ge__ x>=y__gt__ x>yraise
NotImplementedErrordefault ops for x…y is
__cmp__ //2.x
__nonzero__ if x:
__repr__ y = eval(‘x’)
__str__ print x
__unicode__ print x
__getattr__ raise AttributeError
__getattribute__ x.i
__setattr__ x.i=1
More
__float__ float(x)__abs__ abs(x)__add__ x+y__iadd__ x+=y__radd__ y+x__mul__ x*y__imul__ x*=y__rmul__ y*x__floordiv__ x//y__ifloordiv____rfloordiv__
__int__ int(x)__neg__ -x__sub__ x-y__isub__ x-=y__rsub__ y-x__mod____imod____rmod____truediv__ x/y__itruediv____rtruediv__
repr
• repr returns the string of a constructor call to create the data: repr(x) (or `x` in v2.x)– the result should run if given as param to eval.– if no __str__, print x will use x.__repr__()
– “%r” in printf will automatically add quotes for strings, but not for numbers
Others
• There are also C-like bitshifting operators and octal, hexa conversion– <<,>>,&,|,^,~
• += add used if iadd (in-place add) not implemented• radd used if no available add for the left operand• __slots__ attribute of a class can be used to compactly
store more attributes (~5 times). Can contain __dict__ for dynamic new fields. Can be used only with fixed-size fields.__slots__=(‘a’,’b’)
Static Data & Methods
class Ballon(object):unique_colors = set() // static datadef __init__(self,color):
self.color = colorBalloon.unique_colors.add(color)
@staticmethod # decorator, one way of doingdef uniqueColorCount(): return len(Balloon.unique_colors)
def uniqueColors(): # the other wayreturn Balloon.unique_colors
uniquecolors = staticmethod(uniqueColors)
Decorators
• Can write own decorators (e.g. to log the method call, to update other values):– @logger– @recalculate
• ClassMethods are like static methods, but take as first parameter the class on which they are called: typically named “cls”– prefixed with decorator @classmethod
• Automatic elimination of tail recursion with @tailcall
Define logger exampledef trace( aFunc ): """Trace entry, exit and exceptions.""“ def loggedFunc( *args, **kw ):
print "enter", aFunc.__name__ try:
result= aFunc( *args, **kw ) except Exception, e:
print "exception", aFunc.__name__, e raise e
print "exit", aFunc.__name__ return result loggedFunc.__name__= aFunc.__name__ loggedFunc.__doc__= aFunc.__doc__ return loggedFunc
class MyClass( object ): @trace def __init__( self, someValue ): """Create a MyClass instance.""" self.value= someValue @trace def doSomething( self, anotherValue ): """Update a value.""“ self.value += anotherValue
>>> mc= MyClass( 23 ) enter __init__exit __init__
>>> mc.doSomething( 15 ) enter doSomething exit doSomething
>>> mc.value 38
Collection classes
• should implement corresponding methods• exceptions:
– mappings,sets: KeyError– sequences: IndexError
• Special Methods:__contains__ y in x__len__ len(x)__getitem__ c[k]__setitem__ x[k]=v__delitem__ del x[k]__iter__ for ... in x:
Inheritanceclass Painting(Item):
def __init__(self, artist, title, year=None):#super(Painting, self).__init__(artist, title,year) # previous
meth#Item.__init__(self,artist,title,year) # preferred for control
Two ways to call super __init__. Does not have to be the first call (unlike java). Does not have to be called if there is no parameter.
#Multiple inheritance: do it consistently, either use supper in all classes, or never.
Check if an object has method “title” with:
hasattr(item,”title”) and callable(item.title)isInstance(item, Item)
Abstract classes: all methods raise NotImplementedError
Modules
• A module can be a directory.– The directory should contain: __init__.py
• which could be empty
• shorten module names: – import mylib.length as length
Doctest
def add(x,y):“”” Adds two numbers. Doctest results for expected failures may be “Traceback (most recent call last):...IndexError: list”
>>> add(1,3)4“””return x+y
if __name__ == “__main__”:import doctestdoctest.testmod()
Packages
• There are many useful packages with extensions. E.g.:import bisect
bisect.insort_left(sorted_sequence,key) //inserts
bisect.bisect_left(sorted_sequence,key)//find
//index
Internationalization
• Qt provides QtLinguist (Chap 17)
• Have to provide strings with: QApplication.translate(“context”,”string”)
OS access
import osos.listdir(“/dir”) list of file names (bytes or strs,
function on what the parameter is)if parameter is str, files that are bytes are omitted
os.getcwdb() current working directory as bytesos.environ[‘HOME’] encoding defined by default
set with the LANG environment in UNIXos.path.dirname(__file__) path to local fileos.system(“echo \”Hello World!\””)