Throw IllegalArgumentException for Protein Translation

Hello, I’ve been updating several of my solutions to meet updated tests. Most of these involved IllegalArgumentException with (newly) prescribed messages. Usually I’ve suoccesfully used something like

(throw (IllegalArgumentException. msg))

However, with protein translation I’ve not succeeded in getting the tests to pass. It seems that the :message field of the Exception info is nil. However, “Invalid codon” does show up in the :cause. Why?

Here’s my code:

(ns protein-translation)

(def codon-map 
  {
                "AUG" "Methionine"
                "UUU" "Phenylalanine"
                "UUC" "Phenylalanine"
                "UUA" "Leucine"
                "UUG" "Leucine"
                "UCU" "Serine"
                "UCC" "Serine"
                "UCA" "Serine"
                "UCG" "Serine"
                "UAU" "Tyrosine"
                "UAC" "Tyrosine"
                "UGU" "Cysteine"
                "UGC" "Cysteine"
                "UGG" "Tryptophan"
                "UAA" "STOP"
                "UAG" "STOP"
                "UGA" "STOP"
   }  )

(defn translate-codon [codon] 
  (if (or (not (= (count codon) 3))
          (not (contains? codon-map codon)))
    (throw (IllegalArgumentException. "Invalid codon"))
    (get codon-map codon)))

(defn translate-rna [rna-sequence] 
  (take-while #(not (= "STOP" %))
              (map translate-codon 
                   (map #(apply str %)(partition 3 rna-sequence)
                        ))))

Hi @efwhofmann

  1. Please check whether partition always returns what you expect it to return.
  2. Note that translate-rna returns a lazy sequence: both take-while and map are lazy. This means that (protein-translation/translate-rna "XYZ"), which appears in the test
(thrown-with-msg? IllegalArgumentException #"^Invalid codon$"
                          (protein-translation/translate-rna "XYZ"))

will also return a lazy-sequence. However, because it’s lazy, the sequence hasn’t been realized yet — no elements have been computed, so no exception is thrown. The test doesn’t force the realization of the sequence; it simply checks whether calling translate-rna throws an exception. But constructing a lazy sequence doesn’t evaluate its elements, so no error occurs at that point.

You may still be seeing the “invalid codon” message because you’re likely using a different approach to check the result — one that does realize the elements of the sequence, which then triggers the exception.

To make the exception happen in the test, you can wrap the result of translate-rna in doall

Yes, that’s it. Thanks a lot!
Using doall I got the “XYZ” test to work.
And thanks for spotting the missing padding argument for partition. That’s a mistake the previous version of the Test didn’t bring out in my first iteration back when I submitted it.