Planet.DebianPT.org

Graciano TorrãoConstrução de algoritmos em Pseudocódigo – enquanto … fazer … fimfazer

Trata-se de uma estrutura de repetição, controlada pela avaliação do valor lógico de uma condição.

Este tipo de estruturas são geralmente designadas por “ciclos“.

enquanto <condição>
fazer
    instrução 1
    instrução 2
    . . .
    instrução n
fimfazer

Assim temos:

  • <condição> é uma expressão lógica que, sendo verdadeira, determina que se voltem a executar as instruções contidas no ciclo. Caso esta expressão tenha o valor lógico falso, o controlo passa para a instução seguinte, sendo o ciclo abandonado.
  • instrução 1 … instrução n  corresponde ao bloco de instruções que vão ser executados em cada iteração (entenda-se iteração como uma “volta”, tendo presente a noção de cliclo).

Este tipo de estrutura tem infinitas aplicações mas, em termos genéricos, podemos afirmar que se utiliza sempre que:

  • pretendermos repetir 0 bloco de instruções um número indeterminado de vezes;
  • o número de iterações, ou seja, o número de vezes que se repete o ciclo, depende do valor lógico da candição;
  • fazendo variar os valores das variáveis que são utilizadas na condição permite controlar o respetivo valor lógico, consequentemente, continuar a iterar ou terminar.

Vamos pensar, a título de exemplo, no seguinte problema:

“Dada uma sequência de números, terminada por um número negativo, calcular a média dos seus elementos.”

Algoritmo em pseudocódigo

Nome MédiaN
Descrição
    Dada uma sequência de números, cujo fim é assinalado por um número
    negativo, este algoritmo calcula a respetiva média.
Variáveis
    contar: Inteiros
    num, soma, média: Real
Início
    contar ← 0
    soma ← 0
    ler (num)
    enquanto ( num >= 0 )
    fazer
        contar ← contar + 1
        soma ← soma + num
        ler (num)
    fimfazer
    média ← soma / contar
    escrever (média)
fim

Seguem-se uma implementação deste problema.

Em linguagem C++

#include <iostream>
using namespace std;
int main()
{
    int contar;
    double num, soma, media;
    contar = 0;
    soma = 0;
    cin >> num;
    while(num >=0)
    {
        contar = contar + 1;
        soma = soma + num;
        cin >> num;
    }
    media = soma/contar;
    cout << media;
    return 0;
}
Anterior Índice Seguinte

Graciano TorrãoConstrução de algoritmos em Pseudocódigo – selecionar caso … fimselecionar

Depois de alguns exercício a aplicar a estrutura se… então… senão… fimse, provavelmente acabamos por concluir que, em certos casos específicos, não é muito prática a sua utilização.

Vamos pensar, a título de exemplo, no seguinte problema:

“Dado um número inteiro, compreendido entre 1 e 4, representando os quatro trimestres do ano, vamos fazer corresponder a sua descrição por extenso.”

Algoritmo em pseudocódigo

Nome Trimestres
Descrição
    Dado um número inteiro, compreendido entre 1 e 4, representando
    os quatro trimestres do ano, este programa faz corresponder a
    sua descrição por extenso.
Variáveis
    trimestre: Inteiro
Início
    ler (trimestre)
    se trimestre = 1
    então   escrever("Primeiro trimestre")
    senão   se trimestre = 2
            então   escrever("Segundo trimestre")
            senão   se trimestre = 3
                    então   escrever("Terceiro trimestre")
                    senão   se trimestre = 4
                            então   escrever("Quarto trimestre")
                            senão   escrever("ERRO!")
                            fimse
                    fimse
            fimse
    fimse
fim

Neste ponto já somos convidados a pensar como ficaria esta estrutura encadeada para outros exemplos como:

  • os dias da semana;
  • os meses do ano;
  • os signos;

Felizmente existe uma estrutura de escolha múltipla, ou de seleção, que se adequa melhor a estas situações.

Trata-se da estrutura “selecionar caso … fim caso“.

Esta estrutura representa-se assim em pseudocódigo:

    selecionar caso <variável>
        <valor1>: <instruções a executar quando ocorre o valor 1>
        <valor2>: <instruções a executar quando ocorre o valor 2>
        <valor3>: <instruções a executar quando ocorre o valor 3>
         ...
        [senão  : <instruções a executar quando falham todos os valores acima previstos>]

Assim temos:

  • <variável> é uma variável cujo valor pretendemos selecionar.
  • <valor1> trata-se de um valor que, no caso de coincidir com o conteúdo da variável, determina a execução das instruções associadas.
  • [ ... ] a parte do comando relativa ao senão, ou seja, quando todos os valores previstos falharem, é executada esta. A sua utilizaçao é opcional.

O algoritmo ficaria então com este aspeto:

Nome Trimestres
Descrição
    Dado um número inteiro, compreendido entre 1 e 4, representando
    os quatro trimestres do ano, este programa faz corresponder a
    sua descrição por extenso.
Variáveis
    trimestre: Inteiro
início
    ler (trimestre)
    selecionar caso trimestre
        1:  escrever("Primeiro trimestre")
        2:  escrever("Segundo trimestre")
        3:  escrever("Terceiro trimestre")
        4:  escrever("Quarto trimestre")
        senão
            escrever("ERRO!")
    fimselecionar
fim

Seguem-se uma implementação deste problema.

Em linguagem C++

#include <iostream>
using namespace std;
int main()
{
    int trimestre;
    cin >> trimestre;
    switch(trimestre)
    {
        case 1:
            cout << "Primeiro trimestre" << endl;
            break;
        case 2:
            cout << "Segundo trimestre" << endl;
            break;
        case 3:
            cout << "Terceiro trimestre" << endl;
            break;
        case 4:
            cout << "Quarto trimestre" << endl;
            break;
        default:
            cout << "ERRO!" << endl;
    }
    return 0;
}

 

Anterior Índice Seguinte

Graciano TorrãoConstrução de algoritmos em Pseudocódigo – se… então… senão… fimse

Vamos avançar para a utilização de estruturas de decisão.

Em primeiro lugar vamos abordar a estrutura se… então… senão… fimse.

Para o efeito vamos considerar o problema seguinte:

“Dado um número inteiro, verificar se este é par ou ímpar.”

Algoritmo em pseudocódigo

Nome ParOuImpar
Descrição
    Dado um número inteiro, este algoritmo permite verificar se é par ou ímpar.
Variáveis
    nr: Inteiro
Início
    ler (nr)
    se nr % 2 = 0
    então   escrever (&amp;quot;O número é par.&amp;quot;)
    senão   escrever (&amp;quot;O número é ímpar&amp;quot;)
    fimse
Fim

Para saber se o número é par, utilizeio o operador %, conforme expliquei aqui, embora já numa abordagem em linguagem C++.

Em termos genéricos, esta estrutura representa-se assim em pseudocódigo:

    se <condição>
    então   <bloco de instruções a executar se a condição for Verdadeira>
    [senão  <bloco de instruções a executar se a condição for Falsa>
    fimse]

Assim temos:

  • <condição> é uma expressão que, depois de avaliada, resulta num valor lógico (V/F).
  • <bloco de instruções a executar se a condição for Verdadeira> nesta secção escrevemos o comando, ou bloco de comandos, que temos que executar quando a condição é verdadeira.
  • <bloco de instruções a executar se a condição for Falsa> nesta secção escrevemos o comando, ou bloco de comandos, que temos que executar quando a condição é falsa.
  • [ ... ] a parte do comando relativa ao senão, ou seja, quando a condição é falsa, é opcional. Isto significa que, consoante o problema em causa, pode ou não ser necessária.

Seguem-se uma implementação deste problema.

Em linguagem C++

#include <iostream>
using namespace std;
int main()
{
    int nr;
    cin >> nr;
    if (nr % 2 == 0)
        cout << "O número é par" << endl;
    else
        cout << "O número é ímpar" << endl;
    return 0;
} 

No Scratch

http://scratch.mit.edu/projects/31054570/

Anterior Índice Seguinte

Bruno MiguelUma inspiração deliciosa para o Dia das Bruxas

chocolate skulls

Ruth e Sira Garcia são duas artistas espanholas com talento e bastante criatividade. O duo criou um doce em forma de caveira com o cérebro representado por uma noz ou amora, que pode ser preparado com vários ingredientes.

Uma excelente alternativa à tradicional coca – ou Jack-o’-lantern, como é conhecida nos Estados Unidos – que pelo menos vai fazer as vossas delícias.

via

Bruno Miguel31

Graciano TorrãoDivisão inteira em linguagem C++

DivisaoI

Observa o seguinte programa.

Exemplo 1

#include <iostream>
using namespace std;
int main()
{
    int A = 15;
    cout << A/3 << endl;
    cout << A/2 << endl;
    cout << A/30 << endl;
    return 0;
}

Output do Exemplo 1

5
7
0

Comentários ao Exemplo 1

  • o facto de A ser do tipo int, conjugado com a divisão por uma constante do mesmo tipo, força o resultado a ser também do tipo int (inteiro);
  • a parte fracionária do quociente é descartada;
  • é obtido o quociente da divisão, mas perdemos o resto.

 

Vamos agora trocar o operador ‘/’ pelo operador ‘%’.

Exemplo 2

#include <iostream>
using namespace std;
int main()
{
    int A = 15;
    cout << A%3 << endl;
    cout << A%2 << endl;
    cout << A%30 << endl;
    return 0;
}

Output do Exemplo 2

0
1
15

Comentários ao Exemplo 2

  • para cada uma das operações, obtivemos o respetivo resto;
  • o operador ‘%’ permite então calcular o resto de uma divisão inteira;
  • está contornada a limitação resultante do exemplo anterior, transformada agora nuva vantagem;
  • são inúmeras as aplicações deste operador … ;

Exemplo 3

Agora já é possível controlar a operação aritmética da divisão envolvendo o seu dividendo, divisor, quociente e resto.

#include <iostream>
using namespace std;
int main()
{
    int dividendo, divisor, quociente, resto;
    cout << "Dividendo? ";
    cin >> dividendo;
    cout << "Divisor? ";
    cin >> divisor;
    quociente = dividendo / divisor;
    resto = dividendo % divisor;
    cout << "Quociente = " << quociente << endl;
    cout << "Resto = " << resto << endl;
    cout << "Prova real: " << dividendo << " = " << divisor
         << " x " << quociente << " + " << resto << endl;
    return 0;
}

 


Bruno MiguelUm trio de casas na árvore

Desde muito novo que gosto do conceito de casa na árvore, e ainda hoje gostava de ter uma – assim tenha jardim para tal. Nem me recordo porque começou, mas talvez se tenha mantido por nunca ter conseguido construir uma igual às que via na televisão.

O ambientalista norte-americano Peter Bahouth, residente em Atlanta, desenhou e construiu um trio de casas na árvore, que apelidou de “Mind”, “Body” e “Spirit” (“Mente”, “Corpo” e “Espírito”).

As casas estão interligadas por pequenas pontes e distribuídas como divisões. Uma delas é o quarto e tem uma cama que desliza para forma por forma a permitir uma melhor vista das três construções.

A inspiração de Peter terá sido a sua própria infância, em que teve presente casas na árvores.

Desde muito novo que gosto do conceito de casa na árvore, e ainda hoje gostava de ter uma – assim tenha jardim para tal. Nem me recordo porque começou, mas talvez se tenha mantido por nunca ter conseguido construir uma igual às que via na televisão. E agora quero três como estas.

Graciano TorrãoFormatação de números em C++ com recurso a manipuladores

Trata-se apenas de um exemplo muito simples, que pretende demonstrar como podemos formatar de forma rápida os números que enviamos para o output através do stream cout.

O que está em causa são dois aspetos:

  • espaço em carateres que o valor ocupa no stream
  • precisão em termos de casas decimais

A formatação é conseguida com recurso aos manipuladores tendo em conta os dois aspetos acima referidos, daí a utilização da bilbioteca iomanip.

#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
    double pi = 34.1415926535897932384626433;
    int x = 27;

    // Formatar o número para ocupar um determinado espaço em carateres
    cout << "Numero minimo de carateres:" << endl;
    cout << setw(5) << x << endl;
    cout << setw(1) << x << endl;
    cout << setw(10) << pi << endl;
    cout << setw(3) << pi << endl;
    cout << endl;

    // Formatar geral da precisão em números de vírgula flutuante
    cout << "Formatacao geral da precisao em numeros de virgula flutuante:" << endl;
    cout << setprecision(0) << pi << endl;
    cout << setprecision(1) << pi << endl;
    cout << setprecision(2) << pi << endl;
    cout << setprecision(3) << pi << endl;
    cout << setprecision(4) << pi << endl;
    cout << setprecision(5) << pi << endl;
    cout << endl;

    // Formatar fixa da precisão em números de vírgula flutuante
    cout << "Formatacao fixa da precisao em numeros de virgula flutuante:" << endl;
    cout << fixed;
    cout << setprecision(0) << pi << endl;
    cout << setprecision(1) << pi << endl;
    cout << setprecision(2) << pi << endl;
    cout << setprecision(3) << pi << endl;
    cout << setprecision(4) << pi << endl;
    cout << setprecision(5) << pi << endl;
    cout << endl;

    // Combinado as duas anteriores
    cout << "Combinado as duas anteriores:" << endl;
    cout << fixed << setw(8) << setprecision(4) << pi << endl;
    cout << fixed << setw(6) << setprecision(3) << pi << endl;
    cout << fixed << setw(10) << setprecision(6) << pi << endl;
    cout << endl;

    return 0;
}

A imagem seguinte mostra o output obtido.

manipuladoresOutput


Graciano TorrãoComo calcular uma raiz quadrada em Linguagem C++

raizQuadrada

O programa seguinte demonstra como se pode calcular a raiz quadra de um número em linguagem C++.

 

#include <iostream>
#include <cmath>
using namespace std;
int main()
{
    double x;
    cin >> x;
    cout << sqrt(x) << endl;
    return 0;
}

A função sqrt() pertence à bilbioteca cmath.


Bruno Miguel“Cherry Tree House”

Quando tiver casa própria, quero ter obrigatoriamente um jardim. E nesse jardim não me importarei nada de ter esta escultura de Tom Hare chamada “Cherry Tree House”, feita com salgueiro.

Bruno MiguelO meu desagrado com o serviço da NOS

Há mais de um ano que utilizo o serviço da NOS e desde essa altura que noto algumas particularidades menos boas com ele. Quando a Zon se juntou à Optimus e mudaram a marca para NOS, pensei que isso trouxesse melhorias (antes de saber de algumas alterações pela imprensa). Estava tão enganado. Este meu mau hábito de ser idealista…

Sempre que faço um acesso por HTTP, SSH ou outro que normalmente use TCP, a velocidade corresponde sempre ao contratado e o serviço tem qualidade. Até mesmo quando os quatro computadores de casa estão a aceder a conteúdos em simultâneo, não se nota nenhum delay anormal. Como diria o José Sócrates: “Porreiro, pá”.

A porca torce o rabo quando alguém decide fazer um acesso que assente em UDP, como os torrents. Se descarregar a mais recente Stable do Debian ou qualquer conteúdo do Pirate Bay et all, o acesso a qualquer site torna-se no mínimo penoso, mesmo limitando a velocidade de transferência do conteúdo por Bittorrent. Há no entanto diferenças entre estes dois exemplos: a degradação, quando descarrego um ISO do Debian, é menor do que quando uso um dos chamados sites piratas – mesmo que o conteúdo seja também uma imagem desta distribuição, mas com um tracker diferente definido, ou outro conteúdo que posso descarregar legalmente.

O Carlos Martins já abordou este assunto algumas vezes no Aberto Até de Madrugada, uma das quais através de uma carta aberta que teve direito a respostas enlatadas e muito vagas por parte da – na altura – ZON, por isso não acho que valha a pena repetir a informação publicada pelo Carlos acerca da filtragem de tráfego. Recomendo, no entanto, uma visita ao site dele para saberem mais detalhes.

Esta prática, infelizmente, parece ser transversal a todos os operadores. Enquanto percebo que necessitem de fazer algum tipo de balanceamento de tráfego, o que me tem vindo a acontecer é algo que não consigo compreender e cada vez mais me faz pensar em mudar de operador. Pode ser que o próximo ISP não faça isto de forma tão vincada.

E a ANACOM, que é a entidade nacional que regula o setor e, inclusive, publica no próprio site que “defende os interesses dos cidadãos, garantindo a prestação de informações claras e a transparência nas tarifas e nas condições de utilização dos serviços”, parece ter a tendência de fazer de Pilatos nestas questões e lava as mãos.

Para juntar a isto, ultimamente tenho que reiniciar o router várias vezes por semana. Todas as máquinas ficam com acesso interno, conseguem pingar as outras e aceder às partilhas; o acesso externa é que desaparece. Só voltamos a ter ligação depois de reiniciar o router, que entretanto já foi substituído.

Quando o problema era o router, liguei para o apoio técnico da NOS. Depois de selecionar uma quantidade demasiado grande de opções no IVR, lá consegui chegar à fala com uma assistente. Expliquei a situação, mas aparentemente não fui muito claro nos primeiros 10 minutos de conversa, porque ela não conseguiu perceber o que é uma rede interna – ou LAN, se preferirem.

Depois de quase fazer um desenho, a assistente finalmente fez que percebeu e pediu-me para ligar para o apoio informático. Fiquei tão estupefato com a resposta que só disse que ia ligar e terminei a chamada. No momento seguinte, liguei para a retenção a dizer que ia cancelar por este motivo e no dia seguinte tinha o técnico em casa para trocar o equipamento – que efetivamente não estava a funcionar corretamente.

Durante um mês, o serviço esteve a funcionar bem, exceção feita à questão dos torrents. Agora, como eu já esperava, voltou a dar dores de cabeça. E desta vez não parece ser o router.

Graciano TorrãoConstrução de algoritmos em Pseudocódigo – Entrada e Saída de Dados

Finalmente, para sermos capazes de escrever um algoritmo, vamos necessitar de realizar as operações de entrada (input) e saída(output) de dados.

Por uma questão de simplificação, vamos assumir que as entradas de dados são feitas através do teclado.

Da mesma forma, as saídas de dados correspondem ao que é enviado para o ecrã do computador.

INOUTPUT

Operação de entrada de dados (input)

Em pseudocódigo, vamos convencionar que o comando a utilizar de forma a realizar uma entrada de dados é:

ler ( nomeDaVariável )

Exemplo 1 – Ler o valor da variável X a partir do teclado

ler ( X )

Exemplo 2 – Ler o valor das variáveis A e B a partir do teclado

ler ( A )

ler ( B )

ou

ler ( A, B )

Operação de saída de dados (output)

Da mesma forma, vamos convencionar que o comando a utilizar para realizar uma saída de dados é:

escrever( nomeDaVariável )

Exemplo 1 – Mostrar o valor da variável X no ecrã

escrever ( X )

Exemplo 2 – Mostrar o valor das variáveis A e B no ecrã

escrever ( A, B )

Anterior Índice Seguinte

Graciano TorrãoConstrução de algoritmos em Pseudocódigo – Operação de atribuição

A expressão matemática x = 6 é muitas vezes confundida com a operação de atribuição que vamos utilizar em pseudocódigo.

A diferença é clara!

Versão matemática

x = 6

Representa uma equação do 1º grau, que só é verdadeira quando x assume o valor 6.

Versão pseudocódigo

x ← 6

Representa uma instrução que indica ao computador que deve ser armazenado o valor 6 na variável x.

xiguala63532

Sinal de atribuição

Vamos convencionar que o carater “←” representa então a operação de atribuição, ou seja, o armazenamento dos dados fornecidos (6) na variável em questão(x).

Alguns exemplos

A

Sequência de instruções

a ← 5

b ← 2

c ← a – b

Representação gráfica das variáveis no final da execução

exemploa

B

Sequência de instruções

z ← 5

z ← 2

z ← -3

Representação gráfica das variáveis no final da execução

z-3

C

Sequência de instruções

x ← 5 – 1

y ← x + 2

z ← x + y

Representação gráfica das variáveis no final da execução

exemploc

Anterior Índice Seguinte

Graciano TorrãoConstrução de algoritmos em Pseudocódigo – Tipos de dados

Na linha do que afirmei anteriormente, quando apresentei a noção de variável, a uma variável corresponde a seguinte analogia.

exemplocantudovariavelAgora será necessário especificar o tipo de “caixa” que vamos utilizar, consoante aquilo que pretendemos armazenar.

Assim sendo, vamos necessitar de “caixas” próprias para números inteiros, outras para números reais e ainda outras para dados do tipo texto.

Isto significa que a cada variável ficará associado um “tipo de dados”.

Os principais, e sem esgotar todas as possibilidades, são:

  • Inteiro
  • Real
  • Texto

A imagem anterior ficaria assim.

exemplotipodados

Naturalmente que, outras variáveis, de diferentes tipos, poderão ser utilizadas consoante o algoritmo que estamos a escrever.

exemplovariaveis2No início do algoritmo, utiliza-se a lista de variáveis para indicar os nomes e os tipos da variáveis utilizadas no algoritmo.

 

Anterior Índice Seguinte

Graciano TorrãoConstrução de algoritmos em Pseudocódigo – Noção de variável

“Uma variável é uma localização de memória, identificada por um nome, onde é armazenada uma determinada informação.”

Vou utilizar uma analogia muito simples para tentar explicar este conceito.

Vamos supor que as variáveis são como caixas de papelão, onde podemos guardar informação.

Sendo assim, a imagem seguinte representaria uma variável.

variavelComo se pode ler na definição, todas as variáveis têm um nome, ou identificador.

Sendo assim, a figura seguinte representa as variáveis, valor1, valor2 e soma.

exemplovariaveisvalor1, valor2 e soma são os respetivos identificadores.

Naturalmente que não existem caixotes de papelão nos circuitos de memória do computador mas, admitindo a analogia, a nossa RAM (memória primária) vista à lupa, iria conter.ramalupaDesta forma, um algoritmo que leia dois valores e calcule a respetiva soma iria fazer a seguinte utilização da memória.

exemplocantudovariavelNote que os números 4 e 3 seriam fornecidos pelo utilizador, durante a execução do algoritmo, sendo o valor 7 obtido a partir deste.

Mais à frente veremos que existem diferentes tipos de dados, logo diferentes tipos de “caixas de papelão”, bem como a forma de guardar e retirar dados destas caixas.

Anterior Índice Seguinte

Footnotes