cancel
Showing results for
Show  only  | Search instead for
Did you mean:
New Member

## Using IF statements in Formula Questions

Hello, I'm somewhat new to using Canvas for quizzes and am trying to make a formula question.  Without getting into too many details, the question will provide two variables, x and y.  If 3x < y, the question will have one answer, and if 3x > y, the question will have another.  I was planning to use the IF function to help with this.  There may be a more elegant method, but I was thinking that if 3x < y, the statement could return one value, and if it didn't, it could return another.  However, I cannot seem to find any guides or help on how to use this function, and all my attempts to do it keep giving me errors like "unrecognized token at 8" or "unexpected equals at 5".  Can anyone point me in the right direction?  I've been trying to use the statement if(3x<y,1,0).  I thought that if the first statement were true, it would return 1, and if not, it would return 0.  THANKS!

Tags (3)
3 Solutions
Community Champion

Somewhere, there's a lengthy discussion about using formulas with IF (I probably contributed heavily to it), but I don't remember where, so I'll try a short explanation here and hopefully someone can find the other one if necessary.

The IF() function needs a boolean condition, a true or a false. Mathematically, those are normally 1 and 0, but anything other than 0 is considered true.

You can not use relational operators like < or >.

The logic here gets a little convoluted

• If 3x < y then 3x - y < 0. If 3x > y then 3x - y > 0.
• The signum(x) function, often written as SIGN(x), returns -1 if x < 0, +1 if x > 0, and 0 if x = 0.
• SIGN(3x-y) is -1 when 3x<y, +1 when 3x>y, and 0 when 3x=y
• Both -1 and +1 are considered true
• 1+SIGN(3x-y) is 0 (false) when 3x<y, 2 (true) when 3x>y, and 1 (true) when 3x=y
• SIGN(3x-y)-1 is -2 (true) when 3x<y, 0 (false) when 3x>y, and -1 (true) when 3x=y
• Canvas does not have the SIGN(x) function, so you have to create your own. SIGN(x)=x/ABS(x)
• 1+(3x-y)/ABS(3x-y) is 0 (false) when 3x<y, 2 (true) when 3x>y, and undefined because you get division by 0 when 3x=y
• To avoid division by 0, first check to see if 3x=y or 3x-y=0 (false) or not zero (true).
• Nest the check for less than inside the check for equality

IF(3x-y,IF(1+(3x-y)/ABS(3x-y),do_when_3x>y,do_when_3x<y),do_when_3x=y)

Replace the do_when_ blocks with whatever formula you need.

If you can guarantee that 3x is never y, then you can omit the outside IF() and just use the inner.

IF(1+(3x-y)/ABS(3x-y),do_when_3x>y,do_when_3x<y)

I would include both since it doesn't cost any extra except at the time you generate the question.

New Member

There is a simple way to solve this problem:
To test if A > B just do:

if ( (A-B)+abs(A-B),  {case A > B},  {case A<=B})

No division required.

Jorge Sampaio

Community Participant

@James, I am not sure what you said about < and > is true.  I think it does accept inequalities.  This code worked just fine:

if(x<-10,100,200)

as well as this one:

if(x>=-10,100,200)

Let me know if I am misunderstanding my results.

8 Replies
Community Champion

Somewhere, there's a lengthy discussion about using formulas with IF (I probably contributed heavily to it), but I don't remember where, so I'll try a short explanation here and hopefully someone can find the other one if necessary.

The IF() function needs a boolean condition, a true or a false. Mathematically, those are normally 1 and 0, but anything other than 0 is considered true.

You can not use relational operators like < or >.

The logic here gets a little convoluted

• If 3x < y then 3x - y < 0. If 3x > y then 3x - y > 0.
• The signum(x) function, often written as SIGN(x), returns -1 if x < 0, +1 if x > 0, and 0 if x = 0.
• SIGN(3x-y) is -1 when 3x<y, +1 when 3x>y, and 0 when 3x=y
• Both -1 and +1 are considered true
• 1+SIGN(3x-y) is 0 (false) when 3x<y, 2 (true) when 3x>y, and 1 (true) when 3x=y
• SIGN(3x-y)-1 is -2 (true) when 3x<y, 0 (false) when 3x>y, and -1 (true) when 3x=y
• Canvas does not have the SIGN(x) function, so you have to create your own. SIGN(x)=x/ABS(x)
• 1+(3x-y)/ABS(3x-y) is 0 (false) when 3x<y, 2 (true) when 3x>y, and undefined because you get division by 0 when 3x=y
• To avoid division by 0, first check to see if 3x=y or 3x-y=0 (false) or not zero (true).
• Nest the check for less than inside the check for equality

IF(3x-y,IF(1+(3x-y)/ABS(3x-y),do_when_3x>y,do_when_3x<y),do_when_3x=y)

Replace the do_when_ blocks with whatever formula you need.

If you can guarantee that 3x is never y, then you can omit the outside IF() and just use the inner.

IF(1+(3x-y)/ABS(3x-y),do_when_3x>y,do_when_3x<y)

I would include both since it doesn't cost any extra except at the time you generate the question.

New Member

Awesome!  This is exactly what I needed.  I figured out with some experimentation that it only accepted 0 or not 0 for initial arguments, but I was really at a loss for how to do something with that.  There just didn't seem to be a lot of functions to help.  Your explanation is great and I can now get this to work.  Thank you!

Community Participant

@James, I am not sure what you said about < and > is true.  I think it does accept inequalities.  This code worked just fine:

if(x<-10,100,200)

as well as this one:

if(x>=-10,100,200)

Let me know if I am misunderstanding my results.

Community Champion

Are you using New Quizzes or Classic Quizzes?

With classic quizzes, if you include a < or >, you will get an unrecognized token error at [the zero-based position of the < or > in the string] error.

Community Participant

New.  Thank you for the clarification.

Community Participant

Hi James,

Are you saying the IF function does not support < or > symbols. I have a faculty member wanting to use >+ (greater than or equal) in an equation. DOe sclassic or new quizzes support this symbol?

Thanks,

Linda

Community Member

Currently I am having problems getting sign(x) = 1 + x/abs(x) to work. It seems to be an issue that 0.00000 isn't a boolean 0. And I haven't yet been able to turn it into a boolean 0. It probably has to do with something you noted elsewhere about the set precision working its way into formulas. I need the result to have several decimal places. On the other hand, for some reason checking x + abs(x) is working. All of which is to program up a Canvas-available-function approximation (Odeh and Evans, https://link.springer.com/content/pdf/10.3758/BF03200956.pdf) to the Inverse Normal Distribution:

What is the z-score of the percentile rank `P`?

R = if( (P - 0.5) + abs(P - 0.5), 1-P, P)

Y = sqrt(-2*ln(R))

Z= if((R - 0.5), if( (P - 0.5) + abs(P - 0.5), Y - ((((0.0000453642210148*Y + 0.0204231210245)*Y + 0.342242088547)*Y+1)*Y + 0.322232431088) / ((((0.0038560700634*Y + 0.10353775285)*Y+0.531103462366)*Y +0.588581570495)*Y + 0.099348462606),((((0.0000453642210148*Y + 0.0204231210245)*Y + 0.342242088547)*Y+1)*Y + 0.322232431088) / ((((0.0038560700634*Y + 0.10353775285)*Y+0.531103462366)*Y +0.588581570495)*Y + 0.099348462606) -Y ), 0)

New Member

There is a simple way to solve this problem:
To test if A > B just do:

if ( (A-B)+abs(A-B),  {case A > B},  {case A<=B})

No division required.

Jorge Sampaio