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

Showing Inventory Information on Monitor: change string/format

Started by SnowGolem, 26 September 2012 - 07:11 PM
SnowGolem #1
Posted 26 September 2012 - 09:11 PM
I have just begun tot start making a simple program with the help of tutorials and this forum. I have set up a ccSensor to show the content of two chests to a 4*8 monitor. Learnt a lot from codes that are available. The code is below:


os.unloadAPI("sensors")
os.loadAPI("/rom/apis/sensors")
--------------
m1=peripheral.wrap("left")
----------------------------
function printDict(data)
for i,v in pairs(data) do
  print(tostring(i).." - "..tostring(v))
end
end
--------------------------
while true do
------------------------
ctrl = sensors.getController()

data = sensors.getSensors(ctrl)
BB = data[1]
------------
data = sensors.getSensorInfo(ctrl,BB)
sensors.setSensorRange(ctrl,BB,"8")
-----------
data = sensors.getProbes(ctrl,BB)
InventoryContent = data [3]
-------------
data = sensors.getAvailableTargetsforProbe(ctrl,BB,InventoryContent)
--------------
BlueChest= data[1]
OrangeChest = data[2]
Redchest= data[3]
YellowChest= data[4]
--monitor left
term.redirect(m1)
term.clear()
m1.setCursorPos (1, 1)
m1.setTextScale(0.5)
--left up
data = sensors.getSensorReadingAsDict(ctrl,BB,BlueChest,InventoryContent)
printDict(data)
--left down
m1.setCursorPos (1, 25)
print"----------------------------------"
print"								  "
data = sensors.getSensorReadingAsDict(ctrl,BB,OrangeChest,InventoryContent)
printDict(data)
-------------------------------
sleep(.1)
end
-------------------------------

The problem is that the information shown is not the format i want. This:
1 - 35Xtile.Dirt@0
2 - 64Xitem.IngotGold@0
….
11 - 64Xtile.Log@2
12 - 34*tile.Rail@0

must go to:
35 Dirt
64 IngotGold

64 Log
34 Rail

I know there probably is a solution with 'string.match' but i think that does not go with 'print.Dict'.
Help is very much appreciated.
Lyqyd #2
Posted 27 September 2012 - 06:44 AM
Yes, you should use string.match() with the pattern matching to extract the number and name that you want. Something like:


local num, name = string.match(string, "(%d+)X%a+%.(%d+)")
SnowGolem #3
Posted 28 September 2012 - 08:39 AM
Thanks for the reply.

first step for me is to use your string to test it on a record. I wrote:


strng = "2 - 64*item.IngotGold@0"
num, name = string.match(strng, "(%d+)X%a+%.(%d+)")
print(num, name)

Then I get a blank line. What am i doing wrong?
Lyqyd #4
Posted 28 September 2012 - 05:47 PM
You had three entries with an 'X' and only one with an asterisk, so I assumed the Xs were correct. Are both used? If so, replace the X in the matching string with this: [X%*]

If only asterisks are used, replace the X with: %*

If neither of the above options, I'll need to see more strings to figure out what the actual pattern is. Basically, the reason it didn't work is that it matches certain things inside the string. If it can't find the pattern you specify, it will return nil. So when you provided a string with an asterisk where the pattern was expecting an X, it couldn't find the pattern in the string.

Edit: also, I malformed the pattern anyway. Try this if both X and * are used:


local num, name = string.match(string, "(%d+)[X%*]%a+%.(%a+)")
SnowGolem #5
Posted 28 September 2012 - 08:08 PM
Thanks! it was indeed the "X" instead of the asterisk. Making progress.

Now when I test the code in the -simplified- first program, It is:


os.unloadAPI("sensors")
os.loadAPI("/rom/apis/sensors")
--------------
function printDict(data)
for i,v in pairs(data) do
  print(tostring(i).." - "..tostring(v))
end
end
-------------
ctrl = sensors.getController()
------------
data = sensors.getSensors(ctrl)
BB = data[1]
----------
data = sensors.getSensorInfo(ctrl,BB)
----------
data = sensors.getProbes(ctrl,BB)
InventoryContent = data [3]
------------
data = sensors.getAvailableTargetsforProbe(ctrl,BB,InventoryContent)
------------
BlueChest= data[1]

data = sensors.getSensorReadingAsDict(ctrl,BB,BlueChest,InventoryContent)
num, name = string.match(data, "(%d+)[X%*]%a+%.(%a+)")
printdict (num, name)

Which returns the '38: bad argument. string expected, got table', Which I think is because The sensors.GetSensorReadingAsDict results in a table (dict is a sort of table, i read). So the string.match command gets data which it cannnot handle.

So I need some way to:
1. apply the string.match in the 'source' (which means changing this specific function in the api). This way all data is converted before it is in the table
2. or use some function to apply match.string to the whole table

Is my thinking as a 'non'-programmer correct and what is the best option? And could you help me on the way?
Lyqyd #6
Posted 28 September 2012 - 08:12 PM
Modify the printDict function. Use the string.match on v, then print the two values it returns. That should do it.
SnowGolem #7
Posted 28 September 2012 - 10:03 PM
Thanx, Lyqyd, Learning a lot, I am almost there :P/>/>. To understand your suggestion in printDict better i used the following lines with a preset table:


t = { [1] ="40Xtile.Log@2", [2] ="23Xitem.IngotGold@0", [3] ="78Xitem.Diamond@2" }
for i,v in pairs(t) do
print (string.match((tostring(i).." - "..tostring(v)),"(%d+)[X%*]%a+%.(%a+)"))
end

which returned
40Log
23Ingotgold
78Diamond

No all I need is 1 space to get:
40 log
23 Ingotgold
78 Diamond

Can this be fixed in your string.match(variable, "(%d+)[X%*]%a+%.(%a+)")? These matching patterns are just a little too complex for me yet.
Lyqyd #8
Posted 28 September 2012 - 10:12 PM
Thanx, Lyqyd, Learning a lot, I am almost there :P/>/>. To understand your suggestion in printDict better i used the following lines with a preset table:


t = { [1] ="40Xtile.Log@2", [2] ="23Xitem.IngotGold@0", [3] ="78Xitem.Diamond@2" }
for i,v in pairs(t) do
print (string.match((tostring(i).." - "..tostring(v)),"(%d+)[X%*]%a+%.(%a+)"))
end

which returned
40Log
23Ingotgold
78Diamond

No all I need is 1 space to get:
40 log
23 Ingotgold
78 Diamond

Can this be fixed in your string.match(variable, "(%d+)[X%*]%a+%.(%a+)")? These matching patterns are just a little too complex for me yet.

It will work if you separate out the print call. Try:


t = { [1] ="40Xtile.Log@2", [2] ="23Xitem.IngotGold@0", [3] ="78Xitem.Diamond@2" }
for i,v in pairs(t) do
local num, name = string.match(v,"(%d+)[X%*]%a+%.(%a+)")
print(num.." "..name)
end

Also, notice that since you were using the number inside the stored string, you can use the string.match call on just v.
SnowGolem #9
Posted 28 September 2012 - 10:55 PM
It works!

Only 'thing to do' are to ignore or fix are the NULL items (some items in ccsensors are not recognized, this is some sort of bug).

This will come later. Thanks for the help.