From aad3a9a1d5dcf2fbddf628d5d08c1a1e5cd02f6e Mon Sep 17 00:00:00 2001 From: Grzegorz Kotfis Date: Tue, 22 Oct 2019 12:20:47 +0200 Subject: [PATCH 01/10] Init template --- exercises/rational-numbers/.meta/template.j2 | 40 +++++ .../rational-numbers/rational_numbers_test.py | 168 ++++++++---------- 2 files changed, 117 insertions(+), 91 deletions(-) create mode 100644 exercises/rational-numbers/.meta/template.j2 diff --git a/exercises/rational-numbers/.meta/template.j2 b/exercises/rational-numbers/.meta/template.j2 new file mode 100644 index 00000000000..d5bb04ade3f --- /dev/null +++ b/exercises/rational-numbers/.meta/template.j2 @@ -0,0 +1,40 @@ +{%- import "generator_macros.j2" as macros with context -%} + + +{% macro test_case_arithmetic(case) -%} + def test_{{ case["description"] | to_snake }}(self): + pass +{%- endmacro %} + +{% macro test_case_absolutevalue(case) -%} + def test_{{ case["description"] | to_snake }}(self): + # yyy + pass +{%- endmacro %} + +{% macro test_case_exponentiation(case) -%} + {%- set input = case["input"] -%} + def test_{{ case["description"] | to_snake }}(self): + # xxx + pass +{%- endmacro %} + +{{ macros.header() }} + +class {{ exercise | camel_case }}Test(unittest.TestCase): + {% for mathtypescases in cases %} + # Tests of type: {{ mathtypescases["description"] }} + {% for mathoperationcases in mathtypescases["cases"] %} + # {{ mathoperationcases["description"] }} + {% for case in mathoperationcases["cases"] %} + {% if mathtypescases["description"] == 'Arithmetic' %} + {{ test_case_arithmetic(case) }} + {% elif mathtypescases["description"] == 'Absolute value' %} + {{ test_case_absolutevalue(case) }} + {% elif mathtypescases["description"] == 'Exponentiation of a rational number' %} + {{ test_case_exponentiation(case) }} + {% endif %} + {% endfor %} + {% endfor %} + {% endfor %} +{{ macros.footer() }} \ No newline at end of file diff --git a/exercises/rational-numbers/rational_numbers_test.py b/exercises/rational-numbers/rational_numbers_test.py index a7fe7812f5a..e11c59372d6 100644 --- a/exercises/rational-numbers/rational_numbers_test.py +++ b/exercises/rational-numbers/rational_numbers_test.py @@ -1,138 +1,124 @@ -from __future__ import division - import unittest -from rational_numbers import Rational - +from rational_numbers import abs, add, div, exprational, expreal, mul, reduce, sub # Tests adapted from `problem-specifications//canonical-data.json` @ v1.1.0 + class RationalNumbersTest(unittest.TestCase): - # Test addition - def test_add_two_positive(self): - self.assertEqual(Rational(1, 2) + Rational(2, 3), Rational(7, 6)) + # Tests of type: Arithmetic + + # Addition + + def test_add_two_positive_rational_numbers(self): + pass + + def test_add_a_positive_rational_number_and_a_negative_rational_number(self): + pass + + def test_add_two_negative_rational_numbers(self): + pass + + def test_add_a_rational_number_to_its_additive_inverse(self): + pass + + # Subtraction + + def test_subtract_two_positive_rational_numbers(self): + pass + + def test_subtract_a_positive_rational_number_and_a_negative_rational_number(self): + pass + + def test_subtract_two_negative_rational_numbers(self): + pass - def test_add_positive_and_negative(self): - self.assertEqual(Rational(1, 2) + Rational(-2, 3), Rational(-1, 6)) + def test_subtract_a_rational_number_from_itself(self): + pass - def test_add_two_negative(self): - self.assertEqual(Rational(-1, 2) + Rational(-2, 3), Rational(-7, 6)) + # Multiplication - def test_add_opposite(self): - self.assertEqual(Rational(1, 2) + Rational(-1, 2), Rational(0, 1)) + def test_multiply_two_positive_rational_numbers(self): + pass - # Test subtraction - def test_subtract_two_positive(self): - self.assertEqual(Rational(1, 2) - Rational(2, 3), Rational(-1, 6)) + def test_multiply_a_negative_rational_number_by_a_positive_rational_number(self): + pass - def test_subtract_positive_and_negative(self): - self.assertEqual(Rational(1, 2) - Rational(-2, 3), Rational(7, 6)) + def test_multiply_two_negative_rational_numbers(self): + pass - def test_subtract_two_negative(self): - self.assertEqual(Rational(-1, 2) - Rational(-2, 3), Rational(1, 6)) + def test_multiply_a_rational_number_by_its_reciprocal(self): + pass - def test_subtract_from_self(self): - self.assertEqual(Rational(1, 2) - Rational(1, 2), Rational(0, 1)) + def test_multiply_a_rational_number_by_1(self): + pass - # Test multiplication - def test_multiply_two_positive(self): - self.assertEqual(Rational(1, 2) * Rational(2, 3), Rational(1, 3)) + def test_multiply_a_rational_number_by_0(self): + pass - def test_multiply_negative_by_positive(self): - self.assertEqual(Rational(-1, 2) * Rational(2, 3), Rational(-1, 3)) + # Division - def test_multiply_two_negative(self): - self.assertEqual(Rational(-1, 2) * Rational(-2, 3), Rational(1, 3)) + def test_divide_two_positive_rational_numbers(self): + pass - def test_multiply_reciprocal(self): - self.assertEqual(Rational(1, 2) * Rational(2, 1), Rational(1, 1)) + def test_divide_a_positive_rational_number_by_a_negative_rational_number(self): + pass - def test_multiply_by_one(self): - self.assertEqual(Rational(1, 2) * Rational(1, 1), Rational(1, 2)) + def test_divide_two_negative_rational_numbers(self): + pass - def test_multiply_by_zero(self): - self.assertEqual(Rational(1, 2) * Rational(0, 1), Rational(0, 1)) + def test_divide_a_rational_number_by_1(self): + pass - # Test division - def test_divide_two_positive(self): - self.assertEqual(Rational(1, 2) / Rational(2, 3), Rational(3, 4)) + # Tests of type: Absolute value - def test_divide_positive_by_negative(self): - self.assertEqual(Rational(1, 2) / Rational(-2, 3), Rational(-3, 4)) + # Absolute value of a positive rational number - def test_divide_two_negative(self): - self.assertEqual(Rational(-1, 2) / Rational(-2, 3), Rational(3, 4)) + # Absolute value of a positive rational number with negative numerator and denominator - def test_divide_by_one(self): - self.assertEqual(Rational(1, 2) / Rational(1, 1), Rational(1, 2)) + # Absolute value of a negative rational number - # Test absolute value - def test_absolute_value_of_positive(self): - self.assertEqual(abs(Rational(1, 2)), Rational(1, 2)) + # Absolute value of a negative rational number with negative denominator - def test_absolute_value_of_positive_negative_numerator_denominator(self): - self.assertEqual(abs(Rational(-1, -2)), Rational(1, 2)) + # Absolute value of zero - def test_absolute_value_of_negative(self): - self.assertEqual(abs(Rational(-1, 2)), Rational(1, 2)) + # Tests of type: Exponentiation of a rational number - def test_absolute_value_of_negative_with_negative_denominator(self): - self.assertEqual(abs(Rational(1, -2)), Rational(1, 2)) + # Raise a positive rational number to a positive integer power - def test_absolute_value_of_zero(self): - self.assertEqual(abs(Rational(0, 1)), Rational(0, 1)) + # Raise a negative rational number to a positive integer power - # Test exponentiation of a rational number - def test_raise_a_positive_rational_to_a_positive_integer_power(self): - self.assertEqual(Rational(1, 2) ** 3, Rational(1, 8)) + # Raise zero to an integer power - def test_raise_a_negative_rational_to_a_positive_integer_power(self): - self.assertEqual(Rational(-1, 2) ** 3, Rational(-1, 8)) + # Raise one to an integer power - def test_raise_zero_to_an_integer_power(self): - self.assertEqual(Rational(0, 1) ** 5, Rational(0, 1)) + # Raise a positive rational number to the power of zero - def test_raise_one_to_an_integer_power(self): - self.assertEqual(Rational(1, 1) ** 4, Rational(1, 1)) + # Raise a negative rational number to the power of zero - def test_raise_a_positive_rational_to_the_power_of_zero(self): - self.assertEqual(Rational(1, 2) ** 0, Rational(1, 1)) + # Tests of type: Exponentiation of a real number to a rational number - def test_raise_a_negative_rational_to_the_power_of_zero(self): - self.assertEqual(Rational(-1, 2) ** 0, Rational(1, 1)) + # Raise a real number to a positive rational number - # Test exponentiation of a real number to a rational number - def test_raise_a_real_number_to_a_positive_rational(self): - self.assertAlmostEqual(8 ** Rational(4, 3), 16.0, places=8) + # Raise a real number to a negative rational number - def test_raise_a_real_number_to_a_negative_rational(self): - self.assertAlmostEqual( - 9 ** Rational(-1, 2), 0.3333333333333333, places=8 - ) + # Raise a real number to a zero rational number - def test_raise_a_real_number_to_a_zero_rational(self): - self.assertAlmostEqual(2 ** Rational(0, 1), 1.0, places=8) + # Tests of type: Reduction to lowest terms - # Test reduction to lowest terms - def test_reduce_positive(self): - self.assertEqual(Rational(2, 4), Rational(1, 2)) + # Reduce a positive rational number to lowest terms - def test_reduce_negative(self): - self.assertEqual(Rational(-4, 6), Rational(-2, 3)) + # Reduce a negative rational number to lowest terms - def test_reduce_rational_with_negative_denominator(self): - self.assertEqual(Rational(3, -9), Rational(-1, 3)) + # Reduce a rational number with a negative denominator to lowest terms - def test_reduce_zero(self): - self.assertEqual(Rational(0, 6), Rational(0, 1)) + # Reduce zero to lowest terms - def test_reduce_integer(self): - self.assertEqual(Rational(-14, 7), Rational(-2, 1)) + # Reduce an integer to lowest terms - def test_reduce_one(self): - self.assertEqual(Rational(13, 13), Rational(1, 1)) + # Reduce one to lowest terms -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() From 9786f140aff6d4ada07fce1bc6bc5fd8ce26224f Mon Sep 17 00:00:00 2001 From: Grzegorz Kotfis Date: Tue, 22 Oct 2019 19:00:14 +0200 Subject: [PATCH 02/10] Import Rational type Co-Authored-By: Corey McCandless --- exercises/rational-numbers/.meta/template.j2 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/exercises/rational-numbers/.meta/template.j2 b/exercises/rational-numbers/.meta/template.j2 index d5bb04ade3f..bda7d7b9c60 100644 --- a/exercises/rational-numbers/.meta/template.j2 +++ b/exercises/rational-numbers/.meta/template.j2 @@ -19,7 +19,7 @@ pass {%- endmacro %} -{{ macros.header() }} +{{ macros.header(imports=["Rational"]) }} class {{ exercise | camel_case }}Test(unittest.TestCase): {% for mathtypescases in cases %} @@ -37,4 +37,4 @@ class {{ exercise | camel_case }}Test(unittest.TestCase): {% endfor %} {% endfor %} {% endfor %} -{{ macros.footer() }} \ No newline at end of file +{{ macros.footer() }} From 9c09ea74e89ec336659ba1c06b3ca28ddd857071 Mon Sep 17 00:00:00 2001 From: Grzegorz Kotfis Date: Tue, 22 Oct 2019 19:35:58 +0200 Subject: [PATCH 03/10] Implement arithmetic template --- exercises/rational-numbers/.meta/template.j2 | 29 ++++- .../rational-numbers/rational_numbers_test.py | 104 ++++++++++-------- 2 files changed, 79 insertions(+), 54 deletions(-) diff --git a/exercises/rational-numbers/.meta/template.j2 b/exercises/rational-numbers/.meta/template.j2 index bda7d7b9c60..527e57a486a 100644 --- a/exercises/rational-numbers/.meta/template.j2 +++ b/exercises/rational-numbers/.meta/template.j2 @@ -1,9 +1,22 @@ {%- import "generator_macros.j2" as macros with context -%} +{%- set operators = { + "add": "+", + "sub": "-", + "mul": "*", + "div": "/" +} -%} {% macro test_case_arithmetic(case) -%} + {%- set input = case["input"] -%} + {%- set expected = case["expected"] -%} + {%- set left = "Rational({}, {})".format(input["r1"][0], input["r1"][1]) -%} + {%- set right = "Rational({}, {})".format(input["r2"][0], input["r2"][1]) -%} + {%- set expected = "Rational({}, {})".format(expected[0], expected[1]) -%} + {%- set operator = operators[case["property"]] -%} + def test_{{ case["description"] | to_snake }}(self): - pass + self.assertEqual({{left}} {{operator}} {{right}}, {{expected}}) {%- endmacro %} {% macro test_case_absolutevalue(case) -%} @@ -24,17 +37,21 @@ class {{ exercise | camel_case }}Test(unittest.TestCase): {% for mathtypescases in cases %} # Tests of type: {{ mathtypescases["description"] }} - {% for mathoperationcases in mathtypescases["cases"] %} + {% if mathtypescases["description"] == 'Arithmetic' %} + {% for mathoperationcases in mathtypescases["cases"] %} # {{ mathoperationcases["description"] }} - {% for case in mathoperationcases["cases"] %} - {% if mathtypescases["description"] == 'Arithmetic' %} + {% for case in mathoperationcases["cases"] %} {{ test_case_arithmetic(case) }} - {% elif mathtypescases["description"] == 'Absolute value' %} + {% endfor %} + {% endfor %} + {% else %} + {% for case in mathtypescases["cases"] %} + {% if mathtypescases["description"] == 'Absolute value' %} {{ test_case_absolutevalue(case) }} {% elif mathtypescases["description"] == 'Exponentiation of a rational number' %} {{ test_case_exponentiation(case) }} {% endif %} {% endfor %} - {% endfor %} + {% endif %} {% endfor %} {{ macros.footer() }} diff --git a/exercises/rational-numbers/rational_numbers_test.py b/exercises/rational-numbers/rational_numbers_test.py index e11c59372d6..04f8d2c86ce 100644 --- a/exercises/rational-numbers/rational_numbers_test.py +++ b/exercises/rational-numbers/rational_numbers_test.py @@ -1,6 +1,6 @@ import unittest -from rational_numbers import abs, add, div, exprational, expreal, mul, reduce, sub +from rational_numbers import Rational # Tests adapted from `problem-specifications//canonical-data.json` @ v1.1.0 @@ -12,113 +12,121 @@ class RationalNumbersTest(unittest.TestCase): # Addition def test_add_two_positive_rational_numbers(self): - pass + self.assertEqual(Rational(1, 2) + Rational(2, 3), Rational(7, 6)) def test_add_a_positive_rational_number_and_a_negative_rational_number(self): - pass + self.assertEqual(Rational(1, 2) + Rational(-2, 3), Rational(-1, 6)) def test_add_two_negative_rational_numbers(self): - pass + self.assertEqual(Rational(-1, 2) + Rational(-2, 3), Rational(-7, 6)) def test_add_a_rational_number_to_its_additive_inverse(self): - pass + self.assertEqual(Rational(1, 2) + Rational(-1, 2), Rational(0, 1)) # Subtraction def test_subtract_two_positive_rational_numbers(self): - pass + self.assertEqual(Rational(1, 2) - Rational(2, 3), Rational(-1, 6)) def test_subtract_a_positive_rational_number_and_a_negative_rational_number(self): - pass + self.assertEqual(Rational(1, 2) - Rational(-2, 3), Rational(7, 6)) def test_subtract_two_negative_rational_numbers(self): - pass + self.assertEqual(Rational(-1, 2) - Rational(-2, 3), Rational(1, 6)) def test_subtract_a_rational_number_from_itself(self): - pass + self.assertEqual(Rational(1, 2) - Rational(1, 2), Rational(0, 1)) # Multiplication def test_multiply_two_positive_rational_numbers(self): - pass + self.assertEqual(Rational(1, 2) * Rational(2, 3), Rational(1, 3)) def test_multiply_a_negative_rational_number_by_a_positive_rational_number(self): - pass + self.assertEqual(Rational(-1, 2) * Rational(2, 3), Rational(-1, 3)) def test_multiply_two_negative_rational_numbers(self): - pass + self.assertEqual(Rational(-1, 2) * Rational(-2, 3), Rational(1, 3)) def test_multiply_a_rational_number_by_its_reciprocal(self): - pass + self.assertEqual(Rational(1, 2) * Rational(2, 1), Rational(1, 1)) def test_multiply_a_rational_number_by_1(self): - pass + self.assertEqual(Rational(1, 2) * Rational(1, 1), Rational(1, 2)) def test_multiply_a_rational_number_by_0(self): - pass + self.assertEqual(Rational(1, 2) * Rational(0, 1), Rational(0, 1)) # Division def test_divide_two_positive_rational_numbers(self): - pass + self.assertEqual(Rational(1, 2) / Rational(2, 3), Rational(3, 4)) def test_divide_a_positive_rational_number_by_a_negative_rational_number(self): - pass + self.assertEqual(Rational(1, 2) / Rational(-2, 3), Rational(-3, 4)) def test_divide_two_negative_rational_numbers(self): - pass + self.assertEqual(Rational(-1, 2) / Rational(-2, 3), Rational(3, 4)) def test_divide_a_rational_number_by_1(self): - pass + self.assertEqual(Rational(1, 2) / Rational(1, 1), Rational(1, 2)) # Tests of type: Absolute value - # Absolute value of a positive rational number + def test_absolute_value_of_a_positive_rational_number(self): + # yyy + pass - # Absolute value of a positive rational number with negative numerator and denominator + def test_absolute_value_of_a_positive_rational_number_with_negative_numerator_and_denominator( + self + ): + # yyy + pass - # Absolute value of a negative rational number + def test_absolute_value_of_a_negative_rational_number(self): + # yyy + pass - # Absolute value of a negative rational number with negative denominator + def test_absolute_value_of_a_negative_rational_number_with_negative_denominator( + self + ): + # yyy + pass - # Absolute value of zero + def test_absolute_value_of_zero(self): + # yyy + pass # Tests of type: Exponentiation of a rational number - # Raise a positive rational number to a positive integer power + def test_raise_a_positive_rational_number_to_a_positive_integer_power(self): + # xxx + pass - # Raise a negative rational number to a positive integer power + def test_raise_a_negative_rational_number_to_a_positive_integer_power(self): + # xxx + pass - # Raise zero to an integer power + def test_raise_zero_to_an_integer_power(self): + # xxx + pass - # Raise one to an integer power + def test_raise_one_to_an_integer_power(self): + # xxx + pass - # Raise a positive rational number to the power of zero + def test_raise_a_positive_rational_number_to_the_power_of_zero(self): + # xxx + pass - # Raise a negative rational number to the power of zero + def test_raise_a_negative_rational_number_to_the_power_of_zero(self): + # xxx + pass # Tests of type: Exponentiation of a real number to a rational number - # Raise a real number to a positive rational number - - # Raise a real number to a negative rational number - - # Raise a real number to a zero rational number - # Tests of type: Reduction to lowest terms - # Reduce a positive rational number to lowest terms - - # Reduce a negative rational number to lowest terms - - # Reduce a rational number with a negative denominator to lowest terms - - # Reduce zero to lowest terms - - # Reduce an integer to lowest terms - - # Reduce one to lowest terms - if __name__ == "__main__": unittest.main() From 1b719c1237cb2b856350c46a7f0df14d1a65ecba Mon Sep 17 00:00:00 2001 From: Grzegorz Kotfis Date: Tue, 22 Oct 2019 19:45:22 +0200 Subject: [PATCH 04/10] Implement absolute value template --- exercises/rational-numbers/.meta/template.j2 | 6 ++++-- .../rational-numbers/rational_numbers_test.py | 15 +++++---------- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/exercises/rational-numbers/.meta/template.j2 b/exercises/rational-numbers/.meta/template.j2 index 527e57a486a..c4718dc5e0b 100644 --- a/exercises/rational-numbers/.meta/template.j2 +++ b/exercises/rational-numbers/.meta/template.j2 @@ -20,9 +20,11 @@ {%- endmacro %} {% macro test_case_absolutevalue(case) -%} + {%- set left = "Rational({}, {})".format(case["input"]["r"][0], case["input"]["r"][1]) -%} + {%- set expected = "Rational({}, {})".format(case["expected"][0], case["expected"][1]) -%} + {%- set method = case["property"] -%} def test_{{ case["description"] | to_snake }}(self): - # yyy - pass + self.assertEqual({{method}}({{left}}), {{expected}}) {%- endmacro %} {% macro test_case_exponentiation(case) -%} diff --git a/exercises/rational-numbers/rational_numbers_test.py b/exercises/rational-numbers/rational_numbers_test.py index 04f8d2c86ce..0acd92f791d 100644 --- a/exercises/rational-numbers/rational_numbers_test.py +++ b/exercises/rational-numbers/rational_numbers_test.py @@ -74,28 +74,23 @@ def test_divide_a_rational_number_by_1(self): # Tests of type: Absolute value def test_absolute_value_of_a_positive_rational_number(self): - # yyy - pass + self.assertEqual(abs(Rational(1, 2)), Rational(1, 2)) def test_absolute_value_of_a_positive_rational_number_with_negative_numerator_and_denominator( self ): - # yyy - pass + self.assertEqual(abs(Rational(-1, -2)), Rational(1, 2)) def test_absolute_value_of_a_negative_rational_number(self): - # yyy - pass + self.assertEqual(abs(Rational(-1, 2)), Rational(1, 2)) def test_absolute_value_of_a_negative_rational_number_with_negative_denominator( self ): - # yyy - pass + self.assertEqual(abs(Rational(1, -2)), Rational(1, 2)) def test_absolute_value_of_zero(self): - # yyy - pass + self.assertEqual(abs(Rational(0, 1)), Rational(0, 1)) # Tests of type: Exponentiation of a rational number From e717dce6cce90ca76b70dc6b2955551ad5092d72 Mon Sep 17 00:00:00 2001 From: Grzegorz Kotfis Date: Tue, 22 Oct 2019 19:54:41 +0200 Subject: [PATCH 05/10] Implement exponentiation template --- exercises/rational-numbers/.meta/template.j2 | 12 ++++++++---- .../rational-numbers/rational_numbers_test.py | 18 ++++++------------ 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/exercises/rational-numbers/.meta/template.j2 b/exercises/rational-numbers/.meta/template.j2 index c4718dc5e0b..84cce6da7ff 100644 --- a/exercises/rational-numbers/.meta/template.j2 +++ b/exercises/rational-numbers/.meta/template.j2 @@ -4,7 +4,8 @@ "add": "+", "sub": "-", "mul": "*", - "div": "/" + "div": "/", + "exprational": "**" } -%} {% macro test_case_arithmetic(case) -%} @@ -28,10 +29,13 @@ {%- endmacro %} {% macro test_case_exponentiation(case) -%} - {%- set input = case["input"] -%} + {%- set left = "Rational({}, {})".format(case["input"]["r"][0], case["input"]["r"][1]) -%} + {%- set right = case["input"]["n"] -%} + {%- set expected = "Rational({}, {})".format(case["expected"][0], case["expected"][1]) -%} + {%- set operator = operators[case["property"]] -%} + def test_{{ case["description"] | to_snake }}(self): - # xxx - pass + self.assertEqual({{left}} {{operator}} {{right}}, {{expected}}) {%- endmacro %} {{ macros.header(imports=["Rational"]) }} diff --git a/exercises/rational-numbers/rational_numbers_test.py b/exercises/rational-numbers/rational_numbers_test.py index 0acd92f791d..26a3e0e2465 100644 --- a/exercises/rational-numbers/rational_numbers_test.py +++ b/exercises/rational-numbers/rational_numbers_test.py @@ -95,28 +95,22 @@ def test_absolute_value_of_zero(self): # Tests of type: Exponentiation of a rational number def test_raise_a_positive_rational_number_to_a_positive_integer_power(self): - # xxx - pass + self.assertEqual(Rational(1, 2) ** 3, Rational(1, 8)) def test_raise_a_negative_rational_number_to_a_positive_integer_power(self): - # xxx - pass + self.assertEqual(Rational(-1, 2) ** 3, Rational(-1, 8)) def test_raise_zero_to_an_integer_power(self): - # xxx - pass + self.assertEqual(Rational(0, 1) ** 5, Rational(0, 1)) def test_raise_one_to_an_integer_power(self): - # xxx - pass + self.assertEqual(Rational(1, 1) ** 4, Rational(1, 1)) def test_raise_a_positive_rational_number_to_the_power_of_zero(self): - # xxx - pass + self.assertEqual(Rational(1, 2) ** 0, Rational(1, 1)) def test_raise_a_negative_rational_number_to_the_power_of_zero(self): - # xxx - pass + self.assertEqual(Rational(-1, 2) ** 0, Rational(1, 1)) # Tests of type: Exponentiation of a real number to a rational number From 2e390402ae487a4e5ae6cdfa03c3e66972e19e26 Mon Sep 17 00:00:00 2001 From: Grzegorz Kotfis Date: Tue, 22 Oct 2019 20:07:51 +0200 Subject: [PATCH 06/10] Implement exp real and reduce template --- exercises/rational-numbers/.meta/template.j2 | 25 ++++++++++++++++- .../rational-numbers/rational_numbers_test.py | 27 +++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/exercises/rational-numbers/.meta/template.j2 b/exercises/rational-numbers/.meta/template.j2 index 84cce6da7ff..7fe7706da64 100644 --- a/exercises/rational-numbers/.meta/template.j2 +++ b/exercises/rational-numbers/.meta/template.j2 @@ -5,7 +5,8 @@ "sub": "-", "mul": "*", "div": "/", - "exprational": "**" + "exprational": "**", + "expreal": "**" } -%} {% macro test_case_arithmetic(case) -%} @@ -38,6 +39,24 @@ self.assertEqual({{left}} {{operator}} {{right}}, {{expected}}) {%- endmacro %} +{% macro test_case_exponentiation_real(case) -%} + {%- set x = case["input"]["x"] -%} + {%- set r = "Rational({}, {})".format(case["input"]["r"][0], case["input"]["r"][1]) -%} + {%- set expected = case["expected"] -%} + {%- set operator = operators[case["property"]] -%} + + def test_{{ case["description"] | to_snake }}(self): + self.assertEqual({{x}} {{operator}} {{r}}, {{expected}}) +{%- endmacro %} + +{% macro test_case_reduction(case) -%} + {%- set r = "Rational({}, {})".format(case["input"]["r"][0], case["input"]["r"][1]) -%} + {%- set expected = "Rational({}, {})".format(case["expected"][0], case["expected"][1]) -%} + + def test_{{ case["description"] | to_snake }}(self): + self.assertEqual({{r}}, {{expected}}) +{%- endmacro %} + {{ macros.header(imports=["Rational"]) }} class {{ exercise | camel_case }}Test(unittest.TestCase): @@ -56,6 +75,10 @@ class {{ exercise | camel_case }}Test(unittest.TestCase): {{ test_case_absolutevalue(case) }} {% elif mathtypescases["description"] == 'Exponentiation of a rational number' %} {{ test_case_exponentiation(case) }} + {% elif mathtypescases["description"] == 'Exponentiation of a real number to a rational number' %} + {{ test_case_exponentiation_real(case) }} + {% elif mathtypescases["description"] == 'Reduction to lowest terms' %} + {{ test_case_reduction(case) }} {% endif %} {% endfor %} {% endif %} diff --git a/exercises/rational-numbers/rational_numbers_test.py b/exercises/rational-numbers/rational_numbers_test.py index 26a3e0e2465..cfa4b79b113 100644 --- a/exercises/rational-numbers/rational_numbers_test.py +++ b/exercises/rational-numbers/rational_numbers_test.py @@ -114,8 +114,35 @@ def test_raise_a_negative_rational_number_to_the_power_of_zero(self): # Tests of type: Exponentiation of a real number to a rational number + def test_raise_a_real_number_to_a_positive_rational_number(self): + self.assertEqual(8 ** Rational(4, 3), 16.0) + + def test_raise_a_real_number_to_a_negative_rational_number(self): + self.assertEqual(9 ** Rational(-1, 2), 0.3333333333333333) + + def test_raise_a_real_number_to_a_zero_rational_number(self): + self.assertEqual(2 ** Rational(0, 1), 1.0) + # Tests of type: Reduction to lowest terms + def test_reduce_a_positive_rational_number_to_lowest_terms(self): + self.assertEqual(Rational(2, 4), Rational(1, 2)) + + def test_reduce_a_negative_rational_number_to_lowest_terms(self): + self.assertEqual(Rational(-4, 6), Rational(-2, 3)) + + def test_reduce_a_rational_number_with_a_negative_denominator_to_lowest_terms(self): + self.assertEqual(Rational(3, -9), Rational(-1, 3)) + + def test_reduce_zero_to_lowest_terms(self): + self.assertEqual(Rational(0, 6), Rational(0, 1)) + + def test_reduce_an_integer_to_lowest_terms(self): + self.assertEqual(Rational(-14, 7), Rational(-2, 1)) + + def test_reduce_one_to_lowest_terms(self): + self.assertEqual(Rational(13, 13), Rational(1, 1)) + if __name__ == "__main__": unittest.main() From 6313c409d851178bc078e1322e9d3952cc1e44b4 Mon Sep 17 00:00:00 2001 From: Grzegorz Kotfis Date: Tue, 22 Oct 2019 20:11:44 +0200 Subject: [PATCH 07/10] Cleanup template --- exercises/rational-numbers/.meta/template.j2 | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/exercises/rational-numbers/.meta/template.j2 b/exercises/rational-numbers/.meta/template.j2 index 7fe7706da64..f64a12de55e 100644 --- a/exercises/rational-numbers/.meta/template.j2 +++ b/exercises/rational-numbers/.meta/template.j2 @@ -10,33 +10,31 @@ } -%} {% macro test_case_arithmetic(case) -%} - {%- set input = case["input"] -%} - {%- set expected = case["expected"] -%} - {%- set left = "Rational({}, {})".format(input["r1"][0], input["r1"][1]) -%} - {%- set right = "Rational({}, {})".format(input["r2"][0], input["r2"][1]) -%} - {%- set expected = "Rational({}, {})".format(expected[0], expected[1]) -%} + {%- set r1 = "Rational({}, {})".format(case["input"]["r1"][0], case["input"]["r1"][1]) -%} + {%- set r2 = "Rational({}, {})".format(case["input"]["r2"][0], case["input"]["r2"][1]) -%} + {%- set expected = "Rational({}, {})".format(case["expected"][0], case["expected"][1]) -%} {%- set operator = operators[case["property"]] -%} def test_{{ case["description"] | to_snake }}(self): - self.assertEqual({{left}} {{operator}} {{right}}, {{expected}}) + self.assertEqual({{r1}} {{operator}} {{r2}}, {{expected}}) {%- endmacro %} {% macro test_case_absolutevalue(case) -%} - {%- set left = "Rational({}, {})".format(case["input"]["r"][0], case["input"]["r"][1]) -%} + {%- set r = "Rational({}, {})".format(case["input"]["r"][0], case["input"]["r"][1]) -%} {%- set expected = "Rational({}, {})".format(case["expected"][0], case["expected"][1]) -%} {%- set method = case["property"] -%} def test_{{ case["description"] | to_snake }}(self): - self.assertEqual({{method}}({{left}}), {{expected}}) + self.assertEqual({{method}}({{r}}), {{expected}}) {%- endmacro %} {% macro test_case_exponentiation(case) -%} - {%- set left = "Rational({}, {})".format(case["input"]["r"][0], case["input"]["r"][1]) -%} - {%- set right = case["input"]["n"] -%} + {%- set r = "Rational({}, {})".format(case["input"]["r"][0], case["input"]["r"][1]) -%} + {%- set n = case["input"]["n"] -%} {%- set expected = "Rational({}, {})".format(case["expected"][0], case["expected"][1]) -%} {%- set operator = operators[case["property"]] -%} def test_{{ case["description"] | to_snake }}(self): - self.assertEqual({{left}} {{operator}} {{right}}, {{expected}}) + self.assertEqual({{r}} {{operator}} {{n}}, {{expected}}) {%- endmacro %} {% macro test_case_exponentiation_real(case) -%} From 437f4e1d370c762b371d8254506e26a459d4e3bb Mon Sep 17 00:00:00 2001 From: Grzegorz Kotfis Date: Tue, 22 Oct 2019 20:24:08 +0200 Subject: [PATCH 08/10] Extract nested loops to methods --- exercises/rational-numbers/.meta/template.j2 | 46 ++++++++++++-------- 1 file changed, 29 insertions(+), 17 deletions(-) diff --git a/exercises/rational-numbers/.meta/template.j2 b/exercises/rational-numbers/.meta/template.j2 index f64a12de55e..e62ce98c2d9 100644 --- a/exercises/rational-numbers/.meta/template.j2 +++ b/exercises/rational-numbers/.meta/template.j2 @@ -55,30 +55,42 @@ self.assertEqual({{r}}, {{expected}}) {%- endmacro %} -{{ macros.header(imports=["Rational"]) }} +{% macro render_arithmetic_cases(mathtypescases) -%} -class {{ exercise | camel_case }}Test(unittest.TestCase): - {% for mathtypescases in cases %} - # Tests of type: {{ mathtypescases["description"] }} - {% if mathtypescases["description"] == 'Arithmetic' %} - {% for mathoperationcases in mathtypescases["cases"] %} + {% for mathoperationcases in mathtypescases["cases"] %} # {{ mathoperationcases["description"] }} - {% for case in mathoperationcases["cases"] %} + {% for case in mathoperationcases["cases"] %} {{ test_case_arithmetic(case) }} - {% endfor %} - {% endfor %} - {% else %} - {% for case in mathtypescases["cases"] %} - {% if mathtypescases["description"] == 'Absolute value' %} + {% endfor %} + {% endfor %} + +{%- endmacro %} + +{% macro render_other_cases(mathtypescases) -%} + + {% for case in mathtypescases["cases"] %} + {% if mathtypescases["description"] == 'Absolute value' %} {{ test_case_absolutevalue(case) }} - {% elif mathtypescases["description"] == 'Exponentiation of a rational number' %} + {% elif mathtypescases["description"] == 'Exponentiation of a rational number' %} {{ test_case_exponentiation(case) }} - {% elif mathtypescases["description"] == 'Exponentiation of a real number to a rational number' %} + {% elif mathtypescases["description"] == 'Exponentiation of a real number to a rational number' %} {{ test_case_exponentiation_real(case) }} - {% elif mathtypescases["description"] == 'Reduction to lowest terms' %} + {% elif mathtypescases["description"] == 'Reduction to lowest terms' %} {{ test_case_reduction(case) }} - {% endif %} - {% endfor %} + {% endif %} + {% endfor %} + +{%- endmacro %} + +{{ macros.header(imports=["Rational"]) }} + +class {{ exercise | camel_case }}Test(unittest.TestCase): + {% for mathtypescases in cases %} + # Tests of type: {{ mathtypescases["description"] }} + {% if mathtypescases["description"] == 'Arithmetic' %} + {{ render_arithmetic_cases(mathtypescases) }} + {% else %} + {{ render_other_cases(mathtypescases) }} {% endif %} {% endfor %} {{ macros.footer() }} From c1b2302cc70174c3c85b61057d28e9bc9db63024 Mon Sep 17 00:00:00 2001 From: Grzegorz Kotfis Date: Wed, 23 Oct 2019 08:56:10 +0200 Subject: [PATCH 09/10] fix exponentiation real tests assertion --- exercises/rational-numbers/.meta/template.j2 | 2 +- exercises/rational-numbers/rational_numbers_test.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/exercises/rational-numbers/.meta/template.j2 b/exercises/rational-numbers/.meta/template.j2 index e62ce98c2d9..be9b4892347 100644 --- a/exercises/rational-numbers/.meta/template.j2 +++ b/exercises/rational-numbers/.meta/template.j2 @@ -44,7 +44,7 @@ {%- set operator = operators[case["property"]] -%} def test_{{ case["description"] | to_snake }}(self): - self.assertEqual({{x}} {{operator}} {{r}}, {{expected}}) + self.assertAlmostEqual({{x}} {{operator}} {{r}}, {{expected}}, places=8) {%- endmacro %} {% macro test_case_reduction(case) -%} diff --git a/exercises/rational-numbers/rational_numbers_test.py b/exercises/rational-numbers/rational_numbers_test.py index cfa4b79b113..3a86b7467d2 100644 --- a/exercises/rational-numbers/rational_numbers_test.py +++ b/exercises/rational-numbers/rational_numbers_test.py @@ -115,13 +115,13 @@ def test_raise_a_negative_rational_number_to_the_power_of_zero(self): # Tests of type: Exponentiation of a real number to a rational number def test_raise_a_real_number_to_a_positive_rational_number(self): - self.assertEqual(8 ** Rational(4, 3), 16.0) + self.assertAlmostEqual(8 ** Rational(4, 3), 16.0, places=8) def test_raise_a_real_number_to_a_negative_rational_number(self): - self.assertEqual(9 ** Rational(-1, 2), 0.3333333333333333) + self.assertAlmostEqual(9 ** Rational(-1, 2), 0.3333333333333333, places=8) def test_raise_a_real_number_to_a_zero_rational_number(self): - self.assertEqual(2 ** Rational(0, 1), 1.0) + self.assertAlmostEqual(2 ** Rational(0, 1), 1.0, places=8) # Tests of type: Reduction to lowest terms From 766a4fc386493a8d18c90c9d9ae0e3b91cc58e1f Mon Sep 17 00:00:00 2001 From: Grzegorz Kotfis Date: Fri, 25 Oct 2019 08:22:09 +0200 Subject: [PATCH 10/10] Python 2 compatibilty - import division --- exercises/rational-numbers/.meta/template.j2 | 1 + exercises/rational-numbers/rational_numbers_test.py | 1 + 2 files changed, 2 insertions(+) diff --git a/exercises/rational-numbers/.meta/template.j2 b/exercises/rational-numbers/.meta/template.j2 index be9b4892347..3af451e0416 100644 --- a/exercises/rational-numbers/.meta/template.j2 +++ b/exercises/rational-numbers/.meta/template.j2 @@ -82,6 +82,7 @@ {%- endmacro %} +from __future__ import division {{ macros.header(imports=["Rational"]) }} class {{ exercise | camel_case }}Test(unittest.TestCase): diff --git a/exercises/rational-numbers/rational_numbers_test.py b/exercises/rational-numbers/rational_numbers_test.py index 3a86b7467d2..d44729954a0 100644 --- a/exercises/rational-numbers/rational_numbers_test.py +++ b/exercises/rational-numbers/rational_numbers_test.py @@ -1,3 +1,4 @@ +from __future__ import division import unittest from rational_numbers import Rational