Is it possible to parse and evaluate inequalities? - math.net

As per title, is it possible to parse and evaluate inequalities obtaining a true/false result?
As example:
Expression e = Infix.ParseOrThrow("A<B");
It throws:
My current approach:
public static bool CheckInequalitySatisfaction(string inequality, BoxDimensionValues values = null)
{
try
{
if (string.IsNullOrWhiteSpace(inequality))
throw new ArgumentNullException(nameof(inequality));
if (inequality.ToLower().Equals("false"))
return false;
if (inequality.ToLower().Equals("true"))
return true;
var matches = Regex.Match(inequality, "(?<left>.+)(?<operand>==|<=|>=|<|>)(?<right>.+)");
if (!matches.Success)
throw new ArgumentException($"The inequality is not valid {inequality}", nameof(inequality));
var leftExpression = matches.Groups["left"].Value;
if (!TryEvaluateExpression(leftExpression, values, out int leftValue))
throw new ArgumentException($"The left expression of the inequality is not valid {leftExpression}", nameof(inequality));
var rightExpression = matches.Groups["right"].Value;
if (!TryEvaluateExpression(rightExpression, values, out int rightValue))
throw new ArgumentException($"The right expression of the inequality is not valid {rightExpression}", nameof(inequality));
var inequalityOperator = matches.Groups["operand"].Value;
return inequalityOperator switch
{
"==" => leftValue == rightValue,
"<=" => leftValue <= rightValue,
">=" => leftValue >= rightValue,
"<" => leftValue < rightValue,
">" => leftValue > rightValue,
_ => throw new NotImplementedException($"The operator {inequalityOperator} is not supported for inequalities evaluation"),
};
}
catch (Exception ex)
{
ex.Log(MethodBase.GetCurrentMethod());
throw;
}
}

I spent some time trying to solve this for you, and could not with the current featureset in MathNet. But I did notice that MathNet's Expression object can handle operations like + and - with other Expression objects, so you could write an extension method that converted your inequality into a parsable expression.
Basically, since we know that Infix will parse "A-B" but not "A<B", you could replace the "<" with "-" and then check the expression against 0. Something like this, perhaps:
public static Expression SafeParseLessThan(this string mathExpression)
{
var splitExpression = mathExpression.Split("<");
var left = Infix.ParseOrThrow(splitExpression[0]);
var right = Infix.ParseOrThrow(splitExpression[1]);
return left - right;
}
With usage:
var newExpression = "A<B".SafeParseLessThan();
var symbols = new Dictionary<string, FloatingPoint>
{
{"A", 3},
{"B", 5}
};
var result = Evaluate.Evaluate(symbols, newExpression).RealValue < 0; // true
There will be other things for you to consider, given the types of functions you are parsing. For instance, this quick example I whipped up assumes real values. You will also need to get creative if you need include other non-parsable elements in your expressions such as min and max, perhaps like in "min(A,B) < max(C,D)".
I also noticed you posted another question related to MathNet parsing of min/max functions. You could probably apply this type of strategy to that as well.

Related

How to use parseInt in kotlin?

I making fun increase, decrease for item count. I want make count.text plus "T" Character. when I tried to make code like this.
error code: java.lang.NumberFormatException: For input string: "1T"
How can I solve this problem? Any one can help??
fun increaseInteger() {
var count = findViewById<TextView>(R.id.integer_number)
count.text=intent.getStringExtra("case")+"T"
var countResult = parseInt(intent.getStringExtra("case")+"T")
var countValue = countResult+1
if (countValue >= 1 && !decrease.isEnabled) { decrease.isEnabled = true}
intent.putExtra("result",countValue)
display(countValue)
}
fun decreaseInteger() {
var count = findViewById<TextView>(R.id.integer_number)
count.text=intent.getStringExtra("case")+"T"
var countResult = parseInt(intent.getStringExtra("case")+"T")
var countValue = countResult-1
if (countValue <= 1) {decrease.isEnabled = false }
intent.putExtra("result",countValue)
display(countValue)
}
The API is pretty straightforward:
"123".toInt() // returns 123 as Int
"123T".toInt() // throws NumberFormatException
"123".toIntOrNull() // returns 123 Int?
"123T".toIntOrNull() // returns null as Int?
So if you know your input might not be parseable to an Int, you can use toIntOrNull which will return null if the value was not parseable. It allows to use further nullability tools the language offers, e.g.:
input.toIntOrNull() ?: throw IllegalArgumentException("$input is not a valid number")
(This example uses the elvis operator to handle the undesired null response of toIntOrNull, the alternative would involve a try/catch around toInt)
You can use these
val str = "12345"
val str_new = "12345B"
str.toInt() // returns 123 as Int
str_new.toInt() // throws NumberFormatException
str.toIntOrNull() // returns 123 Int?
str_new.toIntOrNull() // returns null as Int?

Duplicate result of Hazealcast Predicate while querying with "in"

I query Hazelcast data map using Predicate with "in" condition like below.
List<String> liveVideoSourceIdList=new ArrayList(){"my_filter"};
Predicate predicate=Predicates.in("myField",liveVideoSourceIdList.toArray(new String[0]));
When i filter map with the created predicate,all the values are duplicated.
If i use "like" instead of "in" like below,no duplication happens. Is there any thoughts about this problem ?
Predicate predicate=Predicates.like("myField",liveVideoSourceIdList.get(0));
I have been unable to reproduce your issue, using 3.9-SNAPSHOT
which version are you using ?
I am using
int min = random.nextInt( keyDomain - range );
int max = min+range;
String values = new String();
for (int i = min; i < max ; i++) {
values += i+", ";
}
SqlPredicate sqlPredicate = new SqlPredicate("personId IN ("+values+")");
Collection<Personable> res = map.values(sqlPredicate);
if(res.size()!=range){
throw new AssertionException(sqlPredicate+" on map "+map.getName()+" returned "+res.size()+" expected "+range);
}
Set<Personable> set = new HashSet<Personable>(res);
if(res.size()!=set.size()){
throw new AssertionException(sqlPredicate+" on map "+map.getName()+" returned Duplicates");
}
for (Personable person : res) {
if(person.getPersonId() < min || person.getPersonId() >= max ){
throw new AssertionException(map.getName()+" "+person+" != "+sqlPredicate);
}
}

Comparing String.Index values

Is it possible to compare two String.Index values in Swift? I'm trying to process a string character by character, and several times I need to check if I am at the end of the string. I've tried just doing
while (currentIndex < string.endIndex) {
//do things...
currentIndex = currentIndex.successor()
}
Which complained about type conversions. Then, I tried defining and overload for < as such:
#infix func <(lhs: String.Index, rhs: String.Index) -> Bool {
var ret = true //what goes here?
return ret
}
Which gets rid of compilation errors, but I have no clue what to do in order to compare lhs and rhs properly. Is this the way I should go about using String.Index, or is there a better way to compare them?
The simplest option is the distance() function:
var string = "Hello World"
var currentIndex = string.startIndex
while (distance(currentIndex, string.endIndex) >= 0) {
println("currentIndex: \(currentIndex)")
currentIndex = currentIndex.successor()
}
Beware distance() has O(N) performance, so avoid it for large strings. However, the entire String class doesn't currently handle large strings anyway — you should probably switch to CFString if performance is critical.
Using an operator overload is a bad idea, but just as a learning exercise this is how you'd do it:
var string = "Hello World"
var currentIndex = string.startIndex
#infix func <(lhs: String.Index, rhs: String.Index) -> Bool {
return distance(lhs, rhs) > 0
}
while (currentIndex < string.endIndex) {
currentIndex = currentIndex.successor()
}
String indexes support = and !=. String indexes are an opaque type, not integers and can not be compared like integers.
Use: if (currentIndex != string.endIndex)
var currentIndex = string.startIndex
while (currentIndex != string.endIndex) {
println("currentIndex: \(currentIndex)")
currentIndex = currentIndex.successor()
}
I believe this REPL/Playground example should illuminate what you (and others) need to know about working with the String.Index concept.
// This will be our working example
let exampleString = "this is a string"
// And here we'll call successor a few times to get an index partway through the example
var someIndexInTheMiddle = exampleString.startIndex
for _ in 1...5 {
someIndexInTheMiddle = someIndexInTheMiddle.successor()
}
// And here we will iterate that string and detect when our current index is relative in one of three different possible ways to the character selected previously
println("\n\nsomeIndexInTheMiddle = \(exampleString[someIndexInTheMiddle])")
for var index: String.Index = exampleString.startIndex; index != exampleString.endIndex; index = index.successor() {
println(" - \(exampleString[index])")
if index != exampleString.startIndex && index.predecessor() == someIndexInTheMiddle {
println("current character comes after someIndexInTheMiddle")
} else if index == someIndexInTheMiddle {
println("current character is the one indicated by someIndexInTheMiddle")
} else if index != exampleString.endIndex && index.successor() == someIndexInTheMiddle {
println("Current character comes before someIndexinTheMiddle")
}
}
Hopefully that provides the necessary information.
Whatever way you decide to iterator over a String, you will immediately want to capture the iteration in a function that can be repeatedly invoked while using a closure applied to each string character. As in:
extension String {
func each (f: (Character) -> Void) {
for var index = self.startIndex;
index < self.endIndex;
index = index.successor() {
f (string[index])
}
}
}
Apple already provides these for C-Strings and will for general strings as soon as they get character access solidified.

How do I reverse a String in Dart?

I have a String, and I would like to reverse it. For example, I am writing an AngularDart filter that reverses a string. It's just for demonstration purposes, but it made me wonder how I would reverse a string.
Example:
Hello, world
should turn into:
dlrow ,olleH
I should also consider strings with Unicode characters. For example: 'Ame\u{301}lie'
What's an easy way to reverse a string, even if it has?
The question is not well defined. Reversing arbitrary strings does not make sense and will lead to broken output. The first (surmountable) obstacle is Utf-16. Dart strings are encoded as Utf-16 and reversing just the code-units leads to invalid strings:
var input = "Music \u{1d11e} for the win"; // Music 𝄞 for the win
print(input.split('').reversed.join()); // niw eht rof
The split function explicitly warns against this problem (with an example):
Splitting with an empty string pattern ('') splits at UTF-16 code unit boundaries and not at rune boundaries[.]
There is an easy fix for this: instead of reversing the individual code-units one can reverse the runes:
var input = "Music \u{1d11e} for the win"; // Music 𝄞 for the win
print(new String.fromCharCodes(input.runes.toList().reversed)); // niw eht rof 𝄞 cisuM
But that's not all. Runes, too, can have a specific order. This second obstacle is much harder to solve. A simple example:
var input = 'Ame\u{301}lie'; // Amélie
print(new String.fromCharCodes(input.runes.toList().reversed)); // eiĺemA
Note that the accent is on the wrong character.
There are probably other languages that are even more sensitive to the order of individual runes.
If the input has severe restrictions (for example being Ascii, or Iso Latin 1) then reversing strings is technically possible. However, I haven't yet seen a single use-case where this operation made sense.
Using this question as example for showing that strings have List-like operations is not a good idea, either. Except for few use-cases, strings have to be treated with respect to a specific language, and with highly complex methods that have language-specific knowledge.
In particular native English speakers have to pay attention: strings can rarely be handled as if they were lists of single characters. In almost every other language this will lead to buggy programs. (And don't get me started on toLowerCase and toUpperCase ...).
Here's one way to reverse an ASCII String in Dart:
input.split('').reversed.join('');
split the string on every character, creating an List
generate an iterator that reverses a list
join the list (creating a new string)
Note: this is not necessarily the fastest way to reverse a string. See other answers for alternatives.
Note: this does not properly handle all unicode strings.
I've made a small benchmark for a few different alternatives:
String reverse0(String s) {
return s.split('').reversed.join('');
}
String reverse1(String s) {
var sb = new StringBuffer();
for(var i = s.length - 1; i >= 0; --i) {
sb.write(s[i]);
}
return sb.toString();
}
String reverse2(String s) {
return new String.fromCharCodes(s.codeUnits.reversed);
}
String reverse3(String s) {
var sb = new StringBuffer();
for(var i = s.length - 1; i >= 0; --i) {
sb.writeCharCode(s.codeUnitAt(i));
}
return sb.toString();
}
String reverse4(String s) {
var sb = new StringBuffer();
var i = s.length - 1;
while (i >= 3) {
sb.writeCharCode(s.codeUnitAt(i-0));
sb.writeCharCode(s.codeUnitAt(i-1));
sb.writeCharCode(s.codeUnitAt(i-2));
sb.writeCharCode(s.codeUnitAt(i-3));
i -= 4;
}
while (i >= 0) {
sb.writeCharCode(s.codeUnitAt(i));
i -= 1;
}
return sb.toString();
}
String reverse5(String s) {
var length = s.length;
var charCodes = new List(length);
for(var index = 0; index < length; index++) {
charCodes[index] = s.codeUnitAt(length - index - 1);
}
return new String.fromCharCodes(charCodes);
}
main() {
var s = "Lorem Ipsum is simply dummy text of the printing and typesetting industry.";
time('reverse0', () => reverse0(s));
time('reverse1', () => reverse1(s));
time('reverse2', () => reverse2(s));
time('reverse3', () => reverse3(s));
time('reverse4', () => reverse4(s));
time('reverse5', () => reverse5(s));
}
Here is the result:
reverse0: => 331,394 ops/sec (3 us) stdev(0.01363)
reverse1: => 346,822 ops/sec (3 us) stdev(0.00885)
reverse2: => 490,821 ops/sec (2 us) stdev(0.0338)
reverse3: => 873,636 ops/sec (1 us) stdev(0.03972)
reverse4: => 893,953 ops/sec (1 us) stdev(0.04089)
reverse5: => 2,624,282 ops/sec (0 us) stdev(0.11828)
Try this function
String reverse(String s) {
var chars = s.splitChars();
var len = s.length - 1;
var i = 0;
while (i < len) {
var tmp = chars[i];
chars[i] = chars[len];
chars[len] = tmp;
i++;
len--;
}
return Strings.concatAll(chars);
}
void main() {
var s = "Hello , world";
print(s);
print(reverse(s));
}
(or)
String reverse(String s) {
StringBuffer sb=new StringBuffer();
for(int i=s.length-1;i>=0;i--) {
sb.add(s[i]);
}
return sb.toString();
}
main() {
print(reverse('Hello , world'));
}
The library More Dart contains a light-weight wrapper around strings that makes them behave like an immutable list of characters:
import 'package:more/iterable.dart';
void main() {
print(string('Hello World').reversed.join());
}
There is a utils package that covers this function. It has some more nice methods for operation on strings.
Install it with :
dependencies:
basic_utils: ^1.2.0
Usage :
String reversed = StringUtils.reverse("helloworld");
Github:
https://github.com/Ephenodrom/Dart-Basic-Utils
Here is a function you can use to reverse strings. It takes an string as input and will use a dart package called Characters to extract characters from the given string. Then we can reverse them and join again to make the reversed string.
String reverse(String string) {
if (string.length < 2) {
return string;
}
final characters = Characters(string);
return characters.toList().reversed.join();
}
Create this extension:
extension Ex on String {
String get reverse => split('').reversed.join();
}
Usage:
void main() {
String string = 'Hello World';
print(string.reverse); // dlroW olleH
}
Reversing "Hello World"

c# string delimiter

I have string value like this:
string strRole = "ab=Admin,ca=system,ou=application,role=branduk|ab=Manager,ca=system,ou=application,role=brankdusa|ab=sale,ca=system,ou=application,role=brandAu";
I just need to retrieve role to string array. I wonder if there is the best way to split the string in C# 4.0
string[] arrStrRole = strRole.Split('|').Select .. ??
Basically, I need brandUK, brandUsa, brandAu to string[] arrStrRole.
Thanks.
string[] arrStrRole = strRole.Split('|').Select(r => r.Split(new []{"role="}, StringSplitOptions.None)[1]).ToArray()
results in an string array with three strings:
branduk
brankdusa
brandAu
you can use string[] arrStrRole = strRole.Split('|',','); and this will split according to | and , characters
You can use String.Split in this LINQ query:
var roles = from token in strRole.Split('|')
from part in token.Split(',')
where part.Split('=')[0] == "role"
select part.Split('=')[1];
Note that this is yet prone to error and requires the data always to have this format. I mention it because you've started with Split('|').Select.... You can also use nested loops.
If you need it as String[] you just need to call ToArray:
String[] result = roles.ToArray();
I would go with Regex rather than splitting string. In combination with your intended Select solution, it could look like this:
var roles = Regex.Matches(strRole, #"role=(\w+)")
.Cast<Match>()
.Select(x => x.Groups[1].Value).ToArray();
You could use an extension like this which would allow you to test it easily.
public static string[] ParseRolesIntoList(this string csvGiven)
{
var list = new List<string>();
if (csvGiven == null) return null;
var csv = csvGiven.Split(',');
foreach (var s in csv)
{
if (string.IsNullOrEmpty(s)) continue;
if(!s.StartsWith("role")) continue;
var upperBound = s.IndexOf("|");
if (upperBound <= 0) upperBound = s.Length;
var role = s.Substring(s.IndexOf("=") + 1,
upperBound - s.IndexOf("=") - 1);
list.Add(role);
}
return list.ToArray();
}
Test below found brankdusa typo in your example. Some of the other answers would not deal with brandAu as it matches slightly differently. Try running this test against them if you like
[Test]
public void Should_parse_into_roles()
{
//GIVEN
const string strRole = "ab=Admin,ca=system,ou=application,role=branduk|ab=Manager,ca=system,ou=application,role=brankdusa|ab=sale,ca=system,ou=application,role=brandAu";
//WHEN
var roles = strRole.ParseRolesIntoList();
//THEN
Assert.That(roles.Length, Is.EqualTo(3));
Assert.That(roles[0], Is.EqualTo("branduk"));
Assert.That(roles[1], Is.EqualTo("brankdusa"));
Assert.That(roles[2], Is.EqualTo("brandAu"));
}
This gives an array of the 3 values.
void Main()
{
string strRole = "ab=Admin,ca=system,ou=application,role=branduk|ab=Manager,ca=system,ou=application,role=brankdusa|ab=sale,ca=system,ou=application,role=brandAu";
var arrStrRole = strRole.Split('|',',')
.Where(a => a.Split('=')[0] == "role")
.Select(b => b.Split('=')[1]);
arrStrRole.Dump();
}

Resources