TheOdinProject / curriculum

The open curriculum for learning web development
https://www.theodinproject.com/
Other
10.11k stars 13.54k forks source link

Recursive Methods: Testing with Jest #27265

Open NikitaRevenco opened 9 months ago

NikitaRevenco commented 9 months ago

Checks

Describe your suggestion

The website linked for solving recursive problems (9 problems in NodeJS path) (7 problems in Ruby path) would be better suited as an exercise in my opinion that users can fork and test using jest.

NodeJS Path

We can create 9 new exercise folders in javascript-exercises repository that will have a README.md, exercise.js, exercise.spec.js, and a solutions folder containing the solution and the solution spec, similar to the first 12 exercises.

Below is an example of how the first exercise could be added.

Exercise 13 - sumRange

README.md

Implement a recursive function that will take a number and return the sum of all numbers from 1 up to to the number passed in.

sumRange(5) // should add 1 + 2 + 3 + 4 + 5 and return 15
sumRange.js
const sumRange = function() {

};

// Do not edit below this line
module.exports = sumRange;
sumRange.spec.js
const sumRange = require('./sumRange')

describe('sumRange', () => {
  test('Sums numbers in a small range', () => {
    const range = 4;
    expect(sumRange(range)).toBe(10);
  });
  test('Sums numbers in a large range', () => {
    const range = 100;
    expect(sumRange(range)).toBe(5050);
  });
  test('Returns undefined for negative range', () => {
    const range = -3;
    expect(sumRange(range)).toBe(undefined);
  });
  test('Returns undefined for non integer range', () => {
    const range = 3.7;
    expect(sumRange(range)).toBe(undefined);
  });
});
sumRange-solution.js
function sumRange(num){
  if (!Number.isInteger(num) || num < 0) return undefined;

  if(num === 1) return 1;

  return num + sumRange(num - 1);
}

module.exports = sumRange;

Ruby path

Similarly, we can create a new folder in the Ruby path repository ruby-exercises to align with the current structure of that repository called 'ruby_recursive' and place the recursive problems there.

Path

Ruby / Rails, Node / JS

Lesson Url

https://www.theodinproject.com/lessons/ruby-recursive-methods

(Optional) Discord Name

Revenco

(Optional) Additional Comments

No response

JoshDevHub commented 9 months ago

I think it's a cool idea to bring this stuff in-house for a couple of reasons:

  1. Similar to the exercises in foundations, our provided tests can make sure learners' solutions are correct and properly consider certain edge cases.
  2. One of the solutions in the JS exercises (problem 6) is incorrect. There's also quite a bit of dated syntax.
  3. We'd have full control over what the problems are, how many there are, etc.

Anyways, I'll check with the team and see if they agree.

github-actions[bot] commented 8 months ago

This issue is stale because it has had no activity for the last 30 days.

JoshDevHub commented 8 months ago

Alright revisiting this because I have some time to pursue it.

Is this still something you're interested in working on @nikitarevenco ?

NikitaRevenco commented 8 months ago

Alright revisiting this because I have some time to pursue it.

Is this still something you're interested in working on @nikitarevenco ?

Yes, I'm happy to work on this!

JoshDevHub commented 8 months ago

Awesome.

Before we start, we can think some about what exercises we want to do. One of the nice things about moving this in-house is that we have full control over the problems. We could also use the same problem set for both paths.

I really like the following ones because they actually present good usecases for recursion rather than being "loop" problems we're telling the learner to think of in a recursive way.

It's also probably nice to have an easier one in there like a factorial problem. I probably don't want to do a Fibonacci problem because there's already a project using it that comes later.

Do you have any opinions on this? @nikitarevenco

NikitaRevenco commented 8 months ago

Awesome.

Before we start, we can think some about what exercises we want to do. One of the nice things about moving this in-house is that we have full control over the problems. We could also use the same problem set for both paths.

I really like the following ones because they actually present good usecases for recursion rather than being "loop" problems we're telling the learner to think of in a recursive way.

  • contains() from the JS challenges
  • totalIntegers() from the JS challenges
  • sumSquares() from the JS challenges
  • #flatten from the Ruby challenges

It's also probably nice to have an easier one in there like a factorial problem. I probably don't want to do a Fibonacci problem because there's already a project using it that comes later.

Do you have any opinions on this? @nikitarevenco

Yeah, great ideas. I like the flatten challenge and having the exercises go from easier, starting with the factorial to more difficult sounds like a plan.

Some additional ideas for the exercises

JoshDevHub commented 8 months ago

I think most of those options have cool potential. I'm maybe a bit skeptical of greatest common denominator. It's definitely a famous recursion problem, but I don't think learners are going to be able to just come up with Euclid's algorithm on the spot. Maybe the README for the exercise could mention it?

Anyways let's proceed with adding all of these in (the ones in my list and the ones in yours), and we can filter out the ones that don't work when it comes to review time and we get some outside input.

So for your part, you want to add the new exercises to our javascript exercises repo. When you make your PR there, you'll want to reference this issue. I'll handle adding them to the ruby exercises repo.

JoshDevHub commented 8 months ago

Actually let's keep things a bit constrained to start. Maybe we can move faster after we get things rolling, but for now, let's try to keep PRs small. We'll definitely need at least a JS maintainer to look over the new exercises you add in the javascript-exercises repo, and I'd rather not hit the reviewer with a massive PR :sweat_smile:

So let's just work on a PR for a factorial exercise for right now and plan to move slowly unless/until reviewers are okay with looking over more work.

Does that sound good @nikitarevenco ?

NikitaRevenco commented 8 months ago

Actually let's keep things a bit constrained to start. Maybe we can move faster after we get things rolling, but for now, let's try to keep PRs small. We'll definitely need at least a JS maintainer to look over the new exercises you add in the javascript-exercises repo, and I'd rather not hit the reviewer with a massive PR :sweat_smile:

So let's just work on a PR for a factorial exercise for right now and plan to move slowly unless/until reviewers are okay with looking over more work.

Does that sound good @nikitarevenco ?

Oh yeah, certainly. It would be better to split a single massive PR into many smaller ones.

NikitaRevenco commented 7 months ago

Actually let's keep things a bit constrained to start. Maybe we can move faster after we get things rolling, but for now, let's try to keep PRs small. We'll definitely need at least a JS maintainer to look over the new exercises you add in the javascript-exercises repo, and I'd rather not hit the reviewer with a massive PR 😅

So let's just work on a PR for a factorial exercise for right now and plan to move slowly unless/until reviewers are okay with looking over more work.

Does that sound good @nikitarevenco ?

Take a look at the new exercise

NikitaRevenco commented 7 months ago

How many more exercises are we going to add?

I'll give a brief explanation of the current ideas I have that are currently draft PRs and I haven't started working on.

Let's decide which ones we want to keep and which ones we want to work on in the future.

@MaoShizhong @JoshDevHub

MaoShizhong commented 7 months ago

At first glance, Tower of Hanoi seems like a classic puzzle suited for recursion. I haven't actually looked into it myself, so can't comment on whether it'd be suitable to include in the proposed exercises when you also take into account how many there would be.

Calculator, I'll push back on. Those challenges would not be suited to recursion, so doing them recursively would just be shoehorning recursion where it doesn't belong.

Can't comment at this time on Pascal in terms of suitability as an exercise to add, nor when also considering the context of the other exercises.

MaoShizhong commented 7 months ago

Very honestly, I think just having approx. 5-6 exercises is plenty. Especially if we're also considering porting recursive fibonacci and/or merge sort over as well.

For me, something like

  1. Factorial
  2. Fibonacci
  3. Contains
  4. Total Integers
  5. Permutations
  6. Tower of Hanoi

Maybe also merge sort somewhere there as well, but I've no strong feelings for whether we need or don't need it.

At a glance seems sufficient for that section. As usual, just my personal opinion taking into account the pedagogy of the whole CS section and the "flow" of the course.

NikitaRevenco commented 7 months ago

Very honestly, I think just having approx. 5-6 exercises is plenty. Especially if we're also considering porting recursive fibonacci and/or merge sort over as well.

For me, something like

  1. Factorial
  2. Fibonacci
  3. Contains
  4. Total Integers
  5. Permutations
  6. Tower of Hanoi

Maybe also merge sort somewhere there as well, but I've no strong feelings for whether we need or don't need it.

At a glance seems sufficient for that section. As usual, just my personal opinion taking into account the pedagogy of the whole CS section and the "flow" of the course.

I agree with you that about 6ish should be good. I think that pascal is worth including though since I feel like its an interesting challenge, thoughts?

MaoShizhong commented 7 months ago

Hmmmm, partially due to unfamiliarity with a Pascal solution, I'd probably prefer including merge sort to be honest.

The sorting algo itself is quite a unique pattern compared to the other exercises, and lends itself very well to recursion. So on reflection, I think it can teach good lessons that warrant its inclusion. And I'm hesitant to go beyond 7, given the current exercises' complexities.

MaoShizhong commented 6 months ago

Very honestly, I think just having approx. 5-6 exercises is plenty. Especially if we're also considering porting recursive fibonacci and/or merge sort over as well.

For me, something like

  1. Factorial
  2. Fibonacci
  3. Contains
  4. Total Integers
  5. Permutations
  6. Tower of Hanoi

Maybe also merge sort somewhere there as well, but I've no strong feelings for whether we need or don't need it.

At a glance seems sufficient for that section. As usual, just my personal opinion taking into account the pedagogy of the whole CS section and the "flow" of the course.

@JoshDevHub thoughts on the above as the order of new exercises? Merge sort can be throw in there as a 7th (but put somewhere in the middle, I feel). Not all too familiar with the Pascal suggestion but am more familiar with merge sort and feel it would be good to have merge sort in there as well. Hence I'm leaning towards omitting the Pascal exercise due to a quantity thing.

NikitaRevenco commented 6 months ago

Very honestly, I think just having approx. 5-6 exercises is plenty. Especially if we're also considering porting recursive fibonacci and/or merge sort over as well. For me, something like

  1. Factorial
  2. Fibonacci
  3. Contains
  4. Total Integers
  5. Permutations
  6. Tower of Hanoi

Maybe also merge sort somewhere there as well, but I've no strong feelings for whether we need or don't need it. At a glance seems sufficient for that section. As usual, just my personal opinion taking into account the pedagogy of the whole CS section and the "flow" of the course.

@JoshDevHub thoughts on the above as the order of new exercises? Merge sort can be throw in there as a 7th (but put somewhere in the middle, I feel). Not all too familiar with the Pascal suggestion but am more familiar with merge sort and feel it would be good to have merge sort in there as well. Hence I'm leaning towards omitting the Pascal exercise due to a quantity thing.

I have already the Pascal and Hanoi solutions down and I think they are very interesting. Once I have internet on my computer I will publish them as PRs. I think the solutions are very interesting for both.

NikitaRevenco commented 6 months ago

So that makes the following new exercises:

And the two ported from existing project:

NikitaRevenco commented 6 months ago

@MaoShizhong @JoshDevHub at some point let's decide the order in which we want the exercises to be in. Obviously it makes sense for it to go easiest to hardest (it's hard to measure exactly - of course it'll vary for everyone. But having some kind of standard is better in my opinion than having none):

  1. Factorial (easiest)
  2. Total Integers
  3. Permutations
  4. Contains
  5. Merge Sort
  6. Fibonacci
  7. Pascal
  8. Tower of Hanoi (hardest)
JoshDevHub commented 6 months ago

Merge sort and Fibonacci will both need some extra consideration. I think it's probably better if they're moved to the exercises, but it will involve some extra work/discussion because they're already a part of an existing "project" lesson.

That project would have to be removed from the curriculum, effectively "orphaning" all existing submissions to it. Maybe the team doesn't mind, but I don't know for sure as we haven't discussed that yet.

Just letting you know of potential issues around those two problems.

github-actions[bot] commented 5 months ago

This issue is stale because it has had no activity for the last 30 days.

NikitaRevenco commented 2 months ago

Should I make a PR to add the new exercises to https://www.theodinproject.com/lessons/javascript-recursive-methods ?

MaoShizhong commented 2 months ago

@JoshDevHub In light of your comment about fib/merge, are you proposing that once we get the JS exercises all approved then the Ruby translations also approved, we can get a PR up to assign those tasks in the pathways' relevant lessons? Then afterwards as a separate thing, discuss with the team and decide on how to handle fib/merge?

JoshDevHub commented 2 months ago

@MaoShizhong Yep exactly

MaoShizhong commented 2 months ago

Awesome. In that case, @nikitarevenco let's hold off until all the JS exercises have been approved by me and Josh, and the Ruby translations have been as well. Then you can PR to add the assignments to both pathways :)