Topo

terça-feira, 5 de novembro de 2013

Python: primeiros passos

Neste post vamos fazer uma pequena introdução ao Python, que versão escolher, como instalar, bem como apresentar alguns conceitos básicos e instruções simples.

O Python é uma linguagem relativamente simples, muito bem documentada e fácil de aprender. Além disso possui uma série de bibliotecas que permitem estender imenso a sua funcionalidade. Tem sido das linguagens com maior crescimento nos últimos anos, e está no Top 10 das linguagens de programação mais usadas no mundo.

Que versão usar? Python 2 ou Python 3?


Sendo o Python 3 o futuro da linguagem, neste blogue vamos falar desta versão. No entanto existem algumas razões para que um programador possa escolher o Python 2. A razão mais importante prende-se com o número de bibliotecas disponíveis, que é superior, embora as bibliotecas mais importantes já estejam convertidas para o Python 3. No entanto o Python 3 apresenta muitas melhorias relativamente à versão anterior, tais como um melhor suporte para caracteres que não pertençam à língua inglesa (caracteres com assentos, alfabeto cirílico e por ai fora), clarificação da operação divisão inteira, uso coerente de instruções como o print e o input, etc.

Apesar de nos basearmos em Python 3, nos programas aqui apresentados tentaremos sempre que possível indicar a alternativa em Python 2.

Instalação


O arquivos de instalação do Python em Windows e MacOSX podem ser descarregados em http://www.python.org/, na secção Download, do lado esquerdo. Certifica-te que descarregas a versão correta, 32 ou 64-bits, dependendo do sistema operativo que tens instalado.

Em Linux o Python 2 costuma vir instalado de raiz, mas o Python 3 apenas vem instalado nas distribuições mais recentes. Para te certificares que o Python 3 está instalado (assim como o IDLE, que é o IDE pré-definido do Python), executa o seguinte comando num terminal:

$ sudo apt-get install python3 idle3


O Python interativo


Em Linux, abre um terminal e escreve:

$ python3

No Windows ou MacOSX corre o programa Python (command line), que foi instalado no passo anterior.

Neste momento deverás ter uma janela de terminal preta à tua frente, com um cursor a piscar. O Python, ao contrário das outras linguagens de programação discutidas neste blogue, permite uma interação direta com o utilizador, isto é, podemos ir inserindo comandos, que serão imediatamente processados pelo Python (semelhante ao que acontece com a linha de comando). Esta característica é bastante útil para testar instruções e experimentar código.

Agora que temos o terminal de Python à nossa frente, vamos executar algumas instruções:

>>> x=5
>>> y=2
>>> z=x+y

A primeira instrução atribui o objeto 5 à variável x. A segunda instrução atribui o objeto 2 à variável y. A última instrução atribui o objeto correspondente à soma dos objetos x e y à variável z.

Neste momento já definimos dois conceitos importantes: objeto e variável. Simplificando, as variáveis servem para associarmos nomes a objetos, tal como fizemos nas instruções anteriores, onde associámos os objetos 5, 2 e 7 às variáveis de nome x, y e z, respetivamente. Para sabermos qual o valor do objeto associado a uma variável, podemos usar a função print:

>>> print(z)
7

A utilização do print em Python 2 é ligeiramente diferente, pois não se usam os parêntesis, ou seja, seria print z. Experimenta criar variáveis com outros nomes e com outros valores, experimenta fazer outras operações matemáticas e verifica que resultados obténs. Não há nada melhor que uma boa experimentação para se entender melhor os pormenores de uma linguagem de programação. Algumas dicas:
  • Os números reais têm um ponto a separar a parte inteira da parte fraccionária, por exemplo, 2.35
  • As operações aritméticas suportadas pelo Python são a + (soma), - (subtração), * (multiplicação), / (divisão), // (divisão inteira), % (resto da divisão inteira) e ** (exponenciação) - atenção que no Python 2 a operação / também realiza a divisão inteira se for aplicada a números inteiros.
  • Os nomes das variáveis em Python podem conter letras, números e o caractere '_' (underscore). No entanto não podem começar com um número (por exemplo, altura_2 é um nome válido, enquanto que 3d_altura é um nome inválido). 
  • Os nomes das variáveis em Python não podem ser iguais a certos nomes pré-definidos na linguagem, tais como if, while, for, e por ai fora. 

Os objetos


Os objectos são os elementos básicos que o Python pode manipular. Um objeto é definido por:
  • id - Um número inteiro que identifica unicamente cada objeto, e que se mantém ao longo do programa para esse mesmo objeto. Este número pode ser obtido com a função id().
  • tipo - O tipo de objeto, por exemplo um número inteiro (int), um número real (float), uma sequência de caracteres (string), etc. O tipo de objeto pode ser obtido com a função type(). Experimenta no terminal de Python executar as instruções type(5) e type(3.98), e verifica o resultado obtido.
  • valor - O valor que está associado a um objeto de determinado tipo. Por exemplo, um objeto do tipo float (número real) pode ter o valor 4.5234. Se for possível alterar o valor de um objeto, esse objecto diz-se mutável. Caso contrário o objeto é imutável.
Os objetos podem representar qualquer estrutura de dados, desde a mais simples até à mais complexa. No Python existem quatro tipos básicos de objetos, denominados de escalares, pois são indivisíveis (isto é, não são compostos por mais objetos). Podem pensar nos objetos escalares como os átomos que constituem a linguagem. Os quatro tipos escalares são:
  • int - Representam números inteiros.
  • float - Representam números reais.
  • bool - Representam os valores lógicos True e False (verdadeiro e falso).
  • None - É um tipo com apenas um valor (None), que tem uma funcionalidade específica que analisaremos noutro post.
Os objetos escalares são por definição imutáveis. O contrário não é necessariamente verdade. Por exemplo, uma sequência de caracteres (objeto do tipo string) é imutável (não pode ser alterada), mas não é escalar (é composta por vários objetos mais pequenos, os caracteres).

Alguns exemplos


Podemos obter o tipo de um objeto (também referido como classe de um objeto) diretamente, ou usando o nome da variável à qual esse mesmo objeto está associado.

>>> um_real=22.91
>>> type(22.91)
<class 'float'>
>>> type(um_real)
<class 'float'>

Agora vamos verificar que podemos associar o mesmo objeto a mais do que uma variável.

>>> real1=6.1
>>> real2=real1
>>> id(real1)
140064643951784 

>>> id(real2)
140064643951784

Podemos concluir que as variáveis real1 e real2 estão associadas ao mesmo objecto pois a função id() retorna o mesmo ID para ambas.

É possível alterar o objeto que está associado a um determinado nome. Por exemplo, a variável x pode estar originalmente associada ao objeto do tipo inteiro com valor 5, e posteriormente podemos alterar x para ficar associada ao objecto do tipo inteiro com valor 7.

>>> x=5
>>> id(x)
10188960

>>> x=7
>>> id(x)
10189024

Verifica-se que a variável x está de fato a ser associada a dois objetos diferentes, pois a funcão id() retorna IDs diferentes. Os objetos em si não foram modificados, pois objetos do tipo inteiro são imutáveis, ou seja, não podem ser alterados.

No próximo post


No próximo post vamos criar o nosso primeiro programa em Python. Por outras palavras, em vez de usarmos o Python interativo, onde as instruções que introduzimos são executadas imediatamente, vamos guardar várias instruções num ficheiro e executar esse ficheiro como um programa. Vamos também falar sobre os comentários em Python. Até breve!

domingo, 16 de junho de 2013

Linguagem C: comentários e identação

Um tópico muito importante em C (e em qualquer linguagem de programação) são os comentários. Quando os programas começam a ficar muito grandes, torna-se difícil seguir o raciocínio que o programador utilizou (mesmo que esse programador tenhas sido tu!). Os comentários são blocos de texto normal que inserimos entre as instruções do nosso programa para nos ajudar a seguir a lógica do mesmo. Substitui o código do nosso programa pelo seguinte:
 
/* Em baixo temos uma diretiva de pré-processador */
#include <stdio.h>

/* Vamos começar o nosso programa. */
int main() {
    /* Escrever no ecrã uma frase */
    printf("O meu primeiro programa em C!\n"); /* O \n indica uma nova linha*/
    /* Vamos retornar zero, indicando que correu tudo bem. */
    return 0;
}

Como podes constatar, os comentários em C são colocados dentro de blocos que começam com /* e terminam com */, como por exemplo /* isto é um comentário */. Se compilares e executares o programa vais verificar que os comentários são totalmente ignorados. É uma excelente prática comentar os nossos programas, e algo que aconselho fazerem sempre, seja em projetos para a universidade ou a nível profissional.

Outra boa prática é a chamada identation (não existe uma palavra exata em Português, mas para facilitar vamos chamar-lhe identação). A identação não é mais do que chegar à frente os conteúdos de um bloco. Por exemplo, tudo o que está dentro do bloco da função main está identado com quatro espaços. Desta forma o programa torna-se mais claro e mais fácil de entender. A identação é essencial para que um programa seja minimamente legível. Aqui vamos usar identação de 4 espaços (o chamado estilo Kernighan & Ritchie), no entanto cada pessoa tem a sua preferência, alguns usam 2 espaços, outros usam um tab, e por ai fora. O que interessa é que o nosso programa seja consistente e mantenha a mesma identação do princípio ao fim. Se por acaso tiverem longas partes do vosso código que não estejam identadas, estejam mal identadas ou estejam identadas de forma inconsistente, existem várias formas automáticas de resolver o problema. Deixo duas soluções, uma usando a interface gráfica, outra usando a linha de comandos:
  1. A maioria dos IDEs (ver aqui o que é um IDE) suporta esta operação. Por exemplo, no Code::Blocks, basta ires ao menu "Plugins => Source Code Formatter (AStyle)", e o teu código fica automaticamente identado. Para alterares o estilo de identação efetuada através deste processo, edita as preferências do plugin em "Setting => Editor", e selecionares em baixo "Source Formatter". Como podes verificar, existem vários estilos de identação, e podes inclusive criar um personalizado.
  2. Usando o comando indent. Este comando também suporta uma série de estilos diferentes, bem como personalizações específicas de cada estilo. Após instalares o indent (ver parágrafo seguinte), podes fazer identação automática do nosso primeiro programa usando o seguinte comando:

    $ indent -kr -nut primeiroprog.c

    As opções -kr e -nut indicam que queres usar o estilo Kernighan & Ritchie e que não queres usar tabs, respetivamente. Para veres todas as opções deste comando basta fazeres:

    $ man indent
Nem o Code::Blocks nem o comando indent estão instalados por defeito na maioria das distribuições Linux. Em distribuições baseadas em Debian (Ubuntu, Mint, WattOS, Bodhi, etc.), um simples comando serve para instalar os dois programas de uma só vez:

$ sudo apt-get install codeblocks indent

Seja qual for o estilo que usares, convém seres consistente e usares esse estilo em todo o teu programa. Em situações em que várias pessoas estão a trabalhar no mesmo código, convém definir à partida o estilo usado, de forma a que o resultado final tenha um aspeto coerente.

segunda-feira, 10 de junho de 2013

Linguagem C: o nosso primeiro programa


Neste post vamos voltar a falar do nosso primeiro programa em C, e vamos assumir que o leitor já tem um sistema preparado para compilar e executar programas em C (ver posts anteriores).

Vamos criar uma pasta para colocarmos o nosso código, e vamos abrir o gedit para editar o nosso programa. Para isso abre um terminal, e insere os seguintes comandos (explicações detalhadas de todos estes comandos estão disponíveis nos posts anteriores):

$ mkdir aprender_c
$ cd aprender_c
$ gedit primeiroprog.c &

Agora, faz copy-paste do código em baixo para dentro do gedit, e guarda o ficheiro.
 
#include <stdio.h>

int main() {
    printf("O meu primeiro programa em C!\n");
    return 0;
}

Vamos então por partes. A linha 1 do código contém o seguinte texto:
 
#include <stdio.h>

Este texto não corresponde a código C, mas sim a uma directiva de pré-processador. Não te assustes com o nome. Esta directiva de pré-processador serve apenas para indicar ao compilador que pretendemos usar funções (ou comandos) que estão na biblioteca de funções stdio.h (Standard Input/Output). Esta biblioteca contém funções de entrada/saída de dados, tais como o printf (usado na linha 4, do qual falaremos adiante). Se quisermos usar outros tipos de funções, tais como funções matemáticas ou funções para tratamentos de sequências de caracteres (strings), vamos ter de incluir (#include) mais bibliotecas (math.h no caso das funções matemáticas, e string.h no caso das funções para tratamento de sequências de caracteres). As directivas de pré-processador começam sempre com um cardinal (#), e, ao contrário de todas as expressões e chamadas de função em C, não devem terminar com um ponto e vírgula (;), como acontece nas linhas 4 e 5.

Nas linhas 3 e 6 temos o início e o fim da função principal, main, que é chamada em primeiro lugar assim que o nosso programa é executado.
 
int main() {
}

A palavra-chave int antes do nome da função (neste caso main), indica o tipo de dados que a função vai devolver a quem a chamou. Por definição, a função main devolve sempre um número inteiro. Adiante falaremos melhor sobre os diferentes tipos de dados existentes em C. Tudo o que está entre as chavetas {...} é o nosso programa propriamente dito, que é composto por instruções. As instruções em C devem ser sempre terminadas por ponto e vírgula.

Na linha 4 temos a função printf.
 
printf("O meu primeiro programa em C!\n");

Esta função, na sua forma mais simples, aceita uma sequência de caracteres, e escreve/imprime essa sequência no ecrã. Em C, as sequências de caracteres são definidas entre aspas (ex. "sou uma sequencia de carateres"). Repara nos dois últimos caracteres da sequência que estão dentro do printf. Temos uma barra "\" seguida de um "n". Esta sequência, "\n", indica uma nova linha (new line), e serve para indicar o fim da linha atual e o início de uma nova linha. Vamos ver um exemplo do seu efeito mais à frente. Por último, na linha 5 temos a seguinte instrução:
 
return 0;

Esta instrução indica o fim da função main, e por consequência o fim do nosso programa, devolvendo o valor zero (que é um número inteiro). Neste caso o valor é devolvido ao sistema operativo, e é comum este valor indicar que o programa terminou sem erros.

Agora que temos um entendimento mais completo sobre o nosso programa, vamos compila-lo e executa-lo. Salva o documento no gedit, e na linha de comandos escreve o seguinte:

$ gcc primeiroprog.c -ansi -pedantic -Wall -g -o primeiroprog

Se tudo correr bem, o programa vai compilar sem erros. Antes de executarmos o nosso programa, uma pequena explicação sobre as opções que usámos para o compilador gcc:
  • gcc : Nome do comando de compilação
  • primeiroprog.c : Nome do ficheiro a compilar
  • -ansi e -pedantic : Indicam que o  nosso ficheiro contém código C o mais standard possível, sem extensões mais recentes.
  • -Wall : Pede ao compilador para nos avisar (Warning) de todos (all) os pequenos problemas que possam existir no programa, mesmo que esses problemas não impeçam a compilação.
  • -g : Pede ao compilador para incluir informação de depuração (debug), que nos pode ajudar a resolver problemas usando um depurador (debugger) tal como o gdb, o qual vamos usar mais à frente.
  • -o primeiroprog : Indica ao compilador que o ficheiro executável resultante (output) da compilação deve-se chamar primeiroprog.
Vamos executar o programa da seguinte forma:

$ ./primeiroprog

O resultado será:

O meu primeiro programa em C!

Se removermos o "\n" da cadeia de caracteres dentro do printf e voltarmos a compilar, vamos verificar que no fim da execução do programa o cursor fica situado logo à frente da frase e não por baixo da mesma. Existem outros caracteres especiais em C, como podes ver aqui. Experimenta inserir alguns destes caracteres especiais na cadeira de caracteres, volta a compilar e executar o programa e observa o resultado!

No final do nosso programa retornamos o valor zero, que indica que o programa terminou sem problemas. Após a execução de qualquer comando em Linux podes verificar o resultado retornado usando outro comando:

$ echo $?

Ao executares este comando após teres executado o nosso primeiro programa, vais ver o resultado retornado: zero. Na linha 5 do nosso programa, substitui o 0 por outro valor inteiro, volta a compilar e executar, e logo de seguida corre o comando anterior e verifica o resultado obtido.

Por último o programador deve ter em atenção que o C é case-sensitive, ou por outras palavras, é sensível às maiúsculas e minúsculas. Se por exemplo em vez de escrevermos main, printf ou return, escrevermos Main, PRINTF ou ReTuRn, o programa não vai sequer compilar.

domingo, 26 de maio de 2013

Introdução à linha de comandos: parte III


Neste vídeo vamos de falar de mais algumas ferramentas úteis para a linha de comandos.

Comando man para procurar comandos

Em publicações anteriores falámos do comando man, e sobre como este comando nos pode dar informações sobre todos os outros comandos (incluindo ele próprio!). O problema é que podemos não saber que comando estamos à procura. No entanto o man também nos ajuda nesse aspeto. Para tal, usamos a opção -k. Por exemplo, se quisermos saber que comandos ou programas estão disponíveis para editar texto, podemos executar o seguinte comando:

man -k edit

Dependendo da distribuição de Linux e do software que tivermos instalado podemos ter diferentes resultados. Experimenta com outras palavras-chave!

Comando ln para criar atalhos

Para criarmos um atalho simples, usamos o comando ln na seguinte forma:

ln -s alvo atalho

em que o alvo é o ficheiro ou pasta para o qual queremos criar um atalho e atalho é o atalho propriamente dito. Notar que o alvo e o atalho podem estar em localizações/pastas diferentes.

Transferir documentos e ficheiros da net

Para este efeito usamos o comando wget. Por exemplo, para transferir o logótipo do jornal Público, basta fazer:

wget http://static.publico.pt/files/homepage/img/logo.png

Comando sudo para obter permissões de administrador

Muitas operações requerem permissões de administrador, como por exemplo, instalar e remover programas, ver conteúdos de certas pastas, adicionar e remover utilizadores, etc. Os comandos/operações que requerem este tipo de permissões devem ser precedidos do comando sudo. No entanto é necessário que o utilizador esteja na lista de administradores para que o comando sudo cumpra a sua função (como é sempre o caso do utilizador que instala o sistema operativo).


Comandos para comprimir/descomprimir ficheiros e pastas

Podemos comprimir e descomprimir ficheiros usando comandos tais como zip, unzip, tar, rar e por ai fora.

Em algumas distribuições, comandos como o rar podem não vir instalados de origem sendo necessário recorrer ao apt-get para os instalar, como por exemplo:

sudo apt-get install rar

O comando apt-get, com a opção install, tem como objetivo instalar programas no computador, operação que requer permissões de administrador. Assim sendo, o comando apt-get tem de ser precedido do comando sudo.

Adicionar e remover utilizadores do sistema

É muito simples adicionar e remover utilizadores do sistema usando a linha de comandos. Para adicionar um utilizador chamado Zé, basta fazer:

sudo adduser ze

Para remover esse mesmo utilizador basta executar:

sudo deluser ze

Como são operações que requerem privilégios de administração, os comandos adduser e deluser têm de ser precedidos por sudo.

Alterar a propriedade de ficheiros ou pastas

Esta funcionalidade é implementada através do comando chown (change owner). Por exemplo, se quisermos que o ficheiro teste.txt passe a ser propriedade do utilizador Zé, vamos fazer:

sudo chown ze:ze teste.txt

Normalmente a mudança de propriedade requer privilégios de administração, mas nem sempre é o caso. O nome ze aparece duas vezes: a primeira corresponde ao utilizador propriamente dito, e a segunda ao grupo de utilizadores. Por defeito cada utilizador típico tem sempre um grupo com o mesmo nome.