Carts and Products (workshop task) - getInfo() method


I would like to raise an issue related to yesterday's JS OOP workshops. I think that for me, as maybe for most of you, the hardest part of task was actually the last method of getShoppingCart() function - getInfo(). We had to agregate all products from the cart to one array of objects, where single element represents all occurances (if more than one) of certain product. 

After couple of hours, I came to conclusion that there were more than one ways to solve this problem. 

(1) One of them, more time-absorbing, was to make getInfo() method create array (products = []) every time when invoked.

(2) Second, in my opinion much simpler, was to make getShoppingCart() function store and update array of objects dynamically - every time, when product is added. Then getInfo() method has only to return this array. And this is the way that I firstly chose. 

My solution:

(link to picture: )

As you can see, array of objects for further usage by getInfo() method is being constructed dynamically after every single invocation of add() method (it works a little bit differently with remove() method, but works).

Meanwhile, mocha test for this task forbids us to go this way. Why? Take a look here:

(link to picture: )

in final test (the one checking getInfo() method) we can see, that there is actually push() method being used instead of add(), when products are being added to cart. In my case - that prevents function buildProductInfo() from being invoked when it's needed. In the same time, we've been asked explicity to construct method add() for adding new products to cart.

I would like to mention, that I've fixed this problem already by changing my solution, so now it sticks to requirements provided by mocha tests.

BUT I was able to do so only because we're allowed to read the actual test file in this course. If it was exam - I propably wouldn't figure out where is the problem, despite the fact that my code is working as expected accordingly to requirements posted in GitHub - in 100%! 

So here we come to my actual set of questions:

1. will we be informed explicity during exam, how our code is demanded to being designed? I mean - if it'd come to problem as described above - BGcoder won't give me points even though I've solved task correctly. What next then? 

2. how did you people handle this problem? Show your code, this task was interesting one, so I think it'd be good to discuss it! :)


My solution :
function solve() { function getProduct(productType, name, price) { return { productType : productType, name : name, price : price } } function getShoppingCart() { var products = []; function add(product) { products.push(product); return this; } function remove(product) { if (products) { var pos = products.findIndex(x=>; if (pos >= 0) { for (var i=pos; i<products.length-1; i+=1) { products[i] = products[i+1]; } products.pop(); } else { throw 'No such product'; } } else { throw 'No products to remove from'; } return this; } function showCost(){ var sum = 0; if (products){ for (var i=0; i<products.length; i+=1) { sum += products[i].price; } } return sum; } function showProductTypes() { var types = []; for (var i=0; i<products.length; i+=1) { if (!types.some(x=>x===products[i].productType)) { types.push(products[i].productType); } } types.sort(); return types; } function getInfo() { var productGroups = []; var names = []; for (var i=0; i<products.length; i+=1) { if (!names.some(x=>x===products[i].name)) { names.push(products[i].name); } } names.sort(); var productGroup; for (var i=0; i<names.length; i+=1) { let repetitions = products.filter(x=>[i]); let groupPrice = repetitions.reduce((sum, x)=>sum+x.price, 0); productGroup = { name : names[i], totalPrice : groupPrice, quantity : repetitions.length } productGroups.push(productGroup); } return { products : productGroups, totalPrice : this.showCost() } } return { products : products, add : add, remove : remove, showCost : showCost, showProductTypes : showProductTypes, getInfo : getInfo } } return { getProduct: getProduct, getShoppingCart: getShoppingCart }; } module.exports = solve();

от hankrum (71 точки)



Great idea, building the getInfo() array dynamically. The problem (as you have noticed) is that the products array in your cart is also required to be exposed. This makes it possible to test for correct behaviour of .add() method.

Also, imagine if you don't have working .add() but do have working .remove(). The .remove() functionality tests wouldn't have passed if they had used .add().

It is probable that something similar may happen on the exam. If your internal data has to be exposed then your methods should be able to handle external tampering. If it is only required to return a copy of the data, then you can actually not expose a reference to the data itself. In the case of the yesterday's task you had to expose a reference, so as it happened, external tampering can cause problems for dynamic solutions.

от cuki (7696 точки)


Ok, I got it, thanks! So to sum up - when certain data has to be exposed, I need to be careful and make these parts of the code as independent as possible. 

BTW, my final solution is here (mocha.js approved) ->

P.S. refering to our yesterday's conversation: mocz (read: moch) is urine in Polish. And test moczu is basically drug test.

#uselessKnowledge :D

от KonstantyCh (90 точки)



As for the candy word, at first I thought you wrote something like: "Cuki is rek". I assumed that rek may be nasty (in the funny sense) or something similar :D

от cuki (7696 точки)


съжалявам, че пиша на БГ, това е

моето решение

но имам един такъв въпрос func getProduct() - не е ли сложена за да имплементира валидации на входящите данни?

тест 1 - категорично изисква входящите параметри да са undefined?

от mitkop (578 точки)