sas.sascalc.data_util package

Submodules

sas.sascalc.data_util.calcthread module

class sas.sascalc.data_util.calcthread.CalcCommandline(n=20000)

Bases: object

Test method

__dict__ = mappingproxy({'__module__': 'sas.sascalc.data_util.calcthread', '__doc__': '\n        Test method\n    ', '__init__': <function CalcCommandline.__init__>, 'update': <function CalcCommandline.update>, 'complete': <function CalcCommandline.complete>, '__dict__': <attribute '__dict__' of 'CalcCommandline' objects>, '__weakref__': <attribute '__weakref__' of 'CalcCommandline' objects>, '__annotations__': {}})
__doc__ = '\n        Test method\n    '
__init__(n=20000)
__module__ = 'sas.sascalc.data_util.calcthread'
__weakref__

list of weak references to the object

complete(total=0.0)
update(i=0)
class sas.sascalc.data_util.calcthread.CalcDemo(completefn: Callable | None = None, updatefn: Callable | None = None, yieldtime=0.01, worktime=0.01, exception_handler: Callable | None = None)

Bases: CalcThread

Example of a calculation thread.

__annotations__ = {}
__doc__ = 'Example of a calculation thread.'
__module__ = 'sas.sascalc.data_util.calcthread'
compute(n)

Perform a work unit. The subclass will provide details of the arguments.

class sas.sascalc.data_util.calcthread.CalcThread(completefn: Callable | None = None, updatefn: Callable | None = None, yieldtime=0.01, worktime=0.01, exception_handler: Callable | None = None)

Bases: object

Threaded calculation class. Inherit from here and specialize the compute() method to perform the appropriate operations for the class.

If you specialize the __init__ method be sure to call CalcThread.__init__, passing it the keyword arguments for yieldtime, worktime, update and complete.

When defining the compute() method you need to include code which allows the GUI to run. They are as follows:

self.isquit()          # call frequently to check for interrupts
self.update(kw=...)    # call when the GUI could be updated
self.complete(kw=...)  # call before exiting compute()

The update() and complete() calls accept field=value keyword arguments which are passed to the called function. complete() should be called before exiting the GUI function. A KeyboardInterrupt event is triggered if the GUI signals that the computation should be halted.

The following documentation should be included in the description of the derived class.

The user of this class will call the following:

thread = Work(...,kw=...)  # prepare the work thread.
thread.queue(...,kw=...)   # queue a work unit
thread.requeue(...,kw=...) # replace work unit on the end of queue
thread.reset(...,kw=...)   # reset the queue to the given work unit
thread.stop()              # clear the queue and halt
thread.interrupt()         # halt the current work unit but continue
thread.ready(delay=0.)     # request an update signal after delay
thread.isrunning()         # returns true if compute() is running

Use queue() when all work must be done. Use requeue() when intermediate work items don’t need to be done (e.g., in response to a mouse move event). Use reset() when the current item doesn’t need to be completed before the new event (e.g., in response to a mouse release event). Use stop() to halt the current and pending computations (e.g., in response to a stop button).

The methods queue(), requeue() and reset() are proxies for the compute() method in the subclass. Look there for a description of the arguments. The compute() method can be called directly to run the computation in the main thread, but it should not be called if isrunning() returns true.

The constructor accepts additional keywords yieldtime=0.01 and worktime=0.01 which determine the cooperative multitasking behaviour. Yield time is the duration of the sleep period required to give other processes a chance to run. Work time is the duration between sleep periods.

Notifying the GUI thread of work in progress and work complete is done with updatefn=updatefn and completefn=completefn arguments to the constructor. Details of the parameters to the functions depend on the particular calculation class, but they will all be passed as keyword arguments. Details of how the functions should be implemented vary from framework to framework.

For wx, something like the following is needed:

import wx, wx.lib.newevent
(CalcCompleteEvent, EVT_CALC_COMPLETE) = wx.lib.newevent.NewEvent()

# methods in the main window class of your application
def __init__():
    ...
    # Prepare the calculation in the GUI thread.
    self.work = Work(completefn=self.CalcComplete)
    self.Bind(EVT_CALC_COMPLETE, self.OnCalcComplete)
    ...
    # Bind work queue to a menu event.
    self.Bind(wx.EVT_MENU, self.OnCalcStart, id=idCALCSTART)
    ...

def OnCalcStart(self,event):
    # Start the work thread from the GUI thread.
    self.work.queue(...work unit parameters...)

def CalcComplete(self,**kwargs):
    # Generate CalcComplete event in the calculation thread.
    # kwargs contains field1, field2, etc. as defined by
    # the Work thread class.
    event = CalcCompleteEvent(**kwargs)
    wx.PostEvent(self, event)

def OnCalcComplete(self,event):
    # Process CalcComplete event in GUI thread.
    # Use values from event.field1, event.field2 etc. as
    # defined by the Work thread class to show the results.
    ...
__annotations__ = {}
__dict__ = mappingproxy({'__module__': 'sas.sascalc.data_util.calcthread', '__doc__': "Threaded calculation class.  Inherit from here and specialize\n    the compute() method to perform the appropriate operations for the\n    class.\n\n    If you specialize the __init__ method be sure to call\n    CalcThread.__init__, passing it the keyword arguments for\n    yieldtime, worktime, update and complete.\n\n    When defining the compute() method you need to include code which\n    allows the GUI to run.  They are as follows: ::\n\n        self.isquit()          # call frequently to check for interrupts\n        self.update(kw=...)    # call when the GUI could be updated\n        self.complete(kw=...)  # call before exiting compute()\n\n    The update() and complete() calls accept field=value keyword\n    arguments which are passed to the called function.  complete()\n    should be called before exiting the GUI function.  A KeyboardInterrupt\n    event is triggered if the GUI signals that the computation should\n    be halted.\n\n    The following documentation should be included in the description\n    of the derived class.\n\n    The user of this class will call the following: ::\n\n        thread = Work(...,kw=...)  # prepare the work thread.\n        thread.queue(...,kw=...)   # queue a work unit\n        thread.requeue(...,kw=...) # replace work unit on the end of queue\n        thread.reset(...,kw=...)   # reset the queue to the given work unit\n        thread.stop()              # clear the queue and halt\n        thread.interrupt()         # halt the current work unit but continue\n        thread.ready(delay=0.)     # request an update signal after delay\n        thread.isrunning()         # returns true if compute() is running\n\n    Use queue() when all work must be done.  Use requeue() when intermediate\n    work items don't need to be done (e.g., in response to a mouse move\n    event).  Use reset() when the current item doesn't need to be completed\n    before the new event (e.g., in response to a mouse release event).  Use\n    stop() to halt the current and pending computations (e.g., in response to\n    a stop button).\n\n    The methods queue(), requeue() and reset() are proxies for the compute()\n    method in the subclass.  Look there for a description of the arguments.\n    The compute() method can be called directly to run the computation in\n    the main thread, but it should not be called if isrunning() returns true.\n\n    The constructor accepts additional keywords yieldtime=0.01 and\n    worktime=0.01 which determine the cooperative multitasking\n    behaviour.  Yield time is the duration of the sleep period\n    required to give other processes a chance to run.  Work time\n    is the duration between sleep periods.\n\n    Notifying the GUI thread of work in progress and work complete\n    is done with updatefn=updatefn and completefn=completefn arguments\n    to the constructor.  Details of the parameters to the functions\n    depend on the particular calculation class, but they will all\n    be passed as keyword arguments.  Details of how the functions\n    should be implemented vary from framework to framework.\n\n    For wx, something like the following is needed::\n\n        import wx, wx.lib.newevent\n        (CalcCompleteEvent, EVT_CALC_COMPLETE) = wx.lib.newevent.NewEvent()\n\n        # methods in the main window class of your application\n        def __init__():\n            ...\n            # Prepare the calculation in the GUI thread.\n            self.work = Work(completefn=self.CalcComplete)\n            self.Bind(EVT_CALC_COMPLETE, self.OnCalcComplete)\n            ...\n            # Bind work queue to a menu event.\n            self.Bind(wx.EVT_MENU, self.OnCalcStart, id=idCALCSTART)\n            ...\n\n        def OnCalcStart(self,event):\n            # Start the work thread from the GUI thread.\n            self.work.queue(...work unit parameters...)\n\n        def CalcComplete(self,**kwargs):\n            # Generate CalcComplete event in the calculation thread.\n            # kwargs contains field1, field2, etc. as defined by\n            # the Work thread class.\n            event = CalcCompleteEvent(**kwargs)\n            wx.PostEvent(self, event)\n\n        def OnCalcComplete(self,event):\n            # Process CalcComplete event in GUI thread.\n            # Use values from event.field1, event.field2 etc. as\n            # defined by the Work thread class to show the results.\n            ...\n    ", '__init__': <function CalcThread.__init__>, 'queue': <function CalcThread.queue>, 'requeue': <function CalcThread.requeue>, 'reset': <function CalcThread.reset>, 'stop': <function CalcThread.stop>, 'interrupt': <function CalcThread.interrupt>, 'isrunning': <function CalcThread.isrunning>, 'ready': <function CalcThread.ready>, 'isquit': <function CalcThread.isquit>, 'update': <function CalcThread.update>, 'complete': <function CalcThread.complete>, 'compute': <function CalcThread.compute>, 'exception': <function CalcThread.exception>, '_run': <function CalcThread._run>, '__dict__': <attribute '__dict__' of 'CalcThread' objects>, '__weakref__': <attribute '__weakref__' of 'CalcThread' objects>, '__annotations__': {}})
__doc__ = "Threaded calculation class.  Inherit from here and specialize\n    the compute() method to perform the appropriate operations for the\n    class.\n\n    If you specialize the __init__ method be sure to call\n    CalcThread.__init__, passing it the keyword arguments for\n    yieldtime, worktime, update and complete.\n\n    When defining the compute() method you need to include code which\n    allows the GUI to run.  They are as follows: ::\n\n        self.isquit()          # call frequently to check for interrupts\n        self.update(kw=...)    # call when the GUI could be updated\n        self.complete(kw=...)  # call before exiting compute()\n\n    The update() and complete() calls accept field=value keyword\n    arguments which are passed to the called function.  complete()\n    should be called before exiting the GUI function.  A KeyboardInterrupt\n    event is triggered if the GUI signals that the computation should\n    be halted.\n\n    The following documentation should be included in the description\n    of the derived class.\n\n    The user of this class will call the following: ::\n\n        thread = Work(...,kw=...)  # prepare the work thread.\n        thread.queue(...,kw=...)   # queue a work unit\n        thread.requeue(...,kw=...) # replace work unit on the end of queue\n        thread.reset(...,kw=...)   # reset the queue to the given work unit\n        thread.stop()              # clear the queue and halt\n        thread.interrupt()         # halt the current work unit but continue\n        thread.ready(delay=0.)     # request an update signal after delay\n        thread.isrunning()         # returns true if compute() is running\n\n    Use queue() when all work must be done.  Use requeue() when intermediate\n    work items don't need to be done (e.g., in response to a mouse move\n    event).  Use reset() when the current item doesn't need to be completed\n    before the new event (e.g., in response to a mouse release event).  Use\n    stop() to halt the current and pending computations (e.g., in response to\n    a stop button).\n\n    The methods queue(), requeue() and reset() are proxies for the compute()\n    method in the subclass.  Look there for a description of the arguments.\n    The compute() method can be called directly to run the computation in\n    the main thread, but it should not be called if isrunning() returns true.\n\n    The constructor accepts additional keywords yieldtime=0.01 and\n    worktime=0.01 which determine the cooperative multitasking\n    behaviour.  Yield time is the duration of the sleep period\n    required to give other processes a chance to run.  Work time\n    is the duration between sleep periods.\n\n    Notifying the GUI thread of work in progress and work complete\n    is done with updatefn=updatefn and completefn=completefn arguments\n    to the constructor.  Details of the parameters to the functions\n    depend on the particular calculation class, but they will all\n    be passed as keyword arguments.  Details of how the functions\n    should be implemented vary from framework to framework.\n\n    For wx, something like the following is needed::\n\n        import wx, wx.lib.newevent\n        (CalcCompleteEvent, EVT_CALC_COMPLETE) = wx.lib.newevent.NewEvent()\n\n        # methods in the main window class of your application\n        def __init__():\n            ...\n            # Prepare the calculation in the GUI thread.\n            self.work = Work(completefn=self.CalcComplete)\n            self.Bind(EVT_CALC_COMPLETE, self.OnCalcComplete)\n            ...\n            # Bind work queue to a menu event.\n            self.Bind(wx.EVT_MENU, self.OnCalcStart, id=idCALCSTART)\n            ...\n\n        def OnCalcStart(self,event):\n            # Start the work thread from the GUI thread.\n            self.work.queue(...work unit parameters...)\n\n        def CalcComplete(self,**kwargs):\n            # Generate CalcComplete event in the calculation thread.\n            # kwargs contains field1, field2, etc. as defined by\n            # the Work thread class.\n            event = CalcCompleteEvent(**kwargs)\n            wx.PostEvent(self, event)\n\n        def OnCalcComplete(self,event):\n            # Process CalcComplete event in GUI thread.\n            # Use values from event.field1, event.field2 etc. as\n            # defined by the Work thread class to show the results.\n            ...\n    "
__init__(completefn: Callable | None = None, updatefn: Callable | None = None, yieldtime=0.01, worktime=0.01, exception_handler: Callable | None = None)
__module__ = 'sas.sascalc.data_util.calcthread'
__weakref__

list of weak references to the object

_run()

Internal function to manage the thread.

complete(**kwargs)

Update the GUI with the completed results from a work unit.

compute(*args, **kwargs)

Perform a work unit. The subclass will provide details of the arguments.

exception()

An exception occurred during computation, so call the exception handler if there is one. If not, then log the exception and continue.

interrupt()

Stop the current work item. To clear the work queue as well call the stop() method.

isquit()

Check for interrupts. Should be called frequently to provide user responsiveness. Also yields to other running threads, which is required for good performance on OS X.

isrunning()
queue(*args, **kwargs)

Add a work unit to the end of the queue. See the compute() method for details of the arguments to the work unit.

ready(delay=0.0)

Ready for another update after delay=t seconds. Call this for threads which can show intermediate results from long calculations.

requeue(*args, **kwargs)

Replace the work unit on the end of the queue. See the compute() method for details of the arguments to the work unit.

reset(*args, **kwargs)

Clear the queue and start a new work unit. See the compute() method for details of the arguments to the work unit.

stop()

Clear the queue and stop the thread. New items may be queued after stop. To stop just the current work item, and continue the rest of the queue call the interrupt method

update(**kwargs)

Update GUI with the lastest results from the current work unit.

sas.sascalc.data_util.pathutils module

Utilities for path manipulation. Not to be confused with the pathutils module from the pythonutils package (http://groups.google.com/group/pythonutils).

sas.sascalc.data_util.pathutils.join(path, *paths)
sas.sascalc.data_util.pathutils.relpath(p1, p2)

Compute the relative path of p1 with respect to p2.

sas.sascalc.data_util.pathutils.test()

Module contents