Sep 23-24, 2019 Vikrant Patil
These notes are available online at http://notes.pipal.in/2019/arcesium_basic_sep/day1.html
© Pipal Academy LLP
We will be using python 3 (>= 3.0) from anaconda for this training. You can download it from
bonus problems
>>> sumdigits(1111)
4
d = {True:1, False:0}
I = [[d[i==j] for i in range(5)] for j in range(5)]
I
sum([i for i in range(1000) if i%7==0 or i%11==0])
def column(data, c):
return [data[r][c] for r in range(len(data))]
def reversedcolumn(data, c):
return [data[r][c] for r in reversed(range(len(data)))]
def rotate90(data):
colcount = len(data[0])
return [reversedcolumn(data, c) for c in range(colcount)]
rotate90(I)
print(__name__)
for i in range(1, 11):
print(i, i*i, i**3)
for i in range(1, 11):
print(str(i).rjust(2), str(i*i).rjust(3), str(i**3).rjust(4))
w = 4
for i in range(1, 11):
print(str(i).rjust(w), str(i*i).rjust(w), str(i**3).rjust(w))
htmltemplate ="""
<html>
<header>
{HEADER}
</header
<body>
<p>
{CONTENTS}
</p>
</body>
</html>
"""
import this
poem = """
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!
"""
html = htmltemplate.format(HEADER="Zen of Python", CONTENTS=poem)
print(html)
"{} of oz is {}".format("Wizard", "Python")
"{1} of oz is {0}".format("Wizard", "Python")
"{wizard} of oz is {somebody}".format(wizard="Wizard", somebody="Python")
import jason
import json
json.dumps(I)
d = {"data":I, "attr1":"hello"}
d
jsonstring = json.dumps(d)
jsonstring
json.loads(jsonstring)
problems
>>> pascal(4)
[[1],[1,1],[1,2,1],[1,3,3,1]]
*
*
* *
* * *
* * * *
* * * * *
bonus
r = [1, 2, 1]
r1 = r[:]
r2 = r[:]
r1
r2
r1.append(0)
r2.insert(0, 0)
r1
r2
[i+j for i,j in zip(r1, r2)]
def nextrow(r):
r1 = r[:]
r2 = r[:]
r1 = r1 + [0]
r2 = [0] + r2
return [x+y for x,y in zip(r1, r2)]
nextrow([1])
def pascal(n):
t = [[1]]
for i in range(n-1):
prev = t[-1]
nextr = nextrow(prev)
t.append(nextr)
return t
pascal(5)
pascal(6)
"*"*5
["*"]*5
def triangle(base, char="*"):
return [ [char]*i for i in range(1, base+1)]
triangle(6)
def createrowstr(row):
return " ".join(row)
def pretty_print(triangle):
n = len(triangle[-1])
width = n + (n-1) # n for items, n-1 for spaces
for row in triangle:
line = createrowstr(row).center(width)
print(line)
def pretty_print(triangle(30))
def totext(data):
return [[str(item) for item in row] for row in data]
pretty_print(totext(pascal(5)))
pretty_print(totext(pascal(6)))
%%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!
with open("poem.txt") as f:
print(f.read())
with open("poem.txt") as f:
for line in f:
print(line, end="")
with open("poem.txt") as f:
for i, line in enumerate(f):
print(i+1, line, end="")
f = open("poem.txt")
f.readline()
f.readline()
f.readline()
f.readlines()
for line in f:
print(line, end="")
r = reversed(range(5))
for i in r:
print(i)
for i in r:
print(i)
problems
cat.py which prints contents of file to standard outputhead.py which prints first n lines of file.python head.py 3 poem.txt
The Zen of Python, by Tim Peters
Beautiful is better than ugly.
wc.py which mimics unix command wc. it should show linecount, wordcount and charcount.python wc.py poem.txt
21 144 857 poem.txt
tail.py which shows last n lines of file.python tail.py 3 poem.txt
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!
!wc poem.txt
!cat poem.txt
!head -n 5 poem.txt
!tail -n 5 poem.txt
%%file cat.py
import sys
def cat(filename):
with open(filename)as f:
print(f.read())
if __name__ == "__main__":
cat(sys.argv[1])
%%file head.py
import sys
def head(n, filename):
with open(filename) as f:
for i in range(n):
print(f.readline(), end="")
if __name__ == "__main__":
head(int(sys.argv[1]), sys.argv[2])
!python head.py 3 poem.txt
%%file wc.py
import sys
def linecount(file):
with open(file) as f:
return len(f.readlines())
def wordcount(file):
with open(file) as f:
return len(f.read().strip().split())
def charcount(file):
with open(file) as f:
return len(f.read())
if __name__ == "__main__":
f = sys.argv[1]
print(linecount(f), wordcount(f), charcount(f), f)
!python wc.py poem.txt
l = [1, 2, 3, 4, 5, 6, 7, 8]
l[2:]
l[:5]
l[:-3]
l[-3:]
n = len(l)
l[3-n:]
l[-3:]
%%file tail.py
import sys
def tail(file, n):
with open(file) as f:
lines = f.readlines()
for line in lines[-n:]:
print(line, end="")
def efficient_tail(file, n):
with open(file) as f:
window = [""]*n
for line in f:
window.append(line)
window.pop(0)
for line in window:
print(line, end="")
if __name__ == "__main__":
file = sys.argv[2]
n = int(sys.argv[1])
efficient_tail(file, n)
!python tail.py 4 poem.txt
l.pop?
"w" -> Write text->
"a" -> append text
"b" -> binary
"rb" -> read binary
"wb" -> write binary->
with open("numbers.txt", "w") as f:
f.write("one\n")
f.write("tow\n")
f.write("three\n")
!python cat.py numbers.txt
with open("numbers.txt", "w") as f: # this will over write existing contents
f.write("one\n")
f.write("two\n")
f.write("three\n")
!python cat.py numbers.txt
with open("numbers.txt", "a") as f:
f.write("four\n")
f.write("five\n")
!python cat.py numbers.txt
b'four'
person = {"name":"Alice",
"email":"alice@wonder.land",
"language":"english"
}
person['name']
person['country']
person.get("country","UK")
person
del person['email']
person
person['email'] = "alice@wonder.land"
%%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 three six seven
one two six seven eight
one six seven eight nine
six seven eight nine ten
six seven eight nine
six seven eight
six seven
six
def wordfreq(words):
freq = {}
for w in words:
if w in freq:
freq[w] += 1
else:
freq[w] = 1
return freq
def getwords(file):
with open(file) as f:
return f.read().strip().split()
words = getwords("words.txt")
wordfreq(words)
def wordfreq1(words):
freq = {}
for w in words:
freq[w] = freq.get(w, 0) + 1
return freq
wordfreq1(words)
def wordfreq2(words):
unique = set(words)
freq = {}
for w in unique:
freq[w] = words.count(w)
return freq
wordfreq2(words)
def wordfreq3(words):
unique = set(words)
return {w:words.count(w) for w in unique}
wordfreq3(words)
freq = wordfreq(words)
for w in sorted(freq):
print(w, freq[w])
for w in sorted(freq, key=lambda w: freq[w], reverse=True):
print(w, freq[w])
for w in sorted(freq, key=lambda w: freq[w], reverse=True):
print(w.rjust(5), freq[w])
for w in sorted(freq, key=lambda w: freq[w], reverse=True):
print(w.rjust(5), freq[w], freq[w]*"*")
for w in freq:
print(w)
for w,f in freq.items():
print(w.rjust(5), f, f*"*")
for f in freq.values():
print(f, end=",")
sorted([1, 2, 3, 4, 5], key=lambda x: 5)
names = ['Elsa',"Alex","Alice","Elisa"]
surnames = ["Frozen", "Lion","Wonder","Hacker"]
dict(zip(names, surnames))
problem
>>> loadconfig("config.cfg")
{"processor":"Corei5","os":"Mint","memory":"16GB"}
%%file config.cfg
processor=Corei5
os=mint
memory=16GB
def loadconfig(file):
with open(file) as f:
conf = {}
for line in f:
k,v = line.strip().split("=")
conf[k] = v
return conf
loadconfig("config.cfg")
def loadconfig(file):
with open(file) as f:
return dict([line.strip().split("=") for line in f])
loadconfig("config.cfg")
def loadconfig(file):
with open(file) as f:
return {k:v for k,v in [line.strip().split("=") for line in f]}
loadconfig("config.cfg")
tables = [[i*j for i in range(1,6)] for j in range(1,11)]
tables
problems
writecsv to write csv file for tabular data.
%%file data.csv
1,2,3,4,5
2,4,6,8,10
.
.
.
parsecsv to read csv file and load data as 2D list of integersdef writecsv(data, file):
with open(file, "w") as f:
for row in data:
line = ",".join([str(item) for item in row])
f.write(line)
f.write("\n")
writecsv(tables, "tables.csv")
!python cat.py tables.csv
def parsecsv(file):
with open(file) as f:
data = []
for line in f:
items = line.strip().split(",")
data.append([int(i) for i in items])
return data
parsecsv("tables.csv")
a = 10
def foo():
a = 20
print(a)
x = [1, 1, 1, 0]
def foo():
x = [0,0,0]
foo()
print(x)
x = [1, 1, 1]
def foo():
x.append(0)
foo()
print(x)
x = [1, 1, 1]
def foo():
x = x + [1]
foo()
print(x)
x = [1, 1, 1]
def foo():
x = [1]
foo()
print(x)
x = [1, 1, 1]
def foo(y):
y.append(0)
foo(x)
print(x)
%%file bank.py
balance = 0
def withdraw(amount):
global balance
balance -= amount
def deposit(amount):
global balance
balance += amount
def get_balance():
return balance
if __name__ == "__main__":
pass
import bank
bank.get_balance()
bank.deposit(10000)
bank.withdraw(2323)
bank.get_balance()
%%file bank1.py
def make_account():
return {"balance":0}
def get_balance(account):
return account['balance']
def withdraw(account, amount):
account['balance'] -= amount
def deposit(account, amount):
account['balance'] += amount
import bank1
a1 = bank1.make_account()
a2 = bank1.make_account()
bank1.deposit(a1, 10000)
bank1.deposit(a2, 2000)
bank1.withdraw(a1, 2323)
print(bank1.get_balance(a1))
print(bank1.get_balance(a2))
class BankAccount:
def __init__(self):
self.balance = 0
def get_balance(self):
return self.balance
def deposit(self, amount):
self.balance += amount
def withdraw(self, amount):
self.balance -= amount
a1 = BankAccount()
a1.get_balance()
a1.deposit(10000)
a1.withdraw(3243)
a1.get_balance()
a2 = BankAccount()
a2.deposit(23323)
a1.balance
a2.balance
class BankAccount:
def __init__(self):
self._balance = 0 # a convention for private attribute
def get_balance(self):
return self.balance
def deposit(self, amount):
self.balance += amount
def withdraw(self, amount):
self.balance -= amount
a1 = BankAccount()
a1._balance
a1.__dict__
class Foo:
pass
f = Foo()
f.x = 10
f.x
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
class RedPoint(Point):
color = "red"
p = Point(3, 4)
r1 = RedPoint(0, 0)
p.x,p.y
r1.x, r1.y
r1.color
r2 = RedPoint(5,6)
r2.color
RedPoint.color
RedPoint.color = "RED"
r1.color
r2.color
r2.color = "red"
RedPoint
r1.color
RedPoint.color
r1.__dict__
r2.__dict__
problem
Timer which will have following methods, start, stop, elapsed_time
t = Timer()
t.start()
task()
t.stop()
print("Time taken by taks:", t.elapsed_time())
`
import time
time.time()
class Timer:
def start(self):
self._start = time.time()
def stop(self):
self._end = time.time()
def reset(self):
self._start = 0
self._end = 0
def elapsed_time(self):
return self._end - self._start
t = Timer()
t.start()
time.sleep(2)
t.stop()
print("Time taken:",t.elapsed_time())
l
str(l)
class Pair:
def __init__(self, x, y):
self.x = x
self.y = y
def __repr__(self):
return "Pair({},{})".format(self.x, self.y)
def __str__(self):
return "<{},{}>".format(self.x, self.y)
p = Pair(2,3)
p
r1
Point(0,0)
print(p)
class Pair:
def __init__(self, x, y):
self.x = x
self.y = y
def __repr__(self):
return "Pair({},{})".format(self.x, self.y)
def __str__(self):
return "<{},{}>".format(self.x, self.y)
def __add__(self, p):
return Pair(self.x + p.x , self.y + p.y)
def __eq__(self, p):
return self.x==p.x and self.y==p.y
p1 = Pair(3,4)
p2 = Pair(5,6)
p1 + p2
p1 == p2
p3 = Pair(3, 4)
p1 == p3
p = Point(3, 4)
p
type(p)
type(p1)
isinstance(p1, Pair)
isinstance(p, Point)
isinstance(r1, Point)
class Pair:
def __init__(self, x, y):
self.x = x
self.y = y
def __repr__(self):
return "Pair({},{})".format(self.x, self.y)
def __str__(self):
return "<{},{}>".format(self.x, self.y)
def __add__(self, p):
return Pair(self.x + p.x , self.y + p.y)
def __eq__(self, p):
return self.x==p.x and self.y==p.y
def __getitem__(self, name):
if name == "x":
return self.x
elif name == "y":
return self.y
else:
raise KeyError("No such item", name)
p = Pair(4,5)
p['x']
p['y']
p['z']
type(1)
%matplotlib inline
from functools import reduce
from matplotlib.pyplot import imshow
class Shape:
def contains(self, p):
pass
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
class Rectangle(Shape):
def __init__(self, width, length):
self.w = width
self.l = length
def contains(self, p):
return p.x <= self.w and p.y <= self.l
class Circle(Shape):
def __init__(self, radius):
self.r = radius
def contains(self, p):
return (p.x**2 + p.y**2)**0.5 <= self.r
class Union(Shape):
def __init__(self, shapes):
self.shapes = shapes
def contains(self, p):
conds = [s.contains(p) for s in self.shapes]
return reduce(lambda x,y: x or y, conds, False)
class Intersection(Shape):
def __init__(self, shapes):
self.shapes = shapes
def contains(self, p):
conds = [s.contains(p) for s in self.shapes]
return reduce(lambda x,y: x and y, conds, True)
class Canvas:
def __init__(self, w=1000, l=1000):
self.w = w
self.l = l
self.display = [[False for i in range(w)] for j in range(l)]
def draw(self, shape):
def translate(p):
return Point(self.w//2 - p.x, self.l//2 -p.y)
self.display = [[shape.contains(translate(Point(i,j))) for i in range(self.w)] for j in range(self.l)]
def plot(self):
imshow(self.display)
c = Circle(50)
canvas = Canvas(100,100)
canvas.draw(c)
canvas.plot()
c1 = Circle(50)
r1 = Rectangle(10, 120)
u = Union([c1, r1])
inter = Intersection([c1, r1])
canvas = Canvas(200, 200)
canvas.draw(u)
canvas.plot()
canvas = Canvas(200, 200)
canvas.draw(inter)
canvas.plot()
import openpyxl