Visualizza post

Questa sezione ti permette di visualizzare tutti i post inviati da questo utente. N.B: puoi vedere solo i post relativi alle aree dove hai l'accesso.


Topics - biagiolicari7

Pagine: [1]
1
Ciao a tutti !
Dovrei fare il parsing e l'indicizzazione di DBLP tramite whoosh. Ho provato ad usare Sax testando il codice da me scritto su una versione ridotta del DBLP composta da circa 30.000 righe andando a creare circa un file xml da 30mb.
Inizialmente il tutto funzionava correttamente in quanto mi creava l'indice che io desideravo, però una volta che ho provato a dargli in pasto il dblp competo da 2,5 GB arrivo ad un punto dove whoosh mi crea circa 10,5 GB di file tmp e non va più avanti ! Come posso sistemare ? Grazie mille.



import xml.sax
from whoosh.index import create_in
from whoosh.fields import *
import sys
import os


types = ["article", "incollection", "inproceedings", "phdthesis", "mastersthesis"]




class DBLPHandler( xml.sax.ContentHandler ):
   def __init__(self):
      self.key = ""
      self.tag = ''
      self.author = ''
      self.title = ""
      self.year = ""
      #self.pages = ""
      #self.url = ''
      #self.ee = ''
      self.volume = ''
      self.journal = ''
      #self.number = ''
      self.crossref = ''
     
     
   def startDocument(self):
        print('Start Parsing......')

   def endDocument(self):
        print('Parse Successfully!')   

   
   # Call when an element starts
   def startElement(self, tag, attributes):
      self.CurrentData = tag
      if tag in types :
         key = attributes["key"]
         self.tag = tag
         self.key = key

         
   # Call when an elements ends
   def endElement(self, tag):
       if self.tag == tag :
           writer.add_document(pubtype = self.tag,
                                    key = self.key,                                   
                                    author = self.author,
                                    title = self.title,
                                    #pages = self.pages,
                                    year = self.year,
                                    volume = self.volume,
                                    journal = self.journal )
                                   # url = self.url,
                                    #ee = self.ee,
                                   # number = self.number,
                                    crossref = self.crossref
                                   
       
           self.author = ''
           self.title = ''
           self.year = ''
           #self.pages = ''
           #self.url = ''
           #self.ee = ''
           self.volume = ''
           self.journal = ''
           self.key = ''
           #self.mdate = ''
           self.crossref = ''
           self.tag = ''
           
           
# Call when a character is read
   def characters(self, content):

      if self.CurrentData == "author":
         self.author += content
      elif self.CurrentData == "title":
         self.title += content
      elif self.CurrentData == "year":
         self.year += content
     # elif self.CurrentData == "pages":
         #self.pages += content
      #elif self.CurrentData == "url":
         #self.url += content
      #elif self.CurrentData == "ee":
        # self.ee += content
      elif self.CurrentData == "volume":
         self.volume += content
      elif self.CurrentData == "journal":
         self.journal += content
      #elif self.CurrentData == "number":
         #self.number += content
      elif self.CurrentData == "crossref":
         self.crossref += content   
   
         
if ( __name__ == "__main__"):
   
    schema = Schema(#date=DATETIME(stored=True),
                                    pubtype=TEXT(stored=True),
                                    key=ID(stored=True),
                                    author=TEXT(stored=True),
                                    title=TEXT(stored=True),
                                    #pages=TEXT(stored=True),
                                    year=TEXT(stored=True),
                                    volume=TEXT(stored=True),
                                    journal=TEXT(stored=True),
                                    #number=TEXT(stored=True),
                                   # url=ID(stored=True),
                                    #ee=ID(stored=True),
                                    crossref=ID(stored=True)
                                    )
                                           
           
    if not os.path.exists("dblpindex"):
        os.mkdir("dblpindex")
    ix = create_in("dblpindex", schema)
    writer = ix.writer()
   
           # create an XMLReader
    parser = xml.sax.make_parser()
           # turn off namepsaces
    parser.setFeature(xml.sax.handler.feature_namespaces, 0)
       
    Handler = DBLPHandler()
    parser.setContentHandler( Handler )
   

    print('Inizio parsing e indicizzazione..')
   
    parser.parse('dblp.xml')
    print('inizio la commit...')
    writer.commit()


2
Base / Ottimizzazione del codice
« il: Febbraio 13, 2019, 19:18 »
salve a tutti ! vorrei alcuni consigli per ottimizzare questo codice..magari per renderlo più pythonico ! grazie mille !
Questa parte di codice mi permette di gestire la classe compress e uncompress e di implementare gli script che ho scritto per eseguire il tutto da terminale.
il programma funziona in tutte le sue parti, ma non riesco a capire se è scritto in maniera adeguata o meno....aspetto i vostri consigli ! Grazie mille.

import os
from src.converter import convertinbits,number_from_bytestring
from pathlib import Path
from src.Compress import Compress,timer
from src.Uncompress import Uncompress,timer_uncompress
import shutil

#from Uncompress import Uncompress
BYTEDIM = 8
pattern = ['.z','.c','.cc','.xml','.html','.py','.htm','.cpp','.rtf','.json','.txt'] #pattern possibili da comprimere
pattern_compressed = ['*.Z', '*.z', '*.lzw']    #pattern lzw       

'''Funzione che legge all'interno di un determinato file compresso e ritorna la stringbit da dare in pasto al decompressore '''       
def read(filename) :
    z = ''
    try :
        f = open(os.path.abspath(filename),'rb')
        try :
            for byte in f.read() :
                z+=(convertinbits(byte,BYTEDIM))
        except (ImportError, EOFError) as ex :
            print('errore imprevisto : ' , ex)
               
    except IOError as ioerr:
        print('File not found :', ioerr)
       
    finally :
        f.close()
       
    return z

''' Funzione che scrive su file la stringa compressa'''
def write(stringbits, filename):
     with open(filename+'.z', "wb") as f:
         if len(stringbits)%BYTEDIM != 0:
             for _ in range(0, BYTEDIM-(len(stringbits)%BYTEDIM)):
                 stringbits += '0' #aggiungo il padding se serve
         numbytes = int(len(stringbits)/BYTEDIM)
         bytevalues = []
         for i in range(0,numbytes):
             bytevalues.append(number_from_bytestring(stringbits[BYTEDIM*i:BYTEDIM*(i+1)]))
         f.write(bytes(bytevalues))
         
'''funzione di ricerca file nel caso in cui is_file() è true, ritorna il codice del file compresso e la sua path abs'''         
def search(filename):
   
    path = Path(filename).resolve()
       
    bin_code = []
    abspath = []
   
    if path.is_file() : #se il path rappresenta un file eseguo i controlli per l'estensione     
        for _ in pattern_compressed : #se il file rientra nelle etensioni previste si esegue la decompressione
            if path.suffix == _[1:] :
                abspath.append(path)
                dec = read(path)
                bin_code.append(dec)
               
    if path.is_dir() : #se il path è un dir si decomprimono tutti i file all'interno
        return 0
       
    return bin_code,abspath

'''funziona che ricerca una dir e ritorna il codice decompresso di ogni file all'interno della dir specificata,in maniera ricorsiva, e relativo path abs '''
def search_dir(dirname) :
    #mposto la Path della directory da considerare, dove cercare i file lzw
    p = Path(dirname).resolve()
       
    abspath = []
    bin_code = []
    for _ in pattern_compressed :
        #Uso la funzione rglob che mi permette di socrrere ricorsivamente le sottocartelle della Path alla ricerca di eventuali file lzw
        for p in p.rglob(_) :#uso rglob per la ricerca ricorsiva
            abspath.append(p.resolve()) #aggiungo la path assoluta alla lista di ritorno
            dec = read(p.resolve()) #richiamo la funzione decompress_file per ogni elelemento lzw all'interno di una qualsiasi dir
            bin_code.append(dec) # aggiungo il testo decompresso ad una lista
       
    return bin_code,abspath

''' Funzione che comprime una intera cartella con annesse subdir presenti all'interno contenenti file compatibili col pattern specificato '''
def write_dir(dirname,dt,verbose) :
   
    p = Path(dirname).resolve()

    for p in p.rglob('*'): #ricerca ricorsiva all'interno del dir Path specificato di file compatili per essere compressi
        if p.suffix == '.z' :
            check_ext(p)
        else :
            if p.suffix in pattern :
                try :
                    size_b = file_size(p) #size prima della compressione per ogni file preso in considerazione
                    f = open(p,'r')
                           
                    if verbose == False:
                        cod_compressed,bin_compressed = Compress(f.read(),dt)
                    elif verbose == True:
                        compress_verbose = timer(Compress)
                        cod_compressed,bin_compressed = compress_verbose(f.read(),dt) #cod_compressed,bin_compressed = Compress(f.read(),dt) #richiamo la definizione di Compressione sul file specificato usando il dizionario o il trie
                        write(bin_compressed,os.path.join(p.parent,p.stem)) #richiamo la funzione che scrive il file compresso
                        f.close()
                        newpath = p.with_suffix('.z')
                        size_a = file_size(newpath)
                        if size_b < size_a:
                            if verbose == True :
                                print("Il file : ", newpath.name, " risulta maggiore dell'originale")
                                newpath.unlink()
                        else:
                            shutil.copymode(p,newpath)
                            p.unlink()
                except IOError :
                    print('errore in apertura di ', p)
               
                                             

'''funzione che comprime un determinato file inerente al pattern impostato'''
def write_file(filename, dict_or_trie,verbose,ric):
    path = Path(filename).resolve()
   
    if path.is_dir() and ric == True : #nel caso in cui la modalita ricorsiva sia attiva e il file passato è una dir, chiamo la funzione write_dir()
        b_size = directory_size(path)
        write_dir(path,dict_or_trie,verbose)
        a_size = directory_size(path)
        if verbose == True:
            percent = (b_size - a_size)/b_size * 100
            print("Compressione avvenuta del {} %".format(percent))           
     
    elif path.is_file() and ric == False  :
        if path.suffix == '.z' or path.suffix == '.Z' :
            check_ext(path) #controllo se file è stato già compresso e nel caso modifico estensione

        else :
            try :
                size_before = file_size(path) #calcolo dimensione prima della compressione
                f = open(path,'r')
               
                if verbose == False:
                    cod_compressed,bin_compressed = Compress(f.read(),dict_or_trie)
                if verbose == True: #se la modalita verbose è attiva applico il decoratore timer alla funzione compress
                    compress_verbose = timer(Compress)
                    cod_compressed,bin_compressed = compress_verbose(f.read(),dict_or_trie)
                   
                write(bin_compressed,os.path.join(path.parent,path.stem))#richiamo la funzione write
                f.close()
                newpath = path.with_suffix('.z')
                size_after = file_size(newpath) #calcolo la dimensione del file post_compressione
                if size_before < size_after:
                    newpath.unlink() #se la dimensione pre-compressione è superiore elimino il file compresso
                   
                else:
                    shutil.copymode(path,newpath)
                    path.unlink()
                   
                if verbose == True:
                    if not newpath.exists():
                        print("Il file : ", newpath.name, " risulta maggiore dell'originale")
                        return
                    percent = (size_before - size_after)/size_before * 100
                    print("Compressione avvenuta del {} %".format(percent))
                   
            except IOError as ex :
                print('Errore nel file : ', ex)
    else :
        print("Inserire correttamente le opzioni di ricerca " )
        return -1
           
    return 0

'''funzione che nel caso in cui il file sia gia compresso con estensione .z, ne modifica l'estensione'''
def check_ext (path): 
        base = os.path.splitext(path)[0]
        os.rename(path,base+".Z")
       
'''funzione che ritorna la dim in bytes del file passato come argomento'''
def file_size(fname):
    path = Path(fname)
    if path.is_file() :
        statinfo = os.stat(path)
        return statinfo.st_size
    elif path.is_dir() :
        dir_size = directory_size(path)
        return dir_size
   
'''funzione che ritorna la dimensione della dir passata come argomento, in bytes'''
def directory_size(path):
    total_size = 0
    seen = set()

    for dirpath, dirnames, filenames in os.walk(path): #ricerca ricorsiva all'interno della dir
        for f in filenames:
            fp = os.path.join(dirpath, f)

            try:
                stat = os.stat(fp)
            except OSError:
                continue

            if stat.st_ino in seen:
                continue

            seen.add(stat.st_ino)

            total_size += stat.st_size
        return total_size  # size in byte

           

'''Funzione che dato un path, una delle st_dati possibili e un argomento -r permettere di decomprimere un/a file/dir'''
def Uncompress_file(filename,dt,r,verbose):
    i = 0
   
    filename = Path(filename).resolve()
   
    if r == False and filename.is_file() :
        bin_cod,path = search(filename) #richiamo la funzione di ricerca file/dir
       
    elif r == True and filename.is_dir() :
        bin_cod,path = search_dir(filename)
    else :
        print("Inserire correttamente le opzioni di ricerca ")
        return -1

    for _ in bin_cod :
       
        if verbose == True:
            uncompress_verbose = timer_uncompress(Uncompress) #richiamo decoratore timer_uncompress nel caso in cui la modalita verbose sia attiva
            dec = uncompress_verbose(_,dt) #ottengo stringa decompressa
        elif verbose == False:
            dec = Uncompress(_,dt) #ottengo stringa decompressa
           
        name = Path(path[i]) #estraggo path del file decompresso
        f = open(os.path.join(name.parent,name.stem+'.txt'), 'w') #creazione nuovo file decompresso
        f.write(dec)
        f.close()
        shutil.copymode(name, os.path.join(name.parent,name.stem+'.txt'))
        name.unlink() #rimuovo il file compresso
        i += 1
       




3
Base / Creare script da eseguire su terminale con setuptools
« il: Gennaio 31, 2019, 18:46 »
salve a tutti, avrei un problema da risolvere. Ho terminato un mio progetto a cui dovrei aggiungere degli script da eseguire una volta installato tramite setuptools.
Per esempio, una volta installato il pacchetto creato da me, da terminale dovrei poter scrivere qualcosa come Compress(nome funzione presente nel progetto) -r -v (esempio di opzioni usabili) file1,file2 (lista file da dare in pasto alla funzione)

com'è possibile fare un qualcosa del genere ? grazie mille !

4
Base / LZW Compression/Decompression
« il: Gennaio 05, 2019, 22:42 »
salve a tutti ragazzi. vorrei chiedere alcuni consigli sullo sviluppo di questo algoritmo come progetto.
premetto che siamo gia ad un buon punto col ragazzo con cui collaboro, solo che dopo aver sviluppato un trie e la funzione di compressione...abbiamo provato a creare la medesima funzione con un dict in modo da sfruttare la def Compression() sia se si usa un trie ( nel caso nella def si avrà un parametro che può essere t=trie o d=dict) sia un dict. ora qui sotto trovate il codice della Compression() e della classe dict che implementa le medesime funzioni del trie....i risultati ovviamente non sono uguali in quanto il trie crea una compressione corretta mentre il dict crea una compressione dove il penultimo valore non è corretto. attendo consigli.


def Compression(input_File):
   
    stringa_compressa = []
    T = lzw_dict()
       
    dim = len(input_File)
    counter = 0
   
    #ciclo che esamina ogni carattere   
    for C in input_File:
        #provo a cercare il prossimo carattere
        val = T.search(C)
        counter = counter + 1 #incremento il contatore dei caratteri
       
        if T.check() :
            stringa_compressa.append(val)
       
        if counter == dim :
            stringa_compressa.append(val)
   
    stringa_compressa.append(256);
   
    return stringa_compressa

test = Compression("BANANA")
print(test)



classe dict :

class lzw_dict() :

    def __init__(self) :
        self.dim = 256
        self.dict = {chr(i) : i for i in range(self.dim)}
        self.prev = ""
        self.conta = 0
        self.value = 0
        self.stringa = []
        self.key = ""
   

    def search(self, char) :
        self.key = self.prev + char
        if self.key in self.dict :
            self.prev = ""
            self.conta= 0
            self.stringa.append(self.dict[self.prev])
            self.value = self.stringa.pop(0)
            return self.value
           
        else:
            self.prev = char
            self.dim += 1
            self.dict[self.key] = self.dim
            self.conta = -1
            return self.conta
       


   
    def check(self) :
        if self.conta == -1 :
            return True
        else :
            return False
           

Pagine: [1]