In [ ]:
# Copied from https://www.youtube.com/watch?v=OSGv2VnC0go

In [ ]:
# Looping over a range of numbers

In [ ]:
for i in [0, 1, 2, 3, 4, 5]:
    print( i**3)

In [ ]:
for i in range(7):
    print( i**4 )

In [ ]:
colors = ['red', 'green', 'blue', 'yellow']

In [ ]:
for idx in range(len(colors)):
    print( colors[idx])

In [ ]:
for idx in range(len(colors)-1, -1, -1):
    print( colors[idx] )

In [ ]:
for color in reversed(colors):
    print(color)

In [ ]:
# Looping over a collection and indices

In [ ]:
for idx in range(len(colors)):
    print( idx, '--->', colors[idx])

In [ ]:
for idx, color in enumerate(colors):
    print( idx, '--->', colors[idx])

In [ ]:
# Looping over two collections

In [ ]:
names=['raymond', 'rachel', 'matthew']
colors=['red', 'green', 'blue', 'yellow']

In [ ]:
n = min(len(names), len(color))
for idx in range(n):
    print( names[idx], '--->', colors[idx])

In [ ]:
for name, color in zip(names,colors):
    print( name, '--->', color)

In [ ]:
# for name, color in izip(names,colors):
    # print( name, '--->', color)

# NameError: name 'izip' is not defined

In [ ]:
# Looping in sorted order

In [ ]:
for color in sorted(colors):
    print(color)

In [ ]:
for color in sorted(colors, reverse=True):
    print(color)

In [ ]:
def compare_length(c1,c2):
    if len(c1) < len(c2): return -1
    if len(c1) > len(c2): return 1
    return 0

In [ ]:
# print( sorted(colors, cmp=compare_length) )
# TypeError: 'cmp' is an invalid keyword argument for this function

In [ ]:
# print( sorted(colors, key=compare_length))
# TypeError: compare_length() missing 1 required positional argument: 'c2'

In [ ]:
from functools import *

In [ ]:
print( sorted(colors, key=cmp_to_key(compare_length)))

In [ ]:
print( sorted(colors, key=len))

In [ ]:
# Call a function until a sentinel value

In [ ]:
blocks = []

In [ ]:
with open('sample-text-file.txt') as f:
    while True:
        block = f.read(32)
        if block == '':
            break
        blocks.append(block)

In [ ]:
blocks

In [ ]:
blocks = []
with open('sample-text-file.txt') as f:
    for block in iter(partial(f.read,32), ''):
        blocks.append(block)

In [ ]:
blocks

In [ ]:
# Distinguishing multiple exit points in loops

In [ ]:
def simple_find(sequence, target):
    found = False
    for idx, value in enumerate(sequence):
        if value == target:
            found = True
            break
    if not found:
        return -1
    return idx

In [ ]:
simple_find(['a', 'b', 'c', 'd'], 'c')

In [ ]:
def find_else(sequence, target):
    for idx, value in enumerate(sequence):
        if value == target:
            break
    else:
        return -1
    return idx

In [ ]:
find_else(['a', 'b', 'c', 'd', 'e'], 'd')

In [ ]:
# Looping over dictionary keys; 48:50

In [ ]:
d = {'matthew':'blue', 'rachel':'green', 'raymond':'red'}

In [ ]:
for k in d:
    print(k)

In [ ]:
for k in list(d):
    if k.startswith('r'):
        del d[k]

In [ ]:
d

In [ ]:
# Looping over a dictionary keys and values; 21:29

In [ ]:
for key,value in d.items():
    print( key, '--->', value)

In [ ]:
# Construct a dictionary from pairs; 21:54

In [ ]:
names = ['raymond', 'rachel', 'matthew']
colors = ['red', 'green', 'blue']

In [ ]:
d = dict(zip(names,colors))

In [ ]:
d

In [ ]:
d.keys()

In [ ]:
d.values()

In [ ]:
list(d)

In [ ]:
list(d.values())

In [ ]:
colors = ['red', 'green', 'red', 'blue', 'green', 'red']

In [ ]:
d = {}
for color in colors:
    if color not in d:
        d[color] = 0
    d[color] += 1

In [ ]:
d

In [ ]:
d = {}
for color in colors:
    d[color] = d.get(color,0) + 1

In [ ]:
d

In [ ]:
from collections import *
d = defaultdict(int)
for color in colors:
    d[color] += 1

In [ ]:
d

In [ ]:
dict(d)

In [ ]:
# Grouping with dictionaries; 25:30

In [ ]:
names = ['raymond', 'rachel', 'matthew', 'roger', 'betty', 'melissa', 'judith', 'charlie']

In [ ]:
d = {}
for name in names:
    key = len(name)
    if key not in d:
        d[key] = []
    d[key].append(name)

In [ ]:
d

In [ ]:
d = {}
for name in names:
    key = len(name)
    d.setdefault(key, []).append(name)

In [ ]:
d

In [ ]:
d = defaultdict(list)
for name in names:
    key = len(name)
    d[key].append(name)

In [ ]:
d

In [ ]:
dict(d)

In [ ]:
# Is a dictionary popitem() atomic?

In [ ]:
d = {'matthew':'blue', 'rachel':'green', 'raymond':'red'}

In [ ]:
while d:
    key, value = d.popitem()
    print( key, '--->', value)

In [ ]:
# Updating sequences; 39:16

In [ ]:
names = ['raymond', 'rachel', 'matthew', 'roger', 'betty', 'melissa', 'judith', 'charlie']
del names[0]
names.pop(0)
names.insert(0,'mark')

In [ ]:
names

In [ ]:
from collections import *
names = deque(['raymond', 'rachel', 'matthew', 'roger', 'betty', 'melissa', 'judith', 'charlie'])

In [ ]:
names.pop()

In [ ]:
names.popleft()

In [ ]:
names

In [ ]:
names.count('melissa')

In [ ]:
names.remove('roger')

In [ ]:
names

In [ ]:
names.rotate(2)

In [ ]:
names

In [ ]:
names.index('judith')

In [ ]:
# Factor-out Temporary Contexts; 41:40

In [ ]:
from decimal import *
with localcontext(Context(prec=50)):
    print ( Decimal(355) / Decimal(113))

In [ ]:
import math
math.pi

In [ ]:
with localcontext(Context(prec=50)):
    print(math.pi)

In [ ]:
# How to Open and Close Files; 42:16

In [ ]:
with open('sample-text-file.txt') as f:
    data = f.read()

In [ ]:
data

In [ ]:
import threading
lock = threading.Lock()

In [ ]:
with lock:
    print("Critical section 1")
    print("Critical section 2")

In [ ]:
help(pow)

In [ ]:
# Factor-out Temporary Contexts; 44:20

In [ ]:
import sys
with open('help.txt', 'w') as f:
    oldstdout = sys.stdout
    sys.stdout = f
    try:
        help(pow)
    finally:
        sys.stdout = oldstdout

In [ ]:
with open('help.txt') as f:
    print(f.read())

In [ ]: