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

Rejecting bad inputs without crashing?

Started by Tassyr, 02 August 2015 - 07:21 PM
Tassyr #1
Posted 02 August 2015 - 09:21 PM

local monSide = "blank"
local redSide = "blank"
local code    = "0000"

term.clear()
term.setCursorPos(1,1)
print("Enter side of monitor:")
term.setCursorPos(1,2)
print("top, back, left, right, front, bottom.")
term.setCursorPos(1,3)
monSide = read():lower()


term.setCursorPos(1,5)
print("Enter Redstone output side:")
term.setCursorPos(1,6)
print("top, back, left, right, front, bottom")
term.setCursorPos(1,7)
redSide = read():lower()


term.setCursorPos(1,9)
print("Enter four digit code:")
term.setCursorPos(1,10)
code = read()

So that right there is the "housekeeping" for a keypad entry system that I'm trying to make. What I'm trying to find a way to do is to make it so you run the program the first time and it stores monitor side, redstone output side, and the code without you having to muck about in the lua script for it. Thing is- I know how to make it so that it'll reject inputs that aren't "top, bottom, left, right, front, back."

I even plan to make it so you can't double up by mistake.

But how on earth do I get it to require four digits for the passcode, but reject five or three, or letters?
HPWebcamAble #2
Posted 02 August 2015 - 09:29 PM
Are you fimiliar with loops?

Here's a simple repeat-loop for that:

local code --# Make things local when possible

repeat --# Executes the code in here until the condition is met
  code = read()
until #code == 4  --# The number sign / hashtag returns the number of letters in a string
Edited on 02 August 2015 - 07:29 PM
Tassyr #3
Posted 02 August 2015 - 09:32 PM
Are you fimiliar with loops?

Here's a simple repeat-loop for that:

local code --# Make things local when possible

repeat --# Executes the code in here until the condition is met
  code = read()
until #code == 4  --# The number sign / hashtag returns the number of letters in a string

That's AWESOME. I didn't know that. Thanks!

… Any chance there's a fancy trick like that for checking "top" "bottom" "left" "right" "front" "back" without comparing it to each one? I seem to be increasingly inexperienced. XD
flaghacker #4
Posted 02 August 2015 - 10:11 PM

--checks if table t contains value val
local function contains (t, val)
  for k, v in pairs (t) do
    if v == val then
      return true
    end
  end
  return false
end

local side

repeat
  side = read ()
until contains (rs.getSides (), side)

This will do the trick, unfortunately it's not that simple. It checks if the side is valid by checking if it's in the table returned by rs.getSides. To fully understand this code, you might want to read up on tables here.
KingofGamesYami #5
Posted 02 August 2015 - 11:09 PM
I'd do this instead:


local sides = {}
for k, v in pairs( rs.getSides() ) do
  sides[ v ] = true
end

local side
repeat
  side = read()
until sides[ side ]
Tassyr #6
Posted 03 August 2015 - 01:31 AM
I'd do this instead:


local sides = {}
for k, v in pairs( rs.getSides() ) do
  sides[ v ] = true
end

local side
repeat
  side = read()
until sides[ side ]

Can you explain what's going on there? Maybe some comments? Because I don't understand what those do…
KingofGamesYami #7
Posted 03 August 2015 - 02:31 AM
First, I make a new table.

Next, I iterate through the table returned by rs.getSides() (which includes all the sides of the computer), building a new table.

The new table would look like this, if manually created:


local sides = {
  right = true,
  left = true,
  --#etc.
}

Then, the repeat loop can simply check if sides[ side ] is true or not.
Edited on 03 August 2015 - 12:31 AM
Tassyr #8
Posted 03 August 2015 - 02:35 AM
First, I make a new table.

Next, I iterate through the table returned by rs.getSides() (which includes all the sides of the computer), building a new table.

The new table would look like this, if manually created:


local sides = {
  right = true,
  left = true,
  --#etc.
}

Then, the repeat loop can simply check if sides[ side ] is true or not.

I'm not trying to be dense. But I don't really know tables man. I'm relearning this after a year plus gap. Any chance you could just – comment what each piece of that above code does…?
KingofGamesYami #9
Posted 03 August 2015 - 03:36 AM
Sure, that's easily done!

local sides = {}
for k, v in pairs( rs.getSides() ) do --#iterate through the table returned by rs.getSides()
  sides[ v ] = true --#make sides[ v ] true, where v is a side (eg "right")
end

local side --#pre-define a variable local to the program
repeat
  side = read() --#define side as reed
until sides[ side ] --#the loop continues until sides[ side ] is true.  For example, if you typed "right", sides[ "right" ] is true, the loop ends.  If you types "rihgt", sides[ "rihgt" ] is nil, the loop continues.
Tassyr #10
Posted 03 August 2015 - 04:07 AM
Sure, that's easily done!

local sides = {}
for k, v in pairs( rs.getSides() ) do --#iterate through the table returned by rs.getSides()
  sides[ v ] = true --#make sides[ v ] true, where v is a side (eg "right")
end

local side --#pre-define a variable local to the program
repeat
  side = read() --#define side as reed
until sides[ side ] --#the loop continues until sides[ side ] is true.  For example, if you typed "right", sides[ "right" ] is true, the loop ends.  If you types "rihgt", sides[ "rihgt" ] is nil, the loop continues.

Thank you, that helps A LOT. :)/>
Tassyr #11
Posted 03 August 2015 - 04:18 AM
Sure, that's easily done!

local sides = {}
for k, v in pairs( rs.getSides() ) do --#iterate through the table returned by rs.getSides()
  sides[ v ] = true --#make sides[ v ] true, where v is a side (eg "right")
end

local side --#pre-define a variable local to the program
repeat
  side = read() --#define side as reed
until sides[ side ] --#the loop continues until sides[ side ] is true.  For example, if you typed "right", sides[ "right" ] is true, the loop ends.  If you types "rihgt", sides[ "rihgt" ] is nil, the loop continues.

Thank you, that helps A LOT. :)/>

Or not. It says: attempt to call nil on the line "for k, v in pairs( rs.getSides) ) do"
KingofGamesYami #12
Posted 03 August 2015 - 04:35 AM
You must have spelled something incorrectly. Make sure pairs and getSides are spelled correctly!
Tassyr #13
Posted 03 August 2015 - 04:38 AM
You must have spelled something incorrectly. Make sure pairs and getSides are spelled correctly!

I'm an idiot- I forgot to capitalize "Sides."