Dec 19-21, 2019 Vikrant Patil, Anand Chitipothu
These notes are available online at http://notes.pipal.in/2019/grofers_basic_dec/day2.html
© Pipal Academy LLP
We will be using python 3 (>= 3.0) from anaconda for this training. You can download it from
def is_palindrome(text):
return text == text[::-1]
is_palindrome("madam")
import os
os.getcwd()
os.listdir("/home/vikrant/trainings/2019/grofers_basic_dec/")
os.listdir()
problems
ls.py which lists files in given directory
python ls.py /home/vikrant/trainings/2019/grofers_basic_dec/
day1.html
day1.ipynb
.
.
squares to find squares of given list
>>> squares([1,2,3])
[1,4,9]
evens to find even numbers from given listdef mysum(nums):
s = 0
for n in nums:
s += n
return s
%%file ls.py
import os, sys
def ls(path):
files = os.listdir(path)
for file in files:
print(file)
if __name__ == "__main__":
ls(sys.argv[1])
!python ls.py .
%%file ls1.py
import os, sys
def ls(path):
files = os.listdir(path)
for file in files:
print(file)
if __name__ == "__main__":
if len(sys.argv)==1:
path = os.getcwd()
else:
path = sys.argv[1]
ls(path)
!python ls1.py
!python ls1.py "/tmp"
def squares(nums):
sqrs = []
for n in nums:
sqrs.append(n*n)
return sqrs
def print_squares(nums):
sqrs = squares(nums)
print("Original list:", end=" ")
for n in nums:
print(n, end=" ")
print("Squared list:")
for s in sqrs:
print(s, end=" ")
print_squares([2,3,4,5])
%%file listoperations.py
def squares(nums):
"""
>>> squares([])
[]
>>> squares([-1, 1, 2])
[1, 1, 4]
"""
sqrs = []
for n in nums:
sqrs.append(n*n)
return sqrs
def evens(nums):
def even(x):
return x%2==0
evens_ = []
for n in nums:
if even(n):
evens_.append(n)
return evens_
!python -m doctest -v listoperations.py
problem
test_lists.py which writes assert tests for list_operations module and test it using pytestnums = [1,2,3,5,8,13]
[n*n for n in nums]
[n**3 for n in nums]
def even(x):
return x%2==0
[n for n in nums if even(n)]
[n*n for n in nums if even(n)]
problem decomposition and lists comprehensions*
def factors(n):
return [i for i in range(1,n+1) if n%i==0]
factors(12)
factors(5)
factors(7)
def is_prime(p):
return len(factors(p))==2
def primes(n):
"""
generate prime numbers less than
"""
return [p for p in range(1, n) if is_prime(p)]
primes(50)
problems
filterpy to filter out only py files from given directory
>>> filterpy(path)
a.py
b.py
filter_by_ext
filter_by_ext(path, ext)
4==3 or 4%2==0 and 1==1
sum([1,2,3,4])
e = []
for i in range(n):
e.append(do(i))
Above loop translates to list comprehesnion as below
[do(i) for i in range(n)]
=======================================================
e = []
for i in range(n):
if cond(i):
e.append(do(i))
Above loop translates to list comprehesnion as below
[do(i) for i in range(n) if cond(i)]
sum([i for i in range(1,1000) if i%7==0 or i%11==0])
def filter_py(path):
files = os.listdir(path)
return [file for file in files if file.endswith(".py")]
def filter_by_ext(path, ext):
files = os.listdir(path)
return [file for file in files if file.endswith(ext)]
def filter_py1(path):
return filter_by_ext(path, ".py")
tables = [[i*j for i in range(1,6)] for j in range(1,11)]
tables
tables[0]
tables[-1]
tables[:]
tables[2:]
tables[0]
tables[0][2]
tables[1][2]
tables[2][2]
def column(data, colnum):
return [data[i][colnum] for i in range(len(data))]
column(tables, 2)
tables
def transpose(data):
colcount = len(data[0])
return [column(data, c) for c in range(colcount)]
transpose(tables)
nums = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]
for n in nums:
print(n, end=",")
for i, n in enumerate(nums[:5]):
print(i, n)
lines = """first line
second line
third line
fourth line
""".strip().split("\n")
lines
for linum, line in enumerate(lines, start=1):
print(linum, line)
x, y = 1,2
enumerate(lines)
list(enumerate(lines))
list(enumerate(lines, start=1))
for line in reversed(lines):
print(line)
for i in reversed(range(5)):
print(i)
first = ["Elsa", "Alice", "Elisa"]
second = ["Frozen", "Wonder", "Hacker"]
for f, s in zip(first, second):
print(f, s)
a = [1, 2, 3, 4]
b = ['a','b','c']
for i, j in zip(a,b):
print(i,j)
items = ["Daliya", "Rava", "Rice"]
quantities = [2,1,3]
prices = [32, 40, 50]
for item, qty,price in zip(items, quantities, prices):
print(item, qty, price)
items = ["Daliya", "Rava", "Rice"]
quantities = [2,1,3]
prices = [32, 40, 50]
for item, qty,price in zip(items, quantities, prices):
print(item.rjust(6), qty, price)
r = reversed([1, 2, 3, 4]) # is only for one time use!
for i in r:
print(i, end=" ")
for i in r:# is only for one time use!
print(i, end=" ")
problems
>>> vector_add([1, 2, 3], [1, 1, 1])
[2, 3, 4]
def vector_add(vector1, vector2):
return [a+b for a,b in zip(vector1, vector2)]
vector_add([2, 3, 4, 5], [1, 1, 1, 1])
for i in range(1, 11):
print(i, i**2, i**3)
for i in range(1, 11):
print(str(i).rjust(2), str(i**2).rjust(3), str(i**3).rjust(4))
"Answer to {} is {}".format("life", 42)
"Answer to {1} is {0}".format("life", 42)
"Wizard of {place} is {name}".format(place="oz", name="python")
template = """
<html>
<header>
{HEADER}
</header>
<body>
{BODY}
</body>
</html>
"""
print(template.format(HEADER="Post1", BODY="Contests of Post1"))
for i in range(1, 11):
print("{num:2} {sqr:3} {cube:4}".format(num=i, sqr=i*i, cube=i**3))
for i in range(1, 11):
print("{num:{w}} {sqr:{w}} {cube:{w}}".format(num=i, sqr=i*i, cube=i**3, w=4))
def make_triangle(n):
return ["*"*row for row in range(1, n+1)]
make_triangle(5)
for row in make_triangle(5):
print(row)
"helo".center(10)
def prety_print(triangle):
width = len(triangle[-1])
for row in triangle:
print(row.center(width))
prety_print(make_triangle(10))
def format_row(row):
return " ".join(list(row))
def prety_print(triangle):
base = len(triangle[-1])
width = base + base -1
for row in triangle:
row_ = format_row(row)
print(row_.center(width))
prety_print(make_triangle(10))
def make_triangle(n, char="*"):
return [char*row for row in range(1, n+1)]
make_triangle(10, "@")
prety_print(make_triangle(10, "@"))
problem
>>> pascal(4)
[[1],[1,1],[1,2,1],[1,3,3,1]]
11**4
11**5
%%file pascal.py
def get_next_row(row):
r1 = [0] + row[:]
r2 = row[:] + [0]
return [a+b for a,b in zip(r1, r2)]
def test_get_next_row():
assert get_next_row([1]) == [1,1]
assert get_next_row([1,1]) == [1,2,1]
assert get_next_row(get_next_row([1])) == [1,2,1]
!pytest pascal.py
%%file pascal1.py
def pascal(n):
tr = [[1]]
for i in range(n-1):
last = tr[-1]
tr.append(get_next_row(last))
return tr
def test_pascal():
assert pascal(1) == [[1]]
assert pascal(2) == [[1],[1,1]]
assert pascal(3) == [[1],[1,1],[1,2,1]]
def get_next_row(row):
r1 = [0] + row[:]
r2 = row[:] + [0]
return [a+b for a,b in zip(r1, r2)]
def test_get_next_row():
assert get_next_row([1]) == [1,1]
assert get_next_row([1,1]) == [1,2,1]
assert get_next_row(get_next_row([1])) == [1,2,1]
!pytest pascal1.py
from pascal1 import pascal
pascal(5)
def print_pascal(n):
pascal_t = pascal(n)
def format_row(row, boxwidth):
return " ".join([f"{r:{boxwidth}}" for r in row])
maxnum = max(pascal_t[-1])
boxwidth = len(str(maxnum))
length = len(pascal_t[-1])
width = boxwidth*length + length -1
for row in pascal_t:
row_ = format_row(row, boxwidth)
print(row_.center(width))
print_pascal(5)
print_pascal(12)
import this
%%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 file:
print(file.read())
with open("poem.txt") as file:
for line in file:
print(line)
with open("poem.txt") as file: # with statement makes sure that file
for line in file: # is closed after with block
print(line, end="")
file = open("poem.txt")
file.readline()
file.readline()
file.read()
file.read()
file.readline()
file.close()
with open("poem.txt") as f:
line = f.readline()
while line:
print(line, end="")
line = f.readline()
if '':
print("false")
else:
print("True")
%%file small.txt
one
two
three
f = open("small.txt")
f.readline()
f.readline()
f.readline()
f.readline()
f.close()
with open("small.txt") as f:
while f.readline():
pass
with open("small.txt") as f:
for line in f:
print(line, end="")
problems
revered_lines to print every line in reversed fashion
>>> reversed_line("small.txt")
eno
owt
eerht
cat.py which mimics unix command cathead.py which mimics unix command headtail.py which prints last five lines of a file.!head -n 5 poem.txt
!tail -n 5 poem.txt
def lines_nums(filename):
with open(filename) as f:
for linum, line in enumerate(f, start=1):
print(linum, line, end="")
lines_nums("poem.txt")
def reversed_lines(filename):
with open(filename) as f:
for line in f:
print(line.strip()[::-1])
reversed_lines("poem.txt")
with open("poem.txt") as f:
lines = f.readlines()
for line in lines:
print(line.strip()[::-1])
%%file cat.py
import sys
def cat(filename):
with open(filename) as f:
print(f.read())
if __name__ == "__main__":
cat(sys.argv[1])
!python cat.py poem.txt
!cat small.txt poem.txt
%%file cat.py
import sys
def cat_(files):
for file in files:
cat(file)
def cat(filename):
with open(filename) as f:
print(f.read())
if __name__ == "__main__":
cat_(sys.argv[1:])
!python cat.py small.txt poem.txt
!python cat.py small.txt
%%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
nums[-5:]
nums
def tail(filename, n):
window = []
with open(filename) as f:
for i in range(n):
window.append(f.readline())
line = f.readline()
while line:
window.pop(0)
window.append(line)
line = f.readline()
for l in window:
print(l, end="")
tail("poem.txt", 5)
!pytest pascal1.py
!pip install pytest-cov pytest-benchmark
!pytest --capture=no --cov=.
Write a function to find unique items from a list, while keeping the order
%%file unique.py
def unique(seq):
seen = []
u = []
for item in seq:
if item not in seen:
u.append(item)
seen.append(item)
return u
def unique1(seq):
seen = set()
u = []
for item in seq:
if item not in seen:
u.append(item)
seen.add(item)
return u
def test_bechmark_unique(benchmark):
benchmark(unique, range(10000))
def test_bechmark_unique1(benchmark):
benchmark(unique1, range(10000))
!pytest -vv unique.py
%%file words.py
def get_words(file):
with open(file) as f:
return f.read().strip().split()
%%file test_words.py
import pytest
from words import get_words
import os
@pytest.fixture
def wordfile():
path = "/tmp/wordcounttest.txt"
with open(path, "w") as f:
f.write("one two three")
print("Setup.....")
yield path
print("Teardown...")
os.remove(path)
def test_words(wordfile):
print("[Test]:", wordfile)
assert get_words(wordfile)==["one","two","three"]
!pytest -vv --capture=no test_words.py
person = {"name":"Vikrant",
"email":"vikrant@pipalacademy",
"address":"Pune"}
person['name']
person['company']
person.get("company", "Pipal Academy")
person
person.get("company")
print(person.get("company"))
for key in person:
print(key)
for key in person:
print(key, person[key])
for value in person.values():
print(value)
for key, value in person.items():
print(key, value)
%%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
seven eight nine ten
eight nine ten
nine ten
ten
def get_words(filename):
with open(filename) as f:
return f.read().strip().split()
def wordfreq(words):
freq = {}
for w in words:
if w not in freq:
freq[w] = 1
else:
freq[w] +=1
return freq
def wordfreq1(words):
freq = {}
for w in words:
freq[w] = freq.get(w, 0) + 1
return freq
def wordfreq2(words):
uniq = set(words)
for w in uniq:
freq[w] = words.count(w)
return freq
words = get_words("words.txt")
freq = wordfreq1(words)
freq
for word in sorted(freq,key=lambda w: freq[w]):
print(word, freq[word])
def get_freq(w):
return freq[w]
for word in sorted(freq,key=get_freq, reverse=True):
print(word, freq[word])
for word, f in sorted(freq.items(),key=lambda r: r[1], reverse=True):
print(word, freq[word])
for word, f in sorted(freq.items(),key=lambda r: r[1], reverse=True):
print(word.rjust(5), f, "*"*f)
%%file weekday.py
import datetime
def now():
return datetime.datetime.now()
def weekday():
t = now()
return t.strftime("%A")
if __name__ == "__main__":
print(weekday())
!python weekday.py
%%file test_weekday.py
import weekday
import datetime
def test_weekday(monkeypatch):
faketime = 2010, 1, 1
def fakenow():
return datetime.datetime(*faketime)
monkeypatch.setattr(weekday, "now", fakenow)
faketime = 2010, 1, 1
assert weekday.weekday() == "Friday"
faketime = 2010, 1, 2
assert weekday.weekday() == "Saturday"
!pytest test_weekday.py