codetiming


Namecodetiming JSON
Version 1.4.0 PyPI version JSON
download
home_pageNone
SummaryA flexible, customizable timer for your Python code.
upload_time2022-11-08 07:12:29
maintainerNone
docs_urlNone
authorNone
requires_python>=3.6
licenseNone
keywords timer class contextmanager decorator
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            [![Python Timer Functions: Three Ways to Monitor Your Code](https://files.realpython.com/media/Three-Ways-to-Time-Your-Code_Watermarked.8d561fcc7a35.jpg)](https://realpython.com/python-timer)

# `codetiming` - A flexible, customizable timer for your Python code

[![Latest version](https://img.shields.io/pypi/v/codetiming)](https://pypi.org/project/codetiming/)
[![Python versions](https://img.shields.io/pypi/pyversions/codetiming)](https://pypi.org/project/codetiming/)
[![Downloads](https://img.shields.io/pypi/dd/codetiming)](https://pypi.org/project/codetiming/)
[![Tests](https://img.shields.io/github/workflow/status/realpython/codetiming/unit_tests?label=tests)](https://github.com/realpython/codetiming/actions)
[![Checked with mypy](http://www.mypy-lang.org/static/mypy_badge.svg)](http://mypy-lang.org/)
[![Interrogate DocStrings](https://raw.githubusercontent.com/realpython/codetiming/main/interrogate_badge.svg)](https://interrogate.readthedocs.io/)
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
[![MIT license](https://img.shields.io/pypi/l/codetiming)](https://mit-license.org/)

Install `codetiming` from PyPI:

```
$ python -m pip install codetiming
```

The source code is [available on GitHub](https://github.com/realpython/codetiming).

For a complete tutorial on `codetiming`, see [Python Timer Functions: Three Ways to Monitor Your Code](https://realpython.com/python-timer) on [Real Python](https://realpython.com/).

## Basic Usage

You can use `codetiming.Timer` in several different ways:

1. As a **class**:

    ```python
    t = Timer(name="class")
    t.start()
    # Do something
    t.stop()
    ```

2. As a **context manager**:

    ```python
    with Timer(name="context manager"):
        # Do something
    ```

3. As a **decorator**:

    ```python
    @Timer(name="decorator")
    def stuff():
        # Do something
    ```


## Arguments

`Timer` accepts the following arguments when it's created. All arguments are optional:

- **`name`:** An optional name for your timer
- **`text`:** The text that's shown when your timer ends. It should contain a `{}` placeholder that will be filled by the elapsed time in seconds (default: `"Elapsed time: {:.4f} seconds"`)
- **`initial_text`:** Show text when your timer starts. You may provide the string to be logged or `True` to show the default text `"Timer {name} started"` (default: `False`)
- **`logger`:** A function/callable that takes a string argument and will report the elapsed time when the logger is stopped (default: `print()`)

You can turn off explicit reporting of the elapsed time by setting `logger=None`.

In the template text, you can also use explicit attributes to refer to the `name` of the timer or log the elapsed time in `milliseconds`, `seconds` (the default), or `minutes`. For example:

```python
t1 = Timer(name="NamedTimer", text="{name}: {minutes:.1f} minutes")
t2 = Timer(text="Elapsed time: {milliseconds:.0f} ms")
```

Note that the strings used by `text` are **not** f-strings. Instead, they are used as templates that will be populated using `.format()` behind the scenes. If you want to combine the `text` template with an f-string, you need to use double braces for the template values:

```python
t = Timer(text=f"{__file__}: {{:.4f}}")
```

`text` is also allowed to be a callable like a function or a class. If `text` is a callable, it is expected to require one argument: the number of seconds elapsed. It should return a text string that will be logged using logger:

```python
t = Timer(text=lambda secs: f"{secs / 86400:.0f} days")
```

This allows you to use third-party libraries like [`humanfriendly`](https://pypi.org/project/humanfriendly/) to do the text formatting:

```python
from humanfriendly import format_timespan

t1 = Timer(text=format_timespan)
t2 = Timer(text=lambda secs: f"Elapsed time: {format_timespan(secs)}")
```

You may include a text that should be logged when the timer starts by setting `initial_text`:

```python
t = Timer(initial_text="And so it begins ...")
```

You can also set `initial_text=True` to use a default initial text.


## Capturing the Elapsed Time

When using `Timer` as a class, you can capture the elapsed time when calling `.stop()`:

```python
elapsed_time = t.stop()
```

You can also find the last measured elapsed time in the `.last` attribute. The following code will have the same effect as the previous example:

```python
t.stop()
elapsed_time = t.last
```


## Named Timers

Named timers are made available in the class dictionary `Timer.timers`. The elapsed time will accumulate if the same name or same timer is used several times. Consider the following example:

```pycon
>>> import logging
>>> from codetiming import Timer

>>> t = Timer("example", text="Time spent: {:.2f}", logger=logging.warning)

>>> t.start()
>>> t.stop()
WARNING:root:Time spent: 3.58
3.5836678670002584

>>> with t:
...     _ = list(range(100_000_000))
... 
WARNING:root:Time spent: 1.73

>>> Timer.timers
{'example': 5.312697440000193}
```

The example shows how you can redirect the timer output to the logging module. Note that the elapsed time spent in the two different uses of `t` has been accumulated in `Timer.timers`.

You can also get simple statistics about your named timers. Continuing from the example above:

```pycon
>>> Timer.timers.max("example")
3.5836678670002584

>>> Timer.timers.mean("example")
2.6563487200000964

>>> Timer.timers.stdev("example")
1.311427314335879
```

`timers` support `.count()`, `.total()`, `.min()`, `.max()`, `.mean()`, `.median()`, and `.stdev()`.


## Acknowledgments

`codetiming` is based on a similar module initially developed for the [Midgard Geodesy library](https://kartverket.github.io/midgard/) at the [Norwegian Mapping Authority](https://www.kartverket.no/en/).
            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "codetiming",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.6",
    "maintainer_email": null,
    "keywords": "timer,class,contextmanager,decorator",
    "author": null,
    "author_email": "Geir Arne Hjelle <geirarne@gmail.com>, Real Python <info@realpython.com>",
    "download_url": "https://files.pythonhosted.org/packages/ad/4e/c40bf151af20ba2748bd6ea24e484d7b6196b1056ba3a1a4ee33b6939c37/codetiming-1.4.0.tar.gz",
    "platform": null,
    "description": "[![Python Timer Functions: Three Ways to Monitor Your Code](https://files.realpython.com/media/Three-Ways-to-Time-Your-Code_Watermarked.8d561fcc7a35.jpg)](https://realpython.com/python-timer)\n\n# `codetiming` - A flexible, customizable timer for your Python code\n\n[![Latest version](https://img.shields.io/pypi/v/codetiming)](https://pypi.org/project/codetiming/)\n[![Python versions](https://img.shields.io/pypi/pyversions/codetiming)](https://pypi.org/project/codetiming/)\n[![Downloads](https://img.shields.io/pypi/dd/codetiming)](https://pypi.org/project/codetiming/)\n[![Tests](https://img.shields.io/github/workflow/status/realpython/codetiming/unit_tests?label=tests)](https://github.com/realpython/codetiming/actions)\n[![Checked with mypy](http://www.mypy-lang.org/static/mypy_badge.svg)](http://mypy-lang.org/)\n[![Interrogate DocStrings](https://raw.githubusercontent.com/realpython/codetiming/main/interrogate_badge.svg)](https://interrogate.readthedocs.io/)\n[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)\n[![MIT license](https://img.shields.io/pypi/l/codetiming)](https://mit-license.org/)\n\nInstall `codetiming` from PyPI:\n\n```\n$ python -m pip install codetiming\n```\n\nThe source code is [available on GitHub](https://github.com/realpython/codetiming).\n\nFor a complete tutorial on `codetiming`, see [Python Timer Functions: Three Ways to Monitor Your Code](https://realpython.com/python-timer) on [Real Python](https://realpython.com/).\n\n## Basic Usage\n\nYou can use `codetiming.Timer` in several different ways:\n\n1. As a **class**:\n\n    ```python\n    t = Timer(name=\"class\")\n    t.start()\n    # Do something\n    t.stop()\n    ```\n\n2. As a **context manager**:\n\n    ```python\n    with Timer(name=\"context manager\"):\n        # Do something\n    ```\n\n3. As a **decorator**:\n\n    ```python\n    @Timer(name=\"decorator\")\n    def stuff():\n        # Do something\n    ```\n\n\n## Arguments\n\n`Timer` accepts the following arguments when it's created. All arguments are optional:\n\n- **`name`:** An optional name for your timer\n- **`text`:** The text that's shown when your timer ends. It should contain a `{}` placeholder that will be filled by the elapsed time in seconds (default: `\"Elapsed time: {:.4f} seconds\"`)\n- **`initial_text`:** Show text when your timer starts. You may provide the string to be logged or `True` to show the default text `\"Timer {name} started\"` (default: `False`)\n- **`logger`:** A function/callable that takes a string argument and will report the elapsed time when the logger is stopped (default: `print()`)\n\nYou can turn off explicit reporting of the elapsed time by setting `logger=None`.\n\nIn the template text, you can also use explicit attributes to refer to the `name` of the timer or log the elapsed time in `milliseconds`, `seconds` (the default), or `minutes`. For example:\n\n```python\nt1 = Timer(name=\"NamedTimer\", text=\"{name}: {minutes:.1f} minutes\")\nt2 = Timer(text=\"Elapsed time: {milliseconds:.0f} ms\")\n```\n\nNote that the strings used by `text` are **not** f-strings. Instead, they are used as templates that will be populated using `.format()` behind the scenes. If you want to combine the `text` template with an f-string, you need to use double braces for the template values:\n\n```python\nt = Timer(text=f\"{__file__}: {{:.4f}}\")\n```\n\n`text` is also allowed to be a callable like a function or a class. If `text` is a callable, it is expected to require one argument: the number of seconds elapsed. It should return a text string that will be logged using logger:\n\n```python\nt = Timer(text=lambda secs: f\"{secs / 86400:.0f} days\")\n```\n\nThis allows you to use third-party libraries like [`humanfriendly`](https://pypi.org/project/humanfriendly/) to do the text formatting:\n\n```python\nfrom humanfriendly import format_timespan\n\nt1 = Timer(text=format_timespan)\nt2 = Timer(text=lambda secs: f\"Elapsed time: {format_timespan(secs)}\")\n```\n\nYou may include a text that should be logged when the timer starts by setting `initial_text`:\n\n```python\nt = Timer(initial_text=\"And so it begins ...\")\n```\n\nYou can also set `initial_text=True` to use a default initial text.\n\n\n## Capturing the Elapsed Time\n\nWhen using `Timer` as a class, you can capture the elapsed time when calling `.stop()`:\n\n```python\nelapsed_time = t.stop()\n```\n\nYou can also find the last measured elapsed time in the `.last` attribute. The following code will have the same effect as the previous example:\n\n```python\nt.stop()\nelapsed_time = t.last\n```\n\n\n## Named Timers\n\nNamed timers are made available in the class dictionary `Timer.timers`. The elapsed time will accumulate if the same name or same timer is used several times. Consider the following example:\n\n```pycon\n>>> import logging\n>>> from codetiming import Timer\n\n>>> t = Timer(\"example\", text=\"Time spent: {:.2f}\", logger=logging.warning)\n\n>>> t.start()\n>>> t.stop()\nWARNING:root:Time spent: 3.58\n3.5836678670002584\n\n>>> with t:\n...     _ = list(range(100_000_000))\n... \nWARNING:root:Time spent: 1.73\n\n>>> Timer.timers\n{'example': 5.312697440000193}\n```\n\nThe example shows how you can redirect the timer output to the logging module. Note that the elapsed time spent in the two different uses of `t` has been accumulated in `Timer.timers`.\n\nYou can also get simple statistics about your named timers. Continuing from the example above:\n\n```pycon\n>>> Timer.timers.max(\"example\")\n3.5836678670002584\n\n>>> Timer.timers.mean(\"example\")\n2.6563487200000964\n\n>>> Timer.timers.stdev(\"example\")\n1.311427314335879\n```\n\n`timers` support `.count()`, `.total()`, `.min()`, `.max()`, `.mean()`, `.median()`, and `.stdev()`.\n\n\n## Acknowledgments\n\n`codetiming` is based on a similar module initially developed for the [Midgard Geodesy library](https://kartverket.github.io/midgard/) at the [Norwegian Mapping Authority](https://www.kartverket.no/en/).",
    "bugtrack_url": null,
    "license": null,
    "summary": "A flexible, customizable timer for your Python code.",
    "version": "1.4.0",
    "project_urls": {
        "Homepage": "https://realpython.com/python-timer",
        "Source Code": "https://github.com/realpython/codetiming",
        "Tutorial": "https://realpython.com/python-timer"
    },
    "split_keywords": [
        "timer",
        "class",
        "contextmanager",
        "decorator"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "bc91e4a2b7c64e738beefddfa24b409d6eecb16c378bde01578918b6ea722a09",
                "md5": "7ce6f60f7a8086f29eb1b9430547e676",
                "sha256": "3b80f409bef00941a9755c5524071ce2f72eaa4520f4bc35b33869cde024ccbd"
            },
            "downloads": -1,
            "filename": "codetiming-1.4.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "7ce6f60f7a8086f29eb1b9430547e676",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.6",
            "size": 7165,
            "upload_time": "2022-11-08T07:12:23",
            "upload_time_iso_8601": "2022-11-08T07:12:23.553243Z",
            "url": "https://files.pythonhosted.org/packages/bc/91/e4a2b7c64e738beefddfa24b409d6eecb16c378bde01578918b6ea722a09/codetiming-1.4.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "ad4ec40bf151af20ba2748bd6ea24e484d7b6196b1056ba3a1a4ee33b6939c37",
                "md5": "7e09e06f90757f9c258a0f4275336d2c",
                "sha256": "4937bf913a2814258b87eaaa43d9a1bb24711ffd3557a9ab6934fa1fe3ba0dbc"
            },
            "downloads": -1,
            "filename": "codetiming-1.4.0.tar.gz",
            "has_sig": false,
            "md5_digest": "7e09e06f90757f9c258a0f4275336d2c",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.6",
            "size": 14899,
            "upload_time": "2022-11-08T07:12:29",
            "upload_time_iso_8601": "2022-11-08T07:12:29.361034Z",
            "url": "https://files.pythonhosted.org/packages/ad/4e/c40bf151af20ba2748bd6ea24e484d7b6196b1056ba3a1a4ee33b6939c37/codetiming-1.4.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2022-11-08 07:12:29",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "realpython",
    "github_project": "codetiming",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "tox": true,
    "lcname": "codetiming"
}
        
Elapsed time: 0.27828s