基于Flask的NBA球员推荐系统

功能截图

注册
在这里插入图片描述

登录
在这里插入图片描述

主页
在这里插入图片描述

搜索球员
在这里插入图片描述

比较球员
在这里插入图片描述
在这里插入图片描述

球员数据
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

部分代码

forms.py

from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, BooleanField, SubmitField, SelectMultipleField
from wtforms.validators import DataRequired, Length, Email, EqualTo


class LoginForm(FlaskForm):
    username = StringField('Username', validators=[DataRequired(), Length(8, 16)])
    password = PasswordField('Password', validators=[DataRequired(), Length(8, 16)])
    submit = SubmitField('Log in')


class RegisterForm(FlaskForm):
    username = StringField("username", validators=[Length(min=7, max=20), DataRequired()])
    email = StringField("email", validators=[Email()])
    password = PasswordField("password", validators=[DataRequired(), EqualTo(fieldname="confirm", message="密码不一致!")])
    confirm = PasswordField("confirm password", validators=[DataRequired()])
    submit = SubmitField('register')

class RecommendForm(FlaskForm):
    tags = SelectMultipleField(
        label='标签', choices=[('潜力待发掘', '潜力待发掘'), ('超级得分手', '超级得分手'), ('进攻万花筒', '进攻万花筒'),
                               ('篮下得分手', '篮下得分手'), ('进攻组织者', '进攻组织者'), ('外线封锁者', '外线封锁者'),
                               ('篮板精英', '篮板精英'), ('标准后卫', '标准后卫'), ('攻防双向球员', '攻防双向球员'),
                               ('禁区守护者', '禁区守护者'), ('全能型球员', '全能型球员')])
    submit = SubmitField(label='提交')

models.py

from wtforms import StringField, validators, PasswordField

from NBADataSystem import db


class User(db.Model):
    __abstractor__ = True
    __tablename__ = "user"
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.Text)
    password = db.Column(db.Text)
    email = db.Column(db.Text)


class Userdata(db.Model):
    __abstractor__ = True
    __tablename__ = "userdata"
    id = db.Column(db.Integer, primary_key=True)
    score = db.Column(db.Integer)
    backboard = db.Column(db.Integer)
    assist = db.Column(db.Integer)


class Players(db.Model):
    __abstractor__ = True
    __tablename__ = "players"
    name = db.Column(db.Text)
    firstname = db.Column(db.Text)
    lastname = db.Column(db.Text)
    born = db.Column(db.Text)
    position = db.Column(db.Text)
    team_name = db.Column(db.Text)
    player_img = db.Column(db.Text)
    avg_score = db.Column(db.Integer)
    avg_backboard = db.Column(db.Integer)
    avg_assist = db.Column(db.Integer)
    penalty_kick = db.Column(db.Integer)
    pointer = db.Column(db.Integer)
    season_time = db.Column(db.Integer)
    defend = db.Column(db.Integer)
    last_time0 = db.Column(db.Text)
    last_time1 = db.Column(db.Text)
    last_time2 = db.Column(db.Text)
    last_time3 = db.Column(db.Text)
    last_time4 = db.Column(db.Text)
    last_score0 = db.Column(db.Integer)
    last_score1 = db.Column(db.Integer)
    last_score2 = db.Column(db.Integer)
    last_score3 = db.Column(db.Integer)
    last_score4 = db.Column(db.Integer)
    player_index = db.Column(db.Integer, primary_key=True)
    similarity = db.Column(db.Integer)


class Tags(db.Model):
    __abstractor__ = True
    __tablename__ = "tags"
    player_index = db.Column(db.Integer, primary_key=True)
    player_tag = db.Column(db.Text)

views.py

from flask import render_template, redirect, url_for, request, session, flash
from werkzeug.security import check_password_hash, generate_password_hash
from scipy.spatial.distance import cosine

from NBADataSystem import app, db
from NBADataSystem.forms import LoginForm, RecommendForm, RegisterForm
from NBADataSystem.models import Players, Tags, User, Userdata


def get_team_avg(team_data):
    n = 0
    team_sum = [0, 0, 0, 0, 0]
    for p in team_data:
        team_sum[0] += float(p.avg_score)
        team_sum[1] += float(p.avg_backboard)
        team_sum[2] += float(p.avg_assist)
        team_sum[3] += float(p.penalty_kick)
        team_sum[4] += float(p.pointer)
        n += 1
    for i in range(len(team_sum)):
        team_sum[i] = round(team_sum[i] / n, 4)
    return team_sum


def data_recommend(data, userdata):
    if userdata is None:
        return data
    user_vec = [userdata.score, userdata.backboard, userdata.assist]
    recommend_list = data
    for i in data:
        player_vec = [i.avg_score, i.avg_backboard, i.avg_assist]
        i.similarity = cosine(user_vec, player_vec)
    recommend_list.sort(key=lambda k: k.similarity)
    return recommend_list


@app.errorhandler(404)
def page_not_found(e):
    return render_template('errors/404.html'), 404


@app.route('/', methods=['GET', 'POST'])
def login():
    form = LoginForm()
    if form.validate_on_submit():
        username = form.username.data
        user = User.query.filter_by(username=username).first()
        if user:
            password = user.password
            if password == form.password.data:
                session['logged_in'] = True
                session['username'] = username
                session['id'] = user.id
                return redirect(url_for('index'))
        else:
            flash("用户名或密码错误")
    return render_template('login.html', form=form)


@app.route('/register/', methods=['GET', 'POST'])
def register():
    form = RegisterForm()
    if form.validate_on_submit():
        id = User.query.count() + 1
        new_user = User(id=id, username=form.username.data, password=form.password.data, email=form.email.data)
        db.session.add(new_user)
        db.session.commit()
        return redirect(url_for('login'))
    else:
        return render_template('register.html', form=form)

@app.route('/index', methods=['GET'])
def index():
    page = request.args.get('page', 1, type=int)
    per_page = 8
    pagination = Players.query.paginate(page=page, per_page=per_page, error_out=False)
    posts = pagination.items
    return render_template("index.html", pagination=pagination, posts=posts)


@app.route('/player<int:player_index>', methods=['GET', 'POST'])
def to_player(player_index):
    data = Players.query.get(player_index)
    team_data = Players.query.filter(Players.team_name.like('%%%s%%' % data.team_name))
    team_avg = get_team_avg(team_data)
    tag = Tags.query.get(player_index)
    return render_template("player.html", player_data=data, player_tag=tag, team_data=team_data, team_avg=team_avg)


@app.route('/player', defaults={'player_index': 0}, methods=['GET', 'POST'])
def player(player_index):
    tag = Tags.query.get(player_index)
    data = Players.query.get(player_index)
    team_data = Players.query.filter(Players.team_name.like('%%%s%%' % data.team_name))
    team_avg = get_team_avg(team_data)
    return render_template("player.html", player_data=data, player_tag=tag, team_data=team_data, team_avg=team_avg)


@app.route('/search')
def search():
    q = request.args.get('q', '')
    data = Players.query.filter(Players.name.like('%%%s%%' % q))
    return render_template("search.html", player_data_list=data)


@app.route('/compare', methods=['GET', 'POST'])
def compare():
    user_data = None
    index1 = request.args.get('player_index1', type=int)
    if index1 is None:
        index1 = 0
    else:
        user_data = index1
    data1 = Players.query.get(index1)

    if user_data is not None:
        store_data = Userdata.query.get(session['id'])
        if store_data:
            score = (data1.avg_score + store_data.score) / 2.0
            backboard = (data1.avg_backboard + store_data.backboard) / 2.0
            assist = (data1.avg_assist + store_data.assist) / 2.0
            store_data.assist = assist
            store_data.backboard = backboard
            store_data.score = score
            db.session.add(store_data)
            db.session.commit()

        else:
            new_data = Userdata(id=session['id'], score=data1.avg_score,
                                backboard=data1.avg_backboard, assist=data1.avg_assist)
            db.session.add(new_data)
            db.session.commit()
    index2 = request.args.get('player_index2', 10, type=int)
    data2 = Players.query.get(index2)
    data = Players.query.all()
    return render_template("compare.html", player_data=data, player_data1=data1, player_data2=data2)


@app.route('/recommend', methods=['POST', 'GET'])
def recommend():
    form = RecommendForm()
    data = []
    if form.validate_on_submit():
        tags = form.tags
        player_tag = Tags.query.filter(Tags.player_tag.like('%%%s%%' % " ".join(tags.data)))
        if not player_tag:
            for tag in tags.data:
                player_tag = Tags.query.filter(Tags.player_tag.like('%%%s%%' % tag))
        for i in player_tag:
            data.append(Players.query.get(i.player_index))
        userdata = Userdata.query.get(session['id'])
        data = data_recommend(data, userdata)
    return render_template('recommend.html', form=form, player_data=data)

init.py

import os
import sys
from flask import Flask
from flask_bootstrap import Bootstrap
from flask_login import LoginManager
from flask_sqlalchemy import SQLAlchemy

app = Flask('NBADataSystem')

# settings
WIN = sys.platform.startswith('win')
if WIN:
    prefix = 'sqlite:///'
else:
    prefix = 'sqlite:'

app.config.from_mapping(
    SECRET_KEY='dev',
)
app.config['SQLALCHEMY_DATABASE_URI'] = \
    os.getenv('DATABASE_URL', prefix + os.path.join(app.root_path, 'playerdata/Data.db'))
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

app.jinja_env.trim_blocks = True
app.jinja_env.lstrip_blocks = True

app.config['BOOTSTRAP_SERVE_LOCAL'] = True
bootstrap = Bootstrap(app)
db = SQLAlchemy(app)

login_manager = LoginManager()


from NBADataSystem import views

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值