Marking
- This assignment will be worth 4% of your final grade.
- You will be marked on the last version pushed to coursegit. Make sure you have pushed your assignment by 4:30PM on Friday November 3.
You will be marked on
- correctness and implementation detail
- Pay attention to the way you are asked to implement things.
- functional JavaScript
- Part of the point of the assignment is to see that a certain tasks can be accomplished in a very similar way in JavaScript as in Racket. So don't go crazy with mutation.
- testing
- Remember to have full test coverage (according to
c8
).
For detailed marking scheme, see javascript-assignment.
A scary Halloween story
Young Brendan decides to help Uncle Escher organize the family candy store for the busy Halloween season. The storeroom is full of different sized boxes, each of which contains packages of candy, other storage boxes, or sometimes nothing at all. Brendan decides to write some JavaScript to help track the inventory. Given an example like Figure 1, Brendan wants to be able to calculate that there is a total of 525g of Smarties™ in the box.
Questions
Candy class
Make a class Candy
that has properties brand
and grams
describing the brand name and size of the package respectively.
Provide a method total
that passes the following tests:
test("candy",
(t) => {
let treat = new Candy("M&M", 25);
test("total, right brand", (t) => assert.strictEqual(treat.total("M&M"),25));
test("total, wrong brand", (t) => assert.strictEqual(treat.total("Milkbone"),0));
});
Boxes class
Write a class Box
representing candy storage boxes. The Box
class
has a constructor that accepts any number of arguments, each of which
is either a Box
object or a Candy
object. Box
objects also
support a total
method that calculates the total weight of candy of
a given brand contained in the box. Either use explicit recursion or
reduce
to implement total
. The total
method should not modify the Box
object. Your class should pass the following
tests, but also work for general Box
input.
Hint:
You might find instanceof
useful to tell the difference
between Box
objects and Candy
objects.
test("boxes in boxes",
(t) => {
let treat1 = new Candy("M&M",100);
let treat2 = new Candy("Smarties",500);
let treat3 = new Candy("O Henry",80);
let treat4 = new Candy("Smarties",25);
let box = new Box (new Box(treat3),
new Box (new Box (treat2),
new Box(new Box(treat1),
new Box()), treat4));
test("single match", (t) => assert.strictEqual(box.total("M&M"),100));
test("multi match", (t) => assert.strictEqual(box.total("Smarties"),525));
test("recursive non matching is 0", (t) => assert.strictEqual(box.total("Wasabi Peas"),0));
});
Iterator
Provide the iterator interface for the Box class, so that
the following test passes. You should provide a BoxIterator
class
with an appropriate next
method.
test("iterator", (t)=> {
let box = new Box (new Box (new Candy("Smarties", 500)),
new Box (new Box(new Candy("M&M", 100))),
new Candy("Smarties", 25));
results = [];
for (thing of box) {
results.push(thing.total("Smarties"));
}
assert.deepStrictEqual(results,[500,0,25]);
});