Closed camblomquist closed 1 year ago
Cheers @camblomquist!
Check out the previous issue: https://github.com/py5coding/py5generator/issues/199
Welcome, @camblomquist !
This bug is a result of a poor design choice on my part. It will be fixed in the next release. In the mean time, you can change your code to:
selection = py5.random_choice(choices)[0]
Which should give the desired result. After the next release (January) you will need to remove the [0]
.
I think there's a misunderstanding. I'm aware of #199. This is a different issue.
Given selection = py5.random_choice(choices)[0]
, the type of selection will be numpy.ndarray
even though the original type was Py5Vector. The Py5Vector is getting stripped away and its data is returned instead.
Oh, I see. Sorry @camblomquist , I didn't read your first comment carefully enough.
You are correct, this is a separate but related issue. I'm glad you found this, because it is very likely my fix for #199 would not have been a proper fix.
What I believe is happening here is numpy sees that Py5Vector implements __iter__()
so it unpacks Py5Vector and makes a numpy array instead. Observe the following:
In [13]: v1 = Py5Vector2D.random()
In [14]: v2 = Py5Vector2D.random()
In [15]: np.array([v1, v2])
Out[15]:
array([[0.59092497, 0.80672652],
[0.20564236, 0.97862721]])
In [16]: np.abs(v1)
Out[16]: array([0.59092497, 0.80672652])
Implementing __iter__()
is useful if you want to write code like py5.vector(*v1)
but it also means that when using numpy functions it will convert Py5Vectors to numpy arrays.
This is now fixed. Thank you @camblomquist for this helpful bug report.
We changed the API a bit. Now py5.random_choice()
will only return one item from the input sequence. An empty input will return None
.
And py5.random_sample()
will return a sequence of one or more items. If you input a numpy array you'll get a numpy array output, if you input a list of things you'll get a list of things back. You can give it a generator. An empty input will return []
.
In [3]: choices = [Py5Vector2D.random() for _ in range(10)]
In [4]: choices
Out[4]:
[Py5Vector2D([0.17232667, 0.98503986]),
Py5Vector2D([-0.94899056, -0.31530448]),
Py5Vector2D([0.96401531, 0.26584673]),
Py5Vector2D([-0.0318977 , 0.99949114]),
Py5Vector2D([ 0.45152884, -0.89225652]),
Py5Vector2D([0.74174634, 0.67068052]),
Py5Vector2D([-0.79971296, 0.60038253]),
Py5Vector2D([0.84921868, 0.52804132]),
Py5Vector2D([0.49868618, 0.86678261]),
Py5Vector2D([0.7289256 , 0.68459292])]
In [5]: py5.random_choice(choices)
Out[5]: Py5Vector2D([0.7289256 , 0.68459292])
In [6]: py5.random_sample(choices)
Out[6]: [Py5Vector2D([-0.94899056, -0.31530448])]
In [7]: py5.random_sample(choices, size=3)
Out[7]:
[Py5Vector2D([0.17232667, 0.98503986]),
Py5Vector2D([ 0.45152884, -0.89225652]),
Py5Vector2D([0.74174634, 0.67068052])]
My words are failing me today
I know that
Py5Vector
is backed by anumpy.ndarray
, and thatrandom_choice
usesnumpy.random.choice
internally, but I won't pretend to have any idea as to how this is happening.