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

[Lua][Question] Program Produces Errors When Not Number

Started by Henness, 01 April 2012 - 10:57 AM
Henness #1
Posted 01 April 2012 - 12:57 PM
How do I stop my program from producing an error when someone types letters or symbols instead of numbers?

The error is
attempt to compare nil with number

I know why it errors I just know know how to fix it.

Here is the part Im working with I just need it to say "Width must be a number" and then start the while loop agin.

-- Functions
function clearscreen()
term.clear()
term.setCursorPos( 12, 1 )
write ( "Advanced Tunnel" )
term.setCursorPos( 2, 12 )
write ( "v1.0" )
term.setCursorPos( 16, 12 )
write ( "Designed by Henness" )
term.setCursorPos( 1, 3 )
end
-- Questions
clearscreen()
while widthanswer == true do
print("Width of tunnel?")
width = read()
width = tonumber(width)
if width > 0 then
  if math.fmod(width, 2) == 0 then
   clearscreen()
   print( "Tunnel width must be odd." )
  else
   widthanswer = false
  end
elseif width == 0 then
  clearscreen()
  print( "The width can't be infinite." )
else
  clearscreen()
  print( "Tunnel width must be positive." )
end
end
MysticT #2
Posted 01 April 2012 - 01:40 PM
The function tonumber() returns nil when it can't convert to number (like when you give it letters), so you should check that:

local num = tonumber(read())
if num == nil then
  print("Enter a number please.")
else
  print("The number is: ", num)
end
Henness #3
Posted 01 April 2012 - 09:16 PM
Thanks that worked!
Anora #4
Posted 23 February 2013 - 02:05 PM
I am geting this error on my script as well was working fine till just today. what could caus it to bork all of a sudent?
theoriginalbit #5
Posted 23 February 2013 - 02:10 PM
I am geting this error on my script as well was working fine till just today. what could caus it to bork all of a sudent?
No way to know without seeing your code, since you didn't provide either it or a link to your code. We aren't mind readers ;)/>
Leijssen #6
Posted 02 June 2013 - 03:50 PM
Sorry to bumb into this old thread, but I also get this error, I know what is causing it but I don't know how to fix it.

when slc is set to 1 or anything else, any keystroke will cause this error and interrupt the loop because it only accepts mouse_click.

Also, it would be nice if paint and edit just closes when an invalid directory is entered or perhaps popup a dialog ^_^/>


--snowfox os (origionally gmod E2 consolescreen OS)
--by "Vadim" Savchenko
diskdriveside = "bottom"
theme = colors.orange
default = "wallpaper"
box1 = paintutils.loadImage("defaultbox1")
box2 = paintutils.loadImage("defaultbox2")
box3 = paintutils.loadImage("defaultbox3")
box4 = paintutils.loadImage("defaultbox4")
slc = 0
term.setBackgroundColor(colors.gray)
term.clear()
term.setCursorPos(10,8)
term.setTextColor(colors.orange)
print("snowFOX 1.0 is loading for you!")
function usIn()
term.setCursorPos(1,1)
term.setBackgroundColor(theme)
term.clearLine()
term.setCursorPos(1,1)
term.setTextColor(colors.black)
print("[  HOME  ]")
term.setBackgroundColor(colors.lightGray)
term.setCursorPos(46,1)
local time = os.time()
print (" "..textutils.formatTime(time, true))
end
function initDesk()
term.clear()
wallpaper = paintutils.loadImage(default) --change wallpaper here
paintutils.drawImage(wallpaper, 1, 1)
term.setBackgroundColor(colors.lightGray)
usIn()
end
function homeMenu()
term.setTextColor(256)
term.setBackgroundColor(colors.brown)
term.setCursorPos(1,2)
print("Options   ")
term.setCursorPos(1,3)
print("Music	 ")
term.setCursorPos(1,4)
print("Quickedit ")
term.setCursorPos(1,5)
print("Paint	 ")
term.setCursorPos(1,6)
print("Pastebin  ")
term.setCursorPos(1,7)
print("Programs  ")
term.setCursorPos(1,8)
print("X-term	")
term.setCursorPos(1,9)
print("Leave	 ")
usIn()
end
function music()
paintutils.drawImage(box1, 18,7)
term.setCursorPos(18,7)
term.setBackgroundColor(colors.orange)
print(" Music")
term.setCursorPos(35,7)
term.setBackgroundColor(colors.red)
print("X")
term.setCursorPos(19,9)
term.setBackgroundColor(colors.yellow)
peripheral.wrap(diskdriveside)
if disk.hasAudio(diskdriveside) then
  paintutils.drawImage(box2, 18,7)
  term.setCursorPos(18,7)
  term.setBackgroundColor(colors.orange)
  print(" Music")
  term.setCursorPos(35,7)
  term.setBackgroundColor(colors.red)
  print("X")
  term.setCursorPos(19,9)
  term.setBackgroundColor(colors.yellow)
  name = disk.getAudioTitle(diskdriveside)
  print(name)
  term.setCursorPos(19,11)
  print("PLAY		STOP")
  slc = 3
else
  print("No disk or drive")
  term.setBackgroundColor(colors.lightGray)
  slc = 1
end
end
function leave()
paintutils.drawImage(box1, 18,7)
term.setCursorPos(18,7)
term.setBackgroundColor(colors.orange)
print(" Leave")
term.setCursorPos(35,7)
term.setBackgroundColor(colors.red)
print("X")
term.setCursorPos(19,9)
term.setBackgroundColor(colors.yellow)
print("Restart  Turnoff")
slc = 2
end
function terminal()
paintutils.drawImage(box1, 18,7)
term.setCursorPos(18,7)
term.setBackgroundColor(colors.orange)
print(" Kill x-server?")
term.setCursorPos(35,7)
term.setBackgroundColor(colors.red)
print("X")
term.setCursorPos(19,9)
term.setBackgroundColor(colors.yellow)
print(" Yes		 No ")
slc = 4
end
function editFile()
paintutils.drawImage(box3, 18,7)
term.setCursorPos(18,7)
term.setBackgroundColor(colors.orange)
print(" Edit file")
term.setCursorPos(35,7)
term.setBackgroundColor(colors.red)
print("X")
term.setCursorPos(19,9)
term.setBackgroundColor(colors.yellow)
print("Directory:")
term.setCursorPos(19,11)
term.setBackgroundColor(colors.white)
input = read()
if input == "" then
  initDesk()
  slc = 0
end
shell.run("edit", input)
initDesk()
usIn()
slc = 0
end
function paintFile()
paintutils.drawImage(box3, 18,7)
term.setCursorPos(18,7)
term.setBackgroundColor(colors.orange)
print(" Paint file")
term.setCursorPos(35,7)
term.setBackgroundColor(colors.red)
print("X")
term.setCursorPos(19,9)
term.setBackgroundColor(colors.yellow)
print("Directory:")
term.setCursorPos(19,11)
term.setBackgroundColor(colors.white)
input = read()
if input == "" then
  initDesk()
  slc = 0
end
shell.run("paint", input)
initDesk()
usIn()
slc = 0
end
function options()
paintutils.drawImage(box4, 18,6)
term.setCursorPos(18,6)
term.setBackgroundColor(colors.orange)
print(" Preferences")
term.setCursorPos(37,6)
term.setBackgroundColor(colors.red)
print("X")
term.setCursorPos(19,8)
term.setBackgroundColor(colors.yellow)
print("Change wallpaper")
term.setCursorPos(19,10)
print("Change windowcolor")
slc = 5
end
initDesk()
--snowFOX kernel
while true do
local event, button, X, Y = os.pullEventRaw()
if slc == 0 then
  if event == "mouse_click" then
   if X >=1 and X <=10 and Y==1 and button ==1 then
	homeMenu()
	slc = 1
   else
	initDesk()
   end
  end
elseif slc == 1 then
  if X >=1 and X <=11 and button == 1 and Y== 3 then
   music()
  elseif X >=1 and X <=11 and button == 1 and Y== 9 then
   leave()
  elseif X >=1 and X <=11 and button == 1 and Y== 8 then
   terminal()
  elseif X >=1 and X <=11 and button == 1 and Y== 4 then
   editFile()
  elseif X >=1 and X <=11 and button == 1 and Y== 5 then
   paintFile()
  elseif X >=1 and X <=11 and button == 1 and Y== 2 then
   options()
  else
   initDesk()
   slc = 0
  end
elseif slc == 2 then
  if X >= 18 and X <= 25 and Y == 9 and button == 1 then
   os.reboot()
  elseif X >= 28 and X <= 34 and Y == 9 and button == 1 then
   os.shutdown()
  else
   term.setBackgroundColor(colors.lightGray)
   initDesk()
   slc = 0
  end
elseif slc == 3 then
  if X >= 18 and X <= 25 and Y == 11 and button == 1 then
   disk.playAudio(diskdriveside)
  elseif X >= 28 and X <= 34 and Y == 11 and button == 1 then
   disk.stopAudio(diskdriveside)
  else
   term.setBackgroundColor(colors.lightGray)
   initDesk()
   slc = 0
  end
elseif slc == 4 then
  if X >= 18 and X <= 25 and Y == 9 and button == 1 then
   term.setBackgroundColor(colors.black)
   term.clear()
   term.setCursorPos(1,1)
   term.setTextColor(colors.white)
   print("Have fun!")
   term.setTextColor(32)
   term.setCursorPos(46,1)
   print("[ OK ]")
   return(0)
  elseif X >= 28 and X <= 34 and Y == 9 and button == 1 then
   term.setBackgroundColor(colors.lightGray)
   initDesk()
   slc = 0
  else
   term.setBackgroundColor(colors.lightGray)
   initDesk()
   slc = 0
  end
elseif slc == 5 then
  if X >= 19 and X <= 34 and Y == 8 and button == 1 then
   term.setCursorPos(19,12)
   input2 = read()
   if input2 == "" then
	initDesk()
	slc = 0
   end
   term.setBackgroundColor(colors.lightGray)
   default = input2
   initDesk()
   usIn()
   slc = 0
  elseif X >= 28 and X <= 34 and Y == 11 and button == 1 then
   --mumble muble
  else
   initDesk()
   slc = 0
  end
else
   term.setBackgroundColor(colors.lightGray)
   initDesk()
   slc = 0
end  --ends continuament mouse input
end  --ends the while loop
Bomb Bloke #7
Posted 02 June 2013 - 07:01 PM
You're doing this:

local event, button, X, Y = os.pullEventRaw()
if slc == 0 then
  if event == "mouse_click" then
    -- Do stuff because we have a "mouse_click" event
  end
elseif slc == 1 then
  -- No check for the event type this time?
  -- Do stuff related to a "mouse_click" event that might not exist...
elseif slc == 2 then
  -- etc

Instead do this:

local event, button, X, Y = os.pullEventRaw()
if event == "mouse_click" then
  if slc == 0 then
    -- Do stuff because we have a "mouse_click" event
  elseif slc == 1 then
    -- Do stuff because we have a "mouse_click" event
  elseif slc == 2 then
    -- etc

Or this:

local event, button, X, Y = nil, nil, nil, nil
while event ~= "mouse_click" do event, button, X, Y = os.pullEventRaw() end
if slc == 0 then
  -- Do stuff because we have a "mouse_click" event
elseif slc == 1 then
  -- Do stuff because we have a "mouse_click" event
elseif slc == 2 then
  -- etc

Or, if you don't need to pull raw events:

local event, button, X, Y = os.pullEvent("mouse_click")
if slc == 0 then
  -- Do stuff because we have a "mouse_click" event
elseif slc == 1 then
  -- Do stuff because we have a "mouse_click" event
elseif slc == 2 then
  -- etc
theoriginalbit #8
Posted 03 June 2013 - 01:02 AM
Or, if you don't need to pull raw events:
Even with raw events you can specify a filter.


local event, button, X, Y = os.pullEventRaw("mouse_click")

The reason for the raw pull event is it doesn't detect and handle the "terminate" event. However when specifying a filter it doesn't matter anyway as it will not return to the Lua code until that filter has been triggered, even if there are terminate events in the mix.
Bomb Bloke #9
Posted 03 June 2013 - 10:18 AM
So os.pullEventRaw can take parameters like os.pullEvent can, but doing so takes the point out of using os.pullEventRaw? Both good facts to know, thanks.

I'll have to make a wiki account at this rate.
Leijssen #10
Posted 03 June 2013 - 10:35 AM
You're doing this:

local event, button, X, Y = os.pullEventRaw()
if slc == 0 then
  if event == "mouse_click" then
	-- Do stuff because we have a "mouse_click" event
  end
elseif slc == 1 then
  -- No check for the event type this time?
  -- Do stuff related to a "mouse_click" event that might not exist...
elseif slc == 2 then
  -- etc

Instead do this:

local event, button, X, Y = os.pullEventRaw()
if event == "mouse_click" then
  if slc == 0 then
	-- Do stuff because we have a "mouse_click" event
  elseif slc == 1 then
	-- Do stuff because we have a "mouse_click" event
  elseif slc == 2 then
	-- etc

So basically every time when slc == x I have to check for the "mouse_click" event again. like

while true do
local event, button, X, Y = os.pullEventRaw("mouse_click")
	if slc == 0 then
		if event == "mouse_click" then
			if X >=1 and X <=10 and Y==1 and button ==1 then
				--mumble mumble
			end
		end
	elseif slc == 1 then
		if event=="mouse_click" then
			if X >=1 and X <=11 and button == 1 and Y== 3 then
				--mumble mumble
			end
		end
	 else
		 --etc
	 end
end

instead of the imaginary mouse_button response

And thanks guys for all your help!
theoriginalbit #11
Posted 03 June 2013 - 10:55 AM
So os.pullEventRaw can take parameters like os.pullEvent can, but doing so takes the point out of using os.pullEventRaw? Both good facts to know, thanks.
I'll have to make a wiki account at this rate.
You don't need a wiki account to learn all this. Reading source can be ever so helpful… This is the code for os.pullEvent and os.pullEventRaw (taken from bios.lua)
Spoiler

function os.pullEventRaw( _sFilter )

  return coroutine.yield( _sFilter )
end

function os.pullEvent( _sFilter )
  local eventData = { os.pullEventRaw( _sFilter ) }
  if eventData[1] == "terminate" then
    error( "Terminated", 0 )
  end
  return unpack( eventData )
end
Bomb Bloke #12
Posted 03 June 2013 - 10:56 AM
I'm well aware I don't need a wiki account to "learn". But if I don't wish others to make the same mistakes I did - eg, believing the wiki when it tells me that os.pullEventRaw doesn't use parameters - well, an account may come in useful for editing purposes. ;)/>

So basically every time when slc == x I have to check for the "mouse_click" event again.
Er, no, that one wasn't on my list of suggestions.

Or rather, you can do it that way too, but it's much more efficient to perform one single check for the event type. It's where that check is performed that matters.