f({bool b, String s}) {
assert(b ? s != null : true);
}
Is there any better way to write the above assert based on the condition?
You can always rewrite a boolean conditional expression (?-:) where one branch is a boolean literal, into a combination of ||, && and !.
| Bad conditional | Good and/or |
|-----------------|-------------|
| b ? true : v | b || v |
| b ? false : v | !b && v |
| b ? v : true | !b || v |
| b ? v : false | b && v |
So, in your case: assert(!b || s != null);
Related
Suppose I have a simple sheet like
|| A | B | C | D | E | F | G
==============================
1 || 1 | 0 | | ? | 1 | 0 | 1
I want to create a new row where each value is either 1 or 0. The logic is if the cell is either blank or ? then it should be 0.
The closest I got was
=ArrayFormula(if(A1:G1="?", 0, A1:G1))
which gave me
|| A | B | C | D | E | F | G
==============================
1 || 1 | 0 | | ? | 1 | 0 | 1
2 || 1 | 0 | | 0 | 1 | 0 | 1
But as soon as I add an OR for checking blanks with
=ArrayFormula(if(or(A1:G1="?", isblank(A1:G1)), 0, A1:G1))
then I only get 1 cell:
|| A | B | C | D | E | F | G
==============================
1 || 1 | 0 | | ? | 1 | 0 | 1
2 || 1 | | | | | |
What am I doing wrong? Or is there a better way to do this?
Two ways:
Simply place the other condition in the value_is_false location
=ArrayFormula(if(A1:G1="?", 0, IF(ISBLANK(A1:G1), 0, A1:G1)))
Use + to represent OR. This works because "true" values are evaluated to 1 and "false" values are evaluated to 0. So, 0+0=false, 1+0=true. For AND, you multiply...0*0=false, 1*0=false, 1*1=true.
=ArrayFormula(if((A1:G1="?")+(ISBLANK(A1:G1)), 0, A1:G1))
i want evaluate at runtime some string expression like:
((foo = true) or (bar <> 'test')) and (baz >= 1)
The string are inputted by user. The user can create a rule by coupling a property choised from a set (eg. foo, bar, baz), inputting the target value to evaluate (string, number and boolean) and choising the operator (=, <>, >, <), eg.:
| Id | Property | Operator | Value | Expression |
-------------------------------------------------------------------------------------------
| $1 | foo | = | true | (foo = true) |
-------------------------------------------------------------------------------------------
| $2 | bar | <> | 'test' | (bar <> 'test') |
-------------------------------------------------------------------------------------------
| $3 | baz | >= | 1 | (baz >= 1) |
-------------------------------------------------------------------------------------------
the single rule can be coupled and nested in child/parent rule by choosing an operator like and, or, eg.:
| Id | Property | Operator | Value | Expression |
-------------------------------------------------------------------------------------------
| $1 | foo | = | true | (foo = true) |
-------------------------------------------------------------------------------------------
| $2 | bar | <> | 'test' | (bar <> 'test') |
-------------------------------------------------------------------------------------------
| $3 | baz | >= | 1 | (baz >= 1) |
-------------------------------------------------------------------------------------------
| $4 | $1 | or | $2 | ((foo = true) or (bar <> 'test')) |
-------------------------------------------------------------------------------------------
| $5 | $4 | and | $3 | ((foo = true) or (bar <> 'test')) and (baz >= 1) |
-------------------------------------------------------------------------------------------
in peseudo code, the idea is:
aExpressionEngine := TExpressionEngine.Create;
try
// Adds to the evaluation scope all the properties with the
// inputted value. AddToScope accept string, variant
aExpressionEngine.AddToScope('foo', false);
aExpressionEngine.AddToScope('bar', 'qux');
aExpressionEngine.AddToScope('baz', 10);
// evaluate the expression, the result is always a boolean
Result := aExpressionEngine.eval('(((foo = true) or (bar <> ''test'')) and (baz >= 1))');
finally
aExpressionEngine.free;
end;
in this pseudo code example, the expression to evaluate become (after replacing the properties with the scope value):
(((false = true) or ('qux' <> 'test')) and (10 >= 1)) // TRUE
by googling, i have found a bit of library for evaluate math expression, but nothing for logical condition evaluating.
Has delphi something for evaluate string expression?
F# beginner here.
I am trying to match a tuple with several cases and return a specific value on the matching condition. This is how it looks:
match inf, sup with
| nan , _
| _ , nan
-> Interval(nan,nan)
| _ , _ when inf = -infinity && sup = -infinity -> Interval(nan,nan)
| _ , _ when inf = infinity && sup = infinity -> Interval(nan,nan)
| _ , _ when inf > sup -> Interval(nan,nan)
| _ , _ -> Interval(inf,sup)
Since almost every case returns Interval(nan,nan) I would like to group them due to readability, but I have no idea how. I tried the following
match inf, sup with
| nan , _
| _ , nan
| _ , _ when inf = -infinity && sup = -infinity
| _ , _ when inf = infinity && sup = infinity
| _ , _ when inf > sup -> Interval(nan,nan)
-> Interval(nan,nan)
| _ , _ -> Interval(inf,sup)
but the compiler says
The two sides of this 'or' pattern bind different sets of varibales
So I tried the following:
match inf, sup with
| nan , _
| _ , nan
-> Interval(nan,nan)
| _ , _ when inf = -infinity && sup = -infinity
| _ , _ when inf = infinity && sup = infinity
| _ , _ when inf > sup -> Interval(nan,nan)
-> Interval(nan,nan)
| _ , _ -> Interval(inf,sup)
Here I get an error at the second | from the second when clause. He expects an '->' or other token.
So: How can I shorten this matching or how can I improve it? Those several Interval(nan,nan) seem uneccesary to me.
Thanks in advance!
You are not checking nan correctly. Matching against nan will result in any supplied value being bound to a value called nan. Notice in FSI:
let isNan x = match x with |nan -> true |_ -> false;;
let isNan x = match x with |nan -> true |_ -> false;;
-----------------------------------------^
stdin(1,42): warning FS0026: This rule will never be matched
You should check for nan values by using System.Double.IsNaN(x).
Bearing this in mind, I would use an active pattern to check for non-valid values:
let (|PositiveInfinity|NegativeInfinity|NaN|Real|) = function
|v when v = -infinity -> NegativeInfinity
|v when v = infinity -> PositiveInfinity
|v when System.Double.IsNaN(v) -> NaN
|v -> Real v
Then reduce your pattern match to:
let test inf sup =
match inf, sup with
|NaN, _
|_, NaN
|NegativeInfinity, NegativeInfinity
|PositiveInfinity, PositiveInfinity
|_, _ when inf > sup -> Interval(nan, nan)
|_, _ -> Interval(inf, sup)
In match statement when clause is common for all or cases that are listed before. If you want to visualize this, you can think like there are parens like this:
( | Case1 n
| Case2 n
| Case3 n ) when predicate(n) ->
You cannot repeat when clause few times before you have result expression (after ->).
Instead you could join all conditions in one when clause, something similar to:
| _ when cond1 ||
cond2 ||
cond3 -> ...
The answer given by #TheInnerLight is great, but handles a corner case differently. The OP considered an interval between (-inf, 10.0) as valid, but the posted answer does not. Here's an answer that handles all cases the same:
let (|PositiveInfinity|NegativeInfinity|NaN|Real|) = function
| v when Double.IsPositiveInfinity v -> PositiveInfinity
| v when Double.IsNegativeInfinity v -> NegativeInfinity
| v when Double.IsNaN v -> NaN
| v -> Real v
let getInterval inf sup =
match inf, sup with
| NaN, _
| _ , NaN
| NegativeInfinity, NegativeInfinity
| PositiveInfinity, PositiveInfinity
| _ , _ when inf > sup -> Interval(nan,nan)
| _ , _ -> Interval(inf,sup)
Slightly off topic: I would generally advise against using NaN as a marker for invalid intervals. Any comparisons with NaN return false, meaning you need to handle them differently in each interval check. Consider the following 2 versions of writing "is a point v inside an interval?", where lower and upper bound happen to be NaN:
let inside1 v = v >= nan && v <= nan
let inside2 v = not (v < nan || v > nan)
In inside1, you check "is the point inside?", in inside2, you ask "is it not outside?". Checking the point 1.0 gives:
> inside1 1.0;;
val it : bool = false
> inside2 1.0;;
val it : bool = true
I would hence suggest that your function returns an Interval option, meaning None in all cases where you presently return Interval(nan,nan). Otherwise, your code will be littered by explicit NaN checks all over.
Just use the Boolean or || in the when clauses:
match inf, sup with
| nan , _
| _ , nan
-> Interval(nan,nan)
| _ , _ when inf = -infinity && sup = -infinity ||
inf = infinity && sup = infinity ||
inf > sup -> Interval(nan,nan)
| _ , _ -> Interval(inf,sup)
I have a set of inputs (a,b,c) and an output type for each set of them. The output type has two fields (p,q). Can I specify values for output type fields like this as part of where data table?
def "test service"(int a, int b, int c) {
setup:
req = reqBldr(a,b,c)
expectedRsp = rspBldr(p,q)
when:
rsp = service.call(req)
then:
expectedRsp=rsp
where:
a | b | c || p | q
1 | 3 | 3 || 0 | 0
7 | 4 | 4 || 0 | 1
0 | 0 | 0 || 1 | 1
}
Yes you can. As the error message will tell you, the method either needs to declare five or zero parameters (all data variables or none). Another error message will tell you that you need to use == rather than = in the assertion. Last but not least, Groovy requires local variables to be declared with def. Otherwise you should get a MissingPropertyException.
I have a Discriminated Union, and I hope to use built in operators like > < compare max for it.
[<CustomComparison>]
type SymbolType =
| A
| B
| C
| D
interface IComparable<SymbolType> with
member x.CompareTo y =
match x, y with
| A, A-> 0
| A, _ -> 1
| _, A-> -1
| _, _ -> 0
I understand I can use IComparable, but then i have to do a null check, what's worse is that I have to cast it like (SymbolType) y which I assume would be time consuming.
You can already use standard comparison operators on the type. The built-in implementation uses the order of declarations of the individual cases, so:
type SymbolType = A | B | C | D
// Behavior of built-in comparison
A < B = true
D <= C = false
max B D = D
This looks very fragile, so maybe it is not the best thing to rely on. If you have cases that do not contain other values, you can use enum instead of discriminated union and define the ordering you wish:
type SymbolType =
| A = 1
| B = 2
| C = 4
| D = 3
// The order is now defined by your code
SymbolType.C < SymbolType.D = false
You can just implement the required methods with thin wrappers:
[<CustomComparison>]
[<CustomEquality>]
type SymbolType =
| A
| B
| C
| D
override x.Equals y =
match y with
| :? SymbolType as t -> (((x :> IComparable<_>).CompareTo) t)=0
| _ -> false
interface IComparable with
member x.CompareTo y =
match y with
| :? SymbolType as t -> ((x :> IComparable<_>).CompareTo) t
| _ -> failwith "bad comparison"
interface IComparable<SymbolType> with
member x.CompareTo y =
match x, y with
| A, A-> 0
| A, _ -> 1
| _, A-> -1
| _, _ -> 0
This way does avoid any duplicate typing.
On CLR, operators are static functions, so you can't define them in an interface. But boxing can also be avoided if your use the interface as a constraint of type parameter of a generic function.
int Compare<T>(T lhs, T rhs) where T : IComparable<T>
{
return lhs.CompareTo(rhs) // no boxing
}
Sorry, I'm not familiar with F#, so I wrote the example in C#.