Basic Python Training at Grofers - Day 1

Dec 19-21, 2019 Vikrant Patil, Anand Chitipothu

These notes are available online at http://notes.pipal.in/2019/grofers_basic_dec/day1.html

© Pipal Academy LLP

Day 1 | Day 2 | Day 3

We will be using python 3 (>= 3.0) from anaconda for this training. You can download it from

https://www.anaconda.com/download/

Ingredients

Day 1

  • Getting started - python interpreter
  • Working with data - I
    • Elements of programming - statements, basic data types
    • functions - built in functions, custom functions
    • functions as first class objects
    • methods Processing text and numeric data using strings, lists, dictionaries
  • modules
    • introduction to os, sys module
    • creating custom modules
    • conditions
    • python script and python module
  • Working with data II
    • conditions
    • looping techniques

Day2

  • Working with lists/sequences
    • indexing techniques, slicing
    • list comprehensions
    • Iteration patterns
    • text formatting, creating reports
  • testing - pytest
    • basic
    • fixtures
    • using requests module to test webapi as black box
  • Working with Files
    • Reading text/binary files • Writing text/binary files

Day3

  • Classes
    • What are classes?
    • Basics of classes in python
  • Selenium from python
  • Locust
  • How to write beautiful programs
  • zen of python
In [2]:
!pip install jupyter
Requirement already satisfied: jupyter in /home/vikrant/anaconda3/lib/python3.7/site-packages (1.0.0)
Requirement already satisfied: notebook in /home/vikrant/anaconda3/lib/python3.7/site-packages (from jupyter) (6.0.0)
Requirement already satisfied: jupyter-console in /home/vikrant/anaconda3/lib/python3.7/site-packages (from jupyter) (6.0.0)
Requirement already satisfied: nbconvert in /home/vikrant/anaconda3/lib/python3.7/site-packages (from jupyter) (5.5.0)
Requirement already satisfied: qtconsole in /home/vikrant/anaconda3/lib/python3.7/site-packages (from jupyter) (4.5.1)
Requirement already satisfied: ipykernel in /home/vikrant/anaconda3/lib/python3.7/site-packages (from jupyter) (5.1.1)
Requirement already satisfied: ipywidgets in /home/vikrant/anaconda3/lib/python3.7/site-packages (from jupyter) (7.5.0)
Requirement already satisfied: pyzmq>=17 in /home/vikrant/anaconda3/lib/python3.7/site-packages (from notebook->jupyter) (18.0.0)
Requirement already satisfied: ipython-genutils in /home/vikrant/anaconda3/lib/python3.7/site-packages (from notebook->jupyter) (0.2.0)
Requirement already satisfied: tornado>=5.0 in /home/vikrant/anaconda3/lib/python3.7/site-packages (from notebook->jupyter) (6.0.3)
Requirement already satisfied: jinja2 in /home/vikrant/anaconda3/lib/python3.7/site-packages (from notebook->jupyter) (2.10.1)
Requirement already satisfied: nbformat in /home/vikrant/anaconda3/lib/python3.7/site-packages (from notebook->jupyter) (4.4.0)
Requirement already satisfied: Send2Trash in /home/vikrant/anaconda3/lib/python3.7/site-packages (from notebook->jupyter) (1.5.0)
Requirement already satisfied: terminado>=0.8.1 in /home/vikrant/anaconda3/lib/python3.7/site-packages (from notebook->jupyter) (0.8.2)
Requirement already satisfied: prometheus-client in /home/vikrant/anaconda3/lib/python3.7/site-packages (from notebook->jupyter) (0.7.1)
Requirement already satisfied: traitlets>=4.2.1 in /home/vikrant/anaconda3/lib/python3.7/site-packages (from notebook->jupyter) (4.3.2)
Requirement already satisfied: jupyter-core>=4.4.0 in /home/vikrant/anaconda3/lib/python3.7/site-packages (from notebook->jupyter) (4.5.0)
Requirement already satisfied: jupyter-client>=5.3.1 in /home/vikrant/anaconda3/lib/python3.7/site-packages (from notebook->jupyter) (5.3.1)
Requirement already satisfied: ipython in /home/vikrant/anaconda3/lib/python3.7/site-packages (from jupyter-console->jupyter) (7.6.1)
Requirement already satisfied: prompt_toolkit<2.1.0,>=2.0.0 in /home/vikrant/anaconda3/lib/python3.7/site-packages (from jupyter-console->jupyter) (2.0.9)
Requirement already satisfied: pygments in /home/vikrant/anaconda3/lib/python3.7/site-packages (from jupyter-console->jupyter) (2.4.2)
Requirement already satisfied: testpath in /home/vikrant/anaconda3/lib/python3.7/site-packages (from nbconvert->jupyter) (0.4.2)
Requirement already satisfied: pandocfilters>=1.4.1 in /home/vikrant/anaconda3/lib/python3.7/site-packages (from nbconvert->jupyter) (1.4.2)
Requirement already satisfied: mistune>=0.8.1 in /home/vikrant/anaconda3/lib/python3.7/site-packages (from nbconvert->jupyter) (0.8.4)
Requirement already satisfied: defusedxml in /home/vikrant/anaconda3/lib/python3.7/site-packages (from nbconvert->jupyter) (0.6.0)
Requirement already satisfied: entrypoints>=0.2.2 in /home/vikrant/anaconda3/lib/python3.7/site-packages (from nbconvert->jupyter) (0.3)
Requirement already satisfied: bleach in /home/vikrant/anaconda3/lib/python3.7/site-packages (from nbconvert->jupyter) (3.1.0)
Requirement already satisfied: widgetsnbextension~=3.5.0 in /home/vikrant/anaconda3/lib/python3.7/site-packages (from ipywidgets->jupyter) (3.5.0)
Requirement already satisfied: MarkupSafe>=0.23 in /home/vikrant/anaconda3/lib/python3.7/site-packages (from jinja2->notebook->jupyter) (1.1.1)
Requirement already satisfied: jsonschema!=2.5.0,>=2.4 in /home/vikrant/anaconda3/lib/python3.7/site-packages (from nbformat->notebook->jupyter) (3.0.1)
Requirement already satisfied: decorator in /home/vikrant/anaconda3/lib/python3.7/site-packages (from traitlets>=4.2.1->notebook->jupyter) (4.4.0)
Requirement already satisfied: six in /home/vikrant/anaconda3/lib/python3.7/site-packages (from traitlets>=4.2.1->notebook->jupyter) (1.12.0)
Requirement already satisfied: python-dateutil>=2.1 in /home/vikrant/anaconda3/lib/python3.7/site-packages (from jupyter-client>=5.3.1->notebook->jupyter) (2.8.0)
Requirement already satisfied: backcall in /home/vikrant/anaconda3/lib/python3.7/site-packages (from ipython->jupyter-console->jupyter) (0.1.0)
Requirement already satisfied: pexpect; sys_platform != "win32" in /home/vikrant/anaconda3/lib/python3.7/site-packages (from ipython->jupyter-console->jupyter) (4.7.0)
Requirement already satisfied: setuptools>=18.5 in /home/vikrant/anaconda3/lib/python3.7/site-packages (from ipython->jupyter-console->jupyter) (41.0.1)
Requirement already satisfied: jedi>=0.10 in /home/vikrant/anaconda3/lib/python3.7/site-packages (from ipython->jupyter-console->jupyter) (0.13.3)
Requirement already satisfied: pickleshare in /home/vikrant/anaconda3/lib/python3.7/site-packages (from ipython->jupyter-console->jupyter) (0.7.5)
Requirement already satisfied: wcwidth in /home/vikrant/anaconda3/lib/python3.7/site-packages (from prompt_toolkit<2.1.0,>=2.0.0->jupyter-console->jupyter) (0.1.7)
Requirement already satisfied: webencodings in /home/vikrant/anaconda3/lib/python3.7/site-packages (from bleach->nbconvert->jupyter) (0.5.1)
Requirement already satisfied: attrs>=17.4.0 in /home/vikrant/anaconda3/lib/python3.7/site-packages (from jsonschema!=2.5.0,>=2.4->nbformat->notebook->jupyter) (19.1.0)
Requirement already satisfied: pyrsistent>=0.14.0 in /home/vikrant/anaconda3/lib/python3.7/site-packages (from jsonschema!=2.5.0,>=2.4->nbformat->notebook->jupyter) (0.14.11)
Requirement already satisfied: ptyprocess>=0.5 in /home/vikrant/anaconda3/lib/python3.7/site-packages (from pexpect; sys_platform != "win32"->ipython->jupyter-console->jupyter) (0.6.0)
Requirement already satisfied: parso>=0.3.0 in /home/vikrant/anaconda3/lib/python3.7/site-packages (from jedi>=0.10->ipython->jupyter-console->jupyter) (0.5.0)
In [4]:
print("hello world!")
hello world!

header1

header2

header3

Data types

It has integers!

In [5]:
1 + 2
Out[5]:
3
In [6]:
2 - 3
Out[6]:
-1
In [9]:
1 / 3 # float divison
Out[9]:
0.3333333333333333
In [10]:
5 // 3 # integr division
Out[10]:
1
In [13]:
5 % 2 #mod
Out[13]:
1
In [12]:
5 ** 2 # power
Out[12]:
25
In [14]:
2 ** 1000
Out[14]:
10715086071862673209484250490600018105614048117055336074437503883703510511249361224931983788156958581275946729175531468251871452856923140435984577574698574803934567774824230985421074605062371141877954182153046474983581941267398767559165543946077062914571196477686542167660429831652624386837205668069376

It has floats

In [15]:
3.5 * 3.4
Out[15]:
11.9

there are strings

In [16]:
"Rupali"
Out[16]:
'Rupali'
In [17]:
'Rupak'
Out[17]:
'Rupak'
In [19]:
"Rupali" "Rupak"
Out[19]:
'RupaliRupak'
In [20]:
first = "Rupali"
second = "Rupak"
In [21]:
first
Out[21]:
'Rupali'
In [22]:
print(first)
Rupali
In [23]:
first
Out[23]:
'Rupali'
In [24]:
print(second)
Rupak
In [25]:
print(first, second)
Rupali Rupak
In [26]:
first
Out[26]:
'Rupali'
In [27]:
single = 'strign with single quote'
In [28]:
double = "data with double quote"
In [29]:
sentence = "He said, 'Answer to eveything is 42'"
In [30]:
print(sentence)
He said, 'Answer to eveything is 42'
In [31]:
multiline = """This is multi
line string in python
which has three lines
"""
In [32]:
multiline
Out[32]:
'This is multi\nline string in python\nwhich has three lines\n'
In [33]:
print(multiline)
This is multi
line string in python
which has three lines

In [35]:
print("string can \t have tabs\n and new lines")
string can 	 have tabs
 and new lines
In [36]:
star = "*"
In [37]:
star*5
Out[37]:
'*****'
In [38]:
first + " " + second
Out[38]:
'Rupali Rupak'
In [39]:
print("="*10)
==========

There are lists

In [40]:
numbers = [1, 1, 2, 3, 5, 8, 12]
In [41]:
numeric_data = [1, 1.1, 2.2]
In [42]:
multidata = [1, 2, "a", "b"]
In [43]:
numbers[0]
Out[43]:
1
In [44]:
numbers[-1]
Out[44]:
12

->  0  1  2  3  4  5
    P  y  t  h  o  n
   -6 -5 -4 -3 -2 -1 <--
In [46]:
numbers[2:4] # start at index 2 end at index 4 (exlude)
Out[46]:
[2, 3]
In [47]:
numbers[:4] #take first 4
Out[47]:
[1, 1, 2, 3]
In [49]:
numbers[3:] # drop first 3
Out[49]:
[3, 5, 8, 12]
In [50]:
ones = [1, 1]
In [51]:
ones*5
Out[51]:
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
In [52]:
ones + ones
Out[52]:
[1, 1, 1, 1]

there are tuple, sibling of list

In [53]:
color = (255, 255, 0)
In [54]:
color[0]
Out[54]:
255
In [56]:
color[-1]
Out[56]:
0
In [57]:
color * 2
Out[57]:
(255, 255, 0, 255, 255, 0)
In [58]:
color + color
Out[58]:
(255, 255, 0, 255, 255, 0)
In [59]:
ones
Out[59]:
[1, 1]
In [60]:
ones[0] = -1
In [61]:
ones
Out[61]:
[-1, 1]
In [62]:
color[-1] = 255
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-62-57316af5d9c9> in <module>
----> 1 color[-1] = 255

TypeError: 'tuple' object does not support item assignment

Dictionaries

In [63]:
specs = {"cpu":"core-i5", "memory":16, "os":"mint"}
In [64]:
specs['cpu']
Out[64]:
'core-i5'
In [65]:
specs['os']
Out[65]:
'mint'
In [66]:
specs['memory']
Out[66]:
16
In [67]:
data = {None:0}
In [68]:
data[None]
Out[68]:
0
In [70]:
specs['memory'] = 8
In [71]:
specs
Out[71]:
{'cpu': 'core-i5', 'memory': 8, 'os': 'mint'}
In [72]:
data[None] = 1
In [73]:
data
Out[73]:
{None: 1}
In [74]:
del specs['os']
In [75]:
specs
Out[75]:
{'cpu': 'core-i5', 'memory': 8}
In [76]:
specs['os'] = "linux"
In [77]:
specs
Out[77]:
{'cpu': 'core-i5', 'memory': 8, 'os': 'linux'}

sets

In [78]:
digits = {0, 1, 2, 3, 4}
In [79]:
digits
Out[79]:
{0, 1, 2, 3, 4}
In [80]:
digits = {0, 0, 1, 1, 2, 3}
In [81]:
digits
Out[81]:
{0, 1, 2, 3}
In [82]:
digits = {0, 0, 1, 1, 2, 3}
print(digits)
{0, 1, 2, 3}
In [83]:
x = 1
y = 2
z = x+ y
print(z**2)
9

multiple assignments

In [84]:
numbers
Out[84]:
[1, 1, 2, 3, 5, 8, 12]
In [85]:
head, tail = numbers[0], numbers[-1]
In [86]:
print(head, tail)
1 12
In [87]:
2,3
Out[87]:
(2, 3)
In [88]:
x, y = [42, 0]
In [89]:
x, y
Out[89]:
(42, 0)
In [90]:
head, tail, count = numbers[0], numbers[-1], len(numbers)
In [91]:
head, tail, _ = numbers[0], numbers[-1], len(numbers)
In [92]:
head
Out[92]:
1
In [93]:
del head
In [94]:
head
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-94-86a12f2d6251> in <module>
----> 1 head

NameError: name 'head' is not defined
In [95]:
len(digits)
Out[95]:
4

Boleans are there which talk able truth!

In [96]:
yes = True
arrrr = False
In [97]:
2 > 3
Out[97]:
False
In [98]:
3 >= 5
Out[98]:
False
In [101]:
0 in digits # check if 0 is in set digits
Out[101]:
True
In [100]:
9 in digits
Out[100]:
False
In [103]:
9 not in digits
Out[103]:
True

binary

In [104]:
binary = b'\x064'
In [105]:
print(binary)
b'\x064'
In [106]:
binary = b"binary"
In [107]:
binary
Out[107]:
b'binary'

built in functions

In [108]:
numbers
Out[108]:
[1, 1, 2, 3, 5, 8, 12]
In [109]:
specs
Out[109]:
{'cpu': 'core-i5', 'memory': 8, 'os': 'linux'}
In [110]:
digits
Out[110]:
{0, 1, 2, 3}
In [111]:
multiline
Out[111]:
'This is multi\nline string in python\nwhich has three lines\n'
In [116]:
len(numbers) # length of list
Out[116]:
7
In [117]:
len(specs) # length of dict
Out[117]:
3
In [118]:
len(multiline) # length of string
Out[118]:
58
In [119]:
len(digits) # length of set
Out[119]:
4
In [120]:
str(2**100)
Out[120]:
'1267650600228229401496703205376'
In [121]:
int("355")
Out[121]:
355
In [123]:
float("3.14")
Out[123]:
3.14
In [124]:
list((255, 0, 0))
Out[124]:
[255, 0, 0]
In [125]:
tuple([1, 2, 2])
Out[125]:
(1, 2, 2)
In [126]:
range(10)
Out[126]:
range(0, 10)
In [127]:
list(range(10))
Out[127]:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In [128]:
sorted([2, 6, 1, 8, 3, 9, 23])
Out[128]:
[1, 2, 3, 6, 8, 9, 23]
In [129]:
max([23, 56, 787, 2])
Out[129]:
787
In [130]:
min([23, 45, 7,1])
Out[130]:
1
In [133]:
max(["one", "two", "three"])
Out[133]:
'two'
In [132]:
sorted(["one", "two", "three"])
Out[132]:
['one', 'three', 'two']
In [134]:
sum([1, 2, 3, 4])
Out[134]:
10
In [135]:
2 + "3"
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-135-6af4f0f0a881> in <module>
----> 1 2 + "3"

TypeError: unsupported operand type(s) for +: 'int' and 'str'
In [136]:
"3" + "2"
Out[136]:
'32'

example

  • find number of digits in 2**100
In [137]:
 result = 2**100
In [138]:
result
Out[138]:
1267650600228229401496703205376
In [139]:
len(result)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-139-69290ace8698> in <module>
----> 1 len(result)

TypeError: object of type 'int' has no len()
In [140]:
str(result)
Out[140]:
'1267650600228229401496703205376'
In [141]:
len(str(result))
Out[141]:
31

Writing custom functions

In [143]:
def add(x, y):
    z = x + y
    return z
In [144]:
add
Out[144]:
<function __main__.add(x, y)>
In [145]:
add(2, 3)
Out[145]:
5
In [146]:
def compute_powers(x):
    sqr = x*x
    cube = x*x*x
    forth = x**4
    return sqr, cube, forth
In [147]:
x_2, x_3, x_4 = compute_powers(2)
In [149]:
print(x_2, x_3, x_4)
4 8 16
In [152]:
def say_hello(person):
    print("Hello", person)
In [153]:
say_hello("vikrant")
Hello vikrant
In [154]:
return_value = say_hello("vikrant")
Hello vikrant
In [155]:
return_value
In [156]:
print(return_value)
None
In [157]:
def twice1(x):
    print(2*x)
    
def twice(x):
    return 2*x
In [158]:
twice1(2)
4
In [159]:
twice(2)
Out[159]:
4
In [160]:
twice_twice_5 = twice1(twice1(5))
10
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-160-f66280a1e2ca> in <module>
----> 1 twice_twice_5 = twice1(twice1(5))

<ipython-input-157-6e505808b8a1> in twice1(x)
      1 def twice1(x):
----> 2     print(2*x)
      3 
      4 def twice(x):
      5     return 2*x

TypeError: unsupported operand type(s) for *: 'int' and 'NoneType'
In [161]:
twice_twice_5 = twice(twice(5))
In [162]:
twice_twice_5
Out[162]:
20
In [163]:
twice1(twice(5))
20

problems

  • Write a function square to square a number
  • Write a function sumnaturals to find sum of first n natural numbers
  • Write a function even to find if given integer is even or not
In [164]:
2 == 3
Out[164]:
False
In [165]:
def square(x):
    return x*x
In [166]:
square(5)
Out[166]:
25
In [167]:
def sumnaturals(n):
    return sum(range(n+1))
In [168]:
sumnaturals(10)
Out[168]:
55
In [169]:
def even(n):
    return n%2 == 0
In [170]:
def odd(n):
    return not even(n)
In [173]:
def even(n):
    result = n%2
    return result == 2
In [174]:
even(3)
Out[174]:
False
In [175]:
sum = 6
In [176]:
sumnaturals(2)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-176-245b7da32bcb> in <module>
----> 1 sumnaturals(2)

<ipython-input-167-3295eb396fbb> in sumnaturals(n)
      1 def sumnaturals(n):
----> 2     return sum(range(n+1))

TypeError: 'int' object is not callable
In [177]:
sumnaturals
Out[177]:
<function __main__.sumnaturals(n)>
In [181]:
sum = 6
In [179]:
sum_ = 6
In [180]:
del sum
In [182]:
sumnaturals(5)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-182-97d4859cfbd3> in <module>
----> 1 sumnaturals(5)

<ipython-input-167-3295eb396fbb> in sumnaturals(n)
      1 def sumnaturals(n):
----> 2     return sum(range(n+1))

TypeError: 'int' object is not callable
In [189]:
def foo(x):
    return x**2
In [187]:
foo(5)
Out[187]:
'foo 5'
In [188]:
foo(5)
Out[188]:
'foo 5'
In [190]:
help(range)
Help on class range in module builtins:

class range(object)
 |  range(stop) -> range object
 |  range(start, stop[, step]) -> range object
 |  
 |  Return an object that produces a sequence of integers from start (inclusive)
 |  to stop (exclusive) by step.  range(i, j) produces i, i+1, i+2, ..., j-1.
 |  start defaults to 0, and stop is omitted!  range(4) produces 0, 1, 2, 3.
 |  These are exactly the valid indices for a list of 4 elements.
 |  When step is given, it specifies the increment (or decrement).
 |  
 |  Methods defined here:
 |  
 |  __bool__(self, /)
 |      self != 0
 |  
 |  __contains__(self, key, /)
 |      Return key in self.
 |  
 |  __eq__(self, value, /)
 |      Return self==value.
 |  
 |  __ge__(self, value, /)
 |      Return self>=value.
 |  
 |  __getattribute__(self, name, /)
 |      Return getattr(self, name).
 |  
 |  __getitem__(self, key, /)
 |      Return self[key].
 |  
 |  __gt__(self, value, /)
 |      Return self>value.
 |  
 |  __hash__(self, /)
 |      Return hash(self).
 |  
 |  __iter__(self, /)
 |      Implement iter(self).
 |  
 |  __le__(self, value, /)
 |      Return self<=value.
 |  
 |  __len__(self, /)
 |      Return len(self).
 |  
 |  __lt__(self, value, /)
 |      Return self<value.
 |  
 |  __ne__(self, value, /)
 |      Return self!=value.
 |  
 |  __reduce__(...)
 |      Helper for pickle.
 |  
 |  __repr__(self, /)
 |      Return repr(self).
 |  
 |  __reversed__(...)
 |      Return a reverse iterator.
 |  
 |  count(...)
 |      rangeobject.count(value) -> integer -- return number of occurrences of value
 |  
 |  index(...)
 |      rangeobject.index(value, [start, [stop]]) -> integer -- return index of value.
 |      Raise ValueError if the value is not present.
 |  
 |  ----------------------------------------------------------------------
 |  Static methods defined here:
 |  
 |  __new__(*args, **kwargs) from builtins.type
 |      Create and return a new object.  See help(type) for accurate signature.
 |  
 |  ----------------------------------------------------------------------
 |  Data descriptors defined here:
 |  
 |  start
 |  
 |  step
 |  
 |  stop

In [196]:
range?
In [198]:
# above statement will work only inside jupyter/ipython
In [201]:
def sumnaturals(n):
    """
    find sum of first n natural numbers
    >>> sumnaturals(3)
    6
    """
    return sum(range(1, n+1))
In [200]:
help(sumnaturals)
Help on function sumnaturals in module __main__:

sumnaturals(n)
    find sum of first n natural numbers

More about functions

In [204]:
def sumofsquares(a, b):
    return square(a) + square(b)


def sumofcubes(a, b):
    return cube(a) + cube(b)

def cube(x):
    return x**3

def sumof(f, x, y):
    return f(x) + f(y)
In [203]:
add
Out[203]:
<function __main__.add(x, y)>
In [205]:
sumofsquares(5, 6)
Out[205]:
61
In [206]:
sumof(square, 5, 6)
Out[206]:
61
In [207]:
sumofcubes(5, 6)
Out[207]:
341
In [208]:
sumof(cube, 5, 6)
Out[208]:
341
In [209]:
words = ["one", "two", "three", "four", "five"]
In [210]:
max(words)
Out[210]:
'two'
In [212]:
max(words, key=len) # parameters can be passed by name
Out[212]:
'three'
In [213]:
sorted(words)
Out[213]:
['five', 'four', 'one', 'three', 'two']
In [214]:
sorted(words, key=len)
Out[214]:
['one', 'two', 'four', 'five', 'three']
In [215]:
sorted(words, key=len, reverse=True)
Out[215]:
['three', 'four', 'five', 'one', 'two']
In [216]:
max(words, len)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-216-173597093508> in <module>
----> 1 max(words, len)

TypeError: '>' not supported between instances of 'builtin_function_or_method' and 'list'
In [217]:
max(words, key=len)
Out[217]:
'three'
In [230]:
records = [
    ("Vishakha", 7.8),
    ("Vishal", 4.5),
    ("Vaishali", 8),
    ("Vishwas", 6),
    ("Vijaya", 5.0)
]
In [224]:
max(records)
Out[224]:
('Vishwas', 6)
In [225]:
sorted(records)
Out[225]:
[('Vaishali', 8),
 ('Vijaya', 5.0),
 ('Vishakha', 7.8),
 ('Vishal', 4.5),
 ('Vishwas', 6)]
In [226]:
def get_score(r):
    return r[1]

max(records, key=get_score)
Out[226]:
('Vaishali', 8)
In [227]:
min(records,key = get_score)
Out[227]:
('Vishal', 4.5)
In [229]:
records3 = [
    ("Vishakha", 7.8, 1),
    ("Vishal", 4.5, 2),
    ("Vaishali", 8, 3),
    ("Vishwas", 6, 4),
    ("Vijaya", 5.0, 5)
]
In [231]:
def get_roll(r):
    return r[2]

def get_name(r):
    return r[0]
In [232]:
max(records3, key=get_roll)
Out[232]:
('Vijaya', 5.0, 5)
In [233]:
max(records3, key=get_name)
Out[233]:
('Vishwas', 6, 4)
In [236]:
sorted_records = sorted(records3, key=get_score)
In [239]:
sorted_records[:2] # top two
Out[239]:
[('Vishal', 4.5, 2), ('Vijaya', 5.0, 5)]
In [240]:
sorted(sorted_records, key=get_score)
Out[240]:
[('Vishal', 4.5, 2),
 ('Vijaya', 5.0, 5),
 ('Vishwas', 6, 4),
 ('Vishakha', 7.8, 1),
 ('Vaishali', 8, 3)]

Function as return value

In [241]:
def make_logger(type_):
    
    def logger(message):
        print("[" + type_.upper() + "]:", message)
        
    return logger
In [242]:
warn = make_logger("warning")
error = make_logger("error")
info = make_logger("info")
critical = make_logger("critical")
In [243]:
warn
Out[243]:
<function __main__.make_logger.<locals>.logger(message)>
In [244]:
warn("This is warning message ..be careful")
[WARNING]: This is warning message ..be careful
In [245]:
error("Some thing wrong...Error")
[ERROR]: Some thing wrong...Error
In [246]:
info("just for your information")
[INFO]: just for your information
In [247]:
critical("You are doomed!")
[CRITICAL]: You are doomed!
In [248]:
def make_adder(x):
    def adder(y):
        return x+y
    return adder
In [249]:
adder5 = make_adder(5)
In [250]:
adder5(10)
Out[250]:
15
In [251]:
adder7 = make_adder(7)
In [252]:
adder7(10)
Out[252]:
17

There is a handy way of writing a function on fly

In [253]:
max(records, key=lambda r: r[1])
Out[253]:
('Vaishali', 8)
In [257]:
sqr = lambda x: x*x
In [256]:
sqr(4)
Out[256]:
16
In [258]:
def make_adder(x):
    return lambda y: x+y

methods

In [259]:
text = "This a text from some novel"
In [260]:
text.lower()
Out[260]:
'this a text from some novel'
In [261]:
text[0]
Out[261]:
'T'
In [262]:
text[0] = t
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-262-fbb80e691124> in <module>
----> 1 text[0] = t

NameError: name 't' is not defined
In [263]:
text.lower()
Out[263]:
'this a text from some novel'
In [264]:
text
Out[264]:
'This a text from some novel'
In [265]:
text.upper()
Out[265]:
'THIS A TEXT FROM SOME NOVEL'
In [266]:
text.count("o")
Out[266]:
3
In [268]:
text.index("e")
Out[268]:
8
In [269]:
text.split()
Out[269]:
['This', 'a', 'text', 'from', 'some', 'novel']
In [270]:
commaseperated = "Helo,this,is,another,text"
In [271]:
commaseperated.split(",")
Out[271]:
['Helo', 'this', 'is', 'another', 'text']
In [272]:
multiline
Out[272]:
'This is multi\nline string in python\nwhich has three lines\n'
In [274]:
multiline.split()
Out[274]:
['This',
 'is',
 'multi',
 'line',
 'string',
 'in',
 'python',
 'which',
 'has',
 'three',
 'lines']
In [275]:
text.split(" ")
Out[275]:
['This', 'a', 'text', 'from', 'some', 'novel']
In [276]:
text.split()
Out[276]:
['This', 'a', 'text', 'from', 'some', 'novel']
In [277]:
multiline.split(" ")
Out[277]:
['This',
 'is',
 'multi\nline',
 'string',
 'in',
 'python\nwhich',
 'has',
 'three',
 'lines\n']
In [278]:
multiline.split("\n")
Out[278]:
['This is multi', 'line string in python', 'which has three lines', '']
In [280]:
trailing = " hello there..... I am just adding few trailing \n"
In [281]:
trailing.strip()
Out[281]:
'hello there..... I am just adding few trailing'
In [282]:
def get_words(textdata):
    return textdata.strip().split()
In [283]:
get_words(multiline)
Out[283]:
['This',
 'is',
 'multi',
 'line',
 'string',
 'in',
 'python',
 'which',
 'has',
 'three',
 'lines']
In [284]:
text.startswith("T")
Out[284]:
True
In [285]:
text.endswith("py")
Out[285]:
False
In [286]:
"this" in text
Out[286]:
False
In [287]:
"this" in text.lower()
Out[287]:
True
In [288]:
text.center(50)
Out[288]:
'           This a text from some novel            '
In [289]:
text.rjust(50)
Out[289]:
'                       This a text from some novel'
In [290]:
text.ljust(50)
Out[290]:
'This a text from some novel                       '
In [292]:
"this".lower() == "This".lower()
Out[292]:
True
In [324]:
text.split()
Out[324]:
['This', 'a', 'text', 'from', 'some', 'novel']
In [325]:
words = text.split()
In [326]:
words
Out[326]:
['This', 'a', 'text', 'from', 'some', 'novel']
In [327]:
"_".join(words)
Out[327]:
'This_a_text_from_some_novel'
In [328]:
" ".join(words)
Out[328]:
'This a text from some novel'
In [329]:
"/".join(["","home","vikrant","trainings"])
Out[329]:
'/home/vikrant/trainings'

methods from lists

In [293]:
numbers
Out[293]:
[1, 1, 2, 3, 5, 8, 12]
In [294]:
numbers.count(1)
Out[294]:
2
In [295]:
numbers.append(23)
In [296]:
numbers
Out[296]:
[1, 1, 2, 3, 5, 8, 12, 23]
In [297]:
numbers.pop()
Out[297]:
23
In [298]:
numbers
Out[298]:
[1, 1, 2, 3, 5, 8, 12]
In [303]:
numbers.insert(0, 0)
In [304]:
numbers.remove(0) #removes item
In [305]:
empty = []
In [306]:
empty.append(1)
In [307]:
empty.append(1)
In [308]:
print(empty)
[1, 1]
In [309]:
randomnums = [3, 6, 2, 1, 87, 2]
In [316]:
randomnums.sort() # sorts list in place
In [311]:
randomnums
Out[311]:
[1, 2, 2, 3, 6, 87]
In [312]:
sorted(numbers)
Out[312]:
[1, 1, 2, 3, 5, 8, 12]
In [317]:
sorted(randomnums, reverse=True) # does not change original list
Out[317]:
[87, 6, 3, 2, 2, 1]
In [315]:
randomnums
Out[315]:
[1, 2, 2, 3, 6, 87]

tuples

In [318]:
t = (1, 0, 1)
In [319]:
t.index(0)
Out[319]:
1
In [320]:
t.count(1)
Out[320]:
2
In [322]:
nums_copy = numbers.copy()
In [323]:
nums_copy
Out[323]:
[1, 1, 2, 3, 5, 8, 12]

problems

  • Write a function count_zeros which counts number of zeros from 2**100
  • There a list containing some names. find name that comes last in dictinary order.
names = ["anand", "Boby", "chitra", "David"]
  • given a miltigidit integer rearrange its digits to from a max number
    >>> rearrangemax(4367)
    7643
In [330]:
2**100
Out[330]:
1267650600228229401496703205376
In [331]:
ord("a")
Out[331]:
97
In [332]:
ord("A")
Out[332]:
65
In [333]:
def count_zeros(n):
    return str(n).count("0")
In [334]:
count_zeros(2**100)
Out[334]:
6
In [335]:
count_zeros(2**1000)
Out[335]:
28
In [336]:
names = ["anand", "Boby", "chitra", "David"]
In [337]:
def ignorecase(text):
    return text.lower()

max(names, key=ignorecase)
Out[337]:
'David'
In [343]:
def rearrangemax(n):
    digits = list(str(n))
    return int("".join(sorted(digits, reverse=True)))
In [344]:
rearrangemax(45378)
Out[344]:
87543
In [345]:
list("3443")
Out[345]:
['3', '4', '4', '3']

modules

In [349]:
import math # this import math module
In [350]:
math.pi
Out[350]:
3.141592653589793
In [351]:
from math import pi # only imports pi
In [352]:
pi
Out[352]:
3.141592653589793
In [353]:
import math as m
In [354]:
import numpy as np
import pandas as pd
In [355]:
m.sin(pi/4)
Out[355]:
0.7071067811865475
In [356]:
math.sin(pi/4)
Out[356]:
0.7071067811865475
In [357]:
import time
In [358]:
time.time()
Out[358]:
1576747844.3557773
In [359]:
time.asctime()
Out[359]:
'Thu Dec 19 15:01:00 2019'
In [362]:
%%file date.py
import time

def print_date():
    print(time.asctime())
    
#print_date()
Overwriting date.py
In [363]:
import date
In [364]:
date.print_date()
Thu Dec 19 15:03:12 2019
In [365]:
!python date.py
In [366]:
%%file date1.py
import time

def print_date():
    print(time.asctime())
    
print_date()
Writing date1.py
In [367]:
!python date1.py
Thu Dec 19 15:06:06 2019
In [368]:
import date1
Thu Dec 19 15:06:58 2019

magic variable __name__

In [369]:
%%file magic.py

print(__name__)
Writing magic.py
In [370]:
!python magic.py
__main__
In [371]:
import magic
magic
In [372]:
%%file today.py

import time

def print_date():
    print(time.asctime())
    
if __name__ == "__main__":
    print_date()
Writing today.py
In [373]:
import today
In [374]:
!python today.py
Thu Dec 19 15:13:16 2019

conditions and if statement

In [375]:
2 > 3
Out[375]:
False
In [376]:
2 == 2
Out[376]:
True
In [377]:
first == "Rupali"
Out[377]:
True
In [378]:
specs
Out[378]:
{'cpu': 'core-i5', 'memory': 8, 'os': 'linux'}
In [379]:
"os" in specs
Out[379]:
True
In [380]:
names
Out[380]:
['anand', 'Boby', 'chitra', 'David']
In [381]:
"anand" in names
Out[381]:
True
In [382]:
text
Out[382]:
'This a text from some novel'
In [383]:
"novel" in text
Out[383]:
True
In [386]:
"today.py".endswith("py")
Out[386]:
True
In [387]:
cond1 = 2>3
In [388]:
cond2 = "hel" in "hello"
In [389]:
cond1 or cond2
Out[389]:
True
In [390]:
cond1 and cond
Out[390]:
False
In [391]:
not cond1
Out[391]:
True
In [392]:
def check_file_type(filename):
    if filename.endswith(".py"):
        return "python"
    elif filename.endswith(".exe"):
        return "executable"
    elif filename.endswith(".txt"):
        return "text"
    else:
        return "Unknown"
In [393]:
check_file_type("hello.py")
Out[393]:
'python'
In [394]:
def min2(x, y):
    if x < y:
        return x
    else:
        return y
In [395]:
min2(5, 45)
Out[395]:
5
In [396]:
min2(45, 5)
Out[396]:
5

problems

  • Write a function min3 which find minimum number from gvien three numbers
>>> min3(6,2,8)
2
  • Write a function min4 which ffinds minimum from given four numbers
>>> min4(8, 2, 5, 7)
2
In [397]:
def min3(x, y, z):
    return min2(min2(x, y), z)
In [398]:
def min4(p, q, r, s):
    return min2(min3(p, q, r), s)
In [403]:
%%file minimum.py

def min2(x, y):
    """
    >>> min2(2, 3)
    2
    >>> min2(3, 2)
    2
    >>> min2(2, 2)
    2
    """
    if x < y:
        return x
    else:
        return y

def min3(x, y, z):
    """
    >>> min3(1, 2, 3)
    1
    >>> min3(2, 1, 3)
    1
    >>> min3(2,3,1)
    1
    """
    return min2(min2(x, y), z)

def min4(p, q, r, s):
    """
    >>> min4(1, 1, 2, 3)
    2
    """
    return min2(min3(p, q, r), s)
Overwriting minimum.py
In [404]:
!python -m doctest -v minimum.py
Trying:
    min2(2, 3)
Expecting:
    2
ok
Trying:
    min2(3, 2)
Expecting:
    2
ok
Trying:
    min2(2, 2)
Expecting:
    2
ok
Trying:
    min3(1, 2, 3)
Expecting:
    1
ok
Trying:
    min3(2, 1, 3)
Expecting:
    1
ok
Trying:
    min3(2,3,1)
Expecting:
    1
ok
Trying:
    min4(1, 1, 2, 3)
Expecting:
    2
**********************************************************************
File "/home/vikrant/trainings/2019/grofers_basic_dec/minimum.py", line 29, in minimum.min4
Failed example:
    min4(1, 1, 2, 3)
Expected:
    2
Got:
    1
1 items had no tests:
    minimum
2 items passed all tests:
   3 tests in minimum.min2
   3 tests in minimum.min3
**********************************************************************
1 items had failures:
   1 of   1 in minimum.min4
7 tests in 4 items.
6 passed and 1 failed.
***Test Failed*** 1 failures.
In [405]:
!pip install pytest
Requirement already satisfied: pytest in /home/vikrant/anaconda3/lib/python3.7/site-packages (5.0.1)
Requirement already satisfied: py>=1.5.0 in /home/vikrant/anaconda3/lib/python3.7/site-packages (from pytest) (1.8.0)
Requirement already satisfied: packaging in /home/vikrant/anaconda3/lib/python3.7/site-packages (from pytest) (19.0)
Requirement already satisfied: attrs>=17.4.0 in /home/vikrant/anaconda3/lib/python3.7/site-packages (from pytest) (19.1.0)
Requirement already satisfied: more-itertools>=4.0.0 in /home/vikrant/anaconda3/lib/python3.7/site-packages (from pytest) (7.0.0)
Requirement already satisfied: atomicwrites>=1.0 in /home/vikrant/anaconda3/lib/python3.7/site-packages (from pytest) (1.3.0)
Requirement already satisfied: pluggy<1.0,>=0.12 in /home/vikrant/anaconda3/lib/python3.7/site-packages (from pytest) (0.12.0)
Requirement already satisfied: importlib-metadata>=0.12 in /home/vikrant/anaconda3/lib/python3.7/site-packages (from pytest) (0.17)
Requirement already satisfied: wcwidth in /home/vikrant/anaconda3/lib/python3.7/site-packages (from pytest) (0.1.7)
Requirement already satisfied: pyparsing>=2.0.2 in /home/vikrant/anaconda3/lib/python3.7/site-packages (from packaging->pytest) (2.4.0)
Requirement already satisfied: six in /home/vikrant/anaconda3/lib/python3.7/site-packages (from packaging->pytest) (1.12.0)
Requirement already satisfied: zipp>=0.5 in /home/vikrant/anaconda3/lib/python3.7/site-packages (from importlib-metadata>=0.12->pytest) (0.5.1)
In [409]:
%%file test_min.py
import minimum

def test_min2():
    assert minimum.min2(1, 2)==1
    assert minimum.min2(1,1)==1
    assert minimum.min2(2,1)==1

def test_min3():
    assert minimum.min3(1, 2, 3)==1
    assert minimum.min3(1,1, 1)==1
    assert minimum.min3(2,1, -1)==1
    
Overwriting test_min.py
In [410]:
!pytest test_min.py
============================= test session starts ==============================
platform linux -- Python 3.7.3, pytest-5.0.1, py-1.8.0, pluggy-0.12.0
rootdir: /home/vikrant/trainings/2019/grofers_basic_dec
plugins: doctestplus-0.3.0, arraydiff-0.3, remotedata-0.3.1, openfiles-0.3.2
collected 2 items                                                              

test_min.py .F                                                           [100%]

=================================== FAILURES ===================================
__________________________________ test_min3 ___________________________________

    def test_min3():
        assert minimum.min3(1, 2, 3)==1
        assert minimum.min3(1,1, 1)==1
>       assert minimum.min3(2,1, -1)==1
E       assert -1 == 1
E        +  where -1 = <function min3 at 0x7f86858ba9d8>(2, 1, -1)
E        +    where <function min3 at 0x7f86858ba9d8> = minimum.min3

test_min.py:11: AssertionError
====================== 1 failed, 1 passed in 0.06 seconds ======================
In [408]:
!pytest
============================= test session starts ==============================
platform linux -- Python 3.7.3, pytest-5.0.1, py-1.8.0, pluggy-0.12.0
rootdir: /home/vikrant/trainings/2019/grofers_basic_dec
plugins: doctestplus-0.3.0, arraydiff-0.3, remotedata-0.3.1, openfiles-0.3.2
collected 1 item                                                               

test_min.py .                                                            [100%]

=========================== 1 passed in 0.02 seconds ===========================
In [411]:
import random
In [412]:
nums = ["one", "two", "three", "four", "five", "six"]
In [413]:
random.choice(nums)
Out[413]:
'five'
In [415]:
random.choice(nums)
Out[415]:
'three'
In [416]:
random.choice(nums)
Out[416]:
'three'
In [417]:
random.choice(nums)
Out[417]:
'one'
In [419]:
random.choices(nums, k=2)
Out[419]:
['five', 'four']
In [420]:
random.random()
Out[420]:
0.318122460757274
In [421]:
help(max)
Help on built-in function max in module builtins:

max(...)
    max(iterable, *[, default=obj, key=func]) -> value
    max(arg1, arg2, *args, *[, key=func]) -> value
    
    With a single iterable argument, return its biggest item. The
    default keyword-only argument specifies an object to return if
    the provided iterable is empty.
    With two or more arguments, return the largest argument.

Command line arguments

In [422]:
import sys
In [423]:
%%file square.py

import sys

def square(x):
    return x*x

if __name__ == "__main__":
    print(sys.argv)
    n = int(sys.argv[1])
    print(square(n))
Writing square.py
In [424]:
!python square.py 2
['square.py', '2']
4
In [425]:
!python square.py 2 2 3 4 5
['square.py', '2', '2', '3', '4', '5']
4
In [426]:
%%file square1.py

import sys

def square(x):
    return x*x

if __name__ == "__main__":
    n = int(sys.argv[1])
    print(square(n))
Writing square1.py
In [427]:
!python square1.py 6
36

Looping techniques

In [428]:
def print_fib(n):
    prev, cur = 1, 1
    while cur < n:
        prev, cur = cur, prev+cur
        print(prev, end=",")
In [429]:
print_fib(100)
1,2,3,5,8,13,21,34,55,89,

for loop

In [431]:
for num in numbers:
    print(num, end=" ")
1 1 2 3 5 8 12 
In [432]:
for c in "This is some text to go through!":
    print(c, end=" ")
T h i s   i s   s o m e   t e x t   t o   g o   t h r o u g h ! 
In [433]:
for item in specs:
    print(item)
cpu
memory
os
In [434]:
for item in (1, 1, 1, 2, 3, 4):
    print(item, end=" ")
1 1 1 2 3 4 
In [435]:
charset = set("this is some text to be used for testing set...how many char?")
In [437]:
for c in charset:
    print(c, end=",")
h,x,m,d,t,y,i,?,n, ,b,w,u,o,g,r,.,a,s,f,c,e,
In [438]:
def sumlist(numbers):
    s = 0 
    for num in numbers:
        s += num
    return s
In [439]:
sumlist([1,2,3,4,5,6])
Out[439]:
21

list slicing

In [440]:
fibnums = [1,2,3,5,8,13,21,34,55,89]
In [441]:
len(fibnums)
Out[441]:
10
In [443]:
fibnums[3:7] # starts at index 3 ends at index 6
Out[443]:
[5, 8, 13, 21]
In [444]:
fibnums[2:9:2] # start at index 2 end at index 8 at interval of 2
Out[444]:
[3, 8, 21, 55]
In [445]:
fibnums[:] # copy
Out[445]:
[1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
In [447]:
fibnums[::2] # take alternate items
Out[447]:
[1, 3, 8, 21, 55]
In [448]:
fibnums[::-1] #reverse
Out[448]:
[89, 55, 34, 21, 13, 8, 5, 3, 2, 1]
In [449]:
fibnums[:2] # take first two
Out[449]:
[1, 2]
In [450]:
fibnums[3:] # drop first 3
Out[450]:
[5, 8, 13, 21, 34, 55, 89]
In [452]:
fibnums[:-2] #drop last two
Out[452]:
[1, 2, 3, 5, 8, 13, 21, 34]

problems

  • Write a python script mysum.py which takes variable number of arguments from commandline and find sum of all numbers.
python mysum.py 1 2 3 4
10
python mysum.py 2 3
5
In [453]:
args = ["mysum.py", "1", "2", "3", "4"]
In [454]:
args[1:]
Out[454]:
['1', '2', '3', '4']
In [455]:
%%file mysum.py
import sys

def mysum(items):
    s = 0
    for item in items:
        s += int(item)
    return s

if __name__ == "__main__":
    print(mysum(sys.argv[1:]))
Writing mysum.py
In [456]:
!python mysum.py 1 2 3 4 5
15

Understanding Environment

In [457]:
x = [1, 1, 0]
y = x
y.append(-1)
print(x)
[1, 1, 0, -1]
In [458]:
x = [1, 1, 1]
y = x
y = [0, 0, 0]
print(x)
[1, 1, 1]
In [459]:
def append_one(nums):
    nums.append(1)
In [461]:
x = [0, 0, 0]
append_one(x)
print(x)
[0, 0, 0, 1]
In [462]:
def foo(nums):
    nums = [1,2,3]
    
x = [0, 0, 0]
foo(x)
print(x)
[0, 0, 0]
In [463]:
def bar(x):
    return x+y
    
In [464]:
del x,y
In [466]:
bar(4)
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-466-2f698661c33a> in <module>
----> 1 bar(4)

<ipython-input-463-864057ed7fa4> in bar(x)
      1 def bar(x):
----> 2     return x+y
      3 

NameError: name 'y' is not defined
In [467]:
y = 10
In [468]:
bar(5)
Out[468]:
15
In [470]:
def foobar(x):
    global y
    y = 15
    return x+y
In [471]:
foobar(4)
Out[471]:
19
In [472]:
y
Out[472]:
15
In [ ]: