case statement in Dax - dax

I have the following case when statement:
case when ts.wgt_kg / ((hgt_cm / 100) * (hgt_cm / 100)) < 18.5 then 'Underweight < 18.5'
when ts.wgt_kg / ((hgt_cm / 100) * (hgt_cm / 100)) between 18.5 and 24.9 then 'Normal 18.5-24.9'
when ts.wgt_kg / ((hgt_cm / 100) * (hgt_cm / 100)) between 25.0 and 29.9 then 'Overweight 25-29.9'
when ts.wgt_kg / ((hgt_cm / 100) * (hgt_cm / 100)) > 30.0 then 'Obese > 30.0'
end as BMI
How can i convert it into DAX? I tried to google it but I wasn't able to find anything useful. Can someone help me with that please.
Thanks

Try something along these lines:
BMI Category =
VAR BMI = ts.wgt_kg / ( ( hgt_cm / 100 ) * ( hgt_cm / 100 ) )
RETURN
SWITCH (
TRUE (),
BMI < 18.5, "Underweight < 18.5",
BMI < 25.0, "Normal 18.5-24.9",
BMI < 30.0, "Overweight 25-29.9",
"Obese > 30.0"
)
This will return the first condition that evaluates to true or use the last argument if none of the above are true.

Related

How to refactor round method with 3 digits

I would like to round float numbers like this :
125.212 = 125.250
125.249 = 125.250
125.268 = 125.250
125.280 = 125.275
125.999 = 126.000
I have do a method, how can I refactor it ?
def round_km(n)
n = n * 1000
m = n % 100
if (m <= 25)
"%.3f" % ((n - m + 25) / 1000).round(3)
elsif (m <= 50)
"%.3f" % ((n - m + 50) / 1000).round(3)
elsif (m <= 75)
"%.3f" % ((n - m + 75) / 1000).round(3)
else
"%.3f" % ((n - m + 100) / 1000).round(3)
end
end
I found a better solution :
def round_km(n)
"%.3f" % ((n/0.250).ceil * 0.250)
end

laravel query builder without raw?

i have a query with this code
return $query
->select([
'lineofpro AS pabrik_line',
'date AS tanggal',
DB::raw('ROUND((100*(COUNT( CASE WHEN `tabTravel Card`.qcresu = "Pass" THEN 1 ELSE NULL END ))/count(`tabTravel Card`.lineofpro))) AS lar_percentage'),
DB::raw("ROUND( IFNULL(SUM(`tabTravel Card`.finga),0) / ( count(`tabTravel Card`.lineofpro) * 200) * 1000000) AS finger_a"),
DB::raw("ROUND( IFNULL(SUM(`tabTravel Card`.fingb),0) / ( count(`tabTravel Card`.lineofpro) * 200) * 1000000) AS finger_b"),
DB::raw("ROUND( IFNULL(SUM(`tabTravel Card`.fingc),0) / ( count(`tabTravel Card`.lineofpro) * 200) * 1000000) AS finger_c"),
DB::raw("ROUND( IFNULL(SUM(`tabTravel Card`.fingd),0) / ( count(`tabTravel Card`.lineofpro) * 200) * 1000000) AS finger_d"),
DB::raw("ROUND( IFNULL(SUM(`tabTravel Card`.finge),0) / ( count(`tabTravel Card`.lineofpro) * 200) * 1000000) AS finger_e"),
DB::raw("ROUND( IFNULL(SUM(`tabTravel Card`.crotchf),0) / ( count(`tabTravel Card`.lineofpro) * 200) * 1000000) AS crotch_f"),
DB::raw("ROUND( IFNULL(SUM(`tabTravel Card`.crotchg),0) / ( count(`tabTravel Card`.lineofpro) * 200) * 1000000) AS crotch_g"),
DB::raw("ROUND( IFNULL(SUM(`tabTravel Card`.crotchh),0) / ( count(`tabTravel Card`.lineofpro) * 200) * 1000000) AS crotch_h"),
DB::raw("ROUND( IFNULL(SUM(`tabTravel Card`.crotchi),0) / ( count(`tabTravel Card`.lineofpro) * 200) * 1000000) AS crotch_i"),
DB::raw("ROUND( IFNULL(SUM(`tabTravel Card`.palmj),0) / ( count(`tabTravel Card`.lineofpro) * 200) * 1000000) AS palm_j"),
DB::raw("ROUND( IFNULL(SUM(`tabTravel Card`.cuffk),0) / ( count(`tabTravel Card`.lineofpro) * 200) * 1000000) AS cuff_k"),
DB::raw("ROUND( IFNULL(SUM(`tabTravel Card`.totalpin),0) / ( count(`tabTravel Card`.lineofpro) * 200) * 1000000) AS total_pinhole"),
])
->where([
['date', '>=', $beginDate],
['date', '<=', $endDate],
$this->generatePlanCodeFilter($plan, $line),
])
->groupBy([
'lineofpro',
'date',
]);
is it possible to query this without DB::raw?
i try to create dynamic query
but using an array to return the select value with DB::raw will only return '' string
You can define your fields as accessors and move your calculation logic there.
Then you can build the query using Eloquent.
Ex:
public function getTotalPinholeAttribute()
{
// calculation logic here
}
You can read more about accessors here: https://laravel.com/docs/8.x/eloquent-mutators#defining-an-accessor

How to calculate percentage between the range of two values a third value is

Example:
I'm trying to figure out the calculation for finding the percentage between two values that a third value is.
Example: The range is 46 to 195. The value 46 would 0%, and the value 195 would be 100% of the range. What percentage of this range is the value 65?
rangeMin=46
rangeMax=195
inputValue=65
inputPercentage = ?
Well, I would use the formula
((input - min) * 100) / (max - min)
For your example it would be
((65 - 46) * 100) / (195 - 46) = 12.75
Or a little bit longer
range = max - min
correctedStartValue = input - min
percentage = (correctedStartValue * 100) / range
If you already have the percentage and you're looking for the "input value" in a given range, then you can use the adjusted formula provided by Dustin in the comments:
value = (percentage * (max - min) / 100) + min
I put together this function to calculate it. It also gives the ability to set a mid way 100% point that then goes back down.
Usage
//[] = optional
rangePercentage(input, minimum_range, maximum_normal_range, [maximum_upper_range]);
rangePercentage(250, 0, 500); //returns 50 (as in 50%)
rangePercentage(100, 0, 200, 400); //returns 50
rangePercentage(200, 0, 200, 400); //returns 100
rangePercentage(300, 0, 200, 400); //returns 50
The function
function rangePercentage (input, range_min, range_max, range_2ndMax){
var percentage = ((input - range_min) * 100) / (range_max - range_min);
if (percentage > 100) {
if (typeof range_2ndMax !== 'undefined'){
percentage = ((range_2ndMax - input) * 100) / (range_2ndMax - range_max);
if (percentage < 0) {
percentage = 0;
}
} else {
percentage = 100;
}
} else if (percentage < 0){
percentage = 0;
}
return percentage;
}
If you want to calculate the percentages of a list of values and truncate the values between a max and min you can do something like this:
private getPercentages(arr:number[], min:number=0, max:number=100): number[] {
let maxValue = Math.max( ...arr );
return arr.map((el)=>{
let percent = el * 100 / maxValue;
return percent * ((max - min) / 100) + min;
});
};
Here the function call:
this.getPercentages([20,30,80,200],20,50);
would return
[23, 24.5, 32, 50]
where the percentages are relative and placed between the min and max value.
Can be used for scaling any number of variables
Python Implementation:
# List1 will contain all the variables
list1 = []
# append all the variables in list1
list1.append(var1)
list1.append(var2)
list1.append(var3)
list1.append(var4)
# Sorting the list in ascending order
list1.sort(key = None, reverse = False)
# Normalizing each variable using ( X_Normalized = (X - X_minimum) / (X_Maximum - X_minimum) )
normalized_var1 = (var1 - list1[0]) / (list1[-1] - list1[0])
normalized_var2 = (var2 - list1[0]) / (list1[-1] - list1[0])
normalized_var3 = (var3 - list1[0]) / (list1[-1] - list1[0])
normalized_var4 = (var4 - list1[0]) / (list1[-1] - list1[0])

Calculating Brightness and Contrast similar to new Adobe Photoshop or Lightroom functions

I am trying to create Brightness and Contrast filters similar to new Adobe Photoshop or Lightroom Brightness and Contrast filters. I am doing RGB -> XYZ - xyY conversion and with increasing pixel Brightness (Y) ( not linear increase, Brightness increase is calculated depending on pixels Brightness) and then converting back to XYZ and RGB trying to get as similar as possible values to test image that I used to increase Brightness in Adobe. I am not getting similar results as I think I am missing something, maybe gamma calculation or as images are in sRGB space some color space conversion, or I simple have bug in Color conversion code? So here are Color conversion function I used (in Objective-C) :
-(void) convertRGBcolor:(cColorRGB*) pRGB toXYZcolor:(zColorXYZ*) pXYZ
{
if(pRGB == nil || pXYZ == nil) {
return;
}
double var_R = ( pRGB->r / 255.0 );
double var_G = ( pRGB->g / 255.0 );
double var_B = ( pRGB->b / 255.0 );
if ( var_R > 0.04045 ) var_R = pow((( var_R + 0.055 ) / 1.055 ) , 2.4);
else var_R = var_R / 12.92;
if ( var_G > 0.04045 ) var_G = pow((( var_G + 0.055 ) / 1.055 ) , 2.4);
else var_G = var_G / 12.92;
if ( var_B > 0.04045 ) var_B = pow((( var_B + 0.055 ) / 1.055 ) , 2.4);
else var_B = var_B / 12.92;
var_R = var_R * 100;
var_G = var_G * 100;
var_B = var_B * 100;
//Observer. = 2°, Illuminant = D65
pXYZ->X = var_R * 0.4124 + var_G * 0.3576 + var_B * 0.1805;
pXYZ->Y = var_R * 0.2126 + var_G * 0.7152 + var_B * 0.0722;
pXYZ->Z = var_R * 0.0193 + var_G * 0.1192 + var_B * 0.9505;
}
-(void) convertXYZcolor:(zColorXYZ*) pXYZ toRGBcolor:(cColorRGB*) pRGB
{
if(pRGB == nil || pXYZ == nil) {
return;
}
double var_X = pXYZ->X / 100; //X from 0 to 95.047
double var_Y = pXYZ->Y / 100; //Y from 0 to 100.000
double var_Z = pXYZ->Z / 100; //Z from 0 to 108.883
double var_R = var_X * 3.2406 + var_Y * -1.5372 + var_Z * -0.4986;
double var_G = var_X * -0.9689 + var_Y * 1.8758 + var_Z * 0.0415;
double var_B = var_X * 0.0557 + var_Y * -0.2040 + var_Z * 1.0570;
if ( var_R > 0.0031308 ) var_R = 1.055 * ( pow( var_R,(1/2.4))) - 0.055;
else var_R = 12.92 * var_R;
if ( var_G > 0.0031308 ) var_G = 1.055 * ( pow( var_G,(1/2.4))) - 0.055;
else var_G = 12.92 * var_G;
if ( var_B > 0.0031308 ) var_B = 1.055 * ( pow( var_B,(1/2.4))) - 0.055;
else var_B = 12.92 * var_B;
pRGB->r = var_R * 255;
pRGB->g = var_G * 255;
pRGB->b = var_B * 255;
}
-(void) convertYxycolor:(zColorYxy*) pYxy toXYZcolor:(zColorXYZ*) pXYZ
{
if(pYxy == nil || pXYZ == nil) {
return;
}
pXYZ->X = pYxy->x * ( pYxy->Y / pYxy->y );
pXYZ->Y = pYxy->Y;
pXYZ->Z = ( 1 - pYxy->x - pYxy->y ) * ( pYxy->Y / pYxy->y );
}
-(void) convertXYZcolor:(zColorXYZ*) pXYZ toYxycolor:(zColorYxy*) pYxy
{
if(pYxy == nil || pXYZ == nil) {
return;
}
pYxy->Y = pXYZ->Y;
pYxy->x = pXYZ->X / ( pXYZ->X + pXYZ->Y + pXYZ->Z );
pYxy->y = pXYZ->Y / ( pXYZ->X + pXYZ->Y + pXYZ->Z );
}

efficient X within limit algorithm

I determine limits as limit(0)=0; limit(y)=2*1.08^(y-1), y∈{1,2,3,...,50} or if you prefeer iterative functions:
limit(0)=0
limit(1)=2
limit(y)=limit(y-1)*1.08, x∈{2,3,4,...,50}
Exmples:
limit(1) = 2*1.08^0 = 2
limit(2) = 2*1.08^1 = 2.16
limit(3) = 2*1.08^2 = 2.3328
...
for a given x∈[0,infinity) I want an efficient formula to calculate y so that limit(y)>x and limit(y-1)≤x or 50 if there is none.
Any ideas?
or is pre-calculating the 50 limits and using a couple of ifs the best solution?
I am using erlang as language, but I think it will not make much of a difference.
limit(y) = 2 * 1.08^(y-1)
limit(y) > x >= limit(y - 1)
Now if I haven't made a mistake,
2 * 1.08^(y - 1) > x >= 2 * 1.08^(y - 2)
1.08^(y - 1) > x / 2 >= 1.08^(y - 2)
y - 1 > log[1.08](x / 2) >= y - 2
y + 1 > 2 + ln(x / 2) / ln(1.08) >= y
y <= 2 + ln(x / 2) / ln(1.08) < y + 1
Which gives you
y = floor(2 + ln(x / 2) / ln(1.08))

Resources