├── .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 | 
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 |
--------------------------------------------------------------------------------