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

Please tell me what's wrong with this script

Started by Rax, 20 June 2013 - 06:39 AM
Rax #1
Posted 20 June 2013 - 08:39 AM
Code is here:

local pass1 = "TeslaCoil"
local depass = "FusionCoil"
local pullEvent = os.pullEvent
os.pullEvent = os.pullEventRaw

term.clear()
term.setCursorPos(1, 1)
while true do
  print("Insert Password: ")
  local input = read("*")
  if input == pass1 then
	term.clear()
	term.setCursorPos(1, 1)
	print("Access granted.")
	rs.setOutput("top", true)
	rs.setOutput("bottom", true)
	sleep(5)
	rs.setOutput("top", false)
	rs,setOutput("bottom", false)
	rs.setOutput("back", true)
	rs.setOutput("back", false)
 elseif input == depass then
    term.clear()
    term.setCursorPos(1, 1)
    break
  else
    print("Access denied.")
    sleep(2)
    os.reboot()
  end
end
Please help.
Saying thanks in advance!
Added picture of setup.
Tjakka5 #2
Posted 20 June 2013 - 08:44 AM
What should it do, and what doesnt it do?
Rax #3
Posted 20 June 2013 - 08:47 AM
It doesnt work. It is supposed to first: Use 2 block breakers to break Obsidian. Then after 5 sec it will stop the block breakers being powered, then place the obsidian back with Deployers. The bottom part of the code: "if input == depass then" is the debug password part. That will stop the program.
Tjakka5 #4
Posted 20 June 2013 - 08:48 AM
Can we have a picture of your setup? Maybe the block breakers don't see the redstone from a turtle as /valid/ redstone?
Bomb Bloke #5
Posted 20 June 2013 - 08:48 AM
Without an extra "end" statement at the very bottom (to close up that "while" loop), it probably doesn't do much.

"input" will never be compared to "depass". You may want to change the lower bit to something like:

  elseif input == depass then
    term.clear()
    term.setCursorPos(1, 1)
    break
  else
    print("Access denied.")
    sleep(2)
    os.reboot()
  end

If you want further assistance, forget about using phrases such as "it doesn't work". We know it doesn't work, that's why you're posting the thread, tell us what it does instead.
Rax #6
Posted 20 June 2013 - 08:49 AM
Can we have a picture of your setup? Maybe the block breakers don't see the redstone from a turtle as /valid/ redstone?
Not using turtles.
Rax #7
Posted 20 June 2013 - 08:55 AM
Without an extra "end" statement at the very bottom (to close up that "while" loop), it probably doesn't do much.

"input" will never be compared to "depass". You may want to change the lower bit to something like:

  elseif input == depass then
	term.clear()
	term.setCursorPos(1, 1)
	break
  else
	print("Access denied.")
	sleep(2)
	os.reboot()
  end

If you want further assistance, forget about using phrases such as "it doesn't work". We know it doesn't work, that's why you're posting the thread, tell us what it does instead.
It is still giving a error.
theoriginalbit #8
Posted 20 June 2013 - 09:01 AM
It is still giving a error.
What is the error? we aren't mind readers.

For better, quicker, and more helpful, help, please post the exact error messages you get.
Rax #9
Posted 20 June 2013 - 09:04 AM
It is still giving a error.
What is the error? we aren't mind readers.

For better, quicker, and more helpful, help, please post the exact error messages you get.
Error: bios:338: [string "startup"]:20: syntax error
Bomb Bloke #10
Posted 20 June 2013 - 09:14 AM
Look at line twenty. In particular, look at the use of commas and full stops.
Xenon #11
Posted 20 June 2013 - 09:56 AM
Fixed the code for you, with comments.


local pass1 = "TeslaCoil"
local depass = "FusionCoil"
local pullEvent = os.pullEvent
os.pullEvent = os.pullEventRaw

function auth() -- While true do loops are bad
  term.clear()
  term.setCursorPos(1, 1)
  print("Insert Password:")
  local input = read("*")
  if input == pass1 then
	term.clear()
	term.setCursorPos(1, 1)
	print("Access granted")
	rs.setOutput("top", true)
	rs.setOutput("bottom", true)
	os.sleep(5) --Changed to os.sleep
	rs.setOutput("top", false)
	rs.setOutput("bottom", false) -- You put a comma instead of a period (what gave you the syntax error)
	rs.setOutput("back", true)
	os.sleep(0.2) -- So the world has time to react
	rs.setOutput("back", false)
  elseif input == depass then
	term.clear()
	term.setCursorPos(1, 1)
	break
  else
	print("Access denied.")
	os.sleep(2)
	auth() -- No reboot needed
  end
end
auth()
theoriginalbit #12
Posted 20 June 2013 - 10:01 AM
Fixed the code for you, with comments.

function auth() -- While true do loops are bad
auth() -- No reboot needed
NO! Infinite loops (while true do) loops are good, recursion is bad! Calling a function from within itself, like you have done will cause the program to error after 256 times of running with a "stack overflow" error. loops should always be used, and infinite loops should always be used to infinitely run code!
Xenon #13
Posted 20 June 2013 - 10:07 AM
Fixed the code for you, with comments.

function auth() -- While true do loops are bad
auth() -- No reboot needed
NO! Infinite loops (while true do) loops are good, recursion is bad! Calling a function from within itself, like you have done will cause the program to error after 256 times of running with a "stack overflow" error. loops should always be used, and infinite loops should always be used to infinitely run code!

I am fully aware of recursions. However, in this case the program stops, waiting for input. I can't see how this could possibly create stack overflow?
theoriginalbit #14
Posted 20 June 2013 - 10:11 AM
I am fully aware of recursions. However, in this case the program stops, waiting for input. I can't see how this could possibly create stack overflow?
When the program pauses for input it does not magically clear the stack, the stack retains all function calls throughout the lifetime of the program, therefore if i was to spam a key and enter 256 times (which won't take long) the program would crash with a stack overflow and the door lock will have been bypassed.
Recursion should be avoided at all costs and loops should be used in their place. Out of curiosity here, why do you say that loops are a bad thing? I've never met anyone to say that before.
Xenon #15
Posted 20 June 2013 - 10:21 AM
I am fully aware of recursions. However, in this case the program stops, waiting for input. I can't see how this could possibly create stack overflow?
When the program pauses for input it does not magically clear the stack, the stack retains all function calls throughout the lifetime of the program, therefore if i was to spam a key and enter 256 times (which won't take long) the program would crash with a stack overflow and the door lock will have been bypassed.
Recursion should be avoided at all costs and loops should be used in their place. Out of curiosity here, why do you say that loops are a bad thing? I've never met anyone to say that before.

I very much doubt the person trying to break it would know the code and therefore the way of breaking it and even if so, crashing the program will render the whole thing useless. It is also quite obvious that the system can be bypassed much more easily, even without touching the computer.

I have used Lua in quite a lot of environments and loops are usually bad, as they take resources. I'm saying they are bad because in many other environments, "while true do" loops, if used incorrectly, crash the program due to the code being ran over and over again very fast, effectively running out of memory and crashing. It is best to learn not to use them if other ways are possible.

Edit: The spam method would also take at least 8.5 minutes, due to the 2 second wait. (256 x 2 = 512 seconds = ~8.53 minutes)
theoriginalbit #16
Posted 20 June 2013 - 10:49 AM
I very much doubt the person trying to break it would know the code and therefore the way of breaking it and even if so, crashing the program will render the whole thing useless. It is also quite obvious that the system can be bypassed much more easily, even without touching the computer.
It is the second thing I do, first being CTRL+T, especially when on a server with block breaking/placing permissions. Also breaking the program does not render the whole thing useless as you then have access to the computer to do whatever you want.

I have used Lua in quite a lot of environments and loops are usually bad, as they take resources.
If your loops are taking resources then you're coding your loops wrong, and/or you have a memory leak in your program(s), a loop does not take more resources each time it runs, localised variables are cleaned up, and global variables are overridden with new ones, the only overhead a loop adds is the conditional checking, which is a very small overhead anyway, not much more than a function call.

I'm saying they are bad because in many other environments, "while true do" loops, if used incorrectly, crash the program due to the code being ran over and over again very fast, effectively running out of memory and crashing.
Based off that you should have the same stance against infinite recursion! But even more so, infinite recursion uses far more resources than a loop!
In ComputerCraft all routines that take any longer than ~10 seconds of runtime will be terminated to allow other routines and computers to run. This is the "failure to yield" error. As for other systems/environments well I'll semi agree, infinite loops aren't a good thing, but that is just because of the design paradigm that OSes and such are expecting from programs, the software life-cycle your programs are given just don't allow for infinite loops, and when you use them for too long your program is reported to the user as unresponsive…

It is best to learn not to use them if other ways are possible.
The only other possible ways are recursion and tail calls. Recursion is worse to use than loops, it is far more resource intensive, it uses much more of the stack and heap, having to preserve the location in the function it was called, and keeping the entire variable scope of the function so that when it is returned to it can continue to run. Tail calls are much better than recursion, not too sure where they sit against loops, as I've rarely used them so haven't researched them in-depth, and they aren't available in every language.
Bomb Bloke #17
Posted 20 June 2013 - 10:53 AM
To be clear, recursive loops (such as the one discussed here) use more and more RAM with each iteration (this is the reason for the eventual overflow!), because each function call never actually ends. While loops do not have this problem, and are the correct choice for a program of this type (or most other programs, for that matter, assuming a for loop won't do).
Xenon #18
Posted 20 June 2013 - 10:54 AM
The only other possible ways are recursion and tail calls. Recursion is worse to use than loops, it is far more resource intensive, it uses much more of the stack and heap, having to preserve the location in the function it was called, and keeping the entire variable scope of the function so that when it is returned to it can continue to run. Tail calls are much better than recursion, not too sure where they sit against loops, as I've rarely used them so haven't researched them in-depth, and they aren't available in every language.

I use tail calls very often and they are indeed very useful, but in this case, it would need a re-write of the code.
I am not disagreeing with what you say in general. I'm just advising not to use while true loops more often than necessary, as they can very easily be used wrongly.
theoriginalbit #19
Posted 20 June 2013 - 11:01 AM
To be clear, recursive loops (such as the one discussed here) use more and more RAM with each iteration (this is the reason for the eventual overflow!)
Well the reason for the overflow isn't actually because the RAM has filled, it is because the data structure used to store the loop has a limit of 256 nodes, so it overflows, have you ever wondered why it was a Java error instead of a Lua error, thats why. But yes you're correct, the memory does fill up each iteration and that is because it needs to remember the state of the code it has just come from, including all local variables.

I use tail calls very often and they are indeed very useful, but in this case, it would need a re-write of the code.
Not at all, no re-write needed, tail calls in lua are as follows

return auth()
that would never overflow. because just like loops the function scope is cleaned up before calling the new function.
Bomb Bloke #20
Posted 20 June 2013 - 11:04 AM
Well the reason for the overflow isn't actually because the RAM has filled, it is because the data structure used to store the loop has a limit of 256 nodes, so it overflows, have you ever wondered why it was a Java error instead of a Lua error, thats why. But yes you're correct, the memory does fill up each iteration and that is because it needs to remember the state of the code it has just come from, including all local variables.
Yes, I'm aware that Lua doesn't get to flood the entirety of our system's RAM. ;)/>