ok, I"m stuck: recursive function restting vars and not returning when expected

ok, I"m stuck: recursive function restting vars and not returning when expected

am 07.09.2007 11:20:25 von pos

arrrrrg:
Condo for rent has 3 price tiers (for different times of the year):
value
regular
premium

For every 7 nites they stay, they get 1 free, and that free one should be the
cheapest night (1 value nite, 6 premium nites, they should get the value nite
free)

main script:
$_POST['vnites'] = 2; $_POST['rnites'] = 0; $_POST['pnites']=12;

$totalnites = $_POST['vnites'] + $_POST['rnites'] + $_POST['pnites'];
echo 'totalnites= '. $totalnites.'

';
$postNights = array('vnites' => $_POST['vnites'] , 'rnites' => $_POST['rnites']
, 'pnites' => $_POST['pnites']);
if (($totalnites > 6)AND($totalnites < 14)){$mult = 1;}
if (($totalnites > 13)AND($totalnites < 21)){$mult = 2;}
if (($totalnites > 20)AND($totalnites < 28)){$mult = 3;}
if (($totalnites > 27)AND($totalnites < 35)){$mult = 4;}
if (($totalnites > 34)AND($totalnites < 42)){$mult = 5;}

$temptotalnites = $totalnites;

if ($totalnites > 6){ // call the func:
$discountnites = subtractFreeDays($postNights ,$temptotalnites, $mult);

echo '

after func $discountnites=';
print_r($discountnites);
echo '
';
}

func:
function subtractFreeDays($fpostNights, $ftotalnites, $fmult){
echo 'in func mult: '.$fmult.'
';
echo 'in func $fpostNights[vnites]: '.$fpostNights['vnites'].'
';
echo 'in func $discvnites='.$discNights['vnites']."

";

if ($fmult > 0){

if($fpostNights['vnites'] > 0){//echo'1';
$discNights['vnites'] = $discNights['vnites'] + 1;
echo '$discvnites='.$discNights['vnites']."
";
$fpostNights['vnites'] = $fpostNights['vnites'] - 1;
echo '$fpostNights[vnites]='.$fpostNights['vnites']."

";
}
elseif($fpostNights['rnites'] > 0){
$discNights['rnites'] = $discNights['rnites'] + 1;
$fpostNights['rnites'] = $fpostNights['rnites'] - 1;
}
else{
$discNights['pnites'] = $discNights['pnites'] + 1;
$fpostNights['pnites'] = $fpostNights['pnites'] - 1;
}
//echo 'before minusing fmlut='.$fmult."
";
$fmult = $fmult - 1;
if ($fmult >= 1){
echo 'before recurse $fmult= '.$fmult.'
';
subtractFreeDays($fpostNights, $ftotalnites, $fmult);
}else{
echo '
returning:';
print_r($discNights);
echo '
';
return $discNights;
}
}
//shouldnt get here
return array('shouldnt','get','here');
}
?>

-- This works on less than 14 days.
Over 14 days, it breaks:
1. $discNights['vnites'] is being reset to nothing every recursion, what gives?
2. I get to
echo '
returning:';
print_r($discNights);
echo '
';
return $discNights;
and it *does* print_r (wrong value, see #1), but it doesnt seem to return, and
that really chaps my hide. It will keep going, eventually returning the
array('shouldnt','get','here').

Thanks for your time,

Re: ok, I"m stuck: recursive function restting vars and not returning when expected

am 07.09.2007 15:41:29 von Sjoerd

On Sep 7, 11:20 am, J. Frank Parnell wrote:
> Condo for rent has 3 price tiers (for different times of the year):
If this is an application for real use, consider how likely it would
be that someone decides that there will be a fourth price tier, and
how easy your application can adapt to that.

> For every 7 nites they stay, they get 1 free, and that free one should be the
> cheapest night (1 value nite, 6 premium nites, they should get the value nite
> free)
If nites is how you spell nights, it's fine with me. If another
English programmer will work on your code, (s)he will make mistakes
very soon. However, if you are using both "nights" and "nites", as you
do, you are asking for bugs. Even if you are the only one working on
the program.

> $totalnites = $_POST['vnites'] + $_POST['rnites'] + $_POST['pnites'];
You can use array_sum($postNights) instead.

> if (($totalnites > 6)AND($totalnites < 14)){$mult = 1;}
> if (($totalnites > 13)AND($totalnites < 21)){$mult = 2;}
> if (($totalnites > 20)AND($totalnites < 28)){$mult = 3;}
> if (($totalnites > 27)AND($totalnites < 35)){$mult = 4;}
> if (($totalnites > 34)AND($totalnites < 42)){$mult = 5;}
Use math instead of this. It's simpler and it works on any number of
nights. Something like
$mult = floor($totalnites / 7);

> $temptotalnites = $totalnites;
Anything with "temp" is typically a bad variable name.

> if ($totalnites > 6){ // call the func:
Always call the function, no matter how many nights are booked. This
allows easier change if it is decided that every third night is free.

I have something here which does not use recursion. This is not a
recursive problem anyway:


$_POST['vnites'] = 2; $_POST['rnites'] = 0; $_POST['pnites']=12;

$types = array('vnites', 'rnites', 'pnites');

foreach ($types as $type) {
$postNights[$type] = $_POST[$type];
}

$totalNights = 0;
foreach ($postNights as $type => $nights) {
$totalNights += $nights;
}

$freeNights = floor($totalNights/7);
for ($i = 0; $i < $freeNights; $i++) {
foreach ($types as $type) {
if ($postNights[$type] > 0) {
$postNights[$type] --;
$postNights['freenites'] ++;
// do not consider other types, continue with for loop
continue 2;
}
}
}

print_r($postNights);

?>

Re: ok, I"m stuck: recursive function restting vars and not returning when expected

am 07.09.2007 16:34:32 von Steve

> For every 7 nites they stay, they get 1 free, and that free one should be
> the
> cheapest night (1 value nite, 6 premium nites, they should get the value
> nite
> free)

i'm assuming they must be consecutive nights and not cumulative. why are you
going through all of that rig-a-ma-role for a straight algorhytmic
calculation? who cares what night it is? all you should need to look at is
how many times should you "comp" the lowest rated night...based on your
info. i have no earthly idea why you're splitting up each night as vnites,
rnites, and pnites.

let's assume every monday is a discounted night, while tuesday through
thursday is a standard rate, and friday through sunday is premium pricing.
it is as simple as this:

$nights = 14;
$discounted = $nights / 7;
$nightBilled = array(
'2007-09-03' => 100;
'2007-09-04' => 200;
'2007-09-05' => 200;
'2007-09-06' => 200;
'2007-09-07' => 200;
'2007-09-08' => 300;
'2007-09-09' => 300;
'2007-09-10' => 100;
'2007-09-11' => 200;
'2007-09-12' => 200;
'2007-09-13' => 200;
'2007-09-14' => 200;
'2007-09-15' => 300;
'2007-09-16' => 300;
);
$discount = array();
foreach ($nightBilled as $date => $price)
{
if (!$discounted){ break; }
$dateInfo = getdate($date);
if ($dateInfo['wday'] == 0)
{
$discount[$date] = $price;
$discounted--;
}
}
print_r($discount, true);


you could do this same thing just knowing the arrival date and the number of
nights they stayed.
there are several "business" problems i see with your method of discounting
(it doesn't benefit the business as much as it could nor is your code
extendable when you figure out why).

as for the code you want fixed...i'm telling you why it doesn't do what you
want. i submit the above as a better use of cpu cycles and maintenance.