python by rj

243

Upload: shantaben-haribhai-gajera-patel-sankul-amreli

Post on 18-Feb-2017

221 views

Category:

Education


0 download

TRANSCRIPT

WHAT IS PROGRAMMING LANGUAGE?

A programming language is a formal computer language or constructed language designed to communicate instructions to a machine, particularly a computer.

Programming languages can be used to create programs to control the behavior of a machine or to express algorithms.

COMPILER VS INTERPRETER An interpreter is a program that reads and executes

code. This includes source code, pre-compiled code, and scripts.

Common interpreters include Perl, Python, and Ruby interpreters, which execute Perl, Python, and Ruby code respectively.

Interpreters and compilers are similar, since they both recognize and process source code.

However, a compiler does not execute the code like and interpreter does.

Instead, a compiler simply converts the source code into machine code, which can be run directly by the operating system as an executable program.

Interpreters bypass the compilation process and execute the code directly.

interpreters are commonly installed on Web servers, which allows developers to run executable scripts within their webpages. These scripts can be easily edited and saved without the need to recompile the code.

without an interpreter, the source code serves as a plain text file rather than an executable program.

INTRODUCTION OF PYTHON Python is an object-oriented, high level language,

interpreted, dynamic and multipurpose programming language.

Python is easy to learn yet powerful and versatile scripting language which makes it attractive for Application Development.

Python's syntax and dynamic typing with its interpreted nature, make it an ideal language for scripting and rapid application development in many areas.

Python supports multiple programming pattern, including object oriented programming, imperative and functional programming or procedural styles.

Python is not intended to work on special area such as web programming. That is why it is known as multipurpose because it can be used with web, enterprise, 3D CAD etc.

We don't need to use data types to declare variable because it is dynamically typed so we can write a=10 to declare an integer value in a variable.

Python makes the development and debugging fast because there is no compilation step included in python development and edit-test-debug cycle is very fast.

It is used for GUI and database programming, client- and server-side web programming, and application testing.

It is used by scientists writing applications for the world's fastest supercomputers and by children first learning to program.

HISTORY OF PYTHON

Python was conceptualized by Guido Van Rossum in the late 1980s.

Rossum published the first version of Python code (0.9.0) in February 1991 at the CWI (Centrum Wiskunde & Informatica) in the Netherlands , Amsterdam.

Python is derived from ABC programming language, which is a general-purpose programming language that had been developed at the CWI.

Rossum chose the name "Python", since he was a big fan of Monty Python's Flying Circus.

Python is now maintained by a core development team at the institute, although Rossum still holds a vital role in directing its progress.

PYTHON VERSIONSRelease dates for the major and minor versions:Python 1.0 - January 1994

Python 1.5 - December 31, 1997 Python 1.6 - September 5, 2000

Python 2.0 - October 16, 2000 Python 2.1 - April 17, 2001 Python 2.2 - December 21, 2001 Python 2.3 - July 29, 2003 Python 2.4 - November 30, 2004 Python 2.5 - September 19, 2006 Python 2.6 - October 1, 2008 Python 2.7 - July 3, 2010

PYTHON VERSIONSRelease dates for the major and minor versions:Python 3.0 - December 3, 2008

Python 3.1 - June 27, 2009 Python 3.2 - February 20, 2011 Python 3.3 - September 29, 2012 Python 3.4 - March 16, 2014 Python 3.5 - September 13, 2015

PYTHON FEATURES

Easy to learn, easy to read and easy to maintain.Portable: It can run on various hardware platforms and has the same interface on all platforms.Extendable: You can add low-level modules to the Python interpreter.Scalable: Python provides a good structure and support for large programs.Python has support for an interactive mode of testing and debugging.Python has a broad standard library cross-platform. Everything in Python is an object: variables, functions, even code. Every object has an ID, a type, and a value.

MORE FEATURES ..

Python provides interfaces to all major commercial databases. Python supports functional and structured programming methods as well

as OOP. Python provides very high-level dynamic data types and supports

dynamic type checking. Python supports GUI applications Python supports automatic garbage collection. Python can be easily integrated with C, C++, and Java.

The Basic Elements of Python A Python program, sometimes called a script, is a

sequence of definitions and commands. These definitions are evaluated and the commands

are executed by the Python interpreter in something called the shell.

Typically, a new shell is created whenever execution of a program begins. In most cases, a window is associated with the shell.

A command, often called a statement, instructs the interpreter to do something.

For example, the statement print 'Yankees rule!' instructs the interpreter to output the string Yankees rule! to the window associated with the shell.

The sequence of commands print 'Yankees rule!' print 'But not in Boston!' print 'Yankees rule,', 'but not in Boston!'

causes the interpreter to produce the output Yankees rule! But not in Boston! Yankees rule, but not in Boston!

Notice that two values were passed to print in the third statement.

The print command takes a variable number of values and prints them, separated by a space character, in the order in which they appear.

Objects, Expressions, and Numerical Types Objects are the core things that Python

programs manipulate. Every object has a type that defines the kinds of

things that programs can do with objects of that type.

Python has four types of scalar objects: int is used to represent integers. Literals of type int are written

in the way we typically denote integers (e.g., -3 or 5 or 10002). float is used to represent real numbers. Literals of type float

always include a decimal point (e.g., 3.0 or 3.17 or -28.72). (It is also possible to write literals of type float using scientific notation. For example, the literal 1.6E3 stands for 1.6 * 10 , i.e., it is the same as 1600.0.) You might wonder why this type is not called real.

Within the computer, values of type float are stored in the computer as floating point numbers. This representation, which is used by all modern programming languages, has many advantages. However, under some situations it causes floating point arithmetic to behave in ways that are slightly different from arithmetic on real numbers.

• bool is used to represent the Boolean values True and False. • None is a type with a single value.

Objects and operators can be combined to form expressions, each of which evaluates to an object of some type. We will refer to this as the value of the expression.

For example, the expression 3 + 2 denotes the object 5 of type int, and the expression 3.0 + 2.0 denotes the object 5.0 of type float.

The == operator is used to test whether two expressions evaluate to the same value, and the != operator is used to test whether two expressions evaluate to different values.

The symbol >>> is a shell prompt indicating that the interpreter is expecting the user to type some Python code into the shell.

The line below the line with the prompt is produced when the interpreter evaluates the Python code entered at the prompt, as illustrated by the following interaction with the interpreter:

>>> 3 + 2 5 >>> 3.0 + 2.0 5.0 >>> 3 != 2 True

The built-in Python function type can be used to find out the type of an object:

>>> type(3) <type 'int'>

>>> type(3.0) <type 'float'>

The operators on types int and float are listed in Figure 2.1.

i+j is the sum of i and j. If i and j are both of type int, the result is an int. If either of them is a float, the result is a float.

i–j is i minus j. If i and j are both of type int, the result is an int . If either of them is a float, the result is a float.

i*j is the product of i and j. If i and j are both of type int, the result is an int. If either of them is a float, the result is a float.

i//j is integer division. For example, the value of 6//2 is the int 3 and the value of 6//4 is the int 1. The value is 1 because integer division returns the quotient and ignores the remainder.

i/j is i divided by j. In Python 2.7, when i and j are both of type int, the result is also an int, otherwise the result is a float.

In this book, we will never use / to divide one int by another. We will use // to do that. (In Python 3, the / operator, thank goodness, always returns a float. For example, in Python 3 the value of 6/4 is 1.5.)

i%j is the remainder when the int i is divided by the int j. It is typically pronounced “i mod j,” which is short for “i modulo j.”

i**j is i raised to the power j. If i and j are both of type int, the result is an int. If either of them is a float, the result is a float.

The comparison operators are == (equal), != (not equal), > (greater), >= (at least), <, (less) and <= (at most).

Operators on types int and float

The arithmetic operators have the usual precedence. For example, * binds more tightly than +, so the

expression x+y*2 is evaluated by first multiplying y by 2, and then adding the result to x.

The order of evaluation can be changed by using parentheses to group subexpressions,

e.g., (x+y)*2 first adds x and y, and then multiplies the result by 2.

The operators on type bool are: a and b is True if both a and b are True, and False

otherwise. a or b is True if at least one of a or b is True, and

False otherwise. not a is True if a is False, and False if a is True.

Variables and Assignment Variables provide a way to associate names with

objects. Consider the code pi = 3 radius = 11 area = pi * (radius**2) radius = 14 It first binds the names pi and radius to different

objects of type int. It then binds the name area to a third object of type int.

This is depicted in the left panel of Figure 2.2.

If the program then executes radius = 11, the name radius is rebound to a different object of type int, as shown in the right panel of Figure 2.2.

Note that this assignment has no effect on the value to which area is bound. It is still bound to the object denoted by the expression 3*(11**2).

In Python, a variable is just a name, nothing more. Remember this—it is important. An assignment statement associates the name to the left of the =

symbol with the object denoted by the expression to the right of the =. Remember this too. An object can have one, more than one, or no name

associated with it.

In Python, variable names can contain uppercase and lowercase letters, digits (but they cannot start with a digit), and the special character _.

Python variable names are case-sensitive e.g., Julie and julie are different names.

Finally, there are a small number of reserved words (sometimes called keywords) in Python that have built-in meanings and cannot be used as variable names.

Different versions of Python have slightly different lists of reserved words.

The reserved words in Python 2.7 are and, as, assert, break, class, continue, def, del, elif, else, except, exec, finally, for, from, global, if, import, in, is, lambda, not, or,pass, print, raise, return, try, with, while, and yield.

Python allows multiple assignment. The statement x, y = 2, 3 binds x to 2 and y to 3. All of the expressions on the right-hand side of the

assignment are evaluated before any bindings are changed. This is convenient since it allows you to use multiple assignment to swap the bindings of two variables.

For example, the code x, y = 2, 3 x, y = y, x print 'x =', x print 'y =', y will print x = 3 y = 2

IDLE Typing programs directly into the shell is highly inconvenient.

Most programmers prefer to use some sort of text editor that is part of an integrated development environment (IDE).

The IDE that comes as part of the standard Python installation package.

IDLE is an application, just like any other application on your computer.

Start it the same way you would start any other application, e.g., by double-clicking on an icon.

IDLE provides a text editor with syntax highlighting, auto completion, and

smart indentation, a shell with syntax highlighting, and an integrated debugger, which you should ignore for now.

When IDLE starts it will open a shell window into which you can type Python commands.

It will also provide you with a file menu and an edit menu (as well as some other menus, which you can safely ignore for now).

The file menu includes commands to create a new editing window into which you can type a

Python program, open a file containing an existing Python program, and save the contents of the current editing window into a

file (with file extension .py). The edit menu includes standard text-editing

commands (e.g., copy, paste, and find) plus some commands specifically designed to make it easy to edit Python code (e.g., indent region and comment out region).

Branching Programs Branching programs are more interesting. The

simplest branching statement is a conditional. As depicted in Figure 2.3, a conditional statement has three parts: a test, i.e., an expression that evaluates to either True or

False; a block of code that is executed if the test evaluates to

True; and an optional block of code that is executed if the test

evaluates to False. After a conditional statement is executed, execution resumes at the code following the statement.

In Python, a conditional statement has the form if Boolean expression:

block of code else:

block of code In describing the form of Python statements we use

italics to describe the kinds of code that could occur at that point in a program.

For example, Boolean expression indicates that any expression that evaluates to True or False can follow the reserved word if, and block of code indicates that any sequence of Python statements can follow else:.

Consider the following program that prints “Even” if the value of the variable x is even and “Odd” otherwise:

if x%2 == 0: print (“Even”)

else: print (“Odd' print 'Done with conditional”)

The expression x%2 == 0 evaluates to True when the remainder of x divided by 2 is 0, and False otherwise. Remember that == is used for comparison, since = is reserved for assignment.

Basic Syntax

Indentation is used in Python to delimit blocks. The number of spaces is variable, but all statements within the same block must be indented the same amount.

The header line for compound statements, such as if, while, def, and class should be terminated with a colon ( : )

The semicolon ( ; ) is optional at the end of statement.

Printing to the Screen: Reading Keyboard Input: Comments

Single line:Multiple lines:

Python files have extension .py

Error!

When either the true block or the false block of a conditional contains another conditional, the conditional statements are said to be nested. In the code below, there are nested conditionals in both branches of the top-level if statement.

if x%2 == 0: if x%3 == 0: print 'Divisible by 2 and 3' else: print 'Divisible by 2 and not by 3'

elif x%3 == 0: print 'Divisible by 3 and not by 2'

The elif in the above code stands for “else if.” It is often convenient to use compound Boolean expressions in the test of a conditional, for example,

if x < y and x < z: print 'x is least‘

elif y < z: print 'y is least'

else: print 'z is least'

Finger exercise: Write a program that examines three variables—x, y, and z— and prints the largest odd number among them. If none of them are odd, it should print a message to that effect.

Strings and Input Strings are amongst the most popular types in Python. We can create them

simply by enclosing characters in quotes. Python treats single quotes the same as double quotes. Creating strings is as simple as assigning a value to a variable. For example − var1 = 'Hello World!' var2 = "Python Programming"

Objects of type str are used to represent strings of characters.11 Literals of type str can be written using either single or double quotes, e.g., 'abc' or "abc".

The literal '123' denotes a string of characters, not the number one hundred twenty-three.

Try typing the following expressions in to the Python interpreter (remember that the >>> is a prompt, not something that you type):

>>> 'a' >>> 3*4 >>> 3*'a' >>> 3+4 >>> 'a'+'a' The operator + is said to be overloaded: It has different meanings

depending upon the types of the objects to which it is applied. For example, it means addition when applied to two numbers and

concatenation when applied to two strings. The operator * is also overloaded. It means what you expect it to mean when its operands are both numbers. When applied to an int and a str, it duplicates the str. For example, the expression 2*'John' has the value

'JohnJohn'. There is a logic to this. Just as the expression 3*2 is equivalent to 2+2+2, the expression 3*'a' is equivalent to 'a'+'a'+'a'.

Now try typing >>> a >>> 'a'*'a' Each of these lines generates an error message. The first line produces the message

NameError: name 'a' is not defined Because a is not a literal of any type, the interpreter

treats it as a name. However, since that name is not bound to any

object, attempting to use it causes a runtime error. The code 'a'*'a' produces the error message

TypeError: can't multiply sequence by non-int of type 'str'

Escape Characters An escape character lets you use characters that are

otherwise impossible to put into a string. An escape character consists of a backslash (\) followed by

the character you want to add to the string. (Despite consisting of two characters, it is commonly referred to as a singular escape character.)

For example, the escape character for a single quote is \'. You can use this inside a string that begins and ends with single quotes. To see how escape characters work, enter the following into the interactive shell:

>>> spam = 'Say hi to Bob\'s mother.' Python knows that since the single quote in Bob\'s has a

backslash, it is not a single quote meant to end the string value.

The escape characters \' and \" let you put single quotes and double quotes inside your strings, respectively.

` >>> print("Hello there!\nHow are you?\

nI\'m doing fine.") Hello there! How are you? I'm doing fine.

Raw Strings

You can place an r before the beginning quotation mark of a string to make it a raw string. A raw string completely ignores all escape characters and prints any backslash that appears in the string. For example, type the following into the interactive shell:

>>> print(r'That is Carol\'s cat.') That is Carol\'s cat.

Because this is a raw string, Python considers the backslash as part of the string and not as the start of an escape character.

Raw strings are helpful if you are typing string values that contain many backslashes, such as the strings used for regular expressions described in the next chapter.

Multiline Strings with Triple Quotes While you can use the \n escape character to put a

newline into a string, it is often easier to use multiline strings.

A multiline string in Python begins and ends with either three single quotes or three double quotes.

Any quotes, tabs, or newlines in between the “triple quotes” are considered part of the string.

Python’s indentation rules for blocks do not apply to lines inside a multiline string.

print('''Dear Alice, Eve's cat has been arrested for catnapping, cat burglary, and extortion. Sincerely, Bob''')

Indexing and Slicing Strings Strings use indexes and slices the same way lists

do. You can think of the string 'Hello world!' as a list and each character in the string as an item with a corresponding index.

' H e l l o w o r l d ! ' 0 1 2 3 4 5 6 7 8 9 10 11

The space and exclamation point are included in the character count, so 'Hello world!' is 12 characters long, from H at index 0 to ! at index 11.

>>> spam = 'Hello world!'

>>> spam[0] 'H‘

>>> spam[4] 'o‘

>>> spam[-1] '!'

>>> spam[0:5] 'Hello'

>>> spam[:5] 'Hello'

>>> spam[6:] 'world!'

If you specify an index, you’ll get the character at that position in the string. .

If you specify a range from one index to another, the starting index is included and the ending index is not.

That’s why, if spam is 'Hello world!', spam[0:5] is 'Hello'.

The substring you get from spam[0:5] will include everything from spam[0] to spam[4], leaving out the space at index 5.

Note that slicing a string does not modify the original string. You can capture a slice from one variable in a separate variable.

Try typing the following into the interactive shell: >>> spam = 'Hello world!‘ >>> fizz = spam[0:5] >>> fizz 'Hello'

By slicing and storing the resulting substring in another variable, you can have both the whole string and the substring handy for quick, easy access.

The in and not in Operators with Strings

The in and not in operators can be used with strings just like with list values.

An expression with two strings joined using in or not in will evaluate to a Boolean True or False.

Enter the following into the interactive shell: >>> 'Hello' in 'Hello World'

True >>> 'Hello' in 'Hello'

True >>> 'HELLO' in 'Hello World'

False >>> '' in 'spam'

True >>> 'cats' not in 'cats and dogs'

False These expressions test whether the first string (the exact string,

case sensitive) can be found within the second string.

upper(), lower(), isupper(), and islower() String Methods

The upper() and lower() string methods return a new string where all the letters in the original string have been converted to uppercase or lower-case, respectively.

Nonletter characters in the string remain unchanged.

Enter the following into the interactive shell:

>>> spam = 'Hello world!' >>> spam = spam.upper()

>>> spam 'HELLO WORLD!' >>> spam = spam.lower()

>>> spam 'hello world!'

Note that these methods do not change the string itself but return new string values.

If you want to change the original string, you have to call upper() or lower() on the string and then assign the new string to the variable where the original was stored.

This is why you must use spam = spam.upper() to change the string in spam instead of simply spam.upper(). (This is just like if a variable eggs contains the value 10.

Writing eggs + 3 does not change the value of eggs, but eggs = eggs + 3 does.)

The upper() and lower() methods are helpful if you need to make a case-insensitive comparison. The strings 'great' and 'GREat' are not equal to each other. But in the following small program, it does not matter whether the user types Great, GREAT, or grEAT, because the string is first converted to lowercase.

print('How are you?') feeling = input() if feeling.lower() ==

'great': print('I feel great too.')

else: print('I hope the rest of your day is good.')

The isupper() and islower() methods will return a Boolean True value if the string has at least one letter and all the letters are uppercase or lowercase, respectively. Otherwise, the method returns False. Enter the following into the interactive shell, and notice what each method call returns:

>>> spam = 'Hello world!' >>> spam.islower()

False >>> spam.isupper()

False >>> 'HELLO'.isupper()

True >>> 'abc12345'.islower()

True >>> '12345'.islower()

False >>> '12345'.isupper()

False

The isX String Methods Along with islower() and isupper(), there are several

string methods that have names beginning with the word is. These methods return a Boolean value that describes the nature of the string. Here are some common isX string methods:

isalpha() returns True if the string consists only of letters and is not blank.

isalnum() returns True if the string consists only of letters and numbers and is not blank.

isdecimal() returns True if the string consists only of numeric characters and is not blank.

isspace() returns True if the string consists only of spaces, tabs, and new-lines and is not blank.

istitle() returns True if the string consists only of words that begin with an uppercase letter followed by only lowercase letters.

>>> 'hello'.isalpha() True

>>> 'hello123'.isalpha() False

>>> 'hello123'.isalnum() True

>>> 'hello'.isalnum() True

>>> '123'.isdecimal() True

>>> ' '.isspace() True

>>> 'This Is Title Case'.istitle() True

>>> 'This Is Title Case 123'.istitle() True

>>> 'This Is not Title Case'.istitle() False

>>> 'This Is NOT Title Case Either'.istitle() False

The startswith() and endswith() String Methods

The startswith() and endswith() methods return True if the string value they are called on begins or ends (respectively) with the string passed to the method; otherwise, they return False. Enter the following into the interactive shell:

>>> 'Hello world!'.startswith('Hello') True

>>> 'Hello world!'.endswith('world!') True

>>> 'abc123'.startswith('abcdef') False

>>> 'abc123'.endswith('12') False

>>> 'Hello world!'.startswith('Hello world!') True

>>> 'Hello world!'.endswith('Hello world!') True

The join() and split() String Methods

The join() method is useful when you have a list of strings that need to be joined together into a single string value. The join() method is called on a string, gets passed a list of strings, and returns a string. The returned string is the concatenation of each string in the passed-in list. For example, enter the following into the interactive shell:

>>> ', '.join(['cats', 'rats', 'bats']) 'cats, rats, bats' `

>>> ' '.join(['My', 'name', 'is', 'Simon']) 'My name is Simon‘

>>> 'ABC'.join(['My', 'name', 'is', 'Simon']) 'MyABCnameABCisABCSimon'

Notice that the string join() calls on is inserted between each string of the list argument. For example, when join(['cats', 'rats', 'bats']) is called on the ', ' string, the returned string is ‘cats, rats, bats’.

The split() method does the opposite: It’s called on a string value and returns a list of strings. Enter the following into the interactive shell:

>>> 'My name is Simon'.split() ['My', 'name', 'is', 'Simon']

The length of a string can be found using the len function.

For example, the value of len('abc') is 3.

Input used to get input directly from a user, input and raw_input. Each takes a string as an argument and displays it as a

prompt in the shell. It then waits for the user to type something, followed by hitting the enter key.

For raw_input, the input line is treated as a string and becomes the value returned by the function;

input treats the typed line as a Python expression and infers a type.

>>> name = raw_input(“Enter your name: “) Enter your name: George Washington

>>> print (“Are you really”, name, “?”) Are you really George Washington ?

>>> print 'Are you really ' + name + '?' Are you really George Washington?

Iteration This kind of a for loop iterates over an enumeration

of a set of items. It is usually characterized by the use of an implicit or explicit iterator. In each iteration step a loop variable is set to a value in a sequence or other data collection.

Syntax of the For Loop the Python for loop is an iterator based for loop. It

steps through the items of lists, tuples, strings, the keys of dictionaries and other iterables.

The Python for loop starts with the keyword "for" followed by an arbitrary variable name, which will hold the values of the following sequence object, which is stepped through.

Syntax for iterating_var in sequence:

statements(s) If a sequence contains an expression list, it is evaluated first.

Then, the first item in the sequence is assigned to the iterating variable iterating_var. Next, the statements block is executed. Each item in the list is assigned to iterating_var, and the statement(s) block is executed until the entire sequence is exhausted.

Example

Iterating by Sequence Index An alternative way of iterating through each item is by index offset

into the sequence itself. Following is a simple example − fruits = ['banana', 'apple', 'mango'] for index in range(len(fruits)):

print (“Current fruit :”, fruits[index] ) print ("Good bye!" )

The len() built-in function, which provides the total number of elements in the tuple as well as the range() built-in function to give us the actual sequence to iterate over.

# Prints out the numbers 0,1,2,3,4 for x in range(5):

print (x)

for x in range(3, 6): print (x)

for x in range(3, 8, 2): print (x)

Using else Statement with Loops

Python supports to have an else statement associated with a loop statement

If the else statement is used with a for loop, the else statement is executed when the loop has exhausted iterating the list.

If the else statement is used with a while loop, the else statement is executed when the condition becomes false.

while Loop A while loop statement in Python programming language

repeatedly executes a target statement as long as a given condition is true.

Syntax The syntax of a while loop in Python programming language is − while expression:

statement(s) Here, statement(s) may be a single statement or a block of

statements. The condition may be any expression, and true is any non-zero value. The loop iterates while the condition is true.

When the condition becomes false, program control passes to the line immediately following the loop.

In Python, all the statements indented by the same number of character spaces after a programming construct are considered to be part of a single block of code.

Python uses indentation as its method of grouping statements.

Here, key point of the while loop is that the loop might not ever run. When the condition is tested and the result is false, the loop body will be skipped and the first statement after the while loop will be executed.

count = 0 while (count < 9): print ('The count is:', count) count=count + 1 print ("Good bye!" )

count = 0 while count < 5:

print count, " is less than 5" count = count + 1

else: print count, " is not less than 5"

"break" and "continue" statements break is used to exit a for loop or a while loop, whereas

continue is used to skip the current block, and return to the "for" or "while" statement.

# Prints out 0,1,2,3,4

count = 0while True: print (count) count += 1 if count >= 5: break

for x in range(10):if x % 2 == 0:

continueprint (x)

"else" clause for loops

# Prints out 0,1,2,3,4 and then it prints "count value reached 5"

count=0 while(count<5):

print (count) count +=1

else: print ("count value reached %d" %(count) )

# Prints out 1,2,3,4for i in range(1,10): if(i%5==0): break print (i)else:

print ("this is not printed because for loop is terminated because of break but not due to fail in condition")

Python nested loops Python programming language

allows to use one loop inside another loop.

for iterating_var in sequence: for iterating_var in sequence: statements(s)

statements(s)

while expression: while expression: statement(s)

statement(s)

A final note on loop nesting is that you can put any type of loop inside of any other type of loop. For example a for loop can be inside a while loop or vice versa.

Python Functions A function is a block of organized, reusable

code that is used to perform a single, related action. Functions provide better modularity for your application and a high degree of code reusing.

As you already know, Python gives you many built-in functions like print(), etc. but you can also create your own functions. These functions are called user-defined functions.

Defining a Function You can define functions to provide the required

functionality. Here are simple rules to define a function in Python.

Function blocks begin with the keyword def followed by the function name and parentheses ( ( ) ).

Any input parameters or arguments should be placed within these parentheses. You can also define parameters inside these parentheses.

The first statement of a function can be an optional statement - the documentation string of the function or docstring.

The code block within every function starts with a colon (:) and is indented.

The statement return [expression] exits a function, optionally passing back an expression to the caller.

A return statement with no arguments is the same as return None.

CALLING A FUNCTION Defining a function only gives it a name, specifies

the parameters that are to be included in the function and structures the blocks of code.

Once the basic structure of a function is finalized, you can execute it by calling it from another function or directly from the Python prompt.

FUNCTION ARGUMENTSYou can call a function by using the

following types of formal arguments:Required argumentsKeyword argumentsDefault argumentsVariable-length arguments

Required arguments

Required arguments are the arguments passed to a function in correct positional order. Here, the number of arguments in the function call should match exactly with the function definition.

To call the function printme(), you definitely need to pass one argument, otherwise it gives a syntax error as follows:

Traceback (most recent call last):File "test.py", line 11, in <module> printme();TypeError: printme() takes exactly 1 argument (0 given)

Keyword arguments

Keyword arguments are related to the function calls. When you use keyword arguments in a function call, the caller identifies the arguments by the parameter name.

This allows you to skip arguments or place them out of order because the Python interpreter is able to use the keywords provided to match the values with parameters.

Default arguments A default

argument is an argument that assumes a default value if a value is not provided in the function call for that argument.

# Function definition is heredef printinfo( name, age =

35 ): "This prints a passed info

into this function" print "Name: ", name print "Age ", age return;

# Now you can call printinfo function

printinfo( age=50, name="miki" )

printinfo( name="miki" )

Variable-length argument You may need to process a function for more arguments

than you specified while defining the function. These arguments are called variable-length arguments and are not named in the function definition, unlike required and default arguments.

Syntax for a function with non-keyword variable arguments is this.

def functionname([formal_args,] *var_args_tuple ): "function_docstring" function_suite return [expression]

An asterisk (*) is placed before the variable name that holds the values of all nonkeyword variable arguments. This tuple remains empty if no additional arguments are specified during the function call.

return statement The return statement is used to return from a function i.e.

break out of the function. We can optionally return a value from the function as well.

Every function implicitly contains a return None statement. You can see this by running print someFunction() where the function someFunction does not use the return statement

Pass by reference vs value All parameters (arguments) in the Python language are passed by

reference. It means if you change what a parameter refers to within a function, the change also reflects back in the calling function.

Here, we are maintaining reference of the passed object and appending values in the same object.

Function example There is one more example where argument is being passed by reference

but inside the function, but the reference is being over-written. The parameter mylist is local to the function changeme. Changing

mylist within the function does not affect mylist

The Anonymous Functions You can use the lambda keyword to create small anonymous functions. These functions

are called anonymous because they are not declared in the standard manner by using the def keyword.

Lambda forms can take any number of arguments but return just one value in the form of an expression. They cannot contain commands or multiple expressions.

An anonymous function cannot be a direct call to print because lambda requires an expression.

Lambda functions have their own local namespace and cannot access variables other than those in their parameter list and those in the global namespace.

Although it appears that lambda's are a one-line version of a function, they are not equivalent to inline statements in C or C++, whose purpose is by passing function stack allocation during invocation for performance reasons.

The syntax of lambda functions contains only a single statement, which is as follows − lambda [arg1 [,arg2,.....argn]]:expression

Scope of Variables All variables in a program may not be accessible at all

locations in that program. This depends on where you have declared a variable.

The scope of a variable determines the portion of the program where you can access a particular identifier. There are two basic scopes of variables in Python Global variables Local variables

Variables that are defined inside a function body have a local scope, and those defined outside have a global scope.

This means that local variables can be accessed only inside the function in which they are declared, whereas global variables can be accessed throughout the program body by all functions.

When you call a function, the variables declared inside it are brought into scope.

Recursion a function can call other functions. It is even possible for the function

to call itself. These type of construct are termed as recursive functions.

Following is an example of recursive function to find the factorial of an integer.

Factorial of a number is the product of all the integers from 1 to that number. For example, the factorial of 6 (denoted as 6!) is 1*2*3*4*5*6 = 720.

Advantages of recursion Recursive functions make the code look clean and stylish. A complex task can be broken down into simpler sub-problems using

recursion. Sequence generation is easier with recursion than using some nested

iteration. Disadvantages of recursion Sometimes the logic behind recursion is hard to follow through. Recursive calls are expensive (inefficient) as they take up a lot of memory

and time. Recursive functions are hard to debug.

Modules A module allows you to logically organize

your Python code. Grouping related code into a module makes the code easier to understand and use.

A module is a Python object with arbitrarily named attributes that you can bind and reference.

Simply, a module is a file consisting of Python code.

A module can define functions, classes and variables. .

A module can also include runnable code.

The import StatementYou can use any Python source file as a

module by executing an import statement in some other Python source file.

The import has the following syntax:import module1[, module2[,... moduleN]

When the interpreter encounters an import statement, it imports the module if the module is present in the search path. A search path is a list of directories that the interpreter searches before importing a module.

The from...import Statement Python's from statement lets you import specific

attributes from a module into the current namespace. The from...import has the following syntax −

from modname import name1[, name2[, ... nameN]]

For example, to import the function oddeven from the module fib, use the following statement −

from k import oddeven This statement does not import the entire module

fib into the current namespace; it just introduces the item fibonacci from the module fib into the global symbol table of the importing module.

The from...import * Statement:

It is also possible to import all names from a module into the current namespace by using the following import statement −

from modname import * This provides an easy way to import all the

items from a module into the current namespace; however, this statement should be used carefully.

The dir( ) Function

The dir() built-in function returns a sorted list of strings containing the names defined by a module.

The list contains the names of all the modules, variables and functions that are defined in a module. Following is a simple example −

# Import built-in module math import math content = dir(math) print (content)

The reload() Function When the module is imported into a script, the code in

the top-level portion of a module is executed only once.

Therefore, if you want to reexecute the top-level code in a module, you can use the reload() function. The reload() function imports a previously imported module again. The syntax of the reload() function is this −

reload(module_name) Here, module_name is the name of the module you

want to reload and not the string containing the module name. For example, to reload hello module, do the following −

reload(hello)

Opening and Closing Files

Python provides basic functions and methods necessary to manipulate files by default. You can do most of the file manipulation using a file object.

The open Function Before you can read or write a file, you have to

open it using Python's built-in open() function. This function creates a file object, which would be

utilized to call other support methods associated with it.

Syntax file object = open(file_name [, access_mode]

[, buffering])

Here are parameter details: file_name: The file_name argument is a string value

that contains the name of the file that you want to access.

access_mode: The access_mode determines the mode in which the file has to be opened, i.e., read, write, append, etc. A complete list of possible values is given below in the table. This is optional parameter and the default file access mode is read (r).

buffering: If the buffering value is set to 0, no buffering takes place. If the buffering value is 1, line buffering is performed while accessing a file. If you specify the buffering value as an integer greater than 1, then buffering action is performed with the indicated buffer size. If negative, the buffer size is the system default(default behavior).

Example.1 # Open a filefo = open("foo.txt", "wb")print ("Name of the file: ", fo.name)print ("Closed or not : ", fo.closed)print ("Opening mode : ", fo.mode)print ("Softspace flag : ", fo.softspace)

Output Name of the file: foo.txt Closed or not : False Opening mode : wb Softspace flag : 0

The close() Method

he close() method of a file object flushes any unwritten information and closes the file object, after which no more writing can be done.

Python automatically closes a file when the reference object of a file is reassigned to another file. It is a good practice to use the close() method to close a file.

Syntax fileObject.close();

# Open a filefo = open("foo.txt", "wb")print ("Name of the file: ",

fo.name)

# Close opend filefo.close()

Reading and Writing Files

The write() Method The write() method

writes any string to an open file. It is important to note that Python strings can have binary data and not just text.

The write() method does not add a newline character ('\n') to the end of the string −

Syntax fileObject.write(string);

# Open a filefo = open("foo.txt",

"wb")fo.write( "Python is a

great language.\nYeah its great!!\n");

# Close opend filefo.close()

The read() Method The read() method reads a

string from an open file. It is important to note that Python strings can have binary data. apart from text data.

Syntax fileObject.read([count]); Here, passed parameter is

the number of bytes to be read from the opened file. This method starts reading from the beginning of the file and if count is missing, then it tries to read as much as possible, maybe until the end of file.

# Open a filefo = open("foo.txt",

"r+")str = fo.read(10);print ("Read String is : ",

str) # Close opend filefo.close()

File Positions

The tell() method tells you the current position within the file; in other words, the next read or write will occur at that many bytes from the beginning of the file.

The seek(offset[, from]) method changes the current file position.

The offset argument indicates the number of bytes to be moved.

The from argument specifies the reference position from where the bytes are to be moved.

If from is set to 0, it means use the beginning of the file as the reference position and 1 means use the current position as the reference position and if it is set to 2 then the end of the file would be taken as the reference position.

# Open a filefo = open("foo.txt", "r+")str = fo.read(10);print ("Read String is : ", str)

# Check current positionposition = fo.tell();print ("Current file position : ", position)

# Reposition pointer at the beginning once again

position = fo.seek(0, 0);str = fo.read(10);print ("Again read String is : ", str) # Close opend filefo.close()

Renaming and Deleting Files Python os module provides

methods that help you perform file-processing operations, such as renaming and deleting files.

To use this module you need to import it first and then you can call any related functions.

The rename() method takes two arguments, the current filename and the new filename.

Syntax os.rename(current_file

_name, new_file_name)

import os

# Rename a file from test1.txt to test2.txt

os.rename( "test1.txt", "test2.txt" )

The remove() Method

You can use the remove() method to delete files by supplying the name of the file to be deleted as the argument.

Syntaxos.remove(file_n

ame)

import os

# Delete file test2.txt

os.remove("text2.txt")

Tuples Tuple is a sequence of immutable Python objects. Tuples are

sequences, just like lists. The differences between tuples and lists are, the tuples

cannot be changed unlike lists and tuples use parentheses, whereas lists use square brackets.

tup1 = ('physics', 'chemistry', 1997, 2000); tup2 = (1, 2, 3, 4, 5 ); tup3 = "a", "b", "c", "d";

The empty tuple is written as two parentheses containing nothing

tup1 = ();

To write a tuple containing a single value you have to include a comma, even though there is only one value −

tup1 = (50,);

Updating Tuples

tup1 = (12, 34.56);tup2 = ('abc', 'xyz');

tup1[0] = 100;print(tup1[0])

tup3 = tup1 + tup2;print (tup3)

Delete Tuple Elements

Removing individual tuple elements is not possible. There is, of course, nothing wrong with putting together another tuple with the undesired elements discarded.

To explicitly remove an entire tuple, just use the del statement.

tup = ('physics', 'chemistry', 1997, 2000);

print (tup)

del (tup)

print ("After deleting tup : ")

print (tup)

Basic Tuples Operations Tuples respond to the + and * operators much

like strings; they mean concatenation and repetition here too, except that the result is a new tuple, not a string.

Indexing & Slicing Because tuples are sequences, indexing and slicing

work the same way for tuples as they do for strings. Assuming following input −

L = ('spam', 'Spam', 'SPAM!')

List A list is a data structure that holds an ordered collection

of items i.e. you can store a sequence of items in a list. This is easy to imagine if you can think of a shopping list

where you have a list of items to buy, except that you probably have each item on a separate line in your shopping list whereas in Python you put commas in between them.

The list of items should be enclosed in square brackets so that Python understands that you are specifying a list.

Once you have created a list, you can add, remove or search for items in the list.

Since we can add and remove items, we say that a list is a mutable data type i.e. this type can be altered.

list1 = ['physics', 'chemistry', 1997, 2000]; list2 = [1, 2, 3, 4, 5 ]; list3 = ["a", "b", "c", "d"]

Accessing Values in Lists

To access values in lists, use the square brackets for slicing along with the index or indices to obtain value available at that index.

list1 = ['physics', 'chemistry', 1997, 2000];list2 = [1, 2, 3, 4, 5, 6, 7 ];

print ("list1[0]: ", list1[0])print ("list2[1:5]: ", list2[1:5])

a[start:end] # items start through end-1a[start:] # items start through the rest of

the arraya[:end] # items from the beginning

through end-1a[:] # a copy of the whole array

a[-1] # last item in the arraya[-2:] # last two items in the arraya[:-2] # everything except the last two

items

Updating Lists

You can update single or multiple elements of lists by giving the slice on the left-hand side of the assignment operator, and you can add to elements in a list with the append() method.

list = ['physics', 'chemistry', 1997, 2000];

print ("Value available at index 2 : “)

print (list[2])

list[2] = 2001;

print ("New value available at index 2 : “)

print (list[2])

Delete List Elements

To remove a list element, you can use either the del statement if you know exactly which element(s) you are deleting or the remove() method if you do not know.

list1 = ['physics', 'chemistry', 1997, 2000];

print (list1)

del list1[2];

print ("After deleting value at index 2 : “)

print (list1)

List Comprehension List comprehension provides a concise way to

apply an operation to the values in a sequence. It creates a new list in which each element is the result of applying a given operation to a value from a sequence (e.g., the elements in another list).

For example, L = [x**2 for x in range(1,7)] print (L)

For example, mixed = [1, 2, 'a', 3, 4.0] print ([x**2 for x in mixed if type(x) == int])

Functions as Objects In Python, functions are first-class objects. That means that they can be treated like objects of

any other type, e.g., int or list. They have types, e.g., the expression type(fact)

has the value <type 'function'>; they can appear in expressions, e.g., as the right-

hand side of an assignment statement or as an argument to a function; they can be elements of lists; etc.

Using functions as arguments can be particularly convenient in conjunction with lists.

It allows a style of coding called higher-order programming.

Map Function

The map(aFunction, aSequence) function applies a passed-in function to each item in an iterable object and returns a list containing all the function call results.

We passed in a user-defined function applied to each item in the list. map calls sqr on each list item and collects all the return values into a new list.

>>> items = [1, 2, 3, 4, 5]

>>> def sqr(x): return x ** 2

>>> list(map(sqr, items))

[1, 4, 9, 16, 25]

Accessing Values in Strings

Python does not support a character type; these are treated as strings of length one, thus also considered a substring.

To access substrings, use the square brackets for slicing along with the index or indices to obtain your substring.

Updating Strings

You can "update" an existing string by (re)assigning a variable to another string.

The new value can be related to its previous value or to a completely different string altogether.

var1 = 'Hello World!' print ("Updated String :- ", var1[:6] +

'Python' )

String Special Operators

String Formatting Operator One of Python's coolest features is the string

format operator %. This operatorunique to strings and makes up for the pack of having functions from C's printfamily.

Following is a simple example: print ("My name is %s and weight is %d kg!" % ('Zara',

21))

count() The method count() returns the number of

occurrences of substring sub in the range [start, end]. Optional arguments start and end are interpreted as in slice notation.

str.count(sub, start= 0,end=len(string)) sub -- This is the substring to be searched. start -- Search starts from this index. First

character starts from 0 index. By default search starts from 0 index.

end -- Search ends from this index. First character starts from 0 index. By default search ends at the last index.

str = "this is string example....wow!!!";

sub = "i"; print ("str.count(sub, 4, 40) : ", str.count(sub,

4, 40)) sub = "wow"; print ("str.count(sub) : ", str.count(sub))

Find() It determines if string str occurs in string, or

in a substring of string if starting index beg and ending index end are given.

str.find(str, beg=0, end=len(string)) str -- This specifies the string to be searched. beg -- This is the starting index, by default

its 0. end -- This is the ending index, by default its

equal to the length of the string. Index if found and -1 otherwise.

str1 = "this is string example....wow!!!"; str2 = "exam";

print (str1.find(str2)) print (str1.find(str2, 10)) print (str1.find(str2, 40))

rfind() The method rfind() returns the last index where

the substring str is found, or -1 if no such index exists, optionally restricting the search to string[beg:end].

Syntax str.rfind(str, beg=0 end=len(string))

str -- This specifies the string to be searched. beg -- This is the starting index, by default its 0. end -- This is the ending index, by default its equal

to the length of the string. Return Value

This method returns last index if found and -1 otherwise.

str1 = "this is really a string example....wow!!!"; str2 = "is";

print (str1.rfind(str2))

print (str1.rfind(str2, 0, 10)) print (str1.rfind(str2, 10, 0))

print (str1.find(str2)) print (str1.find(str2, 0, 10)) print (str1.find(str2, 10, 0))

Index() t determines if string str occurs in string or in a

substring of string if starting index beg and ending index end are given. This method is same as find(), but raises an exception if sub is not found.

Syntax str.index(str, beg=0 end=len(string)) Parameters

str -- This specifies the string to be searched. beg -- This is the starting index, by default its 0. end -- This is the ending index, by default its equal to the

length of the string. Return Value

Index if found otherwise raises an exception if str is not found.

str1 = "this is string example....wow!!!"; str2 = "exam";

print (str1.index(str2)) print (str1.index(str2, 10)) print (str1.index(str2, 40))

replace() The method replace() returns a copy of the string in which the

occurrences of old have been replaced with new, optionally restricting the number of replacements to max.

Syntax Following is the syntax for replace() method − str.replace(old, new[, max]) Parameters

old -- This is old substring to be replaced. new -- This is new substring, which would replace old substring. max -- If this optional argument max is given, only the first

count occurrences are replaced. Return Value This method returns a copy of the string with all occurrences of

substring old replaced by new. If the optional argument max is given, only the first count occurrences are replaced.

str = "this is string example....wow!!! this is really string";

print (str.replace("is", "was")) print (str.replace("is", "was", 3))

rindex() The method rindex() returns the last index

where the substring str is found, or raises an exception if no such index exists, optionally restricting the search to string[beg:end].

Syntax str.rindex(str, beg=0 end=len(string)) Parameters

str -- This specifies the string to be searched. beg -- This is the starting index, by default its 0 len -- This is ending index, by default its equal to the

length of the string. Return Value

This method returns last index if found otherwise raises an exception if str is not found.

str1 = "this is string example....wow!!!"; str2 = "is";

print (str1.rindex(str2)) print (str1.index(str2))

lower() The method lower() returns a copy of the string

in which all case-based characters have been lowercased.

Syntax str.lower() Return Value

This method returns a copy of the string in which all case-based characters have been lowercased.

str = "THIS IS STRING EXAMPLE....WOW!!!";

print (str.lower())

rstrip()

The method rstrip() returns a copy of the string in which all chars have been stripped from the end of the string (default whitespace characters).

Syntax

str.rstrip([chars]) Parameters

chars -- You can supply what chars have to be trimmed.

Return Value This method returns a copy of the string in which

all chars have been stripped from the end of the string (default whitespace characters).

str = " this is string example....wow!!! "; print (str.rstrip()) str = "88888888this is string example....wow!!!

8888888"; print (str.rstrip('8'))

split() The method split() returns a list of all the words in

the string, using str as the separator (splits on all whitespace if left unspecified), optionally limiting the number of splits to num.

Syntax str.split(str="", num=string.count(str)). Parameters

str -- This is any delimeter, by default it is space. num -- this is number of lines to be made

Return Value This method returns a list of lines.

str = "Line1-abcdef \nLine2-abc \nLine4-abcd";

print (str.split( )) print (str.split(' ', 1 ))

Python Dictionary

Each key is separated from its value by a colon (:), the items are separated by commas, and the whole thing is enclosed in curly braces.

An empty dictionary without any items is written with just two curly braces, like this: {}.

Keys are unique within a dictionary while values may not be.

The values of a dictionary can be of any type, but the keys must be of an immutable data type such as strings, numbers, or tuples.

ACCESSING VALUES IN DICTIONARY

To access dictionary elements, you can use the familiar square brackets along with the key to obtain its value.

Example. dict = {'Name': 'Zara', 'Age': 7, 'Class':

'First'}

print ("dict['Name']: ", dict['Name']) print ("dict['Age']: ", dict['Age'])

UPDATING DICTIONARY

You can update a dictionary by adding a new entry or a key-value pair, modifying an existing entry, or deleting an existing entry.

Example dict = {'Name': 'Zara', 'Age': 7, 'Class': 'First'}

dict['Age'] = 8; # update existing entry dict['School'] = "DPS School"; # Add new entry

print ("dict['Age']: ", dict['Age']) print ("dict['School']: ", dict['School'])

DELETE DICTIONARY ELEMENTS You can either remove individual dictionary

elements or clear the entire contents of a dictionary. You can also delete entire dictionary in a single operation.

To explicitly remove an entire dictionary, just use the del statement.

PROPERTIES OF DICTIONARY KEYS Dictionary values have no restrictions. They can

be any arbitrary Python object, either standard objects or user-defined objects. However, same is not true for the keys.

There are two important points to remember about dictionary keys −

(a) More than one entry per key not allowed. Which means no duplicate key is allowed. When duplicate keys encountered during assignment, the last assignment wins.

dict = {'Name': 'Zara', 'Age': 7, 'Name': 'Manni'}

print "dict['Name']: ", dict['Name']

(b) Keys must be immutable. Which means you can use strings, numbers or tuples as dictionary keys but something like ['key'] is not allowed. Following is a simple example:

dict = {['Name']: 'Zara', 'Age': 7} print ("dict['Name']: ", dict['Name'])

WHAT IS EXCEPTION?

An exception is an event, which occurs during the execution of a program that disrupts the normal flow of the program's instructions.

In general, when a Python script encounters a situation that it cannot cope with, it raises an exception. An exception is a Python object that represents an error.

When a Python script raises an exception, it must either handle the exception immediately otherwise it terminates and quits.

HANDLING AN EXCEPTION If you have some suspicious code that may raise an

exception, you can defend your program by placing the suspicious code in a try: block. After the try: block, include an except: statement, followed by a block of code which handles the problem as smartly as possible.

If an error is encountered, a try block code execution is stopped and transferred down to the except block.

In addition to using an except block after the try block, you can also use the finally block.

The code in the finally block will be executed regardless of whether an exception occurs.

Raising an exception breaks current code execution and returns the exception back until it is handled.

RAISING AN EXCEPTIONS

You can raise exceptions in several ways by using the raise statement. The general syntax for the raise statement is as follows.

Syntax raise [Exception as args [, traceback]]]

Here, Exception is the type of exception (for example, NameError) and argument is a value for the exception argument. The argument is optional; if not supplied, the exception argument is None.

The final argument, traceback, is also optional (and rarely used in practice), and if present, is the traceback object used for the exception

CREATING CLASSES The class statement creates a new class definition. The name

of the class immediately follows the keyword class followed by a colon as follows −

class ClassName: 'Optional class documentation string' class_suite

The class has a documentation string, which can be accessed via ClassName.__doc__.

The class_suite consists of all the component statements defining class members, data attributes and functions.

You declare other class methods like normal functions with the exception that the first argument to each method is self.

The first method __init__() is a special method, which is called class constructor or initialization method that Python calls when you create a new instance of this class.

Python adds the self argument to the list for you; you do not need to include it when you call the methods.

you have a class ClassA which contains a method methodA defined as: def methodA(self, arg1, arg2):

# do something and ObjectA is an instance of this class.

Now when ObjectA.methodA(arg1, arg2) is called, python internally converts it for you as: ClassA.methodA(ObjectA, arg1, arg2)

The self variable refers to the object itself.

self is a reference to the class instance,

WHAT IS __INIT__?

__init__ is the constructor for a class. The self parameter refers to the instance of the object (like this in C++).

class Point:def __init__(self, x, y):

self._x = xself._y = y

The init method gets called when memory for the object is allocated:x = Point(1,2)

It is important to use the self parameter inside an object's method if you want to persist the value with the object. If, for instance, you implement the init method like this:

class Point:def __init__(self, x, y):

_x = x_y = y

Your x and y parameters would be stored in variables on the stack and would be discarded when the init method goes out of scope.

Setting those variables as self._x sets those variables as members of the Point object (accessible for the lifetime of the object).

WHY DO WE NEED __INIT__? Putting assignment statements in a class definition

doesn't declare instance attributes; it sets class attributes. If you do that, all pets will share the same name, type_of_pet, and number_of_legs.

__init__ is, among other things, used to set instance attributes:

def __init__(self, type_of_pet, name, number_of_legs):self.type_of_pet = type_of_petself.name = nameself.number_of_legs = number_of_legs

This will set attributes on the instance, rather than the class, so each object will have its own name, type, and leg count.

CREATING INSTANCE OBJECTS

To create instances of a class, you call the class using class name and pass in whatever arguments its __init__ method accepts.

"This would create first object of Employee class"

emp1 = Employee("Zara", 2000) "This would create second object of

Employee class" emp2 = Employee("Manni", 5000)

ACCESSING ATTRIBUTES You access the object's attributes using the dot

operator with object. Class variable would be accessed using class name as follows −

emp1.displayEmployee() emp2.displayEmployee() print ("Total Employee %d" %

Employee.empCount)

Instead of using the normal statements to access attributes, you can use the following functions −

The getattr(obj, name[, default]) : to access the attribute of object.

The hasattr(obj,name) : to check if an attribute exists or not.

The setattr(obj,name,value) : to set an attribute. If attribute does not exist, then it would be created.

The delattr(obj, name) : to delete an attribute.

hasattr(emp1, 'age') # Returns true if 'age' attribute exists

getattr(emp1, 'age') # Returns value of 'age' attribute

setattr(emp1, 'age', 8) # Set attribute 'age' at 8 delattr(empl, 'age') # Delete attribute 'age'

BUILT-IN CLASS ATTRIBUTES Every Python class keeps following built-in attributes

and they can be accessed using dot operator like any other attribute:

__dict__: Dictionary containing the class's namespace.

__doc__: Class documentation string or none, if undefined.

__name__: Class name. __module__: Module name in which the class is

defined. This attribute is "__main__" in interactive mode.

__bases__: A possibly empty tuple containing the base classes, in the order of their occurrence in the base class list.

DESTROYING OBJECTS (GARBAGE COLLECTION)

Python deletes unneeded objects (built-in types or class instances) automatically to free the memory space. The process by which Python periodically reclaims blocks of memory that no longer are in use is termed Garbage Collection.

Python's garbage collector runs during program execution and is triggered when an object's reference count reaches zero. An object's reference count changes as the number of aliases that point to it changes.

An object's reference count increases when it is assigned a new name or placed in a container (list, tuple, or dictionary). The object's reference count decreases when it's deleted with del, its reference is reassigned, or its reference goes out of scope. When an object's reference count reaches zero, Python collects it automatically.

a = 40 # Create object <40> b = a # Increase ref. count of <40> c = [b] # Increase ref. count of <40>

del a # Decrease ref. count of <40> b = 100 # Decrease ref. count of <40> c[0] = -1 # Decrease ref. count of <40>

You normally will not notice when the garbage collector destroys an orphaned instance and reclaims its space.

But a class can implement the special method __del__(), called a destructor, that is invoked when the instance is about to be destroyed. This method might be used to clean up any non memory resources used by an instance.

INHERITANCE Inheritance is used to specify that one class will get

most or all of its features from its parent class. It is a feature of Object Oriented Programming. It is a very powerful feature which facilitates users to

create a new class with a few or more modification to an existing class.

The new class is called child class or derived class and the main class from which it inherits the properties is called base class or parent class.

The child class or derived class inherits the features from the parent class, adding new features to it. It facilitates re-usability of code.

class DerivedClassName(BaseClassName):

<statement-1> . . . <statement-N>

MULTIPLE INHERITANCE a class can be derived from more than one base

classes in Python. This is called multiple inheritance.

In multiple inheritance, the features of all the base classes are inherited into the derived class. The syntax for multiple inheritance is similar to single inheritance.

class Base1: pass

class Base2: pass

class MultiDerived(Base1, Base2): pass

The class MultiDerived inherits from both Base1 and Base2.

ENCAPSULATION AND INFORMATION HIDING

Encapsulation is seen as the bundling of data with the methods that operate on that data.

Information hiding on the other hand is the principle that some internal information or data is "hidden", so that it can't be accidentally changed.

Data encapsulation via methods doesn't necessarily mean that the data is hidden. You might be capable of accessing and seeing the data anyway, but using the methods is recommended.

Finally, data abstraction is present, if both data hiding and data encapsulation is used.

Data Abstraction = Data Encapsulation + Data Hiding

Encapsulation is often accomplished by providing two kinds of methods for attributes:

The methods for retrieving or accessing the values of attributes are called getter methods.

Getter methods do not change the values of attributes, they just return the values.

The methods used for changing the values of attributes are called setter methods.

SEARCH ALGORITHMS Searching is also a common and well-studied task.

This task can be described formally as follows: Given a list of values, a function that compares two

values and a desired value, find the position of the desired value in the list.

We will look at two algorithms that perform this task:

linear search, which simply checks the values in sequence until the desired value is found

binary search, which requires a sorted input list, and checks for the value in the middle of the list, repeatedly discarding the half of the list which contains values which are definitely either all larger or all smaller than the desired value

LINEAR SEARCH

Linear search is the most basic kind of search method. It involves checking each element of the list in turn, until the desired element is found.

For example, suppose that we want to find the number 3.8 in the following list:

We start with the first element, and perform a comparison to see if its value is the value that we want.

In this case, 1.5 is not equal to 3.8, so we move onto the next element:

We perform another comparison, and see that 2.7 is also not equal to 3.8, so we move onto the next element:

We perform another comparison and determine that we have found the correct element. Now we can end the search and return the position of the element (index 2).

We had to use a total of 3 comparisons when searching through this list of 4 elements.

How many comparisons we need to perform depends on the total length of the list, but also whether the element we are looking for is near the beginning or near the end of the list. In the worst-case scenario, if our element is the last element of the list, we will have to search through the entire list to find it.

If we search the same list many times, assuming that all elements are equally likely to be searched for, we will on average have to search through half of the list each time. The cost (in comparisons) of performing linear search thus scales linearly with the length of the list.

ASSIGNMENT Write a function which implements linear

search. It should take a list and an element as a parameter, and return the position of the element in the list. If the element is not in the list, the function should raise an exception. If the element is in the list multiple times, the function should return the first position.

BINARY SEARCH Binary search is a more efficient search algorithm

which relies on the elements in the list being sorted. We apply the same search process to progressively

smaller sub-lists of the original list, starting with the whole list and approximately halving the search area every time.

We first check the middle element in the list. If it is the value we want, we can stop. If it is higher than the value we want, we

repeat the search process with the portion of the list before the middle element.

If it is lower than the value we want, we repeat the search process with the portion of the list after the middle element.

For example, suppose that we want to find the value 3.8 in the following list of 7 elements:

First we compare the element in the middle of the list to our value. 7.2 is bigger than 3.8, so we need to check the first half of the list next.

Now the first half of the list is our new list to search. We compare the element in the middle of this list to our value. 2.7 is smaller than 3.8, so we need to search the second half of this sublist next.

The second half of the last sub-list is just a single element, which is also the middle element. We compare this element to our value, and it is the element that we want.

We have performed 3 comparisons in total when searching this list of 7 items.

The number of comparisons we need to perform scales with the size of the list, but much more slowly than for linear search – if we are searching a list of length N, the maximum number of comparisons that we will have to perform is log2N.

ASSIGNMENT Write a function which implements

binary search. You may assume that the input list will be sorted. Hint: this function is often written recursively.

SORTING ALGORITHMS

Given a list of values and a function that compares two values, order the values in the list from smallest to largest.

The values might be integers, or strings or even other kinds of objects. We will examine two algorithms:

Selection sort, which relies on repeated selection of the next smallest item

Merge sort, which relies on repeated merging of sections of the list that are already sorted

Divide the list to be sorted into a sorted portion at the front (initially empty) and an unsorted portion at the end (initially the whole list).

Find the smallest element in the unsorted list: Select the first element of the unsorted list as the

initial candidate. Compare the candidate to each element of the

unsorted list in turn, replacing the candidate with the current element if the current element is smaller.

Once the end of the unsorted list is reached, the candidate is the smallest element.

Swap the smallest element found in the previous step with the first element in the unsorted list, thus extending the sorted list by one element.

Repeat the steps 2 and 3 above until only one element remains in the unsorted list.

MERGE SORT We now turn our attention to using a divide and conquer

strategy as a way to improve the performance of sorting algorithms.

The first algorithm we will study is the merge sort. Merge sort is a recursive algorithm that continually

splits a list in half. If the list is empty or has one item, it is sorted by definition

(the base case). If the list has more than one item, we split the list and

recursively invoke a merge sort on both halves. Once the two halves are sorted, the fundamental operation,

called a merge, is performed. Merging is the process of taking two smaller sorted lists and

combining them together into a single, sorted, new list. Figure 10 shows our familiar example list as it is being split by mergeSort. Figure 11 shows the simple lists, now sorted, as they are merged back together.

The algorithm for merge sort may be written as this list of steps: Create a temporary storage list which is the same size as the list to be

sorted. Start by treating each element of the list as a sorted one-element sub-

section of the original list. Move through all the sorted sub-sections, merging adjacent pairs as

follows: Use two variables to point to the indices of the smallest uncopied

items in the two sorted sub-sections, and a third variable to point to the index of the start of the temporary storage.

Copy the smaller of the two indexed items into the indicated position in the temporary storage. Increment the index of the sub-section from which the item was copied, and the index into temporary storage.

If all the items in one sub-section have been copied, copy the items remaining in the other sub-section to the back of the list in temporary storage. Otherwise return to step 3 ii.

Copy the sorted list in temporary storage back over the section of the original list which was occupied by the two sub-sections that have just been merged.

If only a single sorted sub-section remains, the entire list is sorted and we are done. Otherwise return to the start of step 3.

# A Python dictionary is a set of key-value pairs

my_dict = {'a_key': 'a_value', 'another_key': 'another_value'}

# which allows access to the values via the keys (lookup)

my_dict['another_key'] # 'another_value' # This data structure is also known as a `map`

or `hash-map`

We said that dictionaries use a technique called hashing to do the lookup in time that is nearly independent of the size of the dictionary.

The basic idea behind a hash table is simple. We convert the key to an integer, and then use that

integer to index into a list, which can be done in constant time.

In principle, values of any immutable type can be easily converted to an integer.

After all, we know that the internal representation of each object is a sequence of bits, and any sequence of bits can be viewed as representing an integer.

For example, the internal representation of 'abc' is the string of bits 011000010110001001100011, which can be viewed as a representation of the decimal integer 6,382,179.

HASH TABLES Hashing is an improvement over Direct Access Table. The

idea is to use hash function that converts a given phone number or any other key to a smaller number and uses the small number as index in a table called hash table.

Hash Function: A function that converts a given big phone number to a small practical integer value. The mapped integer value is used as an index in hash table. In simple terms, a hash function maps a big number or string to a small integer that can be used as index in hash table.A good hash function should have following properties1) Efficiently computable.2) Should uniformly distribute the keys (Each table position equally likely for each key)

a hash table is a data structure that maps keys to values

PLOTTING AND MORE ABOUT CLASSES matplotlib is probably the single most used

Python package for 2D-graphics. It provides both a very quick way to visualize data

from Python and publication-quality figures in many formats.

NumPy is the fundamental package for scientific computing with Python. It contains among other things:

a powerful N-dimensional array object sophisticated (broadcasting) functions tools for integrating C/C++ and Fortran code useful linear algebra, Fourier transform, and random

number capabilities Besides its obvious scientific uses, NumPy can also be

used as an efficient multi-dimensional container of generic data. Arbitrary data-types can be defined. This allows NumPy to seamlessly and speedily integrate with a wide variety of databases.

TESTING AND DEBUGGING Testing is the process of running a

program to try and ascertain whether or not it works as intended.

Debugging is the process of trying to fix a program that you already know does not work as intended.

TESTING The most important thing to say about

testing is that its purpose is to show that bugs exist, not to show that a program is bug-free.

To quote Edsger Dijkstra, “Program testing can be used to show the presence of bugs, but never to show their absence!”Or,

as Albert Einstein reputedly once said, “No amount of experimentation can ever prove me right; a single experiment can prove me wrong.”

Even the simplest of programs has billions of possible inputs.

Consider, for example, a program that purports to meet the specification:

def isBigger(x, y):"""Assumes x and y are ints Returns True if x

is less than y and False otherwise."""

The key to testing is finding a collection of inputs, called a test suite, that has a high likelihood of revealing bugs, yet does not take too long to run.

The key to doing this is partitioning the space of all possible inputs into subsets that provide equivalent information about the correctness of the program, and then constructing a test suite that contains one input from each partition.

A partition of a set divides that set into a collection of subsets such that each

element of the original set belongs to exactly one of the subsets. Consider, for

example, isBigger(x, y). The set of possible inputs is all pairwise combinations of integers.

One way to partition this set is into these seven subsets:

x positive, y positive x negative, y negative x positive, y negative x negative, y positive x = 0, y = 0 x = 0, y ≠ 0 x ≠ 0, y = 0

BLACK-BOX TESTING black-box tests are constructed without looking

at the code to be tested.

Black-box testing allows testers and implementers to be drawn from separate populations.

When those of us who teach programming courses generate test cases for the problem sets we assign students, we are developing black-box test suites.

Developers of commercial software often have quality assurance groups that are largely independent of development groups.

GLASS-BOX TESTING Black-box testing should never be skipped, but it is rarely

sufficient. Without looking at the internal structure of the code, it is impossible to

know which test cases are likely to provide new information. Consider the following trivial example:def isPrime(x):

"""Assumes x is a nonnegative intReturns True if x is prime; False otherwise"""if x <= 2:

return Falsefor i in range(2, x):

if x%i == 0:return False

return True

A glass-box test suite is path-complete if it exercises every potential path through the program.

This is typically impossible to achieve, because it depends upon the number of times each loop is executed and the depth of each recursion.

Despite the limitations of glass-box testing, there are a few rules of thumb that are usually worth following:

Exercise both branches of all if statements. Make sure that each except clause is executed. For each for loop, have test cases in which

The loop is not entered (e.g., if the loop is iterating over the elements of a list, make sure that it is tested on the empty list),

The body of the loop is executed exactly once, and The body of the loop is executed more than once.

For each while loop, Look at the same kinds of cases as when dealing with for loops,

and Include test cases corresponding to all possible ways of exiting the

loop. For example, for a loop starting withwhile len(L) > 0 and not L[i] == efind cases where the loop exits because len(L) is greater thanzero and cases where it exits because L[i] == e.

For recursive functions, include test cases that cause the function to return with no recursive calls, exactly one recursive call, and more than one recursive call.

CONDUCTING TESTS Testing is often thought of as occurring in two phases. One

should always start with unit testing. During this phase testers construct and run tests designed to ascertain whether individual units of code (e.g., functions) work properly.

This is followed by integration testing, which is designed to ascertain whether the program as a whole behaves as intended.

In industry, the testing process is often highly automated. Testers do not sit at terminals typing inputs and checking outputs. Instead, they use test drivers that separately.

Set up the environment needed to invoke the program (or unit) to be tested,

Invoke the program (or unit) to be tested with a predefined or automatically generated sequence of inputs,

Save the results of these invocations, Check the acceptability of the results of the tests, and Prepare an appropriate report.

During unit testing, we often need to build stubs as well as drivers.

Drivers simulate parts of the program that use the unit being tested, whereas stubs simulate parts of the program used by the unit being tested.

Stubs are useful because they allow people to test units that depend upon software or sometimes even hardware that does not yet exist.

This allows teams of programmers to simultaneously develop and test multiple parts of a system.

a stub should Check the reasonableness of the

environment and arguments supplied by the caller (calling a function with inappropriate arguments is a common error),

Modify arguments and global variables in a manner consistent with the specification, and

Return values consistent with the specification.

DEBUGGING Debugging is the process of finding and fixing software

coding errors. Software can be debugged by programmers or testers.

Runtime bugs can be categorized along two dimensions: 1. Overt → covert: An overt bug has an obvious manifestation, e.g., the

program crashes or takes far longer (maybe forever) to run than it should. A covert bug has no obvious manifestation. The program may run to conclusion with no problem—other than providing an incorrect answer. Many bugs fall between the two extremes, and whether or not the bug is overt can depend upon how carefully one examines the behavior of the program.

2. Persistent → intermittent: A persistent bug occurs every time the program is run with the

same inputs. An intermittent bug occurs only some of the time, even when the program is run on the same inputs and seemingly under the same conditions.

import pdb a = "aaa" pdb.set_trace() # pdb.set_trace() anywhere

and it will function as a breakpoint. b = "bbb" c = "ccc" final = a + b + c print (final)

ASSERTIONS Assertions are a systematic way to check that the internal state of a

program is as the programmer expected, with the goal of catching bugs.

The Python assert statement provides programmers with a simple way to confirm that the state of the computation is as expected.

An assert statement can take one of two forms: assert Boolean expression

or assert Boolean expression, argument When an assert statement is encountered, the Boolean expression is

evaluated. If it evaluates to True, execution proceeds on its way. If it evaluates

to False, an AssertionError exception is raised. Assertions are a useful defensive programming tool. They can be

used to confirm that the arguments to a function are of appropriate types. They are also a useful debugging tool. The can be used, for example, to confirm that intermediate values have the expected values or that a function returns an acceptable value.

For ex: assert 2 + 2 == 5, “Not equal“.

DYNAMIC PROGRAMMING Dynamic programming was invented by Richard

Bellman in the early 1950s. Dynamic programming is a method for efficiently

solving problems that show the characteristics of overlapping sub problems and optimal substructure.

A problem has optimal substructure if a globally optimal solution can be found by combining optimal solutions to local subproblems. We’ve already looked at a number of such problems. Merge sort, for example, exploits the fact that a list can be sorted by first sorting sublists and then merging the solutions.

A problem has overlapping sub problems if an optimal solution involves solving the same problem multiple times. Merge sort does not exhibit this property. Even though we are performing a merge many times, we are merging different lists each time.

Dynamic programming (also known as dynamic optimization) is a method for solving a complex problem by breaking it down into a collection of simpler subproblems, solving each of those subproblems just once, and storing their solutions.

for ex. I want to do some math with A + (B * C) for this formula, I divide my problem into two

parts rather than solving it as a whole. First part will be (B * C) and than the result will be added with A i.e. A + Result of (B * C) can be call a dynamic programming.

1.) Top-Down : Start solving the given problem by breaking it down. If you see that the problem has been solved already, then just return the saved answer. If it has not been solved, solve it and save the answer. This is usually easy to think of and very intuitive. This is referred to as Memoization.

2.) Bottom-Up : Analyze the problem and see the order in which the sub-problems are solved and start solving from the trivial subproblem, up towards the given problem. In this process, it is guaranteed that the subproblems are solved before solving the problem. This is referred to as Dynamic Programming.

RECURSIVE IMPLEMENTATION OF FIBONACCI FUNCTION While this implementation of the

recurrence is obviously correct, it is terribly inefficient. Try, for example, running fib(120), but don’t wait for it to complete.

The complexity of the implementation is a bit hard to derive, but it is roughly O(fib(n)).

That is, its growth is proportional to the growth in the value of the result, and the growth rate of the Fibonacci sequence is substantial.

For example, fib(120) is 8,670,007,398,507,948,658,051,921. If each recursive call took a nanosecond, fib(120) would take about 250,000 years to finish.

FIBONACCI SEQUENCES, REVISITED

•Notice that we are computing the same values over and over again. For example fib gets called with 3 three times, and each of these calls provokes four additional calls of fib. •It doesn’t require a genius to think that it might be a good idea to record the value returned by the first call, and then look it up rather than compute it each time it is needed. •This is called memoization, and is the key idea behind dynamic programming.•To evaluate fib(10) we need to compute fib(8) and fib(9). But we already computed fib(8) when computing fib(9). The trick is to remember these results. This is memoization.

MEMOIZATION Memoization effectively refers to remembering

("memoization" -> "memorandum" -> to be remembered) results of method calls based on the method inputs and then returning the remembered result rather than computing the result again. You can think of it as a cache for method results.

Memoization is a way of caching the results of a function call. If a function is memoized, evaluating it is simply a matter of looking up the result you got the first time the function was called with those parameters.

This is recorded in the memoization cache. If the lookup fails, that’s because the function has never been called with those parameters. Only then do you need to run the function itself.

memoization can result in a massive speedup.

DYNAMIC PROGRAMMING AND THE 0/1 KNAPSACK PROBLEM

A knapsack is a bag with straps, usually carried by soldiers to help them take their valuables or things which they might need during their journey.

Given a set of items, each of which is associated with some weight and value. Find the subset of items which can be carried into the knapsack with weight limit W.

It asks you to pick certain items from the set of items such that their total weight is less than or equal to W and the sum of their values is maximum.

The knapsack problem or rucksack problem is a problem in combinatorial optimization: Given a set of items, each with a weight and a value, determine the number of each item to include in a collection so that the total weight is less than or equal to a given limit and the total value is as large as possible.

0/1 means that either we can pick an item or we can leave the item. It is impossible to take a fraction of the item.

Dynamic programming and divide and conquer

Divide & Conquer1. The divide-and-conquer paradigm involves three steps at each level of the recursion:• Divide the problem into a number of sub problems.• Conquer the sub problems by solving them recursively. If the sub problem sizes are small enough, however, just solve the sub problems in a straightforward manner.• Combine the solutions to the sub problems into the solution for the original problem.2. They call themselves recursively one or more times to deal with closely related sub problems.3. D&C does more work on the sub-problems and hence has more time consumption.4. In D&C the sub problems are independent of each other.5. Example: Merge Sort, Binary Search

Dynamic Programming1. The development of a dynamic-programming

algorithm can be broken into a sequence of four steps.a. Characterize the structure of an optimal solution.b. Recursively define the value of an optimal solution. c. Compute the value of an optimal solution in a bottom-up fashion.d. Construct an optimal solution from computed information2. Dynamic Programming is not recursive.

3. DP solves the sub problems only once and then stores it in the table.

4. In DP the sub-problems are not independent.

5. Example : Matrix chain multiplication

Python Syntax

Variables

Python is dynamically typed. You do not need to declare variables!

The declaration happens automatically when you assign a value to a variable.

Variables can change type, simply by assigning them a new value of a different type.

Python allows you to assign a single value to several variables simultaneously.

You can also assign multiple objects to multiple variables.