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
Exactly that, thank you!
– Van Scheur Freud Belmont