Mysterious Organisms - help in how to test my code

Hello All! Thanks again for your continued help, I don’t know what I’d do without this forum!

I’m on the Mysterious Organism project and I’m trying to test my code. Here’s a link to the project: Link

I made up two instances of the pAequor Function in order to test my code but my tutor from the company I’m training with told me I should be using the mockUpStrand function to test my code instead. I’m stuck on the syntax of how to do this. Following is my code for reference:

// Returns a random DNA base
const returnRandBase = () => {
  const dnaBases = ['A', 'T', 'C', 'G']
  return dnaBases[Math.floor(Math.random() * 4)] 
}

// Returns a random single stand of DNA containing 15 bases
const mockUpStrand = () => {
  const newStrand = []
  for (let i = 0; i < 15; i++) {
    newStrand.push(returnRandBase())
  }
  return newStrand
}
 
const pAequorFactory = (specimenNum, dna) => {
    return {
      specimenNum : specimenNum,
      dna : dna,
      mutate() {
        let dnaM = this.dna[Math.floor(Math.random() * this.dna.length)];
        let randI = [Math.floor(Math.random() * 14)];
        this.dna.splice(randI, 1, dnaM);
        if (this.dna === mockUpStrand) {
          mutate()
        } else {
          return this.dna;
        }      
        },
      compareDNA() {
        let zip = [];
        for (let i = 0; i < mockUpStrand.length; i++) {
          zip.push([mockUpStrand.length[i], this.dna[i]]);
        } return zip;
      },
}    

}

My tutor has only signed off for the day, it being past 5pm here in London, England, but I’m ready to code for the rest of the evening! And help would be much appreciated.

Your “dna” attribute being passed into the “pAequorFactory” function for your new organism will be your “mockUpStrand” function. So, when the “pAequorFactory” function is called, it calls the “mockUpStrand” function to get it’s “dna” attribute. So, pass “mockUpStrand()” into your function along with your “specimenNum” when you call the factory for your new organism instances. Hopefully that makes sense. If there’s anything unclear in any of that, let me know and I’ll gladly elaborate.

Great! Thank you so much! There’s an instance of pAequorFactory logged to the console now. I was missing the brackets () after mockUpStrand. What’s the syntax, however, to test two of these instances with the compareDNA() method?

No problem. Happy to help. As far as the compareDNA() method goes, you will need two instances of the organism saved as objects rather than just created in the console. For the sake of this example, we’ll say their variable names are org1 and org2. You would then call the compareDNA() method on one of the two instances while passing in the other one that you want to compare. For example, you could log a call “org1.compareDNA(org2)” and it should (in order to fulfill the project) give you the percentage of DNA bases that are the same. However, I will warn you that you are missing a sizable amount of code in that method to produce the proper result.

1 Like

Thank you! Yes, I’m aware I’m missing a large part of the code, I was just trying to test the first part! Thanks again!

Hi again @therealpelance . So, I did the following:

const pAequorFactory = (specimenNum, dna) => {
    return {
      specimenNum : specimenNum,
      dna : dna,
      mutate() {
        let dnaM = this.dna[Math.floor(Math.random() * this.dna.length)];
        let randI = [Math.floor(Math.random() * 14)];
        this.dna.splice(randI, 1, dnaM);
        if (this.dna === mockUpStrand) {
          mutate()
        } else {
          return this.dna;
        }      
        },
      compareDNA() {
        let zip = [];
        for (let i = 0; i < mockUpStrand.length; i++) {
          zip.push([mockUpStrand.length[i], this.dna[i]]);
        } return zip;
      },
}    

}

org1 = (pAequorFactory(1,mockUpStrand()));
org2 = (pAequorFactory(2, mockUpStrand()));
console.log(org1.compareDNA(org2));

I was hoping to get a list of both the arrays, side by side, in order to move onto the next step of comparing them. However, all I’ve got is an empty array logged to the console [ ]

Okay. Two things. First, you will want to declare each specimen created within the factory as a new object then return it after the closing bracket of the object. I’ve included my example code up through the point that you have completed below.

function pAequorFactory(specimenNum, baseArr) {
  let specimen = {
    specimenNum: specimenNum,
    dna: baseArr,
    mutate(dna) {
      let changeNum = Math.floor(Math.random() * 15);
      const changeBase = this.dna[changeNum];
      do {
        this.dna[changeNum] = returnRandBase();
      } while (this.dna[changeNum] === changeBase);
      return dna;
    },

My second piece of advice is to log things at the source point where you’re testing rather than the end point. For example, you’ve stated that your test is to see both arrays side by side. So, instead of logging org1.compareDNA(org2), log each of the objects’ dna properties seperately. For example:

org1 = (pAequorFactory(1,mockUpStrand()));
org2 = (pAequorFactory(2, mockUpStrand()));
console.log(org1.dna);
console.log(org2.dna);

You’re also getting an empty array from compareDNA() because you’re using “mockUpStrand.length” for your loop. MockUpStrand() is a function and, thus, doesn’t have a length. You want to be pulling your length from the dna property of your object. (My “matchCount” variable in the example below is for my percentage calculation, just a different way of doing things versus what you seem to be setting up for. Not better, just different.)

compareDNA(pAequor) {
      let dna1 = this.dna;
      let dna2 = pAequor.dna;
      let matchCount = 0;
      for (j = 0; j <= dna1.length - 1; j++)
1 Like

Hi @therealpelance . Thanks so much for your detailed reply.

I should be using this.newStrand instead. Am I right? EDIT: tried this.newStrand.length and it’s returning a TypeError. Is that because it’s part of a different function? I thought that if I placed this. before it, it could be accessed.

I’m quite happy with my code for the mutate() method and it works, but did you spot something that potentially doesn’t work in my code for my mutate()?

Nope. I didn’t see anything wrong with your mutate() method. As far as the .length call in your loop, you want to use the dna of that particular object. So, you would want “this.dna.length”. I can’t remember off the top of my head if I created the variable for that because “this.dna.length” was misbehaving on the loop or not, but that’s the value that you want.

@therealpelance Thanks for your reply. I’ve included the.dna in my code for the comparison. Are you saying that I should swap them around?

I feel like I’m so close now!

// Returns a random DNA base
const returnRandBase = () => {
  const dnaBases = ['A', 'T', 'C', 'G']
  return dnaBases[Math.floor(Math.random() * 4)] 
}

// Returns a random single stand of DNA containing 15 bases
const mockUpStrand = () => {
  const newStrand = []
  for (let i = 0; i < 15; i++) {
    newStrand.push(returnRandBase())
  }
  return newStrand
}
 
const pAequorFactory = (specimenNum, dna) => {
    return {
      specimenNum : specimenNum,
      dna : dna,
      mutate() {
        let dnaM = this.dna[Math.floor(Math.random() * this.dna.length)];
        let randI = [Math.floor(Math.random() * 14)];
        this.dna.splice(randI, 1, dnaM);
        if (this.dna === mockUpStrand) {
          mutate()
        } else {
          return this.dna;
        }      
        },
      compareDNA() {
        let zip = [];
        let array1 = this.dna;
        let array2 = mockUpStrand;
        for (let i = 0; i < array1.length; i++) {
          zip.push([array1[i], array2[i]]);
        } return zip;
      },
}    

}

org1 = (pAequorFactory(1,mockUpStrand()));
org2 = (pAequorFactory(2, mockUpStrand()));
console.log(org1.compareDNA(org2));

Returns:

[ [ ‘A’, undefined ],
[ ‘C’, undefined ],
[ ‘G’, undefined ],
[ ‘A’, undefined ],
[ ‘C’, undefined ],
[ ‘G’, undefined ],
[ ‘C’, undefined ],
[ ‘T’, undefined ],
[ ‘G’, undefined ],
[ ‘T’, undefined ],
[ ‘T’, undefined ],
[ ‘C’, undefined ],
[ ‘C’, undefined ],
[ ‘C’, undefined ],
[ ‘C’, undefined ] ]

You are getting very close. The reason you’re getting “undefined” for the second part of each is that the method has no clue what it’s supposed to be checking. When you call the function at the end, you’re passing it “org2” to check. However, when you create the method, you’re not telling it to expect anything to be passed in. Your method within the factory should read compareDNA(specimen). “Specimen” here can be replaced by whatever placeholder variable you would like. Then, your “array2” variable should have a value of “specimen.dna”. Once that is done, the computer will recognize that you are passing in org2 as specimen, and define array2 as having a value of org2.dna.

1 Like

@therealpelance You’re a genius! I never could have figured that out alone. It makes sense to me now, however, so thank you!

No problem! Happy to help anytime.

1 Like

Hi @therealpelance sorry to keep bugging you! But I just noticed it says use the .specimenNum to identify which pAequor objects are being compared. How did you approach this? Because right now I can’t identify which pAequor instances are which. This is what I’ve done so far (which is returning an syntax error).

// Returns a random DNA base
const returnRandBase = () => {
  const dnaBases = ['A', 'T', 'C', 'G']
  return dnaBases[Math.floor(Math.random() * 4)] 
}

// Returns a random single stand of DNA containing 15 bases
const mockUpStrand = () => {
  const newStrand = []
  for (let i = 0; i < 15; i++) {
    newStrand.push(returnRandBase())
  }
  return newStrand
}
 
const pAequorFactory = (specimenNum, dna) => {
    return {
      specimenNum : specimenNum,
      dna : dna,
      mutate() {
        let dnaM = this.dna[Math.floor(Math.random() * this.dna.length)];
        let randI = [Math.floor(Math.random() * 14)];
        this.dna.splice(randI, 1, dnaM);
        if (this.dna === mockUpStrand) {
          mutate()
        } else {
          return this.dna;
        }      
        },
      compareDNA(specimen) {
        let zip = [];
        let array1 = this.dna;
        let array2 = specimen.dna;
        let matchCount = 0
        for (let i = 0; i < array1.length; i++) {
          zip.push([array1[i], array2[i]]);
        } return zip;

        if (array1[i] === array2[i]) {
          matchCount++;
        } let percentage = ((matchCount / 15) * 100);
          percentage.toFixed();
        console.log('Specimen ' + this.specimenNum + ' and specimen ' + this.specimenNum ' have ' + percentage + ' percent DNA in common.');
          }
        } 
      },


org1 = (pAequorFactory(1, mockUpStrand()));
org2 = (pAequorFactory(2, mockUpStrand()));
console.log(org1.compareDNA(org2));






  
  
      
      
    













I’ll have to take a look at it when I get back home and can look at the lesson itself. If that was part of the requirements, I must have missed that because I don’t remember doing it. If it is a requirement, it’s definitely possible, I just need to take a look and see what it says.

1 Like

@therealpelance Great! Thank you so much. I shall hit the hay and recommence tackling it tomorrow!

Okay, so I definitely missed that in the instructions back when I did that project. Oops. Anyway, it’s a fairly simple operation to take care of. You already have both objects within the method (the object it’s being called on and the object being passed into it). So, when logging the final output, simply use org1.specimenNam and org2.specimenNum.

1 Like