|
| 1 | +# Hints |
| 2 | + |
| 3 | +## General |
| 4 | + |
| 5 | +- This challenge is all about validating, "cleaning up", and processing the given question in the **_correct order_**. |
| 6 | +- If you read the directions and tests carefully, you will find there are three conditions that need to be met for a question to be "valid". |
| 7 | +If a question is not valid, you will need to [raise ][raise-statement] a [ValueError][value-error] with a message (_`ValueError("unknown operation")`_). |
| 8 | + It is best if you get this particular check out of the way before doing anything else. |
| 9 | +- Processing a question before calculating the answer is all about utilizing [string methods][str-methods]. |
| 10 | +A few popular ones to investigate include `str.removeprefix`, `str.removesuffix`, `str.replace`, and `str.strip`. |
| 11 | +Others you might want to check out are `str.startswith`, `str.endswith`, and `in` (_which can apply to more than just strings_). |
| 12 | + |
| 13 | +- It is possible to iterate over a string. However, it is **much** easier to iterate over a list of _words_ if the string you are processing is a sentence or fragment with spaces. [`str.split`][split] can break apart a string and return a list of "words". |
| 14 | +- A [`while-loop`][while-loop] is very useful for iterating over the question to process items. |
| 15 | +- For fewer error checks and cleaner error-handling, a [`try-except`][handling-exceptions] is recommended as you process the question. |
| 16 | +- **Remember**: the question is processed **_left-to-right_**. That means "1 plus 12 minus 3 multiplied by 4" gets processed by: |
| 17 | + - Calculating "1 plus 12" (13), |
| 18 | + - Calculating "13 minus 3" (10), |
| 19 | + - Calculating "10 multiplied by 4" (40). |
| 20 | + - The result of the first calculation is _concatenated with the remainder of the question to form a new question for the next step_. |
| 21 | + - This technique is sometimes called [the accumulator pattern][accumulator-pattern], or [fold][fold] / [foldl][foldl] in functional programming languages like [Haskell][haskell-folds] or Lisp. |
| 22 | + - Python includes two methods that are purpose-built to apply the `accumulator-pattern` to iterable data structures like `lists`, `tuples`, and `strings`. |
| 23 | + [`functools.reduce`][reduce] and [`itertools.accumulate`][accumulate] could be interesting to investigate here. |
| 24 | + |
| 25 | +- This exercise has many potential solutions and many paths you can take along the way. |
| 26 | + No path is manifestly "better" than another, although a particular path may be more interesting or better suited to what you want to learn or explore right now. |
| 27 | + |
| 28 | + |
| 29 | +[accumulate]: https://docs.python.org/3/library/itertools.html#itertools.accumulate |
| 30 | +[accumulator-pattern]: https://muzny.github.io/csci1200-notes/08/2/accumulator.html |
| 31 | +[fold]: https://en.wikipedia.org/wiki/Fold_(higher-order_function) |
| 32 | +[foldl]: https://slim.computer/eecs-111-ta-guide/material/higher-order/Fold.html |
| 33 | +[handling-exceptions]: https://docs.python.org/3.11/tutorial/errors.html#handling-exceptions |
| 34 | +[haskell-folds]: https://www.ashwinnarayan.com/post/a-study-on-haskell-folds/ |
| 35 | +[raise-statement]: https://docs.python.org/3/reference/simple_stmts.html#the-raise-statement |
| 36 | +[reduce]: https://docs.python.org/3/library/functools.html#functools.reduce |
| 37 | +[split]: https://docs.python.org/3.9/library/stdtypes.html#str.split |
| 38 | +[str-methods]: https://docs.python.org/3/library/stdtypes.html#string-methods |
| 39 | +[value-error]: https://docs.python.org/3.11/library/exceptions.html#ValueError |
| 40 | +[while-loop]: https://python-practice.com/learn/loops/while_loop/ |
0 commit comments