How to make an error message for this situation?

Asked

Viewed 510 times

4

arq=open('filmes.txt','r')
filmes = arq.readlines()
def buscaPorGenero():

genero=str(input("Digite o gênero do filme: "))
while(True):
    for linha in filmes:
        linha = linha.split(";")
        if genero in str(linha[1]):
            print(linha[0])
    break

When the movie is not in the file, I wanted to show an error msg but I could not, I tried several ways with while and for and did not find one that works. In my txt file the info is separated by ;

inserir a descrição da imagem aqui

3 answers

4


Create a boolean type control variable. I named achou.

achou = False # inicializa a variável
while(True):
    for linha in filmes:
        linha = linha.split(";")
        if genero in str(linha[1]):
            achou = True # seta para verdadeiro se tem algum filme com esse gênero
            print(linha[0])
    break

if not achou: # se não encontrou, então...
    print("O gênero não foi encontrado :( ")

The initialization value is false, it only becomes true if it has passed through all the iterations without finding any movie with the genre to search.

In this example you gave, like the @Andersoncarloswoss said, no need for tie while infinity with a break just when the for. Thus remaining:

achou = False # inicializa a variável
for linha in filmes:
    linha = linha.split(";")
    if genero in str(linha[1]):
        achou = True # seta para verdadeiro se tem algum filme com esse gênero
        print(linha[0])

1

As you are creating a function to do the search, it is not interesting that you do the print. This generates side effects: it will not always be desired to run the function and get the result in the terminal, so the ideal is to return the values instead of displaying them. We call these functions pure functions, if you want to study more on the subject.

In fact, reading the value within the function also breaks with the atomicity of the function; what if it is desired to look for films of a specific genre? Do I have to create another function for this? Ideally this should be a function parameter.

Another change I took the liberty of making was to change the file analysis mode. You are separating the column values in the text file with a semicolon character, ;, This clearly characterizes the CSV format, so there is no reason not to read the file as such. So your file could be something like, where the first row will be the column names:

csv films.

name;genre;id;year
O Hobbit;fantasia;343433434;2007

And in Python, we can define a generator that will look for the genre in the file. The parameters will be the genre we want to search for and the file where it will be searched. For ease, we can define this second parameter with a default value. Then we will open the file for reading, define a CSV reader and go through the lines, checking if the film belongs to the desired genre; if yes, this will be returned via yield, which is basically the return of a generator.

import csv

def search_by_genre(genre, filename='filmes.csv'):
    """ Busca em um arquivo todos os filmes de um determinado gênero.

    Atributos:
        genre (string): Nome do gênero a ser buscado.
        filename (string): Nome do arquivo onde os filmes estão armazenados.

    Retorno:
        Retorna um gerador (iterável) com todos os filmes referentes ao gênero.

    Exceções:
        FileNotFoundError: Quando o arquivo indicado por `filename` não existir.
    """
    with open(filename, 'r') as stream:
        reader = csv.DictReader(stream, delimiter=';')
        for row in reader:
            if row['genre'].lower() == genre.lower():
                yield row

I used the method lower() to check the gender to make the search insensitive to the case, causing the search to Fantasia return the same results as fantasia, for example.

To display all movies of a user-read genre, as it is posed in the question, we can do:

if __name__ == '__main__':
    genre = input('Digite o gênero do filme: ')
    movies = search_by_genre(genre, filename='filmes.csv')
    for movie in movies:
        print(movie['name'])

See working on Repl.it

So by running the program, we would have:

Digite o gênero do filme: fantasia
O Hobbit

0

Do an IF-ELSE. If the value returned from IF is false, the execution of the program jumps to the code block within ELSE, then within this code block you write the message display code. For example:

if genero in str(linha[1]):
            print(linha[0])
else:
            print("Erro!")

I don’t know if ELSE writes like that in this language, I’m sorry. But that’s the logic.

  • 1

    In this case, in any iteration other than the one that was searched, will print "Error!". Shouldn’t search all and if you didn’t find any print error message?

  • I got it. I saw your answer, you used a control variable and did an IF outside of WHILE to check if it was true or false.

  • 1

    That.. and the else That’s right. Just indent with 4 spaces or a tab, I’m not sure it works that way. The indentation in Python can cause a build error, as this is how you define the blocks =) @Douglasöak

  • 1

    Cool @vnbrs, I didn’t know that in Python the blocks organize like this. I never wrote in this language. Good to know, because, in case you decide to venture, I’ll be less lost haha.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.