Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

[Dúvida] Aula 04 - Atividade 07 - Dúvida no exercício 4

No método estático "verificar_disponibilidade", usando [for] na forma reduzida, conforme o exemplo do instrutor, não funcionou. (Parte comentada do Ex. 4). Está retornando só posição de memória.

Saída: Livros disponíveis publicados no ano de 1996: [<my_class.Livro object at 0x0000023A4A2EA780>]

Usando [for] "convencional" (parte não comentada) funcionou ok. Onde errei?

Exs. 1 a 4 (my_class.py)
'''
1. Crie uma classe chamada Livro com um construtor que aceita os parâmetros titulo, autor e ano_publicacao. Inicie um atributo chamado disponivel como True por padrão.
'''
class Livro:
  lista_global = []  
  
  def __init__(self, titulo='', autor='', ano_publicacao=0):
    self._titulo = titulo
    self._autor = autor
    self._ano_publicacao = ano_publicacao
    self._disponivel = True
    Livro.lista_global.append(self)
    
  ''' 
  2. Na classe Livro, adicione um método especial str que retorna uma mensagem formatada com o título, autor e ano de publicação do livro. Crie duas instâncias da classe Livro e imprima essas instâncias. 
  '''
  def __str__(self):
    return f'Título: {self._titulo.ljust(28)} - Autor: {self._autor.ljust(14)} - Ano: {str(self._ano_publicacao).ljust(8)} - Disponível: {self.disponivel}'
  
  '''
  3. Adicione um método de instância chamado emprestar à classe Livro que define o atributo disponivel como False. Crie uma instância da classe, chame o método emprestar e imprima se o livro está disponível ou não.
  '''  
  def emprestar(self):
    self._disponivel = False
    print(f'\nO livro: [{self._titulo}] foi emprestado.')

  @property
  def disponivel(self):
    return '☒' if self._disponivel else '☐'
  
  @classmethod
  def listar_livros(cls):
    print(f'{'\n    Título'.ljust(28)} {'    Autoria'.ljust(25)} {'    Ano'.ljust(12)} {'Disponivel\n'}')
    for livro in cls.lista_global:
      print(f'{livro._titulo.ljust(28)} - {livro._autor.ljust(24)} - {str(livro._ano_publicacao).ljust(10)} - {livro.disponivel}')

  '''
  4. Adicione um método estático chamado verificar_disponibilidade à classe Livro que recebe um ano como parâmetro e retorna uma lista dos livros disponíveis publicados nesse ano.
  '''
  @staticmethod
  def verificar_disponibilidade(ano):
    titulos_disponiveis = []
    for volume in Livro.lista_global:
      if volume._disponivel and volume._ano_publicacao == ano:
        titulos_disponiveis.append(volume._titulo)
        
    # ou - com for, na forma reduzida (não funcionou)
    # titulos_disponiveis = [volume for volume in Livro.lista_global if volume._disponivel and volume._ano_publicacao == ano]
    return titulos_disponiveis

Exs. 5 a 7 (biblioteca.py)

'''
5. Crie um arquivo chamado biblioteca.py e importe a classe Livro neste arquivo.
'''
from my_class import Livro

livro_A = Livro('20k Léguas Submarinas', 'Júlio Verne', 1870)  
livro_B = Livro('As aventuras de Tom Sawyer', 'Mark Twain', 1876) 
livro_C = Livro('Programming Python', 'Mark Lutz', 1996) 
livro_D = Livro('Java how to program', 'Paul & Harvey Deitel', 1996) 

def main():


  Livro.listar_livros()

  '''
  6. No arquivo biblioteca.py, empreste o livro chamando o método emprestar e imprima se o livro está disponível ou não após o empréstimo.
  '''
  livro_C.emprestar()
  Livro.listar_livros()

  '''
  7. No arquivo biblioteca.py, utilize o método estático verificar_disponibilidade para obter a lista de livros disponíveis publicados em um ano específico.
  '''
  # Armazena o ano de publicação do livro
  ano_de_publicacao = 1996

  # Obtém a lista de exemplares disponíveis, dado ano da publicação 
  titulos_disponiveis_por_ano = Livro.verificar_disponibilidade(ano_de_publicacao)

  # Imprime a lista obtida
  print(f'\nLivros disponíveis publicados no ano de {ano_de_publicacao}: {titulos_disponiveis_por_ano}')

if __name__ == '__main__':
  main()

Ex. 8 (main.py)

'''
8. Crie um arquivo chamado main.py, importe a classe Livro e, no arquivo main.py, instancie dois objetos da classe Livro e exiba a mensagem formatada utilizando o método str.
'''
# importa a classe Livro do arquivo "my_class"
from my_class import Livro

def main():

  # Cria duas instâncias da classe Livro
  livro_1 = Livro('20k Léguas Submarinas', 'Júlio Verne', 1870)  
  livro_2 = Livro('Programming Python', 'Mark Lutz', 1996) 
  
  # Exibe mensagem formatada
  print(livro_1)
  print(livro_2)

if __name__ == '__main__':
  main()
2 respostas
solução!

Oi, Eduardo! Como vai?

Agradeço por compartilhar seu código com a comunidade Alura.

No seu código, você mencionou que a versão reduzida do for, conhecida como list comprehension, não funcionou como esperado. O ponto central aqui é o que você está tentando retornar.

Na forma convencional, você fez assim:

titulos_disponiveis = []
for volume in Livro.lista_global:
    if volume._disponivel and volume._ano_publicacao == ano:
        titulos_disponiveis.append(volume._titulo)

Ou seja, você está armazenando apenas o título de cada livro.

Já na forma reduzida, que você comentou como “não funcionando”, o código era:

# titulos_disponiveis = [volume for volume in Livro.lista_global if volume._disponivel and volume._ano_publicacao == ano]

Aqui, você está armazenando os objetos Livro inteiros, e como não fez print(str(livro)) ou print(livro._titulo), o Python exibiu o padrão da classe:

<my_class.Livro object at 0x0000023A4A2EA780>

Isso não é um erro, apenas o comportamento padrão ao imprimir objetos que não foram convertidos para string de forma explícita.

Se você quiser que a list comprehension funcione como no primeiro caso, experimente essa versão:

titulos_disponiveis = [volume._titulo for volume in Livro.lista_global if volume._disponivel and volume._ano_publicacao == ano]

Assim, você continua usando a forma reduzida, mas agora pegando apenas o título, como fez com append.

Alura Conte com o apoio da comunidade Alura na sua jornada. Abraços e bons estudos!

Entendi. Perfeito! Faltou eu especificar o quê, do objeto "livro", imprimir. Acrescentando "._titulo" ao "volume" (volume._titulo), sarou! Obrigado.