Convert If-Else statement to Switch Statement - javascript

I recently completed a problem in CodeWars using an if-else statement, but I wanted to retry it and use a switch statement instead. Too bad that it is not working the way that I thought it would!
The problem I am solving is to take in a distance(s) that an Ironman triathlon athlete has completed and return an object that shows a key based on whether the athlete should be Swimming, Biking or Running with a value of the length of the race to go.
My If-Else Solution:
function iTri(s) {
var triLength = 140.60;
var result = {};
var str = ' to go!';
var lengthLeft = (triLength - s).toFixed(2);
if (s === 0) {
return 'Starting Line... Good Luck!';
} else if (s <= 2.4) {
result.Swim = lengthLeft + str;
} else if (s <= 114.4) {
result.Bike = lengthLeft + str;
} else if (s < 130.60) {
result.Run = lengthLeft + str;
} else if (s < 140.60) {
result.Run = 'Nearly there!';
} else {
return 'You\'re done! Stop running!';
}
return result;
}
The (non-working) Switch statement:
function iTri(s){
let tri = (2.4 + 112 + 26.2).toFixed(2);
let left = tri - s;
let str = ' to go!'
let result = {};
switch(s) {
case (s === 0):
return "Starting Line... Good Luck!";
break;
case (s <= 2.4):
result.Swim = left + str;
return result;
break;
case (s <= 114.4):
result.Bike = left + str;
return result;
break;
case (s <= 130.60):
result.Run = left + str;
return result;
break;
case (s < 140.60):
result.Run = 'Nearly there!';
return result;
break;
default:
return 'You\'re done! Stop running!';
}
}
These are the tests:
Test.describe("Example tests",_=>{
Test.assertSimilar(iTri(36),{'Bike':'104.60 to go!'});
Test.assertSimilar(iTri(103.5),{'Bike':'37.10 to go!'});
Test.assertSimilar(iTri(2),{'Swim':'138.60 to go!'});
});
And the Output:
✘ Expected: '{ Bike: \'104.60 to go!\' }', instead got: '\'You\\\'re done! Stop running!\''
✘ Expected: '{ Bike: \'37.10 to go!\' }', instead got: '\'You\\\'re done! Stop running!\''
✘ Expected: '{ Swim: \'138.60 to go!\' }', instead got: '\'You\\\'re done! Stop running!\''
Also is it worth it to convert it to a switch statement? What are benefits/drawbacks of doing it as if/else vs switch?

Is it even worth it to try to convert it to a switch statement?
No. switch is only useful if you have multiple exact matches. This is not the case for you.

If you turn the problem around slightly then you can use a switch like this. Your switch is very close to this already
function iTri(s) {
var triLength = 140.60;
var result = {};
var str = ' to go!';
var lengthLeft = (triLength - s).toFixed(2);
switch(true) {
case s === 0:
return 'Starting Line... Good Luck!';
case s <= 2.4:
result.Swim = lengthLeft + str;
break;
case s <= 114.4:
result.Bike = lengthLeft + str;
break;
case s < 130.60:
result.Run = lengthLeft + str;
break;
case s < 140.60:
result.Run = 'Nearly there!';
break;
default:
return 'You\'re done! Stop running!';
}
return result;
}
console.log(iTri(0));
console.log(iTri(2));
console.log(iTri(50));
console.log(iTri(120));
console.log(iTri(135));
console.log(iTri(145));

Related

How can I disable only the "debugger" keyword in chrome, that gets executed by an eval inside a loop?

I want to disable only the 'debugger' keyword through out the whole debugging process.
I am debugging a script that is obfuscated and that uses an eval to spawn a [VM] which then, this [VM] has a set interval with another eval that also has the debugger keyword, which gets executed quite a few times (my guessing would be at least hundreds of times).
Ways to replicate: Clone https://github.com/krpar/pooky-browser, and from the README use the pooky from week 10. Afterwards, run "node index.js", open devtools and enable breakpoints
What I have in mind: Get chromium source code, edit the 'debugger' keyword so it has no actual purpose.
Why this is not efficient: Compiling takes 13 hours on my machine; I do not exactly know how I will do this; I will use this as a last resort;
I've looked over Chrome how to disable debugger keyword or disable pause and I've seen Wener answer, I am not sure if I can successfully replicate this, because the repository that I've cloned already "injects" pooky.js script into the supremenewyork.com website
I've also tried looking for more answers but they are just desabling all breakpoints or trying to blackbox the script; downsides of this: I tried using 'never stop here' but as it gets executed by an eval, it has no use
This code is from the first [VM] that is spawned
(function() {
(function a() {
var c = new Date().valueOf();
eval(" try { setTimeout(a, 2000); (function b () { debugger; if((R0ggg() - this) > 30) { b.call(R0ggg()); } }).call(R0ggg()); } catch (e) { } ");
if ((new Date().valueOf() < c) || (new Date().valueOf() - c) > 1062) {
var k0gggg = 2;
for (; k0gggg !== 1; ) {
switch (k0gggg) {
case 2:
(function() {
var D3wg = 2;
for (; D3wg !== 7; ) {
switch (D3wg) {
case 3:
return;
break;
case 4:
D3wg = p3wg[t3wg] ? 3 : 9;
break;
case 2:
var X3wg = "u";
X3wg += "n";
X3wg += "d";
X3wg += "e";
X3wg += "f";
X3wg += "i";
X3wg += "n";
X3wg += "e";
X3wg += "d";
var t3wg = "_";
t3wg += "p";
t3wg += "Z";
t3wg += "6";
t3wg += "R";
t3wg += "H";
t3wg += "z";
t3wg += "K";
t3wg += "3";
t3wg += "L";
t3wg += "T";
t3wg += "1";
t3wg += "I";
var p3wg = typeof window !== X3wg ? window : typeof global !== X3wg ? global : this;
D3wg = 4;
break;
case 9:
try {
var J3wg = 2;
for (; J3wg !== 1; ) {
switch (J3wg) {
case 2:
AtCB();
J3wg = 1;
break;
}
}
} catch (S3wg) {}
p3wg[t3wg] = function() {}
;
D3wg = 7;
break;
}
}
}());
k0gggg = 1;
break;
}
}
}
}
)()
}
)();
I expect for my google chrome devtools to not stop at the 'debugger' keyword
This is a pretty hacky idea, but one possibility would be to monkeypatch window.eval which replaces all instances of debugger with nothing before the script runs. In index.js, right above the first addScriptTag call, put:
await page.addScriptTag({content: `
const origEval = window.eval;
window.eval = (str) => {
const replaced = str.replace(/debugger/g, 'undefined');
return origEval(replaced);
};
`});

Javascript/HTML won't enter switch case other than default

My task was to try and code the game of Pig. I am trying to have the code use a switch statement to determine which chunk of code to follow but it is skipping case 1 and case 2 and going directly to the default case. The roll.score is coming from this Javascript file:
function Dice(d1, d2){ //d1 = die 1 d2 = die 2
this.d1 = d1?d1:parseInt(Math.random()*6 + 1);
this.d2 = d2?d2:parseInt(Math.random()*6 + 1);
}
Dice.prototype.score = function(){ //d1 = die 1 d2 = die 2
if(this.d1 == 1 || this.d2 == 1){
return 1; //return score 0 for turn
}else if(this.d1 == 1 && this.d2 == 1){
return 2; //return 13 as code to reset score to 0
}else
return parseInt(this.d1 + this.d2);
}
Dice.prototype.toString = function(){
return "Rolled " + this.d1 + " and " + this.d2;
}
What it is supposed to do is return either 1, 2, or whatever the 2 number added together are. Like I mentioned above, no matter what the roll.score() returns, the switch statement always goes to the default case.
var again = true;
do {
var roll = new Dice(parseInt(Math.random() * 6 + 1), parseInt(Math.random() * 6 + 1));
window.alert(roll.toString());
turnCounter++;
switch (roll.score) {
case 1: // 1 die = 1
playerScore = roll.score();
again = false;
rollCounter++;
turnCounter++;
document.write("Enters case 1");
break;
case 2: //2 = snake eyes
playerTotal = 0;
playerScore = 0;
again = false;
rollCounter++;
turnCounter++;
break;
default:
playerScore += roll.score();
rollCounter++;
displayScore();
document.write(roll.score() + "<br/>");
var rollAgain = window.prompt("Do you want to roll again?(Y/N)");
if (rollAgain.toUpperCase() === "N") {
again = false;
playerTotal += playerScore;
displayScore();
turnCounter++;
if (playerScore > highScore)
highScore = playerScore;
}
break;
}
rollCounter++;
}while (again);
switch (roll.score) { is not the same as switch (roll.score()) {
roll.score is a function, whereas you want to switch on the result on the returned result (roll.score()).

Can someone please tell me why this method did not work for finding palindromes?

Attempting to complete the algorithms on freeCodeCamp. I eventually found an approach that works, but i still don't understand why this method did not work for all cases.
function palindrome(str) {
var alphaNumericStr = str.replace(/\W/g,"");
var lowerCaseAlphaNumericString = alphaNumericStr.toLowerCase();
var arr = lowerCaseAlphaNumericString.split("");
arr.reverse();
var reversedString = arr.join("");
if(str === reversedString){
return true;
}
return false;
}
palindrome("race car");
You're comparing a string which has been stripped of spaces and converted to lowercase to the original string. Replace your conditional with:
if(lowerCaseAlphaNumericString == reversedString){
rethrn true;
}
return false;
Here's a little refactor if you're interested:
// ...
var reversedString = arr.join('');
return lowerCaseAlphaNumericString == reversedString;
demo
This is where you are going wrong if(str === reversedString)
Try this:
if(lowerCaseAlphaNumericString === reversedString) {
return true;
}
return false;
}
There could be another approach. In this approach, the corner cases are handled separately.
function check_Palindrome(input_str){
var astr = input_str.toLowerCase().replace(/\W/g,'');
var acount = 0;
if(astr==="") {
console.log("Not Palindrome.");
return false;
}
if ((astr.length) % 2 === 0) {
acount = (astr.length) / 2;
} else {
if (astr.length === 1) {
console.log("Palindrome.");
return true;
} else {
acount = (astr.length - 1) / 2;
}
}
for (var x = 0; x < acount; x++) {
if (astr[x] != astr.slice(-1-x)[0]) {
console.log("Not Palindrome.");
return false;
}
}
console.log("Palindrome.");
return true;
}

minus 7 hours from 'now' date time datepicker entry

I have 2 datepickers, start and end time.
i want the start time to be minus 7 hours from "now"
i have this:
$('#<%= txtErrorStartDate.ClientID%>').val(formatDateTime(sqlNow('HH', -7), 'dateshorttime')).validate();
and this:
function formatDateTime(d, format, rtnObj) {
var arr
, type
, arrDate
, arrTime
, str
;
if (!d) {
if (rtnObj) {
return null;
} else {
return '';
}
}
switch (format) {
case 'shortdate':
type = 1;
break;
case 'shorttime':
type = 2;
break;
case 'dateshorttime':
type = 3;
break;
case 'datelongtime':
type = 4;
break;
case 'longtime':
type = 5;
break;
default:
if (rtnObj) {
return null;
} else {
return '';
}
}
if (typeof(d) === 'string') {
if (d.indexOf('/Date(') !== -1) {
// JSON date (milliseconds)
d = new Date(Number(d.replace('/Date(', '').replace(')/', '')));
} else {
str = true;
}
} else if (typeof(d) === 'number') {
d = new Date(d);
}
if (str) {
// Format string
d = $.trim(d);
if (d.indexOf(' ') !== -1) {
// Split date and time
arr = d.split(' ');
arrDate = arr[0].split('/');
arrTime = arr[1].split(':');
if (arrTime.length === 2) {
// Add missing seconds
arrTime.push('00');
}
} else if (d.indexOf('/') !== -1) {
// Split date
arrDate = d.split('/');
arrTime = ['00', '00', '00'];
} else {
arrDate = ['30', '12', '1899'];
arrTime = d.split(':');
if (arrTime.length === 2) {
// Add missing seconds
arrTime.push('00');
}
}
} else {
// Format Javascript date object
// Build date array
arrDate = [];
arrDate.push(d.getDate());
arrDate.push(d.getMonth() + 1);
arrDate.push(d.getFullYear());
// Build time array
arrTime = [];
arrTime.push(d.getHours());
arrTime.push(d.getMinutes());
arrTime.push(d.getSeconds());
// Single digit check
if (Number(arrDate[0]) < 10) { arrDate[0] = '0' + arrDate[0]; }
if (Number(arrDate[1]) < 10) { arrDate[1] = '0' + arrDate[1]; }
if (Number(arrTime[0]) < 10) { arrTime[0] = '0' + arrTime[0]; }
if (Number(arrTime[1]) < 10) { arrTime[1] = '0' + arrTime[1]; }
if (Number(arrTime[2]) < 10) { arrTime[2] = '0' + arrTime[2]; }
}
if (rtnObj) {
// Return Javascript object
// Take 1 from month (0 - 11)
arrDate[1] = String(Number(arrDate[1]) - 1);
switch (type) {
case 1: // shortdate
return new Date(arrDate[2], arrDate[1], arrDate[0]);
break;
case 2: // shorttime
return new Date('1899', '11', '30', arrTime[0], arrTime[1]);
break;
case 3: // dateshorttime
return new Date(arrDate[2], arrDate[1], arrDate[0], arrTime[0], arrTime[1]);
break;
case 4: // datelongtime
return new Date(arrDate[2], arrDate[1], arrDate[0], arrTime[0], arrTime[1], arrTime[2]);
break;
case 5: // longtime
return new Date('1899', '11', '30', arrTime[0], arrTime[1], arrTime[2]);
break;
}
} else {
// Return date string
switch (type) {
case 1: // shortdate
return arrDate.join('/');
break;
case 2: // shorttime
arrTime.pop();
return arrTime.join(':');
break;
case 3: // dateshorttime
arrTime.pop();
return arrDate.join('/') + ' ' + arrTime.join(':');
break;
case 4: // datelongtime
return arrDate.join('/') + ' ' + arrTime.join(':');
break;
case 5: // longtime
return arrTime.join(':');
break;
}
}
}
what i have is not working, i would like to know how to subtract 7 hours from the start time
added datepicker html:
<div class="inputrow" runat="server">
<label style="margin-left: 179px" class="inputlabel">Start Date</label>
<input runat="server" type="text" id="txtErrorStartDate" name="txtErrorStartDate1" class="dateshorttime datepick required" value="" data-taborder="1" required="" style="width: 18%" />
</div>
My java knowledge isn't great, but for what its worth, what I would do in C# to accomplish this is:
string startTime = DateTime.Now; // Fire whenever the event starts
string endTime = DateTime.Now; // Fire whenever the event ends
string subtractedTime = currentTime.ToString("HH") - 7; // The time subtracted by 7 hours
var start_time = new Date();
start_time.setHours(start_time.getHours()-7);
i have resolved the issue, with the line of code below.
$('#<%= txtErrorStartDate.ClientID%>').val(formatDateTime(dateAdd('hour', -7, sqlNow()), 'dateshorttime')).validate();
Thank you for your input.

Trying to add and remove items from an array

The script works by asking user for add or remove an item in the array. Then asks to continue this loop. The problem here is that my script doesn't seem to match my user's input (removeItem) to the item in the list (myList[i]). I'm at a lost as to why this is failing to match.
// new method for removing specific items from a list
Array.prototype.remove = function(from,to) {
var rest = this.slice((to || from) + 1 || this.length);
this.length = from < 0 ? this.length + from : from;
return this.push.apply(this, rest);
};
printList = function() {
var listLength = myList.length;
for (i = 0; i < listLength; i++) {
document.write(i + ":");
document.write(myList[i] + "<br/>");
};
document.write("<br/><br/>");
};
// initial list
var myList = new Array ();
if (myList.length === 0) {
document.write("I have " + myList.length + " item in my list. It is: <br/>");
}
else {
document.write("I have " + myList.length + " items in my list. They are: <br/>");
}
printList();
var continueAdding = "yes";
var askToContinue = "";
while (continueAdding === "yes") {
// loop
var askUser = prompt("What do you want to [A]dd or [R]emove an item to your inventory?").toUpperCase();
switch (askUser) {
case "A": { // add an user specified item to the list
var addItem = prompt("Add something to the list");
myList.push(addItem);
printList();
break;
}
case "R": { // remove an user specified item from the list
var removeItem = prompt("what do you want to remove?");
var listLength = myList.length;
for (i = 0; i < listLength; i++) {
if (removeItem === myList[i]) {
document.write("I found your " + removeItem + " and removed it.<br/>");
myList.remove(i);
}
else {
document.write(removeItem + " does not exist in this list.<br/>");
break;
}
if (myList.length === 0) {
myList[0] = "Nada";
}
};
printList();
break;
}
default: {
document.write("That is not a proper choice.");
}
};
askToContinue = prompt("Do you wish to continue? [Y]es or [N]o?").toUpperCase(); // ask to continue
if (askToContinue === "Y") {
continueAdding = "yes";
}
else {
continueAdding = "no";
}
}
Your loop never allows it to loop through all the items, because it breaks on the first iteration if the item doesn't match.
The break statement should be in the if block, not in the else block - use this instead:
for (i = 0; i < listLength; i++) {
if (removeItem === myList[i]) {
document.write("I found your " + removeItem + " and removed it.<br/>");
myList.remove(i);
break;
}
else {
document.write(removeItem + " does not exist in this list.<br/>");
}
};
if (myList.length === 0) {
myList[0] = "Nada";
}
Also, note that it's looking for an exact match, case sensitive, same punctuation, and everything. If you want it to be a little more lenient you'll need to modify the script to convert both strings to lowercase and strip punctuation before comparing them.
Edit: Just noticed something else -- testing for an empty list needs to be done outside the loop. I updated the above code to reflect this.

Categories