Rasa Core - Understanding Stories - machine-learning

I am having a difficult time understanding how rasa core interprets stories. Say I have the following:
Slot:
name:
type: text
animal:
type: categorical
values:
- dog
- cat
How do I write my stories to handle the sad path for a categorical slot?
*greet
- utter_greet
- utter_please_give_name
*inform{"Name":"Name"}
- utter_hello
- utter_ask_animal
*inform{"Animal": "Dog"}
- utter_hello_fido
- action_restart
*greet
- utter_greet
- utter_please_give_name
*inform{"Name":"Name"}
- utter_hello
- utter_ask_animal
*inform{"Animal": "Cat"}
- utter_hello_kitty
- action_restart
*greet
- utter_greet
- utter_please_give_name
*inform{"Name": null}
-utter_please_give_name
*greet
- utter_greet
- utter_please_give_name
*inform{"Name": "Name"}
-utter_ask_animal
*inform{"Animal": **"?????"**}
- utter_please_tell_animal
Also if I give a partial story in stories.md, like below, how does rasa connect the graph on the back to know what to do next? Does it read each story as an independent flow?
*greet
- utter_greet
- utter_please_give_name
*inform{"Name": null}
-utter_please_give_name
Thank you, any advice is appreciated.

To handle the sad path simply omit the slot annotation, e.g.:
## sad path
*greet
- utter_greet
- utter_please_give_name
*inform
-utter_please_give_name
Depending whether you use augmentation the single stories are glued together during the training to provide more training data.

If you want to handle all animals names so simply you can add more categories or make a custom action to fetch some api to call an animal name or something, Rasa is learning by examples anything not entered in data or domain will act as strange text.

Related

Concatenate lists for a given key in mustache template

Here's what my data looks like (YAML):
-
name: objectA
components:
-
name: "component_1"
-
name: "component_2"
styles:
-
name: "new style"
components:
-
name: "component_1"
-
name: "other style"
components:
-
name: "component_4"
I would like to retrieve in my mustache the full list of components for objectA, meaning i need to access all the components children values and concatenate them or uniq them.
The goal would be to have a template like this:
{{#allComponents}}
{{name}}
{{/allComponents}}
which should output:
component_1
component_2
component_4
PS: i am using GRMustache
There's very little chance any Mustache implementation could handle such a specific need with any native built-in syntax of any kind. And GRMustache does actually not.
The simplest path is to prepare your allComponents key before rendering your data.

How do I write values parsed from a CSV file to a YAML file?

I want to write values parsed from a CSV file to a YAML file:
home_phone = row['HomePhone']
if home_phone.length == 10
puts "First Name: #{row['first_Name']} - Home Phone: #{home_phone} - Zip Code: #{zip_code}"
elsif home_phone.length == 11 && home_phone.start_with?('1')
home_phone.slice!(0)
puts "First Name: #{row['first_Name']} - Home Phone: #{home_phone} - Zip Code: #{zip_code}"
else
puts "First Name: #{row['first_Name']} - Home Phone: #{"0000000000"} - Zip Code: #{zip_code}"
end
The above code is used for printing the details row-wise. The output obtained from the code is:
First Name: Douglas - Home Phone: 4252745000 - Zip Code: 50309'
'First Name: Aya - Home Phone: 9995901339 - Zip Code: 90210'
'First Name: Audrey - Home Phone: 0 - Zip Code: 05667'
How can I write these values to a YAML file?
If you want to convert a CSV file to YAML...
I created a file called "test.csv" which looks like:
First Name,Home Phone,Zip Code
Douglas,4252745000,50309
Aya,9995901339,90210
Audrey,0,05667
Using this code:
require 'csv'
require 'yaml'
csv = CSV.read('test.csv')
File.write('test.yaml', csv.to_yaml)
pp YAML.load_file('test.yaml')
Which generates:
---
- - First Name
- Home Phone
- Zip Code
- - Douglas
- '4252745000'
- '50309'
- - Aya
- '9995901339'
- '90210'
- - Audrey
- '0'
- '05667'
I get this output from pp showing a correct round-trip of the CSV data through YAML-land:
[["First Name", "Home Phone", "Zip Code"],
["Douglas", "4252745000", "50309"],
["Aya", "9995901339", "90210"],
["Audrey", "0", "05667"]]
This is just a simple solution, which loads the entire CSV file into memory. That's not a scalable solution if you are processing files bigger than the available RAM on your system. CSV supports foreach which will let you read the file line by line, but YAML might find it difficult to write the file line-by-line because of how it generates the file; It expects a complete hash or array, but you'll be passing it sub-arrays, which will result in a YAML file looking like:
---
- - First Name
- Home Phone
- Zip Code
---
- - Douglas
- '4252745000'
- '50309'
---
- - Aya
- '9995901339'
- '90210'
---
- - Audrey
- '0'
- '05667'
Loading that with YAML.load_file will result in:
[
[0] [
[0] "First Name",
[1] "Home Phone",
[2] "Zip Code"
]
]
In other words, only the first row will be returned.
The workaround is to use YAML.load_documents(File.open('test.yaml', 'r')) instead of load_file, which reassembles the parts into one array again.
If your row data is a hash (which it looks to be), try using to_yaml like this:
File.open(<path to your output file here>, "w") { |f| f.write(row.to_yaml) }
You can then read it like so:
YAML.load_file(<path to your output file here>)
require 'yaml'
File.open('somefile.yaml','w') do |f|
f.write(row['first_Name'])
f.write(row['home_phone'])
f.write(row['zip_code'])
end

Found shared references to a collection in Grails

In my app, the user makes a search. That search gives back a list of people that can be hired for a duty. But, user can make more than one search for the same duty (say, i need two persons for this city, and three for that city). Every search makes a "Prepresupuesto", and every Prepresupuesto makes a "Cocontrato". All "Cocontrato" makes a "Contrato", and all "Prepresupuestos" makes a single "Presupuesto". And all together conforms the entire duty, called "Campaign" in the app.
When i am trying to save that "Cocontrato", I receive the exception. This is the code:
ArrayList<Prepresupuesto> prepresus=Prepresupuesto.findAllByCamp(campid)
Presupuesto pres=new Presupuesto()
for(int i=0;i<prepresus.size();i++){
pres.prepresu.add(prepresus[i])
pres.camp=Campaign.get(prepres.camp.id)
pres.estado="Pending"
total=total+prepresus[i].total
crearCocontrato(prepresus[i])
}
Method crearCocontrato():
public crearCocontrato(Prepresupuesto prep){
Set <Azafata>azas=prep.azafatas
Cocontrato cocon=new Cocontrato()
cocon.contrato=con
cocon.precio=prep.precio
cocon.azafatas=azas
cocon.total=prep.total
cocon.horas=prep.horas
cocon.horario=prep.horario
cocon.localidad=prep.localidad
cocon.fechaInicio=prep.fechaInicio
cocon.fechaFin=prep.fechaFin
cocon.presu=prep
cocon.camp=prep.camp
if(!(cocon.save(flush:true))){
render (view:"fallos", model:[azafataInstance:cocon])
}
}
The Exception is launched in the if.
Any help? I am a bit lost, I am a newcomer to Grails, and I think i don't understand completely the exception.
Thank you!
EDIT: The Exception:
Found shared references to a collection: com.publidirecta.Cocontrato.azafatas. Stacktrace follows:
Message: Found shared references to a collection: com.publidirecta.Cocontrato.azafatas
Line | Method
->> 2448 | crearCocontrato in com.publidirecta.EntidadController$$ENmku0D2
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 2394 | boton in ''
| 886 | runTask . . . . in java.util.concurrent.ThreadPoolExecutor$Worker
| 908 | run in ''
^ 680 | run . . . . . . in java.lang.Thread
You're probably trying to save more than one entity (cocon) when both refer to the same collection. It's hard to detect that in this code you posted and it could be somewhere else, but I would say it's when you do this:
Set <Azafata>azas=prep.azafatas
cocon.presu=prep
Then when you save cocon, it points to the same collection that prep does. Take a look at this link, that says the same thing.
A way out of this would be to add element by element to the list you want to copy to instead of sharing the reference by doing a.list = b.list.
This can also help you.
Yes, Tiago, after diving a bit in the code (it is inherited code...) i found that the problem was what you are saying. I solved it by doing this:
ArrayList <Azafata> azas=new ArrayList<Azafata>()
for(int i=0;i<prep.azafatas.size(); i++){
azas.add(prep.azafatas.toArray()[i])
}
And everything was ok :) Thank you for your answer.

How to insert parameters in a secure way in ActiveRecord minimum

How can I do this, without risking an SQL injection attack?
nearest = Site.minimum('abs(latitude - ' + params[:lat] + ') - abs(longitude - ' + params[:lon] + ')', group: :id)
I've tried:
nearest = Site.minimum(['abs(latitude - ?) - abs(longitude - ?)', params[:lat], params[:lon]], group: :id)
But that doesn't seem to work. The documentation isn't very clear how to achieve this.
Thanks in advance!
Rails uses sanitize_sql_for_conditions internally for dealing with placeholders. Of course, that method is protected so you can't (cleanly) use it outside of an ActiveRecord model. You can get around the protectedness using send:
nearest = Site.minimum(
Site.send(:sanitize_sql_for_conditions, [
'abs(latitude - ?) - abs(longitude - ?)',
params[:lat].to_f, params[:lon].to_f
]
)
Or you could put that logic inside a Site class method so that you'd be allowed to use sanitize_sql_for_conditions without trickery:
class Site < ActiveRecord::Base
def self.whatever_this_is(lat, lon)
minimum(
sanitize_sql([
'abs(latitude - ?) - abs(longitude - ?)',
lat, lon
])
)
end
end
and then in your controller:
nearest = Site.whatever_this_is(params[:lat].to_f, params[:lon].to_f)
Take note of the to_f calls. If you don't include those then params[:lat] and params[:lon] will be Strings and sanitize_sql_for_conditions will quote them as such:
abs(latitude - '11.23') - abs(longitude - '42.6')
Your database may or may not be happy to see you trying to subtract a string from a number so it is best to say exactly what you mean and do the type conversion yourself.
Granted I can't tell what you're trying to accomplish from the example above, but it looks like you might be improperly using the minimum method which takes a method name as its first argument. For example:
Site.minimum(:latitude)
If you want to add conditions to it, I think you would want to use:
Site.where(country: 'USA').group(:id).minimum(:latitude)
Again, this example won't return the result you're expecting, but it should explain better how the API is used.

How can I format a post request to http://iswcnet.cisac.org/ to search without having to start from within the site?

I'm looking to open search results at http://iswcnet.cisac.org/ with the search parameters POSTed from a Greasemonkey form on another site. Plus, I hate their search interface; it'd be nice to write my own GM wrapper for it, if only I could find how to format the search.
Use URL http://iswcnet.cisac.org/iswcnet/MWI/search.do?
parameters:
firstCriteria=
What to search:
titleFirstCriteria - Title
iswcFirstCriteria - ISWC number
ipNameMwiFirstCriteria - Creator's Name
ipNameNumberFirstCriteria - Creator-Id
firstCriteriaType=
Search type:
E - 'exact'
B - 'begins with'
W - 'contains'
firstCriteriaInput= {the search term}
Example: Search for any work entry by anyone whose name contains "Cobain":
http://iswcnet.cisac.org/iswcnet/MWI/search.do?firstCriteria=ipNameMwiFirstCriteria&firstCriteriaType=B&firstCriteriaInput=Cobain

Resources