├── .github └── pull_request_template.md ├── LICENSE ├── README.md ├── commons ├── .gitkeep ├── copy-data-from-s3.sh └── install-python-packages.sh ├── init-script.png ├── inputs ├── .gitignore ├── DESCRIPTION ├── examples.Rproj ├── renv.lock ├── report.qmd ├── requirements.txt └── tutorial.ipynb ├── jupyter ├── .gitkeep └── open-notebook.sh ├── rstudio ├── .gitkeep ├── customize-settings-r.sh ├── customize-settings-rstudio.sh ├── install-packages.sh ├── open-file.sh ├── open-rproj-using-args.sh └── open-rproj.sh └── vscode ├── .gitkeep ├── customize-settings.sh ├── customize-shortcuts.sh ├── install-extensions-from-script-args.sh └── install-extensions.sh /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | 4 | 5 | ## Description of the change 6 | 7 | 12 | 13 | ## Checklist 14 | 15 | - [ ] I respected the template displayed in the contributing sequence of the README 16 | - [ ] I made sure the header of the script describes what the it does 17 | - [ ] I precised parameters if needed 18 | - [ ] I commented my code where necessary 19 | 20 | ## Additional Notes 21 | 22 | 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 InseeFrLab 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Initialization Scripts for Interactive Services 2 | 3 | Welcome to the Initialization Scripts Repository for the Onyxia platform! This repository provides example scripts that can be used to configure and initialize various [interactive services](https://github.com/InseeFrLab/helm-charts-interactive-services), such as RStudio, VSCode, or Jupyter Notebooks, when they are launched on the [Onyxia](https://www.onyxia.sh/) platforms. 4 | 5 | ## How to use 6 | 1. Make sure the repository containing your initialization script is public 7 | 8 | 2. Get the [raw url](https://docs.github.com/en/repositories/working-with-files/using-files/viewing-a-file#viewing-or-copying-the-raw-file-content) of the script you want to initialize your service with or, preferably, create your own initialization script inspired by this repository. 9 | 10 | 3. When launching your service on the platform, configure your service. Go to the Init tab and fill in the url of your script. 11 | 12 | ![You should provide the url in the user initialization script box ](init-script.png) 13 | 14 | 4. You may want to save your configuration to find it later and avoid these steps. 15 | 16 | 5. Launch your service and enjoy 17 | 18 | ## Contributing 19 | 20 | Contributions are welcome, feel free to submit pull requests 😊 21 | Please, make sure the code is well documented and respect the following template: 22 | 23 | ``` 24 | #!/bin/sh 25 | 26 | # This init script is used for .... 27 | # Expected parameters : 28 | # Indicate None if parameters are not needed, else : 29 | # - parameter1 : brief description 30 | # - parameter2 : brief description 31 | 32 | 33 | ``` 34 | 35 | ## Contact 36 | 37 | For questions or support, please open an issue in this repository or contact the maintainers. 38 | -------------------------------------------------------------------------------- /commons/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /commons/copy-data-from-s3.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This init script shows how to (recursively) import data from MinIO to the service local storage 4 | # using the mc client 5 | # Expected parameters : None 6 | 7 | # Bucket : `donnees-insee` 8 | # Remote directory which content we want to fetch : `diffusion/GEOGRAPHIE/2019 data` 9 | # Local directory (created if it doesn't exist) : `data` 10 | mc cp -r s3/donnees-insee/diffusion/GEOGRAPHIE/2019 data/ 11 | -------------------------------------------------------------------------------- /commons/install-python-packages.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This init script presents various ways of installing Python packages 4 | # Works for both JupyterLab and VSCode services 5 | # Expected parameters : None 6 | 7 | # Clone repository and give permissions to the onyxia user 8 | GIT_REPO=sspcloud-init-scripts 9 | git clone --depth 1 https://github.com/InseeFrLab/${GIT_REPO}.git 10 | chown -R onyxia:users ${GIT_REPO}/ 11 | 12 | # Install Python packages using `pip` 13 | pip install matplotlib plotly 14 | 15 | # Install Python packages using `pip` and a `requirements.txt` file 16 | pip install -r ${GIT_REPO}/inputs/requirements.txt 17 | 18 | # Install Python packages using `conda` 19 | conda install requests scipy 20 | -------------------------------------------------------------------------------- /init-script.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/InseeFrLab/sspcloud-init-scripts/HEAD/init-script.png -------------------------------------------------------------------------------- /inputs/.gitignore: -------------------------------------------------------------------------------- 1 | /.quarto/ 2 | -------------------------------------------------------------------------------- /inputs/DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: templateProjetMutualise 2 | Title: Template de projet mutualisé 3 | Version: 0.0.0.9000 4 | Authors@R: 5 | person("First", "Last", , "first.last@example.com", role = c("aut", "cre"), 6 | comment = c(ORCID = "YOUR-ORCID-ID")) 7 | Description: Un template de projet mutualisé basé sur un package R. 8 | License: MIT + file LICENSE 9 | Encoding: UTF-8 10 | Roxygen: list(markdown = TRUE) 11 | RoxygenNote: 7.2.3 12 | Imports: 13 | dplyr, 14 | magrittr, 15 | readr 16 | -------------------------------------------------------------------------------- /inputs/examples.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: Default 4 | SaveWorkspace: Default 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: Sweave 13 | LaTeX: pdfLaTeX -------------------------------------------------------------------------------- /inputs/renv.lock: -------------------------------------------------------------------------------- 1 | { 2 | "R": { 3 | "Version": "4.4.1", 4 | "Repositories": [ 5 | { 6 | "Name": "CRAN", 7 | "URL": "https://packagemanager.posit.co/cran/latest" 8 | } 9 | ] 10 | }, 11 | "Packages": { 12 | "R6": { 13 | "Package": "R6", 14 | "Version": "2.5.1", 15 | "Source": "Repository", 16 | "Repository": "CRAN", 17 | "Requirements": [ 18 | "R" 19 | ], 20 | "Hash": "470851b6d5d0ac559e9d01bb352b4021" 21 | }, 22 | "base64enc": { 23 | "Package": "base64enc", 24 | "Version": "0.1-3", 25 | "Source": "Repository", 26 | "Repository": "CRAN", 27 | "Requirements": [ 28 | "R" 29 | ], 30 | "Hash": "543776ae6848fde2f48ff3816d0628bc" 31 | }, 32 | "bslib": { 33 | "Package": "bslib", 34 | "Version": "0.8.0", 35 | "Source": "Repository", 36 | "Repository": "CRAN", 37 | "Requirements": [ 38 | "R", 39 | "base64enc", 40 | "cachem", 41 | "fastmap", 42 | "grDevices", 43 | "htmltools", 44 | "jquerylib", 45 | "jsonlite", 46 | "lifecycle", 47 | "memoise", 48 | "mime", 49 | "rlang", 50 | "sass" 51 | ], 52 | "Hash": "b299c6741ca9746fb227debcb0f9fb6c" 53 | }, 54 | "cachem": { 55 | "Package": "cachem", 56 | "Version": "1.1.0", 57 | "Source": "Repository", 58 | "Repository": "CRAN", 59 | "Requirements": [ 60 | "fastmap", 61 | "rlang" 62 | ], 63 | "Hash": "cd9a672193789068eb5a2aad65a0dedf" 64 | }, 65 | "cli": { 66 | "Package": "cli", 67 | "Version": "3.6.3", 68 | "Source": "Repository", 69 | "Repository": "CRAN", 70 | "Requirements": [ 71 | "R", 72 | "utils" 73 | ], 74 | "Hash": "b21916dd77a27642b447374a5d30ecf3" 75 | }, 76 | "digest": { 77 | "Package": "digest", 78 | "Version": "0.6.37", 79 | "Source": "Repository", 80 | "Repository": "CRAN", 81 | "Requirements": [ 82 | "R", 83 | "utils" 84 | ], 85 | "Hash": "33698c4b3127fc9f506654607fb73676" 86 | }, 87 | "evaluate": { 88 | "Package": "evaluate", 89 | "Version": "1.0.0", 90 | "Source": "Repository", 91 | "Repository": "CRAN", 92 | "Requirements": [ 93 | "R" 94 | ], 95 | "Hash": "6b567375113ceb7d9f800de4dd42218e" 96 | }, 97 | "fastmap": { 98 | "Package": "fastmap", 99 | "Version": "1.2.0", 100 | "Source": "Repository", 101 | "Repository": "CRAN", 102 | "Hash": "aa5e1cd11c2d15497494c5292d7ffcc8" 103 | }, 104 | "fontawesome": { 105 | "Package": "fontawesome", 106 | "Version": "0.5.2", 107 | "Source": "Repository", 108 | "Repository": "CRAN", 109 | "Requirements": [ 110 | "R", 111 | "htmltools", 112 | "rlang" 113 | ], 114 | "Hash": "c2efdd5f0bcd1ea861c2d4e2a883a67d" 115 | }, 116 | "fs": { 117 | "Package": "fs", 118 | "Version": "1.6.4", 119 | "Source": "Repository", 120 | "Repository": "CRAN", 121 | "Requirements": [ 122 | "R", 123 | "methods" 124 | ], 125 | "Hash": "15aeb8c27f5ea5161f9f6a641fafd93a" 126 | }, 127 | "glue": { 128 | "Package": "glue", 129 | "Version": "1.7.0", 130 | "Source": "Repository", 131 | "Repository": "CRAN", 132 | "Requirements": [ 133 | "R", 134 | "methods" 135 | ], 136 | "Hash": "e0b3a53876554bd45879e596cdb10a52" 137 | }, 138 | "highr": { 139 | "Package": "highr", 140 | "Version": "0.11", 141 | "Source": "Repository", 142 | "Repository": "CRAN", 143 | "Requirements": [ 144 | "R", 145 | "xfun" 146 | ], 147 | "Hash": "d65ba49117ca223614f71b60d85b8ab7" 148 | }, 149 | "htmltools": { 150 | "Package": "htmltools", 151 | "Version": "0.5.8.1", 152 | "Source": "Repository", 153 | "Repository": "CRAN", 154 | "Requirements": [ 155 | "R", 156 | "base64enc", 157 | "digest", 158 | "fastmap", 159 | "grDevices", 160 | "rlang", 161 | "utils" 162 | ], 163 | "Hash": "81d371a9cc60640e74e4ab6ac46dcedc" 164 | }, 165 | "jquerylib": { 166 | "Package": "jquerylib", 167 | "Version": "0.1.4", 168 | "Source": "Repository", 169 | "Repository": "CRAN", 170 | "Requirements": [ 171 | "htmltools" 172 | ], 173 | "Hash": "5aab57a3bd297eee1c1d862735972182" 174 | }, 175 | "jsonlite": { 176 | "Package": "jsonlite", 177 | "Version": "1.8.9", 178 | "Source": "Repository", 179 | "Repository": "CRAN", 180 | "Requirements": [ 181 | "methods" 182 | ], 183 | "Hash": "4e993b65c2c3ffbffce7bb3e2c6f832b" 184 | }, 185 | "knitr": { 186 | "Package": "knitr", 187 | "Version": "1.48", 188 | "Source": "Repository", 189 | "Repository": "CRAN", 190 | "Requirements": [ 191 | "R", 192 | "evaluate", 193 | "highr", 194 | "methods", 195 | "tools", 196 | "xfun", 197 | "yaml" 198 | ], 199 | "Hash": "acf380f300c721da9fde7df115a5f86f" 200 | }, 201 | "lifecycle": { 202 | "Package": "lifecycle", 203 | "Version": "1.0.4", 204 | "Source": "Repository", 205 | "Repository": "CRAN", 206 | "Requirements": [ 207 | "R", 208 | "cli", 209 | "glue", 210 | "rlang" 211 | ], 212 | "Hash": "b8552d117e1b808b09a832f589b79035" 213 | }, 214 | "memoise": { 215 | "Package": "memoise", 216 | "Version": "2.0.1", 217 | "Source": "Repository", 218 | "Repository": "CRAN", 219 | "Requirements": [ 220 | "cachem", 221 | "rlang" 222 | ], 223 | "Hash": "e2817ccf4a065c5d9d7f2cfbe7c1d78c" 224 | }, 225 | "mime": { 226 | "Package": "mime", 227 | "Version": "0.12", 228 | "Source": "Repository", 229 | "Repository": "CRAN", 230 | "Requirements": [ 231 | "tools" 232 | ], 233 | "Hash": "18e9c28c1d3ca1560ce30658b22ce104" 234 | }, 235 | "rappdirs": { 236 | "Package": "rappdirs", 237 | "Version": "0.3.3", 238 | "Source": "Repository", 239 | "Repository": "CRAN", 240 | "Requirements": [ 241 | "R" 242 | ], 243 | "Hash": "5e3c5dc0b071b21fa128676560dbe94d" 244 | }, 245 | "renv": { 246 | "Package": "renv", 247 | "Version": "1.0.8", 248 | "Source": "Repository", 249 | "Repository": "RSPM", 250 | "Requirements": [ 251 | "utils" 252 | ], 253 | "Hash": "e082251834fa427514e68bec8afc8fda" 254 | }, 255 | "rlang": { 256 | "Package": "rlang", 257 | "Version": "1.1.4", 258 | "Source": "Repository", 259 | "Repository": "CRAN", 260 | "Requirements": [ 261 | "R", 262 | "utils" 263 | ], 264 | "Hash": "3eec01f8b1dee337674b2e34ab1f9bc1" 265 | }, 266 | "rmarkdown": { 267 | "Package": "rmarkdown", 268 | "Version": "2.28", 269 | "Source": "Repository", 270 | "Repository": "CRAN", 271 | "Requirements": [ 272 | "R", 273 | "bslib", 274 | "evaluate", 275 | "fontawesome", 276 | "htmltools", 277 | "jquerylib", 278 | "jsonlite", 279 | "knitr", 280 | "methods", 281 | "tinytex", 282 | "tools", 283 | "utils", 284 | "xfun", 285 | "yaml" 286 | ], 287 | "Hash": "062470668513dcda416927085ee9bdc7" 288 | }, 289 | "sass": { 290 | "Package": "sass", 291 | "Version": "0.4.9", 292 | "Source": "Repository", 293 | "Repository": "CRAN", 294 | "Requirements": [ 295 | "R6", 296 | "fs", 297 | "htmltools", 298 | "rappdirs", 299 | "rlang" 300 | ], 301 | "Hash": "d53dbfddf695303ea4ad66f86e99b95d" 302 | }, 303 | "tinytex": { 304 | "Package": "tinytex", 305 | "Version": "0.53", 306 | "Source": "Repository", 307 | "Repository": "CRAN", 308 | "Requirements": [ 309 | "xfun" 310 | ], 311 | "Hash": "9db859e8aabbb474293dde3097839420" 312 | }, 313 | "xfun": { 314 | "Package": "xfun", 315 | "Version": "0.47", 316 | "Source": "Repository", 317 | "Repository": "CRAN", 318 | "Requirements": [ 319 | "R", 320 | "grDevices", 321 | "stats", 322 | "tools" 323 | ], 324 | "Hash": "36ab21660e2d095fef0d83f689e0477c" 325 | }, 326 | "yaml": { 327 | "Package": "yaml", 328 | "Version": "2.3.10", 329 | "Source": "Repository", 330 | "Repository": "CRAN", 331 | "Hash": "51dab85c6c98e50a18d7551e9d49f76c" 332 | } 333 | } 334 | } 335 | -------------------------------------------------------------------------------- /inputs/report.qmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Simple Example" 3 | author: "Your Name" 4 | date: "`r Sys.Date()`" 5 | output: 6 | html_document: 7 | df_print: paged 8 | --- 9 | 10 | ```{r setup, include=FALSE} 11 | # Load necessary libraries 12 | library(ggplot2) 13 | ``` 14 | 15 | ## Introduction 16 | 17 | This is a simple example using the built-in `mtcars` dataset in R. We will perform basic operations on the dataset and create a plot with `ggplot2`. 18 | 19 | ## Basic Operations 20 | 21 | Let's start by taking a quick look at the `mtcars` dataset. 22 | 23 | ```{r} 24 | # Print the first few rows of the dataset 25 | head(mtcars) 26 | ``` 27 | 28 | Now let's perform a basic summary of the dataset. 29 | 30 | ```{r} 31 | # Summary statistics of the dataset 32 | summary(mtcars) 33 | ``` 34 | 35 | ## Creating a Simple Plot 36 | 37 | We will now create a scatter plot using the `mpg` (miles per gallon) and `hp` (horsepower) variables from the `mtcars` dataset. 38 | 39 | ```{r} 40 | # Create a scatter plot of mpg vs hp 41 | ggplot(mtcars, aes(x = hp, y = mpg)) + 42 | geom_point() + 43 | labs(title = "Scatter Plot of Horsepower vs. MPG", 44 | x = "Horsepower", 45 | y = "Miles Per Gallon (MPG)") + 46 | theme_minimal() 47 | ``` 48 | -------------------------------------------------------------------------------- /inputs/requirements.txt: -------------------------------------------------------------------------------- 1 | numpy 2 | pandas -------------------------------------------------------------------------------- /inputs/tutorial.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Structures de données 1 : listes et tuples\n", 8 | "\n", 9 | "Dans ce tutoriel, nous allons nous intéresser à des structures de\n", 10 | "données de base en Python : les **listes** et les **tuples**. Les\n", 11 | "structures de données peuvent être vues comme des conteneurs car ils\n", 12 | "permettent de stocker, d’organiser et d’accéder à des données. Les\n", 13 | "listes et les tuples sont des **conteneurs séquentiels** : les éléments\n", 14 | "qu’ils contiennent sont **ordonnés**, et leur position est enregistrée\n", 15 | "dans un **index**.\n", 16 | "\n", 17 | "## Listes\n", 18 | "\n", 19 | "### Définition\n", 20 | "\n", 21 | "Dans le tutoriel précédent, nous avons vu que les chaînes de caractères\n", 22 | "étaient des **séquences** de caractères. Les listes sont également des\n", 23 | "séquences, c’est à dire des suites ordonnées d’éléments, mais plus\n", 24 | "générales : les éléments peuvent être de différente nature.\n", 25 | "\n", 26 | "Les listes sont construites avec des crochets **\\[\\]**, et les éléments\n", 27 | "de la liste sont séparés par des virgules.\n", 28 | "\n", 29 | "Assignons une première liste à une variable `a` :" 30 | ], 31 | "id": "ffbb7c3e-4fe4-4416-86ba-058d358e3e00" 32 | }, 33 | { 34 | "cell_type": "code", 35 | "execution_count": null, 36 | "metadata": {}, 37 | "outputs": [], 38 | "source": [ 39 | "a = [1, 2, 3]\n", 40 | "print(a)" 41 | ], 42 | "id": "45b8fe15" 43 | }, 44 | { 45 | "cell_type": "markdown", 46 | "metadata": {}, 47 | "source": [ 48 | "La liste `a` est constituée d’entiers, mais une liste peut en pratique\n", 49 | "contenir des objets de tout type." 50 | ], 51 | "id": "4ee50707-9161-47d7-8ef5-92a7b67e87a4" 52 | }, 53 | { 54 | "cell_type": "code", 55 | "execution_count": null, 56 | "metadata": {}, 57 | "outputs": [], 58 | "source": [ 59 | "b = [\"une séquence\", 56, \"d\"]\n", 60 | "print(b)" 61 | ], 62 | "id": "47f0a9e9" 63 | }, 64 | { 65 | "cell_type": "markdown", 66 | "metadata": {}, 67 | "source": [ 68 | "Il est notamment possible de créer des listes de listes (et ainsi de\n", 69 | "suite), ce qui permet de créer des structures hiérarchiques de données." 70 | ], 71 | "id": "4be9e91d-795c-4932-83c1-a07dfaa8b175" 72 | }, 73 | { 74 | "cell_type": "code", 75 | "execution_count": null, 76 | "metadata": {}, 77 | "outputs": [], 78 | "source": [ 79 | "c = [\"une séquence\", 56, [\"cette liste est imbriquée\", 75, \"o\"]]\n", 80 | "print(c)" 81 | ], 82 | "id": "f3e09292" 83 | }, 84 | { 85 | "cell_type": "markdown", 86 | "metadata": {}, 87 | "source": [ 88 | "Une liste imbriquée peut aussi être construite à partir de listes déjà\n", 89 | "définies." 90 | ], 91 | "id": "7849b019-2687-40ce-9c6e-4b1f7c33afe8" 92 | }, 93 | { 94 | "cell_type": "code", 95 | "execution_count": null, 96 | "metadata": {}, 97 | "outputs": [], 98 | "source": [ 99 | "item1 = [\"cafe\", \"500g\"]\n", 100 | "item2 = [\"biscuits\", \"20\"]\n", 101 | "item3 = [\"lait\", \"1L\"]\n", 102 | "inventaire = [item1, item2, item3]\n", 103 | "print(inventaire)" 104 | ], 105 | "id": "5ac2e427" 106 | }, 107 | { 108 | "cell_type": "markdown", 109 | "metadata": {}, 110 | "source": [ 111 | "On verra cependant dans le prochain tutoriel que les dictionnaires sont\n", 112 | "généralement des structures de données souvent plus adaptées que les\n", 113 | "listes pour représenter des données sous forme hiérarchique.\n", 114 | "\n", 115 | "### Longueur d’une liste\n", 116 | "\n", 117 | "Comme les chaînes de caractères, il est possible d’utiliser la fonction\n", 118 | "`len` pour compter le nombre d’éléments présents dans une liste." 119 | ], 120 | "id": "17955052-e49c-4481-9b4b-ebf1db0d932a" 121 | }, 122 | { 123 | "cell_type": "code", 124 | "execution_count": null, 125 | "metadata": {}, 126 | "outputs": [], 127 | "source": [ 128 | "d = [\"ceci\", \"est\", \"une\", \"liste\"]\n", 129 | "len(d)" 130 | ], 131 | "id": "975e9d14" 132 | }, 133 | { 134 | "cell_type": "markdown", 135 | "metadata": {}, 136 | "source": [ 137 | "### Indexation\n", 138 | "\n", 139 | "Les listes étant des séquences, elles s’indexent de la même manière que\n", 140 | "les chaînes de caractères. Il est notamment important de se rappeler que\n", 141 | "la numérotation des positions commence à 0 en Python." 142 | ], 143 | "id": "e413c558-8a4c-48aa-b765-7da27668054c" 144 | }, 145 | { 146 | "cell_type": "code", 147 | "execution_count": null, 148 | "metadata": {}, 149 | "outputs": [], 150 | "source": [ 151 | "# Troisième élément de la liste a\n", 152 | "print(a[2])" 153 | ], 154 | "id": "fbe0aebe" 155 | }, 156 | { 157 | "cell_type": "markdown", 158 | "metadata": {}, 159 | "source": [ 160 | "Bien entendu, il n’est pas possible de demander un élément qui n’existe\n", 161 | "pas. Python renvoie une erreur nous indiquant que l’index demandé est\n", 162 | "hors limites." 163 | ], 164 | "id": "692ac62e-2d85-40f4-956c-2a9b2d81344e" 165 | }, 166 | { 167 | "cell_type": "code", 168 | "execution_count": null, 169 | "metadata": {}, 170 | "outputs": [], 171 | "source": [ 172 | "print(a[5])" 173 | ], 174 | "id": "9f85490c" 175 | }, 176 | { 177 | "cell_type": "markdown", 178 | "metadata": {}, 179 | "source": [ 180 | "Pour indexer une liste contenue dans une autre liste, on utilise une\n", 181 | "double indexation." 182 | ], 183 | "id": "537926ca-2fdd-4972-b1f5-4ae7aaf246c7" 184 | }, 185 | { 186 | "cell_type": "code", 187 | "execution_count": null, 188 | "metadata": {}, 189 | "outputs": [], 190 | "source": [ 191 | "# Premier élément de la sous-liste qui est à la deuxième position de la liste c\n", 192 | "print(c[2][0])" 193 | ], 194 | "id": "06fd3065" 195 | }, 196 | { 197 | "cell_type": "markdown", 198 | "metadata": {}, 199 | "source": [ 200 | "En termes d’indexation, tout ce qui était possible sur les chaînes\n", 201 | "caractères l’est également avec les listes." 202 | ], 203 | "id": "788fb467-b929-42fa-9d42-f73a81e17bdb" 204 | }, 205 | { 206 | "cell_type": "code", 207 | "execution_count": null, 208 | "metadata": {}, 209 | "outputs": [], 210 | "source": [ 211 | "# Tous les éléments à partir de la 1ère position\n", 212 | "print(b[1:])" 213 | ], 214 | "id": "c20fca20" 215 | }, 216 | { 217 | "cell_type": "code", 218 | "execution_count": null, 219 | "metadata": {}, 220 | "outputs": [], 221 | "source": [ 222 | "# Inverser une liste\n", 223 | "print(a[::-1])" 224 | ], 225 | "id": "7d4f6539" 226 | }, 227 | { 228 | "cell_type": "markdown", 229 | "metadata": {}, 230 | "source": [ 231 | "### Modification d’éléments\n", 232 | "\n", 233 | "Il est possible de modifier les éléments d’une liste manuellement, avec\n", 234 | "une syntaxe similaire à l’assignation de variable." 235 | ], 236 | "id": "e59a4d0f-ad87-40f1-b8f3-80a1e504615d" 237 | }, 238 | { 239 | "cell_type": "code", 240 | "execution_count": null, 241 | "metadata": {}, 242 | "outputs": [], 243 | "source": [ 244 | "# Réassignation d'un élément\n", 245 | "d = [1, 2, \"toto\", 4]\n", 246 | "d[2] = 3\n", 247 | "print(d)" 248 | ], 249 | "id": "05da67d8" 250 | }, 251 | { 252 | "cell_type": "code", 253 | "execution_count": null, 254 | "metadata": {}, 255 | "outputs": [], 256 | "source": [ 257 | "# Substitution d'un élément\n", 258 | "a = [1, 2, 3]\n", 259 | "b = [\"do\", \"re\", \"mi\"]\n", 260 | "b[0] = a[2]\n", 261 | "print(b)" 262 | ], 263 | "id": "96903692" 264 | }, 265 | { 266 | "cell_type": "markdown", 267 | "metadata": {}, 268 | "source": [ 269 | "### Suppression d’éléments\n", 270 | "\n", 271 | "L’instruction `del` permet de supprimer un élément par position. Les\n", 272 | "éléments qui se trouvaient après l’élément supprimé voient donc leur\n", 273 | "index réduit de 1." 274 | ], 275 | "id": "f4c0b3a0-ec28-4060-89dd-14fa95bca1da" 276 | }, 277 | { 278 | "cell_type": "code", 279 | "execution_count": null, 280 | "metadata": {}, 281 | "outputs": [], 282 | "source": [ 283 | "e = [1, \"do\", 6]\n", 284 | "print(e)\n", 285 | "print(e[2])\n", 286 | "\n", 287 | "del e[1]\n", 288 | "print(e)\n", 289 | "print(e[1])" 290 | ], 291 | "id": "cf44feed" 292 | }, 293 | { 294 | "cell_type": "markdown", 295 | "metadata": {}, 296 | "source": [ 297 | "### Quelques propriétés utiles\n", 298 | "\n", 299 | "Là encore, on retrouve des propriétés inhérentes aux séquences." 300 | ], 301 | "id": "b0b827e8-c65f-4ed0-aca9-a86ccfb16c4d" 302 | }, 303 | { 304 | "cell_type": "code", 305 | "execution_count": null, 306 | "metadata": {}, 307 | "outputs": [], 308 | "source": [ 309 | "# Concaténation\n", 310 | "[1, 2, 3] + [\"a\", 12]" 311 | ], 312 | "id": "27ca8b21" 313 | }, 314 | { 315 | "cell_type": "code", 316 | "execution_count": null, 317 | "metadata": {}, 318 | "outputs": [], 319 | "source": [ 320 | "# Réplication\n", 321 | "[\"a\", \"b\", \"c\"] * 3" 322 | ], 323 | "id": "9c135216" 324 | }, 325 | { 326 | "cell_type": "markdown", 327 | "metadata": {}, 328 | "source": [ 329 | "### Quelques méthodes utiles\n", 330 | "\n", 331 | "A l’instar des chaînes de caractères, les listes ont de nombreuses\n", 332 | "méthodes *built-in*, qui s’utilisent selon le format\n", 333 | "`objet.methode(parametres)`. Les plus utiles sont présentées ci-dessous\n", 334 | "; d’autres méthodes seront utilisées dans le cadre des exercices de fin\n", 335 | "de section." 336 | ], 337 | "id": "65c265ad-aa78-4e05-a864-ea7c0d38ca4e" 338 | }, 339 | { 340 | "cell_type": "code", 341 | "execution_count": null, 342 | "metadata": {}, 343 | "outputs": [], 344 | "source": [ 345 | "# Ajouter un élément\n", 346 | "a = [1, 2, 3]\n", 347 | "a.append(4)\n", 348 | "print(a)" 349 | ], 350 | "id": "02db1d05" 351 | }, 352 | { 353 | "cell_type": "code", 354 | "execution_count": null, 355 | "metadata": {}, 356 | "outputs": [], 357 | "source": [ 358 | "# Supprimer un élément par position\n", 359 | "b = [\"do\", \"re\", \"mi\"]\n", 360 | "b.pop(0)\n", 361 | "print(b)" 362 | ], 363 | "id": "b04c0f01" 364 | }, 365 | { 366 | "cell_type": "code", 367 | "execution_count": null, 368 | "metadata": {}, 369 | "outputs": [], 370 | "source": [ 371 | "# Supprimer un élément par valeur\n", 372 | "b = [\"do\", \"re\", \"mi\"]\n", 373 | "b.remove(\"mi\")\n", 374 | "print(b)" 375 | ], 376 | "id": "262a2548" 377 | }, 378 | { 379 | "cell_type": "code", 380 | "execution_count": null, 381 | "metadata": {}, 382 | "outputs": [], 383 | "source": [ 384 | "# Inverser une liste\n", 385 | "l = [1, 2, 3, 4, 5]\n", 386 | "l.reverse()\n", 387 | "print(l)" 388 | ], 389 | "id": "2ff63c43" 390 | }, 391 | { 392 | "cell_type": "code", 393 | "execution_count": null, 394 | "metadata": {}, 395 | "outputs": [], 396 | "source": [ 397 | "# Trouver la position d'un élément\n", 398 | "b = [\"a\", \"b\", \"c\", \"d\", \"e\"]\n", 399 | "b.index(\"d\")" 400 | ], 401 | "id": "20f0b37f" 402 | }, 403 | { 404 | "cell_type": "markdown", 405 | "metadata": {}, 406 | "source": [ 407 | "## Tuples\n", 408 | "\n", 409 | "### Définition\n", 410 | "\n", 411 | "Les **tuples** sont une autre structure de données basique en Python,\n", 412 | "semblable à celle des listes dans leur fonctionnement. Il y a cependant\n", 413 | "une différence fondamentale : là où les éléments d’une liste peuvent\n", 414 | "être modifiés par position comme on l’a vu précédemment, les tuples sont\n", 415 | "**non-modifiables** (*immutable*). Ainsi, les éléments d’un tuple ne\n", 416 | "peuvent pas être modifiés sans redéfinir complètement le tuple.\n", 417 | "\n", 418 | "Quand est-il pertinent d’utiliser un tuple plutôt qu’une liste ? En\n", 419 | "pratique, les tuples sont beaucoup moins fréquemment utilisés que les\n", 420 | "listes. On utilise généralement les tuples pour **stocker des données\n", 421 | "qui n’ont pas vocation à être modifiées** lors de l’exécution de notre\n", 422 | "programme Python. Cela permet de se prémunir contre des problèmes\n", 423 | "d’intégrité de données, c’est à dire de modification non-voulue des\n", 424 | "données d’entrée. On s’évite ainsi parfois de longues et pénibles\n", 425 | "séances de debugging.\n", 426 | "\n", 427 | "Une autre différence, mineure celle-ci, est que les tuples s’écrivent\n", 428 | "avec des **parenthèses** au lieu des crochets. Les différents éléments\n", 429 | "sont toujours séparés par des virgules." 430 | ], 431 | "id": "4e7eb5b9-e06b-437b-ab04-2c35fc95dc22" 432 | }, 433 | { 434 | "cell_type": "code", 435 | "execution_count": null, 436 | "metadata": {}, 437 | "outputs": [], 438 | "source": [ 439 | "x = (1, 2, \"mi\", \"fa\", 5)\n", 440 | "x" 441 | ], 442 | "id": "c3ab51c3" 443 | }, 444 | { 445 | "cell_type": "markdown", 446 | "metadata": {}, 447 | "source": [ 448 | "Afin de bien faire la différence avec l’usage normal des parenthèses\n", 449 | "(dans les calculs ou pour délimiter les expressions), un tuple à un seul\n", 450 | "élément se définit avec une virgule après le premier élément." 451 | ], 452 | "id": "a88a3dcb-da7c-49e4-89dd-e47bced1e6bb" 453 | }, 454 | { 455 | "cell_type": "code", 456 | "execution_count": null, 457 | "metadata": {}, 458 | "outputs": [], 459 | "source": [ 460 | "x1 = (\"a\", )\n", 461 | "x1" 462 | ], 463 | "id": "0fc7a5a3" 464 | }, 465 | { 466 | "cell_type": "markdown", 467 | "metadata": {}, 468 | "source": [ 469 | "Vérifions qu’il est impossible de modifier ou d’ajouter un élément à un\n", 470 | "tuple." 471 | ], 472 | "id": "33566f64-f265-4dde-8624-228b36db471c" 473 | }, 474 | { 475 | "cell_type": "code", 476 | "execution_count": null, 477 | "metadata": {}, 478 | "outputs": [], 479 | "source": [ 480 | "t = (\"do\", \"rez\", \"mi\")\n", 481 | "t[1] = \"re\"" 482 | ], 483 | "id": "cab67397" 484 | }, 485 | { 486 | "cell_type": "code", 487 | "execution_count": null, 488 | "metadata": {}, 489 | "outputs": [], 490 | "source": [ 491 | "t = (\"do\", \"re\", \"mi\")\n", 492 | "t.append(\"fa\")" 493 | ], 494 | "id": "dfe82d1d" 495 | }, 496 | { 497 | "cell_type": "markdown", 498 | "metadata": {}, 499 | "source": [ 500 | "### Fonctionnement\n", 501 | "\n", 502 | "Les tuples s’indexent comme les listes." 503 | ], 504 | "id": "812bbbda-4e52-4117-bbda-87091c01e3f2" 505 | }, 506 | { 507 | "cell_type": "code", 508 | "execution_count": null, 509 | "metadata": {}, 510 | "outputs": [], 511 | "source": [ 512 | "print(x[0])\n", 513 | "print(x[3:5])" 514 | ], 515 | "id": "f93e8ef9" 516 | }, 517 | { 518 | "cell_type": "markdown", 519 | "metadata": {}, 520 | "source": [ 521 | "Et peuvent également s’utiliser de manière hiérarchique." 522 | ], 523 | "id": "a94668b5-895d-463c-9260-0531eba02487" 524 | }, 525 | { 526 | "cell_type": "code", 527 | "execution_count": null, 528 | "metadata": {}, 529 | "outputs": [], 530 | "source": [ 531 | "t1 = (\"a\", \"b\", \"c\")\n", 532 | "t2 = (1, 2, 3)\n", 533 | "t3 = (t1, \"et\", t2)\n", 534 | "\n", 535 | "print(t3)\n", 536 | "print(t3[2][1])" 537 | ], 538 | "id": "1c064fa1" 539 | }, 540 | { 541 | "cell_type": "markdown", 542 | "metadata": {}, 543 | "source": [ 544 | "Les tuples partagent certaines méthodes *built-in* avec les listes :\n", 545 | "celles qui ne provoquent pas de modification de l’objet." 546 | ], 547 | "id": "64b66298-54f8-4ad3-af20-23ef1db4b681" 548 | }, 549 | { 550 | "cell_type": "code", 551 | "execution_count": null, 552 | "metadata": {}, 553 | "outputs": [], 554 | "source": [ 555 | "t = (\"do\", \"re\", \"mi\")\n", 556 | "t.index(\"do\")" 557 | ], 558 | "id": "a7be7a17" 559 | }, 560 | { 561 | "cell_type": "code", 562 | "execution_count": null, 563 | "metadata": {}, 564 | "outputs": [], 565 | "source": [ 566 | "t = (\"do\", \"re\", \"mi\", \"re\", \"do\")\n", 567 | "t.count(\"re\")" 568 | ], 569 | "id": "27039b4a" 570 | }, 571 | { 572 | "cell_type": "markdown", 573 | "metadata": {}, 574 | "source": [ 575 | "### Conversion\n", 576 | "\n", 577 | "Les fonctions `list` et `tuple` permettent de convertir une liste en\n", 578 | "tuple et inversement." 579 | ], 580 | "id": "5502f685-7000-4d67-85bc-c64f89d456ee" 581 | }, 582 | { 583 | "cell_type": "code", 584 | "execution_count": null, 585 | "metadata": {}, 586 | "outputs": [], 587 | "source": [ 588 | "tuple([\"do\", \"re\", \"mi\"])" 589 | ], 590 | "id": "580bca96" 591 | }, 592 | { 593 | "cell_type": "code", 594 | "execution_count": null, 595 | "metadata": {}, 596 | "outputs": [], 597 | "source": [ 598 | "list((1, 2, 3, 4, 5))" 599 | ], 600 | "id": "40303bae" 601 | }, 602 | { 603 | "cell_type": "markdown", 604 | "metadata": {}, 605 | "source": [ 606 | "Ces fonctions ont d’autres usages en pratique, que nous verrons en\n", 607 | "exercice.\n", 608 | "\n", 609 | "## Exercices\n", 610 | "\n", 611 | "### Questions de compréhension\n", 612 | "\n", 613 | "- Pourquoi dit-on des listes et des tuples que ce sont des conteneurs\n", 614 | " ?\n", 615 | "\n", 616 | "- Quel est le point commun entre les listes et les chaînes de\n", 617 | " caractères ?\n", 618 | "\n", 619 | "- Comment est enregistré l’ordre des éléments dans une séquence en\n", 620 | " Python ?\n", 621 | "\n", 622 | "- Quelle est la différence fondamentale entre une liste et un tuple ?\n", 623 | "\n", 624 | "- Dans quel cas aura-t-on plutôt intérêt à utiliser un tuple qu’une\n", 625 | " liste ?\n", 626 | "\n", 627 | "- Peut-on avoir des éléments de types différents (ex : `int` et\n", 628 | " `string`) dans une même liste ? Dans un même tuple ?" 629 | ], 630 | "id": "8a7bd04a-5d76-48c3-b0ab-df0cd52bdbd8" 631 | }, 632 | { 633 | "cell_type": "markdown", 634 | "metadata": {}, 635 | "source": [ 636 | "
\n", 637 | "\n", 638 | "\n", 639 | "\n", 640 | "Afficher la solution\n", 641 | "\n", 642 | "\n", 643 | "\n", 644 | "- 1/ On dit que les listes et les tuples sont des conteneurs parce\n", 645 | " qu’ils permettent de stocker et d’organiser une collection\n", 646 | " d’éléments de différente nature dans une unique structure de\n", 647 | " données.\n", 648 | "\n", 649 | "- 2/ Les listes et les chaînes de caractères sont toutes deux des\n", 650 | " séquences ordonnées d’éléments, qui peuvent être requêtées par\n", 651 | " position. Dans le cas d’une chaîne de caractères, chaque élément est\n", 652 | " lui même une chaîne de caractères. Dans le cas d’une liste, les\n", 653 | " éléments peuvent être de différente nature (chaîne de caractère,\n", 654 | " liste, tuple, etc.)\n", 655 | "\n", 656 | "- 3/ Chaque élément d’une séquence a une position unique, appelée\n", 657 | " indice, qui commence à 0 pour le premier élément, 1 pour le second,\n", 658 | " et ainsi de suite. Les éléments sont stockés dans l’ordre où ils\n", 659 | " sont ajoutés.\n", 660 | "\n", 661 | "- 4/ Une liste est un objet mutable : il est possible d’ajouter,\n", 662 | " supprimer ou modifier des éléments d’une liste après sa création. A\n", 663 | " l’inverse, les tuples sont immutables : une fois qu’un tuple est\n", 664 | " défini, on ne peut ni changer ses éléments, ni ajouter ou supprimer\n", 665 | " des éléments.\n", 666 | "\n", 667 | "- 5/ En vertu de leur immutabilité, les tuples sont particulièrement\n", 668 | " adaptés pour stocker des données dont on voudrait s’assurer qu’elle\n", 669 | " ne seront pas modifiés par erreur. Par exemples, pour stocker des\n", 670 | " constantes d’un algorithme (paramètres, coordonnées géographiques,\n", 671 | " chemin de fichier, etc).\n", 672 | "\n", 673 | "- 6/ Oui, il est tout à fait possible d’avoir des éléments de types\n", 674 | " différents dans une même liste ou dans un même tuple. Ces éléments\n", 675 | " peuvent être de types de base (ex : `int` et `string`), mais\n", 676 | " également des conteneurs (ex : liste, tuple, dictionnaire, etc.).\n", 677 | "\n", 678 | "
" 679 | ], 680 | "id": "0fa4a929-60aa-474a-bd6a-f9ebb4c492e5" 681 | }, 682 | { 683 | "cell_type": "markdown", 684 | "metadata": {}, 685 | "source": [ 686 | "### Les 4 saisons\n", 687 | "\n", 688 | "Créez 4 listes portant les noms des 4 saisons, contenant chacune les\n", 689 | "noms des mois associés (les mois de changement de saison seront\n", 690 | "attribués à la saison précédente). Puis créez une liste `saisons`\n", 691 | "contenant les 4 listes. Essayez de prévoir ce que vont renvoyer (type de\n", 692 | "l’objet, nombre d’éléments et contenu) les instructions suivantes, puis\n", 693 | "vérifiez le.\n", 694 | "\n", 695 | "- `saisons`\n", 696 | "\n", 697 | "- `saisons[0]`\n", 698 | "\n", 699 | "- `saisons[0][0]`\n", 700 | "\n", 701 | "- `saisons[1][-1]`\n", 702 | "\n", 703 | "- `saisons[2][:3]`\n", 704 | "\n", 705 | "- `saisons[1][1:2] + saisons[-1][3:]`\n", 706 | "\n", 707 | "- `saisons[2:]`\n", 708 | "\n", 709 | "- `saisons + saisons[0]`\n", 710 | "\n", 711 | "- `saisons[3][::]`\n", 712 | "\n", 713 | "- `saisons[3][::-1]`\n", 714 | "\n", 715 | "- `saisons * 3`" 716 | ], 717 | "id": "f6709b27-7f3f-4740-b9a6-a61a207924a4" 718 | }, 719 | { 720 | "cell_type": "code", 721 | "execution_count": null, 722 | "metadata": {}, 723 | "outputs": [], 724 | "source": [ 725 | "# Testez votre réponse dans cette cellule" 726 | ], 727 | "id": "d88d3311" 728 | }, 729 | { 730 | "cell_type": "markdown", 731 | "metadata": {}, 732 | "source": [ 733 | "
\n", 734 | "\n", 735 | "\n", 736 | "\n", 737 | "Afficher la solution\n", 738 | "\n", 739 | "\n", 740 | "\n", 741 | "``` python\n", 742 | "printemps = [\"avril\", \"mai\", \"juin\"]\n", 743 | "ete = [\"juillet\", \"aout\", \"septembre\"]\n", 744 | "automne = [\"octobre\", \"novembre\", \"decembre\"]\n", 745 | "hiver = [\"janvier\", \"fevrier\", \"mars\"]\n", 746 | "\n", 747 | "saisons = [printemps, ete, automne, hiver]\n", 748 | "\n", 749 | "l = saisons\n", 750 | "print(type(l), len(l), l, \"\\n\")\n", 751 | "\n", 752 | "l = saisons[0]\n", 753 | "print(type(l), len(l), l, \"\\n\")\n", 754 | "\n", 755 | "l = saisons[0][0]\n", 756 | "print(type(l), len(l), l, \"\\n\")\n", 757 | "\n", 758 | "l = saisons[1][-1]\n", 759 | "print(type(l), len(l), l, \"\\n\")\n", 760 | "\n", 761 | "l = saisons[2][:3]\n", 762 | "print(type(l), len(l), l, \"\\n\")\n", 763 | "\n", 764 | "l = saisons[1][1:2] + saisons[-1][3:]\n", 765 | "print(type(l), len(l), l, \"\\n\")\n", 766 | "\n", 767 | "l = saisons[2:]\n", 768 | "print(type(l), len(l), l, \"\\n\")\n", 769 | "\n", 770 | "l = saisons + saisons[0]\n", 771 | "print(type(l), len(l), l, \"\\n\")\n", 772 | "\n", 773 | "l = saisons[3][::]\n", 774 | "print(type(l), len(l), l, \"\\n\")\n", 775 | "\n", 776 | "l = saisons[3][::-1]\n", 777 | "print(type(l), len(l), l, \"\\n\")\n", 778 | "\n", 779 | "l = saisons * 3\n", 780 | "print(type(l), len(l), l, \"\\n\")\n", 781 | "```\n", 782 | "\n", 783 | "
" 784 | ], 785 | "id": "01aa2263-8b10-4479-9acc-43986d30e8e9" 786 | }, 787 | { 788 | "cell_type": "markdown", 789 | "metadata": {}, 790 | "source": [ 791 | "### Faire ses gammes\n", 792 | "\n", 793 | "En ajoutant, supprimant et modifiant des éléments, nettoyez la liste\n", 794 | "suivante pour qu’elle contienne les notes de musique “do re mi fa sol la\n", 795 | "si” dans le bon ordre.\n", 796 | "\n", 797 | "`l = [\"do\", \"re\", \"re\", \"re\", \"fa\", \"sol\", \"solsi\", \"la\"]`" 798 | ], 799 | "id": "2a31b530-61d3-4e78-8c2b-4387c8f0570a" 800 | }, 801 | { 802 | "cell_type": "code", 803 | "execution_count": null, 804 | "metadata": {}, 805 | "outputs": [], 806 | "source": [ 807 | "# Testez votre réponse dans cette cellule" 808 | ], 809 | "id": "c213bc5e" 810 | }, 811 | { 812 | "cell_type": "markdown", 813 | "metadata": {}, 814 | "source": [ 815 | "
\n", 816 | "\n", 817 | "\n", 818 | "\n", 819 | "Afficher la solution\n", 820 | "\n", 821 | "\n", 822 | "\n", 823 | "``` python\n", 824 | "l = [\"do\", \"re\", \"re\", \"re\", \"fa\", \"sol\", \"solsi\", \"la\"]\n", 825 | "\n", 826 | "del l[1] # On aurait aussi pu utiliser : l.pop(1)\n", 827 | "l[2] = \"mi\"\n", 828 | "del l[5]\n", 829 | "l.append(\"si\")\n", 830 | "\n", 831 | "print(l)\n", 832 | "```\n", 833 | "\n", 834 | "Cet exemple visait simplement à pratiquer la modification et la\n", 835 | "suppression d’éléments. En pratique, il aurait été bien plus simple de\n", 836 | "directement créer la liste correcte.\n", 837 | "\n", 838 | "
" 839 | ], 840 | "id": "dfb34c0d-01c3-4507-b5e5-ec009bb5c83c" 841 | }, 842 | { 843 | "cell_type": "markdown", 844 | "metadata": {}, 845 | "source": [ 846 | "### Inversion de liste\n", 847 | "\n", 848 | "Proposez deux méthodes pour inverser la liste\n", 849 | "`[\"une\", \"liste\", \"quelconque\"]`. Quelle est la différence majeure entre\n", 850 | "les deux méthodes ?" 851 | ], 852 | "id": "ea96b0d1-a5c1-425f-8527-8c335bbaab7b" 853 | }, 854 | { 855 | "cell_type": "code", 856 | "execution_count": null, 857 | "metadata": {}, 858 | "outputs": [], 859 | "source": [ 860 | "# Testez votre réponse dans cette cellule" 861 | ], 862 | "id": "7fda33f8" 863 | }, 864 | { 865 | "cell_type": "markdown", 866 | "metadata": {}, 867 | "source": [ 868 | "
\n", 869 | "\n", 870 | "\n", 871 | "\n", 872 | "Afficher la solution\n", 873 | "\n", 874 | "\n", 875 | "\n", 876 | "``` python\n", 877 | "l1 = [\"une\", \"liste\", \"quelconque\"]\n", 878 | "l1.reverse()\n", 879 | "print(l1)\n", 880 | "\n", 881 | "l2 = [\"une\", \"liste\", \"quelconque\"]\n", 882 | "print(l2[::-1])\n", 883 | "print(l2)\n", 884 | "```\n", 885 | "\n", 886 | "La méthode `reverse` modifie la liste “en place” : la liste est\n", 887 | "durablement inversée après l’avoir exécutée. En revanche, la méthode qui\n", 888 | "inverse la liste via l’indexation renvoie une nouvelle liste et ne\n", 889 | "modifie pas l’existante. Pour que ce changement soit durable, il\n", 890 | "faudrait donc écraser la liste existante, ou bien en créer une nouvelle.\n", 891 | "\n", 892 | "``` python\n", 893 | "l2 = l2[::-1]\n", 894 | "print(l2)\n", 895 | "```\n", 896 | "\n", 897 | "
" 898 | ], 899 | "id": "9e465f50-8e53-4475-8384-1ba046e097d4" 900 | }, 901 | { 902 | "cell_type": "markdown", 903 | "metadata": {}, 904 | "source": [ 905 | "### Pop’it\n", 906 | "\n", 907 | "Nous avons vu que l’instruction `ma_liste.pop(i)` supprimait le i-ème\n", 908 | "élément de la liste `ma_liste`. A l’aide de la documentation Python ou\n", 909 | "d’une recherche sur Google, déterminez le comportement par défaut de\n", 910 | "cette méthode, c’est à dire ce qu’il se passe lorsqu’on ne donne aucun\n", 911 | "paramètre à la fonction `pop`. Vérifiez que vous observez bien ce\n", 912 | "comportement à l’aide d’un exemple de votre choix." 913 | ], 914 | "id": "e4973730-ead7-49d0-9482-b8c954c22cf6" 915 | }, 916 | { 917 | "cell_type": "code", 918 | "execution_count": null, 919 | "metadata": {}, 920 | "outputs": [], 921 | "source": [ 922 | "# Testez votre réponse dans cette cellule" 923 | ], 924 | "id": "662951c3" 925 | }, 926 | { 927 | "cell_type": "markdown", 928 | "metadata": {}, 929 | "source": [ 930 | "
\n", 931 | "\n", 932 | "\n", 933 | "\n", 934 | "Afficher la solution\n", 935 | "\n", 936 | "\n", 937 | "\n", 938 | "``` python\n", 939 | "l = [\"do\", \"re\", \"mi\"]\n", 940 | "l.pop()\n", 941 | "print(l)\n", 942 | "```\n", 943 | "\n", 944 | "
" 945 | ], 946 | "id": "c6f65a1a-dd92-4124-9ce5-776288cebd57" 947 | }, 948 | { 949 | "cell_type": "markdown", 950 | "metadata": {}, 951 | "source": [ 952 | "### Min et max de différentes listes\n", 953 | "\n", 954 | "Il existe beaucoup d’autres méthodes *built-in* pour les listes que\n", 955 | "celles que nous avons déjà vues. Par exemple : `min` et `max`. Vérifiez\n", 956 | "leur comportement :\n", 957 | "\n", 958 | "- sur une liste composée uniquement d’objets numériques (`int` et\n", 959 | " `float`) ;\n", 960 | "\n", 961 | "- sur une liste composée uniquement de chaînes de caractères ;\n", 962 | "\n", 963 | "- sur une liste composée d’un mélange d’objets numériques et textuels." 964 | ], 965 | "id": "3e54c6d4-e250-4702-81a7-efef6731e9e5" 966 | }, 967 | { 968 | "cell_type": "code", 969 | "execution_count": null, 970 | "metadata": {}, 971 | "outputs": [], 972 | "source": [ 973 | "# Testez votre réponse dans cette cellule" 974 | ], 975 | "id": "f44381aa" 976 | }, 977 | { 978 | "cell_type": "markdown", 979 | "metadata": {}, 980 | "source": [ 981 | "
\n", 982 | "\n", 983 | "\n", 984 | "\n", 985 | "Afficher la solution\n", 986 | "\n", 987 | "\n", 988 | "\n", 989 | "``` python\n", 990 | "a = [5, 800, 9.92, 0]\n", 991 | "b = [\"do\", \"re\", \"mi\", \"fa\", \"sol\"]\n", 992 | "c = [1, \"melange\", \"des\", 2]\n", 993 | "\n", 994 | "print(min(a), max(a))\n", 995 | "print(min(b), max(b))\n", 996 | "print(min(c), max(c))\n", 997 | "```\n", 998 | "\n", 999 | "La troisième expression renvoie une erreur : il n’existe pas de relation\n", 1000 | "d’ordre pertinente.\n", 1001 | "\n", 1002 | "
" 1003 | ], 1004 | "id": "bb2405b2-d0c3-4d37-8b41-520fad4977dd" 1005 | }, 1006 | { 1007 | "cell_type": "markdown", 1008 | "metadata": {}, 1009 | "source": [ 1010 | "### Liste vide\n", 1011 | "\n", 1012 | "Essayer de créer une liste vide. Vérifiez son type. Quel intérêt\n", 1013 | "pourrait avoir un tel objet ?" 1014 | ], 1015 | "id": "32c6d7c2-49e3-4b7b-bce0-5d0d09a37c0f" 1016 | }, 1017 | { 1018 | "cell_type": "code", 1019 | "execution_count": null, 1020 | "metadata": {}, 1021 | "outputs": [], 1022 | "source": [ 1023 | "# Testez votre réponse dans cette cellule" 1024 | ], 1025 | "id": "fc05b8e4" 1026 | }, 1027 | { 1028 | "cell_type": "markdown", 1029 | "metadata": {}, 1030 | "source": [ 1031 | "
\n", 1032 | "\n", 1033 | "\n", 1034 | "\n", 1035 | "Afficher la solution\n", 1036 | "\n", 1037 | "\n", 1038 | "\n", 1039 | "``` python\n", 1040 | "l = []\n", 1041 | "print(l)\n", 1042 | "print(type(l))\n", 1043 | "```\n", 1044 | "\n", 1045 | "On peut donc effectivement créer une liste vide. Mais quel intérêt ? Un\n", 1046 | "usage très fréquent est d’initialiser une liste, que l’on va ensuite\n", 1047 | "remplir au fur et à mesure des itérations d’une boucle. Les boucles\n", 1048 | "feront l’objet d’un prochain tutoriel ; mais voici un exemple simple\n", 1049 | "d’un tel usage.\n", 1050 | "\n", 1051 | "``` python\n", 1052 | "for i in range(10):\n", 1053 | " l.append(i)\n", 1054 | " \n", 1055 | "print(l)\n", 1056 | "```\n", 1057 | "\n", 1058 | "
" 1059 | ], 1060 | "id": "32a4009e-d3cf-4b21-90e4-71c0cbac3171" 1061 | }, 1062 | { 1063 | "cell_type": "markdown", 1064 | "metadata": {}, 1065 | "source": [ 1066 | "### La fonction `list`\n", 1067 | "\n", 1068 | "Dans le tutoriel, nous avons vu les fonctions `list` et `tuple` qui\n", 1069 | "permettent de passer d’un type à l’autre. En réalité, le fonctionnement\n", 1070 | "de ces fonctions est plus subtil : le code `list(mon_objet)` renvoie la\n", 1071 | "“version liste” de cet objet, de la même manière par exemple que\n", 1072 | "`str(3)` renvoie `'3'`, c’est à dire la version *string* de l’entier\n", 1073 | "`3`.\n", 1074 | "\n", 1075 | "A l’aide de la fonction `list`, trouver les “versions liste” des objets\n", 1076 | "suivants :\n", 1077 | "\n", 1078 | "- le tuple `a = (1, 2, 3)` ;\n", 1079 | "\n", 1080 | "- la chaîne de caractères `b = \"bonjour\"` ;\n", 1081 | "\n", 1082 | "- l’entier `c = 5`" 1083 | ], 1084 | "id": "43d8a4bd-94f1-4e8d-af44-0cdfc7875a66" 1085 | }, 1086 | { 1087 | "cell_type": "code", 1088 | "execution_count": null, 1089 | "metadata": {}, 1090 | "outputs": [], 1091 | "source": [ 1092 | "# Testez votre réponse dans cette cellule" 1093 | ], 1094 | "id": "de9c2d8b" 1095 | }, 1096 | { 1097 | "cell_type": "markdown", 1098 | "metadata": {}, 1099 | "source": [ 1100 | "
\n", 1101 | "\n", 1102 | "\n", 1103 | "\n", 1104 | "Afficher la solution\n", 1105 | "\n", 1106 | "\n", 1107 | "\n", 1108 | "``` python\n", 1109 | "a = (1, 2, 3)\n", 1110 | "print(list(a))\n", 1111 | "\n", 1112 | "b = \"bonjour\"\n", 1113 | "print(list(b))\n", 1114 | "\n", 1115 | "c = 5\n", 1116 | "print(list(c))\n", 1117 | "```\n", 1118 | "\n", 1119 | "La dernière expression renvoie une erreur : un entier n’est pas une\n", 1120 | "séquence, une “version liste” n’a donc pas sens. On peut par contre bien\n", 1121 | "entendu créer une liste avec pour seul élément 5.\n", 1122 | "\n", 1123 | "``` python\n", 1124 | "d = [5]\n", 1125 | "print(d)\n", 1126 | "```\n", 1127 | "\n", 1128 | "
" 1129 | ], 1130 | "id": "c5392088-fe74-4d10-9b9f-ab2ba4bd999b" 1131 | }, 1132 | { 1133 | "cell_type": "markdown", 1134 | "metadata": {}, 1135 | "source": [ 1136 | "### Immutabilité des tuples\n", 1137 | "\n", 1138 | "Nous avons vu que les tuples avaient la particularité d’être\n", 1139 | "non-modifiables. Mais est-ce que cette propriété se transfère de manière\n", 1140 | "récursive ? Par exemple, est-ce qu’une liste contenue dans un tuple\n", 1141 | "est-elle même non-modifiable ? Vérifiez à l’aide d’un exemple de votre\n", 1142 | "choix." 1143 | ], 1144 | "id": "ccda35ad-57e2-411c-b12c-657580f13362" 1145 | }, 1146 | { 1147 | "cell_type": "code", 1148 | "execution_count": null, 1149 | "metadata": {}, 1150 | "outputs": [], 1151 | "source": [ 1152 | "# Testez votre réponse dans cette cellule" 1153 | ], 1154 | "id": "cce90f0c" 1155 | }, 1156 | { 1157 | "cell_type": "markdown", 1158 | "metadata": {}, 1159 | "source": [ 1160 | "
\n", 1161 | "\n", 1162 | "\n", 1163 | "\n", 1164 | "Afficher la solution\n", 1165 | "\n", 1166 | "\n", 1167 | "\n", 1168 | "``` python\n", 1169 | "t = (1, 2, [\"une\", \"liste\"])\n", 1170 | "t[2][0] = 26\n", 1171 | "print(t)\n", 1172 | "```\n", 1173 | "\n", 1174 | "Verdict : la non-modifiabilité ne s’applique qu’au premier niveau. Elle\n", 1175 | "ne se transfère pas aux sous-éléments.\n", 1176 | "\n", 1177 | "
" 1178 | ], 1179 | "id": "06b28cfd-5292-4822-b322-58448f5ed2e2" 1180 | }, 1181 | { 1182 | "cell_type": "markdown", 1183 | "metadata": {}, 1184 | "source": [ 1185 | "### Dissociation de séquences\n", 1186 | "\n", 1187 | "Lisez la partie concernant l’agrégation et la dissociation de séquences\n", 1188 | "dans la [documentation\n", 1189 | "Python](https://docs.python.org/fr/3/tutorial/datastructures.html#tuples-and-sequences).\n", 1190 | "La dissociation est une propriété souvent utilisée en pratique. Vérifiez\n", 1191 | "qu’elle fonctionne sur les différents objets séquentiels que nous avons\n", 1192 | "vus jusqu’à maintenant (chaînes de caractères, listes et tuples)." 1193 | ], 1194 | "id": "6196e964-982b-45cc-8a72-fe8697b3397e" 1195 | }, 1196 | { 1197 | "cell_type": "code", 1198 | "execution_count": null, 1199 | "metadata": {}, 1200 | "outputs": [], 1201 | "source": [ 1202 | "# Testez votre réponse dans cette cellule" 1203 | ], 1204 | "id": "065e1888" 1205 | }, 1206 | { 1207 | "cell_type": "markdown", 1208 | "metadata": {}, 1209 | "source": [ 1210 | "
\n", 1211 | "\n", 1212 | "\n", 1213 | "\n", 1214 | "Afficher la solution\n", 1215 | "\n", 1216 | "\n", 1217 | "\n", 1218 | "``` python\n", 1219 | "x, y, z = \"abc\"\n", 1220 | "print(y)\n", 1221 | "\n", 1222 | "a, b, c, d = [\"do\", \"re\", \"mi\", \"fa\"]\n", 1223 | "print(c)\n", 1224 | "\n", 1225 | "r, s, t, u = (\"un\", \"tuple\", \"de\", \"test\")\n", 1226 | "print(r)\n", 1227 | "```\n", 1228 | "\n", 1229 | "
" 1230 | ], 1231 | "id": "0d8ec8ab-73e0-4eb0-8caa-305ef56425e9" 1232 | } 1233 | ], 1234 | "nbformat": 4, 1235 | "nbformat_minor": 5, 1236 | "metadata": { 1237 | "kernelspec": { 1238 | "name": "python3", 1239 | "display_name": "Python 3 (ipykernel)", 1240 | "language": "python", 1241 | "path": "/opt/conda/share/jupyter/kernels/python3" 1242 | } 1243 | } 1244 | } -------------------------------------------------------------------------------- /jupyter/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /jupyter/open-notebook.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This init script clones a Git repository that contains a Jupyter notebook 4 | # named `tutorial.ipynb` and opens it in Jupyter Lab at startup 5 | # Expected parameters : None 6 | 7 | # Clone repository and give permissions to the onyxia user 8 | GIT_REPO=sspcloud-init-scripts 9 | git clone --depth 1 https://github.com/InseeFrLab/${GIT_REPO}.git 10 | chown -R onyxia:users ${GIT_REPO}/ 11 | 12 | # Install additional packages if a requirements.txt file is present in the project 13 | REQUIREMENTS_FILE=${GIT_REPO}/requirements.txt 14 | [ -f $REQUIREMENTS_FILE ] && pip install -r $REQUIREMENTS_FILE 15 | 16 | # Open the relevant notebook when starting Jupyter Lab 17 | echo "c.LabApp.default_url = '/lab/tree/${GIT_REPO}/inputs/tutorial.ipynb'" >> /home/onyxia/.jupyter/jupyter_server_config.py 18 | -------------------------------------------------------------------------------- /rstudio/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /rstudio/customize-settings-r.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # This init script updates settings of R by modifying the user `Rprofile.` 4 | # Expected parameters : None 5 | 6 | cat << EOF > ~/.Rprofile 7 | # Uncomment sections to customize R options 8 | 9 | # Customize console prompt, digit display, and continuation prompt 10 | # options( 11 | # repos = c(CRAN = 'https://cran.rstudio.org') # Custom CRAN repository 12 | # prompt = 'R> ', # Custom prompt 13 | # digits = 4, # Limit numeric precision to 4 digits 14 | # continue = '+++ ' # Continuation prompt 15 | # ) 16 | EOF 17 | 18 | chown -R onyxia:users ~/.Rprofile 19 | -------------------------------------------------------------------------------- /rstudio/customize-settings-rstudio.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # This init script updates settings of RStudio by modifying the `restudio-prefs.json` file. 4 | # Configurations are documented below. 5 | # Expected parameters : None 6 | 7 | cat << EOF > ~/.config/rstudio/rstudio-prefs.json 8 | { 9 | "num_spaces_for_tab": 4, 10 | "insert_native_pipe_operator": true, 11 | "margin_column": 100, 12 | "auto_append_newline": true, 13 | "strip_trailing_whitespace": true, 14 | "auto_save_on_blur": true, 15 | "check_arguments_to_r_function_calls": true, 16 | "check_unexpected_assignment_in_function_call": true, 17 | "warn_variable_defined_but_not_used": true, 18 | "style_diagnostics": true, 19 | "editor_theme": "Vibrant Ink", 20 | "posix_terminal_shell": "bash" 21 | } 22 | EOF 23 | 24 | chown -R onyxia:users ~/.config/ 25 | 26 | # num_spaces_for_tab: Number of spaces used for indentation when pressing Tab 27 | # insert_native_pipe_operator: Automatically insert the native R pipe operator (%>%) when typing '|>' 28 | # margin_column: Column number at which a margin line is displayed in the editor 29 | # auto_append_newline: Automatically add a newline at the end of the file on save 30 | # strip_trailing_whitespace: Remove trailing whitespace on save 31 | # auto_save_on_blur: Automatically save files when the editor loses focus 32 | # check_arguments_to_r_function_calls: Enable argument matching checks for R function calls 33 | # check_unexpected_assignment_in_function_call: Warn about unintended assignments within function calls 34 | # warn_variable_defined_but_not_used: Warn if a variable is defined but not used 35 | # style_diagnostics: Enable diagnostics for style issues in the editor 36 | # editor_theme: Theme applied to the editor (e.g., syntax highlighting) 37 | # posix_terminal_shell: Default shell used in the terminal for POSIX systems 38 | -------------------------------------------------------------------------------- /rstudio/install-packages.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # This init script presents various ways of installing R packages 4 | # Expected parameters : None 5 | 6 | # Clone repository and give permissions to the onyxia user 7 | GIT_REPO=sspcloud-init-scripts 8 | git clone --depth 1 https://github.com/InseeFrLab/${GIT_REPO}.git 9 | chown -R onyxia:users ${GIT_REPO}/ 10 | 11 | # Install the remote package (needed for remotes install) 12 | Rscript -e "install.packages('remotes')" 13 | 14 | # Install from a `DESCRIPTION` file that specifies project dependencies 15 | # See https://r-pkgs.org/description.html for more info 16 | PROJECT_DIR="${GIT_REPO}/inputs" 17 | Rscript -e "remotes::install_deps('${PROJECT_DIR}')" 18 | 19 | # Install from a `renv` lockfile 20 | # See https://rstudio.github.io/renv/articles/renv.html for more info 21 | Rscript -e "install.packages('renv')" 22 | Rscript -e "renv::restore('${PROJECT_DIR}')" 23 | 24 | # Install from 25 | # See https://remotes.r-lib.org/reference/install_github.html for more info 26 | # See https://remotes.r-lib.org/reference/install_gitlab.html for the equivalent GitLab function 27 | Rscript -e "remotes::install_github('tidyverse/ggplot2')" 28 | -------------------------------------------------------------------------------- /rstudio/open-file.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # This init script clones a Git repository that open RStudio on a specific file at startup 4 | # Expected parameters : None 5 | 6 | # Clone repository and give permissions to the onyxia user 7 | GIT_REPO=sspcloud-init-scripts 8 | git clone --depth 1 https://github.com/InseeFrLab/${GIT_REPO}.git 9 | chown -R onyxia:users ${GIT_REPO}/ 10 | 11 | # Open the project 12 | FILE_TO_OPEN=${WORKSPACE_DIR}/${GIT_REPO}/inputs/report.qmd 13 | echo \ 14 | " 15 | setHook('rstudio.sessionInit', function(newSession) { 16 | if (newSession && identical(getwd(), '${WORKSPACE_DIR}')) 17 | { 18 | message('Activation du projet RStudio') 19 | rstudioapi::navigateToFile('${FILE_TO_OPEN}') 20 | } 21 | }, action = 'append') 22 | " >> /home/onyxia/.Rprofile 23 | -------------------------------------------------------------------------------- /rstudio/open-rproj-using-args.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # This init script is a variation of open-rproj, which clones 4 | # a Git repository that contains a RStudio project (*.Rproj) 5 | # and opens it in RStudio at startup. 6 | # In addition, it takes as parameter the name of the git account and the git repository. 7 | 8 | # Expected parameters : 9 | # - Name of the github account 10 | # - Name of the github repository 11 | 12 | # Fetch the parameter 13 | GIT_ACCOUNT=$1 14 | GIT_REPO=$2 15 | 16 | # Clone repository and give permissions to the onyxia user 17 | git clone --depth 1 https://github.com/${GIT_ACCOUNT}/${GIT_REPO}.git 18 | chown -R onyxia:users ${GIT_REPO}/ 19 | 20 | # Open the project 21 | PROJECT_DIR=${WORKSPACE_DIR}/${GIT_REPO}/inputs 22 | echo \ 23 | " 24 | setHook('rstudio.sessionInit', function(newSession) { 25 | if (newSession && identical(getwd(), '${WORKSPACE_DIR}')) 26 | { 27 | message('Activation du projet RStudio') 28 | rstudioapi::openProject('${PROJECT_DIR}') 29 | } 30 | }, action = 'append') 31 | " >> /home/onyxia/.Rprofile -------------------------------------------------------------------------------- /rstudio/open-rproj.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # This init script clones a Git repository that contains a RStudio project (*.Rproj) 4 | # and opens it in RStudio at startup 5 | # Expected parameters : None 6 | 7 | # Clone repository and give permissions to the onyxia user 8 | GIT_REPO=sspcloud-init-scripts 9 | git clone --depth 1 https://github.com/InseeFrLab/${GIT_REPO}.git 10 | chown -R onyxia:users ${GIT_REPO}/ 11 | 12 | # Open the project 13 | PROJECT_DIR=${WORKSPACE_DIR}/${GIT_REPO}/inputs 14 | echo \ 15 | " 16 | setHook('rstudio.sessionInit', function(newSession) { 17 | if (newSession && identical(getwd(), '${WORKSPACE_DIR}')) 18 | { 19 | message('Activation du projet RStudio') 20 | rstudioapi::openProject('${PROJECT_DIR}') 21 | } 22 | }, action = 'append') 23 | " >> /home/onyxia/.Rprofile 24 | -------------------------------------------------------------------------------- /vscode/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /vscode/customize-settings.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This init script updates settings of VSCode. Many example of options are displayed. 4 | # See here for the default settings enforced in Onyxia's VSCode-based images : https://github.com/InseeFrLab/images-datascience/blob/main/vscode/settings/User.json 5 | # Expected parameters : None 6 | 7 | # Path to the VSCode settings.json file 8 | SETTINGS_FILE="${HOME}/.local/share/code-server/User/settings.json" 9 | 10 | # Check if the settings.json file exists, otherwise create a new one 11 | if [ ! -f "$SETTINGS_FILE" ]; then 12 | echo "No existing settings.json found. Creating a new one." 13 | mkdir -p "$(dirname "$SETTINGS_FILE")" 14 | echo "{}" > "$SETTINGS_FILE" # Initialize with an empty JSON object 15 | fi 16 | 17 | # Add or modify Python-related settings using jq 18 | # We will keep the comments outside the jq block, as jq doesn't support comments inside JSON. 19 | jq '. + { 20 | "workbench.colorTheme": "Default Dark Modern", # Set the theme 21 | 22 | "editor.rulers": [80, 100, 120], # Add specific vertical rulers 23 | "files.trimTrailingWhitespace": true, # Automatically trim trailing whitespace 24 | "files.insertFinalNewline": true, # Ensure files end with a newline 25 | 26 | "flake8.args": [ 27 | "--max-line-length=100" # Max line length for Python linting 28 | ] 29 | }' "$SETTINGS_FILE" > "$SETTINGS_FILE.tmp" && mv "$SETTINGS_FILE.tmp" "$SETTINGS_FILE" 30 | -------------------------------------------------------------------------------- /vscode/customize-shortcuts.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This init script is used for defining personnal keyboard shortcuts in VSCode. 4 | # Expected parameters : None 5 | 6 | # Add shortcuts 7 | echo '[ 8 | { 9 | "key": "ctrl+shift+d", 10 | "command": "editor.action.duplicateSelection" # Duplicate a line 11 | }, 12 | { 13 | "key": "ctrl+d", 14 | "command": "editor.action.deleteLines", # Delete a line 15 | "when": "editorTextFocus" 16 | } 17 | ]' > "$HOME/.local/share/code-server/User/keybindings.json" 18 | -------------------------------------------------------------------------------- /vscode/install-extensions-from-script-args.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # This init script install VScode extensions provided as args 4 | # NB : only extensions from the Open VSX Registry (https://open-vsx.org/) can be installed on code-server 5 | # Expected parameters : a space separated list of extensions 6 | 7 | # Check if no arguments are provided 8 | if [ "$#" -ge 1 ]; then 9 | # Loop over all the provided arguments (extensions) 10 | for extension in "$@" 11 | do 12 | echo "Installing extension: $extension" 13 | 14 | # Install the extension using code-server 15 | code-server --install-extension "$extension" 16 | 17 | # Check if the installation was successful 18 | if [ $? -eq 0 ]; then 19 | echo "Successfully installed $extension" 20 | else 21 | echo "Failed to install $extension" 22 | fi 23 | done 24 | fi 25 | -------------------------------------------------------------------------------- /vscode/install-extensions.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # This init script install various useful VScode extensions 4 | # NB : only extensions from the Open VSX Registry (https://open-vsx.org/) can be installed on code-server 5 | # Expected parameters : None 6 | 7 | # CONFORT EXTENSIONS ----------------- 8 | 9 | # Colorizes the indentation in front of text 10 | code-server --install-extension oderwat.indent-rainbow 11 | # Extensive markdown integration 12 | code-server --install-extension yzhang.markdown-all-in-one 13 | # Integrates Excalidraw (software for sketching diagrams) 14 | code-server --install-extension pomdtr.excalidraw-editor 15 | 16 | # COPILOT ---------------------------- 17 | 18 | # Install Copilot (Microsoft's AI-assisted code writing tool) 19 | copilotVersion="1.234.0" 20 | copilotChatVersion="0.20.0" # This version is not compatible with VSCode server 1.92.2 21 | 22 | wget --retry-on-http-error=429 https://marketplace.visualstudio.com/_apis/public/gallery/publishers/GitHub/vsextensions/copilot/${copilotVersion}/vspackage -O copilot.vsix.gz 23 | wget --retry-on-http-error=429 https://marketplace.visualstudio.com/_apis/public/gallery/publishers/GitHub/vsextensions/copilot-chat/${copilotChatVersion}/vspackage -O copilot-chat.vsix.gz 24 | 25 | gzip -d copilot.vsix.gz 26 | gzip -d copilot-chat.vsix.gz 27 | 28 | code-server --install-extension copilot.vsix 29 | code-server --install-extension copilot-chat.vsix 30 | rm copilot.vsix copilot-chat.vsix 31 | --------------------------------------------------------------------------------