Mysterious Organism Challenge Project (JavaScript)

Thanks, I’ll take a look at yours too. I take your point re: the variable names but I wanted to represent the bases they related to. I could have done with count_c for example but that was more typing :sweat_smile:

1 Like

Hi I am Marion, this is my project for 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 strandNum = 0; function newStrandNumber() { strandNum++; //+= Math.floor(Math.random() * 10); return strandNum; } //console.log(newStrandNumber()); //console.log(newStrandNumber()); function pAequorFactory(orgNum, dnaBases) { return pAequorObj = { specimenNum: orgNum, dna: dnaBases, mutate() { let randomBase = returnRandBase(); let randomIndex = Math.floor(Math.random() * this.dna.length); //let selectMutate = this.dna[Math.floor(Math.random() * this.dna.length)]; //can't reassign the value back to array object property this way, it is separate from the array this way //if (selectMutate === randomBase) { //while loop takes care of this, if statement not needed to check the same thing as while loop while (this.dna[randomIndex] === randomBase) { randomBase = returnRandBase(); } this.dna[randomIndex] = randomBase; /*} else { selectMutate = randomBase; }*/ return this.dna; }, compareDNA(otherPAequorObj) { let identicalDNA = 0; for (let i = 0; i < this.dna.length; i++) { if (this.dna[i] === otherPAequorObj.dna[i]){ identicalDNA++; } } console.log(`specimen #${this.specimenNum} and specimen #${otherPAequorObj.specimenNum} have ${(identicalDNA / 15) * 100}% DNA in common.`); }, willLikelySurvive() { let count = 0; for (const base of this.dna) { if (base === 'C' || base === 'G') { count++; } } return ((count / 15) * 100 >= 60) ? true : false; }, complementStrand(){ let complementDNA = this.dna.slice(); complementDNA = complementDNA.map(base => { switch (base) { case 'A': return 'T'; case 'T': return 'A'; case 'C': return 'G'; default: return 'C'; } }); return complementDNA; } } } const firstPAequor = pAequorFactory(newStrandNumber(), mockUpStrand()); //console.log(firstPAequor.dna) //console.log(firstPAequor.mutate()); //const firstPAequor = pAequorFactory(newStrandNumber(), mockUpStrand()); //console.log(firstPAequor); //const secondPAequor = pAequorFactory(newStrandNumber(), mockUpStrand()); //const thirdPAequor = pAequorFactory(newStrandNumber(), mockUpStrand()); //firstPAequor.compareDNA(thirdPAequor); //console.log(firstPAequor.willLikelySurvive()); function canSurvive(){ let liveArray = []; while (liveArray.length < 30) { let newStrand = pAequorFactory(newStrandNumber(), mockUpStrand()); if (newStrand.willLikelySurvive()){ liveArray.push(newStrand); } } return liveArray; } const canSurviveArray = canSurvive(); //console.log(canSurviveArray); //console.log(firstPAequor.dna); //console.log(firstPAequor.complementStrand());

I think you did 9-1 great. From a biological-view it completly makes sense and by the look of it, so does the code (but I’m a newby to:) )

1 Like

here is my code:

// 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 } let usedSpecimenNumbers = []; const pAequorFactory = (uniqueNumber, DNAarray) => { let j = uniqueNumber; if ( usedSpecimenNumbers.includes(uniqueNumber) ) { let initiator = 1; while ( usedSpecimenNumbers.includes(initiator) ) { initiator++; } j = initiator; console.log( `Input is not saved because specimen-number is not unique. First available number is: ` + j + `\n`); return null; } else {usedSpecimenNumbers.push(uniqueNumber)} return { specimenNum: uniqueNumber, dna: DNAarray, mutate: function(dna){ let randomIndex; let randomBase; do { randomIndex = Math.floor(Math.random() * 15); randomBase = returnRandBase();} while (this.dna[randomIndex] === randomBase); this.dna.splice(randomIndex, 1, randomBase); }, compareDNA: function(pAequor) { let matches = 0; for (let i = 0 ; i< this.dna.length ; i++){ if (this.dna[i] === pAequor.dna[i]){ matches++;} } let PercentageCommon = (matches / this.dna.length) * 100; PercentageCommon = Math.round(PercentageCommon * 100) / 100; console.log(`specimen #${this.specimenNum} and specimen #${pAequor.specimenNum} have ${PercentageCommon}% DNA in common.`); }, willLikelySurvive: function(dna){ let percentageCandG = 0; for (i = 0 ; i < this.dna.length ; i++) { if (this.dna[i] === 'C' || this.dna[i] === 'G') { percentageCandG += (1/15)*100; } } if (percentageCandG >= 60){ console.log(true); } else {console.log(false);}; } } }; let pAequorInstances = []; for (let i = 1; i<=30 ; i++){pAequorInstances.push(pAequorFactory(i, mockUpStrand() )); } ;
1 Like

Here is my attempt, thanks for taking a look. :slight_smile:

// 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 = (num, arr) => { return { specimenNum: num, dna: arr, mutate() { const randomBaseIndex = Math.floor(Math.random() * 15); const currentBase = this.dna[randomBaseIndex]; let mutation = returnRandBase(); while (currentBase === mutation) { mutation = returnRandBase(); } this.dna[randomBaseIndex] = mutation; return this.dna; }, compareDNA(pAequorObj) { let sameBaseType = 0; for (let i = 0; i < pAequorObj.dna.length; i++) { if (pAequorObj.dna[i] === this.dna[i]) { sameBaseType++; } } console.log(`% of common DNA: ${Math.floor((sameBaseType / 15) * 100)}%`); }, willLikelySurvive() { let cAndGCount = 0; this.dna.forEach((base) => { if (base === 'C' || base === 'G') { cAndGCount++; } }); const survivalPercentage = cAndGCount / 15; if (survivalPercentage >= 0.6) { return true; } else { return false; } }, }; }; //Test DNA const dna1 = ['G', 'C', 'C', 'A', 'T', 'T', 'T', 'A', 'C', 'T', 'G', 'T', 'A', 'C', 'C']; const dna2 = ['A', 'C', 'T', 'T', 'T', 'A', 'C', 'T', 'A', 'T', 'G', 'T', 'A', 'G', 'A']; const pAequorOne = pAequorFactory(1, mockUpStrand()); const pAequorTwo = pAequorFactory(2, mockUpStrand()); const mutatedDNA = pAequorOne.mutate(); pAequorOne.compareDNA(pAequorTwo); // const chanceAtSurvival = pAequorOne.willLikelySurvive(); //force success survival let survived = false; while (!survived) { const pAequorOne = pAequorFactory(1, mockUpStrand()); survived = pAequorOne.willLikelySurvive(); } console.log(`High chance of survival: ${survived}`);

Thanks to your solution of “30 instances” I understand how I need to do this. Thank you for sharing!

This challenge was so important in me actually understanding factory functions. Please let me know if you review and you see better ways I could improve my code. Thank you for your time :slight_smile:

// 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 } //To ensure no two organisms have the same number const loggedSpecimenNumbers = []; const pAequorFactory = (specimenNum, dna) => { if (loggedSpecimenNumbers.includes(specimenNum)){ console.log(`This specimen number is taken!`) } else { loggedSpecimenNumbers.push(specimenNum) return { specimenNum, dna, complementStrand(){ let complimentaryDNA = []; for (let i = 0; i < this.dna.length; i++){ switch (this.dna[i]){ case 'A': complimentaryDNA.push('T'); break; case 'T': complimentaryDNA.push('A'); break; case 'C': complimentaryDNA.push('G'); break; case 'G': complimentaryDNA.push('C'); break; default: complimentaryDNA.push(this.dna[i]) } } return `This Specimen's DNA is [${this.dna}] and it's Complimentary DNA is [${complimentaryDNA}]` }, willLikelySurvive(){ let numOfCandG = 0; for (let i = 0; i < this.dna.length; i++) { if (this.dna[i] !== ('C' || 'G')){ continue; } numOfCandG++; } if (((numOfCandG)/15 * 100) >= 60){ return true } else { return false } }, compareDNA(other){ let counter = 0; for (let i = 0; i < this.dna.length; i++) { if (this.dna[i] !== other.dna[i]){ continue; } counter++ } let percentage = Math.floor((counter/15)*100); return `Specimen #${this.specimenNum} and Specimen #${other.specimenNum} have ${percentage}% DNA in common.`; }, mutate(){ const randIndex = Math.floor(Math.random() * this.dna.length); let ogBase = this.dna[randIndex]; switch (ogBase) { case 'A': this.dna.splice(randIndex, 1, 'T'); break; case 'T': this.dna.splice(randIndex, 1, 'C'); break; case 'C': this.dna.splice(randIndex, 1, 'G'); break; default: this.dna.splice(randIndex, 1, 'A'); } return this.dna } } }} let organismsThatSurvived = []; //To create a batch of organisms that will survive in their natural environment const pAequorFactoryBatch = number => { let organism = { specimenNum: '', dna: '' }; for (let i = 1; organismsThatSurvived.length < number; i++) { organism = pAequorFactory(i,mockUpStrand()); let survival = organism.willLikelySurvive(); if (survival === true) { organismsThatSurvived.push(organism) } continue; } return organismsThatSurvived } // To create a new dna strand. //console.log(mockUpStrand()); // Then copy results into factory function to keep array constant. let organism1 = pAequorFactory(1,[ 'A', 'G', 'C', 'C', 'G', 'C', 'C', 'C', 'G', 'A', 'T', 'A', 'A', 'A', 'A' ]); //let organism2 = pAequorFactory(2,[ 'A', 'A', 'T', 'G', 'A', 'T', 'G', 'T', 'C', 'C', 'T', 'G', 'C', 'G', 'G' ]); //To check if the mutate method is working. //console.log(organism1.mutate()); //To check if the compareDNA method is working. //console.log(organism2.compareDNA(organism1)); //To check if the willLikelySurvive method is working. //console.log(organism1.willLikelySurvive()); //To check if the pAequorFactoryBatch method is working. //console.log(pAequorFactoryBatch(30)); //To check if the complementStrand method is working. //console.log(organism1.complementStrand());

Before going through and optimizing with peers and AI, this was my initial code. I’ve since been able to update the compareDNA using the reduce() method, as well as simplify the chanceOfSurvival() and willeLikelySurvive() using the filter() method.

// 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; }; // Random number between 1-4 const randomNum = (num) => { return Math.floor(Math.random() * num); }; // Easy log const log = (x) => { console.log(x); }; const pAequorFactory = (num, arr) => { return { specimenNum: num, dna: arr, survival: 0, mutate() { const randIndex = randomNum(this.dna.length - 1); const currentBase = this.dna[randIndex]; let newBase; do { newBase = returnRandBase(); } while (newBase === currentBase); // End do/while this.dna[randIndex] = newBase; }, // End mutate() compareDNA(obj) { const dnaLength = this.dna.length; log(dnaLength); let match = 0; for(let i = 0; i < obj.dna.length - 1; i++) { if(this.dna[i] === obj.dna[i]) { match++; }; // End if }; // End for log(`Matches: ${match}`); const percent = Math.round((match/dnaLength) * 100); log(`Specimen #${this.specimenNum} and Speciment #${obj.specimenNum} have ${percent}% DNA in common`) }, // End compareDNA() chanceOfSurvival(match) { this.survival = Math.round((match/this.dna.length) * 100) return this.survival; }, willLikelySurvive() { let match = 0; for (let i = 0; i < this.dna.length; i++) { if (this.dna[i] === 'C' || this.dna[i] === 'G') { match++; } // End if } // End for if (this.chanceOfSurvival(match) < 60) { return false; } else { return true; } // End if/else } // End willLikelySurvive() }; }; let specimenArr = []; let index = 0; let entry; do { do { entry = pAequorFactory(`${index+1}`, mockUpStrand()); } while (!entry.willLikelySurvive()); // End obj creation do/while specimenArr.push(entry); index++; } while (specimenArr.length <= 30 ); // End array do/while specimenArr.forEach((obj) => { log(`Specimen: #${obj.specimenNum}`); log(`DNA: ${obj.dna}`); obj.willLikelySurvive(); log(`Survival Rate: ${obj.survival}%`); });

UPDATED CODE WITH CHANGES

// 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 = () => { return Array.from({ length: 15 }, returnRandBase); }; // Random number between 0 and num - 1 const randomNum = (num) => Math.floor(Math.random() * num); // Easy log const log = console.log; // Object Creation const pAequorFactory = (num, arr) => { return { specimenNum: num, dna: arr, survival: 0, // mutate() function mutate() { const randIndex = randomNum(this.dna.length); let newBase; do { newBase = returnRandBase(); } while (newBase === this.dna[randIndex]); this.dna[randIndex] = newBase; }, // End mutate() // compareDNA() function compareDNA(obj) { const match = this.dna.reduce((acc, base, i) => (base === obj.dna[i] ? acc + 1 : acc), 0); const percent = Math.round((match / this.dna.length) * 100); log(`Specimen #${this.specimenNum} and Specimen #${obj.specimenNum} have ${percent}% DNA in common`); }, // End compareDNA() // chanceOfSurvival() function chanceOfSurvival() { const survivalRate = this.dna.filter(base => base === 'C' || base === 'G').length; this.survival = Math.round((survivalRate / this.dna.length) * 100); return this.survival; }, // End chanceOfSurvival() // willLikelySurvive() function willLikelySurvive() { return this.chanceOfSurvival() >= 60; } // End willLikelySurvive() }; }; const specimenArr = []; let index = 0; while (specimenArr.length < 30) { let entry; do { entry = pAequorFactory(index + 1, mockUpStrand()); } while (!entry.willLikelySurvive()); specimenArr.push(entry); index++; } specimenArr.forEach(obj => { log(`Specimen: #${obj.specimenNum}`); log(`DNA: ${obj.dna}`); log(`Survival Rate: ${obj.survival}%`); });

This was such a difficult challenge! I think I’m going to need to go over this entire module again. I thought I was following along and understanding the concepts, but when it comes to these challenges/projects it’s like I’ve forgotten everything! Either way I think I managed to get through it and here is my code:

Hey Guys! HERE my solution.
Please, give me feedback.
Thanks :stuck_out_tongue_closed_eyes: