Determine int number in an utterance

Be gentle, this is my first post.
I am trying to retrieve a number, located in an utterance, and convert to int . Code below with the utterance ex. “degrees 90” speaks 90 (it works). But I would like the number come before the degrees in the utterance for ex. “turn 90 degrees” Additionally, I want to also recognize the word “turn”. I do not understand the term ‘^.*?’ in the code below (or the code in speakDegrees.voc). Is there an easier way? Thank you for your assistance.

@intent_handler(IntentBuilder("").require("speakDegrees"))
def handle_question_response(self, message):
	utterance = message.data.get('utterance')
	repeat = re.sub('^.*?' + message.data['speakDegrees'], '', utterance)
	self.speak(repeat.strip())
	Num1=int(repeat.strip())
	strNum1 = str(Num1)
	self.speak(strNum1)

file Words.rx
degrees
file: speakDegrees.voc
degrees (?P.*)

Hey Minor,

Welcome to the Community, and thanks for making your first post :tada:

The ^.*? is a regular expression, to learn more about those checkout something like regex101.com, however the best news is that you no longer need to use this for what you’re trying to do.

We now have a beautiful function called extract_number

To use it we have to import it at the top of the file:
from mycroft.util.parse import extract_number

Then your intent handler would look something like:

@intent_handler(IntentBuilder("").require("speakDegrees"))
def handle_question_response(self, message):
	utterance = message.data.get('utterance')
	num = int(extract_number(utterance))
	self.speak_dialog('turning', {'num': num})

If you want to say more than the number itself you can create a dialog/en-us/turn.dialog file, with something like:
turning {num} degrees

With this approach you can delete Words.rx.

Instead of speakDegrees.voc, it might be better to have two vocab terms defined. If you have turn.voc that has turn and degrees.voc that has degrees in them. Then it will return a higher match confidence and avoid triggering if someone is talking about a different type of degree such as the weather. The user could then say

  • turn it 90 degrees
  • turn 90 degrees
  • turn 90 degrees please
  • 90 degrees turn
  • turn it roughly 90 degrees
  • maybe turn it I think 90 degrees should be about right, yeah

You can even add synonyms eg in turn.voc you might have

turn
rotate
twist

which will then allow phrases like “rotate 90 degrees”

Alternatively
If you want to keep it fairly strict to just “turn 90 degrees” it can be useful to use an intent file handler instead. This lets you be very prescriptive and more easily capture specific parts of the utterance. So in a file like vocab/en-us/turn.intent you would put:
turn {num} degrees

Then your handler would look like:

@intent_file_handler('turn.intent')
def handle_question_response(self, message):
	spoken_num = message.data.get('num')
	num = int(extract_number(spoken_num))
	self.speak_dialog('turning', {'num': num})

Hopefully that helps, and please do let us know if you have extra questions.

What sort of Skill are you building?

[gez-mycroft]
That’s perfect! Your answer was just what I was looking for! And giving an alternative method was icing on the cake. The skill I am building is for robotics. The integration with picroft was a huge step up from sending commands from a keyboard. I’m just learning mycroft right now, but when I am more proficient I will contribute a skill to the community.
Thank you for your time, detailed explanation, and quick response.

1 Like

Hey I got another question about regex today, so ended up putting a quick example together.

Might be useful if you specifically want to use regex in the future:

Kris…
Your [regex-example-skill] was excellent. Small examples skills, like this, show a developer how a particular method works, so he/she can integrate the example in their own skill. Looking at code for a large complicated skill, to figure out a small piece of the skill, can overwhelming. Small example skills are very useful.
Thanks

1 Like

Yeah my aim is to incorporate these into the docs, we have code snippets in the docs but I think it helps to then link out to a Skill that does just that one thing. If it works out they might even link together to form a larger functioning Skill… always lots of possibilities…