Strona główna Polish Python Coders Group
   Strona główna   Pomoc Zaloguj się Rejestracja  
Witamy, Gość. Zaloguj się lub zarejestruj.
Czy dotarł do Ciebie email aktywacyjny?

Zaloguj się podając nazwę użytkownika, hasło i długość sesji

Aktualności:
Szukaj Szukaj
Strony: [1]   Do dołu
Drukuj
Wątek: Wyszukiwarka filmów - problem z sortowaniem  (Przeczytany 66 razy)
« : 19:16 08/02/19 »
ss520 Offline
Hello World!

Zobacz profil
*

Reputacja: 0
Wiadomości: 1


Cześć,
dopiero się uczę programować i w ramach nauki stworzyłam sobie wyszukiwarkę filmów na podstawie wcześniej utworzonego przeze mnie pliku csv.
Wszystko mi działa, ale mam problem z sortowaniem. Chciałabym aby pojawiały mi się filmy o najwyższych wartościach (zarówno rok, jak i raitingi) i aby kolejno te liczby malały.
Rozumiem, że to musiało by być sortowanie przez lambdę?
Poniżej kod:


import csv
import re

TITLE = 'movie'
YEAR = 'year'
IMDB = 'imdb'
METASCORE = 'metascore'
VOTES = 'votes'
N_IMDB = 'n_imdb'


def get_movies_dict():
 
    csv.register_dialect("dialect", quotechar='"', skipinitialspace=True, delimiter=',', quoting=csv.QUOTE_ALL)
    return list(csv.DictReader(open('movie_ratings.csv'), dialect="dialect"))


def get_user_input():
    """
    Obsługa użytkownika, pobiera wartości tj. tytuł, rok, metascore i imbd id
    :return:
    """
    print(f"<{'-' * 10} Wyszukaj film  {'-' * 10}>")
    movie_tile = input('Podaj tytuł: ')
    movie_date = input('Podaj rok: ')
    movie_metascore = input('Podaj metascore: ')
    movie_imdb = input('Podaj imdb: ')

    #zamiana wskaznika movie_imdb na float w celu zamiany wartości 8 na 8.0 i ponowna konwersja na string
    # dzieki temu wpisanie wspolczynnika: 8 zwroci filmy ze wspolczynnikiem 8.0
    if movie_imdb:
        movie_imdb = float(movie_imdb)
        format(movie_imdb, '.1f')
        movie_imdb = str(movie_imdb)

    if not any((movie_date, movie_imdb, movie_metascore, movie_tile)):
        raise ValueError('Musisz podać przynajmniej jedną wartość np: tytuł')
    return movie_tile.lower(), movie_date.lower(), movie_metascore.lower(), movie_imdb.lower()


def search_values(movie_database, key, value):
    """
    :param movie_database:      Plik csv w formie słownika
    :param key:                 Kolumna w której szukamy
    :param value:               Wartość której szukamy
    :return:                    Znalezione wiersze
    """
    rows = []
    for row in movie_database:
        line = row.get(key).lower()

        # sub() podmienia znaki w tekscie
        line = re.sub('[(.,?!:Mrugnięcie]', '', line)

        words = line.split()

        if value in words:
            rows.append(row)
    return rows


def intersect(a, b):
    """
    Zwraca części wspólne dwóch list
    :param a:                  Lista A
    :param b:                  Lista B
    :return:                   Lista części wspólnych A i B
    """
    return [val for val in a if val in b]


if __name__ == '__main__':
    # Pobieramy kryteria wyszukiwania
    movie_title, movie_date, movie_metascore, movie_imdb = get_user_input()

    # lista atrybutow, po ktorej bedziemy iterowac wyszukujac filmy
    attributes = [(TITLE, movie_title), (YEAR, movie_date), (METASCORE, movie_metascore), (IMDB, movie_imdb)]

    # listy znalezionych filmow
    searches = []

    for index in range(len(attributes)): # dzieki range() index przyjmuje kolejno wartości: 0, 1, 2, 3
        if attributes[index]:
            attr = attributes[index]
            if attr[1]:
                search = search_values(get_movies_dict(), attr[0], attr[1])
                searches.append(search)

    # tworzymy pusta liste filmow
    movies = []

    # łączymy części wspólne wszystkich dostępnych list wierszy
    for index in range(len(searches)):
        if index==0:
            movies.extend(searches[index])
        else:
            movies = intersect(movies, searches[index])

 
    print(f"<{'-' * 10} Wyniki  {'-' * 10}>")
    if not movies: # to samo co: if len(movies) == 0:
        print(f"Brak filmów dla podanych kryteriów")
    else:
        for movie in movies:
            print(
                f'Tytuł: {movie.get(TITLE)}, '
                f'Rok: {movie.get(YEAR)}, '
                f'Metascore: {movie.get(METASCORE)}, '
                f'IMDB: {movie.get(IMDB)}, '
                f'VOTES: {movie.get(VOTES)}, '
                f'N_IMDB: {movie.get(N_IMDB)}')

Mielibyście jakieś sugestie?
Z góry dzięki za pomoc!
Zapisane
« Odpowiedz #1 : 10:40 09/02/19 »
Guaz Offline
Professional Python User

Zobacz profil
***

Reputacja: 53
Płeć: Mężczyzna
Wiadomości: 412


Hmmm... Ogólnie to dobrze byłoby gdybyś wykorzystywała znaczniki {code=python} twój kod {/code} (Tylko z kwadratowymi nawiasami).

Jeśli chcesz część wspólną, polecam używanie zbiorów. ( set() )
Skoro obiekty typu listy lub inny niehashowalny chcesz tam trzymać to zamrożonego zbioru ( frozenset() ).
Jeśli chcesz sortować, to wynikową część wspólną przerzuć tym:
sorted(twoja_struktura, key=lamda x: x[0]) - Tak jeśli to jest lista zawierająca listy na przykład. I chcesz według pierwszego elementu tej listy wewnętrznej (zagnieżdżonej)

Ale jak zwięźlej pokażesz przykład jak wygląda struktura którą chcesz sortować, to bez poświęcania większej ilości czasu niż ogólnie mogę na jeden problem. Chętnie pomogę Uśmiech
Zapisane

Python 3.5+ / Mint

Daje wędkę zamiast ryby. Chyba że ktoś się chce czegoś nauczyć, wtedy chętnie pomogę każdemu.
Za rybę niestety trzeba zapłacić Z politowaniem.
Strony: [1]   Do góry
Drukuj
Skocz do:  

© 2007 - 2019 Polish Python Coders Group
Powered by SMF 1.1.21 | SMF © 2006-2009, Simple Machines | Theme by PixelSlot