# coding: utf8
"""
Module de calcul des nombres parfaits et chanceux.

Définitions :
  - On appelle *nombre premier* tout entier naturel supérieur à 1 qui possède
    exactement deux diviseurs, lui-même et l'unité ;
  - On appelle *diviseur propre* de 'n' un diviseur quelconque de 'n', 'n' exclu ;
  - Un entier naturel est dit *parfait* s'il est égal à la somme de tous ses 
    diviseurs propres ;
  - Un entier 'n' tel que 'n + i + i+i' est premier pour tout i dans [0, n−2] 
    est dit *premier chanceux*.

Écrire un fichier parfait_chanceux_m.py définissant quatre fonctions som_div(),
  est_parfait(), est_premier(), est_chanceux() et un auto-test :
  - La fonction som_div() retourne la somme des diviseurs propres de son paramètre ;
  - Les trois autres fonctions vérifient que leur paramètre possède la propriété 
    éponyme de la fonction et retournent un booléen. Si par exemple la fonction 
    est_premier() vérifie que son paramètre est premier, elle retourne 'True',
    sinon elle retourne 'False'.
    
L'auto-test doit vérifier que :
  - som_div(12) vaut 16
  - les appels : est_parfait(6), est_premier(31) et est_chanceux(11) retournent 'True'.
  
fichier : parfait_chanceux_m.py
auteur : Bob
"""

# Définition de fonction ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def som_div(n):
    """Retourne la somme des diviseurs propres de <n>."""
    som_div = 1
    for div in range(2, (n//2)+1):
        if n % div == 0:
            som_div += div
    return som_div

def est_parfait(n):
    """Retourne True si <n> est *parfait*, False sinon."""
    return som_div(n) == n

def est_premier(n):
    """Retourne True si <n> est *premier*, False sinon."""
    return som_div(n) == 1

def est_chanceux(n):
    """Retourne True si <n> est *premier-chanceux*, False sinon."""
    est_chanceux = True
    for i in range(0, n-1):
        est_chanceux = est_chanceux and est_premier(n + i + i**2)
    return est_chanceux

# Auto-test ===================================================================
if __name__=='__main__':
    print(som_div(12) == 16)
    print(est_parfait(6))
    print(est_premier(31))
    print(est_chanceux(11))
    
