I'm writing a function that pushes specific (predefined) variables to predefined arrays based on the status of 4 variables, all of which are ranging from 1 to 5 (they are the results of radio buttons pressed on our web page).
If the variables equal A, B, C and D, the predefined variables to predefined arrays X, Y and Z are defined by:
X = the combination of A and B.
Y = the combination of C and D.
Z = the combination of A, B, C and D.
Below is my realization of a solution to said problem (A, B, C and D are motivation, orientation, influence and relevance), using nested if/else statements. However, I find this solution inelegant. I both want to write cleaner code, and leave the code more readable for my fellow coworkers. What would be the most elegant way to type this out? Should I use functions, switch statements, something else?
Below is the entire function:
function getRadioParameters (influence, relevance, motivation, orientation) {
if (influence >= 3) {
if (relevance >= 3) {
influenceRelevanceArr.push(highInfluenceHighRelevance);
if (motivation >= 3) {
if (orientation >= 3) {
motivationOrientationArr.push(highMotivationHighOrientation);
stkImagesArr.push(getImage('HHHH'));
}
else if (orientation < 3) {
motivationOrientationArr.push(highMotivationLowOrientation);
stkImagesArr.push(getImage('HHHL'));
}
else {
motivationOrientationArr.push('');
stkImagesArr.push('');
console.log('problem with orientation. It is = ', orientation)
}
}
else if (motivation < 3) {
if (orientation >= 3) {
motivationOrientationArr.push(lowMotivationHighOrientation);
stkImagesArr.push(getImage('HHLH'));
}
else if (orientation<3) {
motivationOrientationArr.push(lowMotivationLowOrientation);
stkImagesArr.push(getImage('HHLL'));
}
else {
motivationOrientationArr.push('');
stkImagesArr.push('');
console.log('problem with orientation. It is = ', orientation);
}
}
else {
motivationOrientationArr.push('');
stkImagesArr.push('');
console.log('problem with motivation. It is = ', motivation);
}
}
else if (relevance < 3) {
influenceRelevanceArr.push(highInfluenceLowRelevance);
if (motivation >= 3) {
if (orientation >= 3) {
motivationOrientationArr.push(highMotivationHighOrientation);
stkImagesArr.push(getImage('HLHH'));
}
else if (orientation < 3) {
motivationOrientationArr.push(highMotivationLowOrientation);
stkImagesArr.push(getImage('HLHL'));
}
else {
motivationOrientationArr.push('');
stkImagesArr.push('');
console.log('problem with orientation. It is = ', orientation)
}
}
else if (motivation < 3) {
if (orientation >= 3) {
motivationOrientationArr.push(lowMotivationHighOrientation);
stkImagesArr.push(getImage('HLLH'));
}
else if (orientation<3) {
motivationOrientationArr.push(lowMotivationLowOrientation);
stkImagesArr.push(getImage('HLLL'));
}
else {
motivationOrientationArr.push('');
stkImagesArr.push('');
console.log('problem with orientation. It is = ', orientation);
}
}
else {
motivationOrientationArr.push('');
stkImagesArr.push('');
console.log('problem with motivation. It is = ', motivation);
}
}
else {
influenceRelevanceArr.push('');
motivationOrientationArr.push('');
stkImagesArr.push('');
console.log('problem with relevance. It is =', relevance);
}
}
else if (influence < 3) {
if (relevance >= 3) {
influenceRelevanceArr.push(lowInfluenceHighRelevance);
if (motivation >= 3) {
if (orientation >= 3) {
motivationOrientationArr.push(highMotivationHighOrientation);
stkImagesArr.push(getImage('LHHH'));
}
else if (orientation < 3) {
motivationOrientationArr.push(highMotivationLowOrientation);
stkImagesArr.push(getImage('LHHL'));
}
else {
motivationOrientationArr.push('');
stkImagesArr.push('');
console.log('problem with orientation. It is = ', orientation)
}
}
else if (motivation < 3) {
if (orientation >= 3) {
motivationOrientationArr.push(lowMotivationHighOrientation);
stkImagesArr.push(getImage('LHLH'));
}
else if (orientation<3) {
motivationOrientationArr.push(lowMotivationLowOrientation);
stkImagesArr.push(getImage('LHLL'));
}
else {
motivationOrientationArr.push('');
stkImagesArr.push('');
console.log('problem with orientation. It is = ', orientation);
}
}
else {
motivationOrientationArr.push('');
stkImagesArr.push('');
console.log('problem with motivation. It is = ', motivation);
}
}
else if (relevance < 3) {
influenceRelevanceArr.push(lowInfluenceLowRelevance);
if (motivation >= 3) {
if (orientation >= 3) {
motivationOrientationArr.push(highMotivationHighOrientation);
stkImagesArr.push(getImage('LLHH'));
}
else if (orientation < 3) {
motivationOrientationArr.push(highMotivationLowOrientation);
stkImagesArr.push(getImage('LLHL'));
}
else {
motivationOrientationArr.push('');
stkImagesArr.push('');
console.log('problem with orientation. It is = ', orientation)
}
}
else if (motivation < 3) {
if (orientation >= 3) {
motivationOrientationArr.push(lowMotivationHighOrientation);
stkImagesArr.push(getImage('LLLH'));
}
else if (orientation<3) {
motivationOrientationArr.push(lowMotivationLowOrientation);
stkImagesArr.push(getImage('LLLL'));
}
else {
motivationOrientationArr.push('');
stkImagesArr.push('');
console.log('problem with orientation. It is = ', orientation);
}
}
else {
motivationOrientationArr.push('');
stkImagesArr.push('');
console.log('problem with motivation. It is = ', motivation);
}
}
else {
influenceRelevanceArr.push('');
motivationOrientationArr.push('');
stkImagesArr.push('');
console.log('problem with relevance. It is =', relevance);
}
}
}
Thank you!
Here is an example of abstracting it away using a function:
//X = the combination of A and B.
//Y = the combination of C and D.
//Z = the combination of A, B, C and D.
// in this example:
// A > 5, B > 10, C> 15, D > 20
function returnCharacteristic(input) {
if (input[0] > 5 && input[1] > 10 && input[2] > 15 && input[3] > 20) {
return 'Z';
}
if (input[2] > 15 && input[3] > 20) {
return 'Y';
}
if (input[0] > 5 && input[1] > 10) {
return 'X';
}
return 'No criterea met';
}
let test1 = [10, 5, 33, 5];
let test2 = [10, 15, 32, 50];
let test3 = [20, 20, 10, 9];
let test4 = [0, 5, 50, 50];
console.log(returnCharacteristic(test1));
console.log(returnCharacteristic(test2));
console.log(returnCharacteristic(test3));
console.log(returnCharacteristic(test4));
In this example I used some random conditions to determine if a criteria was met but you of course need to tailor them to your needs. Usually when your code is deeply nested like yours you have made a code designing mistake. Usually there are more elegant solutions which require you to refactor the code a bit.
Deeply nesting code increases the difficulty of reasoning about it which not only makes your code less maintainable but also increases the chances of introducing bugs. And even when there are bugs it is harder to debug is deeply nested code.
Hopefully this was helpful.
If i understand what you're trying to do right, i think you can do something like this
var obj = {
"highInfluence_highRelevance": highInfluenceHighRelevance,
"highInfluence_lowRelevance": highInfluenceLowRelevance,
"lowInfluence_highRelevance": lowInfluenceHighRelevance,
"lowInfluence_lowRelevance": lowInfluenceLowRelevance,
"highMotivation_highOrientation": highMotivationHighOrientation,
"highMotivation_lowOrientation": highMotivationLowOrientation,
"lowMotivation_highOrientation": lowMotivationHighOrientation,
"lowMotivation_lowOrientation": lowMotivationLowOrientation
}
var imgStr = "";
function evaluateRadioParameters(num) {
if (num >= 3) return "high";
else if (num < 3) return "low";
return "";
}
function setimgStr(num, str) {
if (num >= 3) imgStr += "H";
else if (num < 3) imgStr += "L";
else console.log('problem with ' + str + '. It is = ', num);
}
function getRadioParameters(influence, relevance, motivation, orientation) {
var influenceStr = evaluateRadioParameters(influence);
var relevanceStr = evaluateRadioParameters(relevance);
var motivationStr = evaluateRadioParameters(motivation);
var orientationStr = evaluateRadioParameters(orientation);
if (influenceStr == "" || relevanceStr == "") {
influenceRelevanceArr.push("");
} else {
influenceRelevanceArr.push(obj[influenceStr + "Influence_" + relevanceStr + "Relevance"]);
}
if (motivationStr == "" || orientationStr == "") {
motivationOrientationArr.push("");
} else {
motivationOrientationArr.push(obj[influenceStr + "Influence_" + relevanceStr + "Relevance"]);
}
if (influenceStr == "" || relevanceStr == "" || motivationStr == "" || orientationStr == "")
stkImagesArr.push('');
else {
setimgStr(influence, "influence");
setimgStr(relevance, "relevance");
setimgStr(motivation, "motivation");
setimgStr(orientation, "orientation");
stkImagesArr.push(getImage(imgStr));
}
}
It might be easier to get each individual value separately, then combine them somehow - it all depends on your data structures. From what I see so far, I think you can do something like this (this is high level, you'll have to fill in the full details yourself):
function getRadioParameters(influence, relevance, motivation, orientation) {
const inf = gague(influence, 'highInfluence', 'lowInfluence');
const rel = gague(relevance, 'highRelevance', 'lowRelevance');
const mot = gague(motivation, 'highMotivation', 'lowMotivation');
const ori = gague(orientation, 'highOrientation', 'lowOrientation');
const allVals = [inf, rel, mot, ori];
const finalValues = getFinalValues(allVals);
return finalValues;
}
function getFinalValues(allVals) {
const finalValues = { img: '', char: '' };
allVals.forEach(function(item) {
finalValues.img += item.img;
finalValues.char += item.char;
});
return finalValues;
}
function gague(param, high, low) {
if (param >= 3) return { char: high, img: 'H' };
return { char: low, img: 'L' };
}
let result = getRadioParameters(3, 3, 3, 3);
console.log(result);
result = getRadioParameters(3, 3, 3, 0);
console.log(result);
result = getRadioParameters(3, 3, 0, 3);
console.log(result);
result = getRadioParameters(3, 0, 3, 3);
console.log(result);
also, if you're using ES6/7 you can simplify the code even more:
function getRadioParameters(influence, relevance, motivation, orientation) {
const inf = gague(influence, 'HIGH-influence', 'LOW-influence');
const rel = gague(relevance, 'HIGH-relevance', 'LOW-relevance');
const mot = gague(motivation, 'HIGH-motivation', 'LOW-motivation');
const ori = gague(orientation, 'HIGH-orientation', 'LOW-orientation');
const allVals = [inf, rel, mot, ori];
const finalValue = allVals.reduce(getFinalValue, { img: '', char: '' });
return finalValue;
}
function getFinalValue(prev, current) {
const img = prev.img + current.img;
const char = prev.char + ' ' + current.char;
return { img, char };
}
function gague(param, high, low) {
if (param >= 3) return { char: high, img: 'H' };
return { char: low, img: 'L' };
}
let result = getRadioParameters(3, 3, 3, 3);
console.log(result);
result = getRadioParameters(3, 3, 3, 0);
console.log(result);
result = getRadioParameters(3, 3, 0, 3);
console.log(result);
result = getRadioParameters(3, 0, 3, 3);
console.log(result);
Related
I have a string and need to check with and get whether the following strings overlap with the start and end of my target string:
target string: "click on the Run"
search strings: "the Run button to", "code and click on"
Apparently:
"the Run button to" is overlapped at the end of target "click on the Run"
"code and click on" is overlapped at the start of target "click on the Run"
Both, "the Run" and "click on" will be the desired results.
I have come up with a function to check and get the overlapped results for the cases at the start and at the end separately.
Question:
But my code could not be able to get the expected results only if I know how the search string overlapped with the target string in the very first place. And how can I combine the searched results in one go as well?
function findOverlapAtEnd(a, b) {
if (b.length === 2) {
return "";
}
if (a.indexOf(b) >= 0) {
return b;
}
if (a.endsWith(b)) {
return b;
}
return findOverlapAtEnd(a, b.substring(0, b.length - 1));
}
function findOverlapAtStart(a, b) {
if (b.length === 2) {
return "";
}
if (a.indexOf(b) >= 0) {
return b;
}
if (a.startsWith(b)) {
return b;
}
return findOverlapAtStart(a, b.substring(1));
}
console.log(findOverlapAtEnd("click on the Run", "the Run button to"))
console.log(findOverlapAtStart("click on the Run", "code and click on"))
edited:
case in the middle is also considered, e.g.:
target string: "click on the Run"
search strings: "on the"
Return value: "on the"
You may try this
function findOverlapAtEnd(a, b, min) {
if (b.length <= min) {
return '';
}
if (a.indexOf(b) >= 0) {
return b;
}
if (a.endsWith(b)) {
return b;
}
return findOverlapAtEnd(a, b.substring(0, b.length - 1), min);
}
function findOverlapAtStart(a, b, min) {
if (b.length <= min) {
return '';
}
if (a.indexOf(b) >= 0) {
return b;
}
if (a.startsWith(b)) {
return b;
}
return findOverlapAtStart(a, b.substring(1), min);
}
const GetOverlappingSection = (target, search, min) => {
if (target.length < search.length) {
const tmp = target;
target = search;
search = tmp;
}
let overlap1 = findOverlapAtStart(target, search, min);
if (overlap1.length === 0) {
overlap1 = findOverlapAtEnd(target, search, min);
}
return overlap1;
};
const removeEmptyKeyword = overlap => {
let tmpFinaloverlap = [];
overlap.forEach((key, idx) => {
if (!(key.trim().length === 0)) {
tmpFinaloverlap = [...tmpFinaloverlap, key];
}
});
return tmpFinaloverlap;
};
// let overlap = ['click on','the Run']
const GetOverlappingOfKeyowrd1And2 = (keywordSet1, keywordSet2,min) => {
let resultSetoverlap = [];
let tmpresultSetoverlap = [];
keywordSet1.forEach(key =>
keywordSet2.forEach(k2 => {
tmpresultSetoverlap = [
...tmpresultSetoverlap,
GetOverlappingSection(key, k2, min),
];
})
);
// get the resultSetoverlap
tmpresultSetoverlap.forEach(element => {
if (element.length > 0) {
resultSetoverlap = [...resultSetoverlap, element];
}
});
return resultSetoverlap;
};
const min = 2;
//To handle overlapping issue in overlapping set, that casuing
overlap.forEach((key, idx) => {
if (idx < overlap.length - 1) {
for (let i = idx + 1; i < overlap.length; i++) {
console.log(`key: ${key}`);
console.log(`search: ${overlap[i]}`);
let overlapSection = GetOverlappingSection(key, overlap[i], min);
if (overlapSection.length > 0) {
console.log(`overlapSection: ${overlapSection}`);
overlap[idx] = overlap[idx].replace(overlapSection, '');
}
}
}
});
overlap = removeEmptyKeyword(overlap);
console.log(overlap);
overlap.forEach(key => {
keywordSet2 = keywordSet2.map((k1, idx) => {
console.log(`checking overlap keyword:'${key}' in '${k1}'`);
return k1.replace(key, '');
});
});
overlap.forEach(key => {
keywordSet1 = keywordSet1.map((k1, idx) => {
console.log(`checking overlap keyword:'${key}' in '${k1}'`);
return k1.replace(key, '');
});
});
keywordSet2 = removeEmptyKeyword(keywordSet2);
keywordSet1 = removeEmptyKeyword(keywordSet1);
overlap.forEach(key => {
text = text.replace(key, `$#k1k2$&$`);
});
keywordSet1.forEach(key => {
text = text.replace(key, `$#k1$&$`);
});
keywordSet2.forEach(key => {
text = text.replace(key, `$#k2$&$`);
});
console.log(`ResultSetoverlap after processing:${text}`);
Because I need to decompress and I find these logic puzzles fun, here's my solution to the problem...
https://highdex.net/begin_end_overlap.htm
You can view source of the page to see JavaScript code I used. But just in case I ever take that page down, here's the important function...
function GetOverlappingSection(str1, str2, minOverlapLen = 4) {
var work1 = str1;
var work2 = str2;
var w1Len = work1.length;
var w2Len = work2.length;
var resultStr = "";
var foundResult = false;
var workIndex;
if (minOverlapLen < 1) { minOverlapLen = 1; }
else if (minOverlapLen > (w1Len > w2Len ? w2Len : w1Len)) { minOverlapLen = (w1Len > w2Len ? w2Len : w1Len); }
//debugger;
//we have four loops to go through. We trim each string down from each end and see if it matches either end of the other string.
for (var i1f = 0; i1f < w1Len; i1f++) {
workIndex = work2.indexOf(work1);
if (workIndex == 0 || (workIndex != -1 && workIndex == w2Len - work1.length)) {
//we found a match!
foundResult = true;
resultStr = work1;
break;
}
work1 = work1.substr(1);
if (work1.length < minOverlapLen) { break; }
}
if (!foundResult) {
//debugger;
//reset the work vars...
work1 = str1;
for (var i1b = 0; i1b < w1Len; i1b++) {
workIndex = work2.indexOf(work1);
if (workIndex == 0 || (workIndex != -1 && workIndex == w2Len - work1.length)) {
//we found a match!
foundResult = true;
resultStr = work1;
break;
}
work1 = work1.substr(0, work1.length - 1);
if (work1.length < minOverlapLen) { break; }
}
}
if (!foundResult) {
//debugger;
//reset the work vars...
work1 = str1;
for (var i2f = 0; i2f < w2Len; i2f++) {
workIndex = work1.indexOf(work2);
if (workIndex == 0 || (workIndex != -1 && workIndex == w1Len - work2.length)) {
//we found a match!
foundResult = true;
resultStr = work2;
break;
}
work2 = work2.substr(1);
if (work2.length < minOverlapLen) { break; }
}
}
if (!foundResult) {
//debugger;
//reset the work vars...
work2 = str2;
for (var i2b = 0; i2b < w2Len; i2b++) {
workIndex = work1.indexOf(work2);
if (workIndex == 0 || (workIndex != -1 && workIndex == w1Len - work2.length)) {
//we found a match!
foundResult = true;
resultStr = work2;
break;
}
work2 = work2.substr(0, work2.length - 1);
if (work2.length < minOverlapLen) { break; }
}
}
return resultStr;
}
Hopefully that's helpful.
This is a problem where I need to return a number which only appears once in the array while the rest of the elements appear twice. Using binary search I did what I can but I was stuck at the first test case. I don't understand why it's returning undefined when I can log the same. Help me understand what's going on.
function singleNonDuplicate(nums) {
if(nums.length == 1) {
console.log(nums[0]);
return nums[0];
}
if((nums[Math.floor(nums.length/2)] !== nums[Math.floor(nums.length/2) - 1]) && (nums[Math.floor(nums.length/2)] !== nums[Math.floor(nums.length/2) + 1])) {
return nums[Math.floor(nums.length/2)];
}
if(Math.floor(nums.length/2) % 2 == 0) {
if(nums[Math.floor(nums.length/2)] == nums[Math.floor(nums.length/2) - 1]) {
singleNonDuplicate(nums.slice(0, Math.floor(nums.length/2) - 1));
console.log('g');
} else {
singleNonDuplicate(nums.slice(Math.floor(nums.length/2) + 2));
console.log('g');
}
} else {
if(nums[Math.floor(nums.length/2)] == nums[Math.floor(nums.length/2) - 1]) {
console.log(nums.slice(Math.floor(nums.length/2) + 1));
singleNonDuplicate(nums.slice(Math.floor(nums.length/2) + 1));
} else {
console.log('g');
singleNonDuplicate(nums.slice(0, Math.floor(nums.length/2)));
}
}
}
console.log(singleNonDuplicate([1,1,2]));
This might be a little off topic but there is a much better way to do this kind of problem using XOR:
function appearsOnlyOnce(array) {
var single = array[0];
for (var i=1; i<array.length; i++) {
single ^= array[i];
}
return single
}
When you call singleNonDuplicate from within your functio you have to return the result.
function singleNonDuplicate(nums) {
if(nums.length == 1) {
console.log(nums[0]);
return nums[0];
}
if((nums[Math.floor(nums.length/2)] !== nums[Math.floor(nums.length/2) - 1]) && (nums[Math.floor(nums.length/2)] !== nums[Math.floor(nums.length/2) + 1])) {
return nums[Math.floor(nums.length/2)];
}
if(Math.floor(nums.length/2) % 2 == 0) {
if(nums[Math.floor(nums.length/2)] == nums[Math.floor(nums.length/2) - 1]) {
return singleNonDuplicate(nums.slice(0, Math.floor(nums.length/2) - 1));
console.log('g');
} else {
return singleNonDuplicate(nums.slice(Math.floor(nums.length/2) + 2));
console.log('g');
}
} else {
if(nums[Math.floor(nums.length/2)] == nums[Math.floor(nums.length/2) - 1]) {
console.log(nums.slice(Math.floor(nums.length/2) + 1));
return singleNonDuplicate(nums.slice(Math.floor(nums.length/2) + 1));
} else {
console.log('g');
return singleNonDuplicate(nums.slice(0, Math.floor(nums.length/2)));
}
}
}
console.log(singleNonDuplicate([1,1,2]));
I have a function:
function brackets(openStock, closeStock, s) {
if (openStock == 0 && closeStock == 0) {
document.getElementById('demo').innerHTML = s;
}
if (openStock > 0) {
brackets(openStock - 1, closeStock + 1, s + "(");
}
if (closeStock > 0) {
brackets(openStock, closeStock - 1, s + ")");
}
}
It should write the combinations of parenthesizes into a paragraph 'demo' however after writing the first one, the other ones are not written into the paragraph.Since it is a recursive function I don't know how to concatenate the results ( combinations) one after another.
function brackets(openStock, closeStock,s)
{
if (openStock == 0 && closeStock == 0) {
var e = document.createElement('div');
e.innerHTML = s;
while(e.firstChild) {
document.getElementById('demo').appendChild(e.firstChild);
}
}
if (openStock > 0) {
brackets(openStock-1, closeStock+1, s + "(");
}
if (closeStock > 0) {
brackets(openStock, closeStock-1, s + ")");
}
}
Ok, so this is my code:
name: function(gameServer, split) {
// Validation checks
var id = parseInt(split[1]);
if (isNaN(id)) {
console.log("[Console] Please specify a valid player ID!");
return;
}
var name = split.slice(2, split.length).join(' ');
if (typeof name == 'undefined') {
console.log("[Console] Please type a valid name");
return;
}
var premium = "";
if (name.substr(0, 1) == "<") {
// Premium Skin
var n = name.indexOf(">");
if (n != -1) {
premium = '%' + name.substr(1, n - 1);
for (var i in gameServer.skinshortcut) {
if (!gameServer.skinshortcut[i] || !gameServer.skin[i]) {
continue;
}
if (name.substr(1, n - 1) == gameServer.skinshortcut[i]) {
premium = gameServer.skin[i];
break;
}
}
name = name.substr(n + 1);
}
} else if (name.substr(0, 1) == "[") {
// Premium Skin
var n = name.indexOf("]");
if (n != -1) {
premium = ':http://' + name.substr(1, n - 1);
name = name.substr(n + 1);
}
}
and i want to change premium to something like <kraken> and <spy> every second, so that then it changes gameServer.skinshortcut to %kraken and then 1 second later it changes that to %spy... and cycles, How do I do this?
Use setInterval(function, delay in ms)
Try:
Var pre_stat=0;
function tgl_pre()
if (pre_stat=0)
{
pre_stat=1;
//change variable to `kraken`;
}
else
{
pre_stat=0;
//change variable to 'spy';
}
setInterval("tgl_pre()", 1000);
end
In my script to generate a playing card, it's generating a 0, even though my random generator is adding a 1, so it should never be 0. What am I doing wrong?! If you refresh, you'll eventually get a "0 of Hearts/Clubs/Diamonds/Spades":
var theSuit;
var theFace;
var theValue;
var theCard;
// deal a card
function generateCard() {
var randomCard = Math.floor(Math.random()*52+1)+1;
return randomCard;
};
function calculateSuit(card) {
if (card <= 13) {
theSuit = "Hearts";
} else if ((card > 13) && (card <= 26)) {
theSuit = "Clubs";
} else if ((card > 26) && (card <= 39)) {
theSuit = "Diamonds";
} else {
theSuit = "Spades";
};
return theSuit;
};
function calculateFaceAndValue(card) {
if (card%13 === 1) {
theFace = "Ace";
theValue = 11;
} else if (card%13 === 13) {
theFace = "King";
theValue = 10;
} else if (card%13 === 12) {
theFace = "Queen";
theValue = 10;
} else if (card%13 === 11) {
theFace = "Jack";
theValue = 10;
} else {
theFace = card%13;
theValue = card%13;
};
return theFace;
return theValue
};
function getCard() {
var randomCard = generateCard();
var theCard = calculateFaceAndValue(randomCard);
var theSuit = calculateSuit(randomCard);
return theCard + " of " + theSuit + " (this card's value is " + theValue + ")";
};
// begin play
var myCard = getCard();
document.write(myCard);`
This line is problematic:
} else if (card%13 === 13) {
Think about it: how a remainder of division to 13 might be equal to 13? ) It may be equal to zero (and that's what happens when you get '0 of... '), but will never be greater than 12 - by the very defition of remainder operation. )
Btw, +1 in generateCard() is not necessary: the 0..51 still give you the same range of cards as 1..52, I suppose.
card%13 === 13
This will evaluate to 0 if card is 13. a % n will never be n. I think you meant:
card % 13 === 0
return theFace;
return theValue
return exits the function; you'll never get to the second statement.