[x3d-public] requesting help for python configuration

Brutzman, Donald (Don) (CIV) brutzman at nps.edu
Thu Apr 11 01:20:35 PDT 2019


John and Loren: a few things standing out in this thread.  Rather than trying to intersperse, here are responses:

===============================================================

1. "return self" is the pattern we've been following in the underlying X3DJSAIL Java methods, it allows pipelining (aka daisy chaining or lambdas).  Since each Java setField(..) method returns a copy of the parent object (i.e. "return this;") then subsequent calls can continue in the same fashion.

Here is a pipelining example excerpted from HelloWorld.java, note repeated invocations on each object:

new TransformObject().setTranslation(0.0f,-2.0f,0.0f)
   .addChild(new ShapeObject()
     .setGeometry(new TextObject("TextMessage").setString(new MFStringObject("\"Hello\" \"world!\""))
       .setFontStyle(new FontStyleObject().setJustify(FontStyleObject.JUSTIFY_MIDDLE_MIDDLE)))
     .setAppearance(new AppearanceObject()
       .setMaterial(new MaterialObject().setUSE("MaterialLightBlue"))))

Java does not have a requirement for a returned object to be used further, so the following line is OK without warning.

TransformObject myTransform = new TransformObject().setTranslation(0.0f,-2.0f,0.0f)
   .addChild(new ShapeObject()
     .setGeometry(new TextObject("TextMessage").setString(new MFStringObject("\"Hello\" \"world!\""))
       .setFontStyle(new FontStyleObject().setJustify(FontStyleObject.JUSTIFY_MIDDLE_MIDDLE)))
     .setAppearance(new AppearanceObject()
       .setMaterial(new MaterialObject().setUSE("MaterialLightBlue"))));

Not sure, it may be necessary for these pyjnius/python mappings to have a "return self" in order for pyjnius to find the correct X3DJSAIL method signature.

===============================================================

2. Regarding private methods:  X3DJSAIL intends for private methods to be internal only and thus are truly private.  This is used sparingly and carefully; an outside programmer should never need a private method.  If there is not a publicly accessible method to set/get a value, or perform some necessary utility function, then that is a hole in the X3DJSAIL API that should get fixed by adding the appropriate public method.

See concurrent email on setUrl(string array) syntax... yes, public methods exist for setters accepting String[] and other similar types.

So I believe that X3DJSAIL has full coverage of types already in setters.  If indeed any are missing then we can add them.

This should provide us with good flexibility when mapping python data structures down to underlying pyjnius-Java-X3DJSAIL methods.

I suppose you are making X3DJAIL quack...

===============================================================

3. Python Scene Access Interface (SAI) is the eventual standardization goal.

This means fully functional X3D scene graph manipulation in Python.  Rendering not required of this sample implementation.

Let's get Python X3D working first.  Then writing the spec will be straightforward, and further tuning will align it nicely with other X3D programming-language bindings.  I suspect that Python SAI will look pretty similar to the Java SAI spec.

	X3D Specification Relationships diagram
	http://www.web3d.org/specifications/X3dSpecificationRelationships.png

===============================================================

4. Importing from another directory just bit us recently when setting up example archive builds.

Loren your difficult experience attempting to get that to work is important to us here, we don't need to fight common practice.

... so that is probably telling us to work on a pip capability sooner rather than later, avoiding repetition of painful mysterious failures.

	pip 19.0.3
	pip install pip
	https://pypi.org/project/pip

	pip (package manager)
	https://en.wikipedia.org/wiki/Pip_(package_manager)

	Installing Python Modules
	https://docs.python.org/3/installing

	PyPA » pip 19.0.3 documentation » The Python Package Installer
	https://pip.pypa.io/en/stable

	PyPA » pip 19.0.3 documentation » User Guide
	https://pip.pypa.io/en/stable/user_guide

and lots of things in

	Python Cookbook, 3rd Edition: Recipes for Mastering Python 3
	By Brian Jones, David Beazley
	Publisher: O'Reilly Media, May 2013, Pages: 706
	http://shop.oreilly.com/product/0636920027072.do

===============================================================

5. Renaming conversion files: gosh no, only iff we hit an unbreakable wall.  Let's try to correctly wag the Python tail first, and not try to wag the whole X3D dog.

I'll add ModelName.py link (or links) to each model file in X3D Example Archives when we think we are ready.  Can apply fair warning at the top of the developmental source files.  The two styles of .py files are getting created now by the build script, so this will only require some autogenerated web-page additions.  The links will simply be added as a top-dead-center icon and text in upper-right-hand corner of pages like:

	http://x3dgraphics.com/examples/X3dForWebAuthors/Chapter01TechnicalOverview/HelloWorldIndex.html

Am hoping to get my second sits-at-home Windows 7 Enterprise box building the .py OK since these full archive builds (of the whole X3D dog) take some time.  That will permit ~daily updates as we keep refining and improving the syntax and the Java bindings.

===============================================================

6. Duck typing, excerpted:

https://en.wikipedia.org/wiki/Duck_typing

Duck typing in computer programming is an application of the duck test—"If it walks like a duck and it quacks like a duck, then it must be a duck"—to determine if an object can be used for a particular purpose. With normal typing, suitability is determined by an object's type. In duck typing, an object's suitability is determined by the presence of certain methods and properties, rather than the type of the object itself.

Example

This is a simple example in Python 3 that demonstrates how any object may be used in any context, up until it is used in a way that it does not support.

class Duck:
     def fly(self):
         print("Duck flying")

class Airplane:
     def fly(self):
         print("Airplane flying")

class Whale:
     def swim(self):
         print("Whale swimming")

def fly(entity):
     entity.fly()

duck = Duck()
airplane = Airplane()
whale = Whale()

fly(duck) # prints `Duck flying`
fly(airplane) # prints `Airplane flying`
fly(whale) # Throws the error `'Whale' object has no attribute 'fly'`

===============================================================

7. Complex mappings

If we squeeze/push/prod hard and find that long-ish method mappings to X3DJSAIL are indeed needed to achieve happily terse Pythonic models, that is OK.

Path to success is that we get the design patterns better and better, then autogenerate mappings from X3DUOM for entire X3D vocabulary.  This avoids error-prone hand code and enables strict compliance across each past and future X3D version.

Once again we have every reason to figure this out well.  Indeed that seems to match the design of python itself, getting things right on the insight to simplify the creation of strictly correct code by programmers on the outside.

===============================================================

8. Kivy (pyjnius) help

a. StackOverflow does have some pyjnius traffic

https://stackoverflow.com/search?q=pyjnius

- - - - - - - - - - -

b. Project channels:

https://github.com/kivy/pyjnius/blob/master/README.md#Support

= Support =

If you need assistance, you can ask for help on our mailing list:
     User Group : https://groups.google.com/group/kivy-users
     Email : kivy-users at googlegroups.com

We also have an IRC channel:
     Server : irc.freenode.net
     Port : 6667, 6697 (SSL only)
     Channel : #kivy

= Contributing =

We love pull requests and discussing novel ideas. Check out our contribution guide and feel free to improve PyJNIus.

The following mailing list and IRC channel are used exclusively for discussions about developing the Kivy framework and its sister projects:

     Dev Group : https://groups.google.com/group/kivy-dev
     Email : kivy-dev at googlegroups.com

===============================================================

9. Better and better...  onward we go.

Again thanks for sharing all this excellent thinking and exploration, really interesting and helpful.

v/r Don

===============================================================


On 4/10/2019 2:54 PM, Peitso, Loren (CIV) wrote:
> 
> The trendline seems to be in the right direction John!
> 
> 
>> Okay, we will move in 2 directions.  Maintain the existing Pyjnius X3DJSAIL API, and also continue on a research pythonic API that is uses assignment statements to set values. Then we need someone to write all property functions.  Per that, here are the specific codes that need to be added to packagemanager.py in pythonapi, so we can generate all these things (DRY):
>>                 [ in setter function]
>>         str += '    @'+fld+'.setter\n'
>>         str += '    def ' + fld +'(self, value = ' + self.getDefault(field) +  "):\n"
>>         str += self.settervalidate(field, "value”)
>>         str += '        self.'+private(fld)+' = value\n’
> 
>>         str += "        return self\n”
> return self not needed for Python setter, it should only return None from the implicit return, there might be something to discuss with respect to the validator calls, but I don’t know enough about what you have on the Java-side already, and the rest of what is required for a fully-Pythonic robust module implementation to know for sure.
> 
> 
> 
>>                 [ in getter function ]
>>             str += '    @property\n'
>>             str += '    def '+ fld + '(self):\n'
>>             str += '        return self.' + private(fld) + "\n"
>> This is essentially what Loren suggested at first.
>> We may have to do some wiggling (change other functions) to make some fld’s private (with private()) and some not. This is a global concern of the code.
> 
> There is no true private in Python, it just is not a goal of the language and that means everything can be accessed everywhere if someone wants to bad enough.  We indicate a desire for programmers to treat a variable or method as private with a leading double underscore.   The @properties work within this limitation to eliminate almost all of the accidental mistakes in updating essentially public instance variables.  We use self.varname to add a new public facing instance variable (personally I only add instance variable in the __init__method, but the language will let you add them anyplace if you know how.)  Then we can add some protection to the underlying data through the properties.
> 
> The property/setter pair build a mapping between that public facing instance variable’s symbol and the property/setter function calls. They keep the actual data in a shadow instance variable (typically) with double underscore prepended to the varname (self.__varname).  All programmers wishing to interact with the instance data just use the public symbol, and the interpreter manages the property/setter calling/substitution.  This way nobody can ever forget to call the setter properly, or even need to know if a setter exists at all; you just use the public variable symbol.
> 
> 
>> We also have arrays and lists (add/remove) functions in our X3DJSAIL API.   How do we make those Pythonic?
> 
> While I don’t have a ‘workable’ answer off the top of my head, NumPy is an example of doing this.  Source should be available, although it won’t be Java all the way underneath.
> 
>> Um.  Can python support overloading?  It can with pyjnius.   We many need overloading.
> 
> pyjnius fakes overloading, based on my quick scan, creating if/else structures to disambiguate and call a generated matching signature function as appropriate.  More Pythonic is to pass in multi-args using *args or **kwargs and resolve those internally in the method body and avoid extra function calls.  So both the “meat and potatoes” API and the “research/pythonic” API are workable with varying loads of effort.
> 
>> Question. Do we add assignment methods to the X3D Python standard, since they are nearly unsupportable by pyjnius (requires at least 2 PhDs)? My vote is to leave it out of the standard, or add it to a higher profile or component, so not everyone has to implement it.  Thus this means that the PyJNIus X3D API is “good enough” for the standard. If someone complains, we ask them to implement assignment methods. Meanwhile, we will be building steam for the next version of the standard, once we get more python programmers on board.   Then we will not be having to implement “overloaded” assignment methods in the short term.
> 
> if by assignment methods you mean property/setter pairs I agree and also concur they should not be specifically called in the X3D standard.  They are best practice implementation goals of a particular language binding.  A deeper question surfaces from that though…   Should any part of the X3D standard “force” a "hard-coded" API look-and-feel via hard-named setters and getters, or should the standard enforce the specific names for fields and require accessor and mutator behaviors supported by the target language implementation?  Any standard update that statement could create should not make any currently compliant implementation change anything, it just removes language specifics from forcing something on a different language to the detriment of a clean implementation
> 
>> So X3D Python X3DJSAIL is our “meat and potatoes” API, where we will try to implement at least limited chaining, and property assignment is our “research/pythonic” API. Can we reach agreement on this statement?   We can also work towards combining the two.
> 
> I think in the future-future what gets learned making the initial “research/pythonic” API will make it possible to go there in one automagical double-shot starting with the “meat and potatoes” API as the first step.  A lot of the “research/pythonic” API differences are going to be straight syntactic transformations.
> 
>> I do not like how difficult it is to set up a PyJNIus environment.   We need to work on that.
>> Since we cannot properly call the set/get Java methods from a pythonic interface, we will declare the two styles of setting/getting non-interoperable for now.  One will store values in Java and the other will store values in Python.
> 
> well you can properly call the Java-side easily enough, and get correct java-side behavior, it just does not come across as Pythonic in a first pass should not be inside a property/setter pair until it is possible to expose the necessary info to the interpreter.  The Pythonic implementation needs extra massaging to integrate into what the interpreter expects on the fly in order to use properties to manage instance variables.  I have not done low level module dev targeting an alternate language underneath, but it is done often by others.  So it can be Pythonic but at some non-trivial extra cost in development.
> 
>> DON:  the future syntax doesn’t work unless you use the “research” API.  FYI!  Make the serializers write to different filenames.  Or at least look at the error output from *.future.py files
>> DON:  The problem is that in PyJNIUs, the Java methods return concrete instances with abstract class type, per Java.   We need research into PyJNIus on how to deal with this in a clean way.   PyJNIus autoclass() doesn’t seem to be doing the trick, so maybe we can use jnius.cast’ing, which will be a horrible mess I think (Imagine each set call being cast to a value with the cast function.  When you use the simple API, you are using assignment, which knows how to resolve the interface to the concrete class.  If you want to try without abstract classes, merely move the sai part of the python org tree out of the way.  If you look at the new imports for abox.py and abox.future.py, you will see that they use the concrete classes.
> 
> On the Python side this may be less of a problem than it looks.  A duck is a duck.  And Python dynamically duck-types.
> 
>> Kivy (pyjnius) help is available on discord at https://chat.kivy.org/  I tried signing up, but haven’t figured out how to enter the chat room yet.
>> I am thinking the simple style of API is the best one for use with PyJNIus, until python assignment expressions are available. If someone wants to put the effort into the python pipelining serializer to add jnius.casts,  I’m not stopping you.
>> I’d like to work on the research API, FYI (we need 2 implementations for a standard, right?).  It’s found in “pythonapi” next to our pyjnius implementation. We should probably move it up next to the java folder.  I’ve already produced 2 versions of the PyJNIus, and I feel a bit stuck on it.
> 
> Is a Python API itself really a standardization goal?  Or is a better goal a way to either show a Python implementation of an existing standard, or learn how the existing standard needs to be tweaked to make it more standard and amenable to multiple language implementations?
> 
>> Is there agreement that the new import’s style and directory structure is appropriate?   Comments?
> 
> *from xxx import as y*  give me the heebee-jeebies from a Python point of view.  Stuff that is imported is also inherently flattened within Python, and ‘as’ does not help when using from-style importing.  I STRONGLY suggest only using* import xxxx as y*  syntax and sucking up the necessity to use the ‘y.’ when accessing functionality from module y.  The work it takes to ensure *from xxx import as y* does not break something at runtime (because it will happily import and overwrite stuff silently) is probably far more than dealing with the prepends, and even then there is no guarantee that the java-code symbol names won’t make this galactic-ally hard.
> 
> And I have yet to find guidance that says anything other than avoid importing from anyplace other than the current directory: meaning no path semantics in the import statements (just in case tat is what you meant by directory structure). Either import a module/file from the current directory, or import a module that is installed into the base Python distro with pip.   I have tried breaking that for running grading scripts and it is full of fail and sorrow, none of the try-this workaround stuff has worked for me.
> 
> 
> 
> 
> v/r  Loren
> 
> 
> 
> 
> 
> 
> 
>> On Apr 10, 2019, at 1:00 PM, John Carlson <yottzumm at gmail.com <mailto:yottzumm at gmail.com>> wrote:
>>
>> I’m too tired to continue on this email. It is what it is.
>> Okay, we will move in 2 directions.  Maintain the existing Pyjnius X3DJSAIL API, and also continue on a research pythonic API that is uses assignment statements to set values. Then we need someone to write all property functions.  Per that, here are the specific codes that need to be added to packagemanager.py in pythonapi, so we can generate all these things (DRY):
>>                 [ in setter function]
>>         str += '    @'+fld+'.setter\n'
>>         str += '    def ' + fld +'(self, value = ' + self.getDefault(field) +  "):\n"
>>         str += self.settervalidate(field, "value”)
>>         str += '        self.'+private(fld)+' = value\n'
>>         str += "        return self\n"
>>                 [ in getter function ]
>>             str += '    @property\n'
>>             str += '    def '+ fld + '(self):\n'
>>             str += '        return self.' + private(fld) + "\n"
>> This is essentially what Loren suggested at first.
>> We may have to do some wiggling (change other functions) to make some fld’s private (with private()) and some not. This is a global concern of the code.
>> We also have arrays and lists (add/remove) functions in our X3DJSAIL API.   How do we make those Pythonic?
>> Um.  Can python support overloading?  It can with pyjnius.   We many need overloading.
>> Question. Do we add assignment methods to the X3D Python standard, since they are nearly unsupportable by pyjnius (requires at least 2 PhDs)? My vote is to leave it out of the standard, or add it to a higher profile or component, so not everyone has to implement it.  Thus this means that the PyJNIus X3D API is “good enough” for the standard. If someone complains, we ask them to implement assignment methods. Meanwhile, we will be building steam for the next version of the standard, once we get more python programmers on board.   Then we will not be having to implement “overloaded” assignment methods in the short term.
>> So X3D Python X3DJSAIL is our “meat and potatoes” API, where we will try to implement at least limited chaining, and property assignment is our “research/pythonic” API. Can we reach agreement on this statement?   We can also work towards combining the two.
>> I do not like how difficult it is to set up a PyJNIus environment.   We need to work on that.
>> Since we cannot properly call the set/get Java methods from a pythonic interface, we will declare the two styles of setting/getting non-interoperable for now.  One will store values in Java and the other will store values in Python.
>> DON:  the future syntax doesn’t work unless you use the “research” API.  FYI!  Make the serializers write to different filenames.  Or at least look at the error output from *.future.py files
>> DON:  The problem is that in PyJNIUs, the Java methods return concrete instances with abstract class type, per Java.   We need research into PyJNIus on how to deal with this in a clean way.   PyJNIus autoclass() doesn’t seem to be doing the trick, so maybe we can use jnius.cast’ing, which will be a horrible mess I think (Imagine each set call being cast to a value with the cast function.  When you use the simple API, you are using assignment, which knows how to resolve the interface to the concrete class.  If you want to try without abstract classes, merely move the sai part of the python org tree out of the way.  If you look at the new imports for abox.py and abox.future.py, you will see that they use the concrete classes.
>> Kivy (pyjnius) help is available on discord athttps://chat.kivy.org/  I tried signing up, but haven’t figured out how to enter the chat room yet.
>> I am thinking the simple style of API is the best one for use with PyJNIus, until python assignment expressions are available. If someone wants to put the effort into the python pipelining serializer to add jnius.casts,  I’m not stopping you.
>> I’d like to work on the research API, FYI (we need 2 implementations for a standard, right?).  It’s found in “pythonapi” next to our pyjnius implementation. We should probably move it up next to the java folder.  I’ve already produced 2 versions of the PyJNIus, and I feel a bit stuck on it.
>> Is there agreement that the new import’s style and directory structure is appropriate?   Comments?
>> 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 11:56 PM
>> *To:*Peitso, Loren (CIV) <mailto:lepeitso at nps.edu>;John Carlson <mailto:yottzumm at gmail.com>
>> *Cc:*X3D Graphics public mailing list <mailto:x3d-public at web3d.org>
>> *Subject:*Re: requesting help for python configuration
>> [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> <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> <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> <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> <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> <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'> <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> <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 <mailto: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
> 


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