Python Programming Fundamentals for Class 11 and 12 – Simple and Compound Statements

A statement is a unit of code that the Python interpreter can execute. A script usually contains a sequence of statements.

Namespace is a logical grouping of the objects used within a program. Most namespaces are currently implemented as Python dictionaries. Examples of namespaces are the set of built-in names (containing functions such as abs (), and built-in exception names), the global names in a module, and the local names in a function definition. The important thing to know about namespace is that there is absolutely no relation between names in different namespaces. For instance, the functions
_builtin_. open () and os . open () are distinguished by their namespaces. The following is an example of local namespace.

>>> def example(arg):
 ... x=4
 ... print locals()
 ...
 >>> example(10)
 {'x': 4, 'arg': 10}
 >>> example('hello')
 {'x': 4, 'arg': 'hello'}

The function example () has two variables in its local namespace: arg, whose value is passed in to the function, and x, which is defined within the function. The locals () built-in function return a dictionary of name-value pairs; the keys of this dictionary are the names of local variables as strings; the values of the dictionary are the actual values of the variables.

Simple statement

Simple statement is comprised within a single logical line. Several simple statements may occur on a single physical line separated by semicolons. The extended BNF notation describing syntax for simple statement is:

simple_stmt ::= expression_stmt
 | assert_stmt
 | assignment_stmt
 | augmented_assignment_stmt
 | pass_stmt
 | del_stmt
 | print_stmt
 | return_stmt
 | yield_stmt
 | raise_stmt
 | break_stmt
 | continue_stmt
 | import_stmt
 | global_stmt
 | exec_stmt

This book will discuss some of the simple statements.

Expression statement

An expression in a programming language is a combination of values, constants, variables, operators, functions etc. that are interpreted according to the particular rules of precedence for a particular programming language, which computes and then return another value. This process is called evaluation. An expression statement evaluates the expression list (which may be a single expression).

expression_stmt ::= expression_list

The following are examples of expression statement and its evaluation.

>>> 4 4
 >>> 4==4
 True
 >>> 2+6
 8
 >>> ' Hi ' *3
 'HiHiHi'

Assignment statement

Assignment statements are used to (re)bind names to values and to modify attributes or items of mutable objects. The following example shows binding value 4 to object (or name) a.

>>> a=4

Pass statement

The pass statement is a null operation, nothing happens when it is executed. It is useful as a placeholder when a statement is required syntactically, but no code needs to be executed.

pass_stmt ::= "pass"

The following example defines a function f and does nothing.

>>> def f(arg):
 ...pass
 ...

Del statement

This statement deletes each target in target_list from left to right.

del_stmt ::= "del" target__list

Deletion of a name removes the binding of that name from the local or global namespace, depending on whether the name occurs in a global statement in the same code block. If the name is unbound, a NameError exception will be raised.

>>> a = [-1, 1, 66.25, 333, 333, 1234.5]
 >>> del a[0]
 >>> a
 [1, 66.25, 333, 333, 1234.5]
 >>> del a [2:4]
 >>> a
 [1, 66.25, 1234.5]
 >>> del a[:]
 >>> a
 []
 >>> a = [-1, 1,66.25, 333, 333, 1234.5]
 >>> del a
 >>> a
 Traceback (most recent call last):
 File "<pyshell#24>", line 1, in a
 NameError: name 'a' is not defined

Print statement

The print statement evaluates each expression and then writes the resulting object to standard output (computer screen). If an object is not a string, it is first converted to a string using the rules for string conversion, the resulting or original string is then written. A space is written before each object is (converted and) written, unless the output system believes it is positioned at the beginning of a line. A ‘ \n’ character is written at the end, unless the print statement ends with a comma. If only print keyword is there in print statement, then only ‘\n’ character is written. Following is a script “print_example.py”, having the following code:

a=20
 print 'hi', 5, a
 print 'bye', 10, a
 print
 print 'hi', 5, a,
 print 'bye', 10, a,

Output after running the script is:

>>> runfile('C:/Temp/print_example.py', wdir=r'C:/Temp')
 hi 5 20
 bye 10 20
 hi 5 20 bye 10 20

Return statement

The return statement leaves the current function call with the expression_list (or None) as return value.

return_stmt "return" [expression_list]

The following script “addition_example.py” demonstrate the use of return statement.

def summation(arg1,arg2):
 return arg1+arg2
 print 'Sum is: summation(1,2)
 def summation(argl,arg2): # The function return None
 print 'Sum is: ',arg1+arg2
 summation(3,4)
 print summation(3,4)
 def summation(arg1,arg2): # The function return None
 print ,'Sum is: ',arg1 + arg2
 return
 summation(5,6)
 print summation(5,6)
 def summation(argl,arg2): # The function return None
 print 'Sum is: ',arg1+arg2
 return None
 summation(7,8)
 print summation(7,8)
 def summation(arg1,arg2):
 def add(argl,arg2):
 return arg1+arg2
 return add(argl,arg2)
 print 'Sum is: ',summation(9,10)

The output after running the script is:

>>> runfile('C:/Temp/addition_example.py', wdir=r'C:/Temp')
 Sum is: 3
 Sum is: 7
 Sum is: 7
 None
 Sum is: 11
 Sum is: 11
 None
 Sum is: 15
 Sum is: 15
 None
 Sum is: 19

Break statement

The break statement terminate the nearest enclosing loop, skipping the optional else clause if the loop has one.

break_stmt ::= "break"

If a for loop is terminated by break, the loop control target keeps its current value. The following script “break_example.py” demonstrates the use of break statement.

a=5
 for i in range(10):
 if i==a:
 break
 else :
 print i
 print i

The output after running the script is:

>>> runfile('C:/Temp/addition_example.py', wdir=r'C:/Temp')
 0
 1
 2
 3
 4
 5

Continue statement

The continue statement makes the current nearest enclosing loop to skip one iteration and executes the remaining ones.

continue_stmt ::= "continue"

The following script “continue_example.py” demonstrate the use of continue statement.

for i in range(10):
 if i>4 and i<8: continue else: print i The output after running the script is: >>> runfile('C:/Temp/continue_example.py', wdir=r'C:/Temp')
 0
 1
 2
 3
 4
 8
 9

Import statement

Definitions (variables, function definitions etc.) from one module can be imported into other module using import statement. For more information, please refer chapter 5.

Global statement

The global statement is a declaration which makes listed identifiers to be interpreted as global. This will become clearer by referring section 3.2.5.

global_stmt ::= "global" identifier ("," identifier)*

Compound statement

Compound statements contain groups of other statements, they affect or control the execution of those other statements in some way. In general, compound statements span multiple lines, although a whole compound statement can be contained in one line.
The if, while and for statements are the traditional control flow compound statements, try specifies exception handlers and/or cleanup code for a group of statements. Function and class definitions are also syntactically compound statements.
Compound statements consist of one or more clauses. A clause consists of a header and a suite. The clause headers of a particular compound statement are all at the same indentation level. Each clause header begin with a uniquely identifying keyword and ends with a colon. A suite is a group of statements controlled by a clause. A suite can be one or more semicolon-separated simple statements on the same line as the header, following the header’s colon, or it can be one or more indented statements on subsequent lines. Only the latter form of suite can contain nested compound statements.

The colon is required primarily to enhance readability.

if a == b
 print aversus
 if a == b:
 print a

Notice how the second one is slightly easier to read. Another minor reason is that the colon makes it easier for editors with syntax highlighting; they can look for colons to decide when indentation needs to be increased.
A code block (or simply “block”) is a piece of Python program text that is executed as a unit. Few examples of block are: a module, a function body, a class definition etc. Each command typed interactively is a block.

If statement

The if statement is used for conditional execution:

if_stmt ::= "if" expression":"suite
 ( "elif" expression":"suite )*
 ["else" ":" suite]

It selects exactly one of the suites by evaluating the expressions one by one until one is found to be true, then that suite is executed (and no other part of the if statement is executed or evaluated). If all expressions are false, the suite of the else clause (if present) is executed.

>>> var=100
 >>> if var==100:
 ...print 'var has value 100
 ...
 var has value 100
 >>>
 >>> var=100
 >>> if var<>100:
 ...print 'var does not have value 100'
 ... else:
 ... print 'var has value 100'
 ...
 var has value 100
 >>>
 >>> var=100
 >>> if var<100: ... print 'varhas value less than 100' ... elif var>100:
 ... print 'var has value greater than 100'
 ... else:
 ... print 'var has value 100'
 ...
 var has value 100

The following example shows that if the evaluation of expression gives result either None, empty string (‘ ‘), zero (0) or Boolean False, then the condition is considered as false.

>>> if None or '' or 0 or False:
 ... print 'Atleast one condition is true'
 ... else:
 ... print 'None of the condition is true'
 ...
 None of the condition is true

There may be a situation when there is a need to check for another condition after a condition resolves to true. In such a situation, the nested if statement can be used.

>>> var=100
 >>> if isinstance(var,str):
 ... print 'var is a string'
 ... elif (type(var) is int):
 ... if var<>100 :
 ... print 'var does not have value 100'
 ... else:
 ... print 'var has value 100'
 var has value 100

While statement

The while statement is used for repeated execution of group of statements as long as an expression is true:

while_stmt ::= "while" expression":"suite
 ["else" ":" suite]

This compound statement repeatedly tests the expression, and if it is true, it executes the first suite; if the expression is false (which may be the first time it is tested) the suite of the else clause (if present) is executed and the loop terminates.

var=1
 >>> while var<=5: 
... print 'Count ' , 
var ... var=var+1 
Count 1 
Count 2 
Count 3 
Count 4 
Count 5 
>>> print 'The loop ends'
 The loop ends

The above code can also be witten as follows:

var=1
 >>> while var<=5: 
... print 'Count ',var ... var=var+1 
... else: 
... print 'The loop ends' 
Count 1 
Count 2 
Count 3 
Count 4 
Count 5

The loop ends A break statement executed in the first suite terminates the loop without executing the else clause’s suite.

>> var=1
 >>> while var<=5: 
... print 'Count ',var 
... var=var+1 
... if var==4: 
... break .
.. else: 
... print 'The loop ends' 
... Count 1 
Count 2 
Count 3
A continue statement executed in the first suite skips the rest of the suite and goes back to testing the expression. 

>>> var=0
 >>> while var<=5: 
... var=var+1 
... if var>=3 and var<=4: 
. . . continue 
... print 'Count ',var 
... Count 1
 Count 2 
Count 5 
Count 6

Consider a scenario where the condition never becomes false. This results in a loop that never ends; such loop is called an infinite loop. One needs to use keyboard Ctrl+C to come out of the program.

For statement

The for statement is used to iterate over the elements of a sequence (such as a string, tuple or list) or other
iterable object:

for_stmt ::= "for" target_list "in" expression_list suite [ "else" ":" suite]

The expression list expression_list is evaluated once; it should yield an iterable object. An iterator is created for the result of the expression_list. The suite is then executed once for each item provided by the iterator, in the order of ascending indices. Each item in turn is assigned to the target list target_list using the standard rules for assignments, and then the suite is executed. When the items are exhausted (which is immediately when the sequence is empty), the suite in the else clause (if present) is executed, and the loop terminates.

>>> for i in [1,2,3,4,5]:
 ... print 'Count ',i
 ...
 Count 1
 Count 2
 Count 3
 Count 4
 Count 5
 >>> print 'The loop ends'
 The loop ends

The above code can also be witten as follows:

>>> for i in range(1,6):
 ... print 'Count ',i
 ... else:
 ... print 'The loop ends'
 ...
 Count 1
 Count 2
 Count 3
 Count 4
 Count 5
 The loop ends

A break statement executed in the first suite terminates the loop without executing the else clause’s suite.

>>> for i in [1,2,3,4,5]:
 ... if i==4:
 . . . break
 ... print 'Count ',i
 ... else:
 ... print 'The loop ends'
 ...
 Count 1
 Count 2
 Count 3

A continue statement executed in the first suite skips the rest of the suite and continues with the next item, or with the else clause if there was no next item.

>>> for i in [1,2,3,4,5]:
 ... if i==4:
 ... continue
 ... print 'Count ',i
 ... else:
 ... print 'The loop ends'
 ...
 Count 1
 Count 2
 Count 3
Count 4
 Count 5
 The loop ends

There might be scenario where one needs to print the item along with its index. The following example demonstrate this scenario using enumerate () built-in function (discussed later in this chapter).

>>> shuttles=['Columbia','endeavour','challenger']
 >>> for index,value in enumerate(shuttles):
 ... print index, value
 ...
 0 Columbia
 1 endeavour
 2 challenger
 >>>
 >>> value
 'challenger'
 >>> index
 2

It can also be observed that the target list is not deleted when the loop is finished.

Functions

Function is a compound statement which returns some value to the caller. The keyword def introduces a function definition. It must be followed by the function name and the parenthesized list of formal parameters. The statements that form the body of the function start at the next line, and must be indented. The first statement of the function body can optionally be a string literal; this string literal is the function’s documentation string, or “docstring”. Docstring is a string literal which appears as the first expression in a class, function or module. While ignored when the suite is executed, it is recognized by the compiler and put into the doc attribute of the enclosing class, function or
module.

>>> def summation(a,b):
 ... """ Gives sum of two numbers"""
 ... sum=a+b
 . . . return sum
 >>> summation(5,10)
 15
 >>> summation._doc_
 ' Gives sum of\n two numbers'

Argument
Argument is the value passed to a function (or method) while calling the function. There are two types of arguments:

Keyword argument
Keyword argument is an argument preceded by an identifier (e.g. name=) in a function call or passed as a value in a dictionary preceded by **. For example, 10, 20, 30 and 40 are keyword arguments in the following calls to summation () function:

>>> def summation(aa,bb,cc,dd):
 ... print 'aa:',aa
 . . . print 'bb: ',bb
 ... print 'cc:',cc
 ... print 'dd:',dd
 ... total=aa+bb+cc+dd
 . . . return total
 ...
 >>> sumup1=summation(bb=20,dd=40,aa=10, cc=30)
 aa: 10
 bb: 20
 cc: 30
 dd: 40
 >>> print 'Sum is:',sumup1
 Sum is: 100
 >>> sumup2=summation(**{'bb':20,'dd':40,'aa':10,'cc':30})
 aa: 10
 bb: 20
 cc: 30
 dd: 40
 >>> print 'Sum is:',sumup2
 Sum is: 100

Positional argument
Positional argument is an argument that is not a keyword argument. Positional arguments can appear at the beginning of an argument list and can also be passed as elements of an iterable preceded by *. For example, 10, 20, 30 and 40 are positional arguments in the following calls to summation () function:

>>> def summation(aa,bb,cc,dd):
 ... print 'aa:' , aa
 . .. print 'bb:',bb
 ... print ' cc : ' , cc
 ... print 'dd:',dd
 ... total=aa+bb+cc+dd
 ... return total
 ...
 >>> sumup3=summation(10,20,30,40)
 aa:10
 bb:20
 cc:30
 dd:40
 >>> print 'Sum is:, sumup3
 Sum is: 100
 >>> sumup4=summation(*(10,20,30,40))
 aa:10
 bb:20
 cc:30
 dd:40
 >>> print 'Sum is: ,sumup4
 Sum is: 100

Parameter
Parameter is a named entity in a function (or method) definition that specifies the argument (or in some cases, arguments), that the function can accept. Parameters are defined by the names that appear in a function definition, whereas arguments are the values actually passed to a function when calling it. For example, given the function definition:

def func(foo,bar=None,**kwargs): pass

foo, bar and kwargs are parameters of func. However, when calling func, for example:

func(42,bar=314,extra=somevar)

the values 42, 314, and somevar are arguments.
The actual parameters (arguments) to a function call are introduced in the local symbol table of the called function when it is called; thus, arguments are passed using call by value (where the value is always an object reference, not the value of the object). Actually, call by object reference would be a better description, since if a mutable object is passed, the caller will see any changes the callee makes to it (items inserted into a list).

>>> def changeme(mylist):
 ... mylist.append([1,2,3,4])
 ... print "Values inside the function: ",mylist
 ... return
 >>> mylist=[10,20,30]
 >>> changeme(mylist)
 Values inside the function: [10, 20, 30, [1, 2, 3, 4]]
 >>> print "Values outside the function: ",mylist
 Values outside the function: [10, 20, 30, [1, 2, 3, 4]]

In the above example, the append operation maintains the passed object reference. In the following example the object reference is overwritten inside the function.

>>> def changeme(mylist):
 ... mylist=[1,2,3,4]
 ... print "Values inside the function: ",mylist
 . . . return
 ...
 >>> mylist=[10,20,30]
 >>> changeme(mylist)
 Values inside the function: [1, 2, 3, 4]
 >>> print "Values outside the function: ",mylist
 Values outside the function: [10, 20, 30]

There are four types of parameters:

  • Positional or keyword parameter
    It specifies that an argument can be passed either positionally or as a keyword argument. Note that, only those parameters which are at the end of the parameter list can be given default argument values i.e. the function cannot have a parameter with a default argument value preceding a parameter without a default argument value in the function’s parameter list. This is because the values are assigned to the parameters by position. For example, def func(a,b=5) is valid, but def func(a=5,b) is not valid.
  • Only positional parameter
    It specifies that an argument that can be supplied only by position.
  • Var-positional parameter
    It specifies that an arbitrary sequence of positional arguments can be provided (in addition to any positional arguments already accepted by other parameters). Such a parameter can be defined by prepending the parameter name with *.
  • Var-keyword parameter
    It specifies that arbitrarily many keyword arguments can be provided (in addition to any keyword arguments already accepted by other parameters). Such a parameter can be defined by prefixing the parameter name with **.

Following are few examples of functions. .

>>> def person_info(fn,In,ag,tel=5128975,nat='American'):
 ... print 'First name:',fn
 ... print 'Last name:',In
 ... print 'Age:',ag
 ... print 'Telephone number:',tel
 ... print 'Nationality:',nat
 >>> person_info('Sachin','Tendulkar',40,17896823,'Indian')
 First name: Sachin
 Last name: Tendulkar
 Age: 40 .
 Telephone number: 17896823
 Nationality: Indian
 >>> person_info('Mike','Johnson',20)
 First name: Mike
 Last name: Johnson
 Age: 20
 Telephone number: 5128975
 Nationality: American
 >>> person_info('Nadeem','Khan',54,nat='Pakistani')
 First name: Nadeem
 Last name: Khan
 Age: 54
 Telephone number: 5128975
 Nationality: Pakistani
 >>> person_info('Chin','Chan',15,nat='Chinese',tel=1894313654)
 First name: Chin
 Last name: Chan
 Age: 15
 Telephone number: 1894313654
 Nationality: Chinese
 >>>
 >>> def person_info(fn,In,ag,tel,nat):
 ... print 'First name:',fn
 ... print 'Last name:',In
 ... print 'Age:',ag
 ... print 'Telephone number:',tel
 ... print ' Nationality:', nat
 ...
 >>> person_info('Sachin','Tendulkar',40,17896823,'Indian')
 First name: Sachin
 Last name: Tendulkar
 Age: 40
 Telephone number: 17896823
 Nationality: Indian
 >>> person_info('Chin','Chan',15,1894313654,'Chinese')
 First name: Chin
 Last name: Chan
 Age: 15
 Telephone number: 1894313654
 Nationality: Chinese
 >>>
 >>> def total(a,b,*numbers):
 ... tot=a+b
 ... for num in numbers:
 . . . tot=tot+num
 . . . return tot
 >>> print 'Total:',total(1,2,3,4,5)
 Total: 15
 >>> print 'Totaltotal(1,2,3,4,5,6,7,8,9,10)
 Total: 55
 >>>
 >>> def person_info(fn='Chinln='Chan**more_info):
 ... print 'First name:',fn
 ... print 'Last name:',In
 ... if more_info.has_key('ag'):
 ... print 'Age:',more_info['ag']
 ... if more_info.has_key('tel'):
 ... print 'Telephone number:',more_info['tel']
 ... if more_info.has_key('nat'):
 ... print 'Nationality:',more_info['nat']
 >>> person_info()
 First name: Chin
 Last names Chan
 >>> person_info(ag=40,tel=1789,ln='Tendulkar',nat='Indian',fn='Sachin' )
 First name: Sachin
 Last name: Tendulkar
 Age: 40
 Telephone number: 1789
 Nationality: Indian
 >>> person_info(ag=15,nat='Chinese',tel=1894313654)
 First name: Chin
 Last name: Chan
 Age: 15
 Telephone number: 1894313654
 Nationality: Chinese
 >>>
 >>> def total(a,b,*numbers,**kwag):
 . .. tot=a+b
 ... for num in numbers:
 . . . tot=tot+num
 . . . for key in kwag:
 ... tot=tot+kwag[key]
 . . . return tot
 >>> print 'Total:',total(5,7,10,2,14,c=100,d=106,e=211)
 Total: 455

Built-in functions
Till now, the discussed functions need to be defined before using it in program; such functions are called user-defined functions. Python has a number of functions that are always available. These are called built-in functions. They are listed here in alphabetical order.

abs () all() any ( )
 basestring () bin () bool()
 bytearray() callable() chr ()
 classmethod() cmp () compile()
 complex() delattr() diet ()
 dir () divmod() enumerate()
 eval() execfile() file()
 filter () float() format()
 frozenset () getattr() globals()
 hasattr() hash() help()
 hex () id () input()
 int () isinstance() issubclass(
 iter () len () list ()
 locals () long() map ()
 max () memoryview() min ()
 next() object() oct ()
 open() ord () pow ()
 print () property() range()
 raw_input() reduce() reload()
 repr() reversed() round()
 set () setattr() slice()
 sorted() staticmethod() str ()
 sum () super() tuple()
 type() unichr() Unicode()
 vars() xrange() zip ()
 import () apply() buffer()
 coerce() intern()

Some of the above built-in functions are discussed below:
abs(x)
Return the absolute value of a number. The argument may be a plain or long integer or a floating point number. If the argument is a complex number, its magnitude is returned.

>>> abs (-34)
 34
 >>> abs(34.5)
 34.5
 >>> abs(-3-4j) •
 5.0

all(iterable)
Return True, if all elements of the iterable are true (or if the iterable is empty).

>>> all ( [True, 10] )
 True
 >>> all([True,10,0])
 False
 >>> all ( () )
 True

any(iterable)
Return True, if any element of the iterable is true. If the iterable is empty, return False.

>>> any([0,5,-3])
 True
 >>> any([0,False,-3])
 True
 >>> any(())
 False

bin(x)
Convert an integer number to a binary string.

>>> bin(8)
 '0b1000'
 >>> bin(27)
 '0b11011'
 >>> (27).bit_length()
 5
 >>> bin(-1327)
 '-0b10100101111'
 >>> (-1327) .bit__length ()
 11

bool([x])
Convert a value to a boolean. If x is false or omitted, this returns False; otherwise it returns True. If no argument is given, this function returns False.

>>> bool(5)
 True
 >>> bool(-5)
 True
 >>> bool(0)
 False
 >>> bool('hi')
 True
 >>> bool()
 False
 >>> bool('')
 False
 >>> bool(None)
 False
 >>> bool('\n')
 True
 >>> bool([0])
 True
 >>> bool((None,))
 True

chr (i)
Return a string of one character whose ASCII-8 code is the integer i. This is the inverse of ord (). The argument must be in the range [0,255]; ValueError will be raised, if i is outside that range.

>>> for i in range(33,95): print i,'=',chr(i)
 33 = !
 34 = "
 35 = #
 36 = $
 37 = %
 38 = &
 39 = '
 40 = (
 41 = )
 42 = *
 43 = +
 44 = ,
 45 = -
 46 = .
 47 = /
 48 = 0
 49 = 1
 50 = 2
 51 = 3
 52 = 4
 53 = 5
 54 = 6
 55 = 7
 56 = 8
 57 = 9
 58 = :
 59 = ;
 60 = <
 61 = =
 62 = >
 63 = ?
 64 = @
 65 = A
 66 = B
 67 = C
 68 = D
 69 = E
 70 = F
 71 = G
 72 = H
 73 = I
 74 = J
 75 = K
 76 = L
 77 = M
 78 = N
 79= 0
 80 = P
 81 = Q
 82 = R
 83 = S
 84 = T
 85 = U
 86 = V
 87 = W
 88 = X
 89 = Y
 90 = Z
 91 = [
 92 = \
 93 = ]
 94 = ^

cmp (x, y)
Compare the two objects x and y, and return an integer according to the outcome. The returned value is negative, if x<y, zero, if x==y, and strictly positive, if x>y.

>>> cmp(2.5,5.2)
 -1
 >>> cmp (5.2,5.2 )
 0
 >>> cmp(5.2,2.5)
 1
 >>> cmp('hi','hello')
 1
 >>> cmp('hellohi')
 -1

complex([real[,imag]])
Create a complex number with the value real+imag* j, or convert a string or number to a complex number. If the first parameter is a string, it will be interpreted as a complex number and the function must be called without a second parameter. The second parameter can never be a string. Each argument may be any numeric type (including complex). If imag is omitted, it defaults to zero. If both arguments are omitted, the function returns 0 j. When converting from a string, the string must not contain whitespace around the central + or – operator. For example, complex ( ‘ 1 + 2 j ‘ ) is fine, but
complex (‘1 + 2 j ‘ ) raises ValueError.

>>> complex()
 0 j
 >>> complex(2.51)
 (2.51+0j)
 >>> complex(2.51,4.79)
 (2.51+4.79j)
 >>> cl=4+5j
 >>> c2=6+7j
 >>> complex(c1,c2) # Equals (4+5j)+(6+7j)j = 4+5j+6j-7 (-3+11j)
 >>> c= ' 7 '
 >>> complex(c)
 (7+0j)
 >>> c='7+4j'
 >>> complex(c)
 (7+4j)
 >>> x=2+3j
 >>> x.real
 2.0
 >>> x.imag
 3.0

delattr(object,name)
This is a relative of setattr (). The arguments are an object and a string. The string must be the name of one of the object’s attributes. The function deletes the named attribute, provided the object allows it.

>>> class new_cls:
 ... def _init_(self,x):
 ... self.x=x
 >>> tt=new_cls (10 )
 >>> tt.x
 10
 >>> setattr(tt,'x', 20)
 >>> tt.x
 20
 >>> setattr (tt, 'y', 'hello')
 >>> tt.y
 'hello'
 >>> delattr(tt,'x')
 >>> tt.x
 Traceback (most recent call last):
 File "", line 1, in
 AttributeError: new_cls instance has no attribute 'x'

divmod(a, b)
Take two (non-complex) numbers as arguments and return a pair of numbers consisting of their quotient and remainder.

>>> divmod(13.5,3)
 (4.0, 1.5)
 >>> divmod(13,3)
 (4, 1)

enumerate(sequence,start=0)
Return an enumerate object. The sequence argument must be a sequence, an iterator, or some other object which supports iteration, while start is a count (default argument as 0).

>>> seasons=['Spring','Summer','Fall','Winter']
 >>> list(enumerate(seasons))
 [(0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'Winter')]
 >>> list(enumerate(seasons,start=2))
 [(2, 'Spring'), (3, 'Summer'), (4, 'Fall'), (5, 'Winter')]
 >>> for num,seasn in • enumerate(seasons,start=1) :
 ... print "[{0}] {1}".format(num,seasn)
 ...
 [1] Spring
 [2] Summer
 [3] Fall
 [4] Winter

filter(function,iterable)
Create a list from those elements of iterable for which function returns True. The iterable may be either a sequence, a container which supports iteration, or an iterator. If iterable is a string or a tuple, the result also has that type, otherwise it will be a list. If function is None, the identity function is assumed, that is, all elements of iterable that are False are removed.

>>> def isOdd(x) :
 ... if(x%2)==l: return True
 ... else: return False
 ...
 >>> filter(isOdd,[88,43,65,-11,202])
 [43, 65, -11]
 >>>
 >>> def isLetter(c): return c.isalpha()
 ...
 >>> filter(isLetter,"01234abcdeFGHIJ*(&!^")
 'abcdeFGHIJ'
 >>> list=[0, 1, () , (2, ) , 0.0, 0.25]
 >>> filter(None,list)
 [1, (2,), 0.25]
 >>> filter(bool, list)
 [1, (2,), 0.25]

getattr(object,name[,default])
Return the value of the named attribute of object; name must be a string. If the string is the name of one of the object’s attributes, the result is the value of that attribute. If the named attribute does not exist, default is returned if provided, otherwise AttributeError is raised. For example, a complex number object has real and imag attributes.

>>> a=3.5+4.9J
 >>> type(a)
>>> getattr(a, ’real’)
 3.5
 >>> getattr(a,’imag1)
 4.9
 >>> getattr(a,’imagine2.2)
 2.2

globals()
Return a dictionary representing the current global symbol table. The following script “GlobalScope.py” gives some idea about the use of this function.

# Filemame: GlobalScope.py
 var1=10
 def func():
 var2=20
 func()
 if ’varl1 in globals().keys():
 print "’var1’ is a global variable of this module"
 if 1var21 in globals().keys():
 print ”'var2' is a global variable of this module"

The output is:

'varl' is a global variable of this module

hasattr(object,name)
The arguments are an object and a string. The result is True, if the string is the name of one of the object’s attributes, otherwise False.

>>> a=3.5+4.9J >» hasattr (a, ’ imag ' )
 True
 >>> hasattr(a,'imagine')
 False

hash()
In computing, a hash table (also “hash map”) is a data structure that can map keys to values. A hash table uses a hash function to compute an index (or hash value) into an array of buckets or slots, from which the correct value can be found. The built-in function hash() return the hash value of the object (if it has one) which is basically an integer and it never changes during its lifetime.
Hashability makes an object usable as a dictionary key and a set member, because these data structures use the hash value internally. All of Python’s immutable built-in objects are hashable, while no mutable containers (such as lists or dictionaries) are hashable.

>>> d={'Lisa' :8 8.5, 'John' :69.73, 'Mike' :88.5}
 >>> hash(d['Lisa'])
 1485012992
 >>> hash(d['John'])
 -1664573625
 >>> hash(d['Mike'])
 1485012992

python-programming-fundamentals-for-class-11-and-12-simple-and-compound-statements-fig3.1

Consider the following example:

>>> map(hash,("namea","nameb","namec","named"))
 [-1658398457, -1658398460, -1658398459, -1658398462]
 >>> map(hash, ( 0,1,2,3))
 [0, 1, 2, 3]

It can be observed that the strings are quite close in their letters, and their hashes are close in terms of numerical distance which is a desirable behaviour. If the keys are close in nature, one wants their hashes to be close as well so that lookups remain fast. Integers have same hash value as itself.

help([object])
This function invokes the built-in help system (this function is intended for interactive use). If no argument is given, the interactive help system starts on the interpreter console. If the argument is a
string, then the string is looked up as the name of a module, function, class, method, keyword, or documentation topic, and a help page is printed on the console. If the argument is any other kind of object, a help page on the object is generated.

>>> help(cmp)
 Help on built-in function cmp in module _builtin_ :
 cmp(...)
 cmp(x, y) -> integer
 Return negative if x<y, zero if x==y, positive if x>y.

hex(x)
Convert an integer number (of any size) to a hexadecimal string. To obtain a hexadecimal string representation for a float, use the float. hex () method.

>>> hex(25)
 '0x19'

id(object)
Return the identity of the object. This is an integer (or long integer) which is guaranteed to be unique and constant for this object during its lifetime. Two objects with non-overlapping lifetimes may have the same id () value.

>>> a=5
 >>> id(a)
 3885104
 >>> b='hello'
 >>> id(b)
 44148000

input([prompt])
This function is used to take input from user and evaluates the expression. There is also raw_input () function which takes input from user, convert it to a string, and returns that.

>>> aa=4
 >>> bb=6
 >>> resultl=input('-->')
 -->aa+bb
 >>> result2=raw_input ( '-->')
 -->aa+bb
 >>>
 >>> result1
 10
 >>> result2
 'aa+bb'

isinstance(object,classinfo)
Return True, if the object argument is an instance of the classinfo argument, or of a subclass thereof.

>>> class new_cls:
 ... def _init_ (self,x):
 ... self.x=x
 >>> tt=new_cls(10)
 >>> isinstance(tt,new_cls)
 True

Also return True, if classinfo is a type object, and object is an object of that type or of a subclass thereof. If object is not a class instance or an object of the given type, the function always returns False.

>>> i=5 >>> type(i) ctype 'int'>
 >>> type(int) ctype 'type'>
 >>> isinstance(i,int)
 True
 >>> isinstance(i,str)
 False

If classinfo is neither a class object nor a type object, it may be a tuple of class or type objects (other sequence types are not accepted). If classinfo is not a class, type, or tuple of classes, types, a TypeError exception is raised.

>>> isinstance (i, (str,int,float,complex))
 True

issubclass(class,classinfo)
Return True, if class is a subclass of classinfo.

>>> class A:
 ... pass
 >>> class B(A):
 . . . pass
 >>> class C:
 ... pass
 >>> class D:
 ... pass
 >>> issubclass (B, A)
 True

A class is considered a subclass of itself.

>>> issubclass(D,D)
 True

The classinfo may be a tuple of class objects, in which case every entry in classinfo will be checked. In any other case, a TypeError exception is raised.

>>> issubclass(B,(A,C,D))
 True

len(s)
Return the length (the number of items) of an object s. The argument may be a sequence (string, tuple or list) or a mapping (dictionary).

>>> len('abcd')
 4
 >>> seq=['a','b','c','d']
 >>> len(seq)
 4
 >>> seq=('a','b','c' ,'d')
 >>> len(seq)
 4
 >» dict= { 'a' :8, 'b' : 9, ' c ' :10, 'd' : 11}
 >>> len(dict)
 4
 >>> len('')
 0

locals ()
The function returns a dictionary representing the current local symbol table.

#! /usr/bin/env python
 # Filemame: LocalScope.py
 varl=10
 var2=20
 def func():
 var3=30
 var4=40
 print 'Local variables of func()=',locals()
 func()
 if 'varl' in locals().keys() and 'var2' in locals().keys():
 print "'varl' and 'var2' are local variables of this module"

Output is:

Local variables of func()= {'var4': 40, 'var3': 30}
 'varl' and 1var21 are local variables of this module

map(function,iterable, …)
Apply function to every item of iterable and return a list of the results. If additional iterable arguments are passed, function must take that many arguments and is applied to the items from all iterables in parallel. If one iterable is shorter than another, it is assumed to be extended with None items. If function is None, the identity function is assumed; if there are multiple arguments, map () returns a list consisting of tuples containing the corresponding items from all iterables. The iterable arguments may be a sequence or any iterable object; the result is always a list.

>>> def add100(x):
 . . . return x+100
 >>> map(add100, (44,22,66))
 [144, 122, 166]
 >>>
 >>> def abc(a,b,c):
 ... return a*10000+b*100+c
 >>> map(abc, (1,2,3), (4,5,6), (7,8,9))
 [10407, 20508, 30609]
 >>>
 >>> map(None,range(3))
 [0, 1, 2]
 >>> map(None,range(3),'abc',[44, 55, 66])
 [(0, 'a', 44), (1, 'b', 55), (2, 'c', 66)]

max(iterable[,key])
Return the largest item in an iterable. The optional argument key specifies a function of one argument that is used to extract a comparison key from each list element. The default value is None (compare the elements directly).

>>> max('hello')
 ' o'
 >>> max( [10, 80,90, 20,-100] )
 90
 >>> def LessThanFifty(x):
 ... if x<=50:
 . . . return 
x >>> max([10,80,90,20,-100],key=LessThanFifty)
 20

The function has an another form max (argl, arg2, *args [, key] ), which return the largest of two or more arguments.

>>> max('hi','hello','bye')
 'hi'
 >>> max('Gumby','Lambert','Sartre','Cheddar')
 'Cheddar'
 >>> max('Gumby','Lambert','Sartre','Cheddar',key=str.upper)
 'Sartre'

min(iterable[,key])
Return the smallest item in an iterable. The key has same meaning as that in max () function.

>>> min('hello')
 ' e'
 >>> min((10,80,90,20,-100))
 -100

The function has an another form min (argl, arg2, *args [, key] ), which return the smallest of two or more arguments.

>>> min(10,80,90,20,-100)
 -100
 >>> def rev(x): return -x
 >>> min(10,80,90,20,-100, key=rev)
 90

next(iterator[,default])
Retrieve the next item from the iterator. If default is given, it is returned if the iterator is exhausted, otherwise Stoplteration is raised.

>>> it=iter(xrange(0,3))
 >>> next(it,'Done')
 0
 >>> next(it,'Done')
 1 ,
 >>> next(it,'Done')
 2
 >>> next(it,'Done') .
 'Done'
 >>> next(it,'Done')
 'Done'
 >>> it=iter (xrange ( 0,3) )
 >>> next(it)
 0
 >>> next(it)
 1 .
 >>> next(it)
 2
 >>> next(it)
 Traceback (most recent call last):
 File "", line 1, in
 StopIteration oct(x)

Convert an integer number (of any size) to an octal string.

>>> oct(135)
 ' 0207'

pow(x,y [,z] )
Return x to the power y; if z is present, return x to the power y, and modulo z (computed more efficiently than pow (x, y) %z). The two-argument form pow (x, y) is equivalent to using the power operator x* *y. The arguments must be of numeric types. If the second argument is negative, the third argument must be omitted. If z is present, x and y must be of integer types, and y must be non negative.

>> 2**4
 16
 >>> pow(2,4)
 16
 >>> (2**4) %3
 1
 >>> pow(2,4,3)
 1
 print(*objects,sep=' ',end='\n',file=sys.stdout)

Print objects to the stream file, separated by sep and followed by end. If sep, end and file, are present, they must be given as keyword arguments. All non-keyword arguments are converted to strings and written to the stream, separated by sep and followed by end. Both sep and end must be strings, they can also be None, which means to use the default values. If no objects are given, print () will just write end. The file argument must be an object with a write () method, if it is not present or None, sys. stdout (file objects corresponding to the interpreter’s standard output stream) will be used.

This function is not normally available as a built-in function, since the name print is recognized as the print statement. To disable the statement and use the print () function, use the following future statement before using the function.

>>> from _future_ import print_function
 >>> x,y=3,5
 >>> print('The sum of',x,'plus',y,'is',x+y)
 The sum of 3 plus 5 is 8
 >>> print('The sum of',x,'plus',y,'is',x+y,sep=' ')
 The sum of 3 plus 5 is 8 -
 >>> print('The sum of',x, 'plus',y, 'is' , x+y,sep=' ', end='\n The \n
 End \n')
 The sum of 3 plus 5 is 8
 The End

range(start,stop[,step])
This function creates list whose elements are in arithmetic progression. The arguments must be plain integers. If the step argument is omitted, it defaults to 1. If the start argument is omitted, it defaults to 0. step must not be zero (or else ValueError is raised).

>>>range(10)
 [0, 1, 2, 3, 4, 5, 6, 7, 9]
 >>> range(1,11)
 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
 >>> range(0,30,5)
 [0, 5, 10, 15, 20, 25]
 >>> range(0,10,3)
 [0, 3, 6, 9]
 >>> range(0,-10,-1)
 [0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
 >>> range(0)
 [ ]
 >>> range(10,5)
 [ ]
 >>> range(10, 5, -1)
 [10, 9, 8, 7, 6]

reload(module)
Reload a previously imported module. The argument must be a module object, so it must have been successfully imported before. This is useful if the programmer has edited the module’s source file using an external editor and wants to try out the new version without leaving the Python interpreter. The return value is the module object.

reversed(seq)
The function returns an iterator object that can iterate over all the objects in the container in reverse order.

>>> Seq= [ 10,20,30]
 >>> revSeq=reversed(Seq)
 >>> for item in revSeq: print item
 30
 20
 10

round(number[,ndigits])
Return the floating point value number rounded to ndigits digits after the decimal point. If ndigits is omitted, it defaults to zero.

>>> round(2.769753)
 3.0
 >>> round(-2.769753)
 -3.0
 >>> round (2.76 9 753, 4 )
 2.7698
 >>> round(-2.769753,4)
 -2.7698

setattr(object,name,value)
This is the counterpart of getattr (). The arguments are an object, a string and an arbitrary value. The string may name an existing attribute or a new attribute. The function assigns the value to the attribute, provided the object allows it. The following example will become clearer after going through chapter 6.

>>> class new_cls:
 ... def _init_ (self,x):
 ... self.x=x
 >>> tt=new_cls(10)
 >>> tt.x
 10
 >>> setattr(tt,'x',20)
 >>> tt.x
 20
 >>> setattr(tt,'y','hello')
 >>> tt.y
 'hello'

slice(start,stop[,step])
Return a slice object representing the set of indices specified by range (start, stop, step). The function can also be of of form slice (stop), where start and step arguments default to None. Slice objects have read-only data attributes start, stop and step, which merely return the argument values (or their default).

>>> slice (20)
 slice (None, 20, None)
 >>> sl=slice(2,20,3)
 >>> type(sl)
 <type 'slice'>
 >>> si.start
 2
 >>> si.stop
 20
 >>> si.step
 3

The slice object can be passed to the getitem () method of the built-in sequences.

>>> range(50). _getitem_(sl)
 [2, 5, 8, 11, 14, 17]

Or use slice objects directly in subscripts:

>>> range(50)[si]
 [2, 5, 8, 11, 14, 17]

sorted(iterable[,cmp[,key[,reverse]]])
Return a new sorted list from the items in iterable. The arguments cmp, key, and reverse are optional.

>>> a=[66.25,333,'abc',333,1,'ab',1234.5]
 >>> sorted(a)
 [1, 66.25, 333, 333, 1234.5, 'ab', 'abc']
 >>> sorted({10:'D',5:'B',8:'B',6:'E',2:'A'})
 [2, 5, 6, 8, 10]

cmp specifies a custom comparison function of two arguments (iterable elements) which should return a negative, zero or positive number depending on whether the first argument is considered smaller than, equal to, or larger than the second argument. The default value is None.
key specifies a function of one argument that is used to extract a comparison key from each list element. The default value is None (compare the elements directly).

>>> strs=['ccc','aaaa','d','bb']
 >>> sorted(strs,key=len) # Sorted by string length
 ['d', 'bb', 'ccc', 'aaaa']
 >>> student_tuples=[
 ... ('john','A',15),
 ... ('jane','B',12),
 ... ('dave','B',10),]
 >>> sorted(student_tuples,key=lambda student: student[2]) #By age
 [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]

reverse is a boolean value. If set to True, then the list elements afe sorted as if each comparison were reversed.

>>> a=[66.25,333,'abc',333,1,’ab',1234.5]
 >>> sorted(a,reverse=True)
 ['abc', 'ab', 1234.5, 333, 333, 66.25, 1]

In general, the key and reverse conversion processes are much faster than specifying an equivalent cmp function. This is because cmp is called multiple times for each list element, while key and reverse touch each element only once.

>>> L=['geas','clue','Zoe','Ann']
 >>> sorted(L)
 ['Ann', 'Zoe', 'clue', 'geas']
 >>> def ignoreCase(x, y) :
 ... return cmp(x.upper(),y.upper())
 >>> sorted (L, ignoreCase)
 ['Ann', 'clue', 'geas', 'Zoe']
 >>> sorted(L,None,str.upper)
 ['Ann', 'clue', 'geas', 'Zoe']
 >>> L
 ['geas', 'clue', 'Zoe', 'Ann'] sum(iterable[,start])

The function returns the sum total of start (defaults to 0) and the items of an iterable.

>>> seq=[5,7.4,2, 11]
 >>> sum(seq)
 25.4
 >>> sum(seq,10.2)
 35.6
 >>> aa=4
 >>> bb=2.5
 >>> cc=9.1
 >>> seq=[aa,bb,cc]
 >>> sum(seq)
 15.6

type(object)
The function returns the type of an object.

>>> 1=50.7
 >>> type(i)
 <type ' float'>
 >>> type(i) is float
 True

xrange(start,stop[,step])
This function is very similar to range (), but returns an xrange object instead of a list. This yields the same values as the corresponding list, without actually storing them all simultaneously. The advantage of xrange () over range () is minimal, except when a very large range is used on a memory-starved machine or when all of the range () elements are never used (such as when the loop is usually terminated with break). The function can also be used as xrange (stop).
The xrange type is an immutable sequence which is commonly used for looping. The advantage of the xrange type is that an xrange object will always take the same amount of memory, no matter the size of the range it represents. There are no consistent performance advantages. The xrange objects supports indexing, iteration, and the len () function.

>>> for i in xrange(2000000000):
 . . . print i
 ... if i>5:
 . . . break
 0
 1
 2
 3
 4
 5
 6
 >>> for i in range(2000000000):
 ... print i
 ... if i>5:
 ... break
 Traceback (most recent call last):
 File "", line 1, in
 MemoryError

zip([iterable, …])
This function returns a list of tuples, where the /’th tuple contains the /’th element from each of the argument sequences or iterables. The returned list is truncated in length to the length of the shortest argument sequence. When there are multiple arguments which are all of the same length, zip () is similar to map () with an initial argument of None. With no arguments, it returns an empty list, zip () in conjunction with the * operator can be used to unzip a list:

>>> x-[1,2,3]
 >>> y=[4,5,6,7,8]
 >>> zipped=zip(x,y)
 >>> zipped
 [(1, 4), (2, 5), (3, 6)]
 >>> zip(x)
 [(1,), (2,), (3,)]
 >>> x2,y2=zip(*zipped)
 >>> x2 (1, 2, 3)
 >>> y2 (4, 5, 6)
 >>> zip()
 []

Scope

A scope defines the visibility of a name within a block. If a local variable is defined in a block, its scope includes that block. If the definition occurs in a function block, the scope extends to any blocks contained within the defining one. The scope of names defined in a class block is limited to the class block. If a name is bound in a block, it is a local variable of that block. If a name is bound at the module level, it is a global variable. The variables of the module code block are local and global.
In Python, variables that are only referenced inside a function are implicitly global. If a variable is ever assigned a new value inside the function, the variable is implicitly local, and the programmer need to explicitly declare it as global.
The scope is bit difficult to understand, the following examples might prove fruitful.

def f () :
 print s
 s="I hate spam"
 f ()

The variable s is defined as the string “I hate spam”, before the function call f (). The only statement in f () is the print statement. As there is no local variable s in f (), the value from the global s will be used. So the output will be the string “I hate spam”. The question is, what will happen, if the programmer changes the value of s inside of the function f () ? Will it affect the global s as well? The test is in the following piece of code:

def f():
 s="Me too."
 print s
 s="I hate spam."
 f()
 print s

The output looks like the following. It can be observed that s in f () is local variable of f ().

Me too.
 I hate spam.

The following example tries to combine the previous two examples i.e. first access s and then assigning a value to it in function f ().

def f():
 print s s="Me too."
 print s
 s="I hate spam."
 f ()
 print s

The code will raise an exception- UnboundLocalError: local variable ‘s’ referenced before assignment
Python assumes that a local variable is required due to the assignment to s anywhere inside f (), so the first print statement gives the error message. Any variable which is changed or created inside of a function is local, if it has not been declared as a global variable. To tell Python to recognize the variable as global, use the keyword global, as shown in the following example.

def f () :
 global s print s
 s="That's clear." print s
 s="Python is great!"
 f ()
 print s

Now there is no ambiguity. The output is as follows:

Python is great!
 That's clear.
 That's clear.

Local variables of functions cannot be accessed from outside the function code block.

def f () :
 s="I am globally not known" print s
 f()
 print s

Executing the above code will give following error message- NameError : name ‘s’ is not
defined

Exceptions

Exception is a way of breaking out of the normal flow of control of a code block in order to handle error or other exceptional condition. An exception is raised at the point where the error is detected.

>>> while True print 'Hello world'
 SyntaxError: invalid syntax
 >>> 10/0
 Traceback (most recent call last):
 File "<pyshell#l>", line 1, in
 10/0
 ZeroDivisionError: integer division or modulo by zero
 >>> 4+tt*3
 Traceback (most recent call last):
 File "<pyshell#2>", line 1, in
 4+tt*3
 NameError: name 'tt' is not defined
 >>> ' 5 ' +7
 Traceback (most recent call last):
 File "<pyshell#3>", line 1, in
 ' 5 ' +7
 TypeError: cannot concatenate 'str' and 'int' objects

The last line of the error message indicates what went wrong. Exceptions are of different types, and the type is printed as part of the message; the types in the above example are SyntaxError, ZeroDivisionError, NameError and TypeError. Standard exception names are built-in identifiers (not reserved keywords). The rest of the lines provides detail based on the type of exception and what caused it.

Handling exceptions
If there is some suspicious code that may raise an exception, it can be handled by placing the suspicious code in a try compound statement. After the try clause, include an except clause, followed by a block of code which handles the problem. The following example attempts to open a file and write something in the file.

#!/usr/bin/python try:
 fh = open("testfile", "w")
 fh.write("This is my test file for exception handling!!")
 except IOError:
 print "Error: can\'t find file or read data"
 else:
 print "Written content in the file successfully"
 fh.close()

Here are few important points that needs to be remembered: …

  • A single try statement can have multiple except clauses. This is useful when the try clause contains statements that may throw different types of exceptions.
  • A generic except clause can be provided, which handles any exception.
  • After the except clause(s), an else clause can be incuded. The code in the else clause is executed, if the code in the try clause does not raise an exception.

Python Programming FundamentalsComputer Science