0

I am creating a conversion table using PHP and I have to check the user's input against A LOT of scenarios and I started by using if statements but this doesn't seem to be efficient whatsoever and I was hoping for an easier way to go through all the scenarios.

I looked into ternary and switch options but those don't seem to do what I need it to do and I also considered array's (the option I think I need to use)

What I'm trying to do: The user enters in a grade level and scores for a category. Based on the sum of those scores and the grade level, I need to compare them to get two other scores Example code:

if ($grade == 1  && $sumScore <= 5)
 {
   $textscore = 'Beginning';
 }
 if ($grade ==1 && ($sumScore>5 && $sumScore <=8)) 
  {
   $textScore = 'Intermediate';
  }

etc....

There are 13 grades (K-12) and 4 categories I need to go through all with their own "raw scores" to consider to get these other scores. How can I avoid using a ton of If/Else if statements?

Thanks!!

9
  • 1
    at first, show those 13 grades and 4 categories descriptions with their interrelations Commented Apr 23, 2016 at 20:44
  • What kind of logic do you need? Is it always ($grade < X && $sumScore <= Y) or could it be something else? Commented Apr 23, 2016 at 20:46
  • etc... Not very helpful. If you show all your IF code we can see what need to be done and suggest better/other ways of doing it Commented Apr 23, 2016 at 20:46
  • The logic is pretty consistent like the example I provided. They all have their own raw score table that has additional scores that are correlated. And the raw scores can vary depending on the grade level. Commented Apr 23, 2016 at 20:54
  • 1
    You are not providing enough information for a proper answer. It is possible that you can just use a mathematical formula to arrive at the answer, but with only providing two of the many possible scenarios. Commented Apr 23, 2016 at 21:04

3 Answers 3

2

You could use a two-dimensional array that's 13x4. Then you can use a nested for loop to go through each possibility and just have one statement that gets run a bunch of times because of the for loops.

For example, the array might look like this:

$textscores = array (
  1 => array(5 => 'Beginning', 8 => 'Intermediate', ...),
  ...
  3 => array(5 => 'Intermediate', ...),
  ...
);

The nested for loop might look like this:

foreach($textscores as $grade => $scores) {
  foreach($scores as $sumScore => $textScore) {
    if($userGrade == $grade &&  $userSumScore <= $sumScore) {
      $userTextScore = $textScore;
      break 2;
    }
  }
}
Sign up to request clarification or add additional context in comments.

4 Comments

Depending on the grade level, it's different. For example, grade 1 can have a "raw score" of 5 and be "beginning", but for grade 3, a "raw score" of 5 can be "intermediate." That's why I need to know which grade level they are.
Yeah, you have a different row for each grade level. I'll expand the example.
I added an example for loop.
I used this and tweaked the code a bit to match what I already had and it works like a charm! You are simply the best. :D
0

I haven't tested this (sorry), but I think something like this

function getTextScore($grade, $sum) {

    $rules = array( array("grade" => 1, "minSum" => null, "maxSum" => 5, "textScore" => "Beginning"),
                    array("grade" => 1, "minSum" => 6, "maxSum" => 8, "textScore" => "Intermediate" ),

                /* ... */
                );


    for ($ruleIdx=0; $ruleIdx<count($rules); $ruleIdx++) {

        $currentRule = $rules[$ruleIdx];

        if (($currentRule['grade'] == $grade) &&
            ((is_null($currentRule['minSum'])) || ($currentRule['minSum'] <= $sum)) &&
            ((is_null($currentRule['maxSum'])) || ($currentRule['maxSum'] >= $sum))) {
            return $currentRule['textScore'];
        }
    }

    // got to the end without finding a match - need to decide what to do
}

The rules have optional min and max values. It will stop as soon as it finds a match, so the order is important. You will need to decide if no rules are matched. You should be able to just drop extra rules in or change the existing ones without changing the logic.

Comments

0

From your example I would suggest the following

Multidimensional array, but a bit different from the way you construct the array

// Grade => [Text => [Min,Max]]
$textScores = [
    1 => [
        'Beginning'    => [0, 5],
        'Intermediate' => [5, 8],
        'Master'       => [8, 10]
    ],
    2 => [
        'Beginning'    => [0, 7],
        'Intermediate' => [7, 8],
        'Master'       => [8, 10]
    ],
    3 => [
        'Beginning'    => [0, 3],
        'Intermediate' => [3, 6],
        'Master'       => [6, 10]
    ]
];

// Random input to test
$grade    = rand(1, 3);
$sumScore = rand(0, 10);

foreach ($textScores[$grade] as $Text => $MinMax) {

    if ($MinMax[0] <= $sumScore && $MinMax[1] >= $sumScore) {
        $textScore = $Grade;
        break;
    }
}

3 Comments

this is also very useful. I think I might look into this one so I don't have to write out each raw score and their text score.
I actually used this method. This reduces my code a lot. I actually made a another array with the sum values instead of using you min/max method and then just added another foreach loop.
I would like to see that code, seems interesting. I love arrays :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.