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

Allow for heterogeneous lists #29

Open
qiemem opened this issue Dec 17, 2019 · 3 comments
Open

Allow for heterogeneous lists #29

qiemem opened this issue Dec 17, 2019 · 3 comments

Comments

@qiemem
Copy link

qiemem commented Dec 17, 2019

Currently, attempting to report a heterogeneous list gives a ParseException pyNetLogo attempts to the elements of a LogoList based on the type first element:

> netlogo.report('["hi" 8]')

java.text.ParseException: Java error in converting result: java.lang.ClassCastException: java.lang.Double cannot be cast to java.lang.String
	at NetLogoLinkV61.NLResult.cast_logolist(NLResult.java:179)
	at NetLogoLinkV61.NLResult.logoToType(NLResult.java:69)
	at NetLogoLinkV61.NLResult.setResultValue(NLResult.java:15)
	at NetLogoLinkV61.NetLogoLink.report(NetLogoLink.java:198)

Heterogeneous lists are quite useful, especially when associating results with parameters.

It should be possible to return heterogeneous lists by leaving the LogoList elements boxed and converting to an object array (instead of a value array), or surfacing the LogoList to jpype directly and converting on the Python side (though I don't know much about jpype). These options could have a performance hit depending on how jpype's memory sharing works, but they could be done as fallback options when returning a value array would fail.

@quaquel
Copy link
Owner

quaquel commented Dec 18, 2019

I'll have to dive into jpype to see if this is possible. Also, I will check how the RNetlogo package deals with this. If possible, I prefer to maintain feature parity with them.

@qiemem
Copy link
Author

qiemem commented Dec 18, 2019

I started messing around with jpype directly as I needed heterogeneous output from something. Here's I ended up using the following python function which can directly take the output from workspace.report:

def _nl_to_py(obj):
    if isinstance(obj, float):
        return obj
    elif isinstance(obj, java.lang.String):
        return str(obj)
    elif isinstance(obj, java.lang.Boolean):
        return bool(obj)
    elif isinstance(obj, org.nlogo.core.LogoList):
        return [_nl_to_py(x) for x in obj.javaIterable()]
    else:
        return obj

The overhead doesn't seem to be about the same as the current version:

> %timeit _nl_to_py(ws.report('[1 2 3]'))

5.58 ms ± 75 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

> %timeit netlogo.report('[1 2 3]')

5.68 ms ± 61.7 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

(ws is an org.nlogo.headless.HeadlessWorkspace created via jpype).

Here's some sample output:

> _nl_to_py(ws.report('[true "two" 3 [4 [5]]]'))

[True, 'two', 3.0, [4.0, [5.0]]]

@quaquel
Copy link
Owner

quaquel commented Dec 20, 2019

Interesting idea. Basically, instead of trying to convert everything within Java as I currently do (see here line 100). You could pass everything straight to python and deal with it there. Dealing with heterogenous collections is much easier this way and performance seems fine.

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

No branches or pull requests

2 participants