Python Virtual Training For Arcesium - Module II - Day 1¶

Jun Jul 18-22, 2022 Vikrant Patil

All notes are available online at https://notes.pipal.in/2022/arcesium_finop_batch1/

Please accept the invitation that you have received in your email and login to

https://engage.pipal.in/

From there launch your jupyter lab. Create a notebook with name module2-day1

© Pipal Academy LLP

Recap¶

In [6]:
def twice(x):
    print(2*x) # any function that does not return actually returns None
In [3]:
twice(25) # but it has only printes the result, not returned!
50
In [4]:
x = twice(20)
40
In [5]:
print(x)
None
In [7]:
def twice(x):
    return 2*x # return is a stetement
In [8]:
y = twice(20)
In [9]:
print(y)
40
In [12]:
## sum_list([1, 2, 3, 4])

def sum_list(nums):
    return nums[0] + nums[1] + nums[2] + nums[3] # this sums only 4 elements
In [11]:
sum_list([1, 2, 3, 4])
Out[11]:
10
In [13]:
sum_list([1, 2, 3, 4, 5, 5, 6, 7, 8, 8])
Out[13]:
10
In [14]:
def sum_list(nums):
    s = 0
    for n in nums:
        s += n
    
    return s
In [15]:
sum_list([1, 2, 3, 4, 5, 5, 6, 7, 8, 8])
Out[15]:
49

Iteration patterns¶

In [16]:
nums = [1, 2, 3, 4, 5, 6]
In [17]:
for i in nums:
    print(i)
1
2
3
4
5
6
In [18]:
for i in nums:
    print(i, end=",")
1,2,3,4,5,6,
In [19]:
for i in reversed(nums):
    print(i, end=",")
6,5,4,3,2,1,
In [20]:
symbols = ["HCL", "INFY", "RELIANCE", "TATA", "M&M"]
In [22]:
for s in symbols:
    print(s, end=",")
HCL,INFY,RELIANCE,TATA,M&M,
In [23]:
for s in reversed(symbols):
    print(s, end=",")
M&M,TATA,RELIANCE,INFY,HCL,
In [24]:
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."""
In [27]:
text = "these are some words in a text"
text.split() # list of words
Out[27]:
['these', 'are', 'some', 'words', 'in', 'a', 'text']
In [28]:
poem.split() # words!
Out[28]:
['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.']
In [29]:
poem.split("\n")
Out[29]:
['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.']
In [30]:
lines = poem.split("\n")
for line in lines:
    print(line)
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.

Write a function inverted which prints the lines in multiline text in revered fashion. i.e. it prints last lines first ...first line at last

In [32]:
def inverted(multiline_text):
    lines = multiline_text.split("\n")
    
    for line in reversed(lines):
        print(line)
    
In [33]:
inverted(poem)
Readability counts.
Sparse is better than dense.
Flat is better than nested.
Complex is better than complicated.
Simple is better than complex.
Explicit is better than implicit.
Beautiful is better than ugly.

The Zen of Python, by Tim Peters

Now wriet a function reversed_lines which print lines in normal order order, but every line should be reversed!

In [34]:
word = "hello"
In [36]:
word[::-1]
Out[36]:
'olleh'
In [37]:
for line in lines:
    print(reversed(line))
<reversed object at 0x7eff627648e0>
<reversed object at 0x7eff627648e0>
<reversed object at 0x7eff627648e0>
<reversed object at 0x7eff627648e0>
<reversed object at 0x7eff627648e0>
<reversed object at 0x7eff627648e0>
<reversed object at 0x7eff627648e0>
<reversed object at 0x7eff627648e0>
<reversed object at 0x7eff627648e0>
In [41]:
for line in lines:
    for char in reversed(line):
        print(char, end="")
    print("\n", end="")
sreteP miT yb ,nohtyP fo neZ ehT

.ylgu naht retteb si lufituaeB
.ticilpmi naht retteb si ticilpxE
.xelpmoc naht retteb si elpmiS
.detacilpmoc naht retteb si xelpmoC
.detsen naht retteb si talF
.esned naht retteb si esrapS
.stnuoc ytilibadaeR
In [42]:
for line in lines:
    print(line[::-1])
sreteP miT yb ,nohtyP fo neZ ehT

.ylgu naht retteb si lufituaeB
.ticilpmi naht retteb si ticilpxE
.xelpmoc naht retteb si elpmiS
.detacilpmoc naht retteb si xelpmoC
.detsen naht retteb si talF
.esned naht retteb si esrapS
.stnuoc ytilibadaeR
In [43]:
rnums = reversed(nums) # iterator
In [44]:
rnums
Out[44]:
<list_reverseiterator at 0x7eff62739120>
In [45]:
for i in rnums: # this can be used only once
    print(i)
6
5
4
3
2
1
In [46]:
for i in rnums: # this can be used only once
    print(i)
In [48]:
nums = [1, 2, 3, 4, 5, 6]
In [49]:
rnums
Out[49]:
<list_reverseiterator at 0x7eff62739120>
In [50]:
for i in rnums:
    print(i)
In [55]:
for i in reversed(nums): # this for loop will work every time I run
    print(i)
6
5
4
3
2
1
In [56]:
nums
Out[56]:
[1, 2, 3, 4, 5, 6]
In [58]:
print(nums)
[1, 2, 3, 4, 5, 6]
In [59]:
nums[::]
Out[59]:
[1, 2, 3, 4, 5, 6]
In [61]:
for line in lines:
    print(line)
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.
In [62]:
for i, line in enumerate(lines):
    print(i, line)
0 The Zen of Python, by Tim Peters
1 
2 Beautiful is better than ugly.
3 Explicit is better than implicit.
4 Simple is better than complex.
5 Complex is better than complicated.
6 Flat is better than nested.
7 Sparse is better than dense.
8 Readability counts.
In [63]:
for i, line in enumerate(lines, start=1):
    print(i, line)
1 The Zen of Python, by Tim Peters
2 
3 Beautiful is better than ugly.
4 Explicit is better than implicit.
5 Simple is better than complex.
6 Complex is better than complicated.
7 Flat is better than nested.
8 Sparse is better than dense.
9 Readability counts.
In [64]:
primes = [2, 3, 5, 7, 11, 13, 17]
In [65]:
for i, p in enumerate(primes):
    print(i, p)
0 2
1 3
2 5
3 7
4 11
5 13
6 17
In [66]:
for i, p in enumerate(primes, start=1):
    print(i, p)
1 2
2 3
3 5
4 7
5 11
6 13
7 17
In [67]:
symbols
Out[67]:
['HCL', 'INFY', 'RELIANCE', 'TATA', 'M&M']
In [68]:
for i, s in enumerate(symbols, start=5):
    print(i, s)
5 HCL
6 INFY
7 RELIANCE
8 TATA
9 M&M
In [69]:
for i, s in reversed(enumerate(symbols, start=5)):
    print(i, s)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Input In [69], in <cell line: 1>()
----> 1 for i, s in reversed(enumerate(symbols, start=5)):
      2     print(i, s)

TypeError: 'enumerate' object is not reversible
In [70]:
help(enumerate)
Help on class enumerate in module builtins:

class enumerate(object)
 |  enumerate(iterable, start=0)
 |  
 |  Return an enumerate object.
 |  
 |    iterable
 |      an object supporting iteration
 |  
 |  The enumerate object yields pairs containing a count (from start, which
 |  defaults to zero) and a value yielded by the iterable argument.
 |  
 |  enumerate is useful for obtaining an indexed list:
 |      (0, seq[0]), (1, seq[1]), (2, seq[2]), ...
 |  
 |  Methods defined here:
 |  
 |  __getattribute__(self, name, /)
 |      Return getattr(self, name).
 |  
 |  __iter__(self, /)
 |      Implement iter(self).
 |  
 |  __next__(self, /)
 |      Implement next(self).
 |  
 |  __reduce__(...)
 |      Return state information for pickling.
 |  
 |  ----------------------------------------------------------------------
 |  Class methods defined here:
 |  
 |  __class_getitem__(...) from builtins.type
 |      See PEP 585
 |  
 |  ----------------------------------------------------------------------
 |  Static methods defined here:
 |  
 |  __new__(*args, **kwargs) from builtins.type
 |      Create and return a new object.  See help(type) for accurate signature.

In [71]:
for i, s in enumerate(symbols, start=-1):
    print(i, s)
-1 HCL
0 INFY
1 RELIANCE
2 TATA
3 M&M
In [72]:
for i, s in enumerate(reversed(symbols), start=0):
    print(i, s)
0 M&M
1 TATA
2 RELIANCE
3 INFY
4 HCL
In [73]:
for i, s in enumerate(symbols):
    print(len(symbols)-i, s)
5 HCL
4 INFY
3 RELIANCE
2 TATA
1 M&M
In [74]:
firstname = ["Alice", "Elsa", "Alex", "Mulan"]
surname = ["Wonder", "Frozen" , "Lion", "Brave"]
In [75]:
for first, last in zip(firstname, surname):
    print(first, last)
Alice Wonder
Elsa Frozen
Alex Lion
Mulan Brave
In [77]:
X = ["x1", "x2", "x3", "x4"]
Y = ["y1", "y2", "y3", "y4"]
Z = ["z1", "z2", "z3", "z4", "z5"]

for x, y, z in zip(X, Y, Z):
    print(x, y, z)
x1 y1 z1
x2 y2 z2
x3 y3 z3
x4 y4 z4

problems

  • Write a function vector_add which adds two vectors. A single vector is represented as a list

kumarshy error debugging¶

In [ ]:
def vector_add(a, b):
    z = []
    s = 0
    for i in a:
        for i in b: # loop variable must not be same!
            s = s + a[i] +b[i]
            y = s.append(z) #what is s? it is not a list...
        return(y) # return is not a function , it is a statement
In [78]:
nums
Out[78]:
[1, 2, 3, 4, 5, 6]
In [79]:
nums.append(-1) # it does not return anything 
In [80]:
def vector_add(vector1, vector2):
    result_vector = []
    for v1, v2 in zip(vector1, vector2):
        result_vector.append(v1 + v2)
        
    return result_vector
        
In [81]:
vector_add([1, 2, 3, 4], [1, 1, 1, 1])
Out[81]:
[2, 3, 4, 5]
In [82]:
def vector_add1(vector1, vector2):
    result_vector = []
    length = len(vector1) # assumetion is vector2 is also of lenght >= len(vector1)
    for i in range(length): # i usually means index
        result_vector.append(vector1[i] + vector2[i])
        
    return result_vector
In [83]:
vector_add1([1, 2, 3, 4], [1, 1, 1, 1])
Out[83]:
[2, 3, 4, 5]
In [85]:
primes
Out[85]:
[2, 3, 5, 7, 11, 13, 17]
In [86]:
primes[0]
Out[86]:
2
In [87]:
primes[5]
Out[87]:
13
In [88]:
primes[7]
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
Input In [88], in <cell line: 1>()
----> 1 primes[7]

IndexError: list index out of range
In [89]:
vector_add1([1, 2, 3, 4], [1, 1, 1])
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
Input In [89], in <cell line: 1>()
----> 1 vector_add1([1, 2, 3, 4], [1, 1, 1])

Input In [82], in vector_add1(vector1, vector2)
      3 length = len(vector1) # assumetion is vector2 is also of lenght >= len(vector1)
      4 for i in range(length): # i usually means index
----> 5     result_vector.append(vector1[i] + vector2[i])
      7 return result_vector

IndexError: list index out of range
In [91]:
vector_add([1, 2, 3, 4], [1, 1, 1]) # zip will take care of uneven lenghts of vectors
Out[91]:
[2, 3, 4]
In [96]:
def vector_add2(vector1, vector2):
    result_vector = []
    for i, v_item in enumerate(vector1):
        result_vector.append(v_item, vector2[i]) # assumption is vector2 is also of lenght >= len(vector1)
        
    return result_vector
In [98]:
def vector_add2(vector1, vector2):
    result_vector = []
    for i, v_item in enumerate(vector1): # even if we don't make use of v_item.. we have to mention it.. 
                                          #because enumerate gives two items# assumetion is vector2 is also of lenght >= len(vector1)
        result_vector.append(vector1[i], vector2[i]) # assumption is vector2 is also of lenght >= len(vector1)
        
    return result_vector
In [99]:
primes
Out[99]:
[2, 3, 5, 7, 11, 13, 17]
In [101]:
for p in primes:
    print(p)
2
3
5
7
11
13
17
In [102]:
for i, prime in enumerate(primes):
    print(i, prime)
0 2
1 3
2 5
3 7
4 11
5 13
6 17
In [103]:
symbols
Out[103]:
['HCL', 'INFY', 'RELIANCE', 'TATA', 'M&M']
In [104]:
for i, symbol in enumerate(symbols): # index and value
    print(i, symbol)
0 HCL
1 INFY
2 RELIANCE
3 TATA
4 M&M

List Comprehensions¶

In [105]:
def findlens(words):
    lens = []
    for word in words:
        l = len(word)
        lens.append(l)
        
    return lens
In [116]:
def squares(nums):
    sqrs = []
    
    for n in nums:
        s = n*n
        sqrs.append(s)
        
    return sqrs
In [107]:
range(10) # 10 numbers starting from zero
Out[107]:
range(0, 10)
In [108]:
import datetime

def trange(n):
    """generates next n dates starting from today
    """
    dates = []
    start = datetime.datetime.today()
    for i in range(n):
        nextdate = start + datetime.timedelta(days=1)
        dates.append(nextdate)
        
    return dates
        
In [109]:
datetime.datetime.today() 
Out[109]:
datetime.datetime(2022, 7, 18, 12, 24, 43, 810395)
In [110]:
datetime.datetime.today() + 3
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Input In [110], in <cell line: 1>()
----> 1 datetime.datetime.today() + 3

TypeError: unsupported operand type(s) for +: 'datetime.datetime' and 'int'
In [115]:
datetime.datetime.today() + datetime.timedelta(days=365)
Out[115]:
datetime.datetime(2023, 7, 18, 12, 26, 37, 192871)
In [114]:
help(datetime.timedelta)
Help on class timedelta in module datetime:

class timedelta(builtins.object)
 |  Difference between two datetime values.
 |  
 |  timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0)
 |  
 |  All arguments are optional and default to 0.
 |  Arguments may be integers or floats, and may be positive or negative.
 |  
 |  Methods defined here:
 |  
 |  __abs__(self, /)
 |      abs(self)
 |  
 |  __add__(self, value, /)
 |      Return self+value.
 |  
 |  __bool__(self, /)
 |      self != 0
 |  
 |  __divmod__(self, value, /)
 |      Return divmod(self, value).
 |  
 |  __eq__(self, value, /)
 |      Return self==value.
 |  
 |  __floordiv__(self, value, /)
 |      Return self//value.
 |  
 |  __ge__(self, value, /)
 |      Return self>=value.
 |  
 |  __getattribute__(self, name, /)
 |      Return getattr(self, name).
 |  
 |  __gt__(self, value, /)
 |      Return self>value.
 |  
 |  __hash__(self, /)
 |      Return hash(self).
 |  
 |  __le__(self, value, /)
 |      Return self<=value.
 |  
 |  __lt__(self, value, /)
 |      Return self<value.
 |  
 |  __mod__(self, value, /)
 |      Return self%value.
 |  
 |  __mul__(self, value, /)
 |      Return self*value.
 |  
 |  __ne__(self, value, /)
 |      Return self!=value.
 |  
 |  __neg__(self, /)
 |      -self
 |  
 |  __pos__(self, /)
 |      +self
 |  
 |  __radd__(self, value, /)
 |      Return value+self.
 |  
 |  __rdivmod__(self, value, /)
 |      Return divmod(value, self).
 |  
 |  __reduce__(...)
 |      __reduce__() -> (cls, state)
 |  
 |  __repr__(self, /)
 |      Return repr(self).
 |  
 |  __rfloordiv__(self, value, /)
 |      Return value//self.
 |  
 |  __rmod__(self, value, /)
 |      Return value%self.
 |  
 |  __rmul__(self, value, /)
 |      Return value*self.
 |  
 |  __rsub__(self, value, /)
 |      Return value-self.
 |  
 |  __rtruediv__(self, value, /)
 |      Return value/self.
 |  
 |  __str__(self, /)
 |      Return str(self).
 |  
 |  __sub__(self, value, /)
 |      Return self-value.
 |  
 |  __truediv__(self, value, /)
 |      Return self/value.
 |  
 |  total_seconds(...)
 |      Total seconds in the duration.
 |  
 |  ----------------------------------------------------------------------
 |  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:
 |  
 |  days
 |      Number of days.
 |  
 |  microseconds
 |      Number of microseconds (>= 0 and less than 1 second).
 |  
 |  seconds
 |      Number of seconds (>= 0 and less than 1 day).
 |  
 |  ----------------------------------------------------------------------
 |  Data and other attributes defined here:
 |  
 |  max = datetime.timedelta(days=999999999, seconds=86399, microseconds=9...
 |  
 |  min = datetime.timedelta(days=-999999999)
 |  
 |  resolution = datetime.timedelta(microseconds=1)

newlist = []
for item in oldlist:
    newitem = do_something(item)
    newlist.append(newitem)
[do_something(item) for item in oldlist]
In [118]:
words = "Hello there, take some words to do some computation".split()
In [119]:
findlens(words)
Out[119]:
[5, 6, 4, 4, 5, 2, 2, 4, 11]
In [120]:
words
Out[120]:
['Hello', 'there,', 'take', 'some', 'words', 'to', 'do', 'some', 'computation']
In [121]:
[len(word) for word in words]
Out[121]:
[5, 6, 4, 4, 5, 2, 2, 4, 11]
In [122]:
squares(primes)
Out[122]:
[4, 9, 25, 49, 121, 169, 289]
In [123]:
[p*p for p in primes]
Out[123]:
[4, 9, 25, 49, 121, 169, 289]
In [124]:
[datetime.datetime.today()+datetime.timedelta(days=i) for i in range(5)]
Out[124]:
[datetime.datetime(2022, 7, 18, 12, 33, 52, 63511),
 datetime.datetime(2022, 7, 19, 12, 33, 52, 63526),
 datetime.datetime(2022, 7, 20, 12, 33, 52, 63531),
 datetime.datetime(2022, 7, 21, 12, 33, 52, 63534),
 datetime.datetime(2022, 7, 22, 12, 33, 52, 63537)]

problem

  • write a list comprehension to add two vectors
In [126]:
[word.upper() for word in words]
Out[126]:
['HELLO', 'THERE,', 'TAKE', 'SOME', 'WORDS', 'TO', 'DO', 'SOME', 'COMPUTATION']
In [127]:
[p**3 for p in primes]
Out[127]:
[8, 27, 125, 343, 1331, 2197, 4913]
In [128]:
vector1 = [1, 2, 3, 4, 5]
vector2 = [1, 1, 1, 1, 1]
In [129]:
def vector_add(vector1, vector2):
    result_vector = []
    for v1, v2 in zip(vector1, vector2):
        result_vector.append(v1 + v2)
        
    return result_vector
In [130]:
[v1+v2 for v1, v2 in zip(vector1, vector2)]
Out[130]:
[2, 3, 4, 5, 6]
In [131]:
def vector_add(vector1, vector2):
    return [v1+v2 for v1, v2 in zip(vector1, vector2)]
In [132]:
vector_add([1, 2, 3, 34, 4], [-1,-1, -1,-1,-1])
Out[132]:
[0, 1, 2, 33, 3]
In [133]:
vector3 = [v1+v2 for v1, v2 in zip(vector1, vector2)]
In [134]:
vector3
Out[134]:
[2, 3, 4, 5, 6]
In [135]:
def find_square_of_even(nums):
    sqrs = []
    for n in nums:
        if n%2==0:
            sqrs.append(n*n)
    
    return sqrs
In [136]:
def even(n):
    return  n%2==0
In [137]:
5%2==0
Out[137]:
False
In [138]:
6%2==0
Out[138]:
True
In [139]:
[n*n for n in nums if even(n)]
Out[139]:
[4, 16, 36]
In [140]:
nums
Out[140]:
[1, 2, 3, 4, 5, 6, -1]
In [141]:
[n*n for n in nums if n%2==0]
Out[141]:
[4, 16, 36]
In [144]:
def even(n):
    return  n%2==0

def odd(n):
    return not even(n)
In [143]:
[n*n for n in nums if odd(n)]
Out[143]:
[1, 9, 25, 1]
In [145]:
[n*n for n in nums]
Out[145]:
[1, 4, 9, 16, 25, 36, 1]
In [146]:
[n*n for n in nums if odd(n)]
Out[146]:
[1, 9, 25, 1]
In [147]:
nums
Out[147]:
[1, 2, 3, 4, 5, 6, -1]
In [148]:
[odd(n) for n in nums]
Out[148]:
[True, False, True, False, True, False, True]
In [149]:
[even(n) for n in nums]
Out[149]:
[False, True, False, True, False, True, False]
In [150]:
[n*n for n in nums if even(n)]
Out[150]:
[4, 16, 36]
newlist = []
for item in oldlist:
    newitem = do_something(item)
    newlist.append(newitem)
[do_something(item) for item in oldlist]
newlist = []
for item in oldlist:
    if cond(item):
        newitem = do_something(item)
        newlist.append(newitem)
[do_something(item) for item in oldlist if cond(item)]
[report(student) for student in classroom]
In [152]:
classroom = ["Himanshu", "Sakshi", "Kumar", "Umang", "Navya"]
def report(name):
    return "Report for " + name

[report(student) for student in classroom]
Out[152]:
['Report for Himanshu',
 'Report for Sakshi',
 'Report for Kumar',
 'Report for Umang',
 'Report for Navya']
In [153]:
prices = [('IBM', 'Monday', 111.71436961893693),
              ('IBM', 'Tuesday', 141.21220022208635),
              ('IBM', 'Wednesday', 112.40571010053796),
              ('IBM', 'Thursday', 137.54133351926248),
              ('IBM', 'Friday', 140.25154281801224),
              ('MICROSOFT', 'Monday', 235.0403622499107),
              ('MICROSOFT', 'Tuesday', 225.0206535036475),
              ('MICROSOFT', 'Wednesday', 216.10342426936444),
              ('MICROSOFT', 'Thursday', 200.38038844494193),
              ('MICROSOFT', 'Friday', 235.80850482793264),
              ('APPLE', 'Monday', 321.49182055844256),
              ('APPLE', 'Tuesday', 340.63612771662815),
              ('APPLE', 'Wednesday', 303.9065277507285),
              ('APPLE', 'Thursday', 338.1350605764038),
              ('APPLE', 'Friday', 318.3912296144338)]
In [154]:
def weekly_average(prices, name):
    total = 0
    count = 0
    for symbol, day, price in prices:
        if symbol == name:
            total += price
            count += 1
    return total/count
In [155]:
def weekly_average(prices, name):
    sumlist = []
    for symbol, day, price in prices:
        if symbol == name:
            sumlist.append(price)
            
    return sum(sumlist)/len(sumlist)
In [156]:
def weekly_average(prices, name):
    sumlist = []
    for record in prices:
        if record[0] == name:
            sumlist.append(record[2])
            
    return sum(sumlist)/len(sumlist)
In [157]:
def weekly_average(prices, name):
    target_prices = [price for symb, day, price in prices if symb==name]
    return sum(target_prices)/len(target_prices)
In [158]:
weekly_average(prices, "IBM")
Out[158]:
128.62503125576717
In [159]:
weekly_average(prices, "APPLE")
Out[159]:
324.51215324332736

problems

  • Find sum of all multiples of 7 or 11 below 1000
In [160]:
def multiple_of_7(n):
    return n%7==0

def multiple_of_11(n):
    return n%11==0
In [161]:
sum([n for n in range(1000) if multiple_of_7(n) or multiple_of_11(n)])
Out[161]:
110110
In [165]:
sum([n for n in range(1000) if n%7==0 or n%11==0])
Out[165]:
110110

problems

  • Write a function factors which finds all factors of given number (include 1 and self)
  • Write a functuon is_prime which checks if given number is prime or not
  • Generate prime numbers less than n
In [163]:
list(range(1, 5))
Out[163]:
[1, 2, 3, 4]
In [173]:
def factors(n):
    return [f for f in range(1,n+1) if n%f==0]
In [174]:
factors(5)
Out[174]:
[1, 5]
In [175]:
factors(6)
Out[175]:
[1, 2, 3, 6]
In [176]:
def is_prime(n):
    return len(factors(n))==2
In [177]:
def generate_primes(n):
    """generates primes less than n
    """ 
    return [p for p in range(n) if is_prime(p)]
In [179]:
generate_primes(100)
Out[179]:
[2,
 3,
 5,
 7,
 11,
 13,
 17,
 19,
 23,
 29,
 31,
 37,
 41,
 43,
 47,
 53,
 59,
 61,
 67,
 71,
 73,
 79,
 83,
 89,
 97]
In [180]:
def factors(n):
    return [f for f in range(1,int(n/2)+1) if n%f==0] + [n]
In [181]:
factors(7)
Out[181]:
[1, 7]
In [182]:
generate_primes(50)
Out[182]:
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]
In [ ]: