Basic Python Training at Arcesium - Day 3

Apr 15-18, 2019 Vikrant Patil

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

© Pipal Academy LLP

Day 1 | Day 2 | Day 3 | Day 4

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

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

Recap

In [1]:
x = [1, 0, 0]
y = x
x = [1,1,1]
In [2]:
y
Out[2]:
[1, 0, 0]
In [3]:
primes = [2,3,5,7,11,13,17,19]
In [6]:
primes[-1]#last element
Out[6]:
19
In [7]:
primes[2:5]
Out[7]:
[5, 7, 11]
In [8]:
primes[:3] #take first three
Out[8]:
[2, 3, 5]
In [9]:
primes[3:] #drop frist three
Out[9]:
[7, 11, 13, 17, 19]
In [10]:
primes[:] #everything
Out[10]:
[2, 3, 5, 7, 11, 13, 17, 19]
In [11]:
primes[1:5:2]
Out[11]:
[3, 7]
In [12]:
primes[::2]
Out[12]:
[2, 5, 11, 17]
In [13]:
primes[::-1]
Out[13]:
[19, 17, 13, 11, 7, 5, 3, 2]
In [15]:
primes[:-3] # drop last three
Out[15]:
[2, 3, 5, 7, 11]
In [16]:
primes[-1:]
Out[16]:
[19]
In [17]:
sentence = "Wizard of oz is python"
In [18]:
sentence[:5]
Out[18]:
'Wizar'
In [19]:
sentence[::-1]
Out[19]:
'nohtyp si zo fo draziW'
In [20]:
pt = tuple(primes)
In [21]:
pt
Out[21]:
(2, 3, 5, 7, 11, 13, 17, 19)
In [22]:
pt[::-1]
Out[22]:
(19, 17, 13, 11, 7, 5, 3, 2)
In [23]:
primes[0] = 0
In [24]:
primes
Out[24]:
[0, 3, 5, 7, 11, 13, 17, 19]
In [26]:
primes[0] = 2
In [27]:
primes
Out[27]:
[2, 3, 5, 7, 11, 13, 17, 19]
In [28]:
pt[0] = 0
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-28-fb4fc018b62b> in <module>
----> 1 pt[0] = 0

TypeError: 'tuple' object does not support item assignment
In [30]:
sentence[0] = "c"
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-30-6f4c2f19d2a7> in <module>
----> 1 sentence[0] = "c"

TypeError: 'str' object does not support item assignment
In [32]:
sentence.count("o")
Out[32]:
3
In [34]:
sentence.split() #split on white space
Out[34]:
['Wizard', 'of', 'oz', 'is', 'python']
In [35]:
sentence  = " "*5 + sentence + "\t"*5
In [36]:
sentence
Out[36]:
'     Wizard of oz is python\t\t\t\t\t'
In [38]:
sentence.split()
Out[38]:
['Wizard', 'of', 'oz', 'is', 'python']
In [39]:
sentence
Out[39]:
'     Wizard of oz is python\t\t\t\t\t'
In [40]:
sentence.replace(" ", ",")
Out[40]:
',,,,,Wizard,of,oz,is,python\t\t\t\t\t'
In [41]:
s = '     Wizard,of,oz,is,python\t\t\t\t\t'
In [43]:
s.split(",")
Out[43]:
['     Wizard', 'of', 'oz', 'is', 'python\t\t\t\t\t']
In [44]:
s.strip().split(",")
Out[44]:
['Wizard', 'of', 'oz', 'is', 'python']

Question

filename = "hello.exe"

Find extension?

In [45]:
filename= "hello.exe"
In [46]:
filename.split(".")
Out[46]:
['hello', 'exe']
In [48]:
filename.split()[-1] # xtension
Out[48]:
'hello.exe'
In [49]:
value = "101 Rs"
In [51]:
value, currency = value.split()
In [52]:
value
Out[52]:
'101'
In [53]:
currency
Out[53]:
'Rs'
In [54]:
value = float(value)
In [55]:
value
Out[55]:
101.0
In [56]:
primes
Out[56]:
[2, 3, 5, 7, 11, 13, 17, 19]
In [57]:
[x*x for x in primes] # square each item in the list
Out[57]:
[4, 9, 25, 49, 121, 169, 289, 361]
In [59]:
[e for e in primes if e%2==0]
Out[59]:
[2]

example

  • find all numbers less than 1000 which are multiples of 7 or 13
In [60]:
[i for i in range(1, 1000) if i%7==0 or i%13==0]
Out[60]:
[7,
 13,
 14,
 21,
 26,
 28,
 35,
 39,
 42,
 49,
 52,
 56,
 63,
 65,
 70,
 77,
 78,
 84,
 91,
 98,
 104,
 105,
 112,
 117,
 119,
 126,
 130,
 133,
 140,
 143,
 147,
 154,
 156,
 161,
 168,
 169,
 175,
 182,
 189,
 195,
 196,
 203,
 208,
 210,
 217,
 221,
 224,
 231,
 234,
 238,
 245,
 247,
 252,
 259,
 260,
 266,
 273,
 280,
 286,
 287,
 294,
 299,
 301,
 308,
 312,
 315,
 322,
 325,
 329,
 336,
 338,
 343,
 350,
 351,
 357,
 364,
 371,
 377,
 378,
 385,
 390,
 392,
 399,
 403,
 406,
 413,
 416,
 420,
 427,
 429,
 434,
 441,
 442,
 448,
 455,
 462,
 468,
 469,
 476,
 481,
 483,
 490,
 494,
 497,
 504,
 507,
 511,
 518,
 520,
 525,
 532,
 533,
 539,
 546,
 553,
 559,
 560,
 567,
 572,
 574,
 581,
 585,
 588,
 595,
 598,
 602,
 609,
 611,
 616,
 623,
 624,
 630,
 637,
 644,
 650,
 651,
 658,
 663,
 665,
 672,
 676,
 679,
 686,
 689,
 693,
 700,
 702,
 707,
 714,
 715,
 721,
 728,
 735,
 741,
 742,
 749,
 754,
 756,
 763,
 767,
 770,
 777,
 780,
 784,
 791,
 793,
 798,
 805,
 806,
 812,
 819,
 826,
 832,
 833,
 840,
 845,
 847,
 854,
 858,
 861,
 868,
 871,
 875,
 882,
 884,
 889,
 896,
 897,
 903,
 910,
 917,
 923,
 924,
 931,
 936,
 938,
 945,
 949,
 952,
 959,
 962,
 966,
 973,
 975,
 980,
 987,
 988,
 994]
In [61]:
def multiplesof13or7(n):
    return [i for i in range(1, n) if i%7==0 or i%13==0]
In [62]:
multiplesof13or7(100)
Out[62]:
[7, 13, 14, 21, 26, 28, 35, 39, 42, 49, 52, 56, 63, 65, 70, 77, 78, 84, 91, 98]

playing with 2d data

In [65]:
tables = [[i*n for i in range(1, 11)] for n in range(1,6)]
In [66]:
tables
Out[66]:
[[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]]
In [67]:
tables[0] ##0th row
Out[67]:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
In [68]:
tables[-1] #last row
Out[68]:
[5, 10, 15, 20, 25, 30, 35, 40, 45, 50]
In [69]:
tables[0]
Out[69]:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
In [70]:
tables[0][0]
Out[70]:
1
In [71]:
tables[0][1]
Out[71]:
2
In [72]:
tables[0][2]
Out[72]:
3
In [73]:
tables[0][3]
Out[73]:
4
In [74]:
tables[0][4]
Out[74]:
5

lets access last column (9th index column)

In [75]:
tables
Out[75]:
[[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]]
In [76]:
tables[0][9]
Out[76]:
10
In [77]:
tables[1][9]
Out[77]:
20
In [78]:
tables[2][9]
Out[78]:
30
In [79]:
tables[3][9]
Out[79]:
40
In [80]:
tables[4][9]
Out[80]:
50
In [81]:
def column(data, colnum):
    return [ data[i][colnum] for i in range(len(data))]
In [82]:
column(tables, 9)
Out[82]:
[10, 20, 30, 40, 50]
In [83]:
column(tables, 1)
Out[83]:
[2, 4, 6, 8, 10]
In [84]:
tables
Out[84]:
[[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]]
In [85]:
for row in tables:
    print(row)
[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]
In [86]:
def column(data, colnum):
    return [row[colnum] for row in data]
In [88]:
column(tables, 0)
Out[88]:
[1, 2, 3, 4, 5]
In [90]:
column(tables, 4)
Out[90]:
[5, 10, 15, 20, 25]
In [91]:
def transpose(data):
    columncount = len(data[0])
    return [column(data, i) for i in range(columncount)]
In [92]:
transpose(tables)
Out[92]:
[[1, 2, 3, 4, 5],
 [2, 4, 6, 8, 10],
 [3, 6, 9, 12, 15],
 [4, 8, 12, 16, 20],
 [5, 10, 15, 20, 25],
 [6, 12, 18, 24, 30],
 [7, 14, 21, 28, 35],
 [8, 16, 24, 32, 40],
 [9, 18, 27, 36, 45],
 [10, 20, 30, 40, 50]]
In [93]:
td = transpose(tables)
In [94]:
td[0]
Out[94]:
[1, 2, 3, 4, 5]
In [95]:
td[-1]
Out[95]:
[10, 20, 30, 40, 50]

iteration patterns

In [106]:
for p in primes:
    print(p, end=",")
2,3,5,7,11,13,17,19,

iterating in reversed fashion

In [98]:
for p in reversed(primes):
    print(p, end=",")
19,17,13,11,7,5,3,2,
In [99]:
reversed(primes)
Out[99]:
<list_reverseiterator at 0x7ff5455f46a0>
In [101]:
rprimes = reversed(primes) # should not do this
In [102]:
for p in rprimes:
    print(p, end=",")
19,17,13,11,7,5,3,2,
In [103]:
for p in rprimes:
    print(p, end=",")
In [104]:
rp = primes[::-1]
In [105]:
rp
Out[105]:
[19, 17, 13, 11, 7, 5, 3, 2]

iterating with index

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

iterating two lists together

In [109]:
first = ["Elsa", "Alice", "Elisa"]
second = ["Frozen", "Wonder", "Hacker"]
In [111]:
for name, surname in zip(first, second):
    print(name, surname)
Elsa Frozen
Alice Wonder
Elisa Hacker
In [112]:
def add(x,y):
    return x+y
In [113]:
add(2,3)
Out[113]:
5
In [114]:
pair = [2, 3]
In [115]:
add(pair[0], pair[1])
Out[115]:
5
In [116]:
add(*pair)
Out[116]:
5
In [117]:
zip(*tables)
Out[117]:
<zip at 0x7ff545549d08>
In [118]:
list(zip(*tables))
Out[118]:
[(1, 2, 3, 4, 5),
 (2, 4, 6, 8, 10),
 (3, 6, 9, 12, 15),
 (4, 8, 12, 16, 20),
 (5, 10, 15, 20, 25),
 (6, 12, 18, 24, 30),
 (7, 14, 21, 28, 35),
 (8, 16, 24, 32, 40),
 (9, 18, 27, 36, 45),
 (10, 20, 30, 40, 50)]

problem

  • Write a function vector_add which does vector addition of two vectors (taken as list or tuple)
In [120]:
list(zip("hello", "there"))
Out[120]:
[('h', 't'), ('e', 'h'), ('l', 'e'), ('l', 'r'), ('o', 'e')]
In [121]:
v1 = [1, 2, 3, 4, 5]
v2 = [1]*5

[x+y for x,y in zip(v1, v2)]
Out[121]:
[2, 3, 4, 5, 6]
In [122]:
import random
In [123]:
values = [random.random() for i in range(10)]
currency = [random.choice(["Rs","$","E"]) for i in range(10) ]
In [124]:
values
Out[124]:
[0.5067496254144116,
 0.1325152628862214,
 0.45151194582227316,
 0.9870799039583654,
 0.7358018197230344,
 0.12539363882954158,
 0.3391783775216465,
 0.8014633381764759,
 0.0005192710695394176,
 0.5174255175063571]
In [125]:
currency
Out[125]:
['$', 'Rs', 'Rs', '$', '$', 'E', 'Rs', 'E', 'E', 'E']
In [126]:
for v,c in zip(values, currency):
    print(v, c)
0.5067496254144116 $
0.1325152628862214 Rs
0.45151194582227316 Rs
0.9870799039583654 $
0.7358018197230344 $
0.12539363882954158 E
0.3391783775216465 Rs
0.8014633381764759 E
0.0005192710695394176 E
0.5174255175063571 E
In [127]:
[str(v) + " " + c for v,c in zip(values, currency)]
Out[127]:
['0.5067496254144116 $',
 '0.1325152628862214 Rs',
 '0.45151194582227316 Rs',
 '0.9870799039583654 $',
 '0.7358018197230344 $',
 '0.12539363882954158 E',
 '0.3391783775216465 Rs',
 '0.8014633381764759 E',
 '0.0005192710695394176 E',
 '0.5174255175063571 E']
In [128]:
list(zip(values, currency))
Out[128]:
[(0.5067496254144116, '$'),
 (0.1325152628862214, 'Rs'),
 (0.45151194582227316, 'Rs'),
 (0.9870799039583654, '$'),
 (0.7358018197230344, '$'),
 (0.12539363882954158, 'E'),
 (0.3391783775216465, 'Rs'),
 (0.8014633381764759, 'E'),
 (0.0005192710695394176, 'E'),
 (0.5174255175063571, 'E')]
In [129]:
l = [1,2,3, [1,2,3]]
In [130]:
for item in l:
    print(item)
1
2
3
[1, 2, 3]

problems

  • strip word by word
  • remove duplicates
In [131]:
tickers = "hcl ,infy , tata,rel,simls"
In [132]:
tickers.split(",")
Out[132]:
['hcl ', 'infy ', ' tata', 'rel', 'simls']
In [133]:
[item.strip() for item in tickers.split(",")]
Out[133]:
['hcl', 'infy', 'tata', 'rel', 'simls']
In [134]:
list(tickers)
Out[134]:
['h',
 'c',
 'l',
 ' ',
 ',',
 'i',
 'n',
 'f',
 'y',
 ' ',
 ',',
 ' ',
 't',
 'a',
 't',
 'a',
 ',',
 'r',
 'e',
 'l',
 ',',
 's',
 'i',
 'm',
 'l',
 's']
In [135]:
nums = [42, 34, 35,35, 232,42, 34, 23, 45, 23, 45, 11, 34, 23, 11]
In [136]:
def removeduplicates(nums):
    uniq = []
    for n in nums:
        if n not in uniq:
            uniq.append(n)
    return uniq
In [137]:
removeduplicates(nums)
Out[137]:
[42, 34, 35, 232, 23, 45, 11]
In [138]:
list(set(nums))
Out[138]:
[34, 35, 232, 42, 11, 45, 23]

String formating

In [139]:
"{desg} of oz is {who}".format(desg="Wizard", who="Python")
Out[139]:
'Wizard of oz is Python'
In [140]:
template = "{0} did something called {1}, which resulted in {2}"
In [141]:
template.format("Alice", "sleeping", "dream")
Out[141]:
'Alice did something called sleeping, which resulted in dream'
In [142]:
template = "{1} did something called {0}, which resulted in {2}"
In [143]:
template.format("Alice", "sleeping", "dream")
Out[143]:
'sleeping did something called Alice, which resulted in dream'
In [144]:
"{} did something called {}, which resulted in {}".format("x","y","z")
Out[144]:
'x did something called y, which resulted in z'
In [145]:
"{} did something called {}, which resulted in {}".format("x","z","y")
Out[145]:
'x did something called z, which resulted in y'
In [146]:
"{} did something called {}, which resulted in {}".format("x","z")
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-146-cc63278e9699> in <module>
----> 1 "{} did something called {}, which resulted in {}".format("x","z")

IndexError: tuple index out of range
In [147]:
"{} did something called {}, which resulted in {}".format("x","z","p","q")
Out[147]:
'x did something called z, which resulted in p'

Reading files

In [148]:
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 [149]:
%%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 [150]:
with open("poem.txt") as f:
    print(f.read())
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 [151]:
with open("poem.txt") as f:
    data = f.read()
    print(data.replace("\n", " "))
    
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 [152]:
f = open("poem.txt")
In [153]:
f.readline()
Out[153]:
'The Zen of Python, by Tim Peters\n'
In [154]:
f.readline()
Out[154]:
'\n'
In [155]:
f.readline()
Out[155]:
'Beautiful is better than ugly.\n'
In [156]:
f.read()
Out[156]:
"Explicit is better than implicit.\nSimple is better than complex.\nComplex is better than complicated.\nFlat is better than nested.\nSparse is better than dense.\nReadability counts.\nSpecial cases aren't special enough to break the rules.\nAlthough practicality beats purity.\nErrors should never pass silently.\nUnless explicitly silenced.\nIn the face of ambiguity, refuse the temptation to guess.\nThere should be one-- and preferably only one --obvious way to do it.\nAlthough that way may not be obvious at first unless you're Dutch.\nNow is better than never.\nAlthough never is often better than *right* now.\nIf the implementation is hard to explain, it's a bad idea.\nIf the implementation is easy to explain, it may be a good idea.\nNamespaces are one honking great idea -- let's do more of those!\n"
In [157]:
f.read()
Out[157]:
''
In [158]:
f.close()
In [159]:
with open("poem.txt") as f:
    for line in f:
        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 [160]:
with open("poem.txt") as f:
    for i, line in enumerate(f):
        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 [161]:
with open("poem.txt") as f:
    for i, line in enumerate(f):
        print(i+1, line)
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 [162]:
with open("poem.txt") as f:
    for line in reversed(f.readlines()):
        print(line, end="")
Namespaces are one honking great idea -- let's do more of those!
If the implementation is easy to explain, it may be a good idea.
If the implementation is hard to explain, it's a bad idea.
Although never is often better than *right* now.
Now is better than never.
Although that way may not be obvious at first unless you're Dutch.
There should be one-- and preferably only one --obvious way to do it.
In the face of ambiguity, refuse the temptation to guess.
Unless explicitly silenced.
Errors should never pass silently.
Although practicality beats purity.
Special cases aren't special enough to break the rules.
Readability counts.
Sparse is better than dense.
Flat is better than nested.
Complex is better than complicated.
Simple is better than complex.
Explicit is better than implicit.
Beautiful is better than ugly.

The Zen of Python, by Tim Peters

problems

  • Write a python script head.py which takes filename and number of lines as argument and prints only those many lines
  • Write a python script tail.py which takes filename and number of lines as argument as prints last lines.
In [163]:
!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.
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.
In [166]:
%%file head.py
import sys

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

Beautiful is better than ugly.
Explicit is better than implicit.
In [169]:
%%file tail.py
import sys

def tail(filename, n):
    with open(filename) as f:
        lines = f.readlines()
        for line in lines[-n:]:
            print(line, end="")
            
if __name__ == "__main__":
    filename = sys.argv[1]
    n = int(sys.argv[2])
    tail(filename, n)
Writing tail.py
In [170]:
!python tail.py poem.txt 5
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 [171]:
from collections import deque
In [174]:
dq = deque(maxlen=3)
In [176]:
dq.append(1)
In [177]:
dq.append(2)
In [178]:
dq.append(3)
In [179]:
dq
Out[179]:
deque([1, 2, 3])
In [180]:
dq.append(4)
In [181]:
dq
Out[181]:
deque([2, 3, 4])
In [184]:
%%file tail1.py
import sys
from collections import deque

def tail(filename, n):
    with open(filename) as f:
        window = deque(maxlen=n)
        for line in f:
            window.append(line)
        for line in window:
            print(line, end="")
            
if __name__ == "__main__":
    filename = sys.argv[1]
    n = int(sys.argv[2])
    tail(filename, n)
Overwriting tail1.py
In [185]:
!python tail1.py poem.txt 5
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 to file

In [186]:
with open("data.txt", "w") as f:
    f.write("one")
    f.write("\n")
    f.write("two\n")
    f.write("three")
In [188]:
!python head.py data.txt 3
one
two
three
In [189]:
%%file cat.py
import sys

if __name__ == "__main__":
    with open(sys.argv[1]) as f:
        print(f.read())
Writing cat.py
In [190]:
!python cat.py data.txt
one
two
three
In [191]:
words = ["one", "two", "three", "four", "five", "six"]
In [192]:
with open("numbers.txt", "w") as f:
    for w in words:
        f.write(w)
        f.write("\n")
In [193]:
!python cat.py  numbers.txt
one
two
three
four
five
six

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

In [196]:
words
Out[196]:
['one', 'two', 'three', 'four', 'five', 'six']
In [197]:
",".join(words)
Out[197]:
'one,two,three,four,five,six'
In [198]:
tables
Out[198]:
[[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]]
In [210]:
def writecsv(data, filename):
    with open(filename, "w") as f:
        for row in data:
            strnums = [str(i) for i in row]
            line = ",".join(strnums)
            f.write(line)
            f.write("\n")
In [203]:
writecsv(tables, "tables.csv")
In [204]:
!python cat.py tables.csv
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

In [205]:
line
Out[205]:
'The Zen of Python, by Tim Peters\n'
In [211]:
def parsecsv(filename):
    with open(filename) as f:
        data  = []
        for line in f:
            data.append(line.strip().split(","))
        return data
In [212]:
parsecsv("tables.csv")
Out[212]:
[['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']]
In [207]:
s = []
for i in nums:
    s.append(i*i)
In [215]:
def intlist(strnums):
    return [int(s) for s in strnums]

def parsecsv(filename):
    with open(filename) as f:
        data  = []
        for line in f:
            strnums = line.strip().split(",")
            data.append(intlist(strnums))
        return data
In [216]:
parsecsv("tables.csv")
Out[216]:
[[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]]
In [217]:
int("dsdsd")
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-217-6c409c6acb3d> in <module>
----> 1 int("dsdsd")

ValueError: invalid literal for int() with base 10: 'dsdsd'
In [218]:
int("[1,2,3,4]")
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-218-256773c2d8ea> in <module>
----> 1 int("[1,2,3,4]")

ValueError: invalid literal for int() with base 10: '[1,2,3,4]'
In [219]:
int(["1","2"])
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-219-8bee6bf3fd9b> in <module>
----> 1 int(["1","2"])

TypeError: int() argument must be a string, a bytes-like object or a number, not 'list'
In [220]:
int("23")
Out[220]:
23
In [222]:
n = ["1","2","3","4"]
In [223]:
[int(i) for i in n]
Out[223]:
[1, 2, 3, 4]

Different modes for reading/writing files

'r' -> read
'w' -> write
'a' - > append
'b' -> binary
'rb' -> read binary
'ab' -> append binary
'wb' -> write brinary

if you don't specify b mode , it means default mode is text file.

dictionary

In [224]:
machine = {
    "cpu" : "corei3",
    "memeory": "4GB",
    "os": "windows",
    "storage" : "512GB",
    "graphics" : "Nvidia"
}
In [225]:
machine
Out[225]:
{'cpu': 'corei3',
 'memeory': '4GB',
 'os': 'windows',
 'storage': '512GB',
 'graphics': 'Nvidia'}
In [228]:
for item in machine:
    print(item, machine[item])
cpu corei3
memeory 4GB
os windows
storage 512GB
graphics Nvidia
In [229]:
for item in machine:
    print(item.ljust(8), machine[item])
cpu      corei3
memeory  4GB
os       windows
storage  512GB
graphics Nvidia
In [230]:
for k, v in machine.items():
    print(k.ljust(8), v)
cpu      corei3
memeory  4GB
os       windows
storage  512GB
graphics Nvidia
In [231]:
machine['cpu']
Out[231]:
'corei3'
In [232]:
machine.get('cpu')
Out[232]:
'corei3'
In [233]:
machine['name']
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-233-09c78ddd9a34> in <module>
----> 1 machine['name']

KeyError: 'name'
In [235]:
machine.get('name',"mozart")
Out[235]:
'mozart'
In [236]:
machine
Out[236]:
{'cpu': 'corei3',
 'memeory': '4GB',
 'os': 'windows',
 'storage': '512GB',
 'graphics': 'Nvidia'}
In [237]:
del machine['cpu']
In [238]:
machine
Out[238]:
{'memeory': '4GB', 'os': 'windows', 'storage': '512GB', 'graphics': 'Nvidia'}
In [239]:
machine['cpu'] = 'corei5'
In [240]:
machine
Out[240]:
{'memeory': '4GB',
 'os': 'windows',
 'storage': '512GB',
 'graphics': 'Nvidia',
 'cpu': 'corei5'}
In [241]:
for v in machine.values():
    print(v)
4GB
windows
512GB
Nvidia
corei5
In [242]:
for k in machine.keys():
    print(k)
memeory
os
storage
graphics
cpu

example

In [243]:
%%file words.txt
one 
one two
one two three
one two three four
one two three four five
one two three four five six
one two three four five six seven
one two three four five six seven eight
one two three four five six seven eight nine
one two three four five six seven eight nine ten
Writing words.txt
In [248]:
def getwords(filename):
    with open(filename) as f:
        return f.read().strip().split()

words = getwords("words.txt")

def wordfreq(words):
    freq = {}
    uniq = set(words)
    for w in uniq:
        freq[w] = words.count(w)
    return freq

freq = wordfreq(words)
In [250]:
freq
Out[250]:
{'eight': 3,
 'four': 7,
 'ten': 1,
 'three': 8,
 'seven': 4,
 'six': 5,
 'nine': 2,
 'two': 9,
 'five': 6,
 'one': 10}
In [251]:
sorted(freq)
Out[251]:
['eight', 'five', 'four', 'nine', 'one', 'seven', 'six', 'ten', 'three', 'two']
In [252]:
def get_freq(row):
    return row[1]

for k,v in sorted(freq.items(), key=get_freq):
    print(k, v)
ten 1
nine 2
eight 3
seven 4
six 5
five 6
four 7
three 8
two 9
one 10
In [253]:
for k,v in sorted(freq.items(), key=get_freq):
    print(k.ljust(5), v)
ten   1
nine  2
eight 3
seven 4
six   5
five  6
four  7
three 8
two   9
one   10
In [254]:
for k,v in sorted(freq.items(), key=get_freq, reverse=True):
    print(k.ljust(5), v)
one   10
two   9
three 8
four  7
five  6
six   5
seven 4
eight 3
nine  2
ten   1
In [257]:
for k,v in sorted(freq.items(), key=get_freq, reverse=True):
    print(k.rjust(5), str(v).ljust(2), "*"*v)
  one 10 **********
  two 9  *********
three 8  ********
 four 7  *******
 five 6  ******
  six 5  *****
seven 4  ****
eight 3  ***
 nine 2  **
  ten 1  *
In [ ]: