mirror of
https://github.com/didyouexpectthat/cs-340.git
synced 2025-07-05 20:41:20 -07:00
Add files via upload
This commit is contained in:
parent
509536bea0
commit
ac3a200a7d
4 changed files with 876 additions and 0 deletions
125
AnimalShelter.py
Normal file
125
AnimalShelter.py
Normal file
|
@ -0,0 +1,125 @@
|
|||
# Cody Cook
|
||||
# CS-340 Client/Server Development
|
||||
# SNHU
|
||||
# 2024/04/02
|
||||
# Project One
|
||||
|
||||
# Import necessary libraries
|
||||
from pymongo import MongoClient
|
||||
from pymongo.errors import ConnectionFailure, OperationFailure
|
||||
from urllib.parse import quote_plus
|
||||
from bson.objectid import ObjectId
|
||||
|
||||
# Define the AnimalShelter class
|
||||
class AnimalShelter():
|
||||
""" CRUD operations for Animal collection in MongoDB """
|
||||
|
||||
# Initialize the MongoClient and the database
|
||||
def __init__(self, username, password, hostname, port, database, collection):
|
||||
""" Initialize the MongoClient and the database """
|
||||
|
||||
connection = "mongodb://%s:%s@%s:%d" % (quote_plus(username), quote_plus(password), hostname, port)
|
||||
|
||||
# Try to connect to the database
|
||||
try:
|
||||
self.client = MongoClient(connection) # The client object is an instance of the MongoClient class
|
||||
self.database = self.client['%s' % (database)] # The database object is an instance of the database class
|
||||
self.collection = self.database['%s' % (collection)] # The collection object is an instance of the collection class
|
||||
|
||||
# If the connection fails, print an error message
|
||||
except ConnectionFailure as e:
|
||||
# If the connection fails, print an error message
|
||||
print("Could not connect to MongoDB: %s" % e)
|
||||
|
||||
# Create method
|
||||
def create(self, data):
|
||||
""" Create a new animal in the database """
|
||||
|
||||
if data is not None:
|
||||
# Try to insert the data into the database
|
||||
try:
|
||||
self.collection.insert_one(data) # Insert the data into the collection
|
||||
print("Animal added successfully") # Print a success message
|
||||
return True # Return True if successful
|
||||
|
||||
# If the operation fails, print an error message
|
||||
except OperationFailure as e:
|
||||
# If the operation fails, print an error message
|
||||
print("Could not add animal: %s" % e)
|
||||
# Return False if the operation fails
|
||||
return False
|
||||
else:
|
||||
# If the data is empty, print an error message
|
||||
print("Data is empty, nothing to add")
|
||||
# Return False if the data is empty
|
||||
return False
|
||||
|
||||
# Read method
|
||||
def read(self, data):
|
||||
""" Read an animal from the database """
|
||||
|
||||
if data is not None:
|
||||
# Try to read the data from the database
|
||||
try:
|
||||
# Read the data from the collection
|
||||
documents = list(self.collection.find(data, {"_id": False}))
|
||||
# Return the documents
|
||||
return documents
|
||||
|
||||
# If the operation fails, print an error message
|
||||
except OperationFailure as e:
|
||||
# Print an error message
|
||||
print("Could not read animal: %s" % e)
|
||||
# Return an empty list
|
||||
return []
|
||||
else:
|
||||
# If the data is empty, print an error message
|
||||
print("Data is empty, nothing to read")
|
||||
# Return an empty list
|
||||
return []
|
||||
|
||||
# Update method
|
||||
def update(self, query, data):
|
||||
""" Update an animal in the database """
|
||||
|
||||
# Check if the query and data are not empty
|
||||
if query is not None and data is not None:
|
||||
# Try to update the data in the database
|
||||
try:
|
||||
# Update the data in the collection
|
||||
result = self.collection.update_many(query, {'$set': data})
|
||||
# Print a success message
|
||||
print(f"Animals updated: {result.modified_count}")
|
||||
# Return the number of animals updated
|
||||
return result.modified_count
|
||||
except OperationFailure as e:
|
||||
# If the operation fails, print an error message
|
||||
print(f"Could not update animal: {e}")
|
||||
return 0
|
||||
else:
|
||||
# If the data or query is empty, print an error message and return 0
|
||||
print("Data and/or query is empty, nothing to update")
|
||||
return 0
|
||||
|
||||
# Delete method
|
||||
def delete(self, data):
|
||||
""" Delete an animal from the database """
|
||||
# Check if the data is not empty
|
||||
if data is not None:
|
||||
# Try to delete the data from the database
|
||||
try:
|
||||
# Delete the data from the collection
|
||||
result = self.collection.delete_many(data)
|
||||
# Print a success message
|
||||
print(f"Animals deleted: {result.deleted_count}")
|
||||
# Return the number of animals deleted
|
||||
return result.deleted_count
|
||||
except OperationFailure as e:
|
||||
# If the operation fails, print an error message and return 0
|
||||
print(f"Could not delete animal: {e}")
|
||||
return 0
|
||||
else:
|
||||
# If the data is empty, print an error message and return 0
|
||||
print("Data is empty, nothing to delete")
|
||||
return 0
|
||||
|
292
AnimalShelterTest.ipynb
Normal file
292
AnimalShelterTest.ipynb
Normal file
|
@ -0,0 +1,292 @@
|
|||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"id": "f9cc3d73",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Import the AnimalShelter class\n",
|
||||
"from AnimalShelter import AnimalShelter"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"id": "fe96019a",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Configure the connection details\n",
|
||||
"username = 'aacuser'\n",
|
||||
"password = '1B@nana4U$'\n",
|
||||
"hostname = 'nv-desktop-services.apporto.com'\n",
|
||||
"port = 30909\n",
|
||||
"database = 'AAC'\n",
|
||||
"collection = 'animals'"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"id": "5685f758",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Create test data\n",
|
||||
"test_file= {\n",
|
||||
" '':\"10001\",\n",
|
||||
" 'age_upon_outcome':\"2 weeks\", \n",
|
||||
" 'animal_id':\"TEST123\",\n",
|
||||
" 'animal_type': \"Dog\", \n",
|
||||
" 'breed':\"Hawaiian Labrador\", \n",
|
||||
" 'color':\"Black\",\n",
|
||||
" 'date_of_birth':\"2024-03-12\", \n",
|
||||
" 'monthyear': \"2024-03-26 21:18:00\", \n",
|
||||
" 'outcome_subtype':'Transfer',\n",
|
||||
" 'outcome_type':\"GOAT\", \n",
|
||||
" 'sex_upon_outcome':\"Intact Male\", \n",
|
||||
" 'location_long':\"-97.4033754809296\",\n",
|
||||
" 'location_lat':\"30.6664774192579\",\n",
|
||||
" 'age_upon_outcome_in_weeks':\"50 years\", \n",
|
||||
" \"name\": \"Bark Obama\",\n",
|
||||
" \"datetime\": \"2024-03-26 21:18:00\",\n",
|
||||
" \"status\": \"Available\"\n",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"id": "5bd5672a",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Create a sample query\n",
|
||||
"query = {\"breed\":\"Hawaiian Labrador\"}"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"id": "e43f344a",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Initiate a failed connection to the MongoDB\n",
|
||||
"shelter = AnimalShelter(\"username\", \"password\", hostname, port, database, collection)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"id": "4d770845",
|
||||
"metadata": {
|
||||
"scrolled": true
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Could not read animal: Authentication failed., full error: {'ok': 0.0, 'errmsg': 'Authentication failed.', 'code': 18, 'codeName': 'AuthenticationFailed'}\n",
|
||||
"Check existing sample: []\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Check to see if the entry exists already \n",
|
||||
"# This assumes this hasn't already been run before.\n",
|
||||
"precheck = shelter.read(query)\n",
|
||||
"print(\"Check existing sample:\", precheck)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"id": "15b3d1bb",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Initiate the connection to the MongoDB\n",
|
||||
"shelter = AnimalShelter(username, password, hostname, port, database, collection);"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"id": "7f73158c",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Check existing sample: []\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Check to see if the entry exists already \n",
|
||||
"# This assumes this hasn't already been run before.\n",
|
||||
"precheck = shelter.read(query)\n",
|
||||
"print(\"Check existing sample:\", precheck)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 9,
|
||||
"id": "38e43a66",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Animal added successfully\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"True"
|
||||
]
|
||||
},
|
||||
"execution_count": 9,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Add the animal to the database\n",
|
||||
"shelter.create(test_file)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 10,
|
||||
"id": "bb4ebdd0",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Check post-add sample: [{'': '10001', 'age_upon_outcome': '2 weeks', 'animal_id': 'TEST123', 'animal_type': 'Dog', 'breed': 'Hawaiian Labrador', 'color': 'Black', 'date_of_birth': '2024-03-12', 'monthyear': '2024-03-26 21:18:00', 'outcome_subtype': 'Transfer', 'outcome_type': 'GOAT', 'sex_upon_outcome': 'Intact Male', 'location_long': '-97.4033754809296', 'location_lat': '30.6664774192579', 'age_upon_outcome_in_weeks': '50 years', 'name': 'Bark Obama', 'datetime': '2024-03-26 21:18:00', 'status': 'Available'}]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Confirm the entry was added\n",
|
||||
"postcheck = shelter.read(query)\n",
|
||||
"print(\"Check post-add sample:\", postcheck)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 11,
|
||||
"id": "a822e964",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Animals updated: 1\n",
|
||||
"Updated items: 1\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Update the test animal to an Adopted status\n",
|
||||
"query = {\"animal_id\": \"TEST123\"}\n",
|
||||
"updates = {\"status\": \"Adopted\"}\n",
|
||||
"result = shelter.update(query, updates)\n",
|
||||
"print(f\"Updated items: {result}\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 12,
|
||||
"id": "5f5300c2",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Result: [{'': '10001', 'age_upon_outcome': '2 weeks', 'animal_id': 'TEST123', 'animal_type': 'Dog', 'breed': 'Hawaiian Labrador', 'color': 'Black', 'date_of_birth': '2024-03-12', 'monthyear': '2024-03-26 21:18:00', 'outcome_subtype': 'Transfer', 'outcome_type': 'GOAT', 'sex_upon_outcome': 'Intact Male', 'location_long': '-97.4033754809296', 'location_lat': '30.6664774192579', 'age_upon_outcome_in_weeks': '50 years', 'name': 'Bark Obama', 'datetime': '2024-03-26 21:18:00', 'status': 'Adopted'}]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Confirm the update took place\n",
|
||||
"check = shelter.read(query)\n",
|
||||
"print(f\"Result: {check}\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 13,
|
||||
"id": "974092b3",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Animals deleted: 1\n",
|
||||
"Deleted result: 1\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Delete animals matching the query\n",
|
||||
"result = shelter.delete(query)\n",
|
||||
"print(f\"Deleted result: {result}\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 14,
|
||||
"id": "aae82505",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Check for records: []\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Check for the deleted animal\n",
|
||||
"check = shelter.read(query)\n",
|
||||
"print(\"Check for records: \", check)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.9.12"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
459
Dashboard.ipynb
Normal file
459
Dashboard.ipynb
Normal file
|
@ -0,0 +1,459 @@
|
|||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"id": "659038cc",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Setup the Jupyter version of Dash\n",
|
||||
"from jupyter_dash import JupyterDash"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"id": "1653e615",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Configure the necessary Python module imports\n",
|
||||
"import dash_leaflet as dl\n",
|
||||
"from dash import dcc\n",
|
||||
"from dash import html\n",
|
||||
"import plotly.express as px\n",
|
||||
"from dash import dash_table\n",
|
||||
"from dash.dependencies import Input, Output, State\n",
|
||||
"import base64"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"id": "b86503df",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Configure OS routines\n",
|
||||
"import os"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"id": "f21674e5",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Configure the plotting routines\n",
|
||||
"import numpy as np\n",
|
||||
"import pandas as pd\n",
|
||||
"import matplotlib.pyplot as plt"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"id": "47fcde56",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# import the CRUD module\n",
|
||||
"from AnimalShelter import AnimalShelter"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"id": "0f0ff9f4",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Instantiate the CRUD module\n",
|
||||
"username = 'aacuser'\n",
|
||||
"password = '1B@nana4U$'\n",
|
||||
"hostname = 'nv-desktop-services.apporto.com'\n",
|
||||
"port = 30909\n",
|
||||
"database = 'AAC'\n",
|
||||
"collection = 'animals'\n",
|
||||
"db = AnimalShelter(username, password, hostname, port, database, collection)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"id": "03f59f24",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# populate df with a dataframe of the items from the CRUD module\n",
|
||||
"df = pd.DataFrame.from_records(db.read({}))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"id": "49395346",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Drop _id; but I actually already do this in the CRUD so I will ignore it\n",
|
||||
"\n",
|
||||
"#df.drop(columns=['_id'],inplace=True)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 9,
|
||||
"id": "4159b76b",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"10000\n",
|
||||
"Index(['rec_num', 'age_upon_outcome', 'animal_id', 'animal_type', 'breed',\n",
|
||||
" 'color', 'date_of_birth', 'datetime', 'monthyear', 'name',\n",
|
||||
" 'outcome_subtype', 'outcome_type', 'sex_upon_outcome', 'location_lat',\n",
|
||||
" 'location_long', 'age_upon_outcome_in_weeks'],\n",
|
||||
" dtype='object')\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Debugging to confirm records pulled\n",
|
||||
"print(len(df.to_dict(orient='records')))\n",
|
||||
"print(df.columns)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 10,
|
||||
"id": "3ed24c36",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# build the layout\n",
|
||||
"app = JupyterDash(__name__)\n",
|
||||
"image_filename = 'logo.png' \n",
|
||||
"header1 = \"CS-340 Dashboard by Cody Cook\"\n",
|
||||
"encoded_image = base64.b64encode(open(image_filename, 'rb').read())\n",
|
||||
"\n",
|
||||
"# define filter options\n",
|
||||
"filter_options = [\n",
|
||||
" {'label': 'Water Rescue', 'value': 'water'},\n",
|
||||
" {'label': 'Mountain or Wilderness Rescue', 'value': 'mountain'},\n",
|
||||
" {'label': 'Disaster or Individual Tracking', 'value': 'disaster'},\n",
|
||||
" {'label': 'Reset', 'value': 'reset'}\n",
|
||||
"]\n",
|
||||
"\n",
|
||||
"app.layout = html.Div([\n",
|
||||
" html.Div([\n",
|
||||
" html.Img(\n",
|
||||
" # show image and set size to 100x100\n",
|
||||
" src='data:image/png;base64,{}'.format(encoded_image.decode()),\n",
|
||||
" style={'height': '100px', 'width': '100px', 'display': 'block', 'margin-left': 'auto', 'margin-right': 'auto'}\n",
|
||||
" ),\n",
|
||||
" # show header1\n",
|
||||
" html.H1(header1, style={'textAlign': 'center'}),\n",
|
||||
" ],\n",
|
||||
" style={'text-align': 'center'}\n",
|
||||
" ),\n",
|
||||
" html.Hr(),\n",
|
||||
" html.Div(\n",
|
||||
" dcc.Dropdown(\n",
|
||||
" id='filter-type',\n",
|
||||
" options=[\n",
|
||||
" # show the filter options\n",
|
||||
" {'label': 'Water Rescue', 'value': 'water'},\n",
|
||||
" {'label': 'Mountain or Wilderness Rescue', 'value': 'mountain'},\n",
|
||||
" {'label': 'Disaster or Individual Tracking', 'value': 'disaster'},\n",
|
||||
" {'label': 'Reset', 'value': 'reset'}\n",
|
||||
" ],\n",
|
||||
" value='reset', \n",
|
||||
" clearable=False \n",
|
||||
" )),\n",
|
||||
" html.Hr(),\n",
|
||||
" dash_table.DataTable(\n",
|
||||
" id='datatable-id',\n",
|
||||
" columns=[{\n",
|
||||
" \"name\": i, \n",
|
||||
" \"id\": i, \n",
|
||||
" \"deletable\": False, \n",
|
||||
" \"selectable\": True\n",
|
||||
" } for i in df.columns],\n",
|
||||
" data=df.to_dict('records'),\n",
|
||||
" editable=False,\n",
|
||||
" filter_action=\"native\",\n",
|
||||
" sort_action=\"native\",\n",
|
||||
" sort_mode=\"multi\",\n",
|
||||
" column_selectable=\"single\",\n",
|
||||
" row_selectable=\"single\",\n",
|
||||
" page_action=\"native\",\n",
|
||||
" page_current=0,\n",
|
||||
" page_size=10,\n",
|
||||
" selected_columns=[df.columns[0]]\n",
|
||||
" ),\n",
|
||||
" html.Br(),\n",
|
||||
" html.Hr(),\n",
|
||||
" html.Div(className='row',\n",
|
||||
" style={'display' : 'flex'},\n",
|
||||
" children=[\n",
|
||||
" html.Div(\n",
|
||||
" # show the graph\n",
|
||||
" id='graph-id',\n",
|
||||
" className='col s12 m6',\n",
|
||||
"\n",
|
||||
" ),\n",
|
||||
" html.Div(\n",
|
||||
" # show the map\n",
|
||||
" id='map-id',\n",
|
||||
" className='col s12 m6',\n",
|
||||
" )\n",
|
||||
" ])\n",
|
||||
"])\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 11,
|
||||
"id": "8b29d287",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"@app.callback(\n",
|
||||
" Output('datatable-id', 'data'),\n",
|
||||
" [Input('filter-type', 'value')]\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"def update_dashboard(filter_type):\n",
|
||||
" # define what happens when the filter_type changes\n",
|
||||
" if filter_type == 'water':\n",
|
||||
" query = {\n",
|
||||
" \"breed\": {\"$in\": [\n",
|
||||
" \"Labrador Retriever Mix\", \n",
|
||||
" \"Chesapeake Bay Retriever\", \n",
|
||||
" \"Newfoundland\"]},\n",
|
||||
" \"sex_upon_outcome\": \"Intact Female\",\n",
|
||||
" \"age_upon_outcome_in_weeks\": {\n",
|
||||
" \"$gte\": 26, \n",
|
||||
" \"$lte\": 156}\n",
|
||||
" }\n",
|
||||
" elif filter_type == 'mountain':\n",
|
||||
" query = {\n",
|
||||
" \"breed\": {\"$in\": [\n",
|
||||
" \"German Shepherd\", \n",
|
||||
" \"Alaskan Malamute\", \n",
|
||||
" \"Old English Sheepdog\", \n",
|
||||
" \"Siberian Husky\", \n",
|
||||
" \"Rottweiler\"]},\n",
|
||||
" \"sex_upon_outcome\": \"Intact Male\",\n",
|
||||
" \"age_upon_outcome_in_weeks\": {\n",
|
||||
" \"$gte\": 26, \n",
|
||||
" \"$lte\": 156}\n",
|
||||
" }\n",
|
||||
" elif filter_type == 'disaster':\n",
|
||||
" query = {\n",
|
||||
" \"breed\": {\"$in\": [\n",
|
||||
" \"Doberman Pinscher\", \n",
|
||||
" \"German Shepherd\", \n",
|
||||
" \"Golden Retriever\", \n",
|
||||
" \"Bloodhound\", \n",
|
||||
" \"Rottweiler\"]},\n",
|
||||
" \"sex_upon_outcome\": \"Intact Male\",\n",
|
||||
" \"age_upon_outcome_in_weeks\": {\n",
|
||||
" \"$gte\": 20, \n",
|
||||
" \"$lte\": 300}\n",
|
||||
" }\n",
|
||||
" else:\n",
|
||||
" # leave it unfiltered\n",
|
||||
" query = {}\n",
|
||||
"\n",
|
||||
" # Fetch data using CRUD module and query\n",
|
||||
" filtered_df = pd.DataFrame.from_records(db.read(query))\n",
|
||||
" \n",
|
||||
" # Ensure the '_id' column is not passed to the DataTable to prevent rendering issues\n",
|
||||
" # I readded this and manually drop the _id without errors in case it already doesn't exist\n",
|
||||
" filtered_df.drop(columns=['_id'], inplace=True, errors='ignore')\n",
|
||||
"\n",
|
||||
" # Convert the df to a compatible dictionary format\n",
|
||||
" return filtered_df.to_dict('records')\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 12,
|
||||
"id": "f91a318d",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Display the breed of animal based on quantity represented in the data table\n",
|
||||
"@app.callback(\n",
|
||||
" Output('graph-id', \"children\"),\n",
|
||||
" [Input('datatable-id', \"derived_virtual_data\")]\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"def update_graphs(viewData):\n",
|
||||
" # return nothing if the data is empty\n",
|
||||
" if not viewData:\n",
|
||||
" return None\n",
|
||||
" \n",
|
||||
" # if there are too many breeds, limit with \"other\"\n",
|
||||
" dff = pd.DataFrame.from_dict(viewData)\n",
|
||||
" breed_counts = dff['breed'].value_counts()\n",
|
||||
" top_breeds = breed_counts.head(10)\n",
|
||||
" other_count = breed_counts.iloc[10:].sum()\n",
|
||||
" pie_title = \"Top 10 Breeds\"\n",
|
||||
"\n",
|
||||
" # Check if other_count is greater than 0\n",
|
||||
" if other_count > 0:\n",
|
||||
" # Create a Series for Other to concatenate with top_breeds\n",
|
||||
" other_series = pd.Series({'Other': other_count})\n",
|
||||
" # Use concat to merge the top breeds with the 'Other' series\n",
|
||||
" chart_data = pd.concat([top_breeds, other_series], axis=0)\n",
|
||||
" pie_title = \"Top 10 Breeds + Other\"\n",
|
||||
" else:\n",
|
||||
" # If 'other_count' is 0 or less, only use top_breeds\n",
|
||||
" chart_data = top_breeds\n",
|
||||
"\n",
|
||||
"\n",
|
||||
" chart_data = chart_data.reset_index()\n",
|
||||
" chart_data.columns = ['Breed', 'Count']\n",
|
||||
" \n",
|
||||
" # Generate a pie chart\n",
|
||||
" fig = px.pie(chart_data, values='Count', names='Breed', title=pie_title)\n",
|
||||
" \n",
|
||||
" return dcc.Graph(figure=fig)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 13,
|
||||
"id": "4c3537de",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Highlight a selected column\n",
|
||||
"@app.callback(\n",
|
||||
" Output('datatable-id', 'style_data_conditional'),\n",
|
||||
" [Input('datatable-id', 'selected_columns')]\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"def update_styles(selected_columns):\n",
|
||||
" return [{\n",
|
||||
" 'if': { 'column_id': i },\n",
|
||||
" 'background_color': '#D2F3FF'\n",
|
||||
" } for i in selected_columns]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 14,
|
||||
"id": "d1c440a0",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Update the geo-location chart with the selected item\n",
|
||||
"@app.callback(\n",
|
||||
" Output('map-id', \"children\"),\n",
|
||||
" [Input('datatable-id', \"derived_virtual_data\"),\n",
|
||||
" Input('datatable-id', \"derived_virtual_selected_rows\")]\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"def update_map(viewData, index):\n",
|
||||
" # If viewData is empty or index is not set \n",
|
||||
" if viewData is None or not index:\n",
|
||||
" # Center on Austin, TX\n",
|
||||
" return [\n",
|
||||
" dl.Map(\n",
|
||||
" style={\n",
|
||||
" 'width': '1000px', \n",
|
||||
" 'height': '500px'\n",
|
||||
" },\n",
|
||||
" center=[30.66, -97.40], \n",
|
||||
" zoom=10, \n",
|
||||
" children=[dl.TileLayer(id=\"base-layer-id\")])\n",
|
||||
" ]\n",
|
||||
" \n",
|
||||
" # Convert viewData to DataFrame\n",
|
||||
" dff = pd.DataFrame.from_dict(viewData)\n",
|
||||
" row = index[0]\n",
|
||||
"\n",
|
||||
" # Latitude and longitude for the selected item\n",
|
||||
" lat = dff.iloc[row, dff.columns.get_loc('location_lat')]\n",
|
||||
" lon = dff.iloc[row, dff.columns.get_loc('location_long')]\n",
|
||||
"\n",
|
||||
" # Update map centering dynamically based on the selected item's location\n",
|
||||
" return [\n",
|
||||
" dl.Map(\n",
|
||||
" style={\n",
|
||||
" 'width': '1000px', \n",
|
||||
" 'height': '500px'\n",
|
||||
" }, \n",
|
||||
" # reposition the map\n",
|
||||
" center=[lat, lon], \n",
|
||||
" zoom=10, \n",
|
||||
" children=[\n",
|
||||
" dl.TileLayer(id=\"base-layer-id\"),\n",
|
||||
" dl.Marker(\n",
|
||||
" # drop a point on the map\n",
|
||||
" position=[lat, lon], \n",
|
||||
" children=[\n",
|
||||
" dl.Tooltip(\n",
|
||||
" # show a tooltip on mouseover\n",
|
||||
" dff.iloc[row, dff.columns.get_loc('breed')]\n",
|
||||
" ),\n",
|
||||
" dl.Popup([\n",
|
||||
" # show a popup of the animal's name\n",
|
||||
" html.H1(\"Animal Name\"),\n",
|
||||
" html.P(dff.iloc[row, dff.columns.get_loc('name')]) \n",
|
||||
" ]) \n",
|
||||
" ])\n",
|
||||
" ])\n",
|
||||
" ]\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 15,
|
||||
"id": "eefb074c",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Dash app running on http://127.0.0.1:30088/\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"app.run_server(debug=True)"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.9.12"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
BIN
logo.png
Normal file
BIN
logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 98 KiB |
Loading…
Add table
Add a link
Reference in a new issue