O Mundo das Margaridas Enunciado da 2 a fase de entrega do projecto Fundamentos da Programação e Elementos de Programação 12 de Dezembro de 2007 Aviso: Este enunciado descreve o que é pretendido na segunda fase de entrega do projecto para as cadeiras de Fundamentos da Programação e Elementos de Programação. É o segundo enunciado de entre três que definem cada uma das três fases do projecto. Eventuais correcções posteriores ao lançamento deste enunciado, bem como explicações adicionais que possam ajudar na elaboração do projecto, serão disponibilizadas na página da cadeira na secção Projecto até ao dia 23 de Dezembro. Esses anúncios terão valor oficial, pelo que a leitura deste enunciado deve obrigatoriamente ser completada com consultas regulares à referida página. O prazo de entrega desta fase do projecto é dia 03 de Janeiro de 2008 às 22h00. 1 Contexto No primeiro enunciado do projecto foi introduzido o Mundo das Margaridas, um modelo simplificado de um planeta que se encontra na proximidade de um sol, e que é habitado apenas por margaridas. Estas margaridas podem ter diferentes cores, e mais importantemente, diferentes albedos, exibindo assim diferentes capacidades de absorção da luz solar. Ao absorver ou reflectir a luz solar, as margaridas influenciam a temperatura local à sua volta, podendo torná-la mais baixa ou mais elevada do que a temperatura planetária. Assim, as populações de margaridas têm a capacidade de intervir no seu ambiente, regulando a sua temperatura local. No modelo original Daisyworld, as margaridas podem ter apenas uma de duas cores branca ou preta. No entanto, tal como foi mencionado no enunciado anterior, o nosso modelo será ligeiramente mais complexo, e permitirá o aparecimento de margaridas com várias tonalidades, através de mutações genéticas que poderão ocorrer no momento da reprodução de cada margarida. 1
Na primeira fase do projecto foram apresentadas e explicadas as várias fórmulas que regem o Mundo das Margaridas. O trabalho proposto consistiu na implementação de um conjunto de procedimentos que traduzissem essas fórmulas. Nesta fase de elaboração do projecto daremos mais atenção à distribuição espacial no planeta das Margaridas, e desenvolveremos ainda os aspectos da geração de aleatoriedade e da representação do planeta e das margaridas. O objectivo desta fase é a apreensão da metodologia dos Tipos Abstractos de Informação (TAIs). 2 Descrição do modelo (continuação) 2.1 Aleatoriedade Geração de números pseudo-aleatórios. As regras que regem o Mundo das Margaridas têm uma componente probabilística, e consequentemente, as simulações terão um certo grau de não-determinismo. Por outras palavras, repetidas execuções do programa não produzirão as mesmas configurações do planeta. Para obter o efeito da aleatoriedade, deverá ser utilizado o procedimento gerador, fornecido na página da cadeira. Este procedimento pode ser chamado de duas maneiras: 1. (gerador "inicializa" semente H V) Quando gerador é chamado tendo como primeiro argumento a cadeia de caracteres "inicializa", um gerador de números pseudo-aleatórios 1 é inicializado com o inteiro semente entre 0 e 2 31 1. A partir desse momento passará a ser possível gerar números aleatórios para cada instante e posição numa grelha com H linhas e V colunas. 2. (gerador "aleatorio" t h v) Quando gerador é chamado tendo como primeiro argumento a cadeia de caracteres "aleatorio", é retornado um novo número aleatório correspondente ao instante t e posição (h, v). Esse número será um inteiro no intervalo {0, 2 31 2}. O número aleatório que é gerado é completamente determinado pela semente com que o gerador tenha sido inicializado, e pelo instante e posição 1 Um gerador de números pseudo-aleatórios é um algoritmo que produz uma sequência de números que aproxima as propriedades dos números aleatórios. A sequência gerada não é verdadeiramente aleatória daí a designação de pseudo por ser determinada por um estado inicial, denominado frequentemente semente. 2
para o qual se gera o número. Sendo assim, pode-se concluir que existirão 2 31 possíveis execuções para o mesmo programa. Na avaliação do projecto vamos tirar partido deste facto do seguinte modo: um dos parâmetros do programa será a semente do gerador de números pseudo-aleatorios; assim, todos os programas correctos que recebam o mesmo inteiro como semente originarão exactamente o mesmo comportamento, tornando possível a avaliação automática. Para este mecanismo funcionar, a inicialização do gerador deve ser feita uma única vez no início do programa. Probabilidades. Dado que os números pseudo-aleatórios gerados pelo processo acima se encontram no intervalo {0, 2 31 2}, decidir a ocorrência de um determinado evento com a probabilidade p é equivalente a testar se o número x que é gerado satisfaz a condição x < p (2 31 1). Propagação de margaridas. Quando, numa mudança de instante t para t + 1, se decide que uma nova margarida deve aparecer num outro ponto do planeta, é necessário decidir em que posição ela deve aparecer. Tal como foi mencionado no primeiro enunciado do projecto, essa posição será escolhida aleatoriamente. Para isso há que considerar o número aleatório x gerado para o instante anterior t e posição da margarida mãe. A partir deste x, é possível obter uma posição num planeta de H linhas e V colunas x mod (H V ) em que cada posição é designada por um número entre 0 e H V 1, preenchendo as posições a partir do canto superior esquerdo, e percorrendo todas as linhas uma a uma da esquerda para a direita e de cima para baixo. O resultado da escolha aleatória de uma posição no planeta não resulta necessariamente numa posição vazia. No caso da posição não ser vazia, deve ser procurada a próxima posição vazia, pesquisando a grelha sequencialmente linha a linha da esquerda para a direita, e de cima para baixo, a partir da posição escolhida inicialmente. Quando for atingida a última posição da grelha, a pesquisa continua na mesma direcção a partir da posição (0, 0) da grelha, até à posição inicial. No caso de não existir nenhuma posição vazia para a margarida nascer, então a margarida não nasce. Mutações Quando, numa mudança de instante t para t + 1, uma margarida se reproduz, criando uma nova margarida, poderá ocorrer um erro de cópia do seu DNA, pelo que a nova margarida não é necessariamente igual à margarida mãe. No nosso mundo, a mutação pode ocorrer apenas a nível 3
do gene que determina o albedo da nova margarida. Isto significa que a nova margarida poderá ter um albedo diferente do da mãe. A probabilidade com que as mutações podem ocorrer será um parâmetro do modelo, designada probabilidade de mutação, e representada por M. O novo albedo (α f ) será obtido a partir do número aleatório x gerado para o instante anterior t e posição da mãe, bem como a partir do albedo α m da mãe, através da fórmula: { αm 1 3 α f =.(α m x 2 31 2 ) se x 2 31 2 < α m α m + 1 3.( x 2 31 2 α x m) se 2 31 2 α m 2.2 Implementação do autómato celular O sistema de coordenadas. Tal como foi descrito no enunciado anterior, as possíveis localizações de margaridas no planeta são referenciadas usando duas coordenadas (h, v), em que h corresponde à linha em que a posição se encontra, e v corresponde à coluna em que a posição se encontra. Assim, num planeta com H linhas e V colunas, as possíveis localizações têm coordenadas 0 h < H e 0 v < V quando H e V > 0. Considera-se que um planeta com H ou V = 0 não tem posições. Convenciona-se que a posição (0, 0) representa a posição do canto superior esquerdo da grelha. Um novo instante. A cada passagem de instante, uma nova configuração C t+1 do planeta deve ser gerada a partir da configuração no instante anterior C t. A configuração C t do planeta deve ser analisada a partir do canto superior esquerdo, percorrendo, da esquerda para a direita, e de cima para baixo todas as células de cada linha. Para cada margarida encontrada, deve decidir-se qual a nova etapa da sua vida: ela poderá sobreviver ou morrer com uma certa probabilidade, e no caso de sobreviver, poderá reproduzir-se com outra probabilidade (conforme especificado no primeiro enunciado). Todas as decisões referentes à nova etapa na vida das margaridas fazemse com base na configuração C t (do instante anterior). Por exemplo, no caso de ela vir a gerar uma nova margarida numa nova localização (vazia) do planeta, a procura de uma posição vazia será feita com base em C t. Esta regra implica que poderá haver mais do que uma nova margarida a surgir na mesma posição do instante seguinte. A desambiguação deste caso será feita dando precedência à primeira margarida a ser gerada nessa posição. Por outras palavras, as margaridas seguintes destinadas a nascer em posições já ocupadas não vingam e pura e simplesmente não nascem. 4
Representação externa do planeta e das margaridas Enquanto que a representação interna isto é, em Scheme do planeta é deixada ao critério de cada grupo, a representação externa isto é, aquela que é utilizada para o programa ler uma configuração inicial do planeta (input), ou imprimir configurações resultantes da simulação (output) deverá respeitar regras muito precisas. Tal como já foi dito, a avaliação automática dos projectos será feita com base na comparação entre o output produzido e o output correcto, mediante o input que é dado. A representação externa de um planeta é uma única string S (cadeia de caracteres), satisfazendo o seguinte formato: A string S é composta por uma sequência de strings s, cada uma delas seguida de uma barra diagonal ( / ). Cada string s é composta por uma sequência de pequenas strings p separadas entre si por uma única barra vertical ( ). Cada string p representa o conteúdo de uma posição na grelha. Se a posição for vazia, p consiste num único caracter espaço ( ) entre os separadores mencionados acima. Se a posição for ocupada por uma margarida, então p constitui a cadeia de caracteres que consiste na representação externa das margaridas (definida a seguir). A representação externa de uma margarida é uma única string p (cadeia de caracteres) constituída por três strings a 1, a 2 e a 3 separadas pelo caracter hífen (, ), em que: a 1 representa o albedo da margarida nessa posição. a 2 representa a temperatura mínima de sobrevivência da margarida nessa posição a 3 representa a temperatura máxima de sobrevivência da margarida nessa posição A título de exemplo, a cadeia de caracteres 0.21,10,30 / 0.8889,12,20 0.21,15,45 / 0.1,15,40 / 0.21,15,45 / corresponde à representação externa de um planeta com a configuração mostrada na Figura 1. Note que não deve aparecer mais nenhum caracter para além daqueles especificados acima, incluindo espaços, tabulações e mudanças de linha. 5
Figura 1: Exemplo de planeta. Para efeitos de visualização e de verificação de representações externas de planetas será fornecido na página da cadeira um procedimento mostra_mundo que recebe como argumentos uma cadeia de caracteres contendo a representação externa de um planeta, e produz uma representação gráfica desse planeta. No caso da cadeia de caracteres não ter a formato especificado acima, o procedimento retorna uma mensagem de erro. Com o objectivo de simplificar a análise de cadeias de caracteres, será fornecido na página da cadeira um procedimento tokenize que recebe como argumentos uma cadeia de caracteres e um caracter separador, e retorna a lista das cadeias de caracteres que compõem a string recebida como argumento, separadas pelo caracter dado: > (tokenize "Olá, bom dia!" #\,) ("Olá" " bom dia!") 3 A entregar Nesta segunda fase do projecto deve ser submetido um ficheiro com nome proj2-fp0708-xx.zip (substituir xx pelo número do grupo, de modo a ocupar dois dígitos), que contém quatro outros ficheiros, nomeados: proj2-margarida-fp0708-xx.scm proj2-posicao-fp0708-xx.scm proj2-planeta-fp0708-xx.scm proj2-procs-fp0708-xx.scm 6
Para além destes quatro ficheiros obrigatórios, pode ser incluído um quinto ficheiro opcional com nome proj2-aux-fp0708-xx.scm (substituir xx pelo número do grupo, de modo a ocupar dois dígitos) no qual se guardam procedimentos auxiliares a ser usados pelos quatro ficheiros principais. Cada ficheiro deve conter um programa em Scheme, em conformidade com as instruções dadas nas quatro secções que se seguem. O código deve ser apresentado de forma mais legível possível; deve ser compatível e fazer uso, sempre que necessário, do código pedido no enunciado anterior. Todos os procedimentos devem testar se o tipo dos argumentos tem o formato esperado. Caso contrário o procedimento deve retornar, tal como na primeira parte do projecto, uma mensagem de erro sob a forma da seguinte cadeia de caracteres: Erro de input. Haverá ainda outro tipo de mensagens de erro, que especificaremos caso a caso, e que designamos erro de consistência. Estes erros ocorrem num procedimento quando, apesar de ter recebido argumentos com o tipo certo, existe algum problema de consistência que impede a realização da operação. Perante a ocorrência deste tipo de erros, os procedimentos devem retornar uma mensagem de erro sob a forma da seguinte cadeia de caracteres: Erro de consist^encia. 3.1 O tipo Margarida No ficheiro proj2-margarida-fp0708-xx.scm deve ser feita a implementação do tipo Margarida, de acordo com a assinatura: nova_margarida : [0, 1] Inteiro Inteiro Margarida String Esta operação recebe como argumentos um albedo, e duas temperaturas correspondentes à temperatura de sobrevivência mínima e máxima, e retorna a representação interna de uma margarida com esse albedo, e que tem como temperatura mínima e máxima de sobrevivência as temperaturas especificadas. Se a temperatura mínima não for inferior ou igual à segunda, o procedimento deve retornar um erro de consistência. albedo_margarida : Margarida [0, 1] String Esta operação recebe como argumento uma margarida, e retorna o seu albedo. 7
tempmin_margarida : Margarida Inteiro String Esta operação recebe como argumento uma margarida, e retorna a sua temperatura mínima de sobrevivência. tempmax_margarida : Margarida Inteiro String Esta operação recebe como argumento uma margarida, e retorna a sua temperatura máxima de sobrevivência. tempideal_margarida : Margarida Racional String Esta operação recebe como argumento uma margarida, e retorna a sua temperatura ideal de proliferação. margarida? : Universal Lógico Esta operação recebe como argumento um objecto qualquer, e retorna o valor lógico verdadeiro se e só se esse objecto for do tipo Margarida. imprime_margarida : Margarida String Esta operação recebe como argumento uma margarida, e retorna a representação externa de uma margarida sob a forma de uma cadeia de caracteres. Estas devem ser as únicas operações básicas do tipo Margarida. 3.2 O tipo Posição No ficheiro proj2-posicao-fp0708-xx.scm deve ser feita a implementação do tipo Posição, de acordo com a seguinte assinatura: nova_posicao : Natural Natural Posição String Esta operação recebe como argumentos uma linha e uma coluna do planeta, e retorna a representação interna da posição que se encontra nessa linha e nessa coluna. A correcção deste procedimento terá grande impacto na avaliação de todos os procedimentos que receberem como argumento a representação interna de uma posição do planeta. linha_posicao : Posição Natural String Esta operação recebe como argumento uma posição, e retorna a componente linha dessa posição. 8
coluna_posicao : Posição Natural String Esta operação recebe como argumento uma posição, e retorna a componente coluna dessa posição. posicao? : Universal Lógico Esta operação recebe como argumento um objecto qualquer, e retorna o valor lógico verdadeiro se e só se esse objecto for do tipo posição. posicao_valida? : Posição Natural Natural Lógico String Esta operação recebe como argumentos uma posição, o número de linhas e o número de colunas de um planeta, e retorna o valor lógico verdadeiro se e só se essa for uma posição válida do planeta, e retorna o valor lógico falso se e só se essa não for uma posição válida do planeta. Estas devem ser as únicas operações básicas do tipo Posição. 3.3 O tipo Planeta No ficheiro proj2-planeta-fp0708-xx.scm deve ser feita a implementação do tipo Planeta, que tem obrigatóriamente de ser baseada em listas, e ser compatível com a seguinte assinatura: novo_planeta : Natural Natural [0, 1] Planeta String Esta operação recebe como argumentos o número de linhas do planeta, o número de colunas do planeta, e o albedo da terra inabitada, e retorna a representação interna de um planeta sem margaridas. nasce_margarida : Planeta Posição Margarida Planeta String Esta operação recebe como argumentos a representação interna de um planeta, uma posição no planeta, e uma margarida, e retorna um planeta que resulta da inserção no planeta inicial da margarida na posição dada. Se nessa posição já se encontrar uma margarida, o procedimento deve retornar o mesmo planeta, inalterado. Se essa posição não for uma posição válida do planeta, o procedimento deve retornar um erro de consistência. morre_margarida : Planeta Posição Planeta String Esta operação recebe como argumentos a representação interna de um planeta e uma posição no planeta, e retorna um planeta que resulta de retirar do planeta inicial a margarida que se encontra na posição 9
dada. Se essa posição não for uma posição válida do planeta, ou se nessa posição não se encontrar nenhuma margarida, o procedimento deve retornar um erro de consistência. linhas_planeta : Planeta Natural String Esta operação recebe como argumento um planeta, e retorna o número de linhas desse planeta. colunas_planeta : Planeta Natural String Esta operação recebe como argumento um planeta, e retorna o número de colunas desse planeta. albedo_planeta : Planeta [0, 1] String Esta operação recebe como argumento um planeta, e retorna o valor do albedo da terra inabitada nesse planeta. obtem_margarida : Planeta Posição Margarida String Esta operação recebe como argumentos a representação interna de um planeta e uma posição no planeta em que se encontra uma margarida, e retorna a representação interna dessa margarida. Se essa posição não for uma posição válida do planeta, ou se nessa posição não se encontrar nenhuma margarida, o procedimento deve retornar um erro de consistência. tem_margarida? : Planeta Posição Lógico String Esta operação recebe como argumentos a representação interna de um planeta e uma posição no planeta, e retorna o valor lógico verdadeiro se e só se nesse planeta existe uma margarida na posição dada, e o valor lógico falso se e só se nessa posição não se encontrar nenhuma margarida. Se essa posição não for uma posição válida do planeta, o procedimento deve retornar um erro de consistência. planeta? : Universal Lógico Esta operação recebe como argumentos um objecto qualquer, e retorna o valor lógico verdadeiro se e só se esse objecto for do tipo Planeta. extern_to_intern : String [0, 1] Planeta String Esta operação recebe como argumento uma string que descreve uma possível configuração do planeta (no formato descrito em 2.2) e o albedo da terra inabitada, e retorna a sua representação interna. 10
A correcção deste procedimento terá grande impacto na avaliação de todos os procedimentos que recebem como argumento a representação interna de um planeta. intern_to_extern : Planeta String Esta operação recebe como argumento uma representação interna de uma configuração do planeta, e retorna uma string de caracteres que descreve a configuração do planeta (no formato descrito acima). Estas devem ser as únicas operações básicas do tipo Planeta. 3.4 Procedimentos No ficheiro proj2-procs-fp0708-xx.scm deve ser feita a implementação dos procedimentos definidos a seguir. Estes procedimentos devem fazer uso dos tipos abstractos de informação definidos anteriormente, e devem respeitar as barreiras da abstracção de dados. Para além do código específico desta segunda parte do projecto, o ficheiro deve conter obrigatóriamente o código correspondente à primeira fase de entrega, e deve continuar a satisfazer todas as condições do primeiro enunciado, salvo se forem explicitamente pedidas alterações. 1. Aleatoriedade (a) Um procedimento que determina se um dado evento deve ocorrer ou não, de acordo com uma probabilidade p. Este procedimento deve chamar-se joga_probabilidades e receber como argumentos (por esta ordem): a probabilidade p (um racional [0, 1]) um número pseudo-aleatório (inteiro {0, 2 31 2}. Este procedimento deve retornar um valor lógico, sendo a probabilidade de retornar #t igual a p. (b) Um procedimento que obtém uma posição aleatória num planeta de dimensões H V. Este procedimento deve chamar-se posicao_a_sorte e receber como argumentos (por esta ordem): o número de linhas H do planeta (inteiro 0) o número de colunas V do planeta (inteiro 0) um número pseudo-aleatório (inteiro {0, 2 31 2} Este procedimento deve retornar a posição gerada aleatoriamente. 11
(c) Um procedimento que obtém o albedo de uma nova margarida a partir de uma margarida mãe com um dado albedo, sabendo que uma mutação pode ocorrer com uma certa probabilidade M. Este procedimento deve chamar-se novo_albedo e receber como argumentos (por esta ordem): o albedo da margarida progenitora (racional [0, 1]) a probabilidade de mutação M (racional [0, 1]) um número pseudo-aleatório (inteiro {0, 2 31 2}) Este procedimento deve retornar o albedo da nova margarida (racional [0, 1]). 2. Vizinhanças Nos procedimentos pedidos nesta secção, sempre que houver uma referência a uma posição que não existe no planeta, deve ser retornado um erro de consistência. (a) Um procedimento que constrói uma lista de coordenadas das células que compõem a vizinhança de ordem n de uma célula numa dada posição pos da grelha (V n (pos)). Este procedimento deve chamar-se vizinhos_lista e receber como argumentos (por esta ordem): a posição pos dessa célula (Posição) o número de linhas H da grelha (inteiro 0) o número de colunas V da grelha (inteiro 0) a ordem n da vizinhança (inteiro 0) Este procedimento deve retornar uma lista de posições (na sua representação interna) contendo as coordenadas das células pertencentes à referida vizinhança, sem repetições, pela mesma ordem devolvida (e não a ordem impressa) pelo procedimento vizinhos_display (tal como especificado na pergunta 8. do primeiro enunciado), ou seja, começando da esquerda para a direita (do planeta) e de cima para baixo. Note-se que o procedimento vizinhos_lista é de facto muito semelhante ao procedimento vizinhos_display, sendo as únicas diferenças 2 o facto de receber uma posição (ao invés da linha e coluna) e devolver uma lista de posições (ao invés de uma lista de cadeias de caracteres). 2 Existe uma diferença adicional que é o facto deste procedimento não necessitar de imprimir as posições no ecrâ, no entanto não existe qualquer problema se o fizer. 12
(b) Um procedimento para determinar o número de margaridas que se encontram na vizinhança de uma posição do planeta. Este procedimento deve chamar-se quantas_vizinhas e receber como argumentos (por esta ordem): a representação interna da configuração de um planeta (Planeta) uma posição do planeta (Posição) a ordem n da vizinhança a considerar (inteiro 0) Este procedimento deve retornar o número de margaridas que se encontram na vizinhança (inteiro 0). (c) Um procedimento para calcular o albedo de uma região (α r ). Este procedimento deve chamar-se alb_regiao e, irá substituir o antigo procedimento com o mesmo nome que foi pedido no enunciado anterior 3. O procedimento tanto poderá ser utilizado para determinar o albedo de um planeta inteiro, como para calcular o albedo de uma pequena região do planeta em torno de uma margarida. No primeiro caso, o procedimento deve receber como argumento a representação interna da configuração do planeta (Planeta) enquanto que no segundo caso deve receber como argumentos (por esta ordem): a representação interna da configuração do planeta (Planeta) a ordem n da vizinhança que define a região (inteiro 0) a posição da margarida em questão (Posição) Este procedimento deve retornar um racional [0, 1]. (d) Um procedimento para determinar o conforto térmico de uma margarida num dado instante, tendo em conta uma ordem de vizinhança que define a temperatura local. Este procedimento deve chamar-se conforto_margarida e receber como argumentos (por esta ordem): o instante t (inteiro 0) a representação interna da configuração do planeta nesse instante (Planeta) a ordem n da vizinhança a considerar (inteiro 0) 3 Tal como foi definido no enunciado anterior, o albedo de uma região é a média ponderada dos albedos de cada posição dessa região. 13
a posição da margarida em questão (Posição) Este procedimento deve retornar o conforto térmico da margarida, um real [ 1, 1]. 4 Método de avaliação A nota resultante da avaliação desta fase do projecto projecto terá peso 25% na nota final do projecto, correspondendo assim a 10% da nota final à cadeira. A nota correspondente a esta fase será calculada do seguinte modo: 70% Execução correcta e robustez Para inputs no formato correcto, o output do programa deve ser igual àquele gerado por um programa correcto. No caso do input não ter o formato esperado, o programa deve retornar uma mensagem de erro (conforme especificado acima) e terminar normalmente. 20% Abstracção de dados O uso dos tipos abstractos de informação deve respeitar as barreira da abstracção de dados. Esta propriedade será testada automaticamente, verificando se os procedimentos implementados funcionam com outras implementações dos tipos pedidos. 10% Legibilidade do código A escolha de nomes, identação e introdução de comentários que apoiem a compreensão do programa. Chama-se a atenção para a importância de satisfazer todas as condições do enunciado. A execução, robustez e respeito pela abstracção de dados projectos serão avaliados automaticamente, pelo que as componentes do código que não satisfaçam literalmente os requisitos aqui definidos, mesmo que por diferenças mínimas, serão rejeitadas automaticamente. Serão aplicados métodos de detecção de cópias a todos os projectos. Projectos em que o código coincida total ou parcialmente com o de outros serão atribuídos a nota zero. 5 Planeamento da entrega do projecto O prazo de submissão da segunda fase é a 03 de Janeiro de 2007 às 22h00. O projecto deve ser feito obrigatoriamente em grupos de três alunos. São permitidas alterações à constituição dos grupos que foram formados na primeira fase do projecto, que se devem registar com antecedência no sistema Fénix (o prazo para o registo é 23 de Dezembro à meia-noite). 14
Qualquer tentativa de submissão de projectos por grupos de menos de três alunos não será avaliada. Qualquer pedido de alterações na constituição de um grupo, ou de formação de grupos, posterior a 23 de Dezembro não será efectuado. O projecto está a decorrer ao longo de três fases, em que as etapas ainda por realizar decorrerão pela seguinte ordem: Fase 2 Lançamento do segundo enunciado (este). Submissão da segunda parte do código, através do sistema Fénix. Lançamento dos resultados da avaliação automática. Discussão com os grupos acerca do desenvolvimento do projecto. Fase 3 Submissão da terceira parte do código, através do sistema Fénix. Entrega de relatório. Lançamento dos resultados da avaliação automática. Lançamento da nota final do projecto. A nota de cada aluno resultante das avaliações automáticas e dos relatórios do seu grupo poderá sofrer alterações de acordo com o seu nível de participação no desenvolvimento do projecto. 15