Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

'int' object has no attribute 'flatten' after incrementing value repeated times #98

Open
jmriddell opened this issue Dec 15, 2024 · 0 comments

Comments

@jmriddell
Copy link

System info

Windows 10
Python 3.12.1

Description

I'm getting this error when casting to int a value that was incremented using the += operator in a loop.

Example code

incremented = Fxp("0.0")
step = Fxp("0.5")

for i in count():
    incremented += step
    int(incremented) # Fails here

Found Behavior

Usually after 31 iterations raises this error:

Traceback (most recent call last):
  File "C:\Users\jmoli\repos\pygame-1\test.py", line 70, in <module>
    rounded_pos = (int(box_x), int(box_y))
                               ^^^^^^^^^^
  File "C:\Users\jmoli\repos\pygame-1\.venv\Lib\site-packages\fxpmath\objects.py", line 1158, in __int__
    return int(self.astype(int))
               ^^^^^^^^^^^^^^^^
  File "C:\Users\jmoli\repos\pygame-1\.venv\Lib\site-packages\fxpmath\objects.py", line 986, in astype
    val = np.array(list(map(int, val.flatten()))).reshape(val.shape)
                                 ^^^^^^^^^^^
AttributeError: 'int' object has no attribute 'flatten'

Expected behavior

Loop until it overflows

Further testing

I made this code to investigate the issue, to find if it happens only for certain values or the number of iterations change.
I te code runs the loop multiple times with different combinations of parameters.

Testing code

from fxpmath import Fxp
from itertools import count, product, groupby
import traceback
from collections import Counter


def sample_case(word_size, frac_bits, rounding, signed, value, step):
    config = {
        "n_word": word_size,
        "n_frac": frac_bits,
        "signed": signed,
        "rounding": rounding,
    }
    incremented = Fxp(value, **config)
    step = Fxp(step, **config)

    for i in count():
        try:
            incremented += step
            int(incremented)
        except Exception:
            return i, incremented, traceback.format_exc()


def _proper_groupby(iterable, key):
    return groupby(sorted(iterable, key=key), key)


def print_counts(label, values):
    counted = Counter(values)
    grouped_by_count = _proper_groupby(counted.items(), lambda x: x[1])

    print(f"Value counts for {label}")
    for count, items in grouped_by_count:
        print(f"    Values that appeared {count} times:")
        for item in items:
            print(f"        {item[0]}")


WORD_SIZES = [32, 64]
FRAC_BITS = [8, 16]
ROUNDINGS = ["around", "floor", "ceil", "trunc"]
SIGNED = [True, False]
VALUES = [0, 0.1, 0.125, 0.5, 1, 33, 55]
STEPS = [0.1, 0.125, 0.5, 1, 33, 55]


argument_cominations_to_test = list(
    product(WORD_SIZES, FRAC_BITS, ROUNDINGS, SIGNED, VALUES, STEPS)
)

print(f"Testing {len(argument_cominations_to_test)} combinations")

# [(arguments, result), ...]
args_and_results = map(
    lambda arguments: (arguments, sample_case(*arguments)), argument_cominations_to_test
)


grouped_by_traceback = _proper_groupby(args_and_results, lambda x: x[1][2])

for tb, args_and_results in grouped_by_traceback:
    print("RESULTS FOR TRACEBACK:")
    print(tb)

    args, results = zip(*tuple(args_and_results))

    word_size, frac_bits, rounding, signed, value, step = zip(*args)
    loop_n, last_incremented, _ = zip(*results)

    print()

    print("ARGUMENTS:")

    print_counts("Word Sizes", word_size)
    print_counts("Frac Bits", frac_bits)
    print_counts("Roundings", rounding)
    print_counts("Signed", signed)
    print_counts("Values", value)
    print_counts("Steps", step)

    print()

    print("RESULTS:")

    print_counts("Loops", loop_n)
    print_counts("Last Incremented", map(str, last_incremented))

    print()

    print("--------------------------------------------------")

Code Output

Testing 1344 combinations
RESULTS FOR TRACEBACK:
Traceback (most recent call last):
  File "C:\Users\jmoli\repos\pygame-1\fxpmathbug.py", line 20, in sample_case
    int(incremented)
  File "C:\Users\jmoli\repos\pygame-1\.venv\Lib\site-packages\fxpmath\objects.py", line 1158, in __int__
    return int(self.astype(int))
               ^^^^^^^^^^^^^^^^
  File "C:\Users\jmoli\repos\pygame-1\.venv\Lib\site-packages\fxpmath\objects.py", line 986, in astype
    val = np.array(list(map(int, val.flatten()))).reshape(val.shape)
                                 ^^^^^^^^^^^
AttributeError: 'int' object has no attribute 'flatten'


ARGUMENTS:
Value counts for Word Sizes
    Values that appeared 672 times:
        32
        64
Value counts for Frac Bits
    Values that appeared 672 times:
        8
        16
Value counts for Roundings
    Values that appeared 336 times:
        around
        floor
        ceil
        trunc
Value counts for Signed
    Values that appeared 672 times:
        True
        False
Value counts for Values
    Values that appeared 192 times:
        0
        0.1
        0.125
        0.5
        1
        33
        55
Value counts for Steps
    Values that appeared 224 times:
        0.1
        0.125
        0.5
        1
        33
        55

RESULTS:
Value counts for Loops
    Values that appeared 672 times:
        31
        0
Value counts for Last Incremented
    Values that appeared 4 times:
        3.3515625
        4.1015625
        16.1015625
        32.1015625
        1056.1015625
        1760.1015625
        3.375
        3.75
        4.25
        36.25
        58.25
        3.125
        3.22265625
        4.09765625
        16.09765625
        32.09765625
        1056.09765625
        1760.09765625
        3.625
        36.125
        58.125
        3.2001953125
        3.300201416015625
        4.100006103515625
        16.100006103515625
        32.100006103515625
        1056.1000061035156
        1760.1000061035156
        3.3251953125
        3.7001953125
        4.2001953125
        36.2001953125
        58.2001953125
        3.19970703125
        3.2996978759765625
        4.0999908447265625
        16.099990844726562
        32.09999084472656
        1056.0999908447266
        1760.0999908447266
        3.32470703125
        3.69970703125
        4.19970703125
        36.19970703125
        58.19970703125
        0.1015625
        0.203125
        0.09765625
        0.1953125
        0.100006103515625
        0.20001220703125
        0.0999908447265625
        0.199981689453125
    Values that appeared 8 times:
        3.25
        0.2265625
        0.6015625
        1.1015625
        33.1015625
        55.1015625
        0.22265625
        0.59765625
        1.09765625
        33.09765625
        55.09765625
        0.225006103515625
        0.600006103515625
        1.100006103515625
        33.100006103515625
        55.100006103515625
        0.2249908447265625
        0.5999908447265625
        1.0999908447265625
        33.09999084472656
        55.09999084472656
    Values that appeared 16 times:
        4.0
        16.0
        32.0
        1056.0
        1760.0
        16.125
        32.125
        1056.125
        1760.125
        4.5
        16.5
        32.5
        1056.5
        1760.5
        5.0
        17.0
        1057.0
        1761.0
        37.0
        49.0
        65.0
        1089.0
        1793.0
        59.0
        71.0
        87.0
        1111.0
        1815.0
        0.125
        0.5
        55.0
        0.25
        2.0
        66.0
    Values that appeared 20 times:
        4.125
    Values that appeared 32 times:
        33.0
        1.0
        0.625
        1.125
        33.125
        55.125
        1.5
        33.5
        55.5
        34.0
        56.0
        88.0

--------------------------------------------------

Results Summary

  • Values tested half the times failed after 0 iterations and the other half 31, the times it failed after 0 probably was for a configuration mistake I introduced in the values, like using wrong combinations of frac_bits and word_size.

  • All argument combinations raised the same exception.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant