A for loop that does the same as if else statement? - javascript

I have an if else statement, I was wondering if I could change it into a for loop or something similar.
if (lastScroll >= 0 && lastScroll < 40) {
pos = 0;
} else if (lastScroll >= 40 && lastScroll < 80) {
pos = 1;
} else if (lastScroll >= 80 && lastScroll < 120) {
pos = 2;
} else if (lastScroll >= 120 && lastScroll < 160) {
pos = 3;
} else if (lastScroll >= 160 && lastScroll < 200) {
pos = 4;
} else if (lastScroll > 200) {
pos = 5;
}
I want to change this because there could be over 100 positions. I was thinking about creating a for loop like this:
var i = 0;
greater = 0;
less = 40;
for (i = 0; i < 100; i++) {
if (lastScroll >= greater && lastScroll < less) {
pos = i;
greater += 40;
less += 40;
}
}
The if else statement works perfectly but I don't want to create 100 if else statements. This is wrapped in a scroll function.

Because it's linear you can use division and rounding
pos = Math.floor(lastScroll / 40);
if (pos > 5) pos = 5;

You don't need a loop. You can do the following:
if( lastScroll > 200 ) {
pos = 5;
} else if ( lastScroll >= 0 ) {
pos = Math.floor( lastScroll / 40 );
}

If you want, you could potentially scrap everything and use
pos = int(lastscroll / 40);

Related

I want to check the grade of the students marks , based on average

What's wrong with this code? I tried get marks using array and pass the array in to function parameters and calculate the average in that function.
const marks = [100,100,80];
var summ = 0;
function calculateGrade(){
for(let i=0; i<=marks.length;i++){
summ = summ+marks[i];
var avg = (summ/marks.length);
}
if(avg<=59){
console.log('F');
}
else if(avg>=60 && avg<=69){
console.log('D');
}
else if(avg>=70 && avg<=79){
console.log('C');
}
else if(avg>=80 && avg<=89){
console.log('B');
}
else if(avg>=90 && avg<=100){
console.log('A');
}
}
console.log(calculateGrade(marks));
const sum = marks.reduce((partialSum, a) => partialSum + a, 0);
const marks = [100, 100, 80];
var summ = 0;
//issue one (Tmarks were missing )
function calculateGrade(Tmarks) {
// issues 2 ( <= should be < )
for (let i = 0; i < Tmarks.length; i++) {
summ += Tmarks[i];
}
var avg = summ / Tmarks.length;
if (avg <= 59) {
console.log("F");
} else if (avg >= 60 && avg <= 69) {
console.log("D");
} else if (avg >= 70 && avg <= 79) {
console.log("C");
} else if (avg >= 80 && avg <= 89) {
console.log("B");
} else if (avg >= 90 && avg <= 100) {
console.log("A");
}
}
console.log(calculateGrade(marks));
Following were the issues in your code
You were not getting the parameters in function definition
issues 2 ( <= should be < )
You just added an extra = in your for loop
i<=marks.length
instead of
i<marks.length
So while calculating the sum & average, a garbage value gets added up.
You are very close
const marks = [100, 100, 80];
function calculateGrade(marks) {
let summ = 0;
for (let i = 0; i < marks.length; i++) {
summ += marks[i];
}
const avg = summ / marks.length;
let grade = '';
if (avg < 59) {
grade = 'F';
} else if (avg <= 69) {
grade = 'D';
} else if (avg <= 79) {
grade = 'C';
} else if (avg <= 89) {
grade = 'B';
} else {
grade = 'A';
}
return grade;
}
console.log(calculateGrade(marks));
There are couple of mistakes in your code.
1.
for(let i=0; i<=marks.length;i++)
marks.length is 3. Array index starting from 0.
const marks = [100,100,80];
index 0 is 100.
index 1 is 100.
index 2 is 80.
When you add i<=marks.length, this is equals to i<=3.
= in here will run the loop extra circle and this will return NaN because there are only 3 elements in you array and array indexing is 0 based.
2.
for(let i=0; i<=marks.length;i++){
summ = summ+marks[i];
var avg = (summ/marks.length);
}
avg is out of scope. you have defined avg inside the loop and trying to access it outside of the loop. Anything declared in the loop is scoped to that loop and are not available outside the loop.
3.
console.log(calculateGrade(marks));
Your calculateGrade() function is not accepting any parameters. So you can't pass any parameter into this function.
4.
console.log(calculateGrade(marks));
since calculateGrade() function is not returning any value, this will print nothing. So you don't need to call this inside a console.log();.
I have simplified your code as below.
const marksArr = [100, 100, 80];
calculateGrade(marksArr);
function calculateGrade(marks) {
console.log('calling calculateGrade(marks)...');
var avg = (marksArr.reduce(function(a, b) {
return a + b;
}, 0)) / marksArr.length;
console.log('avg is', avg);
if (avg <= 59) {
console.log('Grade', 'F');
} else if (avg >= 60 && avg <= 69) {
console.log('Grade', 'D');
} else if (avg >= 70 && avg <= 79) {
console.log('Grade', 'C');
} else if (avg >= 80 && avg <= 89) {
console.log('Grade', 'B');
} else if (avg >= 90 && avg <= 100) {
console.log('Grade', 'A');
}
}
` calculateGrade(){
let marks = [100,100,80];
let summ = 0;
let avg = 0;
for(let i = 0; i < marks.length; i++){
summ = summ+marks[i];
avg = (summ/marks.length);
}
if(avg<=59){
console.log('F');
}
else if(avg>=60 && avg<=69){
console.log('D');
}
else if(avg>=70 && avg<=79){
console.log('C');
}
else if(avg>=80 && avg<=89){
console.log('B');
}
else if(avg>=90 && avg<=100){
console.log('A');
}
}`
> array start from 0

X Position of a Variable Becoming Negative

I'm having a problem in my code where the initial x and y values (gx and gy) start out as positive, then jump to negative at around the third loop (specifically to coordinates (-8, 12)), then continue on as normal. I've checked multiple times, and there is only one thing that changes the variables. However, it doesn't set them to a negative number. Why does it keep going to that particular point?
Edit: To clarify, the fact that gx and gy become negative isn't the issue so much as the fact that they jump to (-8, 12) after being at (355, 350) for two loops. I'm unclear on why this happens, and have not been able to troubleshoot it yet. Any ideas why it goes to that point?
Also, it may be worth noting that I'm using a web editor called p5.js.
Here is my code:
var ris = 0;
var hyp = 0;
var gx = 355;
var gy = 350;
var count = 1;
var rem = 0
var dir = 0
var xdir = 1
var ydir = 1
var cx = 0
var cy = 0
var xpos = 200;
var ypos = 200;
var moveHoriz = 0;
var moveVert = 0;
function gmove(){
if (gx == xpos){
cx = 1
} else if(gy == ypos){
cy = 1
}
if (cx == 1 && cy == 1){
console.log("this functions");
if ((400 - gx)-(400-xpos) < 0 && (400-gy)-(400-ypos) == 0){
xdir = -1
ydir = 1
} else if ((400 - gx)-(400-xpos) < 0 && (400-gy)-(400-ypos) > 0){
xdir = -1
ydir = -1
} else if ((400 - gx)-(400-xpos) == 0 && (400-gy)-(400-ypos) > 0){
xdir = 1
ydir = -1
} else if ((400 - gx)-(400-xpos) > 0 && (400-gy)-(400-ypos) > 0){
xdir = -1
ydir = -1
} else if ((400 - gx)-(400-xpos) > 0 && (400-gy)-(400-ypos) > 0){
xdir = -1
ydir = 1
print("yeeeee")
} else if ((400 - gx)-(400-xpos) > 0 && (400-gy)-(400-ypos) < 0){
xdir = -1
ydir = -1
print("yeeeeee")
} else if ((400 - gx)-(400-xpos) == 0 && (400-gy)-(400-ypos) < 0){
xdir = 1
ydir = -1
print("yeeeeeee")
} else if ((400 - gx)-(400-xpos) < 0 && (400-gy)-(400-ypos) < 0){
xdir = -1
ydir = -1
print("yeeeeeeee")
}
} else {
ellipse(gx, gy, 20, 20);
ris = (ypos-gy);
run = (xpos-gx);
hyp = pow(ris, 2) + pow(run, 2);
hyp = sqrt(hyp);
stroke(0);
line(gx, gy, xpos, ypos);
console.log(xpos+10, ypos+10, gx-10, gy+10);
hyp = hyp/(100*hyp);
if ((400 - gx)-(400-xpos) > -30 && (400-gx)-(400-xpos) < 30 && (400-ypos)-(400-gy) > -30 && (400-ypos)-(400-gy) < 30){
if(count == 1){
rem = round(gx/400);
count = count + 1;
}
} else {
if(count == 1){
rem = round(gx/400);
count = count + 1;
} else {
gx = xdir*(rem*count);
console.log("math:", ydir*(rem*count))
gy = ydir*(rem*count);
count = count + 1;
ellipse(gx, gy, 20, 20);
console.log(count);
}
}
cx = 0;
cy = 0;
}
}
function setup() {
//this part isn't relevant either
createCanvas(400, 400);
print(gx, gy);
}
//this is a forever loop
function draw() {
background(255);
gmove();
ellipse(xpos, ypos, 20, 20);
}
}
//everything below this point is also irrelevant; it just makes an ellipse move with wasd
function keyPressed(){
if (key == "a") {
moveHoriz = -1;
ellipse(xpos, ypos, 20, 20);
}
if (key == "d") {
moveHoriz = 1;
ellipse(xpos, ypos, 20, 20);
}
if (key == "w"){
moveVert = -1;
ellipse(xpos, ypos, 20, 20);
}
if (key == "s"){
moveVert = 1;
ellipse(xpos, ypos, 20, 20);
}
}
function keyReleased(){
if (key == "d") {
moveHoriz = 0;
}
if (key == "a") {
moveHoriz = 0;
}
if (key == "s"){
moveVert = 0;
}
if (key == "w"){
moveVert = 0;
}
}
Apologies for the length, and thank you for taking the time to look at this!

Problem with Javascript function not returning total sum in a for loop with if conditions

I am writing pure javascript without any HTML and I am having trouble with one of my functions that would need to return the total "course points."
The program consists of prompting the user the # of course taken followed by the grade received which is pushed in the "grades" array. The function calculateCP will allow it to reiterate every element of the array and is suppose to give me the total course points given the following if conditions.
Please help why my function isn't working! The output is returning only the first element of the array, not the total sum of all elements.
calculateCP = () => {
let coursePoints;
let total = 0;
for (let i = 0; i < grades.length; i++) {
if (grades[i] >= 90) {
coursePoints = 4;
} else if (grades[i] >= 80 && grades[i] < 90) {
coursePoints = 3;
} else if (grades[i] >= 70 && grades[i] < 80) {
coursePoints = 2;
} else if (grades[i] >= 60 && grades[i] < 70) {
coursePoints = 1;
} else if (grades[i] < 60) {
coursePoints = 0;
}
return total = total + coursePoints;
}
}
const grades = [];
let noOfCourses = parseInt(prompt("Please enter # of courses taken: "));
console.log("\n")
for (let i = 0; i < noOfCourses; i++) {
grades.push(prompt('Enter grade recieved '));
}
console.log(calculateCP());
}
In the for loop you just want to sum the values.. only once you're done, return the total :) something like this..
calculateCP = () => {
let coursePoints;
let total = 0;
for (let i = 0; i < grades.length; i++) {
if (grades[i] >= 90) {
coursePoints = 4;
} else if (grades[i] >= 80 && grades[i] < 90) {
coursePoints = 3;
} else if (grades[i] >= 70 && grades[i] < 80) {
coursePoints = 2;
} else if (grades[i] >= 60 && grades[i] < 70) {
coursePoints = 1;
} else if (grades[i] < 60) {
coursePoints = 0;
}
total = total + coursePoints;
}
return total;
}
const grades = [];
let noOfCourses = parseInt(prompt("Please enter # of courses taken: "));
console.log("\n")
for (let i = 0; i < noOfCourses; i++) {
grades.push(prompt('Enter grade recieved '));
}
console.log(calculateCP());
}
try to remove the return statement from the for loop and put it right after it..
change this:
return total = total + coursePoints;
to this:
... for loop
total = total + coursePoints;
}
return total;

Check the diagonal neighbors of a node

I'm trying to compare the values of a node. Using the flood-fill algorithm I was able to check vertically and horizontally every node of my grid. Now I have to update my code to check the cells that sit on the diagonal, as in the image below:
In red you have the current node, in yellow are the cells that need to be checked.
Here is a snippet of what I have so far:
var mapWidth = Math.sqrt(mapData.length);
var currentCell = $('[data-x="'+ x +'"][data-y="'+ y +'"]');
if (x < 0 || y < 0 || x > mapWidth || y > mapWidth) {
return;
}
if(mapData[x*mapWidth+y] !== 0 || currentCell.hasClass('cell-grey')) {
if(mapData[x*mapWidth+y] > 0) {
currentCell.addClass('cell-grey').css('opacity', '1');
}
if(mapData[(x-1)*mapWidth+(y-1)] > 0 && mapData[(x-1)*mapWidth+(y-1)] < mapWidth) {
currentCell.addClass('cell-grey').css('opacity', '1');
return;
}
if(mapData[(x-1)*mapWidth+(y+1)] > 0 && mapData[(x-1)*mapWidth+(y+1)] < mapWidth) {
currentCell.addClass('cell-grey').css('opacity', '1');
return;
}
if(mapData[(x+1)*mapWidth+(y-1)] > 0 && mapData[(x+1)*mapWidth+(y-1)] < mapWidth) {
currentCell.addClass('cell-grey').css('opacity', '1');
return;
}
if(mapData[(x+1)*mapWidth+(y+1)] > 0 && mapData[(x+1)*mapWidth+(y+1)] < mapWidth) {
currentCell.addClass('cell-grey').css('opacity', '1');
return;
}
return true;
}
mapWidth is the variable that contains all the cells of the grid, and currentCell is the current node cell. This snippet is not really working for me.
When you evaluate mapData[(x-1)*mapWidth+(y-1)], the values of x-1 and y-1 may cause an out-of-bounds reference, which returns undefined. You have to validate the cell coordinates before accessing the array.
You can iterate over the four diagonal neighbors like this:
for (var neighborX = x - 1; neighborX <= x + 1; neighborX += 2) {
if (neighborX < 0 || neighborX >= mapWidth) {
continue;
}
for (var neighborY = y - 1; neighborY <= y + 1; neighborY += 2) {
if (neighborY < 0 || neighborY >= mapWidth) {
continue;
}
currentCell.addClass('cell-grey').css('opacity', '1');
}
}
I'm not sure exactly what you're trying to accomplish, but it looks like there are other bugs in your code. You probably don't want to return immediately after turning a cell gray, for example. If you want each of the diagonal neighbors to turn gray, the loop above should do the trick.
This line near the beginning of your code contains a subtle error:
if (x < 0 || y < 0 || x > mapWidth || y > mapWidth) {
Valid indices range from 0 through mapWidth - 1, so you should write:
if (x < 0 || y < 0 || x >= mapWidth || y >= mapWidth) {

Is there a more efficient way to implement limitTo in AngularJS based on screen size?

I am trying to set up rows with ng-repeats in them that are limited base don the screen size. I have all the break points set up, and I think in theory I have an idea of how to do this, but my first attempt does not seem to be working. Here's what I'm trying
In the controller I have this to check screen size -
$(window).resize(function(){
var sizeCheck = window.innerWidth
$scope.$apply(function(sizeCheck){
if(sizeCheck >= 2250){
$scope.sizeControl = 6;
}else if(sizeCheck < 2250 && sizeCheck >= 1800){
$scope.sizeControl = 5;
}else if(sizeCheck < 1800 && sizeCheck >= 1600){
$scope.sizeControl = 4;
}else if(sizeCheck < 1600 && sizeCheck >= 1260){
$scope.sizeControl = 3;
}else if(sizeCheck < 1260 && sizeCheck >= 600){
$scope.sizeControl = 2;
}else if(sizeCheck < 600){
$scope.sizeControl = 1;
}
});
});
So in the template I just have :
<div ng-repeat="item in marketItemsTest | filter:searchPrivate | limitTo: sizeControl"
In the top of the controller I have this to check the initial size :
var sizeCheck2 = window.innerWidth
if(sizeCheck2 >= 2250){
$scope.sizeControl = 6;
}else if(sizeCheck2 < 2250 && sizeCheck >= 1800){
$scope.sizeControl = 5;
}else if(sizeCheck2 < 1800 && sizeCheck >= 1600){
$scope.sizeControl = 4;
}else if(sizeCheck2 < 1600 && sizeCheck >= 1260){
$scope.sizeControl = 3;
}else if(sizeCheck2 < 1260 && sizeCheck >= 600){
$scope.sizeControl = 2;
}else if(sizeCheck2 < 600){
$scope.sizeControl = 1;
}
This works ok, but I'm wondering if there a more efficient way in javascript, or angular in general. This function fires every single time the window shifts, and runs all these checks, so I'm thinking there must be a better way to do this.
Would appreciate any input! Thanks for reading.
you can reuse ng-matchmedia module, using which your code would look like
if(matchmedia.isTablet()){
$scope.sizeControl = 6;
}else if(matchmedia.isDesktop()){
$scope.sizeControl = 10;
}else .....
and if you want to make it more efficient, do change only when the size changes rather than on each pixel change, you can use angular-breakpoint which does broadcast an event on size change, you can combine it with the above module and then
$scope.$on('breakpointChange', function(event, breakpoint, oldClass)
{
if(matchmedia.isTablet()){
$scope.sizeControl = 6;
}else if(matchmedia.isDesktop()){
$scope.sizeControl = 10;
}else .....
});
I havent tried to combine those two ng-modules.

Categories

Resources