Review 8

'''!
    @brief: Delete duplicates in a list without changing the first list
    @param: l: list

    @return: list without duplicates
'''
def dedup(l):
    return list(set(l))

'''!
    @brief: Create a list of numbers from 1 to n that are multiples of 5 or 7
    @param: n: int

    @return: list of numbers from 1 to n that are multiples of 5 or 7
'''
def multiple(n):
    return [i for i in range(1, n+1) if i % 5 == 0 or i % 7 == 0]

'''!
    @brief: Get index of elements in a list that are multiples of 5 or 7
    @param: l: list

    @return: list of index
'''
def arg_multiple(l):
    return [i for i in range(len(l)) if l[i] % 5 == 0 or l[i] % 7 == 0]

'''!
    @brief: Zip two lists
    @param: l1 list
    @param: l2 list
    
    @return list of tuples
'''
def zipping(l1, l2):
    return [(a, b) for a in l1 for b in l2]

'''!pythagoras_triples.__doc__
    @param: m matrix
    
    @return transposed matrix
'''
def transpose(m):
    return [[m[j][i] for j in range(len(m))] for i in range(len(m[0]))]

'''!
    @brief: Get the elements in a matrix
    @param: m matrix
    
    @return set of elements
'''
def elems(m):
    return {a for l in m for a in l}


def pythagoras_triples(n):
    '''!
    @brief: Find the Pythagoras triples in a range
    @param: n int

    @return list of Pythagoras triples
    '''
    return [(a, b, c) for a in range(1, n) for b in range(a, n) for c in range(b, n) if a**2 + b**2 == c**2]

if __name__ == "__main__":
   print(pythagoras_triples(20))

[(3, 4, 5), (5, 12, 13), (6, 8, 10), (8, 15, 17), (9, 12, 15)]
pythagoras_triples.__doc__
'!\n    @brief: Find the Pythagoras triples in a range\n    @param: n int\n\n    @return list of Pythagoras triples\n    '
'''!
    @brief Function that reads a file and returns a set of words that should be ignored.
    @param filename File to read.

    @return Set of words that should be ignored.
'''
def filtre(filename: str) -> {str}:
    try:
        f = open(filename, "r")
        l = f.read().split('\n')
        f.close()
        return set(l)
    except:
        return set()

def dedup (l) : 
    return list(set(l))
# Test 



### Exercice 2 : 

def multiple (n) : return [i for i in range(n) if i % 5 == 0 or i % 7 == 0]

def arg_multiple(l) : return [i for i in range(n) if l[i] % 5 == 0 or l[i]%7 == 0]

m = [[1,2,3],
     [4,5,6],
     [7,8,9]]


def zipping (l_a, l_b) : return [(l_a[i], l_b[i]) for i in range(min(len(l_a), len(l_b)))]


print (zipping (m[0], m[1]))

def transpose (m) : return [ [m[j][i] for i in range(len(m))] for j in range(len(m)) ]

def elems(m) : return list(set(element for row in m for element in row))

print(elems(m)) 

def pythagoras_triples(n) : return [(j,i,k) for i in range(1,n) for j in range(1,i) for k in range(1,n) if i**2 + j**2 == k**2]

print (pythagoras_triples(100))

## Exercice 3 


#!/usr/bin/env python3

import sys

def load_filter_words(filter_file_path):
    """Charge les mots à ignorer depuis un fichier."""
    with open(filter_file_path, 'r') as f:
        return set(line.strip() for line in f)

def words(file_object, filter_words=None):
    """Compte les mots dans le fichier, en ignorant les mots du fichier de filtrage."""
    word = ""
    word_counts = {}
    for line in file_object:
        for elt in line:
            if elt.isspace():
                if word:
                    # Ignorer les mots de la liste de filtrage
                    if filter_words is None or word not in filter_words:
                        if word in word_counts:
                            word_counts[word] += 1
                        else:
                            word_counts[word] = 1
                    word = ""
            else:
                word += elt
        # Compter le dernier mot si présent
        if word and (filter_words is None or word not in filter_words):
            if word in word_counts:
                word_counts[word] += 1
            else:
                word_counts[word] = 1
            word = ""
    return word_counts

def sorted_by_count(word_counts, n, rarest=False):
    """Trie les mots par fréquence et retourne les n premiers en fonction du tri."""
    return sorted(word_counts.items(), key=lambda x: x[1], reverse=not rarest)[:n]

if __name__ == "__main__":
    if len(sys.argv) < 3:
        print("Usage: lexicon.py [-r] n path/to/some/file.txt [path/to/filter_file.txt]")
        sys.exit(1)

    # Initialiser les variables de configuration
    rarest = False
    filter_file_path = None

    # Vérification des arguments et initialisation
    arg_index = 1
    if sys.argv[arg_index] == "-r":
        rarest = True
        arg_index += 1

    n = int(sys.argv[arg_index])
    file_path = sys.argv[arg_index + 1]

    # Charger le fichier de filtrage si un chemin est donné
    if len(sys.argv) > arg_index + 2:
        filter_file_path = sys.argv[arg_index + 2]
        filter_words = load_filter_words(filter_file_path)
    else:
        filter_words = None

    # Lecture du fichier de texte et comptage des mots
    with open(file_path, 'r') as file:
        word_counts = words(file, filter_words)

    # Récupération des n mots les plus fréquents ou les plus rares
    words_to_display = sorted_by_count(word_counts, n, rarest)

    # Affichage des résultats
    for word, count in words_to_display:
        print(f"{word}: {count}")

#!/usr/bin/env python3

import sys

# Renvoie le dictionnaire {mot : nombre d'occurences}
# des mots apparaissant dans f
def words(f, ignore):
    D = {}
    for x in f.read().split():
        if x not in D:
            D[x] = 0
        D[x] += 1
    return D

# Renvoie la liste triée par nombre d'occurence (décroissant de base)
# des couples (mot, occurences) obtenus à partir du dictionnaire D.
# r booléen tel que, si r vaut False, l'ordre soit effectivement décroissant,
# et si r vaut True, l'ordre est croissant.
def sorted_by_count(D, r = False):
    def n_occurence(c):
        return c[1]

    l = [(x, D[x]) for x in D]
    l.sort(reverse = not r, key = n_occurence)
    return l

# Obtient les mots à ignorer à partir du fichier indiqué par path_ignore
def getignore(f):
    return f.read.split()

# Travaille sur les arguments fournis pour obtenir une valeur utilisable
# par les fonctions définies plus tôt
def getargs(argv):
    n = int(argv[0])
    path = argv[1]

    if len(argv) >= 3:
        if argv[2] == "-r":
            ignore = []
            r = True
        else:
            path_ignore = argv[2]
            with open(path_ignore, "r") as f:
                ignore = getignore(f)

            if len(argv) >= 4 and argv[3] == "-r":
                r = True
            else:
                r = False
    else:
        ignore = []
        r = False

    return n, path, ignore, r

# Prend en argument un entier n, un chemin vers un fichier texte path et éventuellement path_ignore et "-r",
# et renvoie la liste des n mots les plus fréquents de path (les moins fréquents si -r est présent),
# en excluant du compte les mots de path_ignore si path_ignore est précisé.
if __name__ == '__main__':
    n, path, ignore, r = getargs(argv)

    with open(path, "r") as f:
        l = sorted_by_count(words(f, ignore), r)
        for c in l:
            print(c[0])