{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "\"FMP\"\n", "\"AudioLabs\"\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "\"C8\"\n", "

Harmonic–Residual–Percussive Separation (HRPS)

\n", "
\n", "\n", "
\n", "\n", "

\n", "In this notebook, we extend the HP separation approach from [Müller, FMP, Springer 2015] by considering an additional residual component. Furthermore, we introduce a cascaded procedure of the resulting approach. These two extension were proposed in the following two articles:\n", " \n", "

\n", "

" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Motivation\n", "\n", "Recall that the [underlying assumption of HPS](../C8/C8S1_HPS.html) is that harmonic sounds correspond to horizontal structures in a spectrogram, while percussive sounds to vertical structures. However, there are many sounds that neither correspond to horizontal nor to vertical structures. For example, noise-like sounds such as applause or distorted guitar lead to many Fourier coefficients distributed over the entire spectrogram without any clear structure. When applying the [HPS procedure](../C8/C8S1_HPS.html), such noise-like components may be more or less randomly assigned partly to the harmonic and partly to the percussive component. Continuing our example with the violin (harmonic sound) and castanets (percussive sound), we further consider applause (noise-like sound), which is neither of percussive nor of harmonic nature. \n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
ViolinApplauseCastanets
\n", " \n", "
\n", "\n", "Following Driedger et al. (see also Exercise 8.5 of [Müller, FMP, Springer 2015]), we introduce an extension to HPS by considering a third **residual component** which captures the sounds that lie **between** a clearly harmonic and a clearly percussive component. The resulting procedure is also referred to as **harmonic–residual–percussive separation** (HRPS). The following figure illustrates the conceptual difference between HPS and HRPS.\n", "\n", "\"FMP_C8_E05_HRP\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## HRPS Procedure\n", "\n", "Using the same notation as in the [FMP notebook on HPS](../C8/C8S1_HPS.html), we now give the technical description of the HRPS procedure. Let $x:\\mathbb{Z}\\to\\mathbb{R}$ be the input signal. The objective is to decompose $x$ into a harmonic component signal $x^\\mathrm{h}$, a residual component signal $x^\\mathrm{r}$, and a percussive component signal $x^\\mathrm{p}$ such that\n", "\n", "\\begin{equation}\n", " x = x^\\mathrm{h} + x^\\mathrm{r} + x^\\mathrm{p}. \n", "\\end{equation}\n", "\n", "The overall pipeline for the HRPS procedure, which closely follows the one for HPS, is illustrated by the following figure.\n", "\n", "\n", "\"FMP_C8_E05_HRP-color\"\n", "\n", "First the signal $x$ is transformed into a magnitude spectrogram $\\mathcal{Y}$. As described in the FMP notebook on HPS, we apply median filtering once **horizontally** and once **vertically** to obtain $\\tilde{\\mathcal{Y}}^\\mathrm{h}$ and $\\tilde{\\mathcal{Y}}^\\mathrm{p}$, respectively. For the median filtering, let $L^\\mathrm{h}$ and $L^\\mathrm{p}$ be the odd length parameters. To define the residual component, we consider an additional parameter $\\beta\\in\\mathbb{R}$ with $\\beta \\geq 1$ called the **separation factor**. Generalizing the definition of the **binary masks** used in HPS, we define the binary masks $\\mathcal{M}^\\mathrm{h}$, $\\mathcal{M}^\\mathrm{r}$, and $\\mathcal{M}^\\mathrm{p}$\n", "for the clearly harmonic, the clearly percussive, and the residual components by setting\n", "\n", "\\begin{eqnarray*}\n", "\\mathcal{M}^\\mathrm{h}(n,k) &:=& \n", "\\begin{cases}\n", " 1 & \\text{if } \\tilde{\\mathcal{Y}}^\\mathrm{h}(n,k) \\geq \\beta\\cdot \\tilde{\\mathcal{Y}}^\\mathrm{p}(n,k), \\\\\n", " 0 & \\text{otherwise,}\n", " \\end{cases} \\\\\n", "\\mathcal{M}^\\mathrm{p}(n,k) &:=& \n", "\\begin{cases}\n", " 1 & \\text{if } \\tilde{\\mathcal{Y}}^\\mathrm{p}(n,k) > \\beta\\cdot \\tilde{\\mathcal{Y}}^\\mathrm{h}(n,k), \\\\\n", " 0 & \\text{otherwise,}\n", " \\end{cases}\\\\\n", "\\mathcal{M}^\\mathrm{r}(n,k) &:=& 1 - \\big( \\mathcal{M}^\\mathrm{h}(n,k) + \\mathcal{M}^\\mathrm{p}(n,k) \\big).\n", "\\end{eqnarray*}\n", "\n", "Using these masks, one defines\n", "\n", "\\begin{eqnarray*}\n", "\\mathcal{X}^\\mathrm{h}(n,k) &:=& \\mathcal{M}^\\mathrm{h}(n,k) \\cdot \\mathcal{X}(n,k), \\\\\n", "\\mathcal{X}^\\mathrm{p}(n,k) &:=& \\mathcal{M}^\\mathrm{p}(n,k) \\cdot \\mathcal{X}(n,k), \\\\\n", "\\mathcal{X}^\\mathrm{r}(n,k) &:=& \\mathcal{M}^\\mathrm{r}(n,k) \\cdot \\mathcal{X}(n,k)\n", "\\end{eqnarray*} \n", "\n", "for $n,k\\in\\mathbf{Z}$. Finally, one can derive time-domain signal $x^\\mathrm{h}$, $x^\\mathrm{p}$, and $x^\\mathrm{r}$ by applying an inverse STFT. The following function `HRPS` implements this procedure." ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "execution": { "iopub.execute_input": "2024-02-15T08:41:15.933234Z", "iopub.status.busy": "2024-02-15T08:41:15.932940Z", "iopub.status.idle": "2024-02-15T08:41:18.326551Z", "shell.execute_reply": "2024-02-15T08:41:18.325967Z" } }, "outputs": [], "source": [ "import os, sys\n", "import numpy as np\n", "from scipy import signal\n", "import matplotlib.pyplot as plt\n", "import IPython.display as ipd\n", "import librosa.display\n", "import soundfile as sf\n", "import pandas as pd\n", "from collections import OrderedDict\n", "\n", "sys.path.append('..')\n", "import libfmp.b\n", "import libfmp.c8\n", "from libfmp.c8 import convert_l_sec_to_frames, convert_l_hertz_to_bins, make_integer_odd\n", "\n", "\n", "def hrps(x, Fs, N, H, L_h, L_p, beta=2.0, L_unit='physical', detail=False):\n", " \"\"\"Harmonic-residual-percussive separation (HRPS) algorithm\n", "\n", " Notebook: C8/C8S1_HRPS.ipynb\n", "\n", " Args:\n", " x (np.ndarray): Input signal\n", " Fs (scalar): Sampling rate of x\n", " N (int): Frame length\n", " H (int): Hopsize\n", " L_h (float): Horizontal median filter length given in seconds or frames\n", " L_p (float): Percussive median filter length given in Hertz or bins\n", " beta (float): Separation factor (Default value = 2.0)\n", " L_unit (str): Adjusts unit, either 'pyhsical' or 'indices' (Default value = 'physical')\n", " detail (bool): Returns detailed information (Default value = False)\n", "\n", " Returns:\n", " x_h (np.ndarray): Harmonic signal\n", " x_p (np.ndarray): Percussive signal\n", " x_r (np.ndarray): Residual signal\n", " details (dict): Dictionary containing detailed information; returned if \"detail=True\"\n", " \"\"\"\n", " assert L_unit in ['physical', 'indices']\n", " # stft\n", " X = librosa.stft(x, n_fft=N, hop_length=H, win_length=N, window='hann', center=True, pad_mode='constant')\n", " # power spectrogram\n", " Y = np.abs(X) ** 2\n", " # median filtering\n", " if L_unit == 'physical':\n", " L_h = convert_l_sec_to_frames(L_h_sec=L_h, Fs=Fs, N=N, H=H)\n", " L_p = convert_l_hertz_to_bins(L_p_Hz=L_p, Fs=Fs, N=N, H=H)\n", " L_h = make_integer_odd(L_h)\n", " L_p = make_integer_odd(L_p)\n", " Y_h = signal.medfilt(Y, [1, L_h])\n", " Y_p = signal.medfilt(Y, [L_p, 1])\n", "\n", " # masking\n", " M_h = np.int8(Y_h >= beta * Y_p)\n", " M_p = np.int8(Y_p > beta * Y_h)\n", " M_r = 1 - (M_h + M_p)\n", " X_h = X * M_h\n", " X_p = X * M_p\n", " X_r = X * M_r\n", "\n", " # istft\n", " x_h = librosa.istft(X_h, hop_length=H, win_length=N, window='hann', center=True, length=x.size)\n", " x_p = librosa.istft(X_p, hop_length=H, win_length=N, window='hann', center=True, length=x.size)\n", " x_r = librosa.istft(X_r, hop_length=H, win_length=N, window='hann', center=True, length=x.size)\n", "\n", " if detail:\n", " return x_h, x_p, x_r, dict(Y_h=Y_h, Y_p=Y_p, M_h=M_h, M_r=M_r, M_p=M_p, X_h=X_h, X_r=X_r, X_p=X_p)\n", " else:\n", " return x_h, x_p, x_r" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Example: Violin, Applause, Castanets\n", "\n", "We now try out the HRPS procedure by using a superposition of the violin, applause, and castanet recordings from above. The mixture signal sounds like this:\n", "\n", "\n", "\n", "The next figure shows the binary masks $\\mathcal{M}^\\mathrm{h}$, $\\mathcal{M}^\\mathrm{r}$, and $\\mathcal{M}^\\mathrm{p}$. It is very instructive to listen to the reconstructed signals $x^\\mathrm{h}$, $x^\\mathrm{r}$, and $x^\\mathrm{p}$. The harmonic signal $x^\\mathrm{h}$ mostly corresponds to the violin, while the residual signal $x^\\mathrm{r}$ captures most of the applause. While the percussive signal $x^\\mathrm{p}$ contains the castanets, the signal is quite distorted and still contains many applause components. Another reason of the signal distortions is also due to **phase artifacts** that are introduced by the [signal reconstruction](../C8/C8S1_SignalReconstruction.html) step. These artifacts become audible particularly for the percussive component. " ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "execution": { "iopub.execute_input": "2024-02-15T08:41:18.329553Z", "iopub.status.busy": "2024-02-15T08:41:18.329298Z", "iopub.status.idle": "2024-02-15T08:41:19.689705Z", "shell.execute_reply": "2024-02-15T08:41:19.688736Z" } }, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" }, { "data": { "text/html": [ "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "Fs = 22050\n", "fn_wav = os.path.join('..', 'data', 'C8', 'FMP_C8_F02_Long_CastanetsViolinApplause.wav')\n", "x, Fs = librosa.load(fn_wav, sr=Fs)\n", "N = 1024\n", "H = 512\n", "L_h_sec = 0.2\n", "L_p_Hz = 500\n", "beta = 2\n", "x_h, x_p, x_r, D = hrps(x, Fs=Fs, N=N, H=H, \n", " L_h=L_h_sec, L_p=L_p_Hz, beta=beta, detail=True)\n", "\n", "ylim = [0, 3000]\n", "plt.figure(figsize=(10,3))\n", "ax = plt.subplot(1,3,1)\n", "libfmp.b.plot_matrix(D['M_h'], Fs=Fs/H, Fs_F=N/Fs, ax=[ax], clim=[0,1],\n", " title='Horizontal binary mask')\n", "ax.set_ylim(ylim)\n", "\n", "ax = plt.subplot(1,3,2)\n", "libfmp.b.plot_matrix(D['M_r'], Fs=Fs/H, Fs_F=N/Fs, ax=[ax], clim=[0,1],\n", " title='Residual binary mask')\n", "ax.set_ylim(ylim)\n", "\n", "ax = plt.subplot(1,3,3)\n", "libfmp.b.plot_matrix(D['M_p'], Fs=Fs/H, Fs_F=N/Fs, ax=[ax], clim=[0,1],\n", " title='Vertical binary mask')\n", "ax.set_ylim(ylim)\n", "\n", "plt.tight_layout()\n", "plt.show()\n", "\n", "html_x_h = libfmp.c8.generate_audio_tag_html_list([x_h], Fs=Fs, width='220')\n", "html_x_r = libfmp.c8.generate_audio_tag_html_list([x_r], Fs=Fs, width='220')\n", "html_x_p = libfmp.c8.generate_audio_tag_html_list([x_p], Fs=Fs, width='220')\n", "\n", "pd.options.display.float_format = '{:,.1f}'.format \n", "pd.set_option('display.max_colwidth', None) \n", "df = pd.DataFrame(OrderedDict([ \n", " ('$x_h$', html_x_h), \n", " ('$x_r$', html_x_r),\n", " ('$x_p$', html_x_p)]))\n", "ipd.display(ipd.HTML(df.to_html(escape=False, header=False, index=False)))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Effect of Separation Factor\n", "\n", "The separation factor $\\beta$ can be used to adjust the decomposition. The case $\\beta=1$ reduces to the original HP decomposition. By increasing $\\beta$, less time–frequency bins are assigned for the reconstruction of the components $x^\\mathrm{h}$ and $x^\\mathrm{p}$, whereas more time–frequency bins are used for the reconstruction of the residual component $x^\\mathrm{r}$. Intuitively, the larger the parameter $\\beta$, the clearer becomes the harmonic and percussive nature of the components $x^\\mathrm{h}$ and $x^\\mathrm{p}$. For very large $\\beta$, the residual signal $x^\\mathrm{r}$ tends to contain the entire signal $x$. This role $\\beta$ is illustrated by the following experiment.\n", "\n", "\"FMP_C8_E05_HRP_beta\"\n", "\n", "
\n", "Warning: For audio playback, we use the class IPython.display.Audio, which normalizes the audio (dividing by the maximum over all sample values) before playback. Therefore, in the following experiments, separated signals may sound louder than they actually are (see also the notes on normalized audio playback).\n", "
" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "execution": { "iopub.execute_input": "2024-02-15T08:41:19.710309Z", "iopub.status.busy": "2024-02-15T08:41:19.710050Z", "iopub.status.idle": "2024-02-15T08:41:23.933219Z", "shell.execute_reply": "2024-02-15T08:41:23.932436Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "=============================================================\n", "Experiment for ../data/C8/FMP_C8_F02_Long_CastanetsViolinApplause.wav\n", "N=1024, H= 256, L_h_sec=0.20, L_p_Hz=500.0, beta=1.1\n", "N=1024, H= 256, L_h_sec=0.20, L_p_Hz=500.0, beta=2.0\n", "N=1024, H= 256, L_h_sec=0.20, L_p_Hz=500.0, beta=4.0\n", "N=1024, H= 256, L_h_sec=0.20, L_p_Hz=500.0, beta=32.0\n" ] }, { "data": { "text/html": [ "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
$N$$H$$L_h$ (sec)$L_p$ (Hz)$L_h$$L_p$$\\beta$$x$$x_h$$x_r$$x_p$
10242560.250018241.1
10242560.250018242.0
10242560.250018244.0
10242560.2500182432.0
" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "=============================================================\n", "Experiment for ../data/C8/FMP_C8_Audio_Bornemark_StopMessingWithMe-Excerpt_SoundCloud_mix.wav [[1024, 256, 0.2, 500, 1.1], [1024, 256, 0.2, 500, 2], [1024, 256, 0.2, 500, 4], [1024, 256, 0.2, 500, 32]]\n", "N=1024, H= 256, L_h_sec=0.20, L_p_Hz=500.0, beta=1.1\n", "N=1024, H= 256, L_h_sec=0.20, L_p_Hz=500.0, beta=2.0\n", "N=1024, H= 256, L_h_sec=0.20, L_p_Hz=500.0, beta=4.0\n", "N=1024, H= 256, L_h_sec=0.20, L_p_Hz=500.0, beta=32.0\n" ] }, { "data": { "text/html": [ "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
$N$$H$$L_h$ (sec)$L_p$ (Hz)$L_h$$L_p$$\\beta$$x$$x_h$$x_r$$x_p$
10242560.250018241.1
10242560.250018242.0
10242560.250018244.0
10242560.2500182432.0
" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "param_list = [\n", " [1024, 256, 0.2, 500, 1.1],\n", " [1024, 256, 0.2, 500, 2],\n", " [1024, 256, 0.2, 500, 4], \n", " [1024, 256, 0.2, 500, 32], \n", "]\n", "\n", "fn_wav = os.path.join('..', 'data', 'C8', 'FMP_C8_F02_Long_CastanetsViolinApplause.wav')\n", "print('=============================================================')\n", "print('Experiment for ',fn_wav)\n", "libfmp.c8.experiment_hrps_parameter(fn_wav, param_list)\n", "\n", "#fn_wav = os.path.join('..', 'data', 'C8', 'FMP_C8_Audio_Bearlin_Roads_Excerpt-85-99_SiSEC_mix.wav')\n", "fn_wav = os.path.join('..', 'data', 'C8', 'FMP_C8_Audio_Bornemark_StopMessingWithMe-Excerpt_SoundCloud_mix.wav')\n", "print('=============================================================')\n", "print('Experiment for ',fn_wav, param_list)\n", "libfmp.c8.experiment_hrps_parameter(fn_wav, param_list) " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Cascaded HRPS\n", "\n", "The HRPS procedure can be further extended. For example, López-Serrano et al. introduced a **cascaded harmonic–residual–percussive** (CHRPS) procedure. First, using a large separation factor (e.g., $\\beta=5$), a signal is separated into harmonic (H), residual (R), and percussive (P) components. Then, using a smaller separation factor (e.g., $\\beta=3$), the residual component of the first stage is further composed. More generally, using $B\\in\\mathbb{R}$ cascading stages with decreasing separation factors $\\beta_1 > \\beta_2 > \\ldots >\\beta_B$, the CHRP procedure produces $(2B+1)$ component signals—their sum being equal to the input signal $x$ (up to a small error). Once all the required cascading stages are complete, the component signals are sorted on an axis that goes from harmonic, through residual, to percussive. The next figure illustrates this procedure using $B = 3$. In this case, the CHRP procedure produces seven component signals referred to as H, RH, RRH, RRR, RRP, RP, and P. \n", "\n", "\"FMP_C8_E05_CHRP_Ex-Snare\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## CHRP Features\n", "\n", "Motivated by tasks such as **musical event density** and [**music structure analysis**](../C4/C4S1_MusicStructureGeneral.html), we now introduce a mid-level feature representation. To this end, we compute the local energy for each of the $2B+1$ component signals using a sliding window technique. To this end, we use a window of length $N\\in\\mathbb{N}$ and hop size $H\\in\\mathbb{N}$ . Let $M\\in\\mathbb{N}$ be the number of energy frames. We then stack the local energy values of all component signal into a feature matrix $V=(v_1,\\ldots,v_M)$ such that $v_m\\in\\mathbb{R}^{2B+1}$, for $m\\in[1:M]$. Furthermore, the columns $v_m$ may be [normalized using, e.g., the $\\ell^1$-norm](../C3/C3S1_FeatureNormalization.html). Then each $v_m\\in[0,1]^{2B+1}$ expresses the energy distribution across the components for each frame $m\\in[1:M]$.\n", "\n", "In the following example, we show the CHRP feature matrix for a signal consisting of five non-overlapping sound samples: castanets, snare roll, applause, staccato strings and legato violin. The castanets have the highest percussive energy and are well confined to the P component. The snare roll is predominantly composed of RP and RRR. Indeed, snare drums have a percussive attack and a decay curve which is both noisy and tonal (according to the drum's tuning frequency). When struck in rapid succession, the noisy decay tails overpower the percussive onsets. Applause is centered around RRR and well-confined to the residual region. The staccato strings are predominantly harmonic, with an additional RH component which corresponds to the noisy attacks that emerge in this playing technique. Violin legato is confined to the H component, since the stable, harmonic signal properties dominate all other components.\n", "\n", "\"FMP_C8_E05_CHRP_Ex-Ramp\"\n", "\n", "
\n", "\n", "\n", "\n", "The next example shows energy migrating from percussive to residual in a snare-playing technique known as **paradiddles**. In the next figure, we show the waveform of paradiddles played on a snare drum; first with increasing speed ($0$-$40$ sec), and then with decreasing speed ($40$-$75$ sec). In the resulting CHRP feature matrix, one can notice how there is very little remaining P-energy after a certain onset frequency or playing speed has been reached (around $25$ sec). This is due to the fact that the noise-like tails reach a relative proximity and overpower the individual percussive onsets, centering the energy around the residual components in the feature matrix.\n", "\n", "\"FMP_C8_E05_CHRP_Ex-Snare\"\n", "\n", "
\n", "\n", "\n", "\n", "For further sound examples and details, we refer to the [demo website for cascaded HRPS](https://www.audiolabs-erlangen.de/resources/MIR/2017-AES-CHRP) ." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Further Notes\n", "\n", "One finds further instructive examples and links to the research literature in the [FMP notebook on applications of HPS and HRPS](../C8/C8S1_HPS-Application.html)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "Acknowledgment: This notebook was created by Meinard Müller, Frank Zalkow, and Patricio López-Serrano.
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "\n", "
\"C0\"\"C1\"\"C2\"\"C3\"\"C4\"\"C5\"\"C6\"\"C7\"\"C8\"
" ] } ], "metadata": { "anaconda-cloud": {}, "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.16" } }, "nbformat": 4, "nbformat_minor": 1 }