Skip to content

Commit 6a00c51

Browse files
authored
Special callouts for vscode (#558)
* VSCode * Ajoute test PR * duplicate * remove * Nice vscode * Force box in vscode * Box anglaise * update * Retrieve tiff
1 parent f9ba3ba commit 6a00c51

File tree

9 files changed

+266
-11
lines changed

9 files changed

+266
-11
lines changed

.github/workflows/prod.yml

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,63 @@ jobs:
131131
#target-branch: test
132132
create-target-branch-if-needed: true
133133
reset-repo: true
134+
enonces-vscode:
135+
name: Render notebooks (VSCode version)
136+
runs-on: ubuntu-latest
137+
container: linogaliana/python-datascientist:latest
138+
needs: docker
139+
if: ${{ !github.event.pull_request.head.repo.fork }}
140+
steps:
141+
- uses: actions/checkout@v4
142+
with:
143+
fetch-depth: 0
144+
ref: ${{ github.event.pull_request.head.ref }}
145+
- name: Configure safe.directory # Workaround for actions/checkout#760
146+
run: |
147+
git config --global --add safe.directory /__w/python-datascientist/python-datascientist
148+
git config --global --add safe.directory /__w/python-datascientist/python-datascientist-notebooks
149+
- shell: bash
150+
run: |
151+
ls
152+
conda info
153+
conda list
154+
- name: Convert in ipynb with Quarto
155+
run: |
156+
export QUARTO_PROFILE=fr,en
157+
rm _quarto.yml
158+
python build/tweak_pipeline_vscode.py --filename _quarto-prod.yml
159+
cp _quarto-prod2.yml _quarto.yml
160+
quarto render --profile fr --to ipynb
161+
quarto render --profile en --to ipynb
162+
- name: Move to expected directory
163+
run: |
164+
mkdir -p temp_notebooks
165+
mkdir -p temp_notebooks/notebooks
166+
python build/move_files.py --direction temp_notebooks/notebooks
167+
quarto render content --to ipynb --execute -M echo:true
168+
mkdir -p temp_notebooks/corrections
169+
python build/move_files.py --direction temp_notebooks/corrections
170+
- uses: actions/upload-artifact@v4
171+
with:
172+
name: Source enonce
173+
path: content/
174+
- uses: actions/upload-artifact@v4
175+
with:
176+
name: Enonces
177+
path: temp_notebooks/notebooks/
178+
- name: Pushes to another repository
179+
uses: linogaliana/github-action-push-to-another-repository@main
180+
env:
181+
API_TOKEN_GITHUB: ${{ secrets.API_TOKEN_GITHUB }}
182+
with:
183+
source-directory: 'temp_notebooks/'
184+
destination-repository-username: 'linogaliana'
185+
destination-repository-name: 'python-datascientist-notebooks'
186+
user-email: lino.galiana@insee.fr
187+
destination-github-username: linogaliana
188+
#target-branch: test
189+
create-target-branch-if-needed: true
190+
reset-repo: true
134191
define-matrix:
135192
runs-on: ubuntu-latest
136193
needs: enonces
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
name: "Pull request: deploy to preview website (Netlify) and test notebooks"
2+
3+
on:
4+
pull_request:
5+
branches:
6+
- main
7+
- master
8+
9+
jobs:
10+
enonces-vscode:
11+
name: Render notebooks
12+
runs-on: ubuntu-latest
13+
container: linogaliana/python-datascientist:latest
14+
steps:
15+
- uses: actions/checkout@v3
16+
with:
17+
fetch-depth: 0
18+
ref: ${{ github.event.pull_request.head.ref }}
19+
repository: ${{github.event.pull_request.head.repo.full_name}}
20+
- name: Configure safe.directory # Workaround for actions/checkout#760
21+
run: |
22+
git config --global --add safe.directory /__w/python-datascientist/python-datascientist
23+
git config --global --add safe.directory /__w/python-datascientist/python-datascientist-notebooks
24+
- shell: bash
25+
run: |
26+
ls
27+
conda info
28+
conda list
29+
- name: Convert in ipynb with Quarto
30+
run: |
31+
quarto --version
32+
rm _quarto.yml
33+
python build/nice-vscode/tweak_pipeline_vscode.py --filename _quarto.yml
34+
cp /build/nice-vscode/lang-notebook-vscode.lua /build/lang-notebook.lua
35+
cp _quarto-prod2.yml _quarto.yml
36+
quarto render content --to ipynb --profile fr
37+
quarto render content --to ipynb --profile en
38+
mkdir -p temp_notebooks
39+
mkdir -p temp_notebooks/notebooks
40+
python build/move_files.py --direction temp_notebooks/notebooks
41+
quarto render content --to ipynb --execute -M echo:true --profile fr
42+
quarto render content --to ipynb --execute -M echo:true --profile en
43+
mkdir -p temp_notebooks/corrections
44+
python build/move_files.py --direction temp_notebooks/corrections
45+
- name: Pushes to another repository (VSCode)
46+
if: ${{ github.event.pull_request.head.repo.full_name == github.repository }}
47+
uses: linogaliana/github-action-push-to-another-repository@main
48+
env:
49+
API_TOKEN_GITHUB: ${{ secrets.API_TOKEN_GITHUB }}
50+
with:
51+
source-directory: 'temp_notebooks/'
52+
destination-repository-username: 'linogaliana'
53+
destination-repository-name: 'python-datascientist-notebooks-vscode'
54+
user-email: lino.galiana@insee.fr
55+
destination-github-username: linogaliana
56+
target-branch: dev
57+
create-target-branch-if-needed: true
58+
reset-repo: true

404.qmd

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,13 @@ through the site using the table of contents or
3030
by searching for the desired page from the following mosaic:
3131
:::
3232

33+
<details>
3334

35+
<summary>
36+
Dérouler pour explorer les pages de ce site
37+
</summary>
3438

3539
::: {#sample-listings}
3640
:::
41+
42+
</details>

_quarto.yml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,16 +67,14 @@ format:
6767
code-overflow: wrap
6868
include-in-header:
6969
- build/toggle.js
70-
#template-partials:
71-
#- ../../_partials/title-block-link-buttons/title-block.html
7270
ipynb: default
7371

7472

7573
# PAGE OPTIONS ---------------------
7674

7775
filters:
7876
- build/replace-title.lua
79-
- build/lang-notebook.lua
77+
- build/nice-vscode/lang-notebook-vscode.lua
8078
#- black-formatter
8179
- build/callout-jupyter.lua
8280

File renamed without changes.
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
local filename = quarto.doc.input_file
2+
local dirname = quarto.project.directory
3+
4+
-- Escape special characters in dirname
5+
local function escape_pattern(str)
6+
return str:gsub("([^%w])", "%%%1")
7+
end
8+
9+
dirname = escape_pattern(dirname)
10+
11+
local filename_relative = filename:gsub("^" .. dirname, "")
12+
filename_relative = "https://pythonds.linogaliana.fr" .. filename_relative
13+
filename_relative = filename_relative:gsub(".qmd", ".html")
14+
15+
quarto.log.output("Directory name: " .. dirname)
16+
quarto.log.output("Filename: " .. filename)
17+
quarto.log.output("Relative filename: " .. filename_relative)
18+
19+
-- Function to check if string ends with a specific suffix
20+
local function ends_with(str, suffix)
21+
return str:sub(-#suffix) == suffix
22+
end
23+
24+
-- Determine the language based on the filename suffix
25+
local function get_text_language(filename_relative)
26+
local text
27+
local type = "note"
28+
29+
-- Add html formatting around
30+
local headBox = "<div class=\"callout callout-style-default callout-" .. type .. " callout-titled\">\n" ..
31+
"<div class=\"callout-header d-flex align-content-center\">\n" ..
32+
"<div class=\"callout-icon-container\">" ..
33+
"<i class=\"callout-icon\"></i>\n" ..
34+
"</div>\n"
35+
36+
37+
if filename_relative:find("/en") then
38+
title = "Version 🇬🇧 🇺🇸"
39+
text = "Ceci est la version anglaise 🇬🇧 🇺🇸," ..
40+
"pour voir la version française, aller sur " ..
41+
"<a href=\"" .. filename_relative:gsub("_en.html", ".html") ..
42+
"\">there</a>"
43+
quarto.log.output("Language detected: english") -- Debug print
44+
else
45+
title = "Version 🇫🇷"
46+
text = "This is the French version 🇫🇷 of that chapter," ..
47+
"to see the English version go " ..
48+
"<a href=\"" .. filename_relative:gsub("_fr.html", "_en.html") ..
49+
"\">there</a>"
50+
quarto.log.output("Language detected: french") -- Debug print
51+
end
52+
53+
local headNote = "<div class=\"callout-title-container flex-fill\">\n" ..
54+
title .. "\n" ..
55+
"</div>\n" ..
56+
"</div>\n"
57+
local preBody = "<div class=\"callout-body-container callout-body\">\n"
58+
local header = headBox .. headNote .. preBody
59+
60+
text = header .. text .. "\n</div>\n</div>"
61+
62+
return text
63+
end
64+
65+
-- Get the language-specific text
66+
local text_language = get_text_language(filename_relative)
67+
68+
if quarto.doc.is_format("ipynb") then
69+
return {
70+
{
71+
Para = function (elem)
72+
for i, v in ipairs(elem.content) do
73+
if v.text == "{{warninglang}}" then
74+
return pandoc.Div(
75+
pandoc.RawBlock("html", text_language),
76+
{class = "markdown"}
77+
)
78+
end
79+
end
80+
return elem
81+
end,
82+
}
83+
}
84+
end
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import yaml
2+
import argparse
3+
4+
# Set up argument parser
5+
parser = argparse.ArgumentParser(description="Modify a YAML file and replace a specific filter value.")
6+
parser.add_argument(
7+
'filename',
8+
nargs='?',
9+
default='_quarto-prod.yml',
10+
help="YAML file to be modified. Default is '_quarto-prod.yml'."
11+
)
12+
parser.add_argument(
13+
'--output',
14+
default='_quarto-prod2.yml',
15+
help="Output YAML file name. Default is '_quarto-prod2.yml'."
16+
)
17+
18+
# Parse arguments
19+
args = parser.parse_args()
20+
21+
# Load the existing YAML file
22+
with open(args.filename, 'r', encoding='utf-8') as file:
23+
data = yaml.safe_load(file)
24+
25+
# Replace 'build/callout-jupyter.lua' with 'build/callout-vscode.lua' in the filters
26+
filters = data.get('filters', [])
27+
for i, filter_item in enumerate(filters):
28+
if filter_item == 'build/callout-jupyter.lua':
29+
filters[i] = 'build/nice-vscode/callout-vscode.lua'
30+
31+
# Write the modified YAML back to the output file
32+
with open(args.output, 'w', encoding='utf-8') as file:
33+
yaml.dump(data, file, allow_unicode=True, sort_keys=False)
34+
35+
print(f"YAML modification completed and saved as {args.output}")

content/manipulation/02_pandas_suite.qmd

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,6 @@ eval: true
3232
>}}
3333
3434

35-
{{< include "../../build/_printBadges.qmd" >}}
36-
37-
:::
38-
3935

4036
::: {.content-visible when-format="ipynb"}
4137
{{warninglang}}
@@ -1341,7 +1337,7 @@ ax.set_axis_off()
13411337

13421338
Pour relier les microdonnées d'entreprises françaises, il existe un numéro unique d'identification : le [numéro `Siren`](https://entreprendre.service-public.fr/vosdroits/F32135). Il s'agit d'un numéro d'identification dans un répertoire légal d'entreprise indispensable pour toutes démarches juridiques, fiscales... Pour les entreprises qui possèdent plusieurs établissements - par exemple dans plusieurs villes - il existe un identifiant dérivé qui s'appelle le [`Siret`](https://www.economie.gouv.fr/cedef/numero-siret): aux 9 chiffres du numéro Sirene s'ajoutent 5 chiffres d'identifications de l'établissement. D'ailleurs, les administrations publiques sont également concernées par le numéro Siren: étant amenées à effectuer des opérations de marchés (achat de matériel, locations de biens, etc.) elles disposent également d'un identifiant Siren. Etant inscrits dans des répertoires légaux pour lesquels les citoyens sont publics, les numéros Siren et les noms des entreprises associées sont disponibles en _open data_, par exemple sur [annuaire-entreprises.data.gouv.fr/](https://annuaire-entreprises.data.gouv.fr/) pour une recherche ponctuelle, sur [data.gouv.fr](https://www.data.gouv.fr/fr/datasets/base-sirene-des-entreprises-et-de-leurs-etablissements-siren-siret/).
13431339

1344-
Cette base Sirene est une mine d'information, parfois comique, sur les entreprises françaises. Par exemple, le site [tif.hair/](https://tif.hair/) s'est amusé à répertorier la part des salons de coiffures proposant des jeux de mots dans le nom du salon. Lorsqu'un entrepreneur déclare la création d'une entreprise, il reçoit un numéro Sirene et un code d'activité (le [code APE](https://entreprendre.service-public.fr/vosdroits/F33050)) relié à la description qu'il a déclaré de l'activité de son entreprise. Ce code permet de classer l'activité d'une entreprise dans la [Nomenclature d'activités françaises (NAF)](https://www.insee.fr/fr/information/2406147) ce qui servira à l'Insee pour la publication de statistiques sectorielles. En l'occurrence, pour les coiffeurs, le code dans la NAF est [96.02A](https://www.insee.fr/fr/metadonnees/nafr2/sousClasse/96.02A?champRecherche=false). Il est possible à partir de la base disponible en _open data_ d'avoir en quelques lignes de `Python` la liste de tous les coiffeurs puis de s'amuser à explorer ces données (objet du prochain exercice optionnel).
1340+
Cette base Sirene est une mine d'information, parfois comique, sur les entreprises françaises. Par exemple, le site [tif.hair/](https://tif.hair/) s'est amusé à répertorier la part des salons de coiffures proposant des jeux de mots dans le nom du salon. Lorsqu'un entrepreneur déclare la création d'une entreprise, il reçoit un numéro Sirene et un code d'activité (le [code APE](https://entreprendre.service-public.fr/vosdroits/F33050)) relié à la description qu'il a déclaré de l'activité de son entreprise. Ce code permet de classer l'activité d'une entreprise dans la [Nomenclature d'activités françaises (NAF)](https://www.insee.fr/fr/information/2406147) ce qui servira à l'Insee pour la publication de statistiques sectorielles. En l'occurrence, pour les coiffeurs, le code dans la NAF est [`96.02A`](https://www.insee.fr/fr/metadonnees/nafr2/sousClasse/96.02A?champRecherche=false). Il est possible à partir de la base disponible en _open data_ d'avoir en quelques lignes de `Python` la liste de tous les coiffeurs puis de s'amuser à explorer ces données (objet du prochain exercice optionnel).
13451341

13461342
L'exercice suivant, optionnel, propose de s'amuser à reproduire de manière simplifiée le recensement fait par [tif.hair/](https://tif.hair/)
13471343
des jeux de mots dans les salons de coiffure. Il permet de pratiquer quelques méthodes de manipulation textuelle, en avance de phase sur le chapitre consacré aux [expressions régulières](/content/manipulation/04b_regex_TP.qmd).
@@ -1370,6 +1366,7 @@ To read this type of file optimally, it is recommended to use the `DuckDB` libra
13701366

13711367

13721368
{{< include "02_pandas_suite/_exo_optionnel.qmd" >}}
1369+
13731370
{{< include "02_pandas_suite/_exo_optionnel_solution.qmd" >}}
13741371

13751372

content/manipulation/02_pandas_suite/_exo_optionnel_solution.qmd

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,36 @@
44
coiffeurs['denominationUsuelleEtablissement'] = coiffeurs['denominationUsuelleEtablissement'].replace('[ND]', '').fillna('')
55
```
66

7-
::: {.content-visible when-profile="fr"}
7+
::: {.content-visible when-profile="en"}
88
With question 2, we find a list of quite imaginative puns based on the term `tif`
99
:::
1010

11-
::: {.content-visible when-profile="en"}
11+
::: {.content-visible when-profile="fr"}
1212
Avec la question 2, on retrouve une liste de jeux de mots assez imaginatifs à partir du terme `tif`:
1313
:::
1414

15+
```{python}
16+
#| output: false
17+
coiffeurs_tif = duckdb.sql("""
18+
SELECT
19+
siren, siret, dateDebut, enseigne1Etablissement, activitePrincipaleEtablissement, denominationUsuelleEtablissement
20+
FROM
21+
read_parquet('https://minio.lab.sspcloud.fr/lgaliana/data/sirene2024.parquet')
22+
WHERE
23+
activitePrincipaleEtablissement == '96.02A'
24+
AND
25+
denominationUsuelleEtablissement IS NOT NULL
26+
AND
27+
contains(lower(denominationUsuelleEtablissement), 'tif')
28+
""")
29+
coiffeurs_tif = coiffeurs_tif.df()
30+
```
1531

16-
__CHUNK MISSING__
32+
```{python}
33+
", ".join(
34+
coiffeurs_tif.sample(10)["denominationUsuelleEtablissement"]
35+
)
36+
```
1737

1838

1939

0 commit comments

Comments
 (0)