Visualize Lua variables - lua

I would like to display all the variables of Lua code using some debugger functions, but i can't get the exacte size of the tables, and also i can't retrieve the element of some tables (value, name, etc).
The following code illustrate what i did :
local name, value;
local NIL = {} -- to represent nil variables
local locals = {}
local a = 9
local i = 1
local tab ={1,2,3,4,4,4}
local tab2 = {22,22,22,22}
local tab4 = {'X', 'Y','Z'}
while( true ) do
name, value = debug.getlocal( 1, i )
if ( name == nil ) then break end
locals[ name ] = value == nil and NIL or value
i = i + 1
end
for k, v in pairs( locals ) do
if(type(v) ~= "table") then -- if it's a simple variable
print( k, v )
else
print("tabel : "..k) -- if it's a table, display it's element
print("size : "..#k)
-- I want to diplay all the elements of the table !!
for x, y in pairs(v) do
print(y)
end
end
end

you can use inspect library (useful to print nested tables) or print_r function

Related

Lua finding matching value's from 2 different tables and printing it

local Table1 = {"Test"}
local Table2 = {"'Test' = 'True'"}
--my friend showed me this
local Matched = {}
function has_same()
for _,v in pairs(Table1) do
for _,z in pairs(Table2) do
if v == z then table.insert(Matched, v)
end
end
end
end
has_same()
for i,v in pairs(Matched) do
print(v)
end
This is the code I've been trying to use and when I run it just comes up as blank
I am trying to make it so it prints the Test = True If this needs more explanation let me know

Having problem with getPreference and setPreferences in corona

I have been following the tutorials on corona website and everything has been going well so far.
But in the tutorial "Displaying and saving score" i seem to have the following runtime error.
attempt to call field setPreferences' (a nil value)
This is the code of score.lua
local M = {}
M.score = 0
function M.init( options )
local customOptions = options or {} -- nice use of "or" operator
local opt = {}
opt.fontSize = customOptions.fontSize or 24
opt.font = customOptions.font or native.systemFont
opt.x = customOptions.x or display.contentCenterX
opt.y = customOptions.y or opt.fontSize*0.5 -- such that the score is positioned at the top, half of its font size.
opt.maxDigits = customOptions.maxDigits or 6
opt.leadingZeros = customOptions.leadingZeros or false
local prefix = ""
if ( opt.leadingZeros ) then
prefix = "0"
end
M.format = "%" .. prefix .. opt.maxDigits .. "d" -- so that its accesible in other modules.
-- Create the score display object
M.scoreText = display.newText( string.format( M.format, 0 ), opt.x, opt.y, opt.font, opt.fontSize ) -- string.format() works like printf and scanf statements
M.scoreText:setFillColor(1,0,0)
return M.scoreText
end
function M.set( value )
M.score = tonumber(value)
M.scoreText.text = string.format( M.format, M.score )
end
function M.get()
return M.score
end
function M.add( amount )
M.score = M.score + tonumber(amount)
M.scoreText.text = string.format( M.format, M.score )
end
function M.save()
print (" the score is " .. M.score)
local saved = system.setPreferences( "app", { currentScore=M.score } )
if ( saved == false) then
print ( "ERROR: could not save score" )
end
end
function M.load()
local score = system.getPreference( "app", "currentScore", "number" )
if ( score ) then
return tonumber(score)
else
print( "ERROR: could not load score (score may not exist in storage)" )
end
end
return M
This is the code of main.lua
local score = require( "score" )
local scoreText = score.init(
{
fontSize = 20,
font = "CoolCustomFont.ttf",
x = display.contentCenterX,
y = 30,
maxDigits = 7,
leadingZeros = true
})
local savedScore = score.load()
score.set( 1000 ) -- Sets the score to value
score.save()
I am aware there are other ways of keeping score, but I want to know what the problem is in my code. I googled everywhere but couldn't come up with any solution. Maybe I have made a mistake somewhere that I'm not able to identify.
Even tried a build on my smart phone, but ended up getting the same error.
From corona docs
Syntax
system.setPreferences( category, preferences )
category (required)
String. Indicates which set of preferences should be accessed on the system. Currently, only the "app" category is supported — this is the application's custom preferences defined by the Corona app developer.
preferences (required)
Table. Table of preferences to be written to storage. This table should contain key-value pairs where the key is the unique name of the preference and its value is either a boolean, number, or string.
if your M.score is nil then you might get an error
try this
local saved = system.setPreferences( "app", { currentScore=M.score or 0 } )

Converting Python function to Lua function

I am trying to convert existing python function into lua function. But my lua function is not producing same result as python function. Any help is appreciated.
Python function:
import json
test = '{"http://localhost:8080/":{"phone":{"-detail/phone detail.template.html":"5167n,a,7,2","s/motorola-xoom-with-wifi.json":"516a0,5,4,3"},"favicon.ico":"016ad,3,3,2","img/phones/motorola-xoom-with-wi-fi.":{"1.jpg":"*02s,2s,4v,h3|116da,o,l,6","2.jpg":"*02s,2s,4v,kp|116da,j,i,8","3.jpg":"*02s,2s,4v,ob|116da,o,m,8,7,,7,7,7","4.jpg":"*02s,2s,4v,rx|116da,o,m,9,8,,7,7,7","5.jpg":"*02s,2s,4v,vj|116da,p,m,a,8,,7,7,7"}}}'
def tri(param):
t = {}
for key in param:
if key not in param:
continue
if isinstance(param[key], dict) and param[key] is not None:
flat = tri(param[key])
for x in flat:
if x not in flat:
continue
t[key + x] = flat[x]
else:
t[key] = param[key]
return t
print(tri(json.loads(test)))
Lua code ( which is not producing same result as python function)
local json = require('cjson')
local test = '{"http://localhost:8080/":{"phone":{"-detail/phone-detail.template.html":"5167n,a,7,2","s/motorola-xoom-with-wi-fi.json":"516a0,5,4,3"},"favicon.ico":"016ad,3,3,2","img/phones/motorola-xoom-with-wi-fi.":{"1.jpg":"*02s,2s,4v,h3|116da,o,l,6","2.jpg":"*02s,2s,4v,kp|116da,j,i,8","3.jpg":"*02s,2s,4v,ob|116da,o,m,8,7,,7,7,7","4.jpg":"*02s,2s,4v,rx|116da,o,m,9,8,,7,7,7","5.jpg":"*02s,2s,4v,vj|116da,p,m,a,8,,7,7,7"}}}'
local function tri(param)
t = {}
for key in pairs(param) do
if param[key] == nil then end
if type(param[key]) == "table" then
flat = tri(param[key])
for k in pairs(flat) do
t[key .. k] = flat[k]
end
else
t[key] = param[key]
end
end
return t
end
print(json.encode(tri(json.decode(test))))
local function tri(param)
t = {} -- every time we call tri t will be "reset" to an empty table
for key in pairs(param) do
if param[key] == nil then end
if type(param[key]) == "table" then
flat = tri(param[key]) -- here we call tri, but we still need t!
for k in pairs(flat) do
t[key .. k] = flat[k]
end
else
t[key] = param[key]
end
end
return t
end
Making at least t global should solve that problem. But there is also no reason for flat to be global so we make it local too.
local function tri(param)
local t = {}
for key in pairs(param) do
if param[key] == nil then end
if type(param[key]) == "table" then
local flat = tri(param[key])
for k in pairs(flat) do
t[key .. k] = flat[k]
end
else
t[key] = param[key]
end
end
return t
end
Your task could be done a bit easier using json.traverse() function from this Lua JSON module.
Traversing lets you perform arbitrary operations with JSON elements on-the-fly.
This code concatenates element's path (for every JSON element except JSON containers: arrays/objects) and uses it as a key for Lua table.
local json = require'json'
local t = {}
local function callback(path, json_type, value)
if value ~= nil then -- value == nil for containers (arrays/objects)
t[table.concat(path)] = value
end
end
local test = '{"http://localhost:8080/":{"phone":{"-detail/phone detail.template.html":"5167n,a,7,2","s/motorola-xoom-with-wifi.json":"516a0,5,4,3"},"favicon.ico":"016ad,3,3,2","img/phones/motorola-xoom-with-wi-fi.":{"1.jpg":"*02s,2s,4v,h3|116da,o,l,6","2.jpg":"*02s,2s,4v,kp|116da,j,i,8","3.jpg":"*02s,2s,4v,ob|116da,o,m,8,7,,7,7,7","4.jpg":"*02s,2s,4v,rx|116da,o,m,9,8,,7,7,7","5.jpg":"*02s,2s,4v,vj|116da,p,m,a,8,,7,7,7"}}}'
json.traverse(test, callback)
-- Now t == {
-- ["http://localhost:8080/favicon.ico"] = "016ad,3,3,2",
-- ["http://localhost:8080/img/phones/motorola-xoom-with-wi-fi.1.jpg"] = "*02s,2s,4v,h3|116da,o,l,6",
-- ["http://localhost:8080/img/phones/motorola-xoom-with-wi-fi.2.jpg"] = "*02s,2s,4v,kp|116da,j,i,8",
-- ["http://localhost:8080/img/phones/motorola-xoom-with-wi-fi.3.jpg"] = "*02s,2s,4v,ob|116da,o,m,8,7,,7,7,7",
-- ["http://localhost:8080/img/phones/motorola-xoom-with-wi-fi.4.jpg"] = "*02s,2s,4v,rx|116da,o,m,9,8,,7,7,7",
-- ["http://localhost:8080/img/phones/motorola-xoom-with-wi-fi.5.jpg"] = "*02s,2s,4v,vj|116da,p,m,a,8,,7,7,7",
-- ["http://localhost:8080/phone-detail/phone detail.template.html"] = "5167n,a,7,2",
-- ["http://localhost:8080/phones/motorola-xoom-with-wifi.json"] = "516a0,5,4,3"
-- }

How do we change the way print displays a table

Assuming I have a piece of code such as the following
aTable = {aValue=1}
aTable_mt = {}
print(aTable)
What must I do to make Lua print something like aTable current aValue = 1 as opposed to table: 0x01ab1d2.
So far I've tried setting the __tostring metamethod but that doesn't seem to be invoked by print. Is there some metamethod I've been missing or does the answer have nothing to do with metamethods?
__tostring works:
aTable = {aValue=1}
local mt = {__tostring = function(t)
local result = ''
for k, v in pairs(t) do
result = result .. tostring(k) .. ' ' .. tostring(v) .. ''
end
return result
end}
setmetatable(aTable, mt)
print(aTable)
This prints aValue 1 (with one extra whitespace, remove it in real code). The aTable part is not available, because aTable is a variable that references the table, not the content of the table itself.
I'm not sure how you set the metamethod, but the following code prints "stringified" for me:
local aTable = {a = 1, b = 2}
setmetatable(aTable, {__tostring = function() return "stringified" end})
print(aTable)
If you want lua to generally print all tables human readable, you could
hook up/overwrite the print function:
local orig_print = print
print = function(...)
local args = {...}
for i,arg in ipairs(args) do
if type(arg) == 'table' then
args[i] = serialize(arg)
end
end
orig_print(table.unpack(args))
end
serialize could be serpent or some other lib from here
Note that this must be done before any other module/script is loaded.

Scanning folders using lua

I'm trying to get the name of all the file saved in two folders, the name are saved as :
1.lua 2.lua 3.lua 4.lua and so on
the folders name are :
first folder : "/const/"
second folder: "/virt/"
what I'm trying to do is only get the number of the files and this works but not in the right order, when I get the 17 file for example I get the 17th delivered from the function before the 15 and this causes for me a problem here the code of the function that I'm using :
local virt_path = "/virt/"
local const_path = "/const"
local fs = require "lfs"
local const = {}
for num = 1, (numberoffile)do -- numberoffile is predfined and can't be change
const[num] = assert(
dofile (const_path .. mkfilename(num)),
"Failed to load constant ".. num ..".")
end
local function file_number() --this is the function that causes me a headach
local ci, co, num = ipairs(const)
local vi, vo, _ = fs.dir(virt_path)
local function vix(o)
local file = vi(o)
if file == nil then return nil end
local number = file:match("^(%d+).lua$")
if number == nil then return vix(o) end
return tonumber(number)
end
local function iter(o, num)
return ci(o.co, num) or vix(o.vo, num)
end
return iter, {co=co, vo=vo}, num
end
As I said the function delive the need return values but not the right Arithmetic order.
any idea what I'm doing wrong here ?
I use my path[1] library.
1 We fill table with filenames
local t = {}
for f in path.each("./*.lua", "n") do
t[#t + 1] = tonumber((path.splitext(f)))
end
table.sort(t)
for _, i in ipairs(t) do
-- do work
end
2 We check if files exists
for i = 1, math.huge do
local p = "./" .. i .. ".lua"
if not path.exists(p) then break end
-- do work
end
[1] https://github.com/moteus/lua-path

Resources