print '{} == {} is {}'.format(1, [1], False)
print 'My name is {1}, {0} {1}!'.format('James', 'Bond')

"""
Explanation: A. Concepts
1. Python Data Structures

Integers
Floats
Strings
Boolean
Lists
Tuples
Dictionary
Sets

<table>
    <tr>
        <th>Data</th>
        <th>Mutable?</th>
        <th>Ordered Items?</th> 
        <th>Unique Items?</th>
        <th>Item Access</th>
    </tr>
    <tr>
        <td>List</td>
        <td>Yes</td> 
        <td>Yes</td>
        <td>No</td>
        <td>Index</td>
    </tr>
    <tr>
        <td>Tuple</td>
        <td>No</td> 
        <td>Yes</td>
        <td>No</td>
        <td>Index</td>
    </tr>
    <tr>
        <td>Dictionary</td>
        <td>Yes</td> 
        <td>No</td>
        <td>Yes</td>
        <td>Key</td>
    </tr>
    <tr>
        <td>Set</td>
        <td>Yes</td> 
        <td>No</td>
        <td>Yes</td>
        <td>None</td>
    </tr>
    <tr>
        <td>String</td>
        <td>No</td> 
        <td>Yes</td>
        <td>No</td>
        <td>Index</td>
    </tr>
</table>

2. Ternary Operator
truth_statement if condition else false_statement
3. Comprehension
List
List comprehension is a concise way of creating a list. The syntax is 
[expression for item in list if condition] 
Notice [ and ] around the statement indicating that a list will be returned. This is equivalent to
for item in list:  
    if condition:  
        expression
The if-condition is optional.
Set
{item for item in set if condition}
Tuple
tuple(item for item in tuple if condition)
Dictionary
{key:value for (key, value) in list-of-tuples if condition}, 
where list of tuples could be obtained by zip(iterable1, iterable2) (iterables are lists, tuples, sets) or dict.items().
4. Formatted String Literals
'{0} {1}'.format(arg1, arg2), 
where args can be any of the 8 data structures listed above.
End of explanation
"""


celsius = [39.2, 36.5, 37.3, 37.8]
fahrenheit = map(lambda x: (float(9)/5)*x + 32, celsius)
fahrenheit

fib = [0,1,1,2,3,5,8,13,21,34,55]
filter(lambda x: x % 2 == 0, fib)

f = lambda x,y: x if (x > y) else y
reduce(f, [47,11,42,102,13])

"""
Explanation: 5. Functionals
Lambda
Lambda() is small, anonymous function (functions without names). They are disposable functions, i.e. they are used only where they are created.
Map
Map() applies a function to each item in a sequence (list, tuple, set). The syntax is 
map(function, sequence-of-items). 
Great use case for lambda().
Filter
Filter() returns a sequence of items (list, tuple, set) that satisfy a given condition. The syntax is
filter(condition, sequence-of-items). 
Great use case for lambda(). Note: Comprehensions could be used in place of Map() & Filter().
Reduce
Reduce() continually applies a function to a sequence of items (list, tuple, set). It returns a single value. The syntax is
reduce(function, sequence-of-items). 
Great use case for lambda().
End of explanation
"""


a, b = [1, 2]
c, d = (3, 4)
e, f = {5, 6}
print a, b, c, d, e, f

"""
Explanation: 6. Unpacking Lists, Tuples & Sets
With an iterable, such as list or tuple:
args = (1, 2, 3)
f(*args) -&gt; f(1, 2, 3)
python
print range(*(0, 5)) 
print range(*[0, 5, 2])  # range(start, end, step)
With a mapping, such as dict:
kwargs = {'a':1, 'b':2, 'c':3}
f(**kwargs) -&gt; f(a=1, b=2, c=3)
python
dic = {'a':1, 'b':2}
def myFunc(a=0, b=0, c=0):
    print(a, b, c)
myFunc(**dic)
End of explanation
"""


li = range(1, 4)
d = 3
[[l*i for l in li] for i in range(1, d+1)]

"""
Explanation: B. Common Functions
1. List

[] creates empty list
[1, 2], [3, 4] creates nested list
list[start:stop:step] slices
list1 + list2 concatenates
item in list checks membership
.append(item) appends item to the end of the list
.remove(item) removes 1st value from list
.insert(index, item) inserts item to specified index
.pop(index) inverse of insert
.sort() sorts
.reverse() reverses

2. Tuple

() creates empty tuple.  1,2 creates tuple.
(1, 2), (3, 4) creates nested tuple
tup[start:stop:step] slices
tup1 + tup2 concatenates
item in tup checks membership

3. Set

set() creates empty set
{1}, {2} creates nested set
1 in {1, 2} checks membership
set1.issubset(set2) $A \subseteq B$
set1.issuperset(set2) $B \subseteq A$
set1 == set2
set1 | set2 $A \cup B$
set1 &amp; set2 $ A \cap B$
set1 - set2 $A-B$: elements in set1, but NOT in set2
set1 ^ set2 $(A \cap B)^c$: symmetric difference (xor) 
.add(item) appends item to set
.remove(item) removes item to set
set1.update(set2) appends set2 items to set1

4. Dictionary

{} creates empty dictionary
{'a':1}, {'b':2} creates nested dictionary
dict(zip(keys, values)) creates dict from iterable (list, tuple, set) keys and values. zip creates a list of $(k,v)$ tuples.
d[key] prints values for key
d[key] = value inserts/updates value for key
.keys() produces keys list
.values() produces values list
key in d checks if key exists
del d[key] deletes the key-value pair from dictionary
d1.update(d2) appends d2 key-value pairs to d1

5. String

'' or "" or ''' ''' creates empty string. Triple quotes allow line breaks.
string[start:stop:step] slices
str1 + str2 concatenates
's' in 'string' checks membership
.lower() converts to lowercase
.upper() converts to uppercase
str.split(delimiter=" ") splits str by delimiter, default space
separator.join(iterable) concatenates strings in iterable (list, tuple, string, dictionary, set) with separator string
str.replace(old_string, new_string) replaces all occurrences of old_string with new_string
str.strip(string) removes string from the beginning and the end of str. str.lstrip(string) removes string only from the beginning. str.rstrip(string) removes string only from the end.
str.startswith(string) and str.endswith(string) checks if str starts with or ends with string
str.swapcase() swap uppercase with lowercase and vice-versa
str.count(substring) counts how many times substring occurs in str

C. Exercises

Given a list of integers and an integer $d$, build a multiplication table.

Example: [[1, 2, 3], [2, 4, 6], [3, 6, 9]]
End of explanation
"""


li = [1,3,5,8,10,13,18,36,78]
[x for x in li[::2] if x%2 == 0]

"""
Explanation: Given a list of integers, return a list that only contains even integers from even indices.  

Example: If list[2]=2, include. If list[3]=2, exclude
End of explanation
"""


li = range(1, 6)
d = 2
li[d:] + li[:d]

"""
Explanation: Given a sequence of integers and an integer $d$, perform d-left rotations on the list.

Example: If d=2 and list=[1,2,3,4,5], then 2-left rotation is [3,4,5,1,2]
End of explanation
"""


x = 2
y = 3
d = 4
list1 = range(0, x+1)
list2 = range(0, y+1)
[(i,j) for i in list1 for j in list2 if i+j != d]

"""
Explanation: Given three integers $x$, $y$ and $d$, create ordered pairs $(i,j)$ such that $0 \le i \le x$, $0 \le j \le y$, and $i+j \ne d$.
End of explanation
"""


"divya nair".title()
#"divya nair".capitalize()

name = "divya nair"
li = name.split(" ")
li = [li[i].capitalize() for i in range(0, len(li))]
" ".join(li)

"""
Explanation: Capitalize the first letter in first and last names.

Example: Convert "divya nair" to "Divya Nair"
End of explanation
"""


s = "ABCDEFGHIJKLIMNOQRSTUVWXYZ"
d = 4
i = 0
while (i < len(s)): 
    print s[i:i+d]
    i = i+d

"""
Explanation: Given a string and a natural number $d$, wrap the string into a paragraph of width $d$.
End of explanation
"""


string = "divya nair"
vowels = ["a", "e", "i", "o", "u"]
[char for char in string if char in vowels]

"""
Explanation: Find all the vowels in a string.
End of explanation
"""


n = 3
reduce(lambda x,y: x*y, range(1, n+1))

"""
Explanation: Calculate $n!$
End of explanation
"""


import random
size = 3
# Generate 3 random numbers between [1, 10]
numList = [random.randint(1,10) for i in range(0, size)]
print numList
"The sum is {}".format(reduce(lambda x,y: x+y, numList))

# Shuffle item position in numList
random.shuffle(numList)
numList

# Randomly sample 2 items from numList
print random.sample(numList, 2)

"""
Explanation: Given an sequence of $n$ integers, calculate the sum of its elements.
End of explanation
"""


n = 6
d = 3
a = [1, 3, 2, 6, 1, 2]
sums = [(a[i] + a[j], i, j) for i in range(0, len(a)) for j in range(0, len(a))]
[(s[1], s[2]) for s in sums if s[0]%d==0]

"""
Explanation: Given a sequence of $n$ integers, $a_0, a_1, \cdots, a_{n-1}$, and a natural number $d$, print all pairs of $(i, j)$ such that $a_i + a_j$ is divisible by $d$.
End of explanation
"""


fib = [0,1]
n = 6
for i in range(0, n):
    fib.append(fib[i] + fib[i+1])
fib

"""
Explanation: Return $n$ numbers in the Fibonacci sequence.
End of explanation
"""


amount = 0.50
dollar, cent = str(amount).split(".")
cent = cent+'0' if len(cent)==1 else cent  # ternary operation
amount = int(dollar+cent)
deno = [25, 10, 5, 1]
coins = []
for d in deno:
    coins.append(amount/d)
    amount = amount%d
    
print '{} quarters, {} dimes, {} nickels, {} pennies'.format(*coins)  # unpacking list

"""
Explanation: Given 4 coin denominations (1c, 5c, 10c, 25c) and a dollar amount, find the best way to express that amount using least number of coins.

Example: $2.12 = (25c, 8), (10c, 1), (2c, 2)
End of explanation
"""


row = [1]
print row
d = 4
while (len(row) <= d):
    row = [1] + [row[i] + row[i+1] for i in range(0, len(row)-1)] + [1]
    print row

"""
Explanation: Output the first $d$ rows of Pascal's triangle, where $2 \le d \le 10$.
End of explanation
"""


stops = [[10, 6], [5, 4]]
remaining = [x[0]-x[1] for x in stops]
reduce(lambda x,y: x+y, remaining)

"""
Explanation: At bus stop #1, 10 passengers got on the bus and 6 passengers got off the bus. Then, at stop #2, 5 passengers got on and 4 passengers got off. How many passengers are remaining in the bus?
End of explanation
"""


num = [2, 3, 6, 6, -5]
noRep = list(set(num))
noRep.sort()
noRep.pop(-2)

"""
Explanation: Find the 2nd largest number in the list.
End of explanation
"""


length = 2
width = 3
for l in range(0, length):
    print '* ' * width

"""
Explanation: Draw a rectangle of a given length and width.
End of explanation
"""


num = [0, 1, 2, -3]
print num
odd = filter(lambda x: x%2 != 0, num)
print odd
reduce(lambda x,y: x+y, odd)

"""
Explanation: Calculate the sum of all the odd numbers in a list.
End of explanation
"""


