python icon indicating copy to clipboard operation
python copied to clipboard

[Pascals Triangle] Remastered for recursion

Open PaulT89 opened this issue 2 years ago • 9 comments

As per Issue #3078.

Changes

Rewrote example.py:

  • Uses recursion rather than loops.
  • Raises a meaningful error when row_count < 0, instead of just returning None.

Added template.j2:

  • Based general layout of the template on the old pascals_triangle_test file.

Added instructions.append.md:

  • Encourage student to use recursion to solve this problem
  • Added boilerplate message about how to raise exceptions

.meta/config.json:

  • Added name as co-author (though maybe contributor would be more appropriate?)

config.json:

  • practices recursion
  • added (seemingly) sensible sounding prerequisites
  • kept difficulty
  • moved entire block up to be in line with other exercises of similar difficulty.

PaulT89 avatar Jul 24 '22 10:07 PaulT89

Hi & Welcome! 👋🏽 👋

Thank you for contributing to exercism/python 💛 💙 -- we really appreciate it! 🌟 🌈


This is an automated [🤖 🤖  ] comment for the maintainers of this repository, notifying them of your contribution. 🎉 Someone will review/reply to your changes shortly. (usually within 72 hours.) You can safely ignore the maintainers section below.


⚠️  Please be aware ⚠️

     This repo does not generally accept Pull Requests unless they follow our contributing guidelines and are:

     1️⃣     Small, contained fixes for typos/grammar/punctuation/code syntax on [one] exercise,      2️⃣     Medium changes that have been agreed/discussed via a filed issue,      3️⃣     Contributions from our [help wanted][help-wanted] issue list,      4️⃣     Larger (previously agreed-upon) contributions from recent & regular (within the last 6 months) contributors.

    Pull Requests not in these categories will be closed. 😞



💙 It looks like you are changing/adding files in a Practice Exercise! 💙

Please note: generally, changes to existing practice exercises or the addition of new ones are proposed & discussed in problem-specifications first, so that all tracks can potentially benefit. Once a change is approved there by three maintainers, it becomes available for various language tracks to then implement.


‼️  Did You...

  • [ ]  Update & rebase your branch with any (recent) upstream changes.
  • [ ]  Spell and grammar check all prose changes.
  • [ ]  Run Prettier on all markdown and JSON files.
  • [ ]  Run flake8 with flake8 config to check general code style standards.
  • [ ]   Run pylint with pylint config to check extended code style standards.
  • [ ]  Use pytest or the python-track-test-runner to test any changed example.py/exemplar.pyfiles  against their associated test files.
  • [ ]  Similarly, use pytest or the python-track-test-runner to test any changed test files.
    • Check that tests fail properly, as well as succeed.  (e.g., make some tests fail on purpose to "test the tests" & failure messages).
  • [ ]  Double-check all files for proper EOL.
  • [ ]  Regenerate exercise documents when you modified or created a hints.md file for a practice exercise.
  • [ ]  Regenerate the test file if you modified or created a JinJa2 template file for a practice exercise.
    • Run the generated test file result against its example.py.
  • [ ]  Run configlet-lint if the track config.json, or any other exercise config.json has been modified.


✅️  Have You Checked...

. Are there any additional changes you need to make? Please make sure all associated files are present and consistent with your changes!

Practice Exercise Anatomy

  • [ ] .docs/instructions.md(required)
  • [ ] .docs/introduction.md(optional)
  • [ ] .docs/introduction.append.md(optional)
  • [ ] .docs/instructions.append.md (optional)
  • [ ] .docs/hints.md(optional)
  • [ ] .meta/config.json (required)
  • [ ] .meta/example.py (required)
  • [ ] .meta/design.md (optional)
  • [ ] .meta/template.j2 (template for generating tests from canonical data)
  • [ ] .meta/tests.toml (do you need to include or exclude any cases?)
  • [ ] <exercise-slug>_test.py (do you need to regenerate this?)
  • [ ] <exercise-slug>.py (required)

🛠️    Maintainers   

Please take note 📒 of the following sections/review items 👀 ✨



🌈  Acknowledgements and Reputation
  • ❓ Does this PR need to receive a label with a reputation modifier?
    • medium is awarded by default.
  • ❓ Does this contributor need to be added to the exercise authors or contributors?
  • ❓ Does this contributor need to be added to the concept authors or contributors?
  • ❓ Is there an associated issue or issues that should be linked to this PR?
💫  General Code Quality

    Verify:

    • [ ]  The branch was updated & rebased with any (recent) upstream changes.
    • [ ]  All prose was checked for spelling and grammar.
    • [ ]  Files are formatted via yapf (yapf config) & conform to our coding standards
    • [ ]  Files pass flake8 with flake8 config & pylint with pylint config.
    • [ ]  Changed example.py/exemplar.py files still pass their associated test files.
    • [ ]  Changed test files still work with associated example.py/exemplar.py files.
      • Check that tests fail properly, as well as succeed. (e.g., make some tests fail on purpose to "test the tests" & failure messages).
    • [ ]  All files have proper EOL.
    • [ ]  If a JinJa2 template was modified/created, was the test file regenerated?
      • Does the regenerated test file successfully test the exercises example.py file?
    • [ ]  The branch passes all CI checks & configlet-lint.


🌿  Changes to Concept Exercises
  • ❓ Are all required files still up-to-date & configured correctly for this change?_
  • ❓ Does <exercise>/.meta/design.md need to be updated with new implementation/design decisions
  • ❓ Do these changes require follow-on/supporting changes to related concept documents?
    ✨  Where applicable, check the following ✨

      (as a reminder: Concept Exercise Anatomy)

      • [ ] Exercise introduction.md
        • [ ] Do all code examples compile, run, and return the shown output?
        • [ ] Are all the code examples formatted per the Python docs?
      • [ ] Exercise instructions.md
      • [ ] Exercise hints.md
      • [ ] Check that exercise design.md was fulfilled or edited appropriately
      • [ ] Exercise exemplar.py
        • [ ] Only uses syntax previously introduced or explained.
        • [ ] Is correct and appropriate for the exercise and story.
      • [ ] Exercise <exercise_name>.py (stub)
        • [ ] Includes appropriate docstrings and function names.
        • [ ] Includes pass for each function
        • [ ] Includes an EOL at the end
      • [ ] Exercise <exercise_name>_test.py
        • [ ] Tests cover all (reasonable) inputs and scenarios
        • [ ] At least one test for each task in the exercise
        • [ ] If using subtests or fixtures they're formatted correctly for the runner
        • [ ] Classnames are <ExerciseName>Test
        • [ ] Test functions are test_<test_name>
      • [ ] Exercise config.json --> valid UUID4
      • [ ] Corresponding concept introduction.md
      • [ ] Corresponding concept about.md
      • [ ] Concept config.json
      • [ ] All Markdown Files : Prettier linting (for all markdown docs)
      • [ ] All Code files: PyLint linting (except for test files)
      • [ ] All files with text: Spell check & grammar review.
🚀  Changes to Practice Exercises

    Is the exercise is in line with Practice Exercise Anatomy?

    • [ ] .docs/instructions.md(required)
      • Was this file updated and regenerated properly?
    • [ ] .docs/introduction.md(optional)
    • [ ] .docs/introduction.append.md(optional)
    • [ ] .docs/instructions.append.md (optional)
      • Are any additional instructions needed/provided?  (e.g. error handling or information on classes)
    • [ ] .docs/hints.md(optional)
      • Was this file regenerated properly?
    • [ ] .meta/config.json (required)
    • [ ] .meta/example.py (required)
      • Does this pass all the current tests as written/generated?
    • [ ] .meta/design.md (optional)
    • [ ] .meta/template.j2 (template for generating tests from canonical data)
      • Was a test file properly regenerated from this template?
    • [ ] .meta/tests.toml
      • Are there additional test cases to include or exclude?
      • Are there any Python-specific test cases needed for this exercise?
    • [ ] <exercise-slug>_test.py
      • Does this file need to be regenerated?
      • Does this file correctly test the example.py file?
      • Does this file correctly report test failures and messages?
    • [ ] <exercise-slug>.py (required)
      • Does this stub have enough information to get  the student started coding a valid solution?
🐣  Brand-New Concept Exercises

    Is the exercise is in line with Concept Exercise Anatomy?

    • [ ] Exercise introduction.md
      • [ ] Do all code examples compile, run, and return the shown output?
      • [ ] Are all the code examples formatted per the Python docs?
    • [ ] Exercise instructions.md
    • [ ] Exercise hints.md
    • [ ] Check that exercise design.md was fulfilled or edited appropriately
    • [ ] Exercise exemplar.py
      • [ ] Only uses syntax previously introduced or explained.
      • [ ] Is correct and appropriate for the exercise and story.
    • [ ] Exercise <exercise_name>.py (stub)
      • [ ] Includes appropriate docstrings and function names.
      • [ ] Includes pass for each function
      • [ ] Includes an EOL at the end
    • [ ] Exercise <exercise_name>_test.py
      • [ ] Tests cover all (reasonable) inputs and scenarios
      • [ ] At least one test for each task in the exercise
      • [ ] If using subtests or fixtures they're formatted correctly for the runner
      • [ ] Classnames are <ExerciseName>Test
      • [ ] Test functions are test_<test_name>
    • [ ] Exercise config.json --> valid UUID4
    • [ ] Corresponding concept introduction.md
    • [ ] Corresponding concept about.md
    • [ ] Concept config.json
    • [ ] All Markdown Files : Prettier linting (for all markdown docs)
    • [ ] All Code files: Flake8 & PyLint linting
    • [ ] All Code Examples: proper formatting and fencing. Verify they run in the REPL
    • [ ] All files with text: Spell check & grammar review.


Our   💖   for all your review efforts! 🌟 🦄

github-actions[bot] avatar Jul 24 '22 10:07 github-actions[bot]

Hi @PaulT89 👋🏽

Thank you so much for submitting this! Jus to warn you: I will probably be taking this in stages, since my time today/next week is a bit limited. I'll move as quickly as I can, but you may get several "waves" or clusters of comments. At a quick first glance:

  1. This looks to be missing the ./meta/tests.toml file (see this one from diffie-hellman as an example). The tests.toml file is needed by the generator so that it can figure out which test cases to generate/not generate for the exercise. I think the file can be created by using configlet, but you may need to dig in the practice exercise docs for details (apologies - I don't have time at the moment to go dig for a link).
  2. Instead of putting additional tests in the JinJa2 template, we currently define them in a ./meta/additional_tests.json file. See this one for the clock exercise as an example. Seems tedious for just one test case, but that's the way we track them.
  3. If the error handling case is from cannonical data, then you don't have to make an additional_tests.json file -- but you should also change the comment in the template, so that it doesn't confuse us in the future with implying that there are "additional" test cases for this exercise.
  4. Making the recursion concept a prerequisite for this exercise means that a student in learning mode won't be able to unlock this exercise without completing the recursion concept exercise. But we don't currently have a recursion concept exercise...so this exercise would never be unlocked. 😱 Suggest we remove the prerequisite until we can get a recursion concept exercise completed. (are you up for a challenge? Wanna take on a recursion concept exercise? Just let me know.... 😄 )
  5. You totally should be an author here! The JinJa2 template alone is worth an author credit, but you also thought through error handling and other changes.
  6. We may want to elaborate a little bit on recursion in the instruction append. I don't have time at the moment, but there is a way to cross-link concept docs inside instructions. I think we should do that here. We may also want to do an additional callout/warning for Python's recursion limit, so that students coming from a language that doesn't limit recursion aren't caught by surprise. Ditto for the lack of tail-call optimization.
  7. We might want to consider a hints.md file here to give students some extra links around thinking through recursion. It might also be useful to have some hints on how to do this via for or wile loop ... just to cover our bases. But we can discuss that later on.

Apologies -- that's all I have for now, but will pick this up later today my time. Thanks again for all your hard work on this! 🎉 🌈

BethanyG avatar Jul 24 '22 12:07 BethanyG

  1. The .meta/tests.toml file already exists, but remains unmodified (which is why it doesn't show up in this PR).
  2. Okay, I'll go back and fix that. FIXED
  3. There's no test for negative rows in the canonical data. The old pascals_triangle_test.py file tested for negative input, but it checked that None was returned, and I thought that it would be nice to keep the test, but raise a meaningful exception message instead.
  4. Hmm... 🤔. You're right, that does seem somewhat counterproductive - I should probably fix that. FIXED As for creating the concept exercise, maybe later (like in a few weeks?) if nobody else has taken it (and I haven't got anything else on). In theory at least, Pascal's Triangle could become the concept exercise.
  5. YAY! 🎉
  6. Yeah, I kept the instructions to a minimum because I imagined the concept exercise as already existing. I forgot that we don't live in the Platonic Ideal Universe inside my head, so that's an oops on my part. I'll go back and add a bit more to the instructions.
  7. Re: hints.md - yeah, maybe. Re: completing with for and while loops - I doubt that'll be an issue, though I suppose it would depend on how early/late the Recursion concept is put in the track.

Just one more thing. You mentioned Python's recursion limit in point 6 (something that I completely forgot about), but it gave me an idea. I've been trying to figure out a way to ensure that the student completes the exercise using recursion instead of loops. So far, the best that I could come up with was to simply rely on the student to complete this exercise in good faith (i.e. "I totally did it with recursion, not loops - trust me 😜"). But what if there's an additional test that deliberately uses Python's recursion limit to test for this? DONE Maybe something like this:

import sys

def test_solution_is_recursive(self):
    with self.assertRaises(RecursionError) as err:
        rows(sys.getrecursionlimit() + 10) # +10 just to be sure
    self.assertEqual(type(err.exception), RecursionError)
    self.assertEqual(err.exception.args[0], "maximum recursion depth exceeded in comparison")

PaulT89 avatar Jul 25 '22 11:07 PaulT89

Instructions update plus additional hints still pending. Can't seem to figure out why Exercises check / cannonical_sync 3.6, 3.7, and 3.8 keep failing. I might need to download Python 3.6 to figure that out.

PaulT89 avatar Jul 25 '22 14:07 PaulT89

Success! Well that's a fun/annoying little gotcha - the RecursionError message seems to be slightly different across versions (though at least the first 32 chars are identical).

PaulT89 avatar Jul 26 '22 11:07 PaulT89

Okay, I've updated the instructions and added hints. It still might be a little too bare-bones, but I'll leave the final assessment up to you.

PaulT89 avatar Jul 30 '22 13:07 PaulT89

Gah! 😱 Apologies that this has been sitting so long, and has now incurred the wrath of the "did-not-updated-test-cases" bot. @PaulT89 -- I am pretty swamped this morning, but I am hoping to get to this by the end of my day today (PDT), and get it un-stuck and on its way. Thank you so so much for your patience.

BethanyG avatar Oct 13 '22 12:10 BethanyG

@BethanyG Yeah, well, it's been a while since I've done anything on Github, so I decided to update all my repos and rebase various branches - and this happened. I think the CI is objecting to differences in the prob-specs vs the actual tests, so I regenerated and added a PR with the changes. Once that goes through, I'm assuming another rebase will fix this.

PaulT89 avatar Oct 13 '22 12:10 PaulT89

@PaulT89 - indeed it did! Thanks again for doing that. I went ahead and rebased your branch, so now the test are passing. 🎉 I won't have time until the weekend to review the PR. But I will definitely do it then. This has sat an obscenely long time, and is well past a push to production. 😉 My apologies for that. Life and a new job completely swamped me.

I think you (or I) will end up with one more rebase -- there is a PR from Katrina that I will probably approve and merge tonight, so her changes will need to be incorporated, I think.

BethanyG avatar Oct 14 '22 05:10 BethanyG

@PaulT89 - I cannot apologize enough for letting this sit. I've made a few edits to shorten the JinJa template and put in reflinks & widget links into the instruction append. Everything's been re-tested and looks good.

THANK YOU for this exercise! It is approved, and I am merging it in. 😄 I've also given you a little rep bump for your patience and efforts -- this one took way too long.

BethanyG avatar Dec 10 '22 22:12 BethanyG

@PaulT89 - I cannot apologize enough for letting this sit. I've made a few edits to shorten the JinJa template and put in reflinks & widget links into the instruction append. Everything's been re-tested and looks good.

THANK YOU for this exercise! It is approved, and I am merging it in. 😄 I've also given you a little rep bump for your patience and efforts -- this one took way too long.

That's okay. I deliberately didn't push the issue - it was funnier that way. The longer it took for you to realize that this wasn't merged, the funnier it became. Consider me suitably amused. 🤣

PaulT89 avatar Dec 11 '22 07:12 PaulT89