We giving a task for Lua table but it is not working as expectable - lua

Our task is create a table, and read values to the table using a loop. Print the values after the process is complete. - Create a table. - Read the number of values to be read to the table. - Read the values to the table using a loop. - Print the values in the table using another loop. for this we had written code as
local table = {}
for value in ipairs(table) do
io.read()
end
for value in ipairs(table) do
print(value)
end
not sure where we went wrong please help us. Our exception is
Input (stdin)
3
11
22
abc
Your Output (stdout)
~ no output ~
Expected Output
11
22
abc
Correct Code is
local table1 = {}
local x = io.read()
for line in io.lines() do
table.insert(table1, line)
end
for K, value in ipairs(table1) do
print(value)
end

Let's walk through this step-by-step.
Create a table.
Though the syntax is correct, table is a reserved pre-defined global name in Lua, and thus cannot should not be declared a variable name to avoid future issues. Instead, you'll need to want to use a different name. If you're insistent on using the word table, you'll have to distinguish it from the function global table. The easiest way to do this is change it to Table, as Lua is a case-sensitive language. Therefore, your table creation should look something like:
local Table = {}
Read values to the table using a loop.
Though Table is now established as a table, your for loop is only iterating through an empty table. It seems your goal is to iterate through the io.read() instead. But io.read() is probably not what you want here, though you can utilize a repeat loop if you wish to use io.read() via table.insert. However, repeat requires a condition that must be met for it to terminate, such as the length of the table reaching a certain amount (in your example, it would be until (#Table == 4)). Since this is a task you are given, I will not provide an example, but allow you to research this method and use it to your advantage.
Print the values after the process is complete.
You are on the right track with your printing loop. However, it must be noted that iterating through a table always returns two results, an index and a value. In your code, you would only return the index number, so your output would simply return:
1
2
3
4
If you are wanting the actual values, you'll need a placeholder for the index. Oftentimes, the placeholder for an unneeded variable in Lua is the underscore (_). Modify your for loop to account for the index, and you should be set.
Try modifying your code with the suggestions I've given and see if you can figure out how to achieve your end result.
Edited:
Thanks, Piglet, for corrections on the insight! I'd forgotten table itself wasn't a function, and wasn't reserved, but still bad form to use it as a variable name whether local or global. At least, it's how I was taught, but your comment is correct!

Related

Basic Lua/ FREESWITCH array command

I am new to Lua, and this is an elementary question.
I a Lua script, I am querying the Postgress DB for two records via Freeswitch dbh.
I am able to set the first value as a local variable.
I am stuck at how to set the second value as a variable.
local dbh = Database.new('system');
local settings = Settings.new(dbh, A, B);
local sql = "SELECT A, B FROM TABLE WHERE A = '" .. A.."'";
local A = dbh:first_value(sql); --this gets saved correctly
local B = WHAT DO PUT HERE? ; -- Perhaps, I need to create an array instead?
dbh:release()
If you only want a specific row you should do this in the SQL command.
Alternatively you can query the entire table and run through the rows of the result.
I don't know freeswitch but that's what I found here:
https://freeswitch.org/confluence/display/FREESWITCH/Lua+API+Reference
dbh:query("query", function()) takes the query as a string and an optional Lua callback function that is called on each row returned by
the db. The callback function is passed a table representation of the
current row for each iteration of the loop.
Syntax of each row is: { ["column_name_1"] = "value_1", ["column_name_2"] = "value_2" }.
If you (optionally) return a number other than 0 from the
callback-function, you'll break the loop.
In order to use this you should learn how to define functions and how to use function values. Then it should be obvious what to do.
Maybe there is also a function that returns the query result as a table. At least that is the case for many other database interfaces. Ideally you should read the manual of the freeswitch Lua API first. Then you know what commands exist. Together with the Lua manual you'll know how to use them.

How can I get the line of a table while I got its address

local a = {'1'}
b = {'2'}
print('--------a:', a) --------a: table: 002411A0
print('--------b:', b) --------b: table: 005BC470
how can I get like: a.lua:1 in table a
or a.lua:2 in table b
while I know the table address (002411A0)
my lua environment is lua5.1, I don't know if I need to read the source or compiled of lua5.1?
If you are prepared to declare your tables with a helper function, called, say logger, you can achieve your goal.
The idea is to record the line in a virtual table field __line. In the example below I do it using __index metamethod, but you can simply add a field to the created table.
The line number is obtained by debug.getinfo (2).currentline. The choice of 2 is determined by the call stack depth in my example.
local function logged (t)
local line = debug.getinfo (2).currentline
return setmetatable (t, {
__index = function (_, key)
if key == '__line' then
return line
end
end
})
end
local a = logged {'1'}
print (a.__line) -- 12
b = logged {'2'}
print (b.__line) -- 14
There is no way to get a line where the table is defined by using its address (as the line in the source code and the address in memory have no relationship). What you can do is to parse the source code of your script and find where the definition of the table is, but I'm not sure what use it's going to have for you. Maybe you can describe what you are trying to do?
If you indeed want to find where the table is defined, you can use something like metalua that builds abstract syntax tree (AST) of your code fragment that you can then traverse to find where a particular table is defined.
Another option is to parse the output of luac compiler, which will allow you to find what line the NEWTABLE command for a particular table is on.

Replacing empty cells in a variable with values from another

I have a dataset with a number of columns. Two of them are practically the same however in variable column 1 there are string data that I would like to extract and replace in empty cells of variable column 2.
I tried using the syntax
If
variable_2 = "".
Compute variable_1 = variable_2.
End If
But do not get anything. Please, could someone help with this?
Much appreciated.
This should be either
if var2="" var2=var1.
(no period after the condition, no "end if")
OR
do if var2="".
compute var2=var1.
end if.
(this is a "do if" and not just an "if" - enables you to add commands after the condition, and not needed here).
In any case, if variable_2 is empty you want to run variable_2=variable_1 and not the reverse.

Problems with lua filter to iterate over table rows

I'm trying to write a simply lua filter for pandoc in order to do some macro expansion for the elements in a ReST Table.
filter.lua
function tablelength(T)
local count = 0
for _ in pairs(T) do count = count + 1 end
return count
end
function Table(table)
elems=pandoc.Table(table)["rows"]
print(tablelength(table))
for v in pairs(elems) do
print(v) -- Prints nothings
end
return table
end
test.rst
======= =========
A B
======= =========
{{x}} {{y}}
======= =========
Now, if I run pandoc.exe -s --lua-filter filter.lua test.rst -t rst the program says that there are 5 elements in elems, but the for loop is just skipped and I really don't know what I'm doing wrong here.
I'm very new to Lua and also know pandoc very litte. How can I iterate over the elements in elems?
Pandoc lua-filters provide the handy walk_block helper, that recursively walks the document tree down and applies a function to the elements that match the key.
In the example below, we give walk_block a lua table (what's a map or dict in other languages) with only one key (the key Str), and the value of the table is the function to apply. The function checks for the braces, strips them and prepends foo.
function Table(table)
return pandoc.walk_block(table, {
Str = function(el)
if el.text:sub(1,2) == '{{' then
txt = 'foo' .. el.text:sub(3, -3)
else
txt = el.text
end
return pandoc.Str(txt)
end
})
end
There are a couple of areas of misunderstanding in your code. First you need to remember that everything in lua is a table (implemented as an associative array or dictionary), and arrays are just a special case of a table where the keys are integers. To avoid confusion, for the rest of this answer I will use Table when I'm referring to the pandoc document element, and table when I'm referring to the lua data structure.
Your tablelength function is just counting the number of elements in the pandoc table that represents a Table. If you look in https://www.pandoc.org/lua-filters.html#type-ref-Block you will see that a Table has 5 properties- caption, aligns, widths, headers and rows. The return value of this function is 5 because of this. If you print out the values in the loop inside tablelength then you will confirm this. If you want to count the rows then you will need to pass the rows array into the function, not the table.
The second problem is that you are creating a new table rather than using the one passed in by pandoc. Instead of using elems=pandoc.Table(table)["rows"] just use elems=table["rows"] or elems=table.rows which is equivalent. The function pandoc.Table() is used to create a new element.
Furthermore, to loop over the elements in a table that are in the form of an array, you can use the ipairs function- it will return the numerically indexed values as described here What is the difference of pairs() vs. ipairs() in Lua?.
The rows table is, as might be expected, an array of rows where each row is in turn an array of elements. So to access the elements of the table you will need to have two loops.
Finally there is the issue of the pandoc object model. Because a table can contain other things (images, links, bold text etc) the final cell value is actually a list of blocks. Now depending on what you want to do with the table you can deal with this in different ways. You can use the walk_block function that mb21 referred to, but looping over just the blocks in a single cell. If your Table only contains (unformatted) text then you can simplify things by using the stringify function, which collapses the list of blocks into a single string.
Putting all of this together gives the following modified version of your code.
local stringify=pandoc.utils.stringify
-- This function is no longer needed
function tablelength(T)
local count = 0
for e in pairs(T) do
count = count + 1
print(e) -- this shows the key not the value
end
return count
end
function Table(table)
rows=table["rows"]
print("TableLength="..#rows)
for rownum,row in ipairs(rows) do
for colnum, elem in ipairs(row) do
print(stringify(elem)) -- Prints cell text
end
end
return table
end
As to you followup question, if you want to modify things then you just need to replace the cell values, while respecting pandoc's object model. You can construct the various types used by pandoc with the constructors in module pandoc (such as the aforementioned pandoc.Table). The simplest table cell will be an array with a single Plain block, which in turn contains a single Str element (blocks usually contain a list of Inline elements).
The following code shows how you can modify a table using the existing content or the row/column number. Note that I changed the parameter to the Table function from table to tableElem because table is a common type used in lua and overriding it gives hard to track errors.
local stringify=pandoc.utils.stringify
function makeCell(s)
return {pandoc.Plain({pandoc.Str(s)})}
end
function Table(tableElem)
rows=tableElem["rows"]
for rownum,row in ipairs(rows) do
for colnum, elem in ipairs(row) do
local elemText=stringify(elem)
if elemText=="{{x}}" then
row[colnum]=makeCell(elemText:gsub("x","newVal"))
end
if rownum==1 and colnum==2 then
row[colnum]=makeCell("Single cell")
end
end
end
local newRow={ makeCell("New A"), makeCell("New B")}
table.insert(rows,newRow)
return tableElem
end

Is there a way to tell `next` to start at specific key?

My understanding is that pairs(t) simply returns next, t, nil.
If I change that to next, t, someKey (where someKey is a valid key in my table) will next start at/after that key?
I tried this on the Lua Demo page:
t = { foo = "foo", bar = "bar", goo = "goo" }
for k,v in next, t, t.bar do
print(k);
end
And got varying results each time I ran the code. So specifying a starting key has an effect, unfortunately the effect seems somewhat random. Any suggestions?
Every time you run a program that traverses a Lua table the order will be different because Lua internally uses a random salt in hash tables.
This was introduced in Lua 5.2. See luai_makeseed.
From the lua documentation:
The order in which the indices are enumerated is not specified, even
for numeric indices. (To traverse a table in numeric order, use a
numerical for.)

Resources