Skip to content

Commit 7875b77

Browse files
authored
Fixed links and other lingering typos. (exercism#3790)
1 parent c592280 commit 7875b77

File tree

4 files changed

+39
-12
lines changed

4 files changed

+39
-12
lines changed

exercises/practice/wordy/.approaches/dunder-getattribute/content.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,17 @@ def answer(question):
3737
This approach begins by defining a [dictionary][dictionaries] of the word keys with their related [`dunder-methods`][dunder] methods.
3838
Since only whole numbers are involved, the available `dunder-methods` are those for the [`int`][int] class/namespace.
3939
The supported methods for the `int()` namespace can be found by using `print(dir(int))` or `print(int.__dict__)` in a Python terminal.
40-
See [SO: Difference between dir() and __dict__][dir-vs-__dict__] for differences between the two.
40+
See [`SO: Difference between dir() and __dict__`][dir-vs-__dict__] for more details.
41+
42+
<br>
4143

4244
~~~~exercism/note
4345
The built-in [`dir`](https://docs.python.org/3/library/functions.html?#dir) function returns a list of all valid attributes for an object.
4446
The `dunder-method` [`<object>.__dict__`](https://docs.python.org/3/reference/datamodel.html#object.__dict__) is a mapping of an objects writable attributes.
4547
~~~~
4648

49+
<br>
50+
4751
The `OPS` dictionary is defined with all uppercase letters, which is the naming convention for a Python [constant][const].
4852
It indicates that the value should not be changed.
4953

exercises/practice/wordy/.approaches/functools-reduce/content.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,9 @@ A `try-except` is not needed here because the error scenarios are already filter
7272
But it is also hard to understand what is happening if you have not worked with a reduce or foldl function in the past.
7373
It could be argued that writing the code as a `while-loop` or recursive function is easier to reason about for non-functional programmers.
7474

75+
<br>
7576

76-
## Variation: 1: Use a Dictionary of `lambdas` instead of importing from operator
77+
## Variation 1: Use a Dictionary of `lambdas` instead of importing from operator
7778

7879

7980
The imports from operator can be swapped out for a dictionary of `lambda-expressions` (or calls to `dunder-methods`), if so desired.
@@ -119,7 +120,6 @@ def answer(question):
119120
return result
120121
```
121122

122-
123123
[approach-lambdas-in-a-dictionary]: https://exercism.org/tracks/python/exercises/wordy/approaches/lambdas-in-a-dictionary
124124
[callable]: https://treyhunner.com/2019/04/is-it-a-class-or-a-function-its-a-callable/
125125
[functools-reduce]: https://docs.python.org/3/library/functools.html#functools.reduce

exercises/practice/wordy/.approaches/introduction.md

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,12 @@ A whole class of error can be eliminated up front by checking if a question star
2222
Any other question formulation becomes a `ValueError("unknown operation")`.
2323
This could lead to future maintenance issues if the definition of a question ever changes or operations are added, but for the purposes of passing the current Wordy tests, it works well.
2424

25+
<br>
2526

2627
~~~~exercism/note
2728
There are many Pythonic ways to go about the cleaning, parsing, and calculation steps of Wordy.
28-
However, the solutions all follow these general steps:
29+
However, solutions all follow the same general steps:
30+
2931
3032
1. Remove the parts of the question string that do not apply to calculating the answer.
3133
2. Iterate over the question, determining which words are numbers, and which are meant to be mathematical operations.
@@ -38,6 +40,7 @@ However, the solutions all follow these general steps:
3840
6. Once the question is calculated down to a single number, that is the answer. Anything else that happens in the loop/iteration or within the accumulated result is a `ValueError("syntax error")`.
3941
~~~~
4042

43+
<br>
4144

4245
For question cleaning, [`str.removeprefix`][removeprefix] and
4346
[`str.removesuffix`][removesuffix] introduced in `Python 3.9` can be very useful:
@@ -95,6 +98,7 @@ Some solutions use either [lambda][lambdas] expressions, [dunder/"special" metho
9598
However, the exercise can be solved without using `operator`, `lambdas`, `dunder-methods` or `eval`.
9699
It is recommended that you first start by solving it _without_ "advanced" strategies, and then refine your solution into something more compact or complex as you learn and practice.
97100

101+
<br>
98102

99103
~~~~exercism/caution
100104
Using [`eval`][eval] for the operations might seem convenient, but it is a [dangerous][eval-danger] and possibly [destructive][eval-destructive] approach.
@@ -158,6 +162,7 @@ Alternatives could use a [dictionary][dict] to store word --> operator mappings
158162

159163
For more details and variations, read the [String, List and Dictionary Methods][approach-string-list-and-dict-methods] approach.
160164

165+
<br>
161166

162167
## Approach: Import Callables from the Operator Module
163168

@@ -199,6 +204,7 @@ Like the first approach, it uses a [try-except][handling-exceptions] block for h
199204

200205
For more details and options, take a look at the [Import Callables from the Operator Module][approach-import-callables-from-operator] approach.
201206

207+
<br>
202208

203209
## Approach: Regex and the Operator Module
204210

@@ -257,6 +263,7 @@ It is longer than some solutions, but clearer and potentially easier to maintain
257263

258264
For more details, take a look at the [regex-with-operator-module][approach-regex-with-operator-module] approach.
259265

266+
<br>
260267

261268
## Approach: Lambdas in a Dictionary to return Functions
262269

@@ -306,6 +313,7 @@ These "hand-crafted" `lambdas` could also introduce a mathematical error, althou
306313

307314
For more details, take a look at the [Lambdas in a Dictionary][approach-lambdas-in-a-dictionary] approach.
308315

316+
<br>
309317

310318
## Approach: Recursion
311319

@@ -351,6 +359,7 @@ The dictionary in this example could use functions from `operator`, `lambdas`, `
351359

352360
For more details, take a look at the [recursion][approach-recursion] approach.
353361

362+
<br>
354363

355364
## Approach: functools.reduce()
356365

@@ -393,6 +402,7 @@ This solution may be a little less clear to follow or reason about due to the sl
393402

394403
For more details and variations, take a look at the [functools.reduce for Calculation][approach-functools-reduce] approach.
395404

405+
<br>
396406

397407
## Approach: Dunder methods with `__getattribute__`
398408

@@ -444,7 +454,7 @@ For more detail on this solution, take a look at the [dunder method with `__geta
444454
[approach-dunder-getattribute]: https://exercism.org/tracks/python/exercises/wordy/approaches/dunder-getattribute
445455
[approach-functools-reduce]: https://exercism.org/tracks/python/exercises/wordy/approaches/functools-reduce
446456
[approach-import-callables-from-operator]: https://exercism.org/tracks/python/exercises/wordy/approaches/import-callables-from-operator
447-
[approach-lambdas-in-a-dictionary]: https://exercsim.org/tracks/python/exercises/wordy/approaches/lambdas-in-a-dictionary
457+
[approach-lambdas-in-a-dictionary]: https://exercism.org/tracks/python/exercises/wordy/approaches/lambdas-in-a-dictionary
448458
[approach-recursion]: https://exercism.org/tracks/python/exercises/wordy/approaches/recursion
449459
[approach-regex-with-operator-module]: https://exercism.org/tracks/python/exercises/wordy/approaches/regex-with-operator-module
450460
[approach-string-list-and-dict-methods]: https://exercism.org/tracks/python/exercises/wordy/approaches/string-list-and-dict-methods

exercises/practice/wordy/.approaches/recursion/content.md

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,21 @@
55
A recursive strategy [may not always be obvious][looping-vs-recursion] or easy — but it is always possible.
66
So the `while-loop`s used in other approaches to Wordy can be re-written to use recursive calls.
77

8+
<br>
9+
810
That being said, Python famously does not perform [tail-call optimization][tail-call-optimization], and limits recursive calls on the stack to a depth of 1000 frames, so it is important to only use recursion where you are confident that it can complete within the limit (_or something close to it_).
911
[Memoization][memoization] and other strategies in [dynamic programming][dynamic-programming] can help to make recursion more efficient and "shorter" in Python, but it's always good to give it careful consideration.
1012

13+
<br>
14+
1115
Recursion works best with problem spaces that resemble trees, include [backtracking][backtracking], or become progressively smaller.
12-
Some examples include financial processes like calculating [amortization][amortization] and [depreciation][depreciation], tracking [radiation reduction through nuclei decay][nuclei-decay], and algorithms like [biscetion search][bisection-search], [depth-firs search][dfs], and [merge sort][merge-sort].
16+
Some examples include financial processes like calculating [amortization][amortization] and [depreciation][depreciation], tracking [radiation reduction through nuclei decay][nuclei-decay], and algorithms like [biscetion search][bisection-search], [depth-first search][dfs], and [merge sort][merge-sort].
17+
18+
<br>
1319

14-
Other algorithms such as [breadth-first search][bfs], [Dijkstra's algorithm][dijkstra], and the [Bellman-Ford Algorithm][bellman-ford] lend themselves better to iteration.
20+
Other algorithms such as [breadth-first search][bfs], [Dijkstra's algorithm][dijkstra], and the [Bellman-Ford Algorithm][bellman-ford] lend themselves better to loops.
1521

22+
<br>
1623

1724
```python
1825
from operator import add, mul, sub
@@ -68,13 +75,16 @@ This approach separates the solution into three functions:
6875
2. `clean()`, which takes a question string and returns a `list` of parsed words and numbers to calculate from.
6976
3. `calculate()`, which performs the calculations on the `list` recursively, until a single number (_the base case check_) is returned as the answer — or an error is thrown.
7077

78+
<br>
79+
7180
The cleaning logic is separate from the processing logic so that the cleaning steps aren't repeated over and over with each recursive `calculate()` call.
72-
This separation also makes it easier to make changes in processing or calculating without creating conflict or confusion.
81+
This separation also makes it easier to make changes without creating conflict or confusion.
7382

74-
Note that `calculate()` performs the same steps as the `while-loop` from [Import Callables from the Operator Module][approach-import-callables-from-operator] and others.
83+
`calculate()` performs the same steps as the `while-loop` from [Import Callables from the Operator Module][approach-import-callables-from-operator] and others.
7584
The difference being that the `while-loop` test for `len()` 1 now occurs as an `if` condition in the function (_the base case_), and the "looping" is now a call to `calculate()` in the `else` condition.
7685
`calculate()` can also use many of the strategies detailed in other approaches, as long as they work with the recursion.
7786

87+
<br>
7888

7989
`clean()` can also use any of the strategies detailed in other approaches, two of which are below:
8090

@@ -91,6 +101,7 @@ The difference being that the `while-loop` test for `len()` 1 now occurs as an `
91101
question.strip("?").split())) #<-- The () in list() also invokes implicit concatenation.
92102
```
93103

104+
<br>
94105

95106
## Variation 1: Use Regex for matching, cleaning, and calculating
96107

@@ -184,6 +195,7 @@ Because each new iteration of the question needs to be validated, there is an `i
184195

185196
Note that the `for-loop` and VALIDATE use [`re.match`][re-match], but DIGITS validation uses [`re.fullmatch`][re-fullmatch].
186197

198+
<br>
187199

188200
## Variation 2: Use Regex, Recurse within the For-loop
189201

@@ -229,13 +241,14 @@ This saves some space, but requires that the nested `tuples` be unpacked as the
229241
Recursion is used a bit differently here from the previous variations — the calls are placed [within the `for-loop`][recursion-within-loops].
230242
Because the regex are more generic, they will match a `digit-operation-digit` trio in a longer question, so the line `return operation(calculate(match['x']), calculate(match['y']))` is effectively splitting a question into parts that can then be worked on in their own stack frames.
231243

244+
232245
For example:
233246

234247
1. "1 plus -10 multiplied by 13 divided by 2" would match on "1 plus -10" (_group x_) **multiplied by** "13 divided by 2" (_group y_).
235-
2. This would then be re-arranged to `mul(calculate("1 plus -10"), calculate("13 divided by 2"))`
248+
2. This is re-arranged to `mul(calculate("1 plus -10"), calculate("13 divided by 2"))`
236249
3. At this point the loop would pause as the two recursive calls to `calculate()` spawn
237-
4. The loops would run again — and so would the calls to `calculate()`, until there wasn't any match that caused a split of the question or an error.
238-
5. One at a time, the numbers would then be returned, until the main `mul(calculate("1 plus -10"), calculate("13 divided by 2"))` could be solved, at which point the answer would be returned.
250+
4. The loops then run again — and so would the calls to `calculate()`, until there wasn't any match that caused a split of the question or an error.
251+
5. One at a time, the numbers would then be returned, until the main `mul(calculate("1 plus -10"), calculate("13 divided by 2"))` could be solved, at which point the answer is returned.
239252

240253
For a more visual picture, you can step through the code on [pythontutor.com][recursion-in-loop-pythontutor].
241254

0 commit comments

Comments
 (0)