Skip to content

Ενδεικτική λύση εργαστηριακής άσκησης 2 2023-2024

Εκφώνηση

Λύση

my_re_functions.py
import re
from datetime import datetime

a_pgn_game = """
[Event "WCh 2023"]
[Site "Astana KAZ"]
[Date "2023.04.09"]
[Round "1.1"]
[White "Nepomniachtchi,I"]
[Black "Ding Liren"]
[Result "1/2-1/2"]
[WhiteElo "2795"]
[BlackElo "2788"]
[ECO "C85"]

1.e4 e5 2.Nf3 Nc6 3.Bb5 a6 4.Ba4 Nf6 5.O-O Be7 6.Bxc6 dxc6 7.Re1 Nd7 8.d4 exd4
9.Qxd4 O-O 10.Bf4 Nc5 11.Qe3 Bg4 12.Nd4 Qd7 13.Nc3 Rad8 14.Nf5 Ne6 15.Nxe7+ Qxe7
16.Bg3 Bh5 17.f3 f6 18.h3 h6 19.Kh2 Bf7 20.Rad1 b6 21.a3 a5 22.Ne2 Rxd1 23.Rxd1 Rd8
24.Rd3 c5 25.Qd2 c6 26.Rxd8+ Nxd8 27.Qf4 b5 28.Qb8 Kh7 29.Bd6 Qd7 30.Ng3 Ne6
31.f4 h5 32.c3 c4 33.h4 Qd8 34.Qb7 Be8 35.Nf5 Qd7 36.Qb8 Qd8 37.Qxd8 Nxd8
38.Nd4 Nb7 39.e5 Kg8 40.Kg3 Bd7 41.Bc7 Nc5 42.Bxa5 Kf7 43.Bb4 Nd3 44.e6+ Bxe6
45.Nxc6 Bd7 46.Nd4 Nxb2 47.Kf3 Nd3 48.g3 Nc1 49.Ke3  1/2-1/2
"""


def winner(a_pgn_game):
    result = re.compile(r'\[Result "(.*)"\]').search(a_pgn_game).group(1)
    if result == "1/2-1/2":
        return "ΙΣΟΠΑΛΙΑ"
    if result == "1-0":
        return "ΛΕΥΚΑ"
    if result == "0-1":
        return "ΜΑΥΡΑ"


def date_of_game(a_pgn_game):
    pattern = re.compile(r'\[Date "(.*)"\]')
    match = pattern.search(a_pgn_game)
    a_date = match.group(1)
    if a_date is None:
        return None
    try:
        dt = datetime.strptime(a_date, "%Y.%m.%d")
        return dt.date()
    except ValueError:
        return None


def diff_elo(a_pgn_game):
    w_elo = int(re.compile(r'\[WhiteElo "(\d+)"\]').search(a_pgn_game).group(1))
    b_elo = int(re.compile(r'\[BlackElo "(\d+)"\]').search(a_pgn_game).group(1))
    return abs(w_elo - b_elo)


def moves(a_pgn_game):
    results = re.compile(r"(\d+)\.").findall(a_pgn_game)
    return results[-1]


if __name__ == "__main__":
    print(f"ΔΙΑΦΟΡΑ ΔΥΝΑΜΙΚΟΤΗΤΑΣ: {diff_elo(a_pgn_game)}")
    print(f"ΝΙΚΗΤΗΣ: {winner(a_pgn_game)}")
    dts = datetime.strftime(date_of_game(a_pgn_game), "%d-%m-%Y")
    print(f"ΗΜΕΡΟΜΗΝΙΑ ΑΓΩΝΑ: {dts}")
    print(f"ΠΛΗΘΟΣ ΚΙΝΗΣΕΩΝ: {moves(a_pgn_game)}")
test_my_re_functions.py
import datetime
import unittest

from my_re_functions import a_pgn_game, date_of_game, diff_elo, moves, winner


class TestReFunctions(unittest.TestCase):
    def test_diff_elo(self):
        self.assertEqual(diff_elo(a_pgn_game), 7)

    def test_date_of_game(self):
        self.assertEqual(date_of_game(a_pgn_game), datetime.date(2023, 4, 9))

    def test_winner(self):
        self.assertEqual(winner(a_pgn_game), "ΙΣΟΠΑΛΙΑ")

    def test_moves(self):
        self.assertEqual(moves(a_pgn_game), "49")


if __name__ == "__main__":
    unittest.main()
$ python test_my_re_functions.py
....
----------------------------------------------------------------------
Ran 4 tests in 0.002s

OK
erotima1.py
import os
import sys

import my_re_functions as mrf


def main(pgn_fn):
    games = []
    with open(pgn_fn, "r", encoding="latin-1") as f:
        game = ""
        for line in f:
            line = line.strip()
            if line:
                game += line + "\n"
                if (
                    line.endswith("1-0")
                    or line.endswith("0-1")
                    or line.endswith("1/2-1/2")
                ):
                    games.append(game.strip())
                    game = ""
    return games


if __name__ == "__main__":
    # pgn_fn = "WorldChamp2023.pgn"
    if len(sys.argv) != 2:
        print(f"Usage: {sys.argv[0]} <filename.pgn>")
        exit(-1)
    pgn_fn = sys.argv[1]
    games = main(os.path.join(os.path.dirname(__file__), pgn_fn))
    flag = True
    for game in games:
        dt = mrf.date_of_game(game)
        if dt is not None:
            print(f"Ημερομηνία: {dt}")
        print(f"Νικητής: {mrf.winner(game)}")
        print(f"Διαφορά δυναμικότητας: {mrf.diff_elo(game)}")
        print(f"Πλήθος κινήσεων: {mrf.moves(game)}")
        if flag and games != games[-1]:
            c = input("Θέλεις να συνεχίσεις; (ε για επόμενο, ο για όλα, δ για διακοπή)")
            if c == "δ":
                exit(-1)
            if c == "ο":
                flag = False
$ python erotima1.py WorldChamp2023.pgn
Ημερομηνία: 2023-04-09
Νικητής: ΙΣΟΠΑΛΙΑ
Διαφορά δυναμικότητας: 7
Πλήθος κινήσεων: 49
Θέλεις να συνεχίσεις; (ε για επόμενο, ο για όλα, δ για διακοπή)ε
Ημερομηνία: 2023-04-10
Νικητής: ΜΑΥΡΑ
Διαφορά δυναμικότητας: 7
Πλήθος κινήσεων: 29
Θέλεις να συνεχίσεις; (ε για επόμενο, ο για όλα, δ για διακοπή)ο
Ημερομηνία: 2023-04-12
Νικητής: ΙΣΟΠΑΛΙΑ
Διαφορά δυναμικότητας: 7
Πλήθος κινήσεων: 30
Ημερομηνία: 2023-04-13
Νικητής: ΛΕΥΚΑ
Διαφορά δυναμικότητας: 7
Πλήθος κινήσεων: 47
Ημερομηνία: 2023-04-15
Νικητής: ΛΕΥΚΑ
Διαφορά δυναμικότητας: 7
Πλήθος κινήσεων: 48
Ημερομηνία: 2023-04-16
Νικητής: ΛΕΥΚΑ
Διαφορά δυναμικότητας: 7
Πλήθος κινήσεων: 44
Ημερομηνία: 2023-04-18
Νικητής: ΛΕΥΚΑ
Διαφορά δυναμικότητας: 7
Πλήθος κινήσεων: 37
Ημερομηνία: 2023-04-20
Νικητής: ΙΣΟΠΑΛΙΑ
Διαφορά δυναμικότητας: 7
Πλήθος κινήσεων: 45
Ημερομηνία: 2023-04-21
Νικητής: ΙΣΟΠΑΛΙΑ
Διαφορά δυναμικότητας: 7
Πλήθος κινήσεων: 82
Ημερομηνία: 2023-04-23
Νικητής: ΙΣΟΠΑΛΙΑ
Διαφορά δυναμικότητας: 7
Πλήθος κινήσεων: 45
Ημερομηνία: 2023-04-24
Νικητής: ΙΣΟΠΑΛΙΑ
Διαφορά δυναμικότητας: 7
Πλήθος κινήσεων: 39
Ημερομηνία: 2023-04-26
Νικητής: ΛΕΥΚΑ
Διαφορά δυναμικότητας: 7
Πλήθος κινήσεων: 38
Ημερομηνία: 2023-04-27
Νικητής: ΙΣΟΠΑΛΙΑ
Διαφορά δυναμικότητας: 7
Πλήθος κινήσεων: 40
Ημερομηνία: 2023-04-29
Νικητής: ΙΣΟΠΑΛΙΑ
Διαφορά δυναμικότητας: 7
Πλήθος κινήσεων: 90
erotima2.py
import os

import matplotlib.pyplot as plt
import my_re_functions as mrf


def get_games(pgn_fn):
    games = []
    with open(pgn_fn, "r", encoding="latin-1") as f:
        game = ""
        for line in f:
            line = line.strip()
            if line:
                game += line + "\n"
                if (
                    line.endswith("1-0")
                    or line.endswith("0-1")
                    or line.endswith("1/2-1/2")
                ):
                    games.append(game.strip())
                    game = ""
    return games


def main(pgn_fn):
    day_names = [
        "ΔΕΥΤΕΡΑ",
        "ΤΡΙΤΗ",
        "ΤΕΤΑΡΤΗ",
        "ΠΕΜΠΤΗ",
        "ΠΑΡΑΣΚΕΥΗ",
        "ΣΑΒΒΑΤΟ",
        "ΚΥΡΙΑΚΗ",
    ]
    games_nr = [0] * 7
    games = get_games(os.path.join(os.path.dirname(__file__), pgn_fn))
    total_games = 0
    for game in games:
        dt = mrf.date_of_game(game)
        if dt is not None:
            games_nr[dt.weekday()] += 1
            total_games += 1
    print(list(zip(day_names, games_nr)))
    print(f"{total_games=}")
    plt.bar(day_names, games_nr, color='mediumseagreen')
    plt.ylabel('Αγώνες')
    plt.show()


if __name__ == "__main__":
    pgn_fn = "RetiKIA.pgn"
    main(pgn_fn)

$ python erotima2.py
[('ΔΕΥΤΕΡΑ', 4284), ('ΤΡΙΤΗ', 11196), ('ΤΕΤΑΡΤΗ', 4361), ('ΠΕΜΠΤΗ', 4743), ('ΠΑΡΑΣΚΕΥΗ', 5220), ('ΣΑΒΒΑΤΟ', 7669), ('ΚΥΡΙΑΚΗ', 7153)]
total_games=44626
games per week day