Since you are creating a function to search, it is not interesting that you make print
. This generates side effects: it will not always be desired to execute the function and get the result in the terminal, so the ideal is to return the values instead of displaying them. We call these pure functions functions if you want to study more about it.
Incidentally, reading the value inside the function also breaks with the atomicity of the function; and if it is desired to seek the 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 freely to do was to change the way the file is analyzed. You are separating the values of the columns in the text file with a semicolon character, ;
, this clearly characterizes the CSV format, so you do not have to read the file as such. So your file could be something like, where the first line will be the column names:
filmes.csv
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 that we want to search and the file where it will be searched. For ease, we can set this second parameter to a default value. Then we will open the file for reading, define a CSV reader and go through the lines, verifying if the film belongs to the genre you want; if yes, it 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 lower()
method to check the genre to make the search insensitive to the case, causing the search by Fantasia
to return the same results as fantasia
, for example.
To display all the movies of a genre read from the user, as it is placed 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 at Repl.it
So, by running the program, we would have:
Digite o gênero do filme: fantasia
O Hobbit