diff --git a/exercises/concept/bird-watcher/.docs/instructions.md b/exercises/concept/bird-watcher/.docs/instructions.md index e5076aedc4..f08c9f735e 100644 --- a/exercises/concept/bird-watcher/.docs/instructions.md +++ b/exercises/concept/bird-watcher/.docs/instructions.md @@ -6,11 +6,10 @@ You already digitalized the bird counts per day for the past weeks that you kept Now you want to determine the total number of birds that you counted, calculate the bird count for a specific week and correct a counting mistake. - + ~~~~exercism/note -To practice, use a for loop to solve each of the tasks below. +To practice, use a `for` loop to solve each of the tasks below. ~~~~ - ## 1. Determine the total number of birds that you counted so far diff --git a/exercises/concept/bird-watcher/.meta/exemplar.js b/exercises/concept/bird-watcher/.meta/exemplar.js index 616b6c8877..8eb350b240 100644 --- a/exercises/concept/bird-watcher/.meta/exemplar.js +++ b/exercises/concept/bird-watcher/.meta/exemplar.js @@ -12,9 +12,11 @@ */ export function totalBirdCount(birdsPerDay) { let total = 0; + for (let i = 0; i < birdsPerDay.length; i++) { total += birdsPerDay[i]; } + return total; } @@ -27,10 +29,12 @@ export function totalBirdCount(birdsPerDay) { */ export function birdsInWeek(birdsPerDay, week) { let total = 0; + const start = 7 * (week - 1); for (let i = start; i < start + 7; i++) { total += birdsPerDay[i]; } + return total; } @@ -39,11 +43,10 @@ export function birdsInWeek(birdsPerDay, week) { * by one for every second day. * * @param {number[]} birdsPerDay - * @returns {number[]} corrected bird count data + * @returns {void} should not return anything */ export function fixBirdCountLog(birdsPerDay) { for (let i = 0; i < birdsPerDay.length; i += 2) { birdsPerDay[i]++; } - return birdsPerDay; } diff --git a/exercises/concept/bird-watcher/bird-watcher.js b/exercises/concept/bird-watcher/bird-watcher.js index c91a863c31..476d3634f5 100644 --- a/exercises/concept/bird-watcher/bird-watcher.js +++ b/exercises/concept/bird-watcher/bird-watcher.js @@ -30,7 +30,7 @@ export function birdsInWeek(birdsPerDay, week) { * by one for every second day. * * @param {number[]} birdsPerDay - * @returns {number[]} corrected bird count data + * @returns {void} should not return anything */ export function fixBirdCountLog(birdsPerDay) { throw new Error('Please implement the fixBirdCountLog function'); diff --git a/exercises/concept/bird-watcher/bird-watcher.spec.js b/exercises/concept/bird-watcher/bird-watcher.spec.js index db170033c3..bbedf2210e 100644 --- a/exercises/concept/bird-watcher/bird-watcher.spec.js +++ b/exercises/concept/bird-watcher/bird-watcher.spec.js @@ -1,46 +1,97 @@ import { describe, expect, test } from '@jest/globals'; import { birdsInWeek, fixBirdCountLog, totalBirdCount } from './bird-watcher'; +const customInspectSymbol = Symbol.for('nodejs.util.inspect.custom'); +const customLogSymbol = Symbol.for('exercism.javascript.util.log'); + +// Follow the instructions in case you are stuck on "list.method is not a function" +class CountingReport { + constructor(counts) { + // Enables array[index] + counts.forEach((count, index) => { + this[index] = count; + }); + + // Enables .length + this.length = counts.length; + } + + // Log value in non-upgraded environments + toString() { + return arrayOf(this).toString(); + } + + // Overrides logging in node (ie. students working locally) + [customInspectSymbol]() { + return `Seen birds per day: ${arrayOf(this)}`; + } + + // Overrides log overrides in web environment (ie. students working in editor) + [customLogSymbol]() { + return `Seen birds per day: ${arrayOf(this)}`; + } +} + +function report(...values) { + return new CountingReport(values); +} + +function arrayOf(countingReport) { + return Array.from( + { length: countingReport.length }, + (_, i) => countingReport[i], + ); +} + +function randomArray(length) { + return Array.from({ length }, () => Math.floor(Math.random() * 8)); +} + describe('totalBirdCount', () => { test('calculates the correct total number of birds', () => { - const birdsPerDay = [9, 0, 8, 4, 5, 1, 3]; + const birdsPerDay = report(9, 0, 8, 4, 5, 1, 3); expect(totalBirdCount(birdsPerDay)).toBe(30); }); test('works for a short bird count list', () => { - const birdsPerDay = [2]; + const birdsPerDay = report(2); expect(totalBirdCount(birdsPerDay)).toBe(2); }); test('works for a long bird count list', () => { // prettier-ignore - const birdsPerDay = [2, 8, 4, 1, 3, 5, 0, 4, 1, 6, 0, 3, 0, 1, 5, 4, 1, 1, 2, 6]; + const birdsPerDay = report( + 2, 8, 4, 1, 3, 5, 0, 4, 1, 6, 0, 3, 0, 1, 5, 4, 1, 1, 2, 6 + ); + expect(totalBirdCount(birdsPerDay)).toBe(57); }); }); describe('birdsInWeek', () => { test('calculates the number of birds in the first week', () => { - const birdsPerDay = [3, 0, 5, 1, 0, 4, 1, 0, 3, 4, 3, 0, 8, 0]; + const birdsPerDay = report(3, 0, 5, 1, 0, 4, 1, 0, 3, 4, 3, 0, 8, 0); expect(birdsInWeek(birdsPerDay, 1)).toBe(14); }); test('calculates the number of birds for a week in the middle of the log', () => { // prettier-ignore - const birdsPerDay = [4, 7, 3, 2, 1, 1, 2, 0, 2, 3, 2, 7, 1, 3, 0, 6, 5, 3, 7, 2, 3]; + const birdsPerDay = report(4, 7, 3, 2, 1, 1, 2, 0, 2, 3, 2, 7, 1, 3, 0, 6, 5, 3, 7, 2, 3); expect(birdsInWeek(birdsPerDay, 2)).toBe(18); }); test('works when there is only one week', () => { - const birdsPerDay = [3, 0, 3, 3, 2, 1, 0]; + const birdsPerDay = report(3, 0, 3, 3, 2, 1, 0); expect(birdsInWeek(birdsPerDay, 1)).toBe(12); }); test('works for a long bird count list', () => { - const week21 = [2, 0, 1, 4, 1, 3, 0]; - const birdsPerDay = randomArray(20 * 7) - .concat(week21) - .concat(randomArray(10 * 7)); + const week21 = report(2, 0, 1, 4, 1, 3, 0); + const birdsPerDay = report( + ...randomArray(20 * 7) + .concat(arrayOf(week21)) + .concat(randomArray(10 * 7)), + ); expect(birdsInWeek(birdsPerDay, 21)).toBe(11); }); @@ -48,32 +99,32 @@ describe('birdsInWeek', () => { describe('fixBirdCountLog', () => { test('returns a bird count list with the corrected values', () => { - const birdsPerDay = [3, 0, 5, 1, 0, 4, 1, 0, 3, 4, 3, 0]; + const birdsPerDay = report(3, 0, 5, 1, 0, 4, 1, 0, 3, 4, 3, 0); const expected = [4, 0, 6, 1, 1, 4, 2, 0, 4, 4, 4, 0]; - expect(fixBirdCountLog(birdsPerDay)).toEqual(expected); - }); - - test('does not create a new array', () => { - const birdsPerDay = [2, 0, 1, 4, 1, 3, 0]; + fixBirdCountLog(birdsPerDay); - // This checks that the same object that was passed in is returned. - // https://jestjs.io/docs/expect#tobevalue - expect(Object.is(fixBirdCountLog(birdsPerDay), birdsPerDay)).toBe(true); + expect(arrayOf(birdsPerDay)).toEqual(expected); }); test('works for a short bird count list', () => { - expect(fixBirdCountLog([4, 2])).toEqual([5, 2]); + const birdsPerDay = report(4, 2); + fixBirdCountLog(birdsPerDay); + + expect(arrayOf(birdsPerDay)).toEqual([5, 2]); }); test('works for a long bird count list', () => { // prettier-ignore - const birdsPerDay = [2, 8, 4, 1, 3, 5, 0, 4, 1, 6, 0, 3, 0, 1, 5, 4, 1, 1, 2, 6]; + const birdsPerDay = report( + 2, 8, 4, 1, 3, 5, 0, 4, 1, 6, 0, 3, 0, 1, 5, 4, 1, 1, 2, 6 + ); + // prettier-ignore - const expected = [3, 8, 5, 1, 4, 5, 1, 4, 2, 6, 1, 3, 1, 1, 6, 4, 2, 1, 3, 6]; - expect(fixBirdCountLog(birdsPerDay)).toEqual(expected); + const expected = [ + 3, 8, 5, 1, 4, 5, 1, 4, 2, 6, 1, 3, 1, 1, 6, 4, 2, 1, 3, 6 + ] + + fixBirdCountLog(birdsPerDay); + expect(arrayOf(birdsPerDay)).toEqual(expected); }); }); - -function randomArray(length) { - return Array.from({ length: length }, () => Math.floor(Math.random() * 8)); -}