M python 2/koans/__init__.py +1 -1
@@ 1,4 1,4 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-# koans
No newline at end of file
+# koans
M python 2/koans/about_asserts.py +8 -7
@@ 3,14 3,15 @@
from runner.koan import *
+
class AboutAsserts(Koan):
def test_assert_truth(self):
"""
We shall contemplate truth by testing reality, via asserts.
"""
- self.assertTrue(False) # This should be true
-
+ self.assertTrue(False) # This should be true
+
def test_assert_with_message(self):
"""
Enlightenment may be more easily achieved with appropriate messages.
@@ 25,7 26,8 @@ class AboutAsserts(Koan):
def test_assert_equality(self):
"""
- To understand reality, we must compare our expectations against reality.
+ To understand reality, we must compare our expectations against
+ reality.
"""
expected_value = __
actual_value = 1 + 1
@@ 37,14 39,13 @@ class AboutAsserts(Koan):
"""
expected_value = __
actual_value = 1 + 1
-
+
self.assertEqual(expected_value, actual_value)
-
+
def test_that_unittest_asserts_work_the_same_way_as_python_asserts(self):
"""
Knowing how things really work is half the battle
"""
-
+
# This throws an AssertionError exception
assert False
-
M python 2/koans/about_attribute_access.py +68 -60
@@ 7,20 7,21 @@
from runner.koan import *
+
class AboutAttributeAccess(Koan):
-
+
class TypicalObject(object):
pass
-
+
def test_calling_undefined_functions_normally_results_in_errors(self):
typical = self.TypicalObject()
-
+
try:
typical.foobar()
except Exception as exception:
self.assertEqual(__, type(exception).__name__)
self.assertMatch(__, exception[0])
-
+
def test_calling_getattribute_causes_an_attribute_error(self):
typical = self.TypicalObject()
@@ 28,109 29,114 @@ class AboutAttributeAccess(Koan):
typical.__getattribute__('foobar')
except AttributeError as exception:
self.assertMatch(__, exception[0])
-
+
# THINK ABOUT IT:
#
# If the method __getattribute__() causes the AttributeError, then
# what would happen if we redefine __getattribute__()?
-
+
# ------------------------------------------------------------------
-
+
class CatchAllAttributeReads(object):
def __getattribute__(self, attr_name):
- return "Someone called '" + attr_name + "' and it could not be found"
-
+ return "Someone called '" + attr_name + \
+ "' and it could not be found"
+
def test_all_attribute_reads_are_caught(self):
catcher = self.CatchAllAttributeReads()
-
+
self.assertMatch(__, catcher.foobar)
def test_intercepting_return_values_can_disrupt_the_call_chain(self):
catcher = self.CatchAllAttributeReads()
- self.assertMatch(__, catcher.foobaz) # This is fine
-
+ self.assertMatch(__, catcher.foobaz) # This is fine
+
try:
catcher.foobaz(1)
except TypeError as ex:
self.assertMatch(__, ex[0])
-
+
# foobaz returns a string. What happens to the '(1)' part?
# Try entering this into a python console to reproduce the issue:
#
# "foobaz"(1)
- #
-
- def test_changes_to_the_getattribute_implementation_affects_getattr_function(self):
+ #
+
+ def test_changing_getattribute_will_affect__the_getattr_function(self):
catcher = self.CatchAllAttributeReads()
-
+
self.assertMatch(__, getattr(catcher, 'any_attribute'))
-
+
# ------------------------------------------------------------------
-
+
class WellBehavedFooCatcher(object):
def __getattribute__(self, attr_name):
if attr_name[:3] == "foo":
return "Foo to you too"
else:
- return super(AboutAttributeAccess.WellBehavedFooCatcher, self). \
+ return \
+ super(AboutAttributeAccess.WellBehavedFooCatcher, self). \
__getattribute__(attr_name)
-
+
def test_foo_attributes_are_caught(self):
catcher = self.WellBehavedFooCatcher()
-
+
self.assertEqual(__, catcher.foo_bar)
self.assertEqual(__, catcher.foo_baz)
-
+
def test_non_foo_messages_are_treated_normally(self):
catcher = self.WellBehavedFooCatcher()
-
+
try:
catcher.normal_undefined_attribute
except AttributeError as ex:
self.assertMatch(__, ex[0])
# ------------------------------------------------------------------
-
+
global stack_depth
- stack_depth = 0
+ stack_depth = 0
class RecursiveCatcher(object):
def __init__(self):
global stack_depth
- stack_depth = 0
+ stack_depth = 0
self.no_of_getattribute_calls = 0
-
+
def __getattribute__(self, attr_name):
#Uncomment for debugging info:
- #print 'Debug __getattribute__(' + type(self).__name__ + "." + attr_name + ") dict=" + str(self.__dict__)
-
- global stack_depth # We need something that is outside the scope of this class
+ #print 'Debug __getattribute__(' + type(self).__name__ + \
+ # "." + attr_name + ") dict=" + str(self.__dict__)
+
+ # We need something that is outside the scope of this class:
+ global stack_depth
stack_depth += 1
- if stack_depth<=10: # to prevent a stack overflow
+ if stack_depth <= 10: # to prevent a stack overflow
self.no_of_getattribute_calls += 1
- # Oops! We just accessed an attribute (no_of_getattribute_calls)
+ # Oops! We just accessed an attribute: no_of_getattribute_calls
# Guess what happens when self.no_of_getattribute_calls is
- # accessed?
+ # accessed?
# Using 'object' directly because using super() here will also
# trigger a __getattribute__() call.
- return object.__getattribute__(self, attr_name)
-
+ return object.__getattribute__(self, attr_name)
+
def my_method(self):
pass
-
+
def test_getattribute_is_a_bit_overzealous_sometimes(self):
catcher = self.RecursiveCatcher()
catcher.my_method()
global stack_depth
self.assertEqual(__, stack_depth)
-
+
# ------------------------------------------------------------------
class MinimalCatcher(object):
- class DuffObject(object): pass
+ class DuffObject(object):
+ pass
def __init__(self):
self.no_of_getattr_calls = 0
@@ 138,7 144,7 @@ class AboutAttributeAccess(Koan):
def __getattr__(self, attr_name):
self.no_of_getattr_calls += 1
return self.DuffObject
-
+
def my_method(self):
pass
@@ 147,62 153,64 @@ class AboutAttributeAccess(Koan):
catcher.my_method()
self.assertEqual(__, catcher.no_of_getattr_calls)
-
+
def test_getattr_only_catches_unknown_attributes(self):
catcher = self.MinimalCatcher()
catcher.purple_flamingos()
catcher.free_pie()
-
+
self.assertEqual(__,
type(catcher.give_me_duff_or_give_me_death()).__name__)
-
+
self.assertEqual(__, catcher.no_of_getattr_calls)
-
+
# ------------------------------------------------------------------
class PossessiveSetter(object):
def __setattr__(self, attr_name, value):
- new_attr_name = attr_name
-
+ new_attr_name = attr_name
+
if attr_name[-5:] == 'comic':
new_attr_name = "my_" + new_attr_name
elif attr_name[-3:] == 'pie':
- new_attr_name = "a_" + new_attr_name
+ new_attr_name = "a_" + new_attr_name
- object.__setattr__(self, new_attr_name, value)
+ object.__setattr__(self, new_attr_name, value)
def test_setattr_intercepts_attribute_assignments(self):
fanboy = self.PossessiveSetter()
-
+
fanboy.comic = 'The Laminator, issue #1'
fanboy.pie = 'blueberry'
-
- self.assertEqual(__, fanboy.a_pie)
+
+ self.assertEqual(__, fanboy.a_pie)
prefix = '__'
- self.assertEqual("The Laminator, issue #1", getattr(fanboy, prefix + '_comic'))
+ self.assertEqual(
+ "The Laminator, issue #1",
+ getattr(fanboy, prefix + '_comic'))
# ------------------------------------------------------------------
- class ScarySetter(object):
+ class ScarySetter(object):
def __init__(self):
self.num_of_coconuts = 9
self._num_of_private_coconuts = 2
-
+
def __setattr__(self, attr_name, value):
- new_attr_name = attr_name
-
+ new_attr_name = attr_name
+
if attr_name[0] != '_':
new_attr_name = "altered_" + new_attr_name
-
+
object.__setattr__(self, new_attr_name, value)
-
+
def test_it_modifies_external_attribute_as_expected(self):
setter = self.ScarySetter()
setter.e = "mc hammer"
-
+
self.assertEqual(__, setter.altered_e)
-
+
def test_it_mangles_some_internal_attributes(self):
setter = self.ScarySetter()
M python 2/koans/about_class_attributes.py +38 -36
@@ 7,44 7,45 @@
from runner.koan import *
+
class AboutClassAttributes(Koan):
class Dog(object):
pass
-
+
def test_new_style_class_objects_are_objects(self):
# Note: Old style class instances are not objects but they are being
# phased out it Python 3.
-
+
fido = self.Dog()
self.assertEqual(__, isinstance(fido, object))
def test_classes_are_types(self):
- self.assertEqual(__, self.Dog.__class__ == type)
-
+ self.assertEqual(__, self.Dog.__class__ == type)
+
def test_classes_are_objects_too(self):
self.assertEqual(__, issubclass(self.Dog, object))
-
+
def test_objects_have_methods(self):
fido = self.Dog()
self.assertEqual(__, len(dir(fido)))
-
+
def test_classes_have_methods(self):
self.assertEqual(__, len(dir(self.Dog)))
def test_creating_objects_without_defining_a_class(self):
- singularity = object()
+ singularity = object()
self.assertEqual(__, len(dir(singularity)))
def test_defining_attributes_on_individual_objects(self):
fido = self.Dog()
fido.legs = 4
-
+
self.assertEqual(__, fido.legs)
-
+
def test_defining_functions_on_individual_objects(self):
fido = self.Dog()
- fido.wag = lambda : 'fidos wag'
-
+ fido.wag = lambda: 'fidos wag'
+
self.assertEqual(__, fido.wag())
def test_other_objects_are_not_affected_by_these_singleton_functions(self):
@@ 52,16 53,16 @@ class AboutClassAttributes(Koan):
rover = self.Dog()
def wag():
- return 'fidos wag'
+ return 'fidos wag'
fido.wag = wag
-
+
try:
rover.wag()
except Exception as ex:
self.assertMatch(__, ex[0])
-
+
# ------------------------------------------------------------------
-
+
class Dog2(object):
def wag(self):
return 'instance wag'
@@ 75,14 76,14 @@ class AboutClassAttributes(Koan):
@staticmethod
def bark():
return "staticmethod bark, arg: None"
-
+
@classmethod
def growl(cls):
- return "classmethod growl, arg: cls=" + cls.__name__
-
- def test_since_classes_are_objects_you_can_define_singleton_methods_on_them_too(self):
+ return "classmethod growl, arg: cls=" + cls.__name__
+
+ def test_like_all_objects_classes_can_have_singleton_methods(self):
self.assertMatch(__, self.Dog2.growl())
-
+
def test_classmethods_are_not_independent_of_instance_methods(self):
fido = self.Dog2()
self.assertMatch(__, fido.growl())
@@ 94,9 95,9 @@ class AboutClassAttributes(Koan):
def test_staticmethods_also_overshadow_instance_methods(self):
fido = self.Dog2()
self.assertMatch(__, fido.bark())
-
+
# ------------------------------------------------------------------
-
+
class Dog3(object):
def __init__(self):
self._name = None
@@ 106,40 107,41 @@ class AboutClassAttributes(Koan):
def set_name_from_instance(self, name):
self._name = name
-
- @classmethod
+
+ @classmethod
def get_name(cls):
return cls._name
- @classmethod
+ @classmethod
def set_name(cls, name):
cls._name = name
-
+
name = property(get_name, set_name)
- name_from_instance = property(get_name_from_instance, set_name_from_instance)
-
+ name_from_instance = property(
+ get_name_from_instance, set_name_from_instance)
+
def test_classmethods_can_not_be_used_as_properties(self):
fido = self.Dog3()
try:
fido.name = "Fido"
except Exception as ex:
self.assertMatch(__, ex[0])
-
+
def test_classes_and_instances_do_not_share_instance_attributes(self):
fido = self.Dog3()
fido.set_name_from_instance("Fido")
fido.set_name("Rover")
self.assertEqual(__, fido.get_name_from_instance())
self.assertEqual(__, self.Dog3.get_name())
-
+
def test_classes_and_instances_do_share_class_attributes(self):
fido = self.Dog3()
fido.set_name("Fido")
self.assertEqual(__, fido.get_name())
self.assertEqual(__, self.Dog3.get_name())
-
+
# ------------------------------------------------------------------
-
+
class Dog4(object):
def a_class_method(cls):
return 'dogs class method'
@@ 149,15 151,15 @@ class AboutClassAttributes(Koan):
a_class_method = classmethod(a_class_method)
a_static_method = staticmethod(a_static_method)
-
+
def test_you_can_define_class_methods_without_using_a_decorator(self):
self.assertEqual(__, self.Dog4.a_class_method())
def test_you_can_define_static_methods_without_using_a_decorator(self):
self.assertEqual(__, self.Dog4.a_static_method())
-
+
# ------------------------------------------------------------------
-
- def test_heres_an_easy_way_to_explicitly_call_class_methods_from_instance_methods(self):
+
+ def test_you_can_explicitly_call_class_methods_from_instance_methods(self):
fido = self.Dog4()
self.assertEqual(__, fido.__class__.a_class_method())
M python 2/koans/about_control_statements.py +13 -12
@@ 3,6 3,7 @@
from runner.koan import *
+
class AboutControlStatements(Koan):
def test_if_then_else_statements(self):
@@ 17,7 18,7 @@ class AboutControlStatements(Koan):
if True:
result = 'true value'
self.assertEqual(__, result)
-
+
def test_while_statement(self):
i = 1
result = 1
@@ 25,7 26,7 @@ class AboutControlStatements(Koan):
result = result * i
i += 1
self.assertEqual(__, result)
-
+
def test_break_statement(self):
i = 1
result = 1
@@ 34,39 35,39 @@ class AboutControlStatements(Koan):
result = result * i
i += 1
self.assertEqual(__, result)
-
+
def test_continue_statement(self):
i = 0
result = []
while i < 10:
i += 1
if (i % 2) == 0: continue
- result.append(i)
+ result.append(i)
self.assertEqual(__, result)
-
+
def test_for_statement(self):
phrase = ["fish", "and", "chips"]
result = []
for item in phrase:
result.append(item.upper())
self.assertEqual([__, __, __], result)
-
+
def test_for_statement_with_tuples(self):
round_table = [
- ("Lancelot", "Blue"),
+ ("Lancelot", "Blue"),
("Galahad", "I don't know!"),
("Robin", "Blue! I mean Green!"),
("Arthur", "Is that an African Swallow or Amazonian Swallow?")
]
result = []
for knight, answer in round_table:
- result.append("Contestant: '" + knight + "' Answer: '" + answer + "'")
-
+ result.append("Contestant: '" + knight + \
+ "' Answer: '" + answer + "'")
+
text = __
-
+
self.assertMatch(text, result[2])
-
+
self.assertNoMatch(text, result[0])
self.assertNoMatch(text, result[1])
self.assertNoMatch(text, result[3])
-
No newline at end of file
M python 2/koans/about_decorating_with_classes.py +12 -11
@@ 4,10 4,11 @@
from runner.koan import *
import functools
-
+
+
class AboutDecoratingWithClasses(Koan):
def maximum(self, a, b):
- if a>b:
+ if a > b:
return a
else:
return b
@@ 18,9 19,9 @@ class AboutDecoratingWithClasses(Koan):
the partial.
"""
max = functools.partial(self.maximum)
-
- self.assertEqual(__, max(7,23))
- self.assertEqual(__, max(10,-10))
+
+ self.assertEqual(__, max(7, 23))
+ self.assertEqual(__, max(10, -10))
def test_partial_that_wrappers_first_arg(self):
max0 = functools.partial(self.maximum, 0)
@@ 28,7 29,7 @@ class AboutDecoratingWithClasses(Koan):
self.assertEqual(__, max0(-4))
self.assertEqual(__, max0(5))
- def test_partial_that_wrappers_all_args(self):
+ def test_partial_that_wrappers_all_args(self):
always99 = functools.partial(self.maximum, 99, 20)
always20 = functools.partial(self.maximum, 9, 20)
@@ 50,7 51,7 @@ class AboutDecoratingWithClasses(Koan):
return self
else:
# Decorating a bound method
- return functools.partial(self, obj)
+ return functools.partial(self, obj)
@doubleit
def foo(self):
@@ 70,7 71,7 @@ class AboutDecoratingWithClasses(Koan):
# ------------------------------------------------------------------
def sound_check(self):
- #Note: no decorator
+ #Note: no decorator
return "Testing..."
def test_what_a_decorator_is_doing_to_a_function(self):
@@ 98,10 99,11 @@ class AboutDecoratingWithClasses(Koan):
@documenter("Increments a value by one. Kind of.")
def count_badly(self, num):
num += 1
- if num==3:
- return 5
+ if num == 3:
+ return 5
else:
num
+
@documenter("Does nothing")
def idler(self, num):
"Idler"
@@ 125,4 127,3 @@ class AboutDecoratingWithClasses(Koan):
def test_we_can_chain_decorators(self):
self.assertEqual(__, self.homer())
self.assertEqual(__, self.homer.__doc__)
-
No newline at end of file
M python 2/koans/about_decorating_with_functions.py +1 -2
@@ 15,7 15,7 @@ class AboutDecoratingWithFunctions(Koan)
def test_decorators_can_modify_a_function(self):
self.assertMatch(__, self.mediocre_song())
- self.assertEqual(__, self.mediocre_song.wow_factor)
+ self.assertEqual(__, self.mediocre_song.wow_factor)
# ------------------------------------------------------------------
@@ 30,4 30,3 @@ class AboutDecoratingWithFunctions(Koan)
def test_decorators_can_change_a_function_output(self):
self.assertEqual(__, self.render_tag('llama'))
-
M python 2/koans/about_deleting_objects.py +6 -6
@@ 3,6 3,7 @@
from runner.koan import *
+
class AboutDeletingObjects(Koan):
def test_del_can_remove_slices(self):
lottery_nums = [4, 8, 15, 16, 23, 42]
@@ 17,10 18,10 @@ class AboutDeletingObjects(Koan):
try:
win = lottery_nums
except Exception as e:
- pass
+ pass
self.assertMatch(__, e[0])
- # ====================================================================
+ # --------------------------------------------------------------------
class ClosingSale(object):
def __init__(self):
@@ 54,7 55,7 @@ class AboutDeletingObjects(Koan):
self.assertMatch(__, err_msg1)
self.assertMatch(__, err_msg2)
- # ====================================================================
+ # --------------------------------------------------------------------
class ClintEastwood(object):
def __init__(self):
@@ 83,8 84,7 @@ class AboutDeletingObjects(Koan):
del cowboy.name
self.assertEqual(__, cowboy.name)
-
- # ====================================================================
+ # --------------------------------------------------------------------
class Prisoner(object):
def __init__(self):
@@ 110,7 110,7 @@ class AboutDeletingObjects(Koan):
del citizen.name
self.assertEqual(__, citizen.name)
- # ====================================================================
+ # --------------------------------------------------------------------
class MoreOrganisedClosingSale(ClosingSale):
def __init__(self):
M python 2/koans/about_dice_project.py +6 -2
@@ 5,11 5,12 @@ from runner.koan import *
import random
+
class DiceSet(object):
def __init__(self):
self._values = None
- @property
+ @property
def values(self):
return self._values
@@ 18,6 19,7 @@ class DiceSet(object):
# Tip: random.randint(min, max) can be used to generate random numbers
pass
+
class AboutDiceProject(Koan):
def test_can_create_a_dice_set(self):
dice = DiceSet()
@@ 30,7 32,9 @@ class AboutDiceProject(Koan):
self.assertTrue(isinstance(dice.values, list), "should be a list")
self.assertEqual(5, len(dice.values))
for value in dice.values:
- self.assertTrue(value >= 1 and value <= 6, "value " + str(value) + " must be between 1 and 6")
+ self.assertTrue(
+ value >= 1 and value <= 6,
+ "value " + str(value) + " must be between 1 and 6")
def test_dice_values_do_not_change_unless_explicitly_rolled(self):
dice = DiceSet()
M python 2/koans/about_dictionaries.py +15 -12
@@ 7,6 7,7 @@
from runner.koan import *
+
class AboutDictionaries(Koan):
def test_creating_dictionaries(self):
empty_dict = dict()
@@ 15,45 16,47 @@ class AboutDictionaries(Koan):
self.assertEqual(__, len(empty_dict))
def test_dictionary_literals(self):
- babel_fish = { 'one': "uno", 'two': "dos" }
+ babel_fish = {'one': "uno", 'two': "dos"}
self.assertEqual(__, len(babel_fish))
def test_accessing_dictionaries(self):
- babel_fish = { 'one': "uno", 'two': "dos" }
+ babel_fish = {'one': "uno", 'two': "dos"}
self.assertEqual(__, babel_fish['one'])
self.assertEqual(__, babel_fish['two'])
def test_changing_dictionaries(self):
- babel_fish = { 'one': "uno", 'two': "dos" }
+ babel_fish = {'one': "uno", 'two': "dos"}
babel_fish['one'] = "eins"
- expected = { 'two': "dos", 'one': __ }
+ expected = {'two': "dos", 'one': __}
self.assertEqual(expected, babel_fish)
def test_dictionary_is_unordered(self):
- dict1 = { 'one': "uno", 'two': "dos" }
- dict2 = { 'two': "dos", 'one': "uno" }
+ dict1 = {'one': "uno", 'two': "dos"}
+ dict2 = {'two': "dos", 'one': "uno"}
self.assertEqual(____, dict1 == dict2)
def test_dictionary_keys(self):
- babel_fish = { 'one': "uno", 'two': "dos" }
+ babel_fish = {'one': "uno", 'two': "dos"}
self.assertEqual(__, len(babel_fish.keys()))
- self.assertEqual(__, 'one' in babel_fish)
- self.assertEqual(__, 'two' in babel_fish)
+ self.assertEqual(__, 'one' in babel_fish)
+ self.assertEqual(__, 'two' in babel_fish)
self.assertEqual(list, babel_fish.keys().__class__)
def test_dictionary_values(self):
- babel_fish = { 'one': "uno", 'two': "dos" }
+ babel_fish = {'one': "uno", 'two': "dos"}
self.assertEqual(__, len(babel_fish.values()))
self.assertEqual(__, 'uno' in babel_fish.values())
self.assertEqual(__, 'dos' in babel_fish.values())
self.assertEqual(list, babel_fish.values().__class__)
def test_making_a_dictionary_from_a_sequence_of_keys(self):
- cards = {}.fromkeys(("red warrior", "green elf", "blue valkyrie", "yellow dwarf", "confused looking zebra"), 42)
+ cards = {}.fromkeys(
+ ("red warrior", "green elf", "blue valkyrie", "yellow dwarf",
+ "confused looking zebra"),
+ 42)
self.assertEqual(__, len(cards))
self.assertEqual(__, cards["green elf"])
self.assertEqual(__, cards["yellow dwarf"])
-
M python 2/koans/about_exceptions.py +1 -0
@@ 3,6 3,7 @@
from runner.koan import *
+
class AboutExceptions(Koan):
class MySpecialError(RuntimeError):
M +1 -1
@@ 12,9 12,9 @@
from runner.koan import *
class AboutExtraCredit(Koan):
# Write tests here. If you need extra test classes add them to the
# test suite in runner/path_to_enlightenment.py
def test_extra_credit_task(self):
pass
No newline at end of file
M python 2/koans/about_generators.py +14 -13
@@ 10,28 10,31 @@
from runner.koan import *
+
class AboutGenerators(Koan):
def test_generating_values_on_the_fly(self):
result = list()
- bacon_generator = (n + ' bacon' for n in ['crunchy','veggie','danish'])
+ bacon_generator = (n + ' bacon' for \
+ n in ['crunchy', 'veggie', 'danish'])
for bacon in bacon_generator:
result.append(bacon)
self.assertEqual(__, result)
def test_generators_are_different_to_list_comprehensions(self):
- num_list = [x*2 for x in range(1,3)]
- num_generator = (x*2 for x in range(1,3))
+ num_list = [x * 2 for x in range(1, 3)]
+ num_generator = (x * 2 for x in range(1, 3))
self.assertEqual(2, num_list[0])
# A generator has to be iterated through.
- self.assertRaises(___, num_generator, [0]) # Evaluates num_generator[0]
- self.assertEqual(__, list(num_generator)[0]) # This works though
+ self.assertRaises(___, num_generator, [0]) # Evaluates num_generator[0]
+ self.assertEqual(__, list(num_generator)[0]) # This works though
- # Both list comprehensions and generators can be iterated though. However, a generator
- # function is only called on the first iteration. The values are generated on the fly
- # instead of stored.
+ # Both list comprehensions and generators can be iterated
+ # though. However, a generator function is only called on the
+ # first iteration. The values are generated on the fly instead
+ # of stored.
#
# Generators are more memory friendly, but less versatile
@@ 71,7 74,7 @@ class AboutGenerators(Koan):
yield x * x
def test_generator_method_with_parameter(self):
- result = self.square_me(range(2,5))
+ result = self.square_me(range(2, 5))
self.assertEqual(__, list(result))
# ------------------------------------------------------------------
@@ 84,7 87,7 @@ class AboutGenerators(Koan):
yield value
def test_generator_keeps_track_of_local_variables(self):
- result = self.sum_it(range(2,5))
+ result = self.sum_it(range(2, 5))
self.assertEqual(__, list(result))
# ------------------------------------------------------------------
@@ 109,7 112,7 @@ class AboutGenerators(Koan):
generator = self.generator_with_coroutine()
try:
- generator.send(1+2)
+ generator.send(1 + 2)
except TypeError as ex:
self.assertMatch(__, ex[0])
@@ 137,5 140,3 @@ class AboutGenerators(Koan):
next(generator)
# 'next(generator)' is exactly equivelant to 'generator.send(None)'
self.assertEqual(__, generator.send(None))
-
-
M python 2/koans/about_inheritance.py +5 -4
@@ 3,9 3,10 @@
from runner.koan import *
+
class AboutInheritance(Koan):
class Dog(object):
- def __init__(self, name):
+ def __init__(self, name):
self._name = name
@property
@@ 72,11 73,11 @@ class AboutInheritance(Koan):
# ---------------------------------------------------------
class Pug(Dog):
- def __init__(self, name):
+ def __init__(self, name):
pass
class Greyhound(Dog):
- def __init__(self, name):
+ def __init__(self, name):
super(AboutInheritance.Greyhound, self).__init__(name)
def test_base_init_does_not_get_called_automatically(self):
@@ 88,4 89,4 @@ class AboutInheritance(Koan):
def test_base_init_has_to_be_called_explicitly(self):
boxer = self.Greyhound("Boxer")
- self.assertEqual(__, boxer.name)
No newline at end of file
+ self.assertEqual(__, boxer.name)
M python 2/koans/about_iteration.py +10 -8
@@ 3,20 3,21 @@
from runner.koan import *
+
class AboutIteration(Koan):
def test_iterators_are_a_type(self):
- it = iter(range(1,6))
+ it = iter(range(1, 6))
fib = 0
for num in it:
fib += num
- self.assertEqual(__ , fib)
+ self.assertEqual(__, fib)
def test_iterating_with_next(self):
- stages = iter(['alpha','beta','gamma'])
+ stages = iter(['alpha', 'beta', 'gamma'])
try:
self.assertEqual(__, next(stages))
@@ 73,10 74,10 @@ class AboutIteration(Koan):
return accum * item
def test_reduce_will_blow_your_mind(self):
- result = reduce(self.add, [2, 3, 4])
+ result = reduce(self.add, [2, 3, 4])
self.assertEqual(__, result)
- result2 = reduce(self.multiply, [2, 3, 4], 1)
+ result2 = reduce(self.multiply, [2, 3, 4], 1)
self.assertEqual(__, result2)
# Extra Credit:
@@ 85,7 86,8 @@ class AboutIteration(Koan):
# ------------------------------------------------------------------
def test_creating_lists_with_list_comprehensions(self):
- feast = ['lambs', 'sloths', 'orangutans', 'breakfast cereals', 'fruit bats']
+ feast = ['lambs', 'sloths', 'orangutans', 'breakfast cereals',
+ 'fruit bats']
comprehension = [delicacy.capitalize() for delicacy in feast]
@@ 93,7 95,7 @@ class AboutIteration(Koan):
self.assertEqual(__, comprehension[2])
def test_use_pass_for_iterations_with_no_body(self):
- for num in range(1,5):
+ for num in range(1, 5):
pass
self.assertEqual(__, num)
@@ 102,7 104,7 @@ class AboutIteration(Koan):
def test_all_iteration_methods_work_on_any_sequence_not_just_lists(self):
# Ranges are an iteratable sequence
- result = map(self.add_ten, range(1,4))
+ result = map(self.add_ten, range(1, 4))
self.assertEqual(__, list(result))
try:
M python 2/koans/about_lambdas.py +1 -0
@@ 7,6 7,7 @@
from runner.koan import *
+
class AboutLambdas(Koan):
def test_lambdas_can_be_assigned_to_variables_and_called_explicitly(self):
add_one = lambda n: n + 1
M python 2/koans/about_list_assignments.py +1 -0
@@ 7,6 7,7 @@
from runner.koan import *
+
class AboutListAssignments(Koan):
def test_non_parallel_assignment(self):
names = ["John", "Smith"]
M python 2/koans/about_lists.py +2 -1
@@ 7,6 7,7 @@
from runner.koan import *
+
class AboutLists(Koan):
def test_creating_lists(self):
empty_list = list()
@@ 68,7 69,7 @@ class AboutLists(Koan):
self.assertEqual(__, knight)
knight.insert(0, 'Arthur')
- self.assertEqual(__, knight)
+ self.assertEqual(__, knight)
def test_popping_lists(self):
stack = [10, 20, 30, 40]
M python 2/koans/about_method_bindings.py +8 -5
@@ 3,18 3,22 @@
from runner.koan import *
+
def function():
return "pineapple"
+
def function2():
return "tractor"
+
class Class(object):
def method(self):
- return "parrot"
+ return "parrot"
+
class AboutMethodBindings(Koan):
- def test_methods_are_bound_to_an_object(self):
+ def test_methods_are_bound_to_an_object(self):
obj = Class()
self.assertEqual(__, obj.method.im_self == obj)
@@ 56,7 60,7 @@ class AboutMethodBindings(Koan):
try:
cls = function2.get_fruit.im_self
except AttributeError as ex:
- self.assertMatch(__, ex[0])
+ self.assertMatch(__, ex[0])
# ------------------------------------------------------------------
@@ 88,8 92,7 @@ class AboutMethodBindings(Koan):
color = SuperColor()
- def test_set_descriptor_changes_behavior_of_attribute_assignment_changes(self):
+ def test_set_descriptor_changes_behavior_of_attribute_assignment(self):
self.assertEqual(None, self.color.choice)
self.color = 'purple'
self.assertEqual(__, self.color.choice)
-
M python 2/koans/about_methods.py +17 -13
@@ 7,12 7,14 @@
from runner.koan import *
-def my_global_function(a,b):
+
+def my_global_function(a, b):
return a + b
+
class AboutMethods(Koan):
def test_calling_an_global_function(self):
- self.assertEqual(__, my_global_function(2,3))
+ self.assertEqual(__, my_global_function(2, 3))
# NOTE: Wrong number of arguments is not a SYNTAX error, but a
# runtime error.
@@ 22,15 24,15 @@ class AboutMethods(Koan):
except Exception as exception:
self.assertEqual(__, type(exception).__name__)
self.assertMatch(
- r'my_global_function\(\) takes exactly 2 arguments \(0 given\)'
- , exception[0])
+ r'my_global_function\(\) takes exactly 2 arguments \(0 given\)',
+ exception[0])
try:
my_global_function(1, 2, 3)
except Exception as e:
# Note, watch out for parenthesis. They need slashes in front!
- self.assertMatch(__, e[0])
+ self.assertMatch(__, e[0])
# ------------------------------------------------------------------
@@ 58,7 60,7 @@ class AboutMethods(Koan):
def test_calling_with_variable_arguments(self):
self.assertEqual(__, self.method_with_var_args())
- self.assertEqual(('one',), self.method_with_var_args('one'))
+ self.assertEqual(('one', ), self.method_with_var_args('one'))
self.assertEqual(__, self.method_with_var_args('one', 'two'))
# ------------------------------------------------------------------
@@ 70,13 72,13 @@ class AboutMethods(Koan):
def function_with_the_same_name(a, b):
return a * b
- self.assertEqual(__, function_with_the_same_name(3,4))
+ self.assertEqual(__, function_with_the_same_name(3, 4))
def test_calling_methods_in_same_class_with_explicit_receiver(self):
def function_with_the_same_name(a, b):
return a * b
- self.assertEqual(__, self.function_with_the_same_name(3,4))
+ self.assertEqual(__, self.function_with_the_same_name(3, 4))
# ------------------------------------------------------------------
@@ 111,7 113,8 @@ class AboutMethods(Koan):
# ------------------------------------------------------------------
- def one_line_method(self): return 'Madagascar'
+ def one_line_method(self):
+ return 'Madagascar'
def test_no_indentation_required_for_one_line_statement_bodies(self):
self.assertEqual(__, self.one_line_method())
@@ 136,7 139,7 @@ class AboutMethods(Koan):
return "wagging"
def __password(self):
- return 'password' # Genius!
+ return 'password' # Genius!
def test_calling_methods_in_other_objects(self):
rover = self.Dog()
@@ 148,11 151,13 @@ class AboutMethods(Koan):
# This is a little rude, but legal
self.assertEqual(__, rover._tail())
- def test_attributes_with_double_underscore_prefixes_are_subject_to_name_mangling(self):
+ def test_double_underscore_attribute_prefixes_cause_name_mangling(self):
+ """Attributes names that start with a double underscore get
+ mangled when an instance is created."""
rover = self.Dog()
try:
#This may not be possible...
- password = rover.__password()
+ password = rover.__password()
except Exception as ex:
self.assertEqual(__, type(ex).__name__)
@@ 161,4 166,3 @@ class AboutMethods(Koan):
# Name mangling exists to avoid name clash issues when subclassing.
# It is not for providing effective access protection
-
M python 2/koans/about_modules.py +12 -11
@@ 11,9 11,10 @@ from runner.koan import *
from another_local_module import *
from local_module_with_all_defined import *
+
class AboutModules(Koan):
def test_importing_other_python_scripts_as_modules(self):
- import local_module # local_module.py
+ import local_module # local_module.py
duck = local_module.Duck()
self.assertEqual(__, duck.name)
@@ 21,7 22,7 @@ class AboutModules(Koan):
def test_importing_attributes_from_classes_using_from_keyword(self):
from local_module import Duck
- duck = Duck() # no module qualifier needed this time
+ duck = Duck() # no module qualifier needed this time
self.assertEqual(__, duck.name)
def test_we_can_import_multiple_items_at_once(self):
@@ 33,10 34,11 @@ class AboutModules(Koan):
self.assertEqual(__, joes_dog.identify())
def test_importing_all_module_attributes_at_once(self):
- # NOTE Using this module level import declared at the top of this script:
- # from other_local_module import *
- #
- # Import wildcard cannot be used from within classes or functions
+ """
+ importing all attributes at once is done like so:
+ from another_local_module import *
+ The import wildcard cannot be used from within classes or functions.
+ """
goose = Goose()
hamster = Hamster()
@@ 51,18 53,17 @@ class AboutModules(Koan):
self.assertMatch(__, ex[0])
def test_private_attributes_are_still_accessible_in_modules(self):
- from local_module import Duck # local_module.py
+ from local_module import Duck # local_module.py
duck = Duck()
self.assertEqual(__, duck._password)
# module level attribute hiding doesn't affect class attributes
# (unless the class itself is hidden).
- def test_a_module_can_choose_which_attributes_are_available_to_wildcards(self):
- # NOTE Using this module level import declared at the top of this script:
- # from local_module_with_all_defined import *
+ def test_a_modules_XallX_statement_limits_what_wildcards_will_match(self):
+ """Examine results of from local_module_with_all_defined import *"""
- # 'Goat' is on the __ALL__ list
+ # 'Goat' is on the __all__ list
goat = Goat()
self.assertEqual(__, goat.name)
M python 2/koans/about_monkey_patching.py +7 -5
@@ 7,6 7,7 @@
from runner.koan import *
+
class AboutMonkeyPatching(Koan):
class Dog(object):
def bark(self):
@@ 18,9 19,11 @@ class AboutMonkeyPatching(Koan):
# ------------------------------------------------------------------
- # Add a new method to an existing class.
+ # Add a new method to an existing class.
def test_after_patching_dogs_can_both_wag_and_bark(self):
- def wag(self): return "HAPPY"
+ def wag(self):
+ return "HAPPY"
+
self.Dog.wag = wag
fido = self.Dog()
@@ 37,12 40,11 @@ class AboutMonkeyPatching(Koan):
# ------------------------------------------------------------------
- class MyInt(int): pass
+ class MyInt(int):
+ pass
def test_subclasses_of_built_in_classes_can_be_be_monkey_patched(self):
self.MyInt.is_even = lambda self: (self % 2) == 0
self.assertEqual(____, self.MyInt(1).is_even())
self.assertEqual(____, self.MyInt(2).is_even())
-
-
No newline at end of file
M python 2/koans/about_multiple_inheritance.py +31 -31
@@ 7,6 7,7 @@
from runner.koan import *
+
class AboutMultipleInheritance(Koan):
class Nameable(object):
def __init__(self):
@@ 14,20 15,20 @@ class AboutMultipleInheritance(Koan):
def set_name(self, new_name):
self._name = new_name
-
+
def here(self):
return "In Nameable class"
-
- class Animal(object):
+
+ class Animal(object):
def legs(self):
return 4
def can_climb_walls(self):
return False
-
+
def here(self):
return "In Animal class"
-
+
class Pig(Animal):
def __init__(self):
super(AboutMultipleInheritance.Animal, self).__init__()
@@ 36,13 37,13 @@ class AboutMultipleInheritance(Koan):
@property
def name(self):
return self._name
-
+
def speak(self):
return "OINK"
-
+
def color(self):
- return 'pink'
-
+ return 'pink'
+
def here(self):
return "In Pig class"
@@ 68,23 69,23 @@ class AboutMultipleInheritance(Koan):
super(AboutMultipleInheritance.Pig, self).__init__()
super(AboutMultipleInheritance.Nameable, self).__init__()
self._name = "Jeff"
-
+
def speak(self):
return "This looks like a job for Spiderpig!"
-
+
def here(self):
return "In Spiderpig class"
-
- #
- # Hierarchy:
+
+ #
+ # Hierarchy:
# Animal
- # / \
- # Pig Spider Nameable
+ # / \
+ # Pig Spider Nameable
# \ | /
# Spiderpig
- #
+ #
# ------------------------------------------------------------------
-
+
def test_normal_methods_are_available_in_the_object(self):
jeff = self.Spiderpig()
self.assertMatch(__, jeff.speak())
@@ 96,14 97,14 @@ class AboutMultipleInheritance(Koan):
except:
self.fail("This should not happen")
self.assertEqual(____, jeff.can_climb_walls())
-
+
def test_base_class_methods_can_affect_instance_variables_in_the_object(self):
jeff = self.Spiderpig()
self.assertEqual(__, jeff.name)
-
+
jeff.set_name("Rover")
self.assertEqual(__, jeff.name)
-
+
def test_left_hand_side_inheritance_tends_to_be_higher_priority(self):
jeff = self.Spiderpig()
self.assertEqual(__, jeff.color())
@@ 117,25 118,24 @@ class AboutMultipleInheritance(Koan):
# MRO = Method Resolution Order
#
mro = type(self.Spiderpig()).__mro__
- self.assertEqual('Spiderpig', mro[0].__name__)
- self.assertEqual('Pig', mro[1].__name__)
- self.assertEqual(__, mro[2].__name__)
- self.assertEqual(__, mro[3].__name__)
- self.assertEqual(__, mro[4].__name__)
- self.assertEqual(__, mro[5].__name__)
+ self.assertEqual('Spiderpig', mro[0].__name__)
+ self.assertEqual('Pig', mro[1].__name__)
+ self.assertEqual(__, mro[2].__name__)
+ self.assertEqual(__, mro[3].__name__)
+ self.assertEqual(__, mro[4].__name__)
+ self.assertEqual(__, mro[5].__name__)
def test_confirm_the_mro_controls_the_calling_order(self):
jeff = self.Spiderpig()
self.assertMatch('Spiderpig', jeff.here())
-
- next = super(AboutMultipleInheritance.Spiderpig, jeff)
+
+ next = super(AboutMultipleInheritance.Spiderpig, jeff)
self.assertMatch('Pig', next.here())
next = super(AboutMultipleInheritance.Pig, jeff)
self.assertMatch(__, next.here())
-
+
# Hang on a minute?!? That last class name might be a super class of
# the 'jeff' object, but its hardly a superclass of Pig, is it?
#
# To avoid confusion it may help to think of super() as next_mro().
-
M python 2/koans/about_new_style_classes.py +6 -2
@@ 3,6 3,7 @@
from runner.koan import *
+
class AboutNewStyleClasses(Koan):
class OldStyleClass:
"An old style class"
@@ 26,7 27,8 @@ class AboutNewStyleClasses(Koan):
self.assertEqual(__, self.OldStyleClass.__module__)
self.assertEqual(__, len(dir(self.NewStyleClass)))
- # To examine the available attributes, run 'dir(<Class name goes here>)'
+ # To examine the available attributes, run
+ # 'dir(<Class name goes here>)'
# from a python console
# ------------------------------------------------------------------
@@ 44,7 46,9 @@ class AboutNewStyleClasses(Koan):
def test_new_style_classes_have_same_class_as_type(self):
new_style = self.NewStyleClass()
self.assertEqual(__, type(self.NewStyleClass).__name__)
- self.assertEqual(__, type(self.NewStyleClass) == self.NewStyleClass.__class__)
+ self.assertEqual(
+ __,
+ type(self.NewStyleClass) == self.NewStyleClass.__class__)
# ------------------------------------------------------------------
M python 2/koans/about_none.py +6 -5
@@ 7,6 7,7 @@
from runner.koan import *
+
class AboutNone(Koan):
def test_none_is_an_object(self):
@@ 17,14 18,16 @@ class AboutNone(Koan):
"There is only one None"
self.assertEqual(__, None is None)
- def test_what_exception_do_you_get_when_calling_nonexistent_methods_on_None(self):
+ def test_what_exception_do_you_get_when_calling_nonexistent_methods(self):
"""
What is the Exception that is thrown when you call a method that does
not exist?
- Hint: launch python command console and try the code in the block below.
+ Hint: launch python command console and try the code in the
+ block below.
- Don't worry about what 'try' and 'except' do, we'll talk about this later
+ Don't worry about what 'try' and 'except' do, we'll talk about
+ this later
"""
try:
None.some_method_none_does_not_know_about()
@@ 42,5 45,3 @@ class AboutNone(Koan):
"""
self.assertEqual(____, None is not 0)
self.assertEqual(____, None is not False)
-
-
M python 2/koans/about_packages.py +3 -2
@@ 18,11 18,12 @@ from runner.koan import *
# about_attribute_access.py
# about_class_attributes.py
# about_classes.py
-# ...
+# ...
# a_package_folder/
# __init__.py
# a_module.py
+
class AboutPackages(Koan):
def test_subfolders_can_form_part_of_a_module_package(self):
# Import ./a_package_folder/a_module.py
@@ 60,7 61,7 @@ class AboutPackages(Koan):
# almost impossible. So always leave the starting python script in
# a folder which can reach everything else.
- def test_import_a_module_in_a_subfolder_folder_using_an_absolute_path(self):
+ def test_import_a_module_in_a_subfolder_using_an_absolute_path(self):
# Import contemplate_koans.py/koans/a_package_folder/a_module.py
from koans.a_package_folder.a_module import Duck
M python 2/koans/about_proxy_object_project.py +6 -3
@@ 18,6 18,7 @@
from runner.koan import *
+
class Proxy(object):
def __init__(self, target_object):
# WRITE CODE HERE
@@ 25,7 26,8 @@ class Proxy(object):
#initialize '_obj' attribute last. Trust me on this!
self._obj = target_object
- # WRITE CODE HERE
+ # WRITE CODE HERE
+
# The proxy object should pass the following Koan:
#
@@ 64,7 66,6 @@ class AboutProxyObjectProject(Koan):
self.assertEqual(AttributeError, type(ex))
-
def test_proxy_reports_methods_have_been_called(self):
tv = Proxy(Television())
@@ 97,6 98,7 @@ class AboutProxyObjectProject(Koan):
self.assertEqual(["Py", "Ohio", "2010"], result)
self.assertEqual(['upper', 'split'], proxy.messages())
+
# ====================================================================
# The following code is to support the testing of the Proxy class. No
# changes should be necessary to anything below this comment.
@@ 113,7 115,7 @@ class Television(object):
@channel.setter
def channel(self, value):
- self._channel = value
+ self._channel = value
def power(self):
if self._power == 'on':
@@ 124,6 126,7 @@ class Television(object):
def is_on(self):
return self._power == 'on'
+
# Tests for the Television class. All of theses tests should pass.
class TelevisionTest(Koan):
def test_it_turns_on(self):
M python 2/koans/about_regex.py +66 -42
@@ 2,11 2,15 @@
# -*- coding: utf-8 -*-
from runner.koan import *
+
import re
+
+
class AboutRegex(Koan):
"""
- These koans are based on the Ben's book: Regular Expressions in 10 minutes.
- I found this books very useful so I decided to write a koans in order to practice everything I had learned from it.
+ These koans are based on Ben's book: Regular Expressions in 10
+ minutes. I found this book very useful, so I decided to write
+ a koan file in order to practice everything it taught me.
http://www.forta.com/books/0672325667/
"""
@@ 14,47 18,60 @@ class AboutRegex(Koan):
"""
Lesson 1 Matching Literal String
"""
- string = "Hello, my name is Felix and this koans are based on the Ben's book: Regular Expressions in 10 minutes."
+ string = "Hello, my name is Felix and these koans are based " +
+ "on Ben's book: Regular Expressions in 10 minutes."
m = re.search(__, string)
- self.assertTrue(m and m.group(0) and m.group(0)== 'Felix', "I want my name")
+ self.assertTrue(
+ m and m.group(0) and
+ m.group(0) == 'Felix',
+ "I want my name")
def test_matching_literal_text_how_many(self):
"""
- Lesson 1 How many matches?
+ Lesson 1 -- How many matches?
- The default behaviour of most regular extression engines is to return just the first match.
- In python you have the next options:
+ The default behaviour of most regular extression engines is
+ to return just the first match. In python you have the
+ following options:
- match() --> Determine if the RE matches at the beginning of the string.
- search() --> Scan through a string, looking for any location where this RE matches.
- findall() --> Find all substrings where the RE matches, and returns them as a list.
- finditer() --> Find all substrings where the RE matches, and returns them as an iterator.
-
+ match() --> Determine if the RE matches at the
+ beginning of the string.
+ search() --> Scan through a string, looking for any
+ location where this RE matches.
+ findall() --> Find all substrings where the RE
+ matches, and return them as a list.
+ finditer() --> Find all substrings where the RE
+ matches, and return them as an iterator.
"""
- string = "Hello, my name is Felix and this koans are based on the Ben's book: Regular Expressions in 10 minutes. Repeat My name is Felix"
- m = re.match('Felix', string) #TIP: Maybe match it's not the best option
+ string = ("Hello, my name is Felix and these koans are based " +
+ "on Ben's book: Regular Expressions in 10 minutes. " +
+ "Repeat My name is Felix")
+ m = re.match('Felix', string) # TIP: match may not be the best option
- # I want to know how many times appears my name
+ # I want to know how many times my name appears
self.assertEqual(m, __)
def test_matching_literal_text_not_case_sensitivity(self):
"""
- Lesson 1 Matching Literal String non case sensitivity.
- Most regex implementations also support matches that are not case sensitive. In python you can use re.IGNORECASE, in
- Javascript you can specify the optional i flag.
- In Ben's book you can see more languages.
+ Lesson 1 -- Matching Literal String non case sensitivity.
+ Most regex implementations also support matches that are not
+ case sensitive. In python you can use re.IGNORECASE, in
+ Javascript you can specify the optional i flag. In Ben's
+ book you can see more languages.
"""
- string = "Hello, my name is Felix or felix and this koans is based on the Ben's book: Regular Expressions in 10 minutes."
+ string = "Hello, my name is Felix or felix and this koan " + \
+ "is based on Ben's book: Regular Expressions in 10 minutes."
self.assertEqual(re.findall("felix", string, 20), __)
self.assertEqual(re.findall("felix", string, 10), __)
-
+
def test_matching_any_character(self):
"""
- Lesson 1 Matching any character
+ Lesson 1: Matching any character
- . matches any character, alphabetic characters, digits and .
+ `.` matches any character: alphabetic characters, digits,
+ and punctuation.
"""
string = "pecks.xlx\n" \
+ "orders1.xls\n" \
@@ 63,17 80,19 @@ class AboutRegex(Koan):
+ "na2.xls\n" \
+ "sa1.xls"
- # TIP: remember the name of this lesson
-
- change_this_search_string = 'a..xlx' # <-- I want to find all uses of myArray
- self.assertEquals(len(re.findall(change_this_search_string, string)),3)
+ # I want to find all uses of myArray
+ change_this_search_string = 'a..xlx'
+ self.assertEquals(
+ len(re.findall(change_this_search_string, string)),
+ 3)
def test_matching_set_character(self):
"""
- Lesson 2 Matching sets of characters
+ Lesson 2 -- Matching sets of characters
- A set of characters is defined using the metacharacters [ and ]. Everything between them is part of the set and
- any one of the set members must match (but not all).
+ A set of characters is defined using the metacharacters
+ `[` and `]`. Everything between them is part of the set, and
+ any single one of the set members will match.
"""
string = "sales.xlx\n" \
+ "sales1.xls\n" \
@@ 83,17 102,22 @@ class AboutRegex(Koan):
+ "na1.xls\n" \
+ "na2.xls\n" \
+ "sa1.xls\n" \
- + "ca1.xls"
- # I want to find all files for North America(na) or South America(sa), but not (ca)
- # TIP you can use the pattern .a. which matches in above test but in this case matches more than you want
+ + "ca1.xls"
+ # I want to find all files for North America(na) or South
+ # America(sa), but not (ca) TIP you can use the pattern .a.
+ # which matches in above test but in this case matches more than
+ # you want
change_this_search_string = '[nsc]a[2-9].xls'
- self.assertEquals(len(re.findall(change_this_search_string, string)),3)
+ self.assertEquals(
+ len(re.findall(change_this_search_string, string)),
+ 3)
def test_anything_but_matching(self):
"""
- Lesson 2 Using character set ranges
- Occsionally, you'll want a list of characters that you don't want to match.
- Character sets can be negated using the ^ metacharacter.
+ Lesson 2 -- Using character set ranges
+ Occasionally, you'll have a list of characters that you don't
+ want to match. Character sets can be negated using the ^
+ metacharacter.
"""
string = "sales.xlx\n" \
@@ 107,10 131,10 @@ class AboutRegex(Koan):
+ "na1.xls\n" \
+ "na2.xls\n" \
+ "sa1.xls\n" \
- + "ca1.xls"
+ + "ca1.xls"
- # I want to find the name sam
+ # I want to find the name 'sam'
change_this_search_string = '[^nc]am'
- self.assertEquals(re.findall(change_this_search_string, string), ['sam.xls'])
-
-
+ self.assertEquals(
+ re.findall(change_this_search_string, string),
+ ['sam.xls'])
M python 2/koans/about_scope.py +4 -4
@@ 3,10 3,11 @@
from runner.koan import *
-import jims
+import jims
import joes
-counter = 0 # Global
+counter = 0 # Global
+
class AboutScope(Koan):
#
@@ 19,7 20,7 @@ class AboutScope(Koan):
try:
fido = Dog()
except Exception as ex:
- self.assertMatch(__, ex[0])
+ self.assertMatch(__, ex[0])
def test_you_can_reference_nested_classes_using_the_scope_operator(self):
fido = jims.Dog()
@@ 89,4 90,3 @@ class AboutScope(Koan):
def test_global_attributes_can_be_created_in_the_middle_of_a_class(self):
self.assertEqual(__, deadly_bingo[5])
-
No newline at end of file
M python 2/koans/about_scoring_project.py +20 -18
@@ 3,6 3,7 @@
from runner.koan import *
+
# Greed is a dice game where you roll up to five dice to accumulate
# points. The following "score" function will be used calculate the
# score of a single roll of the dice.
@@ 10,7 11,7 @@ from runner.koan import *
# A greed roll is scored as follows:
#
# * A set of three ones is 1000 points
-#
+#
# * A set of three numbers (other than ones) is worth 100 times the
# number. (e.g. three fives is 500 points).
#
@@ 23,10 24,10 @@ from runner.koan import *
#
# Examples:
#
-# score([1,1,1,5,1]) => 1150 points
-# score([2,3,4,6,2]) => 0 points
-# score([3,4,5,3,3]) => 350 points
-# score([1,5,1,2,4]) => 250 points
+# score([1, 1, 1, 5, 1]) => 1150 points
+# score([2, 3, 4, 6, 2]) => 0 points
+# score([3, 4, 5, 3, 3]) => 350 points
+# score([1, 5, 1, 2, 4]) => 250 points
#
# More scoring examples are given in the tests below:
#
@@ 36,6 37,7 @@ def score(dice):
# You need to write this method
pass
+
class AboutScoringProject(Koan):
def test_score_of_an_empty_list_is_zero(self):
self.assertEqual(0, score([]))
@@ 47,26 49,26 @@ class AboutScoringProject(Koan):
self.assertEqual(100, score([1]))
def test_score_of_multiple_1s_and_5s_is_the_sum_of_individual_scores(self):
- self.assertEqual(300, score([1,5,5,1]))
+ self.assertEqual(300, score([1, 5, 5, 1]))
def test_score_of_single_2s_3s_4s_and_6s_are_zero(self):
- self.assertEqual(0, score([2,3,4,6]))
+ self.assertEqual(0, score([2, 3, 4, 6]))
def test_score_of_a_triple_1_is_1000(self):
- self.assertEqual(1000, score([1,1,1]))
+ self.assertEqual(1000, score([1, 1, 1]))
def test_score_of_other_triples_is_100x(self):
- self.assertEqual(200, score([2,2,2]))
- self.assertEqual(300, score([3,3,3]))
- self.assertEqual(400, score([4,4,4]))
- self.assertEqual(500, score([5,5,5]))
- self.assertEqual(600, score([6,6,6]))
+ self.assertEqual(200, score([2, 2, 2]))
+ self.assertEqual(300, score([3, 3, 3]))
+ self.assertEqual(400, score([4, 4, 4]))
+ self.assertEqual(500, score([5, 5, 5]))
+ self.assertEqual(600, score([6, 6, 6]))
def test_score_of_mixed_is_sum(self):
- self.assertEqual(250, score([2,5,2,2,3]))
- self.assertEqual(550, score([5,5,5,5]))
- self.assertEqual(1150, score([1,1,1,5,1]))
+ self.assertEqual(250, score([2, 5, 2, 2, 3]))
+ self.assertEqual(550, score([5, 5, 5, 5]))
+ self.assertEqual(1150, score([1, 1, 1, 5, 1]))
def test_ones_not_left_out(self):
- self.assertEqual(300, score([1,2,2,2]))
- self.assertEqual(350, score([1,5,2,2,2]))
No newline at end of file
+ self.assertEqual(300, score([1, 2, 2, 2]))
+ self.assertEqual(350, score([1, 5, 2, 2, 2]))
M python 2/koans/about_sets.py +10 -9
@@ 3,9 3,11 @@
from runner.koan import *
+
class AboutSets(Koan):
def test_sets_make_keep_lists_unique(self):
- highlanders = ['MacLeod', 'Ramirez', 'MacLeod', 'Matunas', 'MacLeod', 'Malcolm', 'MacLeod']
+ highlanders = ['MacLeod', 'Ramirez', 'MacLeod', 'Matunas',
+ 'MacLeod', 'Malcolm', 'MacLeod']
there_can_only_be_only_one = set(highlanders)
@@ 17,7 19,6 @@ class AboutSets(Koan):
def test_convert_the_set_into_a_list_to_sort_it(self):
self.assertEqual(__, sorted(set('13245')))
-
# ------------------------------------------------------------------
def chars_in(self, a_set):
@@ 27,19 28,19 @@ class AboutSets(Koan):
good_guy = set('macleod')
bad_guy = set('mutunas')
- self.assertEqual(__, self.chars_in( good_guy - bad_guy) )
- self.assertEqual(__, self.chars_in( good_guy | bad_guy ))
- self.assertEqual(__, self.chars_in( good_guy & bad_guy ))
- self.assertEqual(__, self.chars_in( good_guy ^ bad_guy ))
+ self.assertEqual(__, self.chars_in(good_guy - bad_guy))
+ self.assertEqual(__, self.chars_in(good_guy | bad_guy))
+ self.assertEqual(__, self.chars_in(good_guy & bad_guy))
+ self.assertEqual(__, self.chars_in(good_guy ^ bad_guy))
# ------------------------------------------------------------------
def test_we_can_query_set_membership(self):
- self.assertEqual(__, 127 in set([127, 0, 0, 1]) )
- self.assertEqual(__, 'cow' not in set('apocalypse now') )
+ self.assertEqual(__, 127 in set([127, 0, 0, 1]))
+ self.assertEqual(__, 'cow' not in set('apocalypse now'))
def test_we_can_compare_subsets(self):
self.assertEqual(__, set('cake') <= set('cherry cake'))
- self.assertEqual(__, set('cake').issubset(set('cherry cake')) )
+ self.assertEqual(__, set('cake').issubset(set('cherry cake')))
self.assertEqual(__, set('cake') > set('pie'))
M python 2/koans/about_strings.py +8 -6
@@ 3,6 3,7 @@
from runner.koan import *
+
class AboutStrings(Koan):
def test_double_quoted_strings_are_strings(self):
@@ 55,7 56,7 @@ world!
b = """Hello "world"."""
self.assertEqual(__, (a == b))
- def but_you_still_have_to_be_careful_at_the_end_of_a_triple_quoted_string(self):
+ def but_quotes_at_the_end_of_a_triple_quoted_string_are_still_tricky(self):
string = """Hello "world\""""
def test_plus_concatenates_strings(self):
@@ 105,7 106,7 @@ world!
self.assertEqual(__, string)
def test_any_python_expression_may_be_interpolated(self):
- import math # import a standard python module with math functions
+ import math # import a standard python module with math functions
decimal_places = 4
string = "The square root of 5 is {0:.{1}f}".format(math.sqrt(5), \
@@ 121,7 122,7 @@ world!
self.assertEqual(__, string[1])
def test_single_characters_can_be_represented_by_integers(self):
- self.assertEqual(__, ord('a'))
+ self.assertEqual(__, ord('a'))
self.assertEqual(__, ord('b') == (ord('a') + 1))
def test_strings_can_be_split(self):
@@ 130,7 131,7 @@ world!
self.assertEqual([__, __, __], words)
def test_strings_can_be_split_with_different_patterns(self):
- import re #import python regular expression library
+ import re # import python regular expression library
string = "the,rain;in,spain"
pattern = re.compile(',|;')
@@ 139,7 140,8 @@ world!
self.assertEqual([__, __, __, __], words)
- # Pattern is a Python regular expression pattern which matches ',' or ';'
+ # `pattern` is a Python regular expression pattern which matches
+ # ',' or ';'
def test_raw_strings_do_not_interpret_escape_characters(self):
string = r'\n'
@@ 147,7 149,7 @@ world!
self.assertEqual(__, string)
self.assertEqual(__, len(string))
- # Useful in regular expressions, file paths, URLs, etc.
+ # Useful in regular expressions, file paths, URLs, etc.
def test_strings_can_be_joined(self):
words = ["Now", "is", "the", "time"]
M python 2/koans/about_triangle_project.py +1 -0
@@ 6,6 6,7 @@ from runner.koan import *
# You need to write the triangle method in the file 'triangle.py'
from triangle import *
+
class AboutTriangleProject(Koan):
def test_equilateral_triangles_have_equal_sides(self):
self.assertEqual('equilateral', triangle(2, 2, 2))
M python 2/koans/about_triangle_project2.py +2 -1
@@ 6,6 6,7 @@ from runner.koan import *
# You need to finish implementing triangle() in the file 'triangle.py'
from triangle import *
+
class AboutTriangleProject2(Koan):
# The first assignment did not talk about how to handle errors.
# Let's handle that part now.
@@ 15,4 16,4 @@ class AboutTriangleProject2(Koan):
self.assertRaises(TriangleError, triangle, 3, 4, -5)
self.assertRaises(TriangleError, triangle, 1, 1, 3)
- self.assertRaises(TriangleError, triangle, 2, 4, 2)
+ self.assertRaises(TriangleError, triangle, 2, 4, 2)
M python 2/koans/about_true_and_false.py +4 -1
@@ 3,6 3,7 @@
from runner.koan import *
+
class AboutTrueAndFalse(Koan):
def truth_value(self, condition):
if condition:
@@ 34,5 35,7 @@ class AboutTrueAndFalse(Koan):
def test_everything_else_is_treated_as_true(self):
self.assertEqual(__, self.truth_value(1))
self.assertEqual(__, self.truth_value(1,))
- self.assertEqual(__, self.truth_value("Python is named after Monty Python"))
+ self.assertEqual(
+ __,
+ self.truth_value("Python is named after Monty Python"))
self.assertEqual(__, self.truth_value(' '))
M python 2/koans/about_tuples.py +11 -11
@@ 3,33 3,34 @@
from runner.koan import *
+
class AboutTuples(Koan):
def test_creating_a_tuple(self):
- count_of_three = (1, 2, 5)
+ count_of_three = (1, 2, 5)
self.assertEqual(__, count_of_three[2])
def test_tuples_are_immutable_so_item_assignment_is_not_possible(self):
- count_of_three = (1, 2, 5)
+ count_of_three = (1, 2, 5)
try:
count_of_three[2] = "three"
except TypeError as ex:
self.assertMatch(__, ex[0])
def test_tuples_are_immutable_so_appending_is_not_possible(self):
- count_of_three = (1, 2, 5)
+ count_of_three = (1, 2, 5)
try:
count_of_three.append("boom")
except Exception as ex:
self.assertEqual(AttributeError, type(ex))
# Note, assertMatch() uses regular expression pattern matching,
- # so you don't have to copy the whole message.
+ # so you don't have to copy the whole message.
self.assertMatch(__, ex[0])
# Tuples are less flexible than lists, but faster.
def test_tuples_can_only_be_changed_through_replacement(self):
- count_of_three = (1, 2, 5)
+ count_of_three = (1, 2, 5)
list_count = list(count_of_three)
list_count.append("boom")
@@ 46,8 47,8 @@ class AboutTuples(Koan):
self.assertEqual(__, tuple("Surprise!"))
def test_creating_empty_tuples(self):
- self.assertEqual(__ , ())
- self.assertEqual(__ , tuple()) #Sometimes less confusing
+ self.assertEqual(__, ())
+ self.assertEqual(__, tuple()) # Sometimes less confusing
def test_tuples_can_be_embedded(self):
lat = (37, 14, 6, 'N')
@@ 61,10 62,9 @@ class AboutTuples(Koan):
("Stargate B", (41, 10, 43.92, 'N'), (1, 49, 34.29, 'W')),
]
- locations.append( ("Cthulu", (26, 40, 1, 'N'), (70, 45, 7, 'W')) )
+ locations.append(
+ ("Cthulhu", (26, 40, 1, 'N'), (70, 45, 7, 'W'))
+ )
self.assertEqual(__, locations[2][0])
self.assertEqual(__, locations[0][1][2])
-
-
-
M python 2/koans/about_with_statements.py +5 -3
@@ 7,7 7,8 @@
from runner.koan import *
-import re # For regular expression string comparisons
+import re # For regular expression string comparisons
+
class AboutWithStatements(Koan):
def count_lines(self, file_name):
@@ 30,7 31,8 @@ class AboutWithStatements(Koan):
try:
for line in file.readlines():
match = re.search('e', line)
- if match: return line
+ if match:
+ return line
finally:
if file: file.close()
@@ 100,7 102,7 @@ class AboutWithStatements(Koan):
with open(file_name) as file:
count = 0
for line in file.readlines():
- count += 1
+ count += 1
return count
def test_open_already_has_its_own_built_in_context_manager(self):
M python 2/koans/another_local_module.py +4 -1
@@ 1,17 1,20 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
+
class Goose(object):
@property
def name(self):
return "Mr Stabby"
+
class Hamster(object):
@property
def name(self):
return "Phil"
+
class _SecretSquirrel(object):
@property
def name(self):
- return "Mr Anonymous"
No newline at end of file
+ return "Mr Anonymous"
M python 2/koans/jims.py +1 -0
@@ 1,6 1,7 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
+
class Dog(object):
def identify(self):
return "jims dog"
M python 2/koans/joes.py +1 -0
@@ 1,6 1,7 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
+
class Dog(object):
def identify(self):
return "joes dog"
M python 2/koans/local_module.py +2 -1
@@ 1,9 1,10 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
+
class Duck(object):
def __init__(self):
- self._password = 'password' # Genius!
+ self._password = 'password' # Genius!
@property
def name(self):
M python 2/koans/local_module_with_all_defined.py +4 -1
@@ 2,20 2,23 @@
# -*- coding: utf-8 -*-
__all__ = (
- 'Goat',
+ 'Goat',
'_Velociraptor'
)
+
class Goat(object):
@property
def name(self):
return "George"
+
class _Velociraptor(object):
@property
def name(self):
return "Cuddles"
+
class SecretDuck(object):
@property
def name(self):
M python 2/koans/triangle.py +3 -1
@@ 3,7 3,8 @@
# Triangle Project Code.
-# Triangle analyzes the lengths of the sides of a triangle
+
+# triangle(a, b, c) analyzes the lengths of the sides of a triangle
# (represented by a, b and c) and returns the type of triangle.
#
# It returns:
@@ 20,6 21,7 @@ def triangle(a, b, c):
# DELETE 'PASS' AND WRITE THIS CODE
pass
+
# Error class used in part 2. No need to change this code.
class TriangleError(StandardError):
pass