Sunday, April 22, 2012

painless python for python enthusiasts

# Usage
- Email Spell Checker, spams and viruses from Emails
- python is good at data objects and memory managements
- One high level programming language
- Run programs on command-line or IDE
- By default in Mac,unix,linux
./configure; make; make install

#SEGMENT 1
- Source files with .py file extension; .pyc those are the byte code compiled version of the source code
- Intergrated Development Environments (IDEs)
- provides source code editing
- Execution framework
- Tools such as debuggers, analyzers etc
- Various IDE: IDLE, SPE, PyDev/Eclipse
- Ipython is another Interactive cmd-line has much features than the default
Interactive mode
- 3 greater than signs
- To exit: Ctrl-D in IDLE

print 'Hello World!'
print ('Hello World!') print by default add new lines
or
import sys
sys.stdout.write('Hello World!\n')

# SEGMENT 2
Python:
Object-oriented programming language
Can write scripts, applications, APIs
python is good for system capabilities
History: Invented in Holland (1989-1991)
Marketing/Executive Summary
- Robust: system support, datatypes, functionality
- Simple: simpler than VB
- Modular: import features that you need db, networking
- Flexible: java Jython extend into
- Intuitive:

"Batteries Included"
- Standard library provides core functionality

Execution Style
- Interpreted but byte-compiled ( python is interpreted but byte-compiled for performance )
like jave it also byte-compiled, if the source code is not edited it will execute the byte-compiled code directly which makes it little faster
simple arthimetic 5+4*8 = 37
2***3 = 8
s = ' python '
t = ' is cool '
s +' ' + t
python is cool
s * 2
pythonpython
s[0]= p, s[1]=y, s[-1]=n, s[3:6]='hon'
data = [43,'foo', 3.14]
data.append('bar')
data
o/p: [43, 'foo', 3.140000, 'bar']
str(data[2])
'3.14'

# Dictionary is a hash table, key followed by the value
d = {'title': 'Python Fundamental'}
d['year'] = 2009
d
o/p: {'year': 2009, 'title': 'Python Fundamentals'}
for item in data:
print item
42
foo
3.14
bar
for k in d:
print 'key:', k, 'value:', d[k]

Key: year Value: 2009
Key: title Value: Python Fundamentals
i =0
while i 5:
print i
i += 1
0
1
2
3
4
print i
5
if i == 5:
print 'i is equal to five'
i is equal to five
# Files
f = open(r'c:\windows\temp\test.txt','w')
f.write('line 1\n')
f.close()
f = open(r'c:\windows\temp\test.txt', 'r')
for line in f:
print line, # print (line, end='')
line 1
f.close()

# Functions
def foo(x):

- Use '#' to start a comment
- One statement per line
Unless semicolon(;)
- Code blocks delimited by indentation (white space)
- Use '\' to break up long lines

Block Delimitation
# foo() displays & logs its argument
def foo(x):
print "argument is ", x
f = open('log.txt','w')
if isinstance(x, str):
f.write('%s\n' %x)
else:
f.write('%s\n' % str(x))
f.close()
Statements
- simple statements fit on one line
There is no code block following e.g. print
- Compound statements have code block
First line called a header
Indented sub-block of code called a suite
Header plus ':' followed by indented suite
Indentation allows any whitespace
Use spaces not TABs E.g. TAB in Unix platform is 8 spaces whereas in Windows platform 4 characters
Recommended indentation is 4 white spaces
Use same # of spaces for each line

Syntax Elements
# Process weather check on multiple cities
checked = 0 # number of cities checked
cities = ('x','y','z','a',
'b','c')
for city in cities:
condition, wind, temp = get_weather(city)
print "Temp:", temp; checked += 1
if condition == WINDY and wind 10 \
and temp 45:
send_surfing_alert(city)

#SEGMENT 4
- Variables and Assignment
Dynamic Typing... variables not declared
- Type inferred on assignment
- var = expression

Flexible assignment syntax
- var1 = var2 = expression
- var1, var2 = expr1, expr2

Assignment operators
- primary assignment operator: =
- Augmented assignment
+=, *=, ...
- No increment/decrement
++, -- are not permitted instead we have to use += , -=

Identifier Rules
Similar to other languages
- First Character must be alphabetic
- Any others can be alphanumeric
Treat underscores (_) as alphabetic
Case-sensitive: "None" is not "none"

Style
- Variable naming guidelines
similar to other languages
- Names longer than 1 character
- Normal data in lowercase
- Class names should be Titlecases e.g. First letter should be Capital - India,Ganga
- Constants should be in CAPs
Python Gotchas
- Special names begin/end with underscores
- Do not use built-in function/data names
- Reserved words, or keywords, can't be used

Python Keywords
and,as,assert,break,class,continue,def,del,elif,else,except,exec,finally,for,from,global,finally,for,from,global,if,import,in,is,lambda,nonlocal,not,or
pass,print,raise,return,try,while,with,yield
Constants: True, False

Built-In's
def: A _____ is a special predefined(pre-build) python interpreter identifier
Built-ins are either data attributes or functions - usually the latter

Common Build-ins
Some useful built-in functions:
-informational:
dir(), help(), type() - These all will give the information about the objects
-Operational:
int(){conversion to int}, str(), range(). raw_input(), input()

#SEGMENT 5
Function Syntax
Introducing Functions
- Declared using def keyword:
def func_name ([arg1[,arg2[,...argn]...]):
func_body
def add2tome (number):
return number + 2

Functions
- Declarations:
Header line and at least one for body
Can have any number of arguments
- If no value explicitly returned...
Python returns None
None: Python's NULL or void
None: constant Boolean False

Importing & Modules
What is Importing?
Allows use of outside code
In other words to bring in the functionality, suck in some functionality into ur code.
What are Modules?
- Self-contained Python code // plug and play methodology like database import database modules things like that.
- Bring in new functionality/objects
- Import only features that you need

Import Syntax
Two different ways to access module attributes
- Use module elements with name
import os
os.getcwd() // call procedure os module followed by getcwd function
'/tmp'

- Can import individual elements into 'namespace'
from os import getcwd
getcwd() // We can call directly its just like a variable
'/tmp'

#SEGMENT 6
Keyboard Input
- How to get keyword input from user
Use python's raw_input() function
Renamed to input()
Syntax
var = raw_input(prompt)
Example
name = raw_input('Enter name: ')
Enter name: Gyani Pillala
name
'Gyani Pillala

#SEGMENT 7
400a
Introduce standard data types
- Numbers
- Sequences - Starting with index0
- Hashing - Starting with hashing key-value pair

#Standard Types

Standard Types: Numbers, Strings, Lists, Tuples, Dictionaries, Sets
Other Types: None, Funtions and Methods, Modules, Types/Classes, Iterators

Boolean Values
- Every object has an intrinsic boolean value
- Any numeric zero or empty container is False
False bool " " str
0 int [] list
0L long () tuple
0.0 float {} dict
0.0+0.0j complex None None
- All other values are True

Operators
- Apply to most data types
- Object Value Comparison
= = == !=
- Object Identity Comparison
is , is not
E.g. If x=some object, y=some object , if both happen to be pointing to the same object where "is " and "is not " can be compared against two
is , is not
- Boolean
not , and , or

Built-in Functions
- Apply to most data types
dir() object's attributes
help() show help text
type() object type
isinstance() check object type
cmp() compare 2 objects
str() string rep of object

#Numbers
- Integers (int)
No size limit
Decimal, hexadecimal,octal,binary
42, 0xAE, 0237/0o237, 0b1110
- Long intergers (long)
Merged with and replaced by integers
42L, 0xDEACADEEFABDE
- Floating-Point Numbers (float)
IEEE 754 double-precision
3.14, -6e2, 0.1
-1.1 == 1.100000000000000001
Bits do not like repeating fractions
Use round() + string formatting
Or use decimal.Decimal type
http://docs.python.org/tut/node16.html
Others Numbers
Other numeric types
complex (complex)
Boolean (bool)
Other numeric type modules
decimal
fractions
numbers
Numeric Operators
Arithmetic Operators
+ - * / // %(modulus) **(exponential)
// - Classic Division How it is different from normal division(/)
1/2 - The answer is 0 or 1.0/2.0 - The answer is 0.5 whereas
1//2 - The answer is 0.5 or 1.0//2.0 - The answer is 0.5
Unary Operator
+ -
Bit Operators ( int only )
& (bitwise and ) | (bitwise or) ^(Bitwise exclusive OR) (Left shift) (Right Shift) ~(Uniary Bitwise operator- compliment)

Numeric Built-ins
Factory
int() - When we call int we are creating integer object
float() -
complex() -
Note: Factory function works, Example when we pass a floating-point to interger function, the output is a interger itself but it won't change the floating
point number whereas it create a interger from the scratch. In other words the two format are still available
Not "casting" nor "conversion..."

Operational
abs() - absolute value
pow() - Exponential value
round() - round up the floating point value to significant figures
divmod() - It is a combination of division and the modulus operator. E.g. If you want to find out what is the Quotient and the Reminder we can get it
chr() - In python 3 all strings are unicode, you can pass the ascii value or unicode then it will turn u the apropriate string
data = []
if data:
print 'data has element in it'
else:
print 'data is empty'
o/p: data is empty
if len(data) 0:
print 'data has stuff in it'
else:
print 'data is empty'
o/p: data is empty
Note: In second case we are calling len function call. Whenever we have any funtion calls some kind of overload is associated with it.
In first case with boolen values itself we can do the purpose
dir(data) # This takes an object and tells more about it, different attributes of list
isinstance(data, list)
True
isinstance(data, int)
False
type(data)
type 'list'
1 + 2 = 3, 5 % 2 = 1, 2 ** 3 = 8, 9 ** 0.5 = 3.0, 1 / 2 = 0, 1.0/2 = 0.5, 1.0/2.0=0.5, 1.0//2.0 = 0.0
int(3.4) = 3, float(1)=1.0, round(1.185, 2) = 1.18999, '%.2f' %round(1.185, 2) = '1.19', str(round(1.185,2)) = '1.19'

#Sequences
Strings(str,unicode) # Python 2
Bytes(bytes,bytearray)
Lists(list)
Tuples(tuple)
Sequences are ...
- Array-like collections/containers
- Heterogeneous(except strings)
- Accessed by index ( starts at 0 )
Accessing the sequence elements phenomenon are called slicing
Access element(s) by "slicing"
Single-elements slice: seq[i]
Return item i for sequence seq
Where 0 = i len(seq)
Negative indices also allowed, so:
--len(seq) = i len(seq) Note: If you mention -1, it is the last element of the array

Slicing Example
S = " p y t h o n "
0 1 2 3 4 5
-6 -5 -4 -3 -2 -1
String example above
Works for all sequence types
s[2]=t, s[0]=p, s[-2]=o, s[len(s)]=Error

Multi-Element Slicing
-Access multiple element(s) with ":"
Syntax: seq[i:j]
-From i up to but not including j
Missing indices also allowed
-Means from beginning or to end
S = " python"
s[2:5] = tho
s[3:] = hon
s[:2] = py
s[-4:-1] = tho
s[:] = python

Sequence Operators
- Membership : ( in , not in )
- Concatenation : ( + )
- Repetition/Duplication ( * )

Sequence Built-ins
- Factory
str(), list(), tuple(), unicode(), bytes(), bytearray()
- Operational
len(), max(), min()

Strings
- Line an array of characters...
No char(acter) type in Python
- Immutable, as are numbers
Value cannot be changed
- Flexible string formatting
% operator or format() method
- Triple quotes allow special chars

String demo
s = 'Python'
s * 2
'PythonPython'
s
'PythonPython'
s[1]
'y'
s[-1]
'n'
s[:4]
'pyth'
s[2:6]
'thon'
s[-4:-1]
'tho'
s[:6] + ' is cool '
'Python is cool'
'-' * 20
'----------------'
'ton' is s
False
'thon' is s
True
'thon' not in s
False
hi = '''hi
there!'''
hi
'hi\nthere!'
print hi
hi
there!

String Formatting
"Name: %s, age: %d" % ('John', 35)
'Name: John, age:35'
"Name: {0}, age: {1}".format('John',35) # Quite Flexible
'Name: John, age:35'
d = { 'user': 'wes', 'page': 42 }
'http://web/%(user)s/%(page)d.html' %d
'http://web/wes/42.html'
'http://web/{user}/{page}.html'.format(**d)
'http://web/wes/42.html'

String Methods
- Built-in String Method Sampler
split() split on delimiter to list e.g. pass in the delimiter will split, password file delimiter (:)
join() join list with delimiter e.g. pass lists of substing will give new string
find() substring search
strip() remove leading/trailing WS // remove at the begin and end
lower() lowercased version of string
replace() search and replace (not RE)
ljust() create left-justified string

Demo
s = 'Python is cool.'
s
'Python is cool.'
s.find('is not')
-1
s.find('is')
7
s.rfind('o')
12
s.center(25)
' Python is cool. '
s.center(25).strip()
'Python is cool.'
s.split()
['Python', 'is', 'cool.']
'::'.join(s.split())
'Python::is::cool.'
'.'.join(reversed(s.split()))
'cool..is.Python'
s.title()
'Python Is Cool.'
s.upper()
'PYTHON IS COOL.'
s.title().swapcase()
'pYTHON iS cOOL.'
s.isalpha() # It chech the entrie string is all about alphabetic but in our case it has space and fullstop
False
s.endswith('.')
True
s.replace('.','!')
'Python is cool!'

String Miscellany
- Operators and Operational Built-in Functions
raw_input() user input
ord() ASCII/Unicode value
r'c:\tmp\new' raw string # Message to the Interpreter don't do any special conversions like \t tab or \n new line
u'n\xe9' Unicode string
b'n\xc3\xa9' bytes string

Strings and Bytes
- Unicode default string type in 3
- Introduce byte types for 8-bit chars
2. x 3.x Mutalbe
str("") bytes(b"") no
unicode(u"") str("") no
N/A bytearray yes

Lists and Tuples
- Ordered heterogeneous containers
- Lists
Mutable, resizable
Feature many helper methods
- Tuples
Immutable
Transport data to/from functions
Not truly meant for user manipulation

List Methods
- Built-in Methods
append() add object to end
insert() add object anywhere
remove(), pop() delete objects
reverse() reverse in-place
sort() sort in-place
extend() merge another list
*count() number of occurrences
*index() first index of value

Demo
m = ['core', 'programming',9,2007]
m
['core', 'programming', 9 2006 ]
m.append('prentice Hall')
m
['core', 'Programming', 9, 2007, 'prentice Hall']
m.insert(1,'pytho')
m
['core', 'Pytho', 'Programming', 9, 2006, 'Prentice Hall']
2006 in m
True
m.pop(3)
9
m
['core','python','programming',2006,'prentice hall']
m[2:4] = ['Fundamentals', 2008 ]
m
['core','python','Fundamentals', 2008, 'Prentice Hall']
m.remove('core')
m
['Python','Fundamentals',2008, 'Prentice Hall']
m.remove('c')
error

List Comprehensions
- Lists:
Highly-used data type
Most common operations:
choose elements that fit criteria
Apply function to each element
- List Comprehensions("listcomps")
construct lists using logic
Basic syntax:
[ expr for var in iterable ]

Demo
range(10)
[0,1,2,3,4,5,6,7,8,9]
[ i for i in range(10)]
[0,1,2,3,4,5,6,7,8,9]
[i for i in range(10) if i%2 ==0]
[0,2,4,6,8]
[i*3 for i in range(10) if i%2 ==0]
[0,6,12,18,24]
[i//3 for i in range(10) if i % 2 == 0]
[0,0,1,2,2]

- Generator Expressions
List Comprehensions
Not as efficient with memory
Entire list must be created
Generator Expressions
Alternative to list comprehensions
"Generate" Successive values
Nearly identical basic sytax
- (expr for var in iterable )

Hashing Types
- Dictionaries (dict)
- Mutable Sets (set)
- Immutable Sets ( frozenset )

- Hashed collection/container objects
- Accessed by iterator ( or key for dicts )
- Heterogeneous
- Unordered by definition

Dictionaries
- Python's only mapping type
Map keys to values
Mutable, resizable hash tables
- Heterogeneous
Values are arbitrary Python Objects
- Keys are scalar ( must be hashable )
Strings, numbers, etc
- No( key ) collisions allowed

Dictionary Methods
Common Built-in Methods
get() get value given key
update() merge another dict
setdefault() return value, set if nec
pop() remove & return value
items() all key-value pairs
clear() clear dictionary
fromkeys() make new dict w/keys

Dictionary Operations
General Usage
- Number of key-value pairs:
len()
- Key membership:
if k in d: # or not in
- Loop through all keys:
for k in d:
Hashing works pretty faster than the normal list

Demo
d = { 'title': ' Core Python Programming'}
d
{ 'year': 2006, 'title': 'Core Python Programming'}
'year' in d
True
'pub' in d
False
d['title']
'Core Python Programming'
d['pub']
Error, Boc the key pub is not existing
d. get ('pub', 'N/A')
'N/A'
d.setdefault('pub', 'prentice Hall')
'Prentice Hall'
d
{ 'year': 2006, 'pub': "Prentice Hall', 'title': "Core Python Programming'}
d['pub']
'Prentice Hall'
for k in d:
print k.ljust(8), d[k]

year 2006
pub Prentice Hall
title Core Python Programming

for k, v in d.items():
print k.ljust(8), v

year 2006
pub Prentice Hall
title Core Python programming
d.items()
[('year', 2006), ('pub', 'Prentice Hall'), ('title', 'Core PYthon Programming')]
d.iteritems() # Belongs to python 3
dictionary-itemiterator object at 0x11abfa0

Sets and Frozensets
- def: a set is a finite collection of objects
- Mutable(set) or immutable (frozenset)
- No key-value pairs, just values
- Unordered and heterogeneous
- Hashed, like dictionary keys
- No collisions means no duplicates
- Remember Venn diagrams ?

Sets Avoids the same numbers repetition
Demo
a = [1, 4, 6, 3]
b = (9, 5, 2, 7, 5, 3)
a, b
([1, 4, 6, 3], (9, 5, 2, 7, 5, 3))
c = set(a)
d = set(b)
c
set ([1, 3, 4, 6])
d
set ([9, 2, 3, 5, 7])
c.intersection(d)
set([3])
c & d # Intersection
set([3])
c | d # Union of C and D
set([1, 2, 3, 4, 5, 6, 7, 9])
c |= d # Assigning the value of C and D
c
set([1, 2, 3, 4, 5, 6, 7, 9])
c.add(8)
c
set ([1, 2, 3, 4, 5, 6, 7, 8, 9])
c - d # Substract the value from the set
set ([8, 1, 4, 6])

# Set Operations
- in,not in, =, =, &, |, -, ^
- for: len().max(),min()
- Augmented assignments (&=, etc )
- Set Literals {1, ...} ({} is empty dict)
- Set comprehensions { x for x in...}

= All set types have methods
- Only sets can be modified

We gave you very high level overview
Picked up some hands on work

#Summary
- Overview of standard Data types
- Operations & built-in/factory functions
- Usage examples
Next: Objects and Memory Model

#Objects and Memory Model
Objects and Memory Model

- Introducing object references
- Tracking the reference count
- Categorizing the standard types

Python manages the memory with object references... reference count
object are the primary abstraction in python


#Objects

- def: each unit of data or logic in Python is an object, the primary abstraction
All objects will be having 3 attributes mandatory

- Attributes that all objects have
- Identity
- Type
- Value
- All read-only except perhaps value
There is no way we can change the objects Identity and Type

Objects are tagged with garbage collection , when the reference count goes to 0... That basically help python manages memory

# References
- Objects created when requested/needed and (generally*) assigned as a reference
- Variables merely references to objects
- References also called aliases
- Memory management: reference count
- Count in/decrements based on usage
- Objects GC'd when "refcount" goes to 0

# More on References
x = 1
y = x
x === 1 === y
Both are looking/referencing at single object
Objects are most important thing, variables are just referencing...

- Variables...
- Don't "hold" data per se
- Just names that "point" to objects
- Can create additional aliases to objects
- Be aware of cyclic references
It's really not a problem b'cos python will be having inbuilt references manager, but keep in mind when u create a complex program object relationship

#Refcount Increment

- Object's reference count incremented when:
- It ( the object ) is created ( and assigned )
foo = 'Python is cool!'
- Additional aliases for it are created
bar = foo
- Passed to a function ( new local reference )
spam (foo) # function local variable will be pointing..
- Becomes part of a container object
lotsaFoos = [123, foo, 'xyz']

# Refcount Decrement
- Object's reference count decremented when:
- A local reference goes out-of-scope
i.e. when spam() ends
- Alias explicitly destroyed
del bar # or del foo
- Alias reassigned to different objects
bar = 42
- Object removed from container/collection
lotsaFoos.remove(foo)
- Container itself is deallocated
del lotsaFoos # or out-of-scope

#Categorizing Types
- Why categorize the standard types ?
- Make you learn them faster
- Have you understand them better
- Be able to "see" how they work internally
- Encourage more proficient programming
- Three Models
- Storage
- Update
- Access

# Storage Model
- How data is stored in an object
- Can it hold single or multiple objects ?

Model Category Standard Type(s)

literal/scalar numbers, strings
container lists,tuples, dicts, sets

English keywords
This is not like rocket science
That's all i wanted to say in the storage model
I am just trying to put myself into your shoes

Sets:
mutable sets : sets
Immutable sets : frozen sets

# Update Model
- Can an object's value be updated?
- Mutable == yes and immutable == no
- There is one of each set type
- The 'bytearray' type is mutable

Model Category Standard Type(s)

mutable lists, dicts
immutable numbers, strings, tuples

# Access Model
- How data is accessed in an object
- Directly, via index, or by key
- Primary model for type differentiation

Model Category Standard Type(s)

direct numbers, sets
sequence strings,lists,tuples
mappings dicts

# Combining All Models
Data Type Storage Model Update Model Access Model

numbers literal/scalar immutable direct
strings literal/scalar mutable sequence
lists container mutable sequence
tuples container immutable sequence
dicts container mutable mapping
sets(Two types ) container im/mutable direct

# Interning of Objects
- Exception to the general rule
- Some strings and integers are "interned"
- Integers in range (-5, 257 ) [ currently ]
- Oft-used, single-character, or empty strings
- Primarily for performance reasons

x = 4
y = 4
x == 4 == y
x = 4.3
y = 4.3
x == 4.3
y == 4.3

#What is the output here ( and WHY )?

x = ['foo', [1,2,3], 1.2 ]
y = list(x) # copy x; or x[:]

y[1][0] = 4
print x
print y

# Explanation
- Create list object x
- Make a copy and assign to y
- Use y to reference & change value

x = ['foo',[1,2,3], 1.2 ]
y = x[:]
y[1][0] = 4
print x
print y

x == ['foo', [1,2,3], 1.2 ]
y == ['foo', [1,2,3], 1.2 ]


#Answer
Unfortunately we get 4 2 3 in both cases
We just copied the references

x [ , , ] === [ 'foo', [4,2,3], 1.2 ] === y [ , , ]

Both x and y are looking at the same list, that why the data change in the list effected both the objects x & y

#Copied References
- You did copy the list, but you also
- Copied its references and changed one that is mutable (objs not copied )

" Shallow copy " -- It just copies the references it won't copy the objects

English
That is the punch line here
you swear the code is correct, but still it's not working the way you wanted it to work

# Copying Objects
- Always tricker with mutable objects
- Let's copy a list x as list y:
- Creates an alias not a copy
y = x # Conditions Checking ... - x == y and x is y ( It gives True )

- Create a shallow copy ( Copies the references ... )
y = x[:] # Condition Checking .. x == y but x is not y

- Create a deep copy ( Copies the objects ... ) [ both x and y no longer points to the same objects ]
y = copy.deepcopy(x)

## Summary
# References and "Refcounting"
# Storage, Update, & Access Models
# Interning and Copying Objects
# Eye-Opening Quizzes
# Eye-opening Quizzes
# Next: Loops and Conditionals

# Loops and Conditionals
- Syntax Considerations
- Conditional Statements
- Looping Mechanisms
- Loop "Helpers"

#Syntax Considerations
- Code delimitation by indentation
- Code blocks called "suites"
- Indentation must be consistent
- Try to use only spaces (no TABs )
- First "dedented" line not part of block
- Major players likely to be "compound"
- Helpers either BIFs or "simple" statements

# if Statement
- Conditionally execute code
- Parentheses not required

Syntax:
if conditional expression:
# If true, execute this suite
# now outside of it clause

- Example:
if i 100:
print "greater then 100"
print "always see output here "

English :
If you have experience in other programming languages, it should be fairly straight forward.

# if-else Statement
- else used with if for opposing condition

- Example:
if i 100:
print " Greater than 100"
else:
print " Less than or Equal to 100"
print "Execution Resumes Here "

# if-elif-else
- Python's "else-if" spelled elif
- Example:
# prompt, get, and check input
data = raw_input("Enter 'y' or 'n' :") # python 2
data = input("Enter 'y' or 'n' :") # python 3

if data[0] == 'y' :
print "You typed 'y'." # 'y' key
elif data[0] == 'n':
print "You typed 'n'." # 'n' Key
else:
print 'Invalid key!' # other key

Note:
python 3 , the print turning out into function...
It's mandatory that the string should be in double quotes

Demo
def demo():
data = raw_input('Enter "y" or "n": ').stip() or .lower()
if data[0].lower() == 'y': or if data[0] == 'y' or data[0] == 'n':
print 'you typed "y"'
elif data[0] == 'n':
print "you typed "n"'
elif data == 'gooj':
print "you got out of jail free.'
else:
print 'You entered invalid key.'
demo()
Enter "y" or "n": YES
You typed "Y"
demo()

# Ternary Operator
- Ternary operator aka conditional expression
- Syntax in other languages:
C ? T : F

- In python:
- 2.5+: T if C else F
- 2.5: (C and [T] or [F]) [0]
- Example:
x, y = 1, 2
max_xy = x if x y else y
max_xy

# Looping Mechanisms

- def: a_ executes a block of code...
- For a specific number of times
- Iterates over a (not nec. finite) dataset, or
- Until a condition is no longer satisfied
- Looping Statements
- Primarily used to iterate over data(for)
- Primarily used as a counting loop (while)
- Helpers
- Built-in Functions (BIFs)
- Auxiliary (simple) statements

# for Loops
- The python for loop is its most powerful
- The most commonly-used Python loop
- It traverses an "iterable," setting the loop variable to each successive value
- Syntax:
for variable in iterable:
# body of loop (suite)

# Iterables
- def: an iterable is any data structure that supports simple element traversal
- Sequence (strings, lists, tuples )
- Sequence-like objects:
- Iterators, lines of a file, keys of a dictionary, generators, sets, etc.

# range() Built-in
- range(): helper for Python for loops
- Python for more like shell foreach
- Iterating rather than traditional counting
- range() morphs counting into iterating
- range() returns list (2.x) or iterator (3.x)

- Full and Short Syntax (int arguments):
range(start, end[, step])
range([start,] end )

Demo
my_str = 'Python is cool.'
my_list = [3.14,'foo',42]

for c in my_str:
print c
print (c) # python 3
p
y
t
h
o
.... # It just prints character by character
for item in my_list:
print item
3.14
foo
42

for i in range(1, 10):
print i
1
2
3
4
... # prints upto 9

English:
This is just a very high level overview

for i in range(1, 10, 2):
print i
1
3
5
7
9
range(1, 10 )
[1,2,3,....9]

# More on range()
- Examples:
range(5) [0,1,2,3,4]
range(6, 9) [6,7, 8]
range(2, 12, 3) [2,5,8,11]

- 2.x: use xrange() to get iterator version
- Lazier, more memory-friendly
- Raplaces and renamed as range() in 3.x
- range() lets for loops iterate over index:
for i in range(len(data)):
print data[i]

# Item or Index
music = ('Poe', 'Gaudi', 'Freud')
for i in range(len(music)):
print 'album %d: %s' %(i, music[i])

album 0: Poe
album 1: Gaudi
album 2: Freud

- In the above, we iterate by index
- We can also iterate by item/element as usual:
- for album in music: print album
- But there is no access to the index above:
sometimes we want bothe the item and the index

# enumerate() Built-in
- enumerate(): another helper for Python for loops
- Returns a special-purpose iterator
- Iterator emits both index and item!!!
- Example:
music = ('Poe', 'Gaudi', 'Freud')
for i, album in enumerate(music):
print 'album %d: %s' % (i, album)

album 0: Poe
album 1: Gaudi
album 2: Freud

# while Loops
- while loops are conditionals, like a looping if
- Suite executed until condition no longer satisfied
- Suite not executed if condition was never True
- Test performed before each loop interation
- Common use cases:
- A counting loop
- An infinite loop
- Syntax:
while conditional_expression:
# body of loop

Demo
while i 5:
print i
i += 1
0
1.... # prints till 4

# Infinite while loop
not_done = True
while not_done:
# Some block of code to do something
# when finished hopefully call "break"
break
range and enumerate are built-in functions

# break statement
- break terminates a loop, regardless of conditional

- Syntax:
# inside the body of a loop
break
- Example:
while True: # infinite loop
:
if error: # break out of loop
break

# continue statement
- continue terminates current loop iteration
- It does not necessarily start the next loop
- Syntax:
# inside the body of a loop
continue

- Example:
while Ture: # infinite loop
:
if skip_reminder: # skip rest of loop
continue
# code which may be skipped

# pass statement ( Python specific )
- pass performs no action
- Python's "no operation" (NOP) statement
- Used when statement required syntactically
- Good as placeholder for code to be written
- Syntax:
# inside my suite
pass

- Example:
class NetworkError(IOError):
pass

# else Statement
- else can also be used for loops
- Unique compared to other lanugages
- Executed if loop not broken out of

- Syntax:
loop: #While or for
suite1 # normal loop block
else:
suite2 # only w/o break

# Loop else Example
- Prime numbers and the search for a divisor:

value = int(raw_input("Enter #: "))
counter = int(value ** 0.5) # sq root

while counter 1: # stop at 2
if value % counter == 0:
print(value, "is composite")
break
counter -= 1
else:
print (value, " is prime ")

# Summary
- Review indentation as delimitation
- Introduce family of if statements
- Python's Looping Types: for and while
- Define iterables
- Explore roles of loop helpers
- Next Lesson: Files and Input/Output

No comments: