Skip to content

Commit 0317aea

Browse files
committed
Applied edits from code review and re-wrote some more of the prose.
1 parent 4acaa30 commit 0317aea

2 files changed

Lines changed: 113 additions & 118 deletions

File tree

concepts/function-arguments/about.md

Lines changed: 87 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -10,33 +10,32 @@ Parameter names should not contain spaces or punctuation.
1010
## Positional Arguments
1111

1212
Positional arguments are values passed to a function in the same order as the parameters which bind to them.
13-
Positional arguments can optionally be passed by using their parameter name.
13+
Positional arguments can optionally be passed by using their parameter name:
1414

15-
Positional arguments being passed by position and by their parameter name:
1615

1716
```python
18-
>>> def concat(greeting, name):
19-
... return f"{greeting}{name}"
17+
def concat(greeting, name):
18+
return f"{greeting}{name}"
2019

2120
# Passing data to the function by position.
22-
>>> print(concat("Hello, ", "Bob"))
23-
Hello, Bob
21+
print(concat("Hello, ", "Lilly"))
22+
#-> Hello, Lilly
2423

2524
# Passing data to the function using the parameter name.
26-
>>> print(concat(name="Bob", greeting="Hello, "))
25+
print(concat(name="Glenn", greeting="Hello, "))
2726

28-
Hello, Bob
27+
#-> Hello, Glenn
2928
```
3029

3130
The first call to `concat` passes the arguments by position.
3231
The second call to `concat` passes the arguments by name, allowing their positions to be changed.
3332

34-
Note that positional arguments cannot follow keyword arguments.
33+
Note that positional arguments cannot follow arguments passed by name (_also called [keyword arguments][keyword-arguments]. **Not** to be confused with var-positional parameters or [**kwargs][kwargs]_).
3534

3635
This set of arguments:
3736

3837
```python
39-
>>> print(concat(greeting="Hello, ", "Gregor"))
38+
print(concat(greeting="Hello, ", "Gregor"))
4039
```
4140

4241
Results in this error:
@@ -47,60 +46,54 @@ SyntaxError: positional argument follows keyword argument
4746

4847
Requiring positional-only arguments for function calls can be done through the use of the `/` operator in the parameter list:
4948

50-
5149
```python
5250
# Parameters showing a position-only operator.
53-
>>> def concat(greeting, name, /):
54-
... return f"{greeting}{name}"
51+
def concat(greeting, name, /):
52+
return f"{greeting}{name}"
5553

56-
>>> print(concat("Hello, ", "Bob"))
57-
Hello, Bob
54+
print(concat("Hello, ", "Ginnie"))
55+
#-> Hello, Ginnie
5856

5957
# Call to the function using keyword arguments.
60-
>>> print(concat(name="Bob", greeting="Hello, "))
58+
print(concat(name="Franklin", greeting="Hello, "))
6159
Traceback (most recent call last):
62-
print(concat(name="Bob", greeting="Hello, "))
60+
print(concat(name="Franklin", greeting="Hello, "))
6361
TypeError: concat() got some positional-only arguments passed as keyword arguments: 'greeting, name'
6462
```
6563

6664
## Keyword Arguments
6765

6866
Keyword arguments use the parameter name when calling a function.
69-
Keyword arguments can optionally be referred to by position.
70-
71-
Keyword arguments being referred to by their parameter name and by position:
67+
They can optionally be referred to by position:
7268

7369
```python
74-
>>> def concat(greeting, name):
75-
... return f"{greeting}{name}"
70+
def concat(greeting, name):
71+
return f"{greeting}{name}"
7672

7773
# Function call using parameter names as argument keywords.
78-
>>> print(concat(name="Bob", greeting="Hello, "))
79-
Hello, Bob
74+
print(concat(name="Eliza", greeting="Hello, "))
75+
#--> Hello, Eliza
8076

8177
# Function call with positional data as arguments.
82-
>>> print(concat("Hello, ", "Bob"))
83-
Hello, Bob
78+
print(concat("Hello, ", "Tim"))
79+
#-> Hello, Tim
8480
```
8581

86-
Requiring keyword-only arguments for function calls can be done through the use of the `*` operator in the parameter list.
87-
88-
89-
Keyword-only arguments:
82+
Requiring keyword-only arguments for function calls can be done through the use of the `*` operator in the parameter list:
9083

9184
```python
9285
# Function definition requiring keyword-only arguments.
93-
>>> def concat(*, greeting, name):
94-
... return f"{greeting}{name}"
86+
def concat(*, greeting, name):
87+
return f"{greeting}{name}"
9588

9689
# Keyword arguments can be in an arbitrary order.
97-
>>> print(concat(name="Bob", greeting="Hello, "))
98-
Hello, Bob
90+
print(concat(name="Kimmie", greeting="Hello, "))
91+
#-> Hello, Kimmie
9992

10093
# Calling the function with positional data raises an error.
101-
>>> print(concat("Hello, ", "Bob"))
94+
print(concat("Hello, ", "Coleen"))
10295
Traceback (most recent call last):
103-
print(concat("Hello, ", "Bob"))
96+
print(concat("Hello, ", "Coleen"))
10497
TypeError: concat() takes 0 positional arguments but 2 were given
10598
```
10699

@@ -112,41 +105,41 @@ Default values can be overridden by calling the function with a new argument val
112105

113106
```python
114107
# Function with default argument values.
115-
>>> def concat(greeting, name="you", punctuation="!"):
116-
... return f"{greeting}, {name}{punctuation}"
108+
def concat(greeting, name="you", punctuation="!"):
109+
return f"{greeting}, {name}{punctuation}"
117110

118-
>>> print(concat("Hello"))
111+
print(concat("Hello"))
119112
Hello, you!
120113

121114
# Overriding the default values
122-
>>> print(concat("Hello", name="Bob", punctuation="."))
123-
Hello, Bob.
115+
print(concat("Hello", name="Polly", punctuation="."))
116+
Hello, Polly.
124117
```
125118

119+
126120
## Positional or Keyword Arguments
127121

128122
Arguments can be positional or keyword if neither the `/` nor `*` operators are used in the parameter definitions.
129-
Alternately, the positional-or-keyword arguments can be placed between the positional-only parameters on the left and the keyword-only parameters on the right.
130-
131-
Positional-only, positional-or-keyword, and keyword-only arguments:
123+
Alternately, the positional-or-keyword arguments can be placed between the positional-only parameters on the left and the keyword-only parameters on the right:
132124

133125
```python
134126
# Position-only argument followed by position-or-keyword, followed by keyword-only.
135-
>>> def concat(greeting, /, name, *, ending):
136-
... return f"{greeting}{name}{ending}"
127+
def concat(greeting, /, name, *, ending):
128+
return f"{greeting}{name}{ending}"
137129

138-
>>> print(concat("Hello, ", "Bob", ending="!"))
139-
Hello, Bob!
130+
print(concat("Hello, ", "Mark", ending="!"))
131+
Hello, Mark!
140132

141-
>>> print(concat("Hello, ", name="Bob", ending="!"))
142-
Hello, Bob!
133+
print(concat("Hello, ", name="Rachel", ending="!"))
134+
Hello, Rachel!
143135

144-
>>> print(concat(greeting="Hello, ", name="Bob", ending="!"))
136+
>>> print(concat(greeting="Hello, ", name="JoJo", ending="!"))
145137
Traceback (most recent call last):
146-
print(concat(greeting="Hello, ", name="Bob", ending="!"))
138+
print(concat(greeting="Hello, ", name="JoJo", ending="!"))
147139
TypeError: concat() got some positional-only arguments passed as keyword arguments: 'greeting'
148140
```
149141

142+
150143
## `*args`
151144

152145
Code examples will often use a function definition something like the following:
@@ -157,7 +150,7 @@ def my_function(*args, **kwargs):
157150
```
158151

159152
`*args` is a two-part name that represents a `tuple` with an indefinite number of separate positional arguments, also known as a [`variadic argument`][variadic argument].
160-
`args` is the name given to the `tuple` of arguments, but it could be any other valid Python name, such as `my_args`, `arguments`, etc.
153+
`args` is the name given to the `tuple` of arguments, but it could be any other valid Python name, such as `my_args`, `arguments`, etc.
161154
The `*` is the operator which transforms the group of separate arguments into a [`tuple`][tuple].
162155

163156
~~~~exercism/note
@@ -171,70 +164,71 @@ For instance, `*` is used for multiplication, it is used for unpacking, and it i
171164
[unpack-a-tuple]: https://www.geeksforgeeks.org/unpacking-a-tuple-in-python/
172165
~~~~
173166

174-
Since a tuple can be iterated over, `args` can be passed to any other function which takes an iterable.
167+
Since a `tuple` can be iterated over, `args` can be passed to any other function which takes an iterable.
175168
Although `*args` is commonly juxtaposed with `**kwargs`, it doesn't have to be:
176169

177170

178171
```python
179-
>>> def add(*args):
180-
# args is passed to the sum function, which iterates over it.
181-
... return sum(args)
172+
def add(*args):
173+
# args is passed to the sum function, which iterates over it.
174+
return sum(args)
182175

183-
>>> print(add(1, 2, 3))
184-
6
176+
print(add(1, 2, 3))
177+
#-> 6
185178
```
186179

187180
If `*args` follows one or more positional arguments, then `*args` will be what is left over after the positional arguments:
188181

189182

190183
```python
191-
>>> def add(first, *args):
192-
# first will be 1, leaving the values 2 and 3 in *args
193-
... return first + sum(args)
184+
def add(first, *args):
185+
# first will be 1, leaving the values 2 and 3 in *args
186+
return first + sum(args)
194187

195-
>>> print(add(1, 2, 3))
196-
6
188+
print(add(1, 2, 3))
189+
#-> 6
197190
```
198191

199-
If one or more [default arguments][default arguments] are defined after `*args`, they are separate from the `*args` values.
192+
If one or more [default arguments][default arguments] are defined after `*args`, they are separate from the `*args` values:
200193

201-
To put it all together:
202194

203195
```python
204196

205-
>>> def add(first, *args, last=0):
206-
... return first + sum(args) + last
197+
def add(first, *args, last=0):
198+
return first + sum(args) + last
207199

208-
>>> print(add(1, 2, 3))
209-
6
210-
>>> print(add(1, 2, 3, last=4))
211-
10
200+
print(add(1, 2, 3))
201+
#-> 6
202+
203+
print(add(1, 2, 3, last=4))
204+
#-> 10
212205

213206
# This uses the unpacking operator * to separate the list elements into positional arguments.
214207
# It does not have the same behavior as the * (packing) in *args.
215-
>>> print(add(*[1, 2, 3]))
216-
6
208+
print(add(*[1, 2, 3]))
209+
#-> 6
217210
```
218211

219-
Note that when an argument is already inside an `iterable`, such as a `tuple` or `list`, it needs to be [_unpacked_][unpacking-and-multiple-assignment] before being passed to a function that takes an arbitrary number of separate arguments.
212+
Note that when an argument is already inside an `iterable` such as a `tuple` or `list`, it needs to be [_unpacked_][unpacking-and-multiple-assignment] before being passed to a function that takes an arbitrary number of separate arguments.
220213
This is accomplished by using `*`, which is the [unpacking operator][unpacking operator].
221214

222-
`*` in this context _unpacks_ the container into its separate elements which are then transformed by `*args` into a tuple.
215+
`*` in this context _unpacks_ the container into its separate elements which are then transformed by `*args` into a `tuple`.
223216
Where there are only positional arguments, the unpacking action must result in the same number of arguments as there are formal parameters defined.
224217

225218
Without unpacking the list passed into `add`, the program would error:
226219

227220
```python
228-
>>> def add(first, *args, last=0):
229-
... return first + sum(args) + last
221+
def add(first, *args, last=0):
222+
return first + sum(args) + last
230223

231-
>>> print(add([1, 2, 3]))
224+
print(add([1, 2, 3]))
232225
Traceback (most recent call last):
233226
print(add([1, 2, 3]))
234227
return first + sum(args) + last
235228
TypeError: can only concatenate list (not "int") to list
236229
```
237230

231+
238232
## `**kwargs`
239233

240234
`**kwargs` is a two-part name that represents an indefinite number of separate [key-value pair][key-value] arguments.
@@ -246,24 +240,23 @@ Although `**kwargs` is commonly juxtaposed with `*args`, it doesn't have to be:
246240

247241

248242
```python
249-
>>> def add(**kwargs):
250-
... return sum(kwargs.values())
243+
def add(**kwargs):
244+
return sum(kwargs.values())
251245

252-
>>> print(add(one=1, two=2, three=3))
253-
6
246+
print(add(one=1, two=2, three=3))
247+
#-> 6
254248
```
255249

256-
Note that the `dict.values()` method is called to iterate through the `kwargs` dictionary values.
257-
When iterating over a dictionary, the default is to iterate through the _keys_, so `dict.values()` needs to be specified explicitly.
258-
Following is an example of an arbitrary number of key-value pairs being passed to a function that then iterates over `kwargs.items()`:
250+
Note that the `dict.values()` method is called to iterate through the `kwargs` dictionary `values`.
251+
When iterating over a dictionary, the default is to iterate through the _`keys`_, so `dict.values()` needs to be specified explicitly:
259252

260253
```python
261-
>>> def concat(**kwargs):
262-
... # Join concatenates the tuples from `kwargs.items()`
263-
... return " ".join((str(item) for item in kwargs.items()))
254+
def concat(**kwargs):
255+
# Join concatenates the tuples from `kwargs.items()`
256+
return " ".join((str(item) for item in kwargs.items()))
264257

265-
>>> print(concat(one=1, two=2, three=3))
266-
('one', 1) ('two', 2) ('three', 3)
258+
print(concat(one=1, two=2, three=3))
259+
#-> ('one', 1) ('two', 2) ('three', 3)
267260
```
268261

269262
[default arguments]: https://www.geeksforgeeks.org/default-arguments-in-python/
@@ -274,3 +267,6 @@ Following is an example of an arbitrary number of key-value pairs being passed t
274267
[unpacking operator]: https://docs.python.org/3/tutorial/controlflow.html#unpacking-argument-lists
275268
[unpacking-and-multiple-assignment]: https://exercism.org/tracks/python/concepts/unpacking-and-multiple-assignment
276269
[variadic argument]: https://en.wikipedia.org/wiki/Variadic_function
270+
[keyword-arguments]: https://docs.python.org/3/glossary.html#term-argument
271+
[kwargs]: https://docs.python.org/3/glossary.html#term-parameter
272+

0 commit comments

Comments
 (0)