Baccalauréat — Épreuve pratique — 2026 — NSI
Épreuve pratique NSI 2026 — Sujet 02 (sujet zéro 2) : analyse d'écarts de salaires
Sujet
Épreuve pratique d'une heure sur ordinateur. Le candidat dispose de l'énoncé et de fichiers de code et de données. Il agit en autonomie ; aux « appels professeur » indiqués dans le sujet, il présente son travail à l'examinateur ou le sollicite en cas de difficulté.
Ce sujet zéro est devenu le sujet n°02 de la banque nationale 2026 de l'épreuve pratique. Le texte est le même, à la présentation près ; la banque harmonise en outre le nom de la fonction (calcul_ecart_sexe partout) et la clé des hommes ('M' partout), les deux incohérences signalées dans le corrigé.
Analyse d'écarts de salaires
Des écarts de salaires subsistent entre les femmes et les hommes, même à poste équivalent : en France, l'écart de salaire moyen est encore d'environ 15 % en 2023 selon l'INSEE.
Pour observer cet écart et ses conséquences, on dispose de jeux de données représentant les employés d'une entreprise. Chaque jeu de données est une liste de dictionnaires ; chaque dictionnaire représente un employé, avec les champs suivants :
'experience'(int, en années, l'expérience professionnelle) ;'etudes'(int, en années, le nombre d'années d'études après le baccalauréat) ;'sexe'(str,'F'ou'M') ;'salaire'(int, en euros).
Deux jeux de données sont fournis : un jeu de test dans le fichier donnees.py, reproduit ci-dessous, et un jeu plus complet de 2000 employés dans le fichier donnees_completes.py.
employes = [
{'experience': 5, 'etudes': 3, 'sexe': 'F', 'salaire': 2400},
{'experience': 3, 'etudes': 3, 'sexe': 'M', 'salaire': 2550},
{'experience': 5, 'etudes': 5, 'sexe': 'F', 'salaire': 2500},
{'experience': 3, 'etudes': 5, 'sexe': 'M', 'salaire': 2800},
{'experience': 2, 'etudes': 5, 'sexe': 'F', 'salaire': 2300},
{'experience': 2, 'etudes': 3, 'sexe': 'M', 'salaire': 2700}
]Le fichier analyse.py (reproduit plus bas) contient des éléments d'analyse de ces données, à compléter et à améliorer dans les questions suivantes.
1. Écrire le code de la fonction salaire_moyen_condition, qui prend en paramètres un tableau d'employés au format ci-dessus, le nom d'un des trois champs 'experience', 'etudes' ou 'sexe', et une valeur, et qui renvoie un flottant : le salaire moyen des employés dont le champ a la valeur fournie. La fonction renvoie None si aucun employé n'a cette valeur pour ce champ. Ainsi, salaire_moyen_condition(employes, 'sexe', 'F') renvoie le salaire moyen des femmes. Une fonction de test sur le jeu de test est fournie. Déterminer le salaire moyen des femmes et celui des hommes pour le jeu de données complet.
Appel 1 — Appeler le professeur pour lui présenter vos réponses et votre fonction, ou en cas de difficulté de compréhension de la représentation.
2. Écrire une fonction effectif_par_sexe qui prend en paramètre un tableau non vide d'employés et renvoie un dictionnaire associant à chaque sexe l'effectif correspondant. Avec le tableau employes précédent :
>>> effectif_par_sexe(employes)
{'F': 3, 'M': 3}Appel 2 — Appeler le professeur pour lui présenter votre fonction et son fonctionnement, ou en cas de difficultés.
On définit l'écart de salaire moyen en pourcentage par :
Une fonction de calcul de cet écart est écrite dans le fichier analyse.py.
3. Expliquer pourquoi le code de cette fonction est incorrect, et proposer quelques tests simples, sous forme d'assertions, qui mettent ces problèmes en évidence :
- vérifier que le résultat est
Nonequand un seul sexe est présent ; - vérifier qu'un écart de salaires exprimé en pourcentage est toujours compris entre 0 et 100.
Proposer une version corrigée de la fonction, qui valide ces tests et renvoie le bon écart. En déduire l'écart de salaire moyen dans les données complètes.
Appel 3 — Appeler le professeur pour lui présenter vos tests et la correction proposée.
4. Pour proposer un salaire d'embauche à un nouvel employé, le service informatique utilise l'algorithme des k plus proches voisins : la fonction salaire_par_proximite renvoie la moyenne des salaires des trois employés aux caractéristiques les plus proches. Tester et comparer les salaires proposés aux deux futurs employés suivants :
{'experience': 3, 'etudes': 3, 'sexe': 'F'}
{'experience': 3, 'etudes': 3, 'sexe': 'M'}Identifier dans le programme la source de l'écart entre les deux propositions, et la corriger.
Appel 4 — Appeler le professeur pour lui présenter vos tests, votre analyse des écarts et la correction proposée.
Fichier fourni : analyse.py
import donnees
import donnees_completes
from math import sqrt
def salaire_moyen_condition(employes, champ, valeur):
'''Renvoie le salaire moyen des employes ayant val comme valeur associée
au champ donné en argument.
Si le nombre d'employés considéré est nul, cette fonction renvoie None'''
pass # à implémenter
def test_salaire_moyen_condition():
e = donnees.employes
assert salaire_moyen_condition([], 'sexe', 'F') == None
assert salaire_moyen_condition(e, 'sexe', 'F') == 2400.0
assert salaire_moyen_condition(e, 'etudes', 3) == 2550.0
assert salaire_moyen_condition(e, 'etudes', 12) == None
def effectif_par_sexe(employes):
'''Renvoie un dictionnaire ayant deux clés 'F' et 'M'
associée respectivement au nombre d'employées femmes et au
nombre d'employés hommes dans les données en arguments.'''
pass # à implémenter
def test_effectif_par_sexe():
e = donnees.employes
assert effectif_par_sexe(e) == { 'F' : 3, 'M' : 3 }
def calcul_ecart_sexe(employes):
'''Renvoie l'écart de salaire en pourcentage pour les femmes
par rapport aux hommes'''
moy_h = salaire_moyen_condition(employes, 'sexe', 'M')
moy_f = salaire_moyen_condition('employes', 'sexe', 'F')
return moy_h - moy_f
# Attribution d'un premier salaire après embauche par les k plus proches voisins
def sexe_vers_entier(e):
if e['sexe'] == 'F':
return 1
else:
return -1
def distance(e1, e2):
'''Renvoie la mesure de distance entre deux personnes.'''
s = 0
s = s + (sexe_vers_entier(e1) - sexe_vers_entier(e2))**2
s = s + (e1['experience'] - e2['experience'])**2
s = s + (e1['etudes'] - e2['etudes'])**2
return sqrt(s)
def k_plus_proches(k, employes, e):
'''Renvoie les k employes les plus proches de e par la
distance définie au dessus.'''
e_d = [(distance(e, employes[i]), i) for i in range(len(employes))]
e_d.sort() # va trier en premier sur la distance
voisins = []
for i in range(k):
voisins.append(employes[e_d[i][1]])
return voisins
def salaire_moyen(employes):
'''Renvoie le salaire moyen pour une liste d'employes'''
if len(employes) == 0:
return None
s = sum(e['salaire'] for e in employes)
return s/len(employes)
def salaire_par_proximite(employes, e):
'''Prend en entrée une liste d'employés et un dictionnaire comportant
les champs experience, etudes et sexe et renvoie le salaire le plus
proche en moyennant les 3 plus proches voisins'''
voisins = k_plus_proches(3, employes, e)
return salaire_moyen(voisins)Le fichier donnees_completes.py définit de la même façon une liste employes de 2000 dictionnaires (984 femmes et 1016 hommes).
Corrigé
Créez un compte gratuit : votre première correction est offerte.