How to calculate the P/E ratio of the stocks? - javascript

Formula to calculate is, Portfolio P/E = Net Worth/Sum(Stock EPS * Shares Held)
I have the value for net Worth but I am unable to iterate over the EPS values and multiply it by the shares held. Can you please suggest some solution for this. Thank you!
Here is the plunker
<div>
<h3>P/E Ratio: {{getNetWorth())}}
</div>
Script:
$http.get('data.json').then(function(response) {
$scope.stocksArray = [];
var indexes = [];
var epsindex = [];
var eps = {};
$scope.eps = response.data.eps;

It won't win any awards, but here is the long and short of the problem.
Your json file is structured oddly like this:
-price
--stock-name:stock-price
-eps
--stock-name:stock-eps
It should be structure like this:
-stock-name
--price:actual-price
--eps:actual-eps
This would let you pull it in as objects without needing to instantiate the entire collection manually. But I played with the data I was given and it works.
The key is the following two line
$scope.eps = response.data.eps;
AND
mystock.eps = $scope.eps[key];
By adding the eps collection as a seperate array I was able to add it as a field in the object property.
getPortfolioPE() was the easy part:
$scope.getPortfolioPE = function(){
let temp = 0;
let total = 0;
for(let i = 0; i < $scope.stocksArray.length; i++){
total += $scope.stocksArray[i].eps * $scope.stocksArray[i].shares
}
temp += $scope.getNetWorth()/ total;
return temp.toFixed(2);
}

I think your $http.get should return an array of stocks, and the PE ratio is a property of each array element.
Therefore, you should have something like this in controller:
$scope.stocks = response.data;
And you may need use ng-repeat in template, something like this:
<li ng-repeat="item in stocks">
You PE is: {{item.pe}}
</li>

Related

Method push is not adding a value to a vector that previously had the same value

The goal of the code I'm going to present is to create a aux vector that will contain petri nets transitions, arcs and places. I'm dividing a petri net into several groups, each group is a transition with respective input arcs and places.
The issue is the following: After I put the info in the first position of the aux vector, I'm unable to put a place with the same id of the place of the previous group. For example, if I have a transition with place_id=1 and place_id=2, and the next transition have place_id=2 and place_id=3, the code doesn't write the value place_i=2 in the vector for the second group.
function conflict() {
var id = [];
var source = [];
var target = [];
var aux = [];
var cont = [];
var places = pnml.getElementsByTagName("place");
var arcs = pnml.getElementsByTagName("arc");
var transitions = pnml.getElementsByTagName("transition");
for (var i = 0; i < transitions.length; i++) {
target.push(transitions[i].getAttribute("id"));
aux.push([]);
for (var j = 0; j < arcs.length; j++) {
if (arcs[j].getAttribute("target") == transitions[i].getAttribute("id")) {
id.push(arcs[j].getAttribute("id"));
source.push(arcs[j].getAttribute("source"));
//console.log(arcs[j].getAttribute( "source" ));
}
}
//console.log(id);
//console.log(arcs);
//console.log(places);
aux[i].push(id, source, target);
//id.length=0;
target = [];
source = [];
id = [];
}
}
Image of the platform with console open
Thanks in advance
Without knowing a whole lot for the issue, try to change this
aux.push([]);
to this
aux[i]=[];
So that you initialize and fill using an index instead of a push and an index later, for consistency.
Let me know if it helps
EDIT:
Also this
aux[i].push(id, source, target);
to this (maybe? )
aux[i].push({ id: id, source:source, target:target});
You probably want to keep objects in aux, so you need to push an object, not 3 parameters like that

Creating a leaderboard with Firebase

I'm trying to build a top 10 leaderboard using the Firebase Realtime DB - I am able to pull the top 10 ordered by score (last 10 due to the way firebase stores in ascending order) however when I attempt to place them in the page they all appear in key order.
If I was a betting man I'd guess it's to do with the for loop I have to create the elements - but I'm not good enough at Javascript to work out where the issue is I've spent the last 3 hours on MDN and W3Schools and I can't for the life of me work it out.
Either that or I need to run a For Each loop on the actual data query? but I feel like I could avoid that as I'm already collecting the score data so I could just arrange that somehow?
I was sort of expecting everything to appear in ascending order - meaning I would have to go back and prepend my JQuery but instead I've managed to accidentally create a new problem for myself.
Any suggestions will be GREATLY appreciated
Here is my current code:
var db = firebase.database()
var ref = db.ref('images')
ref.orderByChild('score').limitToLast(10).on('value', gotData, errData);
function gotData(data) {
var scores = data.val();
var keys = Object.keys(scores);
var currentRow;
for (var i = 0; i < keys.length; i++){
var currentObject = scores[keys[i]];
if(i % 1 == 0 ){
currentRow = document.createElement("div");
$(currentRow).addClass("pure-u-1-5")
$("#content").append(currentRow);
}
var col = document.createElement("div")
$(col).addClass("col-lg-5");
var image = document.createElement("img")
image.src=currentObject.url;
$(image).addClass("contentImage")
var p = document.createElement("P")
$(p).html(currentObject.score)
$(p).addClass("contentScore");
$(col).append(image);
$(col).append(p);
$(currentRow).append(col);
}
}
Use .sort() beforehand, then iterate over each score object to add it to the page:
function gotData(data) {
const scores = data.val();
const keys = Object.keys(scores);
const sortedKeys = keys.sort((keyA, keyB) => scores[keyB].score - scores[keyA].score);
const content = document.querySelector('#content');
sortedKeys.map(sortedKey => scores[sortedKey])
.forEach(scoreObj => {
const row = content.appendChild(document.createElement('div'));
row.classList.add('pure-u-1-5'); // better done in the CSS if possible
const col = row.appendChild(document.createElement('div'));
col.classList.add('col-lg-5');
const img = col.appendChild(document.createElement('img'));
img.src = scoreObj.url;
img.classList.add('contentScore');
col.appendChild(document.createElement('p')).textContent = scoreObj.score;
});
}
For loops have worse abstraction, require manual iteration, and have hoisting problems when you use var - use the array methods instead when you can.

storing local variable then re-running function?

So I'm making an app that, in a nut shell, takes dimensions from the user and spits out the surface area but it's quickly becoming really repetitive.
function calc() {
var dim1main = +document.getElementById("dim1main").value || 0;
var dim2main = +document.getElementById("dim2main").value || 0;
var mainSurA = dim1main * dim2main;
var dim1mainD1 = +document.getElementById("dim1mainD1").value || 0;
var dim2mainD1 = +document.getElementById("dim2mainD1").value || 0;
var mainD1SurA = dim1mainD1 * dim2mainD1;
// ...
var dim1mainD6 = ...
// ...
var totalSurA = mainSurA + mainD1SurA ... + mainD6SurA;
}
So the idea was to have hundreds of text inputs hidden until the user wanted them and everything that was left empty would run through as zero, therefor not messing with the total. I think I'm safe in assuming this is horrible javascript.
I've been looking for a way to run a function multiple times and store each local variable somewhere for later use. I've played with arrays by deleting the input values onClick but each time I run the function with .push it replaces the first value with the second. I've read about localStorage but I'm not sure that's what I'm looking for. Any suggestions? Sorry if this is too vague.
I have read about storing data in objects as well as global variables but I've heard that gets messy.
One way you can do this is instead of hiding many elements you can dynamically create new input elements when needed. You can give your elements a specific class which you can use to get it via a HTMLCollection and compute the total dimension.
For example:
document.getElementById('add').onclick = function()
{
var container = document.getElementById('container');
var subContainer = document.createElement("div");
var dim1 = document.createElement("input");
var dim2 = document.createElement("input");
dim1.className = "dim1";
dim2.className = "dim2";
dim1.value = dim2.value = 0;
subContainer.className = "sub-container";
subContainer.appendChild(dim1);
subContainer.appendChild(dim2);
container.appendChild(subContainer);
}
document.getElementById('calc').onclick = function()
{
var arrayDim1 = document.getElementsByClassName('dim1');
var arrayDim2 = document.getElementsByClassName('dim2');
var totalSurA = 0;
for (var i = 0; i < arrayDim1.length; i++) {
totalSurA += +arrayDim1[i].value * +arrayDim2[i].value;
}
console.log(totalSurA);
}
<div id="container"></div>
<button id="add">Add Dimension</button>
<button id="calc">Calculate</button>
For storing past page sessions you can use localStorage as you said. I would in JavaScript as a 2D array of each row item (or you can use an array of objects with a property for dim1/dim2), like so:
[
[dim1_0, dim2_0],
[dim1_1, dim2_1],
...
]
Although before saving it to local storage you need it in a text format, which you can convert it to using JSON.stringify()

How to create multiple objects based on dynamic data?

Basically what i'm doing, is trying to create my own steam market JSON, by HTML parsing.
Example of how I'm currently doing that :
var url = 'http://steamcommunity.com/market/search?appid=730'
var itemDiv = $("<div></div>")
$.get(url).success(function(r){
data = $(r).find('stuff i need')
itemDiv.append(data)
})
and now say I wanted to find names of the items in the div, i would do something like :
itemDiv.find('x').each(function(){
var name = $(this).find("y").text()
// console.log(name) [or do whatever is needed ect]
})
As I mentioned before, I need to return objects based on that data in the format of:
var item = {name:"",price:0}
However, things like price will always be changing.
Based on the data thats in the div, the final product would look along the lines of :
var x = {name:"a",price:1}
var x2 = {name:"a2",price:2}
How do I go about doing this? I thought maybe i could store the data in an array, and then do something like
for(x in y){
return object
}
or something along those lines.
Sorry if this seems like a bonehead question, I'm pretty new to javascript.
clarification: i'm trying to figure out how to return multiple objects based on the data inside the div.
Here is the code that builds an array of objects based on two arrays (assuming they are of equal length).
function buildStocks() {
// Names and prices can also be passed as function arguments
var names = ['a', 'b', 'c'];
var prices = [1, 2, 3];
var result = []; // Array of these objects
for (var i = 0; i < names.length; i++) {
result.push({
name: names[i],
price: prices[i]
});
}
return result;
}

accessing nested properties based on structure

Could anyone please give me an alternate syntax to the following
var id = '-JLxSeCPUCVN13FxifTY';
var ResultsContainer = results[id];
var i=0;
for(var k in ResultsContainer)
{
var TheArrayOfObjectsThatIneed = ResultsContainer[Object.keys(ResultsContainer)[i]];
console.log(TheArrayOfObjectsThatIneed);
//loop the TheArrayOfObjectsThatIneed do the processing
i++;
}
as you see in the image i have an array within an object within an object and i have no idea what the property names are but the structure is always the same {results:{id:{idthatidontknow:[{}]}}} and all i need is to access the arrays
the above code is working nicely but i am new to javescript and i was wondering if there is a nicer syntax and if i am doing it the right way
Perhaps something like this?
var id = '-JLxSeCPUCVN13FxifTY';
var ResultsContainer = results[id];
for(var k in ResultsContainer) {
if (ResultsContainer.hasOwnProperty(k)) {
var TheArrayOfObjectsThatIneed = ResultsContainer[k];
console.log(TheArrayOfObjectsThatIneed);
//loop the TheArrayOfObjectsThatIneed do the processing
}
}

Categories

Resources