JavaScript Mysterious Organism Project

The following link is to the exercise I’m working on (I’m on part 7):
https://www.codecademy.com/practice/projects/mysterious-organism

// 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 = (number, array15) => {
 let specimenNum = number;
 let dna = array15;
  return {specimenNum, 
          dna, 
          mutate(){
          let random = this.dna;
     let i = Math.floor(Math.random()*15);
            let base = random[i]
            if (base === 'A'){
               return (random[i] = 'T', console.log(random));
              
           } else if(base === 'T'){
                     return (random[i] = 'A', console.log(random));
                     } else if (base === 'C') {
                   return (random[i] = 'G', console.log(random));
           } else {return (random[i] = 'C', console.log(random));}          
          }, 
          
          compareDNA(object) {
            let obj1 = this.dna;
            let obj2 = object;
            let total = 0;
          for (i =0; i < obj1.length; i++){
            for(j=0; j < obj2.length; j++){
             if(i === j && obj1[i] === obj2[j]){
               total = total + 6.67;
             } 
            }
          }
          return (obj1, obj2, total, console.log(total));
          }, 
          
          willLikelySurvive() {
          let survivors = this.dna;
            let total = 0;
            for (i=0; i<survivors.length; i++){
              if (survivors[i] === 'C' || survivors[i] === 'G') { total = total + 6.67
                                                                }
                
              }
          if (total >= 60) {
            return true;
          } else {return false;
            }
          }
         }
          };




const survivors = () => {
  let survivorsArray = []; 
  let dna = pAequorFactory.dna;
  let willSurvive = pAequorFactory.willLikelySurvive;
  if (survivorsArray.length <= 30 && willSurvive === true){
    survivorArray.push(pAequorFactory.dna)
  }
  return survivorsArray;
}


//let test = pAequorFactory(1, mockUpStrand());
//console.log(test.specimenNum);
//console.log(test.dna);
//test.willLikelySurvive();
console.log(survivors());




The above is my code. It works up until the const survivors function; I can’t figure out how to get methods on my object into my function. The array keeps coming back blank.

Thanks for your time!

You’ll need specimens to test. The factory function itself is not a pAequor object. You’ll need to create the pAequor objects to invoke the .willLikelySurvive() method on, and then push them into your survivorsArray.

// 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 = (number, array15) => {
 let specimenNum = number;
 let dna = array15;
  return {specimenNum, 
          dna, 
          mutate(){
          let random = this.dna;
     let i = Math.floor(Math.random()*15);
            let base = random[i]
            if (base === 'A'){
               return (random[i] = 'T', console.log(random));
              
           } else if(base === 'T'){
                     return (random[i] = 'A', console.log(random));
                     } else if (base === 'C') {
                   return (random[i] = 'G', console.log(random));
           } else {return (random[i] = 'C', console.log(random));}          
          }, 
          
          compareDNA(object) {
            let obj1 = this.dna;
            let obj2 = object;
            let total = 0;
          for (i =0; i < obj1.length; i++){
            for(j=0; j < obj2.length; j++){
             if(i === j && obj1[i] === obj2[j]){
               total = total + 6.67;
             } 
            }
          }
          return (obj1, obj2, total, console.log(total));
          }, 
          
          willLikelySurvive() {
          let survivors = this.dna;
            let total = 0;
            for (i=0; i<survivors.length; i++){
              if (survivors[i] === 'C' || survivors[i] === 'G') { total = total + 6.67
                                                                }
                
              }
          if (total >= 60) {
            return true;
          } else {return false;
            }
          },
          
          survivors () {
            let survivorsArray = [];
            let survivor = this.dna;
             if (survivorsArray.length <= 30 && survivor.willLikelySurvive === true){
    survivorArray.push(this.dna)
  } return (survivorsArray, console.log(survivorsArray));
            
          }
         }
  
          };





let test = pAequorFactory(1, [ 'C', 'C', 'C', 'C', 'C', 'T', 'A', 'A', 'G', 'C', 'C', 'G', 'C', 'A', 'C' ]);
console.log(test.dna);
test.survivors();

I put my function in the object turning it into a method; I’m still not sure how to do each instance. Do I have to do them one by one?

Moving the function into the factory function is unnecessary. The function will need to generate the objects, invoke the .willLikelySurvive() method on them, and then push them into the array if they pass. This process will need to repeat until the array has 30 pAequor instances that are likely to survive. When we want to fill an array with a specified number of elements as we do here, a while loop is a good way to go. Something with a structure similar to the following would work.

const myFunction = () => {
  myArray = [];
  //will continue creating and testing objects until the array has 10 elements
  while(myArray.length < 10) { 
    //create object
    //see if object meets requirements and add it the the array if it does
    if(object.meetsRequirements()) { 
      myArray.push(object);
    }
  }
  return myArray;
}
1 Like

Doesn’t object need to be a parameter of the function?

No. Not if you create the object instances inside the function. You can do that the same way you originally created your test object.

But I really have to do them 30 times, there has to be a faster way

The while loop takes care of that. You may have to create 100’s of instances to get 30 that pass willLikelySurvive(). Recall how you created your test object in the other topic earlier using the mockUpStrand() function. That’s how you’ll want to do it.

This:
let test = pAequorFactory(1, mockUpStrand());

Lol you’re right; I’d be lucky if it was only 30.

Yes, I figured out how to put the test object in the function.

1 Like

It’s running now; so when you put the object inside a function, you can call methods on that object within the function?

Yes. Once the object has been instantiated, its methods can be called from anywhere you have access to the object.

1 Like

ah and it’s better to use mockUpStrand since it’ll loop through different arrays until it gets to 30 where if you put a value, it’ll just return that value 30 times.

1 Like

Yes. 30 instances with the same DNA would be rather boring. Don’t forget to assign each instance a unique specimen number.

Yup I’m working on that now, if it returns true, I’m going to add 1 to specimen number.

Just a suggestion, but you could use the length of the array to assign the specimen number:

let test = pAequorFactory(survivorArray.length + 1, mockUpStrand());
//add 1, so the first specimen gets assigned 1 instead of 0
   if(test.willLikelySurvive) { 

      myArray.push(test);
    }

Why can’t I put test.willLikelySurvive === true ?

You can, but it’s unnecessary. You do have to include the () after the method call though if(test.willLikelySurvive()). Another aside:

const myFunction = () => {
  return 1 < 2; //returns true
}

We seldom, if ever, need to return true or return false if we return an expression that will evaluate to true or false the return value is the expression’s evaluated value like the example above.
The following two examples return the same thing:

if(total >= 60) {
  return true;
} else {
  return false;
}
//same as:
return total >= 60;
1 Like

What are you hoping to return here?

return (obj1, obj2, total, console.log(total))

For starters, what is the type of the value that you mean to return there?

oh I was just doing that for reference

Ahh I get it. I’m trying to do it without looking at hints or the solution, so my code probably isn’t is efficient as it could be.

1 Like