[x3d-public] requesting help for python configuration

Brutzman, Donald (Don) (CIV) brutzman at nps.edu
Tue Apr 9 21:56:13 PDT 2019


[cc: group]

Thanks for the great progress and interesting explorations.  Really illuminating.

I think our primary criteria are simplicity and clarity of python syntax for end programmers building an X3D scene graph.  This leads to terseness, elegance and ease of programming.

So any syntactic complexity should get pushed to our X3DUOM-autogeneratable configuration files whenever possible.

It is interesting that both the "simple" syntax and "future" syntax both essentially work against a single shared pyjnius mapping to X3DJSAIL.  This indicates we are on the right track, and is also similar to the syntax variations (simple object.method invocation or lambda-style pipeline programming) currently available in X3DJSAIL library.  The similarities also aid in debugging and fixing of edge cases whenever necessary.

John, wondering if you can just map all the concrete nodes in a scene graph to the corresponding concrete objects in X3DJSAIL.  That will avoid all of the "abstract method not found" errors.  The X3D abstract classes are specification-defined and helpful and good to expose programmatically, but they are never needed when translating .x3d or other file encodings (uh, since they are abstract).

* "A concrete class is a class that can be instantiated, as opposed to abstract classes, which cannot."
   https://en.wikipedia.org/wiki/Class_(computer_programming)#Abstract_and_concrete

Suggestion to continue facilitating our current design refinements: when a design choice confronts us, try one approach in the "simple" syntax and compare with the alternate approach in the "future.py" file output.  That gives us direct comparisons across every case in ~3000 example scenes, a quite worthy batch of unit tests!  This really helps us converge on best practice.

Final exhortation: when in doubt, be pythonic!  Am still working to understand that well, so Loren your feedback is super valuable. Yes by gosh let's sand down the rough edges now before propagating workarounds to other folks.  We want the Python community to see X3D as a natural extension to the language.  If we get a Pythonic pynius X3DPSAIL that matches well, it gives us one implementation with well-defined language syntax.  Given Python's intentional design strictness on some things, this is very important.

Adding a second non-java/pyjnius/X3DJSAIL implementation will someday be straightforward (a few more SMOPs) if these language efforts are stable.  Indeed that kind of comparison is inevitable and required in specification development.  Thus we have every motivation to take our time and get things right on this round.

Again thanks, onward we go towards X3D Python...

v/r Don


On 4/9/2019 12:57 PM, Peitso, Loren (CIV) wrote:
> John,
> 
> If your code is internal only and not intended for outside programmer consumption then the rest of this really does not matter and can be left for some indeterminate future that may never need to come.  If you intend other Python programmers to invoke any of these classes/functions then this is expectations management and far simpler to work out now then adapt to later.
> 
>> import classpath
>> from org.web3d.x3d.jsail.Core.X3DObject import X3DObject as X3D
> 
>>     X3D0 = X3D()
>>     X3D0.setProfile("Immersive")
>>     X3D0.setVersion("3.3”)
> 
> 
> X3D0 = X3D()
> X3D0.profile = “Immersive"
> X3D0.version = “3.3”
> 
> is where you want to Pythonically get to for externally used code.  EVERYTHING in Python is effectively public hence the property related syntax to implement privacy via conventions.  Class X3D would need these to enable the above for profile:
> 
> @property#the getter, interpreter substitutes this on right-hand-side of assignment statements
>      def profile(self):
>          return self.__profile
> 
>      @profile.setter                     #the setter, interpreter substitutes this on left-hand-side of assignment statements
>      def profile(self, p):
>          self.__profile = p             #really this is where you run p thru some form of verification function so you can guarantee self.__ profile is valid
> 
> 
> the double-underscore variable name indicates to treat it as private by convention and eliminates the vast majority of user/programmer typos directly accessing the instance variable in an unprotected manner.  Most of these can be code-generated pro-forma and if you have a value verification function it can be wired in as the last generation step.
> 
> 
> 
> 
> I’ll leave off stirring things up from there, there is too much I don’t know to be getting overly directive about this.  I’ll continue to field questions/requests as they come in.
> 
> 
> v/r  Loren
> 
> 
> 
>> On Apr 9, 2019, at 11:41 AM, John Carlson <yottzumm at gmail.com <mailto:yottzumm at gmail.com>> wrote:
>>
>> I am somewhat familiar with it.  Most of my “future” API is where I would apply that.  Unless I can do it on top of Java. Currently, I am only interfacing at the class level, but I think getting into python deeper may help.  I am about to release another version of the API with packages, where the file
>> org/web3d/x3d/jsail/Core/X3DObject.py
>> looks like:
>> from jnius import autoclass
>> X3DObject = autoclass('org.web3d.x3d.jsail.Core.X3DObject')  # load Java class into X3DObject
>> I don’t have any opportunity, with autoclass, I think, to add setters and getters but I may be wrong. If I add setters and getters, it would be in addition to the Java class underneath.  If you could work with us  to add setters and getters the python way, but still access the Java classes for memory, that would be terrific.
>> I think Don wants to stick with X3DJSAIL in the short term, but I think we may be limited by Java interfaces.  I will let Don interface with you to reduce the amount of email load you have to deal with.
>> If creating the setter and getters also clears up the interfaces problem, that would be a double win.
>> Here is a sample client file (current) that uses setters (I haven’t tested getters yet):
>> import classpath
>> from org.web3d.x3d.jsail.Core.X3DObject import X3DObject as X3D
>> X3D0 = X3D()
>> X3D0.setProfile("Immersive")
>> X3D0.setVersion("3.3")
>> I’ll be adding my “from…import…as”s and import classpath to my serializers, Don.  X3Dautoclass.py will be untouched, but potentially buggy, and a new folder under pyjnius calls “org” will be created.   The mainline code will remain the same since we are using “as” in the imports.   A new build file, makeorg.sh will create the API instead of autoclass.py.  autoclass.py will remain until the new API generator is fully tested.
>> John
>> Sent fromMail <https://go.microsoft.com/fwlink/?LinkId=550986>for Windows 10
>> *From:*Peitso, Loren (CIV) <mailto:lepeitso at nps.edu>
>> *Sent:*Tuesday, April 9, 2019 12:48 PM
>> *To:*John Carlson <mailto:yottzumm at gmail.com>
>> *Cc:*Brutzman, Donald (Don) (CIV) <mailto:brutzman at nps.edu>
>> *Subject:*Re: requesting help for python configuration
>> For auto-generating, are you aware of the Pythonic way of implementing getter and setter functionalities? While you can match functionalities and function’s generated, it looks a little different and leverages the interpreter at runtime in a way Python is designed to do.
>> Starting with that earlier rather than later has definite benefits in not having to retool too much after the fact.
>> v/r  Loren
>>
>>
>>
>>
>>     On Apr 9, 2019, at 10:40 AM, John Carlson <yottzumm at gmail.com <mailto:yottzumm at gmail.com>> wrote:
>>     I am creating a python file structure similar to the java one. Wish me luck.
>>     John
>>     Sent fromMail <https://go.microsoft.com/fwlink/?LinkId=550986>for Windows 10
>>     *From:*John Carlson <mailto:yottzumm at gmail.com>
>>     *Sent:*Tuesday, April 9, 2019 10:59 AM
>>     *To:*Peitso, Loren (CIV) <mailto:lepeitso at nps.edu>
>>     *Cc:*Brutzman, Donald (Don) (CIV) <mailto:brutzman at nps.edu>
>>     *Subject:*RE: requesting help for python configuration
>>     So I think I could be using
>>     import X3Dautoclass
>>     if I did:
>>     X3D0 = X3Dautoclass.X3D()
>>     With no changes to X3Dautoclass.py (which is generated).
>>     I will have to ask what we want for our API.  I think it may be best to make programmers type (or they can use the from syntax).
>>     So since we are generating the client python code currently, it’s not a problem since we are not importing any other packages.
>>     So using the import as above is probably the way to go, unless we want to change the name of the X3Dautoclass.py filename (the package name).
>>     Don what do you think about the filename to import Java classes, to replace X3Dautoclass.py?  Should we call it X3DJSAIL.py, and have everyone type X3DJSAIL (or use as to rename as they want) before all X3DJSAIL class names in their client code?
>>     John
>>     Sent fromMail <https://go.microsoft.com/fwlink/?LinkId=550986>for Windows 10
>>     *From:*Peitso, Loren (CIV) <mailto:lepeitso at nps.edu>
>>     *Sent:*Tuesday, April 9, 2019 10:41 AM
>>     *To:*John Carlson <mailto:yottzumm at gmail.com>
>>     *Cc:*Brutzman, Donald (Don) (CIV) <mailto:brutzman at nps.edu>
>>     *Subject:*Re: requesting help for python configuration
>>     John,
>>     two parts 1)  the fix;   2) explanation, because to the uninitiated it seems like silly extra keystrokes because... Python!
>>     1)  NameError: name 'X3D' is not defined    wants  X3D0 = X3D.X3D()
>>     is simply the fully qualified naming thing below.  You will need to tell the generator to put in the ‘X3D.’ as part of the naming convention for functionalities accessed in the X3D module when it is imported using import xxx  (which needs to be always for library code).  For generated code and small files, easy peasy. If you are dealing with a big manually generated file, chalk it up to a learning experience and start pasting.  Been there done that.
>>     For a long time I though from math import * was the only way to go, no issues.  Then I ran into a self-created circular import situation playing with geometry classes when creating a course programming project and a set of in-class examples. I did some learning and got religion very fast.
>>     2) The two basic flavors of importing require different naming conventions in the code.
>>     example:
>>     from math import *
>>     area = 2 * radius * pi * pi
>>     import math
>>     area = 2 * radius * math.pi * math.pi
>>     from xxx import *   equates to:  import everything in module XXX, no matter what.  The convenient fiction for the programmer is to consider it as the module gets pasted in right at the import statement in it’s entirety and then interpreted as part of the file it is being imported into.
>>
>>         The 'no matter what' part may cause unintentional namespace collisions and Python simply handles that with a silent last name imported wins.  This also forces at least first level down importing of imports with associated namespace potential issues.  There are some exceptionally nasty issues that may arise in circular imports.
>>         The benefit is you do not need to use the module name of the module in the code, so it works as a shorthand.  While this is great or quick one-off non-shared scripts anything that can be used like a library should never force that paradigm on the importing party because programmers will create voodoo dolls for library programmers that create invisible circular naming issues. The can know this because if you put the imports at the bottom of the file instead of the top most of the problems go away until odd runtime things happen.  The only sane thing to do with libraries that must be imported at the bottom is to kill them with fire and never utter their name again.
>>
>>     import xxx  equates to:  the interpreter temporarily switching to import the indicated module as itself, then resuming interpreting the original file with the newfound knowledge of the imported module.
>>
>>         This means the imported file has it’s own clean namespace and no properly generated name within it will conflict with any external name because the internal names are fully-qualified leading with the module name.  There are no deeper passed along import issues because the import xxx locks those behind the module name.  If each library module follows the convention much happiness will result, far less hair will be pulled out, names will not be taken in vain and no voodoo dolls.
>>
>>     In a nod to, programmers like to be lazy even while benefitting from the full naming conventions, there is the ‘as' option
>>     import supercalifragilisticexpealidocious as sup
>>     answer = sup.fn1(arg)    # avoids   answer = supercalifragilisticexpealidocious.fn1(arg)
>>
>>     v/r  Loren
>>
>>
>>         On Apr 9, 2019, at 3:05 AM, John Carlson <yottzumm at gmail.com <mailto:yottzumm at gmail.com>> wrote:
>>         Loren, when I changed:
>>         /from X3Dautoclass import */
>>         to
>>         /import X3Dautoclass/
>>         according to what I “recall” you suggested in an email, which I can’t find now, so now I am thinking it might have been a dream (yeah, the kind of dream where you magically fix your code in your sleep).
>>         I got the following error:
>>         processSingleScene.pythonValidation:
>>              [echo] processSingleScene.python C:\x3d-code\www.web3d.org <http://www.web3d.org/>\x3d\content\examples\X3dForWebAuthors\Chapter10Geometry2D\Arc2D.py
>>              [echo] Loading X3D model as .py program, if successful then saving as round-trip .x3d version:
>>              [exec] Traceback (most recent call last):
>>              [exec]   File "C:\x3d-code\www.web3d.org <http://www.web3d.org/>\x3d\content\examples\X3dForWebAuthors\Chapter10Geometry2D\Arc2D.py", line 2, in <module>
>>              [exec]     X3D0 = X3D()
>>              [exec] NameError: name 'X3D' is not defined
>>              [exec] Result: 1
>>              [echo] =====================
>>         When I reverted and regenerated python files, the error went away.
>>         Suggestions?  I think I’ll stick with what I have unless you can show me something else that works better.  Working version looks like:
>>         ==============================================
>>         from X3Dautoclass import *
>>         X3D0 = X3D()
>>         X3D0.setProfile("Immersive")
>>         X3D0.setVersion("3.3")
>>         X3Dautoclass.py excerpt:
>>         import jnius_config
>>         jnius_config.set_classpath('.', 'c:/x3d-code/www.web3d.org/x3d/stylesheets/java/jars/X3DJSAIL.3.3.full.jar' <http://www.web3d.org/x3d/stylesheets/java/jars/X3DJSAIL.3.3.full.jar'>)
>>         from jnius import autoclass
>>         X3D = autoclass('org.web3d.x3d.jsail.Core.X3DObject')
>>         For your own experimentation.  Meanwhile, I will stick with what works in half my cases.
>>         Aside:  It might be interesting to reduce X3Dautoclass.py to just this for the *.future.py cases. Hmm.
>>         [ Note that import works with jnius_config to import a single symbol.  I have 362, but not all of them are included in the application source, just X3Dautoclass.py.  I could probably generate a trimmed down list of imports depending on the classes used, but I believe the syntax would be “from X3Dautoclass import X3D”.   I don’t want to have a class per file because that would be 362 files to manage, each looking similar to the above.   But ultimately, we may want to do that. Don?]
>>         Thanks!
>>         John
>>         Sent fromMail <https://go.microsoft.com/fwlink/?LinkId=550986>for Windows 10
>>         *From:*Brutzman, Donald (Don) (CIV) <mailto:brutzman at nps.edu>
>>         *Sent:*Tuesday, April 9, 2019 3:37 AM
>>         *To:*Peitso, Loren (CIV) <mailto:lepeitso at nps.edu>
>>         *Cc:*John Carlson <mailto:yottzumm at gmail.com>
>>         *Subject:*Re: requesting help for python configuration
>>         Loren, am happy to report that I have python 3.7 and pyjnius properly running on Windows 10 so that X3D python language binding can be applied against all X3D example scenes.
>>         Nevertheless this has been problematic on my Windows XP box with identical configurations failing there.  Am hoping we might sit down together sometime for "pair programming" so that you might observe, possibly notice a flaw in what I'm doing.
>>         Might Friday work for you, or next week?  I'd bring my second box to NPS.  Alternatively you are welcome to stop by the house where everything is setup nicely, not far from campus (51 Castro Road).
>>         Thanks for considering this request.
>>         all the best, Don
>>         --
>>         Don Brutzman  Naval Postgraduate School, Code USW/Br brutzman at nps.edu <mailto:brutzman at nps.edu>
>>         Watkins 270,  MOVES Institute, Monterey CA 93943-5000 USA   +1.831.656.2149
>>         X3D graphics, virtual worlds, navy roboticshttp://faculty.nps.edu/brutzman
>>
> 


all the best, Don
-- 
Don Brutzman  Naval Postgraduate School, Code USW/Br       brutzman at nps.edu
Watkins 270,  MOVES Institute, Monterey CA 93943-5000 USA   +1.831.656.2149
X3D graphics, virtual worlds, navy robotics http://faculty.nps.edu/brutzman


More information about the x3d-public mailing list