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

[Ask A Pro] Please Help me Debug This Code

Started by JustIan12, 06 June 2016 - 06:14 PM
JustIan12 #1
Posted 06 June 2016 - 08:14 PM
So, I'm trying to make a turtle Enderman Grinder and I am sending commands from a computer with a wireless modem to the turtles but I'm having issues getting the program to run on the sending and receiving end so I was wandering if you could help me.

Server Code:

-- Intro
term.setColor(colors.blue)
print("End Farm Server")
term.setColor(colors.white)
print("Written By Ian")
rednet.open(rednetSide)
-- Variable
rednetSide = "top"
-- Main Loop
term.setCursorPos(1,4)
term.setColor(colors.green)
write("True")
term.setColor(colors.red)
term.setCursorPos(8,4)
write("False")
term.setColor(colors.white)
term.setCursorPos(1,6)
write("Command: ")
-- Broadcast
while true do
  if read() == "True" then
   rednet.broadcast(read())
  end
  if read() == "False" then
   rednet.broadcast(read())
  end
  else
   term.setColor(colors.red)
   print("Invalid Command")
   sleep(0.5)
  end
end
end

Error: bios:14: [string "startup"]:39: 'end' expected to (to close 'while' at line 28)

I have had this error two times in two different programs I wrote and from what I can see there is an end to close the while XD so if someone could explain the error in depth that would also help me to try and solve these problems myself in the future thanks :)/>

Client Code:

rednet.open("right")
term.clear()
function active()
while true do
turtle.attack()
turtle.drop()
end
end
while true do
  id,message = rednet.receive()
  if id == 311 then
 
  if message == "True" then
   active()
  end
  if message == "False" then
   os.reboot()
  end
end
end

I do not know what is wrong with this code. but just checking :P/>
Dragon53535 #2
Posted 06 June 2016 - 08:44 PM
If elseif else statements are made like this:


if a then
--#stuff
elseif b then
--#Other stuff
else
--#Default
end
Notice the singular end at the end of it all.

Client code has 1 too many ends as well, while server code errors because the else doesn't see an if to connect to because the if above it is closed with an end

Also, your if statements that are like


if read() == "true" then
end
if read() == "false" then
end
Will run the read function two different times. What you want to do is save the result of read into a variable, and test if that variable is true or false.
Same for your rednet.broadcasts
Edited on 06 June 2016 - 06:48 PM
Dog #3
Posted 06 June 2016 - 08:45 PM
In your server code you have an extra end on line 34, just before the else - eliminate that end.

EDIT: ninja'd

In your client code, once you call active() that will loop forever and won't return to your other loop (so you wouldn't be able to reboot once you've started active). You'll probably want to rethink and restructure that code so it doesn't behave that way. For example, you could use parallel and os.queueEvent like so (this is untested)…

rednet.open("right")
term.clear()

local function active()
  os.pullEvent("ACTIVATEGRINDER")
  while true do
    turtle.attack()
    turtle.drop()
  end
end

local function netReceive()
  while true do
    local id,message = rednet.receive()
    if id == 311 then
      if message == "True" then
        os.queueEvent("ACTIVATEGRINDER")
      elseif message == "False" then
        os.reboot()
      end
    end
  end
end

parallel.waitForAny(netReceive, active)

Notice that I also localized your variables/functions, a practice you should get into as locals are faster and more secure.
Edited on 06 June 2016 - 07:03 PM
JustIan12 #4
Posted 06 June 2016 - 08:51 PM
thanks

If elseif else statements are made like this:


if a then
--#stuff
elseif b then
--#Other stuff
else
--#Default
end
Notice the singular end at the end of it all.

Client code has 1 too many ends as well, while server code errors because the else doesn't see an if to connect to because the if above it is closed with an end

Also, your if statements that are like


if read() == "true" then
end
if read() == "false" then
end
Will run the read function two different times. What you want to do is save the result of read into a variable, and test if that variable is true or false.
Same for your rednet.broadcasts

How would I go about doing this?
ReBraLaCC #5
Posted 06 June 2016 - 10:02 PM
Server code:

You're opening rednet before you set the variable… first do rednetSide="right" then rednet.open(rednetSide)
Dragon53535 #6
Posted 06 June 2016 - 10:12 PM
Call read once, save it's return value to a variable. Like you did with fs.open in your other thread.

Check to see if that variable you save it to is "true" or "false", send that variable through rednet.broadcast.
JustIan12 #7
Posted 07 June 2016 - 12:25 AM
okai
JustIan12 #8
Posted 07 June 2016 - 04:30 PM
I have asked the CC community on fixing this code and It all works except one thing the floppy disk is not ejected when I test the "wrong" one everything else works perfectly except that one thing so I was wondering if you could help please ???

-- Intro --
term.clear()
term.setCursorPos(1,1)
print("KCL System")
term.setCursorPos(1,2)
print("Written By Ian")
-- Database --
data = "CodeLvlOne"
-- Variables --
driveSide = "top"
rsSide = "right"
-- Function --
function mainLoop()
while true do
  os.pullEvent("disk", driveSide)
  h = fs.open("disk/database", "r")
  if h ~= nil and h.readAll() == data then
   h.close()
   rs.setOutput(rsSide, true)
   disk.eject(driveSide)
   sleep(2)
   rs.setOutput(rsSide, false)
  if h ~= nil then
   h.close()
   disk.eject(driveSide) -- HERE this doesn't want to work :P/> --
  end
end
end
-- Call Function --
mainLoop()
Edited on 07 June 2016 - 02:32 PM
KingofGamesYami #9
Posted 07 June 2016 - 04:36 PM
That's because if you have the wrong disk, h will be nil. In fact, you shouldn't even open the file unless it's there. I've restructured the loop to remove all redundancies, and make it work properly.

while true do
  os.pullEvent( "disk", driveSide )
  if fs.exists( "disk/database" ) then
    h = fs.open( "disk/database", "r" )
    local diskData = h.readAll()
    h.close()
    disk.eject( driveSide )
    if data == diskData then
      rs.setOutput( rsSide, true )
      sleep( 2 )
      rs.setOutput( rsSide, false )
    else
      disk.eject( driveSide )
    end
end
Edit: Fixed broken string
Edited on 07 June 2016 - 02:39 PM
JustIan12 #10
Posted 07 June 2016 - 05:18 PM
Thank you so much :)/>
JustIan12 #11
Posted 07 June 2016 - 07:58 PM
So I am having issues with my grinder client and server and I was wondering if you could help me fix the code.

Server:

-- Intro
term.setColor(colors.blue)
print("End Farm Server")
term.setColor(colors.white)
print("Written By Ian")
-- Variable
rednetSide = "top"
-- Main Loop
rednet.open(rednetSide)
term.setCursorPos(1,4)
term.setColor(colors.green)
write("True")
term.setColor(colors.red)
term.setCursorPos(8,4)
write("False")
term.setColor(colors.white)
term.setCursorPos(1,6)
write("Command: ")
-- Broadcast
while true do
if read() == "True" then
  rednet.broadcast(read())
if read() == "False" then
  rednet.broadcast(read())
else
  term.setColor(colors.red)
  print("Invalid Command")
  sleep(0.5)
end
end

Error: bios:14: [string "startup"]:41: 'end' expected (to close 'while' at line 28)


Client:

rednet.open("right")
term.clear()
local function active()
  os.pullEvent("ACTIVATEGRINDER")
  while true do
    turtle.attack()
    turtle.drop()
  end
endlocal function netReceive()
  while true do
    local id,message = rednet.receive()
    if id == 311 then
	  if message == "True" then
	    os.queueEvent("ACTIVATEGRINDER")
	  elseif message == "False" then
	    os.reboot()
	  end
    end
  end
end
parallel.waitForAny(netReceive, active)

Thanks

- Light
Lyqyd #12
Posted 07 June 2016 - 08:58 PM
Threads merged. Please stick to one topic for all questions about a given program or piece of code.
JustIan12 #13
Posted 07 June 2016 - 09:28 PM
oki :P/>
Dog #14
Posted 07 June 2016 - 09:38 PM
In your server code, your eighth to last line should be an elseif instead of an if - as Dragon already explained. Also, you can't use read() like you're using it (again, as Dragon already explained), unless you want to be prompted at least twice each loop, with only one answer working for each prompt. There is also no term.setColor - it is term.setTextColor or term.setBackgroundColor. That section of code should look something like this…

while true do
  local answer = read() --# collect user input via read()
  if answer == "True" or answer == "False" then
    rednet.broadcast(answer)
  else
    term.setTextColor(colors.red)
    print("Invalid command")
    sleep(0.5)
  end
end
Also, in your client code on line 9 you've merged two lines - end and local have become endlocal - that needs to be fixed.
Edited on 07 June 2016 - 07:41 PM
JustIan12 #15
Posted 08 June 2016 - 03:49 PM
Ohhhhhhhhhhhhhhhhhhhhhhhh… Sorry I was being repetitive. I did not understand what dragon meant by saving a variable I understand the basics of variables however I'm quite new to the mod and I am trying to understand all of the concepts I will try and edit the code now thanks. Im also new to and and or statements at least I learned something new :P/>
Edited on 08 June 2016 - 01:51 PM
Dog #16
Posted 08 June 2016 - 04:05 PM
No worries. In the future, if you're unclear about something, say so. We're here to help and we don't bite :)/>
JustIan12 #17
Posted 08 June 2016 - 04:55 PM
Oki