Source code for pyPLUTO.utils.pytools
"""PyPLUTO general tools."""
from __future__ import annotations
import importlib.util
import inspect
import os
import warnings
from pathlib import Path
import matplotlib.pyplot as plt
windows = bool(importlib.util.find_spec("winsound"))
def find_example(name: str) -> Path:
"""Resolve the path to a test problem.
The file location is based on the *calling script's*
location, or fall back to $PLUTO_DIR.
"""
# Get the path of the calling file
caller_file = Path(inspect.stack()[1].filename).resolve()
base_dir = caller_file.parent
# Check if the test problem exists in the PyPLUTO Example directory
local_path = base_dir / "Test_Problems" / name
if local_path.exists():
return local_path
# Check if the test problem exists in the PLUTO directory
if env_path := os.environ.get("PLUTO_DIR"):
fallback = Path(env_path) / "Test_Problems" / name
if fallback.exists():
return fallback
# If the test problem is not found, raise an error
raise FileNotFoundError(
f"Test problem '{name}' not found near {base_dir} or in $PLUTO_DIR.",
)
def savefig(**_kwargs: object) -> None:
"""Save the figure created.
This function is deprecated and will be removed in future versions.
Please call savefig from the Image class instead.
"""
raise NotImplementedError(
"pyPLUTO.savefig is deprecated.\n"
"Please call savefig from the Image class instead",
)
[docs]
def show(block: bool = True) -> None:
"""Show the figures created.
Parameters
----------
- block: bool, default True
If True, the function blocks until the figure is closed.
Returns
-------
- None
Examples
--------
- Example #1: Shows the image created
>>> pp.show()
"""
plt.show(block=block)
def ring(length: float = 0.5, freq: int = 440) -> None:
"""Make a sound for a given length and frequency.
It works on Linux, macOS and Windows.
Parameters
----------
- length: float, default 0.5
The length of the sound in seconds.
- freq: int, default 440
The frequency of the sound in Hz.
Returns
-------
- None
Examples
--------
- Example #1: Make a sound with a frequency of 440 Hz and a length
of 0.5 seconds
>>> ring()
- Example #2: Make a sound with a frequency of 880 Hz and a length
of 1 second
>>> ring(freq=880)
- Example #3: Make a sound with a frequency of 220 Hz and a length
of 0.2 seconds
>>> ring(length=0.2, freq=220)
"""
# Check the OS
if windows is not None:
try:
# Check if the 'winsound' package is available on Windows
winsound = importlib.import_module("winsound")
if hasattr(winsound, "Beep"):
winsound.Beep(freq, int(length * 1000))
except UserWarning:
# If the 'winsound' package is not available, raise a warning
text = (
"pyPLUTO.ring requires the 'winsound' package.\n"
"Please install it through the command"
"\n\npip install winsound\n\nand try again."
)
warnings.warn(text, UserWarning, stacklevel=2)
elif os.name == "posix":
# Check if the 'play' command is available on Linux and macOS
try:
os.system(f"play -nq -t alsa synth {length} sine {freq}")
except UserWarning:
# If the 'play' command is not available, raise a warning
text = (
"pyPLUTO.ring requires the 'play' command from the"
"'sox' package. \nPlease install it through the command"
"\n\nsudo apt install sox \n\nand try again."
)
warnings.warn(text, UserWarning, stacklevel=2)
else:
# If the OS is not Linux, macOS or Windows, raise a warning
text = f"pyPLUTO.ring is not implemented for this OS: {os.name}"
warnings.warn(text, UserWarning, stacklevel=2)