Re: Dúvida Mestrado Engenharia Informática

    Rui Carlos
    By Rui Carlos,

    Pessoalmente apostaria no mestrado.  Contudo, convém que estejas consciente que podes acabar por não fazer todas as cadeiras à primeira.  Possivelmente até era capaz de ser boa ideia inscreveres-te apenas a metade das cadeiras do mestrado, e tentares fazer umas cadeiras de bases de programação (de licenciatura) como extra-curriculares.

    • 1 reply

    Ajuda com pendrive

    emausofia
    By emausofia,

    Boas amigos,

    Sou novato nestas andanças de programação, fiz uma aplicação em vb para gerir uma bd de access, com form, depois de inserir os dados nas cxs de texto, exporta para access os dados, depois disso, adicionei um botão para abrir um documento de word, com indicadores que irá ser preenchido com os dados do form.

    Até aqui tudo bem, funciona bem no pc. O meu problema é que não consigo passar para o pendrive, de forma automática.

    Vejam tenho estas linhas como caminho para os *.docx,


                Dim ArqModelo As String, NovoDocumento As String

                ArqModelo = "C:\Users\Tesouraria\Desktop\VS\APPI\mala.docx"
                NovoDocumento = "C:\Users\Tesouraria\Desktop\VS\APPI\Mala\mala2.docx"

     

    Como poderia substituir o C:\ pela letra do pendrive, sendo que essa letra varia, em função do pc que irei trabalhar.

    Desde já o meu obrigado pela ajuda.

     

     

    • 0 replies

    Re: AJAX: URLs amigáveis

    nmoa
    By nmoa,

    como assim ?

    • 2 replies

    Re: AJAX: URLs amigáveis

    HappyHippyHippo
    By HappyHippyHippo,

    não uses caminhos relativos

    • 2 replies

    Re: AJAX: URLs amigáveis

    nmoa
    By nmoa,

    boas

    tenho aqui uma questão

    o meu site esta com url amigáveis e eu gostaria de poder submeter um formulário através de ajax

    o problema que estou a encontrar é que não me esta a ler a pagina do url, pois como esta com url amigáveis ele não está abrir paginas dessa forma

    alguma solução para isto?

    obrigado

     $.ajax({
            url:"cnt/mail.php",
            data: dados,
            type:"post"
    }).done(function (resposta){
            console.log(resposta);
            //window.open("entrada.php?page=13","_self");
    });
    }

     

    • 2 replies

    Re: Utilizar Webservices da AT

    Sergio.
    By Sergio.,
    Em 27/09/2016 às 14:01, RicardoDeSousa disse:

    Boa Tarde,

    Estou a tentar utilizar o webservice da AT com a linguagem Python e continuo a receber  o mesmo erro, no campo NONCE.

    
    (...)

    Estou a tentar gerar o campo Nonce da seguinte maneira, sendo que o meu ficheiro "pubkey.pem" é a chave publica retirada do certificado ChavePublicaAT.cer :

    
    from Crypto.PublicKey import RSA
    from Crypto import Random
    
    session_key = Random.new().read(16)
    
    f = open('pubkey.pem','r')
    public_key = RSA.importKey(f.read())
    
    encrypted = public_key.encrypt(session_key, 'parametro irrelevante para efeitos compatibilidade')        
    NONCE = encrypted[0].encode('base64')

    Conseguem perceber o que estou a fazer de mal camaradas? Qualquer ajuda será bem vinda, obrigado em antecipação.

    Olá Ricardo

    Eu tenho a funcionar em Python desde o inicio :)

    Eu fiz assim:

    from Crypto.PublicKey import RSA
    from Crypto.Cipher import PKCS1_v1_5
    from Crypto.Protocol.KDF import PBKDF2
    from base64 import b64encode, b64decode
    
    (...)
    
    #### RSA #####
    # com a ChavePublicaAT.cer
    # openssl x509 -inform pem -in ChavePublicaAT.cer -pubkey -noout > pubatcrt.pem
    #
    
    tmp=open('data/pubatcrt.pem','r')
    chave=RSA.importKey(tmp.read())
    tmp.close()
    encriptar=PKCS1_v1_5.new(chave)
    nonce=encriptar.encrypt(simetrica)
    bnonce=b64encode(nonce)
    
    (...)

    Espero ter ajudado

    • 6935 replies

    Re: Dados intercalados em DataGridView

    _Rest_
    By _Rest_,

    Conseguiste? Como não dizes nada, deixo aqui um exemplo

    No teu exemplo --> table1 ID Nome Idade Sexo  Table2 --> ID Comentario

    Metes as duas tables num DataSet e depois fazes:

    DataSet ds = new DataSet();
    
    //o teu codigo para carregar os dados da BD para o DataSet
    
    ds.Relations.Add("NomeDaRelação", ds.Tables[0].Columns["ID"], ds.Tables[1].Columns["ID"]);
    
    (tuaGrid).DataSource = ds;

    A sintaxe pode ser um bocado diferente porque uso Infragistics

    Na ultraGrid fico com 

    Nome Idade Sexo

     --comentario

    Nome Idade Sexo

     --comentario

     

    Tens que fazer o Hide ao ID claro

    • 6 replies

    Re: AltGr no IPython

    António Oliveira
    By António Oliveira,

    O problema não é do IPython. Como eu disse, estou no Windows, mas em vez de estar a usar a linha de comandos do Windows estava a usar o Git Bash para Windows. O problema deve vir daí.

    • 5 replies

    Re: AltGr no IPython

    António Oliveira
    By António Oliveira,

    Já agora, a combinação Ctrl + Alt, que é equivalente a AltGr, não funciona no ipython.

     

    • 5 replies

    Re: AltGr no IPython

    António Oliveira
    By António Oliveira,

    Obrigado pela resposta. Estou a usar Windows e o problema com as chavetas e parênteses e tudo o que tenha que introduzir usando a tecla AltGr só ocorrem no IPython. Já se abrir

    ipython qtconsole

    ou

    jupyter qtconsole

     

    deixo de ter esse problema. No entanto, isso não é muito conveniente, porque se usar por exemplo

    ipython --pylab

    continuo com o problema, e é nesse ambiente que queria trabalhar.

     

    Vou tentar ver se há algo equivalente às recomendações para Windows.

    • 5 replies

    Re: AltGr no IPython

    Nilo Menezes
    By Nilo Menezes,

    Fora do IPython os acentos funcionam normalmente? Digo {} e ()?

    Você está usando Linux ou Windows?

    Eu tive problemas no Linux usando LANG=C

    Se for Linux, tenta:

    # locale -a
    C
    C.UTF-8
    POSIX
    pt_PT.utf8

    Deve aparecer pt_PT.utf8.

    export LANG=pt_PT.utf8
    ipython

    Comigo resolveu o problema.

    Se você não instalou pt_PT.utf8, instale com:

    locale-gen pt_PT.utf8

     

    • 5 replies

    Re: AT - questões legais

    davdew05
    By davdew05,

    Bom dia a Todos,

    Uma pergunta rápida :)

    Tenho a seguinte situação: um cliente meu colocou numa fatura uma oferta Unitprice : 10€ Quantity:10 (para ser fácil). Esta linha, como é oferta, não entra nos cálculos dos totais...  

    No saft tenho a seguinte representação: Unitprice:0€, Quantity:10, CreditAmount:0€, SettlementAmount:100€. Isto está certo?

    Desde já obrigado pela ajuda.

    Cumprimentos,

    • 4264 replies

    Re: AltGr no IPython

    António Oliveira
    By António Oliveira,

    Talvez a resposta seja usar a QtConsole? Reparei que o problema que relatei desaparece, usando essa.

    • 5 replies

    Re: AltGr no IPython

    António Oliveira
    By António Oliveira,

    Bom dia. Estou com um problema em digitar caracteres que precisam de que se prima a tecla AltGr (como as chavetas ou os parênteses rectos) na linha de comandos do IPython. Na verdade, não consigo digitar esses caracteres. Alguém me pode ajudar?

    • 5 replies

    Re: Enviar valores para formulario em Angular

    Knitter
    By Knitter,

    O pedido é feito na mesma em POST, tens é de encontrar o URL que está a ser usado e garantir que estás a usar os mesmos cabeçalhos no pedido, mas não muda nada em relação a um form "normal". Tens é de encontrar o URL no código JS ou analisar um pedido na página da portal para veres onde está a ser feito o acesso ao servidor, pode ser em mais que um pedido.

    • 1 reply

    Re: Enviar valores para formulario em Angular

    nportugal
    By nportugal,

    Boas,

    O portal das finanças alterou a forma de emitir os recibos verdes e agora é através de um formulário em angular. No formato anterior, formulário HTML, utilizava uma base de dados em mysql para os clientes e serviços e "postava" via PHP directamente para a página da A.T e o recibo "autopreenchia-se" mas agora com o Angular já não funciona.

    Já tentei enviar os valores via JSON mas também não aceita. Alguém sabe uma técnica para enviar dados externos para angular ?

     

    • 1 reply

    Re: Que plataforma escolher para elaboração de uma página?

    Knitter
    By Knitter,
    10 horas atrás, mcosta78 disse:

    Agora tenho de fazer uma mas aí a minha duvida, devo fazer tudo a mão ou utilizar uma plataforma como wordpress...

    Depende do que pretendes, uma "página" não costuma necessitar de uma base de dados, se quiseres uma plataforma para gestão de conteúdos, o Wordpress é uma opção existem inúmeros CMS que podes usar, vai um pouco da preferência de cada um.

     

    9 horas atrás, mcosta78 disse:

    mas tenho uma dúvida que é capaz de me esclarecer. Para teste e executar sem alojar a pagina devo instalar o wordpress dentro do xampp para correr em localhost.

    Agora a minha dúvida: a base de dados assi crio-a no xampp e faço as ligações em php (em código) ou utilizo o mysql que traz o wordpress??

    Isso está um bocado confuso :), o Wordpress não tem o MySQL (nem faz muito sentido), precisas sempre de instalar o servidor de bases de dados (MySQL), o servidor WEB (Apache Webserver) e o runtime de PHP em que o Wordpress é desenvolvido. O XAMPP traz isso tudo preparado para instalação simples, para facilitar o desenvolvimento de software, mas tens de ter todo o ambiente preparado para instalares o Wordpress (ou qualquer outro CMS baseado em PHP), e vais colocar os ficheiros na pasta htdocs (ou www, já não sei o que é que XAMPP usa). Vê o site do Wordpress porque tens lá instruções de instalação e o CMS tem um instalador (uma página própria que usas na primeira vez) que irá verificar se tens os requisitos todos, criar a base de dados no teu servidor MySQL e registar todas as configurações.

    • 3 replies

    Programar 53 . algoritmo dijkstra, c + linked list + priority queue

    HappyHippyHippo
    By HappyHippyHippo,

    Após ler o artigo na revisto Programar, edição 53 de Agosto de 2016, com o tema Algoritmo de Dijkstra, só me ocorreu uma coisa.

    A autora do artigo foi a própria a afirmar que a sua implementação é somente uma de várias maneiras de abordar o problema. No entanto, eu nunca gostei a solução de uso de uma tabela/matriz para a resolução do problema. Sempre achei que é um desperdício de memória e origina um código menos intuitivo do que o algoritmo realmente está a fazer.

    Para isso, aqui está uma solução em C, que usa linked lists e uma priority queue (que para mim é provavelmente a solução mais fácil de perceber)

    main.c

    #include "graph.h"
    
    #include <stdlib.h>
    #include <stdio.h>
    
    #define SOURCE "A"
    #define DESTINATION "E"
    
    int main(int argc, char ** argv) {
        Graph * graph = NULL;
    
        if ((graph = graph_create()) == NULL) {
            printf("Error allocation graph memory\n");
            exit(-1);
        }
    
        graph_add_node(graph, "G");
        graph_add_node(graph, "F");
        graph_add_node(graph, "E");
        graph_add_node(graph, "D");
        graph_add_node(graph, "C");
        graph_add_node(graph, "B");
        graph_add_node(graph, "A");
    
        graph_node_add_edge(graph_get_node(graph, "A"), 14, graph_get_node(graph, "F"));
        graph_node_add_edge(graph_get_node(graph, "A"),  9, graph_get_node(graph, "C"));
        graph_node_add_edge(graph_get_node(graph, "A"),  7, graph_get_node(graph, "B"));
    
        graph_node_add_edge(graph_get_node(graph, "B"), 15, graph_get_node(graph, "D"));
        graph_node_add_edge(graph_get_node(graph, "B"), 10, graph_get_node(graph, "C"));
        graph_node_add_edge(graph_get_node(graph, "B"),  7, graph_get_node(graph, "A"));
    
        graph_node_add_edge(graph_get_node(graph, "C"),  2, graph_get_node(graph, "F"));
        graph_node_add_edge(graph_get_node(graph, "C"), 11, graph_get_node(graph, "D"));
        graph_node_add_edge(graph_get_node(graph, "C"), 10, graph_get_node(graph, "B"));
        graph_node_add_edge(graph_get_node(graph, "C"),  9, graph_get_node(graph, "A"));
    
        graph_node_add_edge(graph_get_node(graph, "D"),  6, graph_get_node(graph, "E"));
        graph_node_add_edge(graph_get_node(graph, "D"), 11, graph_get_node(graph, "C"));
        graph_node_add_edge(graph_get_node(graph, "D"), 15, graph_get_node(graph, "B"));
    
        graph_node_add_edge(graph_get_node(graph, "E"),  9, graph_get_node(graph, "F"));
        graph_node_add_edge(graph_get_node(graph, "E"),  6, graph_get_node(graph, "D"));
    
        graph_node_add_edge(graph_get_node(graph, "F"),  9, graph_get_node(graph, "E"));
        graph_node_add_edge(graph_get_node(graph, "F"),  2, graph_get_node(graph, "C"));
        graph_node_add_edge(graph_get_node(graph, "F"), 14, graph_get_node(graph, "A"));
    
        graph_print(graph);
    
        GraphEdge ** path = graph_path(graph, graph_get_node(graph, SOURCE), graph_get_node(graph, DESTINATION));
    
        if (!(* path)) {
            printf("No path");
        } else {
            printf("N(%s) ", SOURCE);
    
            GraphEdge ** it = path;
            while (* it) {
                printf("-> E(%2d -> %s)", (*it)->cost, (*it)->target->ID);
                it++;
            }
        }
    
        free(path);
        graph_destroy(& graph);
    
        return 0;
    }

    graph.h

    #ifndef GRAPH_H
    #define GRAPH_H
    
    /// Tipos de dados usados na definição de uma (di)grafo
    typedef struct GraphEdge GraphEdge;
    typedef struct GraphNode GraphNode;
    typedef struct Graph Graph;
    
    /// Estrutura usada para guardar a informação de uma aresta do (di)grafo
    struct GraphEdge {
        GraphNode * owner;
        GraphEdge * next;
    
        unsigned int cost;
        GraphNode * target;
    };
    
    /// Estrutura usada para guardar a informação de um nó do (di)grafo
    struct GraphNode {
        Graph * owner;
        GraphNode * next;
    
        char * ID;
        GraphEdge * edge_list;
        unsigned int edge_count;
    
        struct {
            GraphEdge * path;
            unsigned int cost;
            unsigned int steps;
        } tree;
    };
    
    /// Estrutura usada para guardar a informação de um (di)grafo
    struct Graph {
        GraphNode * node_list;
        unsigned int node_count;
    };
    
    /// Função construtora de uma (di)grafo
    ///
    /// @return Ponteiro para o (di)grafo criado
    Graph * graph_create(void);
    
    /// Função de destruição/libertação de memória de um (di)grafo
    ///
    /// @param graph Referência para o ponteiro pque guarda o (di)grafo a ser
    ///              destruido
    ///
    /// @return Valor inteiro que indica sucesso da operação ao ter o valor de zero
    ///          ou erro caso contrário
    int graph_destroy(Graph ** graph);
    
    /// Função usada para adicionar um novo nó ao (di)grafo
    ///
    /// @param graph Referência ao (di)grafo que irá conter o nó criado
    /// @param ID    String com o nome identificador do nó a ser criado
    ///
    /// @return Ponteiro para o nó criado
    GraphNode * graph_add_node(Graph * graph, char * ID);
    
    /// Função usada para obter um nó do (di)grafo
    ///
    /// @param graph Referência ao (di)grafo que contem o nó a ser obtido
    /// @param ID    String com o nome identificador do nó a ser obtido
    ///
    /// @return Ponteiro para o nó encontrado
    GraphNode * graph_get_node(Graph * graph, char * ID);
    
    /// Função usada para remover um nó do (di)grafo
    ///
    /// @param graph Referência ao (di)grafo que contem o nó a ser removido
    /// @param ID    String com o nome identificador do nó a ser removido
    ///
    /// @return Valor inteiro que indica sucesso da operação ao ter o valor de zero
    ///          ou erro caso contrário
    int graph_remove_node(Graph * graph, char * ID);
    
    /// Função usada para adicionar uma nova aresta a um nó do (di)grafo
    ///
    /// @param node  Referência ao nó do (di)grafo que irá conter a nova aresta
    /// @param cost  Valor de custo de transitar na aresta
    /// @para target Referência ao nó destino da aresta
    ///
    /// @return Ponteiro para a aresta criado
    GraphEdge * graph_node_add_edge(GraphNode * node, unsigned int cost, GraphNode * target);
    
    /// Função usada para obter uma aresta de um nó do (di)grafo
    ///
    /// @param node  Referência ao nó do (di)grafo que contem a aresta a ser obtida
    /// @param index Índice da aresta a ser obtida
    ///
    /// @return Ponteiro para a aresta obtida
    GraphEdge * graph_node_get_edge(GraphNode * node, unsigned int index);
    
    /// Função usada para remover uma aresta de um nó do (di)grafo
    ///
    /// @param node  Referência ao nó do (di)grafo que contem a aresta a ser
    ///              removida
    /// @param index Índice da aresta a ser removida
    ///
    /// @return Valor inteiro que indica sucesso da operação ao ter o valor de zero
    ///          ou erro caso contrário
    int graph_node_remove_edge(GraphNode * node, unsigned int index);
    
    /// Função de escrita do (di)grafo na consola
    ///
    /// @param graph Referência do (di)grafo a ser imprimido
    ///
    /// @return Valor inteiro que indica sucesso da operação ao ter o valor de zero
    ///          ou erro caso contrário
    int graph_print(Graph * graph);
    
    /// Função de determinação do caminho mais curto
    ///
    /// @param graph Referência do (di)grafo onde a pesquisa de percurso irá ser
    ///              efectuada
    /// @param src   Referência ao nó de origem do caminho a ser pesquisado
    /// @param dest  Referência ao nó de destino do caminho a ser pesquisado
    ///
    /// @return Lista de aresta que compoem o caminho encontrado
    ///         Esta lista é alocada internamente e deverá ser libertada
    ///         posteriormente
    GraphEdge ** graph_path(Graph * graph, GraphNode * src, GraphNode * dest);
    
    #endif

    graph.c

    #include "graph.h"
    
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    
    // PRIVATE ----------------------------------------------------------------
    
    /// Função de destruição de uma aresta
    ///
    /// @param edge Referência ao ponteiro que guarda a aresta a ser destruida
    ///
    /// @return Valor inteiro que indica sucesso da operação ao ter o valor de zero
    ///          ou erro caso contrário
    int graph_destroy_edge(GraphEdge ** edge) {
        // validar argumentos
        if (!edge || !(*edge))
            return -1;
    
        // libertar a memória da aresta
        free(* edge);
        * edge = NULL;
    
        return 0;
    }
    
    /// Função de destruição de um nó
    ///
    /// @param node Referência ao ponteiro que guarda o nóa a ser destruido
    ///
    /// @return Valor inteiro que indica sucesso da operação ao ter o valor de zero
    ///          ou erro caso contrário
    int graph_destroy_node(GraphNode ** node) {
        // validar argumentos
        if (!node || !(*node))
            return -1;
    
        // ciclo de libertação de memória das arestas do nó
        GraphNode * aux = (GraphNode *) * node;
        while (aux->edge_count) {
            GraphEdge * del = aux->edge_list;
            aux->edge_list = aux->edge_list->next;
            aux->edge_count--;
    
            graph_destroy_edge(& del);
        }
    
        // libertar a memória do nó
        free((* node)->ID);
        free(* node);
        * node = NULL;
    
        return 0;
    }
    
    /// Função de impressão de uma aresta na consola
    ///
    /// @param edge Referência â aresta que irá ser imprimida
    ///
    /// @return Valor inteiro que indica sucesso da operação ao ter o valor de zero
    ///          ou erro caso contrário
    int graph_print_edge(GraphEdge * edge) {
        // validar argumentos
        if (!edge)
            return -1;
    
        // aprestar a informação da aresta
        printf(" E(%2d -> %s),", edge->cost, edge->target->ID);
    
        return 0;
    }
    
    /// Função de impressão de um nó na consola
    ///
    /// @param node Referência ao nó que irá ser imprimido
    ///
    /// @return Valor inteiro que indica sucesso da operação ao ter o valor de zero
    ///          ou erro caso contrário
    int graph_print_node(GraphNode * node) {
        // validar argumentos
        if (!node)
            return -1;
    
        // aprestar a informação do nó
        printf("    N(%s) -> ", node->ID);
    
        // ciclo de apresentação das arestas do nó
        GraphEdge * edge = node->edge_list;
        while (edge) {
            graph_print_edge(edge);
            edge = edge->next;
        }
        printf("\n");
    
        return 0;
    }
    
    /// Função usada para remover todas as arestas de um nó que tem como destino um
    /// nó definido pelo ID dado como argumento da chamada da função
    /// Esta implementação é necessária para garantir a coerencia dos dados após a
    /// remoção de um nó de forma a eliminiar aresta para nós removidos
    ///
    /// @param node Referência do nó que contem as arestas a serem elimindas
    /// @param ID   Identificador do nó de destino das arestas a serem eliminadas
    ///
    /// @return Valor inteiro que indica sucesso da operação ao ter o valor de zero
    ///          ou erro caso contrário
    int graph_node_remove_edges_to(GraphNode * node, char * ID) {
        // validar argumentos
        if (!node || !ID)
            return -1;
    
        GraphEdge * del = NULL;
    
        // ciclo de remoção das arestas que sáo encontradas no início da lista
        while (node->edge_list && strcmp(node->edge_list->target->ID, ID) == 0) {
            del = node->edge_list;
            node->edge_list = node->edge_list->next;
    
            graph_destroy_edge(& del);
            node->edge_count--;
        }
    
        // ciclo de pesquisa e remoção das arestas no mei oda lista
        GraphEdge * it = node->edge_list;
        while (it && it->next) {
            if (strcmp(it->next->target->ID, ID) == 0) {
                del = it->next;
                it->next = it->next->next;
    
                graph_destroy_edge(& del);
                node->edge_count--;
            } else
                it = it->next;
        }
    
        return 0;
    }
    
    /// Tipo de dados que implementa um priority queue de arestas a ser usada
    /// durante a execução do "dijkstra algorihtm"
    typedef struct GraphEdgeQueue {
        struct GraphEdgeQueue * next;
        GraphEdge * edge;
    } GraphEdgeQueue;
    
    /// Função que insere uma aresta na queue tendo como parâmetro de prioridade, o
    /// custo associado ao processo dado pelo custo a aresta adicionado ao custo
    /// já calculado para chegar ao nó origem da aresta inserida
    ///
    /// @param queue Referência à queue que irá guardar a aresta a ser inserida
    /// @param edge  Referência à aresta a ser inserida na queue
    ///
    /// @return Referência à queue final
    GraphEdgeQueue * graph_edge_queue_push(GraphEdgeQueue * queue, GraphEdge * edge) {
        // validar argumentos
        if (!edge)
            return queue;
    
        // alocar memória para a nova entrada da queue
        GraphEdgeQueue * entry = NULL;
        if ((entry = malloc(sizeof(GraphEdgeQueue))) == NULL)
            return NULL;
    
        // inicializar a entrada
        entry->edge = edge;
        entry->next = NULL;
    
        // verificar se a queue se encnotra vazia ou que mesmo assim, a aresta
        // deverá ser inserida na primeira posição da queue (maior prioridade)
        if (!queue || queue->edge->owner->tree.cost + queue->edge->cost > entry->edge->owner->tree.cost + entry->edge->cost) {
            entry->next = queue;
            queue = entry;
        } else {
            // ciclo de pesquisa pela posição da queue onde a aresta deverá ser
            // inserida
            GraphEdgeQueue * it = queue;
            while (it->next && it->next->edge->owner->tree.cost + it->next->edge->cost <= entry->edge->owner->tree.cost + entry->edge->cost)
                it = it->next;
    
            // inserir a entrada na posição encontrada
            entry->next = it->next;
            it->next = entry;
        }
    
        return queue;
    }
    
    /// Função usada para remover um elemento da queue
    ///
    /// @param queue Referência à queue que contem a aresta a ser removida
    /// @param edge  Referência para um ponteiro que irá guardar a aresta removida
    ///
    /// @return Referência à queue final
    GraphEdgeQueue * graph_edge_queue_pop(GraphEdgeQueue * queue, GraphEdge ** edge) {
        // validar argumentos
        if (!queue || !edge)
            return queue;
    
        // remoção da entrada à cabeça
        GraphEdgeQueue * del = queue;
        queue = queue->next;
        * edge = del->edge;
    
        // libertação da memoria alocada para a entrada da queue
        free(del);
    
        return queue;
    }
    
    // PUBLIC ----------------------------------------------------------------
    
    Graph * graph_create(void) {
        Graph * graph = NULL;
    
        // alocação de memória para o (di)grafo
        if ((graph = malloc(sizeof(Graph))) != NULL) {
            graph->node_list = NULL;
            graph->node_count = 0;
        }
    
        return graph;
    }
    
    int graph_destroy(Graph ** graph) {
        // validar argumentos
        if (!graph || !(*graph))
            return -1;
    
        // ciclo de libertação de memória dos nós do (di)grafo
        Graph * aux = (Graph *) * graph;
        while (aux->node_count) {
            GraphNode * del = aux->node_list;
            aux->node_list = aux->node_list->next;
            aux->node_count--;
    
            graph_destroy_node(& del);
        }
    
        // libertação de memória
        free(* graph);
        * graph = NULL;
    
        return 0;
    }
    
    GraphNode * graph_add_node(Graph * graph, char * ID) {
        // validar argumentos
        if (!graph || !ID)
            return NULL;
    
        GraphNode * node = NULL;
    
        // alocação de memória para o nó a ser inserido
        if ((node = malloc(sizeof(GraphNode))) == NULL)
            return NULL;
    
        size_t length = strlen(ID) + 1;
        if ((node->ID = malloc(length)) == NULL) {
            free(node);
            return NULL;
        }
    
        // inicialização do nó criado
        strcpy(node->ID, ID);
        node->owner = graph;
        node->next = graph->node_list;
        node->edge_list = NULL;    
        node->edge_count = 0;
        node->tree.path = NULL;
        node->tree.cost = 0;
        node->tree.steps = 0;
    
        // inserir o nó à cabeça da lista de nós do (di)grafo
        graph->node_list = node;
        graph->node_count++;
    
        return node;
    }
    
    GraphNode * graph_get_node(Graph * graph, char * ID) {
        // validar argumentos
        if (!graph || !ID)
            return NULL;
    
        // ciclo de pesquisa pelo no pretendido
        GraphNode * node = graph->node_list;
        while (node && strcmp(node->ID, ID) != 0)
            node = node->next;
    
        return node;
    }
    
    int graph_remove_node(Graph * graph, char * ID) {
        // validar argumentos
        if (!graph || !ID)
            return -1;
    
        // verificar se o (di)grafo náo tem nós
        if (!graph->node_list)
            return -2;
    
        GraphNode * it = NULL;
        GraphNode * del = NULL;
    
        // verificar se o nó a ser removido encontrasse à cabeça da lista
        if (strcmp(graph->node_list->ID, ID) == 0) {
            del = graph->node_list;
            graph->node_list = graph->node_list->next;
        } else {
            // ciclo de pesquisa pelo nó a ser removido
            it = graph->node_list;
            while (it->next && strcmp(it->next->ID, ID) != 0)
                it = it->next;
    
            // verificar se o nó foi encontrado e remover-lo da lista
            if (it->next) {
                del = it->next;
                it->next = it->next->next;
            }
        }
    
        // verificar se o nó foi encontrado
        if (!del)
            return -2;
    
        // remover de todos os nós que ficaram na lista, as arestas que possuem como
        // destino, o nó removido
        it = graph->node_list;
        while (it) {
            graph_node_remove_edges_to(it, ID);
            it = it->next;
        }
    
        // destruição do nó removido
        graph_destroy_node(& del);
        graph->node_count--;
    
        return 0;
    }
    
    GraphEdge * graph_node_add_edge(GraphNode * node, unsigned int cost, GraphNode * target) {
        // validar argumentos
        if (!node || !target || node->owner != target->owner)
            return NULL;
    
        // alocação de memória da aresta a ser criada
        GraphEdge * edge = NULL;
        if ((edge = malloc(sizeof(GraphEdge))) == NULL)
            return NULL;
    
        // inicialização da aresta alocada
        edge->owner = node;
        edge->next = node->edge_list;
        edge->cost = cost;
        edge->target = target;
    
        // inserir a aresta criada à cabeça de aresta do nó
        node->edge_list = edge;
        node->edge_count++;
    
        return edge;
    }
    
    GraphEdge * graph_node_get_edge(GraphNode * node, unsigned int index) {
        // validar argumentos
        if (!node || node->edge_count <= index)
            return NULL;
    
        // ciclo de pesquisa da aresta pretendida
        unsigned int it = 0;
        GraphEdge * edge = node->edge_list;
        while (it != index) {
            edge = edge->next;
            it++;
        }
    
        return edge;
    }
    
    int graph_node_remove_edge(GraphNode * node, unsigned int index) {
        // validar argumentos
        if (!node || node->edge_count <= index)
            return -1;
    
        GraphEdge * del = NULL;
    
        // verificar se a aresta a ser removido se necontra à cabeça da lista
        if (index == 0) {
            del = node->edge_list;
            node->edge_list = node->edge_list->next;
        } else {
            // ciclo de pesquisa pela aresta a ser removida
            unsigned int it = 0;
            GraphEdge * edge = node->edge_list;
            while (it != index - 1) {
                edge = edge->next;
                it++;
            }
    
            // remove a aresta encontrada da lista
            del = edge->next;
            edge->next = edge->next->next;
        }
    
        // destruição da aresta removida
        graph_destroy_edge(& del);
        node->edge_count--;
    
        return 0;
    }
    
    int graph_print(Graph * graph) {
        // validar argumentos
        if (!graph)
            return -1;
    
        printf("Graph :\n");
    
        // ciclo de impressãodos nós do (di)grafo
        GraphNode * node = graph->node_list;
        while (node) {
            graph_print_node(node);
            node = node->next;
        }
    
        return 0;
    }
    
    GraphEdge ** graph_path(Graph * graph, GraphNode * src, GraphNode * dest) {
        // validar argumentos
        if (!graph || !src || src->owner != graph || !dest || dest->owner != graph)
            return NULL;
    
        // inicialização dos dados de criação/composição da árvore de menor custo
        GraphNode * node = graph->node_list;
        while (node) {
            node->tree.path = NULL;
            node->tree.cost = 0;
            node->tree.steps = 0;
            node = node->next;
        }
    
        GraphEdgeQueue * queue = NULL;
        GraphNode * current = src;
        GraphEdge * edge = NULL;
    
        // ciclo que implementa o "dijkstra algorithm"
        current->tree.path = (GraphEdge * ) 1;
        do {
            // ciclo de inserção da lista de aresta do último nó que foi inserido na
            // árvore de menor custo
            edge = current->edge_list;
            while (edge) {
                // verificar se a aresta tem como destino um nó que já se encontra
                // na árvore de menor custo
                if (!edge->target->tree.path)
                    queue = graph_edge_queue_push(queue, edge);
                edge = edge->next;
            }
    
            // verificar se exsitem arestas na queue
            if (queue) {
                // pesquisa pela aresta de menor custo na queue que não como destino
                // um nó que já se encontra na árvore de menor custo
                do {
                    edge = NULL;
                    queue = graph_edge_queue_pop(queue, & edge);
                } while (edge && edge->target->tree.path);
    
                // verificar se void encontrada um aresta válida
                if (edge) {
                    // inserir o nó destino da aresta na árvore de menor custo
                    current = edge->target;
                    current->tree.path = edge;
                    current->tree.cost = edge->owner->tree.cost + edge->cost;
                    current->tree.steps = edge->owner->tree.steps + 1;
                }
            }
        } while (queue && current != dest);
    
        // ciclo de limpeza/destruição da queue
        while (queue)
            queue = graph_edge_queue_pop(queue, &edge);
    
        // gerar a lista de arestas que indicará a caminho encontrado
        GraphEdge ** path = NULL;
        unsigned int path_length = graph->node_count + 1;
        if ((path = malloc(sizeof(GraphEdge *) * path_length)) == NULL)
            return NULL;
        memset(path, 0, sizeof(GraphEdge *) * path_length);
    
        // verificar se o algoritmo encontrou um caminho
        if (current == dest) {
            // ciclo de escrita/composição do caminho encontrado no array alocado
            while (current != src) {
                path[current->tree.steps - 1] = current->tree.path;
                current = current->tree.path->owner;
            }
        }
    
        return path;
    }

     

    • 0 replies

    Re: Que plataforma escolher para elaboração de uma página?

    mcosta78
    By mcosta78,

    Olá Jpaulino ok obrigado pela resposta!!

     

    vou investigar o wordpress...

    mas tenho uma dúvida que é capaz de me esclarecer. Para teste e executar sem alojar a pagina devo instalar o wordpress dentro do xampp para correr em localhost.

     

    Agora a minha dúvida: a base de dados assi crio-a no xampp e faço as ligações em php (em código) ou utilizo o mysql que traz o wordpress??

    • 3 replies

    Re: Que plataforma escolher para elaboração de uma página?

    jpaulino
    By jpaulino,

    Eu recomendo para a maioria dos casos o Wordpress.

    Tem base de dados (mysql), backoffice, actualizações (muitas delas de segurança), imensos temas (preparados para diferentes devices), imensos plugins, etc, etc

    • 3 replies

  1. Load more activity
Portal by DevFuse · Based on IP.Board Portal by IPS