<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Scientific software | Victor Boussange</title>
    <link>https://vboussange.github.io/tag/scientific-software/</link>
      <atom:link href="https://vboussange.github.io/tag/scientific-software/index.xml" rel="self" type="application/rss+xml" />
    <description>Scientific software</description>
    <generator>Wowchemy (https://wowchemy.com)</generator><language>en-us</language><lastBuildDate>Thu, 01 Jan 2026 00:00:00 +0000</lastBuildDate>
    <image>
      <url>https://vboussange.github.io/media/icon_hua3c898eed18b98379688891d5011a1d0_203625_512x512_fill_lanczos_center_3.png</url>
      <title>Scientific software</title>
      <link>https://vboussange.github.io/tag/scientific-software/</link>
    </image>
    
    <item>
      <title>AMJAX</title>
      <link>https://vboussange.github.io/software/amjax/</link>
      <pubDate>Thu, 01 Jan 2026 00:00:00 +0000</pubDate>
      <guid>https://vboussange.github.io/software/amjax/</guid>
      <description></description>
    </item>
    
    <item>
      <title>jaxscape</title>
      <link>https://vboussange.github.io/software/jaxscape/</link>
      <pubDate>Thu, 01 Jan 2026 00:00:00 +0000</pubDate>
      <guid>https://vboussange.github.io/software/jaxscape/</guid>
      <description></description>
    </item>
    
    <item>
      <title>A course on reproducible research, data pipelines, and scientific computing</title>
      <link>https://vboussange.github.io/funding/cords-course/</link>
      <pubDate>Tue, 11 Jun 2024 00:00:00 +0000</pubDate>
      <guid>https://vboussange.github.io/funding/cords-course/</guid>
      <description></description>
    </item>
    
    <item>
      <title>Practical introduction to Julia for biodiversity research</title>
      <link>https://vboussange.github.io/resource/julia-biodiversity-workshop/</link>
      <pubDate>Wed, 01 Mar 2023 00:00:00 +0000</pubDate>
      <guid>https://vboussange.github.io/resource/julia-biodiversity-workshop/</guid>
      <description></description>
    </item>
    
    <item>
      <title>HybridDynamicModels.jl</title>
      <link>https://vboussange.github.io/software/hybrid-dynamic-models/</link>
      <pubDate>Wed, 01 Jan 2025 00:00:00 +0000</pubDate>
      <guid>https://vboussange.github.io/software/hybrid-dynamic-models/</guid>
      <description></description>
    </item>
    
    <item>
      <title>yDiv workshop funding</title>
      <link>https://vboussange.github.io/funding/ydiv-julia-workshop/</link>
      <pubDate>Thu, 01 Aug 2024 00:00:00 +0000</pubDate>
      <guid>https://vboussange.github.io/funding/ydiv-julia-workshop/</guid>
      <description></description>
    </item>
    
    <item>
      <title>Course On Reproducible Research, Data Pipelines, and Scientific Computing</title>
      <link>https://vboussange.github.io/resource/cords/</link>
      <pubDate>Tue, 11 Jun 2024 00:00:00 +0000</pubDate>
      <guid>https://vboussange.github.io/resource/cords/</guid>
      <description></description>
    </item>
    
    <item>
      <title>WSL Biodiversity Center Innovative Workshop Grant</title>
      <link>https://vboussange.github.io/funding/wsl-biodiversity-workshop/</link>
      <pubDate>Wed, 01 Mar 2023 00:00:00 +0000</pubDate>
      <guid>https://vboussange.github.io/funding/wsl-biodiversity-workshop/</guid>
      <description></description>
    </item>
    
    <item>
      <title>EcoEvoModelZoo.jl</title>
      <link>https://vboussange.github.io/software/ecoevomodelzoo/</link>
      <pubDate>Sun, 26 Mar 2023 00:00:00 +0000</pubDate>
      <guid>https://vboussange.github.io/software/ecoevomodelzoo/</guid>
      <description></description>
    </item>
    
    <item>
      <title>EvoId.jl</title>
      <link>https://vboussange.github.io/software/evoid/</link>
      <pubDate>Fri, 01 Jan 2021 00:00:00 +0000</pubDate>
      <guid>https://vboussange.github.io/software/evoid/</guid>
      <description></description>
    </item>
    
    <item>
      <title>Developing an algebraic multigrid solver in JAX</title>
      <link>https://vboussange.github.io/studentprojects/amg_jax/</link>
      <pubDate>Wed, 19 Nov 2025 00:00:00 +0000</pubDate>
      <guid>https://vboussange.github.io/studentprojects/amg_jax/</guid>
      <description>&lt;p&gt;Multigrid methods represent the state-of-the-art for solving large-scale linear systems arising from discretized partial differential equations, offering optimal computational complexity for many problem classes.&lt;/p&gt;
&lt;p&gt;Established implementations such as &lt;a href=&#34;https://github.com/pyamg/pyamg&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;pyAMG&lt;/a&gt; and &lt;a href=&#34;https://github.com/JuliaLinearAlgebra/AlgebraicMultigrid.jl&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;AMG.jl&lt;/a&gt; provide robust solvers but lack two critical capabilities for modern scientific machine learning: GPU acceleration and automatic differentiation compatibility. These features are essential for scientific machine learning workflows where differentiable simulation components (e.g., neural networks embedded in physical models) require efficient iterative solves with gradient backpropagation for end-to-end optimization.&lt;/p&gt;
&lt;p&gt;This project aims to develop an algebraic multigrid (AMG) solver in JAX that natively supports automatic differentiation and GPU acceleration. The work involves analyzing existing Python and Julia implementations to design an architecture compatible with JAX&amp;rsquo;s functional programming paradigm and just-in-time compilation model. A successful implementation could have substantial impact on the JAX ecosystem, from &lt;a href=&#34;https://github.com/deepmodeling/jax-fem&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;accelerating finite element packages&lt;/a&gt; to &lt;a href=&#34;https://github.com/vboussange/jaxscape&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;accelerating ecological connectivity analysis&lt;/a&gt; tools.&lt;/p&gt;
&lt;p&gt;The project scope is flexible and can emphasize software engineering or algorithmic optimization depending on the student&amp;rsquo;s background and interests. Prior experience with JAX or advanced numerical linear algebra is beneficial but not required; students will gain deep expertise in iterative solvers, functional programming patterns, and best practices for scientific open-source software development.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>A multi-language overview on how to document your research project code</title>
      <link>https://vboussange.github.io/post/documenting-your-research-code/</link>
      <pubDate>Tue, 11 Jun 2024 00:00:00 +0000</pubDate>
      <guid>https://vboussange.github.io/post/documenting-your-research-code/</guid>
      <description>&lt;p&gt;Documentation serves multiple purposes and may be useful for various audiences, including your future self, collaborators, users and contributors - should you aim at packaging some of your code into a general-purpose library.&lt;/p&gt;
&lt;p&gt;This post is part of a series of posts on best practices for managing research project code. Much of this material was developed in collaboration with &lt;a href=&#34;https://github.com/mauro3&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Mauro Werder&lt;/a&gt; as part of the &lt;a href=&#34;https://github.com/mauro3/CORDS/tree/master&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Course On Reproducible Research, Data Pipelines, and Scientific Computing (CORDS)&lt;/a&gt;. If you have experiences to share or spot any errors, please reach out!&lt;/p&gt;
&lt;h2 id=&#34;content&#34;&gt;Content&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;#content&#34;&gt;Content&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;#style-guides&#34;&gt;Style guides&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#comments&#34;&gt;Comments&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#literal-documentation&#34;&gt;Literal documentation&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;#readme&#34;&gt;README&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#api-documentation--doc-strings&#34;&gt;API documentation / doc strings&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#type-annotations&#34;&gt;Type annotations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#consider-raising-errors&#34;&gt;Consider raising errors&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#tutorials&#34;&gt;Tutorials&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#accessing-documentation&#34;&gt;Accessing documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#doc-testing&#34;&gt;Doc testing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#useful-packages-to-help-you-write-and-lint-your-documentation&#34;&gt;Useful packages to help you write and lint your documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#more-resources&#34;&gt;More resources&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#take-home-messages&#34;&gt;Take home messages&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;style-guides&#34;&gt;Style guides&lt;/h3&gt;
&lt;p&gt;The best documentation starts by writing self-explanatory code with good conventions.&lt;/p&gt;
&lt;p&gt;Correctly naming your variables enhances code clarity.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;There are only two hard things in Computer Science: cache invalidation and naming things.
&lt;em&gt;Martin Fowler&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Instead of using generic names like &lt;code&gt;l&lt;/code&gt; for a list:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;for l in L:
    pass
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Use descriptive names like&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;for line in lines:
    pass
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Using style guides for your chosen language ensures consistency and readability in your code. Here are some resources:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.julialang.org/en/v1/manual/style-guide/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Julia style guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://google.github.io/styleguide/pyguide.html&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Google python style guide&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Do not hesitate to refactor your code regularly and remove dead code to prevent confusion for yourself and others.&lt;/p&gt;
&lt;h3 id=&#34;comments&#34;&gt;Comments&lt;/h3&gt;
&lt;p&gt;In-line comments should be used sparingly. Aim to write self-explanatory code instead. Use comments to provide context not apparent from the code itself, such as references to papers, Stack Overflow topics, or TODOs.&lt;/p&gt;
&lt;p&gt;Use single-line comments for brief explanations and multi-line comments for more detailed information.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;julia&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cm&#34;&gt;#=
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cm&#34;&gt;This is a multi-line
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cm&#34;&gt;comment
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cm&#34;&gt;=#&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;python&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;This is a multi-line
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;comment
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Tip: use vscode &lt;code&gt;rewrap comment/text&lt;/code&gt; to nicely format multiline comments.&lt;/p&gt;
&lt;p&gt;On top of nicely formatting your code and appending comments where necessary, a literal documentation greatly facilitates the maintenance, understandability and reproducibility of your code.&lt;/p&gt;
&lt;h3 id=&#34;literal-documentation&#34;&gt;Literal documentation&lt;/h3&gt;
&lt;p&gt;Literal documentation helps users understand your tool and get started with it.&lt;/p&gt;
&lt;h4 id=&#34;readme&#34;&gt;README&lt;/h4&gt;
&lt;p&gt;A README file is essential for any research repository. It is displayed on under the code structure when accessing a GitHub repo.
It should contain:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;(Badges showing tests, and a nice logo)&lt;/li&gt;
&lt;li&gt;A one-sentence description of your project&lt;/li&gt;
&lt;li&gt;A longer description&lt;/li&gt;
&lt;li&gt;An overview of the repository structure and files&lt;/li&gt;
&lt;li&gt;A &lt;em&gt;Getting started&lt;/em&gt; or &lt;em&gt;Examples&lt;/em&gt; section&lt;/li&gt;
&lt;li&gt;An &lt;em&gt;Installation&lt;/em&gt; section with dependencies&lt;/li&gt;
&lt;li&gt;A &lt;em&gt;Citation&lt;/em&gt;/&lt;em&gt;Reference&lt;/em&gt; section&lt;/li&gt;
&lt;li&gt;(A link to the documentation)&lt;/li&gt;
&lt;li&gt;(A &lt;em&gt;How to contribute&lt;/em&gt; section)&lt;/li&gt;
&lt;li&gt;An &lt;em&gt;Acknowledgement&lt;/em&gt; section&lt;/li&gt;
&lt;li&gt;A &lt;em&gt;License&lt;/em&gt; section&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Some examples:&lt;/p&gt;
&lt;!-- - [HighDimPDE.jl](https://github.com/SciML/HighDimPDE.jl)
- [Code for HighDimPDE paper](https://github.com/SciML/HighDimPDE.jl)
- [Code for PiecewiseInference paper](https://github.com/vboussange/partitioning-time-series) --&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/microsoft/satclip&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;SatClip&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/google-deepmind/graphcast&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;GraphCast&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/google-deepmind/alphafold&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Alphafold&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;api-documentation--doc-strings&#34;&gt;API documentation / doc strings&lt;/h4&gt;
&lt;p&gt;API documentation describes the usage of functions, classes (types) and modules (packages). Parsers usually support markdown styles, which also enhances raw readability for humans. In short, markdown styles consists in using&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;backticks &lt;code&gt;`&lt;/code&gt; for variable names&lt;/li&gt;
&lt;li&gt;&lt;code&gt;#&lt;/code&gt; for titles,&lt;/li&gt;
&lt;li&gt;&amp;hellip;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/carpentries-incubator/markdown-intro&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;See here for an introduction to markdown&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Doc strings in python live inside the function&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;best_function_ever&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a_param&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;another_parameter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;    this is the docstring
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;    &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;# do some stuff&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;But above the function or type definition in Julia&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;this is the docstring
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;best_function_ever&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a_param&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;another_parameter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;# do some stuff&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;Tell whether there are too foo items in the array.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;foo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xs&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Array&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Best practice for docstrings include&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;(in Julia: insert the signature of your function )&lt;/li&gt;
&lt;li&gt;Short description&lt;/li&gt;
&lt;li&gt;Arguments (Args, Input,&amp;hellip;)&lt;/li&gt;
&lt;li&gt;Returns&lt;/li&gt;
&lt;li&gt;Examples&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Several flavours may be used, even for a single language.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;python&lt;/strong&gt;
3 Different documentation style flavours&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://sphinx-rtd-tutorial.readthedocs.io/en/latest/docstrings.html&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;reST (reStructuredText)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://sphinxcontrib-napoleon.readthedocs.io/en/latest/example_google.html&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Google style&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://sphinxcontrib-napoleon.readthedocs.io/en/latest/example_numpy.html&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Numpy style&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Google style is easier to read for humans&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;    Add two integers.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;    This function takes two integer arguments and returns their sum.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;    # Parameters:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;    a: The first integer to be added.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;    b: The second integer to be added.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;    # Return:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;    int: The sum of the two integers.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;    # Raise:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;    TypeError: If either of the arguments is not an integer.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;    Examples:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;    &amp;gt;&amp;gt;&amp;gt; add(2, 3)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;    5
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;    &amp;gt;&amp;gt;&amp;gt; add(-1, 1)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;    0
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;    &amp;gt;&amp;gt;&amp;gt; add(&amp;#39;a&amp;#39;, 1)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;    Traceback (most recent call last):
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;        ...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;    TypeError: Both arguments must be integers.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;    &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;isinstance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;or&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;isinstance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;raise&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;TypeError&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Both arguments must be integers&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;julia&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;    add(a, b)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;Adds two integers.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;This function takes two integer arguments and returns their sum.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;# Arguments
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;- `a`: The first integer to be added.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;- `b`: The second integer to be added.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;# Returns
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;- The sum of the two integers.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;# Examples
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;```julia-repl
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;julia&amp;gt; add(2, 3)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;5
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;julia&amp;gt; add(-1, 1)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;0
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;```
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You may use tools like &lt;a href=&#34;&#34;&gt;&lt;code&gt;Documenter.jl&lt;/code&gt;&lt;/a&gt; or &lt;a href=&#34;https://docs.readthedocs.io/en/stable/intro/getting-started-with-sphinx.html&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;&lt;code&gt;Sphinx&lt;/code&gt;&lt;/a&gt; to automatically render your API documentation on a website. Github actions can automatize the process of building the documentation for you, similarly to how it can automate testing.&lt;/p&gt;
&lt;p&gt;Docstrings may be accompanied by typing.&lt;/p&gt;
&lt;h4 id=&#34;type-annotations&#34;&gt;Type annotations&lt;/h4&gt;
&lt;p&gt;Typing refers to the specification of variable types and function return types within a programming language. It helps define what kind of data a function or variable can handle, ensuring type safety and reducing runtime errors. It&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;clearly indicates the expected input and output types, making the code easier to understand.&lt;/li&gt;
&lt;li&gt;helps catch type-related errors early in the development process.&lt;/li&gt;
&lt;li&gt;encourages consistent usage of types throughout the codebase.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;python&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In Python, using typing does not enforce type checking at runtime! You may use decorators to enforce it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;julia&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;Int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In Julia, types are enforced at runtime! Type annotations help the Julia compiler optimize performance by making type inferences easier.&lt;/p&gt;
&lt;h4 id=&#34;consider-raising-errors&#34;&gt;Consider raising errors&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;We do not like reading manuals. But we are foreced to read error messages. Use assertions and error messages to handle unexpected inputs and guide users.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;python&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;assert&lt;/code&gt;: When an assert doesn’t pass, it raises an AssertionError. You can optionally add an error message at the end.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;NotImplementedError&lt;/code&gt;, &lt;code&gt;ValueError&lt;/code&gt;, &lt;code&gt;NameError&lt;/code&gt;: Commonly used, generic errors you can raise. I probably overuse &lt;code&gt;NotImplementedError&lt;/code&gt; compared to other types.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;convolve_vectors&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vec1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;vec2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;isinstance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vec1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;or&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;isinstance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vec2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;raise&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;ValueError&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Both inputs must be lists.&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;# convolve the vectors&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;tutorials&#34;&gt;Tutorials&lt;/h4&gt;
&lt;p&gt;Create tutorial Jupyter notebooks or vignettes in R to demonstrate the usage of your code. Those can be placed in a folder &lt;code&gt;examples&lt;/code&gt; or &lt;code&gt;tutorials&lt;/code&gt;. Format them as e.g.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;vignettes in R,&lt;/li&gt;
&lt;li&gt;or using Jupyter notebooks, which are the perfect format for tutorials&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;accessing-documentation&#34;&gt;Accessing documentation&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;julia&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;?&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cos&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;?&lt;/span&gt;&lt;span class=&#34;nd&#34;&gt;@time&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;?&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;sr&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;python&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;help&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;myfun&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;But e.g. VSCode can be also quite helpful, and this works also with your own code!&lt;/p&gt;
&lt;p&gt;















&lt;figure  &gt;
  &lt;div class=&#34;d-flex justify-content-center&#34;&gt;
    &lt;div class=&#34;w-100&#34; &gt;&lt;img alt=&#34;&#34; srcset=&#34;
               /post/documenting-your-research-code/figures/hover_doc_hue5248cd512781ef3756192bdda7faf1a_134874_76ec06524fcce10c0f16204c1bae71b0.webp 400w,
               /post/documenting-your-research-code/figures/hover_doc_hue5248cd512781ef3756192bdda7faf1a_134874_6061565650d9d825bd665837e8145a7e.webp 760w,
               /post/documenting-your-research-code/figures/hover_doc_hue5248cd512781ef3756192bdda7faf1a_134874_1200x1200_fit_q75_h2_lanczos_3.webp 1200w&#34;
               src=&#34;https://vboussange.github.io/post/documenting-your-research-code/figures/hover_doc_hue5248cd512781ef3756192bdda7faf1a_134874_76ec06524fcce10c0f16204c1bae71b0.webp&#34;
               width=&#34;760&#34;
               height=&#34;281&#34;
               loading=&#34;lazy&#34; data-zoomable /&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 id=&#34;doc-testing&#34;&gt;Doc testing&lt;/h3&gt;
&lt;p&gt;Doc testing, or doctest, allows you to test your code by running examples embedded in the documentation (docstrings). It compares the output of the examples with the expected results given in the docstrings, ensuring the code works as documented.&lt;/p&gt;
&lt;p&gt;Why doc testing?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ensures that the code examples in your documentation are accurate and up-to-date.&lt;/li&gt;
&lt;li&gt;Simple to write and understand, making it accessible for both writing and reading tests.&lt;/li&gt;
&lt;li&gt;Promotes writing comprehensive docstrings which enhance code readability and maintainability.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Python&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;    Adds two numbers.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;    &amp;gt;&amp;gt;&amp;gt; add(2, 3)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;    5
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;    &amp;gt;&amp;gt;&amp;gt; add(-1, 1)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;    0
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;    &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;To run the test:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;python -m doctest your_module.py
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;or from within a script&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;vm&#34;&gt;__name__&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;__main__&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;doctest&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;doctest&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;testmod&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;julia&lt;/strong&gt;
Available through &lt;code&gt;Documenter.jl&lt;/code&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;Adds two numbers.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;```jldoctest
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;julia&amp;gt; add(2, 3)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;5
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;julia&amp;gt; add(-1, 1)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;0
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;```
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;useful-packages-to-help-you-write-and-lint-your-documentation&#34;&gt;Useful packages to help you write and lint your documentation&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Better Comments
















&lt;figure  &gt;
  &lt;div class=&#34;d-flex justify-content-center&#34;&gt;
    &lt;div class=&#34;w-100&#34; &gt;&lt;img alt=&#34;&#34; srcset=&#34;
               /post/documenting-your-research-code/figures/bettercomments_hue8d71157385fa06c441962f01b246252_98866_aa3af5f002621707c5158a2f1e26e303.webp 400w,
               /post/documenting-your-research-code/figures/bettercomments_hue8d71157385fa06c441962f01b246252_98866_07a116dc3aa99ed2567f79e7697020cb.webp 760w,
               /post/documenting-your-research-code/figures/bettercomments_hue8d71157385fa06c441962f01b246252_98866_1200x1200_fit_q75_h2_lanczos.webp 1200w&#34;
               src=&#34;https://vboussange.github.io/post/documenting-your-research-code/figures/bettercomments_hue8d71157385fa06c441962f01b246252_98866_aa3af5f002621707c5158a2f1e26e303.webp&#34;
               width=&#34;760&#34;
               height=&#34;544&#34;
               loading=&#34;lazy&#34; data-zoomable /&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;Automatic doc string generation
















&lt;figure  &gt;
  &lt;div class=&#34;d-flex justify-content-center&#34;&gt;
    &lt;div class=&#34;w-100&#34; &gt;&lt;img alt=&#34;&#34; srcset=&#34;
               /post/documenting-your-research-code/figures/autodocstring_hua804b0c52ef1ab401e5e02b31f5ca79b_125033_61e87bdfae0bd5a33fcb138c38dfd62b.webp 400w,
               /post/documenting-your-research-code/figures/autodocstring_hua804b0c52ef1ab401e5e02b31f5ca79b_125033_403c51a21759d5cc74ab93df35bd69e5.webp 760w,
               /post/documenting-your-research-code/figures/autodocstring_hua804b0c52ef1ab401e5e02b31f5ca79b_125033_1200x1200_fit_q75_h2_lanczos.webp 1200w&#34;
               src=&#34;https://vboussange.github.io/post/documenting-your-research-code/figures/autodocstring_hua804b0c52ef1ab401e5e02b31f5ca79b_125033_61e87bdfae0bd5a33fcb138c38dfd62b.webp&#34;
               width=&#34;760&#34;
               height=&#34;532&#34;
               loading=&#34;lazy&#34; data-zoomable /&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;Python test explorer
















&lt;figure  &gt;
  &lt;div class=&#34;d-flex justify-content-center&#34;&gt;
    &lt;div class=&#34;w-100&#34; &gt;&lt;img alt=&#34;&#34; srcset=&#34;
               /post/documenting-your-research-code/figures/pythontest_hu5db1f42aa0e77083c56b38ab5823f0c6_102106_ad4bfb4c17ac2034c832e694e2afd772.webp 400w,
               /post/documenting-your-research-code/figures/pythontest_hu5db1f42aa0e77083c56b38ab5823f0c6_102106_552e2d65b4d7411fd6d930b81b8d61e7.webp 760w,
               /post/documenting-your-research-code/figures/pythontest_hu5db1f42aa0e77083c56b38ab5823f0c6_102106_1200x1200_fit_q75_h2_lanczos.webp 1200w&#34;
               src=&#34;https://vboussange.github.io/post/documenting-your-research-code/figures/pythontest_hu5db1f42aa0e77083c56b38ab5823f0c6_102106_ad4bfb4c17ac2034c832e694e2afd772.webp&#34;
               width=&#34;760&#34;
               height=&#34;549&#34;
               loading=&#34;lazy&#34; data-zoomable /&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;/figure&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;more-resources&#34;&gt;More resources&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://docs.julialang.org/en/v1/manual/documentation/#Writing-Documentation&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Julia documentation recommendations&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://goodresearch.dev/docs&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Good research tutorial on documentation&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://carpentries-incubator.github.io/python-packaging-publishing/05-documentation-types-roles/index.html&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Carpentries incubator on packaging and publish python - type roles&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://carpentries-incubator.github.io/python-packaging-publishing/06-documentation-in-code/index.html&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Carpentries incubator on packaging and publish python - documentation in code&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;take-home-messages&#34;&gt;Take home messages&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Good documentation helps maintain the long-term memory of a project.&lt;/li&gt;
&lt;li&gt;Refactor code to reduce complexity instead of documenting tricky code.&lt;/li&gt;
&lt;li&gt;Writing unit tests is often more productive than extensive documentation.&lt;/li&gt;
&lt;li&gt;Types of documentation include literal, API, and tutorial/example documentation.&lt;/li&gt;
&lt;li&gt;Literal documentation explains the big picture and setup.&lt;/li&gt;
&lt;li&gt;API documentation lives in docstrings and explains function usage.&lt;/li&gt;
&lt;li&gt;Examples connect the details to common tasks.&lt;/li&gt;
&lt;li&gt;Consider using tools like ChatGPT to assist with documenting your functions.&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>A multi-language overview on how to handle dependencies within a research project</title>
      <link>https://vboussange.github.io/post/research-project-dependencies/</link>
      <pubDate>Tue, 11 Jun 2024 00:00:00 +0000</pubDate>
      <guid>https://vboussange.github.io/post/research-project-dependencies/</guid>
      <description>&lt;p&gt;Your future self and others should be able to recreate the minimal environment to run the scripts in your research project. This is best achieved using &lt;strong&gt;package managers&lt;/strong&gt;  and &lt;strong&gt;virtual environments&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;This post is part of a series of posts on best practices for managing research project code. Much of this material was developed in collaboration with &lt;a href=&#34;https://github.com/mauro3&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Mauro Werder&lt;/a&gt; as part of the &lt;a href=&#34;https://github.com/mauro3/CORDS/tree/master&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Course On Reproducible Research, Data Pipelines, and Scientific Computing (CORDS)&lt;/a&gt;. If you have experiences to share or spot any errors, please reach out!&lt;/p&gt;
&lt;h2 id=&#34;content&#34;&gt;Content&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;#content&#34;&gt;Content&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#some-definitions&#34;&gt;Some definitions&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;#what-is-a-dependency&#34;&gt;What is a dependency?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#what-is-a-package-manager&#34;&gt;What is a package manager?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#what-is-a-virtual-environment&#34;&gt;What is a virtual environment?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#package-managers&#34;&gt;Package managers&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;#multilanguage-overview&#34;&gt;Multilanguage overview&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;#conda&#34;&gt;&lt;code&gt;conda&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#renv&#34;&gt;&lt;code&gt;renv&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#pkg&#34;&gt;&lt;code&gt;Pkg&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#environment-files&#34;&gt;Environment files&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;#julia&#34;&gt;Julia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#python&#34;&gt;Python&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#r&#34;&gt;R&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#working-with-interactive-environments&#34;&gt;Working with interactive environments&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#caveats-of-virtual-environments&#34;&gt;Caveats of virtual environments&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#advanced-topic-package-development&#34;&gt;Advanced topic: package development&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#take-home-messages&#34;&gt;Take-home messages&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;some-definitions&#34;&gt;Some definitions&lt;/h2&gt;
&lt;h3 id=&#34;what-is-a-dependency&#34;&gt;What is a dependency?&lt;/h3&gt;
&lt;p&gt;A &lt;strong&gt;dependency&lt;/strong&gt;  is an external package that a project requires to run.&lt;/p&gt;
&lt;h3 id=&#34;what-is-a-package-manager&#34;&gt;What is a package manager?&lt;/h3&gt;
&lt;p&gt;A &lt;strong&gt;package manager&lt;/strong&gt; like &lt;code&gt;conda&lt;/code&gt;, &lt;code&gt;Pkg&lt;/code&gt; or &lt;code&gt;renv&lt;/code&gt; &lt;strong&gt;automates the process of installing, upgrading, configuring, and managing dependencies&lt;/strong&gt;. It usually relies on a &lt;strong&gt;package repository&lt;/strong&gt;, which is a central location that stores in one place the source code of packages or where to find it.&lt;/p&gt;
&lt;h3 id=&#34;what-is-a-virtual-environment&#34;&gt;What is a virtual environment?&lt;/h3&gt;
&lt;p&gt;A &lt;strong&gt;virtual environment&lt;/strong&gt; is an isolated environment where you can install and manage dependencies separately from the system-wide installation. This isolation ensures that different projects can have different dependencies and versions of packages without causing conflicts. Why use a virtual environment?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;For yourself, to best deal with multiple projects and to prevent your code from breaking down overtime.
&lt;ul&gt;
&lt;li&gt;Without specifying a virtual environment, you install packages in your base environment, which is shared across all your projects.&lt;/li&gt;
&lt;li&gt;Imagine you are working with Project A and Project B, which both depend on Package1 (currently @v1.1).&lt;/li&gt;
&lt;li&gt;You leave aside Project A for a few months, and focus on Project B.&lt;/li&gt;
&lt;li&gt;A new feature in Package1 motivate you to upgrade to v1.2, which modifies the API or the behavior of one function used in both projects.&lt;/li&gt;
&lt;li&gt;You then want to come back to Project A, but now everything is broken! Because your code has been formatted to work with &lt;a href=&#34;mailto:Package1@v1.1&#34;&gt;Package1@v1.1&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Hence, you want to make sure to compartmentalize environments.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;To share your environment with others individuals and machines.
&lt;ul&gt;
&lt;li&gt;A virtual environement tracks the minimum dependencies, which can easily be shared and installed on other machines (e.g., a HPC).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;package-managers&#34;&gt;Package managers&lt;/h2&gt;
&lt;h3 id=&#34;multilanguage-overview&#34;&gt;Multilanguage overview&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Python&lt;/th&gt;
&lt;th&gt;R&lt;/th&gt;
&lt;th&gt;Julia&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Package Manager&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pip&lt;/code&gt;, &lt;code&gt;conda&lt;/code&gt; (see also &lt;code&gt;mamba&lt;/code&gt;), &lt;code&gt;poetry&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;install.packages()&lt;/code&gt; (base R)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Pkg&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Package Repository&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;PyPI (Python Package Index), &lt;code&gt;conda-forge&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;CRAN (Comprehensive R Archive Network)&lt;/td&gt;
&lt;td&gt;General registry&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Distribution Format&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.whl&lt;/code&gt; (wheel, incl binaries) or &lt;code&gt;tar.gz&lt;/code&gt; (source)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.tar.gz&lt;/code&gt; (source and/or binary)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Pkg&lt;/code&gt; will git clone from source, and download (binary) artifacts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Virtual Environment&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;venv&lt;/code&gt;, &lt;code&gt;virtualenv&lt;/code&gt;, &lt;code&gt;conda env&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;renv&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Built-in in the &lt;code&gt;Pkg&lt;/code&gt; module&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Dependency Management&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;requirements.txt&lt;/code&gt; or &lt;code&gt;Pipfile&lt;/code&gt; (&lt;code&gt;pip&lt;/code&gt;), or &lt;code&gt;environment.yml&lt;/code&gt; (&lt;code&gt;conda env&lt;/code&gt;) or &lt;code&gt;pyproject.toml&lt;/code&gt; (&lt;code&gt;poetry&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;DESCRIPTION&lt;/code&gt;, &lt;code&gt;NAMESPACE&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Project.toml&lt;/code&gt;, &lt;code&gt;Manifest.toml&lt;/code&gt;, &lt;code&gt;Artifacts.toml&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;This table is very much inspired by &lt;a href=&#34;https://scientificcoder.com/comparing-package-management-in-python-r-julia-and-rust&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;The Scientific Coder article&lt;/a&gt; on package managers.&lt;/p&gt;
&lt;p&gt;Julia or R have built-in package managers which can be called within the REPL but Python package managers are called from outside the language.&lt;/p&gt;
&lt;h4 id=&#34;conda&#34;&gt;&lt;code&gt;conda&lt;/code&gt;&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;conda&lt;/code&gt; is a very appropriate package manager for scientific projects in Python. Over its older concurrent &lt;code&gt;pip&lt;/code&gt;, it can handle python versions and all sorts non-python dependencies artifacts. With two lines of code, it allows someone to quickly install the virtual environment, without any pre-requiste python installation.&lt;/p&gt;
&lt;p&gt;Here are some essential &lt;code&gt;conda&lt;/code&gt; commands.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;conda create --name myenv &lt;span class=&#34;c1&#34;&gt;# creates new virtual environment&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;conda activate myenv &lt;span class=&#34;c1&#34;&gt;# activate the environment&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;conda install numpy -c conda-forge &lt;span class=&#34;c1&#34;&gt;# install a package&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;conda deactivate
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Note that not using &lt;code&gt;-c conda-forge&lt;/code&gt; will do just fine, but what is it? &lt;code&gt;conda-forge&lt;/code&gt; is a community-driven &lt;strong&gt;channel&lt;/strong&gt; (repository in the python jargon) that often has more up-to-date packages and a broader selection than the default Anaconda repository. You should use for several reasons, but mostly because &lt;code&gt;conda-forge&lt;/code&gt; generally has the largest volume of packages and the most up-to-date versions&lt;/p&gt;
&lt;p&gt;Note that some packages are only available through PyPi (&lt;code&gt;pip&lt;/code&gt;). But you are covered for that: You can install &lt;code&gt;pip&lt;/code&gt; packages within a &lt;code&gt;conda env&lt;/code&gt;, by first activating the &lt;code&gt;conda env&lt;/code&gt; and then normally using &lt;code&gt;pip&lt;/code&gt;. &lt;code&gt;pip&lt;/code&gt; should be part of your dependencies though. Always try to install packages using &lt;code&gt;conda&lt;/code&gt; first.&lt;/p&gt;
&lt;p&gt;We highly recommend using &lt;a href=&#34;https://mamba.readthedocs.io/en/latest/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;&lt;code&gt;mamba&lt;/code&gt;&lt;/a&gt; as a drop-in replacement for &lt;code&gt;conda&lt;/code&gt;, for much faster use.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Some useful resources&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://earth-env-data-science.github.io/lectures/environment/python_environments.html&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;A good resource for better understanding difference between &lt;code&gt;mamba&lt;/code&gt; and &lt;code&gt;conda&lt;/code&gt;, and their lightweights alternatives&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://carpentries-incubator.github.io/introduction-to-conda-for-data-scientists/04-sharing-environments/index.html&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Advanced tutorial on using &lt;code&gt;conda&lt;/code&gt; environments for a scientific project&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://medium.com/i-want-to-be-the-very-best/installing-packages-from-github-with-conda-commands-ebf10de396f4&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Tutorial on how to install a package directly from github repository&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;renv&#34;&gt;&lt;code&gt;renv&lt;/code&gt;&lt;/h4&gt;
&lt;p&gt;Here are some basics on how to use &lt;code&gt;renv&lt;/code&gt;, but see the &lt;a href=&#34;https://rstudio.github.io/renv/articles/renv.html&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;renv vignette&lt;/a&gt; and documentation for more advanced usage.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-r&#34; data-lang=&#34;r&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Initialize renv in your project&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;renv&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;init&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;project&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;path/to/environment&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Install a package and snapshot the environment&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nf&#34;&gt;install.packages&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;dplyr&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;renv&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;snapshot&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-r&#34; data-lang=&#34;r&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Load the renv environment for the project&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;renv&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;activate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Restore the project&amp;#39;s dependencies&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;renv&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;restore&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;renv&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;update&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;renv::history()
renv::revert()
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id=&#34;pkg&#34;&gt;&lt;code&gt;Pkg&lt;/code&gt;&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;using&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Pkg&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;# Create a new project environment&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;Pkg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;activate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;path/to/MyProject&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;# Add packages to the project environment&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;Pkg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;DataFrames&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You can also use the Julia REPL by typing &lt;code&gt;]&lt;/code&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;(@v1.10) pkg&amp;gt; add DataFrames
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;or string macros &lt;code&gt;pkg&amp;quot;add DataFrames&amp;quot;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Not that in Julia, the global shared environment is inherited in custom environment. This can be useful!
It is a good idea to install utility packages that you will use for development but that are not mandatory to run your code in the global environment. For instance, the macro &lt;code&gt;@btime&lt;/code&gt; from &lt;code&gt;BenchmarkTools&lt;/code&gt; is very handy to profile code. But you may not want to have &lt;code&gt;BenchmarkTools&lt;/code&gt; in your dependencies. Just install it in base, and then you will be able to call
&lt;code&gt;julia  using BenchmarkTools &lt;/code&gt;
within your custom environment.
Other utility packages to consider having in your global environments are&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Test&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/JuliaTesting/TestEnv.jl&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;&lt;code&gt;TestEnv&lt;/code&gt;&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Revise&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;LocalRegistry&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;environment-files&#34;&gt;Environment files&lt;/h3&gt;
&lt;p&gt;Environment files specify the exact versions of the dependencies in your virtual environment, and are used by package managers to instantiate the environment. They are usually &lt;code&gt;.txt&lt;/code&gt;, &lt;code&gt;.toml&lt;/code&gt; or &lt;code&gt;.yml&lt;/code&gt; files.&lt;/p&gt;
&lt;p&gt;Always version control your environment files!&lt;/p&gt;
&lt;h4 id=&#34;julia&#34;&gt;Julia&lt;/h4&gt;
&lt;p&gt;In Julia, the environment is defined using two files: the &lt;code&gt;Project.toml&lt;/code&gt; and &lt;code&gt;Manifest.toml&lt;/code&gt;. The &lt;code&gt;Project.toml&lt;/code&gt; file lists the direct dependencies, while the &lt;code&gt;Manifest.toml&lt;/code&gt; file captures the full dependency graph, including all transitive dependencies. The &lt;code&gt;Manifest.toml&lt;/code&gt; file may not be tracked in a project, and will be reconstructed if missing. It specifies the exact version of the environment. For reproducibility, you want to include &lt;code&gt;Manifest.toml&lt;/code&gt; in your git repo.
&lt;code&gt;Artifacts.toml&lt;/code&gt; is used to handle non-Julia package dependencies.&lt;/p&gt;
&lt;details&gt;
&lt;summary&gt;Project.toml example&lt;/summary&gt;
&lt;pre&gt;&lt;code&gt;
authors = [&#34;Some One &lt;someone@email.com&gt;&#34;,
           &#34;Foo Bar &lt;foo@bar.com&gt;&#34;]
name = &#34;MyEnv&#34;
uuid = &#34;7876af07-990d-54b4-ab0e-23690620f79a&#34; # mandatory for packages
version = &#34;1.2.5&#34;
&lt;p&gt;[deps]
DataFrames = &amp;ldquo;7876af07-990d-54b4-ab0e-23690620f79a&amp;rdquo;
Plots = &amp;ldquo;8dfed614-e22c-5e08-85e1-65c5234f0b40&amp;rdquo;&lt;/p&gt;
&lt;p&gt;[compat]
CUDA = &amp;ldquo;4.4, 5&amp;rdquo;
julia = &amp;ldquo;1.10&amp;rdquo;
&lt;/pre&gt;&lt;/code&gt;&lt;/p&gt;
&lt;/details&gt;
&lt;p&gt;When you are located within the project root folder containing the &lt;code&gt;.toml&lt;/code&gt; file, start julia with&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ julia --project&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This will load the environment. If it is the first time that you use it, you need to instantiate it with&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-julia-repl&#34; data-lang=&#34;julia-repl&#34;&gt;(Example) pkg&amp;gt; instantiate
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;Some useful resources&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://pkgdocs.julialang.org/v1/toml-files/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;see here for more info on Julia &lt;code&gt;.toml&lt;/code&gt; files here&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;python&#34;&gt;Python&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;conda env&lt;/code&gt; reads &lt;code&gt;.yml&lt;/code&gt;, which can take any names. &lt;code&gt;.yml&lt;/code&gt; files are not created automatically! Create &lt;code&gt;environment.yml&lt;/code&gt; with&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;conda env &lt;span class=&#34;nb&#34;&gt;export&lt;/span&gt; --name machine-learning-env --from-history --file environment.yml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This creates an &lt;code&gt;environment.yml&lt;/code&gt; file&lt;/p&gt;
&lt;details&gt;
&lt;summary&gt;environment.yml example&lt;/summary&gt;
&lt;pre&gt;&lt;code&gt;
name: machine-learning-env
&lt;p&gt;channels:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;pytorch&lt;/li&gt;
&lt;li&gt;conda-forge&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;dependencies:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;pytorch=1.1
&lt;/pre&gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/details&gt;
&lt;p&gt;Not using &lt;code&gt;--from-history&lt;/code&gt; will result in listing &lt;strong&gt;all&lt;/strong&gt; dependencies, those installed explicitly AND implicitly. This may be a bit messier.&lt;/p&gt;
&lt;p&gt;To specify &lt;code&gt;pip&lt;/code&gt; packages, just insert in the &lt;code&gt;.toml&lt;/code&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yml&#34; data-lang=&#34;yml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;pip=19.1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;pip&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;kaggle==1.5&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;yellowbrick==0.9&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Note the double ‘==’ instead of ‘=’ for the pip installation and that you should include pip itself as a dependency and then a subsection denoting those packages to be installed via pip. Also, note that &lt;code&gt;--from-history&lt;/code&gt; won&amp;rsquo;t catch the pip dependencies. So the best way to proceed is to specify the dependencies by hand.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Installing from &lt;code&gt;environment.yml&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;mamba env create --prefix ./.env --file environment.yml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Some additional resources&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://note.nkmk.me/en/python-pip-install-requirements/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Good resource on managing packages with pip&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;r&#34;&gt;R&lt;/h4&gt;
&lt;p&gt;Environments with &lt;code&gt;renv&lt;/code&gt; are specified in a &lt;code&gt;renv.lock&lt;/code&gt; and &lt;code&gt;DESCRIPTION&lt;/code&gt; files. It is a JSON file that has two main components: R and Packages. The R component specifies the R version used and the list of repositories where packages were installed. The Packages component includes a record for each package used in the project, with all necessary details for reinstalling that exact version. These details are derived from the installed package’s &lt;code&gt;DESCRIPTION&lt;/code&gt; file and cover installations from any source, including CRAN, Bioconductor, GitHub, Gitlab, and Bitbucket. For more information on supported sources, refer to vignette(&amp;ldquo;package-sources&amp;rdquo;).&lt;/p&gt;
&lt;details&gt;
&lt;summary&gt;renv.lock&lt;/summary&gt;
&lt;pre&gt;&lt;code&gt;
{
  &#34;R&#34;: {
    &#34;Version&#34;: &#34;4.3.3&#34;,
    &#34;Repositories&#34;: [
      {
        &#34;Name&#34;: &#34;CRAN&#34;,
        &#34;URL&#34;: &#34;https://cloud.r-project.org&#34;
      }
    ]
  },
  &#34;Packages&#34;: {
    &#34;markdown&#34;: {
      &#34;Package&#34;: &#34;markdown&#34;,
      &#34;Version&#34;: &#34;1.0&#34;,
      &#34;Source&#34;: &#34;Repository&#34;,
      &#34;Repository&#34;: &#34;CRAN&#34;,
      &#34;Hash&#34;: &#34;4584a57f565dd7987d59dda3a02cfb41&#34;
    },
    &#34;mime&#34;: {
      &#34;Package&#34;: &#34;mime&#34;,
      &#34;Version&#34;: &#34;0.12.1&#34;,
      &#34;Source&#34;: &#34;GitHub&#34;,
      &#34;RemoteType&#34;: &#34;github&#34;,
      &#34;RemoteHost&#34;: &#34;api.github.com&#34;,
      &#34;RemoteUsername&#34;: &#34;yihui&#34;,
      &#34;RemoteRepo&#34;: &#34;mime&#34;,
      &#34;RemoteRef&#34;: &#34;main&#34;,
      &#34;RemoteSha&#34;: &#34;1763e0dcb72fb58d97bab97bb834fc71f1e012bc&#34;,
      &#34;Requirements&#34;: [
        &#34;tools&#34;
      ],
      &#34;Hash&#34;: &#34;c2772b6269924dad6784aaa1d99dbb86&#34;
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/details&gt;
&lt;h3 id=&#34;working-with-interactive-environments&#34;&gt;Working with interactive environments&lt;/h3&gt;
&lt;p&gt;Jupyter notebooks can use &lt;code&gt;Pkg&lt;/code&gt;, &lt;code&gt;conda&lt;/code&gt; and &lt;code&gt;renv&lt;/code&gt; environments, but you may need some extra steps (see how to make Jupyter aware of your Conda environments &lt;a href=&#34;https://carpentries-incubator.github.io/introduction-to-conda-for-data-scientists/04-sharing-environments/index.html#making-jupyter-aware-of-your-conda-environments&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;here&lt;/a&gt; and &lt;a href=&#34;https://medium.com/@nrk25693/how-to-add-your-conda-environment-to-your-jupyter-notebook-in-just-4-steps-abeab8b8d084&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;there&lt;/a&gt;. You do not need to follow these steps if you are using Visual Studio Code.&lt;/p&gt;
&lt;p&gt;Other interactive notebooks solutions store directly the environemnts in the files, which is great for reproducibility purposes. This is the case of &lt;code&gt;Pluto&lt;/code&gt; notebooks, which are designed to be reproducible. Under the hood they contain the package environment inside them &lt;code&gt;Binder&lt;/code&gt; notebooks also ship with a virtual environment, but using &lt;code&gt;Docker&lt;/code&gt; (see below and &lt;a href=&#34;https://earth-env-data-science.github.io/lectures/environment/binder.html&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;a tutorial here&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;I personally do not like notebooks, and prefer using scripts in Visual Studio Code, executing them line by line for development with whether the &lt;code&gt;Julia&lt;/code&gt; extension or the Jupyter extension with &lt;code&gt;&amp;quot;jupyter.interactiveWindow.textEditor.executeSelection&amp;quot;: true&lt;/code&gt;. With such an approach, you can specify which virtual environment should be used at login, and never worry again with that later.&lt;/p&gt;
&lt;h3 id=&#34;caveats-of-virtual-environments&#34;&gt;Caveats of virtual environments&lt;/h3&gt;
&lt;p&gt;Some packages/libraries rely on system libraries and utilities; for instance &lt;code&gt;pytorch&lt;/code&gt; relies on CUDA drivers, which are specific to a certain machine (&lt;a href=&#34;https://carpentries-incubator.github.io/introduction-to-conda-for-data-scientists/05-managing-cuda-dependencies/index.html&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;see how you can deal with CUDA drivers with &lt;code&gt;conda&lt;/code&gt; here&lt;/a&gt;), or the behavior of the packages my be dependent on system environmental variables. As such, by replicating a virtual environment, you won&amp;rsquo;t necessarily reproduce the same exact computing environment.
To reproduce more closely a computing environment, &lt;strong&gt;containers&lt;/strong&gt; may be used. Containers virtualize layers of the operating system, replicating to a deeper lever your environment and making it more reproducible. &lt;a href=&#34;https://docs.docker.com/get-started/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Docker&lt;/a&gt; or Singularity are popular solutions. Unfortunately, building containers may be difficult, and the virtualization may add a layer of complexity to your pipeline&amp;hellip;
But see &lt;a href=&#34;https://rscdata_science.gitlab.io/rsc_data_science_blog/post/singularity_as_devel_env/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Using singularity as a development environment&lt;/a&gt; and &lt;a href=&#34;https://github.com/microsoft/vscode-remote-release/issues/3066#issuecomment-1019500216&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;How to remote dev with vscode and singularity&lt;/a&gt;. Note that you could use both a container and a virtual environment&amp;hellip; See &lt;a href=&#34;https://rstudio.github.io/renv/articles/docker.html&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;here a tutorial with &lt;code&gt;renv&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Some additional resources&lt;/strong&gt;
For more information, check &lt;a href=&#34;https://carpentries-incubator.github.io/docker-introduction/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Reproducible Computational Environments Using Containers: Introduction to Docker&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;advanced-topic-package-development&#34;&gt;Advanced topic: package development&lt;/h2&gt;
&lt;p&gt;It can make sense for research projects to distinguish between scripts placed in &lt;code&gt;scripts/&lt;/code&gt; and reused functions, models, etc., placed in &lt;code&gt;src&lt;/code&gt;. We&amp;rsquo;ll cover that more broadly in another post. In such case, it is best to compartmentalize dependencies so as to have a minimal working environment for the &lt;code&gt;src/&lt;/code&gt; functions and classes, independent of that for your &lt;code&gt;scripts&lt;/code&gt;. One practical approach for this is to specify the &lt;code&gt;src&lt;/code&gt; folder as a package. This has a few advantages, including&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;not having to deal with relative position of files to call the functions in &lt;code&gt;src/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;maximizing your productivity by creating a generic package additionally to your main research project.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can achieve this easily with development tools.&lt;/p&gt;
&lt;p&gt;For Python, tools like &lt;code&gt;setuptools&lt;/code&gt; and &lt;code&gt;poetry&lt;/code&gt; facilitate package development. If you&amp;rsquo;re working in R, &lt;code&gt;devtools&lt;/code&gt; is the go-to tool for developing packages. In Julia, the &lt;code&gt;Pkg&lt;/code&gt; tool serves a similar purpose.&lt;/p&gt;
&lt;p&gt;Package templates can be useful to simplify the creation of packages by generating package skeletons. In Python, checkout out &lt;code&gt;cookiecutter&lt;/code&gt;. In R, check &lt;code&gt;usethis&lt;/code&gt;. For Julia, use the &lt;code&gt;Pkg.generate()&lt;/code&gt; built-in functionality, or the more advanced &lt;code&gt;PkgTemplates.jl&lt;/code&gt; package.&lt;/p&gt;
&lt;p&gt;Note that you may want at some point to locate your &lt;code&gt;src/&lt;/code&gt; (and associated &lt;code&gt;tests&lt;/code&gt;, &lt;code&gt;docs&lt;/code&gt;, etc&amp;hellip;) in a separate git repo.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Some additional resources&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://goodresearch.dev/setup#install-a-project-package&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;goodresearch tutorial&lt;/a&gt; on how to install a project package&lt;/li&gt;
&lt;li&gt;the &lt;a href=&#34;https://py-pkgs.org/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Python Packages book&lt;/a&gt; offers comprehensive guidance using &lt;code&gt;poetry&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;the &lt;a href=&#34;https://r-pkgs.org/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;R Packages book&lt;/a&gt; covers all aspects of package development.&lt;/li&gt;
&lt;li&gt;the &lt;a href=&#34;https://pkgdocs.julialang.org/v1/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Pkg documentation&lt;/a&gt; and this &lt;a href=&#34;https://julialang.org/contribute/developing_package/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;how-to guide&lt;/a&gt; for detailed instructions.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;take-home-messages&#34;&gt;Take-home messages&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Make sure you understand what are package managers, virtual environments, and dependencies both within your project scripts and at the system level.&lt;/li&gt;
&lt;li&gt;Clearly document all dependencies and environment setup instructions in project repositories.&lt;/li&gt;
&lt;li&gt;Provide instructions in an &lt;strong&gt;Installation&lt;/strong&gt; section in the &lt;code&gt;readme.md&lt;/code&gt; on how to set up the virtual environment.&lt;/li&gt;
&lt;li&gt;Check out these toy research repositories &lt;a href=&#34;https://github.com/mauro3/toy-research-project-breithorn&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;in Julia&lt;/a&gt; (which uses relative paths for importing the &lt;code&gt;src&lt;/code&gt; functions), &lt;a href=&#34;https://github.com/vboussange/rere&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Python&lt;/a&gt; (which has &lt;code&gt;src&lt;/code&gt; as package), and &lt;a href=&#34;https://github.com/vboussange/breithornToyProjectCORDS&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;R&lt;/a&gt; (which has &lt;code&gt;src&lt;/code&gt; as package) that implement what I believe good examples of research projects!&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>A multi-language overview on how to organise your research project code and documents</title>
      <link>https://vboussange.github.io/post/best-practices-for-your-research-code/</link>
      <pubDate>Tue, 11 Jun 2024 00:00:00 +0000</pubDate>
      <guid>https://vboussange.github.io/post/best-practices-for-your-research-code/</guid>
      <description>&lt;p&gt;I personally find that one of the biggest challenge when doing research is to keep things neat and organized. Having a good management system for your code and resources is key to optimizing time and brain resources. In this post, I discuss various methods for structuring a research project folder that includes code, data, publications, and more. Additionally, I discuss the specifics of organizing your research code. As I started my PhD, I wish I could have had some of such guidelines. But starting from scratch allowed me to build, with trials and errors, a good system for my later life. Hopefully, some of this can apply to you!&lt;/p&gt;
&lt;p&gt;This post is part of a series of posts on best practices for managing research code. Much of this material was developed in collaboration with &lt;a href=&#34;https://github.com/mauro3&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Mauro Werder&lt;/a&gt; as part of the &lt;a href=&#34;https://github.com/mauro3/CORDS/tree/master&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Course On Reproducible Research, Data Pipelines, and Scientific Computing (CORDS)&lt;/a&gt;. If you have experiences to share or spot any errors, please reach out!&lt;/p&gt;
&lt;h2 id=&#34;content&#34;&gt;Content&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;#content&#34;&gt;Content&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#project-folder-structures&#34;&gt;Project folder structures&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#code-structure&#34;&gt;&lt;code&gt;code/&lt;/code&gt; structure&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#turning-your-code-into-a-package&#34;&gt;Turning your &lt;code&gt;code/&lt;/code&gt; into a &amp;ldquo;package&amp;rdquo;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#wrapping-up&#34;&gt;Wrapping up&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;#take-home-messages&#34;&gt;Take-home messages&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;project-folder-structures&#34;&gt;Project folder structures&lt;/h2&gt;
&lt;p&gt;I quite like this project folder structure, which keeps apart raw data and results from the code, but still place them relatively close, together with admin and publications. Having a separate git repo for the paper is something I would recommend as well (possibly linked to an Overleaf project).&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;|-- code/
|-- data/
|-- results
|-- publications
|    |-- talks
|    |-- posters
|    |-- papers
|-- admin
|-- meetings
|-- more-folders
 -- README.md
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You may want to place &lt;code&gt;results&lt;/code&gt; within &lt;code&gt;code&lt;/code&gt;, together with &lt;code&gt;data&lt;/code&gt; (which you should not git track)
The structure of &lt;code&gt;code/&lt;/code&gt; deserves here some attention.&lt;/p&gt;
&lt;h2 id=&#34;code-structure&#34;&gt;&lt;code&gt;code/&lt;/code&gt; structure&lt;/h2&gt;
&lt;p&gt;Programming languages typically have their own conventions, but often the folders follow this scheme&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;a &lt;code&gt;README.md&lt;/code&gt; file at the top level&lt;/li&gt;
&lt;li&gt;a &lt;code&gt;src/&lt;/code&gt; folder, containing models and other generic function and classes, that will be used in &lt;code&gt;script/&lt;/code&gt; files,&lt;/li&gt;
&lt;li&gt;example usages, e.g. &lt;code&gt;examples/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;scripts to run models, evaluation, etc., e.g. &lt;code&gt;scripts/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;documentation (often generated), e.g. &lt;code&gt;docs/&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It can make sense for research projects to distinguish between scripts placed in &lt;code&gt;scripts/&lt;/code&gt; and reused functions, models, etc., placed in &lt;code&gt;src&lt;/code&gt;.&lt;/p&gt;
&lt;details&gt;
&lt;summary&gt;Python Folder structure&lt;/summary&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;|-- src/            # package code
|-- scripts/        # Custom analysis or processing scripts
|-- tests/
|-- examples/       # Example scripts using the package
|-- docs/           # documentation
 -- environment.yml # to handle project dependencies
 -- README.md
&lt;/code&gt;&lt;/pre&gt;&lt;/details&gt;
&lt;details&gt;
&lt;summary&gt;R Folder structure&lt;/summary&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;|-- R/               # R scripts and functions (package code)
|-- scripts/         # Custom analysis or processing scripts
|-- man/             # Documentation files
|-- tests/
|-- examples/        # Example scripts using the package
|-- vignettes/       # Long-form documentation
 -- DESCRIPTION      # Package description and metadata
 -- NAMESPACE        # Namespace file for package
 -- README.md        # Project overview and details
&lt;/code&gt;&lt;/pre&gt;&lt;/details&gt;
&lt;details&gt;
&lt;summary&gt;Julia Folder structure&lt;/summary&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;|-- src/            # package code
|-- scripts/        # Custom analysis or processing scripts
|-- test/
|-- examples/       # Example scripts using the package
|-- docs/           # documentation
 -- Project.toml    # to handle project dependencies
 -- README.md
&lt;/code&gt;&lt;/pre&gt;&lt;/details&gt;
&lt;h2 id=&#34;turning-your-code-into-a-package&#34;&gt;Turning your &lt;code&gt;code/&lt;/code&gt; into a &amp;ldquo;package&amp;rdquo;&lt;/h2&gt;
&lt;p&gt;You may want to specify the &lt;code&gt;src&lt;/code&gt; folder as a package. This has a few advantages, including&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;not having to deal with relative position of files to call the functions in &lt;code&gt;src/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;maximizing your productivity by creating a generic package additionally to your main research project.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To import functions and classes (types) located in the &lt;code&gt;src&lt;/code&gt; folder, you typically need to indicate in each script the relative path of &lt;code&gt;src&lt;/code&gt;. In Julia, you would typically do something like &lt;code&gt;include(&amp;quot;../src/path/to/your/src_file.jl&amp;quot;)&lt;/code&gt;. In Python, you would do something like:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;sys&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;sys&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;append&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;../src/&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;src.path.to.your.src_file&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;my_fun&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If &lt;code&gt;src/&lt;/code&gt; directory grows, it’s beneficial to convert it into a separate package. Although this process is a bit more complex, it eliminates the need for path specifications, simplifies the import of functions and classes, and makes the codebase easily accessible for other research projects.&lt;/p&gt;
&lt;p&gt;There are typically ways to turn a code-project into an installable package.  This is in particular useful for code which other people (or yourself) use for different projects.&lt;/p&gt;
&lt;p&gt;You can achieve this easily with development tools.&lt;/p&gt;
&lt;p&gt;For Python, tools like &lt;code&gt;setuptools&lt;/code&gt; and &lt;code&gt;poetry&lt;/code&gt; facilitate package development. If you&amp;rsquo;re working in R, &lt;code&gt;devtools&lt;/code&gt; is the go-to tool for developing packages. In Julia, the &lt;code&gt;Pkg&lt;/code&gt; tool serves a similar purpose.&lt;/p&gt;
&lt;p&gt;Package templates can be useful to simplify the creation of packages by generating package skeletons. In Python, checkout out &lt;code&gt;cookiecutter&lt;/code&gt;. In R, check &lt;code&gt;usethis&lt;/code&gt;. For Julia, use the &lt;code&gt;Pkg.generate()&lt;/code&gt; built-in functionality, or the more advanced &lt;code&gt;PkgTemplates.jl&lt;/code&gt; package.&lt;/p&gt;
&lt;p&gt;Note that you may want at some point to locate your &lt;code&gt;src/&lt;/code&gt; (and associated &lt;code&gt;tests&lt;/code&gt;, &lt;code&gt;docs&lt;/code&gt;, etc&amp;hellip;) in a separate git repo.&lt;/p&gt;
&lt;p&gt;Further reading for&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://goodresearch.dev/setup#create-a-pip-installable-package-recommended&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Python&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://statisticsglobe.com/create-package-r&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;R&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://pkgdocs.julialang.org/v1/creating-packages/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Julia Pkg.jl documentation and how to create packages&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://modernjuliaworkflows.github.io&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Modern Julia Workflows website&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;wrapping-up&#34;&gt;Wrapping up&lt;/h2&gt;
&lt;p&gt;Explore these exemplary toy research repositories in different programming languages:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/mauro3/toy-research-project-breithorn&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Julia&lt;/a&gt;, using relative paths for importing &lt;code&gt;src&lt;/code&gt; functions.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/vboussange/rere&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Python&lt;/a&gt;, implementing &lt;code&gt;src&lt;/code&gt; as a package.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/vboussange/breithornToyProjectCORDS&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;R&lt;/a&gt;, also implementing &lt;code&gt;src&lt;/code&gt; as a package.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These repositories showcase what I consider to be best practices in research project organization.&lt;/p&gt;
&lt;h3 id=&#34;take-home-messages&#34;&gt;Take-home messages&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;There is not one way to structure your research project folders, but general guidelines. Create the one that makes most sense for you!&lt;/li&gt;
&lt;li&gt;A chosen structure should be suitable to both work during the development of your project, and to submit (parts) of it to a repository in a future stage.&lt;/li&gt;
&lt;li&gt;Consider turning your &lt;code&gt;src/&lt;/code&gt; into a folder. This can increase your academic productivity, as you could eventually be the developer of a cool package that people re-use, with minimum efforts!&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>A multi-language overview on how to test your research project code</title>
      <link>https://vboussange.github.io/post/testing-your-research-code/</link>
      <pubDate>Tue, 11 Jun 2024 00:00:00 +0000</pubDate>
      <guid>https://vboussange.github.io/post/testing-your-research-code/</guid>
      <description>&lt;p&gt;Code testing is essential to identify and fix potential issues, to maintain sanity over the course of the development of the project and quickly identify bugs, and to ensure the reliability and sanity of your experiment overtime.&lt;/p&gt;
&lt;p&gt;This post is part of a series of posts on best practices for managing research project code. Much of this material was developed in collaboration with &lt;a href=&#34;https://github.com/mauro3&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Mauro Werder&lt;/a&gt; as part of the &lt;a href=&#34;https://github.com/mauro3/CORDS/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Course On Reproducible Research, Data Pipelines, and Scientific Computing (CORDS)&lt;/a&gt;. If you have experiences to share or spot any errors, please reach out!&lt;/p&gt;
&lt;h2 id=&#34;content&#34;&gt;Content&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;#content&#34;&gt;Content&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#unit-testing&#34;&gt;Unit testing&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;#lightweight-formal-tests-with-assert&#34;&gt;Lightweight formal tests with &lt;code&gt;assert&lt;/code&gt;&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;#python&#34;&gt;Python&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#julia&#34;&gt;Julia&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#testing-with-a-test-suite&#34;&gt;Testing with a test suite&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;#python-1&#34;&gt;Python&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#julia-1&#34;&gt;Julia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#r&#34;&gt;R&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#testing-non-pure-functions-and-classes&#34;&gt;Testing non-pure functions and classes&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;#python-2&#34;&gt;Python&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#continuous-integration&#34;&gt;Continuous integration&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;#cool-tip&#34;&gt;Cool tip&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#other-types-of-tests&#34;&gt;Other types of tests&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#resources&#34;&gt;Resources&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#take-home-messages&#34;&gt;Take-home messages&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;unit-testing&#34;&gt;Unit testing&lt;/h2&gt;
&lt;p&gt;Unit testing involves testing a unit of code, typically a single function, to ensure its correctness. Here are some key aspects to consider:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Test for correctness with typical inputs.&lt;/li&gt;
&lt;li&gt;Test edge cases.&lt;/li&gt;
&lt;li&gt;Test for errors with bad inputs.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Some developers start writing unit tests before writing the actual function, a practice known as &lt;a href=&#34;https://en.wikipedia.org/wiki/Test-driven_development&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Test-Driven Development (TDD)&lt;/a&gt;. Define upstream on a piece of paper the behavior of the function, write corresponding tests, and when all tests pass, you are done. This philosophy  ensures that you have a well-tested implementation, and avoids unnecessary feature development, forcing you to focus only on what is needed. While TDD is a powerful idea, it can be challenging to follow strictly.&lt;/p&gt;
&lt;p&gt;A good idea is to write an additional test when you find a bug in your code.&lt;/p&gt;
&lt;h3 id=&#34;lightweight-formal-tests-with-assert&#34;&gt;Lightweight formal tests with &lt;code&gt;assert&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;The simplest form of unit testing involves some sort of &lt;code&gt;assert&lt;/code&gt; statement.&lt;/p&gt;
&lt;h4 id=&#34;python&#34;&gt;Python&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;fib&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;fib&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;fib&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;assert&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;fib&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;assert&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;fib&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;assert&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;fib&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;julia&#34;&gt;Julia&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nd&#34;&gt;@assert&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;When one test is broken, you&amp;rsquo;ll get an error for the corresponding test, which you&amp;rsquo;ll need to fix to check the following tests.&lt;/p&gt;
&lt;p&gt;In Julia or Python, you could directly place the &lt;code&gt;assert&lt;/code&gt; statement after your functions. This way, tests are run each time you execute the script. Here is nother pythonic approach, which can be used to decouple the test&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;fib&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;fib&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;fib&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;vm&#34;&gt;__name__&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;__main__&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;assert&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;fib&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;assert&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;fib&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;assert&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;fib&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;assert&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;fib&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;6&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;8&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;assert&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;fib&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;40&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;102334155&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Tests passed&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Consider using &lt;code&gt;np.isclose&lt;/code&gt;, &lt;code&gt;np.testing.assert_allclose&lt;/code&gt; (Python) or &lt;code&gt;approx&lt;/code&gt; (Julia) for floating point comparisons.&lt;/p&gt;
&lt;h3 id=&#34;testing-with-a-test-suite&#34;&gt;Testing with a test suite&lt;/h3&gt;
&lt;p&gt;Once you have many tests, it makes sense to group them into a test suite and run them with a test runner. This approach will run all tests, even though some are broken, and retrieve and informative statements on those tests that passed, and those that did not. As you&amp;rsquo;ll see, it also allows to automatically run the test at each commit, with continuous integration.&lt;/p&gt;
&lt;h4 id=&#34;python-1&#34;&gt;Python&lt;/h4&gt;
&lt;p&gt;Two main frameworks for unit tests in Python are &lt;code&gt;pytest&lt;/code&gt; and &lt;code&gt;unittest&lt;/code&gt;, with &lt;code&gt;pytest&lt;/code&gt; being more popular.&lt;/p&gt;
&lt;p&gt;Example using &lt;code&gt;pytest&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;src.fib&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;fib&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;pytest&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;test_typical&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;assert&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;fib&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;assert&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;fib&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;assert&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;fib&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;6&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;8&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;assert&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;fib&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;40&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;102334155&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;test_edge_case&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;assert&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;fib&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;test_raises&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pytest&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;raises&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;ne&#34;&gt;NotImplementedError&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;fib&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pytest&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;raises&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;ne&#34;&gt;NotImplementedError&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;fib&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;1.5&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Run the tests with:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;pytest test_fib.py
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;julia-1&#34;&gt;Julia&lt;/h4&gt;
&lt;p&gt;Built in module &lt;code&gt;Test&lt;/code&gt;, relying on the macro &lt;code&gt;@test&lt;/code&gt;. Consider grouping your tests with&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;julia&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;nd&#34;&gt;@testset&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;trigonometric identities&amp;#34;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;begin&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;          &lt;span class=&#34;n&#34;&gt;θ&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;π&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;          &lt;span class=&#34;nd&#34;&gt;@test&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;sin&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;θ&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;≈&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sin&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;θ&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;          &lt;span class=&#34;nd&#34;&gt;@test&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cos&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;θ&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;≈&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cos&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;θ&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;          &lt;span class=&#34;nd&#34;&gt;@test&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;sin&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;θ&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;≈&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sin&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;θ&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cos&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;θ&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;          &lt;span class=&#34;nd&#34;&gt;@test&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cos&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;θ&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;≈&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cos&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;θ&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;^&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;sin&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;θ&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;^&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This will nicely output&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Test Summary:            | Pass  Total  Time
trigonometric identities |    4      4  0.2s
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;which comes handy for grouping tests applied to a single function or concept. Test functions may require additional packages to your minimum working environment specified at your package root folder. An additional virtual environment may be specified for tests! To develop my tests interactively, I like using &lt;a href=&#34;https://github.com/JuliaTesting/TestEnv.jl&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;&lt;code&gt;TestEnv&lt;/code&gt;&lt;/a&gt;. Unfortunately, using &lt;code&gt;Pkg.activate&lt;/code&gt; in &lt;code&gt;tests&lt;/code&gt; would not work there, you. You need &lt;code&gt;TestEnv&lt;/code&gt; to have access to your package functions;&lt;/p&gt;
&lt;p&gt;In your package environment,&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;using TestEnv
TestEnv.activate()
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;will activate the test environment.&lt;/p&gt;
&lt;p&gt;To reactivate the normal environment,&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Pkg.activate(&amp;#34;.&amp;#34;)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;a href=&#34;https://discourse.julialang.org/t/how-to-use-vscode-and-repl-to-write-and-test-a-package/78818/44&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Here is a nice thread to read more on that&lt;/a&gt;.&lt;/p&gt;
&lt;h4 id=&#34;r&#34;&gt;R&lt;/h4&gt;
&lt;p&gt;&lt;a href=&#34;https://testthat.r-lib.org&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;&lt;code&gt;testhat&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;testing-non-pure-functions-and-classes&#34;&gt;Testing non-pure functions and classes&lt;/h3&gt;
&lt;p&gt;For nondeterministic functions, provide the random seed or variables needed by the function as arguments to make them deterministic.
For stateful functions, test postconditions to ensure the internal state changes as expected.
For functions with I/O side effects, create mock files to verify proper input reading and expected output.&lt;/p&gt;
&lt;h4 id=&#34;python-2&#34;&gt;Python&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;file_to_upper&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;in_file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;out_file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;fout&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;out_file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;w&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;in_file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;r&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;line&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;fout&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;write&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;line&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;upper&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;fout&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;close&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;tempfile&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;os&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;test_file_to_upper&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;in_file&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;tempfile&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NamedTemporaryFile&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;delete&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;False&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;mode&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;w&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;out_file&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;tempfile&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NamedTemporaryFile&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;delete&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;False&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;out_file&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;close&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;in_file&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;write&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;test123&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;thetest&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;in_file&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;close&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;file_to_upper&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;in_file&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;out_file&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;out_file&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;r&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;read&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;assert&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;TEST123&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;THETEST&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;os&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;unlink&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;in_file&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;os&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;unlink&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;out_file&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;continuous-integration&#34;&gt;Continuous integration&lt;/h2&gt;
&lt;p&gt;Automated testing on local machines is useful, but you can do better with continuous integration (CI). In fact, CI is essential for projects involving multiple developers and various target platforms. CI consists in running tests whenever changes are committed.
CI can also be used to automatically build documentation, check for code coverage, and more. GitHub Actions is a popular CI tool available within GitHub.
CI is based on &lt;code&gt;.yaml&lt;/code&gt; files, which specify the environment to run the script. You can build matrices to test across different environments (e.g. Linux, Windows and MacOS, with different versino of python or Julia). Jobs will be created that run our tests for each permutation of these.&lt;/p&gt;
&lt;details&gt;
&lt;summary&gt;An example CI.yaml file for Julia&lt;/summary&gt;
&lt;pre&gt;&lt;code&gt;
name: Run tests
&lt;p&gt;on:
push:
branches:
- master
- main
pull_request:&lt;/p&gt;
&lt;p&gt;permissions:
actions: write
contents: read&lt;/p&gt;
&lt;p&gt;jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
matrix:
julia-version: [&amp;lsquo;1.6&amp;rsquo;, &amp;lsquo;1&amp;rsquo;, &amp;rsquo;nightly&amp;rsquo;]
julia-arch: [x64, x86]
os: [ubuntu-latest, windows-latest, macOS-latest]
exclude:
- os: macOS-latest
julia-arch: x86&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;steps:
  - uses: actions/checkout@v4
  - uses: julia-actions/setup-julia@v1
    with:
      version: ${{ matrix.julia-version }}
      arch: ${{ matrix.julia-arch }}
  - uses: julia-actions/cache@v1
  - uses: julia-actions/julia-buildpkg@v1
  - uses: julia-actions/julia-runtest@v1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;/pre&gt;&lt;/code&gt;&lt;/p&gt;
&lt;/details&gt;
&lt;details&gt;
&lt;summary&gt;An example CI.yaml file for Python&lt;/summary&gt;
&lt;p&gt;This action installs the conda environment called &lt;code&gt;glacier-mass-balance&lt;/code&gt;, specified in the &lt;code&gt;environment.yml&lt;/code&gt; file.
It then runs &lt;code&gt;pytest&lt;/code&gt;, supposing that you have a &lt;code&gt;test/&lt;/code&gt; folder where your functions are located. First try whether &lt;code&gt;pytest&lt;/code&gt; works locally. Do not forget to have &lt;code&gt;pytest&lt;/code&gt; in your dependencies.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
name: Run tests
on: push

jobs:
  miniconda:
    name: Miniconda ${{ matrix.os }}
    runs-on: ${{ matrix.os }}
    strategy:
        matrix:
            os: [&#34;ubuntu-latest&#34;]
    steps:
      - uses: actions/checkout@v2
      - uses: conda-incubator/setup-miniconda@v2
        with:
          environment-file: environment.yml
          activate-environment: glacier-mass-balance
          auto-activate-base: false
      - name: Run pytest
        shell: bash -l {0}
        run: | 
          pytest
&lt;/pre&gt;&lt;/code&gt;
&lt;/details&gt;
&lt;h4 id=&#34;cool-tip&#34;&gt;Cool tip&lt;/h4&gt;
&lt;p&gt;You can include a cool badge to show visually whether your tests are passing or failing, like so&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/vboussange/rere/actions/workflows/runtest.yml&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;















&lt;figure  &gt;
  &lt;div class=&#34;d-flex justify-content-center&#34;&gt;
    &lt;div class=&#34;w-100&#34; &gt;&lt;img src=&#34;https://github.com/vboussange/rere/actions/workflows/runtest.yml/badge.svg&#34; alt=&#34;Tests&#34; loading=&#34;lazy&#34; data-zoomable /&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;/figure&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You can get the code for this badge by going on your github repo, then Actions. Click on the test action, then on top right click on the &lt;code&gt;...&lt;/code&gt; and `Create status badge```.&lt;/p&gt;
&lt;p&gt;Cool right?&lt;/p&gt;
&lt;h2 id=&#34;other-types-of-tests&#34;&gt;Other types of tests&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Docstring tests&lt;/strong&gt;: Unit tests embedded in docstrings.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Integration tests&lt;/strong&gt;: Test whether multiple functions work correctly together.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Regression tests&lt;/strong&gt;: Ensure your code produces the same outputs as previous versions.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;resources&#34;&gt;Resources&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Official GitHub documentation on building and testing Python projects&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.allenai.org/ci-with-github-actions-for-research-code-a8460c21c6ba&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;CI with GitHub Action and Docker for Python&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.julialang.org/en/v1/stdlib/Test/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Julia documentation on unit testing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://goodresearch.dev/testing.html&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Good Research Practices: Testing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://carpentries-incubator.github.io/python-testing/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;The Carpentries: Python Testing&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;take-home-messages&#34;&gt;Take-home messages&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Systematically implementing testing allows you to ensure the sanity of your code&lt;/li&gt;
&lt;li&gt;The overhead cost of testing is usually well balanced by the reduced time spent downstream in identifying bugs&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Open source navigation system for sailing</title>
      <link>https://vboussange.github.io/post/navigationsystem/</link>
      <pubDate>Fri, 26 May 2023 00:00:00 +0000</pubDate>
      <guid>https://vboussange.github.io/post/navigationsystem/</guid>
      <description>&lt;p&gt;&lt;em&gt;Back in the days, people used to orient themselves with paper maps and the stars or with a sextant. Unfortunately, we have lost this knowledge. It would now be difficult, at least for me, to live without a digital map and a GPS. In this blog post, I detail how to set up a handy navigation system for sailing, using a Raspberry Pi and OpenPlotter to transmit GPS and AIS signals over Wifi to the Navionics Boating app.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&#34;choosing-the-right-chart-maps&#34;&gt;Choosing the Right Chart Maps&lt;/h2&gt;
&lt;p&gt;There are plenty of digital chart map options available for navigation, and we had to figure out which one would fit our need on the boat. After careful consideration, we narrowed down our choices to two alternatives: &lt;a href=&#34;https://www.o-charts.org&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;o-charts charts&lt;/a&gt;, to be used in combination with OpenCPN, an open source navigation software, or &lt;a href=&#34;https://www.navionics.com&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Navionics&lt;/a&gt; charts, to be used with the &amp;ldquo;Navionics Boating&amp;rdquo; application. Both had a similar pricing for what we wanted (charts for Germany, Denmark, Sweden, Norway, Shetland Islands, UK, Ireland and France): around 120-150EUR, with a slight advantage for Navionics. Pros for o-charts is that you can use them more than one year, although the update option is only valid for a year (I think, although I am not 100% sure). Navionics charts is only valid for a year, the period of the subscription. Pros for Navionics is that you can use your subscription on many devices (at least 5, I think), while you cannot use o-charts on iOS devices and on more than 2 devices. Because we wanted to have charts on our smartphones, we decided to go for Navionics.&lt;/p&gt;
&lt;h2 id=&#34;the-importance-of-accurate-gps-and-ais&#34;&gt;The Importance of Accurate GPS and AIS&lt;/h2&gt;
&lt;p&gt;While our smartphones&amp;rsquo; GPS serves us well in our daily lives, accurate positioning becomes critical when sailing. It ensures that we navigate safely, avoiding shallow waters and potential collisions. Additionally, during nighttime navigation, an instrument called AIS (Automatic Identification System) proves invaluable by providing information about nearby large ships.&lt;/p&gt;
&lt;p&gt;In the following, I explain how I installed a server on our boat that transmits GPS and AIS to the &amp;ldquo;Navionics Boating&amp;rdquo; application our smartphone and tablets through Wifi. For this, I used a Raspberry Pi 4, OpenPlotter, and a GPS beacon and a radio antenna fixed on the outside of the boat and connected to the Raspberry.&lt;/p&gt;
&lt;h2 id=&#34;installing-openplotter-on-the-raspberry-pi&#34;&gt;Installing OpenPlotter on the Raspberry Pi&lt;/h2&gt;
&lt;p&gt;To get started, you need to install &lt;a href=&#34;https://openmarine.net/openplotter&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;OpenPlotter&lt;/a&gt;, a Linux distribution designed for Raspberry Pi and that contains the essential software for navigation. I used the 64-bit &lt;a href=&#34;https://openplotter.readthedocs.io/en/latest/getting_started/downloading.html#openplotter-starting&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;OpenPlotter Starting image&lt;/a&gt; that contains an appropriate pre-built kernel. To install it, you&amp;rsquo;ll need a less than 32GB SD-card, to be formatted in FAT32. My problem was that the SD card I had had already been used on a Raspberry Pi, and as such contained an EXT4 partition. EXT4 partitions are used by Linux systems, but are not recognized by MacOS. This prevented me to format the card in FAT32. To allow formatting, I used the &lt;code&gt;diskutil&lt;/code&gt; utility from MacOS.&lt;/p&gt;
&lt;p&gt;First run&lt;/p&gt;
&lt;p&gt;&lt;code&gt;diskutil list&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;in the Terminal. This allows you to identify your SD card, in my case &lt;code&gt;/dev/disk4&lt;/code&gt;.  I had previously installed &lt;a href=&#34;https://medium.com/@iamalleksy/how-to-mount-raspberry-pi-sd-card-using-mac-3046abc2059a&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;&lt;code&gt;ext4fuse&lt;/code&gt;&lt;/a&gt;, not sure if this is a required step. To format the SD card, execute the command&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;sudo diskutil eraseDisk FAT32 RASPBERRY MBRFormat /dev/disk4
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can change &lt;code&gt;RASPBERRY&lt;/code&gt; with any name you like best. More details of this command in &lt;a href=&#34;https://superuser.com/questions/527657/how-do-you-format-a-2-gb-sd-card-to-fat32-preferably-with-disk-utility&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;this thread&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Now the SD card is ready to be used. Download the &lt;a href=&#34;https://www.raspberrypi.com/software/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Raspberry Pi Imager&lt;/a&gt; to install the image on the SD card. You first need to unzip the image, then execute Raspberry Pi Imager, click &amp;ldquo;Choose OS&amp;rdquo; and click on &amp;ldquo;Use custom&amp;rdquo;. Locate the &lt;code&gt;.img&lt;/code&gt; file, then choose the SD card in &amp;ldquo;Choose storage&amp;rdquo; and hit &amp;ldquo;Write&amp;rdquo;. The SD card is ready. Insert it in the Raspberry Pi and swith the power on. The system is going boot on the SD card and set up OpenPlotter. This took a relatively short amount of time.&lt;/p&gt;
&lt;h2 id=&#34;setting-up-openplotter&#34;&gt;Setting up OpenPlotter&lt;/h2&gt;
&lt;p&gt;I had an external monitor that I could use for the Raspberry Pi. I encountered a minor hurdle as OpenPlotter failed to identify it correctly, and did not properly display. I had to adjust the resolution of the screen by hitting the raspberry, then &amp;ldquo;Preferences&amp;rdquo; and &amp;ldquo;Screen configuration&amp;rdquo;. Check also the configuration of the monitor, that may be set to zoom in the visual signal.&lt;/p&gt;
&lt;h2 id=&#34;setting-up-the-gps&#34;&gt;Setting up the GPS&lt;/h2&gt;
&lt;p&gt;Configuring the GPS was a straightforward process that involved following &lt;a href=&#34;https://youtu.be/r8CGixMl18k?t=358&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;this tutorial&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;setting-up-the-ais&#34;&gt;Setting up the AIS&lt;/h2&gt;
&lt;p&gt;Similar to configuring the GPS, we followed &lt;a href=&#34;https://www.youtube.com/watch?v=qEeyl-WSDHk&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;this video tutorial&lt;/a&gt; (in French, with translation available) to set up the AIS system. At first, I did not correctly calibrate the PPM offset, and although I did follow the rest of the procedure correctly, I had an &amp;ldquo;inactive&amp;rdquo; AIS process. I then redid the whole procedure, properly waiting for more than an hour to get the PPM initial guess correct, and with this value, I did manage to make it work.&lt;/p&gt;
&lt;h2 id=&#34;getting-the-signal-on-navionics-through-openplotter-access-point&#34;&gt;Getting the signal on Navionics through OpenPlotter Access Point&lt;/h2&gt;
&lt;p&gt;To transmit the GPS and AIS data to the Navionics application, we established an access point using the Raspberry Pi. This allowed us to create a Wi-Fi network, enabling our devices to receive the signals. We followed this &lt;a href=&#34;https://www.youtube.com/watch?v=tlU4HKT6XxM&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;this video&lt;/a&gt; to set up the access point, which provided clear instructions for this setup.&lt;/p&gt;
&lt;p&gt;I did struggle to switch off the access point to connect back the Raspberry Pi to a Wifi network with Internet in order to do some updates and download a few stuff. It turns out it is quite easy. Go to the Network app, and on the Network mode tab, select back for &amp;ldquo;AP&amp;rdquo; &amp;ldquo;non&amp;rdquo; instead of &amp;ldquo;xx:xx:..:xx on board&amp;rdquo;. Then hit the pen and sd card button, and reboot. Now you can connect back to a wifi network.&lt;/p&gt;
&lt;h2 id=&#34;setting-up-a-ssh-connection-to-transfer-big-files&#34;&gt;Setting up a SSH connection to transfer big files&lt;/h2&gt;
&lt;p&gt;I could not properly download the charts I needed on the Raspberry Pi because the wifi on the boat was too weak. So I decided to download it on my smartphone that I could bring closer to the hotspot, and then transfer the files to the Raspberry Pi. In order to facilitate the process, I installed a SSH connection between my laptop and the Pi, then transferred through Airdrop the charts from my phone to my laptop, and then from the laptop to the Pi with SSH and the &lt;code&gt;scp&lt;/code&gt; command. To enable the SSH access, click on the Raspberry, then &amp;ldquo;Raspberry Pi Configuration&amp;rdquo;, the go to the &amp;ldquo;Interfaces&amp;rdquo; tab and enable SSH. From your laptop, connect to the Raspberry AP, go to the terminal and run&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;ssh pi@openplotter.local
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The password by default is &lt;code&gt;raspberry&lt;/code&gt; (this is indicated &lt;a href=&#34;https://openplotter.readthedocs.io/en/latest/getting_started/installing.html?highlight=ssh#headless&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;here&lt;/a&gt;). Then you can use the following command to transfer any folder to the Pi&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;scp -r path/to/folder/on/laptop pi@openplotter.local:/home/pi/path/you/want/to/drop/the/folder
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;useful-links&#34;&gt;Useful links&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.o-charts.org&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;o-charts charts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.navionics.com&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Navionics charts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://openmarine.net/openplotter&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;OpenPlotter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://openplotter.readthedocs.io/en/latest/getting_started/downloading.html#openplotter-starting&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;OpenPlotter Starting image&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://medium.com/@iamalleksy/how-to-mount-raspberry-pi-sd-card-using-mac-3046abc2059a&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;ext4fuse&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.raspberrypi.com/software/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Raspberry Pi Imager&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://youtu.be/r8CGixMl18k?t=358&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Tutorial: Setting up GPS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://youtu.be/r8CGixMl18k&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Tutorial: Setting up AIS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=tlU4HKT6XxM&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Tutorial: Creating OpenPlotter Access Point&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://openplotter.readthedocs.io/en/latest/getting_started/installing.html?highlight=ssh#headless&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Tutorial: SSH Connection&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Inverse ecosystem modeling made easy with PiecewiseInference.jl</title>
      <link>https://vboussange.github.io/post/piecewiseinference/</link>
      <pubDate>Sun, 26 Mar 2023 00:00:00 +0000</pubDate>
      <guid>https://vboussange.github.io/post/piecewiseinference/</guid>
      <description>&lt;p&gt;Mechanistic ecosystem models permit to quantiatively describe how population, species or communities grow, interact and evolve. Yet calibrating them to fit real-world data is a daunting task. That&amp;rsquo;s why I&amp;rsquo;m excited to introduce &lt;a href=&#34;https://github.com/vboussange/PiecewiseInference.jl&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;&lt;strong&gt;PiecewiseInference.jl&lt;/strong&gt;&lt;/a&gt;, a new Julia package that provides a user-friendly and efficient framework for inverse ecosystem modeling. In this blog post, I will guide you through the main features of &lt;strong&gt;PiecewiseInference.jl&lt;/strong&gt; and provide a step-by-step tutorial on how to use it with a three-compartment ecosystem model. Whether you&amp;rsquo;re a quantitative ecologist or a curious data scientist, I hope this post will encourage you to join the effort and use and develop inverse ecosystem modelling methods to improve our understanding and predictions of ecosystems.&lt;/p&gt;
&lt;h2 id=&#34;preliminary-steps&#34;&gt;Preliminary steps&lt;/h2&gt;
&lt;p&gt;This tutorial relies on three packages that I have authored but are (yet) not registered on the official Julia registry. Those are&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;PiecewiseInference&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;&lt;code&gt;EcoEvoModelZoo&lt;/code&gt;: a package which provides access to a collection of ecosystem models,&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ParametricModels&lt;/code&gt;: a wrapper package to manipulate dynamical models. Specifically, &lt;code&gt;ParametricModels&lt;/code&gt; avoids the hassle of specifying, at each time you want to simulate an ODE model, boring details such as the algorithm to solve it, the time span, etc&amp;hellip;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To easily install them on your machine, you&amp;rsquo;ll have to add my personal registry by doing the following:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;using&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Pkg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Pkg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Registry&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RegistrySpec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;url&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;https://github.com/vboussange/VBoussangeRegistry.git&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Once this is done, let&amp;rsquo;s import those together with other necessary Julia packages for this tutorial.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;using&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Graphs&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;using&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;EcoEvoModelZoo&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;using&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ParametricModels&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;using&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;LinearAlgebra&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;using&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;UnPack&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;using&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;OrdinaryDiffEq&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;using&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Statistics&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;using&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;SparseArrays&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;using&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ComponentArrays&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;using&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;PythonPlot&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We use &lt;code&gt;Graphs&lt;/code&gt; to create a directed graph to represent the food web to be considered The &lt;code&gt;OrdinaryDiffEq&lt;/code&gt; package provides tools for solving ordinary differential equations, while the &lt;code&gt;LinearAlgebra&lt;/code&gt; package is used for linear algebraic computations. The &lt;code&gt;UnPack&lt;/code&gt; package provides a convenient way to extract fields from structures, and the &lt;code&gt;ComponentArrays&lt;/code&gt; package is used to store and manipulate the model parameters conveniently. Finally, the &lt;code&gt;PythonCall&lt;/code&gt; package is used to interface with Python&amp;rsquo;s Matplotlib library for visualization.&lt;/p&gt;
&lt;h2 id=&#34;definition-of-the-forward-model&#34;&gt;Definition of the forward model&lt;/h2&gt;
&lt;h3 id=&#34;defining-hyperparameters-for-the-forward-simulation-of-the-model&#34;&gt;Defining hyperparameters for the forward simulation of the model.&lt;/h3&gt;
&lt;p&gt;Next, we define the algorithm used for solving the ODE model. We also define the
absolute tolerance (&lt;code&gt;abstol&lt;/code&gt;) and relative tolerance (&lt;code&gt;reltol&lt;/code&gt;) for the solver.
&lt;code&gt;tspan&lt;/code&gt; is a tuple representing the time range we will simulate the system for,
and &lt;code&gt;tsteps&lt;/code&gt; is a vector representing the times we want to output the simulated
data.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;alg&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;BS3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;abstol&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;1e-6&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;reltol&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;1e-6&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;tspan&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;600&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;tsteps&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;range&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;300&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;tspan&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;length&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;100&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;300.0:3.0303030303030303:600.0
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;defining-the-foodweb-structure&#34;&gt;Defining the foodweb structure&lt;/h3&gt;
&lt;p&gt;We&amp;rsquo;ll define a 3-compartment ecosystem as presented in &lt;a href=&#34;http://doi.wiley.com/10.2307/1939558&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;McCann et al. (1994)&lt;/a&gt;. We will use &lt;code&gt;SimpleEcosystemModel&lt;/code&gt; from EcoEvoModeZoo.jl, which requires as input a foodweb structure. Let&amp;rsquo;s use a &lt;code&gt;DiGraph&lt;/code&gt; to represent it.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;N&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt; &lt;span class=&#34;c&#34;&gt;# number of compartment&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;foodweb&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;DiGraph&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;N&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;add_edge!&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;foodweb&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c&#34;&gt;# C to R&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;add_edge!&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;foodweb&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c&#34;&gt;# P to C&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;true
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;N&lt;/code&gt; variable specifies the number of
compartments in the model. The &lt;code&gt;add_edge!&lt;/code&gt; function is used to add edges to the
graph, specifying the flow of resources between compartments.&lt;/p&gt;
&lt;p&gt;For fun, let&amp;rsquo;s just plot the foodweb. Here we use the PythonCall and PythonPlot
packages to visualize the food web as a directed graph using &lt;code&gt;networkx&lt;/code&gt; and &lt;code&gt;numpy&lt;/code&gt;.
We create a color list for the different species, and then create a directed
graph g_nx with networkx using the adjacency matrix of the food web. We also
specify the position of each node in the graph, and use nx.draw to draw the
graph with&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;using&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;PythonCall&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;nx&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pyimport&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;networkx&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;np&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pyimport&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;numpy&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;species_colors&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;tab:red&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;tab:green&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;tab:blue&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;g_nx&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;nx&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DiGraph&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;np&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;array&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;adjacency_matrix&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;foodweb&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;pos&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;Dict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;labs&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;Dict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;Resource&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;Consumer&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;Prey&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;fig&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ax&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;subplots&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;nx&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;draw&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;g_nx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pos&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ax&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ax&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;node_color&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;species_colors&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;node_size&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;labs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;display&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fig&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;













&lt;figure  &gt;
  &lt;div class=&#34;d-flex justify-content-center&#34;&gt;
    &lt;div class=&#34;w-100&#34; &gt;&lt;img alt=&#34;&#34; srcset=&#34;
               /post/piecewiseinference/figures/PiecewiseInference_tuto_3sp_6_1_hu62f1111d24c26835f7d3777e0accf1d1_18752_10e755f0e2d2b299c1ba09efc8ef5dcb.webp 400w,
               /post/piecewiseinference/figures/PiecewiseInference_tuto_3sp_6_1_hu62f1111d24c26835f7d3777e0accf1d1_18752_35f7999e8532103edebd24f910725eba.webp 760w,
               /post/piecewiseinference/figures/PiecewiseInference_tuto_3sp_6_1_hu62f1111d24c26835f7d3777e0accf1d1_18752_1200x1200_fit_q75_h2_lanczos_3.webp 1200w&#34;
               src=&#34;https://vboussange.github.io/post/piecewiseinference/figures/PiecewiseInference_tuto_3sp_6_1_hu62f1111d24c26835f7d3777e0accf1d1_18752_10e755f0e2d2b299c1ba09efc8ef5dcb.webp&#34;
               width=&#34;515&#34;
               height=&#34;389&#34;
               loading=&#34;lazy&#34; data-zoomable /&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;/figure&gt;
&lt;h3 id=&#34;defining-the-ecosystem-model&#34;&gt;Defining the ecosystem model&lt;/h3&gt;
&lt;p&gt;Now that we have defined the foodweb structure, we can build the ecosystem
model, which will be a &lt;code&gt;SimpleEcosystemModel&lt;/code&gt; from &lt;code&gt;EcoEvoModelZoo&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The next several functions are required by &lt;code&gt;SimpleEcosystemModel&lt;/code&gt; and define the
specific dynamics of the model. The &lt;code&gt;intinsic_growth_rate&lt;/code&gt; function specifies
the intrinsic growth rate of each compartment, while the &lt;code&gt;carrying_capacity&lt;/code&gt;
function specifies the carrying capacity of each compartment. The &lt;code&gt;competition&lt;/code&gt;
function specifies the competition between and within compartments, while the
&lt;code&gt;resource_conversion_efficiency&lt;/code&gt; function specifies the efficiency with which
resources are converted into consumer biomass. The &lt;code&gt;feeding&lt;/code&gt; function specifies
the feeding interactions between compartments.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;intinsic_growth_rate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;t&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;r&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;carrying_capacity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;t&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nd&#34;&gt;@unpack&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;K₁₁&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;K&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;vcat&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;K₁₁&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ones&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;N&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;K&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;competition&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;u&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;t&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nd&#34;&gt;@unpack&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;A₁₁&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;A&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;spdiagm&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vcat&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;A₁₁&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;A&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;u&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;resource_conversion_efficiency&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;t&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ones&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;N&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;resource_conversion_efficiency (generic function with 1 method)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To define the feeding processes, we use &lt;code&gt;adjacency_matrix&lt;/code&gt; to get the adjacency matrix of the food web. We then use &lt;code&gt;findnz&lt;/code&gt; from &lt;code&gt;SparseArrays&lt;/code&gt; to get the row and column indices of the non-zero entries in the adjacency matrix, which we store in &lt;code&gt;I&lt;/code&gt; and &lt;code&gt;J&lt;/code&gt;. Those are then used to generate sparse matrices required for defining the functional responses of each species considered. The sparse matrices&amp;rsquo; non-zero coefficients are the model parameters to be fitted.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;using&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;SparseArrays&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;W&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;adjacency_matrix&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;foodweb&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;I&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;J&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;_&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;findnz&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;W&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;([2, 3], [1, 2], [1, 1])
&lt;/code&gt;&lt;/pre&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;feeding&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;u&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;t&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nd&#34;&gt;@unpack&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;H₂₁&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;H₃₂&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;q₂₁&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;q₃₂&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c&#34;&gt;# handling time&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;H&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;sparse&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;I&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;J&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;vcat&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;H₂₁&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;H₃₂&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;N&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;N&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c&#34;&gt;# attack rates&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;q&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;sparse&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;I&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;J&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;vcat&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;q₂₁&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;q₃₂&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;N&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;N&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;q&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.*&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;W&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;./&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;one&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;eltype&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;u&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;q&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.*&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;H&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.*&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;W&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;u&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;feeding (generic function with 1 method)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We are done defining the ecological processes.&lt;/p&gt;
&lt;h4 id=&#34;defining-the-ecosystem-model-parameters-for-generating-a-dataset&#34;&gt;Defining the ecosystem model parameters for generating a dataset&lt;/h4&gt;
&lt;p&gt;The parameters for the ecosystem model are defined using a &lt;code&gt;ComponentArray&lt;/code&gt;. The
&lt;code&gt;u0_true&lt;/code&gt; variable specifies the initial conditions for the simulation. The
&lt;code&gt;ModelParams&lt;/code&gt; type from the ParametricModels package is used to specify the
model parameters and simulation settings. Finally, the &lt;code&gt;SimpleEcosystemModel&lt;/code&gt;
type from the EcoEvoModelZoo package is used to define the ecosystem model.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;p_true&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ComponentArray&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;H₂₁&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;1.24&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                        &lt;span class=&#34;n&#34;&gt;H₃₂&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;2.5&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                        &lt;span class=&#34;n&#34;&gt;q₂₁&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;4.98&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                        &lt;span class=&#34;n&#34;&gt;q₃₂&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.8&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                        &lt;span class=&#34;n&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;1.0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.08&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                        &lt;span class=&#34;n&#34;&gt;K₁₁&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;1.0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                        &lt;span class=&#34;n&#34;&gt;A₁₁&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;1.0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;u0_true&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.77&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.060&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0.945&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;mp&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ModelParams&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;p_true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;tspan&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;u0&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;u0_true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;alg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;reltol&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;abstol&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;saveat&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tsteps&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;verbose&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;c&#34;&gt;# suppresses warnings for maxiters&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;maxiters&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;50_000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;model&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;SimpleEcosystemModel&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;mp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;intinsic_growth_rate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;carrying_capacity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;competition&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;resource_conversion_efficiency&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;feeding&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;`Model` SimpleEcosystemModel
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Let&amp;rsquo;s run the model to generate a dataset! There is nothing more simple than that. Let&amp;rsquo;s also plot it,
to get a sense of what it looks like.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;simulate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;model&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;u0&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;u0_true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;Array&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;# plotting&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;using&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;PythonPlot&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;plot_time_series&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;fig&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ax&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;subplots&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;i&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;N&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;ax&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;plot&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;label&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;Species &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;$i&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;color&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;species_colors&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c&#34;&gt;# ax.set_yscale(&amp;#34;log&amp;#34;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;ax&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;set_ylabel&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;Species abundance&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;ax&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;set_xlabel&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;Time (days)&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;fig&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;set_facecolor&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;None&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;ax&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;set_facecolor&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;None&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;fig&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;legend&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;fig&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;display&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;plot_time_series&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;













&lt;figure  &gt;
  &lt;div class=&#34;d-flex justify-content-center&#34;&gt;
    &lt;div class=&#34;w-100&#34; &gt;&lt;img alt=&#34;&#34; srcset=&#34;
               /post/piecewiseinference/figures/PiecewiseInference_tuto_3sp_11_1_hu88f93306fecaa2cf8298e559a40e861a_58481_c975a3cfc0846552c904f169348dcc29.webp 400w,
               /post/piecewiseinference/figures/PiecewiseInference_tuto_3sp_11_1_hu88f93306fecaa2cf8298e559a40e861a_58481_f877ee1ebc333b179217ec1015565366.webp 760w,
               /post/piecewiseinference/figures/PiecewiseInference_tuto_3sp_11_1_hu88f93306fecaa2cf8298e559a40e861a_58481_1200x1200_fit_q75_h2_lanczos_3.webp 1200w&#34;
               src=&#34;https://vboussange.github.io/post/piecewiseinference/figures/PiecewiseInference_tuto_3sp_11_1_hu88f93306fecaa2cf8298e559a40e861a_58481_c975a3cfc0846552c904f169348dcc29.webp&#34;
               width=&#34;624&#34;
               height=&#34;483&#34;
               loading=&#34;lazy&#34; data-zoomable /&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;/figure&gt;
&lt;p&gt;Let&amp;rsquo;s add a bit of noise to the data to simulate experimental errors. We proceed by adding
log normally distributed noise, so that abundance are always positive (negative abundance would not make sense, but could happen when adding normally distributed noise!).&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.*&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;exp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.1&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;randn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;display&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;plot_time_series&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;













&lt;figure  &gt;
  &lt;div class=&#34;d-flex justify-content-center&#34;&gt;
    &lt;div class=&#34;w-100&#34; &gt;&lt;img alt=&#34;&#34; srcset=&#34;
               /post/piecewiseinference/figures/PiecewiseInference_tuto_3sp_12_1_hu50ffac68b212487f6faa1c84d11603c5_61363_cf84a27edd15202fdc0564e5f5ec4d61.webp 400w,
               /post/piecewiseinference/figures/PiecewiseInference_tuto_3sp_12_1_hu50ffac68b212487f6faa1c84d11603c5_61363_5247d0bf07af9c34f952b80f3e723489.webp 760w,
               /post/piecewiseinference/figures/PiecewiseInference_tuto_3sp_12_1_hu50ffac68b212487f6faa1c84d11603c5_61363_1200x1200_fit_q75_h2_lanczos_3.webp 1200w&#34;
               src=&#34;https://vboussange.github.io/post/piecewiseinference/figures/PiecewiseInference_tuto_3sp_12_1_hu50ffac68b212487f6faa1c84d11603c5_61363_cf84a27edd15202fdc0564e5f5ec4d61.webp&#34;
               width=&#34;624&#34;
               height=&#34;483&#34;
               loading=&#34;lazy&#34; data-zoomable /&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;/figure&gt;
&lt;h2 id=&#34;inversion-with-piecewiseinferencejl&#34;&gt;Inversion with &lt;code&gt;PiecewiseInference.jl&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;Now that we have set up our model and generated some data, we can proceed with the inverse modelling using PiecewiseInference.jl.&lt;/p&gt;
&lt;p&gt;PiecewiseInference.jl allows to perform inversion based on a segmentation method that partitions the data into short time series (segments), each treated independently and matched against simulations of the model considered. The segmentation approach helps to avoid the ill-behaved loss functions that arise from the strong nonlinearities of ecosystem models, when formulation the inference problem. Note that during the inversion, not only the parameters are inferred, but also the &lt;strong&gt;initial conditions&lt;/strong&gt;, which are necessary to simulate the ODE model.&lt;/p&gt;
&lt;h3 id=&#34;definition-of-the-inferenceproblem&#34;&gt;Definition of the &lt;code&gt;InferenceProblem&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;We first import the packages required for the inversion. &lt;code&gt;PiecewiseInference&lt;/code&gt; is the
main package used, but we also need &lt;code&gt;OptimizationFlux&lt;/code&gt; for the &lt;code&gt;Adam&lt;/code&gt; optimizer,
and &lt;code&gt;SciMLSensitivity&lt;/code&gt; to define the sensitivity method used to differentiate
the forward model.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;using&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;PiecewiseInference&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;using&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;OptimizationFlux&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;using&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;SciMLSensitivity&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;To initialize the inversion, we set the initial values for the parameters in &lt;code&gt;p_init&lt;/code&gt; to those of &lt;code&gt;p_true&lt;/code&gt; but modify the &lt;code&gt;H₂₁&lt;/code&gt; parameter.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;p_init&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;p_true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;p_init&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;H₂₁&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.=&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;2.0&lt;/span&gt; &lt;span class=&#34;c&#34;&gt;#&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;1-element view(::Vector{Float64}, 1:1) with eltype Float64:
 2.0
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Next, we define a loss function &lt;code&gt;loss_likelihood&lt;/code&gt; that compares the observed data
with the predicted data. Here, we use a simple mean-squared error loss function while log transforming the abundance, since the noise is log-normally distributed.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;loss_likelihood&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pred&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;sum&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.-&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pred&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.^&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# loss_fn_lognormal_distrib(data, pred, noise_distrib)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;loss_likelihood (generic function with 1 method)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We then define the &lt;code&gt;InferenceProblem&lt;/code&gt;, which contains the forward
model, the initial parameter values, and the loss function.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;infprob&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;InferenceProblem&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;model&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;p_init&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;loss_likelihood&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It is also handy to use a callback function, that will be called after each iteration of the optimization routine, for visualizing the progress of the inference. Here, we use it to track the loss value and plot the data against the model predictions.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;info_per_its&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;50&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;include&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;cb.jl&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c&#34;&gt;# defines the `plotting_fit` function&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;callback&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;p_trained&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;losses&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pred&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ranges&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;length&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;losses&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;%&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;info_per_its&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;plotting_fit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;losses&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pred&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ranges&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;tsteps&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;callback (generic function with 1 method)
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;piecewise_mle-hyperparameters&#34;&gt;&lt;code&gt;piecewise_MLE&lt;/code&gt; hyperparameters&lt;/h3&gt;
&lt;p&gt;To use &lt;code&gt;piecewise_MLE&lt;/code&gt;, the main function of PiecewiseInference  to estimate the parameters that fit the observed data, we need to decide on two critical hyperparameters&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;group_size&lt;/code&gt;: the number of data points that define an interval, or segment. This number is usually small, but should be decided upon the dynamics of the model: to more nonlinear is the model, the lower &lt;code&gt;group_size&lt;/code&gt; should be. We set it here to &lt;code&gt;11&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;batch_size&lt;/code&gt;: the number of intervals, or segments, to consider on a single epoch. The higher the &lt;code&gt;batch_size&lt;/code&gt;, the more computationally expensive a single iteration of &lt;code&gt;piecewise_MLE&lt;/code&gt;, but the faster the convergence. Here, we set it to &lt;code&gt;5&lt;/code&gt;, but could increase it to &lt;code&gt;10&lt;/code&gt;, which is the total number of segments that we have.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Another critical parameter to be decided upon is the automatic differentiation backend used to differentiate the ODE model. Two are supported, &lt;code&gt;Optimization.AutoForwardDiff()&lt;/code&gt; and &lt;code&gt;Optimization.Autozygote()&lt;/code&gt;. Simply put, &lt;code&gt;Optimization.AutoForwardDiff()&lt;/code&gt; is used for forward mode sensitivity analysis, while &lt;code&gt;Optimization.Autozygote()&lt;/code&gt; is used for backward mode sensitivity analysis. For more information on those, please refer to the documentation of &lt;a href=&#34;https://docs.sciml.ai/Optimization/stable/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;&lt;code&gt;Optimization.jl&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Other parameters required by &lt;code&gt;piecewise_MLE&lt;/code&gt; are&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;optimizers&lt;/code&gt; specifies the optimization algorithm to be used for each batch. We use the &lt;code&gt;Adam&lt;/code&gt; optimizer, which is the go-to optimizer to train deep learning models. It has a learning rate parameter that controls the step size at each iteration. We have chosen a value of &lt;code&gt;1e-2&lt;/code&gt; because it provides good convergence without causing numerical instability,&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;epochs&lt;/code&gt; specifies the number of epochs to be used for each batch. We chose a value of &lt;code&gt;500&lt;/code&gt; because it is sufficient to achieve good convergence,&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;info_per_its&lt;/code&gt; specifies after how many iterations the &lt;code&gt;callback&lt;/code&gt; function should be called&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;verbose_loss&lt;/code&gt; prints the value of the loss function during training,&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nd&#34;&gt;@time&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;res&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;piecewise_MLE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;infprob&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                        &lt;span class=&#34;n&#34;&gt;adtype&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Optimization&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AutoZygote&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                        &lt;span class=&#34;n&#34;&gt;group_size&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;11&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                        &lt;span class=&#34;n&#34;&gt;batchsizes&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                        &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                        &lt;span class=&#34;n&#34;&gt;tsteps&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;tsteps&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                        &lt;span class=&#34;n&#34;&gt;optimizers&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Adam&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;1e-2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                        &lt;span class=&#34;n&#34;&gt;epochs&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;500&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                        &lt;span class=&#34;n&#34;&gt;verbose_loss&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                        &lt;span class=&#34;n&#34;&gt;info_per_its&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;info_per_its&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                        &lt;span class=&#34;n&#34;&gt;multi_threading&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                        &lt;span class=&#34;n&#34;&gt;cb&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;callback&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;piecewise_MLE with 100 points and 10 groups.
Current loss after 50 iterations: 36.745952018526495
Current loss after 100 iterations: 15.064711239454626
Current loss after 150 iterations: 9.993029255013324
Current loss after 200 iterations: 7.994491307947515
Current loss after 250 iterations: 6.500818892986831
Current loss after 300 iterations: 5.3892647156988565
Current loss after 350 iterations: 3.0351181646280514
Current loss after 400 iterations: 2.674445730720996
Current loss after 450 iterations: 3.1591980829795676
Current loss after 500 iterations: 2.4343376293865995
157.765049 seconds (1.70 G allocations: 154.827 GiB, 10.16% gc time, 31.31%
 compilation time: 1% of which was recompilation)
`InferenceResult` with model SimpleEcosystemModel
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;













&lt;figure  &gt;
  &lt;div class=&#34;d-flex justify-content-center&#34;&gt;
    &lt;div class=&#34;w-100&#34; &gt;&lt;img alt=&#34;&#34; srcset=&#34;
               /post/piecewiseinference/figures/PiecewiseInference_tuto_3sp_18_1_hu644528a1afcd815ff2b86b36da8e875e_51903_052be7b24d15a8a1ec5bed0bda06abb3.webp 400w,
               /post/piecewiseinference/figures/PiecewiseInference_tuto_3sp_18_1_hu644528a1afcd815ff2b86b36da8e875e_51903_97dcb6d009d016383d30b3bb8171cd37.webp 760w,
               /post/piecewiseinference/figures/PiecewiseInference_tuto_3sp_18_1_hu644528a1afcd815ff2b86b36da8e875e_51903_1200x1200_fit_q75_h2_lanczos_3.webp 1200w&#34;
               src=&#34;https://vboussange.github.io/post/piecewiseinference/figures/PiecewiseInference_tuto_3sp_18_1_hu644528a1afcd815ff2b86b36da8e875e_51903_052be7b24d15a8a1ec5bed0bda06abb3.webp&#34;
               width=&#34;489&#34;
               height=&#34;690&#34;
               loading=&#34;lazy&#34; data-zoomable /&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;/figure&gt;













&lt;figure  &gt;
  &lt;div class=&#34;d-flex justify-content-center&#34;&gt;
    &lt;div class=&#34;w-100&#34; &gt;&lt;img alt=&#34;&#34; srcset=&#34;
               /post/piecewiseinference/figures/PiecewiseInference_tuto_3sp_18_2_hub59b77110153b2205abc9c1e99bfc5bf_57338_a0de2edb622a676911308bc7c027326f.webp 400w,
               /post/piecewiseinference/figures/PiecewiseInference_tuto_3sp_18_2_hub59b77110153b2205abc9c1e99bfc5bf_57338_37371b7de5af5259bdf23d2d6883bd20.webp 760w,
               /post/piecewiseinference/figures/PiecewiseInference_tuto_3sp_18_2_hub59b77110153b2205abc9c1e99bfc5bf_57338_1200x1200_fit_q75_h2_lanczos_3.webp 1200w&#34;
               src=&#34;https://vboussange.github.io/post/piecewiseinference/figures/PiecewiseInference_tuto_3sp_18_2_hub59b77110153b2205abc9c1e99bfc5bf_57338_a0de2edb622a676911308bc7c027326f.webp&#34;
               width=&#34;489&#34;
               height=&#34;690&#34;
               loading=&#34;lazy&#34; data-zoomable /&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;/figure&gt;













&lt;figure  &gt;
  &lt;div class=&#34;d-flex justify-content-center&#34;&gt;
    &lt;div class=&#34;w-100&#34; &gt;&lt;img alt=&#34;&#34; srcset=&#34;
               /post/piecewiseinference/figures/PiecewiseInference_tuto_3sp_18_3_hu0c6830235736031988016ed400339b9a_61477_1c204d0508f20610d84505b1e77cb3bc.webp 400w,
               /post/piecewiseinference/figures/PiecewiseInference_tuto_3sp_18_3_hu0c6830235736031988016ed400339b9a_61477_8c1118e95b11d7c7c26cd9db41ad4523.webp 760w,
               /post/piecewiseinference/figures/PiecewiseInference_tuto_3sp_18_3_hu0c6830235736031988016ed400339b9a_61477_1200x1200_fit_q75_h2_lanczos_3.webp 1200w&#34;
               src=&#34;https://vboussange.github.io/post/piecewiseinference/figures/PiecewiseInference_tuto_3sp_18_3_hu0c6830235736031988016ed400339b9a_61477_1c204d0508f20610d84505b1e77cb3bc.webp&#34;
               width=&#34;489&#34;
               height=&#34;690&#34;
               loading=&#34;lazy&#34; data-zoomable /&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;/figure&gt;













&lt;figure  &gt;
  &lt;div class=&#34;d-flex justify-content-center&#34;&gt;
    &lt;div class=&#34;w-100&#34; &gt;&lt;img alt=&#34;&#34; srcset=&#34;
               /post/piecewiseinference/figures/PiecewiseInference_tuto_3sp_18_4_huecf8cacf7a0f7f9060f2a1c560c36ba2_61371_70796bd92f69d9848045c8747c21e2eb.webp 400w,
               /post/piecewiseinference/figures/PiecewiseInference_tuto_3sp_18_4_huecf8cacf7a0f7f9060f2a1c560c36ba2_61371_e07ca3fe8b9e27e683d1e50c7808840d.webp 760w,
               /post/piecewiseinference/figures/PiecewiseInference_tuto_3sp_18_4_huecf8cacf7a0f7f9060f2a1c560c36ba2_61371_1200x1200_fit_q75_h2_lanczos_3.webp 1200w&#34;
               src=&#34;https://vboussange.github.io/post/piecewiseinference/figures/PiecewiseInference_tuto_3sp_18_4_huecf8cacf7a0f7f9060f2a1c560c36ba2_61371_70796bd92f69d9848045c8747c21e2eb.webp&#34;
               width=&#34;490&#34;
               height=&#34;690&#34;
               loading=&#34;lazy&#34; data-zoomable /&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;/figure&gt;













&lt;figure  &gt;
  &lt;div class=&#34;d-flex justify-content-center&#34;&gt;
    &lt;div class=&#34;w-100&#34; &gt;&lt;img alt=&#34;&#34; srcset=&#34;
               /post/piecewiseinference/figures/PiecewiseInference_tuto_3sp_18_5_huc0b13721a1fc34c0a8afcd483ca19fda_59693_c5f401e8b86a08001a2aebd584ba28af.webp 400w,
               /post/piecewiseinference/figures/PiecewiseInference_tuto_3sp_18_5_huc0b13721a1fc34c0a8afcd483ca19fda_59693_ab36b526814d592e4592f3302e97d665.webp 760w,
               /post/piecewiseinference/figures/PiecewiseInference_tuto_3sp_18_5_huc0b13721a1fc34c0a8afcd483ca19fda_59693_1200x1200_fit_q75_h2_lanczos_3.webp 1200w&#34;
               src=&#34;https://vboussange.github.io/post/piecewiseinference/figures/PiecewiseInference_tuto_3sp_18_5_huc0b13721a1fc34c0a8afcd483ca19fda_59693_c5f401e8b86a08001a2aebd584ba28af.webp&#34;
               width=&#34;489&#34;
               height=&#34;690&#34;
               loading=&#34;lazy&#34; data-zoomable /&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;/figure&gt;













&lt;figure  &gt;
  &lt;div class=&#34;d-flex justify-content-center&#34;&gt;
    &lt;div class=&#34;w-100&#34; &gt;&lt;img alt=&#34;&#34; srcset=&#34;
               /post/piecewiseinference/figures/PiecewiseInference_tuto_3sp_18_6_hu8b153de27522278f60c8b9094dba7d26_58645_4bbecbdf3fa63ce1fede227fce3b8977.webp 400w,
               /post/piecewiseinference/figures/PiecewiseInference_tuto_3sp_18_6_hu8b153de27522278f60c8b9094dba7d26_58645_752c57695f0f5cd04e3cb3a70cb0ce21.webp 760w,
               /post/piecewiseinference/figures/PiecewiseInference_tuto_3sp_18_6_hu8b153de27522278f60c8b9094dba7d26_58645_1200x1200_fit_q75_h2_lanczos_3.webp 1200w&#34;
               src=&#34;https://vboussange.github.io/post/piecewiseinference/figures/PiecewiseInference_tuto_3sp_18_6_hu8b153de27522278f60c8b9094dba7d26_58645_4bbecbdf3fa63ce1fede227fce3b8977.webp&#34;
               width=&#34;489&#34;
               height=&#34;690&#34;
               loading=&#34;lazy&#34; data-zoomable /&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;/figure&gt;













&lt;figure  &gt;
  &lt;div class=&#34;d-flex justify-content-center&#34;&gt;
    &lt;div class=&#34;w-100&#34; &gt;&lt;img alt=&#34;&#34; srcset=&#34;
               /post/piecewiseinference/figures/PiecewiseInference_tuto_3sp_18_7_hub43b68847da7711a5b38542b22e53e3a_56399_10a11afb84b89ce0e9ed83394b7b9e3b.webp 400w,
               /post/piecewiseinference/figures/PiecewiseInference_tuto_3sp_18_7_hub43b68847da7711a5b38542b22e53e3a_56399_2df980826d955efac7e5de19466655fa.webp 760w,
               /post/piecewiseinference/figures/PiecewiseInference_tuto_3sp_18_7_hub43b68847da7711a5b38542b22e53e3a_56399_1200x1200_fit_q75_h2_lanczos_3.webp 1200w&#34;
               src=&#34;https://vboussange.github.io/post/piecewiseinference/figures/PiecewiseInference_tuto_3sp_18_7_hub43b68847da7711a5b38542b22e53e3a_56399_10a11afb84b89ce0e9ed83394b7b9e3b.webp&#34;
               width=&#34;489&#34;
               height=&#34;690&#34;
               loading=&#34;lazy&#34; data-zoomable /&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;/figure&gt;













&lt;figure  &gt;
  &lt;div class=&#34;d-flex justify-content-center&#34;&gt;
    &lt;div class=&#34;w-100&#34; &gt;&lt;img alt=&#34;&#34; srcset=&#34;
               /post/piecewiseinference/figures/PiecewiseInference_tuto_3sp_18_8_hud367ed67f9cef0b1b3e29612594ffe3d_53849_4bff0413d5c6e5b1cb6196a8c43e2c56.webp 400w,
               /post/piecewiseinference/figures/PiecewiseInference_tuto_3sp_18_8_hud367ed67f9cef0b1b3e29612594ffe3d_53849_f9133b73685625059329d3525a171463.webp 760w,
               /post/piecewiseinference/figures/PiecewiseInference_tuto_3sp_18_8_hud367ed67f9cef0b1b3e29612594ffe3d_53849_1200x1200_fit_q75_h2_lanczos_3.webp 1200w&#34;
               src=&#34;https://vboussange.github.io/post/piecewiseinference/figures/PiecewiseInference_tuto_3sp_18_8_hud367ed67f9cef0b1b3e29612594ffe3d_53849_4bff0413d5c6e5b1cb6196a8c43e2c56.webp&#34;
               width=&#34;489&#34;
               height=&#34;690&#34;
               loading=&#34;lazy&#34; data-zoomable /&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;/figure&gt;













&lt;figure  &gt;
  &lt;div class=&#34;d-flex justify-content-center&#34;&gt;
    &lt;div class=&#34;w-100&#34; &gt;&lt;img alt=&#34;&#34; srcset=&#34;
               /post/piecewiseinference/figures/PiecewiseInference_tuto_3sp_18_9_hu9ea766d9bd81b237a28e713a1d702d64_54361_ad72f6d0ff86bfbeb34abb63253fe332.webp 400w,
               /post/piecewiseinference/figures/PiecewiseInference_tuto_3sp_18_9_hu9ea766d9bd81b237a28e713a1d702d64_54361_c7efedd5ddf92a4004a51498d2c68267.webp 760w,
               /post/piecewiseinference/figures/PiecewiseInference_tuto_3sp_18_9_hu9ea766d9bd81b237a28e713a1d702d64_54361_1200x1200_fit_q75_h2_lanczos_3.webp 1200w&#34;
               src=&#34;https://vboussange.github.io/post/piecewiseinference/figures/PiecewiseInference_tuto_3sp_18_9_hu9ea766d9bd81b237a28e713a1d702d64_54361_ad72f6d0ff86bfbeb34abb63253fe332.webp&#34;
               width=&#34;489&#34;
               height=&#34;690&#34;
               loading=&#34;lazy&#34; data-zoomable /&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;/figure&gt;













&lt;figure  &gt;
  &lt;div class=&#34;d-flex justify-content-center&#34;&gt;
    &lt;div class=&#34;w-100&#34; &gt;&lt;img alt=&#34;&#34; srcset=&#34;
               /post/piecewiseinference/figures/PiecewiseInference_tuto_3sp_18_10_hu31111221a9b8d5443a38403556a4aa3b_53967_90f96d7145da90f6a70a84d076c4e54d.webp 400w,
               /post/piecewiseinference/figures/PiecewiseInference_tuto_3sp_18_10_hu31111221a9b8d5443a38403556a4aa3b_53967_df825400af3210504bd5ee8772bcb331.webp 760w,
               /post/piecewiseinference/figures/PiecewiseInference_tuto_3sp_18_10_hu31111221a9b8d5443a38403556a4aa3b_53967_1200x1200_fit_q75_h2_lanczos_3.webp 1200w&#34;
               src=&#34;https://vboussange.github.io/post/piecewiseinference/figures/PiecewiseInference_tuto_3sp_18_10_hu31111221a9b8d5443a38403556a4aa3b_53967_90f96d7145da90f6a70a84d076c4e54d.webp&#34;
               width=&#34;489&#34;
               height=&#34;690&#34;
               loading=&#34;lazy&#34; data-zoomable /&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;Finally, we can examine the results of the inversion. We can look at the final parameters, and the initial conditions inferred for each segement:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-julia&#34; data-lang=&#34;julia&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;# Some more code&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;p_trained&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;res&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;p_trained&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;u0s_trained&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;res&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;u0s_trained&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;print_param_values&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;p_trained&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;p_true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;k&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;keys&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;p_trained&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;println&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;k&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;println&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;trained value = &amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;display&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;p_trained&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;k&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;println&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;true value =&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;display&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;p_true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;k&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;print_param_values&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;p_trained&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;p_true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;H₂₁
trained value = 
1-element Vector{Float64}:
 1.4786844814887716
true value =
1-element Vector{Float64}:
 2.0
H₃₂
trained value = 
1-element Vector{Float64}:
 1.891238277791975
true value =
1-element Vector{Float64}:
 2.5
q₂₁
trained value = 
1-element Vector{Float64}:
 4.550896291686214
true value =
1-element Vector{Float64}:
 4.98
q₃₂
trained value = 
1-element Vector{Float64}:
 0.7250599871665505
true value =
1-element Vector{Float64}:
 0.8
r
trained value = 
3-element Vector{Float64}:
  0.8705446490535288
 -0.30124597815843823
 -0.08241879418666838
true value =
3-element Vector{Float64}:
  1.0
 -0.4
 -0.08
K₁₁
trained value = 
1-element Vector{Float64}:
 1.0397189294700315
true value =
1-element Vector{Float64}:
 1.0
A₁₁
trained value = 
1-element Vector{Float64}:
 0.972947353012839
true value =
1-element Vector{Float64}:
 1.0
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;your-turn-to-play&#34;&gt;Your turn to play!&lt;/h3&gt;
&lt;p&gt;You can try to change e.g. the &lt;code&gt;batch_sizes&lt;/code&gt; and the &lt;code&gt;group_size&lt;/code&gt;. How do those parameters influence the quality of the inversion?&lt;/p&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;PiecewiseInference.jl provides an efficient and flexible way to perform inference on complex ecological models, making use of automatic differentiation and optimizers traditionally used in Machine Learning. The segmentation method implemented in PiecewiseInference.jl regularizes the inference problem and enables inverse modelling of complex dynamical systems, for which standard methods would otherwise fail.&lt;/p&gt;
&lt;p&gt;Furthermore, PiecewiseInference.jl together with EcoEvoModelZoo.jl offer a powerful toolkit for ecologists and evolutionary biologists to benchmark and validate models against data. The combination of theoretical modelling and data can provide new insights into complex ecological systems, helping us to better understand and predict the dynamics of biodiversity.&lt;/p&gt;
&lt;p&gt;We invite users to explore these packages and contribute to their development, by adding new models to the EcoEvoModelZoo.jl and improve the features of PiecewiseInference.jl. With these tools, we can continue to push the boundaries of ecological modelling and make important strides towards a more sustainable future.&lt;/p&gt;
&lt;h2 id=&#34;appendix&#34;&gt;Appendix&lt;/h2&gt;
&lt;p&gt;You can find the corresponding tutorial as a &lt;code&gt;.jmd&lt;/code&gt; file at &lt;a href=&#34;https://github.com/vboussange/MyTutorials&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;https://github.com/vboussange/MyTutorials&lt;/a&gt;.
Please contact me, if you have found a mistake, or if you have any comment or suggestion on how to improve this tutorial.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Create and deploy your Hugo website</title>
      <link>https://vboussange.github.io/post/create-your-hugo-website/</link>
      <pubDate>Sun, 27 Mar 2022 17:40:15 +0200</pubDate>
      <guid>https://vboussange.github.io/post/create-your-hugo-website/</guid>
      <description>&lt;p&gt;This website is based on the &lt;a href=&#34;&#34;&gt;wowchemy template&lt;/a&gt; that relies on &lt;a href=&#34;https://gohugo.io&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Hugo&lt;/a&gt;, a fast framework for building static websites. Although Hugo has many advantages over its brother Jekyll, a Hugo website is not as easy to deploy on &lt;a href=&#34;https://pages.github.com&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;GitHub Pages&lt;/a&gt;, the free service offered by GitHub to host a personal website. If you want to build your Hugo website and deploy it easily, here is the recipe.&lt;/p&gt;
&lt;h2 id=&#34;build-your-hugo-website&#34;&gt;Build your Hugo website&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Fork the &lt;a href=&#34;https://github.com/wowchemy/starter-hugo-academic&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;github repo&lt;/a&gt; of the wowchemy template.&lt;/li&gt;
&lt;li&gt;Rename the repo as &lt;code&gt;your-username.github.io&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Clone the repo and customise the template following your own taste, following the &lt;a href=&#34;https://wowchemy.com/docs/getting-started/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;wowchemy tutorial&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;You can locally build the website with the command &lt;code&gt;hugo server&lt;/code&gt;
and access it at the adress indicated in the the text printed after the execution of the command.&lt;/li&gt;
&lt;li&gt;Once you are satified with your local website, it is time to publish it! I found out that the easiest way to do so is to create a GitHub Action.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;deploy-automatically-a-hugo-website-on-github-pages&#34;&gt;Deploy automatically a Hugo website on GitHub pages&lt;/h2&gt;
&lt;p&gt;Here I detail how to set up a workflow that will build your website and publish it at each new commit. The idea is to set up a GitHub Action, which job will be to&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Clone the &lt;code&gt;master&lt;/code&gt; from your repo&lt;/li&gt;
&lt;li&gt;Build the Hugo website&lt;/li&gt;
&lt;li&gt;Create / clone a &lt;code&gt;gh-pages&lt;/code&gt; branch&lt;/li&gt;
&lt;li&gt;Copy the static files generated in 2. to the &lt;code&gt;gh-pages&lt;/code&gt; repo&lt;/li&gt;
&lt;li&gt;Push those changes to the &lt;code&gt;gh-pages&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;To do so, first create a file &lt;code&gt;.github/workflows/gh-pages.yml&lt;/code&gt; and add the following content, replacing &lt;code&gt;your-username&lt;/code&gt; by your &amp;hellip; username.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;name: Build and Deploy

on:
  push:
    branches:
      - master

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
    - name: Checkout master
      uses: actions/checkout@v1
      with:
        submodules: true

    - name: Hugo Deploy GitHub Pages
      uses: benmatselby/hugo-deploy-gh-pages@master
      env:
        GO_VERSION: 1.17
        HUGO_VERSION: 0.95.0
        HUGO_EXTENDED: true
        TARGET_REPO: your-username/your-username.github.io
        TARGET_BRANCH: gh-pages
        TOKEN: ${{ secrets.TOKEN_HUGO_DEPLOY }}
        CNAME: vboussange.github.io
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You then need to generate a personnal access token. &lt;a href=&#34;https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Here is a tutorial to do so&lt;/a&gt;. Tick the box &amp;ldquo;repo&amp;rdquo;, to grant full control of private repo. More details on why you need to do so are given in Jame Wright post (see below). Copy the generated code, and go in the settings of your &amp;ldquo;your-username.github.io&amp;rdquo; repo. There, &lt;a href=&#34;https://docs.github.com/en/actions/security-guides/encrypted-secrets&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;create a secret&lt;/a&gt;, call it &lt;code&gt;TOKEN_HUGO_DEPLOY&lt;/code&gt; and paste the previously generated token.&lt;/p&gt;
&lt;p&gt;You are almost all set! Make your first commit. Wait for the action to execute. Once you see the green badge symbolising the success of the deployment Action, go to the Settings of your repo, and in &amp;ldquo;Pages&amp;rdquo; in the left side bar, under &amp;ldquo;Source&amp;rdquo; select the branch &lt;code&gt;gh-pages&lt;/code&gt;. After a few minutes, your website should be available at &lt;a href=&#34;https://your-username.github.io/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;https://your-username.github.io/&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Enjoy!&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This post was greatly inspired by &lt;a href=&#34;https://www.jameswright.xyz/post/20200409/deploy_wowchemy_to_githubio/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;James Wright blog post&lt;/a&gt; on the same topic, although his Github Action was not quite working for me.&lt;/p&gt;
&lt;/blockquote&gt;
</description>
    </item>
    
  </channel>
</rss>
