{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "8ebbd194-14bb-498e-932b-2daacf94a1f6",
   "metadata": {},
   "source": [
    "# Virtual Environment\n",
    "\n",
    "We want to create a project directory for your project and a Python virtual environment within that directory for managing Python and all installed package files."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "13785857",
   "metadata": {},
   "source": [
    "## Creating Project Directory\n",
    "In general, when we create a project, it means we are creating a folder/directory. To use a project directory, we use the command line interface (CLI) of your OS. Since they are CLI rather than a graphical user interface (GUI), we need to use commands to create folders and navigate the paths. Although this can be done with a GUI file manager, knowing how to use the CLI is a good skill set to have in the long run. The three shell commands that we use here are: \n",
    "- `ls` (\"list storage\"),\n",
    "- `mkdir` (\"make directory\"), and\n",
    "- `cd` (\"change directory\").\n",
    "\n",
    "For the purpose of clarity, we want to create a `workspace` directory within your user's home directory, and a `py` directory within the `workspace` directory. \n",
    "\n",
    "Note that macOS and Linux use forward slashes for directory separators, while Windows uses backward slashes as separators (Windows can also interpret forward slashes).\n",
    "\n",
    "````{tab-set} \n",
    "```{tab-item} Windows\n",
    "\n",
    "We use `PowerShell` instead of `Command Prompt` as our CLI here because the syntax is more friendly. \n",
    "\n",
    "```powershell\n",
    "PS C:\\Users\\[user]> mkdir workspace\n",
    "    Directory: C:\\Users\\[user]\n",
    "Mode                 LastWriteTime         Length Name\n",
    "----                 -------------         ------ ----\n",
    "d-----         8/31/2025   3:14 AM                workspace\n",
    "\n",
    "PS C:\\Users\\[user]> cd workspace\n",
    "PS C:\\Users\\[user]\\workspace> mkdir py\n",
    "    Directory: C:\\Users\\[user]\\workspace\n",
    "Mode                 LastWriteTime         Length Name\n",
    "----                 -------------         ------ ----\n",
    "d-----         8/31/2025   3:14 AM                py\n",
    "\n",
    "PS C:\\Users\\[user]\\workspace> cd py\n",
    "PS C:\\Users\\[user]\\workspace\\py> \n",
    "```\n",
    "\n",
    "```{tab-item} macOS\n",
    "\n",
    "Use `Terminal.app` as CLI here for this task.\n",
    "\n",
    "```bash\n",
    "[user]@[host]ː~$ mkdir workspace\n",
    "[user]@[host]ː~$ cd workspace\n",
    "[user]@[host]ː~/workspace$ mkdir py\n",
    "[user]@[host]ː~/workspace$ cd py/\n",
    "[user]@[host]ː~/workspace/py$ \n",
    "```\n",
    "````\n",
    "\n",
    "After issuing the above commands, you will have a project directory (**py**) inside the workspace directory, and your current location is inside the **py** project directory. \n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "35a281b2",
   "metadata": {},
   "source": [
    "## Creating Virtual Environment\n",
    "\n",
    "In the **py** project directory, we will create a Python virtual environment for the project. This means that we will place all installed packages (**dependencies**) that we use in the `site-packages` directory of the virtual environment rather than installing them in the system Python, which is prone to conflicts when different versions of software packages are installed or upgraded. \n",
    "\n",
    "On the other hand, installing the packages in the project virtual environment also means that we are making this environment portable, meaning we can replicate the dependencies in another project or device. Note that, in addition to the installed project, the virtual environment also contains a link to the desired Python version. \n",
    "\n",
    "To create the virtual environment for the project, we issue the command as `python -m venv .venv`, in which `python` is the default desired version of Python, `-m` means module, `venv` is the module that creates virtual environment, and `.venv`, as a convention, is the name of the project virtual environment. \n",
    "\n",
    "The syntax for creating a Python virtual environment is:\n",
    "\n",
    "```bash\n",
    "python -m venv <environment_path_and_name>\n",
    "```\n",
    "\n",
    "Since we want to control which version of Python to use (3.12 in this case), we will use the version suffix by issuing `py -3.12 -m venv .venv` (Windows) or `python3.12 -m venv .venv` (macOS) to specify the Python version to use (which may be different from the system default Python version): \n",
    "\n",
    "````{tab-set}\n",
    "```{tab-item} Windows\n",
    "\n",
    "We use `PowerShell` here because the syntax is more friendly. \n",
    "\n",
    "```bash\n",
    "PS C:\\Users\\[user]\\workspace\\py> py -3.12 -m venv .venv\n",
    "PS C:\\Users\\[user]\\workspace\\py> ls\n",
    "    Directory: C:\\Users\\[user]\\workspace\\py\n",
    "Mode                 LastWriteTime         Length Name\n",
    "----                 -------------         ------ ----\n",
    "d-----         8/31/2025   3:36 AM                .venv\n",
    "```\n",
    "\n",
    "```{tab-item} macOS\n",
    "\n",
    "Use Terminal.app for this task.\n",
    "\n",
    "```bash\n",
    "[user]@[host]ː~/workspace/py$ python3.12 -m venv .venv\n",
    "[user]@[host]ː~/workspace/py$ ls -a\n",
    ".     ..    .venv\n",
    "[user]@[host]ː~/workspace/py$ \n",
    "```\n",
    "````\n",
    "\n",
    "Using the `ls` command, we see that the virtual environment **.venv** folder has been created. \n",
    "\n",
    "````{tab-set}\n",
    "```{tab-item} Windows\n",
    "\n",
    "Make sure you are using `PowerShell` as your CLI here. If you are using Command Prompt, issue `dir` instead of `ls` to list files. \n",
    "\n",
    "```bash\n",
    "PS C:\\Users\\[user]\\workspace\\py> ls\n",
    "    Directory: C:\\Users\\[user]\\workspace\\py\n",
    "Mode                 LastWriteTime         Length Name\n",
    "----                 -------------         ------ ----\n",
    "d-----          9/4/2025   9:41 PM                .ipynb_checkpoints\n",
    "d-----          9/4/2025   9:41 PM                .venv\n",
    "```\n",
    "\n",
    "```{tab-item} macOS\n",
    "\n",
    "In macOS, using `ls` you will not see the **.venv** folder because file and directory names beginning with a dot are hidden. To see the .venv virtual environment in macOS, add the `-a` option to the `ls` command: `$ ls -a`.\n",
    "\n",
    "```bash\n",
    "[user]@[host]ː~/workspace/py$ ls -a\n",
    ".                       .venv                   labs                    test.ipynb\n",
    "..                      assignments_grading     NumPy                   test.py\n",
    ".DS_Store               data                    numpy_arrays.ipynb      \n",
    "```\n",
    "````\n",
    "\n",
    "Inside the .venv virtual environment directory, there is a lib/Lib directory containing a folder called **site-packages**, where all packages are installed. Additionally, all binary codes, including links to Python executables, the venv activation scripts, pip, and other program executables, are installed in the **bin** (macOS) or **Scripts** (Windows) folder. \n",
    "\n",
    "````{tab-set}\n",
    "```{tab-item} Windows\n",
    "\n",
    "In Windows, the site-packages directory appears as follows. So far, we only have *pip*, but every package you install will have a folder here, and soon the list will be long.\n",
    "\n",
    "```bash\n",
    "PS C:\\Users\\[user]\\workspace\\py> ls .venv\\lib\\site-packages\\\n",
    "    Directory: C:\\Users\\[user]\\workspace\\py\\.venv\\Lib\\site-packages\n",
    "Mode                 LastWriteTime         Length Name\n",
    "----                 -------------         ------ ----\n",
    "d-----         8/31/2025   3:36 AM                pip\n",
    "d-----         8/31/2025   3:36 AM                pip-24.0.dist-info\n",
    "```\n",
    "\n",
    "```{tab-item} macOS\n",
    "\n",
    "In macOS, the site-packages folder looks like below. So far we only have *pip* but every package you install will come here and soon the list will be long.\n",
    "\n",
    "```bash\n",
    "[user]@[host]ː~/workspace/py$ ls .venv/lib/python3.12/site-packages/\n",
    "pip                pip-24.0.dist-info\n",
    "```\n",
    "````"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4009ade5-0dea-496d-9a51-30255cac532f",
   "metadata": {},
   "source": [
    "## Activating/Deactivating venv\n",
    "\n",
    "To **activate** your virtual environment, in the CLI, make sure you are in the project directory (**py**) and type the following command to activate the project virtual environment. After the virtual environment is activated, a prefix (\"(**.venv**)\") will be present in front of the CLI prompt. \n",
    "\n",
    "::::{tab-set}\n",
    ":::{tab-item} Windows\n",
    "```powershell\n",
    "PS C:\\Users\\[user]\\workspace\\py> .\\.venv\\Scripts\\activate\n",
    "(.venv) PS C:\\Users\\[user]\\workspace\\py>                 \n",
    "```\n",
    "\n",
    "When attempting to activate the virtual environment, Windows users may encounter a PowerShell security policy error. The error message for Windows looks like below:\n",
    "\n",
    "```{figure} ../../images/venv-activate-error-windows.png\n",
    ":name: venv-activate-error-windows\n",
    ":alt: venv-activate-error-windows\n",
    ":width: 80%\n",
    "\n",
    "venv Activation Error for Windows\n",
    "```\n",
    "\n",
    "If it happens, issue the command as below in PowerShell (\"Run as administrator\" is needed if you don't say -Scope CurrentUser), exit all PowerShell tabs and windows, and restart PowerShell before you activate your virtual environment:\n",
    "\n",
    "```powershell\n",
    "Set-ExecutionPolicy RemoteSigned -Scope CurrentUser\n",
    "```\n",
    ":::\n",
    "\n",
    ":::{tab-item} macOS\n",
    "```bash   \n",
    "[user]@[host]ː~/workspace/py$ source .venv/bin/activate\n",
    "(.venv) [user]@[host]ː~/workspace/py$   \n",
    "```\n",
    ":::\n",
    "::::\n",
    "\n",
    "\n",
    "\n",
    "When the virtual environment is successfully activated, you will see **<span style=\" color: green;\">(.venv)</span>** appears before the shell's prompt line, which tells us the virtual environment is activated, we are using the designated version of Python, and that all the packages installation will go into the `site-packages` directory. \n",
    "\n",
    "Note that, after you are done working on the project, you need to **deactivate** the virtual environment to prevent the installation of dependencies intended for other projects into this virtual environment. To do that, use the `deactivate` command (you can deactivate a virtual environment anywhere; it does not have to be in the project folder):\n",
    "\n",
    "::::{tab-set}\n",
    ":::{tab-item} Windows\n",
    "```bash\n",
    "(.venv) PS C:\\Users\\[user]\\workspace\\py> deactivate\n",
    "PS C:\\Users\\[user]\\workspace\\py>\n",
    "```\n",
    ":::\n",
    "\n",
    ":::{tab-item} macOS\n",
    "```bash\n",
    "(.venv) [user]@[host]:~/workspace/py$ deactivate \n",
    "[user]@[host]:~/workspace/py$ \n",
    "```\n",
    ":::\n",
    "::::"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f36783b4-2a5f-481b-87d7-6d3a0d695e86",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "jupytext": {
   "cell_metadata_filter": "-all"
  },
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.13.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
