I was reading some Lua and doing a little course to use it with Löve 2D, in an example they give declare a variable this way, which I honestly do not understand:
ballDX = math.random(2) == 1 and 100 or -100
I've tried to google and read a bit but haven't found a place to specifically explain that. Looking at what it says I identify the obvious, BallDX is equal to a random number between 1 and 2, but from there I get quite confused, what does it mean that the random number is equal to 1 and 100 or -100?
This is a kinda interesting Lua concept
The operator and returns its first argument if it is false; otherwise, it returns its second argument.
The operator or returns its first argument if it is not false; otherwise, it returns its second argument
In this case math.random(2) == 1 and 100 or -100 behaves exactly like a ternary operator, it can translate to:
If math.random(2) equals to 1, set ballDX = 100, otherwise set ballDX = -100
For example, assume you had a variable called c, and you want to assign it a value only if a variable is above 10, with a ternary operator you would do this: c = a > 10 ? a : b
In Lua you would use c = a > 10 and a or b
Related
I'm using Transform > Compute Variable to OR two variables (B,C) together. My two vars can have values 1, 2, or 3. I want to calculate a third var that's 1 if either B or C is 1 and zero otherwise. This works
A = (B=1) | (C=1)
But I'm running into trouble if B or C is missing. What I'd like is
if B and C exist and B or C equals 1, A = 1
if B and C exist and neither equals 1, A = 0
if B is missing and C is missing, A = missing
if B or C is 1 and the other value is missing, A = 1
if B or C is not 1 and the other value is missing, A = 0
Can I use Transform > Compute Variable to accomplish this or do I need another approach?
Here's a one liner for this:
compute A=max((B=1), (C=1)).
exe.
You can do this through the transformation menus, but I recommend getting used to (the power of) using syntax.
You can write this in the syntax window. If variable exists is translated as if ~miss(variable)
if ~miss(B) and ~miss(C) and any(1,B,C) A=1.
if ~miss(B) and ~miss(C) and ~any(1,B,C) A=0.
if miss(B) and miss(C) A=$sysmis.
if miss(B) or miss(C) and any(1,B,C) A=1.
if miss(B) or miss(C) and ~any(1,B,C) A=0.
EXECUTE.
Or, if I understand correctly what you are trying to do:
Compute A=0.
if any(1,B,C) A=1.
if miss(A) and miss(B) A=$sysmis.
EXECUTE.
In Lua, as you may know, arrays start with index 1.
In other languages I will often use modulus to make a value oscillate through the members of an array, for example:
i = (i + 1) % array.length
return array[1]
How can I do this in Lua, where array[0] is nil by default.
Like Egor said in the comments,
First do the modulo and then increment the value.
If i is equal to the length it will end up 0. Incrementing that will result in 1. Every other value just gets incremented.
This only works when incrementing by 1 though. For bigger steps you can do
i = (i+n-1)% #array + 1
I would like to know if it is possible to bound the range of values of a universally quantified variable in Z3.
For example, let's assume that I have a variable of type Real called "time" which is used to model the time in the system.
Let's say that I have an assertion which says that the value of some unary function "func1" shall always be between 1 and 100. The function takes the input the time variable. Expressed in Z3, I have encoded the property as following:
ForAll(time, And(func1(time) >= 1, func1(time) <= 100))
Please note that I explicitly need the time variable to be universally quantified, because I want the Z3 go give me unsat if I inject property of following type:
Exists(time, func1(time) == 101)
As far as my understanding goes for Z3, all the constants have mathematical (theoretical) and not computer (practical) implementation i.e. their values are not bound (unfortunately I cannot point to the resource where I have read this at the moment). Assume that with time I model time in my systems, and according to the system constrains it cannot run for more than x hours, which I can use and say that value of time is between 0 and x*60'*60 to give the maximum execution time in seconds. I know that I can assert the allowed values for time with the following assertion:
And(time >= 0, time <= x*60*60)
but will it affect the universal quantification given in 1?
Consequently, this should lead to a situation where if property 2 is injected and for value of time I specify x*60*60 + 1, it should not be unset since the ForAll is valid only for the values of time.
but will it affect the universal quantification given in 1)?
Note that
ForAll(time, And(func1(time) >= 1, func1(time) <= 100))
treats the variable "time" as bound. The formula has the same meaning as:
ForAll(xx, And(func1(xx) >= 1, func1(xx) <= 100))
When you assert the above, the meaning is that any instantiation of xx holds (is asserted). In particular, you can instantiate the quantified variable with the free variable "time" and in particular, you can instantiate with x*60*60+1 producing the assertion:
And(func1(x*60*60+1) >= 1, func1(x*60*60+1) <= 100)
Suppose you wanted to say that
And(func1(xx) >= 1, func1(xx) <= 100))
holds for every value xx between 0 and x*60*60, then you can write:
ForAll(xx, Implies(And(xx >= 0, xx <= x*60*60), And(func1(xx) >= 1, func1(xx) <= 100)))
(unfortunately I cannot point to the resource where I have read this at the moment).
Reasonable logic text books or foundations of computer science books should explain this in depth. Z3 supports a standard first-order many-sorted logic (with background theories).
The, well, special specification of Lua's length operator made me wonder whether Lua would be "allowed" to return a negative value in a situation like
#{[-5]=1,[-1]=3}
It says:
The length of a table t is defined to be any integer index n such that t[n] is not nil and t[n+1] is nil;
n=-5 and n=-1 would meet this criterion in my example, right?
moreover, if t[1] is nil, n can be zero.
Right, it can be zero, but it's not guaranteed, right?
For a regular array, with non-nil values from 1 to a given n, its length is exactly that n, the index of its last value.
This isn't the case here, so it doesn't apply.
If the array has "holes" (that is, nil values between other non-nil values), then #t can be any of the indices that directly precedes a nil value (that is, it may consider any such nil value as the end of the array).
This is the case here, so again, n=-5 and n=-1 would be valid return values, right?
Can I be entirely certain that Lua always returns 0 for the example table, or any other table containing only negative indices? If (hypothetically) I'd be writing a Lua interpreter and would return either of those values, would I be conforming with the specifications?
Edit
Obviously, the way Lua is implemented, it does not return negative values. I felt the length operator is somewhat underdocumented and I see that Lua 5.2's documentation has changed. It now says:
Unless a __len metamethod is given, the length of a table t is only defined if the table is a sequence, that is, the set of its positive numeric keys is equal to {1..n} for some integer n. In that case, n is its length. Note that a table like
{10, 20, nil, 40}
is not a sequence, because it has the key 4 but does not have the key 3.
So, it now talks about positive numeric keys, that's much clearer. I'm left wiser but not totally happy with the documentation. When it says the "length is only defined if the table is a sequence", it should also state that even if the table is not a sequence a value is returned, but the behavior is undefined. Also, this table looks pretty much like a sequence:
a = setmetatable(
{0},
{
__index = function(t,k)
return k < 10 and k or nil
end
}
)
i = 1
while a[i] do
print(a[i])
i = i+1
end
--[[ prints:
0
2
3
4
5
6
7
8
9
]]
print(#a)
-- prints: 1
However, this is becoming nitpicking as it's pretty clear that it wouldn't make sense to take into account what mess __index might make. And Stackoverflow is certainly not the place to complain about documentation that could be more precise.
As you have noted, the specification of the length operator has changed between 5.1 and 5.2.
Can I be entirely certain that Lua always returns 0 for the example table, or any other table containing only negative indices?
You can for the current reference implementation, which ensures that for ilen defined
function ilen (xs)
local i=0
while xs[i+1] do i=i+1 end
return i
end
we always have #xs >= ilen(xs) - see the definition of luaH_getn in the ltable.c source. But the specification now deliberately does not promise this behaviour: a conformant implementation can return nil or raise an exception for attempts to find the length of tables that are not sequences.
From the text in reference link. The answer is NO.
I think your confusing the fact that if a NIL is found then the length of the table is deemed to be position the NIL was found -1.
Therefore if t(1) is NIL then 1 - 1 = 0 so the table length is 0.
If the length of a table was 5 then the next position or t(6) IS or WOULD BE NIL
The length of a table t is defined to be any integer index n such that t[n] is not nil and t[n+1] is nil; moreover, if t[1] is nil, n can be zero.
I have variable that contains a number. While Lua allows variables to be set to nil, the variable then becomes toxic - destroying all code in its path.
If a variable contains a nil, I want it converted to a zero.
local score;
score = gameResults.finalScore;
I want to ensure that score contains a number, so I try:
local score;
score = tonumber(gameResults.finalScore);
but that doesn't work. So I try:
local function ToNumberEx(v)
if (v == nil) then
return 0
else
return tonumber(v)
end
local score;
score = ToNumberEx(gameResults.finalScore);
but that doesn't work. So I try:
local function ToNumberEx(v)
if (v == nil) then
return 0
else
return tonumber(v)
end
local score;
score = ToNumberEx(gameResults.finalScore);
if (score == nil) then
score = 0
end
That works, but defeats the purpose of having a function.
What is wrong with the function? I'm sure there is a perfectly reasonable and logical explanation - except to anyone who is familiar with programming languages.
score = tonumber(gameResults.finalScore) or 0
If the argument is already a number or
a string convertible to a number, then
tonumber returns this number;
otherwise, it returns nil.
Your code was good, except you didn't take into account what happens when gameResult.finalScore can't be converted to a number, if it was " " or "stuff" or a table than tonumber would return nil. None of your checks could detect that kind of situation.
If you really want to enforce that this variable gameResults.finalScore has this behavior (set to zero when receives any value different from a number), than you should take a look at Lua metatables.
You could create a metatable for gameResults, and "overwrite" the "index" and "newindex" methods of the metatable, checking the value for the finalScore field, and thus enforcing it's value to be on the desired ranges.
Not the best solution, but depending on your case, could be a good defensive practice against some other "evil developer" on the team. :-)
www.lua.org/pil/13.html (I'm not currently allowed to post more than 1 link) PiL 1 can help too, if you are still using Lua 5.0 or you want a more deep understanding of the metatables concept.