CCCPaste

huffmanmejorado

import os
from time import time

class Node: # declaracion de variables para crear los nodos
    # properties
    probability = 0.0 # inicializamos
    symbol = ""
    encoding = ""
    visited = False
    parent = -1 # longitud de 0 a -1

class Huffman: # declaracion de variables para la creacion del arbol de Huffman
    Tree = None # retornar arbol
    Root = None # retornar raiz
    Nodes = [] #Lista
    probs = {} #bloque
    dictEncoder = {}

    # methods
    def __init__(self, symbols):
        self.initNodes(symbols)
        self.buildTree()
        self.buildDictionary()

    def initNodes(self, probs): # creamos los nodos con sus respectivas probabiliddes
        for symbol in probs:
            node = Node() # inicializamos el node
            node.symbol = symbol
            node.probability = probs[symbol] # asignamos una probabilidad a cada simbolo o letra
            node.visited = False # variable q no es fija que va ir cambiando
            self.Nodes.append(node) # creamos una lista por cada nodo creado
            self.probs[symbol]=probs[symbol]  # establece para cada probabilidad un simbolo


    def buildTree(self): # Realizamos las operaciones de acuerdo al regamente para la construccion del arbol de Huffman
        indexMin1 = self.getNodeWithMinimumProb() # Buscamos el menor numero de la primera probabilidad
        indexMin2 = self.getNodeWithMinimumProb() # Buscamos el menor numero de la segunda probabilidad

        while indexMin1 != -1 and indexMin2 != -1: # != evalúa como verdadero si 2 variables son diferentes
            node = Node() # inicializamos
            node.symbol = "."
            node.encoding = ""
            # llamamos a las dos probabilidades minimas
            prob1 = self.Nodes[indexMin1].probability
            prob2 = self.Nodes[indexMin2].probability
            node.probability = prob1 + prob2 # sumamos las probabilidades
            node.visited = False # false = 1
            node.parent = -1 # restamos la probabilidad a -1
            self.Nodes.append(node)
            self.Nodes[indexMin1].parent = len(self.Nodes) - 1 #  lista o cadena que queremos medir
            self.Nodes[indexMin2].parent = len(self.Nodes) - 1

            # Regla: 0 a mayor probabilidad, 1 a menor probabilidad.
            if prob1 >= prob2:
                self.Nodes[indexMin1].encoding = "0"
                self.Nodes[indexMin2].encoding = "1"
            else:
                self.Nodes[indexMin1].encoding = "1"
                self.Nodes[indexMin2].encoding = "0"

            indexMin1 = self.getNodeWithMinimumProb()
            indexMin2 = self.getNodeWithMinimumProb()

    def getNodeWithMinimumProb(self): # realizamos una comparacion para obteener el nodo de menor probabilidad
        minProb = 1.0   # La minima probabilidad no puede ser mayor de 1
        indexMin = -1 # indice para restar a la probalidad

        for index in range(0, len(self.Nodes)): # index es el numero de probabilidad
            if (self.Nodes[index].probability < minProb  and
               (not self.Nodes[index].visited)):
                minProb = self.Nodes[index].probability
                indexMin = index

        if indexMin != -1:
            self.Nodes[indexMin].visited = True

        return indexMin

    def showSymbolEncoding(self, symbol): # designamos un codigo binario a cada simbolo resuelto por el arbol de Huffman
        found = False
        index = 0
        encoding = ""

        for i  in range(0, len(self.Nodes)):
            if self.Nodes[i].symbol == symbol:
                found = True
                index = i
                break

        if found: # encontro
            while index != -1: # si son diferentes
                encoding = "%s%s" % (self.Nodes[index].encoding, encoding)
                index = self.Nodes[index].parent
        else:
            encoding = "simbolo desconocido"

        return encoding

    def buildDictionary(self): # creamos un diccionario, guardamos todos los simbolos con sus respectivos codigos binarios
                               # resueltos por el arbol de Huffman
        for symbol in self.probs:
            encoding = self.showSymbolEncoding(symbol)
            self.dictEncoder[symbol] = encoding

    def encode(self, plain): # agrupa los codigos binarios codificados de acuerdo al mensaje escrito en consola
        encoded = ""
        for symbol in plain:
            encoded = "%s%s" % (encoded, self.dictEncoder[symbol])

        return encoded

    # INICIO DE LA DECODIFICACION ....................................................................................................................................................
    def decode(self, encoded): # recibe la cadena del codigo binario enviado desde el emisor para decodificar
        index = 0
        decoded = ""


        while index < len(encoded): # mientras buscamos en la longitud de la parte codificada


            founf = False # establesemos una variable

            aux = encoded[index:] # va a buscar a cada parte codificada un simbolo
                                  # no va ser fija va ir buscando cual es compatible con cada una


            for symbol in self.probs:
                if aux.startswith(self.dictEncoder[symbol]): # se comprueba si la cadena es verdadera o falsa. si la parte axuliar inicia dentro del diccionario encodificado  nos va a dar
                    decoded = "%s%s" % (decoded, symbol) # parte decodificada
                    index = index + len(self.dictEncoder[symbol]) # busqueda para cada simbolo a cada probabilidad
                    break

        return decoded

    #FIN DE LA DECODIFICACION ..........................................................................................................................................................
if __name__=="__main__":

    print ("INGRESAR LOS SIMBOLOS O UN MENSAJE QUE DESEA COMPRIMIR:")
    print (" " )
    mensaje=input()
    print (" ")

    print ("NUMERO TOTAL DE SIMBILOS O BITS INTRODUCIDOS PARA SER ENVIADOS:  %s" % (len(mensaje)))
    print (" ")
    print ("[ 1 PASO]: NUMERO DE SIMBOLOS O BITS, ERRADOS O REPETIDOS ")
    print (" ")
    simbolos=''
    probabilidad=[]
    msm=mensaje
    d=0

    for i in mensaje:
        if i in msm:
            print (i,"=",int ( msm.count(i)))
            simbolos+=i
            probabilidad.append(float(float ( msm.count(i))/float(len(mensaje))))
            msm=msm.replace(i,'')
            d+= 1

    symbols=dict(zip(simbolos, probabilidad))
    print (" ")
    print ("NUMERO DE SIMBOLOS COMPRIMIDOS=",d)
    print (" ")
    print ("[ 2 PASO]:PROBABILIDAD DE CADA SIMBOLO P(S)= (numero de bit errados) / (numero total de bit enviados)")
    print (" ")
    print (symbols)
    print (" ")
    print ("[ 3-4 PASO]: LA FUNCION [buildTree] DEL CODIGO. ORDENA LAS PROBABILIDADES DE MENOR A MAYOR PROBABILIDAD")
    print ("           Y REALIZA LAS OPERACIONES YA EXPLICADAS QUE SE REQUIEREN PARA IR ARMANDO EL ARBOL DE HUFFMAN")
    print (" ")


    tiempo_inicial= time()


    # codificar instancia
    huffman = Huffman(symbols)
    print ("...........................................................................")
    print ("...........................CODIFICACION....................................")
    print ("...........................................................................")
    print (" ")
    print (" ")
    print ("[ 5 PASO]:CODIFICACION BINARIA USANDO EL ARBOL DE HUFFMAN:")
    print ( " ")
    for symbol in symbols:
        print ("Simbolo: %s; Codificacion: %s" % (symbol, huffman.showSymbolEncoding(symbol)))

    encoded = huffman.encode(mensaje)
    print (" ")
    print ("Mensaje que se esta codificando: %s;" % (mensaje))
    print (" ")
    print ("Codificacion en bits : %s" % (encoded))
    print (" ")
    print ("La longitud de codigo binario es:  %s" % (len(encoded)))
    data = encoded
    print (" ")
    print ("Codigo codificado que esta siento enviado al receptor:  %s" % (data))

    # DECODIFICACION
    print (" ")
    print (" ")
    print (" ")
    print (" ")
    print ("...........................................................................")
    print ("...........................DECODIFICACION..................................")
    print ("...........................................................................")
    print (" ")
    print (" ")
    print ("Esperando el mensaje del emisor para su decodificacion......")


    decoded = huffman.decode(data)
    print (" ")
    print ("CODIGO BINARIO RECIBIDO ES :", data )
    print (" ")
    print ("DECODIFICANDO EL CODIGO....................................")
    print (" ")
    print ("Mensaje decodificado : %s " % (decoded))

    # FIN


    tiempo_final= time()
    tiempo_ejecucion= tiempo_final - tiempo_inicial
    print (" ")
    print ('El tiempo de transmisiOn es:',tiempo_ejecucion) #En segundos)



os._exit(0)