Javascript sum dynamic django rest framework entries - javascript

I'm working on an app that allows a user to calculate information regarding a trade based on their entries. I've been stuck getting proper calculations on trade sums based on entries being added after the page has already retrieved any existing entries.
<td scope="col">${sumTotal('amount')}</td>
<script>
...
mounted() {
this.trade_id = window.location.pathname.split("/")[3];
// Get entries of trade
axios
.get('/trade/' + window.location.pathname.split("/")[3] + '/entries/')
.then(response => (this.entries = response.data));
},
...
methods: {
sumTotal(base) {
return Math.round(this.entries.reduce((sum, cur) => sum + cur[base], 0));
}
</script>
When the page first loads and pulls the existing entries the first calculation (first column) is correct with 16. However, when I add a new entry the auto-calculated value is no longer true.
The first column should be 26 but now is 1610
I can add much more info as needed. I wasn't sure how much would be required and I didn't want to clutter the question.

This happened on JS side,
it is because you are adding a numeric value with a string value, the result will be the concatenation of both values in a new string.
if you noticed
previous sum was 16, and the new value is 10
their concatenation will be 1610
the solution is as simple as converting the new value from string to a numeric value
You should change the line inside sumTotal to:
return Math.round(this.entries.reduce((sum, cur) => sum + parseInt(cur[base]), 0));

Related

How to use filter(), map() to work with values fo an array? JavaScript

My task is:
Implement the function duplicateStudents(), which gets the variable
"students" and filters for students with the same matriculation
number. Firstly, project all elements in students by matriculation
number. After that you can filter for duplicates relatively easily. At
the end project using the following format: { matrikelnummer:
(matrikelnummer), students: [ (students[i], students[j], ... ) ] }.
Implement the invalidGrades() function, which gets the variable "grades"
and filters for possibly incorrect notes. For example, in order to
keep a manual check as low as possible, the function should determine
for which matriculation numbers several grades were transmitted for
the same course. Example: For matriculation number X, a 2. 7 and a 2.
3 were transmitted for course Y. However, the function would also take
into account the valid case, i. e. for matriculation number X, once a
5,0 and once a 2,3 were transmitted for course Y.
In this task you should only use map(), reduce(), and filter(). Do not
implement for-loops.
function duplicateStudents(students) {
return students
// TODO: implement me
}
function invalidGrades(grades) {
return grades
.map((s) => {
// TODO: implement me
return {
matrikelnummer: -1/* put something here */,
grades: []/* put something here */,
};
})
.filter((e) => e.grades.length > 0)
}
The variables students and grades I have in a separate file. I know it might be helpful to upload the files too, but one is 1000 lines long, the other 500. That’s why I’m not uploading them. But I hope it is possible to do the task without the values. It is important to say that the values are represented as an array
I'll give you an example of using reduce on duplicateStudents, that's not returning the expected format but you could go from there.
const duplicateStudents = (students) => {
const grouping = students.reduce((previous, current) => {
if (previous[current.matrikelnummer]) previous[current.matrikelnummer].push(current); // add student if matrikelnummer already exist
else previous[current.matrikelnummer] = [current];
return previous;
}, {});
console.log(grouping);
return //you could process `grouping` to the expected format in here
};
here's preferences for you:
map
filter
reduce

First Empty Row in Excel Spreadsheet using Javascript

I was writing some code for automatically generating report and appending it into a Excel Web Spreadsheet. The program runs periodically, each run generates a set of data and inserts it into the first empty row in a specific spreadsheet file.
when writing code for inserting the row, I found that there is no API for searching where the first empty row is. Therefore I need to use the read API to search the row number for inserting new data.
The read API looks like this:
Since the spreadsheet is stored online, for performance issue, readCells is limited to return at most 30 rows of data each time.
Can I write a function to search the position of the first empty row in column A? Please note that the spreadsheet is for automatic reports, so the number of rows could be very large, and I want to generate the report quickly enough
In a comment you've said that we can assume that previously, data were always written contiguously starting from row 1. That being the case, you're looking for the handy getUsedRange function, probably with a true argument:
const range = worksheet.getUsedRange(true);
From the documentation:
The used range is the smallest range that encompasses any cells that have a value or formatting assigned to them. If the entire worksheet is blank, this function will return the top left cell (i.e. it will not throw an error).
Parameters
valuesOnly boolean
Optional. If true, considers only cells with values as used cells (ignoring formatting).
You'd get the used range, and then query the range to find out where it ends. The first blank row is the next row after the end of the range.
Basically I start from somewhere and get the next 30, and then check if any of the results is null. If not, I call the same function with another start that is 30 +previous start else I return start + index of null
async function readCell(column, start) {
const results = await readCells(`${column}${start}:${column}${start + 30}`);
const foundIndex = results.find(element => element === null);
if (foundIndex === -1) {
return await readCell(column, start + 30);
} else {
return foundIndex + start;
}
}

Setting custom numeric key when pushing new data to firebase database

I am new to Firebase and I want to have my own keys while pushing new data to the database.
Right now I'm using the following.
uid(FirebaseAuth.getInstance().getCurrentUser().getUid())
But I want to create my own id and it must be a numeric value.
How can I create my own custom key there? Such as 0001,0002, etc.
I am asking here because I'm working on a project for online shopping. when a user adds a product to their inventory it needs to assign an id for every product. If it is not possible then just tell me no, I can accept that answer.
You can simply perform a push() function. What that would do is create a random id for your node.
databaseRef.push(); // You have created a node with a random id.
However, if you want to create a node with a numeric id you can have a function that creates a numeric value:
public static long generateRandom(int length) {
Random random = new Random();
char[] digits = new char[length];
digits[0] = (char) (random.nextInt(9) + '1');
for (int i = 1; i < length; i++) {
digits[i] = (char) (random.nextInt(10) + '0');
}
return Long.parseLong(new String(digits));
}
The function is from: 12 Digit unique random number generation in Java
You pass a length and it creates a random numeric value. The ideal length for you would be 5. Then you could go and do this:
long randomFiveDigitValue = generateRandom(5);
databaseRef.child(String.valueOf(randomFiveDigitValue)).setValue(your_object);
Another option would be to use an integer hash-code. It would decrease hash collisions, but you should be ready to handle them as with the previous function too. You could take an identifier from the order, like the date or even a mixture of factors, and do this:
//Replace all these variables with the respective value
String factors = "your_date" + "user_uid" + "product_name";
factors.hashCode(); //String date returns a integer hash value.
Here are the hashCode() collisions for 50000 randomly generated products:
COLLISIONS BETWEEN: 2 Items
ITEM 1: DATE: 24-5-2019 08:09 PM + NAME: IPHONE + UID: 4J3IF93KSKK0295[L3
ITEM 2: DATE: 24-5-2019 09:08 PM + NAME: MARKER + UID: 534KKJI903[PCO4OP5
It took a long time to generate these and I think collisions are really rare now. Like 1 to 50000 ratio. My algorithm could have been flawed, but still this way the collisions are really low.

How to Approach Parsing CSV in Javascript

(My first post, I apologise for any mistakes)
I'm working with a small set of data in CSV files, which I need to read, process, and then export as a text file.
The format of the CSV data is:
REGO,STATUS,SHIFT,LOCATION,LOADED
CCA4110,StatusON,5:43,Brisbane,1
CCA4112,StatusON,5:44,Syndey,0
CCA4118,StatusON,6:11,Melbourne,1
I want to be able to take each line after the header row, and check
a) if the 'LOADED' value equals 0 or 1 (skip to next row if 1).
b) If 'LOADED' is 0, then check if the 'REGO' value matches a pre-defined list of 'REGO' values.
c) If a match, change the 'SHIFT' time.
d) If no match, move on to next row.
After that, I want to export all of the rows, with only the 'REGO' and 'SHIFT' values, to look like:
CCA4110,5:43
CCA4112,5:33
...
Because this feels a little complex to me, I'm having trouble visualising the best way to approach this problem. I was wondering if someone could help me think about this in a way that isn't just hacking together a dozen nested for loops.
Thanks very much,
Liam
Edit: a question about checking multiple conditions:
Say I have two CSV files:
List_to_Change.csv
REGO,STATUS,SHIFT,LOCATION,LOADED
CCA2420,StatusOn,11:24,BRISBANE,1
CCA2744,StatusOn,4:00,SYDNEY,1
CCA2009,StatusOn,4:00,MELBOURNE,0
List_to_Compare.csv
REGO,CORRECT_SHIFT
CCA2420,6:00
CCA2660,6:00
CCA2009,5:30
An algorithm:
1. Check value in 'List_to_Check.csv' 'LOADED' column
A. If value equals '0' go to step 2.
B. If value equals '1' skip this row and go to next.
2. Check if 'REGO' value in 'List_to_Check.csv' shows up in 'List_to_Compare.csv'
A. If true go to step 3.
B. If false skip this row and go to next.
3. Change 'SHIFT' value in 'List_to_Change.csv' with value shown in 'List_to_Compare.csv'
4. Stringify each row that was changed and export to text file.
My advice would be to split the work flow in to three steps:
Parse all rows to javascript objects
Perform the logic on the array of objects
Stringify the objects back to CSV
// This creates an object based on an order of columns:
const Entry = ([rego, status, shift, location, loaded]) =>
({ rego, status, shift, location, loaded });
// Which entries are we interested in?
const shouldHandleEntry = ({ loaded }) => loaded === "1";
// How do we update those entries?
const updateEntry = entry => ({
...entry,
shift: ["CCA4118"].includes(entry.rego)
? "5:33"
: entry.shift
});
// What do we export?
const exportEntry = ({ rego, shift }) => `${rego},${shift}`;
// Chain the steps to create a new table:
console.log(
csvBody(getCSV())
.map(Entry)
.filter(shouldHandleEntry)
.map(updateEntry)
.map(exportEntry)
.join("\n")
)
// (This needs work if you're using it for production code)
function csvBody(csvString) {
return csvString
.split("\n")
.map(line => line.trim().split(","))
.slice(1);
};
function getCSV() { return `REGO,STATUS,SHIFT,LOCATION,LOADED
CCA4110,StatusON,5:43,Brisbane,1
CCA4112,StatusON,5:44,Sydney,0
CCA4118,StatusON,6:11,Melbourne,1`; }

Trying to dynamically organize JSON object elements into different arrays based on values

This is the JSON I'm working with:
https://data.cityofnewyork.us/resource/xx67-kt59.json?$where=camis%20=%2230112340%22
I'd be dynamically making the queries using different data, so it'll possibly change.
What I'm essentially trying to do is to somehow organize the elements within this array into different arrays based on inspection_date.
So for each unique inspection_date value, those respective inspections would be put into its own collection.
If I knew the dates beforehand, I could easily iterate through each element and just push into an array.
Is there a way to dynamically create the arrays?
My end goal is to be able to display each group of inspections (based on inspection date) using Angular 5 on a webpage. I already have the site up and working and all of the requests being made.
So, I'm trying to eventually get to something like this. But of course, using whatever dates in the response from the request.
2016-10-03T00:00:00
List the inspections
2016-04-30T00:00:00
List the inspections
2016-04-12T00:00:00
List the inspections
Just for reference, here's the code I'm using:
ngOnInit() {
this.route.params.subscribe(params => {
this.title = +params['camis']; // (+) converts string 'id' to a number
this.q.getInpectionsPerCamis(this.title).subscribe((res) => {
this.inspectionList = res;
console.log(res);
});
// In a real app: dispatch action to load the details here.
});
}
I wish I could give you more info, but at this point, I'm just trying to get started.
I wrote this in jQuery just because it was faster for me, but it should translate fairly well to Angular (I just don't want to fiddle with an angular app right now)
Let me know if you have any questions.
$(function() {
let byDateObj = {};
$.ajax({
url: 'https://data.cityofnewyork.us/resource/xx67-kt59.json?$where=camis%20=%2230112340%22'
}).then(function(data) {
//probably do a check to make sure the data is an array, im gonna skip that
byDateObj = data.reduce(function(cum, cur) {
if (!cum.hasOwnProperty(cur.inspection_date)) cum[cur.inspection_date] = [];
//if the cumulative array doesn't have the inspection property already, add it as an empty array
cum[cur.inspection_date].push(cur);
//push to inspection_date array.
return cum;
//return cumulatie object
}, byDateObj);
//start with an empty object by default;
console.log(byDateObj);
}, console.error);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Categories