Given a cDNA sequence which is aligned to a reading frame, returns
        the translated protein sequence and a boolean flag indicating whether
        the translated sequence ended on a stop codon (or just ran out of codons).

        Parameters
        ----------
        cdna_sequence : str
            cDNA sequence which is expected to start and end on complete codons.

        first_codon_is_start : bool
            Is the first codon of the sequence a start codon?

def translate(self, cdna_sequence, first_codon_is_start=False):
        """
        Given a cDNA sequence which is aligned to a reading frame, returns
        the translated protein sequence and a boolean flag indicating whether
        the translated sequence ended on a stop codon (or just ran out of codons).

        Parameters
        ----------
        cdna_sequence : str
            cDNA sequence which is expected to start and end on complete codons.

        first_codon_is_start : bool
            Is the first codon of the sequence a start codon?
        """
        if not isinstance(cdna_sequence, str):
            cdna_sequence = str(cdna_sequence)
        n = len(cdna_sequence)

        # trim to multiple of 3 length, if there are 1 or 2 nucleotides
        # dangling at the end of an mRNA they will not affect translation
        # since ribosome will fall off at that point
        end_idx = 3 * (n // 3)

        codon_table = self.codon_table
        if first_codon_is_start and cdna_sequence[:3] in self.start_codons:
            amino_acid_list = ['M']
            start_index = 3
        else:
            start_index = 0
            amino_acid_list = []

        ends_with_stop_codon = False
        for i in range(start_index, end_idx, 3):
            codon = cdna_sequence[i:i + 3]
            aa = codon_table[codon]

            if aa == "*":
                ends_with_stop_codon = True
                break
            amino_acid_list.append(aa)

        amino_acids = "".join(amino_acid_list)
        return amino_acids, ends_with_stop_codon