How to do a basic contextualization in JavaScript using nlp-compromise? - javascript

So I saw this awesome natural language processing in javascript and I wonder how can I do a basic contextualization?
Let's say for example, I want to get the time.
By doing something like this:
var word = nlp(`What's the time`)
console.log(word.match('time').found)
I get a true boolean since the time word is present. But what I wanted to do is for example
nlp('What's the time') and nlp('What time is it') the value will be true but if nlp('Time is gold') the value will be false since the user didn't ask for the time.
Is that possible with this library? Any help would be much appreciated.

It sounds like what you want to do is Intent Recognition, which is usually treated as a classification problem. This article gives an overview of one way to do it; take a look at the training data:
training_data.append({"class":"greeting", "sentence":"how are you?"})
training_data.append({"class":"greeting", "sentence":"how is your day?"})
training_data.append({"class":"greeting", "sentence":"good day"})
training_data.append({"class":"greeting", "sentence":"how is it going today?"})
training_data.append({"class":"goodbye", "sentence":"have a nice day"})
training_data.append({"class":"goodbye", "sentence":"see you later"})
training_data.append({"class":"goodbye", "sentence":"have a nice day"})
training_data.append({"class":"goodbye", "sentence":"talk to you soon"})
training_data.append({"class":"sandwich", "sentence":"make me a sandwich"})
training_data.append({"class":"sandwich", "sentence":"can you make a sandwich?"})
training_data.append({"class":"sandwich", "sentence":"having a sandwich today?"})
training_data.append({"class":"sandwich", "sentence":"what's for lunch?"})
Compromise doesn't have any features for text classification so it won't help you here.

yeah, like polm23 said, this feels like a statistical classification problem.
but, if you knew, (or machine-learned) sentence-templates that suggest the intent, you could locate them in compromise with the match syntax
//what time is..
if(doc.has('#QuestionWord time #Copula')){
return true
}
//time is fun..
if(doc.has('time #Copula #Adjective')){
return false
}

Related

What is the main difference between these two loops as a solution to this exercise? (learning javascript)

I am learning JS and came across this exercise:
Write a loop which prompts for a number greater than 100.
If the visitor enters another number – ask them to input again.
The loop must ask for a number until either the visitor enters a number greater than 100 or
cancels the input/enters an empty line.
Here we can assume that the visitor only inputs numbers.
There’s no need to implement a special handling for a non-numeric input in this task.
My solution works and was as follows:
let value;
while (true) {
value = prompt('Enter a number greater than 100', 0);
if (value > 100 || value === '');
console.log(value);
break;
}
The MDN solution was this, and though it is shorter and more simple, it seems to accomplish the same task.
let num;
do {
num = prompt("Enter a number greater than 100?", 0);
} while (num <= 100 && num);
Is my solution still valid? Is the MDN one more proper?
I just want to make sure I am understanding things correctly as I go.
If your solution worked before, I think you probably typed in your solution incorrectly here. I am going to assume you meant to write:
if (value > 100 || value === '') {
console.log(value);
break;
}
Since you're just starting out with JS, you will eventually learn that there will be multiple ways you can handle any given coding problem. It will not always be a good answer/wrong answer type of scenario. Sometimes there are multiple ways to accomplish the same thing.
In this example, the MSN solution is better in terms of readability and possibly safety.
The MSN solution creates a while loop with the exit condition identified in the while statement. This loop will exit when that condition is met.
In your solution, the loop will never exit on it's own, the while() statement will always evaluate to 'true'. This loop needs an explicit exit statement, which you provide with the if() condition.
Your method, although it works, is a little bit less safe in terms of code readability and overall maintenance profile. For example, a future developer could by mistake change the if() condition and inadvertently create a never ending loop.
Or, if the loop contained several dozen lines of code, a developer may miss the if condition, and may add some important code after the if condition (such code would not execute when the exit condition is met.)
Yes, this specific sample exercise is trivial, so the code complexity and readability may not matter. But in large enterprise applications with hundreds of lines of code, such code choices carry serious risks with costly implications.
That said, I'll reiterate - as you learn more about JS, you will often find that there are multiple ways of solving any given problem. Sometimes you do want to create an explicit exit condition through an if() statement, on rare occasions you will want to create a never ending loop.
As you explore more complex problems, you will find needs for such solutiosn. So keep learning, keep trying different solutions, and keep asking questions.

Getting an enum from backend and use it as a string in javascript

Today I had a rather heathed discussion with a java backend developer. I do the frontend side with jsangular. His rest service sends me an object that includes an enum. I get this as a string and need to show it in an angular grid.
The enums are very self explainable.
Examples what I get:
Person = {gender: "MAN", position: "IS_EMPLOYED"}
In the view I have to show the following:
man is employed
So i solved it in a simple and generic way:
Person.gender.toLowerCase () + ' ' + Person.position.toLowerCase ().replace ('_', ' ')
He found this terrible programming and demanded that I would make a mapper with if else or switch
So: If(Person.gender==="MAN") return "man"
Else if....
The label name is always the same as the enum name (only lower case and space instead of underscore)
He went on a rampage that it was bad coding and basically terrible and a sin against god...
So my question is this bad/good practice (so a b/w story) or rather acceptable and defendable in some cases?
Typed on my phone so I couldn't put the code examples in the right tags..
There are a few ways to look at this:
Mapping is more robust:
He is right in saying that there should be a complete mapping function. This allows you to handle errors (i.e. if the response you get for position is "banana", you should probably not just throw that out there). This is especially important in backend development when you are probably working with a strict schema.
Scale Matters:
There is nothing technically wrong with your approach. If there are a small number of entries or if the user base or application scope is small, it may not matter much. It doesn't really conform to best practices, but it works, and if that is all that matters, it might be enough. Although you should always strive for best practices, you need to keep the big picture in mind.
Efficiency:
One approach may be more efficient than the other. The difference may be negligible. In web dev, speed is a priority, and if both approaches get the same result but one is much faster, choose that one.
It'd probably be a better idea to make a client-enum map - then just send back the actual value. So you could have:
var personTypes: {
"1": "Is Employed",
..
}
Then simply send 1 back as the enum and use the lookup object:
console.log("Person status: " + personTypes[Person.position]);
Which also makes it easier to display a list of types - pick a new one, and simply send the enum back:
<select ng-model="personTypeEnum" ng-options="enum as type for (enum, type) in personTypes"></select>
Check in your console with printing object.
example if object is person then if you are rendering this object as json, gender(enum) would be as
{"success":true,"person":[{"class":"person","id":26,"comment":null,"gender":{"enumType":"com.project.Person$Gender","name":"MEN"},
so u can print person.gender.name, which will give MEN

Which three-values would you choose for a "javascript enum"?

In JavaScript, I'm building something like tic-tac-toe (but more complex). Any given field can have three values: a black piece, a white piece or nothing. What would you use to represent these values? Considering you're gonna be passing around about 300+ at a time.
I was first thinking of 'B', 'W' and 'N'. Then I thought of 0, 1 and 2 and now I'm thinking about true, false and null. Which is the better option as far as JavaScript is concerned? Faster? More idiomatic?
It is not going to make a speed difference.
Personally, I'd go with 0,1,2.
In general, I'd avoid making a difference between undefined, null and false. That will just result in some mistakes in a conditional somewhere. In your case, undefined seems a pretty poor choice anyway, because the contents of the field are not undefined/unknown, it is well-defined to be empty.
As Thilo points out you'd want to avoid having multiple values that can make the statement if(position) evaluate position as true. I'd probably go with using null as the empty value, though, as it seems to make more sense to me.
For the other values, I'd definitely go with something that it's hard to mix up. Strings aren't great, because you're going to wind up using B instead of W somewhere along the line and get annoying errors, so 1 and 2 probably aren't bad options.
Another option, though, is to make your own "enum" for the purposes - just have var black = new Object() and var white = new Object() and use those. That way it's a bit more clear what you're referring to than just 1 and 2. Much of a muchness, though.

e4x newb woes - attribute trace

Sorry if I'm doing anything really dumb, but could anybody see anything immediately wrong with the following?
var layout = new XML()
layout=
<layout color="red">
</layout>
function init()
{
post(layout.#color);
}
it returns what I assume to be a ram address rather than the value.
In the event that the software in question wants an object of type string, what is the best way to enforce that? I doubt thats the cas, but am willing to try
A string cast should work fine, e.g.:
trace(String(layout.#color));
Note that in your example there's no need to assign a new XML object to layout, since you overwrite it with the next assignment one line later.
This article is highly useful if you're just getting started with E4X.

Implementing a complicated decision table in JavaScript

Here's an implementation details question for JavaScript gurus.
I have a UI with a number of fields in which the values of the fields depend in a complicated fashion on the values of seven bits of inputs. Exactly what should be displayed for any one of the possible 128 values that is changing regularly as users see more of the application?
Right now, I've for this being implemented as a decision tree through an if-then-else comb, but it's brittle under the requirements changes and sort of hard to get right.
One implementation approach I've thought about is to make an array of values from 0x0 to 0x7F and then store a closure at each location --
var tbl; // initialize it with the values
...
tbl[0x42] = function (){ doAThing(); doAnotherThing(); }
and then invoke them with
tbl[bitsIn]();
This, at least makes the decision logic into a bunch of assignments.
Question: is there a better way?
(Update: holy crap, how'd that line about 'ajax iphone tags' get in there? No wonder it was a little puzzling.)
Update
So what happened? Basically I took a fourth option, although similar to the one I've checked. The logic was sufficiently complex that I finally built a Python program to generate a truth table in the server (generating Groovy code, in fact, the host is a Grails application) and move the decision logic into the server completely. Now the JavaScript side simply interprets a JSON object that contains the values for the various fields.
Eventually, this will probably go through one more iteration, and become data in a database table, indexed by the vector of bits.
The table driven part certainly came out to be the way to go; there have already been a half dozen new changes in the specific requirements for display.
I see two options...
Common to both solutions are the following named functions:
function aThing() {}
function anotherThing() {}
function aThirdThing() {}
The switch way
function exec(bits) {
switch(bits) {
case 0x00: aThing(); anotherThing(); break;
case 0x01: aThing(); anotherThing(); aThirdThing(); break;
case 0x02: aThing(); aThirdThing(); break;
case 0x03: anotherThing(); aThirdThing(); break;
...
case 0x42: aThirdThing(); break;
...
case 0x7f: ... break;
default: throw 'There is only 128 options :P';
}
}
The map way
function exec(bits) {
var actions = map[bits];
for(var i=0, action; action=actions[i]; i++)
action();
}
var map = {
0x00: [aThing, anotherThing],
0x01: [aThing, anotherThing, aThirdThing],
0x02: [aThing, aThirdThing],
0x03: [anotherThing, aThirdThing],
...
0x42: [aThirdThing],
...
};
in both cases you'd call
exec(0x42);
Since the situation (as you have described) is so irregular, there doesn't seem to be a better way. Although, I can suggest an improvement to your jump table. You mentioned that you have errors and duplicates. So instead of explicitly assigning them to a closure, you can assign them to named functions so that you don't have to duplicate the explicit closure.
var doAThingAndAnother = function (){ doAThing(); doAnotherThing(); }
var tbl; // initialize it with the values
...
tbl[0x42] = doAThingAndAnother;
tbl[0x43] = doAThingAndAnother;
Not that much of an improvement, but it's the only thing I could think of! You seem to have covered most of the other issues. Since it looks like the requirements change so much, I think you might have to forgo elegance and have a design that is not as elegant, but is still easy to change.
Have you considered generating your decision tree on the server rather than writing it by hand? Use whatever representation is clean, easy to work with, and modify and then compile that to ugly yet efficient javascript for the client side.
A decision tree is fairly easy to represent as data and it is easy to understand and work with as a traditional tree data structure. You can store said tree in whatever form makes sense for you. Validating and modifying it as data should also be straight forward.
Then, when you need to use the decision tree, just compile/serialize it to JavaScript as a big if-the-else, switch, or hash mess. This should also be fairly straight forward and probably a lot easier than trying to maintain a switch with a couple hundred elements.
I've got a rough example of a JavaScript decision tree tool if you want to take a look:
http://jsfiddle.net/danw/h8CFe/

Categories

Resources