Sum in constructor - javascript

I'm trying to solve the problem. When the user enter two numbers via ** prompt **, after the display shows the final result. Simple constructor, but this code only accepts the first value, I cannot force it to take the second one too, in order for sum both values
function Num (firstNum) {
this.firstNum = firstNum;
this.read = function() {
this.value = this.x + this.firstNum; {
return this.x = +prompt('a');
}
};
}
let num = new Num(10);
num.read();
num.read();
alert(num.value);

As other commenters have suggested you should probably edit your question to make it clearer. But if I had to take a guess here's my answer:
Lookup "curry functions" or "partial application". You can basically use closures to stash the value from the first prompt until you receive the value from the second.
const sumTwo = firstNum => secondNum => firstNum + secondNum;
// then when you want to use it;
const plusTen = sumTwo(prompt(10);
const resultA = plusTen(prompt(2)); // this will be 12
const resultB = plusTen(prompt(5)); // this will be 15

solve
function Num (firstNum) {
this.value = firstNum;
this.read = function() {
this.value += +prompt('a?', 0);
};
}
let num = new Num(10);
num.read();
num.read();
alert(num.value);

Related

Accessing global variable from function in Javascript

I would like to access variable from inside a function. The variable tip is innerText of different buttons (5, 6, 7...), but they are in %, so I converted them into numbers. However, the numbers are accessible only from inside the percentage function. When I try to call the function and log the variable, it shows NaN. I would like to use the tip for calculation in calc function always after clicking a respective button. How can I do that?
let tip = 0;
const billInput = document.querySelector(".bill__input");
const peopleInput = document.querySelector(".people__input");
const individualTip = document.querySelector(".conclusion__tip-person");
const individualTotal = document.querySelector(".conclusion__total-person");
const reset = document.querySelector(".conclusion__reset");
const buttons = document.querySelectorAll(".select-tip__button");
function percentage() {
tip = parseInt(this.innerText);
}
buttons.forEach((button) => {
button.addEventListener("click", percentage);
});
function calc() {
if (billInput !== "" && peopleInput === "") {
}
individualTip.textContent = (billInput.value / 100) * tip;
individualTotal.textContent =
"$" + (billInput.value / peopleInput.value).toFixed(2);
}
document.addEventListener("input", calc);
To make it little bit smaller:
I cant access numbers from variable tip, which innerText of buttons with different values (5%, 10%...). These numbers are converted from strings to numbers in the percentage function. I can access the correct tip values after clicking on buttons only if I log it directly inside the percentage function. I would like to use it outside the function, however.
let tip = 0;
function percentage() {
tip = parseInt(this.innerText);
}
buttons.forEach((button) => {
button.addEventListener("click", percentage);
});
you need change string to integer before you calculation
parseInt(peopleInput.value)
In the if (billInput !== "" && peopleInput === ""), you should return to not execute the reset of the function, Also the inputs values be as string format, you need to convert to number, you can use + operator.
let tip = 0;
const billInput = document.querySelector(".bill__input");
const peopleInput = document.querySelector(".people__input");
const individualTip = document.querySelector(".conclusion__tip-person");
const individualTotal = document.querySelector(".conclusion__total-person");
const reset = document.querySelector(".conclusion__reset");
const buttons = document.querySelectorAll(".select-tip__button");
function percentage() {
tip = parseInt(this.innerText);
}
buttons.forEach((button) => {
button.addEventListener("click", percentage);
});
function calc() {
if (billInput !== "" && peopleInput === "") {
// if there no value doesn't execute the rest of the function.
return
}
individualTip.textContent = (+billInput.value / 100) * tip;
individualTotal.textContent =
"$" + (+billInput.value / +peopleInput.value).toFixed(2);
}
document.addEventListener("input", calc);
So for anyone who would encounter similar problem, I solved this one. My variables and fucntions works properly. All I had to do was to put function calc() as the last line inside percentage() function. That did the trick. That's it.

Javascript: Object method - why do I need parentheses?

I am learning javascript and Ive stumbled upon issue that I do not understand. Could somebody explain to me why in method compareDNA I need to use parentheses while using this.dna and in the previous method it works just fine?
// Returns a random DNA base
const returnRandBase = () => {
const dnaBases = ['A', 'T', 'C', 'G'];
return dnaBases[Math.floor(Math.random() * 4)];
};
// Returns a random single stand of DNA containing 15 bases
const mockUpStrand = () => {
const newStrand = [];
for (let i = 0; i < 15; i++) {
newStrand.push(returnRandBase());
}
return newStrand;
};
function pAequorFactory(specimenNum, dna){
return {
specimenNum,
dna,
mutate(){
let i = Math.floor(Math.random() * 15)
let newGene = returnRandBase()
while (this.dna[i] === newGene){
newGene = returnRandBase()
}
this.dna[i] = newGene
return this.dna
},
compareDNA(object){
let counter = 0
for(let i = 0; i < this.dna().length; i++){
if(this.dna()[i] === object.dna()[i]){
counter++
}
}
let percentage = counter / this.dna().length * 100
return `Specimen number ${this.specimenNum} and specimen number ${object.specimenNum} have ${percentage}% of DNA in common.`
},
}
}
let aligator = pAequorFactory(1, mockUpStrand)
let dog = pAequorFactory(2, mockUpStrand)
console.log(aligator.compareDNA(dog))
console.log(dog.dna().length)
The problem is that the dna that is passed as an argument is a function, so it becomes a method of the returned object, and needs to be called with .dna(). However, this looks like a mistake - actually an array should have been passed:
let aligator = pAequorFactory(1, mockUpStrand())
// ^^
let dog = pAequorFactory(2, mockUpStrand())
// ^^
Then you can access .dna[i] or .dna.length as normal.
If you don't do that, dog.dna() returns a different DNA every time, which doesn't make sense.
using this.dna and in the previous method it works just fine?
Actually, it doesn't. dog.mutate() does return a function with a single integer property. It's supposed to return an array really.

Calculating the average of several function invocations using closures

I am doing a coding challenge that reads like this:
Create a function runningAverage() that returns a callable function object. Update the series with each given value and calculate the current average.
rAvg = runningAverage();
rAvg(10) = 10.0;
rAvg(11) = 10.5;
rAvg(12) = 11;
I got a working solution, yet they also want the results to be rounded like this:
rAvg(13) = 13.50678; => 13.50
rAvg(13) = 13.50; => 13.50
rAvg(13) = 13.5; => 13.5
rAvg(13) = 13; => 13
Here is my code:
function runningAverage() {
let number = 0;
let numbOfFunctionCalls = 0;
return function (y) {
number += y;
numbOfFunctionCalls ++;
let average = (number/numbOfFunctionCalls);
let averageArray = average.toString().split('.');
//to get the number of decimal places
//e.g 11.543 ==> ['11', '543']
if ((Array.from(averageArray[1]).length) >= 2) {
return average.toPrecision(2);
}
else if ((Array.from(averageArray[1]).length) = 1) {
return average.toPrecision(1);
}
else {
return average;
}
}
}
I tested parts of the function separately and it seems to work, yet when I invoke it I get the message 'cannot convert undefined or null to object'.
This sounds like a fun coding challenge!
In this case, you want toFixed(), not toPrecision(). toPrecision() essentially allows you determine how many digits TOTAL (including those on the left of the decimal point) should appear, whereas toFixed() focuses on the number of digits to the right of the decimal point. Feel free to look these two methods up on MDN. When you read that toPrecision() may return exponential notation, this should make you pause and think, "That's weird. Why does this happen? When does this happen?", rather than "this detail is unimportant."
Your .length = 1 comparison needs to be modified to a ===.
Your code currently fails if an integer is the first number provided to rAvg(). In your first conditional, Array.from(undefined) may run, which is not permissible in JavaScript. You should consider ways to only work with "the digits to the right of the decimal" only if "there are digits to the right of the decimal."
Here is a working solution including all the suggestions, in case someone is interested:
function runningAverage() {
let number = 0;
let numbOfFunctionCalls = 0;
return function (y) {
number += y;
numbOfFunctionCalls ++;
let average = (number/numbOfFunctionCalls);
let numIsDecimal = average.toString().includes('.');
if (numIsDecimal) {
let averageArray = average.toString().split('.');
//to get the number of decimal places
//e.g 11.543 ==> ['11', '543']
if ((Array.from(averageArray[1]).length) >= 2) {
return Number(average.toFixed(2));
}
if ((Array.from(averageArray[1]).length) === 1) {
return Number(average.toFixed(1));
}
}
else {
return Number(average);
}
}
}
Not sure if this works but try it
function runningAverage() {
let number = 0;
let numbOfFunctionCalls = 0;
return function (y) {
number += y;
numbOfFunctionCalls ++;
let average = (number/numbOfFunctionCalls);
let averageArray = average.toString().split('.');
if ((Array.from(averageArray[1]).length) >= 2) {
return Math.round(average.toPrecision(2) * 2) / 2;
} else if ((Array.from(averageArray[1]).length) == 1) {
return Math.round(average.toPrecision(1) * 2) / 2;
} else {
return Math.round(average * 2) / 2;
};
};
};

Object variable is undefined even though it's initialised

I have a Node project where I create a Unit and an AddGate:
var Unit = function(value, weight) {
this.value = value;
this.weight = weight;
}
var AddGate = function() {
this.sum_function = function(units) {
sum = 0;
for (unit in units)
sum += unit.value;
return sum;
};
};
AddGate.prototype = {
forward: function(units) {
this.units = units;
this.output_unit = new Unit(this.sum_function(units), 0.0);
return this.output_unit;
}
}
I create some Units, an AddGate, and a ForwardNeuron (guess what I'm making):
var in_1 = new Unit(1.0, 0.0);
...
var in_9 = new Unit(3.0, 0.0);
var add = new AddGate();
var forwardNeuron = function() {
a = add.forward({in_1, in_2, in_3, in_4, in_5, in_6, in_7, in_8, in_9});
};
forwardNeuron();
But for some reason, when in sum_function of AddGate, I can access each unit of units fine, but when I try to access unit.value, it says it's undefined, even though I've clearly initialised it. Am I missing something?
As the comments specify, for (let unit in units) will actually set unit as the key of the units object. You can correct this in a few ways such as using units[unit].value, but it would make more sense to me for the arguments to forward and sum_function to be an array. More or less as simple as:
add.forward([in_1, in_2, in_3, in_4, in_5, in_6, in_7, in_8, in_9]);
The sum would be a reduce operation on the array as in:
return units.reduce((sum, unit) => sum + unit.value, 0);
FYI 4castle's response worked for me - I wrote:
sum += units[unit].value;
That did the trick for me. Thanks again to 4castle and trincot for their speedy responses.
EDIT: The above is even better.

Trying to wrap this function in an object

Sorry for being vague and confusing everyone, Im grateful for all the feedback but let me explain what i am trying to do.
I want to create an object called Multiplier with two methods: multiply and getCurrentValue
multiply should initially return the number supplied * 1 and from then on whatever the
current value is times the number supplied, getCurrentValue should return the last
answer returned from multiply.
Hey everyone I am having a little trouble grasping this concept.
Here is my code so far:
var multiplier = {
function multiply(){
alert("Input a number to be multiplied by 1")
var a = prompt("Input your desired number");
var b = a * 1;
return alert(b);
}
}
multiply();
any help or further explaining on how i would go about this would be appreciated
var multiplier = {
lastValue: null,
getCurrentValue: function() {
return lastValue;
},
multiply: function() {
alert("Input a number to be multiplied by 1")
var a = prompt("Input your desired number");
var b = a * 1;
lastValue = b;
return alert(b);
}
}
This should do what you want. You're defining an object named multiplier, that has two functions and a variable to save the last value.
Of course, there are other ways to accomplish this, but your question is a little vague.
A more object oriented approach would be like so.
function Multiplier() {
var lastValue = null;
this.getCurrentValue = function() {
return lastValue;
};
this.multiply = function() {
alert("Input a number to be multiplied by 1");
var a = prompt("Input your desired number");
var b = a * 1;
lastValue = b;
return alert(b);
}
}
With this approach, your lastValue variable is private. You've only exposed the two functions. Now you can create a new one of these objects whenever you need one, like so.
var myMultiplier = new Multiplier();
And you can call functions on that multiplier like so.
myMultiplier.multiply();

Categories

Resources