March 27-31, 2017
Anand Chitipothu
These notes are available online at https://notes.pipal.in/2017/symantec
© Pipal Academy LLP
if Statementfor loopimport time
time.asctime()
from time import asctime
asctime()
Q: Where is the time module located? How will Python finds it?
import sys
sys.path
Let us try with os module.
import os
os.__file__
The __file__ is a special attribute available on modules, which provides the path to the module.
Now let us write a small program that uses the time module.
%%file date.py
import time
print(time.asctime())
!python date.py
Let us now look at couple of standard library modules.
os module¶import os
# get the current working directory
os.getcwd()
# all files in the current directory
os.listdir(".")
Problem: Write a function count_files that takes path to a directory as argument and returns the number of files it has.
>>> count_files(".")
16
>>> count_files("/tmp")
9
def count_files(path):
files = os.listdir(path)
return len(files)
count_files(".")
count_files("/tmp")
# you can even write the function body in a single line
def count_files(path):
return len(os.listdir(path))
count_files(".")
%%file args.py
import sys
print(sys.argv)
There is a special variable argv in the sys module that holds all the command-line arguments passed to the program.
!python args.py hello world
By convention, the first element of sys.argv is the program name.
!python args.py hello
!python args.py "hello world"
!python args.py 1 2 3 4 5
Remember that the arguments will always be strings.
Let us write a simple echo program that prints back the first command-line argument.
%%file echo.py
import sys
print(sys.argv[1])
!python echo.py hello
# even if we pass more arguments, it prints only the first one.
!python echo.py hello world
Q: How to print two arguments?
%%file echo2.py
import sys
print(sys.argv[1], sys.argv[2])
!python echo2.py hello world
%%file echo2a.py
import sys
arg1 = sys.argv[1]
arg2 = sys.argv[2]
print(arg1, arg2)
!python echo2a.py hello world
Problem: Write a program square.py that takes a number as command-line argument and prints its square.
$ python square.py 4
16
%%file square.py
import sys
n = int(sys.argv[1])
print(n*n)
!python square.py 4
age = 30
age > 25
age <= 25
name = "Alice"
name == "Alice"
name == "Alice" and age > 25
Python has in operator to check if an element is part of another.
"hell" in "hello"
"yell" in "hello"
"yell" not in "hello"
"a" in ["a", "b", "c", "d"]
vowels = ["a", "e", "i", "o", "u"]
def is_vowel(c):
return c in vowels
is_vowel('x')
is_vowel('e')
Strings have some useful methods for prefix and suffix checking.
"hello".startswith("hell")
"hello".endswith("lo")
def is_python_file(filename):
return filename.endswith(".py")
is_python_file("square.py")
is_python_file("square.c")
if Statement¶n = 34
if n % 2 == 0:
print("even")
else:
print("odd")
def check_even(n):
if n % 2 == 0:
print("even")
else:
print("odd")
check_even(34)
check_even(35)
def check_number(n):
if n < 10:
print(n, "is a single digit number")
elif n < 100:
print(n, "is a two digit number")
else:
print(n, "is a big number")
check_number(4)
check_number(45)
check_number(456)
Problem: Write a function minimum to compute minimum of two numbers, without using the built-in function min. The function should return the minimum of the two numbers passed as arguments to it.
>>> minimum(3, 5)
3
>>> minimum(5, 3)
3
>>> minimum(3, 5) + 1
4
Let us look at the following program.
def square1(x):
return x*x
def square2(x):
print(x*x)
print(square1(4))
square2(4)
Which of the above two functions is better and why?
When a function returns a value, it can be used in other computations.
x = square1(4)
print(x+1)
square1(4) + 1
square1(square1(4))
def minimum(x, y):
if x < y:
return x
else:
return y
minimum(3, 4)
minimum(4, 3)
minimum(3, 4) + 10
x = ["a", "b", "c", "d"]
len(x)
x[0]
x[1]
for a in x:
print(a)
Remember that the body of for is indented.
names = ["Alice", "Bob", "Charlie"]
for name in names:
print("Hello", name)
Python has a built-in function range to iterate over a sequence of numbers.
for i in range(5):
print(i)
range(n) gives numbers from 0 ... n-1.
# numbers from 2 to 5 (end is not included)
for i in range(2, 5):
print(i)
def say_hello(name, n):
for i in range(n):
print("Hello", name)
say_hello("Python", 4)
Problem: The os.listdir function takes path to a directory as argument and returns all the files in that directory as a list. Write a program ls.py that takes path to a directory as command-line argument and prints files in that directory, one per line.
$ python ls.py .
date.py
day1.ipynb
day1.html
day2.ipynb
day2.html
square.py
$ python ls.py /tmp
a.txt
b.txt
Python has a built-in function sum to compute sum of a list of numbers.
sum([1, 2, 3, 4])
Let us try to implement our own sum function.
def my_sum(numbers):
result = 0
#print("BEGIN my_sum", numbers)
#print("result 0")
for n in numbers:
result = result + n
#print("n", n)
#print("result", result)
return result
my_sum([1, 2, 3, 4])
# sum of all numbers below a million
my_sum(range(100000))
Problem: Write a function product to compute product of given numbers.
>>> product([1, 2, 3, 4])
24
x = ["a", "b", "c", "d"]
x
x[1]
x[1] = 'bb'
x
x.append('e')
x
Remember that the append method doesn't return anything, but modifies the list in-place.
Let us write a program to compute squares of all numbers in a list.
def squares(numbers):
result = []
for n in numbers:
result.append(n*n)
return result
print(squares([1, 2, 3, 4]))
# sum of squares of all numbers below one million
sum(squares(range(1000000)))
Problem: Write a function evens that takes a list of numbers as arguments and returns a new list containing only the even numbers from it.
>>> evens([1, 2, 3, 4, 5, 6])
[2, 4, 6]
def evens(numbers):
result = []
for n in numbers:
if n % 2 == 0:
result.append(n)
return result
evens([1, 2, 3, 4, 5, 6])
x = [1, 2, 3, 4, 5, 6]
[a*a for a in x]
[a*a for a in x if a%2 == 0]
Compute sum of squares of all numbers below a million.
sum([n*n for n in range(1000000)])
List comprehensions are usually written as:
[expr for var in alist]
This creates a new list.
def squares(numbers):
result = [n*n for n in numbers]
return result
squares([1, 2, 3, 4])
def squares(numbers):
return [n*n for n in numbers]
print(squares([1, 2, 3, 4]))
Problem: Write a function list_pyfiles that takes path a directory as argument and returns all python files from that directory.
>>> list_pyfiles(".")
['square.py', 'args.py', 'echo.py']
numbers = [1, 2, 3, 4, 5, 6]
even_numbers = [n for n in numbers if n%2 == 0]
print(even_numbers)
import os
def list_pyfiles(path):
files = os.listdir(path)
return [f for f in files if f.endswith(".py")]
list_pyfiles(".")
def list_pyfiles(path):
return [f for f in os.listdir(path) if f.endswith(".py")]
list_pyfiles(".")
There is os.path.getsize function to find size of a file.
os.path.getsize("args.py")
How to compute total size of all python files in the current directory?
[f for f in os.listdir(".") if f.endswith(".py")]
[os.path.getsize(f) for f in os.listdir(".") if f.endswith(".py")]
sum([os.path.getsize(f) for f in os.listdir(".") if f.endswith(".py")])
x = ["a", "b", "c", "d"]
for c in x:
print(c, c.upper())
[c.upper() for c in x]
for i in range(5):
print(i, i*i)
for i in range(2, 5):
print(i, i*i)
[i*i for i in range(5)]
Given names and scores of students, how to print name and score of each student.
names = ["A", "B", "C", "D"]
scores = [10, 20, 30, 40]
for name, score in zip(names, scores):
print(name, score)
zip(names, scores)
list(zip(names, scores))
Q: What happens if one list is shorter?
list(zip(["A", "B", "C", "D"], [10, 20, 30]))
It considers the smallest length.
Q: Is it possible to zip more than two lists?
Yes.
names
list(zip(names, names, names))
Problem: Write a function vector_add to add two vectors.
>>> vector_add([1, 2, 3, 4], [10, 20, 30, 40])
[11, 22, 33, 44]
# traditional way
def vector_add(A, B):
C = []
for a, b in zip(A, B):
C.append(a+b)
return C
vector_add([1, 2, 3, 4], [10, 20, 30, 40])
# list-comprehensions approach
def vector_add(A, B):
return [a+b for a, b in zip(A, B)]
vector_add([1, 2, 3, 4], [10, 20, 30, 40])
names = ["a", "b", "c", "d"]
for i, name in enumerate(names):
print(i, name)
list(enumerate(names))
chapters = ["Getting Started", "Lists", "Working with Files"]
for i, title in enumerate(chapters):
print("Chapter", i+1, ":", title)
for i, title in enumerate(chapters, start=1):
print("Chapter", i, ":", title)
x = ["a", "b", "c", "d", "e"]
x[0]
x[1]
How to get the last element of x?
x[len(x)-1]
Python has a short hand for that.
x[-1] # last element
x[-2] # second last element
Let us try an example.
def get_last_word(sentence):
return sentence.split()[-1]
get_last_word("one two three")
x = ["a", "b", "c", "d", "e", "f", "g", "h"]
x[0:2]
x[:2] # up to index 2
The end in not included.
x[2:] # index 2 onwards
x[2:6] # from index 2 to index 6
x[1:6:2] # take every second element from index 1 to 6
x[:] # copy of the list
x[::-1] # reverse the list
Earlier we wrote a program to print the first command-line argument. Let us improve that to print all command-line arguments.
%%file echo2.py
import sys
#print(sys.argv)
args = sys.argv[1:]
#print(args)
print(" ".join(args))
!python echo2.py hello world