Basic Python Training at PCCOE - Day 3

March 5-7, 2019 Vikrant Patil

These notes are available online at http://notes.pipal.in/2019/pccoe_basic/day3.html

© Pipal Academy LLP

Day 1 | Day 2 | Day 3

We will be using python 3 (>= 3.0) from anaconda for this training. You can download it from

https://www.anaconda.com/download/

  • Write a function print_triangle which will print a triangle of * of base n.
    >>> print_triangle(5)
        * 
       * *
      * * *
     * * * *
    * * * * *

Take home assignment

  • Write a function pascal to generate pascal traingle as a 2D list.
    >>> pascal(4)
    [[1],[1,1],[1,2,1],[1,3,3,1]]
  • Write a function print_pascal to print pascal triangle of base n.
    >>> print_pascal(4)
            1
          1   1
        1   2   1
      1   3   3   1
    `
  • Write a function dirtree to generate tree structure of directory
    >>> dirtree(os.getcwd())
    .
    ├── day1.html
    ├── day1.ipynb
    ├── day2.html
    ├── day2.ipynb
    ├── hello.py
    ├── helloworld.py
    ├── Makefile
    ├── push
    ├── __pycache__
    │   ├── square1.cpython-37.pyc
    │   ├── square2.cpython-37.pyc
    │   └── square.cpython-37.pyc
    ├── python_basic
    │   └── Untitled.ipynb
    ├── square1.py
    ├── square2.py
    └── square.py
In [2]:
def mtable(n):
    return [n*i for i in range(1,11)]
In [3]:
mtable("*")
Out[3]:
['*',
 '**',
 '***',
 '****',
 '*****',
 '******',
 '*******',
 '********',
 '*********',
 '**********']
In [4]:
def triangle(base, char="*"):
    return [char*i for i in range(1, base+1)]    
In [5]:
triangle(3)
Out[5]:
['*', '**', '***']
In [6]:
triangle(5, "@")
Out[6]:
['@', '@@', '@@@', '@@@@', '@@@@@']
In [7]:
def print_triangle(tr):
    for line in tr:
        print(line)
In [8]:
t10 = triangle(10)
In [9]:
print_triangle(t10)
*
**
***
****
*****
******
*******
********
*********
**********
In [10]:
def print_triangle1(tr):
    width = len(tr[-1])
    for line in tr:
        print(line.center(width))
In [11]:
print_triangle1(t10)
    *     
    **    
   ***    
   ****   
  *****   
  ******  
 *******  
 ******** 
********* 
**********
In [12]:
" ".join(["x","y","z"])
Out[12]:
'x y z'
In [13]:
" ".join("xyz")
Out[13]:
'x y z'
In [14]:
def print_triangle2(tr):
    width = len(tr[-1])
    width = width + width -1 
    for line in tr:
        line = " ".join(line)
        print(line.center(width))
In [15]:
print_triangle2(t10)
         *         
        * *        
       * * *       
      * * * *      
     * * * * *     
    * * * * * *    
   * * * * * * *   
  * * * * * * * *  
 * * * * * * * * * 
* * * * * * * * * *
In [16]:
print_triangle2(triangle(25))
                        *                        
                       * *                       
                      * * *                      
                     * * * *                     
                    * * * * *                    
                   * * * * * *                   
                  * * * * * * *                  
                 * * * * * * * *                 
                * * * * * * * * *                
               * * * * * * * * * *               
              * * * * * * * * * * *              
             * * * * * * * * * * * *             
            * * * * * * * * * * * * *            
           * * * * * * * * * * * * * *           
          * * * * * * * * * * * * * * *          
         * * * * * * * * * * * * * * * *         
        * * * * * * * * * * * * * * * * *        
       * * * * * * * * * * * * * * * * * *       
      * * * * * * * * * * * * * * * * * * *      
     * * * * * * * * * * * * * * * * * * * *     
    * * * * * * * * * * * * * * * * * * * * *    
   * * * * * * * * * * * * * * * * * * * * * *   
  * * * * * * * * * * * * * * * * * * * * * * *  
 * * * * * * * * * * * * * * * * * * * * * * * * 
* * * * * * * * * * * * * * * * * * * * * * * * *
In [17]:
print_triangle2(triangle(25, "@"))
                        @                        
                       @ @                       
                      @ @ @                      
                     @ @ @ @                     
                    @ @ @ @ @                    
                   @ @ @ @ @ @                   
                  @ @ @ @ @ @ @                  
                 @ @ @ @ @ @ @ @                 
                @ @ @ @ @ @ @ @ @                
               @ @ @ @ @ @ @ @ @ @               
              @ @ @ @ @ @ @ @ @ @ @              
             @ @ @ @ @ @ @ @ @ @ @ @             
            @ @ @ @ @ @ @ @ @ @ @ @ @            
           @ @ @ @ @ @ @ @ @ @ @ @ @ @           
          @ @ @ @ @ @ @ @ @ @ @ @ @ @ @          
         @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @         
        @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @        
       @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @       
      @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @      
     @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @     
    @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @    
   @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @   
  @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @  
 @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ 
@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @

How do we add two vectors?

In [18]:
x = [1,2,3,4]
y = [1,1,1,1]
In [19]:
z = []
for i in range(4):
    z.append(x[i] + y[i])
In [20]:
z
Out[20]:
[2, 3, 4, 5]
In [21]:
[x[i]+ y[i] for i in range(4)]
Out[21]:
[2, 3, 4, 5]
In [22]:
z = []
for a, b in zip(x,y):
    z.append(a+b)
In [23]:
z
Out[23]:
[2, 3, 4, 5]
In [24]:
[a+b for a,b in zip(x,y)]
Out[24]:
[2, 3, 4, 5]
In [25]:
z = [a+b for a,b in zip(x,y)]
In [26]:
def pascal(base):
    t = [[1]]
    for i in range(base-1):
        last = t[-1]
        x = last[:] + [0]
        y = [0] + last[:]
        z = [a+b for a,b in zip(x,y)]
        t.append(z)
    return t
In [27]:
pascal(5)
Out[27]:
[[1], [1, 1], [1, 2, 1], [1, 3, 3, 1], [1, 4, 6, 4, 1]]
In [28]:
print_triangle2(pascal(5))
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-28-cc90b5e36763> in <module>
----> 1 print_triangle2(pascal(5))

<ipython-input-14-886b0607158d> in print_triangle2(tr)
      3     width = width + width -1
      4     for line in tr:
----> 5         line = " ".join(line)
      6         print(line.center(width))

TypeError: sequence item 0: expected str instance, int found
In [29]:
def to_text(data):
    return [[str(item) for item in row] for row in data]
In [30]:
to_text(pascal(5))
Out[30]:
[['1'],
 ['1', '1'],
 ['1', '2', '1'],
 ['1', '3', '3', '1'],
 ['1', '4', '6', '4', '1']]
In [31]:
print_triangle2(to_text(pascal(5)))
    1    
   1 1   
  1 2 1  
 1 3 3 1 
1 4 6 4 1
In [32]:
print_triangle2(to_text(pascal(6)))
     1     
    1 1    
   1 2 1   
  1 3 3 1  
 1 4 6 4 1 
1 5 10 10 5 1
In [33]:
print_triangle2(to_text(pascal(10)))
         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
In [34]:
def print_triangle3(tr):
    def linelength(line):
        return len(" ".join(line))
    
    width = linelength(tr[-1])
    for line in tr:
        line = " ".join(line)
        print(line.center(width))
In [35]:
print_triangle3(to_text(pascal(10)))
             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
In [36]:
for i in range(1,11):
    print(i,i*i,i*i*i)
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 [38]:
for i in range(1,11):
    print("{:2} {:3} {:4}".format(i,i*i,i*i*i))
 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 [39]:
for i in range(1,11):
    print("{n:2} {sqr:3} {cube:4}".format(n=i,sqr=i*i,cube=i*i*i))
 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 [44]:
def print_triangle4(tr):
    def linewidth(line):
        return maxdigits*len(line) + len(line)-1

    def format_line(line):
        s = ""
        for item in line:
            s =  s+ " {n:{maxdigits}}".format(n=item, maxdigits=maxdigits)
        return s
    
    maxdigits = len(max(tr[-1], key=len))
    width = linewidth(tr[-1])
    for line in tr:
        line = format_line(line)
        print(line.center(width))
In [45]:
print_triangle4(to_text(pascal(10)))
                   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  
In [46]:
print_triangle4(to_text(pascal(15)))
                                   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          
     1    12   66   220  495  792  924  792  495  220  66   12   1        
   1    13   78   286  715  1287 1716 1716 1287 715  286  78   13   1     
 1    14   91   364  1001 2002 3003 3432 3003 2002 1001 364  91   14   1   

working with files

In [47]:
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!
In [48]:
%%file poem.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 poem.txt
In [50]:
with open("poem.txt") as file:
    print(file.read()) # read complete file
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 [52]:
with open("poem.txt") as file:
    for i in range(5):
        print(file.readline(), end="")
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
In [53]:
with open("poem.txt") as file:
    lines = file.readlines() # this reads all lines and gives it as list of lines
    for i, l in enumerate(lines):
        print(i+1, l, 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 [55]:
!head -n 3 poem.txt
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
In [56]:
def head(filename, n=5):
    with open(filename) as f:
        for i in range(n):
            print(f.readline(), end="")
In [58]:
head("poem.txt")
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
In [59]:
!cat poem.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!
In [60]:
f = open("poem.txt")
In [61]:
help(f.readlines)
Help on built-in function readlines:

readlines(hint=-1, /) method of _io.TextIOWrapper instance
    Return a list of lines from the stream.
    
    hint can be specified to control the number of lines read: no more
    lines will be read if the total size (in bytes/characters) of all
    lines so far exceeds hint.

In [64]:
f.readlines(10)
Out[64]:
['\n', 'Beautiful is better than ugly.\n']
In [65]:
f.close()
In [66]:
f = open("poem.txt")
print(f.readlines(3))
['The Zen of Python, by Tim Peters\n']
In [67]:
f.readline()
Out[67]:
'\n'
In [68]:
print(f.readlines(0))
['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!\n"]
In [69]:
f.close()
In [70]:
f = open("poem.txt")
f.readlines(100)
Out[70]:
['The Zen of Python, by Tim Peters\n',
 '\n',
 'Beautiful is better than ugly.\n',
 'Explicit is better than implicit.\n',
 'Simple is better than complex.\n']
In [71]:
f.close()
In [72]:
f = open("poem.txt")
f.readlines(-1)
Out[72]:
['The Zen of Python, by Tim Peters\n',
 '\n',
 '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!\n"]
In [73]:
f.close()
In [75]:
f = open("poem.txt")
f.readlines(0)
Out[75]:
['The Zen of Python, by Tim Peters\n',
 '\n',
 '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!\n"]
In [76]:
!grep "def " square2.py
def square(x):

problem

  • Write a python script "cat.py" to print file contents.
  • Write a python script "head.py" to see first n lines of file
  • Write a python script "grep.py" to search given string in a file and print that line
In [77]:
%%file cat.py
import sys

def cat(filename):
    with open(filename) as file:
        print(file.read())
        
if __name__ == "__main__":
    cat(sys.argv[1])
Writing cat.py
In [78]:
!python cat.py poem.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!

In [79]:
%%file head.py
import sys

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

Beautiful is better than ugly.
Explicit is better than implicit.
In [81]:
!grep "Zen" poem.txt
The Zen of Python, by Tim Peters
In [82]:
!grep "than" poem.txt
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.
Now is better than never.
Although never is often better than *right* now.
In [85]:
%%file grep.py
import sys

def grep(filename, pattern):
    with open(filename) as f:
        for line in f:
            if pattern in line:
                print(line, end="")
    
if __name__ == "__main__":
    grep(sys.argv[1], sys.argv[2])
Overwriting grep.py
In [86]:
!python grep.py poem.txt than
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.
Now is better than never.
Although never is often better than *right* now.

problem

  • Implement unix command wc as a script wc.py. it prints line count, word count and charecter count.
In [87]:
!wc poem.txt
 21 144 857 poem.txt
In [93]:
%%file wc.py
"""
This module implements unix command wc
usage:
python wc FILENAME
"""
import sys

def linecount(filename):
    """
    returns number of lines in given file
    """
    with open(filename) as f:
        return len(f.readlines())
    
def wordcount(filename):
    """
    counts number of words in given file
    """
    with open(filename) as f:
        return len(f.read().split())
    

def charcount(filename):
    """
    returns number of charecters in given file
    """
    with open(filename) as f:
        return len(f.read())
    
if __name__ == "__main__":
    filename = sys.argv[1]
    print(linecount(filename), wordcount(filename), charcount(filename), filename)
Overwriting wc.py
In [94]:
!python wc.py poem.txt
21 144 857 poem.txt
In [95]:
import wc
In [96]:
help(wc)
Help on module wc:

NAME
    wc - This module implements unix command wc

FUNCTIONS
    charcount(filename)
        returns number of charecters in given file
    
    linecount(filename)
        returns number of lines in given file
    
    wordcount(filename)
        counts number of words in given file

FILE
    /home/vikrant/trainings/2019/pccoe_basic/wc.py


In [97]:
"asas  asdad         sadsdsd      sdsdds".split(" ")
Out[97]:
['asas',
 '',
 'asdad',
 '',
 '',
 '',
 '',
 '',
 '',
 '',
 '',
 'sadsdsd',
 '',
 '',
 '',
 '',
 '',
 'sdsdds']
In [98]:
"asas  asdad         sadsdsd      sdsdds".split()
Out[98]:
['asas', 'asdad', 'sadsdsd', 'sdsdds']

Writing files

In [99]:
with open("data.txt", "w") as f:
    f.write("one\n")
    f.write("two\n")
    f.write("three\n")
    
In [100]:
!python cat.py data.txt
one
two
three

In [101]:
with open("data.txt", "w") as f:
    f.write("four\n")
    f.write("five\n")
    f.write("six\n")
    
In [102]:
!python cat.py data.txt
four
five
six

In [103]:
with open("data.txt", "a") as f:
    f.write("one\n")
    f.write("two\n")
    f.write("three\n")
    
In [104]:
!python cat.py data.txt
four
five
six
one
two
three

In [105]:
with open("data.bin", "wb") as b:
    b.write(b"hello world!")
In [106]:
with open("data.bin", "rb") as b:
    print(b.read())
b'hello world!'
In [107]:
"hello".encode()
Out[107]:
b'hello'
In [108]:
binary = b"hello"
In [109]:
binary.decode()
Out[109]:
'hello'

Working with dictionaries

In [110]:
machine = {
    "name":"mozart",
    "cpu":"corei3",
    "memory":"4GB",
    "os":"mint"
}
In [121]:
for key in machine:
    print(key, end=",")
name,cpu,memory,os,
In [114]:
for key in machine:
    print(key, machine[key])
name mozart
cpu corei3
memory 4GB
os mint
In [115]:
for key, value in machine.items():
    print(key, value)
name mozart
cpu corei3
memory 4GB
os mint
In [120]:
for value in machine.values():
    print(value, end=",")
mozart,corei3,4GB,mint,
In [117]:
machine['manufacturer']
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-117-49f5a04f2f70> in <module>
----> 1 machine['manufacturer']

KeyError: 'manufacturer'
In [118]:
machine.get('manufacturer',"Acer")
Out[118]:
'Acer'
In [119]:
machine.get('cpu',"corei5")
Out[119]:
'corei3'
In [122]:
a = ['name','cpu','memory','os']
b = ['mozart','corei3','4GB','mint']
In [123]:
dict(zip(a,b))
Out[123]:
{'name': 'mozart', 'cpu': 'corei3', 'memory': '4GB', 'os': 'mint'}

Example

In [124]:
%%file words.txt
one
one two
one two three
one two three four
one two three four five
one two three four six
one two six seven
six seven eight
nine eight
ten
Writing words.txt
In [125]:
def get_words(filename):
    with open(filename) as f:
        return f.read().split()
In [126]:
words = get_words("words.txt")
In [128]:
uniquewords = set(words)
In [129]:
uniquewords
Out[129]:
{'eight', 'five', 'four', 'nine', 'one', 'seven', 'six', 'ten', 'three', 'two'}
In [131]:
uniquewords.add('five')    
In [132]:
uniquewords
Out[132]:
{'eight', 'five', 'four', 'nine', 'one', 'seven', 'six', 'ten', 'three', 'two'}
In [133]:
for w in uniquewords:
    print(w)
six
four
nine
ten
two
eight
three
one
seven
five
In [134]:
for w in uniquewords:
    print(w, words.count(w))
six 3
four 3
nine 1
ten 1
two 6
eight 2
three 4
one 7
seven 2
five 1
In [135]:
def wordfreq(words):
    uniquewords = set(words)
    freq = {}
    for w in uniquewords:
        freq[w] = words.count(w)
    return freq
In [136]:
wordfreq(words)
Out[136]:
{'six': 3,
 'four': 3,
 'nine': 1,
 'ten': 1,
 'two': 6,
 'eight': 2,
 'three': 4,
 'one': 7,
 'seven': 2,
 'five': 1}
In [137]:
freq = wordfreq(words)
In [138]:
sorted(freq)
Out[138]:
['eight', 'five', 'four', 'nine', 'one', 'seven', 'six', 'ten', 'three', 'two']
In [139]:
for word, f in freq.items():
    print(word, f)
six 3
four 3
nine 1
ten 1
two 6
eight 2
three 4
one 7
seven 2
five 1
In [140]:
def print_freq(freq):
    def get_freq(key):
        return freq[key]

    for word in sorted(freq, key=get_freq):
        print(word, freq[word])
In [141]:
print_freq(freq)
nine 1
ten 1
five 1
eight 2
seven 2
six 3
four 3
three 4
two 6
one 7
In [142]:
def print_freq(freq):
    def get_freq(key):
        return freq[key]

    for word in sorted(freq, reverse=True, key=get_freq):
        print(word, freq[word])
In [143]:
print_freq(freq)
one 7
two 6
three 4
six 3
four 3
eight 2
seven 2
nine 1
ten 1
five 1
In [146]:
def print_freq(freq):
    def get_freq(key):
        return freq[key]

    for word in sorted(freq, reverse=True, key=get_freq):
        print(word.rjust(5), freq[word], "*"*freq[word])
In [147]:
print_freq(freq)
  one 7 *******
  two 6 ******
three 4 ****
  six 3 ***
 four 3 ***
eight 2 **
seven 2 **
 nine 1 *
  ten 1 *
 five 1 *

classes

In [148]:
%%file bank0.py

balance = 0

def get_balance():
    return balance

def deposite(amount):
    global balance
    balance += amount
    
def withdraw(amount):
    global balance
    balance -= amount
    
if __name__ == "__main__":
    pass
Writing bank0.py
In [149]:
import bank0 as account
In [150]:
account.get_balance()
Out[150]:
0
In [151]:
account.deposite(100)
In [152]:
account.get_balance()
Out[152]:
100
In [153]:
account.withdraw(20)
In [154]:
account.get_balance()
Out[154]:
80
In [155]:
%%file bank1.py

def create_account():
    return {"balance":0}

def get_balance(account):
    return account['balance']

def deposite(account, amount):
    account['balance'] += amount
    
def withdraw(account, amount):
    account['balance'] -= amount
    
if __name__ == "__main__":
    pass
Writing bank1.py
In [157]:
import bank1 as bank
In [158]:
a1  = bank.create_account()
a2 = bank.create_account()
In [159]:
bank.deposite(a1, 1000)
bank.deposite(a2, 100)
In [160]:
bank.get_balance(a1)
Out[160]:
1000
In [161]:
bank.get_balance(a2)
Out[161]:
100
In [162]:
bank.withdraw(a1, 200)
In [163]:
bank.get_balance(a1)
Out[163]:
800
In [164]:
class BankAccount:
    
    def __init__(self):
        self.balance = 0
        
    def get_balace(self):
        return self.balance
    
    def deposite(self, amount):
        self.balance += amount
        
    def withdraw(self, amount):
        self.balance -= amount
        
In [165]:
a1 = BankAccount()
a2 = BankAccount()
In [166]:
a1.deposite(1000)
a2.deposite(200)
In [167]:
a1.get_balace()
Out[167]:
1000
In [168]:
a2.get_balace()
Out[168]:
200
In [169]:
def add():
    pass
In [170]:
add
Out[170]:
<function __main__.add()>
In [171]:
class Foo:
    pass
In [172]:
Foo
Out[172]:
__main__.Foo
In [173]:
f = Foo()
In [174]:
f
Out[174]:
<__main__.Foo at 0x7f15c2ee8748>
In [175]:
x = [1,2,3,4]
In [176]:
x
Out[176]:
[1, 2, 3, 4]
In [177]:
type(x)
Out[177]:
list
In [178]:
type(f)
Out[178]:
__main__.Foo
In [179]:
type(Foo)
Out[179]:
type
In [180]:
type(1)
Out[180]:
int
In [181]:
isinstance(1, int)
Out[181]:
True
In [182]:
isinstance(f, Foo)
Out[182]:
True
In [183]:
isinstance(a1, BankAccount)
Out[183]:
True
In [184]:
isinstance(a1, Foo)
Out[184]:
False

problem

  • Write a class Point to represent a point in 2D plane. it has to have x and y coordinate. it should have methods to access x coordinate and y coordinate.
In [188]:
class Point:
    
    def __init__(self, x, y):
        self.x = x
        self.y = y
        
    def getX(self):
        return self.x
        
    def getY(self):
        return self.y
        
    def distance(self):
        return (self.x**2 + self.y**2)**0.5
In [189]:
p1 = Point(1,1)
In [190]:
p1.getX()
Out[190]:
1
In [191]:
p1.
Out[191]:
1

problem

  • Write a class Timer which has methods start, stop and time_taken. When you call start, it should note time at that instance and store it. when you call stop method, it notes time and stores it. when you call time_taken method it returns difference between start time and stop time.
>>> t = Timer()
>>> t.start()
>>> func()
>>> t.stop()
>>> print(t.time_taken())
3.00
In [192]:
import time
In [193]:
time.time()
Out[193]:
1551950148.1815653
In [194]:
p1
Out[194]:
<__main__.Point at 0x7f15c1b402b0>
In [195]:
print(__name__)
__main__
In [196]:
add
Out[196]:
<function __main__.add()>
In [197]:
add = 2
In [198]:
add
Out[198]:
2
In [199]:
class Timer:
    
    def __init__(self):
        self._start = 0
        self._end = 0
        
    def start(self):
        self._start = time.time()
        
    def stop(self):
        self._end = time.time()
        
    def time_taken(self):
        return self._end - self._start
    
    def reset(self):
        self._start = 0
        self._end = 0
    
In [205]:
import math

def foo():
    s = 0
    for i in range(100000000):
        s = s + math.sqrt(i+100)
    return s

from math import sqrt
def bar():
    s = 0
    for i in range(100000000):
        s = s + sqrt(i+100)
    return 
    
In [206]:
t = Timer()
t.start()
foo()
t.stop()
print("Time taken by foo:", t.time_taken())
Time taken by foo: 21.29659914970398
In [207]:
t.reset()
t.start()
bar()
t.stop()
print("Time taken by bar:", t.time_taken())
Time taken by bar: 17.246618509292603

References

  • goolge for python docs.
  • Python practice book by Anand Chitipothu
  • structure and interpretation of computer programs
In [ ]: