Basic Python Training at Arcesium - Day 4

Oct 25-31, 2018 Vikrant Patil

These notes are available online at http://notes.pipal.in/2018/arcesium-basic-oct/day4.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/

Iteration patterns

In [1]:
names = ["Elsa", "Elisa", "Alex", "Oz"]
surnames = ["Frozen", "Hacker", "Lion", "Wizard"]
In [4]:
for name in names:
    print(name)
Elsa
Elisa
Alex
Oz
In [5]:
for name in reversed(names):
    print(name)
Oz
Alex
Elisa
Elsa
In [11]:
reversednames = reversed(names) # do not use it like this, use it inside for loops only!
In [12]:
print(reversednames)
<list_reverseiterator object at 0x7f867a636550>
In [13]:
for name in reversednames:
    print(name)
Oz
Alex
Elisa
Elsa
In [14]:
for name in reversednames:
    print(name)
In [16]:
for i, name in enumerate(names):
    print(i , name)
0 Elsa
1 Elisa
2 Alex
3 Oz
In [18]:
with open("numbers.txt") as f:
    for i, line in enumerate(f):
        print(i+1, line, end="")
1 one
2 two
3 three
In [23]:
nums = [i for i in range(10000)]
In [24]:
len(nums)
Out[24]:
10000
In [26]:
nums_ = (i for i in range(10000))
In [28]:
nums_
Out[28]:
<generator object <genexpr> at 0x7f867a5dce08>
In [29]:
len(nums)
Out[29]:
10000
In [30]:
len(nums_)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-30-3a12a88162b1> in <module>()
----> 1 len(nums_)

TypeError: object of type 'generator' has no len()
In [31]:
sum(nums)
Out[31]:
49995000
In [32]:
sum(nums_)
Out[32]:
49995000
In [33]:
sum(nums_)
Out[33]:
0
In [34]:
nums_1 = (i for i in range(10000))
In [35]:
a = 10
b = a
In [36]:
a = 20
In [37]:
print(a)
20
In [38]:
print(b)
10
In [40]:
la = [1,2,3,4]
lb = la
In [41]:
la.append(5)
In [42]:
lb
Out[42]:
[1, 2, 3, 4, 5]
In [44]:
for name, surname in zip(names, surnames):
    print(name, surname)
Elsa Frozen
Elisa Hacker
Alex Lion
Oz Wizard
In [45]:
for a, name in zip([1,2,3,4,5,6,7], names):
    print(a, name)
1 Elsa
2 Elisa
3 Alex
4 Oz

Working with dictionaries

In [46]:
cart = {"Pencil":10, "Pen":15, "Eraser":5, "Box":30}
In [50]:
def add(*args):
    print(args)
    return sum(args)
In [51]:
add(1,2)
(1, 2)
Out[51]:
3
In [52]:
add(1,2,3,4,5)
(1, 2, 3, 4, 5)
Out[52]:
15
In [53]:
def cylinder_volume(radius, height):
    return 3.14*radius**2*height
In [54]:
cylinder_volume(1, 1.5)
Out[54]:
4.71
In [55]:
cylinder_volume(1, height=2.0)
Out[55]:
6.28
In [56]:
cylinder_volume(radius=1, height=2.1)
Out[56]:
6.594
In [57]:
cylinder_volume(height=2.1, radius=1)
Out[57]:
6.594
In [19]:
cart = {"Pencil":10, "Pen":15, "Eraser":5, "Box":30}
In [59]:
for item in cart:
    print(item)
Pencil
Pen
Eraser
Box
In [62]:
for item in cart:
    print(cart[item])
10
15
5
30
In [63]:
for item, cost in cart.items():
    print(item, cost)
Pencil 10
Pen 15
Eraser 5
Box 30
In [64]:
for cost in cart.values():
    print(cost)
10
15
5
30
In [65]:
sum([cost for cost in cart.values()])
Out[65]:
60
In [66]:
import numpy as np
In [67]:
help(np.average)
Help on function average in module numpy.lib.function_base:

average(a, axis=None, weights=None, returned=False)
    Compute the weighted average along the specified axis.
    
    Parameters
    ----------
    a : array_like
        Array containing data to be averaged. If `a` is not an array, a
        conversion is attempted.
    axis : None or int or tuple of ints, optional
        Axis or axes along which to average `a`.  The default,
        axis=None, will average over all of the elements of the input array.
        If axis is negative it counts from the last to the first axis.
    
        .. versionadded:: 1.7.0
    
        If axis is a tuple of ints, averaging is performed on all of the axes
        specified in the tuple instead of a single axis or all the axes as
        before.
    weights : array_like, optional
        An array of weights associated with the values in `a`. Each value in
        `a` contributes to the average according to its associated weight.
        The weights array can either be 1-D (in which case its length must be
        the size of `a` along the given axis) or of the same shape as `a`.
        If `weights=None`, then all data in `a` are assumed to have a
        weight equal to one.
    returned : bool, optional
        Default is `False`. If `True`, the tuple (`average`, `sum_of_weights`)
        is returned, otherwise only the average is returned.
        If `weights=None`, `sum_of_weights` is equivalent to the number of
        elements over which the average is taken.
    
    
    Returns
    -------
    average, [sum_of_weights] : array_type or double
        Return the average along the specified axis. When returned is `True`,
        return a tuple with the average as the first element and the sum
        of the weights as the second element. The return type is `Float`
        if `a` is of integer type, otherwise it is of the same type as `a`.
        `sum_of_weights` is of the same type as `average`.
    
    Raises
    ------
    ZeroDivisionError
        When all weights along axis are zero. See `numpy.ma.average` for a
        version robust to this type of error.
    TypeError
        When the length of 1D `weights` is not the same as the shape of `a`
        along axis.
    
    See Also
    --------
    mean
    
    ma.average : average for masked arrays -- useful if your data contains
                 "missing" values
    
    Examples
    --------
    >>> data = range(1,5)
    >>> data
    [1, 2, 3, 4]
    >>> np.average(data)
    2.5
    >>> np.average(range(1,11), weights=range(10,0,-1))
    4.0
    
    >>> data = np.arange(6).reshape((3,2))
    >>> data
    array([[0, 1],
           [2, 3],
           [4, 5]])
    >>> np.average(data, axis=1, weights=[1./4, 3./4])
    array([ 0.75,  2.75,  4.75])
    >>> np.average(data, weights=[1./4, 3./4])
    Traceback (most recent call last):
    ...
    TypeError: Axis must be specified when shapes of a and weights differ.

In [69]:
np.average(list(cart.values()), weights=[0.1, 0.3, 0.4, 0.2])
Out[69]:
13.5
In [70]:
cart.values()
Out[70]:
dict_values([10, 15, 5, 30])
In [73]:
for key, value in cart.items():
    print(value, key)
10 Pencil
15 Pen
5 Eraser
30 Box
In [74]:
for key in cart.keys():
    print(key)
Pencil
Pen
Eraser
Box
In [75]:
for key in cart:
    print(key)
Pencil
Pen
Eraser
Box
In [77]:
import random

def get_data(url, s):
    return [random.random()*100 for i in range(3)]


def get_stock_data(url):
    stocks = ["Tata", "Reliance", "Infosys"]
    data = {}
    for s in stocks:
        d = get_data(url, s) # [current_price, day_change, average_of_month]
        data[s] = d
    return data
        
In [78]:
get_stock_data("skjadkjsahdjh")
Out[78]:
{'Infosys': [10.18397315328422, 94.7442051684662, 65.90579293692738],
 'Reliance': [22.777358031188456, 79.8890893329386, 10.888780534567033],
 'Tata': [6.03517766010353, 22.919606316634123, 21.406063839125665]}

problem

  • Write a function find word frequency from given file
In [79]:
%%file words.txt
one
one two
one two three
one two three four
one two three four five
one two three four six
one two three seven
one two eight
one nine
one
Writing words.txt
In [1]:
l = [1,1,1,1,2,2,2,3,4]
In [2]:
l.count(1)
Out[2]:
4
In [5]:
def get_words(filename):
    with open(filename) as f:
        return f.read().split()
In [6]:
get_words("words.txt")
Out[6]:
['one',
 'one',
 'two',
 'one',
 'two',
 'three',
 'one',
 'two',
 'three',
 'four',
 'one',
 'two',
 'three',
 'four',
 'five',
 'one',
 'two',
 'three',
 'four',
 'six',
 'one',
 'two',
 'three',
 'seven',
 'one',
 'two',
 'eight',
 'one',
 'nine',
 'one']
In [10]:
def get_freq(words):
    freq = {}
    uniq = set(words)
    for word in uniq:
        freq[word] = words.count(word)
    return freq
In [11]:
words = get_words("words.txt")
get_freq(words)
Out[11]:
{'eight': 1,
 'five': 1,
 'four': 3,
 'nine': 1,
 'one': 10,
 'seven': 1,
 'six': 1,
 'three': 5,
 'two': 7}
In [15]:
def get_words(filename):
    with open(filename) as f:
        words = []
        for line in f:
            words = words + line.split()
            #words.extend(line.split())
        return words
    
def get_words(filename):
    with open(filename) as f:
        return f.read().split()
In [16]:
get_words("words.txt")
Out[16]:
['one',
 'one',
 'two',
 'one',
 'two',
 'three',
 'one',
 'two',
 'three',
 'four',
 'one',
 'two',
 'three',
 'four',
 'five',
 'one',
 'two',
 'three',
 'four',
 'six',
 'one',
 'two',
 'three',
 'seven',
 'one',
 'two',
 'eight',
 'one',
 'nine',
 'one']
In [17]:
def get_freq(words):
    freq = {}
    uniq = set(words)
    for word in uniq:
        freq[word] = words.count(word)
    return freq

def get_freq(words):
    freq = {}
    for word in words:
        if word in freq:
            freq[word] += 1
        else:
            freq[word] = 1
    return freq
In [18]:
cart
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-18-98134a1b7d63> in <module>()
----> 1 cart

NameError: name 'cart' is not defined
In [23]:
cart['ruler']
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-23-67ef67e6e5c8> in <module>()
----> 1 cart['ruler']

KeyError: 'ruler'
In [24]:
person = {"name":"alice", "email":"alice@wonder.land"}
In [27]:
person["country"]
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-27-c97b5344276d> in <module>()
----> 1 person["country"]

KeyError: 'country'
In [28]:
person.get("country", "India")
Out[28]:
'India'
In [29]:
def get_freq(words):
    freq = {}
    for word in words:
        freq[word] = freq.get(word, 0) + 1
    return freq
In [32]:
fr = get_freq(words)
In [33]:
for word, freq in fr.items():
    print(word, freq)
one 10
two 7
three 5
four 3
five 1
six 1
seven 1
eight 1
nine 1
In [34]:
for word, freq in fr.items():
    print(word.rjust(5), freq)
  one 10
  two 7
three 5
 four 3
 five 1
  six 1
seven 1
eight 1
 nine 1
In [35]:
for word, freq in fr.items():
    print(word.rjust(5), freq*"*")
  one **********
  two *******
three *****
 four ***
 five *
  six *
seven *
eight *
 nine *
In [36]:
import requests
In [37]:
ticker = requests.get("https://koinex.in/api/ticker").json()
In [38]:
type(ticker)
Out[38]:
dict
In [39]:
len(ticker)
Out[39]:
2
In [41]:
ticker.keys()
Out[41]:
dict_keys(['prices', 'stats'])
In [42]:
type(ticker['prices'])
Out[42]:
dict
In [43]:
len(ticker['prices'])
Out[43]:
4
In [45]:
ticker['prices'].keys()
Out[45]:
dict_keys(['inr', 'bitcoin', 'ether', 'ripple'])
In [46]:
ticker['prices']['bitcoin']
Out[46]:
{'BCH': '0.066',
 'EOS': '0.001',
 'ETH': '0.02750051',
 'LTC': '0.00727275',
 'NCASH': '0.00000114',
 'OMG': '0.00027501',
 'REQ': '0.00001333',
 'TRX': '0.00000355',
 'TUSD': '0.00014',
 'XRP': '0.00007484',
 'ZCO': '0.00000195'}
In [47]:
ticker['prices']['ether']
Out[47]:
{'BCH': '2.5',
 'EOS': '0.02998',
 'LTC': '0.22',
 'OMG': '0.021998',
 'TRX': '0.00011974',
 'TUSD': '0.0029001',
 'XRP': '0.00225',
 'ZCO': '0.00005999'}
pip install requests

string formating

In [48]:
answer = 42
"Answer to every question in life is {}".format(answer)
Out[48]:
'Answer to every question in life is 42'
In [49]:
"{} of oz is {}".format("wizard", "python")
Out[49]:
'wizard of oz is python'
In [50]:
"{desg} of oz is {who}".format(desg="Wizard", who="python")
Out[50]:
'Wizard of oz is python'
In [52]:
for i in range(1,11):
    print(i, i*i, i*i*i)
1 1 1
2 4 8
3 9 27
4 16 64
5 25 125
6 36 216
7 49 343
8 64 512
9 81 729
10 100 1000
In [54]:
for i in range(1,11):
    print("{} {} {}".format(i, i*i, i*i*i))
1 1 1
2 4 8
3 9 27
4 16 64
5 25 125
6 36 216
7 49 343
8 64 512
9 81 729
10 100 1000
In [56]:
for i in range(1,11):
    print("{:2d} {:3d} {:4d}".format(i, i*i, i*i*i))
 1   1    1
 2   4    8
 3   9   27
 4  16   64
 5  25  125
 6  36  216
 7  49  343
 8  64  512
 9  81  729
10 100 1000

classes

In [57]:
%%file bank0.py

balance = 0

def get_balance():
    return balance

def withdraw(amount):
    global balance
    balance -= amount
    
def deposit(amount):
    global balance
    balance += amount
Writing bank0.py
In [58]:
import bank0
In [59]:
bank0.get_balance()
Out[59]:
0
In [60]:
bank0.deposit(100)
In [61]:
bank0.get_balance()
Out[61]:
100
In [62]:
bank0.withdraw(20)
In [63]:
bank0.get_balance()
Out[63]:
80
In [64]:
%%file bank1.py



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

def get_balance(account):
    return account['balance']

def withdraw(account, amount):
    account['balance'] -= amount
    
def deposit(account, amount):
    account['balance'] += amount
Writing bank1.py
In [65]:
import bank1
In [66]:
a1 = bank1.make_account()
In [67]:
bank1.get_balance(a1)
Out[67]:
0
In [68]:
a2 = bank1.make_account()
In [69]:
bank1.deposit(a1, 1000)
In [70]:
print("a1", bank1.get_balance(a1))
print("a2", bank1.get_balance(a2))
a1 1000
a2 0
In [71]:
class BankAccount:
    
    def __init__(account):
        account.balance = 0
        
    def get_balance(account):
        return account.balance
    
    
    def withdraw(account, amount):
        account.balance -=  amount
        
    def deposit(account, amount):
        account.balance += amount
        
In [72]:
acc1 = BankAccount()     #a1 = bank1.make_account()
In [73]:
acc1.get_balance()
Out[73]:
0
In [74]:
acc1.deposit(1000)
In [75]:
acc1.get_balance()
Out[75]:
1000
In [76]:
acc1.withdraw(20)
In [77]:
acc1.get_balance()
Out[77]:
980
In [78]:
a1
Out[78]:
{'balance': 1000}
In [83]:
class BankAccount:
    
    def __init__(account):
        account._balance = 0
        
    def get_balance(account):
        return account._balance
    
    
    def withdraw(account, amount):
        account._balance -=  amount
        
    def deposit(account, amount):
        account._balance += amount
        
In [89]:
class BankAccount1:
    """
    A class which models bank account
    """
    def __init__(self, balance=0):
        """
        Help for constructor of BankAccount1
        """
        self._balance = balance
        
    def get_balance(self):
        return self._balance
    
    
    def withdraw(self, amount):
        self._balance -=  amount
        
    def deposit(self, amount):
        self._balance += amount
        
In [90]:
acccount1 = BankAccount1(3000)
In [91]:
acccount1._balance
Out[91]:
3000
In [92]:
acccount1.get_balance()
Out[92]:
3000
In [93]:
help(BankAccount1)
Help on class BankAccount1 in module __main__:

class BankAccount1(builtins.object)
 |  A class which models bank account
 |  
 |  Methods defined here:
 |  
 |  __init__(self, balance=0)
 |      Help for constructor of BankAccount1
 |  
 |  deposit(self, amount)
 |  
 |  get_balance(self)
 |  
 |  withdraw(self, amount)
 |  
 |  ----------------------------------------------------------------------
 |  Data descriptors defined here:
 |  
 |  __dict__
 |      dictionary for instance variables (if defined)
 |  
 |  __weakref__
 |      list of weak references to the object (if defined)

problem

  • Write a class for working with stock data

    Stock - 
      data:
      symbol, _current
    
      methods:
      add_value
      get_std
      get_max
      get_return
In [103]:
import numpy as np
class StockData:
    
    def __init__(self, symbol, current):
        self.symbol = symbol
        self._current = current
        self.history = [current]
        self.returns = []
        
        
    def add_value(self, value):
        self._current = value
        self.returns.append(value - self.history[-1])
        self.history.append(value)
        
    def get_max(self):
        return max(self.history)
    
    def get_std(self):
        return np.std(self.history)
    
    def get_returns(self):
        return np.average(self.returns)
In [96]:
r = StockData("Reliance", 50)
In [98]:
import random
for i in range(10):
    r.add_value(random.random()*5 + 50)
In [99]:
r.get_max()
Out[99]:
54.939941429231396
In [100]:
r.get_std()
Out[100]:
1.8727826998107624
In [101]:
r.get_returns()
Out[101]:
0.061168618095729953
In [102]:
r.history
Out[102]:
[50,
 52.077938719857144,
 50.93679799254237,
 54.8864104960353,
 50.46315169301672,
 54.39161910929492,
 52.50355269877176,
 54.095536587007096,
 54.64592844094494,
 54.939941429231396,
 50.6116861809573]

XlsxWriter

In [106]:
import xlsxwriter
from xlsxwriter import Workbook
In [107]:
workbook = Workbook(filename="sample.xlsx")
In [108]:
sheet = workbook.add_worksheet("sample1")
In [109]:
sheet.write("A1", "Some data in A1")
for i in range(1, 10):
    for j in range(1, 5):
        sheet.write(i, j, i*j)
In [110]:
workbook.close()
In [112]:
with Workbook(filename="sample1.xlsx") as w:
    s = w.add_worksheet("s")
    s.write("A1","A")
!pip install XlsxWriter
In [115]:
data = [["Pencil", "Pen", "Earaser", "Notebook"], [10,25,5,25]]
with Workbook(filename="format.xlsx") as w:
    s = w.add_worksheet("sheet1")
    bold = w.add_format({"bold":True})
    number_format = w.add_format({"num_format": "$#,##0"})
    s.write("A1","Products", bold)
    s.write("B1", "Prices", bold)
    
    for i,product in enumerate(data[0]):
        s.write(i+1, 0, product)
    
    for i, cost in enumerate(data[1]):
        s.write(i+1, 1, cost, number_format)
    
In [ ]:
 
In [119]:
data = [["Pencil",10],["Pen", 25], ["Earaser",5], ["Notebook",25]]
with Workbook(filename="tables.xlsx") as w:
    s = w.add_worksheet("sheet1")
    s.add_table("B2:C6", 
                {"data":data})
In [ ]:
 
In [121]:
data = [["Pencil",10],["Pen", 25], ["Earaser",5], ["Notebook",25]]
with Workbook(filename="tables1.xlsx") as w:
    s = w.add_worksheet("sheet1")
    s.add_table("B2:C7", 
                {"data":data,
                 "columns":[{'header':"Products",'total_string':"Total"},
                            {'header':"Cost", "total_function":"sum"}]})
In [ ]: