MEL : extract entire value of a keyframe in maya - maya

My question is pretty simple, i use a mel command to extract camera data value.
i use this code :
keyframe -q -vc Camera0Node.translateX
it result : 2385.11
the problem is my keyframe value is 2385.11010742
the difference is minimal but i want to have the exact value
any idea how i can get non rounded value ?
thank you

I'm pretty sure the result is your full value, but Maya only displays it as a rounded number.
As an example, let's assign that value directly to a variable:
$val = 2385.11010742;
Then print it to console:
print($val);
The result displays 2385.110107.
Now let's do a comparison:
print($val == 2385.110107); // returns 0 for False
But when comparing to the original value:
print($val == 2385.11010742); // returns 1 for True

Related

<Pinescript> Indicator error using bar prices in arrays

I'm using this simple code to learn arrays in pine v5:
var float[] my_arr = array.new_float(0)
if barstate.islast
array.push(my_arr, close[1])
a = array.get (my_arr, 0)
plot(a)
I'm trying to insert the previous close in my_arr and plot its value. I think the value of the close[1] should be entered in the array at the index 0 using: array.push() But when I plot that value, It appears to me this message:
The barstate last call will not run until the last bar of the chart. When you load a script it runs on all historical bars first beginning at the first bar in time. The array.get call is trying to pull a value from an array that is not populated. You can put in a ternary check to make sure the array size is greater than 0, or you could initialize your array with a size and a value like (1) which would give the first populated value na until populated by your of statement. If you just want to plot close[1] you can skip the array and just plot that series
Cheers

Normalizing, returns divide by zero error

I have a sensor reading in data, that I wish to normalize.
f1020=[]
While True:
cmnd = getMsrMnt(filter.1020) #command to get a sensor value
f1020.append(cmnd.measurement) #write the sensor value to the above array
norm_f1020 = [(float(i)-min(f1020))/(max(f1020)-min(f1020)) for i in f1020] #normalize the data
However, at this point, I get the following error
ZeroDivisionError: float division by zero
This will always happen at index zero because there is only one value in the array at the moment! How can I get around this error with the present norm_f1020 technique, if there is one.
You can solve this by 2 ways:
add to the division really small value
because it should be something that divided by 0, you can do try except and add float('inf') instead of the result of the division
but I would go with the first way:
f1020=[]
While True:
cmnd = getMsrMnt(filter.1020) #command to get a sensor value
f1020.append(cmnd.measurement) #write the sensor value to the above array
norm_f1020 = [(float(i)-min(f1020))/((max(f1020)-min(f1020) + 10**-100)) for i in f1020] #normalize the data
Just make sure that the value that you have selected isn't too small (for example at 1/(0 + 10**-500) I got ZeroDivisionError.

trying to get the value of the struct inside an array

Looking for a one liner code either in java or cfm, where i do not need to loop over te array of structs to use te structfind to get the value from it.
right now looking at it,
Coldfusion - How to loop through an Array of Structure and print out dynamically all KEY values?
where i can loop over and get the value of the key match
but trying to check if something like this can be done
<cfset myvalue = structfindvaluefromAnything(myarrayofstruct,"infor")>
I like Sev's approach. I would change it slightly
<cfscript>
superheroes=[
{"name":"Iron Man","member":"Avengers"},
{"name":"Spider-Man","member":"Avengers"},
{"name":"Wonder Woman","member":"Justice League"},
{"name":"Hulk","member":"Avengers"},
{"name":"Thor","member":"Avengers"},
{"name":"Aquaman","member":"Justice League"}
];
avengers = superheroes.filter(function(item) {
return item.member == "Avengers";
});
writeDump(avengers);
</cfscript>
If you really want to do it in one line then you could use ArrayFilter() in combination with StructFindValue().
Adapting from the Adobe docs for ArrayFilter - https://helpx.adobe.com/coldfusion/cfml-reference/coldfusion-functions/functions-a-b/arrayfilter.html - something like this:
<cfscript>
superheroes=[
{"name":"Iron Man","member":"Avengers"},
{"name":"Wonder Woman","member":"Justice League"},
{"name":"Hulk","member":"Avengers"},
{"name":"Thor","member":"Avengers"},
{"name":"Aquaman","member":"Justice League"}
];
avengers=ArrayFilter(superheroes,function(item){
return ArrayLen(StructFindValue( item, "Avengers"));
});
writeDump(var=avengers, label="all matches");
writeDump(var=ArrayLen(avengers) ? avengers[1] : "Not found", label="first match only");
writeDump(var=structFindValue({"a":superheroes}, "Avengers", "all"), label="without arrayFilter");
</cfscript>
I believe the function available for this nearly exactly what you were hoping for...
StructFindValue(struct, value [, scope])
Searches recursively through a substructure of nested arrays, structures, and other elements for structures with values that match the search key in the value parameter.
Returns an array that contains structures keys whose values match the search key value. If none are found, returns an array of size 0.
Based on the gist you provided above (https://cffiddle.org/app/file?filepath=3e26c1ac-d5db-482f-9bb2-995e6cabe704/49b3e106-8db9-4411-a6d4-10deb3f8cb0e/24e44eba-45ef-4744-a6e6-53395c09a344.cfm), I think you've clarified your expectations a little bit.
In your gist, you say you want to be able to search an array of structs and find the row that has a "name" key with a value of "form". Then, you want to take the value of the "value" key that's associated with that struct in the array row. If there is no value then return 0.
You wanted to be able to do this in a single line of code, and the above answers do accomplish that. My answer essentially builds on those.
As demonstrated in the earlier answers, you still want to use closure functions to filter down your final output. Those are very quick and essentially built to do what you're trying to do.
The Fiddle that I worked with is here: https://cffiddle.org/app/file?filepath=b3507f1d-6ac2-4900-baed-fb3faf5a3b3a/e526afc2-bb85-4aea-ad0e-dcf38f52b642/75d88d2b-f990-44c1-9d9f-22931bf9d4d7.cfm
I've done two things with this.
First, I worked it as if you expected to encounter multiple records for your filtering value, and then turn those into a comma-delimited list. If you need another structure, the reduce() function in my code can be modified to handle this.
Second, I worked it as if you expected to encounter only one filtered record, returning only a single value.
The first thing I did, which is mostly the same in both methods, and which is essentially the same as the previous answers, is to filter your original array for just the value you want.
This is done like this:
myResult = originalArray.filter(
function(itm){
return itm?.name=="form"; /// ?. = safe-navigation operator.
}
)
I've broken it to multiple lines for clarity.
This will return a new array of structs consisting of your filtered rows.
But then you want to take those records and return the "value" from those rows (defaulting to 0 if no value. You can do this with a reduce().
commaDelimitedValue =
myResult.reduce(
function(prev,nxt) {
return prev.listappend( ( nxt.value.len() ? nxt.value : 0 ) ) ;
}
, "" /// Initialization value
) ;
Again, this can be written in one row, but I've included line breaks for clarity.
The reduce() function essentially just reduces your input to a single value. It follows the format of .reduce( function( previousValue, nextValue ){ return .... },<initializationValue>), where, on the first iterations, the initializationValue is substituted for previousValue, then previousValue becomes the result of that iteration. nextValue is actually the current iteration that you will derive a result from.
More at: https://coldfusion.adobe.com/2017/10/map-reduce-and-filter-functions-in-coldfusion/
In my assumption here, you could possibly have multiple rows returned from your filter(). You take those rows and append the value to a commma-delimited list. So you would end up with a result like 20,10,0,0 - representing 4 rows in your filtered results.
I also check for a length of the value and default it to 0 if it's an empty string. Above, I said that you could just use an Elvis Operator (:?) on that, but that doesn't work for a simple value like an empty string. Elvis works with NULLs, which the earlier array did have.
To put this back to one line, you can chain both of these functions. So you end up with:
myFinalResult =
myOriginalArray.filter(
function(itm){
return itm?.name=="form";
}
)
.reduce(
function(prev,nxt) {
return prev.listappend( ( nxt.value.trim().len() ? nxt.value : 0 ) ) ;
}
, ""
)
;
Again, that code is doing a lot, but it is still essentially one line. The final result from that would again be something like "20,10,0,0" for 4 rows with 2 defaulted to 0.
If you only expect your filter to return a single row, or if you only want a single value, you can simplify that a little bit.
myFinalResult = myOriginalArray.filter( function(itm){ return itm?.name=="fm" && (itm?.value.trim().len()>0) ; } )[1]["value"] ?: 0 ;
With this, I am back to using my previous trick with Elvis to default a row with no value, since I am filtering out the "form" struct with an empty-string "value". && is the same as AND. Technically this CAN filter more than one row from the original array, but the [1] will only pick the first row from the filtered rows. It also doesn't need to use a reduce(). If there's more than one row filtered, each iteration will just overwrite the previous one.
This will return a simple, single value with something like 42 - which is the last filtered value in the array, since it overwrites the previous row's value.
My Fiddle (https://cffiddle.org/app/file?filepath=b3507f1d-6ac2-4900-baed-fb3faf5a3b3a/e526afc2-bb85-4aea-ad0e-dcf38f52b642/75d88d2b-f990-44c1-9d9f-22931bf9d4d7.cfm) has some additional comments, and I set up a couple of edge cases that demonstrate the filtering and safe-navigation.
I would also like to reiterate that if this is Lucee 5+ or ACF2018+, you can shorten this further with Arrow Functions.

Empty find matlab

I am trying to find what's the number on the array for the 1000 value. This is my code:
size = linspace(420, 2200, 100000);
size1000 = find(size==1000);
It returns an empty variable for size 1000. If I actually change 1000 with 420 it actually returns 1 like it should. Why is this not working?
The result of find is empty because 1000 is not in the array and isn't expected to be. Using the inputs to linspace, your expected step size is going to be 0.0178
(2200 - 420) / 100000
% 0.0178
With this step size and a starting value of 420, you're never going to hit the value 1000 exactly. The closest values in the array are 1000.001 and 999.983. If you want to identify values that are close to 1000, you can do something like the following instead.
inds = find(abs(size - 1000) < 0.01);
As a side-note, do not use size as the name of a variable since that is the name of a built-in MATLAB function and using it as a variable name can result in unexpected behavior.
You can also use logical indexing to simply remove all of the values below 1000, and then you know that the first component of what is left will be your answer....
a = size(size>1000);
a(1)
For what it is worth, please PLEASE do not use size as a variable name. size is an important MATLAB function to get the size of a matrix. For example,
>> size(randn(2,3))
ans =
2 3
However, when you declare a variable named size, like you do in your code, you will hide this function. So now, at some point later in your code, if you called size(randn(2,3)), you will get the cryptic error
Subscript indices must either be real positive integers or
logicals.
These are extremely tricky to track down, so please avoid it.

Array formula in excel suddenly not working... troubleshooting

I am currently using this array formula..
{=LARGE(IF(('Data Input'!$L$3:$L$15000=$B10)*('Data Input'!$H$3:$H$15000>$C10),'Data Input'!$O$3:$O$15000,0),1)}
Where B10 is a text ID, like 658A and L:L is the column with the IDs.
C10 is a date, with H:H being the column with dates.
O:O being the column with the # value that I am retrieving.
This formula works fine with my purposes when used with ctrl,shift,enter
The problem arises when I try to use...
{=IF('Data Input'!$L$3:$L$15000=$B10,1,0)}
It always returns a FALSE result, even though it works correctly in the first formula.
What is different about the second formula that changes the results?
This is very strange to me.
Thanks for any help.
the IF is only comaring the first value of the array that is returned, so only if the first comparison is true, will it return a true value.
Example to illustrate:
formula
Formula:
{=IF(A1:A3=B2,1,0)} will; return 0, unless cell A1 is changed to true. To change the result to have it return true if any of the values are true, you have to resort to a little trickery...
First, use -- to change the True/False values to 1/0, then use SUM to add them together. as IF treats any non-zero result as true, this will result in 1 being returned when any comparison is true.
Working through our example with the new formula {=IF(SUM(--(A1:A3=B2)),1,0)} (still an array formula) we get the following steps in evaluation:
=IF(SUM(--(A1:A3=B2)),1,0)
=IF(SUM(--(A1:A3=2)),1,0)
=IF(SUM(--({1,2,2}=2)),1,0)
=IF(SUM(--({False,True,True})),1,0)
=IF(SUM(0,1,1),1,0)
=IF(2,1,0)
=1
Your second formula is, itself, returning an array. You are only viewing the top left element in that return array - which happens to be FALSE.
Your first formula returns a scalar value; that is the difference.
If you want to sum the '1' values then your second formula could be amended to
{=SUM(IF('Data Input'!$L$3:$L$15000=$B10,1,0))}
which is also a scalar return.

Resources