Skip to main content
Mathematics LibreTexts

1.4: Defining Functions

  • Page ID
    181182
  • \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)

    \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)

    \( \newcommand{\dsum}{\displaystyle\sum\limits} \)

    \( \newcommand{\dint}{\displaystyle\int\limits} \)

    \( \newcommand{\dlim}{\displaystyle\lim\limits} \)

    \( \newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\)

    ( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\)

    \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)

    \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\)

    \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)

    \( \newcommand{\Span}{\mathrm{span}}\)

    \( \newcommand{\id}{\mathrm{id}}\)

    \( \newcommand{\Span}{\mathrm{span}}\)

    \( \newcommand{\kernel}{\mathrm{null}\,}\)

    \( \newcommand{\range}{\mathrm{range}\,}\)

    \( \newcommand{\RealPart}{\mathrm{Re}}\)

    \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)

    \( \newcommand{\Argument}{\mathrm{Arg}}\)

    \( \newcommand{\norm}[1]{\| #1 \|}\)

    \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)

    \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\AA}{\unicode[.8,0]{x212B}}\)

    \( \newcommand{\vectorA}[1]{\vec{#1}}      % arrow\)

    \( \newcommand{\vectorAt}[1]{\vec{\text{#1}}}      % arrow\)

    \( \newcommand{\vectorB}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)

    \( \newcommand{\vectorC}[1]{\textbf{#1}} \)

    \( \newcommand{\vectorD}[1]{\overrightarrow{#1}} \)

    \( \newcommand{\vectorDt}[1]{\overrightarrow{\text{#1}}} \)

    \( \newcommand{\vectE}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash{\mathbf {#1}}}} \)

    \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)

    \(\newcommand{\longvect}{\overrightarrow}\)

    \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)

    \(\newcommand{\avec}{\mathbf a}\) \(\newcommand{\bvec}{\mathbf b}\) \(\newcommand{\cvec}{\mathbf c}\) \(\newcommand{\dvec}{\mathbf d}\) \(\newcommand{\dtil}{\widetilde{\mathbf d}}\) \(\newcommand{\evec}{\mathbf e}\) \(\newcommand{\fvec}{\mathbf f}\) \(\newcommand{\nvec}{\mathbf n}\) \(\newcommand{\pvec}{\mathbf p}\) \(\newcommand{\qvec}{\mathbf q}\) \(\newcommand{\svec}{\mathbf s}\) \(\newcommand{\tvec}{\mathbf t}\) \(\newcommand{\uvec}{\mathbf u}\) \(\newcommand{\vvec}{\mathbf v}\) \(\newcommand{\wvec}{\mathbf w}\) \(\newcommand{\xvec}{\mathbf x}\) \(\newcommand{\yvec}{\mathbf y}\) \(\newcommand{\zvec}{\mathbf z}\) \(\newcommand{\rvec}{\mathbf r}\) \(\newcommand{\mvec}{\mathbf m}\) \(\newcommand{\zerovec}{\mathbf 0}\) \(\newcommand{\onevec}{\mathbf 1}\) \(\newcommand{\real}{\mathbb R}\) \(\newcommand{\twovec}[2]{\left[\begin{array}{r}#1 \\ #2 \end{array}\right]}\) \(\newcommand{\ctwovec}[2]{\left[\begin{array}{c}#1 \\ #2 \end{array}\right]}\) \(\newcommand{\threevec}[3]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \end{array}\right]}\) \(\newcommand{\cthreevec}[3]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \end{array}\right]}\) \(\newcommand{\fourvec}[4]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \\ #4 \end{array}\right]}\) \(\newcommand{\cfourvec}[4]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \\ #4 \end{array}\right]}\) \(\newcommand{\fivevec}[5]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \\ #4 \\ #5 \\ \end{array}\right]}\) \(\newcommand{\cfivevec}[5]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \\ #4 \\ #5 \\ \end{array}\right]}\) \(\newcommand{\mattwo}[4]{\left[\begin{array}{rr}#1 \amp #2 \\ #3 \amp #4 \\ \end{array}\right]}\) \(\newcommand{\laspan}[1]{\text{Span}\{#1\}}\) \(\newcommand{\bcal}{\cal B}\) \(\newcommand{\ccal}{\cal C}\) \(\newcommand{\scal}{\cal S}\) \(\newcommand{\wcal}{\cal W}\) \(\newcommand{\ecal}{\cal E}\) \(\newcommand{\coords}[2]{\left\{#1\right\}_{#2}}\) \(\newcommand{\gray}[1]{\color{gray}{#1}}\) \(\newcommand{\lgray}[1]{\color{lightgray}{#1}}\) \(\newcommand{\rank}{\operatorname{rank}}\) \(\newcommand{\row}{\text{Row}}\) \(\newcommand{\col}{\text{Col}}\) \(\renewcommand{\row}{\text{Row}}\) \(\newcommand{\nul}{\text{Nul}}\) \(\newcommand{\var}{\text{Var}}\) \(\newcommand{\corr}{\text{corr}}\) \(\newcommand{\len}[1]{\left|#1\right|}\) \(\newcommand{\bbar}{\overline{\bvec}}\) \(\newcommand{\bhat}{\widehat{\bvec}}\) \(\newcommand{\bperp}{\bvec^\perp}\) \(\newcommand{\xhat}{\widehat{\xvec}}\) \(\newcommand{\vhat}{\widehat{\vvec}}\) \(\newcommand{\uhat}{\widehat{\uvec}}\) \(\newcommand{\what}{\widehat{\wvec}}\) \(\newcommand{\Sighat}{\widehat{\Sigma}}\) \(\newcommand{\lt}{<}\) \(\newcommand{\gt}{>}\) \(\newcommand{\amp}{&}\) \(\definecolor{fillinmathshade}{gray}{0.9}\)

    Sage comes with many built-in functions. While Math terminology is not always standard, be sure to refer to the documentation to understand the exact functionality of these built-in functions and know how to use them. You can also define custom functions to suit your specific needs. You are welcome to use the custom functions we define in this book. However, since these custom functions are not part of the Sage source code, you will need to copy and paste the functions into your Sage environment. In this section, we’ll explore how to define custom functions and use them.

    To define a custom function in Sage, use the def keyword followed by the function name and the function’s arguments. The body of the function is indented, and it should contain a return statement that outputs a value. Note that the function definition will only be stored in memory after executing the cell. You won’t see any output when defining the function, but once it is defined, you can use it in other cells. If the cell is successfully executed, you will see a green box underneath it. If the box is not green, run the cell again to define the function.

    A simple example of defining a function is one that returns the nth (0-indexed) row of Pascal’s Triangle. Pascal’s Triangle is a triangular array of numbers where each number is the sum of the two numbers directly above it.

    Here’s a function definition that computes a specific row of Pascal’s Triangle. You need execute the cell to store the function in memory. You can only call the pascal_row() function once the definition has been executed. If you attempt to use the function without defining it first, you will receive a NameError.

    def pascal_row(n):
        return [binomial(n, i) for i in range(n + 1)]
     

    After defining the function above, let’s try calling it. :

    pascal_row(5)
    [1, 5, 10, 10, 5, 1]

    Sage functions can sometimes produce unexpected results if given improper input. For instance, passing a string or a decimal value into the function will raise a TypeError:

    pascal_row("5")
    ---------------------------------------------------------------------------
    TypeError                                 Traceback (most recent call last)
    Cell In[4], line 1
    ----> 1 pascal_row("5")
    
    Cell In[2], line 2, in pascal_row(n)
          1 def pascal_row(n):
    ----> 2     return [binomial(n, i) for i in range(n + Integer(1))]
    
    File /srv/conda/envs/notebook/lib/python3.8/site-packages/sage/rings/integer.pyx:1787, in sage.rings.integer.Integer.__add__ (build/cythonized/sage/rings/integer.c:12525)()
       1785         return y
       1786 
    -> 1787     return coercion_model.bin_op(left, right, operator.add)
       1788 
       1789 cpdef _add_(self, right):
    
    File /srv/conda/envs/notebook/lib/python3.8/site-packages/sage/structure/coerce.pyx:1248, in sage.structure.coerce.CoercionModel.bin_op (build/cythonized/sage/structure/coerce.c:11786)()
       1246     # We should really include the underlying error.
       1247     # This causes so much headache.
    -> 1248     raise bin_op_exception(op, x, y)
       1249 
       1250 cpdef canonical_coercion(self, x, y):
    
    TypeError: unsupported operand parent(s) for +: '<class 'str'>' and 'Integer Ring'

    However, if you pass a negative integer, the function will silently return an empty list. This lack of error handling can lead to unnoticed errors or unexpected behaviors that are difficult to debug, so it is essential to incorporate input validation. Let’s add a ValueError to handle negative input properly:

    def pascal_row(n):
        if n < 0:
            raise ValueError("`n` must be a non-negative integer")
        return [binomial(n, i) for i in range(n + 1)]
     

    With the updated function definition above, try calling the function again with a negative integer. You will now receive an informative error message rather than an empty list:

    pascal_row(-5)
    ---------------------------------------------------------------------------
    ValueError                                Traceback (most recent call last)
    Cell In[6], line 1
    ----> 1 pascal_row(-Integer(5))
    
    Cell In[5], line 3, in pascal_row(n)
          1 def pascal_row(n):
          2     if n < Integer(0):
    ----> 3         raise ValueError("`n` must be a non-negative integer")
          4     return [binomial(n, i) for i in range(n + Integer(1))]
    
    ValueError: `n` must be a non-negative integer

    Functions can also include a docstring in the function definition to describe its purpose, inputs, outputs, and any examples of usage. The docstring is a string that appears as the first statement in the function body. This documentation can be accessed using the help() function or the ? operator.

    def pascal_row(n):
        """
        Return row `n` of Pascal's triangle.
    
        INPUT:
        - ``n`` -- non-negative integer; the row number of Pascal's triangle to return.
          The row index starts from 0, which corresponds to the top row.
    
        OUTPUT: list; row `n` of Pascal's triangle as a list of integers.
    
        EXAMPLES:
        This example illustrates how to get various rows of Pascal's triangle (0-indexed) :
    
            sage: pascal_row(0)  # the top row
            [1]
            sage: pascal_row(4)
            [1, 4, 6, 4, 1]
    
        It is an error to provide a negative value for `n`:
            sage: pascal_row(-1)
            Traceback (most recent call last):
            ...
            ValueError: `n` must be a non-negative integer
    
        .. NOTE::
            This function uses the `binomial` function to compute each
            element of the row.
        """
        if n < 0:
            raise ValueError("`n` must be a non-negative integer")
    
        return [binomial(n, i) for i in range(n + 1)]
     

    After redefining the function, you can view the docstring by calling the help() function on the function name:

    help(pascal_row)
    Help on function pascal_row in module __main__:
    
    pascal_row(n)
        Return row `n` of Pascal's triangle.
        
        INPUT:
        - ``n`` -- non-negative integer; the row number of Pascal's triangle to return.
          The row index starts from 0, which corresponds to the top row.
        
        OUTPUT: list; row `n` of Pascal's triangle as a list of integers.
        
        EXAMPLES:
        This example illustrates how to get various rows of Pascal's triangle (0-indexed) :
        
            sage: pascal_row(0)  # the top row
            [1]
            sage: pascal_row(4)
            [1, 4, 6, 4, 1]
        
        It is an error to provide a negative value for `n`:
            sage: pascal_row(-1)
            Traceback (most recent call last):
            ...
            ValueError: `n` must be a non-negative integer
        
        .. NOTE::
            This function uses the `binomial` function to compute each
            element of the row.
    
    

    Alternatively, you can access the source code using the ?? operator:

    pascal_row??
    Signature: pascal_row(n)
    Docstring:
       Return row n of Pascal's triangle.
    
       INPUT: - "n" -- non-negative integer; the row number of Pascal's
       triangle to return.
    
          The row index starts from 0, which corresponds to the top row.
    
       OUTPUT: list; row n of Pascal's triangle as a list of integers.
    
       EXAMPLES: This example illustrates how to get various rows of
       Pascal's triangle (0-indexed) :
    
          sage: pascal_row(0)  # the top row [1] sage: pascal_row(4) [1,
          4, 6, 4, 1]
    
       It is an error to provide a negative value for n:
          sage: pascal_row(-1) Traceback (most recent call last): ...
          ValueError: n must be a non-negative integer
    
       Note:
    
         This function uses the binomial function to compute each element
         of the row.
    Source:   
    def pascal_row(n):
        """
        Return row `n` of Pascal's triangle.
    
        INPUT:
        - ``n`` -- non-negative integer; the row number of Pascal's triangle to return.
          The row index starts from 0, which corresponds to the top row.
    
        OUTPUT: list; row `n` of Pascal's triangle as a list of integers.
    
        EXAMPLES:
        This example illustrates how to get various rows of Pascal's triangle (0-indexed) :
    
            sage: pascal_row(0)  # the top row
            [1]
            sage: pascal_row(4)
            [1, 4, 6, 4, 1]
    
        It is an error to provide a negative value for `n`:
            sage: pascal_row(-1)
            Traceback (most recent call last):
            ...
            ValueError: `n` must be a non-negative integer
    
        .. NOTE::
            This function uses the `binomial` function to compute each
            element of the row.
        """
        if n < Integer(0):
            raise ValueError("`n` must be a non-negative integer")
    
        return [binomial(n, i) for i in range(n + Integer(1))]
    File:      ~/<ipython-input-7-b46457fa0781>
    Type:      function

    To learn more on code style conventions and writing documentation strings, refer to the General Conventions article in the Sage Developer’s Guide.


    1.4: Defining Functions is shared under a CC BY 4.0 license and was authored, remixed, and/or curated by LibreTexts.

    • Was this article helpful?