Word number to actual number

Posted by Rene on Sun 01 Oct 2017 05:27 PM — 17 posts, 72,948 views.

#0
I'm kind of new to coding, and am trying to change a capture called 'amount' from the word of a number, i.e. 'one' 'twenty three' to the digits, '1' '23'. I figured I can do it by writing a string with all the words and have it run a for string through it until it matches. Is this the way to go about doing it, or is there a simpler way?

To note, the number is likely to be under 20 if that makes any way of doing it more optimal.

THanks.
#1
Hi,

Mmmm first of all you should show the Trigger with which you are supposed to capture the number.

This is for sure the difficult part. As regarding your question i'm sure there are many elegant way to solve it (i remember an old excel sheet with a macro doing that..)

BUT ... you are speaking about numbers < 20!

So, even if it is UNelegant, the first things come in mind is a table

In first place i would've created a simple array (table without any keys) trying to find a way to get the index position by knowing the element you are looking for, but i don't remember how to do it :').

So, since we are speaking about only twenty members i'd create a table with keys like that:
local litNumb = {
one = 1,
two = 2,
three = 3,
four = 4,
five = 5,
six = 6,
seven = 7,
eight = 8,
nine = 9,
ten = 10,
eleven = 11,
twelve = 12,
thirteen = 13,
fourteen = 14,
fifteen = 15,
sixteen = 16,
seventeen = 17,
eighteen = 18,
nineteen = 19,
twenty = 20 } -- end litNum 


..then to lookup at the number you need only to capture (correctly) the string containing the number (for example "four") and...
 local RealNum = litNum ["%1"] 

.. supposing the number "four" is captured in the first wildcard.

Make some trial and post again in case of need.
Anyhow would be interesting knowing an example of string from your MUD and how you are trying to capture the literal numbers..
#2
Thanks, two things, I mentioned likely under 20, but it can go up to 100.
Then, here is what I am working with:
The capture is coming from this trigger:
<trigger
enabled="y"
keep_evaluating="y"
omit_from_output="n"
match="^You count (?:.+) small knives in your pack.$"
regexp="y"
script="count_knives"
name="Count"
sequence="100"
>
</trigger>

It is the response to a 'count knives' command, and it will show: You count seven knives in your pack. as a result.

I've been using:
function count_knives (name, line, wildcards)

wildcards[1] comes out to seven, now I want to convert that to the number 7.
THerefore if I then drop one it will have a number to subtract it from.
Thanks again!
#3
Rene said:

...
...
match="^You count (?:.+) small knives in your pack.$" ...
...
It is the response to a 'count knives' command, and it will show: You count seven knives in your pack. as a result.


Sorry, only a question: for what i remember the sequence:
 "(?:" 
is a non capturing string

So, instead, i would use...
 match="^You count (.+?) (.*?) in your pack.$" 


In this way with wildcard [1] (%1) you capture the quantity, with wildcard [2] (%2) you capture the object the number is referred to.

Final... 100 hundred become a more serious quantity; even though it's possible to manage array (ok table without a key) till 50.000 elements easy and quick.
I don't know how fast will be using a table with 100 elements but (knowing how quick is Lua in MUSH) i think should work as good as for only twenty elements.

I didn't make any experimentation on the above but is a solid starting point.

Let us know!
#4
Sorry, you are right, I copied the wrong one, I a using it without the ?:.

To clarify, in the function how would I get the number from wildcard[1]? The line of code would just be 'wildcard[1](%1)'?

That will make it that wildcard[1] will be a number?

Thanks!
Kind of new to this stuff, sorry for the ignorant questions.
#5
Rene said:

To clarify, in the function how would I get the number from wildcard[1]? The line of code would just be 'wildcard[1](%1)'?


Don't worry, i'll try to help you as i can, even though ( never forget) Fiendish and Nick Gammon are WAY more exert than anyone else.

As previously said ( i put again to be more clear and give you sure reference ) i suggest you put the following code in the edit windows just below the trigger box where you put your trigger. Remember, you have to select (in the box Sendto ) Script

So, create a table with keys like that:
local litNumb = {
one = 1,
two = 2,
three = 3,
four = 4,
five = 5,
six = 6,
seven = 7,
eight = 8,
nine = 9,
ten = 10,
eleven = 11,
twelve = 12,
thirteen = 13,
fourteen = 14,
fifteen = 15,
sixteen = 16,
seventeen = 17,
eighteen = 18,
nineteen = 19,
twenty = 20 } -- end litNum 


..then to lookup at the number you need only to code:
 local RealNum = litNum ["%1"] 

.. So refer to the wildcard putting it in quotation marks .
Obviusly, make some trial and be sure %1 contain only the bit of string with the number, as you written in the table, or you'll get a fail in the match and the RealNum variable will be Nil .

So i suggest (before you code everything) to put just after the above code:
 print ("Triggered!")
if RealNum ~= nil then 
   print ("this is the content of wildcard [1] --> " .. "%1")
   print ("and this the literal converted to number --> " .. RealNum) 
end -- if 

Just to be sure and test your trigger.

Tell us what's the outcome!
Amended on Mon 02 Oct 2017 08:46 PM by Marco
#6
Firstly, I assume you meant local litNum without the b?

Also it fails to match, I'm unsure what the "%1" is doing, but wildcards[1] is clearly just the word for the number.

I'm unsure what ' local RealNum = litNum ["%1"] ' does and why it should return the right number.
Thanks.
#7
Rene said:

I'm unsure what ' local RealNum = litNum ["%1"] ' does and why it should return the right number.
Thanks.


LitNum (or whatever -- since it's a variable, so you can give it any name you like ... -- ) is the Table you defined with keys ( keys are the words inside the " { } " that are not contained in quotation marks ) and the "values" those keys are associated (values are inside quotation marks after the " = " sign)

So the wildcard "%1" HAS to match Exactly the keys you used.

If you copy and paste the code i posted you, you should understand how it works.

Also, in the code, there are the "print" instructions that let you see when the trigger is activated and the content of "%1" and of RealNum.

Try the code! it works!

Also, if you want, when you use MUSH and you select the world you want to play with, even without connecting, you can press Ctrl+Shift+F12; --> A box will appear; in this box you can write the text you want and when given confirmation MUSH interpret that string as if coming from the world.

In this way you can simulate every incoming text and that's very useful to TEST your Triggers.
Amended on Tue 03 Oct 2017 07:20 AM by Marco
Australia Forum Administrator #8
See: http://www.gammon.com.au/forum/?id=10155

In particular there is a module that ships with MUSHclient that does that. Example:


require "words_to_numbers"

number = convert_words_to_numbers ("one hundred eight thousand three hundred nine")

print (number)   --> 108309


You can also convert back:


require "words_to_numbers"
print (convert_numbers_to_words ("94921277802687490518"))


That prints:


ninety four quintillion nine hundred twenty one quadrillion two hundred seventy seven trillion eight hundred two billion six hundred eighty seven million four hundred ninety thousand five hundred eighteen
#9
Nick Gammon said:

See: http://www.gammon.com.au/forum/?id=10155

In particular there is a module that ships with MUSHclient that does that. Example:


Amazing :O
#10
I'm trying to get a variable to be replace as a number and can't figure out the syntax, i.e.

local amount = fourteen
Note(convert_words_to_number(amount))

But it gives me an error, how would I use it?
Thanks.
Australia Forum Administrator #11
Rene said:


local amount = fourteen
Note(convert_words_to_number(amount))




You have two problems. The function is called convert_words_to_numbers - note the "s" on the end.

Second, if you want to literally convert "fourteen" you have to quote it, like this:


require "words_to_numbers"

local amount = "fourteen"
Note(convert_words_to_numbers(amount))
#12
Sorry, was a typo I meant like that.
I realised my issue what with using ColourNote, (i.e. ColourNote("white", "", convert_words_to_numbers(amount) ) for some reason that gave an error, but I found if I use tostring(convert_words_to_numbers(amount)) it works fine.
Not sure why that is, can you explain that to me?
Thanks.
USA Global Moderator #13
[EDIT]
There appears to be an inconsistency between Note and ColourNote with regards to whether the output from bc.number is accepted as an argument. Note appears to implicity call tostring while ColourNote does not.
Amended on Mon 06 Nov 2017 05:57 AM by Nick Gammon
Australia Forum Administrator #14
You are right, Fiendish. Note (as documented) will concatenate multiple arguments together, and thus they must be converted to strings.

eg.


Note ("The number is ", 42, " ", true)


In this case the number 42 and the boolean value true will be converted to their string equivalents (similarly for a big number).

However ColourNote does not behave like this. It takes triples of arguments, like:


foreground, background, text


There is no implicit conversion of the "text" argument to a string.
Australia Forum Administrator #15
It looks like Lua changed its behaviour between version 5.1 (which MUSHclient uses) and 5.2.

In 5.1 only strings and numbers can be implicitly used as strings. In 5.2 a value with a "__tostring" metatable entry could be used to convert it to a string (like a "big number" value).

Thus, since ColourNote does not call "tostring" implicitly, you need to explicitly call it in the example you have provided.
Australia Forum Administrator #16
Rene said:

Sorry, was a typo I meant like that.
I realised my issue what with using ColourNote, (i.e. ColourNote("white", "", convert_words_to_numbers(amount) ) for some reason that gave an error ...


It is always helpful to post the error message, rather than vaguely saying that it "gave an error".