Here I have written a function which takes two lists as argument. But when I called this function passing one list as argument, it works well! Why is this working? Here name_function has two arguments but I passed only one list as argument.
def name_function(names=list(),_list=list()):
for name in names:
_list.append(name)
return _list
print(name_function(['mike','smith','bob']))
Here in the function definition you have initialized both the
arguments with the empty list i.e. you are using two default
arguments in the function definition.
For the above reason the function call works if you provide provide
both the arguments or any one of the arguments or no argument at
all.
To learn more about default arguments in python you can refer this
link or this link.
Related
I have a function that performs a specific task, and this function takes many options, both named and unnamed options. For example:
def eat_fruit(x,a_number=None , a_fruit=None):
return(f'{x} ate {str(a_number)} {a_fruit}')
#call the function
eat_fruit("John",a_number=5,a_fruit='apples') #outputs 'John ate 5 apples'
Now, I have another function that takes many options, for example:
def do_lots_of_stuff(a,b,activity_1=None,activity_2=None):
return(f'''{a} and {b} {activity_1} and {activity_2}''')
do_lots_of_stuff("Bob","Mary",activity_1='run',activity_2='jump') #returns "Bob and Mary run and jump"
I want to have the function do_lots_of_stuff call the function eat_fruit, sometimes with options. However, it is not clear to me how to pass options from one to the other in a straightforward manner.
Ideally, I am looking for something like:
#This code does not work; it demos the type of functionality I am looking for.
do_lots_of_stuff("Bob","Mary",activity_1='run',activity_2='jump', eat_fruit_options={*put_options_here*}):
eat_fruit(eat_fruit_options)
return(f'''{a} and {b} {activity_1} and {activity_2}''')
Note that this can't be accomplished via do_lots_of_stuff(*do_lots_of_stuff_options*, *eat_fruit_options*) since options for eat_fruit are not valid do_lots_of_stuff options. Furthermore, keyword arguments must come after positional arguments. In addition this solution does not seem to be sufficient here, because I only want to pass some arguments, not all of them.
Other relevant links (although I don't believe they successfully address my question):
can I pass all positional arguments from one function to another in python?
Passing variables between functions in Python
Passing value from one function to another in Python
do_lots_of_stuff("Bob","Mary",activity_1='run',activity_2='jump', eat_fruit_args=["John"], eat_fruit_kwargs={"a_number": 5, "a_fruit": "apples"}):
eat_fruit(*eat_fruit_args, **eat_fruit_kwargs)
return(f'''{a} and {b} {activity_1} and {activity_2}''')
You can pass and forward arguments and keyword arguments. Arguments are in the form of a list. Keyword arguments (kwargs) are in the form of a dictionary, with the key as a string, and the value as the correlating keyword value.
Apparently, if you need to use both keyword and positional arguments while calling your function, you have to use the positional argument first. But the following code results in an error;
def greet(first_name, l_name):
print(f'Hi, {first_name} {last_name}!')
greet('Holmes',
first_name='Harry')
So does it mean that if you're using both, you have to use the positional argument first in the required order, and only then the keyword argument?
Positional arguments must be passed in order as declared in the function. So if you pass three positional arguments, they must go to the first three arguments of the function, and those three arguments can't be passed by keyword. If you want to be able to pass the first argument out of order by keyword, all your arguments must be passed by keyword (or not at all, if they have defaults).
If it helps, Python's binding mechanism is roughly:
Assign positional arguments one by one to sequential parameters of the function. These parameters are now set.
Assign keyword arguments to remaining parameters in any order. If one of the keyword arguments matches an argument already assigned positionally (or the same keyword argument is passed twice), it's an error.
In your case, what this means is that:
greet('Holmes', first_name='Harry')
first binds 'Holmes' to first_name. Then it saw you tried to pass first_name again as a keyword argument and objected.
I have some questions about the following code fragments:
>>> def init_weights(m):
print(m)
if type(m) == nn.Linear:
m.weight.data.fill_(1.0)
print(m.weight)
>>> net = nn.Sequential(nn.Linear(2, 2), nn.Linear(2, 2))
>>> net.apply(init_weights)
apply() is part of the pytorch.nn package. You find the code in the documentation of this package. The final questions:
1. Why does this code sample work, although there is no argument or brackets added to init_weights() when it is given to apply()?
2. Where does the function init_weights(m) gets its argument m from, when it's given as a parameter to the function apply() without brackets and an m?
We find the answers to your questions in said documentation of torch.nn.Module.apply(fn):
Applies fn recursively to every submodule (as returned by .children())
as well as self. Typical use includes initializing the parameters of a model
(see also torch-nn-init).
Why does this code sample work, althouh there is no argument or brackets added to init_weights() when it is given to apply()?
The given function init_weights isn't called prior to the apply call, precisely because there are no parentheses, rather a reference to init_weights is given to apply, and only from within apply later on init_weights is called.
Where does the function init_weights(m) gets its argument m from, when it's given as a parameter to the function apply() without brackets and an m?
It gets its argument with each call within apply, and, as the documentation tells, it is called for m iterating over every submodule of (in this case) net as well as net itself, due to the method call net.apply(…).
Python has classes for Tkinter variables StringVar(), BooleanVar(), etc. These all share the methods get(), set(string), and trace(mode, callback). The callback function passed as the second argument to trace(mode, callback) is passed four arguments, self, n, m, x.
For an example of a BooleanVar() these appear to be '', 'PYVAR0', 'w'.
The third argument x appears to be the mode that triggered the trace, in my case the variable was changed. However, what is the first variable that appears to be an empty string? What is the second, if I had to guess I'd say some internal name for the variable?
The first argument is the internal variable name. You can use this name as an argument to the tkinter getvar and setvar methods. If you give your variable a name (eg: StringVar(name='foo')) this will be the given name, otherwise it will be a name generated for you by tkinter (eg: PYVAR0)
If the first argument represents a list variable (highly unlikely in tkinter), the second argument will be an index into that list. If it is a scalar variable, the second argument will be the empty string.
The third argument is the operation, useful if you are using the same method for reading, writing and/or deleting the variable. This argument tells you which operation triggered the callback. It will be one of "read", "write", or "unset".
Tkinter is a python wrapper around a tcl/tk interpreter. The definitive documentation for variable traces can be found here: http://tcl.tk/man/tcl8.5/TclCmd/trace.htm#M14. Though, this only documents how the internal trace works, the tkinter wrapper sometimes massages the data.
The first argument is the name of the variable, but is not "useless" since you can set it when you declare the variable, e.g.:
someVar = IntVar(name="Name of someVar")
When you check the first argument in the trace callback it will equal "Name of someVar". Using the name to distinguish between variables, you can then bind the same handler to trace changes to any number of variables, rather than needing a separate handler for each variable.
Can someone explain call by name, reference, and value in depth and also compare them to each other?
Simple examples would be great as well. I am really focused on call by name, it feels like it's very similar to call by reference.
call by name : in call by name actual argument is not evaluated at the place of function calling rather they replace all the instance of corresponding formal parameters in text.
Actual argument are evaluated as many times as required.
Actual argument are evaluated within "caller" environment (if needed) :