diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml
index 830e2e6..89612ec 100644
--- a/.github/workflows/python-app.yml
+++ b/.github/workflows/python-app.yml
@@ -36,4 +36,6 @@ jobs:
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
- name: Test with pytest
run: |
- pytest
+ pip install pytest pytest-cov
+ pytest tests.py --doctest-modules --junitxml=junit/test-results.xml --cov=com --cov-report=xml --cov-report=html
+ continue-on-error: true
diff --git a/src/ratings_calculator/Profile.py b/src/ratings_calculator/Profile.py
new file mode 100644
index 0000000..d5a0c2c
--- /dev/null
+++ b/src/ratings_calculator/Profile.py
@@ -0,0 +1,72 @@
+"""Class to get cfc profile information of the user"""
+import json
+import requests
+
+
+class CFCProfile:
+ """User id of the user that we are trying to get data for"""
+
+ # default constructor for ratings calculator
+ def __init__(self, user_id: int, request=True) -> None:
+ self.user_id = user_id
+ self.profile = self.initialize_profile(request)
+ return
+
+ def initialize_profile(self, request=True) -> dict:
+ """
+ Gets the profile of the user
+ :param request: boolean indicating whether to use the web to search for this fvalue or not.
+ :return: json dictionary mapping of the player and its fields
+ """
+ if request:
+ URL = f"https://server.chess.ca/api/player/v1/{self.user_id}"
+ page = requests.get(URL)
+ return page.json()
+ else:
+ # open the json file and place the file as the value into the page
+ filepath = "player_info.json"
+ f = open(filepath)
+ data = json.load(f)
+ return data
+
+ def get_profile(self) -> dict:
+ """
+ Gets the profile of the current user
+ :return: json dictionary mapping of the player and its fields
+ """
+ return self.profile
+
+ def get_events_played(self) -> int:
+ """
+ Gets the number of events that this user has participated in
+ :return: events that this user has played in
+ """
+ numEvents = 0
+ if self.profile["player"]["events"] == []:
+ return 0
+ else:
+ return len(self.profile["player"]["events"])
+
+ def get_last_tournaments(self, num_tournaments: int) -> []:
+ """
+ Gets the number of events that this user has participated in
+ :param num_tournaments: previous n tournaments to get.
+ :return: events that this user has played in
+ """
+
+ tournament_data = []
+
+ if num_tournaments > len(self.profile["player"]["events"]):
+ # if the number of tournaments is greater than the number that exists in the json, take that number
+ num_tournaments = len(self.profile["player"]["events"])
+
+ for i in range(num_tournaments):
+ tournament_data.append(self.profile["player"]["events"][i])
+
+ return tournament_data
+
+
+class FIDEProfile:
+ """Gets user id data for FIDE profile"""
+
+ pass
diff --git a/src/ratings_calculator/RatingsCalculator.py b/src/ratings_calculator/RatingsCalculator.py
new file mode 100644
index 0000000..ba0659f
--- /dev/null
+++ b/src/ratings_calculator/RatingsCalculator.py
@@ -0,0 +1,178 @@
+import math
+from csv import reader
+
+
+class RatingsCalculator:
+ """Ratings Calculator is a class that calculates ratings, cfc-style"""
+
+ # default constructor for ratings calculator
+ def __init__(self) -> None:
+ self.expected_scores = self.expected_scores_init()
+
+ return
+
+ def average_rating(self, ratings: list) -> float:
+ """
+ Average ratings of the list of the ratings
+ :param ratings: a list of ratings
+ :return: average rating
+ """
+ ave_rating = 0
+ for rating in ratings:
+ ave_rating += rating
+ return ave_rating / len(ratings)
+
+ def provisional_unrated_players(self, ratings: list, wins: int, losses: int, games_played: int) -> object:
+ """
+ wins is the number of wins,
+ losses is the number of losses
+ games_played is the number of games
+ ratings is the list of opponent's ratings
+ """
+ Rc = self.average_rating(ratings)
+ # Rp = Rc + 400 (W - L) / N
+ Rp = Rc + 400 * (wins - losses) / games_played
+ return Rp
+
+ def established_ratings(self, all_time_high_score: int, old_rating: int, score: float, opponent_ratings: list,
+ quick=False) -> float:
+ """
+ Returns the established rating from the dictionary of ratings
+ :param all_time_high_score: the all time high of the player
+ :param score: the total score from the tournament
+ :param opponent_ratings: a list of opponent ratings
+ :param old_rating: the player's old rating
+ :param quick: if the time control used is between 5 and 14 minutes
+ :return: returns the established rating of the player
+ >>> ratingTest = RatingsCalculator()
+ >>> # expected_dict = ratingTest.expected_scores_init()
+ >>> ratingTest.established_ratings(1450, 1450, 4, [1237, 1511, 1214, 1441, 1579, 2133])
+ 1487
+ """
+ if score > len(opponent_ratings):
+ raise Exception("Cannot have higher score than games played")
+
+ # K=32 for players under 2200 and K=16 for players at or over 2200;
+ # Rn = Ro + 32 (S - Sx)
+ if old_rating >= 2199:
+ multiplier = 16
+ else:
+ multiplier = 32
+
+ # if quick (where time control used is between 5-14 min)
+ if quick:
+ multiplier = multiplier // 2
+
+ # expected_scores_dict = self.expected_scores_init()
+
+ expected_total = self.expected_total_score(old_rating, opponent_ratings)
+ new_rating = old_rating + multiplier * (score - expected_total)
+
+ if new_rating > all_time_high_score:
+ all_time_high_valid = 1
+ else:
+ all_time_high_valid = 0
+
+ multiplier_e = multiplier // 32 # ratio of the multiplier to ratings under 2200.
+ bonus = self.bonuses(all_time_high_valid, multiplier_e, new_rating, old_rating, len(opponent_ratings))
+ sum_of_scores = new_rating + bonus
+ return sum_of_scores
+
+ def bonuses(self, a: int, k_factor_e: int, r_new: float, r_old: int, n: int) -> int:
+ """
+ Returns the total sum of all bonuses available
+ :param a: is = 1 if all time high, 0 otherwise
+ :param k_factor_e: ratio of the player's k factor to the k factor used for players under 2200
+ :param r_new: post-event rating
+ :param r_old: pre-event rating
+ :param n: number of games played
+ :return: value of the new rating
+ >>> ratingTest = RatingsCalculator()
+ >>> ratingTest.bonuses(0, 1, 1487, 1450, 6)
+ 1496
+ """
+ if n < 4: # no bonus points awarded if less than 4 games played
+ return 0
+
+ R_MAX_BONUS = 20 # constants set
+ R_CHANGE_BONUS = 1.75
+ R_CHANGE_THRESHOLD = 13
+
+ bonus1 = a * R_MAX_BONUS * k_factor_e
+ threshold = R_CHANGE_THRESHOLD * k_factor_e * math.sqrt(n)
+
+ if r_new > (r_old + threshold):
+ b = 1
+ else:
+ b = 0
+
+ bonus2 = b * R_CHANGE_BONUS * (r_new - r_old - threshold) * k_factor_e
+ total_bonus = round(bonus1 + bonus2)
+ return total_bonus
+
+ def expected_total_score(self, rating: int, opponent_ratings: list):
+ """
+ Returns the expected total score from the tournament
+ :param rating: is the player's rating
+ :param opponent_ratings: is the opponent's rating in a lists
+ >>> ratingTest = RatingsCalculator()
+ >>> ratingTest.expected_total_score(1450, [1237, 1511, 1214, 1441, 1579, 2133])
+ 2.84
+ """
+ sum_expected = 0
+ for opp_rating in opponent_ratings:
+ if rating >= opp_rating: # your rating is bigger than the opponents
+ sum_expected += self.find_expected_value(rating - opp_rating, 0)
+ else:
+ sum_expected += self.find_expected_value(opp_rating - rating, 1)
+
+ return sum_expected
+
+ def find_expected_value(self, difference: int, lower_val: int):
+ """
+ Returns the expected value of the individual based on whether it is a lower or higher score.
+ :param lower_val: whether the number is a lower value
+ :param difference: is the difference in ratings
+ :return: expected value based on the expected dictionary
+ """
+ expected_dict = self.expected_scores
+ expected = expected_dict[int(difference)]
+ if lower_val == 1:
+ expected = round(1 - expected, 2)
+ else:
+ # keep the older value
+ pass
+
+ return expected
+
+ def expected_scores_init(self) -> dict:
+ """
+ Returns the expected score dictionary
+ :return: dictionary containing expected scores
+ """
+ # file is recommend to be in the following format: starting rank, Name of Player, CFC ID
+ # information of the event
+ file_name = "C:\\Users\\zheng\\PycharmProjects\\ratings-calculator\\ExpectedScores.csv"
+ expected_scores_higher = {}
+
+ with open(file_name, 'r') as f:
+ csv_reader = reader(f)
+ next(csv_reader)
+
+ for row in csv_reader:
+ # iterate through each row
+ # print(row)
+ # if it's the last line
+ max_diff = 2000
+ if row[0][0:3] == "735":
+ for j in range(735, max_diff):
+ expected_scores_higher[j] = 1
+ else:
+ row_vals = row[0].split("-")
+ starting_val = int(row_vals[0])
+ end_val = int(row_vals[1])
+
+ for j in range(starting_val, end_val + 1):
+ expected_scores_higher[j] = float(row[1]) # the location of the csv file
+
+ return expected_scores_higher
diff --git a/src/ratings_calculator/chesscanada.html b/src/ratings_calculator/chesscanada.html
new file mode 100644
index 0000000..37bf65d
--- /dev/null
+++ b/src/ratings_calculator/chesscanada.html
@@ -0,0 +1,323 @@
+
+
+ CFC Ratings Calculator
+
+
+
+
+
+
+
+
+
+
+
+ ![](http://www.chess.ca/themes/cfc/images/logo.png)
+
+ CFC Ratings Calculator
+ |
+
+
+
+
+
+ Using the current CFC Ratings formulas as of August 1st, 2012.
+
+
+ |
+
+
+
+
+
+
+
+
+
+ To use this calculator, enter your current rating as well as the result and ratings of your opponents.
+ The calculator will display your new ratings!
+
+
+
+
+
+
+ For new rating, no bonus would mean under normal circumstances. If the regular bonus field is higher,
+ that will be your new rating.
+ The lifetime high bonus rating will only be yours if the no bonus rating exceeds your highest ever
+ rating. Regular Bonus does not apply unless you play at least four games.
+
+ Also please note that due to rounding issues, results here may not exactly duplicate your CFC rating.
+ They should always be within 1 point, however.
+
+
+ |
+
+
+
+
+
diff --git a/src/ratings_calculator/main.py b/src/ratings_calculator/main.py
index 666228b..9e9e6b4 100644
--- a/src/ratings_calculator/main.py
+++ b/src/ratings_calculator/main.py
@@ -1,5 +1,4 @@
-import math
-from csv import reader
+from src.ratings_calculator.RatingsCalculator import RatingsCalculator
"""
@author Victor Zheng
@@ -51,6 +50,24 @@
RChangeThreshold = 13 (a constant).
The numerical values in the bonus point equation may be adjusted from time to time by the Rating Auditor
as deemed necessary and in consultation with the CFC Executive.
+
+TODO: From 411.1 Quick Chess, quick ratings will be calculated with 1/2 of the k factor
+- this appears to not be in effect?
+
+TODO: This is not covered by the current calculation:
+416. For a player with a pre-event rating below 800.
+
+TODO: If a player’s post tournament rating (including any participation and bonus points) is less than 200, the player
+is entered in the rating list at 200. This applies to both provisional and permanent ratings.
+
+TODO: Provisional ratings: 3 to 24 games
+
+
+TODO: For players who start a tournament above 2200 and during the event drop below 2200, we currently assume that the
+k factor remians the same.
+
+However, this is not correct as the ratings can change.
+
"""
"""
@@ -58,173 +75,6 @@
"""
-class RatingsCalculator:
- """Ratings Calculator is a class that calculates ratings, cfc-style"""
-
- # default constructor for ratings calculator
- def __init__(self) -> None:
- self.expected_scores = self.expected_scores_init()
-
- return
-
- def average_rating(self, ratings: list) -> float:
- """
- Average ratings of the list of the ratings
- :param ratings: a list of ratings
- :return: average rating
- """
- ave_rating = 0
- for rating in ratings:
- ave_rating += rating
- return ave_rating / len(ratings)
-
- def provisional_unrated_players(self, ratings: list, wins: int, losses: int, games_played: int) -> object:
- """
- wins is the number of wins,
- losses is the number of losses
- games_played is the number of games
- ratings is the list of opponent's ratings
- """
- Rc = self.average_rating(ratings)
- # Rp = Rc + 400 (W - L) / N
- Rp = Rc + 400 * (wins - losses) / games_played
- return Rp
-
- def established_ratings(self, all_time_high_score: int, old_rating: int, score: float, opponent_ratings: list) -> float:
- """
- Returns the established rating from the dictionary of ratings
- :param all_time_high_score: the all time high of the player
- :param score: the total score from the tournament
- :param opponent_ratings: a list of opponent ratings
- :param old_rating: the player's old rating
- :return: returns the established rating of the player.
- >>> ratingTest = RatingsCalculator()
- >>> # expected_dict = ratingTest.expected_scores_init()
- >>> ratingTest.established_ratings(1450, 1450, 4, [1237, 1511, 1214, 1441, 1579, 2133])
- 1487
- """
- # K=32 for players under 2200 and K=16 for players at or over 2200;
- # Rn = Ro + 32 (S - Sx)
- if old_rating >= 2199:
- multiplier = 16
- else:
- multiplier = 32
-
- # expected_scores_dict = self.expected_scores_init()
-
- expected_total = self.expected_total_score(old_rating, opponent_ratings)
- new_rating = old_rating + multiplier * (score - expected_total)
-
- if new_rating > all_time_high_score:
- all_time_high_valid = 1
- else:
- all_time_high_valid = 0
-
- multiplier_e = multiplier // 32 # ratio of the multiplier to ratings under 2200.
- bonus = self.bonuses(all_time_high_valid, multiplier_e, new_rating, old_rating, len(opponent_ratings))
- sum_of_scores = new_rating + bonus
- return sum_of_scores
-
- def bonuses(self, a: int, k_factor_e: int, r_new: float, r_old: int, n: int) -> int:
- """
- Returns the total sum of all bonuses available
- :param a: is = 1 if all time high, 0 otherwise
- :param k_factor_e: ratio of the player's k factor to the k factor used for players under 2200
- :param r_new: post-event rating
- :param r_old: pre-event rating
- :param n: number of games played
- :return: value of the new rating
- >>> ratingTest = RatingsCalculator()
- >>> ratingTest.bonuses(0, 1, 1487, 1450, 6)
- 1496
- """
- if n < 4: # no bonus points awarded if less than 4 games played
- return 0
-
- R_MAX_BONUS = 20 # constants set
- R_CHANGE_BONUS = 1.75
- R_CHANGE_THRESHOLD = 13
-
- bonus1 = a * R_MAX_BONUS * k_factor_e
- threshold = R_CHANGE_THRESHOLD * k_factor_e * math.sqrt(n)
-
- if r_new > (r_old + threshold):
- b = 1
- else:
- b = 0
-
- bonus2 = b * R_CHANGE_BONUS * (r_new - r_old - threshold) * k_factor_e
- total_bonus = round(bonus1 + bonus2)
- return total_bonus
-
- def expected_total_score(self, rating: int, opponent_ratings: list):
- """
- Returns the expected total score from the tournament
- :param rating: is the player's rating
- :param opponent_ratings: is the opponent's rating in a lists
- >>> ratingTest = RatingsCalculator()
- >>> ratingTest.expected_total_score(1450, [1237, 1511, 1214, 1441, 1579, 2133])
- 2.84
- """
- sum_expected = 0
- for opp_rating in opponent_ratings:
- if rating >= opp_rating: # your rating is bigger than the opponents
- sum_expected += self.find_expected_value(rating - opp_rating, 0)
- else:
- sum_expected += self.find_expected_value(opp_rating - rating, 1)
-
- return sum_expected
-
- def find_expected_value(self, difference: int, lower_val: int):
- """
- Returns the expected value of the individual based on whether it is a lower or higher score.
- :param lower_val: whether the number is a lower value
- :param difference: is the difference in ratings
- :return: expected value based on the expected dictionary
- """
- expected_dict = self.expected_scores
- expected = expected_dict[int(difference)]
- if lower_val == 1:
- expected = round(1 - expected, 2)
- else:
- # keep the older value
- pass
-
- return expected
-
- def expected_scores_init(self) -> dict:
- """
- Returns the expected score dictionary
- :return: dictionary containing expected scores
- """
- # file is recommend to be in the following format: starting rank, Name of Player, CFC ID
- # information of the event
- file_name = "C:\\Users\\zheng\\PycharmProjects\\ratings-calculator\\ExpectedScores.csv"
- expected_scores_higher = {}
-
- with open(file_name, 'r') as f:
- csv_reader = reader(f)
- next(csv_reader)
-
- for row in csv_reader:
- # iterate through each row
- # print(row)
- # if it's the last line
- max_diff = 2000
- if row[0][0:3] == "735":
- for j in range(735, max_diff):
- expected_scores_higher[j] = 1
- else:
- row_vals = row[0].split("-")
- starting_val = int(row_vals[0])
- end_val = int(row_vals[1])
-
- for j in range(starting_val, end_val + 1):
- expected_scores_higher[j] = float(row[1]) # the location of the csv file
-
- return expected_scores_higher
-
-
if __name__ == "__main__":
print("Welcome to Ratings Calculator\n\n"
"This project is about calculating more accurate CFC ratings than ever before. \n"
@@ -263,7 +113,7 @@ def expected_scores_init(self) -> dict:
n = int(numInput)
ratings_list = []
- for i in range(1, n+1):
+ for i in range(1, n + 1):
ele = input("Rating of player " + str(i) + ": ")
if not ele.isnumeric():
@@ -286,11 +136,14 @@ def expected_scores_init(self) -> dict:
all_time_high = int(input("All Time High Rating: "))
# established or provisional rating? (can be removed in the future))
- rating_type = int(input("Rating Type: (1 for established, 0 for provisional: "))
+ rating_type = int(input("Rating Type: (1 for established, 0 for provisional): "))
+
+ # established or provisional rating? (can be removed in the future))
+ quickTourney = int(input("Quick Tournament: (1 for quick less than 15 minutes total, 0 for classical): "))
if rating_type == 1:
# new_rating = established_ratings(1450, 1450, 4, [1237, 1511, 1214, 1441, 1579, 2133])
- calc_new_rating = ratingsCalc.established_ratings(all_time_high, current_rating, (wins+draws), ratings_list)
+ calc_new_rating = ratingsCalc.established_ratings(all_time_high, current_rating, (wins + draws), ratings_list)
else:
calc_new_rating = ratingsCalc.provisional_unrated_players(ratings_list, n, wins, losses)
diff --git a/src/ratings_calculator/player_info.json b/src/ratings_calculator/player_info.json
new file mode 100644
index 0000000..6cd648c
--- /dev/null
+++ b/src/ratings_calculator/player_info.json
@@ -0,0 +1,1540 @@
+{
+ "updated": "2023-12-21",
+ "player": {
+ "cfc_id": 150532,
+ "cfc_expiry": "2024-06-30",
+ "fide_id": 2620189,
+ "name_first": "Victor",
+ "name_last": "Zheng",
+ "addr_city": "Toronto",
+ "addr_province": "ON",
+ "regular_rating": 2073,
+ "regular_indicator": 2160,
+ "quick_rating": 2092,
+ "quick_indicator": 2092,
+ "events": [
+ {
+ "id": 202312054,
+ "name": "2023 GTCL Cup U1800",
+ "date_end": "2023-11-27",
+ "rating_type": "Q",
+ "games_played": 5,
+ "score": 5.0,
+ "rating_pre": 2002,
+ "rating_perf": 2202,
+ "rating_post": 2092,
+ "rating_indicator": 2092
+ },
+ {
+ "id": 202311050,
+ "name": "2023 ACC Hallowe'en Rapid",
+ "date_end": "2023-10-30",
+ "rating_type": "Q",
+ "games_played": 5,
+ "score": 4.0,
+ "rating_pre": 1882,
+ "rating_perf": 2132,
+ "rating_post": 2002,
+ "rating_indicator": 2002
+ },
+ {
+ "id": 202310075,
+ "name": "Hart House October Open - Crown",
+ "date_end": "2023-10-22",
+ "rating_type": "R",
+ "games_played": 5,
+ "score": 3.0,
+ "rating_pre": 2014,
+ "rating_perf": 2211,
+ "rating_post": 2073,
+ "rating_indicator": 2160
+ },
+ {
+ "id": 202307026,
+ "name": "2023 Canadian Junior Open",
+ "date_end": "2023-07-09",
+ "rating_type": "R",
+ "games_played": 6,
+ "score": 3.5,
+ "rating_pre": 2068,
+ "rating_perf": 1850,
+ "rating_post": 2014,
+ "rating_indicator": 2160
+ },
+ {
+ "id": 202306079,
+ "name": "Cdn Transnational Blitz General",
+ "date_end": "2023-06-03",
+ "rating_type": "Q",
+ "games_played": 14,
+ "score": 9.0,
+ "rating_pre": 1856,
+ "rating_perf": 1843,
+ "rating_post": 1882,
+ "rating_indicator": 1882
+ },
+ {
+ "id": 202303124,
+ "name": "5th Ivy League Challenge",
+ "date_end": "2023-03-26",
+ "rating_type": "R",
+ "games_played": 1,
+ "score": 1.0,
+ "rating_pre": 2050,
+ "rating_perf": 2503,
+ "rating_post": 2068,
+ "rating_indicator": 2160
+ },
+ {
+ "id": 202302001,
+ "name": "CUCC - Championship Section",
+ "date_end": "2023-01-29",
+ "rating_type": "R",
+ "games_played": 5,
+ "score": 2.5,
+ "rating_pre": 2043,
+ "rating_perf": 2080,
+ "rating_post": 2050,
+ "rating_indicator": 2160
+ },
+ {
+ "id": 202212022,
+ "name": "Hart House Holidays Open - Crown",
+ "date_end": "2022-12-11",
+ "rating_type": "R",
+ "games_played": 1,
+ "score": 0.0,
+ "rating_pre": 2052,
+ "rating_perf": 1808,
+ "rating_post": 2043,
+ "rating_indicator": 2160
+ },
+ {
+ "id": 202212042,
+ "name": "GTCL Cup Crown",
+ "date_end": "2022-12-05",
+ "rating_type": "Q",
+ "games_played": 5,
+ "score": 2.0,
+ "rating_pre": 1818,
+ "rating_perf": 1943,
+ "rating_post": 1856,
+ "rating_indicator": 1856
+ },
+ {
+ "id": 202211105,
+ "name": "Toronto Closed - Reserves",
+ "date_end": "2022-11-21",
+ "rating_type": "R",
+ "games_played": 9,
+ "score": 3.0,
+ "rating_pre": 2139,
+ "rating_perf": 1905,
+ "rating_post": 2052,
+ "rating_indicator": 2160
+ },
+ {
+ "id": 202209014,
+ "name": "NAYCC U18 Open",
+ "date_end": "2022-08-14",
+ "rating_type": "R",
+ "games_played": 9,
+ "score": 4.5,
+ "rating_pre": 2160,
+ "rating_perf": 2105,
+ "rating_post": 2139,
+ "rating_indicator": 2160
+ },
+ {
+ "id": 202205047,
+ "name": "2022 Ontario Open - U2200",
+ "date_end": "2022-05-23",
+ "rating_type": "R",
+ "games_played": 6,
+ "score": 5.0,
+ "rating_pre": 1918,
+ "rating_perf": 2336,
+ "rating_post": 2160,
+ "rating_indicator": 2160
+ },
+ {
+ "id": 202002048,
+ "name": "BC Open Premier",
+ "date_end": "2020-02-17",
+ "rating_type": "R",
+ "games_played": 6,
+ "score": 2.5,
+ "rating_pre": 1950,
+ "rating_perf": 1841,
+ "rating_post": 1918,
+ "rating_indicator": 2000
+ },
+ {
+ "id": 202001037,
+ "name": "2020 Victoria Open - Premier",
+ "date_end": "2020-01-19",
+ "rating_type": "R",
+ "games_played": 5,
+ "score": 3.0,
+ "rating_pre": 1965,
+ "rating_perf": 1898,
+ "rating_post": 1950,
+ "rating_indicator": 2000
+ },
+ {
+ "id": 201911058,
+ "name": "2019 BC Junior Championship",
+ "date_end": "2019-11-11",
+ "rating_type": "R",
+ "games_played": 5,
+ "score": 4.0,
+ "rating_pre": 1942,
+ "rating_perf": 2051,
+ "rating_post": 1965,
+ "rating_indicator": 2000
+ },
+ {
+ "id": 201910042,
+ "name": "New West Fall Open Premier",
+ "date_end": "2019-10-14",
+ "rating_type": "R",
+ "games_played": 6,
+ "score": 3.0,
+ "rating_pre": 1979,
+ "rating_perf": 1818,
+ "rating_post": 1942,
+ "rating_indicator": 2000
+ },
+ {
+ "id": 201908008,
+ "name": "New West Summer Open Premier",
+ "date_end": "2019-08-05",
+ "rating_type": "R",
+ "games_played": 6,
+ "score": 3.0,
+ "rating_pre": 1976,
+ "rating_perf": 1985,
+ "rating_post": 1979,
+ "rating_indicator": 2000
+ },
+ {
+ "id": 201905094,
+ "name": "Paul Keres Memorial Premier",
+ "date_end": "2019-05-20",
+ "rating_type": "R",
+ "games_played": 6,
+ "score": 2.0,
+ "rating_pre": 2000,
+ "rating_perf": 1904,
+ "rating_post": 1976,
+ "rating_indicator": 2000
+ },
+ {
+ "id": 201904097,
+ "name": "GPO 2019 Premier",
+ "date_end": "2019-04-22",
+ "rating_type": "R",
+ "games_played": 6,
+ "score": 3.0,
+ "rating_pre": 1961,
+ "rating_perf": 2038,
+ "rating_post": 2000,
+ "rating_indicator": 2000
+ },
+ {
+ "id": 201903041,
+ "name": "2019 BCYCC U16 Open",
+ "date_end": "2019-03-10",
+ "rating_type": "R",
+ "games_played": 4,
+ "score": 3.0,
+ "rating_pre": 1978,
+ "rating_perf": 1601,
+ "rating_post": 1961,
+ "rating_indicator": 1978
+ },
+ {
+ "id": 201902048,
+ "name": "2019 BC Open Premier",
+ "date_end": "2019-02-18",
+ "rating_type": "R",
+ "games_played": 6,
+ "score": 3.0,
+ "rating_pre": 1951,
+ "rating_perf": 1984,
+ "rating_post": 1978,
+ "rating_indicator": 1978
+ },
+ {
+ "id": 201901053,
+ "name": "2019 Victoria Open Premier",
+ "date_end": "2019-01-20",
+ "rating_type": "R",
+ "games_played": 5,
+ "score": 3.5,
+ "rating_pre": 1869,
+ "rating_perf": 2073,
+ "rating_post": 1951,
+ "rating_indicator": 1951
+ },
+ {
+ "id": 201811026,
+ "name": "2018 BC Junior Championship",
+ "date_end": "2018-11-12",
+ "rating_type": "R",
+ "games_played": 5,
+ "score": 3.0,
+ "rating_pre": 1876,
+ "rating_perf": 1799,
+ "rating_post": 1869,
+ "rating_indicator": 1876
+ },
+ {
+ "id": 201810029,
+ "name": "New West Open 2018 Premier",
+ "date_end": "2018-10-08",
+ "rating_type": "R",
+ "games_played": 6,
+ "score": 4.0,
+ "rating_pre": 1772,
+ "rating_perf": 2016,
+ "rating_post": 1876,
+ "rating_indicator": 1876
+ },
+ {
+ "id": 201808026,
+ "name": "2018 Semiahmoo Open Premier",
+ "date_end": "2018-08-06",
+ "rating_type": "R",
+ "games_played": 6,
+ "score": 1.0,
+ "rating_pre": 1808,
+ "rating_perf": 1666,
+ "rating_post": 1772,
+ "rating_indicator": 1852
+ },
+ {
+ "id": 201804019,
+ "name": "Grand Pacific Open U2000",
+ "date_end": "2018-04-02",
+ "rating_type": "R",
+ "games_played": 6,
+ "score": 4.0,
+ "rating_pre": 1788,
+ "rating_perf": 1875,
+ "rating_post": 1808,
+ "rating_indicator": 1852
+ },
+ {
+ "id": 201802024,
+ "name": "2018 BC Open Premier",
+ "date_end": "2018-02-12",
+ "rating_type": "R",
+ "games_played": 5,
+ "score": 1.5,
+ "rating_pre": 1808,
+ "rating_perf": 1715,
+ "rating_post": 1788,
+ "rating_indicator": 1852
+ },
+ {
+ "id": 201711054,
+ "name": "2017 BC Junior Championship",
+ "date_end": "2017-11-13",
+ "rating_type": "R",
+ "games_played": 5,
+ "score": 3.0,
+ "rating_pre": 1814,
+ "rating_perf": 1764,
+ "rating_post": 1808,
+ "rating_indicator": 1852
+ },
+ {
+ "id": 201705101,
+ "name": "Keres Memorial Premier",
+ "date_end": "2017-05-22",
+ "rating_type": "R",
+ "games_played": 5,
+ "score": 2.0,
+ "rating_pre": 1819,
+ "rating_perf": 1819,
+ "rating_post": 1814,
+ "rating_indicator": 1852
+ },
+ {
+ "id": 201704070,
+ "name": "11th Grand Pacific Open Premier",
+ "date_end": "2017-04-17",
+ "rating_type": "R",
+ "games_played": 6,
+ "score": 2.0,
+ "rating_pre": 1814,
+ "rating_perf": 1825,
+ "rating_post": 1819,
+ "rating_indicator": 1852
+ },
+ {
+ "id": 201702066,
+ "name": "2017 BC Open Premier",
+ "date_end": "2017-02-13",
+ "rating_type": "R",
+ "games_played": 6,
+ "score": 1.5,
+ "rating_pre": 1849,
+ "rating_perf": 1706,
+ "rating_post": 1814,
+ "rating_indicator": 1852
+ },
+ {
+ "id": 201611047,
+ "name": "2016 BC Junior Championship",
+ "date_end": "2016-11-13",
+ "rating_type": "R",
+ "games_played": 5,
+ "score": 2.5,
+ "rating_pre": 1822,
+ "rating_perf": 1965,
+ "rating_post": 1849,
+ "rating_indicator": 1852
+ },
+ {
+ "id": 201608025,
+ "name": "2016 NAYCC U12",
+ "date_end": "2016-08-11",
+ "rating_type": "R",
+ "games_played": 9,
+ "score": 5.0,
+ "rating_pre": 1852,
+ "rating_perf": 1755,
+ "rating_post": 1822,
+ "rating_indicator": 1852
+ },
+ {
+ "id": 201606004,
+ "name": "2016 Paul Keres U2000",
+ "date_end": "2016-05-23",
+ "rating_type": "R",
+ "games_played": 6,
+ "score": 4.5,
+ "rating_pre": 1717,
+ "rating_perf": 1970,
+ "rating_post": 1852,
+ "rating_indicator": 1852
+ },
+ {
+ "id": 201603087,
+ "name": "10th Grand Pacific Open Premier",
+ "date_end": "2016-03-28",
+ "rating_type": "R",
+ "games_played": 6,
+ "score": 1.5,
+ "rating_pre": 1712,
+ "rating_perf": 1771,
+ "rating_post": 1717,
+ "rating_indicator": 1764
+ },
+ {
+ "id": 201602021,
+ "name": "2016 BC Open U1900",
+ "date_end": "2016-02-08",
+ "rating_type": "R",
+ "games_played": 6,
+ "score": 4.5,
+ "rating_pre": 1688,
+ "rating_perf": 1785,
+ "rating_post": 1712,
+ "rating_indicator": 1764
+ },
+ {
+ "id": 201511042,
+ "name": "Vancouver West Open #8",
+ "date_end": "2015-11-15",
+ "rating_type": "R",
+ "games_played": 6,
+ "score": 3.0,
+ "rating_pre": 1743,
+ "rating_perf": 1495,
+ "rating_post": 1688,
+ "rating_indicator": 1764
+ },
+ {
+ "id": 201509048,
+ "name": "Vancouver West Open #7",
+ "date_end": "2015-09-27",
+ "rating_type": "R",
+ "games_played": 6,
+ "score": 2.5,
+ "rating_pre": 1764,
+ "rating_perf": 1694,
+ "rating_post": 1743,
+ "rating_indicator": 1764
+ },
+ {
+ "id": 201505066,
+ "name": "2015 Paul Keres Memorial U2000",
+ "date_end": "2015-05-18",
+ "rating_type": "R",
+ "games_played": 6,
+ "score": 3.0,
+ "rating_pre": 1701,
+ "rating_perf": 1855,
+ "rating_post": 1764,
+ "rating_indicator": 1764
+ },
+ {
+ "id": 201504043,
+ "name": "9th Grand Pacific Open U1900",
+ "date_end": "2015-04-06",
+ "rating_type": "R",
+ "games_played": 6,
+ "score": 4.0,
+ "rating_pre": 1539,
+ "rating_perf": 1837,
+ "rating_post": 1701,
+ "rating_indicator": 1701
+ },
+ {
+ "id": 201504012,
+ "name": "BCYCC U12 Open",
+ "date_end": "2015-03-29",
+ "rating_type": "R",
+ "games_played": 5,
+ "score": 3.0,
+ "rating_pre": 1494,
+ "rating_perf": 1606,
+ "rating_post": 1539,
+ "rating_indicator": 1539
+ },
+ {
+ "id": 201503015,
+ "name": "Vancouver West Open #4",
+ "date_end": "2015-03-08",
+ "rating_type": "R",
+ "games_played": 6,
+ "score": 3.0,
+ "rating_pre": 1371,
+ "rating_perf": 1780,
+ "rating_post": 1494,
+ "rating_indicator": 1494
+ },
+ {
+ "id": 201502019,
+ "name": "2015 BC Open U1900",
+ "date_end": "2015-02-09",
+ "rating_type": "R",
+ "games_played": 6,
+ "score": 2.0,
+ "rating_pre": 1365,
+ "rating_perf": 1391,
+ "rating_post": 1371,
+ "rating_indicator": 1481
+ },
+ {
+ "id": 201501023,
+ "name": "West Vancouver Open #3",
+ "date_end": "2015-01-25",
+ "rating_type": "R",
+ "games_played": 5,
+ "score": 1.5,
+ "rating_pre": 1428,
+ "rating_perf": 1182,
+ "rating_post": 1365,
+ "rating_indicator": 1481
+ },
+ {
+ "id": 201412019,
+ "name": "Vancouver West Open #2",
+ "date_end": "2014-12-07",
+ "rating_type": "R",
+ "games_played": 6,
+ "score": 2.5,
+ "rating_pre": 1427,
+ "rating_perf": 1529,
+ "rating_post": 1428,
+ "rating_indicator": 1481
+ },
+ {
+ "id": 201411027,
+ "name": "2014 BC Junior Championship",
+ "date_end": "2014-11-09",
+ "rating_type": "R",
+ "games_played": 5,
+ "score": 1.5,
+ "rating_pre": 1399,
+ "rating_perf": 1576,
+ "rating_post": 1427,
+ "rating_indicator": 1481
+ },
+ {
+ "id": 201410050,
+ "name": "2014 Vancouver West Open",
+ "date_end": "2014-10-26",
+ "rating_type": "R",
+ "games_played": 6,
+ "score": 3.0,
+ "rating_pre": 1420,
+ "rating_perf": 1401,
+ "rating_post": 1399,
+ "rating_indicator": 1481
+ },
+ {
+ "id": 201408021,
+ "name": "BC Day Open, 2014",
+ "date_end": "2014-08-04",
+ "rating_type": "R",
+ "games_played": 6,
+ "score": 2.5,
+ "rating_pre": 1451,
+ "rating_perf": 1303,
+ "rating_post": 1420,
+ "rating_indicator": 1481
+ },
+ {
+ "id": 201405043,
+ "name": "2014 Keres Memorial - U1600",
+ "date_end": "2014-05-19",
+ "rating_type": "R",
+ "games_played": 6,
+ "score": 4.5,
+ "rating_pre": 1463,
+ "rating_perf": 1376,
+ "rating_post": 1451,
+ "rating_indicator": 1481
+ },
+ {
+ "id": 201404069,
+ "name": "8th Grand Pacific Open - U1800",
+ "date_end": "2014-04-21",
+ "rating_type": "R",
+ "games_played": 6,
+ "score": 3.5,
+ "rating_pre": 1481,
+ "rating_perf": 1371,
+ "rating_post": 1463,
+ "rating_indicator": 1481
+ },
+ {
+ "id": 201402017,
+ "name": "2014 BC Open - U1800",
+ "date_end": "2014-02-10",
+ "rating_type": "R",
+ "games_played": 6,
+ "score": 4.5,
+ "rating_pre": 1324,
+ "rating_perf": 1617,
+ "rating_post": 1481,
+ "rating_indicator": 1481
+ },
+ {
+ "id": 201311087,
+ "name": "2013 November VCS Open",
+ "date_end": "2013-11-24",
+ "rating_type": "R",
+ "games_played": 5,
+ "score": 2.5,
+ "rating_pre": 1305,
+ "rating_perf": 1434,
+ "rating_post": 1324,
+ "rating_indicator": 1390
+ },
+ {
+ "id": 201311050,
+ "name": "2013 BCCF Junior Reserves",
+ "date_end": "2013-11-10",
+ "rating_type": "R",
+ "games_played": 5,
+ "score": 3.5,
+ "rating_pre": 1334,
+ "rating_perf": 1075,
+ "rating_post": 1305,
+ "rating_indicator": 1390
+ },
+ {
+ "id": 201311042,
+ "name": "2013 October VCS U1600",
+ "date_end": "2013-10-27",
+ "rating_type": "R",
+ "games_played": 5,
+ "score": 2.5,
+ "rating_pre": 1390,
+ "rating_perf": 1062,
+ "rating_post": 1334,
+ "rating_indicator": 1390
+ },
+ {
+ "id": 201311039,
+ "name": "2013 Vancouver Open",
+ "date_end": "2013-10-15",
+ "rating_type": "R",
+ "games_played": 6,
+ "score": 3.0,
+ "rating_pre": 1178,
+ "rating_perf": 1799,
+ "rating_post": 1390,
+ "rating_indicator": 1390
+ },
+ {
+ "id": 201309042,
+ "name": "2013 Vancouver September U1800",
+ "date_end": "2013-09-22",
+ "rating_type": "R",
+ "games_played": 4,
+ "score": 3.0,
+ "rating_pre": 1136,
+ "rating_perf": 1267,
+ "rating_post": 1178,
+ "rating_indicator": 1178
+ },
+ {
+ "id": 201308025,
+ "name": "2013 NAYCC - U10",
+ "date_end": "2013-08-18",
+ "rating_type": "R",
+ "games_played": 9,
+ "score": 5.0,
+ "rating_pre": 1016,
+ "rating_perf": 1227,
+ "rating_post": 1136,
+ "rating_indicator": 1136
+ },
+ {
+ "id": 201304020,
+ "name": "VCS April Juniors",
+ "date_end": "2013-04-14",
+ "rating_type": "R",
+ "games_played": 3,
+ "score": 2.0,
+ "rating_pre": 1013,
+ "rating_perf": 1042,
+ "rating_post": 1016,
+ "rating_indicator": 1016
+ },
+ {
+ "id": 201304001,
+ "name": "7th Annual Grand Pacific Open U1800",
+ "date_end": "2013-04-01",
+ "rating_type": "R",
+ "games_played": 6,
+ "score": 2.5,
+ "rating_pre": 859,
+ "rating_perf": 1348,
+ "rating_post": 1013,
+ "rating_indicator": 1013
+ },
+ {
+ "id": 201304057,
+ "name": "2013 Victoria YCC U10",
+ "date_end": "2013-03-29",
+ "rating_type": "Q",
+ "games_played": 5,
+ "score": 5.0,
+ "rating_pre": 745,
+ "rating_perf": 1267,
+ "rating_post": 1180,
+ "rating_indicator": 6
+ },
+ {
+ "id": 201302029,
+ "name": "Vancouver Chess School Feb 2013",
+ "date_end": "2013-02-17",
+ "rating_type": "R",
+ "games_played": 3,
+ "score": 1.0,
+ "rating_pre": 872,
+ "rating_perf": 764,
+ "rating_post": 859,
+ "rating_indicator": 872
+ },
+ {
+ "id": 201212006,
+ "name": "2012 BC Junior Ch Reserves",
+ "date_end": "2012-12-02",
+ "rating_type": "R",
+ "games_played": 5,
+ "score": 2.5,
+ "rating_pre": 836,
+ "rating_perf": 948,
+ "rating_post": 872,
+ "rating_indicator": 872
+ },
+ {
+ "id": 201207018,
+ "name": "2012 Canadian Youth Ch U8 Open",
+ "date_end": "2012-07-06",
+ "rating_type": "R",
+ "games_played": 7,
+ "score": 4.0,
+ "rating_pre": 846,
+ "rating_perf": 791,
+ "rating_post": 836,
+ "rating_indicator": 846
+ },
+ {
+ "id": 201204025,
+ "name": "2012 BCYCC U8 Open",
+ "date_end": "2012-04-22",
+ "rating_type": "R",
+ "games_played": 5,
+ "score": 4.0,
+ "rating_pre": 745,
+ "rating_perf": 987,
+ "rating_post": 846,
+ "rating_indicator": 846
+ },
+ {
+ "id": 201111017,
+ "name": "2011 BC Junior Ch Boosters",
+ "date_end": "2011-11-13",
+ "rating_type": "R",
+ "games_played": 5,
+ "score": 3.0,
+ "rating_pre": 745,
+ "rating_perf": 682,
+ "rating_post": 745,
+ "rating_indicator": 745
+ },
+ {
+ "id": 201110029,
+ "name": "October Junior Open Intermediate",
+ "date_end": "2011-10-15",
+ "rating_type": "R",
+ "games_played": 4,
+ "score": 1.0,
+ "rating_pre": 745,
+ "rating_perf": 530,
+ "rating_post": 745,
+ "rating_indicator": 745
+ },
+ {
+ "id": 201105009,
+ "name": "2011 BCYCC U8 Open",
+ "date_end": "2011-05-01",
+ "rating_type": "R",
+ "games_played": 5,
+ "score": 3.5,
+ "rating_pre": 684,
+ "rating_perf": 966,
+ "rating_post": 745,
+ "rating_indicator": 745
+ },
+ {
+ "id": 201104018,
+ "name": "2011 BC Chess Challenge Gr 1",
+ "date_end": "2011-04-09",
+ "rating_type": "R",
+ "games_played": 5,
+ "score": 4.5,
+ "rating_pre": 633,
+ "rating_perf": 869,
+ "rating_post": 684,
+ "rating_indicator": 684
+ },
+ {
+ "id": 201103046,
+ "name": "Vancouver Regional Grade K-1",
+ "date_end": "2011-03-12",
+ "rating_type": "R",
+ "games_played": 5,
+ "score": 4.0,
+ "rating_pre": 595,
+ "rating_perf": 731,
+ "rating_post": 633,
+ "rating_indicator": 633
+ },
+ {
+ "id": 201102045,
+ "name": "2011 Valentines Scholastic Gr 1",
+ "date_end": "2011-02-20",
+ "rating_type": "R",
+ "games_played": 5,
+ "score": 3.0,
+ "rating_pre": 590,
+ "rating_perf": 585,
+ "rating_post": 595,
+ "rating_indicator": 595
+ },
+ {
+ "id": 201101029,
+ "name": "New Year Scholastic Grade K to 1",
+ "date_end": "2011-01-15",
+ "rating_type": "R",
+ "games_played": 4,
+ "score": 4.0,
+ "rating_pre": 532,
+ "rating_perf": 795,
+ "rating_post": 590,
+ "rating_indicator": 22
+ },
+ {
+ "id": 201010050,
+ "name": "October Junior Beginner U800",
+ "date_end": "2010-10-23",
+ "rating_type": "R",
+ "games_played": 5,
+ "score": 2.5,
+ "rating_pre": 441,
+ "rating_perf": 768,
+ "rating_post": 532,
+ "rating_indicator": 18
+ },
+ {
+ "id": 201004029,
+ "name": "2010 BC Provincials Gr K",
+ "date_end": "2010-04-11",
+ "rating_type": "R",
+ "games_played": 3,
+ "score": 3.0,
+ "rating_pre": 293,
+ "rating_perf": 908,
+ "rating_post": 441,
+ "rating_indicator": 13
+ },
+ {
+ "id": 201002065,
+ "name": "Vanc Reg Chess Chall Grade K 1",
+ "date_end": "2010-02-21",
+ "rating_type": "R",
+ "games_played": 5,
+ "score": 1.0,
+ "rating_pre": 306,
+ "rating_perf": 260,
+ "rating_post": 293,
+ "rating_indicator": 10
+ },
+ {
+ "id": 201001048,
+ "name": "Sprott Shaw Scholastic Gr K to 2",
+ "date_end": "2010-01-24",
+ "rating_type": "R",
+ "games_played": 5,
+ "score": 2.0,
+ "rating_pre": 0,
+ "rating_perf": 296,
+ "rating_post": 306,
+ "rating_indicator": 5
+ }
+ ],
+ "orgarb": [
+ {
+ "id": 202312038,
+ "name": "Hart House Holidays Open - Crown",
+ "date_end": "2023-12-10",
+ "province": "ON",
+ "organizer_id": 150532,
+ "arbiter_id": 127516,
+ "pairings": "SS",
+ "rating_type": "R",
+ "n_players": 16,
+ "n_rounds": 5,
+ "organizer_name": "Victor Zheng",
+ "arbiter_name": "Alex T. Ferreira"
+ },
+ {
+ "id": 202312039,
+ "name": "Hart House Holidays Open - U1300",
+ "date_end": "2023-12-10",
+ "province": "ON",
+ "organizer_id": 150532,
+ "arbiter_id": 127516,
+ "pairings": "SS",
+ "rating_type": "R",
+ "n_players": 47,
+ "n_rounds": 5,
+ "organizer_name": "Victor Zheng",
+ "arbiter_name": "Alex T. Ferreira"
+ },
+ {
+ "id": 202312040,
+ "name": "Hart House Holidays Open - U1600",
+ "date_end": "2023-12-10",
+ "province": "ON",
+ "organizer_id": 150532,
+ "arbiter_id": 127516,
+ "pairings": "SS",
+ "rating_type": "R",
+ "n_players": 44,
+ "n_rounds": 5,
+ "organizer_name": "Victor Zheng",
+ "arbiter_name": "Alex T. Ferreira"
+ },
+ {
+ "id": 202312041,
+ "name": "Hart House Holidays Open - U1900",
+ "date_end": "2023-12-10",
+ "province": "ON",
+ "organizer_id": 150532,
+ "arbiter_id": 127516,
+ "pairings": "SS",
+ "rating_type": "R",
+ "n_players": 45,
+ "n_rounds": 5,
+ "organizer_name": "Victor Zheng",
+ "arbiter_name": "Alex T. Ferreira"
+ },
+ {
+ "id": 202312042,
+ "name": "Hart House Holidays Open - U2200",
+ "date_end": "2023-12-10",
+ "province": "ON",
+ "organizer_id": 150532,
+ "arbiter_id": 127516,
+ "pairings": "SS",
+ "rating_type": "R",
+ "n_players": 36,
+ "n_rounds": 5,
+ "organizer_name": "Victor Zheng",
+ "arbiter_name": "Alex T. Ferreira"
+ },
+ {
+ "id": 202312043,
+ "name": "Hart House Holidays Open Jrs U1100",
+ "date_end": "2023-12-10",
+ "province": "ON",
+ "organizer_id": 150532,
+ "arbiter_id": 111715,
+ "pairings": "SS",
+ "rating_type": "R",
+ "n_players": 11,
+ "n_rounds": 6,
+ "organizer_name": "Victor Zheng",
+ "arbiter_name": "Michael Corrie"
+ },
+ {
+ "id": 202312044,
+ "name": "Hart House Holidays Open Jrs U800",
+ "date_end": "2023-12-10",
+ "province": "ON",
+ "organizer_id": 150532,
+ "arbiter_id": 111715,
+ "pairings": "SS",
+ "rating_type": "R",
+ "n_players": 13,
+ "n_rounds": 6,
+ "organizer_name": "Victor Zheng",
+ "arbiter_name": "Michael Corrie"
+ },
+ {
+ "id": 202311052,
+ "name": "2023 Hart House Rapid Championship",
+ "date_end": "2023-11-05",
+ "province": "ON",
+ "organizer_id": 150532,
+ "arbiter_id": 150532,
+ "pairings": "SS",
+ "rating_type": "Q",
+ "n_players": 25,
+ "n_rounds": 6,
+ "organizer_name": "Victor Zheng",
+ "arbiter_name": "Victor Zheng"
+ },
+ {
+ "id": 202311053,
+ "name": "2023 Hart House Rapid U1200",
+ "date_end": "2023-11-05",
+ "province": "ON",
+ "organizer_id": 150532,
+ "arbiter_id": 150532,
+ "pairings": "SS",
+ "rating_type": "Q",
+ "n_players": 34,
+ "n_rounds": 6,
+ "organizer_name": "Victor Zheng",
+ "arbiter_name": "Victor Zheng"
+ },
+ {
+ "id": 202311054,
+ "name": "2023 Hart House Rapid U1800",
+ "date_end": "2023-11-05",
+ "province": "ON",
+ "organizer_id": 150532,
+ "arbiter_id": 150532,
+ "pairings": "SS",
+ "rating_type": "Q",
+ "n_players": 49,
+ "n_rounds": 6,
+ "organizer_name": "Victor Zheng",
+ "arbiter_name": "Victor Zheng"
+ },
+ {
+ "id": 202308085,
+ "name": "Hart House Summer Junior U1300",
+ "date_end": "2023-08-26",
+ "province": "ON",
+ "organizer_id": 150532,
+ "arbiter_id": 150532,
+ "pairings": "SS",
+ "rating_type": "R",
+ "n_players": 25,
+ "n_rounds": 4,
+ "organizer_name": "Victor Zheng",
+ "arbiter_name": "Victor Zheng"
+ },
+ {
+ "id": 202308086,
+ "name": "Hart House Summer Junior U900",
+ "date_end": "2023-08-26",
+ "province": "ON",
+ "organizer_id": 150532,
+ "arbiter_id": 150532,
+ "pairings": "SS",
+ "rating_type": "R",
+ "n_players": 27,
+ "n_rounds": 4,
+ "organizer_name": "Victor Zheng",
+ "arbiter_name": "Victor Zheng"
+ },
+ {
+ "id": 202307041,
+ "name": "Hart House Summer Blitz Premier",
+ "date_end": "2023-07-15",
+ "province": "ON",
+ "organizer_id": 150532,
+ "arbiter_id": 150532,
+ "pairings": "SS",
+ "rating_type": "Q",
+ "n_players": 64,
+ "n_rounds": 14,
+ "organizer_name": "Victor Zheng",
+ "arbiter_name": "Victor Zheng"
+ },
+ {
+ "id": 202307042,
+ "name": "Hart House Summer Blitz U1500",
+ "date_end": "2023-07-15",
+ "province": "ON",
+ "organizer_id": 150532,
+ "arbiter_id": 150532,
+ "pairings": "SS",
+ "rating_type": "Q",
+ "n_players": 42,
+ "n_rounds": 14,
+ "organizer_name": "Victor Zheng",
+ "arbiter_name": "Victor Zheng"
+ },
+ {
+ "id": 202307043,
+ "name": "Hart House Summer Rapid Premier",
+ "date_end": "2023-07-15",
+ "province": "ON",
+ "organizer_id": 150532,
+ "arbiter_id": 150532,
+ "pairings": "SS",
+ "rating_type": "Q",
+ "n_players": 49,
+ "n_rounds": 5,
+ "organizer_name": "Victor Zheng",
+ "arbiter_name": "Victor Zheng"
+ },
+ {
+ "id": 202307044,
+ "name": "Hart House Summer Rapid U1000",
+ "date_end": "2023-07-15",
+ "province": "ON",
+ "organizer_id": 150532,
+ "arbiter_id": 150532,
+ "pairings": "SS",
+ "rating_type": "Q",
+ "n_players": 32,
+ "n_rounds": 5,
+ "organizer_name": "Victor Zheng",
+ "arbiter_name": "Victor Zheng"
+ },
+ {
+ "id": 202307045,
+ "name": "Hart House Summer Rapid U1600",
+ "date_end": "2023-07-15",
+ "province": "ON",
+ "organizer_id": 150532,
+ "arbiter_id": 150532,
+ "pairings": "SS",
+ "rating_type": "Q",
+ "n_players": 42,
+ "n_rounds": 5,
+ "organizer_name": "Victor Zheng",
+ "arbiter_name": "Victor Zheng"
+ },
+ {
+ "id": 202305031,
+ "name": "Hart House Youth Chess U10",
+ "date_end": "2023-04-29",
+ "province": "ON",
+ "organizer_id": 150532,
+ "arbiter_id": 150532,
+ "pairings": "SS",
+ "rating_type": "Q",
+ "n_players": 25,
+ "n_rounds": 5,
+ "organizer_name": "Victor Zheng",
+ "arbiter_name": "Victor Zheng"
+ },
+ {
+ "id": 202305032,
+ "name": "Hart House Youth Chess U12",
+ "date_end": "2023-04-29",
+ "province": "ON",
+ "organizer_id": 150532,
+ "arbiter_id": 150532,
+ "pairings": "SS",
+ "rating_type": "Q",
+ "n_players": 38,
+ "n_rounds": 5,
+ "organizer_name": "Victor Zheng",
+ "arbiter_name": "Victor Zheng"
+ },
+ {
+ "id": 202305033,
+ "name": "Hart House Youth Chess U14",
+ "date_end": "2023-04-29",
+ "province": "ON",
+ "organizer_id": 150532,
+ "arbiter_id": 150532,
+ "pairings": "SS",
+ "rating_type": "Q",
+ "n_players": 48,
+ "n_rounds": 5,
+ "organizer_name": "Victor Zheng",
+ "arbiter_name": "Victor Zheng"
+ },
+ {
+ "id": 202305034,
+ "name": "Hart House Youth Chess U16",
+ "date_end": "2023-04-29",
+ "province": "ON",
+ "organizer_id": 150532,
+ "arbiter_id": 150532,
+ "pairings": "SS",
+ "rating_type": "Q",
+ "n_players": 10,
+ "n_rounds": 5,
+ "organizer_name": "Victor Zheng",
+ "arbiter_name": "Victor Zheng"
+ },
+ {
+ "id": 202305035,
+ "name": "Hart House Youth Chess U18",
+ "date_end": "2023-04-29",
+ "province": "ON",
+ "organizer_id": 150532,
+ "arbiter_id": 150532,
+ "pairings": "SS",
+ "rating_type": "Q",
+ "n_players": 8,
+ "n_rounds": 5,
+ "organizer_name": "Victor Zheng",
+ "arbiter_name": "Victor Zheng"
+ },
+ {
+ "id": 202305036,
+ "name": "Hart House Youth Chess U8",
+ "date_end": "2023-04-29",
+ "province": "ON",
+ "organizer_id": 150532,
+ "arbiter_id": 150532,
+ "pairings": "SS",
+ "rating_type": "Q",
+ "n_players": 26,
+ "n_rounds": 5,
+ "organizer_name": "Victor Zheng",
+ "arbiter_name": "Victor Zheng"
+ },
+ {
+ "id": 202303124,
+ "name": "5th Ivy League Challenge",
+ "date_end": "2023-03-26",
+ "province": "ON",
+ "organizer_id": 150532,
+ "arbiter_id": 127516,
+ "pairings": "SS",
+ "rating_type": "R",
+ "n_players": 29,
+ "n_rounds": 5,
+ "organizer_name": "Victor Zheng",
+ "arbiter_name": "Alex T. Ferreira"
+ },
+ {
+ "id": 202303076,
+ "name": "Hart House Spring Junior Open 2023",
+ "date_end": "2023-03-18",
+ "province": "ON",
+ "organizer_id": 150532,
+ "arbiter_id": 150532,
+ "pairings": "SS",
+ "rating_type": "R",
+ "n_players": 10,
+ "n_rounds": 4,
+ "organizer_name": "Victor Zheng",
+ "arbiter_name": "Victor Zheng"
+ },
+ {
+ "id": 202303077,
+ "name": "Hart House Spring Junior U1300",
+ "date_end": "2023-03-18",
+ "province": "ON",
+ "organizer_id": 150532,
+ "arbiter_id": 150532,
+ "pairings": "SS",
+ "rating_type": "R",
+ "n_players": 29,
+ "n_rounds": 4,
+ "organizer_name": "Victor Zheng",
+ "arbiter_name": "Victor Zheng"
+ },
+ {
+ "id": 202303078,
+ "name": "Hart House Spring Junior U900",
+ "date_end": "2023-03-18",
+ "province": "ON",
+ "organizer_id": 150532,
+ "arbiter_id": 150532,
+ "pairings": "SS",
+ "rating_type": "R",
+ "n_players": 28,
+ "n_rounds": 4,
+ "organizer_name": "Victor Zheng",
+ "arbiter_name": "Victor Zheng"
+ },
+ {
+ "id": 202303011,
+ "name": "GTCL 2023 Bronze Cup",
+ "date_end": "2023-02-28",
+ "province": "ON",
+ "organizer_id": 150532,
+ "arbiter_id": 150532,
+ "pairings": "SS",
+ "rating_type": "R",
+ "n_players": 19,
+ "n_rounds": 3,
+ "organizer_name": "Victor Zheng",
+ "arbiter_name": "Victor Zheng"
+ },
+ {
+ "id": 202303012,
+ "name": "GTCL 2023 Gold Cup",
+ "date_end": "2023-02-28",
+ "province": "ON",
+ "organizer_id": 150532,
+ "arbiter_id": 150532,
+ "pairings": "SS",
+ "rating_type": "R",
+ "n_players": 19,
+ "n_rounds": 3,
+ "organizer_name": "Victor Zheng",
+ "arbiter_name": "Victor Zheng"
+ },
+ {
+ "id": 202303013,
+ "name": "GTCL 2023 Silver Cup",
+ "date_end": "2023-02-28",
+ "province": "ON",
+ "organizer_id": 150532,
+ "arbiter_id": 150532,
+ "pairings": "SS",
+ "rating_type": "R",
+ "n_players": 16,
+ "n_rounds": 3,
+ "organizer_name": "Victor Zheng",
+ "arbiter_name": "Victor Zheng"
+ },
+ {
+ "id": 202302081,
+ "name": "Hart House Reading Week Crown",
+ "date_end": "2023-02-20",
+ "province": "ON",
+ "organizer_id": 150532,
+ "arbiter_id": 127516,
+ "pairings": "SS",
+ "rating_type": "R",
+ "n_players": 25,
+ "n_rounds": 6,
+ "organizer_name": "Victor Zheng",
+ "arbiter_name": "Alex T. Ferreira"
+ },
+ {
+ "id": 202302082,
+ "name": "Hart House Reading Week U1000",
+ "date_end": "2023-02-20",
+ "province": "ON",
+ "organizer_id": 150532,
+ "arbiter_id": 127516,
+ "pairings": "SS",
+ "rating_type": "R",
+ "n_players": 28,
+ "n_rounds": 6,
+ "organizer_name": "Victor Zheng",
+ "arbiter_name": "Alex T. Ferreira"
+ },
+ {
+ "id": 202302083,
+ "name": "Hart House Reading Week U1300",
+ "date_end": "2023-02-20",
+ "province": "ON",
+ "organizer_id": 150532,
+ "arbiter_id": 127516,
+ "pairings": "SS",
+ "rating_type": "R",
+ "n_players": 50,
+ "n_rounds": 6,
+ "organizer_name": "Victor Zheng",
+ "arbiter_name": "Alex T. Ferreira"
+ },
+ {
+ "id": 202303001,
+ "name": "GTCL 2023 Pool B",
+ "date_end": "2023-02-07",
+ "province": "ON",
+ "organizer_id": 150532,
+ "arbiter_id": 150532,
+ "pairings": "SS",
+ "rating_type": "R",
+ "n_players": 33,
+ "n_rounds": 5,
+ "organizer_name": "Victor Zheng",
+ "arbiter_name": "Victor Zheng"
+ },
+ {
+ "id": 202303002,
+ "name": "GTCL 2023 Pool A",
+ "date_end": "2023-02-07",
+ "province": "ON",
+ "organizer_id": 150532,
+ "arbiter_id": 150532,
+ "pairings": "SS",
+ "rating_type": "R",
+ "n_players": 37,
+ "n_rounds": 5,
+ "organizer_name": "Victor Zheng",
+ "arbiter_name": "Victor Zheng"
+ },
+ {
+ "id": 202302020,
+ "name": "Hart House Weekly Winter Swiss",
+ "date_end": "2023-01-31",
+ "province": "ON",
+ "organizer_id": 150532,
+ "arbiter_id": 150532,
+ "pairings": "SS",
+ "rating_type": "R",
+ "n_players": 16,
+ "n_rounds": 4,
+ "organizer_name": "Victor Zheng",
+ "arbiter_name": "Victor Zheng"
+ },
+ {
+ "id": 202212022,
+ "name": "Hart House Holidays Open - Crown",
+ "date_end": "2022-12-11",
+ "province": "ON",
+ "organizer_id": 150532,
+ "arbiter_id": 127516,
+ "pairings": "SS",
+ "rating_type": "R",
+ "n_players": 22,
+ "n_rounds": 5,
+ "organizer_name": "Victor Zheng",
+ "arbiter_name": "Alex T. Ferreira"
+ },
+ {
+ "id": 202212023,
+ "name": "Hart House Holidays Open - U1000",
+ "date_end": "2022-12-11",
+ "province": "ON",
+ "organizer_id": 150532,
+ "arbiter_id": 127516,
+ "pairings": "SS",
+ "rating_type": "R",
+ "n_players": 32,
+ "n_rounds": 5,
+ "organizer_name": "Victor Zheng",
+ "arbiter_name": "Alex T. Ferreira"
+ },
+ {
+ "id": 202212024,
+ "name": "Hart House Holidays Open - U1300",
+ "date_end": "2022-12-11",
+ "province": "ON",
+ "organizer_id": 150532,
+ "arbiter_id": 127516,
+ "pairings": "SS",
+ "rating_type": "R",
+ "n_players": 39,
+ "n_rounds": 5,
+ "organizer_name": "Victor Zheng",
+ "arbiter_name": "Alex T. Ferreira"
+ },
+ {
+ "id": 202212025,
+ "name": "Hart House Holidays Open - U1600",
+ "date_end": "2022-12-11",
+ "province": "ON",
+ "organizer_id": 150532,
+ "arbiter_id": 127516,
+ "pairings": "SS",
+ "rating_type": "R",
+ "n_players": 57,
+ "n_rounds": 5,
+ "organizer_name": "Victor Zheng",
+ "arbiter_name": "Alex T. Ferreira"
+ },
+ {
+ "id": 202212026,
+ "name": "Hart House Holidays Open - U1900",
+ "date_end": "2022-12-11",
+ "province": "ON",
+ "organizer_id": 150532,
+ "arbiter_id": 127516,
+ "pairings": "SS",
+ "rating_type": "R",
+ "n_players": 42,
+ "n_rounds": 5,
+ "organizer_name": "Victor Zheng",
+ "arbiter_name": "Alex T. Ferreira"
+ },
+ {
+ "id": 202212027,
+ "name": "Hart House Holidays Open - U2200",
+ "date_end": "2022-12-11",
+ "province": "ON",
+ "organizer_id": 150532,
+ "arbiter_id": 127516,
+ "pairings": "SS",
+ "rating_type": "R",
+ "n_players": 24,
+ "n_rounds": 5,
+ "organizer_name": "Victor Zheng",
+ "arbiter_name": "Alex T. Ferreira"
+ },
+ {
+ "id": 202211086,
+ "name": "Hart House Rapid & Raffle U1400",
+ "date_end": "2022-11-12",
+ "province": "ON",
+ "organizer_id": 150532,
+ "arbiter_id": 127516,
+ "pairings": "SS",
+ "rating_type": "Q",
+ "n_players": 21,
+ "n_rounds": 6,
+ "organizer_name": "Victor Zheng",
+ "arbiter_name": "Alex T. Ferreira"
+ },
+ {
+ "id": 202211087,
+ "name": "Hart House Rapid Raffle Fundraiser",
+ "date_end": "2022-11-12",
+ "province": "ON",
+ "organizer_id": 150532,
+ "arbiter_id": 127516,
+ "pairings": "SS",
+ "rating_type": "Q",
+ "n_players": 29,
+ "n_rounds": 6,
+ "organizer_name": "Victor Zheng",
+ "arbiter_name": "Alex T. Ferreira"
+ }
+ ],
+ "is_organizer": true,
+ "is_arbiter": true
+ },
+ "apicode": 0,
+ "error": ""
+}
diff --git a/src/ratings_calculator/rating_tests.py b/src/ratings_calculator/rating_tests.py
index 7062018..2418855 100644
--- a/src/ratings_calculator/rating_tests.py
+++ b/src/ratings_calculator/rating_tests.py
@@ -1,14 +1,25 @@
import unittest
+from src.ratings_calculator.Profile import CFCProfile
+from src.ratings_calculator.RatingsCalculator import RatingsCalculator
-from src.ratings_calculator.main import RatingsCalculator
+
+class TestProfileFunctionality(unittest.TestCase):
+ def test_name_input_correct(self) -> None:
+ profile = CFCProfile(150532, False) # for now, input int
+ profile_dict = profile.get_profile()
+ self.assertEqual(profile_dict["player"]["name_first"], "Victor")
+ self.assertEqual(profile_dict["player"]["name_last"], "Zheng")
+
+ tour_data = profile.get_last_tournaments(5)
+ print(tour_data)
class TestBasicFunctionalities(unittest.TestCase):
- def test_default_CFC_ratings(self) -> None:
+ def test_default_CFC_ratings_without_bonus(self) -> None:
ratings = RatingsCalculator()
- new_rating = ratings.established_ratings(1450, 1450, 4, [1237, 1511, 1214, 1441, 1579, 2133])
+ new_rating = ratings.established_ratings(1600, 1450, 4, [1237, 1511, 1214, 1441, 1579, 2133])
print("New Rating is: ", new_rating)
- self.assertEqual(new_rating, 1516.12) # add assertion here
+ self.assertEqual(int(new_rating), 1496) # this is from the handbook
def test_null_values(self) -> None:
ratings = RatingsCalculator()
@@ -18,9 +29,40 @@ def test_null_values(self) -> None:
def test_one_game(self) -> None:
ratings = RatingsCalculator()
- new_rating = ratings.established_ratings(1000, 1000, 1, [1200])
+ new_rating = ratings.established_ratings(2160, 2052, 0, [2208])
+ print("New Rating is: ", new_rating)
+ self.assertEqual(round(new_rating), 2043) # add assertion here
+
+ def test_victor_october_open(self) -> None:
+ # test the calc against perf at october open for 150532
+ ratings = RatingsCalculator()
+ new_rating = ratings.established_ratings(2160, 2014, 3, [2276, 2151, 1972, 2155, 2100])
+ print("New Rating is: ", new_rating)
+ self.assertEqual(round(new_rating), 2073) # add assertion here
+
+ def test_victor_can_junior_open(self) -> None:
+ # test the calc against perf at october open for 150532
+ ratings = RatingsCalculator()
+ new_rating = ratings.established_ratings(2160, 2068, 2.5, [1949, 1982, 1892, 1843, 1898, 1936])
+ print("New Rating is: ", new_rating)
+ self.assertEqual(round(new_rating), 2014) # add assertion here
+
+ def test_quick_ratings_gtcl_rapid(self) -> None:
+ # test the calc against perf at october open for 150532
+ ratings = RatingsCalculator()
+ # Can transnational of 14 games
+ new_rating = ratings.established_ratings(2002, 2002, 5, [1927, 1876, 1899, 1841, 1429], quick=False)
+ print("New Rating is: ", new_rating)
+ # within three points
+ self.assertTrue(abs(round(new_rating) - 2092) <= 3) # add assertion here
+
+ def test_quick_ratings_with_lifetime_high(self) -> None:
+ # test the calc against perf at october open for 150532
+ ratings = RatingsCalculator()
+ new_rating = ratings.established_ratings(1856, 1856, 9, [1431, 1431, 2024, 2024, 1478, 1478, 1710, 1710, 1938, 1938, 1535, 1535, 1986, 1986], quick=False)
print("New Rating is: ", new_rating)
- self.assertEqual(new_rating, 1200) # add assertion here
+ self.assertEqual(round(new_rating), 1882) # add assertion here
+ # note for this tournament that this should be set to quick as true?
if __name__ == '__main__':