Python Training - Vizag Interns

May 30 - June 1, 2017
Anand Chitipothu

These notes are available online at https://notes.pipal.in/2017/vizag-interns

© Pipal Academy LLP

Home | Day 1 | Day 2 | Day 3

Problem: Greet in random language

In [1]:
import random

def say_hello(name):
    hello_options = ["Namaskaram", "Hello", "Vanakkam", "Namaskar"]
    hello = random.choice(hello_options)
    print(hello, name)
In [2]:
say_hello("Python")
Namaskaram Python
In [3]:
say_hello("Python")
Namaskar Python
In [6]:
say_hello("Python")
Vanakkam Python

How to greet with both a message and a suffix (like "Hello Python Garu")?

In [7]:
# this version is not correct 
def say_hello(name):
    hello_options = ["Namaskaram", "Hello", "Vanakkam", "Namaskar"]
    hello = random.choice(hello_options)
    
    suffix_options = ["Garu", "Sir", "Anna", "Ji"]
    suffix = random.choice(suffix_options)
    
    print(hello, name, suffix)
In [8]:
say_hello("Python")
Namaskaram Python Sir

This says hello in one language and the suffix in another language. That is not what we wanted.

In [9]:
def say_hello(name):
    hello_options = [
        ("Namaskaram", "Garu"),
        ("Hello", "Sir"),
        ("Vanakkam", "Anna"),
        ("Namaskar", "Ji")
    ]
    hello, suffix = random.choice(hello_options)    
    print(hello, name, suffix)
In [10]:
say_hello("Python")
Hello Python Sir
In [11]:
say_hello("Python")
Vanakkam Python Anna
In [12]:
say_hello("Python")
Namaskar Python Ji

Conditional Expressions

In [13]:
score = 47
In [14]:
score > 35
Out[14]:
True
In [15]:
score < 35
Out[15]:
False
In [16]:
name = "Alice"
In [17]:
name == "Alice"
Out[17]:
True
In [18]:
name == "Alice" and score > 35
Out[18]:
True

The in operator can be used to check if an element is part of another.

In [19]:
"hell" in "hello"
Out[19]:
True
In [20]:
"yell" in "hello"
Out[20]:
False
In [21]:
"yell" not in "hello"
Out[21]:
True
In [22]:
"a" in ["a", "b", "c"]
Out[22]:
True
In [23]:
vowels = ["a", "e", "i", "o", "u"]
def is_vowel(c):
    return c in vowels
In [24]:
is_vowel('x')
Out[24]:
False
In [25]:
is_vowel('e')
Out[25]:
True

Strings have other useful methods to check for prefix and suffix matching.

In [26]:
"hello".startswith("hell")
Out[26]:
True
In [28]:
"hello".endswith("lo")
Out[28]:
True
In [29]:
def is_python_file(filename):
    return filename.endswith(".py")
In [30]:
is_python_file("hello.py")
Out[30]:
True
In [31]:
is_python_file("hello.c")
Out[31]:
False

The if Statement

In [32]:
n = 35
if n % 2 == 0:
    print("even")
else:
    print("odd")
odd
In [33]:
def check_even(n):
    if n % 2 == 0:
        print("even")
    else:
        print("odd")
In [34]:
check_even(34)
even
In [35]:
check_even(345)
odd

Checking multiple conditions can be done using elif statements.

In [36]:
def check_number(n):
    if n < 10:
        print(n, "is a single digit number")
    elif n < 100:
        print(n, "is a double digit number")
    else:
        print(n, "is a big number")
In [37]:
check_number(3)
3 is a single digit number
In [38]:
check_number(34)
34 is a double digit number
In [39]:
check_number(345)
345 is a big number

Problem: Write a function minimum to compute the minimum of two numbers, without using the built-in min function. Please note that the function should return the minimum value, not print.

>>> minimum(3, 7)
3
>>> minimum(33, 7)
7
>>> 1 + minimum(3, 7)
4

Bonus Problem: Write a function mimimum3 to compute minimum of three numbers. Can you do this using the minimum function defined above?

>>> minimum3(3, 4, 5)
3
>>> minimum3(13, 4, 5)
4    
>>> minimum3(13, 14, 5)
5        

Lists

In [40]:
x = ["a", "b", "c", "d"]
In [41]:
len(x)
Out[41]:
4
In [42]:
x[0]
Out[42]:
'a'
In [43]:
x[1]
Out[43]:
'b'

For Loop

In [45]:
x = ["a", "b", "c", "d"]

for element in x:
    print(element)
a
b
c
d
In [48]:
names = ["Alice", "Bob", "Charlie", "Dave"]
for name in names:
    print("Hello", name)
Hello Alice
Hello Bob
Hello Charlie
Hello Dave

How to print all words in a sentence?

In [49]:
sentence = "when in doubt, use brute force"

Problem: Write a program ls.py that takes path to a directory as command-line argument and prints all the files in that directory. The output should contain one filename per line.

$ python ls.py .
Makefile
day1.ipynb
day1.html
day2.ipynb
day2.html
square.py
In [52]:
%%file ls.py
import sys
import os
path = sys.argv[1]
files = os.listdir(path)
for f in files:
    print(f)
Overwriting ls.py
In [53]:
!python ls.py .
.ipynb_checkpoints
Makefile
args.py
date.py
day1.html
day1.ipynb
day2.html
day2.ipynb
day3.html
day3.ipynb
echo.py
hello.py
index.html
index.ipynb
ls.py
push
square.py

Python has a built-in function range to iterate over a sequence of numbers.

In [54]:
for i in range(5):
    print(i)
0
1
2
3
4

range(5) gives values from 0 to 4.

In [55]:
# we can optionally provide begin as well.
for i in range(2, 5):
    print(i)
2
3
4
In [56]:
# say hello n times
def say_hello(name, n):
    for i in range(n):
        print("Hello", name)
In [57]:
say_hello("Python", 5)
Hello Python
Hello Python
Hello Python
Hello Python
Hello Python

Example: Computing sum of numbers

Python has a built-in function sum to compute sum of a list of numbers.

In [58]:
sum([1, 2, 3, 4, 5])
Out[58]:
15
In [59]:
sum(range(10)) 
Out[59]:
45
In [60]:
# sum of all numbers below one million
sum(range(1000000))
Out[60]:
499999500000

Let us try to implement our own sum function.

In [61]:
def my_sum(numbers):
    result = 0
    for n in numbers:
        result = result + n
    return result
In [62]:
my_sum([1, 2, 3, 4, 5])
Out[62]:
15
In [63]:
my_sum(range(1000000))
Out[63]:
499999500000

Problem: Write a function product that takes a list of numbers and computes their product.

>>> product([1, 2, 3, 4])
24

Problem: Write a function factorial that takes a number as argument and computes its factorial. Can you use the above implementation of product in computing it?

>>> factorial(4)
24

Modifying and Growing Lists

In [64]:
x = ["a", "b", "c", "d"]
In [65]:
x
Out[65]:
['a', 'b', 'c', 'd']
In [66]:
x[0]
Out[66]:
'a'
In [67]:
x[1]
Out[67]:
'b'
In [68]:
x[1] = 'bb'
In [69]:
x
Out[69]:
['a', 'bb', 'c', 'd']
In [70]:
x.append('e')
In [71]:
x
Out[71]:
['a', 'bb', 'c', 'd', 'e']

Notice that the append method doesn't return any value, it just modifies the list in-place.

Example: squares

Let us write a function squares to compute squares of all numbers in a list.

In [72]:
def squares(numbers):
    result = []
    for n in numbers:
        result.append(n*n)
    return result
In [73]:
squares([1, 2, 3, 4, 5])
Out[73]:
[1, 4, 9, 16, 25]
In [74]:
# How to compute sum of squares of all numbers
# below one million?
sum(squares(range(1000000)))
Out[74]:
333332833333500000

Problem: Write a function evens that takes a list of numbers as argument and returns a new list containing only the even numbers out of them.

>>> evens([1, 2, 3, 4, 5, 6])
[2, 4, 6]

List Comprehensions

In [75]:
x = [1, 2, 3, 4, 5, 6]
In [76]:
[a*a for a in x]
Out[76]:
[1, 4, 9, 16, 25, 36]
In [77]:
[a*a for a in x if a % 2 == 0]
Out[77]:
[4, 16, 36]
In [78]:
names = ["a", "b", "c", "d"]
In [79]:
upper_names = [name.upper() for name in names]
In [80]:
upper_names
Out[80]:
['A', 'B', 'C', 'D']

List comprehensions are used to transform one list to another.

They are usually written as:

[expr for var in alist]
[expr for var in alist if some_condition]    

Problem: Write a function list_pyfiles that takes path to a directory as argument and returns all python files in that directory.

>>> list_pyfiles(".")
["args.py", "echo.py", "square.py"]
In [81]:
import os

def list_pyfiles(path):
    files = os.listdir(path)
    return [f for f in files if f.endswith(".py")]
In [82]:
list_pyfiles(".")
Out[82]:
['args.py', 'date.py', 'echo.py', 'hello.py', 'ls.py', 'square.py']
In [83]:
# all python files
[f for f in os.listdir(".") if f.endswith(".py")]
Out[83]:
['args.py', 'date.py', 'echo.py', 'hello.py', 'ls.py', 'square.py']
In [85]:
# size of each python file
[os.path.getsize(f) for f in os.listdir(".") if f.endswith(".py")]
Out[85]:
[26, 33, 29, 23, 93, 58]
In [86]:
# total size of all python files in the current directory
sum([os.path.getsize(f) for f in os.listdir(".") 
                         if f.endswith(".py")])
Out[86]:
262

Iteration Patterns

Iterating over list

In [87]:
x = ["a", "b", "c", "d"]
for a in x:
    print(a)
a
b
c
d
In [88]:
x = ["a", "b", "c", "d"]
for a in x:
    print(a.upper())
A
B
C
D
In [89]:
x_upper  = [a.upper() for a in x]
print(x_upper)
['A', 'B', 'C', 'D']

Iterating over a sequence of numbers

In [90]:
for i in range(5):
    print(i, i*i)
0 0
1 1
2 4
3 9
4 16
In [91]:
for i in range(2, 5):
    print(i, i*i)
2 4
3 9
4 16
In [92]:
[i*i for i in range(10)]
Out[92]:
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

Iterating over two lists together

In [93]:
names = ["a", "b", "c", "d"]
scores = [10, 20, 30, 40]
In [94]:
for name, score in zip(names, scores):
    print(name, score)
a 10
b 20
c 30
d 40
In [96]:
list(zip(names, scores))
Out[96]:
[('a', 10), ('b', 20), ('c', 30), ('d', 40)]

Problem: write a function vector_add to add two vectors.

>>> vector_add([1, 2, 3, 4], [10, 20, 30, 40])
[11, 22, 33, 44]

Iterating over the index and the value together

In [97]:
names = ["a", "b", "c", "d"]
In [98]:
for i, name in enumerate(names):
    print(i, name)
0 a
1 b
2 c
3 d

Let us look at a simple example.

In [99]:
chapters = ["Getting Started", "Lists", "Building Games"]
In [101]:
for i, title in enumerate(chapters):
    print("chapter", i+1, ":", title)
chapter 1 : Getting Started
chapter 2 : Lists
chapter 3 : Building Games
In [102]:
for i, title in enumerate(chapters, start=1):
    print("chapter", i, ":", title)
chapter 1 : Getting Started
chapter 2 : Lists
chapter 3 : Building Games

List Indexing

In [103]:
x = ["a", "b", "c", "d"]
In [104]:
x[1]
Out[104]:
'b'
In [105]:
x[len(x)-1]
Out[105]:
'd'
In [106]:
x[-1]
Out[106]:
'd'
In [107]:
def get_last_word(sentence):
    return sentence.split()[-1]
In [108]:
get_last_word("one tow three")
Out[108]:
'three'

how to find extension of a file?

In [109]:
def getext(filename):
    return filename.split(".")[-1]
In [110]:
getext("hello.py")
Out[110]:
'py'
In [111]:
getext("a.tar.gz")
Out[111]:
'gz'

List Slicing

In [112]:
x = ["a", "b", "c", "d", "e", "f", "g", "h"]
In [113]:
x[0:2]
Out[113]:
['a', 'b']
In [114]:
x[:2] # upto index 2 (index 2 not included)
Out[114]:
['a', 'b']
In [115]:
x[2:] # index 2 onwards
Out[115]:
['c', 'd', 'e', 'f', 'g', 'h']
In [116]:
x[2:6] # from index 2 to index 6
Out[116]:
['c', 'd', 'e', 'f']
In [117]:
x[:] # copy of x
Out[117]:
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
In [118]:
x[1:6:2] # every second element from index 1 to 6
Out[118]:
['b', 'd', 'f']
In [119]:
x[::-1] # reverse of a list
Out[119]:
['h', 'g', 'f', 'e', 'd', 'c', 'b', 'a']

Building Games

Hints

The range function can take optional third argument.

In [121]:
for i in range(0, 100, 25):
    print(i)
0
25
50
75
In [ ]: