Love2d adding value to table inside for loop.. Using a variable - lua

This is something that's really been nagging at me for some time:
for i = 1, 4 do
x = love.physics.newFixture(diffTable[i].body, diffTable[i].shape):setCategory(10)
x = x:setUserData('Border') -- error here
table.insert(data, x)
end
Let's say I want to insert a variable into the table (basically creating the variable, and then modifying it) and then inserting it:
When I do the x = x:setUserData(...) an error comes up.. saying attempt to index global variable x (nil)
So my question is, how would I create a variable inside a for loop, specifically
I need to do it this way because I'm using love.physics, and creating a fixture with a category. I also need to setUserData at that time but it's not possible.
And I'm sure there has to be a way of doing this...
Thanks in advance!!

The function Fixture:setCategory does not return a value.
so when you do this
x = love.physics.newFixture(diffTable[i].body, diffTable[i].shape):setCategory(10)
you are setting x = nil.
Fixture:setUserData also does not return a value.
If you change it to this you will no longer get that error.
for i = 1, 4 do
x = love.physics.newFixture(diffTable[i].body, diffTable[i].shape)
x:setCategory(10)
x:setUserData('Border') -- error here
table.insert(data, x)
end

Related

lua in a table to get another element of the same table

When creating an element in the table, I need to use another element that I created before in the same table. please help me with this.
local table = {
distance = 30.0,
last_distance = table.distance-10.0
}
I want to do the above operation but I can't, I think I need to use self or setmetatable but I don't know how to do it. and please don't give me answers like first create a value outside and then use it in the table, I don't want to do that.
Basic life advice
First of all: Don't call your table table. That will shadow the global table library. Call it t, tab, tabl, Table, table_, or actually give it a useful name, but don't call it table, or there'll be a big surprise when you try to access any table.* methods. Ideally, your linter should warn you about this.
Implementing it using hacks
Table constructors are equivalent to creating a table on the stack - there is no named local variable self or the like. It is likely possible that there is a hidden local variable accessible using debug.getlocal however:
$ lua
Lua 5.4.4 Copyright (C) 1994-2022 Lua.org, PUC-Rio
> function getlocals()
>> local i = 1; repeat local k, v = debug.getlocal(2, i); i = i + 1; print(k, v) until not k
>> t = {a = getlocals(), b = ()}
stdin:3: unexpected symbol near ')'
> function getlocals()
local i = 1; repeat local k, v = debug.getlocal(2, i); i = i + 1; print(k, v) until not k end
> t = {a = getlocals(), b = 2}
(temporary) table: 0x55e9181302d0
nil nil
> t
table: 0x55e9181302d0
Indeed, from basic testing it appears that this is even the first local inside the table constructor! However, it isn't quite as easy:
> local a = 1; local b = a; t = {a = getlocals(), b = 2}; print(b)
a 1
b 1
(temporary) table: 0x55e918130160
nil nil
1
Using extensive hacks, you might be able to write something that returns the currently constructed table most of the time (probably relying on the fact that it will usually be the last local). The following works:
function lastlocal()
local i = 0
local last
::next:: -- you could (and perhaps should) use a loop instead
i = i + 1
local k, v = debug.getlocal(2, i)
if v then
last = v
goto next
end
return last
end
from my basic testing, this works fine to obtain the table currently being constructed:
> function lastlocal()
local i = 0
local last
::next:: -- you could (and perhaps should) use a loop instead
i = i + 1
local k, v = debug.getlocal(2, i)
if v then
last = v
goto next
end
return last
end
> t = {a = 1, b = lastlocal().a}
> t.a
1
> t.b
1
Why you should not implement this using hacks
With all of this in mind: Don't ever do this. The purpose of this merely is to lead this ad absurdum. There are multiple reasons why this is horribly unreliable:
The order of execution of table constructor assignments is undefined. An optimizing interpreter like LuaJIT (and the PUC Lua implementation just as well) is free to reorder {a = 1, b = 2} to {b = 2, a = 1}.
Likewise, how table constructors are implemented internally is entirely undefined. There is no guarantee that the local variable actually exists and is the last one.
It is horribly inefficient and relies on the debug library for something other than debugging.
What's a metatable?
Metatables serve an entirely different purpose; you could dynamically generate derived fields like last_distance using them, but you can't use them to reference a table using a table constructor. Here's a basic example:
local t = {distance = 30}
setmetatable(t, {__index = function(self, k)
if k ~= "last_distance" then return nil end
return t.distance - 10 -- calculate `last_distance` & return it
end})
print(t.last_distance) -- 20
t.distance = 10
print(t.last_distance) -- 0
Back to the question
When creating an element in the table, I need to use another element that I created before in the same table.
The proper way to do this is to either (1) create a value outside of the table
local distance = 30
local last_distance = distance - 10
local tab = {distance = distance, last_distance = last_distance}
Perfectly readable, perfectly fine.
Or (2) first create a table with some properties, then add derived properties:
local tab = {distance = 30}
tab.last_distance = tab.distance - 10
as readable, as fine.
Both will be highly efficient; only micro-optimizations would be debatable (could (1) choose a better layout for the hashes by choosing the right insertion order? does it pre-allocate the right size (likely yes)? does (2) incur a penalty since it indexes tab to obtain tab.distance?), but none of this will likely ever matter.
I want to do the above operation but I can't, I think I need to use self or setmetatable but I don't know how to do it.
I have shown you:
How you can do it using egregious hacks and why you shouldn't.
How you can do something similar (derived attributes) using a metamethod.
and please don't give me answers like first create a value outside and then use it in the table, I don't want to do that.
This is the correct, idiomatic way to do this in Lua though. Your restriction seems arbitrary.

CC Tweaked, Im trying to make a quarry program but im gettting a error about Comparing a number with a string, but both values are numbers

The error I get:
query.lua:25: attempt to compare number with string
The rest of my code - I'm not sure why its not working, because I made sure that both values were in fact numbers, and the error still keeps happening, I have tried looking it up, and I cant find a solution, any help would be greatly appreciated.
print("Enter L,W,H values")
x = read()
y = read()
z = read()
length = 5
width = 5
height = 5
length = x
width = y
height = z
volume = length * width * height
print(volume.." blocks to mine")
turtle.refuel()
turtleFuel = turtle.getFuelLevel()
fuelNeeded = turtleFuel - volume
if fuelNeeded >= 0 then
print("Enough Fuel Detected")
else
print("not Enough fuel, error,"..fuelNeeded..", fuel required "..volume)
end
length1 = length
while length1 > 0 do
turtle.forward()
length1 = length1 - 1
end
In Computercraft, read() returns a string. You should change the first few lines of your code:
Instead of
x = read()
y = read()
z = read()
write
x = tonumber(read())
y = tonumber(read())
z = tonumber(read())
Do note, that read() is not the same as io.read(). One is a standard Lua function (which is also implemented in Computercraft) and read() is a function created specifically for CC computers and that can take a few extra parameters, and that you can use to do a few tricks once you get more advanced. (I am saying this because someone in the comments mentioned checking io.read())
Also, you mentioned that you "checked the type of the variable in the editor". Lua is a dynamically typed language, and the type of a variable CANNOT be known before the program is actually run. What your editor is probably doing is guessing the type of the variable based what it expects your program to do. These guesses are almost always inaccurate. That's why you should understand what your program is doing, and not rely on your editor. If you want to be extra sure, you want to run some tests, or the type of the variable simply is not known before the program is actually executed (because it may vary), you can use type(), like you have, to check its type at runtime. type() returns a string, representing the type of the variable:
type(nil) ---> nil
type("helloworld") ---> "string"
type(42) ---> "number"
type(function()print("HELLO")end) ---> "function"
type({1,2,3}) ---> "table"

I am looking for a Lua find and replace logic

enter image description here
I just started working on lua scripting since a week. I have a lua file where in the logic needs to be written for a certain condition.
The condition when gets triggered
it does an iteration on one of the fields to change value from
(ABC123-XYZ) to this value
(ABC123#1-XYZ) and it keeps increasing whenever iterations happens (ABC123#2-XYZ)
I need to run a function that removes the # followed by number to change it back to (ABC123-XYZ). Looking for any advice!
Edit 1:
Below is the updated code that is written Thanks to #Piglet
I have another scenario if therr are two hashes in the variable.
local x = 'BUS144611111-PNB_00#80901#1555-122TRNHUBUS'
local b = x:gsub("#%d+","")
function remove_char(a) a=a:gsub("#%d+","")
return a;
end if string.match(x,"#")
then print('function')
print(remove_char(x));
else print(x);
end
Expected output should be
x = 'BUS144611111-PNB_00#80901-122TRNHUBUS' for the aforesaid variable
local a = "ABC123#1-XYZ"
local b = a:gsub("#%d+", "")
this will remove any # followed by or one more digits from your string.

Initialising hist function in Julia for use in a loop

When I use a loop, to access the variables outside of the loop they need to be initialised before you enter the loop. For example:
Y = Array{Int}()
for i = 1:end
Y = i
end
Since I have initialised Y before entering the loop, I can access it later by typing
Y
If I had not initialised it before entering the loop, typing Y would not have returned anything.
I want to extend this functionality to the output of the 'hist' function. I don't know how to set up the empty hist output before the loop. The only work around I have found is below.
yHistData = [hist(DataSet[1],Bins)]
for j = 2:NumberOfLayers
yHistData = [yHistData;hist(DataSet[j],Bins)]
end
Now when I access this later on by simply typing
yHistData
I get the correct values returned to me.
How can I initialise this hist data before entering the loop without defining it using the first value of the list I'm iterating over?
This can be done with a loop like follows:
yHistData = []
for j = 1:NumberOfLayers
push!(yHistData, hist(DataSet[j], Bins))
end
push! modifies the array by adding the specified element to the end. This increases code speed because we do not need to create copies of the array all the time. This code is nice and simple, and runs faster than yours. The return type, however, is now Array{Any, 1}, which can be improved.
Here I have typed the array so that the performance when using this array in the future is better. Without typing the array, the performance is sometimes better and sometimes worse than your code, depending on NumberOfLayers.
yHistData = Tuple{FloatRange{Float64},Array{Int64,1}}[]
for j = 1:NumberOfLayers
push!(yHistData, hist(DataSet[j], Bins))
end
Assuming length(DataSet) == NumberOfLayers, we can use anonymous functions to simplify the code even further:
yHistData = map(data -> hist(data, Bins), DataSet)
This solution is short, easy to read, and very fast on Julia 0.5. However, this version is not yet released. On 0.4, the currently released version, the performance of this version will be slower.

Return multiple values to a function, and access them separately in Lua?

If I have a function that returns multiple values, how can I access those values separately? Something like table[i].
angles = function()
x = function()
local value = 0
return value
end
y = function()
local value = 90
return value
end
z = function()
local value = 180
return value
end
return x(), y(), z()
end
A problem arises here when wanting to use, for example, the x value separately, while keeping it in the function angles.
print(????)
Sort of wish functions worked like tables in this respect, so I could type something like print(angles.x)
Also, I know that code seems really redundant, but it's actually a much more simplified version of what I'm actually using. Sorry if it makes less sense that way.
x, y, z= angles()
print (x,y,z)
There's a couple of ways to do this.
Most obvious would be
local x, y, z = angles()
print(x)
If you want the first value specifically
local x = ( angles() )
-- `local x = angles()` would work too. Lua discards excess return values.
print(x)
or, somewhat less readably
print((angles()))
You could also return a table from the function, or use the standard module table to pack the return values into one.
local vals = table.pack(angles())
print(vals[1])
Another way of accessing them individually (as the question wording implies) rather than all at once is this:
print((select(1,angles())))
print((select(2,angles())))
print((select(3,angles())))
Output:
0
90
180
The select() call needs to be in parentheses in order to return individual entries rather than all after the given offset.

Resources