Writing tutorials#
You can improve the PyDPF-Core documentation by adding a:
To do so, you must follow the guidelines presented here.
Tutorials are Python scripts processed by sphinx-gallery and live in the
doc/sphinx_gallery_tutorials/ directory. During the build, sphinx-gallery automatically
converts them to HTML pages, Jupyter notebooks, and downloadable Python scripts. Manual toctree
entries are only needed in the doc/sphinx_gallery_tutorials/index.rst file to link the section
landing pages, but not for individual tutorials. sphinx-gallery manages the toctree for individual
tutorials.
You also need to understand the structure of the doc directory on the PyDPF-Core library:
.
├── doc
│ ├── sphinx_gallery_tutorials
│ │ ├── index.rst <- Tutorials landing page
│ │ └── section_name
│ │ ├── GALLERY_HEADER.rst <- Section landing page
│ │ └── tutorial_name.py <- Tutorial script
│ ├── source
│ │ ├── api
│ │ ├── tutorials <- Auto-generated by sphinx-gallery
│ │ ├── examples <- Auto-generated by sphinx-gallery
│ │ ├── getting_started
│ │ ├── images
│ │ ├── user_guide
│ │ ├── conf.py
│ │ ├── index.rst
│ ├── styles
│ ├── make.bat
Tutorials source files are in doc/sphinx_gallery_tutorials.
The doc/source/tutorials directory is auto-generated and must not be edited by hand.
Adding a new tutorial section#
Download the new tutorial section template
Note
Avoid creating new sections unless absolutely necessary.
When in doubt, mention the intended location in the pull request for approval.
Every section folder must contain a GALLERY_HEADER.rst file as the documentation
ignores folders that lack this file.
Location and naming#
The new tutorial section must reside in a new folder such as
doc/sphinx_gallery_tutorials/new_section_name.
.
├── doc
│ ├── sphinx_gallery_tutorials
│ │ ├── new_section_name
Structure#
The section folder must contain a GALLERY_HEADER.rst file with:
a reference label for cross-referencing this section from other parts of the documentation,
a section title,
a general description of the topics covered in the tutorials in this section,
grid cards with links, titles, and descriptions for the tutorials in the section.
.. _ref_tutorials_new_section_name:
=================
New section title
=================
Description of what the tutorials in this section cover.
.. grid:: 1 1 3 3
:gutter: 2
:padding: 2
:margin: 2
.. grid-item-card:: Tutorial title
:link: ref_tutorial_name
:link-type: ref
:text-align: center
This tutorial ...
.. raw:: html
<style>.sphx-glr-thumbnails { display: none; }</style>
You must add a card linking to the new section in the top-level
doc/sphinx_gallery_tutorials/index.rst, following the same
.. grid-item-card:: pattern as the existing sections; and you
must also add a toctree entry for the new section to the same file
following the same tutorials/<section-name>/index.rst pattern as the existing
toctree entries.
Adding a new tutorial#
Download the tutorial card template
Download the tutorial structure template
Download the tutorial content formatting template
Location and naming#
New tutorials are Python .py files in the corresponding tutorial section folder,
for example: doc/sphinx_gallery_tutorials/section_name/new_tutorial.py
.
├── doc
│ ├── sphinx_gallery_tutorials
│ │ ├── section_name
│ │ │ ├── new_tutorial.py
You must also add a card to the section’s GALLERY_HEADER.rst.
The card must include:
a tutorial title,
a short description (same as the goal sentence in the tutorial file itself),
a link to the tutorial’s reference label.
Structure#
The tutorial file is divided in two main parts:
Header#
The tutorial file begins with:
MIT license block (21 lines) — copy verbatim from any existing tutorial file, updating only the year range if needed.
Ordering comment (line 23, immediately after the blank line that follows the license): sets the position of this tutorial within its section. Must be unique within the section.
Module docstring: the sphinx-gallery header that defines the RST page title, the cross-reference label, and the introductory text for this tutorial page.
The module docstring format is:
# _order: 1
"""
.. _ref_tutorial_template:
==============
Tutorial title
==============
A single sentence describing the goal of the tutorial, which must match the one on the
tutorial card in the section page.
Introduction to the tutorial. Here, you provide the necessary context or foundational
information for understanding the tutorial.
"""
The main PyDPF-Core library references are available in the doc/source/links_and_refs.rst
file. To use a substitution reference in a text cell or in the docstring, include it as
standard RST:
# Here we use the |MeshedRegion| substitution text.
For more information about the predefined references, see the
links and references file.
Content cells#
The goal of a tutorial is to present a feature or explain how to perform a common task step by step while explaining behaviors or underlying concepts. Thus, its structure must prioritize clarity, simplicity, and logical flow.
After the module docstring, the tutorial is organized as a series of cells separated
by a line of exactly 79 # characters (###...###).
Each cell is either a text cell (consecutive # ``-prefixed comment lines, full RST supported)
or a **code cell** (executable Python lines). A cell separator followed by ``# Title /
# ----- comment lines renders as an RST section heading in the output HTML.
The content steps are generally:
A first step where you get some data and create DPF objects based on the data;
One or more steps where you manipulate the data or the DPF objects;
A final step where you reach the objective of the tutorial and obtain the expected result.
For example:
A tutorial explains how to plot a mesh using PyDPF-Core. The steps to achieve this task are:
Import a result file;
Extract the mesh;
Plot the mesh.
To create a section heading, write the separator followed by the title and underline using ``# ``-prefixed comment lines:
###############################################################################
# Import result file
# ------------------
#
# First, you ...
###############################################################################
# Extract the mesh
# ----------------
#
# Then, you extract ...
###############################################################################
# Plot the mesh
# -------------
#
# Finally, you plot ...
Code blocks#
The tutorials must have code cells where you show how the task is actually implemented. In addition to the guidelines presented here, you must also follow the Coding style guide to ensure that all code looks the same across the project.
Executable code in tutorials is plain Python. There is no special directive; code cells are simply the lines of the file that are not prefixed with
#:
Correct
# This is a code cell (plain Python)
from ansys.dpf import core as dpf
Incorrect
.. jupyter-execute::
# This is a jupyter-execute block (old format)
from ansys.dpf import core as dpf
Use comments within a code block to clarify the purpose of a line:
Correct
# Define the model
my_model = dpf.Model(data_sources=ds)
# Get the stress results
stress_fc = my_model.results.stress.eval()
Incorrect
model = dpf.Model(data_sources=ds)
stress_fc = model.results.stress.eval()
Split code into separate cells using the
###...###separator to include longer text explanations or to force showing an intermediate output:
Correct
###############################################################################
# Step 1
# ------
#
# Explanation for a first code cell
# Code comment 1
code1
###############################################################################
# Step 2
# ------
#
# Explanation for a second code cell
# Code comment 2
code2
Incorrect
###############################################################################
# Step 1 and 2
# -------------
#
# A single broad explanation for both steps.
# Code comment 1
code1
# Code comment 2
code2
When using a PyDPF-Core object or method you must name arguments:
Correct
# Get the stress results
stress_fc = model.results.stress(time_scoping=time_steps).eval()
Incorrect
# Get the stress results
stress_fc = model.results.stress(time_steps).eval()
When quoting APIs in the code comments you must always use their scripting name. Mind the use of a capital letter to name the DPF objects
Correct
# Define the DataSources object
ds = dpf.DataSources()
Incorrect
# Define the data sources object
ds = dpf.DataSources()
# Define the Data Sources object
ds = dpf.DataSources()
Use blank lines between code lines for better clarity.
Correct
# Define the result file path
result_file_path_1 = dpf.core.examples.find_simple_bar()
# Define the DataSources object
ds_1 = dpf.DataSources(result_path=result_file_path_1)
# Create a Model
my_model_1 = dpf.Model(data_sources=ds_1)
# Get the stress results
stress_fc = my_model_1.results.stress.eval()
Incorrect
# Define the result file path
result_file_path_1 = dpf.core.examples.find_simple_bar()
# Define the DataSources object
ds_1 = dpf.DataSources(result_path=result_file_path_1)
# Create a Model
my_model_1 = dpf.Model(data_sources=ds_1)
# Get the stress results
stress_fc = my_model_1.results.stress.eval()
Avoid naming the variables with the same name as an argument or an API. You can get inspiration from the tutorials available at Tutorials.
Correct
# Define the result file path
result_file_path = dpf.core.examples.find_simple_bar()
# Define the DataSources object
ds = dpf.DataSources(result_path=result_file_path)
# Create a Model
my_model = dpf.Model(data_sources=ds)
Incorrect
# Define the result file path
result_path = dpf.core.examples.find_simple_bar()
# Define the DataSources object
data_sources = dpf.DataSources(result_path=result_path)
# Create a Model
model = dpf.Model(data_sources=data_sources)
Text formatting#
In addition to the guidelines presented here, you must also follow the Documentation style guide to ensure that the tutorials follow a coherent writing style across the project.
Text in tutorials is written as ``# ``-prefixed RST comment lines inside text cells.
When quoting APIs in the text you must always use a reference to redirect it to the API reference:
Correct
# Here we use the |MeshedRegion| substitution text.
Rendered text:
Here is some text. Here we use the MeshedRegion substitution text
Incorrect
# Here we do not use the MeshedRegion substitution text.
Rendered text:
Here is some text. Here we do not use the MeshedRegion substitution text
Use bullet lists when enumerating items:
Correct
# This operator accepts as arguments:
#
# - A Result
# - An Operator
# - A FieldsContainer
Incorrect
# This operator accepts a Result, an Operator or a
# FieldsContainer as arguments.
Use a numbered list for ordered items:
Correct
# To extract the mesh you need to follow those steps:
#
# #. Get the result file;
# #. Create a Model;
# #. Get the MeshedRegion.
The #. inside a text cell renders as a numbered list.
Incorrect
# To extract the mesh you need to follow those steps:
#
# - Get the result file;
# - Create a Model;
# - Get the MeshedRegion.
If you need to develop explanations for each item of the list, first, enumerate and reference them. Then, explore each of them separately in sub headings.
Correct
###############################################################################
# Section title
# -------------
#
# This section presents two items:
#
# - :ref:`Item 1 <ref_tutorial_name_item_1>`
# - :ref:`Item 2 <ref_tutorial_name_item_2>`
#
# .. _ref_tutorial_name_item_1:
#
# Item 1
# ^^^^^^
#
# Presentation of the first item...
# Code for item 1
###############################################################################
# .. _ref_tutorial_name_item_2:
#
# Item 2
# ^^^^^^
#
# Presentation of the second item...
# Code for item 2
Incorrect
###############################################################################
# Section title
# -------------
#
# This section presents two items:
#
# - Item 1
# - Item 2
#
# Item 1
# ^^^^^^
# Presentation of the first item...
# Code for item 1
# Item 2
# ^^^^^^
# Presentation of the second item...