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

Double "end" needed for if + elseif + end conditional statement?

Started by WhamyKaBlamy, 25 January 2015 - 02:52 PM
WhamyKaBlamy #1
Posted 25 January 2015 - 03:52 PM
Hi guys,

I have something that I find a little confusing with some of my code - I've read over the computercraft wiki, through the tutorials I can find here but I haven't found the answer to this yet (although it's completely possible I've missed it like a derp)

So, to put this in persepctive, I'm doing a tutorial on biofuel and because I find big systems fun to work with I'm controlling the flow to each biorector based on how full they are - for this I'm using openCCsensors. So that I could explain how all that worked, I set up a little program to show them in action and I had an error cropping up to tell me that I was missing an "end" statement for the while loop.

I indent my coding, so I know I wasn't missing one, and although it was simple fix and I can see what is happening, I am intrigued as to why it is happening.

So, here's an overview of the code I'm using for a while loop (I've taken out a lot of the gubbins to make it easier to read)


while exit_loop ~= true do
  os.startTimer(1)
  local event, a, b, c = os.pullEvent()
  if event == "timer" then
	screen_display(selection)
  elseif event == "monitor_touch" then
	local width, height = monitor.getSize()
	if b<11 and c<= #keys then
	  selection = c
	  screen_display(selection)
	elseif b<= 4 and c == height then
	  monitor.clear()
	  monitor.setCursorPos(1,1)
	  monitor.write("You don't want to do that dave")
	  os.sleep(2.0)
	  monitor.clear()
	  exit_loop = true
	else
	  selection = 0
	  screen_display(selection)
	end
  end
end
end --this is the second end I have to put in

If I remove the "else" statement then the second "end" isn't needed and it's obvious that it isn't registering the end for that if+elseif+else when the variable is changed to true. I've looked over the computercraft wiki and every example I've found of something using if, else if and else all at once only have a single "end" statement for them.

I hope I'm not being an eedjit, but from my understanding whether lua is using a "while" or a "do while" loop (I've honestly not had a reason to check into this as nothing I do at the moment matters either way), the "exit_loop ~= true" should be evaluated either before the internal code is executed or after, it shouldn't be quitting out of the loop at the point of the variable being switched to true?

So it should be either:
Start loop, check exit_loop ~= true, execute code, check exit_loop ~= true, execute code, etc, etc (while)
or
Start loop, execute code, check exit_loop ~= true, execute code, check exit_loop ~= true, etc, etc (do while)

anyway, it's nothing serious or major, I'd just be interested to know what's going on there so I can adapt the code without having to have a second "elseif" with a ton of conditions on it. Plus the second end is annoying the hell out of me (I know, that's purely aesthetic and I'm being anal about it)

Thanks for any help or information people :)/>
Lyqyd #2
Posted 25 January 2015 - 10:46 PM
Can you post the whole code, with nothing removed? You may have an "else if" somewhere.
HPWebcamAble #3
Posted 25 January 2015 - 11:10 PM

os.startTimer(1)
  local event, a, b, c = os.pullEvent()
  if event == "timer" then
	    screen_display(selection)
  elseif event == "monitor_touch" then

This should be


  local timer = os.startTimer(1)
  local event, a, b, c = os.pullEvent()
  if event == "timer" and a == timer then
	    screen_display(selection)
  elseif event == "monitor_touch" then
Otherwise ANY timer will trigger your screen_dipslay
Bomb Bloke #4
Posted 26 January 2015 - 01:30 AM
When the Lua interpreter says that it expects and "end" to go with a given if/while/for/whatever statement, it doesn't mean for sure that it goes with the particular line it's complaining about - it can't read your mind to figure out what you were intending, that's just it making an "educated guess". Keep checking the rest of your code to make sure all the "end"s match up.

I hope I'm not being an eedjit, but from my understanding whether lua is using a "while" or a "do while" loop (I've honestly not had a reason to check into this as nothing I do at the moment matters either way), the "exit_loop ~= true" should be evaluated either before the internal code is executed or after, it shouldn't be quitting out of the loop at the point of the variable being switched to true?

"do while" is implemented as a "repeat" loop in Lua, but otherwise you've about got it right. The variable is either checked at the top or the bottom of the loop, not in-between.

Eg:

-- Condition checked once before every iteration is performed:
while <condition> do
  -- stuff
end

-- Condition checked once after every iteration is performed:
repeat
  -- stuff
until condition

If you decide you want to exit a loop part-way, use the "break" keyword.
WhamyKaBlamy #5
Posted 26 January 2015 - 12:35 PM
Hi guys,

Update: I was being an eedjit and couldn't see I'd put a space between the else and if of one of the statements.

Thank you for the replies :)/>

@Lyqyd: I found it when I was posting it into here, sods law

@HPWebcamAble: Aye, normally I would do that condition in there, and I think I will change the code. I honestly only just checked for if it was a timer event because I knew I only had one in there and I jumped on here once I'd been through it a few times looking for the extra if-else statement without success.

@Bomb-bloke: Thank you for confirming that :)/> I don't know if I was being stubborn or not by not thinking about the "break" keyword, I haven't done any scripting that I make the main loop myself for a while, the ones I've been using for applications/programs (like second life) have been event based languages, so I just defaulted to worrying about an infinite loop being caused.

Sorry about that fuss, I'll post the code below here so you can see - when I'd originally pasted the code into my post and edited it I'd obviously thought the space there was a mistake from when I was taking out some of the bits and just corrected it without realising. D'oh! *bangs head repeatedly off of the desk in embarrassment* Really am sorry about that, I must've looked over it a hundred times and not seen it…hell, I even corrected it in here without thinking.

Spoiler

os.loadAPI("ocs/apis/sensor")
local monitor = peripheral.wrap("left")
local strg_snsr = sensor.wrap("top")
local keys = {}
local selection = 0
local exit_loop = false

function get_keys(target_keys)
  keys = {}
  for k,_ in pairs(target_keys) do
	table.insert(keys,k)
  end
end

function screen_display(number)
  monitor.clear()
  local width, height = monitor.getSize()
  for i=1, #keys do
	if number == i then
	  monitor.setBackgroundColor(colors.green)
	end
	monitor.setCursorPos(1,i)
	monitor.write("Object "..i)
	monitor.setBackgroundColor(colors.black)
  end
  monitor.setCursorPos(1,height)
  monitor.write("quit")
  for i=1, height do
	monitor.setCursorPos(11,i)
	monitor.write("|")
  end
  if number ~= 0 then
	local info = strg_snsr.getTargetDetails(keys[number])
	monitor.setCursorPos(13,1)
	monitor.write("Name: "..info["Name"])
	monitor.setCursorPos(13,3)
	monitor.write("Percent Full: "..string.sub(tostring(info["InventoryPercentFull"]),1,5).."%")
	monitor.setCursorPos(13,4)
	monitor.write("Space Left: "..(info["TotalSpace"]-info["ItemCount"]))
	monitor.setCursorPos(13,6)
  end
end

get_keys(strg_snsr.getTargets())
screen_display(selection)

while exit_loop ~= true do
  os.startTimer(5.0)
  local event, a, b, c = os.pullEvent()
  if event == "timer" then
	screen_display(selection)
  elseif event == "monitor_touch" then
	local width, height = monitor.getSize()
	if b<11 and c<= #keys then
	  selection = c
	  screen_display(selection)
	else if b<=4 and c == height then
	  monitor.clear()
	  monitor.setCursorPos(1,1)
	  monitor.write("you don't want to do that dave..")
	  os.sleep(2.0)
	  monitor.clear()
	  exit_loop = true
	else
	  selection = 0
	  screen_display(selection)
	end
  end
end
end
Edited on 26 January 2015 - 11:55 AM