user2748626
user2748626

Reputation: 17

Python - successive random calls to the same method

On the following strip-down version of my program, I want to simulate an exchange where the user and the computer will act following a random sequence.

Here the variable row contains the sequence order. A value of 0 means the program is waiting for a user input (method val0). A value of 1 means there should be an automatic process (method val1).

It seems to work at the beginning when alternating 0 and 1 but as soon as we are waiting for two successive automatic calls, it goes out of whack.

I tried using the after method but I can't see how and where to insert it.

A while loop might do the trick on this example but the end program is more complex, with sequence interruption, reevaluation of the sequence and so on. So I don't know if it would still apply then.

    from tkinter import *

class Application:  
    def __init__(self,master = None):
        self.master = master
        Label(master,text='press next').grid()
        Button(master,text='Next',command=self.val0).grid()
        self.index = IntVar()
        self.index.set(0)
        self.index.trace("w",self.nextTurn)

    def val0(self):
        print("User action")
        self.index.set(self.index.get() +1)

    def val1(self):
        print("Automatic action")
        self.index.set(self.index.get() +1)

    def nextTurn(self, *args):
        i = self.index.get()
        if i >= len(row):
            self.master.destroy()
            return
        if row[i] == 1:
            self.val1()


if __name__ == "__main__":
    row = [0,1,0,0,1,1,0,0,0,1,1,1]
    root = Tk()
    win = Application(root)
    root.mainloop()

Upvotes: 1

Views: 66

Answers (1)

Isac
Isac

Reputation: 1874

You can easily solve your problem by calling the nextTurn directly in the automatic action function:

def val1(self):
    print("Automatic action")
    self.index.set(self.index.get() +1)
    self.nextTurn() # call nextTurn after this action

So if it was an automatic action, you step into the next row position, and call nextTurn again.

However this may become a problem if your row becomes too large because it uses recursion. In that case you will want another approach with the while you mentioned. For this second option you would only need to change nextTurn:

def nextTurn(self, *args):
    i = self.index.get()

    # while it is an automatic action and it has row values, keep calling val1
    while i < len(row) and row[i] == 1: 
        self.val1() # call automatic action
        i = self.index.get() #update the row position
    else:

        if i >= len(row):
            self.master.destroy()
            return

Upvotes: 1

Related Questions