From bd74ee54f0793c9c40e5f1a81c8df639a6c888c8 Mon Sep 17 00:00:00 2001 From: Chris Tarazi Date: Mon, 12 Dec 2016 16:38:34 -0800 Subject: [PATCH] Convert to web app --- .gitignore | 111 ++++++++++++++++++++++++++++++++ Procfile | 1 + app.py | 39 ++++++++++++ draw.py | 27 ++++---- requirements.txt | 7 ++ runtime.txt | 1 + templates/form.html | 10 +++ templates/index.html | 141 +++++++++++++++++++++++++++++++++++++++++ templates/results.html | 28 ++++++++ 9 files changed, 354 insertions(+), 11 deletions(-) create mode 100644 .gitignore create mode 100644 Procfile create mode 100644 app.py create mode 100644 requirements.txt create mode 100644 runtime.txt create mode 100644 templates/form.html create mode 100644 templates/index.html create mode 100644 templates/results.html diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9e60443 --- /dev/null +++ b/.gitignore @@ -0,0 +1,111 @@ + +# Created by https://www.gitignore.io/api/python,git,vim + +### Python ### +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +*.egg-info/ +.installed.cfg +*.egg + +# 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/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py + +# 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 + +# dotenv +.env + +# virtualenv +.venv/ +venv/ +ENV/ + +# Spyder project settings +.spyderproject + +# Rope project settings +.ropeproject + + +### Git ### +*.orig + + +### Vim ### +# swap +[._]*.s[a-w][a-z] +[._]s[a-w][a-z] +# session +Session.vim +# temporary +.netrwhist +*~ +# auto-generated tag files +tags diff --git a/Procfile b/Procfile new file mode 100644 index 0000000..ca6e941 --- /dev/null +++ b/Procfile @@ -0,0 +1 @@ +web: gunicorn app:app diff --git a/app.py b/app.py new file mode 100644 index 0000000..4e5b5fe --- /dev/null +++ b/app.py @@ -0,0 +1,39 @@ +from flask import Flask, render_template, redirect, \ + url_for, request, flash, escape + +import os +import draw # Import simulator code + +app = Flask(__name__) + +app.secret_key = os.urandom(24) + +@app.route("/", methods=["GET", "POST"]) +def index(): + if request.method == "POST": + try: + draws = None + n = int(escape(request.form["simulations"])) + if n > 1000000: + flash("Error: 1,000,000 is the maximum number of simulations.") + elif n < 1: + flash("Error: Number must be greater than zero.") + else: + draws = draw.execute_simulation(n) + return render_template("results.html", draws=draws, n=n) + except Exception as e: + print(e) + flash("Error: Tricky tricky, only numbers are accepted here.") + # else: + + return render_template("form.html") + + if __name__ == "__main__": + app.run() + +@app.context_processor +def utility_processor(): + def format_odds(odds): + return "{0:.5}".format(odds) + + return dict(format_odds=format_odds) diff --git a/draw.py b/draw.py index 3037899..a7ac45c 100644 --- a/draw.py +++ b/draw.py @@ -32,13 +32,13 @@ ("H", "SPA", "Sevilla") ] -if len(sys.argv) != 2: - print("Usage:", sys.argv[0], "") - sys.exit(-1) +# if len(sys.argv) != 2: +# print("Usage:", sys.argv[0], "") +# sys.exit(-1) valid_draws = defaultdict(list) # Holds all valid draws draws = {} # Holds the count of the simulations -n = int(sys.argv[1]) # Number of simulations +# n = int(sys.argv[1]) # Number of simulations def init_draws(): for winner in group_winners: @@ -112,12 +112,17 @@ def simulate_draw(): # ----------------------------------------------------------------------------- -init_draws() -for i in range(n): - simulate_draw() +def execute_simulation(n): + init_draws() + for i in range(n): + simulate_draw() -for match, count in draws.items(): - if count != 0: - print("{:18} {} {:18}".format(match[0][2], "vs", match[1][2]), - "|", count, "/", n, "=", "{0:.5}".format(count / n)) + # for match, count in draws.items(): + # if count != 0: + # print("{:18} {} {:18}".format(match[0][2], "vs", match[1][2]), + # "|", count, "/", n, "=", "{0:.5}".format(count / n)) + return draws + +if __name__ == "__main__": + execute_simulation() diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..076e619 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,7 @@ +click==6.6 +Flask==0.11.1 +gunicorn==19.6.0 +itsdangerous==0.24 +Jinja2==2.8 +MarkupSafe==0.23 +Werkzeug==0.11.11 diff --git a/runtime.txt b/runtime.txt new file mode 100644 index 0000000..c0354ee --- /dev/null +++ b/runtime.txt @@ -0,0 +1 @@ +python-3.5.2 diff --git a/templates/form.html b/templates/form.html new file mode 100644 index 0000000..cb03892 --- /dev/null +++ b/templates/form.html @@ -0,0 +1,10 @@ +{% extends "index.html" %} +{% block body %} +
+ + + +
+{% endblock %} diff --git a/templates/index.html b/templates/index.html new file mode 100644 index 0000000..7bd598a --- /dev/null +++ b/templates/index.html @@ -0,0 +1,141 @@ + + + + + + UCL Draw Simulator + + + + + + + +
+ +
+
+ UCL Draw + +
+
+ +
+

UCL Round of 16 Draw Simulator 2016-2017

+{% with messages = get_flashed_messages() %} + {% if messages %} +
+ {% for message in messages %} +

{{ message }}

+ {% endfor %} +
+ {% endif %} +{% endwith %} +{% block body %}{% endblock %} +
+ +
+ + + diff --git a/templates/results.html b/templates/results.html new file mode 100644 index 0000000..d3623ef --- /dev/null +++ b/templates/results.html @@ -0,0 +1,28 @@ +{% extends "index.html" %} +{% block body %} +
+
Number of simulations: {{ n }}

+ + + + + + + + + + + {% for match, count in draws.items() %} + {% if count != 0 %} + + + + + + + {% endif %} + {% endfor %} + +
WinnerRunner-upCountOdds
{{ match[0][2] }}{{ match[1][2] }}{{ count }}{{ format_odds(count / n) }}
+
+{% endblock %}