22-12-2021

Cosa ho fatto

  • Nuovo script cleaner.py, contenente la classe Cleaner, che si inizializza passando una stringa, dalla quale vengono immediatamente rimossi i caratteri nulli (’\0’). I metodi di Cleaner corrispondono a tutte le funzioni relative alla pulizia di stringhe. Tutte i metodi contenuti sono stati documentati in reStructuredText e testati con dati reali. Ecco l’elenco dei metodi contenuti:
    • string_fix, che si occupa di sostituire hyphen-minus a tutti gli altri tipi di hyphen, dash e segno meno.
      • Corretto un bug per cui veniva ritornata la stringa originale senza apportare sostituzione alcuna.
      • Ora la sostituzione non avviene tramite il glifo, ma tramite l’encoding utf8. Avevo paura che usando il glifo un copia-incolla erroneo introducesse un errore invisibile.
      • La funzione è stata ribattezzata normalize_hyphens, un nome più esplicito.
    • clean_title ✅
    • clean_date ✅
    • clean_name ✅
  • Ho testato e documentato i metodi della classe ResourceFinder.
    • retrieve_venue_from_meta.
      • Questo metodo funzionava in maniera ricorsiva. Per ogni venue cercava i volumi corrispondenti e per ogni volume cercava gli issue corrispondenti, ma c’erano due bug:
        • Mancava la chiave ‘id’ in riferimento al dizionario sugli issue.

        • C’era un bug nella ricorsione, ****che si manifestava in presenza di più issue associati allo stesso volume. Evidenzio entrambi i bug nel codice:

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          26
          27
          28
          29
          30
          31
          32
          33
          34
          35
          36
          37
          38
          39
          40
          def retrieve_vvi(self, meta, content):
          query = """
          SELECT DISTINCT ?res
          (group_concat(DISTINCT ?type;separator=' ;and; ') as ?type_)
          (group_concat(DISTINCT ?title;separator=' ;and; ') as ?title_)

          WHERE {
          ?res <%s> <%s>.
          ?res a ?type.
          ?res <%s> ?title.
          } group by ?res

          """ % (GraphEntity.iri_part_of, "https://w3id.org/oc/meta/br/" + str(meta),
          GraphEntity.iri_has_sequence_identifier)
          result = self.__query(query)
          if result["results"]["bindings"]:
          results = result["results"]["bindings"]
          for x in results:
          res = str(x["res"]["value"]).replace("https://w3id.org/oc/meta/br/", "")
          title = str(x["title_"]["value"])
          types = str(x["type_"]["value"]).split(" ;and; ")
          if content:
          if str(GraphEntity.iri_journal_issue) in types:
          # Qui dovrebbe essere content["issue"][title]['id'] = res
          content["issue"][title] = res
          elif str(GraphEntity.iri_journal_volume) in types:
          content["volume"][title] = dict()
          content["volume"][title]["id"] = res
          content["volume"][title]["issue"] = dict()
          # Qui parte la ricorsione
          content["volume"][title]["issue"] = self.retrieve_vvi(res, None)
          # Problema: se c'è più di un x
          # content smette di essere None anche se ci trova nella ricorsione,
          # sollevando un'eccezione di tipo KeyError
          else:
          if str(GraphEntity.iri_journal_issue) in types:
          content = dict()
          content[title] = dict()
          content[title]['id'] = res
          return content

          Ho fixato il bug eliminando la ricorsione ed effettuando una singola ricerca SPARQL che tramite frbr:partOf+ trova direttamente tutti i volumi e gli issue. Ecco la nuova funzione:

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          26
          27
          28
          29
          def __retrieve_vvi(self, meta:str, content:Dict[str, dict]) -> dict:
          query = f'''
          SELECT DISTINCT ?res
          (GROUP_CONCAT(DISTINCT ?container; separator=' ;and; ') AS ?container_)
          (GROUP_CONCAT(DISTINCT ?type; separator=' ;and; ') AS ?type_)
          (GROUP_CONCAT(DISTINCT ?title) AS ?title_)
          WHERE {{
          ?res <{GraphEntity.iri_part_of}>+ <https://w3id.org/oc/meta/br/{meta}>;
          <{GraphEntity.iri_part_of}> ?container;
          a ?type;
          <{GraphEntity.iri_has_sequence_identifier}> ?title.
          }} group by ?res
          '''
          result = self.__query(query)
          if result['results']['bindings']:
          results = result['results']['bindings']
          for x in results:
          res = str(x['res']['value']).replace('https://w3id.org/oc/meta/br/', '')
          container = str(x['container_']['value'])
          title = str(x['title_']['value'])
          types = str(x['type_']['value']).split(' ;and; ')
          if str(GraphEntity.iri_journal_issue) in types and self.__is_contained_in_venue(results, container):
          content['issue'].setdefault(title, dict())
          content['issue'][title]['id'] = res
          elif str(GraphEntity.iri_journal_volume) in types:
          content['volume'].setdefault(title, dict())
          content['volume'][title]['id'] = res
          content['volume'][title]['issue'] = self.__retrieve_issues_by_volume(results, res)
          return content
    • retrieve_br_from_id ✅
    • retrieve_metaid_from_id ✅
    • retrieve_ra_from_meta ✅
    • retrieve_ra_from_id ✅
    • retrieve_ra_sequence_from_meta ✅
    • retrieve_re_from_br_meta ✅
    • retrieve_br_info_from_meta ✅
      • __type_it ✅
      • __vvi_find ✅
  • Ho cominciato a testare i metodi di Curator
    • clean_id_list ✅
  • Ho aggiunto un plugin che permette di ottenere l’elenco di tutti i DOI contenuti in COCI a partire dal dump. La documentazione del README è stata aggiornata per spiegare come usare questo plugin.

Domande

  • Nella tesi di Fabio a pagina 70 si dice che tutti i tipi di hyphen, dash e il segno meno devono essere sostituiti da un soft-hyphen (U+00AD). Tuttavia, alle pagine 29-30 si dice che le date e i numeri delle pagine devono essere separati da un hyphen-minus (U+002D). Immagino che la seconda sia quella giusta, visto che il soft hyphen serve per la sillabazione, giusto?

  • Ho notato che Meta necessita di un file di configurazione per funzionare, oltre agli argomenti specificati quando si lancia l’applicazione da terminale. Personalmente, trovo questa soluzione un po’ scomoda e ridondante. Direi, o l’una o l’altra: proporrei di spostare tutta la configurazione in un unico file YAML. Dopodiché, l’applicazione si lancia specificando unicamente il percorso di questo file. Cosa ne pensi?

    • Preferirei un file di configurazione agli argomenti perché i parametri sono tanti. Così vanno scritti una volta sola ed è più facile modificarli su file che da terminale, riducendo la possibilità di commettere errori.
    • Ho pensato a YAML perché è molto piacevole da leggere e, a differenza di JSON, è commentabile.
  • In riferimento al campo ‘id’ del CSV, la tesi dice:

    The cell contains the IDs for the document described within the line.

    Mi confermi che tali ID devono essere solo quelli del documento descritto? Quindi niente id degli agenti responsabili, editori, riviste ecc.

  • La funzione retrieve_ra_sequence_from_br_meta restituisce gli agenti responsabili di una risorsa nel giusto ordine. Essa è stata implementata per funzionare per autori, curatori e case editrici. Tuttavia, non mi è mai capitato di vedere più case editrici per una singola risorsa bibliografica. Esiste questa possibilità?


22-12-2021
https://arcangelo7.github.io/p/29e6e045fe414959823fd63a4ef83ad6/
Author
Arcangelo Massari
Posted on
December 21, 2021
Licensed under