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

mtoce_unit3-sprint-3 #177

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"python.pythonPath": "C:\\Users\\Mike\\anaconda3\\envs\\unit3\\python.exe"
}
85 changes: 85 additions & 0 deletions Study_Guide-Unit3-Sprint3.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
This study guide should reinforce and provide practice for all of the concepts you have seen in the past week. There are a mix of written questions and coding exercises, both are equally important to prepare you for the sprint challenge as well as to be able to speak on these topics comfortably in interviews and on the job.

If you get stuck or are unsure of something remember the 20 minute rule. If that doesn't help, then research a solution with google and stackoverflow. Only once you have exausted these methods should you turn to your Team Lead - they won't be there on your SC or during an interview. That being said, don't hesitate to ask for help if you truly are stuck.

Have fun studying!

# Questions of Understanding
1. Define the following and give an example of an appropriate task for each:
- Front-end:
- Back-end:
- Database:
2. What is a decorator?
3. What is a route?
4. Why do we want to separate our code into separate files when writing an application? Why not just one big file?
5. What is an API? Give an example of an API that is not Twitter's.
6. What does it mean to pickle a model? Why might this be useful?

# Basics of Flask

## Coding
Write a Flask application that displays "Hello World!" to the local host (usually `127.0.0.1:5000` or `localhost:5000`)

## Questions of Understanding
1. Flask is described as a "microframework" for developing web applications. What is a "microframework"?
2. What is another web development framework in Python?
3. In this line of code: `APP = Flask(__name__)` What does `__name__` do?
4. What line of your code tells when and where "Hello World!" should be displayed?
5. What do we need to type into the terminal to run our flask application?

# API's

## Coding
API's are a common part of programming, whether setting up your own or using someone else's. Today we will be looking at the API for the board gaming hobby site BoardGameGeek (BGG). The API instructions can be found [here](https://boardgamegeek.com/wiki/page/BGG_XML_API&redirectedfrom=XML_API#). There are many wrappers online for the BGG API that you may use but the sample code below will use `requests` and the web scraping library `BeautifulSoup`.

```python
import requests
import bs4

game_id = 13
url = 'https://www.boardgamegeek.com/xmlapi/boardgame/' + str(game_id)
result = requests.get(url)
soup = bs4.BeautifulSoup(result.text, features='lxml')
print(soup.find('name').text)
```

The code above uses the API to search for a game by its ID number (more than 16,000 entries on BGG). Once the API returns the results, BeautifulSoup is used to parse the XML and make it easily searchable.

Explore the BGG API and see if you are able to find the following information about a game:
- Name
- Max and Min Players
- Play Time
- Game Description
- Some of the game mechanics

# Flask and Databases

## Code
Write a Flask web application using `SQLAlchemy` with the following:
- A home route that displays at least one entry from a database of stored BGG game information
- A dynamic route `/add/<game_id>` that adds game information into your database based on the ID in the route.
- A route that resets the database
- The database should have the following following columns as a minimum: id (integer), name (string), and max_players (integer)

## Questions of Understanding
1. What line of code establishes what database should be used for your application?
2. How do we define our table, what columns are going to be in it, and what those column datatypes are?
3. How do we make a query to our database?

# HTML Templates

## Code
Create a small HTML template to display all the games in your database. Update your home route to use this template.

## Questions of Understanding
1. What is an HTML template?
2. What module do we need to import from `flask` to use our HTML template?

# Heroku

## Code
It is not necessary, but you can try putting your app on Heroku

## Questions of Understanding
1. What is a platform-as-a-service?
2. Why do we need to use a service like Heroku? Why not just host the application on our local machine?
7 changes: 7 additions & 0 deletions bw/csv_to_dict.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import pandas as pd

strains = pd.read_csv('https://raw.githubusercontent.com/Build-Week-Med-Cabinet-2-MP/bw-med-cabinet-2-ml/data-generation/data/CLEAN_WMS_2020_05_24.csv')

strains_json = strains.to_json(orient='index')

print(strains_json)
1 change: 1 addition & 0 deletions bw/strains.json

Large diffs are not rendered by default.

File renamed without changes.
Binary file added mod1/models/latest_model.pkl
Binary file not shown.
104 changes: 104 additions & 0 deletions mod1/web_app/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# 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/
*.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/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
.pytest_cache/

# Translations
*.mo
*.pot

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

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
target/

# Jupyter Notebook
.ipynb_checkpoints

# pyenv
.python-version

# celery beat schedule file
celerybeat-schedule

# 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/
37 changes: 37 additions & 0 deletions mod1/web_app/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# web_app/__init__.py

from flask import Flask

from web_app.models import db, migrate
from web_app.routes.home_routes import home_routes
from web_app.routes.tweet_routes import tweet_routes
from web_app.routes.twitter_routes import twitter_routes
from web_app.routes.stats_routes import stats_routes

import os
from dotenv import load_dotenv

load_dotenv()

DATABASE_URI = "sqlite:///C:\\Users\\Mike\\LambdaSchool\\unit3\\DS-Unit-3-Sprint-3-Productization-and-Cloud\\mod1\\web_app_99.db" # using absolute filepath on Windows (recommended) h/t: https://stackoverflow.com/a/19262231/670433

SECRET_KEY = os.getenv("TWITTER_API_SECRET", default="OOPS")

def create_app():
app = Flask(__name__)
app.config["SECRET_KEY"] = SECRET_KEY

app.config["SQLALCHEMY_DATABASE_URI"] = DATABASE_URI
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
db.init_app(app)
migrate.init_app(app, db)

app.register_blueprint(home_routes)
app.register_blueprint(tweet_routes)
app.register_blueprint(twitter_routes)
app.register_blueprint(stats_routes)
return app

if __name__ == "__main__":
my_app = create_app()
my_app.run(debug=True)
48 changes: 48 additions & 0 deletions mod1/web_app/iris_classifier.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# web_app/classifier.py

import os
import pickle

from sklearn.datasets import load_iris
from sklearn.linear_model import LogisticRegression # for example

MODEL_FILEPATH = os.path.join(os.path.dirname(__file__), "..", "models", "latest_model.pkl")

def train_and_save_model():
print("TRAINING THE MODEL...")
X, y = load_iris(return_X_y=True)
#print(type(X), X.shape) #> <class 'numpy.ndarray'> (150, 4)
#print(type(y), y.shape) #> <class 'numpy.ndarray'> (150,)
classifier = LogisticRegression() # for example
classifier.fit(X, y)

print("SAVING THE MODEL...")
# save our classifier model to a new filepath we specified above
# "wb" stands for: "write binary"
with open(MODEL_FILEPATH, "wb") as model_file:
pickle.dump(classifier, model_file)

return classifier

def load_model():
print("LOADING THE MODEL...")
# "rb" stands for read binary
with open(MODEL_FILEPATH, "rb") as model_file:
saved_model = pickle.load(model_file)
return saved_model

if __name__ == "__main__":

train_and_save_model()

clf = load_model()
print("CLASSIFIER:", clf)

breakpoint()

X, y = load_iris(return_X_y=True) # just to have some data to use when predicting
inputs = X[:2, :]
print(type(inputs), inputs)

result = clf.predict(inputs)
print("RESULT:", result)
1 change: 1 addition & 0 deletions mod1/web_app/migrations/README
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Generic single-database configuration.
45 changes: 45 additions & 0 deletions mod1/web_app/migrations/alembic.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# A generic, single database configuration.

[alembic]
# template used to generate migration files
# file_template = %%(rev)s_%%(slug)s

# set to 'true' to run the environment during
# the 'revision' command, regardless of autogenerate
# revision_environment = false


# Logging configuration
[loggers]
keys = root,sqlalchemy,alembic

[handlers]
keys = console

[formatters]
keys = generic

[logger_root]
level = WARN
handlers = console
qualname =

[logger_sqlalchemy]
level = WARN
handlers =
qualname = sqlalchemy.engine

[logger_alembic]
level = INFO
handlers =
qualname = alembic

[handler_console]
class = StreamHandler
args = (sys.stderr,)
level = NOTSET
formatter = generic

[formatter_generic]
format = %(levelname)-5.5s [%(name)s] %(message)s
datefmt = %H:%M:%S
Loading