Escolar Documentos
Profissional Documentos
Cultura Documentos
Sebenta de
Desenvolvimento de
Software
www.moodle.univ-ab.pt//print.php?id 1/85
26-01-2010 name
ndice
1 - Introduo
2 - Especificao
3 - Desenho
4 - Cdigo
5 - Testes
6 - Testes Empricos com o Engine Tester
7 - Instalao e Manuteno
www.moodle.univ-ab.pt//print.php?id 2/85
26-01-2010 name
1 - Introduo
A presente sebenta um texto sobre Desenvolvimento de Software, o qual deve ser complementado
pela utilizao de um ambiente de desenvolvimento avanado, sendo o Visual C++ 2008 Express Edition
o ambiente de desenvolvimento adoptado. Os textos desta sebenta so na sua maioria baseados no livro
de texto na bibliografia opcional.
O nosso objectivo nesta unidade curricular no conseguir desenvolver software, encontrar a melhor
maneira de o fazer, de forma a minimizar os custos e maximizar a qualidade do software, e porque no,
maximizar o prazer de o desenvolver. Este texto acompanhado de exemplos concretos, para assim
auxiliar o estudante a assimilar o contedo dos textos.
Ser fcil fazer uma especificao bem feita? Desde que esta seja consistente, ou seja, que todas as suas
especificaes possam ser satisfeitas, e seja completa, ou seja, que todas as situaes estejam previstas,
ser certamente uma boa especificao. Necessita ainda que seja uma soluo para o problema que o
cliente pretende resolver, assumindo que o cliente conhece bem qual o problema que pretende resolver.
Para tal h ferramentas que auxiliam este processo, nomeadamente diagramas UML, e que so matria
da unidade curricular Anlise de Sistemas. Nesta unidade curricular esta matria abordada
superficialmente.
Assumindo que no h problemas na especificao, o desenho deve ser feito correctamente para que se
www.moodle.univ-ab.pt//print.php?id 3/85
26-01-2010 name
possa comear a escrever cdigo. O desenho deve especificar uma implementao concreta ao que
pedido pelo cliente, formalizado na fase anterior. Caso no implemente o que pedido, as restantes fases
vo ser feitas para nada. Na fase de teste, ou numa pior situao em que o cliente no est envolvido, na
fase de instalao, o cliente vem dizer que no era aquilo que pretendia e parte do trabalho deitado
fora. Os diagramas UML continuam aqui a ter um papel importante, sendo esta matria tambm da
unidade curricular Anlise de Sistemas. Nesta unidade curricular esta matria abordada
superficialmente.
1.1.2 Cdigo
Chegamos fase do cdigo, fase esta que confia que as fases anteriores foram feitas com a mxima
ateno. Qualquer erro nessas fases significa que o trabalho a iniciar agora poder no servir para nada.
Mas isso no seria problema, no fosse esta fase ter sempre uma certa incerteza associada: ser que
serei capaz de implementar o algoritmo especificado? Para alm disto h que conhecer a sintaxe da
linguagem de programao, as bibliotecas disponveis, a estrutura de dados e o algoritmo a implementar,
e o resto dos mtodos que sero implementados pelo prprio programador posteriormente, ou por um
colega. Ao programar um algoritmo complexo, o programador tem de ter em mente a estrutura de dados
e os seus valores a cada passo da execuo do algoritmo. uma tarefa em que o mais fcil errar, mas
felizmente nem sempre h algoritmos complexos, mas mesmo sem algoritmo complexo, o que necessita
de estar na mente do programador ao escrever cada linha de cdigo um volume considervel de
informao.
No h forma de se saber com certeza que o trabalho feito est correcto. Assim, pode-se ir avanando
na implementao de outras partes e ter que se voltar para trs ao descobrir que uma das partes no
funciona correctamente. Felizmente que a programao orientada por objectos permite modelar cdigo
de forma a tornar as diferentes partes do cdigo mais independentes, ou seja, caso um mdulo esteja
incorrecto, apenas tem que ser revisto o cdigo desse mdulo.
Este cenrio no nada agradvel para o programador, dir-se-ia que ningum gostaria de estar na pele
de um programador. No entanto as grandes dificuldades atraem pessoas que as fazem, pelo desafio e
pelo prazer de ver a dificuldade ultrapassada, e a programao no excepo. Existem hoje em dia
ferramentas para auxiliarem este processo, que so os Ambientes de Desenvolvimento Integrados, os
quais so de importncia capital em grandes projectos e com todo o mrito so matria desta unidade
www.moodle.univ-ab.pt//print.php?id 4/85
26-01-2010 name
curricular. Estas ferramentas no servem para que o programador no necessite saber fazer isto ou
aquilo, servem apenas para poupar na memria e na escrita que o programador necessita para escrever
cada linha de cdigo. natural que um programador que conhea bem o ambiente de desenvolvimento
que tem, no gastar tempo a ver as bibliotecas que tem disponveis, j as conhece, tendo uma
produtividade bastante mais elevada que outro que se inicia nesse ambiente de desenvolvimento.
Pretende-se nesta unidade curricular analisar um ambiente de desenvolvimento em concreto, Visual C++
2008 Express Edition, de forma a que o estudante conhea as principais funcionalidades que lhe
permitem programar de forma mais confortvel, sem necessidade de tanta memorizao e ateno,
resultando num aumento claro da sua produtividade.
1.1.3 Teste
O cdigo aps implementado e testado pelo seu programador passa agora fase de testes, para poder
ser devidamente verificado por um colega. O objectivo do colega encontrar falhas no cdigo, e para tal
vai efectuar grande volume de testes na tentativa de encontrar falhas. Ao encontrar uma falha tem de a
poder repetir para que esta seja reportada, mas no tem que sequer olhar para o cdigo. Os testes so
feitos tanto a cada mdulo separadamente (testes unitrios), como ao conjunto dos mdulos (testes de
integrao). Esta actividade requer alguma imaginao e criatividade de forma a colocar o sistema
perante situaes novas, dado que repetir situaes normais em que o sistema funciona, de nada adianta
nos testes. Caso no exista essa imaginao e criatividade, apenas as falhas mais banais sero
identificadas, e as restantes ficaro por identificar. Sero alguma vez identificadas? Concerteza que sim,
pelo o utilizador do sistema, que tem normalmente sempre mais criatividade e imaginao para colocar o
sistema perante situaes no testadas.
Este trabalho no notoriamente algo que deva ser feito por quem acabou de escrever o cdigo.
Primeiro pelo cansao ao cdigo que j dever ter acumulado aps ter escrito o cdigo, e desta forma
no ter a dose de imaginao e criatividade necessrias, e segundo porque uma tarefa que se falhar tem
menos trabalho, e em terceiro porque uma tarefa que se falhar ningum d por isso. Naturalmente que
se detectar uma falha no deixar de a reportar. No entanto a falta de imaginao e criatividade do autor
do cdigo podem ser aqui determinantes. Alm disso, se um erro ou outro passar para os
utilizadores descobrirem, qual o problema para o programador? At d um certo gozo, dado que o
trabalho e a complexidade do cdigo que os programadores fazem normalmente desconhecido dos
utilizadores. Havendo um erro, o utilizador reconhece a sua total incompetncia e nem sequer l a
mensagem de erro porque considera partida que nunca a iria entender. Decididamente, no dever ser
o programador que escreveu o cdigo a fazer os testes.
Esta fase por vezes no executada. Porqu? O cdigo est escrito, h um responsvel pelo desenho,
no caso do sistema no corresponder ao que est na especificao assinada pelo cliente, e cada bloco de
cdigo foi escrito por um programador, que o responsvel pelo que fez. Para alm deste argumento h
tambm outros dois, talvez at de maior peso: a fase de testes aumenta o tempo e custo de
desenvolvimento de software. Ainda por cima cria um mal estar na empresa, colegas a fiscalizarem o
trabalho de colegas. Todo este tipo de argumentos so aceites apenas por quem no compreende a
impossibilidade de se fazer cdigo sem erros, e no considera normal que o cdigo tenha erros. Dever
ser feita a melhor tentativa para identificar e remover os erros enquanto a aplicao est na empresa,
caso contrrio sero encontrados fora da empresa com maiores custos no s em termos de tempo gasto
nos recursos humanos como tambm em termos da imagem da empresa. Esta matria desta unidade
curricular, onde ser utilizado um software de testes, o EngineTester.
www.moodle.univ-ab.pt//print.php?id 5/85
26-01-2010 name
Os materiais da fase de Teste, o 5 e 6 captulo da sebenta e os vdeos de demonstrao do Engine
Tester. Como materiais complementares aconselha-se o livro opcional, captulos 8 e 9.
Aps desenvolvido e testado o software, este tem de ser entregue ao seu destinatrio final, o cliente. O
software ser instalado e utilizado pelos utilizadores sem problemas, e funcionar para sempre, gastando
apenas energia elctrica? Infelizmente no ser assim. Os utilizadores iro tentar utilizar o software de
acordo com o que acham que este deve de ser, e caso o software no faa o que pretendem,
consideram que no funciona e deixam de o utilizar. Caso o software sobreviva ao tempo, ser
reinstalado vrias vezes, quer por actualizao de hardware, quer por actualizao de sistema operativo.
Sero encontrados erros, ser necessrio implementar novas funcionalidades, mas as pessoas que
desenvolveram o software podem j no estar a trabalhar na empresa.
Muitas so as situaes que levam a que o software deixe de ser utilizado. As ltimas fases no
desenvolvimento de software so determinantes para a longevidade deste, e portanto a sua rentabilidade.
Como lidar com as situaes expostas no pargrafo anterior? Simplesmente com o recurso boa
documentao, e nos sistemas mais complexos e essenciais, alocao permanente de recursos humanos
para a manuteno do sistema.
A documentao deve existir a todos os nveis: interna no prprio cdigo; externa ao cdigo mas tcnica;
documentao para o utilizador. destinada a poupar o tempo de quem a l, seja o utilizador para poder
utilizar o sistema, seja o programador (o prprio que desenvolveu o cdigo ou um colega) para poder
compreender o cdigo e corrigir um bug, ou implementar uma nova funcionalidade.
As tendncias para que a documentao no exista ou seja de m qualidade devem ser combatidas, caso
contrrio o software poder rapidamente deixar de ser utilizado, ou nunca chegar a ser utilizado. Este
problema aumenta em projectos que necessitem de equipas de desenvolvimento de software. Os
diferentes programadores no vo estar permanentemente em reunies a falar sobre o cdigo. O grosso
da comunicao feita atravs da documentao tcnica, que deve estar em boas condies para ser
facilmente compreendida por quem a l, seja por um colega no dia seguinte, seja pelo prprio
programador daqui a um ano. Nesta unidade curricular esta matria abordada superficialmente.
Um projecto feito por um conjunto de ficheiros que vai sendo editado ao longo do tempo pela equipa
de desenvolvimento. Quando se tem vrias pessoas a editar os mesmos ficheiros, pode haver situaes
em que o mesmo ficheiro esteja a ser editado em simultneo por duas pessoas, levando a que as
alteraes feitas pela primeira pessoa a gravar sejam perdidas. Vrias outras situaes indesejadas
podem ocorrer, por exemplo, algum acidentalmente apaga um ou mais ficheiros do projecto. Para que
se possa trabalhar em equipa, necessrio um sistema de controlo de verses, que impede que situaes
destas ocorram.
www.moodle.univ-ab.pt//print.php?id 6/85
26-01-2010 name
Os materiais da fase de Instalao e Manuteno, o 7 captulo da sebenta. Como materiais
complementares aconselha-se o livro opcional, captulos 10 e 11.
1.2 Conceitos
Nesta seco descrevem-se alguns conceitos soltos de Desenvolvimento de Software.
Nem todos os problemas passam por solues informticas. H que analisar o problema e subproblemas
envolvidos e suas relaes, e construir uma soluo. Os problemas surgem da necessidade de melhoria
dos processos que decorrem numa empresa e na sua maioria as solues envolvem informtica.
Processos que utilizam muito papel podem ser aligeirados pela informatizao de parte do processo,
simplesmente por mudar o suporte de parte da documentao para ficheiros em disco e numa segunda
fase para base de dados.
Um processo que requeira comunicao intensa entre pessoas pode tambm ser aligeirada com o simples
aumento do uso do email em vez do telefone, e numa segunda fase um sistema informtico que tenha o
processo implementado, passando o processo automaticamente pelas pessoas que o devem analisar.
Um defeito uma consequncia do erro no cdigo (ou especificao / desenho) que assim ir funcionar
de forma defeituosa. Um defeito ir acontecer aps um erro, se quem cometer o erro no der por isso.
Um defeito pode ou no ter consequncias finais. No caso de ter, ir provocar uma ou mais falhas no
sistema, que so uma no conformidade do sistema com os requisitos.
Exemplos:
Um programador pode esquecer-se de declarar uma varivel. Este erro no teria no entanto
grandes consequncias, j que seria detectado em tempo de compilao, e seria de imediato
corrigido.
Um programador poder declarar uma varivel do tipo real (double) quando deveria ser do tipo
inteira (int). Neste caso o erro passaria a defeito, mas sem consequncias de maior dado que um
double pode guardar todos os valores de inteiros. Se no entanto o cdigo tiver divises
supostamente inteiras, neste caso seriam feitas divises reais, e o defeito poderia passar a falha,
sendo visvel para o utilizador.
www.moodle.univ-ab.pt//print.php?id 7/85
26-01-2010 name
Os ambiente de desenvolvimento modernos (exemplo do Eclipse e Vistual Studio), tm tendncia a evitar
erros ao completar parte do cdigo automaticamente, e a levar o programador a detectar imediatamente
erros ao colorir parte do cdigo e sublinhar o cdigo suspeito. Assim diminui-se o nmero de defeitos.
A filosofia do Visual Basic no sentido de permitir os tipos de erros mais comuns, e no obrigar o
programador a grande escrita. Desta forma diminui o nmero de defeitos, mas permite de igual forma
alguns defeitos que o programador detectaria caso fosse obrigado a maior detalhe no cdigo. A no
obrigatoriedade de declarar variveis e o no distinguir minsculas de maisculas, deixam passar defeitos
que no passam em outras linguagens.
Os defeitos que passam desapercebidos, alguns nem tanto uma vez que resultam em alertas de
compilador muitas vezes ignorados pelo programador, no so tipicamente simples de descobrir
por leitura atenta do cdigo. Com o evoluir dos ambientes de desenvolvimento estes defeitos ficam
restritos aos que tm baixa frequncia de ocorrncia, e no existe nada que os detecte seno uma fase de
teste feita correctamente, e mesmo assim nada garantido.
1.2.3 Participantes
Existem basicamente trs participantes no desenvolvimento de software: o cliente, o utilizador e o
programador. O cliente quem paga pelo sistema, o utilizador quem usa o sistema e o programador
quem implementa o sistema. Estes participantes tanto podem ser uma s pessoa como vrias pessoas ou
uma organizao. Nem sempre so entidades distintas, num caso limite so uma s pessoa, no caso de
um programador fazer um programa para ele prprio utilizar.
Esta diviso til para ver os diversos pontos de vista. O cliente que tem o problema que necessita de
ser resolvido, no vale a pena resolver um outro problema que no seja o do cliente. O utilizador que
vai utilizar o sistema, ou seja a soluo, e deve conseguir faz-lo, no vale a pena fazer o sistema se os
utilizadores a que se destina no o conseguirem utilizar. O programador que tem que desenvolver o
sistema, no deve deixar nenhuma das fases que lhe pertencem para o utilizador fazer, como por exemplo
o teste do sistema.
Definio de Requisitos - participa o Analista - tem que saber o que o cliente quer;
Desenho do Sistema - participa o Desenhador, e o Analista - descrio do sistema de acordo com
os requisitos;
Desenho do Programa - participa o Desenhador, e o Programador - descrio detalhada;
Implementao - participa o Programador;
Teste de Unidades - participa o Programador, e o Tester - testes de cada unidade implementada;
Teste de Integrao - participa o Tester - testes das diferentes unidades em conjunto;
Teste do Sistema - participa o Tester - teste de todo o sistema;
Instalao / Entrega - participa o Instrutor - mostrar/formar utilizadores do sistema;
Manuteno - participa o Instrutor - corrigir problemas que ocorram.
H que ter em ateno que a dimenso do projecto pode justificar ou no a existncia de determinadas
fases, podendo tambm a mesma pessoa desempenhar diversos papeis. No caso limite, se a equipa de
desenvolvimento de software tiver apenas uma pessoa, esta desempenha todos os papeis. no entanto
conveniente que as diversas fases sejam feitas por pessoas diferentes, de forma a que umas possam
verificar o trabalho das outras.
www.moodle.univ-ab.pt//print.php?id 8/85
26-01-2010 name
verificar o trabalho das outras.
Manda o bom senso que se atribua s pessoas com maior experincia as primeiras fases, j que as fases
seguintes esto normalmente dependentes das anteriores. Algo mal feito numa fase inicial pode
condicionar muito mais que algo mal feito nas ltimas fases.
Mais informao:
http://pt.wikipedia.org/wiki/Engenharia_de_Software
"Software Engineering, theory and practice", second edition,
Prentice Hall, Shari Pfleeger, pg. 2-4, 6, 14-15, 25-27, 136, 141,
145
www.moodle.univ-ab.pt//print.php?id 9/85
26-01-2010 name
2 - Especificao
Este captulo aborda superficialmente a fases da Especificao, e o captulo seguinte Desenho. Estas
matrias so abordadas com o devido detalhe na unidade curricular de Anlise de Sistemas.
Um requisito diz-se funcional se se refere a uma interaco entre o sistema e o exterior, definindo o
procedimento que o sistema deve fazer para uma ou mais situaes. Exemplos: registar todas as entradas
e sadas de dados num ficheiro; ter um campo de observaes para cada registo de uma lista de
contactos; devolver o valor da expresso matemtica que o utilizador introduzir; apresentar a pgina
seguinte de texto, aps o utilizador ter carregado na tecla PgDn.
Um requisito diz-se no funcional se impor apenas uma restrio ao sistema, no definindo nenhuma
procedimento concreto. Exemplos: impor um tempo de resposta mximo para determinadas situaes;
forar um sistema operativo ou um determinado computador.
Os requisitos so completos caso todas as situaes em que o sistema possa vir a estar tiverem um
procedimento definido. Por exemplo, a definio de uma funo factorial, que recebe um inteiro natural,
pode deixar de fora o caso do factorial de zero. Embora esta funo possa no vir a ser chamada com
este argumento, pode ser complicado demonstrar que essa situao no ir ocorrer, pelo que estipulando
o valor de retorno nessa situao garante que os requisitos ficam completos.
Os requisitos devem ser realistas e verificveis. Um requisito impossvel na tecnologia actual, no pode
ser implementado, e um requisito que no se possa verificar, provavelmente nunca ficaria bem
implementado devido a no poder ser testado convenientemente.
Para se conseguir uma boa especificao necessrio conseguir comunicar com o cliente. Primeiro
conseguir compreender o problema do cliente. Segundo, conseguir transmitir a soluo proposta ao
cliente. Normalmente a linguagem tcnica no a melhor forma de o fazer, muito embora seja
normalmente a mais fcil. A utilizao de diagramas UML so aqui de grande utilidade, em complemento
a uma lista de requisitos. Embora o cliente possa vir a validar a especificao de requisitos, provvel
que no saiba se a soluo proposta resolve o seu problema. da responsabilidade do analista certificar-
se que a soluo que prope resolve o problema do cliente.
Por vezes h uma inverso de papeis nesta fase. O cliente pode at nem sequer falar do seu problema e
apresentar ao analista o que pretende que se faa, a soluo, na sua prpria linguagem, sendo afinado
pelo analista de forma a fazer sentido. Tal no ser aceitvel a no ser que o cliente tenha competncias
para tal. Se no tiver competncias o mais provvel que o que pede no ser soluo do seu problema.
Ser implementado e haver seguramente mais iteraes do tipo: " necessrio tambm isto, caso
contrrio isto tudo no faz sentido". Fica um projecto condenado a custar muito mais, tanto no
preo como na pacincia, isto apenas para que o analista no ponha em causa as capacidades
www.moodle.univ-ab.pt//print.php?id 10/85
26-01-2010 name
informticas do cliente.
Exemplo: Poker
Especificao A:
1. Pretende-se um sistema para simular jogos de poker entre quatro jogadores, com 7
cartas, com 2 cartas fechadas e 5 abertas (ver:
http://en.wikipedia.org/wiki/Texas_hold_%27em).
2. Pretende-se para cada jogo obter a melhor mo de cada jogador.
Quem j tenha jogado poker, provavelmente a especificao a cima suficiente. No entanto h diversos
conceitos indefinidos na frase acima, alguns dos quais so de conhecimento geral, outros nem tanto.
sempre conveniente que na especificao seja especificado tudo com clareza, mesmo conceitos do
conhecimento geral. Por exemplo, quem nunca tiver jogado poker, poder no saber qual o baralho que
se utiliza, e quem nunca tiver jogado cartas, poder no saber que um jogo de cartas implica a utilizao
e um baralho. Os conceitos de cartas fechadas e abertas, no s esto relacionados com o jogo, pelo
que requerem conhecer-se o jogo, como pode eventualmente existir mais que uma denominao para o
mesmo conceito. Finalmente, nem sequer referido que mos existem, nem a sua ordem de valor.
Se tanto o analista como o cliente se entendem atravs de uma especificao do nvel desta, valer a
pena maior formalizao? Vale concerteza, j que o risco envolvido aceitando uma especificao deste
tipo muito elevado. O cliente poder nem ter conscincia do que est a pedir, e muito provavelmente o
analista tambm no sabe o que est a aceitar. Para alm disso, se houver conflitos esta especificao de
nada serve, cada parte ir elaborar a interpretao que lhe interessar.
Esta poderia ter sido a primeira interaco do analista com o cliente, vamos reflectir um pouco sobre a
especificao em outra prespectiva. Quem o cliente? Eventualmente um jogador de poker, ou um
casino. Qual o problema que o jogador de poker quer resolver? Ser realmente a simulao de jogos
de poker? Provavelmente no, j que no tem ganho directo por ver um jogo simulado, dado que
quando estiver a jogar o jogo no ser o mesmo. O que o cliente quer muito provvelmente informao
til que possa utilizar durante um jogo de poker, pelo que esta especificao ir certamente evoluir.
Como para obter informao til num jogo de poker ser necessrio simular jogos de poker, no vale a
pena complicar a especificao com a informao que se pretende extrair atravs dos jogos simulados.
Outro ponto a ter em ateno na especificao a introduo de constantes. Neste caso, o jogo
jogado entre 4 jogadores, com mos de 7 cartas, com 5 cartas abertas, 2 cartas fechadas. neste
problema que o cliente est interessado, no entanto no h grande ganho em utilizar esta informao
como constantes, e o prprio cliente facilmente poder mudar de ideias e espera que a mudana seja
simples, pelo que, a no ser que exista uma vantagem bvia, as constantes devem ser tratadas como
parmetros, tendo naturalmente os valores iniciais que o cliente especificou. Desta forma estamos a
aumentar a reusabilidade do cdigo.
Especificao B:
www.moodle.univ-ab.pt//print.php?id 11/85
26-01-2010 name
0<CF<=5; 5<=CA+CF<=7);
3. Analisar as cartas de cada jogador juntamente com as duas cartas na mesa, e
calcular a melhor mo;
4. A mo mais alta a sequncia e cr real, em que consiste em 5 cartas todas do
mesmo naipe, com os 5 nmeros mais altos (10;V;D;R;A);
5. A segunda mo a sequncia e cr, em que consiste em 5 cartas todas do mesmo
naipe, com 5 nmeros seguidos;
6. A terceira mo o poker, em que consiste em 4 cartas com o mesmo nmero;
7. A quarta mo o fullen, em que consiste em 3 cartas com o mesmo nmero, e outras
2 cartas com o mesmo nmero;
8. A quinta mo a cr, em que consiste em 5 cartas todas do mesmo naipe;
9. A sexta mo a sequncia, em que consistem em 5 cartas com nmeros seguidos;
10. A stima mo o trio, em que consiste em 3 cartas com o mesmo nmero;
11. A oitava mo so dois pares, em que consiste em 2 cartas com o mesmo nmero, e
outras duas cartas com o mesmo nmero;
12. A nona mo o par, em que consiste em 2 cartas com o mesmo nmero;
13. A dcima mo nada, quando no existe nenhuma outra mo;
14. Se duas mos forem iguais, a mo com a carta mais alta a melhor.
Nesta especificao j no h grandes conceitos omissos, excepto o conceito de naipe e nmero, que
para quem nunca tenha visto um baralho pode ser confuso. tambm uma especificao mais longa, pelo
que poder no ser lida com a mesma ateno que a primeira especificao. sempre conveniente
colocar o mais importante primeiro, de forma a aproveitar no s a maior ateno do leitor, como para
ser sempre clara a utilidade de cada requisito.
A passagem de constantes para variveis fora a especificar o domnio das variveis. Como no faz parte
da especificao inicial do cliente, convm colocar domnios que no causem problemas, nem
compliquem o resto da especificao, caso contrrio perde-se a vantagem de passagem das constantes
para variveis. Por exemplo, ao no incluir a restrio 5<=CA+CF poderia acontecer que para cada
jogador existissem menos de 5 cartas, enquanto que as mos so vistas em grupos de 5 cartas. Teriamos
de definir o que acontece para esses casos, e estariamos provavelmente a seguir por um caminho bem
distante do que o cliente pretende.
Especificao C
1.
2.
3.
4.
5.
6.
7.
8.
www.moodle.univ-ab.pt//print.php?id 12/85
26-01-2010 name
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
At que frmula leu antes de passar para esta linha? Se leu todas as frmulas, certamente um entre
poucos que se sente vontade na matemtica. Esta linguagem pode no ser a melhor forma de
comunicar com o cliente, no entanto, este problema tem uma especificao complexa, e dado o
background do cliente, jogador de poker, provvel que se sinta vontade na matemtica, e desta
www.moodle.univ-ab.pt//print.php?id 13/85
26-01-2010 name
forma fica claro o trabalho envolvido, que tem que ser pago e reconhecido em conformidade.
Vamos percorrer as frmulas e comentar, construindo o que poderia ser uma segunda verso da
especificao C para um cliente adverso matemtica:
A utilidade dos diagramas UML nesta fase reduzida para este exemplo, dado que um simulador, e
no h grandes interaces com o utilizador, este apenas manda o simulador correr e v o resultado.
Estes requisitos so todos funcionais, um exemplo de um requisito no funcional seria forar a linguagem
de programao a ser C++. So tambm consistentes, mas facilmente se poderia ter colocado requisitos
inconsistentes, logo no requisito 3, no caso de haver um erro no nmero de cartas no baralho, se este
fosse superior a 52 seria impossvel de utilizar o nmero e naipe para identificar cada carta, dado que h
13 nmeros e 4 naipes. Estes requisitos no so provavelmente completos, ao contrrio do que seria
ideal. No esto definidas situaes que possibilitem sempre escolher a melhor mo de qualquer conjunto
de cartas. Por exemplo, se o conjunto de cartas todo o baralho, o melhor tipo de mo SCR,
existindo 4 mos possveis, de igual valor (uma sequncia cr real de cada naipe), pelo que fica indefinido
www.moodle.univ-ab.pt//print.php?id 14/85
26-01-2010 name
que mo deve ser escolhida nessa situao.
O cliente disse o que queria, tempo do analista propr uma soluo, que o que ser feito na fase
seguinte.
www.moodle.univ-ab.pt//print.php?id 15/85
26-01-2010 name
3 - Desenho
Atravs de desenhos podem-se representar a duas dimenses objectos reais, pessoas, paisagens,
mapas, etc. Esses desenhos tm informao sobre as entidades que representam. Assim tambm o
desenho em informtica, mas destina-se a representar um sistema informtico, podendo ser feito a vrios
nveis de detalhe.
O cdigo no pode ser comeado a escrever aps a especificao de requisitos. Primeiro necessrio
fazer o desenho do sistema para se saber que cdigo necessrio desenvolver.
Actualmente a programao orientada a objectos dominante, pelo que estas estratgias podem-se
fundir numa s, tendo em ateno que uma classe deve: ter uma funo clara no sistema (decomposio
modular); assentar numa estrutura de dados tambm bem definida (decomposio orientada nos
dados); os eventos ou mtodos que trata devem ser claros e naturais relativamente funo principal que
implementa.
A programao orientada a objectos apenas uma boa forma de dividir o programa em componentes,
ou mdulos, mas resta ainda a tarefa de saber quais os mdulos que devem ser criados para um
determinado sistema. A resposta a esta pergunta no est na especificao de requisitos, o analista tem
de construir alternativas e escolher a melhor.
Na programao orientada por objectos, se todas as variveis forem privadas evita-se no mnimo a
dependncia de Selo entre classes, o que aceitvel. Caso no se passe estruturas de dados entre
objectos, as dependncias entre componentes so quanto muito dependncias de Dados, o que
desejvel que assim seja.
Um exemplo de um erro em programao orientada por objectos, que tem consequncias nos custos
de desenvolvimento e manuteno: A dependncia de contedo de uma classe A com outras classes B1,
B2, ... Bn, por exemplo, obriga a sempre que se acrescente algo na classe A, se tenha de analisar e
testar as classes B1,...,Bn, ou quando se descobre um valor errado numa varivel da classe A, se tenha
de ver o cdigo para tentar perceber, no s da classe A como tambm das classes B1,...,Bn. Impede
tambm o teste de unidades de forma independente da classe A relativamente s classes B1,...,Bn.
Um componente diz-se coeso se constitudo por partes que se relacionem entre si. A coeso de
componentes uma caracterstica desejvel num bom desenho. Pode ocorrer a diversos nveis:
Funcional - quando as partes se destinam todas a implementar a mesma funo, e apenas essa
funo;
www.moodle.univ-ab.pt//print.php?id 17/85
26-01-2010 name
Sequencial - quando o resultado de uma parte entrada para a outra parte, e as partes tm de ser
executadas em sequncia;
Comunicacional - quando as partes tm de produzir ou alterar o mesmo conjunto de dados, ou um
recurso externo;
Procedimental - quando as partes esto juntas apenas por deverem ser chamadas em conjunto por
uma determinada ordem;
Temporal - quando as partes esto relacionadas pela altura em que so chamadas, por exemplo,
todos os procedimentos de inicializao juntos no mesmo componente;
Lgica - as partes esto relacionadas apenas ao nvel lgico, por exemplo, todos os
procedimentos de entrada de dados juntos no mesmo componente;
Coincidental - as partes do componente no tm qualquer relao entre si.
ideal que as coeses dos componentes sejam funcionais. Assim, ao dar a um programador uma
funcionalidade para implementar ou para testar, ir desenvolver/analisar apenas um componente. Quando
h um erro detectado, normalmente sobre uma determinada funcionalidade que no est a ser
verificada, e dever ser fcil identificar o componente que no est a funcionar bem, uma vez que a
coeso funcional.
No outro extremo, da coeso dos componentes ser coincidental, qualquer das tarefas descritas no
pargrafo anterior vo obrigar anlise de todos os componentes. Mesmo que o programador tenha
tudo em mente, caso tenha acabado de escrever o cdigo (assumindo que apenas ele escreveu cdigo),
mesmo assim h penalidade de ter de alterar/ver vrios componentes, que normalmente esto em vrios
ficheiros.
O Desenho deve ser devidamente revisto e optimizado antes de se comear a implement-lo. Existem as
seguintes alternativas:
O desenho por contracto perde o sentido na programao orientada por objectos, em que cada classe
segue essa filosofia. A anlise de rvore-de-falhas no concretamente uma tcnica para melhorar um
desenho, excepto se se chamar a deteco de uma incoerncia e respectiva remoo de incoerncia um
melhoramento do desenho.
A validao matemtica permite em partes mais algortmicas provar que o algoritmo satisfaz os
requisitos. Muitas vezes esta tcnica consome demasiado tempo, dependendo da complexidade do que
se pretende provar.
Uma reviso de desenho uma reunio com o intuito de verificar e validar o desenho. A reviso
preliminar do desenho destina-se a verificar se o desenho conceptual corresponde ao que o cliente
pretende e est de acordo com os requisitos. A reviso crtica do desenho e a reviso do programa
de desenho, destinam-se a verificar o desenho tcnico. As reunies devem ser feitas com algum
formalismo, devendo existir um secretrio responsvel por redigir uma Acta com os principais pontos
apontados escritos de forma clara e concisa. O cliente deve estar presente nas revises preliminares do
desenho. Deve-se convidar colegas no envolvidos no projecto, mas deve-se manter o nmero de
participantes reduzido de forma a facilitar o dilogo.
Nota: As primeiras cinco mtricas podem ser utilizadas em fases iniciais do projecto, para decidir entre
desenhos alternativos, ou ter uma primeira ideia do esforo de implementao. As ltimas 4 mtricas so
mais centradas na classe, muito embora sejam bastante superficiais, uma vez que consideram os mtodos
todos com igual contribuio para o tamanho da classe, assim como os atributos.
Exemplo de SI: Uma classe definida a partir de uma s super-classe, com 10 mtodos redefinidos de
um total de 33 mtodos da super-classe, tendo a classe mais 3 mtodos novos. O nvel da classe 1
uma vez que s h uma super-classe. Aplicando a frmula tem-se: SI=10*1/36=0,28.
www.moodle.univ-ab.pt//print.php?id 19/85
26-01-2010 name
Mtricas propostas por Chidamber & Kemerer:
Mtodos pesados por classe ("weighted methods per class"/ WMC) - deixa a complexidade de
cada mtodo em aberto;
Nvel da rvore de herana ("depth of inheritance tree" / DIT);
Nmero de subclasses ("number of children" / NOC) - subclasses imediactas;
Dependncias entre objectos ("coupling between objects" / CBO) - nmero de classes que
interagem com a classe;
Resposta de uma classe ("response for a class" / RFC) - nmero de mtodos que podem ser
executados em resposta a uma mensagem;
Falta de coeso dos mtodos ("lack of cohesion of methods" / LCOM) - max{0;|P|-|Q|}; P -
conjunto de pares de mtodos cujos atributos que utilizam so disjuntos; Q - conjunto de pares de
mtodos que utilizam um ou mais atributos em comum.
Notas: estas mtricas so mais detalhadas e tambm relevantes para a estimativa do esforo de
implementao/manuteno de cdigo, mas mantendo a simplicidade. A mtrica mais complicada de
calcular a falta de coeso. Nesta mtrica consideram-se todos os pares de mtodos, e v-se para cada
par se utilizam atributos da classe em comum ou no. Caso a maior parte dos pares utilize atributos em
comum, a falta de coeso nula, caso contrrio a falta de coeso o nmero de pares a mais que no
tm atributos em comum.
Exemplo de LCOM: Uma classe tem um atributo, que utilizado no mtodo m1 e m2, tendo tambm
os mtodos m3 e m4 que no utilizam o atributo da classe. O nico par de mtodos com atributos em
comum o (m1,m2), e os restantes 5 pares no tm nada em comum. A classe tem portanto valor 5-1=4
de falta de coeso.
altura de se dar uma soluo ao problema do cliente, mas ainda na linguagem do cliente, de forma a
que este valide a soluo proposta. Este exemplo, sendo um simulador, temos de indicar de alguma
forma o essencial do algoritmo.
Parmetros:
semente aleatria;
nmero de jogadores;
nmero de cartas fechadas;
nmero de cartas abertas;
nmero de jogos.
Algoritmo:
www.moodle.univ-ab.pt//print.php?id 20/85
26-01-2010 name
1. Baralhar o baralho de cartas;
2. Dar cartas a cada jogador;
3. Calcular a melhor mo de cada jogador (ordenar as cartas do jogador com as cartas da melhor
mo em primeiro lugar);
4. Mostrar resultado.
O ponto 3 do algoritmo aqui o desafio, e tambm o ponto que poderemos necessitar de validao da
parte do cliente, pelo que deve ser detalhado. Evidentemente que, se o cliente no conseguir
compreender, este ponto pode passar para o desenho tcnico.
1. Ordenar as cartas por nmeros (pares, trios, quadras ficam todas seguidas);
2. Processar todas as cartas, e para cada carta:
1. Se existirem 3 cartas seguintes com o mesmo nmero da carta actual, ento o resultado
passa a poker=7;
2. Se existirem 2 cartas seguintes com o mesmo nmero da carta actual, ento o resultado
passa a trio=3. No entanto, se j tiver sido detectado um par, dois pares ou outro trio,
ento o resultado passa a fullen=6;
3. se existir 1 carta seguinte igual, ento o resultado passa a par=1. Se j foi detectado um
par, ou dois pares, ento o resultado dois pares=2. Caso tenha sido detectado um trio, o
resultado passa a fullen=6.
Verificar sequncia:
Verificar Cor:
www.moodle.univ-ab.pt//print.php?id 21/85
26-01-2010 name
2. se o contador atingiu o valor 5, o resultado cor=5, e pra.
Se o cliente no compreender a descrio do algoritmo, no h nada a fazer, mas se tal no for o caso, a
vantagem do cliente validar a soluo apresentada muito importante porque: por um lado retira ao
analista parte da responsabilidade de garantir que a soluo proposta resolve o problema do cliente, e
por outro lado permite ao cliente reflectir se o problema que especificou realmente o problema do qual
necessita de uma soluo. Caso o desenho conceptual no seja devidamente compreendido pelo cliente,
este s ir reflectir quando tiver a primeira verso da aplicao, altura em que compreende realmente
qual tinha sido a soluo proposta.
Nesta fase necessrio dar solues tcnicas, no necessrio ter a preocupao de fazer um
documento que o cliente compreenda, mas sim que o programador compreenda, e possa com base nele
construir uma aplicao.
Dado que o cliente no especificou nenhuma interface com o utilizador, e para facilitar os testes, faremos
uma aplicao de linha de comando e que funciona com o EngineTester. Esta opo no nos restringe
futuras utilizaes do cdigo em outros contextos, apenas nos facilitar a interface e tambm os testes.
Para tal necessrio reutilizar cdigo do EngineTester com as classes: TEngine; TVector; TRand, sendo
fornecido tambm o cdigo da funo main. Tem que se redefinir uma subclasse de TEngine para o
problema concreto, e as classes especficas.
Atravs da documentao existente podem-se identificar vrios candidatos a classes: Carta; Baralho;
Mo; TipoMo; Jogador; Jogo. A experincia e o bom senso so essenciais, podendo nesta altura tanto
simplificar um problema complexo, como complicar um problema simples. As indicaes neste captulo
sobre um bom ou mau desenho devem ser lidas e questionadas principalmente por quem no tenha ainda
muita experincia. Neste caso concreto, quais dos candidatos a classe descritos acima valem a pena
passar para classe? Nenhum. No entanto, de toda a convenincia a criao de uma classe. Vamos
comear por analisar os candidatos a classe:
Carta - Tem como atributos o naipe e nmero. Tem algum mtodo? No. Os atributos mudam ao
longo do tempo? No. Ainda por cima cabe num s byte, pelo que no faz sentido uma classe.
Baralho - Esta classe poderia guardar para cada carta o local onde est, e em que posio.
Poderia ter um mtodo para baralhar, outro para ordenar as cartas que esto num local, e um
mtodo para calculo da melhor mo para as cartas de um determinado local. O nico mtodo a
utilizar todas as cartas seria o mtodo Baralhar, de resto os restantes s utilizam parte dos dados
da classe, pelo que faz mais sentido uma classe que tenha um conjunto de cartas em vez de ter
www.moodle.univ-ab.pt//print.php?id 22/85
26-01-2010 name
todas as cartas separadas por local.
Mo - Esta a classe mais parecida com um conjunto de cartas, dado que uma mo um
conjunto de cartas, mas o nome deixa de fora a possibilidade de ter todo o baralho, pelo que um
nome Cartas mais geral e indicativo do conceito que representa, um conjunto de cartas.
TipoMo - Poderia haver um conjunto de classes em que cada uma tinha um mtodo para
detectar se uma mo era desse tipo ou no, mas como se viu no desenho conceptual, h vantagem
em verificar todos os tipos de mo de uma s vez, numa s funo por uma ordem especfica. Esta
classe a existir teria apenas mtodos, o que no um bom indicador para uma classe.
Jogador - Os atributos seriam as cartas que um jogador possui, ou seja, um objecto com um
conjunto de cartas. A classe contem um s atributo, no h mtodos que no sejam aplicados
directamente ao nico atributo que possui, pelo que a criao desta classe, para j no trs
vantagens.
Jogo - Dado que se pretende simular 1 jogo, no h vantagem aparente. Quando se pretender
simular vrios jogos e manter os jogos em memria, ento nessa altura far sentido a criao desta
classe.
Aconselha-se portanto a criao da classe especfica TCartas e redefinio da classe TEngine, a classe
TCartasEngine.
Este diagrama de classes tem para as classes reutilizadas os atributos e mtodos que so relevantes para
a nossa implementao, e para as classes implementadas os atributos e mtodos que se prev serem
necessrios.
O TVector uma classe que para gerir a alocao/dealocao de vectores de objectos de uma classe
arbitria Item. Tem os mtodos convenientes a uma abstraco tanto a uma sequncia de objectos,
como a um conjunto de objectos. So apresentados no diagrama os mais teis para o nosso problema. A
classe TRand tem um gerador de nmeros aleatrios implementado, utilizado pelo TVector para o
mtodo RandomOrder, o que permite manter o output constante no caso do cdigo ser compilado num
outro compilador, o que no aconteceria se se utilizar o gerador de nmeros aleatrios de uma biblioteca
disponvel num compilador especfico.
www.moodle.univ-ab.pt//print.php?id 23/85
26-01-2010 name
O TEngine uma classe abstracta, que tem 5 vectores com informao sobre os parmetros. Para cada
parmetro tem de existir um valor em cada um dos vectores (mais correcto seria ter feito uma classe
para parmetro, e um vector de parmetros). Cada parmetro tem um valor, um nome, uma descrio,
um valor mximo e um valor mnimo. As unidades so sempre em inteiros. Os parmetros devem ser
inicializados no mtodo Reset. O mtodo Run deve ter o algoritmo, que deve aceder ao vector value
para obter o valor dos parmetros, que podem no ser os inicializados no mtodo Reset no caso do
utilizador ter alterado o valor de omisso. A classe TCartasEngine deve portanto redefinir esses dois
mtodos.
O mtodo TCartas tem um TVector com o conjunto de cartas, sendo cada carta um char. Para aceder
ao nmero e naipe de uma carta, os mtodos estticos Numero e Naipe esto definidos, bem como para
construir uma carta com o nmero e naipe, pode-se utilizar o mtodo esttico Carta. O mtodo Baralho
inicializa este conjunto de cartas com todas as cartas do baralho, enquanto que o mtodo Poker calcula o
valor da melhor mo disponvel (o algoritmo principal), existindo ainda um mtodo Dar, que retira n
cartas deste conjunto de cartas, e coloca-as no conjunto de cartas mao. No necessrio um mtodo
para baralhar, j que TVector j tem o mtodo RandomOrder.
Vamos ficar por aqui, os mtodos Run e Poker esto no desenho conceptual, sendo provavelmente mais
penosa a construo de um diagrama de actividades do que propriamente o cdigo. Os mtodos
Baralho e Dar tm uma implementao simples, e embora a utilizao da classe TVector facilite, mesmo
sem esta classe apenas se ter cuidado na alocao de memria e implementar um algoritmo de
ordenao e outro para baralhar. portanto altura de comear a escrever o cdigo!
"Software Engineering, theory and practice", second edition, Prentice Hall, Shari Pfleeger, pg. 196-201,
220-225, 231-248, 294-300.
www.moodle.univ-ab.pt//print.php?id 24/85
26-01-2010 name
4 - Cdigo
Esta a parte do processo em que se d realmente instrues ao computador para que sejam
executadas de forma automtica: o cdigo. No se ensina aqui a escrever cdigo, a programar, essa
matria j deve ser do conhecimento do estudante. Neste captulo estamos interessados em programar
bem, no em termos de conseguir implementar um algoritmo complexo e eficiente, mas em termos de
facilidade de escrita e de leitura.
Cdigo complexo e brilhante, com documentao interna de forma a ser lida por pessoas inteligentes,
com capacidade de ler e apreciar a obra de arte, ser lido por um colega apenas aps algum bug ter sido
reportado, e a sua apreciao ser mais do tipo: "que grande baralhada que para aqui anda".
Como se pode tornar mais fcil a escrita? Atravs de um ambiente de desenvolvimento com auxiliares de
memria e de escrita, levando a que o cdigo fique partida com menos erros e simultaneamente leve
menos tempo a ser escrito, contribuindo ambos os pontos para a reduo do custo do software, e para o
aumento do prazer de programar.
A reduo do tempo de escrita do cdigo consegue-se apenas se o cdigo for escrito com calma. Caso
o cdigo seja escrito pressa, independentemente do ambiente de desenvolvimento, o nmero de erros
sobe e a quantidade de trabalho feita que no final no serve para nada aumenta, levando a um aumento
no tempo de escrita de cdigo.
Como se pode tornar mais fcil a leitura? Aqui o ambiente de desenvolvimento tem tambm influncia,
mas com menor relevo. A boa documentao interna, a utilizao de uma norma de escrita de cdigo e a
reutilizao de cdigo a base para se conseguir escrever cdigo de fcil leitura e portanto mais
facilmente testvel e com menores custos de manuteno.
Caso algo corra mal nesta fase, no se pode concluir que a culpa do programador. Existe tambm o
prprio problema que deveria estar resolvido na fase de desenho. Caso tenha que ser implementado um
algoritmo complexo, no completamente definido na fase de desenho, o programador pode no ter bases
matemticas para o compreender e implementar. Ou o mdulo a implementar pode ser demasiado
grande e o desenho actual no permitir abstraces. Nesse caso o programador poder no ter
capacidade para compreender e implementar o mdulo. portanto necessrio que a fase de desenho
seja bem realizada para que esta fase tambm o seja. O bom senso manda tambm que se atribua os
mdulos mais complexos aos programadores mais experientes.
www.moodle.univ-ab.pt//print.php?id 25/85
26-01-2010 name
Num segundo passo tem que se escrever as declaraes das classes, e escrever as implementaes dos
diferentes mtodos vazios, bem como tudo o que necessrio para o programa se poder compilar, e
finalmente compilar o programa. Aps alguns acertos entre nomes das classes e mtodos que esto
ligeiramente diferentes na declarao e implementao, o programa compila.
No terceiro passo comea-se a escrever cdigo propriamente dito, a implementao de cada mtodo de
uma classe. Nessa altura necessrio conhecer para que servem todos os atributos da classe e restantes
mtodos, bem como ter o conhecimento das classes e bibliotecas que so utilizadas. Aps cada mtodo
escrito, h que compilar para ver os erros de sintaxe. Nomes de atributos/mtodos mal escritos, blocos
de cdigo mal fechados, argumentos do tipo errado, so exemplos de erros de sintaxe encontrados e
corrigidos. O compilador d uma lista de defeitos, com a linha em que ocorrem. Infelizmente o defeito no
cdigo pode ser originado por um erro em outra zona do cdigo, provavelmente anterior, e o mesmo
erro pode originar muitos defeitos. Como se v a lista de defeitos, convm aps a localizao do erro
voltar a compilar para obter a lista actualizada de defeitos. Este processo deve ser repetido aps cada
mtodo para limitar a zona que se tem que procurar pelos erros.
Num quarto passo, aps uma classe estar completamente escrita, convm preparar um pequeno bloco
de teste para ver se a classe est a fazer o que era suposto. O programa compila e corre o bloco de
teste. Este passo deve ser feito sem ansiedade, j que tem-se a certeza que haver problemas. Aps
confirmada a dura realidade tem que se obter mais informao sobre o que no est correcto,
normalmente espalhando informao de debug do que est a ser feito a cada momento para o ecran.
Pode-se tambm utilizar um debuguer de linha de comando, o qual permite correr o programa e parar
numa determinada linha de cdigo, podendo nessa altura consultar o estado do programa,
nomeadamente consultar o valor das variveis, saber quais os mtodos chamados e com que
argumentos, etc. Ao detectar um problema so introduzidas alteraes ao cdigo para que este funcione
melhor e repete-se o processo. Por vezes as alteraes no resolvem e criam elas mais problemas, mas
eventualmente todos os problemas ficam resolvidos e o primeiro teste classe implementada passado
positivamente.
As outras classes vo sendo feitas, algumas delas passando por cima do ponto quatro, isto , no so
testadas em separado de forma a no perder tempo a fazer o cdigo de teste. Uma altura chegar em
que tudo est implementado. Nessa altura o cdigo novamente testado atravs de um processo
idntico ao ponto quatro mas com cdigo suspeito todo o cdigo produzido e no apenas uma
classe. Nesta altura normal dizer que o cdigo j est feito, s falta testar, sendo de prever que logo
que o cdigo corra uma vez correctamente, seja dado como cdigo a funcionar, no havendo lugar a
mais demora.
claro que tudo isto possvel acabar aqui caso o desenho esteja em condies. Se o nosso
programador teve a sorte de ter um colega experiente que fez o desenho, ento tudo bate certo. Caso o
desenho tenha sido feito por algum sem experincia, descobre agora que o desenho no dava para
resolver o problema em questo, era at incoerente, pelo que no consegue completar o programa para
fazer o teste final.
4.1.2 Melhoramentos
Pode-se facilitar a escrita de cdigo primeiro no editor de cdigo. O editor deve conhecer a sintaxe da
linguagem de programao, de forma a colorir as palavras pertencentes linguagem, bem como o incio e
fim de blocos. Deve tambm ter conhecimento dos restantes ficheiros pertencentes ao projecto, de forma
a poder identificar nomes de atributos e mtodos vlidos, identificando assim os mal escritos. Desta
forma, erros de sintaxe so detectados logo em tempo de edio e corrigidos. Este conhecimento
aproveitado tambm para facilitar a escrita. Ao escrever as primeiras letras de um atributo ou mtodo, o
www.moodle.univ-ab.pt//print.php?id 26/85
26-01-2010 name
editor fornece logo as vrias possibilidades que existem para completar com um nome vlido.
Ao criar uma nova classe, o ambiente de desenvolvimento cria logo os ficheiros de declarao e
implementao, e o cdigo essencial, dependente naturalmente da linguagem de programao. Pode-se
adicionar um mtodo ou atributo atravs do ambiente de desenvolvimento, sendo colocada logo uma
declarao e implementao nos ficheiros respectivos. Ao chamar-se um determinado mtodo tem que
se conhecer o que este faz e quais os seus argumentos. Durante a escrita, ao comear a escrever os
argumentos de um mtodo, o editor apresenta de imediacto ao programador no s os argumentos na
declarao do mtodo, como tambm o comentrio que est junto da declarao com a descrio do
que o mtodo faz.
A navegao pode ser tambm melhorada. Sem ambiente de desenvolvimento, o programador quando
quiser ir para a implementao de um mtodo, tem que saber em que ficheiro est, abrir o ficheiro no
editor, e navegar no ficheiro at ao mtodo. O ambiente de desenvolvimento pode listar todas as classes
e mtodos do projecto, independentemente dos ficheiros em que esto, permitindo ao utilizador ir
directamente para a declarao ou implementao do mtodo. Naturalmente que se o programador
necessitar, pode efectuar procuras ou substituio de texto num ou em todos os ficheiros do projecto.
A integrao do editor, compilador e debuguer, permite por um lado que da lista dos erros de
compilao se v directamente para a linha do cdigo onde o erro foi detectado, e por outro lado que se
possa colocar pontos de paragem no cdigo e mandar correr, e ao parar o programa obtem-se logo
janelas com o estado do programa. Pode-se nessa altura efectuar algumas alteraes ao cdigo e
compilar continuando a correr o programa com a actualizao, no sendo necessrio em muitas
situaes reiniciar a corrida.
As diferentes ajudas nunca devem ser vistas de forma a que o programador no necessite de saber isto
ou aquilo. O programador responsvel por todo o cdigo, excepto o cdigo das bibliotecas que
utilizar, que tem de o ler e perceber, mesmo que parte deste tenha sido escrito automaticamente pelo
ambiente de desenvolvimento.
Esta ltima pergunta poder pensar-se que deva ser ao contrrio. Como natural que o cdigo tenha
falhas, a existncia do historial de falhas corrigidas apenas vem dar informao que o cdigo foi bastante
testado e pode ser utilizado com segurana. Se por outro lado nada se saber sobre falhas, quer dizer que
no se encontrou falhas porque se testou pouco.
Fazer o componente genrico, utilizando sempre que possvel parmetros em vez de constantes;
Separar partes que eventualmente possam ter de ser alteradas das que provavelmente nunca sero
alteradas;
Manter historial de falhas corrigidas;
Respeitar a norma de escrita de cdigo (formatao; comentrios; nomes; estilo).
Estes pontos podem ser respeitados o mximo possvel, mesmo ao escrever cdigo que no para ser
reutilizado. Isto porque na verdade no se sabe se no ir aparecer no prprio programa uma situao
em que o cdigo que se est a escrever no possa ser reutilizado, e depois porque o mdulo a construir
pode vir a ser repensado e feito reutilizvel para outros projectos. Estes pontos facilitam tambm a fase
de testes.
Esta seco est orientada para terminologia da programao orientada por objectos, mas pode ser
utilizado tambm na programao estruturada e programao funcional. A correspondncia de classe
para programao estruturada poder ser mdulo ou ficheiro de cdigo, enquanto que a
correspondncia de mtodo ser funo ou procedimento.
O ambiente de desenvolvimento em programao orientada por objectos tratar da criao dos ficheiros,
devendo os nomes serem iguais aos nomes das classes. Caso assim no seja, dever ser criado um
ficheiro por cada classe, com o mesmo nome da classe, ou dois no caso de existir ficheiro de declarao
e implementao. Em programao no orientada por objectos, o projecto deve ser dividido em
mdulos, ficando cada mdulo num ficheiro. Os mdulos devem conter funes que estejam relacionadas
entre si, e no devem ser muito grandes.
A lngua utilizada deve ser sempre a mesma ao longo de todo o cdigo, tanto no nome das variveis e
funes como nos comentrios.
1. Formatao
1.1 Indentao: Cada linha de cdigo deve comear por 4 espaos por cada bloco de cdigo em que
estiver inserido. aceitvel em vez de 4 espaos utilizar outro valor, desde que seja sempre o mesmo
para todo o ficheiro.
Exemplos C++:
www.moodle.univ-ab.pt//print.php?id 28/85
26-01-2010 name
As duas primeiras linhas e a ltima, no esto dentro
de bloco nenhum, enquanto que a 3, 4 e 6 linha
esto dentro do bloco de cdigo do mtodo, sendo
antecedidas de 4 espaos. A 5 linha est ainda
dentro do bloco do ciclo for, pelo que sobe 8
espaos.
Este cdigo est aparentemente bem indentado, no
entanto utiliza 2 espaos para a 3, 4 e 6 linha,
enquanto que para a 5 linha utiliza 6 espaos. Se a
indentao a 2 espaos, a 5 linha teria de ter 4
espaos e no 6.
1.2 Tamanho das linhas: As linhas tanto cdigo como de comentrios no devem exceder os 80
caracteres. Caso tal no seja possvel, a linha de cdigo deve ocupar mais que uma linha. Conta para
efeitos de indentao a segunda linha e seguintes, como se estivessem dentro de mais um bloco de
cdigo. Uma linha de comentrio que continue na linha seguinte mantm a indentao.
1.4 Incio e fim de bloco: A marca de incio e de fim de bloco de cdigo deve utilizar uma linha para o
incio e outra para o fim do bloco. As linguagens funcionais podem ignorar esta regra, uma vez que em
geral o primeiro elemento do bloco um identificador e convm que fique na mesma linha que a abertura
de bloco.
A questo da indentao muitas das vezes vista como uma opo pessoal. Cada um acha que indenta
bem o cdigo, o que leva a que cada cdigo que se leia fique na sua indentao prpria, perdendo-se
parte da vantagem para quem l. J o cdigo no indentado por completo torna a leitura tortuosa, dado
que fora o leitor a prestar grande ateno ao incio e fim de blocos, ateno essa que faz parte das
obrigaes de quem escreve e assim passa tambm para quem l o cdigo, caso este no esteja
indentado.
2. Comentrios
2.1 Localizao: Os comentrios devem anteceder o cdigo que comentam. Pode-se colocar pequenos
comentrios ao bloco na prpria linha de incio ou fim de bloco de cdigo.
2.2 Comentrio de classe: No incio de cada classe deve existir um comentrio de classe. Neste
comentrio deve conter informao sumria sobre a classe. D-se liberdade de incluir mais ou menos
campos conforme apropriado, no entanto o comentrio de classe deve ter obrigatoriamente os campos
(ingls/portugus):
www.moodle.univ-ab.pt//print.php?id 29/85
26-01-2010 name
2.3 Comentrio de mtodo: Cada mtodo deve ter um comentrio inicial, idntico ao comentrio de
classe, acrescentando:
2.4 Comentrio de linha: Devem ser colocados comentrios de linha apenas em zonas complexas, de
forma a complementar a descrio do algoritmo feita no comentrio de mtodo. Os comentrios de linha
devem assumir que o leitor conhece a linguagem de programao, pelo que no devem repetir o que est
no cdigo.
Exemplo C++:
O primeiro comentrio desnecessrio, uma vez
que suposto antes de ler este mtodo tenha sido
lida a definio de classe onde estar definido a. O
nome do mtodo tambm suficientemente
sugestivo, pelo que o comando no necessita de
comentrio.
3. Nomes
3.1 Variveis iteradoras inteiras: Os nomes das variveis devem comear por letras minsculas. As
variveis iteradoras inteiras devem ser chamadas i, j e k. Devem ser reutilizadas, devendo o k ser
utilizado apenas se o i e j estiverem em utilizao. Caso sejam necessrias mais que trs variveis
www.moodle.univ-ab.pt//print.php?id 30/85
26-01-2010 name
iteradoras, adicionar um nmero letra i (i1, i2, ...). Caso as variveis iteradoras sejam reais ou de outra
natureza, utilizar as letras l, m e n.
3.2 Variveis no iteradoras: Para as variveis no iteradoras deve-se utilizar nomes elucidativos. Na
juno de dois nomes, a letra inicial do segundo nome deve ser maiscula. A primeira letra deve ser
sempre minscula. Caso no existam nomes elucidativos, utilizar as letras u, v e w para os valores
inteiros, x, y e z para os valores reais, a, b e c para nomes (strings), e p, q e r para apontadores ou
variveis de outra natureza.
3.3 Constantes e macros: Constantes ou macros devem ser escritos em maisculas, e as palavras
separadas por um "underscore": '_'.
3.4 Estruturas e classes: Os nomes das estruturas ou classes tm de ter sempre nomes elucidativos e
devem comear por T se um tipo abstracto de dados, S se for uma estrutura, e C se for uma classe no
geral, D se for uma classe para caixas de dilogo de uma interface grfica. Na juno de dois nomes, a
letra inicial de cada nome deve ser maiscula.
3.5 Mtodos: Os nomes dos mtodos devem ter sempre nomes elucidativos. No caso de programao
no orientada por objectos, o nome das funes e procedimentos deve ser antecedida do nome ou
iniciais do mdulo a que pertencem. Na juno de dois nomes, a letra inicial de cada nome deve ser
maiscula. No utilizar o mesmo nome para funes ou mtodos com argumentos diferentes, a no ser
que as funes ou mtodos sejam apenas diferentes verses. Em princpio, o nome de um procedimento
deve conter um verbo no infinitivo, enquanto que o nome de uma funo dever ter o nome da grandeza
que calcula, no necessitando de verbo. As funes com resultado booleano devem conter um verbo no
presente ou adjectivo de forma a serem utilizadas dentro de condicionais.
4. Estilo
4.1 Blocos de cdigo: No abrir um bloco de cdigo para um s comando, excepto para evitar confuso
por exemplo numa cadeia if/else.
Exemplo C++:
O bloco de cdigo criado para o ciclo for
desnecessrio uma vez que tem apenas um
comando.
www.moodle.univ-ab.pt//print.php?id 31/85
26-01-2010 name
4.2 Repeties: No repetir uma sequncia de comandos. Muitas vezes por facilidade ao escrever
cdigo, repetem-se comandos quando poderiam ser postos dentro de um ciclo.
Exemplo em C++:
A segunda implementao da funo taxa
prefervel primeira, uma vez que o teste sempre
o mesmo e pode ser colocado dentro de um ciclo.
Por vezes no s um comando repetido mas sim
vrios comandos que poderiam estar dentro de um
ciclo, com eventualmente recurso a um ou mais
vectores estticos com os argumentos que sejam
necessrios.
4.3 Tamanho dos mtodos: No fazer mtodos demasiado grandes (mais de 100 linhas de cdigo).
Nesse caso agrupar comandos relacionados em mtodos, mesmo que o mtodo venha a ser chamado
uma s vez.
4.4 Comandos numa linha: Iniciar sempre uma nova linha para um comando, ou seja, no colocar antes
de um comando um condicional, ciclo, ou outro comando.
Exemplo em C++:
Os dois comandos do if/else deviam estar em linhas
diferentes.
Exemplo: Poker
A segunda via claramente mais simples e menos real que a primeira via, mas entre no fazer nada no
Ambiente de Desenvolvimento, prevervel ao menos re-escrever cdigo, que poder mesmo assim
colocar o estudante em situaes em que lhe sero teis os mecanismos de facilitao de leitura, escrita e
depurao do cdigo.
Este exemplo do Poker tem cdigo reutilizado, o TVector, enquanto que o TEngine apenas tenha a sua
utilidade clarificada no captulo do EngineTester. Por agora pode ser visto como uma forma de poupar a
escrita da interface com o utilizador, que embora seja de texto, d sempre algum trabalho. A classe
TCartas pode ser vista como uma classe a ser reutilizada em outras aplicaes de cartas, pelo que as
preocupaes em escrever cdigo reutilizvel devem ser consideradas para esta classe.
Aps realizar esta actividade, pela via 1 ou 2, coloque o cdigo no frum de estudante, e veja o cdigo
dos seus colegas. Pode ver o nvel de diferenas que duas implementaes com a mesma especificao e
desenho podem atingir, e por outro lado, a dificuldade que poder ter em ler o cdigo de um colega,
www.moodle.univ-ab.pt//print.php?id 32/85
26-01-2010 name
mesmo tendo acabado de implementar uma aplicao idntica.
Vamos agora simular uma primeira alterao especificao, e respectiva resoluo passo a passo. Se
quiser resolva primeiro e s depois veja a resoluo.
Pretende-se calcular a frequncia absoluta de ocorrncia de cada tipo de mo, devendo essa
informao ser guardada de forma a ser retornada no mtodo TCartasEngine::Indicator
De forma a simular uma situao real, esta actividade no deve ser realizada logo aps a actividade
anterior. Deve fazer uma actividade formativa de outra unidade curricular, e s depois continuar. O
objectivo desta actividade no apenas reflectir a alterao no cdigo, mas faz-lo do modo mais rpido
e seguro, numa altura em que j tem a cabea em outro projecto, utilizando para tal funcionalidades
disponveis no Ambiente de Desenvolvimento. Quem no fez a actividade anterior, pode realizar esta,
partindo do cdigo da via 2 (Cartas.zip).
A - Recepo do Cdigo
H que ter alguns cuidados ao receber cdigo de outras pessoas, nomeadamente conveniente estes trs
passos:
No trabalho, o cdigo so os ficheiros cpp e h, pelo que no Visual C++ 2008 Express Edition h que
criar um novo projecto com estes ficheiros e mandar correr, tal como no tuturial.
Pode-se verificar se os ficheiros esto todos, aps o qual manda-se correr (F5). Dever compilar e de
seguida o programa inicia. Caso no tivesse escolhido Console Application Project, daria um erro e o
programa no corria.
set seed 1
www.moodle.univ-ab.pt//print.php?id 33/85
26-01-2010 name
set information 1
set limit states 1
run
Neste caso no h integrao do cdigo, parte-se de um cdigo e pede-se para fazer uma alterao.
B - Alterao ao Cdigo
Tendo um cdigo a funcionar, feito por outra pessoa ou pelo prprio j h bastante tempo, pretende-se a
correco de um bug, ou uma pequena nova funcionalidade.
A abordagem mais convencional consultar toda a documentao de forma a ter a ideia global da
aplicao. Caso a alterao seja pequena no sequer necessrio a compreenso global do cdigo,
desde que se mantenha o focus no que necessrio fazer. Por outro lado, como regra geral deve-se
manter o cdigo desenvolvido o mais pequeno quanto possvel, o que leva a que se reutilize a maior
quantidade possvel de cdigo existente, pelo que algum conhecimento do que existe deve ser mantido.
Segue-se o raciocnio de uma possvel abordagem, que tenta minimizar o cdigo alterado, e tambm o
cdigo consultado. S analisado o cdigo que tem de ser, e tudo o resto ignorado. As alteraes no
podem no entanto ser cegas, so sempre baseadas em evidncias. Alteraes cegas do origem a bugs e
muito tempo perdido, pelo que vale sempre a pena consultar mais cdigo para ter uma evidncia antes de
tomar a deciso de alterar algo.
1. Identificar o que tem que ser feito, a resposta pergunta: o que deve o sistema fazer de novo?
Tem que estar claro este ponto, caso contrrio no vale a pena comear. Se for possvel assentar
a resposta no teste que existe ao cdigo, melhor. No trabalho, tem que se contar quantas mos
ocorreram de cada tipo a cada jogador. H evidncia que j existe uma funo que calcula o tipo
de mo, uma vez que essa informao colocada no exemplo (nada, par, etc).
2. Estrutura de dados. O que o sistema tem que guardar? No trabalho um contador (portanto um
inteiro) por cada tipo de mo. Quantas mos existem? Basta procurar no cdigo caso no tivesse
essa informao j no enunciado. Poderia-se procurar por nada (Ctrl+F nada) e encontrava-
se um vector, alis dois vectores de nome poker com as vrias mos possveis, ou seja, 10 tipos
de mos. portanto suficiente um vector de inteiros de tamanho 10.
3. Onde guardar os dados? Tem que ser num local onde se possa aceder nos diversos locais. O
enunciado diz-nos que se tem que se devolver o resultado no mtodo TCartasEngine::Indicator,
pelo que os dados tm que ser acediveis a partir desse mtodo, mas a simulao no feita neste
mtodo, pelo que os dados no podem ser locais. S podem ficar ento na classe do mtodo,
TCartasEngine.
1. Criao da estrutura de dados. No Visual Studio h a possibilidade de adicionar variveis a
objectos atravs de wizard (na Class View, boto de contexto em cima da classe: Add
Add variable variable type = long [10] variable name = contador).
2. Caso se reutilize a estrutura de dados presente no cdigo, seria necessrio rever a sua
utilizao. Neste caso a classe TCartasEngine no tinha quaisquer dados, pelo que criou-se
a estrutura que era necessria.
www.moodle.univ-ab.pt//print.php?id 34/85
26-01-2010 name
3. Convm colocar um comentrio em todas as zonas alteradas, referenciar a alterao com
um cdigo (ou a data de alterao), para no caso de se querer saber o que foi feito para
determinada alterao ao cdigo se localizar facilmente as linhas alteradas.
4. Inicializao da estrutura de dados. Onde se inicializa o contador? A primeira resposta : no
construtor da classe. No entanto, no construtor da classe h um s comando, uma chamada ao
mtodo Reset(). A interpretao clara: esta classe tem a inicializao dos dados num mtodo
que no o construtor, de forma a poder reinicializar quando for preciso. Mantendo a filsofia, h
que colocar a reinicializao no mtodo Reset, mas se no entanto se colocar no construtor no
estaria incorrecto. A inicializao neste caso a colocao da estrutura a zero: for(int
i=0;i<10;i++) contador[i]=0;
5. Actualizao dos dados. Onde se incrementa o contador?
1. H que localizar o cdigo onde a mo calculada. Um bom ponto de partida descobrir o
local onde mostrada a informao para a consola: Ctrl+F Jogador, aps algumas
iteraes localizavam-se as linhas onde tal informao disponibilizada:
i. fprintf(stdout,"\nJogador %d: ",i+1);
ii. m[i].Save(stdout);
iii. m[i].SaveSolution(stdout);
2. Dado que aparece na consola a mo deste jogador, evidente que no objecto m[i] est j
o resultado da mo, ou ento esta calculada numa destas funes. Que tipo o objecto
m[i]? Basta parar o rato em cima da varivel e o Visual Studio diz, no h necessidade de
andar para cima e para baixo com a scrollbar: TVector<TCartas>, sendo portanto um
elemento do tipo TCartas. H que investigar esses dois mtodos, um deles dever utilizar o
vector poker, que contem os textos dos tipos de mos.
3. No mtodo SaveSolution encontra-se a utilizao do vector poker, com o argumento sendo
a chamada a um mtodo Poker(). Este mtodo deve portanto retornar o tipo de mo que
um objecto TCartas tem.
4. H agora que localizar a linha de cdigo em que o vector m ficou actualizado com as mos
de cada jogador. Colocando o cursor no cdigo da linha 5.a.i, basta procurar a anterior
referncia a m[ (Ctrl+Shift+I m[ , para continuar a recuar, continuar a carregar em
Ctrl+Shift+I). Onde a varivel aparecer numa situao de acesso no interessa, queremos a
ltima alterao, o que s pode acontecer atravs de uma atribuio ou chamada a um
mtodo. A primeira destas alteraes na linha: m[i].Poker();
5. Este mtodo j conhecemos, o que devolve o ndice da mo, os comentrios e cdigo
envolvente clarificam que se localizou o local correcto, pelo que pode-se fazer a alterao
da estrutura pretendida, a actualizao do contador: contador[m[i].Poker()]++;
6. Utilizao dos dados. No mtodo indicador basta retornar o valor do contador com base no
indicador recebido, testando eventualmente primeiro para ver se o indicador est dentro dos
limites do vector: if(indicador>=0 && indicador<10) return contador[indicador];
7. Compilar e Testar: h que repetir o teste, e utilizar a interface para obter o resultado pretendido.
Analisando o texto de ajuda, verifica-se que para pedir o indicador 3 tem que se escrever: get
indicator 3. O resultado a descrio da ajuda novamente, e lendo com mais ateno verifica-se
que h um comando para saber o nmero de indicadores: get indicators. O resultado 0. Falta
portanto definir os 10 indicadores que fizemos.
8. Corrigir. Procurando no cdigo onde indicado o nmero de indicadores, acabaria-se por
encontrar na funo main esse cdigo, em que o nmero de indicadores : engine-
>indname.Count(). O objecto engine do tipo TEngine, pelo que seguindo para a definio da
varivel obtem-se na classe a informao que os dois tvectors de strings indname e inddesc, tm
os nomes e descries dos indicadores. Estes dados tm de ser inicializados, e no foram, pelo
que tem que se ir novamente ao mtodo TCartasEngine::Reset para inicializar tambm estes
vectores com o tipos das mos. Bastar reutilizar o ciclo j feito e incluir tambm a adio de
www.moodle.univ-ab.pt//print.php?id 35/85
26-01-2010 name
novas linhas (objectos TVector esto a ser utilizados no mesmo mtodo que serve de exemplo,
para adicionar um novo elemento basta chamar o mtodo Add): indname.Add(poker[i]);
inddesc.Add(poker[i]);. Se se quiser pode-se fazer um novo vector com as descries dos tipos
das mos.
9. Compilar e Testar: repetir o teste e aps terminar efectuar o comando: get indicator 1, get
indicator 2, etc. Verificar que o nmero devolvido coincide com o nmero de tipos de mos
obtidos pelos jogadores no teste. Fazer um segundo teste com maior volume, por exemplo:
1. set information 0
2. set limit states 1000
3. run
4. (aguardar que acabe)
5. get indicator 1
6. get indicator 2
10. H evidncia que a alterao foi correctamente bem feita, o prximo passo enviar o cdigo a
algum que o teste.
"Software Engineering, theory and practice", second edition, Prentice Hall, Shari Pfleeger, pg. 307, 319-
320
www.moodle.univ-ab.pt//print.php?id 36/85
26-01-2010 name
5 - Testes
5.1 Introduo
A fase de teste no se destina a provar que o cdigo est correcto, uma vez que tal no possvel. O
objectivo da fase de teste encontrar falhas, e por mais cuidadoso que os programadores tenham sido
na fase do cdigo, juntamente com os intervenientes anteriores nas fases de especificao e desenho, as
falhas vo existir. No entanto no se pode efectuar as restantes fases de forma relaxada, assumindo que
na fase de testes qualquer problema ser encontrado. Se assim acontecer, a fase de testes encontrar
demasiadas falhas, e o custo do projecto ser muito superior.
Os testes so feitos de forma a verificar se os requisitos e o desenho so satisfeitos. Podem ser feitos
testes de unidades, a cada componente, e testes de integrao a diversos componentes, sendo feito um
teste final a todo o sistema. Ao encontrar uma falha h que clarificar as condies em que a falha ocorre,
para que possa ser repetida e seja relativamente simples de localizar o componente defeituoso. Por esse
motivo, manda o bom senso efectuar testes de unidades e s depois os testes envolvendo mais
componentes, de forma a ser facilmente localizada a origem da falha. Aps estes testes terem sido
realizados com sucesso, que so testes de funcionalidades, h que fazer testes de performance, e testes
de aceitao. Neste captulo sero vistas tcnicas e boas prticas para a realizao de testes.
Antes comear procura de defeitos, podemos questionar como so os defeitos? Do que que
andamos procura? A IBM construiu uma classificao ortogonal para os defeitos, de forma a
conhecer-se um pouco mais do que se procura nesta fase, e tentar desta forma orientar os testes:
Adicionalmente, um defeito diz-se de omisso caso seja derivado de algum aspecto em falta no cdigo
(exemplo: varivel no inicializada). Um defeito diz-se de no omisso caso seja derivado de algum
aspecto errado no cdigo (exemplo: varivel inicializada para o valor errado).
www.moodle.univ-ab.pt//print.php?id 37/85
26-01-2010 name
Nestes casos faltar ou uma inicializao ou uma utilizao da varivel atribuda. Os defeitos de no
omisso so a maioria dos erros detectados, tipicamente os sintacticamente incorrectos.
Os testes so feitos a diversos nveis, e por diferentes intervenientes. O primeiro teste feito pelo
programador na fase de implementao. Actualmente os ambientes de desenvolvimento permitem ter o
cdigo sempre pronto a correr, de forma a se ir testando o que se vai fazendo. Desta forma fcil aps a
escrita de um mtodo verificar se est a funcionar. Um teste maior ser feito pelo prprio programador
aps toda a classe estar implementada. Assim o programador pode detectar problemas cedo e corrigir
de imediato, uma vez que sabe que a origem do problema muito provavelmente no cdigo que acabou
de escrever. Um teste a uma classe ou mdulo, chama-se teste de mdulos, ou teste de componentes, ou
ainda teste de unidades. Deve ser realizado tambm por uma pessoa diferente da que implementou o
mdulo.
Os componentes vo ficando prontos, e aps estes terem passado o teste de unidades, h que executar
um teste de integrao envolvendo mais que um componente, de forma a verificar que os diversos
componentes interagem da forma correcta.
Aps os testes de integrao h que efectuar testes a todo o sistema. O primeiro o teste funcional que
consiste em testar o sistema para verificar se est de acordo com os requisitos funcionais. De seguida h
que efectuar o teste de performance, de forma a verificar os requisitos no funcionais. O teste seguinte
o de aceitao, que envolve o cliente e verifica os requisitos do cliente. Finalmente instala-se o sistema no
seu local final e efectua-se um teste de instalao com utilizadores finais.
Uma falha em qualquer documento pode ser encontrada em qualquer altura. Salienta-se o facto de os
primeiros documentos a produzir serem os ltimos a testar, e portanto a verificar. O pior que poderia
acontecer seria a documentao tcnica de requisitos no estar coerente com os requisitos do cliente.
Caso a incoerncia no fosse detectada antes seria apenas no teste de aceitao, ou seja, numa fase
muito terminal do projecto, o que poderia obrigar a refazer tudo de novo. portanto natural que seja
atribuda a responsabilidade das fases iniciais do projecto s pessoas com mais experincia.
Quando o componente testado por outra pessoa, ao encontrar uma falha a preocupao dever ser a
de conseguir repetir a falha e report-la para que esta seja corrigida, e no propriamente de culpar a
pessoa que desenvolveu o componente.
Reviso de cdigo;
Provas matemticas;
Testes empricos.
A primeira via permite envolver recursos humanos no teste, tirando assim proveito em que pessoas
experientes detectam falhas muito rapidamente, mas por outro lado tm um custo elevado. A segunda via
requer que quem faa o teste tenha muito tempo e bases matemticas, e estas provas tm tambm de ser
verificadas, uma vez que tambm podem ter erros. A terceira via a mais utilizada, tambm
www.moodle.univ-ab.pt//print.php?id 38/85
26-01-2010 name
complementar das anteriores. Consiste em efectuar testes empricos atravs de execues do cdigo em
teste, e comparar os argumentos com os resultados de forma a verificar se os resultados esto correctos.
O teste analisa uma amostra das possveis execues que o cdigo pode originar, permitindo assim
verificar se funciona bem nessa amostra e por outro lado efectuar desde logo testes de performance.
Convm que a amostra seja representativa da populao, pelo que a escolha dos dados de teste
determinante. A dimenso da amostra ser dependente do tempo de execuo de cada corrida e do
tempo disponvel para todo o teste do componente.
Uma de duas filosofias pode ser utilizada na escolha de dados de teste: caixa preta (ou caixa fechada);
caixa branca (ou caixa aberta). No teste efectuado como caixa preta os dados de teste so escolhidos
sem fazer uso da implementao do objecto de teste, e so normalmente gerados aleatoriamente. O teste
em modo de caixa branca consiste em escolher os argumentos com base na anlise da estrutura interna
do componente, permitindo assim escolher uma amostra mais representativa de todas as execues que
podem ser efectuadas com o componente.
Os argumentos do teste so o conjunto de todas as variveis que se tem de inicializar para testar o
componente. No caso de serem muitas variveis torna-se complicado testar todas as combinaes.
Normalmente prefervel em caixa preta seleccionar uma distribuio para cada varivel. Caso as
variveis tenham um valor mnimo e mximo pode-se utilizar a distribuio uniforme, mas caso no
tenham limite pode-se utilizar por exemplo a distribuio exponencial negativa. Esta distribuio tem
probabilidade de gerar um valor muito elevado, muito embora tenha mais probabilidades de gerar um
valor perto do zero. Tem uma forma simples de ser gerada a partir da distribuio uniforme: -
log(Uniforme(0;1))
Em caixa branca o cdigo analisado e pode-se querer garantir que durante a execuo de todo o teste
as diversas situaes so testadas:
Se o cdigo for complexo poder ser difcil obter os dados de entrada para se garantir que se verifique
qualquer uma destas situaes. Pode-se naturalmente combinar a caixa branca com a caixa preta,
utilizando parte do teste valores que garantem por exemplo que todos os comandos so executados, e o
resto dos valores gerados aleatoriamente.
Uma reviso de cdigo pode ser de "walkthrough" ou inspeco de cdigo. No "walkthrough" quem
escreve o cdigo tem de apresentar equipa de reviso o seu cdigo, conduzindo a discusso de forma
www.moodle.univ-ab.pt//print.php?id 39/85
26-01-2010 name
informal, centrando-se a ateno no cdigo e no no programador.
Na inspeco de cdigo, a equipa de reviso tem de preparar uma lista de preocupaes as quais tem
de as verificar sobre a documentao e cdigo, por exemplo: definio da estrutura de dados est
consistente com a documentao de desenho; os comentrios no cdigo esto consistentes com o cdigo
que comentam; estimar a complexidade temporal e espacial do cdigo. O prprio programador pode
no fazer parte da equipa de reviso.
As revises de cdigo permitem a deteco de erros mais cedo, e portanto reduzindo a influncia desses
erros que teriam um custo muito maior para serem identificados mais tarde, e tambm um maior custo de
correco. Muitas das vezes no se fazem revises de cdigo porque as equipas de desenvolvimento de
software so pequenas, ou todas as pessoas esto atarefadas, ou ainda por ser muito cansativo analisar
cdigo feito por outros. O ganho de revises de cdigo pode no entanto ser muito elevado, se os
programadores passarem a ter mais cuidado no cdigo que escrevem, uma vez que vai ser analisado por
outros, e respectiva reduo no nmero de erros.
A estratgia Big-bang consiste em testar cada componente isoladamente primeiro, e de seguida testar
www.moodle.univ-ab.pt//print.php?id 40/85
26-01-2010 name
todo o sistema. Esta estratgia necessita de stubs e drivers e tem a desvantagem de ser complicado
localizar a origem das falhas no teste geral. possvel utilizar-se esta estratgia apenas em pequenos
sistemas.
Os testes de unidade e testes de integrao so direccionados a verificar se o cdigo est de acordo com
o desenho. O teste do sistema destina-se primeiramente a verificar se todo o sistema est de acordo com
os requisitos funcionais, de seguida efectuam-se testes de performance para verificar os requisitos no
funcionais, seguindo-se o teste de aceitao envolvendo o cliente e teste de instalao no ambiente do
utilizador final.
Os testes de performance devem ser efectuados conforme os requisitos no funcionais. Os mais comuns
so:
Teste de stress o sistema testado at aos limites especificados, num pequeno espao de
tempo, simulando um pico de utilizao;
Teste de volume grande volume de dados fornecido ao sistema, de forma a verificar se
responde correctamente quando tem demasiados dados;
Teste de velocidade verifica os tempos de resposta do sistema;
Teste de configurao so feitos testes com diferentes configuraes no software e no hardware;
Teste de compatibilidade so executados se o sistema necessitar de interagir com outros
sistemas;
Teste de regresso necessrio quando o sistema substitui outro sistema. Tem que se assegurar
que as funcionalidades anteriores esto implementadas no novo sistema;
Teste de segurana verifica a segurana do sistema.
Estes testes so chatos de se fazerem, e muitas das vezes so substitudos pela garantia do
profissionalismo e competncia da empresa que desenvolve o software. No apresenta ao cliente
relatrio de testes algum, o prprio cliente no pediu este relatrio, apenas quer o sistema a funcionar e
contenta-se com uma demonstrao do sistema. Se o sistema falhar durante a demonstrao, haver
certamente um conjunto de explicaes que o cliente no percebe e por isso fica satisfeito.
medida que o tempo passa, quando o sistema for sendo cada vez mais utilizado o cliente vai-se
apercebendo do que est mal no sistema, atravs das queixas dos utilizadores: "s X horas, quando
todos tentam aceder o sistema no responde", "no funciona quando se quer introduzir uma ficha com
mais de Y campos", "o sistema lento", "no funciona em computadores com o Sistema Operativo W",
"aps a ltima actualizao, j no se consegue introduzir uma ficha do tipo K, nem imprimir", "o
utilizador convidado, mesmo sem permisses consegue ver e editar as fichas". Nessa altura o cliente paga
empresa a manuteno que o sistema necessitar.
www.moodle.univ-ab.pt//print.php?id 41/85
26-01-2010 name
desenvolvimento de software.
Os testes de aceitao so feitos de acordo as preferncias do cliente. O cliente pode fazer um conjunto
de testes a efectuar, com as situaes tipo em que o sistema ser utilizado, de forma a verificar no s
que o sistema funciona bem como tambm a avaliar a performance do sistema. Normalmente efectua-se
tambm testes piloto, em que os utilizadores utilizam o sistema nas condies finais. Caso os utilizadores
sejam da empresa, o teste piloto chama-se de teste alfa, se os utilizadores forem os finais, chama-se
teste beta.
Aps o teste de aceitao terminar, o cliente dever dizer quais os requisitos que no esto satisfeitos, e
quais os que devem ser apagados, revistos ou adicionados.
Plano de teste - deve descrever o sistema e os testes a efectuar para verificar os requisitos;
Especificao de teste - deve conter os requisitos testados e como so testados;
Descrio de teste deve definir os dados de teste e os procedimentos de teste;
Relatrio de teste deve descrever os resultados obtidos.
Uma hiptese inserir falhas no software, que deve ser feita por algum da equipa de teste, mas que no
participa no teste. Inserindo-se por exemplo S=20 falhas, caso a equipa de teste encontre s=15 dessas
falhas e mais n=10 falhas diferentes, ento pode-se estimar o nmero total de falhas N pela frmula:
, assumindo que . Neste caso daria faltas, faltando portanto
encontrar 3,3 falhas. O problema deste mtodo que tem que se inserir muitas falhas para ter algum grau
de preciso, e as falhas devem ser da mesma natureza das que esto por descobrir. H tambm um
aumento no custo de teste.
Uma segunda hiptese utilizar duas equipas de teste independentes, descobrindo cada equipa um
nmero de falhas f1 e f2, das quais algumas falhas so iguais f12. Pode-se assumir que a eficincia de cada
equipa relativamente a descobrir o total de falhas n, ser de E1=f1/n e E2=f2/n. Pode-se estimar a
eficincia de uma equipa a descobrir as falhas que a outra equipa descobriu como sendo E1=f12/f2 e
E2=f12/f1, e portanto estimar o nmero total de falhas atravs da frmula n=f12/(E1*E2). Nesta soluo o
custo aumenta porque h falhas descobertas por ambas as equipas, mas no duplica propriamente, uma
fez que todas as pessoas envolvidas esto a testar o software. Notar no entanto que as equipas nunca
podem ser completamente independentes, uma vez que os testers tm formaes idnticas, e acabam
por ter a tendncia de descobrir as mesmas falhas.
www.moodle.univ-ab.pt//print.php?id 42/85
26-01-2010 name
Uma terceira hiptese utilizar o modelo Motorola, que nos permite saber o nmero de horas que se tem
de testar sem que nenhuma falha seja encontrada para garantir que o cdigo apenas tem um determinado
nmero de falhas. O modelo tem tambm assumpes, pelo que o valor aconselhado meramente
indicativo, e no propriamente uma certeza.
Exemplo:
Uma falha acabou de ser encontrada, num teste que decorre h 80 horas, sendo j a 10 falha
encontrada. Foi decidido que apenas 1 falha dever ficar por identificar, e pretende-se saber quanto
tempo se ter de testar sem que apaream novas falhas para assumir que apenas existe uma falha por
descobrir.
Exemplo: Poker
Vamos testar no nosso exemplo o mtodo TCartas::Poker, dado que o mtodo mais
complexo, assumindo mos de 7 cartas. O teste deve verificar se os diferentes tipos de mos so
identificados correctamente.
Caso no tenha feito as actividades anteriores, o cdigo de partida o Cartas.zip. Se quiser pode fazer
os testes apenas com esta informao, e continuar a ler apenas quando acabar, ou aceitar algumas
sugestes lendo o prximo pargrafo.
Sugesto: faa um gerador de mos de determinados tipos, e chame o mtodo para verficar se a
resposta correcta. Por exemplo, para gerar uma mo com um par, retire de um baralho um par gerado
www.moodle.univ-ab.pt//print.php?id 43/85
26-01-2010 name
aleatoriamente e adicione-o mo, e de forma a no haver mais pares nem trios, retire as restantes duas
cartas do mesmo nmero do baralho, e retire tambm trs cartas aleatoriamente de cada um dos
restantes nmeros. Para evitar sequncias, retire um dos nmeros 5 ou 6 e o nmero 10 ou V
respectivamente. Baralhe as restantes cartas e junte mo as 5 primeiras. Finalmente, para evitar a cor,
conte quantas cartas tem de cada naipe na mo, e no caso de ter 5 ou mais troque o naipe de uma das
cartas que no fazem parte do par.
Resoluo
O trabalho resume-se a alterar o mtodo TCartasEngine::Run e a criar um mtodo para gerar as mos,
portanto dois mtodos.
No mtodo TCartasEngine::Run, h que apagar tudo e gerar as mos por ordem, verificando se esto
correctas:
void TCartasEngine::Run()
{
Seed();
// processar todos os tipos de mos
for(int i=0;i<10;i++) {
// para cada mo testar o nmero especificado de vezes
for(long j=0;j<States();j++) {
// gerar uma mo
TCartas mao;
GerarMao(mao,i,7);
int resultado=mao.Poker();
if(resultado!=i) {
// erro, a mo gerada no coincide com a calculada
printf("\n%s: #%d (%s)",poker[i],j,poker[resultado]);
mao.Save(stdout);
}
}
}
}
O gerador de mos mais complexo, tem que se ir desenvolvendo. Foi implementada uma filosofia
diferente da sugesto no enunciado, que consiste no seguinte:
www.moodle.univ-ab.pt//print.php?id 44/85
26-01-2010 name
Este mtodo acaba por ter duas zonas, as mos com numeraes idnticas, e as mos com cor e
sequncia. O cdigo torna-se um pouco mais complexo porque tem que se impedir que na gerao de
um par no aparea por engano um trio, ou no aparea cor. O cdigo completo da funo est
comentado de forma a ser melhor interpretado.
for(int j=0;j<i&&j<ncartas;j++)
if(TC_NUMERO(mao.cartas[j])==TC_NUMERO(mao.cartas[i])) {
if( // o estado requerido j foi atingido
www.moodle.univ-ab.pt//print.php?id 45/85
26-01-2010 name
estado==tmao ||
estado>0 && (
// ou quer-se dois pares e estava para vir um trio
tmao==2 && bloquear.Find(j)>=0 ||
// ou quer-se um trio e estava para vir dois pares
(tmao==3 || tmao==7) && bloquear.Find(j)<0 ||
// ou quer-se fullen e estava para vir trs pares
tmao==6 && estado==2 && bloquear.Find(j)<0))
{
mao.cartas.Delete(i--);
} else {
// aceitar esta carta se:
if(estado==0 ||
(tmao==3 || tmao==7) && bloquear.Find(j)>=0 ||
tmao==2 && bloquear.Find(j)<0 ||
tmao==6 && (estado<=1 ||
estado==2 && bloquear.Find(j)>=0 ||
estado==3 && bloquear.Find(j)<0))
{
if(estado==0) estado=1;
else if(estado==1)
estado=(bloquear.Find(j)<0?2:3);
else if(estado==2) estado=6;
else if(estado==3)
estado=(bloquear.Find(j)<0?6:7);
if(i>ncartas-1) {
// arranjar uma carta para trocar
for(int l=0;l<ncartas&&l<i;l++)
if(l!=j && bloquear.Find(l)<0) {
bloquear.Add(j);
bloquear.Add(l);
mao.cartas[l]=mao.cartas[i];
mao.cartas.Delete(i--);
break;
}
} else {
bloquear.Add(i);
bloquear.Add(j);
}
} else {
// no aceitar a carta
mao.cartas.Delete(i--);
}
}
break;
}
}
} else if(tmao==4 || tmao==5 || tmao==8 || tmao==9) {
// sequncia, cor, sequncia + cor, sequncia + cor real
for(int i=0;i<mao.cartas.Count();i++) {
www.moodle.univ-ab.pt//print.php?id 46/85
26-01-2010 name
// coloca as primeiras 5 cartas com o requerido, as outras so sorte
if( // apagar todas as cartas de naipe diferente
i<5 && (tmao==5 || tmao==8 || tmao==9) &&
TC_NAIPE(mao.cartas[i])!=TC_NAIPE(mao.cartas[i-1]) ||
// apagar todas as cartas baixas
i<5 && tmao==9 && TC_NUMERO(mao.cartas[i])<8 ||
// apagar os ases para impedir a sequncia + cor real
tmao==8 && TC_NUMERO(mao.cartas[i])==12 ||
// no deixar sequncia passar a cor em 5 cartas
i==1 && tmao==4 && TC_NAIPE(mao.cartas[0])==TC_NAIPE(mao.cartas[1]) ||
// no deixar cor passar a sequncia em 5 cartas
i==1 && tmao==5 && abs(TC_NUMERO(mao.cartas[0])-
TC_NUMERO(mao.cartas[1]))<=4)
{
mao.cartas.Delete(i--);
} else if(tmao==4 && i>=5) {
// no deixar a sequncia passar a cor
int count=1;
for(int j=0;j<i&&j<ncartas;j++)
if(TC_NAIPE(mao.cartas[i])==TC_NAIPE(mao.cartas[j]))
count++;
if(count>=5) {
mao.cartas.Delete(i--);
continue;
}
} else if(tmao==5 && i>=5) {
// no deixar a cor passar a sequncia
int de;
bool seq=false;
for(de=TC_NUMERO(mao.cartas[i])-4;de<=TC_NUMERO(mao.cartas[i]);de++) {
int j=de;
for(j=de;j<de+5;j++) {
int l;
for(l=0;l<=i;l++)
if(TC_NUMERO(mao.cartas[l])==j)
break;
if(l==i+1) break; // no h este nmero, no h problema
}
if(j==de+5) { // sequncia
mao.cartas.Delete(i--);
seq=true;
break;
}
}
if(seq) continue;
} else if(i<5 && (tmao==4 || tmao==8 || tmao==9))
for(int j=0;j<i;j++)
// apagar todos os nmeros que distam mais de 4 dos anteriores
if(TC_NUMERO(mao.cartas[j])==TC_NUMERO(mao.cartas[i]) ||
abs(TC_NUMERO(mao.cartas[j])-TC_NUMERO(mao.cartas[i]))>4)
www.moodle.univ-ab.pt//print.php?id 47/85
26-01-2010 name
{
mao.cartas.Delete(i--);
break;
}
}
}
if(mao.cartas.Count()>ncartas)
mao.cartas.Count(ncartas);
}
Executar e correr. Verificar que no h mos mal colocadas, mesmo fazendo 1000 testes para cada mo:
set seed 1
set limit states 1000
run
Run end.
Para verificar da necessidade de impedir, por exemplo, a cor na gerao das cartas mltiplas, pode-se
comentar a zona de cdigo correspondente (aps o comentrio impedir cor) e correr novamente:
www.moodle.univ-ab.pt//print.php?id 49/85
26-01-2010 name
par: #954 (cor)[ AR1042 V A ]
2pares: #5 (cor)[ D10932 9 10 ]
2pares: #104 (cor)[ R RV985 8 ]
2pares: #155 (cor)[ 6 V9864 8 ]
2pares: #184 (cor)[ D7432 D7 ]
2pares: #189 (cor)[ D8 D10852 ]
2pares: #199 (cor)[ V8 V10984 ]
2pares: #325 (cor)[ 75 A10975 ]
2pares: #418 (cor)[ D10832 108 ]
2pares: #471 (cor)[ 2 4 109742 ]
2pares: #515 (cor)[ A R ARV42 ]
2pares: #833 (cor)[ 5 AD852 A ]
2pares: #887 (cor)[ V7 V10973 ]
trio: #6 (cor)[ 5 5 AR753 ]
trio: #88 (cor)[ R10962 R R ]
trio: #190 (cor)[ 3 3 109643 ]
trio: #303 (cor)[ AV532 5 5 ]
trio: #339 (cor)[ V V ADV103 ]
trio: #341 (cor)[ 9 9 V9752 ]
trio: #463 (cor)[ A10763 10 10 ]
trio: #527 (cor)[ D D ADV84 ]
trio: #589 (cor)[ DV653 D D ]
trio: #639 (cor)[ RD1073 3 3 ]
trio: #640 (cor)[ R10653 6 6 ]
trio: #724 (cor)[ 5 V10532 5 ]
trio: #927 (cor)[ AR982 R R ]Run end.
Verifica-se a gerao de cor acidentalmente quando se pretendia gerar mos de diversos tipos, pelo
que se confirma que o cdigo para impedir a cor nas mos de numeraes idnticas essencial.
O cdigo no teve nenhum crash, e todas as mos deram o mesmo resultado que a funo geradora,
confirmando assim o bom funcionamento do mtodo TCartas::Poker.
Se fosse necessrio maior grau de certeza, o passo seguinte, para alm de aumentar o nmero de testes,
a reviso do mtodo manualmente. Ter o teste operacional muito til nesta situao porque assim
pode-se nessa fase comentar partes do cdigo que no se compreenda de forma a ver se a ausncia do
cdigo leva a resultados incorrectos.
"Software Engineering, theory and practice", second edition, Prentice Hall, Shari Pfleeger, pg. 331-
362, 371-374, 401-403, 410, 412-414, 417-426
www.moodle.univ-ab.pt//print.php?id 50/85
26-01-2010 name
Um componente bem testado pode ser utilizado com segurana tanto no prprio projecto como ser
reutilizado em projectos posteriores. um componente que ir sobreviver ao tempo. O que o tempo
extra para teste se se ir poupar um tempo indefinido a localizar e corrigir problemas que originem no
componente que ficou por testar?
O EngineTester tem duas funcionalidades principais: efectuar testes empricos em algoritmos e testar
componentes. Podem ser analisados parmetros do algoritmo, comparar vrios algoritmos e um ou mais
conjuntos de ficheiros de dados. Estas duas funcionalidades no so incompatveis. Executar um
algoritmo com diversos valores nos seus parmetros com vista a conhecer quais os valores que o
optimizam, no incompatvel a executar um algoritmo com diversos valores nos seus parmetros com
vista a saber se funciona bem em todos os valores. Depende dos indicadores que se calcular para cada
corrida, podendo at ter-se ambos os objectivos em simultneo: optimizao e teste.
O Visual c++ 2008 Express Edition no tem ferramentas dedicadas a testes de componentes. Pode-se
sempre fazer pequenos programas para testar cada componente, mas isso leva a que o custo dos testes
aumente e que quem testa o componente tenha de construir cdigo para o testar. Na soluo de teste de
componentes com o EngineTester, quem desenvolve um componente cria tambm um engine para correr
sobre o EngineTester. Quem testa o componente no necessita olhar para o cdigo mas pode efectuar
testes de volume com qualquer nmero de parmetros e indicadores de verificao, que se podem incluir
na documentao interna do componente e se podem repetir a qualquer momento sem trabalho extra,
por exemplo aps uma actualizao do componente.
O EngineTester permite encadeamento entre algoritmos, ou seja, o resultado de um algoritmo pode ser
enviado para outro algoritmo. Todos os resultados podem ser exportados em texto, para serem
posteriormente processados, mas pode-se no prprio EngineTester construir anlises grficas a partir
dos resultados, sendo essas anlises reconstruidas cada vez que os testes sejam repetidos. Eventualmente
esta funcionalidade pode ser utilizada para testes de integrao, mas como compreensvel este tipo de
testes mais complexo e depende da aplicao concreta.
Todas as parametrizaes dos testes so armazenadas em ficheiro, de forma aos testes poderem ser
repetidos facilmente. Assim, se se quiser repetir testes j efectuados devido a um melhoramento num dos
algoritmos, ou repetir os testes numa nova mquina, ou simplesmente conferir resultados relatados por
um colega, no necessrio passar pelo processo todo, basta mandar correr o documento previamente
gravado, e todas as chamadas aos algoritmos com as respectivas parametrizaes e ficheiros de dados,
sero executadas novamente. Se os grficos forem feitos no EngineTester, at os prprios relatrios so
reconstruidos sem qualquer esforo.
O EngineTester no fora os algoritmos a serem escritos numa linguagem prpria, nem numa linguagem
especfica, apenas determina que sejam programas de linha de comando e que aceitem uma linguagem de
comunicao de texto fixa, esta sim prpria, de forma a que o EngineTester possa criar um processo e
www.moodle.univ-ab.pt//print.php?id 51/85
26-01-2010 name
comunicar com o algoritmo. O EngineTester est implementado em Windows, pelo que os algoritmos
devem ser compilados para este sistema operativo.
A linguagem de comunicao pode ser utilizada de forma manual por um utilizador sem o EngineTester,
ao mandar correr o executvel correspondente ao algoritmo.
A linguagem de comunicao definida neste documento, sendo ainda fornecida uma implementao em
C++ de forma a que um programador apenas tenha de redefinir uma classe para implementar o
algoritmo, sem ter de se preocupar com a linguagem de comunicao. Assim, um algoritmo j
implementado pode ser facilmente adaptado para poder funcionar no EngineTester.
Algoritmos codificados em interpretadores que no possam criar executveis de linha de comando, como
o caso do VBA do Excel, no podem ser utilizados no EngineTester. Aconselha-se no caso do VBA
do Excel a fazer migrao para o Visual Basic.
No resto da seco est a descrio textual do laboratrio indicado nos vdeos, que pode ler em
alternativa ou em complemento aos vdeos.
Os dados do problema so de natureza flexvel: assim um problema de rotas ter informao da rede de
estradas que se pode utilizar e um problema de afectao ter informao das entidades que se podem
afectar e respectivos custos. Por esse motivo os dados de um problema so guardados num ficheiro, num
formato prprio ao problema em questo e que o algoritmo dever conseguir ler.
De referir que podendo a instncia ser descrita por mais de um formato, poder um dos parmetros do
algoritmo ser a escolha do formato de leitura e/ou escrita da instncia.
www.moodle.univ-ab.pt//print.php?id 52/85
26-01-2010 name
A soluo do problema (que identificada como soluo ou em ingls solution)
Conjunto de indicadores sobre a soluo e a forma como esta foi obtida (que so identificados como
indicadores ou em ingls indicators)
O formato de dados da soluo tambm muito dependente do problema a resolver. A soluo pode
ser gravada em ficheiro. Os indicadores sero tipicamente valores escalares calculados com base na
soluo. Por exemplo, num problema de optimizao de rotas a soluo ser um trajecto, sendo um
indicador possvel o comprimento do trajecto.
Tal como no caso dos parmetros, pode-se definir o nmero de indicadores que se pretender. Existem j
alguns indicadores pr-definidos, nomeadamente:
O valor dos indicadores, tal como o valor utilizado dos parmetros do algoritmo, sero utilizados nas
anlises grficas. H que construir o maior nmero de indicadores possveis, uma vez que atravs deles
que se visualizar os resultados. Seria impossvel ver todas as solues, mas facilmente se pode ver uma
soluo que tenha um determinado indicador muito alto (ou baixo). Convm naturalmente que estes
indicadores sejam to independentes quanto possvel, de forma a apanharem aspectos diferentes da
soluo. A escala a que estes indicadores esto no relevante, uma vez que se pode construir
expresses com base nos indicadores e/ou parmetros, podendo alterar a escala destes.
At agora centrmos a ateno em algoritmos para resoluo de problemas, mas podemos considerar
tambm algoritmos de outros tipos:
www.moodle.univ-ab.pt//print.php?id 53/85
26-01-2010 name
A prpria linguagem, no caso de no ser dado um comando vlido, envia uma descrio dos comandos,
como se pode ver na imagem seguinte.
RUN - o algoritmo dever comear a correr neste momento, com os parmetros de entrada e
instncia que estiver carregada. Dever ser criado uma thread parte para correr o algoritmo, de modo a
que este consiga em simultneo ler comandos, nomeadamente o comando seguinte (STOP)
STOP - paragem forada do algoritmo. Ao receber este comando o algoritmo deve retornar o mais
breve possvel, com a melhor soluo caso j tenha encontrado alguma, caso contrrio sai sem soluo.
Como se poder ver na proposta de cdigo em C++, bastar incluir na condio de paragem dos ciclos
principais o mtodo Stop() para que esta funcionalidade seja implementada.
RESET - limpar todos os parmetros (ficam com valor de omisso), e descarregar a instncia que
eventualmente tenha sido carregada.
SET INSTANCE [instance data] - carregar um ficheiro (instncia), directamente pela entrada de
dados (acaba com um caracter final de ficheiro)
SET FILE [file name] - carregar um ficheiro (instncia), atravs do seu nome (com a directoria
completa).
SET SOLUTION [solution] - alterar a soluo corrente para a fornecida
SET [k] [value] - alterar o valor do parmetro [k] para o valor [value]
SET SEED [value] - alterar o valor da semente aleatria para o valor [value]
SET LIMIT STATES [states] - alterar o limite do nmero de estados permitidos para [states]
SET LIMIT TIME [miliseconds] - alterar o limite de tempo, em milissegundos para [miliseconds]
www.moodle.univ-ab.pt//print.php?id 54/85
26-01-2010 name
SET LIMIT LEVEL [maximal level] - alterar o limite do nmero mximo de nveis para [maximal level]
SET INFORMATION [value] - alterar o nvel de informao para [value]. O algoritmo que define
quantos nveis de informao tem. Quanto maior, mais detalhe o algoritmo reportar, sobre o seu
comportamento (ideal para saber o porqu de um resultado incorrecto).
GET INSTANCE - devolver a instncia para a consola
GET FILE [file name] - gravar a instncia para o ficheiro [file name]
GET SOLUTION - devolver a soluo actual
GET STATES - retornar o nmero de estados analisado
GET TIME - retornar o tempo utilizado em milissegundos
GET LEVEL - retornar o nvel mximo atingido
GET SETTINGS - retornar o nmero de parmetros que o algoritmo tem
GET [k] - retornar o valor actual do parmetro [k]
GET NAME [k] - retornar o nome do parmetro [k]
GET DESCRIPTION [k] - retornar uma descrio do parmetro [k]
GET MINIMAL [k] - retornar o valor mnimo possvel para o parmetro [k]
MAXIMAL [k] - retornar o valor mximo possvel para o parmetro [k]
GET INDICATORS - retornar o nmero de indicadores disponvel
GET INDICATOR [k] - retornar o valor do indicador [k]
GET INDICATOR NAME [k] - retornar o nome do indicador [k]
GET INDICATOR DESCRIPTION [k] - retornar uma descrio do indicador [k]
GET ENGINE NAME - retornar o nome do algoritmo (engine)
GET ENGINE VERSION - retornar a verso do algoritmo
GET ENGINE DATE - retornar a data de compilao do executvel
GET ENGINE AUTHOR - retornar o nome do autor (ou autores)
GET ENGINE CONTACT - retornar um ou mais contactos com o autor
GET ENGINE DESCRIPTION - retornar uma descrio curta do algoritmo
GET LIMIT STATES - retornar o nmero de estados permitidos
GET LIMIT TIME - retornar o tempo em milissegundos permitido
GET LIMIT LEVEL - retornar o nvel mximo permitido
GET INFORMATION - retornar o nvel de informao actual
INFORMATION [value] - retornar uma descrio sobre o nvel de informao [value]. O primeiro
nvel de informao no dever mostrar nada.
A directoria "NewEngine" tem os seguintes ficheiros que podem ser consultados, mas no devem ser
alterados:
So tambm criados os ficheiros que vo ser alterados para conter a implementao do novo algoritmo:
NewEngine.cpp o ficheiro tem a funo main, e o cdigo da linguagem de comunicao. Aqui h que
www.moodle.univ-ab.pt//print.php?id 55/85
26-01-2010 name
modificar apenas o nome da subclasse com o novo algoritmo
TNewEngine.cpp TNewEngine.h com a implementao e declarao do novo algoritmo numa
subclasse de TEngine
Para iniciar um novo algoritmo tem que alterar o nome "NewEngine" pelo nome do seu algoritmo, tanto
no nome dos ficheiros como tambm nas referncias internas dentro dos ficheiros "NewEngine.cpp",
"TNewEngine.cpp" e "TNewEngine.h". De seguida basta implementar o algoritmo editando apenas os
novos ficheiros "TNewEngine.cpp" e "TNewEngine.h".
Para compilar este cdigo o compilador tem de ser posto em modo de multi-thread. O presente cdigo
foi testado no Visual Studio 6.0, e de omisso no est neste modo. Se tem dvidas que o seu
compilador tenha um modo multi-thread, compile os ficheiros antes de os alterar, para ver se consegue.
Caso no consiga compilar, o problema ser na chamada a "_beginthread" e "_endthread". Notar que
uma thread diferente de um processo. Esta implementao necessita de uma thread para a leitura de
dados, e cria outra thread para o algoritmo correr. No caso do Visual Studio 2005, no preciso fazer
nada. Na figura est o resultado aps construir um projecto "Win32 Console Application", adicionar os
ficheiros e substituir o "NewEngine" por "Partition". Est pronto a correr.
Pode fazer uma verso que no suporte multi-thread substituindo o _beginthread pela chamada prpria
funo e comentando o _endthread, mas tal pode ter efeitos indesejveis. O EngineTester assume que a
comunicao entre a aplicao EngineTester e todos os algoritmos (engines) abertos, deve estar sempre
activa, e no haver momentos em que a comunicao ignorada porque est um algoritmo a correr.
Aps a compilao correcta tem um conjunto de tarefas a fazer nos ficheiros TNewEngine.cpp e
TNewEngine.h:
www.moodle.univ-ab.pt//print.php?id 56/85
26-01-2010 name
criar a estrutura de dados para guardar uma soluo
verificar que construtor e destrutor esto de acordo com a estrutura criada
implementar Load/Save da instncia
implementar LoadSolution/SaveSolution
implementar em Reset: identificao de todos os parmetros (ver cdigo comentado); identificao de
todos os indicadores (ver cdigo comentado); adicionar modos de informao, adicionando valores para
info_description (ver declarao de TEngine).
implementar em Run o algoritmo, e adicionar parmetros se necessrio (nesta fase j se pode utilizar o
EngineTester para testes). Nos ciclos mais importantes, incluir no critrio de paragem a chamada ao
mtodo Stop() (de TEngine), para que seja possvel parar o algoritmo no caso do utilizador ter mandado
parar, ou o tempo estar esgotado (ou qualquer outro critrio de paragem). H que actualizar tambm o
nmero de estados e nvel mais alto (value_states, value_level de TEngine). Por exemplo, o loop base de
um algoritmo pode ser: while(!Stop()) { value_states++; /*processar*/ }
implementar indicadores (mtodo Indicator)
optimizaes, testes de fiabilidade
A partir dos ficheiros da directoria "NewEngine", criar um algoritmo para o problema da partio
(partition). Este problema consiste em tendo um conjunto de nmeros inteiros, saber se se podem dividir
em dois grupos cuja soma seja exactamente igual. O algoritmo a implementar determinstico e
exaustivo, percorre todas as parties possveis (algumas indirectamente) e retorna assim que encontrar
uma vivel.
www.moodle.univ-ab.pt//print.php?id 58/85
26-01-2010 name
Falta agora implementar o algoritmo. Primeiro h que salientar alguns pontos que nos permitem aliviar
algum tempo de processamento:
o algoritmo apenas deve tentar encontrar parties caso a soma total dos nmeros seja par. Caso a
soma seja impar impossvel obter uma partio uma vez que os nmeros so todos inteiros, e nessa
situao o engine pode retornar logo impossvel
processar os elementos 1 a 1, e ter sempre o valor da soma total a dividir por dois (para no
considerar parties com valores superiores a esse valor)
ter o valor do somatrio dos elementos na partio a considerar
considerar em cada passo um elemento i: se somando o valor de i com os elementos j na partio for
igual ao total/2, retornar sucesso; caso seja superior, tentar fazer parties apartir de i+1 sem entrar com
i; caso seja inferior, se no houver mais elementos (i o ltimo), retornar insucesso, caso contrrio tentar
apartir de i+1 entrando em linha de conta com i, e caso no d tentar sem entrar com i.
Se for suficiente a ideia, ou se conseguir implementar um algoritmo seu, fora. Caso contrrio pode fazer
os seguintes passos, ao estilo de laboratrio:
criar mtodo partition com os argumentos o valor i, subtotal e total2, retornando inteiro
no mtodo Run, calcular a soma total
caso seja divisivel por 2, chamar partition, caso contrrio 0, e guardar o resultado na varivel resultado
www.moodle.univ-ab.pt//print.php?id 59/85
26-01-2010 name
no mtodo partition, verificar se subtotal com i fica igual a total2, retornar sucesso nesse caso.
verificar se i==0, nesse caso no h hiptese, retornar insucesso
verificar se sem este elemento existe uma partio, e retornar sucesso se existir
verificar se o valor no ultrapassado se se contar com este elemento, e retornar a chamada
partio
na ltima linha inserir return 0; porque nesse caso no possvel
Est feito, agora h que fazer um pequeno teste antes de o testar no EngineTester. Compilar e correr,
inserir uma instncia divisivel e outra divisivel e mand-lo correr.
www.moodle.univ-ab.pt//print.php?id 60/85
26-01-2010 name
Estes pequenos testes no garantem no entanto que o algoritmo esteja a funcionar correctamente, nem
do ideia da sua complexidade algoritmica. So necessrios testes mais extensos, algo que o
EngineTester facilita e sem este provavelmente o investigador j fatigado nesta altura, acabaria por dar o
trabalho como concluido. Neste caso a complexidade algoritmica possvel de calcular, de O(2^n)
para o pior caso, mas mesmo neste problema no h ideia do tempo mdio para um conjunto por
exemplo de 1000 inteiros gerados aleatoriamente entre 1 e 1000.
Cada conjunto tem uma "combobox", em que est seleccionado o elemento desse conjunto activo, e
possui os botes Add/Delete para adicionar e remover um elemento a cada conjunto respectivamente. O
nome do elemento e respectivas configuraes, so editveis em dialogs especficas.
www.moodle.univ-ab.pt//print.php?id 61/85
26-01-2010 name
O boto "?" junto de cada conjunto, tal como outros botes com "?" espalhados um pouco por todo o
lado, d uma informao breve do que representa.
Para abrir uma dialog de edio de um dos elementos dos quatro conjuntos, basta que seleccione o
elemento. Faa isso para as instncias, e de seguida minimize a dialog base.
Alternativamente a se dar os ficheiros, pode-se fornecer um engine que gera as instncias, sendo nesse
caso passado o resultado desse engine para o engine que necessitar deste conjunto de instncias.
www.moodle.univ-ab.pt//print.php?id 62/85
26-01-2010 name
Vamos continuar com o exemplo dado, Partition. H que construir um conjunto de instncias de teste
para o partition. O formato simples, um conjunto de nmeros acabando no 0, com os nmeros postos
um por linha:
conveniente que todo o conjunto esteja na mesma directoria. No caso de se levar todo o teste para
outro computador, incluindo as instncias, as directorias podem ser diferentes, e nesse caso o
EngineTester pergunta a nova directoria. Para as restantes instncias no conjunto, assume que a
directoria trocada se mantm, mas se no achar o ficheiro pergunta por nova directoria. De forma a
poupar trabalho de indicar novas directorias, aconselha-se a que um conjunto de instncias esteja na
mesma directoria.
www.moodle.univ-ab.pt//print.php?id 63/85
26-01-2010 name
Na imagem anterior pode-se ver o ficheiro i05.txt seleccionado, sendo o seu conteudo mostrado na zona
da direita.
Convem que as instncias de teste sejam diferentes, de forma a poder ver como o algoritmo se comporta
nas diferentes situaes. No Partition, pode-se suspeitar ser relevante ao desempenho do algoritmo o
nmero de elementos, e o nmero de dgitos mdio por elemento. Naturalmente que as instncias cuja
soma dos elementos no seja par, de pouco interesse, j que o algoritmo detecta que impossvel e
rejeita de imediacto.
O leitor facilmente concordar que um conjunto construido manualmente dificilmente pode ter instncias
de acordo com o ideal especificado no pargrafo anterior. Primeiro devido a ser trabalhoso construir
instncias grandes, e segundo porque para tirar concluses so necessrias muitas instncias, e no
apenas uma dzia.
Apesar destas questes, vamos para j manter o exemplo assim, de forma a este ficar simples, e passar
configurao do nosso engine.
Seleccione na toolbar direita, o icon que se parece com um motor. Esta um forma rpida de trocar de
dialog, passando a editar o engine de seleccionado na dialog base.
www.moodle.univ-ab.pt//print.php?id 64/85
26-01-2010 name
Para configurar um engine, h que seleccionar o executavel de linha de comando que implementa o
algoritmo. Carregue no boto "Browse" e seleccione o executvel Partition.exe construido na seco
anterior. Na zona "Engine executable" dever aparecer o executvel. Se necessrio, pode criar mais que
um engine com o mesmo executvel, desde que d nomes diferentes a cada engine no documento
EngineTester.
A lista do canto superior-direito, tem as instncias que possui juntamente com o nmero de ficheiros. A
lista permite multipla-seleco, de forma a que se seleccione os conjuntos de instncias a enviar para este
engine. A lista de conjuntos de parmetros, no canto inferior-direito, segue a mesma filosofia.
O campo dos indicadores permite seleccionar um subconjunto dos indicadores possveis. Apenas os
seleccionados aqui sero pedidos ao engine, aps o fim do processamento, e estaro disponveis para
construo das variveis de sada. Desta forma, caso o engine tenha por exemplo 20 indicadores, e
apenas sejam precisos 3, evita-se ter de calcular 20 indicadores para apenas utilizar 3.
[ind]:=[ind1]|[ind1] [ind]
[ind1]:==[nmero]|[nmero]-[nmero]|[nmero]-[nmero]:[nmero]
Um ou mais [ind1] podem ser inseridos, desde que separados por um espao. Um [ind1] ou um
www.moodle.univ-ab.pt//print.php?id 65/85
26-01-2010 name
nmero, ou do tipo [a]-[b] e nesse caso so todos os nmeros entre [a] e [b] inclusiv, ou ento do
tipo [a]-[b]:[c], e nesse caso so todos os nmeros de [a] a [b] de [c] em [c]. Por exemplo: "1 6-9 20-
80:15" corresponde aos nmeros 1 6 7 8 9 20 35 50 65 80. Como apenas temos um s indicador,
implementado no Partition, deixa-se este campo com o valor de omisso "1".
As variveis de sada podem ser construdas utilizando as funes matemticas comuns (sin, cos, sqrt,
pow,...) e com base em diversas variveis:
Como temos apenas um indicador, para j podemos colocar as seguintes variveis: VT; I1; NI. Ateno
que para adicionar uma nova varivel, a lista de variveis no pode estar seleccionada, caso contrrio
editada a varivel seleccionada e no criada nova varivel.
No campo de formatao de ficheiros (File format), coloca-se o formato do nome dos ficheiros para
serem gravados com novo nome, aps serem processados. Caso o campo esteja em branco, os ficheiros
no so gravados:
prefixo*prefixo_apagado*sufixo_apagado*sufixo
utilizar #i, #s, #e, para substituir pelo nmero da instncia, nmero do parmetro, e nmero do engine
respectivamente
Os ficheiros criados para teste ficaram com os nomes: "i01.txt"; ...; "i12.txt". Para os modificar de forma
a ficarem "partition01.txt"; ... ;"partition12.txt", bastaria inserir a formatao: "partition*i**", ou seja,
apagar o i e adicionar o prefixo "partition".
Se um ou mais ficheiros tiverem sido apagados, o nmero do ficheiro deixa de ter significado. Nesse caso
pode-se ignorar o nmero: "partition#i.txt". Esta formatao ignora o nome original da instncia, e
distingue as instncias apenas no nmero de instncia.
Cada engine pode ter um conjunto de parmetros, para adicionar novo parmetro basta escrever o
nmero do parmetro e os valores, e nova linha adicionada. Os parmetros do algoritmo que no
ficarem especificados, ficam com o valor de omisso. No nosso exemplo do Partition, no temos de
momento nenhum parmetro.
Quatro parmetros so fixos: semente do gerador aleatrio (Seed Value), de forma a que em algoritmos
no determinsticos o resultado possa ser repetido; nmero mximo de estados analisados (States Limit);
tempo mximo em milisegundos (Time Limit), mas apenas nesse instante ser enviada ordem para sada,
e no caso do algoritmo no chamar com frequncia o mtodo Stop (ver seco anterior), este pode
ultrapassar este valor; nvel mximo a explorar (Level Limit), sendo o nvel um conceito mais aplicvel a
algoritmos de procura em rvore, mas pode ser livremente utilizado. Voltaremos com um exemplo a esta
dialog, quando se adicionar parmetros ao Partition.
www.moodle.univ-ab.pt//print.php?id 66/85
26-01-2010 name
O nmero de elementos deste conjunto pode crescer rapidamente. Suponhamos que temos 4
parmetros, e que em cada um queremos testar 10 valores diferentes. Est-se nesta situao a definir
10^4 hipteses, que so 10.000 corridas. Este valor conjugado com o nmero de instncias, por
exemplo 100, daria um total de 1.000.000 de corridas.
Aconselha-se a fazer testes pequenos primeiro, antes dos grandes testes. Nos testes pequenos detecta-
se rapidamente pequenos problemas com o algoritmo, ou com os resultados, que podem eventualmente
levar escolha de outros parmetros para o grande teste.
Antes de criar um grfico, mande o algoritmo correr, atravs do menu Tester|Start ou do boto "Start".
Ir abrir uma outra janela que ir comunicar com o engine. Esta janela tambm abriria no caso de na
dialog Engine carregar no boto "Open".
www.moodle.univ-ab.pt//print.php?id 67/85
26-01-2010 name
A janela apresenta informao do engine no canto inferior-esquerdo, permite enviar qualquer comando
no canto superior-esquerdo. No resto da zona esquerda tem uma "combobox" com os nveis de
informao possveis, outra "combobox" com os parmetros possveis e respectivo valor, uma terceira
"combobox" com os indicadores. Seleccione o valor "Resultado" nos indicadores, e ver informao
descriptiva, que voc prprio escreveu quando o construiu. De resto esto os limites do nmero de
estados, tempo em milisegundos e nvel mximo.
Caso no esteja um teste a correr, pode utilizar esta dialog para comunicar com um engine, para saber
que parmetros e indicadores tem implementados, ou para seleccionar uma determinada instncia que d
um resultado incompreensvel, seleccionando um nvel de informao adequado para se compreender o
porqu do resultado.
J tendo corrido, faa Tester|Export|Results e grave num ficheiro. Veja o resultado. Dever ter 12 linhas,
caso no tenha abra a dialog Engine e seleccione o conjunto de instncias. A informao aparece em
forma tabelar, com o nmero de Engine, nmero de instncia e nmero de parmetro (neste caso no h
parmetros), seguidos das variveis de sada (VT, I1, NI).
Crie agora uma vista grfica atravs da dialog base, e responda "no" a todas as perguntas. Essas
perguntas so relativas a cada elemento escolhido (do conjunto dos engines, das instncias e dos
parmetros), de forma a fazer um grfico entrando em linha de conta apenas com resultados desse
elemento. Abra agora a vista grfica criada.
www.moodle.univ-ab.pt//print.php?id 68/85
26-01-2010 name
O grfico partida mostra os valores seleccionados em srie. Tendo 3 variveis de sada, ficamos com 3
sries com tantos elementos quantas as corridas, neste caso 12. Mesmo neste grfico podemos ver que a
instncia 10 houve um tempo muito elevado de 350 milisegundos.
Dado que a escala igual para todas as sries, a segunda srie com o resultado 0 ou 1 no se v. Pode-
se portanto dividir o tempo por 1000 para passar a segundos, e o nmero da instncia por 10 (na dialog
Engine). Antes de mandar correr novamente (pode-se manter a vista grfica sempre aberta), carregue no
boto "Clear results", caso contrrio os resultados so adicionados aos anteriores.
Neste caso, abrindo a dialog do conjunto de instncias, foi possvel ver a instncia que estava a consumir
mais tempo, e esta tinha 43 elementos.
A vista grfica, para alm de sries, pode visualizar basicamente histogramas e scatterplots. Com o menu
de contexto do DataView, possvel editar a vista grfica, sendo essas modificaes gravadas no
documento EngineTester. Vamos mostrar algumas dessas funcionalidades com o evoluir da anlise ao
nosso algoritmo Partition.
Abra o projecto do Partition e no mtodo Reset adicione um novo indicador "N" com descrio
"Nmero de elementos da instncia.". No mtodo Indicator, crie um novo "case" para o indicador e
retorne o nmero de elementos de instance: case 1: return instance.Count(); break;
Compile, mas antes feche o EngineTester gravando o ficheiro, uma vez que pode ter o executvel aberto,
e volte a abrir o EngineTester novamente aps ter o ficheiro compilado.
www.moodle.univ-ab.pt//print.php?id 69/85
26-01-2010 name
Para verificar que o novo indicador est funcional, abra a dialog de engine, e carregue no boto "Open".
Ir abrir a dialog de comunicao com o engine e um processo onde estar o executvel a correr. Se
quiser pode abrir o Task Manager e ver o novo processo. Seleccione o valor "N" na "combobox" com
os indicadores para ver a sua descrio.
Na dialog de Engine, coloque tambm o indicador 2, ficando portanto "1 2". Nas variveis de sada
coloque o indicador I2, de forma a ter-se acesso a este valor nas anlises. Mande correr e reparar que
no h nada de novo na vista grfica. Abra a dialog base, e apague a vista grfica refazendo-a novamente
da mesma forma, j que adicionou uma varivel de sada. Ver agora a nova varivel.
www.moodle.univ-ab.pt//print.php?id 70/85
26-01-2010 name
Agora h que construir um gerador. Comece por criar um engine apartir de NewEngine, tal como foi
feito para criar Partition, e d o nome de GenPartition. Como a estrutura de dados ser igual do
Partition, crie tambm a varivel instance.
O gerador precisa de um gerador de nmeros aleatrio. fornecido a classe TRand para gerar valores,
no sendo necessrio instanciar a classe j que os seus membros so estticos. A semente logo
inicializada no TEngine, pelo que no h que preocupar com o assunto, apenas chamar o mtodo Seed();
no incio do mtodo Run, e chamar o mtodo TRand::rand() sempre que for preciso um novo valor
aleatrio.
O gerador necessita de parmetros de entrada, como o nmero de elementos a gerar (N). Cada nmero
pode ser gerado de acordo com uma distribuio uniforme, de 1 a M, mas obviamente h instncias que
podem ter os nmeros distribuidos no uniformemente mas sim de forma logaritmica ou outra situao.
Abstraindo desse facto, pode-se ento criar um parmetro (M) com o maior nmero possvel.
Crie os dois parmetros acima, com valores de omisso razoveis (10 e 1000 respectivamente). No
mtodo Run faa a gerao dos valores: Reset(); for(long k=0;k<value[0];k++)
instance.Add(TRand::rand()%value[1]+1); instance.Add(0);
Compile e corra para efectuar o primeiro teste: no engine, faa "run" e "get instance" para ver a instncia
gerada. Altere o valor dos settings para verificar que os parmetros influnciam a instncia gerada. Se
alterar o valor do Seed antes de mandar correr, verifica que a mesma instncia gerada.
Aparentemente tudo em condies para testar o desempenho do algoritmo Partition, mas na verdade no
possvel verificar o resultado sucesso/insucesso, devido a no haver essa informao.
www.moodle.univ-ab.pt//print.php?id 71/85
26-01-2010 name
tornando a instncia mais simples de resolver. As instncias simples inviesam a anlise de desempenho
nas instncias dificeis.
Para evitar gerar instncias demasiado simples, resolveu-se gerar instncias sempre possveis, porque
aparentemente no haver muitas destas instncias demasiado simples, a no ser que um s nmero seja
igual soma dos restantes. Por isso a soluo dever ter uma seleco de aproximadamente metade dos
elementos de forma a que a complexidade seja mxima.
Resta saber como transformar o gerador puro anterior num gerador que garanta que existe uma soluo?
Normalmente bastar construir uma soluo. Neste caso basta ter dois registos de somatrios parciais, a
cada nmero que gerado somado num dos registos (o que tiver valor inferior), sendo o ltimo nmero
a diferena de valor entre os dois registos. Assim garante-se que h uma diviso, mas para que o
algoritmo que resolver no possa fazer uso do algoritmo de gerao para resolver o problema, h que
baralhar (ou ordenar) a ordem dos nmeros gerados antes de devolver a instncia
(instance.RandomOrder();).
Compile e corra, fazendo novamente os mesmos testes. O gerador est pronto para ser utilizado.
Edite o conjunto de parmetros criado de omisso (ou crie um novo), e d o nome de "GenPartition".
Para o valor do primeiro parmetro (N) colocar "10-100:10", e para o segundo parmetro colocar "10
100 1000". De forma a ter mais do que uma instncia para um conjunto de parmetros, colocar na
semente (Seed Value) 5 valores "1-5".
www.moodle.univ-ab.pt//print.php?id 72/85
26-01-2010 name
Abra agora o engine GenPartition e seleccione o conjunto de parmetros criado. Coloque no formato
para gravao a string "g#s.txt" de forma a gravar as instncias.
Mande correr, e os ficheiros devem ficar gravados. Mova os ficheiros criados para a directoria de
instncias do Partition e crie agora um novo conjunto de instncias, e adicione os ficheiros gravados para
www.moodle.univ-ab.pt//print.php?id 73/85
26-01-2010 name
os ver.
Notar que se utilizou o TRand::rand() para gerar nmeros aleatrios, a instncia g100.txt visualizada na
imagem anterior, dever coincidir com a sua, dado que a semente utilizada na sequncia aleatria ter
sido a mesma. Verifique em qualquer das formas se tem uma chamada no mtodo Run() ao mtodo
Reset(), e no caso positivo apague-a, caso contrrio os valores dos settings alterados so ignorados e
substituidos pelos valores de omisso. Pode confirmar que est tudo em condies relativamente
instncia g0.txt que deve ter os valores: 5 6 8 9 9 1 1 5 9 1 0.
Pode agora facilmente repetir os testes do Partition utilizando apenas as instncias geradas, bastando
para isso trocar a seleco do conjunto de instncia a utilizar, na dialog de Engine do Partition. Nesse
caso, no interessa o resultado do gerador, pelo que h que limpar as variveis de sada, de forma a que
este no corra. Antes de mandar correr, abra a vista grfica e limpe os resultados entretanto
armazenados, de forma a ir vendo os resultados a sarem medida que so processados.
Enquanto corre, pode abrir o Task Manager para ver a ocupao do CPU, e ir monitorizando os
resultados. Haver 4 variveis, a primeira o tempo, a segunda o resultado (que dever ser sempre 1,
devido a que todas as instncias so possveis), a terceira o nmero de instncia e a quarta o nmero de
elementos.
Ser interessante ver o tempo vs tamanho, de forma a verificar se h dependncia. Para isso h que
primeiramente apagar do relatrio as variveis que no se querem (a 1 e 2, ficando a 0 e 4). As variveis
continuam disponveis para outros relatrios. Boto da direita, seguido de Edit/Delete/Columns... e
escrever "1 2". Apartir desse momento apenas se v informao de duas variveis.
Agora h que passar a vista para tipo Scatterplot: boto da direita, seguido de Settings/Type/Scatterplot.
Falta agora dar nomes certos, atravs tambm do boto da direita, seguido de Edit/Labels/Axis e
Edit/Labels/Caption. Estas alteraes ficam guardadas no documento.
www.moodle.univ-ab.pt//print.php?id 74/85
26-01-2010 name
Verifica-se que o algoritmo, nas instncias de 60 elementos j leva muito tempo. Como o nosso engine
no tem verificaes para abortar o algoritmo, este no pra seno quando acabar, retornando sucesso
ou insucesso.
Aps compilar, volte a abrir o EngineTester no mesmo documento, e crie um novo conjunto de
parmetros Partition, e coloque no limite de tempo 10000 milisegundos, e no nmero de estados
100000000. Se o nmero de estados permitido for inferior, provvel que o algoritmo pre no devido
ao limite de tempo mas sim ao limite de estados. Corra novamente, mas antes no se esquea de no
Engine Partition seleccionar o respectivo conjunto de parmetros, e limpar os resultados anteriores.
www.moodle.univ-ab.pt//print.php?id 75/85
26-01-2010 name
Se correr de imediacto, ver que o limite de tempo ignorado, acabando todas as instncias
practicamente instantaneamente. Tal deve-se ao facto de no mtodo "Load" haver uma chamada ao
mtodo "Reset", sendo nesse mtodo reposto o tempo limite de omisso (1 segundo) e limite de nmero
de estados (1000 o que pouco neste caso). H que trocar a chamada a "Reset" no mtodo "Load"
pelos comandos: instance.Count(0); resultado=0;
www.moodle.univ-ab.pt//print.php?id 76/85
26-01-2010 name
Correndo em outro computador, o grfico ser idntico, apenas os pontos podem ser ligeiramente
deslocados para a esquerda ou direita, conforme o computador mais rpido ou mais lento, mas devido
s caractersticas exponenciais do algoritmo, estas diferenas no fariam grande diferena. Caso o limite
seja o nmero de estados, no teria havido diferena nenhuma.
O EngineTester permite no entanto aliviar este processo, no sendo necessrio que as instncias sejam
gravadas. sempre conveniente gravar e ver as instncias quando se est a desenvolver o gerador, mas
aps ter a certeza que este funciona bem, pode-se utiliz-lo apenas para gerar instncias de determinado
tipo, sendo as instncias utilizadas directamente no gerador.
No engine Partition, seleccione o novo conjunto de instncias GenPartition2, limpe os resultados e mande
correr. Os resultados so refeitos automaticamente. A vista grfica volta a dar informaes preciosas
sobre a fase de transio entre instncias dificeis e simples.
Ateno que os resultados podem ser mal lidos. Com 50 elementos no grfico no aparece nenhuma
instncia simples, ou seja, que se resolva em menos de 1 segundo. Isso no quer dizer que no existam
instncias simples, apenas que o nosso gerador no as gera, uma vez que tivemos o cuidado de manter
equilibrado o nmero de elementos em cada seleco. Caso tivesse sido utilizada a primeira verso do
gerador, teriamos muitas mais instncias simples, nubelando os grficos.
www.moodle.univ-ab.pt//print.php?id 77/85
26-01-2010 name
Este algoritmo fica validado em termos prticos para resolver qualquer instncia at 40 elementos. Este
tipo de informao no nos d uma anlise puramente analtica, que resultaria a informao de que o
algoritmo tem complexidade O(2^n).
Suponhamos agora que desconfiava que o algoritmo iria correr mais rpido se escolher primeiro os
elementos maiores e s depois os menores. H hiptese de implementar isso facilmente, basta que a
instncia seja ordenada antes de arrancar com o algoritmo. Tem tambm que comparar essa opo com
a actual, uma vez que a alterao requer mais tempo a ordenar, o que poderia no compensar.
No Partition h que adicionar um parmetro (no mtodo "Reset"), que de omisso est a 0 e se for 1 a
instncia ordenada: value.Add(0); name.Add("Ordenar"); description.Add("0 - no ordenar; 1 -
ordenar"); min.Add(0); max.Add(1);
No mtodo "Run", antes de chamar partition, mandar remover os zeros e ordenar. No esquecer de
adicionar o zero no fim, para ficar uma instncia vlida, no caso de se gravar. O ltimo comando passa a
ser antecedido por: if(value[0]==1) { if(total%2==0) { instance.Remove(0); instance.Sort();
resultado=partition(instance.Count()-1,0,total/2); instance.Add(0); } else resultado=0; } else [ltimo
comando]
www.moodle.univ-ab.pt//print.php?id 78/85
26-01-2010 name
Naturalmente o nmero de corridas a efectuar duplicam, passa agora a 480 corridas, mas permite fazer a
comparao dos desempenhos com e sem a ordenao. Pode mandar correr aps limpar os resultados
actuais, que levar tempo, e os grficos fazem-se com as corridas em curso.
Pretende-se agora uma vista tipo a anterior, mas apenas para o caso do conjunto de parmetros ser
Partition. Para tal h que na dialog de base selecionar o conjunto de parmetros Partition, e criar uma
vista, respondendo sim pergunta de ser restrito ao conjunto de parmetros Partition. Apague desde j
todas as colunas excepto o tempo "1-3".
Seleccione agora o conjunto de parmetros Partition2 e crie uma vista, respondendo sim no s
pergunta de ser restrito ao conjunto de parmetros Partition2, como tambm a fundir com a vista
anterior. Apague tambm aqui as colunas "1-3", ficando apenas com duas linhas, com a informao do
tempo gasto em ambas as opes.
Agora pode construir um scatterplot e comparar directamente os tempos gastos num caso e no outro.
Neste caso pode-se ver que o desempenho do algoritmo piora claramente. Se houver dvidas de qual
o eixo com as novas opes, bastar abrir a vista do tamanho vs tempo e verifica-se que os resultados
pioraram na globalidade.
www.moodle.univ-ab.pt//print.php?id 79/85
26-01-2010 name
Pode-se parar a corrida, j que agora suspeita-se que invertendo a ideia d bom resultado, ou seja,
processar primeiro os nmeros mais baixos e depois os mais altos. Embora intuitivamente a primeira ideia
faa mais sentido, no campo dos testes h que olhar para os resultados.
Dado que a inverso no est implementada, h que incluir aps a ordenao (comando instance.Sort();)
cdigo para inverter a instncia: for(int i=0,j;i<instance.Count()/2;i++) { j=instance[i];
instance[i]=instance[instance.Count()-i-1]; instance[instance.Count()-i-1]=j; }
Ao mandar correr, observa-se que at a actual dimenso das instncias, de 30 a 60 elementos, no est
convenientemente dimensionada para o mtodo ordenar, dado que todas as instncias so resolvidas,
levando a mais difcil pouco mais de 3 segundos. Haver agora que passar este parmetro a ter um valor
fixo, deixando de ser parmetro, ou pelo menos o valor de omisso passar a ser 1, em vez de 0.
www.moodle.univ-ab.pt//print.php?id 80/85
26-01-2010 name
O processo repete-se, voltando a identificar novo teto do algoritmo, e volta-se a testar novas ideias. Sem
EngineTester, quanto tempo levaria a montar as corridas, fazer os grficos e a reagir? Provavelmente
demasiado tempo, e ideias para melhoramento tivessem ficado por testar dado o custo de fazer
novamente todas as anlises.
Muitas vezes faz-se tantas anlises que se perde a origem de algumas anlises. No EngineTester poupa-
se tambm no facto de se conseguir explicar como se fez cada anlise, dado que o documento
EngineTester tem toda a informao sobre como feita cada anlise, e est sempre pronto a refaz-la.
Paramos por aqui, o leitor pode completar a anlise de forma a concluir em termos prticos at que
instncias pode ser utilizado este algoritmo com sucesso.
www.moodle.univ-ab.pt//print.php?id 81/85
26-01-2010 name
7 - Instalao e Manuteno
Aps o sistema construdo e devidamente testado, resta colocar o sistema em utilizao. Para tal h que
formar os utilizadores do sistema e construir documentao necessria para que o sistema possa ser
utilizado com sucesso.
7.1 Instalao
A instalao no deve ser efectuada sem uma documentao. O sistema pode ser facilmente instalado
pela equipa de desenvolvimento que acabou de desenvolver o software, no necessita naturalmente
nenhuma documentao. O problema quando o hardware necessitar de ser actualizado, ou o sistema
operativo, e as pessoas envolvidas no desenvolvimento da aplicao esto em outros projectos ou em
outra empresa.
Para alm dos utilizadores do sistema, h tambm os operadores ou administradores, que efectuam
operaes de administrao do sistema. A formao dos administradores deve ser direccionada ao
funcionamento interno do sistema, e s operaes que tm de ser efectuadas regularmente para que este
funcione correctamente. Algumas dessas operaes podem ser: dar acessos a utilizadores; fazer backups
do sistema; instalar novos mdulos. Os administradores tm tambm de dar apoio aos utilizadores do
sistema, de modo que tm tambm de ter a formao dos utilizadores.
Poder haver utilizadores que utilizam o sistema apenas esporadicamente, ou apenas para consulta,
devendo haver uma formao mais leve para esses utilizadores.
A formao deve ter em ateno os conhecimentos prvios dos utilizadores. Por exemplo, caso existam
utilizadores no familiarizados com computadores, necessrio um curso de iniciao a esses
utilizadores. A formao deve ser dividida em unidades pequenas.
A formao no deve ser apenas numa sesso na entrega do sistema. Deve estar disponvel sempre que
o utilizador necessitar, por diferentes formas: manual impresso; manual online; sesses de formao;
utilizadores experientes.
Os manuais impressos tm de ser completos e portanto acabam por serem volumosos. Normalmente so
considerados pelos utilizadores como no essenciais, muitas vezes porque pretendem fazer apenas
www.moodle.univ-ab.pt//print.php?id 82/85
26-01-2010 name
operaes simples e no sabem como encontrar rapidamente a informao que necessitam, e no
querem perder muito tempo a ler o manual. Os manuais devem ser consultados quando h dvidas, ou
antes de uma operao pouco frequente, e devem ter hiptese de serem utilizados tanto em modo de
consulta rpida (manual de referncia), como em modo de formao (manual tutorial).
Um esquema geral com as principais funcionalidades do sistema e de como se relacionam entre si;
Uma descrio dos dados necessrios a cada funcionalidade do sistema;
Uma descrio dos dados produzidos por cada funcionalidde do sistema;
Uma descrio de caractersticas especiais de cada funcionalidade do sistema.
O manual online, juntamente com nomes de menus e icons sugestivos, e toda a interface do sistema no
geral, so outra forma de formao, normalmente a mais utilizada. O manual online pode ser uma cpia
do manual impresso ou uma verso reduzida deste, mas dever ter hiptese de ser acedido de diversos
locais com ligaes directas pgina do manual onde descrito o comando que poderia ser executado.
No manual impresso as referncias a outras zonas do manual so feitas por indicao da pgina, no
manual online estas devem ser atravs de hiper-texto, de forma a obter-se a pgina distncia de um
clique.
7.3 Manuteno
Aps o sistema estar em funcionamento h sempre operaes de desenvolvimento que se necessita de
fazer, para no s corrigir falhas que se encontrem entretanto, como para desenvolver novos mdulos
que venham a revelar-se importantes. A manuteno a actividade de correco ou desenvolvimento
feita aps o sistema estar em funcionamento. Tudo o que for sendo feito deve ficar registado de forma a
poder ser repetido quando se fizer actualizaes ao sistema.
Com o sistema em funcionamento, ao longo dos tempos o custo de manuteno pode ir aumentando. H
que decidir o ponto em que se toma a deciso de substituir o sistema actual por um novo. Para tal h que
analisar: custo de manuteno; fiabilidade do sistema; capacidade de evoluo do sistema; alternativas no
mercado.
Naturalmente que sistemas de grande dimenso e essenciais ao negcio da empresa, requerem recursos
humanos atribudos permanentemente manuteno.
Estas grandezas podem ser medidas, desde que para tal se recolha a informao necessria:
Com base nestes valores mdios pode-se calcular rcios para que o valor 1 seja o ideal e o valor 0
indesejado, para as trs grandezas fiabilidade, disponibilidade e manutenabilidade:
fiabilidade;
disponibilidade;
manutenabilidade.
H tambm indicadores de complexidade do cdigo a manter, que se podem calcular de forma a ter uma
ideia dos custos de manuteno futuros. Utiliza-se normalmente o nmero ciclomtico para complexidade
de cdigo. H tambm a possibilidade de calcular indicadores sobre documentao, de forma a
contabilizar a legibilidade do texto. Esses indicadores no esto no entanto muito desenvolvidos.
O nmero ciclomtico o nmero de caminhos diferentes no cdigo. Mostrou-se que esse nmero
igual ao nmero de comandos de deciso mais 1. portanto muito fcil de calcular, mesmo para uma
grande quantidade de linhas de cdigo.
O nmero ciclomtico permite dar uma ideia da complexidade de um bloco de cdigo, mas ao decidir
efectuar uma alterao ao cdigo, o custo estimado nessa alterao poder passar no s pelo mdulo
afectado, mas tambm pelos mdulos que este interage, e pela reviso da documentao associada. Os
testes que esto ligados aos mdulos afectados, tm de ser refeitos, e a documentao actualizada.
Todos estes custos tm de ser levados em considerao, para saber se vale a pena efectuar a correco,
ou se por outro lado se deixa como est. Notar que aps identificar um problema, a sua resoluo
poder passar por corrigir apenas o cdigo, mas pode tambm passar por alterar o desenho, ou mesmo
os requisitos, levando a custos muito superiores nestes dois ltimos casos.
"Software Engineering, theory and practice", second edition, Prentice Hall, Shari Pfleeger, pg. 403-407,
448-460, 464-502
www.moodle.univ-ab.pt//print.php?id 85/85