Bored php guy?

y2kbgy2kbg New
edited March 2007 in Vanilla 1.0 Help
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[1] = 0; while($c[1] != 2){ $c[2] = 0; while($c[2] != 2){ $c[3] = 0; while($c[3] != 2){ $c[4] = 0; while($c[4] != 2){ $returner[] = array($A[1],$A[2],$A[3],$A[4]); flipA(4,$par); $c[4]++; } flipA(3,$par); $c[3]++; } flipA(2,$par); $c[2]++; } flipA(1,$par); $c[1]++; } return($returner); }

Comments

  • 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) }
  • NickENickE New
    edited March 2007
    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[0]['p']);
    	for($i = 0; $i < $len[0]['p']; $i++)
    	{
    		$outcome[$i] = array($len[1]['p']);
    		for($j = 0; $j < $len[1]['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
  • NickENickE New
    edited March 2007
    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[0]['p'] / 2; $i < $len[0]['str']; $i += 2, $n /= 2)
    	{
    		$tbl .= '<tr>'.(!$i ? '<th rowspan="'.($len[0]['str'] / 2).'" colspan="'.($len[1]['str'] / 2).'">' : '');
    		for($j = 0; $j * $n < $len[0]['p']; $j++)
    			$tbl .= '<th colspan="'.$n.'">'.$genotype[0][$i + ($j & 1)];
    	}
    	
    	for($i = 0; $i < $len[1]['p']; $i++)
    	{
    		$tbl .= '<tr>';
    		for($j = 0, $n = $len[1]['p'] / 2; $j < $len[1]['str']; $j += 2, $n /= 2) 
    			if($i % $n == 0) $tbl .= '<th rowspan="'.$n.'">'.$genotype[1][$j + ( (int)($i / $n) & 1 )];
    		
    		for($j = 0; $j < $len[0]['p']; $j++) 
    			$tbl .= '<td>'.$pg[$j][$i];
    	}
    	
    	return '<table border="1" cellpadding="3">'.$tbl.'</table>';
    }
    (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[1] = array('T','T','G','g','i','i','A','a'); $InA[2] = array('t','t','g','g','I','I','a','a'); } else{ $InA[1] = str_split($_GET['a']); $InA[2] = 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[1] = 0; while($c[1] != 2){ $c[2] = 0; while($c[2] != 2){ $c[3] = 0; while($c[3] != 2){ $c[4] = 0; while($c[4] != 2){ $returner[] = array($A[1],$A[2],$A[3],$A[4]); flipA(4,$par); $c[4]++; } flipA(3,$par); $c[3]++; } flipA(2,$par); $c[2]++; } flipA(1,$par); $c[1]++; } return($returner); } echo '<h2>',implode($InA[1]),' x ',implode($InA[2]),'</h2>'; $parent1 = sepAle(1); $parent2 = sepAle(2); echo '<table border="1"><tr><td>Zak K.</td>'; foreach($parent1 as $v){ echo '<td>'.$v[0].$v[1].$v[2].$v[3].'</td>'; } echo '</tr>'; foreach($parent2 as $k => $v){ echo '<tr><td>'.$v[0].$v[1].$v[2].$v[3].'</td>'; foreach($parent1 as $kk => $vv){ echo '<td>'.caseMatch($v[0],$vv[0]).caseMatch($v[1],$vv[1]).caseMatch($v[2],$vv[2]).caseMatch($v[3],$vv[3]).'</td>'; if(isset($genotype[caseMatch($v[0],$vv[0]).caseMatch($v[1],$vv[1]).caseMatch($v[2],$vv[2]).caseMatch($v[3],$vv[3])])){ $genotype[caseMatch($v[0],$vv[0]).caseMatch($v[1],$vv[1]).caseMatch($v[2],$vv[2]).caseMatch($v[3],$vv[3])]++; } else{ $genotype[caseMatch($v[0],$vv[0]).caseMatch($v[1],$vv[1]).caseMatch($v[2],$vv[2]).caseMatch($v[3],$vv[3])] = 1; } if(isset($phenotype[GetPheno($v[0],$vv[0]).'_'.GetPheno($v[1],$vv[1]).'_'.GetPheno($v[2],$vv[2]).'_'.GetPheno($v[3],$vv[3])])){ $phenotype[GetPheno($v[0],$vv[0]).'_'.GetPheno($v[1],$vv[1]).'_'.GetPheno($v[2],$vv[2]).'_'.GetPheno($v[3],$vv[3])]++; } else{ $phenotype[GetPheno($v[0],$vv[0]).'_'.GetPheno($v[1],$vv[1]).'_'.GetPheno($v[2],$vv[2]).'_'.GetPheno($v[3],$vv[3])] = 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
  • y2kbgy2kbg New
    edited March 2007
    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
  • NickENickE New
    edited March 2007
    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.
  • ok
This discussion has been closed.