Any examples of using multilogicadapter in chatterbot? - python-3.x

I am trying to combine multiple logic adapters in Python chatterbot. I cannot seem to get it right. I tried this:
english_bot = ChatBot("English Bot",
storage_adapter="chatterbot.storage.SQLStorageAdapter",
multi_logic_adapter = [
"chatterbot.logic.MathematicalEvaluation",
"chatterbot.logic.TimeLogicAdapter",
"chatterbot.logic.BestMatch"]
)
Only BestMatch seems to be active
And I tried this:
english_bot = ChatBot("English Bot",
storage_adapter="chatterbot.storage.SQLStorageAdapter",
logic_adapter = [
"chatterbot.logic.multi_adapter.MultiLogicAdapter",
"chatterbot.logic.MathematicalEvaluation",
"chatterbot.logic.TimeLogicAdapter",
"chatterbot.logic.BestMatch"]
)
But I get this error: AttributeError: 'NoneType' object has no attribute 'confidence' and none of the logic_adapters seems to be active.
Thanks,
Herb

BestMatch
Adapter is the default adapter for chatterbot, You don't need explicitly specify that. More information http://chatterbot.readthedocs.io/en/stable/logic/index.html#best-match-adapter
And you code should like this
# -*- coding: utf-8 -*-
from chatterbot import ChatBot
bot = ChatBot(
"English Bot",
logic_adapters=[
"chatterbot.logic.MathematicalEvaluation",
"chatterbot.logic.TimeLogicAdapter"
]
)
# Print an example of getting one math based response
response = bot.get_response("What is 4 + 9?")
print(response)
# Print an example of getting one time based response
response = bot.get_response("What time is it?")
print(response)

Every logic adapter in logic_adapters=[] is automatically processed by MultiLogicAdapter. You might need to tweak the confidence levels though.
More info about the MultiLogicAdapter here:
http://chatterbot.readthedocs.io/en/stable/logic/multi-logic-adapter.html

Multi Logic adapter is an inbuilt class and is not explicitly defined in the code.You can see this statement in the introduction part:"ChatterBot internally uses a special logic adapter that allows it to choose the best response generated by any number of other logic adapters" This is the link - http://chatterbot.readthedocs.io/en/stable/logic/multi-logic-adapter.html
Also, similar query is already available on stackover flow. Refer this as well.
Error while using chatterbot

The MultiLogicAdapter typically doesn't get used directly in this way.
Each logic adapter that you add to the logic_adapters=[] will get processed by the MultiLogicAdapter internally by ChatterBot, no need to explicitly specify it.

Related

Read variables value from PLC with Python opcua-asyncio – BadNoMatch: “The requested operation has no match to return.”

Edited to correct some typos:
Hi I’m new to opcua-asyncio package so please be patient if I missed something really obvious, I’m trying to figure out how to connect to a Siemens S7 1200 CPU 1212C firmware version 14 PLC from Python (3.11) and read some variables values.
I’m sorry I can’t figure out a way to support my case with a reproducible example because it’s intrinsically connected to the test PLC I’m working with, if you can suggest a way to make it reproducible I’m going to amend the answer accordingly.
The structure on my test PLC is detailed in the picture, I can access it through different clients, the variables from t1 to t19 are my goal.
[PLC Structure][1]
I went through the documentation (especially the client minimal example ) and some stackoverflow answers and I wrote the following code
# modules
import asyncio
from asyncua import Client
# url and namespace
url = foo bar # the plc location on the network
namespace = "OPC-UA:PLC_1"
t2 =[]
# I can find the objects inside the node
async with Client(url=url) as client:
# Find the namespace index
nsidx = await client.get_namespace_index("urn:OPC-UA:PLC_1")
print(nsidx)
root = client.nodes.root
print("Root node is: ", root)
objects = client.nodes.objects
print("Objects node is: ", objects)
# I can’t find my variables
var = await client.nodes.root.get_child(
["0:Objects", "3:ServerInterfaces", "0:Face"])
print("Var is: ", var)
t2 = await var.get_children_descriptions()
print(t2)
By my understanding of the structure in OPC-UA:PLC_1 namespace I should find an “Objects” node object listing a “ServerInterfaces” node object listing a “Face” node object listing the variables from t1 to t19. However if I ask “Objects” to describe its childs through get_children_descriptions() I can see the ServerInterfaces node object however this Serverinterfaces appears to be named “Face”.
If I ask for the childrens of “Face” I receive a BadNoMatch error.
Any help pointing me to the right direction would be much appreciated. Thank you!
[1]: https://i.stack.imgur.com/QyQCJ.png
I think the Browsename namespace index of Face is wrong.
The index 0 is used for the base nodeset.
You can check the correct index with an other UA Client like the UAExpert (here you need to look at the attibute window not the address space window (which do not show the namespace index)).
If you defined the Face in the face "OPC-UA:PLC_1" the line should be:
var = await client.nodes.root.get_child(
["0:Objects", "3:ServerInterfaces", "3:Face"])

How do I use build_full_result() in Boto3

I was Googling around to understand how boto3 paginator works, and found a solution that potentially doesn't require writing any logic with NextToken and While loops.
Still, I'm not quite sure what I'm getting when I'm using this:
client = boto3.client('ec2', region_name='eu-west-1')
results = (
client.get_paginator('describe_instances')
.paginate()
.build_full_result()
)
print(results)
I got a huge JSON output and I'm not sure whether I got what I wanted, which is basically the output of all of my EC2 instances.
I'm also not sure how to loop over it, I keep getting TypeError: string indices must be integers which didn't happen before when I used something like:
for instance in response_iterator:
instance = instance['Reservations'][0]
instance_id = instance['Instances'][0]['InstanceId']
print(instance_id)
I would love to understand how to use the build_full_result() method.
I saw a post that says that it's not documented yet, pretty recent to now (as of writing this post).
Interesting find.. this isn't mentioned anywhere in the latest version of boto3 documentation, however it does appear to properly return all available results.
Below is an example from Lambda that shows how to perform a simple loop through the response.. you can update the last two lines to handle the response syntax from EC2 describe instances.
import boto3
client = boto3.client('lambda')
results = (
client.get_paginator('list_functions')
.paginate()
.build_full_result()
)
for result in results['Functions']:
print(result['FunctionName'])

What happened to the metadata object in IBM's Natural Language Understanding?

I used to work with IBM's Natural Language Understanding API for analyzing URLs. I am using Python's IBM Watson SDK 5.1 on Python 3.8.
I successfully used the code below [all approprioate options have been imported] to extract metadata, in addition to entities, concepts, etc:
def NLU_analysis(url):
try:
response = natural_language_understanding.analyze(
url=url, return_analyzed_text=True, clean=True, language=True,
features=Features(keywords=KeywordsOptions(limit=10),
entities=EntitiesOptions(limit=10),
concepts=ConceptsOptions(limit=5),
metadata=MetadataOptions(),
categories=CategoriesOptions(limit=5))).get_result()
return response
except:
pass
The code above used to return the metadata. Now, in Python SDK 5.1.0, IBM recently changed to way to retrieve the URL's metadata. The "MetadataOptions" feature has been replaced by "FeatureMetadataResults". If I use the code above and replace the MetadataOptions by FeatureMetadataResults as shown below:
def NLU_analysis(url):
try:
response = natural_language_understanding.analyze(
url=url, return_analyzed_text=True, clean=True, language=True,
features=Features(keywords=KeywordsOptions(limit=10),
entities=EntitiesOptions(limit=10),
concepts=ConceptsOptions(limit=5),
metadata=FeaturesResultsMetadata(),
categories=CategoriesOptions(limit=5))).get_result()
return response
except:
pass
Now, if I run the modified code, I get the following error message:
"TypeError: Object of type FeaturesResultsMetadata is not JSON serializable"
If I read IBM's documentation, I am getting somewhat confused (Link to the API documentation. Here's the IBM's code example:
import json
from ibm_watson import NaturalLanguageUnderstandingV1
from ibm_cloud_sdk_core.authenticators import IAMAuthenticator
from ibm_watson.natural_language_understanding_v1
import Features, MetadataOptions
authenticator = IAMAuthenticator('{apikey}')
natural_language_understanding = NaturalLanguageUnderstandingV1(
version='2020-08-01',
authenticator=authenticator
)
natural_language_understanding.set_service_url('{url}')
response = natural_language_understanding.analyze(
url='www.ibm.com',
features=Features(metadata=MetadataOptions())).get_result()
Does anyone know whether it is still possible to retrieve an URL's metadata using IBM Watson's Natural Language Understanding API?
Have a nice day!
It appears that the sample in IBM's API-documentation is incorrect.
The code below has been pasted as plain text, to be able to strike through obsolete elements in IBM's sample code.
import json
from ibm_watson import NaturalLanguageUnderstandingV1
from ibm_cloud_sdk_core.authenticators import IAMAuthenticator
from ibm_watson.natural_language_understanding_v1
import Features, MetadataOptions
authenticator = IAMAuthenticator('{apikey}')
natural_language_understanding = NaturalLanguageUnderstandingV1(
version='2020-08-01',
authenticator=authenticator
)
natural_language_understanding.set_service_url('{url}')
response = natural_language_understanding.analyze(
url='www.ibm.com',
features=Features(metadata=MetadataOptions() {} )).get_result()
print(json.dumps(response, indent=2))
So for requesting the metadata object, just provide an empty dictionary (metadata={})
Enjoy your day!
Joost

Invoke autoscript (has WO object launch point) when Service Address is updated?

I have a WO in Maximo 7.6.1.1.
When a user updates the Service Address, I want to invoke an autoscript that has an Object Launch Point on the WORKORDER object.
Is there a way to invoke an autoscript (that has an object launch point on the WORKORDER object) when the Service Address is updated?
You should see if mbo.getOwner() returns something and if that something.getName() is WORKORDER and, further, the work order you are expecting it to be. Subject to all that, you can invoke that other autoscript with code like this:
from java.util import HashMap
lpVars = HashMap()
lpVars.put("mbo",mbo.getOwner())
#repeat the last line for any other implicit/explicit variables your target
#script is going to use / expect to be defined
service.invokeScript("YOURSCRIPTNAME", lpVars)
someVar = lpVars.get("someVarDefinedInYOURSCRIPTNAMEWhenItEnded")
Note the work with the lpVars variable. I use it to store the "implicit"/"explicit" variables (e.g. "mbo") that the script I'm calling will expect to be defined. Basically, I'm doing the setup a launch point normally does, since my code is the launch point. Then, since I'm the launch point, I have access to whatever variables were defined when the script ended by Maximo adding them to / updating them in lpVars.
You can create reusable "library" scripts that you can call directly as Preacher explained. See IBM example here: https://www.ibm.com/support/knowledgecenter/SSFGJ4_7.6.0/com.ibm.mbs.doc/autoscript/c_example_reuse.html
So you could have your WO object launchpoint call the library script and your SA object launchpoint calling the same. You then just need to make change to one script if needed and that's great.
I don't believe you can. An object launch point is all about telling Maximo which object to monitor for the following event(s), not exactly about which object to launch the script on (though, for various reasons, those two are necessarily tied together).
What you can do, though, is put your launch point on the service address as you really do want, but then in your script fetch the on-screen/in-memory work order that you want to do something with and do that. This is done through the getOwner() method call or the special ":owner" (maybe with the ampersands, I can't remember) relationship reference.
This is the solution I came up with:
mboName=mbo.getName()
if mboName == 'WOSERVICEADDRESS':
mboWO = mbo.getOwner()
elif mboName == 'WORKORDER':
mboWO=mbo
sax = mboWO.getDouble("SERVICEADDRESS.LONGITUDEX")
say = mboWO.getDouble("SERVICEADDRESS.LATITUDEY")
if sax and say:
mboWO.setValue("longitudex", sax)
mboWO.setValue("latitudey", say)
elif mboWO.getString("ASSETNUM") and mboWO.getBoolean("ASSET.PLUSSISGIS") == 1:
mboWO.setValue("longitudex", mboWO.getDouble("ASSET.longitudex"))
mboWO.setValue("latitudey", mboWO.getDouble("ASSET.latitudey"))
elif mboWO.getString("LOCATION") and mboWO.getBoolean("LOCATION.PLUSSISGIS") == 1:
mboWO.setValue("longitudex", mboWO.getDouble("LOCATION.longitudex"))
mboWO.setValue("latitudey", mboWO.getDouble("LOCATION.latitudey"))
else:
mboWO.setValue("longitudex", None)
mboWO.setValue("latitudey", None)
The script has launch points on multiple objects:

How to translate error messages in Colander

How can I translate the error messages from the colander validators? The documentation just says that it's possible.
def valid_text(node, value):
raise Invalid(node, u"Some error message")
class form(colander.MappingSchema):
name = colander.SchemaNode(colander.String(), validator=valid_text)
I know that deform does it already but I need to use colander on his own.
According to the API documentation, the msg argument to Invalid can be a translation string instance. Information on working with translation strings is here.
Looks like this issue was already addressed and fixed, but it will be part of the next release. I've just added the changes from commit f6be836 and it works like a charm.

Resources