From 095c3be6e490c7010326fe8242beede9e3577ccc Mon Sep 17 00:00:00 2001 From: Jim Date: Mon, 29 Aug 2022 06:24:00 -0400 Subject: [PATCH] release 0.8.2a1 --- py5/__init__.py | 2577 +++++++++++++++++++----------------- py5/graphics.py | 128 +- py5/jars/core.jar | Bin 1015391 -> 1015216 bytes py5/jars/dxf/dxf.jar | Bin 2539 -> 2532 bytes py5/jars/pdf/pdf.jar | Bin 5568 -> 5561 bytes py5/jars/py5.jar | Bin 34256 -> 34259 bytes py5/jars/svg/svg.jar | Bin 3400 -> 3393 bytes py5/mixins/math.py | 4 +- py5/mixins/print_tools.py | 9 +- py5/reference.py | 27 +- py5/shape.py | 128 +- py5/sketch.py | 194 ++- py5/vector.py | 21 +- py5_tools/__init__.py | 2 +- py5_tools/imported.py | 9 +- py5_tools/kernel/kernel.py | 2 +- py5_tools/py5bot/kernel.py | 2 +- py5_tools/reference.py | 2 + py5_tools/split_setup.py | 5 +- py5_tools/utilities.py | 6 +- setup.py | 2 +- 21 files changed, 1642 insertions(+), 1476 deletions(-) diff --git a/py5/__init__.py b/py5/__init__.py index 1669d0e..b0c15d6 100644 --- a/py5/__init__.py +++ b/py5/__init__.py @@ -47,7 +47,7 @@ py5_tools.add_jars(str(base_path / 'jars')) # if the cwd has a jars subdirectory, add that next py5_tools.add_jars(Path('jars')) - # if the PY5_CLASSPATH environment variable exists, add those jars + # if the PY5_JARS environment variable exists, add those jars if (py5_classpath := os.environ.get('PY5_JARS')): py5_tools.add_jars(Path(py5_classpath)) @@ -88,7 +88,7 @@ pass -__version__ = '0.8.1a1' +__version__ = '0.8.2a1' _PY5_USE_IMPORTED_MODE = py5_tools.get_imported_mode() py5_tools._lock_imported_mode() @@ -672,52 +672,52 @@ def apply_matrix(n00: float, n01: float, n02: float, ---------- n00: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 0 of the matrix n01: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 1 of the matrix n02: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 2 of the matrix n03: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 3 of the matrix n10: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 0 of the matrix n11: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 1 of the matrix n12: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 2 of the matrix n13: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 3 of the matrix n20: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 0 of the matrix n21: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 1 of the matrix n22: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 2 of the matrix n23: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 3 of the matrix n30: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 0 of the matrix n31: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 1 of the matrix n32: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 2 of the matrix n33: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 3 of the matrix source: npt.NDArray[np.floating] transformation matrix with a shape of 2x3 for 2D transforms or 4x4 for 3D transforms @@ -769,52 +769,52 @@ def apply_matrix( ---------- n00: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 0 of the matrix n01: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 1 of the matrix n02: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 2 of the matrix n03: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 3 of the matrix n10: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 0 of the matrix n11: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 1 of the matrix n12: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 2 of the matrix n13: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 3 of the matrix n20: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 0 of the matrix n21: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 1 of the matrix n22: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 2 of the matrix n23: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 3 of the matrix n30: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 0 of the matrix n31: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 1 of the matrix n32: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 2 of the matrix n33: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 3 of the matrix source: npt.NDArray[np.floating] transformation matrix with a shape of 2x3 for 2D transforms or 4x4 for 3D transforms @@ -849,52 +849,52 @@ def apply_matrix(source: npt.NDArray[np.floating], /) -> None: ---------- n00: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 0 of the matrix n01: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 1 of the matrix n02: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 2 of the matrix n03: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 3 of the matrix n10: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 0 of the matrix n11: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 1 of the matrix n12: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 2 of the matrix n13: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 3 of the matrix n20: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 0 of the matrix n21: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 1 of the matrix n22: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 2 of the matrix n23: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 3 of the matrix n30: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 0 of the matrix n31: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 1 of the matrix n32: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 2 of the matrix n33: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 3 of the matrix source: npt.NDArray[np.floating] transformation matrix with a shape of 2x3 for 2D transforms or 4x4 for 3D transforms @@ -928,52 +928,52 @@ def apply_matrix(*args): ---------- n00: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 0 of the matrix n01: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 1 of the matrix n02: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 2 of the matrix n03: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 3 of the matrix n10: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 0 of the matrix n11: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 1 of the matrix n12: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 2 of the matrix n13: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 3 of the matrix n20: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 0 of the matrix n21: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 1 of the matrix n22: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 2 of the matrix n23: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 3 of the matrix n30: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 0 of the matrix n31: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 1 of the matrix n32: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 2 of the matrix n33: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 3 of the matrix source: npt.NDArray[np.floating] transformation matrix with a shape of 2x3 for 2D transforms or 4x4 for 3D transforms @@ -10907,6 +10907,9 @@ def push() -> None: ``push_matrix()``, ``pop_matrix()``, ``push_style()``, and ``pop_style()``. The difference is that ``push()`` and ``pop()`` control both the transformations (rotate, scale, translate) and the drawing styles at the same time. + + This method can be used as a context manager to ensure that ``pop()`` always + gets called, as shown in the last example. """ return _py5sketch.push() @@ -10926,6 +10929,9 @@ def push_matrix() -> None: ``push_matrix()`` and ``pop_matrix()`` are used in conjuction with the other transformation functions and may be embedded to control the scope of the transformations. + + This method can be used as a context manager to ensure that ``pop_matrix()`` + always gets called, as shown in the last example. """ return _py5sketch.push_matrix() @@ -10953,6 +10959,9 @@ def push_style() -> None: ``ellipse_mode()``, ``shape_mode()``, ``color_mode()``, ``text_align()``, ``text_font()``, ``text_mode()``, ``text_size()``, ``text_leading()``, ``emissive()``, ``specular()``, ``shininess()``, and ``ambient()``. + + This method can be used as a context manager to ensure that ``pop_style()`` + always gets called, as shown in the last example. """ return _py5sketch.push_style() @@ -12890,6 +12899,14 @@ def size(width: int, height: int, /) -> None: * ``SVG``: The ``SVG`` renderer draws 2D graphics directly to an SVG file. This is great for importing into other vector programs or using for digital fabrication. + + When using the ``PDF`` and ``SVG`` renderers with the ``size()`` method, you + must use the ``path`` parameter to specify the file to write the output to. No + window will open while the Sketch is running. You must also call + ``exit_sketch()`` to exit the Sketch and write the completed output to the file. + Without this call, the Sketch will not exit and the output file will be empty. + If you would like to draw 3D objects to a PDF or SVG file, use the ``P3D`` + renderer and the strategy described in ``begin_raw()``. """ pass @@ -12982,6 +12999,14 @@ def size(width: int, height: int, renderer: str, /) -> None: * ``SVG``: The ``SVG`` renderer draws 2D graphics directly to an SVG file. This is great for importing into other vector programs or using for digital fabrication. + + When using the ``PDF`` and ``SVG`` renderers with the ``size()`` method, you + must use the ``path`` parameter to specify the file to write the output to. No + window will open while the Sketch is running. You must also call + ``exit_sketch()`` to exit the Sketch and write the completed output to the file. + Without this call, the Sketch will not exit and the output file will be empty. + If you would like to draw 3D objects to a PDF or SVG file, use the ``P3D`` + renderer and the strategy described in ``begin_raw()``. """ pass @@ -13074,6 +13099,14 @@ def size(width: int, height: int, renderer: str, path: str, /) -> None: * ``SVG``: The ``SVG`` renderer draws 2D graphics directly to an SVG file. This is great for importing into other vector programs or using for digital fabrication. + + When using the ``PDF`` and ``SVG`` renderers with the ``size()`` method, you + must use the ``path`` parameter to specify the file to write the output to. No + window will open while the Sketch is running. You must also call + ``exit_sketch()`` to exit the Sketch and write the completed output to the file. + Without this call, the Sketch will not exit and the output file will be empty. + If you would like to draw 3D objects to a PDF or SVG file, use the ``P3D`` + renderer and the strategy described in ``begin_raw()``. """ pass @@ -13165,6 +13198,14 @@ def size(*args): * ``SVG``: The ``SVG`` renderer draws 2D graphics directly to an SVG file. This is great for importing into other vector programs or using for digital fabrication. + + When using the ``PDF`` and ``SVG`` renderers with the ``size()`` method, you + must use the ``path`` parameter to specify the file to write the output to. No + window will open while the Sketch is running. You must also call + ``exit_sketch()`` to exit the Sketch and write the completed output to the file. + Without this call, the Sketch will not exit and the output file will be empty. + If you would like to draw 3D objects to a PDF or SVG file, use the ``P3D`` + renderer and the strategy described in ``begin_raw()``. """ return _py5sketch.size(*args) @@ -17404,80 +17445,6 @@ def year() -> int: """ return Sketch.year() -############################################################################## -# module functions from print_tools.py -############################################################################## - - -def set_println_stream(println_stream: Any) -> None: - """Customize where the output of ``println()`` goes. - - Parameters - ---------- - - println_stream: Any - println stream object to be used by println method - - Notes - ----- - - Customize where the output of ``println()`` goes. - - When running a Sketch asynchronously through Jupyter Notebook, any ``print`` - statements using Python's builtin function will always appear in the output of - the currently active cell. This will rarely be desirable, as the active cell - will keep changing as the user executes code elsewhere in the notebook. The - ``println()`` method was created to provide users with print functionality in a - Sketch without having to cope with output moving from one cell to the next. Use - ``set_println_stream`` to change how the output is handled. The - ``println_stream`` object must provide ``init()`` and ``print()`` methods, as - shown in the example. The example demonstrates how to configure py5 to output - text to an IPython Widget. - """ - return _py5sketch.set_println_stream(println_stream) - - -def println( - *args, - sep: str = ' ', - end: str = '\n', - stderr: bool = False) -> None: - """Print text or other values to the screen. - - Parameters - ---------- - - args - values to be printed - - end: str = '\\n' - string appended after the last value, defaults to newline character - - sep: str = ' ' - string inserted between values, defaults to a space - - stderr: bool = False - use stderr instead of stdout - - Notes - ----- - - Print text or other values to the screen. For a Sketch running outside of a - Jupyter Notebook, this method will behave the same as the Python's builtin - ``print`` method. For Sketches running in a Jupyter Notebook, this will place - text in the output of the cell that made the ``run_sketch()`` call. - - When running a Sketch asynchronously through Jupyter Notebook, any ``print`` - statements using Python's builtin function will always appear in the output of - the currently active cell. This will rarely be desirable, as the active cell - will keep changing as the user executes code elsewhere in the notebook. This - method was created to provide users with print functionality in a Sketch without - having to cope with output moving from one cell to the next. - - Use ``set_println_stream()`` to customize the behavior of ``println()``. - """ - return _py5sketch.println(*args, sep=sep, end=end, stderr=stderr) - ############################################################################## # module functions from data.py ############################################################################## @@ -17567,1238 +17534,905 @@ def parse_json(serialized_json: Any, **kwargs: dict[str, Any]) -> Any: return Sketch.parse_json(serialized_json, **kwargs) ############################################################################## -# module functions from pixels.py +# module functions from math.py ############################################################################## -def load_np_pixels() -> None: - """Loads the pixel data of the current display window into the ``np_pixels[]`` - array. +def hex_color(color: int) -> str: + """Convert a color value to a hex color string. + + Parameters + ---------- + + color: int + any color value Notes ----- - Loads the pixel data of the current display window into the ``np_pixels[]`` - array. This method must always be called before reading from or writing to - ``np_pixels[]``. Subsequent changes to the display window will not be reflected - in ``np_pixels[]`` until ``load_np_pixels()`` is called again. - - The ``load_np_pixels()`` method is similar to ``load_pixels()`` in that - ``load_np_pixels()`` must be called before reading from or writing to - ``np_pixels[]`` just as ``load_pixels()`` must be called before reading from or - writing to ``pixels[]``. + Convert a color value to a hex color string. Processing and py5 store color + values in 32 bit integers that are inconvenient for a human to parse. To + interpret these values, one can use methods like ``red()``, ``green()``, and + ``blue()`` to extract color channel values from the 32 bit integers. This method + provides an alternative approach, converting the 32 bit integer into a string + such as ``'#0F3FF0FF'``. The hex string has 8 hexadecimal values following a + ``#`` character. The first two values represent the red value, the next two + green, the next two blue, and the last two alpha. This is consistent with CSS 8 + digit hex colors. - Note that ``load_np_pixels()`` will as a side effect call ``load_pixels()``, so - if your code needs to read ``np_pixels[]`` and ``pixels[]`` simultaneously, - there is no need for a separate call to ``load_pixels()``. However, be aware - that modifying both ``np_pixels[]`` and ``pixels[]`` simultaneously will likely - result in the updates to ``pixels[]`` being discarded. + Conveniently, the hex color string returned by this method can also be used as + parameter for other methods that accept color values. Observe how this is done + in the example code. """ - return _py5sketch.load_np_pixels() + return Sketch.hex_color(color) -def update_np_pixels() -> None: - """Updates the display window with the data in the ``np_pixels[]`` array. +def sin(angle: Union[float, npt.ArrayLike]) -> Union[float, npt.NDArray]: + """Calculates the sine of an angle. + + Parameters + ---------- + + angle: Union[float, npt.ArrayLike] + angle in radians Notes ----- - Updates the display window with the data in the ``np_pixels[]`` array. Use in - conjunction with ``load_np_pixels()``. If you're only reading pixels from the - array, there's no need to call ``update_np_pixels()`` — updating is only - necessary to apply changes. + Calculates the sine of an angle. This function expects the values of the angle + parameter to be provided in radians (values from ``0`` to ``TWO_PI``). Values + are returned in the range -1 to 1. - The ``update_np_pixels()`` method is similar to ``update_pixels()`` in that - ``update_np_pixels()`` must be called after modifying ``np_pixels[]`` just as - ``update_pixels()`` must be called after modifying ``pixels[]``. + This function makes a call to the numpy ``sin()`` function. """ - return _py5sketch.update_np_pixels() - - -np_pixels: npt.NDArray[np.uint8] = None + return Sketch.sin(angle) -def set_np_pixels(array: npt.NDArray[np.uint8], bands: str = 'ARGB') -> None: - """Set the entire contents of ``np_pixels[]`` to the contents of another properly - sized and typed numpy array. +def cos(angle: Union[float, npt.ArrayLike]) -> Union[float, npt.NDArray]: + """Calculates the cosine of an angle. Parameters ---------- - array: npt.NDArray[np.uint8] - properly sized numpy array to be copied to np_pixels[] - - bands: str = 'ARGB' - color channels in the array's third dimension + angle: Union[float, npt.ArrayLike] + angle in radians Notes ----- - Set the entire contents of ``np_pixels[]`` to the contents of another properly - sized and typed numpy array. The size of ``array``'s first and second dimensions - must match the height and width of the Sketch window, respectively. The array's - ``dtype`` must be ``np.uint8``. - - The ``bands`` parameter is used to interpret the ``array``'s color channel - dimension (the array's third dimension). It can be one of ``'L'`` (single- - channel grayscale), ``'ARGB'``, ``'RGB'``, or ``'RGBA'``. If there is no alpha - channel, ``array`` is assumed to have no transparency, but recall that the - display window's pixels can never be transparent so any transparency in - ``array`` will have no effect. If the ``bands`` parameter is ``'L'``, - ``array``'s third dimension is optional. - - This method makes its own calls to ``load_np_pixels()`` and - ``update_np_pixels()`` so there is no need to call either explicitly. + Calculates the cosine of an angle. This function expects the values of the angle + parameter to be provided in radians (values from ``0`` to ``TWO_PI``). Values + are returned in the range -1 to 1. - This method exists because setting the array contents with the code - ``py5.np_pixels = array`` will cause an error, while the correct syntax, - ``py5.np_pixels[:] = array``, might also be unintuitive for beginners. + This function makes a call to the numpy ``cos()`` function. """ - return _py5sketch.set_np_pixels(array, bands=bands) + return Sketch.cos(angle) -def save(filename: Union[str, - Path, - BytesIO], - *, - format: str = None, - drop_alpha: bool = True, - use_thread: bool = False, - **params) -> None: - """Save the drawing surface to an image file. +def tan(angle: Union[float, npt.ArrayLike]) -> Union[float, npt.NDArray]: + """Calculates the ratio of the sine and cosine of an angle. Parameters ---------- - drop_alpha: bool = True - remove the alpha channel when saving the image - - filename: Union[str, Path, BytesIO] - output filename - - format: str = None - image format, if not determined from filename extension - - params - keyword arguments to pass to the PIL.Image save method - - use_thread: bool = False - write file in separate thread + angle: Union[float, npt.ArrayLike] + angle in radians Notes ----- - Save the drawing surface to an image file. This method uses the Python library - Pillow to write the image, so it can save images in any format that that library - supports. - - Use the ``drop_alpha`` parameter to drop the alpha channel from the image. This - defaults to ``True``. Some image formats such as JPG do not support alpha - channels, and Pillow will throw an error if you try to save an image with the - alpha channel in that format. + Calculates the ratio of the sine and cosine of an angle. This function expects + the values of the angle parameter to be provided in radians (values from ``0`` + to ``TWO_PI``). Values are returned in the range infinity to -infinity. - The ``use_thread`` parameter will save the image in a separate Python thread. - This improves performance by returning before the image has actually been - written to the file. + This function makes a call to the numpy ``tan()`` function. """ - return _py5sketch.save( - filename, - format=format, - drop_alpha=drop_alpha, - use_thread=use_thread, - **params) - -############################################################################## -# module functions from threads.py -############################################################################## + return Sketch.tan(angle) -def launch_thread( - f: Callable, - name: str = None, - *, - daemon: bool = True, - args: tuple = None, - kwargs: dict = None) -> str: - """Launch a new thread to execute a function in parallel with your Sketch code. +def asin(value: Union[float, npt.ArrayLike]) -> Union[float, npt.NDArray]: + """The inverse of ``sin()``, returns the arc sine of a value. Parameters ---------- - args: tuple = None - positional arguments to pass to the given function + value: Union[float, npt.ArrayLike] + value in the range of -1 to 1 whose arc sine is to be returned - daemon: bool = True - if the thread should be a daemon thread + Notes + ----- - f: Callable - function to call in the launched thread + The inverse of ``sin()``, returns the arc sine of a value. This function expects + the values in the range of -1 to 1 and values are returned in the range + ``-HALF_PI`` to ``HALF_PI``. - kwargs: dict = None - keyword arguments to pass to the given function + This function makes a call to the numpy ``asin()`` function. + """ + return Sketch.asin(value) - name: str = None - name of thread to be created - Notes - ----- +def acos(value: Union[float, npt.ArrayLike]) -> Union[float, npt.NDArray]: + """The inverse of ``cos()``, returns the arc cosine of a value. - Launch a new thread to execute a function in parallel with your Sketch code. - This can be useful for executing non-py5 code that would otherwise slow down the - animation thread and reduce the Sketch's frame rate. + Parameters + ---------- - The ``name`` parameter is optional but useful if you want to monitor the thread - with other methods such as ``has_thread()``. If the provided ``name`` is - identical to an already running thread, the running thread will first be stopped - with a call to ``stop_thread()`` with the ``wait`` parameter equal to ``True``. + value: Union[float, npt.ArrayLike] + value in the range of -1 to 1 whose arc cosine is to be returned - Use the ``args`` and ``kwargs`` parameters to pass positional and keyword - arguments to the function. + Notes + ----- - Use the ``daemon`` parameter to make the launched thread a daemon that will run - without blocking Python from exiting. This parameter defaults to ``True``, - meaning that function execution can be interupted if the Python process exits. - Note that if the Python process continues running after the Sketch exits, which - is typically the case when using a Jupyter Notebook, this parameter won't have - any effect unless if you try to restart the Notebook kernel. Generally speaking, - setting this parameter to ``False`` causes problems but it is available for - those who really need it. See ``stop_all_threads()`` for a better approach to - exit threads. + The inverse of ``cos()``, returns the arc cosine of a value. This function + expects the values in the range of -1 to 1 and values are returned in the range + ``0`` to ``PI``. - The new thread is a Python thread, so all the usual caveats about the Global - Interpreter Lock (GIL) apply here. + This function makes a call to the numpy ``acos()`` function. """ - return _py5sketch.launch_thread( - f, name=name, daemon=daemon, args=args, kwargs=kwargs) + return Sketch.acos(value) -def launch_promise_thread( - f: Callable, - name: str = None, - *, - daemon: bool = True, - args: tuple = None, - kwargs: dict = None) -> Py5Promise: - """Create a ``Py5Promise`` object that will store the returned result of a function - when that function completes. +def atan(value: Union[float, npt.ArrayLike]) -> Union[float, npt.NDArray]: + """The inverse of ``tan()``, returns the arc tangent of a value. Parameters ---------- - args: tuple = None - positional arguments to pass to the given function - - daemon: bool = True - if the thread should be a daemon thread - - f: Callable - function to call in the launched thread - - kwargs: dict = None - keyword arguments to pass to the given function - - name: str = None - name of thread to be created + value: Union[float, npt.ArrayLike] + value whose arc tangent is to be returned Notes ----- - Create a ``Py5Promise`` object that will store the returned result of a function - when that function completes. This can be useful for executing non-py5 code that - would otherwise slow down the animation thread and reduce the Sketch's frame - rate. - - The ``Py5Promise`` object has an ``is_ready`` property that will be ``True`` - when the ``result`` property contains the value function ``f`` returned. Before - then, the ``result`` property will be ``None``. - - The ``name`` parameter is optional but useful if you want to monitor the thread - with other methods such as ``has_thread()``. If the provided ``name`` is - identical to an already running thread, the running thread will first be stopped - with a call to ``stop_thread()`` with the ``wait`` parameter equal to ``True``. - - Use the ``args`` and ``kwargs`` parameters to pass positional and keyword - arguments to the function. - - Use the ``daemon`` parameter to make the launched thread a daemon that will run - without blocking Python from exiting. This parameter defaults to ``True``, - meaning that function execution can be interupted if the Python process exits. - Note that if the Python process continues running after the Sketch exits, which - is typically the case when using a Jupyter Notebook, this parameter won't have - any effect unless if you try to restart the Notebook kernel. Generally speaking, - setting this parameter to ``False`` causes problems but it is available for - those who really need it. See ``stop_all_threads()`` for a better approach to - exit threads. + The inverse of ``tan()``, returns the arc tangent of a value. This function + expects the values in the range of -Infinity to Infinity and values are returned + in the range ``-HALF_PI`` to ``HALF_PI``. - The new thread is a Python thread, so all the usual caveats about the Global - Interpreter Lock (GIL) apply here. + This function makes a call to the numpy ``atan()`` function. """ - return _py5sketch.launch_promise_thread( - f, name=name, daemon=daemon, args=args, kwargs=kwargs) + return Sketch.atan(value) -def launch_repeating_thread(f: Callable, name: str = None, *, - time_delay: float = 0, daemon: bool = True, - args: tuple = None, kwargs: dict = None) -> str: - """Launch a new thread that will repeatedly execute a function in parallel with - your Sketch code. +def atan2(y: Union[float, npt.ArrayLike], x: Union[float, + npt.ArrayLike]) -> Union[float, npt.NDArray]: + """Calculates the angle (in radians) from a specified point to the coordinate + origin as measured from the positive x-axis. Parameters ---------- - args: tuple = None - positional arguments to pass to the given function - - daemon: bool = True - if the thread should be a daemon thread - - f: Callable - function to call in the launched thread - - kwargs: dict = None - keyword arguments to pass to the given function - - name: str = None - name of thread to be created + x: Union[float, npt.ArrayLike] + x-coordinate of the point - time_delay: float = 0 - time delay in seconds between calls to the given function + y: Union[float, npt.ArrayLike] + y-coordinate of the point Notes ----- - Launch a new thread that will repeatedly execute a function in parallel with - your Sketch code. This can be useful for executing non-py5 code that would - otherwise slow down the animation thread and reduce the Sketch's frame rate. - - Use the ``time_delay`` parameter to set the time in seconds between one call to - function ``f`` and the next call. Set this parameter to ``0`` if you want each - call to happen immediately after the previous call finishes. If the function - ``f`` takes longer than expected to finish, py5 will wait for it to finish - before making the next call. There will not be overlapping calls to function - ``f``. - - The ``name`` parameter is optional but useful if you want to monitor the thread - with other methods such as ``has_thread()``. If the provided ``name`` is - identical to an already running thread, the running thread will first be stopped - with a call to ``stop_thread()`` with the ``wait`` parameter equal to ``True``. - - Use the ``args`` and ``kwargs`` parameters to pass positional and keyword - arguments to the function. - - Use the ``daemon`` parameter to make the launched thread a daemon that will run - without blocking Python from exiting. This parameter defaults to ``True``, - meaning that function execution can be interupted if the Python process exits. - Note that if the Python process continues running after the Sketch exits, which - is typically the case when using a Jupyter Notebook, this parameter won't have - any effect unless if you try to restart the Notebook kernel. Generally speaking, - setting this parameter to ``False`` causes problems but it is available for - those who really need it. See ``stop_all_threads()`` for a better approach to - exit threads. + Calculates the angle (in radians) from a specified point to the coordinate + origin as measured from the positive x-axis. Values are returned as a float in + the range from ``PI`` to ``-PI``. The ``atan2()`` function is most often used + for orienting geometry to the position of the cursor. Note: The y-coordinate of + the point is the first parameter, and the x-coordinate is the second parameter, + due the the structure of calculating the tangent. - The new thread is a Python thread, so all the usual caveats about the Global - Interpreter Lock (GIL) apply here. + This function makes a call to the numpy ``atan2()`` function. """ - return _py5sketch.launch_repeating_thread( - f, - name=name, - time_delay=time_delay, - daemon=daemon, - args=args, - kwargs=kwargs) + return Sketch.atan2(y, x) -def has_thread(name: str) -> None: - """Determine if a thread of a given name exists and is currently running. +def degrees(radians: Union[float, npt.ArrayLike]) -> Union[float, npt.NDArray]: + """Converts a radian measurement to its corresponding value in degrees. Parameters ---------- - name: str - name of thread + radians: Union[float, npt.ArrayLike] + radian value to convert to degrees Notes ----- - Determine if a thread of a given name exists and is currently running. You can - get the list of all currently running threads with ``list_threads()``. + Converts a radian measurement to its corresponding value in degrees. Radians and + degrees are two ways of measuring the same thing. There are 360 degrees in a + circle and ``2*PI`` radians in a circle. For example, ``90° = PI/2 = + 1.5707964``. All trigonometric functions in py5 require their parameters to be + specified in radians. + + This function makes a call to the numpy ``degrees()`` function. """ - return _py5sketch.has_thread(name) + return Sketch.degrees(radians) -def stop_thread(name: str, wait: bool = False) -> None: - """Stop a thread of a given name. +def radians(degrees: Union[float, npt.ArrayLike]) -> Union[float, npt.NDArray]: + """Converts a degree measurement to its corresponding value in radians. Parameters ---------- - name: str - name of thread - - wait: bool = False - wait for thread to exit before returning + degrees: Union[float, npt.ArrayLike] + degree value to convert to radians Notes ----- - Stop a thread of a given name. The ``wait`` parameter determines if the method - call will return right away or wait for the thread to exit. - - This won't do anything useful if the thread was launched with either - ``launch_thread()`` or ``launch_promise_thread()`` and the ``wait`` parameter is - ``False``. Non-repeating threads are executed once and will stop when they - complete execution. Setting the ``wait`` parameter to ``True`` will merely block - until the thread exits on its own. Killing off a running thread in Python is - complicated and py5 cannot do that for you. If you want a thread to perform some - action repeatedly and be interuptable, use ``launch_repeating_thread()`` - instead. + Converts a degree measurement to its corresponding value in radians. Radians and + degrees are two ways of measuring the same thing. There are 360 degrees in a + circle and ``2*PI`` radians in a circle. For example, ``90° = PI/2 = + 1.5707964``. All trigonometric functions in py5 require their parameters to be + specified in radians. - Use ``has_thread()`` to determine if a thread of a given name exists and - ``list_threads()`` to get a list of all thread names. Use ``stop_all_threads()`` - to stop all threads. + This function makes a call to the numpy ``radians()`` function. """ - return _py5sketch.stop_thread(name, wait=wait) + return Sketch.radians(degrees) -def stop_all_threads(wait: bool = False) -> None: - """Stop all running threads. +def constrain(amt: Union[float, + npt.NDArray], + low: Union[float, + npt.NDArray], + high: Union[float, + npt.NDArray]) -> Union[float, + npt.NDArray]: + """Constrains a value to not exceed a maximum and minimum value. Parameters ---------- - wait: bool = False - wait for thread to exit before returning + amt: Union[float, npt.NDArray] + the value to constrain - Notes - ----- + high: Union[float, npt.NDArray] + minimum limit - Stop all running threads. The ``wait`` parameter determines if the method call - will return right away or wait for the threads to exit. - - When the Sketch shuts down, ``stop_all_threads(wait=False)`` is called for you. - If you would rather the Sketch waited for threads to exit, create an ``exiting`` - method and make a call to ``stop_all_threads(wait=True)``. - """ - return _py5sketch.stop_all_threads(wait=wait) - - -def list_threads() -> None: - """List the names of all of the currently running threads. + low: Union[float, npt.NDArray] + maximum limit Notes ----- - List the names of all of the currently running threads. The names of previously - launched threads that have exited will be removed from the list. + Constrains a value to not exceed a maximum and minimum value. """ - return _py5sketch.list_threads() - -############################################################################## -# module functions from math.py -############################################################################## + return Sketch.constrain(amt, low, high) -def hex_color(color: int) -> str: - """Convert a color value to a hex color string. +def remap(value: Union[float, + npt.NDArray], + start1: Union[float, + npt.NDArray], + stop1: Union[float, + npt.NDArray], + start2: Union[float, + npt.NDArray], + stop2: Union[float, + npt.NDArray]) -> Union[float, + npt.NDArray]: + """Re-maps a number from one range to another. Parameters ---------- - color: int - any color value + start1: Union[float, npt.NDArray] + lower bound of the value's current range + + start2: Union[float, npt.NDArray] + lower bound of the value's target range + + stop1: Union[float, npt.NDArray] + upper bound of the value's current range + + stop2: Union[float, npt.NDArray] + upper bound of the value's target range + + value: Union[float, npt.NDArray] + the incoming value to be converted Notes ----- - Convert a color value to a hex color string. Processing and py5 store color - values in 32 bit integers that are inconvenient for a human to parse. To - interpret these values, one can use methods like ``red()``, ``green()``, and - ``blue()`` to extract color channel values from the 32 bit integers. This method - provides an alternative approach, converting the 32 bit integer into a string - such as ``'#0F3FF0FF'``. The hex string has 8 hexadecimal values following a - ``#`` character. The first two values represent the red value, the next two - green, the next two blue, and the last two alpha. This is similar to web colors - except for the addition of the alpha channel. + Re-maps a number from one range to another. - Conveniently, the hex color string returned by this method can also be used as - parameter for other methods that accept color values. Observe how this is done - in the example code. + In the first example, the number 0.5 is converted from a value in the range of 0 + to 1 into a value that ranges from the left edge of the window (0) to the right + edge (``width``). + + As shown in the second example, numbers outside of the range are not clamped to + the minimum and maximum parameters values, because out-of-range values are often + intentional and useful. If that isn't what you want, try pairing this function + with ``constrain()``. + + In Processing this functionality is provided by ``map()`` but was renamed in py5 + because of a name conflict with a builtin Python function. """ - return Sketch.hex_color(color) + return Sketch.remap(value, start1, stop1, start2, stop2) -def sin(angle: Union[float, npt.ArrayLike]) -> Union[float, npt.NDArray]: - """Calculates the sine of an angle. +@overload +def dist(x1: Union[float, npt.NDArray], y1: Union[float, npt.NDArray], x2: Union[float, + npt.NDArray], y2: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray]: + """Calculates the distance between two points. - Parameters - ---------- + Methods + ------- - angle: Union[float, npt.ArrayLike] - angle in radians + You can use any of the following signatures: - Notes - ----- + * dist(x1: Union[float, npt.NDArray], y1: Union[float, npt.NDArray], x2: Union[float, npt.NDArray], y2: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] + * dist(x1: Union[float, npt.NDArray], y1: Union[float, npt.NDArray], z1: Union[float, npt.NDArray], x2: Union[float, npt.NDArray], y2: Union[float, npt.NDArray], z2: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] - Calculates the sine of an angle. This function expects the values of the angle - parameter to be provided in radians (values from ``0`` to ``TWO_PI``). Values - are returned in the range -1 to 1. + Parameters + ---------- - This function makes a call to the numpy ``sin()`` function. - """ - return Sketch.sin(angle) + x1: Union[float, npt.NDArray] + x-coordinate of the first point + x2: Union[float, npt.NDArray] + x-coordinate of the second point -def cos(angle: Union[float, npt.ArrayLike]) -> Union[float, npt.NDArray]: - """Calculates the cosine of an angle. + y1: Union[float, npt.NDArray] + y-coordinate of the first point - Parameters - ---------- + y2: Union[float, npt.NDArray] + y-coordinate of the second point - angle: Union[float, npt.ArrayLike] - angle in radians + z1: Union[float, npt.NDArray] + z-coordinate of the first point + + z2: Union[float, npt.NDArray] + z-coordinate of the second point Notes ----- - Calculates the cosine of an angle. This function expects the values of the angle - parameter to be provided in radians (values from ``0`` to ``TWO_PI``). Values - are returned in the range -1 to 1. - - This function makes a call to the numpy ``cos()`` function. + Calculates the distance between two points. """ - return Sketch.cos(angle) + pass -def tan(angle: Union[float, npt.ArrayLike]) -> Union[float, npt.NDArray]: - """Calculates the ratio of the sine and cosine of an angle. +@overload +def dist(x1: Union[float, + npt.NDArray], + y1: Union[float, + npt.NDArray], + z1: Union[float, + npt.NDArray], + x2: Union[float, + npt.NDArray], + y2: Union[float, + npt.NDArray], + z2: Union[float, + npt.NDArray], + /) -> Union[float, + npt.NDArray]: + """Calculates the distance between two points. - Parameters - ---------- + Methods + ------- - angle: Union[float, npt.ArrayLike] - angle in radians + You can use any of the following signatures: - Notes - ----- + * dist(x1: Union[float, npt.NDArray], y1: Union[float, npt.NDArray], x2: Union[float, npt.NDArray], y2: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] + * dist(x1: Union[float, npt.NDArray], y1: Union[float, npt.NDArray], z1: Union[float, npt.NDArray], x2: Union[float, npt.NDArray], y2: Union[float, npt.NDArray], z2: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] - Calculates the ratio of the sine and cosine of an angle. This function expects - the values of the angle parameter to be provided in radians (values from ``0`` - to ``TWO_PI``). Values are returned in the range infinity to -infinity. + Parameters + ---------- - This function makes a call to the numpy ``tan()`` function. - """ - return Sketch.tan(angle) + x1: Union[float, npt.NDArray] + x-coordinate of the first point + x2: Union[float, npt.NDArray] + x-coordinate of the second point -def asin(value: Union[float, npt.ArrayLike]) -> Union[float, npt.NDArray]: - """The inverse of ``sin()``, returns the arc sine of a value. + y1: Union[float, npt.NDArray] + y-coordinate of the first point - Parameters - ---------- + y2: Union[float, npt.NDArray] + y-coordinate of the second point - value: Union[float, npt.ArrayLike] - value in the range of -1 to 1 whose arc sine is to be returned + z1: Union[float, npt.NDArray] + z-coordinate of the first point + + z2: Union[float, npt.NDArray] + z-coordinate of the second point Notes ----- - The inverse of ``sin()``, returns the arc sine of a value. This function expects - the values in the range of -1 to 1 and values are returned in the range - ``-HALF_PI`` to ``HALF_PI``. - - This function makes a call to the numpy ``asin()`` function. + Calculates the distance between two points. """ - return Sketch.asin(value) + pass -def acos(value: Union[float, npt.ArrayLike]) -> Union[float, npt.NDArray]: - """The inverse of ``cos()``, returns the arc cosine of a value. +def dist(*args: Union[float, npt.NDArray]) -> float: + """Calculates the distance between two points. - Parameters - ---------- + Methods + ------- - value: Union[float, npt.ArrayLike] - value in the range of -1 to 1 whose arc cosine is to be returned + You can use any of the following signatures: - Notes - ----- + * dist(x1: Union[float, npt.NDArray], y1: Union[float, npt.NDArray], x2: Union[float, npt.NDArray], y2: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] + * dist(x1: Union[float, npt.NDArray], y1: Union[float, npt.NDArray], z1: Union[float, npt.NDArray], x2: Union[float, npt.NDArray], y2: Union[float, npt.NDArray], z2: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] - The inverse of ``cos()``, returns the arc cosine of a value. This function - expects the values in the range of -1 to 1 and values are returned in the range - ``0`` to ``PI``. + Parameters + ---------- - This function makes a call to the numpy ``acos()`` function. - """ - return Sketch.acos(value) + x1: Union[float, npt.NDArray] + x-coordinate of the first point + x2: Union[float, npt.NDArray] + x-coordinate of the second point -def atan(value: Union[float, npt.ArrayLike]) -> Union[float, npt.NDArray]: - """The inverse of ``tan()``, returns the arc tangent of a value. + y1: Union[float, npt.NDArray] + y-coordinate of the first point - Parameters - ---------- + y2: Union[float, npt.NDArray] + y-coordinate of the second point - value: Union[float, npt.ArrayLike] - value whose arc tangent is to be returned + z1: Union[float, npt.NDArray] + z-coordinate of the first point + + z2: Union[float, npt.NDArray] + z-coordinate of the second point Notes ----- - The inverse of ``tan()``, returns the arc tangent of a value. This function - expects the values in the range of -Infinity to Infinity and values are returned - in the range ``-HALF_PI`` to ``HALF_PI``. - - This function makes a call to the numpy ``atan()`` function. + Calculates the distance between two points. """ - return Sketch.atan(value) + return Sketch.dist(*args) -def atan2(y: Union[float, npt.ArrayLike], x: Union[float, - npt.ArrayLike]) -> Union[float, npt.NDArray]: - """Calculates the angle (in radians) from a specified point to the coordinate - origin as measured from the positive x-axis. +def lerp(start: Union[float, + npt.NDArray], + stop: Union[float, + npt.NDArray], + amt: Union[float, + npt.NDArray]) -> Union[float, + npt.NDArray]: + """Calculates a number between two numbers at a specific increment. Parameters ---------- - x: Union[float, npt.ArrayLike] - x-coordinate of the point + amt: Union[float, npt.NDArray] + float between 0.0 and 1.0 - y: Union[float, npt.ArrayLike] - y-coordinate of the point + start: Union[float, npt.NDArray] + first value + + stop: Union[float, npt.NDArray] + second value Notes ----- - Calculates the angle (in radians) from a specified point to the coordinate - origin as measured from the positive x-axis. Values are returned as a float in - the range from ``PI`` to ``-PI``. The ``atan2()`` function is most often used - for orienting geometry to the position of the cursor. Note: The y-coordinate of - the point is the first parameter, and the x-coordinate is the second parameter, - due the the structure of calculating the tangent. - - This function makes a call to the numpy ``atan2()`` function. + Calculates a number between two numbers at a specific increment. The ``amt`` + parameter is the amount to interpolate between the two values where 0.0 equal to + the first point, 0.1 is very near the first point, 0.5 is half-way in between, + etc. The lerp function is convenient for creating motion along a straight path + and for drawing dotted lines. If the ``amt`` parameter is greater than 1.0 or + less than 0.0, the interpolated value will be outside of the range specified by + the ``start`` and ``stop`` parameter values. """ - return Sketch.atan2(y, x) + return Sketch.lerp(start, stop, amt) -def degrees(radians: Union[float, npt.ArrayLike]) -> Union[float, npt.NDArray]: - """Converts a radian measurement to its corresponding value in degrees. +@overload +def mag(a: Union[float, npt.NDArray], + b: Union[float, npt.NDArray], /) -> float: + """Calculates the magnitude (or length) of a vector. + + Methods + ------- + + You can use any of the following signatures: + + * mag(a: Union[float, npt.NDArray], b: Union[float, npt.NDArray], /) -> float + * mag(a: Union[float, npt.NDArray], b: Union[float, npt.NDArray], c: Union[float, npt.NDArray], /) -> float Parameters ---------- - radians: Union[float, npt.ArrayLike] - radian value to convert to degrees + a: Union[float, npt.NDArray] + first value + + b: Union[float, npt.NDArray] + second value + + c: Union[float, npt.NDArray] + third value Notes ----- - Converts a radian measurement to its corresponding value in degrees. Radians and - degrees are two ways of measuring the same thing. There are 360 degrees in a - circle and ``2*PI`` radians in a circle. For example, ``90° = PI/2 = - 1.5707964``. All trigonometric functions in py5 require their parameters to be - specified in radians. - - This function makes a call to the numpy ``degrees()`` function. + Calculates the magnitude (or length) of a vector. A vector is a direction in + space commonly used in computer graphics and linear algebra. Because it has no + "start" position, the magnitude of a vector can be thought of as the distance + from the coordinate ``(0, 0)`` to its ``(x, y)`` value. Therefore, ``mag()`` is + a shortcut for writing ``dist(0, 0, x, y)``. """ - return Sketch.degrees(radians) + pass -def radians(degrees: Union[float, npt.ArrayLike]) -> Union[float, npt.NDArray]: - """Converts a degree measurement to its corresponding value in radians. +@overload +def mag(a: Union[float, npt.NDArray], b: Union[float, + npt.NDArray], c: Union[float, npt.NDArray], /) -> float: + """Calculates the magnitude (or length) of a vector. + + Methods + ------- + + You can use any of the following signatures: + + * mag(a: Union[float, npt.NDArray], b: Union[float, npt.NDArray], /) -> float + * mag(a: Union[float, npt.NDArray], b: Union[float, npt.NDArray], c: Union[float, npt.NDArray], /) -> float Parameters ---------- - degrees: Union[float, npt.ArrayLike] - degree value to convert to radians + a: Union[float, npt.NDArray] + first value + + b: Union[float, npt.NDArray] + second value + + c: Union[float, npt.NDArray] + third value Notes ----- - Converts a degree measurement to its corresponding value in radians. Radians and - degrees are two ways of measuring the same thing. There are 360 degrees in a - circle and ``2*PI`` radians in a circle. For example, ``90° = PI/2 = - 1.5707964``. All trigonometric functions in py5 require their parameters to be - specified in radians. - - This function makes a call to the numpy ``radians()`` function. + Calculates the magnitude (or length) of a vector. A vector is a direction in + space commonly used in computer graphics and linear algebra. Because it has no + "start" position, the magnitude of a vector can be thought of as the distance + from the coordinate ``(0, 0)`` to its ``(x, y)`` value. Therefore, ``mag()`` is + a shortcut for writing ``dist(0, 0, x, y)``. """ - return Sketch.radians(degrees) + pass -def constrain(amt: Union[float, - npt.NDArray], - low: Union[float, - npt.NDArray], - high: Union[float, - npt.NDArray]) -> Union[float, - npt.NDArray]: - """Constrains a value to not exceed a maximum and minimum value. +def mag(*args: Union[float, npt.NDArray]) -> float: + """Calculates the magnitude (or length) of a vector. + + Methods + ------- + + You can use any of the following signatures: + + * mag(a: Union[float, npt.NDArray], b: Union[float, npt.NDArray], /) -> float + * mag(a: Union[float, npt.NDArray], b: Union[float, npt.NDArray], c: Union[float, npt.NDArray], /) -> float Parameters ---------- - amt: Union[float, npt.NDArray] - the value to constrain + a: Union[float, npt.NDArray] + first value - high: Union[float, npt.NDArray] - minimum limit + b: Union[float, npt.NDArray] + second value - low: Union[float, npt.NDArray] - maximum limit + c: Union[float, npt.NDArray] + third value Notes ----- - Constrains a value to not exceed a maximum and minimum value. + Calculates the magnitude (or length) of a vector. A vector is a direction in + space commonly used in computer graphics and linear algebra. Because it has no + "start" position, the magnitude of a vector can be thought of as the distance + from the coordinate ``(0, 0)`` to its ``(x, y)`` value. Therefore, ``mag()`` is + a shortcut for writing ``dist(0, 0, x, y)``. """ - return Sketch.constrain(amt, low, high) + return Sketch.mag(*args) -def remap(value: Union[float, - npt.NDArray], - start1: Union[float, - npt.NDArray], - stop1: Union[float, - npt.NDArray], - start2: Union[float, - npt.NDArray], - stop2: Union[float, - npt.NDArray]) -> Union[float, - npt.NDArray]: - """Re-maps a number from one range to another. +def norm(value: Union[float, + npt.NDArray], + start: Union[float, + npt.NDArray], + stop: Union[float, + npt.NDArray]) -> Union[float, + npt.NDArray]: + """Normalizes a number from another range into a value between 0 and 1. Parameters ---------- - start1: Union[float, npt.NDArray] + start: Union[float, npt.NDArray] lower bound of the value's current range - start2: Union[float, npt.NDArray] - lower bound of the value's target range - - stop1: Union[float, npt.NDArray] + stop: Union[float, npt.NDArray] upper bound of the value's current range - stop2: Union[float, npt.NDArray] - upper bound of the value's target range - value: Union[float, npt.NDArray] the incoming value to be converted Notes ----- - Re-maps a number from one range to another. + Normalizes a number from another range into a value between 0 and 1. Identical + to ``remap(value, low, high, 0, 1)``. - In the first example, the number 0.5 is converted from a value in the range of 0 - to 1 into a value that ranges from the left edge of the window (0) to the right - edge (``width``). + Numbers outside of the range are not clamped to 0 and 1, because out-of-range + values are often intentional and useful. (See the second example.) If that isn't + what you want, try pairing this function with ``constrain()``. + """ + return Sketch.norm(value, start, stop) - As shown in the second example, numbers outside of the range are not clamped to - the minimum and maximum parameters values, because out-of-range values are often - intentional and useful. If that isn't what you want, try pairing this function - with ``constrain()``. - In Processing this functionality is provided by ``map()`` but was renamed in py5 - because of a name conflict with a builtin Python function. - """ - return Sketch.remap(value, start1, stop1, start2, stop2) +def sq(value: Union[float, npt.NDArray]) -> Union[float, npt.NDArray]: + """Squares a number (multiplies a number by itself). + + Parameters + ---------- + value: Union[float, npt.NDArray] + number to square -@overload -def dist(x1: Union[float, npt.NDArray], y1: Union[float, npt.NDArray], x2: Union[float, - npt.NDArray], y2: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray]: - """Calculates the distance between two points. + Notes + ----- - Methods - ------- + Squares a number (multiplies a number by itself). The result is always a + positive number, as multiplying two negative numbers always yields a positive + result. For example, ``-1 * -1 = 1``. + """ + return Sketch.sq(value) - You can use any of the following signatures: - * dist(x1: Union[float, npt.NDArray], y1: Union[float, npt.NDArray], x2: Union[float, npt.NDArray], y2: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] - * dist(x1: Union[float, npt.NDArray], y1: Union[float, npt.NDArray], z1: Union[float, npt.NDArray], x2: Union[float, npt.NDArray], y2: Union[float, npt.NDArray], z2: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] +def sqrt(value: Union[float, npt.NDArray] + ) -> Union[float, complex, npt.NDArray]: + """Calculates the square root of a number. Parameters ---------- - x1: Union[float, npt.NDArray] - x-coordinate of the first point + value: Union[float, npt.NDArray] + value to calculate the square root of - x2: Union[float, npt.NDArray] - x-coordinate of the second point + Notes + ----- - y1: Union[float, npt.NDArray] - y-coordinate of the first point + Calculates the square root of a number. The square root of a positive number is + always positive, even though there may be a valid negative root. The square root + of a negative number is a complex number. In either case, the square root ``s`` + of number ``a`` is such that ``s*s = a``. It is the opposite of squaring. - y2: Union[float, npt.NDArray] - y-coordinate of the second point + Python supports complex numbers, but such values cannot be passed to py5 drawing + functions. When using the ``sqrt()`` function, you should check if the result is + complex before using the value. You can also extract the real and imaginary + components of the complex value with ``.real`` and ``.imag``. See the second + example to learn how to do both of these things. + """ + return Sketch.sqrt(value) - z1: Union[float, npt.NDArray] - z-coordinate of the first point - z2: Union[float, npt.NDArray] - z-coordinate of the second point +def floor(value: Union[float, npt.ArrayLike]) -> Union[int, npt.NDArray]: + """Calculates the closest int value that is less than or equal to the value of the + parameter. + + Parameters + ---------- + + value: Union[float, npt.ArrayLike] + number to round down Notes ----- - Calculates the distance between two points. - """ - pass + Calculates the closest int value that is less than or equal to the value of the + parameter. + This function makes a call to the numpy ``floor()`` function. + """ + return Sketch.floor(value) -@overload -def dist(x1: Union[float, - npt.NDArray], - y1: Union[float, - npt.NDArray], - z1: Union[float, - npt.NDArray], - x2: Union[float, - npt.NDArray], - y2: Union[float, - npt.NDArray], - z2: Union[float, - npt.NDArray], - /) -> Union[float, - npt.NDArray]: - """Calculates the distance between two points. - - Methods - ------- - - You can use any of the following signatures: - * dist(x1: Union[float, npt.NDArray], y1: Union[float, npt.NDArray], x2: Union[float, npt.NDArray], y2: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] - * dist(x1: Union[float, npt.NDArray], y1: Union[float, npt.NDArray], z1: Union[float, npt.NDArray], x2: Union[float, npt.NDArray], y2: Union[float, npt.NDArray], z2: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] +def ceil(value: Union[float, npt.ArrayLike]) -> Union[int, npt.NDArray]: + """Calculates the closest int value that is greater than or equal to the value of + the parameter. Parameters ---------- - x1: Union[float, npt.NDArray] - x-coordinate of the first point - - x2: Union[float, npt.NDArray] - x-coordinate of the second point - - y1: Union[float, npt.NDArray] - y-coordinate of the first point - - y2: Union[float, npt.NDArray] - y-coordinate of the second point - - z1: Union[float, npt.NDArray] - z-coordinate of the first point - - z2: Union[float, npt.NDArray] - z-coordinate of the second point + value: Union[float, npt.ArrayLike] + number to round up Notes ----- - Calculates the distance between two points. - """ - pass - - -def dist(*args: Union[float, npt.NDArray]) -> float: - """Calculates the distance between two points. + Calculates the closest int value that is greater than or equal to the value of + the parameter. - Methods - ------- + This function makes a call to the numpy ``ceil()`` function. + """ + return Sketch.ceil(value) - You can use any of the following signatures: - * dist(x1: Union[float, npt.NDArray], y1: Union[float, npt.NDArray], x2: Union[float, npt.NDArray], y2: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] - * dist(x1: Union[float, npt.NDArray], y1: Union[float, npt.NDArray], z1: Union[float, npt.NDArray], x2: Union[float, npt.NDArray], y2: Union[float, npt.NDArray], z2: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] +def exp(value: Union[float, npt.ArrayLike]) -> Union[float, npt.NDArray]: + """Returns Euler's number e (2.71828...) raised to the power of the ``n`` + parameter. Parameters ---------- - x1: Union[float, npt.NDArray] - x-coordinate of the first point + value: Union[float, npt.ArrayLike] + exponent to raise - x2: Union[float, npt.NDArray] - x-coordinate of the second point + Notes + ----- - y1: Union[float, npt.NDArray] - y-coordinate of the first point + Returns Euler's number e (2.71828...) raised to the power of the ``n`` + parameter. This function is the compliment to ``log()``. - y2: Union[float, npt.NDArray] - y-coordinate of the second point + This function makes a call to the numpy ``exp()`` function. + """ + return Sketch.exp(value) - z1: Union[float, npt.NDArray] - z-coordinate of the first point - z2: Union[float, npt.NDArray] - z-coordinate of the second point +def log(value: Union[float, npt.ArrayLike]) -> Union[float, npt.NDArray]: + """Calculates the natural logarithm (the base-e logarithm) of a number. + + Parameters + ---------- + + value: Union[float, npt.ArrayLike] + number greater than 0.0 Notes ----- - Calculates the distance between two points. + Calculates the natural logarithm (the base-e logarithm) of a number. This + function expects the ``n`` parameter to be a value greater than 0.0. This + function is the compliment to ``exp()``. + + This function makes a call to the numpy ``log()`` function. If the ``n`` + parameter is less than or equal to 0.0, you will see a ``RuntimeWarning`` and + the returned result will be numpy's Not-a-Number value, ``np.nan``. """ - return Sketch.dist(*args) + return Sketch.log(value) -def lerp(start: Union[float, - npt.NDArray], - stop: Union[float, - npt.NDArray], - amt: Union[float, - npt.NDArray]) -> Union[float, - npt.NDArray]: - """Calculates a number between two numbers at a specific increment. +np_random: np.random.Generator = None - Parameters - ---------- - amt: Union[float, npt.NDArray] - float between 0.0 and 1.0 +def random_seed(seed: int) -> None: + """Sets the seed value for py5's random functions. - start: Union[float, npt.NDArray] - first value + Parameters + ---------- - stop: Union[float, npt.NDArray] - second value + seed: int + seed value Notes ----- - Calculates a number between two numbers at a specific increment. The ``amt`` - parameter is the amount to interpolate between the two values where 0.0 equal to - the first point, 0.1 is very near the first point, 0.5 is half-way in between, - etc. The lerp function is convenient for creating motion along a straight path - and for drawing dotted lines. If the ``amt`` parameter is greater than 1.0 or - less than 0.0, the interpolated value will be outside of the range specified by - the ``start`` and ``stop`` parameter values. + Sets the seed value for py5's random functions. This includes ``random()``, + ``random_int()``, ``random_choice()``, and ``random_gaussian()``. By default, + all of these functions would produce different results each time a program is + run. Set the seed parameter to a constant value to return the same pseudo-random + numbers each time the software is run. """ - return Sketch.lerp(start, stop, amt) + return _py5sketch.random_seed(seed) @overload -def mag(a: Union[float, npt.NDArray], - b: Union[float, npt.NDArray], /) -> float: - """Calculates the magnitude (or length) of a vector. +def random() -> float: + """Generates random numbers. Methods ------- You can use any of the following signatures: - * mag(a: Union[float, npt.NDArray], b: Union[float, npt.NDArray], /) -> float - * mag(a: Union[float, npt.NDArray], b: Union[float, npt.NDArray], c: Union[float, npt.NDArray], /) -> float + * random() -> float + * random(high: float, /) -> float + * random(low: float, high: float, /) -> float Parameters ---------- - a: Union[float, npt.NDArray] - first value - - b: Union[float, npt.NDArray] - second value + high: float + upper limit - c: Union[float, npt.NDArray] - third value + low: float + lower limit Notes ----- - Calculates the magnitude (or length) of a vector. A vector is a direction in - space commonly used in computer graphics and linear algebra. Because it has no - "start" position, the magnitude of a vector can be thought of as the distance - from the coordinate ``(0, 0)`` to its ``(x, y)`` value. Therefore, ``mag()`` is - a shortcut for writing ``dist(0, 0, x, y)``. + Generates random numbers. Each time the ``random()`` function is called, it + returns an unexpected value within the specified range. This function's + randomness can be influenced by ``random_seed()``. + + If no parameters are passed to the function, it will return a float between zero + and one. + + If only one parameter is passed to the function, it will return a float between + zero and the value of the ``high`` parameter. For example, ``random(5)`` returns + values between 0 and 5 (starting at zero, and up to, but not including, 5). + + If two parameters are specified, the function will return a float with a value + between the two values. For example, ``random(-5, 10.2)`` returns values + starting at -5 and up to (but not including) 10.2. To convert a floating-point + random number to an integer, use the ``int()`` function, or alternatively, + consider using ``random_int()``. + + This function makes calls to numpy to generate the random values. """ pass @overload -def mag(a: Union[float, npt.NDArray], b: Union[float, - npt.NDArray], c: Union[float, npt.NDArray], /) -> float: - """Calculates the magnitude (or length) of a vector. +def random(high: float, /) -> float: + """Generates random numbers. Methods ------- You can use any of the following signatures: - * mag(a: Union[float, npt.NDArray], b: Union[float, npt.NDArray], /) -> float - * mag(a: Union[float, npt.NDArray], b: Union[float, npt.NDArray], c: Union[float, npt.NDArray], /) -> float + * random() -> float + * random(high: float, /) -> float + * random(low: float, high: float, /) -> float Parameters ---------- - a: Union[float, npt.NDArray] - first value - - b: Union[float, npt.NDArray] - second value + high: float + upper limit - c: Union[float, npt.NDArray] - third value + low: float + lower limit Notes ----- - Calculates the magnitude (or length) of a vector. A vector is a direction in - space commonly used in computer graphics and linear algebra. Because it has no - "start" position, the magnitude of a vector can be thought of as the distance - from the coordinate ``(0, 0)`` to its ``(x, y)`` value. Therefore, ``mag()`` is - a shortcut for writing ``dist(0, 0, x, y)``. + Generates random numbers. Each time the ``random()`` function is called, it + returns an unexpected value within the specified range. This function's + randomness can be influenced by ``random_seed()``. + + If no parameters are passed to the function, it will return a float between zero + and one. + + If only one parameter is passed to the function, it will return a float between + zero and the value of the ``high`` parameter. For example, ``random(5)`` returns + values between 0 and 5 (starting at zero, and up to, but not including, 5). + + If two parameters are specified, the function will return a float with a value + between the two values. For example, ``random(-5, 10.2)`` returns values + starting at -5 and up to (but not including) 10.2. To convert a floating-point + random number to an integer, use the ``int()`` function, or alternatively, + consider using ``random_int()``. + + This function makes calls to numpy to generate the random values. """ pass -def mag(*args: Union[float, npt.NDArray]) -> float: - """Calculates the magnitude (or length) of a vector. +@overload +def random(low: float, high: float, /) -> float: + """Generates random numbers. Methods ------- You can use any of the following signatures: - * mag(a: Union[float, npt.NDArray], b: Union[float, npt.NDArray], /) -> float - * mag(a: Union[float, npt.NDArray], b: Union[float, npt.NDArray], c: Union[float, npt.NDArray], /) -> float + * random() -> float + * random(high: float, /) -> float + * random(low: float, high: float, /) -> float Parameters ---------- - a: Union[float, npt.NDArray] - first value - - b: Union[float, npt.NDArray] - second value + high: float + upper limit - c: Union[float, npt.NDArray] - third value - - Notes - ----- - - Calculates the magnitude (or length) of a vector. A vector is a direction in - space commonly used in computer graphics and linear algebra. Because it has no - "start" position, the magnitude of a vector can be thought of as the distance - from the coordinate ``(0, 0)`` to its ``(x, y)`` value. Therefore, ``mag()`` is - a shortcut for writing ``dist(0, 0, x, y)``. - """ - return Sketch.mag(*args) - - -def norm(value: Union[float, - npt.NDArray], - start: Union[float, - npt.NDArray], - stop: Union[float, - npt.NDArray]) -> Union[float, - npt.NDArray]: - """Normalizes a number from another range into a value between 0 and 1. - - Parameters - ---------- - - start: Union[float, npt.NDArray] - lower bound of the value's current range - - stop: Union[float, npt.NDArray] - upper bound of the value's current range - - value: Union[float, npt.NDArray] - the incoming value to be converted - - Notes - ----- - - Normalizes a number from another range into a value between 0 and 1. Identical - to ``remap(value, low, high, 0, 1)``. - - Numbers outside of the range are not clamped to 0 and 1, because out-of-range - values are often intentional and useful. (See the second example.) If that isn't - what you want, try pairing this function with ``constrain()``. - """ - return Sketch.norm(value, start, stop) - - -def sq(value: Union[float, npt.NDArray]) -> Union[float, npt.NDArray]: - """Squares a number (multiplies a number by itself). - - Parameters - ---------- - - value: Union[float, npt.NDArray] - number to square - - Notes - ----- - - Squares a number (multiplies a number by itself). The result is always a - positive number, as multiplying two negative numbers always yields a positive - result. For example, ``-1 * -1 = 1``. - """ - return Sketch.sq(value) - - -def sqrt(value: Union[float, npt.NDArray] - ) -> Union[float, complex, npt.NDArray]: - """Calculates the square root of a number. - - Parameters - ---------- - - value: Union[float, npt.NDArray] - value to calculate the square root of - - Notes - ----- - - Calculates the square root of a number. The square root of a positive number is - always positive, even though there may be a valid negative root. The square root - of a negative number is a complex number. In either case, the square root ``s`` - of number ``a`` is such that ``s*s = a``. It is the opposite of squaring. - - Python supports complex numbers, but such values cannot be passed to py5 drawing - functions. When using the ``sqrt()`` function, you should check if the result is - complex before using the value. You can also extract the real and imaginary - components of the complex value with ``.real`` and ``.imag``. See the second - example to learn how to do both of these things. - """ - return Sketch.sqrt(value) - - -def floor(value: Union[float, npt.ArrayLike]) -> Union[int, npt.NDArray]: - """Calculates the closest int value that is less than or equal to the value of the - parameter. - - Parameters - ---------- - - value: Union[float, npt.ArrayLike] - number to round down - - Notes - ----- - - Calculates the closest int value that is less than or equal to the value of the - parameter. - - This function makes a call to the numpy ``floor()`` function. - """ - return Sketch.floor(value) - - -def ceil(value: Union[float, npt.ArrayLike]) -> Union[int, npt.NDArray]: - """Calculates the closest int value that is greater than or equal to the value of - the parameter. - - Parameters - ---------- - - value: Union[float, npt.ArrayLike] - number to round up - - Notes - ----- - - Calculates the closest int value that is greater than or equal to the value of - the parameter. - - This function makes a call to the numpy ``ceil()`` function. - """ - return Sketch.ceil(value) - - -def exp(value: Union[float, npt.ArrayLike]) -> Union[float, npt.NDArray]: - """Returns Euler's number e (2.71828...) raised to the power of the ``n`` - parameter. - - Parameters - ---------- - - value: Union[float, npt.ArrayLike] - exponent to raise - - Notes - ----- - - Returns Euler's number e (2.71828...) raised to the power of the ``n`` - parameter. This function is the compliment to ``log()``. - - This function makes a call to the numpy ``exp()`` function. - """ - return Sketch.exp(value) - - -def log(value: Union[float, npt.ArrayLike]) -> Union[float, npt.NDArray]: - """Calculates the natural logarithm (the base-e logarithm) of a number. - - Parameters - ---------- - - value: Union[float, npt.ArrayLike] - number greater than 0.0 - - Notes - ----- - - Calculates the natural logarithm (the base-e logarithm) of a number. This - function expects the ``n`` parameter to be a value greater than 0.0. This - function is the compliment to ``exp()``. - - This function makes a call to the numpy ``log()`` function. If the ``n`` - parameter is less than or equal to 0.0, you will see a ``RuntimeWarning`` and - the returned result will be numpy's Not-a-Number value, ``np.nan``. - """ - return Sketch.log(value) - - -np_random: np.random.Generator = None - - -def random_seed(seed: int) -> None: - """Sets the seed value for py5's random functions. - - Parameters - ---------- - - seed: int - seed value - - Notes - ----- - - Sets the seed value for py5's random functions. This includes ``random()``, - ``random_int()``, ``random_choice()``, and ``random_gaussian()``. By default, - all of these functions would produce different results each time a program is - run. Set the seed parameter to a constant value to return the same pseudo-random - numbers each time the software is run. - """ - return _py5sketch.random_seed(seed) - - -@overload -def random() -> float: - """Generates random numbers. - - Methods - ------- - - You can use any of the following signatures: - - * random() -> float - * random(high: float, /) -> float - * random(low: float, high: float, /) -> float - - Parameters - ---------- - - high: float - upper limit - - low: float - lower limit + low: float + lower limit Notes ----- @@ -18825,8 +18459,7 @@ def random() -> float: pass -@overload -def random(high: float, /) -> float: +def random(*args: float) -> float: """Generates random numbers. Methods @@ -18869,138 +18502,45 @@ def random(high: float, /) -> float: This function makes calls to numpy to generate the random values. """ - pass + return _py5sketch.random(*args) @overload -def random(low: float, high: float, /) -> float: - """Generates random numbers. +def random_int() -> int: + """Generates random integers. Methods ------- You can use any of the following signatures: - * random() -> float - * random(high: float, /) -> float - * random(low: float, high: float, /) -> float + * random_int() -> int + * random_int(high: int, /) -> int + * random_int(low: int, high: int, /) -> int Parameters ---------- - high: float + high: int upper limit - low: float + low: int lower limit Notes ----- - Generates random numbers. Each time the ``random()`` function is called, it - returns an unexpected value within the specified range. This function's + Generates random integers. Each time the ``random_int()`` function is called, it + returns an unexpected integer within the specified range. This function's randomness can be influenced by ``random_seed()``. - If no parameters are passed to the function, it will return a float between zero - and one. + If no parameters are passed to the function, it will return either 0 or 1. + Recall that in a Python boolean expression, 0 evaluates to ``False`` and 1 + evaluates to ``True``. This is equivalent to a coin toss. - If only one parameter is passed to the function, it will return a float between - zero and the value of the ``high`` parameter. For example, ``random(5)`` returns - values between 0 and 5 (starting at zero, and up to, but not including, 5). - - If two parameters are specified, the function will return a float with a value - between the two values. For example, ``random(-5, 10.2)`` returns values - starting at -5 and up to (but not including) 10.2. To convert a floating-point - random number to an integer, use the ``int()`` function, or alternatively, - consider using ``random_int()``. - - This function makes calls to numpy to generate the random values. - """ - pass - - -def random(*args: float) -> float: - """Generates random numbers. - - Methods - ------- - - You can use any of the following signatures: - - * random() -> float - * random(high: float, /) -> float - * random(low: float, high: float, /) -> float - - Parameters - ---------- - - high: float - upper limit - - low: float - lower limit - - Notes - ----- - - Generates random numbers. Each time the ``random()`` function is called, it - returns an unexpected value within the specified range. This function's - randomness can be influenced by ``random_seed()``. - - If no parameters are passed to the function, it will return a float between zero - and one. - - If only one parameter is passed to the function, it will return a float between - zero and the value of the ``high`` parameter. For example, ``random(5)`` returns - values between 0 and 5 (starting at zero, and up to, but not including, 5). - - If two parameters are specified, the function will return a float with a value - between the two values. For example, ``random(-5, 10.2)`` returns values - starting at -5 and up to (but not including) 10.2. To convert a floating-point - random number to an integer, use the ``int()`` function, or alternatively, - consider using ``random_int()``. - - This function makes calls to numpy to generate the random values. - """ - return _py5sketch.random(*args) - - -@overload -def random_int() -> int: - """Generates random integers. - - Methods - ------- - - You can use any of the following signatures: - - * random_int() -> int - * random_int(high: int, /) -> int - * random_int(low: int, high: int, /) -> int - - Parameters - ---------- - - high: int - upper limit - - low: int - lower limit - - Notes - ----- - - Generates random integers. Each time the ``random_int()`` function is called, it - returns an unexpected integer within the specified range. This function's - randomness can be influenced by ``random_seed()``. - - If no parameters are passed to the function, it will return either 0 or 1. - Recall that in a Python boolean expression, 0 evaluates to ``False`` and 1 - evaluates to ``True``. This is equivalent to a coin toss. - - If only one parameter is passed to the function, it will return an integer - between zero and the value of the ``high`` parameter, inclusive. For example, - ``random(5)`` returns one of 0, 1, 2, 3, 4, or 5. + If only one parameter is passed to the function, it will return an integer + between zero and the value of the ``high`` parameter, inclusive. For example, + ``random(5)`` returns one of 0, 1, 2, 3, 4, or 5. If two parameters are specified, the function will return an integer with a value between the two values, inclusive. For example, ``random(2, 5)`` returns @@ -19952,162 +19492,663 @@ def os_noise(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], z: Unio Parameters ---------- - w: Union[float, npt.NDArray] - w-coordinate in noise space + w: Union[float, npt.NDArray] + w-coordinate in noise space + + x: Union[float, npt.NDArray] + x-coordinate in noise space + + y: Union[float, npt.NDArray] + y-coordinate in noise space + + z: Union[float, npt.NDArray] + z-coordinate in noise space + + Notes + ----- + + Generate pseudo-random noise values for specific coodinates using the + OpenSimplex 2 algorithm (smooth version / SuperSimplex). Noise functions are + random sequence generators that produce a more natural, harmonic succession of + numbers compared to the ``random()`` method. + + In contrast to the ``random()`` method, noise is defined in an n-dimensional + space, in which each coordinate corresponds to a fixed pseudo-random value + (fixed only for the lifespan of the program). The noise value can be animated by + moving through the noise space, as demonstrated in the examples. Any dimension + can also be interpreted as time. An easy way to animate the noise value is to + pass the ``os_noise()`` method the ``frame_count`` divided by a scaling factor, + as is done in a few of the examples. + + The generated noise values for this method will be between -1 and 1, and can be + generated in 2, 3, or 4 dimensions. To generate noise in 1 dimension, add a + constant value as an extra parameter, as shown in a few examples. Py5 also + provides the ``noise()`` method, which generates noise using Processing's noise + algorithm. That algorithm typically generates noise values between 0 and 1, and + can be generated in 1, 2, or 3 dimensions. Be aware of both of these differences + when modifying your code to switch from one to the other. There are other + differences in the character of the noise values generated by both methods, so + you'll need to do some experimentation to get the results you want. + + The nature of the noise values returned can be adjusted with + ``os_noise_seed()``. + + Another way to adjust the character of the resulting sequence is the scale of + the input coordinates. As the method works within an infinite space, the value + of the coordinates doesn't matter as such; only the distance between successive + coordinates is important. As a general rule, the smaller the difference between + coordinates, the smoother the resulting noise sequence. Steps of 0.005-0.03 work + best for most applications, but this will differ depending on the use case and + the noise settings. + + Py5's ``os_noise()`` method can also accept numpy arrays as parameters. It will + use broadcasting when needed and calculate the values efficiently. Using numpy + array parameters will be much faster and efficient than calling the + ``os_noise()`` method repeatedly in a loop. See the examples to see how this can + be done. The noise algorithm for this method is implemented in Java. + + Noise generation is a rich and complex topic, and there are many noise + algorithms and libraries available that are worth learning about. Early versions + of py5 used the Python "noise" library, which can generate noise using the + "Improved Perlin Noise" algorithm (as described in Ken Perlin's 2002 SIGGRAPH + paper) and the Simplex Noise algorithm (also developed by Ken Perlin). That + Python library was removed from py5 because it has some bugs and hasn't had a + release in years. Nevertheless, it might be useful to you, and can be installed + separately like any other Python package. You can also try the Python library + "vnoise", which is a pure Python implementation of the Improved Perlin Noise + algorithm. Note that py5 can also employ Java libraries, so consider "FastNoise + Lite" to experiment with a large selection of noise algorithms with efficient + implementations. + """ + pass + + +def os_noise(*args) -> Union[float, npt.NDArray]: + """Generate pseudo-random noise values for specific coodinates using the + OpenSimplex 2 algorithm (smooth version / SuperSimplex). + + Methods + ------- + + You can use any of the following signatures: + + * os_noise(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] + * os_noise(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], z: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] + * os_noise(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], z: Union[float, npt.NDArray], w: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] + + Parameters + ---------- + + w: Union[float, npt.NDArray] + w-coordinate in noise space + + x: Union[float, npt.NDArray] + x-coordinate in noise space + + y: Union[float, npt.NDArray] + y-coordinate in noise space + + z: Union[float, npt.NDArray] + z-coordinate in noise space + + Notes + ----- + + Generate pseudo-random noise values for specific coodinates using the + OpenSimplex 2 algorithm (smooth version / SuperSimplex). Noise functions are + random sequence generators that produce a more natural, harmonic succession of + numbers compared to the ``random()`` method. + + In contrast to the ``random()`` method, noise is defined in an n-dimensional + space, in which each coordinate corresponds to a fixed pseudo-random value + (fixed only for the lifespan of the program). The noise value can be animated by + moving through the noise space, as demonstrated in the examples. Any dimension + can also be interpreted as time. An easy way to animate the noise value is to + pass the ``os_noise()`` method the ``frame_count`` divided by a scaling factor, + as is done in a few of the examples. + + The generated noise values for this method will be between -1 and 1, and can be + generated in 2, 3, or 4 dimensions. To generate noise in 1 dimension, add a + constant value as an extra parameter, as shown in a few examples. Py5 also + provides the ``noise()`` method, which generates noise using Processing's noise + algorithm. That algorithm typically generates noise values between 0 and 1, and + can be generated in 1, 2, or 3 dimensions. Be aware of both of these differences + when modifying your code to switch from one to the other. There are other + differences in the character of the noise values generated by both methods, so + you'll need to do some experimentation to get the results you want. + + The nature of the noise values returned can be adjusted with + ``os_noise_seed()``. + + Another way to adjust the character of the resulting sequence is the scale of + the input coordinates. As the method works within an infinite space, the value + of the coordinates doesn't matter as such; only the distance between successive + coordinates is important. As a general rule, the smaller the difference between + coordinates, the smoother the resulting noise sequence. Steps of 0.005-0.03 work + best for most applications, but this will differ depending on the use case and + the noise settings. + + Py5's ``os_noise()`` method can also accept numpy arrays as parameters. It will + use broadcasting when needed and calculate the values efficiently. Using numpy + array parameters will be much faster and efficient than calling the + ``os_noise()`` method repeatedly in a loop. See the examples to see how this can + be done. The noise algorithm for this method is implemented in Java. + + Noise generation is a rich and complex topic, and there are many noise + algorithms and libraries available that are worth learning about. Early versions + of py5 used the Python "noise" library, which can generate noise using the + "Improved Perlin Noise" algorithm (as described in Ken Perlin's 2002 SIGGRAPH + paper) and the Simplex Noise algorithm (also developed by Ken Perlin). That + Python library was removed from py5 because it has some bugs and hasn't had a + release in years. Nevertheless, it might be useful to you, and can be installed + separately like any other Python package. You can also try the Python library + "vnoise", which is a pure Python implementation of the Improved Perlin Noise + algorithm. Note that py5 can also employ Java libraries, so consider "FastNoise + Lite" to experiment with a large selection of noise algorithms with efficient + implementations. + """ + return _py5sketch.os_noise(*args) + +############################################################################## +# module functions from pixels.py +############################################################################## + + +def load_np_pixels() -> None: + """Loads the pixel data of the current display window into the ``np_pixels[]`` + array. + + Notes + ----- + + Loads the pixel data of the current display window into the ``np_pixels[]`` + array. This method must always be called before reading from or writing to + ``np_pixels[]``. Subsequent changes to the display window will not be reflected + in ``np_pixels[]`` until ``load_np_pixels()`` is called again. + + The ``load_np_pixels()`` method is similar to ``load_pixels()`` in that + ``load_np_pixels()`` must be called before reading from or writing to + ``np_pixels[]`` just as ``load_pixels()`` must be called before reading from or + writing to ``pixels[]``. + + Note that ``load_np_pixels()`` will as a side effect call ``load_pixels()``, so + if your code needs to read ``np_pixels[]`` and ``pixels[]`` simultaneously, + there is no need for a separate call to ``load_pixels()``. However, be aware + that modifying both ``np_pixels[]`` and ``pixels[]`` simultaneously will likely + result in the updates to ``pixels[]`` being discarded. + """ + return _py5sketch.load_np_pixels() + + +def update_np_pixels() -> None: + """Updates the display window with the data in the ``np_pixels[]`` array. + + Notes + ----- + + Updates the display window with the data in the ``np_pixels[]`` array. Use in + conjunction with ``load_np_pixels()``. If you're only reading pixels from the + array, there's no need to call ``update_np_pixels()`` — updating is only + necessary to apply changes. + + The ``update_np_pixels()`` method is similar to ``update_pixels()`` in that + ``update_np_pixels()`` must be called after modifying ``np_pixels[]`` just as + ``update_pixels()`` must be called after modifying ``pixels[]``. + """ + return _py5sketch.update_np_pixels() + + +np_pixels: npt.NDArray[np.uint8] = None + + +def set_np_pixels(array: npt.NDArray[np.uint8], bands: str = 'ARGB') -> None: + """Set the entire contents of ``np_pixels[]`` to the contents of another properly + sized and typed numpy array. + + Parameters + ---------- + + array: npt.NDArray[np.uint8] + properly sized numpy array to be copied to np_pixels[] + + bands: str = 'ARGB' + color channels in the array's third dimension + + Notes + ----- + + Set the entire contents of ``np_pixels[]`` to the contents of another properly + sized and typed numpy array. The size of ``array``'s first and second dimensions + must match the height and width of the Sketch window, respectively. The array's + ``dtype`` must be ``np.uint8``. + + The ``bands`` parameter is used to interpret the ``array``'s color channel + dimension (the array's third dimension). It can be one of ``'L'`` (single- + channel grayscale), ``'ARGB'``, ``'RGB'``, or ``'RGBA'``. If there is no alpha + channel, ``array`` is assumed to have no transparency, but recall that the + display window's pixels can never be transparent so any transparency in + ``array`` will have no effect. If the ``bands`` parameter is ``'L'``, + ``array``'s third dimension is optional. + + This method makes its own calls to ``load_np_pixels()`` and + ``update_np_pixels()`` so there is no need to call either explicitly. + + This method exists because setting the array contents with the code + ``py5.np_pixels = array`` will cause an error, while the correct syntax, + ``py5.np_pixels[:] = array``, might also be unintuitive for beginners. + """ + return _py5sketch.set_np_pixels(array, bands=bands) + + +def save(filename: Union[str, + Path, + BytesIO], + *, + format: str = None, + drop_alpha: bool = True, + use_thread: bool = False, + **params) -> None: + """Save the drawing surface to an image file. + + Parameters + ---------- + + drop_alpha: bool = True + remove the alpha channel when saving the image + + filename: Union[str, Path, BytesIO] + output filename + + format: str = None + image format, if not determined from filename extension + + params + keyword arguments to pass to the PIL.Image save method + + use_thread: bool = False + write file in separate thread + + Notes + ----- + + Save the drawing surface to an image file. This method uses the Python library + Pillow to write the image, so it can save images in any format that that library + supports. + + Use the ``drop_alpha`` parameter to drop the alpha channel from the image. This + defaults to ``True``. Some image formats such as JPG do not support alpha + channels, and Pillow will throw an error if you try to save an image with the + alpha channel in that format. + + The ``use_thread`` parameter will save the image in a separate Python thread. + This improves performance by returning before the image has actually been + written to the file. + """ + return _py5sketch.save( + filename, + format=format, + drop_alpha=drop_alpha, + use_thread=use_thread, + **params) + +############################################################################## +# module functions from print_tools.py +############################################################################## + + +def set_println_stream(println_stream: Any) -> None: + """Customize where the output of ``println()`` goes. + + Parameters + ---------- + + println_stream: Any + println stream object to be used by println method + + Notes + ----- + + Customize where the output of ``println()`` goes. + + When running a Sketch asynchronously through Jupyter Notebook, any ``print`` + statements using Python's builtin function will always appear in the output of + the currently active cell. This will rarely be desirable, as the active cell + will keep changing as the user executes code elsewhere in the notebook. The + ``println()`` method was created to provide users with print functionality in a + Sketch without having to cope with output moving from one cell to the next. Use + ``set_println_stream`` to change how the output is handled. The + ``println_stream`` object must provide ``init()`` and ``print()`` methods, as + shown in the example. The example demonstrates how to configure py5 to output + text to an IPython Widget. + """ + return _py5sketch.set_println_stream(println_stream) + + +def println( + *args, + sep: str = ' ', + end: str = '\n', + stderr: bool = False) -> None: + """Print text or other values to the screen. + + Parameters + ---------- + + args + values to be printed + + end: str = '\\n' + string appended after the last value, defaults to newline character + + sep: str = ' ' + string inserted between values, defaults to a space + + stderr: bool = False + use stderr instead of stdout + + Notes + ----- + + Print text or other values to the screen. For a Sketch running outside of a + Jupyter Notebook, this method will behave the same as the Python's builtin + ``print`` method. For Sketches running in a Jupyter Notebook, this will place + text in the output of the cell that made the ``run_sketch()`` call. + + When running a Sketch asynchronously through Jupyter Notebook, any ``print`` + statements using Python's builtin function will always appear in the output of + the currently active cell. This will rarely be desirable, as the active cell + will keep changing as the user executes code elsewhere in the notebook. This + method was created to provide users with print functionality in a Sketch without + having to cope with output moving from one cell to the next. + + Use ``set_println_stream()`` to customize the behavior of ``println()``. + """ + return _py5sketch.println(*args, sep=sep, end=end, stderr=stderr) + +############################################################################## +# module functions from threads.py +############################################################################## + + +def launch_thread( + f: Callable, + name: str = None, + *, + daemon: bool = True, + args: tuple = None, + kwargs: dict = None) -> str: + """Launch a new thread to execute a function in parallel with your Sketch code. + + Parameters + ---------- + + args: tuple = None + positional arguments to pass to the given function + + daemon: bool = True + if the thread should be a daemon thread + + f: Callable + function to call in the launched thread + + kwargs: dict = None + keyword arguments to pass to the given function + + name: str = None + name of thread to be created + + Notes + ----- + + Launch a new thread to execute a function in parallel with your Sketch code. + This can be useful for executing non-py5 code that would otherwise slow down the + animation thread and reduce the Sketch's frame rate. + + The ``name`` parameter is optional but useful if you want to monitor the thread + with other methods such as ``has_thread()``. If the provided ``name`` is + identical to an already running thread, the running thread will first be stopped + with a call to ``stop_thread()`` with the ``wait`` parameter equal to ``True``. + + Use the ``args`` and ``kwargs`` parameters to pass positional and keyword + arguments to the function. + + Use the ``daemon`` parameter to make the launched thread a daemon that will run + without blocking Python from exiting. This parameter defaults to ``True``, + meaning that function execution can be interupted if the Python process exits. + Note that if the Python process continues running after the Sketch exits, which + is typically the case when using a Jupyter Notebook, this parameter won't have + any effect unless if you try to restart the Notebook kernel. Generally speaking, + setting this parameter to ``False`` causes problems but it is available for + those who really need it. See ``stop_all_threads()`` for a better approach to + exit threads. + + The new thread is a Python thread, so all the usual caveats about the Global + Interpreter Lock (GIL) apply here. + """ + return _py5sketch.launch_thread( + f, name=name, daemon=daemon, args=args, kwargs=kwargs) + + +def launch_promise_thread( + f: Callable, + name: str = None, + *, + daemon: bool = True, + args: tuple = None, + kwargs: dict = None) -> Py5Promise: + """Create a ``Py5Promise`` object that will store the returned result of a function + when that function completes. + + Parameters + ---------- + + args: tuple = None + positional arguments to pass to the given function + + daemon: bool = True + if the thread should be a daemon thread + + f: Callable + function to call in the launched thread + + kwargs: dict = None + keyword arguments to pass to the given function + + name: str = None + name of thread to be created + + Notes + ----- + + Create a ``Py5Promise`` object that will store the returned result of a function + when that function completes. This can be useful for executing non-py5 code that + would otherwise slow down the animation thread and reduce the Sketch's frame + rate. + + The ``Py5Promise`` object has an ``is_ready`` property that will be ``True`` + when the ``result`` property contains the value function ``f`` returned. Before + then, the ``result`` property will be ``None``. + + The ``name`` parameter is optional but useful if you want to monitor the thread + with other methods such as ``has_thread()``. If the provided ``name`` is + identical to an already running thread, the running thread will first be stopped + with a call to ``stop_thread()`` with the ``wait`` parameter equal to ``True``. + + Use the ``args`` and ``kwargs`` parameters to pass positional and keyword + arguments to the function. + + Use the ``daemon`` parameter to make the launched thread a daemon that will run + without blocking Python from exiting. This parameter defaults to ``True``, + meaning that function execution can be interupted if the Python process exits. + Note that if the Python process continues running after the Sketch exits, which + is typically the case when using a Jupyter Notebook, this parameter won't have + any effect unless if you try to restart the Notebook kernel. Generally speaking, + setting this parameter to ``False`` causes problems but it is available for + those who really need it. See ``stop_all_threads()`` for a better approach to + exit threads. + + The new thread is a Python thread, so all the usual caveats about the Global + Interpreter Lock (GIL) apply here. + """ + return _py5sketch.launch_promise_thread( + f, name=name, daemon=daemon, args=args, kwargs=kwargs) + + +def launch_repeating_thread(f: Callable, name: str = None, *, + time_delay: float = 0, daemon: bool = True, + args: tuple = None, kwargs: dict = None) -> str: + """Launch a new thread that will repeatedly execute a function in parallel with + your Sketch code. + + Parameters + ---------- + + args: tuple = None + positional arguments to pass to the given function - x: Union[float, npt.NDArray] - x-coordinate in noise space + daemon: bool = True + if the thread should be a daemon thread - y: Union[float, npt.NDArray] - y-coordinate in noise space + f: Callable + function to call in the launched thread - z: Union[float, npt.NDArray] - z-coordinate in noise space + kwargs: dict = None + keyword arguments to pass to the given function + + name: str = None + name of thread to be created + + time_delay: float = 0 + time delay in seconds between calls to the given function Notes ----- - Generate pseudo-random noise values for specific coodinates using the - OpenSimplex 2 algorithm (smooth version / SuperSimplex). Noise functions are - random sequence generators that produce a more natural, harmonic succession of - numbers compared to the ``random()`` method. - - In contrast to the ``random()`` method, noise is defined in an n-dimensional - space, in which each coordinate corresponds to a fixed pseudo-random value - (fixed only for the lifespan of the program). The noise value can be animated by - moving through the noise space, as demonstrated in the examples. Any dimension - can also be interpreted as time. An easy way to animate the noise value is to - pass the ``os_noise()`` method the ``frame_count`` divided by a scaling factor, - as is done in a few of the examples. + Launch a new thread that will repeatedly execute a function in parallel with + your Sketch code. This can be useful for executing non-py5 code that would + otherwise slow down the animation thread and reduce the Sketch's frame rate. - The generated noise values for this method will be between -1 and 1, and can be - generated in 2, 3, or 4 dimensions. To generate noise in 1 dimension, add a - constant value as an extra parameter, as shown in a few examples. Py5 also - provides the ``noise()`` method, which generates noise using Processing's noise - algorithm. That algorithm typically generates noise values between 0 and 1, and - can be generated in 1, 2, or 3 dimensions. Be aware of both of these differences - when modifying your code to switch from one to the other. There are other - differences in the character of the noise values generated by both methods, so - you'll need to do some experimentation to get the results you want. + Use the ``time_delay`` parameter to set the time in seconds between one call to + function ``f`` and the next call. Set this parameter to ``0`` if you want each + call to happen immediately after the previous call finishes. If the function + ``f`` takes longer than expected to finish, py5 will wait for it to finish + before making the next call. There will not be overlapping calls to function + ``f``. - The nature of the noise values returned can be adjusted with - ``os_noise_seed()``. + The ``name`` parameter is optional but useful if you want to monitor the thread + with other methods such as ``has_thread()``. If the provided ``name`` is + identical to an already running thread, the running thread will first be stopped + with a call to ``stop_thread()`` with the ``wait`` parameter equal to ``True``. - Another way to adjust the character of the resulting sequence is the scale of - the input coordinates. As the method works within an infinite space, the value - of the coordinates doesn't matter as such; only the distance between successive - coordinates is important. As a general rule, the smaller the difference between - coordinates, the smoother the resulting noise sequence. Steps of 0.005-0.03 work - best for most applications, but this will differ depending on the use case and - the noise settings. + Use the ``args`` and ``kwargs`` parameters to pass positional and keyword + arguments to the function. - Py5's ``os_noise()`` method can also accept numpy arrays as parameters. It will - use broadcasting when needed and calculate the values efficiently. Using numpy - array parameters will be much faster and efficient than calling the - ``os_noise()`` method repeatedly in a loop. See the examples to see how this can - be done. The noise algorithm for this method is implemented in Java. + Use the ``daemon`` parameter to make the launched thread a daemon that will run + without blocking Python from exiting. This parameter defaults to ``True``, + meaning that function execution can be interupted if the Python process exits. + Note that if the Python process continues running after the Sketch exits, which + is typically the case when using a Jupyter Notebook, this parameter won't have + any effect unless if you try to restart the Notebook kernel. Generally speaking, + setting this parameter to ``False`` causes problems but it is available for + those who really need it. See ``stop_all_threads()`` for a better approach to + exit threads. - Noise generation is a rich and complex topic, and there are many noise - algorithms and libraries available that are worth learning about. Early versions - of py5 used the Python "noise" library, which can generate noise using the - "Improved Perlin Noise" algorithm (as described in Ken Perlin's 2002 SIGGRAPH - paper) and the Simplex Noise algorithm (also developed by Ken Perlin). That - Python library was removed from py5 because it has some bugs and hasn't had a - release in years. Nevertheless, it might be useful to you, and can be installed - separately like any other Python package. You can also try the Python library - "vnoise", which is a pure Python implementation of the Improved Perlin Noise - algorithm. Note that py5 can also employ Java libraries, so consider "FastNoise - Lite" to experiment with a large selection of noise algorithms with efficient - implementations. + The new thread is a Python thread, so all the usual caveats about the Global + Interpreter Lock (GIL) apply here. """ - pass + return _py5sketch.launch_repeating_thread( + f, + name=name, + time_delay=time_delay, + daemon=daemon, + args=args, + kwargs=kwargs) -def os_noise(*args) -> Union[float, npt.NDArray]: - """Generate pseudo-random noise values for specific coodinates using the - OpenSimplex 2 algorithm (smooth version / SuperSimplex). +def has_thread(name: str) -> None: + """Determine if a thread of a given name exists and is currently running. - Methods - ------- + Parameters + ---------- - You can use any of the following signatures: + name: str + name of thread - * os_noise(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] - * os_noise(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], z: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] - * os_noise(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], z: Union[float, npt.NDArray], w: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray] + Notes + ----- + + Determine if a thread of a given name exists and is currently running. You can + get the list of all currently running threads with ``list_threads()``. + """ + return _py5sketch.has_thread(name) + + +def stop_thread(name: str, wait: bool = False) -> None: + """Stop a thread of a given name. Parameters ---------- - w: Union[float, npt.NDArray] - w-coordinate in noise space + name: str + name of thread - x: Union[float, npt.NDArray] - x-coordinate in noise space + wait: bool = False + wait for thread to exit before returning - y: Union[float, npt.NDArray] - y-coordinate in noise space + Notes + ----- - z: Union[float, npt.NDArray] - z-coordinate in noise space + Stop a thread of a given name. The ``wait`` parameter determines if the method + call will return right away or wait for the thread to exit. + + This won't do anything useful if the thread was launched with either + ``launch_thread()`` or ``launch_promise_thread()`` and the ``wait`` parameter is + ``False``. Non-repeating threads are executed once and will stop when they + complete execution. Setting the ``wait`` parameter to ``True`` will merely block + until the thread exits on its own. Killing off a running thread in Python is + complicated and py5 cannot do that for you. If you want a thread to perform some + action repeatedly and be interuptable, use ``launch_repeating_thread()`` + instead. + + Use ``has_thread()`` to determine if a thread of a given name exists and + ``list_threads()`` to get a list of all thread names. Use ``stop_all_threads()`` + to stop all threads. + """ + return _py5sketch.stop_thread(name, wait=wait) + + +def stop_all_threads(wait: bool = False) -> None: + """Stop all running threads. + + Parameters + ---------- + + wait: bool = False + wait for thread to exit before returning Notes ----- - Generate pseudo-random noise values for specific coodinates using the - OpenSimplex 2 algorithm (smooth version / SuperSimplex). Noise functions are - random sequence generators that produce a more natural, harmonic succession of - numbers compared to the ``random()`` method. - - In contrast to the ``random()`` method, noise is defined in an n-dimensional - space, in which each coordinate corresponds to a fixed pseudo-random value - (fixed only for the lifespan of the program). The noise value can be animated by - moving through the noise space, as demonstrated in the examples. Any dimension - can also be interpreted as time. An easy way to animate the noise value is to - pass the ``os_noise()`` method the ``frame_count`` divided by a scaling factor, - as is done in a few of the examples. + Stop all running threads. The ``wait`` parameter determines if the method call + will return right away or wait for the threads to exit. - The generated noise values for this method will be between -1 and 1, and can be - generated in 2, 3, or 4 dimensions. To generate noise in 1 dimension, add a - constant value as an extra parameter, as shown in a few examples. Py5 also - provides the ``noise()`` method, which generates noise using Processing's noise - algorithm. That algorithm typically generates noise values between 0 and 1, and - can be generated in 1, 2, or 3 dimensions. Be aware of both of these differences - when modifying your code to switch from one to the other. There are other - differences in the character of the noise values generated by both methods, so - you'll need to do some experimentation to get the results you want. + When the Sketch shuts down, ``stop_all_threads(wait=False)`` is called for you. + If you would rather the Sketch waited for threads to exit, create an ``exiting`` + method and make a call to ``stop_all_threads(wait=True)``. + """ + return _py5sketch.stop_all_threads(wait=wait) - The nature of the noise values returned can be adjusted with - ``os_noise_seed()``. - Another way to adjust the character of the resulting sequence is the scale of - the input coordinates. As the method works within an infinite space, the value - of the coordinates doesn't matter as such; only the distance between successive - coordinates is important. As a general rule, the smaller the difference between - coordinates, the smoother the resulting noise sequence. Steps of 0.005-0.03 work - best for most applications, but this will differ depending on the use case and - the noise settings. +def list_threads() -> None: + """List the names of all of the currently running threads. - Py5's ``os_noise()`` method can also accept numpy arrays as parameters. It will - use broadcasting when needed and calculate the values efficiently. Using numpy - array parameters will be much faster and efficient than calling the - ``os_noise()`` method repeatedly in a loop. See the examples to see how this can - be done. The noise algorithm for this method is implemented in Java. + Notes + ----- - Noise generation is a rich and complex topic, and there are many noise - algorithms and libraries available that are worth learning about. Early versions - of py5 used the Python "noise" library, which can generate noise using the - "Improved Perlin Noise" algorithm (as described in Ken Perlin's 2002 SIGGRAPH - paper) and the Simplex Noise algorithm (also developed by Ken Perlin). That - Python library was removed from py5 because it has some bugs and hasn't had a - release in years. Nevertheless, it might be useful to you, and can be installed - separately like any other Python package. You can also try the Python library - "vnoise", which is a pure Python implementation of the Improved Perlin Noise - algorithm. Note that py5 can also employ Java libraries, so consider "FastNoise - Lite" to experiment with a large selection of noise algorithms with efficient - implementations. + List the names of all of the currently running threads. The names of previously + launched threads that have exited will be removed from the list. """ - return _py5sketch.os_noise(*args) + return _py5sketch.list_threads() ############################################################################## # module functions from sketch.py @@ -20481,6 +20522,44 @@ def select_output( prompt, callback, default_file=default_file) +def create_image_from_numpy( + array: npt.NDArray[np.uint8], bands: str = 'ARGB', *, dst: Py5Image = None) -> Py5Image: + """Convert a numpy array into a Py5Image object. + + Parameters + ---------- + + array: npt.NDArray[np.uint8] + numpy image array + + bands: str = 'ARGB' + color channels in array + + dst: Py5Image = None + existing Py5Image object to put the image data into + + Notes + ----- + + Convert a numpy array into a Py5Image object. The numpy array must have 3 + dimensions and the array's ``dtype`` must be ``np.uint8``. The size of + ``array``'s first and second dimensions will be the image's height and width, + respectively. The third dimension is for the array's color channels. + + The ``bands`` parameter is used to interpret the ``array``'s color channel + dimension (the array's third dimension). It can be one of ``'L'`` (single- + channel grayscale), ``'ARGB'``, ``'RGB'``, or ``'RGBA'``. If there is no alpha + channel, ``array`` is assumed to have no transparency. If the ``bands`` + parameter is ``'L'``, ``array``'s third dimension is optional. + + The caller can optionally pass an existing Py5Image object to put the image data + into using the ``dst`` parameter. This can have performance benefits in code + that would otherwise continuously create new Py5Image objects. The array's width + and height must match that of the recycled Py5Image object. + """ + return _py5sketch.create_image_from_numpy(array, bands=bands, dst=dst) + + def convert_image(obj: Any, *, dst: Py5Image = None) -> Py5Image: """Convert non-py5 image objects into Py5Image objects. diff --git a/py5/graphics.py b/py5/graphics.py index 91b4149..9a075fd 100644 --- a/py5/graphics.py +++ b/py5/graphics.py @@ -894,52 +894,52 @@ def apply_matrix(self, n00: float, n01: float, n02: float, ---------- n00: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 0 of the matrix n01: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 1 of the matrix n02: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 2 of the matrix n03: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 3 of the matrix n10: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 0 of the matrix n11: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 1 of the matrix n12: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 2 of the matrix n13: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 3 of the matrix n20: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 0 of the matrix n21: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 1 of the matrix n22: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 2 of the matrix n23: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 3 of the matrix n30: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 0 of the matrix n31: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 1 of the matrix n32: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 2 of the matrix n33: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 3 of the matrix source: npt.NDArray[np.floating] transformation matrix with a shape of 2x3 for 2D transforms or 4x4 for 3D transforms @@ -994,52 +994,52 @@ def apply_matrix( ---------- n00: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 0 of the matrix n01: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 1 of the matrix n02: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 2 of the matrix n03: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 3 of the matrix n10: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 0 of the matrix n11: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 1 of the matrix n12: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 2 of the matrix n13: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 3 of the matrix n20: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 0 of the matrix n21: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 1 of the matrix n22: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 2 of the matrix n23: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 3 of the matrix n30: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 0 of the matrix n31: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 1 of the matrix n32: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 2 of the matrix n33: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 3 of the matrix source: npt.NDArray[np.floating] transformation matrix with a shape of 2x3 for 2D transforms or 4x4 for 3D transforms @@ -1076,52 +1076,52 @@ def apply_matrix(self, source: npt.NDArray[np.floating], /) -> None: ---------- n00: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 0 of the matrix n01: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 1 of the matrix n02: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 2 of the matrix n03: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 3 of the matrix n10: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 0 of the matrix n11: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 1 of the matrix n12: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 2 of the matrix n13: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 3 of the matrix n20: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 0 of the matrix n21: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 1 of the matrix n22: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 2 of the matrix n23: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 3 of the matrix n30: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 0 of the matrix n31: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 1 of the matrix n32: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 2 of the matrix n33: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 3 of the matrix source: npt.NDArray[np.floating] transformation matrix with a shape of 2x3 for 2D transforms or 4x4 for 3D transforms @@ -1157,52 +1157,52 @@ def apply_matrix(self, *args): ---------- n00: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 0 of the matrix n01: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 1 of the matrix n02: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 2 of the matrix n03: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 3 of the matrix n10: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 0 of the matrix n11: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 1 of the matrix n12: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 2 of the matrix n13: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 3 of the matrix n20: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 0 of the matrix n21: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 1 of the matrix n22: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 2 of the matrix n23: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 3 of the matrix n30: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 0 of the matrix n31: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 1 of the matrix n32: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 2 of the matrix n33: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 3 of the matrix source: npt.NDArray[np.floating] transformation matrix with a shape of 2x3 for 2D transforms or 4x4 for 3D transforms diff --git a/py5/jars/core.jar b/py5/jars/core.jar index dfbd5ccb5f43b29bd1c605c0e72cc10c0692beb4..6e5f32d24b6d8b70d04fe5be3315af4a1658252e 100644 GIT binary patch delta 108725 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

8nb*ql=ti-<-X&`@BTOC({tY$mi! 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�p4 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 diff --git a/py5/jars/dxf/dxf.jar b/py5/jars/dxf/dxf.jar index fb10b084a6a278b24c344479717739c21b2a5c9a..7be9032da0065801fb7e68d228f5cb46dfee48bd 100644 GIT binary patch delta 213 zcmaDY{6v^Hz?+$ci-CcIf#It)=R{r&!7tXFp=Tz3I+w`6z>o{XB9s4fh);~QG4k1> zTjD&~>$8_vDQ_>&7akuG6Q(Ys(+yoBbG(d;gG?%SR_tUzHSUrcGsx86S|Dn(24gKd zh%tEuhXpT+HIv_Rn92iXLV@pKnK79Kb$4N@YeAikXKNYpPX7;oSB!d zpHh*gAK=Z%B*F~x2?xk0p&YIcHn_4gFvRjQFi68SGcYV^l%BkSQ;%&X(8ml60B7e% AwEzGB diff --git a/py5/jars/pdf/pdf.jar b/py5/jars/pdf/pdf.jar index e9904744d1dd5c3ca1b511e404758192a7327541..a8f6fb3a35514fa1d177902c1ae175de1f748cc7 100644 GIT binary patch delta 213 zcmX@0y;GYvz?+$ci-CcIf#It)=R{r&!7tXFp=Tz3I+w`6z>o{XB9qUFh);~QG4k1> zTjD&~>$8_vDQ_>&7akuG6Q(Ys(+yoBbG(d;gG?%SR_tUzHSUrcGsx86S|Dn(2BVKK zh%vcb#DW*an#p@aOyz+xp+NiKfE&&dV0i1eZ?b@>6j-;es5ImA$)2KeU|trGCo;KB L)PyZj1f&4~dKWsn delta 288 zcmdm~eL$Nxz?+$ci-CcIf#L32mWjL?ym!{JgqC_t@y%dhU?`vH6mHqG^=zs0WUtR& zUZuQV2e&lNo7gz7v2)(SCO3z`G|7OSO~ILIeqCz%;`-tYsHUA(V+I-eMGHi2R%G-M z1~DcVh*+T7GI^_rDOl#Mh;;o?puGh}`N^rp#hH2O`T^dIOd`y17ls05;ea2`5@2}i z_zuWJ(pZp^hNPJTD9ORgc%qPsxvSs!ZkB6ENPTxgleALE~>+pAp(*F08@}o A!2kdN diff --git a/py5/jars/py5.jar b/py5/jars/py5.jar index c0628ef9f467396bc11fbe22c38671758e4952fe..9a17ba11009b504a8b729bbb8c904ca309efb569 100644 GIT binary patch delta 832 zcmcc6&2+h&i8sKTnT3mifrEje%s_S`uLg4|kg{lD2J!aGgQyPSxESf2Q`fUBx`)B1_KijaG|L2SOW61L0c=4S*X9_>h zBG1nE@&Dbu{{w%|N#AxX{=r0H;e+yeni}6Cf7CYJSO4*mJL{(lckxd?`7IU8mMFw` zt1mnneBlxMg$J5ep|)>jxOkbC#r=*+*|zv-j(hjbzIw6Exw=o@>0WfQdwlVi$d}8@ zx%R%dn14s5!Okm&-C!PPx$&ZdcD_E?;6I>UzCgv zdz-lJ?OE{0%dbgmtD9=oRr@b1>Q~jD6jqt^%lzbXk+`q&Hnkf2ZP(OSe|gW;AOF4j zhpGPo<^OkjH6A#&zBaURowqRLlRYf@I6%?2Ip5+qB-Aafw3)!6o^JCQA`)xI%mEfj zcAEf^`sSf;4icHH(O?0J#mUJH_F(?f27NHy*C;*tQ-dU!&DUrPrv0FFU!w_F&(TH~ zusBbXGnfu)as|_~n!LgEizZJnZPM(Ii1W!k%~oL1lg-jhsTPy#EDUu5ycwB9m_aEK z?3GaCw%ezlGcquEFf%Y{G9bW`Mt!Tv9#-0u^ICYoX4JMwGsW6W&aso3ysbq}0hF*F z9^KG+f*qKm`571#5Ly|QGzQxN6)I_?Tb5&J+2+Z_z>o>FOb10ni@!BJyX)}K)}oVxRx z#Oxc`{4cJ2mH9j%L%`tct>;RcWp&f6qt29VnUR}auUMYnDfUUS|Jw2e^X)=k)E@u& zM2(T>(83_I4asZ5U+vZEa#^^m&qiX(`tt?q@q#>`UugiN@Kq|y z)9@mpkd?X@SO0Tf=>9kOulGEKiC6Y}+AaUE>i>h6&OhHK{=L1pUcBPZuKS1AS2D@{ ze4gjR$gdUC|4{Q2&(cZ%8DVk90gAiLMHa^)L2hHE%>)keESt{|kpw$t4zNg?+XRTz zPY-=_kjP~11`AM>PflyF2lH1n=!5Brjnb39Hb{cmf{nIdIuJ@vY%~G$Pc*uKY5pc> zFdf?D3Z~~ad4uWKO`c%dyxAWS;gkEDt-zvZnx&bNEG9Qv7*3XI;Q|4UXAcIiHu%z+j(qARVn}g diff --git a/py5/jars/svg/svg.jar b/py5/jars/svg/svg.jar index 367e954fd192f8af55ea3dc2a8b89e1c082e0f0a..1a31e1a4205c1fa01e67562771f7733faf193ce9 100644 GIT binary patch delta 304 zcmX>hbx?{oz?+$ci-CcIf#It)=R{r&-Y?dip=Tz3I+w`6z>qu9Dcs0si*AYYWUtR& zUZuRfJYRTxL`;~vj7~RniOlgbE)FuO+*z@c0o9mGYRn+hertiK%^HjWOkhSevnvOP zG5IjJ1*$!hIe1LLG7db_jQb|X@JNAql|0h*&w=hJD9TSxEiTT?OV=+hOV-=TanHU(NnHd=PfXZQDNuvlO14DRGW=U#rn7dwbPGWH}x?bM0y<+S@ f-#->$U{Hi<1ky_y(}AWH6ipW9)n{AF4Uz!>8|6?; delta 256 zcmX>obwY|az?+$ci-CcIf#JbgmWjL?ym!~KgqC_t@y%dhU?`vH6mHqG^=zs0WUtR& zUZuQV2e&lNo7gz7v2)(SCO3z`G|7OSO~ILIeqCz%;`-tYsHUA(V+I-eMGHi2R%8rd z0y9dOT{%FE$$PjhP_3KH$YTnYvE-4qItp|^K~a8kYH@L9Ub=pOHzSh>Gu)}6Kv_88 qhqDA2-a5XU+{YsaHfBAKG^6z7(>$_Z-fJK)Z!$Zt3ELKKkOlzWG)jE{ diff --git a/py5/mixins/math.py b/py5/mixins/math.py index 6894c70..8e52f32 100644 --- a/py5/mixins/math.py +++ b/py5/mixins/math.py @@ -70,8 +70,8 @@ def hex_color(cls, color: int) -> str: provides an alternative approach, converting the 32 bit integer into a string such as ``'#0F3FF0FF'``. The hex string has 8 hexadecimal values following a ``#`` character. The first two values represent the red value, the next two - green, the next two blue, and the last two alpha. This is similar to web colors - except for the addition of the alpha channel. + green, the next two blue, and the last two alpha. This is consistent with CSS 8 + digit hex colors. Conveniently, the hex color string returned by this method can also be used as parameter for other methods that accept color values. Observe how this is done diff --git a/py5/mixins/print_tools.py b/py5/mixins/print_tools.py index 9d8d023..cf8308e 100644 --- a/py5/mixins/print_tools.py +++ b/py5/mixins/print_tools.py @@ -17,6 +17,8 @@ # along with this library. If not, see . # # ***************************************************************************** +import sys + from typing import Any @@ -96,5 +98,8 @@ def println( having to cope with output moving from one cell to the next. Use ``set_println_stream()`` to customize the behavior of ``println()``.""" - self._println_stream.print(sep.join(str(x) - for x in args), end=end, stderr=stderr) + msg = sep.join(str(x) for x in args) + if self._println_stream is None: + print(msg, end=end, file=sys.stderr if stderr else sys.stdout) + else: + self._println_stream.print(msg, end=end, stderr=stderr) diff --git a/py5/reference.py b/py5/reference.py index ca67c21..65cb9dd 100644 --- a/py5/reference.py +++ b/py5/reference.py @@ -235,22 +235,9 @@ (('Sketch', 'window_resize'), ['(new_width: int, new_height: int, /) -> None']), (('Sketch', 'window_title'), ['(title: str, /) -> None']), (('Sketch', 'year'), ['() -> int']), - (('Sketch', 'set_println_stream'), ['(println_stream: Any) -> None']), - (('Sketch', 'println'), ["(*args, sep: str = ' ', end: str = '\\n', stderr: bool = False) -> None"]), (('Sketch', 'load_json'), ['(json_path: Union[str, Path], **kwargs: dict[str, Any]) -> Any']), (('Sketch', 'save_json'), ['(json_data: Any, filename: Union[str, Path], **kwargs: dict[str, Any]) -> None']), (('Sketch', 'parse_json'), ['(serialized_json: Any, **kwargs: dict[str, Any]) -> Any']), - (('Sketch', 'load_np_pixels'), ['() -> None']), - (('Sketch', 'update_np_pixels'), ['() -> None']), - (('Sketch', 'set_np_pixels'), ["(array: npt.NDArray[np.uint8], bands: str = 'ARGB') -> None"]), - (('Sketch', 'save'), ['(filename: Union[str, Path, BytesIO], *, format: str = None, drop_alpha: bool = True, use_thread: bool = False, **params) -> None']), - (('Sketch', 'launch_thread'), ['(f: Callable, name: str = None, *, daemon: bool = True, args: tuple = None, kwargs: dict = None) -> str']), - (('Sketch', 'launch_promise_thread'), ['(f: Callable, name: str = None, *, daemon: bool = True, args: tuple = None, kwargs: dict = None) -> Py5Promise']), - (('Sketch', 'launch_repeating_thread'), ['(f: Callable, name: str = None, *, time_delay: float = 0, daemon: bool = True, args: tuple = None, kwargs: dict = None) -> str']), - (('Sketch', 'has_thread'), ['(name: str) -> None']), - (('Sketch', 'stop_thread'), ['(name: str, wait: bool = False) -> None']), - (('Sketch', 'stop_all_threads'), ['(wait: bool = False) -> None']), - (('Sketch', 'list_threads'), ['() -> None']), (('Sketch', 'hex_color'), ['(color: int) -> str']), (('Sketch', 'sin'), ['(angle: Union[float, npt.ArrayLike]) -> Union[float, npt.NDArray]']), (('Sketch', 'cos'), ['(angle: Union[float, npt.ArrayLike]) -> Union[float, npt.NDArray]']), @@ -280,6 +267,19 @@ (('Sketch', 'random_gaussian'), ['() -> float', '(loc: float, /) -> float', '(loc: float, scale: float, /) -> float']), (('Sketch', 'noise'), ['(x: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray]', '(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray]', '(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], z: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray]']), (('Sketch', 'os_noise'), ['(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray]', '(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], z: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray]', '(x: Union[float, npt.NDArray], y: Union[float, npt.NDArray], z: Union[float, npt.NDArray], w: Union[float, npt.NDArray], /) -> Union[float, npt.NDArray]']), + (('Sketch', 'load_np_pixels'), ['() -> None']), + (('Sketch', 'update_np_pixels'), ['() -> None']), + (('Sketch', 'set_np_pixels'), ["(array: npt.NDArray[np.uint8], bands: str = 'ARGB') -> None"]), + (('Sketch', 'save'), ['(filename: Union[str, Path, BytesIO], *, format: str = None, drop_alpha: bool = True, use_thread: bool = False, **params) -> None']), + (('Sketch', 'set_println_stream'), ['(println_stream: Any) -> None']), + (('Sketch', 'println'), ["(*args, sep: str = ' ', end: str = '\\n', stderr: bool = False) -> None"]), + (('Sketch', 'launch_thread'), ['(f: Callable, name: str = None, *, daemon: bool = True, args: tuple = None, kwargs: dict = None) -> str']), + (('Sketch', 'launch_promise_thread'), ['(f: Callable, name: str = None, *, daemon: bool = True, args: tuple = None, kwargs: dict = None) -> Py5Promise']), + (('Sketch', 'launch_repeating_thread'), ['(f: Callable, name: str = None, *, time_delay: float = 0, daemon: bool = True, args: tuple = None, kwargs: dict = None) -> str']), + (('Sketch', 'has_thread'), ['(name: str) -> None']), + (('Sketch', 'stop_thread'), ['(name: str, wait: bool = False) -> None']), + (('Sketch', 'stop_all_threads'), ['(wait: bool = False) -> None']), + (('Sketch', 'list_threads'), ['() -> None']), (('Sketch', 'sketch_path'), ['() -> Path', '(where: str, /) -> Path']), (('Sketch', 'hot_reload_draw'), ['(draw: Callable) -> None']), (('Sketch', 'profile_functions'), ['(function_names: list[str]) -> None']), @@ -289,6 +289,7 @@ (('Sketch', 'select_folder'), ['(prompt: str, callback: Callable, default_folder: str = None) -> None']), (('Sketch', 'select_input'), ['(prompt: str, callback: Callable, default_file: str = None) -> None']), (('Sketch', 'select_output'), ['(prompt: str, callback: Callable, default_file: str = None) -> None']), + (('Sketch', 'create_image_from_numpy'), ["(array: npt.NDArray[np.uint8], bands: str = 'ARGB', *, dst: Py5Image = None) -> Py5Image"]), (('Sketch', 'convert_image'), ['(obj: Any, *, dst: Py5Image = None) -> Py5Image']), (('Sketch', 'load_image'), ['(image_path: Union[str, Path], *, dst: Py5Image = None) -> Py5Image']), (('Sketch', 'request_image'), ['(image_path: Union[str, Path]) -> Py5Promise']), diff --git a/py5/shape.py b/py5/shape.py index 50512dc..8aca973 100644 --- a/py5/shape.py +++ b/py5/shape.py @@ -476,52 +476,52 @@ def apply_matrix(self, n00: float, n01: float, n02: float, ---------- n00: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 0 of the matrix n01: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 1 of the matrix n02: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 2 of the matrix n03: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 3 of the matrix n10: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 0 of the matrix n11: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 1 of the matrix n12: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 2 of the matrix n13: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 3 of the matrix n20: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 0 of the matrix n21: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 1 of the matrix n22: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 2 of the matrix n23: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 3 of the matrix n30: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 0 of the matrix n31: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 1 of the matrix n32: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 2 of the matrix n33: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 3 of the matrix source: npt.NDArray[np.floating] transformation matrix with a shape of 2x3 for 2D transforms or 4x4 for 3D transforms @@ -578,52 +578,52 @@ def apply_matrix( ---------- n00: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 0 of the matrix n01: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 1 of the matrix n02: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 2 of the matrix n03: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 3 of the matrix n10: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 0 of the matrix n11: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 1 of the matrix n12: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 2 of the matrix n13: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 3 of the matrix n20: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 0 of the matrix n21: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 1 of the matrix n22: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 2 of the matrix n23: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 3 of the matrix n30: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 0 of the matrix n31: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 1 of the matrix n32: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 2 of the matrix n33: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 3 of the matrix source: npt.NDArray[np.floating] transformation matrix with a shape of 2x3 for 2D transforms or 4x4 for 3D transforms @@ -662,52 +662,52 @@ def apply_matrix(self, source: npt.NDArray[np.floating], /) -> None: ---------- n00: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 0 of the matrix n01: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 1 of the matrix n02: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 2 of the matrix n03: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 3 of the matrix n10: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 0 of the matrix n11: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 1 of the matrix n12: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 2 of the matrix n13: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 3 of the matrix n20: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 0 of the matrix n21: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 1 of the matrix n22: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 2 of the matrix n23: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 3 of the matrix n30: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 0 of the matrix n31: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 1 of the matrix n32: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 2 of the matrix n33: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 3 of the matrix source: npt.NDArray[np.floating] transformation matrix with a shape of 2x3 for 2D transforms or 4x4 for 3D transforms @@ -745,52 +745,52 @@ def apply_matrix(self, *args): ---------- n00: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 0 of the matrix n01: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 1 of the matrix n02: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 2 of the matrix n03: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 3 of the matrix n10: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 0 of the matrix n11: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 1 of the matrix n12: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 2 of the matrix n13: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 3 of the matrix n20: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 0 of the matrix n21: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 1 of the matrix n22: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 2 of the matrix n23: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 3 of the matrix n30: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 0 of the matrix n31: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 1 of the matrix n32: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 2 of the matrix n33: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 3 of the matrix source: npt.NDArray[np.floating] transformation matrix with a shape of 2x3 for 2D transforms or 4x4 for 3D transforms diff --git a/py5/sketch.py b/py5/sketch.py index a14af42..62ed4c6 100644 --- a/py5/sketch.py +++ b/py5/sketch.py @@ -18,7 +18,6 @@ # # ***************************************************************************** from __future__ import annotations -from re import S import time import os @@ -879,6 +878,14 @@ def select_folder(self, prompt: str, callback: Callable, the Sketch is run through a Jupyter notebook. On Windows, Sketches using the OpenGL renderers (``P2D`` or ``P3D``) will be minimized while the select dialog box is open. This method only uses native dialog boxes on OSX.""" + if not isinstance( + prompt, + str) or not callable(callback) or ( + default_folder is not None and not isinstance( + default_folder, + str)): + raise TypeError( + "This method's signature is select_folder(prompt: str, callback: Callable, default_folder: str)") self._generic_select( self._instance.py5SelectFolder, 'select_folder', @@ -920,6 +927,14 @@ def select_input( the Sketch is run through a Jupyter notebook. On Windows, Sketches using the OpenGL renderers (``P2D`` or ``P3D``) will be minimized while the select dialog box is open. This method only uses native dialog boxes on OSX.""" + if not isinstance( + prompt, + str) or not callable(callback) or ( + default_file is not None and not isinstance( + default_file, + str)): + raise TypeError( + "This method's signature is select_input(prompt: str, callback: Callable, default_file: str)") self._generic_select( self._instance.py5SelectInput, 'select_input', @@ -961,6 +976,14 @@ def select_output( the Sketch is run through a Jupyter notebook. On Windows, Sketches using the OpenGL renderers (``P2D`` or ``P3D``) will be minimized while the select dialog box is open. This method only uses native dialog boxes on OSX.""" + if not isinstance( + prompt, + str) or not callable(callback) or ( + default_file is not None and not isinstance( + default_file, + str)): + raise TypeError( + "This method's signature is select_output(prompt: str, callback: Callable, default_file: str)") self._generic_select( self._instance.py5SelectOutput, 'select_output', @@ -2710,52 +2733,52 @@ def apply_matrix(self, n00: float, n01: float, n02: float, ---------- n00: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 0 of the matrix n01: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 1 of the matrix n02: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 2 of the matrix n03: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 3 of the matrix n10: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 0 of the matrix n11: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 1 of the matrix n12: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 2 of the matrix n13: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 3 of the matrix n20: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 0 of the matrix n21: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 1 of the matrix n22: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 2 of the matrix n23: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 3 of the matrix n30: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 0 of the matrix n31: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 1 of the matrix n32: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 2 of the matrix n33: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 3 of the matrix source: npt.NDArray[np.floating] transformation matrix with a shape of 2x3 for 2D transforms or 4x4 for 3D transforms @@ -2807,52 +2830,52 @@ def apply_matrix( ---------- n00: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 0 of the matrix n01: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 1 of the matrix n02: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 2 of the matrix n03: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 3 of the matrix n10: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 0 of the matrix n11: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 1 of the matrix n12: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 2 of the matrix n13: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 3 of the matrix n20: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 0 of the matrix n21: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 1 of the matrix n22: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 2 of the matrix n23: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 3 of the matrix n30: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 0 of the matrix n31: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 1 of the matrix n32: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 2 of the matrix n33: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 3 of the matrix source: npt.NDArray[np.floating] transformation matrix with a shape of 2x3 for 2D transforms or 4x4 for 3D transforms @@ -2886,52 +2909,52 @@ def apply_matrix(self, source: npt.NDArray[np.floating], /) -> None: ---------- n00: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 0 of the matrix n01: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 1 of the matrix n02: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 2 of the matrix n03: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 3 of the matrix n10: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 0 of the matrix n11: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 1 of the matrix n12: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 2 of the matrix n13: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 3 of the matrix n20: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 0 of the matrix n21: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 1 of the matrix n22: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 2 of the matrix n23: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 3 of the matrix n30: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 0 of the matrix n31: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 1 of the matrix n32: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 2 of the matrix n33: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 3 of the matrix source: npt.NDArray[np.floating] transformation matrix with a shape of 2x3 for 2D transforms or 4x4 for 3D transforms @@ -2964,52 +2987,52 @@ def apply_matrix(self, *args): ---------- n00: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 0 of the matrix n01: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 1 of the matrix n02: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 2 of the matrix n03: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 0 and column 3 of the matrix n10: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 0 of the matrix n11: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 1 of the matrix n12: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 2 of the matrix n13: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 1 and column 3 of the matrix n20: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 0 of the matrix n21: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 1 of the matrix n22: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 2 of the matrix n23: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 2 and column 3 of the matrix n30: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 0 of the matrix n31: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 1 of the matrix n32: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 2 of the matrix n33: float - numbers which define the 4x4 matrix to be multiplied + numeric value in row 3 and column 3 of the matrix source: npt.NDArray[np.floating] transformation matrix with a shape of 2x3 for 2D transforms or 4x4 for 3D transforms @@ -12789,6 +12812,9 @@ def push(self) -> None: ``push_matrix()``, ``pop_matrix()``, ``push_style()``, and ``pop_style()``. The difference is that ``push()`` and ``pop()`` control both the transformations (rotate, scale, translate) and the drawing styles at the same time. + + This method can be used as a context manager to ensure that ``pop()`` always + gets called, as shown in the last example. """ return self._instance.push() @@ -12808,6 +12834,9 @@ def push_matrix(self) -> None: ``push_matrix()`` and ``pop_matrix()`` are used in conjuction with the other transformation functions and may be embedded to control the scope of the transformations. + + This method can be used as a context manager to ensure that ``pop_matrix()`` + always gets called, as shown in the last example. """ return self._instance.pushMatrix() @@ -12835,6 +12864,9 @@ def push_style(self) -> None: ``ellipse_mode()``, ``shape_mode()``, ``color_mode()``, ``text_align()``, ``text_font()``, ``text_mode()``, ``text_size()``, ``text_leading()``, ``emissive()``, ``specular()``, ``shininess()``, and ``ambient()``. + + This method can be used as a context manager to ensure that ``pop_style()`` + always gets called, as shown in the last example. """ return self._instance.pushStyle() @@ -14730,6 +14762,14 @@ def size(self, width: int, height: int, /) -> None: * ``SVG``: The ``SVG`` renderer draws 2D graphics directly to an SVG file. This is great for importing into other vector programs or using for digital fabrication. + + When using the ``PDF`` and ``SVG`` renderers with the ``size()`` method, you + must use the ``path`` parameter to specify the file to write the output to. No + window will open while the Sketch is running. You must also call + ``exit_sketch()`` to exit the Sketch and write the completed output to the file. + Without this call, the Sketch will not exit and the output file will be empty. + If you would like to draw 3D objects to a PDF or SVG file, use the ``P3D`` + renderer and the strategy described in ``begin_raw()``. """ pass @@ -14821,6 +14861,14 @@ def size(self, width: int, height: int, renderer: str, /) -> None: * ``SVG``: The ``SVG`` renderer draws 2D graphics directly to an SVG file. This is great for importing into other vector programs or using for digital fabrication. + + When using the ``PDF`` and ``SVG`` renderers with the ``size()`` method, you + must use the ``path`` parameter to specify the file to write the output to. No + window will open while the Sketch is running. You must also call + ``exit_sketch()`` to exit the Sketch and write the completed output to the file. + Without this call, the Sketch will not exit and the output file will be empty. + If you would like to draw 3D objects to a PDF or SVG file, use the ``P3D`` + renderer and the strategy described in ``begin_raw()``. """ pass @@ -14913,6 +14961,14 @@ def size(self, width: int, height: int, * ``SVG``: The ``SVG`` renderer draws 2D graphics directly to an SVG file. This is great for importing into other vector programs or using for digital fabrication. + + When using the ``PDF`` and ``SVG`` renderers with the ``size()`` method, you + must use the ``path`` parameter to specify the file to write the output to. No + window will open while the Sketch is running. You must also call + ``exit_sketch()`` to exit the Sketch and write the completed output to the file. + Without this call, the Sketch will not exit and the output file will be empty. + If you would like to draw 3D objects to a PDF or SVG file, use the ``P3D`` + renderer and the strategy described in ``begin_raw()``. """ pass @@ -15003,6 +15059,14 @@ def size(self, *args): * ``SVG``: The ``SVG`` renderer draws 2D graphics directly to an SVG file. This is great for importing into other vector programs or using for digital fabrication. + + When using the ``PDF`` and ``SVG`` renderers with the ``size()`` method, you + must use the ``path`` parameter to specify the file to write the output to. No + window will open while the Sketch is running. You must also call + ``exit_sketch()`` to exit the Sketch and write the completed output to the file. + Without this call, the Sketch will not exit and the output file will be empty. + If you would like to draw 3D objects to a PDF or SVG file, use the ``P3D`` + renderer and the strategy described in ``begin_raw()``. """ return self._instance.size(*args) diff --git a/py5/vector.py b/py5/vector.py index 848ee9a..2c32244 100644 --- a/py5/vector.py +++ b/py5/vector.py @@ -76,6 +76,7 @@ class Py5Vector(Sequence): the ``copy`` parameter to ``False``, such as ``v6 = py5.Py5Vector(arr, copy=False)``. """ + _DEFAULT_DIM = 3 def __new__( cls, @@ -86,7 +87,8 @@ def __new__( kwarg_dim = dim kwarg_dtype = dtype - dim = 3 if dim is None else dim + used_default_dim = len(args) == 0 and dim is None + dim = Py5Vector._DEFAULT_DIM if dim is None else dim dtype = np.float_ if dtype is None else dtype if not isinstance( @@ -180,6 +182,7 @@ def __new__( raise RuntimeError(f'Why is dim == {dim}? Please report bug') v._data = data + v._used_default_dim = used_default_dim return v @@ -229,6 +232,16 @@ def __str__(self): def __repr__(self): return f'Py5Vector{self._data.size}D{repr(self._data)[5:]}' + def _check_used_default_dim(self, other): + if self._used_default_dim or ( + isinstance( + other, + Py5Vector) and other._used_default_dim): + other_dim = self._data.size + other._data.size - Py5Vector._DEFAULT_DIM + return f" Note that one of the Py5Vectors was created with Py5Vector(), and is therefore by default a {Py5Vector._DEFAULT_DIM}D vector. If you wanted a {other_dim}D vector instead, use the `dim` parameter, like this: Py5Vector(dim={other_dim})." + else: + return "" + def _run_op( self, op, @@ -243,7 +256,8 @@ def _run_op( f"Cannot perform {opname} operation on two Py5Vectors. If you want to do {opname} on the Py5Vector's data elementwise, use the `.data` attribute to access the Py5Vector's data as a numpy array.") elif self._data.size != other._data.size: raise RuntimeError( - f"Cannot perform {opname} operation on a {self._data.size}D Py5Vector a {other._data.size}D Py5Vector. The dimensions must be the same.") + f"Cannot perform {opname} operation on a {self._data.size}D Py5Vector and a {other._data.size}D Py5Vector. The dimensions must be the same." + + self._check_used_default_dim(other)) elif inplace: op(self._data[:other._data.size], other._data[:other._data.size]) @@ -580,7 +594,8 @@ def _run_calc(self, other, calc, name, maybe_vector=False): other = other._data else: raise RuntimeError( - f'Py5Vector dimensions must be the same to calculate the {name} two Py5Vectors') + f'Py5Vector dimensions must be the same to calculate the {name} two Py5Vectors.' + + self._check_used_default_dim(other)) if isinstance(other, np.ndarray): try: diff --git a/py5_tools/__init__.py b/py5_tools/__init__.py index c9bb602..9e6897d 100644 --- a/py5_tools/__init__.py +++ b/py5_tools/__init__.py @@ -28,4 +28,4 @@ from . import translators # noqa -__version__ = '0.8.1a1' +__version__ = '0.8.2a1' diff --git a/py5_tools/imported.py b/py5_tools/imported.py index a28d0c0..714bb45 100644 --- a/py5_tools/imported.py +++ b/py5_tools/imported.py @@ -91,10 +91,9 @@ def setup(): ) """ -_CODE_FRAMEWORK = """ -__file__ = "{4}" +_CODE_FRAMEWORK = """{0} + -{0} run_sketch(block=True, py5_options={2}, sketch_args={3}) if {1} and is_dead_from_error: @@ -214,8 +213,7 @@ def _run_sketch(sketch_path, classpath, exit_if_error): with open(sketch_path, 'r', encoding='utf8') as f: sketch_code = _CODE_FRAMEWORK.format( - f.read(), exit_if_error, py5_options_str, sketch_args_str, re.sub( - r"""(\"|\')""", r'\\\1', str(original_sketch_path))) + f.read(), exit_if_error, py5_options_str, sketch_args_str) # does the code parse? if not, display an error message try: @@ -253,6 +251,7 @@ def _run_sketch(sketch_path, classpath, exit_if_error): sys.path.extend([str(sketch_path.absolute().parent), os.getcwd()]) py5_ns = dict() py5_ns.update(py5.__dict__) + py5_ns['__file__'] = str(original_sketch_path) exec(sketch_compiled, py5_ns) diff --git a/py5_tools/kernel/kernel.py b/py5_tools/kernel/kernel.py index 11fe955..c4ffeea 100644 --- a/py5_tools/kernel/kernel.py +++ b/py5_tools/kernel/kernel.py @@ -80,7 +80,7 @@ class Py5Kernel(IPythonKernel): *_PY5_HELP_LINKS]).tag(config=True) implementation = 'py5' - implementation_version = '0.8.1a1' + implementation_version = '0.8.2a1' class Py5App(IPKernelApp): diff --git a/py5_tools/py5bot/kernel.py b/py5_tools/py5bot/kernel.py index fe76eea..da6a714 100644 --- a/py5_tools/py5bot/kernel.py +++ b/py5_tools/py5bot/kernel.py @@ -87,7 +87,7 @@ class Py5BotKernel(Py5Kernel): shell_class = Type(Py5BotShell) implementation = 'py5bot' - implementation_version = '0.8.1a1' + implementation_version = '0.8.2a1' class Py5BotApp(IPKernelApp): diff --git a/py5_tools/reference.py b/py5_tools/reference.py index da913b1..1390d82 100644 --- a/py5_tools/reference.py +++ b/py5_tools/reference.py @@ -107,6 +107,7 @@ 'create_font_file', 'create_graphics', 'create_image', + 'create_image_from_numpy', 'create_shape', 'CROSS', 'cursor', @@ -572,6 +573,7 @@ 'create_font_file', 'create_graphics', 'create_image', + 'create_image_from_numpy', 'create_shape', 'CROSS', 'cursor', diff --git a/py5_tools/split_setup.py b/py5_tools/split_setup.py index 668a207..46e9ff4 100644 --- a/py5_tools/split_setup.py +++ b/py5_tools/split_setup.py @@ -25,7 +25,8 @@ COMMENT_LINE = re.compile(r'^\s*#.*' + chr(36), flags=re.MULTILINE) -DOCSTRING = re.compile(r'^\s*"""[^"]*"""', flags=re.MULTILINE | re.DOTALL) +DOCSTRING = re.compile(r'^\s*""".*?"""', flags=re.MULTILINE | re.DOTALL) +SETUP_LINE = re.compile(r'^def setup[^:]*:') MODULE_MODE_METHOD_LINE = re.compile(r'^\s*py5\.(\w+)\([^\)]*\)') IMPORTED_MODE_METHOD_LINE = re.compile(r'^\s*(\w+)\([^\)]*\)') GLOBAL_STATEMENT_LINE = re.compile( @@ -66,7 +67,7 @@ def find_cutoffs(code, mode, static_mode=False): for i, line in enumerate(code.split('\n')): if not line.strip(): continue - if not static_mode and line == 'def setup():': + if not static_mode and SETUP_LINE.match(line): def_statement = True continue diff --git a/py5_tools/utilities.py b/py5_tools/utilities.py index 45ccb90..e18024d 100644 --- a/py5_tools/utilities.py +++ b/py5_tools/utilities.py @@ -59,21 +59,21 @@ class Py5Utilities { py5 py5-processing4 - 0.8.1a1 + 0.8.2a1 system ${{jarlocation}}/core.jar py5 py5-jogl - 0.8.1a1 + 0.8.2a1 system ${{jarlocation}}/jogl-all.jar py5 py5 - 0.8.1a1 + 0.8.2a1 system ${{jarlocation}}/py5.jar diff --git a/setup.py b/setup.py index 96d8ca7..425bb6d 100644 --- a/setup.py +++ b/setup.py @@ -23,7 +23,7 @@ with open('README.md') as f: README = f.read() -VERSION = '0.8.1a1' +VERSION = '0.8.2a1' INSTALL_REQUIRES = [ 'autopep8>=1.5',