def getByteCountStringsTest():
     '''
     Verify use cases for getByteCountStrings.
     '''
     myLogger.info('\n*** GET BYTE COUNT STRINGS TEST ***\n')
     for power in range(9):
         myInput = int(1.0 * 1024**power)
         output = str(tsrpu.getByteCountStrings(myInput))
         myLogger.info('  1024^%d %s' % (power, output))
    def tsGetPlatformRunTimeEnvironment(self):
        '''
        Build list of strings that describe the following standard runtime
        enviroment features: "Network Host", "Python Virtual Machine",
        "Host Operating System", "Host Central Processing Unit",
        "Process Parameters" with associated platform specific details.
        '''
        theInfo = []

        lines = __header__.split('\n')
        for line in lines:
            theInfo += [line]

        theBeginTitle = 'Begin Platform Run Time Environment'
        theEndTitle = 'End Platform Run Time Environment'
        theInfo += ['%s' % \
                    tsrpu.getSeparatorString(title=theBeginTitle,
                                             separatorCharacter='=',
                                             position=tsrpu.layout[
                                                 'TitleCenter'])]
 
        theInfo += ['\n']
        theInfo += ['  Reported %s' % \
                    tsrpu.getDateAndTimeString(time.time())]

        self.tsGetNetworkIdentification(theInfo)
        self.tsGetHostCentralProcessingUnit(theInfo)
        self.tsGetHostOperatingSystem(theInfo)
        self.tsGetHostConsoleDisplaySize(theInfo)
        self.tsGetPythonPlatform(theInfo)
        self.tsGetJavaPlatform(theInfo)
        self.tsGetMacPlatform(theInfo)
        self.tsGetLinuxPlatform(theInfo)
        self.tsGetWindowsPlatform(theInfo)
        self.tsGetProcessParameters(theInfo)

        theInfo += ['%s' % \
                    tsrpu.getSeparatorString(title=theEndTitle,
                                             separatorCharacter='=',
                                             position=tsrpu.layout[
                                                 'TitleCenter'])]

        return theInfo
 def getDayHourMinuteSecondStringTest():
     '''
     Verify use cases for getDayHourMinuteSecondString.
     '''
     myList = [0, 1, 59, 60, 120, 3599, 3600, 24*3600, 25*3600]
     myLogger.info('\n*** GET DAY HOUR MINUTE SECOND STRING TEST ***\n')
     for myInput in myList:
         myOutput = str(tsrpu.getDayHourMinuteSecondString(
             inputSeconds=myInput,
             firstDelimiter='-'))
         myLogger.info('  %s %s' % (myInput, myOutput))
 def getNextPathNameTest():
     '''
     Verify use cases for getNextPathName.
     '''
     myLogger.info('\n*** GET NEXT PATH NAME TEST ***\n')
     theDirectory = './'
     theName = 'junk'
     myLogger.info(
         '  %s %s %s' % (theDirectory,
                         theName,
                         tsrpu.getNextPathName(theDirectory,
                                               theName)))
 def getTimeStatisticsListTest():
     '''
     Verify use cases for getTimeStatisticsList.
     '''
     startupTime = time.time()
     currentTime = startupTime + float(3600)
     myInput = '%s %s' % (str(startupTime),
                          str(currentTime))
     myLogger.info('\n*** GET STATISTICS TIME TEST ***\n')
     output = str(tsrpu.getTimeStatisticsList(startupTime,
                                              currentTime))
     myLogger.info('  %s %s' % (myInput, output))
    def displayDictionaryTest():
        '''
        Verify use cases for displayDictionary.
        '''
        myLogger.info('\n*** DISPLAY DICTIONARY TEST ***\n')

        sequentialDictionary = {100: 'apple',
                                -1: 'pear',
                                50: 'orange',
                                25: 1234,
                                15: 1.234,
                                'name': 'sequentialDictionary'}

        releaseDictionary = {'list1': [12, 34, 56],
                             'name': 'releaseDictionary',
                             'title': __title__,
                             'version': __version__,
                             'date': __date__}

        programDictionary = {'name': 'programDictionary',
                             'list2': ['ab', 'cd', 'ef'],
                             'main': __name__,
                             'mainTitleVersionDate': mainTitleVersionDate}

        myDictionary = {
            'name': 'myDictionary',
            'contents': {'releaseDictionary': releaseDictionary,
                         'programDictionary': programDictionary,
                         'sequentialDictionary': sequentialDictionary,
                         'name': 'contents'}}

        myConsole = sys.stdout
        tsrpu.displayDictionary(0, myDictionary, myConsole)

        myFile = open(os.path.join(myLogger.theLogPath,
                                   'displayDictionaryTest.log'), 'w')

        tsrpu.displayDictionary(0, myDictionary, myFile)
        myFile.close()
 def getSecondsTimeFromHoursMinutesSecondsStringTest():
     '''
     Verify use cases for getSecondsTimeFromHoursMinutesSecondsString.
     '''
     myList = [None,
               '00:00:00',
               '01:02:03',
               '12:34:56',
               '23:59:59',
               '24:00:00']
     myLogger.info(
         '\n*** GET SECONDS TIME FROM ' + \
         'HOURS MINUTES SECONDS STRING TEST ***\n')
     for myInput in myList:
         if myInput is None:
             output = str(
                 tsrpu.getSecondsTimeFromHoursMinutesSecondsString())
         else:
             output = str(
                 tsrpu.getSecondsTimeFromHoursMinutesSecondsString(
                     myInput))
         myLogger.info('  %s %s' % (myInput, output))
    def tsCreateScrollableRedirectionLog(self):
        '''
        Return file instance used for scrollable redirected output.
        '''
        # TBD - Begin prototype for Scrollable Redirection Window
        # Will need an application instance specific file name.
        theDirectory = os.getcwd()
        theWindowTitle = self.ts_Title
        theKeyWord = theWindowTitle.split(' ', 1)
        theNickName = theKeyWord[0].strip('_').title()
        theFileName = '%s-stdout' % theNickName

        if True:
            thePathName = os.path.join(
                tsLogger.TsLogger.defaultStandardOutputPath,
                '%s.log' % theFileName)
        else:
            thePathName = tsru.getNextPathName(theDirectory, theFileName)
 
        theLogFile = open(thePathName, 'w')

        theLogFileHeader = tsru.getSeparatorString(
            title='Begin %s on %s' % (
                'PRINT/STDOUT/STDERR log',
                tsru.getDateAndTimeString(time.time())),
            indent=0,
            position=tsru.layout['TitleIndent'],
            separatorCharacter='$',
            tab=4)

        theLogFile.write('%s\n\n' % theLogFileHeader)
        theLogFile.write('%s - Started logging to file "%s".\n\n' % (
            tsru.getDateTimeString(time.time(), msec=True),
            thePathName))
        # TBD - End prototype for Scrollable Redirection Window
        return (theLogFile)
    def write(self, text):
        '''
        Output specified text with the appropriate timestamp
        prefix.
        '''
        self.ts_LineCount += 1
        if self.ts_LineCount <= self.ts_LastHeaderLine or \
           text == '\n':

            self.ts_File.write(text)

        else:

            self.ts_File.write('%s - %s' % (
                tsru.getDateTimeString(time.time()), text))
 def getStatisticsListTest():
     '''
     Verify use cases for getStatisticsList.
     '''
     startupTime = time.time()
     currentTime = startupTime + float(3600)
     numberOfTestRuns = 100
     numberOfTestPasses = 80
     numberOfTestFailures = 20
     myInput = '%s %s %s %s %s' % (str(startupTime),
                                   str(currentTime),
                                   str(numberOfTestRuns),
                                   str(numberOfTestPasses),
                                   str(numberOfTestFailures))
     myLogger.info('\n*** GET STATISTICS LIST TEST ***\n')
     output = str(tsrpu.getStatisticsList(
         startupTime,
         currentTime,
         numberOfTestRuns,
         numberOfTestPasses,
         numberOfTestFailures))
     myLogger.info('  %s %s' % (myInput, output))
    def write(self, text):
        '''
        Create the output window if needed and write the string to it.
        If not called in the context of the gui thread then uses CallAfter
        to do the work there.

        NOTE: In accordance with Python convention, this method supports the
        formating of a single line of output across multiple print statements.
        '''
        if self.ts_Frame is None:
 
            msg1 = 'Print statements and other standard output '
            msg2 = 'will now be directed to this window.'

            if wx.ThemeToUse['Stdio']['Timestamp']:
                theStartupText = '\n\n%s\n' % (msg1 + msg2)
            else:
                theStartupText = '%s\n' % (msg1 + msg2)

            if wx.ThemeToUse['Stdio']['Timestamp']:
                # Begin the new record with a timestamp.
                timestamp = tsru.getDateTimeString(time.time(), msec=True)
                self.ts_Cache += '%s - %s' % (timestamp, theStartupText)
            else:
                # Append the text to the existing record.
                self.ts_Cache += theStartupText

            self.CreateOutputWindow(theStartupText)

        if self.ts_logFile is None and \
           wx.ThemeToUse['Stdio']['ScrollableLogFile']:
            self.ts_logFile = self.tsCreateScrollableRedirectionLog()

        theMarkup = None
        if self.ts_Frame.display.HasColors:
            # TBD - Fix so that we pass Attributes without colors.
            for theKey in wx.ThemeToUse['Stdio']['Markup'].keys():

                thePriorityKey = '%s:' % theKey
                theKeyPosition = text.find(thePriorityKey)
                ## print('theKeyPosition[%s] = %d' % (theKey, theKeyPosition))
                if (theKeyPosition > -1):
                    theMarkup = wx.ThemeToUse['Stdio']['Markup'][theKey]
                    ## print('theKeyPosition[%s] = %d' % (
                    ##     theKey, theKeyPosition))

                    break

        # Original design based on wxPyOnDemandOutputWindow
        # without markup

        if theMarkup is None:

            # Apply default markup to increase brightness/conrtrast
            # in order to improve readability
            theKey = 'DEFAULT'
            theMarkup = wx.ThemeToUse['Stdio']['Markup'][theKey]

        if self.ts_Text is not None:

            terminalCharacter = len(text)
            terminalNewLine = text[
                terminalCharacter - 1:terminalCharacter] == '\n'

            if text not in list(printMarkupToIgnore.keys()):

                if (self.ts_Cache == wx.EmptyString):

                    # Begin the new record with a timestamp.
                    timestamp = tsru.getDateTimeString(time.time(),
                                                       msec=True)
                    self.ts_Cache += '%s - %s' % (timestamp, text)

                else:

                    # Append the text to the existing record.
##                    timestamp = wx.EmptyString
##                    theMarkup = None
                    self.ts_Cache += text

                if terminalNewLine:

                    # End and output those existing records that
                    # contain a new line.
                    self.ts_Text.AppendText(self.ts_Cache,
                                            markup=theMarkup)
                    self.tsUpdateScrollableRedirectionLog(self.ts_Cache)
                    self.ts_Cache = wx.EmptyString

            elif terminalNewLine:

                # End and output those existing records that
                # would now contain a new line.
                self.ts_Text.AppendText(self.ts_Cache, markup=theMarkup)
                self.tsUpdateScrollableRedirectionLog(self.ts_Cache)
                self.ts_Cache = wx.EmptyString

            else:

                # Append the text to the existing record.
                self.ts_Cache += text

        self.ts_Frame.Show(True)
        print("%s: ImportError (tsLibCLI); " % __title__ + "importCode=%s" % str(importCode))

    # -------------------------------------------------------------------

    print(__header__)

    # -------------------------------------------------------------------

    myLogger = Logger.TsLogger(name="", threshold=Logger.INFO)

    # -------------------------------------------------------------------

    sizex, sizey = get_terminal_size()
    print("\n  width = %d; height = %d" % (sizex, sizey))

    current_os = platform.system()
    print("\n  current_os = %s" % current_os)

    # -------------------------------------------------------------------

    level = 0
    myDictionary = ThemeToUse
    myConsole = sys.stdout
    tsrpu.displayDictionary(level, myDictionary, myConsole)

    myFile = open(os.path.join(myLogger.theLogPath, "tsCxGlobalsDictionaryTest.log"), "w")

    tsrpu.displayDictionary(level, myDictionary, myFile)
    myFile.close()
                                      'stderr': sys.stderr,
                                      ' stdin': sys.stdin}

                for theKey in list(fileStdioDevices.keys()):
                    self.logger.debug(
                        '    Saved %s %s' % (
                            theKey, fileStdioDevices[theKey]))
            except Exception, fileStdioDevicesError:
                msg = "tsWxApp: %s" % fileStdioDevicesError
                raise tse.ProgramException(
                    tse.APPLICATION_TRAP, msg)

            theLogFileHeader = tsru.getSeparatorString(
                title='Begin %s on %s' % (
                    'PRINT/STDOUT/STDERR log',
                    tsru.getDateAndTimeString(time.time())),
                indent=0,
                position=tsru.layout['TitleIndent'],
                separatorCharacter='$',
                tab=4)

            self.stdioLog.write('%s\n\n' % theLogFileHeader)
            self.stdioLog.write('%s - Started logging to file "%s".\n\n' % (
                tsru.getDateTimeString(time.time()),
                filename))

            msg1 = 'Print statements and other standard output '
            msg2 = 'will now be directed to this file.'
            self.stdioLog.write('%s\n' % (msg1 + msg2))

            self.stdioLog.flush()
    def wrapperTest():
        '''
        Verify operation of logging to devices and files.
        '''
##        def taskTest():
##            '''
##            Verify logging to application log.
##            '''
##            theName = 'taskTest.log'
##            defaultLogger = TsLogger(threshold=INFO,
##                                     start=time.time())
##            print('\tStarted Logging to %s' % defaultLogger.name)
##            defaultLogger.info('Started Logging to %s' % defaultLogger.name)

##            print('\tDefault Task: %s' % \
##                  defaultLogger.theTopLevelApplicationTask)
##            defaultLogger.info('Default Task: %s' % \
##                          defaultLogger.theTopLevelApplicationTask)

##            theName = 'taskTest.log'
##            myLogger = TsLogger(threshold=INFO,
##                                start=time.time(),
##                                name=theName)
##            print('\tStarted Logging to %s' % myLogger.name)
##            myLogger.info('Started Logging to %s' % myLogger.name)

##            print('\tTask: %s' % myLogger.theTopLevelApplicationTask)
##            myLogger.info('Task: %s' % myLogger.theTopLevelApplicationTask)

        #-------------------------------------------------------------------

        def propertyTest(myLogger):
            '''
            Verify logger properties.
            '''
            try:
                myLogger.info(
                    'appLogger= "%s"' % myLogger.appLogger)
                myLogger.info(
                    'theLogName= "%s"' % myLogger.theLogName)
                myLogger.info(
                    'theLogPath= "%s"' % myLogger.theLogPath)
                level = myLogger.theLogThreshold
                levelName = getLevelName(level)
                myLogger.info(
                    'theLogThreshold= "%s" (%s)' % (levelName, level))
            except Exception as propertyErrorCode:
                myLogger.error(
                    'propertyErrorCode="%s"' % propertyErrorCode)

        #-------------------------------------------------------------------

        def levelTest(myLogger):
            '''
            Verify logging for each level.
            '''
            availableLevels = [
                tsLogger.NOTSET,
                tsLogger.PRIVATE,
                # tsLogger.DEBUG_TRACE_LEVEL,
                tsLogger.DEBUG,
                tsLogger.INFO,
                tsLogger.NOTICE,
                tsLogger.WARNING,
                tsLogger.ALERT,
                tsLogger.ERROR,
                tsLogger.CRITICAL,
                tsLogger.EMERGENCY]

            if TROUBLE_SHOOTING_DEBUG:

                print('begin levelTest on <%s>' % myLogger.thisLogName)

            for level in availableLevels:

                levelName = tsLogger.getLevelName(level)

                myLogger.log(
                    level,
                    '%s Level report on <%s>' % (levelName,
                                                 myLogger.thisLogName))

            if TROUBLE_SHOOTING_DEBUG:

                print('end levelTest on <%s>' % myLogger.thisLogName)


        #-------------------------------------------------------------------

        def deviceTest():
            '''
            Verify logging to stdout, stderr and syslog.
            '''
            separator = '-' * (72 - 8)
            for device in tsLogger._deviceList:
                print('\n\t%s' % separator)
                myLogger = tsLogger.TsLogger(threshold=tsLogger.INFO,
                                    start=time.time(),
                                    name=device)
                print('\tName: %s' % myLogger.thisRegisteredName)
                print('\tID: %s' % myLogger.thisLogID)
                levelTest(myLogger)

                if False and TROUBLE_SHOOTING_DEBUG:
                    # Cannot close shared devices because there is
                    # no mechanism to automatically re-open them.
                    myLogger.close()

        #-------------------------------------------------------------------

        def fileTest():
            '''
            Verify logging to files.
            '''
            separator = '-' * (72 - 8)
            for device in ['', 'myMethod.log']:
                print('\n\t%s' % separator)
                myLogger = tsLogger.TsLogger(threshold = tsLogger.NOTSET,
                                    start = time.time(),
                                    name = device)
                print('\tName: %s' % myLogger.thisRegisteredName)
                print('\tID: %s' % myLogger.thisLogID)
                levelTest(myLogger)

        #-------------------------------------------------------------------

        def descriptionTest():
            '''
            Verify text wrapping operation when outputting multi-line text
            to logger.
            '''
            myLogger = tsLogger.TsLogger(threshold = tsLogger.ERROR,
                                start = time.time(),
                                name = 'myDescription.log',
                                file_header = 'Error Report Started',
                                file_footer = 'Error Report Finished',
                                width = 70,
                                initial_indent = '\t',
                                subsequent_indent = '\t')
            print('\tName: %s' % myLogger.thisRegisteredName)
            print('\tID: %s' % myLogger.thisLogID)

            paragraph = "The textwrap module provides two convenience" \
                        " functions, wrap() and fill(), as well as" \
                        " TextWrapper, the class that does all the work,"\
                        " and a utility function dedent(). If you're just" \
                        " wrapping or filling one or two text strings, the" \
                        " convenience functions should be good enough;" \
                        " otherwise, you should use an instance of" \
                        " TextWrapper for efficiency."

            message = ['1st line; no tabs']
            myLogger.description(message,
                                 level = tsLogger.ERROR,
                                 indent = 1,
                                 tab = 4,
                                 title = 'Data Corruption #1')

            message = ['2nd line;\tone tab']
            myLogger.description(message,
                                 level = tsLogger.ERROR,
                                 indent = 1,
                                 tab = 4,
                                 title = 'Data Corruption #2')

            message = ['3rd line;\t\ttwo tabs',
                       '',
                       paragraph]
            myLogger.description(message,
                                 level = tsLogger.ERROR,
                                 indent = 1,
                                 tab = 4,
                                 title = 'Data Corruption #3')
            myLogger.close()

        #-------------------------------------------------------------------

        def rewriteTest():
            '''
            '''
            myLogger = tsLogger.TsLogger(threshold = tsLogger.WARNING,
                                start = time.time(),
                                name = 'myProgress.log')
            print('\tName: %s' % myLogger.thisRegisteredName)
            print('\tID: %s' % myLogger.thisLogID)
            myLogger.progress('No Level update', level = tsLogger.NOTSET)
            myLogger.progress('Debug Level update', level = tsLogger.DEBUG)
            myLogger.progress('Info Level update', level = tsLogger.INFO)
            myLogger.progress('Warning Level update', level = tsLogger.WARNING)
            myLogger.progress('Error Level update', level = tsLogger.ERROR)
            myLogger.progress('Critical Level update', level = tsLogger.CRITICAL)

            myLogger.event('\n\nFinished New Logging Tests\n\n')
            myLogger.close()

        #-------------------------------------------------------------------

        def assertTest():
            '''
            '''

            def pseudoOp(number):
                print(number)

            myDebugHandlers = tsLogger.TsLogger(threshold = tsLogger.DEBUG,
                                       start = time.time(),
                                       name = 'myAsserts.log')

            conditions = [True, False]
            line = 0
            for cond in conditions:

                print('#################### cond=%s ####################' % cond)
                line += 1 # 1
                try:
                    print('line= %d; rc=%s' % (
                        line,
                        myDebugHandlers.wxASSERT(
                            cond)))
                except Exception as errorCode:
                    print('Handled Trap for line= %d; errorCode=%s' % (
                        line, errorCode))

                line += 1 # 2
                try:
                    print('line= %d; rc=%s' % (
                        line,
                        myDebugHandlers.wxASSERT_MSG(
                            cond,
                            msg='Sample #%d' % line)))
                except Exception as errorCode:
                    print('Handled Trap for line= %d; errorCode=%s' % (
                        line, errorCode))

                line += 1 # 3
                try:
                    print('line= %d; rc=%s' % (
                        line,
                        myDebugHandlers.wxCHECK(
                            cond,
                            rc=123 + line)))
                except Exception as errorCode:
                    print('Handled Trap for line= %d; errorCode=%s' % (
                        line, errorCode))

                line += 1 # 4
                try:
                    print('line= %d; rc=%s' % (
                        line,
                        myDebugHandlers.wxCHECK_MSG(
                            cond,
                            rc=123 + line,
                            msg='Sample #%d' % line)))
                except Exception as errorCode:
                    print('Handled Trap for line= %d; errorCode=%s' % (
                        line, errorCode))

                line += 1 # 5
                try:
                    print('line= %d; rc=%s' % (
                        line,
                        myDebugHandlers.wxCHECK2(
                            cond,
                            op=pseudoOp(line))))
                except Exception as errorCode:
                    print('Handled Trap for line= %d; errorCode=%s' % (
                        line, errorCode))

                line += 1 # 6
                try:
                    print('line= %d; rc=%s' % (
                        line,
                        myDebugHandlers.wxCHECK2_MSG(
                            cond,
                            op=pseudoOp(line),
                            msg='Sample #%d' % line)))
                except Exception as errorCode:
                    print('Handled Trap for line= %d; errorCode=%s' % (
                        line, errorCode))

                line += 1 # 7
                try:
                    print('line= %d; rc=%s' % (
                        line,
                        myDebugHandlers.wxFAIL()))
                except Exception as errorCode:
                    print('Handled Trap for line= %d; errorCode=%s' % (
                        line, errorCode))

                line += 1 # 8
                try:
                    print('line= %d; rc=%s' % (
                        line, myDebugHandlers.wxFAIL_COND_MSG(
                            cond, msg='Sample #%d' % line)))
                except Exception as errorCode:
                    print('Handled Trap for line= %d; errorCode=%s' % (
                        line, errorCode))

                line += 1 # 9
                try:
                    print('line= %d; rc=%s' % (
                        line,
                        myDebugHandlers.wxFAIL_MSG(
                            msg='Sample #%d' % line)))
                except Exception as errorCode:
                    print('Handled Trap for line= %d; errorCode=%s' % (
                        line, errorCode))

                line += 1 # 10
                try:
                    print('line= %d; rc=%s' % (
                        line,
                        myDebugHandlers.wxTRAP()))
                except Exception as errorCode:
                    print('Handled Trap for line= %d; errorCode=%s' % (
                        line, errorCode))

        #-------------------------------------------------------------------

        separator = '-' * 72
        # taskTest()
        print('\n%s' % separator)
        deviceTest()

        print('\n%s' % separator)
        fileTest()

        print('\n%s' % separator)
        descriptionTest()

        print('\n%s' % separator)
        rewriteTest()

        print('\n%s' % separator)
        assertTest()

        print('\n%s' % separator)

        myLogger = tsLogger.TsLogger(threshold = tsLogger.DEBUG,
                            start = time.time(),
                            name = 'myProperties.log')

        level=0
        head = myLogger.tsGetLoggerPath()
        tail = 'tsLogger-Dict.txt'
        deviceName = '%s/%s' % (head, tail)
        myFile = open(deviceName, 'w+')
        myDictionary = tsLogger.TsLogger.activeLoggerIDs
        tsrpu.displayDictionary(level, myDictionary, myFile, myLogger=None)
        myFile.close()

        propertyTest(myLogger)
    def RedirectStdio(self, filename=None):
        '''
        Redirect sys.stdout and sys.stderr to a file or a popup window.
        '''
        # Verify user accessibility of one library known to be in hierarchy.
        try:
            preRedirectStdioDevices = {'stdout': sys.stdout,
                                       'stderr': sys.stderr,
                                       ' stdin': sys.stdin}

            for theKey in list(preRedirectStdioDevices.keys()):
                self.logger.debug(
                    '    Saved %s %s' % (
                        theKey, preRedirectStdioDevices[theKey]))
        except Exception as preRedirectStdioDevicesError:
            msg = "tsWxApp: %s" % preRedirectStdioDevicesError
            raise tse.ProgramException(
                tse.APPLICATION_TRAP, msg)

        # Save configuration for future restoration by RestoreStdio.
        self.saveStdio = (sys.stdout, sys.stderr)

        if filename is None:

            # Redirect output to a window on the screen.
            # Capture redirected output to a default file for scrolling.
            # TBD - How can this support the ThemeToUse Timestamp feature?
            self.stdioWin = self.outputWindowClass(wx.ThemeToUse['Stdio']['Title'])
            sys.stdout = self.stdioWin
            sys.stderr = self.stdioWin

            try:
                windowStdioDevices = {'stdout': sys.stdout,
                                      'stderr': sys.stderr,
                                      ' stdin': sys.stdin}

                for theKey in list(windowStdioDevices.keys()):
                    self.logger.debug(
                        '    Saved %s %s' % (
                            theKey, windowStdioDevices[theKey]))
            except Exception as windowStdioDevicesError:
                msg = "tsWxApp: %s" % windowStdioDevicesError
                raise tse.ProgramException(
                    tse.APPLICATION_TRAP, msg)

        else:
 
            # Redirect output to the specified file.
            # Setting buffer size of 0 eliminates need for flushing.
            if wx.ThemeToUse['Stdio']['Timestamp']:
                self.stdioLog = tsCustomStdioFile(filename, 'w', 1)
            else:
                self.stdioLog = open(filename, 'w', 1)

            sys.stdout = self.stdioLog
            sys.stderr = self.stdioLog

            try:
                fileStdioDevices = {'stdout': sys.stdout,
                                      'stderr': sys.stderr,
                                      ' stdin': sys.stdin}

                for theKey in list(fileStdioDevices.keys()):
                    self.logger.debug(
                        '    Saved %s %s' % (
                            theKey, fileStdioDevices[theKey]))
            except Exception as fileStdioDevicesError:
                msg = "tsWxApp: %s" % fileStdioDevicesError
                raise tse.ProgramException(
                    tse.APPLICATION_TRAP, msg)

            theLogFileHeader = tsru.getSeparatorString(
                title='Begin %s on %s' % (
                    'PRINT/STDOUT/STDERR log',
                    tsru.getDateAndTimeString(time.time())),
                indent=0,
                position=tsru.layout['TitleIndent'],
                separatorCharacter='$',
                tab=4)

            self.stdioLog.write('%s\n\n' % theLogFileHeader)
            self.stdioLog.write('%s - Started logging to file "%s".\n\n' % (
                tsru.getDateTimeString(time.time()),
                filename))

            msg1 = 'Print statements and other standard output '
            msg2 = 'will now be directed to this file.'
            self.stdioLog.write('%s\n' % (msg1 + msg2))

            self.stdioLog.flush()
        print('\n%s' % separator)
        assertTest()

        print('\n%s' % separator)

        myLogger = tsLogger.TsLogger(threshold = tsLogger.DEBUG,
                            start = time.time(),
                            name = 'myProperties.log')

        level=0
        head = myLogger.tsGetLoggerPath()
        tail = 'tsLogger-Dict.txt'
        deviceName = '%s/%s' % (head, tail)
        myFile = open(deviceName, 'w+')
        myDictionary = tsLogger.TsLogger.activeLoggerIDs
        tsrpu.displayDictionary(level, myDictionary, myFile, myLogger=None)
        myFile.close()

        propertyTest(myLogger)

    def getOptions():
        '''
        Parse the command line and return a list of positional arguments
        and a dictionanary of keyword options.

        NOTE: Requirement is an inappropriate, oversimplification.
              Invoking argparse or optparse (deprecated with Python 2.7.0)
              do not produce equivalent output without substantial post
              processing that has not yet been created. This may explain
              inability to migrate use of tsApplication to tsCommandLineEnv
              or to tsWxMultiFrameEnv.