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

110 lines
2.8 KiB
Python

#!/usr/bin/env python
# -*- encoding: utf-8 -*-
'''
@File : utils.py
@Author : liuyihui
@Email : liuyihui02@gmail.com
'''
# here put the import lib
import math
from typing import List
from . import db_init
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?check_same_thread=False', echo=False)
session_maker = sessionmaker(bind=engine)
Person = db_init.Person
def get_session() -> Session:
'''make a session instance
Returns
-------
: a session instance
'''
return session_maker()
def get_counts(ses: Session) -> int:
res = ses.query(Person).count()
return res
def get_person(ses: Session) -> Person:
'''get random person
Parameters
----------
ses : session
Returns
-------
res : a person
'''
res = ses.query(Person).order_by(func.random()).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]:
'''get rank
Parameters
----------
ses : session
b : offset subscript
len : length of list
Returns
-------
res : rank list between b and b+len-1
'''
res = ses.query(Person).order_by(desc('rate')).offset(b-1).limit(len).all()
return res
def match(ses: Session) -> Person:
'''select two persons
Parameters
----------
ses : session
Returns
-------
: two persons
'''
A = get_person(ses)
B = get_enemy(A, ses)
return A, B