Mysterious Organism Challenge Project (JavaScript)

Second time I’ve done this challenge after one year and half. Very fun! I’ve improved in some areas and left you here my code with some extra code :smiley:

// 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; }; // Store Specimen Numbers in use const usedSpecimenNum = []; // Creates objects const pAequorFactory = (num) => { // Check if Specimen Number it's in use if (usedSpecimenNum.includes(num)) { console.log( `Error! Use a different Specimen Number, ${num} it's allready in use!` ); return null; } else { console.log("Specimen Number " + num + " created successfully!"); } // Add num to array of Specimen Numbers usedSpecimenNum.push(num); return { _specimenNum: num, dna: mockUpStrand(), mutate() { // Select random index on dna const randomIndex = Math.floor(Math.random() * this.dna.length); // Replace random Base let newBase = returnRandBase(); while (newBase === this.dna[randomIndex]) { newBase = returnRandBase(); } // Replace dna base this.dna[randomIndex] = newBase; // Return DNA return this.dna; }, compareDNA(other) { // Retreive DNA array from other object const otherDNA = other.dna; let identicalBases = 0; // Check DNA in common for (let i = 0; i < this.dna.length; i++) { if (this.dna[i] === otherDNA[i]) { identicalBases++; } } // Check percentage DNA in commmon const identicalPercentage = (identicalBases / this.dna.length) * 100; // Round percentage const roundedPercentage = identicalPercentage.toFixed(1); // Logs message to console console.log( `Specimen ${this._specimenNum} and Specimen ${other._specimenNum} has ${roundedPercentage} % DNA in common.` ); }, willLikelySurvive() { // Count how many C and G bases on DNA const countCG = this.dna.filter( (base) => base === "C" || base === "G" ).length; // Check percentage of C and G bases const percentageCG = (countCG / this.dna.length) * 100; this._survivalPercentage = percentageCG.toFixed(1); return percentageCG >= 60 }, complementStrand() { // Returns complementary DNA strand where 'A' match 'T' and 'C' match 'G' vice-versa const complementDNA = []; for (let i = 0; i < this.dna.length; i++) { switch (this.dna[i]) { case 'A' : complementDNA.push('T'); break; case 'T' : complementDNA.push('A'); break; case 'C' : complementDNA.push('G'); break; case 'G' : complementDNA.push('C'); break; default: console.log('Wrong base!') break; } } return complementDNA }, }; }; /* // Creating 30 instances and store them in an array to be study later const pAequorArray = []; for (let i = 0; i < 30; i++) { pAequorArray.push(pAequorFactory([i])) } // console.log(pAequorArray); */ // Uncomment testing to check results // Comment out the loop that creates 30 instances for only test resulst will appear in console. // Testing unique ID functionality const pAequor1 = pAequorFactory(1); const pAequor2 = pAequorFactory(1); const pAequor3 = pAequorFactory(3); // Testing Mutate method function testMutate() { const pAequor = pAequorFactory(4); // Store original DNA const originalDNA = [...pAequor.dna]; // Mutate DNA const mutated = pAequor.mutate(); // Count mutations let mutationCount = 0; for (let i = 0; i < originalDNA.length; i++) { if (originalDNA[i] !== mutated[i]) { mutationCount++; console.log( `DNA mutated at position: ${i}: originalDNA: ${originalDNA[i]} mutated for: ${mutated[i]}!` ); } } // Check if only one base was mutated if (mutationCount === 1) { console.log("Only 1 base mutated, method works correctly"); } else { console.log( "More them one base mutated! Method isn't working like it should!!!" ); } } testMutate(); // Testing compareDNA method pAequor1.compareDNA(pAequor3); // Testing willLikelySurvive method function testWillLikelySurvive() { const pAequor5 = pAequorFactory(5); console.log('pAequor will survive if chances are higher them 60%') if(pAequor5.willLikelySurvive() > 59) { console.log('Survival percentage of: ' + pAequor5._survivalPercentage + '% pAequor will survive!' ) } else { console.log('Survival percentage of: ' + pAequor5._survivalPercentage + '% pAequor will not survive!' ) } pAequor5.willLikelySurvive(); } testWillLikelySurvive() function testComplementStrand(specimen) { const originalDNA = specimen.dna; const complementDNA = specimen.complementStrand(); console.log('Checking if complementary DNA it\'s correct...'); let result = true; for (let i = 0; i < originalDNA.length; i++) { const originalBase = originalDNA[i]; const complementBase = complementDNA[i]; switch (originalBase) { case 'A' : if (complementBase !== 'T') { result === false; } break case 'T' : if (complementBase !== 'A') { result === false; } break case 'C' : if (complementBase !== 'G') { result === false; } break case 'G' : if (complementBase !== 'C') { result === false; } break default: console.log('Wrong base!') break; } }; if (result) { console.log('All bases match correctly') } else { console.log('Wrong matches! DNA vulnerable!') } } testComplementStrand(pAequor1);
1 Like

Here the link to my solution: DNA app project Codecademy · GitHub

Happy coding!

P. aequor Simulation

This repository contains JavaScript code simulating the creation, mutation, survival, and comparison of hypothetical organisms named P. aequor.

Key Features:

  • P. aequor Object: Represents an organism with properties like specimen number, DNA sequence, and methods for mutation, DNA comparison, survival likelihood, and complement strand generation.
  • DNA Simulation: Generates random DNA sequences and simulates mutations.
  • Survival Analysis: Determines organism viability based on DNA composition.
  • DNA Comparison: Calculates DNA similarity between two organisms.

Usage:

  • pAequorFactory(specimenNum, dna) : Creates a new P. aequor instance.
  • createSurvivingpAequor(numpAequor) : Generates a specified number of surviving P. aequor instances.
  • findMostRelated(pAequorPopulation) : Finds the two most related P. aequor instances from a population.

Hello,
It was really challenge for me and I learned a lot about objects.
Here I send a link to my code, looking forward to some comments.

Regards
Pawel

here is my solution: my solution

here in my solution added with the extra challenges https://gist.github.com/codecademydev/7c4839c040e09faa6fbb01a64d102dc7

No, I don’t know anything about Java.

that javaSCRIPT, not JAVA, that’s totally a different language. however, if you meant javascript, I don’t mind to try helping you with specific questions. anyway, I’m sorry for the misunderstanding.

Here is my solution;

Here was my approach:

I wonder what a better clear way to find the closest pair of specimens would be.

1 Like

Hello! I stepped away from this project a while ago because it was tough for me. With no live guidance, I really struggle. However, I used ChatGPT as a mentor this time, and I’m happy with the results! (I ensured ChatGPT would not give me the full answer to a question - only guidance.) Please tell me what you think!

// Returns a random DNA base, which is represented by A, T, C, G
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 = (num, arr) => {
  return {
    specimenNum: num,
    dna: arr,
    mutate() {
      // Obtains a random index from the inputted dna array, which will be replaced
      const randomIndex = Math.floor(Math.random() * this.dna.length);
      let currentBase = this.dna[randomIndex];

      // Introduces newBase, & do...while ensures it is not the same base as currentBase
      let newBase;
      do {
        newBase = returnRandBase();
      } while (currentBase === newBase);

      // Assigns newBase to currentBase's index & returns the dna array/property
      this.dna[randomIndex] = newBase;
      return this.dna;
    },

    compareDNA(otherDNA) {
      // Setup
      const dna1 = this.dna;
      const dna2 = otherDNA.dna;
      let matchCount = 0;

      // Comparison
      for (let i = 0; i < dna1.length; i++) {
        if (dna1[i] === dna2[i]) {
          matchCount++;
        }
      }

      // Return note & conversion to a percentage
      const percentage = (matchCount / this.dna.length) * 100;
      return `Specimen #${this.specimenNum} & Specimen #${otherDNA.specimenNum} have ${percentage.toFixed(2)}% DNA in common.`;
    },

    willLikelySurvive() {
      const dna = this.dna;
      const totalBases = dna.length;
      const cgCount = dna.filter(base => base === 'C' || base === 'G').length;
      const percentageCG = (cgCount / totalBases) * 100;
      return percentageCG >= 60;
    }
  }
}

// Organism #1
const organism = pAequorFactory(1, mockUpStrand());

// mutate() Test - SUCCESS
/* console.log("Before Mutation:", organism.dna);
organism.mutate();
console.log("After Mutation:", organism.dna); */

// Organism #2
const organism2 = pAequorFactory(2, mockUpStrand());

// compareDNA() TEST - between 1 & 2 - SUCCESS
// console.log(organism.compareDNA(organism2));

// willLikelySurvive() TEST - 1 & 2 - SUCCESS
/* console.log("#1 is likely to survive: " + organism.willLikelySurvive());
console.log("#2 is likely to survive: " + organism2.willLikelySurvive()); */


// Acquiring 30 instances of organisms that are likely to survive
const likelySamples = [];
let specimenCounter = 1;

while (likelySamples.length < 30) {
  const org = pAequorFactory(specimenCounter, mockUpStrand());
  if (org.willLikelySurvive()) {
    likelySamples.push(org);
  }
  specimenCounter++;
}

// Testing to ensure 30 instances - SUCCESS
/* console.log("Here are " + likelySamples.length + " promising samples eligible for further study:");
console.log(likelySamples); */
1 Like

Hello, here’s my attempt without the last one extra task. Thanks for your time.

Jakub :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 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() { const randomBaseIndex = Math.floor(Math.random() * this.dna.length); const generatedBase = returnRandBase(); if (this.dna[randomBaseIndex] === generatedBase) { console.log( `pAequorFactory.mutate() - The new DNA base '${generatedBase}' is identical to the current base '${this.dna[randomBaseIndex]}' and does not need changes.\n` ); } else { console.log( `----------------\nOriginal DNA base: ${this.dna[randomBaseIndex]} at index: ${randomBaseIndex}` ); this.dna[randomBaseIndex] = generatedBase; console.log( `Newly inserted DNA base: ${this.dna[randomBaseIndex]} at index ${randomBaseIndex}\n----------------\n` ); } return this.dna; }, compareDNA(object) { console.log(`My DNA sequence: ${this.dna}`); console.log(`Other specimens DNA sequence: ${object.dna}`); if (this.dna === object.dna) { console.log( `Specimen ${object.specimenNum} has an identical DNA sequence.` ); } else { let identicalBases = 0; for (let i = 0; i < this.dna.length; i++) { if (this.dna[i] === object.dna[i]) { identicalBases++; } } console.log( `Total DNA in common between specimen ${ this.specimenNum } and specimen ${object.specimenNum}: ${( identicalBases / this.dna.length * 100 ).toFixed(2)}%` ); } }, willLikelySurvive(object) { let desiredBases = 0; for (let i = 0; i < object.dna.length; i++) { if (object.dna[i] === 'C' || object.dna[i] === 'G') { desiredBases++; } } if ((desiredBases / object.dna.length * 100) > 60) { return true; } else { return false; } }, }; }; const specimen = pAequorFactory(1, mockUpStrand()); console.log("Original DNA:", specimen.dna.join("") + "\n"); const mutatedDna = specimen.mutate(); console.log("Mutated DNA: ", mutatedDna.join("") + "\n"); const specimen2 = pAequorFactory(7, mockUpStrand()); specimen.compareDNA(specimen2); console.log(specimen.willLikelySurvive(specimen)); let willTheySurvive = false; let arrayOfSurvivors = []; let iter = 1; while (arrayOfSurvivors.length < 30) { let specimenToCheck = pAequorFactory(iter, mockUpStrand()); willTheySurvive = specimenToCheck.willLikelySurvive(specimenToCheck); if (willTheySurvive) { arrayOfSurvivors.push(specimenToCheck); iter++; } } //console.log(arrayOfSurvivors);

Ktotz

Here’s what I did. any suggestion to improve code is highly appreciated :slightly_smiling_face:

// Returns a random DNA base const returnRandBase = () => { const dnaBases = ["A", "T", "C", "G"]; return dnaBases[Math.floor(Math.random() * dnaBases.length)]; }; // 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 = (uniqueNum, dnaBases) => ({ specimenNum: uniqueNum, dna: dnaBases, mutate() { const baseIndex = Math.floor(Math.random() * this.dna.length); const selectedBase = this.dna[baseIndex]; let newBase = returnRandBase(); while (newBase === selectedBase) { newBase = returnRandBase(); } this.dna[baseIndex] = newBase; return this.dna; }, compareDNA(pAequorB) { let identicalBases = 0; pAequorB.dna.forEach((base, index) => { if (this.dna[index] === base) { identicalBases++; } }); const dnaMatchPercentage = (identicalBases / this.dna.length) * 100; // console.log( // `specimen #1 and specimen #2 have ${dnaMatchPercentage}% DNA in common.` // ); return dnaMatchPercentage; }, willLikelySurvive() { const baseGCount = this.dna.reduce((acc, curBase) => { return acc + (curBase === "G" || curBase === "C" ? 1 : 0); }, 0); const baseGPercent = (baseGCount / this.dna.length) * 100; return baseGPercent > 60; }, }); // create instances that can survive in their natural environment. const instancesToCreate = 30; const pAequors = []; for (let i = 0; i < instancesToCreate; i++) { const dnaBases = mockUpStrand(); const pAequor = pAequorFactory(i, dnaBases); // start mutation while (!pAequor.willLikelySurvive()) { pAequor.mutate(); } // save specimen for later study pAequors.push(pAequor); } // EXTRAS : 2 most related instances let similarityScore = 0, relatedIndexes; pAequors.forEach((org1, idx1) => { pAequors.forEach((org2, idx2) => { if (idx1 === idx2) { return; } const newSimilarityScore = org1.compareDNA(org2); if (newSimilarityScore > similarityScore) { similarityScore = newSimilarityScore; relatedIndexes = [idx1, idx2]; } }); }); console.log( `organims with index ${relatedIndexes[0]} and ${relatedIndexes[1]} have ${similarityScore}% identical DNA.` );

Here’s my solution to this challenge project:

Hi everyone,

Here is my code after completing both tasks 9. Please let me know, what do you think about?

// 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 randomIndex = Math.floor(Math.random() * this.dna.length); let randomBase = this.dna[randomIndex]; //console.log(randomBase); let newBase = returnRandBase(); //console.log(newBase) while (randomBase === newBase) { newBase = returnRandBase(); } this.dna[randomIndex] = newBase; //console.log('This is the final randomBase: ' + this.dna[randomIndex]); return this.dna; }, compareDNA(pAequor) { //console.log('This is the new pAequor to compare ' + pAequor.specimenNum) let count = 0; for (let i = 0; i < this.dna.length; i++) { if (this.dna[i] === pAequor.dna[i]) { count++; } } const percentage = (count / pAequor.dna.length) * 100; //console.log(`Specimen #${this.specimenNum} and specimen #${pAequor.specimenNum} have ${percentage}% DNA in common.`) return percentage; }, willLikelySurvive() { let count = 0; const countingBCBases = this.dna.forEach(base => { if (base === 'C' || base === 'G') { count++; } }); const percentage = (count/this.dna.length)*100; //console.log(percentage); if (percentage >= 60) { return true; } else { return false; } }, complementStrand() { console.log(this.dna) const complementaryDNA = this.dna.map(base => { switch (base) { case 'A': return base = 'T'; break; case 'T': return base = 'A'; break; case 'C': return base = 'G'; break; case 'G': return base = 'C'; break; } }); //console.log(complementaryDNA) return complementaryDNA; } } }; const newPAequor = pAequorFactory(1214, mockUpStrand()); const newPAequor2 = pAequorFactory(1215, mockUpStrand()); newPAequor.complementStrand(); console.log('This is the new pAequor dna just after being created: ' + newPAequor.dna); //console.log(newPAequor2); console.log('This is the new pAequor dna after being modified in one base: ' + newPAequor.mutate()); //console.log(newPAequor); newPAequor.compareDNA(newPAequor2); console.log('Will this pAequor survive?: '+ newPAequor2.willLikelySurvive()); const createInstances = () => { let poolPAequor = []; while (poolPAequor.length <30) { let ID = Math.floor(Math.random() * 123); //console.log('ID: ' + ID); const checkID = poolPAequor.find(object => object.specimenNum === ID); //console.log('ID check: ' + checkID); if (!checkID) { let newAequor = pAequorFactory(ID, mockUpStrand()); const checkViability = newAequor.willLikelySurvive(); if (checkViability) { poolPAequor.push(newAequor); //console.log('This is, by now, the pool of pAequor: ' + poolPAequor); } else { newAequor = pAequorFactory(checkID, mockUpStrand()); } } else { ID = Math.floor(Math.random() * 122); } } //console.log('This is the final pool: ' + poolPAequor); return poolPAequor; }; const firstPool = createInstances(); const findMostRelated = (instances) => { let highestMatch = 0; let mostRelated = []; for (let i = 0; i < instances.length - 1; i++) { for (let j = i + 1; j < instances.length; j++) { const percentage = instances[i].compareDNA(instances[j]); if (percentage > highestMatch) { highestMatch = percentage; mostRelated = [instances[i], instances[j]]; } } } console.log(`The most related specimens are #${mostRelated[0].specimenNum} and #${mostRelated[1].specimenNum} with ${highestMatch.toFixed(2)}% DNA in common.`); return mostRelated; }; findMostRelated(firstPool);

Cheers,
Sergio

1 Like

This is my code without the extra task. Please let me know what you think

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
}

let ex2 = mockUpStrand();
const pAequorFactory = (numb,dnaArray) => {
return {
_specimenNum: numb,
_dna: dnaArray,
mutate () {
let i = Math.floor(Math.random() * dnaArray.length);
let mutateDna = this._dna[i];
let randomDna = returnRandBase();
if (mutateDna !== randomDna) {
this._dna[i] = randomDna;
}
return this._dna;
},
compareDNA () {
let compareSum = 0;
for(let x = 0; x < this._dna.length; x++) {
if (this._dna == ex2) {
compareSum++;
}
}
return ((compareSum/15) * 100).toFixed(2) + “%”;
},
willLikelySurvive () {
let surviveDna = 0;
for (let y = 0; y < this._dna.length; y++){
if (this._dna[y] == ‘G’ || this._dna[y] == ‘C’){
surviveDna++;
}
}
surviveDna = (surviveDna/15) *100
if (surviveDna >= 60) {
return surviveDna;
} else {
return surviveDna;
}
},
complementStrand () {
let complementDna = ;
for (z = 0; z < this._dna.length; z++) {
switch (this._dna[z]) {
case ‘A’: complementDna.push(‘T’)
break;
case ‘T’: complementDna.push(‘A’)
break;
case ‘C’: complementDna.push(‘G’)
break;
case ‘G’: complementDna.push(‘C’)
break;
default: complementDna.push(‘Unknown’)
}
}
return complementDna;
}

};
};

let ex = pAequorFactory(1,mockUpStrand());
console.log(ex);
console.log(ex.mutate());
console.log(ex.compareDNA());
console.log(ex.willLikelySurvive());
console.log(ex.complementStrand());