diff --git a/module3/exo1/analyse-syndrome-grippal.ipynb b/module3/exo1/analyse-syndrome-grippal.ipynb index 59d72b5b58a3ae26346460dd39e62a39c55243d7..4933e016e5d0241312815f3bee24f6b3e7bfad67 100644 --- a/module3/exo1/analyse-syndrome-grippal.ipynb +++ b/module3/exo1/analyse-syndrome-grippal.ipynb @@ -364,7 +364,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.6.1" + "version": "3.6.4" } }, "nbformat": 4, diff --git a/module3/exo2/exercice.ipynb b/module3/exo2/exercice.ipynb index 0bbbe371b01e359e381e43239412d77bf53fb1fb..85494b469e1fc84ca7c0de77b3a96940f3783687 100644 --- a/module3/exo2/exercice.ipynb +++ b/module3/exo2/exercice.ipynb @@ -1,6 +1,1206 @@ { - "cells": [], + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "hideCode": true, + "hidePrompt": true + }, + "source": [ + "# varicelle" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hideCode": true, + "hidePrompt": true + }, + "source": [ + "Les données de l'incidence la varicelle sont disponibles du site Web du Réseau Sentinelles. Nous les récupérons sous forme d'un fichier en format CSV dont chaque ligne correspond à une semaine de la période demandée. Nous téléchargeons toujours le jeu de données complet, qui commence en 1999 semaine 49 et se termine avec une semaine récente : 2022 semaine 6.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "hideCode": true, + "hidePrompt": true + }, + "outputs": [], + "source": [ + "%matplotlib inline\n", + "import matplotlib.pyplot as plt\n", + "import pandas as pd\n", + "import isoweek" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "hideCode": true, + "hidePrompt": true + }, + "outputs": [], + "source": [ + "data_url = \"http://www.sentiweb.fr/datasets/incidence-PAY-7.csv\"" + ] + }, + { + "cell_type": "raw", + "metadata": { + "hideCode": true, + "hidePrompt": true + }, + "source": [ + "La première ligne du fichier CSV est un commentaire, que nous ignorons en précisant `skiprows=1`." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "hideCode": true, + "hidePrompt": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "pandas.core.frame.DataFrame" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "raw_data = pd.read_csv(data_url, skiprows=1)\n", + "type(raw_data)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "hideCode": true, + "hidePrompt": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "1628" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(raw_data)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "hideCode": true, + "hidePrompt": true + }, + "outputs": [ + { + "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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
weekindicatorincinc_lowinc_upinc100inc100_lowinc100_upgeo_inseegeo_name
0202206710414712813700161121FRFrance
1202205710866775813974161121FRFrance
220220479547672112373141018FRFrance
32022037139721068017264211626FRFrance
42022027849560261096413917FRFrance
\n", + "
" + ], + "text/plain": [ + " week indicator inc inc_low inc_up inc100 inc100_low inc100_up \\\n", + "0 202206 7 10414 7128 13700 16 11 21 \n", + "1 202205 7 10866 7758 13974 16 11 21 \n", + "2 202204 7 9547 6721 12373 14 10 18 \n", + "3 202203 7 13972 10680 17264 21 16 26 \n", + "4 202202 7 8495 6026 10964 13 9 17 \n", + "\n", + " geo_insee geo_name \n", + "0 FR France \n", + "1 FR France \n", + "2 FR France \n", + "3 FR France \n", + "4 FR France " + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "raw_data[:5]" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "hideCode": true, + "hidePrompt": true + }, + "outputs": [ + { + "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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
weekindicatorincinc_lowinc_upinc100inc100_lowinc100_upgeo_inseegeo_name
16231991017155651027120859271836FRFrance
16241990527193751329525455342345FRFrance
16251990517190801380724353342543FRFrance
1626199050711079666015498201228FRFrance
16271990497114302610205FRFrance
\n", + "
" + ], + "text/plain": [ + " week indicator inc inc_low inc_up inc100 inc100_low \\\n", + "1623 199101 7 15565 10271 20859 27 18 \n", + "1624 199052 7 19375 13295 25455 34 23 \n", + "1625 199051 7 19080 13807 24353 34 25 \n", + "1626 199050 7 11079 6660 15498 20 12 \n", + "1627 199049 7 1143 0 2610 2 0 \n", + "\n", + " inc100_up geo_insee geo_name \n", + "1623 36 FR France \n", + "1624 45 FR France \n", + "1625 43 FR France \n", + "1626 28 FR France \n", + "1627 5 FR France " + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "raw_data[-5:]" + ] + }, + { + "cell_type": "raw", + "metadata": { + "hideCode": true, + "hidePrompt": true + }, + "source": [ + "Y a-t-il des points manquants dans ce jeux de données ? Non" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "hideCode": true, + "hidePrompt": true + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
weekindicatorincinc_lowinc_upinc100inc100_lowinc100_upgeo_inseegeo_name
\n", + "
" + ], + "text/plain": [ + "Empty DataFrame\n", + "Columns: [week, indicator, inc, inc_low, inc_up, inc100, inc100_low, inc100_up, geo_insee, geo_name]\n", + "Index: []" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "raw_data[raw_data.isnull().any(axis=1)]" + ] + }, + { + "cell_type": "raw", + "metadata": { + "hideCode": true, + "hidePrompt": true + }, + "source": [ + "copie des donnés raw_data dans data, sans filtrage car il n'y a pas de données manquantes" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "hideCode": true, + "hidePrompt": true + }, + "outputs": [], + "source": [ + "data = raw_data.copy()" + ] + }, + { + "cell_type": "raw", + "metadata": { + "hideCode": true, + "hidePrompt": true + }, + "source": [ + "Nos données utilisent une convention inhabituelle: le numéro de semaine est collé à l'année, donnant l'impression qu'il s'agit de nombre entier. C'est comme ça que Pandas les interprète.\n", + "\n", + "Un deuxième problème est que Pandas ne comprend pas les numéros de semaine. Il faut lui fournir les dates de début et de fin de semaine. Nous utilisons pour cela la bibliothèque isoweek.\n", + "\n", + "Comme la conversion des semaines est devenu assez complexe, nous écrivons une petite fonction Python pour cela. Ensuite, nous l'appliquons à tous les points de nos donnés. Les résultats vont dans une nouvelle colonne 'period'.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "hideCode": true, + "hidePrompt": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "1628" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def convert_week(year_and_week_int):\n", + " year_and_week_str = str(year_and_week_int)\n", + " year = int(year_and_week_str[:4])\n", + " week = int(year_and_week_str[4:])\n", + " w = isoweek.Week(year, week)\n", + " return pd.Period(w.day(0), 'W')\n", + "\n", + "data['period'] = [convert_week(yw) for yw in data['week']]\n", + "len(data)" + ] + }, + { + "cell_type": "raw", + "metadata": { + "hideCode": true, + "hidePrompt": true + }, + "source": [ + "2 modifications à faire.\n", + "\n", + "Premièrement, nous définissons les périodes d'observation comme nouvel index de notre jeux de données. Ceci en fait une suite chronologique, ce qui sera pratique par la suite.\n", + "\n", + "Deuxièmement, nous trions les points par période, dans le sens chronologique.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "hideCode": true, + "hidePrompt": true + }, + "outputs": [ + { + "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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
weekindicatorincinc_lowinc_upinc100inc100_lowinc100_upgeo_inseegeo_nameperiod
0202206710414712813700161121FRFrance2022-02-07/2022-02-13
1202205710866775813974161121FRFrance2022-01-31/2022-02-06
220220479547672112373141018FRFrance2022-01-24/2022-01-30
32022037139721068017264211626FRFrance2022-01-17/2022-01-23
42022027849560261096413917FRFrance2022-01-10/2022-01-16
\n", + "
" + ], + "text/plain": [ + " week indicator inc inc_low inc_up inc100 inc100_low inc100_up \\\n", + "0 202206 7 10414 7128 13700 16 11 21 \n", + "1 202205 7 10866 7758 13974 16 11 21 \n", + "2 202204 7 9547 6721 12373 14 10 18 \n", + "3 202203 7 13972 10680 17264 21 16 26 \n", + "4 202202 7 8495 6026 10964 13 9 17 \n", + "\n", + " geo_insee geo_name period \n", + "0 FR France 2022-02-07/2022-02-13 \n", + "1 FR France 2022-01-31/2022-02-06 \n", + "2 FR France 2022-01-24/2022-01-30 \n", + "3 FR France 2022-01-17/2022-01-23 \n", + "4 FR France 2022-01-10/2022-01-16 " + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data[:5]" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "hideCode": true, + "hidePrompt": true + }, + "outputs": [ + { + "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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
weekindicatorincinc_lowinc_upinc100inc100_lowinc100_upgeo_inseegeo_nameperiod
16231991017155651027120859271836FRFrance1990-12-31/1991-01-06
16241990527193751329525455342345FRFrance1990-12-24/1990-12-30
16251990517190801380724353342543FRFrance1990-12-17/1990-12-23
1626199050711079666015498201228FRFrance1990-12-10/1990-12-16
16271990497114302610205FRFrance1990-12-03/1990-12-09
\n", + "
" + ], + "text/plain": [ + " week indicator inc inc_low inc_up inc100 inc100_low \\\n", + "1623 199101 7 15565 10271 20859 27 18 \n", + "1624 199052 7 19375 13295 25455 34 23 \n", + "1625 199051 7 19080 13807 24353 34 25 \n", + "1626 199050 7 11079 6660 15498 20 12 \n", + "1627 199049 7 1143 0 2610 2 0 \n", + "\n", + " inc100_up geo_insee geo_name period \n", + "1623 36 FR France 1990-12-31/1991-01-06 \n", + "1624 45 FR France 1990-12-24/1990-12-30 \n", + "1625 43 FR France 1990-12-17/1990-12-23 \n", + "1626 28 FR France 1990-12-10/1990-12-16 \n", + "1627 5 FR France 1990-12-03/1990-12-09 " + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data[-5:]" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "hideCode": true, + "hidePrompt": true + }, + "outputs": [], + "source": [ + "sorted_data = data.set_index('period').sort_index()" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "hideCode": true, + "hidePrompt": true + }, + "outputs": [ + { + "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", + " \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", + "
weekindicatorincinc_lowinc_upinc100inc100_lowinc100_upgeo_inseegeo_name
period
1990-12-03/1990-12-091990497114302610205FRFrance
1990-12-10/1990-12-16199050711079666015498201228FRFrance
1990-12-17/1990-12-231990517190801380724353342543FRFrance
1990-12-24/1990-12-301990527193751329525455342345FRFrance
1990-12-31/1991-01-061991017155651027120859271836FRFrance
\n", + "
" + ], + "text/plain": [ + " week indicator inc inc_low inc_up inc100 \\\n", + "period \n", + "1990-12-03/1990-12-09 199049 7 1143 0 2610 2 \n", + "1990-12-10/1990-12-16 199050 7 11079 6660 15498 20 \n", + "1990-12-17/1990-12-23 199051 7 19080 13807 24353 34 \n", + "1990-12-24/1990-12-30 199052 7 19375 13295 25455 34 \n", + "1990-12-31/1991-01-06 199101 7 15565 10271 20859 27 \n", + "\n", + " inc100_low inc100_up geo_insee geo_name \n", + "period \n", + "1990-12-03/1990-12-09 0 5 FR France \n", + "1990-12-10/1990-12-16 12 28 FR France \n", + "1990-12-17/1990-12-23 25 43 FR France \n", + "1990-12-24/1990-12-30 23 45 FR France \n", + "1990-12-31/1991-01-06 18 36 FR France " + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "sorted_data[:5]" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "hideCode": true, + "hidePrompt": true + }, + "outputs": [ + { + "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", + " \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", + "
weekindicatorincinc_lowinc_upinc100inc100_lowinc100_upgeo_inseegeo_name
period
2022-01-10/2022-01-162022027849560261096413917FRFrance
2022-01-17/2022-01-232022037139721068017264211626FRFrance
2022-01-24/2022-01-3020220479547672112373141018FRFrance
2022-01-31/2022-02-06202205710866775813974161121FRFrance
2022-02-07/2022-02-13202206710414712813700161121FRFrance
\n", + "
" + ], + "text/plain": [ + " week indicator inc inc_low inc_up inc100 \\\n", + "period \n", + "2022-01-10/2022-01-16 202202 7 8495 6026 10964 13 \n", + "2022-01-17/2022-01-23 202203 7 13972 10680 17264 21 \n", + "2022-01-24/2022-01-30 202204 7 9547 6721 12373 14 \n", + "2022-01-31/2022-02-06 202205 7 10866 7758 13974 16 \n", + "2022-02-07/2022-02-13 202206 7 10414 7128 13700 16 \n", + "\n", + " inc100_low inc100_up geo_insee geo_name \n", + "period \n", + "2022-01-10/2022-01-16 9 17 FR France \n", + "2022-01-17/2022-01-23 16 26 FR France \n", + "2022-01-24/2022-01-30 10 18 FR France \n", + "2022-01-31/2022-02-06 11 21 FR France \n", + "2022-02-07/2022-02-13 11 21 FR France " + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "sorted_data[-5:]" + ] + }, + { + "cell_type": "raw", + "metadata": { + "hideCode": true, + "hidePrompt": true + }, + "source": [ + "Nous vérifions la cohérence des données. Entre la fin d'une période et le début de la période qui suit, la différence temporelle doit être zéro, ou au moins très faible. Nous laissons une \"marge d'erreur\" d'une seconde.\n", + "Normalement il n'y aura rien." + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "hideCode": true, + "hidePrompt": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "cpt = 0\n" + ] + } + ], + "source": [ + "periods = sorted_data.index\n", + "cpt = 0\n", + "for p1, p2 in zip(periods[:-1], periods[1:]):\n", + " delta = p2.to_timestamp() - p1.end_time\n", + " if delta > pd.Timedelta('1s'):\n", + " print(p1, p2)\n", + "print(f'cpt = {cpt}')" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": { + "hideCode": true, + "hidePrompt": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Period('2022-01-31/2022-02-06', 'W-SUN')" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "p1" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true, + "hideCode": true, + "hideOutput": true, + "hidePrompt": true + }, + "outputs": [], + "source": [] + } + ], "metadata": { + "hide_code_all_hidden": true, "kernelspec": { "display_name": "Python 3", "language": "python", @@ -16,10 +1216,9 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.6.3" + "version": "3.6.4" } }, "nbformat": 4, "nbformat_minor": 2 } -