1

So I am seeing really strange behavior from my python code and couldn't find any other examples of my problem. From what I've read of python, a function can only access variables that are either global or inside it. However, I've discovered in the following snippet that the two print statements return different results even though the variable 'density' is never returned by the function and isn't declared globally.

def findHeight(density):
  print density
  height = integrateHeight(density, cutOff)
  print density
  return height

This is a real pain in the a** because it is messing up code later on in the script.

I am using python 2.7.6 and my function definition is as follows:

def integrateHeight(data, cutOff):
  # accumulate data values and rescale to fit interval [0,1]
  # Calculate bin widths (first one is a different size from the others)
  data[0,1] = -2*data[0,0]*data[0,1]
  data[1:,1] = (data[2,0] - data[1,0])*data[1:,1]
  # accumulate distribution and divide by the total
  data[:,1] = np.cumsum(data[:,1]) / data[:,1].sum()

  # Assign a default height value
  height = data[0,0]
  # store the first height,fraction pair
  prev = data[0]
  # loop through remaining height,fraction pairs
  for row in data[1:]:
    # check that the cut-off is between two values
    if row[1] > cutOff >= prev[1]:
      # Interpolate between height values
      height = interpolate(cutOff, prev[::-1], row[::-1])
      # exit the loop when the height is found
      break
    # store the current height,fraction value
    prev = row

  return height

This particular script is supposed to take a distribution, accumulate it, and find the height corresponding to a certain fraction of the cumulative distribution.

3
  • "a function can only access variables that are either global or inside it." That's something of an oversimplification. For example, a function can also mutate the arguments you pass to it, which seems to be what's happening here. What is the type of the density object? Maybe you can make a deep copy of it and pass that instead. Commented Jan 28, 2016 at 16:44
  • data[0,1] = ... is a much different operation from data = .... The former invokes data.__setitem__, the latter changes what the name data points to. Commented Jan 28, 2016 at 16:49
  • density is a numpy.ndarray object. I used the numpy.copy method when I passed it to integrateHeight and it now works as intended. Commented Jan 28, 2016 at 17:30

1 Answer 1

3

The variable isn't being modified, the object you passed to integrateHeight is being modified. This is normal. If you don't want integrateHeight to mutate its inputs, write it in such a way that it doesn't mutate its inputs. To do so, you'll probably need to make a copy of it in the function, or find some other way to perform the computation without mutating the object.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.