From 52c8518fb7f1067352d7671031eea40c77affc18 Mon Sep 17 00:00:00 2001 From: liuyihui Date: Wed, 29 Dec 2021 22:23:26 +0800 Subject: [PATCH] ref: elo method;add: db methods;change: html file --- .gitignore | 8 ++++- lib/db_init.py | 30 +++++++++++++++++++ lib/elo.py | 76 +++++++++++++++++------------------------------ lib/utils.py | 48 ++++++++++++++++++++++++++++++ public/index.html | 2 -- 5 files changed, 113 insertions(+), 51 deletions(-) create mode 100644 lib/db_init.py create mode 100644 lib/utils.py diff --git a/.gitignore b/.gitignore index 78690ef..bf9c300 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,10 @@ pyelo/ # config file setup.cfg -.vscode/ \ No newline at end of file +.vscode/ + +# data +*.db + +# cache +__pycache__/ \ No newline at end of file diff --git a/lib/db_init.py b/lib/db_init.py new file mode 100644 index 0000000..5189eb6 --- /dev/null +++ b/lib/db_init.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python +# -*- encoding: utf-8 -*- +''' +@File : db_init.py +@Author : liuyihui +@Email : liuyihui02@gmail.com +''' + +# here put the import lib +from sqlalchemy import create_engine +from sqlalchemy import Column, Integer, String, Float +from sqlalchemy.ext.declarative import declarative_base + +Base = declarative_base() + +class Person(Base): + __tablename__ = 'persons' + + id = Column(Integer, primary_key=True, autoincrement=True) + name = Column(String) + work = Column(String) + rate = Column(Float, default=1400) + + def __repr__(self): + return "" % (self.name, self.work, self.rate) + + +if __name__ == '__main__': + engine = create_engine('sqlite:///data.db', echo=True) + Base.metadata.create_all(engine, checkfirst=True) diff --git a/lib/elo.py b/lib/elo.py index ed6035f..9eae196 100644 --- a/lib/elo.py +++ b/lib/elo.py @@ -8,60 +8,40 @@ # here put the import lib import math -from typing_extensions import Self +from db_init import Person -class Person(object): - '''personal information +def __compute_wre(A: Person, B: Person) -> float: + '''compute win rate expectation (wre for short) - Attributes + Parameters ---------- - rate : elo rate - name : name - sex : male or female - link : baike link + A, B : two persons - Methods + Returns ------- - compute_K : compute the constant K + wre : win rate expectation of A ''' - def __init__(self, name: str, rate: float = 1400, *, sex: str = None, link: str = None) -> None: - self.name = name - self.rate = rate - self.link = link + wre = 1 / (1 + math.pow(10, (B.rate-A.rate)/400)) + return wre - if sex and sex not in ['male', 'female']: - raise ValueError("Sex must be male or female") - self.sex = sex +def __compute_K(P: Person) -> float: + if P.rate > 2400: + return 12 + elif P.rate > 1900: + return 24 + else: + return 36 - def compute_wre(self, B: Self) -> float: - '''compute win rate expectation (wre for short) +def set_result(A: Person, B: Person, res: float) -> None: + '''set result of this game - Parameters - ---------- - B : another person - - Returns - ------- - wre : win rate expectation - ''' - wre = 1 / (1 + math.pow(10, (B.rate-self.rate)/400)) - return wre - - def compute_K(self) -> float: - if self.rate > 2400: - return 12 - elif self.rate > 2000: - return 24 - else: - return 36 - - def set_result(self, wre: float, res: float) -> None: - '''set result of this game - - Parameters - ---------- - wre : win rate expectation - res : the result, 0 for lose, 1 for win and 0.5 for draw - ''' - K = self.compute_K() - self.rate += K * (res - wre) + Parameters + ---------- + A, B : two persons + res : the result, 0 for A win, 1 for B win and -1 for draw + ''' + wre1 = __compute_wre(A, B) + wre2 = 1 - wre1 + if res >= 0: + A.rate += __compute_K(A) * (1 - res - wre1) + B.rate += __compute_K(B) * (res - wre2) diff --git a/lib/utils.py b/lib/utils.py new file mode 100644 index 0000000..6c0f16c --- /dev/null +++ b/lib/utils.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python +# -*- encoding: utf-8 -*- +''' +@File : utils.py +@Author : liuyihui +@Email : liuyihui02@gmail.com +''' + +# here put the import lib +import elo +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: + return session_maker() + +def get_person(id: int, ses: Session) -> Person: + res = ses.query(Person).filter_by(id=id).first() + return res + +def get_enemy(P: Person, ses: Session, delta: float = 0.01) -> Person: + min_ = P.rate * (1 - delta) + max_ = P.rate * (1 + 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 + + +ses = get_session() +A = get_person(1, ses) +res = get_enemy(A, ses) +print(res) diff --git a/public/index.html b/public/index.html index 8929845..81d44e3 100644 --- a/public/index.html +++ b/public/index.html @@ -43,7 +43,6 @@
姓名:


- 年龄:


代表作:


@@ -53,7 +52,6 @@
姓名:


- 年龄:


代表作: