# # Chapitre 8 - Activité 2 - Réseau social simple # class Personne: def __init__(self, nom, annee_naissance): self.nom = nom self.annee_naissance = annee_naissance self.relations = {} # clés : noms, valeurs : année de début de la relation def __repr__(self): """ La fonction appelée par `print` """ texte = f"Personne '{self.nom}' née en {self.annee_naissance}" if len(self.relations) > 0: texte += ", connait :" for nom, annee in self.relations.items(): texte += f"\n • {nom} depuis {annee}" return texte donnees_personnes = { "Rafael": 1994, "Stéphanie": 1980, "Dinesh": 1980, "Margot": 1987, "Sofiane": 1985, "Lucia": 1988, "Antti": 1979, "Johanna": 1980, "Ahmed": 1986, "Didier": 1971, "Chimène": 1984, "Marc": 1980, "Charles": 1991, "Antoine": 1991, "Maurice": 1992, "Samuli": 1989, "Marlène": 1980, "Carl": 1986 } exemple_reseau = { nom: Personne(nom, annee) for nom, annee in donnees_personnes.items() } donnees_liens = { ('Rafael', 'Margot'): 2021, ('Dinesh', 'Antti'): 1998, ('Margot', 'Lucia'): 2022, ('Margot', 'Ahmed'): 2004, ('Margot', 'Didier'): 2011, ('Antti', 'Samuli'): 1999, ('Chimène', 'Carl'): 2011, ('Charles', 'Antoine'): 2021, ('Samuli', 'Marlène'): 2020, ('Stéphanie', 'Dinesh'): 2003, ('Margot', 'Sofiane'): 2020, ('Margot', 'Johanna'): 2021, ('Margot', 'Charles'): 2021, ('Ahmed', 'Maurice'): 2008, ('Didier', 'Charles'): 2004, ('Marc', 'Chimène'): 2000, ('Chimène', 'Marlène'): 1992, ('Antoine', 'Maurice'): 1999, ('Marlène', 'Carl'): 2010, } for lien, annee in donnees_liens.items(): nom1 = lien[0] nom2 = lien[1] p1 = exemple_reseau[nom1] p2 = exemple_reseau[nom2] if (nom1 in p2.relations) or (nom2 in p1.relations): print(f"/!\\ Attention, la relation {nom1} - {nom2} existe déjà !") if (annee < p1.annee_naissance): raise ValueError(f"L'année de relation {annee} est antérieure à la naissance de {nom1} ({p1.annee_naissance}) !") if (annee < p2.annee_naissance): raise ValueError(f"L'année de relation {annee} est antérieure à la naissance de {nom2} ({p2.annee_naissance}) !") p1.relations[nom2] = annee p2.relations[nom1] = annee from datetime import date def duree_relation(p1, p2): annee = p1.relations.get(p2.nom, None) if annee is None: return None return date.today().year - annee def plus_ancienne_relation(personnes): plus_ancienne_relation = None gens = None for p1 in personnes: for p2 in personnes: if p1.nom == p2.nom: continue d = duree_relation(p1, p2) if plus_ancienne_relation is None or (d is not None and d > plus_ancienne_relation): plus_ancienne_relation = d gens = (p1, p2) return gens # print(plus_ancienne_relation(exemple_reseau.values())) def plus_de_relations(personnes): return max(personnes, key=lambda p: len(p.relations)) # print(plus_de_relations(exemple_reseau.values())) def search(personnes, personne, target, depth=1): if depth > len(personnes): return None if target in personne.relations: return depth distances = [search(personnes, personnes[relation], target, depth+1) for relation in personne.relations] distances = [distance for distance in distances if distance is not None] if distances: return min(distances) def search(personnes, personne, target, depth=1): # Condition d'arret if depth > len(personnes): return None if target in personne.relations: return depth, [personne, personnes[target]] # On appelle récursivement pour toutes les relations distances = [] for relation in personne.relations: other = personnes[relation] distance = search(personnes, other, target, depth + 1) if distance is not None: distances.append(distance) # Autre méthode # distances = [search(personnes, personnes[relation], target, depth + 1) for relation in personne.relations] # distances = [distance for distance in distances if distance is not None] # On trouve la liaison la plus courte if distances: distance, personnes = min(distances, key=lambda d: d[0]) return distance, [personne] + personnes distance, personnes = search(exemple_reseau, exemple_reseau["Marc"], "Stéphanie") print(f"La relation la plus courte entre Marc est Stéphanie est de {distance} relations:") for personne in personnes: print(f" - {personne}") # On vérifie si des personnes ne sont pas reliées checked = [] for personne in exemple_reseau.values(): for other in exemple_reseau.values(): if personne == other: continue two = sorted([personne.nom, other.nom]) if two in checked: continue checked.append(two) if search(exemple_reseau, personne, other.nom) is None: print(f"{personne.nom} et {other.nom} n'ont pas de liaison possible")