About the exemplar solution in the Freelancer Rates exercise in the JS Track

Hello!

My name is Gabriel Frederico and this is my first time using this forum. I noticed pull requests are currently paused in the JavaScript Track, but I would like to propose an amendment to the exemplar solution.

Currently, the last task (Task 3) has the following code as the exemplar solution:

export function priceWithMonthlyDiscount(ratePerHour, numDays, discount) {
  const numMonths = Math.floor(numDays / 22);
  const monthlyRate = 22 * dayRate(ratePerHour);
  const monthlyDiscountedRate = (1 - discount) * monthlyRate;

  const numExtraDays = numDays % 22;
  const priceExtraDays = numExtraDays * dayRate(ratePerHour);

  return Math.ceil(numMonths * monthlyDiscountedRate + priceExtraDays);
}

Yet, the number 22 is used three times. Based on the DRY principle and the fact that the freelancer might increase or decrease the number of billable days in a month, I believe that value should be passed as a variable. The result would be:

export function priceWithMonthlyDiscount(ratePerHour, numDays, discount) {
  const billableDaysPerMonth = 22
  const numMonths = Math.floor(numDays / billableDaysPerMonth);
  const monthlyRate = billableDaysPerMonth * dayRate(ratePerHour);
  const monthlyDiscountedRate = (1 - discount) * monthlyRate;

  const numExtraDays = numDays % billableDaysPerMonth;
  const priceExtraDays = numExtraDays * dayRate(ratePerHour);

  return Math.ceil(numMonths * monthlyDiscountedRate + priceExtraDays);
}

Also, the daily rate is calculated twice, which should be also put in a variable. Making the final code something like this:

export function priceWithMonthlyDiscount(ratePerHour, numDays, discount) {
  const billableDaysPerMonth = 22
  const fullMonths = Math.floor(numDays / billableDaysPerMonth);

  const dailyRate = dayRate(ratePerHour);
  const monthlyRate = billableDaysPerMonth * dailyRate;
  const monthlyDiscountedRate = (1 - discount) * monthlyRate;
  
  const remainingDays = numDays % billableDaysPerMonth;
  const remainingDaysRate = remainingDays * dailyRate;

  return Math.ceil((fullMonths * monthlyDiscountedRate) + remainingDaysRate);
}

This is just a suggestion, of course. Thank you for any feedback.

3 Likes

The exemplar is a sample solution for verifying that it is in fact possible to pass the tests, and it’s used as part of the continuous integration workflow for a given track. It’s not exposed to students.

1 Like

This is very true of the example files in practice exercises, but not true of examplars (I’m aware the fact that the names are so similar is terrible - example would ideally be changed to proof or similar but legacy :person_shrugging:)

Examplars are currently shown to mentors as “get students to aim for this” and will appear in the future to students (they might already - I can’t remember), so it is worth trying to get them as idiomatic as possible.


@mazzog Hello :slight_smile: Thanks for the forum discussion. I’d welcome a PR for this as I think it’s a valid and valuable tweak, and a refinement that doesn’t introduce any new concepts or ideas. @SleeplessByte Happy for this PR?

Yeah sure. Feel free to PR either both changes or just the first @mazzog.

I don’t think the proposed change is better (or worse) than the current exemplar. I do not agree that we gain much from the extra two variables. I do think in general naming a magic number is more idiomatic than not, but “caching” the dayRate gives us nothing more than premature optimisation.


The function was introduced in Improve Concept Exercise: Freelancer Rates by JaPatGitHub · Pull Request #1472 · exercism/javascript · GitHub. I think this PR was a good addition to the exercise, but I never loved this particular function because there are too many ways of solving it “sorta right”.

Sidenote @iHiD , in JS, the example files are called proof instead of exemplar :wink:

I am aware and always inspired :wink:

1 Like

Thank you for the feedback. I’ll make the PR tomorrow.

@SleeplessByte, I’ll just send the first one, since the second one is more of a preference than anything else.

1 Like

@SleeplessByte, sorry for the delay. Here is the link to the PR:

https://github.com/exercism/javascript/pull/2218