Jump to content
xisto Community

marekdudek

Members
  • Content Count

    8
  • Joined

  • Last visited

About marekdudek

  • Rank
    Newbie
  • Birthday 10/13/1976

Contact Methods

  • Website URL
    http://

Profile Information

  • Gender
    Male
  • Location
    Poland, Wrocław
  1. Hello again Fourth lesson concerns functional programming capabilities embedded with Python. Whole code is: #! /usr/bin/env python# -*- coding: utf-8 -*-import random# ---------------------------------------------------------------------------def lambdaCalculus() : f1 = lambda x: x + 2 lst = range( 5 ) assert lst == [ 0, 1, 2, 3, 4 ] assert [ f1(x) for x in lst ] == [ 2, 3, 4, 5, 6 ] f2 = lambda x: f1(x) assert f2( 3 ) == 5 factorial = lambda n: n * factorial( n - 1 ) if n > 0 else 1 f = [ factorial( i ) for i in range( 6 ) ] assert f == [ 1, 1, 2, 6, 24, 120 ] identity = lambda x: x max = 100 for i in range( max ) : n = random.randint( 1, max * max ) assert n == identity( n ) sum = lambda x,y: x+y assert sum( 2, 3 ) == 5# ---------------------------------------------------------------------------def functionals() : lst = range( 1, 11 ) # 'map' function def f1(x) : return x*2 def f2(x) : return x**2 def f3(x) : return x**3 assert lst == [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ] assert map( f1, lst ) == map( lambda x: 2*x , lst ) == [ 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 ] assert map( f2, lst ) == map( lambda x: x**2, lst ) == [ 1, 4, 9, 16, 25, 36, 49, 64, 81, 100 ] assert map( f3, lst ) == map( lambda x: x**3, lst ) == [ 1, 8, 27, 64, 125, 216, 343, 512, 729, 1000 ] def f(x, y) : return x+y lst2 = [ x*2 for x in lst ] assert map( f, lst, lst2 ) == [3, 6, 9, 12, 15, 18, 21, 24, 27, 30 ] # 'filter' function def even(x) : return x%2==0 def odd(x) : return x%2<>0 assert filter( even, lst ) == filter( lambda x: x%2==0, lst ) == [2, 4, 6, 8, 10] assert filter( odd , lst ) == filter( lambda x: x%2<>0, lst ) == [1, 3, 5, 7, 9 ] # 'reduce' function lst = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ] assert reduce( lambda x,y: x+y , lst ) == 55 # another way to calculate factorial def factorial( n ) : return reduce( lambda x,y: x*y, range(1, n+1), 1 ) assert factorial( 0 ) == 1 assert factorial( 1 ) == 1 assert factorial( 2 ) == 2 assert factorial( 3 ) == 6 assert factorial( 4 ) == 24 assert factorial( 5 ) == 120 def sum( x, y ) : return x+y assert reduce( sum, [1, 2, 3] ) == 6 assert reduce( sum, [1, 2 ] ) == 3 assert reduce( sum, [1 ] ) == 1 # ---------------------------------------------------------------------------def usefulFunctions() : # 'enumerate' fun = lambda x: x*2+2 X = map( fun, range( 11 ) ) print 'index value' print '-----------' for index, x in enumerate( X ) : print '%5d %5d' % (index, x) assert [ (x, index) for x, index in enumerate( X ) ] == [ (0, 2), (1, 4), (2, 6), (3, 8), (4, 10), (5, 12), (6, 14), (7, 16), (8, 18), (9, 20), (10, 22) ] D = { 'one':1, 'two':2, 'three':3 } print 'index key' print '-----------' for index, k in enumerate( D ) : print '%5d %5s' % (index, k ) print 'index key value' print '-----------------' for index, (k, v) in enumerate( D.items() ) : print '%5d %5s %5d' % (index, k, v ) # 'zip' fun = lambda x: x**2 X = range( 5, 11 ) Y = map( fun, X ) print 'arg value' print '---------' for x, y in zip( X, Y ) : print '%3d %5d' % (x, y) Z = map( lambda x: x**3, X ) print 'arg value value' print '---------------' for x, y, z in zip( X, Y, Z ) : print '%3d %5d %5d' % (x, y, z)# ---------------------------------------------------------------------------def unpacking() : a, b, c = 1, 2, 3 ( a, b, c ) = ( 1, 2, 3 ) X = [3, 4, 5] Y = map( lambda x: x*x, X ) for x, y in zip( X, Y ) : print '%s %s' % (x, y) for (x, y) in zip( X, Y ) : print x, y for i, x in enumerate( X ) : print i, x for (i, x) in enumerate( X ) : print i, x assert [ '%s %s' % (x, y) for x, y in zip( X, Y ) ] == ['3 9', '4 16', '5 25'] assert [ '%s %s' % (x, y) for (x, y) in zip( X, Y ) ] == ['3 9', '4 16', '5 25'] try : ( a, b, c ) = ( 1, 2 ) assert False except ValueError, ve : assert str(ve) == 'need more than 2 values to unpack' try : ( a, b ) = ( 1, 2, 3 ) assert False except ValueError, ve : assert str(ve) == 'too many values to unpack' a, b = 1, (2, 3) c, d = b assert a == 1 and c == 2 and d == 3 a, (c, d) = 1, (2, 3) assert a == 1 and c == 2 and d == 3# ---------------------------------------------------------------------------if __name__ == '__main__' : lambdaCalculus() functionals() usefulFunctions() unpacking() Let's look closer. Lambda functions Very useful is possibility to create lambda functions (based on lambda calculus theoretical notation). General for is lambda arguments: expressionwhich is equivalent to def name(arguments): return expressionExamples of declaration: lambda x _linenums:0'>f1 = <strong class='bbc'>lambda</strong> x: x + 2 lst = range( 5 ) <strong class='bbc'>assert</strong> lst == [ 0, 1, 2, 3, 4 ] <strong class='bbc'>assert</strong> [ f1(x) <strong class='bbc'>for</strong> x <strong class='bbc'>in</strong> lst ] == [ 2, 3, 4, 5, 6 ]Example with two arguments: lambda x,y _linenums:0'>sum = <strong class='bbc'>lambda</strong> x,y: x+y <strong class='bbc'>assert</strong> sum( 2, 3 ) == 5Lambda function can use names from outside of it's scope: lambda x _linenums:0'>f2 = <strong class='bbc'>lambda</strong> x: f1(x) <strong class='bbc'>assert</strong> f2( 3 ) == 5Lambda function may evaluate to a reference: lambda x _linenums:0'>identity = <strong class='bbc'>lambda</strong> x: x max = 100 <strong class='bbc'>for</strong> i <strong class='bbc'>in</strong> range( max ) : n = random.randint( 1, max * max ) <strong class='bbc'>assert</strong> n == identity( n )Lambda functions can be recursive: lambda n _linenums:0'>factorial = <strong class='bbc'>lambda</strong> n: n * factorial( n - 1 ) <strong class='bbc'>if</strong> n > 0 <strong class='bbc'>else</strong> 1 f = [ factorial( i ) <strong class='bbc'>for</strong> i <strong class='bbc'>in</strong> range( 6 ) ] <strong class='bbc'>assert</strong> f == [ 1, 1, 2, 6, 24, 120 ]While You can name and reuse lambda function they are very often used as anonymous functions, ie. defined exactly (inline) where they're used, we'll see examples further. Functionals There are three functions in Python that behave like functionals. They are map(), filter() and reduce(). Let's see their usage. map() accepts function and collection and creates list of results of applying a function to elements of collection def f1(x) _linenums:0'>lst = range( 1, 11 ) <strong class='bbc'>def</strong> f1(x) : <strong class='bbc'>return</strong> x*2 <strong class='bbc'>def</strong> f2(x) : <strong class='bbc'>return</strong> x**2 <strong class='bbc'>def</strong> f3(x) : <strong class='bbc'>return</strong> x**3 <strong class='bbc'>assert</strong> lst == [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ] <strong class='bbc'>assert</strong> map( f1, lst ) == map( <strong class='bbc'>lambda</strong> x: 2*x , lst ) == [ 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 ] <strong class='bbc'>assert</strong> map( f2, lst ) == map( <strong class='bbc'>lambda</strong> x: x**2, lst ) == [ 1, 4, 9, 16, 25, 36, 49, 64, 81, 100 ] <strong class='bbc'>assert</strong> map( f3, lst ) == map( <strong class='bbc'>lambda</strong> x: x**3, lst ) == [ 1, 8, 27, 64, 125, 216, 343, 512, 729, 1000 ](note anonymous function usage). More than one collection can be passed. In this case result of map() is a list of results of calling a function of multiple arguments (as many as collections). Function must accept multiple arguments. def f(x, y) _linenums:0'><strong class='bbc'>def</strong> f(x, y) : <strong class='bbc'>return</strong> x+y lst2 = [ x*2 <strong class='bbc'>for</strong> x <strong class='bbc'>in</strong> lst ] <strong class='bbc'>assert</strong> map( f, lst, lst2 ) == [3, 6, 9, 12, 15, 18, 21, 24, 27, 30 ] filter() accepts function (a predicate) and collection returning as a result a list of elements from collection that the predicate evaluates to True: def even(x) _linenums:0'><strong class='bbc'>def</strong> even(x) : <strong class='bbc'>return</strong> x%2==0 <strong class='bbc'>def</strong> odd(x) : <strong class='bbc'>return</strong> x%2<>0 <strong class='bbc'>assert</strong> filter( even, lst ) == filter( lambda x: x%2==0, lst ) == [2, 4, 6, 8, 10] <strong class='bbc'>assert</strong> filter( odd , lst ) == filter( lambda x: x%2<>0, lst ) == [1, 3, 5, 7, 9 ] reduce() accepts (binary, ie. two-argument) function and collection and returns single value. This value is a result of applying function to 1st and 2nd elements and then the result to 3rd, 4th and so on (or simply the only element if collection's length is 1): assert reduce( lambda x,y _linenums:0'>lst = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]<strong class='bbc'>assert</strong> reduce( <strong class='bbc'>lambda</strong> x,y: x+y , lst ) == 55<strong class='bbc'>def</strong> sum( x, y ) : <strong class='bbc'>return</strong> x+y<strong class='bbc'>assert</strong> reduce( sum, [1, 2, 3] ) == 6<strong class='bbc'>assert</strong> reduce( sum, [1, 2 ] ) == 3<strong class='bbc'>assert</strong> reduce( sum, [1 ] ) == 1 reduce() may accept additional third value that is returned in special case when passed collection is empty. We will use it to define factorial once more: def factorial( n ) _linenums:0'><strong class='bbc'>def</strong> factorial( n ) : <strong class='bbc'>return</strong> reduce( <strong class='bbc'>lambda</strong> x,y: x*y, range(1, n+1), 1 ) <strong class='bbc'>assert</strong> factorial( 0 ) == 1 <strong class='bbc'>assert</strong> factorial( 1 ) == 1 <strong class='bbc'>assert</strong> factorial( 2 ) == 2 <strong class='bbc'>assert</strong> factorial( 3 ) == 6 <strong class='bbc'>assert</strong> factorial( 4 ) == 24 <strong class='bbc'>assert</strong> factorial( 5 ) == 120 Other functions useful for collection processing enumerate(lst) is useful to iterate over list and it's indexes, example of usage: lambda x _linenums:0'>fun = <strong class='bbc'>lambda</strong> x: x*2+2 X = map( fun, range( 11 ) ) <strong class='bbc'>for</strong> index, x <strong class='bbc'>in</strong> enumerate( X ) : <strong class='bbc'>print</strong> '%5d %5d' % (index, x)More formally: enumerate() function returns enumerate object whose next() method returns tuple containing index and element of iterated-over collection. In example above next() method is not explicitly called, for loop calls it behind the scenes. Also during list comprehension, by the way: assert [ (x, index) for x, index in enumerate( X ) ] == [ (0, 2), (1, 4), (2, 6), (3, 8), (4, 10), (5, 12), (6, 14), (7, 16), (8, 18), (9, 20), (10, 22) ] _linenums:0'><strong class='bbc'>assert</strong> [ (x, index) <strong class='bbc'>for</strong> x, index <strong class='bbc'>in</strong> enumerate( X ) ] == [ (0, 2), (1, 4), (2, 6), (3, 8), (4, 10), (5, 12), (6, 14), (7, 16), (8, 18), (9, 20), (10, 22) ] Enumerating a dictionary: D = { 'one':1, 'two':2, 'three':3 } <strong class='bbc'>for</strong> index, k <strong class='bbc'>in</strong> enumerate( D ) : <strong class='bbc'>print</strong> '%5d %5s' % (index, k ) <strong class='bbc'>for</strong> index, (k, v) <strong class='bbc'>in</strong> enumerate( D.items() ) : <strong class='bbc'>print</strong> '%5d %5s %5d' % (index, k, v )As in "dictionary" comprehension, simple dictionary reference iterates over keys only (first usage above). To iterate over key-value pair use items() method (second usage). zip( col1, col2 , ...) returns list of tuples so that first tuple contains first element from col1 and col2 (and col3 ...), second tuple contains second element from col1 and col2 (and col3 ...) and so on: lambda x _linenums:0'>fun = <strong class='bbc'>lambda</strong> x: x**2 X = range( 5, 11 ) Y = map( fun, X ) <strong class='bbc'>for</strong> x, y <strong class='bbc'>in</strong> zip( X, Y ) : <strong class='bbc'>print</strong> '%3d %5d' % (x, y) Z = map( <strong class='bbc'>lambda</strong> x: x**3, X ) <strong class='bbc'>for</strong> x, y, z <strong class='bbc'>in</strong> zip( X, Y, Z ) : <strong class='bbc'>print</strong> '%3d %5d %5d' % (x, y, z) Unpacking:Explanation of mechanism that we used before without knowing it exists: whenever we use comma notation in constructs like: lambda x _linenums:0'>X = [3, 4, 5]Y = map( <strong class='bbc'>lambda</strong> x: x*x, X ) [color= #FF0000]a, b, c[/color] = [color= #00FF00]1, 2, 3[/color]<strong class='bbc'>for</strong> [color= #FF0000] i, x[/color] <strong class='bbc'>in</strong> enumerate( X ) : <strong class='bbc'>print</strong> i, x<strong class='bbc'>assert</strong> [ '%s %s' % (x, y) <strong class='bbc'>for</strong> [color= #FF0000]x, y[/color] <strong class='bbc'>in</strong> zip( X, Y ) ] == ['3 9', '4 16', '5 25']in reality we operate on (implicitly created) tuple(s), omiting parentheses is only a shorthand. Above statements are equivalent to ( a, b, c ) = 1, 2, 3 for (i, x) in enumerate( X ) _linenums:0'>( a, b, c ) = 1, 2, 3<strong class='bbc'>for</strong> (i, x) <strong class='bbc'>in</strong> enumerate( X ) : <strong class='bbc'>print</strong> i, x<strong class='bbc'>assert</strong> [ '%s %s' % (x, y) <strong class='bbc'>for</strong> (x, y) <strong class='bbc'>in</strong> zip( X, Y ) ] == ['3 9', '4 16', '5 25'] The process of matching values from result tuple to corresponding references of newly created tuple is called unpacking. (Expression in green also implicitly creates tuple contrary to comma separated arguments to print statement. Of course no unpacking is involved). Since Python allows us to construct functions and expressions that may generally return tuples of unknown length we may encounter (and handle) run-time error during unpacking: try _linenums:0'><strong class='bbc'>try</strong> : ( a, b, c ) = ( 1, 2 ) <strong class='bbc'>assert</strong> False <strong class='bbc'>except</strong> ValueError, ve : <strong class='bbc'>assert</strong> str(ve) == 'need more than 2 values to unpack' <strong class='bbc'>try</strong> : ( a, b ) = ( 1, 2, 3 ) <strong class='bbc'>assert</strong> False <strong class='bbc'>except</strong> ValueError, ve : <strong class='bbc'>assert</strong> str(ve) == 'too many values to unpack'More complicated unpacking is involved when collection being unpacked is nested: assert a == 1 and c == 2 and d == 3 a, (c, d) = 1, (2, 3) assert a == 1 and c == 2 and d == 3 _linenums:0'>a, b = 1, (2, 3) c, d = b <strong class='bbc'>assert</strong> a == 1 <strong class='bbc'>and</strong> c == 2 <strong class='bbc'>and</strong> d == 3 a, (c, d) = 1, (2, 3) <strong class='bbc'>assert</strong> a == 1 <strong class='bbc'>and</strong> c == 2 <strong class='bbc'>and</strong> d == 3 This last code snippet at last explains notation while enumerating over items of dictionary: for index, (k, v) in enumerate( D.items() ) _linenums:0'><strong class='bbc'>for</strong> [color= #FF0000]index, (k, v)[/color] <strong class='bbc'>in</strong> enumerate( D.items() ) : <strong class='bbc'>print</strong> '%5d %5s %5d' % (index, k, v ) That's all for now. Exception handling in next part.Happy New Year to everybody
  2. Hello again Third part of tutorial presents very useful feature called list comprehension. Whole code: #! /usr/bin/env python# -*- coding: utf-8 -*-import mathimport cmathimport types# ---------------------------------------------------------------------------def squareList1( lst ) : result = [] for el in lst : result.append( math.sqrt( el ) ) return resultdef squareList2( lst ) : result = [ math.sqrt( el ) for el in lst ] return resultdef squareList3( lst ) : return [ math.sqrt( el ) for el in lst ]def squareList4( lst ) : return [ math.sqrt( el ) if el >= 0 else cmath.sqrt( el ) for el in lst ]# ---------------------------------------------------------------------------def listComprehension() : l = [ 1, 4, 9, 16, 25 ] assert type( l ) == types.ListType assert squareList1( l ) == squareList2( l ) assert squareList1( l ) == squareList3( l ) assert squareList2( l ) == squareList3( l ) l = [ 1, 4, -9, 16, 25 ] assert squareList4( l ) == [1.0, 2.0, 3j, 4.0, 5.0] # ---------------------------------------------------------------------------def tupleComprehension(): t = ( 1, 4, 9, 16, 25 ) assert type( t ) == types.TupleType assert squareList3( t ) == [1.0, 2.0, 3.0, 4.0, 5.0] assert type( squareList3( t ) ) == types.ListType# ---------------------------------------------------------------------------def dictComprehension() : d = { 1: 'one', 2: 'two', 3: 'three' } assert type( d ) == types.DictType assert [ str( v ) + str( k ) for k, v in d.items() ] == [ 'one1', 'two2', 'three3' ] assert [ k for k in d ] == [ 1, 2, 3 ] assert [ k for k in d.keys() ] == [ 1, 2, 3 ] assert [ v for v in d.values() ] == [ 'one', 'two', 'three' ]# ---------------------------------------------------------------------------def conditionalComprehension() : l = range( 5 ) assert l == [ 0, 1, 2, 3, 4 ] evens = [ el for el in l if el % 2 == 0 ] odds = [ el for el in l if el % 2 <> 0 ] assert evens == [ 0, 2, 4 ] assert odds == [ 1, 3 ]# ---------------------------------------------------------------------------def complexComprehensions() : l = range( 5 ) assert l == [ 0, 1, 2, 3, 4 ] l2 = [ el + len( l ) for el in l if l[el] % 2 == 0 ] assert l2 == [ 5, 7, 9 ] a = 0.5 l3 = [ el + a for el in l ] assert l3 == [ 0.5, 1.5, 2.5, 3.5, 4.5 ] l4 = [ [ el, 3*el ] for el in l ] assert l4 == [[0, 0], [1, 3], [2, 6], [3, 9], [4, 12]] t5 = [ ( el, 3*el ) for el in l ] assert t5 == [(0, 0), (1, 3), (2, 6), (3, 9), (4, 12)] d6 = [ { el : 3*el } for el in l ] assert d6 == [{0: 0}, {1: 3}, {2: 6}, {3: 9}, {4: 12}]# ---------------------------------------------------------------------------def multipleListComprehensions() : l1 = [ 0, 1 ] l2 = [ 2, 3 ] l3 = [ 4, 5 ] l4 = [ 6, 7 ] assert [ ( e1, e2 ) for e1 in l1 for e2 in l2 ] == [ (0, 2), (0, 3), (1, 2), (1, 3) ] assert [ ( e1, e2, e3 ) for e1 in l1 for e2 in l2 for e3 in l3 ] == [ (0, 2, 4), (0, 2, 5), (0, 3, 4), (0, 3, 5), (1, 2, 4), (1, 2, 5), (1, 3, 4), (1, 3, 5) ] assert [ ( e1, e2, e3, e4 ) for e1 in l1 for e2 in l2 for e3 in l3 for e4 in l4 ] == [ (0, 2, 4, 6), (0, 2, 4, 7), (0, 2, 5, 6), (0, 2, 5, 7), (0, 3, 4, 6), (0, 3, 4, 7), (0, 3, 5, 6), (0, 3, 5, 7), (1, 2, 4, 6), (1, 2, 4, 7), (1, 2, 5, 6), (1, 2, 5, 7), (1, 3, 4, 6), (1, 3, 4, 7), (1, 3, 5, 6), (1, 3, 5, 7) ] def xor( b1 , b2, b3 ) : """Exclusive 'or' True if and only if exactly one of arguments is true """ return ( b1 and not (b2 or b3) ) or \ ( b2 and not (b1 or b3) ) or \ ( b3 and not (b1 or b2) ) b = [ False, True ] assert [ ( b1, b2, b3 ) for b1 in b for b2 in b for b3 in b if xor( b1, b2, b3 ) ] == [ (False, False, True), (False, True, False), (True, False, False) ]# ---------------------------------------------------------------------------if __name__ == '__main__' : listComprehension() tupleComprehension() dictComprehension() conditionalComprehension() complexComprehensions() multipleListComprehensions() Earlier we used to process list using loop constructs. While it can be done that way in most cases more elegant and efficient way exists: list comprehension. Simplest form looks like this: [ expression for variable in list ] and as a result produces a list. It is equivalent for: result = []for el in list : result.append( expression( el ) )return result Lets see how example from the first post evolve: def squareList1( lst ) _linenums:0'><strong class='bbc'>def</strong> squareList1( lst ) : result = [] <strong class='bbc'>for</strong> el <strong class='bbc'>in</strong> lst : result.append( math.sqrt( el ) ) <strong class='bbc'>return</strong> result<strong class='bbc'>def</strong> squareList2( lst ) : result = [ math.sqrt( el ) <strong class='bbc'>for</strong> el <strong class='bbc'>in</strong> lst ] <strong class='bbc'>return</strong> result<strong class='bbc'>def</strong> squareList3( lst ) : <strong class='bbc'>return</strong> [ math.sqrt( el ) <strong class='bbc'>for</strong> el <strong class='bbc'>in</strong> lst ]<strong class='bbc'>def</strong> listComprehension() : l = [ 1, 4, 9, 16, 25 ] <strong class='bbc'>assert</strong> type( l ) == types.ListType <strong class='bbc'>assert</strong> squareList1( l ) == squareList2( l ) <strong class='bbc'>assert</strong> squareList1( l ) == squareList3( l ) <strong class='bbc'>assert</strong> squareList2( l ) == squareList3( l ) List comprehension can have conditional clause, example: def conditionalComprehension() _linenums:0'><strong class='bbc'>def</strong> conditionalComprehension() : l = range( 5 ) <strong class='bbc'>assert</strong> l == [ 0, 1, 2, 3, 4 ] evens = [ el <strong class='bbc'>for</strong> el <strong class='bbc'>in</strong> l <strong class='bbc'>if</strong> el % 2 == 0 ] odds = [ el <strong class='bbc'>for</strong> el <strong class='bbc'>in</strong> l <strong class='bbc'>if</strong> el % 2 <> 0 ] <strong class='bbc'>assert</strong> evens == [ 0, 2, 4 ] <strong class='bbc'>assert</strong> odds == [ 1, 3 ] While list comprehension always produces result of type list it can process other iterable Python types ie. tuples and dictionaries (and types derived from them). Tuple is an immutable list and dictionary works as associative memory (map). Lets see how to process them using list comprehension: t = ( 1, 4, 9, 16, 25 ) assert squareList3( t ) == [1.0, 2.0, 3.0, 4.0, 5.0] d = { 1: 'one', 2: 'two', 3: 'three' } assert [ str( v ) + str( k ) for k, v in d.items() ] == [ 'one1', 'two2', 'three3' ] # 6 assert [ k for k in d ] == [ 1, 2, 3 ] # 7 assert [ k for k in d.keys() ] == [ 1, 2, 3 ] # 8 assert [ v for v in d.values() ] == [ 'one', 'two', 'three' ] # 9 Tuple (You initialize it like a list but using round parentheses) is processed exactly like a list (pay attention that it can be passed to a function that we wrote for a list). Things get more complicated when dictionary is involved. Using only dictionary reference (like #7) causes only keys of dictionary being process, #8 proves it. If You want to process also values use items() method. Notice that You get two variables for every key-value pair in dictionary. To process only values use values(). Multiple list comprehension: You can process multiple list in one expression, in this case You get to process all combinations. [ ( e1, e2 ) for e1 in lst1 for e2 in lst2 ]is equivalent for result = []for e1 in lst1 : for e2 in lst2 : result.append( (e1, e2) )return result Example: assert [ ( e1, e2 ) for e1 in l1 for e2 in l2 ] == [ (0, 2), (0, 3), (1, 2), (1, 3) ] _linenums:0'>l1 = [ 0, 1 ]l2 = [ 2, 3 ]<strong class='bbc'>assert</strong> [ ( e1, e2 ) <strong class='bbc'>for</strong> e1 <strong class='bbc'>in</strong> l1 <strong class='bbc'>for</strong> e2 <strong class='bbc'>in</strong> l2 ] == [ (0, 2), (0, 3), (1, 2), (1, 3) ] and another: def xor( b1 , b2, b3 ) _linenums:0'><strong class='bbc'>def</strong> xor( b1 , b2, b3 ) : """Exclusive 'or' True if and only if exactly one of arguments is true """ <strong class='bbc'>return</strong> ( b1 <strong class='bbc'>and</strong> <strong class='bbc'>not</strong> (b2 <strong class='bbc'>or</strong> b3) ) <strong class='bbc'>or</strong> \ ( b2 <strong class='bbc'>and</strong> <strong class='bbc'>not</strong> (b1 <strong class='bbc'>or</strong> b3) ) <strong class='bbc'>or</strong> \ ( b3 <strong class='bbc'>and</strong> <strong class='bbc'>not</strong> (b1 <strong class='bbc'>or</strong> b2) ) b = [ False, True ]<strong class='bbc'>assert</strong> [ ( b1, b2, b3 ) <strong class='bbc'>for</strong> b1 <strong class='bbc'>in</strong> b <strong class='bbc'>for</strong> b2 <strong class='bbc'>in</strong> b <strong class='bbc'>for</strong> b3 <strong class='bbc'>in</strong> b <strong class='bbc'>if</strong> xor( b1, b2, b3 ) ] == [ (False, False, True), (False, True, False), (True, False, False) ] List comprehension is a powerful technique, it belongs to set of functional programming concepts available in Python. Together with them it is one of reasons for Python's well-earned fame.-------------------------------- 1. Function type() gets type of object. Constants available in types module. 2. Function range() generates list with arithmetic progression, based on start (default=0), stop and step (default=1) arguments: assert range( 5 ) == [ 0, 1, 2, 3, 4 ]assert range( 5 , 10 ) == [ 5, 6, 7, 8, 9 ]assert range( 5 , 10 , 2 ) == [ 5, 7, 9 ]As You can see stop value is never included. Bye, see You around
  3. Hello Second part of tutorial presents while loop and conditional language constructs. Whole code: #! /usr/bin/env python# -*- coding: utf-8 -*-import mathimport sysimport cmath# -----------------------------------------------------------def factorial( i ) : assert i >= 0 if i == 0 : return 1 else : return i * factorial( i-1 )# -----------------------------------------------------------def estimate( number , precision = 0.01 ) : """Estimates square root of a number with given precision""" def avg( a , b ) : return ( a + b ) / 2.0 min , max = 0 , number while True : est = avg( max , min ) diff = ( est * est ) - number if math.fabs( diff ) <= precision : return est else : if diff > 0 : max = est else : min = est # -----------------------------------------------------------def sqrtList( lst , allowNegative = False , allowComplex = False ) : if allowComplex : allowNegative = True result = [] while not len( lst ) == 0 : number , lst = lst[ 0 ] , lst[ 1: ] root = None if number > 0 : root = math.sqrt( number ) else: if not allowNegative : break else : if allowComplex : root = cmath.sqrt( number) result.append( root ) else : return result# -----------------------------------------------------------def factorials( n ) : print '%s %10s' % ( 'i' , 'fac' ) print 12 * '-' for i in range( n ) : print '%s %10s' % ( i , factorial( i ) )# -----------------------------------------------------------def swap() : a = 2 b = 3 a , b = b , a assert a == 3 and b == 2# -----------------------------------------------------------def absList( lst ) : result = [] for el in lst: if el > 0 : abs = 1 elif el == 0 : abs = 0 else : abs = -1 result.append( abs ) return result# -----------------------------------------------------------def bigFactorial( n ) : print 'Recursion limit: %d, setting to %d' % ( sys.getrecursionlimit() , n+3 ) sys.setrecursionlimit( n + 3 ) f = factorial( n ) print 'Factorial of %d has %d digits:\n%d' % ( n , len( str( f ) ) , f )# -----------------------------------------------------------def conditionalExpression() : a = 2 b = 4 cond = True c = a if cond else b assert c == a cond = False c = a if cond else b assert c == b# -----------------------------------------------------------def slices() : a , b , c , d , e = 1 , 2 , 3 , 4 , 5 assert a == 1 and b == 2 and c == 3 and d == 4 and e == 5 # # indexes = 0 1 2 3 4 lst = [ a , b , c , d , e ] assert lst[0] == a and lst[4] == e assert lst[0:3] == [ a , b , c ] assert lst[1:3] == [ b , c ] assert lst[ :3] == [ a , b , c ] assert lst[2:4] == [ c , d ] assert lst[2:5] == [ c , d , e ] assert lst[2: ] == [ c , d , e ]if __name__ == '__main__' : factorials( 10 ) print number = 25 precision = 0.0001 print 'Estimated (prec. %f) square root of %d is %f' % ( precision , number , estimate( number , precision ) ) print swap() print bigFactorial( 1024 ) print lst = [ 1 , 4 , -9 , 16 , 25 ] print 'List is :' , lst print 'Square list is:' , sqrtList( lst ) print 'Square list is:' , sqrtList( lst , allowNegative = True ) print 'Square list is:' , sqrtList( lst , True ) print 'Square list is:' , sqrtList( lst , allowComplex = True ) print 'Square list is:' , sqrtList( lst , False , True ) print 'Square list is:' , sqrtList( lst , True , True ) assert sqrtList( lst , allowComplex = True ) == [1.0, 2.0, 3j, 4.0, 5.0] lst = [ 0 , 4 , -9 , 16 , 25 ] print 'List is :' , lst print 'Abs list is:' , absList( lst ) print conditionalExpression() slices()... and step by step: while loop Typical use of while loop: def estimate( number , precision = 0.01 ) _linenums:0'><strong class='bbc'>def</strong> estimate( number , precision = 0.01 ) : """Estimates square root of a number with given precision""" <strong class='bbc'>def</strong> avg( a , b ) : return ( a + b ) / 2.0 min , max = 0 , number # simultaneous assignment <strong class='bbc'>while</strong> True : est = avg( max , min ) diff = ( est * est ) - number <strong class='bbc'>if</strong> math.fabs( diff ) <= precision : <strong class='bbc'>return</strong> est <strong class='bbc'>else</strong> : <strong class='bbc'>if</strong> diff > 0 : max = est <strong class='bbc'>else</strong> : min = est... and use with else clause def sqrtList( lst , allowNegative = False , allowComplex = False ) _linenums:0'><strong class='bbc'>def</strong> sqrtList( lst , allowNegative = False , allowComplex = False ) : <strong class='bbc'>if</strong> allowComplex : allowNegative = True result = [] <strong class='bbc'>while</strong> <strong class='bbc'>not</strong> len( lst ) == 0 : number , lst = lst[0] , lst[1:] # simultaneous assignment and slice root = None <strong class='bbc'>if</strong> number > 0 : root = math.sqrt( number ) <strong class='bbc'>else</strong>: <strong class='bbc'>if</strong> <strong class='bbc'>not</strong> allowNegative : <strong class='bbc'>break</strong> <strong class='bbc'>else</strong> : <strong class='bbc'>if</strong> allowComplex : root = cmath.sqrt( number) result.append( root ) <strong class='bbc'>else</strong> : <strong class='bbc'>return</strong> result Semantics is similar to for loop. else clause (if present) is executed after condition is no longer satisfied with exception of break statement executed in this loop. continue is not an exception. Worth of mentioning: 1. Both functions use arguments with default values. There are multiple ways to execute functions like that: assert sqrtList( lst , allowComplex = True ) == [1.0, 2.0, 3j, 4.0, 5.0] _linenums:0'>lst = [ 1 , 4 , -9 , 16 , 25 ]sqrtList( lst ) sqrtList( lst , allowNegative = True )sqrtList( lst , True )sqrtList( lst , allowComplex = True )sqrtList( lst , False , True )sqrtList( lst , True , True )<strong class='bbc'>assert</strong> sqrtList( lst , allowComplex = True ) == [1.0, 2.0, 3j, 4.0, 5.0] Simple constraint is that You cannot declare non-default arguments after default argument. Last three lines of previous code snippet present the advantage of naming arguments. (Code is longer in this case but clarity is higher, and imagine ten switches like that).Argument passing and taking is quite complicated matter, more on this later. 2. You can declare functions INSIDE functions as seen in the first snippet. 3. You can make simultaneous assignments, works with any number of pairs: assert a == 1 and b == 2 and c == 3 and d == 4 and e == 5 _linenums:0'>a , b , c , d , e = 1 , 2 , 3 , 4 , 5<strong class='bbc'>assert</strong> a == 1 <strong class='bbc'>and</strong> b == 2 <strong class='bbc'>and</strong> c == 3 <strong class='bbc'>and</strong> d == 4 <strong class='bbc'>and</strong> e == 5 Assignments are really simultaneous: def swap() _linenums:0'><strong class='bbc'>def</strong> swap() : a = 2 b = 3 a , b = b , a <strong class='bbc'>assert</strong> a == 3 <strong class='bbc'>and</strong> b == 24. Slices:You can access sublists of a list with slice notation. Simplest form is: # # indexes = 0 1 2 3 4 lst = [ a , b , c , d , e ] assert lst[0] == a and lst[4] == e assert lst[0:3] == [ a , b , c ] assert lst[1:3] == [ b , c ] assert lst[ :3] == [ a , b , c ] assert lst[2:4] == [ c , d ] assert lst[2:5] == [ c , d , e ] assert lst[2: ] == [ c , d , e ]... more complicated form involves negative and "too big" indexes. We'll get there. 5. Complex numbers, You declare them as: c = 2 + 3j... and standard numeric functions are in cmath instead of math. Recursion Recursion in Python brings no surprises : def factorial( i ) _linenums:0'><strong class='bbc'>def</strong> factorial( i ) : <strong class='bbc'>if</strong> i == 0 : <strong class='bbc'>return</strong> 1 <strong class='bbc'>else</strong> : <strong class='bbc'>return</strong> i * factorial( i-1 ) Conditionals if statement in full form: def absList( lst ) _linenums:0'><strong class='bbc'>def</strong> absList( lst ) : result = [] <strong class='bbc'>for</strong> el <strong class='bbc'>in</strong> lst: <strong class='bbc'>if</strong> el > 0 : abs = 1 <strong class='bbc'>elif</strong> el == 0 : abs = 0 <strong class='bbc'>else</strong> : abs = -1 result.append( abs ) <strong class='bbc'>return</strong> resultMultiple elifs are possible.There is no case nor switch statements in Python. Conditions are evaluated from top to bottom, statements after the first true one are executed, there is no fall-through logic. Conditional expression a = cond ? b : c // That would be in Java a = b <strong class='bbc'>if</strong> cond <strong class='bbc'>else</strong> c # That's in Python ... looks somewhat strange but instead it has been chosen from among many after Serious Considerations That's all for now, bye Marek
  4. Hello I'm afraid that You misinterpreted my concerns. Let me explain. 1. What I believe or not is not important when we are talking about "proven maths and science". What I was asking is: is there a conclusive scientific proof that astrologic predictions of any kind are actually accurate. 2. Many conditions upon time of my birth (and ever since) influenced my life, that's clear. If You advocate that positions of objects, whose distances from me are measured in millions of kilometers, do it in significant way - You are the one to prove it. Not me if I say they don't. 3. Any maths can be involved in creating charts. In science question is: does experience support theory? In other way: were there any research on the subject. Is there any statistically significant correlation between birth date and (let's use the word) fate of the born? If not then You are the one that mixes believing with knowing. I have great respect for old wisdom even if what it says sounds bizarre at first. But that does not relieve me from criticism when I say about the proofs. And then You give me a walk through procedure which result is doubtful ... Don't get me wrong. I'm not fighting with Your conviction. I would really like to see evidence if it exists.
  5. HelloCould You please provide at least some of those "proven maths and science for Astrology" and "pure maths of astronomical science"?I read a lot of very unorthodox worldviews but as for astrology I didn't meet any convincing argument. Not to say about "maths and science". Some links would be enough.
  6. Python can produce *.pyc file for every *.py file. It is a bytecode so it's pretty unreadable althou it's done to load faster. There are also *.pyo files, but they can cause trouble.Other thing is to produce *.exe executable from *.py. It can be done for Windows but not for Linux AFAIK.Hope that helps
  7. Hello This is the first part of my Python tutorial. The code is pretty self-explanatory so few comments should be enough. If not - let me know. Tutorial assumes that You have already Python installed. Python 2.4 should be enough. Let's go, then. #! /usr/bin/env python# -*- coding: utf-8 -*-<strong class='bbc'>import</strong> math<strong class='bbc'>def</strong> squareRoot_1( lst ) : """Returns list of square roots. No negative number validation. Allows fractions in result. """ result = [] <strong class='bbc'>for</strong> el <strong class='bbc'>in</strong> lst : sqrtFloat = math.sqrt( el ) result.append( sqrtFloat ) <strong class='bbc'>return</strong> result <strong class='bbc'>def</strong> squareRoot_2( lst ) : '''Returns list of square roots.No negative number validation.Omits fractions in result. ''' result = [] <strong class='bbc'>for</strong> el <strong class='bbc'>in</strong> lst : sqrtFloat = math.sqrt( el ) <strong class='bbc'>if</strong> int( sqrtFloat ** 2 ) != el : <strong class='bbc'>continue</strong> result.append( sqrtFloat ) <strong class='bbc'>return</strong> result<strong class='bbc'>def</strong> squareRoot_3( lst ) : result = [] <strong class='bbc'>for</strong> el <strong class='bbc'>in</strong> lst : <strong class='bbc'>if</strong> el < 0 : <strong class='bbc'>break</strong> sqrtFloat = math.sqrt( el ) result.append( sqrtFloat ) <strong class='bbc'>return</strong> result<strong class='bbc'>def</strong> squareRoot_4( lst ) : result = [] <strong class='bbc'>for</strong> el <strong class='bbc'>in</strong> lst : sqrtFloat = math.sqrt( el ) result.append( sqrtFloat ) <strong class='bbc'>else</strong> : <strong class='bbc'>return</strong> result <strong class='bbc'>def</strong> squareRoot_5( lst ) : result = [] <strong class='bbc'>for</strong> el <strong class='bbc'>in</strong> lst : sqrtFloat = math.sqrt( el ) <strong class='bbc'>if</strong> int( sqrtFloat ** 2 ) != el : <strong class='bbc'>continue</strong> result.append( sqrtFloat ) <strong class='bbc'>else</strong> : <strong class='bbc'>return</strong> result<strong class='bbc'>def</strong> squareRoot_6( lst ) : result = [] <strong class='bbc'>for</strong> el <strong class='bbc'>in</strong> lst : <strong class='bbc'>if</strong> el < 0 : <strong class='bbc'>break</strong> sqrtFloat = math.sqrt( el ) result.append( sqrtFloat ) <strong class='bbc'>else</strong> : <strong class='bbc'>return</strong> result<strong class='bbc'>def</strong> testForLoop() : numbers = [ 1.0 , 2.0 , 3.0 , 4.0 , 5.0 ] squares = [ 1 , 4 , 9 , 16 , 25 ] <strong class='bbc'>assert</strong> squareRoot_1( squares ) == numbers <strong class='bbc'>assert</strong> squareRoot_1( [ 1 , 6.25 , 9 , 16 , 25 ] ) == [ 1.0 , 2.5 , 3.0 , 4.0 , 5.0 ] <strong class='bbc'>try</strong> : squareRoot_1( [ 1 , 4 , -9 , 16 , 25 ] ) # error at -9 <strong class='bbc'>assert</strong> False, "Processing cannot get here" <strong class='bbc'>except</strong> ValueError, e : <strong class='bbc'>pass</strong> <strong class='bbc'>assert</strong> squareRoot_2( squares ) == numbers <strong class='bbc'>assert</strong> squareRoot_2( [ 1 , 6.25 , 9 , 16 , 25 ] ) == [ 1.0 , 3.0 , 4.0 , 5.0 ] <strong class='bbc'>try</strong> : squareRoot_2( [ 1 , 4 , -9 , 16 , 25 ] ) # error at -9 <strong class='bbc'>assert</strong> False, 'Processing cannot get here' <strong class='bbc'>except</strong> ValueError, e : <strong class='bbc'>pass</strong> <strong class='bbc'>assert</strong> squareRoot_3( squares ) == numbers <strong class='bbc'>assert</strong> squareRoot_3( [ 1 , 4 , -9 , 16 , 25 ] ) == [ 1.0 , 2.0 ] <strong class='bbc'>assert</strong> squareRoot_3( [ 1 , 6.25 , 9 , 16 , 25 ] ) == [ 1.0 , 2.5 , 3.0 , 4.0 , 5.0 ] <strong class='bbc'>assert</strong> squareRoot_4( squares ) == numbers <strong class='bbc'>assert</strong> squareRoot_4( [ 1 , 6.25 , 9 , 16 , 25 ] ) == [ 1.0 , 2.5 , 3.0 , 4.0 , 5.0 ] <strong class='bbc'>try</strong> : squareRoot_4( [ 1 , 4 , -9 , 16 , 25 ] ) # error at -9 <strong class='bbc'>assert</strong> False <strong class='bbc'>except</strong> ValueError, e : <strong class='bbc'>pass</strong> <strong class='bbc'>assert</strong> squareRoot_5( squares ) == numbers <strong class='bbc'>assert</strong> squareRoot_5( [ 1 , 4.01 , 9 , 16 , 25 ] ) == [ 1.0 , 3.0 , 4.0 , 5.0 ] <strong class='bbc'>try</strong> : squareRoot_5( [ 1 , 4 , -9 , 16 , 25 ] ) # error at -9 <strong class='bbc'>assert</strong> False <strong class='bbc'>except</strong> ValueError, e : <strong class='bbc'>pass</strong> <strong class='bbc'>assert</strong> squareRoot_6( squares ) == numbers <strong class='bbc'>assert</strong> squareRoot_6( [ 1 , 4 , -9 , 16 , 25 ] ) == None <strong class='bbc'>assert</strong> squareRoot_6( [ 1 , 6.25 , 9 , 16 , 25 ] ) == [ 1.0 , 2.5 , 3.0 , 4.0 , 5.0 ]<strong class='bbc'>if</strong> __name__ == '__main__' : testForLoop() This code creates six different functions for doing basically the same (ie. calculating square root for list of numbers) and then tests differences between them. It presents different forms of for loop construct. General form of for loop is : for element in list_expression _linenums:0'><strong class='bbc'>for</strong> element <strong class='bbc'>in</strong> list_expression : commands1[<strong class='bbc'>else</strong> : commands2]Semantics is as follows: 1. For every element in list being result of list_expression perform commands1. 2. If no element is on the list or after the list has been processed perform commands2 3. break statement in commands1 exits the loop without entering else clause. 4. continue statement in commands1 skips rest of commands and gets to the next element (if exists) or to else clause Code in function testForLoop() should explain all possible cases. When commands1 actually modify list_expression (case when list_expression is simply l-value) by adding or removing elements, due to internal counter some elements in the list may be omitted from processing or processed more than once. Better clone the list in case like it. else clause is optional and rarely used in practise. Other things in code: 1. Header #! /usr/bin/env python# -*- coding: utf-8 -*-is UNIX specific, it informs the shell how to interpret script. It is not needed in Windows.Second line shows how to declare text encoding in Python. 2. Keywords def - declares function return - returns value, if not present (or not performed) it works as return None assert - checks if expression (the first one) is True if not throws AssertionError and prints second expression break & continue - similar to other languages pass - empty instruction, does nothing, contrary to what one may think - used very frequently try & except (& finally) - exception handling, we will get there sometime import - loads module, also in form 3. Code if __name__ == '__main__' _linenums:0'><strong class='bbc'>if</strong> __[i]name[/i]__ == '__main__' : [i]testForLoop[/i]() Explanation: If this script is being performed as main program then __name__ variable is going to be equal '__main__' (ie. test passes and function performs ), if it is being imported as module then __name__ is NOT equal '__main__' (and test fails, skipping function). It is very convenient way to distinguish between these two cases, it simplifies development and tests of complex applications. 4. Strings As You can see there are two ways to quote strings: with apostrophe and with quote. It works both for 'ordinary' strings (like '__main__' == "__main__") and for documentation strings ( """Some help""" == '''Some help'''). It is easier to quote the quote character itself, like this: 'She said "Hello" to him' or "She said 'Hello' to him" (watch out, this strings are not equal, contrary to two previous examples). 5. ** ... stands for 'power', ie: 2**3 == 8 6. Documentation strings You can access them in run-time with : print squareRoot_1.__doc__ print squareRoot_2.__doc__ Observe difference in formatting. 7. Special constants True is boolean true False is boolean false None is sth like null Remember: first letter is capitalised PS. I tried to upload the source code but all I got was "Upload failed. You are not permitted to upload this type of file". ??
  8. Hello I'm quite fluent in Python. If You ever need some advice be my guest. I'm also thinking of developing some tutorial here at Xisto. Bye
×
×
  • Create New...

Important Information

Terms of Use | Privacy Policy | Guidelines | We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.