#!/usr/bin/env python
# coding: utf-8

# In[206]:


#Make a generator of all fibonacci numbers ... 1 1 2 3 5 8 ... 
def fib(max):
    first = 0
    second = 1
    _sum = 0
    while True:
        _sum = first + second
        first = second
        second = _sum
        if _sum >= max: 
            return _sum
        yield _sum


# In[207]:


x = fib(100)
print(next(x))
print(list(x))


# In[208]:


#Create an Iterable that lists the first 10 powers of 2 till .. 2^10
class Iterable: 
    _i = 0
    def __init__(self):
        self._i = 2
        
    class it:
        _i = 0
        _val = 0

        def __init__(self,val):
            self._val=val

        def __next__(self):
            old  = self._val
            self._val *= 2
            self._i+=1
            if self._i > 10:
                raise StopIteration 
            return old
        
        def __iter__(self):
            return self
        
    def __iter__(self):
        return Iterable.it(self._i)


# In[209]:


x = Iterable()
p = iter(x)
print(list(p))
print(list(x))


# In[210]:


## Write the Map function.
def _map(f,list1,*list2):
    if len(list2) > 0:
        zipper = zip(list1,*list2)
        return (f(*a) for a in zipper)
    else:
        return (f(a) for a in list1)


# In[211]:


from operator import *
from unittest import *

a = [1,2,3,4,5]
b = [5,4,3,2,1]
c = [10,20,30,40,50]
x = map(lambda x: x, a)
y = map(lambda x,y: x+y ,a,b)
z = map(lambda x,y,z: x+y+z ,a,b,c)

print(list(x))
print(list(y))
print(list(z))

w=  _map(lambda x: x, a)
ww = _map(lambda x,y: x+y ,a,b)
www = _map(lambda x,y,z: x+y+z ,a,b,c)

print(list(w))
print(list(ww))
print(list(www))


# In[212]:


from io       import StringIO
from unittest import *

class TestMap (TestCase):
    def test_map_1 (self):
        a = [1,2,3,4,5]
        b = [5,4,3,2,1]
        w =   map(lambda x,y: x+y ,a,b)
        ww = _map(lambda x,y: x+y ,a,b)
        self.assertEqual(list(w),list(ww))
                         
    def test_map_2 (self):
        a = [4,5]
        b = [3,1]
        c = [3,2]
        w =   map(lambda x,y,z: x+y-z ,a,b,c)
        ww = _map(lambda x,y,z: x+y+z ,a,b,c)
        self.assertNotEqual(list(w),list(ww))
                      
    def test_map_3 (self):
        a = [4,5,3,2,1]
        b = [4,3,3,2,1]
        w =   map(lambda x,y: x+y ,a,b)
        ww = _map(lambda x,y: x+y ,a,b)
        self.assertEqual(list(w),list(ww))

a = TestMap()
# unittest.TextTestRunner().run(a)

suite = unittest.TestLoader().loadTestsFromModule(a)
unittest.TextTestRunner().run(suite)


# In[213]:


a=[1,2,3,4,5]
# x=[]
# for num in a:
#     if num%2: 
#        x+=[num*2]
#     else:
#         x+=[num**2]
# pprint(list(x))
x = [num**2 if not num%2  else num*2 for num in a]
pprint(x)