Full Code of Praful932/Kitabe for AI

master 923f937686df cached
64 files
28.7 MB
2.0M tokens
75 symbols
1 requests
Download .txt
Showing preview only (7,859K chars total). Download the full file or copy to clipboard to get everything.
Repository: Praful932/Kitabe
Branch: master
Commit: 923f937686df
Files: 64
Total size: 28.7 MB

Directory structure:
gitextract_s0diptc6/

├── .github/
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.md
│   │   └── feature_request.md
│   ├── pull_request_template.md
│   └── workflows/
│       └── tests.yml
├── .gitignore
├── .pre-commit-config.yaml
├── BookRecSystem/
│   ├── __init__.py
│   ├── asgi.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── mainapp/
│   ├── __init__.py
│   ├── admin.py
│   ├── apps.py
│   ├── forms.py
│   ├── helpers.py
│   ├── migrations/
│   │   ├── 0001_initial.py
│   │   ├── 0002_saveforlater.py
│   │   └── __init__.py
│   ├── models.py
│   ├── tests.py
│   ├── urls.py
│   ├── views.py
│   └── views_ajax.py
├── manage.py
├── pyproject.toml
├── requirements.txt
├── setup.cfg
├── static/
│   └── mainapp/
│       ├── css/
│       │   ├── explore.css
│       │   ├── genre.css
│       │   ├── index.css
│       │   ├── layout.css
│       │   ├── login.css
│       │   ├── password_reset.css
│       │   ├── read.css
│       │   ├── recommendation.css
│       │   ├── saved_book.css
│       │   └── signup.css
│       ├── dataset/
│       │   ├── books.csv
│       │   ├── books_cleaned.csv
│       │   └── full_book.csv
│       └── model_files/
│           ├── surprise/
│           │   ├── book_embedding.npy
│           │   ├── book_inner_id_to_raw.pickle
│           │   ├── book_raw_to_inner_id.pickle
│           │   └── sim_books.pickle
│           └── tf-idf/
│               ├── cosine_rating_sim.npz
│               └── indices.pkl
└── templates/
    ├── account/
    │   ├── login.html
    │   ├── password_reset.html
    │   ├── password_reset_done.html
    │   ├── password_reset_from_key.html
    │   ├── password_reset_from_key_done.html
    │   └── signup.html
    └── mainapp/
        ├── error_handler.html
        ├── explore.html
        ├── genre.html
        ├── index.html
        ├── layout.html
        ├── read.html
        ├── recommendation.html
        └── saved_book.html

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''

---

**Describe the bug**
A clear and concise description of what the bug is.

**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error

**Expected behavior**
A clear and concise description of what you expected to happen.

**Screenshots**
If applicable, add screenshots to help explain your problem.

**Are you willing to contribute to this issue?** [Yes/No]

**Desktop (please complete the following information):**
 - OS: [e.g. iOS]
 - Browser [e.g. chrome, safari]
 - Version [e.g. 22]

**Smartphone (please complete the following information):**
 - Device: [e.g. iPhone6]
 - OS: [e.g. iOS8.1]
 - Browser [e.g. stock browser, safari]
 - Version [e.g. 22]

**Additional context**
Add any other context about the problem here.


================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''

---

**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

**Describe the solution you'd like**
A clear and concise description of what you want to happen.

**Are you willing to contribute to this issue?** [Yes/No]

**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.

**Additional context**
Add any other context or screenshots about the feature request here.


================================================
FILE: .github/pull_request_template.md
================================================
## Description
- List out your changes
- Link the Issue which this resolves

## Affected Dependencies


## How has this been tested?

## GIF Before
- If any UI Changes, Use [this](https://www.screentogif.com/) to record or else specify NA

## GIF After

## Checklist
- [ ] I have followed the [Contribution Guidelines](https://github.com/Praful932/Kitabe/blob/master/CONTRIBUTING.md).
- [ ] My changes do not edit/add any unrequired files.
- [ ] My changes are covered by tests.



================================================
FILE: .github/workflows/tests.yml
================================================
# This is a basic workflow to help you get started with Actions
name: Tests
# Controls when the action will run.
on:
  # Triggers the workflow on all branches
  push:
    branches: '*'
  pull_request:
    branches: '*'

  # Allows you to run this workflow manually from the Actions tab
  workflow_dispatch:

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
  # This workflow contains a single job called "build"
  build:
    # The type of runner that the job will run on
    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: ['3.8.6']

    # Steps represent a sequence of tasks that will be executed as part of the job
    steps:
      # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
      - uses: actions/checkout@v2


      - name: Set up Python 🐍 ${{ matrix.python-version }}
        uses: actions/setup-python@v2
        with:
          python-version: ${{ matrix.python-version }}


      - name: Install dependencies
        run: |
          curl -sSL https://install.python-poetry.org | python3 -
          poetry export -f requirements.txt --output requirements.txt --without-hashes
          pip install -r requirements.txt

      - name: Run Lint and Unit Tests ⚒
        env:
          KITABE_SECRET_KEY: "RANDOM_KEY"
        run: |
          pre-commit run --all-files
          python manage.py collectstatic --no-input
          python manage.py test


================================================
FILE: .gitignore
================================================
bookenv/
.vscode
# colllect static output
staticfiles/

# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
pip-wheel-metadata/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# PyInstaller
#  Usually these files are written by a python script from a template
#  before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
target/

# Jupyter Notebook
.ipynb_checkpoints

# IPython
profile_default/
ipython_config.py

# pyenv
.python-version

# pipenv
#   According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
#   However, in case of collaboration, if having platform-specific dependencies or dependencies
#   having no cross-platform support, pipenv may install dependencies that don't work, or not
#   install all needed dependencies.
#Pipfile.lock

# PEP 582; used by e.g. github.com/David-OConnor/pyflow
__pypackages__/

# Celery stuff
celerybeat-schedule
celerybeat.pid

# SageMath parsed files
*.sage.py

# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

# Spyder project settings
.spyderproject
.spyproject

# Rope project settings
.ropeproject

# mkdocs documentation
/site

# mypy
.mypy_cache/
.dmypy.json
dmypy.json

# Pyre type checker
.pyre/


================================================
FILE: .pre-commit-config.yaml
================================================
exclude: 'wip'
repos:
- repo: https://github.com/ambv/black
  rev: 22.3.0
  hooks:
    - id: black
      name: black-py
- repo: https://github.com/asottile/pyupgrade
  rev: v2.32.0
  hooks:
  -   id: pyupgrade
      name: pyupgrade-py

================================================
FILE: BookRecSystem/__init__.py
================================================


================================================
FILE: BookRecSystem/asgi.py
================================================
"""
ASGI config for BookRecSystem project.

It exposes the ASGI callable as a module-level variable named ``application``.

For more information on this file, see
https://docs.djangoproject.com/en/3.1/howto/deployment/asgi/
"""

import os

from django.core.asgi import get_asgi_application

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "BookRecSystem.settings")

application = get_asgi_application()


================================================
FILE: BookRecSystem/settings.py
================================================
"""
Django settings for BookRecSystem project.

Generated by 'django-admin startproject' using Django 3.1.1.

For more information on this file, see
https://docs.djangoproject.com/en/3.1/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/3.1/ref/settings/
"""

from pathlib import Path
from django.contrib.messages import constants as messages
import os

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.1/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = os.environ.get("SECRET_KEY", "RANDOM_KEY")

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = str(os.environ.get("DEBUG", True)) == "True"

# Check if production environment
PROD_ENV = str(os.environ.get("PROD_ENV", False)) == "True"

ALLOWED_HOSTS = [
    "kitabe-app.herokuapp.com",
    "kitabe.up.railway.app",
    "127.0.0.1",
    "localhost",
]

CSRF_TRUSTED_ORIGINS = [
    "https://kitabe-app.herokuapp.com",
    "https://kitabe.up.railway.app",
]


# Application definition

INSTALLED_APPS = [
    "django.contrib.admin",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    # disable django static file handling during development as well
    "whitenoise.runserver_nostatic",
    "django.contrib.staticfiles",
    "django.contrib.sites",
    "allauth",
    "allauth.account",
    "allauth.socialaccount",
    "allauth.socialaccount.providers.google",
    "mainapp",
    "storages",
]

MIDDLEWARE = [
    "django.middleware.security.SecurityMiddleware",
    "whitenoise.middleware.WhiteNoiseMiddleware",
    "django.contrib.sessions.middleware.SessionMiddleware",
    "django.middleware.common.CommonMiddleware",
    "django.middleware.csrf.CsrfViewMiddleware",
    "django.contrib.auth.middleware.AuthenticationMiddleware",
    "django.contrib.messages.middleware.MessageMiddleware",
    "django.middleware.clickjacking.XFrameOptionsMiddleware",
]

ROOT_URLCONF = "BookRecSystem.urls"

TEMPLATES = [
    {
        "BACKEND": "django.template.backends.django.DjangoTemplates",
        "DIRS": [
            os.path.join(BASE_DIR, "templates"),
        ],
        "APP_DIRS": True,
        "OPTIONS": {
            "context_processors": [
                "django.template.context_processors.debug",
                "django.template.context_processors.request",
                "django.contrib.auth.context_processors.auth",
                "django.contrib.messages.context_processors.messages",
                # allauth
                "django.template.context_processors.request",
            ],
        },
    },
]

WSGI_APPLICATION = "BookRecSystem.wsgi.application"


# Database
# https://docs.djangoproject.com/en/3.1/ref/settings/#databases
if PROD_ENV:
    DATABASES = {
        "default": {
            "ENGINE": "django.db.backends.postgresql",
            "NAME": os.environ.get("PGDATABASE"),
            "USER": os.environ.get("PGUSER"),
            "PASSWORD": os.environ.get("PGPASSWORD"),
            "HOST": os.environ.get("PGHOST"),
            "PORT": os.environ.get("PGPORT"),
        }
    }
else:
    DATABASES = {
        "default": {
            "ENGINE": "django.db.backends.sqlite3",
            "NAME": BASE_DIR / "db.sqlite3",
        }
    }


# Password validation
# https://docs.djangoproject.com/en/3.1/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
    },
    {
        "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",
    },
    {
        "NAME": "django.contrib.auth.password_validation.CommonPasswordValidator",
    },
    {
        "NAME": "django.contrib.auth.password_validation.NumericPasswordValidator",
    },
]


# Internationalization
# https://docs.djangoproject.com/en/3.1/topics/i18n/

LANGUAGE_CODE = "en-us"

TIME_ZONE = "Asia/Calcutta"

USE_I18N = True

USE_L10N = True

USE_TZ = True


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.1/howto/static-files/

# url/placeholder path at which static files are served
STATIC_URL = "/static/"
# other folders to look for static files
STATICFILES_DIRS = [os.path.join(BASE_DIR, "static")]
STATICFILES_STORAGE = "whitenoise.storage.CompressedManifestStaticFilesStorage"

# Deployment
# Directory where collectstatic will collect the static files for deployment
STATIC_ROOT = os.path.join(BASE_DIR, "staticfiles")


AUTHENICATION_BACKENDS = [
    "django.contrib.auth.backends.ModelBackend",
    # allauth
    "allauth.account.auth_backends.AuthenicationBackend",
]

SITE_ID = 1

SOCIALACCOUNT_PROVIDERS = {
    "google": {
        "APP": {
            "client_id": os.environ.get("KITABE_AUTH_ID"),
            "secret": os.environ.get("KITABE_AUTH_SECRET"),
            "key": "",
        }
    }
}

DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"

# media files
MEDIA_ROOT = os.path.join(BASE_DIR, "media")
MEDIA_URL = "/media/"

LOGIN_REDIRECT_URL = "index"
LOGOUT_REDIRECT_URL = "index"

# simple mail transfer protocal
# EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend"
EMAIL_HOST = "smtp.gmail.com"
EMAIL_PORT = 587
EMAIL_USE_TLS = True
EMAIL_HOST_USER = os.environ.get("KITABE_EMAIL")
EMAIL_HOST_PASSWORD = os.environ.get("KITABE_PASS")

# Alluth Settings
ACCOUNT_AUTHENTICATION_METHOD = "username"
ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_EMAIL_VERIFICATION = "none"
ACCOUNT_LOGOUT_ON_GET = True

if not DEBUG:
    # access via https in production
    ACCOUNT_DEFAULT_HTTP_PROTOCOL = "https"

MESSAGE_TAGS = {
    messages.DEBUG: "alert-info",
    messages.INFO: "alert-info",
    messages.SUCCESS: "alert-success",
    messages.WARNING: "alert-warning",
    messages.ERROR: "alert-danger",
}


================================================
FILE: BookRecSystem/urls.py
================================================
"""BookRecSystem URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/3.1/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    path("", include("mainapp.urls")),
    path("admin/", admin.site.urls),
    path("accounts/", include("allauth.urls")),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
# error handler
handler404 = "mainapp.views.handler404"
handler500 = "mainapp.views.handler500"


================================================
FILE: BookRecSystem/wsgi.py
================================================
"""
WSGI config for BookRecSystem project.

It exposes the WSGI callable as a module-level variable named ``application``.

For more information on this file, see
https://docs.djangoproject.com/en/3.1/howto/deployment/wsgi/
"""

import os

from django.core.wsgi import get_wsgi_application

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "BookRecSystem.settings")

application = get_wsgi_application()


================================================
FILE: CONTRIBUTING.md
================================================
## Contributing Guidelines

You are **Awesome!** Thank you for your Interest in Contributing to this Project 🤗
For Contributions we strictly follow [Github Flow](https://guides.github.com/introduction/flow/).

## Contents

- [Setting Up the Project](#user-content-setting-up-the-project)
- [Contributing](#user-content-contributing)

### Setting Up the Project

1. The Project works seamlessly on Python version `3.8.6`

2. (Optional) [Fork](https://docs.github.com/en/github/getting-started-with-github/fork-a-repo#fork-an-example-repository) the Repository

3. Clone Your Forked copy/the original repo - `git clone https://github.com/[YOUR-USERNAME]/Kitabe.git`

4.  Navigate to the directory of project -  `cd Kitabe/`


5. (Optional) If you're intending to raise an MR else you can skip this step, Create a new branch -  `git checkout -b [branch_name]`

6. Install requirements from [poetry](https://python-poetry.org/docs/#installation) - `poetry install`
    - If you prefer the vanilla route `poetry export -f requirements.txt --output requirements.txt --without-hashes` skip to step (8)


7. Activate the environment -  `poetry shell`

8. Open `BookRecSystem/settings.py`

9. Make Migrations - `python manage.py migrate`

10. `python manage.py runserver` - You're good to Go!!

📝 Raise an issue/start a discussion if you face difficulties while setting up the repo, we'll try to resolve it asap
#### Optional

- [Setting up Google Auth](https://django-allauth.readthedocs.io/en/latest/installation.html)

- [Setting up SMTP](https://youtu.be/-tyBEsHSv7w)

- [Creating Superuser](https://www.geeksforgeeks.org/how-to-create-superuser-in-django/)

### Contributing

- Please go through [Github Flow](https://guides.github.com/introduction/flow/), if not already. :)

- Take up an [Issue](https://github.com/Praful932/Kitabe/issues) or [Raise](https://github.com/Praful932/Kitabe/issues/new) one.

- Discuss your proposed changes & Get assigned.

- If your changes are approved, do the changes in branch `[branch_name]`.

- Run tests

- `flake8`, `python manage.py test`

- Fix if any test fails.

- Still in branch `[branch_name].`

- **Stage and Commit only the required files.**

- `git push origin [branch_name] -u`

- Browse [here](https://github.com/Praful932/Kitabe) and create a PR from your branch with the appropriate required details.

- If your PR is accepted, it is automatically deployed once merged. :)

- That's it!

**Tip**: To keep your Fork Repo all branches updated with Upstream use [this](https://upriver.github.io/).


================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2020 Praful932

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: README.md
================================================

![1](https://user-images.githubusercontent.com/45713796/98271308-d18aac80-1fb5-11eb-9db3-dda942cc1b07.png)


**Kitabe** (*Book in Hindi*) is a Book Recommendation System built for all you Book Lovers📖.
Simply Rate ⭐ some books and get immediate recommendations tailored for you 🤩.<br>
See [Demo](#user-content-demo-) 🎥

[![Website shields.io](https://img.shields.io/website-up-down-green-red/http/shields.io.svg)](https://kitabe.up.railway.app/)
[![Build Status](https://travis-ci.com/Praful932/Kitabe.svg?token=XKcoN48yFyATXWUZ6d8j&branch=master)](https://travis-ci.com/Praful932/Kitabe)
[![contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](https://github.com/Praful932/Kitabe/blob/master/CONTRIBUTING.md)
[![GitHub license](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE) <br>
[![Hits](https://hits.seeyoufarm.com/api/count/incr/badge.svg?url=https%3A%2F%2Fgithub.com%2FPraful932%2FKitabe&count_bg=%2379C83D&title_bg=%23555555&icon=&icon_color=%23E7E7E7&title=hits&edge_flat=false)](https://hits.seeyoufarm.com)
[![Maintenance](https://img.shields.io/badge/Maintained%3F-yes-green.svg)](https://GitHub.com/Praful932/Kitabe/graphs/commit-activity)
![GitHub stars](https://img.shields.io/github/stars/Praful932/Kitabe?style=social) ![GitHub forks](https://img.shields.io/github/forks/Praful932/Kitabe?style=social) ![GitHub watchers](https://img.shields.io/github/watchers/Praful932/Kitabe?style=social)

For Contributing 💜 and setting Up head [here](https://github.com/Praful932/Kitabe/blob/master/CONTRIBUTING.md).

# Contents
- [Demo](#user-content-demo-) 🎥
- [Approach](#objective-) 🧐
    - [Objective](#objective-) ✍
    - [Dataset](#dataset-) 🧾
    - [PreProcessing](#preprocessing-) 🛠
    - [Model Exploration](#model-exploration-) 🤯
    - [Final Result](#final-result-) 😁
- [Project Structure](#project-structure-%EF%B8%8F) 💁‍♀️
- [To Do](#to-do-) 🎯
- [Contribute](https://github.com/Praful932/Kitabe/blob/master/CONTRIBUTING.md) 🧏‍♂️
- [Notebooks and Files](#notebooks-and-files-) 📓
- [References](#references-) 😇
- [Contributors](#contributors-) 🤗
- [License](#license-) ✍

### Demo 🎥

![kitabe](https://user-images.githubusercontent.com/45713796/98460071-f6a23980-21c6-11eb-881f-ba0f75896751.gif)<br>
[Live Application](https://kitabe.up.railway.app/) 🌐

### Objective ✍
Our objective is to build an application for all Book Lovers ♥ like us out there where all you have to
do is rate some of your favorite books and the application will do it's **voodoo magic** 🧙‍♂️ and give you some more books that you may **love😍 to read**.

### Dataset 🧾
The Dataset that we used for this task is the [goodbooks-10k](https://github.com/zygmuntz/goodbooks-10k) dataset. It consists of 10k books with a total of 6 million ratings. That's huge right! 😮. There are some more huge datasets such as [Book-Crossings](http://www2.informatik.uni-freiburg.de/~cziegler/BX/) but they are kinda old 😬.

**Dataset Structure**
```
GoodBooks10k
    ├── books.csv         # Contains book info with book-id
    ├── ratings.csv       # Maps user-id to book-id and rating
    ├── book_tags.csv     # Contains tag-id associated with book-ids
    ├── tags.csv          # Contains tag-name associated with tag-id
    ├── to_read.csv       # Contains book-ids marked as to-read by user
```

### PreProcessing 🛠
Since this is a recommendation problem, we have to make sure that the `books.csv` is as clean as possible and only consider those ratings whose book-id is present, same goes for vice versa.

More Cleaning for `books.csv`
- Missing Book Image URLs
- Book & Rating Duplicates

### Model Exploration 🤯
For Recommendation Problems there are multiple approaches that are possible:
- Embedding Matrix
- Singular Matrix Decomposition
- Term Frequency

We experimented with several methods and chose Embedding Matrix & Term Frequency.

- **Embedding Matrix** - This method is often called [FunkSVD](https://www.coursera.org/lecture/matrix-factorization/deriving-funksvd-lyTpD) which won the Netflix Prize back in 2004. Since it is a gradient based function minimization approach we like to call it as Embedding Matrix. Calling it SVD [confuses](https://www.quora.com/What-is-the-difference-between-SVD-and-matrix-factorization-in-context-of-recommendation-engine/answer/Luis-Argerich) it with the one in Linear Algebra. This Embedding Matrix constructs a vector for each user and each book, such that when the product is applied with additional constraints it gives us the rating. For more elaborate info on FunkSVD refer [this](http://sifter.org/~simon/journal/20061211.html).
We used the book embedding as a representation of the books to infer underlying patterns. This led to the embedding able to detect books from the same authors and also infer genres such as Fiction, Autobiography and more.

- **Term Frequency** - This method is like a helper function to above, it shines where embedding fails. Term Frequency takes into account the tokens in a book title be it the book title itself, the name of authors and also rating. Taking into consideration it finds books which match closely with the tokens in the rated book.

> 🛠 Code for every step can be found in the [Notebooks and Files](#notebooks-and-files) Section.

### Final Result 😁
The [Image](https://coggle.it/diagram/X6TOUxlMvSl8FBM4/t/dataset/7083ac4f2de39517a4d97cd9d3d211c11af6e65f9a0034c46d613ff0f9cd5) says it All.

![coggle](https://user-images.githubusercontent.com/45713796/98331008-ae95e200-2021-11eb-915b-892854f88a6e.png)


### Project Structure 💁‍♀️
```
Kitabe
│
├───BookRecSystem               # Main Project Directory
│
├───mainapp                     # Project Main App Directory
│   │
│   └───migrations              # Migrations
│
├───static
|   |                           # Static Directory
│   └───mainapp
│       ├───css                 # CSS Files
|       |
│       ├───dataset             # Dataset Files
│       │
│       ├───gif                 # GIF Media
│       │
│       ├───model_files         # Model Files
|       |   |
│       │   ├───surprise        # FunkSVD Files
│       │   │
│       │   └───cv              # CV Files
│       │
│       └───png                 # PNG Media FIles
|
└───templates                   # Root Template DIrectory
    |
    ├───account                 # Account App Templates
    │
    └───mainapp                 # Project Main App Templates

```

### To Do 🎯
- [X] Display Popular Books Among Users
- [X] Add AJAX View Tests
- [X] Add Model Tests
- [X] Use a Better Approach than Count Vectorizer

### Notebooks and Files 📓
- [All Dataset & Model Files](https://drive.google.com/drive/folders/1SvuCvfiSxwuF21EvmKyhSkuwjgK7KU6S?usp=sharing)
- [Cleaning and Embedding Notebook](https://drive.google.com/file/d/1wlKiSvYQEXG7xtru5jDQWQwxffaVd9Ap/view?usp=sharing)
- [Fix Missing Images Notebook](https://drive.google.com/file/d/1S0pd5t9oU9a63EdmlXmxhNWGc228W3ke/view?usp=sharing)
- [Genre Wise & Tfidf Vectorizer Notebook](https://drive.google.com/file/d/1LRr4Nm2I2HRJUTXbRea3sK5A1Bvp_lav/view?usp=sharing)

### References 😇

- [Dataset](https://github.com/zygmuntz/goodbooks-10k)
- [Count Vectorizer](https://www.kaggle.com/sasha18/recommend-books-using-count-tfidf-on-titles)
- [Books2Rec](https://github.com/dorukkilitcioglu/books2rec)

### Contributors 🤗
![2](https://contributors-img.web.app/image?repo=Praful932/Kitabe)

### License ✍
```
MIT License

Copyright (c) 2020 Praful Mohanan & Prajakta Mane

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
```


================================================
FILE: mainapp/__init__.py
================================================


================================================
FILE: mainapp/admin.py
================================================
from django.contrib import admin
from mainapp.models import UserRating, SaveForLater

# Register your models here.

admin.site.register(UserRating)
admin.site.register(SaveForLater)


================================================
FILE: mainapp/apps.py
================================================
from django.apps import AppConfig


class MainappConfig(AppConfig):
    name = "mainapp"


================================================
FILE: mainapp/forms.py
================================================


================================================
FILE: mainapp/helpers.py
================================================
import pandas as pd
import numpy as np
import os
import math
import pickle
import operator
import random
from collections import Counter
import BookRecSystem.settings as settings
import mainapp.models

book_path = os.path.join(settings.STATICFILES_DIRS[0] + "/mainapp/dataset/books.csv")

# For Count Vectorizer
cosine_sim_path = os.path.join(
    settings.STATICFILES_DIRS[0] + "/mainapp/model_files/tf-idf/cosine_rating_sim.npz"
)
book_indices_path = os.path.join(
    settings.STATICFILES_DIRS[0] + "/mainapp/model_files/tf-idf/indices.pkl"
)

# For Embedding
book_id_map_path = os.path.join(
    settings.STATICFILES_DIRS[0]
    + "/mainapp/model_files/surprise/book_raw_to_inner_id.pickle"
)
book_raw_map_path = os.path.join(
    settings.STATICFILES_DIRS[0]
    + "/mainapp/model_files/surprise/book_inner_id_to_raw.pickle"
)
book_embed_path = os.path.join(
    settings.STATICFILES_DIRS[0] + "/mainapp/model_files/surprise/book_embedding.npy"
)
sim_books_path = os.path.join(
    settings.STATICFILES_DIRS[0] + "/mainapp/model_files/surprise/sim_books.pickle"
)

with open(book_id_map_path, "rb") as handle:
    book_raw_to_inner_id = pickle.load(handle)

with open(book_raw_map_path, "rb") as handle:
    book_inner_id_to_raw = pickle.load(handle)
book_embedding = np.load(book_embed_path)

with open(sim_books_path, "rb") as handle:
    sim_books_dict = pickle.load(handle)

cols = ["original_title", "authors", "average_rating", "image_url", "book_id"]

df_book = pd.read_csv(book_path)
total_books = df_book.shape[0]


def is_rating_invalid(rating):
    """Return a boolean value.

    Checks if the rating is invalid.

    Parameters
    ----------
    rating : int
        Rating of a book, which should be a digit <= 5.

    Returns
    -------
    bool
        `True` if the rating is invalid, else `False`.

    """
    if not rating or not rating.isdigit():
        return True
    if int(rating) > 5:
        return True
    return False


def is_bookid_invalid(bookid):
    """Return a boolean value.

    Checks if the bookid is invalid.

    Parameters
    ----------
    bookid : int
        book-id of the book to be checked for existence.

    Returns
    -------
    bool
        `True` if the bookid exists, else `False`.

    """
    if not bookid or not bookid.isdigit():
        return True
    elif sum(df_book["book_id"] == int(bookid)) == 0:
        # If bookid does not exist
        return True
    return False


def get_book_title(bookid):
    """Return book title given bookid.

    Parameters
    ----------
    bookid : int
        book-id of a book whose title needs to be determined.

    Returns
    -------
    bookname : str
        Title of the book corresponding the given book id.

    """
    return df_book[df_book["book_id"] == bookid]["original_title"].values[0]


def get_book_ids(index_list):
    """Return bookids given list of indexes.

    Parameters
    ----------
    index_list : list
        List of indexes for which the book-ids are to be determined.

    Returns
    -------
    bookid_list : list
        List of bookids corresponding to given list of indexes.

    """
    bookid_list = list(df_book.loc[index_list].book_id.values)
    return bookid_list


def get_rated_bookids(user_ratings):
    """Return list of already rated bookids.

    Parameters
    ----------
    user_ratings : list
        List of ratings by the users.

    Returns
    -------
    already_rated : list
        List of book-ids, corresponding to the books already rated by the users.

    """
    already_rated = []
    for rating in user_ratings:
        book_id = rating.bookid
        already_rated.append(book_id)
    return already_rated


def get_raw_id(book_id):
    """Return raw_id given book_id.

    Parameters
    ----------
    book_id : int
        Integer to determine the raw-id of a book.

    Returns
    -------
    raw_id : int
        Corresponding raw_id of the book_id.

    """
    raw_id = df_book[df_book.book_id == book_id]["r_index"].values[0]
    return raw_id


def get_bookid(raw_id_list):
    """Return bookid list given rawid list.

    Parameters
    ----------
    raw_id_list : list
        List containing raw-ids to determine respective book-ids.

    Returns
    -------
    bookid_list : list
        List of bookids corresponding to raw ids.

    """
    bookid_list = list(df_book[df_book.r_index.isin(raw_id_list)]["book_id"].values)
    return bookid_list


def genre_wise(genre, percentile=0.85):
    """Return top genre books according to a cutoff percentile.

    Parameters
    ----------
    genre : str
        Genre of the book in string format.

    percentile : float
         Float determinig the cutoff percentile (Default value = `0.85`).

    Returns
    -------
    df : pandas.core.frame.DataFrame
        Top genre books according to a cutoff percentile.

    """
    n_books = 16
    min_genre_book_count = 48

    qualified = df_book[df_book.genre.str.contains(genre.lower())]
    # Imdb Formula
    v = qualified["ratings_count"]
    m = qualified["ratings_count"].quantile(percentile)
    R = qualified["average_rating"]
    C = qualified["average_rating"].mean()
    W = (R * v + C * m) / (v + m)
    qualified = qualified.assign(weighted_rating=W)
    qualified.sort_values("weighted_rating", ascending=False, inplace=True)

    return qualified[cols].head(min_genre_book_count).sample(n_books)


def tfidf_recommendations(bookid):
    """Return recommenedations based on count vectorizer.

    Parameters
    ----------
    bookid : int
        Integer which needs to be passed in order to get book-title.

    Returns
    -------
    bookid_list : list
        List of bookids based on count vectorizer.

    """
    indices = pd.read_pickle(book_indices_path)
    cosine_sim = np.load(cosine_sim_path)["array1"]
    book_title = get_book_title(bookid)
    book_title = book_title.replace(" ", "").lower()
    idx = indices[book_title]

    # Get this books similarity with all other books, enum to keep track of book index
    sim_scores = list(enumerate(cosine_sim[idx]))
    sim_scores = sorted(sim_scores, key=lambda x: x[1], reverse=True)
    sim_scores = sim_scores[1:10]

    book_indices = [i[0] for i in sim_scores]
    bookid_list = get_book_ids(book_indices)
    return bookid_list


def embedding_recommendations(sorted_user_ratings):
    """Return recommended book ids based on embeddings.

    Parameters
    ----------
    sorted_user_ratings : list
        List containing the ratings given by user.

    Returns
    -------
    similar_bookid_list : list
        A list of recommended book ids based on embeddings.

    """
    best_user_books = []
    similar_bookid_list = []
    max_user_rating_len = 10
    # Only keep user rating >= 4
    threshold = 4
    top_similiar = 2

    for i, rating in enumerate(sorted_user_ratings):
        if rating.bookrating < threshold or i > max_user_rating_len:
            break
        else:
            best_user_books.append(rating.bookid)

    for book in best_user_books:
        raw_id = get_raw_id(book)
        top_sim_books = [
            book for book, similiarity in sim_books_dict[raw_id][:top_similiar]
        ]
        similar_bookid_list.extend(top_sim_books)

    similar_bookid_list = get_bookid(similar_bookid_list)

    return similar_bookid_list


def get_book_dict(bookid_list):
    """Return book details based on provided bookids.

    Parameters
    ----------
    bookid_list : list
        List containing book-ids which needs to be passed to determine book-details.

    Returns
    -------
    rec_books_dict : dict
        Dictionary of book details based on provided list of bookids.

    """
    rec_books_dict = df_book[df_book["book_id"].isin(bookid_list)][cols].to_dict(
        "records"
    )
    return rec_books_dict


def combine_ids(tfidf_bookids, embedding_bookids, already_rated, recommendations=9):
    """Return best bookids combining both approaches.

        Embedding - Top 6
        Tf-Idf - Top 3

    Parameters
    ----------
    tfidf_bookids : list
        List containing book-ids of books based on Tf-Idf.

    embedding_bookids : list
        List containing book-ids of books rated by users.

    already_rated : list
        List containing book-ids of already rated books.

    recommendations : int
         Integer denoting the number of recommendations (Default value = 9).

    Returns
    -------
    best_bookids : list
        List containing bookids of top books based on embeddings and tfidf.

    """
    tfidf_bookids = list(tfidf_bookids.difference(already_rated))
    top_3_tfidf = set(tfidf_bookids[:3])
    embedding_bookids = embedding_bookids.difference(already_rated)
    embedding_bookids = list(embedding_bookids.difference(top_3_tfidf))
    top_3_tfidf = list(top_3_tfidf)
    top_6_embed = list(embedding_bookids[:6])
    best_bookids = top_3_tfidf + top_6_embed

    # If not enough recommendations
    if len(best_bookids) < recommendations:
        two_n = recommendations - len(best_bookids)
        # Divide remaining recommendations into two parts
        n1, n2 = math.ceil(two_n / 2), math.floor(two_n / 2)

        # n1 number of books from remaining tf_idf books
        best_bookids_tfidf = tfidf_bookids[3 : (3 * 2) + n1]
        best_bookids_tfidf = list(
            set(best_bookids_tfidf).difference(set(best_bookids))
        )[:n1]

        # n2 number of books from list of top rated books of the most common genre among the books yet recommended
        genre_recomm_bookids = most_common_genre_recommendations(
            best_bookids + already_rated + best_bookids_tfidf, n2
        )

        # number of recommendations = len(best_bookids) + n1 + n2 = len(best_bookids) + two_n
        best_bookids = best_bookids + best_bookids_tfidf + genre_recomm_bookids
    return best_bookids


def most_common_genre_recommendations(books, n):
    """Returns n top rated of the most_common_genre among all lists taken as input

    Parameters
    ----------
    books : list
        List of books to find common genre for
    n : int
        Integer denoting the number of books required (Default value = 9).
    Returns
    -------
    genre_recommendations : list
        List containing n number of books of the most common genre among all the input books.
    """

    # Accumulation of all the genres listed from books
    genre_frequency = []
    for book in books:
        genre_frequency.append(
            df_book[df_book["book_id"] == book]["genre"].values[0].split(", ")[0]
        )

    most_common_genre = sorted(Counter(genre_frequency).most_common())[0][0]

    # Recommendations list, listing 2n bookids
    genre_recommendations = genre_wise(most_common_genre).book_id.to_list()[: 2 * n]
    # Removing common bookids from `books` and Slicing out the first n bookids
    genre_recommendations = list(set(genre_recommendations).difference(books))[:n]

    return genre_recommendations


def get_top_n(top_n=400):
    """Return a sample of top N books based on weighted average ratings.

    Parameters
    ----------
    top_n : int
         Number of samples to be returned (Default value = 400).

    Returns
    -------
    df : pandas.core.frame.DataFrame
        Sample of top N books.

    """
    df_books_copy = df_book.copy()
    v = df_books_copy["ratings_count"]
    m = df_books_copy["ratings_count"].quantile(0.95)
    R = df_books_copy["average_rating"]
    C = df_books_copy["average_rating"].mean()
    W = (R * v + C * m) / (v + m)
    df_books_copy = df_books_copy.assign(weighted_rating=W)
    qualified = df_books_copy.sort_values("weighted_rating", ascending=False)[
        cols
    ].head(top_n)
    return qualified.sample(top_n)


def popular_among_users(N=15):
    """Return Popular Books Among Users in the rating range 4-5.

        If enough books are not available, top books are
        sampled randomly.

    Parameters
    ----------
    N : int
         Number of samples to be returned (Default value = 15).

    Returns
    -------
    book_details : dict
        Dictionary of book details.

    """
    all_ratings = list(mainapp.models.UserRating.objects.all().order_by("-bookrating"))
    random.shuffle(all_ratings)
    best_user_ratings = sorted(
        all_ratings, key=operator.attrgetter("bookrating"), reverse=True
    )

    filtered_books = set()
    for i, rating in enumerate(best_user_ratings):
        if rating.bookrating >= 4:
            filtered_books.add(rating.bookid)
        elif rating.bookrating < 4 or len(filtered_books) == N:
            break

    remaining_books_nos = N - len(filtered_books)
    if remaining_books_nos >= 0:
        rem_books = get_top_n(2 * N)["book_id"].tolist()
        filtered_books = (
            list(filtered_books)
            + list(set(rem_books) - filtered_books)[:remaining_books_nos]
        )

    return get_book_dict(filtered_books)


================================================
FILE: mainapp/migrations/0001_initial.py
================================================
# Generated by Django 3.1.1 on 2020-09-27 15:02

from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

    initial = True

    dependencies = [
        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
    ]

    operations = [
        migrations.CreateModel(
            name="UserRating",
            fields=[
                (
                    "id",
                    models.AutoField(
                        auto_created=True,
                        primary_key=True,
                        serialize=False,
                        verbose_name="ID",
                    ),
                ),
                ("bookid", models.IntegerField()),
                ("bookrating", models.IntegerField()),
                (
                    "user",
                    models.ForeignKey(
                        on_delete=django.db.models.deletion.CASCADE,
                        related_name="user_rating",
                        to=settings.AUTH_USER_MODEL,
                    ),
                ),
            ],
        ),
    ]


================================================
FILE: mainapp/migrations/0002_saveforlater.py
================================================
# Generated by Django 3.1.6 on 2021-04-14 18:18

from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

    dependencies = [
        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
        ("mainapp", "0001_initial"),
    ]

    operations = [
        migrations.CreateModel(
            name="SaveForLater",
            fields=[
                (
                    "id",
                    models.AutoField(
                        auto_created=True,
                        primary_key=True,
                        serialize=False,
                        verbose_name="ID",
                    ),
                ),
                ("bookid", models.IntegerField()),
                (
                    "user",
                    models.ForeignKey(
                        on_delete=django.db.models.deletion.CASCADE,
                        to=settings.AUTH_USER_MODEL,
                    ),
                ),
            ],
        ),
    ]


================================================
FILE: mainapp/migrations/__init__.py
================================================


================================================
FILE: mainapp/models.py
================================================
from django.db import models
from django.contrib.auth.models import User
from mainapp.helpers import get_book_title

import BookRecSystem.settings as settings
import pandas as pd
import os

book_path = os.path.join(settings.STATICFILES_DIRS[0] + "/mainapp/dataset/books.csv")
df_book = pd.read_csv(book_path)


class UserRating(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="user_rating")
    bookid = models.IntegerField()
    bookrating = models.IntegerField()

    def __str__(self):
        return (
            self.user.username.capitalize()
            + "- "
            + get_book_title(self.bookid)
            + "  - "
            + str(self.bookrating)
        )


class SaveForLater(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    bookid = models.IntegerField()

    def __str__(self):
        return self.user.username.capitalize() + "- " + get_book_title(self.bookid)


================================================
FILE: mainapp/tests.py
================================================
from django.urls import reverse, resolve
from django.test import TestCase, Client
from mainapp import views
from django.contrib.auth.models import User
from mainapp.models import UserRating, SaveForLater
from mainapp.helpers import most_common_genre_recommendations
import pandas as pd
import os
import random
import math
import BookRecSystem.settings as settings


class HomeTests(TestCase):
    """
    Index View Test Case
    """

    def setUp(self):
        self.url = reverse("index")

    def test_home_view_status_code(self):
        """
        Index View Status Code
        """
        response = self.client.get(self.url)
        self.assertEqual(response.status_code, 200)

    def test_home_url_resolves_home_view(self):
        """
        Root URL Status Code
        """
        view = resolve("/")
        self.assertEqual(view.func, views.index)


class GenreTestCase(TestCase):
    """
    Genre View Test Case
    """

    def setUp(self):
        self.genres = [
            "art",
            "biography",
            "business",
            "Christian",
            "Comics",
            "Contemporary",
            "Cookbooks",
            "Crime",
            "Fantasy",
            "Fiction",
            "History",
            "Horror",
            "Manga",
            "Memoir",
            "Mystery",
            "Nonfiction",
            "Paranormal",
            "Philosophy",
            "Poetry",
            "Psychology",
            "Religion",
            "Science",
            "Suspense",
            "Spirituality",
            "Sports",
            "Thriller",
            "Travel",
            "Classics",
        ]

    def test_genre_status_code(self):
        """
        All Genre Tests
        """
        for genre in self.genres:
            url = reverse("genre_books", kwargs={"genre": genre})
            response = self.client.get(url)
            self.assertEqual(response.status_code, 200)


class ExploreTestCase(TestCase):
    """
    Explore View Test Case
    """

    def setUp(self):
        self.url = reverse("explore_books")

    def test_explore_status_code(self):
        """
        Explore View Status Code
        """
        response = self.client.get(self.url)
        self.assertEqual(response.status_code, 200)


class SearchAjaxTestCase(TestCase):
    """
    AJAX Search View Test Case
    """

    def setUp(self):
        self.url = reverse("search_ajax")

    def test_search_ajax_view_status_code(self):
        """
        AJAX Test request with valid and invalid Book Name
        """
        response = self.client.post(
            self.url, data={"bookName": "Text"}, HTTP_X_REQUESTED_WITH="XMLHttpRequest"
        )
        self.assertEqual(response.status_code, 200)
        self.assertIn("true", response.content.decode("utf-8"))

        response = self.client.post(
            self.url, data={}, HTTP_X_REQUESTED_WITH="XMLHttpRequest"
        )
        self.assertEqual(response.status_code, 200)
        self.assertIn("false", response.content.decode("utf-8"))


class BookSummaryTestCase(TestCase):
    """
    Book Summary View Test Case
    """

    def setUp(self):
        self.url = reverse("summary_ajax")
        self.inputs = ["random_text", 1e10, ""]

    def test_book_summary_view_status_code(self):
        """
        AJAX Test request with valid and invalid Book Id
        """
        for ele in self.inputs:
            response = self.client.post(
                self.url, data={"bookid": ele}, HTTP_X_REQUESTED_WITH="XMLHttpRequest"
            )
            self.assertEqual(response.status_code, 200)
            self.assertIn("false", response.content.decode("utf-8"))


class BookDetailsTestCase(TestCase):
    """
    AJAX Book Details View Test Case
    """

    def setUp(self):
        self.url = reverse("book_details")
        self.inputs = ["random_text", 1e10, ""]

    def test_book_details_view_status_code(self):
        """
        AJAX Test request with valid and invalid Book Id
        """
        for ele in self.inputs:
            response = self.client.post(
                self.url, data={"bookid": ele}, HTTP_X_REQUESTED_WITH="XMLHttpRequest"
            )
            self.assertEqual(response.status_code, 200)
            self.assertIn("false", response.content.decode("utf-8"))


class UserRateBookTestCase(TestCase):
    """
    AJAX User Rate Book Test Case
    """

    def setUp(self):
        self.client = Client()
        self.user = User.objects.create_user(
            username="test_user", email="qwe@gmail.com"
        )
        self.user.set_password("foopassword")
        self.user.save()
        self.url = reverse("user_rate_book")
        self.inputs = [("random_text", 7), (1e10, 5), ("", 1.0)]

    def test_user_rated_book_invalid(self):
        """
        Test User Rates Book with invalid bookid
        with/out login
        """
        for bookid, bookrating in self.inputs:
            response = self.client.post(
                self.url,
                data={"bookid": bookid, "bookrating": bookrating},
                HTTP_X_REQUESTED_WITH="XMLHttpRequest",
            )
            self.assertEqual(response.status_code, 302)

        self.client.login(username="test_user", password="foopassword")
        for bookid, bookrating in self.inputs:
            response = self.client.post(
                self.url,
                data={"bookid": bookid, "bookrating": bookrating},
                HTTP_X_REQUESTED_WITH="XMLHttpRequest",
            )
            self.assertEqual(response.status_code, 200)
            self.assertIn("false", response.content.decode("utf-8"))
        self.client.logout()

    def test_user_rated_book_valid(self):
        """
        Test User Rates Book with valid bookid
        with/out login
        """
        valid_book_id = 2
        valid_bookrating = 4

        response = self.client.post(
            self.url,
            data={"bookid": valid_book_id, "bookrating": valid_bookrating},
            HTTP_X_REQUESTED_WITH="XMLHttpRequest",
        )
        self.assertEqual(response.status_code, 302)

        self.client.login(username="test_user", password="foopassword")

        response = self.client.post(
            self.url,
            data={"bookid": valid_book_id, "bookrating": valid_bookrating},
            HTTP_X_REQUESTED_WITH="XMLHttpRequest",
        )
        self.assertEqual(response.status_code, 200)
        self.assertIn("true", response.content.decode("utf-8"))

        rating = UserRating.objects.get(bookid=valid_book_id)
        self.assertEqual(rating.bookrating, valid_bookrating)
        self.assertEqual(rating.user, self.user)
        self.client.logout()


class MostCommonGenreTestCase(TestCase):
    """
    Test most common genre books when recommendations are short
    """

    def setUp(self):
        self.SEED = 42
        self.df_book = pd.read_csv(
            os.path.join(settings.STATICFILES_DIRS[0] + "/mainapp/dataset/books.csv")
        )

    def test_genre_driver(self):
        test_cases = [
            (10, 5, 1),
            (10, 5, 2),
            (10, 5, 3),
            (10, 5, 4),
            (10, 5, 5),
            (10, 6, 1),
            (10, 6, 1),
            (10, 6, 2),
            (10, 6, 3),
            (10, 6, 4),
            (10, 7, 1),
            (10, 7, 2),
            (10, 7, 3),
            (10, 8, 1),
            (10, 8, 2),
            (10, 9, 1),
            (10, 10, 0),
        ]
        for tnum, already_slice, bestbookids_slice in test_cases:
            all_books, n2 = self.template(tnum, already_slice, bestbookids_slice)
            genre_recomm_bookids = most_common_genre_recommendations(all_books, n2)
            if n2:
                genre_recomm_bookids = most_common_genre_recommendations(all_books, n2)
                self.assertEqual(len(genre_recomm_bookids), n2)

    def template(self, tnum, already_slice, bestbookids_slice):
        """
        Generates `tnum` random bookids, divides the bookids into 3 input variables of the function `most_common_genre_recommendations`
        The variables store,
        already_rated - books rated by user
        best_bookids - books recommended consisting of top 6 bookids from embedding_bookids and top 3 from tfidf recommendations
        best_bookids_tfidf - `n1` books taken from remaining tfidf recommendations
        """
        random.seed(self.SEED)
        books = random.sample(self.df_book.book_id.to_list(), tnum)
        already_rated = books[:already_slice]
        best_bookids = books[already_slice : already_slice + bestbookids_slice]
        n1 = math.ceil((9 - len(best_bookids)) / 2)
        n2 = math.floor((9 - len(best_bookids)) / 2)
        best_bookids_tfidf = books[tnum - n1 + 1 :]
        all_books = best_bookids + already_rated + best_bookids_tfidf
        return all_books, n2


class RatedBooksTestCase(TestCase):
    """Already Read Books View Test Case"""

    def setUp(self):
        self.client = Client()
        self.user = User.objects.create_user(
            username="test_user", email="qwe@gmail.com"
        )
        self.user.set_password("foopassword")
        self.user.save()
        self.url = reverse("read_books")

    def test_redirect_if_not_rated(self):
        """Test If The read_books Redirects
        Accordingly When No Book Is Rated
        """
        self.client.login(username="test_user", password="foopassword")
        response = self.client.get(self.url)
        self.assertRedirects(response, reverse("index"))
        self.client.logout()

    def test_read_book_status_code(self):
        """Test The Status Code Of read_books
        When Book Has Been Rated
        """
        self.userRating = UserRating.objects.create(
            user=self.user, bookid="2", bookrating="4"
        )
        self.userRating.save()
        self.client.login(username="test_user", password="foopassword")
        response = self.client.get(self.url)
        self.assertEqual(response.status_code, 200)
        self.client.logout()


class AddBooksTestCase(TestCase):
    """Saved For Later Books View Test Case"""

    def setUp(self):
        self.client = Client()
        self.user = User.objects.create_user(
            username="test_user", email="qwe@gmail.com"
        )
        self.user.set_password("foopassword")
        self.user.save()
        self.book = pd.read_csv(
            os.path.join(settings.STATICFILES_DIRS[0] + "/mainapp/dataset/books.csv")
        )
        self.bookid = self.book.iloc[0]["book_id"]

    def test_save_book_status(self):
        """Test the status code of save_book
        When a book is Saved
        """
        book_id = self.bookid
        self.client.login(username="test_user", password="foopassword")

        response = self.client.post(
            reverse("save_book"),
            data={"bookid": book_id},
            HTTP_X_REQUESTED_WITH="XMLHttpRequest",
        )
        self.assertEqual(response.status_code, 200)
        self.assertIn("true", response.content.decode("utf-8"))
        self.client.logout()

    def test_after_remove(self):
        """Test the status code of
        remove_saved_book When a book is removed
        """
        book_id = self.bookid
        self.client.login(username="test_user", password="foopassword")

        response = self.client.post(
            reverse("remove_saved_book"),
            data={"bookid": book_id},
            HTTP_X_REQUESTED_WITH="XMLHttpRequest",
        )
        self.assertEqual(response.status_code, 200)
        self.assertIn("true", response.content.decode("utf-8"))
        self.client.logout()

    def test_redirect_if_not_saved(self):
        """Test If The to_read Redirects
        Accordingly When No Book Is Saved
        """
        self.client.login(username="test_user", password="foopassword")
        response = self.client.get(reverse("to_read"))
        self.assertRedirects(response, reverse("index"))
        self.client.logout()

    def test_to_read_status_if_saved(self):
        """Test the status code of to_read
        When a book is Saved
        """
        self.client.login(username="test_user", password="foopassword")
        self.saveLater = SaveForLater.objects.create(user=self.user, bookid="2")
        self.saveLater.save()
        response = self.client.get(reverse("to_read"))
        self.assertEqual(response.status_code, 200)
        self.client.logout()


================================================
FILE: mainapp/urls.py
================================================
from django.urls import path
from mainapp import views, views_ajax

urlpatterns = [
    path("", views.index, name="index"),
    path("genre_books/<genre>", views.genre_books, name="genre_books"),
    path("explore_books/", views.explore_books, name="explore_books"),
    path(
        "book_recommendations/", views.book_recommendations, name="book_recommendations"
    ),
    path("library/rated_books", views.read_books, name="read_books"),
    path("library/saved_books", views.SaveList, name="to_read"),
]

# Ajax Views
urlpatterns += [
    path("search_ajax/", views_ajax.search, name="search_ajax"),
    path("book_summary_ajax/", views_ajax.book_summary, name="summary_ajax"),
    path("book_details_ajax/", views_ajax.get_book_details, name="book_details"),
    path("user_rate_book/", views_ajax.user_rate_book, name="user_rate_book"),
    path("save_book/", views_ajax.save_book, name="save_book"),
    path("remove_saved_book/", views_ajax.remove_saved_book, name="remove_saved_book"),
]


================================================
FILE: mainapp/views.py
================================================
from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required
from django.views.decorators.csrf import ensure_csrf_cookie
from mainapp.helpers import (
    genre_wise,
    tfidf_recommendations,
    get_book_dict,
    get_rated_bookids,
    combine_ids,
    embedding_recommendations,
    get_top_n,
    popular_among_users,
)
from mainapp.models import UserRating, SaveForLater
from django.contrib import messages
from django.core.paginator import Paginator


import random
import operator


@ensure_csrf_cookie
def index(request):
    """
    View to render Homepage
    """
    books = popular_among_users()
    return render(request, "mainapp/index.html", {"books": books})


@ensure_csrf_cookie
def genre_books(request, genre):
    """
    View to render Books in a particular genre
    """
    genre_topbooks = genre_wise(genre)
    genre_topbooks = genre_topbooks.to_dict("records")
    context = {
        "genre": genre.capitalize(),
        "genre_topbook": genre_topbooks,
    }
    return render(request, "mainapp/genre.html", context)


@ensure_csrf_cookie
def explore_books(request):
    """
    View to Render Explore Page
    Renders Top N Books
    """
    N = 152
    sample = get_top_n().sample(N).to_dict("records")
    return render(request, "mainapp/explore.html", {"book": sample})


@login_required
@ensure_csrf_cookie
def book_recommendations(request):
    """
    View to render book recommendations

    Count Vectorizer Approach:
        1. Get Ratings of User
        2. Shuffle by Top Ratings(For Randomness each time)
        3. Recommend according to Top Rated Book
    """
    user_ratings = list(
        UserRating.objects.filter(user=request.user).order_by("-bookrating")
    )
    random.shuffle(user_ratings)
    best_user_ratings = sorted(
        user_ratings, key=operator.attrgetter("bookrating"), reverse=True
    )

    if len(best_user_ratings) < 4:
        messages.info(request, "Please rate atleast 5 books")
        return redirect("index")
    if best_user_ratings:
        # If one or more book is rated
        bookid = best_user_ratings[0].bookid
        already_rated_books = get_rated_bookids(user_ratings)
        # Get bookids based on TF-IDF weighing
        tfidf_bookids = set(tfidf_recommendations(bookid))

        # Shuffle again for randomness for second approach
        random.shuffle(user_ratings)
        best_user_ratings = sorted(
            user_ratings, key=operator.attrgetter("bookrating"), reverse=True
        )
        # Get Top 10 bookids based on embedding
        embedding_bookids = set(embedding_recommendations(best_user_ratings))

        best_bookids = combine_ids(
            tfidf_bookids, embedding_bookids, already_rated_books
        )
        all_books_dict = get_book_dict(best_bookids)
    else:
        return redirect("index")
    return render(request, "mainapp/recommendation.html", {"books": all_books_dict})


@login_required
@ensure_csrf_cookie
def read_books(request):
    """View To Render Library Page"""
    user_ratings = list(
        UserRating.objects.filter(user=request.user).order_by("-bookrating")
    )
    if len(user_ratings) == 0:
        messages.info(request, "Please rate some books")
        return redirect("index")
    if user_ratings:
        rated_books = set(get_rated_bookids(user_ratings))
        books = get_book_dict(rated_books)
        num = len(books)
        # Add pagination to the page showing 10 books
        paginator = Paginator(books, 10)
        page_number = request.GET.get("page")
        page_obj = paginator.get_page(page_number)
    else:
        return redirect("index")
    return render(request, "mainapp/read.html", {"page_obj": page_obj, "num": num})


def handler404(request, *args, **argv):
    response = render(request, "mainapp/error_handler.html")
    response.status_code = 404
    return response


def handler500(request, *args, **argv):
    response = render(request, "mainapp/error_handler.html")
    response.status_code = 500
    return response


def SaveList(request):
    """View to render Saved books page"""
    user_ratings = list(
        UserRating.objects.filter(user=request.user).order_by("-bookrating")
    )
    rated_books = set(get_rated_bookids(user_ratings))
    book = set(
        SaveForLater.objects.filter(user=request.user).values_list("bookid", flat=True)
    )
    book_id = list(book)
    for i in range(len(book_id)):
        if book_id[i] in rated_books:
            saved_book = SaveForLater.objects.filter(
                user=request.user, bookid=book_id[i]
            )
            saved_book.delete()
            book_id.remove(book_id[i])
    if len(book_id) == 0:
        messages.info(request, "Please Add Some Books")
        return redirect("index")
    books = get_book_dict(book_id)
    total_books = len(books)
    paginator = Paginator(books, 10)
    page_number = request.GET.get("page")
    page_obj = paginator.get_page(page_number)
    return render(
        request, "mainapp/saved_book.html", {"page_obj": page_obj, "num": total_books}
    )


================================================
FILE: mainapp/views_ajax.py
================================================
from django.http import JsonResponse
from django.contrib.auth.decorators import login_required
from mainapp.helpers import is_bookid_invalid, is_rating_invalid, get_rated_bookids
import BookRecSystem.settings as settings
from mainapp.models import UserRating, SaveForLater
from bs4 import BeautifulSoup
import pandas as pd
import os
import json
import requests

"""
    Production File Path :  staticfiles_storage.url(file)
    Developement File Path : settings.STATICFILES_DIRS[0] + 'app/.../file'
"""
book_path = os.path.join(settings.STATICFILES_DIRS[0] + "/mainapp/dataset/books.csv")
user_ratings_path = os.path.join(
    settings.STATICFILES_DIRS[0] + "/mainapp/csv/userratings.csv"
)


def is_ajax(request):
    return request.META.get("HTTP_X_REQUESTED_WITH") == "XMLHttpRequest"


def search(request):
    """
    AJAX request for search bar functionality
    """
    if request.method == "POST" and is_ajax(request=request):
        query = request.POST.get("bookName", None)
        if not query:
            return JsonResponse({"success": False}, status=200)
        df_book = pd.read_csv(book_path)
        top5_result = df_book[
            df_book["original_title"].str.contains(query, regex=False, case=False)
        ][:5]
        top5_result = json.dumps(top5_result.to_dict("records"))

        return JsonResponse({"success": True, "top5_result": top5_result}, status=200)


def book_summary(request):
    """
    AJAX request for book summary
    """
    if request.method == "POST" and is_ajax(request=request):
        bookid = request.POST.get("bookid", None)
        if is_bookid_invalid(bookid):
            return JsonResponse({"success": False}, status=200)
        URL = "https://www.goodreads.com/book/show/" + bookid
        page = requests.get(URL)
        soup = BeautifulSoup(page.content, "html.parser")
        div_container = soup.find(id="description")
        full_book_summary = ""
        if not div_container:
            return JsonResponse({"success": False}, status=200)
        for spantag in div_container.find_all("span"):
            try:
                # When text is too long, consider till last complete sentence
                full_book_summary += spantag.text[: spantag.text.rindex(".")] + ". "
            except ValueError:
                full_book_summary += spantag.text + " "
            break
        part_summary = " ".join(full_book_summary.split()[:65]) + " . . ."
        return JsonResponse({"success": True, "booksummary": part_summary}, status=200)


def get_book_details(request):
    """
    AJAX request for book details
    """
    if request.method == "POST" and is_ajax(request=request):
        bookid = request.POST.get("bookid", None)
        if is_bookid_invalid(bookid):
            return JsonResponse({"success": False}, status=200)

        df_book = pd.read_csv(book_path)
        book_details = df_book[df_book["book_id"] == int(bookid)]
        if not len(book_details):
            return JsonResponse({"success": False}, status=200)

        book_details = json.dumps(book_details.to_dict("records"))
        return JsonResponse({"success": True, "book_details": book_details}, status=200)


@login_required
def user_rate_book(request):
    """
    AJAX request when user rates book
    """
    if request.method == "POST" and is_ajax(request=request):
        bookid = request.POST.get("bookid", None)
        bookrating = request.POST.get("bookrating", None)
        if is_bookid_invalid(bookid) or is_rating_invalid(bookrating):
            return JsonResponse({"success": False}, status=200)

        # Using Inbuilt Model
        query = UserRating.objects.filter(user=request.user).filter(bookid=bookid)
        if not query:
            # Create Rating
            UserRating.objects.create(
                user=request.user, bookid=bookid, bookrating=bookrating
            )
        else:
            # Update Rating
            rating_object = query[0]
            rating_object.bookrating = bookrating
            rating_object.save()
        return JsonResponse({"success": True}, status=200)


def save_book(request):
    """AJAX request when user saves book"""
    if request.method == "POST" and is_ajax(request=request):
        bookid = request.POST.get("bookid", None)
        user_ratings = list(UserRating.objects.filter(user=request.user))
        rated_books = set(get_rated_bookids(user_ratings))
        if is_bookid_invalid(bookid) or bookid in rated_books:
            return JsonResponse({"success": False}, status=200)

        SaveForLater.objects.create(user=request.user, bookid=bookid)
        return JsonResponse({"success": True}, status=200)


def remove_saved_book(request):
    """AJAX request when user removes book"""
    if request.method == "POST" and is_ajax(request=request):
        bookid = request.POST.get("bookid", None)
        if is_bookid_invalid(bookid):
            return JsonResponse({"success": False}, status=200)

        saved_book = SaveForLater.objects.filter(user=request.user, bookid=bookid)
        saved_book.delete()
        return JsonResponse({"success": True}, status=200)


================================================
FILE: manage.py
================================================
#!/usr/bin/env python
"""Django's command-line utility for administrative tasks."""
import os
import sys


def main():
    """Run administrative tasks."""
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "BookRecSystem.settings")
    try:
        from django.core.management import execute_from_command_line
    except ImportError as exc:
        raise ImportError(
            "Couldn't import Django. Are you sure it's installed and "
            "available on your PYTHONPATH environment variable? Did you "
            "forget to activate a virtual environment?"
        ) from exc
    execute_from_command_line(sys.argv)


if __name__ == "__main__":
    main()


================================================
FILE: pyproject.toml
================================================
[tool.poetry]
name = "kitabe"
version = "0.1.0"
description = "Book Recommendation System"
authors = ["maneprajakta <prajakta916mane1@gmail.com>", "Praful932 <praful.mohanan@gmail.com>"]
license = "MIT"

[tool.poetry.dependencies]
python = "^3.8"
Django = "^4.1.2"
django-allauth = "^0.51.0"
django-storages = "^1.13.1"
pandas = "^1.5.0"
numpy = "^1.23.3"
bs4 = "^0.0.1"
pre-commit = "^2.20.0"
pylint = "^2.15.4"
gunicorn = "^20.1.0"
whitenoise = "^6.2.0"
psycopg2-binary = "*"

[tool.poetry.dev-dependencies]

[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"


================================================
FILE: requirements.txt
================================================
asgiref==3.5.2 ; python_version >= "3.8" and python_version < "4.0"
astroid==2.12.11 ; python_version >= "3.8" and python_version < "4.0"
backports-zoneinfo==0.2.1 ; python_version >= "3.8" and python_version < "3.9"
beautifulsoup4==4.11.1 ; python_version >= "3.8" and python_version < "4.0"
bs4==0.0.1 ; python_version >= "3.8" and python_version < "4.0"
certifi==2022.9.24 ; python_version >= "3.8" and python_version < "4"
cffi==1.15.1 ; python_version >= "3.8" and python_version < "4.0"
cfgv==3.3.1 ; python_version >= "3.8" and python_version < "4.0"
charset-normalizer==2.1.1 ; python_version >= "3.8" and python_version < "4"
colorama==0.4.5 ; python_version >= "3.8" and python_version < "4.0" and sys_platform == "win32"
cryptography==38.0.1 ; python_version >= "3.8" and python_version < "4.0"
defusedxml==0.7.1 ; python_version >= "3.8" and python_version < "4.0"
dill==0.3.5.1 ; python_version >= "3.8" and python_version < "4.0"
distlib==0.3.6 ; python_version >= "3.8" and python_version < "4.0"
django-allauth==0.51.0 ; python_version >= "3.8" and python_version < "4.0"
django-storages==1.13.1 ; python_version >= "3.8" and python_version < "4.0"
django==4.1.2 ; python_version >= "3.8" and python_version < "4.0"
filelock==3.8.0 ; python_version >= "3.8" and python_version < "4.0"
gunicorn==20.1.0 ; python_version >= "3.8" and python_version < "4.0"
identify==2.5.6 ; python_version >= "3.8" and python_version < "4.0"
idna==3.4 ; python_version >= "3.8" and python_version < "4"
isort==5.10.1 ; python_version >= "3.8" and python_version < "4.0"
lazy-object-proxy==1.7.1 ; python_version >= "3.8" and python_version < "4.0"
mccabe==0.7.0 ; python_version >= "3.8" and python_version < "4.0"
nodeenv==1.7.0 ; python_version >= "3.8" and python_version < "4.0"
numpy==1.23.3 ; python_version < "4.0" and python_version >= "3.8"
oauthlib==3.2.1 ; python_version >= "3.8" and python_version < "4.0"
pandas==1.5.0 ; python_version >= "3.8" and python_version < "4.0"
platformdirs==2.5.2 ; python_version >= "3.8" and python_version < "4.0"
pre-commit==2.20.0 ; python_version >= "3.8" and python_version < "4.0"
psycopg2-binary==2.9.5 ; python_version >= "3.8" and python_version < "4.0"
pycparser==2.21 ; python_version >= "3.8" and python_version < "4.0"
pyjwt[crypto]==2.5.0 ; python_version >= "3.8" and python_version < "4.0"
pylint==2.15.4 ; python_version >= "3.8" and python_version < "4.0"
python-dateutil==2.8.2 ; python_version >= "3.8" and python_version < "4.0"
python3-openid==3.2.0 ; python_version >= "3.8" and python_version < "4.0"
pytz==2022.4 ; python_version >= "3.8" and python_version < "4.0"
pyyaml==6.0 ; python_version >= "3.8" and python_version < "4.0"
requests-oauthlib==1.3.1 ; python_version >= "3.8" and python_version < "4.0"
requests==2.28.1 ; python_version >= "3.8" and python_version < "4"
setuptools==65.6.3 ; python_version >= "3.8" and python_version < "4.0"
six==1.16.0 ; python_version >= "3.8" and python_version < "4.0"
soupsieve==2.3.2.post1 ; python_version >= "3.8" and python_version < "4.0"
sqlparse==0.4.3 ; python_version >= "3.8" and python_version < "4.0"
toml==0.10.2 ; python_version >= "3.8" and python_version < "4.0"
tomli==2.0.1 ; python_version >= "3.8" and python_version < "3.11"
tomlkit==0.11.5 ; python_version >= "3.8" and python_version < "4.0"
types-cryptography==3.3.23 ; python_version >= "3.8" and python_version < "4.0"
typing-extensions==4.4.0 ; python_version >= "3.8" and python_version < "3.10"
tzdata==2022.4 ; python_version >= "3.8" and python_version < "4.0" and sys_platform == "win32"
urllib3==1.26.12 ; python_version >= "3.8" and python_version < "4"
virtualenv==20.16.5 ; python_version >= "3.8" and python_version < "4.0"
whitenoise==6.2.0 ; python_version >= "3.8" and python_version < "4.0"
wrapt==1.14.1 ; python_version >= "3.8" and python_version < "4.0"


================================================
FILE: setup.cfg
================================================
[flake8]
exclude = .git,*migrations*,__pycache__,.vscode,bookenv
max-line-length = 1196
[coverage:run]
omit =
    BookRecSystem/*
    *env/*
    mainapp/tests.py
    mainapp/urls.py
    manage.py

================================================
FILE: static/mainapp/css/explore.css
================================================
.hide {
    display: none;
}

.centre {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    padding: 1rem;
}

.data:hover+.hide {
    display: block;
    color: red;
}

.hide:hover {
    display: block;
    color: red;
}

.cover-img-size {
    width: 200px;
    height: 300px;
    margin-right: 22px;
    margin-top: 2px;
    margin-bottom: 4px;
}

.content {
    width: 200px;
}

.title {
    font-family: "Sora", sans-serif;
    color: #d7722c;
}

.author {
    font-family: "Rockwell", serif;
    font-weight: bold;
}

#demo,
#demo2,
#demo3 {
    padding-left: 6.5%;
    padding-bottom: 1%;
}

.rateYo {
    margin-left: auto;
    margin-right: auto;
    display: none;
}

.small-screen {
    display: none;
}

.card-deck {
    padding-left: 5%;
    padding-right: 5%;
    padding-bottom: 2%;
}

.card {
    transition: 0.5s;
    cursor: pointer;
    border-radius: 3px;
    box-shadow: -2px 6px 19px 0px #7f818e;
}

.card-img {
    flex-shrink: 0;
    bottom: -35px;
    left: 35px;
    border-radius: 3px;
    box-shadow: -2px 6px 19px 0px #7f818e;
    transition: 0.3s ease;
    width: 85%;
    height: 60%;
    margin: 0 auto;
}

.card-img:hover {
    transform: scale(1.07);
}

.card-horizontal {
    display: flex;
    flex: 1 1 auto;
}

.card-body-wrap {
    display: flex;
}

.card-title {
    font-family: "Sora", sans-serif;
    font-size: large;
    color: #d7722c;
}

.card::before,
.card::after {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    transform: scale3d(0, 0, 1);
    transition: transform 0.3s ease-out 0s;
    content: "";
    pointer-events: none;
}

.card::before {
    transform-origin: left top;
}

.card::after {
    transform-origin: right bottom;
}

.card:hover::before,
.card:hover::after,
.card:focus::before,
.card:focus::after {
    transform: scale3d(1, 1, 1);
}

.more-details {
    text-align: center;
    background-color: #3d348b;
    color: #fff;
    font-weight: 600;
    font-size: 11px;
    border-radius: 20px;
    position: absolute;
    bottom: 10px;
    right: 2%;
}

.more-details:hover {
    color: #3d348b;
    background: white;
    border: 2px solid #3d348b;
    text-shadow: 1px 1px 3px #727ff0;
}

.rating-block {
    display: inline-block;
    text-align: center;
    background-color: #31c2cf;
    font-weight: 600;
    font-size: 11px;
    border-radius: 20px;
    position: absolute;
    bottom: 10px;
    left: 4%;
    padding: 8px;
}

.rating-block.btn,
.btn.more-details {
    padding: 8px;
}

.rating-block:hover {
    text-shadow: 0px 0px 6px rgba(255, 255, 255, 1);
    transition: all 0.4s ease 0s;
}

.card-text {
    font-family: "Rockwell", serif;
    color: black;
    font-weight: bold;
    font-size: 15px;
    padding-bottom: 1px;
    overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    /* number of lines to show */
    -webkit-box-orient: vertical;
}

@media (max-width: 420px) {
    .cover-img-size {
        margin-left: 53px;
    }
    .content {
        margin-left: 53px;
    }
    .hide {
        display: block;
    }
    .rating-block {
        margin-left: 5%;
    }
    .more-details {
        right: 15%;
    }
    .large-screen {
        display: none;
    }
    .small-screen {
        display: inline;
    }
    .card,
    .card-deck {
        margin: auto;
    }
    .cover-img-size {
        margin: auto;
        margin-top: 8%;
    }
    .row {
        margin-bottom: 5%;
    }
}

@media (max-width: 390px) {
    .card,
    .card-deck {
        margin-left: -1.5%;
    }
}

================================================
FILE: static/mainapp/css/genre.css
================================================
.genre-head,
.topbook-head {
    font-family: "Lobster", cursive;
    font-size: 300%;
    background-color: #d7722c;
    margin-top: 0px;
    color: white;
}

.card-horizontal {
    display: flex;
    flex: 1 1 auto;
}

.card-img {
    flex-shrink: 0;
    bottom: -35px;
    left: 35px;
    border-radius: 3px;
    box-shadow: -2px 6px 19px 0px #7f818e;
    transition: 0.3s ease;
    width: 85%;
    height: 60%;
    margin: 0 auto;
}

.card-img:hover {
    transform: scale(1.07);
}

.card-body-wrap {
    display: flex;
}

.card {
    transition: 0.5s;
    cursor: pointer;
    border-radius: 3px;
    box-shadow: -2px 6px 19px 0px #7f818e;
}

.card-title {
    font-family: "Sora", sans-serif;
    font-size: large;
    color: #d7722c;
}

.card-text {
    font-family: "Rockwell", serif;
    color: black;
    font-weight: bold;
    font-size: 15px;
    padding-bottom: 1px;
}

.card::before,
.card::after {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    transform: scale3d(0, 0, 1);
    transition: transform 0.3s ease-out 0s;
    content: "";
    pointer-events: none;
}

.card::before {
    transform-origin: left top;
}

.card::after {
    transform-origin: right bottom;
}

.card:hover::before,
.card:hover::after,
.card:focus::before,
.card:focus::after {
    transform: scale3d(1, 1, 1);
}

.more-details {
    text-align: center;
    background-color: #3d348b;
    color: #fff;
    font-weight: 600;
    font-size: 11px;
    border-radius: 20px;
    position: absolute;
    bottom: 10px;
    right: 10%;
}

.more-details:hover {
    color: #3d348b;
    background: white;
    border: 2px solid #3d348b;
    text-shadow: 1px 1px 3px #727ff0;
}

.rating-block {
    display: inline-block;
    text-align: center;
    background-color: #31c2cf;
    font-weight: 600;
    font-size: 11px;
    border-radius: 20px;
    position: absolute;
    padding: 8px;
    bottom: 10px;
    left: 10%;
}

.rating-block:hover {
    text-shadow: 0px 0px 6px rgba(255, 255, 255, 1);
    transition: all 0.4s ease 0s;
}

.rateYo {
    display: none;
}

.card-deck {
    padding-left: 5%;
    padding-right: 5%;
    padding-bottom: 2%;
}

.card-text {
    overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    /* number of lines to show */
    -webkit-box-orient: vertical;
}

@media screen and (max-width: 600px) {
    .card-text {
        margin-bottom: 10px !important;
    }
    .rating-block {
        left: 5%;
        font-size: 12px;
    }
    .more-details {
        right: 10px;
        font-size: 12px;
    }
    .card-deck {
        padding-right: 0;
        padding-left: 8%;
    }
}

================================================
FILE: static/mainapp/css/index.css
================================================
/*---------------------------------------- preloader ----------------------------------*/

.preloader-container {
    position: fixed;
    top: 0;
    left: 0;
    height: 100vh;
    width: 100vw;
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 0;
    background-color: #FFDAB9;
    z-index: 99;
}

.spinner {
    width: 270px;
    height: 45px;
    text-align: center;
}

.rect1,
.rect2,
.rect3,
.rect4,
.rect5 {
    height: 45px;
    width: 12px;
    display: inline-block;
    -webkit-animation: updown 1.2s infinite;
    animation: updown 1.2s ease infinite;
}

.stand {
    width: 90px;
    height: 9px;
    background: #000;
    display: block;
    border-radius: 15px;
    margin: auto;
}

.spinner .rect2 {
    -webkit-animation-delay: -1.1s;
    animation-delay: -1.1s;
}

.spinner .rect3 {
    -webkit-animation-delay: -1.0s;
    animation-delay: -1.0s;
}

.spinner .rect4 {
    -webkit-animation-delay: -0.9s;
    animation-delay: -0.9s;
}

.spinner .rect5 {
    -webkit-animation-delay: -0.8s;
    animation-delay: -0.8s;
}

@keyframes updown {
    0% {
        transform: translateY(0%);
    }
    40% {
        transform: translateY(-100%);
    }
    100% {
        transform: translateY(0%);
    }
}

@-webkit-keyframes updown {
    0% {
        transform: translateY(0%);
    }
    40% {
        transform: translateY(100%);
    }
    100% {
        transform: translateY(0%);
    }
}


/* ---------------------- banner ------------------------------------- */

@media screen and (min-width: 250px) {
    .banner .carousel-item {
        height: 180px;
    }
    .banner .banner-img {
        height: 82%;
        object-fit: cover;
    }
}

@media screen and (min-width: 620px) {
    .banner .carousel-item {
        height: 240px;
    }
    .banner .banner-img {
        height: 100%;
        object-fit: cover;
    }
}

@media screen and (min-width:1000px) {
    .banner .carousel-item,
    .banner .banner-img {
        height: auto;
    }
}


/* ---------------------- carousel -------------------------------------*/

.carousel img {
    width: 100%;
    height: auto;
}

#demo img {
    height: 160px;
}

.genre-head,
.topbook-head {
    font-family: "Lobster", cursive;
}

.heading-genre {
    padding: 30px 30px;
    font-size: 47px;
}

.genre-container,
.top-books {
    background-color: #153450;
    box-shadow: 10px 10px 15px rgba(0, 0, 0, 0.5);
}

.col-lg-3:hover {
    transform: scale(1.07);
    transition: all 0.5s ease;
    border-radius: 10px;
    box-shadow: 0 10px 20px rgba(0, 0, 0, .12), 0 4px 8px rgba(0, 0, 0, .06);
}

.top-books-carousel {
    align-items: center;
    margin-left: -13%;
    margin-right: -13%;
}

.navbar-nav .nav-link {
    color: black;
}


/* Genre wise */

.carousel-indicators {
    bottom: -28px;
}

ol.carousel-indicators li {
    width: 7px;
    height: 7px;
    border: none;
    border-radius: 10px;
    background-color: #dc3545;
    opacity: 0.6;
    margin: 0 5px;
}

ol.carousel-indicators li.active {
    height: 7px;
    width: 20px;
}

.inner-row {
    place-content: center;
    height: auto;
    min-width: auto;
}

.genre-img {
    width: 80%;
    height: auto;
    margin: 1rem auto;
}

#carousel-2 .carousel-control-prev,
#carousel-2 .carousel-control-next {
    width: 50px;
    height: 50px;
    top: 50%;
    border-radius: 50%;
    background-color: #dc3545;
}

@media screen and (min-width: 992px) {
    .carousel-indicators {
        bottom: -8px;
    }
    .inner-row {
        height: 17rem;
        min-width: 57rem;
    }
    #carousel-2 .carousel-control-prev,
    #carousel-2 .carousel-control-next {
        top: 6.5rem;
        transform: translateY(0px);
    }
}


/*---------------------------------------- book card ----------------------------------*/

.card {
    transition: 0.5s;
    cursor: pointer;
    border-radius: 3px;
    height: 300px;
    display: inline-flex;
}

.card-img {
    flex-shrink: 0;
    bottom: -35px;
    left: 35px;
    border-radius: 3px;
    box-shadow: -2px 6px 19px 0px #7f818e;
    transition: 0.3s ease;
    height: 200px;
    width: 100px;
}

.card-title {
    font-family: "Sora", sans-serif;
    font-size: x-large;
    color: #d7722c;
}

.card-img:hover {
    transform: scale(1.07);
}

.card-body-wrap {
    display: flex;
}

.card-text {
    font-family: "Rockwell", serif;
    color: black;
    font-weight: bold;
    font-size: large;
}

.card:hover {
    transform: scale(1.02);
    box-shadow: 10px 10px 15px rgba(0, 0, 0, 0.1);
}

.card::before,
.card::after {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    transform: scale3d(0, 0, 1);
    transition: transform 0.3s ease-out 0s;
    content: "";
    pointer-events: none;
}

.card::before {
    transform-origin: left top;
}

.card::after {
    transform-origin: right bottom;
}

.card:hover::before,
.card:hover::after,
.card:focus::before,
.card:focus::after {
    transform: scale3d(1, 1, 1);
}

.more-details {
    text-align: center;
    background-color: #3d348b;
    color: #fff;
    font-weight: 600;
    font-size: 14px;
    border-radius: 20px;
    position: absolute;
    bottom: 10px;
    right: 10px;
}

.more-details:hover {
    color: #3d348b;
    background: white;
    border: 2px solid#3d348b;
    text-shadow: 1px 1px 3px #727ff0;
}

.rating-block {
    display: inline-block;
    text-align: center;
    background-color: #31c2cf;
    font-weight: 600;
    font-size: 14px;
    border-radius: 20px;
    position: absolute;
    bottom: 10px;
    right: 35%;
    padding: 6px 12px;
}

.rating-block:hover {
    text-shadow: 0px 0px 6px rgba(255, 255, 255, 1);
    transition: all 0.4s ease 0s;
}

.rateYo {
    display: none;
}

@media only screen and (min-width: 996px) {
    .col-md-3point9 {
        max-width: 33%;
    }
    #demo .card-title {
        margin-top: 0rem;
    }
}


/* media query*/

@media screen and (max-width: 575px) {
    .col-lg-3:hover {
        transform: scale(1.03);
    }
    #demo .card-title {
        margin-top: 2rem;
    }
}

@media screen and (max-width: 600px) {
    .genre-head {
        font-size: 29px;
    }
    .heading-genre {
        padding: 9px 9px;
        font-size: 29px;
    }
    .genre-container:hover {
        transform: none;
    }
    /* card image */
    .card-img {
        height: 240px;
        width: 120px !important;
    }
    .card-body {
        margin-top: -220px;
        margin-left: 130px;
    }
    .card-title {
        font-size: 18px;
    }
    .rating-block {
        padding-top: 1px;
        right: 50%;
        padding: 6px 12px;
    }
    .more-details {
        margin-top: 2px;
        right: 30px;
    }
    .top-books-carousel {
        align-items: center;
        margin-left: -9%;
        margin-right: -9%;
    }
}

@media screen and (min-width: 600px) {
    #demo .card-title {
        margin-top: 0rem;
        margin-bottom: 0rem;
    }
}

================================================
FILE: static/mainapp/css/layout.css
================================================
html,
body {
    background-color: #ffdab9;
    height: 100%;
    max-width: 100%;
    overflow-x: hidden;
}

#navbarNav {
    float: right;
}


/* Custom Scrollbar */

body::-webkit-scrollbar {
    width: 13px;
    background-color: #fff;
}

body::-webkit-scrollbar-thumb {
    border-radius: 10px;
    background-color: #FE7D6A;
}

body::-webkit-scrollbar-thumb:hover {
    background-color: #f86751;
}


/* For Firefox */

body {
    overflow-y: scroll;
    scrollbar-color: #ec9108 rgb(255, 255, 255);
    scrollbar-width: thin;
}


/* nav bar css */

.nav-item {
    display: flex !important;
    flex-direction: column !important;
    align-items: center !important;
    font-family: 'Lato', sans-serif;
}

.navbrandimg {
    width: 94px;
}

.navbar-toggler {
    border-color: black;
    background-color: white;
}

.img-book {
    height: 200px !important;
}

.model-rate {
    position: inherit !important;
    margin-bottom: 12px !important;
    margin-top: 12px !important;
}


/*-------------------------Drop down library -----------------------*/

.dropdown:hover .dropdown-menu {
    display: block;
}

.dropdown-item:hover {
    text-shadow: 2px 2px 5px #d7722c;
    background-color: peachpuff;
}


/* -------------------------search bar-----------------------  */

.searchbar {
    font-family: "Kumbh Sans", sans-serif;
}

#bookrating {
    padding-top: 2%;
}

#bookName {
    border-radius: 50px;
}

#searchdropdown {
    margin-left: 50%;
    width: 260px;
}

#searchdropdown #bookName {
    width: 100%;
    font-size: 16px;
    padding: 12px 16px;
    border: 1px solid #ddd;
}

#searchdropdown .dropdown-content {
    display: block;
    position: absolute;
    background-color: #f1f1f1;
    -webkit-box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
    box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
    z-index: 1;
    border-radius: 10px;
    max-width: 260.33px;
}

#searchdropdown .dropdown-content a {
    color: black;
    padding: 12px 16px;
    text-decoration: none;
    display: block;
}

#searchdropdown .dropdown-content a:hover {
    background-color: #ddd;
    border-radius: 10px;
}

.modal {
    line-height: 1.5;
}

.modal .modal-header {
    display: -webkit-box;
    display: -ms-flexbox;
    display: flex;
    padding: 1rem 1rem;
    background-color: #ffc107;
}

.modal .modal-title {
    padding: 0.3rem;
    margin: 0;
    font-size: 1.15rem;
    color: #fff;
}

.modal .close {
    opacity: 1;
    padding: 1rem 1rem;
    margin: -1rem -1rem -1rem auto;
    cursor: pointer;
    background-color: transparent;
    border: 0;
    font-size: 1.5rem;
    font-weight: 700;
    text-shadow: 0 1px 0 #fff;
}

.modal-footer {
    color: white;
}

#save-book-button {
    display: inline-block;
    text-align: center;
    background-color: #ffc107;
    font-weight: 600;
    font-size: 11px;
    border-radius: 20px;
    padding: 8px;
    margin-left: 10px;
    margin-bottom: 10px;
    margin-top: 10px;
}


/*  -------------------------------------------------------------------------------fotter css -------------------------------------------------*/


/*FOOTER*/

.footer-content {
    padding: 15px;
}

strong {
    color: red;
}

footer {
    background-color: black;
    color: white;
    margin-top: 10%;
    text-align: center;
}

footer a {
    color: #fff;
    font-size: 14px;
    transition-duration: 0.2s;
    padding: 3px;
}

footer a:hover {
    color: #fa944b;
    text-decoration: none;
}

.copy {
    font-size: 12px;
}


/* media query */

@media screen and (max-width: 768px) and (min-width: 600px) {
    #searchdropdown #bookName {
        position: relative;
        top: 0px;
        right: 75px;
        margin: 10px;
    }
    .navbar-light .navbar-toggler {
        position: absolute;
        right: 1rem;
        top: 1.4rem;
    }
    .navbrandimg {
        position: absolute;
        top: 15px;
    }
    .nav-icon-s {
        display: none;
    }
    li.nav-item {
        margin-top: -25px;
        margin-bottom: 15px;
    }
}

@media screen and (max-width: 600px) {
    #searchdropdown {
        margin-left: 8%;
        padding-left: 0%;
        width: 200px;
    }
    .navbar-brand {
        width: 8px;
        margin-right: 28px;
        padding-left: 0;
    }
    .navbrandimg {
        width: 65px;
        padding-right: 5px;
    }
    .img-book {
        height: 140px !important;
    }
    .nav-icon-s {
        display: none;
    }
    .nav-link {
        margin-top: -2px;
        margin-top: -25px;
    }
    .nav-link:hover {
        text-decoration: underline;
        font-weight: 100;
    }
    body::-webkit-scrollbar {
        width: 5px;
    }
}

body {
    scroll-behavior: smooth;
}

#topBtn {
    display: none;
    position: fixed;
    bottom: 1rem;
    right: 1.5rem;
    z-index: 100;
    border: 0.1rem solid white;
    outline: none;
    background-color: black;
    color: white;
    cursor: pointer;
    padding: 0.2rem 0.8rem 0.2rem 0.8rem;
    border-radius: 30rem;
    font-size: 1.2rem;
}

@media screen and (max-width: 760px) {
    #topBtn {
        right: 1rem;
    }
}

@media screen and (min-width:800px) {
    #topBtn:hover {
        background-color: #ff6666;
    }
}

================================================
FILE: static/mainapp/css/login.css
================================================
.account-block {
    margin: auto;
    height: 80%;
    width: 70%;
    background-color: white;
}

.signin-block {
    text-align: center;
}

.img-block {
    color: white;
    background-size: cover;
    background-position: center;
}

.btn-bot {
    font-family: "Fredoka One", cursive;
    position: absolute;
    margin-left: -45px;
    left: 50%;
    padding: 5px 10px 5px 10px;
    border: 2px solid white;
    border-radius: 10px;
    bottom: 25px;
    text-decoration: none !important;
    color: white;
}

.btn-bot:hover {
    color: black;
    border: 2px solid black;
    background-color: rgba(255, 255, 255, 0.891);
}

.welcome {
    font-family: "Pacifico", cursive;
    position: relative;
    top: 12%;
    left: 28%;
    border-radius: 50px;
    font-size: 2.2rem;
    background-color: #ffdab9;
    width: 44%;
}

label {
    font-family: "Kalam", cursive;
    font-size: 1.2em;
}

.form-group {
    padding: 6% 8% 8% 8%;
    position: relative;
    display: inline-block;
    top: 80px;
    color: black;
}

#id_login,
#id_password {
    border-top: none;
    border-left: none;
    border-right: none;
    color: #000;
}

.loginbutton {
    font-family: "Fredoka One", cursive;
    padding: 8px 10px 5px 10px;
    font-size: 1rem;
    margin-bottom: 1.6rem;
    margin-top: 1rem;
    border: 2px solid white;
    box-shadow: 0 0 6px 2px rgba(0, 0, 0, 0.5);
    border: 3px solid #fff;
    color: #fff;
    background: rgba(1, 1, 1);
    border-radius: 15px;
    outline: none;
}

.loginbutton:hover {
    background-color: #ffdab9;
    color: black;
    border: 3px solid black;
}

fa-google {
    padding-right: 5px;
}

.googlebutton {
    position: relative;
    background-color: #f25f5c;
    font-family: "Fredoka One", cursive;
    color: white;
    padding: 7px 5px;
    border: 2px solid white;
    border-radius: 15px;
    text-decoration: none !important;
    box-shadow: 0 0 6px 2px rgba(0, 0, 0, 0.5);
    border: 3px solid #fff;
    bottom: -1%;
    left: 3px;
}

.forgotpassword {
    font-family: 'Raleway', sans-serif;
    font-size: 15px;
    position: relative;
    left: 30px;
    top: 10px;
}

.googlebutton:hover {
    color: #f25f5c;
    background-color: white;
    border: 3px solid #f25f5c;
}

strong {
    color: red;
}

@media only screen and (max-width: 1200px) {
    .img-block {
        display: none;
    }
    .googlebutton {
        bottom: 2%;
    }
}

@media only screen and (max-width: 900px) {
    .loginbutton {
        font-family: "Fredoka One", cursive;
        padding: 8px 10px 5px 10px;
        font-size: 1rem;
        margin-bottom: 2rem;
        margin-top: 1rem;
    }
    .form-group {
        padding: 5% 5% 13% 5%;
        margin-top: -1rem;
    }
    .account-block {
        margin: auto;
        height: 70%;
        background-color: white;
    }
    .welcome {
        font-size: 1.5rem;
        width: 40%;
        left: 30%;
    }
    .googlebutton {
        bottom: 5%;
    }
}

@media only screen and (max-width: 600px) {
    .loginbutton {
        font-family: "Fredoka One", cursive;
        padding: 8px 10px 5px 10px;
        font-size: 1rem;
        margin-bottom: 5rem;
        margin-top: 1rem;
        margin-left: -1rem;
    }
    .welcome {
        font-size: 1.75rem;
        margin-top: -2rem;
    }
    .form-group {
        padding: 7% 5% 5% 5%;
    }
    .forgotpassword {
        font-size: 16px;
        position: relative;
        left: 30px;
        top: 10px;
    }
    .welcome {
        font-size: 1.5rem;
        width: 60%;
        left: 20%;
    }
}

::placeholder {
    color: #000;
    font-weight: normal;
}

================================================
FILE: static/mainapp/css/password_reset.css
================================================
.heading {
  font-family: "Lobster", cursive;
  font-size: xx-large;
}

.resetButton {
  font-family: "Fredoka One", cursive;
  padding: 5px 10px 5px 10px;
  background-color: #09bc8a;
  color: white;
  border-radius: 25px;
}

#id_email {
  border-top: none;
  border-left: none;
  border-right: none;
  text-align: center;
  height: 35px;
}

label {
  font-family: "Kalam", cursive;
  font-size: 35px;
}

.content {
  text-align: center;
  font-family: "Sora", sans-serif;
  font-size: 20px;
}

.form-content {
  text-align: center;
}

.head2 {
  padding-top: 8%;
}

.head3 {
  padding-top: 5%;
  padding-bottom: 3%;
}

.reset {
  padding-top: 3%;
  padding-bottom: 19%;
}

.pass-form {
  padding-top: 5%;
  padding-bottom: 13.5%;
}

@media screen and (max-width: 600px) {
  .head3 {
    padding-bottom: 32%;
  }
  .reset {
    padding-top: 15%;
    padding-bottom: 80%;
  }
  .done {
    padding-bottom: 110% !important;
  }
  .pass-form {
    padding-bottom: 57%;
  }
}


================================================
FILE: static/mainapp/css/read.css
================================================
.card-deck {
    padding-left: 3.5%;
}

.genre-head,
.topbook-head {
    font-family: "Lobster", cursive;
    font-size: 300%;
    background-color: #d7722c;
    margin-top: 0px;
    color: white;
}

.card-img {
    flex-shrink: 0;
    bottom: -35px;
    left: 35px;
    border-radius: 3px;
    box-shadow: -2px 6px 19px 0px #7f818e;
    transition: 0.3s ease;
    max-width: 100%;
    max-height: 232px;
    margin: 0;
    padding: 0;
}

.card {
    transition: 0.5s;
    cursor: pointer;
    border-radius: 3px;
    box-shadow: -2px 6px 19px 0px #7f818e;
    margin-left: auto;
    margin-right: auto;
}

.card-title {
    font-family: "Sora", sans-serif;
    font-size: 1.5rem;
    color: #d7722c;
    padding-bottom: 20px;
}

.card-text {
    font-family: "Rockwell", serif;
    color: black;
    font-weight: bold;
    font-size: 1 rem;
    padding-bottom: 25px;
}

.card::before,
.card::after {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    transform: scale3d(0, 0, 1);
    transition: transform 0.3s ease-out 0s;
    content: "";
    pointer-events: none;
}

.card::before {
    transform-origin: left top;
}

.card::after {
    transform-origin: right bottom;
}

.card:hover::before,
.card:hover::after,
.card:focus::before,
.card:focus::after {
    transform: scale3d(1, 1, 1);
}

.more-details {
    text-align: center;
    background-color: #3d348b;
    color: #fff;
    font-weight: 600;
    font-size: 1rem;
    border-radius: 20px;
    margin-right: 20px;
    margin-left: 30px;
}

.more-details:hover {
    color: #3d348b;
    background: white;
    border: 2px solid #3d348b;
    text-shadow: 1px 1px 3px #727ff0;
}

.rating-block {
    display: inline-block;
    text-align: center;
    background-color: #31c2cf;
    font-weight: 600;
    font-size: 1rem;
    border-radius: 20px;
    padding: 8px;
}

.rating-block:hover {
    text-shadow: 0px 0px 6px rgba(255, 255, 255, 1);
    transition: all 0.4s ease 0s;
}

.rateYo {
    display: none;
}

.card-text {
    overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    /* number of lines to show */
    -webkit-box-orient: vertical;
}

.link {
    background-color: white;
    color: #d7722c;
}

.link:hover {
    color: #d7722c;
    background-color: #e5e4e2;
}

.des {
    background-color: #d7722c;
    color: white;
}

.pagination {
    margin-top: 50px;
}

@media screen and (max-width: 600px) {
    .more-details {
        font-size: 12px;
        right: 10px;
        position: absolute;
        bottom: 10px;
    }
    .rating-block {
        left: 10%;
        font-size: 12px;
        position: absolute;
        bottom: 10px;
    }
    .card-deck {
        padding-left: 0%;
    }
    .card-text {
        margin-bottom: 10px !important;
        font-size: 14px;
    }
    .card-title {
        padding-bottom: 0;
        font-size: large;
    }
    .card {
        margin: 50px;
    }
    .card img {
        height: auto;
        width: 100%;
    }
}

================================================
FILE: static/mainapp/css/recommendation.css
================================================
@import url("https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap");
@import url(//netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.css);
* {
    outline: none;
    box-sizing: border-box;
}

.heading {
    font-family: "Lobster", cursive;
    font-size: 300%;
    background-color: #d7722c;
    margin-top: 0px;
    color: white;
}

.cover-img {
    max-width: 100%;
}

.book-cell {
    position: relative;
    display: flex;
    padding: 25px;
    width: 33.33%;
    height: 250px;
    background-color: #133050;
}

.book-photo {
    width: 180px;
    flex-shrink: 0;
    bottom: -35px;
    left: 35px;
    border-radius: 2px;
    box-shadow: -2px 6px 19px 0px #7f818e;
    transition: 0.3s ease;
}

.book-photo:hover {
    transform: scale(1.03);
}

.book-img {
    flex-shrink: 0;
}

.book-title {
    text-overflow: ellipsis;
    white-space: nowrap;
    overflow: hidden;
    color: #ffffff;
    font-weight: 600;
    font-size: larger;
}

.book-author {
    margin-top: 3px;
    font-size: 18px;
    text-overflow: ellipsis;
    white-space: nowrap;
    overflow: hidden;
}

.book-content {
    padding: 0 20px;
    color: #ffffff;
    overflow: hidden;
}

.book-voters {
    color: #fff;
    vertical-align: sub;
    font-size: 18px;
    margin-left: 7px;
    white-space: nowrap;
    margin-top: 7px;
}

.book-see {
    margin-top: 10px;
    text-align: center;
    background-color: #fff;
    color: #d7722c;
    font-weight: 600;
    padding: 8px;
    font-size: 14px;
    width: 160px;
    border-radius: 20px;
}

.book-see:hover {
    color: black;
}

@media (max-width: 1103px) {
    .book-cell {
        width: 60%;
    }
}

@media (max-width: 765px) {
    .book-cell {
        width: 80%;
    }
}

@media (max-width: 575px) {
    .book-cell {
        width: 100%;
    }
}

@media (max-width: 458px) {
    .book-photo {
        width: 180px;
    }
}

@media (max-width: 421px) {
    .book-see {
        width: 120px;
        font-size: 13px;
    }
    .book-photo {
        width: 130px;
    }
    .more-details {
        font-size: 13px !important;
        right: 22% !important;
    }
    .rating-block {
        font-size: 13px !important;
    }
}

.more-details {
    text-align: center;
    background-color: #3d348b;
    color: #fff;
    font-weight: 600;
    font-size: 15px;
    border-radius: 20px;
    position: absolute;
    right: 26%;
    margin-top: 20%;
    bottom: 70px;
    margin-right: -12px;
}

.more-details:hover {
    color: #3d348b;
    background: white;
    border: 2px solid #3d348b;
    text-shadow: 1px 1px 3px #727ff0;
}

.rating-block {
    text-align: center;
    background-color: #31c2cf;
    font-weight: 600;
    font-size: 15px;
    border-radius: 20px;
    padding: 8px;
    bottom: 10px;
    position: absolute;
    left: 50%;
}

.more-details {
    padding-left: -2px;
}

.rating-block:hover {
    text-shadow: 0px 0px 6px rgba(255, 255, 255, 1);
    transition: all 0.4s ease 0s;
}

.rateYo {
    display: none;
}

================================================
FILE: static/mainapp/css/saved_book.css
================================================
.genre-head {
    font-family: "Lobster", cursive;
    font-size: 300%;
    background-color: #d7722c;
    margin-top: 0px;
    color: white;
}

#sekil img {
    padding-left: 10px;
    margin-top: -60px;
    width: 200px;
    height: 260px;
    box-shadow: 2px 2px 2px #9e9e9e;
    -webkit-box-shadow: 5px 5px 3px #9e9e9e;
    -moz-box-shadow: 3px 3px 1px #9e9e9e;
}

.obsu {
    margin-top: 70px;
    width: 550px;
    background-color: white;
    border-radius: 10px;
    margin-left: 6.5%;
}

#book_name {
    margin-top: -190px;
    padding-left: 220px;
    font-family: "Sora", sans-serif;
    font-size: 1.2rem;
    color: #d7722c;
}

#author_name {
    padding-left: 220px;
    font-family: "Rockwell", serif;
    color: black;
    font-weight: bold;
    font-size: 1 rem;
    padding-bottom: 25px;
    padding-top: 9px;
}

#content {
    display: absolute;
}

.remove {
    margin-top: 10px;
    background-color: red;
    text-align: center;
    font-weight: 600;
    font-size: 1rem;
    border-radius: 20px;
    color: #fff;
    margin-left: 53%;
    margin-bottom: 3%;
}

.remove:hover {
    color: red;
    background: white;
    border: 2px solid red;
    text-shadow: 1px 1px 3px #ffcccb;
}

.more-details {
    margin-left: 40%;
    text-align: center;
    background-color: #3d348b;
    color: #fff;
    font-weight: 600;
    font-size: 1rem;
    border-radius: 20px;
    margin-right: 20px;
}

.more-details:hover {
    color: #3d348b;
    background: white;
    border: 2px solid #3d348b;
    text-shadow: 1px 1px 3px #727ff0;
}

.rating-block {
    display: inline-block;
    text-align: center;
    background-color: #31c2cf;
    font-weight: 600;
    font-size: 1rem;
    border-radius: 20px;
    padding: 8px;
}

.rating-block:hover {
    text-shadow: 0px 0px 6px rgba(255, 255, 255, 1);
    transition: all 0.4s ease 0s;
}

.rateYo {
    display: none;
}

.link {
    background-color: white;
    color: #d7722c;
}

.link:hover {
    color: #d7722c;
    background-color: #e5e4e2;
}

.des {
    background-color: #d7722c;
    color: white;
}

.pagination {
    margin-top: 50px;
}

@media screen and (max-width: 600px) {
    .obsu {
        width: 323px;
    }
    #sekil img {
        width: 160px;
        height: 200px;
    }
    #book_name {
        font-size: 18px;
        padding-top: 22%;
        padding-left: 54%;
    }
    #author_name {
        padding-left: 54%;
    }
    .more-details {
        font-size: 12px;
        margin-left: 13%;
    }
    .rating-block {
        font-size: 12px;
    }
    .remove {
        font-size: 12px;
        margin-left: 28%;
    }
    #content {
        padding-top: 13%;
    }
}

================================================
FILE: static/mainapp/css/signup.css
================================================
.account-block {
    margin: auto;
    height: 80%;
    width: 70%;
    background-color: white;
}

.signup-block {
    text-align: center;
}

fa-google {
    padding-right: 5px;
}

.googlebutton {
    position: relative;
    background-color: #f25f5c;
    font-family: "Fredoka One", cursive;
    color: white;
    padding: 6px 5px;
    border: 2px solid white;
    border-radius: 15px;
    text-decoration: none !important;
    box-shadow: 0 0 6px 2px rgba(0, 0, 0, 0.5);
    border: 3px solid #fff;
    bottom: 9%;
    left: 1px;
}

.googlebutton:hover {
    color: #f25f5c;
    background-color: white;
    border: 3px solid #f25f5c;
}

.img-block {
    color: white;
    background-size: cover;
    background-position: center;
}

.btn-bot {
    font-family: "Fredoka One", cursive;
    position: absolute;
    margin-left: -45px;
    left: 50%;
    padding: 5px 10px 5px 10px;
    border: 2px solid white;
    border-radius: 25px;
    bottom: 250px;
    text-decoration: none !important;
    color: white;
}

.btn-bot:hover {
    color: black;
    border: 2px solid black;
    background-color: rgba(255, 255, 255, 0.891);
}

.welcome {
    font-family: "Pacifico", cursive;
    position: relative;
    top: 4%;
    left: 32%;
    border-radius: 50px;
    font-size: 2.5rem;
    background-color: #ffdab9;
    width: 35%;
}

label {
    font-family: "Kalam", cursive;
    font-size: 1.2em;
}

.form-group {
    padding: 3% 4% 4% 3%;
    position: relative;
    display: inline-block;
    top: 25px;
    color: black;
}

#id_username,
#id_email,
#id_password1,
#id_password2 {
    border-top: none;
    border-left: none;
    border-right: none;
    color: #000;
}

.signupbutton {
    font-family: "Fredoka One", cursive;
    padding: 8px 10px 5px 10px;
    font-size: 1rem;
    margin-bottom: 3rem;
    margin-top: 0.5rem;
    border: 2px solid white;
    box-shadow: 0 0 6px 2px rgba(0, 0, 0, 0.5);
    border: 3px solid #fff;
    color: #fff;
    background: rgba(1, 1, 1);
    border-radius: 15px;
    outline: none;
}

.signupbutton:hover {
    background-color: #ffdab9;
    color: black;
    border: 3px solid black;
}

strong {
    color: red;
    font-size: 0.9rem;
}

::placeholder {
    color: #000;
    font-weight: normal;
}

.error_div {
    margin-top: 10px !important;
}

@media only screen and (max-width: 1200px) {
    .img-block {
        display: none;
    }
    .account-block {
        width: 70%;
    }
    .welcome {
        font-size: 2rem;
        width: 35%;
        left: 32%;
        margin-top: -0.2rem;
    }
}

@media only screen and (max-width: 600px) {
    .signupbutton {
        margin-bottom: 3.8rem;
        margin-top: 0.5rem;
    }
    .welcome {
        font-size: 1.5rem;
        width: 60%;
        left: 20%;
        margin-top: -0.5rem;
    }
    .form-group {
        padding: 3% 6% 3% 3%;
        margin-top: 1rem;
    }
    .account-block {
        width: 60%;
    }
}

@media only screen and (max-width: 450px) {
    .form-group {
        padding: 4% 3% 3% 3%;
        margin-top: 0rem;
    }
    .signupbutton {
        margin-bottom: 3.5rem;
    }
    .account-block {
        width: 70%;
    }
}

@media only screen and (min-width: 1200px) {
    .form-group {
        padding: 4% 3% 3% 3%;
        margin-top: 0rem;
    }
    .signupbutton {
        margin-bottom: 2.3rem;
        margin-top: 1.5rem;
    }
    .googlebutton {
        margin-top: 1rem;
    }
}

================================================
FILE: static/mainapp/dataset/books.csv
================================================
,r_index,book_id,authors,original_title,image_url,average_rating,ratings_count,genre,desc
0,1,2767052,Suzanne Collins,The Hunger Games,https://images.gr-assets.com/books/1447303603l/2767052.jpg,4.34,4780653,"fiction, fantasy","In a future North America, where the rulers of Panem maintain control
through an annual televised survival competition pitting young people from
each of the twelve districts against one another, sixteen-year-old
Katniss's skills are put to the test when she voluntarily takes her younger
sister's place."
1,2,3,"J.K. Rowling, Mary GrandPré",Harry Potter and the Philosopher's Stone,https://images.gr-assets.com/books/1474154022l/3.jpg,4.44,4602479,"fantasy, fiction","Rescued from the outrageous neglect of his aunt and uncle, a young boy with
a great destiny proves his worth while attending Hogwarts School for
Witchcraft and Wizardry."
2,3,41865,Stephenie Meyer,Twilight,https://images.gr-assets.com/books/1361039443l/41865.jpg,3.57,3866839,"fantasy, fiction","With 160 million copies of the Twilight Saga sold worldwide, this addictive
love story between a teenage girl and a vampire redefined romance for a
generation. Here's the book that started it all. Isabella Swan's move to
Forks, a small, perpetually rainy town in Washington, could have been the
most boring move she ever made. But once she meets the mysterious and
alluring Edward Cullen, Isabella's life takes a thrilling and terrifying
turn. Up until now, Edward has managed to keep his vampire identity a
secret in the small community he lives in, but now nobody is safe,
especially Isabella, the person Edward holds most dear. The lovers find
themselves balanced precariously on the point of a knife-between desire and
danger. Deeply romantic and extraordinarily suspenseful, Twilightcaptures
the struggle between defying our instincts and satisfying our desires. This
is a love story with bite. ""People do not want to just read Meyer's books;
they want to climb inside them and live there.""-Time ""A literary
phenomenon.""-The New York Times"
3,4,2657,Harper Lee,To Kill a Mockingbird,https://images.gr-assets.com/books/1361975680l/2657.jpg,4.25,3198671,"classics, fiction","The unforgettable novel of a childhood in a sleepy Southern town and the
crisis of conscience that rocked it, To Kill A Mockingbird became both an
instant bestseller and a critical success when it was first published in
1960. It went on to win the Pulitzer Prize in 1961 and was later made into
an Academy Award-winning film, also a classic. Compassionate, dramatic, and
deeply moving, To Kill A Mockingbird takes readers to the roots of human
behavior - to innocence and experience, kindness and cruelty, love and
hatred, humor and pathos. Now with over 18 million copies in print and
translated into forty languages, this regional story by a young Alabama
woman claims universal appeal. Harper Lee always considered her book to be
a simple love story. Today it is regarded as a masterpiece of American
literature."
4,5,4671,F. Scott Fitzgerald,The Great Gatsby,https://images.gr-assets.com/books/1490528560l/4671.jpg,3.89,2683664,"classics, fiction","A young man newly rich tries to recapture the past and win back his former
love, despite the fact that she has married."
5,6,11870085,John Green,The Fault in Our Stars,https://images.gr-assets.com/books/1360206420l/11870085.jpg,4.26,2346404,"fiction, romance","Despite the medical miracle that has bought her a few more years, Hazel has
never been anything but terminal, but when Augustus Waters suddenly appears
at the Cancer Kid Support Group, Hazel's story is about to be rewritten."
6,7,5907,J.R.R. Tolkien,The Hobbit or There and Back Again,https://images.gr-assets.com/books/1372847500l/5907.jpg,4.25,2071616,"fantasy, classics","Chronicles the adventures of the inhabitants of Middle-earth and Bilbo
Baggins, the hobbit who brought home to The Shire the One Ring of Power"
7,8,5107,J.D. Salinger,The Catcher in the Rye,https://images.gr-assets.com/books/1398034300l/5107.jpg,3.79,2044241,"classics, fiction","The ""brilliant, funny, meaningful novel"" (The New Yorker) that established
J. D. Salinger as a leading voice in American literature--and that has
instilled in millions of readers around the world a lifelong love of books.
""If you really want to hear about it, the first thing you'll probably want
to know is where I was born, and what my lousy childhood was like, and how
my parents were occupied and all before they had me, and all that David
Copperfield kind of crap, but I don't feel like going into it, if you want
to know the truth."" The hero-narrator of The Catcher in the Rye is an
ancient child of sixteen, a native New Yorker named Holden Caufield.
Through circumstances that tend to preclude adult, secondhand description,
he leaves his prep school in Pennsylvania and goes underground in New York
City for three days."
8,9,960,Dan Brown,Angels & Demons ,https://images.gr-assets.com/books/1303390735l/960.jpg,3.85,2001311,"fiction, mystery","The explosive Robert Langdon thriller from Dan Brown, the #1 New York Times
bestselling author of The Da Vinci Code and Inferno—now a major film
directed by Ron Howard and starring Tom Hanks and Felicity Jones. Angels &
Demons careens from enlightening epiphanies to dark truths as the battle
between science and religion turns to war. This is the book that started it
all: we meet Robert Langdon for the first time, caught up in a race against
time to find an apocalyptic time-bomb, planted by an ancient secret society
that has surfaced to carry out its ultimate threat: to destroy the Vatican."
9,10,1885,Jane Austen,Pride and Prejudice,https://images.gr-assets.com/books/1320399351l/1885.jpg,4.24,2035490,"classics, fiction","In early nineteenth-century England, a spirited young woman copes with the
suit of a snobbish gentleman, as well as the romantic entanglements of her
four sisters."
10,11,77203,Khaled Hosseini,The Kite Runner ,https://images.gr-assets.com/books/1484565687l/77203.jpg,4.26,1813044,"fiction, contemporary",The Kite Runner Khaled Hosseini
11,12,13335037,Veronica Roth,Divergent,https://images.gr-assets.com/books/1328559506l/13335037.jpg,4.24,1903563,"fiction, fantasy","Paperback features over fifty pages of bonus materials, including a sneak
peek of Insurgent, an author Q&A, a discussion guide, a Divergent playlist,
faction manifestos, and more! In Beatrice Prior's dystopian Chicago world,
society is divided into five factions, each dedicated to the cultivation of
a particular virtue—Candor (the honest), Abnegation (the selfless),
Dauntless (the brave), Amity (the peaceful), and Erudite (the intelligent).
On an appointed day of every year, all sixteen-year-olds must select the
faction to which they will devote the rest of their lives. For Beatrice,
the decision is between staying with her family and being who she really
is—she can't have both. So she makes a choice that surprises everyone,
including herself. During the highly competitive initiation that follows,
Beatrice renames herself Tris and struggles alongside her fellow initiates
to live out the choice they have made. Together they must undergo extreme
physical tests of endurance and intense psychological simulations, some
with devastating consequences. As initiation transforms them all, Tris must
determine who her friends really are—and where, exactly, a romance with a
sometimes fascinating, sometimes exasperating boy fits into the life she's
chosen. But Tris also has a secret, one she's kept hidden from everyone
because she's been warned it can mean death. And as she discovers unrest
and growing conflict that threaten to unravel her seemingly perfect
society, she also learns that her secret might help her save those she
loves . . . or it might destroy her. Veronica Roth is the New York Times
bestselling author of Divergent, the first in a trilogy of dystopian
thrillers filled with electrifying decisions, heartbreaking betrayals,
stunning consequences, and unexpected romance."
12,13,5470,"George Orwell, Erich Fromm, Celâl Üster",Nineteen Eighty-Four,https://images.gr-assets.com/books/1348990566l/5470.jpg,4.14,1956832,"fiction, fantasy","Renowned urban artist Shepard Fairey's new look for Orwell's classic
dystopian tale One of Britain's most popular novels, George Orwell's
Nineteen Eighty-Four is set in a society terrorised by a totalitarian
ideology propagated by The Party. Winston Smith works for the Ministry of
Truth in London, chief city of Airstrip One. Big Brother stares out from
every poster, the Thought Police uncover every act of betrayal. When
Winston finds love with Julia, he discovers that life does not have to be
dull and deadening, and awakens to new possibilities. Despite the police
helicopters that hover and circle overhead, Winston and Julia begin to
question the Party; they are drawn towards conspiracy. Yet Big Brother will
not tolerate dissent - even in the mind. For those with original thoughts
they invented Room 101. . . Nineteen Eighty-Four is George Orwell's
terrifying vision of a totalitarian future in which everything and everyone
is slave to a tyrannical regime. The novel also coined many new words and
phrases which regular appear in popular culture, such as 'Big Brother',
'thoughtcrime', 'doublethink' and 'Newspeak'."
13,14,7613,George Orwell,Animal Farm: A Fairy Story,https://images.gr-assets.com/books/1424037542l/7613.jpg,3.87,1881700,"classics, fiction","A satire on totalitarianism in which farm animals overthrow their human
owner and set up their own government"
14,15,48855,"Anne Frank, Eleanor Roosevelt, B.M. Mooyaart-Doubleday",Het Achterhuis: Dagboekbrieven 14 juni 1942 - 1 augustus 1944,https://images.gr-assets.com/books/1358276407l/48855.jpg,4.1,1972666,"classics, history","Dagboek waarin een gevoelig joods meisje, ondergedoken in een achterhuis op
één der Amsterdamse grachten, zich met grote openhartigheid uitspreekt over
ales wat haar van haar 13e tot haar 15e jaar bezighoudt."
15,16,2429135,"Stieg Larsson, Reg Keeland",Män som hatar kvinnor,https://images.gr-assets.com/books/1327868566l/2429135.jpg,4.11,1808403,"fiction, mystery","Forty years after the disappearance of Harriet Vanger from the secluded
island owned and inhabited by the powerful Vanger family, her octogenarian
uncle hires journalist Mikael Blomqvist and Lisbeth Salander, an
unconventional young hacker, to investigate."
16,17,6148028,Suzanne Collins,Catching Fire,https://images.gr-assets.com/books/1358273780l/6148028.jpg,4.3,1831039,"fantasy, romance","By winning the Hunger Games, Katniss and Peeta have secured a life of
safety and plenty for themselves and their families, but because they won
by defying the rules, they unwittingly become the faces of an impending
rebellion."
17,18,5,"J.K. Rowling, Mary GrandPré, Rufus Beck",Harry Potter and the Prisoner of Azkaban,https://images.gr-assets.com/books/1499277281l/5.jpg,4.53,1832823,"fantasy, fiction","Harry Potter and the Prisoner of AzkabanJ.K. Rowling, Mary GrandPré, Rufus Beck"
18,19,34,J.R.R. Tolkien, The Fellowship of the Ring,https://images.gr-assets.com/books/1298411339l/34.jpg,4.34,1766803,"fantasy, classics","In anticipation of the new film The Hobbit, opening in December 2012, comes
a reissue of the first book in The Lord of the Rings series. Reissue.
200,000 first printing."
19,20,7260188,Suzanne Collins,Mockingjay,https://images.gr-assets.com/books/1358275419l/7260188.jpg,4.03,1719760,"fiction, fantasy","Two-time Hunger Games survivor Katniss Everdeen is targeted by a vengeful
Capitol that vows to make Katniss and all of District 12 pay for the
current unrest."
20,21,2,"J.K. Rowling, Mary GrandPré",Harry Potter and the Order of the Phoenix,https://images.gr-assets.com/books/1387141547l/2.jpg,4.46,1735368,"fantasy, fiction","When the government of the magic world and authorities at Hogwarts School
of Witchcraft and Wizardry refuse to believe in the growing threat of a
freshly revived Lord Voldemort, fifteen-year-old Harry Potter finds support
from his loyal friends in facingthe evil wizard and other new terrors."
21,22,12232938,Alice Sebold,The Lovely Bones,https://images.gr-assets.com/books/1457810586l/12232938.jpg,3.77,1605173,"fiction, mystery","The spirit of fourteen-year-old Susie Salmon describes her murder, her
surprise at her new home in heaven, and her witness to her family's grief,
efforts to find the killer, and attempts to come to terms with what has
happened. A first novel. Reader's Guide included. Reprint. 750,000 first
printing."
22,23,15881,"J.K. Rowling, Mary GrandPré",Harry Potter and the Chamber of Secrets,https://images.gr-assets.com/books/1474169725l/15881.jpg,4.37,1779331,"fantasy, fiction","Harry Potter and the Chamber of SecretsJ.K. Rowling, Mary GrandPré"
23,24,6,"J.K. Rowling, Mary GrandPré",Harry Potter and the Goblet of Fire,https://images.gr-assets.com/books/1361482611l/6.jpg,4.53,1753043,"fantasy, fiction","In Harry Potter and the Goblet of Fire, Harry is midway through both his
training as a wizard and his coming of age. He wants to get away from the
malicious Dursleys and go to the Quidditch World Cup with Hermione, Ron,
and the Weasleys. He wants to dream about his crush, Cho Chang (and maybe
do more than dream). And now that he’s gotten the hang of things at
Hogwarts—he hopes—he just wants to be a normal fourteen-year-old wizard.
But even by his standards, Harry's year is anything but normal. First
Dumbledore announces the revival of a grand competition that hasn't taken
place for one hundred years: the Triwizard Tournament, where a Hogwarts
champion will compete against rivals from two other schools of magic in
three highly dangerous tasks. Then someone frames Harry to participate in
the tournament—which really means someone wants him dead. Harry is guided
through the competition by Professor Alastor Moody, this year's Defense
Against the Dark Arts teacher, but he must also contend with a nasty
reporter named Rita Skeeter, who digs up some highly unflattering secrets
about Hagrid; a terrible fight with Ron, who is deeply jealous of Harry's
fame; Hermione's newfound activism on behalf of house-elves; and the
terrifying prospect of asking a date to the Yule Ball. Worst of all, Lord
Voldemort may finally have gathered the materials necessary for his
rejuvenation... and he has a faithful servant at Hogwarts waiting only for
a sign. No, nothing is ever normal for Harry Potter. And in his case,
different can be deadly."
24,25,136251,"J.K. Rowling, Mary GrandPré",Harry Potter and the Deathly Hallows,https://images.gr-assets.com/books/1474171184l/136251.jpg,4.61,1746574,"fantasy, fiction","In Harry Potter and the Deathly Hallows, the seventh and final book in the
epic tale of Harry Potter, Harry and Lord Voldemort each prepare for their
ultimate encounter. Voldemort takes control of the Ministry of Magic,
installs Severus Snape as headmaster at Hogwarts, and sends his Death
Eaters across the country to wreak havoc and find Harry. Meanwhile, Harry,
Ron, and Hermione embark on a desperate quest the length and breadth of
Britain, trying to locate and destroy Voldemort’s four remaining Horcruxes,
the magical objects in which he has hidden parts of his broken soul. They
visit the Burrow, Grimmauld Place, the Ministry, Godric’s Hollow, Malfoy
Manor, Diagon Alley…But every time they solve one mystery, three more
evolve—and not just about Voldemort, but about Dumbledore, and Harry’s own
past, and three mysterious objects called the Deathly Hallows. The Hallows
are literally things out of a children’s tale, which, if real, promise to
make their possessor the “Master of Death;” and they ensnare Harry with
their tantalizing claim of invulnerability. It is only after a nigh-
unbearable loss that he is brought back to his true purpose, and the trio
returns to Hogwarts for the final breathtaking battle between the forces of
good and evil. They fight the Death Eaters alongside members of the Order
of the Phoenix, Dumbledore’s Army, the Weasley clan, and the full array of
Hogwarts teachers and students. Yet everything turns upon the moment the
entire series has been building up to, the same meeting with which our
story began: the moment when Harry and Voldemort face each other at last."
25,26,968,Dan Brown,The Da Vinci Code,https://images.gr-assets.com/books/1303252999l/968.jpg,3.79,1447148,"fiction, thriller","Harvard symbologist Robert Langdon and French cryptologist Sophie Neveu
work to solve the murder of an elderly curator of the Louvre, a case which
leads to clues hidden in the works of Da Vinci and a centuries-old secret
society."
26,27,1,"J.K. Rowling, Mary GrandPré",Harry Potter and the Half-Blood Prince,https://images.gr-assets.com/books/1361039191l/1.jpg,4.54,1678823,"fantasy, fiction","As Harry enters his sixth year at Hogwarts, a storm is brewing in the
battle between good and evil, a battle that promises to have incredible
consequences for the magic world."
27,28,7624,William Golding,Lord of the Flies ,https://images.gr-assets.com/books/1327869409l/7624.jpg,3.64,1605019,"classics, fiction","The classic study of human nature which depicts the degeneration of a group
of schoolboys marooned on a desert island."
28,29,18135,"William Shakespeare, Robert           Jackson",An Excellent conceited Tragedie of Romeo and Juliet,https://images.gr-assets.com/books/1327872146l/18135.jpg,3.73,1628519,"classics, fiction","An Excellent conceited Tragedie of Romeo and JulietWilliam Shakespeare, Robert           Jackson"
29,30,8442457,Gillian Flynn,Gone Girl,https://images.gr-assets.com/books/1339602131l/8442457.jpg,4.03,512475,"mystery, crime","When a woman goes missing on her fifth wedding anniversary, her diary
reveals hidden turmoil in her marriage, while her husband, desperate to
clear himself of suspicion, realizes that something more disturbing than
murder may have occurred."
30,31,4667024,Kathryn Stockett,The Help,https://images.gr-assets.com/books/1346100365l/4667024.jpg,4.45,1531753,"fiction, contemporary","Limited and persecuted by racial divides in 1962 Jackson, Mississippi,
three women, including an African-American maid, her sassy and chronically
unemployed friend and a recently graduated white woman, team up for a
clandestine project against a backdrop of the budding civil rights era.
Reprint. A #1 best-selling novel. 2 million first printing."
31,32,890,John Steinbeck,Of Mice and Men ,https://images.gr-assets.com/books/1437235233l/890.jpg,3.84,1467496,"classics, fiction","The tragic story of the friendship between two migrant workers, George and
mentally retarded Lenny, and their dream of owning a farm"
32,33,930,Arthur Golden,Memoirs of a Geisha,https://i.gr-assets.com/images/S/compressed.photo.goodreads.com/books/1388367666l/930.jpg,4.08,1300209,"fiction, romance","National best seller, Japan's most celebrated geisha, confessions novel."
33,34,10818853,E.L. James,Fifty Shades of Grey,https://images.gr-assets.com/books/1385207843l/10818853.jpg,3.67,1338493,"romance, fiction","When Anastasia Steele, a young literature student, interviews wealthy young
entrepreneur Christian Grey for her campus magazine, their initial meeting
introduces Anastasia to an exciting new world that will change them both
forever."
34,35,865,"Paulo Coelho, Alan R. Clarke",O Alquimista,https://images.gr-assets.com/books/1483412266l/865.jpg,3.82,1299566,"fiction, classics","""My heart is afraid that it will have to suffer,"" the boy told the
alchemist one night as they looked up at the moonless sky."" Tell your heart
that the fear of suffering is worse than the suffering itself. And that no
heart has ever suffered when it goes in search of its dreams."" Every few
decades a book is published that changes the lives of its readers forever.
The Alchemist is such a book. With over a million and a half copies sold
around the world, The Alchemist has already established itself as a modern
classic, universally admired. Paulo Coelho's charming fable, now available
in English for the first time, will enchant and inspire an even wider
audience of readers for generations to come. The Alchemist is the magical
story of Santiago, an Andalusian shepherd boy who yearns to travel in
search of a worldly treasure as extravagant as any ever found. From his
home in Spain he journeys to the markets of Tangiers and across the
Egyptian desert to a fateful encounter with the alchemist. The story of the
treasures Santiago finds along the way teaches us, as only a few stories
have done, about the essential wisdom of listening to our hearts, learning
to read the omens strewn along life's path, and, above all, following our
dreams."
35,36,3636,Lois Lowry,The Giver,https://images.gr-assets.com/books/1342493368l/3636.jpg,4.12,1296825,"fiction, classics","Given his lifetime assignment at the Ceremony of Twelve, Jonas becomes the
receiver of memories shared by only one other in his community and
discovers the terrible truth about the society in which he lives."
36,37,100915,C.S. Lewis,"The Lion, the Witch and the Wardrobe",https://images.gr-assets.com/books/1353029077l/100915.jpg,4.19,1531800,"fantasy, classics",They open a door and enter a world.
37,38,14050,Audrey Niffenegger,The Time Traveler's Wife,https://images.gr-assets.com/books/1437728815l/14050.jpg,3.95,746287,"fiction, romance","Passionately in love, Clare and Henry vow to hold onto each other and their
marriage as they struggle with the effects of Chrono-Displacement Disorder,
a condition that casts Henry involuntarily into the world of time travel."
38,39,13496,George R.R. Martin,A Game of Thrones,https://images.gr-assets.com/books/1436732693l/13496.jpg,4.45,1319204,"fiction, fantasy","The kingdom of the royal Stark family faces its ultimate challenge in the
onset of a generation-long winter, the poisonous plots of the rival
Lannisters, the emergence of the Neverborn demons and the arrival of
barbarian hordes. Reissue. TV tie-in."
39,40,19501,Elizabeth Gilbert,"Eat, pray, love: one woman's search for everything across Italy, India and Indonesia",https://images.gr-assets.com/books/1503066414l/19501.jpg,3.51,1181647,"memoir, travel","Eat, pray, love: one woman's search for everything across Italy, India and IndonesiaElizabeth Gilbert"
40,41,28187,Rick Riordan,The Lightning Thief,https://images.gr-assets.com/books/1400602609l/28187.jpg,4.23,1366265,"fantasy, fiction",The Lightning ThiefRick Riordan
41,42,1934,Louisa May Alcott,Little Women,https://i.gr-assets.com/images/S/compressed.photo.goodreads.com/books/1562690475l/1934._SY475_.jpg,4.04,1257121,"classics, fiction",Little WomenLouisa May Alcott
42,43,10210,"Charlotte Brontë, Michael Mason",Jane Eyre,https://images.gr-assets.com/books/1327867269l/10210.jpg,4.1,1198557,"fiction, ebooks","Retells the classic story of an orphaned young woman who accepts employment
as a governess and soon finds herself in love with her employer."
43,44,15931,Nicholas Sparks,The Notebook,https://images.gr-assets.com/books/1385738917l/15931.jpg,4.06,1053403,"fiction, romance",The NotebookNicholas Sparks
44,45,4214,Yann Martel,Life of Pi,https://images.gr-assets.com/books/1320562005l/4214.jpg,3.88,1003228,"fantasy, classics","Possessing encyclopedia-like intelligence, unusual zookeeper's son Pi Patel
sets sail for America, but when the ship sinks, he escapes on a life boat
and is lost at sea with a dwindling number of animals until only he and a
hungry Bengal tiger remain."
45,46,43641,Sara Gruen,Water for Elephants,https://images.gr-assets.com/books/1494428973l/43641.jpg,4.07,1068146,"fiction, romance",Water for ElephantsSara Gruen
46,47,19063,Markus Zusak,The Book Thief,https://images.gr-assets.com/books/1390053681l/19063.jpg,4.36,1159741,"fiction, classics","Trying to make sense of the horrors of World War II, Death relates the
story of Liesel--a young German girl whose book-stealing and story-telling
talents help sustain her family and the Jewish man they are hiding, as well
as their neighbors."
47,48,4381,Ray Bradbury,Fahrenheit 451,https://images.gr-assets.com/books/1351643740l/4381.jpg,3.97,570498,"classics, fiction","A totalitarian regime has ordered all books to be destroyed, but one of the
book burners, Guy Montag, suddenly realizes their merit."
48,49,49041,Stephenie Meyer,"New Moon (Twilight, #2)",https://images.gr-assets.com/books/1361039440l/49041.jpg,3.52,1149630,"fantasy, romance","New Moon (Twilight, #2)Stephenie Meyer"
49,50,30119,Shel Silverstein,Where the Sidewalk Ends: The Poems and Drawings of Shel Silverstein,https://images.gr-assets.com/books/1168052448l/30119.jpg,4.29,1016888,"poetry, classics","If you are a dreamer, come in, If you are a dreamer, A wisher, a liar, A
hope-er, a pray-er, A magic bean buyer … Come in … for where the sidewalk
ends, Shel Silverstein’s world begins. You’ll meet a boy who turns into a
TV set, and a girl who eats a whale. The Unicorn and the Bloath live there,
and so does Sarah Cynthia Sylvia Stout who will not take the garbage out.
It is a place where you wash your shadow and plant diamond gardens, a place
where shoes fly, sisters are auctioned off, and crocodiles go to the
dentist. Shel Silverstein’s masterful collection of poems and drawings is
at once outrageously funny and profound."
50,51,256683,Cassandra Clare,City of Bones,https://images.gr-assets.com/books/1432730315l/256683.jpg,4.12,1154031,"paranormal, romance","Suddenly able to see demons and the Shadowhunters who are dedicated to
returning them to their own dimension, fifteen-year-old Clary Fray is drawn
into this bizarre world when her mother disappears and Clary herself is
almost killed by a monster."
51,52,428263,Stephenie Meyer,Eclipse,https://images.gr-assets.com/books/1361038355l/428263.jpg,3.69,1134511,"fantasy, romance","Readers captivated by Twilight and New Moon will eagerly devour the
paperback edition Eclipse, the third book in Stephenie Meyer's riveting
vampire love saga. As Seattle is ravaged by a string of mysterious killings
and a malicious vampire continues her quest for revenge, Bella once again
finds herself surrounded by danger. In the midst of it all, she is forced
to choose between her love for Edward and her friendship with Jacob ---
knowing that her decision has the potential to ignite the ageless struggle
between vampire and werewolf. With her graduation quickly approaching,
Bella has one more decision to make: life or death. But which is which?"
52,53,113436,Christopher Paolini,Eragon,https://images.gr-assets.com/books/1366212852l/113436.jpg,3.86,1104021,"fantasy, fiction","In Alagaèesia, a fifteen-year-old boy of unknown lineage called Eragon
finds a mysterious stone that weaves his life into an intricate tapestry of
destiny, magic, and power, peopled with dragons, elves, and monsters."
53,54,11,Douglas Adams,The Hitchhiker's Guide to the Galaxy,https://images.gr-assets.com/books/1327656754l/11.jpg,4.2,936782,"fiction, fantasy","Chronicles the journeys, notions, and acquaintances of reluctant galactic
traveler Arthur Dent, accompanied by never-before-published material from
the late author's archives as well as commentary by famous fans."
54,55,5129,Aldous Huxley,Brave New World,https://images.gr-assets.com/books/1487389574l/5129.jpg,3.97,1022601,"classics, fiction","Huxley's classic prophetic novel describes the socialized horrors of a
futuristic utopia devoid of individual freedom."
55,56,1162543,Stephenie Meyer,Breaking Dawn,https://images.gr-assets.com/books/1361039438l/1162543.jpg,3.7,1070245,"fantasy, contemporary","In an addition to the author's vampire love saga, following New Moon and
Eclipse, questions are answered about the fate of Bella and Edward.
Reissue."
56,57,37435,Sue Monk Kidd,The Secret Life of Bees,https://images.gr-assets.com/books/1473454532l/37435.jpg,4.01,916189,"fiction, classics","After her ""stand-in mother,"" a bold black woman named Rosaleen, insults the
three biggest racists in town, Lily Owens joins Rosaleen on a journey to
Tiburon, South Carolina, where they are taken in by three black, bee-
keeping sisters."
57,58,2956,"Mark Twain, John Seelye, Guy Cardwell",The Adventures of Huckleberry Finn,https://images.gr-assets.com/books/1405973850l/2956.jpg,3.8,953758,"classics, fiction","A feisty young boy fakes his own death to escape his abusive father and
heads off down the Mississippi River with his newfound friend Jim, a
runaway slave."
58,59,24178,"E.B. White, Garth Williams, Rosemary Wells",Charlotte's Web,https://images.gr-assets.com/books/1439632243l/24178.jpg,4.15,1064521,"classics, fiction","Beloved by generations, Charlotte's Web and Stuart Little are two of the
most cherished stories of all time. Now, for the first time ever, these
treasured classics are available in lavish new collectors' editions. In
addition to a larger trim size, the original black-and-white art by Garth
Williams has been lovingly colorized by renowned illustrator Rosemary
Wells, adding another dimension to these two perfect books for young and
old alike."
59,60,1618,Mark Haddon,The Curious Incident of the Dog in the Night-Time,https://images.gr-assets.com/books/1479863624l/1618.jpg,3.85,867553,"fiction, classics",The Curious Incident of the Dog in the Night-TimeMark Haddon
60,61,22557272,Paula Hawkins,The Girl on the Train,https://images.gr-assets.com/books/1490903702l/22557272.jpg,3.88,1008778,"mystery, fiction",The Girl on the TrainPaula Hawkins
61,62,119322,Philip Pullman,Northern Lights,https://images.gr-assets.com/books/1451271747l/119322.jpg,3.94,953970,"fantasy, fiction","Accompanied by her daemon, Lyra Belacqua sets out to prevent her best
friend and other kidnapped children from becoming the subject of gruesome
experiments in the Far North."
62,63,6185,"Emily Brontë, Richard J. Dunn",Wuthering Heights,https://i.gr-assets.com/images/S/compressed.photo.goodreads.com/books/1587655304l/6185._SY475_.jpg,3.82,899195,"classics, fiction","Wuthering HeightsEmily Brontë, Richard J. Dunn"
63,64,10917,Jodi Picoult,My Sister's Keeper,https://images.gr-assets.com/books/1369504683l/10917.jpg,4.06,863879,"fiction, contemporary","Written with grace, wisdom, and sensitivity, this novel is about a teen who
was conceived as a bone marrow match for her sister Kate, and what happens
when she begins to question who she really is."
64,65,4981,Kurt Vonnegut Jr.,"Slaughterhouse-Five, or The Children's Crusade: A Duty-Dance with Death ",https://images.gr-assets.com/books/1440319389l/4981.jpg,4.06,846488,"classics, fiction","Slaughterhouse-Five, or The Children's Crusade: A Duty-Dance with Death Kurt Vonnegut Jr."
65,66,18405,Margaret Mitchell,Gone with the Wind,https://images.gr-assets.com/books/1328025229l/18405.jpg,4.28,873981,"classics, fiction","The turbulent romance of Scarlett O'Hara and Rhett Butler is shaped by the
ravages of the Civil War and Reconstruction."
66,67,128029,Khaled Hosseini,A Thousand Splendid Suns,https://images.gr-assets.com/books/1345958969l/128029.jpg,4.34,818742,"fiction, contemporary",A Thousand Splendid SunsKhaled Hosseini
67,68,22628,Stephen Chbosky,The Perks of Being a Wallflower,https://images.gr-assets.com/books/1167352178l/22628.jpg,4.21,888806,"fiction, contemporary","A series of letters to an unknown correspondent reveals the coming-of-age
trials of a high-schooler named Charlie"
68,69,11735983,Veronica Roth,Insurgent,https://images.gr-assets.com/books/1325667729l/11735983.jpg,4.07,836362,"fiction, fantasy","As war surges in the dystopian society around her, sixteen-year-old
Divergent Tris Prior must continue trying to save those she loves--and
herself--while grappling with haunting questions of grief and forgiveness,
identity and loyalty, politics, and love."
69,70,375802,Orson Scott Card,Ender's Game,https://images.gr-assets.com/books/1408303130l/375802.jpg,4.3,813439,"fiction, fantasy","From New York Times bestselling author Orson Scott Card, Ender's Game is
the classic Hugo and Nebula award-winning science fiction novel of a young
boy's recruitment into the midst of an interstellar war. In order to
develop a secure defense against a hostile alien race's next attack,
government agencies breed child geniuses and train them as soldiers. A
brilliant young boy, Andrew ""Ender"" Wiggin lives with his kind but distant
parents, his sadistic brother Peter, and the person he loves more than
anyone else, his sister Valentine. Peter and Valentine were candidates for
the soldier-training program but didn't make the cut—young Ender is the
Wiggin drafted to the orbiting Battle School for rigorous military
training. Ender's skills make him a leader in school and respected in the
Battle Room, where children play at mock battles in zero gravity. Yet
growing up in an artificial community of young soldiers Ender suffers
greatly from isolation, rivalry from his peers, pressure from the adult
teachers, and an unsettling fear of the alien invaders. His psychological
battles include loneliness, fear that he is becoming like the cruel brother
he remembers, and fanning the flames of devotion to his beloved sister. Is
Ender the general Earth needs? But Ender is not the only result of the
genetic experiments. The war with the Buggers has been raging for a hundred
years, and the quest for the perfect general has been underway for almost
as long. Ender's two older siblings are every bit as unusual as he is, but
in very different ways. Between the three of them lie the abilities to
remake a world. If, that is, the world survives. Orson Scott Card's Ender's
Game is the winner of the 1985 Nebula Award for Best Novel and the 1986
Hugo Award for Best Novel. THE ENDER UNIVERSE Ender Quintet series Ender’s
Game / Ender in Exile / Speaker for the Dead / Xenocide / Children of the
Mind Ender’s Shadow series Ender’s Shadow / Shadow of the Hegemon / Shadow
Puppets / Shadow of the Giant / Shadows in Flight Children of the Fleet The
First Formic War (with Aaron Johnston) Earth Unaware / Earth Afire / Earth
Awakens The Second Formic War (with Aaron Johnston) The Swarm /The Hive
Ender novellas A War of Gifts /First Meetings"
70,71,18490,"Mary Wollstonecraft Shelley, Percy Bysshe Shelley, Maurice Hindle","Frankenstein; or, The Modern Prometheus",https://images.gr-assets.com/books/1381512375l/18490.jpg,3.75,808589,"classics, fiction",Edited by Maurice Hindle.
71,72,11588,Stephen King,The Shining,https://images.gr-assets.com/books/1353277730l/11588.jpg,4.17,791850,"fiction, fantasy","Jack Torrance sees his stint as winter caretaker of a Colorado hotel as a
way back from failure, his wife sees it as a chance to preserve their
family, and their five-year-old son sees the evil waiting just for them."
72,73,1656001,Stephenie Meyer,The Host,https://images.gr-assets.com/books/1318009171l/1656001.jpg,3.84,749780,"fiction, paranormal","A member of a species that takes over the minds of human bodies, Wanderer
is unable to disregard his host's love for a man in hiding, a situation
that forces both possessor and host to become unwilling allies. A first
adult novel by the author of Eclipse."
73,74,99561,John Green,Looking for Alaska,https://images.gr-assets.com/books/1394798630l/99561.jpg,4.09,783470,"fiction, contemporary","Sixteen-year-old Miles' first year at Culver Creek Preparatory School in
Alabama includes good friends and great pranks, but is defined by the
search for answers about life and death after a fatal car crash. An ALA
Best Book for Young Adults & ALA Quick Pick. Reprint."
74,76,14935,"Jane Austen, Tony Tanner, Ros Ballaster",Sense and Sensibility,https://images.gr-assets.com/books/1397245675l/14935.jpg,4.06,738894,"fiction, ebooks","Sisters Elinor and Marianne Dashwood set their sights on men to perfectly
match their disparate personalities, with unexpected results."
75,77,38709,"Louis Sachar, Louis Sachar",Holes,https://images.gr-assets.com/books/1327781893l/38709.jpg,3.93,747445,"fiction, mystery","HolesLouis Sachar, Louis Sachar"
76,78,5139,Lauren Weisberger,The Devil Wears Prada,https://i.gr-assets.com/images/S/compressed.photo.goodreads.com/books/1388179604l/5139.jpg,3.7,665930,"fiction, contemporary","A small-town girl fresh out of an Ivy League college lands a job at a
prestigious fashion magazine, but wonders if the glamorous perks are worth
working for the editor from hell."
77,79,1381,"Homer, Robert Fagles, E.V. Rieu, Frédéric Mugler, Bernard Knox",Ὀδύσσεια,https://images.gr-assets.com/books/1390173285l/1381.jpg,3.73,670326,"classics, fiction","A new translation of the epic poem retells the story of Odysseus's ten-year
voyage home to Ithaca after the Trojan War."
78,80,157993,"Antoine de Saint-Exupéry, Richard Howard, Dom Marcos Barbosa, Melina Karakosta",Le Petit Prince,https://images.gr-assets.com/books/1367545443l/157993.jpg,4.28,738757,"fantasy, philosophy","An aviator whose plane is forced down in the Sahara Desert encounters a
little prince from a small planet who relates his adventures in seeking the
secret of what is important in life. Howard's new translation of this
beloved classic beautifully reflects Saint-Exupery's unique, gifted style.
Color and b&w illustrations."
79,81,7445,Jeannette Walls,The Glass Castle,https://images.gr-assets.com/books/1400930557l/7445.jpg,4.24,621099,"memoir, nonfiction","Now a major motion picture from Lionsgate starring Brie Larson, Woody
Harrelson, and Naomi Watts. MORE THAN SEVEN YEARS ON THE NEW YORK TIMES
BESTSELLER LIST The perennially bestselling, extraordinary, one-of-a-kind,
“nothing short of spectacular” (Entertainment Weekly) memoir from one of
the world’s most gifted storytellers. The Glass Castle is a remarkable
memoir of resilience and redemption, and a revelatory look into a family at
once deeply dysfunctional and uniquely vibrant. When sober, Jeannette’s
brilliant and charismatic father captured his children’s imagination,
teaching them physics, geology, and how to embrace life fearlessly. But
when he drank, he was dishonest and destructive. Her mother was a free
spirit who abhorred the idea of domesticity and didn’t want the
responsibility of raising a family. The Walls children learned to take care
of themselves. They fed, clothed, and protected one another, and eventually
found their way to New York. Their parents followed them, choosing to be
homeless even as their children prospered. The Glass Castle is truly
astonishing—a memoir permeated by the intense love of a peculiar but loyal
family."
80,82,1845,Jon Krakauer,Into the Wild,https://images.gr-assets.com/books/1403173986l/1845.jpg,3.94,647684,"nonfiction, biography","In April 1992, a young man from a well-to-do family hitchhikes to Alaska
and walks alone into the wilderness north of Mt. McKinley. Four months
later, his decomposed body is found by a moose hunter. How Chris McCandless
came to die is the unforgettable story of Into the Wild."
81,83,1953,"Charles Dickens, Richard Maxwell, Hablot Knight Browne",A Tale of Two Cities,https://images.gr-assets.com/books/1344922523l/1953.jpg,3.81,637412,"classics, fiction",Edited with an Introduction and Notes by Richard Maxwell.
82,84,7677,Michael Crichton,Jurassic Park,https://i.gr-assets.com/images/S/compressed.photo.goodreads.com/books/1348796998l/7677.jpg,3.96,447833,"fiction, thriller","An American bioengineering research firm erects a theme park on a Caribbean
island, complete with living dinosaurs, and invites a group of scientists
to be its first terrified guests."
83,85,370493,Shel Silverstein,The Giving Tree,https://images.gr-assets.com/books/1174210942l/370493.jpg,4.38,702332,"classics, fiction","""Once there was a tree ... and she loved a little boy."" So begins a story
of unforgettable perception, beautifully written and illustrated by the
gifted and versatile Shel Silverstein. Every day the boy would come to the
tree to eat her apples, swing from her branches, or slide down her trunk
... and the tree was happy. But as the boy grew older he began to want more
from the tree, and the tree gave and gave and gave. This is a tender story,
touched with sadness, aglow with consolation. Shel Silverstein has created
a moving parable for readers of all ages that offers an affecting
interpretation of the gift of giving and a serene acceptance of another's
capacity to love in return. This miniature full-cloth, gold-stamped edition
will be treasured by all ages."
84,86,32542,John Grisham,A Time to Kill,https://i.gr-assets.com/images/S/compressed.photo.goodreads.com/books/1554303029l/32542.jpg,4.03,597775,"fiction, mystery","A Southern town is shocked when a 10-year-old black girl is raped by two
white men--until the girl's father takes the law into his own hands."
85,87,1617,"Elie Wiesel, Marion Wiesel",Un di Velt Hot Geshvign,https://images.gr-assets.com/books/1473495285l/1617.jpg,4.3,691231,"classics, history","The narrative of a boy who lived through Auschwitz and Buchenwald provides
a short and terrible indictment of modern humanity."
86,88,6442769,John Green,Paper Towns,https://images.gr-assets.com/books/1349013610l/6442769.jpg,3.88,461311,"contemporary, fiction","One month before graduating from his Central Florida high school, Quentin
""Q"" Jacobsen basks in the predictable boringness of his life until the
beautiful and exciting Margo Roth Spiegelman, Q's neighbor and classmate,
takes him on a midnight adventure and then mysteriously disappears. An ALA
Best Book for Young Adults. Reprint."
87,89,21787,William Goldman,The Princess Bride,https://images.gr-assets.com/books/1327903636l/21787.jpg,4.25,628637,"ebooks, contemporary","A classic swashbuckling romance retells the tale of a drunken swordsman and
a gentle giant who come to the aid of Westley, a handsome farm boy, and
Buttercup, a princess in dire need of rescue from the evil schemers
surrounding her. Reader's Guide available. Simultaneous."
88,90,231804,S.E. Hinton,The Outsiders,https://images.gr-assets.com/books/1442129426l/231804.jpg,4.06,659248,"fiction, classics","The struggle of three brothers to stay together after their parent's death
and their quest for identity among the conflicting values of their
adolescent society."
89,91,6186357,James Dashner,The Maze Runner,https://images.gr-assets.com/books/1375596592l/6186357.jpg,4.02,719925,"fiction, fantasy","Sixteen-year-old Thomas wakes up with no memory in the middle of a maze and
realizes he must work with the community in which he finds himself if he is
to escape."
90,92,1202,"Steven D. Levitt, Stephen J. Dubner",Freakonomics: A Rogue Economist Explores the Hidden Side of Everything,https://images.gr-assets.com/books/1327909092l/1202.jpg,3.93,524191,"nonfiction, science","Which is more dangerous, a gun or a swimming pool? What do schoolteachers
and sumo wrestlers have in common? How much do parents really matter? These
may not sound like typical questions for an economist to ask. But Steven D.
Levitt is not a typical economist. He studies the riddles of everyday
life—from cheating and crime to parenting and sports—and reaches
conclusions that turn conventional wisdom on its head. Freakonomics is a
groundbreaking collaboration between Levitt and Stephen J. Dubner, an
award-winning author and journalist. They set out to explore the inner
workings of a crack gang, the truth about real estate agents, the secrets
of the Ku Klux Klan, and much more. Through forceful storytelling and wry
insight, they show that economics is, at root, the study of incentives—how
people get what they want or need, especially when other people want or
need the same thing."
91,93,2998,Frances Hodgson Burnett,The Secret Garden,https://images.gr-assets.com/books/1327873635l/2998.jpg,4.12,639357,"classics, fiction","A ten-year-old orphan comes to live in a lonely house on the Yorkshire
moors where she discovers an invalid cousin and the mysteries of a locked
garden."
92,94,320,"Gabriel García Márquez, Gregory Rabassa",Cien años de soledad,https://images.gr-assets.com/books/1327881361l/320.jpg,4.04,490565,"classics, fiction","Cien años de soledadGabriel García Márquez, Gregory Rabassa"
93,95,5297,"Oscar Wilde, Jeffrey Eugenides",The Picture of Dorian Gray,https://images.gr-assets.com/books/1424596966l/5297.jpg,4.06,590014,"classics, fiction","The handsome appearance of dissolute young Dorian Gray remains unchanged
while the features in his portrait become distorted as his degeneration
progresses"
94,96,13536860,E.L. James,Fifty Shades Freed,https://images.gr-assets.com/books/1336418837l/13536860.jpg,3.88,387290,"fiction, contemporary","Even though Christian and Anastasia are now a proper couple, they still
have many obstacles to overcome, including Christian's past coming back to
haunt Anastasia."
95,97,17245,"Bram Stoker, Nina Auerbach, David J. Skal",Dracula,https://images.gr-assets.com/books/1387151694l/17245.jpg,3.98,618973,"classics, horror","This Norton Critical Edition presents fully annotated the text of the 1897
First Edition."
96,98,5060378,"Stieg Larsson, Reg Keeland",Flickan som lekte med elden,https://images.gr-assets.com/books/1351778881l/5060378.jpg,4.22,563994,"fiction, mystery","Flickan som lekte med eldenStieg Larsson, Reg Keeland"
97,99,11857408,E.L. James,Fifty Shades Darker,https://images.gr-assets.com/books/1358266080l/11857408.jpg,3.87,552059,"romance, fiction","Fifty Shades Darker is a 2012 erotic romance novel by British author E. L.
James. It is the second installment in the Fifty Shades trilogy that traces
the deepening relationship between a college graduate, Anastasia Steele,
and a young business magnate, Christian Grey. The first and third volumes,
Fifty Shades of Grey and Fifty Shades Freed, were published in 2011 and
2012. The novel is published by Vintage Books and reached #1 on the USA
Today best seller list."
98,100,7244,Barbara Kingsolver,The Poisonwood Bible,https://images.gr-assets.com/books/1412242487l/7244.jpg,4.02,546502,"fiction, classics","The Poisonwood Bible is a story told by the wife and four daughters of
Nathan Price, a fierce, evangelical Baptist who takes his family and
mission to the Belgian Congo in 1959. They carry with them everything they
believe they will need from home, but soon find that all of it -- from
garden seeds to Scripture -- is calamitously transformed on African soil.
What follows is a suspenseful epic of one family's tragic undoing and
remarkable reconstruction over the course of three decades in postcolonial
Africa. This P.S. edition features an extra 16 pages of insights into the
book, including author interviews, recommended reading, and more."
99,101,4137,David Sedaris,Me Talk Pretty One Day,https://i.gr-assets.com/images/S/compressed.photo.goodreads.com/books/1431013639l/4137.jpg,3.97,495736,"memoir, nonfiction","A recent transplant to Paris, humorist David Sedaris, bestselling author of
""Naked"", presents a collection of his strongest work yet, including the
title story about his hilarious attempt to learn French. A number one
national bestseller now in paperback."
100,102,19543,Maurice Sendak,Where the Wild Things Are,https://images.gr-assets.com/books/1384434560l/19543.jpg,4.22,620618,"fiction, classics","Max is sent to bed without supper and imagines sailing away to the land of
Wild Things,where he is made king."
101,103,7126,"Alexandre Dumas, Robin Buss",Le Comte de Monte-Cristo,https://images.gr-assets.com/books/1309203605l/7126.jpg,4.21,555822,"classics, fiction",Translated with an Introduction by Robin Buss
102,104,6288,Cormac McCarthy,The Road,https://images.gr-assets.com/books/1439197219l/6288.jpg,3.95,504793,"fiction, horror","In a novel set in an indefinite, futuristic, post-apocalyptic world, a
father and his young son make their way through the ruins of a devastated
American landscape, struggling to survive and preserve the last remnants of
their own humanity."
103,105,18710190,Veronica Roth,Allegiant,https://images.gr-assets.com/books/1395582745l/18710190.jpg,3.63,463257,"fiction, fantasy","The explosive conclusion to Veronica Roth's #1 New York Times bestselling
Divergent trilogy reveals the secrets of the dystopian world that
captivated millions of readers and film fans in Divergent and Insurgent.
This paperback edition includes bonus content by Veronica Roth! One choice
will define you. What if your whole world was a lie? What if a single
revelation—like a single choice—changed everything? What if love and
loyalty made you do things you never expected? Told from a riveting dual
perspective, this third installment in the series follows Tris and Tobias
as they battle to comprehend the complexities of human nature—and their
selves—while facing impossible choices of courage, allegiance, sacrifice,
and love."
104,106,9418327,Tina Fey,Bossypants,https://images.gr-assets.com/books/1481509554l/9418327.jpg,3.94,506250,"memoir, nonfiction",BossypantsTina Fey
105,107,3473,Nicholas Sparks,A Walk to Remember,https://images.gr-assets.com/books/1385738968l/3473.jpg,4.15,546948,"romance, fiction","A high school rebel and a minister's daughter find strength in each other
in this star-crossed tale of ""young but everlasting love"" (Chicago Sun-
Times). There was a time when the world was sweeter....when the women in
Beaufort, North Carolina, wore dresses, and the men donned hats.... Every
April, when the wind smells of both the sea and lilacs, Landon Carter
remembers 1958, his last year at Beaufort High. Landon had dated a girl or
two, and even once sworn that he'd been in love. Certainly the last person
he thought he'd fall for was Jamie, the shy, almost ethereal daughter of
the town's Baptist minister....Jamie, who was destined to show him the
depths of the human heart-and the joy and pain of living. The inspiration
for this novel came from Nicholas Sparks's sister: her life and her
courage. From the internationally bestselling author Nicholas Sparks, comes
his most moving story yet...."
106,108,9416,Sophie Kinsella,Confessions of a Shopaholic,https://images.gr-assets.com/books/1327872404l/9416.jpg,3.61,543658,"fiction, romance","Financial journalist Rebecca Bloomwood seeks solace from the boredom and
pressures in life with her shopping, a solution that brings her close to
financial disaster, until she encounters a story that will change her life."
107,109,24280,"Victor Hugo, Lee Fahnestock, Norman MacAfee",Les Misérables,https://images.gr-assets.com/books/1411852091l/24280.jpg,4.14,513407,"classics, fiction","Les MisérablesVictor Hugo, Lee Fahnestock, Norman MacAfee"
108,110,10572,George R.R. Martin,A Clash of Kings,https://images.gr-assets.com/books/1358254974l/10572.jpg,4.4,523303,"fantasy, fiction","Six separate factions vie for control of the realm of the late Lord Eddard
Stark, while an ancient form of magic, an everlasting winter, and an
unearthly army threaten to return."
109,111,10441,Kim Edwards,The Memory Keeper's Daughter,https://i.gr-assets.com/images/S/compressed.photo.goodreads.com/books/1552112312l/10441._SY475_.jpg,3.64,501430,"fiction, contemporary","In a tale spanning twenty-five years, a doctor delivers his newborn twin
daughter during a snowstorm and, rashly deciding to protect his wife from
the baby's affliction with Down Syndrome, turns her over to a nurse, who
secretly raises the child. A first novel. Reader's Guide included. Reprint.
100,000 first printing."
110,112,15507958,Jojo Moyes,Me Before You,https://images.gr-assets.com/books/1357108762l/15507958.jpg,4.27,587647,"romance, fiction","Taking a job as an assistant to extreme sports enthusiast Will, who is
wheelchair bound after a motorcycle accident, Louisa struggles with her
employer's acerbic moods and learns of his shocking plans before
demonstrating to him that life is still worth living."
111,113,168668,Joseph Heller,Catch-22,https://images.gr-assets.com/books/1463157317l/168668.jpg,3.98,563265,"classics, fiction",Catch-22Joseph Heller
112,114,6900,"Mitch Albom, Saulius Dagys",Tuesdays with Morrie,https://images.gr-assets.com/books/1423763749l/6900.jpg,4.06,556518,"fiction, nonfiction","When an eighty-two-year-old rabbi from Albom's old hometown asks him to
deliver his eulogy, Albom goes back to his nonfiction roots and becomes
involved with a Detroit pastor--a reformed drug dealer and convict--who
preaches to the poor and homeless in a decaying church with a hole in its
roof. A timely, moving, and inspiring look at faith: not just who believes,
but why."
113,115,2187,Jeffrey Eugenides,Middlesex,https://images.gr-assets.com/books/1437029776l/2187.jpg,3.98,488243,"fiction, contemporary",MiddlesexJeffrey Eugenides
114,116,24583,"Mark Twain, Guy Cardwell, John Seelye",The Adventures of Tom Sawyer,https://images.gr-assets.com/books/1404811979l/24583.jpg,3.89,555359,"classics, fiction","The classic adventure story of boyhood escapades on the shores of the
Mississippi chronicles the exploits of the mischievous Tom Sawyer and his
friends. Reissue."
115,117,18131,Madeleine L'Engle,A Wrinkle in Time,https://images.gr-assets.com/books/1329061522l/18131.jpg,4.04,615907,"fantasy, fiction","A midnight visitor escorts Meg, Calvin, and Charles across the barriers of
space and time to another world."
116,118,7763,Amy Tan,The Joy Luck Club,https://images.gr-assets.com/books/1304978653l/7763.jpg,3.9,515090,"classics, fiction","Encompassing two generations and a rich blend of Chinese and American
history, the story of four struggling, strong women also reveals their
daughter's memories and feelings."
117,119,38447,Margaret Atwood,The Handmaid's Tale,https://images.gr-assets.com/books/1498057733l/38447.jpg,4.06,607889,"fiction, classics",The Handmaid's TaleMargaret Atwood
118,120,452306,Ann Brashares,The Sisterhood of the Traveling Pants,https://images.gr-assets.com/books/1461611233l/452306.jpg,3.75,525706,"fiction, contemporary","During their first summer apart, four teenage girls, best friends since
earliest childhood, stay in touch through a shared pair of secondhand jeans
that magically adapts to each of their figures and affects their attitudes
to their different summer experiences."
119,121,7604,"Vladimir Nabokov, Craig Raine",Lolita,https://images.gr-assets.com/books/1377756377l/7604.jpg,3.88,469836,"fiction, classics","In this Readers' Guide, Christine Clegg examines the critical history of
""Lolita"" through a broad range of interpretations. Although early criticism
of the text polarized around 'that' question - is it literature or
pornography? - the influence of American critics such as Lionel Trilling
quickly secured canonical status for the novel. A compelling aspect of
""Lolita"" criticism is the way in which that question continues to return in
different forms. In the 1980s and 1990s, ""Lolita"" has been the subject of
diverse critical attention, beyond 'Nabokov Studies': from Richard Rorty's
philosophical inquiry into the ethics of cruelty, to Rachel Bowlby's
feminist analysis of the rhetoric of consumer culture in the novel. All of
the main critical approaches to the novel are covered by this indispensable
sourcebook."
120,122,37442,"Gregory Maguire, Douglas Smith",Wicked: The Life and Times of the Wicked Witch of the West,https://images.gr-assets.com/books/1437733293l/37442.jpg,3.52,506900,"fantasy, classics","Following the traditions of Gabriel GarcÍa Marquez, John Gardner and J.R.R.
Tolkien, Wicked is a richly woven tale that takes us to the other, darker
side of the rainbow as novelist Gregory Maguire chronicles the Wicked Witch
of the West's odyssey through the complex world of Oz -- where people call
you wicked if you tell the truth. Years before Dorothy and her dog crash-
land, another little girl makes her presence known in Oz. This girl,
Elphaba, is born with emerald-green skin -- no easy burden in a land as
mean and poor as Oz, where superstition and magic are not strong enough to
explain or to overcome the natural disasters of flood and famine. But
Elphaba is smart, and by the time she enters the university in Shiz, she
becomes a member of a charmed circle of Oz' most promising young citizens.
Elphaba's Oz is no utopia. The Wizard's secret police are everywhere.
Animals -- those creatures with voices, souls and minds -- are threatened
with exile. Young Elphaba, green and wild and misunderstood, is determined
to protect the Animals -- even it means combating the mysterious Wizard,
even if it means risking her single chance at romance. Even wiser in guilt
and sorrow, she can find herself grateful when the world declares her a
witch. And she can even make herself glad for that young girl from Kansas.
In Wicked, Gregory Maguire has taken the largely unknown world of Oz and
populated it with the power of his own imagination. Fast-paced,
fantastically real and supremely entertaining, this is a novel of vision
and re-vision. Oz never will be the same again."
121,123,5358,John Grisham,The Firm,https://images.gr-assets.com/books/1418465200l/5358.jpg,3.99,488269,"fiction, thriller","Originally published: [New York]: Doubleday, 1991."
122,124,7937843,Emma Donoghue,Room,https://images.gr-assets.com/books/1344265419l/7937843.jpg,4.03,511360,"fiction, contemporary","Held captive for years in a small shed, a woman and her precocious young
son finally gain their freedom, and the boy experiences the outside world
for the first time. Inspiration for the MAJOR MOTION PICTURE starring
Academy Award winner Brie Larson To five-year-old-Jack, Room is the world.
. . . It's where he was born, it's where he and his Ma eat and sleep and
play and learn. At night, his Ma shuts him safely in the wardrobe, where he
is meant to be asleep when Old Nick visits. Room is home to Jack, but to Ma
it's the prison where she has been held for seven years. Through her fierce
love for her son, she has created a life for him in this eleven-by-eleven-
foot space. But with Jack's curiosity building alongside her own
desperation, she knows that Room cannot contain either much longer. Room is
a tale at once shocking, riveting, exhilarating--a story of unconquerable
love in harrowing circumstances, and of the diamond-hard bond between a
mother and her child."
123,125,1420,"William Shakespeare, Richard Andrews, Rex Gibson","The Tragicall Historie of Hamlet, Prince of Denmark",https://images.gr-assets.com/books/1351051208l/1420.jpg,4,515820,"classics, fiction","The Tragicall Historie of Hamlet, Prince of DenmarkWilliam Shakespeare, Richard Andrews, Rex Gibson"
124,126,234225,Frank Herbert,Dune,https://images.gr-assets.com/books/1434908555l/234225.jpg,4.19,485032,"fiction, fantasy","Opposing forces struggle for control of the universe when the archenemy of
the cosmic emperor is banished to a barren world where savages fight for
water"
125,127,2612,Malcolm Gladwell,The Tipping Point: How Little Things Can Make a Big Difference,https://images.gr-assets.com/books/1473396980l/2612.jpg,3.92,490504,"nonfiction, business",The Tipping Point: How Little Things Can Make a Big DifferenceMalcolm Gladwell
126,128,11084145,Walter Isaacson,Steve Jobs,https://images.gr-assets.com/books/1327861368l/11084145.jpg,4.09,560715,"biography, business","Draws on more than forty interviews with Steve Jobs, as well as interviews
with family members, friends, competitors, and colleagues to offer a look
at the co-founder and leading creative force behind the Apple computer
company."
127,129,332613,Ken Kesey,One Flew Over the Cuckoo's Nest,https://images.gr-assets.com/books/1485308778l/332613.jpg,4.18,491642,"classics, fiction","McMurphy, a criminal who feigns insanity, is admitted to a mental hospital
where he challenges the autocratic authority of the head nurse."
128,130,2165,Ernest Hemingway,The Old Man and the Sea,https://images.gr-assets.com/books/1329189714l/2165.jpg,3.73,520630,"classics, fiction","Told in language of great simplicity and power, this story of courage and
personal triumph remains one of Ernest Hemingway’s most enduring works. The
Old Man and the Sea is one of Hemingway’s most enduring works. Told in
language of great simplicity and power, it is the story of an old Cuban
fisherman, down on his luck, and his supreme ordeal—a relentless, agonizing
battle with a giant marlin far out in the Gulf Stream. Here Hemingway
recasts, in strikingly contemporary style, the classic theme of courage in
the face of defeat, of personal triumph won from loss. Written in 1952,
this hugely successful novella confirmed his power and presence in the
literary world and played a large part in his winning the 1954 Nobel Prize
for Literature."
129,131,4395,John Steinbeck,The Grapes of Wrath,https://images.gr-assets.com/books/1352912927l/4395.jpg,3.92,322321,"classics, fiction",STEINBECK/GRAPES OF WRATH (BC)
130,132,3431,Mitch Albom,The Five People You Meet in Heaven,https://i.gr-assets.com/images/S/compressed.photo.goodreads.com/books/1388200541l/3431.jpg,3.9,449501,"fiction, christian","A specially produced paperback edition -- with flaps -- of the phenomenal
#1 New York Times bestseller, that has sold more than six million copies in
hardcover Eddie is a grizzled war veteran who feels trapped in a
meaningless life of fixing rides at a seaside amusement park. His days are
a dull routine of work, loneliness, and regret. Then, on his 83rd birthday,
Eddie dies in a tragic accident, trying to save a little girl from a
falling cart. He awakens in the afterlife, where he learns that heaven is
not a lush Garden of Eden, but a place where your earthly life is explained
to you by five people. These people may have been loved ones or distant
strangers. Yet each of them changed your path forever. One by one, Eddie's
five people illuminate the unseen connections of his earthly life. As the
story builds to its stunning conclusion, Eddie desperately seeks redemption
in the still-unknown last act of his life: Was it a heroic success or a
devastating failure The answer, which comes from the most unlikely of
sources, is as inspirational as a glimpse of heaven itself. In The Five
People You Meet in Heaven, Mitch Albom gives us an astoundingly original
story that will change everything you've ever thought about the afterlife
-- and the meaning of our lives here on earth. With a timeless tale,
appealing to all, this is a book that readers of fine fiction, and those
who loved Tuesdays with Morrie, will treasure."
131,133,8127,L.M. Montgomery,Anne of Green Gables,https://i.gr-assets.com/images/S/compressed.photo.goodreads.com/books/1390789015l/8127.jpg,4.23,502247,"fiction, romance","Anne, an eleven-year-old orphan, is sent by mistake to live with a lonely,
middle-aged brother and sister on a Prince Edward Island farm and proceeds
to make an indelible impression on everyone around her."
132,134,3777732,Cassandra Clare,City of Glass,https://images.gr-assets.com/books/1369452339l/3777732.jpg,4.34,593173,"fantasy, paranormal","Still pursuing a cure for her mother's enchantment, Clary uses all her
powers and ingenuity to get into Idris, the forbidden country of the
secretive Shadowhunters, and to its capital, the City of Glass, where with
the help of a newfound friend, Sebastian, she uncovers important truths
about her family's past that will not only help save her mother but all
those that she holds most dear."
133,135,62291,George R.R. Martin,A Storm of Swords,https://images.gr-assets.com/books/1497931121l/62291.jpg,4.54,469022,"fantasy, fiction","The three surviving contenders for the throne of the Seven Kingdoms
continue to struggle among themselves, Robb defends his kingdom from the
Greyjoys, Jon confronts an escalating threat, and Daenerys and her dragon
allies continue to grow in power."
134,136,137791,Rebecca Wells,Divine Secrets of the Ya-Ya Sisterhood,https://images.gr-assets.com/books/1408313524l/137791.jpg,3.79,465676,"fiction, contemporary",Divine Secrets of the Ya-Ya SisterhoodRebecca Wells
135,137,10964,Diana Gabaldon,Outlander,https://images.gr-assets.com/books/1402600310l/10964.jpg,4.2,515547,"romance, fantasy","Claire Randall is leading a double life. She has a husband in one century,
and a lover in another... In 1945, Claire Randall, a former combat nurse,
is back from the war and reunited with her husband on a second honeymoon--
when she innocently touches a boulder in one of the ancient stone circles
that dot the British Isles. Suddenly she is a Sassenach—an ""outlander""—in a
Scotland torn by war and raiding border clans in the year of our
Lord...1743. Hurled back in time by forces she cannot understand, Claire's
destiny in soon inextricably intertwined with Clan MacKenzie and the
forbidden Castle Leoch. She is catapulted without warning into the
intrigues of lairds and spies that may threaten her life ...and shatter her
heart. For here, James Fraser, a gallant young Scots warrior, shows her a
passion so fierce and a love so absolute that Claire becomes a woman torn
between fidelity and desire...and between two vastly different men in two
irreconcilable lives."
136,138,12296,"Nathaniel Hawthorne, Thomas E. Connolly, Nina Baym",The Scarlet Letter,https://images.gr-assets.com/books/1404810944l/12296.jpg,3.37,509883,"romance, history","A young woman, publicly scorned for bearing an illegitimate child, refuses
to be vanquished by the seventeenth-century Boston community."
137,139,9460487,Ransom Riggs,Miss Peregrine’s Home for Peculiar Children,https://images.gr-assets.com/books/1472782916l/9460487.jpg,3.89,613674,"fantasy, fiction","After a family tragedy, Jacob feels compelled to explore an abandoned
orphanage on an island off the coast of Wales, discovering disturbing facts
about the children who were kept there."
138,140,6892870,"Stieg Larsson, Reg Keeland",Luftslottet som sprängdes,https://images.gr-assets.com/books/1327708260l/6892870.jpg,4.2,443951,"fiction, mystery","While recovering in the hospital, Lisbeth Salander enlists the aid of
journalist Mikael Blomkvist to prove her innocent of three murders and
identify the corrupt politicians who have allowed her to suffer, and, on
her own, Lisbeth plots revenge against the man who tried to kill her. By
the best-selling author of The Girl Who Played With Fire."
139,141,18007564,Andy Weir,The Martian,https://images.gr-assets.com/books/1413706054l/18007564.jpg,4.39,423344,"science, thriller","Stranded on Mars by a dust storm that compromised his space suit and forced
his crew to leave him behind, astronaut Watney struggles to survive in
spite of minimal supplies and harsh environmental challenges that test his
ingenuity in unique ways. A first novel."
140,142,5043,Ken Follett,The Pillars of the Earth,https://i.gr-assets.com/images/S/compressed.photo.goodreads.com/books/1576956100l/5043.jpg,4.29,462517,"fiction, history","Set in twelfth-century England, this epic of kings and peasants juxtaposes
the building of a magnificent church with the violence and treachery that
often characterized the Middle Ages. Reissue."
141,144,8664353,Laura Hillenbrand,"Unbroken: A World War II Story of Survival, Resilience, and Redemption",https://images.gr-assets.com/books/1327861115l/8664353.jpg,4.4,487775,"history, biography","Relates the story of a U.S. airman who survived when his bomber crashed
into the sea during World War II, spent forty-seven days adrift in the
ocean before being rescued by the Japanese Navy, and was held as a prisoner
until the end of the war."
142,145,976,Dan Brown,Deception Point,https://i.gr-assets.com/images/S/compressed.photo.goodreads.com/books/1551277487l/976._SY475_.jpg,3.67,455610,"fiction, thriller","On the eve of a presidential race in which NASA's budget is a pivotal
issue, the space agency announces the discovery of an ancient meteorite
filled with fossils deep in the Arctic ice."
143,146,17333223,Donna Tartt,The Goldfinch,https://images.gr-assets.com/books/1451554970l/17333223.jpg,3.87,396756,"fiction, contemporary",The GoldfinchDonna Tartt
144,147,1217100,Jay Asher,Thirteen Reasons Why,https://images.gr-assets.com/books/1333822506l/1217100.jpg,4.02,463783,"romance, contemporary","""Now a Netflix original series-- photos and exclusive interviews inside""--
Cover."
145,148,2865,Tracy Chevalier,Girl with a Pearl Earring,https://images.gr-assets.com/books/1327197580l/2865.jpg,3.85,467577,"fiction, art","A poor seventeenth-century servant girl knows her place in the household of
the painter Johannes Vermeer, but when he begins to paint her, nasty
whispers and rumors circulate throughout the town. Reprint."
146,149,4374400,Gayle Forman,If I Stay,https://images.gr-assets.com/books/1347462970l/4374400.jpg,3.96,503527,"romance, contemporary","With no memory of the car accident itself, 17-year-old Mia must come to
terms with never really knowing what happened one horrific winter's day
that changed her life forever. Reprint."
147,150,4989,Anita Diamant,The Red Tent,https://i.gr-assets.com/images/S/compressed.photo.goodreads.com/books/1405739117l/4989.jpg,4.16,424981,"history, fiction",The Red TentAnita Diamant
148,151,28186,Rick Riordan,The Sea of Monsters,https://images.gr-assets.com/books/1400602661l/28186.jpg,4.23,514932,"fantasy, fiction","When Camp Half-Blood, the only safe haven for demigods, comes close to
being overrun by mythological monsters, Percy must find his best friend
Grover, who is prisoner on an island in the Bermuda Triangle, and then set
out to save the Camp."
149,152,5526,Nicholas Sparks,Dear John,https://images.gr-assets.com/books/1397749854l/5526.jpg,4.01,441062,"romance, fiction","John, a rebel who dropped out of school to enlist in the army, meets
Savannah, the girl of his dreams, but the events of September 11, 2001,
John's decision to re-enlist, and Savannah's marriage to another man
threaten their love."
150,153,1582996,Cassandra Clare,City of Ashes,https://images.gr-assets.com/books/1432730356l/1582996.jpg,4.21,541117,"fantasy, paranormal","Sixteen-year-old Clary continues trying to make sense of the swiftly
changing events and relationships in her life as she becomes further
involved with the Shadowhunters and their pursuit of demons and discovers
some terrifying truths about her parents, her brother Jace, and her
boyfriend Simon."
151,154,8852,William Shakespeare,The Tragedy of Macbeth,https://images.gr-assets.com/books/1459795224l/8852.jpg,3.88,496018,"fiction, poetry",The Tragedy of MacbethWilliam Shakespeare
152,155,15241,J.R.R. Tolkien,The Two Towers,https://images.gr-assets.com/books/1298415523l/15241.jpg,4.42,480446,"fantasy, classics","The second volume in J.R.R. Tolkien's epic adventure The Lord of the Rings
One Ring to rule them all, One Ring to find them, One Ring to bring them
all and in the darkness bind them Frodo and his Companions of the Ring have
been beset by danger during their quest to prevent the Ruling Ring from
falling into the hands of the Dark Lord by destroying it in the Cracks of
Doom. They have lost the wizard, Gandalf, in a battle in the Mines of
Moria. And Boromir, seduced by the power of the Ring, tried to seize it by
force. While Frodo and Sam made their escape, the rest of the company was
attacked by Orcs. Now they continue the journey alone down the great River
Anduin-alone, that is, save for the mysterious creeping figure that follows
wherever they go."
153,156,42156,Emily Giffin,Something Borrowed,https://images.gr-assets.com/books/1305063535l/42156.jpg,3.83,403601,"romance, fiction","After a night of indiscriminate partying, Rachel sleeps with a close
friend's fianc and is consumed with guilt, until the intensity of her
feelings forces her to make a difficult choice. A first novel. Reprint.
125,000 first printing."
154,157,23772,"Dr. Seuss, לאה נאור",Green Eggs and Ham,https://images.gr-assets.com/books/1468680100l/23772.jpg,4.29,457475,"classics, fiction","Green Eggs and HamDr. Seuss, לאה נאור"
155,158,6310,"Roald Dahl, Quentin Blake",Charlie and the Chocolate Factory,https://images.gr-assets.com/books/1309211401l/6310.jpg,4.1,453959,"fiction, classics","Each of five children lucky enough to discover an entry ticket into Mr.
Willy Wonka's mysterious chocolate factory takes advantage of the situation
in his own way."
156,159,2120932,Rick Riordan,The Battle of the Labyrinth,https://images.gr-assets.com/books/1443142158l/2120932.jpg,4.39,508214,"fantasy, fiction",The Battle of the LabyrinthRick Riordan
157,160,2623,Charles Dickens,Great Expectations,https://images.gr-assets.com/books/1327920219l/2623.jpg,3.75,459247,"classics, fiction",Great ExpectationsCharles Dickens
158,161,18512,J.R.R. Tolkien,The Return of the King,https://images.gr-assets.com/books/1389977161l/18512.jpg,4.51,463959,"fantasy, fiction",An adult fairy tale which takes place in the third age of middle- earth.
159,162,49552,"Albert Camus, Matthew    Ward",L’Étranger,https://images.gr-assets.com/books/1349927872l/49552.jpg,3.96,420600,"classics, fiction",An ordinary man is unwittingly caught up in a senseless murder in Algeria
160,163,7736182,Rick Riordan,The Lost Hero,https://images.gr-assets.com/books/1464201003l/7736182.jpg,4.35,271576,"fantasy, fiction",The Lost HeroRick Riordan
161,164,15745753,Rainbow Rowell,Eleanor & Park,https://images.gr-assets.com/books/1341952742l/15745753.jpg,4.11,514312,"romance, contemporary","""Set over the course of one school year in 1986, this is the story of two
star-crossed misfits--smart enough to know that first love almost never
lasts, but brave and desperate enough to try""--"
162,165,13497,George R.R. Martin,A Feast for Crows,https://images.gr-assets.com/books/1429538615l/13497.jpg,4.1,428186,"fantasy, fiction","The uneasy peace that exists following the death of Robb Stark is
threatened by new plots, intrigues, and alliances that once again will
plunge the Seven Kingdoms into all-out war for control of the Iron Throne."
163,166,7735333,Ally Condie,Matched,https://images.gr-assets.com/books/1367706191l/7735333.jpg,3.68,511815,"romance, fiction","Cassia has always trusted the Society to make the right choices for her. So
when Xander's face appears on-screen at her Matching ceremony, Cassia knows
he is her ideal mate . . . until she sees Ky Markham's face flash for an
instant before the screen fades to black."
164,167,4407,Neil Gaiman,American Gods,https://images.gr-assets.com/books/1258417001l/4407.jpg,4.11,378019,"fantasy, fiction",American GodsNeil Gaiman
165,168,149267,"Stephen King, Bernie Wrightson",The Stand,https://images.gr-assets.com/books/1213131305l/149267.jpg,4.34,438832,"horror, fiction","The StandStephen King, Bernie Wrightson"
166,169,6400090,Nicholas Sparks,The Last Song,https://images.gr-assets.com/books/1286549186l/6400090.jpg,4.14,424637,"romance, fiction","Seventeen year old Veronica ""Ronnie"" Miller's life was turned upside-down
when her parents divorced and her father moved from New York City to
Wrightsville Beach, North Carolina. Three years later, she remains angry
and alientated from her parents, especially her father...until her mother
decides it would be in everyone's best interest if she spent the summer in
Wilmington with him. Ronnie's father, a former concert pianist and teacher,
is living a quiet life in the beach town, immersed in creating a work of
art that will become the centerpiece of a local church. The tale that
unfolds is an unforgettable story of love on many levels--first love, love
between parents and children -- that demonstrates, as only a Nicholas
Sparks novel can, the many ways that love can break our hearts...and heal
them."
167,170,11125,Dan Brown,Digital Fortress,https://images.gr-assets.com/books/1360095966l/11125.jpg,3.6,423019,"fiction, thriller","When the NSA's invincible code-breaking machine encounters a mysterious
code it cannot break, the agency calls its head cryptographer, Susan
Fletcher, a brilliant, beautiful mathematician. What she uncovers sends
shock waves through the corridors of power. The NSA is being held hostage--
not by guns or bombs -- but by a code so complex that if released would
cripple U.S. intelligence. Caught in an accelerating tempest of secrecy and
lies, Fletcher battles to save the agency she believes in. Betrayed on all
sides, she finds herself fighting not only for her country but for her
life, and in the end, for the life of the man she loves."
168,171,6969,"Jane Austen, Fiona Stafford",Emma,https://images.gr-assets.com/books/1373627931l/6969.jpg,3.99,459826,"classics, fiction","New chronology and further reading; Tony Tanner's original introduction
reinstated Edited with an introduction and notes by Flora Stafford."
169,172,15823480,"Leo Tolstoy, Louise Maude, Leo Tolstoj, Aylmer Maude",Анна Каренина,https://images.gr-assets.com/books/1352422904l/15823480.jpg,4.02,297472,"classics, fiction","Presents the nineteenth-century Russian novelist's classic in which a young
woman is destroyed when she attempts to live outside the moral law of her
society"
170,173,227463,Anthony Burgess,A Clockwork Orange,https://images.gr-assets.com/books/1348339306l/227463.jpg,3.98,431195,"classics, fiction","Great Music, it said, and Great Poetry would like quieten Modern Youth down
and make Modern Youth more Civilized. Civilized my syphilised yarbles. A
vicious fifteen-year-old droog is the central character of this 1963
classic. In Anthony Burgess's nightmare vision of the future, where the
criminals take over after dark, the story is told by the central character,
Alex, who talks in a brutal invented slang that brilliantly renders his and
his friends' social pathology. A Clockwork Orange is a frightening fable
about good and evil, and the meaning of human freedom. When the state
undertakes to reform Alex to ""redeem"" him, the novel asks, ""At what cost?""
This edition includes the controversial last chapter not published in the
first edition and Burgess's introduction ""A Clockwork Orange Resucked."""
171,174,1812457,William Paul Young,The Shack: Where Tragedy Confronts Eternity,https://images.gr-assets.com/books/1344270232l/1812457.jpg,3.74,419539,"fiction, christian",The Shack: Where Tragedy Confronts EternityWilliam Paul Young
172,175,4502507,Rick Riordan,The Last Olympian,https://images.gr-assets.com/books/1327924597l/4502507.jpg,4.5,397500,"fantasy, fiction","All year the half-bloods have been preparing for battle against the Titans,
knowing the odds are against them. Kronos is stronger than ever, and with
every god and half-blood he recruits, his power only grows. In this
momentous final book in the New York Times best-selling series, the
prophecy surrounding Percy’s sixteenth birthday unfolds. And as the battle
for Western civilization rages on the streets of Manhattan, Percy faces a
terrifying suspicion that he may be fighting against his own fate."
173,176,18342,Stephen King,It,https://images.gr-assets.com/books/1309376909l/18342.jpg,4.18,292592,"horror, fiction","They were seven teenagers when they first stumbled upon the horror. Now
they were grown-up men and women who had gone out into the big world to
gain success and happiness. But none of them could withstand the force that
drew them back to Derry, Maine to face the nightmare without an end, and
the evil without a name."
174,177,7144,"Fyodor Dostoyevsky, David McDuff",Преступление и наказание,https://images.gr-assets.com/books/1382846449l/7144.jpg,4.18,380903,"fiction, philosophy","Supreme masterpiece recounts in feverish, compelling tones the story of
Raskolnikov, an impoverished student tormented by his own nihilism, and the
struggle between good and evil."
175,178,6514,Sylvia Plath,The Bell Jar,https://images.gr-assets.com/books/1473890514l/6514.jpg,3.98,401605,"classics, fiction","Esther Greenwood, a talented and successful writer, finally succumbs to
madness when the world around her begins to falter."
176,179,252577,Frank McCourt,Angela's Ashes: A Memoir,https://i.gr-assets.com/images/S/compressed.photo.goodreads.com/books/1348317139l/252577.jpg,4.07,392103,"memoir, biography","The author recounts his childhood in Depression-era Brooklyn as the child
of Irish immigrants who decide to return to worse poverty in Ireland when
his infant sister dies"
177,180,52036,"Hermann Hesse, Hilda Rosner",Siddhartha,https://images.gr-assets.com/books/1428715580l/52036.jpg,3.99,372099,"classics, fiction","Blends elements of psychoanalysis and Asian religions to probe an Indian
aristocrat's efforts to renounce sensual and material pleasures and
discover ultimate spiritual truths"
178,181,168642,Truman Capote,In Cold Blood,https://images.gr-assets.com/books/1424931136l/168642.jpg,4.05,381652,"classics, nonfiction","An account of the senseless murder of a Kansas farm family and the search
for the killers"
179,182,6304335,"Kami Garcia, Margaret Stohl",Beautiful Creatures,https://images.gr-assets.com/books/1327873282l/6304335.jpg,3.76,436093,"fantasy, paranormal","This edition features exclusive movie cover art! Lena Duchannes is unlike
anyone the small Southern town of Gatlin has ever seen, and she's
struggling to conceal her power, and a curse that has haunted her family
for generations. But even within the overgrown gardens, murky swamps and
crumbling graveyards of the forgotten South, a secret cannot stay hidden
forever. Ethan Wate, who has been counting the months until he can escape
from Gatlin, is haunted by dreams of a beautiful girl he has never met.
When Lena moves into the town's oldest and most infamous plantation, Ethan
is inexplicably drawn to her and determined to uncover the connection
between them. In a town with no surprises, one secret could change
everything."
180,183,7171637,Cassandra Clare,Clockwork Angel,https://images.gr-assets.com/books/1454962884l/7171637.jpg,4.33,490890,"fantasy, paranormal","Includes excerpts from Clock prince, City of bones, Lady Midnight, and a
sneak peek at Vampires, scones, and Edmund Herondale."
181,184,39988,"Roald Dahl, Quentin Blake",Matilda,https://i.gr-assets.com/images/S/compressed.photo.goodreads.com/books/1388793265l/39988.jpg,4.29,440743,"fiction, fantasy","Now reissued--Dahl's tale of a sweet five-year-old little girl with
extraordinary mental powers that she uses to teach her school's evil head
mistress a lesson she'll never forget."
182,185,9361589,Erin Morgenstern,The Night Circus,https://images.gr-assets.com/books/1387124618l/9361589.jpg,4.03,429543,"fantasy, fiction","Waging a fierce competition for which they have trained since childhood,
circus magicians Celia and Marco unexpectedly fall in love with each other
and share a fantastical romance that manifests in fateful ways. A first
novel. Reprint."
183,186,37470,Philippa Gregory,The Other Boleyn Girl,https://images.gr-assets.com/books/1355932638l/37470.jpg,4.04,381080,"fiction, romance","The #1 New York Times bestseller from “the queen of royal fiction” (USA
TODAY) Philippa Gregory is a rich, compelling novel of love, sex, ambition,
and intrigue surrounding the Tudor court of Henry VIII, Anne Boleyn, and
the infamous Boleyn family. When Mary Boleyn comes to court as an innocent
girl of fourteen, she catches the eye of the handsome and charming Henry
VIII. Dazzled by the king, Mary falls in love with both her golden prince
and her growing role as unofficial queen. However, she soon realizes just
how much she is a pawn in her family’s ambitious plots as the king’s
interest begins to wane, and soon she is forced to step aside for her best
friend and rival: her sister, Anne. With her own destiny suddenly unknown,
Mary realizes that she must defy her family and take fate into her own
hands. With more than one million copies in print and adapted for the big
screen, The Other Boleyn Girl is a riveting historical drama. It brings to
light a woman of extraordinary determination and desire who lived at the
heart of the most exciting and glamorous court in Europe, and survived a
treacherous political landscape by following her heart."
184,187,24770,Scott Westerfeld,Uglies,https://images.gr-assets.com/books/1443904172l/24770.jpg,3.86,449073,"fiction, fantasy","A fresh repackaging of the bestselling Uglies boks...the series that
started the whole dystopian trend!"
185,188,10664113,George R.R. Martin,A Dance with Dragons,https://images.gr-assets.com/books/1327885335l/10664113.jpg,4.31,365954,"fantasy, fiction","A latest installment of the popular series follows a showdown set in the
north of the Seven Kingdoms and reveals the circumstances that shaped
southern-region events. By the best-selling author of A Feast for Crows.
Reprint. 400,000 first printing."
186,189,33,J.R.R. Tolkien,The Lord of the Rings,https://images.gr-assets.com/books/1411114164l/33.jpg,4.47,389054,"fantasy, classics","Presents the epic depicting the Great War of the Ring, a struggle between
good and evil in Middle-earth, following the odyssey of Frodo the hobbit
and his companions on a quest to destroy the Ring of Power."
187,190,12262741,Cheryl Strayed,Wild: From Lost to Found on the Pacific Crest Trail ,https://images.gr-assets.com/books/1453189881l/12262741.jpg,3.96,379872,"memoir, nonfiction","Traces the personal crisis the author endured after the death of her mother
and a painful divorce, which prompted her ambition to undertake a dangerous
thousand-mile solo hike that both drove her to rock bottom and helped her
to heal."
188,191,472331,"Alan Moore, Dave Gibbons, John Higgins",Watchmen,https://images.gr-assets.com/books/1442239711l/472331.jpg,4.35,398018,"fiction, fantasy","As former members of a disbanded group of superheroes called the
Crimebusters start turning up dead, the remaining members of the group try
to discover the identity of the murderer before they, too, are killed."
189,192,186074,Patrick Rothfuss,The Name of the Wind,https://images.gr-assets.com/books/1472068073l/186074.jpg,4.55,400101,"fantasy, fiction","A hero named Kvothe, now living under an assumed name as the humble
proprietor of an inn, recounts his transformation from a magically gifted
young man into the most notorious wizard, musician, thief, and assassin in
his world. Reprint."
190,193,3228917,Malcolm Gladwell,Outliers: The Story of Success,https://images.gr-assets.com/books/1344266315l/3228917.jpg,4.11,353011,"nonfiction, psychology",Outliers: The Story of SuccessMalcolm Gladwell
191,194,153747,"Herman Melville, Andrew Delbanco, Tom Quirk","Moby Dick; or, The Whale",https://images.gr-assets.com/books/1327940656l/153747.jpg,3.46,358050,"classics, fiction","On board the whaling ship Pequod a crew of wise men and fools, renegades
and seeming phantoms is hurled through treacherous seas by a crazed captain
hell-bent on hunting down the mythic White Whale. Melville transforms the
little world of the whale-ship into a crucible where mankind¿s fears, faith
and frailties are pitted against a relentless fate. Teeming with ideas and
imagery, and with its extraordinary, compressed intensity sustained by
mischievous irony and moments of exquisite beauty, Moby-Dick is both a
great American epic and a most profoundly imaginative literary creation.
With an afterword by Nigel Cliff. Designed to appeal to the book lover, the
Macmillan Collector's Library is a series of beautifully bound pocket-sized
gift editions of much loved classic titles. Bound in real cloth, printed on
high quality paper, and featuring ribbon markers and gilt edges, Macmillan
Collector's Library are books to love and treasure."
192,195,2728527,"Mary Ann Shaffer, Annie Barrows",The Guernsey Literary and Potato Peel Pie Society,https://images.gr-assets.com/books/1351979318l/2728527.jpg,4.12,393626,"fiction, romance","In 1946, writer Juliet Ashton receives a letter from a stranger, a founding
member of the Guernsey Literary and Potato Peel Pie Society. And so begins
a remarkable tale of the island of Guernsey during the German occupation,
and of a society as extraordinary as its name."
193,196,5759,Chuck Palahniuk,Fight Club,https://images.gr-assets.com/books/1357128997l/5759.jpg,4.2,365349,"fiction, contemporary","In a confusing world poised on the brink of mayhem, Tyler Durden, a
projectionist, waiter, and anarchic genius, comes up with an idea to create
clubs in which young men can escape their humdrum existence and prove
themselves in barehanded fights. Reprint. 50,000 first printing."
194,197,301082,Charlaine Harris,Dead Until Dark,https://images.gr-assets.com/books/1468560853l/301082.jpg,3.96,420764,"fantasy, paranormal","Love blossoms between Sookie Stackhouse, a cocktail waitress in rural
Louisiana who keeps to herself because of her ability to read minds, and
Bill, a tall, dark, and handsome vampire with ties to a creepy crowd that
may be responsible for the death of one of Sookie's coworkers. Original."
195,198,11486,Alice Walker,The Color Purple,https://i.gr-asset
Download .txt
gitextract_s0diptc6/

├── .github/
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.md
│   │   └── feature_request.md
│   ├── pull_request_template.md
│   └── workflows/
│       └── tests.yml
├── .gitignore
├── .pre-commit-config.yaml
├── BookRecSystem/
│   ├── __init__.py
│   ├── asgi.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── mainapp/
│   ├── __init__.py
│   ├── admin.py
│   ├── apps.py
│   ├── forms.py
│   ├── helpers.py
│   ├── migrations/
│   │   ├── 0001_initial.py
│   │   ├── 0002_saveforlater.py
│   │   └── __init__.py
│   ├── models.py
│   ├── tests.py
│   ├── urls.py
│   ├── views.py
│   └── views_ajax.py
├── manage.py
├── pyproject.toml
├── requirements.txt
├── setup.cfg
├── static/
│   └── mainapp/
│       ├── css/
│       │   ├── explore.css
│       │   ├── genre.css
│       │   ├── index.css
│       │   ├── layout.css
│       │   ├── login.css
│       │   ├── password_reset.css
│       │   ├── read.css
│       │   ├── recommendation.css
│       │   ├── saved_book.css
│       │   └── signup.css
│       ├── dataset/
│       │   ├── books.csv
│       │   ├── books_cleaned.csv
│       │   └── full_book.csv
│       └── model_files/
│           ├── surprise/
│           │   ├── book_embedding.npy
│           │   ├── book_inner_id_to_raw.pickle
│           │   ├── book_raw_to_inner_id.pickle
│           │   └── sim_books.pickle
│           └── tf-idf/
│               ├── cosine_rating_sim.npz
│               └── indices.pkl
└── templates/
    ├── account/
    │   ├── login.html
    │   ├── password_reset.html
    │   ├── password_reset_done.html
    │   ├── password_reset_from_key.html
    │   ├── password_reset_from_key_done.html
    │   └── signup.html
    └── mainapp/
        ├── error_handler.html
        ├── explore.html
        ├── genre.html
        ├── index.html
        ├── layout.html
        ├── read.html
        ├── recommendation.html
        └── saved_book.html
Download .txt
SYMBOL INDEX (75 symbols across 9 files)

FILE: mainapp/apps.py
  class MainappConfig (line 4) | class MainappConfig(AppConfig):

FILE: mainapp/helpers.py
  function is_rating_invalid (line 54) | def is_rating_invalid(rating):
  function is_bookid_invalid (line 77) | def is_bookid_invalid(bookid):
  function get_book_title (line 101) | def get_book_title(bookid):
  function get_book_ids (line 118) | def get_book_ids(index_list):
  function get_rated_bookids (line 136) | def get_rated_bookids(user_ratings):
  function get_raw_id (line 157) | def get_raw_id(book_id):
  function get_bookid (line 175) | def get_bookid(raw_id_list):
  function genre_wise (line 193) | def genre_wise(genre, percentile=0.85):
  function tfidf_recommendations (line 226) | def tfidf_recommendations(bookid):
  function embedding_recommendations (line 256) | def embedding_recommendations(sorted_user_ratings):
  function get_book_dict (line 295) | def get_book_dict(bookid_list):
  function combine_ids (line 315) | def combine_ids(tfidf_bookids, embedding_bookids, already_rated, recomme...
  function most_common_genre_recommendations (line 371) | def most_common_genre_recommendations(books, n):
  function get_top_n (line 403) | def get_top_n(top_n=400):
  function popular_among_users (line 430) | def popular_among_users(N=15):

FILE: mainapp/migrations/0001_initial.py
  class Migration (line 8) | class Migration(migrations.Migration):

FILE: mainapp/migrations/0002_saveforlater.py
  class Migration (line 8) | class Migration(migrations.Migration):

FILE: mainapp/models.py
  class UserRating (line 13) | class UserRating(models.Model):
    method __str__ (line 18) | def __str__(self):
  class SaveForLater (line 28) | class SaveForLater(models.Model):
    method __str__ (line 32) | def __str__(self):

FILE: mainapp/tests.py
  class HomeTests (line 14) | class HomeTests(TestCase):
    method setUp (line 19) | def setUp(self):
    method test_home_view_status_code (line 22) | def test_home_view_status_code(self):
    method test_home_url_resolves_home_view (line 29) | def test_home_url_resolves_home_view(self):
  class GenreTestCase (line 37) | class GenreTestCase(TestCase):
    method setUp (line 42) | def setUp(self):
    method test_genre_status_code (line 74) | def test_genre_status_code(self):
  class ExploreTestCase (line 84) | class ExploreTestCase(TestCase):
    method setUp (line 89) | def setUp(self):
    method test_explore_status_code (line 92) | def test_explore_status_code(self):
  class SearchAjaxTestCase (line 100) | class SearchAjaxTestCase(TestCase):
    method setUp (line 105) | def setUp(self):
    method test_search_ajax_view_status_code (line 108) | def test_search_ajax_view_status_code(self):
  class BookSummaryTestCase (line 125) | class BookSummaryTestCase(TestCase):
    method setUp (line 130) | def setUp(self):
    method test_book_summary_view_status_code (line 134) | def test_book_summary_view_status_code(self):
  class BookDetailsTestCase (line 146) | class BookDetailsTestCase(TestCase):
    method setUp (line 151) | def setUp(self):
    method test_book_details_view_status_code (line 155) | def test_book_details_view_status_code(self):
  class UserRateBookTestCase (line 167) | class UserRateBookTestCase(TestCase):
    method setUp (line 172) | def setUp(self):
    method test_user_rated_book_invalid (line 182) | def test_user_rated_book_invalid(self):
    method test_user_rated_book_valid (line 206) | def test_user_rated_book_valid(self):
  class MostCommonGenreTestCase (line 237) | class MostCommonGenreTestCase(TestCase):
    method setUp (line 242) | def setUp(self):
    method test_genre_driver (line 248) | def test_genre_driver(self):
    method template (line 275) | def template(self, tnum, already_slice, bestbookids_slice):
  class RatedBooksTestCase (line 294) | class RatedBooksTestCase(TestCase):
    method setUp (line 297) | def setUp(self):
    method test_redirect_if_not_rated (line 306) | def test_redirect_if_not_rated(self):
    method test_read_book_status_code (line 315) | def test_read_book_status_code(self):
  class AddBooksTestCase (line 329) | class AddBooksTestCase(TestCase):
    method setUp (line 332) | def setUp(self):
    method test_save_book_status (line 344) | def test_save_book_status(self):
    method test_after_remove (line 360) | def test_after_remove(self):
    method test_redirect_if_not_saved (line 376) | def test_redirect_if_not_saved(self):
    method test_to_read_status_if_saved (line 385) | def test_to_read_status_if_saved(self):

FILE: mainapp/views.py
  function index (line 24) | def index(request):
  function genre_books (line 33) | def genre_books(request, genre):
  function explore_books (line 47) | def explore_books(request):
  function book_recommendations (line 59) | def book_recommendations(request):
  function read_books (line 105) | def read_books(request):
  function handler404 (line 126) | def handler404(request, *args, **argv):
  function handler500 (line 132) | def handler500(request, *args, **argv):
  function SaveList (line 138) | def SaveList(request):

FILE: mainapp/views_ajax.py
  function is_ajax (line 22) | def is_ajax(request):
  function search (line 26) | def search(request):
  function book_summary (line 43) | def book_summary(request):
  function get_book_details (line 69) | def get_book_details(request):
  function user_rate_book (line 88) | def user_rate_book(request):
  function save_book (line 113) | def save_book(request):
  function remove_saved_book (line 126) | def remove_saved_book(request):

FILE: manage.py
  function main (line 7) | def main():
Condensed preview — 64 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (7,984K chars).
[
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "chars": 893,
    "preview": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n**Describe the b"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "chars": 654,
    "preview": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n**Is your fea"
  },
  {
    "path": ".github/pull_request_template.md",
    "chars": 480,
    "preview": "## Description\n- List out your changes\n- Link the Issue which this resolves\n\n## Affected Dependencies\n\n\n## How has this "
  },
  {
    "path": ".github/workflows/tests.yml",
    "chars": 1468,
    "preview": "# This is a basic workflow to help you get started with Actions\nname: Tests\n# Controls when the action will run.\non:\n  #"
  },
  {
    "path": ".gitignore",
    "chars": 1855,
    "preview": "bookenv/\n.vscode\n# colllect static output\nstaticfiles/\n\n# Byte-compiled / optimized / DLL files\n__pycache__/\n*.py[cod]\n*"
  },
  {
    "path": ".pre-commit-config.yaml",
    "chars": 234,
    "preview": "exclude: 'wip'\nrepos:\n- repo: https://github.com/ambv/black\n  rev: 22.3.0\n  hooks:\n    - id: black\n      name: black-py\n"
  },
  {
    "path": "BookRecSystem/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "BookRecSystem/asgi.py",
    "chars": 403,
    "preview": "\"\"\"\nASGI config for BookRecSystem project.\n\nIt exposes the ASGI callable as a module-level variable named ``application`"
  },
  {
    "path": "BookRecSystem/settings.py",
    "chars": 6032,
    "preview": "\"\"\"\nDjango settings for BookRecSystem project.\n\nGenerated by 'django-admin startproject' using Django 3.1.1.\n\nFor more i"
  },
  {
    "path": "BookRecSystem/urls.py",
    "chars": 1087,
    "preview": "\"\"\"BookRecSystem URL Configuration\n\nThe `urlpatterns` list routes URLs to views. For more information please see:\n    ht"
  },
  {
    "path": "BookRecSystem/wsgi.py",
    "chars": 403,
    "preview": "\"\"\"\nWSGI config for BookRecSystem project.\n\nIt exposes the WSGI callable as a module-level variable named ``application`"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 2545,
    "preview": "## Contributing Guidelines\n\nYou are **Awesome!** Thank you for your Interest in Contributing to this Project 🤗\nFor Contr"
  },
  {
    "path": "LICENSE",
    "chars": 1066,
    "preview": "MIT License\n\nCopyright (c) 2020 Praful932\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\n"
  },
  {
    "path": "README.md",
    "chars": 8511,
    "preview": "\n![1](https://user-images.githubusercontent.com/45713796/98271308-d18aac80-1fb5-11eb-9db3-dda942cc1b07.png)\n\n\n**Kitabe**"
  },
  {
    "path": "mainapp/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "mainapp/admin.py",
    "chars": 182,
    "preview": "from django.contrib import admin\nfrom mainapp.models import UserRating, SaveForLater\n\n# Register your models here.\n\nadmi"
  },
  {
    "path": "mainapp/apps.py",
    "chars": 89,
    "preview": "from django.apps import AppConfig\n\n\nclass MainappConfig(AppConfig):\n    name = \"mainapp\"\n"
  },
  {
    "path": "mainapp/forms.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "mainapp/helpers.py",
    "chars": 12922,
    "preview": "import pandas as pd\nimport numpy as np\nimport os\nimport math\nimport pickle\nimport operator\nimport random\nfrom collection"
  },
  {
    "path": "mainapp/migrations/0001_initial.py",
    "chars": 1148,
    "preview": "# Generated by Django 3.1.1 on 2020-09-27 15:02\n\nfrom django.conf import settings\nfrom django.db import migrations, mode"
  },
  {
    "path": "mainapp/migrations/0002_saveforlater.py",
    "chars": 1060,
    "preview": "# Generated by Django 3.1.6 on 2021-04-14 18:18\n\nfrom django.conf import settings\nfrom django.db import migrations, mode"
  },
  {
    "path": "mainapp/migrations/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "mainapp/models.py",
    "chars": 958,
    "preview": "from django.db import models\nfrom django.contrib.auth.models import User\nfrom mainapp.helpers import get_book_title\n\nimp"
  },
  {
    "path": "mainapp/tests.py",
    "chars": 12466,
    "preview": "from django.urls import reverse, resolve\nfrom django.test import TestCase, Client\nfrom mainapp import views\nfrom django."
  },
  {
    "path": "mainapp/urls.py",
    "chars": 1000,
    "preview": "from django.urls import path\nfrom mainapp import views, views_ajax\n\nurlpatterns = [\n    path(\"\", views.index, name=\"inde"
  },
  {
    "path": "mainapp/views.py",
    "chars": 5102,
    "preview": "from django.shortcuts import render, redirect\nfrom django.contrib.auth.decorators import login_required\nfrom django.view"
  },
  {
    "path": "mainapp/views_ajax.py",
    "chars": 5133,
    "preview": "from django.http import JsonResponse\nfrom django.contrib.auth.decorators import login_required\nfrom mainapp.helpers impo"
  },
  {
    "path": "manage.py",
    "chars": 669,
    "preview": "#!/usr/bin/env python\n\"\"\"Django's command-line utility for administrative tasks.\"\"\"\nimport os\nimport sys\n\n\ndef main():\n "
  },
  {
    "path": "pyproject.toml",
    "chars": 602,
    "preview": "[tool.poetry]\nname = \"kitabe\"\nversion = \"0.1.0\"\ndescription = \"Book Recommendation System\"\nauthors = [\"maneprajakta <pra"
  },
  {
    "path": "requirements.txt",
    "chars": 3862,
    "preview": "asgiref==3.5.2 ; python_version >= \"3.8\" and python_version < \"4.0\"\nastroid==2.12.11 ; python_version >= \"3.8\" and pytho"
  },
  {
    "path": "setup.cfg",
    "chars": 195,
    "preview": "[flake8]\nexclude = .git,*migrations*,__pycache__,.vscode,bookenv\nmax-line-length = 1196\n[coverage:run]\nomit =\n    BookRe"
  },
  {
    "path": "static/mainapp/css/explore.css",
    "chars": 3576,
    "preview": ".hide {\n    display: none;\n}\n\n.centre {\n    display: flex;\n    flex-wrap: wrap;\n    justify-content: center;\n    padding"
  },
  {
    "path": "static/mainapp/css/genre.css",
    "chars": 2672,
    "preview": ".genre-head,\n.topbook-head {\n    font-family: \"Lobster\", cursive;\n    font-size: 300%;\n    background-color: #d7722c;\n  "
  },
  {
    "path": "static/mainapp/css/index.css",
    "chars": 6914,
    "preview": "/*---------------------------------------- preloader ----------------------------------*/\n\n.preloader-container {\n    po"
  },
  {
    "path": "static/mainapp/css/layout.css",
    "chars": 5189,
    "preview": "html,\nbody {\n    background-color: #ffdab9;\n    height: 100%;\n    max-width: 100%;\n    overflow-x: hidden;\n}\n\n#navbarNav"
  },
  {
    "path": "static/mainapp/css/login.css",
    "chars": 3615,
    "preview": ".account-block {\n    margin: auto;\n    height: 80%;\n    width: 70%;\n    background-color: white;\n}\n\n.signin-block {\n    "
  },
  {
    "path": "static/mainapp/css/password_reset.css",
    "chars": 973,
    "preview": ".heading {\n  font-family: \"Lobster\", cursive;\n  font-size: xx-large;\n}\n\n.resetButton {\n  font-family: \"Fredoka One\", cur"
  },
  {
    "path": "static/mainapp/css/read.css",
    "chars": 3015,
    "preview": ".card-deck {\n    padding-left: 3.5%;\n}\n\n.genre-head,\n.topbook-head {\n    font-family: \"Lobster\", cursive;\n    font-size:"
  },
  {
    "path": "static/mainapp/css/recommendation.css",
    "chars": 3009,
    "preview": "@import url(\"https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap\");\n@import url(//netdna.b"
  },
  {
    "path": "static/mainapp/css/saved_book.css",
    "chars": 2654,
    "preview": ".genre-head {\n    font-family: \"Lobster\", cursive;\n    font-size: 300%;\n    background-color: #d7722c;\n    margin-top: 0"
  },
  {
    "path": "static/mainapp/css/signup.css",
    "chars": 3418,
    "preview": ".account-block {\n    margin: auto;\n    height: 80%;\n    width: 70%;\n    background-color: white;\n}\n\n.signup-block {\n    "
  },
  {
    "path": "static/mainapp/dataset/books.csv",
    "chars": 4454996,
    "preview": ",r_index,book_id,authors,original_title,image_url,average_rating,ratings_count,genre,desc\r\n0,1,2767052,Suzanne Collins,T"
  },
  {
    "path": "static/mainapp/dataset/books_cleaned.csv",
    "chars": 124041,
    "preview": ",Unnamed: 0,book_id,isbn13,authors,original_title,average_rating,ratings_count,image_url\n1,1,3,9780439554930.0,\"J.K. Row"
  },
  {
    "path": "static/mainapp/dataset/full_book.csv",
    "chars": 3063081,
    "preview": "r_index,book_id,best_book_id,work_id,books_count,isbn,isbn13,authors,original_publication_year,original_title,title,lang"
  },
  {
    "path": "templates/account/login.html",
    "chars": 2331,
    "preview": "{% extends 'mainapp/layout.html' %}\n{% load i18n %}\n{% load static %}\n{% load account socialaccount %}\n{% get_providers "
  },
  {
    "path": "templates/account/password_reset.html",
    "chars": 1094,
    "preview": "{% extends 'mainapp/layout.html' %}\n{% load static %}\n{% load i18n %}\n{% load account %}\n\n{% block title %}\nPassword Res"
  },
  {
    "path": "templates/account/password_reset_done.html",
    "chars": 680,
    "preview": "{% extends 'mainapp/layout.html' %}\n{% load static %}\n\n{% load i18n %}\n{% load account %}\n\n{% block title %}\nPassword Re"
  },
  {
    "path": "templates/account/password_reset_from_key.html",
    "chars": 1170,
    "preview": "{% extends 'mainapp/layout.html' %}\n{% load static %}\n{% load i18n %}\n\n{% block title %}\nChange Password\n{% endblock tit"
  },
  {
    "path": "templates/account/password_reset_from_key_done.html",
    "chars": 531,
    "preview": "{% extends 'mainapp/layout.html' %}\n{% load static %}\n{% load i18n %}\n\n{% block title %}\nChange Password\n{% endblock tit"
  },
  {
    "path": "templates/account/signup.html",
    "chars": 2258,
    "preview": "{% extends 'mainapp/layout.html' %}\n{% load i18n %}\n{% load static %}\n{% load account socialaccount %}\n{% get_providers "
  },
  {
    "path": "templates/mainapp/error_handler.html",
    "chars": 2909,
    "preview": "<!doctype html>\n<html lang=\"en\">\n{% load static %}\n<head>\n\t<!-- Required meta tags -->\n\t<meta charset=\"utf-8\">\n\t<meta na"
  },
  {
    "path": "templates/mainapp/explore.html",
    "chars": 11215,
    "preview": "{% extends \"mainapp/layout.html\" %}\n{% load static %}\n\n{% block title %}\nExplore\n{% endblock title %}\n\n\n{% block head %}"
  },
  {
    "path": "templates/mainapp/genre.html",
    "chars": 1878,
    "preview": "{% extends \"mainapp/layout.html\" %}\n{% load static %}\n\n{% block title  %}\nGenre\n{% endblock title %} \n\n{% block head %}\n"
  },
  {
    "path": "templates/mainapp/index.html",
    "chars": 20528,
    "preview": "{% extends \"mainapp/layout.html\" %}\n{% load static %}\n{% block title %} Home {% endblock title %}\n{% block head %}\n<link"
  },
  {
    "path": "templates/mainapp/layout.html",
    "chars": 19579,
    "preview": "<!doctype html> \n{% load static %}\n<html lang=\"en\">\n\n<head>\n    <!-- Required meta tags -->\n    <meta charset=\"utf-8\">\n "
  },
  {
    "path": "templates/mainapp/read.html",
    "chars": 2227,
    "preview": "{% extends \"mainapp/layout.html\" %} \n{% load static %} \n{% block title %} \n Library \n{% endblock title %} \n{% block head"
  },
  {
    "path": "templates/mainapp/recommendation.html",
    "chars": 2032,
    "preview": "{% extends \"mainapp/layout.html\" %}\n{% load static %}\n\n{% block title  %}\nPersonalized Read\n{% endblock title %}\n\n{% blo"
  },
  {
    "path": "templates/mainapp/saved_book.html",
    "chars": 2780,
    "preview": "{% extends \"mainapp/layout.html\" %} \n{% load static %} \n{% block title %} \nLibrary \n{% endblock title %} \n{% block head "
  }
]

// ... and 6 more files (download for full content)

About this extraction

This page contains the full source code of the Praful932/Kitabe GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 64 files (28.7 MB), approximately 2.0M tokens, and a symbol index with 75 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!