From 1f82d14376cb35670a01886f3e5f427298e208cb Mon Sep 17 00:00:00 2001 From: Yrahcaz7 <74512479+Yrahcaz7@users.noreply.github.com> Date: Fri, 15 May 2026 21:15:46 -0500 Subject: [PATCH] Clean up Darts approach docs --- .../.approaches/booleans-as-ints/content.md | 10 ++-- .../.approaches/booleans-as-ints/snippet.txt | 4 +- .../practice/darts/.approaches/config.json | 22 +++++--- .../.approaches/dict-and-dict-get/content.md | 22 ++++---- .../.approaches/dict-and-dict-get/snippet.txt | 2 +- .../.approaches/dict-and-generator/content.md | 37 +++++++------ .../dict-and-generator/snippet.txt | 13 ++--- .../.approaches/if-statements/content.md | 27 +++++---- .../.approaches/if-statements/snippet.txt | 4 +- .../darts/.approaches/introduction.md | 55 ++++++++++--------- .../darts/.approaches/match-case/content.md | 30 +++++----- .../darts/.approaches/match-case/snippet.txt | 4 +- .../.approaches/tuple-and-loop/content.md | 14 +++-- .../.approaches/tuple-and-loop/snippet.txt | 13 +++-- 14 files changed, 136 insertions(+), 121 deletions(-) diff --git a/exercises/practice/darts/.approaches/booleans-as-ints/content.md b/exercises/practice/darts/.approaches/booleans-as-ints/content.md index d3c1541d2a6..c948f3d631c 100644 --- a/exercises/practice/darts/.approaches/booleans-as-ints/content.md +++ b/exercises/practice/darts/.approaches/booleans-as-ints/content.md @@ -3,8 +3,8 @@ ```python def score(x_coord, y_coord): - radius = (x_coord**2 + y_coord**2) - return (radius<=1)*5 + (radius<=25)*4 + (radius<=100)*1 + radius_squared = x_coord**2 + y_coord**2 + return (radius_squared<=1)*5 + (radius_squared<=25)*4 + (radius_squared<=100)*1 ``` @@ -25,12 +25,12 @@ Instead, the Python documentation recommends an explicit conversion to `int`: ```python def score(x_coord, y_coord): - radius = (x_coord**2 + y_coord**2) - return int(radius<=1)*5 + int(radius<=25)*4 + int(radius<=100)*1 + radius_squared = x_coord**2 + y_coord**2 + return int(radius_squared<=1)*5 + int(radius_squared<=25)*4 + int(radius_squared<=100)*1 ``` Beyond that recommendation, the terseness of this approach might be harder to reason about or decode — especially if a programmer is coming from a programming langauge that does not treat Boolean values as `ints`. -Despite the "radius" variable name, it is also more difficult to relate the scoring "rings" of the Dartboard to the values being checked and calculated in the `return` statement. +Despite the "radius_squared" variable name, it is also more difficult to relate the scoring "rings" of the Dartboard to the values being checked and calculated in the `return` statement. If using this code in a larger program, it would be strongly recommended that a docstring be provided to explain the Dartboard rings, scoring rules, and the corresponding scores. [bools-as-ints]: https://docs.python.org/3/library/stdtypes.html#boolean-type-bool \ No newline at end of file diff --git a/exercises/practice/darts/.approaches/booleans-as-ints/snippet.txt b/exercises/practice/darts/.approaches/booleans-as-ints/snippet.txt index ec7dcfabbfc..f09eb53386f 100644 --- a/exercises/practice/darts/.approaches/booleans-as-ints/snippet.txt +++ b/exercises/practice/darts/.approaches/booleans-as-ints/snippet.txt @@ -1,3 +1,3 @@ def score(x_coord, y_coord): - radius = (x_coord**2 + y_coord**2) - return (radius<=1)*5 + (radius<=25)*4 +(radius<=100)*1 \ No newline at end of file + radius_squared = x_coord**2 + y_coord**2 + return (radius_squared<=1)*5 + (radius_squared<=25)*4 + (radius_squared<=100)*1 \ No newline at end of file diff --git a/exercises/practice/darts/.approaches/config.json b/exercises/practice/darts/.approaches/config.json index 77f331bfce0..337f370bf9e 100644 --- a/exercises/practice/darts/.approaches/config.json +++ b/exercises/practice/darts/.approaches/config.json @@ -1,7 +1,7 @@ { "introduction": { "authors": ["bethanyg"], - "contributors": [] + "contributors": ["yrahcaz7"] }, "approaches": [ { @@ -9,42 +9,48 @@ "slug": "if-statements", "title": "Use If Statements", "blurb": "Use if-statements to check scoring boundaries for a dart throw.", - "authors": ["bethanyg"] + "authors": ["bethanyg"], + "contributors": ["yrahcaz7"] }, { "uuid": "f8f5533a-09d2-4b7b-9dec-90f268bfc03b", "slug": "tuple-and-loop", "title": "Use a Tuple & Loop through Scores", "blurb": "Score the Dart throw by looping through a tuple of scores.", - "authors": ["bethanyg"] + "authors": ["bethanyg"], + "contributors": ["yrahcaz7"] }, { "uuid": "a324f99e-15bb-43e0-9181-c1652094bc4f", "slug": "match-case", "title": "Use Structural Pattern Matching ('Match-Case')", "blurb": "Use a Match-Case (Structural Pattern Matching) to score the dart throw.)", - "authors": ["bethanyg"] + "authors": ["bethanyg"], + "contributors": ["yrahcaz7"] }, { "uuid": "966bd2dd-c4fd-430b-ad77-3a304dedd82e", "slug": "dict-and-generator", "title": "Use a Dictionary with a Generator Expression", "blurb": "Use a generator expression looping over a scoring dictionary, getting the max score for the dart throw.", - "authors": ["bethanyg"] + "authors": ["bethanyg"], + "contributors": ["yrahcaz7"] }, { "uuid": "5b087f50-31c5-4b84-9116-baafd3a30ed6", "slug": "booleans-as-ints", "title": "Use Boolean Values as Integers", "blurb": "Use True and False as integer values to calculate the score of the dart throw.", - "authors": ["bethanyg"] + "authors": ["bethanyg"], + "contributors": ["yrahcaz7"] }, { "uuid": "0b2dbcd3-f0ac-45f7-af75-3451751fd21f", "slug": "dict-and-dict-get", "title": "Use a Dictionary with dict.get", - "blurb": "Loop over a dictionary and retrieve score via dct.get.", - "authors": ["bethanyg"] + "blurb": "Loop over a dictionary and retrieve score via dict.get.", + "authors": ["bethanyg"], + "contributors": ["yrahcaz7"] } ] } \ No newline at end of file diff --git a/exercises/practice/darts/.approaches/dict-and-dict-get/content.md b/exercises/practice/darts/.approaches/dict-and-dict-get/content.md index a3c5bc2ac58..62c79f36a0d 100644 --- a/exercises/practice/darts/.approaches/dict-and-dict-get/content.md +++ b/exercises/practice/darts/.approaches/dict-and-dict-get/content.md @@ -3,11 +3,11 @@ ```python def score(x_coord, y_coord): - point = (x_coord**2 + y_coord**2) + point = x_coord**2 + y_coord**2 scores = { point <= 100: 1, point <= 25: 5, - point <= 1: 10 + point <= 1: 10, } return scores.get(True, 0) @@ -17,10 +17,10 @@ At first glance, this approach looks similar to the [Booleans as Integers][appro However, this approach is **not** interpreting Booleans as integers and is instead exploiting three key properties of [dictionaries][dicts]: -1. [Keys must be hashable][hashable-keys] — in other words, keys have to be _unique_. -2. Insertion order is preserved (_as of `Python 3.7`_), and evaluation/iteration happens in insertion order. -3. Duplicate keys _overwrite_ existing keys. - If the first key is `True` and the third key is `True`, the _value_ from the third key will overwrite the value from the first key. +1. [Keys must be hashable][hashable-keys] — in other words, keys have to be _unique_. +2. Insertion order is preserved (_as of `Python 3.7`_), and evaluation/iteration happens in insertion order. +3. Duplicate keys _overwrite_ existing keys. + If the first key is `True` and the third key is `True`, the _value_ from the third key will overwrite the value from the first key. Finally, the `return` line uses [`dict.get()`][dict-get] to `return` a default value of 0 when a throw is outside the existing circle radii. To see this in action, you can view this code on [Python Tutor][dict-get-python-tutor]. @@ -34,9 +34,8 @@ The following code variations do not pass the exercise tests: ```python - def score(x_coord, y_coord): - point = (x_coord**2 + y_coord**2) + point = x_coord**2 + y_coord**2 scores = { point <= 1: 10, point <= 25: 5, @@ -44,11 +43,11 @@ def score(x_coord, y_coord): } return scores.get(True, 0) - - #OR# + +#OR# def score(x_coord, y_coord): - point = (x_coord**2 + y_coord**2) + point = x_coord**2 + y_coord**2 scores = { point <= 25: 5, point <= 1: 10, @@ -56,7 +55,6 @@ def score(x_coord, y_coord): } return scores.get(True, 0) - ``` While this approach is a _very clever_ use of dictionary properties, it is likely to be very hard to reason about for those who are not deeply knowledgeable. diff --git a/exercises/practice/darts/.approaches/dict-and-dict-get/snippet.txt b/exercises/practice/darts/.approaches/dict-and-dict-get/snippet.txt index 6d496f54d33..8d2f426d84e 100644 --- a/exercises/practice/darts/.approaches/dict-and-dict-get/snippet.txt +++ b/exercises/practice/darts/.approaches/dict-and-dict-get/snippet.txt @@ -1,5 +1,5 @@ def score(x_coord, y_coord): - point = (x_coord**2 + y_coord**2) + point = x_coord**2 + y_coord**2 scores = {point <= 100: 1, point <= 25: 5, point <= 1: 10} return scores.get(True, 0) \ No newline at end of file diff --git a/exercises/practice/darts/.approaches/dict-and-generator/content.md b/exercises/practice/darts/.approaches/dict-and-generator/content.md index 30ffeac1eb0..57e2ba3ecd9 100644 --- a/exercises/practice/darts/.approaches/dict-and-generator/content.md +++ b/exercises/practice/darts/.approaches/dict-and-generator/content.md @@ -3,14 +3,15 @@ ```python def score(x_coord, y_coord): throw = x_coord**2 + y_coord**2 - rules = {1: 10, 25: 5, 100: 1, 200: 0} + rules = {1: 10, 25: 5, 100: 1} - return max(point for distance, point in - rules.items() if throw <= distance) + return max(point for distance, point in + rules.items() if throw <= distance, + default=0) ``` -This approach is very similar to the [tuple and loop][approach-tuple-and-loop] approach, but iterates over [`dict.items()`][dict-items] and writes the `loop` as a [`generator-expression`][generator-expression] inside `max()`. +This approach is very similar to the [tuple and loop][approach-tuple-and-loop] approach, but iterates over [`dict.items()`][dict-items] and writes the `loop` as a [`generator-expression`][generator-expression] inside `max()`. In cases where the scoring circles overlap, `max()` will return the maximum score available for the throw. The generator expression inside `max()` is the equivalent of using a `for-loop` and a variable to determine the max score: @@ -24,6 +25,7 @@ def score(x_coord, y_coord): for distance, point in rules.items(): if throw <= distance and point > max_score: max_score = point + return max_score ``` @@ -33,19 +35,21 @@ A `list` or `tuple` can also be used in place of `max()`, but then requires an i ```python def score(x_coord, y_coord): throw = x_coord**2 + y_coord**2 - rules = {1: 10, 25: 5, 100: 1, 200: 0} + rules = {1: 10, 25: 5, 100: 1} - return [point for distance, point in - rules.items() if throw <= distance][0] #<-- have to specify index 0. - + return ([point for distance, point in + rules.items() if throw <= distance] + or [0])[0] # <-- Have to specify index 0. + #OR# def score(x_coord, y_coord): throw = x_coord**2 + y_coord**2 - rules = {1: 10, 25: 5, 100: 1, 200: 0} + rules = {1: 10, 25: 5, 100: 1} - return tuple(point for distance, point in - rules.items() if throw <= distance)[0] + return (tuple(point for distance, point in + rules.items() if throw <= distance) + or (0,))[0] ``` @@ -53,10 +57,11 @@ This solution can even be reduced to a "one-liner". However, this is not performant, and is difficult to read: ```python -def score(x_coord, y_coord): - return max(point for distance, point in - {1: 10, 25: 5, 100: 1, 200: 0}.items() if - (x_coord**2 + y_coord**2) <= distance) +def score(x_coord, y_coord): + return max(point for distance, point in + {1: 10, 25: 5, 100: 1}.items() if + (x_coord**2 + y_coord**2) <= distance, + default=0) ``` While all of these variations do pass the tests, they suffer from even more over-engineering/performance caution than the earlier tuple and loop approach (_although for the data in this problem, the performance hit is slight_). @@ -64,6 +69,6 @@ Additionally, the dictionary will take much more space in memory than using a `t In some circumstances, these variations might also be harder to reason about for those not familiar with `generator-expressions` or `list comprehensions`. -[approach-tuple-and-loop]: https://exercism.org/tracks/python/exercises/darts/approaches/tuple-and-loop +[approach-tuple-and-loop]: https://exercism.org/tracks/python/exercises/darts/approaches/tuple-and-loop [dict-items]: https://docs.python.org/3/library/stdtypes.html#dict.items [generator-expression]: https://dbader.org/blog/python-generator-expressions diff --git a/exercises/practice/darts/.approaches/dict-and-generator/snippet.txt b/exercises/practice/darts/.approaches/dict-and-generator/snippet.txt index f6649cf3a92..6738920c4e7 100644 --- a/exercises/practice/darts/.approaches/dict-and-generator/snippet.txt +++ b/exercises/practice/darts/.approaches/dict-and-generator/snippet.txt @@ -1,8 +1,7 @@ def score(x_coord, y_coord): - length = x_coord**2 + y_coord**2 - rules = {1.0: 10, 25.0: 5, 100.0: 1, 200: 0} - score = max(point for - distance, point in - rules.items() if length <= distance) - - return score \ No newline at end of file + throw = x_coord**2 + y_coord**2 + rules = {1: 10, 25: 5, 100: 1} + + return max(point for distance, point in + rules.items() if throw <= distance, + default=0) \ No newline at end of file diff --git a/exercises/practice/darts/.approaches/if-statements/content.md b/exercises/practice/darts/.approaches/if-statements/content.md index 40e2886ddb5..9bbb7ecf8c4 100644 --- a/exercises/practice/darts/.approaches/if-statements/content.md +++ b/exercises/practice/darts/.approaches/if-statements/content.md @@ -9,8 +9,8 @@ def score(x_coord, y_coord): distance = math.sqrt(x_coord**2 + y_coord**2) if distance <= 1: return 10 - if distance <= 5: return 5 - if distance <= 10: return 1 + if distance <= 5: return 5 + if distance <= 10: return 1 return 0 ``` @@ -21,23 +21,23 @@ Because the `if-statements` are simple and readable, they're written on one line Zero is returned if no other check is true. -To avoid importing the `math` module (_for a very very slight speedup_), (x**2 +y**2) can be calculated instead, and the scoring rings can be adjusted to 1, 25, and 100: +To avoid importing the `math` module (_for a very very slight speedup_), (`x**2 + y**2`) can be calculated instead, and the scoring rings can be adjusted to 1, 25, and 100: ```python # Checks scores from the center --> edge. def score(x_coord, y_coord): - distance = x_coord**2 + y_coord**2 + distance_squared = x_coord**2 + y_coord**2 - if distance <= 1: return 10 - if distance <= 25: return 5 - if distance <= 100: return 1 + if distance_squared <= 1: return 10 + if distance_squared <= 25: return 5 + if distance_squared <= 100: return 1 return 0 ``` -# Variation 1: Check from Edge to Center Using Upper and Lower Bounds +## Variation 1: Check from Edge to Center Using Upper and Lower Bounds ```python @@ -56,18 +56,17 @@ def score(x_coord, y_coord): This variant checks from the edge moving inward, checking both a lower and upper bound due to the overlapping scoring circles in this direction. -Scores for any of these solutions can also be assigned to a variable to avoid multiple `returns`, but this isn't really necessary: +Scores for any of these solutions can also be assigned to a variable to avoid multiple `returns`, but this isn't really necessary: ```python # Checks scores from the edge --> center def score(x_coord, y_coord): - distance = x_coord**2 + y_coord**2 + distance_squared = x_coord**2 + y_coord**2 points = 10 - if distance > 100: points = 0 - if 25 < distance <= 100: points = 1 - if 1 < distance <= 25: points = 5 + if distance_squared > 100: points = 0 + if 25 < distance_squared <= 100: points = 1 + if 1 < distance_squared <= 25: points = 5 return points ``` - diff --git a/exercises/practice/darts/.approaches/if-statements/snippet.txt b/exercises/practice/darts/.approaches/if-statements/snippet.txt index 18537416e2f..b91a4285e6d 100644 --- a/exercises/practice/darts/.approaches/if-statements/snippet.txt +++ b/exercises/practice/darts/.approaches/if-statements/snippet.txt @@ -3,6 +3,6 @@ import math def score(x_coord, y_coord): distance = math.sqrt(x_coord**2 + y_coord**2) if distance <= 1: return 10 - if distance <= 5: return 5 - if distance <= 10: return 1 + if distance <= 5: return 5 + if distance <= 10: return 1 return 0 \ No newline at end of file diff --git a/exercises/practice/darts/.approaches/introduction.md b/exercises/practice/darts/.approaches/introduction.md index cf7c6a23dd5..f4ca20dcf0c 100644 --- a/exercises/practice/darts/.approaches/introduction.md +++ b/exercises/practice/darts/.approaches/introduction.md @@ -1,7 +1,7 @@ # Introduction -There are multiple Pythonic ways to solve the Darts exercise. +There are multiple Pythonic ways to solve the Darts exercise. Among them are: - Using `if-statements` @@ -17,10 +17,10 @@ Among them are: The goal of the Darts exercise is to score a single throw in a Darts game. The scoring areas are _concentric circles_, so boundary values need to be checked in order to properly score a throw. -The key is to determine how far from the center the dart lands (_by calculating sqrt(x**2 + y**2), or a variation_) and then determine what scoring ring it falls into. +The key is to determine how far from the center the dart lands (_by calculating `sqrt(x**2 + y**2)`, or a variation_) and then determine what scoring ring it falls into. -**_Order matters_** - each bigger target circle contains all the smaller circles, so the most straightforward solution is to check the smallest circle first. +**_Order matters_** — each bigger target circle contains all the smaller circles, so the most straightforward solution is to check the smallest circle first. Otherwise, you must box your scoring by checking both a _lower bound_ and an _upper bound_. @@ -38,8 +38,8 @@ def score(x_coord, y_coord): distance = math.sqrt(x_coord**2 + y_coord**2) if distance <= 1: return 10 - if distance <= 5: return 5 - if distance <= 10: return 1 + if distance <= 5: return 5 + if distance <= 10: return 1 return 0 ``` @@ -49,16 +49,18 @@ This approach uses [concept:python/conditionals]() to check the boundaries for e For more details, see the [if statements][approach-if-statements] approach. -## Approach: Using a `tuple` and a `loop` +## Approach: Using a `tuple` and a `loop` ```python def score(x_coord, y_coord): throw = x_coord**2 + y_coord**2 - rules = (1, 10), (25, 5), (100, 1), (200, 0) + rules = (1, 10), (25, 5), (100, 1) for distance, points in rules: if throw <= distance: return points + + return 0 ``` @@ -71,34 +73,35 @@ For more details, see the [tuple and loop][approach-tuple-and-loop] approach. ```python def score(x_coord, y_coord): throw = x_coord**2 + y_coord**2 - rules = {1: 10, 25: 5, 100: 1, 200: 0} + rules = {1: 10, 25: 5, 100: 1} - return max(point for distance, point in - rules.items() if throw <= distance) + return max(point for distance, point in + rules.items() if throw <= distance, + default=0) ``` -This approach is very similar to the [tuple and loop][approach-tuple-and-loop] approach, but iterates over [`dict.items()`][dict-items]. -For more information, see the [dict and generator][approach-dict-and-generator] approach. +This approach is very similar to the [tuple and loop][approach-tuple-and-loop] approach, but iterates over [`dict.items()`][dict-items]. +For more information, see the [dict and generator][approach-dict-and-generator] approach. ## Approach: Using Boolean Values as Integers ```python def score(x_coord, y_coord): - radius = (x_coord**2 + y_coord**2) - return (radius<=1)*5 + (radius<=25)*4 +(radius<=100)*1 + radius_squared = x_coord**2 + y_coord**2 + return (radius_squared<=1)*5 + (radius_squared<=25)*4 + (radius_squared<=100)*1 ``` This approach exploits the fact that Boolean values are an integer subtype in Python. -For more information, see the [boolean values as integers][approach-boolean-values-as-integers] approach. +For more information, see the [boolean values as integers][approach-booleans-as-ints] approach. ## Approach: Using a `Dictionary` and `dict.get()` ```python def score(x_coord, y_coord): - point = (x_coord**2 + y_coord**2) + point = x_coord**2 + y_coord**2 scores = { point <= 100: 1, point <= 25: 5, @@ -109,17 +112,17 @@ def score(x_coord, y_coord): ``` This approach uses a dictionary to hold the distance --> scoring mappings and `dict.get()` to retrieve the correct points value. -For more details, read the [`Dictionary and dict.get()`][approach-dict-and-dict-get] approach. +For more details, read the [`Dictionary and dict.get()`][approach-dict-and-dict-get] approach. -## Approach: Using `match/case` (structural pattern matching) +## Approach: Using `match/case` (structural pattern matching) ```python from math import hypot, ceil -def score(x, y): - match ceil(hypot(x, y)): +def score(x_coord, y_coord): + match ceil(hypot(x_coord, y_coord)): case 0 | 1: return 10 case 2 | 3 | 4 | 5: return 5 case 6 | 7 | 8 | 9 | 10: return 1 @@ -129,7 +132,7 @@ def score(x, y): This approach uses `Python 3.10`'s structural pattern matching with `return` values on the same line as `case`. A fallthrough case (`_`) is used if the dart throw is outside the outer circle of the target (_greater than 10_). -For more details, see the [structural pattern matching][approach-struct-pattern-matching] approach. +For more details, see the [structural pattern matching][approach-match-case] approach. ## Which approach to use? @@ -137,10 +140,10 @@ For more details, see the [structural pattern matching][approach-struct-pattern- Many of these approaches are a matter of personal preference - there are not significant memory or performance differences. Although a strong argument could be made for simplicity and clarity — many listed solutions (_while interesting_) are harder to reason about or are over-engineered for the current scope of the exercise. -[approach-boolean-values-as-integers]: https://exercism.org/tracks/python/exercises/darts/approaches/boolean-values-as-integers -[approach-dict-and-dict-get]: https://exercism.org/tracks/python/exercises/darts/approaches/dict-and-dict-get +[approach-booleans-as-ints]: https://exercism.org/tracks/python/exercises/darts/approaches/booleans-as-ints +[approach-dict-and-dict-get]: https://exercism.org/tracks/python/exercises/darts/approaches/dict-and-dict-get [approach-dict-and-generator]: https://exercism.org/tracks/python/exercises/darts/approaches/dict-and-generator -[approach-if-statements ]: https://exercism.org/tracks/python/exercises/darts/approaches/if-statements -[approach-struct-pattern-matching]: https://exercism.org/tracks/python/exercises/darts/approaches/struct-pattern-matching -[approach-tuple-and-loop]: https://exercism.org/tracks/python/exercises/darts/approaches/tuple-and-loop +[approach-if-statements ]: https://exercism.org/tracks/python/exercises/darts/approaches/if-statements +[approach-match-case]: https://exercism.org/tracks/python/exercises/darts/approaches/match-case +[approach-tuple-and-loop]: https://exercism.org/tracks/python/exercises/darts/approaches/tuple-and-loop [dict-items]: https://docs.python.org/3/library/stdtypes.html#dict.items diff --git a/exercises/practice/darts/.approaches/match-case/content.md b/exercises/practice/darts/.approaches/match-case/content.md index 04430a5dc52..39bb3c35b8b 100644 --- a/exercises/practice/darts/.approaches/match-case/content.md +++ b/exercises/practice/darts/.approaches/match-case/content.md @@ -5,8 +5,8 @@ from math import hypot, ceil -def score(x, y): - throw = ceil(hypot(x, y)) +def score(x_coord, y_coord): + throw = ceil(hypot(x_coord, y_coord)) match throw: case 0 | 1: return 10 @@ -16,8 +16,8 @@ def score(x, y): #OR# -def score(x, y): - match ceil(hypot(x, y)): +def score(x_coord, y_coord): + match ceil(hypot(x_coord, y_coord)): case 0 | 1: return 10 case 2 | 3 | 4 | 5: return 5 case 6 | 7 | 8 | 9 | 10: return 1 @@ -26,16 +26,16 @@ def score(x, y): This approach uses `Python 3.10`'s [`structural pattern matching`][structural-pattern-matching] with `return` values on the same line as `case`. Because the match is numeric, each case explicitly lists allowed values using the `|` (OR) operator. -A fallthrough case (`_`) is used if the dart throw is greater than 10 (_the outer circle radius of the target_). -This is equivalent to using `if-statements` to check throw values although some might argue it is clearer to read. +A fallthrough case (`_`) is used if the dart throw is greater than 10 (_the outer circle radius of the target_). +This is equivalent to using `if-statements` to check throw values, although some might argue it is clearer to read. An `if-statement` equivalent would be: ```python from math import hypot, ceil -def score(x, y): - throw = ceil(hypot(x, y)) +def score(x_coord, y_coord): + throw = ceil(hypot(x_coord, y_coord)) if throw in (0, 1): return 10 if throw in (2, 3, 4, 5): return 5 @@ -51,8 +51,8 @@ One can also use `<`, `>`, or `<=` and `>=` in structural pattern matching, alth from math import hypot, ceil -def score(x, y): - throw = ceil(hypot(x, y)) +def score(x_coord, y_coord): + throw = ceil(hypot(x_coord, y_coord)) match throw: case throw if throw <= 1: return 10 @@ -63,17 +63,17 @@ def score(x, y): Finally, one can use an [assignment expression][assignment-expression] or [walrus operator][walrus] to calculate the throw value rather than calculating and assigning a variable on a separate line. -This isn't necessary (_the first variations shows this clearly_) and might be harder to reason about/understand for some programmers: +This isn't necessary (_the previous variations show this clearly_) and might be harder to reason about/understand for some programmers: ```python from math import hypot, ceil -def score(x, y): - match throw := ceil(hypot(x, y)): +def score(x_coord, y_coord): + match throw := ceil(hypot(x_coord, y_coord)): case throw if throw <= 1: return 10 - case throw if throw <=5: return 5 - case throw if throw <=10: return 1 + case throw if throw <= 5: return 5 + case throw if throw <= 10: return 1 case _: return 0 ``` diff --git a/exercises/practice/darts/.approaches/match-case/snippet.txt b/exercises/practice/darts/.approaches/match-case/snippet.txt index e66b5382b21..564f4999491 100644 --- a/exercises/practice/darts/.approaches/match-case/snippet.txt +++ b/exercises/practice/darts/.approaches/match-case/snippet.txt @@ -1,7 +1,7 @@ from math import hypot, ceil -def score(x, y): - match ceil(hypot(x, y)): +def score(x_coord, y_coord): + match ceil(hypot(x_coord, y_coord)): case 0 | 1: return 10 case 2 | 3 | 4 | 5: return 5 case 6 | 7 | 8 | 9 | 10: return 1 diff --git a/exercises/practice/darts/.approaches/tuple-and-loop/content.md b/exercises/practice/darts/.approaches/tuple-and-loop/content.md index 042b9e88ae9..ec92b3142e9 100644 --- a/exercises/practice/darts/.approaches/tuple-and-loop/content.md +++ b/exercises/practice/darts/.approaches/tuple-and-loop/content.md @@ -3,11 +3,13 @@ ```python def score(x_coord, y_coord): throw = x_coord**2 + y_coord**2 - rules = (1, 10), (25, 5), (100, 1), (200, 0) + rules = (1, 10), (25, 5), (100, 1) for distance, points in rules: if throw <= distance: return points + + return 0 ``` This approach uses a loop to iterate through the _rules_ `tuple`, unpacking each (`distance`, `points`) pair (_For a little more on unpacking, see [Tuple Unpacking Improves Python Code Readability][tuple-unpacking]_). @@ -24,16 +26,18 @@ def score(x_coord, y_coord): return points return 0 - + #OR# def score(x_coord, y_coord): throw = x_coord**2 + y_coord**2 - rules = [(1, 10), (25, 5), (100, 1), (200, 0)] + rules = [(1, 10), (25, 5), (100, 1)] for distance, points in rules: if throw <= distance: return points + + return 0 #OR# @@ -48,8 +52,8 @@ def score(x_coord, y_coord): return 0 ``` -This approach would work nicely in a scenario where you expect to be adding more scoring "rings", since it is cleaner to edit the data structure than to add additional `if-statements` as you would have to in the [`if-statement` approach][approach-if-statements ]. +This approach would work nicely in a scenario where you expect to be adding more scoring "rings", since it is cleaner to edit the data structure than to add additional `if-statements` as you would have to in the [`if-statement` approach][approach-if-statements]. For the three rings as defined by the current exercise, it is a bit over-engineered to use a data structure + `loop`, and results in a slight (_**very** slight_) slowdown over using `if-statements`. [tuple-unpacking]: https://treyhunner.com/2018/03/tuple-unpacking-improves-python-code-readability/#Unpacking_in_a_for_loop -[approach-if-statements ]: https://exercism.org/tracks/python/exercises/darts/approaches/if-statements +[approach-if-statements]: https://exercism.org/tracks/python/exercises/darts/approaches/if-statements diff --git a/exercises/practice/darts/.approaches/tuple-and-loop/snippet.txt b/exercises/practice/darts/.approaches/tuple-and-loop/snippet.txt index ad505005263..f777f4c04ec 100644 --- a/exercises/practice/darts/.approaches/tuple-and-loop/snippet.txt +++ b/exercises/practice/darts/.approaches/tuple-and-loop/snippet.txt @@ -1,7 +1,8 @@ def score(x_coord, y_coord): - distance = x_coord**2 + y_coord**2 - rules = (1.0, 10), (25.0, 5), (100.0, 1), (200.0, 0) - - for distance, point in rules: - if length <= distance: - return point \ No newline at end of file + throw = x_coord**2 + y_coord**2 + rules = (1, 10), (25, 5), (100, 1) + + for distance, points in rules: + if throw <= distance: + return points + return 0 \ No newline at end of file