Mysterious Organism Challenge Project (JavaScript)

This is a link to my solution. Everything works fine. Can someone please review.

// 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; }; let pAequorFactory = (number, arr) => { let pAequor = { spicemenNum : number, dna : arr, mutate (){ let randomlySelectedBase = this.dna[Math.floor(Math.random() * this.dna.length)] let uniqueBases = ["A","T","C","G"]; let filteredBase = uniqueBases.filter(elm => elm !== randomlySelectedBase); let newBase = filteredBase[Math.floor(Math.random() * 3)] return this.dna.map(elm => { if(elm !== randomlySelectedBase) return elm elm = newBase; return elm } ) }, compareDNA(obj){ if(this.spicemenNum === obj["specimenNum"]) return "Two DNAs cannot have the same specimen number"; let count = 0; for(let i = 0; i<this.dna.length;i++){ for(j = 0; j<obj["dna"].length; j++){ if(obj["dna"][j] === this.dna[i] && i === j){ count += 1; } } } let percentage = count/this.dna.length * 100; console.log(`Spicemen #${pAequor.spicemenNum} and Specimen #${obj["specimenNumber"]} have ${percentage}% DNA in common`) }, willLikelySurvive(){ let numberOfC = this.dna.filter(elm => elm === "C") let probabilityOfC = numberOfC.length/this.dna.length let numberOfG = this.dna.filter(elm => elm === "G") let probabilityOfG = numberOfG.length/this.dna.length; if(probabilityOfC < 0.6 && probabilityOfG < 0.6) return false return true; } } return pAequor; } let pAequor = pAequorFactory(1,["A","A","C","C"]) console.log(pAequor.willLikelySurvive()) // pAequor.compareDNA({specimenNumber : 2, dna : ["C","A", "T", "T"]}) //Creating 30 samples; let createSamples = (numOfSamples) => { let samples = []; for(let i = 0; samples.length < numOfSamples; i++){ let dnaSamples = pAequorFactory(i,mockUpStrand()) if(dnaSamples.willLikelySurvive()){ samples.push(dnaSamples) } } return samples; } console.log(createSamples(30))

Your variables are well labelled and generally you do a great job organizing your code so that it was readable. One thing I think is not quite right is the willLikelySurvive() function. It should be returning true if the sum of C and G is greater than 60% of the total DNA. It appears you are expecting both to be over 60% which would result in the function always returning false.

1 Like

Thank you for the reply. What I did with willLikelySurvive() is, I used guard clause to avoid writing an else statement. So by default, the function returns true, it only returns false if the probabilityOfC and probabilityOfG are less than 0.6. So I think it should work fine. You can test it out

1 Like

I see. I think the difference in our understanding is this. I read the requirement that dna array contains at least 60% ‘C’ or ‘G’ bases as this meaning the strand is 60% (C or G) and you are reading it as 60% C or 60% G. Subtle, but a good illustration as to how an unclear requirement can lead to different interpretations/results.

ie. the following strand would return false in your implementation, but true in mine:
[‘C’, ‘G’, ‘C’, ‘G’, ‘C’, ‘G’, ‘C’, ‘G’, ‘C’, ‘G’, ‘C’, ‘G’, ‘C’, ‘G’, ‘C’]

Nice work!

1 Like

Anyone can tell me why the mutate method() return undefined? I don’t understand

// Returns a random DNA base const returnRandBase = () => { const dnaBases = ['A', 'T', 'C', 'G'] return dnaBases[Math.floor(Math.random() * 4)] } // Returns a random single strand of DNA containing 15 bases const mockUpStrand = () => { const newStrand = [] for (let i = 0; i < 15; i++) { newStrand.push(returnRandBase()) } return newStrand } const pAequorFactory = (number, array) => { return { specimenNum: number, dna: array, mutate() { const randInd = Math.floor(Math.random() * this.dna.length); let base = returnRandBase(); if (this.dna[randInd] !== base) { this.dna[randInd] = base; } else { this.dna[Math.floor(Math.random() * this.dna.length)] = base; } return this.dna } } } console.log(pAequorFactory(5, mockUpStrand())) console.log(pAequorFactory.mutate)

pAequorFactory will return the object that has the mutate function. The call to pAequorFactory.mutate is an attempt to access a property ‘mutate’ on a pAequorFactory object, which doesn’t exist. Therefore the request returns a value of undefined. To call the mutate function you would need to assign the returned value of pAequorFactory to a variable:

let creature = (pAequorFactory(5, mockUpStrand());
console.log(creature.mutate());

Note that the function call also requires the parenthesis.

Hope that helps!

It helps me a lot, thank you so much for your help, I appreciate it :slight_smile:

I forgot to post my solution! <a target=“_blank” href =“Mysterious-Organism/script.js at main · DanieleMineo/Mysterious-Organism · GitHub
This one was really hard for me but i think this code is good. Probably the script would be shorter if i had used more arrays method but develop the code with the basis logic helped me a lot.
I already done the task number 9. If someone have some hint or can give me a review of the code i would really appreciate it. Thanks in advance and happy coding :slight_smile:

Nice job!

I would suggest refactoring your code to use the array methods. Just change one for loop at a time and test to make sure it works. It is good practice and most code you will see as you progress will use these methods.

I’m not sure if you’re still looking for the right way to solve that task :slight_smile: But I noticed two problems in your code. The first one is IF statement you use. Will be better to use a WHILE loop (and == operator inside it), for example.
The second one is that you define ex1Strand and ex1Mutate. Correct way was to call your pAequorFactory() function just once (when you define ex1). And then just write to the console ex1._dna and ex1.mutate().
Try it - it should work! :slight_smile:

You are not permitted to view the requested resource. Getting this error while posting my code and issues. Can anyone help?

Hey guys! Facing an issue with the last function in my code.

Context* Use the .compareDNA() to find the two most related instances of pAequor.

GitHub link

The output and code is printed below. Can someone tell me why the 6.67 percent value is being a accepted by the function even though its lower than the previous percent value. Its only giving me this issue when the % value is 6.67.

Pls help, thanks!

Output:
26.67
0
1
6.67 ISSUE
0
2
60.00
14
17
The two most related instances are Specimen #14 and Specimen #17

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

// Returns a random single strand of DNA containing 15 bases
const mockUpStrand = () => {
  const newStrand = []
  for (let i = 0; i < 15; i++) {
    newStrand.push(returnRandBase())
  }
  return newStrand
}

// factory function to create multiple objects
function pAequorFactory (specimenNum, dna) {
  return {
    specimenNum: specimenNum,
    dna: dna,
    //to simulate P. aequor‘s high rate of mutation (change in its DNA)
    mutate () {
      let i = Math.floor(Math.random() * 15) ;
      currentBase = this.dna[i];
      do 
      {
         mutateBase = returnRandBase();
      } while (mutateBase === currentBase);
      this.dna[i] = mutateBase;
      return this.dna;
    },
    // to compare the DNA sequences of different P. aequor & return the percentage of DNA the two objects have in common
    compareDNA (pAequor) {
      let counter =0; 
      //console.log(pAequor.dna);
      //console.log(this.dna);
      for (j=0; j< pAequor.dna.length ;j++)
      {
        if (pAequor.dna[j] === this.dna[j]) {
          counter++ ;
        }
      }
      const ident = (counter/pAequor.dna.length ) *100 ;
      let percent = ident.toFixed(2);
      //console.log(`specimen #${pAequor.specimenNum} and specimen #${this.specimenNum} have ${percent}% DNA in common`);
      return percent;
    },
//    
   willLikelySurvive () {
     let sum= 0;
     for (l=0; l<this.dna.length ; l++)
     {
       if ( this.dna[l]=== 'C' || this.dna[l]=== 'G') {
         sum++ ;
       }
     }
     let likely = (sum/this.dna.length ) *100 ;
    // console.log(likely);
     if (likely >= 60) {
       return true;
     } else {
       return false;
     }
   },

 complementStrand () {
   complDna =[];
   for (p=0; p<this.dna.length ; p++)
   {
     if ( this.dna[p] === 'A') {
       complDna.dna[p] = 'T'
     }
     else if ( this.dna[p] === 'T') {
       complDna.dna[p] = 'A'
     }
      else if ( this.dna[p] === 'C') {
       complDna.dna[p] = 'G'
     }
      else if ( this.dna[p] === 'G') {
       complDna.dna[p] = 'C'
     }
   }
   return complDna;
 }
//end of fatory function below
  }
};

/*print to check input dna and mutated dna
let ex1 = pAequorFactory(1, mockUpStrand());
console.log(ex1.dna);
console.log(ex1.mutate()); */

/*print to check identical bases
let ex1 = pAequorFactory(1, mockUpStrand());
let ex2 = pAequorFactory(2, mockUpStrand());
ex2.compareDNA(ex1); */

/*print to survival likelihood
let ex1 = pAequorFactory(1, mockUpStrand());
console.log(ex1.dna);
console.log(ex1.willLikelySurvive()); */


//to create 30 instances of  pAequor
createSurvivors = () => {
  let instances = [];
  let instance = [];
  let nums=1;
  do {
      instance = pAequorFactory(nums, mockUpStrand());
      if (instance.willLikelySurvive() === true) 
      {
        //console.log(instance);
        instances.push(instance);
        nums++;
        }
  } while (nums <=30);
  return instances;
  };

/*to print 30 instances of  pAequor
 console.log(createSurvivors()); */

//  to find the two most related instances of pAequor

relatedMost = arr => {
  let ex1, ex2;
  let percent =0;
  for (a=0 ; a<30 ; a++)
  { ex1= arr[a]; 
    for (b=a+1; b<30; b++)
    {  ex2 = arr[b] ; 
         if (ex1.compareDNA(ex2) > percent && a !== b) 
         {
          console.log(ex1.compareDNA(ex2));
          sNum1= a; console.log(a);
          sNum2=b; console.log(b);
          percent = ex1.compareDNA(ex2) ;
        }
      }
    }
    console.log(`The two most related instances are Specimen #${sNum1} and Specimen #${sNum2} `)
  };
  
  relatedMost(createSurvivors());


Thanks for sharing, @robertjhbiz !

You can share your code in the display window by clicking “Create a Codebyte” in the right hand corner of the reply box.

The toFixed() function returns a string representation of the formatted number. A string comparison of (‘6.67%’ > ‘20.0%’) evaluates to true. While the string representation is nice for display purposes, it this unintended side-effect.

MDN .toFixed()

Hey folks! I am pretty stuck on step 5- creating the .compareDNA() method…

After checking various solutions, it seems that my method is written correctly, but whenever I try to call the method, it returns NAN… Would anyone be willing to take a look at my code and shed some light on why it is returning NAN? I am thinking that I am probably calling the method incorrectly… Thanks in advance!

// 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, dna, mutate(){ let randomIndex=Math.floor(Math.random()*16); let newBase= returnRandBase(); while(this.dna[randomIndex]=== newBase){ newBase= returnRandBase(); } this.dna[randomIndex]=newBase; return this.dna; }, compareDNA(otherStrand){ let count=0; for(let i=0; i < this.dna.length; i++){ if(this.dna[i] === otherStrand.dna[i]){ count++; } } let percent= (count/otherStrand.length) * 100; return percent } } } let strand1=pAequorFactory(1, mockUpStrand()); let strand2=pAequorFactory(2, mockUpStrand()); console.log(strand1.compareDNA(strand2));

In your compareDNA method,
you have:

let percent = (count/otherStrand.length) * 100;

put these objects don’t have a .length, so that is undefined, and dividing by something undefined gives you NAN.

The
otherStrand.length
should be
otherStrand.dna.length
or probably,
this.dna.length

Ah, such a sublte change that makes all the difference! Thank you!!