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

Bug when return iterable with one element #10

Open
artzet-s opened this issue Aug 31, 2018 · 6 comments
Open

Bug when return iterable with one element #10

artzet-s opened this issue Aug 31, 2018 · 6 comments
Assignees
Labels
bug Something isn't working

Comments

@artzet-s
Copy link

artzet-s commented Aug 31, 2018

Hi, I encounter problem :

def test_bug_0():  
    return {"A": 0, "B": 1}

def test_bug_1():
    return {"A": 0, "B": 1, "C": 2}

def test_bug_2():
    return {"A": {0: 42, 1: 21}, "B": 1, "C": 2}

def test_bug_3():
    return {"A": {0: 42, 1: 21}}

def test_bug_4():
    return {"A": {0: 42}, "B": {1: 21}}

test_bug_3() bug and return :

Traceback (most recent call last):
  File "c:\users\artzetsi\miniconda2\envs\develop\lib\site-packages\openalea.core-2.0.2-py2.7.egg\openalea\core\algo\dataflow_evaluation.py", line 227, in eval_vertex_code
    ret = node.eval()
  File "c:\users\artzetsi\miniconda2\envs\develop\lib\site-packages\openalea.core-2.0.2-py2.7.egg\openalea\core\node.py", line 654, in eval
    self.outputs[0] = outlist[0]
KeyError: 0

Worst with a collection.defaultdict like :

def test_bug_5():
    d = collections.defaultdict(dict)
    d["A"][0] = 42
    return d

don't throw error; just return a empty dict {}

Same for you ?

@artzet-s artzet-s added the bug Something isn't working label Aug 31, 2018
@pradal
Copy link
Contributor

pradal commented Aug 31, 2018

Hi Simon,
A node in visualea return several arguments: a tuple.
The problem comes from when you return an iterable with one element.
Do you want to return the first element of the iterable or the iterable itself.

To solve this problem (Python has exactly the same ambiguity), you have to return a tuple of one element:
def test_bug_3(): return {"A": {0: 42, 1: 21}},

Add a coma at the end of your expression

@artzet-s
Copy link
Author

artzet-s commented Aug 31, 2018

Do you want to return the first element of the iterable or the iterable itself

I want return the iterable itself

you have to return a tuple of one element

Ok, thanks that works !

So, it's still a limitation/problem to wrap external code (= not modifiable) who return iterable with one element ? It is resolvable ?

@pradal
Copy link
Contributor

pradal commented Aug 31, 2018

In Python to create a tuple with one element, you have to do:
my_tuple = 1,
Because otherelse mytuple is an int of value 1. Even if you do:
my_tuple=(1)

We have exactly the same problem and there is no simple solution

@artzet-s
Copy link
Author

artzet-s commented Aug 31, 2018

Ok, but the thing a don't understand, I return a dict not a tuple. Even with a defaultdict, list or numpy array.

def defaultdict_one_element():
    d = collections.defaultdict(int)
    d["A"] = 42
    return d

> 0

def dict_one_element():
    return {"A": 42}

> key error 0

def list_one_element():
    return [42]

> 42 and not [42]

def numpy_on_element():
    return numpy.array([42])

> 42 and not array([42])

So openalea can't transform/wrap (=make a node) correctly a iterable with one element if they not return like a tuple of one element. It's still a huge limitation, scikit-image, scikit-learn, opencv, etc. don't return systematically (even practically never) their numpy_array/list/dict like a tuple of one element.

@artzet-s artzet-s changed the title Bug when return dict of dict with one element Bug when return iterable with one element Aug 31, 2018
@artzet-s
Copy link
Author

artzet-s commented Aug 31, 2018

So, more, I try "the tuple of one element" solution. But I don't understood that changed my type of return during the python execution.

def list_one_element(): 
     return [42],

Through visualea return the list [42] otherwise with classic python execution the tuple ([42],)

@pradal
Copy link
Contributor

pradal commented Feb 16, 2023

In fact, in visualea, the default behavior is several outputs.
If the number of outputs is not define (in our case we use a Python function), then there is a problem between

  • a iterable of one element
  • the element of the iterable

In our case, list, tuple, dict are considered as iterable.
We have the same case in Python:

  • How to differentiate a tuple of one element?

(1) is not similar to (1,)

Possible solutions

  1. Create a node explicitly (from the class Node) with an eval function (eg here)
  2. Add a decorator of a given function for functions with one output that return a list
  3. Use Python 3 Annotations to improe the export of functions as OpenAlea components

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants