Vanilla 1 is no longer supported or maintained. If you need a copy, you can get it here.

# Bored php guy?

well i am trying to learn effcient coding in php and it has come to my attention that the folling code isn't effcient. Could someone tell me how i could make it better, i see each nest of loop are equilent so theretically could i make it so that loop could kepp going deeper with just the change of one varible by calling a function in itself, and passing a variable minus one until it reaches zero than so nesting?

``` function sepAle(\$par){ Global \$A; Global \$InA; \$count = 0; while(\$count !=4){ \$count++; \$A[\$count] = \$InA[\$par][(\$count*2)-1]; } \$c = 0; while(\$c != 2){ \$c = 0; while(\$c != 2){ \$c = 0; while(\$c != 2){ \$c = 0; while(\$c != 2){ \$returner[] = array(\$A,\$A,\$A,\$A); flipA(4,\$par); \$c++; } flipA(3,\$par); \$c++; } flipA(2,\$par); \$c++; } flipA(1,\$par); \$c++; } return(\$returner); } ```

• What are you actually trying to do with that code? I wish I could get my head round it for a number of reasons but right now I'm way too tired and my brain has gone to jelly since I stopped learning stuff...
• You could make the loops in almost half as many lines of code by using for loops, both of these blocks would be equalivent:```\$count = 0; while(\$count < 4){ \$count++; \$A[\$count] = \$InA[\$par][(\$count*2)-1]; } // read as: For count starting at zero, while it's less than four, add one to it in each loop for (\$count = 0; count < 4; \$count++) { \$A[\$count] = \$InA[\$par][(\$count*2)-1]; }```

Notice that I changed the comparison to count is less than four--this is one tip I learned that can help keep you from getting stuck in an infinite loop--which can happen if you are manipulating the count inside the loop.

This also appears to be a good candidate for recursion... but its late and my brain is spent from debugging code at work.
• well it doesnt really matter just know that it servers its purpose correctly, but people say it could be more effcient, if you are interested, it is part of a script to generate a quad hybrid punett square.
• This also appears to be a good candidate for recursion... that is what i was hoping for, now that i know the word i can research and read!! thank man!
• To learn recursion, nothing is better than this example i remember from the Pascal language book:```//translated to php from Pascal, and from memory //compute the factorial of a number function fact(\$n) { if (\$n == 1) return 1; else return \$n * fact(\$n-1); //or (--\$n) }```
• here's what I'd do. it takes a more general approach and generates a punett square for two genotypes of any size.
```/*
parameters are strings
expects two letters (alleles) per attribute
*/

function gen_punett_square(\$genotype1, \$genotype2)
{
//arrays so we can simplify everything in to two loop iterations
\$len = array(
array('str' => strlen(\$genotype1), 'p' => pow(2, strlen(\$genotype1) / 2)),
array('str' => strlen(\$genotype2), 'p' => pow(2, strlen(\$genotype2) / 2)),
);
\$genotype = array(\$genotype1, \$genotype2);

//initialize array
\$outcome = array(\$len['p']);
for(\$i = 0; \$i < \$len['p']; \$i++)
{
\$outcome[\$i] = array(\$len['p']);
for(\$j = 0; \$j < \$len['p']; \$j++)
\$outcome[\$i][\$j] = '';
}

for(\$ii = 0; \$ii < 2; \$ii++)
{
for(\$i = 0, \$n = \$len[\$ii]['p'] / 2; \$i < \$len[\$ii]['str']; \$i += 2, \$n /= 2)
{
for(\$j = 0; \$j < \$len[\$ii]['p']; \$j++)
{
//which allele?
if((int)(\$j / \$n) & 1) \$t = \$genotype[\$ii][\$i + 1];
else \$t = \$genotype[\$ii][\$i];

//now fill in the columns/rows
if(!\$ii)
{
for(\$k = 0; \$k < \$len[!\$ii]['p']; \$k++)
\$outcome[\$j][\$k] .= \$t;
}
else
{
for(\$k = 0; \$k < \$len[!\$ii]['p']; \$k++)
\$outcome[\$k][\$j] .= \$t;
}
}
}
}

return \$outcome;
}```
you can test it like so:`var_dump(gen_punett_square('AaBbCc', 'DdEe'));`(I know that's not very realistic, but it's better for testing because you can more easily see the permutations)
• would you not need third pair on the second parent also though:
ccool i will have to look into each of these more carefully and learn!!. I will post my whole code in a minute
• you could also do a table like this:
```function punett_square_html(\$genotype1, \$genotype2)
{
\$len = array(
array('str' => strlen(\$genotype1), 'p' => pow(2, strlen(\$genotype1) / 2)),
array('str' => strlen(\$genotype2), 'p' => pow(2, strlen(\$genotype2) / 2)),
);
\$genotype = array(\$genotype1, \$genotype2);

\$pg = gen_punett_square(\$genotype1, \$genotype2);

\$tbl = '';
for(\$i = 0, \$n = \$len['p'] / 2; \$i < \$len['str']; \$i += 2, \$n /= 2)
{
\$tbl .= '<tr>'.(!\$i ? '<th rowspan="'.(\$len['str'] / 2).'" colspan="'.(\$len['str'] / 2).'">' : '');
for(\$j = 0; \$j * \$n < \$len['p']; \$j++)
\$tbl .= '<th colspan="'.\$n.'">'.\$genotype[\$i + (\$j & 1)];
}

for(\$i = 0; \$i < \$len['p']; \$i++)
{
\$tbl .= '<tr>';
for(\$j = 0, \$n = \$len['p'] / 2; \$j < \$len['str']; \$j += 2, \$n /= 2)
if(\$i % \$n == 0) \$tbl .= '<th rowspan="'.\$n.'">'.\$genotype[\$j + ( (int)(\$i / \$n) & 1 )];

for(\$j = 0; \$j < \$len['p']; \$j++)
\$tbl .= '<td>'.\$pg[\$j][\$i];
}

}```
(by the way, I updated the gen_punett_square function so it generates it 'forward', if you will; if you're using it you might want to recopy it)
• forward,, you mean so dominent is in upper left instead of lower right?
• ohh sorry, but i wasnt using your in the link up there i had this one done last night.
• well before I had switched the logic, so on 'odd' iterations it'd use the first allele, and on 'even' ones it'd use the second specified, so it'd generate it 'back-to-front' sort of. so yes, if you had specified the dominant allele(s) first, it now comes up in the upper left instead of lower right.
• haha mine does that too(wrong order).

``` <style type="text/css"> * { font-family: monospace; } </style> <?php \$time_start = microtime(true); If(!isset(\$_GET['a'])){ \$InA = array('T','T','G','g','i','i','A','a'); \$InA = array('t','t','g','g','I','I','a','a'); } else{ \$InA = str_split(\$_GET['a']); \$InA = str_split(\$_GET['b']); } //mendels 7 pea traights \$pheno['G'] = 'Green';//Pod Color \$pheno['g'] = 'Yellow'; \$pheno['T'] = 'Tall';//Stem Length \$pheno['t'] = 'Short'; \$pheno['I'] = 'Inflated';//Pod Tightness \$pheno['i'] = 'Constricted'; \$pheno['A'] = 'Axial';//Flower Postion \$pheno['a'] = 'Terminal'; \$pheno['Y'] = 'Yellow';//Seed Color \$pheno['y'] = 'Green'; \$pheno['P'] = 'Purple';//Flower Color \$pheno['p'] = 'White'; \$pheno['R'] = 'Round';//Seed Texture \$pheno['r'] = 'Wrinkled'; function flipA(\$ale,\$par){ Global \$A; Global \$InA; if(\$A[\$ale] == \$InA[\$par][(\$ale*2)-1]){ \$A[\$ale] = \$InA[\$par][(\$ale*2)-2]; } else{ \$A[\$ale] = \$InA[\$par][(\$ale*2)-1]; } } function caseMatch(\$a,\$b){ if(\$b > \$a){ return(\$a.\$b); } else{ return(\$b.\$a); } } function GetPheno(\$a,\$b){ Global \$pheno; if(\$a===\$b){ return(\$pheno[\$a]); } else{ return(\$pheno[strtoupper(\$a)]); } } function sepAle(\$par){ Global \$A; Global \$InA; \$count = 0; while(\$count !=4){ \$count++; \$A[\$count] = \$InA[\$par][(\$count*2)-1]; } \$c = 0; while(\$c != 2){ \$c = 0; while(\$c != 2){ \$c = 0; while(\$c != 2){ \$c = 0; while(\$c != 2){ \$returner[] = array(\$A,\$A,\$A,\$A); flipA(4,\$par); \$c++; } flipA(3,\$par); \$c++; } flipA(2,\$par); \$c++; } flipA(1,\$par); \$c++; } return(\$returner); } echo '<h2>',implode(\$InA),' x ',implode(\$InA),'</h2>'; \$parent1 = sepAle(1); \$parent2 = sepAle(2); echo '<table border="1"><tr><td>Zak K.</td>'; foreach(\$parent1 as \$v){ echo '<td>'.\$v.\$v.\$v.\$v.'</td>'; } echo '</tr>'; foreach(\$parent2 as \$k => \$v){ echo '<tr><td>'.\$v.\$v.\$v.\$v.'</td>'; foreach(\$parent1 as \$kk => \$vv){ echo '<td>'.caseMatch(\$v,\$vv).caseMatch(\$v,\$vv).caseMatch(\$v,\$vv).caseMatch(\$v,\$vv).'</td>'; if(isset(\$genotype[caseMatch(\$v,\$vv).caseMatch(\$v,\$vv).caseMatch(\$v,\$vv).caseMatch(\$v,\$vv)])){ \$genotype[caseMatch(\$v,\$vv).caseMatch(\$v,\$vv).caseMatch(\$v,\$vv).caseMatch(\$v,\$vv)]++; } else{ \$genotype[caseMatch(\$v,\$vv).caseMatch(\$v,\$vv).caseMatch(\$v,\$vv).caseMatch(\$v,\$vv)] = 1; } if(isset(\$phenotype[GetPheno(\$v,\$vv).'_'.GetPheno(\$v,\$vv).'_'.GetPheno(\$v,\$vv).'_'.GetPheno(\$v,\$vv)])){ \$phenotype[GetPheno(\$v,\$vv).'_'.GetPheno(\$v,\$vv).'_'.GetPheno(\$v,\$vv).'_'.GetPheno(\$v,\$vv)]++; } else{ \$phenotype[GetPheno(\$v,\$vv).'_'.GetPheno(\$v,\$vv).'_'.GetPheno(\$v,\$vv).'_'.GetPheno(\$v,\$vv)] = 1; } } echo '</tr>'; } echo '</table><br /><div style="width: 100%">GenoTypic Ratio:<br />'; \$countt = 1; \$total = count(\$genotype); foreach(\$genotype as \$k => \$v){ if (\$countt == \$total){ echo \$v.\$k.' '; } else{ echo \$v.\$k.' : '; } \$countt++; } \$displayPheno = '</div><br /><div style="width: 100%">PhenoTypic Ratio:<br />'; \$countt = 1; \$total = count(\$phenotype); foreach(\$phenotype as \$k => \$v){ if (\$countt == \$total){ \$displayPheno .= \$v.\$k.' '; } else{ \$displayPheno .= \$v.\$k.' : '; } \$countt++; } \$displayPheno = str_replace("_", ",", \$displayPheno); echo \$displayPheno,'</div>'; \$time_end = microtime(true); \$time = (\$time_end - \$time_start)*1000; echo "<br /><br />generatated in: \$time ms\n"; ?> ```
• here's an online example of what I posted: http://sirnot.110mb.com/punett.php?a=TtGgIiAa&b=TtGgIiAa
• sweet dude, innovative idea!!!
• ``` function sepAle(\$par){ Global \$A; for(\$ca=0; \$ca != 2; ++\$ca){ for(\$cb=0; \$cb != 2; ++\$cb){ for(\$cc=0; \$cc != 2; ++\$cc){ for(\$cd=0; \$cd != 2; ++\$cd){ \$returner[] = \$A; flipA(3,\$par); } flipA(2,\$par); } flipA(1,\$par); } flipA(0,\$par); } return(\$returner); } ```
ok so i have it convert to for loops whitch saved alot of space! i didnt indent because when i did it got confusing this is easier to see it this way. I think i chould use recursion for this (ot something else) as i want to make it be ale to go up to any number, not just 3 maybe 1 or maybe 100
• I wouldn't recommend using recursion for this; especially with larger numbers, you'd see a big performance drop. with some algorithms recursion is really just the most elegant solution, but efficiency-wise iteration is almost always the best option. see what I posted above if you want an example of an iterative version that can go up to any number.
This discussion has been closed.