Glossário
Ao longo do tutorial aparecem muitos termos novos: do labirinto, das contas com bits, do Python, das ferramentas e da arquitetura. Cada página explica os seus, mas um termo explicado lá atrás pode ser esquecido. Esta página reúne os termos, cada um com uma frase e o link para a página que o explica em detalhe.
O labirinto
| Termo | Significado |
|---|---|
| grade | o retângulo de células que forma o labirinto, com WIDTH colunas e HEIGHT linhas. Veja |
| célula | um quadradinho da grade. Veja |
| lado | cada uma das quatro bordas de uma célula: Norte (em cima), Leste (à direita), Sul (embaixo) e Oeste (à esquerda). Veja |
| parede | um lado fechado: não dá para passar por ali. Veja |
| passagem | um lado aberto entre duas células vizinhas: dá para andar de uma para a outra. Veja |
| borda | os lados que dão para fora da grade; são sempre paredes, inclusive na entrada e na saída. Veja |
coordenada x,y | o endereço de uma célula: x é a posição na horizontal (a coluna) e y na vertical (a linha), contando de 0 a partir do canto de cima à esquerda; no código, grid[y][x]. Veja |
| vizinha | a célula colada a outra por um dos quatro lados; uma célula da borda tem menos vizinhas. Veja |
| coerência | a regra de que duas células vizinhas concordam sobre a parede que dividem. Veja |
| entrada e saída | duas células escolhidas no arquivo de opções; o caminho mais curto vai de uma à outra. Veja |
| corredor | uma célula livre do labirinto, que dá para alcançar andando; só as células do "42" não são corredores. Veja |
| o "42" | o número 42 desenhado no meio do labirinto por 18 células com as quatro paredes fechadas, fora do labirinto. Veja |
| beco sem saída | uma célula com uma única abertura: quem entra só sai por onde entrou. Veja |
| beco real | um beco que tem pelo menos uma parede dando para uma célula livre, e que por isso dá para abrir; é o que conta na regra "no máximo dois becos". Veja |
| beco cercado | um beco em que todas as paredes fechadas dão para a borda da grade ou para o "42": não há parede que dê para abrir, e ele não conta como beco real. Exemplo: as duas células dentro das curvas do "2", cercadas pelo "42" em três lados, que todo "42" cria. Veja |
| ciclo | um caminho que dá a volta e termina na célula onde começou; existe quando há duas rotas diferentes entre duas células. Veja |
| rotas independentes | ciclos que não são combinação de outros; o tabuleiro Pac-Man precisa de pelo menos dois. Veja |
| labirinto perfeito | labirinto sem nenhum ciclo: entre duas células existe exatamente um caminho. Veja |
| árvore geradora | o nome, em teoria dos grafos, de um conjunto de ligações que conecta tudo sem formar ciclo; é a forma de um labirinto perfeito. Veja |
| tabuleiro Pac-Man | labirinto com ciclos e quase sem becos, onde quem foge sempre tem outra rota; o enunciado o chama de modo padrão. Veja |
| braiding | ("trançar") transformar um labirinto perfeito num tabuleiro Pac-Man, abrindo paredes dos becos e criando ciclos. Veja |
| área aberta 3x3 (salão) | um bloco de 3x3 células sem nenhuma parede por dentro; proibido pelo enunciado. Veja |
| janela | no código, um bloco 3x3 da grade que o programa examina para ver se virou um salão. Veja |
| caminho mais curto | a menor sequência de passos da entrada à saída, escrita com as letras N, E, S, W. Veja |
| arquivo de configuração | o arquivo de texto com as opções (WIDTH, HEIGHT, ENTRY, ...), uma CHAVE=valor por linha; o do projeto é o config.txt. Veja |
| arquivo de saída | o arquivo de texto em que o programa grava o labirinto, um caractere hexadecimal por célula. Veja |
| quadro | a tabela de posições do desenho no terminal: uma posição por célula, por parede e por canto, 2 × WIDTH + 1 de largura. Veja |
Números e algoritmos
| Termo | Significado |
|---|---|
| bit | um dígito binário, 0 ou 1. Cada lado de uma célula ocupa um bit: 1 = parede, 0 = passagem. Veja |
| binário | o jeito de escrever números só com 0 e 1; cada casa, da direita para a esquerda, vale o dobro da anterior (1, 2, 4, 8). No Python, um número binário se escreve com 0b na frente: 0b1001 é 9. Veja |
| hexadecimal | o jeito de escrever números de 0 a 15 com um só caractere: 0 a 9 e depois a (10) a f (15). Veja |
| operações de bit | & ("e" bit a bit), | ("ou" bit a bit) e ~ (inverte os bits): as contas que perguntam por uma parede, abrem e fecham. Veja |
divisão inteira (//) | a divisão que joga fora a parte quebrada: 13 // 2 dá 6. Veja |
| semente (seed) | um número que fixa o sorteio: com a mesma semente, o programa gera sempre o mesmo labirinto. Veja |
| grafo | um desenho de pontos ligados por traços; num labirinto, cada célula é um ponto e cada passagem um traço. Veja |
| backtracker | o algoritmo que cava o labirinto perfeito: anda sorteando caminhos e volta atrás quando fica sem saída. Veja |
| pilha | uma lista em que só se mexe numa ponta, o topo: o último que entra é o primeiro que sai. Veja |
| recursão | uma função que chama a si mesma; o Carver usa uma pilha no lugar dela. Veja |
| BFS | busca em largura: o algoritmo que acha o caminho mais curto explorando primeiro as células mais próximas. Veja |
| fila | uma lista em que se entra por uma ponta e se sai pela outra: o primeiro que entra é o primeiro que sai; em Python, um collections.deque. Veja |
Python
| Termo | Significado |
|---|---|
| módulo | um arquivo .py; mazegen/errors.py é o módulo mazegen.errors. Veja |
| pacote | uma pasta com um arquivo __init__.py, que o Python importa pelo nome; mazegen/ é o pacote mazegen. Veja |
__init__.py | o arquivo que faz de uma pasta um pacote; o código dele roda na primeira vez que o pacote é importado. Veja |
| docstring | o texto entre """ logo no começo de um módulo, classe ou função, que documenta o que ele faz. Veja |
| anotação de tipo | a indicação do tipo de um parâmetro ou retorno, como em def soma(a: int, b: int) -> int:; o mypy confere. Veja |
| compreensão de lista | (list comprehension) um laço for entre colchetes que monta uma lista: [n * 2 for n in range(4)]; com chaves, monta um conjunto (compreensão de conjunto). Veja |
| função geradora | uma função com yield, que entrega os valores um de cada vez em vez de montar uma lista inteira. Veja |
| expressão geradora | uma compreensão entre parênteses, que produz os itens um de cada vez para quem a consome. Veja |
| f-string | um texto com f antes das aspas, em que cada {nome} é trocado pelo valor da variável. Veja |
| exceção | um objeto de erro: o código o levanta com raise, e quem chamou o captura com try/except. Veja |
| decorador | a linha com @ em cima de um def ou class, que muda o jeito de usar o que vem abaixo. Veja |
@property | decorador que faz um método ser lido como atributo, sem parênteses. Veja |
@classmethod | decorador de um método chamado pela classe, que recebe a classe em cls. Veja |
@staticmethod | decorador de um método que não usa o objeto nem a classe. Veja |
| Enum e IntEnum | uma classe com uma lista fechada de valores com nome; no IntEnum, os valores também são números inteiros. Veja |
| dataclass | uma classe marcada com @dataclass, que ganha sozinha o construtor e a comparação a partir dos campos. Veja |
frozen=True | opção da dataclass que impede mudar os campos depois de criado o objeto. Veja |
slots=True | opção da dataclass que reserva espaço só para os campos declarados, sem aceitar atributos novos. Veja |
| hash | um número calculado a partir do conteúdo de um objeto, que o set e o dict usam para achá-lo rápido. Veja |
frozenset | o conjunto (set) imutável do Python. Veja |
__contains__ | o método que o Python chama para responder x in objeto. Veja |
Protocol | um recurso de typing que descreve os métodos que um objeto precisa ter, sem herança. Veja |
__all__ | a lista dos nomes que um pacote oferece a quem o importa: a API pública dele. Veja |
| bytecode | a tradução que o Python faz de um módulo na primeira importação, guardada em __pycache__. Veja |
| traceback | a listagem de erro que o Python imprime quando uma exceção não é tratada; o programa nunca deve mostrá-la ao usuário. Veja |
| stdout e stderr | as duas saídas de texto de um programa: a normal e a de erros. Veja |
| código de saída | o número que o programa devolve ao terminar: 0 é sucesso, outro valor é erro; no terminal, aparece com echo $?. Veja |
sys.argv | a lista com os argumentos da linha de comando; o main do projeto recebe sys.argv[1:], sem o nome do script. Veja |
| UTF-8 | a tabela mais usada para transformar letras em bytes num arquivo de texto. Veja |
Ferramentas e entrega
| Termo | Significado |
|---|---|
| ambiente virtual (venv) | uma pasta .venv com um Python e bibliotecas só deste projeto, separados do resto do computador. Veja |
pip | o programa que baixa e instala bibliotecas Python. Veja |
| Makefile | arquivo com atalhos de comandos: make install, make run, make lint... Veja |
| alvo | o nome de uma regra do Makefile, usado no terminal: o lint de make lint. Veja |
depurador (pdb) | o programa que vem com o Python para rodar outro passo a passo; a regra debug o usa. Veja |
| lint | verificar o código sem executá-lo, à procura de erros e de desvios do padrão. Veja |
| flake8 | ferramenta de lint que confere o estilo do código. Veja |
| PEP 8 | o guia de estilo oficial do Python: linhas de até 79 caracteres, espaços em volta de operadores... Veja |
| mypy | ferramenta que confere as anotações de tipo do código. Veja |
pyproject.toml | o arquivo que descreve o pacote do gerador: nome, versão e como construí-lo; escrito no formato TOML. Veja |
.gitignore | a lista de arquivos gerados que o git não guarda. Veja |
wheel (.whl) e sdist (.tar.gz) | os dois formatos de arquivo em que um pacote Python é distribuído e instalado com pip. Veja |
| licença MIT | a licença do projeto: permite a qualquer um usar, copiar e redistribuir o gerador. Veja |
maze_analyzer.py | o verificador que acompanha o enunciado: lê um arquivo de saída e diz se o labirinto cumpre as regras. Veja |
| ANSI | as sequências de caracteres especiais que mandam o terminal mudar de cor. Veja |
| SGR | a sequência ANSI que escolhe a cor (Select Graphic Rendition). Veja |
Arquitetura
| Termo | Significado |
|---|---|
| camada | um grupo de classes com o mesmo papel, num dos anéis da arquitetura. Veja |
| Clean Architecture | ("arquitetura limpa") o estilo de organizar o código em anéis, com as regras no centro e os detalhes (arquivos, terminal) na borda. Veja |
| regra de dependência | o código de uma camada importa a própria camada e os anéis mais para dentro, nunca mais para fora; camadas diferentes do mesmo anel não se importam. Veja |
| inversão de dependência | o centro declara o que precisa (uma porta), e a borda fornece; assim o centro não importa a borda. Veja |
| domínio | os dados com que a aplicação trabalha (a configuração lida, o labirinto pronto, o estado da tela), sem arquivo e sem terminal. Veja |
| value object | um objeto que é só um valor: não muda depois de criado e é comparado pelo conteúdo (ex.: uma coordenada). Veja |
| método de fábrica | um método que recebe os dados, aplica a regra de criação e devolve o objeto pronto. Veja |
| entidade | um objeto cujo estado muda, mas que protege as próprias regras (ex.: a grade de paredes). Veja |
| service | uma classe que só executa uma operação, sem guardar estado (ex.: o algoritmo que cava). Veja |
| use case | uma operação completa da aplicação, num único método execute. Veja |
| porta (port) | a descrição do que uma classe precisa de outra (os métodos e os tipos), sem dizer quem vai fornecer. Veja |
| fachada | uma classe que fica na frente de várias outras e oferece um jeito simples de usá-las; aqui, o MazeGenerator. Veja |
| repository | a classe que lê ou grava arquivos; a única camada que mexe em disco. Veja |
| retrato | um value object com tudo o que se sabe de um labirinto pronto, tirado de uma vez: o GeneratedMaze. Veja |
| composition root | o ponto do programa que cria todas as peças e as liga; aqui, a função main do a_maze_ing.py. Veja |
As classes do projeto
| Classe | O que faz |
|---|---|
MazeError | o erro do gerador: um parâmetro impossível ou um tabuleiro que não deu certo. Veja |
Direction | os quatro lados de uma célula, cada um com o seu bit. Veja |
Cell | a posição x,y de uma célula. Veja |
Pattern42 | as células do "42" para um tamanho de grade. Veja |
Maze | a grade de paredes, com as perguntas e as mudanças que se faz nela. Veja |
Carver | o algoritmo que cava o labirinto perfeito. Veja |
Solver | o algoritmo que acha o caminho mais curto. Veja |
Braider | o algoritmo que transforma o labirinto perfeito num tabuleiro Pac-Man. Veja |
MazeGenerator | a fachada do gerador: a única classe que outro projeto precisa usar. Veja |
AppError | o erro da aplicação, com as variações ConfigError e OutputError. Veja |
ValueParser | converte o texto de uma opção em número, True/False ou coordenada. Veja |
Ansi | as sequências de cor do terminal. Veja |
MazeConfig | as opções lidas do arquivo de configuração, já validadas. Veja |
FileConfigRepository | lê o arquivo de configuração e devolve um MazeConfig. Veja |
GeneratedMaze | o retrato do labirinto pronto: grade, entrada, saída, caminho e "42". Veja |
MazeRepository | a porta que diz como um labirinto é gravado. Veja |
FileMazeRepository | grava o labirinto no arquivo de saída. Veja |
GenerateMaze | o use case que gera um labirinto, grava e devolve o retrato. Veja |
ViewState | o estado da tela: caminho visível ou não e a cor atual das paredes. Veja |
RenderService | transforma o labirinto nas linhas coloridas do terminal. Veja |
Menu | mostra o labirinto e o menu e responde às escolhas do usuário. Veja |