3 de enero de 2018

FoxPro es excelente para realizar análisis gramatical de datos

Artículo original: FoxPro Rocks Parsing Data
http://rickschummer.com/blog/2006/04/foxpro-rocks-parsing-data.html
Autor: Rick Schummer
Traducido por: Ana María Bisbé York


La semana pasada uno de mis clientes me envió un correo pidiéndome ayuda para analizar unos datos. Tenía un montón de documentos que se emplean en su industria, todos guardados en campos memos. Comenzaron a preparar una tabla de contenidos (que tenía el número de página y la guía de puntos). Cada una de las sesiones dentro del campo memo tenía un encabezado que estaba incluido en la tabla de contenidos.

Mi misión era obtener un código para analizar el campo memo y dividirlo en registros individuales para cada sección que había en el campo memo. Si el campo memo tenía 53 entradas en la tabla de contenidos, yo debía tener 53 registros en la tabla resultante. El contenido para cada sección era variable. Podía no haber texto alguno, podían haber varios párrafos de texto, o un término medio entre estos. Si la tabla de contenidos tenía, al menos, una entrada tendría el encabezado en el texto. El código necesitaba colocar el encabezado en una columna y toda la sesión correspondiente en un campo memo.

¿Quiere adivinar cuánto tiempo me llevó escribir y cuántas líneas de código? Adelante, hágase una idea aproximada. Mi idea fue que tardaría 60 minutos. No tenía idea de la cantidad de líneas que necesitaría.

Escribí la parte inicial de la solución en menos de una hora. Analicé la tabla de contenidos utilizando ALINES() y luego analicé los encabezados de sesiones a partir de la tabla de contenidos, buscando todos los textos que aparecían antes de la guía de puntos. Extraje todo el texto entre los encabezados de sección en el resto del memo utilizando STREXTRACT(). Desafortunadamente algunas de las palabras en el memo se duplicaron en la tabla de contenido. Me tomó unos minutos revisar los datos duplicados, limpiar algunos espacios extras y retornos.

La solución que preparé para el usuario es el siguiente código que también lo pueden descargar desde: ParseMemoViaTableOfContents.zip

LOCAL lcDots, ;
      lcNextChapter

LOCAL ARRAY laMemo[1]

CREATE TABLE ParsedMemo ;
   ( ;
    cChapter    c(200), ;
    mChapter    m ;
   )

SCATTER MEMO BLANK NAME loData

lcDots  = "..............."
lnLines = ALINES(laMemo, MemoTestFree.FannieMemo)

SET STEP ON

FOR lnI = 2 TO lnLines
   IF lcDots $ laMemo[lnI]
      loData.cChapter = SUBSTRC(laMemo[lnI], 1, ATC(lcDots, laMemo[lnI]) - 1)
      lcNextChapter   = SUBSTRC(laMemo[lnI+1], 1, ATC(lcDots, laMemo[lnI+1]) - 1)

      * Find occurance with exact match, stating
      * with second occurence (one after table of contents
      lnY = 2

      DO WHILE .T.
         loData.mChapter = STREXTRACT(MemoTestFree.FannieMemo, loData.cChapter, lcNextChapter, lnY, 2+4)

         DO CASE
            CASE EMPTY(loData.mChapter)
               * Nothing returned, bail
               EXIT
            CASE NOT (lcDots $ loData.mChapter)
               * Strip out delimiters since this is not another TOC entry
               loData.mChapter = STREXTRACT(MemoTestFree.FannieMemo, loData.cChapter, lcNextChapter, lnY, 2)
               EXIT
            OTHERWISE
               * Keep going, found a near match but not exact match
               lnY = lnY + 1
         ENDCASE
      ENDDO

      * Remove all the initial extra spaces, carriage returns, linefeeds, and tabs
      DO WHILE INLIST(SUBSTRC(loData.mChapter, 1, 1), SPACE(1), CHR(13), CHR(10), CHR(9))
         loData.mChapter = SUBSTRC(loData.mChapter, 2)
      ENDDO

      INSERT INTO ParsedMemo FROM NAME loData
   ELSE
      EXIT
   ENDIF
ENDFOR

RETURN

Todo está programado en 61 líneas de código (incluyendo algunas pocas líneas de comentarios y algunas líneas en blanco). La capacidad de VFP para analizar gramáticamente texto es excelente ¿A que si?

Se que el cliente quedó muy satisfecho.

1 comentario :

Los comentarios son moderados, por lo que pueden demorar varias horas para su publicación.