How to utter the input text as output (respnse) in rasa core? - rasa-nlu

Example-
Input -> My name is XYZ
Output -> My name is XYZ
I want this to happen for every input.

You can use custom actions to accomplish this behaviour. Should this only happen for certain intents or in general?
Story would look like:
* intent_whose_message_should_be_mirrored
- action_respond_with_user_message
And the like:
class ActionRespondWithUserMessage(Action):
def name(self):
return "action_respond_with_user_message"
def run(self, dispatcher, tracker, domain):
last_message = tracker.latest_message.get("text", "")
dispatcher.utter_message(last_message)
return []

Related

PyQGIS, custom processing algorithm: How to use selected features only?

I want to create a custom processing algorithm with PyQGIS, which is able to take a vector layer as input (in this case of type point) and then do something with it's features. It's working well as long as I just choose the whole layer. But it doesn't work if I'm trying to work on selected features only.
I'm using QgsProcessingParameterFeatureSource to be able to work on selected features only. The option is shown and I can enable the checkbox. But when I'm executing the algorithm, I get NoneType as return of parameterAsVectorLayer.
Below you'll find a minimal working example to reproduce the problem:
from qgis.PyQt.QtCore import QCoreApplication
from qgis.core import (
QgsProcessing,
QgsProcessingAlgorithm,
QgsProcessingParameterFeatureSource
)
name = "selectedonly"
display_name = "Selected features only example"
group = "Test"
group_id = "test"
short_help_string = "Minimal working example code for showing my problem."
class ExampleProcessingAlgorithm(QgsProcessingAlgorithm):
def tr(self, string):
return QCoreApplication.translate('Processing', string)
def createInstance(self):
return ExampleProcessingAlgorithm()
def name(self):
return name
def displayName(self):
return self.tr(display_name)
def group(self):
return self.tr(group)
def groupId(self):
return group_id
def shortHelpString(self):
return self.tr(short_help_string)
def initAlgorithm(self, config=None):
self.addParameter(
QgsProcessingParameterFeatureSource(
'INPUT',
self.tr('Some point vector layer.'),
types=[QgsProcessing.TypeVectorPoint]
)
)
def processAlgorithm(self, parameters, context, feedback):
layer = self.parameterAsVectorLayer(
parameters,
'INPUT',
context
)
return {"OUTPUT": layer}
If I'm working on the whole layer, the output is {'OUTPUT': <QgsVectorLayer: 'Neuer Temporärlayer' (memory)>}, which is what I would expect.
If I'm working on selected features only, my output is {'OUTPUT': None}, which doesn't makes sense to me. I selected some of the features before executing of course.
I'm using QGIS-version 3.22 LTR, if it's relevant.
Can anybody tell me what I'm doing wrong?
I would suggest you trying to use the method 'parameterAsSource' in the 'processAlgorithm' method.
layer = self.parameterAsSource(
parameters,
'INPUT',
context
)

Kv related question - How to bound an on_press/release function to the viewclass of the recycleview?

I've been working on a project which required me to learn kv.
what I'm trying to do is use recycleview to display a list of people that are a part of a dataset I built and allow easy edit of the dataset.
what I've done is read the documentation and simply use the first example from there (with a slight change, the viewclass being a togglebutton:
[The Example][1]
so as for my question, what I want to do is simply bound an on_press/release function to the viewclass objects, for example what I want to do is to bound a function to all of the toggle buttons which appends the button's text to a list when It's being pressed and removes the name from the list when It's being released.
[1]: https://i.stack.imgur.com/55FlM.png
You can do that by adding the on_press to the data:
class RV(RecycleView):
def __init__(self, **kwargs):
self.list = []
super(RV, self).__init__(**kwargs)
self.data = [{'text': str(x), 'on_press':partial(self.toggle, str(x))} for x in range(100)]
def toggle(self, name):
print('toggle')
if name in self.list:
self.list.remove(name)
else:
self.list.append(name)
print('list is now:', self.list)

Get the user's value of an intent in RASA Core/NLU

I have the same question as in: Get Intent Value in RASA Core/NLU
but I want the value that the user gives for a given intent.
For example:
User: I want to take it (this sentence is an intent called: 'use_it')
Bot: ....
User: .... (Later in the chat I decide to answer with the same phrase of intent 'use it')
Bot: you said previously "I want to take it"
How can I do something like: tracker.get_slot but for intent?
I don't want the name of the last intent I want the text of a user-given intent.
Execute a custom action after the intent in which you store the intent text in a slot:
from rasa_core_sdk import Action
from rasa_core_sdk.events import SlotSet
class ActionStoreIntentMessage(Action):
"""Stores the bot use case in a slot"""
def name(self):
return "action_store_intent_message"
def run(self, dispatcher, tracker, domain):
# we grab the whole user utterance here as there are no real entities
# in the use case
message = tracker.latest_message.get('text')
return [SlotSet('intent_message', message)]
You can then use the value of the set slot within an utter template:
slots:
intent_message:
type: text
templates:
utter_last_intent:
- "you said previously: {intent_message}"
You can use tracker for the task.
text=tracker.latest_message['text']

rails string substitution or similar solution in controller

I'm building a site with users in all 50 states. We need to display information for each user that is specific to their situation, e.g., the number of events they completed in that state. Each state's view (a partial) displays state-specific information and, therefore, relies upon state-specific calculations in a state-specific model. We'd like to do something similar to this:
##{user.state} = #{user.state.capitalize}.new(current_user)
in the users_controller instead of
#illinois = Illinois.new(current_user) if (#user.state == 'illinois')
.... [and the remaining 49 states]
#wisconsin = Wisconsin.new(current_user) if (#user.state == 'wisconsin')
to trigger the Illinois.rb model and, in turn, drive the view defined in the users_controller by
def user_state_view
#user = current_user
#events = Event.all
#illinois = Illinois.new(current_user) if (#user.state == 'illinois')
end
I'm struggling to find a better way to do this / refactor it. Thanks!
I would avoid dynamically defining instance variables if you can help it. It can be done with instance_variable_set but it's unnecessary. There's no reason you need to define the variable as #illinois instead of just #user_state or something like that. Here is one way to do it.
First make a static list of states:
def states
%{wisconsin arkansas new_york etc}
end
then make a dictionary which maps those states to their classes:
def state_classes
states.reduce({}) do |memo, state|
memo[state] = state.camelize.constantize
memo
end
end
# = { 'illinois' => Illinois, 'wisconsin' => Wisconsin, 'new_york' => NewYork, etc }
It's important that you hard-code a list of state identifiers somewhere, because it's not a good practice to pass arbitrary values to contantize.
Then instantiating the correct class is a breeze:
#user_state = state_classes[#user.state].new(current_user)
there are definitely other ways to do this (for example, it could be added on the model layer instead)

How to get django ModelForm to not clean a ManyToManyField before running clean_ for that field?

class MyModel(models.Model) :
people = models.ManyToManyField(User,related_name='people')
...
class MyForm(ModelForm) :
class Meta :
model = MyModel
widgets = {'people':TextInput(),}
def clean_people(self) :
# turn a comma-separated list of names into a Python list
return [name0,name1,...]
def clean(self) :
# if no other errors, turn list of names into list of Users
This doesn't work, because clean_people doesn't get called before field.clean gets called, where field is an instance of ModelMultipleChoiceField, which checks for a Python list or tuple and so raises a ValidationError and skips clean_people.
Is there a reason why the order of calls is the way it is, and is there some standard provision for avoiding this problem? I could set field.clean to lambda x:x in each instance of MyForm, but that seems really ugly. Is perhaps the right thing to do to explicitly define the people field in MyForm as a CharField ?
why don't you override clean's behaviour?
class MyForm(ModelForm):
class Meta:
model = MyModel
widgets = {'people':TextInput(),}
def clean_people(self):
# turn a comma-separated list of names into a Python list
return [name0,name1,...]
# override below!
def clean(self):
super(MyForm, self).clean()
# do stuff you need, eg: call clean_people(self)
return self.cleaned_data
I'm not sure I understood your problem 100%, but just by defining clean_people() before clean() doesn't mean that's going to be called before, or even called at all.
It seems that the right? thing is to define the people field in the form, overriding the model's idea of that field
class MyModel(models.Model) :
people = models.ManyToManyField(User,related_name='people')
...
class MyForm(ModelForm):
people = CharField(...)
class Meta :
model = MyModel
def clean_people(self) :
# turn a comma-separated list of names into a Python list
return [name0,name1,...]
def clean(self) :
# if no other errors, turn list of names into list of Users

Resources