Hone logo
Hone
Problems

Custom Sorting with Complex Object Comparison

In Python, sorting is a fundamental operation. While Python's built-in sort() method and sorted() function are powerful, they rely on default comparison logic or a key function that transforms objects before comparison. However, there are scenarios where you need to define custom, complex comparison logic that directly compares objects based on multiple attributes, potentially with varying priorities or conditional rules. This challenge will test your ability to implement such custom comparison logic.

Problem Description

You are tasked with sorting a list of Book objects. Each Book object has the following attributes: title (string), author (string), year (integer), and rating (float).

Your sorting criteria are as follows:

  1. Primary Sort: Sort by year in ascending order.
  2. Secondary Sort: If two books have the same year, sort them by rating in descending order.
  3. Tertiary Sort: If two books have the same year and rating, sort them by title in alphabetical (ascending) order.

You should implement this sorting logic using Python's functools.cmp_to_key to convert a traditional comparison function into a key function suitable for sorted().

Key Requirements:

  • Define a Book class with title, author, year, and rating attributes.
  • Implement a comparison function that takes two Book objects as input and returns:
    • -1 if the first book should come before the second.
    • 1 if the first book should come after the second.
    • 0 if they are considered equal for sorting purposes (though the tertiary sort will likely prevent this for distinct books).
  • Use functools.cmp_to_key to adapt your comparison function.
  • Sort a given list of Book objects using the adapted key and the sorted() function.

Expected Behavior:

The sorted() function should return a new list of Book objects ordered according to the specified criteria.

Edge Cases to Consider:

  • Empty input list.
  • Books with identical year and rating but different titles.

Examples

Example 1:

Input:
books_data = [
    {"title": "The Hitchhiker's Guide to the Galaxy", "author": "Douglas Adams", "year": 1979, "rating": 4.5},
    {"title": "Pride and Prejudice", "author": "Jane Austen", "year": 1813, "rating": 4.8},
    {"title": "1984", "author": "George Orwell", "year": 1949, "rating": 4.7},
    {"title": "To Kill a Mockingbird", "author": "Harper Lee", "year": 1960, "rating": 4.9},
    {"title": "The Great Gatsby", "author": "F. Scott Fitzgerald", "year": 1925, "rating": 4.6},
]

# Assume Book class and comparison function are defined
# sorted_books = sorted(books_list, key=cmp_to_key(compare_books))
Output:
[
    Book(title='Pride and Prejudice', author='Jane Austen', year=1813, rating=4.8),
    Book(title='The Great Gatsby', author='F. Scott Fitzgerald', year=1925, rating=4.6),
    Book(title='1984', author='George Orwell', year=1949, rating=4.7),
    Book(title='To Kill a Mockingbird', author='Harper Lee', year=1960, rating=4.9),
    Book(title="The Hitchhiker's Guide to the Galaxy", author='Douglas Adams', year=1979, rating=4.5)
]

Explanation: The books are sorted primarily by year (1813, 1925, 1949, 1960, 1979). There are no ties in year, so the secondary and tertiary sorts are not demonstrated here.

Example 2:

Input:
books_data = [
    {"title": "Book C", "author": "Author Y", "year": 2020, "rating": 4.2},
    {"title": "Book A", "author": "Author X", "year": 2020, "rating": 4.5},
    {"title": "Book B", "author": "Author Z", "year": 2020, "rating": 4.5},
    {"title": "Book D", "author": "Author W", "year": 2019, "rating": 4.1},
]

# Assume Book class and comparison function are defined
# sorted_books = sorted(books_list, key=cmp_to_key(compare_books))
Output:
[
    Book(title='Book D', author='Author W', year=2019, rating=4.1),
    Book(title='Book A', author='Author X', year=2020, rating=4.5),
    Book(title='Book B', author='Author Z', year=2020, rating=4.5),
    Book(title='Book C', author='Author Y', year=2020, rating=4.2)
]

Explanation:

  • "Book D" is sorted first because it has the earliest year (2019).
  • The remaining books are from 2020.
  • "Book A" and "Book B" have the highest rating (4.5). Between them, they are sorted by title alphabetically: "Book A" comes before "Book B".
  • "Book C" has a lower rating (4.2) and comes last among the 2020 books.

Example 3 (Edge Case):

Input:
books_data = []

# Assume Book class and comparison function are defined
# sorted_books = sorted(books_list, key=cmp_to_key(compare_books))
Output:
[]

Explanation: An empty input list results in an empty output list.

Constraints

  • The number of books in the list will be between 0 and 1000 (inclusive).
  • title and author will be non-empty strings.
  • year will be an integer between 1000 and 3000.
  • rating will be a float between 0.0 and 5.0.
  • The sorting operation should be efficient enough to complete within a reasonable time for the given constraints.

Notes

  • You will need to import the functools module for cmp_to_key.
  • Consider how to handle comparisons for each criterion in your comparison function.
  • Remember that cmp_to_key requires a function that adheres to the traditional comparison function signature (returning -1, 0, or 1).
  • Implementing __eq__ and __repr__ methods for your Book class will be helpful for testing and debugging.
Loading editor...
python