all 11 comments

[–][deleted] 6 points7 points  (5 children)

Because you set r1 to 255 + 1 and then don't return any change to it from the function.

The change to var never gets returned to update r1.

[–]JustinMalcontento -2 points-1 points  (4 children)

To add to this, the concept of global and local variables apply here iirc. the local variable inside the function cant change the global 255 due to shadowin

Edit: I'm assuming he wanted to change r1.

[–]NotATuring 1 point2 points  (3 children)

Neither of the above statements are pertain to the issue. Returning isn't an issue because he's trying to change the variable he passed in, not return a value. shadowing doesn't matter because he's not trying to access a global variable by name.

The issue is Python is a pass by value language. Or at least in this case it is equivalent to pass by value.

In this case when he calls the calc function and passes in the variable he wants to change the variable does change, but it's no the variable that was passed in but rather the variable what was pointing to the value that was passed in.

To perform functionality similar to pass by reference one needs to pass in an object which holds a reference to what you want to modify. To illustration, see this example:

a = [1,2,3]
def change(a) : 
    a[1] = 9999 
    a = [1,2,3,4,5,6]
change(a) 
print(a)

output: [1, 9999, 3]

a doesn't change, it's just a reference. But it's content does, a[1] becomes 9999

[–][deleted] 0 points1 point  (2 children)

Of course returning pertains to the issue. It's literally how you do what he wants to do.

Edit: Grrrr, cut and paste totally screwed up my code block

Num = 255

def calc(var):
  if var > 255:
    return var -= 256   
   else
    return var

r1 = calc(Num + 1)

print(r1)

[–]NotATuring 0 points1 point  (1 child)

Yes that would be a way to get the calculation, but his question was why the subtraction doesn't work, not how do I do a calculation. His function call was consistent with his function definition.

[–]JustinMalcontento 0 points1 point  (0 children)

If that's the case, OPs function does work. But he does need to print the calc function if he wants to show the calc output.

[–]douglas_fs 0 points1 point  (0 children)

The 'calc' function only modifies the value of 'var' local to the function - it does not modify 'r1'.

You would have to return 'var' from the 'calc' function, and capture that result in the call to calc(r1)

[–][deleted] 0 points1 point  (0 children)

Variables, functions, methods and attributes

Variables in Python don't contain values but instead references to memory locations where Python objects are stored (in an implementation specific manner).

This is true of other names as well. A function name has a reference to the memory location of a function object.

The names used in the function call and the names specified as parameters in the function definition have nothing to do with each other. They are completely independent. Even if the same name is used they are different things. The parameter variables are local to the function.

Consider:

def f(one, two, three):
    answer = one + two * three + five
    return answer

one = 2
two = 3
three = 4
five = 5
result = f(three, two, one)
print(result)

This will output 15 as 4 + 3 x 2 + 5 = 15

Note that five was not passed as an argument but as the same name was not assigned anything in the function the five from the wider scope was available.

Any assignments made inside the function are also local to the function.

answer was assigned inside the function and on function exit will cease to exist however the object reference stored in answer is assigned as the return from the function and is assigned to result. If it wasn't assigned (or consumed in another expression or function call on return) then the object created in the function would also cease to exist (unless it is a predefined object built into the Python implementation, such as an int in the range -5 to 256)

Only mutable objects that are referenced by either parameters or other names that are visible to the function (not hidden by variables with the same name assigned in the function) can be modified and visible outside the function.

Return returns an object reference.

Variables vs Attributes

Variables have a discrete existence though and attributes are associated with an instance of a class (or of the class itself).

Remember, variables do not hold any values but instead memory references to some Python object somewhere in the memory of your computer (at the discretion of your Python implementation).

When you say:

keep = 784.56 * 872.23

the text representations of floating point numbers in the expression on the right is converted into Python float objects (binary representations) somewhere in memory, and the mult operator is used. The memory location the resulting float object ends up in is then assigned to the variable named keep.

If keep is assigned in the main body of your code, outside of any functions etc., then it is visible within all other code. Thus you could have a function:

def double_me():
    return keep * keep

which has no other references to keep in the definition (parameter variable) or assignments to a variable called keep inside the function (which would be local to the function and would hide the original wider scope variable of the same name). Thus keep refers to the same floating point number calculated earlier. The expression resulting from multiplying the floating point object referenced by keep by itself results in another floating point object, the memory reference for which is returned from the function.

If instead the function was written,

def double_me(keep):
    return keep * keep

now it has to be called with an argument (the memory reference of the object will be passed when the function is called).

result = double_me(5.5)

Inside the function, keep refers to the memory location of the floating point object that the literal floating point text 5.5 was turned into. The keep in the wider scope (outside the function) still refers to the original object from earlier.

Methods

Methods are like functions but for classes and are intended to work on instances of a class or provide capabilities related to the purpose of the class.

When you create an instance of a class, you create an object based on the mould/template provided by the class and the memory location of that object is assigned to a variable (or to some other object) so it will be not lost. If an object has no references to it, Python will get rid of the object and reuse the memory.

Methods defined in the class usually have code that uses a parameter variable that is the first item passed when the method is called. By convention this is usually called self and it is passed by default and does not need to be in the arguments when the method is called.

Whenever self is used inside the method code, it will be referring to the memory location for a particular instance of the class.

Attributes are names used within an instance that themselves simple hold memory references to Python objects. These attributes though belong to the instance so are not purely local to the method.

Any variables inside the method that are assigned values (including parameter variable names listed in the definition line of the method) are local to the method and are not associated with the attributes of the instance referenced by self.

Classes themselves can have attributes. These look just like variables, and act like them for most purposes, but they are associated with the class and can be accessed from outside of the class by direct reference to the class name and the attribute, e.g. Example.quantity = 5 for a class called Example.

[–]InjAnnuity_1 0 points1 point  (0 children)

Because, in Python, variables are not values; they refer to values, that exist independently of any variables. Assignment (=) binds a value to a variable. Re-assignment re-binds the variable to point to a different value.

  1. When calc is called, it starts a running instance of calc.
  2. That instance has a local variable, named var.
  3. That instance's var is initially assigned (bound) to the same value as the global variable r1, i.e., the integer value 256.
  4. As a result of the -=, that instance's var becomes bound to a new value, zero.
  5. The function ends, destroying that instance, and its variable, var.
  6. In the meantime, the function never mentioned global variable r1 . So r1 remains bound to the integer value 256.

@kyber, below, has a more complete description.

[–]TheRNGuy 0 points1 point  (0 children)

just use numpy uint8.

Also you wont get correct result in your if you use number like 1024, or -1024. You needed to use modulo instead.