Python Forum
When Defining a Function with an Equation as a Default Argument, which Value Is Used?
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
When Defining a Function with an Equation as a Default Argument, which Value Is Used?
#1
I have shortened my function and code to make it easier to follow but it reflects an equivalent situation.

I am wondering when you define a function with input arguments having default values that are described as equations, where are the variables in the equations taken from my python? I shall explain with my example below.

I want the default value for y in the nested dictionaries to increase the more keys are added to the main dictionary as shown by y in the code below.

my_dict = dict()
default_sizes = [300, 100]


def create(text = "Default Text", x = default_sizes[0], y = default_sizes[1] + (10*len(my_dict))):
    local_dict = dict()
    local_dict["x_position"] = x
    local_dict["y_position"] = y
    print("Internal: ", default_sizes[1] + (10*len(my_dict)))
    return local_dict

print("Before: ", default_sizes[1] + (10*len(my_dict)))

my_dict["1"] = create()
print("My_dict[\"1\"][\"y_position\"]: ", my_dict["1"]["y_position"])
print("After 1: ", default_sizes[1] + (10*len(my_dict)))


my_dict["2"] = create()
print("My_dict[\"2\"][\"y_position\"]: ", my_dict["2"]["y_position"])
print("After 2: ", default_sizes[1] + (10*len(my_dict)))
The output of the code is as follows:

Before: 100
Internal: 100
My_dict["1"]["y_position"]: 100
After 1: 110
Internal: 110
My_dict["2"]["y_position"]: 100
After 2: 120

So as you can see when the create function is run, the len(my_dict) is calculated using the original length of my_dict above the defined function rather than the new length of my_dict. Inside the function it uses the new my_dict value but in the argument defaults it seems to use the my_dict from above the function.

Am I correct? Is there any way to fix this so the argument uses the current variables when it is called?

Thank you so much in advance for this head sore, really appreciate any help with this.
Reply
#2
default argument's are evaluated at function definition time.
If you want different value, pass it as argument when calling function, not as "new" default argument

my_dict=dict()
DEFAULT_X = 300
DEFAULT_Y = 100
def create(text = "Default Text", x=DEFAULT_X, y=DEFAULT_Y):
    local_dict = dict()
    local_dict["x_position"] = x
    local_dict["y_position"] = y
    print("Internal: ", y + (10*len(my_dict)))
    return local_dict
 
print("Before: ", DEFAULT_Y + (10*len(my_dict)))
 
my_dict["1"] = create()
print("My_dict[\"1\"][\"y_position\"]: ", my_dict["1"]["y_position"])
print("After 1: ", DEFAULT_Y + (10*len(my_dict)))
 
 
my_dict["2"] = create(y=DEFAULT_Y + (10*len(my_dict)))
print("My_dict[\"2\"][\"y_position\"]: ", my_dict["2"]["y_position"])
print("After 2: ", DEFAULT_Y + (10*len(my_dict)))
Now, I don't fully understand what you are doing, but it may be possible to do it better/cleaner, if for example using namedtuple or custom class.
Also you don't use the text param of the function
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#3
I refactored the code a litte bit.
Test it if it works as expected. Look at the differences.
Have no time to check it for myself.

my_dict = {}
default_sizes = [300, 100]
 
 
def create(text="Default Text", x=None, y=None):
    local_dict = {}
    
    if x is None:
        local_dict["x_position"] = default_sizes[0]
    else:
        local_dict["x_position"] = x
    if y is None:
        local_dict["y_position"] = default_sizes[1] + len(my_dict)
    else:
        local_dict["y_position"] = y
    
    return local_dict


for idx in range(10):
    my_dict[idx] = create()


print(my_dict)
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
Reply
#4
from collections import namedtuple

Point=namedtuple('Point', 'x y', defaults=[300, 100])

def create_points(point=Point(), step=10, number=0):
    current = 0 
    while True:
        yield Point(point.x, point.y + current * 10)
        current += 1
        if current == number:
            break


my_dict = {idx:point for idx, point in enumerate(create_points(number=10))}
print(my_dict)

points = create_points()
for i in range(5):
    print(next(points))
Output:
{1: Point(x=300, y=100), 2: Point(x=300, y=110), 3: Point(x=300, y=120), 4: Point(x=300, y=130), 5: Point(x=300, y=140), 6: Point(x=300, y=150), 7: Point(x=300, y=160), 8: Point(x=300, y=170), 9: Point(x=300, y=180), 10: Point(x=300, y=190)} Point(x=300, y=100) Point(x=300, y=110) Point(x=300, y=120) Point(x=300, y=130) Point(x=300, y=140)
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#5
By the way, the dict could be a list.
Basically you use the indices as keys.
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  mutable argument in function definition akbarza 1 425 Dec-15-2023, 02:00 PM
Last Post: deanhystad
Information How to take url in telegram bot user input and put it as an argument in a function? askfriends 0 1,033 Dec-25-2022, 03:00 PM
Last Post: askfriends
  i want to use type= as a function/method keyword argument Skaperen 9 1,776 Nov-06-2022, 04:28 AM
Last Post: Skaperen
  Conjugate Gradient having issues with defining A (function to solve [A]{x} = {b} ) DimosG 2 2,783 Sep-21-2021, 08:32 PM
Last Post: 1968Edwards
  Regex - Pass Flags as a function argument? muzikman 6 3,484 Sep-06-2021, 03:43 PM
Last Post: muzikman
  Defining a function with input abcd 5 3,037 Feb-21-2021, 02:34 AM
Last Post: NullAdmin
  Defining an object's argument whose name is stored in a variable arbiel 2 2,146 Dec-11-2020, 10:19 PM
Last Post: arbiel
  How to use a tuple as an argument of a function zarox 5 3,464 Nov-14-2020, 08:02 PM
Last Post: buran
  calling a function and argument in an input phillup7 3 2,554 Oct-25-2020, 02:12 PM
Last Post: jefsummers
  Passing argument from top-level function to embedded function JaneTan 2 2,204 Oct-15-2020, 03:50 PM
Last Post: deanhystad

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020