NBA predictions for friends
A simple app, really. NBA predictions is a quick and dirty little flask app fulfilling 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 ultimate Flask teacher and preacher and I recommend 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.
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:
def calculate_score(pred, actual): # the scores are in a text format, i.e. 4:2, 1:4 etc. pred_home = int(pred.split(':')) pred_away = int(pred.split(':')) actual_home = int(actual.split(':')) actual_away = int(actual.split(':')) 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.