I have 2 methods, 1 is to get the initial amount and when I add credit I need to add it to the initial amount, somthing like paying my balance, I am using this:
updateBalanceAmount(){
let total = this.balance;
let transactionType = document.getElementById("selectMovimiento").value;
this.transaction.forEach(transactionAmount => {
if (transactionType === 'credito') {
total += Number(transactionAmount.amount)
}
});
this.total = total
document.querySelector('.available-amount').textContent = total
}
the second method is to update the balance when I add a transaction (buy something)
totalBalance(){
let balance = parseFloat(document.querySelector('.balance-amount').textContent);
let transactionType = document.getElementById("selectMovimiento").value;
this.transaction.forEach(transactionAmount => {
if (transactionType === 'gasto') {
balance += Number(transactionAmount.amount)
}
});
if (!isNaN(balance)) { // check if balance is not NaN
this.balance = balance;
document.querySelector('.balance-amount').textContent = balance;
}
}
I would like to know if I can get this done with a better code or if you can see something wrong on it or if you can help me to understand how can I merge both methods to create just one. Thanks for your help
Related
This is a really unusual code i haven't written myself, each day a database is updated with around 200 records.
This means we have to do 200 api calls to figure out infomation about theese records every day at 7 am.
This has been working fine until now,
the api has implemented a limit of 50 api calls pr hour, and IF you try to do 51 calls, you get banned for 24 hours...
SO, how do i make the for loop do a maximum of 50 loops here?
for (let record of records ) {
//This loop has to be limited to 50 iterations pr run.
let brregRawData = await fetch(`some url/${record.name}/someurl`);
let brregJson = await brregRawData.json()
let personNavn = brregJson.rollegrupper[0].roller[0].person.navn.fornavn
let personEtternavn = brregJson.rollegrupper[0].roller[0].person.navn.etternavn
// if mellomnavn = undefined, then do nothing
if (brregJson.rollegrupper[0].roller[0].person.navn.mellomnavn == undefined) {
var personMellomNavn = ""
} else {
let personMellomNavn = brregJson.rollegrupper[0].roller[0].person.navn.mellomnavn + " "
}
I tried looking up different ways to use a for loop, but all the solutions i looked at broke the "${record.name}" part of the url, i have to loop through an entire view of an entire database.
I'm not sure if this is right for the case, but can you define a counter outside of the loop, increment internally and break when it reaches 50.
let count = 0;
for (....)
...
if (count++ > 50) break;
...
If I'm understanding you correctly, you need to limit the number of api calls to 50 but the current implementation uses a for ... of loop. The simplest way to achieve what you're looking for with the least amount of modification is to use a standard for loop.
Assuming this all happens inside an async function...
async function limitToFiftyApiCalls(records) {
const max = Math.min(records.length, 50);
for (let i = 0; i < max; i++) {
const record = records[i];
let brregRawData = await fetch(`some url/${record.name}/someurl`);
let brregJson = await brregRawData.json();
let personNavn = brregJson.rollegrupper[0].roller[0].person.navn.fornavn;
let personEtternavn = brregJson.rollegrupper[0].roller[0].person.navn.etternavn;
// if mellomnavn = undefined, then do nothing
if (brregJson.rollegrupper[0].roller[0].person.navn.mellomnavn == undefined) {
var personMellomNavn = "";
} else {
let personMellomNavn = brregJson.rollegrupper[0].roller[0].person.navn.mellomnavn + " ";
}
}
}
The code above doesn't modify your existing code much other than limiting the number of API calls. However there's a few things you could do that would generally make the code easier to read and edit.
async function limitToFiftyApiCalls(records) {
const max = Math.min(records.length, 50);
for (let i = 0; i < max; i++) {
const record = records[i];
let personMellomNavn = "";
let brregRawData = await fetch(`some url/${record.name}/someurl`);
let brregJson = await brregRawData.json();
// why write this more than once?
// save it to a variable and make life easier
let someVar = brregJson.rollegrupper[0].roller[0].person.navn;
let personNavn = someVar.fornavn;
let personEtternavn = someVar.etternavn;
if (someVar.mellomnavn) {
personMellomNavn = someVar.mellomnavn + ' '
}
}
}
A very simple way to do this is implementing a count that increments every time the loop executes the body. So for the the loop you provided it would look like this:
let count = 0; // initialize count as 0
for (let record of records ) {
if(count >= 50) break; // break out of loop if count is equal to or greater than 50 (since count starts from 0)
//This loop has to be limited to 50 iterations pr run.
let brregRawData = await fetch(`some_url/${record.name}/some_url`);
let brregJson = await brregRawData.json()
let personNavn = brregJson.rollegrupper[0].roller[0].person.navn.fornavn
let personEtternavn = brregJson.rollegrupper[0].roller[0].person.navn.etternavn
// if mellomnavn = undefined, then do nothing
if (brregJson.rollegrupper[0].roller[0].person.navn.mellomnavn == undefined) {
var personMellomNavn = ""
} else {
let personMellomNavn = brregJson.rollegrupper[0].roller[0].person.navn.mellomnavn + " "
}
count++; // Increment the count after each iteration
}
Answer to you question:
for (let i=0; i<math.min(records.length, 50); i++ ) {
let record = records[i];
But what happens then with the records you have not checked? Will you wait 24h? I guess that's not what's expected, and instead will have to check 50 records every hour until you have checked them all (so 4 times for 200 records).
Hi im doing a job at work where we have a camera system that pings everytime someone enters or exits a room so you would have data like this:
{enter:7, exit:6}
which should mean one person is left in room
I want to know what was the highest amount of people in the room over a given period lets just say 45 minutes. I could have 50 to 100 points of data how can i would out what the average would be
Thanks
// update with a code sample here
.then((results) => {
// maybe a correct algorithim
results.sort((a, b) => b.enter - a.enter);
results.sort((a, b) => b.exit - a.exit);
results.sort((a, b) => a.enter - b.enter || b.exit - a.exit);
// results.sort(fieldSorter(["enter"]));
let final_result = result.pop();
console.log(final_result);
if (final_result) {
return parseInt(final_result.enter - final_result.exit);
} else {
return 0;
}
})
So before this code im gathering all the datapoints then try and sort them and pop off the highest entertence to the lowest exits but i think im going about this wrong
Assuming that enter time is always smaller than exit time (which contradicts your example data), the issue could be solved like this:
function getAverage(startTime, endTime, items) {
let slots = {};
for (let timeIndex = startTime; timeIndex <= endTime; timeIndex++) {
slots[timeIndex] = 0;
}
for (item of items) {
let enter = Math.min(item.enter, startTime);
let exit = Math.min(item.exit, endTime);
for (let momentIndex = enter; momentIndex <= exit; momentIndex++) {
slots[momentIndex]++;
}
}
let avg = 0;
for (let slot of slots) avg += slot;
return avg / slots.length;
}
EDIT
For computing the maximum you can do something like this:
function getAverage(startTime, endTime, items) {
let slots = {};
for (let timeIndex = startTime; timeIndex <= endTime; timeIndex++) {
slots[timeIndex] = 0;
}
for (item of items) {
let enter = Math.min(item.enter, startTime);
let exit = Math.min(item.exit, endTime);
for (let momentIndex = enter; momentIndex <= exit; momentIndex++) {
slots[momentIndex]++;
}
}
let max = 0;
for (let slot of slots) max = Math.max(max, slot);
return max;
}
I have a simple function that has to give a change. Something like vending machine. It takes 2 arguments: price of the item and an array of bills and coins received. The output must be an array of numbers only in [quarter, dime, nickel, penny] format. For example, item costs 3.29 and the amount received is [1,1,2]. In this case the output must be [2,2,0,1] because the change which is 0.71 can be divided as 2 quarters, 2 dimes, 0 nickels and 1 penny. If amount received is less than a price then it has to return the full amount but only in format mentioned above. For example, if the price is 5 but amount paid is [2,2], the output must be [16,0,0,0]. I have created this function:
`function change(price,paid) {
const totalPaidVal = paid.reduce((a,b)=>a+b,0)
if (totalPaidVal === price) {
return(Array(4).fill(0))
} else if (price > totalPaidVal) {
const qNum = Math.floor(totalPaidVal/0.25);
const dNum = Math.floor((totalPaidVal-(qNum*0.25))/0.1);
const nNum = Math.floor((totalPaidVal-(qNum*0.25)-(dNum*0.1))/0.05);
const pNum = Math.round((totalPaidVal-(qNum*0.25)-(dNum*0.1)-(nNum*0.05))/0.01);
const arr = [qNum,dNum,nNum,pNum];
return arr;
} else if(price<totalPaidVal) {
const change = totalPaidVal-price;
const qNum = Math.floor(change/0.25);
const dNum = Math.floor((change-(qNum*0.25))/0.1);
const nNum = Math.floor((change-(qNum*0.25)-(dNum*0.1))/0.05);
const pNum = Math.round((change-(qNum*0.25)-(dNum*0.1)-(nNum*0.05))/0.01);
const arr = [qNum,dNum,nNum,pNum];
return arr;
}
}`
It works fine but I know that it looks like I repeat myself over again what is not good. I've been trying to create other variables to clean it up but it still looks pretty weird. There must be more efficient way to do that without repeating same pieces of code all the time. So, here is the question: what is the best way to clean it up and make it look simpler than now?
You can use a function to remove the duplicity from code.
function getNums(value){
const qNum = Math.floor(value/0.25);
const dNum = Math.floor((value-(qNum*0.25))/0.1);
const nNum = Math.floor((value-(qNum*0.25)-(dNum*0.1))/0.05);
const pNum = Math.round((value-(qNum*0.25)-(dNum*0.1)-(nNum*0.05))/0.01);
return [qNum,dNum,nNum,pNum];
}
call this function based on condition
if (price > totalPaidVal) {
return getNums(totalPaidVal)
} else if(price < totalPaidVal){
return getNums(totalPaidVal - price)
}
I'm struggling for while trying to figure out how to increase a number based on a Date or based on a time (Using setInterval).
I don't know which option is easier. I made it by using setInterval:
HTML
<p class="counter"></p>
JS
let tickets = 35000;
const counter = document.querySelector('.counter');
let interval = setInterval(function(){
console.log(tickets);
if (tickets >= 60000) {
var textSoldOut = `<p>¡Todo vendido!</p>`;
counter.innerHTML = textSoldOut;
console.log("Sold out");
clearInterval(interval);
}else{
var text = `¡${tickets} tickets Sold!`;
contador.innerHTML = text;
console.log(text)
}
const random = Math.floor(Math.random()*(200-100+1)+100);
tickets += random;
}, 10000);
The thing is every time the page is refreshed the counter starts from 35000 again. I am trying to figure out how to storage the var tickets. I guess this would be made by using localStorage, but since I am a beginner in JS, I am not able to do it.
Other option would be by checking the date, and based on that, show a number:
function date() {
var d = new Date();
var month = d.getMonth();
var day = d.getDate();
const counter = document.querySelector('.contador');
const random = Math.floor(Math.random()*(200-100+1)+100);
for (let i = 350000; i <= 60000 ; i++) {
if (month == 0 & day == 28) {
var sum = i + random;
document.getElementById("contador").innerHTML = suma;
}else if (mes == 0 & dia == 30) {
...
} else if (...){
...
}
}
document.getElementById("dia").innerHTML = dia;
document.getElementById("mes").innerHTML = mes;
}
fecha();
Could someone help me out to reach the result?
I would really appreciate it
The Storage object accessible via the localStorage property offers two methods to save or retrieve data: setItem and getItem().
Usage is quite simple. If you want to save the numbers of tickets into a myTickets key on localStorage you have to do it like this:
localStorage.setItem("myTickets", tickets);
To retrieve that data later on:
localStorage.getItem("myTickets");
You just have to make sure to update the myTickets key on localStorage as you increase the number of tickets inside the setinterval callback function.
let tickets = 35000;
if (localStorage.getItem("myTickets") == null) {
localStorage.setItem("myTickets", tickets);
} else {
tickets = localStorage.getItem("myTickets");
}
const counter = document.querySelector('.counter');
let interval = setInterval(function() {
console.log(tickets);
if (tickets >= 60000) {
var textSoldOut = `<p>¡Todo vendido!</p>`;
counter.innerHTML = textSoldOut;
console.log("Sold out");
clearInterval(interval);
} else {
var text = `¡${tickets} tickets Sold!`;
console.log(text)
}
const random = Math.floor(Math.random() * (200 - 100 + 1) + 100);
tickets += random;
localStorage.setItem("myTickets", tickets);
}, 10000);
I am using a dataset that contains around 65k data. I am mapping over the dataset multiple times to massage the dataset. After obtaining the dataset in the required format, I am using map to do some computations with the price of the current item. But, whenever I return the current object, it contains the computation data of the previous object.
Whenever I log the data, it always shows the current object and the computations based on the current object. But, the returned object contains a previous object's data. Here is the route:
const {priceBands} = require('../utils/profitComputations');
let profitArray = [];
//calculating the price bands
profitArray = _.map(nfoArray, item=>{
console.log(item.cmp);
//returns the current market price; getting the correct value here
let priceBandVar = priceBands(Number(item.cmp));
console.log(priceBandVar);
//applying some algorithms; getting the correct value here
return {item: item.cmp, profitBand: priceBandVar};
//Here I find a mismatch between the parameter and the calculations
});
Here is the priceBands function in my 'utils/profitComputations':
const _ = require('lodash');
const priceBandInterval = {'-4':0, '-3':0, '-2':0, '-1':0, '0floor':0,'0ceil':0,'1':0, '2':0, '3':0, '4':0};
let priceBands = {};
module.exports = {
priceBands: function(price){
let factor = 0;
if(price>=10000){
factor = 100;
}else if (price>=1000 && price<10000){
factor = 50;
}else if (price>=500 && price<1000){
factor = 25;
}else if (price>=100 && price<500){
factor = 10;
}else if(price>=25 && price<100){
factor = 2;
}else{
factor = 0.5;
}
let priceCeil, priceFloor;
if((price%factor) == 0){
priceCeil = price + factor;
priceFloor = price - factor;
} else {
const remainder = price%factor;
priceCeil = price - remainder + factor;
priceFloor = price - remainder;
}
_.map(Object.keys(priceBandInterval), item=>{
if(parseInt(item)>0){
priceBands[item] = (parseInt(item)*factor) + priceCeil;
} else if (parseInt(item)<0){
priceBands[item] = (parseInt(item)*factor) + priceFloor;
} else {
priceBands['0floor'] = priceFloor;
priceBands['0ceil'] = priceCeil;
}
});
return priceBands;
}
}
I would appreciate if someone can share some valuable insights on what I am missing.
You must clone the variable priceBandVar because javaScript variables are called by reference. The following code is your answer:
profitArray = _.map(nfoArray, item => {
console.log(item.cmp);
//returns the current market price; getting the correct value here
let priceBandVar = priceBands(Number(item.cmp));
console.log(priceBandVar);
//applying some algorithms; getting the correct value here
return {
item: item.cmp,
profitBand: clone(priceBandVar)
};
//Here I find a mismatch between the parameter and the calculations
});
function clone(o) {
var ret = {};
Object.keys(o).forEach(function(val) {
ret[val] = o[val];
});
return ret;
}