Difference between revisions of "Programação com Objectos/Projecto de Programação com Objectos/Enunciado do Projecto de 2023-2024 (rascunho)"

From Wiki**3

< Programação com Objectos‎ | Projecto de Programação com Objectos
(Pesquisas)
 
(39 intermediate revisions by the same user not shown)
Line 1: Line 1:
{{PRJPOAvisosEN20232024}}
+
#REDIRECT [[Programação com Objectos/Projecto de Programação com Objectos/Enunciado do Projecto de 2023-2024]]
{{PRJPOMandatory20232024}}
 
{{TOCright}}
 
'''<font color="red">EM PREPARAÇÃO</font>'''
 
 
 
'''<font color="red">ÉPOCA NORMAL</font>'''
 
 
 
O objectivo do projecto é desenvolver uma folha de cálculo.
 
 
 
= Propriedades e funcionalidade da folha de cálculo =
 
 
 
A folha de cálculo é capaz de manipular números inteiros, cadeias de caracteres, referências entre células e funções sobre células. Além disso, permite também operações de corte, cópia e inserção (cut/copy/paste).
 
 
 
== Endereçamento: Células, Intervalos, Gamas == 
 
 
 
O número de linhas e de colunas da folha é fixo, sendo definidos na altura da criação. Os endereços (posições na folha: linha e coluna) têm início em 1 (um).
 
 
 
Uma célula é definida com base na sua posição na folha: '''CÉLULA ::= LINHA;COLUNA'''
 
 
 
Um intervalo de endereçamento (são sempre fechados) é definido entre duas células da mesma linha ou da mesma coluna: '''INTERVALO ::= CÉLULA:CÉLULA'''
 
 
 
Utiliza-se o termo “gama” para especificar indiscriminadamente uma célula única ou um intervalo de células.
 
 
 
Exemplo:
 
* '''1;2''' (linha 1, coluna 2); ou '''23;4''' (linha 23, coluna 4)
 
* '''1;2:1;20''' (linha 1, entre as colunas 2 e 20); ou '''23;4:57;4''' (coluna 4, entre as linhas 23 e 57)
 
 
 
== Conteúdo: Literais, Referências, Funções ==
 
 
 
Por omissão, as células estão vazias (sem conteúdo). Os conteúdos admissíveis são: literais (números inteiros e cadeias de caracteres), referências para células e funções. As referências indicam-se com o símbolo “=” seguido do endereço da célula referenciada ([[#Endereçamento: Células, Intervalos, Gamas|Endereçamento]]). As funções indicam-se com o símbolo '''=''' ("igual"), o nome da função e a lista (possivelmente vazia) de argumentos entre parênteses (separados por vírgulas). Estão pré-definidas:
 
 
 
# Funções binárias sobre valores inteiros, cujos argumentos podem ser referências a células ou valores literais: '''ADD''' (adição), '''SUB''' (subtração), '''MUL''' (multiplicação), '''DIV''' (divisão inteira). Todos os argumentos têm de ser passíveis de produzir valores inteiros.
 
# Funções aplicáveis a um intervalo de células com valores inteiros (não podem conter outros valores): '''AVERAGE''' (média de todos os valores do intervalo; a divisão é inteira), '''PRODUCT''' (produto de todos os valores do intervalo).
 
# Funções sobre cadeias de caracteres:
 
#*'''CONCAT''' (aceita um intervalo de células que podem ou não conter cadeias de caracteres e retorna a concatenação das cadeias de caracteres, ignorando todos os outros valores). Se o intervalo tiver apenas uma célula, produz o valor de entrada. Se não existir no intervalo nenhuma cadeia de caracteres, produz a cadeia vazia.
 
#*'''COALESCE''' (aceita um intervalo de células que podem ou não conter cadeias de caracteres e retorna o primeiro valor que for uma cadeia de caracteres). Se o intervalo apenas tiver uma célula ou não contiver nenhuma cadeia de caracteres, produz a cadeia vazia.
 
 
 
Considera-se que não existem dependências circulares, nem directas, nem indirectas, entre uma função e as células referidas pelos seus argumentos. Funções com argumentos inválidos (e.g., referem gamas com células vazias), têm valor inválido (apresentado como '''#VALUE'''), excepto nos casos especiais indicados.
 
 
 
Exemplos:
 
* Inteiros (números com um sinal opcional no início): '''-25''', '''+12''', '''48'''
 
* Cadeias de caracteres (começam sempre com plica): ''''string'''
 
* Referências: '''=1;2'''
 
* Funções: '''=ADD(2;3,1)''', '''=SUB(6;2,22;1)''', '''=MUL(1,2)''', '''=DIV(1,5;2)''', '''=AVG(1;2:1;19)''', '''=PRD(2;33:5;33)''', '''=CONCAT(1;12:1;17)''', '''=COALESCE(1;12:1;17)'''
 
 
 
== Operações Sobre Células ==
 
 
 
É possível inserir, apagar e mostrar conteúdos. É ainda possível copiar conteúdos entre células.
 
 
 
== Cut Buffer ==
 
 
 
Existe um cut buffer independente das folhas de cálculo manipuladas pela aplicação e que permite as operações habituais (copiar, cortar, colar) entre células de uma ou mais folhas.
 
 
 
As operações têm a semântica descrita a seguir.
 
 
 
=== Copiar ===
 
 
 
O conteúdo da origem é copiado para o cut buffer e torna-se independente da fonte, i.e., alterações aos objectos originais não são propagadas para os que estão no cut buffer. O conteúdo anterior do cut buffer é destruído.
 
 
 
=== Cortar ===
 
 
 
Esta operação funciona como a operação de cópia, mas o conteúdo original é destruído.
 
 
 
=== Colar ===
 
 
 
Esta operação insere o conteúdo do cut buffer numa gama da folha de destino. Se o cut buffer estiver vazio, não é realizada qualquer operação. Se a gama for uma única célula, todo o cut buffer deve ser inserido a partir da célula especificada, até ser atingido o limite da folha de cálculo. Caso contrário, se a dimensão do cut buffer for diferente da da gama de destino, não insere nenhum valor.
 
 
 
O conteúdo do cut buffer não é alterado pela operação. Os objectos inseridos no destino são independentes dos que estão no cut buffer.
 
 
 
= Funcionalidade da aplicação =
 
 
 
A aplicação permite manter informação sobre as entidades do modelo. Possui ainda a capacidade de preservar o seu estado (não é possível manter várias versões do estado da aplicação em simultâneo).
 
 
 
Deve ser possível efectuar pesquisas sujeitas a vários critérios e sobre as diferentes entidades geridas pela aplicação.
 
 
 
Uma base de dados textual com conceitos pré-definidos pode ser [[#Leitura de Dados a Partir de Ficheiros Textuais|carregada no início da aplicação]].
 
 
 
{{Suggestion|Note-se que não é necessário nem desejável implementar de raiz a aplicação: já existem classes que representam e definem a interface geral da funcionalidade do ''core'' da aplicação, tal como é visível pelos comandos da aplicação.}}
 
{{CVSCode|A interface geral do ''core'' já está parcialmente implementada na classe '''xxl.Calculator''' e outras fornecidas (cujos nomes devem ser mantidos), devendo ser adaptadas onde necessário. É ainda necessário criar e implementar as restantes classes que suportam a operação da aplicação.}}
 
 
 
== Serialização ==
 
 
 
É possível guardar e recuperar o estado actual da aplicação, preservando toda a informação relevante, descrita acima.
 
 
 
= Requisitos de Desenho =
 
 
 
Devem ser possíveis extensões ou alterações de funcionalidade com impacto mínimo no código produzido: em particular, deve ser simples definir novas funções e novas pesquisas sobre células. O objectivo é aumentar a flexibilidade da aplicação relativamente ao suporte de novas funções. Deve ainda ser possível definir novas políticas de protecção de células.
 
 
 
A estrutura de armazenamento dos conteúdos da folha deve ser flexível, por forma a permitir a representação eficiente de folhas de diferentes dimensões. Assim, deve ser possível usar diferentes estratégias de representação do conteúdo, sem impacto no resto da aplicação. O objectivo deste requisito é optimizar o espaço ocupado em memória para guardar o conteúdo de uma folha de cálculo. Não é necessário concretizar para todas as situações, bastando ser suficientemente flexível para permitir novas implementações.
 
 
 
Uma função depende de células cujo conteúdo pode ser alterado em qualquer instante. Por forma a reduzir o custo de execução do programa sempre que uma célula é alterada, o número de vezes que cada fórmula é calculada deve ser minimizado. Este requisito deve ser considerado apenas depois de tudo estar implementado.
 
 
 
= Interação com o Utilizador =
 
 
 
Descreve-se nesta secção a '''funcionalidade máxima''' da interface com o utilizador. Em geral, os comandos pedem toda a informação antes de procederem à sua validação (excepto onde indicado). Todos os menus têm automaticamente a opção '''Sair''' (fecha o menu).
 
 
 
As operações de pedido e apresentação de informação ao utilizador '''devem''' realizar-se através dos objectos ''form'' e ''display'', respectivamente, presentes em cada comando. As mensagens são produzidas pelos métodos das [[Programação com Objectos/Projecto de Programação com Objectos/Material de Apoio ao Desenvolvimento|bibliotecas de suporte]] ('''po-uilib''' e '''xxl-app'''). As mensagens não podem ser usadas no núcleo da aplicação ('''xxl-core'''). Além disso, não podem ser definidas novas. Potenciais omissões devem ser esclarecidas antes de qualquer implementação.
 
 
 
As excepções usadas na interacção (subclasses de '''pt.tecnico.uilib.menus.CommandException'''), excepto se indicado, são lançadas pelos comandos (subclasses de '''pt.tecnico.uilib.menus.Command''') e tratadas pelos menus (instâncias de subclasses de '''pt.tecnico.uilib.menus.Menu'''). Outras excepções não devem substituir as fornecidas nos casos descritos.
 
 
 
{{CVSCode|Note-se que o programa principal e os comandos e menus, a seguir descritos, já estão parcialmente implementados nas ''packages'' '''xxl.app''', '''xxl.app.---''', '''xxl.app.---''', '''xxl.app.---''', '''xxl.app.---''', '''xxl.app.---'''. Estas classes são de uso obrigatório e estão disponíveis no [[Programação com Objectos/Projecto de Programação com Objectos/Repositório GIT|GIT]] (módulo '''xxl-app''').}}
 
 
 
== Endereçamento de Células ==
 
 
 
Para o pedido de uma gama, utiliza-se a mensagem '''Prompt.address()'''. A excepção '''xxl.app.edit.InvalidCellRangeException''' e lançada se forem especificados endereços inválidos.
 
 
 
== Menu Principal ==
 
As acções deste menu permitem gerir a salvaguarda do estado da aplicação, abrir submenus e aceder a alguma informação global. A lista completa é a seguinte: [[#Salvaguarda do estado actual da aplicação|Abrir]], [[#Salvaguarda do estado actual da aplicação|Guardar]], [[#Gestão e consulta de dados da aplicação|Menu de Edição]], [[#Gestão e consulta de dados da aplicação|Menu de Consultas]].
 
 
 
As etiquetas das opções deste menu estão definidas na classe '''xxl.app.main.Label'''. Todos os métodos correspondentes às mensagens de diálogo para este menu estão definidos na classe '''xxl.app.main.Message'''.
 
 
 
{{CVSCode|Estes comandos já estão implementados nas classes da ''package'' '''xxl.app.main''' (disponível no GIT), respectivamente: '''DoCreateFile''', '''DoOpenFile''', '''DoSaveFile''', '''DoOpenMenuEdit''', '''DoOpenMenuLookup'''.}}
 
 
 
=== Salvaguarda do estado actual da aplicação ===
 
 
 
Inicialmente, a aplicação não tem nenhuma folha. Nesta situação, apenas são apresentadas as opções Criar e Abrir, pois as restantes necessitam uma folha. As opções irrelevantes nesta situação devem ser omitidas.
 
O conteúdo da aplicação (toda a informação actualmente em memória) pode ser guardado para posterior recuperação (via serialização Java: '''java.io.Serializable'''). Na leitura e escrita do estado da aplicação, devem ser tratadas as excepções associadas. A funcionalidade é a seguinte:
 
 
 
* '''Criar''' -- Permite criar de uma nova folha vazia: pedem-se as dimensões da nova folha, devendo ser utilizadas as mensagens '''Prompt.lines()''' e '''Prompt.columns()'''. Esta folha não fica associada a nenhum ficheiro (é anónima).
 
* '''Abrir''' -- Carrega os dados de uma sessão anterior a partir de um ficheiro previamente guardado (ficando este ficheiro associado à aplicação, para futuras operações de salvaguarda). Pede-se o nome do ficheiro a abrir ('''Prompt.openFile()'''). Caso ocorra um problema na abertura ou processamento do ficheiro, deve ser lançada a excepção '''FileOpenFailedException'''. A execução bem-sucedida desta opção substitui toda a informação da aplicação.
 
* '''Guardar''' -- Guarda o estado actual da aplicação no ficheiro associado. Se não existir associação, pede-se o nome do ficheiro a utilizar, ficando a ele associado (para operações de salvaguarda subsequemtes). Esta interacção realiza-se através do método '''Prompt.newSaveAs()'''. Não é executada nenhuma acção se não existirem alterações desde a última salvaguarda.
 
 
 
Apenas existe uma folha na aplicação. Quando se abandona uma folha com modificações não guardadas (porque se cria ou abre outra), deve perguntar-se se se quer guardar a informação actual antes de a abandonar, através de '''Prompt.saveBeforeExit()''' (a resposta é obtida invocando '''readBoolean()'''). A opção “Sair” nunca guarda a folha, mesmo que existam alterações.
 
 
 
Note-se que a opção '''Abrir''' não permite a leitura de ficheiros de texto (estes apenas podem ser utilizados no início da aplicação).
 
 
 
A opção '''Sair''' nunca implica a salvaguarda do estado da aplicação, mesmo que existam alterações.
 
 
 
=== Gestão e consulta de dados da aplicação ===
 
 
 
Além das operações de manipulação de ficheiros, existem ainda no menu principal as seguintes opções. Estas opções só estão disponíveis quando existir uma folha activa válida.
 
 
 
* '''Menu de Edição''' -- Abre o menu de edição.
 
* '''Menu de Consultas''' -- Abre o menu de consultas (pesquisas).
 
 
 
== Menu de Edição ==
 
 
 
O menu de edição permite visualizar e alterar o conteúdo das células da folha activa. A lista completa é a seguinte: Visualizar, Inserir, Apagar, Copiar, Cortar, Colar e Visualizar cut buffer. As secções abaixo descrevem estas opções.
 
 
 
As opções deste menu estão definidas na classe calc.textui.edit.MenuEntry. Todos os métodos correspondentes às mensagens de diálogo para as acções do menu estão definidos na classe calc.textui.edit.Message.
 
 
 
{{CVSCode|Estes comandos já estão implementados nas classes da ''package'' '''xxl.app.main''' (disponível no GIT), respectivamente: '''DoCreateFile''', '''DoOpenFile''', '''DoSaveFile''', '''DoOpenMenuEdit''', '''DoOpenMenuLookup'''.}}
 
 
 
=== Visualizar ===
 
 
 
Permite visualizar a gama especificada ([[#Endereçamento: Células, Intervalos, Gamas|Endereçamento]]), conforme as indicações da tabela. Se o conteúdo não for um literal, deve ser apresentado o seu valor e a sua expressão. Não deve ser apresentado qualquer conteúdo para células vazias.
 
 
 
{|
 
| '''Célula, Referências, Funções'''
 
| '''Intervalo Vertical'''
 
| '''Intervalo Horizontal'''
 
|-
 
| <nowiki>linha;coluna| </nowiki>
 
| <nowiki>linha1;coluna|conteudo</nowiki>
 
| <nowiki>linha;coluna1|conteudo</nowiki>
 
|-
 
| <nowiki>linha;coluna|conteudo</nowiki>
 
| <nowiki>linha2;coluna|conteudo</nowiki>
 
| <nowiki>linha;coluna2|conteudo</nowiki>
 
|-
 
| <nowiki>linha;coluna|valor=expressão</nowiki>
 
| <nowiki>linha3;coluna|conteudo</nowiki>
 
| <nowiki>linha;coluna3|conteudo</nowiki>
 
|}
 
 
 
=== Inserir ===
 
 
 
É especificada a gama ([[#Endereçamento: Células, Intervalos, Gamas|Endereçamento]]). É especificado o conteúdo a inserir ([[#Conteúdo: Literais, Referências, Funções|Conteúdo]]), através da mensagem '''Prompt.contents()'''. O conteúdo é inserido em todas as células da gama. Por simplicidade, não são inseridos nomes de funções inexistentes.
 
 
 
=== Copiar ===
 
 
 
É especificada a gama ([[#Endereçamento: Células, Intervalos, Gamas|Endereçamento]]) cujo conteúdo deve ser copiado para o cut buffer.<!-- Os conteúdos copiados são independentes da folha (i.e., alterações aos originais não são propagadas para o cut buffer).-->
 
 
 
=== Apagar ===
 
 
 
É especificada a gama ([[#Endereçamento: Células, Intervalos, Gamas|Endereçamento]]) cujo conteúdo deve ser apagado.
 
 
 
=== Cortar ===
 
 
 
Esta acção corresponde à execução sequencial das acções descritas em [[#Copiar|Copia]] e [[#Apagar|Apagar]].
 
 
 
=== Colar ===
 
 
 
Insere o conteúdo do cut buffer na gama especificada ([[#Endereçamento: Células, Intervalos, Gamas|Endereçamento]]).
 
 
 
=== Visualizar cut buffer ===
 
 
 
Permite visualizar o conteúdo do cut buffer. O formato de apresentação é o descrito em [[#Visualizar|Visualizar]].
 
 
 
== Menu de Consultas ==
 
 
 
Permite efectuar pesquisas sobre as células da folha activa, produzindo listas de células. As células resultantes são apresentadas pela ordem em que aparecem na tabela ([[#Visualizar|Visualizar]]). As entradas do menu estão definidas em calc.textui.search.MenuEntry.
 
 
 
As mensagens estão definidas em calc.textui.search.Message.
 
 
 
O termo de pesquisa deve ser comparado com o valor avaliado de cada célula. Assim, considerando as expressões iniciais das células indicadas de seguida, uma pesquisa pelo valor 5 encontraria as células 1;3 e 2;1.
 
 
 
1;1|4
 
1;2|1
 
1;3|5
 
2;1|5=ADD(1;1,1;2)
 
2;2|
 
2;3|
 
 
 
Sempre que for feita uma consulta e nenhuma entidade satisfizer as condições associadas ao pedido, nada deve ser apresentado.
 
 
 
{{CVSCode|Estes comandos já estão implementados nas classes da ''package'' '''prr.app.clients''' (disponível no GIT), respectivamente: '''DoShowClient''', '''DoShowAllClients''', '''DoRegisterClient''', '''DoEnableClientNotifications''', '''DoDisableClientNotifications''', '''DoShowClientPaymentsAndDebts'''.}}
 
 
 
=== Procurar Valor ===
 
Pede-se o valor a procurar (mensagem searchValue()) e apresentam-se os resultados.
 
===Procurar Função ===
 
 
 
Pede-se o nome da função a procurar (mensagem searchFunction()) e apresentam-se os resultados.
 
 
 
= Inicialização por Ficheiro de Dados Textuais =
 
 
 
Por omissão, quando a aplicação começa, não existe nenhuma folha activa. Além das opções de manipulação de ficheiros descritas no [[#Salvaguarda do Documento Actual|menu principal]], é possível iniciar a aplicação com um ficheiro de texto especificado pela propriedade Java '''[[#Execução dos Programas e Testes Automáticos|import]]'''.
 
 
 
As várias entidades têm os formatos descritos abaixo. Sugere-se a utilização do método '''String.split''' para o processamento preliminar destas linhas. Não existem entradas mal-formadas.
 
 
 
Além das [[#Salvaguarda do estado actual da aplicação|opções descritas acima]], é possível iniciar a aplicação utilizado um ficheiro de texto especificado pela propriedade Java import (apresentada abaixo; este exemplo está presente no ficheiro test.import). Os dados textuais são apenas uma forma cómoda de inicialização e nunca são produzidos pela aplicação (nem mesmo para salvaguardar o estado para execuções futuras). Quando se especifica a propriedade, é criada uma folha activa anónima que representa o conteúdo do ficheiro indicado.
 
 
 
No processamento destes dados, assume-se que não há entradas mal-formadas (células não referidas são vazias). Sugere-se a utilização do método '''String.split()''', para dividir uma cadeia de caracteres em campos.
 
 
 
As duas primeiras linhas definem o número de linhas e de colunas da folha de cálculo. As restantes linhas contêm sempre o formato linha;coluna|conteúdo (o campo conteúdo está descrito em [[#Conteúdo: Literais, Referências, Funções|Conteúdo]]).
 
 
 
No seguinte exemplo, o conteúdo do ficheiro inicial ('''test.import''') correspondente à folha apresentada a seguir.
 
{{CollapsedCode|Exemplo de ficheiro de entrada textual|
 
<source lang="text">
 
linhas=4
 
colunas=3
 
3;3|=ADD(3;1,3;2)
 
4;1|
 
1;1|5
 
1;2|49
 
2;1|25 
 
2;2|43
 
2;3|=ADD(2;2,5)
 
3;1|10
 
3;2|=1;1
 
1;3|=ADD(2,5)
 
4;3|=AVG(1;3:3;3)
 
4;2|
 
</source>
 
}}
 
 
 
{| style="width: 30%;"
 
|
 
| &nbsp;&nbsp;&nbsp;1&nbsp;&nbsp;&nbsp;
 
| &nbsp;&nbsp;&nbsp;2&nbsp;&nbsp;&nbsp;
 
| &nbsp;&nbsp;&nbsp;3&nbsp;&nbsp;&nbsp;
 
|-
 
| &nbsp;&nbsp;&nbsp;1&nbsp;&nbsp;&nbsp;
 
| 5
 
| 49
 
| =ADD(2,5)
 
|-
 
| &nbsp;&nbsp;&nbsp;2&nbsp;&nbsp;&nbsp;
 
| 25
 
| 43
 
| =ADD(2;2,5)
 
|-
 
| &nbsp;&nbsp;&nbsp;3&nbsp;&nbsp;&nbsp;
 
| 10
 
| =1;1
 
| =ADD(3;1,3;2)
 
|-
 
| &nbsp;&nbsp;&nbsp;4&nbsp;&nbsp;&nbsp;
 
|
 
|
 
| =AVG(1;3,3;3)
 
|}
 
A codificação dos ficheiros a ler é garantidamente [[wp:UTF-8|UTF-8]].
 
 
 
{{Suggestion|Note-se que o programa nunca produz ficheiros com este formato.}}
 
 
 
= Execução dos Programas e Testes Automáticos =
 
 
 
Usando os ficheiros '''test.import''', '''test.in''' e '''test.out''', é possível verificar automaticamente o resultado correcto do programa. Note-se que é necessária a definição apropriada da variável '''CLASSPATH''' (ou da opção equivalente '''-cp''' do comando '''java'''), para localizar as classes do programa, incluindo a que contém o método correspondente ao ponto de entrada da aplicação ('''prr.app.App.main'''). As propriedades são tratadas automaticamente pelo código de apoio.
 
 
 
        java -Dimport=test.import -Din=test.in -Dout=test.outhyp xxl.app.App
 
 
 
Assumindo que aqueles ficheiros estão no directório onde é dado o comando de execução, o programa produz o ficheiro de saída '''test.outhyp'''. Em caso de sucesso, os ficheiros das saídas esperada ('''test.out''') e obtida ('''test.outhyp''') devem ser iguais. A comparação pode ser feita com o comando:
 
 
 
        diff -b test.out test.outhyp
 
 
 
Este comando não deve produzir qualquer resultado quando os ficheiros são iguais. Note-se, contudo, que este teste não garante o correcto funcionamento do código desenvolvido, apenas verificando alguns aspectos da sua funcionalidade.
 
 
 
[[category: Ensino]]
 
[[category:PO]]
 
[[category:Projecto de PO]]
 
[[en:Object-Oriented Programming]]
 

Latest revision as of 18:17, 12 September 2023