CCCPaste

codigo_huffman

import os
from time import time

class Node: #Declaración de variables para crear los nodos
    probability =0.0 #Declarada como fload
    symbol = " " #Variable vacia
    encodings = ""
    visited = False #variable Boolean
    parent = -1 #Longitud de 0 a -1 variable entera
class Huffman: #Declaración de variables para la creación del arbol de Huffman
    Tree = None #Retornar arbol
    Root = None #Retornar raiz
    Nodes = []
    probs = {} #bloque, instancia el método
    dictEncoder = {}

    #1
    def __init__(self,symbols): #Inicianilizamos las funciones, con los atributos que va a utilizar
        self.initNodes(symbols) #retorna valores
        self.buildTree()
        self.buildDictionary()
    #2

    def initNodes(self,probs): #creamos los nodos con sus respectivas posibilidades
        for symbol in probs:
            node =Node() #inicializamos el node
            node.symbol = symbol
            node.probability = probs[symbol] # Asiganamos una probabilidad a cada simbolo o letra
            node.visited = False #Variable que no es fija que va a ir cambiando
            self.Nodes.append(node) #creamos una lista para cada nodo creado
            self.probs[symbol]=probs[symbol] #Establece para ca probabilidad de simbolo
    #3

    def buildTree(self): #Realizamos las operaciones de acuerdo a la lógica de Huffman
        indexMin1 = self.getNodeWithMinimumProb() #buscamos el menor número de la primera probabilidad
        indexMin2 = self.getNodeWithMinimumProb() #buscamos el menor número de la segunda probabilidad

        while indexMin1 != -1 and indexMin2 !=-1: #(!= evalua como verdadero si 2 variable son diferentes)
            node =Node()
            node.symbol="." # se llama el simbolo digitado para que salga el resultado
            node.encodings=""
            #llamamos a las dos probabilidades minimas
            prob1 = self.Nodes[indexMin1].probability
            prob2 = self.Nodes[indexMin2].probability
            node.probability = prob1 + prob2
            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 probalidad
            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()
    #4
    def getNodeWithMinimumProb(self):
        minProb = 1.0
        indexMin = -1
        for index in range(0, len(self.Nodes)):
            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
    #5
    def showSymbolEncoding(self, symbol):
        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:
            while index != -1:
                encoding = "%s%s" % (self.Nodes[index].encoding, encoding)
                index = self.Nodes[index].parent
        else:
            encoding = "simbolo desconocido"
        return encoding

    # 6
    def buildDictionary(self):  # Creacion de diccionaio, se guardan los simbolos con sus respectivos
    # codigos binarios resueltos por el arbol
        for symbol in self.probs:
            encoding = self.showSymbolEncoding(symbol)
            self.dictEncoder[symbol] = encoding

    # 7
    def encode(self, plain): #Agrupa los codigos binarios codificados de acuerdo al mensaje escrito
        #en la 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
        index = 0
        decoded = ""

        while index < len(encoded):
            found = False
            #Busca cada en parte codificada un simbolo, buscando cuál es compatible
            #con otra
            aux = encoded[index:]

            for symbol in self.probs:
                if aux.startswith(self.dictEncoder[symbol]):
                    decoded = "%s%s" % (decoded, symbol)
                    index = index + len(self.dictEncoder[symbol])
                    break

            return decoded
    #Fin

if __name__ == "__main__":
    print ("\n\n............CODIFICACION........\n\n")
    mensaje =input("Ingrese la palabra u oracion: ")
    print ("\n\nTotal de simbolos: \n\n %s"% (len(mensaje)))
    simbolos=''
    probabilidad=[]
    msm=mensaje
    d=0

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

    symbols=dict(zip(simbolos, probabilidad)) #Funcion para llamar al simbolo y a su probabilidad
    print ("\n\nSimbolos comprimidos: \n\n" ,d) #Imprime la cantidad de simbolos que contabilizalo la funcion count
    print ("\n\nPROBABILIDAD DE CADA SIMBOLO:\n\n" , symbols)
    tiempo_inicial=time() #Funcion para determinar el tiempo del programa
    #Codificacion de los simbolos
    huffman=Huffman(symbols) #Llamamos a la clase Huffman
    print ("\n\nSimbolos codificados usando el arbol de Huffman: \n\n")
    for symbol in symbols:
        print ("Simbolo: %s; Codificacion: %s" % (symbol, huffman.showSymbolEncoding(symbol)))
    encoded = huffman.encode(mensaje) #Llama funcion tras funcion para el procedimiento de codificacion
    print ("\n\nMensaje que se esta codificando: \n\n%s" % (mensaje))
    print ("\n\nCodificacion en bits : \n\n%s" % (encoded)) #Notamos el msj en bits
    print ("\n\nLa longitud de codigo binario es: \n\n%s" % (len(encoded)))
    data = encoded

#Decodificacion
    print ("\n\n..................DECODIFICACION..................\n\n")
    decoded = huffman.decode(data) #Llamamos a las funciones correspondientes y el mensaje llamado data
    print ("El codigo binario a decodificar es:\n\n", data )
    print ("\n\nEl mensaje decodificando es: \n\n %s" % (decoded)) #Imprimimos el resultado de la funcion decoded

#Calculo para el tiempo del procedimiento
    tiempo_final= time()
    tiempo_ejecucion= tiempo_final - tiempo_inicial
    print ('\n\nEl tiempo de transmision es: ',tiempo_ejecucion)
os._exit(0)