diff --git a/Examples/Session01/schedule.py b/Examples/Session01/schedule.py
index 7dcb1300..4bdb59db 100644
--- a/Examples/Session01/schedule.py
+++ b/Examples/Session01/schedule.py
@@ -8,16 +8,17 @@
 # remove the header line
 del students[0]
 
+# strip the whitespace
+students = [line.strip() for line in students]
+
 # remove the languages, colon, etc.
 students = [line.split(":")[0] for line in students]
 
 # reverse the first, last names
-
 # separate them:
 students = [line.split(",") for line in students]
-
 # put them back together
-students = ["{} {}".format(first, last) for last, first in students]
+students = ["{} {}".format(first.strip(), last) for last, first in students]
 
 # put them in random order
 random.shuffle(students)
@@ -26,7 +27,7 @@
 weeks = list(range(2, 11))
 
 # make three of them...
-weeks = weeks * 3
+weeks = weeks * 4
 
 # put the students together with the weeks
 schedule = zip(weeks, students)
diff --git a/Examples/Session01/schedule.txt b/Examples/Session01/schedule.txt
deleted file mode 100644
index 2325408f..00000000
--- a/Examples/Session01/schedule.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-week 2:  Brendan Fogarty
-week 2:  Bruce Bauman
-week 2:  Michelle Yu
-week 3:  Eric Rosko
-week 3:  Michael Waddle
-week 3:  Robert Stevens Alford
-week 4:  Andrey Gusev
-week 4:  Cheryl Ohashi
-week 4:  Maxwell MacCamy
-week 5:  Michael Cimino
-week 5:  Pei Lin
-week 5:  Tiffany Ku
-week 6:  Gabriel Meringolo
-week 6:  Joseph Cardenas
-week 6:  Marc Teale
-week 7:  Eric Starr Vegors
-week 7:  Ian Cote
-week 7:  Masako Tebbetts
-week 8:  Kathleen Devlin (Moved to week 9)
-week 8:  Robert Ryan Leslie
-week 8:  Ryan Morin
-week 9:  Erica Winberry
-week 9:  Robert Jenkins
-week 9:  Kathleen Devlin
-week 10:  Austin Scara
-week 10:  Marty Pitts
diff --git a/Examples/Session01/students.txt b/Examples/Session01/students.txt
deleted file mode 100644
index 2f992dfd..00000000
--- a/Examples/Session01/students.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-name: languages
-Alford, Robert Stevens: javascript php
-Bauman, Bruce: chemstation macro fortran, java
-Cardenas, Joseph: python C html CSS lisp javascript
-Cimino, Michael: C  C++ Java SQL
-Cote, Ian: bash ruby perl python
-Devlin, Kathleen: 4D
-Fogarty, Brendan: SQL
-Gusev, Andrey: perl java bash
-Jenkins, Robert: assm pascal
-Ku, Tiffany: python SQL
-Leslie, Robert Ryan: python
-Lin, Pei: SQL java R
-MacCamy, Maxwell: C C++ C# assm java
-Meringolo, Gabriel: python
-Morin, Ryan: python sql
-Ohashi, Cheryl:
-Pitts, Marty: python, similink and matlab
-Rosko, Eric: C C++
-Scara, Austin: VBA SQL
-Teale, Marc: perl bash
-Tebbetts, Masako: SQL
-Vegors, Eric Starr: bash perl
-Waddle, Michael:
-Winberry, Erica: python
-Yu, Michelle: ruby objectiveC
diff --git a/Examples/Session01/test.py b/Examples/Session01/test.py
index 1466c954..8a557325 100644
--- a/Examples/Session01/test.py
+++ b/Examples/Session01/test.py
@@ -1,9 +1,12 @@
 x = 5
 y = 55
 
-print x, y
+print(x, y)
 
 
 def f():
     x = 5
     return x
+
+def f2():
+    5 + "5"
diff --git a/Examples/Session03/mailroom_start.py b/Examples/Session03/mailroom_start.py
new file mode 100644
index 00000000..9605afe7
--- /dev/null
+++ b/Examples/Session03/mailroom_start.py
@@ -0,0 +1,42 @@
+#!/usr/bin/env python
+
+
+def print_report():
+    print("This will print a report")
+
+
+def send_thanks():
+    print("This will write a thank you note")
+
+# here is where triple quoted strings can be helpful
+msg = """
+What would you like to do?
+
+To send a thank you: type "s"
+To print a report: type "p"
+To exit: type "x"
+"""
+
+
+def main():
+    """
+    run the main interactive loop
+    """
+
+    response = ''
+    # keep asking until the users responds with an 'x'
+    while True:  # make sure there is a break if you have infinite loop!
+        print(msg)
+        response = input("==> ").strip()  # strip() in case there are any spaces
+
+        if response == 'p':
+            print_report()
+        elif response == 's':
+            send_thanks()
+        elif response == 'x':
+            break
+        else:
+            print('please type "s", "p", or "x"')
+
+if __name__ == "__main__":
+    main()
diff --git a/Examples/Session04/__main__example.py b/Examples/Session04/__main__example.py
new file mode 100755
index 00000000..603f2e57
--- /dev/null
+++ b/Examples/Session04/__main__example.py
@@ -0,0 +1,13 @@
+#!/usr/bin/env python
+
+print("every module has a __name__")
+
+print("What it is depends on how it is used")
+
+print("right now, this module's __name__ is: {}".format(__name__))
+
+# so if you want coce to run only when a module is a top level script,
+# you use this clause:
+#if __name__ == "__main__":
+
+print("I must be running as a top-level script")
diff --git a/Examples/Session06/cigar_party.py b/Examples/Session06/cigar_party.py
new file mode 100644
index 00000000..992d99bd
--- /dev/null
+++ b/Examples/Session06/cigar_party.py
@@ -0,0 +1,15 @@
+
+"""
+When squirrels get together for a party, they like to have cigars.
+A squirrel party is successful when the number of cigars is between
+40 and 60, inclusive. Unless it is the weekend, in which case there
+is no upper bound on the number of cigars.
+
+Return True if the party with the given values is successful,
+or False otherwise.
+"""
+
+
+def cigar_party(num, weekend):
+    return num >= 40  and (num <= 60 or weekend)
+
diff --git a/Examples/Session06/codingbat.py b/Examples/Session06/codingbat.py
new file mode 100644
index 00000000..25865839
--- /dev/null
+++ b/Examples/Session06/codingbat.py
@@ -0,0 +1,31 @@
+#!/usr/bin/env python
+
+"""
+Examples from: http://codingbat.com
+
+Put here so we can write unit tests for them ourselves
+"""
+
+# Python > Warmup-1 > sleep_in
+
+# The parameter weekday is True if it is a weekday, and the parameter
+# vacation is True if we are on vacation.
+#
+# We sleep in if it is not a weekday or we're on vacation.
+# Return True if we sleep in.
+
+
+def sleep_in(weekday, vacation):
+    return not weekday or vacation
+
+
+# We have two monkeys, a and b, and the parameters a_smile and b_smile
+# indicate if each is smiling.
+
+# We are in trouble if they are both smiling or if neither of them is
+# smiling.
+
+# Return True if we are in trouble.
+
+def monkey_trouble(a_smile, b_smile):
+    return a_smile is b_smile
diff --git a/Examples/Session06/safe_input.py b/Examples/Session06/safe_input.py
new file mode 100644
index 00000000..81785375
--- /dev/null
+++ b/Examples/Session06/safe_input.py
@@ -0,0 +1,25 @@
+def safe_input():
+    try:
+        the_input = input("\ntype something >>> ")
+    except (KeyboardInterrupt, EOFError) as error:
+        print("the error: ", error)
+        error.extra_info = "extra info for testing"
+        # raise
+        return None
+    return the_input
+
+def main():
+    safe_input()
+
+def divide(x,y):
+    try:
+        return x/y
+    except ZeroDivisionError as err:
+        print("you put in a zero!!!")
+        print("the exeption:", err)
+        err.args = (("very bad palce for a zero",))
+        err.extra_stuff = "all kinds of things"
+        raise
+
+# if __name__ == '__main__':
+#     main()
\ No newline at end of file
diff --git a/Examples/Session06/test_cigar_party.py b/Examples/Session06/test_cigar_party.py
index b3d76446..80bc0920 100644
--- a/Examples/Session06/test_cigar_party.py
+++ b/Examples/Session06/test_cigar_party.py
@@ -61,3 +61,4 @@ def test_10():
 
 def test_11():
     assert cigar_party(39, True) is False
+
diff --git a/Examples/Session06/test_codingbat.py b/Examples/Session06/test_codingbat.py
new file mode 100755
index 00000000..354dcb34
--- /dev/null
+++ b/Examples/Session06/test_codingbat.py
@@ -0,0 +1,43 @@
+#!/usr/bin/env python
+
+"""
+test file for codingbat module
+
+This version can be run with nose or py.test
+"""
+
+from codingbat import sleep_in, monkey_trouble
+
+
+# tests for sleep_in
+def test_false_false():
+    assert sleep_in(False, False)
+
+
+def test_true_false():
+    assert not (sleep_in(True, False))
+
+
+def test_false_true():
+    assert sleep_in(False, True)
+
+
+def test_true_true():
+    assert sleep_in(True, True)
+
+
+# put tests for monkey_trouble here
+# monkey_trouble(True, True) → True
+# monkey_trouble(False, False) → True
+# monkey_trouble(True, False) → False
+
+def test_monkey_true_true():
+    assert monkey_trouble(True, True)
+
+def test_monkey_false_false():
+    assert monkey_trouble(False, False)
+
+def test_monkey_true_false():
+    assert monkey_trouble(True, False) is False
+
+# more!
diff --git a/Examples/Session06/test_pytest_parameter.py b/Examples/Session06/test_pytest_parameter.py
new file mode 100644
index 00000000..4e82a3ab
--- /dev/null
+++ b/Examples/Session06/test_pytest_parameter.py
@@ -0,0 +1,31 @@
+#!/usr/bin/env python
+
+"""
+pytest example of a parameterized test
+
+NOTE: there is a failure in here! can you fix it?
+
+"""
+import pytest
+
+
+# a (really simple) function to test
+def add(a, b):
+    """
+    returns the sum of a and b
+    """
+    return a + b
+
+# now some test data:
+
+test_data = [((2, 3), 5),
+             ((-3, 2), -1),
+             ((2, 0.5), 2.5),
+             (("this", "that"), "this that"),
+             (([1, 2, 3], [6, 7, 8]), [1, 2, 3, 6, 7, 8]),
+             ]
+
+
+@pytest.mark.parametrize(("input", "result"), test_data)
+def test_add(input, result):
+    assert add(*input) == result
diff --git a/Examples/Session06/test_random_pytest.py b/Examples/Session06/test_random_pytest.py
new file mode 100644
index 00000000..441f239a
--- /dev/null
+++ b/Examples/Session06/test_random_pytest.py
@@ -0,0 +1,43 @@
+#!/usr/bin/env python
+
+"""
+port of the random unit tests from the python docs to py.test
+"""
+
+import random
+import pytest
+
+
+seq = list(range(10))
+
+
+def test_shuffle():
+    # make sure the shuffled sequence does not lose any elements
+    random.shuffle(seq)
+    # seq.sort()  # commenting this out will make it fail, so we can see output
+    print("seq:", seq)  # only see output if it fails
+    assert seq == list(range(10))
+
+
+def test_shuffle_immutable():
+    """should get a TypeError with an imutable type """
+    with pytest.raises(TypeError):
+        random.shuffle((1, 2, 3))
+
+
+def test_choice():
+    """make sure a random item selected is in the original sequence"""
+    element = random.choice(seq)
+    assert (element in seq)
+
+
+def test_sample():
+    """make sure all items returned by sample are there"""
+    for element in random.sample(seq, 5):
+        assert element in seq
+
+
+def test_sample_too_large():
+    """should get a ValueError if you try to sample too many"""
+    with pytest.raises(ValueError):
+        random.sample(seq, 20)
diff --git a/Examples/Session06/test_random_unitest.py b/Examples/Session06/test_random_unitest.py
new file mode 100644
index 00000000..f825be5b
--- /dev/null
+++ b/Examples/Session06/test_random_unitest.py
@@ -0,0 +1,30 @@
+import random
+import unittest
+
+
+class TestSequenceFunctions(unittest.TestCase):
+
+    def setUp(self):
+        self.seq = list(range(10))
+
+    def test_shuffle(self):
+        # make sure the shuffled sequence does not lose any elements
+        random.shuffle(self.seq)
+        self.seq.sort()
+        self.assertEqual(self.seq, list(range(10)))
+
+        # should raise an exception for an immutable sequence
+        self.assertRaises(TypeError, random.shuffle, (1, 2, 3))
+
+    def test_choice(self):
+        element = random.choice(self.seq)
+        self.assertTrue(element in self.seq)
+
+    def test_sample(self):
+        with self.assertRaises(ValueError):
+            random.sample(self.seq, 20)
+        for element in random.sample(self.seq, 5):
+            self.assertTrue(element in self.seq)
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/Examples/Session07/html_render/run_html_render.py b/Examples/Session07/html_render/run_html_render.py
index 663e5ff8..d282fdc9 100644
--- a/Examples/Session07/html_render/run_html_render.py
+++ b/Examples/Session07/html_render/run_html_render.py
@@ -42,12 +42,16 @@ def render_page(page, filename):
 
 page = hr.Element()
 
-page.append("Here is a paragraph of text -- there could be more of them, but this is enough  to show that we can do some text")
+page.append("Here is a paragraph of text -- there could be more of them, "
+            "but this is enough  to show that we can do some text")
 
 page.append("And here is another piece of text -- you should be able to add any number")
 
 render_page(page, "test_html_output1.html")
 
+# The rest of the steps have been commented out.
+#  Uncomment them a you move along with the assignment.
+
 # ## Step 2
 # ##########
 
@@ -55,7 +59,8 @@ def render_page(page, filename):
 
 # body = hr.Body()
 
-# body.append(hr.P("Here is a paragraph of text -- there could be more of them, but this is enough  to show that we can do some text"))
+# body.append(hr.P("Here is a paragraph of text -- there could be more of them, "
+#                  "but this is enough  to show that we can do some text"))
 
 # body.append(hr.P("And here is another piece of text -- you should be able to add any number"))
 
@@ -75,7 +80,8 @@ def render_page(page, filename):
 
 # body = hr.Body()
 
-# body.append(hr.P("Here is a paragraph of text -- there could be more of them, but this is enough  to show that we can do some text"))
+# body.append(hr.P("Here is a paragraph of text -- there could be more of them, "
+#                  "but this is enough  to show that we can do some text"))
 # body.append(hr.P("And here is another piece of text -- you should be able to add any number"))
 
 # page.append(body)
@@ -94,7 +100,8 @@ def render_page(page, filename):
 
 # body = hr.Body()
 
-# body.append(hr.P("Here is a paragraph of text -- there could be more of them, but this is enough  to show that we can do some text",
+# body.append(hr.P("Here is a paragraph of text -- there could be more of them, "
+#                  "but this is enough  to show that we can do some text",
 #               style="text-align: center; font-style: oblique;"))
 
 # page.append(body)
@@ -113,7 +120,8 @@ def render_page(page, filename):
 
 # body = hr.Body()
 
-# body.append(hr.P("Here is a paragraph of text -- there could be more of them, but this is enough  to show that we can do some text",
+# body.append(hr.P("Here is a paragraph of text -- there could be more of them, "
+#                  "but this is enough  to show that we can do some text",
 #               style="text-align: center; font-style: oblique;"))
 
 # body.append(hr.Hr())
@@ -134,7 +142,8 @@ def render_page(page, filename):
 
 # body = hr.Body()
 
-# body.append(hr.P("Here is a paragraph of text -- there could be more of them, but this is enough  to show that we can do some text",
+# body.append(hr.P("Here is a paragraph of text -- there could be more of them, "
+#                  "but this is enough  to show that we can do some text",
 #               style="text-align: center; font-style: oblique;"))
 
 # body.append(hr.Hr())
@@ -161,7 +170,8 @@ def render_page(page, filename):
 
 # body.append( hr.H(2, "PythonClass - Class 6 example") )
 
-# body.append(hr.P("Here is a paragraph of text -- there could be more of them, but this is enough  to show that we can do some text",
+# body.append(hr.P("Here is a paragraph of text -- there could be more of them, "
+#                  "but this is enough  to show that we can do some text",
 #               style="text-align: center; font-style: oblique;"))
 
 # body.append(hr.Hr())
@@ -200,7 +210,8 @@ def render_page(page, filename):
 
 # body.append( hr.H(2, "PythonClass - Class 6 example") )
 
-# body.append(hr.P("Here is a paragraph of text -- there could be more of them, but this is enough  to show that we can do some text",
+# body.append(hr.P("Here is a paragraph of text -- there could be more of them, "
+#                  "but this is enough  to show that we can do some text",
 #                  style="text-align: center; font-style: oblique;"))
 
 # body.append(hr.Hr())
diff --git a/Examples/Session07/simple_classes.py b/Examples/Session07/simple_classes.py
index 267f0d5e..4f996061 100644
--- a/Examples/Session07/simple_classes.py
+++ b/Examples/Session07/simple_classes.py
@@ -46,6 +46,18 @@ def __init__(self, x, y):
     def get_color(self):
         return self.color
 
+    def get_size(self):
+        return  self.size
+
+class Rect:
+
+    def __init__(self, w, h):
+        self.w = w
+        self.h = h
+
+    def get_size(self):
+        return self.w * self.h
+
 
 p3 = Point3(4, 5)
 print(p3.size)
diff --git a/Examples/Session08/circle.py b/Examples/Session08/circle.py
index 88ee5240..6d2d6018 100644
--- a/Examples/Session08/circle.py
+++ b/Examples/Session08/circle.py
@@ -9,4 +9,16 @@
 
 
 class Circle:
-    pass
+    @staticmethod
+    def a_method(x):
+        return x**2
+
+    def regular_method(self):
+        print(self)
+
+    @classmethod
+    def class_method(cls):
+        print(cls)
+
+
+
diff --git a/Examples/Session09/capitalize/capitalize/__init__.py b/Examples/Session09/capitalize/capitalize/__init__.py
deleted file mode 100644
index e69de29b..00000000
diff --git a/Examples/Session09/capitalize/capitalize/capital_mod.py b/Examples/Session09/capitalize/capitalize/capital_mod.py
deleted file mode 100644
index 352f0874..00000000
--- a/Examples/Session09/capitalize/capitalize/capital_mod.py
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/usr/bin/env python
-
-"""
-A really simple module, just to demonstrate disutils
-"""
-
-def capitalize(infilename, outfilename):
-    """
-    reads the contents of infilename, and writes it to outfilename, but with
-    every word capitalized
-
-    note: very primitive -- it will mess some files up!
-
-    this is called by the capitalize script
-    """
-    infile = open(infilename, 'U')
-    outfile = open(outfilename, 'w')
-
-    for line in infile:
-        outfile.write( " ".join( [word.capitalize() for word in line.split() ] ) )
-        outfile.write("\n")
-    
-    return None
\ No newline at end of file
diff --git a/Examples/Session09/capitalize/capitalize/test/__init__.py b/Examples/Session09/capitalize/capitalize/test/__init__.py
deleted file mode 100644
index e69de29b..00000000
diff --git a/Examples/Session09/capitalize/capitalize/test/test_text_file.txt b/Examples/Session09/capitalize/capitalize/test/test_text_file.txt
deleted file mode 100644
index a64b50f7..00000000
--- a/Examples/Session09/capitalize/capitalize/test/test_text_file.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-This is a really simple Text file.
-It is here so that I can test the capitalize script.
-
-And that's only there to try out distutils.
-
-So there.
-    
\ No newline at end of file
diff --git a/Examples/Session09/capitalize/scripts/cap_script.py b/Examples/Session09/capitalize/scripts/cap_script.py
deleted file mode 100755
index 08f999e3..00000000
--- a/Examples/Session09/capitalize/scripts/cap_script.py
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/usr/bin/env python
-
-"""
-A really simple script just to demonstrate disutils
-"""
-
-import sys, os
-from capitalize import capital_mod
-
-
-if __name__ == "__main__":
-    try:
-        infilename = sys.argv[1]
-    except IndexError:
-        print "you need to pass in a file to process"
-
-    root, ext = os.path.splitext(infilename)
-    outfilename = root + "_cap" + ext
-    
-    # do the real work:
-    print "Capitalizing: %s and storing it in %s"%(infilename, outfilename)
-    capital_mod.capitalize(infilename, outfilename)
-    
-    print "I'm done"
-    
\ No newline at end of file
diff --git a/Examples/Session09/capitalize/setup.py b/Examples/Session09/capitalize/setup.py
deleted file mode 100755
index d7acd8eb..00000000
--- a/Examples/Session09/capitalize/setup.py
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/usr/bin/env python
-
-"""
-This is about as simple a setup.py as you can have
-
-It installs the capitalize module and script
-
-"""
-
-# classic distutils
-#from distutils.core import setup
-
-## uncomment to support "develop" mode
-from setuptools import setup
-
-setup(
-    name='Capitalize',
-    version='0.1.0',
-    author='Chris Barker',
-    py_modules=['capitalize/capital_mod',],
-    scripts=['scripts/cap_script.py',],
-    description='Not very useful capitalizing module and script',
-)
-
diff --git a/Examples/Session09/closure.py b/Examples/Session09/closure.py
new file mode 100644
index 00000000..a7e7d07d
--- /dev/null
+++ b/Examples/Session09/closure.py
@@ -0,0 +1,26 @@
+#!/usr/bin/env python
+
+"""
+Example code for closures / currying
+"""
+
+from functools import partial
+
+
+def counter(start_at=0):
+    count = [start_at]
+
+    def incr():
+        count[0] += 1
+        return count[0]
+    return incr
+
+
+def power(base, exponent):
+    """returns based raised to the given exponent"""
+    return base ** exponent
+
+# now some specialized versions:
+
+square = partial(power, exponent=2)
+cube = partial(power, exponent=3)
diff --git a/Examples/Session10/p_wrapper.py b/Examples/Session10/p_wrapper.py
new file mode 100644
index 00000000..f80c4d15
--- /dev/null
+++ b/Examples/Session10/p_wrapper.py
@@ -0,0 +1,24 @@
+#!/usr/bin/env python
+"""
+p_wrapper decorator
+"""
+
+
+def p_wrapper(function):
+    def func(*args, **kwargs):
+        string = function(*args, **kwargs)
+        string = "
 {} 
".format(string)
+        return string
+    return func
+
+
+class tag_wrapper:
+    def __init__(self, tag):
+        self.tag = tag
+
+    def __call__(self, orig_func):
+        def func(*args, **kwargs):
+            string = orig_func(*args, **kwargs)
+            string = "<{tag}> {s} {tag}>".format(tag=self.tag, s=string)
+            return string
+        return func
diff --git a/Examples/Session10/test_p_wrapper.py b/Examples/Session10/test_p_wrapper.py
index 40ba0fde..12603692 100644
--- a/Examples/Session10/test_p_wrapper.py
+++ b/Examples/Session10/test_p_wrapper.py
@@ -4,7 +4,7 @@
 test code for the p_wrapper assignment
 """
 
-from p_wrapper import p_wrapper #, tag_wrapper
+from p_wrapper import p_wrapper, tag_wrapper
 
 
 def test_p_wrapper():
@@ -22,7 +22,7 @@ def f_string(a, b, this=45 ):
     assert f_string(2, 3, this=54) == " the numbers are: 2, 3, 54 
"
 
 
-#Extra credit:
+# #Extra credit:
 
 def test_tag_wrapper():
     @tag_wrapper('html')
diff --git a/Examples/Session10/timer.py b/Examples/Session10/timer.py
new file mode 100644
index 00000000..3a07bd75
--- /dev/null
+++ b/Examples/Session10/timer.py
@@ -0,0 +1,18 @@
+#!/usr/bin/env python
+
+"""
+timing context manager
+"""
+
+import sys
+import time
+
+class Timer:
+    def __init__(self, outfile=sys.stdout):
+        self.outfile = outfile
+
+    def __enter__(self):
+        self.start = time.time()
+
+    def __exit__(self, exc_type, exc_val, exc_tb):
+        self.outfile.write("elapsed time:{} seconds".format(time.time() - self.start))
\ No newline at end of file
diff --git a/README.rst b/README.rst
index 835744c3..9274ab3e 100644
--- a/README.rst
+++ b/README.rst
@@ -3,7 +3,7 @@ IntroToPython
 
 Introduction to Python: First in the Python Certification series.
 
-This repository contains the source materials for the first class in the the University of Washington Professional and Continuing Education Program Python Certification Program:
+This repository contains the source materials for the first class in the University of Washington Professional and Continuing Education Program Python Certification Program:
 
 .. _Certificate in Python Programming : http://www.pce.uw.edu/certificates/python-programming.html
 
diff --git a/Syllabus.rst b/Syllabus.rst
index 3257c7fe..86a9b6ef 100644
--- a/Syllabus.rst
+++ b/Syllabus.rst
@@ -15,7 +15,7 @@ The Python Certificate program is a 9-month curriculum divided into three course
 First Course: Introduction to Python
 =====================================
 
-Tuesdays 6-9 pm: Oct 6 - Dec 8, 2015 (10 Sessions)
+Tuesdays 6-9 pm: Sept 27 - Dec 6, 2016 (10 Sessions)
 ---------------------------------------------------
 
 
@@ -142,7 +142,7 @@ Reading:
 
 There is no assigned text book. However, you may find it beneficial to read other discussions of topics in addition to what I present in class or assign as reading: either to explore a topic more deeply, or to simple get another viewpoint. There are many good books on Python, and many more excellent discussions of individual topics on the web.
 
-Note that mamny books still cover primarily (or only) Python 2. THey can still be very, very useful, the syntax is only a little different, and the concepts the same.
+Note that many books still cover primarily (or only) Python 2. THey can still be very, very useful, the syntax is only a little different, and the concepts the same.
 
 A few you may want to consider:
 
@@ -233,7 +233,7 @@ Class Schedule:
 Topics of each week
 --------------------
 
-Week 1: Oct 6
+Week 1: September 27
 ................
 
 General Introduction to Python and the class. Using the command interpreter and development environment.
@@ -245,7 +245,7 @@ Finding and using the documentation. Getting help.
 Python 2/3 differences.
 
 
-Week 2: Oct 13
+Week 2: October 4
 ................
 
 Introduction to git and gitHub
@@ -259,7 +259,7 @@ Modules and import
 Conditionals and Boolean expressions
 
 
-Week 3: Oct 20
+Week 3: October 11
 .................
 
 Sequences: Strings, Tuples, Lists
@@ -269,7 +269,7 @@ Iteration, looping and control flow.
 String methods and formatting
 
 
-Week 4: Oct 27
+Week 4: October 18
 ................
 
 Dictionaries, Sets and Mutability.
@@ -277,47 +277,50 @@ Dictionaries, Sets and Mutability.
 Files and Text Processing
 
 
-Week 5: November 3
+Week 5: October 25
 ........................
 
 Exceptions
 
-Testing
-
 List and Dict Comprehensions
 
+Week 6: November 1
+..................
 
-Week 6: November 10
-....................
+Testing
 
 Advanced Argument passing
 
-Lambda
 
-Functions as Objects
 
+**No class Nov 8th for election night**
+
+Week 7: November 15
+...................
 
-Week 7: November 17
-.......................
+Object Oriented Programming:
 
-Object Oriented Programming: classes, instances, and methods
+classes, instances, methods, inheritance
 
 
-Week 8: November 24
-....................
+Week 8: November 22
+...................
 More OO: Multiple inheritance, Properties, Special methods.
 
 Emulating built-in types
 
 
-Week 9: December 1
+Week 9: November 29
 ...................
+Lambda
+
+Functions as Objects
 
 Iterators and Generators
 
 
-Week 10: December 8
-....................
+Week 10: December 6
+...................
 
 Decorators
 
diff --git a/slides_sources/build_gh_pages.sh b/slides_sources/build_gh_pages.sh
index 02ab36d3..6eccd8fb 100755
--- a/slides_sources/build_gh_pages.sh
+++ b/slides_sources/build_gh_pages.sh
@@ -3,15 +3,26 @@
 # simple script to build and push to gh-pages
 # designed to be run from master
 
+# To use this script you need another copy of the repo, right next this
+# one, but named "IntroToPython.gh-pages"
+# this script builds the docs, then copies them to the other repo
+# then pushes that to gitHub
+
+GHPAGESDIR=../../IntroToPython.gh-pages/
+
+# make sure the Gh pages repo is there and in the right branch
+pushd $GHPAGESDIR
+git checkout gh-pages
+popd
+
 # make the docs
 make html
-
 # copy to other repo (on the gh-pages branch)
-cp -R build/html/ ../../IntroToPython.gh-pages
+cp -R build/html/ $GHPAGESDIR
 
-cd ../../IntroToPython.gh-pages
-git checkout gh-pages
+pushd $GHPAGESDIR
 git add * # in case there are new files added
 git commit -a -m "updating presentation materials"
-git pull -s ours
+git pull -s ours --no-edit
 git push
+
diff --git a/slides_sources/source/conf.py b/slides_sources/source/conf.py
index f31fc924..ace14544 100644
--- a/slides_sources/source/conf.py
+++ b/slides_sources/source/conf.py
@@ -36,11 +36,15 @@
     'sphinx.ext.coverage',
     # 'sphinx.ext.pngmath',
     'sphinx.ext.mathjax',
+    #'sphinx.ext.jsmath',
     'sphinx.ext.ifconfig',
     'IPython.sphinxext.ipython_console_highlighting',
     'IPython.sphinxext.ipython_directive',
 ]
 
+# this doesn't work.
+jsmath_path = "../../../jsMath-3.6e/easy/load.js" # needed for jsmath
+
 # Add any paths that contain templates here, relative to this directory.
 templates_path = ['_templates']
 
diff --git a/slides_sources/source/exercises/args_kwargs_lab.rst b/slides_sources/source/exercises/args_kwargs_lab.rst
new file mode 100644
index 00000000..2adffc00
--- /dev/null
+++ b/slides_sources/source/exercises/args_kwargs_lab.rst
@@ -0,0 +1,71 @@
+.. _exercise_args_kwargs_lab:
+
+*******************
+args and kwargs Lab
+*******************
+
+Learning about ``args`` and ``kwargs``
+======================================
+
+Goal:
+-----
+
+Develop an understanding of using advanced argument passing and parameter definitons.
+
+If this is all confusing -- you may want to review this:
+
+http://stupidpythonideas.blogspot.com/2013/08/arguments-and-parameters.html
+
+Procedure
+---------
+
+**Keyword arguments:**
+
+* Write a function that has four optional parameters (with defaults):
+
+  - `fore_color`
+  - `back_color`
+  - `link_color`
+  - `visited_color`
+
+* Have it print the colors (use strings for the colors)
+
+* Call it with a couple different parameters set
+
+  - using just positional arguments:
+
+    - ``func('red', 'blue', 'yellow', 'chartreuse')``
+
+  - using just keyword arguments:
+
+    -  ``func(link_color='red', back_color='blue')``
+
+  - using a combination of positional and keyword
+
+    -  ````func('purple', link_color='red', back_color='blue')``
+
+  - using ``*some_tuple`` and/or ``**some_dict``
+
+    - ``regular = ('red', 'blue')``
+
+    - ``links = {'link_color': 'chartreuse'}``
+
+    - ``func(*regular, *links)``
+
+.. nextslide::
+
+**Generic parameters:**
+
+* Write a the same function with the parameters as:
+
+``*args`` and ``**kwags``
+
+* Have it print the colors (use strings for the colors)
+
+* Call it with the same various combinations of arguments used above.
+
+*  Also have it print `args` and `kwargs` directly, so you can be sure you understand what's going on.
+
+* Note that in general, you can't know what will get passed into ``**kwargs`` So maybe adapt your function to be able to do something reasonable with any keywords.
+
+
diff --git a/slides_sources/source/exercises/comprehensions_lab.rst b/slides_sources/source/exercises/comprehensions_lab.rst
index 5fac6b40..fb9152e5 100644
--- a/slides_sources/source/exercises/comprehensions_lab.rst
+++ b/slides_sources/source/exercises/comprehensions_lab.rst
@@ -133,7 +133,7 @@ Dictionary comprehensions
                            'forth':'fanatical devotion',
                            'fifth': None}
     >>> dict_comprehension = \
-    { k.upper(): weapon for k, weapon in dict_of_weapons.iteritems() if weapon}
+    { k.upper(): weapon for k, weapon in dict_of_weapons.items() if weapon}
 
 What is the output of:
 
@@ -164,8 +164,6 @@ https://github.com/gregmalcolm/python_koans/blob/master/python3/koans/about_comp
 Count Even Numbers
 ------------------
 
-Use test-driven development!
-
 This is from CodingBat "count_evens" (http://codingbat.com/prob/p189616)
 
 *Using a list comprehension*, return the number of even integers in the given array.
@@ -190,7 +188,7 @@ Note: the % "mod" operator computes the remainder, e.g. ``5 % 2`` is 1.
 ``dict`` and ``set`` comprehensions
 ------------------------------------
 
-Let's revisiting the dict/set lab -- see how much you can do with
+Revisiting the dict/set lab -- see how much you can do with
 comprehensions instead.
 
 (:ref:`exercise_dict_lab`)
@@ -234,11 +232,19 @@ divisible 2, 3 and 4.
 
     a. Do this with one set comprehension for each set.
 
-    b. What if you had a lot more than 3? -- Don't Repeat Yourself (DRY)
+    b. What if you had a lot more than 3? -- Don't Repeat Yourself (DRY).
 
-       - create a sequence that holds all three sets
+       - create a sequence that holds all the divisors you might want --
+         could be 2,3,4, or could be any other arbitrary divisors.
 
        - loop through that sequence to build the sets up -- so no repeated code.
+         you will end up with a list of sets -- one set for each divisor in your
+         sequence.
+
+       - The idea here is that when you see three (Or more!) lines of code that
+         are almost identical, then you you want to find a way to generalize
+         that code and have it act on a set of inputs, so the actual code is
+         only written once.
 
     c. Extra credit:  do it all as a one-liner by nesting a set comprehension
        inside a list comprehension. (OK, that may be getting carried away!)
diff --git a/slides_sources/source/exercises/dict_lab.rst b/slides_sources/source/exercises/dict_lab.rst
index 519e1f10..fe4ce49c 100644
--- a/slides_sources/source/exercises/dict_lab.rst
+++ b/slides_sources/source/exercises/dict_lab.rst
@@ -67,7 +67,7 @@ actions:
 
 
 * Using the dictionary from item 1: Make a dictionary using the same keys but
-  with the number of 't's in each value.
+  with the number of 't's in each value as the value. (upper and lower case?).
 
 .. nextslide:: Sets
 
diff --git a/slides_sources/source/exercises/fib_and_lucas.rst b/slides_sources/source/exercises/fib_and_lucas.rst
index 0181536c..86343f60 100644
--- a/slides_sources/source/exercises/fib_and_lucas.rst
+++ b/slides_sources/source/exercises/fib_and_lucas.rst
@@ -73,6 +73,14 @@ Calling this function with no optional parameters will produce numbers from the
 produce values from the *lucas numbers*. Other values for the optional
 parameters will produce other series.
 
+**Note:** While you *could* check the input arguments, and then call one
+of the functions you wrote, the idea of this exercise is to make a general
+function, rather than one specialized. So you should re-impliment the code
+in this function.
+
+In fact, you could go back and re-impliment your fibonacci and lucas
+functions to call this one with particular arguments.
+
 Ensure that your function has a well-formed ``docstring``
 
 Tests...
diff --git a/slides_sources/source/exercises/file_lab.rst b/slides_sources/source/exercises/file_lab.rst
new file mode 100644
index 00000000..44b3f656
--- /dev/null
+++ b/slides_sources/source/exercises/file_lab.rst
@@ -0,0 +1,55 @@
+.. _exercise_file_lab:
+
+********
+File LAB
+********
+
+A bit of practice with files
+============================
+
+Goal:
+-----
+
+Get a little bit of practice with handling files and parsing simple text.
+
+
+Paths and File Processing
+--------------------------
+
+* write a program which prints the full path to all files in the current
+  directory, one per line
+
+* write a program which copies a file from a source, to a destination
+  (without using shutil, or the OS copy command)
+
+  - advanced: make it work for any size file: i.e. don't read the entire
+    contents of the file into memory at once.
+
+  - This should work for any kind of file, so you need to open
+    the files in binary mode: ``open(filename, 'rb')`` (or ``'wb'`` for
+    writing). Note that for binary files, you can't use ``readline()`` --
+    lines don't have any meaning for binary files.
+
+  - Test it with both text and binrary files (maybe jpeg or??)
+
+
+File reading and parsing
+------------------------
+
+
+In the class repo, in:
+
+``Examples/Session01/students.txt``
+
+You will find the list I generated in the first class of all the students in the class, and what programming languages they have used in the past.
+
+Write a little script that reads that file, and generates a list of all
+the languages that have been used.
+
+Extra credit: keep track of how many students specified each language.
+
+If you've got git set up right, ``git pull upstream master`` should update
+your repo. Otherwise, you can get it from gitHub:
+
+https://github.com/UWPCE-PythonCert/IntroPython2016/blob/master/Examples/Session01/students.txt
+
diff --git a/slides_sources/source/exercises/fizz_buzz.rst b/slides_sources/source/exercises/fizz_buzz.rst
index 33f0091c..d6f19fe1 100644
--- a/slides_sources/source/exercises/fizz_buzz.rst
+++ b/slides_sources/source/exercises/fizz_buzz.rst
@@ -35,12 +35,12 @@ Hint:
 
 * Look up the ``%``  operator. What do these do?
 
-  * ``10 % 7 == 3``
-  * ``14 % 7 == 0``
+  * ``10 % 7``
+  * ``14 % 7``
 
 (try that in iPython)
 
-* Do try to write it without looking it up -- there are a million nifty solutions posted on the web.
+* **Do** try to write a solution *before* looking it up -- there are a million nifty solutions posted on the web, but you'll learn a lot more if you figure it out on your own first.
 
 Results:
 --------
diff --git a/slides_sources/source/exercises/grid_printer.rst b/slides_sources/source/exercises/grid_printer.rst
index 22619198..41e43f57 100644
--- a/slides_sources/source/exercises/grid_printer.rst
+++ b/slides_sources/source/exercises/grid_printer.rst
@@ -169,7 +169,7 @@ Even more general...
 A function with two parameters
 -------------------------------
 
-Write a function that draws a similar grid with a specified number of rows and three columns.
+Write a function that draws a similar grid with a specified number of rows and columns, and each cell a given size.
 
 for example,  ``print_grid2(3,4)`` results in::
 
diff --git a/slides_sources/source/exercises/html_renderer.rst b/slides_sources/source/exercises/html_renderer.rst
index eaa1bf73..d38dc6e0 100644
--- a/slides_sources/source/exercises/html_renderer.rst
+++ b/slides_sources/source/exercises/html_renderer.rst
@@ -39,7 +39,7 @@ You should be able to run that code at each step, uncommenting each new step in
 
 It builds up an html tree, and then calls the ``render()`` method of your element to render the page.
 
-It uses a ``cStringIO`` object (like a file, but in memory) to render to memory, then dumps it to the console, and writes a file. Take a look at the code at the end to make sure you understand it.
+It uses a ``StringIO`` object (like a file, but in memory) to render to memory, then dumps it to the console, and writes a file. Take a look at the code at the end to make sure you understand it.
 
 The html generated at each step will be in the files: ``test_html_ouput?.html``
 
@@ -93,7 +93,7 @@ It should have a ``render(file_out, ind = "")`` method that renders the tag and
 
 The amount of each level of indentation should be set by the class attribute: ``indent``
 
-NOTE: don't worry too much about indentation at this stage -- the primary goal is to get proper, compliant html. i.e. the opening and closing tags rendered correctly. Worry about cleaning up the indentation once you've got that working.
+NOTE: don't worry too much about indentation at this stage -- the primary goal is to get proper, compliant html. i.e. the opening and closing tags rendered correctly. Worry about cleaning up the indentation once you've got that working. See "Note on indentation" below for more explaination.
 
 .. nextslide::
 
@@ -162,6 +162,42 @@ You can now render some ```` tags (and others) with attributes
 
 See ``test_html_output4.html``
 
+.. nextslide:: the "class" attribute.
+
+NOTE: if you do "proper" CSS+html, then you wouldn't specify style directly in element attributes.
+
+Rather you would set the "class" attribute::
+
+  
+    This is my recipe for making curry purely with chocolate
+  
+
+However, if you try this as a keywork argument in Python:
+
+.. code-block:: ipython
+
+   In [1]: P("some content", class="intro")
+   File "", line 1
+     P("some content", class="intro")
+                          ^
+   SyntaxError: invalid syntax
+
+Huh?
+
+"class" is a reserved work in Python -- for making classes.
+So it can't be used as a keywork argument.
+
+But it's a fine key in a dict, so you can put it in a dict, and pass it in with ``**``:
+
+.. code-block:: python
+
+    attrs = {'class': 'intro'}
+    P("some content", **attrs)
+
+You could also special-case this in your code -- so your users could use "clas"
+with one s, and you could tranlate it in the generated html.
+
+
 Step 5:
 --------
 
@@ -176,7 +212,7 @@ Create a couple subclasses of ``SelfClosingTag`` for and 
 and 
 
 Note that you now have a couple render methods -- is there repeated code in them?
 
-Can you refactor the common parts into a separate method that all the render methods can call?
+Can you refactor the common parts into a separate method that all the render methods can call? And do all your tests still pass (you do have tests for everything, don't you?) after refactoring?
 
 See ``test_html_output5.html``
 
@@ -191,7 +227,7 @@ where ``link`` is the link, and ``content`` is what you see. It can be called li
 
     A("http://google.com/", "link to google")
 
-You should be able to subclass from ``Element``, and only override the ``__init__`` --- Calling the ``Element`` ``__init__`` from the  ``A __init__``
+You should be able to subclass from ``Element``, and only override the ``__init__`` --- calling the ``Element`` ``__init__`` from the  ``A __init__``
 
 You can now add a link to your web page.
 
@@ -235,6 +271,32 @@ new tags, etc....
 
 See ``test_html_output8.html``
 
+Note on indentation
+===================
+
+Indentation is not stricly required for html -- html ignores most whitespace.
+
+But it can make it much easier to read for humans, and it's a nice excercise to see how one might make it nice.
+
+There is also more than one way to indent html -- so you have a bit of flexibility here.
+
+So:
+
+* You probably  ``ind`` to be an optional argument to render -- so it will not indent if nothing is passed in. And that lets you write the code without indentation first if you like.
+
+* But ultimately, you want your code to USE the ind parameter -- it is supposed to indicate how much this entire tag is already indented.
+
+* When this one gets rendered, you don't know where it is in a potentially deeply nested hierarchy -- it could be at the top level or ten levels deep. passing ``ind`` into the render method is how this is communicated.
+
+* You have (at least) two options for how to indicate level of indentation:
+
+  - It could be a integer indicating number of levels of indentation
+  - It could, more simply, be a bunch of spaces.
+
+* You want to have the amount of spaces per indentation defined as a class attribute of the base class (the ``Element`` class). That way, you could change it in one place, and it would change everywhere an remain consistent.
+
+
+
 Notes on handling "duck typing"
 ===============================
 
@@ -266,7 +328,8 @@ You can handle it ahead of time by creating a simple object that wraps a string
           self.text = text
 
       def render(self, file_out, current_ind=""):
-          file_out.write(current_ind + self.text)
+          file_out.write(current_ind)
+          file_out.write(self.text)
 
 .. nextslide::
 
@@ -284,7 +347,7 @@ But this is not very Pythonic style -- it's OO heavy. Strings for text are so co
 
 So much easier.
 
-To accomplish this, you can update the ``append()`` method to put this wrapper around plain strings when somethign new is added.
+To accomplish this, you can update the ``append()`` method to put this wrapper around plain strings when something new is added.
 
 
 Checking if it's the right type
@@ -321,24 +384,28 @@ I think this is a little better -- strings are a pretty core type in python, it'
 Duck Typing
 -----------
 
-The Python model of duck typing is if quacks like a duck, then treat it like a duck.
+The Python model of duck typing is: If quacks like a duck, then treat it like a duck.
 
 But in this case, we're not actually rendering the object at this stage, so calling the method isn't appropriate.
 
 **Checking for an attribute**
 
-Instead of calling the method, see if it's there:
+Instead of calling the method, see if it's there. You can do that with ``hasattr()``
 
-You can check if the passed-in object has a ``render()`` attribute:
+check if the passed-in object has a ``render()`` attribute:
 
 .. code-block:: python
 
     if hasattr(content, 'render'):
         self.content.append(content)
     else:
-        self.content.append(TextWrapper(content))
+        self.content.append(TextWrapper(str(content))
+
+
+Note that I added a ``str()`` call too -- so you can pass in anything -- it will get stringified -- this will be ugly for many objects, but will work fine for numbers and other simple objects.
+
+This is my favorite. ``html_render_wrap.py`` in Solutions demonstrates some core bits of this approach.
 
-This is my favorite. ``html_render_wrap.py`` in Solutions demonstrates with method.
 
 Duck Typing on the Fly
 ----------------------
@@ -356,7 +423,7 @@ Again, you could type check -- but I prefer the duck typing approach, and EAFP:
 
 If content is a simple string then it won't have a render method, and an ``AttributeError`` will be raised.
 
-You can catch that, and simply write the content.
+You can catch that, and simply write the content directly instead.
 
 .. nextslide::
 
@@ -376,11 +443,11 @@ If the object doesn't have a ``render`` method, then an AttributeError will be r
 
 Depending on what's broken, it could raise any number of exceptions. Most will not get caught by the except clause, and will halt the program.
 
-But if, just by bad luck, it has an bug that raises an ``AttributeError`` -- then this could with catch it, and try to simply write it out instead. So you may get somethign like: ```` in the middle of your html.
+But if, just by bad luck, it has an bug that raises an ``AttributeError`` -- then this could catch it, and try to simply write it out instead. So you may get something like: ```` in the middle of your html.
 
 **The beauty of testing**
 
-If you have a unit test that calls every render method in your code -- then it should catch that error, and it wil be clear where it is coming from.
+If you have a unit test that calls every render method in your code -- then it should catch that error, and in the unit test it will be clear where it is coming from.
 
 
 HTML Primer
@@ -388,13 +455,13 @@ HTML Primer
 
 .. rst-class:: medium
 
-    The very least you need to know about html to do this assigment.
+    The very least you need to know about html to do this assignment.
 
 .. rst-class:: left
 
-  If you are familar with html, then this will all make sense to you. If you have never seen html before, this might be a bit intimidating, but you really don't need to know much to do this assignment.
+  If you are familiar with html, then this will all make sense to you. If you have never seen html before, this might be a bit intimidating, but you really don't need to know much to do this assignment.
 
-  First of all, sample output from each step is provided. So all you really need to do is look at that, and make your code do the same thing. But it does help to know a little bit about what you are doing.
+  First of all, sample output from each step is provided. So all you really need to do is look at that, and make your code do the same thing. But it does help understand a little bit about what you trying to do.
 
 HTML
 ----
@@ -421,15 +488,16 @@ Elements
 Modern HTML is a particular dialect of XML (eXtensible Markup Language),
 which is itself a special case of SGML (Standard Generalized Markup Language)
 
-It inherits from SGML a basic structure: each piece of the document is an element. each element is described by a "tag". Each tag has a different meaning, but they all have the same structure::
+It inherits from SGML a basic structure: each piece of the document is an element. Each element is described by a "tag". Each tag has a different meaning, but they all have the same structure::
 
      some content 
 
-that is, the tag name is surrounded by < and >, which marks the beginning of
+That is, the tag name is surrounded by < and >, which marks the beginning of
 the element, and the end of the element is indicated by the same tag with a slash.
 
 The real power is that these elements can be nested arbitrarily deep. In order to keep that all readable, we often want to indent the content inside the tags, so it's clear what belongs with what. That is one of the tricky bits of this assignment.
 
+
 Basic tags
 ----------
 
@@ -450,7 +518,7 @@ In addition to the tag name and the content, extra attributes can be attached to
 
 .. code-block:: html
 
-    
+    
 
 There can be all sorts of stuff stored in attributes -- some required for specific tags, some extra, like font sizes and colors. Note that since tags can essentially have any attributes, your code will need to support that -- doesn't it kind of look like a dict? And keyword arguments?
 
@@ -471,7 +539,10 @@ To make a link, you use an "anchor" tag: ````. It requires attributes to indi
 
 The ``href`` attribute is the link (hyper reference).
 
-To make a bulleted list, you use a  tag (unordered list), and inside that, you put individual list elements - :
+lists
+-----
+
+To make a bulleted list, you use a  tag (unordered list), and inside that, you put individual list items - :
 
 .. code-block:: html
 
@@ -484,7 +555,7 @@ To make a bulleted list, you use a  tag (unordered list), and inside that, y
              
 -Note that the list itself, and the list items can both take various attributes (all tags can...)
+Note that the list itself *and* the list items can both take various attributes (all tags can...)
 
 Section Headers are created with "h" tags: is the biggest (highest level), and there is , , etc. for sections, sub sections, subsub sections...
 
@@ -493,17 +564,3 @@ Section Headers are created with "h" tags:  is the biggest (highest level),
     PythonClass - Class 7 exampleI think that's all you need to know!
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/slides_sources/source/exercises/index.rst b/slides_sources/source/exercises/index.rst
index 51cc1031..78ac470e 100644
--- a/slides_sources/source/exercises/index.rst
+++ b/slides_sources/source/exercises/index.rst
@@ -34,6 +34,7 @@ Session 4:
     :maxdepth: 1
 
     dict_lab
+    file_lab
     kata_fourteen
 
 Session 5:
@@ -49,8 +50,8 @@ Session 6:
 .. toctree::
     :maxdepth: 1
 
-    lambda_magic
-    trapezoid
+    args_kwargs_lab
+
 
 Session 7:
 ----------
@@ -65,5 +66,12 @@ Session 8:
     :maxdepth: 1
 
     circle_class
-
     sparse_array
+
+Session 9:
+----------
+.. toctree::
+    :maxdepth: 1
+
+    lambda_magic
+    trapezoid
\ No newline at end of file
diff --git a/slides_sources/source/exercises/lambda_magic.rst b/slides_sources/source/exercises/lambda_magic.rst
index 1c288a80..edcde112 100644
--- a/slides_sources/source/exercises/lambda_magic.rst
+++ b/slides_sources/source/exercises/lambda_magic.rst
@@ -23,7 +23,7 @@ incremented by an increasing number.
 
 Use a for loop, ``lambda``, and a keyword argument
 
-( Extra credit ):
+**Extra credit:**
 
 Do it with a list comprehension, instead of a for loop
 
@@ -56,6 +56,6 @@ Example calling code
 
 .. nextslide::
 
-See the test code in Examples/Session06
+See the test code in Examples/Session09
 
 
diff --git a/slides_sources/source/exercises/list_lab.rst b/slides_sources/source/exercises/list_lab.rst
index cb5aaae2..36943bfb 100644
--- a/slides_sources/source/exercises/list_lab.rst
+++ b/slides_sources/source/exercises/list_lab.rst
@@ -31,7 +31,7 @@ to query the user for info at the command line, you use:
 Procedure
 ---------
 
-In your student dir in the IntroPython2015 repo, create a ``session02`` dir and put in a new ``list_lab.py`` file.
+In your student dir in the IntroPython2015 repo, create a ``session03`` dir and put in a new ``list_lab.py`` file.
 
 The file should be an executable python script. That is to say that one
 should be able to run the script directly like so:
@@ -50,6 +50,14 @@ should be able to run the script directly like so:
 
 (The +x means make this executable)
 
+The file will also need this on the first line::
+
+    #!/usr/bin/env python3
+
+This is known as the "she-bang" line -- it tells the shell how to execute that file -- in this case, with ``python3``
+
+NOTE: on Windows, there is a python launcher which, if everything is configured correctly look at that line to know you want python3 if there is more than one python on your system.
+
 .. nextslide::
 
 Add the file to your clone of the repository and commit changes frequently
diff --git a/slides_sources/source/exercises/mailroom-oo.rst b/slides_sources/source/exercises/mailroom-oo.rst
new file mode 100644
index 00000000..17f0dacb
--- /dev/null
+++ b/slides_sources/source/exercises/mailroom-oo.rst
@@ -0,0 +1,167 @@
+.. _exercise_mailroom_oo:
+
+********
+Mailroom
+********
+
+Making Mailroom Object Oriented
+
+A complete program
+==================
+
+It was quite resonable to build the simple MailRoom program using a
+single module, a simple data structure, and functions that manipulate
+that data structure.
+
+But if one were to expand the program with additional functionality, it
+would start to get a bit unwieldy and hard to maintain.
+
+So it's a pretty good candidate for an object-oriented approach.
+
+Goal:
+-----
+
+Refactor the mailroom program usined a couple classes to help organise the code.
+
+
+
+
+The program
+-----------
+
+Write a small command-line script called ``mailroom.py``. This script should be executable. The script should accomplish the following goals:
+
+* It should have a data structure that holds a list of your donors and a
+  history of the amounts they have donated. This structure should be populated
+  at first with at least five donors, with between 1 and 3 donations each
+
+* The script should prompt the user (you) to choose from a menu of 3 actions:
+  'Send a Thank You' or 'Create a Report' or 'quit')
+
+Sending a Thank You
+-------------------
+
+* If the user (you) selects 'Send a Thank You', prompt for a Full Name.
+
+  * If the user types 'list', show them a list of the donor names and re-prompt
+  * If the user types a name not in the list, add that name to the data structure and use it.
+  * If the user types a name in the list, use it.
+  * Once a name has been selected, prompt for a donation amount.
+  * Turn the amount into a number -- it is OK at this point for the program to crash if someone types a bogus amount.
+  * Once an amount has been given, add that amount to the donation history of
+    the selected user.
+  * Finally, use string formatting to compose an email thanking the donor for
+    their generous donation. Print the email to the terminal and return to the
+    original prompt.
+
+**It is fine to forget new donors once the script quits running.**
+
+Creating a Report
+------------------
+
+* If the user (you) selected 'Create a Report' print a list of your donors,
+  sorted by total historical donation amount.
+
+  - Include Donor Name, total donated, number of donations and average donation amount as values in each row. You do not need to print out all their donations, just the summary info.
+  - Using string formatting, format the output rows as nicely as possible.  The end result should be tabular (values in each column should align with those above and below)
+  - After printing this report, return to the original prompt.
+
+* At any point, the user should be able to quit their current task and return
+  to the original prompt.
+
+* From the original prompt, the user should be able to quit the script cleanly
+
+
+Your report should look something like this::
+
+    Donor Name                | Total Given | Num Gifts | Average Gift
+    ------------------------------------------------------------------
+    William Gates, III         $  653784.49           2  $   326892.24
+    Mark Zuckerberg            $   16396.10           3  $     5465.37
+    Jeff Bezos                 $     877.33           1  $      877.33
+    Paul Allen                 $     708.42           3  $      236.14
+
+Guidelines
+----------
+
+First, factor your script into separate functions. Each of the above
+tasks can be accomplished by a series of steps.  Write discreet functions
+that accomplish individual steps and call them.
+
+Second, use loops to control the logical flow of your program. Interactive
+programs are a classic use-case for the ``while`` loop.
+
+Of course, ``input()`` will be useful here.
+
+Put the functions you write into the script at the top.
+
+Put your main interaction into an ``if __name__ == '__main__'`` block.
+
+Finally, use only functions and the basic Python data types you've learned
+about so far. There is no need to go any farther than that for this assignment.
+
+Submission
+----------
+
+As always, put the new file in your student directory in a ``session03``
+directory, and add it to your clone early. Make frequent commits with
+good, clear messages about what you are doing and why.
+
+When you are done, push your changes and make a pull request.
+
+.. _exercise_mailroom_plus:
+
+Adding dicts...
+---------------
+
+
+For the next week (after Session04)
+
+You should have been able to do all that with the basic data types:
+
+numbers, strings, lists and tuples.
+
+But once you've learned about dictionaries (Session04) you may be able to re-write it a bit more simply and efficiently.
+
+ * Update mailroom from last week to:
+
+  - Use dicts where appropriate
+  - Write a full set of letters to everyone to individual files on disk
+  - See if you can use a dict to switch between the users selections
+  - Try to use a dict and the .format() method to do the letter as one
+    big template -- rather than building up a big string in parts.
+
+Example:
+
+.. code-block:: ipython
+
+  In [3]: d
+  Out[3]: {'first_name': 'Chris', 'last_name': 'Barker'}
+
+
+  In [5]: "My name is {first_name} {last_name}".format(**d)
+  Out[5]: 'My name is Chris Barker'
+
+Don't worry too much about the "**" -- we'll get into the details later, but for now, it means, more or less -- pass this whole dict in as a bunch of keyword arguments.
+
+
+.. _exercise_mailroom_exeptions:
+
+Adding Exceptions
+-----------------
+
+**After Session05:**
+
+* Exceptions:
+
+Now that you've learned about Exception handling, you can update your code to handle errors better -- like when a user inputs bad data.
+
+* Comprehensions:
+
+Can you use comprehensions to clean up your code a bit?
+
+* Tests
+
+Add some tests..
+
+
diff --git a/slides_sources/source/exercises/mailroom.rst b/slides_sources/source/exercises/mailroom.rst
index 077349b7..656e5c19 100644
--- a/slides_sources/source/exercises/mailroom.rst
+++ b/slides_sources/source/exercises/mailroom.rst
@@ -14,7 +14,7 @@ Goal:
 
 You work in the mail room at a local charity. Part of your job is to write
 incredibly boring, repetitive emails thanking your donors for their generous
-gifts. You are tired of doing this over an over again, so yo've decided to
+gifts. You are tired of doing this over an over again, so you've decided to
 let Python help you out of a jam.
 
 The program
@@ -26,8 +26,8 @@ Write a small command-line script called ``mailroom.py``. This script should be
   history of the amounts they have donated. This structure should be populated
   at first with at least five donors, with between 1 and 3 donations each
 
-* The script should prompt the user (you) to choose from a menu of 2 actions:
-  'Send a Thank You' or 'Create a Report'.
+* The script should prompt the user (you) to choose from a menu of 3 actions:
+  'Send a Thank You' or 'Create a Report' or 'quit')
 
 Sending a Thank You
 -------------------
@@ -38,7 +38,7 @@ Sending a Thank You
   * If the user types a name not in the list, add that name to the data structure and use it.
   * If the user types a name in the list, use it.
   * Once a name has been selected, prompt for a donation amount.
-  * Verify that the amount is in fact a number, and re-prompt if it isn't.
+  * Turn the amount into a number -- it is OK at this point for the program to crash if someone types a bogus amount.
   * Once an amount has been given, add that amount to the donation history of
     the selected user.
   * Finally, use string formatting to compose an email thanking the donor for
@@ -50,10 +50,10 @@ Sending a Thank You
 Creating a Report
 ------------------
 
-* If the user (you) selected 'Create a Report' Print a list of your donors,
+* If the user (you) selected 'Create a Report' print a list of your donors,
   sorted by total historical donation amount.
 
-  - Include Donor Name, total donated, number of donations and average donation amount as values in each row.
+  - Include Donor Name, total donated, number of donations and average donation amount as values in each row. You do not need to print out all their donations, just the summary info.
   - Using string formatting, format the output rows as nicely as possible.  The end result should be tabular (values in each column should align with those above and below)
   - After printing this report, return to the original prompt.
 
@@ -62,6 +62,16 @@ Creating a Report
 
 * From the original prompt, the user should be able to quit the script cleanly
 
+
+Your report should look something like this::
+
+    Donor Name                | Total Given | Num Gifts | Average Gift
+    ------------------------------------------------------------------
+    William Gates, III         $  653784.49           2  $   326892.24
+    Mark Zuckerberg            $   16396.10           3  $     5465.37
+    Jeff Bezos                 $     877.33           1  $      877.33
+    Paul Allen                 $     708.42           3  $      236.14
+
 Guidelines
 ----------
 
@@ -89,3 +99,60 @@ directory, and add it to your clone early. Make frequent commits with
 good, clear messages about what you are doing and why.
 
 When you are done, push your changes and make a pull request.
+
+.. _exercise_mailroom_plus:
+
+Adding dicts...
+---------------
+
+
+For the next week (after Session04)
+
+You should have been able to do all that with the basic data types:
+
+numbers, strings, lists and tuples.
+
+But once you've learned about dictionaries (Session04) you may be able to re-write it a bit more simply and efficiently.
+
+ * Update mailroom from last week to:
+
+  - Use dicts where appropriate
+  - Write a full set of letters to everyone to individual files on disk
+  - See if you can use a dict to switch between the users selections
+  - Try to use a dict and the .format() method to do the letter as one
+    big template -- rather than building up a big string in parts.
+
+Example:
+
+.. code-block:: ipython
+
+  In [3]: d
+  Out[3]: {'first_name': 'Chris', 'last_name': 'Barker'}
+
+
+  In [5]: "My name is {first_name} {last_name}".format(**d)
+  Out[5]: 'My name is Chris Barker'
+
+Don't worry too much about the "**" -- we'll get into the details later, but for now, it means, more or less -- pass this whole dict in as a bunch of keyword arguments.
+
+
+.. _exercise_mailroom_exeptions:
+
+Adding Exceptions
+-----------------
+
+**After Session05:**
+
+* Exceptions:
+
+Now that you've learned about Exception handling, you can update your code to handle errors better -- like when a user inputs bad data.
+
+* Comprehensions:
+
+Can you use comprehensions to clean up your code a bit?
+
+* Tests
+
+Add some tests..
+
+
diff --git a/slides_sources/source/exercises/sparse_array.rst b/slides_sources/source/exercises/sparse_array.rst
index a74f1a1d..f627c82a 100644
--- a/slides_sources/source/exercises/sparse_array.rst
+++ b/slides_sources/source/exercises/sparse_array.rst
@@ -20,7 +20,7 @@ Oftentimes, at least in computation programming, we have large arrays of data th
 
 These are referred to as "sparse" as the information in them is widely scattered, or sparse.
 
-Since they are mostly zeros, it can be memory an computationally efficient to store only the value that are non-zero.
+Since they are mostly zeros, it can be memory and computationally efficient to store only the value that are non-zero.
 
 But you want it to look like a regular array in user code.
 
diff --git a/slides_sources/source/exercises/string_formatting.rst b/slides_sources/source/exercises/string_formatting.rst
index c28c3f0a..f01556d9 100644
--- a/slides_sources/source/exercises/string_formatting.rst
+++ b/slides_sources/source/exercises/string_formatting.rst
@@ -21,10 +21,10 @@ https://pyformat.info/
 
 And a nice "Cookbook":
 
-https://mkaz.github.io/2012/10/10/python-string-format/
+https://mkaz.tech/python-string-format.html
 
 
-A couple Exercises
+A Couple Exercises
 ------------------
 
 * Write a format string that will take:
@@ -33,17 +33,79 @@ A couple Exercises
 
     and produce:
 
-    ``'file_002 :   123.46, 1e+04'``
+    ``'file_002 :   123.46, 1.00e+04'``
 
-* Rewrite: ``"the first 3 numbers are: {:d}, {:d}, {:d}".format(1,2,3)``
-  to take an arbitrary number of values
+**Note:** the idea behind the "file_002" is that if you have a bunch of files that you want to name with numbers that can be sorted, you need to "pad" the numbers with zeros to get the right sort order.
 
-Trick: You can pass in a tuple of values to a function with a ``*``::
+.. nextslide::
+
+For example:
+
+.. code-block:: ipython
+
+    In [10]: fnames = ['file1', 'file2', 'file10', 'file11']
+    In [11]: fnames.sort()
+    In [12]: fnames
+    Out[12]: ['file1', 'file10', 'file11', 'file2']
+
+That is probably not what you want. However:
+
+.. code-block:: ipython
+
+    In [1]: fnames = ['file001', 'file002', 'file010', 'file011']
+    In [3]: sorted(fnames)
+    Out[3]: ['file001', 'file002', 'file010', 'file011']
+
+That works!
+
+So you want to find a string formatting operator that will "pad" the number with zeros for you.
+
+Dynamically Building up format strings
+--------------------------------------
+
+* Rewrite:
+
+``"the 3 numbers are: {:d}, {:d}, {:d}".format(1,2,3)``
+
+to take an arbitrary number of values.
+
+Trick: You can pass in a tuple of values to a function with a ``*``:
 
 .. code-block:: ipython
 
     In [52]: t = (1,2,3)
 
-    In [53]: "the first 3 numbers are: {:d}, {:d}, {:d}".format(* t)
-    Out[53]: 'the first 3 numbers are: 1, 2, 3'
+    In [53]: "the 3 numbers are: {:d}, {:d}, {:d}".format(*t)
+    Out[53]: 'the 3 numbers are: 1, 2, 3'
+
+.. nextslide::
+
+The idea here is that you may have a tuple of three numbers, but might also have 4 or 5 or....
+
+So you can dynamically build up the format string to accommodate the length of the tuple.
+
+The string object has the ``format()`` method, so you can call it with a string that is bound to a name, not just a string literal. For example:
+
+.. code-block:: ipython
+
+    In [16]: fstring = "{:d}, {:d}"
+
+    In [17]: nums = (34, 56)
+
+    In [18]: fstring.format(*nums)
+    Out[18]: '34, 56'
+
+So how would you make an fstring that was the right length for an arbitrary tuple?
+
+.. nextslide::
+
+Put your code in a function that will return the formatted string like so:
+
+.. code-block:: ipython
+
+    In [20]: formatter((2,3,5))
+    Out[20]: 'the 3 numbers are: 2, 3, 5'
+
+    In [21]: formatter((2,3,5,7,9))
+    Out[21]: 'the 5 numbers are: 2, 3, 5, 7, 9'
 
diff --git a/slides_sources/source/exercises/trapezoid.rst b/slides_sources/source/exercises/trapezoid.rst
index f95230d6..bf6c97ef 100644
--- a/slides_sources/source/exercises/trapezoid.rst
+++ b/slides_sources/source/exercises/trapezoid.rst
@@ -8,11 +8,11 @@ Passing functions around
 =========================
 
 
-.. rst-class:: large left
+.. rst-class:: medium left
 
     Goal:
 
-.. rst-class:: medium left
+.. rst-class:: left
 
     Making use of functions as objects -- functions that act on functions.
 
@@ -20,17 +20,15 @@ Passing functions around
 Trapezoidal rule
 ----------------
 
-.. rst-class:: medium
-
-  The "trapezoidal rule":
+The "trapezoidal rule":
 
-  https://en.wikipedia.org/wiki/Trapezoidal_rule
+https://en.wikipedia.org/wiki/Trapezoidal_rule
 
-  Is one of the easiest "quadrature" methods.
+Is one of the easiest "quadrature" methods.
 
-  Otherwise known as computing a definite integral, or, simply,
+Otherwise known as computing a definite integral, or, simply,
 
-  Computing the area under a curve.
+Computing the area under a curve.
 
 The task
 --------
@@ -163,7 +161,7 @@ https://www.python.org/dev/peps/pep-0485/
 
 In earlier pythons -- you'll need your own. There is one in:
 
-``Examples/Session06/test_trapz.py``
+``Examples/Session09/test_trapz.py``
 
 
 
@@ -232,7 +230,7 @@ or
 
 This is pretty conceptually challenging -- but it's very little code!
 
-If you are totally lost -- look at the lecture notes from last class -- how can you both accept and pass arbitrary arguments to/from a function?
+If you are totally lost -- look at the lecture notes from previous classes -- how can you both accept and pass arbitrary arguments to/from a function?
 
 .. nextslide::
 
diff --git a/slides_sources/source/extra_topics.rst b/slides_sources/source/extra_topics.rst
new file mode 100644
index 00000000..39062e0a
--- /dev/null
+++ b/slides_sources/source/extra_topics.rst
@@ -0,0 +1,131 @@
+.. _extra_topics:
+
+************
+Extra Topics
+************
+
+Here are some extra topics that we didn't have time for in the regular class sessions:
+
+==============================
+Closures and function Currying
+==============================
+
+Defining specialized functions on the fly
+
+Closures
+--------
+
+"Closures" and "Currying" are cool CS terms for what is really just defining functions on the fly.
+
+you can find a "proper" definition here:
+
+https://en.wikipedia.org/wiki/Closure_(computer_programming)
+
+but I even have trouble following that.
+
+So let's go straight to an example:
+
+.. nextslide::
+
+.. code-block:: python
+
+    def counter(start_at=0):
+        count = [start_at]
+        def incr():
+            count[0] += 1
+            return count[0]
+        return incr
+
+What's going on here?
+
+We have stored the ``start_at`` value in a list.
+
+Then defined a function, ``incr`` that adds one to the value in the list, and returns that value.
+
+[ Quiz: why is it: ``count = [start_at]``, rather than just ``count=start_at`` ]
+
+.. nextslide::
+
+So what type of object do you get when you call ``counter()``?
+
+.. code-block:: ipython
+
+    In [37]: c = counter(start_at=5)
+
+    In [38]: type(c)
+    Out[38]: function
+
+So we get a function back -- makes sense. The ``def`` defines a function, and that function is what's getting returned.
+
+Being a function, we can, of course, call it:
+
+.. code-block:: ipython
+
+    In [39]: c()
+    Out[39]: 6
+
+    In [40]: c()
+    Out[40]: 7
+
+Each time is it called, it increments the value by one.
+
+.. nextslide::
+
+But what happens if we call ``counter()`` multiple times?
+
+.. code-block:: ipython
+
+    In [41]: c1 = counter(5)
+
+    In [42]: c2 = counter(10)
+
+    In [43]: c1()
+    Out[43]: 6
+
+    In [44]: c2()
+    Out[44]: 11
+
+So each time ``counter()`` is called, a new function is created. And that function has its own copy of the ``count`` object. This is what makes in a "closure" -- it carries with it the scope in which is was created.
+
+the returned ``incr`` function is a "curried" function -- a function with some parameters pre-specified.
+
+``functools.partial``
+---------------------
+
+The ``functools`` module in the standard library provides utilities for working with functions:
+
+https://docs.python.org/3.5/library/functools.html
+
+Creating a curried function turns out to be common enough that the ``functools.partial`` function provides an optimized way to do it:
+
+What functools.partial does is:
+
+ * Makes a new version of a function with one or more arguments already filled in.
+ * The new version of a function documents itself.
+
+Example:
+
+.. code-block:: python
+
+    def power(base, exponent):
+        """returns based raised to the give exponent"""
+        return base ** exponent
+
+Simple enough. but what if we wanted a specialized ``square`` and ``cube`` function?
+
+We can use ``functools.partial`` to *partially* evaluate the function, giving us a specialized version:
+
+square = partial(power, exponent=2)
+cube = partial(power, exponent=3)
+
+Reading:
+--------
+
+http://www.pydanny.com/python-partials-are-fun.html
+
+https://pymotw.com/3/functools/
+
+http://www.programiz.com/python-programming/closure
+
+https://www.clear.rice.edu/comp130/12spring/curry/
+
diff --git a/slides_sources/source/include.rst b/slides_sources/source/include.rst
index d2586b12..607ee281 100644
--- a/slides_sources/source/include.rst
+++ b/slides_sources/source/include.rst
@@ -1,7 +1,6 @@
 
-.. |instructor_1_name| replace:: Rick Riehle
-.. |instructor_1_email| replace:: rriehle (at) uw (dot) edu
-
-.. |instructor_2_name| replace:: Kai Yang
-.. |instructor_2_email| replace:: hky2 (at) uw (dot) edu
+.. |instructor_1_name| replace:: Christopher Barker
+.. |instructor_1_email| replace:: PythonCHB@gmail.com
 
+.. |instructor_2_name| replace:: Maria McKinley
+.. |instructor_2_email| replace:: maria@mariakathryn.net
diff --git a/slides_sources/source/index.rst b/slides_sources/source/index.rst
index 3d08ed33..040d3dfe 100644
--- a/slides_sources/source/index.rst
+++ b/slides_sources/source/index.rst
@@ -51,6 +51,7 @@ In This Course
     .. toctree::
         :maxdepth: 2
 
+        extra_topics
         exercises/index
         supplements/index
 
diff --git a/slides_sources/source/session01.rst b/slides_sources/source/session01.rst
index 1fbf2c63..a282e32a 100644
--- a/slides_sources/source/session01.rst
+++ b/slides_sources/source/session01.rst
@@ -67,14 +67,16 @@ Who are you?
 
 * name
 * programming background: what languages have you used?
-* what do you hope to get from this class
+* neighbor's name
+* neighbor's favorite coffee shop or bar
+
 
 Introduction to This Class
 ==========================
 
 .. rst-class:: center large
 
-Intro to Python
+  Introduction to Python
 
 
 Course Materials Online
@@ -84,19 +86,19 @@ A rendered HTML copy of the slides for this course may be found online at:
 
 http://uwpce-pythoncert.github.io/IntroToPython
 
-Also there are some excercise descriptions and supplemental materials.
+Also there are some exercise descriptions and supplemental materials.
 
 The source of these materials are in the class gitHub repo:
 
 https://github.com/UWPCE-PythonCert/IntroToPython
 
-Class email list: We will be using this list to communicate for this class:
+We also have a bunch of supplemental resources for the program here:
 
-programming-in-python@googlegroups.com
+http://uwpce-pythoncert.github.io/PythonResources/index.html
 
-You should have (or will soon) received and email invitation to join
-the mailing list.
+The source for those is here:
 
+https://github.com/UWPCE-PythonCert/PythonResources
 
 Class Structure
 ---------------
@@ -116,7 +118,7 @@ Interrupt me with questions -- please!
 Homework:
 ---------
 
-* Most homework will be reading, and the occasional Video
+* Homework will be reading, exercises, and the occasional Video
 
 * Exercises will be started in class -- but you can finish them at home.
 
@@ -124,28 +126,41 @@ Homework:
 
 * You can do a gitHub "pull request" if you want us to review your work.
 
-    - We'll review how to do that in the second Session
+    - We'll show you how to do that in the second session
 
 
-Mailing list and Office Hours
-------------------------------
+Communication
+-------------
 
 **Mailing list:**
 
-We've set up a google group -- you will all be invited to join:
+We've set up a Google Group for this class:
+
+programming-in-python@googlegroups.com
+
+We will be using this list to communicate with you. You should have (or will soon) received an email invitation to join the mailing list.
+
+Slack: We have set up a slack channel for discussions. Anything python related is fair game.
 
-``programming-in-python@googlegroups.com``
+https://python2016fall.slack.com/
 
-**Office Hours:**
+We highly encourage you to work together. You will learn at a much deeper level if you work together,
+and it gets you ready to collaborate with colleagues.
 
-I generally will hold "office hours" at a coffee shop for a couple hours
+
+Office Hours
+------------
+
+We will generally will hold "office hours" at a coffee shop for a couple hours
 each weekend.
 
-Maria can do some as well.
+Please feel free to attend even if you do not have a specific question.
+It is an opportunity to work with the instructors and fellow students,
+and learn from each other.
 
 What are good times for you?
 
-
+And what locations?
 
 Lightning Talks
 ----------------
@@ -155,14 +170,12 @@ Lightning Talks
  * 5 minutes each (including setup) - no kidding!
  * Every student will give one
  * Purposes: introduce yourself, share interests, show Python applications
- * Any topic you like, that is related to Python -- according to you!
-
+ * Any topic you like that is related to Python -- according to you!
 
 
 Python Ecosystem
 ================
 
-
 What is Python?
 ---------------
 
@@ -275,14 +288,14 @@ Python 3.x ("py3k")
 
 This class uses Python 3 -- not Python 2
 
-.. rst-class:: build
-
 * Adoption of Python 3 is growing fast
 
   * Almost all key packages now supported (https://python3wos.appspot.com/)
-  * But most code in the wild is still 2.x
+  * But much code in the wild is still 2.x
 
-* If you find yourself needing to work with Python 2 and 3, there are ways to write compatible code: https://wiki.python.org/moin/PortingPythonToPy3k
+* If you find yourself needing to work with Python 2 and 3, there are ways to write compatible code:
+
+https://wiki.python.org/moin/PortingPythonToPy3k
 
 * We will cover that more later in the program. Also: a short intro to the differences you really need to know about up front later this session.
 
@@ -309,9 +322,7 @@ Having some facility on the command line is important
 We won't cover this much in class, so if you are not comfortable,
 please bone up at home.
 
-I suggest running through the **cli** tutorial at "learn code the hard way":
-
-http://cli.learncodethehardway.org/book/
+We have some resources here: `PythonResources--command line `_
 
 **Windows:**
 
@@ -321,38 +332,102 @@ Windows provides the "DOS" command line, which is OK, but pretty old and limited
 
 If you are comfortable with either of these -- go for it.
 
-If not, you can use the "git Bash" shell -- which is much like the bash shell on OS-X and Linux.
+If not, you can use the "git Bash" shell -- which is much like the bash shell on OS-X and Linux. Or, on Windows 10, look into the "bash shell for Windows" otherwise known as the "Linux system" - - more info here: `PythonResources--Windows Bash  `_
 
-Your Interpreter
-----------------
 
-Python comes with a built-in interpreter.
+LAB: Getting set up
+-------------------
+
+Before we move on -- we need to get all of us on the same page, with the tools we need for class.
 
-You see it when you type ``python`` at the command line:
+You will find instructions for how to get python, etc, up and running on your machine here:
 
-.. code-block:: python
+**Windows:**
+
+http://uwpce-pythoncert.github.io/PythonResources/Installing/python_for_windows.html
+
+**OS-X:**
+
+http://uwpce-pythoncert.github.io/PythonResources/Installing/python_for_mac.html
+
+**Linux:**
+
+http://uwpce-pythoncert.github.io/PythonResources/Installing/python_for_linux.html
+
+We'll run through some of that together.
+
+If you already have a working environment, please feel free to help your neighbor or look at the Python Resources pages, particularly reviewing/learning the shell and git.
+
+http://uwpce-pythoncert.github.io/PythonResources
+
+Our Class Environment
+---------------------
+
+We are going to work from a common environment in this class.
+
+We will take the time here in class to get this going.
+
+This helps to ensure that you will be able to work.
+
+
+Step 1: Python 3
+------------------
+
+.. rst-class:: medium
+
+  Do you already have this??
+
+.. code-block:: bash
 
   $ python
-  Python 3.5.0 (v3.5.0:374f501f4567, Sep 12 2015, 11:00:19)
+  Python 3.6.1 (v3.5.2:4def2a2901a5, Jun 26 2016, 10:47:25)
   [GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
   Type "help", "copyright", "credits" or "license" for more information.
+  >>>
 
-That last thing you see, ``>>>`` is the "Python prompt".
+If not, or you have an older version -- let's install it!
 
-This is where you type code.
+If you're all ready to go -- take this time to get started on a tutorial:
 
-LAB: Getting set up
--------------------
+http://uwpce-pythoncert.github.io/PythonResources/GeneralPython/learning.html#getting-started-tutorials
 
-Before we move on -- we need to get all of us on the same page, with the tools we need for class.
 
-You will find instructions for how to get python, etc, up and running on your machine here:
+Step 2: Pip
+-----------
+
+Python comes with quite a bit ("batteries included").
+
+Sometimes you need a bit more.
+
+Pip allows you to install Python packages to expand your system.
+
+The previous instructions include pip as well - make sure it's working.
+
+Once you've installed pip, you use it to install Python packages by name:
+
+.. code-block:: bash
+
+    $ python -m pip install foobar
+    ...
+
+To find packages (and their proper names), you can search the python
+package index (PyPI):
+
+https://pypi.python.org/pypi
 
-**Windows:** ::ref:`python_for_windows`
 
-**OS-X:** ::ref:`python_for_mac`
+Step 3: Install iPython
+------------------------
+
+As this is an intro class, we are going to use almost entirely features
+of the standard library. But there are a couple things you may want:
+
+**iPython** is an "enhanced python shell" -- it make s it easier to work with python interactively.
+
+.. code-block:: bash
+
+  $ python -m pip install ipython[all]
 
-**Linux:** ::ref:`python_for_linux`
 
 Python in the Interpreter
 -------------------------
@@ -429,8 +504,7 @@ Your Editor
 
 Typing code in an interpreter is great for exploring.
 
-But for anything "real", you'll want to save the work you are doing in a more permanent
-fashion.
+But for anything "real", you'll want to save the work you are doing in a more permanent fashion.
 
 This is where an Editor fits in.
 
@@ -442,7 +516,7 @@ MS Word is **not** a text editor.
 
 Nor is *TextEdit* on a Mac.
 
-``Notepad`` is a text editor -- but a crappy one.
+``Notepad`` on Windows is a text editor -- but a crappy one.
 
 You need a real "programmers text editor"
 
@@ -451,7 +525,6 @@ characters hidden behind the scenes.
 
 .. nextslide:: Minimum Requirements
 
-
 At a minimum, your editor should have:
 
 .. rst-class:: build
@@ -465,16 +538,19 @@ In addition, great features to add include:
 
 * Tab completion
 * Code linting
-* Jump-to-definition
 
 Have an editor that does all this? Feel free to use it.
 
-If not, I suggest ``SublimeText``:
-
-http://www.sublimetext.com/
+If not, I suggest ``SublimeText``: http://www.sublimetext.com/
 
 (Use version 3, even though it's "beta")
 
+http://uwpce-pythoncert.github.io/PythonResources/DevEnvironment/sublime_as_ide.html
+
+"Atom" is another good open source option.
+
+And, of course, vi or Emacs on Linux, if you are familiar with those.
+
 Why No IDE?
 -----------
 
@@ -495,83 +571,6 @@ Particularly when you are first learning, you don't want too much done for you.
 YAGNI
 
 
-Setting Up Your Environment
-===========================
-
-.. rst-class:: centered large
-
-Shared setup means reduced complications.
-
-
-Our Class Environment
----------------------
-
-We are going to work from a common environment in this class.
-
-We will take the time here in class to get this going.
-
-This helps to ensure that you will be able to work.
-
-
-Step 1: Python 3
-------------------
-
-.. rst-class:: large
-
-Do you already have this??
-
-.. code-block:: bash
-
-
-  $ python
-  Python 3.5.0 (v3.5.0:374f501f4567, Sep 12 2015, 11:00:19)
-  [GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
-  Type "help", "copyright", "credits" or "license" for more information.
-  >>> ^D
-
-If not:
-
- * `For OS X  <./supplements/python_for_mac.html>`_
-
- * `For Linux  <./supplements/python_for_linux.html>`_
-
- * `For Windows  <./supplements/python_for_windows.html>`_
-
-Step 2: Pip
------------
-
-Python comes with quite a bit ("batteries included").
-
-Sometimes you need a bit more.
-
-Pip allows you to install Python packages to expand your system.
-
-The previous instructions include pip as well - make sure it's working.
-
-Once you've installed pip, you use it to install Python packages by name:
-
-.. code-block:: bash
-
-    $ python -m pip install foobar
-    ...
-
-To find packages (and their proper names), you can search the python
-package index (PyPI):
-
-https://pypi.python.org/pypi
-
-
-Step 3: Install iPython
-------------------------
-
-As this is an intro class, we are going to use almost entirely features
-of standard library. But there are a couple things you may want:
-
-**iPython** is an "enhanced python shell" -- it make s it easier to work with python interatively.
-
-.. code-block:: bash
-
-  $ python -m pip install ipython
 
 Introduction to iPython
 =======================
@@ -590,8 +589,8 @@ Specifically, you'll want to pay attention to the information about
 `Using iPython for Interactive Work`_.
 
 .. _iPython: http://ipython.org
-.. _official documentation: http://ipython.org/ipython-doc/stable/index.html
-.. _Using iPython for Interactive Work: http://ipython.org/ipython-doc/stable/interactive/index.html
+.. _official documentation: http://ipython.readthedocs.io/en/stable/
+.. _Using iPython for Interactive Work: http://ipython.readthedocs.io/en/stable/interactive/index.html
 
 .. ifslides::
 
@@ -680,7 +679,19 @@ To run it, you have a couple options:
 
   $ python the_name_of_the_script.py
 
-2) run ``iPython``, and run it from within iPython with the ``run`` command
+2) On *nix (linux, OS-X, Windows bash), you can make the file "executable"::
+
+       chmod +x the_file.py
+
+   And make sur it has a "shebang" line at the top::
+
+       #!/usr/bin/env python
+
+   Then you can run it directly::
+
+       ./the_file.py
+
+3) run ``iPython``, and run it from within iPython with the ``run`` command
 
 .. code-block:: ipython
 
@@ -700,7 +711,7 @@ Basic Python Syntax
 .. rst-class:: center mlarge
 
 
-| Values, Types, and Symbols
+| Values, Types, and Names
 |
 | Expressions and Statements
 
@@ -710,15 +721,13 @@ Values
 
 All of programming is really about manipulating values.
 
-.. rst-class:: build
-
-* Values are pieces of unnamed data: ``42, 'Hello, world',``
+* Values are pieces of unnamed data: ``42``, ``'Hello, world'``
 
 * In Python, all values are objects
 
   - Try ``dir(42)``  - lots going on behind the curtain!
 
-* Every value belongs to a type
+* Every value has a type
 
   - Try ``type(42)`` - the type of a value determines what it can do
 
@@ -745,8 +754,10 @@ Boolean values:
   -  ``True``
   -  ``False``
 
-(There are intricacies to all of these that we'll get into later)
+The nothing object:
+  - ``None``
 
+(There are intricacies to all of these that we'll get into later)
 
 Code structure
 --------------
@@ -787,7 +798,7 @@ It's kind of obvious, but handy when playing with code:
 
 .. code-block:: ipython
 
-    In [1]: print ("something")
+    In [1]: print("something")
     something
 
 You can print multiple things:
@@ -891,6 +902,7 @@ Make sure your editor is set to use spaces only --
 
 Even when you hit the  key
 
+[Python itself allows any number of spaces (and tabs), but you are just going to confuse yourself and others if you do anything else]
 
 Expressions
 ------------
@@ -906,8 +918,7 @@ An *expression* is made up of values and operators.
 * Integer vs. float arithmetic
 
   * (Python 3 smooths this out)
-  * Always use ``/`` when you want float results, ``//`` when you want
-    floored (integer) results
+  * Always use ``/`` when you want division with float results, ``//`` when you want floored (integer) results (no remainder).
 
 * Type conversions
 
@@ -922,31 +933,31 @@ An *expression* is made up of values and operators.
         [demo]
 
 
-Symbols
+Names
 -------
 
-Symbols are how we give names to values (objects).
+Names are how we give names to values (objects) -- hence "names"
 
 .. rst-class:: build
 
-* Symbols must begin with an underscore or letter
-* Symbols can contain any number of underscores, letters and numbers
+* Names must begin with an underscore or letter
+* Names can contain any number of underscores, letters and numbers
 
-  * this_is_a_symbol
+  * this_is_a_name
   * this_is_2
   * _AsIsThis
   * 1butThisIsNot
   * nor-is-this
 
-* Symbols don't have a type; values do
+* Names don't have a type; values do
 
   * This is why python is "Dynamic"
 
 
-Symbols and Type
+Names and Type
 ----------------
 
-Evaluating the type of a *symbol* will return the type of the *value* to which
+Evaluating the type of a *name* will return the type of the *value* to which
 it is bound.
 
 .. code-block:: ipython
@@ -969,11 +980,12 @@ it is bound.
     In [26]: type(a)
     Out[26]: float
 
+*wait!* a has a different type?!? -- yes, because it's the type of teh value: "3.14", names don't actually have a type, they can refer to any type.
 
 Assignment
 ----------
 
-A *symbol* is **bound** to a *value* with the assignment operator: ``=``
+A *name* is **bound** to a *value* with the assignment operator: ``=``
 
 .. rst-class:: build
 
@@ -981,7 +993,6 @@ A *symbol* is **bound** to a *value* with the assignment operator: ``=``
 * A value can have many names (or none!)
 * Assignment is a statement, it returns no value
 
-
 .. nextslide::
 
 Evaluating the name will return the value to which it is bound
@@ -1008,7 +1019,7 @@ Variables?
 
 .. rst-class:: build
 
-* In most languages, what I'm calling symbols, or names, are called "variables".
+* In most languages, what I'm calling names are called "variables".
 
 * In fact, I'll probably call them variables in this class.
 
@@ -1094,12 +1105,12 @@ Using this feature, we can swap values between two names in one statement:
     In [55]: j
     Out[55]: 4
 
-Multiple assignment and symbol swapping can be very useful in certain contexts
+Multiple assignment and name swapping can be very useful in certain contexts
 
 Deleting
 --------
 
-You can't actually delete anything in python...
+You can't actually directly delete values in python...
 
 ``del`` only deletes a name (or "unbinds" the name...)
 
@@ -1150,7 +1161,7 @@ Identity
 Every value in Python is an object.
 
 Every object is unique and has a unique *identity*, which you can inspect with
-the ``id`` *builtin*:
+the ``id`` *builtin* function:
 
 .. code-block:: ipython
 
@@ -1169,7 +1180,7 @@ the ``id`` *builtin*:
 Testing Identity
 ----------------
 
-You can find out if the values bound to two different symbols are the **same
+You can find out if the values bound to two different names are the **same
 object** using the ``is`` operator:
 
 .. code-block:: ipython
@@ -1192,6 +1203,7 @@ object** using the ``is`` operator:
 
         [demo]
 
+**NOTE:** checking the id of an object, or using "is" to check if two objects are the same is rarely used except for debugging and understanding what's going on under the hood. They are not used regularly in production code.
 
 Equality
 --------
@@ -1212,12 +1224,34 @@ You can test for the equality of certain values with the ``==`` operator
     In [81]: val1 == val3
     Out[84]: False
 
+A string is never equal to a number!
+
 .. ifslides::
 
     .. rst-class:: centered
 
         [demo]
 
+For the numerical values, there is also::
+
+    >, <, >=, <=, !=
+
+Singletons
+----------
+
+Python has three "singletons" -- value fro which there is only one instance:
+
+  ``True``, ``False``, and ``None``
+
+To check if a name is bound to one of these, you use ``is``::
+
+    a is True
+
+    b is False
+
+    x is None
+
+Note that in contrast to english -- "is" is asking a question, not making an assertion -- ``a is True`` means "is a the True value?"
 
 Operator Precedence
 -------------------
@@ -1228,8 +1262,11 @@ Operator Precedence determines what evaluates first:
 
     4 + 3 * 5 != (4 + 3) * 5
 
-To force statements to be evaluated out of order, use parentheses.
+To force statements to be evaluated out of order, use parentheses -- expressions in parentheses are always evaluated first:
+
+   (4 + 3) * 5 != 4 + (3 * 5)
 
+Python follows the "usual" rules of algebra.
 
 Python Operator Precedence
 --------------------------
@@ -1291,7 +1328,7 @@ String Literals
 
 A "string" is a chunk of text.
 
-You define a ``string`` value by writing a string *literal*:
+You define a "string" value by writing a string *literal*:
 
 .. code-block:: ipython
 
@@ -1324,6 +1361,10 @@ You define a ``string`` value by writing a string *literal*:
     In [7]: r'a "raw" string, the \n comes through as a \n'
     Out[7]: 'a "raw" string, the \\n comes through as a \\n'
 
+Python3 strings are fully support Unicode, which means that it can suport literally all the languages in the world (and then some -- Klingon, anyone?)
+
+Because Unicode is native, you can get very far without even thinking about it. Anything you can type in your editor will work fine.
+
 
 Keywords
 --------
@@ -1332,7 +1373,7 @@ Python defines a number of **keywords**
 
 These are language constructs.
 
-You *cannot* use these words as symbols.
+You *cannot* use these words as names.
 
 ::
 
@@ -1347,7 +1388,7 @@ You *cannot* use these words as symbols.
 .. nextslide::
 
 
-If you try to use any of the keywords as symbols, you will cause a
+If you try to use any of the keywords as names, you will cause a
 ``SyntaxError``:
 
 .. code-block:: ipython
@@ -1372,7 +1413,7 @@ If you try to use any of the keywords as symbols, you will cause a
 __builtins__
 ------------
 
-Python also has a number of pre-bound symbols, called **builtins**
+Python also has a number of pre-bound names, called **builtins**
 
 Try this:
 
@@ -1386,14 +1427,13 @@ Try this:
      'BaseException',
      'BufferError',
      ...
-     'unicode',
      'vars',
      'xrange',
      'zip']
 
 .. nextslide::
 
-You are free to rebind these symbols:
+You are free to rebind these names:
 
 .. code-block:: ipython
 
@@ -1410,7 +1450,7 @@ You are free to rebind these symbols:
 
     TypeError: 'str' object is not callable
 
-In general, this is a **BAD IDEA**.
+In general, this is a **BAD IDEA** -- hopefully your editor will warn you.
 
 
 Exceptions
@@ -1424,9 +1464,12 @@ There are several exceptions that you are likely to see a lot of:
 
 .. rst-class:: build
 
-* ``NameError``: indicates that you have tried to use a symbol that is not bound to a value.
+* ``NameError``: indicates that you have tried to use a name that is not bound to a value.
+
 * ``TypeError``: indicates that you have tried to use the wrong kind of object for an operation.
+
 * ``SyntaxError``: indicates that you have mis-typed something.
+
 * ``AttributeError``: indicates that you have tried to access an attribute or
   method that an object does not have (this often means you have a different
   type of object than you expect)
@@ -1444,7 +1487,7 @@ A function is a self-contained chunk of code
 You use them when you need the same code to run multiple times,
 or in multiple parts of the program.
 
-(DRY)
+(DRY) -- "Don't Repeat Yourself"
 
 Or just to keep the code clean
 
@@ -1452,22 +1495,23 @@ Functions can take and return information
 
 .. nextslide::
 
-Minimal Function does nothing
+The minimal Function has at least one statement
 
 .. code-block:: python
 
-    def ():
-        
+    def a_name():
+        a_statement
 
 .. nextslide::
 
-Pass Statement (Note the indentation!)
+Pass Statement does nothing (Note the indentation!)
 
 .. code-block:: python
 
     def minimal():
         pass
 
+This, or course, is not useful -- you will generally have multiple statements in a function.
 
 Functions: ``def``
 ------------------
@@ -1479,6 +1523,7 @@ Functions: ``def``
   * it is executed
   * it creates a local name
   * it does *not* return a value
+
 .. nextslide::
 
 function defs must be executed before the functions can be called:
@@ -1512,17 +1557,20 @@ You **call** a function using the function call operator (parens):
 
     In [2]: type(simple)
     Out[2]: function
+
     In [3]: simple
     Out[3]: 
+
     In [4]: simple()
     I am a simple function
 
 Calling a function is how you run the code in that function.
 
+
 Functions: Call Stack
 ---------------------
 
-functions call functions -- this makes an execution stack -- that's all a trace back is
+functions can call other functions -- this makes an execution stack -- that's what a "trace back" is:
 
 .. code-block:: ipython
 
@@ -1567,7 +1615,7 @@ Functions: Tracebacks
 
     ZeroDivisionError: integer division or modulo by zero
 
-
+The error occurred in the ``doer`` function -- but the traceback shows you where that was called from. In a more complex system, this can be VERY useful -- learn to read tracebacks!
 
 Functions: ``return``
 ---------------------
@@ -1583,7 +1631,7 @@ This is actually the simplest possible function:
 
 .. nextslide::
 
-if you don't explicilty put ``return``  there, Python will:
+if you don't explicitly put ``return``  there, Python will return None for you:
 
 .. code-block:: ipython
 
@@ -1626,7 +1674,7 @@ However, functions *can* return multiple results:
 .. code-block:: ipython
 
     In [16]: def fun():
-       ....:     return (1, 2, 3)
+       ....:     return 1, 2, 3
        ....:
     In [17]: fun()
     Out[17]: (1, 2, 3)
@@ -1638,7 +1686,7 @@ Remember multiple assignment?
 
 .. code-block:: ipython
 
-    In [18]: x,y,z = fun()
+    In [18]: x, y, z = fun()
     In [19]: x
     Out[19]: 1
     In [20]: y
@@ -1674,7 +1722,20 @@ When you call a function, you pass values to the function parameters as
     In [23]: fun(3, 4, 5)
     3 4 5 12
 
-The values you pass in are *bound* to the symbols inside the function and used.
+The values you pass in are *bound* to the names inside the function and used.
+
+The name used outside the object is separete from the name used inside teh function:
+
+.. code-block:: python
+
+    x = 5
+
+    def fun(a):
+        print(a)
+
+    fun(x)
+
+The "a" printed inside the function is the *same* object as the "x" outside the function.
 
 The ``if`` Statement
 ---------------------
@@ -1683,7 +1744,7 @@ In order to do anything interesting at all, you need to be able to make a decisi
 
 .. nextslide::
 
-.. code-block:: python
+.. code-block:: ipython
 
     In [12]: def test(a):
        ....:     if a == 5:
@@ -1729,7 +1790,7 @@ Python 2-3 Differences
 
 Much of the example code you'll find online is Python2, rather than Python3
 
-For the most part, they are the same -- so you can sue those examples to learn from.
+For the most part, they are the same -- so you can use those examples to learn from.
 
 There are a lot of subtle differences that you don't need to concern yourself with just yet.
 
@@ -1738,7 +1799,7 @@ But a couple that you'll need to know right off the bat:
 print()
 -------
 
-In python2, ``print`` is a "statement", rather than a function. That means it didn't require parenthes around what you want printed::
+In python2, ``print`` is a "statement", rather than a function. That means it didn't require parentheses around what you want printed::
 
   print something, something_else
 
@@ -1759,7 +1820,7 @@ So -- if you get this error, simply add the parentheses::
 
 .. nextslide:: division
 
-In python 3, the divsion operator is "smart" when you divide integers::
+In python 3, the division operator is "smart" when you divide integers::
 
   In [17]: 1 / 2
   Out[17]: 0.5
@@ -1807,7 +1868,7 @@ Task 1
 Make sure you have the basics of command line usage down:
 
 Work through the supplemental tutorials on setting up your
-Command Line (::ref:`shell_customization`) for good development support.
+Command Line (http://uwpce-pythoncert.github.io/PythonResources/DevEnvironment/shell.html) for good development support.
 
 Make sure you've got your editor set up productively -- at the very very
 least, make sure it does Python indentation and syntax coloring well.
@@ -1818,7 +1879,7 @@ least, make sure it does Python indentation and syntax coloring well.
 
 If you are using SublimeText, here are some notes to make it super-nifty:
 
-::ref:`sublime_as_ide`
+http://uwpce-pythoncert.github.io/PythonResources/DevEnvironment/sublime_as_ide.html
 
 At the end, your editor should support tab completion and pep8 and pyflakes
 linting.
@@ -1877,22 +1938,23 @@ Every one of you has a different backgrond and learning style.
 
 So take a bit of time to figure out which resource works for you.
 
-:ref:`python_learning_resources` provides some options. Do look it over.
+http://uwpce-pythoncert.github.io/PythonResources/GeneralPython/learning.html
+
+provides some options. Do look it over.
 
 But here are few to get you started this week:
 
-*Think Python:* Chapters 1–7 (http://greenteapress.com/thinkpython/)
+*Think Python:* Chapters 1–7 (http://greenteapress.com/wp/think-python-2e/)
 
 *Dive Into Python:* Chapters 1–2 (http://www.diveintopython3.net/)
 
 *LPTHW:* ex. 1–10, 18-21 (http://learnpythonthehardway.org/book/)
-  **NOTE:** LPTHW is python 2 -- you will need to add parentheses to all yoru print calls!
 
-Or follow this excellent introductory tutorial:
+*NOTE:* LPTHW is python 2 -- you will need to add parentheses to all your print calls!
 
-http://pyvideo.org/video/1850/a-hands-on-introduction-to-python-for-beginning-p
+Or follow this excellent introductory tutorial:
 
-(also python2 -- so same thing with the print function...)
+https://www.youtube.com/watch?v=MirG-vJOg04
 
 You should be comfortable with working with variables, numbers, strings, and basic functions.
 
@@ -1913,7 +1975,7 @@ Next Class
 
 Next week, we'll:
 
- * get set up with git
+ * get set up with git and gitHub
  * Some more basic Python
  * More on Functions
  * Boolean Expressions
@@ -1925,7 +1987,7 @@ Office Hours
 
 We will have office hours on either Saturday or Sunday from 10:00 to noon.
 
-Preferences?  
+Preferences?
 
 Locations?
 
diff --git a/slides_sources/source/session02.rst b/slides_sources/source/session02.rst
index 901dfd48..a5199d68 100644
--- a/slides_sources/source/session02.rst
+++ b/slides_sources/source/session02.rst
@@ -25,15 +25,15 @@ Lightning Talks Today:
 
 .. rst-class: medium
 
+
 |
+| David E Tobey
 |
-| Brendan Fogarty
-|
-| Bruce Bauman
-|
-| Michelle Yu
+| Sharmila Muralidharan
 |
+| Shu A Latif
 |
+| Spencer G McGhin
 
 Class Outline
 -------------
@@ -80,7 +80,7 @@ What is git?
 
     That last one is a bit tricky, and is not necessary to understand right out of the gate. When you are ready, you can look at this supplement to gain a better understanding:
 
-    :ref:`supplement_git_states`
+    :ref: http://uwpce-pythoncert.github.io/PythonResources/DevEnvironment/git_overview.html
 
 Setting up git
 --------------
@@ -95,8 +95,16 @@ You should have git installed on your machine and accessible from the command li
 Editor
 ------
 
-You will never have to use an editor with git for anything extensive, so a simple editor is fine. Unfortunately, the default, VI, is not intuitive to new users. So, unless you already know vi, you should set up a different editor.
-Nano is a straight-forward, simple editor, available out of the box on Macs and Linux boxes, but needs to be installed on Windows (or you can use sublime or Notepad++ as shown in link below). To install nano on Windows: :ref:`supplement_install_nano_win`
+* git needs an editor occasionally
+* default is VI, which is not very intuitive to non-Unix Geeks
+* Nano is simple, easy solution for Macs and Linux
+* Nano no longer available for windows, use Sublime or Notepad++
+
+
+For Windows users:
+ http://uwpce-pythoncert.github.io/PythonResources/Installing/git_editor_windows.html
+
+.. nextslide::
 
 Once you have chosen/installed an editor, configure git to use it:
 
@@ -120,7 +128,7 @@ A repository is just a collection of files that 'belong together'.
 Since ``git`` is a *distributed* versioning system, there is no **central**
 repository that serves as the one to rule them all. This simply means that all repositories should look the same.
 
-However, to keep things sane, there is generally one repository chosen that users check with for changes, for us this is GitHub.
+However, to keep things sane, there is generally one "central" repository chosen that users check with for changes, for us this is GitHub.
 
 
 Working with Remotes
@@ -136,11 +144,12 @@ With git, you work with *local* repositories and *remotes* that they are connect
     .. code-block:: bash
 
         $ git remote -v
-        origin  https://github.com/UWPCE-PythonCert/IntroPython2015.git (fetch)
-        origin  https://github.com/UWPCE-PythonCert/IntroPython2015.git (push)
+        origin  https://github.com/UWPCE-PythonCert/IntroPython2016.git (fetch)
+        origin  https://github.com/UWPCE-PythonCert/IntroPython2016.git (push)
 
     This shows that the local repo on my machine *originated* from the one in
-    the UWPCE-PythonCert gitHub account (don't worry that it shows it twice, they should be the same)
+    the UWPCE-PythonCert gitHub account (it shows up twice, because I there is
+    a shortcut for both fetch from and push to this remote)
 
 .. nextslide::
 
@@ -163,21 +172,42 @@ Our class materials reside in a repository on *Github* in the *UWPCE-PythonCert*
     :width: 50%
     :class: center
 
-We will do a live demo of setting up a machine. Please follow along.
+.. nextslide::
+
+Note that this is not the same repository as the class materials.
+
+It will be a repository that is created just for this class, and will be called IntroPython*quarter*.
+
+In examples below it is called IntroToPython, so replace that in your head with the name of this year's repository. :)
+
+We will create this repository now.
+
+.. nextslide::
+
+This new repository will include examples and we will add relevant materials (and exercise solutions) to it throughout the quarter.
+
+There will be a folder called students at the top level, and everyone will create their own directory within it.
+
+So, everyone will commit to this repository, and everyone will have access to everyone's code.
+
+This will make it easier to collaborate.
+
+We will do a live demo of setting up a machine now.
 
 .. nextslide::
 
 We will now create a fork of the class repository from the ``UWPCE-PythonCert``
 account on GitHub into your personal account. This is done on the GitHub website.
 
+Let's pause now to let you all create a gitHub account if you don't have one already.
+
 .. figure:: /_static/remotes_fork.png
     :width: 50%
     :class: center
 
 .. nextslide::
 
-The next step is to make a *clone* of your fork on your own computer, which means that
-**your fork** in github is the *origin* (Demo):
+The next step is to make a *clone* of your fork on your own computer, which means that **your fork** in github is the *origin* (Demo):
 
 .. figure:: /_static/remotes_clone.png
     :width: 50%
@@ -185,21 +215,25 @@ The next step is to make a *clone* of your fork on your own computer, which mean
 
 .. nextslide::
 
-We will now set up our individual folders and include a README in this folder. In your terminal, cd
-into the students directory in the directory created when we made the clone, which may or may not be called IntroPython2015.
+We will now set up our individual folders and include a README in this folder.
+
 
 .. rst-class:: build
 .. container::
 
     .. code-block:: bash
 
-        $ cd IntroPython2015/students
+        $ cd IntroPythonXXXX
         $ git status
 
     .. code-block:: bash
 
         $ git pull origin master
 
+    .. code-block:: bash
+
+        $ cd students
+
     .. code-block:: bash
 
         $ mkdir maria_mckinley
@@ -235,17 +269,30 @@ into the students directory in the directory created when we made the clone, whi
 
         $ git commit -m 'added a readme file'
 
-    Push your changes:
 
-    .. code-block:: bash
+.. nextslide::
+
+Push your changes:
 
-        $ git push origin master
+  .. code-block:: bash
+
+      $ git push origin master
+
+  origin is the default name given by git refering to the server you cloned
+  (in this case your github repository)
+
+  master is the branch that you are currently pushing to that server
+
+  Go onto GitHub, and make a pull request!
+
+  (This will be a pull request from a fork rather than from a branch)
+
+  https://help.github.com/articles/creating-a-pull-request-from-a-fork/
 
-    Go onto GitHub, and make a pull request!
 
 .. nextslide::
 
-You've pushed your own changes to that fork, and then issued pull requests to have that worked merged back to the ``UWPCE-PythonCert`` original.
+You've pushed your own changes to that fork, and then issued pull requests to have that work merged back to the ``UWPCE-PythonCert`` original.
 
 .. rst-class:: build
 .. container::
@@ -260,16 +307,13 @@ You've pushed your own changes to that fork, and then issued pull requests to ha
 You can add *remotes* at will, to connect your *local* repository to other
 copies of it in different remote locations.
 
-When you add a *remote* (existing git repository), it creates a directory with the name of the repository at the top level.
-
 .. rst-class:: build
 .. container::
 
     This allows you to grab changes made to the repository in these other
     locations.
 
-    For our class, we will add an *upstream* remote to our local copy that points
-    to the original copy of the material in the ``UWPCE-PythonCert`` account.
+    For our class, we will add an *upstream* remote to our local copy that points to the original copy of the material in the ``UWPCE-PythonCert`` account, and we will call it, appropriately, "upstream"
 
     .. code-block:: bash
 
@@ -321,20 +365,16 @@ Start by making sure you are on your own master branch:
 
     $ git checkout master
 
-This is **really really** important.  Take the time to ensure you are where you
-think you are, iow, not on a remote. Use git status to find out where you are, if necesary.
+This is **really really** important.  Take the time to ensure you are where you think you are, iow, not on a remote. Use git status to find out where you are, if necesary.
 
 .. nextslide:: Merging Upstream Changes
 
-Then, fetch the upstream master branch and merge it into your master:
+Then, fetch the upstream master branch and merge it into your master.
+You can do this in one step with:
 
 .. code-block:: bash
 
-  $ git fetch upstream master
-  From https://github.com/UWPCE-PythonCert/IntroPython2015
-   * branch            master     -> FETCH_HEAD
-
-  $ git merge upstream/master
+  $ git pull upstream master
   Updating 3239de7..9ddbdbb
   Fast-forward
    Examples/README.rst              |  4 ++++
@@ -342,15 +382,10 @@ Then, fetch the upstream master branch and merge it into your master:
    create mode 100644 Examples/README.rst
   ...
 
-NOTE: you can do that in one step with:
-
-.. code-block:: bash
-
-  $ git pull upstream master
 
 .. nextslide:: Pushing to Origin
 
-Now all the changes from *upstream* are present in your local clone. 
+Now all the changes from *upstream* are present in your local clone.
 You should do this pull everytime you start to work on code.
 
 In order to preserve them in your fork on GitHub, you'll have to push:
@@ -372,12 +407,18 @@ In order to preserve them in your fork on GitHub, you'll have to push:
 
 You can incorporate this into your daily workflow: ::
 
+    [make sure you are on correct branch]
     $ git checkout master
+    [get any changes from class repository]
     $ git pull upstream master
-    $ git push
-    [do some work]
-    $ git commit -a 'I wrote some Python.'
+    [make sure you are in your student directory, do work]
+    [verify you are happy with changes]
+    $ git status
+    [add your changes to what will be committed]
+    $ git add .
     [add a good commit message]
+    $ git commit -m 'I wrote some Python.'
+    [push your changes to your remote github account]
     $ git push
     [make a pull request on the GitHub website]
 
@@ -385,13 +426,13 @@ You can incorporate this into your daily workflow: ::
 .. nextslide:: Note
 
 Because of the way we have set up the class, you will be able
-to see all work submitted to us from everyone in the class in 
+to see all work submitted to us from everyone in the class in
 the students directory on your machine. This is not a bad thing.
-And the files tend to be small. 
+And the files tend to be small.
 
 We encourage sharing of knowledge in this class. Helping your
-fellow students will also help you to better understand. Share 
-your code, and get use to giving/receiving feedback on how to 
+fellow students will also help you to better understand. Share
+your code, and get use to giving/receiving feedback on how to
 improve your code, if you are not already.
 
 
@@ -447,7 +488,7 @@ And when you want us to take a look, you can go to gitHub and do a "Pull Request
 Committing your code
 --------------------
 
-Commit early and often. 
+Commit early and often.
 
 
 Lightning Talk:
@@ -455,7 +496,7 @@ Lightning Talk:
 
 .. rst-class:: center medium
 
-Brendan Fogarty
+David E Tobey
 
 
 Beyond Printing
@@ -482,13 +523,13 @@ Making a Decision
 .. code-block:: python
 
     if a:
-        print 'a'
+        print('a')
     elif b:
-        print 'b'
+        print('b')
     elif c:
-        print 'c'
+        print('c')
     else:
-        print 'that was unexpected'
+        print('that was unexpected')
 
 
 .. nextslide:: if
@@ -498,15 +539,15 @@ What's the difference between these two?
 .. code-block:: python
 
     if a:
-        print 'a'
+        print('a')
     elif b:
-        print 'b'
+        print('b')
 
     ## versus...
     if a:
-        print 'a'
+        print('a')
     if b:
-        print 'b'
+        print('b')
 
 
 
@@ -562,7 +603,8 @@ When you need to do something to all the objects in a sequence
     5
 
 
-.. nextslide:: ``range()`` and for
+``range()`` and for
+-------------------
 
 ``range`` builds sequences of numbers automatically
 
@@ -606,7 +648,7 @@ Lightning Talk:
 
 .. rst-class:: center medium
 
-Bruce Bauman
+Sharmila Muralidharan
 
 
 More on Functions
@@ -909,8 +951,7 @@ Recursion is especially useful for a particular set of problems.
 
 For example, take the case of the *factorial* function.
 
-In mathematics, the *factorial* of an integer is the result of multiplying that
-integer by every integer smaller than it down to 1.
+In mathematics, the *factorial* of an integer is the result of multiplying that integer by every integer smaller than it down to 1.
 
 ::
 
@@ -963,7 +1004,7 @@ Lightning Talk:
 
 .. rst-class:: center medium
 
-Michelle Yu
+Shu A Latif
 
 
 Boolean Expressions
@@ -1198,6 +1239,14 @@ And you can even do math with them (though it's a bit odd to do so):
     (demo)
 
 
+Lightning Talk:
+---------------
+
+.. rst-class:: center medium
+
+Spencer G McGhin
+
+
 LAB: Booleans
 =============
 
@@ -1209,7 +1258,7 @@ LAB: Booleans
 
     Experiment with ``locals`` by adding this statement one of the functions you wrote today::
 
-        print locals()
+        print(locals())
 
 
 Code Structure, Modules, and Namespaces
@@ -1245,7 +1294,7 @@ You can put a one-liner after the colon:
 .. code-block:: ipython
 
     In [167]: x = 12
-    In [168]: if x > 4: print x
+    In [168]: if x > 4: print(x)
     12
 
 But this should only be done if it makes your code **more** readable.
@@ -1390,8 +1439,8 @@ It must be explicitly reloaded to be re-run
 
 .. code-block:: python
 
-    import modulename
-    reload(modulename)
+    import importlib
+    importlib.reload(modulename)
 
 .. ifslides::
 
@@ -1414,7 +1463,7 @@ There are a few ways to do this:
 * ``In [149]: run hello.py``     -- at the IPython prompt -- running a module brings its names into the interactive namespace
 
 
-.. nextslide:: Running a Module
+.. nextslide
 
 Like importing, running a module executes all statements at the module level.
 
@@ -1492,9 +1541,9 @@ Experiment with importing different ways:
 .. code-block:: python
 
     import sys
-    print sys.path
+    print(sys.path)
     import os
-    print os.path
+    print(os.path)
 
 You wouldn't want to import * those!
 
@@ -1516,9 +1565,12 @@ Next Class
 * Strings and String Formatting
 
 * Lightning talks by:
-  - Eric Rosko
-  - Michael Waddle
-  - Robert Stevens Alford
+
+  - Beatrice He
+  - Bradley I Baumel
+  - Jerry Bearer
+  - Sheree Pena
+
 
 Office hours: Sunday 10:00 -- 12:00
 
diff --git a/slides_sources/source/session03.rst b/slides_sources/source/session03.rst
index 0f13df27..bd58f2ff 100644
--- a/slides_sources/source/session03.rst
+++ b/slides_sources/source/session03.rst
@@ -45,11 +45,11 @@ Lightning Talks Today:
 
 .. rst-class:: mlarge
 
-   Eric Rosko
-
-   Michael Waddle
-
-   Robert Alford
+|
+| Beatrice He
+| Bradley I Baumel
+| Jerry Bearer
+| Sheree Pena
 
 
 Sequences
@@ -92,7 +92,8 @@ There are eight builtin types in Python that are *sequences*:
 * array.array
 * range object (almost)
 
-For this class, you won't see much beyond string, lists, and tuples -- the rest are pretty special purpose.
+For this class, you won't see much beyond string, lists, and tuples --
+the rest are pretty special purpose.
 
 But what we learn today applies to all sequences (with minor caveats)
 
@@ -214,7 +215,7 @@ Why is the "first" item indexed with **zero**?
 
 Why is the last item in the slice **not** included?
 
-Because these lead to some nifty properties::
+*Because* these lead to some nifty properties::
 
     len(seq[a:b]) == b-a
 
@@ -269,7 +270,7 @@ Indexing past the end of a sequence will raise an error, slicing will not:
     In [131]: s[10:20]
     Out[131]: ' words'
     In [132]: s[20:30]
-    Out[132]: "
+    Out[132]: ''
 
 
 (demo)
@@ -456,10 +457,10 @@ Lightning Talks
 ----------------
 
 |
-| Eric Rosko
+| Beatrice He
 |
 |
-| Michael Waddle
+| Bradley Baumel
 |
 
 
@@ -634,15 +635,14 @@ Ever.
 
 .. nextslide:: The Types We Know
 
-========= =======
+========= ===========
 Immutable Mutable
-========= =======
-Unicode   List
-String
-Integer
+========= ===========
+String    List
+Integer   Dictionary
 Float
 Tuple
-========= =======
+========= ===========
 
 
 .. nextslide:: Lists Are Mutable
@@ -1100,6 +1100,27 @@ https://docs.python.org/3.5/library/stdtypes.html#mutable-sequence-types
 
 (actually any mutable sequence....)
 
+One Last Trick
+---------------
+
+.. rst-class:: left
+
+For some of the exercises, you'll need to interact with a user at the
+command line.
+
+There's a nice built in function to do this - ``input``:
+
+.. code-block:: ipython
+
+    In [85]: fred = input('type something-->')
+    type something-->I've typed something
+
+    In [86]: print(fred)
+    I've typed something
+
+This will display a prompt to the user, allowing them to input text and
+allowing you to bind that input to a symbol.
+
 LAB
 ====
 
@@ -1112,13 +1133,14 @@ Let's play a bit with Python lists...
 
 
 
-Lightning Talk
+Lightning Talks
 ---------------
 
 |
-| Robert Alford
+| Jerry Bearer
+|
+| Sheree Pena
 |
-
 
 Iteration
 =========
@@ -1461,7 +1483,7 @@ Common Escape Sequences::
     \ooo  Character with octal value ooo
     \xhh  Character with hex value hh
 
-for example -- for tab-separted values:
+for example -- for tab-separated values:
 
 .. code-block:: ipython
 
@@ -1639,28 +1661,6 @@ It's well worth your while to spend some time getting to know this
 .. _formatting language: https://docs.python.org/3/library/string.html#format-specification-mini-language
 
 
-One Last Trick
----------------
-
-.. rst-class:: left
-
-For some of the exercises, you'll need to interact with a user at the
-command line.
-
-There's a nice built in function to do this - ``input``:
-
-.. code-block:: ipython
-
-    In [85]: fred = input('type something-->')
-    type something-->I've typed something
-
-    In [86]: print(fred)
-    I've typed something
-
-This will display a prompt to the user, allowing them to input text and
-allowing you to bind that input to a symbol.
-
-
 String Formatting LAB
 =====================
 
@@ -1712,11 +1712,13 @@ Next Week:
 
     **Lightning talks next week:**
 
-Andrey Gusev
+Abdishu Hagi
+
+Enrique R Silva
 
-Cheryl Ohashi
+Isaac Cowhey
 
-Maxwell MacCamy
+Paul G Anderson
 
 
 
diff --git a/slides_sources/source/session04.rst b/slides_sources/source/session04.rst
index 21706665..77ee3d1d 100644
--- a/slides_sources/source/session04.rst
+++ b/slides_sources/source/session04.rst
@@ -4,7 +4,6 @@
 Session Four: Dictionaries, Sets, and Files
 *******************************************
 
-
 ================
 Review/Questions
 ================
@@ -33,13 +32,15 @@ Any questions?
 Lightning Talks Today:
 ----------------------
 
-.. rst-class:: mlarge
+.. rst-class:: medium
+
+  Abdishu Hagi
 
- Andrey Gusev
+  Enrique R Silva
 
- Cheryl Ohashi
+  Isaac Cowhey
 
- Maxwell MacCamy
+  Paul G Anderson
 
 
 ==============================
@@ -68,7 +69,7 @@ You can do that in a for loop, also:
   In [4]: l = [(1, 2), (3, 4), (5, 6)]
 
   In [5]: for i, j in l:
-              print("i:%i, j:%i"%(i, j))
+              print("i:{}, j:{}".format(i, j))
 
   i:1, j:2
   i:3, j:4
@@ -77,8 +78,8 @@ You can do that in a for loop, also:
 (Mailroom example)
 
 
-Looping through two loops at once:
-----------------------------------
+Looping through two iterables at once:
+--------------------------------------
 
 .. rst-class:: mlarge
 
@@ -91,8 +92,8 @@ Looping through two loops at once:
     In [11]: l2 = [3, 4, 5]
 
     In [12]: for i, j in zip(l1, l2):
-       ....:     print("i:%i, j:%i"%(i, j))
-       ....:
+              print("i:{}, j:{}".format(i, j))
+
     i:1, j:3
     i:2, j:4
     i:3, j:5
@@ -116,7 +117,7 @@ Need the index and the item?
     In [2]: l = ['this', 'that', 'the other']
 
     In [3]: for i, item in enumerate(l):
-       ...:     print("the %ith item is: %s"%(i, item))
+       ...:     print("the {:d}th item is: {:s}".format(i, item))
        ...:
     the 0th item is: this
     the 1th item is: that
@@ -162,7 +163,34 @@ You can put a mutable item in an immutable object!
 | Deleting from list (list_lab)
 |
 
-.. nextslide::
+__main__
+--------
+
+What is this::
+
+  if __name__ == __main__
+
+about?
+
+Every module has a __name__
+
+If the module is loaded by ``import`` then it's name is the filename.
+
+If the module is run at the command line, like:
+
+.. code-block:: bash
+
+    python3 the_module.py
+
+Then it's ``__name__`` will be "__main__"
+
+This can be used to run code only when a module is run as a command,
+but not when it is imported.
+
+(demo)
+
+assert
+------
 
 What is ``assert`` for?
 
@@ -175,10 +203,33 @@ in operational code should be::
     if m < 0:
         raise ValueError
 
-I'll cover next week ...
+I'll cover more next week ...
 
 (Asserts get ignored if optimization is turned on!)
 
+what the heck is reversed()?
+----------------------------
+
+I had a question in a PR:
+
+"what is ``reversed(x)``'s resultant object? what good is it?""
+
+.. nextslide::
+
+try it:
+
+.. code-block:: ipython
+
+  In [14]: type(reversed(l))
+  Out[14]: list_reverseiterator
+
+so it's a ``list_reverseiterator`` object -- not helpful, is it :-)
+
+But what it means is that it's an "iterable" that you can then do things like loop through with a for loop, etc. but it hasn't made a copy of the list -- it returns the items one by one as they are asked for. this has performance benefits, as it doesn't have to make a copy of the whole thing.
+
+So you use it if you want to loop through something in reversed order, but dont actually need an actual list with the order reversed.
+
+we'll get more into the details of iterators and iterables later in the class.
 
 =================
 A little warm up
@@ -191,6 +242,15 @@ Fun with strings
 
     - for an arbitrary number of numbers...
 
+===============
+Lightning Talks
+===============
+
+|
+| Isaac Cowhey
+|
+| Paul G Anderson
+|
 
 =====================
 Dictionaries and Sets
@@ -650,13 +710,14 @@ Have some fun with dictionaries and sets!
 :ref:`exercise_dict_lab`
 
 
-Lightning Talk
---------------
+Lightning Talks
+---------------
 
 |
-| Maxwell MacCamy
+| Abdishu Hagi
+|
+| Enrique R Silva
 |
-
 
 ========================
 File Reading and Writing
@@ -919,25 +980,8 @@ LAB
 
 Files Lab: If there is time.
 
-Files Lab
----------
-
-In the class repo, in:
-
-``Examples\students.txt``
-
-You will find the list I generated of all the students in the class, and
-what programming languages they have used in the past.
-
-Write a little script that reads that file, and generates a list of all
-the languages that have been used.
-
-Extra credit: keep track of how many students specified each language.
+:ref:`exercise_file_lab`
 
-If you've got git set up right, ``git pull upstream master`` should update
-your repo. Otherwise, you can get it from gitHub:
-
-``https://github.com/UWPCE-PythonCert/IntroPython2015/blob/master/Examples/students.txt``
 
 
 =========
@@ -946,68 +990,21 @@ Homework
 
 Recommended Reading:
 ---------------------
-  * Dive Into Python: Chapt. 13,14
-
-Assignments:
--------------
-
- * Finish the dict/sets lab
- * Finish the Exceptions lab
- * Coding kata: trigrams
- * Paths and files
- * Update mailroom with dicts and exceptions
-
-
-Text and files and dicts, and...
----------------------------------
-
-* Coding Kata 14 - Dave Thomas
 
-    http://codekata.com/kata/kata14-tom-swift-under-the-milkwood/
+  * Dive Into Python 3: Chapt. 2.7 (and 4 if you haven't already)
 
-    and in this doc:
+http://www.diveintopython3.net/native-datatypes.html#dictionaries
 
-    :doc:`./exercises/kata_fourteen`
+  * Dive Into Python 3: Chapt. 11
 
-    and on github here
+http://www.diveintopython3.net/files.html
 
-    http://uwpce-pythoncert.github.io/IntroToPython/exercises/kata_fourteen.html
 
-.. nextslide::
-
-* Use The Adventures of Sherlock Holmes as input:
-
-    :download:`./exercises/sherlock.txt`
-
-    and on github here:
-
-    http://uwpce-pythoncert.github.io/IntroToPython/_downloads/sherlock.txt
-
-* This is intentionally open-ended and underspecified. There are many interesting decisions to make.
-
-* Experiment with different lengths for the lookup key. (3 words, 4 words, 3 letters, etc)
-
-
-Paths and File Processing
---------------------------
-
-* write a program which prints the full path to all files in the current
-  directory, one per line
-
-* write a program which copies a file from a source, to a destination
-  (without using shutil, or the OS copy command)
-
-  - advanced: make it work for any size file: i.e. don't read the entire
-    contents of the file into memory at once.
-
-  - Note that if you want it to do any kind of file, you need to open the files in binary mode:
-    ``open(filename, 'rb')`` (or ``'wb'`` for writing.)
-
-* update mailroom from last week to:
+Assignments:
+-------------
 
-  - Use dicts where appropriate
-  - Write a full set of letters to everyone to individual files on disk
-  - See if you can use a dict to switch between the users selections
-  - Try to use a dict and the .format() method to do the letter as one
-    big template -- rather than building up a big string in parts.
+ * Finish the dict/sets lab: :ref:`exercise_dict_lab`
+ * Finish the files lab: :ref:`exercise_file_lab`
+ * Coding kata: trigrams: :ref:`exercise_trigrams`
 
+ * update mailroom with dicts :ref:`exercise_mailroom_plus`
diff --git a/slides_sources/source/session05.rst b/slides_sources/source/session05.rst
index 74287d5a..04b21d7a 100644
--- a/slides_sources/source/session05.rst
+++ b/slides_sources/source/session05.rst
@@ -1,8 +1,8 @@
 .. include:: include.rst
 
-*************************************************
-Session Five: Exceptions, Testing, Comprehensions
-*************************************************
+****************************************
+Session Five: Exceptions, Comprehensions
+****************************************
 
 ======================
 Lightning Talks Today:
@@ -10,11 +10,13 @@ Lightning Talks Today:
 
 .. rst-class:: medium
 
-    Michael Cimino
+    Alexander C Truong
 
-    Pei Lin
+    Darryl Wong
 
-    Tiffany Ku
+    Madhumita Acharya
+
+    Matthew T Weidner
 
 ================
 Review/Questions
@@ -53,17 +55,63 @@ Review of Previous Class
 
     * I'll take time to go over it in class.
 
+    * And this week is a light load, so you can catch up.
+
 
 Homework review
 ---------------
 
-Homework Questions?
-
 My Solutions to all the exercises in the class repo in:
 
 ``Solutions/Session04``
 
-A few tidbits ....
+A few tidbits, then I'll take specific questions.
+
+
+The count() method
+------------------
+
+All Python sequences (including strings) have a ``count()`` method:
+
+.. code-block:: ipython
+
+    In [1]: s = "This is an arbitrary string"
+
+    In [2]: s.count('t')
+    Out[2]: 2
+
+What if you want a case-insensitive count?
+
+.. code-block:: ipython
+
+    In [3]: s.lower().count('t')
+    Out[3]: 3
+
+set.update()
+------------
+
+If you want to add a bunch of stuff to a set, you can use update:
+
+.. code-block:: ipython
+
+    In [1]: s = set()
+
+In [2]: s.update
+Out[2]: 
+
+In [3]: s.update(['this', 'that'])
+
+In [4]: s
+Out[4]: {'that', 'this'}
+
+In [5]: s.update(['this', 'thatthing'])
+
+In [6]: s
+Out[6]: {'that', 'thatthing', 'this'}
+
+**NOTE:** It's VERY often the case that when you find yourself writing a trivial loop -- there is a way to do it with a built in method!
+
+
 
 Sorting stuff in dictionaries:
 -------------------------------
@@ -77,7 +125,7 @@ The "standard" way:
   for key in sorted(d.keys()):
       ...
 
-Other options:
+Another option:
 
 .. code-block:: python
 
@@ -87,6 +135,73 @@ Also other nifty stuff in the ``collections`` module:
 
 https://docs.python.org/3.5/library/collections.html
 
+Using files and "with"
+-----------------------
+
+Sorry for the confusion, but I'll be more clear now.
+
+When working with files, unless you have a good reason not to, use ``with``:
+
+.. code-block:: python
+
+  with open(the_filename, 'w') as outfile:
+      outfile.write(something)
+      do_some_more...
+  # now done with out file -- it will be closed, regardless of errors, etc.
+  do_other_stuff
+
+``with`` invokes a context manager -- which can be confusing, but for now,
+just follow this pattern -- it really is more robust.
+
+And you can even do two at once:
+
+.. code-block:: python
+
+    with open(source, 'rb') as infile, open(dest, 'wb') as outfile:
+        outfile.write(infile.read())
+
+
+Binary files
+------------
+
+Python can open files in one of two modes:
+
+ * Text
+ * Binary
+
+This is just what you'd think -- if the file contains text, you want text mode. If the file contains arbitrary binary data, you want binary mode.
+
+All data in all files is binary -- that's how computers work. So in Python3, "text" actually means Unicode -- which is a particular system for matching characters to binary data.
+
+But this too is complicated -- there are multiple ways that binary data can be mapped to Unicode text, known as "encodings". In Python, text files are by default opened with the "utf-8" encoding. These days, that mostly "just works".
+
+.. nextslide::
+
+But if you read a binary file as text, then Python will try to interpret the bytes as utf-8 encoded text -- and this will likely fail:
+
+.. code-block:: ipython
+
+    In [13]: open("a_photo.jpg").read()
+    ---------------------------------------------------------------------------
+    UnicodeDecodeError                        Traceback (most recent call last)
+     in ()
+    ----> 1 open("PassportPhoto.JPG").read()
+
+    /Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/codecs.py in decode(self, input, final)
+        319         # decode input (taking the buffer into account)
+        320         data = self.buffer + input
+    --> 321         (result, consumed) = self._buffer_decode(data, self.errors, final)
+        322         # keep undecoded input until the next call
+        323         self.buffer = data[consumed:]
+
+    UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte
+
+.. nextslide::
+
+In Python2, it's less likely that you'll get an error like this -- it doesn't try to decode the file as it's read -- even for text files -- so it's a bit tricky and more error prone.
+
+**NOTE:** If you want to actually DO anything with a binary file, other than passing it around, then you'll need to know a lot about how the details of what the bytes in the file mean -- and most likely, you'll use a library for that -- like an image processing library for the jpeg example above.
+
 
 PEP 8 reminder
 --------------
@@ -101,12 +216,12 @@ But style matters -- consistent style makes your code easier to read and underst
 
 So **follow PEP 8**
 
-*Exception* -- if you have a company style guide follow that instead.
+**Exception:** if you have a company style guide -- follow that instead.
 
-try the "pep8" module on your code::
+Try the "pycodestyle" module on your code::
 
-  $ python3 -m pip install pep8
-  $ pep8 my_python_file
+  $ python3 -m pip install pycodestyle
+  $ pycodestyle my_python_file
 
 (demo)
 
@@ -126,7 +241,7 @@ So use names that make sense to the reader.
 Naming Guidelines
 -----------------
 
-Only use single-letter names for things with limited scope: indexes and teh like:
+Only use single-letter names for things with limited scope: indexes and the like:
 
 .. code-block:: python
 
@@ -177,6 +292,34 @@ Anyone look at my solutions?
 
 Anything in particular you'd like me to go over?
 
+
+trigrams
+--------
+
+Let's take a close look at trigrams!
+
+Some of you have already done a nice solution to this.
+
+But some of you are not sure how to start.
+
+So let's start from the beginning...
+
+NOTE: think about set vs list.
+
+(demo)
+
+Lightning Talks
+----------------
+
+.. rst-class:: medium
+
+|
+| Alexander C Truong
+|
+|
+| Darryl Wong
+|
+
 ==========
 Exceptions
 ==========
@@ -199,6 +342,7 @@ Another Branching structure:
 
 Exceptions
 ----------
+
 Never Do this:
 
 .. code-block:: python
@@ -210,6 +354,8 @@ Never Do this:
     except:
         print "couldn't open missing.txt"
 
+**always** capture the *particular* Exception you know how to handle.
+
 
 Exceptions
 ----------
@@ -223,7 +369,7 @@ Don't do this:
     do_something()
     if os.path.exists('missing.txt'):
         f = open('missing.txt')
-        process(f)   # never called if file missing
+        process(f)
 
 It will almost always work -- but the almost will drive you crazy
 
@@ -250,7 +396,8 @@ So you can do
 Or let the Exception be raised....
 
 
-.. nextslide:: EAFP
+EAFP
+----
 
 
 "it's Easier to Ask Forgiveness than Permission"
@@ -262,6 +409,7 @@ http://www.youtube.com/watch?v=AZDWveIdqjY
 
 (PyCon talk by Alex Martelli)
 
+
 .. nextslide:: Do you catch all Exceptions?
 
 For simple scripts, let exceptions happen.
@@ -388,22 +536,20 @@ LAB
 
 Exceptions Lab:
 
-A number of you already did this -- so do it at home if you haven't
 
 :ref:`exercise_exceptions_lab`
 
 
 Lightning Talks
-----------------
+---------------
 
 .. rst-class:: medium
 
 |
-| Michael Cimino
-|
-|
-| Pei Lin
+| Madhumita Acharya
 |
+| Matthew T Weidner
+
 
 
 ============================
@@ -575,260 +721,15 @@ Example
 LAB
 ===
 
-List comps exercises:
-
-:ref:`exercise_comprehensions`
-
-
-
-Lightning Talk
-----------------
-
-.. rst-class:: medium
-
-|
-| Tiffany Ku
-|
-
-
-=======
-Testing
-=======
-
-.. rst-class:: build left
-.. container::
-
-    You've already seen some a very basic testing strategy.
-
-    You've written some tests using that strategy.
-
-    These tests were pretty basic, and a bit awkward in places (testing error
-    conditions in particular).
-
-    .. rst-class:: centered
-
-    **It gets better**
-
-Test Runners
-------------
+Here is a nice tutorial on list comprehensions:
 
-So far our tests have been limited to code in an ``if __name__ == "__main__":``
-block.
+http://treyhunner.com/2015/12/python-list-comprehensions-now-in-color/
 
-.. rst-class:: build
-
-* They are run only when the file is executed
-* They are always run when the file is executed
-* You can't do anything else when the file is executed without running tests.
-
-.. rst-class:: build
-.. container::
-
-    This is not optimal.
-
-    Python provides testing systems to help.
-
-
-Standard Library: ``unittest``
--------------------------------
-
-The original testing system in Python.
-
-``import unittest``
-
-More or less a port of ``Junit`` from Java
-
-A bit verbose: you have to write classes & methods
-
-(And we haven't covered that yet!)
-
-
-Using ``unittest``
--------------------
-
-You write subclasses of the ``unittest.TestCase`` class:
-
-.. code-block:: python
-
-    # in test.py
-    import unittest
-
-    class MyTests(unittest.TestCase):
-        def test_tautology(self):
-            self.assertEquals(1, 1)
-
-Then you run the tests by using the ``main`` function from the ``unittest``
-module:
-
-.. code-block:: python
-
-    # in test.py
-    if __name__ == '__main__':
-        unittest.main()
-
-.. nextslide:: Testing Your Code
-
-This way, you can write your code in one file and test it from another:
-
-.. code-block:: python
-
-    # in my_mod.py
-    def my_func(val1, val2):
-        return val1 * val2
-
-    # in test_my_mod.py
-    import unittest
-    from my_mod import my_func
-
-    class MyFuncTestCase(unittest.TestCase):
-        def test_my_func(self):
-            test_vals = (2, 3)
-            expected = reduce(lambda x, y: x * y, test_vals)
-            actual = my_func(*test_vals)
-            self.assertEquals(expected, actual)
-
-    if __name__ == '__main__':
-        unittest.main()
-
-.. nextslide:: Advantages of ``unittest``
-
-.. rst-class:: build
-.. container::
-
-    The ``unittest`` module is pretty full featured
-
-    It comes with the standard Python distribution, no installation required.
-
-    It provides a wide variety of assertions for testing all sorts of situations.
-
-    It allows for a setup and tear down workflow both before and after all tests and before and after each test.
-
-    It's well known and well understood.
-
-.. nextslide:: Disadvantages:
-
-.. rst-class:: build
-.. container::
-
-
-    It's Object Oriented, and quite heavy.
-
-      - modeled after Java's ``junit`` and it shows...
-
-    It uses the framework design pattern, so knowing how to use the features
-    means learning what to override.
-
-    Needing to override means you have to be cautious.
-
-    Test discovery is both inflexible and brittle.
-
-    And there is no built-in parameterized testing.
-
-Other Options
--------------
-
-There are several other options for running tests in Python.
-
-* `Nose`: https://nose.readthedocs.org/
-
-* `pytest`: http://pytest.org/latest/
-
-* ... (many frameworks supply their own test runners)
-
-Both are very capable and widely used. I have a personal preference for pytest -- so we'll use it for this class
-
-Installing ``pytest``
----------------------
-
-The first step is to install the package:
-
-.. code-block:: bash
-
-    $ python3 -m pip install pytest
-
-Once this is complete, you should have a ``py.test`` command you can run
-at the command line:
-
-.. code-block:: bash
-
-    $ py.test
-
-If you have any tests in your repository, that will find and run them.
-
-.. rst-class:: build
-.. container::
-
-    **Do you?**
-
-Pre-existing Tests
-------------------
-
-Let's take a look at some examples.
-
-``IntroToPython\Examples\Session05``
-
-`` $ py.test``
-
-You can also run py.test on a particular test file:
-
-``py.test test_this.py``
-
-The results you should have seen when you ran ``py.test`` above come
-partly from these files.
-
-Let's take a few minutes to look these files over.
-
-[demo]
-
-.. nextslide:: What's Happening Here.
-
-When you run the ``py.test`` command, ``pytest`` starts in your current
-working directory and searches the filesystem for things that might be tests.
-
-It follows some simple rules:
-
-.. rst-class:: build
-
-* Any python file that starts with ``test_`` or ``_test`` is imported.
-* Any functions in them that start with ``test_`` are run as tests.
-* Any classes that start with ``Test`` are treated similarly, with methods that begin with ``test_`` treated as tests.
-
-
-.. nextslide:: pytest
-
-This test running framework is simple, flexible and configurable.
-
-`Read the documentation`_ for more information.
-
-.. _Read the documentation: http://pytest.org/latest/getting-started.html#getstarted
-
-.. nextslide:: Test Driven Development
-
-What we've just done here is the first step in what is called **Test Driven
-Development**.
-
-A bunch of tests exist, but the code to make them pass does not yet exist.
-
-The red you see in the terminal when we run our tests is a goad to us to write
-the code that fixes these tests.
-
-Let's do that next!
-
-===
-LAB
-===
-
-Pick an example from codingbat:
-
-``http://codingbat.com``
+List comps exercises:
 
-Do a bit of test-driven development on it:
+:ref:`exercise_comprehensions`
 
- * run something on the web site.
- * write a few tests using the examples from the site.
- * then write the function, and fix it 'till it passes the tests.
 
-Do at least two of these...
 
 =========
 Homework
@@ -837,15 +738,13 @@ Homework
 Catch up!
 ---------
 
-
 * Finish the LABs from today
   - Exceptions lab
 
 * Catch up from last week.
 
   - Add Exception handling to mailroom
-  - and add some tests
-  - and list (and dict, and set) comprehensions...
+  - And list (and dict, and set) comprehensions...
 
 * If you've done all that -- check out the collections module:
 
@@ -856,19 +755,22 @@ Catch up!
 Material to review before next week:
 ====================================
 
- * Dive into Python3: 7.2 -- 7.3
-   http://www.diveintopython3.net/iterators.html#defining-classes
+**Unit Testing:**
+
+* Dive into Python: chapter 9:
+  http://www.diveintopython3.net/unit-testing.html
+
+NOTE: you will find that most introductions to unit testing with Python use the builtin ``unitest`` module. However, it is a bit heavyweight, and requires some knowledge of OOP -- classes, etc. So we'll be using pytest in this class: http://doc.pytest.org/en/latest/. But the principles of testing are the same.
+
+* Ned Batchelder's intro to testing presentation:
 
- * Think Pyhton: 15 -- 18
-   http://www.greenteapress.com/thinkpython/html/thinkpython016.html
+  - http://nedbatchelder.com/text/test0.html
 
- * LPTHW: 40 -- 44
-   http://learnpythonthehardway.org/book/ex40.html
+** Advanced Argument Passing
 
-[note that in py3 you dont need to inherit from object]
+* arguments and parameters:
 
-Talk by Raymond Hettinger:
+  - http://stupidpythonideas.blogspot.com/2013/08/arguments-and-parameters.html
 
-https://youtu.be/HTLu2DFOdTg
+  - https://pythontips.com/2013/08/04/args-and-kwargs-in-python-explained/
 
-https://speakerdeck.com/pyconslides/pythons-class-development-toolkit-by-raymond-hettinger
diff --git a/slides_sources/source/session06.rst b/slides_sources/source/session06.rst
index 63aac572..d5e624b9 100644
--- a/slides_sources/source/session06.rst
+++ b/slides_sources/source/session06.rst
@@ -1,9 +1,8 @@
 .. include:: include.rst
 
-********************************************************************
-Session Six: Advanced Argument Passing, lambda, functions as objects
-********************************************************************
-
+***********************************************
+Session Six: Testing, Advanced Argument Passing
+***********************************************
 
 ======================
 Lightning Talks Today:
@@ -11,11 +10,11 @@ Lightning Talks Today:
 
 .. rst-class:: medium
 
-    Gabriel Meringolo
+    Adam Hollis
 
-    Joseph Cardenas
+    Nachiket Galande
 
-    Marc Teale
+    Paul A Casey
 
 ================
 Review/Questions
@@ -28,7 +27,6 @@ Review of Previous Class
 
 * Comprehensions
 
-* Testing
 
 ===============
 Homework review
@@ -57,16 +55,6 @@ rich comparisons: numpy
 
 .. nextslide::
 
-Binary mode for files:
-
-.. code-block:: python
-
-    infile = open(infilename, 'rb')
-    outfile = open(outfilename, 'wb')
-
-|
-|
-
 You don't actually need to use the result of a list comp:
 
 .. code-block:: python
@@ -76,13 +64,11 @@ You don't actually need to use the result of a list comp:
 
 .. nextslide::
 
-Apropos of today's topics:
-
-Python functions are objects, so if you dont call them, you do'nt get an error, you jsut get the function object, ususally not what you want::
+Python functions are objects, so if you don't call them, you don't get an error, you just get the function object, usually not what you want::
 
         elif donor_name.lower == "exit":
 
-this is comparing the string ``lower`` method to the string "exit" and theyare never going to be equal!
+this is comparing the string ``lower`` method to the string "exit" and they are never going to be equal!
 
 That should be::
 
@@ -90,20 +76,381 @@ That should be::
 
 This is actually a pretty common typo -- keep an eye out for it when you get strange errors, or something just doesn't seem to be getting triggered.
 
-============================
+long strings
+------------
+
+if you need to do along string literal, sometimes a triple quoted string is perfect::
+
+  """this is a long string.
+  I want it to hvae multiple lines.
+  so having the line endings automatic is great.
+  """
+
+But you don't always want the line endings quite like that. And you may not want all that whitespace when fitting it into indented code.
+
+It turns out that when you put a multiple strings together with no commas or anythign in between -- python will join them:
+
+.. code-block:: ipython
+
+  In [81]: "this is " "a string " "built up of parts"
+  Out[81]: 'this is a string built up of parts'
+
+.. nextslide::
+
+If it's in parentheses, you can put the next chunk on the next line:
+
+.. code-block:: python
+
+  print("{} is from {}, and he likes "
+        "{} cake, {} fruit, {} salad, "
+        "and {} pasta.".format(food_prefs["name"],
+                               food_prefs["city"],
+                               food_prefs["cake"],
+                               food_prefs["fruit"],
+                               food_prefs["salad"],
+                               food_prefs["pasta"]))
+
+pretty print
+------------
+
+If you need to print our nested (or large) data structure in a more readable fashion, the "pretty print" module is handy:
+
+.. code-block:: ipython
+
+  from pprint import pprint
+
+    In [28]: print(food_prefs)
+    {'pasta': 'lasagna', 'cake': 'chocolate', 'salad': 'greek', 'fruit': 'mango', 'name': 'Chris', 'city': 'Seattle'}
+
+    In [29]: pprint(food_prefs)
+    {'cake': 'chocolate',
+     'city': 'Seattle',
+     'fruit': 'mango',
+     'name': 'Chris',
+     'pasta': 'lasagna',
+     'salad': 'greek'}
+
+Exceptions
+----------
+
+Adding stuff to an Exception:
+
+Example from slack
+
+
+Anything else?
+--------------
+
+.. rst-class:: center medium
+
+   Anything else you want me to go over?
+
+
+Lightning Talks
+----------------
+
+.. rst-class:: medium
+
+|
+| Adam Hollis
+|
+| Nachiket Galande
+|
+
+=======
+Testing
+=======
+
+.. rst-class:: build left
+.. container::
+
+    You've already seen a very basic testing strategy.
+
+    You've written some tests using that strategy.
+
+    These tests were pretty basic, and a bit awkward in places (testing error
+    conditions in particular).
+
+    .. rst-class:: centered large
+
+    **It gets better**
+
+Test Runners
+------------
+
+So far our tests have been limited to code in an ``if __name__ == "__main__":``
+block.
+
+.. rst-class:: build
+
+* They are run only when the file is executed
+* They are always run when the file is executed
+* You can't do anything else when the file is executed without running tests.
+
+.. rst-class:: build
+.. container::
+
+    This is not optimal.
+
+    Python provides testing systems to help.
+
+
+Standard Library: ``unittest``
+-------------------------------
+
+The original testing system in Python.
+
+``import unittest``
+
+More or less a port of ``Junit`` from Java
+
+A bit verbose: you have to write classes & methods
+
+(And we haven't covered that yet!)
+
+
+Using ``unittest``
+-------------------
+
+You write subclasses of the ``unittest.TestCase`` class:
+
+.. code-block:: python
+
+    # in test.py
+    import unittest
+
+    class MyTests(unittest.TestCase):
+        def test_tautology(self):
+            self.assertEquals(1, 1)
+
+Then you run the tests by using the ``main`` function from the ``unittest``
+module:
+
+.. code-block:: python
+
+    # in test.py
+    if __name__ == '__main__':
+        unittest.main()
+
+.. nextslide:: Testing Your Code
+
+This way, you can write your code in one file and test it from another:
+
+.. code-block:: python
+
+    # in my_mod.py
+    def my_func(val1, val2):
+        return val1 * val2
+
+    # in test_my_mod.py
+    import unittest
+    from my_mod import my_func
+
+    class MyFuncTestCase(unittest.TestCase):
+        def test_my_func(self):
+            test_vals = (2, 3)
+            expected = reduce(lambda x, y: x * y, test_vals)
+            actual = my_func(*test_vals)
+            self.assertEquals(expected, actual)
+
+    if __name__ == '__main__':
+        unittest.main()
+
+.. nextslide:: Advantages of ``unittest``
+
+.. rst-class:: build
+.. container::
+
+    The ``unittest`` module is pretty full featured
+
+    It comes with the standard Python distribution, no installation required.
+
+    It provides a wide variety of assertions for testing all sorts of situations.
+
+    It allows for a setup and tear down workflow both before and after all tests and before and after each test.
+
+    It's well known and well understood.
+
+.. nextslide:: Disadvantages:
+
+.. rst-class:: build
+.. container::
+
+
+    It's Object Oriented, and quite "heavyweight".
+
+      - modeled after Java's ``junit`` and it shows...
+
+    It uses the framework design pattern, so knowing how to use the features
+    means learning what to override.
+
+    Needing to override means you have to be cautious.
+
+    Test discovery is both inflexible and brittle.
+
+    And there is no built-in parameterized testing.
+
+Other Options
+-------------
+
+There are several other options for running tests in Python.
+
+* `Nose`: https://nose.readthedocs.org/
+
+* `pytest`: http://pytest.org/latest/
+
+* ... (many frameworks supply their own test runners: e.g. django)
+
+Both are very capable and widely used. I have a personal preference for pytest
+
+-- so we'll use it for this class
+
+Installing ``pytest``
+---------------------
+
+The first step is to install the package:
+
+.. code-block:: bash
+
+    $ python3 -m pip install pytest
+
+Once this is complete, you should have a ``py.test`` command you can run
+at the command line:
+
+.. code-block:: bash
+
+    $ py.test
+
+If you have any tests in your repository, that will find and run them.
+
+.. rst-class:: build
+.. container::
+
+    **Do you?**
+
+Pre-existing Tests
+------------------
+
+Let's take a look at some examples.
+
+in ``IntroPython2016\Examples\Session06``
+
+.. code-block:: bash
+
+  $ py.test
+
+You can also run py.test on a particular test file:
+
+.. code-block:: bash
+
+  $ py.test test_random_unitest.py
+
+The results you should have seen when you ran ``py.test`` above come
+partly from these files.
+
+Let's take a few minutes to look these files over.
+
+[demo]
+
+What's Happening Here.
+----------------------
+
+When you run the ``py.test`` command, ``pytest`` starts in your current
+working directory and searches the filesystem for things that might be tests.
+
+It follows some simple rules:
+
+* Any python file that starts with ``test_`` or ``_test`` is imported.
+
+* Any functions in them that start with ``test_`` are run as tests.
+
+* Any classes that start with ``Test`` are treated similarly, with methods that begin with ``test_`` treated as tests.
+
+( don't worry about "classes" part just yet ;-) )
+
+pytest
+------
+
+This test running framework is simple, flexible and configurable.
+
+Read the documentation for more information:
+
+http://pytest.org/latest/getting-started.html#getstarted
+
+It will run ``unittest`` tests for you.
+
+But in addition to finding and running tests, it makes writting tests simple, and provides a bunch of nifty utilities to support more complex testing.
+
+
+Test Driven Development
+-----------------------
+in the Examples dir, try::
+
+  $ py.test test_cigar_party
+
+What we've just done here is the first step in what is called:
+
+.. rst-class:: centered
+
+  **Test Driven Development**.
+
+A bunch of tests exist, but the code to make them pass does not yet exist.
+
+The red you see in the terminal when we run our tests is a goad to us to write the code that fixes these tests.
+
+Let's do that next!
+
 Test Driven development demo
-============================
+-----------------------------
+
+Open up:
+
+``Examples/Session06/test_cigar_party.py``
+
+and:
+
+``Examples/Session06/cigar_party.py``
+
+and run::
+
+  $ py.teset test_cigar_party.py
+
+Now go in to ``cigar_party.py`` and let's fix the tests.
+
+Let's play with codingbat.py also...
+
+===
+LAB
+===
+
+.. rst-class:: left
+
+  Pick an example from codingbat:
+
+  ``http://codingbat.com``
+
+  Do a bit of test-driven development on it:
+
+   * run something on the web site.
+   * write a few tests using the examples from the site.
+   * then write the function, and fix it 'till it passes the tests.
 
-We did some of this last class -- but I want to really drive it home :-)
+  Do at least two of these...
 
-In ``Examples/Session06/test_cigar_party.py``
+Lightning Talk
+--------------
 
+.. rst-class:: medium
+
+    |
+    | Paul A Casey
+    |
 
 =========================
 Advanced Argument Passing
 =========================
 
-This is a very, very nift Python feature -- it really lets you write dynamic programs.
+This is a very, very nifty Python feature -- it really lets you write dynamic programs.
 
 Keyword arguments
 -----------------
@@ -172,7 +519,7 @@ This is a **very** important point -- I will repeat it!
 Function arguments in variables
 -------------------------------
 
-function arguments are really just
+When a function is called, its arguments are really just:
 
 * a tuple (positional arguments)
 * a dict (keyword arguments)
@@ -232,35 +579,39 @@ And pass to ``format()``with ``**``
     In [26]: "My name is {first} {last}".format(**d)
     Out[26]: 'My name is Chris Barker'
 
-LAB
-----
+Kinda handy for the dict lab, eh?
 
-.. rst-class:: medium
+This:
 
-  keyword arguments:
+.. code-block:: ipython
 
-* Write a function that has four optional parameters (with defaults):
+  print("{} is from {}, and he likes "
+        "{} cake, {} fruit, {} salad, "
+        "and {} pasta.".format(food_prefs["name"],
+                               food_prefs["city"],
+                               food_prefs["cake"],
+                               food_prefs["fruit"],
+                               food_prefs["salad"],
+                               food_prefs["pasta"]))
 
-  - fore_color
-  - back_color
-  - link_color
-  - visited_color
+Becomes:
 
-* Have it print the colors (use strings for the colors)
-* Call it with a couple different parameters set
-* Have it pull the parameters out with ``*args, **kwargs``
-  - and print those
+.. code-block:: ipython
 
-Lightning Talks
-----------------
+  print("{name} is from {city}, and he likes "
+        "{cake} cake, {fruit} fruit, {salad} salad, "
+        "and {pasta} pasta.".format(**food_prefs))
 
-.. rst-class:: medium
+LAB
+----
 
-    |
-    | Gabriel Meringolo
-    |
-    | Joseph Cardenas
-    |
+Time to play with all this to get a feel for it.
+
+:ref:`exercise_args_kwargs_lab`
+
+This is not all that clearly specified -- the goal is for you to
+experiment with various ways to define and call functions, so you
+can understand what's possible, and what happens with each call.
 
 
 =====================================
@@ -441,428 +792,43 @@ The standard practice for such a mutable default argument:
 You get a new list every time the function is called
 
 
+========
+Homework
+========
 
-===================
-Anonymous functions
-===================
-
-lambda
-------
-
-.. code-block:: ipython
-
-    In [171]: f = lambda x, y: x+y
-    In [172]: f(2,3)
-    Out[172]: 5
-
-Content of function can only be an expression -- not a statement
-
-Anyone remember what the difference is?
-
-Called "Anonymous": it doesn't get a name.
-
-.. nextslide::
-
-It's a python object, it can be stored in a list or other container
-
-.. code-block:: ipython
-
-    In [7]: l = [lambda x, y: x+y]
-    In [8]: type(l[0])
-    Out[8]: function
-
-
-And you can call it:
-
-.. code-block:: ipython
-
-    In [9]: l[0](3,4)
-    Out[9]: 7
-
-
-Functions as first class objects
----------------------------------
-
-You can do that with "regular" functions too:
-
-.. code-block:: ipython
-
-    In [12]: def fun(x,y):
-       ....:     return x+y
-       ....:
-    In [13]: l = [fun]
-    In [14]: type(l[0])
-    Out[14]: function
-    In [15]: l[0](3,4)
-    Out[15]: 7
-
-
-
-======================
-Functional Programming
-======================
-
-No real consensus about what that means.
-
-But there are some "classic" methods available in Python.
-
-map
----
-
-``map``  "maps" a function onto a sequence of objects -- It applies the function to each item in the list, returning another list
-
-
-.. code-block:: ipython
-
-    In [23]: l = [2, 5, 7, 12, 6, 4]
-    In [24]: def fun(x):
-                 return x*2 + 10
-    In [25]: map(fun, l)
-    Out[25]: [14, 20, 24, 34, 22, 18]
-
-
-But if it's a small function, and you only need it once:
-
-.. code-block:: ipython
-
-    In [26]: map(lambda x: x*2 + 10, l)
-    Out[26]: [14, 20, 24, 34, 22, 18]
-
-
-filter
-------
-
-``filter``  "filters" a sequence of objects with a boolean function --
-It keeps only those for which the function is True -- filtering our the rest.
-
-To get only the even numbers:
-
-.. code-block:: ipython
-
-    In [27]: l = [2, 5, 7, 12, 6, 4]
-    In [28]: filter(lambda x: not x%2, l)
-    Out[28]: [2, 12, 6, 4]
-
-If you pass ``None`` to ``filter()``, you get only items that evaluate to true:
-
-.. code-block:: ipython
-
-    In [1]: l = [1, 0, 2.3, 0.0, 'text', '', [1,2], [], False, True, None ]
-
-    In [2]: filter(None, l)
-    Out[2]: [1, 2.3, 'text', [1, 2], True]
-
-
-reduce
-------
-
-``reduce``  "reduces" a sequence of objects to a single object with a function that combines two arguments
-
-To get the sum:
-
-.. code-block:: ipython
-
-    In [30]: l = [2, 5, 7, 12, 6, 4]
-    In [31]: reduce(lambda x,y: x+y, l)
-    Out[31]: 36
-
-
-To get the product:
-
-.. code-block:: ipython
-
-    In [32]: reduce(lambda x,y: x*y, l)
-    Out[32]: 20160
-
-or
-
-.. code-block:: ipython
-
-    In [13]: import operator
-    In [14]: reduce(operator.mul, l)
-    Out[14]: 20160
-
-Comprehensions
---------------
-
-Couldn't you do all this with comprehensions?
-
-Yes:
-
-.. code-block:: ipython
-
-    In [33]: [x+2 + 10 for x in l]
-    Out[33]: [14, 17, 19, 24, 18, 16]
-
-    In [34]: [x for x in l if not x%2]
-    Out[34]: [2, 12, 6, 4]
-
-    In [6]: l
-    Out[6]: [1, 0, 2.3, 0.0, 'text', '', [1, 2], [], False, True, None]
-    In [7]: [i for i in l if i]
-    Out[7]: [1, 2.3, 'text', [1, 2], True]
-
-(Except Reduce)
-
-But Guido thinks almost all uses of reduce are really ``sum()``
-
-Functional Programming
-----------------------
-
-Comprehensions and map, filter, reduce are all "functional programming" approaches}
-
-``map, filter``  and ``reduce``  pre-date comprehensions in Python's history
-
-Some people like that syntax better
-
-And "map-reduce" is a big concept these days for parallel processing of "Big Data" in NoSQL databases.
-
-(Hadoop, MongoDB, etc.)
-
-
-A bit more about lambda
-------------------------
-
-It is very useful for specifying sorting as well:
-
-.. code-block:: ipython
-
-    In [55]: lst = [("Chris","Barker"), ("Fred", "Jones"), ("Zola", "Adams")]
-
-    In [56]: lst.sort()
-
-    In [57]: lst
-    Out[57]: [('Chris', 'Barker'), ('Fred', 'Jones'), ('Zola', 'Adams')]
-
-    In [58]: lst.sort(key=lambda x: x[1])
-
-    In [59]: lst
-    Out[59]: [('Zola', 'Adams'), ('Chris', 'Barker'), ('Fred', 'Jones')]
-
-lambda in keyword arguments
-----------------------------
-
-.. code-block:: ipython
-
-    In [186]: l = []
-    In [187]: for i in range(3):
-        l.append(lambda x, e=i: x**e)
-       .....:
-    In [189]: for f in l:
-        print(f(3))
-    1
-    3
-    9
-
-Note when the keyword argument is evaluated: this turns out to be very handy!
-
-===
-LAB
-===
-
-Here's an exercise to try out some of this:
-
-:ref:`exercise_lambda_magic`
-
-Lightning Talk
---------------
-
-.. rst-class:: medium
-
-|
-|  Marc Teale
-|
-
-==============
-dict as switch
-==============
-
-What to use instead of "switch-case"?
-
-switch-case
------------
-
-A number of languages have a "switch-case" construct::
-
-    switch(argument) {
-        case 0:
-            return "zero";
-        case 1:
-            return "one";
-        case 2:
-            return "two";
-        default:
-            return "nothing";
-    };
-
-How do you spell this in python?
-
-``if-elif`` chains
--------------------
-
-The obvious way to spell it is a chain of ``elif`` statements:
-
-.. code-block:: python
-
-    if argument ==  0:
-        return "zero"
-    elif argument == 1:
-        return "one"
-    elif argument == 2:
-        return "two"
-    else:
-        return "nothing"
-
-And there is nothing wrong with that, but....
-
-.. nextslide::
-
-The ``elif`` chain is neither elegant nor efficient. There are a number of ways to spell it in python -- but one elgant one is to use a dict:
-
-.. code-block:: python
-
-    arg_dict = {0:"zero", 1:"one", 2: "two"}
-        dict.get(argument, "nothing")
-
-Simple, elegant, and fast.
-
-You can do a dispatch table by putting functions as the value.
-
-Example: Chris' mailroom2 solution.
-
-==============================
-Closures and function Currying
-==============================
-
-Defining specialized functions on the fly
-
-Closures
---------
-
-"Closures" and "Currying" are cool CS terms for what is really just defining functions on the fly.
-
-you can find a "proper" definition here:
-
-https://en.wikipedia.org/wiki/Closure_(computer_programming)
-
-but I even have trouble following that.
-
-So let's go straight to an example:
-
-.. nextslide::
-
-.. code-block:: python
-
-    def counter(start_at=0):
-        count = [start_at]
-        def incr():
-            count[0] += 1
-            return count[0]
-        return incr
-
-What's going on here?
-
-We have stored the ``start_at`` value in a list.
-
-Then defined a function, ``incr`` that adds one to the value in the list, and returns that value.
-
-[ Quiz: why is it: ``count = [start_at]``, rather than just ``count=start_at`` ]
-
-.. nextslide::
-
-So what type of object do you get when you call ``counter()``?
-
-.. code-block:: ipython
-
-    In [37]: c = counter(start_at=5)
-
-    In [38]: type(c)
-    Out[38]: function
-
-So we get a function back -- makes sense. The ``def`` defines a function, and that function is what's getting returned.
-
-Being a function, we can, of course, call it:
-
-.. code-block:: ipython
-
-    In [39]: c()
-    Out[39]: 6
-
-    In [40]: c()
-    Out[40]: 7
-
-Each time is it called, it increments the value by one.
-
-.. nextslide::
-
-But what happens if we call ``counter()`` multiple times?
-
-.. code-block:: ipython
-
-    In [41]: c1 = counter(5)
-
-    In [42]: c2 = counter(10)
-
-    In [43]: c1()
-    Out[43]: 6
-
-    In [44]: c2()
-    Out[44]: 11
-
-So each time ``counter()`` is called, a new function is created. And that function has its own copy of the ``count`` object. This is what makes in a "closure" -- it carries with it the scope in which is was created.
-
-the returned ``incr`` function is a "curried" function -- a function with some parameters pre-specified.
-
-``functools.partial``
----------------------
-
-The ``functools`` module in the standard library provides utilities for working with functions:
-
-https://docs.python.org/3.5/library/functools.html
-
-Creating a curried function turns out to be common enough that the ``functools.partial`` function provides an optimized way to do it:
-
-What functools.partial does is:
-
- * Makes a new version of a function with one or more arguments already filled in.
- * The new version of a function documents itself.
+.. rst-class:: left
 
-Example:
+  Finish up the Labs
 
-.. code-block:: python
+  Write a complete set of unit tests for your mailroom program.
 
-    def power(base, exponent):
-        """returns based raised to the give exponent"""
-        return base ** exponent
+   * You will likely find that it is really hard to test without refactoring.
 
-Simple enough. but what if we wanted a specialized ``square`` and ``cube`` function?
+   * This is Good!
 
-We can use ``functools.partial`` to *partially* evaluate the function, giving us a specialized version:
+   * If code is hard to test -- it probably should be refactored.
 
-square = partial(power, exponent=2)
-cube = partial(power, exponent=3)
 
-===
-LAB
-===
 
-Let's use some of this ability to use functions a objects for something useful:
+Material to review for next week
+--------------------------------
 
-:ref:`exercise_trapezoidal_rule`
+Next week, we'll get started on Object Oriented Methods. It's a good idea to read up on it first -- so we can dive right in:
 
-Some reading on these topics:
+ * Dive into Python3: 7.2 -- 7.3
+   http://www.diveintopython3.net/iterators.html#defining-classes
 
-http://www.pydanny.com/python-partials-are-fun.html
+ * Think Python: 15 -- 18
+   http://www.greenteapress.com/thinkpython/html/thinkpython016.html
 
-https://pymotw.com/2/functools/
+ * LPTHW: 40 -- 44
+   http://learnpythonthehardway.org/book/ex40.html
 
-http://www.programiz.com/python-programming/closure
+[note that in py3 you don't need to inherit from object]
 
-https://www.clear.rice.edu/comp130/12spring/curry/
+Talk by Raymond Hettinger:
 
-========
-Homework
-========
+Video of talk: https://youtu.be/HTLu2DFOdTg
 
-Finish up the Labs
+Slides: https://speakerdeck.com/pyconslides/pythons-class-development-toolkit-by-raymond-hettinger
 
diff --git a/slides_sources/source/session07.rst b/slides_sources/source/session07.rst
index ac733776..46bbd8e4 100644
--- a/slides_sources/source/session07.rst
+++ b/slides_sources/source/session07.rst
@@ -4,20 +4,16 @@
 Object Oriented Programming
 ***************************
 
-.. rst-class:: medium centered
-
-.. container::
-
-  Classes
-
-  Instances
-
-  Class and instance attributes
-
-  Subclassing
+Lightning Talks today
+---------------------
 
-  Overriding methods
+.. rst-class:: medium
 
+    |
+    | Charles E Robison
+    |
+    | Paul Vosper
+    |
 
 ================
 Review/Questions
@@ -27,65 +23,74 @@ Review of Previous Class
 ------------------------
 
 .. rst-class:: medium
+
   Advanced Argument passing
 
-  Lambda
+  Testing
 
-  Functions as Objects
+Any questions?
 
-Homework review
----------------
+Should I go over my solution(s)?
 
-Homework Questions?
 
-Did you all get a trapedzoidal rule function working?
+Notes from homework:
+--------------------
 
-Anyone get the "passing through of arguments"?
+**chaining or...**
 
-How about the adaptive solutions?
+Consider this:
 
+``elif selection == '3' or 'exit':``
 
-Notes on Floating point
------------------------
+Careful here: you want to check if selection is '3' or 'exit', but that is no quite what this means:
 
-Did anyone look at the isclose() function?
+You want:
 
-How to make a range of numbers in floating point?
+``(selection == '3') or (selection == 'exit')``
 
-Anyone do something like this?:
+== has higher precedence than or, so you don't need the parentheses.
 
-.. code-block:: python
+``selection == '3' or selection == 'exit'``
 
-  s = []
-  x = a
-  while x <= b:
-      s.append(x)
-      x += delta_x
+That feels like more typing, but that's what you have to do.
 
-  -- see my solution.
+.. nextslide::
 
-Some notes about FP issues:
+So what does the first version mean?
 
-https://docs.python.org/3.5/tutorial/floatingpoint.html
+It would return true for '3', but would never fail. Due to operator precedence, it is:
 
-Code Review
------------
+``(selection == '3') or 'exit'``
 
-Anyone unsatisfied with their solution -- or stuck?
+so first it's checking if selection == '3', which will return True or False.
 
-Let's do a code review!
+Then it does the or: ``True or 'exit'`` or ``False or 'exit'``
 
+``or`` returns the first "truthy" value it finds, to it will return either True or 'exit', regardless of the value of selection. 'exit' is truthy, so this if clause will always run.
 
-Lightning Talks Today:
------------------------
+(let's try this out in iPython)
 
-.. rst-class:: medium
 
- Eric Vegors
+===========================
+Object Oriented Programming
+===========================
+
+.. rst-class:: medium centered
+
+.. container::
+
+  Classes
+
+  Instances
+
+  Class and instance attributes
+
+  Subclassing
+
+  Overriding methods
+
 
- Ian Cote
 
- Masako Tebbetts
 
 ===========================
 Object Oriented Programming
@@ -142,7 +147,8 @@ Python is a Dynamic Language
 That clashes with "pure" OO
 
 Think in terms of what makes sense for your project
- -- not any one paradigm of software design.
+
+-- not any one paradigm of software design.
 
 
 .. nextslide::
@@ -341,8 +347,10 @@ Does this look familiar from C-style procedural programming?
 
 .. nextslide::
 
-Anything assigned to a ``self.``  attribute is kept in the instance
-name space -- ``self`` *is* the instance.
+Anything assigned to a ``self``  attribute is kept in the instance
+name space
+
+-- ``self`` *is* the instance.
 
 That's where all the instance-specific data is.
 
@@ -422,6 +430,9 @@ Huh???? I only gave 2
 
 LAB
 ----
+.. rst-class:: medium
+
+  We now know enough to do something useful.
 
 Let's say you need to render some html...
 
@@ -445,12 +456,11 @@ Lightning Talks
 
 .. rst-class:: medium
 
-|
-| Eric Vegors
-|
-| Ian Cote
-|
-| Masako Tebbetts
+    |
+    | Charles E Robisons
+    |
+    | Paul Vosper
+    |
 
 =======================
 Subclassing/Inheritance
@@ -537,7 +547,7 @@ Here's a program design suggestion:
 
 """
 
-Whenever you override a method, the interface of the new method should be the same as the old.  It should takethe same parameters, return the same type, and obey the same preconditions and postconditions.
+Whenever you override a method, the interface of the new method should be the same as the old.  It should take the same parameters, return the same type, and obey the same preconditions and postconditions.
 
 If you obey this rule, you will find that any function designed to work with an instance of a superclass, like a Deck, will also work with instances of subclasses like a Hand or PokerHand.  If you violate this rule, your code will collapse like (sorry) a house of cards.
 
@@ -605,7 +615,7 @@ When to Subclass
 
 .. nextslide::
 
-"Is a" vs "Has a"
+"**Is** a" vs "**Has** a"**
 
 You may have a class that needs to accumulate an arbitrary number of objects.
 
@@ -736,16 +746,17 @@ LAB
 
     * html renderer: let's see how much more we can do!
 
-:ref:`exercise_html_renderer`
+.. rst-class:: left
 
+    :ref:`exercise_html_renderer`
 
-Now we have a base class, and we can:
+    Now we have a base class, and we can:
 
-* Subclass overriding class attributes
-* Subclass overriding a method
-* Subclass overriding the ``__init__``
+    * Subclass overriding class attributes
+    * Subclass overriding a method
+    * Subclass overriding the ``__init__``
 
-These are the core OO approaches
+    These are the core OO approaches
 
 
 ===================
@@ -838,7 +849,7 @@ Where do you put a Platypus?
 
 Real World Example: `FloatCanvas`_
 
-.. _FloatCanvas: https://github.com/svn2github/wxPython/blob/master/3rdParty/FloatCanvas/floatcanvas/FloatCanvas.py#L485
+.. _FloatCanvas: https://github.com/wxWidgets/wxPython/blob/master/wx/lib/floatcanvas/FloatCanvas.py#L485
 
 
 ``super()``
@@ -893,7 +904,7 @@ Homework
 
 Complete your html renderer.
 
-Watch those videos:
+Watch these videos:
 
 Python class toolkit: *Raymond Hettinger* -- https://youtu.be/HTLu2DFOdTg
 
diff --git a/slides_sources/source/session08.rst b/slides_sources/source/session08.rst
index 66eec310..609a26e1 100644
--- a/slides_sources/source/session08.rst
+++ b/slides_sources/source/session08.rst
@@ -1,8 +1,8 @@
 .. include:: include.rst
 
-**************************************************************************
+****************************************************
 Session Eight: More OO: Properties, Special methods.
-**************************************************************************
+****************************************************
 
 
 ================
@@ -25,9 +25,11 @@ Lightning Talks Today:
 
 .. rst-class:: medium
 
-  Robert Ryan Leslie
+  Paul Briant
 
-  Ryan Morin
+  Jay Raina
+
+  Josh Hicks
 
 
 Personal Project
@@ -44,7 +46,7 @@ The bulk of the homework for the rest of the class will be a personal project:
 * I don't require any specific python features (i.e. classes): use
   what is appropriate for your project
 
-* Due the Friday after the last class (December 11)
+* Due the Sunday after the last class (December 11)
 
 |
 |  By next week, send me a project proposal: short and sweet.
@@ -71,13 +73,183 @@ And there is no need to check if it's empty before trying to loop through it.
 
 no need for ``!= {}`` -- an empty dict is "Falsey"
 
-**but** no need for that check at all. If the dict (or ist, or tuple) is
+**but** no need for that check at all. If the dict (or list, or tuple) is
 empty, then the loop is a do-nothing operation:
 
-* notes on Duck Typing: :ref:`exercise_html_renderer` and  code review
+.. code-block:: python
+
+    for key, value in self.attributes.items():
+        self.atts += ' {}="{}"'.format(key, value)
+
+will not run if self.attributes is an empty dict.
+
+
+Dynamic typing and class attributes
+-----------------------------------
+
+* what happens if we change a class attribute after creating instances??
+
+  - let's try ``Element.indent`` ...
+
+* setting an instance attribute overwrites class attributes:
+
+``self.tag =`` overrights the class attribute (sort of!)
+
+Let's experiment with that.
+
+
+dict as switch
+--------------
+
+.. rst-class:: medium
+
+  What to use instead of "switch-case"?
+
+A number of languages have a "switch-case" construct::
+
+    switch(argument) {
+        case 0:
+            return "zero";
+        case 1:
+            return "one";
+        case 2:
+            return "two";
+        default:
+            return "nothing";
+    };
+
+How do you spell this in python?
+
+``if-elif`` chains
+-------------------
+
+The obvious way to spell it is a chain of ``elif`` statements:
+
+.. code-block:: python
+
+    if argument ==  0:
+        return "zero"
+    elif argument == 1:
+        return "one"
+    elif argument == 2:
+        return "two"
+    else:
+        return "nothing"
+
+And there is nothing wrong with that, but....
+
+.. nextslide::
+
+The ``elif`` chain is neither elegant nor efficient.
+
+There are a number of ways to spell it in python -- one elegant one is to use a dict:
+
+.. code-block:: python
+
+    arg_dict = {0:"zero", 1:"one", 2: "two"}
+        dict.get(argument, "nothing")
+
+Simple, elegant, and fast.
+
+You can do a dispatch table by putting functions as the value.
+
+Example: Chris' mailroom2 solution.
+
+Polymorphism as switch:
+-----------------------
+
+It turns out that a lot of uses of switch-case in non-OO languages is to
+change behaviour depending on teh type of object being worked on::
+
+    switch(object.tag) {
+        case 'html':
+            render_html_element;
+        case 'p':
+            render_p_element;
+    ...
+
+I saw some of this in the html renderer:
+
+.. nextslide::
+
+.. code-block:: python
+
+     def render(out_file, ind=""):
+         ....
+         if self.tag == 'html':
+             tag = ""
+             end_tag = ""
+         elif self.tag == 'p':
+             tag = ""
+             end_tag = " "
+
+This will work, of course, but:
+
+* it means you need to know every tag that you might render when you write this render method.
+
+* In a more complex system, you will need to go update all sorts of things all over teh place when you add a tag.
+
+* It means anyone extending the system with more tags needs to edit the core base class.
+
+Polymorphism
+------------
+
+The alternative is to use polymorphism:
+
+Your ``render()`` method doesn't need to know what all the objects are
+that it may need to render.
+
+All it needs to know is that they all will have a method
+that does the right thing.
+
+So the above becomes, simply:
+
+.. code-block:: python
+
+     def render(out_file, ind=""):
+         ....
+         tag, end_tag = self.make_tags()
+
+This is known as polymorphism, because many different objects are behave
+the same way.
+
+.. nextslide::
+
+This is usally handled by subclassing, so they all get all teh same
+methods by default, and you only need to specialize the ones that need it.
+
+But in Python -- it can be done with duck-typing instead, as the TextWrapper example.
+
+Duck typing and EAFP
+--------------------
+
+* notes on Duck Typing: :ref:`exercise_html_renderer`
+
+* put the ``except`` as close as you can to where you expect an exception to be raised!
+
+* Let's look at a couple ways to do that.
+
+Code Review
+-----------
 
 * anyone stuck that wants to work through your code?
 
+* And/or go through mine...
+
+Lightning Talks:
+----------------
+
+.. rst-class:: medium
+
+  |
+  | Paul Briant
+  |
+  | Jay Raina
+  |
+  |  Josh Hicks
+
+
+
 ==========
 Properties
 ==========
@@ -138,6 +310,7 @@ But what if you need to add behavior later?
 
 .. _Java: http://dirtsimple.org/2004/12/python-is-not-java.html
 
+
 properties
 -----------
 
@@ -242,15 +415,6 @@ For now, Let's do steps 1-4 of:
 
 :ref:`exercise_circle_class`
 
-Lightning talks:
------------------
-
-.. rst-class:: medium
-
-  Robert Ryan Leslie
-
-  Ryan Morin
-
 
 ========================
 Static and Class Methods
@@ -268,7 +432,6 @@ Static and Class Methods
     And you've seen how you can call *unbound* methods on a class object so
     long as you pass an instance of that class as the first argument.
 
-    |
 
     .. rst-class:: centered
 
@@ -537,8 +700,11 @@ implement ``__add__``:
 
 .. rst-class:: centered
 
-[a more complete example may be seen :download:`here <../../Examples/Session08/vector.py>`]
+A more complete example may be seen in:
 
+Examples/Session08/vector.py
+
+or: :download:`here <../../Examples/Session08/vector.py>`
 
 .. nextslide:: Summary
 
@@ -550,7 +716,7 @@ Look up the special methods you need and define them.
 There's more to read about the details of implementing these methods:
 
 * https://docs.python.org/3.5/reference/datamodel.html#special-method-names
-* http://www.rafekettler.com/magicmethods.html
+* https://github.com/RafeKettler/magicmethods/blob/master/magicmethods.markdown
 
 ===
 LAB
@@ -691,7 +857,7 @@ https://docs.python.org/3/reference/datamodel.html#emulating-container-types
 
 and
 
-http://www.rafekettler.com/magicmethods.html#sequence
+https://github.com/RafeKettler/magicmethods/blob/master/magicmethods.markdown#sequence
 
 The key ones are:
 
@@ -747,6 +913,14 @@ Homework
 
 .. rst-class:: left
 
+  Reading:
+
+  Lambda:
+
+  http://www.blog.pythonlibrary.org/2015/10/28/python-101-lambda-basics/
+
+  https://pythonconquerstheuniverse.wordpress.com/2011/08/29/lambda_tutorial/
+
   Complete the Circle class
 
   Complete the Sparse Array class
diff --git a/slides_sources/source/session09.rst b/slides_sources/source/session09.rst
index 550ff50f..e6d953d7 100644
--- a/slides_sources/source/session09.rst
+++ b/slides_sources/source/session09.rst
@@ -1,37 +1,241 @@
 .. include:: include.rst
 
-**************************************************
-Session Nine: Iterators, Iterables, and Generators
-**************************************************
+************************************************************
+Anonymous Functions and Iterators, Iterables, and Generators
+************************************************************
 
-.. rst-class:: large centered
+====================
+Lightning Talks Now:
+====================
+
+.. rst-class:: medium
+
+    Jack M Hefner
+
+    Ninad Naik
+
+    Simbarashe P Change
+
+
+===================
+Anonymous functions
+===================
+
+lambda
+------
+
+.. code-block:: ipython
+
+    In [171]: f = lambda x, y: x+y
+    In [172]: f(2,3)
+    Out[172]: 5
+
+Content of function can only be an expression -- not a statement
+
+Anyone remember what the difference is?
+
+Called "Anonymous": it doesn't get a name.
+
+.. nextslide::
+
+It's a python object, it can be stored in a list or other container
+
+.. code-block:: ipython
+
+    In [7]: l = [lambda x, y: x+y]
+    In [8]: type(l[0])
+    Out[8]: function
+
+
+And you can call it:
+
+.. code-block:: ipython
+
+    In [9]: l[0](3,4)
+    Out[9]: 7
+
+
+Functions as first class objects
+---------------------------------
+
+You can do that with "regular" functions too:
+
+.. code-block:: ipython
+
+    In [12]: def fun(x,y):
+       ....:     return x+y
+       ....:
+    In [13]: l = [fun]
+    In [14]: type(l[0])
+    Out[14]: function
+    In [15]: l[0](3,4)
+    Out[15]: 7
 
-The tools of Pythonicity
 
 
 ======================
-Lightning Talks Today:
+Functional Programming
 ======================
 
-.. rst-class:: medium
+No real consensus about what that means.
+
+But there are some "classic" methods available in Python.
+
+map
+---
+
+``map``  "maps" a function onto a sequence of objects -- It applies the function to each item in the list, returning another list
+
+
+.. code-block:: ipython
+
+    In [23]: l = [2, 5, 7, 12, 6, 4]
+    In [24]: def fun(x):
+                 return x*2 + 10
+    In [25]: map(fun, l)
+    Out[25]: