Seems to me you should do the % 3
-check before you start building your protein:
def build_protein(self, request, phrase):
if len(phrase) % 3:
messages.error(request, 'CHAIN MUST BE DIVISIBLE BY 3')
return ()
protein = []
for i in range(0, len(phrase), 3):
amino = self.translate_amino(phrase[i: i + 3])
if not amino:
messages.error(request, "PROTEIN WAS NOT FOUND")
return () # you might stop the loop already
protein.append(amino)
return protein
It’s difficult to determine from your description what it is you’re trying to achieve exactly. Looking through your code, it appears you might be calling build_protein() once, but you are seeing 3 (potentially duplicate) error messages appear in the template/view – is this correct?
If so, you would like to summarize these to only show one error message for each call to build_protein() ?
To do this, it’s probably easier to simply assign a flag to indicate whether an error condition has been hit within the loop, which consolidates multiple hits into a single boolean value, as shown here:
def build_protein(self, request, phrase):
protein= []
protein_error = False
i = 0
while i < len(phrase):
codon = phrase[i: i + 3]
amino = self.translate_amino(codon)
if amino:
protein.append(amino)
else:
# Setting this on time or many has the same effect
protein_error = True
i += 3
if len(phrase) % 3:
# NOTE: Better to do this test (and return) *before* the while loop
messages.error(request, 'CHAIN MUST BE DIVISIBLE BY 3')
return()
else:
if protein_error:
# This generates only a single error message if any issues encountered
messages.error(request, "PROTEIN WAS NOT FOUND")
return protein
I am currently working on a dna to protein translator. The code works pretty well. However, I’d like to improve it with the messages framework in django: https://docs.djangoproject.com/en/3.1/ref/contrib/messages/
What I did is put three if statements in the functions translate and build protein so that when this statement is true, it raises a message. However, when the message appears, they also appear the other messages.errors. Is there any way I can print the message I want.
Here’s the views.py code where I type the if statements:
class TranslatorView(View):
def translate(self, request, phrase):
translation = ""
for letter in phrase:
if letter.lower() in self.rna_mapper:
translation += self.rna_mapper[letter.lower()].upper() if letter.isupper() else self.rna_mapper[letter]
else:
translation = "INVALID DNA CHAIN"
return translation
def translate_amino(self, codon):
return self.amino_mapper.get(codon, "")
def build_protein(self, request, phrase):
protein= []
i = 0
while i < len(phrase):
codon = phrase[i: i + 3]
amino = self.translate_amino(codon)
if amino:
protein.append(amino)
else:
messages.error(request, "PROTEIN WAS NOT FOUND")
i += 3
if len(phrase) % 3:
messages.error(request, 'CHAIN MUST BE DIVISIBLE BY 3')
return()
else:
return protein
And here’s the template where the messages appear:
{% extends "base.html"%}
{% block content%}
<div >
<h2 class = "display-3">DNA TRANSLATED SUCCESFULLY </h2>
<br>
<br>
<br>
<h2>
{{ translation }}
</h2>
<br>
<br>
<br>
<h2 class = "display-4">YOUR PROTEIN IS</h2>
<div class = "protein_image"></div>
<br>
<br>
{% if messages %}
<ul class="messages">
{% for message in messages %}
<h2>{{ message }}</h2>
{% endfor %}
</ul>
{% endif %}
<h2>
{{ protein }}
</h2>
<button class= "button_with_image_save" value="Back" onclick="window.history.back()" ></button>
</div>
{% endblock content%}
Having posted the code, I believe that I have to change something in the template in order to see one message instead of all of them. Perhaps indexing the messages?