Project So Far

  • Last Trimester I made improvments to my project and met alomost all college board criteria. My project is a sports quiz. It is a quiz where you are asked questions based on your personality and what you want in a sport and then gives you some sports options based on those answers
  • There are questions like "do you want to play outside." You can either pick yes or no. When you click one of these options it removes certain sports from a list of different sports. It then displays the final list with the removed sports.
  • There are 6 questions so by the end most sports are removed from the list. There should only be about 2-6 sports at the end based on your questions.
  • I also have a feature where when you are done with the sports quiz you can use a selection menu and a "save data" button to save the data on the website. When you refresh the page it saves and the sport is still on the screen.

Improvments

  • I hope to make sure to fit all of the critera of college board even better
    • This will help me make sure to get a good score
      • Right now it is debatable if the criteria will fit.
    • I can manege complexity better and make my code simpiler
    • I havn't tested yet
      • I need a video of two different run throughs
    • There isn't great iteration
      • I want to add a button that says "redo quiz"
    • My writeup needs a bit more clarification
      • Collegeboard may be confused by some of the ways I phrase things
  • I want to change my list to a database
    • The list fits collegeboard criteria for data abstraction however I think that making a database would make it better
      • Last trimester I had a hard time understanding backend code however this trimester it is starting to make more sense
        • I understand databases more after the CRUD lesson
      • With this database I want to add the CRUD functions
        • CRUD has started to interest me
        • In this database I will have the names of sports
          • Every sport will have different properties
            • Name
            • Id
            • "Yes" or "No" to variables. Every one of these variables will be linked to a question. Every sport will either be yes or no to each variable. Depending on these variables, the sport will be removed from the list based on these variables.
              • - Outside - Relates to question on if the user wants to play outside or inside - Competitive - Relates to question on if the user wants to be competitive or not - Team - Relates to question on if the user wants to be on a team or not - Running - Relates to question on if the user wants to run or not - Contact - Relates to question on if the user wants to be in a contact sport or not - Ball - Relates to question on if the user wants to play with a ball or not or not - For example, if basketball is a sport in the database, certain questions will remove it from the database - Basketball has a column for team and it says "yes" for team - If the user selects "yes" for team oriented in the quiz then nothing will happen - If the user selects "no" then basketball would be removed from the database through the delete function - I will be able to do this with multiple sports at once.
          • I also want to add a create function where people can add a sport to the database
            • They can add a sport like rock climbing to the database and put in its id as RC
              • - For every variable or question column they will either put "no" or "yes" - If they do not use this I will clear the garbage and it will use an iteration to force them to put yes or no - Every question will now be yes or no - This is because the way the sports will be removed from the list is by conditionals - Example: If a user selects "no" for playing on a team, then I will use an if statment to remove all sports from the list that have the outside prpery as "yes"

Code Functions

"""
These imports define the key objects
"""
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
"""
These object and definitions are used throughout the Jupyter Notebook.
"""
# Setup of key Flask object (app)
app = Flask(__name__)
# Setup SQLAlchemy object and properties for the database (db)
database = 'sqlite:///countries.db'  # path and filename of database
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['SQLALCHEMY_DATABASE_URI'] = database
app.config['SECRET_KEY'] = 'SECRET_KEY'
db = SQLAlchemy()
# This belongs in place where it runs once per project
db.init_app(app)

""" database dependencies to support sqlite examples """
import datetime
from datetime import datetime
import json

from sqlalchemy.exc import IntegrityError
from werkzeug.security import generate_password_hash, check_password_hash


''' Tutorial: https://www.sqlalchemy.org/library.html#tutorials, try to get into a Python shell and follow along '''

# Define the User class to manage actions in the 'users' table
# -- Object Relational Mapping (ORM) is the key concept of SQLAlchemy
# -- a.) db.Model is like an inner layer of the onion in ORM
# -- b.) User represents data we want to store, something that is built on db.Model
# -- c.) SQLAlchemy ORM is layer on top of SQLAlchemy Core, then SQLAlchemy engine, SQL
class Country(db.Model):
    __tablename__ = 'countries'  # table name is plural, class name is singular

    # Define the User schema with "vars" from object
    id = db.Column(db.Integer, primary_key=True)
    _country = db.Column(db.String(255), unique=False, nullable=False)
    _cid = db.Column(db.String(255), unique=True, nullable=False)
    _continent = db.Column(db.String(255), unique=False, nullable=False)
    _population = db.Column(db.Integer, unique=False, nullable=False)
    #_population = db.Column(db.Integer, unique=False, nullable=False)

    # constructor of a User object, initializes the instance variables within object (self)
    def __init__(self, country, cid, continent, population):
        self._country = country    # variables with self prefix become part of the object, 
        self._cid = cid
        self._continent = continent
        self._population = population
        #self._population = population

    # a name getter method, extracts name from object
    @property
    def country(self):
        return self._country
    
    # a setter function, allows name to be updated after initial object creation
    @country.setter
    def country(self, country):
        self._country = country
    
    # a getter method, extracts uid from object
    @property
    def cid(self):
        return self._cid
    
    # a setter function, allows uid to be updated after initial object creation
    @cid.setter
    def cid(self, cid):
        self._cid = cid
        
    # check if uid parameter matches user id in object, return boolean
    def is_cid(self, cid):
        return self._cid == cid
    
    @property
    def continent(self):
        return self._continent
    
    # a setter function, allows name to be updated after initial object creation
    @continent.setter
    def continent(self, continent):
        self._continent = continent
    
    @property
    def population(self):
        return self._population
    
    # a setter function, allows name to be updated after initial object creation
    @population.setter
    def population(self, population):
        self._population = population

    
    # output content using str(object) is in human readable form
    # output content using json dumps, this is ready for API response
    def __str__(self):
        return json.dumps(self.read())

    # CRUD create/add a new record to the table
    # returns self or None on error
    def create(self):
        try:
            # creates a person object from User(db.Model) class, passes initializers
            db.session.add(self)  # add prepares to persist person object to Users table
            db.session.commit()  # SqlAlchemy "unit of work pattern" requires a manual commit
            return self
        except IntegrityError:
            db.session.remove()
            return None

    # CRUD read converts self to dictionary
    # returns dictionary
    def read(self):
        return {
            "id": self.id,
            "country": self.country,
            "cid": self.cid,
            "continent": self.continent,
            "population": self.population,
        }

    # CRUD update: updates user name, password, phone
    # returns self
    def update(self, country="", continent="", population=""):
        """only updates values with length"""
        if len(country) > 0:
            self.country = country
        if len(continent) > 0:
            self.continent = continent
        if len(population) > 0:
            self.population = population
        db.session.merge(self)
        db.session.commit()
        return self

    # CRUD delete: remove self
    # None
    def delete(self):
        db.session.delete(self)
        db.session.commit()
        return None
    
"""Database Creation and Testing """


# Builds working data for testing
    
# SQLAlchemy extracts single user from database matching User ID
def find_by_cid(cid):
    with app.app_context():
        place = Country.query.filter_by(_cid=cid).first()
    return place # returns user object

# Check credentials by finding user and verify password
def check_credentials(cid, continent):
    # query email and return user record
    place = find_by_cid(cid)
    if place == None:
        return False
    if (place.is_continent(continent)):
        return True
    return False

def find_by_country(country):
    with app.app_context():
        place = Country.query.filter_by(_country=country).first()
    return place # returns user object

# Check credentials by finding user and verify password
def check_credentials(country):
    # query email and return user record
    place = find_by_cid(country)
    if place == None:
        return False