Specman coverage: Is there a way to define ranges using variable? - range

I have comp_value that gets values between 1 .. 100.
In addition I have an input variable period (of the same range). I need to cover 2 ranges of comp_values: [1..period] and [period+1 .. 100]. Something like this:
cover some_event_e is {
item period using no_collect;
item comp_val using no_collect,
ranges = {
range([1..period], "Smaller_than_period");
range([period+1..100], "Bigger_than_period");
};
};
(The code causes compilation error since no variable can be written inside range).
Is there a way to collect the coverage?
Thank you for your help.

Ranges must be constant.
But if I understood your intent correctly, you can define new items like
cover some_event_e is {
item smaller_or_equal_than_period: bool = (comp_val in [1..period]) using
ignore = (not smaller_or_equal_than_period);
item greater_than_period: bool = (comp_val in [(min(100,period+1)..100]) using
ignore = (not greater_than_period);
};
Assuming period is always in [1..100].

Related

Libreoffice calc - how to write a same value into a range

I know how to 'select' a range in LO (7.2.4.1) Calc BASIC ....
ThisComponent.CurrentController.ActiveSheet.getCellRangeByName("D1:H6")
But how to write a value, e.g. "1", into that range using BASIC?
myRange = ThisComponent.CurrentController.ActiveSheet.getCellRangeByName("D1:H6")
myRange.Value = 1
Gives an "property or method not found" error. But I can't find any properties or values to go after Range to allow me to do what I want. Flailing around and trying
myRange.setValue = 1
myRange.writeValue = 1
myRange.setString = "1"
and numerous other variants don't work either.
Would really appreciate the solution. Thanks.
You can edit the value of an individual cell, but not the entire range. You will have to iterate over all the cells in the range one at a time, changing the value of each of them.
Sub Set1ToD1H6
myRange = ThisComponent.CurrentController.ActiveSheet.getCellRangeByName("D1:H6")
For i = 0 To myRange.getRows().getCount()-1
For j = 0 To myRange.getColumns().getCount()-1
myRange.getCellByPosition(j, i).setValue(1)
Next j
Next i
End Sub
But since the read-write operation to a cell is comparable in time to the read-write operation to a whole range, it is preferable to use another method - to prepare data in an array and write from it to a range in one operation:
Sub Set1ToRange
myRange = ThisComponent.CurrentController.ActiveSheet.getCellRangeByName("D1:H6")
dataOfRange = myRange.getData()
For i = LBound(dataOfRange) To UBound(dataOfRange)
For j = LBound(dataOfRange(i)) To UBound(dataOfRange(i))
dataOfRange(i)(j) = 1
Next j
Next i
myRange.setData(dataOfRange)
End Sub
(For your example, this will be approximately 30 times faster, for a larger range the time winnings will be even more significant)
The .getData() and .setData() methods work on numeric range values. To work with text strings (and numbers), use .getDataArray() and .setDataArray(), for working with cell formulas use .getFormulaArray() and .setFormulaArray()

How to contunally add to a number in SparkAR ( += equivalent)

New to reactive programming and pretty lost.
I have a number (which can be positive or negative) coming into a script from a patch in SparkAR and I'd like to add the number to itself once every frame.
ie if the incoming number is 1 and it comes in 9 times the variable would be 9.
let intoScript = Patches.getScalarValue('intoScript').pinLastValue;
let myValue = Reactive.add(myValue, intoScript);
The above doesnt work.
One way-
Increment counter in Patch editor and send variable value to SparkAR.
(https://sparkar.facebook.com/ar-studio/learn/documentation/docs/visual-programming/javascript-to-patch-bridging/)
let originalValue = Reactive.val(0)
function increment(newValue){
Diagnostics.watch('originalValue', originalValue)
originalValue = newValue.add(originalValue)
}
Don't forget to import Reactive module. more info about logical operations here

Anylogic referencing columns in a collection

I am using a collection to represent available trucks in a system. I am using a 1 or 0 for a given index number, using a 1 to say that indexed truck is available. I am then trying to assign that index number to a customer ID. I am trying to randomly select an available truck from those listed as available. I am getting an error saying the left-hand side of an assignment must be a variable and highlighting the portion of the code reading Available_Trucks() = 1. This is the code:
agent.ID = randomWhere(Available_Trucks, Available_Trucks() = 1);
The way you are doing it won't work... randomWhere when applied to a collection of integers, will return the element of the collection (in this case 1 or 0).
So doing
randomWhere(Available_Trucks,at->at==1); //this is the right synthax
will return 1 always since that's the value of the number chosen in the collection. So what you need is to get the index of the number of the collection that is equal to 1. But you will have to create a function to do that yourself... something like this (probably not the best way but it works: agent.ID=getRandomAvailbleTruck(Available_Trucks);
And the function getRandomAvailbleTruck will take as an argument a collection (arrayList probably).. it will return -1 if there is no availble truck
int availableTrucks=count(collection,c->c==1);
if(availableTrucks==0) return -1;
int rand=uniform_discr(1,availableTrucks);
int i=0;
int j=0;
while(i<rand){
if(collection.get(j)==1){
i++;
if(i==rand){
return j;
}
}
j++;
}
return -1;
Now another idea is to instead of using 0 and 1 for the availability, you can use correlative numbers: 1,2,3,4,5 ... etc and use a 0 if it's not available. For instance if truck 3 is not availble, the array will be 1,2,0,4,5 and if it's available it will be 1,2,3,4,5.
In that case you can use
agent.ID=randomTrue(available_trucks,at->at>0);
But you will get an error if there is no available truck, so check that.
Nevertheless, what you are doing is horrible practice... And there is a much easier way to do it if you put the availability in your truck if your truck is an agent...
Then you can just do
Truck truck=randomWhere(trucks,t->t.available==1);
if(truck!=null)
agent.ID=truck.ID;

"Appending" to an ArraySlice?

Say ...
you have about 20 Thing
very often, you do a complex calculation running through a loop of say 1000 items. The end result is a varying number around 20 each time
you don't know how many there will be until you run through the whole loop
you then want to quickly (and of course elegantly!) access the result set in many places
for performance reasons you don't want to just make a new array each time. note that unfortunately there's a differing amount so you can't just reuse the same array trivially.
What about ...
var thingsBacking = [Thing](repeating: Thing(), count: 100) // hard limit!
var things: ArraySlice<Thing> = []
func fatCalculation() {
var pin: Int = 0
// happily, no need to clean-out thingsBacking
for c in .. some huge loop {
... only some of the items (roughly 20 say) become the result
x = .. one of the result items
thingsBacking[pin] = Thing(... x, y, z )
pin += 1
}
// and then, magic of slices ...
things = thingsBacking[0..<pin]
(Then, you can do this anywhere... for t in things { .. } )
What I am wondering, is there a way you can call to an ArraySlice<Thing> to do that in one step - to "append to" an ArraySlice and avoid having to bother setting the length at the end?
So, something like this ..
things = ... set it to zero length
things.quasiAppend(x)
things.quasiAppend(x2)
things.quasiAppend(x3)
With no further effort, things now has a length of three and indeed the three items are already in the backing array.
I'm particularly interested in performance here (unusually!)
Another approach,
var thingsBacking = [Thing?](repeating: Thing(), count: 100) // hard limit!
and just set the first one after your data to nil as an end-marker. Again, you don't have to waste time zeroing. But the end marker is a nuisance.
Is there a more better way to solve this particular type of array-performance problem?
Based on MartinR's comments, it would seem that for the problem
the data points are incoming and
you don't know how many there will be until the last one (always less than a limit) and
you're having to redo the whole thing at high Hz
It would seem to be best to just:
(1) set up the array
var ra = [Thing](repeating: Thing(), count: 100) // hard limit!
(2) at the start of each run,
.removeAll(keepingCapacity: true)
(3) just go ahead and .append each one.
(4) you don't have to especially mark the end or set a length once finished.
It seems it will indeed then use the same array backing. And it of course "increases the length" as it were each time you append - and you can iterate happily at any time.
Slices - get lost!

Cassandra: get_range_slices of TimeUUID super column?

I have a schema of Row Keys 1-n. In each row there are a variable number of supercolumns with a TimeUUID 'name'. Im hoping to be able to query this data by a time range.
Two issues have come up:
in KeyRange -> the values that I put in for 'start_key' and 'end_key' are getting misunderstood (for lack of a better term) by Thrift. Experimenting with different groups of values Im not seeing what I expect and often get back something completely unexpected.
Example: my row keys are running from 1-1000 with lots of random gaps. I put start_key = 50 and end_key = 20 .. and I get back rows with keys ranging from 99 to 414.
Example: I have a known row with key = 13. Putting this value into start_key and end_key gives me no results.
Second issue: even when I do get results the 'columns' portion of the 'keyslice' is always empty. I have checked via cassandra-cli and I know there is data.
Im using Perl as follows:
my $slice_range = new Cassandra::SliceRange();
$slice_range->{ start } = create_UUID( UUID::Tiny::UUID_TIME, "2010-12-24 00:00:00" );
$slice_range->{ finish } = create_UUID( UUID::Tiny::UUID_TIME, "2011-12-25 00:00:00" );
my $slice_predicate = new Cassandra::SlicePredicate();
$slice_predicate->{ slice_range } = $slice_range;
my $key_range = new Cassandra::KeyRange();
$key_range->{ start_key } = 13;
$key_range->{ end_key } = 13;
my $result = $client->get_range_slices( $column_parent, $slice_predicate, $key_range, $consistency_level );
print Dumper( $result );
Clearly Im misunderstanding some basic precept.
EDIT: It turns out that the Perl library Im using is not properly documented. The UUID creation was not working as advertised. I opened it up, fixed it, and now its all going a bit more as I was expecting. I can slice my supercolumns by date/time range. Still working on getting the key range portion to work.
http://wiki.apache.org/cassandra/FAQ#range_rp covers why you're not seeing what you expect with key ranges.
You need to specify a SlicePredicate that contains the actual range of what you're trying to select. The default of no column_names and no slice_range will result in the empty columns list that you see.