What is the difference between a variable and a parameter - python

I am learning python 3 and programming in general for the first time, but I can't seem to distinguish a parameter and a variable?

A variable is just something that refers/points to some data you have.
x = 5
Here x is a variable. Variables can point to more kinds of data than just numbers, though. They can point to strings, functions, etc.
A parameter is something that is passed into a function
def my_function(y):
print(y)
Here y is a parameter. It doesn't contain a value yet. But if I want to call the function, I need to provide an argument to the function.
An argument is the actual value you provide to the function that replaces the parameter.
my_function(5)
Here, 5 is the argument. Of course, since x points to the value "5", I can do this too:
my_function(x)
which also prints 5

A parameter is a variable that was received as an argument to a function. Once the function has begun executing, the parameter is just like any other variable; it can be reassigned (and stops being tied to the caller's argument) like anything else.
global_variable = ... still a variable, just defined globally ...
def foo(parameter):
function_local_variable = ... something defined locally ...
foo(... argument that is bound to parameter in foo ...)

A parameter is a type of variable that serves as the input to a method.

A variable is a name (identifier) that refers to some value. Values can be either immutable types, that is, types that cannot be changed such as strings, bytes, integers and floating point numbers:
x = 5 # immutable type
y = x # y points to what x currently points to, namely 5
x = 9 # x points to a new value, 9
print(x, y) # 9 5
A variable can also name a mutable type:
class MyType:
pass
t1 = MyType()
t1.x = 5 # set member x to 5
t2 = t1 # t2 points to the same object as t1
t1.x = 9
print(t1.x, t2.x) # 9 9
A parameter (or argument) is a value passed to a function:
def foo(x):
print(x)
foo(some_value)
x is an argument to function foo. foo(some_value) invokes function foo with the value some_value as the actual value. The Python interpreter implicitly assigns x = some_value at the entry to function foo. Note that x is a variable is every sense of the word but that it is defined in the scope of foo so that it hides any other definition of x that may exist outside of foo.

Related

Trying to understand in Python 3.7 how to get a number returned from a function to the main program

In general terms, I cannot get any function to return a value inside a variable (an integer, back to the main program. I have included the variable name as one of 2 arguments in the function (in this case mod_stone_value), and am using the return command to hopefully return that integer value to the main program, where that value is then added to a total value.
The key lines of code in the function would be:
def calc_real_stone_value(base_stone_value, mod_stone_value):
return mod_stone_value
and then, back in the main program:
total_stone_value = total_stone_value + mod_stone_value
The variable total_stone_value ends up being 0, yet non-zero values of mod_stone_value do print inside the function. I know I am doing something fundamentally wrong, but have no idea what it is.
If I understand correctly, you want to use the number value returned by the function calc_real_stone_value and are confused as to why it is not changing after you call your function which supposedly "updates it's value".
The fundamental thing you are misunderstanding is that primitive data types (double, int, char, etc.) are passed by value, not by reference. Therefore, if you make changes to the local variable mod_stone_value within the function, the changes will not show in the variable that exists outside the function. If you want to use the value you are returning with the line return mod_stone_value you need to call the function with the variables you want to be used in the calculations and then assign that value to a variable (mod_stone_value in this case).
Example:
base_stone_value = 1
mod_stone_value = 4
def calc_real_stone_value(base_stone_value, mod_stone_value):
# calculations
# e.g. add the two integer arguments
mod_stone_value += base_stone_value
return mod_stone_value
# print the values for mod_stone_value
print(mod_stone_value)
# call function and assign value to mod_stone_value
mod_stone_value = calc_real_stone_value(base_stone_value, mod_stone_value)
print(mod_stone_value)
Output:
4
5
Conclusion:
Primitive variables are passed by value and in order to retrieve the value from a function that returns an integer for example, it needs to be re-assigned.
To reduce confusion, you can avoid using variable names that shadow variable names from an outer scope.
Using your code as a template, here is an example that illustrates passing a value from "inside" the function to the outer level (here, the outermost level of the program). I would recommend reading this part of the official Python tutorial (or from the beginning if it does not make sense) as it describes concepts (e.g. global vs. local variables) that are relevant to your problem.
c = 0
d = 5
e = 2
def foo(a, b):
# insert whatever code here
d = 10
print(f"Inside foo(), d has value {d}")
# to match your example
return b
# c has the value 0, d has the value 5
print(f"(c, d) has the value ({c}, {d})")
# call function and pass return value to c
c = foo(d, e)
# c has the value 2, d has the value 5
print(f"(c, d) has the value ({c}, {d})")
By the way, regarding your code, statements inside the body of the function should be indented. This includes the return statement.

Python interpreter sequence with a function [duplicate]

Suppose I have a Python function foo which takes a default argument, where that default is set to some global variable. If I now change that global variable before calling the function, the default argument is still set to the original value of that global variable.
For example:
x = 1
def foo(a=x):
print a
x = 2
foo()
This prints 1, instead of 2.
How should I be writing my code, so that I can change this global variable, and have it update this default argument?
A default variable is only evaluated and set once. So Python makes a copy of the reference and from then on, it always passes that reference as default value. No re-evaluation is done.
You can however solve this by using another object as default object, and then use an if statement to substitute it accordingly. Something like:
the_default = object()
x = 1
def foo(a = the_default):
if a is the_default:
a = x
print a
x = 2
foo()
Note that we use is to perform reference equality. So we check if it is indeed the default_object. You should not use the the_default object somewhere else in your code.
In many Python code, they use None as a default (and thus reduce the number of objects the construct). For instance:
def foo(a = None):
if a is None:
a = x
print a
Note however that if you do that, your program cannot make a distinction between a user calling foo() and foo(None) whereas using something as the_object makes it harder for a user to obtain a reference to that object. This can be useful if None would be a valid candidate as well: if you want foo(None) to print 'None' and not x.

Same variable names but with different values within two seperate "def" functions. Can they not change down the code somehow?

Short example:
def Tk1():
x = 1
def Tk2():
x = 2
I want "x" to not change down the code into the subsequent variable. Can I have both "x" assigned to different values and not mess up the code within the def?
Yes a variable that is defined in the function, will always stay the same in that specific function, however if you define it outside the two functions the value can change depending on which function you call first:
a = 0
def f_a():
a = 10
return a
def f_b():
a = 4
return a
print(f_a())
print(f_b())
Will return this result:
10
4
The way you showed in your question defines the variable inside the function meaning it is local to that specific function. Note the fact it isn't a global variable.

When defining a lambda function with a variable inside, how to prevent changes in function when I change the variable?

For example: in this code, function changes when the variable changes. I would like to learn how to prevent the change in function behaviour when i change the variable. Is there some way to only get the value of the variable instead of the variable itself? Also are there any sources where I can learn more about problems like this?
a = 5
adder = lambda x: x + a
print(adder(5)) # prints 10
a = 50
print(adder(5)) # prints 55
Just like the equivalent function defined by a def statement (which is what you should be using, rather than assigning the result of a lambda expression to a name explicitly)
def adder(x):
return x + a
the name a isn't looked up until the function is called.
One way to make a function that specifically computes x + 5 when a == 5 at definition time is use a default argument value:
def adder(x, a=a):
return x + a
where the left-hand a is a new parameter (which isn't intended to be set explicitly), and the right-hand a is the value of the a in the current scope.
A better idea, though, is to define a closure, so that your function doesn't have a "hidden" parameter that can be abused.
# This is where a lambda expression does make sense: you want
# a function, but don't need to give it a name.
def make_adder(a):
return lambda x: x + a
adder = make_adder(5)
a in adder is still a free variable, but now it refers to a variable in a scope which you don't "outside" access to after make_adder returns.

Python - by value and by reference function arguments [duplicate]

This question already has answers here:
Why can a function modify some arguments as perceived by the caller, but not others?
(13 answers)
Closed 4 years ago.
Sorry if the title is not accurate, not sure how to name it properly.
the question is. If I do this code:
num = 1
def test_func2(arg):
arg = 10
test_func2(num)
print(num)
The num will obviously stay 1
But if I do similar thing with objects
class TestClass:
def __init__(self):
self.one = 1
self.two = 2
test_obj = TestClass()
def test_func(arg):
arg.one = 10
test_func(test_obj)
print(test_obj.one)
The value of test_obj.one will change to 10. Why are integers passed by value and user defined objects by reference?
In the first case, num refers to the integer object of value 1. Passing it to a function assigns arg to also refer to the same integer object of value 1, but then arg is reassigned to a new integer object of value 10. num is still referring to the original integer object of value 1.
In the second case, test_obj as assigned the value of a new TestClass instance. Passing it to a function assigns arg to the same TestClass instance. The object itself is altered, and both arg and test_obj still refer to the same object, so even after the function returns, test_obj "sees" the change.
This happens because -
In first case, after passing a variable to a function test_func2(num), that value like will be caught in a local variable arg, whose scope is local to the function. After we return from function that variable is destroyed as the function has ended its execution.
num = 1
def test_func2(arg): // arg catches value 1 here
arg = 10 // arg variable changed to 10 but this value is not reflected back to num variable
// so num is still 1
test_func2(num) // function called with variable
print(num) // that's why 1 gets printed here
And when you pass object to the function test_func(test_obj), the arg in function will be a reference to the object it catches i.e., test_obj. That means after modifying arg.one = 10 you are actually modifying the original objects value i.e., test_obj.one = 10.
def test_func(arg): // arg points to test_obj
arg.one = 10 // actually changing test_obj.one
test_func(test_obj) // function called with object
print(test_obj.one) //that's why 10 gets printed here

Categories