Nov 20-22, 2017 Vikrant Patil
These notes will be available online at http://notes.pipal.in/2017/vmware-nov-advpython/ after this training!
© Pipal Academy LLP
%%file functions.py
def cat(filename):
"""
prints given file to standard output
"""
print(open(filename).read())
def head(filename, n):
"""
prints first n lines from given file to standard output
"""
with open(filename) as f:
for i in range(n):
print(f.readline(), end="")
def grep(pattern, filename):
"""
looks for pattern in given file
"""
for line in open(filename):
if pattern in line:
print(line.strip())
import functions
functions.head("day1.html", 3)
functions.grep("html", "day1.html")
s = " hello \n"
print(s)
s.strip()
%%file cmdline.py
import sys
commands = {}
def command(f):
commands[f.__qualname__] = f
return f
def main():
cmdname = sys.argv[1]
args = sys.argv[2:]
cmd = commands[cmdname]
cmd(*args)
%%file function_commands.py
from cmdline import command, main
@command
def cat(filename):
"""
prints given file to standard output
"""
print(open(filename).read())
@command
def head(filename, n):
"""
prints first n lines from given file to standard output
"""
with open(filename) as f:
for i in range(n):
print(f.readline(), end="")
@command
def grep(pattern, filename):
"""
looks for pattern in given file
"""
for line in open(filename):
if pattern in line:
print(line.strip())
if __name__ == "__main__":
main()
!python function_commands.py cat data.csv
!python function_commands.py grep def cmdline.py
functions.grep.__doc__
%%file cmdline.py
import sys
commands = {}
def command(f):
commands[f.__qualname__] = f
return f
def help_():
print("Following commands are available")
for name, func in commands.items():
print(name.rjust(6), ":" ,func.__doc__.strip())
def main():
cmdname = sys.argv[1]
if cmdname == "help":
help_()
else:
args = sys.argv[2:]
cmd = commands[cmdname]
cmd(*args)
!python function_commands.py help
@with_retries(retries=5, dealy=0.1)
def wget(url):
...
@debug(prefix)
def fib(n):
@login_required(role="admin")
def edit_interface(..)
import time
def with_retries(retries=5, delay=0):
def decor(f):
def wrapper(*args):
print("retires = {0}, delay ={1}".format(retries, delay))
for i in range(retries):
try:
return f(*args)
except Exception as e:
print(f.__name__, args, "failed:", e)
time.sleep(delay)
print("Giving up!")
return wrapper
return decor
from urllib.request import urlopen
@with_retries(retries=3, delay=0.5)
def wget(url):
response = urlopen(url)
if response:
return response.read()
wget("http://google.com/nosuchpage")
#ddecor_fun = with_retries()
#wget ddecor_fun(wget)
from functools import partial
import time
def with_retries(f=None, retries=5, delay=0):
if f is None:
return partial(with_retries, retries=retries, delay=delay)
def g(*args):
print("retires = {0}, delay ={1}".format(retries, delay))
for i in range(retries):
try:
return f(*args)
except Exception as e:
print(f.__name__, args, "failed:", e)
time.sleep(delay)
print("Giving up!")
return g
from urllib.request import urlopen
@with_retries(retries=3, delay=0.5)
def wget(url):
response = urlopen(url)
if response:
return response.read()
wget("http://google.com/noptapage")
import fib
help(fib.fib)
!cat fib.py
from fib import fib
fib.__name__
help(fib)
from functools import wraps
def debug(f):
@wraps(f)
def wrapper(*args):
print("DEBUG ", f.__name__)
return f(*args)
return wrapper
@debug
def add(x,y):
"""
adds two entities
"""
return x+y
help(add)
add.__name__
for n in [1,2,3,4,5]:
print(n)
for s in "string":
print(s)
for key in {"one":1, "two":2}:
print(key)
%%file nums.txt
one
two
three
four
for line in open("nums.txt"):
print(line.strip())
items = [1,2,3]
itr = iter(items)
next(itr)
next(itr)
next(itr)
next(itr)
def squares(n):
for i in range(1,n+1):
yield i*i
sqr = squares(4)
next(sqr)
for s in sqr:
print(s)
def squares(n):
print("inside squares")
for i in range(1,n+1):
print("Computing square of ", i)
yield i*i
print("back after yield")
print("Finished squares")
sqr4 = squares(4)
sqr4
next(sqr4)
next(sqr4)
next(sqr4)
next(sqr4)
next(sqr4)
for i in squares(4):
print(i)
def f():
for i in range(10000):
if i==6:
return
yield i*i
g = f()
for item in g:
print(item)
problem Write a generator countdown which will take a number n as argument and generate sequence of integers starting from n and ending at 1
>>> for i in countdown(3):
... print(i)
3
2
1
problem Write a generator triangular that takes a number n as argument and generate sequence of first n triangular numbers. nth triangular number is sum of first n natural numbers.
>>> for t in triangular(5):
... print(t, end=",")
1,3,6,10,15
bonus problem : remove duplicates from a sequence while maintaining the order. can same generators be used to remove duplicate lines from a file?
>>> for item in consumedup([3,5,3,4,5,6,7,8,8,9])
... print(item, end=",")
3,5,4,6,8,9,
def countdown(n):
while n >0:
yield n
n -= 1
for i in countdown(5):
print(i, end=",")
def triangular(n):
for i in range(1, n+1):
yield sum(range(1,i+1))
for t in triangular(10):
print(t, end=",")
def consumedup(seq):
seen = set()
for item in seq:
if item not in seen:
yield item
seen.add(item)
"".join([c for c in consumedup("This statement has few chars repeated!")])
[n*n for n in range(1,11)]
s = (n*n for n in range(1,100000000))
next(s)
for item in s:
if item == 625:
break
print(item, end=",")
next(s)
sum(s)
def cdown(n):
return (n-i for i in range(n))
for i in cdown(10):
print(i, end=",")
sum((n*n for n in range(1,10)))
sum(n*n for n in range(1,10))
import os
def find(root):
for path, dirnames, filenames in os.walk(root):
for f in filenames:
yield os.path.join(path, f)
def take(n , seq):
it = iter(seq)
return list([next(it) for i in range(n)])
def integers():
"""
generates infinite sequence of natural numbers
"""
i = 0
while True:
yield i
i += 1
def squares(numbers):
return (n*n for n in numbers)
take(10, squares(integers()))
def grep(pattern, seq):
return (x for x in seq if pattern in x)
files = find(".")
pyfiles = grep(".py", files)
print(take(10, pyfiles))
def count(seq):
i = 0
for x in seq:
i += 1
return i
count(range(10))
files = find(".")
pyfiles = grep(".py", files)
print(count(pyfiles))
def readlines(filenames):
"""
gives iterator over lines in all files in filenames
"""
for f in filenames:
for line in open(f):
yield line
files = find(".")
pyfiles = grep(".py", files)
lines = readlines(pyfiles)
print(count(lines))
files = find(".")
pyfiles = grep(".py", files)
lines = readlines(pyfiles)
functions = grep("def ", lines)
print(count(functions))
!yes "hello python this is python" | head -n 10000000 > /tmp/big1.txt
!yes "hello python this is python" | head -n 10000000 > /tmp/big2.txt
!yes "hello python this is python" | head -n 10000000 > /tmp/big3.txt
!yes "hello python this is python" | head -n 10000000 > /tmp/big4.txt
!yes "hello python this is python" | head -n 10000000 > /tmp/big5.txt
!echo "somepattern" >> /tmp/big5.txt
lines = readlines(grep(".txt", find("/tmp")))
take(1, grep("somepattern", lines))
problem Write a function get_paragraphs to split given text into paragraphs. The function sholuld take a sequence of lines as argument and return a sequence of paragraphs.
paragraphs are seperated by empty lines.
sample data is http://anandology.com/tmp/pg1342.txt
once the function is ready , we should be able to find
def get_paragraphs(lines):
para = []
for line in lines:
if line.strip()=="":
if para:
yield "".join(para)
para = []
else:
para.append(line)
if para:
yield "".join(para)
p = get_paragraphs(open("pg1342.txt"))
p
count(p)
p = get_paragraphs(open("pg1342.txt"))
max(p, key=len)
!ls
!ls /home/
!cp day1.html /tmp/
!ls -l
!ls --help
%%file fib.py
import argparse
def fib(n):
prev, current = 1, 1
for i in range(2, n):
current, prev = prev+current, current
return current
def parse_args():
p = argparse.ArgumentParser()
p.add_argument("n", help="n for computing nth fibonacci number",
type=int)
return p.parse_args()
def main():
args = parse_args()
print(args)
print(fib(args.n))
if __name__ == "__main__":
main()
!python fib.py
!python fib.py -h
!python fib.py 10
%%file fib.py
import argparse
def fib(n):
prev, current = 1, 1
for i in range(2, n):
current, prev = prev+current, current
return current
def print_fiblist(n):
prev, current = 1, 1
for i in range(2, n):
current, prev = prev+current, current
print(current, end=" ")
def parse_args():
p = argparse.ArgumentParser()
p.add_argument("n", help="n for computing nth fibonacci number",
type=int)
p.add_argument("-s", "--sequence",
help="Print sequence",
action="store_true")
return p.parse_args()
def main():
args = parse_args()
if args.sequence:
print_fiblist(args.n)
else:
print(fib(args.n))
if __name__ == "__main__":
main()
!python fib.py -h
!python fib.py -s 10
!python fib.py 10
import re
pattern = re.compile("^def")
s = "def "
m = pattern.match(s)
print(m)
s = " def "
m = pattern.match(s)
print(m)
s = """
def add(x,y):
def should start at start of line
return x+y
defination of add is shown above
"""
[line for line in s.split("\n") if pattern.match(line)]
pattern = re.compile("[a-zA-Z]{5,10}[\d]{2}$")
print(pattern.match("hello"))
print(pattern.match("hello12"))
print(pattern.match("hello123"))
print(list(range(5)))
str(list(range(3)))
p = re.compile("\[(\d), (\d), (\d)\]")
l = str(list(range(3)))
l
m = p.match(l)
m
m.groups()
import sqlite3
conn = sqlite3.connect("a.db")
cur = conn.cursor()
result = cur.execute("select * from person")
result.fetchall()
def find_person(email):
#not right way to do?
q = "select * from person where email='{}'".format(email)
print(q)
cur = conn.cursor()
result = cur.execute(q)
return result.fetchall()
find_person("alice@example.com")
def find_person(email):
query = "select * from person where email=?"
cur = conn.cursor()
result = cur.execute(query, (email, ))
return result.fetchall()
find_person("alice@example.com")
def query(conn, querystring, params):
cur = conn.cursor()
result = cur.execute(querystring, params)
return result.fetchall()
query(conn, "select * from person where name=?", params=("alice",))
conn.close()
conn = sqlite3.connect("a.db")
cur = conn.cursor()
persons = [
("dilbert", "dilbert@dilbert.com"),
("calvin", "calvin@calvinhobes.com"),
("jerry", "jerry@disney.com")
]
cur.executemany("insert into person values(?,?)", persons)
conn.commit()
conn.close()
conn = sqlite3.connect("a.db")
cur = conn.cursor()
for name, email in cur.execute("select * from person ORDER by name"):
print(name.rjust(10), email)