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

Sorting system - Website / Interactive sorter

Started by W00dyR, 12 January 2013 - 05:15 AM
W00dyR #1
Posted 12 January 2013 - 06:15 AM
Hey, I am trying to make a script that allows me to call a simple file from my website, I will use this data for setting up an interactive sorter from the miscPheripherals mod (I think, might be wrong =.=).

I have no idea where to get started on this pretty much, so I started on calling from a simple file from my website, the file is just called "test" and has no extension. The thing that is on this site is this:


100 cobblestone 1
200 dirt 2
300 gravel 3

The way I will use this is (still have to edit the first part according to the interactive sorter), but I want it to see it as:

[Item ID from the interactive sorter] [Name it will be given] [Chest number to go into]

so I got started with looking around and trying to get it to put the stuff from the website into a table. This is where my first problem shows up, I have no idea how to do this. I wrote the following script:


website = http.get("http://www.nowebsiteforyou.com/ftb/test")
print(website.readAll()) -- check if it even sees the website


itemtable = { }
table.insert(itemtable,website)

itemtest = itemtable[1]
itemtest2 = itemtable[2]
print(itemtest)
print(itemtest2)

As you pro's will look at this, you will probably facepalm, but as I said, I have no idea what I'm doing. I also read something about "ipairs" but I can't seem to understand what they exactly are, and the way you use them what every part does :/ So if you suggest that, please explain with it how it works :)/>

Also small note: Again, I am a starter with all this, I've only wrote basic scripts and nothing really complicated so this is my first real big project so please, please explain every single part :P/>

Thanks ahead! :)/>
Lyqyd #2
Posted 12 January 2013 - 06:45 AM
After itemTable declaration:


--get the first line
local line = website.readLine()
--as long as it is not nil (the file still has stuff in it)
while line do
  --add the line to the table of lines
  table.insert(lineTable, line)
  --get the next line
  line = website.readLine()
end
remiX #3
Posted 12 January 2013 - 06:54 AM
I have no idea where to get started on this pretty much, so I started on calling from a simple file from my website, the file is just called "test" and has no extension. The thing that is on this site is this:


100 cobblestone 1
200 dirt 2
300 gravel 3

The way I will use this is (still have to edit the first part according to the interactive sorter), but I want it to see it as:

[Item ID from the interactive sorter] [Name it will be given] [Chest number to go into]

If you want each to have 3 information like so, you would probably need to add a table for each block, so something like this:


itemTable = {
	{itemID = 100, name = "cobblestone", chest = 1},
	{itemID = 200, name = "dirt", chest = 2},
	{itemID = 300, name = "gravel", chest = 3},
}

What you could do use use string.find and string.sub to separate each line from the website into three different parts, or use this split function:



function splitLine(text)
  local line = {} --Define a empty table for our words
  for word in string.gmatch(text, "%w+")  -- Go the the string word by word ("%w+") and give one word at a time the value word
	table.insert(line, word) --WE take our word and put it in the table line.
  end --end our for loop
  return line
end

And then call it it like this,


line = website.readLine() -- read the line from the website...
tableToAdd = splitLine(text)
table.insert(itemtable, tableToAdd)

Although this will just add it like this:


{"100", "cobblestone", "1"}
Cranium #4
Posted 12 January 2013 - 06:58 AM
But you can convert the numbers before adding them to the table just by adding to the line

table.insert(line, tonumber(word))
--it will change it to a number if possible, otherwise it will keep it a string.
remiX #5
Posted 12 January 2013 - 07:09 AM
But you can convert the numbers before adding them to the table just by adding to the line

table.insert(line, tonumber(word))
--it will change it to a number if possible, otherwise it will keep it a string.

Really? I'm sure last time i tried that it error'd out when it tried to tunumber a string that isn't a number. Cool

edit: fixed post, quoted twice for some reason
Lyqyd #6
Posted 12 January 2013 - 07:22 AM
That's not how tonumber works–it returns nil if it cannot convert it to a number. You'd want to replace the tonumber(word) with: tonumber(word) or word
W00dyR #7
Posted 12 January 2013 - 07:29 AM
Alright, so I read through the comments and I pretty much copied remiX's stuff and this is what I have now.


website = http.get("http://www.blabla.com/ftb/test")
print(website.readAll())


itemtable = { }

function splitLine(text)
local line = { }
for word in string.gmatch(text, "%w+")
  table.insert(line,word)
end
return line
end


line = website.readLine()
tableToAdd = splitLine(text)
table.insert(itemtable, tableToAdd)

itemtest = itemtable[1]
itemtest2 = itemtable[2]


print(itemtest)
print(itemtest2)

But the error it gives me:


webtest:8: bad argument #1 to string.gmatch (string expected, got nil)

Since I am unfamiliar with the string.gmatch stuff, I dont know how to fix it (I dont even know what it does actually :/)



EDIT: I also tried the function like this:


function splitLine(text)
local line = { }
for word in string.gmatch(text, "%w+")
  table.insert(line, tonumber(word) or word)
end
return line
end

which gives me the same error, again, I am not familiar with all this so I am just trying stuff I read :P/>
remiX #8
Posted 12 January 2013 - 07:31 AM
That's not how tonumber works–it returns nil if it cannot convert it to a number. You'd want to replace the tonumber(word) with: tonumber(word) or word

That's what I thought.

Btw W00dyR, if you did want it to be in this format:
{itemID = 100, name = "cobblestone", chest = 1}

You could try change the splitLine function to this (if each line only has 3 pieces of information



function splitLine(text)
  local line = {} --Define a empty table for our words
  for word in string.gmatch(text, "%w+")  -- Go the the string word by word ("%w+") and give one word at a time the value word
        table.insert(line, tonumber(word) or word) --WE take our word and put it in the table line.
  end --end our for loop
  return {itemID = line[1], name = line[2], chest = line[3]} -- separates each piece
end

Not entirely sure if that'll work, though
Lyqyd #9
Posted 12 January 2013 - 07:33 AM
Alright, so I read through the comments and I pretty much copied remiX's stuff and this is what I have now.


website = http.get("http://www.blabla.com/ftb/test")
print(website.readAll())


itemtable = { }

function splitLine(text)
local line = { }
for word in string.gmatch(text, "%w+")
  table.insert(line,word)
end
return line
end


line = website.readLine()
tableToAdd = splitLine(text)
table.insert(itemtable, tableToAdd)

itemtest = itemtable[1]
itemtest2 = itemtable[2]


print(itemtest)
print(itemtest2)

But the error it gives me:


webtest:8: bad argument #1 to string.gmatch (string expected, got nil)

Since I am unfamiliar with the string.gmatch stuff, I dont know how to fix it (I dont even know what it does actually :/)



EDIT: I also tried the function like this:


function splitLine(text)
local line = { }
for word in string.gmatch(text, "%w+")
  table.insert(line, tonumber(word) or word)
end
return line
end

which gives me the same error, again, I am not familiar with all this so I am just trying stuff I read :P/>

This is also still missing the loop structure that would make it handle more than just the first line of the file.
remiX #10
Posted 12 January 2013 - 07:38 AM
Yeah, it happens because you read the entire website which and now if you readLine() it doesn't read anything because it has already read the entire website.

Do this to insert the website information into a table:


t_website = {}

line = website.readLine()
while line do
  table.insert(t_website, line)
  line = website.readLine()
end

-- To print all of it:

for i = 1, #t_website do
   print(t_website[i])
end
W00dyR #11
Posted 12 January 2013 - 07:39 AM
This is also still missing the loop structure that would make it handle more than just the first line of the file.

can I solve this with a simple while true loop?


line = website.readLine()
while line do
tableToAdd = splitLine(text)
table.insert(itemtable, tableToAdd)
line = website.readLine()
end

something like that what you posted before?
remiX #12
Posted 12 January 2013 - 07:44 AM
This is also still missing the loop structure that would make it handle more than just the first line of the file.

can I solve this with a simple while true loop?


line = website.readLine()
while line do
tableToAdd = splitLine(text)
table.insert(itemtable, tableToAdd)
line = website.readLine()
end

something like that what you posted before?

Yeah that should work, but change 'text' into 'line' within the splitLine(text)
W00dyR #13
Posted 12 January 2013 - 07:45 AM
Yeah, it happens because you read the entire website which and now if you readLine() it doesn't read anything because it has already read the entire website.

Do this to insert the website information into a table:


t_website = {}

line = website.readLine()
while line do
  table.insert(t_website, line)
  line = website.readLine()
end

-- To print all of it:

for i = 1, #t_website do
   print(t_website[i])
end

So using this, it will store an entire line in one space in the table, if I call it it gives me the full line, is there a simple way to seperate these so if I call for the t_website[1] it only returns 100, and not 100 cobblestone 1 ?
W00dyR #14
Posted 12 January 2013 - 07:50 AM
This is also still missing the loop structure that would make it handle more than just the first line of the file.

can I solve this with a simple while true loop?


line = website.readLine()
while line do
tableToAdd = splitLine(text)
table.insert(itemtable, tableToAdd)
line = website.readLine()
end

something like that what you posted before?

Yeah that should work, but change 'text' into 'line' within the splitLine(text)

I feel so stupid, but I tried changing them and I cant get it to print the things I want it to print for testing purposes, it just prints a blank space :/
remiX #15
Posted 12 January 2013 - 07:55 AM
Try this:

website = http.get("http://www.blabla.com/ftb/test")

itemtable = {}

function splitLine(text)
	local line = { }
	for word in string.gmatch(text, "%w+") do
		table.insert(line, tonumber(word) or word)
	end
	return {itemID = line[1], name = line[2], chest = line[3]} -- separates each piece
end

line = website.readLine()
while line do
tableToAdd = splitLine(line)
table.insert(itemtable, tableToAdd)
line = website.readLine()
end

--[[
To print each thing
]]

for i = 1, #itemtable do
print(itemtable[i].itemID)
print(itemtable[i].name)
print(itemtable[i].chest)
end
website.close()
W00dyR #16
Posted 12 January 2013 - 08:12 AM
Try this:

website = http.get("http://www.blabla.com/ftb/test")

itemtable = {}

function splitLine(text)
	local line = { }
	for word in string.gmatch(text, "%w+") do
		table.insert(line, tonumber(word) or word)
	end
	return {itemID = line[1], name = line[2], chest = line[3]} -- separates each piece
end

line = website.readLine()
while line do
tableToAdd = splitLine(line)
table.insert(itemtable, tableToAdd)
line = website.readLine()
end

--[[
To print each thing
]]

for i = 1, #itemtable do
print(itemtable[i].itemID)
print(itemtable[i].name)
print(itemtable[i].chest)
end
website.close()

Just tried it, it only prints out the first line:


100
cobblestone
1

I figured that for the other lines, it needs something that makes it so instead of itemID/name/chest, it will number those, so it will sort each line with the linenumber:

so the first line would be

itemID1 / name1 / chest1
100 cobblestone 1

and the second would be
itemID2 / name2 / chest2
200 dirt 2

but again, I'm learning and the way I would do it, is make a variable that gets set to 1 in the start, and for every line it reads it will add 1 to that counter, but I'm not sure how to incorporate all that + there would probably be an easier way?
remiX #17
Posted 12 January 2013 - 08:40 AM
Works fine for me?

I used this to test:

website = http.get("http://pastebin.com/raw.php?i="..textutils.urlEncode( "3gui83ne" ))

itemtable = {}

function splitLine(text)
	local line = { }
	for word in string.gmatch(text, "%w+") do
		table.insert(line, tonumber(word) or word)
	end
	return {itemID = line[1], name = line[2], chest = line[3]} -- separates each piece
end

line = website.readLine()
while line do
tableToAdd = splitLine(line)
table.insert(itemtable, tableToAdd)
line = website.readLine()
end

--[[
To print each thing
]]

for i = 1, #itemtable do
print(itemtable[i].itemID)
print(itemtable[i].name)
print(itemtable[i].chest)
end
website.close()

that pastebin website has this:

100 cobblestone 1
200 dirt 2
300 grass 3

Outcome was perfect, check attachment.
W00dyR #18
Posted 12 January 2013 - 08:51 AM
Works fine for me?

I used this to test:

website = http.get("http://pastebin.com/raw.php?i="..textutils.urlEncode( "3gui83ne" ))

itemtable = {}

function splitLine(text)
	local line = { }
	for word in string.gmatch(text, "%w+") do
		table.insert(line, tonumber(word) or word)
	end
	return {itemID = line[1], name = line[2], chest = line[3]} -- separates each piece
end

line = website.readLine()
while line do
tableToAdd = splitLine(line)
table.insert(itemtable, tableToAdd)
line = website.readLine()
end

--[[
To print each thing
]]

for i = 1, #itemtable do
print(itemtable[i].itemID)
print(itemtable[i].name)
print(itemtable[i].chest)
end
website.close()

that pastebin website has this:

100 cobblestone 1
200 dirt 2
300 grass 3

Outcome was perfect, check attachment.

Ahh apperently I accidently typed a capital W in website in the while loop, which caused it to not being able to read the other lines, noticed after a few times checking :P/>

Alright, thanks a lot everything, I got a little wiser, I'll most likely post a new topic with even more trouble making this soon :P/>
Lyqyd #19
Posted 12 January 2013 - 09:04 AM
If you have further questions about the same program, please simply add a post to this topic with the new question rather than posting a new topic.
W00dyR #20
Posted 12 January 2013 - 10:07 AM
Alright, so I've been playing around with the Interactive Sorters, doing some reading as well, I cannot find a single topic on these forums or anywhere else about these things, in Guude's videos I can see the codes but they dont show what I want :P/>

so my setup is a computer, with the sorter on top, with a chest on top of the sorter.

As I read in the topic of the mod that adds this, whenever the sorter sorts an item, it emits the event isort_item

I am trying to make it print this event when I run the sorter, but it doesn't get the event, which is I think because it doesnt pull the event from the sorter, but I dont know how to do this.

My code:


s = peripheral.wrap("top")
s.sort(1,2)
message = os.pullEvent()
print(message)
remiX #21
Posted 12 January 2013 - 10:19 AM
Hmm, well I've never ever heard of these things before so I have no clue about the events of it. Could you link the topic you're reading this off?

Maybe try restricting the os.pullEvent() to isort_item because right now, it'll continue with any event

message, p1, p2, p3 = os].pullEvent("isort_item")
W00dyR #22
Posted 12 January 2013 - 10:24 AM
Hmm, well I've never ever heard of these things before so I have no clue about the events of it. Could you link the topic you're reading this off?

Maybe try restricting the os.pullEvent() to isort_item because right now, it'll continue with any event

message, p1, p2, p3 = os].pullEvent("isort_item")


http://www.computercraft.info/forums2/index.php?/topic/4587-cc1481mc146-miscperipherals-23/


Scroll about 1/3rd down.

Also, whenever this program executes, it instantly sends away the item correctly and with this happening it should straight away give the event isort_item, so it shouldnt really mather I figured :/
remiX #23
Posted 12 January 2013 - 10:34 AM
Also, whenever this program executes, it instantly sends away the item correctly and with this happening it should straight away give the event isort_item, so it shouldnt really mather I figured :/

The Interactive Sorter can send an incoming item (into its inventory slot) into a specific direction. When an item enters the sorter, it emits event "isort_item", with the item identifier and amount as parameters. The item identifier is an universally unique ID identifying the item and its metadata. Exposes the following functions:

It says it only emits the event when an item enters the sorter not when it leaves it.

Edit:

Tested it now, and it pulled the event when I put the a glass inside it. Then took out of it, it didn't pull the event.
W00dyR #24
Posted 12 January 2013 - 10:39 AM
Also, whenever this program executes, it instantly sends away the item correctly and with this happening it should straight away give the event isort_item, so it shouldnt really mather I figured :/

The Interactive Sorter can send an incoming item (into its inventory slot) into a specific direction. When an item enters the sorter, it emits event "isort_item", with the item identifier and amount as parameters. The item identifier is an universally unique ID identifying the item and its metadata. Exposes the following functions:

It says it only emits the event when an item enters the sorter not when it leaves it.


Ahh, I was being stupid sorry, anyhow, now it does work and prints the message "isort_item". This message comes with parameters, how do I print those?
remiX #25
Posted 12 January 2013 - 10:44 AM
When you pull the event, you're only giving it one variable for it to set to which is the event,

message = os.pullEvent()

Add more parameters like this:

event, p1, p2, p3

print(event) -- isort_item
print(p1)
print(p2)