average of five valuesin javascript - javascript

I work for a charter school and I'm just learning my way around javascript. I've got some code written by the person who formerly filled my position and it seems to me that it should work, but it doesn't.
This is what I have in the custom HTML page in my SIS:
GED Status: <script language="Javascript">gedCheck('~(ELC_tspp_GED_read_score)','~ (ELC_tspp_GED_wri_score)','~(ELC_tspp_math_GED_score)','~(ELC_science_state_exam_score)','~(soc_sci_state_exam_score)')</script>
That seems to be retrieving the values from the various DB fields correctly, as the javascript routine is evaluating each value to ensure it's at least 410. But that's as far as it goes...
Here's the javascript routine code:
function gedCheck(read,wri,math,sci,soc) {
if( read < 0 && read > 1000 )
read = 0;
if( wri < 0 && wri > 1000 )
wri = 0;
if( math < 0 && math > 1000 )
math = 0;
if( sci < 0 && read > 1000 )
read = 0;
if( soc < 0 && soc > 1000 )
soc = 0;
if ( (read >= 410) && (wri >= 410) && (math >= 410) && (sci >= 410) && (soc >= 410) ) {
if( read+wri+math+sci+soc >= 2250 )
document.write( "PASSED" )
}
else
document.write( "NOT PASSED" )
}
It is supposed to be checking that every score in the GED tests is at least 410, and that the sum of all scores should be at least 2250. However, it's not getting as far as the last part. It's returning "PASSED" if all the scores are over 410.
I tried this but it, also, doesn't work.
function gedCheck(read,wri,math,sci,soc) {
if( read < 0 && read > 1000 )
read = 0;
if( wri < 0 && wri > 1000 )
wri = 0;
if( math < 0 && math > 1000 )
math = 0;
if( sci < 0 && read > 1000 )
read = 0;
if( soc < 0 && soc > 1000 )
soc = 0;
if ( (read >= 410) && (wri >= 410) && (math >= 410) && (sci >= 410) && (soc >= 410) ) {
if( read+wri+math+sci+soc/5 >= 450 )
document.write( "PASSED" )
}
else
document.write( "NOT PASSED" )
}
Would somebody please help me work this out so it either averages all 5 numbers and returns "PASSED" only if the average is 450, OR simply adds all 5 numbers and returns "PASSED" only if the total sum is 2250 or greater?

To get the average, you'll want to do this:
(((read + wri + math + sci + soc) / 5) > 450)
The parenthesis around the addition ensures that you divide the sum of all scores by 5. The way that you have it now, you are only dividing the soc score by 5.
Edit (Rewriting the entire method):
function gedCheck(read, wri, math, sci, soc) {
// As was said before, these should all be ORs
// If the score is less than 0, OR greater than 1000
if( read < 0 || read > 1000 ) {
read = 0;
}
if( wri < 0 || wri > 1000 ) { // I prefer to put the braces around all if/else statements just for absolute clarity
wri = 0;
}
if( math < 0 || math > 1000 ) {
math = 0;
}
if( sci < 0 || read > 1000 ) {
read = 0;
}
if( soc < 0 || soc > 1000 ) {
soc = 0;
}
if ( read >= 410 && // Doing this will only pass the student
wri >= 410 && // if ALL of the conditions are met.
math >= 410 &&
sci >= 410 &&
soc >= 410 &&
( (read + wri + math + sci + soc) >= 2250 || // Separated more for clarity
((read + wri + math + sci + soc) / 5) > 450) ) {
// Either all scores total over 2250
// Or the average of all 5 are over 450 to pass
document.write( "PASSED" )
}
else
document.write( "NOT PASSED" )
}

What about
if ((read >= 410) &&
(wri >= 410) &&
(math >= 410) &&
(sci >= 410) &&
(soc >= 410) &&
(read+wri+math+sci+soc >= 2250)) {
document.write( "PASSED" )
} else {
document.write( "NOT PASSED" )
}

function gedCheck(read, wri, math, sci, soc) {
if( read < 0 || read > 1000 )
read = 0;
if( wri < 0 || wri > 1000 )
wri = 0;
if( math < 0 && math > 1000 )
math = 0;
if( sci < 0 && read > 1000 )
read = 0;
if( soc < 0 && soc > 1000 )
soc = 0;
var total = read + wri + math + sci + soc;
if (read >= 410 && wri >= 410 && math >= 410 && sci >= 410 && soc >= 410 && total >= 2250) {
document.write("PASSED");
} else {
document.write("NOT PASSED");
}
}
That whole first section was impossible code. It was checking to see if a number was BOTH less than zero and greater than 1000. Obviously impossible, so I changed it to use OR.
I also created a total variable, which you can check in the same way as everything else.

Using an array here will help you reduce the amount of duplicated code
function gedCheck(read, wri, math, sci, soc) {
var subjects, totalScore, averageScore;
subjects = [read, wri, math, sci, soc];
totalScore = 0;
averageScore = 0;
for (var i = 0; i < subjects.length; i++) {
if (subjects[i] < 0 || subjects[i] > 1000) {
subjects[i] = 0;
}
totalScore += subjects[i];
};
averageScore = totalScore / subjects.length;
if (averageScore >= 450 || totalScore >= 2250) {
document.write("PASSED");
} else {
document.write("NOT PASSED");
}
}
The first loop iterates through each subject and sets it to zero if necessary, and then adds it to the total score variable.
Then the total score is averaged by the number of subjects.
Then if the average score is equal to or greater than 450, or equal to or greater than 2250, it passes.

Related

What is the best condition between negative and positive numbers to avoid repeating comparisons?

I would like to make a bunch of comparisons between numbers, both negative and positive and based on that trim the number toFixed decimal points, but I would like to avoid lengthy conditions. Here's a code sample:
if (
(numberValue > 100 && numberValue < 999) ||
(numberValue > -999 && numberValue < -100)
)
scalarNotation = numberValue.toFixed(0);
else if (
(numberValue > 10 && numberValue < 99) ||
(numberValue < -10 && numberValue > -99)
)
scalarNotation = numberValue.toFixed(1);
else if (
(numberValue > 1 && numberValue < 9) ||
(numberValue < -1 && numberValue > -9)
)
scalarNotation = numberValue.toFixed(2);
else if (
(numberValue > 0 && numberValue < 1) ||
(numberValue < 0 && numberValue > -1)
)
scalarNotation = numberValue.toFixed(3);
else if (numberValue > 1000 || numberValue < -1000)
numberValue.toFixed(4);
What is the best way to refactor and perhaps to convert the number to absolute value, add a flag to indicate if the number is positive or negative, and then you can multiply by the modifier at the end?
Here's one way to simplify the problem.
You can store the checks inside an array of objects, where you specify the limit and the number of decimals. Then, test each one on the absolute value, and return the first match:
function test(num){
const abs = Math.abs(num)
const tests = [
{limits: [100, 999], toFixed: 0},
{limits: [10, 99], toFixed: 1},
{limits: [1, 9], toFixed: 2},
{limits: [0, 1], toFixed: 3},
]
let res;
tests.forEach(({ limits, toFixed }) => {
if(!res && abs > limits[0] && abs < limits[1]) {
res = num.toFixed(toFixed)
}
})
return res || num.toFixed(4)
}
console.log(test(0.5))
console.log(test(5))
console.log(test(15))
console.log(test(150))
console.log(test(-150))
console.log(test(1500))
Make simpler and easier
const decimalFn = ( n ) => {
let dec;
n = Math.abs(n)
if(n <= 999) dec = 0
if(n <= 99) dec = 1
if(n <= 9) dec = 2
if(n <= 1) dec = 3
return n.toFixed(dec)
}
console.log( decimalFn(-99) )
console.log( decimalFn(-9) )
console.log( decimalFn(-1) )
console.log( decimalFn(0.5) )
console.log( decimalFn(1) )
console.log( decimalFn(9) )
console.log( decimalFn(99) )
console.log( decimalFn(999) )

how to write a function in javascript that transforms multiple of 3 into a string

This is what I have done so far but how to create the list of numbers and how to put in the loop thank you:
Simply use an Object with arrays in it to return your results.
In addition, you must install the parameters in the loop counter
function mojitor(startOfCount, endOfCount) {
var output = {
menthe : [],
glace : [],
rhum : [],
mentheGlace : [],
mojito : [],
};
for (var x=startOfCount; x <= endOfCount; x++){
if( x % 3 == 0 ){
output.menthe.push(x)
}
if( x % 5 == 0 ){
output.glace.push(x)
}
if( x % 7 == 0 ){
output.rhum.push(x)
}
if( ( x % 3 == 0 ) && ( x % 5 == 0 ) ){
output.mentheGlace.push(x)
}
if( ( x % 3 == 0 ) && ( x % 5 == 0 )&& ( x % 7 == 0 ) ){
output.mojito.push(x)
}
}
return output;
}
var result = mojitor(1, 110);
console.log('Menthe: ' + result.menthe); //"Menthe"
console.log('Glace: ' + result.glace); //"Glace"
console.log('Rhum: ' + result.rhum); //"Rhum"
console.log('MentheGlace: ' + result.mentheGlace); //"MentheGlace"
console.log('Mojito: ' + result.mojito); //"Mojito"
I think you want something like this:
function mojitor(startOfCount, endOfCount) {
var items = [];
for (var x=startOfCount; x <= endOfCount; x++){
if( ( x % 3 == 0 ) && ( x % 5 == 0 )&& ( x % 7 == 0 ) ){
items.push("Mojito");
}
else if( ( x % 3 == 0 ) && ( x % 5 == 0 ) ){
items.push("MentheGlace");
}
else if( ( x % 3 == 0 ) && ( x % 7 == 0 ) ){
items.push("MentheRum");
}
else if( x % 3 == 0 ){
items.push("Menthe");
}
else if( x % 5 == 0 ){
items.push("Glace");
}
else if( x % 7 == 0 ){
items.push("Rhum");
}
else {
items.push(x);
}
}
return items;
}
var numbers = mojitor(1,110);
var line = "";
var j = 0;
for(i = 0; i < numbers.length; i++) {
line += numbers[i] + " ";
j++;
if(j === 11){
console.log(line);
line = "";
j = 0;
}
}
if(line != ""){
console.log(line); //prints the remaining
}

Recursively setting a value depending on range using JavaScript

I don't know how to word this but this is what I'm trying to do:
if (score >= 0 && score <= 10) overallScore = 0;
else if (score >= 11 && score <= 20) overallScore = 1;
else if (score >= 21 && score <= 30) overallScore = 2;
else if (score >= 31 && score <= 40) overallScore = 3;
else if (score >= 91 && score <= 100) overallScore = 9;
...
Is there any way to recursively do this using a function?
overallScore = Math.max(0, Math.floor((score - 1) / 10));
no need for recursion. But if you need that:
const getOverall = score => score <= 10 ? 0 : getOverall(score - 10) + 1;
Recursion is not really appropriate here, since you can get the required value in constant time. Recursion becomes interesting when you need at least O(logn) time.
But as you ask for it, here is one way to make it recursive:
function range(score, depth = 0) {
return score <= 10 || depth >= 9 ? 0 : range(score-10, depth+1) + 1;
}
console.log(range(0)); // 0
console.log(range(10)); // 0
console.log(range(11)); // 1
console.log(range(60)); // 5
console.log(range(91)); // 9
console.log(range(110)); // 9

Javascript: + 1 Limit for Counter/Conditional Statement

In my javascript game i have a function that is called every 0.1 seconds with setInterval:
updateTimerID = setInterval(function(e) {checkProgress();}, 100);
I store a users score in a variable and have a conditional statement inside the checkProgress function which checks when my slider x position falls between 45 - 48:
var score = 0;
function checkProgress(){
if( slider_1.x => 45 && slider_1.x <= 48 ) {
score = score + 1
}
}
I then increase the score variable by one when this happens. The problem i have is i only want the score to be updated by 1 every time, not everytime - so with my function being called every .1 seconds - at the moment my score is adding at least 3 each time
if( slider_1.x => 50 && slider_1.x <= 60 ) {
score ++;
}
Can i limit it to 1 each time?
Something like this maybe?:
var isOver = false;
function checkProgress(){
if( slider_1.x => 45 && slider_1.x <= 48 && !isOver ) {
score = score + 1;
isOver = true;
} else if( slider_1.x < 45 && slider_1.x > 48 ) {
isOver = false;
}
}
you can do that by storing the score update time at a variable than substract it from current time to look for the time passed from last update is greater than 1 second
var score = 0;
var last_update =0;
function checkProgress(){
if( slider_1.x => 45 && slider_1.x <= 48 && ((new Date().getTime()-last_update) > 1000) ) {
score = score + 1
last_update=new Date().getTime();
}
}
Something like this will do the trick
var score = 0;
var inc = true;
function checkProgress(){
if( slider_1.x => 45 && slider_1.x <= 48 ) {
if(inc)
{
score = score + 1
inc = false;
}
}
if(slider_1.x < 45 || slider_1.x > 48)
{
inc = true;
}
}

javascript minesweeper placed unnecessary "1"

i wrote a minesweeper in JavaScript which was working fine for a while, and then randomly on 1 run (i was trying to improve the styling) it gave me this:
note the "1" in the upper-right corner as well as 2 missing 1's two and three spaces below it
here is my function for adding numbers to squares:
function nextToBombCheck(event) {
//reset bomb count
bombCount = 0 ;
//initialize variable for checking nerby boxes
var nextToBox = 0;
//asign the box's id as a number
var boxNum = parseInt(event.id);
var checkSide = 0;
for ( var i = 9 ; i <= 11 ; i++ ) {
nextToBox = boxNum + i;
//check if its a wrap
if ( ( nextToBox%10 === 0 && boxNum%10 === 9 ) || ( nextToBox%10 === 9 && boxNum%10 === 0 ) ) {
continue;
//check boxes below
} else if ( bomb.indexOf( nextToBox ) >= 0 ) {
bombCount++;
}
}
for ( i = -1 ; i <= 1 ; i++ ) {
nextToBox = boxNum + i;
//check if its a wrap (above and below wont work anyway)
if ( ( nextToBox%10 === 0 && boxNum%10 === 9 ) || ( nextToBox%10 === 9 && boxNum%10 === 0 ) ) {
continue;
//check boxes alongside
} else if ( bomb.indexOf( nextToBox ) >= 0 ) {
bombCount++;
}
}
for ( i = -11 ; i <= -9 ; i++ ) {
nextToBox = boxNum + i;
if ( ( nextToBox%10 === 0 && boxNum%10 === 9 ) || ( nextToBox%10 === 9 && boxNum%10 === 0 ) ) {
continue;
//check boxes above
} else if ( bomb.indexOf( nextToBox ) >= 0 ) {
bombCount++;
}
}
//set class(colors) based on bombCount
event.className = classList[ bombCount ];
if ( bombCount !== 0 ) {
//write number of neighboring bombs
event.innerHTML = bombCount;
}
}
my program works on using a table and each td has an id 0-99
heres a link if that helps
Nice game. But you commit the common error of counting the last index. Do you see that your table have size of 11x11 = 121? But in your program you use
var rowAmount = 10;
var columnAmount = 10;
cellAmount = columnAmount * rowAmount;
which is wrong. The for loop also explicitly assume there are 11 column:
for ( i = 0 ; i <= rowAmount ; i++ ) {
gameBox += "<tr>";
for ( var j = 0 ; j <= columnAmount ; j++ ) {
var idValue = i * 10 + j;
gameBox += "<td class = 'box' id = '" + idValue + "' onclick = 'process(this);' ></td>"; }
gameBox += "</tr>";
}
but idValue is using 10 column. It means that your program will ignore the last column. Change that in all your codes and you will be fine.
I believe that the problem is related to the multiple elements with the same id as you can see in the screen shot from Chrome inspector. As you can notice the last cell of the row and the first cell of the next row have the same id. And this is true for all rows.
Instead of using modulo trickery etc, use X and Y coordinates and have a function to get a cell id from given X and Y, that is
function getCellId(x, y) {
return 'cell-' + x + '-' + y);
}
And name your cell id's cell-0-0 -> cell-9-9
Then the neighboring cells are
(x - 1, y - 1)
(x, y - 1)
(x + 1, y - 1)
(x - 1, y )
(x + 1, y )
(x - 1, y + 1)
(x, y + 1)
(x + 1, y + 1)
This problem could have also be avoided, provided that this approach was used.

Categories

Resources