Pessoal, boa noite.
Estamos no dia 22 de julho de 2020,
uma quarta-feira.
Estou aqui pra falar pra vocês do Grupo de Slides número 10 - Parte B.
Cuja temática é
utilização efetiva e desacoplada de lista encadeada com templates.
Bom, justamente, na aula passada, na exposição passada
ficou posto se a gente não conseguia uma solução melhor que a apresentada
no sentido de continuar tendo uma lista template
aonde a gente, entretanto, conseguisse um equilíbrio
entre generalidade e especificidade
sem violar a coesão e o desacoplamento.
Bom, justamente, o que a gente vai trabalhar nessa aula
é uma solução buscando esse equilíbrio citado
Aqui, o Grupo de Slides foi feito com o apoio do então Monitor
Fabiano Cezar Domingos, lá nos ides de 2013.
Melhorando a solução apresentada no Grupo de Slides 10 - Parte A.
De fato.
A solução começa sendo melhorada comentando ou eliminando
aquela questão de poder replicar dados, particularmente, o nome
dentro de cada Elemento.
Aqui, a gente tá na classe obviamente Elemento template parametrizado com um TIPO.
Agora a gente não vai permitir que a gente replique em Elemento informações
de nome de objetos que serão tratados por esses Elementos,
no âmbito de listas encadeadas.
Claro, no contexto do template dado.
Aqui, nós temos a parte implementação
da nossa lista encadeada,
não é isso?
Lembrando que lista aqui, no caso, template, né,
dessa lista encadeada, dessa lista em geral, template enfim,
é tudo feito no .h.
Como aqui a gente tá fazendo uma... Elementos, visando uma lista encadeada
então, esse template Elemento
ele vai ficar tanto a parte de especificação da classe
quanto a parte de implementação dos métodos da classe,
tudo no .h pertinente,
cito, Elemento.h.
Então, esse Elemento ele, em relação ao Grupo de Slides anterior,
o que modificou foi que ele não tem mais esses
nome, setNome e getNome.
Enquanto aqui eu comentei set e getNome,
pra cá fica... nem aparece, inclusive.
Não é isso?
O atributo, voltando um pouquinho aí, tá,
o atributo nome da classe Elemento não deve existir.
Deve-se evitar a replicação de dados.
Dados necessários para uma posterior listagem
devem ser obtidos através do ponteiro pInfo.
O que, de fato, procede.
Então, aqui, eu insisto,
eu tirei, eu comentei esses elementos aqui,
o atributo nome os sets e gets
e já na implementação
eu já nem sequer comentei, eu já tirei efetivamente, tá,
Não existe mais aqui, nome, setNome e getNome.
Bom, particularmente, setNome e getNome, bem entendido,
já que a gente tá na parte de implementação, obviamente.
O resto continua aí.
Construtora, destrutora de Elemento, setProximo e getProximo,
o setAnterior, getAnterior, setInfo e o getInfo.
Tudo, claro, trabalhando em termos de template,
conforme explicado na exposição anterior.
Agora, vamos pra classe Lista.
Lista template, bem entendido.
A Lista template não deve possuir
métodos para listar os dados.
Não há como generalizar os algoritmos de listagem.
Quando a gente tenta generalizar, a gente percebeu na solução dada no Grupo de Slides anterior
que a solução não fica elegante.
Até há alguma maneira de você generalizar,
mas pagando preço de replicar dados
daí violando coesão e desacoplamento.
Então, não há como generalizar os algoritmos de listagem, né,
nesse sentido do contexto dado
e de respeitar a coesão e o desacoplamento, bem entendido.
Aqui, tá, então, o que a gente fez foi
eliminar o listeInfos, tá. Não tem mais listeInfos.
E aqui também teve algumas modificações no incluaElemento.
Antes o incluaElemento, se você for no Grupo de Slides anterior,
ele tinha um segundo parâmetro que era justamente o nome,
agora não vai ter mais nome aqui, né.
Tudo o que a gente não quer é replicar informação dentro dos Elementos.
E aqui ficou então, no final das contas,
na classe Lista template, só o que é algoritmo realmente genérico.
Conforme já explicado na aula anterior,
na exposição anterior, a inclusão é algo genérico,
a exclusão é algo genérico.
Aqui nós temos a definição da classe Lista, conforme vocês tão vendo,
e aí, como é template, ainda no .h,
a gente vai ter a especificação aqui, né, da implementação dos métodos.
Tá aqui a construtora que chama o inicializa.
Tem a destrutora que chama o limpar.
Então, o inicializa aterra o ponteiro pPrimeiro e o pAtual.
O getpPrimeiro, o getpAtual.
Aqui não foi colocado sets
porque aparentemente não tá sendo necessário,
se fosse necessário não teria dificuldade.
De fato está só com os gets mesmo.
Está sem os sets.
Aqui tem o limpar, tinha ficado como exercício da aula anterior,
então tá aqui posto uma maneira de limpar.
O incluaInfo que vocês já conhecem, tá.
Talvez um pouquinho mais
apresentado de maneira mais organizada,
com os devidos espaçamentos.
O incluaInfo que vai receber
uma dada informação, um dado dado.
Por exemplo se o tipo for ponteiro de Aluno,
então ele vai receber um endereço de Aluno, ué.
Se o TIPO for Aluno, aliás, como eu tenho o asterisco na frente aqui,
aí o pInfo vai ser o ponteiro da coisa,
a coisa que seria Aluno.
Então, eu vou ser capaz, através de um ponteiro de Aluno,
receber o endereço de Aluno e encadear na minha Lista.
Ora, pra gerenciar esse suposto Aluno,
eu vou criar um novo Elemento parametrizado com Aluno.
O que permite, né, criar um Elemento que gerencie Alunos na prática.
Você veja que agora em Elemento não tem mais a replicação de nome,
porque isso foi abolido aqui na nossa nova organização.
O que eu faço, sim, é o Elemento conhecer
o cara que tá sendo tratado aqui na lista.
Uma vez que o Elemento conhece o cara,
é criado e conhece o cara e que vai estar lá na lista,
aí esse Elemento é incluído nos encadeamentos de próximo e anterior e assim vai,
através da função incluaElemento que tá aqui e vocês já conhecem.
Aqui tem uns códigos comentados, tá, que funcionam
mas eram prolixos, tá, eram redundantes, então eu comentei,
mas deixei esses pra reflexão da produtividade.
Agora a gente fez, então, uma lista, que é template à luz
de si mesma e do Elemento template
que não tem mais tentativas ineficazes de generalizar listagens.
É feito só o que realmente tem que pertencer à lista template.
O algoritmo de inclusão e exclusão por exemplo.
Aqui vocês tão vendo os algoritmos que permitem fazer a inclusão,
que são genéricos,
e aqui tem a exclusão, ó.
Verdade é que aqui é a exclusão de todos, né,
mas é uma exclusão mesmo assim, vai ser limpar
que são genéricos e não dependem da tipagem.
Bom, mas daí como que a gente faz pra ter listagens?
Vocês lembram que o problema na aula passada
é que eu tava lá na classe Disciplina
do método listarAlunos, fazendo lá, imbricado, enxertado,
dentro do método da classe Disciplina,
a listagem dos Alunos, tá.
O que, ali, a gente sabe que não procede, porque viola a coesão e o desacoplamento.
Bom, como que a gente vai resolver isso?
Vejam só o que acontece no próximo slide.
Próximo slide vem a solução.
A gente volta a criar uma classe ListaAlunos.
Ué, mas ideia não era justamente a gente não ter uma classe ListaAlunos?
Não necessariamente.
A ideia é que na classe ListaAlunos, ListaDisciplinas,
ListaUniversidades, ListaQualquerCoisa
você não ficar refazendo algoritmo que é genérico,
agora o que é específico é específico, é a vida.
Então, tá aqui, ó. LTAlunos,
é um objeto de Lista parametrizado com Aluno,
que vem a ser o núcleo dessa classe.
A classe ListaAlunos armazenará os apontamentos de aluno
por meio de uma Lista template parametrizada com Aluno.
Conforme tá aí.
Construtora e destrutora.
Aqui tem os métodos limpaLista e incluaAluno.
Vejam que ele recebe um Aluno, né, por parâmetro,
que, obviamente, é o endereço de um Aluno,
isso é um apontamento de qualquer coisa.
listeAlunos e listeAlunos2
graveAlunos e recupereAlunos.
Aqui a gente até trouxe aquela parte da persistência,
os métodos limpar e incluaAluno
chamam diretamente os métodos da Lista template,
visto que o código é generalizado.
Sim, esses algoritmos aqui eles são genéricos,
de inclusão e de limpagem, né,
ou de limpeza, melhor dizendo.
A gente não vai ficar reinventando a roda,
o que a gente vai fazer é simplesmente chamar apropriadamente, aqui,
os métodos pertinentes
de LTAlunos aqui e acolá.
Agora, nos métodos de listagem e de gravação.
Os algoritmos de listagem para os alunos são específicos
eles são definidos antes na classe.
Sim, aqui a gente vai criar daí, bem encapsulado,
bem desacoplado de outras partes do código
no ambiente apropriado que é o ListaAlunos,
a gente vai criar os códigos de listagem e a parte de gravação
no tocante a ListaAlunos.
E vamos ver como é que segue essa implementação aí.
Tá aqui a construtora sem parâmetros e vazia aparentemente.
A destrutora que chama o limpaLista
e o limpaLista que pede para o seu núcleo, que é o LTAlunos, limpar, né.
Quem que é o núcleo mesmo? Vou voltar um pouquinho aqui, ó, slide 8.
O LTAlunos é uma lista parametrizada com Aluno.
Por que que o núcleo da ListaAlunos é esse LTAlunos?
Porque eu tô usando a parte genérica aqui do template,
pra eu não ter que reinventar a roda a cada lista que eu for criar.
Então tá aqui, ó.
Tô mandando o LTAlunos
que é o núcleo dessa ListaAlunos, fazer a limpeza.
A inclusão, eu posso, como sempre, testar ponteiro, né, velho hábito.
E aí, se o ponteiro for diferente de nulo,
for um ponteiro válido, nesse sentido,
eu vou pegar o ponteiro do Aluno e repassar
pro núcleo, né, pro cerne de LTAlunos,
através da função incluaInfo.
Vejam que a função aqui é genérica, naturalmente, porque tá vindo de um template
e pode ser genérica, porque a natureza dessa função permite.
Tal qual permite lá, que seja genérico, bem entendido.
Tá, aqui tem o graveAlunos, né,
que daí vocês podem fazer.
O que vai modificar em relação ao que vocês já tinham,
é que agora em vez de ter a lista toda,
inclusive, a parte supostamente genérica,
enxertada ou acoplada
dentro aqui da classe ListaAlunos
eu vou utilizar o artifício da parte genérica,
por meio do template.
E assim, aqui, pra fazer a gravação e fazer a recuperação,
naturalmente, que eu vou ter que usar o template também.
Como? Ora, tem aqui uma dica
se você olhar o ListaAlunos, tá, por exemplo.
Esse é o ListaAlunos 2.
Acontece que você não tá só mostrando uma ListaAlunos aqui, tá,
essa parte de cima.
Pra eu gravar a coisa eu não tenho que navegar na Lista
e em vez de fazer lá, por exemplo, um cout
se eu tiver usando arquivo sequencial
eu usar o objeto arquivo sequencial aqui?
Sim, né.
Então vai ser um algoritmo muito parecido com esse
lá no graveAlunos, tá.
Isso considerado, vamos nos concentrar aqui no
ListaAlunos nesse momento preciso.
O que eu faço é criar um pElAux,
um Elemento que vai permitir eu navegar nos elementos
que compõe a lista encadeada,
para tal eu tô usando o template Elemento parametrizado com Aluno,
é ponteiro, bem entendido,
por isso tá aterrado com nulo, inclusive.
Crio um outro auxiliar que é ponteiro de Aluno,
pAlAux aterrado com nulo.
Aqui eu faço o pElAux apontar pro primeiro lugar, primeiro elemento da Lista,
através do meu getpPrimeiro.
Enquanto o pElAux não estiver apontando pra alguma coisa nula
e aqui na primeira passagem a gente sabe que a Lista não está vazia
pelo menos, a gente supõe que não tá vazia
ele tá recebendo, aqui, então, esse primeiro,
e ele vai entrar no loop.
Aí, eu faço o quê?
A partir do primeiro elemento da lista,
que é o elemento apontado nesse momento por pElAux,
eu recupero o Aluno que tá lá dentro.
Pra acessar esse Aluno eu uso esse ponteiro temporário pAlAux,
e ali vai recuperar nome e RA do Aluno, por exemplo.
Aí eu faço o pElAux apontar pro próximo,
e vou dar loop e assim eu vou, né, até percorrer toda lista.
Então, veja que a parte que é um pouco mais específica
que depende se é de outro tipo,
eu faço dentro da classe ListaAlunos
e não no template, porque o template é genérico
e tem um pouco na Disciplina, porque Disciplina
ou qualquer outra classe,
não tem que ter listagem de Alunos,
ela tem que utilizar o que tá definido aqui
nessa classe que é o ListaAlunos.
Bom, o ListaAlunos agora melhora o que a gente tinha anterior,
ele respeita o equilíbrio entre a generalidade e a especificidade.
Tanto é que o núcleo da solução é
oriunda de template que reaproveita a parte genérica, insisto.
Muito bem, agora a gente vai ver a classe Disciplina.
Tá aqui a classe Disciplina
com tudo que ela tem
agora ela tem um objeto LAlunos como o seu cerne
que não é mais uma lista parametrizada com Aluno
e sim uma ListaAlunos.
ListaAlunos 2 que já foi definida agora há pouco ali nos slides anteriores,
que era objeto até agora agora do meu discurso.
A gente sabe que o ListaAlunos aqui, tem como essência
uma lista parametrizada com Aluno.
mas ele tem mais coisa ainda, ele tem algoritmo por exemplo de...
a listagem e de gravação que dependem de saber a tipagem.
Muito bem.
Então, aqui você tem o teu ObjLAlunos do tipo ListaAlunos
e essa ListaAlunos aí, mais elegante
que a gente elaborou no decorrer dessa aula.
A classe Disciplina irá gerenciar
os seus ponteiros de Aluno por meio de ObjLAlunos.
Aqui tem a construtora a destrutora, setId, getID,
setNome, getNome, setDepartamento, getDepartamento
e aqui tem o incluaAluno e as listagens de Alunos.
Como os métodos e inclusão e listagem já foram definidos na classe ListaAlunos,
basta chamá-los diretamente.
Vamos ver aqui, então, agora o Disciplina.cpp.
Tá aqui construtora, destrutora,
tem mais código que a gente omitiu, porque não é o foco nesse momento.
O listeAlunos
ele vai lá no ObjLAlunos e chama o listagem.
listeAlunos2 idem,
chama o listeAlunos2, né, que é o pertinente nesse contexto.
E aqui tá o incluaAluno.
Velho hábito de testar se um ponteiro não é nulo.
Aí eu vou testaras condições pra ver se um Aluno pode ser incluído ou não.
E aí, sim, através do ObjLAlunos eu vou fazer a inclusão de Aluno,
e aí, fazer a contagem aqui de Alunos, tá,
senão eu tenho uma situação, daí, de mensagem de erro
dizendo que a turma tá lotada ou algo assim.
Se ele não passar lá no primeiro if, vai também ter outra mensagem de erro,
então sem maiores problemas.
Então, a gente elaborou uma solução mais decente,
inclusive, a gente pode modelá-la também, tá, em termos de UML.
Tá aqui, ó.
A classe Disciplina, agora, ela, em termos de Análise, né,
até poderia pintar isso aqui em azul, mas enfim.
Essa história de pintar a Análise em azul, ou deixar
o suposto Projeto em vermelho que eu fiz em outro slide,
foi uma opção minha pedagógica, tá.
Porque a ferramenta CASE permite eu colorir as
as associações, enfim, as entidades, aí,
mas ele não é obrigatório
foi uma opção naquele momento,
tanto não é obrigatório que aqui não está colorido
está com o valor default que vem na ferramenta.
Aqui, então, a Disciplina tem essa relação de associação
Conhecer com o Aluno.
Aqui aparentemente, nesse modelo, pelo menos,
a relação tá direcional.
Ah, professor, eu queria que fosse bidirecional,
porque tem que ser bidirecional.
Não tem problema, tá.
Você tira a seta daqui, né.
E aí, vai criar mais um relacionamento aqui, fazendo o Aluno ter um apontamento
para a Disciplina?
Não, né.
Não, porque, na verdade, o Aluno
não vai conhecer apenas uma Disciplina, ele vai conhecer várias Disciplinas.
Então, aqui, se fosse bidirecional,
a coisa fica um pouquinho mais complexa,
porque além de você realizar isso
através de uma Lista de Alunos, você também tem que realizar
através de uma Lista de Disciplinas.
Mas isso aqui é uma discussão que a gente pode retomar em outro momento,
pra quem estiver interessado,
mas é justamente o que eu disse, tá, se fosse bidirecional
pra realizar a coisa além de ter uma Lista de Alunos
eu teria que ter lá pra cima também uma Lista de Disciplinas,
mas vamos focar com o que está aqui de concreto
que é a Disciplina que conhece os Alunos.
É uma relação direcional,
n pra n, mas direcional.
Como é que a gente vai resolver essa questão do ponto de vista técnico?
Ué, a gente vai ter... vai resolver através dessa agregação, aqui, na prática.
Por quê?
Porque você vai ter ali, ó, o ObjLAlunos
do tipo ListaAlunos,
você tá agregando esse objeto aqui,
e você permite realizar
aquela associação lá da Análise, né, teórica.
Mais que a classe realizar a associação,
essa agregação dessa classe que realiza.
Isso aqui tá muito mais preciso do que modelos anteriores.
Então, legal. Então, eu consigo resolver, em termos de Projeto
essa relação de Análise dessa forma, justamente,
agregando, por composição, agregação-forte, uma Lista de Alunos.
A Lista de Alunos, vocês sabem, que ela vai
conhecer um conjunto de Alunos.
e os Alunos podem ser conhecidos também
em várias listas.
Mas como é que isso acontece,
como é que essa classe ListaAlunos
consegue conhecer uma Lista de Alunos?
Bom, ele consegue fazer isso por causa do seu núcleo.
E o que é o seu núcleo?
Seu núcleo é um objeto LTAlunos,
que a gente já viu no código,
que é a Lista parametrizada com Aluno.
Em termos de UML, isso significa, então, que esse objeto aqui, ó,
ListaAlunos agrega uma Lista parametrizada com Aluno.
Tanto é parametrizada com Aluno que tem essa dependência, aqui, ó, do Aluno.
Essa agregação depende de alguém.
Depende do Aluno.
Ao mesmo tempo essa agregação aqui, ela permite realizar
aquela situação da ListaAlunos conhecer um conjunto de Alunos.
É graças a essa agregação
desse template, aqui, parametrizado com Aluno,
que eu consigo realizar aquilo ali.
Legal.
Minha Lista template se relaciona lá com o Elemento, né,
através das classes Elemento template
e através das associações
usuais de conhecer o primeiro conhecer o atual
entre Lista e Elemento,
e no próprio Elemento ainda tem Conhecer Anterior e Conhecer Próximo
as relações reflexivas já conhecidas.
Bom, muito bem, pessoal, então aqui tem um modelo, tá.
Imaginem que agora vocês querem colocar uma classe Departamento aqui,
em algum momento.
Você quer uma classe Departamento.
Tô desenhando, ó.
Departamento.
Desenhando com o mouse imaginariamente
Departamento. Como é que eu faço o Departamento ter uma Lista de Alunos?
Simples.
Eu simplesmente faço o Departamento agregar
a sua Lista de Alunos.
E aí, esse Departamento vai ter que listar os seus Alunos
o seu algoritmo de listagem ele vai chamar
a listagem do seu objeto.
Sendo que o código vai tá na classe ListaAlunos.
E esse objeto em questão
de ListaAlunos vai ter a chamada de método.
Nesse sentido, como é que eu fiz a listagem aqui dentro da Disciplina?
A Disciplina foi lá, e mandou o seu objeto se listar,
usando o código que tá aqui.
Se eu tiver uma classe Departamento, insisto, com uma listagem,
ele vai chamar, vai mandar o seu ObjLAlunos
também se listar
utilizando o código definido na classe.
de maneira, então, desacoplada e também coesa.
Então, essa é uma solução que respeitou aí,
coesão e desacoplamento e ao mesmo tempo
respeitou generalidade e especificidade num bom trade-off, num bom equilíbrio.
Bom, pessoal, tudo isso considerado,
nós temos o Grupo de, aliás, temos o slide 13
desse Grupo de Slides em questão
que traz um exercício.
Exercício a).
Substituir todas as outras listas 'específicas'
elaboradas nas versões anteriores do 'sistema exemplo',
ou seja, Sistema Acadêmico,
por 'instâncias' de listas cujo cerne provenha de gabarito ou template desenvolvido
para o tratamento de lista, ou de listas.
Outramente dito,
aplicar essa solução que foi utilizada nesse Grupo de Slides, aí,
lá no Sistema Acadêmico.
Gerar uma nova versão do código de vocês, aí, que vocês tão trabalhando aí no dia a dia
e gerar uma solução apropriada, mas, então, respeitando aí,
as coesões e os acoplamentos à luz da solução posta.
O exercício b) ele pede para,
Estender em classe especializada
cada lista baseada em template
para que suas instâncias tenham a 'capacidade' de gravar e recuperar as informações incluídas nela.
Daí ele traz um exemplo do que o exercício tá querendo.
Neste sentido, por exemplo,
a classe ListaAlunos seria derivada em ListaAlunosGravadora.
Ah, isso é interessante.
Isso significa que vocês vão ter que voltar aqui um pouquinho
e modificar essa classe aqui, ó.
A classe ListaAlunos,
e tem aliás o grave e o recupereAlunos,
mas ele deixaria de ter.
Deixaria de ter porque eu vou criar uma nova classe, aqui, chamada ListaAlunosGravadora
derivada de listaAlunos
e aí nessa ListaAlunosGravadora os algoritmos de gravar e recuperar.
Professor, e pra que que eu faria isso?
Ora, porque que eu crio uma classe ListaAlunosGravadora
e coloco os algoritmos de gravação e de recuperação?
Pra aumentar a coesão e desacoplamento.
Pode ser que tenha momentos de listagem de Alunos que eu não esteja interessado em gravar.
Então, não preciso carregar aquela bagagem.
Eu vou criar objetos que vão ser do tipo ListaAlunos.
Se eu quiser, em algum momento, que uma dada ListaAlunos
grave seus conteúdos
para fins diversos como persistência,
aí eu vou criar um objeto não ListaAlunos e sim
de ListaAlunosGravadora
que vai ser uma classe a mais que vocês vão criar aqui
derivada de ListaAlunos.
Vão criar tanto em termos de modelo quanto em termos de código, obviamente.
Bom, além do exercício a) e b) temos o c).
Retomando um exercício anterior:
- Elaborar uma classe para o armazenar
das notas (1ª parcial, 2ª parcial e final)
e número de faltas de cada Aluno em cada Disciplina.
E é isso. Elaborar uma solução para armazenar as notas
1ª parcial, 2ª parcial e final e o número de faltas de cada Aluno em cada Disciplina.
Obviamente que aqui vocês vão utilizar no exercício C,
utilizando essa solução elegante
proposta nesse Grupo de Slides em questão.
Ainda, tá. Você tem o conjunto de Slides...
aliás, você tem um último slide nesse conjunto de Slides presente,
que é o 14 e traz Exercícios Suplementares.
Aqui ele exige, inclusive,
que a pessoa estude Grupos de Slides subsequentes.
Então, esse é um exercício que só vai conseguir fazer
quem for estudar os Grupos pra frente.
A gente tá no 10, então você vai ter que estudar o 11,
e aí chegar no 12, e lá, ó.
Conforme o subsequente Grupo de Slides 12,
fazer com que o Elemento Tipo
seja uma classe aninhada, privada, de Lista Tipo.
Inclusive, tem um exemplo disso lá no meu site,
de como resolver essa questão.
E aqui, por fim.
Substituir os objetos de Lista template LTAlunos na classe ListaAlunos
por um vector ou list da STL, seguindo o Grupo de Slides 16.
Bom, a gente já fez uma prévia da utilização de
list e de vector da STL, Standard Template Library, né, no passado.
Então, nas exposições passadas lá, em algum momento.
Então, lá pelo final do grupo de Slides 3, lá, acho que parte C, né.
Se não for a C é a D... perdão a B.
O fato é que tem esses dois exercícios, tá.
Esses exercícios se vocês quiserem fazer vocês vão ter que
estudar um pouquinho mais os Grupos de Slides pra frente
pra aprender esses conceitos e fazer o exercício.
Isso aqui, na verdade, é só um memento
de lembrar da capacidade autodidática dos alunos, tá.
É importante que o cara aprenda a aprender.
É importante que ele quando tá cursando uma disciplina
ele avance com os conteúdos já um pouco pra frente,
de maneira tal que permita ele fazer um melhor debate
e até absorver melhor o conteúdo,
quando ele tá vendo um conteúdo que ele já estudou de antemão.
Bom, pessoal, eu espero que vocês tenham aproveitado essa exposição aqui,
feita aqui durante as férias de julho pra vocês e
e nos encontramos no próximo Grupo de Slides
que será o número...
Grupo de Slides número 11
objeto da próxima exposição.
Até breve e bons estudos aí.