Lower Triangle Matrix

Viewed 56

I am trying to create a lower triangle matrix, without imports (though I use a math import in the beginning). The function I have written takes a list of DNA sequences, and compares them and inputs a float in a list of lists. The problem, however is that I accidentally created the upper triangle. Here is my code (I'll include the other functions so it might make sense):

def sequence_difference(seq1, seq2):
    counter = 0

    if len(seq1) == len(seq2):
        for i in range(len(seq1)):
            if seq1[i] != seq2[i]:
                 counter += 1
        return counter / len(seq1)

    else:
         return ''

def jukes_cantor(diff):
    K = -(3/4) * log(1 - (4/3) * diff)
    return K

def lower_trian_matrix(list_of_seq):
    matrix = []

    for i in range(len(list_of_seq)):
         matrix.append([])

         for j in range(i + 1, len(list_of_seq)):
            matrix[i].append(jukes_cantor(sequence_difference(list_of_seq[j], list_of_seq[i])))     
    return matrix

sequences = ['TAAAAAAAAAAA',
             'TTAAAAAAAAAA', 
             'AAAAAAAAAAGG', 
             'AAAAAAAAGGGG']

print(lower_trian_matrix(sequences))

It outputs:

[[0.08833727674228764, 0.30409883108112323, 0.6081976621622466], 
 [0.4408399986765892, 0.8239592165010822], 
 [0.18848582121067953], 
 []]

But I want it to output:

[[], 
 [0.08833727674228764], 
 [0.30409883108112323, 0.4408399986765892], 
 [0.6081976621622466, 0.8239592165010822, 0.18848582121067953]]

The sequence_difference returns how different two sequences are in frequencies. The jukes_cantor returns a corrected estimate of how much the sequences actually have changed over the course of evolution.

2 Answers

Print this line matrix.append([]) below this for loop for j in range(i + 1, len(list_of_seq)): matrix[i].append(jukes_cantor(sequence_difference(list_of_seq[j], list_of_seq[i])))

Currently, it is above, hence it is executing first.

Just reverse the indexing for i and j:

from math import log

def sequence_difference(seq1, seq2):
    counter = 0

    if len(seq1) == len(seq2):
        for i in range(len(seq1)):
            if seq1[i] != seq2[i]:
                counter += 1
        return counter / len(seq1)

    else:
        return ''

def jukes_cantor(diff):
    K = -(3/4) * log(1 - (4/3) * diff)
    return K

def lower_trian_matrix(list_of_seq):
    matrix = [[]]

    for i in range(1, len(list_of_seq)):
        matrix.append([])

        for j in range(i):
            matrix[i].append(jukes_cantor(sequence_difference(list_of_seq[j], list_of_seq[i])))     
    return matrix

sequences = ['TAAAAAAAAAAA',
             'TTAAAAAAAAAA', 
             'AAAAAAAAAAGG', 
             'AAAAAAAAGGGG']

print(lower_trian_matrix(sequences))

Alternatively, rename it to def upper_trian_matrix(list_of_seq): and tell your teacher, you always wanted to create the upper triangle.

Related