You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: _episodes/06-functions.md
+97-7Lines changed: 97 additions & 7 deletions
Original file line number
Diff line number
Diff line change
@@ -17,7 +17,7 @@ keypoints:
17
17
18
18
Most code is organized into blocks of code which perform a particular task. These code blocks are called *functions*. A commercial software package likely has hundreds of thousands or millions of functions. Functions break up our code into smaller, more easily understandable statements, and also allow our code to be more *modular*, meaning we can take pieces and reuse them. Functions also make your code easier to test, which we will see in a later lesson.
19
19
20
-
In general, each function should perform only one computational task.
20
+
**In general, each function should perform only one computational task.**
21
21
22
22
## Defining and running a function
23
23
@@ -35,7 +35,7 @@ Functions are defined using the `def` keyword, followed by the name of the funct
35
35
## Writing functions into our geometry analysis project
36
36
37
37
Let's go back and consider a possible solution for the geometry analysis project.
38
-
```
38
+
~~~
39
39
import numpy
40
40
import os
41
41
@@ -54,31 +54,32 @@ for num1 in range(0, num_atoms):
print(F'{symbols[num1]} to {symbols[num2]} : {bond_length_12:.3f}')
57
-
```
57
+
~~~
58
58
{: .language-python}
59
59
60
60
To think about where we should write functions in this code, let's think about parts we may want to use again or in other places. One of the first places we might think of is in the bond distance calculation. Perhaps we'd want to calculate a bond distance in some other script. We can reduce the likelihood of errors in our code by defining this in a function (so that if we wanted to change our bond calculation, we would only have to do it in one place.)
61
61
62
62
Let's change this code so that we write a function to calculate the bond distance. As explained above, to define a function, you start with the word `def` and then give the name of the function. In parenthesis are in inputs of the function followed by a colon. The the statements the function is going to execute are indented on the next lines. For this function, we will `return` a value. The last line of a function shows the return value for the function, which we can use to store a variable with the output value. Let's write a function to calculate the distance between atoms.
print(F'{symbols[num1]} to {symbols[num2]} : {bond_length_12:.3f}')
81
-
```
82
+
~~~
82
83
{: .language-python}
83
84
84
85
Next, let's write another function that checks to see if a particular bond distance represents a bond. This function will be called `bond_check`, and will return `True` if the bond distance is within certain bounds (At first we'll set this to be between 0 and 1.5 angstroms).
@@ -109,11 +110,89 @@ This is great! Our function will currently return `True` if our bond distance is
109
110
> {: .solution}
110
111
{: .challenge}
111
112
113
+
## Function Documentation
114
+
Recall from our work with tabular data that we were able to use `help` to see a help message on a function. As a reminder, we used it like this.
115
+
116
+
~~~
117
+
help(numpy.genfromtxt)
118
+
~~~
119
+
{: .language-python}
120
+
121
+
~~~
122
+
Help on function genfromtxt in module numpy.lib.npyio:
Load data from a text file, with missing values handled as specified.
126
+
127
+
Each line past the first `skip_header` lines is split at the `delimiter`
128
+
character, and characters following the `comments` character are discarded.
129
+
~~~
130
+
{: .output}
131
+
132
+
Let's try the same thing on our function.
133
+
134
+
~~~
135
+
help(calculate_distance)
136
+
~~~
137
+
{: .language-python}
138
+
139
+
~~~
140
+
Help on function calculate_distance in module __main__:
141
+
142
+
calculate_distance(atom1_coord, atom2_coord)
143
+
~~~
144
+
{: .output}
145
+
146
+
There is no help for our function! That is because you haven't written it yet. In Python, we can document our functions using something called `docstrings`. When you call help on something, it will display the docstring you have written. In fact, most Python libraries use docstrings and other automated tools to pull the docstrings out of the code to make online documentation. For example, see the [documentation](https://docs.scipy.org/doc/numpy/reference/generated/numpy.genfromtxt.html) for the `genfromtxt` function online.
147
+
148
+
To add a docstring to our function, we simply add a block quote directly underneath the function definition. We do this in in the same way we type a string, except that we use three quotation marks to open and close the string instead of one.
149
+
150
+
~~~
151
+
def calculate_distance(atom1_coord, atom2_coord):
152
+
"""Calculate the distance between two three-dimensional points."""
We are using a very simple docstring in this example. However, there are many formats for docstrings. Now, you should see a message when you call help on this function.
163
+
164
+
~~~
165
+
help(calculate_distance)
166
+
~~~
167
+
{: .language-python}
168
+
169
+
~~~
170
+
Help on function calculate_distance in module __main__:
171
+
172
+
calculate_distance(atom1_coord, atom2_coord)
173
+
Calculate the distance between two three-dimensional points
174
+
~~~
175
+
{: .output}
176
+
177
+
If you use a well-known format, you can use software to extract the docstring and make a webpage with your documentation. MolSSI recommends using numpy style docstrings. You can learn more about this in our [Python Package Development Best Practices Workshop](https://molssi-education.github.io/python-package-best-practices/).
178
+
179
+
> ## Help vs Online Documentation
180
+
> Many python libraries we have used such as numpy and matplotlib have extensive online documentation. It is a good idea to use online documentation if it is available. Typically, documentation for functions will be pulled from docstrings in the code, but additional information the code developers have provided will also be available through online documentation.
181
+
>
182
+
> However, if you are offline or using a library without online documentation, you can check for documentation using the `help` function.
183
+
{: .callout}
184
+
185
+
Remember, help for your code only exists if you write it! Every time you write a function, you should take some time to also write a docstring describing what the function does.
186
+
112
187
### Function Default arguments
113
188
When there are parameters in a function definition, we can set these parameters to default values. This way, if the user does not input values, the default values can be used instead of the code just not working. For example, if we want the default values in bond check to be 0 and 1.5, we can change the function definition to the following:
0 commit comments