From 43dc93ff5cf88c151ea7aa41aba9f8549115fffa Mon Sep 17 00:00:00 2001 From: liam mall <29150314+liamcmall@users.noreply.github.com> Date: Mon, 1 Apr 2024 20:18:30 +0000 Subject: [PATCH 01/11] Still need to fix MongoDB connection erghhh --- app/data.py | 146 +++++++++++++++++++++++++++++++++++++++++++++++++--- app/main.py | 9 +++- 2 files changed, 147 insertions(+), 8 deletions(-) diff --git a/app/data.py b/app/data.py index 61e69e5..2b5d5cd 100644 --- a/app/data.py +++ b/app/data.py @@ -1,25 +1,159 @@ from os import getenv - +import random +from datetime import datetime +import math from certifi import where from dotenv import load_dotenv from MonsterLab import Monster from pandas import DataFrame from pymongo import MongoClient +from typing import Dict, Iterable, Iterator + +ranks = ['Private', 'Sergeant', 'Lieutenant', 'Captain', 'Commander'] +rank_probabilities = [round(random.uniform(0.0,0.1),2), + round(random.uniform(0.1,0.15),2), + round(random.uniform(0.2,0.25),2), + round(random.uniform(0.25,0.3),2), + round(random.uniform(0.3,0.35),2)] + +clone_types = ['Standard','Recon', 'Heavy', 'Commando', 'ARC Trooper'] +clone_type_probabilities = [round(random.uniform(0.0,0.1),2), + round(random.uniform(0.1,0.15),2), + round(random.uniform(0.2,0.25),2), + round(random.uniform(0.25,0.3),2), + round(random.uniform(0.3,0.35),2)] + +asssigned_weapons = ["DC-15A Blaster Rifle", + "DC-15X Sniper Rifle", + "DC-17m Blaster Rifle", + "DC-15S Blaster Carbine", + "WESTAR-M5 Blaster Rifle"] + +assigned_general = ['General Mace Windu', "General Plo Koon", 'General Yoda', 'General Kenobi', 'General Skywalker',] +assigned_general_probabilities = [round(random.uniform(0.0,0.1),2), + round(random.uniform(0.1,0.15),2), + round(random.uniform(0.2,0.25),2), + round(random.uniform(0.25,0.3),2), + round(random.uniform(0.3,0.35),2)] class Database: + def __init__(self, collection: str): + self.db = MongoDB(collection) def seed(self, amount): - pass + data = self.generate_clone_trooper(amount) + self.db.create_many(data) def reset(self): - pass + self.db.delete_all() def count(self) -> int: - pass + return self.db.count_documents() def dataframe(self) -> DataFrame: - pass + return self.db.to_dataframe() def html_table(self) -> str: - pass + return self.db.to_html_table() + + @staticmethod + def generate_clone_trooper(n): + data = [] + for _ in range(n): + clone_trooper_name = f"CT-{random.randint(0, 999999):06}" + # ... rest of your code here ... + data.append({ + "CT ID": clone_trooper_name, + 'Clone Type': clone_type, + 'Rank': rank, + 'Assigned Weapon': assigned_weapon, + 'Health': health, + 'Energy': energy, + 'Success Percentage': success_percentage, + 'Assigned General': general, + 'Check In Time': datetime.now().strftime('%Y-%m-%d %H:%M:%S') + }) + return data + + +class MongoDB: + load_dotenv() + database = MongoClient(getenv("DB_URL") + "&tls=true&tlsInsecure=true")["Database"] + # load_dotenv() + # database = MongoClient(getenv("DB_URL"), tlsCAFile=where())["Database"] + + def __init__(self, collection: str): + self.collection = self.database[collection] + + def create_one(self, record: Dict) -> bool: + return self.collection.insert_one(record).acknowledged + + def read_one(self, query: Dict) -> Dict: + return self.collection.find_one(query, {"_id": False}) + + def update_one(self, query: Dict, update: Dict) -> bool: + return self.collection.update_one(query, {"$set": update}).acknowledged + + def delete_one(self, query: Dict) -> bool: + return self.collection.delete_one(query).acknowledged + + def create_many(self, records: Iterable[Dict]) -> bool: + return self.collection.insert_many(records).acknowledged + + def read_many(self, query: Dict) -> Iterator[Dict]: + return self.collection.find(query, {"_id": False}) + + def update_many(self, query: Dict, update: Dict) -> bool: + return self.collection.update_many(query, {"$set": update}).acknowledged + + def delete_many(self, query: Dict) -> bool: + return self.collection.delete_many(query).acknowledged + + def reset(self): + self.db.delete_all() + + def count(self) -> int: + return self.db.count_documents() + + def dataframe(self) -> DataFrame: + return self.db.to_dataframe() + + def html_table(self) -> str: + return self.db.to_html_table() + + def count_documents(self) -> int: + return self.collection.count_documents({}) + +# if __name__ == '__main__': +# db = MongoDB("Collection") +# db.create_many({"Value": randrange(1, 100)} for _ in range(10)) +# print(DataFrame(db.read_many({}))) + +# import unittest +# from data import Database + +# class TestDatabase(unittest.TestCase): +# def setUp(self): +# self.db = Database('test_collection') + +# def test_seed(self): +# self.db.seed(10) +# self.assertEqual(self.db.count(), 10) + +# def test_reset(self): +# self.db.reset() +# self.assertEqual(self.db.count(), 0) + +# def test_dataframe(self): +# self.db.seed(10) +# df = self.db.dataframe() +# self.assertEqual(len(df), 10) + +# def test_html_table(self): +# self.db.seed(10) +# html = self.db.html_table() +# self.assertIsNotNone(html) + +# if __name__ == '__main__': +# unittest.main() \ No newline at end of file diff --git a/app/main.py b/app/main.py index 1f9e0b0..2996dd7 100644 --- a/app/main.py +++ b/app/main.py @@ -5,12 +5,14 @@ from MonsterLab import Monster from flask import Flask, render_template, request from pandas import DataFrame +from datetime import datetime from app.data import Database +from app.data import MongoDB from app.graph import chart from app.machine import Machine -SPRINT = 0 +SPRINT = 1 APP = Flask(__name__) @@ -28,7 +30,10 @@ def home(): def data(): if SPRINT < 1: return render_template("data.html") - db = Database() + # for personal reasons + collection_name = "Collection_" + datetime.now().strftime("%Y%m%d%H%M%S") + db = Database(collection_name) + # db = MongoDB(collection_name) return render_template( "data.html", count=db.count(), From 9982bc8fdf5921823bd01be3a97149cc0a43fc4e Mon Sep 17 00:00:00 2001 From: liam mall <29150314+liamcmall@users.noreply.github.com> Date: Thu, 4 Apr 2024 20:50:00 +0000 Subject: [PATCH 02/11] Moved from MongoDB to ElephantSQL. Test --- .vscode/settings.json | 3 + app/data.py | 171 +++++++++++++++++++--------------------- app/data2.py | 163 ++++++++++++++++++++++++++++++++++++++ app/graph.py | 1 + app/main.py | 9 +-- app/templates/data.html | 4 +- 6 files changed, 254 insertions(+), 97 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 app/data2.py diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..457f44d --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "python.analysis.typeCheckingMode": "basic" +} \ No newline at end of file diff --git a/app/data.py b/app/data.py index 2b5d5cd..f4d907b 100644 --- a/app/data.py +++ b/app/data.py @@ -1,14 +1,23 @@ -from os import getenv -import random +# Standard library imports from datetime import datetime +from os import getenv import math +import random +import unittest + +# Misc imports from certifi import where from dotenv import load_dotenv -from MonsterLab import Monster -from pandas import DataFrame from pymongo import MongoClient +from pymongo.errors import ServerSelectionTimeoutError +import pandas as pd + +# Typing from typing import Dict, Iterable, Iterator + +# List and Etc. + ranks = ['Private', 'Sergeant', 'Lieutenant', 'Captain', 'Commander'] rank_probabilities = [round(random.uniform(0.0,0.1),2), round(random.uniform(0.1,0.15),2), @@ -23,7 +32,7 @@ round(random.uniform(0.25,0.3),2), round(random.uniform(0.3,0.35),2)] -asssigned_weapons = ["DC-15A Blaster Rifle", +assigned_weapons = ["DC-15A Blaster Rifle", "DC-15X Sniper Rifle", "DC-17m Blaster Rifle", "DC-15S Blaster Carbine", @@ -38,31 +47,65 @@ class Database: - def __init__(self, collection: str): - self.db = MongoDB(collection) + load_dotenv() + + def __init__(self, collection_name: str): + db_url = getenv("DB_URL") + self.client = MongoClient(db_url, + tlsCAFile=where(), + tls=True, + tlsAllowInvalidCertificates=True)["MainDatabase"] + self.collection = self.client[collection_name] def seed(self, amount): data = self.generate_clone_trooper(amount) - self.db.create_many(data) - - def reset(self): - self.db.delete_all() + self.collection.insert_many(data) + + def reset(self) -> int: + return self.collection.delete_many({}).deleted_count def count(self) -> int: - return self.db.count_documents() + return self.collection.count_documents({}) - def dataframe(self) -> DataFrame: - return self.db.to_dataframe() + def to_dataframe(self) -> pd.DataFrame: + return pd.DataFrame(list(self.collection.find())) - def html_table(self) -> str: - return self.db.to_html_table() + def to_html_table(self) -> str: + df = self.to_dataframe() + return df.to_html() + # Generate a random clone trooper! @staticmethod def generate_clone_trooper(n): data = [] for _ in range(n): clone_trooper_name = f"CT-{random.randint(0, 999999):06}" - # ... rest of your code here ... + + # Select a clone type and its probability + clone_type_index = random.choices(range(len(clone_types)), clone_type_probabilities, k=1)[0] + clone_type = clone_types[clone_type_index] + clone_type_probability = clone_type_probabilities[clone_type_index] + + # Select a rank and its probability + rank_index = random.choices(range(len(ranks)), rank_probabilities, k=1)[0] + rank = ranks[rank_index] + rank_probability = rank_probabilities[rank_index] + + # Weapon Selected + assigned_weapon = random.choice(assigned_weapons) + + # Random health and energy + health = random.randint(3, 9) + energy = random.randint(2, 6) + + # Select a general and its probability + general_index = random.choices(range(len(assigned_general)), assigned_general_probabilities, k=1)[0] + general = assigned_general[general_index] + general_probability = assigned_general_probabilities[general_index] + + # Calculated the success percentage. But also included a skew towards healthier clones + success_percentage = round(sum([clone_type_probability, rank_probability, general_probability,math.log10(health)-0.80]), 2) + data.append({ "CT ID": clone_trooper_name, 'Clone Type': clone_type, @@ -77,83 +120,33 @@ def generate_clone_trooper(n): return data -class MongoDB: - load_dotenv() - database = MongoClient(getenv("DB_URL") + "&tls=true&tlsInsecure=true")["Database"] - # load_dotenv() - # database = MongoClient(getenv("DB_URL"), tlsCAFile=where())["Database"] - - def __init__(self, collection: str): - self.collection = self.database[collection] - - def create_one(self, record: Dict) -> bool: - return self.collection.insert_one(record).acknowledged - - def read_one(self, query: Dict) -> Dict: - return self.collection.find_one(query, {"_id": False}) - - def update_one(self, query: Dict, update: Dict) -> bool: - return self.collection.update_one(query, {"$set": update}).acknowledged - - def delete_one(self, query: Dict) -> bool: - return self.collection.delete_one(query).acknowledged - - def create_many(self, records: Iterable[Dict]) -> bool: - return self.collection.insert_many(records).acknowledged - - def read_many(self, query: Dict) -> Iterator[Dict]: - return self.collection.find(query, {"_id": False}) - - def update_many(self, query: Dict, update: Dict) -> bool: - return self.collection.update_many(query, {"$set": update}).acknowledged - - def delete_many(self, query: Dict) -> bool: - return self.collection.delete_many(query).acknowledged - - def reset(self): - self.db.delete_all() - - def count(self) -> int: - return self.db.count_documents() - - def dataframe(self) -> DataFrame: - return self.db.to_dataframe() - - def html_table(self) -> str: - return self.db.to_html_table() - - def count_documents(self) -> int: - return self.collection.count_documents({}) +## TESTING CENTER ### -# if __name__ == '__main__': -# db = MongoDB("Collection") -# db.create_many({"Value": randrange(1, 100)} for _ in range(10)) -# print(DataFrame(db.read_many({}))) +class TestMongoDBConnection(unittest.TestCase): -# import unittest -# from data import Database + def setUp(self): + db_url = getenv("DB_URL") + # Set serverSelectionTimeoutMS to 5000 milliseconds (5 second) + self.client = MongoClient(db_url, + tlsCAFile=where(), + tls=True, + tlsAllowInvalidCertificates=True, + serverSelectionTimeoutMS=5000) + self.db_class = Database("test_collection") -# class TestDatabase(unittest.TestCase): -# def setUp(self): -# self.db = Database('test_collection') -# def test_seed(self): -# self.db.seed(10) -# self.assertEqual(self.db.count(), 10) + def test_connection(self): + try: + self.client.admin.command('ismaster') + except ServerSelectionTimeoutError: + self.fail("MongoDB connection failed.") -# def test_reset(self): -# self.db.reset() -# self.assertEqual(self.db.count(), 0) + def test_generate_clone_trooper(self): + n = 5 + result = self.db_class.generate_clone_trooper(n) + self.assertEqual(len(result), n) -# def test_dataframe(self): -# self.db.seed(10) -# df = self.db.dataframe() -# self.assertEqual(len(df), 10) -# def test_html_table(self): -# self.db.seed(10) -# html = self.db.html_table() -# self.assertIsNotNone(html) -# if __name__ == '__main__': -# unittest.main() \ No newline at end of file +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff --git a/app/data2.py b/app/data2.py new file mode 100644 index 0000000..1588914 --- /dev/null +++ b/app/data2.py @@ -0,0 +1,163 @@ +# Standard library imports +from datetime import datetime +from os import getenv +import math +import random +import unittest + +from dotenv import load_dotenv +import pandas as pd + +import psycopg2 + +# Typing +from typing import Dict, Iterable, Iterator, List, Tuple + +# List and Etc. + +ranks = ['Private', 'Sergeant', 'Lieutenant', 'Captain', 'Commander'] +rank_probabilities = [round(random.uniform(0.0,0.1),2), + round(random.uniform(0.1,0.15),2), + round(random.uniform(0.2,0.25),2), + round(random.uniform(0.25,0.3),2), + round(random.uniform(0.3,0.35),2)] + +clone_types = ['Standard','Recon', 'Heavy', 'Commando', 'ARC Trooper'] +clone_type_probabilities = [round(random.uniform(0.0,0.1),2), + round(random.uniform(0.1,0.15),2), + round(random.uniform(0.2,0.25),2), + round(random.uniform(0.25,0.3),2), + round(random.uniform(0.3,0.35),2)] + +assigned_weapons = ["DC-15A Blaster Rifle", + "DC-15X Sniper Rifle", + "DC-17m Blaster Rifle", + "DC-15S Blaster Carbine", + "WESTAR-M5 Blaster Rifle"] + +assigned_generals = ['General Mace Windu', "General Plo Koon", 'General Yoda', 'General Kenobi', 'General Skywalker',] +assigned_general_probabilities = [round(random.uniform(0.0,0.1),2), + round(random.uniform(0.1,0.15),2), + round(random.uniform(0.2,0.25),2), + round(random.uniform(0.25,0.3),2), + round(random.uniform(0.3,0.35),2)] + + +class Database: + load_dotenv() + + def __init__(self): + self.conn = psycopg2.connect( + dbname=getenv("DB_NAME"), + user=getenv("DB_USER"), + password=getenv("DB_PASSWORD"), + host=getenv("DB_HOST") + ) + self.cur = self.conn.cursor() + + def create_table(self): + self.cur.execute(""" + CREATE TABLE IF NOT EXISTS clone_troopers ( + ct_id SERIAL PRIMARY KEY, + clone_type VARCHAR(50), + rank VARCHAR(50), + assigned_weapon VARCHAR(50), + health INTEGER, + energy INTEGER, + success_percentage NUMERIC, + assigned_general VARCHAR(50), + check_in_time TIMESTAMP + ) + """) + self.conn.commit() + + def seed(self, amount): + data = self.generate_clone_trooper(amount) + for row in data: + self.cur.execute(""" + INSERT INTO clone_troopers (clone_type, rank, assigned_weapon, health, energy, success_percentage, assigned_general, check_in_time) + VALUES (%s, %s, %s, %s, %s, %s, %s, %s) + """, row) + self.conn.commit() + + def reset(self) -> int: + self.cur.execute("DELETE FROM clone_troopers") + self.conn.commit() + return self.cur.rowcount + + def count(self) -> int: + self.cur.execute("SELECT COUNT(*) FROM clone_troopers") + return self.cur.fetchone()[0] + + def dataframe(self) -> pd.DataFrame: + self.cur.execute("SELECT * FROM clone_troopers") + rows = self.cur.fetchall() + columns = [desc[0] for desc in self.cur.description] + return pd.DataFrame(rows, columns=columns) + + def html_table(self) -> str: + df = self.to_dataframe() + return df.to_html() + + # Generate a random clone trooper! + @staticmethod + def generate_clone_trooper(n: int) -> List[Tuple]: + data = [] + for _ in range(n): + clone_type = random.choices(clone_types, clone_type_probabilities)[0] + rank = random.choices(ranks, rank_probabilities)[0] + assigned_weapon = random.choice(assigned_weapons) + health = random.randint(3, 9) + energy = random.randint(2, 6) + assigned_general = random.choices(assigned_generals, assigned_general_probabilities)[0] + success_percentage = round(sum([random.uniform(0, 0.35), math.log10(health)-0.80]), 2) + check_in_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S') + data.append((clone_type, rank, assigned_weapon, health, energy, success_percentage, assigned_general, check_in_time)) + return data + +class TestDatabase(unittest.TestCase): + def setUp(self): + self.db = Database() # Adjust this to match your setup + + def test_connection(self): + self.assertIsNotNone(self.db.conn) + + def test_seed(self): + self.db.reset() + self.db.seed(10) + self.assertEqual(self.db.count(), 10) + + def test_reset(self): + self.db.reset() + self.db.seed(10) + self.db.reset() + self.assertEqual(self.db.count(), 0) + + def test_count(self): + self.db.reset() + self.db.seed(5) + self.assertEqual(self.db.count(), 5) + + def test_dataframe(self): + self.db.reset() + self.db.seed(5) + df = self.db.dataframe() + self.assertIsInstance(df, DataFrame) + self.assertEqual(len(df), 5) + + def test_html_table(self): + self.db.reset() + self.db.seed(5) + html = self.db.html_table() + self.assertIsInstance(html, str) + self.assertTrue(' Chart: pass diff --git a/app/main.py b/app/main.py index 2996dd7..5ed867e 100644 --- a/app/main.py +++ b/app/main.py @@ -1,14 +1,12 @@ from base64 import b64decode import os -from Fortuna import random_int, random_float from MonsterLab import Monster from flask import Flask, render_template, request from pandas import DataFrame from datetime import datetime -from app.data import Database -from app.data import MongoDB +from app.data2 import Database from app.graph import chart from app.machine import Machine @@ -31,9 +29,8 @@ def data(): if SPRINT < 1: return render_template("data.html") # for personal reasons - collection_name = "Collection_" + datetime.now().strftime("%Y%m%d%H%M%S") - db = Database(collection_name) - # db = MongoDB(collection_name) + # collection_name = "Collection_" + datetime.now().strftime("%Y%m%d%H%M%S") + db = Database() return render_template( "data.html", count=db.count(), diff --git a/app/templates/data.html b/app/templates/data.html index e00c476..50dc544 100644 --- a/app/templates/data.html +++ b/app/templates/data.html @@ -1,6 +1,6 @@ {% extends "layout.html" %} {% block content %} -

Bandersnatch Data

-

Monster Count: {{ count | safe }}

+

Grand Army of the Republic Trooper Database

+

Clone Troopeer Count: {{ count | safe }}

{{ table | safe }} {% endblock %} From 8dd84801c97191bb7c50c9c0b8671915a2938af7 Mon Sep 17 00:00:00 2001 From: liam mall <29150314+liamcmall@users.noreply.github.com> Date: Fri, 5 Apr 2024 05:14:41 +0000 Subject: [PATCH 03/11] All done with the database now I need to make it pep 8 compliant and work on the graphing --- app/data.py | 3 +-- app/data2.py | 10 +++++----- app/graph.py | 16 ++++++++++++---- app/main.py | 2 +- app/templates/home.html | 4 ++-- requirements.txt | 1 + 6 files changed, 22 insertions(+), 14 deletions(-) diff --git a/app/data.py b/app/data.py index f4d907b..1b549f1 100644 --- a/app/data.py +++ b/app/data.py @@ -79,7 +79,6 @@ def to_html_table(self) -> str: def generate_clone_trooper(n): data = [] for _ in range(n): - clone_trooper_name = f"CT-{random.randint(0, 999999):06}" # Select a clone type and its probability clone_type_index = random.choices(range(len(clone_types)), clone_type_probabilities, k=1)[0] @@ -103,7 +102,7 @@ def generate_clone_trooper(n): general = assigned_general[general_index] general_probability = assigned_general_probabilities[general_index] - # Calculated the success percentage. But also included a skew towards healthier clones + # Calculated the success percentage. But also included a skew towards healthier clones. success_percentage = round(sum([clone_type_probability, rank_probability, general_probability,math.log10(health)-0.80]), 2) data.append({ diff --git a/app/data2.py b/app/data2.py index 1588914..17a65fa 100644 --- a/app/data2.py +++ b/app/data2.py @@ -76,7 +76,7 @@ def seed(self, amount): for row in data: self.cur.execute(""" INSERT INTO clone_troopers (clone_type, rank, assigned_weapon, health, energy, success_percentage, assigned_general, check_in_time) - VALUES (%s, %s, %s, %s, %s, %s, %s, %s) + VALUES ( %s, %s, %s, %s, %s, %s, %s, %s) """, row) self.conn.commit() @@ -96,7 +96,7 @@ def dataframe(self) -> pd.DataFrame: return pd.DataFrame(rows, columns=columns) def html_table(self) -> str: - df = self.to_dataframe() + df = self.dataframe() return df.to_html() # Generate a random clone trooper! @@ -117,7 +117,7 @@ def generate_clone_trooper(n: int) -> List[Tuple]: class TestDatabase(unittest.TestCase): def setUp(self): - self.db = Database() # Adjust this to match your setup + self.db = Database() def test_connection(self): self.assertIsNotNone(self.db.conn) @@ -142,7 +142,7 @@ def test_dataframe(self): self.db.reset() self.db.seed(5) df = self.db.dataframe() - self.assertIsInstance(df, DataFrame) + self.assertIsInstance(df, pd.DataFrame) self.assertEqual(len(df), 5) def test_html_table(self): @@ -154,7 +154,7 @@ def test_html_table(self): self.db.reset() html = self.db.html_table() - self.assertIsNone(html) + self.assertTrue('\n ' in html) # Check if the table body is empty if __name__ == '__main__': unittest.main() diff --git a/app/graph.py b/app/graph.py index 2213b40..c8acc3c 100644 --- a/app/graph.py +++ b/app/graph.py @@ -1,6 +1,14 @@ -from altair import Chart +# Imports +import pandas as pd +import math +import random +from datetime import datetime +import plotly.express as px +from app.data2 import Database # Import the Database class +db = Database() +df = db.dataframe() - -def chart(df, x, y, target) -> Chart: - pass +def chart(df, x, y, target): + fig = px.box(df, x=x, y=y, title=target) + fig.show() diff --git a/app/main.py b/app/main.py index 5ed867e..3943f68 100644 --- a/app/main.py +++ b/app/main.py @@ -43,7 +43,7 @@ def view(): if SPRINT < 2: return render_template("view.html") db = Database() - options = ["Level", "Health", "Energy", "Sanity", "Rarity"] + options = ["clone_type", "rank""health", "assigned_general", "success_percentage"] x_axis = request.values.get("x_axis") or options[1] y_axis = request.values.get("y_axis") or options[2] target = request.values.get("target") or options[4] diff --git a/app/templates/home.html b/app/templates/home.html index ae82ee4..747dd2a 100644 --- a/app/templates/home.html +++ b/app/templates/home.html @@ -17,8 +17,8 @@

Tech Stack

  • Templates: Jinja2
  • Structure: HTML5
  • Styling: CSS3
  • -
  • Database: MongoDB
  • -
  • Graphs: Altair
  • +
  • Database: ElephantSQL
  • +
  • Graphs: Plotly
  • Machine Learning: Scikit
  • Example Monster

    diff --git a/requirements.txt b/requirements.txt index a23d75a..4f6203f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -13,3 +13,4 @@ pymongo[srv] python-dotenv scikit-learn scipy +psycopg2 From 2566d0df1d4dee984f0bdaa95d92ca5769524d93 Mon Sep 17 00:00:00 2001 From: liam mall <29150314+liamcmall@users.noreply.github.com> Date: Fri, 5 Apr 2024 05:44:46 +0000 Subject: [PATCH 04/11] trying to adjust the original code to adapt plotly --- app/graph.py | 25 +++++++++++++++++++++++-- app/main.py | 35 +++++++++++++++++++++++++++++++---- 2 files changed, 54 insertions(+), 6 deletions(-) diff --git a/app/graph.py b/app/graph.py index c8acc3c..282716e 100644 --- a/app/graph.py +++ b/app/graph.py @@ -4,11 +4,32 @@ import random from datetime import datetime import plotly.express as px -from app.data2 import Database # Import the Database class +from data2 import Database +import plotly.io as pio +import unittest db = Database() df = db.dataframe() def chart(df, x, y, target): fig = px.box(df, x=x, y=y, title=target) - fig.show() + return fig + + +class TestChart(unittest.TestCase): + def test_chart(self): + # Creates a rando Dataframe + df = pd.DataFrame({ + 'clone_type': ['A', 'B', 'C'], + 'rank': [1, 2, 3], + 'health': [100, 200, 300], + 'assigned_general': ['X', 'Y', 'Z'], + 'success_percentage': [0.5, 0.6, 0.7] + }) + + fig = chart(df, 'rank', 'health', 'Test') + + self.assertEqual(type(fig).__name__, 'Figure') + +if __name__ == '__main__': + unittest.main() diff --git a/app/main.py b/app/main.py index 3943f68..23745b7 100644 --- a/app/main.py +++ b/app/main.py @@ -5,12 +5,13 @@ from flask import Flask, render_template, request from pandas import DataFrame from datetime import datetime +import plotly.io as pio from app.data2 import Database from app.graph import chart from app.machine import Machine -SPRINT = 1 +SPRINT = 2 APP = Flask(__name__) @@ -38,12 +39,36 @@ def data(): ) +# @APP.route("/view", methods=["GET", "POST"]) +# def view(): +# if SPRINT < 2: +# return render_template("view.html") +# db = Database() +# options = ["clone_type", "rank","health", "assigned_general", "success_percentage"] +# x_axis = request.values.get("x_axis") or options[1] +# y_axis = request.values.get("y_axis") or options[2] +# target = request.values.get("target") or options[4] +# graph = chart( +# df=db.dataframe(), +# x=x_axis, +# y=y_axis, +# target=target, +# ).to_json() +# return render_template( +# "view.html", +# options=options, +# x_axis=x_axis, +# y_axis=y_axis, +# target=target, +# count=db.count(), +# graph=graph, +# ) @APP.route("/view", methods=["GET", "POST"]) def view(): if SPRINT < 2: return render_template("view.html") db = Database() - options = ["clone_type", "rank""health", "assigned_general", "success_percentage"] + options = ["clone_type", "rank","health", "assigned_general", "success_percentage"] x_axis = request.values.get("x_axis") or options[1] y_axis = request.values.get("y_axis") or options[2] target = request.values.get("target") or options[4] @@ -52,7 +77,8 @@ def view(): x=x_axis, y=y_axis, target=target, - ).to_json() + ) + graph_html = pio.to_html(graph, full_html=False) return render_template( "view.html", options=options, @@ -60,10 +86,11 @@ def view(): y_axis=y_axis, target=target, count=db.count(), - graph=graph, + graph=graph_html, ) + @APP.route("/model", methods=["GET", "POST"]) def model(): if SPRINT < 3: From f29a2edf5bec7eccf59b57c46287357da3f4bdbb Mon Sep 17 00:00:00 2001 From: liam mall <29150314+liamcmall@users.noreply.github.com> Date: Fri, 5 Apr 2024 05:50:02 +0000 Subject: [PATCH 05/11] Adjusted some code and tried to correctly format. --- app/graph.py | 2 +- app/templates/view.html | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/graph.py b/app/graph.py index 282716e..0a28b71 100644 --- a/app/graph.py +++ b/app/graph.py @@ -4,7 +4,7 @@ import random from datetime import datetime import plotly.express as px -from data2 import Database +from app.data2 import Database import plotly.io as pio import unittest diff --git a/app/templates/view.html b/app/templates/view.html index 597366c..a796470 100644 --- a/app/templates/view.html +++ b/app/templates/view.html @@ -7,8 +7,8 @@ {% endblock %} {% block content %} -

    Bandersnatch Viewer

    -

    Monster Count: {{ count | safe }}

    +

    Clone Trooper Data Viewer

    +

    Clone Trooper Count: {{ count | safe }}

    Bandersnatch Model

    +

    Clone Trooper Prediction Model

    {{ info | safe }}

    -

    Prediction Basis

    +

    Prediction




    -


    - +

    Prediction: {{ prediction }} -
    - Confidence: {{ confidence }}

    {% endblock %}