Home > Net >  Changing dictionary key to a float (Python)
Changing dictionary key to a float (Python)

Time:12-11

I have a super long given dictionary like this:

book_dictionary = {'Fiction': [{'title': "Antiques Roadkill: A Trash 'n' Treasures Mystery", 'author': 'Barbara Allan', 'rating': '3.3', 'publisher': 'Kensington Publishing Corp.', 'page_count': '288', 'language': 'English'}, {'title': 'The Painted Man (The Demon Cycle, Book 1)', 'author': 'Peter V. Brett', 'rating': '4.5', 'publisher': 'HarperCollins UK', 'page_count': '544', 'language': 'English'}, {'title': 'Edgedancer: From the Stormlight Archive', 'author': 'Brandon Sanderson', 'rating': '4.8', 'publisher': 'Tor Books', 'page_count': '226', 'language': 'English'}, {'title': 'Sword of Destiny: Witcher 2: Tales of the Witcher', 'author': 'Andrzej Sapkowski', 'rating': '4.8', 'publisher': 'Hachette UK', 'page_count': '400', 'language': 'English'}, {'title': 'After Anna', 'author': 'Alex Lake', 'rating': '4.1', 'publisher': 'HarperCollins UK', 'page_count': '416', 'language': 'English'}, {'title': 'Little Girl Lost: A Lucy Black Thriller', 'author': 'Brian McGilloway', 'rating': '4', 'publisher': 'Harper Collins', 'page_count': '336', 'language': 'English'}, {'title': 'The Guardians: The explosive new thriller from international bestseller John Grisham', 'author': 'John Grisham', 'rating': '', 'publisher': 'Hachette UK', 'page_count': '384', 'language': 'English'}, {'title': 'Bring Me Back', 'author': 'B A Paris', 'rating': '3.8', 'publisher': 'HarperCollins UK', 'page_count': '368', 'language': 'English'}, {'title': "Final Option: 'The best one yet'", 'author': 'Clive Cussler', 'rating': '5', 'publisher': 'Penguin UK', 'page_count': '400', 'language': 'English'}, {'title': 'The Red Signal: An Agatha Christie Short Story', 'author': 'Agatha Christie', 'rating': '5', 'publisher': 'HarperCollins UK', 'page_count': '40', 'language': 'English'}, {'title': 'The Name of the Wind: The Kingkiller Chronicle:, Book 1', 'author': 'Patrick Rothfuss', 'rating': '4.3', 'publisher': 'Hachette UK', 'page_count': '672', 'language': 'English'}, {'title': 'Antiques Con', 'author': 'Barbara Allan', 'rating': '4.8', 'publisher': 'Kensington Books', 'page_count': '288', 'language': 'English'}, {'title': 'Antiques Chop', 'author': 'Barbara Allan', 'rating': '4.5', 'publisher': 'Kensington Books', 'page_count': '240', 'language': 'English'}, {'title': "Salem's Lot", 'author': 'Stephen King', 'rating': '4.4', 'publisher': 'Hachette UK', 'page_count': '300', 'language': 'English'}, {'title': 'Killer Blonde', 'author': 'Laura Levine', 'rating': '4', 'publisher': 'Kensington Books', 'page_count': '288', 'language': 'English'}, {'title': 'No Mercy: The brand new novel from the Queen of Crime', 'author': 'Martina Cole', 'rating': '', 'publisher': 'Hachette UK', 'page_count': '416', 'language': 'English'}, {'title': 'Antiques Knock-Off', 'author': 'Barbara Allan', 'rating': '4.3', 'publisher': 'Kensington Publishing Corp.', 'page_count': '240', 'language': 'English'}, {'title': 'A Trace of Vice (a Keri Locke Mystery--Book #3)', 'author': 'Blake Pierce', 'rating': '4.8', 'publisher': 'Blake Pierce', 'page_count': '250', 'language': 'English'}, {'title': 'Total Control', 'author': 'David Baldacci', 'rating': '4', 'publisher': 'Pan Macmillan', 'page_count': '624', 'language': 'English'}, {'title': 'Mrs. Pollifax Unveiled', 'author': 'Dorothy Gilman', 'rating': '3.9', 'publisher': 'Ballantine Books', 'page_count': '208', 'language': 'English'}, {'title': 'And Then There Were None', 'author': 'Agatha Christie', 'rating': '4.6', 'publisher': 'HarperCollins UK', 'page_count': '224', 'language': 'English'}, {'title': 'The Lord of the Rings: The Fellowship of the Ring, The Two Towers, The Return of the King', 'author': 'J. R. R. Tolkien', 'rating': '4.6', 'publisher': 'HarperCollins UK', 'page_count': '1216', 'language': 'English'}, {'title': 'A Feast for Crows (A Song of Ice and Fire, Book 4)', 'author': 'George R.R. Martin', 'rating': '4.5', 'publisher': 'HarperCollins UK', 'page_count': '864', 'language': 'English'}, {'title': 'A Game of Thrones: The Story Continues Books 1-5: A Game of Thrones, A Clash of Kings, A Storm of Swords, A Feast for Crows, A Dance with Dragons (A Song of Ice and Fire)', 'author': 'George R.R. Martin', 'rating': '4.5', 'publisher': 'HarperCollins UK', 'page_count': '4544', 'language': 'English'}, {'title': 'The Mysterious Affair at Styles', 'author': 'Agatha Christie', 'rating': '4.4', 'publisher': 'HarperCollins UK', 'page_count': '208', 'language': 'English'}, {'title': "The Girl in the Spider's Web: A Lisbeth Salander novel, continuing Stieg Larsson's Millennium Series", 'author': 'David Lagercrantz', 'rating': '4.1', 'publisher': 'Vintage Crime/Black Lizard', 'page_count': '416', 'language': 'English'}, {'title': 'Night of the Bold (Kings and Sorcerers--Book 6)', 'author': 'Morgan Rice', 'rating': '4.3', 'publisher': 'Morgan Rice', 'page_count': '250', 'language': 'English'}, {'title': 'A Trace of Crime (a Keri Locke Mystery--Book #4)', 'author': 'Blake Pierce', 'rating': '4.7', 'publisher': 'Blake Pierce', 'page_count': '250', 'language': 'English'}, {'title': 'Shantaram', 'author': 'Gregory David Roberts', 'rating': '4.5', 'publisher': 'Hachette UK', 'page_count': '944', 'language': 'English'}, {'title': 'The Black Box', 'author': 'Michael Connelly', 'rating': '4', 'publisher': 'Hachette UK', 'page_count': '448', 'language': 'English'}, {'title': 'The Tower of the Swallow: Witcher 6', 'author': 'Andrzej Sapkowski', 'rating': '4.6', 'publisher': 'Hachette UK', 'page_count': '400', 'language': 'English'}, {'title': 'Prince of Thorns (The Broken Empire, Book 1)', 'author': 'Mark Lawrence', 'rating': '4.2', 'publisher': 'HarperCollins UK', 'page_count': '416', 'language': 'English'}, {'title': 'The Vagrant (The Vagrant Trilogy)', 'author': 'Peter Newman', 'rating': '4.2', 'publisher': 'HarperCollins UK', 'page_count': '416', 'language': 'English'}, {'title': 'The Weight of Honor (Kings and Sorcerers--Book 3)', 'author': 'Morgan Rice', 'rating': '4.4', 'publisher': 'Morgan Rice', 'page_count': '250', 'language': 'English'}, {'title': 'The Memoirs of Sherlock Holmes', 'author': 'Arthur Conan Doyle', 'rating': '4.2', 'publisher': 'Simon and Schuster', 'page_count': '320', 'language': 'English'}, {'title': 'We', 'author': 'Yevgeny Zamyatin', 'rating': '4.3', 'publisher': 'Pan', 'page_count': '226', 'language': 'English'}, {'title': 'In Dark Company: A Kate Burkholder Short Story', 'author': 'Linda Castillo', 'rating': '4.3', 'publisher': 'Minotaur Books', 'page_count': '60', 'language': 'English'}, {'title': "Chronicle of the Unhewn Throne: (The Emperor's Blades, The Providence of Fire, The Last Mortal Bond)", 'author': 'Brian Staveley', 'rating': '4.3', 'publisher': 'Macmillan', 'page_count': '1728', 'language': 'English'}, {'title': 'The Malady and Other Stories: An Andrzej Sapkowski Sampler', 'author': 'Andrzej Sapkowski', 'rating': '4.8', 'publisher': 'Hachette UK', 'page_count': '96', 'language': 'English'}], 'Comics': [{'title': 'Deadpool Kills the Marvel Universe', 'author': 'Cullen Bunn', 'rating': '4.2', 'publisher': 'Marvel Entertainment', 'page_count': '96', 'language': 'English'}, {'title': 'Young Justice Vol. 1', 'author': 'Art Baltazar', 'rating': '4.1', 'publisher': 'DC', 'page_count': '164', 'language': 'English'}, {'title': 'Ultimate Spider-Man Vol. 11: Carnage', 'author': 'Brian Michael Bendis', 'rating': '4.1', 'publisher': 'Marvel Entertainment', 'page_count': '144', 'language': 'English'}, {'title': 'Immortal Hulk Vol. 1: Or Is He Both?', 'author': 'Al Ewing', 'rating': '4.4', 'publisher': 'Marvel Entertainment', 'page_count': '128', 'language': 'English'}, {'title': 'Watchmen (2019 Edition)', 'author': 'Alan Moore', 'rating': '4.2', 'publisher': 'DC Comics', 'page_count': '448', 'language': 'English'}, {'title': 'The Joker', 'author': 'Brian Azzarello', 'rating': '4.4', 'publisher': 'DC', 'page_count': '130', 'language': 'English'}, {'title': 'Venomized', 'author': 'Cullen Bunn', 'rating': '4.5', 'publisher': 'Marvel Entertainment', 'page_count': '136', 'language': 'English'}], {'Economics':[...]}}

NOTE: There are empty ratings. What I am trying to do is write a function that takes an integer argument, the rating, and the dictionary itself. The function returns a list with the book for the given rating.

For example, if the input parameter of the function is 3, the function will return the book whose rate is greater or equal to 3 and smaller than 4. It will then print it like:

Title: "Antiques Roadkill: A Trash 'n' Treasures Mystery"
Authors: " Barbara Allan”
Language: "English"
Rating: 3.3
Publisher: "Kensington Publishing Corp."
Category: "Fiction”
Page Count: 288

What I currently have is:

def get_books_by_rate(rate: int, book_dictionary) -> list:
    ratings = []
              
    for category in book_dictionary.keys(): 
        books = book_dictionary[category]
        for book in books:
            x = book['rating']
            if (x >= rate) and (x < rate   1): 
                    title = book('title')
                    author = book('author')
                    language = book('language')
                    rating = book('rating')
                    publisher = book('publisher')
                    cat = books
                    page_count = book('page_count')                
                
                    result = {'Title': title,
                             'Authors': author,
                             'Language': language,
                             'Rating': rating,
                             'Publisher': publisher,
                             'Category': cat,
                             'Page Count': page_count}
                    ratings.append(result)
    return ratings

get_books_by_rate_print = get_books_by_rate(3, book_dictionary)
print(get_books_by_rate_print)

I am trying to get the function to properly print before attempting to format it. However, I am stuck:

Traceback (most recent call last):
  File "C:/Users/aL/Downloads/Python/rate_func.py", line 50, in <module>
    get_books_by_rate_print = get_books_by_rate(3, book_dictionary)
  File "C:/Users/aL/Downloads/Python/rate_func.py", line 31, in <module>
    if (x >= rate) and (x < rate   1):
builtins.TypeError: '>=' not supported between instances of 'str' and 'int'

I am not sure how to convert x into a float/int value to compare the two variables.

CodePudding user response:

Try this:

def get_books_by_rate(rate: int, book_dictionary) -> list:
    ratings = []
              
    for category in book_dictionary.keys(): 
        books = book_dictionary[category]
        for book in books:
            x = 0

            rating_valid = True

            try:
                x = float(book['rating'])
            except:
                rating_valid = False

            if rating_valid and (x >= rate) and (x < rate   1):            
                result = {}
                result.update({'Title': book['title']})
                result.update({'Authors': book['author']})
                result.update({'Language': book['language']})
                result.update({'Rating': book['rating']})
                result.update({'Publisher': book['publisher']})
                result.update({'Category': category})
                result.update({'Page Count': book['page_count']})

                ratings.append(result)

    return ratings

book_dictionary = *PUT YOUR DICTIONARY HERE*

get_books_by_rate_print = get_books_by_rate(3, book_dictionary)

for item in get_books_by_rate_print:
    print(item)

CodePudding user response:

This approach should work as well:

my_dict = {'Fiction': [{'title': "Antiques Roadkill: A Trash 'n' Treasures Mystery", 'author': 'Barbara Allan', 'rating': '3.3', 'publisher': 'Kensington Publishing Corp.', 'page_count': '288', 'language': 'English'}], 
'Economics': [{'title': 'How To Win Friends and Influence People', 'author': 'Dale Carnegie', 'rating': '4.3', 'publisher': 'Simon and Schuster', 'page_count': '320', 'language': 'English'}]}

def get_books_by_rate(rate: int, book_dictionary = my_dict) -> list:
    res = []
    vote = int(rate)
    for k, l in book_dictionary.items():
        for book in l:
            if vote == int(float(book["rating"])):
                book["category"] = k
                res.append(book)
    return res

def print_book(book):
    print(f'Title: {book["title"]}')
    print(f'Authors: {book["author"]}')
    print(f'Language: {book["language"]}')
    print(f'Rating: {book["rating"]}')
    print(f'Publisher: {book["publisher"]}')
    print(f'Category: {book["category"]}')
    print(f'Page Count: {book["page_count"]}')


for book in get_books_by_rate(3):
    print_book(book)
    print(30 * "-")

I think truncating the float rating to its integer part using int(float(book["rating"])) is more compact that something like min <= rating < max, but maybe it is just matter of tastes.

CodePudding user response:

Perhaps this will help:

book_dictionary = {'Fiction': [{'title': "Antiques Roadkill: A Trash 'n' Treasures Mystery", 'author': 'Barbara Allan', 'rating': '3.3', 'publisher': 'Kensington Publishing Corp.', 'page_count': '288', 'language': 'English'}],
                   'Economics': [{'title': 'How To Win Friends and Influence People', 'author': 'Dale Carnegie', 'rating': '4.3', 'publisher': 'Simon and Schuster', 'page_count': '320', 'language': 'English'}]}

def get_books_by_rate(rate, books):
    ratings = []
    for v in books.values():
        for lb in v:
            rating = float(lb['rating'])
            if rating >= rate and rating < rate   1:
                ratings.append(lb)
    return ratings

print(get_books_by_rate(3, book_dictionary))

CodePudding user response:

Use .strip() to remove space, and float() to convert type to float.

To set empty rating as 0:

rating = book['rating'].strip()
x = float(rating) if rating != '' else 0

or, to ignore empty ratings:

rating = book['rating'].strip()
if rating == '':
    continue
  • Related