API
App
Manages job requests from user through the command line.
- class pgnhelper.app.PgnHelper(job: str, inpgnfn: Optional[str] = None, outpgnfn: Optional[str] = None, inecopgnfn: Optional[str] = None, sort_tag: str = 'eco', sort_direction: str = 'lowtohigh', output: Optional[str] = None, winpoint: float = 1.0, drawpoint: float = 0.5, encoding: str = 'utf-8', armageddonfile: Optional[str] = None, winpointarm: float = 1.0, losspointarm: float = 0.0, showmaxscore: bool = False, round: int = 20)[source]
Manages user options to execute the job.
- job
The kind of job to be done, sort, addeco and roundrobin.
- inpgnfn
The input pgn file or path and filename.
- outpgnfn
The output pgn file or path and filename.
- inecopgnfn
The eco.pgn that will be used in addeco job.
- sort_tag
Used in sorting games.
- sort_direction
The output sorting ordering, lowtohigh or hightolow.
Add ECO
Add eco, opening and variation names to the input pgn file.
The eco codes, opening and variations names are coming from the file eco.pgn that you have to supply to pgnhelper for this to work.
eco.pgn file sources:
eco.pgn from pgn-extract
eco.pgn from my eco repository in github
eco.pgn from pgnhelper repository
Example:
>>> import pgnhelper.eco
>>> pgnhelper.eco.add_eco("./pgn/candidates_zurich_1953.pgn", "eco_cz.pgn", "./eco/eco.pgn")
Example output from eco_cz.pgn
:
[Event "ct"]
[Site "Zurich"]
[Date "1953.??.??"]
[Round "01"]
[White "Szabo L"]
[Black "Geller E"]
[Result "0-1"]
[ECO "A15"]
[ECOT "E02"]
[Opening "English"]
[OpeningT "Catalan"]
[Variation "Anglo-Indian"]
[VariationT "open, 5.Qa4"]
1. c4 Nf6 2. g3 e6 3. Bg2 d5 4. d4 dxc4 5. Qa4+ Nbd7 ...
Note there are ECOT, OpeningT, and VariationT,
these are new tags where
T refers to Transposition.
The ECO A15
is the ECO based on the first
2 moves and ECOT E02
is the ECO after 12 moves.
- pgnhelper.eco.add_eco(inpgnfn: str, outpgnfn: str, inecopgnfn: str, ply: int = 4, maxply: int = 24)[source]
Add eco, opening and variation names to the pgn file.
- Parameters
inpgnfn – The input pgn file.
outpgnfn – The output file.
inecopgnfn – The eco.pgn file.
ply – The game ply to start classifying the opening.
maxply – The max game ply to stop classifying the opening.
Sort games
Sort games by game tags.
- pgnhelper.sort.read_games(inpgnfn: str, encoding: str = 'utf-8') List[Game] [source]
Read games from input pgn file.
- Parameters
inpgnfn – The input pgn file.
encoding – Encoding used in reading a file. If you encounter a
UnicodeDecodeError
we can useISO-8859-1
instead ofutf-8.
- Returns
A list of Game objects.
- pgnhelper.sort.save_games(games: List[Game], outpgnfn: str)[source]
Save the games to output file.
- Parameters
games – A list of games.
outpgnfn – The output file.
- pgnhelper.sort.sort_games(inpgnfn: str, outpgnfn: str, sort_tag: str, sort_direction: str, encoding: str = 'utf-8') None [source]
Sort based on criteria and save the games.
Read the input pgn file, sort it and save the sorted games in output file. The input file is not changed.
- Parameters
inpgnfn – The input pgn file.
outpgnfn – The output pgn file.
sort_tag – The sorting criteria, can be event, site, date, round, white, black and eco.
sort_direction – Direction can be hightolow or lowtohigh.
encoding – Encoding used in reading the input file.
Roundrobin
Generates a round-robin result table.
It reads the input pgn file and generates a dataframe of round-robin table. It also add columns for tie-break scores for tied players.
Typical tie-break system that can be applied to a round-robin tournament according to FIDE.
- 13.16.2. Individual Round-Robin Tournaments:
Direct encounter
The greater number of wins, including forfeits
Sonneborn-Berger
Koya System (to be implemented in pgnhelper)
https://handbook.fide.com/files/handbook/C02Standards.pdf
- class pgnhelper.roundrobin.RoundRobin(infn: str, infnarm: Optional[str] = None, winpoint: float = 1.0, drawpoint: float = 0.5, winpointarm: float = 1.0, losspointarm: float = 0.0, showmaxscore: bool = False)[source]
Manages round-robin result table generation.
- infn
The input pgn file.
- infnarm
The input pgn file with armageddon games.
- winpoint
The point for the winner.
- drawpoint
The point when player draws.
- winpointarm
The point for the winner in armageddon game.
- losspointarm
The point for the loser in armageddon game.
- games_per_encounter() int [source]
Counts the number of games per encounter excluding armageddon.
- Returns
The number of games per encounter.
- player_ranking() DataFrame [source]
Generates a dataframe of player ranking.
- Returns
A pandas dataframe of players ranking.
Swiss
Generates a swiss result table.
It reads the input pgn file and generates a dataframe of swiss table. It also add columns for tie-break scores for tied players.
Typical tie-break system that can be applied to a swiss tournament according to FIDE.
13.16.4. Individual Swiss Tournaments where not all the ratings are consistent:
Buchholz Cut 1
Buchholz
Sonneborn-Berger
Cumulative system - Sum of Progressive Scores
Direct encounter
The greater number of wins including forfeits
The greater number of wins with Black pieces
13.16.5. Individual Swiss Tournaments where all the ratings are consistent:
Buchholz Cut 1
Buchholz
Direct encounter
AROC
The greater number of wins including forfeits
The greater number of wins with Black pieces
The greater number of games with Black (unplayed games shall be counted as played with White)
Sonneborn-Berger
https://handbook.fide.com/files/handbook/C02Standards.pdf
Other reference: FIDE Chess.com Grand Swiss 2021
4. 8. 3. Tie-breaks If two (2) or more players score the same points, the tie is to be decided by the following criteria, in order of priority:
Buchholz Cut 1;
Buchholz;
Sonneborn-Berger;
Direct encounter between the players in tie;
Drawing of lots.
All tie-breaks are calculated as described in C.02.13 of the FIDE Handbook.
Tie-break supported by this library:
TB1 = Buchholz Cut 1 TB2 = Buchholz TB3 = Sonneborn-Berger TB4 = Direct Encounter TB5 = Number of wins TB6 = Number of wins as black
- class pgnhelper.swiss.Swiss(infn: str, round: int = 20)[source]
Manages swiss result table generation.
- infn
The input pgn file.
- infnarm
The input pgn file with armageddon games.
- winpoint
The point for the winner.
- drawpoint
The point when player draws.
- winpointarm
The point for the winner in armageddon game.
- losspointarm
The point for the loser in armageddon game.
- round
The number of rounds.
- get_opp_info(opp_data: List, df_final: DataFrame, dfr: DataFrame, p: str) Tuple[List, bool] [source]
Creates result data to build swiss table.
Record
Manages conversion of pgn file into a pandas dataframe.
Read the games in the pgn file. Each game will be converted to a row with header:
Round, White, Black, WElo, BElo, Result, Wpt, Bpt, Arm, Eco, Opening, WRChg, BRChg
Example:
PS F:\Github\pgnhelper> python
>>> import pgnhelper
>>> df, players, rating = pgnhelper.record.get_pgn_data("./pgn/wchcand22.pgn")
>>> df
Round White Black WElo ... Eco Opening WRChg BRChg
1.1 Duda, Jan-Krzysztof Rapport, Richard 2750 ... B44 Sicilian defence 0.201367 -0.201367
1.2 Ding, Liren Nepomniachtchi, Ian 2806 ... A20 English opening -5.573116 5.573116
1.3 Caruana, Fabiano Nakamura, Hikaru 2783 ... C65 Ruy Lopez 4.669486 -4.669486
Tiebreak
Generates tie-break points on tied players.
- Tie-breaks supported:
Direct Encounter
Number of wins
Sonneborn-Berger
Koya system
- pgnhelper.tiebreak.direct_encounter(result_df: DataFrame, ranking_df: DataFrame, winpoint: float = 1.0, drawpoint: float = 0.5, winpointarm: float = 1.5, losspointarm: float = 1.0, label: str = 'DE') DataFrame [source]
Creates a dataframe with DE column or direct encounter.
- Requirement:
It is only applied when tied players have played each other. In round-robin format this can be applied automatically. But for swiss format, the tied players have to be checked.
- pgnhelper.tiebreak.koya_system(result_df: DataFrame, ranking_df: DataFrame, winpoint: float = 1.0, drawpoint: float = 0.5) DataFrame [source]
Creates a dataframe with Koya column for Koya system score.
Koya system - the number of points achieved against all opponents who have achieved 50 % or more.
11.5.4.3, https://handbook.fide.com/files/handbook/C02Standards.pdf
- Parameters
result_df – A dataframe of [Round, White, Black, Result …].
ranking_df – A dataframe of standing, [Name, Games, Score].
- Returns
A ranking dataframe with Koya column.
- pgnhelper.tiebreak.num_wins(result_df: DataFrame, ranking_df: DataFrame, label: str = 'Wins', bwins: bool = False) DataFrame [source]
Creates a dataframe with Win column.
If a game has an armageddon tie-break, we will only count the number of wins based from the normal game only.
- Parameters
result_df – The result dataframe.
ranking_df – Ranking of players based on score.
label – The label or header of the resulting dataframe.
bwins – If true then only count wins by black. If not count all wins.
- Returns
A dataframe of ranking with Wins column for tie-break.
- pgnhelper.tiebreak.sonneborn_berger(result_df: DataFrame, ranking_df: DataFrame, gpe: int = 1, winpoint: float = 1.0, drawpoint: float = 0.5, label: str = 'SB') DataFrame [source]
Creates a dataframe with SB column for Sonneborn-Berger score.
Armageddon games currently are excluded in the calculation.
- Parameters
result_df – A dataframe of [Round, White, Black, Result].
ranking_df – A dataframe of standing, [Name, Games, Score].
gpe – games per encounter
- Returns
A dataframe of round-robin result table.
- pgnhelper.tiebreak.tb_buchholz(record_df: DataFrame, rank_df: DataFrame, cut: int = 0, label: str = 'TB1') DataFrame [source]
Calculates buchholz score or sum of opponents score.
This tie-break system is only applied for a tournament with swiss format.
- Parameters
record_df – A dataframe of tournament games records.
rank_df – A dataframe with player ranking, initially at [‘Name, Games, Score]. Later [‘Name, Games, Score, Buchholz, … tie-break system]
cut – Cut the player opponent score, if cut is 0 the default then no one will be cut, this is the normal buchholz. If this is 1 then the lowest score will be cut. If this is 2 then the last two lowest scores will be cut. If value is -1 this is median or cut the highest and lowest. If value is -2 then cut the 2 highest and 2 lowest.
- Returns
A dataframe of name and buchholz score.
Elo
- pgnhelper.elo.add_rating_change(df: DataFrame, is_rating: bool, k: int = 10) DataFrame [source]
Adds rating change columns to existing df.
- Parameters
df – A dataframe of players match records.
is_rating – True if players have rating.
k – The k factor.
- Returns
A dataframe of game records with elo rating change columns. [Round, White, Black, WElo, BElo, Result, Wpt, Bpt, Arm, WRChg, BRChg]
- pgnhelper.elo.expected_score(rating_a: int, rating_b: int) float [source]
Calculates the expected score of player_a against player_b.
- Parameters
rating_a – Rating of player_a
rating_b – Rating of player_b
- Returns
expected score of player_a
Example:
>>> import pgnhelper.elo >>> white_elo = 2600 >>> black_elo = 2500 >>> score = pgnhelper.elo.expected_score(white_elo, black_elo) >>> score 0.6400649998028851
- pgnhelper.elo.get_rating(df: DataFrame, p: str) Union[int, str] [source]
Gets the rating of player p.
- Parameters
df – A dataframe of players match records.
p – A player name.
- Returns
rating of player p
- pgnhelper.elo.get_rating_change(df: DataFrame, p: str, k: int = 10) float [source]
Gets the rating change of player p.
The given df has a rating change column for each side. This rating change column was calculated using a k factor with value 10. The k parameter if not 10 will be used to recalculate the rating change for the given player.
Armageddon games are not included in the returned rating change value.
- Parameters
df – A dataframe of players match records.
p – A player named p.
k – The rating change k factor.
- Returns
rating change
Eample 1, get the rating change of a player in the PGN file:
>>> import pgnhelper.record >>> import pgnhelper.elo >>> df, players, is_rating = pgnhelper.record.get_pgn_data("./pgn/superbet_classic_2022_bucharest.pgn") >>> players ['Firouzja, Alireza', 'Aronian, Levon', 'So, Wesley', 'Nepomniachtchi, Ian', 'Caruana, Fabiano', 'Vachier-Lagrave, Maxime', 'Deac, Bogdan-Daniel', 'Mamedyarov, Shakhriyar', 'Dominguez Perez, Leinier', 'Rapport, Richard'] >>> rc_levon = pgnhelper.elo.get_rating_change(df, "Aronian, Levon", k=10) >>> rc_levon 9.496967974633389
Eample 2, get the rating change of black player:
>>> import pgnhelper.elo >>> white_rating = 2700 >>> black_rating = 2600 >>> black_point = 1 >>> white_point = 0 >>> expected_score = pgnhelper.elo.expected_score(black_rating, white_rating) >>> k = 10 >>> rating_change = k * (black_point - expected_score) >>> rating_change 6.400649998028851
Utility
Helps build the round-robin result table.
- pgnhelper.utility.df_to_html(df: DataFrame, fn: str) None [source]
Converts pandas dataframe to basic html table.
Read the df and write html in the fn.
- Parameters
df – Pandas dataframe.
fn – the output file, can be csv, txt or html.
- Returns
Nothing
- pgnhelper.utility.get_encounter_score(df: DataFrame, p: str, op: str, winpoint: float = 1.0, drawpoint: float = 0.5, winpointarm: float = 1.0, losspointarm: float = 0.0) List[float] [source]
Calculates the scores between the player p and op.
- Parameters
df – A pandas dataframe containing players match results.
p – A player name.
op – Opponent of player p.
winpoint – The point when player wins.
drawpoint – The point when player draws.
winpointarm – The point when player wins in armageddon game.
losspointarm – The point when player loses in armageddon game.
- Returns
A list of score for p and op, score[<p score>, <op score>].