Make an if statement shorter - php

Hay all, I have an if statement. How could I make this as short as possible?
if ( $a < 0 ){
if( $a > -2 ){
echo "standard";
}elseif( $a <= -2 && $a > -4 ){
echo "thin";
}elseif( $a <= -4 ){
echo "super thin";
}
}else{
if( $a < 2 ){
echo "standard";
}
if( $a > 2.01 && $a <= 4){
echo "thin";
}
if( $a > 4.01 && $a <= 8.00){
echo "super thin";
}
}
EDIT: basically $a will be any number (positive or negative) and we match it like this.
If the value is
+0.00 to +/- 2.00 – Standard
+/- 2.25 to +/- 4.00 – Thin
+/- 4.25 to +/- 8.00 – Super Thin
Extra marks for anyone who knows what this might be used for :)

You can shorten it by using the absolute value:
$b = abs($a);
if ($b <= 2) {
echo "standard";
} else if ($b <= 4) {
echo "thin";
} else if ($b <= 8) {
echo "super thin";
}

What about this:
$a = abs($a);
if($a<=2) echo "standard";
elseif($a<=4) echo "thin";
elseif($a<=8) echo "super thin";

This is about as simple as it gets:
<?php
$b = abs($a);
$ranges = array(
'standard' => 2,
'thin' => 4,
'super thin' => 8
);
foreach($ranges as $range=>$max) {
$size = $range;
if($b > $max) continue;
break;
}
?>

Or you can keep the actual ranges, allow the range ends to be different (rather than just the absolute values), and allow easy inclusion of additional ranges:
$ranges = array(
'standard' => array(-2, 2),
'thin' => array(-4, 4),
'super thin' => array(null,8),
);
foreach($ranges as $key => $range) {
if((is_null($range[0]) || $a => $range[0]) && (is_null($range[1]) || $a <= $range[1])) {
echo $key;
break;
}
}
The first matching range in the list is the one that qualifies.

if ( $a < 0 )
{
if( $a > -2 ) echo "standard";
elseif($a > -4) echo "thin";
else echo "super thin";
}
else
{
if( $a < 2 ) echo "standard";
elseif( $a > 2.01 && $a <= 4) echo "thin";
elseif( $a > 4.01 && $a <= 8.00) echo "super thin";
}

Its always better to use switch rather than else if! It makes the code cleaner and extensible.
switch($a) {
case (-2 < $a):
case ($a < 2):
$r = 'Standard';
break;
case ( 2.25 > $a):
case (-2.25 < $a):
case ($a < 4):
case ($a > -4):
$r = 'Thin';
break;
case ( 4.25 > $a):
case (-4.25 < $a):
case ($a < 8):
case ($a > -8):
$r = 'Super Thin';
break;
default:
$r = 'Out of range';
}
echo $r;
The case expression may be any
expression that evaluates to a simple
type, that is, integer or
floating-point numbers and strings.
Arrays or objects cannot be used here
unless they are dereferenced to a
simple type.
Taken from the documentation at http://us3.php.net/manual/en/control-structures.switch.php

Related

Using four level If Else syntax and percentage

I got some stuck here with my jobs here I got some test like this:
Illustration :
There are 4 edges which have their own tax rate:
From Rp 0 to Rp 50,000,000 the tax rate is 5%.
From Rp 50,000,000 to Rp 250,000,000 the tax rate is 15%.
From Rp 250,000,000 to Rp 500,000,000 the tax rate is 25%.
Above 500,000,000 the tax rate is 30%.
and heres my Code :
<?php
$a = //Input for Variable
$b = 5*$a/100 ;
$c = 15*$a/100 ;
$d = 25*$a/100 ;
$e = 30*$a/100 ;
if($a == o and =< 50000000){
echo $b ;
}
elseif($a => 50000000 and =< 250000000){
echo $c ;
}
elseif($a => 250000000 and =<500000000){
echo $d ;
}
else{
echo $e ;
}
?>
But I got some error when after I fill Value for Variable $a.
There are few minor changes that you've to do
- Missing variable in each if condition
- Instead of o take 0
- Always put the = sign last like >= or <= or !=
- Extra :- Optimize the code for better performance (take less variable)
<?php
$a = 50000000;
if($a == 0 and $a <= 50000000)
$total = 5*$a/100;
else if($a >= 50000000 and $a <= 250000000)
$total = 15*$a/100;
else if($a >= 250000000 and $a <= 500000000)
$total = 25*$a/100;
else
$total = 30*$a/100;
echo $total;
?>
Try the below code:
<?php
$a = //Input for Variable
$b = 5*$a/100 ;
$c = 15*$a/100 ;
$d = 25*$a/100 ;
$e = 30*$a/100 ;
if($a == 0 && $a <= 50000000){
echo $b ;
} elseif($a == "Sun"){
echo "Have a nice Sunday!";
}
elseif($a >= 50000000 && $a <= 250000000){
echo $c ;
}
elseif($a >= 250000000 && $a <= 500000000){
echo $d ;
}
else{
echo $e ;
}
?>

converting hexadecimal to decimal php

I have to convert hexadecimal to decimal with PHP (without using hexdec) for my homework, but my code does not convert properly.
For example, when I use the function HexToDez ("1F4");, the answer should be 500, not 1.
Why is it not working?
the code
<?php
function Replace ($i)
{
switch (strToLower ($i))
{
case "a" : return 10;
case "b" : return 11;
case "c" : return 12;
case "d" : return 13;
case "e" : return 14;
case "f" : return 15;
default : return $i;
}
}
function HexToDez($i) # 1F4
{
$input=$i;
$num=strlen ($input) ;
$pos=0;
$output="";
$hochzahl="";
while($pos<$num)
{
$mid = substr ($input, $pos, 1);
$pos++;
return $end=Replace ($mid);
}
while ($end != 0){
$zahl = $input%10;
$output += $zahl*pow(16, $hochzahl);
$end = $end/10;
$hochzahl++;
}
echo $output;
}
?>
here is "classic" algorithm for you to consider, check the comments:
function HexToDez($s) {
$output = 0;
for ($i=0; $i<strlen($s); $i++) {
$c = $s[$i]; // you don't need substr to get 1 symbol from string
if ( ($c >= '0') && ($c <= '9') )
$output = $output*16 + ord($c) - ord('0'); // two things: 1. multiple by 16 2. convert digit character to integer
elseif ( ($c >= 'A') && ($c <= 'F') ) // care about upper case
$output = $output*16 + ord($s[$i]) - ord('A') + 10; // note that we're adding 10
elseif ( ($c >= 'a') && ($c <= 'f') ) // care about lower case
$output = $output*16 + ord($c) - ord('a') + 10;
}
return $output;
}
echo HexToDez("1F4"); // outputs 500
also, you can use intval function to do the same, just convert your number into hex representation, like 0x###
function HexToDez($s) {
return intval('0x'.$s, 16);
}

How to test if $a is divisible by $b when $b is larger than $a

I'm trying to work out if one string, $a, is divisible by another, $b.
All of the examples I can find tell me to use modulus, e.g.:
if(($a %$b) == 0) : echo "Is dividible" ; endif;
However, because modulus returns the remainder of the calculation, this doesn't work if $b is larger than $a, because there's still no remainder.
How do I check divisibility where $b is sometimes (but not always) larger than $a?
why don't you do this as a function:
function isDivisible($smaller,$bigger){
//handle division by zero, and hmm.. let's cover negative numbers too
if($smaller<=0) return false;
if($smaller>$bigger) return false;
return !($bigger % $smaller);
}
The negation ! should be a working and elegant way to handle it.
How about:
echo ( ($a < $b) && (($a % $b) == 0) ) ? "Is dividible" : "Is not divisable" ;
if($a==$b)
{echo "divisible a and b are equal";
}
else if($a>$b){
if(($a %$b) == 0) : echo "Is dividible" ; endif;
}
else{
echo "\$b is either large or equal to \$a";
}
Try this it should work:
$a = 7;
$b = 14;
//echo ( ($a > $b) && ( ($a % $b) == 0) ) ? "is divisible":"no divisible";
echo ( ($a < $b) && (($b % $a) == 0) ) ? "Is dividible" : "Is not divisable" ;
You can use ternary operator as example given below
(($a%$b)==0)?echo "Is divisible": echo "not divisible";

PHP Conditional > how to know what didn't match?

if i have statement:
$a = 1;
$b = 2;
$c = 3;
if($a == 1 && $b == 2 && $c == 3)
{
echo 'correct';
}
else
{
echo 'what variable's weren't matched';
}
Is there any way of knowing what didn't watch instead of writing everything separately?
Cheers!
No. Your expression was turned into a boolean, so apart from checking the equality(s) again you cannot find out which triggered the "false".
You need to test each individually, but you could do something like this:
$a = 1;
$b = 2;
$c = 3;
$a_matched = $a == 1;
$b_matched = $b == 1;
$c_matched = $c == 1;
if($a_matched && $b_matched && $c_matched)
{
echo 'correct';
}
else
{
if (!$a_matched) echo 'a did not match!';
if (!$b_matched) echo 'b did not match!';
if (!$c_matched) echo 'c did not match!';
}
but that's less clear than just:
$a = 1;
$b = 2;
$c = 3;
if($a == 1 && $b == 2 && $c == 3)
{
echo 'correct';
}
else
{
if (!$a == 1) echo 'a did not match!';
if (!$b == 2) echo 'c did not match!';
if (!$c == 3) echo 'b did not match!';
}
Actually, heh, I take back my comment. You can rely on the boolean short-circuiting to set a variable indicating the last part of the conditional which was true:
if (($x = 'a') && $a == 1 && ($x = 'b') && $b == 2 && ($x = 'c') && $c == 3) {
echo "correct\n";
} else {
echo "$x is wrong\n";
}
Note, I would never write this in production code because it's goofy and very hard to understand what's supposed to be going on. But fun to fiddle with, at least.
Nope! That's not possible. You can make life a lot simpler by using arrays, though:
$results = array(1, 2, 4);
$expected = array(1, 2, 3);
$count = count($results);
$wrong = array();
for($i = 0; $i < $count; $i++) {
if($results[$i] !== $expected[$i]) {
$wrong[] = $i;
}
}
if(count($wrong) > 0) {
echo "There were wrong ones. They were at positions: " . implode(', ', $wrong);
} else {
echo "All good!";
}
For example.

Faster way to check if integer is in any of ranges?

I wonder if there is another way to shorten this ? Here is the example im looking for to do same thing just shorter.
if($c <= 100){
echo 'A';
}elseif($c <= 200 && $c > 100){
echo 'B';
}elseif($c <= 300 && $c > 200){
echo 'C';
}elseif($c <= 400 && $c > 300){
echo 'D';
}elseif($c <= 500 && $c > 400){
echo 'E';
}elseif($c <= 600 && $c > 500){
echo 'F';
}elseif($c <= 700 && $c > 600){
echo 'Z';
}elseif($c <= 800 && $c > 700){
echo 'H';
}elseif($c <= 900 && $c > 800){
echo 'I';
}elseif($c < 1000 && $c > 900){
echo 'K';
}elseif($c <= 1100 && $c > 1000){
echo 'L';
}elseif($c <= 1200 && $c > 1100){
echo 'M';
}elseif($c < 1300 && $c > 1200){
echo 'N';
}elseif($c <= 1400 && $c > 1300){
echo 'O';
}elseif($c <= 1500 && $c > 1400){
echo 'P';
}elseif($c <= 1600 && $c > 1500){
echo 'Q';
}elseif($c <= 1700 && $c > 1600){
echo 'R';
}elseif($c <= 1800 && $c > 1700){
echo 'S';
}elseif($c <= 1900 && $c > 1800){
echo 'T';
}elseif($c <= 2000 && $c > 1900){
echo 'V';
}elseif($c <= 2100 && $c > 2000){
echo 'X';
}else{
echo 'AA';
}
faster and shorter - no*, but you can make it more flexible and elegant
function find_range($n, $ranges) {
foreach($ranges as $key => $range)
if($n >= $range[0] && $n <= $range[1])
return $key;
return false;
}
$ages = array(
'baby' => array(0, 1),
'child' => array(2, 13),
'teen' => array(14, 19),
'adult' => array(20, 59),
'senior' => array(60, 100)
);
var_dump(find_range(20, $ages));
(* assuming ranges are arbitrary. If we know more about ranges, for example, that they are sorted, or always intersect, or follow some formula, we can find a better algorithm).
You could write an auxiliary function that could take an array full of anonymous functions, I guess. It would work well if your code to execute was nice and simple. Otherwise, if you're on PHP5.3 you could use proper lambdas to do more complex things. That would make it neater.
function integer_in_ranges($integer, $array) {
foreach ($array as $range => $function) {
if ($integer < $range) {
$results[] = $function();
}
}
return $results;
}
integer_in_ranges($c, array(
101 => create_function('', "execute_function(); return TRUE;"),
202 => create_function('', "execute_other_function(); return TRUE;"),
// ...
));
Not builtin, but because your plan is not that complex
switch ((int) (($c - 1) / 100)) {
case 0: /* action here */ break;
case 1: /* action here */ break;
case 2: /* action here */ break;
case 3: /* action here */ break;
default: /* action here */ break;
}
Another solution which works with arbitrary limits. I assume, that there is an upper limit
$c; // value to test
$ranges = array(101,201,199); // and so on
$index = 0;
while ($ranges[$index] >= $c) { $index++; }
// Do something useful with "$index"
Is this really your code? You always want to return AA if $c is a multiple of 100?
The fastest way to get the same result with the least amount of code would be....
$res=array('A','B','C',....);
if (($c % 100) && ($c>0) && ($c<2100)) {
echo $res[(integer)($c/100)];
} else {
echo 'AA';
}
But I would use a solution like that from sterofrog.
If the number of branches is large, you might want to look at a binary search tree
This will reduce the maximum number of comparisons that any specific branch will need to be tested against (although the minimum number of tests will also increase).
e.g. The below case there is a minimum of 2 tests and a maximum of 3 tests. In your example above, there is a maximum of 4 tests.
if ($c< 202)
{
if($c < 101){
// action 101 here
}
else {
// action 202 here
}
}
else {
if($c < 303){
// action here
}
elseif($c < 404){
// action here
}
Edit : Depends on what you mean by 'shorten'. As per your title 'faster' am assuming performance.
Edit (you've updated the List) : Case in Point 'A' needs only one comparison test, whereas the 'AA' fall through will have failed ~25 tests. Assuming an even distribution of data across all bins, the average number of tests would be ~12 ('L') whereas in a binary tree formation, the most checks would be Log2(N) + 1 - i.e. 6 tests would cover 32 branches. Unfortunately in your case, there are gaps in the data on the even '100's. If you exclude these (i.e. if value MOD 100 == 0 then fall through to 'AA') then you can do just a one sided test for the rest of the permutations.

Categories