Python Training at Arcesium - Day 2

Oct 25-27, 2017 Vikrant Patil

These notes are available online at http://notes.pipal.in/2017/arcesium-oct-python/day2.html

© Pipal Academy LLP

Day 1 | Day 2 | Day 3

while loop

In [1]:
def print_fibonacci(n):
    """
    print fibonacci numbers less than using while loop
    """
    prev, current = 1, 1
    
    while current < n:
        prev, current = current, prev + current
        print(prev, end=",")
In [2]:
print_fibonacci(1000)
1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,

for loop

for loops in python are different as compared c/java. for loop in python gives you handle to iterate over collection

In [3]:
names = ["Elsa", "David", "Mahesh", "Hari"]
for person in names:
    print("hello", person)
hello Elsa
hello David
hello Mahesh
hello Hari
In [4]:
for f in [1,2,3,5,8,13,21,34,55,89,144,233,377,610,987]:
    print(f, end=",")
1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,
In [5]:
for c in "This is a sentence to demo for loop":
    print(c, end=",")
T,h,i,s, ,i,s, ,a, ,s,e,n,t,e,n,c,e, ,t,o, ,d,e,m,o, ,f,o,r, ,l,o,o,p,
In [6]:
for word in "This sentence is to demo words in for loop".split():
    print(word, end=",")
This,sentence,is,to,demo,words,in,for,loop,
In [7]:
range(5)
Out[7]:
range(0, 5)
In [8]:
for num in range(5):
    print(num, end=",")
0,1,2,3,4,
In [9]:
for num in range(2, 10, 2): #range(start, end, step)
    print(num, end=",")
2,4,6,8,

problem

  • Write a python script ls.py to list files in current directory.
    python ls.py
    day1.html
    .
    .
  • Write a function mysum that sums up elements from a list
>>> mysum([1,1,1,1])
4
  • Write a function product that computes product of all numbers from a list
    >>> product([1,2,3,4])
    24
  • Write a function to compute factorial of a number
In [14]:
%%file ls.py
import os

def ls(location):
    for file in os.listdir(location):
        print(file)
        
if __name__ == "__main__":
    ls(os.getcwd())
    
Overwriting ls.py
In [15]:
!python ls.py
.ipynb_checkpoints
mymodule1.py
push
day1.ipynb
rectangle.py
main.py
mymodule3.py
Untitled.ipynb
day2.ipynb
echo.py
day2.html
Untitled.html
square.py
mymodule.py
circle.py
day3.ipynb
mymodule2.py
day3.html
Makefile
__pycache__
add.py
day1.html
ls.py
In [17]:
from ls import ls
In [19]:
ls(".")
.ipynb_checkpoints
mymodule1.py
push
day1.ipynb
rectangle.py
main.py
mymodule3.py
Untitled.ipynb
day2.ipynb
echo.py
day2.html
Untitled.html
square.py
mymodule.py
circle.py
day3.ipynb
mymodule2.py
day3.html
Makefile
__pycache__
add.py
day1.html
ls.py
In [22]:
def mysum(numbers):
    s = 0
    for num in numbers:
        s += num 
    return s

def product(numbers):
    p = 1
    for num in numbers:
        p = p *num
    return p

def factorial(n):
    return product(range(1,n+1))
In [23]:
mysum(range(10))
Out[23]:
45
In [24]:
factorial(4)
Out[24]:
24

There is break statement, which stops at current iteration and breaks from loop. There is also optional else block for for loop which is to be used with break statement.

In [25]:
def print_primes(n):
    """
    prints prime numbers less than n 
    """
    
    for i in range(2, n):
        for j in range(2, i):
            if i%j==0:
                break
        else:
            print(i, end=",")
In [26]:
print_primes(100)
2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,
In [27]:
list(range(2,2))
Out[27]:
[]
In [28]:
list(range(2,3))
Out[28]:
[2]
In [29]:
list(range(2,4))
Out[29]:
[2, 3]
In [35]:
def prime_fibonacci(n):
    """
    prints fibonacci less than n but are also prime
    """
    prev, current = 1, 2
    while prev < n:
        for i in range(2, prev):
            if prev%i==0:
                break
        else:
            print(prev, end=",")
        
        prev, current = current, prev+current
In [36]:
prime_fibonacci(50)
1,2,3,5,13,

Recap List methods

In [37]:
numbers = list(range(10))
In [38]:
numbers
Out[38]:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In [39]:
numbers.append(11)
In [40]:
numbers
Out[40]:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11]
In [41]:
numbers.insert(0, -1)
In [42]:
numbers
Out[42]:
[-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11]
In [43]:
numbers.pop()
Out[43]:
11
In [44]:
numbers.pop(0)
Out[44]:
-1
In [45]:
emptylist = []

problem

  • write a function square which takes a list of numbers as argument and returns a new list with squared numbers
    >>> square([1,2,3.4])
    [1,4,9,16]
  • write a function evens to find out even numbers from a given list
    >>> evens([1,2,3,4,5,6,7])
    [2,4,6]
In [46]:
def square(numbers):
    s = []
    for num in numbers:
        s.append(num*num)
    return s

def evens(numbers):
    def even(n):
        return not n%2
    
    e = []
    for num in numbers:
        if even(num):
            e.append(num)
    return e
In [47]:
evens(range(10))
Out[47]:
[0, 2, 4, 6, 8]

List slicing

In [48]:
digits = list(range(10))
In [49]:
digits
Out[49]:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In [50]:
digits[1:6] #new list from index 1(included) to index 6(exluded)
Out[50]:
[1, 2, 3, 4, 5]
In [51]:
digits[2:5]
Out[51]:
[2, 3, 4]
In [52]:
digits[1:]#list containing itesm from index 1 till end
Out[52]:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
In [53]:
digits[:4] #from start till index 4(exlcuded)
Out[53]:
[0, 1, 2, 3]
In [54]:
digits[4:] #from index 4 till end
Out[54]:
[4, 5, 6, 7, 8, 9]
In [55]:
digits[-1]
Out[55]:
9
In [56]:
digits[:-1] # all elements except last
Out[56]:
[0, 1, 2, 3, 4, 5, 6, 7, 8]
In [57]:
digits[:] # all ..copy
Out[57]:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In [58]:
digits[2:7:2]
Out[58]:
[2, 4, 6]
In [59]:
digits[::-1] # reverse
Out[59]:
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
In [60]:
word = "madam"
In [62]:
word == word[::-1]
Out[62]:
True
In [63]:
is_palindrom = lambda word: word==word[::-1]
In [64]:
is_palindrom
Out[64]:
<function __main__.<lambda>>
In [65]:
is_palindrom("civic")
Out[65]:
True

problems

  • Write a function split_at which splits given list in two lists. First list is items from start till the index and second list is items from index till end of list.
    >>> split_at([0,1,2,3,4,5,6,7,8], 2)
    ([0,1], [2,3,4,5,6,7,8])
  • write a function find_extension to find extension of a file, given file name.
    >>> find_extension("python.exe")
    exe
  • what might be output of this?
    >>> s = "Do geese see God?"
    >>> s[100]
    >>> s[3:100]
In [67]:
def split_at(items, index):
    return intems[:index], items[index:]

def find_extension(filename):
    return filename.split(".")[-1]
In [68]:
s = "Do geese see God?"
In [69]:
s[100]
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-69-4868bd16d438> in <module>()
----> 1 s[100]

IndexError: string index out of range
In [70]:
s[3:100]
Out[70]:
'geese see God?'

list comprehensions

In [71]:
sq = []
for n in [1,2,3,4]:
    sq.append(n*n)
print(sq)
[1, 4, 9, 16]
In [72]:
numbers = range(10)
In [73]:
print(numbers)
range(0, 10)
In [74]:
nums = [n for n in numbers]
In [75]:
nums
Out[75]:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In [76]:
squares = [n*n for n in numbers]
In [77]:
[n*n*n for n in numbers]
Out[77]:
[0, 1, 8, 27, 64, 125, 216, 343, 512, 729]
In [78]:
[factorial(n) for n in numbers]
Out[78]:
[1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880]
In [79]:
[word.upper() for word in ["these", "are", "few", "words"]]
Out[79]:
['THESE', 'ARE', 'FEW', 'WORDS']
In [80]:
words = ["Some", "sentence", "that", "contains", "some", "s"]
[word for word in words if word.lower().startswith("s")]
Out[80]:
['Some', 'sentence', 'some', 's']
In [82]:
[i for i in range(20) if i%2==0]
Out[82]:
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

problems

  • Write a function listpy which will return list all ".py" files from given directory
    >>> listpy(os.getcwd())
    ['add.py', 'module.py', 'main.py'...]
  • Write a function factors which will return list of factors of a given integer including 1 and self.
    >>> factors(10)
    [1,2,,5,10]
  • Given that prime number has only two factors 1 and self, write a function is_prime which determines if given number is prime or not
    >>> is_prime(23)
    True
  • Now using list comprehensions can you write a function that generates prime numbers less than or equal to n
    >>> primes(23)
    [2,3,5,7,11,13,19,23]
In [92]:
import os
def listpy(dirpath):
    files = os.listdir(dirpath)
    return [file for file in files if file.endswith(".py")]

def factors(n):
    return [i for i in range(1, n+1) if n%i ==0]

is_prime = lambda n: factors(n)==[1,n]

def primes(n):
    return [p for p in range(2,n+1) if is_prime(p)]
In [93]:
listpy(os.getcwd())
Out[93]:
['mymodule1.py',
 'rectangle.py',
 'main.py',
 'mymodule3.py',
 'echo.py',
 'square.py',
 'mymodule.py',
 'circle.py',
 'mymodule2.py',
 'add.py',
 'ls.py']
In [94]:
factors(13)
Out[94]:
[1, 13]
In [95]:
is_prime(13)
Out[95]:
True
In [97]:
primes(50)
Out[97]:
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]
In [98]:
[[i*j for i in range(1,11)] for j in range(1, 6)]
Out[98]:
[[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
 [2, 4, 6, 8, 10, 12, 14, 16, 18, 20],
 [3, 6, 9, 12, 15, 18, 21, 24, 27, 30],
 [4, 8, 12, 16, 20, 24, 28, 32, 36, 40],
 [5, 10, 15, 20, 25, 30, 35, 40, 45, 50]]

Can you generate unit matrix of dimension 5x5 which has only diagonal element as 1 , other lements are 0..using list comprehension

In [99]:
def f(x,y):
    if x==y:
        return 1
    else:
        return 0
[[f(i,j) for i in range(5)] for j in range(5)]
Out[99]:
[[1, 0, 0, 0, 0],
 [0, 1, 0, 0, 0],
 [0, 0, 1, 0, 0],
 [0, 0, 0, 1, 0],
 [0, 0, 0, 0, 1]]
In [100]:
[[1 if i==j else 0 for i in range(5)] for j in range(5)]
Out[100]:
[[1, 0, 0, 0, 0],
 [0, 1, 0, 0, 0],
 [0, 0, 1, 0, 0],
 [0, 0, 0, 1, 0],
 [0, 0, 0, 0, 1]]
In [101]:
x = 2
y = 3
In [102]:
a = 5 if x==y else 4
In [103]:
a
Out[103]:
4

Iteration patterns

Iterating over a list/string/sequence

In [104]:
for prime in primes(23):
    print(prime, end=",")
2,3,5,7,11,13,17,19,23,
In [105]:
for prime in reversed(primes(23)):
    print(prime, end=",")
23,19,17,13,11,7,5,3,2,
In [106]:
countdown = reversed(list(range(10)))
In [107]:
countdown
Out[107]:
<list_reverseiterator at 0x7f95ec0acf98>

Iterating with index and item

In [108]:
primenums = primes(23)
for i, item in enumerate(primenums):
    print(i, item)
0 2
1 3
2 5
3 7
4 11
5 13
6 17
7 19
8 23

iterating over two lists together

In [109]:
names = ["Elsa", "Alisa", "Exotica", "Beauty"]
surnames = ["Frozen", "Hacker", "Logica", "Nurd"]
for name, surname in zip(names, surnames):
    print(name, surname)
Elsa Frozen
Alisa Hacker
Exotica Logica
Beauty Nurd

problems

  • Write a function to do vector addition of vectors given as two lists
    >>> vector_add([1,2,3],[3,2,1])
    [4,4,4]
  • Write a function zip3 which zips 3 lists and returns a tuples of three as list
    >>> zip3([1,2,3],["one","two","three"],['x','y','z'])
    [(1,"one",'x'), (2,"two","y"), (3,"three", "z")]
In [110]:
def vector_add(vector1, vector2):
    return [x+y for x,y in zip(vector1, vector2)]
In [111]:
def zip3(first, second, third):
    return [(first[i],second[i],third[i]) for i in range(len(first))]
        
In [112]:
vector_add([1,1,1],[2,2,2])
Out[112]:
[3, 3, 3]
In [113]:
zip3([1,2,3],["one","two","three"],['x','y','z'])
Out[113]:
[(1, 'one', 'x'), (2, 'two', 'y'), (3, 'three', 'z')]

Functions revisited

  • Fucntions can be aliased
  • functions can be passed as arguments to another function
  • functions can be returned as return value from a function
In [114]:
def usual_way_polynomial(coeffs, x):
    s = 0
    for i, c in enumerate(reversed(coeffs)):
        s += c*x**i
    return s
In [115]:
usual_way_polynomial([1,1,1], 2)
Out[115]:
7
In [116]:
def make_polynomial(coeffs):
    def poly(x):
        s = 0
        for i, c in enumerate(reversed(coeffs)):
            s += c*x**i
        return s
    return poly
In [117]:
P2 = make_polynomial([1,1,1])
In [119]:
P2
Out[119]:
<function __main__.make_polynomial.<locals>.poly>
In [120]:
P2(2)
Out[120]:
7

problem

  • Write a functon compose which takes two functions f and g as argument and return a fucntion which will compute f(g(x))
    >>> f = lambda x: x**2
    >>> g = lambda x: x-1
    >>> fg = compose(f,g)
    >>> fg(3)  ## (3-1)**2
    4
    >>> gf = compose(g,f)
    >>> gf(3) # (3**2)-1
    8
  • write a function zip_with which takes function as argument, two lists as argument and returns a single list which is formed by combining items from two lists using given function
In [121]:
def compose(f,g):
    return lambda x: f(g(x))

def zip_with(f):
    return lambda first, second: [f(x,y) for x,y in zip(first, second)]
In [122]:
vector_adder = zip_with(lambda x,y: x+y)
In [123]:
vector_adder([1,1,1],[2,2,2])
Out[123]:
[3, 3, 3]
In [124]:
vector_multiplier = zip_with(lambda x,y: x*y)
In [125]:
vector_multiplier([1,1,1],[2,2,2])
Out[125]:
[2, 2, 2]

Docstrings

In [141]:
%%file functions.py
"""
module functions
this serves as long description of module functions
"""

def usual_way_polynomial(coeffs, x):
    """
    computes values of polynomial given coefficients and x
    >>> usual_way_polynomial([1,1,1], 2)
    7
    """
    s = 0
    for i, c in enumerate(reversed(coeffs)):
        s += c*x**i
    return s

def make_polynomial(coeffs):
    """
    makes a polynomial function given coefficients. the returned function can be used
    to compute value of polynomial if x is given
    >>> make_polynomial([1,1,1])(2)
    7
    """
    def poly(x):
        s = 0
        for i, c in enumerate(reversed(coeffs)):
            s += c*x**i
        return s
    return poly
Overwriting functions.py
In [137]:
!pydoc functions
Help on module functions:

NNAAMMEE
    functions

DDEESSCCRRIIPPTTIIOONN
    module functions
    this serves as long description of module functions

FFUUNNCCTTIIOONNSS
    mmaakkee__ppoollyynnoommiiaall(coeffs)
        makes a polynomial function given coefficients. the returned function can be used
        to compute value of polynomial if x is given
        >>> make_polynomial([1,1,1])(2)
        7
    
    uussuuaall__wwaayy__ppoollyynnoommiiaall(coeffs, x)
        computes values of polynomial given coefficients and x
        >>> usual_way_polynomial([1,1,1], 2)

FFIILLEE
    /home/vikrant/trainings/2017/arcesium-oct-python/functions.py


In [138]:
import functions
In [139]:
help(functions)
Help on module functions:

NAME
    functions

DESCRIPTION
    module functions
    this serves as long description of module functions

FUNCTIONS
    make_polynomial(coeffs)
        makes a polynomial function given coefficients. the returned function can be used
        to compute value of polynomial if x is given
        >>> make_polynomial([1,1,1])(2)
        7
    
    usual_way_polynomial(coeffs, x)
        computes values of polynomial given coefficients and x
        >>> usual_way_polynomial([1,1,1], 2)
        7

FILE
    /home/vikrant/trainings/2017/arcesium-oct-python/functions.py


Testing

In [140]:
!python -m doctest -v functions.py
Trying:
    make_polynomial([1,1,1])(2)
Expecting:
    7
ok
Trying:
    usual_way_polynomial([1,1,1], 2)
Expecting nothing
**********************************************************************
File "/home/vikrant/trainings/2017/arcesium-oct-python/functions.py", line 9, in functions.usual_way_polynomial
Failed example:
    usual_way_polynomial([1,1,1], 2)
Expected nothing
Got:
    7
1 items had no tests:
    functions
1 items passed all tests:
   1 tests in functions.make_polynomial
**********************************************************************
1 items had failures:
   1 of   1 in functions.usual_way_polynomial
2 tests in 3 items.
1 passed and 1 failed.
***Test Failed*** 1 failures.

py.test is a third party tool for doing testing. to install it use following command

pip3 install pytest
In [142]:
from functions import usual_way_polynomial, make_polynomial
In [144]:
if usual_way_polynomial([1,1,1],2) == 7:
    print("pass")
pass
In [146]:
assert usual_way_polynomial([1,1,1],2) == 1
---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
<ipython-input-146-f8e460313f60> in <module>()
----> 1 assert usual_way_polynomial([1,1,1],2) == 1

AssertionError: 
In [147]:
def test_polynomial():
    assert usual_way_polynomial([],2) == 0
    assert usual_way_polynomial([1,1,1],1) == 3
In [155]:
%%file function1.py
"""
module functions
this serves as long description of module functions
"""

def usual_way_polynomial(coeffs, x):
    """
    computes values of polynomial given coefficients and x
    >>> usual_way_polynomial([1,1,1], 2)
    7
    """
    s = 0
    for i, c in enumerate(reversed(coeffs)):
        s += c*x**i
    return s

def make_polynomial(coeffs):
    """
    makes a polynomial function given coefficients. the returned function can be used
    to compute value of polynomial if x is given
    >>> make_polynomial([1,1,1])(2)
    7
    """
    def poly(x):
        s = 0
        for i, c in enumerate(reversed(coeffs)):
            s += c*x**i
        return s
    return poly

def test_usual():
    assert usual_way_polynomial([1,1,1],0) == 1
    assert usual_way_polynomial([1,1,1], 2) == 7
    assert usual_way_polynomial([],0) == 0
    assert usual_way_polynomial([],2) == 3
    
def test_make_poly():
    coeff0 = []
    poly0 = make_polynomial(coeff0)
    assert poly0(1) == usual_way_polynomial(coeff0, 1)
    coeff2 = [1,1,1]
    poly2 = make_polynomial(coeff2)
    assert poly2(2) == 5
    
Overwriting function1.py
In [156]:
!py.test function1.py
============================= test session starts ==============================
platform linux -- Python 3.6.1, pytest-3.0.7, py-1.4.33, pluggy-0.4.0
rootdir: /home/vikrant/trainings/2017/arcesium-oct-python, inifile:
collected 2 items 

function1.py FF

=================================== FAILURES ===================================
__________________________________ test_usual __________________________________

    def test_usual():
        assert usual_way_polynomial([1,1,1],0) == 1
        assert usual_way_polynomial([1,1,1], 2) == 7
        assert usual_way_polynomial([],0) == 0
>       assert usual_way_polynomial([],2) == 3
E       assert 0 == 3
E        +  where 0 = usual_way_polynomial([], 2)

function1.py:35: AssertionError
________________________________ test_make_poly ________________________________

    def test_make_poly():
        coeff0 = []
        poly0 = make_polynomial(coeff0)
        assert poly0(1) == usual_way_polynomial(coeff0, 1)
        coeff2 = [1,1,1]
        poly2 = make_polynomial(coeff2)
>       assert poly2(2) == 5
E       assert 7 == 5
E        +  where 7 = <function make_polynomial.<locals>.poly at 0x7f106b5c5400>(2)

function1.py:43: AssertionError
=========================== 2 failed in 0.05 seconds ===========================

Formating strings

In [157]:
for i in range(1,11):
    print(i, i**2, i**3)
1 1 1
2 4 8
3 9 27
4 16 64
5 25 125
6 36 216
7 49 343
8 64 512
9 81 729
10 100 1000
In [158]:
for i in range(1,11):
    print(repr(i).rjust(2), repr(i*i).rjust(3), repr(i*i*i).rjust(4))
 1   1    1
 2   4    8
 3   9   27
 4  16   64
 5  25  125
 6  36  216
 7  49  343
 8  64  512
 9  81  729
10 100 1000
In [159]:
"Wizard of oz is {}".format("python")
Out[159]:
'Wizard of oz is python'
In [160]:
"wizard of {} is in {}".format("python", "oz")
Out[160]:
'wizard of python is in oz'
In [161]:
"purpose of life is {0} , my computation in {1} says so".format(42, "python")
Out[161]:
'purpose of life is 42 , my computation in python says so'
In [162]:
for i in range(1,11):
    line = "{integer:2d} {square:3d} {cube:4d}".format(integer=i, square=i**2, cube=i**3)
    print(line)
 1   1    1
 2   4    8
 3   9   27
 4  16   64
 5  25  125
 6  36  216
 7  49  343
 8  64  512
 9  81  729
10 100 1000
In [163]:
"12".zfill(4)
Out[163]:
'0012'
In [164]:
"12.24".zfill(8)
Out[164]:
'00012.24'
In [178]:
"{0:.4f} {1:.2f}".format(3.14, 1.3)
Out[178]:
'3.1400 1.30'

problem

  • Write a function pascal to generate pascal triangle of base n
    >>> pascal(3)
    [[1],[1,1],[1,2,1]]
  • Write a function print_pascal to prety print pascal triangle as shown below
    >>> print_pascal(5)
        1
       1 1
      1 2 1
     1 3 3 1
    1 4 6 4 1
In [165]:
def pascal(base):
    triangle = [[1]]
    
    for i in range(base-1):
        prev = triangle[-1]
        pre = prev[:]
        pre.insert(0, 0)
        post = prev[:]
        post.append(0)
        row = [x+y for x,y in zip(pre, post)]
        triangle.append(row)
        
    return triangle
In [166]:
pascal(3)
Out[166]:
[[1], [1, 1], [1, 2, 1]]
In [167]:
pascal(5)
Out[167]:
[[1], [1, 1], [1, 2, 1], [1, 3, 3, 1], [1, 4, 6, 4, 1]]
In [168]:
pascal(6)
Out[168]:
[[1], [1, 1], [1, 2, 1], [1, 3, 3, 1], [1, 4, 6, 4, 1], [1, 5, 10, 10, 5, 1]]
In [171]:
def print_pascal(base):
    def count_digits(n):
        return len(str(n))
    
    triangle = pascal(base)
    d = count_digits(max(triangle[-1]))#digits in biggest number
    width = d*base + base-1 #total width of triangle including spaces
    
    for row in triangle:
        line = ""
        for number in row:
            line += "{number:{spaces}} ".format(number=number, spaces=d)
        line = line.center(width)
        print(line)
In [172]:
print_pascal(12)
                        1                      
                      1   1                    
                    1   2   1                  
                  1   3   3   1                
                1   4   6   4   1              
              1   5  10  10   5   1            
            1   6  15  20  15   6   1          
          1   7  21  35  35  21   7   1        
        1   8  28  56  70  56  28   8   1      
      1   9  36  84 126 126  84  36   9   1    
    1  10  45 120 210 252 210 120  45  10   1  
  1  11  55 165 330 462 462 330 165  55  11   1 
In [173]:
import this
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!

Working with files

In [179]:
%%file three.txt
one
two
three
Writing three.txt
In [180]:
fhandle = open("three.txt")
In [181]:
fhandle.read() #complete contents of file
Out[181]:
'one\ntwo\nthree'
In [182]:
fhandle.read()
Out[182]:
''
In [183]:
fhandle.close()
In [184]:
%%file data.txt
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
Writing data.txt
In [185]:
fhandle = open("data.txt")
In [186]:
fhandle.readline()
Out[186]:
'The Zen of Python, by Tim Peters\n'
In [187]:
fhandle.readline()
Out[187]:
'\n'
In [188]:
fhandle.readlines()
Out[188]:
['Beautiful is better than ugly.\n',
 'Explicit is better than implicit.\n',
 'Simple is better than complex.\n',
 'Complex is better than complicated.\n',
 'Flat is better than nested.\n',
 'Sparse is better than dense.\n',
 'Readability counts.\n',
 "Special cases aren't special enough to break the rules.\n",
 'Although practicality beats purity.\n',
 'Errors should never pass silently.\n',
 'Unless explicitly silenced.\n',
 'In the face of ambiguity, refuse the temptation to guess.\n',
 'There should be one-- and preferably only one --obvious way to do it.\n',
 "Although that way may not be obvious at first unless you're Dutch.\n",
 'Now is better than never.\n',
 'Although never is often better than *right* now.\n',
 "If the implementation is hard to explain, it's a bad idea.\n",
 'If the implementation is easy to explain, it may be a good idea.\n',
 "Namespaces are one honking great idea -- let's do more of those!"]
In [189]:
fhandle = open("data.txt")
In [190]:
for line in fhandle.readlines():
    print(line, end="")
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
In [191]:
for i, line in enumerate(open("data.txt")):
    print(i+1, line, end="")
1 The Zen of Python, by Tim Peters
2 
3 Beautiful is better than ugly.
4 Explicit is better than implicit.
5 Simple is better than complex.
6 Complex is better than complicated.
7 Flat is better than nested.
8 Sparse is better than dense.
9 Readability counts.
10 Special cases aren't special enough to break the rules.
11 Although practicality beats purity.
12 Errors should never pass silently.
13 Unless explicitly silenced.
14 In the face of ambiguity, refuse the temptation to guess.
15 There should be one-- and preferably only one --obvious way to do it.
16 Although that way may not be obvious at first unless you're Dutch.
17 Now is better than never.
18 Although never is often better than *right* now.
19 If the implementation is hard to explain, it's a bad idea.
20 If the implementation is easy to explain, it may be a good idea.
21 Namespaces are one honking great idea -- let's do more of those!
In [192]:
for line in open("data.txt"):
    print(len(line.strip().split()))
7
0
5
5
5
5
5
5
2
9
4
5
3
10
13
12
5
8
11
13
12
  • Write a python script cat.py which is equivalent of unix command cat. it prints contents of file to standard output
    python cat.py three.txt
    one
    two
    three
  • write a python script head.py which takes number lines to be shown as first argument and filename as second argument of and prints first n lines of file.
python head.py 5 data.txt
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
In [193]:
%%file cat.py
import sys

def cat(file):
    for line in open(file):
        print(line, end="")
        
if __name__ == "__main__":
    cat(sys.argv[1])
Writing cat.py
In [194]:
!python cat.py three.txt
one
two
three
In [197]:
%%file head.py
import sys

def head(n, file):
    f = open(file)
    for i in range(n):
        print(f.readline(), end="")
        
if __name__ == "__main__":
    n = int(sys.argv[1])
    file = sys.argv[2]
    head(n, file)
Overwriting head.py
In [198]:
!python head.py 5 data.txt
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
In [ ]: