Python Virtual Training For Arcesium - Module I - Day 4

Aug 10-14, 2020 Vikrant Patil

These notes are available online at http://notes.pipal.in/2020/arcesium_finop_batch1_module1/day4.html

© Pipal Academy LLP

Day 1 | Day 2 | Day 3 | Day 4 | Day 5

We will be using jupyter hub from http://lab1.pipal.in for this training.

make use of notebook module1-day4.ipynb for today's session.

Introduction to programming constructs

Conditions

In [1]:
True
Out[1]:
True
In [2]:
False
Out[2]:
False
In [3]:
"hello".startswith("hel")
Out[3]:
True
In [4]:
"hel" in "hello"
Out[4]:
True
In [235]:
"hel" not in "hello"
Out[235]:
False
In [5]:
first = "hel"
second = "hello world!"
In [6]:
first in second
Out[6]:
True
In [7]:
"python" in second
Out[7]:
False
In [236]:
"python" not in second
Out[236]:
True
In [8]:
x = 2
y = 4
In [9]:
x == y
Out[9]:
False
In [17]:
x == 2 #checks if both sides of operator have same values
Out[17]:
False
In [11]:
x, y = 5, 4
In [18]:
x < y # comparison operator
Out[18]:
False
In [13]:
x > y
Out[13]:
True
In [14]:
x >= y
Out[14]:
True
In [15]:
x <= y
Out[15]:
False
In [19]:
x != y # checks if both sides are not equal
Out[19]:
True
In [20]:
2 != 2
Out[20]:
False
In [21]:
2 != 3
Out[21]:
True

if elif else statements

In [24]:
if "hel" in "cell": # this ends with :
    print("hell") # 4 space indentation shoube given
    print("another print statement")
elif "cel" in "hell":
    print("cell")
elif "del" in "bell":
    print("dell")
else:
    print("Finally, if none of above conditons matched!")
Finally, if none of above conditons matched!

if the conditions have only two possiblities and simple satetments, then it is also possible to write if-else statement in one line

In [40]:
cond = True
In [41]:
x = 2 if cond else 3
In [42]:
print(x)
2
In [237]:
cond = False
In [44]:
x = 2 if cond else 3
In [45]:
print(x)
3

While loop

In [48]:
def print_list(items):
    i = 0
    
    while i < len(items):
        print(items[i])
        i += 1 ##  is equivalent i = i +1
In [47]:
print_list([1, 2, 3, 4, 2, 4])
1
2
3
4
2
4
In [56]:
def print_list(items):
    i = 0
    n = len(items)
    print("i =", i, "n =", n, "i< n" , i <n)
    while i < n:
        print(items[i])
        i += 1 ##  is equivalent i = i +1​
        print("i =", i, "n =", n, "i< n" , i <n)
In [57]:
print_list([12, 1, 2, 3])
i = 0 n = 4 i< n True
12
i = 1 n = 4 i< n True
1
i = 2 n = 4 i< n True
2
i = 3 n = 4 i< n True
3
i = 4 n = 4 i< n False
In [58]:
4 < 4
Out[58]:
False

And here is classic fibonacci

In [59]:
def print_fib(n):
    """
    This function prints fibonacci numbers less than n
    """
    
    curr, prev = 1, 1
    
    while prev < n:
        print(prev, end=",")
        curr, prev = curr+prev, curr
In [60]:
print_fib(100)
1,1,2,3,5,8,13,21,34,55,89,

Recusrsion

a function that calls itself is called as recursive function.

In [61]:
def foo():
    foo() # this is infinite resursion
In [62]:
foo()
---------------------------------------------------------------------------
RecursionError                            Traceback (most recent call last)
<ipython-input-62-c19b6d9633cf> in <module>
----> 1 foo()

<ipython-input-61-bd60a80b7115> in foo()
      1 def foo():
----> 2     foo() # this is infinite resursion

... last 1 frames repeated, from the frame below ...

<ipython-input-61-bd60a80b7115> in foo()
      1 def foo():
----> 2     foo() # this is infinite resursion

RecursionError: maximum recursion depth exceeded
In [66]:
def fib(n):
    if n == 1 or n == 0:
        return 1
    else:
        return fib(n-1) + fib(n-2)
In [67]:
fib(1)
Out[67]:
1
In [68]:
fib(2)
Out[68]:
2
In [69]:
fib(5)
Out[69]:
8
In [70]:
fib(10)
Out[70]:
89
In [71]:
def print_fib1(n):
    
    i = 0
    f = fib(i)
    while f < n:
        print(f, end=",")
        i = i +1
        f = fib(i)
In [72]:
print_fib1(100)
1,1,2,3,5,8,13,21,34,55,89,
In [73]:
fib(15)
Out[73]:
987
In [74]:
fib(30)
Out[74]:
1346269
In [77]:
#fib(50) # don;t execute this on your notebook, it take very long time
In [78]:
def print_list(items):
    i = 0
    
    while i < len(items):
        print(items[i])
        i += 1 ##  is equivalent i = i +1

For loops

Using while loop to iterate over items from a list has a problem that , we have to do correct book keeping of index. if that goes wrong, we might end up in infinite loop or might access out of index. Python gives alternative for this through for loop. Just like we sya in plain english, for every_student in class. Just similar statement is supported in python as programming construct.

In [79]:
words = ["one", "two", "three", "four", "five", "six"]

for word in words: # it ends with :
    print(word, end=",") # next line starts with 4 spaces indentation
one,two,three,four,five,six,
In [81]:
for w in words:
    print(w, end=",")
one,two,three,four,five,six,
In [82]:
for i in word:
    print(i, end=",")
s,i,x,
In [83]:
for word in words: # it ends with :
    print(word, end=",") # next line starts with 4 spaces indentation
one,two,three,four,five,six,
In [84]:
for c in "this string":
    print(c, end=",")
t,h,i,s, ,s,t,r,i,n,g,
In [85]:
for t in (0 , 1, 2, 3):
    print(t, end=",")
0,1,2,3,
In [86]:
for item in {"x":1, "y":2}:
    print(item)
x
y
In [87]:
stock = {"name":"IBM",
         "open":123.5,
         "high":125.3,
         "low":122.3,
         "close":124.2
        }
In [88]:
for paramater in stock:
    print(paramater)
name
open
high
low
close
In [89]:
for paramater in stock:
    print(paramater, stock[paramater])
name IBM
open 123.5
high 125.3
low 122.3
close 124.2
In [90]:
stock
Out[90]:
{'name': 'IBM', 'open': 123.5, 'high': 125.3, 'low': 122.3, 'close': 124.2}
In [91]:
stock['name']
Out[91]:
'IBM'
In [92]:
stock['low']
Out[92]:
122.3
In [93]:
stock['name']
Out[93]:
'IBM'
In [94]:
stock['name'] = "MICROSOFT"
In [95]:
stock
Out[95]:
{'name': 'MICROSOFT',
 'open': 123.5,
 'high': 125.3,
 'low': 122.3,
 'close': 124.2}
In [96]:
stock['name'] = "IBM"
In [97]:
stock
Out[97]:
{'name': 'IBM', 'open': 123.5, 'high': 125.3, 'low': 122.3, 'close': 124.2}

Problems

  1. Write a function product which finds product of all elements from a list.
    >>> product([3, 2, 4])
    24
  1. Write a function factorial which computes factorial of a number.
    >>> factorial(5)
    120
  1. Write a function findlens which will find length of every string from given list of strings.
    >>> findlens(["one", "two", "three"])
    [3, 3, 5]
  1. Write a function find_words_of_len to find words of given length from given list.
    >>> ["one", "two", "three", "four", "five", "six"]
    >>> find_words_of_len(words, 3)
    ['one', 'two', 'six']

Example function which will find sum of items from a list

In [98]:
def sumlist(numbers):
    s = 0
    for n in numbers:
        s = s + n
    return s
In [99]:
sumlist([1, 2, 3, 1, 2])
Out[99]:
9
In [100]:
i++
  File "<ipython-input-100-56f7e036d680>", line 1
    i++
       ^
SyntaxError: invalid syntax
In [102]:
i = 0
i += 1
In [104]:
# i++ , i-- is not there in python 
In [105]:
i = 0
i -= 1
In [106]:
nums = [1, 2, 3, 4, 5]
In [107]:
range(5) # created a sequ of numbers starting from 0 till less than , 4
Out[107]:
range(0, 5)
In [108]:
for i in range(5):
    print(i, end=",")
0,1,2,3,4,
In [109]:
for i in range(1,6):
    print(i, end=",")
1,2,3,4,5,
In [111]:
for i in range(1, 20, 2): ## start, end , step
    print(i, end=",")
1,3,5,7,9,11,13,15,17,19,

Solutions 1

In [112]:
def product(numbers):
    p = 1
    
    for num in numbers:
        p = p *num
    
    return p
In [113]:
product([1,2,4,2])
Out[113]:
16
In [116]:
product(range(1, 6)) # product of 1, 2, 3, 4, 5
Out[116]:
120
In [117]:
def factorial(n):
    return product(range(1, n+1))
In [118]:
factorial(5)
Out[118]:
120
In [119]:
factorial(4)
Out[119]:
24
In [120]:
for i in range(5): # end with :, for _ in __: this is structure of for loop
    print(i, end=",") # indentation of 4 spaces
0,1,2,3,4,
In [122]:
i = 0
n = 5
for i < n: # incorrect
    print(i, end=",")
  File "<ipython-input-122-69e808eb9939>", line 3
    for i < n: # incorrect
          ^
SyntaxError: invalid syntax
In [125]:
i = 0
n = 5
while i < n: 
    print(i, end=",")
    i += 1
0,1,2,3,4,
In [126]:
def findlens(words):
    lens = []
    
    for w in words:
        lens.append(len(w))
        
    return lens
In [127]:
findlens(["helllo", "these", "are", "some", "words"])
Out[127]:
[6, 5, 3, 4, 5]
In [128]:
def fancy_print(words):
    for w in words:
        print("lenghth of", w, "=", len(w))
In [129]:
fancy_print(["helllo", "these", "are", "some", "words"])
lenghth of helllo = 6
lenghth of these = 5
lenghth of are = 3
lenghth of some = 4
lenghth of words = 5
In [131]:
def find_words_of_len(words, l):
    filtered = []
    
    for word in words:
        if len(word) == l:
            filtered.append(word)
        
    return filtered
In [133]:
words = "How do I make words from this sentence?".split()
find_words_of_len(words, 2)
Out[133]:
['do']
In [134]:
find_words_of_len(words, 4)
Out[134]:
['make', 'from', 'this']

More problems

  1. Write a function unique which will remove duplicate items from a list.
    >>> unique([1, 1, 2, 2, 3, 1, 2, 3, 1]
    [1, 2, 3]
  1. List of urls is given. Some urls are from same domain and some are from different. Find unique dammain names used in the urls
    urls = ['www.abrakadabra.com/dccEcB/EGdd',
            'www.abrakadabra.com/gADFeD/bcAF',
            'www.abra.com/AGadbb/eagE',
            'www.dabra.com/cffdfD/FCAD',
            'www.abra.com/GFGaBE/dcfc',
            'www.abra.com/gaFegG/Bdaf',
            'www.abrakadabra.com/aGabaf/EEfa',
            'www.dabra.com/ceEgFD/bGgc',
            'www.dabra.com/bDEffC/bcEA']
  1. Write a function min2 which finds minumum from given two numbers. Then write another function min3 which finds minimum number from given 3 numbers. Do not make use of built in min function.
    >>> min2(5, 4.5)
    4.5
    >>> min3(1, 2, 4)
    1
  1. Write a function rearrange_max to rearrange digits of an integer to form a maximum number.
    >>> rearrange_max(1321)
    3211
In [135]:
"hel" in "hello"
Out[135]:
True
In [137]:
1 in [1, 2, 3, 4] # check if given item is in list or not
Out[137]:
True
In [138]:
nums = [1, 2, 3, 4,4, 3, 42]
In [139]:
42 in nums
Out[139]:
True
In [140]:
43 in  nums
Out[140]:
False
In [141]:
def unique(items): # a function defination has () brackets not [] brackets.
    uniq = []
    
    for item in items:
        if item not in uniq:
            uniq.append(item)

    return uniq
In [142]:
unique([1, 1, 2, 3, 1, 3, 4, 1, 3, 2, 2])
Out[142]:
[1, 2, 3, 4]
In [143]:
nums = [3, 4, 1, 1, 2, 3, 1, 3, 4, 1, 3, 2, 2]
In [146]:
s = set(nums) # set is unique but order is not garanteed!
In [145]:
s
Out[145]:
{1, 2, 3, 4}
In [148]:
sorted(s)
Out[148]:
[1, 2, 3, 4]
In [149]:
nums = [42, 1, 43, 42, 1, 3, 3, 2, 2, 1, 1, 1, 5, 5]
In [150]:
unique(nums)
Out[150]:
[42, 1, 43, 3, 2, 5]
In [154]:
sorted(set(nums), reverse=True)
Out[154]:
[43, 42, 5, 3, 2, 1]

** rohit's code

In [243]:
def unique(num1):
    num1.sort()
    x = []
    n = 1
    for i in num1:
        print(n)
        if num1[n] != num1[n-1]:
            x.append(num1[n]) # there is a bug here! find out! it will skip first number
            n += 1
        else:
            n += 1
        
    return x
In [161]:
len(nums)
Out[161]:
14
In [162]:
nums[14]
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-162-e2bc9b291fa6> in <module>
----> 1 nums[14]

IndexError: list index out of range
In [163]:
nums[13]
Out[163]:
43
In [160]:
unique(nums)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-160-a135c1991bc3> in <module>
----> 1 unique(nums)

<ipython-input-159-6af386a6362f> in unique(num1)
      5     for i in num1:
      6         print(n)
----> 7         if num1[n] != num1[n-1]:
      8             x.append(num1[n])
      9             n += 1

IndexError: list index out of range
In [164]:
def unique(num1):
    num1.sort()
    x = []
    n = 1
    for i in num1[1:]: # drop first item
        print(n)
        if num1[n-1] != num1[n]:
            x.append(num1[n])
            n += 1
        else:
            n += 1
        
    return x
In [165]:
unique(nums)
1
2
3
4
5
6
7
8
9
10
11
12
13
Out[165]:
[2, 3, 5, 42, 43]
  * * * * * *
  - -
    - -
      - -
        - -
          - -
In [241]:
def unique(num1):
    num1.sort()
    x = []
    n = 1
    for i in range(len(num1)-1): # THis is not using i!
        if num1[n-1] != num1[n]: # check with next number if it is same
            x.append(num1[n-1])
            n += 1
        else:
            n += 1
        
    return x
In [242]:
unique(nums)
Out[242]:
[1, 2, 3, 5, 42]
In [172]:
def unique(items): # a function defination has () brackets not [] brackets.
    uniq = []
    
    for item in items:
        if item not in uniq:
            uniq.append(item)

    return uniq
In [168]:
not True
Out[168]:
False
In [171]:
urls = ['www.abrakadabra.com/dccEcB/EGdd',
            'www.abrakadabra.com/gADFeD/bcAF',
            'www.abra.com/AGadbb/eagE',
            'www.dabra.com/cffdfD/FCAD',
            'www.abra.com/GFGaBE/dcfc',
            'www.abra.com/gaFegG/Bdaf',
            'www.abrakadabra.com/aGabaf/EEfa',
            'www.dabra.com/ceEgFD/bGgc',
            'www.dabra.com/bDEffC/bcEA']

urls
Out[171]:
['www.abrakadabra.com/dccEcB/EGdd',
 'www.abrakadabra.com/gADFeD/bcAF',
 'www.abra.com/AGadbb/eagE',
 'www.dabra.com/cffdfD/FCAD',
 'www.abra.com/GFGaBE/dcfc',
 'www.abra.com/gaFegG/Bdaf',
 'www.abrakadabra.com/aGabaf/EEfa',
 'www.dabra.com/ceEgFD/bGgc',
 'www.dabra.com/bDEffC/bcEA']
In [178]:
def domain(url):
    return url.split("/")[0]


def unique_domains(urls):
    domains = []
    
    for url in urls:
        domains.append(domain(url))
    
    return unique(domains)
        
        
In [177]:
unique_domains(urls)
Out[177]:
['www.abrakadabra.com', 'www.abra.com', 'www.dabra.com']
In [180]:
def min2(x, y):
    if x < y:
        return x
    else:
        return y
In [181]:
def min3(x, y, z):
    return min2(min2(x, y), z)
In [182]:
min3(1, 1, 1)
Out[182]:
1
In [183]:
min3(1, 2, 3)
Out[183]:
1
In [184]:
min3(2, 1, 3)
Out[184]:
1
In [185]:
min3(3, 2, 1)
Out[185]:
1
In [186]:
def my_min(*args):
    m = args[0]
    for n in args[1:]:
        m = min2(m, n)
    return m
In [187]:
my_min(3, 4, 5, 6, 1, 4, 3)
Out[187]:
1
In [188]:
str(12344)
Out[188]:
'12344'
In [189]:
d = []
for c in str(12344):
    d.append(c)
In [190]:
d
Out[190]:
['1', '2', '3', '4', '4']
In [192]:
sorted(d, reverse=True)
Out[192]:
['4', '4', '3', '2', '1']
In [193]:
"".join(sorted(d, reverse=True))
Out[193]:
'44321'
In [194]:
list(12123)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-194-962bb745d8ef> in <module>
----> 1 list(12123)

TypeError: 'int' object is not iterable
In [195]:
list((1, 2, 3))
Out[195]:
[1, 2, 3]
In [196]:
list("sladlsad")
Out[196]:
['s', 'l', 'a', 'd', 'l', 's', 'a', 'd']
In [197]:
list(str(12123))
Out[197]:
['1', '2', '1', '2', '3']
In [198]:
str(12)
Out[198]:
'12'
In [201]:
def rearrange_max(number):
    digits = list(str(number))
    digits_ = sorted(digits, reverse=True)
    return int("".join(digits_))
    
In [202]:
rearrange_max(345454)
Out[202]:
554443

Modules

In [203]:
import math
In [204]:
math.sqrt(45)
Out[204]:
6.708203932499369
In [205]:
math.pi
Out[205]:
3.141592653589793
In [206]:
import math as m
In [207]:
m.pi
Out[207]:
3.141592653589793
In [208]:
from math import sin
In [209]:
sin(m.pi)
Out[209]:
1.2246467991473532e-16
In [210]:
import os
In [213]:
current = os.getcwd() # get me present working directory/folder
In [212]:
#c:\\Program files\\Python3.7
In [215]:
os.listdir(current) # list of files and folders from given folder
Out[215]:
['day2.html',
 'day5.html',
 'push',
 'day2.ipynb',
 'day1.html',
 'day5.ipynb',
 'day3.html',
 'day1.ipynb',
 'day4.html',
 'Makefile',
 '.ipynb_checkpoints',
 'day4.ipynb',
 'day3.ipynb']
In [217]:
os.listdir() # if you don't give any parameter, it will take current folder
Out[217]:
['day2.html',
 'day5.html',
 'push',
 'day2.ipynb',
 'day1.html',
 'day5.ipynb',
 'day3.html',
 'day1.ipynb',
 'day4.html',
 'Makefile',
 '.ipynb_checkpoints',
 'day4.ipynb',
 'day3.ipynb']
In [218]:
os.path.exists("day3.html")
Out[218]:
True
In [219]:
os.path.exists("/home/vikrant/Documents/prayas")
Out[219]:
True
In [220]:
current
Out[220]:
'/home/vikrant/trainings/2020/arcesium_finop_batch1_module1'
In [222]:
os.path.sep # this is platform dependent
Out[222]:
'/'
In [223]:
#os.path.sep on windows will be `\\`
In [224]:
os.path.sep.join([current, "day3.html"])
Out[224]:
'/home/vikrant/trainings/2020/arcesium_finop_batch1_module1/day3.html'
In [225]:
os.path.join(current, "day3.html")
Out[225]:
'/home/vikrant/trainings/2020/arcesium_finop_batch1_module1/day3.html'
In [226]:
day3 = os.path.join(current , "day3.html")
In [227]:
day3
Out[227]:
'/home/vikrant/trainings/2020/arcesium_finop_batch1_module1/day3.html'
In [228]:
os.path.exists(day3)
Out[228]:
True
In [229]:
file = '/home/vikrant/trainings/2020/arcesium_finop_batch1_module1/module1-day1.ipynb'
In [230]:
os.path.exists(file)
Out[230]:
False
In [234]:
os.path.getsize(day3) # this gives size correctly for files , not for directory
Out[234]:
384697

Example

Find biggest file in current directory

In [232]:
files = os.listdir()
max(files, key=os.path.getsize)
Out[232]:
'day4.html'
In [ ]: