# Error when Adding a Python Script to a Driver

I seem to have a bit of a problem that I was wondering if someone could help me with. As the title says, for some reason I keep getting an error when I try to add my script to the driver, and I can’t seem to figure out why at all. Here is the screenshot of how I’m applying it to the driver:

and here is the code:

import bpy
import math

def ShiftMoonMonth(objectName):
obj = bpy.data.objects[objectName]
sourceRotation = obj.rotation_euler.z
finalRotation = (math.floor(sourceRotation/389.10)*29.10564039280042)
return finalRotation

bpy.app.driver_namespace['ShiftMoonMonth'] = ShiftMoonMonth


I have auto-run python scripts turned on, and when I look through the available namespaces in the blender console, ShiftMoonMonth is one of the options I can use. So I’m pretty sure that the code is linked to the driver, but for some reason it’s still giving this error.

The place I got the code template from was this tutorial here: https://youtu.be/rfEFU0Mdq3Q?t=21m50s at 21:50, where he is trying to solve a very similar problem to what I’m solving. As far as I can tell, it seems to be the same as what I have, although it is quite old, so there may be something else you have to do. I also don’t understand the language, so I may have missed something.

Anyway, any help would be very appreciated!

For a single property type driver variable you need also to set the path value. For example

import bpy

def x(name):
print(name)
return 0

bpy.app.driver_namespace["x"] = x


for example shown prints "Lamp", the name of the lamp object, to the console. Ok, string properties can be passed via driver variables. (personally don't recommend it) (note also for this case, the expression could simply be x("Lamp") with no need for a driver variable)

Not setting path for the single property driver variable will result in "None" being printed to console.

Ok, now that we know a name can be passed, it's best to check for errors with something like,

if name is None:
print("problem with name variable")
return 0

obj = bpy.context.scene.objects.get(name)

if obj is None:
print("no object named:", name)
return 0


as errors will mark the driver as "bad" which can result it in being turned off.

A more usual way would be, where the x Euler rotation of the Lamp object, is passed as a float variable, "var", to the expression floor(2 * var / pi).

PS also of note is that rotation in blender is in radians.

You're using an object reference, but your code expects a name.

You may want to use rotation_euler as data path setting, and use that as parameter value. It'll make your code easier (and probably solves this problem).

It also avoids accessing objects by name; name based access is usually a bad idea, since names are not unique. Objects linked from other blend files may have the same name.

(I had to put this here to have enough characters to reply)

Ah, I see now. bpy.data.objects[ ] is looking for the name of an object, and if I had gone the next step and set the Driver’s Data Path to rotation_euler, I would have been trying to pass the rotation into it when it was looking for the name. The reason it was giving the error was that it didn’t have any name being passed into it.

To help out anyone in the future, here is the way it’s set up so that it works:

and how the working code looks with the object reference omitted:

import bpy
import math

def ShiftMoonMonth(valueToGet):
#obj = bpy.data.objects[objectName]
#sourceRotation = obj.rotation_euler.z
finalRotation = (math.floor(valueToGet/389.10)*29.10564039280042)
return finalRotation

bpy.app.driver_namespace['ShiftMoonMonth'] = ShiftMoonMonth


That’s great to know that just adding floor to the expression area works as well, batFINGER. I had thought I would need to import the math library to get it to work, which is why I went the script route in the first place. Thanks for the tip of using radians, too. That would have been very difficult trying to figure out why the calculations weren’t working with degrees. Everything is working perfectly now. :)

Thanks so much to you both for taking the time to answer it!

Is there a way to mark both of your answers as correct, or do I need to choose just one?