Pular para o conteúdo principal

Postagem em destaque

BlackTDN :: LeetCode :: Comparando Implementações Harbour e TLPP para o Desafio Longest Palindromic Substring

_Créditos das imagens: ChatGPT_ ### LeetCode :: Comparando Implementações Harbour e TLPP para o Desafio Longest Palindromic Substring Resolver o problema do [Longest Palindromic Substring](https://leetcode.com/problems/longest-palindromic-substring/description/) é um exercício clássico de programação, que desafia desenvolvedores a encontrar a maior substring palindrômica dentro de uma string. Recentemente, exploramos soluções tanto em Harbour quanto em TLPP (Total Language Protheus Programming). Neste artigo, comparamos as implementações nessas duas linguagens, destacando suas semelhanças, diferenças e funcionalidades específicas. #### Implementações em Harbour ##### Versão 5.1 Essa solução utiliza a técnica de expansão a partir do centro do palíndromo. Cada caractere ou par de caracteres consecutivos é considerado um possível "centro". O algoritmo expande em ambas as direções enquanto os caracteres forem iguais, retornando o maior palíndromo encontrado. ##### Versão 5....

BlackTDN :: Harbour/ADVPL :: Send/GetData uma alternativa a apconnxcontrol.ocx

Vimos, em Protheus :: apconnxcontrol.ocx with Harbour e Protheus :: apconnxcontrol.ocx, PowerShell e SendMessage para envio de Mensagem a Usuário Específico, que é possível a comunicação e transferência de dados usando apconnxcontrol.ocx. Um exemplo mais completo poderá ser obtido em “integração do Protheus com C# (Luis Gustavo Pessoa Lacombe)”.

O problema com apconnxcontrol.ocx é sua instalação. Temos que garantir que estaremos utilizando, sempre, a última versão do aplicativo.

Uma alternativa, na comunicação de dados entre aplicações externas e o protheus, poderá ser a técnica desenvolvida por Roberto Lopez (criador da Harbour MiniGui e mantenedor do fórum HMG Fórum para divulgação de suas idéias) para comunicação entre aplicações da HMG.hmg A idéia básica é que cada aplicação possua um Nome (StationName) e um local para Gravação/Compartilhamento dos Dados (CommPath). Os dados são gravados em arquivos Nomeados de acordo com o Destino.Origem e são enviados e recuperados, respectivamente, através das funções SendData e GetData (funções essas muito simples de implementar em qualquer linguagem). Uma idéia bem simples, de fácil implementação e que resolve muitos problemas de comunicação de dados e que não necessita de nenhum aplicativo adicional. Além disso é extensível (poderá ter os recursos ampliados de acordo com a necessidade e, se padronizado, servir como base de comunicação com qualquer aplicação).

As funções originais SendData e GetData foram adaptadas para o Protheus e, com isso, além de servirem para comunicação de dados entre aplicações da HMG poderão ser utilizadas para comunicação entre aplicações do Protheus e aplicações externas; como o próprio Harbour.

Veremos, agora, um exemplo de SendData e GetData usando uma aplicação em Harbour e, posteriormente, o mesmo exemplo usando o Protheus como Receptor/Transmissor dos Dados. Nele termos:

  1. Como aplicação receptora:  'John_Station' e;
  2. Como aplicação transmissora: 'Roberto_Station'

Os nomes dos exemplos originais do HMG foram mantidos.

O código, para o envio dos dados, baseado no HMG:

/*
* MINIGUI - Harbour Win32 GUI library Demo
*
* Copyright 2002 Roberto Lopez <harbourminigui@gmail.com>
* http://harbourminigui.googlepages.com/
*/

#include "minigui.ch"

Function Main

    Set StationName To 'Roberto_Station'
    Set CommPath    To 'D:\totvs\p10\ndj\pdata\comm\'

    DEFINE WINDOW Form_0 ;
        AT 0,0 ;
        WIDTH 640 HEIGHT 480 ;
        TITLE 'MiniGUI Communications Demo' ;
        ICON 'DEMO.ICO' ;
        MAIN ;
        FONT 'Arial' SIZE 10

        DEFINE MAIN MENU
            POPUP 'File'
                ITEM 'SendData'    ACTION SendTest()
                ITEM 'Exit'        ACTION Form_0.Release
            END POPUP
            POPUP 'Help'
                ITEM 'About'        ACTION MsgInfo ("MiniGUI Communications Demo")
            END POPUP
        END MENU

    END WINDOW

    CENTER WINDOW Form_0

    ACTIVATE WINDOW Form_0

Return Nil

Procedure SendTest
Local aData := {} , aMultiData := {}

    aAdd ( aData , 'Juan'      )
    aAdd ( aData , 'Carlos'  )
    aAdd ( aData , 'Roberto' )

    aAdd ( aMultiData , {'John','Smith','555-5555'} )
    aAdd ( aMultiData , {'Peter','Gomez','543-8372'} )
    aAdd ( aMultiData , {'Albert','Anderson','854-8273'} )

    SendData ( 'John_Station' , 100 )

    SendData ( 'John_Station' , Date() )

    SendData ( 'John_Station' , Time() )

    SendData ( 'John_Station' , .t. )

    SendData ( 'John_Station' , aData )

    SendData ( 'John_Station' , aMultiData )

Return

e, para a recepção:

/*
* MINIGUI - Harbour Win32 GUI library Demo
*
* Copyright 2002 Roberto Lopez <harbourminigui@gmail.com>
* http://harbourminigui.googlepages.com/
*/

#include "minigui.ch"

Function Main

    Set StationName To 'John_Station'
    Set CommPath    To 'D:\totvs\p10\ndj\pdata\comm\'

    DEFINE WINDOW Form_0 ;
        AT 0,0 ;
        WIDTH 640 HEIGHT 480 ;
        TITLE 'MiniGUI Communications Demo' ;
        ICON 'DEMO.ICO' ;
        MAIN ;
        FONT 'Arial' SIZE 10

        DEFINE MAIN MENU
            POPUP 'File'
                ITEM 'GetData'     ACTION GetTest()
                ITEM 'Exit'        ACTION Form_0.Release
            END POPUP
            POPUP 'Help'
                ITEM 'About'       ACTION MsgInfo ("MiniGUI Communications Demo")
            END POPUP
        END MENU

    END WINDOW

    CENTER WINDOW Form_0

    ACTIVATE WINDOW Form_0

Return Nil

Procedure GetTest()
Local r , i

    Repeat

        r := GetData()

        If Valtype (r) == 'A'

            If Valtype ( r [1] ) != 'A'

                Aeval ( r, { |i| MsgInfo( i ) } )

            Else

                For Each i In r

                    Aeval ( i, { |j| MsgInfo( j ) } )

                Next

            EndIf

        ElseIf r # Nil

            MsgInfo( r )

        EndIf

    Until r # Nil

Return

(Olha que interessante: Harbour suporta Repeat/Until)

Executando os exemplos do HMG teremos:

image

image

Os dados serão gravados em: D:\totvs\p10\ndj\pdata\comm conforme definição

image

e agora; usando GetDada:

image

image

image image image image image image

A cada dado obtido o arquivo que o originou é excluído até que todos os dados tenham sido recuperados e todos os arquivos excluídos.

image

Agora, o mesmo exemplo no Protheus:

Vou usar o Programa SendData em Harbour para Enviar os Dados e U_HBDataEx para recuperá-los a partir do Protheus.

image

image

image

image

e mostrar a saída no Browser:

image

O código do Exemplo de GetData, no Protheus, poderá ser obtido em: Source path: svn/trunk/harbour/samples/MiniGUI/comm/U_HBDataEx.prg ou através do svn/update em sua cópia local. O exemplo depende de: NDJLIB023.prg e NDJ.CH

No Exemplo abaixo, o Protheus Envia e Recebe os Dados. A opção de “Reenviar” é para o teste com captura pelo Harbour dos dados gerados pelo Protheus.

#INCLUDE "NDJ.CH"

#DEFINE HBDataExCommPath    "D:\totvs\p10\ndj\pdata\comm"

/*/
    Procedure:  HBDataEx
    Autor:      Marinaldo de Jesus
    Data:       22/02/2012
    Descricao:  Exemplo de Uso de GetData e SendData
    Sintaxe:    U_HBDataEx
/*/
USER PROCEDURE HBDataEx()
    MsgRun( "Aguarde...." , "Enviando Dados" , { || HBSDataEx() } )
    MsgRun( "Aguarde...." , "Obtendo Dados"  , { || HBGDataEx() } )
    IF MsgNoYes( "Reenviar os Dados" )
        MsgRun( "Aguarde...." , "Enviando Dados" , { || HBSDataEx() } )
    EndIF   
Return

/*/
    Procedure:  HBGDataEx
    Autor:      Marinaldo de Jesus
    Data:       22/02/2012
    Descricao:  Exemplo de Uso da GetData
    Sintaxe:    HBGDataEx
/*/
Static Procedure HBGDataEx()

    Local aData
    Local oData

    Set StationName To "John_Station"
    Set CommPath    To HBDataExCommPath

    aData    := StaticCall( NDJLIB023 , GetAllData )
    oData    := U_TVarInfoNew( aData , "HbGetData" )
    oData:Save(.T.,.F.)
    oData:Show()
    Sleep( 3000 ) //Wait 3 seconds to erase files

    oData:Close( .T. , .T. )

    oData := NIL

Return

/*/
    Procedure:  HBSDataEx
    Autor:      Marinaldo de Jesus
    Data:       22/02/2012
    Descricao:  Exemplo de Uso da SendData
    Sintaxe:    HBSDataEx
/*/
Static Procedure HBSDataEx()

    Local aData
    Local aMultData
    Local cDest    := "John_Station"

    Local nI
    Local nF        := 20
    Local nB
    Local nT

    Set StationName To "Robert_Station"
    Set CommPath    To HBDataExCommPath

    StaticCall( NDJLIB023 , SendData , cDest , "Olá" )
    StaticCall( NDJLIB023 , SendData , cDest , 123456.789 )
    StaticCall( NDJLIB023 , SendData , cDest , .T. )
    StaticCall( NDJLIB023 , SendData , cDest , .F. )
    StaticCall( NDJLIB023 , SendData , cDest , Date() )
    StaticCall( NDJLIB023 , SendData , cDest , Dtos(Date()) )

    aData    := {;
                     { "Naldo"     , Date() , .T. , 1500.00                        },;
                     { "OverFail"  , Date() - 100 , .F.            , 1500.00 * 4   },;
                     { "RLeg"      , Date() + 100 , .F. .or. .T.  , 1500.00 / 2   },;
                     { "OBona"     , Date() - 100 , .T. .and. .F. , 1500.00 * 100 },;
                     { "LF Altran" , Date() + 100 , .T. .and. .F. , 1500.00 * 2   },;
                     { "C Regazzo" , Date() - 100 , .T. .and. .F. , 1500.00 / 4   };
                }

    StaticCall( NDJLIB023 , SendData , cDest , aClone( aData ) )
    aMultData    := Array(0)
    nT           := Len( aData )

    For nI := 1 To nF
        For nB := 1 To nT
            aData[nB][1] := Embaralha( aData[nB][1] , 0 )
            aData[nB][2] := aData[nB][2] + nI
            aData[nB][3] := !( aData[nB][3] )
            aData[nB][4] += ( nB * nI )
            aAdd( aMultData , aClone( aData[nB] ) )
        Next nB   
    Next nI

    StaticCall( NDJLIB023 , SendData , cDest , aMultData )
    aSize( aMultData , 0 )
    aMultData := NIL

Return

Static Function __Dummy( lRecursa )
    Local oException
    TRYEXCEPTION
        lRecursa := .F.
        IF !( lRecursa )
            BREAK
        EndIF
        lRecursa    := __Dummy( .F. )
        SYMBOL_UNUSED( __cCRLF )
    CATCHEXCEPTION USING oException
    ENDEXCEPTION
Return( lRecursa )

image

image

[]s

иαldσ dj

Comentários

  1. Bom artigo. Legal ver que existem várias possibilidades de integração do Protheus com outras linguagens. Parabéns.

    ResponderExcluir

Postar um comentário

Postagens mais visitadas