I'm using a script that dynamically combines a category name with an item id. It will then call images from a folder that match the file name. It consists of the file path, category name and item id e.g. Banking-1.jpg, Banking-2.jpg, etc.
var f = {
image: "/img/" + this.item.Categories[0].Category + "-" + this.itemId + ".jpg"
}
Right now it just returns a value like Banking-50.jpg, for which there is no existing image. Is it possible to define a range so that the maximum value it can return is Banking-10.jpg?
You can cap the integer with the Math.min and Math.max functions. See the following example.
var f = {
image: "/img/" + this.item.Categories[0].Category + "-" + Math.min(Math.max(this.itemId, 0), 10) + ".jpg"
}
This will work unless this.itemId is a string, in which case you will need to cast it to an integer with parseInt.
var f = {
image: "/img/" + this.item.Categories[0].Category + "-" + Math.min(Math.max(parseInt(this.itemId,10), 0), 10) + ".jpg"
}
If you like, you can define a helper function like this.
function capToRange(i, min, max)
{
return Math.min(Math.max(i, min), max);
}
And use it like this.
var f = {
image: "/img/" + this.item.Categories[0].Category + "-" + capToRange(this.itemId, 0, 10) + ".jpg"
}
Related
This is my javascript implementation for the knapsack problem. In this problem, you are given a list of items with weights and values, and a knapsack with a weight capacity. The object is to determine how to maximize the value of objects you can hold in the knapsack without exceeding the weight capacity. My function below takes two parameters, items (an array of item objects, each containing a weight and value field, and a capacity integer representing the knapsack weight capacity. I use a memo table in which each index:weight is stored for repeated access to avoid duplicate calculations of getMax(). Is my implementation good? Can it be improved?
function knapsackMaxValue(items, capacity) {
const memo = {}
function getMax(i, weight) {
if (i == items.length) {
return 0;
}
if (memo[i + ':' + weight] != undefined) {
console.log('memo found')
return memo[i + ':' + weight]
}
if (items[i].weight + weight > capacity) {
memo[i + ':' + weight] = getMax(i + 1, weight)
return memo[i + ':' + weight]
} else {
let maxValue = Math.max(getMax(i + 1, weight), items[i].value + getMax(i + 1, weight + items[i].weight))
memo[i + ':' + weight] = maxValue
return maxValue
}
}
return getMax(0, 0)
}
I have javascript code like this:
var strikePrice = parseFloat(this.props.data.strike).toFixed(1);
var commission = parseFloat(this.props.commission / 100).toFixed(2);
var callInMoney = parseFloat(strikePrice + this.state.callPrice + commission).toFixed(2);
var putInMoney = parseFloat(strikePrice - this.state.putPrice - commission).toFixed(2);
console.log("strikePrice: " + strikePrice + " commission: " + commission);
console.log("callprice: " + this.state.callPrice + " putprice: " + this.state.putPrice);
console.log("call: " + callInMoney + " put: " + putInMoney);
and the output is this:
strikePrice: 34.0 commission: 0.08
callprice: 0 putprice: 0
call: 34.00 put: 33.92
That is wrong. The call should be 34.08 (8 cents higher) just like the put is 8 cents lower.
Why is the results not correct?
Thank you
Matt
toFixed returns a string so you're actually doing some string concatenation rather than the arithmetic you expect.
Check out what happens when you just print out your initial addition.
var strikePrice = parseFloat('34').toFixed(1);
var commission = parseFloat('0.08').toFixed(2);
console.log(strikePrice + 0 + commission);
Instead, you'll need to convert those strings to numbers first.
var strikePrice = parseFloat('34').toFixed(1);
var commission = parseFloat('0.08').toFixed(2);
strikePrice = parseFloat(strikePrice);
commission = parseFloat(commission);
console.log(strikePrice + 0 + commission);
This expression:
strikePrice + this.state.callPrice + commission
Evaluates to this value:
"34.000.08"
Because commission is a string value, which is because [toFixed()][1] takes an integer and returns a string.
You need to refactor your code so that commission is a float value, or so that you call parseFloat() again on the parameters of line 3.
I can't comment on why putInMoney works for you. For me it gave "NaN".
Ok, so I I'm having this strange behaviour that I cannot explain. Look at the following:
$("#completeData").on("click", function() {
var toUpdate = {};
var toUpdateCount = 0;
var ratios = {};
This.calculateGradePerSize();
//1) Select all sizes that are equal to NA or are Equal to 0 (means its a new one)
$.each(This.logements, function(key, l) {
if (l.sizeMyId === "NA" || l.sizeMyId === 0) {
toUpdate[l.rueNum] = l;
toUpdateCount++;
} else { //else init the ratios because it means they are actually present
/**
//My problem is this variable,
I want it to be equal to an empty object
But for reasons I cannot seem to understand,
it takes in account the latter modification in the code
that happens to this variables
*/
ratios[l.sizeMyId] = {};
}
});
console.log(toUpdate);
console.log(ratios);
console.log(This.sizeRatio);
//2) Calculate Ratios and build the ratios function of the toUpdate
$.each(This.sizeRatio, function(sizeMyId, count) {
if (sizeMyId !== "NA" && sizeMyId != 0) {
console.log("COUNT SIZE: " + count + " COUNT LOGEMENT: " + This.countLogement + " toUpdateCount: " + toUpdateCount + " SizeMyId: " + sizeMyId);
console.log("Calculation: " + count / This.countLogement * toUpdateCount);
ratios[sizeMyId].count = Math.ceil(count / This.countLogement * toUpdateCount);
console.log("Calculation WITH CEIL: " + Math.ceil(count / This.countLogement * toUpdateCount));
ratios[sizeMyId].grade = This.sizeGrade[sizeMyId];
ratios[sizeMyId].sizeMyId = sizeMyId;
}
});
console.log(ratios);
});
As explained in the multiline comment, my problem is the ratio variable. I tried declaring the variable without var prefix, so that JS doesn't know its existence but still, I want it to be empty object. In fact, the problem has stronger roots than simply that, I cannot update it. Each change I make to the ratios var are not registered, but I wanna start with the beginning how can I make sure that this variable is empty at the beginning of the function.
I don't know if this question is really worth. Thinking about deleting it. My bug was that the count variable in the each function as well as the ratio definition were the same hence not registering.
As for the variable not being an empty one at function start. It simply how the JS engine works. If there is something not working, more likely than not, there is something wrong in your code.
$.each(This.sizeRatio, function (sizeMyId, count) {
if (sizeMyId !== "NA" && sizeMyId != 0) {
console.log("COUNT SIZE: " + count + " COUNT LOGEMENT: " + This.countLogement + " toUpdateCount: " + toUpdateCount + " SizeMyId: " + sizeMyId);
console.log("Calculation: " + count / This.countLogement * toUpdateCount);
//HERE ratios[sizeMyId].count IS THE SAME than the anonymous function.
ratios[sizeMyId].count = Math.ceil(count / This.countLogement * toUpdateCount);
console.log("Calculation WITH CEIL: " + Math.ceil(count / This.countLogement * toUpdateCount));
ratios[sizeMyId].grade = This.sizeGrade[sizeMyId];
ratios[sizeMyId].sizeMyId = sizeMyId;
}
});
I have object like this:
{
Name: "John"
Location: "Unknown"
Type: "Unknown"
Status: "Unknown"
Phone_number: "Unknown"
}
Need to format it like this (with tabs or spaces):
Name: John // three tabs
Location: Unknown // two tabs
Type: Unknown // three tabs
Status: Unknown // three tabs
Phone_number: Unknown // one tab
Java and Perl has this functionality in printf, but how to do this in javascript?
Ok. Found here:
/**
* object.padding(number, string)
* Transform the string object to string of the actual width filling by the padding character (by default ' ')
* Negative value of width means left padding, and positive value means right one
*
* #param number Width of string
* #param string Padding chacracter (by default, ' ')
* #return string
* #access public
*/
String.prototype.padding = function(n, c)
{
var val = this.valueOf();
if ( Math.abs(n) <= val.length ) {
return val;
}
var m = Math.max((Math.abs(n) - this.length) || 0, 0);
var pad = Array(m + 1).join(String(c || ' ').charAt(0));
// var pad = String(c || ' ').charAt(0).repeat(Math.abs(n) - this.length);
return (n < 0) ? pad + val : val + pad;
// return (n < 0) ? val + pad : pad + val;
};
This not works with tabs, but works with spaces exactly how I describe in question.
For my example code will be:
$.each(myObj, function(myKey, myVal) {
myOut += myKey.padding(20) + " = " + myVal + "\r\n";
});
Output will be:
Name = John
Location = Unknown
Type = Unknown
Status = Unknown
Phone_number = Unknown
The String.prototype.padEnd(targetLength, padString) method will do the job, it is documented here.
The padString parameter is set to a single-space string if omitted.
Example:
console.log(` ${'Player'.padEnd(19)} ` +
`${'MATCH'.padEnd(8) } ` +
`${'SCORE'.padEnd(8) } `
);
for (const player of this.players) {
console.log(` - ${player.name.padEnd(20)} ` +
`${player.matches.length.toString().padEnd(8) } ` +
`${player.score.toString().padEnd(8) } `
);
}
Result:
Player MATCH SCORE
- Bradly 5 15
- Sam 4 9
- Dew 3 5
EDIT You can add more tabs by using '\t'. Each '\t' means one tab, so in the console.log you can use more console.log(prop + ":\t\t\t" + obj[prop]);
Pass your object to this function (this works for any object):
function printObject(obj)
for(var prop in obj){
if (obj.hasOwnProperty(prop)) {
console.log(prop + ":\t" + obj[prop]);
}
}
You can also get a pretty similar output (but with quotes) by using
JSON.stringify(obj, null, 2);
This will basically print your objects in jason format and will use the last argument (the 2) as the number of separator spaces.
My Javascript / Mootools knowledge is limited, so I am having trouble figuring out how to take the following code and make it produce a sum and assign the value to the ordertotal variable.
$('ordertotal').value = '$' + 100 * $('tickets').value + 10 * $('fiftytickets').value + '.00';
The tickets variable is either 1 or 2 depending on the user selection and the fiftytickets variable is either 0.5, 2.5 or 5.0 depending of the user selection. Both variables are supplied values using a HTML select menu and they function correctly when used individually.
For example:
$('ordertotal').value = '$' + 100 * $('tickets').value + '.00';
Works correctly and
$('ordertotal').value = '$' + 10 * $('fiftytickets').value + '.00';
Works correctly, but I can figure out how to add them together and assign them to the ordertotal variable.
Any assistance with this issue would be greatly appreciated.
Thank you.
Mike
Seems like you are trying to get sum of string + int + int + string
Your two examples worked, because there was only concatenation (string + int(converted to string) + string)
And when you add a nubmer to a "$" - your number get converted to a string. What you can do is to either put numbers sum in () or get the value separately:
sumValue = 100 * $('tickets').value + 10 * $('fiftytickets').value
$('ordertotal').value = '$' + sumValue + '.00';
Example:
> "1" + 1
"11"
> "$" + 1 + ".00"
"$1.00"
> "$" + 1 + 1 + ".00"
"$11.00"
> "$" + (1 + 1) + ".00"
"$2.00"