Fix place ordinal calculation (#1067)

* Fix scoreboard place ordinalization in Python 3
* Extract ordinalization code to `CTFd.utils.humanize.numbers.ordinalize`.
selenium-screenshot-testing
Kevin Chung 2019-07-24 01:44:20 -04:00 committed by GitHub
parent f2e0b9e8b5
commit 2bdf7b64d6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 34 additions and 11 deletions

View File

@ -3,6 +3,7 @@ from flask_marshmallow import Marshmallow
from sqlalchemy.orm import validates, column_property from sqlalchemy.orm import validates, column_property
from sqlalchemy.ext.hybrid import hybrid_property from sqlalchemy.ext.hybrid import hybrid_property
from CTFd.utils.crypto import hash_password from CTFd.utils.crypto import hash_password
from CTFd.utils.humanize.numbers import ordinalize
from CTFd.cache import cache from CTFd.cache import cache
import datetime import datetime
import six import six
@ -349,14 +350,11 @@ class Users(db.Model):
standings = get_user_standings(admin=admin) standings = get_user_standings(admin=admin)
# http://codegolf.stackexchange.com/a/4712
try: try:
i = standings.index((self.id,)) + 1 n = standings.index((self.id,)) + 1
if numeric: if numeric:
return i return n
else: return ordinalize(n)
k = i % 10
return "%d%s" % (i, "tsnrhtdd"[(i / 10 % 10 != 1) * (k < 4) * k :: 4])
except ValueError: except ValueError:
return None return None
@ -469,7 +467,7 @@ class Teams(db.Model):
score += member.get_score(admin=admin) score += member.get_score(admin=admin)
return score return score
def get_place(self, admin=False): def get_place(self, admin=False, numeric=False):
""" """
This method is generally a clone of CTFd.scoreboard.get_standings. This method is generally a clone of CTFd.scoreboard.get_standings.
The point being that models.py must be self-reliant and have little The point being that models.py must be self-reliant and have little
@ -480,11 +478,11 @@ class Teams(db.Model):
standings = get_team_standings(admin=admin) standings = get_team_standings(admin=admin)
# http://codegolf.stackexchange.com/a/4712
try: try:
i = standings.index((self.id,)) + 1 n = standings.index((self.id,)) + 1
k = i % 10 if numeric:
return "%d%s" % (i, "tsnrhtdd"[(i / 10 % 10 != 1) * (k < 4) * k :: 4]) return n
return ordinalize(n)
except ValueError: except ValueError:
return None return None

View File

View File

@ -0,0 +1,6 @@
def ordinalize(n):
"""
http://codegolf.stackexchange.com/a/4712
"""
k = n % 10
return "%d%s" % (n, "tsnrhtdd"[(n // 10 % 10 != 1) * (k < 4) * k :: 4])

View File

@ -0,0 +1,19 @@
from CTFd.utils.humanize.numbers import ordinalize
def test_ordinalize():
tests = {
1: "1st",
2: "2nd",
3: "3rd",
4: "4th",
11: "11th",
12: "12th",
13: "13th",
101: "101st",
102: "102nd",
103: "103rd",
111: "111th",
}
for t, v in tests.items():
assert ordinalize(t) == v