Calling functions without recalling all variables

  • Context: Python 
  • Thread starter Thread starter member 428835
  • Start date Start date
  • Tags Tags
    Functions Variables
Join the discussion
Ask a follow-up here, or get your own question answered by working scientists, mathematicians and engineers — people, not an autocomplete.
Real named experts · corrections over time · the nuance an AI answer skips
19 replies · 2K views
member 428835
Hi PF

Given the following

Python:
def f1(var1, var2):
    var3 = var1 + var2
    return var3

def f2(var1, var2, var4)
    var4 = 10
    var5 = f1(var1, var2)*var4
    return var5

it is obvious function f2 does not explicitly need variables var1 and var2. However, it needs the result of f1, which relies on var1 and var2. Is there a way to write the f2 function without having to pass into it var1 and var2? Could this be handled better with classes?
 
Physics news on Phys.org
Well, 'var4' doesn't seem to be doing anything useful.
 
hmmm27 said:
Well, 'var4' doesn't seem to be doing anything useful.
typo, my bad. but you get the idea
 
<shrug> something like...

Code:
/* not python'y but you get the idea */

def f1(a,b)
return a+b.

def f2(c,d)
return c*d.
.
.
.
w = f2(f1(x,y),z)
 
Last edited:
If your objection is that f2 does not need to know the values of var1 and var2, then you are correct that you could use a class to hide those values away from f2. This is called "information hiding". It is a key idea of Object Oriented Programming. Of course, even with a class, those variables must be set somewhere before f2 calls f1. The concept makes the most sense in examples where the hidden information belongs to an object that "owns" the information and is the only thing that really needs to know or manipulate that information.
 
  • Like
Likes   Reactions: member 428835 and Wrichik Basu
Here's a simplified version of the code from post #1, with extraneous variables and parameters removed:
Python:
def f1(var1, var2):
    return var1 + var2

def f2(var1, var2):
    return 10 * f1(var1, var2)
Since f2 is essentially a composite function (using math terminology), and f1 takes two parameters, then f2 also needs to take two parameters.

Note that it's possible to return an expression directly without have to first store the value of that expression in a variable.
 
  • Love
Likes   Reactions: Vanadium 50
Vanadium 50 said:
Doesn't it? It gets set to 10 every time f2 is called. Presumably, that's the intent.
Ah, so Python uses global variables... then why bother passing parameters ?
 
Last edited:
hmmm27 said:
Python uses global variables
var4 isn't a global variable; it's a local variable in function f2.

hmmm27 said:
why bother passing parameters
For the same reason we use functions with parameters in other languages that have global variables (which is pretty much all of them): because there are a lot of good reasons not to use global variables for everything.
 
Vanadium 50 said:
It gets set to 10 every time f2 is called. Presumably, that's the intent.
If it's going to be 10 every time, var4 could be eliminated and "10" could be put in the line where var4 appears as a factor.
 
Vanadium 50 said:
f2 sets it to 10. But f3 could set it to some other value.
f3 can't set it to anything. It's a local variable inside f2. f3 could pass a value for it other than 10 to f2, but that wouldn't matter, f2 would still overwrite it to 10.
 
  • Like
Likes   Reactions: pbuk
Vanadium 50 said:
f2 sets it to 10. But f3 could set it to some other value.

If you want to say relying on side effects is bad coding, I agree with you. But side effects are still real.
I think you are missing the point that there is no side effect because var4 = 10 in f2 creates a new local variable var4.

Python scalars are not passed by reference.
 
Vanadium 50 said:
Isn't Python pass by reference?
Not the way you mean. At the C level, yes, every Python object is ultimately a pointer; but the way the pointers are handled for function parameters make the behavior the same as pass by value in other languages. In Python there is no such thing as pass by reference as it exists in other languages; the only way to get that kind of functionality in Python is to pass a mutable object as a parameter and have the function mutate it (for example, setting items in a container or setting attributes on an object).
 
pbuk said:
var4 = 10 in f2 creates a new local variable var4.
It doesn't create the local variable because that local variable already exists as a function parameter. But it does force the object bound to that local variable to be a Python int object with the value 10, regardless of what object was bound to that parameter when the function was called.
 
PeterDonis said:
It doesn't create the local variable because that local variable already exists as a function parameter. But it does force the object bound to that local variable to be a Python int object with the value 10, regardless of what object was bound to that parameter when the function was called.
I appreciate the distinction between "creates a new local variable" and "creates a new integer object and binds it to the symbol with local scope created by the declaration in the parameter, overwriting the existing binding", but I am not sure it is completely relevant here so I opted for brevity.
 
FactChecker said:
If your objection is that f2 does not need to know the values of var1 and var2, then you are correct that you could use a class to hide those values away from f2. This is called "information hiding". It is a key idea of Object Oriented Programming. Of course, even with a class, those variables must be set somewhere before f2 calls f1. The concept makes the most sense in examples where the hidden information belongs to an object that "owns" the information and is the only thing that really needs to know or manipulate that information.
Thanks so much! This helps a ton! Below is a good example of what I was trying to do (which I was able to do after reading your comment).

Python:
class maths:
    def __init__(self, var1, var2):
        self.var1 = var1
        self.var2 = var2

    def f1(self):
        var3 = self.var1 + self.var2
        return var3

    def f2(self, var4):
        var5 = var4 * self.f1()
        print(var5)

if __name__ == "__main__":
    obj1 = maths(5,7)
    obj1.f2(4)
 
  • Like
Likes   Reactions: FactChecker
joshmccraney said:
Thanks so much! This helps a ton! Below is a good example of what I was trying to do (which I was able to do after reading your comment).

Python:
class maths:
    def __init__(self, var1, var2):
        self.var1 = var1
        self.var2 = var2

    def f1(self):
        var3 = self.var1 + self.var2
        return var3

    def f2(self, var4):
        var5 = var4 * self.f1()
        print(var5)

if __name__ == "__main__":
    obj1 = maths(5,7)
    obj1.f2(4)
Just don't get too carried away with it. I have seen very simple algorithms turned into obscure code because everything was hidden away. It takes some wisdom and experience to balance the benefits and the cost.
 
  • Like
Likes   Reactions: member 428835