This repository has been archived on 2021-12-30. You can view files and clone it, but cannot push or open issues or pull requests.
ELOStar/lib/utils.py

81 lines
2.3 KiB
Python

#!/usr/bin/env python
# -*- encoding: utf-8 -*-
'''
@File : utils.py
@Author : liuyihui
@Email : liuyihui02@gmail.com
'''
# here put the import lib
import elo
import math
import random
from typing import List
from db_init import Person
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.orm.session import Session
from sqlalchemy.sql.expression import desc, func
engine = create_engine('sqlite:///data.db', echo=False)
session_maker = sessionmaker(bind=engine)
def get_session() -> Session:
'''make a session instance
Returns
-------
: a session instance
'''
return session_maker()
def get_person(id: int, ses: Session) -> Person:
'''get person by id
Parameters
----------
id : person id
ses : session
Returns
-------
res : a person
'''
res = ses.query(Person).filter_by(id=id).first()
return res
def get_enemy(P: Person, ses: Session, delta: float = 1.623354290020702) -> Person:
'''get enemy of Person P
We should know that the rate of one person obeys logistic distribution F(t).
If rate of P (r for short) is within the interval [r1, r2] with 90% certainly:
Assuming that X obeys stand logistic distribution, so the possibility that X is in [-2.94443897916644,
2.94443897916644] equals 0.9. The standard deviation of F is pi/sqrt(3)*gamma where gamma is shape
parameter. Assuming variance of r equals expectation mu, we have sqrt(mu) = pi/sqrt(3)*gamma. And x =
(r - mu) / gamma, so r = x * gamma + mu. Instead x with ±2.94443897916644, gamma = sqrt(3*mu)/pi, we get
r = ±2.94443897916644 * sqrt(3*mu) / pi + mu = 1.623354290020702 * sqrt(mu) + mu.
Parameters
----------
P : a person
ses : session
delta : allowable gap of rate
Returns
-------
res : a person who will be enemy of Person P
'''
delta = delta * math.sqrt(P.rate)
min_ = P.rate - delta
max_ = P.rate + delta
res = ses.query(Person).filter(
Person.id != P.id,
Person.rate >= min_,
Person.rate <= max_
).order_by(func.random()).first()
return res
def get_rank(ses: Session, b: int = 1, len: int = 10) -> List[Person]:
res = ses.query(Person).order_by(desc('rate')).offset(b-1).limit(len).all()
return res