Vanilla 1 is no longer supported or maintained. If you need a copy, you can get it here.
HackerOne users: Testing against this community violates our program's Terms of Service and will result in your bounty being denied.

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.