Little help needed with Python

Hello all,

I am trying to alter a Python script a little bit.
The script overrides dimension values which works great.
I want to edit the script so a user can choose wether the script: overrides the value of the dimension, Adds a value below the dimension, or adds a value above dimension (dim.ValueOverride, dim.Above, dim.Below)

IN[6] was apointed for this and is called ‘positie’
If i change ‘dim.ValueOverride’ to ‘Positie’ in line 24 of the script, nothing happens.

I bet this is just a very simple issue that starts and ends with my lack of understanding of Python…

Anyone who can help me out?
Attatched screenshot below for clarification:

# Enable Python support and load DesignScript library
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

doc = DocumentManager.Instance.CurrentDBDocument

# Functions
def getForm(dim, brick, brickN, seam, seamN):
	val = round(dim.Value * ftmm)
	x = str(int(round(val / brick)))
	if val % brick == seam:
		form = x + brickN + " + " + seamN
	elif val % brick == brick - seam:
		form = x + brickN + " - " + seamN
	elif val % brick == 0:
		form = x + brickN
	else:
		form = str(int(val // brick)) + brickN + " + " + rest
	dim.ValueOverride = form
	return form


# The inputs to this node will be stored as a list in the IN variables.
if isinstance(IN[0],list):
    	allDims = UnwrapElement(IN[0])
else:
    	allDims = [UnwrapElement(IN[0])]
brick = IN[1]
seam = IN[2]
brickN = IN[3]
seamN = IN[4]
ftmm = 304.8
rest = IN[5]
Positie = IN[6]

forms = []
TransactionManager.Instance.EnsureInTransaction(doc)
for dims in allDims:
	if dims.Value == None:
		form = []
		for dim in dims.Segments:
			form.append(getForm(dim, brick, brickN, seam, seamN))
		forms.append(form)
	else:
		form = []
		form.append(getForm(dims, brick, brickN, seam, seamN))
		forms.append(form)
TransactionManager.Instance.TransactionTaskDone()

OUT = forms`Preformatted text`

Two problems:

  1. You’re defining your variable, Positie, after calling it in the defining function. Variables should always come first.

  2. You’re providing a string. You cannot use a string as code. Rather than providing “the code” you want, you’ll want to use a switch to determine which code you run. I’d advise something like “Override”, “Above”, and “Below” for the three switches. Then you create three separate loops for

if Positie == [switch]: 
    [supporting code]

so that the ValueOverride code runs when you supply the “Override” string and the other functions run when you supply their respective switches as well.

2 Likes

Thank you Nick, for your very clear explanation!
I have changed my script with your suggestions and it worked on the first try :slight_smile:
Thanks again!

Glad to hear, however, I misspoke a bit. I missed that you were defining your variable within a new function.

The variables that you define in your function are not the same variables that you use to call that function (even if they have the same names). So it actually didn’t matter that your function came before the input variable was defined - they were being considered separately. This also means that your function wouldn’t have updated anyway. For this reason, it’s best to use different names when defining the function and calling it.

That doesn’t actually matter when you write separate loops for the different conditions, but I thought I’d clarify.

I think you have lost me unfortunately…
I am really really new to python and used a script I found on this forum :slight_smile:

Would yo mind describing what you mean with a screenshot of the script perhaps?
I would like to understand what you are saying but it’s rather hard without visual aid…

Please only if you don’t mind to do so! You have already helped me out a lot

Hopefully this quick example proves my point:
image
Here’s what you’d expect. I define the function with inputs val1 and val2 and also call the function with the same inputs.

image
If I define the function with inputs val1 and val2 but call the function with val2 and val1 my output matches the called function, not the original inputs of the definition. This is because the defined inputs are only used as variables when defining the function - they’re essentially placeholders. The order of the inputs is what matters, not the name.

image
You can best see it here, where the defined function uses val1 and val2 but the called function uses a and b. Variables a and b are defined for my code when I call the function, val1 and val2 are just for the definition.

3 Likes

Thats a very clear example!
Thank you very much!!

1 Like