This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
mbrmc's profile picture

Multiple "ors" don't work?

Started by mbrmc, 19 July 2013 - 01:07 PM
mbrmc #1
Posted 19 July 2013 - 03:07 PM
Title: Multiple "ors" don't work?

I'm very new to Computer Craft and programming in general and I'm really enjoying it. I decided to make a simple, little test program in which questions are asked by the computer and you don't proceed with the "game" unless you enter the correct answer.
I want there to be more than one acceptable answers, so I tried having the code look for "answerA or answerB or answerC" as shown in the code below:

--Function(s)

function riddle(question, answerA, answerB, answerC, extraText)
  local ans = ""
  print(question)
  term.write("Answer: ")
  ans = read()
    if ans ~= answerA or answerB or answerC then
	  textutils.slowPrint("Wrong! Try Again!")
	  return false
    else
	  textutils.slowPrint("Correct!".. x)
	  return true
    end
end
 
--Main Program

textutils.slowPrint("Welcome to the Riddle 'Challenge'!!!")
textutils.slowPrint("Question #1: ")
while not riddle("What color is an apple?", "red", "green", "yellow", " Next Question...") do
end
textutils.slowPrint("Question 2: ")
while not riddle("What part of your body do you smell with?", "nose", "Nose", "Nose.", " Next Question...") do
end
textutils.slowPrint("Question 3: ")
while not riddle("What planet are you on right now?", "earth", "Earth", "Earth.", "") do
end
textutils.slowPrint("Congratulations! You are a 'genius'!")

However, when I have the code set up like this, it doesn't even accept any answers at all! I think it may be a problem regarding the multiple ors I wrote in the function, but I'm not sure. I would be grateful if someone could tell me exactly why my program doesn't accept any of the three possible answers when the questions are asked.
Thanks! (and tell me if I used too many "textutils.slowPrint"s :P/>)
bjornir90 #2
Posted 19 July 2013 - 03:37 PM
You need to do like this :

If asnwer == "random string" or answer == "other string" then
H4X0RZ #3
Posted 19 July 2013 - 04:34 PM
You need to do like this :

If asnwer == "random string" or answer == "other string" then
You have written asnwer ŁØŁ
ittle bit smaler:

if answer == (answer1 or answer2 or answer3) then
  --Do something
end
PixelToast #4
Posted 19 July 2013 - 04:47 PM
Freack100: that is invalid syntax, actually learn lua before posting please

the problem is here:
if ans ~= answerA or answerB or answerC then
this is how you do it

if ans~=answerA and ans~=answerB and ans~=answerC then
H4X0RZ #5
Posted 19 July 2013 - 04:52 PM
Freack100: that is invalid syntax, actually learn lua before posting please

the problem is here:
if ans ~= answerA or answerB or answerC then
this is how you do it

if ans~=answerA and ans~=answerB and ans~=answerC then
Really?
I've used a snipped like this sometimes in my programs and it works…

And I know lua -_-/>
PixelToast #6
Posted 19 July 2013 - 05:00 PM

Spoiler
do i need to direct you to the tutorial on the OR operator?

"a" or "b" = "a"
false or "a" = "a"
"a" or false = "a"
false or false = false

these will apply no matter what you do
theoriginalbit #7
Posted 19 July 2013 - 05:15 PM
Freack100: that is invalid syntax, actually learn lua before posting please
The syntax isn't what is wrong here. The syntax is fine, if it wasn't the code wouldn't even compile (assuming all the `answer`s, are variables and not meant to be strings) the actual problem with the help he was providing is a logical error as it evaluates the brackets down to a single value and then the conditional based on that value. *sarcastic tone* So a table flip back to you sir as you also got it wrong.


I've used a snipped like this sometimes in my programs and it works…
Chances are you're doing something like this

local var = "hello"
print( var == ("hello" or "Hello" or "Hi") )
which in that case it would be fine as the value returned from the brackets is "hello" and "hello" does equal "hello".
Some explanation to help.
SpoilerIn Lua any nil or false value is evaluated to be false in a conditional
Similarly any other value or true is evaluated to be true

Knowing this, given this conditional

if str == ( "hello" or "world" ) then

we actually have

if str == ( true or true ) then

now knowing how boolean logic works… (like so)
OR

true OR true = true
true OR false = true
false OR true  = true
false OR false = false

we can see that whenever the conditional is being evaluated, and we get a true value, there is no point checking the rest of the conditionals (assuming there is no AND's or it being NOT'd) as nothing could ever change that true to false.

knowing this, now we see that, since the first string "hello" is evaluated and becomes true the second string, "world", never needs to be evaluated because Lua doesn't care what it is, nothing will be able to change that true because we do not have an AND anywhere in the conditional, and it is not being inverted with a NOT.

So effectively our conditional always becomes

if str == "hello" then

Knowing the above knowledge we can also understand how Lua's ternary-ish operator works.

<conditional> and <if true=""> or <if false="">
however obviously the `if true` value could not be nil or false otherwise the `if false` value will always be returned…
</if></if></conditional>
H4X0RZ #8
Posted 19 July 2013 - 05:23 PM

Spoiler
do i need to direct you to the tutorial on the OR operator?

"a" or "b" = "a"
false or "a" = "a"
"a" or false = "a"
false or false = false

these will apply no matter what you do
You'r first a in the first picture is in parantheses. Thats wrong.

You can't say that the string "a" is equal to "b" :P/>
mbrmc #9
Posted 19 July 2013 - 05:53 PM
Thanks guys! I was able to fix my problem. This worked:

the problem is here:
if ans ~= answerA or answerB or answerC then
this is how you do it

if ans~=answerA and ans~=answerB and ans~=answerC then

So I guess it doesn't work to have something like, "if variable ~= this or that", but the variable has to be re-written like "if variable ~= this and/or variable ~= that".
albrat #10
Posted 19 July 2013 - 07:49 PM
- snip -

So I guess it doesn't work to have something like, "if variable ~= this or that", but the variable has to be re-written like "if variable ~= this and/or variable ~= that".

with if statements when checking multiple values to a single varible… you have to declare the varible Every time. (lua will not assume you mean to check a single varible against a value.)

so in the case of your origional check… if ans~= answerA or answerB or answerC then… would return "ans Not Equal to answerA OR is answerB a true value? or is answerC a true value? (applying no operators to the statement of a varible defaults to "is it boolean true or false" ) This is why we have to use the varible and operator on each value check.
http://lua-users.org/wiki/ExpressionsTutorial
or

The or binary operator also does not necessarily return a boolean value (see notes for and above). If the first argument is not false or nil it is returned, otherwise the second argument is returned. So, a boolean is only returned if the first argument is true or the second argument is a boolean.

and

The binary operator and does not necessarily return a boolean value true or false to the logical expression x and y. In some languages the and operator returns a boolean dependent on the two inputs. Rather in Lua, it returns the first argument if its value is false or nil, and the second argument if the first argument is not false or nil. So, a boolean is only returned if the first argument is false or the second argument is a boolean.

I guess that confirms what I said about the comparison of a answerA == ans or answerB ~= ans. lol (answerB ~= ans will return a boolean true if the answer is wrong which then passes it on to the third check) and ans ~= answerC which is also a boolean response.. so
if ans ~= answerA or ans ~= answerB or ans ~= answerC then
is functional code that gives the answer you require.

if ans == (answer1 or answer2 or answer3) then
The above code would respond to only if ans == all 3 possible answers at once… (in this case it would always return false unless the answer1 was right, either that or just always return false…)
But… it is also valid code. Just not functional code.
Cranium #11
Posted 19 July 2013 - 07:56 PM
The real fun comes when you start learning ternary operations.

local variable = condition and true_value or false_value
It's really helpful when trying to shorten really long if/else/elseif statements.
Pharap #12
Posted 21 July 2013 - 12:05 PM
Freack100: that is invalid syntax, actually learn lua before posting please

the problem is here:
if ans ~= answerA or answerB or answerC then
this is how you do it

if ans~=answerA and ans~=answerB and ans~=answerC then
Really?
I've used a snipped like this sometimes in my programs and it works…

You were probably using boolean values.

In any language, or and and on boolean values will follow the basic boolean logic tables.
However, in no known language will a == (b or c) be the same as (a == b or a == c).
In the expression (a == b or a == c), the boolean values of a == b and a == c will be equated first, then those two boolean values will be logically or-ed following the boolean logic table.
In the expression a == (b or c), the or operator is applied to the values of b and c, and the result of that operation is tested with a. Because of the way 'or' gets compiled in lua, that means that if b and c aren't booleans, they are evaluated depending on whether either of the values are nil.
Thus in a == (b or c), if b isn't nil, a is tested with b so the expression boils down to a == b. If b is nil, a is tested with c instead, so the expression is the same as a == c.
Because of this a == (b or c) will give a different result to a == (c or b ) providing b and c aren't booleans.
Thus:

local a = "a";
local b = "b";
local c = "a";
print(a == (b or c)); --prints false
print(a == (c or B)/>/>/>); --prints true
However:

local a = true;
local b = true;
local c = false;
print(a == (b or c)); --prints true
print(a == (c or B)/>/>/>); --prints true

Which is why you have experienced such statements sometimes working.
MudkipTheEpic #13
Posted 21 July 2013 - 03:52 PM
The real fun comes when you start learning ternary operations.

local variable = condition and true_value or false_value
It's really helpful when trying to shorten really long if/else/elseif statements.

That doesn't always work, like if the true_value is nil or false, but that isnt often. :P/>
Pharap #14
Posted 21 July 2013 - 05:51 PM
The real fun comes when you start learning ternary operations.

local variable = condition and true_value or false_value
It's really helpful when trying to shorten really long if/else/elseif statements.

That doesn't always work, like if the true_value is nil or false, but that isnt often. :P/>
That's the intended behaviour, that's how ternary operators work.
MudkipTheEpic #15
Posted 21 July 2013 - 05:57 PM
The real fun comes when you start learning ternary operations.

local variable = condition and true_value or false_value
It's really helpful when trying to shorten really long if/else/elseif statements.

That doesn't always work, like if the true_value is nil or false, but that isnt often. :P/>/>/>/>/>
That's the intended behaviour, that's how ternary operators work.

I get that, just saying that it doesnt always equal to true_value if it is nil or false, that's all.

(i know this is intended behavior, just make sure you account for that before using it as a replacement for if statements)
Pharap #16
Posted 21 July 2013 - 07:47 PM
The real fun comes when you start learning ternary operations.

local variable = condition and true_value or false_value
It's really helpful when trying to shorten really long if/else/elseif statements.

That doesn't always work, like if the true_value is nil or false, but that isnt often. :P/>/>/>/>/>
That's the intended behaviour, that's how ternary operators work.

I get that, just saying that it doesnt always equal to true_value if it is nil or false, that's all.

(i know this is intended behavior, just make sure you account for that before using it as a replacement for if statements)

Condition can be a compound statement, so making it include nil checking would be perfectly viable.
I'm not sure if lua supports nested ternary operations, but if it does that's also a solution. I get the feeling it probably doesn't though since lua is insanely minimalistic and hates symbolic operators.