Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Library with Author

case class Author(name: String, nationality: String)

case class Book(title: String, author: Author, year: Int, category: String, price: Double)

class ShoppingBasket {
  private var items: List[Book] = List()

  def addBook(book: Book): Unit = {
    items = book :: items
  }

  def totalCost: Double = {
    items.map(_.price).sum
  }

  def showBasket(): Unit = {
    println("Shopping Basket:")
    items.foreach(book => println(s"${book.title} by ${book.author.name} - ${book.price}"))
  }
}

object EnhancedLibraryManagement extends App {
  val authors = List(
    Author("George Orwell", "British"),
    Author("Harper Lee", "American"),
    Author("F. Scott Fitzgerald", "American"),
    Author("Aldous Huxley", "British"),
    Author("Herman Melville", "American"),
    Author("J.D. Salinger", "American"),
    Author("Yuval Noah Harari", "Israeli")
  )

  var library = List(
    Book("1984", authors(0), 1949, "Dystopian", 15.99),
    Book("To Kill a Mockingbird", authors(1), 1960, "Fiction", 10.99),
    Book("The Great Gatsby", authors(2), 1925, "Classic", 8.99),
    Book("Brave New World", authors(3), 1932, "Dystopian", 12.99),
    Book("Moby Dick", authors(4), 1851, "Classic", 9.99),
    Book("The Catcher in the Rye", authors(5), 1951, "Fiction", 14.99)
  )

  def addBook(library: List[Book], book: Book): List[Book] = {
    book :: library
  }

  def searchBooks(library: List[Book], query: String): List[Book] = {
    library.filter(book => book.title.contains(query) || book.author.name.contains(query))
  }

  def filterByCategory(library: List[Book], category: String): List[Book] = {
    library.filter(_.category == category)
  }

  def totalBooks(library: List[Book]): Int = {
    library.length
  }

  def averagePublicationYear(library: List[Book]): Double = {
    if (library.isEmpty) 0.0
    else library.map(_.year).sum.toDouble / library.length
  }

  def sortBooksByTitle(library: List[Book]): List[Book] = {
    library.sortBy(_.title)
  }

  def sortBooksByYear(library: List[Book]): List[Book] = {
    library.sortBy(_.year)
  }

  def groupBooksByCategory(library: List[Book]): Map[String, List[Book]] = {
    library.groupBy(_.category)
  }

  def partitionBooksByYear(library: List[Book], year: Int): (List[Book], List[Book]) = {
    library.partition(_.year < year)
  }

  def collectTitlesAfterYear(library: List[Book], year: Int): List[String] = {
    library.collect {
      case Book(title, _, y, _, _) if y > year => title
    }
  }

  def averagePublicationYearByCategory(library: List[Book]): Map[String, Double] = {
    val groupedByCategory = library.groupBy(_.category)
    groupedByCategory.mapValues(books => books.map(_.year).sum.toDouble / books.length)
  }

  println("Initial Library:")
  library.foreach(println)

  // Add a new book
  val newBook = Book("Sapiens", authors(6), 2011, "Non-Fiction", 19.99)
  library = addBook(library, newBook)

  println("\nLibrary after adding a new book:")
  library.foreach(println)

  // Search for books
  val searchQuery = "George Orwell"
  val searchResults = searchBooks(library, searchQuery)

  println(s"\nSearch results for '$searchQuery':")
  searchResults.foreach(println)

  // Filter by category
  val category = "Dystopian"
  val dystopianBooks = filterByCategory(library, category)

  println(s"\nBooks in the '$category' category:")
  dystopianBooks.foreach(println)

  // Calculate statistics
  val total = totalBooks(library)
  val averageYear = averagePublicationYear(library)

  println(s"\nTotal number of books: $total")
  println(f"Average publication year: $averageYear%.2f")

  // Sort books by title
  val sortedByTitle = sortBooksByTitle(library)
  println("\nBooks sorted by title:")
  sortedByTitle.foreach(println)

  // Sort books by year
  val sortedByYear = sortBooksByYear(library)
  println("\nBooks sorted by year:")
  sortedByYear.foreach(println)

  // Group books by category
  val groupedByCategory = groupBooksByCategory(library)
  println("\nBooks grouped by category:")
  groupedByCategory.foreach { case (category, books) =>
    println(s"$category:")
    books.foreach(println)
  }

  // Partition books by year
  val (before2000, after2000) = partitionBooksByYear(library, 2000)
  println("\nBooks published before 2000:")
  before2000.foreach(println)
  println("\nBooks published after 2000:")
  after2000.foreach(println)

  // Collect titles of books published after 1950
  val titlesAfter1950 = collectTitlesAfterYear(library, 1950)
  println("\nTitles of books published after 1950:")
  titlesAfter1950.foreach(println)

  // Calculate average publication year by category
  val avgYearByCategory = averagePublicationYearByCategory(library)
  println("\nAverage publication year by category:")
  avgYearByCategory.foreach { case (category, avgYear) =>
    println(s"$category: $avgYear%.2f")
  }

  // Shopping Basket functionality
  val basket = new ShoppingBasket()
  basket.addBook(library.head)
  basket.addBook(library(1))
  basket.addBook(library(2))
  basket.showBasket()
  println(s"Total cost: ${basket.totalCost}")
}