Understanding positional arguments in Python - python

For the following Python script:
from sys import argv
script, input_encoding, error = argv
def main(language_file, encoding, errors):
line = language_file.readline()
if line:
print_line(line, encoding, errors)
return main(language_file, encoding, errors)
def print_line(line, encoding, errors):
next_lang = line.strip()
raw_bytes = next_lang.encode(encoding, errors=errors)
cooked_string = raw_bytes.decode(encoding, errors=errors)
print(raw_bytes, "<===>", cooked_string)
languages = open("languages.txt", encoding="utf-8")
main(languages, input_encoding, error)
Looking at the main function I do not understand the following line:
print_line(line, encoding, errors)
Why are we calling the print_line function and passing arguments to it that are named exactly the same as its parameters?
print_line()
When I attempt to call the print_line() argument without passing arguments Python is outputting:
print_line() missing 3 required positional arguments: 'line',
'encoding', and 'errors'

OP: print_line() missing 3 required positional arguments: 'line', 'encoding', and 'errors'
The error is obvious since it is the way the function print_line() was defined.
Furthermore:
def print_line(line, encoding, errors):
print(line, encoding, errors)
line = 1
encoding = 2
errors = 3
print_line(errors, encoding, line)
OUTPUT:
3 2 1
Note: It is positional, not naming arguments
EDIT: 1
def abc(a,b,c=2):
return a+b+c
abc(1,2) #both positional argument and c is default
5
abc(2, b=3) # positional, named and again c is default
7
abc(a=2,b=4) # both named argument and c is default
8
EDIT 2:
OP: What is the purpose of a positional argument please?
Well ..
Short answer: A positional argument is any argument that's not supplied as a key=value pair.
To understand what that means, unfortunately, is somewhat involved.
The term "argument" is used somewhat imprecisely throughout the programming community and especially in Python documentation.
Technically arguments are what you pass into functions and parameters are what you define as the names/placeholders for those arguments.
So, when I define a function thus:
def foo(a,b):
return a+b
... and call it like so:
foo(1,3)
... then a and b are my parameters while 1 and 3 are arguments for a given call to that function.
Now this is a quibble. People will often refer to a and b as "arguments" to their function when they are actually the names (parameters) which will contain the arguments while the function is executing.
Now, with this point made, understand that Python supports four classes of parameters: "required positional" (the kind you've seen for just about any other programming language), "optional" ... or "defaulted" ... positional parameters with some default value specified, "star args" (similar to the VARARGS support in some other languages such as C/C++ and Java), and "kwargs."
The latter is almost unique to Python (though Ruby has very similar support).
So you can define a function with a parameter list like:
def bar(a, b, c=None, d=[], *e, **opts):
'''bar takes all sorts of arguments
'''
results = dict()
results['positional 1'] = a
results['positional 2'] = b
results['sum']=a+b
results['optional'] = list()
for each in e:
results['optional'].append(each)
if c is not None:
results['default over-ridden']=c
else:
results['default']='no arg supplied for parameter c'
d.append(results)
if 'verbose' in opts and opts['verbose']:
for k,v in results:
print '%s:%s' % (k, v)
return (results, d)
... this, rather contrived, example has a couple of normal, traditional positional parameters (a and b), and optional third and fourth parameters (one of which will default to the special Python singleton value None if bar() is called with only two arguments and the other which will default to a list) as well as an optional variable number of additional arguments (which are passed into our function through the parameter named "e") and, finally, bar() can accept any number of "keyword" arguments (passed to it as key-value pairs and referenced through the parameter "opts" (in my example).
There's a lot to digest there. First there are a and b. Those are just like you'd see in most programming languages. If you call this with only one argument you'll get an error because the function requires two arguments. Then there are c and d ... these parameters can be supplied with arguments ... but if the function is called with only the two required arguments than parameter c will refer to "None" and d will refer to the list ... which was instantiated at the time we defined the function!
Whoa! Re-read that last bit because it's a common source of confusion to people who make the mistake of defining functions with parameters that default to mutable types (lists, dictionaries, sets, or most instances of your custom defined classes).
When you're defining a function in Python the interpreter is executing code. It's executing the def statement and evaluating the arguments (which become your function's parameters). So a Python virtual machine instantiates a list (the [] --- empty list literal) as the function is defined. The parameter (e in my example) is now bound to that list, just as any Python "variable" (name) is bound to any other object. And the object to which it refers will be accessible any time bar() is called with three or fewer arguments.
Here's the tricky bit: any time you call bar with more than three arguments then the parameter e will be bound (for the duration of that particular call) to the fourth argument. The underlying list will be hidden for the duration of that call. Such the default list object is contained in a closure and would normally be completely inaccessible outside of the function. (In this example I've including a reference to it in my return statement, showing how we can export a reference to that enclosed object if we choose).
So, if I pass bar() four arguments then it will attempt to modify the object referred to through its "e" parameter using that object's 'append' method. (Obviously that will fail and raise an exception for any object that doesn't support an append method). Every time I call bar() with only three arguments then I'm modifying that enclosed list object within its closure.
This can be useful but is rarely what new programmers expect when they are learning Python. So, as a rule, don't define functions with mutable objects as defaults to your parameters. When you understand the semantics well enough then you know when to break that rule.
I used "None" as my default for the other parameter for a reason. It's often useful to use "None" as the default for any parameter for which you want to have a default value and, then, to explicitly test "is None" and supply your own default from within the body of your function. In this way you can distinguish between your default parameter value and any argument that was explicitly passed to you (and happened to match your default). (This will also prevent the case where you might inadvertently create a mutable closure as previously described. The assignments/bindings occurring in the body of your function will result in a new instantiation for every call that reaches that condition).
So we've covered the required positional parameters, and those which supply defaults (and are, thus, optionally positional parameters).
With parameter 'e' we see Python's support for variable numbers of arguments. Any arguments specified after the fourth will all be gathered up into a tuple and passed to us through our parameter 'e' ... except for any arguments of the form: this=that.
Which brings us, at last. to "opts." Conventionally Python programmers will refer to this parameter as "kwargs" (key/word arguments). I named it "opts" to emphasize that point that "kwargs" is only a conventional bit of terminology and, technically, a bit confusing since, as I've belabored throughout this text, it's a parameter which is referring to any keyword arguments which might have been passed as parameters through some function call.
It's possible to write all your functions such that they take NO positional arguments and are only defined with a "key/words arguments" parameter. You can then ensure that callers to your function must always spell out which argument is bound to what name every time that call on you. This can be handy if your function might have catastrophic consequences in any case where it was called with arguments in the wrong order.
I realize this is confusing ... and I definitely recommend that you play with different function definitions and a wide variety of calls to see how these interact.
I'll also note one additional "gotchya" that can bite you. Your callers CANNOT pass kwargs (opts) values with keys that have names conflicting with your parameter names. Try calling bar() with an argument list like: bar(1,2,3,4,a=99) and you'll get an exception like this: "TypeError: bar() got multiple values for keyword argument 'a'"
Python is parsing the arguments into parameters by managing a namespace (like a dictionary). Attempting to supply a key/word argument which any keys that match your parameter names creates an ambiguity ... and thus raises an exception.
I'll also add two additional notes to this already cumbersome answer.
When you're calling functions in Python you can pass arguments like so:
myargs=(1,2,3)
bar(*myargs)
... and this will be treated as though you'd called it with bar(1,2,3) --- or as if you make the following function call: apply(bar, myargs).
In fact it used to be that you had to use the apply() function in order to accomplish this layer of indirection (back when you could define functions with *foo parameters but not call them with *foo arguments).
(The addition of the *args syntax on function calls largely displaced the use of Python's apply() builtin function).
... and lastly it's possible to pass a dictionary of kwargs using this syntax:
mykwargs={'z':99, 'whatever':'yikes'}
bar(1,2,3, **mykwargs)
... or combined with my previous example:
bar(*myargs, **mykwargs)
So it's vital to understand this distinction between what * and ** mean when defining functions and what they mean when calling them. The meanings are complementary to one another and intuitive if you understand the distinction between arguments and parameters (despite how the term "arguments" is more commonly used).

Why are we calling the print_line function and passing arguments to it that are named exactly the same as it's parameters?
That is really just a coincidence. The following does exactly the same as your example:
from sys import argv
script, input_encoding, error = argv
def main(language_file, what_encoding_do_you_want, list_of_errors):
next_line = language_file.readline()
if next_line:
print_line(next_line, what_encoding_do_you_want, list_of_errors)
return main(language_file, what_encoding_do_you_want, list_of_errors)
def print_line(line, encoding, errors):
next_lang = line.strip()
raw_bytes = next_lang.encode(encoding, errors=errors)
cooked_string = raw_bytes.decode(encoding, errors=errors)
print(raw_bytes, "<===>", cooked_string)
languages = open("languages.txt", encoding="utf-8")
main(languages, input_encoding, error)
It all comes down to 'scope'. The function-definition of print_line declares that it has three (positional) arguments, which can be referred to inside the function as 'line', 'encoding' and 'errors'.
The function-call to print_line from main adds three arguments to the call that refer to existing variables or arguments at that point in code: line refers to the variable created there; encoding and encoding refer to the argument to main function itself.

The function requires three arguments, and normally, you provide them in the order specified.
Python allows you to pass them in any order you like, though:
print_line(encoding='ascii', line='hello', errors=None)
or even
my_dict = {
'line': 'privet, mir!',
'errors': None,
'encoding': 'utf-8'
}
print_line(**my_dict)
However, the function requires all these arguments; you have to pass them in somehow, or you get an error message, like you well noticed.
The variables' scope is local: Anything in the def is local to the function it defines, and separate from any other variables with the same name outside of that block.
A parameter can be made optional by defining a default value. Optional parameters must always come after mandatory parameters in Python.
def another_fun(confetti, fireworks, bassoons=None, candy='sugar fluff')
If you call another_fun with only two parameters, bassoons will default to None and candy will be set to the string 'sugar fluff'.

Why are we calling the print_line function
Well, to execute it obviously ;-)
and passing arguments to it
Because the function is defined to take arguments - it cannot do its job if you don't give what it needs to work on.
that are named exactly the same as its parameters?
This is actually totally irrelevant - it just happens that the variables in main() are named the same as the function's arguments (which makes sense since we're taling about the same things - a "line of text", an encoding name and a value that describes how to handle encoding errors), but you pass litteral (unnamed) values or variables with just any arbitrary name, it would work just the same.
A function is a (mostly) self-contained unit of work. It usually uses some internal ("local") variables which only it can sees and that only exists during the function's execution. It also usually takes arguments: values that must be passed by the caller, and are bound to the matching arguments names (in our case, the first value will be bound to the line name, the second to the encoding name etc). The local names (local variables and arguments) are totally unrelated to the name under which those values are known in the caller's scope (if even they are bound to names - as I said you can as well pass literal values or other anonymous objects)
When I attempt to call the print_line() argument without passing arguments Python is outputting "print_line() missing 3 required positional arguments: 'line', 'encoding', and 'errors'"
Yes, of course. The function needs three arguments, so you have to pass three arguments, plain and simple. The fact that you have three local variables by the same name in the caller scope (the main function) will not automagically "fill in" those arguments for you, and the print_line function knows absolutely nothing about it's caller's scope anyway.
Note that the terms "positional" and "named" arguments mostly to refer to how you pass the arguments themselves - by position (the default), which I already explained above, or by name (ie print_line(line="hello", errors="ignore", encoding="utf-8"), which allow you to pass the arguments in a different order, or from a dictionnary you've built dynamically etc etc, but you first need to understand the concepts of function, arguments and scope before going further...
I strongly suggest that you do the official tutorial, which does have a chapter on functions - it's mostly intended at peoples with already some programming experience (it's not a CS101 course) but it's still well explained.

Related

Python Multiple Dispatch on only some arguments

What I would really like to do is make a function with a default first argument
def do_thing(self, category:str='default', sub_category:str, argA:int|float, argB:int|float, argC:int|float)
...
obj.do_thing('cat1', 'sub1', 1, 2, 3)
obj.do_thing('sub2', 1, 2, 3) #In thise case 'default' is used for the category
But that isn't possible since all arguments with default values must come after non-default arguments.
I could technically move the category argument last and the default work work fine, but the category and sub_category arguments are closely related so I would like to keep them grouped together at the beginning of the line then followed by argA/B/C since it follows the format [selected thing, arguments to use on selected thing]
Using *args would also technically work and could check number of arguments and whether there are one or two strings at the beginning of the list.
But this seems much less clear what arguments are expected to be given and doesn't have type hinting or the arguments which are useful for IDE auto-suggestions.
def do_thing(self, *args)
Multiple Dispatch seemed like it did sort of what I wanted since it allows different versions of the function to be called based on the arguments that are used.
So I tried doing this
from multipledispatch import dispatch
#dispatch(str, str, object, object, object) #Use object to allow more than one type since float and int are both valid
def do_thing(self, category:str='default', sub_category:str, argA:int|float, argB:int|float, argC:int|float)
...
#dispatch(str, object, object, object)
def do_thing(self, sub_category:str, argA:int|float, argB:int|float, argC:int|float)
do_thing('default', sub_category, argA, argB, argC)
This mostly works if all the arguments are entered as positional arguments, however the users of this library regularly (but not always) call the function with argA-argC as keyword arguments, which doesn't work with multiple dispatch.
Is there any way to check if there are at least 2 positional argument and then only if the first two arguments of the function are strings run one function, else for any other combination, call the other version?
functools.singledispatchmethod almost does what I want to do, but in both cases, the first argument will always be a string, so I don't think that will work unless there's a way to tell it to look at the second argument instead of the first
Alternatively, is there a better way to go about doing what I was trying to do to begin with? Basically create a default value for the first argument?

What are practical use case of Positional only arguments and Keyword only arguments in python? [duplicate]

This question already has answers here:
Why use positional only arguments in python 3.8?
(1 answer)
Mandatory keywords arguments
(2 answers)
Closed 11 months ago.
Python has support for postional only and keyword only arguments
Positional only arguments
def postional_only_func(a,b,/):
...
Keyword only arguments
def keyword_only_func(*,a,b):
...
But, what are its practical use case when writing a function? Is it just to make code more readable?
Both of these features were added to make writing certain functions easier. IF you want to read the full rational and motivation, you should read the corresponding PEPs:
PEP 570 – Python Positional-Only Parameters
PEP 3102 – Keyword-Only Arguments
For positional only, here are concrete examples for use-cases, using examples from the built-in functions:
There are functions with other interesting semantics:
range(), an overloaded function, accepts an optional parameter to the left of its required parameter. [4]
dict(), whose mapping/iterator parameter is optional and semantically must be positional-only. Any externally visible name for
this parameter would occlude that name going into the **kwarg keyword
variadic parameter dict. [3]
One can emulate these semantics in Python code by accepting (*args,
**kwargs) and parsing the arguments manually. However, this results in a disconnect between the function definition and what the function
contractually accepts. The function definition does not match the
logic of the argument handling.
And for keyword-only arguments it says the following regarding motivation:
There are often cases where it is desirable for a function to take a
variable number of arguments. The Python language supports this using
the ‘varargs’ syntax (*name), which specifies that any ‘left over’
arguments be passed into the varargs parameter as a tuple.
One limitation on this is that currently, all of the regular argument
slots must be filled before the vararg slot can be.
This is not always desirable. One can easily envision a function which
takes a variable number of arguments, but also takes one or more
‘options’ in the form of keyword arguments. Currently, the only way to
do this is to define both a varargs argument, and a ‘keywords’
argument (**kwargs), and then manually extract the desired keywords
from the dictionary.

What is the best way to pass multiple parameters to class init in python?

I am creating a module in python that can take multiple arguments. What would be the best way to pass the arguments to the definition of a method?
def abc(arg):
...
abc({"host" : "10.1.0.100", "protocol" : "http"})
def abc(host, protocol):
...
abc("10.1.0.100", "http")
def abc(**kwargs):
...
abc(host = "10.1.0.100", protocol = "http")
Or something else?
Edit
I will actually have those arguments (username, password, protocol, host, password2) where none of them are required.
def abc(host, protocol):
...
abc("10.1.0.100", "http")
abc(host="10.1.0.100", protocol="http")
If you call it using positional args or keyword args depends on the number of arguments and if you skip any. For your example I don't see much use in calling the function with keyword args.
Now some reasons why the other solutions are bad:
abc({"host" : "10.1.0.100", "protocol" : "http"})
This is a workaround for keyword arguments commonly used in languages which lack real keyword args (usually JavaScript). In those languages it is nice, but in Python it is just wrong since you gain absolutely nothing from it. If you ever want to call the functions with args from a dict, you can always do abc(**{...}) anyway.
def abc(**kwargs):
People expect the function to accept lots of - maybe even arbitrary - arguments. Besides that, they don't see what arguments are possible/required and you'd have to write code to require certain arguments on your own.
If all the arguments are known ahead, use an explicit argument list, optionally with default values, like def abc(arg1="hello", arg2="world",...). This will make the code most readable.
When you call the function, you can use either abd("hello", "world") or abc(arg1="hello", arg2="world"). I use the longer form if there are more than 4 or 5 arguments, it's a matter of taste.
This really depends on the context, the design and the purpose of your method.
If the parameters are defined and compulsory, then the best option is:
def abc(host, protocol):
...
abc('10.1.0.100', 'http')
in case the parameters are defined but optional, then:
def abc(host=None, protocol=None): # I used None, but put a default value
...
you can call it thorugh positional arguments as abc('10.1.0.100', 'http') or by their name abc(protocol='http')
And if you don't know at first what are the arguments it will receive are (for example in string formatting) then the best option is using the **kwargs argument:
def abc(**kwargs):
...
And in this way you must call it using named arguments.

Function arguments (in Python for example)

What are [function] arguments? What are they used for?
I started learning Python very recently; I'm new to programming and I apologize for this basic question.
In every Python tutorial I go through they talk about arguments. I have looked for the answer to this question and have found many answers but they are just a little too hard for me to understatnd. I may just be missing some conceptual background.
So... when I define a function, what are the things in parenthesis used for?
Example:
def hi( This is the part that i dont get):
print 'hi'
Edit:
Two follow-up questions related to this one were later closed and merged here, hence the partial out-of-context trait of some of the answers.
The follow-up questions were: [paraphrased]
Can arguments only be used for input ?
what are other examples of the use of arguments ?
Why use arguments, rather than having the function call raw_input ?
Why is the concept of argument passing described as such a powerful thing? it seems to me we're merely using them to replace stuff the user could have type on the keyboard.
In a few words, they're data that gets "passed into" the function to tell it what to do. Wikipedia has details.
http://en.wikipedia.org/wiki/Function_argument
For instance, your hi() function might need to know who to say hello to:
def hi(person):
print "Hi there " + person + ", how are you?"
Or a mathematical function might need a value to operate on:
def square(x):
return x * x
This is not a Python question, but rather a generic programming question. A very basic one.
Before answering the question about arguments, and in view of the other questions you asked, it is useful to discuss the concept of variables.
A variable is a named piece of memory where information of interest to the underlying program can be stored and retrieved. In other words, it is a symbolic name, chosen by the programmer, that is associated to its contents. Using various language constructs generally known as assignments, the programmer can read or write the contents of a variable.
It is important to note that the value (i.e. the content) of a variable needn't be defined when the program is written. It is only necessary at run-time. This allows the program to describe actions to be performed on symbolic elements without knowing exactly the value these elements have. Consider this snippet, part of a bigger program:
# ... some logic above
ball_volume = 4.0 / 3 * math.pi * ball_radius
if ball_volume > 200:
print ("Man, that's a big ball")
# ... more logic below
At the time the program is written one doesn't need to know the actual value of ball_radius; yet, with the assumption that this variable will contain the numeric value of some hypothetical ball, the snippet is capable of describing how to compute the ball's volume. In this fashion, when the program is running, and somehow (more on this later) the ball_radius variable has been initialized with some appropriate value, the variable ball_volume can too be initialized and used, here in the conditional statement (if), and possibly below. (At some point the variable may go out-of-scope, but this concept which controls when particular variables are accessible to the program is well beyond this primer).
In some languages the type of data that may be associated with a particular variable needs to be explicitly defined and cannot change. For example some variables could hold only integer values, other variables string values (text) etc. In Python there is no such restriction, a variable can be assigned and re-assigned to any type of data, but of course, the programmer needs to keep track of this for example to avoid passing some text data to a mathematical function.
The data stored inside variable may come from very different sources. Many of the examples provided in tutorials and introductory documentation have this data coming from keyboard input (as when using raw_input as mentioned in some of your questions). That is because it allows interactive tests by the people trying out these tutorial snippets. But the usefulness of programs would be rather limited if variables only get their data from interactive user input. There are many other sources and this is what makes programming so powerful: variables can be initialized with data from:
databases
text files or files various text-base formats (XML, JSON, CSV..)
binary files with various formats
internet connections
physical devices: cameras, temperature sensors...
In a nutshell, Arguments, also called Parameters, are variables passed to the function which [typically] are used to provide different output and behavior from the function. For example:
>>> def say_hello(my_name):
... print("Hello,", my_name, "!")
>>> say_hello("Sam")
Hello, Sam !
>>> customer_name = "Mr Peter Clark" #imagine this info came from a database
>>> # ...
>>> say_hello(customer_name)
Hello, Mr Peter Clark !
>>>
In the example above, my_name is just like any local variable of the say_hello function; this allows the function to define what it will do with the underlying value when the function is called, at run-time.
At run-time, the function can be called with an immediate value (a value that is "hard-coded" in the logic, such as "Sam" in the example), or with [the value of] another variable (such as customer_name). In both cases the value of the function's my_name variable gets assigned some value, "Sam" and "Mr Peter Clark" respectively. In the latter case, this value is whatever the customer_name variable contains. Note that the names of the variables used inside the function (my_name) and when the function is called (customer_name) do not need to be the same. (these are called the "formal parameter(s)" and the "actual parameters" respectively)
Note that while typically most arguments as passed as input to a function, in some conditions, they can be used as output, i.e. to provide new/modified values at the level of the logic which called the function. Doing so requires using, implicitly or explicitly, the proper calling convention specification (See Argument passing conventions below)
Now... beyond this very basic understanding of the purpose of parameters, things get a little more complicated than that (but not much). I'll discuss these additional concepts in general and illustrate them as they apply to Python.
Default values for arguments (aka "optional" arguments)
When the function is declared it may specify the default value for some parameters. These values are used for the parameters which are not specified when the function is called. For obvious reasons these optional parameters are found at the end of the parameter list (otherwise the language compiler/interpreter may have difficulty figuring out which parameter is which...)
>>> def say_hello(dude = "Sir"):
... print("Hello,", dude, "!")
...
>>> say_hello()
Hello, Sir !
>>> say_hello("William Gates")
Hello, Bill ! #just kidding ;-)
Hello, William Gates ! # but indeed. works as the original function when param
# is specified
Variable number of parameters
In some cases it may be handy to define a function so that it may accept a variable number of parameters. While such lists of parameter values ultimately get passed in some kind of container (list, array, collection...) various languages offers convenient ways of accessing such parameter values.
>>> def add_many(operand1, *operands):
... Sum = operand1
... for op in operands:
... Sum += op
... return Sum
...
>>> add_many(1, 3, 5, 7, 20)
36
>>> add_many(1, 3)
4
Named Arguments (Keyword Arguments)
With Python and a few other languages, it is possible to explicitly name the arguments when calling the function. Whereby argument passing is by default based a positional basis ("1st argument, 2nd argument etc.), Python will let you name the arguments and pass them in any order. This is mostly a syntactic nicety, but can be useful, in combination with default arguments for functions that accept very many arguments. It is also a nice self-documenting feature.
>>> def do_greetings(greeting, person):
... print (greeting, "dear", person, "!")
...
>>> do_greetings(person="Jack", greeting="Good evening")
Good evening dear Jack !
In Python, you can even pass a dictionary in lieu of several named arguments for example, with do_greetingsas-is, imagine you have a dictionary like:
>>> my_param_dict = {"greeting":"Aloha", "person":"Alan"}
>>> do_greetings(**my_param_dict)
Aloha dear Alan !
In closing, and while the fancy ways of passing arguments, and the capability for methods to handle variable number of arguments are useful features of various languages, two key concepts need to be mentioned:
Argument passing convention : by value or by reference
So far all the functions we used didn't alter the value of the parameters passed to them. We can imagine however many instances when functions may want to do this, either to perform some conversion or computation on the said values, for its own internal use, or to effectively change the value of the variable so that the changes are reflected at the level of logic which called the function. That's where argument passing conventions come handy...
arguments which are passed by value may be altered by the function for its own internal computations but are not changed at the level of the calling method.
arguments which are passed by reference will reflect changes made to them, at the level of the calling method.
Each language specifies the ways that arguments are passed. A typical convention is to pass integers, numberic values and other basic types by value and to pass objects by reference. Most language also offer keyword that allow altering their default convention.
In python all arguments are passed by reference. However a few variables types are immutable (numbers, strings, tuples...) and they can therefore not be altered by the function.
Implicit "self" or "this" argument of class methods
In object oriented languages, methods (i.e. functions within a class) receive an extra argument that is the value of underlying object (the instance of the class), allowing the method to use various properties members of the class in its computation and/or to alter the value of some of these properties.
in Python, this argument is declared at the level of the method definition, but is passed implicitly. Being declared, it may be named most anything one wishes, although by convention this is typically called self.
>>> class Accumulator:
... def __init__(self, initialValue = 0):
... self.CurValue = initialValue
... def Add(self, x):
... self.CurValue += x
... return self.CurValue
...
>>> my_accu = Accumulator(10)
>>> my_accu.Add(5)
15
>>> my_accu.Add(3)
18
In that case for using arguments, it is simply a demo on how to use them, not the most effective perhaps as you demonstrated. Functions are very useful. for example if i wanted to add two numbers:
def add(num1, num2):
x = num1 + num2
return x
add(1,3)
Functions are useful for performing repetitive tasks, let's say in your example you had to say hello to hundreds of names, instead of having to do a loop of that raw_input() function to read their name and add some text to it you could simply call a function to perform the task and pass arguments (the persons name to it).
Per your second question, arguments are just variables passed to the function, so whatever variable you pass to it from the outside, for example I pass numbers 1 and 3 to my function add on the inside of that function they are simply referred to as num1 num2.
In your case with passing too many arguments would yield this:
>>> add(1,2)
3
>>> add(1,2,3)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: add() takes exactly 2 arguments (3 given)
>>>
Best of luck! and feel free to shoot me an email if you need further help (sbrichards (at) mit.edu)
The stuff in the parentheses are called arguments. Basically these are variables that you want the function to work with. For example, say you have a function, and you want it to print a word when you call it. With arguments, you can define what that word will be. Here is an example:
def hi(word):
print word
now, if I do something like this:
hi('Hello!')
it will print:
'Hello!'
hi() gets passed 'Hello!' as a variable called word, and then it prints that word.
In your example they are not used.
If your function needs to behave differently depending on what arguments you give it, then what's arguments are for.
def hi_name(name):
print 'Hi ' + name
hi_name("John doe")
This prints "Hi John Doe".
Now back to the basics about functions.
An argument is a special variable that exists only in that function.
In your example you have a function that takes 2 arguments:
def add(num1,num2):
x = num1 + num2
return x
When I call this function with add(), I have to add in the parentheses what I want num1 and num2 to be. In your case, you have 1 and 3, so you call it like this add(1,3).
What you're saying there is that you want to call add() and you want the first argument, num1 to be equal to 1, and the second argument, num2, to be equal to 3.
def main(a, b):
print(a)
print(b)
main(3, 5)
This is a basic example of a function with parameters, check for more information here.
output:
3
5
Functions would be useless if you can't give them information they should handle.
Arguments are such information.
def GiveMeANumberAndIDuplicateIt(x):
return x * 2
def DontGiveMeAnythingAtAll():
return None

Python arguments- how do you use them? [duplicate]

What are [function] arguments? What are they used for?
I started learning Python very recently; I'm new to programming and I apologize for this basic question.
In every Python tutorial I go through they talk about arguments. I have looked for the answer to this question and have found many answers but they are just a little too hard for me to understatnd. I may just be missing some conceptual background.
So... when I define a function, what are the things in parenthesis used for?
Example:
def hi( This is the part that i dont get):
print 'hi'
Edit:
Two follow-up questions related to this one were later closed and merged here, hence the partial out-of-context trait of some of the answers.
The follow-up questions were: [paraphrased]
Can arguments only be used for input ?
what are other examples of the use of arguments ?
Why use arguments, rather than having the function call raw_input ?
Why is the concept of argument passing described as such a powerful thing? it seems to me we're merely using them to replace stuff the user could have type on the keyboard.
In a few words, they're data that gets "passed into" the function to tell it what to do. Wikipedia has details.
http://en.wikipedia.org/wiki/Function_argument
For instance, your hi() function might need to know who to say hello to:
def hi(person):
print "Hi there " + person + ", how are you?"
Or a mathematical function might need a value to operate on:
def square(x):
return x * x
This is not a Python question, but rather a generic programming question. A very basic one.
Before answering the question about arguments, and in view of the other questions you asked, it is useful to discuss the concept of variables.
A variable is a named piece of memory where information of interest to the underlying program can be stored and retrieved. In other words, it is a symbolic name, chosen by the programmer, that is associated to its contents. Using various language constructs generally known as assignments, the programmer can read or write the contents of a variable.
It is important to note that the value (i.e. the content) of a variable needn't be defined when the program is written. It is only necessary at run-time. This allows the program to describe actions to be performed on symbolic elements without knowing exactly the value these elements have. Consider this snippet, part of a bigger program:
# ... some logic above
ball_volume = 4.0 / 3 * math.pi * ball_radius
if ball_volume > 200:
print ("Man, that's a big ball")
# ... more logic below
At the time the program is written one doesn't need to know the actual value of ball_radius; yet, with the assumption that this variable will contain the numeric value of some hypothetical ball, the snippet is capable of describing how to compute the ball's volume. In this fashion, when the program is running, and somehow (more on this later) the ball_radius variable has been initialized with some appropriate value, the variable ball_volume can too be initialized and used, here in the conditional statement (if), and possibly below. (At some point the variable may go out-of-scope, but this concept which controls when particular variables are accessible to the program is well beyond this primer).
In some languages the type of data that may be associated with a particular variable needs to be explicitly defined and cannot change. For example some variables could hold only integer values, other variables string values (text) etc. In Python there is no such restriction, a variable can be assigned and re-assigned to any type of data, but of course, the programmer needs to keep track of this for example to avoid passing some text data to a mathematical function.
The data stored inside variable may come from very different sources. Many of the examples provided in tutorials and introductory documentation have this data coming from keyboard input (as when using raw_input as mentioned in some of your questions). That is because it allows interactive tests by the people trying out these tutorial snippets. But the usefulness of programs would be rather limited if variables only get their data from interactive user input. There are many other sources and this is what makes programming so powerful: variables can be initialized with data from:
databases
text files or files various text-base formats (XML, JSON, CSV..)
binary files with various formats
internet connections
physical devices: cameras, temperature sensors...
In a nutshell, Arguments, also called Parameters, are variables passed to the function which [typically] are used to provide different output and behavior from the function. For example:
>>> def say_hello(my_name):
... print("Hello,", my_name, "!")
>>> say_hello("Sam")
Hello, Sam !
>>> customer_name = "Mr Peter Clark" #imagine this info came from a database
>>> # ...
>>> say_hello(customer_name)
Hello, Mr Peter Clark !
>>>
In the example above, my_name is just like any local variable of the say_hello function; this allows the function to define what it will do with the underlying value when the function is called, at run-time.
At run-time, the function can be called with an immediate value (a value that is "hard-coded" in the logic, such as "Sam" in the example), or with [the value of] another variable (such as customer_name). In both cases the value of the function's my_name variable gets assigned some value, "Sam" and "Mr Peter Clark" respectively. In the latter case, this value is whatever the customer_name variable contains. Note that the names of the variables used inside the function (my_name) and when the function is called (customer_name) do not need to be the same. (these are called the "formal parameter(s)" and the "actual parameters" respectively)
Note that while typically most arguments as passed as input to a function, in some conditions, they can be used as output, i.e. to provide new/modified values at the level of the logic which called the function. Doing so requires using, implicitly or explicitly, the proper calling convention specification (See Argument passing conventions below)
Now... beyond this very basic understanding of the purpose of parameters, things get a little more complicated than that (but not much). I'll discuss these additional concepts in general and illustrate them as they apply to Python.
Default values for arguments (aka "optional" arguments)
When the function is declared it may specify the default value for some parameters. These values are used for the parameters which are not specified when the function is called. For obvious reasons these optional parameters are found at the end of the parameter list (otherwise the language compiler/interpreter may have difficulty figuring out which parameter is which...)
>>> def say_hello(dude = "Sir"):
... print("Hello,", dude, "!")
...
>>> say_hello()
Hello, Sir !
>>> say_hello("William Gates")
Hello, Bill ! #just kidding ;-)
Hello, William Gates ! # but indeed. works as the original function when param
# is specified
Variable number of parameters
In some cases it may be handy to define a function so that it may accept a variable number of parameters. While such lists of parameter values ultimately get passed in some kind of container (list, array, collection...) various languages offers convenient ways of accessing such parameter values.
>>> def add_many(operand1, *operands):
... Sum = operand1
... for op in operands:
... Sum += op
... return Sum
...
>>> add_many(1, 3, 5, 7, 20)
36
>>> add_many(1, 3)
4
Named Arguments (Keyword Arguments)
With Python and a few other languages, it is possible to explicitly name the arguments when calling the function. Whereby argument passing is by default based a positional basis ("1st argument, 2nd argument etc.), Python will let you name the arguments and pass them in any order. This is mostly a syntactic nicety, but can be useful, in combination with default arguments for functions that accept very many arguments. It is also a nice self-documenting feature.
>>> def do_greetings(greeting, person):
... print (greeting, "dear", person, "!")
...
>>> do_greetings(person="Jack", greeting="Good evening")
Good evening dear Jack !
In Python, you can even pass a dictionary in lieu of several named arguments for example, with do_greetingsas-is, imagine you have a dictionary like:
>>> my_param_dict = {"greeting":"Aloha", "person":"Alan"}
>>> do_greetings(**my_param_dict)
Aloha dear Alan !
In closing, and while the fancy ways of passing arguments, and the capability for methods to handle variable number of arguments are useful features of various languages, two key concepts need to be mentioned:
Argument passing convention : by value or by reference
So far all the functions we used didn't alter the value of the parameters passed to them. We can imagine however many instances when functions may want to do this, either to perform some conversion or computation on the said values, for its own internal use, or to effectively change the value of the variable so that the changes are reflected at the level of logic which called the function. That's where argument passing conventions come handy...
arguments which are passed by value may be altered by the function for its own internal computations but are not changed at the level of the calling method.
arguments which are passed by reference will reflect changes made to them, at the level of the calling method.
Each language specifies the ways that arguments are passed. A typical convention is to pass integers, numberic values and other basic types by value and to pass objects by reference. Most language also offer keyword that allow altering their default convention.
In python all arguments are passed by reference. However a few variables types are immutable (numbers, strings, tuples...) and they can therefore not be altered by the function.
Implicit "self" or "this" argument of class methods
In object oriented languages, methods (i.e. functions within a class) receive an extra argument that is the value of underlying object (the instance of the class), allowing the method to use various properties members of the class in its computation and/or to alter the value of some of these properties.
in Python, this argument is declared at the level of the method definition, but is passed implicitly. Being declared, it may be named most anything one wishes, although by convention this is typically called self.
>>> class Accumulator:
... def __init__(self, initialValue = 0):
... self.CurValue = initialValue
... def Add(self, x):
... self.CurValue += x
... return self.CurValue
...
>>> my_accu = Accumulator(10)
>>> my_accu.Add(5)
15
>>> my_accu.Add(3)
18
In that case for using arguments, it is simply a demo on how to use them, not the most effective perhaps as you demonstrated. Functions are very useful. for example if i wanted to add two numbers:
def add(num1, num2):
x = num1 + num2
return x
add(1,3)
Functions are useful for performing repetitive tasks, let's say in your example you had to say hello to hundreds of names, instead of having to do a loop of that raw_input() function to read their name and add some text to it you could simply call a function to perform the task and pass arguments (the persons name to it).
Per your second question, arguments are just variables passed to the function, so whatever variable you pass to it from the outside, for example I pass numbers 1 and 3 to my function add on the inside of that function they are simply referred to as num1 num2.
In your case with passing too many arguments would yield this:
>>> add(1,2)
3
>>> add(1,2,3)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: add() takes exactly 2 arguments (3 given)
>>>
Best of luck! and feel free to shoot me an email if you need further help (sbrichards (at) mit.edu)
The stuff in the parentheses are called arguments. Basically these are variables that you want the function to work with. For example, say you have a function, and you want it to print a word when you call it. With arguments, you can define what that word will be. Here is an example:
def hi(word):
print word
now, if I do something like this:
hi('Hello!')
it will print:
'Hello!'
hi() gets passed 'Hello!' as a variable called word, and then it prints that word.
In your example they are not used.
If your function needs to behave differently depending on what arguments you give it, then what's arguments are for.
def hi_name(name):
print 'Hi ' + name
hi_name("John doe")
This prints "Hi John Doe".
Now back to the basics about functions.
An argument is a special variable that exists only in that function.
In your example you have a function that takes 2 arguments:
def add(num1,num2):
x = num1 + num2
return x
When I call this function with add(), I have to add in the parentheses what I want num1 and num2 to be. In your case, you have 1 and 3, so you call it like this add(1,3).
What you're saying there is that you want to call add() and you want the first argument, num1 to be equal to 1, and the second argument, num2, to be equal to 3.
def main(a, b):
print(a)
print(b)
main(3, 5)
This is a basic example of a function with parameters, check for more information here.
output:
3
5
Functions would be useless if you can't give them information they should handle.
Arguments are such information.
def GiveMeANumberAndIDuplicateIt(x):
return x * 2
def DontGiveMeAnythingAtAll():
return None

Categories