Pre-requisits: This guide assumes that you are running on a *nix system (e.g. Linux or Mac), and that you have access to a terminal (command line) and are comfortable using it. It is also assumed that you are using the bash
shell.
In what follows, when commands are different in Linux and Mac, they will be preceded by [linux]$
or by [mac]$
, respectively. The actual command that you will be typing should not include the $ sign or what proceeds it.
We will set up our python environment using conda
(more specifically the Miniconda distribution) and install the required packages explicitly (rather than go with a full distribution like Anaconda). This will keep things light-weight and more transparent (in the sense of explicitly deciding what packages are being used).
A big advantage of conda
(versus pip
) is that it can manage environments for different programming languages, not just python.
Per best practices, we will install python for a single user (rather than the whole system), and so both python and conda will live in your user folder (i.e. $HOME: /home/username on Linux or /Users/username on Mac).
Contents
a) Miniconda
Start by installing Miniconda. This will install conda
, python
, their dependencies, and major packages such as pip
. Below is a summary of the installation steps, which are detailed in the Miniconda official page. If in doubt, follow the instructions in the Miniconda page.
- Go to the Miniconda official page, and download the installer for the latest version of Python that corresponds to your system (if you are on a Mac, we suggest you pick the bash installer). In what follows, replace <miniconda-filename> with the name of the file you just downloaded.
- Verify the hash of the installer file you just downloaded using the command for your system
[mac]$ shasum -a 256 <miniconda-filename> [linux]$ sha256sum <miniconda-filename>
and check the result against what is given in the download page before proceeding to the next step.
- Run the installer (which is a .sh file):
bash <miniconda-filename>
and follow the prompts. Make sure to say ‘yes’ to the question
“Do you wish the installer to initialize Miniconda3 by running conda init?”, which will create a~/.bash_profile
file that allows your system to recognize conda.Important note for Mac users: If you are on a Mac, there is one additional step to do here: because the bash shell installation is a little peculiar on macOS, the fact that you now have a
~/.bash_profile
file will create some confusion. To fix that, add the following lines to the newly created~/.bash_profile
file, after the conda part:if [ -r ~/.bashrc ]; then source ~/.bashrc fi
This will source your
~/.bashrc
after the conda setup, and so bring you back to your beloved bash configuration as specified in~/.bashrc
. Thus, anything that you put in~/.bashrc
will take precedence (as it should). So for instance if you do something to your path to add another location for a conda or python binary, those will be used instead of the miniconda version. The advise is thus: do not try to manage python/conda environments directly by specifying paths in~/.bashrc
, but rather only use the appropriateconda
commands and the files in~/.conda
to manage your environments (see Managing Environments) - Close and reopen your terminal window, or open a new window so that changes take effect.
- Test the installation by listing the packages that were installed:
conda list
You should see the list of installed packages, which will look similar to:
Check also that python is now called from the miniconda distribution: the commandwhich python
should return something like
/home/username/miniconda3/bin/python
on Linux or/Users/username/miniconda3/bin/python
on Mac, andpython --version
will be something like Python 3.9.1
After installing Miniconda, you will have the following:
-
- a
~/miniconca3
folder: this is the installation location for (mini)conda and the packages it manages - a
~/.bash_profile
file: this adds the paths necessary for your shell to find the packages - a
~/.conda
folder: this will in time have your conda environment files, and it currently just specifies the (mini)conda installation location
- a
Before proceeding any further, let’s update conda itself to make sure we are using the latest release:
conda update conda
- Remove the miniconda folder:
rm -rf ~/miniconda3
- [Proceed with caution!] Remove the conda folder (backup before deleting if you want to keep your customizations):
rm -rf ~/.conda
- Remove the part of the ~/.bash_profile that sets up conda (edit it in a text editor), or if it only has the conda set up and a sourcing of the bashrc file then you can remove ~/.bash_profile entirely [Proceed with caution!]:
rm ~/.bash_profile
- [Proceed with caution!] If you created a conda configuration file, remove it (backup before deleting if you want to keep your customizations):
rm ~/.condarc
b) Environments
What we are trying to avoid
Because different codes often require different python versions and packages, we’ll use conda
to manage what is referred to as our environment. It is a best practice to create a different environment for each project/code you are developing.
We favor conda
in lieu of python’s virtualenv
because we find it better suited for our needs of engineering and scientific computing (e.g. more transparent structure, everything is installed in one directory so easier to clean/purge, and it can be used with languages other than python).
At this point, we haven’t explicitly created any environments. Running
conda env list
will show only the base
environment which gets created when installing miniconda.
To get started, we’ll create an environment called basecamp
which we’ll use for general python code development:
conda create --name basecamp
creates an environment with no packages. (It will be stored in ~/miniconda3/envs/basecamp
, and this path is appended to the file ~/.conda/environments.txt
). If you now run again
conda env list
you will see two environments: base
and basecamp
. The * indicates that base is currently active.
Let’s switch to basecamp:
conda activate basecamp
You can confirm that it is now active by making sure the * is now on basecamp
when you run via conda env list
. You will also now see (basecamp)
prepended to the terminal prompt (unless you have disabled the prompt indicator).
If you now run
conda list
we’d get an empty list since we created an empty environment and haven’t added any packages yet. Let’s now install the packages that we’ll need.
conda
, the command prompt is updated to show the name of the active environment. This takes precious space in the terminal line, and you can disable it with
conda config --set changeps1 false
You can of course reverse this at any time via
conda config --set changeps1 true
Note: any time you set a configuration parameter via conda config
, the file ~/.condarc
gets updated.
conda create --name python2.7 python=2.7.18
this will create an environment called python2.7
which has Python 2.7.18. If you are not sure which exact version to request, you can see all the options available via
conda search python
base
), you can run the activate
command without arguments:
conda activate
or explicitly activate it
conda activate base
or just deactivate the current (non-default) environment via
conda deactivate
Note that if you activated several environments in a row, conda deactivate
will bring you back through the environments in reverse order one step at a time, so you may need to execute conda deactivate
several times to make your way back to base
.
- Update conda itself
conda update conda
- Installing a package:
conda install <packageName>
or to install a specific version
conda install <packageName>=<version-number>
conda update <packageName>
conda update --all
conda remove <packageName>
conda search <keywordToSearch>
conda env export > environment.yml
and then use that file to recreate your environment (for yourself or others):
conda env create -f environment.yml
Important note: if you are going to export the environment to use across different platforms, you should only export the packages that were explicitly specified for installation, so that the platform in which you create an environment out of your yaml
file will be the one managing the dependencies. This is done via the option --from-history
:
conda env export --from-history > environment.yaml
with the only caveat being that if package versions were not specified when installed, then creating an environment from the resulting yml file might end up with newer versions of the packages.
conda env remove -n <environmentName>
or
conda env remove --prefix <pathToEnvironment>
At this point, you may want to read some good articles on conda environments:
- Official conda documentation: Managing Environments
- Good conceptual explanation: Why You Need Python Environments and How to Manage Them with Conda (dated 2018 but explanations and commands are still relevant)
c) Packages
Make sure you’re in the basecamp
environment:
conda activate basecamp
First of all, we need to install python itself:
conda install python
By not specifying a package’s version, we will be getting the latest one.
Note that two major dependencies of python
that will be installed are pip
(the standard python package installer) and wheel
(python package installation system).
We will be needing the following major packages: NumPy (numerical python) for math functions and array/matrix operations; SciPy (scientific python) for linear algebra, integration, interpolation, optimization, signal processing, etc.; Matplotlib (mathematical ploting library) for plotting functions; SymPy (symbolic python) for symbolic math manipulation. Let’s install them:
conda install numpy scipy matplotlib sympy
It is a good habit to clean up any left-overs from time to time, so let’s clean up while we’re here:
conda clean --all
Your code development environment is now ready! In order to use it, make sure to run
conda activate basecamp
whenever you’re ready to do code development work in python.
Suggestion:
You may want to disable the activation of the default base
environment so at least you won’t be using it by mistake, which you can do via
conda config --set auto_activate_base false
If you ever change your mind, you can of course undo this with
conda config --set auto_activate_base true
or remove the corresponding line from your ~/.condarc
file.
A final warning:
We have decided to use conda
to avoid ending with a maze for an environment (in which which-version-of-which-package-installed-where-is-being-used is anyone’s guess: see illustration above). So avoid using pip
as much as possible! If there is absolutely no way to have conda install a necessary package, and therefore you must use pip
, then make sure to: create a dedicated new environment, install first all the packages that you can with conda
, and only at the end use pip
for that rebellious package.
d) Going further
It is a good practice to store the environment needed for each project in that project’s directory. Say for instance that you have a project called ‘airplane’. You will put all the project’s code and files in a folder called airplane/
, and create an environment named after the project’s name which is stored in the project’s folder. Here’s what the steps would look like:
- Create the project’s folder and move into it
mkdir airplane cd airplane
- Create the folder for the environment (once inside the project’s folder):
mkdir env
- Create the environment with the required packages:
conda create --prefix ./env python numpy scipy matplotlib
The
--prefix
option specifies the location where the environment is to be stored, which will be theenv
sub-folder in our project’s main folder (i.e.airplane/env/
) - Activate the project’s environment:
conda activate ./env
Note how the
activate
command accepts either a name (for environments stored in the default conda location, e.g.~/miniconda3/env/
) or a folder location (where the environment is stored).
If you consistently store your conda
environment in a sub-folder called env
under each of your project’s folders, you will then have a consistent workflow and if your project is version controlled (e.g. using git), then the corresponding environment will also be automatically version controlled. So your workflow would look something like:
cd myProject
conda activate ./env
...
vi main.py
...
python main.py
...
git add .
git commit -m "update to main file"
...
If distributing your code:
A leaner alternative that is good for distributing your code is to use a YAML file instead of storing the whole environment in your project’s folder. This will ensure things work across platforms. To do this, before sharing your project (or maybe regularly to benefit from version control) you would do:
- Export the environment to a YAML file:
cd airplane conda env export > environment.yml
- (optional) Modify the environment’s name in the file
environment.yml
with any text editor to match the name of your project. So the first line ofenvironment.yml
should read:name: airplane
- (optional) If the environment will be recreated in a different platform, you will likely want to leave only the actual packages that were explicitly installed together with their version number, so that the receiving system is left to handle dependencies (which can be platform-dependent). You can look at the result of
conda env export --from-history
to see the baseline packages that were explicitly installed, and then edit the file
environment.yml
to remove anything that is a dependency.
For our basecamp environment, the resultingenvironment.yml
file will contain
- Finally, distribute the entire
airplane
folder (or copy it to a new machine for yourself) and there docd airplane conda env create --file environment.yml