Q:

I can't decrement N, but I can use it when evaluating logic. Can someone explain this?

Increment is defined as:
def increment(x):
    return x + 1

The following works, and spits out a result of 8:
def repeated(f, n): 
    def h(x):
        counter = 0
        while counter < n:
            x = f(x)
            counter += 1
        return x
    return h
addthree = repeated(increment,3)
addthree(5)

The following code errors and tells me that i am referencing n before assignment:
def repeated3(f,n): 
    def h(x):
        total=0
        while n != 0:
            total = f(x) + total
            n -= 1
        return total
    return h
addthree = repeated(increment,3)
addthree(5)

why does the error throw when i try to decrement n, even though i am allowed to  use it in the logic statement that precedes it?

A:

When functions are nested, the use of an argument or variable of an outer function in an inner function is called a closure.  
Python closures are read only
So, if you want to use a decrement loop, you will need to copy the repetition argument to a writable local variable.
In [10]: def r(f,n):
   ....:     def h(x):
   ....:         total = 0
   ....:         m = n
   ....:         while m!=0:
   ....:             total += f(x)
   ....:             m -= 1
   ....:         return total
   ....:     return h
   ....: 

In [11]: r(increment, 3)(0)
Out[11]: 3

This isn't a problem with the previously posted incrementing repeated() function code because although there the repetitions argument n is also a closure, it is used read-only in a comparison and not written to.

A:

The first function works as you are not assigning/mutating n to a new value, using n -= 1 you are assigning n to a new value so you are creating a local variable n not using the n from the outer function so you end up with a  local variable 'n' referenced before assignment error as n is not defined when you use while n != 0: in the local scope.
In python3, you can use the nonlocal keyword:
def repeated3(f, n):
    def h(x):
        nonlocal n
        total = 0
        while n != 0:
            total = f(x) + total
            n -= 1
        return total
    return h

If you are using python2 you could  reassign a new variable to point to n and use that or use a dict:
def repeated3(f,n):
    n = {"n":n}
    def h(x):
        total = 0
        while n["n"] != 0:
            total = f(x) + total
            n["n"] -= 1
        return total
    return h
addthree = repeated3(increment,3)
addthree(5)

You could also make it a function attribute:
def repeated3(f,n):
    repeated3.n = n
    def h(x):
        total = 0
        while repeated3.n != 0:
            total = f(x) + total
            repeated3.n -= 1
        return total
    return h
addthree = repeated3(increment,3)

There are numerous other workarounds but the main point is you can read but not mutate the closure variable and creating n in your local scope is going to cause  n to become a local variable meaning the while n != 0 is looking for n in the local scope so you get the referencing n before assignment:

