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

Item Data base

Started by how2doit, 13 February 2016 - 08:51 PM
how2doit #1
Posted 13 February 2016 - 09:51 PM
Hello, I've been trying for many hours to get my program to save data from an item in a turtles inventory to a file that can later be re-read but I've been having a lot of trouble I would appreciate it if you could help :D/>.
Code:
Spoilerif rs.getInput("right", true) then do
local data1 = turtle.getItemDetail(1)
if data1 then
print("Item name:", data1.name)
print("Item damage value:", data1.damage)
print("Item count:", data1.count)
sleep(1)
end
function save(table,data1)
local file = fs.open(data1, "w")
file.write(textutils.serialize(data1))
file.close()
end
end
else
function load(data1)
local file = fs.open(data1,"r")
local data = file.readAll()
file.close()
return textutils.unserialize(data)
end
print(data)
sleep(1)
end
Lupus590 #2
Posted 13 February 2016 - 10:57 PM
[.code] tags

Code, in code tags

if rs.getInput("right", true) then do
  local data1 = turtle.getItemDetail(1)
  if data1 then
	print("Item name:", data1.name)
	print("Item damage value:", data1.damage)
	print("Item count:", data1.count)
	sleep(1)
  end
  function save(table,data1)
	local file = fs.open(data1, "w")
	file.write(textutils.serialize(data1))
	file.close()
  end
end -- #no end with an else
else
  function load(data1)
	local file = fs.open(data1,"r")
	local data = file.readAll()
	file.close()
	return textutils.unserialize(data)
  end
  print(data)
  sleep(1)
end

two things, you have an end with an else in your if statement - I've commented this.
your functions are useless like that, are you trying to call (use) the functions? if so then define them at the top. http://lua-users.org...nctionsTutorial
Edited on 13 February 2016 - 10:05 PM
HPWebcamAble #3
Posted 13 February 2016 - 11:01 PM
First, use code tags on the forums, like this:
[.code] (No . though)



Second, indent your code to make it easier to read: http://www.computerc...608#entry166608

Regarding your code, I think I know where you were going with that, but that'll error when you run it.
This should work, if you just want to save and read the item in slot 1:

if rs.getInput("right") then

  local data1 = turtle.getItemDetail(1) --# Store the data
  if data1 then --# If there was an item to get data from

	print("Item name:", data1.name)
	print("Item damage value:", data1.damage)
	print("Item count:", data1.count)

	local f = fs.open("item-data","w") --# Open the file to write to
	f.write(textutils.serialize(data1)) --# Serialize the table (that means make it a string) and write it to the file
	f.close() --# Tell the file we are done writting to it, allow other programs to access it

	f = fs.open("item-data","r") --# Open it in read mode
	local data = textutils.unserialize( f.readAll() ) --# Read the text in the file, turn it into a table
	f.close() --# Close the file

	print(textutils.serialize(data)) --# Print the data, must be serialized again because printing a table makes no sense. Try it!

  else --# There was no data, since there wasn't an item

	print("No item in slot 1")

  end

end

If you are going to do it for every item in the inventory, you should use a for-loop.
Edited on 13 February 2016 - 10:03 PM
how2doit #4
Posted 13 February 2016 - 11:28 PM
Thank you, but i want it to where I can see the data even after i remove the item.
how2doit #5
Posted 14 February 2016 - 03:15 AM
OH and i'll be looking at this post for awhile because i'm going to be making the program more complex and useful
how2doit #6
Posted 14 February 2016 - 08:45 PM
I'm having trouble getting any data what so ever back can someone help?
Lupus590 #7
Posted 14 February 2016 - 08:57 PM
here is a partially complete item database which I made. I have no idea if this is in a working state, so best of luck in getting it working.
Spoiler
local fileName = "itemDB"
local dummyEvent = "dummyEvent"
local suckFunc = turtle.suckDown --easier then direction switch
local dropFunc = turtle.drop

local known = {}
--load the file
local file
local fileStr = ""
if fs.exists(fileName) then
  file = fs.open(fileName, "r")
  if not file then
	error("Can't load file",0)
  end
  fileStr = file.readAll()
  known = textutils.unserialize("{"..fileStr.."}")--presume unwrapped table
  file.close()
end

--data.name --string minecraft:stone
--data.damage --number int
file = fs.open(fileName, "w")
file.write(fileStr.."\n")
local exit = false
while not exit do
  if suckFunc() then
	local data = turtle.getItemDetail()
	if data then
	  --print(data.name.." "..data.damage)
	  if not (known[data.name] or known[data.name][data.damage]) then
		known[data.name] = {[data.damage] = true}
		file.write("[\""..data.name.."\"] = { [\""..data.damage.."\"] = true}\n")
		file.flush()
	  else
		print("already processed")
	  end
	end
	dropFunc()
  end
  os.queueEvent(dummyEvent)
  local event = {os.pullEventRaw()}
  if event[1] == "terminate" then
	exit = true
	file.close()
  end
end
Edited on 14 February 2016 - 07:58 PM
how2doit #8
Posted 14 February 2016 - 09:04 PM
it seems to get stuck doing something
Lupus590 #9
Posted 14 February 2016 - 09:36 PM
this my code that you are saying "get stuck"? if yes then it may be because the turtle is trying to suck an item from a chest. look at the top of the code.
how2doit #10
Posted 14 February 2016 - 10:43 PM
oh ok

Well it worked better this time but at line thirty it says attempt to call index a nil value
KingofGamesYami #11
Posted 14 February 2016 - 11:04 PM
If it's doing turtle.getItemDetail on an empty slot it's going to throw that error when it tries to use non-existant data. Just add a check if data is a table and that error will stop occurring.
how2doit #12
Posted 14 February 2016 - 11:14 PM
Side Question i cannot get this to work and i cannot figure out why it won't work i want this code to count every time it receives a redstone pulse, and break if i press e, but it will not work.
Code:

local x = 0
while true do
local event, key = os.pullEvent( "key" ) -- limit os.pullEvent to the 'key' event
if key ~= keys.e then
if rs.getInput("right", true) then
x = x+1
term.setCursorPos(1,1)
print(x)
else
end
elseif key == keys.e then -- if the key pressed was 'e'
break
end
end

If it's doing turtle.getItemDetail on an empty slot it's going to throw that error when it tries to use non-existant data. Just add a check if data is a table and that error will stop occurring.
Nope still have the same error even when all of it's slots are filled
Edited on 14 February 2016 - 10:09 PM
KingofGamesYami #13
Posted 14 February 2016 - 11:28 PM
Your line 30 looks like this, right?


          if not (known[data.name] or known[data.name][data.damage]) then

To fix it you presumably did not this:


          if data and not (known[data.name] or known[data.name][data.damage]) then

That code is not detecting redstone pulses, as it would only increment if redstone was on when you press a key other than 'e'.


local x = 0
while true do
  local event = {os.pullEvent()}
  if event[ 1 ] == "redstone" and rs.getInput( "right" ) then
    x = x + 1
    term.setCursorPos( 1, 1 )
    term.write( x )
  elseif event[ 1 ] == "key" and event[ 2 ] == keys.e then
    break
  end
end
how2doit #14
Posted 15 February 2016 - 12:14 AM
I know it wasn't detecting pulses but my setup only sends pulses
how2doit #15
Posted 15 February 2016 - 01:35 AM
Another Question, is it possible to have part of a program run in the background what i mean by this is like this if i wanted to run some program without any delays in it but also wanted to get a time value by something like this,

local y = 0
while true do
y = y+1
sleep(1)
and have that in the background not adding delay to some other code?
KingofGamesYami #16
Posted 15 February 2016 - 01:53 AM
Yes, in fact I wrote an API to make doing that much easier.

It's not necessary for most applications though, for most things you can simply use an existing asynchronous function. For example, if I wanted to write a loop that adds 1 to y every second, but also detects if someone presses 'x', I would do this:


local y, id = 0, os.startTimer( 1 )
while true do
  local event = {os.pullEvent()}
  if event[ 1 ] == "timer" and event[ 2 ] == id then
    id = os.startTimer( 1 )
    y = y + 1
  elseif event[ 1 ] = "key" and event[ 2 ] == keys.x then
    print( "X was pressed" )
  end
end
Edited on 15 February 2016 - 12:53 AM
how2doit #17
Posted 16 February 2016 - 02:04 AM
Okay i'l try that
how2doit #18
Posted 16 February 2016 - 10:24 PM
But back to my earlier statement i'm having trouble re-accessing and reading the data that i store with fs
KingofGamesYami #19
Posted 16 February 2016 - 11:25 PM
If you are referring to this code:
Spoiler
[.code] tags

Code, in code tags

if rs.getInput("right", true) then do
  local data1 = turtle.getItemDetail(1)
  if data1 then
	print("Item name:", data1.name)
	print("Item damage value:", data1.damage)
	print("Item count:", data1.count)
	sleep(1)
  end
  function save(table,data1)
	local file = fs.open(data1, "w")
	file.write(textutils.serialize(data1))
	file.close()
  end
end -- #no end with an else
else
  function load(data1)
	local file = fs.open(data1,"r")
	local data = file.readAll()
	file.close()
	return textutils.unserialize(data)
  end
  print(data)
  sleep(1)
end

two things, you have an end with an else in your if statement - I've commented this.
your functions are useless like that, are you trying to call (use) the functions? if so then define them at the top. http://lua-users.org...nctionsTutorial

…I'd say "Why are you unserializing a table, then printing it?". Serialized tables display their contents, otherwise you're just going to get the memory reference (eg "table: ######)