Python Training at VMWare Bangalore - Day

Sep 18-20 2017 Vikrant Patil

These notes are available online at http://notes.pipal.in/2017/vmware-python

© Pipal Academy LLP

Day 1 | Day 2 | Day 3

Working with files

In [1]:
%%file three.txt
one
two
three
Writing three.txt
In [2]:
fhandle = open("three.txt")
In [3]:
fhandle.read() # will read complete contents of file in single statement
Out[3]:
'one\ntwo\nthree'
In [4]:
fhandle.read()
Out[4]:
''
In [5]:
fhandle.close()
In [6]:
!python -c "import this" > data.txt
In [7]:
filehandle = open("data.txt")
In [8]:
filehandle.readline()
Out[8]:
'The Zen of Python, by Tim Peters\n'
In [9]:
lines = filehandle.readlines()
In [10]:
print(lines)
['\n', 'Beautiful is better than ugly.\n', 'Explicit is better than implicit.\n', 'Simple is better than complex.\n', 'Complex is better than complicated.\n', 'Flat is better than nested.\n', 'Sparse is better than dense.\n', 'Readability counts.\n', "Special cases aren't special enough to break the rules.\n", 'Although practicality beats purity.\n', 'Errors should never pass silently.\n', 'Unless explicitly silenced.\n', 'In the face of ambiguity, refuse the temptation to guess.\n', 'There should be one-- and preferably only one --obvious way to do it.\n', "Although that way may not be obvious at first unless you're Dutch.\n", 'Now is better than never.\n', 'Although never is often better than *right* now.\n', "If the implementation is hard to explain, it's a bad idea.\n", 'If the implementation is easy to explain, it may be a good idea.\n', "Namespaces are one honking great idea -- let's do more of those!\n"]
In [11]:
lines
Out[11]:
['\n',
 'Beautiful is better than ugly.\n',
 'Explicit is better than implicit.\n',
 'Simple is better than complex.\n',
 'Complex is better than complicated.\n',
 'Flat is better than nested.\n',
 'Sparse is better than dense.\n',
 'Readability counts.\n',
 "Special cases aren't special enough to break the rules.\n",
 'Although practicality beats purity.\n',
 'Errors should never pass silently.\n',
 'Unless explicitly silenced.\n',
 'In the face of ambiguity, refuse the temptation to guess.\n',
 'There should be one-- and preferably only one --obvious way to do it.\n',
 "Although that way may not be obvious at first unless you're Dutch.\n",
 'Now is better than never.\n',
 'Although never is often better than *right* now.\n',
 "If the implementation is hard to explain, it's a bad idea.\n",
 'If the implementation is easy to explain, it may be a good idea.\n',
 "Namespaces are one honking great idea -- let's do more of those!\n"]
In [12]:
filehandle = open("data.txt")
In [13]:
for line in filehandle.readlines():
    words = line.strip().split()
    print(len(words))
7
0
5
5
5
5
5
5
2
9
4
5
3
10
13
12
5
8
11
13
12

Do it yourself

  • Write a program cat.py equivalent to cat command in
    python cat.py three.txt
    one
    two
    three
  • Write a program head.py equivalent to unix command head. it should take first commandline argument as number of lines and second argument as filename
python head.py 5 data.txt
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
In [14]:
%%file cat.py
import sys

def print_file(filename):
    f = open(filename)
    for line in f.readlines():
        print(line.strip())
    
if __name__ == "__main__":
    print_file(sys.argv[1])
Writing cat.py
In [16]:
!python cat.py three.txt
one
two
three
In [23]:
%%file head.py
import sys

def head(filename, n):
    f = open(filename)
    
    for line in f.readlines()[:n]:
        print(line.strip())

if __name__ == "__main__":
    head(sys.argv[1], int(sys.argv[2]))
Overwriting head.py
In [24]:
!python head.py data.txt 5
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
In [27]:
%%file wc.py
"""
module wc implements unix equivalnet of wc cammand
"""
import sys

def line_count(f):
    lines = open(f).readlines()
    return len(lines)

def word_count(f):
    words = open(f).read().split()
    return len(words)
    
def char_count(f):
    return len(open(f).read())


if __name__ == "__main__":
    f = sys.argv[1]
    print(line_count(f), word_count(f), char_count(f))
    
    
Overwriting wc.py
In [28]:
!python wc.py data.txt
21 144 857
In [29]:
import os
In [47]:
files = [f for f in os.listdir(".") if f.endswith(".txt")]
files
Out[47]:
['three.txt', 'yes.txt', 'data.txt', 'other.txt']
In [48]:
import wc
max(files, key=wc.line_count)
Out[48]:
'yes.txt'
In [49]:
max(files, key=wc.word_count)
Out[49]:
'other.txt'
In [50]:
max(files, key=wc.char_count)
Out[50]:
'other.txt'

Writing files

In [51]:
f = open("primes.txt", "w")
In [52]:
f.write("two\n")
f.write("five\n")
f.write("three\n")
f.close()
In [53]:
!python cat.py primes.txt
two
five
three
In [54]:
f = open("primes.txt", "a")
f.write("seven\n")
f.write("eleven\n")
f.close()
In [55]:
!python cat.py primes.txt
two
five
three
seven
eleven

Similarly we can read and write binary files with following mode

  • rb => read in binary mode
  • wb => write in binary mode
  • ab => append in binary mode
In [56]:
open("primes.txt", "r").read() # read in text mode
Out[56]:
'two\nfive\nthree\nseven\neleven\n'
In [57]:
open("primes.txt", "rb").read()
Out[57]:
b'two\nfive\nthree\nseven\neleven\n'
In [58]:
f = open("binarydata.bin", "wb")
f.write(b'x025x082')
f.close()
In [59]:
open("binarydata.bin", "rb").read()
Out[59]:
b'x025x082'
In [60]:
f = open("binarydata.bin", "ab")
f.write(b'hello')
f.close()
In [61]:
open("binarydata.bin", "rb").read()
Out[61]:
b'x025x082hello'

with statement

In [63]:
with open("primes.txt", "a") as f:
    f.write("thirteen")
In [64]:
!python cat.py primes.txt
two
five
three
seven
eleven
thirteen
In [67]:
with open("regional.txt", "w", encoding='utf-8') as regional:
    regional.write("\u0c05\u0c06")
In [68]:
!python cat.py regional.txt
à°…à°†
In [69]:
open("regional.txt", encoding='utf-8').read()
Out[69]:
'à°…à°†'
In [70]:
open("regional.txt", 'rb').read()
Out[70]:
b'\xe0\xb0\x85\xe0\xb0\x86'

Working with dictionaries

In [72]:
author = {'name':"lewis carrol",
        "books": ["alice in wonderland", "looking through the glass"],
         "language" : "English"}
In [74]:
author['name'] = "lewis"
In [75]:
author
Out[75]:
{'books': ['alice in wonderland', 'looking through the glass'],
 'language': 'English',
 'name': 'lewis'}
In [76]:
del author['language']
In [77]:
author
Out[77]:
{'books': ['alice in wonderland', 'looking through the glass'],
 'name': 'lewis'}
In [78]:
'name' in author
Out[78]:
True
In [79]:
author['name']
Out[79]:
'lewis'
In [80]:
author.get('name')
Out[80]:
'lewis'
In [81]:
author['language']
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-81-808b3817d72f> in <module>()
----> 1 author['language']

KeyError: 'language'
In [82]:
author.get("language", "English")
Out[82]:
'English'
In [83]:
author
Out[83]:
{'books': ['alice in wonderland', 'looking through the glass'],
 'name': 'lewis'}
In [84]:
author.get("language")
In [85]:
author.get("language") == None
Out[85]:
True
In [86]:
author.get("books")
Out[86]:
['alice in wonderland', 'looking through the glass']
In [87]:
del author['books']
In [88]:
author
Out[88]:
{'name': 'lewis'}
In [89]:
author.get("books", [])
Out[89]:
[]

Iterating over dictionary

In [90]:
d = {"one":1, "two":2, "three":3}
In [91]:
for key in d.keys():
    print(key, d[key])
one 1
three 3
two 2
In [92]:
for values in d.values():
    print(values)
1
3
2
In [93]:
for key, value in d.items():
    print(key, value)
one 1
three 3
two 2

What if we iterate over dictionary directly?

In [94]:
for item in d:
    print(item)
one
three
two
In [95]:
numbers = [("one", 1), ("two", 2), ("three", 3)]
In [96]:
dict(numbers)
Out[96]:
{'one': 1, 'three': 3, 'two': 2}
In [97]:
items = ("pen", "pencil", "colorbox")
prices = (25, 10, 50)
cart = dict(zip(items, prices))
In [98]:
cart
Out[98]:
{'colorbox': 50, 'pen': 25, 'pencil': 10}
In [99]:
for item, price in cart.items():
    print(item.rjust(8), price)
print("-"*12)
print("Total".rjust(8), sum(cart.values()))
  pencil 10
colorbox 50
     pen 25
------------
   Total 85

can you write a function unzip which retuns two separate lists of keys and values

In [102]:
def unzip(d):
    return list(d.keys()), list(d.values())
In [103]:
unzip(cart)
Out[103]:
(['pencil', 'colorbox', 'pen'], [10, 50, 25])
In [104]:
%%file words.txt
five
five four
five four three
five four three two
five four three two one
six seven eight nine
six seven eight
six seven
six
Writing words.txt
In [105]:
%%file wordfreq.py

import sys

def read_words(file):
    return open(file).read().split()

def wordfreq(words):
    freq = {}
    
    for word in words:
        if word in freq:
            freq[word] += 1
        else:
            freq[word] = 1
    return freq

if __name__ == "__main__":
    words = read_words(sys.argv[1])
    freq = wordfreq(words)
    print(freq)
    
Writing wordfreq.py
In [106]:
!python wordfreq.py words.txt
{'nine': 1, 'two': 2, 'six': 4, 'four': 4, 'five': 5, 'one': 1, 'seven': 3, 'eight': 2, 'three': 3}
In [107]:
%%file wordfreq.py

import sys

def read_words(file):
    return open(file).read().split()

def wordfreq(words):
    freq = {}
    
    for word in words:
        freq[word] = freq.get(word, 0) + 1
        
    return freq

if __name__ == "__main__":
    words = read_words(sys.argv[1])
    freq = wordfreq(words)
    print(freq)
Overwriting wordfreq.py
In [108]:
!python wordfreq.py words.txt
{'three': 3, 'six': 4, 'nine': 1, 'one': 1, 'eight': 2, 'four': 4, 'two': 2, 'five': 5, 'seven': 3}
In [109]:
import wordfreq
In [110]:
words = wordfreq.read_words("words.txt")
In [111]:
freq = wordfreq.wordfreq(words)
In [112]:
for w, f in freq.items():
    print(w, f)
three 3
nine 1
five 5
two 2
one 1
seven 3
eight 2
four 4
six 4
In [113]:
for k,v in sorted(freq.items()):
    print(k.rjust(5), v)
eight 2
 five 5
 four 4
 nine 1
  one 1
seven 3
  six 4
three 3
  two 2
In [114]:
for k, v in sorted(freq.items(), key = lambda x:x[1]):
    print (k.rjust(5), v)
 nine 1
  one 1
  two 2
eight 2
three 3
seven 3
 four 4
  six 4
 five 5
In [115]:
for k, v in sorted(freq.items(), key = lambda x:x[1], reverse=True):
    print (k.rjust(5), v)
 five 5
 four 4
  six 4
three 3
seven 3
  two 2
eight 2
 nine 1
  one 1
In [116]:
for k, v in sorted(freq.items(), key = lambda x:x[1], reverse=True):
    print (k.rjust(5), v, "*"*v)
 five 5 *****
 four 4 ****
  six 4 ****
three 3 ***
seven 3 ***
  two 2 **
eight 2 **
 nine 1 *
  one 1 *

Grouping all keys based on values

In [117]:
team = {"david":"USA", "anand":"India","linus":"USA","nouful":"India","alice":"UK"}
In [118]:
[name for name in team.keys() if team[name]=="India"]
Out[118]:
['anand', 'nouful']
In [119]:
[name for name in team.keys() if team[name]=="USA"]
Out[119]:
['david', 'linus']

Pitfalls

In [120]:
x = [1,2,3]
y = x
y.append(4)
print(x)
[1, 2, 3, 4]
In [121]:
x = [1, 2, 3, 4]
y = x
y = [1, 2, 3]
print(x)
[1, 2, 3, 4]
In [122]:
x = 1
y = x
y = 2
print(x)
1

Classes

In [123]:
class Complex:
    
    def __init__(self, r, i):
        self.real = r
        self.imaginary = i
        
    def get_real(self):
        return self.real
    
    def get_imaginary(self):
        return self.imaginary
    
In [124]:
p = Complex(10, 5)
In [125]:
class Dummy:
    pass
In [126]:
d = Dummy()
In [127]:
print(d)
<__main__.Dummy object at 0x7fefccee9748>
In [128]:
class Dummy:
    def __init__(self):
        pass
In [129]:
d = Dummy()
In [130]:
print(d)
<__main__.Dummy object at 0x7fefd430d9b0>
In [132]:
p = Complex(10, 5)
In [133]:
type(p)
Out[133]:
__main__.Complex
In [134]:
isinstance(p, Complex)
Out[134]:
True
In [135]:
isinstance(p, Dummy)
Out[135]:
False
In [136]:
class Complex:
    
    def __init__(self, r, i):
        self.real = r
        self.imaginary = i
        
    def get_real(self):
        return self.real
    
    def get_imaginary(self):
        return self.imaginary
    
    def display(self):
        print(self.real, "+", str(self.imaginary) + "j")
        
    def add(self, c):
        r = self.real + c.get_real()
        i = self.imaginary + c.get_imaginary()
        return Complex(r, i)
In [137]:
p = Complex(10, 5)
In [138]:
p1 = Complex(3, 4)
In [139]:
p2 = p.add(p1)
In [140]:
p1.display()
p2.display()
p.display()
3 + 4j
13 + 9j
10 + 5j

Do it yourself

  • add provision to double the complex number

Why classes?

In [142]:
%%file bank0.py

balance = 0

def deposit(amount):
    global balance
    balance = balance + amount
    
def withdraw(amount):
    global balance
    balance = balance - amount
    
def get_balance():
    global balance
    return balance

def main():
    deposit(100)
    withdraw(40)
    print(get_balance())
    
    deposit(20)
    print(get_balance())

if __name__ =="__main__":
    main()
Overwriting bank0.py
In [143]:
!python bank0.py
60
80
In [147]:
%%file bank1.py


def make_account():
    return {"balance":0}

def deposit(account , amount):
    account['balance'] = account['balance'] + amount
    
def withdraw(account, amount):
    account['balance'] -= amount
    
def get_balance(account):
    return account['balance']

def main():
    a1 = make_account()
    deposit(a1, 100)
    withdraw(a1, 40)
    print(get_balance(a1))
    
    deposit(a1, 20)
    print(get_balance(a1))
    
    a2 = make_account()
    deposit(a2, 1000)
    withdraw(a2, 200)
    print(get_balance(a2))

if __name__ =="__main__":
    main()
Overwriting bank1.py
In [148]:
!python bank1.py
60
80
800
In [149]:
import time
In [150]:
time.time()
Out[150]:
1505900809.371694

Do it yourself

  • Write a class Timer to measure the time taken in task. The class should have start and stop methods and it shoould be able to find time taken between the two calls.hint: use time.time()
t = Timer()
t.start()
do_some_stuff()
t.stop()
print("Time taken: ", t.get_time_taken())
In [151]:
import time
class Timer:
    
    def start(self):
        self.starttime = time.time()
        
    def stop(self):
        self.endtime = time.time()
        
    def get_time_taken(self):
        return self.endtime - self.starttime
In [152]:
t = Timer()
t.start()
s = 0
for i in range(1000):
    for j in range(10000):
        s += i*j
t.stop()
print("Time taken:", t.get_time_taken())
Time taken: 1.8775839805603027

Exceptions

In [155]:
z
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-155-3a710d2a84f8> in <module>()
----> 1 z

NameError: name 'z' is not defined
In [156]:
int("Hello")
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-156-5cdea6865089> in <module>()
----> 1 int("Hello")

ValueError: invalid literal for int() with base 10: 'Hello'
In [157]:
"2" * "3"
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-157-c32b222837be> in <module>()
----> 1 "2" * "3"

TypeError: can't multiply sequence by non-int of type 'str'
In [159]:
b = "2"
c = "3"

try:
    a = b*c
except TypeError as e:
    a = 1
    print("Handled TypeError", e)
except ValueError as e:
    b = 0
    print("Handled ValueError", e)

print(a)
Handled TypeError can't multiply sequence by non-int of type 'str'
1
In [160]:
def parseinteger(strnum):
    try:
        return int(strnum)
    except ValueError as e:
        return 0

def read_with_missing(filename):
    with open(filename) as file:
        return [parseinteger(line.strip()) for line in file.readlines()]
In [161]:
%%file missing.txt
1
2
3
4
5
N/A
6
6
7
Nan
8
9
Writing missing.txt
In [162]:
read_with_missing("missing.txt")
Out[162]:
[1, 2, 3, 4, 5, 0, 6, 6, 7, 0, 8, 9]

Writing commandline applications

In [166]:
%%file command.py 
import argparse

def parse_args():
    p = argparse.ArgumentParser()
    p.add_argument("word", help="word which command.py will print to screen",
                  type=str)
    return p.parse_args()


def print_word(word):
    print(word)

def main():
    args = parse_args()
    print(args)
    print_word(args.word)
    
if __name__ == "__main__":
    main()
Overwriting command.py
In [167]:
!python command.py hello
Namespace(word='hello')
hello
In [168]:
!python command.py 
usage: command.py [-h] word
command.py: error: the following arguments are required: word
In [170]:
!python command.py -h
usage: command.py [-h] word

positional arguments:
  word        word which command.py will print to screen

optional arguments:
  -h, --help  show this help message and exit
In [179]:
%%file command.py 
import argparse

def parse_args():
    p = argparse.ArgumentParser()
    p.add_argument("word", help="word which command.py will print to screen",
                  type=str)
    p.add_argument("-u", "--username", 
                  help = "User name for executing this command")
    p.add_argument("--debug", 
               help="Debug mode",
              action="store_true")
    
    return p.parse_args()


def print_word(word):
    print("From default :", word)

def print_user(user):
    print("From -u :", user)
    
def print_debug(debug):
    if debug:
        print("From debug")
    
def main():
    args = parse_args()
    print(args)
    print_word(args.word)
    print_user(args.username)
    print_debug(args.debug)
    
if __name__ == "__main__":
    main()
Overwriting command.py
In [180]:
!python command.py -h
usage: command.py [-h] [-u USERNAME] [--debug] word

positional arguments:
  word                  word which command.py will print to screen

optional arguments:
  -h, --help            show this help message and exit
  -u USERNAME, --username USERNAME
                        User name for executing this command
  --debug               Debug mode
In [182]:
!python command.py -u vikrant --debug hello
Namespace(debug=True, username='vikrant', word='hello')
From default : hello
From -u : vikrant
From debug
In [184]:
!python command.py hello
Namespace(debug=False, username=None, word='hello')
From default : hello
From -u : None

Downloading stuff from internet

In [185]:
from urllib.request import urlopen
In [186]:
response = urlopen("http://httpbin.org/html")
In [187]:
response
Out[187]:
<http.client.HTTPResponse at 0x7fefd41c7eb8>
In [188]:
contents = response.read()
In [189]:
contents[:100]
Out[189]:
b'<!DOCTYPE html>\n<html>\n  <head>\n  </head>\n  <body>\n      <h1>Herman Melville - Moby-Dick</h1>\n\n     '
In [190]:
html = contents.decode("utf-8")
In [192]:
print(html[:400])
<!DOCTYPE html>
<html>
  <head>
  </head>
  <body>
      <h1>Herman Melville - Moby-Dick</h1>

      <div>
        <p>
          Availing himself of the mild, summer-cool weather that now reigned in these latitudes, and in preparation for the peculiarly active pursuits shortly to be anticipated, Perth, the begrimed, blistered old blacksmith, had not removed his portable forge to the hold again, af
In [193]:
response.status
Out[193]:
200

There is third party library requests

pip3 install requests
In [194]:
import requests
In [195]:
response = requests.get("http://httpbin.org/html")
In [196]:
print(response.text[:400])
<!DOCTYPE html>
<html>
  <head>
  </head>
  <body>
      <h1>Herman Melville - Moby-Dick</h1>

      <div>
        <p>
          Availing himself of the mild, summer-cool weather that now reigned in these latitudes, and in preparation for the peculiarly active pursuits shortly to be anticipated, Perth, the begrimed, blistered old blacksmith, had not removed his portable forge to the hold again, af
In [197]:
response.headers
Out[197]:
{'Via': '1.1 vegur', 'Content-Type': 'text/html; charset=utf-8', 'Connection': 'keep-alive', 'X-Powered-By': 'Flask', 'Server': 'meinheld/0.6.1', 'Date': 'Wed, 20 Sep 2017 11:22:44 GMT', 'X-Processed-Time': '0.000496864318848', 'Access-Control-Allow-Credentials': 'true', 'Access-Control-Allow-Origin': '*', 'Content-Length': '3741'}
In [198]:
response.status_code
Out[198]:
200
In [199]:
response = requests.get("http://httpbin.org/get", params={"param1":"hello", "param2":"hello2"})
In [200]:
print(response.text)
{
  "args": {
    "param1": "hello", 
    "param2": "hello2"
  }, 
  "headers": {
    "Accept": "*/*", 
    "Accept-Encoding": "gzip, deflate", 
    "Connection": "close", 
    "Host": "httpbin.org", 
    "User-Agent": "python-requests/2.18.4"
  }, 
  "origin": "42.106.10.34", 
  "url": "http://httpbin.org/get?param1=hello&param2=hello2"
}

In [201]:
response = requests.post("http://httpbin.org/post", data="some string")
In [202]:
print(response.text)
{
  "args": {}, 
  "data": "some string", 
  "files": {}, 
  "form": {}, 
  "headers": {
    "Accept": "*/*", 
    "Accept-Encoding": "gzip, deflate", 
    "Connection": "close", 
    "Content-Length": "11", 
    "Host": "httpbin.org", 
    "User-Agent": "python-requests/2.18.4"
  }, 
  "json": null, 
  "origin": "42.106.10.34", 
  "url": "http://httpbin.org/post"
}

In [203]:
url = "https://api.github.com/orgs/vmware/repos"
In [204]:
repos = requests.get(url).json()
In [205]:
type(repos)
Out[205]:
list
In [206]:
for repo in repos:
    print(repo['full_name'], repo['forks'])
vmware/pyvco 4
vmware/rvc 46
vmware/rbvmomi 152
vmware/vprobe-toolkit 8
vmware/CloudFS 15
vmware/vcd-nclient 2
vmware/lmock 5
vmware/FireBreath 2
vmware/weasel 1
vmware/vmware-vcenter 83
vmware/vmware-vshield 6
vmware/vcloud-rest 38
vmware/GemstoneWebTools 0
vmware/vmware-vcsa 17
vmware/vmware-vmware_lib 23
vmware/saml20serviceprovider 1
vmware/pg_rewind 19
vmware/vco-powershel-plugin 2
vmware/jenkins-reviewbot 12
vmware/dbeekeeper 0
vmware/thinapp_factory 16
vmware/vmware-cassandra 4
vmware/vmware-java 0
vmware/data-driven-framework 2
vmware/pyvmomi 419
vmware/pyvmomi-community-samples 352
vmware/open-vm-tools 132
vmware/pyvmomi-tools 18
vmware/upgrade-framework 11
vmware/webcommander 29
In [208]:
reps = sorted(repos, key=lambda r:r['forks'], reverse=True)[:5]
In [209]:
for r in reps:
    print(r['full_name'], r['forks'])
vmware/pyvmomi 419
vmware/pyvmomi-community-samples 352
vmware/rbvmomi 152
vmware/open-vm-tools 132
vmware/vmware-vcenter 83

Feedback please

feedback