-
-
Save codecademydev/8a2daeaaddfe0cff4a230202905dfb3b to your computer and use it in GitHub Desktop.
Codecademy export
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Mysterious Organism 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 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, | |
// 4. Randomly select base in DNA and change it | |
mutate() { | |
const rIndex = Math.floor(Math.random() * this.dna.length); // random index | |
let = rBase = returnRandBase(); // select a new random base | |
while (this.dna[rIndex] === rBase) { | |
rBase = returnRandBase(); // select a different random if rBase === dna base | |
} // end while | |
this.dna[rIndex] = rBase; // Insert the new random base in dna array | |
return this.dna; | |
}, // end mutate() Mthd | |
// **** various approaches to solving Item 5 (compareDNA() method ***** | |
// 5 (option 1). Compares current pAequor's DNA with | |
// other pAequor DNA (otherOrg). this is codecademy solution | |
// using Array.prototype.reduce() | |
compareDNA(otherOrg) { | |
const similarities = this.dna.reduce((acc, curr, idx, arr) => { | |
if (arr[idx] === otherOrg.dna[idx]) { | |
return acc + 1; | |
} else { | |
return acc; | |
} // end if | |
}, 0 /* set acc = 0 */); // end this.dna.reduce() | |
const percentOfDNAshared = (similarities / this.dna.length) * 100; | |
const percentageTo2Deci = percentOfDNAshared.toFixed(2); // returns string | |
console.log(`${this.specimenNum} and ${otherOrg.specimenNum} have ${percentageTo2Deci}% DNA in common.`); | |
return parseFloat(percentageTo2Deci); // convert string to floating number | |
}, // end compareDNA() Mthd | |
// 5 (option2). Compares current pAequor's DNA with other pAequor DNA | |
// using Array.prototype.reduce() but uses a conditional ternary operator. | |
// Also combines formula for percentageTo2Deci but making the code possibly | |
// more difficult to read and edit | |
compareDNA2(otherOrg) { | |
const similarities = this.dna.reduce((acc, curr, idx, arr) => { | |
return (arr[idx] === otherOrg.dna[idx]) ? acc + 1 : acc; // conditional ternary op | |
}, 0 /* set acc = 0 */); // end this.dna.reduce() | |
const percentageTo2Deci = ((similarities / this.dna.length) * 100).toFixed(2); | |
console.log(`${this.specimenNum} and ${otherOrg.specimenNum} have ${percentageTo2Deci}% DNA in common.`); | |
}, // end compareDNA() Mthd | |
// 5 (option3). Compares current pAequor's DNA with other pAequor DNA (otherOrg) | |
// using Array.prototype.forEach(). Note thatArray.prototype.reduce() already | |
// provides an accumulator for this type of problem and is more efficient | |
compareDNA3(otherOrg) { | |
let totalDnaMatch = 0; // note that array.forEach returns 'undefined'; hence, an | |
// accumulator variable needs to be defined before .forEach is called | |
this.dna.forEach((el, idx, arr) => { | |
return ((arr[idx] === otherOrg.dna[idx]) ? totalDnaMatch += 1 : totalDnaMatch = totalDnaMatch); | |
}); // end this.dna.reduce() | |
const percentOfDNAshared = (totalDnaMatch / this.dna.length) * 100; | |
const percentageTo2Deci = percentOfDNAshared.toFixed(2); | |
console.log(`${this.specimenNum} and ${otherOrg.specimenNum} have ${percentageTo2Deci}% DNA in common.`); | |
}, // end compareDNA() Mthd | |
// 5 (option4). Compares current pAequor's DNA with other pAequor DNA | |
// using a for loop and variable to accumulate (total) DNA matches | |
compareDNA4(otherOrg) { | |
let total = 0; | |
for (let i=0; i < this.dna.length; i++) { | |
this.dna[i] === otherOrg.dna[i] ? total += 1 : total = total; // conditional ternary op | |
} // end for | |
const percentOfDNAshared = (total / this.dna.length) * 100; | |
const percentageTo2Deci = percentOfDNAshared.toFixed(2); | |
console.log(`${this.specimenNum} and ${otherOrg.specimenNum} have ${percentageTo2Deci}% DNA in common.`); | |
}, // end compareDNA() Mthd | |
// **** Approaches to solving Item 6 willLikelySurvive() method ***** | |
// 6 (option1). willLikelySurvive() Mthdurns true if objects DNA array | |
// contains atleast 60% 'C' or 'G' bases, else returns false. | |
// this.dan.filter() creates a new array of just 'C' and 'G' bases | |
// codecademy solution | |
willLikelySurvive() { | |
const arrayOfGorC = this.dna.filter(el => el === 'C' || el === 'G'); | |
return arrayOfGorC.length / this.dna.length >= 0.6; | |
}, // end willLikelySurvive() Mthd | |
// 6 (option2). willLikelySurvive() Mthdurns true if objects DNA array | |
// contains atleast 60% 'C' or 'G' bases, else returns false. | |
// Usees for loop to count total 'C' or 'G' bases then divides total | |
// by length of original array | |
willLikelySurvive2() { | |
let total = 0; | |
for (let idx = 0; idx < this.dna.length; idx ++) { | |
(this.dna[idx] === 'C' || this.dna[idx] === 'G') ? total += 1 : total = total; | |
} // end for | |
return (total / this.dna.length >= 0.6); | |
}, // end willLikelySurvive() Mthd | |
// 6 (option3). willLikelySurvive() Mthd returns true if objects DNA array | |
// contains at least 60% 'C' or 'G' bases, else returns false. | |
// Uses .reduce() to count the number of 'C' or 'G' bases in array | |
willLikelySurvive3() { | |
const numCorG = this.dna.reduce((acc, curr, idx, arr) => { | |
return (arr[idx] === 'C' || arr[idx] === 'G') ? acc + 1 : acc; // conditional ternary op | |
}, 0 /* set acc = 0 */); // end this.dna.reduce() | |
return numCorG / this.dna.length >= 0.6; | |
}, // end willLikelySurvive() Mthd | |
// 9. complementStrand() Method creates a new array of | |
// complementary DNA bases (A = T) and (C = G) based on the | |
// DNA strand provided. | |
complementStrand() { | |
let complementDNA = []; // Array of complement dna bases | |
complementDNA = this.dna.map(el => { | |
return el === 'A' ? 'T' : // multiple ternary expression | |
el === 'T' ? 'A' : | |
el === 'C' ? 'G' : 'C'; | |
}); // end of .map() | |
return complementDNA; | |
}, // end complementStrand() Mthd | |
} // end return | |
}; // end pQequoreFactory() Fn | |
// 9. Use .compareDNA() to find the two most | |
// related instances of pAequor. | |
// Returns a three element array with highest %, specimenNum 1, specimenNum 2 | |
// idxA increments outer loop, and idxB increments inner loop | |
const findRelatedInstances = (studyArr) => { | |
let highPercent = 0.0; // tracks highest percent similar between two DNA strands | |
let rPercent = 0.0; // returned number from .compareDNA() Method | |
let relatedArr = [0.0, 0, 0]; // [0] = highest %; [1][2] = specimenNums compared | |
for (let idxA = 0; idxA < studyArr.length-1; idxA ++) { // outer for loop | |
for (let idxB = idxA + 1; idxB < studyArr.length; idxB ++) { // inner for loop | |
rPercent = studyArr[idxA].compareDNA(studyArr[idxB]); | |
if (rPercent > highPercent) { | |
highPercent = rPercent; | |
relatedArr[0] = highPercent; // assign values to array for return | |
relatedArr[1] = studyArr[idxA].specimenNum; | |
relatedArr[2] = studyArr[idxB].specimenNum; | |
}; // end if | |
}; // end for idxB inner loop | |
}; // end for idxA outer loop | |
// return array with 3 elements: | |
// [0] = highest percent DNA match in floating point number | |
// [1] = the first DNA specimenNum compared to produce highest % | |
// [2] = the second DNA specimenNum compared to first to produce highest % | |
return relatedArr; // return array with 3 elements | |
}; // end findRelatedInstances() Fn | |
// 7. Function creates requested number (instanceNum) of | |
// new organisms and returns surviving DNA in an array | |
function createInstances(instanceNum) { | |
let newOrg = [], survivingDNA = []; | |
survived = 0; | |
for (idCount = 1; idCount < instanceNum; idCount ++) { | |
newOrg = pAequorFactory(idCount, mockUpStrand()); | |
if (newOrg.willLikelySurvive()) { | |
survivingDNA.push(newOrg); | |
} // end if | |
}; // end for loop | |
return survivingDNA; // return array of surviving DNA | |
}; // end mainProg Fn | |
// ***** MAIN PROGRM ***** | |
// 7. Run 30 DNA strands by calling createInstance() function, | |
let studyArray = []; | |
numToCreate = 30; | |
studyArray = createInstances(numToCreate); | |
console.log('New species that survived is ' + (studyArray.length) + ' out of ' + numToCreate + '\n'); | |
console.log(studyArray); | |
// 9. TEST: Create a complement of the DNA strand at index [0] | |
console.log('\nDNA Study Array at index 0') | |
console.log(studyArray[0].dna); // log original strand at [0] for comparison | |
let compArray = studyArray[0].complementStrand(); | |
console.log('DNA Complement Array'); | |
console.log(compArray); // log comparison DNA strand to compare with original | |
console.log(' '); | |
// 9. TEST: compare DNA from studyArray batch to determine which to specimen | |
// DNA strands have the most bases elements in common | |
let compareArrays = findRelatedInstances(studyArray); | |
console.log(`\nAt ${(compareArrays[0])}%, specimen DNA numbers ${compareArrays[1]} and ${compareArrays[2]} have the highest number of bases in common in the current study batch.`); | |
// **** Below are other TESTS for pAequorFactory Methods ***** | |
// Uncomment the /* */ to run tests | |
/* | |
let dnaArray2 = pAequorFactory(2, mockUpStrand()); | |
// let cloneDnaArray = Array.from(dnaArray.dna); // clone original dna for comparison | |
console.log(dnaArray2); | |
console.log(' ') | |
dnaArray.compareDNA(dnaArray2); | |
dnaArray.compareDNA2(dnaArray2); | |
dnaArray.compareDNA3(dnaArray2); | |
dnaArray.compareDNA4(dnaArray2); | |
console.log(' '); | |
console.log(dnaArray.willLikelySurvive()); | |
console.log(dnaArray.willLikelySurvive2()); | |
console.log(dnaArray.willLikelySurvive3()); | |
*/ | |
/* | |
// test mutate method | |
// call mutate method on dnaArray and note that | |
// eventhough mutated dna is assigned to mutateDnaArray, the original | |
// dnaArray is also changed | |
let mutatedDnaArray = dnaArray.mutate(); // call mutate method on dnaArray | |
console.log('Random Mutation'); | |
console.log(mutatedDnaArray); | |
console.log(cloneDnaArray); | |
console.log(dnaArray.dna + '\n'); // changed to mutated dna | |
*/ | |
// ***** Sample Output ***** | |
/* | |
New species that survived is 5 out of 30 | |
[ { specimenNum: 9, | |
dna: [ 'A', 'A', 'C', 'C', 'G', 'C', 'T', 'G', 'A', 'G', 'C', 'T', 'T', 'C', 'C' ], | |
mutate: [Function: mutate], | |
compareDNA: [Function: compareDNA], | |
compareDNA2: [Function: compareDNA2], | |
compareDNA3: [Function: compareDNA3], | |
compareDNA4: [Function: compareDNA4], | |
willLikelySurvive: [Function: willLikelySurvive], | |
willLikelySurvive2: [Function: willLikelySurvive2], | |
willLikelySurvive3: [Function: willLikelySurvive3], | |
complementStrand: [Function: complementStrand] }, | |
{ specimenNum: 14, | |
dna: [ 'T', 'T', 'G', 'T', 'G', 'C', 'G', 'G', 'T', 'A', 'G', 'G', 'A', 'G', 'G' ], | |
mutate: [Function: mutate], | |
compareDNA: [Function: compareDNA], | |
compareDNA2: [Function: compareDNA2], | |
compareDNA3: [Function: compareDNA3], | |
compareDNA4: [Function: compareDNA4], | |
willLikelySurvive: [Function: willLikelySurvive], | |
willLikelySurvive2: [Function: willLikelySurvive2], | |
willLikelySurvive3: [Function: willLikelySurvive3], | |
complementStrand: [Function: complementStrand] }, | |
{ specimenNum: 16, | |
dna: [ 'C', 'C', 'C', 'A', 'T', 'A', 'T', 'T', 'G', 'A', 'G', 'C', 'C', 'G', 'C' ], | |
mutate: [Function: mutate], | |
compareDNA: [Function: compareDNA], | |
compareDNA2: [Function: compareDNA2], | |
compareDNA3: [Function: compareDNA3], | |
compareDNA4: [Function: compareDNA4], | |
willLikelySurvive: [Function: willLikelySurvive], | |
willLikelySurvive2: [Function: willLikelySurvive2], | |
willLikelySurvive3: [Function: willLikelySurvive3], | |
complementStrand: [Function: complementStrand] }, | |
{ specimenNum: 25, | |
dna: [ 'G', 'C', 'G', 'T', 'C', 'C', 'T', 'G', 'T', 'C', 'C', 'C', 'C', 'T', 'G' ], | |
mutate: [Function: mutate], | |
compareDNA: [Function: compareDNA], | |
compareDNA2: [Function: compareDNA2], | |
compareDNA3: [Function: compareDNA3], | |
compareDNA4: [Function: compareDNA4], | |
willLikelySurvive: [Function: willLikelySurvive], | |
willLikelySurvive2: [Function: willLikelySurvive2], | |
willLikelySurvive3: [Function: willLikelySurvive3], | |
complementStrand: [Function: complementStrand] }, | |
{ specimenNum: 26, | |
dna: [ 'G', 'G', 'C', 'G', 'T', 'C', 'A', 'A', 'C', 'G', 'T', 'C', 'G', 'C', 'G' ], | |
mutate: [Function: mutate], | |
compareDNA: [Function: compareDNA], | |
compareDNA2: [Function: compareDNA2], | |
compareDNA3: [Function: compareDNA3], | |
compareDNA4: [Function: compareDNA4], | |
willLikelySurvive: [Function: willLikelySurvive], | |
willLikelySurvive2: [Function: willLikelySurvive2], | |
willLikelySurvive3: [Function: willLikelySurvive3], | |
complementStrand: [Function: complementStrand] } ] | |
DNA Study Array at index 0 | |
[ 'A', 'A', 'C', 'C', 'G', 'C', 'T', 'G', 'A', 'G', 'C', 'T', 'T', 'C', 'C' ] | |
DNA Complement Array | |
[ 'T', 'T', 'G', 'G', 'C', 'G', 'A', 'C', 'T', 'C', 'G', 'A', 'A', 'G', 'G' ] | |
9 and 14 have 20.00% DNA in common. | |
9 and 16 have 20.00% DNA in common. | |
9 and 25 have 26.67% DNA in common. | |
9 and 26 have 26.67% DNA in common. | |
14 and 16 have 20.00% DNA in common. | |
14 and 25 have 40.00% DNA in common. | |
14 and 26 have 13.33% DNA in common. | |
16 and 25 have 26.67% DNA in common. | |
16 and 26 have 20.00% DNA in common. | |
25 and 26 have 26.67% DNA in common. | |
At 40%, specimen DNA numbers 14 and 25 have the highest number of bases in common in the current study batch. | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment