Mysterious Organism doesn't loggs the second specimen

Hi the last line where i call the method should print:
Specimen 1 and specimen 2 have xxxx % DNA in common
but the second specimen is “undefined” and don’t really know why. This is a minor issue but it bothers me

// 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 = (num, arr) => { return { specimen: num, dna: arr, mutate() { let ranNum = Math.floor(Math.random() * this.dna.length) let newBase = returnRandBase() while (this.dna[ranNum] === newBase) { newBase = returnRandBase(); } this.dna[ranNum] = newBase return this.dna }, compareDNA(pAequor) { let matches = 0; let length = this.dna.length for (let i = 0; i< pAequor.length; i++) { if (this.dna[i] !== pAequor[i]){ matches++ } } const simliaritys = 100 * matches / length console.log(` Specimen ${this.specimen} and specimen ${pAequor.specimen} have ${simliaritys.toFixed(2)} % DNA in common`) } } } const test1 = mockUpStrand() console.log(`Original DNA: ${test1}`) const test2 = pAequorFactory(1, mockUpStrand()) console.log(`Factory DNA 1: ${test2.dna}`) const test3 = pAequorFactory(1, mockUpStrand()) console.log(`Factory DNA 2: ${test3.dna}`) const test4 = test3.mutate() console.log(`Mutation DNA: ${test4}`) test2.compareDNA(test3.dna)

PS: yes i know the if statement is wrong, it should be === not !== hehe

What you’re passing to the function compareDNA is an array:

test2.compareDNA(test3.dna)
console.log(test3.dna) // logs --> ["A", "T", "C", "A", "G", "C", "T", "G", "G", "C", "G", "T", "C", "C", "T"]

Therefore test3.dna is not an object and does not have properties, that’s why pAequor.specimen is undefined. What you do with the parameter pAequor in your function compareDNA is the same as if you wrote test3.dna.specimen in the global scope.

You could solve that by passing the whole object in:
test2.compareDNA(test3)

Then you’ll need to address the properties of the object inside the compareDNA function, e.g.:
pAequor.dna.length

1 Like

Okay, thank you man. But how exactly do I do the last step. I have no clue :confused:

What is the last step? Could you post a link to the lesson?

nono i mean your last step

" Then you’ll need to address the properties of the object inside the compareDNA function, e.g.:
pAequor.dna.length"

bc i have either the dna comparsion on 0% or (like i did before) the specimen undefined printed to the console.

for (let i = 0; i< pAequor.length; i++) {

If you pass test3 rather than test3.dna as an argument to compareDNA, there is no .length property, because test3 is an object. You need to get the length of the array dna:

pAequor.dna.length

The same issue here:

   if (this.dna[i] !== pAequor[i])

You need to get item i of dna:

pAequor.dna[i]

Then ${pAequor.specimen} in your console is defined.

I’m so sorry but I still don’t get it right. I tried to add the pAequor[i] or the .length property to multiple things in my code but honestly i don’t understand what to do. I feel so dumb :frowning:

This is really hard compared to everything before

I don’t quite understand where you’re stuck. I think it would help if you post your current code – formatted, but not as codebyte, please. Would it help to switch to german?

I got the same code as before.

Ja schon aber das wäre glaube ich für andere, die auch stuck sind und die Frage finden, doof.
Aber nice dass du Deutscher bist. Für Mentoring hast du aber wahrscheinlich keine Zeit oder?

Anyways here’s the code as Preformatted text

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

    mutate() {
        let ranNum = Math.floor(Math.random() * this.dna.length)
          let newBase = returnRandBase()
          while (this.dna[ranNum] === newBase) {
            newBase = returnRandBase();
            }
            this.dna[ranNum] = newBase
            return this.dna
    },
    compareDNA(pAequor) {
      let matches = 0;
      let length = this.dna.length
        for (let i = 0; i< length; i++) {
          if (this.dna[i] === pAequor[i]){
            matches++
          }
        }  const simliaritys = 100 * matches / length
          console.log(` Specimen ${this.specimen} and specimen ${pAequor.specimen} have ${simliaritys.toFixed(2)} % DNA in common`)
    } 
  }
}

const test1 = mockUpStrand()
console.log(`Original DNA: ${test1}`)

const test2 = pAequorFactory(1, mockUpStrand())
console.log(`Factory DNA 1: ${test2.dna}`)

const test3 = pAequorFactory(2, mockUpStrand())
console.log(`Factory DNA 2: ${test3.dna}`)

const test4 = test3.mutate()
console.log(`Mutation DNA: ${test4}`)

test2.compareDNA(test3)

Ja, versuchen wir einen Mix…

Ich habe noch nicht ganz verstanden, wo es hakt. Ist es der Parameter? Oder ist die Aufgabe, die die Methode compareDNA erfüllen soll, nicht klar? Darauf würde ich meine Antwort dann ausrichten. (Dann wieder auf Englisch)

Nein, aber die Chancen stehen gut, dass ich hier antworte.

Bin jetzt aber gerade mal für eine Weile offline…

So compareDNA() compares two different arrays and prints the differences in percent to the console. The calculation works, like u can see but the string is not.

When i add .dna to the argument in compare(): test2.compareDNA(test3.dna) it prints the right calculation, but not the correct string.

If i don’t add .dna it will print the right string but the calculation is wrong: 0.00%
But i want it both to work and print the correct string like the task said:
specimen #1 and specimen #2 have 25% DNA in common .

I kinda know what you wanted me todo beforehand but i really don’t know how to implement this:

PS: ich finds übel nice wie dedicated du hier bist. Ich seh’ dich fast unter jeder Frage.

1. Passing an array to the function

Let’s play this with your initial approch:

test2.compareDNA(test3.dna) // <-- test3.dna is an array

Because you passed an array as an argument to the method compareDNA, the parameter pAequor is an array:

compareDNA(pAequor) // <-- pAequor is an array

The array is all you need for your initial loop:

for (let i = 0; i< pAequor.length; i++) { // <-- pAequor is an array and therefore has a length property. So this works
          if (this.dna[i] !== pAequor[i]){ // <-- pAequor[i] is one letter of the array
            matches++
          }
        }

But the array pAequor which in this example is the same as test3.dna, it does not have a specimen property. So this:

${pAequor.specimen}

is undefined. No chance to get this information within this method now.

1. Passing an object to the function

So you have to pass more information as an argument to the method:

test2.compareDNA(test3) // <-- test3 is an object with all the properties you defined in the factory function

Because you passed an object as an argument to the method compareDNA, the parameter pAequor is an object:

compareDNA(pAequor) // <-- pAequor is an object

It has the following properties:

  • specimen
  • dna
  • mutate()
  • compareDNA()

That means that pAequor has a property specimen and ${pAequor.specimen} is not undefined.
But it has no length property. So in your for loop, you have to get the length of pAequor.dna.
And in the if statement, you want to get a single character of the dna:


for (let i = 0; i< pAequor.dna.length; i++) {
     if (this.dna[i] !== pAequor.dna[i]){
           matches++
    }
}

The above code works as expected if the method is called with an object.
It logs in my example " Specimen 1 and specimen 1 have 86.67 % DNA in common"
That still is not what you want, I guess. But you created both objects with the same specimen number:

const test2 = pAequorFactory(1, mockUpStrand())
const test3 = pAequorFactory(1, mockUpStrand())

Eine gute Ablenkung von den eigenen Code-Problemen :slight_smile:
So, das wars für heute…

2 Likes

Thank you so much for your time.

i did my best but matched not every little detail from the tasks.
But everything is running so that it works

1 Like

Haha, ja glaube ich dir ist auf jeden fall ehrenwert!

1 Like