Files
pybricks-api/src/pybricks/tools.py
T

298 lines
8.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# SPDX-License-Identifier: MIT
# Copyright (c) 2018-2023 The Pybricks Authors
"""Common tools for timing, data logging, and linear algebra."""
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Optional, Sequence, Tuple, overload, Coroutine
if TYPE_CHECKING:
from ._common import MaybeAwaitable, MaybeAwaitableTuple
from .parameters import Number
def wait(time: Number) -> MaybeAwaitable:
"""wait(time)
Pauses the user program for a specified amount of time.
Arguments:
time (Number, ms): How long to wait.
"""
class StopWatch:
"""A stopwatch to measure time intervals. Similar to the stopwatch
feature on your phone."""
def __init__(self): ...
def time(self) -> int:
"""time() -> int: ms
Gets the current time of the stopwatch.
Returns:
Elapsed time.
"""
def pause(self) -> None:
"""pause()
Pauses the stopwatch."""
def resume(self) -> None:
"""resume()
Resumes the stopwatch."""
def reset(self) -> None:
"""reset()
Resets the stopwatch time to 0.
The run state is unaffected:
* If it was paused, it stays paused (but now at 0).
* If it was running, it stays running (but starting again from 0).
"""
class DataLog:
"""Create a file and log data."""
def __init__(
self,
*headers: str,
name: str = "log",
timestamp: bool = True,
extension: str = "csv",
append: bool = False,
):
"""DataLog(*headers, name='log', timestamp=True, extension='csv', append=False)
Arguments:
headers (str, str, ...): Column headers. These are the
names of the data columns. For example, choose ``'time'`` and
``'angle'``.
name (str): Name of the file.
timestamp (bool): Choose ``True`` to add the date and time to the
file name. This way, your file has a unique name.
Choose ``False`` to omit the timestamp.
extension (str): File extension.
append (bool): Choose ``True`` to reopen an existing data log file
and append data to it. Choose ``False`` to clear existing
data. If the file does not exist yet, an empty file will be
created either way.
"""
def log(self, *values: Any) -> None:
"""log(value1, value2, ...)
Saves one or more values on a new line in the file.
Arguments:
values (object, object, ...): One or more objects or values.
"""
class Matrix:
"""Mathematical representation of a matrix. It supports
addition (``A + B``), subtraction (``A - B``),
and matrix multiplication (``A * B``) for matrices of compatible size.
It also supports scalar multiplication (``c * A`` or ``A * c``)
and scalar division (``A / c``).
A :class:`.Matrix` object is immutable."""
def __add__(self, other) -> Matrix: ...
def __iadd__(self, other) -> Matrix: ...
def __sub__(self, other) -> Matrix: ...
def __isub__(self, other) -> Matrix: ...
def __mul__(self, other) -> Matrix: ...
def __rmul__(self, other) -> Matrix: ...
def __imul__(self, other) -> Matrix: ...
def __truediv__(self, other) -> Matrix: ...
def __itruediv__(self, other) -> Matrix: ...
def __floordiv__(self, other) -> Matrix: ...
def __ifloordiv__(self, other) -> Matrix: ...
def __init__(self, rows: Sequence[Sequence[float]]):
"""Matrix(rows)
Arguments:
rows (list): List of rows. Each row is itself a list of numbers.
"""
@property
def T(self) -> Matrix: # noqa: N802
"""Returns a new :class:`.Matrix` that is the transpose of the
original."""
@property
def shape(self) -> Tuple[int, int]:
"""Returns a tuple (``m``, ``n``),
where ``m`` is the number of rows and ``n`` is the number of columns.
"""
@overload
def vector(x: float, y: float) -> Matrix:
"""
Convenience function to create a :class:`.Matrix` with the shape (``2``, ``1``).
Arguments:
x (float): x-coordinate of the vector.
y (float): y-coordinate of the vector.
Returns:
A matrix with the shape of a column vector.
"""
@overload
def vector(x: float, y: float, z: float) -> Matrix:
"""
Convenience function to create a :class:`.Matrix` with the shape (``3``, ``1``).
Arguments:
x (float): x-coordinate of the vector.
y (float): y-coordinate of the vector.
z (float): z-coordinate of the vector.
Returns:
A matrix with the shape of a column vector.
"""
def vector(*args):
"""
vector(x, y) -> Matrix
vector(x, y, z) -> Matrix
Convenience function to create a :class:`.Matrix` with the
shape (``2``, ``1``) or (``3``, ``1``).
Arguments:
x (float): x-coordinate of the vector.
y (float): y-coordinate of the vector.
z (float): z-coordinate of the vector (optional).
Returns:
A matrix with the shape of a column vector.
"""
def cross(a: Matrix, b: Matrix) -> Matrix:
"""
cross(a, b) -> Matrix
Gets the cross product ``a`` × ``b`` of two vectors.
Arguments:
a (Matrix): A three-dimensional vector.
b (Matrix): A three-dimensional vector.
Returns:
The cross product, also a three-dimensional vector.
"""
def read_input_byte(last: bool = False, chr: bool = False) -> Optional[int | str]:
"""
read_input_byte() -> int | str | None
Reads one byte from standard input without blocking and removes it from the
input buffer.
Arguments:
last (bool): Choose ``True`` to read the last (most recent) byte in the buffer and discard the rest.
Choose ``False`` to read only the first (oldest) byte.
chr (bool): Choose ``True`` to convert the result to a one-character string.
Returns:
The byte that was read, as a numeric value (``0`` to ``255``) or
string (e.g. ``"B"``). Returns ``None`` if no data is available. If
``chr=True``, it also return ``None`` if the byte that was read is not
printable as a character.
"""
def hub_menu(*symbols: int | str) -> int | str:
"""
hub_menu(symbol1, symbol2, ...) -> int | str
Shows a menu on the hub display and waits for the user to select an item
using the buttons. Can be used in your own menu-program that lets you
choose which of your other programs to run.
Note that this is just a convenience function that combines the display,
buttons, and waits to make a simple menu. This means that it can be used
anywhere in a program, not just at the start.
Arguments:
symbol1 (int or str): The first symbol to show in the menu.
symbol2 (int or str): The second symbol, and so on...
Returns:
The selected symbol.
"""
def multitask(*coroutines: Coroutine, race=False) -> MaybeAwaitableTuple:
"""
multitask(coroutine1, coroutine2, ...) -> Tuple
Runs multiple coroutines concurrently. This creates a new coroutine that
can be used like any other, including in another ``multitask`` statement.
Arguments:
coroutines (coroutine, coroutine, ...): One or more coroutines to run
in parallel.
race (bool): Choose ``False`` to wait for all coroutines to finish.
Choose ``True`` to wait for one coroutine to finish and then
cancel the others, as if it's a "race".
Returns:
Tuple of the return values of each coroutine. Unfinished coroutines
will have ``None`` as their return value.
"""
def run_task(coroutine: Coroutine) -> Optional[bool]:
"""
run_task(coroutine) -> bool | None
Runs a coroutine from start to finish while blocking the rest of the
program. This is used primarily to run the main coroutine of a program.
Calls to this function are not allowed to be nested.
Arguments:
coroutine (coroutine): The main coroutine to run.
Returns:
If no ``coroutine`` is given, this function returns whether the
run loop is currently active (``True``) or not (``False``).
"""
# HACK: hide from jedi
if TYPE_CHECKING:
del Number
del MaybeAwaitable
del MaybeAwaitableTuple