getting a Python wx.gauge to work with SPSS

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

getting a Python wx.gauge to work with SPSS

mpirritano
Spsser's

Happy new year!

Here's the deal. I'm trying to get a wxpython gauge to signal the
beginning and ending of spss commands. Currently, I'm using the thread
command to run my spss commands while a gauge is running. The main
problem I'm having, and I recognize that this may be a symptom of larger
more basic pythonic problems (due to my inexperience), is that I cannot
get the gauge to sync with my spss process. I want it to start when an
spss process starts and end when it ends. Perhaps the thread command is
not appropriate here?

I have written this program to create a list of doctors from medical
claims data to be used in another module where I have set up check boxes
that trigger an analysis to be run for whatever doctor's box is checked.
The program is running with the SPSS Python-Integration Package, and is
running externally, not in SPSS. I just needed some indicator that the
process was running because it can take a long time (15, 20, or 30
minutes, depending on the size of the claims file which can be more than
4gb).

Okay, here's the syntax. Please excuse any sloppiness in my form. I'm
just
learning.

I really appreciate any help!


# Ask the user to select the AMM  file they would like to use
import wx, os, spss, sys, thread


class MyFrame(wx.Frame):
    def __init__(self, parent, title):
        wx.Frame.__init__(self, parent, -1, title,
                          pos=(350, 150), size=(250, 150))

        # Create the menubar
        menuBar = wx.MenuBar()

        # and a menu
        menu = wx.Menu()

        # Now create the Panel to put the other controls on.
        panel = wx.Panel(self)

        # and a few controls
        text = wx.StaticText(panel, -1, "I'm working on it!!!")
        text.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL, wx.BOLD))
        text.SetSize(text.GetBestSize())
        btn = wx.Button(panel, -1, "Close", (10,30))

        self.count = 0

        self.g2 = wx.Gauge(panel, -1 , 50, (50, 60), (125, 25))

        self.Bind(wx.EVT_END_PROCESS, self.on_end_process)
        self.Bind(wx.EVT_TIMER, self.TimerHandler)
        self.timer = wx.Timer(self)
        self.timer.Start(100)

        # bind the button events to handlers
        self.Bind(wx.EVT_BUTTON, self.OnTimeToClose, btn)

        # Use a sizer to layout the controls, stacked vertically and
with
        # a 10 pixel border around each
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(text, 0, wx.ALL, 10)
        panel.SetSizer(sizer)
        panel.Layout()

        self.chooserThread()

    def chooserThread(self):
        thread.start_new_thread(self.chooser,())


    def OnTimeToClose(self, evt):
        """Event handler for the button click."""
        print "See ya later!"
        self.Close

    def TimerHandler(self, event):
        self.count = self.count + 1

        if self.count >= 50:
            self.count = 0

        self.g2.Pulse()

    def on_end_process(self, event):
        self.Close(True)

    def onProvlistDone(self):

        self.gauge.abort
        self.Close
        self.kill

    def chooser(self):

        self.Close
        app = wx.PySimpleApp()

        self.infile = ''
        fileWildcard = "sav files (*.sav)|*.sav|" \
                        "All files (*.*)|*.*"
        dlg = wx.FileDialog(None,
                            message="Choose the file to derive list
from...",
                            defaultDir="d:/data/",
                            defaultFile="",
                            wildcard=fileWildcard,
                            style=wx.OPEN| wx.MULTIPLE | wx.CHANGE_DIR
                            )
        self.on_end_process
        if dlg.ShowModal() == wx.ID_OK:
            self.infile = dlg.GetPath()
        else:
            self.infile = None

        dlg.Destroy()
        app.Destroy()

        thread.start_new_thread(self.provlist,())




    def getfile(self):
        return self.infile


    def provlist(self):
        spss.Submit(r"""
        GET FILE= '%s'.
        save outfile = '%s'
            /compressed.
        get file = '%s'.
        SORT CASES BY license2.
        AGGREGATE
          /OUTFILE='D:\Data\AMM\providers\list.sav'
          /PRESORTED
          /BREAK=license2
          /N_BREAK=N.
        get file = 'D:\Data\AMM\providers\list.sav'.
        delete variables N_BREAK.
        """ % (self.infile, self.infile, self.infile))


        i = [0]
        dataCursor=spss.Cursor(i)
        oneVar=dataCursor.fetchall()
        dataCursor.close()
        uniqueCount=len(set(oneVar))
        licenses =[]
        i = [0]
        for i in range(uniqueCount):
             licenses.append(oneVar[i][:1][0])
        print licenses
        self.getfile
        print self.infile
        self.on_end_process

if __name__ == "__main__":
    app = wx.PySimpleApp()
    app.TopWindow = MyFrame(None, "Please be patient!")
    app.TopWindow.Show()
    app.MainLoop()


Matthew Pirritano, Ph.D.
Research Analyst IV
Medical Services Initiative (MSI)
Orange County Health Care Agency
(714) 568-5648

=====================
To manage your subscription to SPSSX-L, send a message to
[hidden email] (not to SPSSX-L), with no body text except the
command. To leave the list, send the command
SIGNOFF SPSSX-L
For a list of commands to manage subscriptions, send the command
INFO REFCARD
Reply | Threaded
Open this post in threaded view
|

Re: getting a Python wx.gauge to work with SPSS

Jon K Peck

You are using the thread module.  The threading module is higher level and might be easier to use.  However, with thread, the way to make this work is to first allocate a lock (thread.allocate_lock).  Have the thread running syntax acquire the lock and release it when it is done.

Meantime, your progress dialog would try to acquire the lock with a timeout of a second or so.  If it fails to acquire the lock (acquire returns False), poke your progress message (or let it keep running).
Once it succeeds in acquiring the lock, tear down the progress message and delete the lock.

You could keep this lock around and reuse this protocol if you have multiple instances where you need to wait.

If you used the threading module, you might do this  by having the syntax thread exit when it is done and using threading.join with a timeout to wait for it.

HTH,

Jon Peck
SPSS, an IBM Company
[hidden email]
312-651-3435


Caveat: I haven't used this type of threading to run SPSS syntax.  It would not work with V15 or earlier and maybe not with V16, but it probably works with later versions.


From: "Pirritano, Matthew" <[hidden email]>
To: [hidden email]
Date: 01/04/2010 09:30 AM
Subject: [SPSSX-L] getting a Python wx.gauge to work with SPSS
Sent by: "SPSSX(r) Discussion" <[hidden email]>





Spsser's

Happy new year!

Here's the deal. I'm trying to get a wxpython gauge to signal the
beginning and ending of spss commands. Currently, I'm using the thread
command to run my spss commands while a gauge is running. The main
problem I'm having, and I recognize that this may be a symptom of larger
more basic pythonic problems (due to my inexperience), is that I cannot
get the gauge to sync with my spss process. I want it to start when an
spss process starts and end when it ends. Perhaps the thread command is
not appropriate here?

I have written this program to create a list of doctors from medical
claims data to be used in another module where I have set up check boxes
that trigger an analysis to be run for whatever doctor's box is checked.
The program is running with the SPSS Python-Integration Package, and is
running externally, not in SPSS. I just needed some indicator that the
process was running because it can take a long time (15, 20, or 30
minutes, depending on the size of the claims file which can be more than
4gb).

Okay, here's the syntax. Please excuse any sloppiness in my form. I'm
just
learning.

I really appreciate any help!


# Ask the user to select the AMM  file they would like to use
import wx, os, spss, sys, thread


class MyFrame(wx.Frame):
   def __init__(self, parent, title):
       wx.Frame.__init__(self, parent, -1, title,
                         pos=(350, 150), size=(250, 150))

       # Create the menubar
       menuBar = wx.MenuBar()

       # and a menu
       menu = wx.Menu()

       # Now create the Panel to put the other controls on.
       panel = wx.Panel(self)

       # and a few controls
       text = wx.StaticText(panel, -1, "I'm working on it!!!")
       text.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL, wx.BOLD))
       text.SetSize(text.GetBestSize())
       btn = wx.Button(panel, -1, "Close", (10,30))

       self.count = 0

       self.g2 = wx.Gauge(panel, -1 , 50, (50, 60), (125, 25))

       self.Bind(wx.EVT_END_PROCESS, self.on_end_process)
       self.Bind(wx.EVT_TIMER, self.TimerHandler)
       self.timer = wx.Timer(self)
       self.timer.Start(100)

       # bind the button events to handlers
       self.Bind(wx.EVT_BUTTON, self.OnTimeToClose, btn)

       # Use a sizer to layout the controls, stacked vertically and
with
       # a 10 pixel border around each
       sizer = wx.BoxSizer(wx.VERTICAL)
       sizer.Add(text, 0, wx.ALL, 10)
       panel.SetSizer(sizer)
       panel.Layout()

       self.chooserThread()

   def chooserThread(self):
       thread.start_new_thread(self.chooser,())


   def OnTimeToClose(self, evt):
       """Event handler for the button click."""
       print "See ya later!"
       self.Close

   def TimerHandler(self, event):
       self.count = self.count + 1

       if self.count >= 50:
           self.count = 0

       self.g2.Pulse()

   def on_end_process(self, event):
       self.Close(True)

   def onProvlistDone(self):

       self.gauge.abort
       self.Close
       self.kill

   def chooser(self):

       self.Close
       app = wx.PySimpleApp()

       self.infile = ''
       fileWildcard = "sav files (*.sav)|*.sav|" \
                       "All files (*.*)|*.*"
       dlg = wx.FileDialog(None,
                           message="Choose the file to derive list
from...",
                           defaultDir="d:/data/",
                           defaultFile="",
                           wildcard=fileWildcard,
                           style=wx.OPEN| wx.MULTIPLE | wx.CHANGE_DIR
                           )
       self.on_end_process
       if dlg.ShowModal() == wx.ID_OK:
           self.infile = dlg.GetPath()
       else:
           self.infile = None

       dlg.Destroy()
       app.Destroy()

       thread.start_new_thread(self.provlist,())




   def getfile(self):
       return self.infile


   def provlist(self):
       spss.Submit(r"""
       GET FILE= '%s'.
       save outfile = '%s'
           /compressed.
       get file = '%s'.
       SORT CASES BY license2.
       AGGREGATE
         /OUTFILE='D:\Data\AMM\providers\list.sav'
         /PRESORTED
         /BREAK=license2
         /N_BREAK=N.
       get file = 'D:\Data\AMM\providers\list.sav'.
       delete variables N_BREAK.
       """ % (self.infile, self.infile, self.infile))


       i = [0]
       dataCursor=spss.Cursor(i)
       oneVar=dataCursor.fetchall()
       dataCursor.close()
       uniqueCount=len(set(oneVar))
       licenses =[]
       i = [0]
       for i in range(uniqueCount):
            licenses.append(oneVar[i][:1][0])
       print licenses
       self.getfile
       print self.infile
       self.on_end_process

if __name__ == "__main__":
   app = wx.PySimpleApp()
   app.TopWindow = MyFrame(None, "Please be patient!")
   app.TopWindow.Show()
   app.MainLoop()


Matthew Pirritano, Ph.D.
Research Analyst IV
Medical Services Initiative (MSI)
Orange County Health Care Agency
(714) 568-5648

=====================
To manage your subscription to SPSSX-L, send a message to
[hidden email] (not to SPSSX-L), with no body text except the
command. To leave the list, send the command
SIGNOFF SPSSX-L
For a list of commands to manage subscriptions, send the command
INFO REFCARD


Reply | Threaded
Open this post in threaded view
|

Re: getting a Python wx.gauge to work with SPSS

Albert-Jan Roskam
Hi,
 
Interesting thread (no pun intended!). Wouldn't it be clearer to put verything that's not related to the Gui in its own class? Also, I saw you used fetchall and then use set() on the resulting values. Doesn't that make the overhead of the dialog of the dialog very large?
 
Just some thoughts...  Could you post the code once you've got it working? I haven't used threading yet, but it's interesting to see a research-related example.

Cheers!!
Albert-Jan

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In the face of ambiguity, refuse the temptation to guess.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

--- On Mon, 1/4/10, Jon K Peck <[hidden email]> wrote:

From: Jon K Peck <[hidden email]>
Subject: Re: [SPSSX-L] getting a Python wx.gauge to work with SPSS
To: [hidden email]
Date: Monday, January 4, 2010, 6:08 PM


You are using the thread module.  The threading module is higher level and might be easier to use.  However, with thread, the way to make this work is to first allocate a lock (thread.allocate_lock).  Have the thread running syntax acquire the lock and release it when it is done.

Meantime, your progress dialog would try to acquire the lock with a timeout of a second or so.  If it fails to acquire the lock (acquire returns False), poke your progress message (or let it keep running).
Once it succeeds in acquiring the lock, tear down the progress message and delete the lock.

You could keep this lock around and reuse this protocol if you have multiple instances where you need to wait.

If you used the threading module, you might do this  by having the syntax thread exit when it is done and using threading.join with a timeout to wait for it.

HTH,

Jon Peck
SPSS, an IBM Company
[hidden email]
312-651-3435


Caveat: I haven't used this type of threading to run SPSS syntax.  It would not work with V15 or earlier and maybe not with V16, but it probably works with later versions.


From: "Pirritano, Matthew" <[hidden email]>
To: [hidden email]
Date: 01/04/2010 09:30 AM
Subject: [SPSSX-L] getting a Python wx.gauge to work with SPSS
Sent by: "SPSSX(r) Discussion" <[hidden email]>





Spsser's

Happy new year!

Here's the deal. I'm trying to get a wxpython gauge to signal the
beginning and ending of spss commands. Currently, I'm using the thread
command to run my spss commands while a gauge is running. The main
problem I'm having, and I recognize that this may be a symptom of larger
more basic pythonic problems (due to my inexperience), is that I cannot
get the gauge to sync with my spss process. I want it to start when an
spss process starts and end when it ends. Perhaps the thread command is
not appropriate here?

I have written this program to create a list of doctors from medical
claims data to be used in another module where I have set up check boxes
that trigger an analysis to be run for whatever doctor's box is checked.
The program is running with the SPSS Python-Integration Package, and is
running externally, not in SPSS. I just needed some indicator that the
process was running because it can take a long time (15, 20, or 30
minutes, depending on the size of the claims file which can be more than
4gb).

Okay, here's the syntax. Please excuse any sloppiness in my form. I'm
just
learning.

I really appreciate any help!


# Ask the user to select the AMM  file they would like to use
import wx, os, spss, sys, thread


class MyFrame(wx.Frame):
   def __init__(self, parent, title):
       wx.Frame.__init__(self, parent, -1, title,
                         pos=(350, 150), size=(250, 150))

       # Create the menubar
       menuBar = wx.MenuBar()

       # and a menu
       menu = wx.Menu()

       # Now create the Panel to put the other controls on.
       panel = wx.Panel(self)

       # and a few controls
       text = wx.StaticText(panel, -1, "I'm working on it!!!")
       text.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL, wx.BOLD))
       text.SetSize(text.GetBestSize())
       btn = wx.Button(panel, -1, "Close", (10,30))

       self.count = 0

       self.g2 = wx.Gauge(panel, -1 , 50, (50, 60), (125, 25))

       self.Bind(wx.EVT_END_PROCESS, self.on_end_process)
       self.Bind(wx.EVT_TIMER, self.TimerHandler)
       self.timer = wx.Timer(self)
       self.timer.Start(100)

       # bind the button events to handlers
       self.Bind(wx.EVT_BUTTON, self.OnTimeToClose, btn)

       # Use a sizer to layout the controls, stacked vertically and
with
       # a 10 pixel border around each
       sizer = wx.BoxSizer(wx.VERTICAL)
       sizer.Add(text, 0, wx.ALL, 10)
       panel.SetSizer(sizer)
       panel.Layout()

       self.chooserThread()

   def chooserThread(self):
       thread.start_new_thread(self.chooser,())


   def OnTimeToClose(self, evt):
       """Event handler for the button click."""
       print "See ya later!"
       self.Close

   def TimerHandler(self, event):
       self.count = self.count + 1

       if self.count >= 50:
           self.count = 0

       self.g2.Pulse()

   def on_end_process(self, event):
       self.Close(True)

   def onProvlistDone(self):

       self.gauge.abort
       self.Close
       self.kill

   def chooser(self):

       self.Close
       app = wx.PySimpleApp()

       self.infile = ''
       fileWildcard = "sav files (*.sav)|*.sav|" \
                       "All files (*.*)|*.*"
       dlg = wx.FileDialog(None,
                           message="Choose the file to derive list
from...",
                           defaultDir="d:/data/",
                           defaultFile="",
                           wildcard=fileWildcard,
                           style=wx.OPEN| wx.MULTIPLE | wx.CHANGE_DIR
                           )
       self.on_end_process
       if dlg.ShowModal() == wx.ID_OK:
           self.infile = dlg.GetPath()
       else:
           self.infile = None

       dlg.Destroy()
       app.Destroy()

       thread.start_new_thread(self.provlist,())




   def getfile(self):
       return self.infile


   def provlist(self):
       spss.Submit(r"""
       GET FILE= '%s'.
       save outfile = '%s'
           /compressed.
       get file = '%s'.
       SORT CASES BY license2.
       AGGREGATE
         /OUTFILE='D:\Data\AMM\providers\list.sav'
         /PRESORTED
         /BREAK=license2
         /N_BREAK=N.
       get file = 'D:\Data\AMM\providers\list.sav'.
       delete variables N_BREAK.
       """ % (self.infile, self.infile, self.infile))


       i = [0]
       dataCursor=spss.Cursor(i)
       oneVar=dataCursor.fetchall()
       dataCursor.close()
       uniqueCount=len(set(oneVar))
       licenses =[]
       i = [0]
       for i in range(uniqueCount):
            licenses.append(oneVar[i][:1][0])
       print licenses
       self.getfile
       print self.infile
       self.on_end_process

if __name__ == "__main__":
   app = wx.PySimpleApp()
   app.TopWindow = MyFrame(None, "Please be patient!")
   app.TopWindow.Show()
   app.MainLoop()


Matthew Pirritano, Ph.D.
Research Analyst IV
Medical Services Initiative (MSI)
Orange County Health Care Agency
(714) 568-5648

=====================
To manage your subscription to SPSSX-L, send a message to
[hidden email] (not to SPSSX-L), with no body text except the
command. To leave the list, send the command
SIGNOFF SPSSX-L
For a list of commands to manage subscriptions, send the command
INFO REFCARD