Trouble resetting / backtracking with variables - python-2.7

I've written a Cryptoquote Generator in Python using wxPython. I don't really have any problems with wxPython itself, but rather with resetting my variables. My program works this way: I have a button that generates an encrypted quote. Then, the user has a decode button they press to change one letter at a time. There is a button to reset the whole quote and a button to reset changes one step back at a time.
I have a base_copy variable to store the original encrypted quote. It is an empty list that is populated with the individual characters of the encrypted quote one at a time when on_generate_quote is called. It remains unchanged throughout the loop -- so that I may call on it with on_clear_all or on_clear_last to reset my encrypted quote. The problem is, if I use my decode_button to decode a letter, then use my clear_all_button, then decode_button again, my clear_all_button calls on a base_copy that has now been somehow tainted with changed letters that should only be in my split_cryptoquote copy. Why is this, since I never make an implicit call to alter base_copy? (I do, however, make a call in on_clear_all to set split_cryptoquote to base_copy, but this shouldn't change base_copy.)
#/------------------ wxPython GUI -----------------\
class MainWindow(wx.Frame):
quote = []
quote.append(quote_fetch(quotes))
split_cryptoquote = []
base_copy = []
split_buffer = []
buffer_origin = None
buffer_replace = None
quote_altered = False #Becomes true after first decoding change.
def __init__(self, parent, title):
wx.Frame.__init__(self, parent, title="Cryptogrammar", size=(1000, 200))
self.CreateStatusBar()
self.txt = wx.StaticText(self, -1, "".join(MainWindow.split_cryptoquote), (20,30), (40,40))
self.txt.SetForegroundColour("WHITE")
#Menu
filemenu = wx.Menu()
menu_about = filemenu.Append(wx.ID_ABOUT, "&About", " Information about this program")
menu_how = filemenu.Append(HOW_TO, "&How to Play", " How to play Cryptogrammar")
menu_exit = filemenu.Append(wx.ID_EXIT,"E&xit", " Close Cryptogrammar")
#menuGenerate = filemenu.Append(wx.ID_NONE, "&Generate New", "Generate a new cryptogram")
#menu_bar
menu_bar = wx.MenuBar()
menu_bar.Append(filemenu, "&File")
self.SetMenuBar(menu_bar)
#Buttons
generate_button = wx.Button(self, -1, "&Generate Cryptogram")
decode_button = wx.Button(self, -1, "&Decode Letter")
clear_all_button = wx.Button(self, -1, "&Clear All Changes")
clear_last_button = wx.Button(self, -1, "Clear &Last Change")
answer_button = wx.Button(self, -1, "Show &Answer")
but_list = [generate_button, decode_button, clear_all_button, clear_last_button, answer_button]
#Sizers
self.sizer2 = wx.BoxSizer(wx.HORIZONTAL)
for i in range(0, 5):
self.sizer2.Add(but_list[i], 1, wx.EXPAND)
self.sizer = wx.BoxSizer(wx.VERTICAL)
self.sizer.Add(self.txt, 1, wx.EXPAND)
self.sizer.Add(self.sizer2, 0, wx.EXPAND)
#Events
self.Bind(wx.EVT_MENU, self.on_about, menu_about)
self.Bind(wx.EVT_MENU, self.on_exit, menu_exit)
self.Bind(wx.EVT_MENU, self.on_how, menu_how)
self.Bind(wx.EVT_BUTTON, self.on_generate_quote, generate_button)
self.Bind(wx.EVT_BUTTON, self.on_decode, decode_button)
self.Bind(wx.EVT_BUTTON, self.on_answer, answer_button)
self.Bind(wx.EVT_BUTTON, self.on_clear_all, clear_all_button)
self.Bind(wx.EVT_BUTTON, self.on_clear_last, clear_last_button)
self.SetSizer(self.sizer)
self.SetAutoLayout(1)
self.sizer.Fit(self)
self.SetTitle("Cryptogrammar")
self.Centre()
def on_about(self, e):
dialogue = wx.MessageDialog(self, "A program for generating random cryptograms.\n\n\n\nCopyright 2014 Joshua Simmons\nVersion 0.1.0", "About Cryptogrammar", wx.OK)
dialogue.ShowModal()
dialogue.Destroy()
def on_exit(self, e):
self.Close(True)
def on_how(self, e):
dialogue = wx.MessageDialog(self, "HOW TO PLAY:\n\n\n--\tPress the 'Generate Cryptogram' to spawn a cryptogram.\n\n--\tUse the 'Decode Letter' to replace an encrypted letter with a letter of your choice. 'Decoded' letters will be lowercase to distinguish them.\n\n--\tUse the 'Clear Changes' button to reset the puzzle.\n\n--\t'Show Answer' solves the puzzle!", "How to play Cryptogrammar", wx.OK)
dialogue.ShowModal()
dialogue.Destroy()
def on_decode(self, e):
dialogue = wx.TextEntryDialog(self, "Which letter do you wish to change? Use format: 'a=e'", "Decode Letter", "")
dialogue.ShowModal()
decode = dialogue.GetValue()
#Text entry filter
match = re.search(r'\w+=\w+|^\d*$', decode)
if not match:
err = wx.MessageDialog(self, "That is not a correct entry format.", "Entry Error", style=wx.ICON_HAND)
err.ShowModal()
#Letter replacement
else:
if not MainWindow.quote_altered:
MainWindow.buffer_origin = decode[0].upper()
MainWindow.buffer_replace = decode[2].upper()
else:
for n in range(0, len(MainWindow.split_buffer)):
if MainWindow.split_buffer[n] == MainWindow.buffer_origin:
MainWindow.split_buffer[n] = MainWindow.buffer_replace.lower()
MainWindow.buffer_origin = decode[0].upper()
MainWindow.buffer_replace = decode[2].upper()
origin = decode[0].upper()
replace = decode[2].upper() #For resetting changes one at a time.
for n in range(0, len(MainWindow.split_cryptoquote)):
if MainWindow.split_cryptoquote[n] == origin:
MainWindow.split_cryptoquote[n] = replace.lower()
MainWindow.quote_altered = True
origin = None
replace = None
self.txt.SetLabel("".join(MainWindow.split_cryptoquote))
self.sizer.Layout()
dialogue.Destroy()
def on_generate_quote(self, e):
MainWindow.quote.pop()
MainWindow.quote.append(quote_fetch(quotes))
cryptoquote = generate_cryptogram(MainWindow.quote[0], encrypt_key(shuffle_alphabet()))
MainWindow.split_cryptoquote = []
MainWindow.base_copy = []
for i in cryptoquote:
MainWindow.split_cryptoquote.append(i)
MainWindow.base_copy.append(i)
MainWindow.split_buffer.append(i)
self.txt.SetLabel("".join(MainWindow.split_cryptoquote))
self.txt.SetForegroundColour("BLACK")
self.sizer.Layout()
def on_answer(self, e):
if len(MainWindow.base_copy) == 0:
err = wx.MessageDialog(self, "You haven't generated a puzzle yet, doofus!", "Encryption Error", style=wx.ICON_HAND)
err.ShowModal()
else:
self.txt.SetLabel(MainWindow.quote[0])
self.txt.SetForegroundColour("BLUE")
self.sizer.Layout()
def on_clear_last(self, e):
if MainWindow.quote_altered:
self.txt.SetLabel("".join(MainWindow.split_buffer))
else:
self.txt.SetLabel("".join(MainWindow.base_copy))
self.txt.SetForegroundColour("BLACK")
self.sizer.Layout()
def on_clear_all(self, e):
print MainWindow.base_copy
MainWindow.split_cryptoquote = MainWindow.base_copy
MainWindow.split_buffer = MainWindow.base_copy
MainWindow.quote_altered = False
self.txt.SetLabel("".join(MainWindow.base_copy))
self.txt.SetForegroundColour("BLACK")
self.sizer.Layout()
app = wx.App(False)
frame = MainWindow(None, "Cryptogrammar")
frame.Show()
app.MainLoop()

(I do, however, make a call in on_clear_all to set split_cryptoquote
to base_copy, but this shouldn't change base_copy.)
You've spotted your own problem:
MainWindow.split_cryptoquote = MainWindow.base_copy binds MainWindow.split_cryptoquote to the same object as MainWindow.base_copy, so when you modify one, you modify the other.
If you change the line to
MainWindow.split_cryptoquote = MainWindow.base_copy[:]
You will force python to create a new object (a copy of MainWindow.base_copy) , and this problem should not occur.
Edit: The line below:
MainWindow.split_buffer = MainWindow.base_copy also needs the same treatment, I think.
See this example:
>>> lista = [1,2]
>>> listb = lista
>>> listb.append(3)
>>> lista
[1, 2, 3]
>>> listb
[1, 2, 3]
>>> listc = lista[:]
>>> listc.append(4)
>>> listc
[1, 2, 3, 4]
>>> lista
[1, 2, 3]

Related

How to populate wxpython LIstCtrl with OnClick event

I want to design a wxpython ListCtrl. So when the Search button is clicked i am getting list like this
[(7, u'GLUOCOSE', u'C6H1206'), (8, u'SUCROSE', u'C12H22O11')]
I want to populate the listctrl with the above output. I am InsertStringItem method, which will return me the index of current row and rest of the columns are filled by SetStringItem() method.But that gives me TypeError: String or Unicode type required.How do i accomplish this?
def OnSearch(self, event):
placeholder = '?'
placeholders = ','.join(placeholder for unused in self.molecule_list)
query = 'SELECT * FROM MOLECULE WHERE MOL_NUMBER IN (%s)' % placeholders
cursor = self.conn.execute(query, self.molecule_list)
final = cursor.fetchall()
print final
for j in final:
index = self.list.InsertStringItem(sys.maxint, j[0])
self.list.SetStringItem(index, 1, j[1])
self.list.SetStringItem(index, 2, j[2])
You are iterating over the cursor, rather than the data which was returned in the variable final. Swap over to iterate using final
index = 0
for j in final:
index = self.list.InsertStringItem(index, str(j[0]))
self.list.SetStringItem(index, 1, j[1])
self.list.SetStringItem(index, 2, j[2])
index +=1
The easiest way, is to ensure that the ListCtrl has a style=wx.LC_REPORT and then use Append.
for j in final:
self.list.Append((j[0],j[1],j[2],j[3]))
Where j[n] is each item you require from the data for the number of items in the ListCtrl. I hope that makes sense.
Here is an example showing both methods
import wx
class MyForm(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, wx.ID_ANY, "Molecules")
panel = wx.Panel(self, wx.ID_ANY)
self.index = 0
self.list_ctrl = wx.ListCtrl(panel, size=(-1,100),
style=wx.LC_REPORT
)
self.list_ctrl.InsertColumn(0, 'Number')
self.list_ctrl.InsertColumn(1, 'Element')
self.list_ctrl.InsertColumn(2, 'Make up')
btn = wx.Button(panel, label="Add data")
btn.Bind(wx.EVT_BUTTON, self.add_lines)
btn2 = wx.Button(panel, label="Append data")
btn2.Bind(wx.EVT_BUTTON, self.app_lines)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.list_ctrl, 0, wx.ALL|wx.EXPAND, 5)
sizer.Add(btn, 0, wx.ALL|wx.CENTER, 5)
sizer.Add(btn2, 0, wx.ALL|wx.CENTER, 5)
panel.SetSizer(sizer)
def add_lines(self, event):
data = [[7, 'GLUCOSE', 'C6H1206'],[8,'SUCROSE', 'C12H22O11']]
index = 0
for j in data:
self.list_ctrl.InsertStringItem(index, str(j[0]))
self.list_ctrl.SetStringItem(index, 1, j[1])
self.list_ctrl.SetStringItem(index, 2, j[2])
index += 1
def app_lines(self, event):
data = [[7, 'GLUCOSE', 'C6H1206'],[8,'SUCROSE', 'C12H22O11']]
for j in data:
self.list_ctrl.Append((j[0],j[1],j[2]))
if __name__ == "__main__":
app = wx.App(False)
frame = MyForm()
frame.Show()
app.MainLoop()

Generate a bunch of tkinter checkbuttons and read the status of all those radio buttons at once

I have a tkinter class which reads some data into a couple of lists. From this now i have created a dictionary for creating checkbuttons.
I'm trying to create those checkbuttons in a new window() with a button to submit and read the stutus of those. I want this data to process.
def get_data(self):
self.flags = ["one","two","three", "four"]
self.tests = ["Jack","Queen","King","Ace"]
self.value = [11,12,13,1]
self.dict1 = {k:v for k,v in enumerate(self.flags,1)}
def get_status(self):
self.selectWindow = Toplevel(root)
self.selectWindow.title("Select Test Cases")
Submit_btn = Button(selectWindow, text="Submit", command=read_status )
for testcase in self.dict1:
self.dict1[testcase] = Variable()
l = Checkbutton(self.selectWindow,text=self.dict1[testcase], variable=self.dict1[testcase])
l.pack()
def read_status(self):
pass
From here I'm not able go ahead and read the status of checkbuttons and get those are checked. I need this data for further processing on tests(not actual lists given here I have few more). How to solve? Please let me know.
Checkbutton has a built in command function that can solve this problem. Every time you press a button that function is called, and you can print out the values of the buttons (0,1)
def get_data(self):
self.flags = ["one","two","three", "four"]
self.tests = ["Jack","Queen","King","Ace"]
self.value = [11,12,13,1]
self.dict1 = {k:v for k,v in enumerate(self.flags,1)}
def get_status(self):
self.selectWindow = Toplevel(self)
self.selectWindow.title("Select Test Cases")
self.get_data()
Submit_btn = Button(self.selectWindow, text="Submit", command=read_status ) # This button should be packed
Submit_btn.pack()
for testcase in self.dict1:
self.dict1[testcase] = Variable()
l = Checkbutton(self.selectWindow,text=self.dict1[testcase], variable=self.dict1[testcase], command=self.read_status) # Note the command
l.pack()
self.selectWindow.mainloop()
# Here comes the interesting part
def read_status(self):
for i,j in self.dict1.iteritems():
print j.get()
You forgot to use self and pack method:
Submit_btn = Button(self.selectWindow, text="Submit", command=self.read_status )
Submit_btn.pack()
Checkbutton's states are (0, 1) so use IntVar() to inspect the state:
...
self.dict1[testcase] = IntVar()
...
Then use IntVar get method:
def read_status(self):
for v in self.dict1:
print self.dict1[v].get()

Getting selected items from a Tkinter listbox without using a listbox bind

I have 2 listboxes (which are connected so that items can move from one to the other) and at the end I would like to get all the entries in the second listbox by using a 'Ok' button (or simply closing the frame). I could add/remove values to a list every time an item is selected (as shown in the commented section of the code below) but I would rather have a single line of code along the lines of [master.selected.get(idx) for idx in master.selected.curselection()] in the close function but I am unable to get it working.
Code:
def measurementPopup(self,master):
self.chargeCarrier = StringVar()
self.massModifiers = StringVar()
self.chargeCarrier.set("[M+xH]")
def onselect1(evt):
w = evt.widget
index = int(w.curselection()[0])
value = w.get(index)
# My Dirty fix -> Here I could enter the selected value to a buffer list (to be returned in the ok function).
master.selected.insert(END,value)
master.avail.delete(index)
def onselect2(evt):
w = evt.widget
index = int(w.curselection()[0])
value = w.get(index)
# My Dirty fix -> Here I could remove the selected value from a buffer list (to be returned in the ok function).
master.selected.delete(index)
master.avail.insert(END,value)
def close(self):
# Here I would return the buffer list and close the window
master.measurementWindow = 0
top.destroy()
if master.measurementWindow == 1:
return
master.measurementWindow = 1
top = self.top = Toplevel()
top.protocol( "WM_DELETE_WINDOW", lambda: close(self))
self.charge = Label(top, text = "Charge", width = 10)
self.charge.grid(row = 0, column = 0, sticky = W)
self.min = Label(top, text = "Min", width = 5)
self.min.grid(row=0, column = 1, sticky = W)
self.minCharge = Spinbox(top, from_= 1, to = 3, width = 5)
self.minCharge.grid(row = 0, column = 2, sticky = W)
self.max = Label(top, text = "Max", width = 5)
self.max.grid(row = 0, column = 3, sticky = W)
self.maxCharge = Spinbox(top, from_ = 1, to=3, width=5)
self.maxCharge.grid(row = 0, column = 4, sticky = W)
self.chargeCarrier = OptionMenu(top, self.chargeCarrier, "[M+xH]", "[M+xNa]")
self.chargeCarrier.grid(row = 0, column = 5, sticky = W)
self.availMass = Label(top, text = "Available")
self.availMass.grid(row = 1, column = 1, sticky = W)
self.selectMass = Label(top, text = "Selected")
self.selectMass.grid(row = 1, column = 3, sticky = W)
self.massMod = Label(top, text = "Mass Mods")
self.massMod.grid(row = 2, column = 0, sticky = W)
self.avail = Listbox(top)
for i in UNITS:
if BLOCKS[i]['available'] == 1:
self.avail.insert(END,BLOCKS[i]['human_readable_name'])
self.avail.grid(row = 2, column = 1, columnspan = 2, sticky = W)
self.avail.bind('<<ListboxSelect>>',onselect1)
self.selected = Listbox(top)
self.selected.grid(row = 2, column = 3, columnspan = 2, sticky = W)
self.selected.bind('<<ListboxSelect>>',onselect2)
self.ok = Button(top,text = 'Ok',command = lambda: close(self))
self.ok.grid(row = 3, column = 0, sticky = W)
I have tried to use the following small snippet in the close function:
values = [master.selected.get(idx) for idx in master.selected.curselection()]
print ', '.join(values)
However, the for segment doesn't return anything. I would expect that this is due to the fact that nothing is actually selected but that I would need something opposite, along the lines of master.selected.allitems() (if it exists and if I understand it correctly).
Summary
How would one get all the items in 1 specific listbox?
The .get() function for the Listbox widget allows you to specify a range of items, which can be specified as 0 to END to return a tuple of all the items.
Example:
from Tkinter import *
root = Tk()
l = Listbox(root, width = 15)
l.pack()
l.insert(END, "Hello")
l.insert(END, "world")
l.insert(END, "here")
l.insert(END, "is")
l.insert(END, "an")
l.insert(END, "example")
def close():
global l, root
items = l.get(0, END)
print(items)
root.destroy()
b = Button(root, text = "OK", command = close).pack()
root.mainloop()
I hope this helps, if it's not what you were looking for let me know in a comment and I can try expand my answer.

check entry inputs in tkinter using a function

I trying to create physics calculator using python tkinter but I find it quite difficult. I have done this calculator in Command line interface but I a bit different with tkinter. basically, I have 5 entry boxes and above each one of them a button. the user will insert values in three of them and should press the button on top of each unknown value to make the calculation and get the result. my main issue is how can I create a function that evaluates the inputs in my entry boxes and make the calculation then print the results inside the entry box. I made some coding but unfortunately the operation is not working due to few mistakes.
here is my coding part:
from Tkinter import *
import math
class calculator():
def is_positive_number(number): # validation function
if number <= 0:
return False
else :
return True
def value_of_time(prompt):
while True: # loop command for time
try:
valid = False
while not valid:
value = float((prompt))
if is_positive_number(value):
valid = True
return value
else :
valid = False
print ('I donot know what is happening')
except ValueError:
print("Oops, unfortunately this is a wrong input, please try again.")
#better try again... Return to the start of the loop
continue
else:
#value was successfully parsed!
#we're ready to exit the loop.
break
def input_of_box(prompt):
while True: # loop for initial velocity
try:
value = float(input(prompt))
return value
except ValueError:
print("Oops, we are you not typing a number, please try again.")
#better try again... Return to the start of the loop
continue
else:
#value was successfully parsed!
#we're ready to exit the loop.
break
# def minput(numberofinput):
if numberofinput == 1:
t = value_of_time("Enter the time that takes an object to accelerate in seconds:")
return
elif numberofinput == 2:
u = input_of_box("Enter the initial velocity in m/s:")
return
elif numberofinput == 2:
v = input_of_box("Enter the final velocity in m/s:")
return
def my_calculation(mvariables): # this function is to operate the calculation
if mvariables == 1:
a = (v-u) /(t)
mentery1 = a
return
elif mvariables == 2:
v = u + a*t
mentery2 = v
return
elif mvariables == 3:
u = a*t - v
mentery3 = t
elif mvariables == 4:
t = (v - u)/a
mentery3 = t
return
elif mvariables == 5:
s = (v**2-u**2)/2*a
mentery4 = s
else:
print ('there is an error')
cal = Tk()
cal.configure(background='sky blue')
a = StringVar()
u = StringVar()
v = StringVar()
t = StringVar()
s = StringVar()
cal.geometry('650x420+350+225')
cal.title('Main Menu')
# here we start greating buttons and entry boxes
m_label = Label(text='Calculator',fg = 'Navy', font=("Helvetica", 20,"bold italic"), bg='sky blue')
m_label.pack()
button1 = Button(cal,text='A',fg='white',bg='dark green',bd =3, width=4, command= lambda : my_calculation(1))
button1.place(x=92,y=210)
mentery1 = Entry(cal, textvariable = a ,width=10,bd =3)
mentery1.place(x=82,y=240)
button2 = Button(cal,text='U',fg='white',bg='dark green',bd =3, width=4, command= lambda : my_calculation(3))
button2.place(x=192,y=210)
mentery2 = Entry(cal, textvariable = u ,width=10,bd =3)
mentery2.place(x=182,y=240)
button3 = Button(cal,text='V',fg='white',bg='dark green',bd =3, width=4, command= lambda : my_calculation(2))
button3.place(x=292,y=210)
mentery3 = Entry(cal, textvariable = v ,width=10,bd =3)
mentery3.place(x=282,y=240)
button4 = Button(cal,text='T',fg='white',bg='dark green',bd =3, width=4,command= lambda : my_calculation(4))
button4.place(x=392,y=210)
mentery4 = Entry(cal, textvariable = t ,width=10,bd =3)
mentery4.place(x=382,y=240)
button5 = Button(cal,text='S',fg='white',bg='dark green',bd =3, width=4,command= lambda : my_calculation(5))
button5.place(x=492,y=210)
mentery5 = Entry(cal, textvariable = s , width=10,bd =3)
mentery5.place(x=482,y=240)
# end of button commands
app = calculator()
app.mainloop()
For validating the input, do the following:
def returnValidatedInput(entry):
value = entry.get() # Get the text in the 'entry' widget
evaluation = eval(value) # Evaluate 'value'
return evaluation
And for inserting the answers into the entries (it's not called printing the answers into the entries):
def insertAnswer(entry, answer):
entry.delete(0, 'end') # Be sure the entry is empty, if it is not, clear it
entry.insert(END, str(answer)) # Insert the answer into the 'entry' widget.

Tkinter and displaying iterating list

I have the following code:
from Tkinter import *
import itertools
l1 = [1, 'One', [[1, '1', '2'], [2, '3', '4'], [3, '5', '6']]]
l2 = [2, 'Two', [[1, 'one', 'two'], [2, 'three', 'four'], [3, 'five', 'six']]]
def session(evt,contents):
def setup_cards():
cards = [stack[2] for stack in contents]
setup = [iter(stack) for stack in cards]
return cards, setup
def end():
window.destroy()
def start():
print setup
print cards
pair = next(setup[0])
def flip():
side2cont.set(pair[2])
flipbutton.configure(command=start)
for stack in setup:
try:
for card in cards:
try:
side1cont.set(pair[1])
flipbutton.configure(command=flip)
except StopIteration:
continue
except StopIteration:
pair = next(setup[1])
window = Toplevel()
window.grab_set()
window.title("Session")
card_frame = Frame(window)
card_frame.grid(row=0, column=0, sticky=W, padx=2, pady=2)
button_frame = Frame(window)
button_frame.grid(row=1, column=0, pady=(5,0), padx=2)
side1_frame = LabelFrame(card_frame, text="Side 1")
side1_frame.grid(row=0, column=0)
side1cont = StringVar()
side2cont = StringVar()
side1 = Label(side1_frame, textvariable=side1cont)
side1.grid(row=0, column=0, sticky=W)
side2_frame = LabelFrame(card_frame, text="Side 2")
side2_frame.grid(row=1, column=0)
side2 = Label(side2_frame, textvariable=side2cont)
side2.grid(row=0, column=0, sticky=W)
flipbutton = Button(button_frame, text="Flip", command=start)
flipbutton.grid(row=0, column=2)
finishbutton = Button(button_frame, text="End", command=end)
finishbutton.grid(row=0,column=0, sticky=E)
cards = setup_cards()[0]
setup = setup_cards()[1]
w = Tk()
wbutton = Button(text='toplevel')
wbutton.bind('<Button-1>', lambda evt, args=(l1, l2): session(evt, args))
wbutton.pack()
w.mainloop()
It is piece of my project, I remade it just to the basics so it's easy to understand. In my project, function session accepts files, these are now emulated as lists l1 and l2.
The point where I am struggling is when I hit StopIteration exception. I would like my script to do the following:
1. When iteration reaches end, switch to another iterator (next item in setup list, in this case l2 iterator).
2. If no other iterators are present in setup, reset the iterator ("start over from the beginning").
The code above is the best I was able to come up with, that's why I'm turning to you folks. Thank you (also I'm newbie so I'm still struggling with basics of Python/programming in general).
StopIteration is caught by for and not propagated further. You may want to use for…else.
But your methods of iteration are weird, why not just use regular for loops?