PHP ceil calculation differs in result from manually calculated result - php

I have this script:
function round_price_with_limits( $price = null, $multiplier = 9.3, $nearest = 10, $minus = 0.05, $map = 9.95, $msrp = 9999999999) {
// Ensure a price was provided.
if ( !empty( $price ) ) {
// Calculate price with markup and round it.
$rounded_price = ( ceil ( ( $price * $multiplier ) / $nearest ) * $nearest ) - $minus;
// If price is less than minimum, return minimum.
if($rounded_price < $map){
return $map;
}
// If price is greater than maximum, return maximum.
elseif($rounded_price > $msrp){
return $msrp;
} else {
// Return price otherwise.
return $rounded_price;
}
}
}
It works on almost all products, except for one with $price value = 1,76.
The end result when running the script becommes 9.95
When I calculate by hand, the result is 19.95
Can you spot why this is calculated differently via the php?

Related

WP cli php script gives notice error: A non well formed numeric value

My script gives this error: PHP Notice: A non well formed numeric value encountered.
The offending line is:
// Calculate price with markup and round it.
$rounded_price = ( ceil ( ( $price * $multiplier ) / $nearest ) * $nearest ) - $minus;
Can you help me figure out how to fix the error notice?
--
Total script:
function round_price_with_limits( $price = null, $multiplier = 9.3, $nearest = 10, $minus = 0.05, $map = 0, $msrp = 9999999999) {
// Ensure a price was provided.
if ( !empty( $price ) ) {
// Calculate price with markup and round it.
$rounded_price = ( ceil ( ( $price * $multiplier ) / $nearest ) * $nearest ) - $minus;
// If price is less than minimum, return minimum.
if($rounded_price < $map){
return $map;
}
// If price is greater than maximum, return maximum.
elseif($rounded_price > $msrp){
return $msrp;
} else {
// Return price otherwise.
return $rounded_price;
}
}
}

php - how to calculate percentage with scale different from 0-100?

I want to check how percent is $current on the scale from $minimum to $maximum
$minimum = 0.5
$maximum = 5.5
$current = 2.5
How can I do that in PHP?
You would do that in PHP the same way you would do it in any other language or even if you write that calculation by hand.
Because minimum can be > 0 in your case, we subtract minimum from all values to make it easier in calculation. There's probably a faster way to do the maths behind that, however thats an algebra level that I cannot do
public function getPercentageValue($maximum, $minimum, $value) {
$tempMax = $maximum - $minimum;
$tempValue = $value - $minimum;
return $tempValue / $tempMax;
}
Now if we take your values into consideration when we call getPercentageValue()
we will get an answer of 0,4
$result = getPercentageValue(5.5, 0.5, 2.5);
echo $result; // 0.4
If you want the value not as float but as 40 for 40% you would change the function so that it multiplies the answer by 100
public function getPercentageValue($maximum, $minimum, $value) {
$tempMax = $maximum - $minimum;
$tempValue = $value - $minimum;
return ($tempValue / $tempMax) * 100;
}

PHP: Price range / average calculation based on historical data

I'm building a little app that analyze ebay historical prices of sold items
and for some keywords/items the range is very wide because the search is too broad or simply wrong, infected by item not properly related
eg.
search prices for iphone the results include either the phone, but
also the charger and accessories/unrelated items which adulterate the prices data...
so i have a range that goes form $5 fro a charger and 500$ for an
iphone
so, given that I will try to improve the search on my side, i'm wondering if there is math calculation to exclude the outliers
say I have
$1200
$549
$399
$519
$9
$599
$549
$9
$499
$399
$519
$99
$5
$5
how to i get the price range to be $300-$600 instead of $10-$800 or so...
her ebelow the current php im using...not sure if is the best
function remove_outliers($dataset, $magnitude = 1)
{
$count = count($dataset);
$mean = array_sum($dataset) / $count; // Calculate the mean
$deviation = sqrt(array_sum(array_map("sd_square", $dataset, array_fill(0, $count, $mean))) / $count) * $magnitude; // Calculate standard deviation and times by magnitude
return array_filter($dataset, function ($x) use ($mean, $deviation) {return ($x <= $mean + $deviation && $x >= $mean - $deviation);}); // Return filtered array of values that lie within $mean +- $deviation.
}
function sd_square($x, $mean)
{
return pow($x - $mean, 2);
}
function calculate_median($arr)
{
sort($arr);
$count = count($arr);
$middleval = floor(($count - 1) / 2);
if ($count % 2) {
$median = $arr[$middleval];
} else {
$low = $arr[$middleval];
$high = $arr[$middleval + 1];
$median = (($low + $high) / 2);
}
return $median;
}
$prices = remove_outliers($prices); //$prices is the array with all the prices stored
$trend = calculate_median($prices);
$trend = round(($trend));
$min = round(min($prices));
$max = round(max($prices));
I find this function useful. The $cleaness variable will give granularity
/**
* Returns an average value from a dirt list of numbers.
*
* #require
*
* $numbers = an array of numbers
* $cleaness = a percentage value
*
* #return integer
* an average value from a cleaner list.
*/
public function CleanAverage ( $numbers, $cleaness ) {
// A
$extremes_to_remove = floor(count($numbers)/100*$cleaness);
if ($extremes_to_remove < 2) {$extremes_to_remove = 2;}
// B
sort ($numbers) ;
// C
//remove $extremes from top
for ($i = 0; $i < ($extremes_to_remove/2); $i++) {
array_pop($numbers);
}
// D
// revers order
rsort($numbers);
// E
//remove $extremes from top
for ( $i = 0; $i < ($extremes_to_remove/2); $i++ ) {
array_pop($numbers);
}
// F
// average
$average = array_sum($numbers)/count($numbers);
return $average;
}

Displaying min() value in array

I want to display 10 highest figure and 10 lowest figure in a multi-dimensional array.
I have figured out way to display the maximum figure using max(), but when I use min(), the least less value get looped again and again for 10 times e.g 2.
How can I reuse my code to display minimum value in my array?
$totalCustomer = count($customerArray);
$postion = 0;
foreach ($customerArray as $custom) {
$postion = $postion + 1;
if($totalCustomer - $postion < 9){
$top[] = $custom['spend'];
$maxprice = max($top);
echo "Max spend price is ". $maxprice. "<br>";
}
}
#hek2mgl answer is a good one. But you can take advantage of PHP array's indexes to avoid sorting and gaining performance.
$prices = [];
foreach ( $customerArray as $custom )
{
// This approach uses your price as an ordering index, and supposes two decimal points
$index = intval( $custom['spend'] * 100 );
$prices[$index] = $custom['spend'];
}
// Showing lowest 10 prices
$top = array_slice( $prices, 0, 10 );
// Showing top 10 prices
$low = array_slice( array_reverse( $prices ), 0, 10 );
I would use usort:
/* Sort the array the value of 'spend' */
usort($customerArray, function($a, $b) {
if($a['spend'] == $b['spend']) {
return 0;
} else if ($a['spend'] > $b['spend']) {
return -1;
} else {
return 1;
}
});
/* The top 10 elements are now on top of the array */
$top = array_slice($customerArray, 0, 10);
/* If we reverse the array using array_reverse() the
smallest items are on top */
$low = array_slice(array_reverse($customerArray), 0, 10);

Displaying currency values greater than 1000

I'm trying to modify a pseudo-shopping cart (it's array based storing values in user meta and not database) PHP file that wrongly displays currency > 1000 as 0.01
Here's the block I want to change:
public function get_cart_value()
{
$cart = $this->cart;
$prices = array();
$cart = apply_filters('ss_mod_cart_value', $cart);
foreach ($cart['products'] as $product)
{
array_push( $prices, array('price'=>trim($product['price']), 'discount' => trim($product['discount'] )));
}
$total = 0;
foreach($prices as $price)
{
$price = $this->calc_discount($price['price'], $price['discount']);
$price = str_replace('.', '', $price['final_price']);
$total += $price;
}
$total = number_format($total/100, 2);
return $total;
}
The cart button it works on will correctly display the total values of items less than 4 digits, for example:
300 + 500 = 800
but
300 + 500 + 1000 = 800.01 instead of 1,800
I've been trying to change number_format() to make it work but cannot find a solution.
I think by this line
$price = str_replace('.', '', $price['final_price']);
300+500+ "1000";
your numbers like 1,000 are converted to a string and then your total becomes 801.
you have to convert to float in proper way as suggested in this
PHP: unformat money

Categories