Skip to content

[Practice Exercises]: Add Better Error Handling Instructions & Tests for Error Raising Messages (# 7 of 8) #2727

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Nov 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion exercises/practice/rational-numbers/.meta/template.j2
Original file line number Diff line number Diff line change
Expand Up @@ -94,4 +94,3 @@ class {{ exercise | camel_case }}Test(unittest.TestCase):
{{ render_other_cases(mathtypescases) }}
{% endif %}
{% endfor %}
{{ macros.footer(True) }}
8 changes: 0 additions & 8 deletions exercises/practice/rational-numbers/rational_numbers_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,11 +145,3 @@ def test_reduce_an_integer_to_lowest_terms(self):

def test_reduce_one_to_lowest_terms(self):
self.assertEqual(Rational(13, 13), Rational(1, 1))

# Utility functions
def assertRaisesWithMessage(self, exception):
return self.assertRaisesRegex(exception, r".+")


if __name__ == "__main__":
unittest.main()
3 changes: 0 additions & 3 deletions exercises/practice/robot-simulator/.meta/template.j2
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,3 @@ class {{ exercise | camel_case }}Test(unittest.TestCase):
{% for case in supercase["cases"] -%}
{{ test_case(case) }}
{% endfor %}{% endfor %}


{{ macros.footer(True) }}
8 changes: 0 additions & 8 deletions exercises/practice/robot-simulator/robot_simulator_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,11 +141,3 @@ def test_moving_east_and_north(self):

self.assertEqual(robot.coordinates, (11, 5))
self.assertEqual(robot.direction, NORTH)

# Utility functions
def assertRaisesWithMessage(self, exception):
return self.assertRaisesRegex(exception, r".+")


if __name__ == "__main__":
unittest.main()
2 changes: 0 additions & 2 deletions exercises/practice/roman-numerals/.meta/template.j2
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,3 @@ class {{ exercise | camel_case }}Test(unittest.TestCase):
def test_{{ case["description"] | to_snake }}(self):
self.assertEqual({{ case["property"] }}({{ case["input"]["number"] }}), "{{ case["expected"] }}")
{% endfor %}

{{ macros.footer(True) }}
8 changes: 0 additions & 8 deletions exercises/practice/roman-numerals/roman_numerals_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,3 @@ def test_1024_is_mxxiv(self):

def test_3000_is_mmm(self):
self.assertEqual(roman(3000), "MMM")

# Utility functions
def assertRaisesWithMessage(self, exception):
return self.assertRaisesRegex(exception, r".+")


if __name__ == "__main__":
unittest.main()
3 changes: 0 additions & 3 deletions exercises/practice/run-length-encoding/.meta/template.j2
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,3 @@ class {{ exercise | camel_case }}Test(unittest.TestCase):
{{ test_case(case, title_modifier) }}
{% endfor %}
{% endfor %}


{{ macros.footer(True) }}
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,3 @@ def test_decode_lowercase_string(self):

def test_encode_followed_by_decode_gives_original_string(self):
self.assertMultiLineEqual(decode(encode("zzz ZZ zZ")), "zzz ZZ zZ")

# Utility functions
def assertRaisesWithMessage(self, exception):
return self.assertRaisesRegex(exception, r".+")


if __name__ == "__main__":
unittest.main()
14 changes: 14 additions & 0 deletions exercises/practice/saddle-points/.docs/instructions.append.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Instructions append

## Exception messages

Sometimes it is necessary to [raise an exception](https://docs.python.org/3/tutorial/errors.html#raising-exceptions). When you do this, you should always include a **meaningful error message** to indicate what the source of the error is. This makes your code more readable and helps significantly with debugging. For situations where you know that the error source will be a certain type, you can choose to raise one of the [built in error types](https://docs.python.org/3/library/exceptions.html#base-classes), but should still include a meaningful message.

This particular exercise requires that you use the [raise statement](https://docs.python.org/3/reference/simple_stmts.html#the-raise-statement) to "throw" a `ValueError` if the `matrix` is irregular. The tests will only pass if you both `raise` the `exception` and include a message with it.

To raise a `ValueError` with a message, write the message as an argument to the `exception` type:

```python
# if the matrix is irregular
raise ValueError("irregular matrix")
```
7 changes: 3 additions & 4 deletions exercises/practice/saddle-points/.meta/template.j2
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ irregular.
matrix = []
{% endif -%}
{% if case is error_case -%}
with self.assertRaisesWithMessage(ValueError):
with self.assertRaises(ValueError) as err:
{{- case["property"] | to_snake }}(matrix)
self.assertEqual(type(err.exception), ValueError)
self.assertEqual(err.exception.args[0], "{{ case["expected"]["error"] }}")
{% else -%}
self.assertEqual(
sorted_points({{ case["property"] | to_snake }}(matrix)),
Expand All @@ -44,6 +46,3 @@ class {{ exercise | camel_case }}Test(unittest.TestCase):
{{ test_case(case) }}
{% endfor %}
{%- endif %}


{{ macros.footer(True) }}
12 changes: 3 additions & 9 deletions exercises/practice/saddle-points/saddle_points_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,13 +96,7 @@ def test_can_identify_that_saddle_points_in_a_single_row_matrix_are_those_with_t

def test_irregular_matrix(self):
matrix = [[3, 2, 1], [0, 1], [2, 1, 0]]
with self.assertRaisesWithMessage(ValueError):
with self.assertRaises(ValueError) as err:
saddle_points(matrix)

# Utility functions
def assertRaisesWithMessage(self, exception):
return self.assertRaisesRegex(exception, r".+")


if __name__ == "__main__":
unittest.main()
self.assertEqual(type(err.exception), ValueError)
self.assertEqual(err.exception.args[0], "irregular matrix")
20 changes: 20 additions & 0 deletions exercises/practice/satellite/.docs/instructions.append.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Instructions append

## Exception messages

Sometimes it is necessary to [raise an exception](https://docs.python.org/3/tutorial/errors.html#raising-exceptions). When you do this, you should always include a **meaningful error message** to indicate what the source of the error is. This makes your code more readable and helps significantly with debugging. For situations where you know that the error source will be a certain type, you can choose to raise one of the [built in error types](https://docs.python.org/3/library/exceptions.html#base-classes), but should still include a meaningful message.

This particular exercise requires that you use the [raise statement](https://docs.python.org/3/reference/simple_stmts.html#the-raise-statement) to "throw" a `ValueError` if the `preorder` and `inorder` arguments are mis-matched length-wise, element-wise, or the elements are not unique. The tests will only pass if you both `raise` the `exception` and include a message with it.

To raise a `ValueError` with a message, write the message as an argument to the `exception` type:

```python
# if preorder and inorder are not the same length
raise ValueError("traversals must have the same length")

# if preorder and inorder do not share the same elements
raise ValueError("traversals must have the same elements")

# if element repeat (are not unique)
raise ValueError("traversals must contain unique items")
```
6 changes: 3 additions & 3 deletions exercises/practice/satellite/.meta/template.j2
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ class {{ exercise | camel_case }}Test(unittest.TestCase):
preorder = {{ case["input"]["preorder"] }}
inorder = {{ case["input"]["inorder"] }}
{% if "Reject" in case["description"] %}
with self.assertRaisesWithMessage(ValueError):
with self.assertRaises(ValueError) as err:
{{ case["property"] | to_snake }}(preorder, inorder)
self.assertEqual(type(err.exception), ValueError)
self.assertEqual(err.exception.args[0], "{{ case["expected"]["error"] }}")
{% else %}
expected = {{ case["expected"] }}
self.assertEqual({{ case["property"] | to_snake }}(preorder, inorder), expected)
{% endif %}
{% endfor %}

{{ macros.footer() }}
22 changes: 11 additions & 11 deletions exercises/practice/satellite/satellite_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,27 +41,27 @@ def test_reject_traversals_of_different_length(self):
preorder = ["a", "b"]
inorder = ["b", "a", "r"]

with self.assertRaisesWithMessage(ValueError):
with self.assertRaises(ValueError) as err:
tree_from_traversals(preorder, inorder)
self.assertEqual(type(err.exception), ValueError)
self.assertEqual(err.exception.args[0], "traversals must have the same length")

def test_reject_inconsistent_traversals_of_same_length(self):
preorder = ["x", "y", "z"]
inorder = ["a", "b", "c"]

with self.assertRaisesWithMessage(ValueError):
with self.assertRaises(ValueError) as err:
tree_from_traversals(preorder, inorder)
self.assertEqual(type(err.exception), ValueError)
self.assertEqual(
err.exception.args[0], "traversals must have the same elements"
)

def test_reject_traversals_with_repeated_items(self):
preorder = ["a", "b", "a"]
inorder = ["b", "a", "a"]

with self.assertRaisesWithMessage(ValueError):
with self.assertRaises(ValueError) as err:
tree_from_traversals(preorder, inorder)

# Utility functions
def assertRaisesWithMessage(self, exception):
return self.assertRaisesRegex(exception, r".+")


if __name__ == "__main__":
unittest.main()
self.assertEqual(type(err.exception), ValueError)
self.assertEqual(err.exception.args[0], "traversals must contain unique items")