A Brief Context
---------------

I recently gave an interview in a company where I was asked this particular question. After the interview was over, the HR gave the feedback that my solution (is correct programmatically) but is monolithic and not scalable. **The interview was for frontend developer 2**.

---

Question
--------

Suppose there is a company which does some analytics work and returns data. The company (let's say X) gets a stream of numbers and it calculates average at that instant for all numbers received and returns the average. There could be other companies (let's say Y) which can ask for the average.

> 
> Data:   1  3  5  7  9  
> 
>  Avg:    1  2  3  4  5
> 
> 
> 

So, in the above example, the average are calculated by company X. 

* After first no, average is 1,
* After second no (i.e. 3), average is 2 ((3+1)/2) and so on

At any point in time, companies are only concerned about average at that time (basically, if average is asked after data value 5, you only need to return 3) 

The *geeksforgeeks* link for problem is <https://www.geeksforgeeks.org/average-of-a-stream-of-numbers/>

### Complexity

The solution needs to be O(1) time and O(1) space

---

My solution:
------------

I wrote a `closure in Javascript` to save the current average and total number of values encountered so far. Then wrote another function to call it by passing some parameters. The parameters decide whether I should be updating the average or returning it.

```js
function analytics() {
  const data = {
    avg: 0, //the average at that instant
    totalPoints: 0 //total number of values encountered till that point
  }
  return function(value) {
    //if value is not present, return the avg
    if (!value) {
      return data.avg
    }
    const newTotal = data.avg * data.totalPoints + value
    const newTotalP = data.totalPoints + 1
    //update the value for next usage
    data.avg = newTotal / newTotalP
    data.totalPoints = newTotalP
    return data.avg
  }
}

fn = analytics()

/*
 param = {
  type: //Company Names
  value: //Value to update
 }
*/

function y({
  type,
  value
}) {
  if (["Y"].indexOf(type) >= 0) {
    return fn()
  } else if (["X"].indexOf(type) >= 0) {
    return fn(value)
  }
}

console.log("get avg", y({
  type: "Y"
}))
console.log("update avg", y({
  type: "X",
  value: 1
}))
console.log("update avg", y({
  type: "X",
  value: 3
}))
console.log("update avg", y({
  type: "X",
  value: 5
}))
console.log("get avg", y({
  type: "Y"
}))
console.log("update avg", y({
  type: "X",
  value: 7
}))
console.log("update avg", y({
  type: "X",
  value: 9
}))
console.log("get avg", y({
  type: "Y"
}))
```

### My concerns/doubts:

* What did I miss here so that solution is not scalable
* Any use cases when it might cause issues
* How can it be re-written to make it scalable

### Things the can be assumed won't cause any issues

* Need not worry about precision issues while calculating the average
* Need not worry about issues due to Number datatype not able to accomodate very large values
* Data validation issues
* Variable names etc (I re-wrote the solution again for codereview, so some names are not correct)

Hope, I am able to explain the situation properly and would like to get more insights here. Also, let me know if anyone needs any further explanation or something is missing