JK36
JK36

Reputation: 853

write better looking and less verbose code

Ive got the following snippet of code, which works and does what I need it to do. The only problem is I think its a little 'verbose' and can do with some optimising. Can someone help me reduce the repetitiveness if at all possible. Most of the code is very similar...

Many thanks

<?php 

// condition = Less Than; More Than; Between
// noofweeks = this is the number of weeks chosen by the user

function fmsSupplements($condition, $conditionWeeks, $noofweeks, $weekno, $weekStartno,      $weekEndno, $basicprice, $supplementAmnt, $supplementType) {

if ($condition== "Between") {
// I need to get the start and end values as the data in this parameter should look like 1-17 
$betweenArray = explode('-',$conditionWeeks);
$startWeek = $betweenArray[0];
$endWeek = $betweenArray[1];
}


if(($condition == "Less Than") && ($noofweeks < $conditionWeeks) && ($supplementType ==    'Subtract') && ($weekno >= $weekStartno && $weekno <= $weekEndno) )  { return $basicprice -  $supplementAmnt; }

elseif(($condition == "Less Than") && ($noofweeks < $conditionWeeks) && ($supplementType == 'Add') && ($weekno >= $weekStartno && $weekno <= $weekEndno) )  { return $basicprice + $supplementAmnt; }

elseif(($condition == "More Than") && ($noofweeks > $conditionWeeks) && ($supplementType == 'Subtract') && ($weekno >= $weekStartno && $weekno <= $weekEndno) )  { return $basicprice - $supplementAmnt; }

elseif(($condition == "More Than") && ($noofweeks > $conditionWeeks) && ($supplementType == 'Add') && ($weekno >= $weekStartno && $weekno <= $weekEndno) )  { return $basicprice + $supplementAmnt; }    

elseif(($condition == "Between") && ($noofweeks >= $startWeek && $noofweeks <= $endWeek) && ($supplementType == 'Add') && ($weekno >= $weekStartno && $weekno <= $weekEndno) )  { return $basicprice + $supplementAmnt; }

elseif(($condition == "Between") && ($noofweeks >= $startWeek && $noofweeks <= $endWeek) && ($supplementType == 'Substract') && ($weekno >= $weekStartno && $weekno <= $weekEndno) )  { return $basicprice - $supplementAmnt; }   

//if no conditions match, just return the unaltered basic price back

else { return $basicprice ;}

;} ?>

Upvotes: 1

Views: 94

Answers (1)

GolezTrol
GolezTrol

Reputation: 116110

That one list of ifs can be written as a nested if.

The most important changes:

  1. ($weekno >= $weekStartno && $weekno <= $weekEndno) is part of all conditions, so it is in the outer if.
  2. The three varying conditions, that match with the given condition string are put in 1 if using or (||).
  3. The inner if is also singlified. Add results in an addition. Subtract in a subtraction.

All comes down to repeating the conditions as less as possible, although you should keep in mind that the structure should still be clear. In some cases, it may be easier your way.

<?php 

// condition = Less Than; More Than; Between
// noofweeks = this is the number of weeks chosen by the user

function fmsSupplements($condition, $conditionWeeks, $noofweeks, $weekno, $weekStartno, $weekEndno, $basicprice, $supplementAmnt, $supplementType) {
  if ($condition == "Between") {
    // I need to get the start and end values as the data in this parameter should look like 1-17 
    $betweenArray = explode('-',$conditionWeeks);
    $startWeek = $betweenArray[0];
    $endWeek = $betweenArray[1];
  }

  if ($weekno >= $weekStartno && $weekno <= $weekEndno)
  {
    if (($condition == 'Less Than' && $noofweeks < $conditionWeeks) ||
        ($condition == 'More Than' && $noofweeks > $conditionWeeks) ||
        ($condition == 'Between' && $noofweeks >= $startWeek && $noofweeks <= $endWeek))
    {
      // You can use a 'switch' as well, instead of if...elseif.
      if ($supplementType == 'Subtract') {
        return $basicprice - $supplementAmnt;
      } elseif ($supplementType == 'Add' {
        return $basicprice + $supplementAmnt;
      }
    }
  }
  return $basicprice;
} ?>

In a different setup, I put the intermediate results in separate variables, which I think makes it even more readable. I added a little more comments here, explaining the decisions:

function fmsSupplements($condition, $conditionWeeks, $noofweeks, $weekno, $weekStartno, $weekEndno, $basicprice, $supplementAmnt, $supplementType) {

  // Create two 'helper' booleans to make the if condition easier.
  $weekInRange = ($weekno >= $weekStartno && $weekno <= $weekEndno);
  $noOfWeeksInRange = 
      ($condition == 'Less Than' && $noofweeks < $conditionWeeks) ||
      ($condition == 'More Than' && $noofweeks > $conditionWeeks);

  // Alternatively, you can break the single line above up in multiple 
  // lines, which makes debugging easier:
  //$noOfWeeksInRange = ($condition == 'Less Than' && $noofweeks < $conditionWeeks);
  //$noOfWeeksInRange |= ($condition == 'More Than' && $noofweeks > $conditionWeeks);

  if ($condition == "Between") {
    // I need to get the start and end values as the data in this parameter should look like 1-17 
    $betweenArray = explode('-',$conditionWeeks);
    $startWeek = $betweenArray[0];
    $endWeek = $betweenArray[1];
    // Overwrite this variable with the condition that goes with 'Between'.
    // We're already in that if, so we don't need to check 'Condition' again..
    // You could use betweenArray[0] and [1] in the condition below, but using
    // the variables $startWeek and $endWeek does make it more readable.
    $noOfWeeksInRange = ($noofweeks >= $startWeek && $noofweeks <= $endWeek);
  }

  // And not this 'if' is even more readable.
  if ($weeksInRange && $noOfWeeksInRange)
  {
      // You can use a 'switch' as well, instead of if...elseif.
      if ($supplementType == 'Subtract') {
        return $basicprice - $supplementAmnt;
      } elseif ($supplementType == 'Add' {
        return $basicprice + $supplementAmnt;
      }
  }
  return $basicprice;
} ?>

Upvotes: 2

Related Questions