Last test won't pass on Recreating Lodash Library .inRange()

Project link: https://www.codecademy.com/paths/web-development/tracks/web-dev-js-arrays-loops-objects/modules/pjs-javascript-capstone/projects/lodash

My code is failing one test – #5 (see below)

  inRange(num,start,end) {
    if (end === undefined) {
      end === start && start === 0;
    }
    if (start > end) {
      let temp = end;
      end = start;
      start = temp;
      }
    const isInRange = start <= num && num < end ? true : false;
    return isInRange;
      }
    };

image

I’ve gone back and re-read everything, written down my strategy, and tried to figure out why my boolean is coming back false when it should be true, but somehow I’m not seeing the missing or errant code.

Can someone please offer a hint?

do you know the input for which it fails?
what result do you manually get for that input?
does your program get a different result?
if so, what do you do differently? start observing what your program is doing for that input

you can’t miss it if you’re tracing every single operation. you don’t stare at your code and suddenly find it.
you are however quite likely to miss it if you don’t look.

also, your ternary expression is redundant, you’re saying if you have true, use true, otherwise use false… just use the value you already have

I don’t know. I suspect it has to do with this, but I’m not sure

end = start;

How do I “get a manual result”? Not sure what you mean.

Good advice. How do I do this? Again, I don’t understand what you mean.

well, it says in the test output

do it in your head

you can look at things by printing them.

Hm, so none of that helped. But I appreciate the effort.

Is anyone else available to weigh in please?

there isn’t really a way to fail this. there’s only not doing it
and there’s no alternative route either, if things go wrong and you don’t know where then you find out by observing what’s happening

and if you’re not yet familiar with making observations then that’s something to learn. just about every bug you’ll ever encounter will involve observation

every task you as a human being carry out involves monitoring what you’re doing. when you type text you read what you type, some will look at their keyboard to see if they’re hitting the right buttons or to find those buttons
when you’re cooking you use sound smell and sight to find out how things are coming along

…when you’re programming, you would monitor your program the same way

pretty sure you’re really just saying that you didn’t look and therefore saw nothing. you don’t expect to need to look at the individual actions, so you don’t. but they’re observable, so you can, and if you did, you could pinpoint the problem. so if it’s possible, then that’s probably what you should be doing.

use console.log to print out every single action. you’ll have a log in written english detailing what was done to reach the faulty result. if you read that, you’ll be able to point out where things are wrong.
alternatively, if the log says everything that it should say, then you would have the right answer and it wouldn’t be wrong

Awesome. So that was super helpful. I’ll do that. Thanks.

So I’m using my Chrome browser and webdev tools to try and figure this out, but due to all the console.logs I’ve inserted, I keep running into errors that English but definitely not in a syntax I understand, and now I’m really lost.

Here’s my code as it stands with comments and console.logs

const _ = {
  clamp(number,lower,upper) {
    const lowNum = Math.max(number,lower);
    const clampNum = Math.min(lowNum,upper);
    return clampNum;
  },
//add method called inRange, add 3 params: number, start, end  
  inRange(number,start,end) {
//create if state to check to see if end is undefined
    if (end === undefined) {
//set end equal to start, set start equal to 0
      end === start && start === 0;
    }
console.log(inRange(3,2,4))
//add another if statement to check whether start is bigger than end by swapping the start and end values
    if (start > end) 
console.log(inRange(3,2,4))    
  {
//create var called temp set to current end value (do they really actually mean to set it to the end value???)      
  let temp = end;
console.log(inRange(3,2,4)) 
//set end equal to start      
  end = start;
console.log(inRange(3,2,4)) 
//finally set start equal to temp      
  start = temp;
  }
console.log(inRange(3,2,4)) 
//create var called isInRange, set it equal to a boolean expression that checks if start is smaller than or equal to number and if number is smaller than end
  const isInRange = start <= number && num < end ? true : false;
console.log(inRange(3,2,4)) 
//finally return value of isInRange (again, return VALUE or just return the var???)
  return isInRange;
  }
};

console.log(inRange(3,2,4)) 

And this is the error it’s throwing in the Chrome console:

VM145:37 Uncaught ReferenceError: inRange is not defined
at :37:9

Agree this is technically English, but I don’t speak this version of English. So I’ve researched the error, and the most understandable explanation says

browser throws this error when you are using a variable which is not defined

Okay, so I take that to mean I’ve got a variable that undefined. Fine. For the inRange method I’ve created (and defined? I guess not, but I don’t know what’s undefined and can’t even figure out how step through it since it keeps throwing errors) five variables:

  1. number
  2. start
  3. end
  4. temp
  5. isInRange

Can someone help me identify what’s undefined/how it’s undefined so that the code can be stepped through using the console.logs? Otherwise, I’m totally stuck…okay, I’m totally stuck. And just need a little help.

The only english you’d get printed out is that which you print yourself.
You probably don’t want to call inRange from within inRange

Instead, you might for example print out the arguments you receive at the start.

console.log(`initial arguments: ${number} ${start} ${end}`)

the next thing you do is test whether end is undefined. you could write out the result of that comparison as well.

console.log(`is end undefined? ${end === undefined}`)

after your comparison, you could write out which branch it ended up in.

if (end === undefined) {
    console.log('end is undefined, therefore setting end to start and start to 0')
//set end equal to start, set start equal to 0
      end === start && start === 0;
    }
else {
  console.log('end is defined, not changing the arguments')
}

and then, since you changed the arguments, you’d print them out again to see whether that had the desired effect.

you’d use console.log to write out a description of each thing you carry out, as well as the effect after having done so.

1 Like

I’ve been attempting to evaluate my code in my Chrome console, and now it just keeps throwing syntax errors.

const _ = {
  clamp(number,lower,upper) {
    const lowNum = Math.max(number,lower);
    const clampNum = Math.min(lowNum,upper);
    return clampNum;
  },
//add method called inRange, add 3 params: number, start, end  
  inRange(number,start,end) {
//create if state to check to see if end is undefined
    if (end === undefined) {
//set end equal to start, set start equal to 0
      end === start && start === 0;
    }
//    console.log('this is end ' + end + ' and this is start ' + start);
//add another if statement to check whether start is bigger than end by swapping the start and end values
    if (start > end) {
//create var called temp set to current end value (do they really actually mean to set it to the end value???)      
  let temp = end;
//  console.log('this is end ' + end + ' and this is temp ' + temp) 
//set end equal to start      
  end = start;
//  console.log('this is end ' + end + ' and this is temp ' + temp) 
//finally set start equal to temp      
  start = temp;
  }
// console.log('this is end ' + end + ' and this is temp ' + temp)
//create var called isInRange, set it equal to a boolean expression that checks if start is smaller than or equal to number and if number is smaller than end
  const isInRange = {
    if (start <= number && number < end) {
      return true
    }
//finally return value of isInRange (again, return VALUE or just return the var???)
  return isInRange;
  }
  };

// console.log(inRange(3,2,4))

Here’s the most current error.

if (start <= number && number < end) {
^^
SyntaxError: Unexpected token <=
at createScript (vm.js:53:10)

This had been working, but I changed my code to make it more clear for me because I was told my boolean expression was redundant.

Before: const isInRange = start <= number && num < end ? true : false;
After: const isInRange = { if (start <= number && number < end) { return true }

I’m not sure how to test or observe this code now to even figure out why it’s throwing a syntax error.

Can I get some feedback explaining, in layman’s terms, what will help me get past this? Thanks much.

Let me first explain why the following is redundant.

const isInRange = start <= number && number < end ? true : false;

The expression: start <= number && number < end is going to evaluate to either true or false, so you don’t need the ternary expression at all. If I asked you to go the refrigerator, and choose an apple or an orange, and you came back with an apple, and then I said, “Ok. You want an apple. Go get an apple.” You’d be wondering why you couldn’t just keep the one you already have. Same here. The expression already evaluates to true or false, so you can just assign it instead of adding the redundant step of returning true if it’s true or false if it’s false. So…

//this:
const isInRange = start <= number && number < end;
//is the same as this:
const isInRange = start <= number && number < end ? true : false;
//we can prove this out by printing: (example only - don't add this to your code)
const number = 5;
const start = 2;
const end = 6;
console.log(start <= number && number < end); //prints true
console.log(start <= number && number < end ? true : false); //prints true

As for your initial issue, printing the values involved in each operation before and after the action is carried out is how we find errors in our code. What @ionatan is suggesting is the way it’s done. Some bugs you can find by simply proof reading what you wrote, but when the mistake isn’t immediately obvious, making observations of the actions carried out by printing is pretty much what we have left. Since you’ve been struggling with this one for some time, I’ll point you more directly to the problem.

Consider how you used && in your original ternary expression. && is a logical comparison operator. As such, it will return true or false. In javascript, when we give instructions to the computer, we can’t say do this && do that. We say, do this; do that. When we include && the computer evaluates the truthiness of do this and the truthiness of do that. If they are both truthy the result is true. If either or both are falsy, the result is false. This behavior was illustrated in the example above. In your code, you have the following:

Your comment says what you intended to do, but what does the code you wrote actually do? If you were to have printed the values of end and start both before and after the operation, you’d have seen that the values didn’t change. This is what @ionatan was trying to get you to do, so you could see for yourself that the actions carried out were not the actions that you wanted.

I didn’t know that about this (and other comparison) operator/s. Thanks for explaining that. Helpful to know.

Did I mis-use === as well? Should I be using = instead?

I didn’t understand that “observe” meant to print. I also am not clear on what I should print.

Thank you for this bit of insight. I may be completely mistaken, but I thought I had seen other similar expressions in others’ code written this way that included ? true : false . Also it seems like to me, in coding, it’s important write so that it’s as clear, obvious as possible. Perhaps that’s my misconception. Question: would including this? true : false throw an error? It seems like that test passed (and that is also evident in your response – thank you, by the way for your example – seeing it written out like that for me is immensely helpful), so maybe for my own clarity and understand, I’m curious whether it is okay to write it out like I did, despite it being redundant/unnecessary, when learning? Or is that sort of thing considered verboten even for “students?”

After reading your clear explanation of && I can now understand that my code is likely NOT doing what it’s expected/desired to do. So to “observe” this bit of code

//set end equal to start, set start equal to 0
      end === start && start === 0;

…would I just write something like below, and also, if so, does it go inside the curly brackets, or outside, or does that matter?

console.log("end is supposed to be start and start should be zero, so here is end :" + end + " and her is start " + start + "did my code work as expected?");

Finally, why is it that each time I add the console.log statements to my code and run them in my browser’s console, I get these syntax errors? The code is written correctly and didn’t throw these errors before, so I’m just trying to figure out how to best test/observe and not make it worse. Is there a better way to “print” and observe that I am not aware of? Or is it just that I’m putting console.log expressions in where I’m not supposed to?

Yes.

You can log/print whatever you want. I, personally, would be less verbose. Something like:

    if (end === undefined) {
      console.log(`Before: end is ${end}  start is ${start}`); //debug print
//set end equal to start, set start equal to 0
      end === start && start === 0;
      console.log(`After: end is ${end}  start is ${start}`); //debug print
    }

The important thing is that you can identify where the printed information came from in your code. Once everything is working correctly, you’d then either comment out the console.log statements used for debugging, or just delete them if you’re sure you won’t need them again.

Syntactically, there is nothing wrong with it, but like my picking an apple or orange example shows, it’s redundant. You likely will see it a lot from new coders, and probably even in tutorials as a simplistic example of how to write a ternary expression, or in tutorials simply showing returning true or false in general. It isn’t wrong, it’s just unnecessary, and many new coders don’t realize that the result of a logical comparison can be returned, assigned, printed, etc. without the additional redundant step. Learning this early on is just a plus or benefit if you choose to use it.

I’m not sure about every case where you’ve added console.log statements, but you can only print values that exist in the same scope as the console.log. You can’t print values that the computer has no definition for. This error:

had nothing to do with any console.log statement. It was thrown because the computer was confused by what you were doing:

It starts out looking like you are creating an object (not sure if you’ve gotten to objects yet). Then suddenly there’s an if, and when the interpreter got to <= it gave up, and told you that <= was unexpected. Error messages don’t always show exactly what the problem is. They show how far the interpreter or compiler got before it could no longer continue.

You can pretty much put them everywhere, but you can only print values that exist in the same scope, as mentioned earlier.

2 Likes

Sorry I’m still just a bit confused on something, so just one last point of clarification and I promise I’ll leave you all alone and try to re-tackle exercise.

I was creating a function, but given your feedback, I think I must have missed the mark.

The lesson material instructs

…create a variable called isInRange and set it equal to a boolean expression that checks if start is smaller than or equal to number and if number is smaller than end

My (original) interpretation of this was

const isInRange = start <= number && number < end ? true : false;

Now I’ve learned that the ? true : false part of the statement can be omitted, but now, given the console’s syntax error, I am thinking that I’ve fumbled this expression altogether despite it (seemingly) passing the test in bash. Based on your examples, would printing these statements to the console (like this) help resolve this, or do I need to start from scratch on writing everything that comes after const isInRange = ?

console.log (`Before: end is ${end}  start is ${start} number is ${number}`)
const isInRange = start <= number && number < end
console.log (`After: end is ${end}  start is ${start} number is ${number}`)

If you were to write it as a function, you’d then have to call the function in order to use it. All completely unnecessary. The instruction says create a variable, so that is all you need. What you had first is fine:

const isInRange = start <= number && number < end ? true : false;

Eliminating the redundant part is better:

const isInRange = start <= number && number < end;

In either case, if you wanted to add some debug printing before and after the assignment, you’d probably want to print the result of the assignment after instead of the values that aren’t changed by the assignment:

console.log (`Before: end is ${end}  start is ${start} number is ${number}`); //seeing which values are used in the comparison is a good move
const isInRange = start <= number && number < end; //we haven't changed start, number or end, but we have assigned a value to a new variable
console.log (`isInRange: ${isInRange}`); //so, seeing what that value is is also a good idea
2 Likes