I am trying to create a simple code which splits a string at ',' . The expected string is a list of numbers separated by commas. I have to print the sum of those numbers. My code is here:
function add(numbers) {
if (numbers === "")
{
return 0;
}
else if (typeof parseInt(numbers) == 'number')
{
return parseInt(numbers);
}
else
{
let numArray = numbers.toString().split(',');
console.log(numArray);
let value = numArray.every(checkElement);
if (value) {
return (getSum(numArray));
}
else
{
return "Error in formatting";
}
}
}
function checkElement(element)
{
return (typeof parseInt(element) == 'number')
}
function getSum(numArray)
{
let total = 0;
for (let i = 0; i < numArray.length; i++)
{
total += numArray[i];
}
return total
}
module.exports = add
My Jest code is:
const add = require('../sum.js')
test('Returns sum of numbers', () => {
expect (
add("225,75")
).toBe(300)
})
I am getting this error:
● Returns sum of numbers
expect(received).toBe(expected) // Object.is equality
Expected: 300
Received: 225
17 | add("225,75")
> 18 | ).toBe(300)
| ^
19 | })
at Object.toBe (js/Testing/sum.test.js:18:7)
Moreover, my VS Code is not printing any console.log if I try to run the my js file using node filename.js command. It just starts a new terminal line. Not sure what's going wrong. The error looks like split() isn't working properly - it's only ever returning the 1st element (don't understand why) and VS Code won't print my console logs to check where it is stuck.
instead of typeof parseInt(numbers) ,
you should have done
typeof numbers
as even typeof NaN is also a number and thus wrong result.
My process of checking the typeof parseInt("some possible not number") itself is faulty. As parsing anything to int produces a number, I should have checked with isNaN instead. I think we can close off this question. It certainly did help in enhancing my knowledge of small things like parseInt's actions.
The issue is with the attempt to handle the case of "just one number" in a special way. It turns out the result of parseInt("") is always of type "number". So, the answer is:
Scrap the special case and all will be well.
Related
So I'm new to Javascript, just finished a small free online crash course that covers the bare bones basics but I'm still pretty clueless.
Found TwilioQuest that takes problems and gets the player to solve them in a game format.
One issue has me at the mercy of the same 11 lines of code.
The task is write a script that will take two command line arguments - a pair of strings that should be compared to see which one comes first alphabetically (letter casing is not important). The script should determine if the first string is before, after, or in the same position (equal) to the second string, alphabetically. For each case, you should print out a number with console.log.
When the first argument is earlier in the alphabet than the second, your script should print -1.
When the first argument is the same as the second, your script should print 0.
When the first argument is later in the alphabet than the second, your function should print 1.
This is what I have right now and I'm being told that its false or that it doesn't work
const firstValue = process.argv[2];
const secondValue = process.argv[3];
if ((firstValue.toLowerCase() < secondValue.toLowerCase())) {
console.log(-1)
};
if ((firstValue > secondValue)) {
console.log(1);
};
if ((firstValue.ignoreCase == secondValue.ignoreCase)) {
console.log(0);
};
I have tried nesting the conditional operator and I'm still told its wrong
You're only doing the case-insensitive comparison in the first condition. toLowerCase() doesn't modify the string, so you need to do it in all the comparisons.
But it's easier if you do it once when assigning the variables.
const firstValue = process.argv[2].toLowerCase();
const secondValue = process.argv[3].toLowerCase();
if (firstValue < secondValue) {
console.log(-1);
} else if (firstValue == secondValue) {
console.log(0);
} else {
console.log(1);
}
When you have a series of mutually exclusive tests, you should use else if and else so it doesn't perform unnecessary tests.
you can use charCodeAt() it provides the ascii value of a string character
const firstValue = process.argv[2];
const secondValue = process.argv[3];
firstValue.toLowerCase()
secondValue.toLowerCase()
if ((firstValue.charCodeAt(0) < secondValue.charCodeAt(0))) {
console.log(-1)
};
if ((firstValue.charCodeAt(0) > secondValue.charCodeAt(0))) {
console.log(1);
};
if ((firstValue.charCodeAt(0) == secondValue.charCodeAt(0))) {
console.log(0);
};
hope this solves your problem
A group of me and two other people are working to make a Jeopardy game (themed around United States History questions) all in JavaScript. For our final Jeopardy screen, the two teams will each bet a certain amount of money. To prevent a team from typing in random letters for a bet (i.e typing in "hasdfhgasf" instead of an actual amount), we're trying to write an 'onEvent' command that checks to see if a bet is null. If that bet is null, then the code should come up with a message on the screen that tells them to check their bets again.
We tried using statements like, if "null" or if " " but neither of these statements works. We've worked with using getNumber and getText commands, along with just regular variable comparisons with or booleans. So far, we haven't had any luck with these methods.
Here's the group of code we're having issues with:
onEvent("finalJeopardyBetSubmit", "click", function() {
team1Bet = getNumber("team1BetInput");
team2Bet = getNumber("team2BetInput");
console.log(team1Bet);
console.log(team2Bet);
if (getText("team1BetInput") == "" || getText("team2BetInput") == "") {
console.log("Check bet!");
finalJeopardyError();
} else if ((getText("team1BetInput") != 0 || getText("team2BetInput") != 0)) {
console.log("Check bet!");
finalJeopardyError();
} else if ((getNumber("team1BetInput") < 0 || getNumber("team2BetInput") < 0)) {
console.log("Check bet!");
finalJeopardyError();
} else if ((getNumber("team1BetInput") > team1Money || getNumber("team2BetInput") > team2Money)) {
console.log("Check bet!");
finalJeopardyError();
} else {
console.log("Done");
}
});
You can also check out the whole program on Code.org if you'd like to get a better look.
We expect that with the console.log commands, it should say "check bet" if the bets return as null. Instead, the code has ended up fine, and not displaying our error message, even if we type in nothing or just random letters.
a null variable will evaluate to false. Try:
if(variable){
// variable not null
}else{
// variable null
}
Convert the value to a Number first using Number(value) and then check for falsy values using the logical not ! operator. If they enter alphabetic characters, then calling Number('abc') results in NaN.
If a value can be converted to true, the value is so-called truthy. If
a value can be converted to false, the value is so-called falsy.
Examples of expressions that can be converted to false are:
null; NaN; 0; empty string ("" or '' or ``); undefined.
The ! will change any of the falsy values above to true, so you can check for all of them with just the first if statement below.
onEvent("finalJeopardyBetSubmit", "click", function() {
// Convert these values to numbers first
var team1Bet = Number(getNumber("team1BetInput"));
var team2Bet = Number(getNumber("team2BetInput"));
if (!team1Bet || !team2Bet) {
// Handle invalid number error
}
else if (team1Bet < 0 || team2Bet < 0) {
// Handle invalid range error
}
else if (team1Bet > team1Money || team2Bet > team2Money) {
// Handle insufficient funds error
}
else {
// Finish game
}
})
You can read more about the logical operators here.
I am wondering why the following works:
oldversion = "1.3.52";
newversion = "1.3.54";
if (newversion > oldversion) {
console.log('test');
}
but this does not:
if (1.3.54 > 1.3.52) {
console.log('test');
}
I know that the last example won't work because they are not actual numbers. But I am trying to find out what JavaScript is doing when it encounters a string with a number in it.
This is what I found on W3Schools' JavaScript Comparison and Logical Operators page:
When comparing a string with a number, JavaScript will convert the
string to a number when doing the comparison.
So how come it converts the string to a number and suddenly I am not getting an Uncaught SyntaxError: Unexpected number anymore?
You could use a function which iterates the segments.
function checkVersion(a, b) {
var aa = a.split('.').map(Number),
bb = b.split('.').map(Number),
i,
r = 0,
l = Math.max(aa.length, bb.length);
for (i = 0; !r && i < l; i++) {
r = (aa[i] || 0) - (bb[i] || 0);
}
return r;
}
var oldversion = "1.3.52",
newversion = "1.3.54";
if (checkVersion(newversion, oldversion) > 0) {
console.log('test');
}
As mentioned in the comments, it's actually doing a string compare and not trying to turn anything into numbers.
You can verify this by trying:
var a = "a";
var b = "b";
console.log(a>b) // gives false
var a = "a";
var b = "b";
console.log(b>a) // gives true
As you say, when you compare a number and a string, the string gets transformed into a number. However, if the string contains an invalid number, the result will be NaN. This is funny due to the fact that:
NaN > 15 === false
NaN < 15 === false
So:
"1.3.52" > 1.4 === false
"1.3.52" < 1.4 === false
Obviously (and as you said in your post), comparing 1.3.52 with 1.3.54 will throw an exception because they're not valid numbers.
Why "1.3.52" is interpreted bigger than '1.12.10'?
Strings are compared using Unicode code point order. For example, "Banana" comes before "cherry". "9" is bigger than "80", but because "80" comes before "9" in Unicode order. Thus, "1.3.52" is interpreted as bigger than '1.12.10'.
An easy way to find out order between strings and not getting tricked is using sort. For instance, ["1.3.52", "1.12.10", "1.11.0.0.0"].sort()
#Nina's solution should be the accepted answer, as it will be easier to understand I think. But anyway..
function versionGreaterEqual(newversion, oldversion) {
var ov = oldversion.split('.').map(Number), //credit Nina :)
nv = newversion.split('.').map(Number);
return nv.reduce(function (a,b,i){
return a+=b>=ov[i];
},0)===nv.length;
}
console.log(versionGreaterEqual("1.3.54", "1.3.52")); //true
console.log(versionGreaterEqual("1.3.54", "1.13.52")); //false
Thanks to some of the answers on this site, I built a function to validate an integer inside a prompt in javascript. I found out how to use isNaN and the result of % in order to meet my needs, but there must be something wrong, because is still not working: This function for validation needs to accept only integers, and as extra bonus, it will also accept a special keyword used for a different purpose later on in the program.
So, previously I had defined:
var value = prompt("Type an integer");
So after that, I made a call for the validation function, and that included three conditions: The validation warning would jump if:
1) The string is not a number
2) The string % 1 is not 0 (means is not an integer)
3) The string is not the special keyword ("extra") which is also valid as input.
The function needs to loop and keep showing the prompt until a valid data is written.
while (isNaN(value) == true && value % 1 != 0 && value != "extra") {
alert("Please, type an integer");
var value = prompt("Type an integer");
}
What am I doing wrong? Thank you so much for any ideas. I know the integer validation has been asked many times here, and here I got a few ideas, but I might be missing something...
You might be complicating things too much... A quick regular expression will do the trick.
while (!/^(\d+|extra)$/i.test(value)) {
...
}
You typed only one equal at
isNaN(value) = true
jsFiddle example
var int = 10;
var str = "10";
var isInt = function(value) {
return (str === 'extra' || !isNaN(parseInt(value, 16)) || /^\d+$/.test(value));
};
var isIntStrict = function(value) {
return (isInt(value) && typeof value !== 'string');
}
console.log('false', isInt('kirk'));
console.log('true', isInt(int));
console.log('true', isInt(str));
console.log('true', 'strict - int', isIntStrict(int));
console.log('false','strict - string', isIntStrict(str));
console.log('false','strict - string', isIntStrict('0x04'));
console.log('true','strict - string', isIntStrict(0x04));
I assume that for your purposes #elclanrs' answer is all you need here, and is the simplest and most straightforward, but just for completeness and dubious laughs, I'm pretty sure that the following would also do what you're looking for:
function isAnIntOrExtra(v) {
if (parseInt(+v) === +v && v !== '') {
return parseInt(+v);
}
else if (v === 'extra') {
return v;
}
else {
return false;
}
}
Fiddle here
These should all pass and return an integer in decimal notation:
'387' returns 387
'-4' returns -4
'0' returns 0
'2.4e3' returns 2400
'0xf4' returns 244
while these should all fail:
'4.5' returns false
'2.4e-3' returns false
'0xgc' returns false
'' returns false
'seven' returns false
And the magic-word 'extra' returns 'extra'
Of course, it'll "fail" miserably with values like '1,345', and will probably roll right over octal notation, treating it as though it were decimal notation (depending on the JavaScript engine?), but it could be tweaked to handle those situations as well, but really, you're better off with the regex.
I have the following function:
var checkNameLenght = function(name,nameLenght,allowedLenght,defaultName) {
var result;
if(!(nameLenght <= allowedLenght) || !(/[^a-z]/i.test(name))) {
result = name;
}
else {
if(opts.debug == true) {
console.log(name+' is to long or contains special characters / numbers | Please choose a name shorter than '+allowedLenght+' characters or remove any character / number');
}
result = defaultName;
}
return result;
}
I use it to check the length of a string ( in my case the value of an input ) and if it contains any special characters or numbers.
I use it like so:
var input = 'Somevalue';
checkNameLenght(input ,input.length,16,'Username');
The only thing is that if the input string contains some of the above conditions than the console will output the message twice.
Why is that happening ?
I have tested it and it works just fine. Are you sure you are not calling the function twice?
And try to avoid whatever opts.debug does, just use plain old js with if(console)