from sage.all_cmdline import *
_sage_const_3 = Integer(3); _sage_const_2 = Integer(2); _sage_const_1 = Integer(1); _sage_const_0 = Integer(0); _sage_const_5 = Integer(5); _sage_const_4 = Integer(4); _sage_const_1000 = Integer(1000)
from lib.enum import Enum
from datetime import datetime
import traceback
import sys
class TsLevel(Enum):
Silent = _sage_const_0
StackInfo = _sage_const_1
Body = _sage_const_2
BodySub1 = _sage_const_3
BodySub2 = _sage_const_4
Debug = _sage_const_5
def print_time_tb( Text="", Info="", MaxDepth = _sage_const_1 , Offset = _sage_const_1 , Level = TsLevel.Silent, ShowDateTime = True ):
"""
This is a utility to implement a time-stamp debugging in any function
Whenever this function is called it prints the actual timestamp together with traceback information.
If you don't see this well formatted type
sage: print print_time_tb.__doc__
INPUT (all optional keywords):
- "Text": string describing the code position
- "Info": string containing further information (for instance on elapse time)
- "MaxDepth": integer representing the number of traceback steps (top down) to be printed
- "Offset": integer representing the number of traceback steps (top down) to be ignored
- "Level": Constants with integer value (substitutes enum type): classifies the position of invocation. The
following values are possible:
constant integer usage
--------------------------------------------------------------------------------------------------
TsLevel.Silent: 0, a message to be printed always
TsLevel.StackInfo: 1, indicating function / method entry or exit. typical Text = "Begin", "End"
TsLevel.Body: 2, indicating a position in the Body of a function / method
TsLevel.BodySub1: 3, similar to the former but subordinary to it
TsLevel.BodySub2: 4, similar to the former but subordinary to it
TsLevel.Debug: 5, Debug message
- "ShowDateTime": boolean (Default = True). If set to False the date and time part of the message is supressed
OUTPUT:
only prints, no return value
EXAMPLES:
sage: print_time_tb( Text="Hello", Info="Test" )
L: Silent Time 2016-10-06 18:30:22.574296 Test Hello In: <module> Line: 1
sage:
using the Level option
sage: print_time_tb( Text="Hello", Info="Test", Level = TsLevel.StackInfo )
L: StackInfo Time 2016-10-06 18:31:58.569208 Test Hello In: <module> Line: 1
sage:
using the MaxDepth option
sage:
sage: print_time_tb( Text="Hello", Info="Test", MaxDepth = 2, Level = TsLevel.StackInfo )
L: StackInfo Time 2016-10-06 18:32:21.537412 Test Hello In: <module> Line: 1
---> run_code In: /opt/sage/sage-6.9-i686-Linux/local/lib/python2.7/site-packages/IPython/core/
interactiveshell.py Line: 3066
sage: print_time_tb( Text="Hello", Info="Test", MaxDepth = 3, Level = TsLevel.StackInfo )
L: StackInfo Time 2016-10-06 18:32:31.292799 Test Hello In: <module> Line: 1
---> run_code In: /opt/sage/sage-6.9-i686-Linux/local/lib/python2.7/site-packages/IPython/core/
interactiveshell.py Line: 3066
---> run_ast_nodes In: /opt/sage/sage-6.9-i686-Linux/local/lib/python2.7/site-packages/IPython/core/
interactiveshell.py Line: 3012
using the Offset option
sage: print_time_tb( Text="Hello", Info="Test", MaxDepth = 3, Offset = 2, Level = TsLevel.StackInfo )
L: StackInfo Time 2016-10-06 18:33:20.339336 Test Hello In: run_code Line: 3066
---> run_ast_nodes In: /opt/sage/sage-6.9-i686-Linux/local/lib/python2.7/site-packages/IPython/core/
interactiveshell.py Line: 3012
---> run_cell In: /opt/sage/sage-6.9-i686-Linux/local/lib/python2.7/site-packages/IPython/core/
interactiveshell.py Line: 2902
AUTHOR
- Sebastian Oehms, Oct. 2016
"""
intLevel = Level.value
TraceBack = traceback.extract_stack()
LenTb = len(TraceBack)
if LenTb < _sage_const_1 +Offset:
return
TraceBackEntry = TraceBack[LenTb-_sage_const_1 -Offset]
TraceBackEntryModule = TraceBackEntry[_sage_const_0 ]
TraceBackEntryLineNo = TraceBackEntry[_sage_const_1 ]
TraceBackEntryFunction = TraceBackEntry[_sage_const_2 ]
DateTime =''
if ShowDateTime == True:
DateTime = str(datetime.today())
print "L: %-12s: %s %s %s In: %s Line: %s"%(Level.name, DateTime, Info, Text, TraceBackEntryFunction, TraceBackEntryLineNo )
for i in range( MaxDepth -_sage_const_1 ):
TraceBackEntry = TraceBack[LenTb-_sage_const_2 -Offset-i]
TraceBackEntryModule = TraceBackEntry[_sage_const_0 ]
TraceBackEntryLineNo = TraceBackEntry[_sage_const_1 ]
TraceBackEntryFunction = TraceBackEntry[_sage_const_2 ]
print " --->", TraceBackEntryFunction, "In:", TraceBackEntryModule, "Line:", TraceBackEntryLineNo
if TraceBackEntryFunction == "<module>":
break
return
class timeStampControl:
"""
This class controls a consistent use of the print_time_tb function
If you don't see this well formatted type
sage: print timeStampControl.__doc__
to learn more about the function print_time_tb type
sage: print print_time_tb.__doc__
The printing of messages is done be the method "print_timestamp". But only those messages are printed which
agree with the verbose level of the "timeStampControl"-instance which can be desribed by the constructor parameters
- "KeepSilentOnElapse"
- "TimeStampLevel":
To learn more about the printing method type
sage: timeStampControl.print_timestamp.__doc__
INPUT (to the constructor):
- "KeepSilentOnElapse": integer representing milli-seconds (default is 0). If this is set to a positive value only
those messages are printed which firstly occur after the indicated number of milli-seconds
behind the former printed message
- "TimeStampLevel": Member of Enum-class TsLevel. For possible values see the values of
the Level parameter of the function (print_time_tb). To see this type
"sage: print print_time_tb.__doc__"
Default value is TsLevel.Silent meaning that only messages of Level TsLevel.Silent are printed.
If this is set to another value only those messages are printed, whose integer value of
"Level" is less or equal to "TimeStampLevel".
- "TraceBackDepth": integer representing number of lines of traceback information to be printed (top down,
default is 1). This parameter is passed to the corresponding parameter of the
print_time_tb function
- "Offset": integer representing number of lines of traceback information to be ignored (top down,
default is 1). This parameter is passed to the corresponding parameter of the
print_time_tb function after increasing it by one (supress the traceback information of
the print_timestamp method itselfe).
- "ShowDateTime": boolean (Default = True). If set to False the date and time part of the message is supressed
RAISE (on construction):
- TypeError "KeepSilentOnElapse must be of type Integer"
- TypeError "TraceBackDepth must be of type Integer"
- TypeError "Offset must be of type Integer"
- ValueError "TimeStampLevel must be a member of Enum TsLevel"
- ValueError "KeepSilentOnElapse must be non negative"
- ValueError "TraceBackDepth must be non negative"
- ValueError "Offset must be non negative"
EXAMPLES:
sage: TestTimeStampControl = timeStampControl( )
sage: TestTimeStampControl.print_timestamp(Text="Look")
L: Silent Time 2016-10-07 18:20:21.827425 Elapse: 5581, Total: 5 Look In: <module> Line: 1
using KeepSilentOnElapse:
sage: TestTimeStampControl2 = timeStampControl( KeepSilentOnElapse = 2000 )
sage: TestTimeStampControl2.print_timestamp(Text="Look 2")
L: Silent Time 2016-10-07 18:28:40.404085 Elapse: 2942, Total: 2 Look 2 In: <module> Line: 1
sage: TestTimeStampControl2.print_timestamp(Text="Look 2")
sage: TestTimeStampControl2.print_timestamp(Text="Look 2")
L: Silent Time 2016-10-07 18:28:43.239652 Elapse: 2848, Total: 5 (truncated 1) Look 2 In: <module> Line: 1
sage: TestTimeStampControl2.print_timestamp(Text="Look 2")
sage: TestTimeStampControl2.print_timestamp(Text="Look 2")
sage: TestTimeStampControl2.print_timestamp(Text="Look 2")
L: Silent Time 2016-10-07 18:28:45.683139 Elapse: 2443, Total: 8 (truncated 2) Look 2 In: <module> Line: 1
sage: TestTimeStampControl2.print_timestamp(Text="Look 2")
L: Silent Time 2016-10-07 18:28:47.891519 Elapse: 2208, Total: 10 Look 2 In: <module> Line: 1
using TimeStampLevel:
sage: TestTimeStampControl3 = timeStampControl( TimeStampLevel = TsLevel.StackInfo )
sage: def testTsLevel( ):
....: TestTimeStampControl3.print_timestamp(Text="Entry", Level = TsLevel.StackInfo )
....: TestTimeStampControl3.print_timestamp(Text="Body", Level = TsLevel.Body )
....: TestTimeStampControl3.print_timestamp(Text="Exit", Level = TsLevel.StackInfo )
....:
sage:
sage: testTsLevel()
L: StackInfo Time 2016-10-07 18:38:38.041593 Elapse: 39631, Total: 39 Entry In: testTsLevel Line: 2
L: StackInfo Time 2016-10-07 18:38:38.044064 Elapse: 4, Total: 39 Exit In: testTsLevel Line: 4
sage:
sage: TestTimeStampControl3 = timeStampControl( TimeStampLevel = TsLevel.Body )
sage: testTsLevel()
L: StackInfo Time 2016-10-07 18:50:57.921070 Elapse: 1791, Total: 1 Entry In: testTsLevel Line: 2
L: Body Time 2016-10-07 18:50:57.923609 Elapse: 519, Total: 2 Body In: testTsLevel Line: 3
L: StackInfo Time 2016-10-07 18:50:57.926158 Elapse: 2, Total: 2 Exit In: testTsLevel Line: 4
sage: TestTimeStampControl3 = timeStampControl( TimeStampLevel = TsLevel.Debug )
sage: testTsLevel()
L: StackInfo Time 2016-10-07 18:51:09.257619 Elapse: 1638, Total: 1 Entry In: testTsLevel Line: 2
L: Body Time 2016-10-07 18:51:09.260104 Elapse: 3, Total: 1 Body In: testTsLevel Line: 3
L: StackInfo Time 2016-10-07 18:51:09.262624 Elapse: 2, Total: 1 Exit In: testTsLevel Line: 4
sage:
AUTHOR:
- Sebastian Oehms, Oct. 2016
"""
def __init__( self, KeepSilentOnElapse = _sage_const_0 , TimeStampLevel = TsLevel.Silent, TraceBackDepth = _sage_const_1 , Offset = _sage_const_1 , ShowDateTime = True ):
"""
Python constructor.
for more information type
sage: print timeStampControl.__doc__
AUTHOR
- Sebastian Oehms, Oct. 2016
"""
if type( KeepSilentOnElapse ) != Integer:
raise TypeError( "KeepSilentOnElapse must be of type Integer" )
elif KeepSilentOnElapse < _sage_const_0 :
raise ValueError( "KeepSilentOnElapse must be non negative" )
if isinstance(TimeStampLevel, TsLevel) == False:
raise ValueError( "TimeStampLevel must belong to enum %s", TsLevel )
if type( TraceBackDepth ) != Integer:
raise TypeError( "TraceBackDepth must be of type Integer" )
elif TraceBackDepth < _sage_const_0 :
raise ValueError( "TraceBackDepth must be non negative" )
if type( Offset ) != Integer:
raise TypeError( "Offset must be of type Integer" )
elif Offset < _sage_const_0 :
raise ValueError( "Offset must be non negative" )
self._KeepSilentOnElapse_ = KeepSilentOnElapse
self._TimeStampLevel_ = TimeStampLevel
self._TraceBackDepth_ = TraceBackDepth
self._Offset_ = Offset
self._ShowDateTime_ = ShowDateTime
self._init_time_ = datetime.today()
self._reset_time_ = datetime.today()
self._last_time_ = datetime.today()
self._act_time_ = datetime.today()
self._count_ = _sage_const_0
def __reduce__(self):
"""
Checks or unity
If you don't see this well formatted type
sage: print timeStampControl.__recuce__.__doc__
EXAMPLE:
sage: TestTimeStampControl3 = timeStampControl( TimeStampLevel = TsLevel.Debug )
sage: TestTimeStampControl3.__reduce__()
(<class lib.utils_sys.timeStampControl at 0xac49398c>, (0, 'Debug', 1, 1))
sage:
"""
return (timeStampControl, (self._KeepSilentOnElapse_, self._TimeStampLevel_, self._TraceBackDepth_, self._Offset_,))
def _repr_( self ):
"""
Return a string representation
If you don't see this well formatted type
sage: print timeStampControl._repr_.__doc__
OUTPUT:
String decribing self
EXAMPLE:
sage: TestTimeStampControl3 = timeStampControl( TimeStampLevel = TsLevel.Debug )
sage: TestTimeStampControl3._repr_()
'TimeStampControl with KeepSilentOnElapse = 0, TimeStampLevel = Debug, TraceBackDepth = 1, Offset 1'
sage:
"""
return "TimeStampControl with KeepSilentOnElapse = %d, TimeStampLevel = %s, TraceBackDepth = %d, Offset %d, ShowDateTime %s"\
%(self._KeepSilentOnElapse_, self._TimeStampLevel_, self._TraceBackDepth_, self._Offset_, self._ShowDateTime_)
def reset(self):
"""
Reset the elapse time control counters
If you don't see this well formatted type
sage: print timeStampControl.reset.__doc__
EXAMPLE:
sage: TestTimeStamp = setupTimeStamp( verbose = True )
sage: TestTimeStamp.print_timestamp()
L: Silent Time 2016-10-11 18:29:04.012623 Elapse: 2307, Total: 2 In: <module> Line: 1
sage: TestTimeStamp.print_timestamp()
L: Silent Time 2016-10-11 18:29:06.321664 Elapse: 2309, Total: 4 In: <module> Line: 1
sage: TestTimeStamp.reset()
sage: TestTimeStamp.print_timestamp()
L: Silent Time 2016-10-11 18:29:11.679048 Elapse: 2187, Total: 2/ 9 In: <module> Line: 1
sage: TestTimeStamp.print_timestamp()
L: Silent Time 2016-10-11 18:29:14.343407 Elapse: 2665, Total: 4/ 12 In: <module> Line: 1
AUTHOR
- Sebastian Oehms, Oct. 2016
"""
self._reset_time_ = datetime.today()
self._last_time_ = datetime.today()
self._act_time_ = datetime.today()
self._count_ = _sage_const_0
return
def print_timestamp( self, Text="", Level = TsLevel.Silent ):
"""
This method prints a timestamp message depending on the parameters
- KeepSilentOnElapse
- TimeStampLevel
which have been set in the constructor of the class. It uses the function print_time_tb.
If you don't see this well formatted type
sage: print timeStampControl.print_timestamp.__doc__
to learn more about the function print_time_tb type
sage: print print_time_tb.__doc__
to learn more about the parmeters "KeepSilentOnElapse" and "TimeStampLevel" or to see examples
sage: print timeStampControl.__doc__
INPUT (all optional keyword):
- "Text": string (default empty) describing the position of invocation. This parameter is passed to
the corresponding parameter of print_time_tb
- "Level": Enum constants (class TsLevel) with integer value: classifies the position of invocation.
This parameter is passed to the corresponding parameter of print_time_tb
OUTPUT:
only prints, no return value
EXAMPLES:
to see examples type
sage: print timeStampControl.__doc__
AUTHOR:
- Sebastian Oehms, Oct. 2016
"""
if Level.value > self._TimeStampLevel_.value:
return
self._act_time_ = datetime.today()
elapse_time_timedelta = self._act_time_ - self._last_time_
total_time_timedelta = self._act_time_ - self._init_time_
reset_time_timedelta = self._act_time_ - self._reset_time_
elapse_time_msec_float = elapse_time_timedelta.total_seconds()*_sage_const_1000
total_time_sec_float = total_time_timedelta.total_seconds()
reset_time_sec_float = reset_time_timedelta.total_seconds()
elapse_time_msec = elapse_time_msec_float.__trunc__()
total_time_sec = total_time_sec_float.__trunc__()
reset_time_sec = reset_time_sec_float.__trunc__()
if total_time_sec > reset_time_sec:
if self._count_ > _sage_const_0 :
info_str = "Elapse: %5d, Total: %3d/%3d (truncated %3d)"%(elapse_time_msec,\
reset_time_sec, total_time_sec, self._count_)
else:
info_str = "Elapse: %5d, Total: %3d/%3d"%(elapse_time_msec, reset_time_sec, total_time_sec)
else:
if self._count_ > _sage_const_0 :
info_str = "Elapse: %5d, Total: %3d (truncated %3d)"%(elapse_time_msec, total_time_sec, self._count_)
else:
info_str = "Elapse: %5d, Total: %3d"%(elapse_time_msec, total_time_sec)
self._count_ = self._count_ +_sage_const_1
if self._KeepSilentOnElapse_ <= elapse_time_msec:
print_time_tb( Text, Info=info_str, MaxDepth = self._TraceBackDepth_, Offset = self._Offset_+_sage_const_1 ,
Level=Level, ShowDateTime = self._ShowDateTime_ )
self._last_time_ = self._act_time_
self._count_ = _sage_const_0
return
def setupTimeStamp( verbose = False, Offset = None, TraceBackDepth = None, ShowDateTime = True ):
"""
This is a function which should make the declaration of a timeStampControl instance easier.
It interprets the commonly used "verbose" parameter into "KeepSilentOnElapse" and "TimeStampLevel" parameters
of the timeStampControl class.
If you don't see this well formatted type:
sage: print setupTimeStamp.__doc__
to learn more about the timeStampControl class type:
sage: print timeStampControl.__doc__
INPUT:
- "verbose": This parameter allowes multi type input, namely a boolean, an integer, an instance of the
timeStanpControl class or an constant from Enum class TsLevel
- By default it is set to the "boolean False" meaning that only silent messages are printed.
- Setting it as a "boolean True" leads to printing all messages (of any level).
- Setting it to an integer > 0 leads to printing messages after an elapse time of the same number
of milli seconds after the former printed message (see the "KeepSilentOnElapse" parameter of the
timeStampControl class)
- Setting it to a member of the Enum class TsLevel leads to printing all messages whose level is not
larger as the Enum-Integer-Value of the level
- Giving an instance of the timeStampControl class performes a reset of counting variables.
- "TraceBackDepth": integer representing number of lines of traceback information to be printed (top down,
default is 1 if no elapse time is set, else it defaults to 4). This parameter is passed
to the corresponding parameter of the timeStampControl class and print_time_tb function
- "Offset": integer representing number of lines of traceback information to be ignored (top down,
default is 1). This parameter is passed to the corresponding parameter of the
timeStampControl class and print_time_tb function.
- "ShowDateTime": boolean (Default = True). If set to False the date and time part of the message is supressed.
This parameter is passed to the corresponding parameter of the timeStampControl class and
print_time_tb function.
OUTPUT:
an instance of the class timeStampControl according to the given parameters
RAISE:
- ValueError "Elapse time must be non negative" if verbose is set to a negative integer
- TypeError "verbose mut be a boolean, integer, an instance of timeStampControll or a member of Enum TsLevel"
if verbose is something else (not allowed)
EXAMPLES:
verbose as boolean
sage: TestTimeStamp = setupTimeStamp( verbose = True )
sage: def testTsLevel( ):
....: TestTimeStamp.print_timestamp(Text="Entry", Level = TsLevel.StackInfo )
....: TestTimeStamp.print_timestamp(Text="Body", Level = TsLevel.Body )
....: TestTimeStamp.print_timestamp(Text="Exit", Level = TsLevel.StackInfo )
....:
sage: testTsLevel()
L: StackInfo Time 2016-10-11 08:39:16.355601 Elapse: 2001, Total: 2 Entry In: testTsLevel Line: 2
L: Body Time 2016-10-11 08:39:16.358169 Elapse: 3, Total: 2 Body In: testTsLevel Line: 3
L: StackInfo Time 2016-10-11 08:39:16.362389 Elapse: 2, Total: 2 Exit In: testTsLevel Line: 4
sage:
verbose as member of Enum "TsLevel":
sage: TestTimeStamp = setupTimeStamp( verbose = TsLevel.StackInfo )
sage: testTsLevel()
L: StackInfo Time 2016-10-11 08:38:03.463870 Elapse: 8481, Total: 8 Entry In: testTsLevel Line: 2
L: StackInfo Time 2016-10-11 08:38:03.466694 Elapse: 3, Total: 8 Exit In: testTsLevel Line: 4
sage:
verbose as instance of timeStampControl (resets Total Time Counter):
sage: TestTimeStamp = setupTimeStamp( verbose = TestTimeStamp )
sage: testTsLevel()
L: StackInfo Time 2016-10-11 18:20:39.091622 Elapse: 2302, Total: 2/ 81 Entry In: testTsLevel Line: 2
L: StackInfo Time 2016-10-11 18:20:39.094596 Elapse: 4, Total: 2/ 81 Exit In: testTsLevel Line: 4
sage: testTsLevel()
L: StackInfo Time 2016-10-11 18:20:44.686855 Elapse: 5592, Total: 7/ 86 Entry In: testTsLevel Line: 2
L: StackInfo Time 2016-10-11 18:20:44.689293 Elapse: 2, Total: 7/ 86 Exit In: testTsLevel Line: 4
default verbose = False:
sage: TestTimeStamp = setupTimeStamp( )
sage: testTsLevel()
verbose as integer (elapse time):
sage: TestTimeStamp = setupTimeStamp( verbose = 1 )
sage: testTsLevel()
L: StackInfo Time 2016-10-11 08:39:51.658389 Elapse: 1784, Total: 1 Entry In: testTsLevel Line: 2
---> <module> In: <ipython-input-18-85e0e9a26a0d> Line: 1
L: Body Time 2016-10-11 08:39:51.661864 Elapse: 4, Total: 1 Body In: testTsLevel Line: 3
---> <module> In: <ipython-input-18-85e0e9a26a0d> Line: 1
L: StackInfo Time 2016-10-11 08:39:51.665626 Elapse: 3, Total: 1 Exit In: testTsLevel Line: 4
---> <module> In: <ipython-input-18-85e0e9a26a0d> Line: 1
sage: TestTimeStamp = setupTimeStamp( verbose = 10 )
sage: testTsLevel()
L: StackInfo Time 2016-10-11 08:40:26.402257 Elapse: 1575, Total: 1 Entry In: testTsLevel Line: 2
---> <module> In: <ipython-input-20-85e0e9a26a0d> Line: 1
AUTHOR:
- Sebastian Oehms, Oct. 2016
"""
TimeStamp = None
LocTsLevel = TsLevel.Silent
elapsetime = _sage_const_0
if type( verbose ) == bool:
if verbose == True:
elapsetime = _sage_const_0
LocTsLevel = TsLevel.Debug
else:
elapsetime = _sage_const_0
LocTsLevel = TsLevel.Silent
elif type( verbose ) == Integer:
if verbose > _sage_const_0 :
elapsetime = verbose
LocTsLevel = TsLevel.Debug
else:
raise ValueError( "Elapse time must be non negative" )
elif isinstance( verbose, timeStampControl ) == True:
TimeStamp = verbose
elif isinstance( verbose, TsLevel ) == True:
LocTsLevel = verbose
else:
raise TypeError( "verbose mut be a boolean, integer, or an instance of %s or %s"\
%(timeStampControl, TsLevel ) )
if Offset == None:
Offset = _sage_const_1
if TraceBackDepth == None:
if elapsetime > _sage_const_0 :
TraceBackDepth = _sage_const_4
else:
TraceBackDepth = _sage_const_1
if TimeStamp == None:
TimeStamp = timeStampControl( KeepSilentOnElapse = elapsetime, TimeStampLevel = LocTsLevel,
TraceBackDepth = TraceBackDepth, Offset = Offset, ShowDateTime = ShowDateTime )
else:
TimeStamp.reset()
return TimeStamp
def print_doc( function ):
"""
This function capsules a formatted print of the docstring
"""
print "\n"
print "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
print "-----------------------------------------------------------------------------------------------------------------"
print "Docstring of", function; print function.__doc__
print "_________________________________________________________________________________________________________________"
print "-----------------------------------------------------------------------------------------------------------------"
print "\n"