Prazo de entrega recomendado:
Nesta tarefa, você irá construir um de gerenciador de documentos. Para isso, será necessário escolher e utilizar estruturas de dados adequadas para representar conjuntos de dados.
Não muito tempo atrás, guardávamos nossos dados apenas nos computadores pessoais. Esses dados eram de todo tipo de arquivo, como fotos, documentos de texto, planilhas, e eram guardados no disco rígido, organizados na mais cuidadosa hierarquia do sistema de arquivos.
Tudo muito bom, tudo muito bem, até precisarmos compartilhar um
documento com algum colega. Então precisávamos comprar um pen
drive disquete que poderíamos entregar a outra pessoa. O problema
disso é que, não só o disquete não era um meio muito confiável, mas
isso criava duas versões do mesmo arquivo. Quando recebíamos o arquivo
de volta, tínhamos que ter certeza de que não havíamos modificado a
versão original. Pior, se tivéssemos modificado, teríamos que comparar
palavra por palavra.
Com a popularização da internet surgiu um alternativa: guardarmos o arquivo em um servidor centralizado e editarmos esse arquivo diretamente usando o navegador. São várias as opções disponíveis de gerenciadores de documentos e suítes de escritório online, Google Docs, Office Online, Dropbox, etc. Cada um com uma interface diferente.
Embora muito práticas e fáceis de usar, essas ferramentas trazem duas complicações importantes que não existiam antes.
-
Como não existe mais uma hierarquia de arquivos pessoais bem organizada, precisamos encontrar, entre as centenas ou milhares de arquivos existentes, aqueles que contêm uma ou mais palavras de busca. E devemos fazer isso muito rapidamente.
-
Como vários usuários podem editar um documento ao mesmo tempo, não podemos mais guardar um arquivo apenas quando terminamos de editá-lo. Ao invés disso, toda vez que fazemos qualquer edição em um arquivo, enviamos um comando ao servidor pela internet e aguardamos a resposta.
Nesta tarefa, você irá criar um novo gerenciador de documentos com o
objetivo de desbancar as soluções existentes. O diferencial: seu
gerenciador de documentos é voltado para programadores, então
implementaremos apenas a interface de comandos — e cada programador
pode criar a interface mais adequada para seus usuários!
Você irá criar um programa chamado gerenciador.py
que será capaz
de executar uma série de comandos especificados neste enunciado.
Por enquanto, implementaremos apenas um protótipo com diversas simplificações. Uma delas é que nosso gerenciador de documentos não armazenará os arquivos de fato e guardará os dados apenas em memória. Além disso, ele permite apenas criar e editar arquivos de texto. Cada arquivo existente contém as seguintes propriedades:
- nome do arquivo;
- texto do conteúdo;
- nome de usuário que criou o arquivo;
- data da criação.
Lembre-se de que você deve definir uma representação em memória adequada para cada tipo de objeto abstraído. Para cada tipo, você deve armazenar e escolher as estruturas de dados que julgar necessárias ou convenientes para implementar os diferentes comandos de seu gerenciador.
Entrada
A entrada consiste de uma sequência de comandos, um por linha. Em cada
momento, deve haver exatamente um usuário ativo e cada comando será
executado por esse usuário. Assim, o primeiro comando será sempre
entrar <nome>
, para descrever o primeiro usuário ativo. A entrada
termina quando for executado o comando terminar
.
entrar laura
criar frutas.txt
digitar frutas.txt banana
digitar frutas.txt abacaxi pera
digitar frutas.txt jabuticaba banana
substituir frutas.txt abacaxi goiaba
entrar pedro
buscar banana
mostrar frutas.txt
terminar
Saída
Cada uma dos comandos produz uma saída de texto. Por exemplo, o
comando mostrar
exibe o conteúdo de um arquivo.
laura entrou!
frutas.txt criado
frutas.txt modificado: 1 linhas
frutas.txt modificado: 2 linhas
frutas.txt modificado: 3 linhas
frutas.txt modificado: 3 linhas
pedro entrou!
frutas.txt contém banana
1 arquivos encontrados
--- início de frutas.txt ---
banana
goiaba pera
jabuticaba banana
--- final de frutas.txt ---
até mais!
Comandos
O conjunto completo de comandos está listado abaixo.
-
terminar
Mostra a mensagem
até mais!
e encerra a execução do programa. -
entrar <usuário>
Altera o usuário ativo e mostra a mensagem
<usuário> entrou!
. -
criar <arquivo>
Cria um novo arquivo vazio com o nome fornecido se já não existir. A resposta deve ser
arquivo <arquivo> criado
ouarquivo <arquivo> existente
. -
carregar <arquivo_local> <arquivo>
Cria um novo arquivo com o conteúdo de um aquivo local armazenado no seu computador. Por exemplo:
carregar dados/arquivo_local.txt novo_arquivo.txt
. A resposta deve ser<arquivo_local> carregado como <arquivo>
. Você pode supor que ainda não existe aquivo com o mesmo nome no gerenciador. -
digitar <arquivo> <linha de texto>
Acrescenta uma linha de texto no final do arquivo e mostra mensagem
<arquivo> modificado: <numero> linhas
com o número de linhas do arquivo. -
mostrar <arquivo>
Mostra todo o conteúdo do arquivo entre linhas demarcadoras:
--- início de frutas.txt --- ... conteúdo ... --- final de frutas.txt ---
-
substituir <arquivo> <termo> <substituto>
Substitui todas as ocorrências do termo no arquivo e mostra mensagem
<arquivo> modificado: <numero> linhas
com o número de linhas do arquivo. -
listar
oulistar -t
Mostra a lista de arquivos existentes. Para cada arquivo, é mostrada uma linha com
<arquivo> <usuário>
. Por padrão, os arquivos são listados em ordem alfabética. Caso seja passado o argumento opcional-t
, então os arquivos são listados em ordem de criação.Ao final, mostra a mensagem
<numero> arquivos existentes
, onde<numero>
é a quantidade de arquivos que há no gerenciador. -
buscar <termo>
Lista os arquivos que contêm o termo buscado, um por linha e em ordem alfabética. Para cada arquivo encontrado, o comando mostra uma linha com a mensagem
<arquivo> contém <termo>
.Ao final, o comando mostra
<numero> arquivos encontrados
, onde<numero>
é a quantidade de arquivos que contêm o termo procurado. -
comparar <arquivo1> <arquivo2>
Mostra diferença entre dois arquivos, linha por linha, em um formato similar à saída do comando
diff
do Unix. Você pode supor que os dois arquivos têm o mesmo número de linhas e todas as linhas diferentes são adjacentes. Veja o exemplo:a.txt
Já vai embora? Viver é que nem andar de bicicleta. Se parar, cai.
b.txt
Já vai embora? Programar é que nem andar na corda bamba. Se parar, cai.
saída do diff
< Viver é que nem < andar de bicicleta. --- > Programar é que nem > andar na corda bamba.
Simplificações
Nas substituições e buscas de palavras, serão consideradas apenas
palavras completas. Por exemplo, os resultados de uma busca por ama
não incluem amargo
, grama
. Você pode supor que não existem palavas
com caracteres de pontuações adjacentes, como ama,
. Além disso, as
operações são case-sensitive, isto é, são consideradas diferentes as
palavras ama
e Ama
.
Critérios
Nesta tarefa você deverá usar apenas as estruturas de dados fornecidas por padrão na linguagem Python.
Correção
Esta tarefa será corrigida automaticamente sempre que você realizar um
git push
. Depois de submetida a versão final da tarefa, você deverá
apresentá-la a um monitor PED. Para isso, você deve procurar
atendimento em algum horário com monitor PED e digitar apresentar 8
no canal fila-apresentar
para entrar na fila.