How can I use Watson NLP to analyze Keywords with JS? - javascript

I am trying to create a keyword analysis using Watson NLP and JS.
I tried the following code line but the result says ReferrenceError{} and I have no idea on how to make it work..
var keywords=response.result.keywords;
print(keywords);
createElement("h3", "Main keywords of this synopsis");
nbkeywords = 3;
createP("Keywords in this synopsis are:");
createP(keywords[i].text);
}

This is an example of JSON response from the keywords feature of the Watson NLU API (reference):
{
"usage": {
"text_units": 1,
"text_characters": 1536,
"features": 1
},
"keywords": [
{
"text": "curated online courses",
"sentiment": {
"score": 0.792454
},
"relevance": 0.864624,
"emotions": {
"sadness": 0.188625,
"joy": 0.522781,
"fear": 0.12012,
"disgust": 0.103212,
"anger": 0.106669
}
},
{
"text": "free virtual server",
"sentiment": {
"score": 0.664726
},
"relevance": 0.864593,
"emotions": {
"sadness": 0.265225,
"joy": 0.532354,
"fear": 0.07773,
"disgust": 0.090112,
"anger": 0.102242
}
}
],
"language": "en",
"retrieved_url": "https://www.ibm.com/us-en/"
}
Meaning that the "keywords" key in the JSON response is an array containing other JSON objects. To print all keywords you need to loop this array, like shown below with the use of a "for" statement:
var keywords = response.result.keywords;
...
createElement("h3", "Main keywords of this synopsis");
createP("Keywords in this synopsis are:");
var numberOfKeywords = keywords.length;
for (var i = 0; i < numberOfKeywords; i++) {
createP(keywords[i].text);
}
In the official Watson NLU documentation there are Javascript examples that could also help you understand the service API. See https://cloud.ibm.com/apidocs/natural-language-understanding?code=node#keywords.
I hope this answer helps you.

Related

How to convert Excel Table to specific JSON format using Office Scripts

I'm trying to get a specific JSON output from Office Scripts in order to make an API call with Power Automate. The output I'm receiving from Power Automate does not have the format required in the API docs (link to API docs below). Tried modifying the script to get the required output but unfortunately, I'm just starting out with js, so I can't figure out what I need.
Right now, the input must come from an Excel table. I can format the excel table differently for this flow if it's needed, but nevertheless, the input must come from an Excel table. Right now, the Excel table looks like this:
This is the Office Script I am using, comes from this blog post: https://learn.microsoft.com/en-us/office/dev/scripts/resources/samples/get-table-data:
function main(workbook: ExcelScript.Workbook): TableData[] {
// Get the first table in the "WithHyperLink" worksheet.
// If you know the table name, use `workbook.getTable('TableName')` instead.
const table = workbook.getWorksheet('WithHyperLink').getTables()[0];
// Get all the values from the table as text.
const range = table.getRange();
// Create an array of JSON objects that match the row structure.
let returnObjects: TableData[] = [];
if (table.getRowCount() > 0) {
returnObjects = returnObjectFromValues(range);
}
// Log the information and return it for a Power Automate flow.
console.log(JSON.stringify(returnObjects));
return returnObjects
}
function returnObjectFromValues(range: ExcelScript.Range): TableData[] {
let values = range.getTexts();
let objectArray : TableData[] = [];
let objectKeys: string[] = [];
for (let i = 0; i < values.length; i++) {
if (i === 0) {
objectKeys = values[i]
continue;
}
let object = {}
for (let j = 0; j < values[i].length; j++) {
// For the 4th column (0 index), extract the hyperlink and use that instead of text.
if (j === 4) {
object[objectKeys[j]] = range.getCell(i, j).getHyperlink().address;
} else {
object[objectKeys[j]] = values[i][j];
}
}
objectArray.push(object as TableData);
}
return objectArray;
}
interface TableData {
"Event ID": string
Date: string
Location: string
Capacity: string
"Search link": string
Speakers: string
}
And this is the output I am getting in Power Automate when I run the Office Script:
[
{
"Line": "",
"Id": "0",
"Description": "nov portion of rider insurance",
"Amount": "100",
"DetailType": "JournalEntryLineDetail",
"JournalEntryLineDetail": "",
"PostingType": "Debit",
"AccountRef": "",
"value": "39",
"name": "Opening Bal Equity"
},
{
"Line": "",
"Id": "",
"Description": "nov portion of rider insurance",
"Amount": "100",
"DetailType": "JournalEntryLineDetail",
"JournalEntryLineDetail": "",
"PostingType": "Credit",
"AccountRef": "",
"value": "44",
"name": "Notes Payable"
}
]
BUT, the schema I need looks like this (it is based on this API doc https://developer.intuit.com/app/developer/qbo/docs/api/accounting/all-entities/journalentry):
{
"Line": [
{
"Id": "0",
"Description": "nov portion of rider insurance",
"Amount": 100.0,
"DetailType": "JournalEntryLineDetail",
"JournalEntryLineDetail": {
"PostingType": "Debit",
"AccountRef": {
"value": "39",
"name": "Opening Bal Equity"
}
}
},
{
"Description": "nov portion of rider insurance",
"Amount": 100.0,
"DetailType": "JournalEntryLineDetail",
"JournalEntryLineDetail": {
"PostingType": "Credit",
"AccountRef": {
"value": "44",
"name": "Notes Payable"
}
}
}
]
}
There are a lot of differences and obviously, when I try to make the API call, I get a 400 'Bad request' error. Does anyone know how I must modify either the Script or the Excel table or do something different in Power Automate in order to get the specific schema I need?
Any help will be appreciated. Thanks!!
I think the core of what's going on is that your script is parsing everything to match a linear "TableData" interface given in the tutorial you followed before it sends it to the Stringify method, but your data doesn't match that interface, so it does the best it can and outputs each individual row into an object array. When Stringify gets called, it sees an array of plain objects, so it just converts everything to a string.
I think you want this to be a bit more structured, which means you'll want to hand-code the objects you're passing for each of your rows. Basically, what your JSON schema is telling you is that your data types should be something like this:
Interface AccountRefPart {
value: string
name: string
}
Interface JournalEntryLineDetailPart {
PostingType: string
AccountRef: AccountRefPart
}
Interface LinePart {
ID?: string
Description: string
Amount: number
DetailType: string
JournalEntryLineDetail: JournalEntryLineDetailPart
}
Interface TableData {
Line: LinePart[]
}
If you just want to pass a single Line element as a JSON (what the outer-most curly braces suggest), you'll want to stringify a single object of the TableData type, and you want to construct this object using the data from the rows of your table. (I can't actually see your table, but I trust that it has the information you need above.)

How to access an array of objects with tooltip.format() from anychart.js

I am having trouble trying to present an array of objects on the tooltip of an Anychart.js map. I understand that we can access the dataset by doing something like: %[name of property in data set]. My data set has the following form:
{
"country": "Austria",
"id": "AT",
"continent": "Europe",
"songs": [
{
"rank": 33,
"title": "Stuck with U (with Justin Bieber)",
"artists": "Ariana Grande, Justin Bieber",
"album": "Stuck with U",
"explicit": 0,
"duration": "3:48"},
{
"rank": 34,
"title": "Late Night",
"artists": "Luciano",
"album": "Late Night",
"explicit": 0,
"duration": "3:20"
},
... more objects
]
}
}
If I wanted to access the Country property I would simply add it to the tooltip by doing:
tooltip.format("Country: " + {%country});
The issue is when trying to access an array of objects, I have tried different variations and none of them worked. Trying to show the title of every song:
tooltip.format({%songs}.{%title});
tooltip.format({%songs.%title});
tooltip.format({%songs}[{%title}]);
I also saw in the documentation that we can send a function as argument so I tried the following where I would concatenate every title of the collection but did not succeed either:
tooltip.format(function() {
let concatenated = '';
this.songs.forEach(song => {
concatenated += song + ' ';
});
return concatenated;
});
I would really appreciate your help guys.
String tokens do not support nested objects/properties. But you can use the callback function of the formatted to get access to songs. The context prototype includes getData() method provides that. Like this:
series.tooltip().format(function() {
console.log(this.getData('songs'));
return 'tooltip';
});
For details, check the live sample we prepared.
In case any one else is looking for a solution to this answer. I figured out how to loop through an embed array, and call on specific information.
chart.edges().tooltip().format(function () {
var format = ''
var songs = this.getData('songs');
songs.forEach(function (data, builtin, dom) {
format = '<p>'+data['title']+' by '+data['artists']+' </span></p>' + format
});
console.log(format)
return format
});

AWS DynamoDB Transactions with JavaScript: One or more parameter values were invalid

Help me, Obi-Wan...
I'm trying to do a docClient.transactWrite(params), where my params look like (there are other fields too, trying to keep this fairly short):
{
"TransactItems": [
{
"Put": {
"Item": {
"slug": {
"S": "marbled_crockpot_cheesecake"
},
"tag": {
"S": "metadata"
},
"recipe_name": {
"S": "Marbled Crockpot Cheesecake"
}
},
"TableName": "recipes-table-dev"
}
},
{
"Put": {
"Item": {
"slug": {
"S": "marbled_crockpot_cheesecake"
},
"tag": {
"S": "marbled"
},
"recipe_name": {
"S": "Marbled Crockpot Cheesecake"
}
},
"TableName": "recipes-table-dev"
}
}
]
}
As near as I can tell by looking at this example and the official documentation it's fine, but whenever I run it I get to following error:
ERROR Error performing transactWrite { cancellationReasons:
[ { Code: 'ValidationError',
Message:
'One or more parameter values were invalid: Type mismatch for key slug
expected: S actual: M' } ],
I should point out that the Primary partition key is slug (String) and the Primary sort key tag (String). So I don't understand the Type mismatch for key slug expected: S actual: M phrase: If it's expecting S, well, that's what I sent, right? I don't see an M in there anywhere.
Note the following when working with the Document Client (which offers a higher level API than the DynamoDB class):
The document client simplifies working with items in Amazon DynamoDB by abstracting away the notion of attribute values. This abstraction annotates native JavaScript types supplied as input parameters, as well as converts annotated response data to native JavaScript types.
The document client affords developers the use of native JavaScript types instead of AttributeValues to simplify the JavaScript development experience with Amazon DynamoDB. JavaScript objects passed in as parameters are marshalled into AttributeValue shapes required by Amazon DynamoDB. Responses from DynamoDB are unmarshalled into plain JavaScript objects by the DocumentClient. The DocumentClient, does not accept AttributeValues in favor of native JavaScript types.
This means that slug must be a plain string (S) and not a map (M) with attribute type.
The following should work:
{
"TransactItems": [
{
"Put": {
"Item": {
"slug": "marbled_crockpot_cheesecake",
"tag": "metadata",
"recipe_name": "Marbled Crockpot Cheesecake",
},
"TableName": "recipes-table-dev"
}
},
{
"Put": {
"Item": {
"slug": "marbled_crockpot_cheesecake",
"tag": "marbled",
"recipe_name": "Marbled Crockpot Cheesecake"
},
"TableName": "recipes-table-dev"
}
}
]
}
When working directly with the DynamoDB class (lower level) attribute types must be specified.

Replacing all instances of a value in JSON using pure JavaScript

Is it possible using JavaScript only to replace all instances of the version with another number and then return the JSON structure intact?
{
"savedSearches": [{
"id": 123,
"version": 10,
"name": "Project Manager",
"query": "www.foo.com"
}, {
"id": 123,
"version": 10,
"name": "Project Manager",
"query": "www.foo.com"
}],
"deletedSavedSearches": []
}
I need this to be very quick and lightweight as I'll be using it within JMeter.
JSON structure is nothing more than a JavaScript object. You can iterate over its properties and modify their values as usual. For instance, to increase each version by one:
var json = { … }
for (var i in json.savedSearches) json.savedSearches[i].version += 1;
You can try this
var jsonObject = JSON.parse(yourJSONString);
for(var i = 0, len = jsonObject.savedSearches.length; i < len; i++) {
jsonObject.savedSearches[i].version = "Number you want here";
}
If you, for some reason, want to return a string:
JSON.stringify(jsonObject)
If you already have the object, you can skip the JSON.parse

how to access individual elements of a javascript object literal?

I have a javascript object literal?
I access them in my webpage as
data.list[i].ger or data.list[i].eng
If I want to directly search an entry how can I directly access that entry?
or do I have to do a linear search or a binary search upon sort?
data = {
list: [
{
"ger": "A-as",
"eng": "A as"
},
{
"ger": "A-aws",
"eng": "a-was "
},
{
"ger": "we",
"eng": "cv"
},
{
"ger": "q",
"eng": "w-la-w"
},....
for e.g. if i wanted to access
"ger": "q","eng": "w-la-w"
I would acces it as data.list[4].ger
is there any way of directly accessing knowing what is the index of that entry?
I think you may be looking for JSONSelect. It makes it easy to access data in complex JSON documents, but looks like CSS.
Check out the examples, it looks pretty much like what you want to do.
For instance, to get the eng version of ger:q, you would do .ger:val("q") ~ .eng
You can download it here and use it with JSONSelect.match or JSONSelect.forEach.
If you just want to search through your array, I'd go with something like
function lookupTrans(value, fromLang, toLang) {
for (var i = 0, dataLen = data.list.length; i < dataLen; i++) {
if (data.list[i][fromLang] === value) {
return data.list[i][toLang];
// return i (if you're lookup for just the index number)
}
}
return "";
}
However, I do want to make sure you're not trying to just do one-way internationalization. If that's the case, I'd recommend just using named keys:
var i18n = {
"translation": {
"en": "translation",
"ja": "hon'yaku"
},
"list": {
"en": "list",
"ja": "risuto"
},
"example": {
"en": "example",
"ja": "rei"
},
"imbueWithConfidence": {
"en": "Let's translate!",
"ja": "Hon'yaku shimashou!"
}
};

Categories