home | tech | misc | code | bookmarks (broken) | contact | README


Programação

Note

Esse trabalho ainda está muito cru, muito incipiente. Sugestões de melhoria são bem vindas. Por favor, entre em contato.

Introdução

Iniciei esse trabalho para tentar ensinar um pouco de programação a algumas pessoas que me rodeiam. Inicialmente, eu poderia utilizar qualquer um dos milhões de materiais disponíveis na web. Entretanto, porque decidi fazer mais este?

Em primeiro lugar, eu gostaria de ter um material que fosse utilizado como uma ferramenta de proximidade entre eu e as pessoas que gostariam de aprender programação comigo. A ideia é que a pessoa possa utilizar esse material para estudo e depois vir conversar comigo pessoalmente ou pela internet e tirar as dúvidas. Nesse ponto de vista, é um material muito pessoal.

Também queria trazer para a experiência algumas tecnologias que admiro e acho muito boas mas que, devido à pressão do mercado, são muito pouco tratadas no dia a dia. Os books utilizam linguagens de programação que são muito utilizadas (por motivos que não valem a pena explicar aqui) como Java, C#, dentre outras, esquecendo que há uma miríade de linguagens diferentes e a compreensão de várias linguagens faz você compreender melhor outras. Neste livro vamos utilizar várias linguagens e utilizar os aspectos principais de cada uma.

Além disso, infelizmente, a grande maioria dos books não tem uma preocupação didática e próxima do aluno.

Objetivo do livro

Público-alvo desta publicação

Como este livro deve ser lido

Começando a programar: um software gráfico para cadastrar suas coisas

Como se programa computadores? Em primeiro lugar, um computador só entende uma linguagem chamada "código binário", que nada mais é do que um fluxo de zeros e uns. Nós não vamos tentar compreender esse código por enquanto, uma vez que é muito complicado e até programadores experientes tem dificuldades de lidar com esse código. Para falar a linguagem dos computadores, os seres humanos criaram as "linguagens de programação", que são formas que os seres humanos podem utilizar para dizer aos computadores o que fazer.

Por exemplo, supomos que, para se desenhar um botão na tela, talvez um computador precise receber as seguintes instruções:

110000111000010010001100100000001010001110000100000010010000101011110010
000110010101100011101000000101001110000000100100010101100011000100000100
101100000000100100100100100010011011010001011001000010111000000100011100
000001100001001001110001110110000000010101011000110000011111000100100111
001010101110100000000110001011000110000001100001001001000010100010000101

Em uma linguagem de programação, isso seria muito mais fácil, como:

button .btn -caption "Clique aqui!"

O que vamos fazer, portanto, é expressar nosso pensamento, dizer o que queremos que o computador faça, utilizando uma linguagem de programação [1].

[1]TODO: recomendar Sebesta?

A linguagem de programação que vamos utilizar chama-se Tcl [2]. Para elaboração de softwares gráficos vamos utilizar uma biblioteca chamada Tk para desenvolvimento de aplicações gráficas. [3]. As duas juntas formam uma ferramenta conhecida por Tcl/Tk. Não vamos explicar, por enquanto, a diferença entre Tcl e Tk. Iremos utilizar ambas de como se fossem somente uma ferramenta e depois nos preocuparemos com a diferença e os detalhes de cada uma.

[2]Tool Command Language: www.tcl.tk
[3]Tk: TODO

Para saber como instalar o Tcl/Tk, verifique o Apêndice 1: Instalando e utilizando o Tcl/Tk.

Assim, vamos iniciar nossa programação com um software muito básico para cadastrar as coisas que você tem, livros, CDs, DVDs, etc. Vamos começar criando um arquivo texto comum, com o conteúdo abaixo.

Note

Ao instalar o Tcl/Tk, não será instalado um editor de texto para você digitar o código. Você pode utilizar qualquer editor de texto básico para digitar o conteúdo dos arquivos, como o Bloco de Notas do Windows. Entretanto, é recomendado que você utilize algum editor com realce de sintaxe [4]. Um deles é o gedit que existe para diferentes sistemas operacionais.

[4]https://pt.wikipedia.org/wiki/Realce_de_sintaxe
Não utilize um processador de texto como o Microsoft Word ou LibreOffice Writer. Esses programas gravam muito mais informação que o texto digitado e o formato de arquivo que eles gravam não será reconhecido pelos interpretadores e compiladores das linguagens de programação.

Important

O arquivo abaixo pode ser copiado para seu editor de texto. Entretanto, é altamente recomendável que você digite linha a linha. A digitação irá te ajudar a memorizar os comandos. Eventualmente você cometerá alguns erros na digitação, que acarretarão erros de execução do programa, mas você aprenderá muito ao estudar o programa digitado e interpretando as mensagens de erro, encontrar o problema e solucioná-lo.

Arquivo management1.tcl:

# Informa ao Tcl que vamos utilizar a biblioteca Tk
package require Tk

# Cria os componentes
listbox .books -listvariable books
entry .bookname -textvariable bookname
button .add -text Adicionar -command {
    lappend books $bookname
    set bookname ""
}

# Posiciona os componentes na tela
grid .books
grid .bookname
grid .add

A execução do programa acima deverá mostrar uma tela cujo esquema lembra o desenho abaixo:

+--------------------------+
|+------------------------+|
||                        ||
||                        ||
||                        ||
||                        ||
||                        ||
||                        ||
||                        ||
||                        ||
||                        ||
||                        ||
|+------------------------+|
|+------------------------+|
||                        ||
|+------------------------+|
|      +-----------+       |
|      | Adicionar |       |
|      +-----------+       |
+--------------------------+

Tente experimentar digitar algo na caixa de texto (a caixa branca na parte de baixo). E clicar no botão "Adicionar". O que aconteceu? O que você digitou na caixa de texto apareceu na lista acima. Você pode incluir vários itens na lista e selecionar cada um deles. O programa é muito simples, mas já tem algumas capacidades básicas de armazenamento. Iremos melhorá-lo para ter mais funcionalidades.

Por enquanto, vamos voltar ao conteúdo do programa e estudá-lo linha a linha.

As duas primeiras linhas são:

# Informa ao Tcl que vamos utilizar a biblioteca Tk
package require Tk

Essas linhas já dizem bastante a respeito da linguagem de programação que estamos utilizando. Em primeiro lugar, toda linguagem de programação aceita comentários para esclarecer o funcionamento do programa. É altamente recomendável que o programador coloque comentários no programa, explicando a outros programadores (e também a ele mesmo) o funcionamento de determinado trecho de código. Em Tcl, comentários iniciam-se após o caractere #. A próxima linha, package require Tk diz que vamos utilizar a biblioteca gráfica Tk. Posteriormente, vamos utilizar várias outras bibliotecas e, portante, utilizaremos mais vezes o comando package require.

As próximas duas linhas são:

# Cria os componentes
listbox .books -listvariable books

Os comentários já explicamos em parágrafo anterior. O mistério aqui é a linha que começa com listbox. Este é o comando para criarmos uma lista a ser posicionada na tela. Este é o widget (nome para "componente", na nomenclatura do Tk) que mostra a lista de itens adicionados no programa. O nome do widget é .books.

Note

Aqui vale a pena explicar um pouco o significado desse nome. A janela principal de seu programa sempre terá um nome: . (ponto). Se essa janela for fechada o seu programa será finalizado. Todos os widgets criados (inclusive outras janelas, que veremos posteriormente) devem estar dentro ou dependentes desta janela, o que significa que o seu nome deverá vir depois do nome da janela ou widget em questão. Assim, .books significa "crie uma lista chamada books dentro da janela . (ponto). Um outro exemplo que ajudaria a compreender a natureza hierárquica do posicionamento de widgets poderia ser explicado pelo trecho .avo.pai.filho.neto, onde o neto é filho de filho, que é filho de pai, que é filho de avo e assim por diante. Você compreenderá essa relação hierárquica com mais detalhes conforme for utilizando Tk para criar aplicações cada vez mais complexas.

O trecho -listvariable books é especial. Vamos trabalhar durante muito tempo com variáveis. Variáveis representam trechos da memória do computador. São "lugares" onde vamos armazenar as informações. Neste caso, precisamos dizer que os itens da lista .books estão na variável books. O nome da variável, neste programa, é o mesmo do nome dos componentes, mas isso é opcional.

A próxima linha é:

entry .bookname -textvariable bookname

Este trecho é semelhante ao anterior. Criamos uma caixa de texto para o usuário digitar, que é feito pela palavra entry. O nome da caixa é .bookname. O ponto no início significa que ela ficará na janela principal da aplicação. O trecho -textvariable bookname indica a variável que estará associada ao conteúdo da caixa de texto. O nome dessa variável é bookname [5].

[5]Para mais informações sobre variáveis, verifique o capítulo Variáveis.

As próximas linhas são mais complexas:

button .add -text Adicionar -command {
    lappend books $bookname
    set bookname ""
}

Observando o que você leu anteriormente, consegue também interpretar esse trecho de código? Criamos um botão chamado .add. O texto que estará escrito neste botão é passado pelo parâmetro -text e é Adicionar. A próxima parte é especial. É o parâmetro -command. É seguido por um block de código com instruções sobre o que fazer quando o botão é pressionado. Um bloco de código é composto por uma ou mais linhas de programação, com as instruções para o computador executar. Neste caso, se você já executou o programa acima, queremos que, a cada vez que o usuário clicar no botão, o programa faça duas coisas:

  1. Incluir o nome do livro digitado na listbox acima.
  2. Apagar o conteúdo da entry.

Essas instruções são exatamente as linhas do bloco de códigos. A primeira linha é lappend books $bookname. Você lembra o que são books e bookname? Variáveis que contém, respectivamente, o conteúdo da listbox e da entry. A variável $bookname tem um sinal de cifrão ($) antes porque não estamos interessados na variável em si, mas no conteúdo dela. Lembre-se: Em Tcl, sempre que você utilizar um cifrão antes do nome da variável, significa que você está obtendo o conteúdo que está armazenado dentro dela.

Por fim, o comando lappend requer mais atenção. Veja o seguinte código:

lappend  numeros  1
lappend  numeros  2
lappend  numeros  3

Neste exemplo temos uma variável chamada numeros. Utilizamos o comando lappend para add a esta variável ou números 1, depois 2 depois 3. Ao final, teremos uma lista {1 2 3}. O comando lappend, portanto, adiciona um item em uma lista. Note a ordem dos parâmetros: a variável que será a lista a ser aumentada é sempre o primeiro parâmetro.

Então, o que significa o trecho lappend books $bookname? Significa que o computador está obtendo o conteúdo da variável bookname e adicionando na lista books. Lembre-se bookname é a variável associada à entry que acabamos de criar e books é a lista associada à listbox. Logo, ao fazer isso, ele irá mostrar o nome do livro digitado na listbox.

Por fim, o trecho set bookname "" também opera de maneira análoga. set é um comando que utilizaremos muito para definir o valor de uma variável. Neste caso, o valor "". Aqui, vale a pena também dar alguns exemplos:

set  variavel1  "Oi, tudo bem?"
set  variavel2  123
set  variavel3  $variavel1
set  variavel4  ""

Neste caso, estamos definindo três variáveis. A variavel1 recebe o texto Oi, tudo bem?? As aspas são opcionais em algumas situações, mas vamos tratar disso em outra ocasião. A variavel2 recebe o número 123. Aqui não estamos utilizando aspas, mas poderíamos utilizar. Normalmente, em Tcl, evitamos utilizar aspas quando o valor é um numeral. A variavel3 recebe o valor da variavel1, ou seja, o texto Oi, tudo bem?. Por fim, a variavel4 recebe um valor vazio.

Voltando ao código, o que significa a linha set bookname ""? Que a variável bookname recebe um valor vazio (ou, em outras palavras, tem seu conteúdo apagado). Como a variável bookname está associada à entry .bookname, o conteúdo desta caixa de texto é apagado.

Então, finalizamos o programa com as seguintes linhas:

# Posiciona os componentes na tela
grid .books
grid .bookname
grid .add

O comando grid somente posiciona os componentes na tela. Somente criá-los não é suficiente: eles ficarão na memória mas não aparecerão na tela até você utilizar o comando grid ou os comandos pack e place que veremos adiante. Posteriormente, também aprederemos a utilizar os parâmetros do comando grid para construir interfaces cada vez mais complexas.

Exercícios

  1. Melhore a interface acima criando um outro botão com o texto "Apagar" para apagar o conteúdo da lista. Por enquanto o botão não precisa ter nenhuma funcionalidade.

Iniciando a construção da aplicação

Alto e baixo nível

Variáveis

Documentação

Programação e literatura

O fluxo de desenvolvimento e o fluxo de programação

Testando seu código

Apêndice 1: Instalando e utilizando o Tcl/Tk

Instalação do Tcl/Tk no NetBSD

Instalação do Tcl/Tk no Linux

Instalação do Tcl/Tk no Windows

Entre no site http://www.tcl.tk/, baixe e instale a aplicação ActiveTcl (a versão mais recente).

Para executar os programas deste livro, basta criar o arquivo com a extensão .tcl (exemplo: arquivo.tcl) em qualquer editor de texto e, após inserir o código e salvar o arquivo, dar um duplo clique no arquivo. O ActiveTcl trás vários programas e bibliotecas utilizadas no decorrer deste livro, mas não traz um editor de texto. Para utilização de um editor de texto para iniciantes no Windows, recomendo o gedit.

Apêndice 2: Códigos para testar os programas deste livro

Listagem de todos os programas de teste

Arquivo management1.test.tcl:

# Check ::bookname variable and entry correspondance
progtest::test entry1 {
    set ::bookname "a book name"
}
progtest::check {[.bookname get] eq "a book name"}

# Check one item inclusion
progtest::test list1 {
    set ::bookname "foo"
    .add invoke
}
progtest::check {$::books eq "foo"}
progtest::check {$::bookname eq {}}

# Check another item inclusion
progtest::test list2 {
    set ::bookname "bar more"
    .add invoke
}
progtest::check {$::books eq [list foo {bar more}]}
progtest::check {$::bookname eq {}}

Framework de teste

Arquivo programming-test-header.tcl:

namespace eval progtest {
    set ::checks_total 0
    set ::checks_failed 0

    proc test {name body} {
        set ::name $name
        set ::body $body
        eval $body
    }

    proc check {expr} {
        set ret [expr $expr]
        if {$ret == 0} {
            puts "Check failed: $expr"
            puts "Test name: $::name."
            puts "Body: {$::body}"
            puts ""
            incr ::checks_failed
        }
        incr ::checks_total
    }
}

Arquivo programming-test-footer.tcl:

puts "= Summary ="
puts "Checks total:         $checks_total"
puts "Checks successful:    [expr {$checks_total - $checks_failed}]"
puts "Checks failed:        $checks_failed"
exit 0