code: def translate(self, cdna_sequence, first_codon_is_start=False):
          
          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
docs: 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?