from jyquickhelper import add_notebook_menu
add_notebook_menu()

"""
Explanation: 1A.1 - Liste, tuple, ensemble, dictionnaire, liste chaînée, coût des opérations
Exemples de containers, list, tuple, set, dict.
End of explanation
"""


import time, collections
N = 1000000

for p in range(0,3):
    print("passage ", p)
    print("  insertion en fin")

    li = list()
    a = time.perf_counter()
    for i in range(0,N) :
        li.append(i)
    b = time.perf_counter()
    print("    list", N, "éléments, temps par éléments :", (b-a)/N)    
        
    li = collections.deque()
    a = time.perf_counter()
    for i in range(0,N) :
        li.append(i)
    b = time.perf_counter()
    print("    deque", N, "éléments, temps par éléments :", (b-a)/N)    
    
    print("  insertion au début")
    li = collections.deque()
    a = time.perf_counter()
    for i in range(0,N) :
        li.appendleft(i)
    b = time.perf_counter()
    print("    deque", N, "éléments, temps par éléments :", (b-a)/N)    
    
    N2 = N // 100
    li = list()
    a = time.perf_counter()
    for i in range(0,N2) :
        li.insert(0,i)
    b = time.perf_counter()
    print("    list", N, "éléments, temps par éléments :", (b-a)/N)   

"""
Explanation: Python propose différents containers pour stocker des éléments. Voici les plus courants :

list : tableau d'éléments indexés de 0 à $n$ exclu auquel on peut ajouter ou retirer des éléments
dict : tableau d'éléments indexés par des types immuables auquel on peut ajouter ou retirer des éléments
tuple : tableau d'éléments indexés de 0 à $n$ exclu qu'on ne peut pas modifier
set : tableau d'éléments uniques non indexés
frozenset : set immuables (non modifiable)
deque : presque équivalent à une listes, la différent vient de l'implémentation, les mêmes opérations n'auront pas les mêmes coûts (deque = liste chaînée)

D'autres containers sont disponibles via le module collections. Tous proposent de stocker un nombre variables d'éléments. Deux aspects difféèrent :

la façon de désigner un élément de l'ensemble
le coût de certaines opérations, il faut choisir qui minisera le coût des opérations pour votre programme

Insertion avec list et deque
On veut comparer les coûts d'insertion en début et fin de liste pour un grand nombre d'éléments.
End of explanation
"""


import time, collections
N = 100000
lens = list(range(0,1000))
tens = tuple(lens)
sens = set(lens)
fens = frozenset(lens)

for p in range(0,3):
    print("passage",p)
    a = time.perf_counter()
    s = 0
    for i in range(0,N) :
        if i in lens : s += 1
    b = time.perf_counter()
    print("  list", N, "fois, temps par éléments :", (b-a)/N)    
    
    a = time.perf_counter()
    s = 0
    for i in range(0,N) :
        if i in tens : s += 1
    b = time.perf_counter()
    print("  tuple", N, "fois, temps par éléments :", (b-a)/N)    
    
    a = time.perf_counter()
    s = 0
    for i in range(0,N) :
        if i in sens : s += 1
    b = time.perf_counter()
    print("  set", N, "fois, temps par éléments :", (b-a)/N)    
    
    a = time.perf_counter()
    s = 0
    for i in range(0,N) :
        if i in fens : s += 1
    b = time.perf_counter()
    print("  frozenset", N, "fois, temps par éléments :", (b-a)/N)    

"""
Explanation: On voit que l'insertion au début du tableau est beaucoup plus coûteuse pour une liste que pour un deque.
Un élément dans un ensemble
Faut-il écrire i in [0,1] ou i in (0,1) ou ... Essayons.
End of explanation
"""


