# Punnett Squarer

Discussion in 'C++' started by Bjnix04, Mar 2, 2009.

1. ### Bjnix04New Member

Joined:
Apr 24, 2008
Messages:
2
0
Trophy Points:
0
This week in my AP Biology class we are doing a thing on Drosophila Flies. The experiment involves making a BOATLOAD of Punnett Squares.

After a few minutes of doing them, I got kind of bored :snore: and made a quick program to make punnett squares for me, as well as analyze the punnet square. Later I added more functions to make things easier for me.

I just wanted to post it here to get a critique of my code, I'm kind of just starting out so I wanted to know how I'm doing. Don't take it easy on me though. :nice:
Here's the code:
Code:
```#include <iostream>

using namespace std;

void boxes(char a, char b, char c, char d);
void analyze(char a2, char b2, char c2, char d2);

int main()
{
char a1,a2,a3,a4,resp;
resp = 'y';
cout<<"Punnet Squarer\n V1.0"<<endl;
while(resp == 'y'){
cout<<"enter first letter for top row A/a"<<endl;
cin>>a1;
cout<<"enter second letter for top row A/a"<<endl;
cin>>a2;
cout<<"enter first letter for side column A/a"<<endl;
cin>>a3;
cout<<"enter second letter for side comumn A/a"<<endl;
cin>>a4;

boxes(a1,a2,a3,a4);
analyze(a1,a2,a3,a4);

cout<<"\n\n";

cout<<"do another punnett square? y/n"<<endl;
cin>>resp;
}

return 0;
}

void boxes(char a, char b, char c, char d) {

if(a=='a' && c=='A'){
a='A';
c='a';
}
if(b=='a' && c=='A'){
b='A';
c='a';
}
if(a=='a' && d=='A'){
a='A';
d='a';
}
if(b=='a' && d=='A'){
b='A';
d='a';
}
cout<<"\n\n";
cout<<"      ";
cout<<a<<c;
cout<<" ";
cout<<"|";
cout<<" ";
cout<<b<<c;
cout<<endl;

cout<<"      ";
cout<<"--------"<<endl;

cout<<"      ";
cout<<a<<d;
cout<<" ";
cout<<"|";
cout<<" ";
cout<<b<<d;
cout<<endl;
}

void analyze(char a2, char b2, char c2, char d2){
int count, homdcount, homrcount, hetrocount,homd,homr,hetro;
count=0;
homdcount=0;
homrcount=0;
hetrocount=0;
homd=0;
homr=0;
hetro=0;
/*Analysis section START*/
/* Analyze top left corner */
if(a2=='A' && c2=='A' || a2=='A' && c2=='a' || a2=='a' && c2=='A' ){
++count;
}
/* Analyze top right corner */
if(b2=='A' && c2=='A' || b2=='A' && c2=='a' || b2=='a' && c2=='A' ){
++count;
}
/* Analyze bottom left corner */
if(a2=='A' && d2=='A' || a2=='A' && d2=='a' || a2=='a' && d2=='A' ){
++count;
}
/* Analyze bottom right corner */
if(b2=='A' && d2=='A' || b2=='A' && d2=='a' || b2=='a' && d2=='A' ){
++count;
}
/*Analyze top left square*/
if(a2=='A' && c2=='A'){
++homdcount;
}
else if(a2=='a' && c2=='a'){
++homrcount;
}
else{
++hetrocount;
}
/*Analyze top right square*/
if(b2=='A' && c2=='A'){
++homdcount;
}
else if(b2=='a' && c2=='a'){
++homrcount;
}
else{
++hetrocount;
}

/*Analyze bottom left square*/
if(a2=='A' && d2=='A'){
++homdcount;
}
else if(a2=='a' && d2=='a'){
++homrcount;
}
else{
++hetrocount;
}
/*Analyze bottom right square*/
if(b2=='A' && d2=='A'){
++homdcount;
}
else if(b2=='a' && d2=='a'){
++homrcount;
}
else{
++hetrocount;
}
switch(hetrocount){
case 1:
hetro=25;
break;
case 2:
hetro=50;
break;
case 3:
hetro=75;
break;
case 4:
hetro=100;
break;
}
switch(homrcount){
case 1:
homr=25;
break;
case 2:
homr=50;
break;
case 3:
homr=75;
break;
case 4:
homr=100;
break;
}
switch(homdcount){
case 1:
homd=25;
break;
case 2:
homd=50;
break;
case 3:
homd=75;
break;
case 4:
homd=100;
break;
}
/*Analysis section END*/
/*Show results of Analysis*/
switch(count){
case 1:
cout<<"25% Dominant"<<endl;
break;
case 2:
cout<<"50% Dominant"<<endl;
break;
case 3:
cout<<"75% Dominant"<<endl;
break;
case 4:
cout<<"100% Dominant"<<endl;
break;
}
cout<<"analysis:"<<endl;
cout<<"This Generation is "<<homd<<"% Homozygous Dominant"<<endl;
cout<<"This Generation is "<<homr<<"% Homozygous recessive"<<endl;
cout<<"This Generation is "<<hetro<<"% Heterozygous"<<endl;
}```
Thanks guys.

2. ### xpi0t0sMentor

Joined:
Aug 6, 2004
Messages:
3,012
203
Trophy Points:
0
Occupation:
Senior Support Engineer
Location:
England
Well done! Programming is all about making tools that make our lives easier. This takes me right back to the first useful program I wrote; my Mum was doing an Open University degree and was doing a load of chi-squares; each took about half n hour with a calculator and she'd got bored with it having done enough to understand them and still having loads left over; so she showed me how they worked and I knocked up a quick program on my trusty old Commodore 64 which took the numbers in and spat out a chi square almost instantly.

I don't know anything about punnet squares (thought at first it was something to do with strawberries), but the code looks just fine to me and if it works I think you've got something there worth keeping. The only nit I would pick on the above code is that the indentation could be better; use 3 or 4 spaces per indent not just one, and code can sometimes look clearer if it's formatted into a tabular layout rather than following strict code layout rules, e.g.:
Code:
```     if (b2=='A' && c2=='A') { ++homdcount;  }
else if (b2=='a' && c2=='a') { ++homrcount;  }
else                         { ++hetrocount; }
```

3. ### xpi0t0sMentor

Joined:
Aug 6, 2004
Messages:
3,012
203
Trophy Points:
0
Occupation:
Senior Support Engineer
Location:
England
Oh, and maybe:
Code:
```switch(homdcount){
case 1:
homd=25;
break;
case 2:
homd=50;
break;
case 3:
homd=75;
break;
case 4:
homd=100;
break;
}
```
could be replaced with
Code:
```homd=25*homdcount;
```
assuming various things of course, can homdcount only be 1,2,3 or 4, and if not what if it isn't? Maybe if (homdcount>=1 && homdcount<=4) homd=25*homdcount; would work better.

4. ### Bjnix04New Member

Joined:
Apr 24, 2008
Messages:
2
0
Trophy Points:
0
THANKS!
I was looking for a way to get rid of those switch's. Never occurred to me simply use homd=25*homdcount;
I really appreciate you pointing that out to me.

5. ### LukaBNew Member

Joined:
Mar 4, 2009
Messages:
51
0
Trophy Points:
0
This is some good information, thanks for posting

6. ### ljlongNew Member

Joined:
Dec 30, 2008
Messages:
10
1
Trophy Points:
0
Occupation:
Software engineer, embedded, rtos, machine control
Location:
Santa Rosa, CA
I had to look up Punnett on the web.
and found it. Your software is an interesting problem so I played around with the idea a little.
You have a nice beginning but it's not very general and would be hard to modify.

One thing I always try and keep in mind is make it general and make it expandable. I've included a short program that would be easy to improve. It's currently hard-coded for a 4x4 dihybrid cross. Easy modification would be to make a generalized input. Do other types of cross than dihybrid. Make the structures classes. Create an output class for printing.... the list goes on. However, it's just a start and a simple demo... thanks for the problem I hope you find this program helpfull
take care and happy computing.

it's a win32 program comprised of three files doPair.h , doPair.cpp and punn.cpp
Code:
```//include file doPair.h

typedef struct {
int mixed;
int recessive;
int dominant;
int homogeneous;
}stats;

typedef struct {
char g1[5];
}gene;

class doPair
{
public:
doPair(char*, char*, char*, stats*);
virtual ~doPair(void);
};

//class doPair.cpp
#include "StdAfx.h"
#include ".\dopair.h"

#define ISLOWER(x)  ((x >='a' && x<='z') ? 1 : 0)
#define ISUPPER(x)  ((x >='A' && x<='Z') ? 1 : 0)

/*
Pair member function
takes advantage of the pairing of the genes
makes some simple calculation and saves in a status struct
indexed by the gene index

*/
doPair::doPair(char* g1, char* g2, char* r1, stats* s1)
{
int i;
char temp;
char* rs = r1;

*r1++ = *g2++;
*r1++ = *g1++;
*r1++ = *g2;
*r1++ = *g1;
*r1   = 0;
//correct for caps in front
//do some simple summing... just place holders to demo the idea
//
for(i=0;i<2;i++)
{
if( rs[i] != rs[i+1] && rs[i] > rs[i+1])
{//mixed
temp = rs[i];
rs[i] = rs[i+1];
rs[i+1] = temp;
s1->mixed++;

}
else if(rs[i] == rs[i+1])
{
s1->homogeneous++;  //homogen
if( ISLOWER(rs[i]) )
{
s1->recessive++; //recessive

}
else
{

s1->dominant++; //dom
}
}
}

}

doPair::~doPair(void)
{

}

//main function *********************************8

// punn.cpp : Punnett Square
//

#include "stdafx.h"
#include <iostream>
#include <fstream>

#include "doPair.h"

using namespace std;

//globals
gene Gamates[16];
stats geneInfo[16];

int _tmain(int argc, _TCHAR* argv[])
{
int i,j;
char gene1[] = "RYRyrYry";
char gene2[] = "RYRyrYry";

char *g1 = gene1;
char *g2 = gene2;
char* r1;
stats* s1;

//generate the 16 groups
for(i=0; i<16; )
{

for(j=0; j<4; j++)    //number of gene groups
{
s1 = &geneInfo[i];
r1 = &Gamates[i].g1[0];
::doPair( g1, g2, r1, s1);
g2++;
g2++;
i++;
}

g2 = gene2;
g1++;
g1++;
}
//do output
for(i=0;i<16;i++)
{
s1 = &geneInfo[i];
r1 = &Gamates[i].g1[0];
cout << r1;
cout << "   info: ";

cout << " mixed: ";
cout << s1->mixed;

cout << " recessive: ";
cout << s1->recessive;
cout << " dominant: ";
cout << s1->dominant;
cout << " homogeneous: ";
cout << s1->homogeneous;

cout << "\n";

}

return 0;
}```