# HG changeset patch # User Sietse Brouwer # Date 1326898438 -3600 # Wed Jan 18 15:53:58 2012 +0100 # Node ID eef9b4bf71b3c3516db9ec34079b5ae27a205697 # Parent 5315d33c2205dd948c2eedcddf7bcfded883900a Make python2 koans pep8-compliant. Running the pep8 script still throws up a number of errors: mostly W293 (whitespace on blank line), E701 (multiple statements on one line (colon)), and E501 (line too long). W293 I ignore to make copy-pasting into the interpreter easier: a blank line between two class methods would make the interpreter think the class was done. Where E701 survives, it's mostly in statements like ``if i > 10: break``. E501, lastly, matches a particular pet peeve of mine, and I have chopped up the lines in question wherever possible. The long-named method definitions were hardest: I renamed those to something shorter where I could think of somthing, but a number remain. diff --git a/python 2/koans/__init__.py b/python 2/koans/__init__.py --- a/python 2/koans/__init__.py +++ b/python 2/koans/__init__.py @@ -1,4 +1,4 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# koans \ No newline at end of file +# koans diff --git a/python 2/koans/about_asserts.py b/python 2/koans/about_asserts.py --- a/python 2/koans/about_asserts.py +++ b/python 2/koans/about_asserts.py @@ -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 @@ 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 @@ """ 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 - diff --git a/python 2/koans/about_attribute_access.py b/python 2/koans/about_attribute_access.py --- a/python 2/koans/about_attribute_access.py +++ b/python 2/koans/about_attribute_access.py @@ -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 @@ 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 @@ def __getattr__(self, attr_name): self.no_of_getattr_calls += 1 return self.DuffObject - + def my_method(self): pass @@ -147,62 +153,64 @@ 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() diff --git a/python 2/koans/about_class_attributes.py b/python 2/koans/about_class_attributes.py --- a/python 2/koans/about_class_attributes.py +++ b/python 2/koans/about_class_attributes.py @@ -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 @@ 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 @@ @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 @@ 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 @@ 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 @@ 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()) diff --git a/python 2/koans/about_control_statements.py b/python 2/koans/about_control_statements.py --- a/python 2/koans/about_control_statements.py +++ b/python 2/koans/about_control_statements.py @@ -3,6 +3,7 @@ from runner.koan import * + class AboutControlStatements(Koan): def test_if_then_else_statements(self): @@ -17,7 +18,7 @@ if True: result = 'true value' self.assertEqual(__, result) - + def test_while_statement(self): i = 1 result = 1 @@ -25,7 +26,7 @@ result = result * i i += 1 self.assertEqual(__, result) - + def test_break_statement(self): i = 1 result = 1 @@ -34,39 +35,39 @@ 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 diff --git a/python 2/koans/about_decorating_with_classes.py b/python 2/koans/about_decorating_with_classes.py --- a/python 2/koans/about_decorating_with_classes.py +++ b/python 2/koans/about_decorating_with_classes.py @@ -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 @@ 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 @@ 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 @@ 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 @@ # ------------------------------------------------------------------ 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 @@ @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 @@ def test_we_can_chain_decorators(self): self.assertEqual(__, self.homer()) self.assertEqual(__, self.homer.__doc__) - \ No newline at end of file diff --git a/python 2/koans/about_decorating_with_functions.py b/python 2/koans/about_decorating_with_functions.py --- a/python 2/koans/about_decorating_with_functions.py +++ b/python 2/koans/about_decorating_with_functions.py @@ -15,7 +15,7 @@ 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 @@ def test_decorators_can_change_a_function_output(self): self.assertEqual(__, self.render_tag('llama')) - diff --git a/python 2/koans/about_deleting_objects.py b/python 2/koans/about_deleting_objects.py --- a/python 2/koans/about_deleting_objects.py +++ b/python 2/koans/about_deleting_objects.py @@ -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 @@ try: win = lottery_nums except Exception as e: - pass + pass self.assertMatch(__, e[0]) - # ==================================================================== + # -------------------------------------------------------------------- class ClosingSale(object): def __init__(self): @@ -54,7 +55,7 @@ self.assertMatch(__, err_msg1) self.assertMatch(__, err_msg2) - # ==================================================================== + # -------------------------------------------------------------------- class ClintEastwood(object): def __init__(self): @@ -83,8 +84,7 @@ del cowboy.name self.assertEqual(__, cowboy.name) - - # ==================================================================== + # -------------------------------------------------------------------- class Prisoner(object): def __init__(self): @@ -110,7 +110,7 @@ del citizen.name self.assertEqual(__, citizen.name) - # ==================================================================== + # -------------------------------------------------------------------- class MoreOrganisedClosingSale(ClosingSale): def __init__(self): diff --git a/python 2/koans/about_dice_project.py b/python 2/koans/about_dice_project.py --- a/python 2/koans/about_dice_project.py +++ b/python 2/koans/about_dice_project.py @@ -5,11 +5,12 @@ import random + class DiceSet(object): def __init__(self): self._values = None - @property + @property def values(self): return self._values @@ -18,6 +19,7 @@ # 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 @@ 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() diff --git a/python 2/koans/about_dictionaries.py b/python 2/koans/about_dictionaries.py --- a/python 2/koans/about_dictionaries.py +++ b/python 2/koans/about_dictionaries.py @@ -7,6 +7,7 @@ from runner.koan import * + class AboutDictionaries(Koan): def test_creating_dictionaries(self): empty_dict = dict() @@ -15,45 +16,47 @@ 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"]) - diff --git a/python 2/koans/about_exceptions.py b/python 2/koans/about_exceptions.py --- a/python 2/koans/about_exceptions.py +++ b/python 2/koans/about_exceptions.py @@ -3,6 +3,7 @@ from runner.koan import * + class AboutExceptions(Koan): class MySpecialError(RuntimeError): diff --git a/python 2/koans/about_extra_credit.py b/python 2/koans/about_extra_credit.py --- a/python 2/koans/about_extra_credit.py +++ b/python 2/koans/about_extra_credit.py @@ -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 diff --git a/python 2/koans/about_generators.py b/python 2/koans/about_generators.py --- a/python 2/koans/about_generators.py +++ b/python 2/koans/about_generators.py @@ -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 @@ 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 @@ 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 @@ 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 @@ next(generator) # 'next(generator)' is exactly equivelant to 'generator.send(None)' self.assertEqual(__, generator.send(None)) - - diff --git a/python 2/koans/about_inheritance.py b/python 2/koans/about_inheritance.py --- a/python 2/koans/about_inheritance.py +++ b/python 2/koans/about_inheritance.py @@ -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 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 @@ 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) diff --git a/python 2/koans/about_iteration.py b/python 2/koans/about_iteration.py --- a/python 2/koans/about_iteration.py +++ b/python 2/koans/about_iteration.py @@ -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 @@ 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 @@ # ------------------------------------------------------------------ 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 @@ 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 @@ 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: diff --git a/python 2/koans/about_lambdas.py b/python 2/koans/about_lambdas.py --- a/python 2/koans/about_lambdas.py +++ b/python 2/koans/about_lambdas.py @@ -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 diff --git a/python 2/koans/about_list_assignments.py b/python 2/koans/about_list_assignments.py --- a/python 2/koans/about_list_assignments.py +++ b/python 2/koans/about_list_assignments.py @@ -7,6 +7,7 @@ from runner.koan import * + class AboutListAssignments(Koan): def test_non_parallel_assignment(self): names = ["John", "Smith"] diff --git a/python 2/koans/about_lists.py b/python 2/koans/about_lists.py --- a/python 2/koans/about_lists.py +++ b/python 2/koans/about_lists.py @@ -7,6 +7,7 @@ from runner.koan import * + class AboutLists(Koan): def test_creating_lists(self): empty_list = list() @@ -68,7 +69,7 @@ self.assertEqual(__, knight) knight.insert(0, 'Arthur') - self.assertEqual(__, knight) + self.assertEqual(__, knight) def test_popping_lists(self): stack = [10, 20, 30, 40] diff --git a/python 2/koans/about_method_bindings.py b/python 2/koans/about_method_bindings.py --- a/python 2/koans/about_method_bindings.py +++ b/python 2/koans/about_method_bindings.py @@ -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 @@ try: cls = function2.get_fruit.im_self except AttributeError as ex: - self.assertMatch(__, ex[0]) + self.assertMatch(__, ex[0]) # ------------------------------------------------------------------ @@ -88,8 +92,7 @@ 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) - diff --git a/python 2/koans/about_methods.py b/python 2/koans/about_methods.py --- a/python 2/koans/about_methods.py +++ b/python 2/koans/about_methods.py @@ -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 @@ 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 @@ 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 @@ 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 @@ # ------------------------------------------------------------------ - 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 @@ 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 @@ # 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 @@ # Name mangling exists to avoid name clash issues when subclassing. # It is not for providing effective access protection - diff --git a/python 2/koans/about_modules.py b/python 2/koans/about_modules.py --- a/python 2/koans/about_modules.py +++ b/python 2/koans/about_modules.py @@ -11,9 +11,10 @@ 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 @@ 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 @@ 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 @@ 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) diff --git a/python 2/koans/about_monkey_patching.py b/python 2/koans/about_monkey_patching.py --- a/python 2/koans/about_monkey_patching.py +++ b/python 2/koans/about_monkey_patching.py @@ -7,6 +7,7 @@ from runner.koan import * + class AboutMonkeyPatching(Koan): class Dog(object): def bark(self): @@ -18,9 +19,11 @@ # ------------------------------------------------------------------ - # 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 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 diff --git a/python 2/koans/about_multiple_inheritance.py b/python 2/koans/about_multiple_inheritance.py --- a/python 2/koans/about_multiple_inheritance.py +++ b/python 2/koans/about_multiple_inheritance.py @@ -7,6 +7,7 @@ from runner.koan import * + class AboutMultipleInheritance(Koan): class Nameable(object): def __init__(self): @@ -14,20 +15,20 @@ 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 @@ @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 @@ 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 @@ 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 @@ # 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(). - diff --git a/python 2/koans/about_new_style_classes.py b/python 2/koans/about_new_style_classes.py --- a/python 2/koans/about_new_style_classes.py +++ b/python 2/koans/about_new_style_classes.py @@ -3,6 +3,7 @@ from runner.koan import * + class AboutNewStyleClasses(Koan): class OldStyleClass: "An old style class" @@ -26,7 +27,8 @@ self.assertEqual(__, self.OldStyleClass.__module__) self.assertEqual(__, len(dir(self.NewStyleClass))) - # To examine the available attributes, run 'dir()' + # To examine the available attributes, run + # 'dir()' # from a python console # ------------------------------------------------------------------ @@ -44,7 +46,9 @@ 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__) # ------------------------------------------------------------------ diff --git a/python 2/koans/about_none.py b/python 2/koans/about_none.py --- a/python 2/koans/about_none.py +++ b/python 2/koans/about_none.py @@ -7,6 +7,7 @@ from runner.koan import * + class AboutNone(Koan): def test_none_is_an_object(self): @@ -17,14 +18,16 @@ "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 @@ """ self.assertEqual(____, None is not 0) self.assertEqual(____, None is not False) - - diff --git a/python 2/koans/about_packages.py b/python 2/koans/about_packages.py --- a/python 2/koans/about_packages.py +++ b/python 2/koans/about_packages.py @@ -18,11 +18,12 @@ # 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 @@ # 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 diff --git a/python 2/koans/about_proxy_object_project.py b/python 2/koans/about_proxy_object_project.py --- a/python 2/koans/about_proxy_object_project.py +++ b/python 2/koans/about_proxy_object_project.py @@ -18,6 +18,7 @@ from runner.koan import * + class Proxy(object): def __init__(self, target_object): # WRITE CODE HERE @@ -25,7 +26,8 @@ #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 @@ self.assertEqual(AttributeError, type(ex)) - def test_proxy_reports_methods_have_been_called(self): tv = Proxy(Television()) @@ -97,6 +98,7 @@ 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 @@ @channel.setter def channel(self, value): - self._channel = value + self._channel = value def power(self): if self._power == 'on': @@ -124,6 +126,7 @@ 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): diff --git a/python 2/koans/about_regex.py b/python 2/koans/about_regex.py --- a/python 2/koans/about_regex.py +++ b/python 2/koans/about_regex.py @@ -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 @@ """ 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 @@ + "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 @@ + "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 @@ + "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']) diff --git a/python 2/koans/about_scope.py b/python 2/koans/about_scope.py --- a/python 2/koans/about_scope.py +++ b/python 2/koans/about_scope.py @@ -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 @@ 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 @@ 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 diff --git a/python 2/koans/about_scoring_project.py b/python 2/koans/about_scoring_project.py --- a/python 2/koans/about_scoring_project.py +++ b/python 2/koans/about_scoring_project.py @@ -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 @@ # 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 @@ # # 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 @@ # 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 @@ 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])) diff --git a/python 2/koans/about_sets.py b/python 2/koans/about_sets.py --- a/python 2/koans/about_sets.py +++ b/python 2/koans/about_sets.py @@ -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 @@ 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 @@ 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')) diff --git a/python 2/koans/about_strings.py b/python 2/koans/about_strings.py --- a/python 2/koans/about_strings.py +++ b/python 2/koans/about_strings.py @@ -3,6 +3,7 @@ from runner.koan import * + class AboutStrings(Koan): def test_double_quoted_strings_are_strings(self): @@ -55,7 +56,7 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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"] diff --git a/python 2/koans/about_triangle_project.py b/python 2/koans/about_triangle_project.py --- a/python 2/koans/about_triangle_project.py +++ b/python 2/koans/about_triangle_project.py @@ -6,6 +6,7 @@ # 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)) diff --git a/python 2/koans/about_triangle_project2.py b/python 2/koans/about_triangle_project2.py --- a/python 2/koans/about_triangle_project2.py +++ b/python 2/koans/about_triangle_project2.py @@ -6,6 +6,7 @@ # 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 @@ 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) diff --git a/python 2/koans/about_true_and_false.py b/python 2/koans/about_true_and_false.py --- a/python 2/koans/about_true_and_false.py +++ b/python 2/koans/about_true_and_false.py @@ -3,6 +3,7 @@ from runner.koan import * + class AboutTrueAndFalse(Koan): def truth_value(self, condition): if condition: @@ -34,5 +35,7 @@ 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(' ')) diff --git a/python 2/koans/about_tuples.py b/python 2/koans/about_tuples.py --- a/python 2/koans/about_tuples.py +++ b/python 2/koans/about_tuples.py @@ -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 @@ 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 @@ ("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]) - - - diff --git a/python 2/koans/about_with_statements.py b/python 2/koans/about_with_statements.py --- a/python 2/koans/about_with_statements.py +++ b/python 2/koans/about_with_statements.py @@ -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 @@ 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 @@ 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): diff --git a/python 2/koans/another_local_module.py b/python 2/koans/another_local_module.py --- a/python 2/koans/another_local_module.py +++ b/python 2/koans/another_local_module.py @@ -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" diff --git a/python 2/koans/jims.py b/python 2/koans/jims.py --- a/python 2/koans/jims.py +++ b/python 2/koans/jims.py @@ -1,6 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- + class Dog(object): def identify(self): return "jims dog" diff --git a/python 2/koans/joes.py b/python 2/koans/joes.py --- a/python 2/koans/joes.py +++ b/python 2/koans/joes.py @@ -1,6 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- + class Dog(object): def identify(self): return "joes dog" diff --git a/python 2/koans/local_module.py b/python 2/koans/local_module.py --- a/python 2/koans/local_module.py +++ b/python 2/koans/local_module.py @@ -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): diff --git a/python 2/koans/local_module_with_all_defined.py b/python 2/koans/local_module_with_all_defined.py --- a/python 2/koans/local_module_with_all_defined.py +++ b/python 2/koans/local_module_with_all_defined.py @@ -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): diff --git a/python 2/koans/triangle.py b/python 2/koans/triangle.py --- a/python 2/koans/triangle.py +++ b/python 2/koans/triangle.py @@ -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 @@ # DELETE 'PASS' AND WRITE THIS CODE pass + # Error class used in part 2. No need to change this code. class TriangleError(StandardError): pass