Autor: elGuille

  • Google Cloud Natural Language, ejemplo en Visual Basic .NET

    Pues eso… aquí te dejo un ejemplo para usar las API de Google Cloud Natural Language, pero para Visual Basic .NET

    Con esas API podrás analizar textos (también en español) y ver las palabras que la forman (tokens), su estructura sintáctica, etc.

    Nota:
    Para usar este código tendrás que crearte una cuenta en Google Cloud, generar una «key» para usarla y poco más, todos los pasos están explicados en este enlace (el código de ejemplo es para C#, pero te servirá.

    Pasos para crear un proyecto usando dotnet (cli):

    – Abre una ventana de consola (o terminal)
    – Posicionarse en la carpeta donde crear el proyecto
    – Crear el proyecto
    dotnet new console -n <nombre-proyecto>
    dotnet new console -lang VB -n <nombre-proyecto>
    – Cambiar al directorio del proyecto
    cd <nombre-proyecto>
    – Añadir el paquete de Google Cloud Natural Language API
    dotnet add package Google.Cloud.Language.V1
    – Copiar el fichero key.json con las claves y permisos
    – Ver estos pasos para crearla:
    https://codelabs.developers.google.com/codelabs/cloud-natural-language-csharp#3
    – En IAM, añadir la cuenta creada (incluida en el fichero key.json) en +OTORGAR ACCESO
    Solo estará la principal y/o las otras añadidas
    – Si se ha usado otra cuenta, estará en IAM>Cuentas de Servicio
    – Modificar Program.cs (o Program.vb) para usar el código que accede a la API de Natural Language
    – Ejecutar el código
    dotnet run

    Notas:
    – Debes crear una variable de entorno en Windows, (lo puedes hacer desde la misma consola) indicando el path donde estará el fichero key.json.
    – Lo que yo hago es copiar ese fichero en la carpeta del ejecutable y la variable de entorno la defino de esta forma:
    set GOOGLE_APPLICATION_CREDENTIALS=key.json
    – Puedes modificar el fichero del proyecto y añadir lo siguiente:

      <ItemGroup>
        <None Update="key.json">
          <CopyToOutputDirectory>Always</CopyToOutputDirectory>
        </None>
      </ItemGroup>
    

    El código de ejemplo

    '--------------------------------------------------------------------------------
    ' Ejemplo de Google Cloud Natural Language en Visual Basic .NET (31/ene/23 18.50)
    '
    ' (c)Guillermo Som (Guille), 2023
    '--------------------------------------------------------------------------------
    
    Imports System
    Imports System.Text
    Imports gcl = Google.Cloud.Language.V1
    Imports Google.Protobuf.Collections
    Imports Google.Cloud.Language.V1.AnnotateTextRequest.Types
    
    'Namespace NaturalLanguageApiDemo
    Class Program
        Shared client As gcl.LanguageServiceClient '?
    
        Shared Sub Main(args As String())
            'Dim text = "El 8 de Febrero voy en bici al Camino de Santiago desde Sarria ¿crees que aguantaré?"
            Dim text = "Probando Google Cloud Natural Language con VB.NET ¿Funcionará esto?"
    
            Console.WriteLine("Ejemplos de Google.Cloud.Language")
            Console.WriteLine()
            Console.WriteLine("Pruebas de Google Cloud Natural Language en Visual Basic .NET")
            Console.WriteLine()
            Console.WriteLine("  Creando el cliente...")
            client = gcl.LanguageServiceClient.Create()
            Console.WriteLine()
    
            Dim repitiendo As Boolean = False
    
            Do
    
                If repitiendo Then
                    Console.WriteLine($"Última: '{text}'")
                    Console.WriteLine("Indica la frase que quieres analizar (0 salir, [la última])")
                Else
                    Console.WriteLine($"Predeterminada: '{text}'")
                    Console.WriteLine("Indica la frase que quieres analizar (0 salir, [predeterminada])")
                End If
    
                Console.Write("> ")
                Dim resText = Console.ReadLine()
    
                If Not String.IsNullOrEmpty(resText) Then
    
                    If resText = "0" Then
                        Exit Do
                    End If
    
                    text = resText
                End If
    
                Do
                    Console.WriteLine($"Analizar: '{text}'")
                    Console.Write("1- Todo con tokens, 2- Todo sin tokens, 3- Solo tokens, 0- nueva frase [2] ? ")
                    resText = Console.ReadLine()
                    Console.WriteLine()
    
                    If String.IsNullOrEmpty(resText) Then
                        resText = "2"
                    End If
    
                    If resText = "1" Then
                        Analizar(text, conTokens:=True)
                    ElseIf resText = "2" Then
                        Analizar(text, conTokens:=False)
                    ElseIf resText = "3" Then
                        AnalizarTokens(text)
                    ElseIf resText = "0" Then
                        Exit Do
                    End If
    
                    Console.WriteLine()
                Loop While True
    
                repitiendo = True
            Loop While True
        End Sub
    
        Private Shared Sub Analizar(text As String, conTokens As Boolean)
            If client Is Nothing Then
                client = gcl.LanguageServiceClient.Create()
            End If
    
            Dim document = gcl.Document.FromPlainText(text)
            Dim response As gcl.AnnotateTextResponse
    
            Try
                response = client.AnnotateText(document, New Features With {
                        .ExtractSyntax = True,
                        .ExtractEntities = True,
                        .ExtractDocumentSentiment = True,
                        .ExtractEntitySentiment = True,
                        .ClassifyText = True
                    })
            Catch
                response = client.AnnotateText(document, New Features With {
                        .ExtractSyntax = True,
                        .ExtractEntities = True,
                        .ExtractDocumentSentiment = True,
                        .ExtractEntitySentiment = True
                    })
            End Try
    
            Dim sentiment = response.DocumentSentiment
            Console.WriteLine($"Detected language: {response.Language}")
            Console.WriteLine($"Sentiment Score: {sentiment.Score}, Magnitude: {sentiment.Magnitude}")
            Console.WriteLine("***Entities:")
            Dim entity1 As gcl.Entity = Nothing
    
            For Each entity0 In response.Entities
    
                If entity1 Is Nothing Then
                    entity1 = entity0
                Else
                    If entity0.Equals(entity1) Then Continue For
                End If
    
                Console.WriteLine($"Entity: '{entity0.Name}'")
                Console.WriteLine($"  Type: {entity0.Type},  Salience: {CInt((entity0.Salience * 100))}%")
    
                If entity0.Mentions.Count > 0 Then
                    Console.WriteLine($"  Mentions: {entity0.Mentions.Count}")
    
                    For Each mention In entity0.Mentions
                        Console.Write($"    Text: '{mention.Text.Content}' (beginOffset: {mention.Text.BeginOffset}),")
                        Console.WriteLine($" Type: {mention.Type}, Sentiment: {mention.Sentiment}")
                    Next
                End If
    
                If entity0.Metadata.Count > 0 Then
                    Console.WriteLine($"  Metadata: {entity0.Metadata}")
    
                    If entity0.Metadata.ContainsKey("wikipedia_url") Then
                        Console.WriteLine($"    URL: {entity0.Metadata("wikipedia_url")}")
                    End If
                End If
            Next
    
            Console.WriteLine("***Categories:")
    
            For Each cat In response.Categories
                Console.WriteLine($"Category: '{cat.Name}' (Confidence: {cat.Confidence})")
            Next
    
            Console.WriteLine("***Sentences:")
    
            For Each sentence In response.Sentences
                Console.WriteLine($" Sentence.Text.Content: '{sentence.Text.Content}'")
                Console.WriteLine($"   Sentence.Text.BeginOffset: {sentence.Text.BeginOffset}")
                Console.WriteLine($" Sentence.Sentiment .Magnitude: {sentence.Sentiment.Magnitude}, .Score: {sentence.Sentiment.Score}")
            Next
    
            If conTokens Then
                Console.WriteLine("***Tokens:")
    
                For i As Integer = 0 To response.Tokens.Count - 1
                    MostrarToken(i, response.Tokens, conContenido:=False)
                Next
            End If
        End Sub
    
        Private Shared Sub AnalizarTokens(text As String)
            If client Is Nothing Then
                client = gcl.LanguageServiceClient.Create()
            End If
    
            Dim document = gcl.Document.FromPlainText(text)
            Dim response As gcl.AnnotateTextResponse
    
            Try
                response = client.AnnotateText(document, New Features With {
                        .ExtractSyntax = True,
                        .ExtractEntities = True,
                        .ExtractDocumentSentiment = True,
                        .ExtractEntitySentiment = True,
                        .ClassifyText = True
                    })
            Catch
                response = client.AnnotateText(document, New Features With {
                        .ExtractSyntax = True,
                        .ExtractEntities = True,
                        .ExtractDocumentSentiment = True,
                        .ExtractEntitySentiment = True
                    })
            End Try
    
            AnalizarSentecias(response)
        End Sub
    
        Private Shared Sub AnalizarSentecias(self As gcl.AnnotateTextResponse)
            Dim index As Integer = 0
    
            For Each sentence In self.Sentences
                Dim content = sentence.Text.Content
                Dim sentence_begin = sentence.Text.BeginOffset
                Dim sentence_end = sentence_begin + content.Length - 1
    
                While index < self.Tokens.Count AndAlso self.Tokens(index).Text.BeginOffset <= sentence_end
                    MostrarToken(index, self.Tokens, conContenido:=True)
                    index += 1
                End While
            Next
        End Sub
    
        Private Shared Sub MostrarToken(nToken As Integer, tokens As RepeatedField(Of gcl.Token), Optional conContenido As Boolean = True)
            Dim token As gcl.Token = tokens(nToken)
            Console.WriteLine($"{nToken}- Token: Text.Content: '{token.Text.Content}', Lemma: '{token.Lemma}'")
    
            If token.DependencyEdge.Label = gcl.DependencyEdge.Types.Label.Root Then
                Console.Write($"  **DependencyEdge Label: {token.DependencyEdge.Label}")
    
                If token.DependencyEdge.HeadTokenIndex <> nToken Then
                    Console.Write($", HeadTokenIndex: {token.DependencyEdge.HeadTokenIndex}")
                End If
    
                Console.WriteLine("**")
            Else
                Console.Write($"  DependencyEdge Label: {token.DependencyEdge.Label}, HeadTokenIndex: {token.DependencyEdge.HeadTokenIndex}")
                Dim tokenDependency = tokens(token.DependencyEdge.HeadTokenIndex)
                Console.WriteLine($" ('{tokenDependency.Text.Content}')")
            End If
    
            If conContenido Then
                Console.WriteLine($"  PartOfSpeech:")
                Console.Write($"    Tag: {token.PartOfSpeech.Tag},")
                Dim sb = New StringBuilder()
    
                If token.PartOfSpeech.Aspect <> gcl.PartOfSpeech.Types.Aspect.Unknown Then
                    sb.Append($" (Aspect: {token.PartOfSpeech.Aspect},")
    
                    If token.PartOfSpeech.[Case] <> gcl.PartOfSpeech.Types.[Case].Unknown Then
                        sb.Append($" Case: {token.PartOfSpeech.[Case]},")
                    End If
    
                    If token.PartOfSpeech.Form <> gcl.PartOfSpeech.Types.Form.Unknown Then
                        sb.Append($" Form: {token.PartOfSpeech.Form},")
                    End If
    
                    If sb.ToString().EndsWith(","c) Then
                        sb.Length -= 1
                    End If
    
                    sb.Append("),")
                End If
    
                If token.PartOfSpeech.Gender <> gcl.PartOfSpeech.Types.Gender.Unknown Then
                    sb.Append($" (Gender: {token.PartOfSpeech.Gender},")
    
                    If token.PartOfSpeech.Mood <> gcl.PartOfSpeech.Types.Mood.Unknown Then
                        sb.Append($" Mood: {token.PartOfSpeech.Mood},")
                    End If
    
                    If token.PartOfSpeech.Number <> gcl.PartOfSpeech.Types.Number.Unknown Then
                        sb.Append($" Number: {token.PartOfSpeech.Number},")
                    End If
    
                    If sb.ToString().EndsWith(","c) Then
                        sb.Length -= 1
                    End If
    
                    sb.Append("),")
                End If
    
                If token.PartOfSpeech.Proper <> gcl.PartOfSpeech.Types.Proper.Unknown Then
                    sb.Append($" Proper: {token.PartOfSpeech.Proper}")
                End If
    
                If sb.ToString().Trim().Length > 0 Then
                    Console.WriteLine(sb.ToString().TrimEnd(","c))
                End If
    
                sb.Clear()
                sb.Append("   ")
    
                If token.PartOfSpeech.Person <> gcl.PartOfSpeech.Types.Person.Unknown Then
                    sb.Append($" Person: {token.PartOfSpeech.Person},")
                End If
    
                If token.PartOfSpeech.Reciprocity <> gcl.PartOfSpeech.Types.Reciprocity.Unknown Then
                    sb.Append($" Reciprocity: {token.PartOfSpeech.Reciprocity},")
                End If
    
                If token.PartOfSpeech.Tense <> gcl.PartOfSpeech.Types.Tense.Unknown Then
                    sb.Append($" Tense: {token.PartOfSpeech.Tense},")
                End If
    
                If token.PartOfSpeech.Voice <> gcl.PartOfSpeech.Types.Voice.Unknown Then
                    sb.Append($" Voice: {token.PartOfSpeech.Voice}")
                End If
    
                If sb.ToString().Trim().Length > 0 Then
                    Console.WriteLine(sb.ToString())
                End If
            Else
                Console.WriteLine($"  PartOfSpeech Aspect: {token.PartOfSpeech.Aspect}, Case: {token.PartOfSpeech.[Case]}, Form: {token.PartOfSpeech.Form}")
                Console.WriteLine($"  PartOfSpeech Gender: {token.PartOfSpeech.Gender}, Mood: {token.PartOfSpeech.Mood}, Number: {token.PartOfSpeech.Number}")
                Console.WriteLine($"  PartOfSpeech Person: {token.PartOfSpeech.Person}, Proper: {token.PartOfSpeech.Proper}")
                Console.WriteLine($"  PartOfSpeech Reciprocity: {token.PartOfSpeech.Reciprocity}, Tag: {token.PartOfSpeech.Tag}")
                Console.WriteLine($"  PartOfSpeech Tense:: {token.PartOfSpeech.Tense}, Voice: {token.PartOfSpeech.Voice}")
            End If
        End Sub
    End Class
    'End Namespace

    Una captura

    La aplicación en funcionamiento

    Código fuente

    El código fuente del ejemplo para Visual Basic .NET, así como el de C#, los puedes ver/descargar desde este repositorio en GitHub.

    Y esto ha sido todo amigos… 😉

    Nos vemos.
    Guillermo

  • Algunos compiladores para FORTH

    Pues eso, aquí te dejo una pequeña lista de compiladores gratuitos para FORTH, esta lista me la ha facilitado ChatGPT (DEC 15 Version), podría haberlo buscado en GOOGLE, pero… Más que nada, para ver si ChatGPT/OpenAI sabía algo de este vetusto lenguaje, que por lo que puedo ver aún sigue vigente, se ve que hay muchos jubilados por ahí… 😉

    La pregunta ha sido:

    Hola, ¿puedes decirme qué compiladores gratuitos hay para el lenguaje FORTH?

    Y esta ha sido su respuesta:
    (en itálica las faltas de ortografía)

    Hola, sí, hay varios compiladores gratuitos para el lenguaje FORTH disponibles. Algunos ejemplos incluyen:

    Gforth: Es un compilador FORTH estandar y gratuito disponible para una variedad de sistemas operativos, incluyendo Windows, Linux, macOS y varios sistemas Unix. Gforth es compatible con la norma FORTH-83, así como con varias extensiones.

    SwiftForth: Es un compilador FORTH gratuito para Windows, macOS y Linux. Viene con una interfaz de línea de comandos y una ventana de depuración, así como una serie de herramientas de desarrollo adicionales, como un editor de código integrado y una ventana de registro de sistema.

    pForth: es un compilador FORTH gratuito para Windows y Linux que tambien incluye una interfaz de línea de comandos y una ventana de depuración. Es fácil de usar y se puede ejecutar en una variedad de plataformas.

    Win32Forth: es un compilador FORTH gratuito para Windows con una interfaz gráfica de usuario. También incluye una ventana de depuración, un editor de código integrado y una ventana de registro de sistema.

    4tH es otro compilador FORTH gratuito y multi plataforma, con ejecutar tanto en Windows, Linux y macOS.

    Es importante mencionar que estos son solo algunos ejemplos y puede haber muchos más opciones disponibles. Te recomendaría investigar un poco para encontrar el compilador que mejor se adapte a tus necesidades específicas.

    La pregunta la hice en español y la respuesta la ha dado en español.
    Pero le he dicho que lo traduzca al inglés.

    Por favor, ¿puedes traducir tu respuesta al inglés? gracias

    Y aquí su respuesta con la traducción dada por ChatGPT:

    Sure, here is my response translated to English:

    Hello, yes, there are several free compilers available for the FORTH language. Some examples include:

    Gforth: It is a standard and free FORTH compiler available for a variety of operating systems, including Windows, Linux, macOS, and several Unix systems. Gforth is compliant with the FORTH-83 standard, as well as various extensions.

    SwiftForth: It’s a free FORTH compiler for Windows, macOS, and Linux. It comes with a command-line interface and a debugging window, as well as a number of additional development tools, such as an integrated code editor and a system log window.

    pForth: It’s a free FORTH compiler for Windows and Linux that also includes a command-line interface and a debugging window. It is easy to use and can be run on a variety of platforms.

    Win32Forth: It’s a free FORTH compiler for Windows with a graphical user interface. It also includes a debugging window, an integrated code editor, and a system log window.

    4tH is another free and multi-platform FORTH compiler, running in Windows, Linux and macOS.

    It’s worth noting that these are just a few examples and there may be many more options available. I would recommend researching a bit to find the compiler that best suits your specific needs.

    Aquí tienes los enlaces a las páginas principales y a las de descargas.

    Gforth de GNU (descargar snapshots, manual actualizado en gforth.org)

    SwiftForth de FORTH Inc. (descargar evaluación)

    pForth (descargar y código fuente en GitHub)

    Win32Forth (descargar en sourceforge)

    4tH (descargar en sourceforge)

     

    Nos vemos.
    Guillermo

  • A la de una, a la de dos, a la de tres y a la de FORTH

    Pues eso… que en estos días me ha dado por retomar un viejo amigo (lenguaje de programación) que usé por primera vez en los años 80 (sobre el 84 u 85) en mi Commodore-64, me refiero al lenguaje FORTH.

    Ya no lo recuerdo, pero creo que era un «cartucho» que se insertaba en el C-64, el FORTH 64, de eso estoy seguro, porque he encontrado esta página con el manual y esa imagen (ver la captura de aquí abajo) sí que la recuerdo.

    Manual de Forth 64 para Commodore

    La cuestión es que, en aquellos años, el BASIC del Commodore, primero del VIC-20, después del C-64, era… ¿cómo decirlo? muy GO-TerO, es decir, que no tenía DO/LOOP, WHILE, UNTIL y lo que se hacía era el clásico GOTO.
    Y este lenguaje, FORTH, lo recuerdo como el primero en el que no usé un GOTO, entre otras cosas porque no existe la palabra GOTO en Forth. 😉

    La verdad es que no tengo nada de aquello, porque llegué hasta comprar un libro de Forth, pero para el BBC Micro, y de algo me sirvió. No recuerdo detalles, pero recuerdo que era «emocionante» programar en ese lenguaje, sobre todo en aquellos tiempos que lo más que teníamos a nuestra disposición eran los GOSUB, y eso de que pudieras crear tus propias palabras (WORD es el término de Forth para las «subrutinas»), pues… ¡era una pasada!

    Hablando de DO, LOOP, WHILE y UNTIL y el Commodore 64, también por aquellos años ochenta me fabriqué en «código máquina» (CM para el C-64) unas extensiones para BASIC, entre ellas el DO-LOOP UNTIL y DO-LOOP WHILE. Con el C-64 y el C-128 (pero menos) hice cosillas «curiosas» en ensamblador para el Commodore 64, en fin… chocheando que está ya uno… jajaja… en fin-bis.

    Volviendo al Forth, decirte que lo mismo publico algunas cosillas de las que estoy haciendo, en este caso ya son para ANS-FORTH, el estándar, que estoy haciendo con Gforth de GNU (abajo tienes el enlace) para no olvidarme… aunque ahora ha cambiado un poco, sigue siendo un «peñazo» el tema de los números y las cadenas…

    Lo más curioso de este lenguaje es que usa la notación polaca inversa, y que todo lo maneja poniendo y sacando cosas de la pila (stack), que es de tipo LIFO (last-in first-out, el último en entrar es el primero en salir), de forma que si quieres sumar dos números lo harás de esta forma:

    7 3 + y para mostrarlo escribes un punto para ver el resultado.

    Y si quieres hacer algo como: (3 + 2 ) * 8, tendrás que hacerlo, por ejemplo, de esta otra:

    8 2 3 + * .

    Y te mostrará 40, 5 * 8.

    Los pasos que sigue son:

    1- Pone el 8 en la pila
    2- Pone el 2 en la pila
    3- Pone el 3 en la pila
    4- Pone el + en la pila y
    5- Suma dos valores que haya en la pila y pone el resultado (5)
    6- Pone el * en la pila
    7- Multiplica dos valores de la pila y pone el resultado (40)
    8- El punto muestra el valor que haya en la pila.

    En FORTH no se usan los paréntesis ni hay nivel de precedencia, todo se maneja con el orden en que esté en la pila.

    El ejemplo anterior se puede escribir también así:

    2 3 + 8 *

    Imagina cómo lo hace en este caso.

    Solo comentarte que cuando pulsas intro es cuando empieza la acción, es decir, no hace nada mientras estás escribiendo las cosas para que se pongan en la pila.

    Como te comento abajo, los de GNU han hecho una versión de Gforth para Android (ver la captura con el clásico HOLA-MUNDO).

    GFORTH funcionando en un Pixel 4a de Android

    Y poco más puedo decirte, salvo ponerte el código del HOLA-MUNDO que he hecho para el Android 😉

    : HOLA-MUNDO   ( -- muestra el mensaje )
        ." Hola Mundo de GFORTH!"
    ;
    

    Ahí abajo te dejo unos cuantos enlaces sobre FORTH por si quieres echarle un vistazo.

    Y esto es todo… ah, y ¡Felices Fiestas! aunque sea en el día de los Reyes Magos 😉

    Nos vemos.
    Guillermo

    P.S.
    Enlaces sobre FORTH:
    Wiki de Forth para Commodore.
    GForth de GNU (el que estoy usando ahora), también existe una versión para Android.
    FORTH, Inc., entre otros del «inventor» de Forth.
    Starting Forth, un libro online de Leo Brodie.
    FORTH Standard, pues eso…
    And so Forth, también te puede servir.

    Hay muchos más en internet, me he quedado sorprendido de que haya tanto movimiento sobre FORTH.