Hello community,
here is the log from the commit of package python-adapt-parser for
openSUSE:Factory checked in at 2019-06-12 13:13:26
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-adapt-parser (Old)
and /work/SRC/openSUSE:Factory/.python-adapt-parser.new.4811 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-adapt-parser"
Wed Jun 12 13:13:26 2019 rev:3 rq:708401 version:0.3.3
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-adapt-parser/python-adapt-parser.changes
2019-03-05 12:26:38.048833153 +0100
+++
/work/SRC/openSUSE:Factory/.python-adapt-parser.new.4811/python-adapt-parser.changes
2019-06-12 13:13:28.116868935 +0200
@@ -1,0 +2,7 @@
+Fri Jun 7 14:25:19 UTC 2019 - Marketa Calabkova <[email protected]>
+
+- Update to 0.3.3
+ * Change license to Apache 2.0
+ * other minor changes
+
+-------------------------------------------------------------------
Old:
----
v0.3.2.tar.gz
New:
----
v0.3.3.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-adapt-parser.spec ++++++
--- /var/tmp/diff_new_pack.YWPsvI/_old 2019-06-12 13:13:29.024867983 +0200
+++ /var/tmp/diff_new_pack.YWPsvI/_new 2019-06-12 13:13:29.028867978 +0200
@@ -18,10 +18,10 @@
%{?!python_module:%define python_module() python-%{**} python3-%{**}}
Name: python-adapt-parser
-Version: 0.3.2
+Version: 0.3.3
Release: 0
Summary: A text-to-intent parsing framework
-License: LGPL-3.0-only
+License: Apache-2.0
Group: Development/Languages/Python
URL: https://github.com/MycroftAI/adapt
Source:
https://github.com/MycroftAI/adapt/archive/release/v%{version}.tar.gz
++++++ v0.3.2.tar.gz -> v0.3.3.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/adapt-release-v0.3.2/README.md
new/adapt-release-v0.3.3/README.md
--- old/adapt-release-v0.3.2/README.md 2018-04-25 17:40:28.000000000 +0200
+++ new/adapt-release-v0.3.3/README.md 2019-05-28 23:12:08.000000000 +0200
@@ -1,42 +1,49 @@
-[](https://waffle.io/MycroftAI/adapt)
+[](LICENSE.md)
[](https://mycroft.ai/cla)
[](https://github.com/MycroftAI/contributors/blob/master/team/Mycroft%20Core.md)

+
+[](https://travis-ci.org/MycroftAI/adapt)
[](https://coveralls.io/github/MycroftAI/adapt?branch=master)
+[](http://makeapullrequest.com)
+[](https://chat.mycroft.ai)
+
+Adapt Intent Parser
+==================
+The Adapt Intent Parser is a flexible and extensible intent definition and
determination framework. It is intended to parse natural language text into a
structured intent that can then be invoked programatically.
+
+[](https://www.youtube.com/watch?v=zR9xvPtM6Ro)
+
Getting Started
===============
To take a dependency on Adapt, it's recommended to use virtualenv and pip to
install source from github.
-
- $ virtualenv myvirtualenv
- $ . myvirtualenv/bin/activate
- $ pip install -e git+https://github.com/mycroftai/adapt#egg=adapt-parser
-
+```bash
+$ virtualenv myvirtualenv
+$ . myvirtualenv/bin/activate
+$ pip install -e git+https://github.com/mycroftai/adapt#egg=adapt-parser
+```
Examples
========
Executable examples can be found in the [examples
folder](https://github.com/MycroftAI/adapt/tree/master/examples).
-Overview
-==================
-The Adapt Intent Parser is a flexible and extensible intent definition and
determination framework. It is intended to parse natural language text into a
structured intent that can then be invoked programatically.
-
Intent Modelling
================
In this context, an Intent is an action the system should perform. In the
context of Pandora, we’ll define two actions: List Stations, and Select Station
(aka start playback)
With the Adapt intent builder:
-
- list_stations_intent = IntentBuilder('pandora:list_stations')\
- .require('Browse Music Command')\
- .build()
-
+```Python
+list_stations_intent = IntentBuilder('pandora:list_stations')\
+ .require('Browse Music Command')\
+ .build()
+```
For the above, we are describing a “List Stations” intent, which has a single
requirement of a “Browse Music Command” entity.
-
- play_music_command = IntentBuilder('pandora:select_station')\
- .require('Listen Command')\
- .require('Pandora Station')\
- .optionally('Music Keyword')\
- .build()
-
+```Python
+play_music_command = IntentBuilder('pandora:select_station')\
+ .require('Listen Command')\
+ .require('Pandora Station')\
+ .optionally('Music Keyword')\
+ .build()
+```
For the above, we are describing a “Select Station” (aka start playback)
intent, which requires a “Listen Command” entity, a “Pandora Station”, and
optionally a “Music Keyword” entity.
@@ -52,32 +59,33 @@
For my Pandora implementation, there is a static set of vocabulary for the
Browse Music Command, Listen Command, and Music Keyword (defined by me, a
native english speaker and all-around good guy). Pandora Station entities are
populated via a "List Stations" API call to Pandora. Here’s what the vocabulary
registration looks like.
-
- def register_vocab(entity_type, entity_value):
- # a tiny bit of code
-
- def register_pandora_vocab(emitter):
- for v in ["stations"]:
- register_vocab('Browse Music Command', v)
-
- for v in ["play", "listen", "hear"]:
- register_vocab('Listen Command', v)
-
- for v in ["music", "radio"]:
- register_vocab('Music Keyword', v)
-
- for v in ["Pandora"]:
- register_vocab('Plugin Name', v)
-
- station_name_regex = re.compile(r"(.*) Radio")
- p = get_pandora()
- for station in p.stations:
- m = station_name_regex.match(station.get('stationName'))
- if not m:
- continue
- for match in m.groups():
- register_vocab('Pandora Station', match)
-
+```Python
+def register_vocab(entity_type, entity_value):
+ pass
+ # a tiny bit of code
+
+def register_pandora_vocab(emitter):
+ for v in ["stations"]:
+ register_vocab('Browse Music Command', v)
+
+ for v in ["play", "listen", "hear"]:
+ register_vocab('Listen Command', v)
+
+ for v in ["music", "radio"]:
+ register_vocab('Music Keyword', v)
+
+ for v in ["Pandora"]:
+ register_vocab('Plugin Name', v)
+
+ station_name_regex = re.compile(r"(.*) Radio")
+ p = get_pandora()
+ for station in p.stations:
+ m = station_name_regex.match(station.get('stationName'))
+ if not m:
+ continue
+ for match in m.groups():
+ register_vocab('Pandora Station', match)
+```
Learn More
========
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/adapt-release-v0.3.2/adapt/intent.py
new/adapt-release-v0.3.3/adapt/intent.py
--- old/adapt-release-v0.3.2/adapt/intent.py 2018-04-25 17:40:28.000000000
+0200
+++ new/adapt-release-v0.3.3/adapt/intent.py 2019-05-28 23:12:08.000000000
+0200
@@ -78,7 +78,7 @@
def resolve_one_of(tags, at_least_one):
- """This searches tags for Entites in at_least_one and returns any match
+ """This searches tags for Entities in at_least_one and returns any match
Args:
tags(list): List of tags with Entities to search for Entities
@@ -95,7 +95,7 @@
for entity_type in pr:
last_end_index = -1
if entity_type in resolution:
- last_end_index =
resolution.get[entity_type][-1].get('end_token')
+ last_end_index = resolution[entity_type][-1].get('end_token')
tag, value, c = find_first_tag(tags, entity_type,
after_index=last_end_index)
if not tag:
break
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/adapt-release-v0.3.2/setup.py
new/adapt-release-v0.3.3/setup.py
--- old/adapt-release-v0.3.2/setup.py 2018-04-25 17:40:28.000000000 +0200
+++ new/adapt-release-v0.3.3/setup.py 2019-05-28 23:12:08.000000000 +0200
@@ -19,7 +19,7 @@
setup(
name = "adapt-parser",
- version = "0.3.2",
+ version = "0.3.3",
author = "Sean Fitzgerald",
author_email = "[email protected]",
description = ("A text-to-intent parsing framework."),
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/adapt-release-v0.3.2/test/IntentTest.py
new/adapt-release-v0.3.3/test/IntentTest.py
--- old/adapt-release-v0.3.2/test/IntentTest.py 2018-04-25 17:40:28.000000000
+0200
+++ new/adapt-release-v0.3.3/test/IntentTest.py 2019-05-28 23:12:08.000000000
+0200
@@ -17,7 +17,7 @@
import unittest
from adapt.parser import Parser
from adapt.entity_tagger import EntityTagger
-from adapt.intent import IntentBuilder
+from adapt.intent import IntentBuilder, resolve_one_of
from adapt.tools.text.tokenizer import EnglishTokenizer
from adapt.tools.text.trie import Trie
@@ -32,6 +32,7 @@
self.regex_entities = []
self.tagger = EntityTagger(self.trie, self.tokenizer,
regex_entities=self.regex_entities)
self.trie.insert("play", ("play", "PlayVerb"))
+ self.trie.insert("stop", ("stop", "StopVerb"))
self.trie.insert("the big bang theory", ("the big bang theory",
"Television Show"))
self.trie.insert("the big", ("the big", "Not a Thing"))
self.trie.insert("barenaked ladies", ("barenaked ladies", "Radio
Station"))
@@ -70,6 +71,24 @@
assert result_intent.get('PlayVerb') == 'play'
assert result_intent.get('Radio Station') == "barenaked ladies"
+ def test_at_least_one_with_tag_in_multiple_slots(self):
+ self.trie.insert("temperature", ("temperature", "temperature"))
+ self.trie.insert("living room", ("living room", "living room"))
+ self.trie.insert("what is", ("what is", "what is"))
+
+ intent = IntentBuilder("test intent")\
+ .one_of("what is")\
+ .one_of("temperature", "living room")\
+ .one_of("temperature")\
+ .build()
+
+ for result in self.parser.parse("what is the temperature in the living
room"):
+ result_intent = intent.validate(result.get("tags"),
result.get("confidence"))
+ assert result_intent.get("confidence") > 0.0
+ assert result_intent.get("temperature") == "temperature"
+ assert result_intent.get("living room") == "living room"
+ assert result_intent.get("what is") == "what is"
+
def test_at_least_on_no_required(self):
intent = IntentBuilder("play intent") \
.one_of("Television Show", "Radio Station") \
@@ -134,3 +153,162 @@
assert result_intent.get('Play Verb') == 'play'
assert result_intent.get('series') == "the big bang theory"
+ def test_resolve_one_of(self):
+ tags = [
+ {
+ "confidence": 1.0,
+ "end_token": 1,
+ "entities": [
+ {
+ "confidence": 1.0,
+ "data": [
+ [
+ "what is",
+ "skill_iot_controlINFORMATION_QUERY"
+ ]
+ ],
+ "key": "what is",
+ "match": "what is"
+ }
+ ],
+ "from_context": False,
+ "key": "what is",
+ "match": "what is",
+ "start_token": 0
+ },
+ {
+ "end_token": 3,
+ "entities": [
+ {
+ "confidence": 1.0,
+ "data": [
+ [
+ "temperature",
+ "skill_weatherTemperature"
+ ],
+ [
+ "temperature",
+ "skill_iot_controlTEMPERATURE"
+ ]
+ ],
+ "key": "temperature",
+ "match": "temperature"
+ }
+ ],
+ "from_context": False,
+ "key": "temperature",
+ "match": "temperature",
+ "start_token": 3
+ },
+ {
+ "confidence": 1.0,
+ "end_token": 7,
+ "entities": [
+ {
+ "confidence": 1.0,
+ "data": [
+ [
+ "living room",
+ "skill_iot_controlENTITY"
+ ]
+ ],
+ "key": "living room",
+ "match": "living room"
+ }
+ ],
+ "from_context": False,
+ "key": "living room",
+ "match": "living room",
+ "start_token": 6
+ }
+ ]
+
+ at_least_one = [
+ [
+ "skill_iot_controlINFORMATION_QUERY"
+ ],
+ [
+ "skill_iot_controlTEMPERATURE",
+ "skill_iot_controlENTITY"
+ ],
+ [
+ "skill_iot_controlTEMPERATURE"
+ ]
+ ]
+
+ result = {
+ "skill_iot_controlENTITY": [
+ {
+ "confidence": 1.0,
+ "end_token": 7,
+ "entities": [
+ {
+ "confidence": 1.0,
+ "data": [
+ [
+ "living room",
+ "skill_iot_controlENTITY"
+ ]
+ ],
+ "key": "living room",
+ "match": "living room"
+ }
+ ],
+ "from_context": False,
+ "key": "living room",
+ "match": "living room",
+ "start_token": 6
+ }
+ ],
+ "skill_iot_controlINFORMATION_QUERY": [
+ {
+ "confidence": 1.0,
+ "end_token": 1,
+ "entities": [
+ {
+ "confidence": 1.0,
+ "data": [
+ [
+ "what is",
+ "skill_iot_controlINFORMATION_QUERY"
+ ]
+ ],
+ "key": "what is",
+ "match": "what is"
+ }
+ ],
+ "from_context": False,
+ "key": "what is",
+ "match": "what is",
+ "start_token": 0
+ }
+ ],
+ "skill_iot_controlTEMPERATURE": [
+ {
+ "end_token": 3,
+ "entities": [
+ {
+ "confidence": 1.0,
+ "data": [
+ [
+ "temperature",
+ "skill_weatherTemperature"
+ ],
+ [
+ "temperature",
+ "skill_iot_controlTEMPERATURE"
+ ]
+ ],
+ "key": "temperature",
+ "match": "temperature"
+ }
+ ],
+ "from_context": False,
+ "key": "temperature",
+ "match": "temperature",
+ "start_token": 3
+ }
+ ]
+ }
+
+ assert resolve_one_of(tags, at_least_one) == result