-
Notifications
You must be signed in to change notification settings - Fork 0
Home
Welcome to NerdScout, the FIRST Robotics Competition scouting app of FRC Team 687, The Nerd Herd!
For Python, follow PEP 8 except for the following modifications:
- Do not break lines for the sake of length. Break lines for seperate statements or for clarity.
- Use double quotes when possible.
- Add whitespace between all operators.
- Docstrings follow the following format:
"""
Summary of function
Inputs:
- name1 (type1): description
- name2 (type2): description
- ...
Returns:
- type1: description
- type2: description
- ...
"""- Use camelCase for functions and variables.
- Format with Black, following this styleguide.
TODO: Add frontend style guide
NerdScout uses Flask, a Python web framework by Pallets. At its core, Flask allows us to define functions which are run when certain HTTP requests are recieved by the server. Take this example:
@app.route("/")
def index():
if "username" in session:
username = session["username"]
else:
username = None
return render_template("index.html", username=username)In this block, we define the response for the route /, or the index page of the website. Whenever a request for / is recieved, the server will run index() then respond with the output of render_template("index.html", username=username). So, what does render_template do?
Every webpage of NerdScout is defined by a Jinja 2 HTML template. In the previous example, render_template uses the index.html template found within the /templates directory of NerdScout.
Jinja templates are mostly regular HTML, but with some parts that can dynamically change depending on what is passed into render_template. For example, when we pass in username=username, the template now has a variable called username which it can use.
Jinja can insert variables or other information using the format:
{{ statement }}This statement could be as simple as a single variable, or it could be an if statement, or it could include formatting.
Jinja also has support for if statements, loops, and variables defined within the template. This is done with the format:
{% statement %}Here are a few examples:
{% if foo %}
<h1>Hello</h1>
{# is in the file if foo is true #}
{% else %}
<h1>World</h1>
{# in in the file if foo is false #}
{% endif %}<ul>
{% for i in range(1,6) %}
<li>abaca {{ i }}</li>
{# creates 5 li with the text abaca then the number i #}
{% endfor %}
</ul>{% set foo = "bar" %}
<div>
...
</div>
<p>{{ foo }}</p> {# becomes bar #}Jinja templates can also extend or include others. Most pages in NerdScout include the following line:
{% extends 'base.html' %}This means that the page is based on base.html, making certain modifications to the different blocks within it.
Say that inside of base.html we include this line:
{% block foo %}<p>Hello World! :)</p>{% endblock %}then in our file world.html that extends base.html we include the line
{% block foo %}<p>Goodbye World! >:(</p>{% endblock %}The original foo block in base.html is replaced with the new foo block. So, the output would be
<p>Goodbye World! >:(</p> If we didn't define a foo block in world.html, the output would be
<p>Hello World! :)<p>This allows us to reuse certain files and code across pages. Now, let's say we have a single component we want to use in multiple pages. This would be best done with an include statement. Many pages in NerdScout have the line
{% include 'backButton.html' %}Here, the code from backButton.html is inserted into the file. Importantly, this can include Jinja statements also, and can interact with variables from the inserting page. For example, in team.html, the inclusion line is after a variable declaration, like so:
{% set previousPage = url_for("teamPage") %}
{% include 'backButton.html' %}Inside of backButton.html, the varaible previousPage is used to define where the back button leads to. By doing this, we can add minor changes to the included template.
Using both extends and include, we can reuse code on several pages, even if we need minor changes between instances.
Like most webapps, NerdScout can be split into two major parts: the frontend and the backend.
This half of NerdScout defines how the user interacts with the webapp and what they see in their browser. There are two major parts of the frontend:
- The
/templatesdirectory- Contains all of the Jinja HTML templates for NerdScout. This is split among several subdirectories.
- The
/staticdirectory- Contains all of the static assets for the frontend, such as images, CSS stylesheets, fonts, and Javascript.
This half of NerdScout defines how the server processes user input, along with interacting with the database server. It comprises of five Python files and two directories:
-
app.py- The main file, which actually runs Flask, starts up the app, and contains the frontend handlers.
-
constants.py- Keeps all of the constants and functions applicable to multiple backend files.
-
database.py- Holds all of the database interactions, including sending and retreieving data from the database.
-
auth.py- Has functions relating to accounts, including signing in and creating accounts.
-
games.py- Contains the
Gameclass, which defines most (preferrably all) season specific backend behavior. More about theGameclass can be found at Updating for a New Game.
- Contains the
- The
/cachedirectory- Holds text files created by NerdScout containing semi-persistant data, like event alliances and team statistics.
- The
/secretsdirectory- Holds text files with connection information, api keys, and the server's secret key.
Also on the backend is the MongoDB database server, seperate from NerdScout. NerdScout interacts with MongoDB to store matches, users, and teams, and more information can be found at Database Structure.
Certain directories, both in the frontend and the backend, are changed by NerdScout or are instance specific, and contain a README with more information.
Setup information can be found at the project README, found at /README.md.
Information about running NerdScout for production can be found at Running and Maintaining.

hi