adafruit / circuitpython

CircuitPython - a Python implementation for teaching coding with microcontrollers
https://circuitpython.org
Other
4.04k stars 1.19k forks source link

File Copy Error and Corruption in CircuitPython Device (multisparkline.py, polygon.py, rect.py, roundrect.py, sparkline.py, triangle.py) #9503

Open Axlfc opened 1 month ago

Axlfc commented 1 month ago

Similar issue here.

Description:

When attempting to copy the files multisparkline.py, polygon.py, rect.py, roundrect.py, sparkline.py, triangle.py into my CircuitPython device (drive E: named CIRCUITPY), the file becomes corrupted with strange characters, and the following error message appears:

No puede copiar el archivo debido a un error inesperado. Si sigue recibiendo este error, puede usar el código de error para buscar ayuda para este problema.

Error 0x800701 B1: Se ha especificado un dispositivo que no existe.

Steps to Reproduce:

  1. Connect the CircuitPython device to the computer.
  2. Copy the files multisparkline.py, polygon.py, rect.py, roundrect.py, sparkline.py, triangle.py from the source directory to the CIRCUITPY drive at directory E:\lib\adafruit_display_shapes.
  3. Observe the error message during the copy process.
  4. After copying, open any of the folloring files multisparkline.py, polygon.py, rect.py, roundrect.py, sparkline.py, triangle.py on the CIRCUITPY drive.

Actual Behavior:

Additional Information:

Content on the resultant files: multisparkline.py:

# SPDX-FileCopyrightText: 2020 Kevin Matocha
#
# SPDX-License-Identifier: MIT

"""
`multisparkline`
================================================================================

Various common shapes for use with displayio - Multiple Sparklines on one chart!

* Author(s): Kevin Matocha, Maciej Sokolowski

Implementation Notes
--------------------

**Software and Dependencies:**

* Adafruit CircuitPython firmware for the supported boards:
  https://github.com/adafruit/circuitpython/releases

"""

try:
    from typing import Optional, List, TypeVar

    T = TypeVar("T")
except ImportError:
    pass
import displayio
from adafruit_display_shapes.polygon import Polygon

class _CyclicBuffer:
    def __init__(self, size: int, init_value: T) -> None:
        self._buffer = [init_value] * size
        self._start = 0  # between 0 and size-1
        self._end = 0  # between 0 and 2*size-1

    def push(self, value: T) -> None:
        """Pushes value at the end of the buffer.

        :param T value: value to be pushed

        """

        if self.len() == len(self._buffer):
            raise RuntimeError("Trying to push to full buffer")
        self._buffer[self._end % len(self._buffer)] = value
        self._end += 1

    def pop(self) -> T:
        """Pop value from the start of the buffer and returns it."""

        if self.len() == 0:
            raise RuntimeError("Trying to pop from empty buffer")
        result = self._buffer[self._start]
        self._start += 1
        if self._start == len(self._buffer):
            self._start -= len(self._buffer)
            self._end -= len(self._buffer)
        return result

    def len(self) -> int:
        """Returns count of valid data in the buffer."""

        return self._end - self._start

    def clear(self) -> None:
        """Marks all data as invalid."""

        self._start = 0
        self._end = 0

    def values(self) -> List[T]:
        """Returns valid data from the buffer."""

        if self.len() == 0:
            return []
        start = self._start
        end = self._end % len(self._buffer)
        if start < end:
            return self._buffer[start:end]
        return self._buffer[start:] + self._buffer[:end]

class MultiSparkline(displayio.TileGrid):
    """A multiple sparkline graph.

    :param int width: Width of the multisparkline graph in pixels
    :param int height: Height of the multisparkline graph in pixels
    :param int max_items: Maximum number of values housed in each sparkline
    :param bool dyn_xpitch: (Optional) Dynamically change xpitch (True)
    :param list y_mins: Lower range for the y-axis per line.
                        Set each to None for autorange of respective line.
                        Set to None for autorange of all lines.
    :param list y_maxs: Upper range for the y-axis per line.
                        Set each to None for autorange of respective line.
                        Set to None for autorange of all lines.
    :param int x: X-position on the screen, in pixels
    :param int y: Y-position on the screen, in pixels
    :param list colors: Each line color. Number of items in this list determines maximum
                       number of sparklines

    Note: If dyn_xpitch is True (default), each sparkline will allways span
    the complete width. Otherwise, each sparkline will grow when you
    add values. Once the line has reached the full width, each sparkline
    will scroll to the left.
    """

    # pylint: disable=too-many-arguments, too-many-instance-attributes
    def __init__(
        self,
é?À{7@î           ÿÿ      <ˆ  2TÍ«            9.1.0-beta.3                    circuitpython                   20:28:06        May 22 2024     da9dc379                        ¶T¦1˜„5l"‹~©NSÌq$~G8ŸY›™0D‡                                                                                __dir__ *   <module>    __call__    __class__   __delitem__ __enter__   __exit__    __getattr__ __getitem__ __hash__    __init__    __int__ __iter__    __len__ __main__    __module__  __name__    __new__ __next__    __qualname__    __repr__    __setitem__ __str__ ArithmeticError AssertionError  AttributeError  BaseException   EOFError    Ellipsis    GeneratorExit   ImportError IndentationError    IndexError  KeyError    KeyboardInterrupt   LookupError MemoryError NameError   NoneType    NotImplementedError OSError OverflowError   RuntimeError    StopIteration   SyntaxError SystemExit  TypeError   ValueError  ZeroDivisionError   abs any append  args    bool    builtins    bytearray   bytecode    callable    chr classmethod clear   close   const   copy    dict    divmod  endswith    eval    exec    extend  find    format  from_bytes  get getattr globals hasattr hash    id  insert  isalpha isdigit isinstance  islower isspace issubclass  isupper join    key len little  locals  lower   lstrip  main    micropython next    object  open    ord pop popitem pow print   read    readinto    readline    remove  replace repr    reverse rfind   rindex  round   rsplit  rstrip  self    send    sep set setattr setdefault  sort    sorted  split   startswith  staticmethod    step    stop    str strip   sum super   throw   to_bytes    tuple   update  upper   utf-8   values  write   zip __abs__ __add__ __and__ __bool__    __complex__ __contains__    __delete__  __divmod__  __eq__  __float__   __floordiv__    __ge__  __get__ __gt__  __iadd__    __invert__  __isub__    __le__  __lshift__  __lt__  __matmul__  __mod__ __mul__ __ne__  __neg__ __or__  __pos__ __pow__ __radd__    __rand__    __rfloordiv__   __rlshift__ __rmatmul__ __rmod__    __rmul__    __ror__ __rpow__    __rrshift__ __rshift__  __rsub__    __rtruediv__    __rxor__    __set__ __sub__ __truediv__ __xor__ %#o %#x {:#b}   <lambda>    <listcomp>  <dictcomp>  <setcomp>   <genexpr>   <string>    <stdin> /lib    <input> ABS ADD_DIV ADD_SUB AES AF_INET AF_INET6    ATTACK  AUTO_RELOAD Adapter AddressRange    AnalogIn    AnalogOut   Architecture    Atkinson    Attribute   AuthMode    BGR BGR555  BGR555_SWAPPED  BGR565  BGR565_SWAPPED  BOOT0   BOOTLOADER  BROADCAST   BROWNOUT    BUS_OFF BUTTON  Biquad  Bitmap  BlendMode   BlockInput  BluetoothError  BrokenPipeError BufferedIn  BuiltinFont BusDisplay  BusState    ByteArray   BytesIO CAN CH  CIRCUITPYTHON_TERMINAL  CONSTRAINED_LERP    CONSUMER_CONTROL    CancelledError  ChannelMixer    ChannelMixerOffset  ChannelScale    ChannelScaleOffset  Characteristic  CharacteristicBuffer    Circle  ColorConverter  ColorSpace  Colorspace  Connection  ConnectionError Counter D1  D2  DECAY   DEEP_SLEEP_ALARM    DISPLAY DIV_ADD DOWN    DeepSleepRequest    DemuxKeyMatrix  Descriptor  Device  DigitalInOut    Direction   Display DitherAlgorithm DriveMode   EACCES  EADDRINUSE  EAGAIN  EAI_NONAME  EALREADY    EBADF   ECONNABORTED    ECONNREFUSED    ECONNRESET  EEXIST  EHOSTUNREACH    EINPROGRESS EINVAL  EIO EISDIR  ENCRYPT_NO_MITM ENCRYPT_WITH_MITM   ENOBUFS ENODEV  ENOENT  ENOMEM  ENOTCONN    ENTERPRISE  EOPNOTSUPP  EPERM   EPaperDisplay   ERROR_ACTIVE    ERROR_PASSIVE   ERROR_WARNING   ESPNow  ESPNowPacket    ETIMEDOUT   EVEN    Edge    Envelope    EnvelopeState   Event   EventQueue  ExtType FALL    FLASH_WRITE_FAIL    FONT    FSM FileIO  Flash   FloydStenberg   FourWire    FramebufferDisplay  FrequencyIn FutureWarning   GC_ALLOC_OUTSIDE_VM GPIO0   GPIO1   GPIO10  GPIO11  GPIO12  GPIO13  GPIO14  GPIO15  GPIO16  GPIO17  GPIO18  GPIO19  GPIO2   GPIO20  GPIO21  GPIO26  GPIO27  GPIO28  GPIO29  GPIO3   GPIO30  GPIO31  GPIO32  GPIO33  GPIO34  GPIO35  GPIO36  GPIO37  GPIO38  GPIO39  GPIO4   GPIO40  GPIO41  GPIO42  GPIO43  GPIO44  GPIO45  GPIO46  GPIO47  GPIO48  GPIO5   GPIO6   GPIO7   GPIO8   GPIO9   GifWriter   Glyph   Group   HARD_FAULT  Hash    I2C I2CDevice   I2CDisplay  I2CDisplayBus   I2SOut  I2S_BIT_CLOCK   I2S_DATA    I2S_WORD_SELECT IDFError    INDICATE    INTERRUPT_ERROR IOBase  IPPROTO_ICMP    IPPROTO_IP  IPPROTO_IPV6    IPPROTO_RAW IPPROTO_TCP IPPROTO_UDP IP_MULTICAST_TTL    IPv4Address IR_TX   IncrementalEncoder  JpegDecoder KB_A_0  KB_A_1  KB_A_2  KB_COL_0    KB_COL_1    KB_COL_2    KB_COL_3    KB_COL_4    KB_COL_5    KB_COL_6    KEYBOARD    KeyMatrix   Keys    L8  LEN LESC_ENCRYPT_WITH_MITM  LFO Listener    MAX MIC_CLK MIC_DATA    MID MIN MISO    MODE_CBC    MODE_CTR    MODE_ECB    MOUSE   MP3Decoder  MUL_DIV Match   Math    MathOperation   Max3421E    Message MidiTrack   Mixer   MixerVoice  Monitor NEOPIXEL    NLR_JUMP_FAIL   NONE    NORMAL  NOTIFY  NO_ACCESS   NO_CIRCUITPY    NO_HEAP Network None    Normal  Note    ODD OFFSET_SCALE    OPEN    OPEN_DRAIN  OUTPUT  OnDiskBitmap    OnDiskGif   OneWire OrderedDict PDMIn   POLLERR POLLHUP POLLIN  POLLOUT PORTA1  PORTA2  PORTA_I2C   POWER_ON    PRODUCT PROGRAMMATIC    PSK PUBLIC  PUSH_PULL   PWMOut  Packet  PacketBuffer    Palette ParallelBus Parity  Peer    Peers   Pin PinAlarm    PixelBuf    PixelMap    Polygon PortIn  PortOut Processor   Ps2 buffer  Ps2 Pull    PulseIn PulseOut    Q   RAISE   RANDOM_PRIVATE_NON_RESOLVABLE   RANDOM_PRIVATE_RESOLVABLE   RANDOM_STATIC   READ    RELEASE REPL_RELOAD RESCUE_DEBUG    RESET_PIN   RGB555  RGB555_SWAPPED  RGB565  RGB565_SWAPPED  RGB888  RGBMatrix   RISCV   RISE    RISE_AND_FALL   RSSI    RTC RX  Radio   RawSample   ReadableBuffer  Rectangle   ReloadException RemoteService   RemoteTransmissionRequest   ResetRea

polygon.py:

# SPDX-FileCopyrightText: 2019 Limor Fried for Adafruit Industries
#
# SPDX-License-Identifier: MIT

"""
`polygon`
================================================================================

Various common shapes for use with displayio - Polygon shape!

* Author(s): Melissa LeBlanc-Williams

Implementation Notes
--------------------

**Software and Dependencies:**

* Adafruit CircuitPython firmware for the supported boards:
  https://github.com/adafruit/circuitpython/releases

"""

try:
    from typing import Optional, List, Tuple
except ImportError:
    pass

import displayio

__version__ = "0.0.0+auto.0"
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_Display_Shapes.git"

class Polygon(displayio.TileGrid):
    """A polygon.

    :param list points: A list of (x, y) tuples of the points
    :param int|None outline: The outline of the polygon. Can be a hex value for a color or
                    ``None`` for no outline.
    :param bool close: (Optional) Wether to connect first and last point. (True)
    :param int colors: (Optional) Number of colors to use. Most polygons would use two, one for
                    outline and one for fill. If you're not filling your polygon, set this to 1
                    for smaller memory footprint. (2)
    """

    _OUTLINE = 1
    _FILL = 2

    def __init__(
        self,
        points: List[Tuple[int, int]],
        *,
        outline: Optional[int] = None,
        close: Optional[bool] = True,
        colors: Optional[int] = 2,
    ) -> None:
        (x_s, y_s) = zip(*points)

        x_offset = min(x_s)
        y_offset = min(y_s)

        # Find the largest and smallest X values to figure out width for bitmap
        width = max(x_s) - min(x_s) + 1
        height = max(y_s) - min(y_s) + 1

        self._palette = displayio.Palette(colors + 1)
        self._palette.make_transparent(0)
        self._bitmap = displayio.Bitmap(width, height, colors + 1)

        shifted = [(x - x_offset, y - y_offset) for (x, y) in points]

        if outline is not None:
            self.outline = outline
            self.draw(self._bitmap, shifted, self._OUTLINE, close)

        super().__init__(
            self._bitmap, pixel_shader=self._palette, x=x_offset, y=y_offset
        )

    @staticmethod
    def draw(
        bitmap: displayio.Bitmap,
        points: List[Tuple[int, int]],
        color_id: int,
        close: Optional[bool] = True,
    ) -> None:
        """Draw a polygon conecting points on provided bitmap with provided color_id

        :param displayio.Bitmap bitmap: bitmap to draw on
        :param list points: A list of (x, y) tuples of the points
        :param int color_id: Color to draw with
        :param bool close: (Optional) Wether to connect first and last point. (True)
        """

        if close:
            points.append(points[0])

        for index in range(len(points) - 1):
            Polygon._line_on(bitmap, points[index], points[index + 1], color_id)

    # pylint: disable=too-many-arguments
    def _line(
        self,
        x_0: int,
        y_0: int,
        x_1: int,
        y_1: int,
        color: int,
    ) -> None:
        self._line_on(self._bitmap, (x_0, y_0), (x_1, y_1), color)

    # pylint: enable=too-many-arguments

    @staticmethod
    def _safe_draw(
        bitmap: displayio.Bitmap,
        point: Tuple[int, int],
        color: int,
    ) -> None:
        (x, y) = point
        if 0 <= x < bitmap.width and 0 <= y < bitmap.height:
            bitmap[x, y] = color

    # pylint: disable=too-many-branches, too-mané?À{7@î           ÿÿ      <ˆ  2TÍ«            9.1.0-beta.3                    circuitpython                   20:28:06        May 22 2024     da9dc379                        ¶T¦1˜„5l"‹~©NSÌq$~G8ŸY›™0D‡                                                                                __dir__ *   <module>    __call__    __class__   __delitem__ __enter__   __exit__    __getattr__ __getitem__ __hash__    __init__    __int__ __iter__    __len__ __main__    __module__  __name__    __new__ __next__    __qualname__    __repr__    __setitem__ __str__ ArithmeticError AssertionError  AttributeError  BaseException   EOFError    Ellipsis    GeneratorExit   ImportError IndentationError    IndexError  KeyError    KeyboardInterrupt   LookupError MemoryError NameError   NoneType    NotImplementedError OSError OverflowError   RuntimeError    StopIteration   SyntaxError SystemExit  TypeError   ValueError  ZeroDivisionError   abs any append  args    bool    builtins    bytearray   bytecode    callable    chr classmethod clear   close   const   copy    dict    divmod  endswith    eval    exec    extend  find    format  from_bytes  get getattr globals hasattr hash    id  insert  isalpha isdigit isinstance  islower isspace issubclass  isupper join    key len little  locals  lower   lstrip  main    micropython next    object  open    ord pop popitem pow print   read    readinto    readline    remove  replace repr    reverse rfind   rindex  round   rsplit  rstrip  self    send    sep set setattr setdefault  sort    sorted  split   startswith  staticmethod    step    stop    str strip   sum super   throw   to_bytes    tuple   update  upper   utf-8   values  write   zip __abs__ __add__ __and__ __bool__    __complex__ __contains__    __delete__  __divmod__  __eq__  __float__   __floordiv__    __ge__  __get__ __gt__  __iadd__    __invert__  __isub__    __le__  __lshift__  __lt__  __matmul__  __mod__ __mul__ __ne__  __neg__ _

rect.py:

# SPDX-FileCopyrightText: 2019 Limor Fried for Adafruit Industries
#
# SPDX-License-Identifier: MIT

"""
`rect`
================================================================================

Various common shapes for use with displayio - Rectangle shape!

* Author(s): Limor Fried

Implementation Notes
--------------------

**Software and Dependencies:**

* Adafruit CircuitPython firmware for the supported boards:
  https://github.com/adafruit/circuitpython/releases

"""

try:
    from typing import Optional
except ImportError:
    pass

import displayio

__version__ = "0.0.0+auto.0"
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_Display_Shapes.git"

class Rect(displayio.TileGrid):
    """A rectangle.

    :param int x: The x-position of the top left corner.
    :param int y: The y-position of the top left corner.
    :param int width: The width of the rectangle.
    :param int height: The height of the rectangle.
    :param int|None fill: The color to fill the rectangle. Can be a hex value for a color or
                    ``None`` for transparent.
    :param int|None outline: The outline of the rectangle. Can be a hex value for a color or
                    ``None`` for no outline.
    :param int stroke: Used for the outline. Will not change the outer bound size set by ``width``
                    and ``height``.

    """

    def __init__(
        self,
        x: int,
        y: int,
        width: int,
        height: int,
        *,
        fill: Optional[int] = None,
        outline: Optional[int] = None,
        stroke: int = 1,
    ) -> None:
        if width <= 0 or height <= 0:
            raise ValueError("Rectangle dimensions must be larger than 0.")

        self._bitmap = displayio.Bitmap(width, height, 2)
        self._palette = displayio.Palette(2)

        if outline is not None:
            self._palette[1] = outline
            for w in range(width):
                for line in range(stroke):
                    self._bitmap[w, line] = 1
                    self._bitmap[w, height - 1 - line] = 1
            for _h in range(height):
                for line in range(stroke):
                    self._bitmap[line, _h] = 1
                    self._bitmap[width - 1 - line, _h] = 1

        if fill is not None:
            self._palette[0] = fill
            self._palette.make_opaque(0)
        else:
            self._palette[0] = 0
            self._palette.make_transparent(0)
        super().__init__(self._bitmap, pixel_shader=self._palette, x=x, y=y)

    @property
    def fill(self) -> Optional[int]:
        """The fill of the rectangle. Can be a hex value for a color or ``None`` for
        transparent."""
        return self._palette[0]

    @fill.setter
    def fill(self, color: Optional[int]) -> None:
        if color is None:
            self._palette[0] = 0
            self._palette.make_transparent(0)
        else:
            self._palette[0] = color
            self._palette.make_opaque(0)

    @property
    def outline(self) -> Optional[int]:
        """The outline of the rectangle. Can be a hex value for a color or ``None``
        for no outline."""
        return self._palette[1]

    @outline.setter
    def outline(self, color: Optional[int]) -> None:
        if color is None:
            self._palette[1] = 0
            self._palette.make_transparent(1)
        else:
            self._palette[1] = color
            self._palette.make_opaque(1)

    @property
    def width(self) -> int:
        """
        :return: the width of the rectangle in pixels
        """é?À{7@î        ÿÿ      <ˆ  2TÍ«            9.1.0-beta.3                    circuitpython                   20:28:06        May 22 2024     da9dc379                        ¶T¦1˜„5l"‹~©N

roundrect.py:

# SPDX-FileCopyrightText: 2019 Limor Fried for Adafruit Industries
#
# SPDX-License-Identifier: MIT

"""
`roundrect`
================================================================================

A slightly modified version of Adafruit_CircuitPython_Display_Shapes that includes
an explicit call to palette.make_opaque() in the fill color setter function.

"""

try:
    from typing import Optional
except ImportError:
    pass

import displayio

__version__ = "0.0.0+auto.0"
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_Display_Shapes.git"

class RoundRect(displayio.TileGrid):
    # pylint: disable=too-many-arguments
    """A round-corner rectangle.

    :param int x: The x-position of the top left corner.
    :param int y: The y-position of the top left corner.
    :param int width: The width of the rounded-corner rectangle.
    :param int height: The height of the rounded-corner rectangle.
    :param int r: The radius of the rounded corner.
    :param int|None fill: The color to fill the rounded-corner rectangle. Can be a hex value
                    for a color or ``None`` for transparent.
    :param int|None outline: The outline of the rounded-corner rectangle. Can be a hex value
                    for a color or ``None`` for no outline.
    :param int stroke: Used for the outline. Will not change the outer bound size set by ``width``
                    and ``height``.

    """

    def __init__(
        self,
        x: int,
        y: int,
        width: int,
        height: int,
        r: int,
        *,
        fill: Optional[int] = None,
        outline: Optional[int] = None,
        stroke: int = 1,
    ) -> None:
        if width <= 0 or height <= 0:
            raise ValueError("Rectangle dimensions must be larger than 0.")
        if r > width / 2 or r > height / 2:
            raise ValueError(
                "Radius cannot exceed half of the smaller side (width or height)."
            )

        self._palette = displayio.Palette(3)
        self._palette.make_transparent(0)
        self._bitmap = displayio.Bitmap(width, height, 3)
        for i in range(0, width):  # draw the center chunk
            for j in range(r, height - r):  # draw the center chunk
                self._bitmap[i, j] = 2
        self._helper(
            r,
            r,
            r,
            color=2,
            fill=True,
            x_offset=width - 2 * r - 1,
            y_offset=height - 2 * r - 1,
        )

        if fill is not None:
            self._palette[2] = fill
            self._palette.make_opaque(2)
        else:
            self._palette.make_transparent(2)
            self._palette[2] = 0

        if outline is not None:
            self._palette[1] = outline
            # draw flat sides
            for w in range(r, width - r):
                for line in range(stroke):
                    self._bitmap[w, line] = 1
                    self._bitmap[w, height - line - 1] = 1
            for _h in range(r, height - r):
                for line in range(stroke):
                    self._bitmap[line, _h] = 1
                    self._bitmap[width - line - 1, _h] = 1
            # draw round corners
            self._helper(
                r,
                r,
                r,
                color=1,
                stroke=stroke,
                x_offset=width - 2 * r - 1,
                y_offset=height - 2 * r - 1,
            )
        super().__init__(self._bitmap, pixel_shader=self._palette, x=x, y=y)

    # pylint: disable=invalid-name, too-many-locals, too-many-branches
   é?À{7@î        ÿÿ      <ˆ  2TÍ«            9.1.0-beta.3                    circuitpython                   20:28:06        May 22 2024     da9dc379                        ¶T¦1˜„5l"‹~©NSÌq$~G8ŸY›™0D‡                                                                                __dir__ *   <module>    __call__    __class__   __delitem__ __enter__   __exit__    __getattr__ __getitem__ __hash__    __init__    __int__ __iter__    __len__ __main__    __module__  __name__    __new__ __next__    __qualname__    __repr__    __setitem__ __str__ ArithmeticError AssertionError  AttributeError  BaseException   EOFError    Ellipsis    GeneratorExit   ImportError IndentationError    IndexError  KeyError    KeyboardInterrupt   LookupError MemoryError NameError   NoneType    NotImplementedError OSError OverflowError   RuntimeError    StopIteration   SyntaxError SystemExit  TypeError   ValueError  ZeroDivisionError   abs any append  args    bool    builtins    bytearray   bytecode    callable    chr classmethod clear   close   const   copy    dict    divmod  endswith    eval    exec    extend  find    format  from_bytes  get getattr globals hasattr hash    id  insert  isalpha isdigit isinstance  islower isspace issubclass  isupper join    key len little  locals  lower   lstrip  main    micropython next    object  open    ord pop popitem pow print   read    readinto    readline    remove  replace repr    reverse rfind   rindex  round   rsplit  rstrip  self    send    sep set setattr setdefault  sort    sorted  split   startswith  staticmethod    step    stop    str strip   sum super   throw   to_bytes    tuple   update  upper   utf-8   values  write   zip __abs__ __add__ __and__ __bool__    __complex__ __contains__    __delete__  __divmod__  __eq__  __float__   __floordiv__    __ge__  __get__ __gt__  __iadd__    __invert__  __isub__    __le__  __lshift__  __lt__  __matmul__  __mod__ __mul__ __ne__  __neg__ __or__  __pos__ __pow__ __radd__    __rand__    __rfloordiv__   __rlshift__ __rmatmul__ __rmod__    __rmul__    __ror__ __rpow__    __rrshift__ __rshift__  __rsub__    __rtruediv__    __rxor__    __set__ __sub__ __truediv__ __xor__ %#o %#x {:#b}   <lambda>    <listcomp>  <dictcomp>  <setcomp>   <genexpr>   <string>    <stdin> /lib    <input> ABS ADD_DIV ADD_SUB AES AF_INET AF_INET6    ATTACK  AUTO_RELOAD Adapter AddressRange    AnalogIn    AnalogOut   Architecture    Atkinson    Attribute   AuthMode    BGR BGR555  BGR555_SWAPPED  BGR565  BGR565_SWAPPED  BOOT0   BOOTLOADER  BROADCAST   BROWNOUT    BUS_OFF BUTTON  Biquad  Bitmap  BlendMode   BlockInput  BluetoothError  BrokenPipeError BufferedIn  BuiltinFont BusDisplay  BusState    ByteArray   BytesIO CAN CH  CIRCUITPYTHON_TERMINAL  CONSTRAINED_LERP    CONSUMER_CONTROL    CancelledError  ChannelMixer    ChannelMixerOffset  ChannelScale    ChannelScaleOffset  Characteristic  CharacteristicBuffer    Circle  ColorConverter  ColorSpace  Colorspace  Connection  ConnectionError Counter D1  D2  DECAY   DEEP_SLEEP_ALARM    DISPLAY DIV_ADD DOWN    DeepSleepRequest    DemuxKeyMatrix  Descriptor  Device  DigitalInOut    Direction   Display DitherAlgorithm DriveMode   EACCES  EADDRINUSE  EAGAIN  EAI_NONAME  EALREADY    EBADF   ECONNABORTED    ECONNREFUSED    ECONNRESET  EEXIST  EHOSTUNREACH    EINPROGRESS EINVAL  EIO EISDIR  ENCRYPT_NO_MITM ENCRYPT_WITH_MITM   ENOBUFS ENODEV  ENOENT  ENOMEM  ENOTCONN    ENTERPRISE  EOPNOTSUPP  EPE

sparkline.py:

# SPDX-FileCopyrightText: 2020 Kevin Matocha
#
# SPDX-License-Identifier: MIT

# class of sparklines in CircuitPython

# See the bottom for a code example using the `sparkline` Class.

# # File: display_shapes_sparkline.py
# A sparkline is a scrolling line graph, where any values added to sparkline using `
# add_value` are plotted.
#
# The `sparkline` class creates an element suitable for adding to the display using
# `display.root_group = mySparkline`
# or adding to a `displayio.Group` to be displayed.
#
# When creating the sparkline, identify the number of `max_items` that will be
# included in the graph. When additional elements are added to the sparkline and
# the number of items has exceeded max_items, any excess values are removed from
# the left of the graph, and new values are added to the right.
"""
`sparkline`
================================================================================

Various common shapes for use with displayio - Sparkline!

* Author(s): Kevin Matocha

Implementation Notes
--------------------

**Software and Dependencies:**

* Adafruit CircuitPython firmware for the supported boards:
  https://github.com/adafruit/circuitpython/releases

"""

try:
    from typing import Optional, List
except ImportError:
    pass
from adafruit_display_shapes.multisparkline import MultiSparkline

class Sparkline(MultiSparkline):
    """A sparkline graph.

    :param int width: Width of the sparkline graph in pixels
    :param int height: Height of the sparkline graph in pixels
    :param int max_items: Maximum number of values housed in the sparkline
    :param bool dyn_xpitch: (Optional) Dynamically change xpitch (True)
    :param int|None y_min: Lower range for the y-axis.  Set to None for autorange.
    :param int|None y_max: Upper range for the y-axis.  Set to None for autorange.
    :param int x: X-position on the screen, in pixels
    :param int y: Y-position on the screen, in pixels
    :param int color: Line color, the default value is 0xFFFFFF (WHITE)

    Note: If dyn_xpitch is True (default), the sparkline will allways span
    the complete width. Otherwise, the sparkline will grow when you
    add values. Once the line has reached the full width, the sparkline
    will scroll to the left.
    """

    # pylint: disable=too-many-arguments
    def __init__(
        self,
        width: int,
        height: int,
        max_items: int,
        dyn_xpitch: Optional[bool] = True,  # True = dynamic pitch size
        y_min: Optional[int] = None,  # None = autoscaling
        y_max: Optional[int] = None,  # None = autoscaling
        x: int = 0,
        y: int = 0,
        color: int = 0xFFFFFF,  # line color, default is WHITE
    ) -> None:
        super().__init__(
            width, height, max_items, [color], dyn_xpitch, [y_min], [y_max], x, y
        )

    # pylint: enable=too-many-arguments

    def add_value(self, value: float, update: bool = True) -> None:
        """Add a value to the sparkline.

        :param float value: The value to be added to the sparkline
        :param bool update: trigger recreation of primitives

        Note: when adding multiple values it is more efficient to call
        this method with parameter 'update=False' and then to manually
        call the update()-method
        """

        self.add_values([value], update)

    def update(self) -> None:
        """Update the drawing of the sparkline."""

        self.update_line(0)

    def values(self) -> List[float]:
        """Returns the values displayed on the sparkline."""

        return self.values_of(0)é?À{7@î           ÿÿ      <ˆ  2TÍ«            9.1.0-beta.3                    circuitpython                   20:28:06        May 22 2024     da9dc379                        ¶T¦1˜„5l"‹~©NSÌq$~G8ŸY›™0D‡                                                                                __dir__ *   <module>    __call__    __class__   __delitem__ __enter__   __exit__    __getattr__ __getitem

triangle.py:

# SPDX-FileCopyrightText: 2019 Limor Fried for Adafruit Industries
#
# SPDX-License-Identifier: MIT

"""
`triangle`
================================================================================

Various common shapes for use with displayio - Triangle shape!

* Author(s): Melissa LeBlanc-Williams

Implementation Notes
--------------------

**Software and Dependencies:**

* Adafruit CircuitPython firmware for the supported boards:
  https://github.com/adafruit/circuitpython/releases

"""

try:
    from typing import Optional
except ImportError:
    pass

from adafruit_display_shapes.polygon import Polygon

__version__ = "0.0.0+auto.0"
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_Display_Shapes.git"

class Triangle(Polygon):
    # pylint: disable=too-many-arguments,invalid-name
    """A triangle.

    :param int x0: The x-position of the first vertex.
    :param int y0: The y-position of the first vertex.
    :param int x1: The x-position of the second vertex.
    :param int y1: The y-position of the second vertex.
    :param int x2: The x-position of the third vertex.
    :param int y2: The y-position of the third vertex.
    :param int|None fill: The color to fill the triangle. Can be a hex value for a color or
                    ``None`` for transparent.
    :param int|None outline: The outline of the triangle. Can be a hex value for a color or
                    ``None`` for no outline.
    """

    # pylint: disable=too-many-locals
    def __init__(
        self,
        x0: int,
        y0: int,
        x1: int,
        y1: int,
        x2: int,
        y2: int,
        *,
        fill: Optional[int] = None,
        outline: Optional[int] = None,
    ) -> None:
        # Sort coordinates by Y order (y2 >= y1 >= y0)
        if y0 > y1:
            y0, y1 = y1, y0
            x0, x1 = x1, x0

        if y1 > y2:
            y1, y2 = y2, y1
            x1, x2 = x2, x1

        if y0 > y1:
            y0, y1 = y1, y0
            x0, x1 = x1, x0

        # Find the largest and smallest X values to figure out width for bitmap
        xs = [x0, x1, x2]
        points = [(x0, y0), (x1, y1), (x2, y2)]

        # Initialize the bitmap and palette
        super().__init__(points)

        if fill is not None:
            self._draw_filled(
                x0 - min(xs), 0, x1 - min(xs), y1 - y0, x2 - min(xs), y2 - y0
            )
            self.fill = fill
        else:
            self.fill = None

        if outline is not None:
            self.outline = outline
            for index, _ in enumerate(points):
                point_a = points[index]
                if index == len(points) - 1:
                    point_b = points[0]
                else:
                    point_b = points[index + 1]
                self._line(
                    point_a[0] - min(xs),
                    point_a[1] - y0,
                    point_b[0] - min(xs),
                    point_b[1] - y0,
                    self._OUTLINE,
                )

    # pylint: disable=invalid-name, too-many-branches
    def _draw_filled(
        self,
        x0: int,
        y0: int,
        x1: int,
        y1: int,
        x2: int,
        y2: int,
    ) -> None:
        if y0 == y2:  # Handle awkward all-on-same-line case as its own thing
            a = x0
            b = x0
            if x1 < a:
                a = x1
            elif x1 > b:
                b = x1

            if x2 < a:
                a = x2
            elif x2 > b:
                b = x2
            self._line(a, y0, b, y0, self._FILL)
            é?À{7@î           ÿÿ      <ˆ  2TÍ«            9.1.0-beta.3                    circuitpython                   20:28:06        May 22 2024     da9dc379                        ¶T¦1˜„5l"‹~©NSÌq$~G8ŸY›™0D‡                                                                                __dir__ *   <module>    __call__    __class__   __delitem__ __enter__   __exit__    __getattr__ __getitem__ __hash__    __init__    __int__ __iter__    __len__ __main__    __module__  __name__    __new__ __next__    __qualname__    __repr__    __setitem__ __str__ ArithmeticError AssertionError  AttributeError  BaseException   EOFError    Ellipsis    GeneratorExit   ImportError IndentationError    IndexError  KeyError    KeyboardInterrupt   LookupError MemoryError NameError   NoneType    NotImplementedError OSError OverflowError   RuntimeError    StopIteration   SyntaxError SystemExit  TypeError   ValueError  ZeroDivisionError   abs any append  args    bool    builtins    bytearray   bytecode    callable    chr classmethod clear   close   const   copy    dict    divmod  endswith    eval    exec    extend  find    format  from_bytes  get getattr globals hasattr hash    id  insert  isalpha isdigit isinstance  islower isspace issubclass  isupper join    key len little  

Best regards

dhalbert commented 1 month ago

Transferred issue to https://github.com/adafruit/circuitpython, because this issue is not related to the particular files.

There are various reasons the copies might be corrupted.

  1. How are you copying the files? Drag and drop?
  2. The CIRCUITPY drive may be corrupted due to previously unplugging or resetting the device before a write was complete. Try this in the REPL serial connection. It will erase and reformat CIRCUITPY. Then copy the files agan.
    import storage
    storage.erase_filesystem()
  3. The flash chip on the Cardputer may be defective. This is quite rare.
  4. The original files may be corrupted. I'm guessing you looked for this already?
  5. There my be utility programs (antivirus or disk utility, etc.) that are interfering with the copy.
Axlfc commented 1 month ago

Hello and so many thanks for the quick response.

1. How are you copying the files? Drag and drop?

Yes, I download manually the source code and copy/paste to the board's folder, I went file by file because I noticed when copying the whole folder the behavior happens too.

2. The CIRCUITPY drive may be corrupted due to previously unplugging or resetting the device before a write was complete. Try this in the REPL serial connection. It will erase and reformat CIRCUITPY. Then copy the files agan.
import storage
storage.erase_filesystem()

I tried this line, as well as installing the circuitpython .bin file... I used the bmorcelli's M5Stick-Launcher project and downloaded the .bin file from CircuitPython M5Stack Cardputer

3. The flash chip on the Cardputer may be defective. This is quite rare.

No idea, right now I'm currently trying to do this again using another USB port from my computer. It seems that using a non blue USB port it let me copy some of the files without the error. I may have my blue USB port damaged.

4. The original files may be corrupted. I'm guessing you looked for this already?

Yes, the original files are okay.

5. There my be utility programs (antivirus or disk utility, etc.) that are interfering with the copy.

I tried to blocking antivirus and still hapening.

It seems that using another usb port from my computer that is not blue let me copy some the files successfully and without any errors... It is still happening.

Axlfc commented 1 month ago

It happened again with switch_round.py 🤐

Weird, but I tried copiying it again (I have the board connected to a different USB already, first time it happened the error, the second it let me copy the file) and it let me copy (?)

It's behaviour is like the unit unmounts/mounts again when copying the files... The partition of this CIRCUITPYTHON (E:) it's in FAT format.

Now I'm trying to delete the folder adafruit_display_shapes, it's not letting me delete the folder, and it's showing this...

imagen

The content of the folder:

imagen

😱

I managed to remove it.

Maybe I do have some problem with the board itself, or maybe is the cable I'm using...

Axlfc commented 1 month ago

This is how the unit looks when I try to copy the files: imagen

After a short time (or some times pressing Enter in the Cardputer itself) it mounts. imagen

dhalbert commented 1 month ago

Are you using a hub or a direct connection?

Please try a different cable as well.

Could you try CircuitPython 9.0.5 and see if it makes any difference?

Axlfc commented 1 month ago

Are you using a hub or a direct connection?

Direct connection to the pc.

Please try a different cable as well.

I have another cable and it still happening...

Could you try CircuitPython 9.0.5 and see if it makes any difference?

Sure I will try again, I'm resetting using the command you gave me earlier and try the whole process again and write it here in few minutes.

import storage
storage.erase_filesystem()
Axlfc commented 1 month ago

Using CircuitPython 9.0.5:

imagen

This files are copied without problems.

Now I try to copy the mentioned files.

imagen

This has given no errors so far, now I go with the folder on my next step:

imagen

ALL FILES COPIED SUCCESSFULLY USING CircuitPython 9.0.5

Axlfc commented 1 month ago

I also have been messing putting a git repository in this folder... That may have affected this in some way... after i copied a .git folder into the file system the error appeared again...

dhalbert commented 1 month ago

So 9.0.5 is not better when the .git tree is added?

If you have another computer to try that's rather different (e.g. Mac, RPi, etc.) that would be a useful experiment.

Axlfc commented 1 month ago

Sorry I do not have a Mac nor RapsberryPi, but next day I'll try I'd replicate whole file copying and file editing process in my dual boot ubuntu GNU/Linux (it's the same pc I run Windows 10) and see what happens.


It blocked again like this imagen trying to edit the code.py file...

😰

It's only happening randomly at some times... But fortunately the last changes I made it worked.

But for now it's accomplished copying the library files inside the filesystem and they are not showing corrupt.

Well I guess I won't be using .git folder in the Cardputer running CircuitPython 9.0.5 nor the beta version, I will keep running this version for now, but we accomplished to copy the libraries, very much a success. 😁

Thank you very much for your help!!