Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hoke 1/172024 #9

Open
wants to merge 17 commits into
base: main
Choose a base branch
from
26 changes: 26 additions & 0 deletions Pipfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"

[packages]
altair = "*"
certifi = "*"
flask = "*"
fortuna = "*"
gunicorn = "*"
jinja2 = "*"
joblib = "*"
jupyter = "*"
numpy = "*"
monsterlab = "*"
pandas = "*"
pymongo = {extras = ["srv"], version = "*"}
python-dotenv = "*"
scikit-learn = "*"
scipy = "*"

[dev-packages]

[requires]
python_version = "3.11"
60 changes: 52 additions & 8 deletions app/data.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,69 @@
from os import getenv

from certifi import where
from dotenv import load_dotenv
from MonsterLab import Monster
import pandas as pd
from pandas import DataFrame
from pymongo import MongoClient
from pymongo.mongo_client import MongoClient


class Database:
"""
A class that is used to generate a randomized database of
monsters with different valued columns both numerical and text.
"""


load_dotenv()

database = MongoClient(getenv("CONNECTION_STR"),
tlsCAFile=where())["Database"]

def __init__(self, collection: str):
"""
Establishes a connection with our database.
"""
self.collection = self.database[collection]

def seed(self, amount):
pass
def seed(self, amount = 1000):
"""
Correctly inserts the specified number of monsters into the
collection.
"""
Monsters = [Monster().to_dict() for _ in range(amount)]
MonsterBook = self.collection.insert_many(Monsters)
return f"{MonsterBook.acknowledged}"

def reset(self):
pass
"""
Correctly deletes all monsters from the collection.
"""
return f"{self.collection.delete_many(filter={}).acknowledged}"

def count(self) -> int:
pass
"""
Correctly returns the number of monsters in the
collection.
"""
return self.collection.count_documents({})

def dataframe(self) -> DataFrame:
pass
"""
Correctly returns a DataFrame containing all monsters in
the collection.
"""
return pd.DataFrame(list(self.collection.find({}, {"_id":False})))

def html_table(self) -> str:
pass
"""
Correctly returns an HTML table representation of the
DataFrame or None if the collection is empty.
"""
if self.count() > 0:
return self.dataframe().to_html(index=False)
else:
return None

if __name__ == '__main__':
db = Database("Collection")
db.seed()
24 changes: 21 additions & 3 deletions app/graph.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,23 @@
from altair import Chart
from altair import Chart, Tooltip
from pandas import DataFrame
from app.data import Database

def chart(df: DataFrame, x: str, y: str, target: str) -> Chart:
"""
Creates a chart based on our information from our data.py file.
"""
graph = Chart(
df,
title=f"{x} by {y} for {target}",
background = "gray"
).mark_circle(size=100).encode(
x=x,
y=y,
color=target,
tooltip=Tooltip(df.columns.to_list())
)
return graph

def chart(df, x, y, target) -> Chart:
pass
if __name__ == '__main__':
collection_graph = Database("Collection")
collection_graph.seed()
40 changes: 29 additions & 11 deletions app/machine.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,35 @@
class Machine:
from pandas import DataFrame
from sklearn.ensemble import RandomForestClassifier
import joblib
from datetime import datetime


def __init__(self, df):
pass
class Machine:
"""
This class should take in features from our Monsterbook and return a
prediction for the rarity of the monster based on input factors of
the other attributes of the monsters.
"""

def __init__(self, df: DataFrame):
self.name = "Random Forest Classifier"
target = df["Rarity"]
features = df.drop(columns=["Rarity"])
self.model = RandomForestClassifier()
self.model.fit(features, target)

def __call__(self, feature_basis):
pass
def __call__(self, pred_basis: DataFrame):
prediction, *_ = self.model.predict(pred_basis)
probability, *_ = self.model.predict_proba(pred_basis)
return prediction, max(probability)

def save(self, filepath):
pass

@staticmethod
def open(filepath):
pass
joblib.dump(self.model, filepath)

def open(self, filepath):
loaded_model = joblib.load(filepath)
return loaded_model

def info(self):
pass
ret_str = f"""Base Model: {self.name}\nTimestamp: {datetime.now()}"""
return ret_str
13 changes: 7 additions & 6 deletions app/main.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from base64 import b64decode
import os

from Fortuna import random_int, random_float
from MonsterLab import Monster
from flask import Flask, render_template, request
Expand All @@ -10,7 +9,7 @@
from app.graph import chart
from app.machine import Machine

SPRINT = 0
SPRINT = 3
APP = Flask(__name__)


Expand All @@ -28,7 +27,7 @@ def home():
def data():
if SPRINT < 1:
return render_template("data.html")
db = Database()
db = Database("Collection")
return render_template(
"data.html",
count=db.count(),
Expand All @@ -40,7 +39,7 @@ def data():
def view():
if SPRINT < 2:
return render_template("view.html")
db = Database()
db = Database("Collection")
options = ["Level", "Health", "Energy", "Sanity", "Rarity"]
x_axis = request.values.get("x_axis") or options[1]
y_axis = request.values.get("y_axis") or options[2]
Expand All @@ -66,15 +65,17 @@ def view():
def model():
if SPRINT < 3:
return render_template("model.html")
db = Database()
db = Database("Collection")
options = ["Level", "Health", "Energy", "Sanity", "Rarity"]
filepath = os.path.join("app", "model.joblib")
if not os.path.exists(filepath):
df = db.dataframe()
machine = Machine(df[options])
machine.save(filepath)
else:
machine = Machine.open(filepath)
df = db.dataframe()
machine = Machine(df[options])
machine.open(filepath)
stats = [round(random_float(1, 250), 2) for _ in range(3)]
level = request.values.get("level", type=int) or random_int(1, 20)
health = request.values.get("health", type=float) or stats.pop()
Expand Down
Binary file added app/model.joblib
Binary file not shown.
1 change: 1 addition & 0 deletions fortuna-bin-win64
Submodule fortuna-bin-win64 added at 1e873e