NBA predictions

August 28, 2017
python flask

NBA predictions is a quick and dirty little flask app fullfilling the need of a group of friends (maybe a hundred) to play with the NBA playoff predictions. The structure is based on the work of Miguel Grinberg - a very simple modular flask app using the factory pattern, a tiny sqlite database, a login system. Miguel is the utlimate Flask teacher and preacher and I reccomend all of his tutorials, videos and this book which is a real Flask Bible.

Users can make one prediction and the score is calculated on a formula that was agreed upon. A couple of admin users were in charge of updating the score and inserting new series. It was fun and it lasted for two years. By the way, Steph Curry is amazing.

The code is available on github.

# models.py
class User(UserMixin, db.Model):

    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key = True)
    #email = db.Column(db.String(64), unique = True, index = True) not using this...
    username = db.Column(db.String(64), unique = True, index = True)
    password_hash = db.Column(db.String(128))
    is_admin = db.Column(db.Boolean(),default=False)
   
    @property
    def total(self):

        total=0
        user_preds = Prediction.query.filter(
            Prediction.user==self).all()

        for predict in user_preds:
            if predict.score_made:
                total+=int(predict.score_made)

        return total

The code that calculates the score:

# models.py
def calculate_score(pred, actual):
	# the scores are in a text format, i.e. 4:2, 1:4 etc.
    
    pred_home = int(pred.split(':')[0])
    pred_away = int(pred.split(':')[1])

    actual_home = int(actual.split(':')[0])
    actual_away = int(actual.split(':')[1])

    score = 0


    # the 15 points for the overall winner
    if (pred_home-pred_away)*(actual_home-actual_away)>0:
        score+=15

        diff = abs(min(pred_home, pred_away)-min(actual_home,actual_away))
        
        if (diff == 0):
            score+=10

        if (diff == 1):
            score+=5

        if (diff==2):
            score+=2

        # bonus points for an upset
        if (actual_home-actual_away)<0:
            score+=5


    return score

The predictions model:

class Prediction(db.Model):

    __tablename__ = 'predictions'


    id = db.Column(db.Integer, primary_key = True)

    series_id = db.Column(db.Integer, db.ForeignKey('series.id'))
    series = db.relationship('Series',  foreign_keys=[series_id])

    created = db.Column(db.DateTime(), default=datetime.now)
    
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'))
    user = db.relationship('User',  foreign_keys=[user_id])
    
    predicted = db.Column(db.String)
    score_made = db.Column(db.Integer(),default=0)

    # the user can make only one prediction on a single series
    __table_args__ = (
        db.UniqueConstraint(series_id, user_id),
    )

I should mention that I wasn’t really sure that a tiny sqlite database would be able to handle it, but it worked great. We’ve had maybe 20 people online at a time, watching the results (reading) and probably no more than 5 players writing at the same time.

Anyway, it turned out to be a great little setup that I used again for an office intranet app for emailing newsletters and editing news.

Prototyping a simple flask app

January 1, 0001
flask python
comments powered by Disqus