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

assistance with table converted to variable

Started by kain184, 24 January 2015 - 01:50 AM
kain184 #1
Posted 24 January 2015 - 02:50 AM
having a bit of an issue i'm using open peripheral to look at the contents of a chest. i am trying to find if any of the slots have items and to set a veriable as the slot number as such

c1=peripheral.wrap("ender_chest_0")
j=c1.getInvintorySize()
-------------------------------------------------------
function itemC1()
  for i=1,j do
  local disp,qty,dmg,max,size,raw,id,name,mod=c1.getStackInSlot(i)
  local sizen,sizet=size-- trying to seperate out the return from size
  print(sizet)
  print(size)
    if  sizet > 0 then
    Slot=i
	  return true  -- Function ends if the "return" statement is triggered.
    end
  endprint
  return false   -- If none of the slots already prompted a return of "true",
end	

the problem i am having is in the return from getstackinslot of size or qty returns first a nil than the number of the stack but i can only read the nil value so all my true false tests fail with a nil can anyone help me get the information i am needing.
KingofGamesYami #2
Posted 24 January 2015 - 03:18 AM
I'm not exactly sure what your issue is.

if/then statements look for false and nil as an indicator.

For example:

local b = nil
if b then
  print( "True!" )
else
  print( "False!" )
end

That will print False!

Or this:


local b = "hello"
if b then
  print( "True!" )
else
  print( "False!" )
end

Which will print True!

Notice I'm not using ==. Since == is simply a comparison that returns true/false, we don't always need to use it.


local word = "hi"
local wordIsHi = (word == "hi")
if wordIsHi then
   print( "The word was hi" )
else
   print( "The word wasn't hi" )
end
kain184 #3
Posted 24 January 2015 - 03:22 AM
the issue is the return of size or qty is as fallows
nil
1
the true false statement only reads the nil while i am trying to read the 1
and i cant find a way to make it read the 1 and not the nil which i dont want. becouse i am trying to find if in i there is any item so it will set slot to i for a later test of what is in the slot.
KingofGamesYami #4
Posted 24 January 2015 - 03:27 AM
Um, what? A function is returning two values into a single variable? That isn't possible. Unless they are a table. In which case you should serialize the table, then print it, to know what keys to access.
HPWebcamAble #5
Posted 24 January 2015 - 03:27 AM
EDIT:
King is right, see his post below


————————————————-
Ok, a theres a few things I see here

You spelled inventory wrong

j=c1.getInvintorySize()

This should error since it isn't doing anything

endprint

And you might be missing an 'end' somewhere

But to answer your question (if I understand correctly), this is what you need:

Instead of:

local sizen,sizet=size

Use:

local sizen = size[1]
local sizet = size[2]

Is this what you want?

So this would be the result:

c1=peripheral.wrap("ender_chest_0")
j=c1.getInventorySize()

function itemC1()
  for i=1,j do
	local disp,qty,dmg,max,size,raw,id,name,mod=c1.getStackInSlot(i)
	local sizen = size[1]
	local sizet = size[2]
	print(sizet)
	print(size)
	if  sizet > 0 then
	   Slot=i
	   return true
	end
  end
  return false
end	
Edited on 24 January 2015 - 03:35 AM
kain184 #6
Posted 24 January 2015 - 03:49 AM
the typo is becouse i retyped that real qick its right in my code. and is it possible for it to have a table called that contains another table like that and i tried what you put at the end still gives me a nil but when i run the command c1.getStackInSlot(i) is whats in the picture i guess i need to look for qty insted of size got that mixed up but it still gives me the other photo
KingofGamesYami #7
Posted 24 January 2015 - 04:29 AM
Oh, I see what the problem is. c1.getStackInSlot( 1 ) returns a table, not multiple values.


local tbl = c1.getStackInSlot( 1 )
disp = tbl.display_name
qty = tbl.qty
--#etc.
Bomb Bloke #8
Posted 24 January 2015 - 05:47 AM
Or:

local disp,qty,dmg,max,size,raw,id,name,mod = unpack(c1.getStackInSlot(i))

Though personally I'd just leave the data in table form.

the issue is the return of size or qty is as fallows
nil
1

To clarify: you're reading that wrong. That extra 1 is the result of calling print(qty) in the Lua command prompt.

The Lua prompt runs the command - which in this case, happens to print an empty line, because qty is nil - then also prints anything the command returned. The print function returns 1, because you asked it to print one line - that figure has nothing to do with the number of items in a chest slot!
kain184 #9
Posted 25 January 2015 - 08:14 AM
but qty should not be nil as there is a bucket in the first slot in the chest and name tells me so . but i did get the info i wanted using

Oh, I see what the problem is. c1.getStackInSlot( 1 ) returns a table, not multiple values.


local tbl = c1.getStackInSlot( 1 )
disp = tbl.display_name
qty = tbl.qty
--#etc.
sorry for the delayed reply.
however i am now getting a new error that i have been working on and its still illuding me where my issue is coming from

bact=peripheral.wrap("ender_chest_4")
tact=peripheral.wrap("ender_chest_0")
c1=peripheral.wrap("crystal_2")
bMax=bact.getInventorySize()
tMax=tact.getInventorySize()
mon=peripheral.find("monitor")
-------------------------------------
function bactPush(Dirct,Slot,reqName)
for i=1,bMax do
  local info=bact.getStackInSlot(i)
  local itemqty= info.qty
  local itemName=info.name
  print(info)
  print(itemqty)
  print(itemName)
   if itemqty > 0 and itemName==reqName then
   print("true")
    bact.pushItem(Dirct,Slot,1,1)
    return true
    else
   
   end
  return false
end
end
------------------------------------
function tactPush(Dirct,Slot,reqName)
for i=1,tMax do
  local info=tact.getStackInSlot(i)
  local itemqty= info.qty
  local itemName= info.name
   if itemqty > 0 and itemName==reqName then
    tact.pushItem(Dirct,1,Slot)
    return true
    else
    return false
   end
end
end
-----------------------------------------------------
function rT(side,color)
rs.setBundledOutput(side,color)
sleep(1)
rs.setBundledOutput(side,0)
end
-----------------------------------------------------
function bactPull(Side,Slot,reqName)
bact.pullItem(Side,Slot)
sleep(1)
  for i=1,bMax do
   local info=bact.getStackInSlot(i)
   local itemName=info.name -- error is here says attempt to index ? nil when water bucket is in slot 1
    while not itemName==reqName do
	 bactPush("down",1,"bucket")
	 bact.pullItem(Side,Slot)
	 local info=bact.getStackInSlot(i)
	 local itemName=info.name
    end
  end
end
----------------------------------------------------
function tactPull(Side,Slot,reqName)
tact.pullItem(Side,Slot)
  for i=1,bMax do
   local info=bact.getStackInSlot(i)
   local itemName=info.name
    while not itemName==reqName do
	 tactPush("down",1,"bucket")
	 tact.pullItem(Side,Slot)
	 local info=tact.getStackInSlot(i)
	 local itemName=info.name
    end
  end
end
-----------------------------------------------------
function Disp()
sleep(5)
bactPush("down",1,"bucket")
rT("bottom",colors.red)
bactPull("up",1,"water_bucket")
tactPush("down",1,"water_bucket")
rt("bottom",colors.brown)
tactPull("up",1,"bucket")
end
-----------------------------------
Disp()
my code so far.
Edited on 25 January 2015 - 07:20 AM
Bomb Bloke #10
Posted 25 January 2015 - 08:30 AM
but qty should not be nil as there is a bucket in the first slot in the chest and name tells me so .

But you took all the data relating to that slot and dumped it into a single variable, "disp" - leaving the likes of "qty" as nil. The code Yami and I gave you serves to spread it out over the rest of your variables.

however i am now getting a new error that i have been working on and its still illuding me where my issue is coming from

You're not just checking the first slot there - you're checking EVERY slot in the inventory, so unless you've got every slot filled, your code's going to crash.

Don't attempt to index into the "info" table unless you're sure it exists. Refer to the examples Yami gave you here.
kain184 #11
Posted 25 January 2015 - 03:45 PM
i guess i need to stick to keep it simple stupid a bit more. i dont realy need the for statements in this function anyway but to get it to fuction the way i was thinking i would have just needed to put a return so it did not go past the first slot that matched i was looking at that code for the future. but relized with how my build needs to be set up that i needed that on a diffrent peripheral anyway . but something in my code is buggy again you said that the for loop will check every slot in the invintory as it runs through slots 1 through max number. is that right.
Bomb Bloke #12
Posted 26 January 2015 - 01:50 AM
you said that the for loop will check every slot in the invintory as it runs through slots 1 through max number. is that right.

Yes, though it sounds like you only want it to check the slot that the function was asked to check, sorta like this:

function bactPull(Side,Slot,reqName)
	while true do
		local info = bact.getStackInSlot(Slot)
		
		if info then  -- If there's something in the slot,
			if info.name == reqName then  -- If that something matches what was requested already,
				return                -- ... exit the function.
			else
				repeat
					bactPush("down",1,info.name)  -- ... attempt to get rid of it,
				until not bact.getStackInSlot(Slot)   -- ... until there's nothing in the slot anymore.
			end
		end

		-- If we reach this point we know nothing's in the slot, so...
		while not bact.pullItem(Side,Slot) do end  -- ... keep sucking until we get something.
	end
end

I'm sorta going by memory - I'm pretty sure bact.pullItem() should return true if it gets something. Ideally you'd want to alter this further so that it either starts trying to pull/push using different slots, or perhaps even throws an error, if the requested action just isn't possible.