Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to verify your details, confirm your email, resolve issues, making threats, or asking for money, are
spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the
password reset link.
Due to spam on this forum, all posts now need moderator approval.
Entire forum
➜ MUSHclient
➜ General
➜ Working with tables and regexp
Working with tables and regexp
|
It is now over 60 days since the last post. This thread is closed.
Refresh page
Posted by
| Mccane
(28 posts) Bio
|
Date
| Tue 27 Nov 2007 07:50 AM (UTC) Amended on Fri 30 Nov 2007 09:16 AM (UTC) by Mccane
|
Message
| Okay, on this game there are different trading centers. When you go into a trading center, you type MENU and see something like:
--- Place; Trading Post ---
Item Demand Buying For
----------------------------------------------------------
Product1 201500.0 145.93
Product2 19780.0 275.0
Product3 526700.0 48.87
Item Supply Selling For
----------------------------------------------------------
Produ1a 971390.0 50.07
Produ1b 463284.0 35.0
Produ1c 133500.0 88.57
At every trading center, they sell different items and buy different items. Every center has different prices.
Here is what I'm trying to do. I figured I would have a trigger that's regexp that fires on <String>spaces <Floating Point Number>spaces <Floating Point Number>
I could also make a trigger that toggles between selling and buy based on (when it sees Item Supply Selling For
it sets a Selling variable to 1, which the previous trigger checks and stores accordingly by or it sets it to 0, on which the previous trigger assumes you're buying and not selling).
I was hoping someone could help me figure out or point me to documentation in regular expressions so I could make it match on <String>spaces <Floating Point Number>spaces <Floating Point Number>
I'd also like some help with or a point towards documentation that would help me in figuring out how to store A) The trading center name B) Item name C) Selling/Buy price. The item and price would be associated to that center (the center could be set as a variable when it matches the line
--- Place; Trading Post ---
What I'm eventually trying to do is take all the values for Product1 and print me the lowest value and where it's being sold out, then take the highest buying value for Product1 and spit out the price and place so I can make the most efficient trades. Any help would be much appreciated! | Top |
|
Posted by
| Nick Gammon
Australia (23,133 posts) Bio
Forum Administrator |
Date
| Reply #1 on Tue 27 Nov 2007 07:52 PM (UTC) Amended on Tue 27 Nov 2007 07:53 PM (UTC) by Nick Gammon
|
Message
| If you are logged into the forum you can edit and delete posts you know, you don't have to repost the same thing with corrections.
As for the regexp, something like this will match on the product lines:
<triggers>
<trigger
enabled="y"
match="^(?P<name>[A-Za-z0-9]+)\s+(?P<demand>[0-9.]+)\s+(?P<buying>[0-9.]+)\s+$"
regexp="y"
send_to="2"
sequence="100"
>
<send>Name = %<name>
Demand = %<demand>
Buying = %<buying>
</send>
</trigger>
</triggers>
I used named wildcards to make subsequent scripting a bit easier, so you can refer to the names rather than just %1, %2 etc.
The match line looks a bit strange in XML, if you look at it in the trigger edit dialog it looks like this:
^(?P<name>[A-Za-z0-9]+)\s+(?P<demand>[0-9.]+)\s+(?P<buying>[0-9.]+)\s+$
Using your test data I got this, the echoed lines are in bold:
Item Demand Buying For
----------------------------------------------------------
Product1 201500.0 145.93
Name = Product1
Demand = 201500.0
Buying = 145.93
Product2 19780.0 275.0
Name = Product2
Demand = 19780.0
Buying = 275.0
Product3 526700.0 48.87
Name = Product3
Demand = 526700.0
Buying = 48.87
Item Supply Selling For
----------------------------------------------------------
Produ1a 971390.0 50.07
Name = Produ1a
Demand = 971390.0
Buying = 50.07
Produ1b 463284.0 35.0
Name = Produ1b
Demand = 463284.0
Buying = 35.0
Produ1c 133500.0 88.57
Name = Produ1c
Demand = 133500.0
Buying = 88.57
|
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|
Posted by
| Mccane
(28 posts) Bio
|
Date
| Reply #2 on Wed 28 Nov 2007 07:42 AM (UTC) |
Message
| Gracias, Nick.
I've gotten the regex down, I think. It turned out some of the items in the game have more than one word in the name, for example there's a product called 'Carbon' and a product called 'carbon dioxide', so
^(?P<name>[A-Za-z0-9]+)\s+(?P<demand>[0-9.]+)\s+(?P<buying>[0-9.]+)\s+$
would not match to the carbon dioxide line. I changed it to
^(?P<name>.+)\s+(?P<demand>[0-9.]+)\s+(?P<buying>[0-9.]+)\s+
and it seems to match to every line right.
The trouble for me comes in with Lua tables. I thought the easiest way to do it would to be make a table such as
trade.Item.Selling/Buying = {Location, Demand/Supply, Price}
The problem comes in with the multiple names. I can't seem to figure out how to turn 'Carbon Dioxide' into just 'CarbonDioxide' (I tried doing an if Name == "Carbon Dioxide" then Name = "CarbonDioxide" but I couldn't get it to work. I also can't seem to figure out how to add tables to within tables in the format I'm using (right now it just rewriting a new location over the last location every time I test it).
I thought about doing trade.Item.Selling/Buying.@Location = {}, where Location is stored in a variable and expand variables is checked, but I didn't see any feasability on running searches through all the data (my goal is to run through trade.Item1.Selling and find the LOWEST number and then trade.Item2.Buying and find the HIGHEST number. I figured it might help to show a realistic look at what the game actually shows:
--- Miriani; Trading Post ---
Item Demand Buying For
----------------------------------------------------------
Aluminum 201500.0 145.93
Bardenium 19780.0 275.0
Grain 526700.0 48.87
Carbon 602970.0 53.88
Oxygen 950000.0 75.0
Argon 285000.0 156.81
Item Supply Selling For
----------------------------------------------------------
Xenon 971395.0 50.07
Bread 463284.0 35.0
Carbon Dioxide 133500.0 88.57
Water 51432426.0 5.0
Zyprexasil 12456.0 900.0
Aluminum Wires 108476.0 119.75
Every trading center has different stuff, so it doesn't overlap consistently to every center. There's about twenty trading centers or so. The supply/demand changes everytime you sell or buy (if you buy a lot, supply will go down, et cetera), so I was hoping to just continuously reupdate the tables every time I made a trade at a different center by rechecking the menu when I finish a trade.
Thanks for your help. | Top |
|
Posted by
| Nick Gammon
Australia (23,133 posts) Bio
Forum Administrator |
Date
| Reply #3 on Wed 28 Nov 2007 06:42 PM (UTC) |
Message
|
Quote:
The problem comes in with the multiple names. I can't seem to figure out how to turn 'Carbon Dioxide' into just 'CarbonDioxide'
So you are saying that something like:
trade.Carbon Dioxide.Selling = { something }
... won't work?
You can use a different syntax and keep the original names, like this:
trade ["Carbon Dioxide"].Selling = { something }
Quote:
I also can't seem to figure out how to add tables to within tables in the format I'm using ...
You can create the tables, where needed. Something like this:
trade = trade or {} -- create trade table if it doesn't exist
item = "Carbon Dioxide" -- test
-- make table for this item and its subtables, if this is the first time for this item
trade [item] = trade [item] or { Selling = {}, Buying = {} }
-- now fill in the fields
trade [item] . Selling . Location = "John's General Store"
trade [item] . Selling . Demand = 602970.0
trade [item] . Selling . Price = 156.81
|
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|
Posted by
| Mccane
(28 posts) Bio
|
Date
| Reply #4 on Thu 29 Nov 2007 08:44 AM (UTC) |
Message
| Thanks Nick, here is the code I have:
Selling = tonumber(GetVariable("Selling"))
item = "%<name>"
if Selling == 0 then
trade [item] = trade [item] or { Buying = {}, Selling = {} }
trade [item] . Buying . Location = "@LocName"
trade [item] . Buying . Demand = %<demand>
trade [item] . Buying . Price = %<buying>
else
trade [item] = trade [item] or { Buying = {}, Selling = {} }
trade [item] . Selling . Location = "@LocName"
trade [item] . Selling . Demand = %<demand>
trade [item] . Selling . Price = %<buying>
end
When I try to enter /table.foreach (trade, print)
, it returns this:
table: 0244B8F0
Bardenium table: 0232F728
Xenon table: 024A8380
Oxygen table: 0232E398
Bread table: 0232D030
Aluminum Wires table: 00D84128
Zyprexasil table: 0244DBB0
Water table: 0241E480
Carbon Dioxide table: 0241E3E0
Carbon table: 024A5800
Aluminum table: 024A4190
Argon table: 0232DD20
Grain table: 0232F088
But when I try to go further, such as trade.Bardenium or anything like that, it returns this error:
Error number: 0
Event: Run-time error
Description: [string "Command line"]:1: bad argument #1 to 'foreach' (table expected, got nil)
stack traceback:
[C]: in function 'foreach'
[string "Command line"]:1: in main chunk
Called by: Immediate execution
It seems as though the data is not being entered into a subtable as I thought the code would do. Where is the data going, and now do I retrieve it?
| Top |
|
Posted by
| Nick Gammon
Australia (23,133 posts) Bio
Forum Administrator |
Date
| Reply #5 on Thu 29 Nov 2007 06:45 PM (UTC) |
Message
| Well that doesn't make a heap of sense, because you have already established they are tables. Perhaps, because of your triggers, the keys have a space in them. Table keys "Bardenium", "Bardenium " and " Bardenium" are all different.
I suggest to print your table you use "tprint" which comes with MUSHclient. That recursively prints tables for you. For example, with my test data from before I see this:
require "tprint"
tprint (trade)
Output:
"Carbon Dioxide":
"Selling":
"Location"="John's General Store"
"Demand"=602970
"Price"=156.81
"Buying":
|
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|
Posted by
| Mccane
(28 posts) Bio
|
Date
| Reply #6 on Fri 30 Nov 2007 05:31 AM (UTC) Amended on Fri 30 Nov 2007 08:33 AM (UTC) by Mccane
|
Message
| Thanks, Nick. Got it working almost. Turned out the regex I was using to match on was storing the space after the item name and before the first number in the subtable name. The only problem is that if I change it so it doesn't match whitespace, it'll cutoff after the first names (will match Carbon but not Carbon Dioxide). Here is what I mean:
^(?P<name>[A-Za-z0-9]+)\s+(?P<demand>[0-9.]+)\s+(?P<buying>[0-9.]+)\s+$
will match Carbon but not Carbon Dioxide because of whitespace in between the two.
^(?P<name>.+)\s+(?P<demand>[0-9.]+)\s+(?P<buying>[0-9.]+)\s+
will match everything, but the matching ends up like this:
"Carbon Dioxide ":
"Buying":
"Selling":
"Location"="Miriani"
"Demand"=133500
"Price"=88.57
"Carbon ":
"Buying":
"Location"="Miriani"
"Demand"=602970
"Price"=53.88
"Selling":
A lot of whitespace following the item name. How can I cut out the additional whitespace after the name from being stored in the %<name> variable? | Top |
|
Posted by
| Nick Gammon
Australia (23,133 posts) Bio
Forum Administrator |
Date
| Reply #7 on Fri 30 Nov 2007 07:47 AM (UTC) |
Message
| It's an interesting problem. ;)
This worked for me, adding in an assertion that the name has to end on a word boundary:
^(?P<name>[A-Za-z0-9 ]+\b)\s+(?P<demand>[0-9.]+)\s+(?P<buying>[0-9.]+)\s+$
|
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|
Posted by
| Mccane
(28 posts) Bio
|
Date
| Reply #8 on Fri 30 Nov 2007 08:37 AM (UTC) |
Message
| You know, it's not often you use someone's software and then you post questions to their forums and they help you every time personally. In most instances you'd be told to figure it out for yourself. 10,000+ posts? In other words, thanks, you're awesome. :) | Top |
|
The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).
To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.
20,632 views.
It is now over 60 days since the last post. This thread is closed.
Refresh page
top