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

[Lua][Error]Odd error when I try to run program.

Started by Beardmoresam, 25 October 2012 - 09:11 PM
Beardmoresam #1
Posted 25 October 2012 - 11:11 PM
Hi, I wrote a program in notepad++. I'm relatively new to programing and what I do know I didn't learn in lua, so don't expect perfect code.
The issue I'm having is when I dropped the file into the programs folder for CC, the file shows up in the computers rom directory but throws an error when I run it and is blank when I edit it.
The error thrown up is:
bios:206:[string "testfile"]:109: 'then' expected

The code is included here:

--Turtle Navigation Program
--Samuel Beardmore
location = 0
direction = 0
inputs(location, direction)-- Gathers required inputs from user.
processes(location, direction, destination) --Sends inputs to be processed.
function inputs()
  location = getLocation()
  direction = getDirection()
  destination = getDestination()
  return location, direction, destination
end
function checkOneNumber(num1)
  tonumber(num1)
  return num1
end
function checkThreeNumbers(num1, num2, num3)
  tonumber(num1)
  tonumber(num2)
  tonumber(num3)
  return num1, num2, num3
end
function getLocation(location) --Gets location in co-ordinates.
  isNumber = false
  while isnumber == false do
	print("Please enter current X co-ordinate: ")
	x = read()
	print("")
	print("Please enter current Y co-ordinate: ")
	y = read()
	print("")
	print("Please enter current Z co-ordinate: ")
	z = read()
	if pcall(checkThreeNumbers(x, y, z))
	  then
		isNumber = true --Attempts to call checkNumber. If it works, it will return true and end the loop.
	  else
		print("Unrecognised values inputted")
		os.sleep(2) --These 3 lines are to allow the user to read the screen before it is cleaned up for another go.
		term.clear()
		term.setCursorPos(1,1)
	end
  end
  location = {x, y, z}
  return location
end
function getDirection(direction) --Gets the direction the turtle is facing.
  isNumber = false
  while isNumber == false do
	print("Please enter the direction the turtle is facing: ")
	direction = read()
	print("")
	if pcall(checkOneNumber(direction))
	  then
		isNumber = true
	  else
		print("Unrecognised values inputted")
		os.sleep(2)
		term.clear()
		term.setCursorPos(1,1)
	end
  end
  return direction
end
function getDestination() --Gets the destination co-ordinates.
  isNumber = false
while isnumber == false do
	print("Please enter destination X co-ordinate: ")
	x = read()
	print("")
	print("Please enter destination Y co-ordinate: ")
	y = read()
	print("")
	print("Please enter destination Z co-ordinate: ")
	z = read()
	if pcall(checkThreeNumbers(x, y, z))
	  then
		isNumber = true
	  else
		print("Unrecognised values inputted")
		os.sleep(2)
		term.clear()
		term.setCursorPos(1,1)
	end
  end
  destination = {x, y, z}
  return destination
end
function processes(location, direction, destination) --Within this function, all the actual work happens.
  while location.y < 255 do --This loop gets the turtle up to cruising altitude.
	turtle.up()
  end
  calcPath(location, destination)--Calculates  path to reach destination.
  destinationReached = false
  while destinationReached and (turtle.getFuelLevel() > 0) == false do --This loop makes the turtle keep going untill the destination is reached.
	pathCheck()
	followPath(direction, path)
  end
  while (location.y > destination.y) and (turtle.getFuelLevel() > 0) do
	turtle.down()
  end
  if turtle.getFuelLevel() = 0
	then print("Out of fuel")
	else print("Destination reached")
  end
end
function pathCheck() -- checks that the path ahead is clear, if it isn't, will check for altenatives, if trapped, will throw an error.'
  if turtle.detect() == true
	then turtle.turnLeft()
	  trackDirection(-1)
	  if turtle.detect() == true
		then
		  turtle.turnRight()
		  turtle.turnRight()
		  trackDirection(2)
		  if turtle.detect() == true
			then
			  print("Error: Unable to find a clear path.")
		  end
	  end
  end
end

function calcPath(location, destination) -- Calculates the path to be taken by the turtle.
  xPath = destination.x - location.x
  if (destination.x < 0) or (location.x < 0)
	then xPath = 0 - xPath
  end
  zPath = destination.z - location.z
  if (destination.z < 0) or (location.z < 0)
	then zPath = 0 - zPath
  end
  path = {xPath, zPath}
  return path
end
function followPath(direction, path) -- Causes the turtle to move towards the correct X co-ordinate, then the correct Z co-ordinate.
  if path.xPath > 0
	then
	  while direction ~= 3 do
		turtle.turnRight()
		trackDirection(1)
	  end
	  while path.xPath > 0 do
		turtle.forward()
		path.xPath = path.xPath - 1
	  end
	else
	  while direction ~= 1 do
		turtle.turnRight()
		trackDirection(1)
	  end
	  while path.xPath > 0 do
		turtle.forward()
		path.xPath = path.xPath + 1
	  end
  end
  if path.zPath > 0
	then
	  while direction ~= 2 do
		turtle.turnRight()
		trackDirection(1)
	  end
	  while path.xPath < 0 do
		turtle.forward()
		path.xPath = path.xPath - 1
	  end
	else
	  while direction ~= 0 do
		turtle.turnRight()
		trackDirection(1)
	  end
	  while path.xPath < 0 do
		turtle.forward()
		path.xPath = path.xPath + 1
	  end
  end
end
function trackDirection(turn) -- Tracks direction, edditing the global variable as required.
  direction = direction + turn
  if direction > 4
	then direction = direction -4
  elseif direction < 0
	then direction = direction + 4
  end
end
Any help is much appreciated, thanks, Sam.
tom2018 #2
Posted 25 October 2012 - 11:49 PM
SpoilerTurtle Navigation Program
Samuel Beardmore
location = 0
direction = 0
inputs(location, direction)– Gathers required inputs from user.
processes(location, direction, destination) Sends inputs to be processed.
function inputs()
location = getLocation()
direction = getDirection()
destination = getDestination()
return location, direction, destination
end
function checkOneNumber(num1)
tonumber(num1)
return num1
end
function checkThreeNumbers(num1, num2, num3)
tonumber(num1)
tonumber(num2)
tonumber(num3)
return num1, num2, num3
end
function getLocation(location) Gets location in co-ordinates.
isNumber = false
while isnumber == false do
print("Please enter current X co-ordinate: ")
x = read()
print("")
print("Please enter current Y co-ordinate: ")
y = read()
print("")
print("Please enter current Z co-ordinate: ")
z = read()
if pcall(checkThreeNumbers(x, y, z))
then
isNumber = true Attempts to call checkNumber. If it works, it will return true and end the loop.
else
print("Unrecognised values inputted")
os.sleep(2) These 3 lines are to allow the user to read the screen before it is cleaned up for another go.
term.clear()
term.setCursorPos(1,1)
end
end
location = {x, y, z}
return location
end
function getDirection(direction) Gets the direction the turtle is facing.
isNumber = false
while isNumber == false do
print("Please enter the direction the turtle is facing: ")
direction = read()
print("")
if pcall(checkOneNumber(direction))
then
isNumber = true
else
print("Unrecognised values inputted")
os.sleep(2)
term.clear()
term.setCursorPos(1,1)
end
end
return direction
end
function getDestination() Gets the destination co-ordinates.
isNumber = false
while isnumber == false do
print("Please enter destination X co-ordinate: ")
x = read()
print("")
print("Please enter destination Y co-ordinate: ")
y = read()
print("")
print("Please enter destination Z co-ordinate: ")
z = read()
if pcall(checkThreeNumbers(x, y, z))
then
isNumber = true
else
print("Unrecognised values inputted")
os.sleep(2)
term.clear()
term.setCursorPos(1,1)
end
end
destination = {x, y, z}
return destination
end
function processes(location, direction, destination) Within this function, all the actual work happens.
while location.y < 255 do This loop gets the turtle up to cruising altitude.
turtle.up()
end
calcPath(location, destination)–Calculates path to reach destination.
destinationReached = false
while destinationReached and (turtle.getFuelLevel() > 0) == false do This loop makes the turtle keep going untill the destination is reached.
pathCheck()
followPath(direction, path)
end
while (location.y > destination.y) and (turtle.getFuelLevel() > 0) do
turtle.down()
end
if turtle.getFuelLevel() = 0
then print("Out of fuel")
else print("Destination reached")
end
end
function pathCheck() checks that the path ahead is clear, if it isn't, will check for altenatives, if trapped, will throw an error.'
if turtle.detect() == true then
turtle.turnLeft()
trackDirection(-1)
if turtle.detect() == true
then
turtle.turnRight()
turtle.turnRight()
trackDirection(2)
if turtle.detect() == true
then
print("Error: Unable to find a clear path.")
end
end
end
end

function calcPath(location, destination) Calculates the path to be taken by the turtle.
xPath = destination.x - location.x
if (destination.x < 0) or (location.x < 0)
then xPath = 0 - xPath
end
zPath = destination.z - location.z
if (destination.z < 0) or (location.z < 0)
then zPath = 0 - zPath
end
path = {xPath, zPath}
return path
end
function followPath(direction, path) Causes the turtle to move towards the correct X co-ordinate, then the correct Z co-ordinate.
if path.xPath > 0
then
while direction ~= 3 do
turtle.turnRight()
trackDirection(1)
end
while path.xPath > 0 do
turtle.forward()
path.xPath = path.xPath - 1
end
else
while direction ~= 1 do
turtle.turnRight()
trackDirection(1)
end
while path.xPath > 0 do
turtle.forward()
path.xPath = path.xPath + 1
end
end
if path.zPath > 0
then
while direction ~= 2 do
turtle.turnRight()
trackDirection(1)
end
while path.xPath < 0 do
turtle.forward()
path.xPath = path.xPath - 1
end
else
while direction ~= 0 do
turtle.turnRight()
trackDirection(1)
end
while path.xPath < 0 do
turtle.forward()
path.xPath = path.xPath + 1
end
end
end
function trackDirection(turn) Tracks direction, edditing the global variable as required.
direction = direction + turn
if direction > 4
then direction = direction -4
elseif direction < 0
then direction = direction + 4
end
end
the then for line 109 was on line 110
remiX #3
Posted 25 October 2012 - 11:49 PM
Try changing

if turtle.detect() == true
				then
to
if turtle.detect() then
same with the one a few lines below

if turtle.getFuelLevel() = 0
needs two ='
Beardmoresam #4
Posted 25 October 2012 - 11:52 PM
Cheers, I didn't know it was that picky about it, will keep it in mind :P/>/>

EDIT – While we're at it, any pointers at to what bits of code could be improved and that kind of thing? Even be picky about the commenting and structure if you want ^_^/>/>
ChunLing #5
Posted 26 October 2012 - 02:01 AM
Hah, there's no end to how many different "style" changes you can make without changing the substance. Then again, there are some funny bits. Like your function checkThreeNumbers(num1, num2, num3). It doesn't actually do anything to the arguments before returning them. I know you think it does, but you're throwing away the tonumber() returns, you aren't using them to actually change your arguments into numbers. It should be just:

function checkThreeNumbers(num1, num2, num3) return tonumber(num1),tonumber(num2),tonumber(num3) end 

Stylewise, it looks like your print() 's in the next function should be write() 's. More substantively, you don't need to pcall that checkThreeNumbers function, if the inputs aren't numbers then the corresponding returns are just nils, so the function is already error-proof. The difficulty is that a number in any return doesn't mean that all of them were numbers, so you'd have to use "x,y,z = checkThreeNumbers(x,y,z)" And at that point you're not saving any time, you might as well just say
repeat
  write("Please enter current X co-ordinate: ") x = tonumber(read())
  write("Please enter current Y co-ordinate: ") y = tonumber(read())
  write("Please enter current Z co-ordinate: ") z = tonumber(read())
	    if not (x and y and z) then
			    print("Unrecognised values inputted")
			    os.sleep(2) --These 3 lines are to allow the user to read the screen before it is cleaned up for another go.
			    term.clear()
			    term.setCursorPos(1,1)
	    end
until x and y and z
Also, you don't need to do things like "location = {x, y, z} return location", just make that "return {x, y, z}", or just "location = {x, y, z}" as it is now, you have to have a table input into the function for it to work, but the table is cloned in memory and then the clone is modified, and then presumably you use your output to change the reference to the old table to refer to the clone.

You either pass it the table to modify, or you only return the new table. Much less confusing that way.

Anyway, applying those kinds of things throughout should make things a little smoother, I think.
Beardmoresam #6
Posted 26 October 2012 - 05:01 PM
Yeah, I'm used to python where you use int(variable) and it converts it to an integer (or crashed if it's a word becuase nill doesn't exist in python, hence the pcall).
May I ask why write() is used instead of print() ? It seems that one just does things slower than the other to me?? Thanks.
Ditto8353 #7
Posted 26 October 2012 - 05:21 PM
When you use 'write()' the user will be typing on the same line as the output, directly after what is written. As far as I know it just looks better and saves screen space.
Beardmoresam #8
Posted 26 October 2012 - 05:34 PM
The turtle screen is too small to have a line that long on it by the looks of things. I threw a n into the end of the line so that the user can see what they are typing. If that is the only advantage, I might aswell use print() ?
Ditto8353 #9
Posted 26 October 2012 - 05:37 PM
The turtle screen is too small to have a line that long on it by the looks of things. I threw a n into the end of the line so that the user can see what they are typing. If that is the only advantage, I might aswell use print() ?
Yes. print vs write should not have any effect on how your program runs.
Beardmoresam #10
Posted 26 October 2012 - 05:47 PM
Cheers, as you have probably gathered, I'm pretty new to this.

Here's the code after my troubleshooting so far. As you can see, I've re-arranged functions and code so that they are defined before they are called on (Stupid mistake on my part not to think of that in the first place lol). I've also made the changed reccomended above :D/>/>

Spoiler

--Turtle Navigation Program
--Samuel Beardmore
function trackDirection(turn) -- Tracks direction, edditing the global variable as required.
  direction = direction + turn
  if direction > 4 then direction = direction -4
  elseif direction < 0 then direction = direction + 4
  end
end
function getLocation() --Gets location in co-ordinates.
  repeat
  write("Please enter current X co-ordinate: n") x = tonumber(read())
  write("Please enter current Y co-ordinate: n") y = tonumber(read())
  write("Please enter current Z co-ordinate: n") z = tonumber(read())
	if not(x and y and z)  then
	  write("Unrecognised values inputted")
	  os.sleep(2) --These 3 lines are to allow the user to read the screen before it is cleaned up for another go.
	  term.clear()
	  term.setCursorPos(1,1)
	end
  until (x and y and z)
  return {x, y, z}
end
function getDirection(direction) --Gets the direction the turtle is facing.
  repeat
  write("Please enter the direction the turtle is facing: n") direction = tonumber(read())
	if not direction then
	  write("Unrecognised values inputted")
	  os.sleep(2)
	  term.clear()
	  term.setCursorPos(1,1)
	end
  until direction
  return direction
end
function getDestination() --Gets the destination co-ordinates.
  repeat
  write("Please enter destination X co-ordinate: n") x = tonumber(read())
  write("Please enter destination Y co-ordinate: n") y = tonumber(read())
  write("Please enter destination Z co-ordinate: n") z = tonumber(read())
	if not(x and y and z) then
	  write("Unrecognised values inputted")
	  os.sleep(2)
	  term.clear()
	  term.setCursorPos(1,1)
	end
  until (x and y and z)
  return {x, y, z}
end
function pathCheck() -- checks that the path ahead is clear, if it isnt, will check for altenatives, if trapped, will throw an error.
  if turtle.detect() == true then
   turtle.turnLeft()
   trackDirection(-1)
	if turtle.detect() == true then
	  turtle.turnRight()
	  turtle.turnRight()
	  trackDirection(2)
	  if turtle.detect() == true then
		write("Error: Unable to find a clear path.")
	  end
	end
  end
end

function calcPath(location, destination) -- Calculates the path to be taken by the turtle.
  xPath = destination.x - location.x
  if (destination.x < 0) or (location.x < 0) then xPath = 0 - xPath end
  zPath = destination.z - location.z
  if (destination.z < 0) or (location.z < 0) then zPath = 0 - zPath end
  path = {xPath, zPath}
  return path
end
function followPath(direction, path) -- Causes the turtle to move towards the correct X co-ordinate, then the correct Z co-ordinate.
  if path.xPath > 0 then
	while direction ~= 3 do
	  turtle.turnRight()
	  trackDirection(1)
	end
	while path.xPath > 0 do
	  turtle.forward()
	  path.xPath = path.xPath - 1
	end
  else
	while direction ~= 1 do
	  turtle.turnRight()
	  trackDirection(1)
	end
	while path.xPath > 0 do
	  turtle.forward()
	  path.xPath = path.xPath + 1
	end
  end
  if path.zPath > 0 then
	while direction ~= 2 do
	  turtle.turnRight()
	  trackDirection(1)
	end
	while path.xPath < 0 do
	  turtle.forward()
	  path.xPath = path.xPath - 1
	end
  else
	while direction ~= 0 do
	  turtle.turnRight()
	  trackDirection(1)
	end
	  while path.xPath < 0 do
		turtle.forward()
		path.xPath = path.xPath + 1
	  end
  end
end
function processes(location, direction, destination) --Within this function, all the actual work happens.
  print(location.y)
  while (location.y < 255) do --This loop gets the turtle up to cruising altitude.
	turtle.up()
  end
  calcPath(location, destination)--Calculates  path to reach destination.
  destinationReached = false
  while destinationReached and (turtle.getFuelLevel() > 0) == false do --This loop makes the turtle keep going untill the destination is reached.
	pathCheck()
	followPath(direction, path)
  end
  while (location.y > destination.y) and (turtle.getFuelLevel() > 0) do
	turtle.down()
  end
  if turtle.getFuelLevel() == 0  then write("Out of fuel")
  else write("Destination reached")
  end
end
location = getLocation()
direction = getDirection()
destination = getDestination()
processes(location, direction, destination) --Sends inputs to be processed.

EDIT – I also changed the location.y 's in the code to location[2] as I realised that it's incorrect.