@@ -271,6 +271,7 @@ def make_text(self, words, font_size, parent=window, width=None, height=None, ju
271271 def make_entry (self , parent = window , placeholder = "" , ** extras ):
272272 '''
273273 creates a text input for user input
274+ use entry_reference.is_empty() to return a boolean of whether the input is empty (or has the placeholder value)
274275 '''
275276 widget = tk .Entry (parent , relief = "flat" , borderwidth = 1 , highlightbackground = fg , highlightcolor = "blue" , highlightthickness = 1 , background = bg , foreground = fg , insertbackground = fg , ** extras )
276277 ### identifier = self.canvas.create_window(x*self.unit, y*self.unit, window=widget)
@@ -285,6 +286,7 @@ def focusOut(_):
285286 input_box .insert (0 , placeholder )
286287 input_box .bind ("<FocusIn>" , focusIn )
287288 input_box .bind ("<FocusOut>" , focusOut )
289+ input_box .is_empty = lambda : input_box .get () == "" or input_box .get () == placeholder
288290 self .widget_list .append (input_box )
289291 return input_box
290292
@@ -326,15 +328,22 @@ def make_gradient_frame(self, parent=window):
326328 def make_checkbutton (self , label , selected = False , cursor = "hand2" , parent = window , ** extras ):
327329 '''
328330 creates a checkbox
329- use checkbutton_reference.selected.get () to retrieve a boolean of whether the box is checked or not
331+ use checkbutton_reference.is_selected () to retrieve a boolean of whether the box is checked or not
330332 '''
331333 checked = tk .BooleanVar (value = selected )
332334 checkbox = tk .Checkbutton (parent , text = label , variable = checked , bg = bg , fg = fg , selectcolor = bg , cursor = cursor , ** extras )
333- checkbox .selected = checked
335+ checkbox .is_selected = checked . get
334336 self .widget_list .append (checkbox )
335337 return checkbox
336338
337339 def make_radiobutton (self , grouping , value , label , selected = False , cursor = "hand2" , parent = window , ** extras ):
340+ '''
341+ creates a radio button
342+
343+ grouping = the name of the group the radio button belongs to
344+ value = the value of the radio button
345+ label = the text to display next to the radio button
346+ '''
338347 if grouping not in self .radiobutton_groups :
339348 self .radiobutton_groups [grouping ] = tk .StringVar ()
340349 radio = tk .Radiobutton (parent , text = label , variable = self .radiobutton_groups [grouping ], value = value , bg = bg , fg = fg , selectcolor = bg , cursor = cursor , ** extras )
@@ -711,6 +720,9 @@ def compare_iterables(source, target):
711720aa_prefs = {}
712721
713722gfp_aa_seq = "MSKGEELFTGVVPILVELDGDVNGHKFSVSGEGEGDATYGKLTLKFICTTGKLPVPWPTLVTTFSYGVQCFSRYPDHMKQHDFFKSAMPEGYVQERTIFFKDDGNYKTRAEVKFEGDTLVNRIELKGIDFKEDGNILGHKLEYNYNSHNVYIMADKQKNGIKVNFKIRHNIEDGSVQLADHYQQNTPIGDGPVLLPDNHYLSTQSALSKDPNEKRDHMVLLEFVTAAGITHGMDELYK*"
723+ ### The following is a sequence that almost doubles the optimizer output for a random seed of 42.
724+ ### Normal GFP will sometimes almost double when a seed isn't set.
725+ ### gfp_aa_seq = "MSKGEELFTGVVPILVELDGDVNGHKFSVSGEGEGDATYGKLTLKFICTTGKLPVPWPTLVTTFSYGVQCFSRYPDHMKQHDFFKSAMPEGYVQERTIFFKDDGNYKTRAEVKFEGDTLVNRIELKGIDFKEDGNILGHKLEYNYNSHNVYIMADKQKNGIKVNFKHNIEDGSVQLADHYQQNTPIGPVLLPDNHYLSTQSALSKDPKRDHMVLLEFVTAAGITHGMDELYK*"
714726
715727# target_species = { "Saccaromyces cerevisiae": 1, "Procambarus clarkii": 1, "Escherichia coli": 1, "Caenorhabditis elegans": 1, "Aliivibrio fischeri": 1, "Pyrocystis fusiformis": 1, "Vibrio natriegens": 1, "Physcomitrella patens": 1, "Synechocystis sp. PCC 6803": 1, "Deinococcus radiodurans R1": 1, "Danio rerio": 1, "Drosophila melanogaster": 1, "Homo sapiens": 1, "Oryza sativa": 1, "Bacillus subtilis": 1, "Arabidopsis thaliana": 1, "Populus trichocarpa": 1, "Haloferax volcanii": 1, "Hydra vulgaris": 1 } # all the species
716728# target_species = { "Escherichia coli": 1, "Saccaromyces cerevisiae": 1 } # demonstration of how saccaromyces ruins everything
@@ -780,8 +792,9 @@ def set_preferences():
780792 takes into account your species preference
781793 '''
782794 global aa_dict , codon_dict , aa_prefs , target_species
795+ # sets the internal weights for each species
783796 for box in species_boxes :
784- target_species [box .get_label ()] = int (box .entry .get ())
797+ target_species [box .get_label ()] = int (box .entry .get () or 0 )
785798 ts = {key : value for key , value in target_species .items () if value != 0 } # removes species with a weight of 0
786799 print (ts )
787800 if not ts : # if no species are selected
@@ -1034,17 +1047,19 @@ def optimize_amino_acids():
10341047 turn a string of amino acids or DNA into a species-optimized sequence of DNA
10351048 '''
10361049 global restriction_enzymes
1037- sequence = aa_input .get ().lower ()
1038- # sequence = gfp_aa_seq.lower() # default sequence for testing
1039- if (sequence == "" or " " in sequence ) and DNA_input .get () != "" and not " " in DNA_input .get (): # if the amino acid input isn't filled but the DNA input is
1040- sequence = dna_to_aa (DNA_input .get ())
1041- elif " " in sequence : # if the sequence data is just placeholder text and there's no DNA input
1042- sequence = ""
1050+ sequence = ""
1051+ if not aa_input .is_empty (): # if amino acids were provided
1052+ sequence = aa_input .get ().strip ().lower ()
1053+ elif not DNA_input .is_empty (): # if DNA was provided
1054+ sequence = dna_to_aa (DNA_input .get ().strip ())
1055+ else : # if no sequence was provided
1056+ messagebox .showerror ("Error" , "No sequence data was provided." )
1057+ raise ValueError ("No sequence data was provided." )
10431058 random .seed (42 ) # makes optimizations reproducible
10441059 best_seq = { "seq" : "" , "score" : float ("-inf" ), "probs" : [], "bad_probs" : [], "gc" : 0 , "unsuccessful" : 0 }
10451060 restriction_enzymes = []
10461061 for box in restriction_checkbuttons :
1047- if box .selected . get ():
1062+ if box .is_selected ():
10481063 restriction_enzymes .append (box .seq )
10491064 print (restriction_enzymes )
10501065 for _ in range (80 ): # finds the best of 80 random optimization attempts
@@ -1156,6 +1171,7 @@ def optimize_amino_acids():
11561171 result .text .tag_add ("issue" , "1.{}" .format (start ), "1.{}" .format (end ))
11571172 for start , end in best_seq ["bad_probs" ]:
11581173 result .text .tag_add ("bad_issue" , "1.{}" .format (start ), "1.{}" .format (end ))
1174+ '''
11591175 # draws attention to important parts of the sequence
11601176 result.text.tag_config("underline", underline=1)
11611177 for site in ["gatatc", "ggtctc"]:
@@ -1165,16 +1181,22 @@ def optimize_amino_acids():
11651181 locations.extend(find_overlapping(best_seq["seq"], reverse_complement(site)))
11661182 for i in locations:
11671183 result.text.tag_add("underline", "1.{}".format(i), "1.{}".format(i+span))
1184+ '''
11681185 # returns the cursor back to nomal
11691186 gui .root .config (cursor = "" )
11701187 optimize_button .config (cursor = "hand2" )
11711188
11721189def start_optimizing ():
11731190 set_preferences ()
1191+ # aa_input.delete(0, "end")
1192+ # aa_input.insert(0, gfp_aa_seq.lower()) # provides a default amino acid sequence for testing purposes
11741193 if any (weight > 0 for weight in target_species .values ()): # if at least one species has a weight greater than zero
1175- gui .root .config (cursor = "watch" )
1176- optimize_button .config (cursor = "watch" )
1177- threading .Thread (target = optimize_amino_acids ).start ()
1194+ if not (DNA_input .is_empty () and aa_input .is_empty ()): # if a sequence was provided
1195+ gui .root .config (cursor = "watch" )
1196+ optimize_button .config (cursor = "watch" )
1197+ threading .Thread (target = optimize_amino_acids ).start ()
1198+ else :
1199+ messagebox .showerror ("Error" , "No sequence was provided to optimize." )
11781200 else :
11791201 messagebox .showerror ("Error" , "At least one species must have a weight greater than zero." )
11801202
0 commit comments