Imagine a scenario where monthly rent is 100,000 which is payable at the end of each month.
A tenant then decides to make a payment 350,000 to cater for the current month and those ahead. How do I distribute this amount since I can obviously see here that this amount caters for 3 months and a half month?
Here is what I was trying in PHP but I just can't get the last 50,000 to appear.
$rent = 100000; // rent amount
$amountPaid = 350000; // amount paid by tenant
$length = $amountPaid/$rent; // number of months paid for
for ($c = 1; $c <= $length; $c++)
{
$foreachMonth = $rent;
assignRentFunction($c, $foreachMonth);
}
function assignRentFunction($count, $amt)
{
echo "Month ".$count.': '.$amt."<br>";
}
Steps:
1) Get total months with ceil() function.
2) It will return 4 months. 3 months fully paid and one month paid only 50000.
3) Now, for each loop will add 10000 to total rent paid.
4) if this surpasses the amount paid, get mod which is 50000
$rent = 100000; // rent amount
$amountPaid = 350000; // amount paid by tenant
$length = ceil($amountPaid/$rent); // number of months paid for
$totalRent = 0;
for ($c = 1; $c <= $length; $c++) {
$totalRent += $rent;
$foreachMonth = $rent;
if ($amountPaid < $totalRent) { // Here is the logic, if amount exceeds, use the remaining amount.
$foreachMonth = $amountPaid % $rent;
}
assignRentFunction($c, $foreachMonth);
}
function assignRentFunction($count, $amt) {
echo "Month ".$count.': '.$amt."<br>";
}
**Output:**
Month 1: 100000
Month 2: 100000
Month 3: 100000
Month 4: 50000
$rent= 100000; // rent amount
$amountPaid= 350000; // amount paid by tenant
$length= $amountPaid/$rent; // number of months paid for
for ($c = 1; $c <= ceil($length); $c++)
{
$foreachMonth = 100000;
if($amountPaid>$rent)
{
$rent=$rent;
$amountPaid=$amountPaid-$rent;
}
else
{
$rent=$rent-$amountPaid;
}
assignRentFunction($c, $rent);
}
function assignRentFunction($count, $amt)
{
echo "Month ".$count.': '.$amt."<br>";
}
Since there seems to be a few ways to slice this, I thought I'd throw my hat in the ring also:
for($c = 1; $c<=ceil($amountPaid/$rent); $c++){
assignRentFunction($c, $rent - max(($c * $rent - $amountPaid),0));
}
And now the commented version:
for($month = 1; $month<=ceil($amountPaid/$rent); $month++){
//For each month there is money for rent (using ceil() to account for fractions)
assignRentFunction(
$month,
// The number of the month
$rent
//Show the rent ($rent)
-
//Deduct
max(($month * $rent - $amountPaid),0)
//Any difference if the whole rent for that month hasn't been paid
/**
* This relies on a little hack with the max() function:
* max($var,0) will return 0 if $var is less than 0.
* So we check to see if the sum of rent up to that month ($month * $rent)
* is greater than what was paid ($month * $rent) - $amountPaid.
* If it isn't because it's wrapped in the max,
* the net (negative) number will just be shown as nill.
* If it is, the net positive number will be subtracted
* from the month's rent.
**/
);
}
Change your loop part to
for ($c = 1; $c <= $length; $c++) {
$foreachMonth = $rent;
assignRentFunction($c, $foreachMonth);
}
$fractionalMonth = $length - intval($length);
if ($fractionalMonth)
assignRentFunction($c, $foreachMonth * $fractionalMonth);
Your error was since you're always incrementing $c by one, you wasn't able to get the fractional part for the last month
You can solve your problem like this,
$rent = 100000; // rent amount
$amountPaid = 350000; // amount paid by tenant
$length = ceil($amountPaid / $rent); // number of months paid for
$temp1 = $amountPaid;
for ($c = 1; $c <= $length; $c++) {
if($temp1 < $rent){ // assigning left amount to rent if less than amount left
$rent = $temp1;
}
if($temp1 > $rent){ // checking if amount left is still more than per month rent then minus that rent from pending paid amount
$temp1 = $temp1 - $rent;
}
assignRentFunction($c, $rent);
}
function assignRentFunction($count, $amt)
{
echo "Month " . $count . ': ' . $amt . "<br>";
}
Demo.
Related
i'm trying to increase a variable value depending on the other variable value for example:
i have a variable called $totalhousesleft...
i want to set a price depending on how many $totalhousesleft i have...
everytime the totalhousesleft is down by 10, i want to increase the variable $currentprice by 1.
the starting value of $totalhouses left is 8000 and every time it goes down by 10, i set the $currentprice +1... the starting value of current price is 9...
something like:
If ($totalhousesleft >= 8000) {$currentprice = 9; $sellingprice = 8;}
If ($totalhousesleft >= 7990) {$currentprice = 10; $sellingprice = 9;}
If ($totalhousesleft >= 7980) {$currentprice = 11; $sellingprice = 10;}
If ($totalhousesleft >= 7970) {$currentprice = 12; $sellingprice = 11;}
ALL THE WAY DOWN UNTIL HOUSES LEFT IS 1. If someone can please show me a loop or a shorter code i would really appreciate it!
#elias-soares answer is close, but is missing ceil...and an explanation.
foreach ( [8000, 7995, 7990, 7985, 7980, 7975, 7970, 7965] as $totalhousesleft ) {
$currentprice = 9 + ((ceil(800 - ((min(8000, $totalhousesleft)) / 10))) * 1);
$sellingprice = $currentprice - 1;
}
Try it here: https://onlinephp.io/c/68196
Let's break down how to get $currentprice:
//$currentprice = ceil(9 + (800 - (min(8000, $totalhousesleft) / 10)));
// get the lesser of 8000, or $totalhousesleft
// in other words, 8000 is the maximum number to calculate
$totalhousesleft = min(8000, $totalhousesleft);
// divide total houses left into number of tenth units
$tenth = $totalhousesleft / 10;
// since the price increases when the number of tenth units decreases,
// the unit factor is the difference between the max possible tenths
// and tenths of the current total houses left
$tenthunit = 800 - $tenth;
// tenth unit is fractional for values not evenly divisible by 10,
// so round up
$tenthroundup = ceil($tenthunit);
// multiply the number of tenth units with the price per unit
$pricepertenth = $tenthroundup * 1; // 1 currency per tenth unit
// add the price per tenth cost to the base cost (9 currency)
$currentprice = 9 + $pricepertenth;
Bonus: this can be implemented in a function:
function getPrices ($totalhousesleft, $baseprice = 9, $discount = 1, $priceperunit = 1, $maxtotal = 8000, $units = 10) {
$currentprice = $baseprice + ((ceil(($maxtotal / $units) - ((min($maxtotal, $totalhousesleft)) / $units))) * $priceperunit);
return [$currentprice, $currentprice - $discount];
}
foreach ( [8000, 7995, 7990, 7985, 7980, 7975, 7970, 7965] as $totalhousesleft ) {
list($currentprice, $sellingprice) = getPrices($totalhousesleft);
}
Try it here: https://onlinephp.io/c/2672b
A for or while loop could be used for this. I'd use for:
$iteration = 0;
for($x = 8000; $x > 0; $x = $x - 10){
if(empty($iteration)) {
$iteration = $x/1000;
}
if ($totalhousesleft >= $x) {
$currentprice = $iteration;
$sellingprice = $currentprice + 1;
break;
}
$iteration++;
}
if(empty($currentprice)){
$currentprice = $iteration;
$sellingprice = $currentprice + 1;
}
This iterates over until a match is found then breaks out of the looping. The prices are based on the iteration it is in.
Demo link: https://3v4l.org/Mm432 (updated for edge cases 0-9)
You can use Math.
$currentprice = 9 + (800 - (min(8000,$totalhousesleft)/10));
$sellingprice = $currentprice - 1;
Is there a fast way to get a decreasing rental cost based on the number of days?
For example:
If I rent a car for 1day, the cost is 100$
If I rent a car for 2days, the cost is 100$ + 70$ = 170$
If I rent a car for 3days, the cost is 100$ + 70$ + 50$ = 220$
If I rent a car for 4days, the cost is 100$ + 70$ + 50$ + 50$ = 270$
If I rent a car for 5days, the cost is 100$ + 70$ + 50$ + 50$ + 50$ = 320$
So I need a fast way to get the total cost based on the number of days.
For example:
function getcost(days){
...
return $cost;
}
echo getcost(1); // it show 100$
echo getcost(3); // it show 220$
// and so on...
Assuming that from day three all consecutive days cost 50$:
function getcost(int $days) {
return ($days > 1) ? (($days - 2) * 50 + 170) : (($days == 1) ? 100 : 0);
}
function getcost(days){
$cost=0;
for($idx=1;$idx<=$days;$idx++)
{
switch($idx)
{
case 1:
$cost+=100;
break;
case 2:
$cost+=70;
break;
default:
$cost+=50;
break;
}
}
return $cost;
}
$price = $days * 50 + ($days > 1 ? 70 : 20);
If you want to you can put it in a function.
You can try like this way-
<?php
function getcost($days){
$array=['base' => 100, 'for_2nd' => 70, 'after_2nd' => 50];
if($days==1){
$cost = $array['base'] * $days;
}else if($days>=2){
$cost = $array['base'] + ($days == 2 ? $array['for_2nd'] : $array['for_2nd'] + ($days - 2) * $array['after_2nd']);
}
return $cost.'$';
}
echo getcost(1); // it show 100$
echo getcost(2); // it show 170$
echo getcost(3); // it show 220$
echo getcost(4); // it show 270$
echo getcost(5); // it show 320$
?>
DEMO: https://3v4l.org/h9tF5
If your day rate is based on number of days, then to allow you to have a dynamic rate (perhaps different type of car etc.) then it's best to have some form of array which is passed into the function. The function then uses this and adds the days up till it the rates run out and adds any remaining days according to the last rate...
// Cost for each day
$costs = [100, 70, 50];
function getcost( $costs, $days){
$totalCost = 0;
foreach ( $costs as $dayCost ) {
// Add each cost
$totalCost += $dayCost;
// Decrement number of days left and exit if reached 0
if ( --$days == 0 ) {
break;
}
}
// If remaining days - add last day cost * number of days
if ($days > 0 ) {
$totalCost += ($dayCost*$days);
}
return $totalCost;
}
echo getcost($costs, 1); // it show 100$
echo getcost($costs, 3); // it show 220$
echo getcost($costs, 5); // it show 320$
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;
}
OK, I've had the same problem for a few weeks now and cant perfect it.
Aim
To build a regular deposit savings account system where it prints out the total balance at the current time.
Problem
The current equation I have:
If the interest is 6% with the user paying in 200 a month with compound being each month the balance would be after 6 months 1,220.61
I am getting 1217.13
I have tested different lengths of time and many different online calculators, my calculation is always less.
My code
<h2>Total Balance To Date</h2>
<?php
$p = 0; // Starting amount
$i = 0.06; // Interest rate
$c = 12; // compound frequency set to monthly
$n = 6/12; // Current time invested set to 6 months
$r = 200; // Monthly investment is 200
$x = $i / $c;
$y = pow((1 + $x), ($n * $c));
if($p!=0)
{
$vf = $p * $y + ($r * ($y - 1) / $x);
}
else
{
$vf = 1 + $y + ($r * ($y - 1) / $x);
}
?>
<p>£<?php echo round($vf, 2, PHP_ROUND_HALF_UP); ?></p> // Comes out at 1217.13
LINK to sandbox https://3v4l.org/9X7OH
Setting
q = pow(1.06 , 1.0/12) = 1.0048675505653430
and computing
200*(q+q^2+q^3+q^4+q^5+q^6) = 200*q*(q^6-1)/(q-1)
gives the result
1220.61037336530790
which is obviously what the online calculators worked with. It is slightly wrong, as for the nominal interest rate, the monthly compound factor should be
q = 1 + 0.06/12 = 1.005
resulting in a balance after 6 months of
1221.1758776293781
As you see, you got the formula almost right, it should be
$vf = $p * $y + ($r * (1 + $x) * ($y - 1) / $x);
since the rate is deposited at the start of the month, so the first rate gets compounded as r*(1+x)^6 and the last rate as r*(1+x). However, the second formula in the else branch does not make sense at all.
I have a requirement where users are forced to choose the multiple of (n) quantity of a product.
The (n) value is set with each product that can be any number.
customer can only purchase the quantity of product in the multiple of (n) quantity set with product.
Suppose if (n) is 5 and user entered quantity as 4 and says Add to Cart. I have to add quantity of that product as 5 automatically.
and if user entered 6 as quantity then I have to add the 10 quantity of that product.
How I go about that?
I am not getting what logic should be applied here.
$entered_quantity = 6;
$suppose_n = 5;
$quantity = ceil($entered_quantity / $suppose_n) * $suppose_n;
echo $quantity;
prints 10
that's not php specific;
what you wonna do is to compute.
ceiling(q / n) * n
where q is the user's quantity,
n is the multiplicity
You could try getting the remainder of the number when dividing by the given n
e.g.:
$n = 5;
$amount = 6; // This would be the input, so replace the 6 with a $_POST/$_GET/etc.
$batches = floor($amount / $n);
$rest = $amount % $n;
if ($rest > 0) {
$batches += 1;
// You could give the user feedback here that they didn't put in a full multiple of $n
}
// $batches now contains the right amount of batches, so to get the total:
$total = $batches * $n;
Ofcourse this can be condensed a lot, but this might give a better overview of what happens :).
Try the below function.
function getNextMultipleOfFive($n) {
$tmp=explode('.',($n/5));
if($tmp[1]) {
return ($tmp[0]+1)*5;
}
return $tmp[0]*5;
}
With a do...while loop:
$q = 6; // quantity by user input
$n = 5; // per purchace amount
$i = 0;
if ($q > 0)
{
do
{
$i += $n;
}
while ($i <= $q);
}
echo $i; // 10
Note: not very effective if $q >> $n