# Source code for timer

    #
    ##
    ##  This file is part of pyFormex 1.0.5  (Sat Feb 16 10:40:32 CET 2019)
    ##  pyFormex is a tool for generating, manipulating and transforming 3D
    ##  geometrical models by sequences of mathematical operations.
    ##  Home page: http://pyformex.org
    ##  Project page:  http://savannah.nongnu.org/projects/pyformex/
    ##  Copyright 2004-2018 (C) Benedict Verhegghe (benedict.verhegghe@ugent.be)
    ##  Distributed under the GNU General Public License version 3 or later.
    ##
    ##  This program is free software: you can redistribute it and/or modify
    ##  it under the terms of the GNU General Public License as published by
    ##  the Free Software Foundation, either version 3 of the License, or
    ##  (at your option) any later version.
    ##
    ##  This program is distributed in the hope that it will be useful,
    ##  but WITHOUT ANY WARRANTY; without even the implied warranty of
    ##  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    ##  GNU General Public License for more details.
    ##
    ##  You should have received a copy of the GNU General Public License
    ##  along with this program.  If not, see http://www.gnu.org/licenses/.
    ##
    """A timer class.

    """
    from __future__ import absolute_import, division, print_function

    from datetime import datetime
    from pyformex import round

    class Timer(object):
        """A class for measuring elapsed time.

        A Timer object measures elapsed real time since a specified time, which
        by default is the time of the creation of the Timer. A builtin tag can
        be used for identifying subsequent measurements.

        Parameters:

        - `start`: a datetime object. If not specified, the time of the creation
          of the Timer is used.
        - `tag`: a string used as an identifier for the current measurement. It
          is displayed when printing the Timer value

        Example:

        >>> import time
        >>> t = Timer()
        >>> time.sleep(1.234)
        >>> r = t.read()
        >>> print(r.days, r.seconds, r.microseconds)  # doctest: +ELLIPSIS
        0 1 23...
        >>> t.seconds()  # doctest: +ELLIPSIS
        1.23...
        >>> t.seconds(rounded=True)
        1

        Note that the precise result of microseconds will be slightly larger
        than the input sleep time. The precise result is unknown, therefore
        ellipses are shown.

        >>> tim = Timer(tag="First")
        >>> time.sleep(0.13)
        >>> print(tim)
        Timer: First: 0.13 sec.
        >>> tim.reset(tag="Next")
        >>> time.sleep(0.13)
        >>> print(tim)
        Timer: Next: 0.13 sec.

        """

        def __init__(self, start=None, tag=None):
            """Create and reset the timer."""
            self.reset(start,tag)

        def reset(self, start=None, tag=None):
            """(Re)Start the timer.

            Sets the start time of the timer to the specified value, or to
            the current time if not specified. Sets the tag to the specified
            value or to 'None'.

            Parameters:

            - `start`: a datetime object. If not specified, the current time as
              returned by datetime.now() is used.
            - `tag`: a string used as an identifier for the current measurement
            """
            if isinstance(start, datetime):
                self.start = start
            else:
                self.start = datetime.now()
            self.tag = str(tag)

        def read(self, reset=False):
            """Read the timer.

            Returns the elapsed time since the last reset (or the creation
            of the timer) as a datetime.timedelta object.

            If reset=True, the timer is reset to the time of reading.
            """
            now = datetime.now()
            ret = now - self.start
            if reset:
                self.start = now
            return ret

        def seconds(self, reset=False, rounded=False):
            """Return the timer readings in seconds.

            The default return value is a rounded integer number of seconds.
            With ``rounded == False``, a floating point value with granularity of
            1 microsecond is returned.

            If reset=True, the timer is reset at the time of reading.
            """
            e = self.read(reset)
            sec = e.days*24*3600 + e.seconds + e.microseconds / 1000000.
            if rounded:
                sec = round(sec)
            return sec

        def report(self, format="%.2f sec."):
            """Report the elapsed time in seconds since last reset"""
            return ("Timer: %s: "+format) % (self.tag,self.seconds(False))

        def __str__(self):
            """Report the elapsed time in a standard format"""
            return self.report()

    # End