Formflow bot confused with enum answer position vs answer text - botframework

I have a formflow dialog that has the following question defined as an enum
public enum PreviousOwnerOptions
{
[Describe("Owned from new")]
[Terms("0", "new", ".*[O|o]wned from new")]
OwnedFromNew = 0,
[Terms("1", "One")]
One,
[Terms("2", "Two")]
Two,
[Terms("3", "Three")]
Three,
[Terms("4", "Four")]
Four,
[Terms("5", "Five")]
Five,
[Terms("6", "Six")]
Six,
[Describe("More than six")]
[Terms(".*More than six", "more")]
MoreThanSix
}
Here is how the question appears to the user...
The problem I have is that if you enter, say, the number "3" as an answer, then the response is this...
It looks like the bot is not sure whether I meant the answer in position 3, or the answer "Three". I thought the Terms attribute would take care of that clarification?
How can I fix this please?

This is happening because of a combination of 2 things.
First, you are trying to use the 0 Enum values on what appears to be a non-nullable field. The 0 value is reserved for null in this case. From the formflow docs page:
Any of the data types may be nullable, which you can use to model that the field does not have a value. If a form field is based on an enumeration property that is not nullable, the value 0 in the enumeration represents null (i.e., indicates that the field does not have a value), and you should start your enumeration values at 1. FormFlow ignores all other property types and methods.
The second piece of this is that since you are using the numerical values of 1,2,3 etc in your Terms attribute like [Terms("1", "One")] by default formflow will try to align these values with the correct enumeration. So what I think is happening is that it is letting you select "3" as you used in your example and since 3 is one of your terms [Terms("3", "Three")] it offeres you that options. but in the zero index enumeration values since 0 is reserved, the actual enumeration value of [Terms("2", "Two")] Two, is 3. So it doesn't know which you mean.
So in order to get this to work using these terms would be like this:
public enum PreviousOwnerOptions
{
[Terms("1", "One")]
One=1,
[Terms("2", "Two")]
Two,
[Terms("3", "Three")]
Three,
[Terms("4", "Four")]
Four,
[Terms("5", "Five")]
Five,
[Terms("6", "Six")]
Six,
[Describe("More than six")]
[Terms(".*More than six", "more")]
MoreThanSix,
[Describe("Owned from new")]
[Terms("new", ".*[O|o]wned from new")]
OwnedFromNew
}

Related

How to convert a string to enum in Godot?

Using Godot 3.4, I have an enum setup as:
enum {
STRENGTH, DEXTERITY, CONSTITUTION, INTELLIGENCE, WISDOM, CHARISMA
}
And I would like to be able to make the string "STRENGTH" return the enum value (0). I would like the below code to print the first item in the array however it currently presents an error that STRENGTH is an invalid get index.
boost = "STRENGTH"
print(array[boost])
Am I doing something wrong or is there a function to turn a string into something that can be recognised as an enum?
First of all, your enum needs a name. Without the name, the enum is just a fancy way to make a series of constants. For the purposes of this answer, I'll use MyEnum, like this:
enum MyEnum {
STRENGTH, DEXTERITY, CONSTITUTION, INTELLIGENCE, WISDOM, CHARISMA
}
Now, we can refer to the enum and ask it about its elements. In particular, we can figure out what is the value associated with a name like this:
var boost = "DEXTERITY"
print("Value of ", boost, ": ", MyEnum.get(boost))
That should print:
Value of DEXTERITY: 1
By the way, if you want to get the name from the value, you can do this:
var value = MyEnum.DEXTERITY
print("Name of ", value, ": ", MyEnum.keys()[value])
That should print:
Name of 1: DEXTERITY
What you are getting is just a regular dictionary preset with the contents of the enum. So, we can ask it about all the values:
for boost in MyEnum:
print(boost)
Which will print:
STRENGTH
DEXTERITY
CONSTITUTION
INTELLIGENCE
WISDOM
CHARISMA
And we can also ask it if it has a particular one, for example print(MyEnum.has("ENDURANCE")) prints False.
And yes you could edit the dictionary. It is just a dictionary you get initialized with the values of the enum.

What are scalar types in GraphQL

From their docs, it says:
The leaf values of any request and input values to arguments are Scalars (or Enums) and are defined with a name and a series of serialization functions used to ensure validity
but I am unable to comprehend that definition. From the answer to my previous question, I think scalars are associated with enums. Can someone break down in simpler terms what do GraphQL scalar types do and when to use scalar types as opposed to enum types?
Scalars are equivalent to primitive data types in a programming language. In GraphQL, there are five built-in scalar types:
Boolean, true or false
Int, a signed 32‐bit numeric non‐fractional value
Float, a signed double‐precision fractional values
String, a sequence of UTF‐8 characters
ID, a unique identifier
A scalar simply represents a single value and are the basic building blocks of your schema. This is in comparison to object types, which represent a collection of values. An object type has fields, and each field has a type which may be a scalar or an object type itself. If the field's type is an object, that object will have fields that are also scalars or other objects, and so on. In this way we end up with a tree-like structure in both our schema and the queries made against it.
query { # <- The "root" of the tree
movies {
actors {
name # <- A "leaf" on the tree
}
crew {
name # <- Another "leaf"
}
}
}
Enums are similar to scalars, in that an enum represents a single, concrete value. However, each enum type is defined explicitly in the schema (there are no "built-in" enums) and its definition must include a set of values that the enum type can be. For example, we might create an enum like:
enum Animal {
Cat
Dog
Bird
}
A field that returns an Animal will still have a single value, like a scalar, but that value will be either "Cat", "Dog" or "Bird" -- no other values are allowed.
A leaf type is a term that encompasses both scalars and enums. Leaf types represent the leaves or terminating points in our tree-like queries and their responses.
When a field returns an object type (like movies, actors, or crew in the above example), we have to tell GraphQL which of the object type's fields we want to query. This selection of fields is called a selection set and is wrapped by curly brackets. In our example, name is the selection set for the crew field, crew and actors are the selection set for the movies field, and even the movies field is part of the selection set for the query root type.
The important thing to notice here is that leaf types do not have fields, so any field that returns a leaf type will not have a selection set.
For more information, you can check out the official spec.

What's the usage of org.springframework.data.repository.query.parser.Part?

As you can see in the title , I'd appreciate it if somebody can tell the usage of the Class .
There's a inside enum Type ,how to use it?
public static enum Type {
BETWEEN(2, "IsBetween", "Between"), IS_NOT_NULL(0, "IsNotNull", "NotNull"), IS_NULL(0, "IsNull", "Null"), LESS_THAN(
"IsLessThan", "LessThan"), LESS_THAN_EQUAL("IsLessThanEqual", "LessThanEqual"), GREATER_THAN("IsGreaterThan",
"GreaterThan"), GREATER_THAN_EQUAL("IsGreaterThanEqual", "GreaterThanEqual"), BEFORE("IsBefore", "Before"), AFTER(
"IsAfter", "After"), NOT_LIKE("IsNotLike", "NotLike"), LIKE("IsLike", "Like"), STARTING_WITH("IsStartingWith",
"StartingWith", "StartsWith"), ENDING_WITH("IsEndingWith", "EndingWith", "EndsWith"), NOT_CONTAINING(
"IsNotContaining", "NotContaining", "NotContains"), CONTAINING("IsContaining", "Containing", "Contains"), NOT_IN(
"IsNotIn", "NotIn"), IN("IsIn", "In"), NEAR("IsNear", "Near"), WITHIN("IsWithin", "Within"), REGEX(
"MatchesRegex", "Matches", "Regex"), EXISTS(0, "Exists"), TRUE(0, "IsTrue", "True"), FALSE(0, "IsFalse",
"False"), NEGATING_SIMPLE_PROPERTY("IsNot", "Not"), SIMPLE_PROPERTY("Is", "Equals");
// Need to list them again explicitly as the order is important
// (esp. for IS_NULL, IS_NOT_NULL)
private static final List<Part.Type> ALL = Arrays.asList(IS_NOT_NULL, IS_NULL, BETWEEN, LESS_THAN, LESS_THAN_EQUAL,
GREATER_THAN, GREATER_THAN_EQUAL, BEFORE, AFTER, NOT_LIKE, LIKE, STARTING_WITH, ENDING_WITH, NOT_CONTAINING,
CONTAINING, NOT_IN, IN, NEAR, WITHIN, REGEX, EXISTS, TRUE, FALSE, NEGATING_SIMPLE_PROPERTY, SIMPLE_PROPERTY);
...}
Part is internal to Spring Data. It is not intended to be used by client code. So if you don't implement your own Spring Data Modul you shouldn't use it at all nor anything inside it.
A Part is basically an element of an AST that will probably result in an element of a where clause or equivalent depending on the store in use.
E.g. if you have a method findByNameAndDobBetween(String, Date, Date) parsing the method name will result in two parts. One for the name condition and one for the DOB between condition.
The type enum lists all the different types of conditions that are possible.
The parameters of the elements are the number of method arguments required and (possibly multiple) Strings that identify this type inside a method name.

Look up Enum by label instead of by value

Is there a quick way to look up an Enum with only using the label of the enum instead of the value. Let's say the Enum type is SalesStatus, I want to be able to basically call into some kind of a function like enumLabel2Value(enumStr(SalesStatus), "Open order") and it will return 1.
I'm trying to avoid looping thru all possible values and checking each one separately, it seems like this should be something that's readily available since whenever a user filters on a enum column on a grid, they enter in the label, not the value, but I haven't seen anything like it.
You can use the str2Enum function for that. From the documentation:
Retrieves the enum element whose localized Label property value
matches the input string.
In addition to the caveats from Alex Kwitny's answer, I recommend taking a look at the comments of the documentation, specifically the comment
Please note that str2Enum performs partial matching and matches the
beginning of the string. If there are multiple matches, it will take
the first one.
In addition take a look at method string2Enum of class DMFEntityBase, which supports different options how the enum element can be specified. I think with the DictEnum.name2Value() method enum elements specified by their label are handled.
Update
OP mentioned in the comments to Alex Kwitny's answer that it is a specific enum ExchangeRateDisplayFactor he has issues with. str2Enum also works with that enum, as the following job demonstrates:
static void str2EnumTest(Args _args)
{
ExchangeRateDisplayFactor factor;
factor = str2Enum(factor, '1');
info(strFmt('%1', factor)); // outputs '1'
factor = str2Enum(factor, '10');
info(strFmt('%1', factor)); // outputs '10'
factor = str2Enum(factor, '100');
info(strFmt('%1', factor)); // outputs '100'
factor = str2Enum(factor, '1000');
info(strFmt('%1', factor)); // outputs '1000'
factor = str2Enum(factor, '10000');
info(strFmt('%1', factor)); // outputs '10000'
}
It doesn't exist because labels can be all sorts of things in different languages. symbol2Value() exists though and may be what you're looking for, but your question is specifically on labels. An example of where this could be very bad...
Let's say you have an enum called GoodBadPresent, to indicate what type of Christmas present you will receive, with two values:
GoodBadPresent::Poison English label: "Poison"; German label: "Gift"
GoodBadPresent::Gift English label: "Gift"; German label: "Geschenk"
If this example isn't clear, the word for Poison in German is Gift. So if you tried to resolve Gift to an enum value, you'd also have to provide the language. The performance problems here are probably greater than the performance problems of looping through an enum.
You can look at DictEnum to see if there are any methods that can help you more succinctly achieve what you want though. https://msdn.microsoft.com/en-us/library/gg837824.aspx
I'm more curious to the details of your scenario where you need to get back to an enum from a label.

Sense of Optional.orElse() [duplicate]

Why does this throw a java.lang.NullPointerException?
List<String> strings = new ArrayList<>();
strings.add(null);
strings.add("test");
String firstString = strings.stream()
.findFirst() // Exception thrown here
.orElse("StringWhenListIsEmpty");
//.orElse(null); // Changing the `orElse()` to avoid ambiguity
The first item in strings is null, which is a perfectly acceptable value. Furthermore, findFirst() returns an Optional, which makes even more sense for findFirst() to be able to handle nulls.
EDIT: updated the orElse() to be less ambiguous.
The reason for this is the use of Optional<T> in the return. Optional is not allowed to contain null. Essentially, it offers no way of distinguishing situations "it's not there" and "it's there, but it is set to null".
That's why the documentation explicitly prohibits the situation when null is selected in findFirst():
Throws:
NullPointerException - if the element selected is null
As already discussed, the API designers do not assume that the developer wants to treat null values and absent values the same way.
If you still want to do that, you may do it explicitly by applying the sequence
.map(Optional::ofNullable).findFirst().flatMap(Function.identity())
to the stream. The result will be an empty optional in both cases, if there is no first element or if the first element is null. So in your case, you may use
String firstString = strings.stream()
.map(Optional::ofNullable).findFirst().flatMap(Function.identity())
.orElse(null);
to get a null value if the first element is either absent or null.
If you want to distinguish between these cases, you may simply omit the flatMap step:
Optional<String> firstString = strings.stream()
.map(Optional::ofNullable).findFirst().orElse(null);
System.out.println(firstString==null? "no such element":
firstString.orElse("first element is null"));
This is not much different to your updated question. You just have to replace "no such element" with "StringWhenListIsEmpty" and "first element is null" with null. But if you don’t like conditionals, you can achieve it also like:
String firstString = strings.stream()
.map(Optional::ofNullable).findFirst()
.orElseGet(()->Optional.of("StringWhenListIsEmpty"))
.orElse(null);
Now, firstString will be null if an element exists but is null and it will be "StringWhenListIsEmpty" when no element exists.
You can use java.util.Objects.nonNull to filter the list before find
something like
list.stream().filter(Objects::nonNull).findFirst();
The following code replaces findFirst() with limit(1) and replaces orElse() with reduce():
String firstString = strings.
stream().
limit(1).
reduce("StringWhenListIsEmpty", (first, second) -> second);
limit() allows only 1 element to reach reduce. The BinaryOperator passed to reduce returns that 1 element or else "StringWhenListIsEmpty" if no elements reach the reduce.
The beauty of this solution is that Optional isn't allocated and the BinaryOperator lambda isn't going to allocate anything.
Optional is supposed to be a "value" type. (read the fine print in javadoc:) JVM could even replace all Optional<Foo> with just Foo, removing all boxing and unboxing costs. A null Foo means an empty Optional<Foo>.
It is a possible design to allow Optional with null value, without adding a boolean flag - just add a sentinel object. (could even use this as sentinel; see Throwable.cause)
The decision that Optional cannot wrap null is not based on runtime cost. This was a hugely contended issue and you need to dig the mailing lists. The decision is not convincing to everybody.
In any case, since Optional cannot wrap null value, it pushes us in a corner in cases like findFirst. They must have reasoned that null values are very rare (it was even considered that Stream should bar null values), therefore it is more convenient to throw exception on null values instead of on empty streams.
A workaround is to box null, e.g.
class Box<T>
static Box<T> of(T value){ .. }
Optional<Box<String>> first = stream.map(Box::of).findFirst();
(They say the solution to every OOP problem is to introduce another type :)

Resources