Basic Python Training at Arcesium - Day 2

Nov 26-30, 2018 Vikrant Patil

These notes are available online at http://notes.pipal.in/2018/arcesium-basic-nov/day2.html

© Pipal Academy LLP

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

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

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

In [1]:
len_ = len(range(10)) 
In [6]:
len = 5 # don't use builtins as variable names
In [3]:
len([1,2,3])
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-3-585ba3dd93cc> in <module>()
----> 1 len([1,2,3])

TypeError: 'int' object is not callable
In [30]:
del len
In [31]:
len([1,2,3])
Out[31]:
3
In [7]:
name = "Alice"
In [8]:
name.upper()
Out[8]:
'ALICE'
In [9]:
name.lower()
Out[9]:
'alice'
In [10]:
name.split("i")
Out[10]:
['Al', 'ce']
In [11]:
name_ = "  Alice   "
In [13]:
name_.strip() # it removes only trailing spaces
Out[13]:
'Alice'
In [14]:
fullname = "Alice in wonderland    "
In [15]:
fullname.strip()
Out[15]:
'Alice in wonderland'
In [16]:
def functionname(paramater):
    upper = paramater.upper()
    return upper
In [17]:
functionname("hello")
Out[17]:
'HELLO'
In [18]:
functionname(2)
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-18-c6734bb482ea> in <module>()
----> 1 functionname(2)

<ipython-input-16-b05da0133873> in functionname(paramater)
      1 def functionname(paramater):
----> 2     upper = paramater.upper()
      3     return upper

AttributeError: 'int' object has no attribute 'upper'
In [19]:
functionname("2")
Out[19]:
'2'

problem Given any text write a function to

  1. Find word count
    >>> wordcount(poem)
  2. Find line count
  3. Find charecter count
In [20]:
import this
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
In [22]:
poem = """The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
"""
In [23]:
'''
this 
is 
multiline string
'''
Out[23]:
'\nthis \nis \nmultiline string\n'
In [24]:
"""
one
two
three four
"""
Out[24]:
'\none\ntwo\nthree four\n'
In [32]:
def linecount(text):
    lines = text.split("\n")
    return len(lines)

def wordcount(text):
    words = text.split()
    return len(words)

def charcount(text):
    return len(text)
In [33]:
linecount(poem)
Out[33]:
22
In [ ]:
 
In [36]:
wordcount(poem)
Out[36]:
144
In [37]:
charcount(poem)
Out[37]:
857
In [38]:
text = "word1 word2 word3"
In [40]:
text.count(" ") + 1
Out[40]:
3
In [41]:
text = "word1 word2     word3"
In [42]:
text.count(" ") + 1
Out[42]:
7
In [43]:
s = "hello\tworld"
In [44]:
print(s)
hello	world
In [45]:
s.count(" ")
Out[45]:
0
In [46]:
s.count("\t")
Out[46]:
1

methods from list

In [47]:
numbers = [1,1,1,1, 2,2, 3, 3, 3, 4, 4, 5]
In [48]:
numbers.count(1)
Out[48]:
4
In [49]:
numbers.count(5)
Out[49]:
1
In [50]:
numbers.append(6)
In [51]:
numbers
Out[51]:
[1, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 6]
In [52]:
numbers.insert(0, -1)
In [53]:
numbers
Out[53]:
[-1, 1, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 6]
In [54]:
numbers.extend(range(6,10))
In [55]:
numbers
Out[55]:
[-1, 1, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 6, 6, 7, 8, 9]
In [56]:
numbers.extend([6,13,17.19])
In [57]:
numbers
Out[57]:
[-1, 1, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 6, 6, 7, 8, 9, 6, 13, 17.19]
In [58]:
numbers.insert(2, 100)
In [59]:
numbers
Out[59]:
[-1, 1, 100, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 6, 6, 7, 8, 9, 6, 13, 17.19]
In [60]:
sorted(numbers)
Out[60]:
[-1, 1, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 6, 6, 6, 7, 8, 9, 13, 17.19, 100]
In [61]:
sorted(numbers, reverse=True)
Out[61]:
[100, 17.19, 13, 9, 8, 7, 6, 6, 6, 5, 4, 4, 3, 3, 3, 2, 2, 1, 1, 1, 1, -1]
In [62]:
numbers.append("a")
In [63]:
sorted(numbers)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-63-b1633f3c58bf> in <module>()
----> 1 sorted(numbers)

TypeError: '<' not supported between instances of 'str' and 'int'
In [64]:
numbers.pop()
Out[64]:
'a'
In [65]:
numbers
Out[65]:
[-1, 1, 100, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 6, 6, 7, 8, 9, 6, 13, 17.19]
In [66]:
sorted(numbers)
Out[66]:
[-1, 1, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 6, 6, 6, 7, 8, 9, 13, 17.19, 100]
In [67]:
words = ["one", "two", "three", "four", "five"]
In [69]:
sorted(words)
Out[69]:
['five', 'four', 'one', 'three', 'two']
In [70]:
sorted(words, reverse=True)
Out[70]:
['two', 'three', 'one', 'four', 'five']
In [71]:
numbers.remove(-1)
In [72]:
numbers
Out[72]:
[1, 100, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 6, 6, 7, 8, 9, 6, 13, 17.19]
In [73]:
numbers.remove(6)
In [74]:
numbers
Out[74]:
[1, 100, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 6, 7, 8, 9, 6, 13, 17.19]
In [75]:
help(numbers.pop)
Help on built-in function pop:

pop(...) method of builtins.list instance
    L.pop([index]) -> item -- remove and return item at index (default last).
    Raises IndexError if list is empty or index is out of range.

In [76]:
help(numbers)
Help on list object:

class list(object)
 |  list() -> new empty list
 |  list(iterable) -> new list initialized from iterable's items
 |  
 |  Methods defined here:
 |  
 |  __add__(self, value, /)
 |      Return self+value.
 |  
 |  __contains__(self, key, /)
 |      Return key in self.
 |  
 |  __delitem__(self, key, /)
 |      Delete self[key].
 |  
 |  __eq__(self, value, /)
 |      Return self==value.
 |  
 |  __ge__(self, value, /)
 |      Return self>=value.
 |  
 |  __getattribute__(self, name, /)
 |      Return getattr(self, name).
 |  
 |  __getitem__(...)
 |      x.__getitem__(y) <==> x[y]
 |  
 |  __gt__(self, value, /)
 |      Return self>value.
 |  
 |  __iadd__(self, value, /)
 |      Implement self+=value.
 |  
 |  __imul__(self, value, /)
 |      Implement self*=value.
 |  
 |  __init__(self, /, *args, **kwargs)
 |      Initialize self.  See help(type(self)) for accurate signature.
 |  
 |  __iter__(self, /)
 |      Implement iter(self).
 |  
 |  __le__(self, value, /)
 |      Return self<=value.
 |  
 |  __len__(self, /)
 |      Return len(self).
 |  
 |  __lt__(self, value, /)
 |      Return self<value.
 |  
 |  __mul__(self, value, /)
 |      Return self*value.n
 |  
 |  __ne__(self, value, /)
 |      Return self!=value.
 |  
 |  __new__(*args, **kwargs) from builtins.type
 |      Create and return a new object.  See help(type) for accurate signature.
 |  
 |  __repr__(self, /)
 |      Return repr(self).
 |  
 |  __reversed__(...)
 |      L.__reversed__() -- return a reverse iterator over the list
 |  
 |  __rmul__(self, value, /)
 |      Return self*value.
 |  
 |  __setitem__(self, key, value, /)
 |      Set self[key] to value.
 |  
 |  __sizeof__(...)
 |      L.__sizeof__() -- size of L in memory, in bytes
 |  
 |  append(...)
 |      L.append(object) -> None -- append object to end
 |  
 |  clear(...)
 |      L.clear() -> None -- remove all items from L
 |  
 |  copy(...)
 |      L.copy() -> list -- a shallow copy of L
 |  
 |  count(...)
 |      L.count(value) -> integer -- return number of occurrences of value
 |  
 |  extend(...)
 |      L.extend(iterable) -> None -- extend list by appending elements from the iterable
 |  
 |  index(...)
 |      L.index(value, [start, [stop]]) -> integer -- return first index of value.
 |      Raises ValueError if the value is not present.
 |  
 |  insert(...)
 |      L.insert(index, object) -- insert object before index
 |  
 |  pop(...)
 |      L.pop([index]) -> item -- remove and return item at index (default last).
 |      Raises IndexError if list is empty or index is out of range.
 |  
 |  remove(...)
 |      L.remove(value) -> None -- remove first occurrence of value.
 |      Raises ValueError if the value is not present.
 |  
 |  reverse(...)
 |      L.reverse() -- reverse *IN PLACE*
 |  
 |  sort(...)
 |      L.sort(key=None, reverse=False) -> None -- stable sort *IN PLACE*
 |  
 |  ----------------------------------------------------------------------
 |  Data and other attributes defined here:
 |  
 |  __hash__ = None

In [77]:
numbers[0]
Out[77]:
1
In [79]:
numbers[2:6] # start at 2nd index till 6th (excluding)
Out[79]:
[1, 1, 1, 2]
In [81]:
numbers[2:8:2] # start at 2nd index till 8th (exclude) at interval of 2
Out[81]:
[1, 1, 2]
In [82]:
numbers[2:]
Out[82]:
[1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 6, 7, 8, 9, 6, 13, 17.19]
In [83]:
digits = list(range(10))
In [84]:
digits
Out[84]:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In [86]:
digits[2:] # drop frist two
Out[86]:
[2, 3, 4, 5, 6, 7, 8, 9]
In [87]:
digits[:5] #take first five
Out[87]:
[0, 1, 2, 3, 4]
In [88]:
digits[:]
Out[88]:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In [89]:
def head(n, seq):
    return seq[:n]
In [90]:
head(3, digits)
Out[90]:
[0, 1, 2]
In [92]:
digits[::-1] #reverse
Out[92]:
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
In [93]:
poem[0]
Out[93]:
'T'
In [94]:
poem[:50]
Out[94]:
'The Zen of Python, by Tim Peters\n\nBeautiful is bet'

tuples

In [95]:
t = (1, 2, 3, 4, 5)
In [96]:
t.count(1)
Out[96]:
1
In [97]:
t.index(3)
Out[97]:
2
In [98]:
t[:2]
Out[98]:
(1, 2)

dictionary

In [99]:
d = {"one":1,
     "two":2,
     "three":3,
     "four":4
      }
In [100]:
d
Out[100]:
{'four': 4, 'one': 1, 'three': 3, 'two': 2}
In [101]:
d.keys()
Out[101]:
dict_keys(['one', 'two', 'three', 'four'])
In [102]:
d.values()
Out[102]:
dict_values([1, 2, 3, 4])
In [103]:
"one" in d
Out[103]:
True
In [104]:
1 in d
Out[104]:
False
In [105]:
1 in d.values()
Out[105]:
True
In [106]:
numbers
Out[106]:
[1, 100, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 6, 7, 8, 9, 6, 13, 17.19]
In [111]:
first = numbers.index(1)
In [113]:
first
Out[113]:
0
In [116]:
def secondindex(seq, item):
    first = seq.index(item)
    tail = seq[first+1:]
    second = tail.index(item)
    return first + second + 1
In [118]:
secondindex(numbers, 2)
Out[118]:
6
In [119]:
numbers.index(2)
Out[119]:
5
In [120]:
d['one']
Out[120]:
1
In [121]:
d.get("one")
Out[121]:
1
In [122]:
d.get("five")
In [124]:
d.get("five", "Item not Found")
Out[124]:
'Item not Found'

conditions

In [125]:
if "hel" in "hello":
    print("hel is with hello")
    print("That means this conditon is true!")
else:
    print("That means hel is not in hello!")
hel is with hello
That means this conditon is true!
In [127]:
cond1, cond2, cond3, cond4 = [True]*4
if cond1:
    print("cond1")
elif cond2:
    print("cond2")
elif cond3:
    print("cond3")
elif cond4:
    print("cond4")
else:
    print("else")
cond1
In [128]:
cond1, cond2, cond3, cond4 = False, False, True, True
if cond1:
    print("cond1")
elif cond2:
    print("cond2")
elif cond3:
    print("cond3")
elif cond4:
    print("cond4")
else:
    print("else")
cond3
In [129]:
[1]*5
Out[129]:
[1, 1, 1, 1, 1]
In [130]:
cond1, cond2, cond3, cond4 = False, False, False, False
if cond1:
    print("cond1")
elif cond2:
    print("cond2")
elif cond3:
    print("cond3")
elif cond4:
    print("cond4")
else:
    print("else")
else

problem

  • Find type of file based on extension
    ext        type
    exe        executable
    py         python
    xlsx       excel
    doc        document
    else       unknown
In [131]:
def filetype(filename):
    if filename.endswith(".exe"):
        return "executable"
    elif filename.endswith(".py"):
        return "python"
    elif filename.endswith(".xlsx"):
        return "excel"
    elif filename.endswith("doc"):
        return "document"
    else:
        return "unknown"
In [132]:
filetype("hello.py")
Out[132]:
'python'
In [133]:
filetype("anaconda.exe")
Out[133]:
'executable'
In [134]:
filetype("system.dll")
Out[134]:
'unknown'
In [135]:
f = "virtuenv.exe"
In [136]:
filetype(f)
Out[136]:
'executable'
In [137]:
def add(x, y):
    return x+y
In [138]:
a = 3
b = 15
In [139]:
add(a, b)
Out[139]:
18
In [140]:
add(15, 20)
Out[140]:
35
In [141]:
filetype("windows.exe")
Out[141]:
'executable'
In [142]:
def findextn(filename):
    return filename.split(".")[-1]
In [143]:
def filetype_(filename):
    data = {"exe": "executable",
            "py" :  "python",
            "xlsx": "excel",
            "doc":  "document"}
    extn = findextn(filename)
    return data.get(extn, "unknown")
In [144]:
filetype_("hello.py")
Out[144]:
'python'

modules

In [145]:
import math
In [146]:
math.pi
Out[146]:
3.141592653589793
In [147]:
def cylinder_volume(radius, height):
    return math.pi*radius**2*height
In [148]:
cylinder_volume(1, 1)
Out[148]:
3.141592653589793
In [149]:
from math import pi
In [150]:
pi
Out[150]:
3.141592653589793
In [151]:
import math as pymath
In [152]:
pymath.sin(pymath.pi)
Out[152]:
1.2246467991473532e-16
In [153]:
from math import pi as pie
In [154]:
pie
Out[154]:
3.141592653589793
In [156]:
from pymath import pi
---------------------------------------------------------------------------
ModuleNotFoundError                       Traceback (most recent call last)
<ipython-input-156-23451eabb64c> in <module>()
----> 1 from pymath import pi

ModuleNotFoundError: No module named 'pymath'
In [158]:
pymath.pi
Out[158]:
3.141592653589793
In [159]:
import os
In [160]:
del pymath
In [161]:
pymath
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-161-1454b5487fcc> in <module>()
----> 1 pymath

NameError: name 'pymath' is not defined
In [165]:
import os
In [163]:
os.getcwd() #current working directory
Out[163]:
'/home/vikrant/trainings/2018/arcesium-basic-nov'
In [164]:
os.listdir() # list of all items from current directory
Out[164]:
['.ipynb_checkpoints',
 'push',
 'day1.ipynb',
 'day2.ipynb',
 'day2.html',
 'training',
 'poem.txt',
 'Makefile',
 'day1.html']
In [167]:
help(os.getcwd)
Help on built-in function getcwd in module posix:

getcwd()
    Return a unicode string representing the current working directory.

In [171]:
os.listdir("/home/vikrant/trainings/2018")
Out[171]:
['vmware-advanced-apr',
 'vmware-practical-master-sep',
 'arcesium-basic-nov',
 'vmware-jan-python',
 'arcesium-advanced-oct',
 'arcesium-basic-oct',
 'vmware-pune-jan-python',
 'vmware-advanced-may',
 'mit-pune-march',
 'vmware-feb-python']
In [172]:
training_dirs = os.listdir("/home/vikrant/trainings/2018")
In [173]:
training_dirs
Out[173]:
['vmware-advanced-apr',
 'vmware-practical-master-sep',
 'arcesium-basic-nov',
 'vmware-jan-python',
 'arcesium-advanced-oct',
 'arcesium-basic-oct',
 'vmware-pune-jan-python',
 'vmware-advanced-may',
 'mit-pune-march',
 'vmware-feb-python']
In [174]:
os.mkdir("test")
In [175]:
os.path.exists("test")
Out[175]:
True
In [176]:
os.path.isdir("test")
Out[176]:
True
In [177]:
os.path.isfile("test")
Out[177]:
False
In [178]:
os.path.getsize("day1.html")
Out[178]:
393851
In [180]:
dirpath = os.getcwd()
In [181]:
os.path.join(dirpath, "day1.html")
Out[181]:
'/home/vikrant/trainings/2018/arcesium-basic-nov/day1.html'
In [182]:
words 
Out[182]:
['one', 'two', 'three', 'four', 'five']
In [184]:
" ".join(words)
Out[184]:
'one two three four five'
In [185]:
"_".join(words)
Out[185]:
'one_two_three_four_five'
In [186]:
"/".join(words)
Out[186]:
'one/two/three/four/five'
In [187]:
setence = 'one two three four five'
In [189]:
w = setence.split()
In [190]:
w
Out[190]:
['one', 'two', 'three', 'four', 'five']
In [191]:
" ".join(w)
Out[191]:
'one two three four five'
In [192]:
w
Out[192]:
['one', 'two', 'three', 'four', 'five']
In [193]:
sent = " ".join(w)
In [194]:
sent
Out[194]:
'one two three four five'
In [195]:
w
Out[195]:
['one', 'two', 'three', 'four', 'five']

problem

  • write a function countfiles to count files from given directory (include directories as well)
In [198]:
import os
def countfiles(dirpath):
    contents = os.listdir(dirpath)
    return len(contents)
In [197]:
countfiles(".")
Out[197]:
10
In [200]:
countfiles("/home/vikrant/")
Out[200]:
78

custom modules

In [201]:
%%file wc.py
"""
A module for counting number of lines, words and charecters from given text
"""

def wordcount(text):
    """
    Counts words from given text
    """
    return len(text.split())


def linecount(text):
    return len(text.split("\n"))

def charcount(text):
    return len(text)
Writing wc.py
In [203]:
import wc
In [204]:
wc.wordcount(poem)
Out[204]:
144
In [205]:
help(wc)
Help on module wc:

NAME
    wc - A module for counting number of lines, words and charecters from given text

FUNCTIONS
    charcount(text)
    
    linecount(text)
    
    wordcount(text)
        Counts words from given text

FILE
    /home/vikrant/trainings/2018/arcesium-basic-nov/wc.py


In [206]:
os.getcwd()
Out[206]:
'/home/vikrant/trainings/2018/arcesium-basic-nov'
In [207]:
import hello
In [208]:
hello.greeting()
Hello World!
In [209]:
os.getcwd()
Out[209]:
'/home/vikrant/trainings/2018/arcesium-basic-nov'
In [211]:
def foo(x):
    print("foo:", x)
In [212]:
foo
Out[212]:
<function __main__.foo>
In [213]:
foo(4)
foo: 4
In [218]:
%%file square.py

def square(x):
    return x*x


print(square(3))
Overwriting square.py
In [219]:
!python square.py
9
In [220]:
%%file square1.py
import sys

def square(x):
    return x*x

print(sys.argv)

a = float(sys.argv[1])
print(square(a))
Writing square1.py
In [222]:
!python square1.py 5 543 hello xyz hsjdh jshdjh
['square1.py', '5', '543', 'hello', 'xyz', 'hsjdh', 'jshdjh']
25.0
In [223]:
 
Overwriting wc.py
In [224]:
with open("poem.txt") as f:
    print(f.read())
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!


In [227]:
%%file wc.py
"""
A module for counting number of lines, words and charecters from given text
"""
import sys

def wordcount(text):
    """
    Counts words from given text
    """
    return len(text.split())


def linecount(text):
    return len(text.split("\n"))

def charcount(text):
    return len(text)

filename = sys.argv[1]
with open(filename) as f:
    text = f.read()
print(linecount(text), wordcount(text), charcount(text), filename)
Overwriting wc.py
In [228]:
!python wc.py poem.txt
23 144 858 poem.txt

problem

  • Write a script add.py which adds two numbers taken from commandline
In [ ]:
%%file add.py
import sys
def add():