This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
hbomb79's profile picture

Variable Names

Started by hbomb79, 17 December 2014 - 06:50 AM
hbomb79 #1
Posted 17 December 2014 - 07:50 AM
Hey, Lets jump in!

Lets say I have a var: i = 4

and I want to create a variable that is: displayi = "something"

that 'i' var will change as it is a loop, I want to create several variables each time that loops;

display0
display1
display2
etc…

each one will perform a different function, I know how to do that part, Just the variables them selves, I have tried display..i with no luck, I know how to do this in php and java, But not here, any ideas?
theoriginalbit #2
Posted 17 December 2014 - 08:03 AM
I would actually really like to know how you 'know how do to [it in] java'. Dynamic variable names are not possible in Java, period. Nor are they really possible in Lua, well they are, but if you're considering doing them you should rethink your design choices for your program. I'd probably say that tables will be your adequate solution.

local display = {}
display[ 4 ] = "some value"
print( display[ 4 ] )

for i = 1, 8 do
  display[ i ] = i * 2
end

for i = 1, 8 do
  print( display[ i ] )
end
Edited on 17 December 2014 - 07:04 AM
hbomb79 #3
Posted 17 December 2014 - 08:24 AM
Well, I need it so that when clicked it will launch a function that has the i var as a param

function doSomething(id)
–#id would be the id at the time the loop executed
end

although when I click the button they all have the same var, 1 or 6, heres my code;


local function clientList(title, ...)
local title = "Choose the device you want to manage"
        local tArgs = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19"}
if #tArgs < 1 then
drawTitleBar()
printer.centered("You Haven't Registered Any Clients!", 6)
printer.centered("Register Some First", 7)
printer.centered("Click To Return", 18)
os.pullEvent("mouse_click")
return
end
        local pages = {[1]={}}
        for i = 1, #tArgs, 1 do
                if #pages[ #pages ] == 6 then
                        pages[ #pages + 1 ] = {}
                end
                pages[ #pages ][ #pages[#pages] + 1 ] = tArgs[ i ]
        end
        local maxLen = 0
        for k, v in ipairs( tArgs ) do
                if #v > maxLen then maxLen = #v end
        end
        local maxx, maxy = term.getSize()
        if maxLen > maxx - 20 then
                error('The Largest String In The Array Is Too LARGE To Display!')
        end
        local centerx = math.ceil( maxx/2 )
        local centery
        local page = 1
        local selected = 1
        local function render()
                local tbl = pages[ page ]
LogFile.i("Render, Page: "..tostring(page).." table length: "..tostring(#tbl))
                centery = (maxy/2) - #tbl/2
                printer.centered(title, 4)
local xValue = 2
local Count = 1
local yValue = 8
                for i = 1, #tbl do
if Count == 1 then x = 2 y = 8
elseif Count == 2 then y = 8 x = termX-4-#"Manage Client"-#tbl[i]
elseif Count == 3 then y = 11 x = 2
elseif Count == 4 then y = 11 x = termX-4-#"Manage Client"-#tbl[i]
elseif Count == 5 then y = 14 x = 2
elseif Count == 6 then y = 14 x = termX-4-#"Manage Client"-#tbl[i] Count = 1
end
                    displayButtons[i] = btnInit("Manage Client "..tbl[i], nil, nil, x, y, 1, colors.cyan, 1, 256, function() error(tbl[i]) end, false, nil, nil, nil, nil)
Count = Count + 1
                end
                if pages[ page - 1 ] then
                    element.opacity(prevBtn, true)
                end
                if pages[ page + 1 ] then
                    element.opacity(nxtBtn, true)
                end
                local str = "(" .. page .. "/" .. #pages .. ")"
                term.setCursorPos( centerx - (#str/2), maxy )
                term.write( str )
        end
        while true do
render()
local event, param1, p2, p3 = os.pullEvent()
if event == "mouse_click" then
checkClick(event, param1, p2, p3)
elseif event == "PreviousPage" then
page = page -1
element.opacity(prevBtn, false)
element.opacity(nxtBtn, false) 
elseif event == "NextPage" then
page = page +1
element.opacity(prevBtn, false)
element.opacity(nxtBtn, false)
end
        end
end
clientList()
changePage("main")
end
Edited on 17 December 2014 - 08:13 AM
theoriginalbit #4
Posted 17 December 2014 - 08:33 AM
you can simply just do

displayButtons[i] = btnInit("Manage Client "..i, nil, 3, 2, 18, 1, colors.cyan, 1, 256, function() execute( i ) end, false, nil, nil, nil, nil)
the variable i is accessible from that scope
Edited on 17 December 2014 - 07:33 AM
hbomb79 #5
Posted 17 December 2014 - 08:55 AM
Thanks, I was missing something there.
hbomb79 #6
Posted 17 December 2014 - 09:15 AM
I have revised the code (Check Above) The numbers are jumbled up and if I click number 10 on the second page it errors 4… It is the fourth button on the page, But it should error 10

Also, There are only twenty entries, the fourth page has six, It is displaying them anyway…
Bomb Bloke #7
Posted 17 December 2014 - 10:17 AM
Difficult to comment, as you're not showing the whole script. I'm going to guess that it's got something to do with you never unregistering the old buttons you've created.

For example, you never clear the old contents from your displayButtons table. So, if on one iteration you put six entries in it, then on the next you only put in four… it'll still have six entries, as you never did anything to remove the remaining two.

Very likely you're doing something similar-ish that results in the list of buttons that're eligible to click on never being reset.

In regards to this chunk here:

local Count = 1
local yValue = 8
                for i = 1, #tbl do
if Count == 1 then x = 2 y = 8
elseif Count == 2 then y = 8 x = termX-4-#"Manage Client"-#tbl[i]
elseif Count == 3 then y = 11 x = 2
elseif Count == 4 then y = 11 x = termX-4-#"Manage Client"-#tbl[i]
elseif Count == 5 then y = 14 x = 2
elseif Count == 6 then y = 14 x = termX-4-#"Manage Client"-#tbl[i] Count = 1
end
.
.
.

The value you assign to y goes up by three every time Count goes up by two. We could hence use math.floor() to round division of Count down and thus calculate y with a single line:

local Count = 0  -- Count will range from 0 to 5
for i = 1, #tbl do
	y = 8 + math.floor(Count / 2) * 3
	.
	.
	.

The value of x depends on whether Count is even or not. bit.band(Count, 1) will always return 0 if Count is even (as would a modulus operation - Count%1), and if we combine that fact with a ternary (or the closest Lua's got), we can again work it out in a single line:

local Count = 0
for i = 1, #tbl do
	x = bit.band(Count, 1) == 0 and 2 or termX-17-#tbl[i]
	y = 8 + math.floor(Count / 2) * 3
	.
	.
	.
theoriginalbit #8
Posted 17 December 2014 - 10:24 AM
-snip-
your math is a little off there Bomb. y = 8 + math.floor(Count / 2) * 3 if Count is 2 then it will result in 11, which it is 8 in the if statements. Also you missed the fact that in the elseif for 6 the count gets reset back to 1.
Bomb Bloke #9
Posted 17 December 2014 - 10:31 AM
I altered the starting value of Count from 1 to 0, and the loop only repeats up to six times anyways.
theoriginalbit #10
Posted 17 December 2014 - 10:44 AM
Right, I did miss the 0 change. but I can see potential for it looping more than 6 times.
hbomb79 #11
Posted 17 December 2014 - 05:57 PM
So maybe if I completely clear the display table every time the page is changed? I already hide everything with the hideElement function… If you like I will show you the entire code when I get on my PC.
hbomb79 #12
Posted 18 December 2014 - 04:21 AM
Thanks guys, All done now, heres the final code, Let me know if there are any things I can do to make it better!


function viewClients()
changePage("clientPage")
term.clear()
drawTitleBar()
printer.centered("Please Wait While We Ping Your Clients", 6)
closeButton = btnInit("Cancel", nil, nil, termX/2-#"Cancel"/2, 18, 1, colors.red, 1, 256, function() os.queueEvent('cancel') end, false, nil, nil, nil, nil)

local function pingClients()
  sleep(0.6)
  for _, i in ipairs(current.devices.Client) do
   printer.centered("Pinging ID: "..i, 17)
   rednet.send(i, "PingRequest")
   local senderID, message, protocol = rednet.receive(5)
   if senderID == i then
    --Correct ID
    if message == "ClientReady" then
	 LogFile.i("Client "..i.." Ready", runningProgram)
    else
	 LogFile.w("Invalid Message, Client Is Off-line", runningProgram)
    end
   else
    LogFile.w("No Response From ID: "..i.." Message From: "..senderID, runningProgram)
    --Invalid return ID, malicious
   end
  end
end

local function cancel()
  while true do
   e, p1, p2, p3 = os.pullEventRaw()
   if e == "cancel" then drawTitleBar() printer.centered('Returning...', 6) return 'cancel' elseif e=="mouse_click" then
    checkClick(e, p1, p2, p3)
   end
  end
end

parallel.waitForAny(pingClients, loadingIcon, function() state = cancel() end)
if state == "cancel" then
  changePage("main")
  return state
end

changePage("clientList")

displayButtons = {}
buttonBlacklist = {""}

local function tableClear()
  tablesToRemove = {displayButtons, elements}
  for i, v in ipairs (tablesToRemove) do
   LogFile.i("Clearing "..tostring(v).." Table, Please Wait...", runningProgram)
   local k = next(v)
   while k do
    v[k] = nil
    k = next(v)
   end
   LogFile.i(tostring(v).." Table Amount: "..tostring(#v), runningProgram)
  end
 
end

local function clientList(title, ...)
  local title = "Choose the device you want to manage"
	    local tArgs = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19"}
  if #tArgs < 1 then
   drawTitleBar()
   printer.centered("You Haven't Registered Any Clients!", 6)
   printer.centered("Register Some First", 7)
   printer.centered("Click To Return", 18)
   os.pullEvent("mouse_click")
   return
  end
	    local pages = {[1]={}}
	    for i = 1, #tArgs, 1 do
			    if #pages[ #pages ] == 6 then
					    pages[ #pages + 1 ] = {}
			    end
			    pages[ #pages ][ #pages[#pages] + 1 ] = tArgs[ i ]
	    end
	    local maxLen = 0
	    for k, v in ipairs( tArgs ) do
			    if #v > maxLen then maxLen = #v end
	    end
	    local maxx, maxy = term.getSize()
	    if maxLen > maxx - 20 then
			    error('The Largest String In The Array Is Too LARGE To Display!')
	    end
	    local centerx = math.ceil( maxx/2 )
	    local centery
	    local page = 1
	    local selected = 1
	    local function render()
			    local tbl = pages[ page ]
			    centery = (maxy/2) - #tbl/2
			    printer.centered(title, 4)
    local xValue = 2
    local Count = 1
    local yValue = 8
    tableClear()
    LogFile.i("Length Of PreRender: "..tostring(#tbl), runningProgram)
    if pages[page-1] then prevBtn = btnInit("Previous Page", nil, nil, 2, 18, 1, colors.cyan, 1, 256, function() os.queueEvent("PreviousPage") end, false, nil, nil, nil, nil) end
    if pages[page+1] then nxtBtn = btnInit("Next Page", nil, nil, termX - 2 - #"Next Page", 18, 1, colors.cyan, 1, 256, function() os.queueEvent("NextPage") end, false, nil, nil, nil, nil) end
			    for i = 1, #tbl do
	 LogFile.i("Loop: "..tostring(i), runningProgram)
	 if Count == 1 then x = 2 y = 8
	 elseif Count == 2 then y = 8 x = termX-4-#"Manage Client"-#tbl[i]
	 elseif Count == 3 then y = 11 x = 2
	 elseif Count == 4 then y = 11 x = termX-4-#"Manage Client"-#tbl[i]
	 elseif Count == 5 then y = 14 x = 2
	 elseif Count == 6 then y = 14 x = termX-4-#"Manage Client"-#tbl[i] Count = 1
	 end
				    displayButtons[tbl[i]] = btnInit("Manage Client "..tbl[i], nil, nil, x, y, 1, colors.cyan, 1, 256, function() error(tbl[i]) end, false, nil, nil, nil, nil)
	 Count = Count + 1
			    end
			    if pages[ page - 1 ] then
				    element.opacity(prevBtn, true)
			    end
			    if pages[ page + 1 ] then
				    element.opacity(nxtBtn, true)
			    end
			    local str = "(" .. page .. "/" .. #pages .. ")"
			    term.setCursorPos( centerx - (#str/2), maxy )
			    term.write( str )
	    end
	    while true do
   render()
   local event, param1, p2, p3 = os.pullEvent()
   if event == "mouse_click" then
    checkClick(event, param1, p2, p3)
   elseif event == "PreviousPage" then
    if pages[page-1] then
	 drawTitleBar()
	 printer.centered("Loading, Please Wait...", 4)
	 page = page -1
	 hideElement("-a")
	 element.opacity(prevBtn, false)
	 element.opacity(nxtBtn, false)
	 tableClear()
	 drawTitleBar()
    else
	 prevBtn.visible = false
	 LogFile.w("Previous Button Fired When On First Page!", runningProgram)
    end
   elseif event == "NextPage" then
    if pages[page+1] then
	 drawTitleBar()
	 printer.centered("Loading, Please Wait...", 4)
	 page = page + 1
	 element.opacity(prevBtn, false)
	 element.opacity(nxtBtn, false)
	 tableClear()
	 drawTitleBar()
    else
	 nxtBtn.visible = false
	 LogFile.w("Next Button Fired When On Last Page!", runningProgram)
    end
   
   end
	    end
end
clientList()
changePage("main")
end