If - then/variables

Posted by Hoss on Sun 28 Nov 2004 03:32 AM — 13 posts, 41,644 views.

USA #0
Hey Again I'm working with an if then statement which uses variables but it doesn't seem to work so I was wondering if anyone had any ideas why not?

Here it is
if world.GetVariable ("ratcount") = "1" or "2" or "3" and world.getvariable ("balance") = "1" then
world.send "b"
world.send "ss"
end if

Ratcount is a variable that is storing a number either 0 1 2 or 3 and balance is either a 0 or a 1. What I'm trying to get it to do is that when both ratcount > 0 (thus it's 1,2,or 3) and balance = 1 then it will send the stuff else it won't. I tried using @ratcount and @balance and expanding the variables but that didn't seem to work either any and all suggestions are welcome

Thanks

Hoss

Australia Forum Administrator #1
If you try this:

Note "1" or "2" or "3"

It will print 3.

That means your line is the same as:

if world.GetVariable ("ratcount") = "3" and world.getvariable ("balance") = "1" then

What you want is:


if (world.GetVariable ("ratcount") = "1" or _
    world.GetVariable ("ratcount") = "2" or _
    world.GetVariable ("ratcount") = "3") and _
    world.getvariable ("balance") = "1" then

Australia Forum Administrator #2
However even that is rather convoluted. I did that to show what you need to do the "or" stuff properly. In your case you just want:


if CInt (world.GetVariable ("ratcount")) > 0 and _
    world.getvariable ("balance") = "1" then
USA #3
I think this is the first thread that Nick has replied to in quite a while that hasnt included lua. Alert the media.
Australia Forum Administrator #4
Ah yes, I'd forgotten all about Lua. :P

Interestingly, Lua has the same problem - or a similar one anyway. In Lua, if you do this:


print  ("1" or "2" or "3")


You get the answer 1. That is, the result is true, because at least one argument was true.

In fact, what you are attempting to do would have worked in Cobol (anyone remember that?) which, if memory serves me correctly, would have interpreted what you wanted correctly.

I know it is boring, but this is where stuff like "operator precedence" becomes important. You can look that up in the VBscript manual (try "order of precedence").

The manual specifies that "or" has higher precedence than "=", so the "or" is evaluated first. So, putting in the implied brackets:


if world.GetVariable ("ratcount") = ("1" or "2" or "3") ...


So, you see that the expression ("1" or "2" or "3") is going to be evaluated before any comparison to the variable.


USA #5
Actually. Lua's interpretation is correct, at least with respect to precedence. VB's problem is that it can't tell the difference between normal OR and logical OR. This is a hold over from the days when & and | where not used in the language as the math (logic) version. Most modern languages may confuse precedence with respect to ancient ones languages like COBOL, but at least don't 'guess' about which OR you are actually trying to use.
USA #6
Thank You and while we are at it what the heck is Lua?

Hoss
USA #7
Quote:
if world.GetVariable ("ratcount") = ("1" or "2" or "3")
Even this, though, probably wouldn't do at all what one might intuitively expect. It certainly won't check to see if ratcount is equal to 1, or equal to 2, or equal to three.

Quote:
This is a hold over from the days when & and | where not used in the language as the math (logic) version.
What difference are you establishing between "normal OR" and "logic OR"?

Languages never 'guess', there are in fact strict rules that show which interpretations are used where. Perl for instance is rife with indications where here, a given variable is interpreted in scalar context, here it's in list context, etc. Of course, you can always force a specific context, but I guess you would accuse Perl of "guessing" as well. :-)
USA #8
Well then VBScript gets it wrong...

"1" or "2" or "3" ends up being treated as numbers, not strings (even though the quotes imply it), so you get 3, in Lua they are seen as strings and you end up with 'True'. The later behaviour is the right one. VBScript is basically doing this:

I have a 1, 2 and 3, must be numbers, so lets OR them the mathimatical way and return 3, then deal with the rest of the line.

But that is 'not' what you told it to do. Not in any other language, only variations of Basic, which uses OR to mean both:

Are either of these values True.
Take 1, OR it with 2, then OR it with 3.

Yeah, the result is consistant, but 'only' if you are sure the values being ORed will always be numbers or always be strings. The moment it is possible for both to exist on the same line or a = 1, b = "cat", a OR b, it doesn't work anymore.
Amended on Sun 28 Nov 2004 09:20 PM by Shadowfyr
USA #9
Well, 3 is 'true', so I'm not sure what the problem is. Besides, VBscript appears to be a very, very loosely typed language, so I'm not surprised that it casts the strings to integers before doing bitwise operations on them. In fact, that makes sense and is probably good behavior.

Quote:
so lets OR them the mathimatical way and return 3
By 'mathmetical' do you mean bitwise?
USA #10
Yes. Couldn't remember the term. I don't exactly agree that it is good for it to work that way, especially not if somewhat inconsistant to every other language. Technically 3 evaluates to True, but in most languages -1 is True, so you could still get false results if the language incorrectly cast to numeric values then you compared to the 'literal' value of True, instead of using something like IF result THEN.... It would also completely fail in cases where you had "0" OR "00". Bitwise this returns a numeric value, if first cast to integers, that would test as False, while in reality, since both strings are not empty (or even if only one of them was), it should evaluate to True.
Australia Forum Administrator #11
Actually, most languages consider 0 to be false, and everything else to be true, otherwise you would have things like 2 being "not true" and "not false" which wouldn't make sense.

VBscript certainly defines true as -1, whereas many language would define it as 1 (however accepting non-zero as meaning true in contexts where it is possible to use them).

I can't very well let this moment pass without mentioning that in Lua, 0 is considered true as well, rather strangely.

They made a design decision, which they now admit they regret, that the special value "nil" (meaning no value) was the only one which represented false.

Later on they added a "boolean type" in which case true and false had their expected meanings. However you cannot, of course, do arthmetic on booleans.

For example, in VBscript, try this:


Note vbtrue + 2


You get the answer 3 (that is, -1 + 4 = 3).

However in Lua, doing this:


Note (true + 4)


gives this error message: "attempt to perform arithmetic on a boolean value"

There is a certain amount of sense to this. Here is one application, in Lua you can convert a string to a number, eg:


Note (tonumber ("4e3"))


This (correctly) displays 4000, as that is 4 times 10 to the power 3.

Now if I try an invalid number:


Note (tonumber ("xxx"))


This prints "nil" which means the conversion failed.

Let's try a tricky case now:


Note (tonumber ("0"))


This prints zero as you would expect, but the important thing is that there is a distinction between zero and nil. This is where it is useful:


if not tonumber (somestring) then
  error ("invalid string")
end


The important thing is that this code works for every case, including where the string "0" was supplied. If zero was considered false then you could not be able to tell the difference between zero and a "bad number".

USA #12
Quote:
while in reality, since both strings are not empty (or even if only one of them was), it should evaluate to True.
Well, in reality, you're not really supposed to be using bitwise operations on strings to begin with! :) C/C++ probably wouldn't know what to do either. It would probably just do the bitwise operation on the pointers to the characters... which would always result in true.
Quote:
If zero was considered false then you could not be able to tell the difference between zero and a "bad number".
At least it has really useful applications. I guess you have to be careful since you can't cast things to boolean without making sure you use nil instead of 0, but all in all I can see why they did it.