JSX/Photoshop: layer opacity issue - opacity

Photoshop CS6/JSX. I'm changing the opacity of the selected layer by increasing or reducing it by 10. The problems I'm getting:
When reducing the value by 10 I get this secuence of reductions:
100 - 90 - 80 - 71 - 61 - 51 - 41 - 31 - 22 - 12 - 2
When increasing the results are:
0 - 10 - 20 - 31 - 41 - 51 - 61 - 71 - 82 - 92
The code is something like this:
var opc = app.activeDocument.activeLayer.opacity;
desc2.putUnitDouble(cTID('Opct'), cTID('#Prc'), opc - 10.0);
/* or
desc2.putUnitDouble(cTID('Opct'), cTID('#Prc'), opc + 10.0); */
Any idea on how to fix it in order to get only multiples of 10?
Thanks in advance

Math.round() do the trick. First, force the opacity of the layer to be round:
var opc = Math.round(app.activeDocument.activeLayer.opacity)
Now you can change the opacity by adding or substracting the desired value:
app.activeDocument.activeLayer.opacity = opc -10; //or +10
Thanks to Anna Forrest for the help.

Related

How can I efficiently convert the output of one KDB function into three table columns?

I have a function that takes as input some of the values in a table and returns a tuple if you will - three separate return values, which I want to transpose into the output of a query. Here's a simplified example of what I want to achieve:
multiplier:{(x*2;x*3;x*3)};
select twoX:multiplier[price][0]; threeX:multiplier[price][1]; fourX:multiplier[price][2] from data;
The above basically works (I think I've got the syntax right for the simplified example - if not then hopefully my intention is clear), but is inefficient because I'm calling the function three times and throwing away most of the output each time. I want to rewrite the query to only call the function once, and I'm struggling.
Update
I think I missed a crucial piece of information in my explanation of the problem which affects the outcome - I need to get other data in the query alongside the output of my function. Here's a hopefully more realistic example:
multiplier:{(x*2;x*3;x*4)};
select average:avg price, total:sum price, twoX:multiplier[sum price][0]; threeX:multiplier[sum price][1]; fourX:multiplier[sum price][2] by category from data;
I'll have a go at adapting your answers to fit this requirement anyway, and apologies for missing this bit of information. The real function if a proprietary and fairly complex algorithm and the real query has about 30 output columns, hence the attempt at simplifying the example :)
If you're just looking for the results themselves you can extract (exec) as lists, create dictionary and then flip the dictionary into a table:
q)exec flip`twoX`threeX`fourX!multiplier[price] from ([]price:til 10)
twoX threeX fourX
-----------------
0 0 0
2 3 4
4 6 8
6 9 12
8 12 16
10 15 20
12 18 24
14 21 28
16 24 32
18 27 36
If you need other columns from the original table too then its trickier but you could join the tables sideways using ,'
q)t:([]price:til 10)
q)t,'exec flip`twoX`threeX`fourX!multiplier[price] from t
An apply # can also achieve what you want. Here data is just a table with 10 random prices. # is then used to apply the multiplier function to the price column while also assigning a column name to each of the three resulting lists:
q)data:([] price:10?100)
q)multiplier:{(x*2;x*3;x*3)}
q)#[data;`twoX`threeX`fourX;:;multiplier data`price]
price twoX threeX fourX
-----------------------
80 160 240 240
24 48 72 72
41 82 123 123
0 0 0 0
81 162 243 243
10 20 30 30
36 72 108 108
36 72 108 108
16 32 48 48
17 34 51 51

Postgresql get the distinct values with another max value

I have a table with this values:
id - idProduction - historical - idVehicle - km
1 - 200 - 1 - 258 - 100
2 - 200 - 2 - 258 - 100
3 - 200 - 2 - 259 - 150
4 - 200 - 3 - 258 - 120
5 - 200 - 3 - 259 - 170
6 - 300 - 1 - 100 - 80
7 - 100 - 1 - 258 - 140
8 - 300 - 2 - 325 - 50
I need to get the values with the max historical, for all the distinct idProduction. In that case:
4 - 200 - 3 - 258 - 120
5 - 200 - 3 - 259 - 170
7 - 100 - 1 - 258 - 140
8 - 300 - 2 - 325 - 50
It my first work with postgresql, so I don't have to much idea on how to do it, does anyone can help me?
Thank you!
I think with that I can solve my problem, but I'm not sure... :
SELECT id, productions_vehicles.id_production, nu_task_number, id_historical, id_vehicle
FROM productions_vehicles
INNER JOIN
(SELECT id_production, MAX(id_historical) AS idHistorico
FROM productions_vehicles
GROUP BY id_production) topHistorico
ON productions_vehicles.id_production = topHistorico.id_production
AND productions_vehicles.id_historical = topHistorico.idHistorico;
You effectively need two requests, your solution looks good, you can also use the WITH clause to do the first request :
WITH topHistorico (
SELECT id_production, MAX(id_historical) SA idHistorico
FROM productions_vehicles
GROUP BY id_production)
SELECT id, pv.id_production, nu_task_number, id_historical, id_vehicle
FROM production_vehicles pv
INNER JOIN topHistorico th ON pv.id_production = th.id_production AND pv.id_historical = th.idHistorico
PostgreSQL: Documentation: 9.1: WITH Queries (Common Table Expressions)

Calculate Variance of a Group data

I have a table contain height and frequency.I want to calculate the variance of it.
Height 140 150 160 170 180 190
Frequency 3 5 57 63 30 2
I have tried the below code:
height=[140 150 160 170 180 190;3 5 57 63 30 2]
height=height(:)
V = var(height) %Calculate Variance
**This give an answer of 5.7316e+03**
while with formula it give an answer of 81.8594. Now please tell me how can i do this?
Use weighted variance:
h=height;
var(h(1,:),h(2,:))

Matlab Date Vector

I have an array A with time information in the format hhmmss. Ultimately, I would like to normalize this array by indicating the elapsed time (in seconds, starting from the first time).
A = [ 150213
150013
145813
145613
145413
145313
145213
145113
145013
144943
144913
144843
144833
144823
144813
144803
144753
144743
144741
144739
144737
144735
144733
144731
144729
144727
144725
144723
144721
144719]
So, in the end the array should be :
A_updated = [894
774
654
534
414
354
294
234
174
144
114
84
74
64
54
44
34
24
22
20
18
16
14
12
10
8
6
4
2
0
]
What would be the quickest 'Matlab way' to proceed with this? Many thanks in advance for your ideas.
I haven't used Matlab in a while, so forgive the syntax mistakes, and I don't have it available right now, but here's what I would try. Basically, convert everything to seconds then subtract the last element.
At = uint32(A);
A_updated = mod(At,100);
At = floor(At ./ 100);
A_updated = A_updated + mod(At,100) * 60;
At = floor(At ./ 100);
A_updated = A_updated + At * 3600;
A_updated = A_updated - A_updated(end);
I did this in Octave so you may need to adjust the syntax for datenum:
B = double(A);
hh = floor(B/10000);
mm = floor((B-hh*10000)/100);
ss = B - hh*10000 - mm*100;
C = datenum(2013,10,28,hh,mm,ss);
elapsed_time = (C-C(end))*3600*24;

Tidying up a list

I'm fairly sure there should be an elegant solution to this (in MATLAB), but I just can't think of it right now.
I have a list with [classIndex, start, end], and I want to collapse consecutive class indices into one group like so:
This
1 1 40
2 46 53
2 55 55
2 57 64
2 67 67
3 68 91
1 94 107
Should turn into this
1 1 40
2 46 67
3 68 91
1 94 107
How do I do that?
EDIT
Never mind, I think I got it - it's almost like fmarc's solution, but gets the indices right
a=[ 1 1 40
2 46 53
2 55 55
2 57 64
2 67 67
3 68 91
1 94 107];
d = diff(a(:,1));
startIdx = logical([1;d]);
endIdx = logical([d;1]);
b = [a(startIdx,1),a(startIdx,2),a(endIdx,3)];
Here is one solution:
Ad = find([1; diff(A(:,1))]~=0);
output = A(Ad,:);
output(:,3) = A([Ad(2:end)-1; Ad(end)],3);
clear Ad
One way to do it if the column in question is numeric:
Build the differences along the id-column. Consecutive identical items will have zero here:
diffind = diff(a(:,1)');
Use that to index your array, using logical indexing.
b = a([true [diffind~=0]],:);
Since the first item is always included and the difference vector starts with the difference from first to second element, we need to prepend one true value to the list.