Mysterious Organism Challenge Project (JavaScript)

Hello!

Here is my completer code.

I’m very happy with the result of this one!

// 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;
};

//Factory Function
const pAequorFactory = (num, arr) => {
  return {
    specimenNum: num,
    dna: arr,
    //mutate DNA
    mutate() {
      for (let i = 0; i < this.dna.length; i++) {
        let newBase = returnRandBase();
        if (this.dna[i] != newBase) {
          this.dna[i] = newBase;
        } else {
          this.dna[i] = returnRandBase();
        }
      }
      return this.dna;
    },
    //compare DNA
    compareDNA(obj) {
      const dnaOne = this.dna;
      const dnaTwo = obj.dna;
      //counters
      let fullCounter = 0;
      let sameCounter = 0;

      //compare
      for (let i = 0; i < dnaOne.length; i++) {
        for (let j = 0; j < dnaTwo.length; j++) {
          //need to compare at same index
          if (i === 0) {
            if (dnaOne[i + j] === dnaTwo[j]) {
              sameCounter += 1;
            }
          }
        }
        fullCounter += 1;
      }
      let percent = Math.floor((sameCounter / fullCounter) * 100);
      return `Specimen #1 and Specimen #2 have ${percent}% DNA in common`;
    },
    //likely to survive method
    willLikelySurvive() {
      let fullCount = 0;
      let counter = 0;
      for (let i = 0; i < this.dna.length; i++) {
        if (this.dna[i] === "C" || this.dna[i] === "G") {
          counter += 1;
        } else {
          counter += 0;
        }
        fullCount += 1;
      }
      if ((counter / fullCount) * 100 >= 60) {
        return true;
      } else {
        return false;
      }
    },
  };
};

let dnaWillSurvive = [];
let i = 0;
while (dnaWillSurvive.length < 30) {
  let specimen = pAequorFactory(i, mockUpStrand());
  if (specimen.willLikelySurvive() == true) {
    dnaWillSurvive.push(specimen);
    i += 1;
  }
}

I’ve noticed that many people so far have used a loop in the mutate method to return a random base (different from the one already at that random index)
I created a function to do that task instead.

const dnaBases = ['A', 'T', 'C', 'G'];

const returnRandOtherBase = (base) => {
  const foundIndex = dnaBases.indexOf(base);
  let randomIndex = Math.floor(Math.random() * 3); // random integer 0 to 2
  if ((foundIndex > -1) && (randomIndex >= foundIndex)) {
    randomIndex++;
  }
  return dnaBases[randomIndex];
}

After being stuck on the previous challange for a year (yes, a year) this one was a breeze. Only took me a few hours to complete.

What I really enjoyed about doing this project, was that I was able to come up with novel solutions on my own that made me happy.

While there’s lots for me to learn, in making my code more graceful, I’m still leaps and bounds better than I was yesterday.

So here we go:

For creating the factory function pAequorFactory, I assigned the function’s parameters to the object elements.

specimenNum: number,
dna: array,

I saw others not do this, so a little clarity on whether this is ok or not would be great.

For the mutate method, instead of relying on the previous RandBase function, I wrote my own array of possible elements and used .splice and .push to remove the matching element and push it back in after updating the new array element.

For the compareDNA method, I first checked that both DNA lengths were the same, if not an error would be logged, and used a for loop to increment an integer variable for every array index that matched. Then I used some janky string concatenation to bring it all together for the log output.

For willLikelySurvive method, I used two variable placeholders and a for loop to iterate over the array and use a similar method to compareDNA.

complementStrand was a bit of a doozy and took awhile, but I created an empty array and used .push to fill it up with the right string.

I set out not to explicitly define all specimens myself, I tried to make a function that would do this for me and push each viable element into an array, but I got caught up in thinking that each variable had to be named differently. However, I saw in other’s solutions they were able to accomplish this without worrying about the namespace, so…will play with this later on.

I was unable to finish the last extra credit step. I mean, I can of course manually compare to see which one has the most matching, but my goal was to make a function. To do this I would have to write a new method or modify the existing compareDNA method, and I ran out of time to be honest.

Feedback is always appreciated!

1 Like

It was soooooooooo hard! It took almost a full day to do it… haha

Mysterious Organism.js

1 Like

This was my solution

// 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 dnaBaseA = ['T', 'C', 'G'] const dnaBaseT = ['A', 'C', 'G'] const dnaBaseC = ['A', 'T', 'G'] const dnaBaseG = ['A', 'T', 'C'] var baseIndex = Math.floor(Math.random()*15) console.log(this.dna) var newBase = ""; if (this.dna[baseIndex] === "A") {newBase = dnaBaseA[Math.floor(Math.random()*3)]} else if (this.dna[baseIndex] === "T") {newBase = dnaBaseT[Math.floor(Math.random()*3)]} else if (this.dna[baseIndex] === "C") {newBase = dnaBaseC[Math.floor(Math.random()*3)]} else {newBase = dnaBaseG[Math.floor(Math.random()*3)]} this.dna[baseIndex] = newBase return this.dna }, compareDNA(object) { console.log(object); console.log(this.dna); var identicalPercent = 0 for (let i = 0; i < 15; i++) { if (object[i] === this.dna[i]) {identicalPercent += (1/15)}} var identicalPercentR = (Math.round(identicalPercent * 100)/100) * 100 console.log(`Specimen 1 and specimen 2 have ${identicalPercentR}% DNA in common`) }, willLikelySurvive() { //console.log(this.dna); var survivalRate = 0; for (let i = 0; i < 15; i++) { if ((this.dna[i] === "C") || (this.dna[i] === "G")) { survivalRate += (1/15) } } //console.log(survivalRate) var survivalRateR = (Math.round(survivalRate * 100)/100) * 100 //console.log(survivalRateR); if (survivalRateR >= 60) {return true} else {return false} } } } //STEP 7 let strongPA = []; let counter=1; while (strongPA.length < 30) { let temp = pAequorFactory(counter, mockUpStrand()) if (temp.willLikelySurvive() === true) {strongPA.push(temp.dna)}; counter++; }

My solution! I checked the Codecademy’s solution and my conclusion is: I need to start getting more comfortable with iterators.

Here is my solution for the Mysterious Organism Project in JavaScript, let me know any feedback!
https://github.com/willdodsonn/DNArandomizer/blob/master/main.js

A very fun and engaging way to practice the concepts we have learnt by putting them into practice in a fictional story. I found it very entertaining and quite humorous how the concepts covered were applied to such an abstract fiction-based palette of ideas yet it felt like I was truly bringing these little creatures to life. :laughing: :rofl:

Here is mine completed:

My solution. Enjoyable project.

// 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 = (specimenNum,dna) => { return { spicimenNum: specimenNum, dna: dna, mutate() { const selectRandBase = this.dna[Math.floor(Math.random()*this.dna.length)]; const returnRandBaseCall = returnRandBase(); if(selectRandBase === returnRandBaseCall) { return this.mutate() } else { return this.dna[this.dna.indexOf(selectRandBase)] } }, compareDNA(arg) { const argDNA = arg.dna const currentDNA = this.dna let counter = currentDNA.reduce((total, currentBase, index) => currentBase === argDNA[index] ? total + 1: total, 0) const divideDNAs = Math.floor((counter / currentDNA.length) * 100) const toPercent = (divideDNAs + '%') return toPercent; }, willLikelySurvive() { const currentDNA = this.dna let counterC = 0; let counterG = 0; currentDNA.forEach((base) => { if( base === 'C') { counterC++ } if(base === 'G') { counterG++ } }) const cBasePercent = Math.floor((counterC / currentDNA.length) * 100); const gBasePercent = Math.floor((counterG / currentDNA.length) * 100); if(cBasePercent >= 60 || gBasePercent >= 60) { return true }else{ return false } } } } const createInstances = () => { instArray = []; let i = 1; while(instArray.length < 30) { instArray.push(pAequorFactory(i,mockUpStrand())) i++ } return instArray } console.log(createInstances());

I liked this one. Here’s my code if anyone wants to see. :grinning:

Good ■■■■ on finishing the last project after a whole year! Thats some perserverence!

Got everything working, but if anyone spots any bad habits I’m forming please let me know!

Here is my solution. Any feedback much appreciated

// 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 = (specimenNum, dna) => {
    return {
      specimenNum: specimenNum,
      dna: dna,

      mutate () { //function which mutates one selected base
        let generated = returnRandBase() //getting a random base from function aboce
        let randomNum = Math.floor(Math.random() * this.dna.length); //used to generate a random index for dna array
        if(this.dna[randomNum] !== generated){ //comparing if the random dna is the same as generated, if not, we change it
          this.dna[randomNum] = generated;
          return this.dna //return the changed dna
        }

      },

      compareDNA (pAequor) { //method to calculate % similarity between 2 given DNAS
        
        let current = pAequor //saving the passed pA as a var

        let counter = 0; //using this variable to store total similarities
        for (let i = 0; i < current.dna.length; i++){ //using loop to loop and check
          if(this.dna[i] === current.dna[i]){ //checking similarity between both
            counter++; //increase the counter if above is true
            
          }
          
        }
        
        let perc = (counter/current.dna.length)*100 //finding the percentage value
        return perc.toFixed(1);
        
      },

      willLikelySurvive () {
        let counter = 0;
        for (let i = 0; i < this.dna.length; i++){
          if(this.dna[i] === 'C' || this.dna[i] === 'G'){
            counter++;
          }
          let perc = (counter/this.dna.length)*100
          return perc > 60 ? true : false;
        }
      }
      
    }
  }

  //creating instances
  let instances = []
  for(let i = 0; i < 30; i++){
    let sample = pAequorFactory(i, mockUpStrand())
    if (sample.willLikelySurvive() === true){
      instances.push(sample)
    }
    
  }

console.log(instances)




  

Looking good! One thing though, is your instances array (at the bottom) full? that part had me stuck for a while, because it was only pushing it if .willLikelySurvive === true, and only ran 30 times, which meant for me that my supposed array of 30 only ended up having 1 or 2 instances

1 Like

Yeah that is actually true, any suggestions on how to change that so it does what’s needed? Thanks

My solution to the challenge question. I added a few small extras such as a randomly generated ID number, but it all works as it should…I think! ha

let uniqueId = () => { return Math.floor(Math.random() * 10000); }; // 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; }; class pAequorFactory { constructor(specID, sequence) { this.specimenNum = specID; this.dna = sequence; } } pAequorFactory.prototype.mutate = function () { let dnaBases = ["A", "T", "C", "G"]; let randomBaseIndex = Math.floor(Math.random() * 15); altDnaBases = dnaBases.filter((base) => base !== this.dna[randomBaseIndex]); this.dna[randomBaseIndex] = `*${altDnaBases[Math.floor(Math.random() * 3)]}`; return this.dna; }; pAequorFactory.prototype.willLikelySurvive = function () { let subArr = this.dna.filter((base) => base == "C" || base == "G").length; let survivability = Math.floor((subArr / 15) * 100); return survivability >= 60; }; pAequorFactory.prototype.compareDNA = function (obj) { let commonDna = 0; for (let i = 0; i < this.dna.length; i++) { if (this.dna[i] === obj.dna[i]) { commonDna++; } } commonDna = Math.floor((commonDna / 15) * 100); console.log( `Specimen ${this.specimenNum} and specimen ${obj.specimenNum} share ${commonDna}% of DNA in common.` ); }; function collection() { let dnaCollection = []; while (dnaCollection.length < 30) { let newDna = new pAequorFactory(uniqueId(), mockUpStrand()); if (newDna.willLikelySurvive()) { dnaCollection.push(newDna); } } return dnaCollection; } const sampleCollection = collection(); console.log(sampleCollection); console.log(sampleCollection[29].compareDNA(sampleCollection[18])); console.log(sampleCollection[7].mutate()); console.log(sampleCollection[13].willLikelySurvive());

For mine, I changed that loop to a while loop, added anothr variable called ‘count’ and said while (arrayOfThirty.length < 30 && count <= 100000) {push paeuqor objects that pass .willLikelySurvive}

Here’s my Mysterious Organism challenge. Feedback is always appreciated. :slight_smile:

1 Like