I've got a DOORS module with attributes that are filled with number strings, because the attributes are not applicable to all objects. To identify unambiuously the objects which aren't affected, the attributes currently contain "N/A" . For purposes of sorting and other operations, I would like to replace these attributes with numeric types. Is there any special value that DOORS understands as "NULL" or "N/A", or even 'Inf' that can be used in a numeric attribute?
I know I could do some scripting to create separate DXL attributes which convert the number strings to numeric but would rather avoid that if possible.
I fear that you will either have to stick to strings or define your personal integer value which represents 'n/a', for example '0'. Objects with the '0' value will be easy to treat after sorting -- with DXL you may use the bool null(t value) function which checks if value is null (bool: false, char: '0', int: 0, real: 0.0, string: ""). If you stick to integer strings, there is the function bool isValidInt(string s) which would help you to treat the "n/a" string accordingly.
Could you just leave the attribute empty for that object?
It seems like an int type attribute can be set to "" - and you could filter the objects based on that attribute being empty or non-empty.
Interestingly, in DXL space, the following seems to work for an integer based attribute ( inttest )
Object o = current
int x = o."inttest"
print ( x ) "\n"
print ( null x ) "\n"
print ( x == 0 )
Prints the following results:
0
true
true
So nulls are interpreted into 0 - something to be aware of if 0 is an expected value in your attributes.
Related
I have two int values in Dart, test them equals or not with == previously, it was fine. Now I have to test if first one is greater or equals to the second one, so I changed == to >= instinctively, but it seems Dart was not happy with me doing that
I double checked documentation of Dart, >= should work to test greater or equals operation
IMO, in the end, if >= has something wrong, then the same should come to ==
You are comparing two different operators which comes from different part of the Dart language. The == operator is defined on Object:
https://api.dart.dev/stable/2.15.1/dart-core/Object/operator_equals.html
Which needs to be able to compare every type of object including null. The reason why the == operator does not have Object? as input parameter is because of the following detail in the Dart Language Specification (page 167) under the section "Equality":
Evaluation of an equality expression ee of the form e1 == e2 proceeds as follows:
The expression e1 is evaluated to an object o1.
The expression e2 is evaluated to an object o2.
If either o1 or o2 is the null object (17.4), then ee evaluates to true if both o1 and o2 are the null object and to false otherwise. Otherwise,
evaluation of ee is equivalent to the method invocation o1.==(o2)
...
https://dart.dev/guides/language/specifications/DartLangSpec-v2.10.pdf
So based on third rule, the language itself will make sure that null values are compared correctly and therefore the Object.== method will never see a null object as its input.
The other operator is >= and comes (in your case) from num which int extends from:
https://api.dart.dev/stable/2.15.1/dart-core/num/operator_greater_equal.html
And is specified to accept only num (so int or double) which are a non-nullable type (null is therefore not allowed).
You are then trying to call the num.>= operator with the result from values?.length. This is a problem since values is nullable and can therefore potentially be null. And when you use the ?. operator, you are saying that if values are null, don't care calling .lenght but instead just return null.
So the type of values?.length ends up being int? which is not compatible with num.
In my web page there are 5 values given in the text field(like $10, $20, $30, $40 and $50) and I am trying to sum the values using ruby and selenium WebDriver.
Here is my code:
def get_sum_of_all_elements()
#logger.info("Searching element #{value1, value2, value3, value4, value5}");
allelements = #driver.find_elements(:id = "lbl_val_")
#logger.info("Total Elements Found with locator #{locator} are : #{allelements.size}");
if allelements.start_with?("$")
allelements = "((allelements))".tr('$', '') #removing '$' sign from values
iSum =0
allelements.each do|i|
iSum += i
end
end
end
I am expecting to see output as 150. Do I need to store values in an array?
Any help would be appreciated.
There a couple of things you should modify in your code to make it work:
Fix how arguments are passed to find_elements; it should be id: "lbl_val_".
find_elements returns an array of WebDriver::Element objects, so you must check the value for each object.
The string "Searching element #{value1, value2, value3, value4, value5}" is not valid since you are trying to interpolate the value of 5 variables chained with a comma. You either need to interplate only the variable (keeping commas as strings) or use square brackets ([]) to interpolate an array.
Now your code should look something like this1:
def get_sum_of_all_elements
#logger.info("Searching element #{[value1, value2, value3, value4, value5]}")
allelements = #driver.find_elements(id: "lbl_val_")
#logger.info("Total Elements Found with locator #{locator} are : #{allelements.size}");
if allelements.all? { |elem| elem.value.start_with?("$") }
elements = allelements.map { |elem| elem.value.tr('$', '').to_i }
elements.reduce(:+)
end
end
A few things to note:
Parenthesis (()) were removed in method definition, ruby doesn't need them when no arguments are passed.
There is no longer need to assign the final value to a variable (e.g iSum) since ruby will return the result of last evaluated code.
If any value doesn't start with "$", it will return false. You could change this by adding a default value after if block.
Semicolons (;) were removed, you don't need them in ruby (unless you want to chain multiple statements in a singe line).
One more thing, the variables value1, value2, value3, value4, value5 and locator doesn't seem to be set anywhere in your method; you must set them within your method (or pass them as arguments) or you will get an error.
1 This considers the same logic that you seemed to be looking for in your code, that is, sum all values only if all of them start with "$".
It's hard to say exactly what you are trying to do, but this might help. I assume you have an array of string values with dollar signs:
>> allelements = ["$10", "$20", "$30", "$40", "$50"]
=> ["$10", "$20", "$30", "$40", "$50"]
We can make a new array stripping out all non-numeric characters and transforming the string values to integers:
>> integers = allelements.map { |e| e.gsub(/[^\d]/, '').to_i }
=> [10, 20, 30, 40, 50]
Now use inject to sum the values:
>> integers.inject(:+)
=> 150
I am trying some things in Dafny. I want to code a simple datastructure that holds an uncompressed image in memory:
datatype image' = image(width: int, height: int, data: array<byte>)
newtype byte = b: int | 0 <= b <= 255
Actually using it:
method Main() {
var dat := [1,2,3];
var im := image(1, 3, dat);
}
datatype image' = image(width: int, height: int, data: array<byte>)
newtype byte = b: int | 0 <= b <= 255
leads Dafny to complain:
stdin.dfy(3,24): Error: incorrect type of datatype constructor argument (found seq, expected array)
1 resolution/type errors detected in stdin.dfy
I might also want to demand that the byte array is not null, and the size of the byte array is equal to width * height * 3 (to store three bytes representing the RGB value of that pixel).
What way should I enforce this? I looked into newtype, which lets you put some constraints on variables with a certain type, but this works only for numeric types.
Dafny supports both immutable sequences (which are like mathematical sequences of elements) and mutable arrays (which are, like in C and Java, pointers to elements). The error you're getting is telling you that you're calling the image constructor with a seq<byte> value where an array<byte> value is expected.
You can fix the problem by replacing your definition of dat with:
var dat := new byte[3];
dat[0], dat[1], dat[2] := 1, 2, 3;
However, the more typical thing, if you're using a datatype (which is immutable), would be to use a sequence. So, you probably want to instead change your definition of image to:
datatype image = image(width: int, height: int, data: seq<byte>)
Btw, note that Dafny allows you to name a type and one of its constructors the same, so there's no reason to name one of them with a prime (unless you want to, of course).
Another matter of style is to use a half-open interval in your definition of byte:
newtype byte = b: int | 0 <= b < 256
Since half-open intervals are prevalent in computer science, Dafny's syntax favors them. For example, for a sequence s, the expression s[52..57] denotes a subsequence of s of length 5 (that is, 57 minus 52) starting in s at index 52. One more thing, you can also leave out the type int of b if you want, since Dafny will infer it:
newtype byte = b | 0 <= b < 256
You also asked about the possibility of adding a type constraint, so that the sequence in your datatype will always be of length 3. As you discovered, you cannot do this with a newtype, because newtype (at least for now) only works with numeric types. You can (almost) use a subset type, however. This would be done as follows:
type triple = s: seq<byte> | |s| == 3
(In this example, the first vertical bar is like the one in the newtype declaration and says "such that", whereas the next two denote the length operator on sequences.) The trouble with this declaration is that types must be nonempty and Dafny isn't convinced that there are any values that satisfy the constraint of triple. Well, Dafny is not trying very hard. The plan is to add a witness clause to the type (and newtype) declaration, so that a programmer can show Dafny a value that belongs to the triple type. However, this support is waiting for some implementation changes that will allow customized initial values, so you cannot use this constraint at this time.
Not that you want it here, but Dafny would let you give a weaker constraint that admits the empty sequence:
type triple = s: seq<byte> | |s| <= 3
So, instead, if you want to talk about that an image value has a data component of length 3, then introduce a predicate:
predicate GoodImage(img: image)
{
|img.data| == 3
}
and use this predicate in specifications like pre- and postconditions.
Program safely,
Rustan
I'm having a problem with lua's table.concat, and suspect it is just my ignorance, but cannot find a verbose answer to why I'm getting this behavior.
> t1 = {"foo", "bar", "nod"}
> t2 = {["foo"]="one", ["bar"]="two", ["nod"]="yes"}
> table.concat(t1)
foobarnod
> table.concat(t2)
The table.concat run on t2 provides no results. I suspect this is because the keys are strings instead of integers (index values), but I'm not sure why that matters.
I'm looking for A) why table.concat doesn't accept string keys, and/or B) a workaround that would allow me to concatenate a variable number of table values in a handful of lines, without specifying the key names.
Because that's what table.concat is documented as doing.
Given an array where all elements are strings or numbers, returns table[i]..sep..table[i+1] ยทยทยท sep..table[j]. The default value for sep is the empty string, the default for i is 1, and the default for j is the length of the table. If i is greater than j, returns the empty string.
Non-array tables have no defined order so table.concat wouldn't be all that helpful then anyway.
You can write your own, inefficient, table concat function easily enough.
function pconcat(tab)
local ctab, n = {}, =1
for _, v in pairs(tab) do
ctab[n] = v
n = n + 1
end
return table.concat(ctab)
end
You could also use next manually to do the concat, etc. yourself if you wanted to construct the string yourself (though that's probably less efficient then the above version).
I'm trying to code something but there is happening something I don't understand.
I get some values from a database and loop over them and change some of them if needed.
This is what I'm trying to do:
if qryGeneral.fieldbyname('B_PRIJS').IsNull or
qryGeneral.fieldbyname('B_PRIJS').Value = 0 then
begin
if (qryGeneral.fieldbyname('V_PRIJS').Value <> 0) or
(qryGeneral.fieldbyname('V_PRIJSEXCL').Value <> 0) then
//make some calculations and save data
end;
B_PRIJS is a float, null type in a SQL Server DB. When I set a breakpoint and I hover .Value it shows 0,11. When I hover IsNull it shows False, so far so good.
Now I would expect it would NOT enter the if-structure, because it is not null and not equal to 0, but it does enter the if-structure.
I don't understand why, I always coded like this.
When I select qryGeneral.fieldbyname('B_PRIJS').Value = 0 while still being in debug mode, I get a message "Expression illegal in evaluator".
I tried replacing Value into AsFloat or changing 0 into 0.0 but it doesn't work.
What am I doing wrong or not understanding here?
Delphi's operator precedence rules mean that your expression is evaluated like this:
if (qryGeneral.fieldbyname('B_PRIJS').IsNull or qryGeneral.fieldbyname('B_PRIJS').Value)
= 0 then
Put parentheses around your = expression just like you have around you <> expressions, and you should get closer to the results you expect. However, the Value property is a Variant. When comparing a Variant to an Integer, the = operator will cause the Variant to be converted to an Integer. Delphi's variant-type-conversion rules show that a Variant holding a real value will be rounded to the nearest integer when the target type is an integer, so your 0.11 value will be rounded to zero. Consider comparing to 0.0 instead.