quarta-feira, 23 de setembro de 2009

A árvore genealógica das linguagens de programação

Uma linguagem de programação é um conjunto de palavras capaz de expressar instruções para um computador. É um conjunto de regras padronizadas usadas para construir um programa de computador. Uma determinada combinação das palavras da linguagem, formando uma seqüência lógica de eventos, constitui o código fonte de um software. Esse código fonte, armazenado em um aquivo texto, é depois traduzido para código de máquina, que é executado pelo computador.

A intenção das linguagens de programação é tornar mais fácil a criação de softwares pelo programador, pois é uma linguagem próxima à linguagem humana, ao contrário da linguagem de máquina que utiliza códigos semelhantes às instruções do hardware.

Nos anos 50 foi o início das linguagens modernas de programação. As três primeiras linguagens de programação modernas, as quais suas descendentes ainda são utilizadas são FORTRAN (FORmula TRANslator), LISP (LISt Processor) e COBOL (COmmon Business Oriented Language).

Do FORTRAN vieram linguagens como Basic, C, Pascal, estas vindas da linha da linguagem ALGOL. Muitas outras, a maioria, vieram a partir destas descendências. Para ter uma idéia, Perl, PHP, Java, vieram da linguagem C, e também tem VisualBasic e Delphi que vieram do Basic e Pascal respectivamente.

No site de Éric Lévénez existe uma página que contém uma apresentação gráfica muito interessante da linha do tempo das linguagens de programação com todas as descendências. Lá é possível conhecer a origem das diversas linguagens. Acesse esta página neste endereço: http://www.levenez.com/lang/

Outros sites possuem conteúdo semelhante, são acessados nos endereços abaixo:

http://www.digibarn.com/collections/posters/tongues/
http://oreilly.com/pub/a/oreilly/news/languageposter_0504.html
http://merd.sourceforge.net/pixel/language-study/diagram.html

segunda-feira, 21 de setembro de 2009

Problema de lógica: A cor dos vestidos das três senhoras

Atenção, a resposta está logo após o problema!

Três senhoras, dona Branca, dona Rosa e dona Violeta, passeavam pelo parque quando dona Rosa disse:
- Não é curioso que estejamos usando vestidos de cores branca, rosa e violeta, embora nenhuma de nós esteja usando um vestido de cor igual ao seu próprio nome?
- Uma simples coincidência. - respondeu a senhora com o vestido violeta.
Qual a cor do vestido de cada senhora?





RESPOSTA





Se a senhora com o vestido violeta respondeu a dona Rosa, então ela não é a própria dona Rosa. Além disso, como ela não tem o vestido da mesma cor de seu nome, ela também não é a dona Violeta. Logo, é a dona Branca que está com o vestido violeta. Dona Rosa não está usando o vestido rosa nem o violeta, portanto só pode estar usando o branco. Conseqüentemente, dona Violeta veste o vestido rosa.

sábado, 19 de setembro de 2009

Unidades de Medida do Computador

Toda informação introduzida em um computador precisa ser entendida pela máquina, para que possa corretamente interpretá-la e processá-la. O computador, sendo um equipamento eletrônico, armazena e movimenta as informações internamente sob forma eletrônica, em um valor de voltagem ou de corrente. Para uma maior simplicidade e confiabilidade na representação elétrica da informação, os valores de voltagem, ou de corrente, são gerados e manipulados pelos circuitos em apenas dois valores diferentes, 0 e 1.

Dessa forma, os computadores digitais são totalmente binários. Toda informação introduzida em um computador é convertida para a forma binária. Tornando inclusive mais simples o emprego da lógica booleana para o tratamento da informação.

Assim, a menor unidade de informação armazenável em um computador é o algarismo binário ou dígito binário, conhecido como bit (contração das palavras inglesas binary digit). O bit pode ter então somente dois valores, 0 e 1.

Mas para poder armazenar as informações da linguagem humana, o computador manipula os bits em grupos ordenados. Por definição, instituída pela IBM e atualmente utilizada por praticamente todos os fabricantes de computadores, um caractere da linguagem humana é armazenado em um grupo ordenado de oito bits. Com isso o byte, definido como um grupo ordenado de oito bits, é a menor unidade de armazenamento de informação útil em computadores para nossa linguagem.

Em Dezembro de 1998 a Comissão Eletrotécnica Internacional (IEC), líder em padronização mundial de eletrotecnologia, aprovou como um padrão internacional nomes e símbolos para os prefixos dos múltiplos binários usados no campo de processamento e transmissão de dados.

Prefixos binários são nomes ou sí­mbolos que precedem a unidade de medida, para indicar a sua multiplicação por potências de base dois, semelhante aos prefixos padronizados pelo Sistema Internacional de Unidades (SI), onde a multiplicação se dá por potências de base dez. Os nomes e símbolos dos prefixos binários e suas respectivas potências binárias são mostrados abaixo:

1 Kilobyte  (KB)                   = 2^10 Bytes = 1.024 Bytes
1 Megabyte (MB) = 1024 Kilobytes = 2^20 Bytes = 1.048.576 Bytes
1 Gigabyte (GB) = 1024 Megabytes = 2^30 Bytes = 1.073.741.824 Bytes
1 Terabyte (TB) = 1024 Gigabytes = 2^40 Bytes = 1.099.511.627.776 Bytes
1 Petabyte (PB) = 1024 Terabytes = 2^50 Bytes = 1.125.899.906.842.624 Bytes
1 Exabyte (EB) = 1024 Petabytes = 2^60 Bytes = 1.152.921.504.606.846.976 Bytes
1 Zettabyte (ZB) = 1024 Exabytes = 2^70 Bytes = 1.180.591.620.717.411.303.424 Bytes
1 Yottabyte (YB) = 1024 Zettabytes = 2^80 Bytes = 1.208.925.819.614.629.174.706.176 Bytes


Com o passar dos anos e com a acelerada evolução tecnológica dos computadores, torna-se mais comum entre nós o uso dos prefixos de potências maiores. O primeiro computador pessoal padrão IBM tinha apenas 640KB de memória RAM, hoje é comum computadores com 4 GB de RAM. Os primeiros discos rígidos para estes computadores tinham até 10 MB, hoje usamos discos rígidos de 500 GB. As primeiras mídias removíveis armazenavam 180 KB, hoje temos as mídias Blu-ray que armazenam até 93,2 GB.

Por enquanto estamos na era dos Terabytes e Petabytes, pois os maiores bancos de dados do planeta e os mais grandiosos cálculos matemáticos realizados em computadores manipulam quantidades de informações dentro destas faixas. Não se assuste se um dia começar a ver anúncios de câmeras digitais de 5 Exabytes!

sexta-feira, 18 de setembro de 2009

Medidas de Tendência Central

Uma forma útil de descrever um grupo como um todo consiste em encontrar um único número que represente o que é "médio" naquele conjunto particular de dados. Em estatística descritiva este valor é conhecido por medida de tendência central, pois geralmente se localiza em torno do centro de uma distribuição, onde a maior parte dos dados tende a concentrar-se.

A estatística descritiva é um ramo da estatística que aplica várias técnicas para descrever e sumariar um conjunto de dados. As medidas de tendência central mais conhecidas são a moda, a mediana, o ponto médio e a média.

A moda simplesmente é o dado que ocorre com maior freqüência no conjunto. A moda pode ser localizada com muito mais facilidade por exame do que por cálculo. Se os dados estão organizados em uma tabela de freqüências, a moda é o valor que possui a maior freqüência na tabela. Um conjunto pode não ter valores que se repetem, tornando uma distribuição amodal, ou pode ter duas ou mais modas tornando uma distribuição bimodal ou polimodal. Um conjunto com uma moda apenas é uma distribuição unimodal.

A mediana corresponde ao ponto central da distribuição e é localizada quando os dados estão dispostos em ordem. A mediana é considerada a medida de tendência central que corta a distribuição em duas partes iguais. Se for uma distribuição com número ímpar de dados, a mediana será o dado que fica exatamente no meio da distribuição. Sua posição é dada pela fórmula n+1/2. Se o número de dados for par haverá dois valores considerados centrais. Visto que a posição pela fórmula n+1/2 será um valor fracionado, a mediana vai cair entre os dois valores centrais, então a mediana será a média aritmética destes dois valores. Se os dados estão apresentados em uma tabela de freqüências basta construir uma distribuição de freqüências acumuladas e a mediana será o dado em que o valor acumulado contém a posição da mediana.

O ponto médio é o valor que está a meio caminho entre o menor e o maior valor do conjunto de dados. Para calcular soma-se esses valores extremos e divide-se o resultado por dois.

A média é o valor que aponta para onde mais se concentram os dados de uma distribuição. Pode ser considerada o ponto de equilíbrio das freqüências, num histograma. É a medida de tendência central mais comumente usada. Existem diversos tipos de média, cada uma adequada para uma determinada característica do conjunto de dados. Para suas fórmulas existem duas versões, uma para dados agrupados em uma tabela de freqüências, ou ponderada pelos pesos dos dados, e outra para dados não agrupados.

A média aritmética é a média mais simples, é o somatório dos dados de um conjunto dividido pelo número de dados deste conjunto.

Média aritmética:

Média aritmética ponderada:

A média geométrica é indicada para um conjunto onde os dados fazem uma progressão geométrica. É a raiz n-ésima do produtório dos dados de um conjunto.

Média geométrica:

Média geométrica ponderada:

A média harmônica de um conjunto de dados é utilizada quando se quer valorizar o conjunto onde os dados são mais uniformes, ou mais equilibrados. É o número de dados do conjunto dividido pelo somatório dos inversos dos dados:

Média harmônica:

Média harmônica ponderada:

Caso especial da média harmônica para dois valores:

A média desarmônica é utilizada quando se quer valorizar o conjunto onde os dados possuem uma maior disparidade, ou maior oscilação. É definida como a média harmônica entre a média aritmética desse conjunto e o quadrado da média aritmética do conjunto dividido pela média harmônica do mesmo:

Média desarmônica:

Média desarmônica ponderada:

Caso especial da média desarmônica para dois valores:

A média quadrática é a raiz quadrada da média aritmética dos quadrados dos dados:

Média quadrática:

Média quadrática ponderada:

A média cúbica é a raiz cúbica da média aritmética dos cubos dos dados:

Média cúbica:

Média cúbica ponderada:

Em uma análise estatística a moda nos mostra o valor mais comum do conjunto de dados, porém não é necessariamente igual à média. A mediana nos mostra o equilíbrio da distribuição dos dados no conjunto, se próxima ao valor da média. E a média é limitada pela influência dos valores das extremidades, por isso em alguns casos é muito comum ignorar o maior e o menor valor de um conjunto para se calcular a média.

A maioria dos autores adotam como símbolo da média populacional a letra grega μ (Mu) e o símbolo da média amostral a letra grega χ (Qui).

terça-feira, 15 de setembro de 2009

A proporção do nosso Sistema Solar

Um modelo do nosso Sistema Solar mantendo a mesma proporção, em dimensão reduzida, e adotando o diâmetro do Sol sendo igual a 1 metro, tem a escala de 1:1.391.900.000. A tabela abaixo mostra os diâmetros e órbitas dos principais astros do nosso Sistema Solar em escala reduzida, proporcionalmente ao modelo do Sol com 1 metro de diâmetro:

            Diâmetro (milímetros)   Raio da Órbita (metros)
Mercúrio 3,4 41,633
Vênus 8,6 77,67
Terra 9,1 107,457
Lua 2,4 0,276
Marte 4,8 163,689
Júpiter 100,2 559,048
Saturno 83,6 1.025,217
Urano 33,7 2.062,145
Netuno 32,6 3.232,919
Plutão 1,6 4.248,15


Nesta escala a velocidade da luz seria 215,3 milímetros por segundo, percorrendo em um ano 6.796,8 quilômetros, e o centro da nossa galáxia estaria a 188.340.398 quilômetros de distância.

segunda-feira, 14 de setembro de 2009

Configurando Serviços no Linux

Os serviços são programas (daemons) que são iniciados e mantidos em execução em segundo plano, ficam monitorando o computador e respondem às mudanças. Por exemplo o servidor Apache possui um daemon chamado httpd (o d é de daemon) que fica escutando a porta 80 do computador e quando ele recebe uma requisição por uma página, ele envia os dados apropriados para a máquina cliente.

Muitos serviços ficam em execução na maioria do tempo entretanto muitos podem ser seguramente desligados por razões de segurança como também por razões de desempenho. Pode não ser muita a diferença mas o computador é iniciado um pouco mais rápido quando há menos serviços para iniciar.

Existem dois comandos que são usados para controlar os serviços:

/sbin/chkconfig - Este controla quais serviços serão iniciados durante a inicialização da máquina. As mudanças aplicadas por este programa não alterará o estado do serviço imediatamente, apenas deixará marcada a configuração para a próxima inicialização da máquina.

/sbin/service - Este controla o início ou o fim da execução dos serviços imediatamente durante a seção atual, não mantendo para a próxima inicialização da máquina.

Antes vamos conhecer como o sistema Linux organiza o controle dos serviços. Muitas variantes do Unix System V, e isto inclui diversas distribuições do Linux, usam scripts nos diretórios "/etc/rcN.d/" para controlar quais serviços serão iniciados dentre os níveis de execução. Se um serviço deve ser iniciado no nível de execução 5 então é colocado o seu script em "/etc/rc5.d/".

Entretanto este modelo envolve em existir múltiplas cópias do mesmo script em diretórios diferentes, então foi adotado o padrão de colocar todos os scripts de controle dos serviços no diretório "/etc/init.d/", e usar ligações simbólicas para estes scripts nos vários diretórios "/etc/rcN.d/". Isto permitiu a inovação com o comando "chkconfig".

Na distribuição Fedora Linux as ligações e os scripts estão nos diretórios "/etc/rc.d/rcN.d/" e "/etc/rc.d/init.d/", porém é mantido no diretório "/etc/" as ligações simbólicas para estes diretórios, imitando a origem vinda do Unix System V.

Para o comando "chkconfig" poder operar adequadamente, os arquivos dos scripts de controle devem ter seus nomes refletindo o nome do serviço o qual eles controlam. E no inicio de cada script deve existir um cabeçalho com algumas linhas que fazem com que o "chkconfig" entenda que pode controlar a execução.

A principal linha deste cabeçalho é a que especifica os níveis de execução e a ordem de execução dos scripts. Esta linha é semelhante a mostrada abaixo:

# chkconfig: 2345 55 25

O primeiro conjunto de números "2345" indica os níveis no qual o script será executado e "55" e "25" representam a ordem em que o script será executado e parado no nível de execução.

Para adicionar um script e ativar o controle do serviço pelo gerenciamento do "chkconfig" primeiro é preciso colocar o script no diretório "/etc/rc.d/init.d/" e então executar no prompt do terminal o comando "chkconfig --add nome_do_serviço". A partir deste ponto basta executar o comando "chkconfig nome_do_serviço on" para que a devida ligação simbólica seja criada nos diretórios "/etc/rc.d/rcN.d/" especificados no cabeçalho do script. Com a execução do comando "chkconfig nome_do_serviço off" estas ligações são removidas. Do mesmo modo, pode-se remover o controle do serviço pelo gerenciamento do "chkconfig" executando o comando "chkconfig --del nome_do_serviço".

Estas ligações simbólicas existentes dos diretórios "/etc/rc.d/rcN.d/" seguem um padrão em seus nomes. Os nomes iniciam com os caracteres "S" ou "K" (de Start e Kill) seguido do número da ordem de execução (aqueles do cabeçalho), semelhante a algo como por exemplo "S85httpd" ou "K30proftpd".

O comando "chkconfig --list" retorna uma listagem de todos os serviços disponíveis junto com suas respectivas configurações para a inicialização da máquina. Um retorno mais específico pode ser obtido com o comando "chkconfig --list nome_do_serviço". E é possível alterar os níveis definidos no cabeçalho diretamente na linha do comando, por exemplo se no cabeçalho do script estão definidos os níveis 2345 e a linha de comando for "chkconfig --level 35 nome_do_serviço on", somente será criada as ligações simbólicas nos diretórios "/etc/rc.d/rc3.d/" e "/etc/rc.d/rc5.d/".

Estes scripts usualmente atendem aos argumentos "start", "stop", "status" e "restart", do mesmo modo os comandos que controlam os serviços. A execução imediata do serviço pode ser feita com a chamada do próprio script pela linha de comando, em algo como "/etc/rc.d/init.d/nome_do_serviço start". Ou também utilizando o comando "service" em algo como "service nome_do_serviço start". Lembrando que estas formas só funcionam para a seção atual, não mantendo para a próxima inicialização da máquina. O argumento "stop" para o serviço, o argumento "status" mostra a situação atual do serviço e o argumento "restart" reinicia o serviço. O comando "service" pode ir mais além, executando o comando "service --status-all" ele retorna o estado de todos os serviços instalados no sistema.

Uma alternativa para o comando "chkconfig" é o utilitário "ntsysv", que é uma simples interface para configurar os serviços nos níveis de execução. Por padrão ele configura somente no nível de execução atual e para configurar também para algum outro nível é necessário executá-lo com o argumento "--level NNN", por exemplo "ntsysv --level 35" edita os níveis 3 e 5.

Estes comandos são o padrão na distribuição Fedora. As outras distros poderão ter comandos ligeiramente diferentes.

quinta-feira, 10 de setembro de 2009

Controlador de luz através da porta paralela

Há alguns anos saiu nas bancas uma coleção portuguesa chamada Electrónica PC. Eu comprei os números que vieram até a revista sair de linha. Era uma coleção que ensinava hardware, eletrônica digital e vinha com um projeto para montagem. No segundo fascículo veio o "Controlador luminoso através de Centronics".

É um equipamento que faz com que o computador controle oito saídas de energia da rede elétrica, comunicando pela porta paralela. Pode-se programar um software para operar o equipamento usando qualquer linguagem, em qualquer sistema operacional.

Anexado à este fascículo estava esta placa de circuito:





Bastou então adquirir os componentes necessários, que são estes:

8 resistores de 470 ohms.
8 resistores de 1200 ohms.
8 circuitos integrados MOC3011 ou MCP3011.
8 circuitos integrados TIC 226D ou BT 137.
8 terminais de ligação por parafuso para circuito impresso.
1 conector DB-25 macho dobrada para circuito impresso.
1 cabo de 25 condutores.
2 conectores DB-25 para cabo, macho e fêmea.
1 caixa plástica.
8 tomadas fêmea de 220 V.
cabo de ligação à rede, encaixes para CI etc.

Veja as fotos do equipamento montado:





Segundo a revista este equipamento agüenta até 800W por canal, mas os cabos que usei não tem bitola suficiente, então ligo somente lâmpadas de baixa potência.

Com um equipamento desse pode-se automatizar uma residência, ligando e desligando lâmpadas em horários pré-programados, também como televisão, rádio etc. Inclusive pode-se acessar remotamente o computador para modificar o estado das saídas. Pela internet é comum encontrar referências à equipamentos deste tipo como controlador de cafeteira.

Criando funções no Excel com o Visual Basic for Aplications

Além das funções que acompanham o software Excel, nós podemos desenvolver e acrescentar mais funções utilizando o Editor do Visual Basic for Aplications. Uma função é uma seqüência de comandos armazenada em um módulo do VBA. Uma função programada no Editor do VBA pode ser usada diretamente em uma célula, bastando por exemplo digitar =NomeDaFunção(), semelhante a qualquer outra função existente no Excel.

Este artigo descreve os procedimentos para o Excel versão 2003, para as outras versões pode haver alguma diferença.

Para criar uma funcão entre no Editor do VBA em Ferramentas -> Macro -> Editor do Visual Basic. Insira um módulo pelo menu Inserir -> Módulo e insira uma função dentro desse módulo pelo menu Inserir -> Procedimento. Escolha um nome, selecione o tipo Função e o escopo Público, clique OK. Na janela do módulo digite todo o código da sua função dentro do espaço em branco entre o nome da função e seu delimitador final. Salve as mudanças para este módulo e, de volta ao Excel, digite a chamada à função na célula desejada.

Para retornar à edição do código da função, volte no Editor do Visual Basic e na janela "Project Explorer" (menu Exibir) expanda VBAProject e Módulos, clique com o botão direito sobre um módulo e clique "Exibir código" (ou duplo clique sobre o módulo). Faça as alterações que desejar e salve. Para cada vez que o código de uma função for alterado, será necessário executar novamente a função dentro da célula.

Não é possível neste artigo ensinar toda a linguagem VBA, mas é possível apresentar um resumo contendo os principais comandos da linguagem. Assim pelo menos alguma coisa já vai ser possível fazer. Como em diversas linguagens de programação, no VBA existem palavras reservadas que são os comandos da linguagem. Estas palavras devem ser digitadas respeitando as letras maiúsculas e minúsculas e não podem ser usadas como por exemplo para nomes de variáveis.

Um procedimento é um conjunto de instruções, ao qual é atribuído um nome e sua execução feita individualmente num módulo. Existem dois tipos de procedimentos: Sub e Function. A diferença entre estes dois tipos reside no fato de Function poder devolver um valor, o que não acontece com Sub. Este artigo está demonstrando o desenvolvimento e o uso de funções então segue apenas a estrutura de uma Function:

Function nome(arg1,arg2,...) As tipo
Comando 1
Comando 2
...
nome = valor
End Function


Uma função pode receber valores para sua execução, valores vindos de outras células por exemplo, e estes valores entram como argumentos para o nome da função. No invocamento da função na célula usa-se a mesma sintaxe separando os argumentos com ponto-e-vírgula. E para que uma função possa devolver um determinado valor é necessário que uma de suas instruções faça a atribuição ao seu nome.

Todos os valores, numéricos ou não, são armazenados em variáveis. Antes de utilizar uma variável no código é necessário declará-la primeiro, seguindo o modelo:

Dim nome As tipo
Dim nome(1 To n) As tipo


Os tipos podem ser:

Boolean         True ou False
Byte inteiro de 0 até 255
Integer inteiro de -32.768 até 32.767
Long inteiro de -2.147.483.648 até 2.147.483.647
Single ponto flutuante de -3,4E38 e -1,4E-45 até 3,4E38 e 1,4E-45
Double ponto flutuante de -1,798E308 e -4,94E-324 até 1,798E308 e 4,94E-324
Currency ponto flutuante de -923.337.203.685.447,5808 até 922.337.203.685.447,5807
Date 01/01/100 até 31/12/9999 e horas de 0:00:00 até 23:59:59
String até 2 bilhões de caracteres
Error número de erro
Variant suporta todos os tipos


Observação: Uma variável declarada sem tipo, é do tipo Variant e pode conter qualquer valor.

Exemplos de declarações de variáveis:

Dim nome As String
Dim nota1,nota2 As Integer
Dim vetor(1 To 4) As Double
Dim matriz(1 To 5, 1 To 6) As Integer


Para uma variável receber um valor utiliza-se o operador de atribuição. Um operador de atribuição é o que atribui um valor à uma variável e é representado pelo sinal de igual "=". a = b significa a toma o valor de b, exemplos:

x = y
x = a + b
vetor(2) = 7
matriz(1,3) = x*y


Os operadores aritméticos fazem as operações aritméticas entre variáveis e ou valores, eles são:

Adição                 +
Subtração -
Multiplicação *
Divisão /
Inteiro da Divisão \
Potência ^
Resto da Divisão Mod

Exemplos: x/y a^2 a Mod b


No caso de Strings, que são conjunto de caracteres, existe o operador de concatenação & ou +. Então "bom" & "dia" ou "bom" + "dia" retorna "bomdia".

Também é possível comparar os conteúdos das variáveis utilizando os operadores de comparação, os quais retornam como resposta verdadeiro ou falso:

Igualdade               =
Diferença <>
Maior que >
Menor que <
Maior ou igual a >=
Menor ou igual a <=

Exemplos: a = b x >= 6


E diversas comparações podem ser agrupadas por operadores lógicos:

E               And
Ou Or
Ou Exclusivo Xor
Não Not

Exemplos: a = b And a > c x >= 3 Or y <> 7


Existem algumas estruturas de comandos que são para seleção e para repetição de partes do código. Uma estrutura de seleção atende a um retorno de um operador lógico e executa o código referente à resposta. Uma estrutura de repetição pode executar novamente o código, quantas vezes a condição for verdadeira.

Estruturas de Seleção:

If x>y Then            If x>y Or a<>b Then            If (x>y Or a=b) And i>=j Then
Comando 1 Comando 1 Comando 1
Comando 2 Comando 2 Comando 2
... ... ...
End If Else ElseIf x=y Then
Comando 1 Comando 1
Comando 2 Comando 2
... ...
End If Else
Comando 1
Comando 2
...
End If


Select Case x Select Case x
Case 2 Case Is < 2
Comando 1 Comando 1
Comando 2 Comando 2
... ...
Case 4 Case Is = 1, 3 To 5
Comando 1 Comando 1
Comando 2 Comando 2
... ...
Case 6 Case 6 To 8, 10
Comando 1 Comando 1
Comando 2 Comando 2
... ...
Case Else Case Else
Comando 1 Comando 1
Comando 2 Comando 2
... ...
End Select End Select



Estruturas de Repetição:

For i=1 To 10            For i=1 To 10 Step 2            For Each valor In matriz
Comando 1 Comando 1 Comando 1
Comando 2 Comando 2 Comando 2
... ... ...
Next Next Next


Do While x<=y Do Do
Comando 1 Comando 1 If x>y Then
Comando 2 Comando 2 Comandos
... ... Else
Loop Loop While x<=y Exit Do
Loop

Do Until x=y Do
Comando 1 Comando 1
Comando 2 Comando 2
... ...
Loop Loop Until x=y


Exemplo de código de uma função:

Public Function PRIMO(escolhido As Integer) As Long

Dim pos As Integer
Dim num, divisor, nprimo As Long

num = 2
pos = 0

If escolhido < 1 Then
PRIMO = 0
Else
Do While pos < escolhido
divisor = 2
Do While divisor <= num
If divisor = num Then
nprimo = num
pos = pos + 1
Exit Do
ElseIf num Mod divisor = 0 Then
Exit Do
Else
divisor = divisor + 1
End If
Loop
num = num + 1
Loop
PRIMO = nprimo
End If

End Function


A função demonstrada neste exemplo pode ser invocada em uma célula da planilha com o comando =PRIMO(B3), por exemplo. A função receberá o valor contido na célula B3 e a célula que invoca esta função receberá o valor de retorno da função.

O Visual Basic for Aplications proporciona aos usuários uma rica ferramenta para adaptar o Excel às suas necessidades. Assim o usuário não fica limitado aos recursos de fábrica do Excel. Experimente criar algumas funções e se houver interesse aprenda à fundo a linguagem VBA.

O desenvolvimento do núcleo Linux

O núcleo (kernel) que forma o coração do sistema Linux é o resultado de um dos maiores projetos cooperativos de software. Os lançamentos regulares a cada dois ou três meses entregam aos usuários do Linux atualizações estáveis, com novas características significativas, adicionando suporte a novos dispositivos e desempenho melhorado. A taxa de mudanças no núcleo é alta e está crescendo, a cada lançamento do núcleo mais de dez mil remendos (patches) são adicionados. E estes lançamentos contém o trabalho de mais de mil desenvolvedores individuais representando mais de duzentas empresas.

O núcleo Linux é o software de nível mais baixo executando em um sistema Linux. É encarregado de gerenciar o hardware, executar programas dos usuários e manter a segurança e a integridade de todo o sistema. O núcleo é relativamente a menor parte dentre os softwares de todo o sistema Linux, mas é o coração no qual determina como o sistema será executado e é a parte que é verdadeiramente o Linux.

O número de desenvolvedores individuais e de empresas que patrocinam o trabalho do desenvolvimento do Linux vem crescendo a cada lançamento de uma nova versão e a comunidade de desenvolvedores tem dobrado nos últimos três anos.

Sobre o grandioso número de desenvolvedores individuais apenas uma pequena parte faz a maioria do trabalho. Aproximadamente um terço dos desenvolvedores envolvidos contribuem com apenas um remendo. Nos últimos 4,5 anos os dez maiores desenvolvedores individuais contribuíram com 12% do número de mudanças e os trinta maiores tem contribuído com 25%.

O primeiro desenvolvedor do núcleo Linux, o finlandês Linus Torvalds, não está mais entre os trinta maiores desenvolvedores, porém sua contribuição não pode ser mais medida somente pelo número de mudanças realizadas pois o Linus ainda possui uma parte ativa e crucial no processo de desenvolvimento, realizando a organização, revisão e aprovação do código.

Algumas empresas patrocinam o desenvolvimento do núcleo Linux empregando os desenvolvedores individuais. Estas empresas não participam do desenvolvimento do núcleo, são empresas que estão satisfeitas com o andamento e não sentem a necessidade de ajudar o desenvolvimento em uma direção particular. As maiores empresas que patrocinam são a Red Hat, a IBM, a Novell, a Intel e a Oracle. Contudo a maior parte do desenvolvimento do núcleo Linux provém de indivíduos que fazem o trabalho por conta própria, não recebendo contribuições financeiras.

O núcleo Linux é um dos maiores e mais bem sucedidos projetos de software livre de toda a história. A imensa taxa de crescimento do código e do número de desenvolvedores individuais mostra o quanto está vibrante e ativa a comunidade de desenvolvedores. E esta taxa de crescimento está se elevando, aumentando ainda mais o número de desenvolvedores e de empresas envolvidas no processo. Com a expansão do uso do Linux em servidores, desktops e dispositivos embarcados, a expectativa é que continue a crescer.

Lista ligada simples

Na Ciência da Computação, uma lista ligada ou lista encadeada é uma estrutura de dados que consiste em uma seqüência de registros de dados, semelhante a um vetor (array), porém em cada registro existe um campo contendo a referência para o próximo registro na seqüência.

Uma característica da lista ligada é ser dinâmica quanto ao seu tamanho em número de elementos, o limite passa a ser o espaço livre na memória, diferentemente de um vetor pois seu tamanho é fixo. Conseqüentemente não há desperdício de memória como existe por exemplo em um vetor com apenas 30% de espaço ocupado e os 70% restantes também consumindo a memória. Possui outra vantagem em relação a um vetor na inserção de um dado no início ou no meio pois não é necessário deslocar os dados à frente. Uma desvantagem é que para ter acesso a um dado é necessário percorrer a lista desde o início.

Cada registro, ou elemento, de uma lista é denominado célula, ou nó, e em uma lista ligada simples a célula é composta por dois campos, um campo que armazena o dado e um campo que armazena o endereço para a próxima célula. O campo dado é uma variável comum de qualquer tipo para armazenar um valor qualquer. O campo que armazena o endereço para o próximo é um ponteiro. A informação fundamental é o início da lista, a partir dele as outras células são acessadas. O último elemento da lista aponta para o nada, para o vazio.

Diversas implementações podem ser acrescentadas em uma lista ligada. A lista pode ser circular, onde o último elemento aponta para o primeiro elemento da lista. A lista pode ser duplamente ligada, deste modo cada célula também contém o endereço da célula anterior. Pode-se ter a informação do endereço da última célula, assim não é necessário percorrer toda a lista para adicionar uma célula no final. A lista pode ser com cabeça, onde existe um "falso" primeiro elemento, que não contém dado e apenas é um ponteiro que contém o endereço da primeira célula, ou até ser uma estrutura especial contendo também o endereço do último elemento. E cada célula da lista pode ter mais de um dado armazenado, por exemplo um pequeno vetor.

Abaixo apresento um exemplo de código, na linguagem C, de um programa capaz de manipular uma lista ligada simples. O código está estruturado em funções que criam, removem, imprimem e contam as células, junto com um menu para a interface com o usuário. O código está preparado para ser compilado no sistema Linux, utilizando a biblioteca nCurses. Para compilar em outro sistema pode ser necessária uma adaptação.

/**
Compilar com o comando:
gcc -o listaligada listaligada.c -lncurses
*/

#include <stdio.h>
#include <stdlib.h>
#include <ncurses.h>

#define ESC 27 /* Constante ESC recebe o código da tecla Esc */

struct celula { // Estrutura de cada célula da lista.
int valor; // A célula terá um valor qualquer.
struct celula *prox; // E o endereço para à próxima célula.
};

struct celula *inicio; // Variáveis globais para guardar o início e o fim da lista.
struct celula *ultimo;

int contacelulas() { /** Função que retorna o número de células da lista. */

int cont=0;
struct celula *aux, *pos;

aux = inicio; // Nossa variável auxiliar retorna no início da lista.

while (aux != NULL) { // Enquanto a célula que "aux" se refere não for vazia.
cont++;
pos = aux->prox; // A variável "pos" recebe o endereço da próxima depois da que "aux" se refere.
aux = pos; // A variável auxiliar avança para à próxima célula.
}

return cont;

}

void mostralista() { /** Função que imprime a toda a lista na tela. */

struct celula *aux;

for (aux=inicio; aux!=NULL; aux=aux->prox) // Percorre desde o início usando a variável "aux" para o deslocamento nas células.
printw("%d ", aux->valor); // Imprime o valor contido na célula atual em que "aux" se refere.

printw("(%d)", contacelulas()); // Mudança de linha na tela.

}

void inserecelula(int posicao, int valor){ /** Função que insere (cria) uma célula na posição escolhida. */

int i;
struct celula *aux, *pos;

pos=inicio; // Usaremos a variável "pos" para percorrer a lista desde o início.

if(inicio==NULL) { // Se ainda não existe a lista...

inicio = (struct celula *)malloc(sizeof(struct celula)); // Aloca memória para a primeira célula da lista.
inicio->valor = valor; // Alimenta um valor para esta primeira célula.
inicio->prox = NULL; // Esta primeira célula, como ainda é a única, recebe NULL como endereço para uma próxima.
ultimo = inicio; // Como ainda só temos uma célula então a última é a primeira célula.

} else { // Se já existe a lista...

if(posicao == 1) { // Se vai inserir antes da primeira célula...

aux = (struct celula *)malloc(sizeof(struct celula)); // Aloca memória para a nova célula da lista.
aux->valor = valor; // Alimenta esta nova célula com o valor de parâmetro.
aux->prox = inicio; // Esta nova célula vai apontar para o inicio.
inicio = aux; // O início passa a ser esta célula inserida.

} else if(posicao > contacelulas()) { // Se vai inserir após a última célula...

aux = (struct celula *)malloc(sizeof(struct celula)); // Aloca memória para a próxima célula da lista.
aux->valor = valor; // Esta próxima célula é alimentada com o valor de "valor".
aux->prox = NULL; // E recebe NULL como endereço para uma próxima.
ultimo->prox = aux; // A última célula aponta para esta próxima.
ultimo = aux; // Esta próxima célula passa a ser a última.

} else { // Se não é antes da primeira nem após a última...

for(i=1; i<=posicao-1; i++) { // Percorre da primeira até a célula anterior à posição que receberá uma nova célula.
if(i==posicao-1) { // Se chegamos na posição anterior...
aux = (struct celula *)malloc(sizeof(struct celula)); // Aloca memória para a nova célula da lista.
aux->valor = valor; // Alimenta esta nova célula com o valor de parâmetro.
aux->prox = pos->prox; // Esta nova célula vai apontar para a próxima na qual a anterior estava apontando.
pos->prox = aux; // A célula anterior agora aponta para esta nova célula.
} else // Se ainda não chegamos na posição...
pos = pos->prox; // A variável avança para à próxima célula.

}
}
}
}

void removecelula(int posicao) { /** Função que remove uma célula na posição escolhida. */

int i;
struct celula *aux, *ant;

aux=inicio; // Nossa variável auxiliar retorna no início da lista.

if(inicio!=NULL) { // Se existe a lista...

if(posicao == 1) { // Se vai remover a primeira célula...

inicio = aux->prox; // A variável "inicio" recebe o endereço da próxima depois da que "aux" se refere.
free(aux); // Libera o espaço alocado na memória.

} else if(posicao == contacelulas()) { // Se vai remover a última célula...

for(i=1; i<=posicao; i++) { // Percorre da primeira célula até a posição da célula que será removida.
if(i==posicao-1) { // Se está na célula anterior à que vai ser removida...
ant = aux; // Guardamos ela como sendo a anterior da que será removida.
ant->prox = NULL; // A anterior recebe NULL como endereço para uma próxima.
}
if(i==posicao) { // Se está na célula que será removida...
free(aux); // Libera o espaço alocado na memória.
ultimo = ant; // A última célula agora é a anterior.
} else // Se ainda não chegou na célula à ser removida...
aux = aux->prox; // A variável auxiliar avança para à próxima célula.
}

} else if((posicao > 1) && (posicao < contacelulas())) { // Se não é a primeira nem a última que vai ser removida...

for(i=1; i<=posicao; i++) { // Percorre da primeira célula até a posição da célula que será removida.
if(i==posicao-1) // Se está na célula anterior à que vai ser removida...
ant = aux; // Guardamos ela como sendo a anterior da que será removida.
if(i==posicao) { // Se está na célula que será removida...
ant->prox = aux->prox; // A célula anterior recebe o endereço da próxima depois da que vai ser removida.
free(aux); // Libera o espaço alocado na memória.
} else // Se ainda não chegou na célula à ser removida...
aux = aux->prox; // A variável auxiliar avança para à próxima célula.
}

}
}
}

void limpalista() { /** Função que limpa toda a memória alocada pelas células da lista. */

struct celula *aux;

aux = inicio; // Nossa variável auxiliar retorna no início da lista.

while (aux != NULL) { // Enquanto a célula que "aux" se refere não for vazia.
inicio = aux->prox; // A variável "inicio" recebe o endereço da próxima depois da que "aux" se refere.
free(aux); // Libera a memória alocada para a célula em que "aux" se refere.
aux = inicio; // A variável auxiliar avança para à próxima célula, que passa a ser o início.
}

}

int main() {

initscr(); /* Inicialização do ncurses */
cbreak(); /* Desabilita o buffer do teclado */
echo(); /* Ativa o echo para os caracteres digitados */
clear(); /* Limpa a tela */

char tecla; /* Variável que recebe os comandos para as ações na fila */
int valor; /* Variável que recebe o valor para ser adicionado */
int posicao; /* Variável que recebe a posição para a operação */
int i;
inicio = NULL; /* Ainda não existe uma lista na memória */

while (tecla != ESC) { /* Enquanto não for pressionado Esc é executado o bloco a seguir */

clear(); /* Limpa a tela */
printw("\nOperacoes em Lista Ligada Simples, o que deseja fazer? (ESC sair)"); /* menu inicial */
printw("\n\nOpcoes: (i)nserir");
printw("\n (r)emover");
printw("\n\nConteudo da fila: ");
if(contacelulas() > 0) /* Se a fila não estiver vazia */
mostralista(); /* Imprime todos os valores */
else
printw("vazio");

printw("\n\nDigite a opcao: "); /* Prompt de linha comando */

posicao = contacelulas()+1;
valor = 0;

tecla = getch(); /* Lê a tecla pressionada, comando inserir ou remover */

switch(tecla) {
case 'i': /* Operação de inserção na fila */
printw("\n\nInserir:");
printw(" Em qual posicao? ");
scanw("%d", &posicao); /* Recebe a posição */
printw("\n Qual o valor? ");
scanw("%d", &valor); /* Recebe o valor */
inserecelula(posicao, valor); /* Executa a função */
break;
case 'r': /* Operação de remoção na fila */
printw("\n\nRemover:");
printw(" Qual posicao? ");
scanw("%d", &posicao); /* Recebe a posição */
removecelula(posicao); /* Executa a função */
break;
case ESC: /* Operação de saída com confirmação */
printw("\n\nDeseja sair? s/n ");
if(getch() == 'n')
tecla = 'n'; /* Se não quiser sair então é retirado o Esc da tecla */
break;
}

}

limpalista(); /* Executa a função */
endwin(); /* Finaliza o ncurses */
return 0;

}

segunda-feira, 7 de setembro de 2009

Problema de Lógica: Pergunta aos guardas verdadeiro e mentiroso

Atenção, resposta logo após a pergunta!

No antigo Egito, havia um prisioneiro numa cela com duas saídas, cada uma delas com um guarda. Cada saída dava para um corredor diferente em que um dava para o campo e, portanto, para a liberdade e o outro para um fosso de crocodilos. Só os guardas sabiam qual a saída certa, mas um deles dizia sempre a verdade e outro mentia sempre. Os guardas se conheciam, isto é, o mentiroso sabia que o outro era verdadeiro e vice-versa. O prisioneiro não sabia nem qual a saída certa nem qual o guarda verdadeiro. Qual a pergunta, e uma só pergunta, que o prisioneiro deveria fazer à um dos guardas ao acaso, para saber qual a porta certa?





RESPOSTA





Pergunta: "Se eu perguntar ao seu colega, qual a porta certa, qual é a que ele me indica?"

Seja qual for o guarda inquirido, a resposta indica sempre a porta errada. Se perguntasse ao guarda verdadeiro, ele indicaria a porta errada pois o mentiroso não indica a porta certa. Se perguntasse ao guarda mentiroso, ele indicaria a porta errada pois o verdadeiro indica a porta certa.

domingo, 6 de setembro de 2009

O Sistema Internacional de Unidades

A metrologia é a ciência da medição, abrangendo todas as medições realizadas num nível conhecido de incerteza, em qualquer domínio da atividade humana. O desenvolvimento e a consolidação da cultura metrológica vêm-se constituindo em uma estratégia permanente das organizações, uma vez que resultam em ganhos de produtividade, qualidade dos produtos e serviços, redução de custos e eliminação de desperdícios. A construção de um senso de cultura metrológica não é tarefa simples, requer ações duradouras de longo prazo e depende não apenas de treinamentos especializados, mas de uma ampla difusão dos valores da qualidade em toda a sociedade.

A necessidade de medir é muito antiga e remonta à origem das civilizações. Por longo tempo cada país, cada região, teve o seu próprio sistema de medidas, baseado em unidades arbitrárias e imprecisas, como por exemplo, aquelas baseadas no corpo humano: palmo, pé, polegada, braça, côvado.

Em 1789, numa tentativa de resolver o problema, o Governo Republicano Francês pediu à Academia de Ciências da França que criasse um sistema de medidas baseado numa "constante natural". Assim foi criado o Sistema Métrico Decimal. Posteriormente, muitos outros países adotaram o sistema, inclusive o Brasil, aderindo à "Convenção do Metro". O Sistema Métrico Decimal adotou, inicialmente, três unidades básicas de medida: o metro, o litro e o quilograma.

O Bureau Internacional de Pesos e Medidas (BIPM) foi criado pela Convenção do Metro, assinada em Paris em 20 de maio de 1875. Funciona sob a fiscalização exclusiva do Comitê Internacional de Pesos e Medidas (CIPM), sob autoridade da Conferência Geral de Pesos e Medidas (CGPM). O Bureau Internacional, que tem por missão assegurar a unificação mundial das medidas físicas, é encarregado de estabelecer os padrões fundamentais e as escalas das principais grandezas físicas, de efetuar a comparação dos padrões nacionais e internacionais, de assegurar a coordenação das técnicas de medidas correspondentes e de efetuar e de coordenar as determinações relativas às constantes físicas que intervêm naquelas atividades.

Entretanto, o desenvolvimento científico e tecnológico passou a exigir medições cada vez mais precisas e diversificadas. Por isso, em 1960, o sistema métrico decimal foi substituído pelo Sistema Internacional de Unidades - SI, mais complexo e sofisticado, adotado também pelo Brasil em 1962 e ratificado pela Resolução nº 12 de 1988 do Conselho Nacional de Metrologia, Normalização e Qualidade Industrial - Conmetro, tornando-se de uso obrigatório em todo o Território Nacional.

As sete unidades de base do SI, fornecem as referências que permitem definir todas as unidades de medida do Sistema Internacional. Com o progresso da ciência e com o aprimoramento dos métodos de medição, torna-se necessário revisar e aprimorar periodicamente as suas definições. Quanto mais exatas forem as medições, maior deve ser o cuidado para a realização das unidades de medida.

As sete grandezas de base, que correspondem às sete unidades de base, são: comprimento, massa, tempo, corrente elétrica, temperatura termodinâmica, quantidade de substância e intensidade luminosa. As grandezas de base e as unidades de base se encontram listadas, juntamente com seus símbolos, na tabela abaixo:

Grandeza de base              Símbolo              Unidade de base       Símbolo

comprimento l, h, r, x metro m
massa m quilograma kg
tempo, duração t segundo s
corrente elétrica I, i ampere A
temperatura termodinâmica T kelvin K
quantidade de substância n mol mol
intensidade luminosa Iv candela cd


Todas as outras grandezas são descritas como grandezas derivadas e são medidas utilizando unidades derivadas, que são definidas como produtos de potências de unidades de base. Exemplos de grandezas derivadas e de unidades derivadas estão listadas abaixo:

Grandeza derivada             Símbolo              Unidade derivada                Símbolo

área A metro quadrado m²
volume V metro cúbico m³
velocidade v metro por segundo m/s
aceleração a metro por segundo ao quadrado m/s²


Algumas unidades derivadas recebem nome especial, sendo este simplesmente uma forma compacta de expressão de combinações de unidades de base que são usadas freqüentemente. Alguns exemplos abaixo:

Grandeza derivada             Nome da unidade      Símbolo da unidade   Expressão

angulo plano radiano radiano m/m = 1
freqüência hertz Hz s^-1
força newton N m kg s^-2
energia, trabalho, calor joule J N m = m^2 kg s^-2
potência watt W J/s = m^2 kg s^-2
diferença de potencial volt V W/A = m^2 kg s^-3 A^-1


Para mais informações e download dos documentos acesse os sites abaixo:

http://www.inmetro.gov.br/consumidor/unidLegaisMed.asp

http://www.bipm.org/en/si/

sábado, 5 de setembro de 2009

Antivírus para o sistema Linux

Apesar de existir poucos vírus para o sistema Linux e também ser o sistema Linux mais seguro que um outro sistema operacional, mesmo assim existem versões compatíveis com o sistema Linux dos principais antivírus do mercado.

A utilidade de um antivírus em um sistema Linux é poder verificar os arquivos que serão utilizados no outro sistema operacional. Por exemplo, a limpeza de um pendrive ou um HD externo torna-se fácil e segura em um sistema Linux.

As versões dos antivírus para o usuário doméstico costumam ser gratuitas, sendo assim encontram-se disponíveis para o download nos sites dos desenvolvedores. Alguns até são disponibilizados em pacotes RPM ou DEB, facilitando a sua instalação.

Eu costumo ter cinco antivírus diferentes instalados em meu sistema. Quando vou verificar um arquivo eu utilizo os cinco. Possibilitando uma maior eficiência em encontrar um arquivo infectado. Veja a lista com os principais antivírus e seus respectivos endereços para download:

avast! Linux Home Edition
http://www.avast.com/eng/download-avast-for-linux-edition.html

AVG Anti-Virus Free Edition
http://free.avg.com/download?prd=afl

Clam AntiVirus
http://www.clamav.net/

F-PROT Antivirus Free Version
http://www.f-prot.com/download/trial_forms/linux-ws-tgz.html

McAfee VirusScan Command Line Scanners
https://secure.nai.com/apps/downloads/free_evaluations/default.asp

Como o Linux é um ambiente bastante seguro, alguns antivírus não costumam ter o daemon para o monitoramento constante do sistema, apenas trazem o scanner manual. Todos podem ser facilmente atualizados e o Clam Antivirus costuma vir por padrão nas distribuições Linux.

Só não vá brincar de ter uma pasta chamada "Meus vírus" em um sistema Linux porque os usuários do outro sistema operacional irão ficar sem graça!

O poder do administrador

Quando precisar de autoridade, execute como root.


Extraído de: http://xkcd.com/149/

Pilhas e Filas

Em Ciência da Computação, uma estrutura de dados é uma forma particular de armazenamento e organização de dados em um computador de modo que possam ser usados de maneira eficiente. Os algoritmos que representam as estruturas de dados podem ser aplicados em diversas linguagens de programação. As estruturas básicas são a pilha, a fila, a lista e a árvore.

As pilhas são estruturas baseadas no princípio LIFO (last in, first out), na qual os dados que foram inseridos por último na pilha serão os primeiros a serem removidos. Existem duas funções que se aplicam a todas as pilhas: PUSH, que insere um dado no topo da pilha, e POP, que remove um dado do topo da pilha. As duas funções devem respeitar uma o limite de capacidade e a outra o estado vazio da pilha.

As filas são estruturas baseadas no princípio FIFO (first in, first out), em que os primeiros elementos que foram inseridos serão os primeiros a serem removidos. Uma fila possui duas funções básicas: INSERT, que adiciona um dado ao final da fila, e REMOVE, que remove um dado do início da fila. A mesma coisa para fila, as duas funções devem respeitar uma o limite de capacidade e a outra o estado vazio da fila.

Na estrutura de uma pilha devem conter as informações do limite, que indica a última posição disponível, e do topo, que indica a posição do último valor adicionado. E na estrutura de uma fila devem conter as informações do limite, que indica a última posição disponível, e do fim, que indica a posição do último valor adicionado. Em ambas as estruturas os valores são armazenados em vetores comuns.

Abaixo apresento um exemplo de código, na linguagem C, que traz as funções para as operações em pilhas e filas, contendo também uma interface para a escolha da operação. O código está preparado para o ambiente Linux, utilizando a biblioteca nCurses.


/*
* pilhaefila.c
*
* Pequeno programa que demonstra as operações em uma pilha e uma fila.
*
* Compilar com o comando:
* gcc -o pilhaefila pilhaefila.c -lncurses
*
*/

#include <stdio.h>
#include <stdlib.h>
#include <ncurses.h>

#define ESC 27 /* constante ESC recebe o código da tecla Esc */

struct pilha{ /* pilha é LIFO, last in first out */
int topo; /* posição do último valor adicionado */
int limite; /* última posição disponível no vetor */
int lista[10]; /* vetor de 0 a 9 */
};

struct fila{ /* fila é FIFO, first in first out */
int limite; /* última posição disponível no vetor */
int fim; /* posição do último valor adicionado */
int lista[10]; /* vetor de 0 a 9 */
};

int push(struct pilha* pi, int valor){ /* função que adiciona valor na pilha*/
if(pi->limite == pi->topo){ /* se o topo já estiver no limite */
printw("\nErro: Pilha cheia!");
printw("\nPressione qualquer tecla para continuar...");
getch();
}
else{
pi->lista[pi->topo+1] = valor; /* o vetor da pilha recebe o valor na posição acima do topo */
pi->topo++; /* o topo é incrementado para corresponder à posição do novo valor */
}
}

int pop(struct pilha* pi){ /* função que retira um valor da pilha*/
int AUX;
if(pi->topo == -1){ /* se a pilha estiver vazia */
printw("\n\nErro: Pilha vazia!");
printw("\nPressione qualquer tecla para continuar...");
getch();
}
else{
AUX = pi->lista[pi->topo]; /* valor a ser retirado da pilha, o de cima */
pi->lista[pi->topo] = 0; /* limpa a posição na qual estava o valor retirado */
pi->topo--; /* decrementa o topo para a posição do valor abaixo */
return AUX;
}
}

int insert(struct fila* fi, int valor){ /* função que adiciona valor na fila*/
if(fi->limite == fi->fim){ /* se o fim já estiver no limite */
printw("\nErro: Fila cheia!");
printw("\nPressione qualquer tecla para continuar...");
getch();
}
else{
fi->lista[fi->fim+1] = valor; /* o vetor da fila recebe o valor na posição atrás do último */
fi->fim++; /* o fim é incrementado para corresponder à posição do novo valor */
}
}

int remover(struct fila* fi){ /* função que retira um valor da fila*/
int AUX, i;
if(fi->fim == -1){ /* se a fila estiver vazia */
printw("\n\nErro: Fila vazia!");
printw("\nPressione qualquer tecla para continuar...");
getch();
}
else{
AUX = fi->lista[0]; /* valor a ser retirado da fila, o primeiro */
for(i = 1; i <= fi->fim; i++){ /* do segundo valor até o último */
fi->lista[i-1] = fi->lista[i]; /* transfere para uma posição à frente */
}
fi->lista[fi->fim] = 0; /* limpa a posição na qual estava o último valor */
fi->fim--; /* decrementa o fim para atualizar a posição do último valor */
return AUX;
}
}

int main(){

initscr(); /* inicialização do ncurses */
cbreak(); /* desabilita o buffer do teclado */
echo(); /* ativa o echo para os caracteres digitados */
clear(); /* limpa a tela */

char tecla; /* variável que recebe os comandos para as ações em pilha e fila */
int valor, /* variável que recebe o valor para ser adicionado */
i;

struct pilha p1; /* estruturação das variáveis tipo pilha e fila */
struct fila f1;

/* inicialização dos valores para topo, fim e limite na pilha e na fila */
p1.topo = -1; /* pilha vazia */
p1.limite = 9; /* última posição no vetor */
f1.fim = -1; /* fila vazia */
f1.limite = 9; /* última posição no vetor */

while (tecla != ESC){ /* enquanto não for pressionado Esc é executado o bloco a seguir */

clear(); /* limpa a tela */
printw("\nOperações em Pilha e Fila, o que deseja fazer? (ESC sair)"); /* menu inicial */
printw("\n\nSintaxe: (p)ilha (p)ush|p(o)p [valor]");
printw("\n (f)ila (i)nsert|(r)emove [valor]");
printw("\n\nEx.: pp45, fi9, po, fr.");
printw("\n\nConteúdo da pilha: ");
if(p1.topo >= 0){ /* se a pilha não estiver vazia */
for(i = 0; i <= p1.topo; i++){ /* da posição 0 até a posição do topo */
printw("%d ", p1.lista[i]); /* imprime todos os valores */
}
} else {
printw("vazio");
}
printw("\nConteúdo da fila: ");
if(f1.fim >= 0){ /* se a fila não estiver vazia */
for(i = 0; i <= f1.fim; i++){ /* da posição 0 até a posição do fim */
printw("%d ", f1.lista[i]); /* imprime todos os valores */
}
} else {
printw("vazio");
}
printw("\n\n> "); /* prompt de linha comando */

tecla = getch(); /* Lê a tecla pressionada, comando pilha ou fila */

switch(tecla){
case 'p': /* operação na pilha */
tecla = getch(); /* Lê a tecla pressionada, comando push ou pop */
switch(tecla){
case 'p': /* chama a função que adiciona um valor */
scanw("%d", &valor); /* recebe o valor */
push(&p1, valor); /* executa a função */
break;
case 'o': /* chama a função que retira um valor */
pop(&p1); /* executa a função */
break;
case ESC: /* operação de saída com confirmação */
printw("\n\nDeseja sair? s/n ");
if(getch() == 'n'){
tecla = 'n'; /* se não quiser sair então é retirado o Esc da tecla */
}
break;
}
break;
case 'f': /* operação na fila */
tecla = getch(); /* Lê a tecla pressionada, comando insert ou remove */
switch(tecla){
case 'i': /* chama a função que adiciona um valor */
scanw("%d", &valor); /* recebe o valor */
insert(&f1, valor); /* executa a função */
break;
case 'r': /* chama a função que retira um valor */
remover(&f1); /* executa a função */
break;
case ESC: /* operação de saída com confirmação */
printw("\n\nDeseja sair? s/n ");
if(getch() == 'n'){
tecla = 'n'; /* se não quiser sair então é retirado o Esc da tecla */
}
break;
}
break;
case ESC: /* operação de saída com confirmação */
printw("\n\nDeseja sair? s/n ");
if(getch() == 'n'){
tecla = 'n'; /* se não quiser sair então é retirado o Esc da tecla */
}
break;
}
}

endwin(); /* Finaliza o ncurses */
return 0;
}

quarta-feira, 2 de setembro de 2009

O jogo Hex

Hex é um jogo de tabuleiro para dois jogadores, sendo o tabuleiro composto por hexágonos arranjados em um losango n x n. Ambos os jogadores tem como objetivo formar uma linha sem interrupções, ligando um lado ao outro, colocando as pedras sobre o tabuleiro.

O jogo foi primeiramente inventado pelo matemático dinamarquês Piet Hein com o nome de Polygon em 1942. E em 1948 foi independentemente inventado pelo matemático John Nash, na Universidade de Princeton, onde os estudantes deram o nome para o jogo como sendo Nash.

Em 1952 a Parker Brothers começou a comercializar uma versão com o nome de Hex e o nome mantém-se até hoje. Outros nomes atualmente conhecidos são Six e Hexy, ambos em versões para computador.

O Hex pode ser jogado em tabuleiros de diferentes tamanhos, Piet Hein usava um tabuleiro de tamanho 11, enquanto John Nash usava um tabuleiro de tamanho 14. Hoje também se joga em tabuleiros de tamanhos 13 e 19.

Regras:

Cada jogador tem uma cor atribuída. Os jogadores jogam por turnos colocando uma pedra da sua cor em uma única célula no tabuleiro. O objetivo é formar um caminho com as suas pedras que ligue os lados opostos do tabuleiro marcados pela sua cor, antes que o seu oponente conecte os seus lados de forma semelhante. O primeiro jogador a completar a sua ligação ganha o jogo.

Opcionalmente existe um acréscimo à regra onde o segundo jogador para começar pode, se desejar, trocar a primeira peça do adversário por uma sua.

Tabuleiro:

terça-feira, 1 de setembro de 2009

O exercício físico como ajuda no controle da hipertensão arterial

Hoje, 1º de Setembro, é o Dia do Profissional de Educação Física.

A nossa saúde está inteiramente relacionada com as nossas medidas para reduzir os fatores de risco e assim prevenir as doenças. Dentre um programa de prevenção está o hábito regular da prática de exercícios físicos.

O exercício físico é capaz de melhorar substancialmente as qualidades físicas básicas do corpo humano. Qualidades como resistência, força, velocidade, flexibilidade e coordenação motora são desenvolvidas com programas específicos de treinamento. Assim também o exercício físico promove adaptações na condição aeróbia e na função autonômica do organismo.

No meu trabalho de conclusão de curso, para a obtenção do diploma de graduação em Licenciatura Plena em Educação Física, apresentei o tema "O exercício físico como ajuda no controle da hipertensão arterial". Na produção do texto foram utilizadas as mais importantes referências sobre o assunto. O arquivo PDF com o meu TCC está disponível para download neste endereço:

http://www.programapostural.com.br/artigos/madeira-fefiso.pdf

Hoje cabe então este conselho: Pratique com regularidade um exercício físico.

Ranking das melhores universidades do mundo

O "Webometrics Ranking of World Universities" é uma iniciativa do Cybermetrics Lab, um grupo de pesquisa pertencente ao Consejo Superior de Investigaciones Científicas (CSIC), o maior órgão público de pesquisa na Espanha.

Desde 2004, o ranking é publicado duas vezes ao ano, em janeiro e julho e cobre mais de 17 mil instituições de ensino superior por todo o mundo. A lista final tem cerca de 6.000 universidades e leva em conta a atividade e a visibilidade das instituições na Web. Segundo a organização, a presença na Web é um bom indicador do impacto e prestígio das universidades.

O ranking resume a performance global das universidades, no fornecimento de informações para vestibulandos e estudantes e no compromisso com a disseminação do conhecimento científico. Em primeiro lugar aparece o MIT e no Brasil a USP obtém a melhor colocação.

Posição    Universidade                                  País

1 Massachusetts Institute of Technology EUA
2 Harvard University EUA
3 Stanford University EUA
4 University of California Berkeley EUA
5 Cornell University EUA
6 University of Wisconsin Madison EUA
7 University of Minnesota EUA
8 California Institute of Technology EUA
9 University of Illinois Urbana Champaign EUA
10 University of Michigan EUA
...
22 University of Cambridge Reino Unido
...
24 University of Tokyo Japão
...
26 National Taiwan University China
...
28 University of Toronto Canadá
...
38 Universidade de São Paulo Brasil
...
115 Universidade Estadual de Campinas Brasil
...
134 Universidade Federal de Santa Catarina Brasil
...
152 Universidade Federal do Rio Grande do Sul Brasil
...
196 Universidade Federal do Rio de Janeiro Brasil
...
204 Universidade de Brasília Brasil
...
241 Universidade Federal de Minas Gerais Brasil


Outras informações podem ser obtidas no site do ranking: http://www.webometrics.info/