Programação 2009/2010 MEEC MEAer Projecto de Programação population_workbench 1. Introdução Com o desenvolvimentos das redes de sensores e tecnologias de telemetria e identificação remota é possível monitorizar grandes populações de animais no meio selvagem. Devido à elevada quantidade de dados produzidos por estes sistemas é necessário automatizar o seu processamento. Assim, o projecto de programação consiste no desenvolvimento de um programa (chamado population_workbench) que permite analisar e apresentar os dados produzidos por sistemas de lo calização de animais selvagens. O programa interage com o utilizador por meio de comandos textuais, permitindo ao utiliza dor a leitura de conjuntos de dados (contendo as diversas localizações de uma população ao longo do tempo), a geração de gráficos com a localização individual dos indivíduo e deslocamento da po pulação e geração de estatística. O utilizador, após invocar a aplicação population_workbench tem à sua disposição uma linha de comando onde deverá escrever os comandos. Estes comandos seguem a sintaxe que se apresenta na próxima secção. 2. Comandos Neste projecto deverão ser implementados os comandos que permite ao utilizador interagir com a aplicação: ler dados, configurar aplicação e gerar resultados. 2.1. Leitura de dados read population_name [ start_time_step [ end_time_step ] ] Lê vários ficheiros cujos nomes têm a forma population_name_X.data , em que X é substituído por um valor numérico entre start_time_step e end_time_step (inclusive). A leitura começa no ficheiro com o valor X menor e continua lendo os ficheiros com X su periores. Projecto de Programação (MEECMEAer) 2009/2010 29092009 Se não for indicado end_time_step a leitura termina quando não conseguir ler um ficheiro de dados. Se não for indicado start_time_step o primeiro ficheiro lido corresponde ao do instante zero, X com o valor 0 (zero). Quando forem indicados os dois parâmetros numéricos (start_time_step e end_time_step) a leitura deve continuar para o ficheiro seguinte, mesmo que um ficheiro não exista. Cada ficheiro lido contém as coordenadas dos diversos indivíduos de uma determinada po pulação. O armazenamento dos dados correspondentes a vários instantes permite o estudo da evolu ção temporal dessas populações. As coordenadas correspondentes a cada instante deverão ser armazenadas em memória para processamento posterior. A leitura repetida de dados correspondentes a populações com informação já armazenada em memória, implica a adição de novos dados (correspondentes a instantes não lidos anteriormente). Para uma população não poderá haver dados repetidos referentes a um mesmo instante, i.e. para um determinado instante e para uma população não pode haver dados repetidos. Exemplos read flock Este comando tenta ler o ficheiro flock_0.data, seguido de flock_1.data, flock_2.data, flock_3.data, flock_4.data,... Termina a leitura quando não conseguir ler um ficheiro. read eagle 10 Este comando tenta ler o ficheiro eagle_10.data, seguido de eagle_11.data, eagle_12.data, eagle_13.data, eagle_14.data ,... Termina a leitura quando não conseguir ler um ficheiro. read eagle 15 20 Este comando tenta ler todos os ficheiros: eagle_15.data, eagle_16.data, eagle_17.data, eagle_18.data, eagle_19.data e eagle_20.data . Neste comando, se algum dos ficheiros não existir, a leitura deverá continuar pelos próximos ficheiros. 2/16 Projecto de Programação (MEECMEAer) 2009/2010 29092009 2.2. Remoção de dados remove population_name [ start_time_step [ end_time_step ] ] O comando remove apaga da memória os dados correspondentes à população cujo nome aparece como parâmetro (population_name). Os valores start_time_step e end_time_step limitam quais os dados a ser removidos. No caso de ambos forem indicados, só os dados correspondentes a instantes pertencentes a este interva lo são removidos. Se apenas for indicado o start_time_step, são removidos todos os dados correspondentes a instantes posteriores a esse instante, i.e. dados cujo time_step seja superior a start_time_step. Se não for indicado start_time_step nem end_time_step todos os dados da população são apagados. Exemplos remove flock Este comando remove todos os dados armazenados em memória correspondentes à popula ção flock remove eagle 10 Este comando remove todos os dados armazenados em memória correspondentes à popula ção eagle, cujo instante (time_step) é maior ou igual a 10 read eagle 15 20 Este comando remove todos os dados armazenados em memória correspondentes à popula ção eagle para os instantes entre 15 e 20 (inclusive). 2.3. Definição dos limites dos gráficos set limits auto set limits minx miny maxx maxy Uma funcionalidade desta aplicação é a geração de gráficos (mapas) com a localização dos indivíduos das diversas populações. O comando set limits permite definir quais os limites da região que será mostrada em cada gráfico. Este comando definirá quais os valores mínimos e máximos para as coordenadas x e y da região a apresentar nos gráficos. 3/16 Projecto de Programação (MEECMEAer) 2009/2010 29092009 Se o utilizador der o comando set limits auto, os limites da região deverão garantir que to dos os indivíduos lidos e armazenados até esse momento estão incluídos no intervalo calculado. Na outra alternativa (set limits minx miny maxx maxy) é o utilizador que define os limites dos gráficos. A partir deste momento e até que novo comando set limits seja dados os mapas terão o mes mos limites. Ao desenhar os mapas, qualquer indivíduo com coordenadas externas a estes intervalos não é impresso. A leitura de novos dados não altera os limites definidos por este comando. Só uma nova invocação do comando set limits altera os limites dos gráficos. Exemplos set limits auto Este comando define de forma automática os limites dos gráficos que forem gerados poste riormente. Os limites calculados deverão circundar as coordenadas de todos os indivíduos armazenadas até este momento. A leitura de novos dados, não altera os limites definidos com este comando. set limits 0 0 1000 800 Este comando define explicitamente o novos limites para os gráficos (coordenadas x entre 0 e 1000 e coordenadas y entre 0 e 800). 4/16 Projecto de Programação (MEECMEAer) 2009/2010 29092009 2.4. Atribuição de símbolo a uma população assign population_name symbol Aquando da geração dos mapas com as populações, é necessário identificar e distinguilas. Assim é necessário que os indivíduos de cada população sejam representados por símbolos dife rentes. Este comando atribuí a uma população um símbolo (um caracter) que será usado na geração dos mapas. Exemplos assign eagle v A partir deste momento qualquer mapa ou gráfico que apresente indivíduos da população eagle, usa o caracter v para os representar (ver exemplos na secção 2.5). Para indivíduos de outras populações deverão ser usados outros caracteres (também defini dos pelo utilizador e atribuídos com outro comando assign) . 2.5. Apresentação de dados show pop all time_step show pop population_name time_step O comando show pop abre uma janela e apresenta nela um gráfico com a localização dos indivíduos num determinado instante (time_step). Se for usada a palavra all, são apresentados os indivíduos de todas as populações para as quais haja dados nesse instante. Caso se use um outro nome diferente de all, apenas serão apresentados os indivíduos da po pulação com esse nome, também no instante definido. Exemplos Show pop eagle 1 Esta instrução abre uma janela e, usando os limites definidos anteriormente (automáticos ou explicitamente definidos), desenha o gráfico com a posição dos indivíduos da população eagle no instante 1. 5/16 Projecto de Programação (MEECMEAer) 2009/2010 29092009 Show pop all 100 Esta instrução abre uma janela e, usando os limites definidos anteriormente (automáticos ou explicitamente definidos), desenha o gráfico com a posição dos indivíduos de todas as populações existentes no instante 1. Neste caso do seguinte exemplo existiam duas populações diferentes, que se podem observar no gráfico representadas por símbolos diferentes: uma representada pelo caracter x e outra pelo caracter v. 6/16 Projecto de Programação (MEECMEAer) 2009/2010 29092009 show center population_name O comando show center abre uma janela e apresenta nela um gráfico com o percurso reali zado pela população identificada por population_name. Na apresentação do percurso é usado o “centro de massa” da população. Cálculo do centro de massa O centro de uma população pode ser calculado de diversas maneiras. Neste projectos este ponto será calculado de modo semelhante ao centro de massa de um sistema com N partículas: 1 N C= ∑ m i∗ pi em que N é o número de partículas, p i á a posição e m i N i =1 corresponde à massa de cada partícula. No caso das populações deste projecto, considerase que todos os elementos da população como tem massa igual, ficando assim a fómula: N C= 1 ∑p N i =1 i As coordenadas (x e y) do centro da população podem ser calculadas separadamente: • • 1 xc= N N 1 ∑ x i e y c= N i=1 N ∑ yi são as coordenadas do centro da população i=1 x i e x i são as coordenadas de cada uma dos elementos da população Exemplos show center flock Esta instrução abre uma janela e, usando os limites definidos anteriormente (automáticos ou explícitos) e desenha uma linha que representa o percurso do bando flock. 7/16 Projecto de Programação (MEECMEAer) 2009/2010 29092009 2.6. Geração de ficheiros gráficos plot pop all file_name plot pop population_name file_name Este comando gera vários mapas (um para cada instante armazenado em memória) com a lo calização dos diversos indivíduos de cada população. Se se usar o parâmetro all, cada um dos mapas conterá indivíduos de todas as populações existentes. Caso contrário, só a população identificada por population_name será referenciada nos mapas gerados. É criado um ficheiro do tipo PNG com nome no seguinte formato: file_name_X.png , em que X deverá ser substituído pelo número de instante (time_step). Se para um determinado instante não existirem dados, não é gerado nenhum ficheiro. A representação das populações usando este comando é semelhante à do comando show. Exemplos Show pop all all_pop Este comando gera uma imagem para cada instante para o qual existem dados, independen temente da população a que pertencem. O nome dessas imagens tem o prefixo all_pop_. Em alguns instantes (neste exemplo até ao instante 429) aparecem indivíduos de várias po pulações, noutros só aparecem indivíduos de uma população. 8/16 Projecto de Programação (MEECMEAer) 2009/2010 29092009 Se para um determinado instante não existirem dados não é gerada nenhuma imagem para esse instante. As imagens são geradas na directoria de trabalho. all_pop_00000.png all_pop_00001.png all_pop_00076.png ... ... all_pop_00074.png all_pop_00075.png all_pop_00429.png all_pop_00430.png ... Show pop eagle pop_eagle Este comando gera uma imagem para cada instante para o qual existem dados referentes à população eagle. O nome dessas imagens tem o prefixo pop_eagle_. Só aparecem indivíduos da população definida (neste caso eagle). Se para um determinado instante não existirem dados, não é gerada nenhuma imagem. As imagens são geradas na directoria de trabalho. pop_eagle_00000.png pop_eagle_00001.png pop_eagle_00431.png ... ... pop_eagle_00429.png pop_eagle_00430.png pop_eagle_00622.png pop_eagle_00623.png pop_eagle_00624.png 2.7. Geração de estatísticas get stats population_name [ file_name ] Este comando imprime uma tabela com as estatísticas de uma determinada população. Para cada instante, a partir dos dados armazenados em memória, é impressa uma linha contendo a seguinte informação: • Limites da população (minx, miny, maxx, maxy) 9/16 Projecto de Programação (MEECMEAer) 2009/2010 • 29092009 Centro da população (centrox, centroy) Se for indicado o nome de um ficheiro, a informação acerca da população é escrita num ficheiro chamado file_name . Exemplo get stats eagle 0 217.08 85.27 794.61 666.47 530.32 314.22 1 233.11 91.44 782.50 646.87 529.55 308.22 2 252.30 98.88 772.36 627.10 529.82 301.44 3 271.35 105.60 762.53 607.32 529.87 293.42 4 290.40 112.51 752.44 608.19 528.90 287.00 20 216.62 164.69 511.65 468.47 355.17 236.93 21 203.31 166.13 510.38 455.09 342.55 235.76 ... .... 2.8. Resumo dos comandos São apresentados de seguida todos os comandos a implementar. Para cada comando são indicados a itálico quais os seus parâmetros (que o utilizador deve definir) e os seus tipos. • read population_name [ start_time_step [ end_time_step ] ] o population_name string o start_time_step e end_time_step – inteiros o start_time_step e end_time_step são opcionais • remove population_name [ start_time_step [ end_time_step ] ] o population_name string o start_time_step e end_time_step – inteiros o start_time_step e end_time_step são opcionais • set limits auto • set limits minx miny maxx maxy o minx miny maxx maxy reais • assign population_name symbol o population_name – string o symbol – caracter • show pop all time_step o time_step – inteiro 10/16 Projecto de Programação (MEECMEAer) 2009/2010 • 29092009 show pop population_name time_step o population_name – string o time_step – inteiro • show center population_name o population_name – string • plot pop all file_name o file_name – string • plot pop population_name file_name o population_name e file_name – string • get stats population_name [ file_name ] o population_name e file_name – string o file_name é opcional 3. Formato dos Ficheiros de dados As coordenadas dos indivíduos de uma população são armazenadas persistentemente em vários ficheiros. Cada ficheiro contém as coordenadas dos diversos indivíduos num determinado instante. O formato do nome dos ficheiros é o seguinte NNNNNN_X.data , em que: • NNNNNN é substituído pelo nome da população • X corresponde ao instante a que os dados dizem respeito Por exemplo o ficheiro eagle_127.data tem as coordenadas dos indivíduos da população eagle no instante 127. Cada uma das linha destes ficheiros contém unicamente as coordenadas (x e y) de um indivíduo, separadas por um espaço (ou tab). Nenhuma outra informação está contida nos ficheiros de dados. Exemplo do conteúdo de um ficheiros de dados eagle_1.data contendo as coordenadas de 20 aves: 371.42462 517.76807 745.8838 498.4199 782.49634 560.77795 233.11032 287.37665 587.2787 201.70482 586.4744 235.28424 403.76346 314.4696 11/16 Projecto de Programação (MEECMEAer) 2009/2010 745.3034 295.49466 713.2797 494.72754 712.14197 156.99321 531.9933 188.20189 317.48935 91.43638 381.3252 459.7714 364.15906 139.0551 759.3824 458.51932 456.92392 232.4197 629.93115 216.20279 539.61304 514.93555 496.79605 646.87274 603.6028 171.79942 29092009 4. Directoria de trabalho Os ficheiros de dados deverão ser todos lidos de uma directoria de trabalho, as escrita de ficheiros também é feita nessa directoria. Normalmente esta directoria é aquela onde se encontra a aplicação. Se o utilizador desejar alterar esta directoria de trabalho, para ler (ou escrever) de uma directoria diferente, deverá utilizar os argumentos da linha de comando. A opção –d (seguida de um nome) permite alterar a directoria de trabalho. Por exemplo population_workbench –d /data/ permitirá a leitura dos ficheiros de dados a partir da directoria /data/ . Mais tarde a mesma aplicação poderá ser utilizada para ler e processar dados existente noutra directoria (/data2 por exemplo): population_workbench –d /data2 . 5. Formato do gráficos Os gráficos deverão ser desenhados (no écran ou nos ficheiros) usando a biblioteca g2: • http://g2.sourceforge.net/g2_ref/ Esta biblioteca contêm uma série de funções para geração de imagens em diversos formatos: inclui os mecanismos para criação dos ficheiros e abertura de janelas, assim como funções para escrita de figuras gráficas (pontos, polilinhas e polígonos). Os gráficos apresentados no écran (com o comando show) ou escritos nos ficheiros (com o comando plot) seguem sempre o mesmo formato. A dimensão dos gráficos (janelas ou ficheiros .png) é sempre 800x600: 800 pontos de largu ra e 600 pontos de altura. 12/16 Projecto de Programação (MEECMEAer) 2009/2010 29092009 Dentro desta área deverá ser desenhado um rectângulo em cujo interior serão assinaladas as posições dos indivíduos. Para representar cada indivíduo deverão ser usados os caracteres definidos pelo comando assign. As dimensões deste rectângulo são fixas e deverão ser definidas pelo programador. Nos eixos do gráfico deverão ser apresentados os limites definidos com o comando set limits. No exemplo anterior os limites calculados com o comando set limits auto foram: • eixo x 42.54 1023.18 • eixo y 0.01 752.0 6. Desenvolvimento do projecto Sugerese um desenvolvimento faseado do projecto, devendo os alunos garantir que todas as funcionalidades codificadas até esse momento se encontram a funcionar correctamente. É preferível um programa que implementa poucas funcionalidades, mas que funcio nam correctamente, do que um programa totalmente desenvolvido mas que não faz nada. Assim sugeremse os seguintes passos, pela ordem apresentada, para realização do projecto: • Leitura e verificação dos comandos dados pelo utilizador • Leitura e verificação dos ficheiros de dados 13/16 Projecto de Programação (MEECMEAer) 2009/2010 29092009 • Armazenamento dos dados referentes a um instante • Comando set limits minx miny maxx maxy • Funções auxiliares para o comando set limits auto • Implementação parcial do comando assign • Implementação parcial do comando show (criação da janela e desenho dos indivíduos de uma única população) • Implementação parcial do comando plot (criação do ficheiro e desenho dos indivíduos de uma única população) As funcionalidade listadas anteriormente podem ser implementadas sem o código de mani pulação de listas. A partir do momento em que se armazenam vários conjuntos de dados (de popula ções e instantes diferentes) todas as funcionalidade podem ser implementadas: • Armazenamento dos dados de diversos ficheiros • Comando remove • Comando set limits auto • Comando assign • Comando show pop • Comando show center • Comando plot • Comando get stats 6.1. Codificação Devido ao tipo de dados (grande variabilidade e desconhecimento da quantidade máxima de populações e instantes), deverão ser utilizadas listas dinâmicas para armazenamento dos dados. O estilo de codificação (indentação, posicionamento das chavetas, nomes dos identificado res) deve ser escolhido pelos alunos, mas consistente em todo o projecto. Existem diversas variações da linguagem C. Aquela que deve ser usada é a apresentada nas aulas teóricas e descrita no livro The C Programming Language The ANSI edition. 6.2. Documentação O código produzido pelos alunos deverá ser comentado e documentado. Os comentários pre sentes no código deverão explicitar e explicar o funcionamento da aplicação assim como as deci sões tomadas. 14/16 Projecto de Programação (MEECMEAer) 2009/2010 29092009 Na geração da documentação relativa às funções implementadas, deverá também ser usada o formato implementado pela aplicação Doxygen. 6.3. Compilação O compilador a usar na execução do projecto é o gcc, em ambiente Linux. Na compilação do código devem ser usados os seguintes argumentos da linha de comando –Wall –ansi –pedantic. Projectos que não compilem quando usando as opções anteriores, i.e. que tenham erros de sintaxe, não serão avaliados. A existência de avisos durante a fase de compilação é indício da existência de problemas no código e será penalizada. Não é permitido o uso de biblioteca distintas da g2 e das apresentadas no livro The C Pro gramming Language The ANSI edition. 6.4. Decisões de projecto Como em qualquer projecto de informática, o funcionamento do programa não está total mente definido no enunciado, existindo algumas ambiguidades e omissões. Para resolver essas omissões os alunos deverão tomar algumas decisões aquando do desen volvimento do projecto. Estas decisões devem ser fundamentadas, sem nunca ir contra o definido no enunciado. 7. Avaliação A avaliação do projecto terá em conta diversos parâmetros: • Funcionalidades implementadas • Qualidade do código produzido • Estruturação da aplicação • Estruturas de dados usadas no armazenamento das populações • Comentários e documentação • Tratamento de erros • Organização do código (separação modular do código) • Discussão oral 7.1. Entrega intermédia A aplicação a realizar para a entrega intermédia deve ter a seguinte funcionalidade: 15/16 Projecto de Programação (MEECMEAer) 2009/2010 29092009 • Leitura dos comandos a partir do teclado • Verificação da correcção sintáctica dos comandos • Verificação do formato da informação contida nos ficheiros de dados • Identificação de possíveis erros, com escrita no écran de mensagens explicativas • Contabilização do número de ficheiros correctamente lidos • Apresentação do número de coordenadas existentes em cada ficheiro de dados lido • Contabilização discriminada de cada um dos comandos correctamente invocados pelo utilizador (read, remove, set limits, assign, show, plot e get stats) Nesta fase, não é necessário armazenar nenhuma informação contida nos ficheiros da dados. A única informação a armazenar é aquela necessária à contabilização pedida. Este programa servirá de base para o desenvolvimento do projecto final. A entrega será realizada de modo electrónico, através do sistema Fénix. Nas semanas seguintes a nota e os problemas encontrados serão apresentados aos alunos. Esta entrega intermédia será cotada entre 0 e 3 valores, sendo avaliado o seguinte: • Funcionalidade implementada e a funcionar • Estruturação do código • Comentários 7.2. Entrega Final Aquando da entrega final do projecto, os alunos deverão ter um programa que implemente todas as funcionalidades pedidas. Os alunos deverão entregar uma cópia em papel das listagens do código e, em versão electrónica (CD), a directoria do projecto KDevelop (comprimida num ficheiro .tar.gz) contendo o código e a documentação gerada pelo Doxygen. O trabalho final e a discussão desse trabalho será cotada entre 0 e 17 valores. 16/16