Zulko/vapory

API is not very pythonic

lily-mara opened this issue · 4 comments

This is just an opinion, but all of the POVRayElement subclasses seem to have a very peacemeal API that has some strange conventions.

If I'm creating a new Camera object and I want it to be located at [0, 2, -3], and looking at [0, 1, 2], compare these methods for constructing that Camera:

# current method
c = Camera( 'location', [0, 2, -3], 'look_at', [0, 1, 2] )

# If I later want to update the properties of that Camera, I have some very confusing parsing to do:

# update c's location to [1, 2, 3]
c.args[c.args.index('location')+1] = [1, 2, 3]

Proposed API:

# current method
c = Camera( location=[0, 2, -3], look_at=[0, 1, 2] )

# If I later want to update the properties of that Camera, it's very easy:

# update c's location to [1, 2, 3]
c.location = [1, 2, 3]

The implementation for this is not much more complex than the current one:

class POVRayElement:
    def __init__(self, **kwargs):
        self.__dict__.update(kwargs)

I know that it is not Pythonic at all, but your API won't work, because in POVRay the order of the arguments matters a lot. For instance this:

Sphere(xyz, radius, Texture(...), 'scale', 0.5)

Is different from this:

Sphere(xyz, radius, 'scale', 0.5, Texture(...))

In the first example the scaling applies to the texture, in the second it doesn't. You lose this flexibility if you have an argument scale=0.5 because then you can't decide of an order. And that's just one example, there are other syntaxic things that you just can't reproduce with keyword arguments.

And I am too lazy to reprogram each function to give the order in which the arguments must appear.

But it's not a big deal, to change the properties of the camera, just construct a new camera, for instance:

myscene = Scene(camera=Camera(), items=[...])
# later
myscene.camera = Camera(...)

wouldn't the scale only apply to the Texture if it was layed out like this?

sphere { xyz radius texture { scale 0.5 } }

See at the end of this page. Another example which comes to mind is "translate" and "rotate", for which the order matters.

So yeah this whole library is just an horrible hack. If you have other suggestions, they are welcome !