Решение на Шахматни фенове от Емилиан Спасов

Обратно към всички решения

Към профила на Емилиан Спасов

Резултати

  • 9 точки от тестове
  • 0 бонус точки
  • 9 точки общо
  • 16 успешни тест(а)
  • 1 неуспешни тест(а)

Код

WHITE_KING = "K"

Предполагам, че ако дефинираш само малки или само главни бувки, после можеш лесно да ги сравняваш с str.lower() и str.upper(). Това е само предложение, за да няма дублиране на дефиниции, както тук, така и на ред 16.

BLACK_KING = "k"
WHITE_PAWN = "P"
BLACK_PAWN = "p"
CHESS_COLUMN_TO_NUMERICAL = {
"A": 1,
"B": 2,
"C": 3,
"D": 4,
"E": 5,
"F": 6,
"G": 7,
"H": 8,
}
FIGURE_TO_POINTS = {
"r": 5,
"n": 3,
"b": 3,
"q": 9,
"k": 4,
"p": 1,
"R": 5,
"N": 3,
"B": 3,
"Q": 9,
"K": 4,
"P": 1,
}
class ChessException(Exception):
pass
class ChessPosition:
def __init__(self, fen_board: str = ""):
self._set_fen_board(fen_board)
def _set_fen_board(self, fen_board):
self._original_fen = fen_board
self._create_board(fen_board)
self._check_for_neighboring_kings(self._board)
self._check_for_correct_kings(self._board)
self._check_for_incorrect_pawns(self._board)
self._set_points(self._board)
self._set_figures(self._board)
def _set_figures(self, board):
self._figures = []
for row in board:
for cell in row:
if cell in FIGURE_TO_POINTS:
self._figures.append(cell)
def _set_points(self, board):
white_figures = []
black_figures = []
for row in board:
for cell in row:
if cell is not None and cell.isupper():
white_figures.append(cell)
elif cell is not None and cell.islower():
black_figures.append(cell)
self._white_score = ChessScore(white_figures)
self._black_score = ChessScore(black_figures)
def _create_board(self, fen_board):
self._board = [[None for _ in range(8)] for _ in range(8)]
j = 0
for i, row in enumerate(fen_board.split("/")):
for cell in row:
if cell.isdigit():
for _ in range(int(cell)):
j += 1
else:
self._board[i][j] = cell
j += 1
j = 0
def _check_for_neighboring_kings(self, board):
for i, row in enumerate(board):
for j, cell in enumerate(row):
if cell == BLACK_KING or cell == WHITE_KING:
self._check_neighboring_squares((i, j))
def _check_for_correct_kings(self, board):
white_kings = 0
black_kings = 0
for _, row in enumerate(board):
for _, cell in enumerate(row):
if cell == BLACK_KING:
black_kings += 1
elif cell == WHITE_KING:
white_kings += 1
if white_kings != 1 or black_kings != 1:
raise ChessException("kings")
def _check_for_incorrect_pawns(self, board):
if (BLACK_PAWN in board[0]
or WHITE_PAWN in board[0]
or BLACK_PAWN in board[-1]
or WHITE_PAWN in board[-1]):
raise ChessException("pawns")
def _check_neighboring_squares(self, position: tuple[int, int]):
neighbouring_positions = [

Би могъл да спестиш тези дефиниции, ако направиш обратното - да изчислиш разстоянието между двата царя и да провериш дали е 0/1. Няма проблем с тази имплементация, освен, че е дълга и лесно може да се сгреши при писане и преправяне.

(position[0] - 1, position[1] - 1),
(position[0] - 1, position[1]),
(position[0], position[1] - 1),
(position[0], position[1] + 1),
(position[0] + 1, position[1]),
(position[0] - 1, position[1] + 1),
(position[0] + 1, position[1] - 1),
(position[0] + 1, position[1] + 1),
]
current_king = self._board[position[0]][position[1]]
opposite_king = self._get_opposite_king(current_king)
for nb in neighbouring_positions:
if (self._is_in_board(nb)
and self._board[nb[0]][nb[1]] == opposite_king):
raise ChessException("kings")
def _is_in_board(self, position: tuple[int, int]):
return (position[0] >= 0
and position[0] <= 7
and position[1] >= 0
and position[1] <= 7)
def _get_opposite_king(self, king):
if king == BLACK_KING:

Ако си извикал функцията с невалиден цар, по-скоро бих хвърлил грешка. Връщайки празен стринг, замаскираш потенциален проблем, който ще се манифестира по-късно, но вече няма да е ясна причината.

return WHITE_KING
elif king == WHITE_KING:
return BLACK_KING
raise ValueError("Invalid king provided")
def __len__(self):
return len(self._figures)
def __repr__(self):
return self._original_fen
def __str__(self):
return self._original_fen
def __setitem__(self, key, item):
self.__dict__[key] = item
def __getitem__(self, key):
if len(key) != 2 or key[0] not in CHESS_COLUMN_TO_NUMERICAL:
raise ValueError("Invalid position provided")
row = int(key[1])
col = int(CHESS_COLUMN_TO_NUMERICAL[key[0]])
return self._board[row][col]
def get_white_score(self):
return self._white_score
def get_black_score(self):
return self._black_score
def white_is_winning(self):
return self._black_score < self._white_score
def black_is_winning(self):
return self._black_score > self._white_score
def is_equal(self):
return self._black_score == self._white_score
class ChessScore:
def __init__(self, pieces: list[str] = None):
self._set_score(pieces)
def _set_score(self, pieces: list[str] = None):
self._total = 0
for piece in pieces:
if piece in pieces:
self._total += FIGURE_TO_POINTS[piece]
def __int__(self):
return self._total
def __lt__(self, other):
return self._total < int(other)
def __le__(self, other):
return self._total <= int(other)
def __ge__(self, other):
return self._total >= int(other)
def __eq__(self, other):
return self._total == int(other)
def __gt__(self, other):
return self._total > int(other)
def __add__(self, other):
return self._total + int(other)
def __sub__(self, other):
return self._total - int(other)

Лог от изпълнението

.....F...........
======================================================================
FAIL: test_getitem (test.TestChessPosition)
Test getitem functionality.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/storage/deedee/data/rails/pyfmi-2022/releases/20221115154139/lib/language/python/runner.py", line 67, in thread
    raise result
AssertionError: 'p' != 'K'
- p
+ K


----------------------------------------------------------------------
Ran 17 tests in 0.172s

FAILED (failures=1)

История (2 версии и 12 коментара)

Емилиан обнови решението на 23.11.2022 21:43 (преди почти 2 години)

+WHITE_KING = "K"

Предполагам, че ако дефинираш само малки или само главни бувки, после можеш лесно да ги сравняваш с str.lower() и str.upper(). Това е само предложение, за да няма дублиране на дефиниции, както тук, така и на ред 16.

+BLACK_KING = "k"
+WHITE_PAWN = "P"
+BLACK_PAWN = "p"
+CHESS_COLUMN_TO_NUMERICAL = {
+ "A": 1,
+ "B": 2,
+ "C": 3,
+ "D": 4,
+ "E": 5,
+ "F": 6,
+ "G": 7,
+ "H": 8,
+}
+
+FIGURE_TO_POINTS = {
+ "r": 5,
+ "n": 3,
+ "b": 3,
+ "q": 9,
+ "k": 4,
+ "p": 1,
+ "R": 5,
+ "N": 3,
+ "B": 3,
+ "Q": 9,
+ "K": 4,
+ "P": 1,
+}
+
+
+class ChessException(BaseException):

Наследяване от BaseException работи, но е против препоръките на Python. Причината е, че специалните изключения като KeyboardInterrupt наследяват BaseException и ако искаш да хванеш такъв Exception, маскираш KeyboardInterrupt и един вид губиш функционалност. Всички къстъм изключения трябва да наследяват Exception.

https://waylonwalker.com/python-base-exception/

+ pass
+
+
+class ChessPosition:
+ def __init__(self, fen_board: str = ""):
+ self._set_fen_board(fen_board)
+
+ def _set_fen_board(self, fen_board):
+ self._original_fen = fen_board
+ self._create_board(fen_board)
+ self._check_for_neighboring_kings(self._board)
+ self._check_for_correct_kings(self._board)
+ self._check_for_incorrect_pawns(self._board)
+ self._set_points(self._board)
+ self._set_figures(self._board)
+
+ def _set_figures(self, board):
+ self._figures = []
+ for row in board:
+ for cell in row:
+ if cell in FIGURE_TO_POINTS:
+ self._figures.append(cell)
+
+ def _set_points(self, board):
+ self._white_points = 0
+ self._black_points = 0
+ for row in board:
+ for cell in row:
+ if cell is not None and cell.isupper():
+ self._white_points += FIGURE_TO_POINTS[cell]
+ elif cell is not None and cell.islower():
+ self._black_points += FIGURE_TO_POINTS[cell]
+
+ def _create_board(self, fen_board):
+ self._board = [[None for _ in range(8)] for _ in range(8)]
+ i = 0
+ j = 0
+ for row in fen_board.split("/"):
+ for cell in row:
+ if cell.isdigit():
+ for _ in range(int(cell)):
+ j += 1
+ else:
+ self._board[i][j] = cell
+ j += 1
+ i += 1
+ j = 0
+
+ def _check_for_neighboring_kings(self, board):
+ for i, row in enumerate(board):
+ for j, cell in enumerate(row):
+ if cell == BLACK_KING or cell == WHITE_KING:
+ self._check_neighboring_squares((i, j))
+
+ def _check_for_correct_kings(self, board):
+ white_kings = 0
+ black_kings = 0
+ for _, row in enumerate(board):
+ for _, cell in enumerate(row):
+ if cell == BLACK_KING:
+ black_kings += 1
+ elif cell == WHITE_KING:
+ white_kings += 1
+ if white_kings == 0 or white_kings > 1 or\
+ black_kings == 0 or black_kings > 1:
+ raise ChessException("kings")
+
+ def _check_for_incorrect_pawns(self, board):
+ if BLACK_PAWN in board[0] or\
+ WHITE_PAWN in board[0] or\
+ BLACK_PAWN in board[-1] or\
+ WHITE_PAWN in board[-1]:
+ raise ChessException("pawns")
+
+ def _check_neighboring_squares(self, position: tuple[int, int]):
+ neighbouring_positions = [

Би могъл да спестиш тези дефиниции, ако направиш обратното - да изчислиш разстоянието между двата царя и да провериш дали е 0/1. Няма проблем с тази имплементация, освен, че е дълга и лесно може да се сгреши при писане и преправяне.

+ (position[0] - 1, position[1] - 1),
+ (position[0] - 1, position[1]),
+ (position[0], position[1] - 1),
+ (position[0], position[1] + 1),
+ (position[0] + 1, position[1]),
+ (position[0] - 1, position[1] + 1),
+ (position[0] + 1, position[1] - 1),
+ (position[0] + 1, position[1] + 1),
+ ]
+
+ current_king = self._board[position[0]][position[1]]
+ opposite_king = self._get_opposite_king(current_king)
+ for nb in neighbouring_positions:
+ if self._is_in_board(nb) and\
+ self._board[nb[0]][nb[1]] == opposite_king:
+ raise ChessException("kings")
+
+ def _is_in_board(self, position: tuple[int, int]):
+ return position[0] > 0 and position[0] <= 7 \
+ and position[1] > 0 and position[1] <= 7
+
+ def _get_opposite_king(self, king):
+ if king == BLACK_KING:

Ако си извикал функцията с невалиден цар, по-скоро бих хвърлил грешка. Връщайки празен стринг, замаскираш потенциален проблем, който ще се манифестира по-късно, но вече няма да е ясна причината.

+ return WHITE_KING
+ elif king == WHITE_KING:
+ return BLACK_KING
+ return ""
+
+ def __len__(self):
+ return len(self._figures)
+
+ def __repr__(self):
+ return self._original_fen
+
+ def __str__(self):
+ return self._original_fen
+
+ def __setitem__(self, key, item):
+ self.__dict__[key] = item
+
+ def __getitem__(self, key):
+ if len(key) != 2 or key[0] not in CHESS_COLUMN_TO_NUMERICAL:
+ return None
+
+ row = int(key[1])
+ col = int(CHESS_COLUMN_TO_NUMERICAL[key[0]])
+ return self._board[row][col]
+
+ def get_white_score(self):
+ return self._white_points
+
+ def get_black_score(self):
+ return self._black_points
+
+ def white_is_winning(self):
+ return self._black_points < self._white_points
+
+ def black_is_winning(self):
+ return self._black_points > self._white_points
+
+ def is_equal(self):
+ return self._black_points == self._white_points
+
+
+class ChessScore:
+ def __init__(self, pieces: list[str] = None):
+ self._set_score(pieces)
+
+ def _set_score(self, pieces: list[str] = None):
+ self._total = 0
+ for piece in pieces:
+ if piece in pieces:
+ self._total += FIGURE_TO_POINTS[piece]
+
+ def get_total_score(self):
+ return self._total
+
+ def __int__(self):
+ return self._total
+
+ def __lt__(self, other):
+ return self._total < other.get_total_score()
+
+ def __le__(self, other):
+ return self._total <= other.get_total_score()
+
+ def __ge__(self, other):
+ return self._total >= other.get_total_score()
+
+ def __eq__(self, other):
+ return self._total == other.get_total_score()
+
+ def __gt__(self, other):
+ return self._total > other.get_total_score()
+
+ def __add__(self, other):
+ return self._total + other.get_total_score()
+
+ def __sub__(self, other):
+ return self._total - other.get_total_score()

WHITE_KING = "K" BLACK_KING = "k" WHITE_PAWN = "P" BLACK_PAWN = "p" CHESS_COLUMN_TO_NUMERICAL = { "A": 1, "B": 2, "C": 3, "D": 4, "E": 5, "F": 6, "G": 7, "H": 8, }

FIGURE_TO_POINTS = { "r": 5, "n": 3, "b": 3, "q": 9, "k": 4, "p": 1, "R": 5, "N": 3, "B": 3, "Q": 9, "K": 4, "P": 1, }

class ChessException(Exception): pass

class ChessPosition: def init(self, fen_board: str = ""): self._set_fen_board(fen_board)

def _set_fen_board(self, fen_board):
    self._original_fen = fen_board
    self._create_board(fen_board)
    self._check_for_neighboring_kings(self._board)
    self._check_for_correct_kings(self._board)
    self._check_for_incorrect_pawns(self._board)
    self._set_points(self._board)
    self._set_figures(self._board)

def _set_figures(self, board):
    self._figures = []
    for row in board:
        for cell in row:
            if cell in FIGURE_TO_POINTS:
                self._figures.append(cell)

def _set_points(self, board):
    white_figures = []
    black_figures = []
    for row in board:
        for cell in row:
            if cell is not None and cell.isupper():
                white_figures.append(cell)
            elif cell is not None and cell.islower():
                black_figures.append(cell)
    self._white_score = ChessScore(white_figures)
    self._black_score = ChessScore(black_figures)

def _create_board(self, fen_board):
    self._board = [[None for _ in range(8)] for _ in range(8)]
    j = 0
    for i, row in enumerate(fen_board.split("/")):
        for cell in row:
            if cell.isdigit():
                for _ in range(int(cell)):
                    j += 1
            else:
                self._board[i][j] = cell
                j += 1
        j = 0

def _check_for_neighboring_kings(self, board):
    for i, row in enumerate(board):
        for j, cell in enumerate(row):
            if cell == BLACK_KING or cell == WHITE_KING:
                self._check_neighboring_squares((i, j))

def _check_for_correct_kings(self, board):
    white_kings = 0
    black_kings = 0
    for _, row in enumerate(board):
        for _, cell in enumerate(row):
            if cell == BLACK_KING:
                black_kings += 1
            elif cell == WHITE_KING:
                white_kings += 1
    if white_kings != 1 or black_kings != 1:
        raise ChessException("kings")

def _check_for_incorrect_pawns(self, board):
    if (BLACK_PAWN in board[0]
            or WHITE_PAWN in board[0]
            or BLACK_PAWN in board[-1]
            or WHITE_PAWN in board[-1]):
        raise ChessException("pawns")

def _check_neighboring_squares(self, position: tuple[int, int]):
    neighbouring_positions = [
        (position[0] - 1, position[1] - 1),
        (position[0] - 1, position[1]),
        (position[0], position[1] - 1),
        (position[0], position[1] + 1),
        (position[0] + 1, position[1]),
        (position[0] - 1, position[1] + 1),
        (position[0] + 1, position[1] - 1),
        (position[0] + 1, position[1] + 1),
    ]

    current_king = self._board[position[0]][position[1]]
    opposite_king = self._get_opposite_king(current_king)
    for nb in neighbouring_positions:
        if (self._is_in_board(nb)
                and self._board[nb[0]][nb[1]] == opposite_king):
            raise ChessException("kings")

def _is_in_board(self, position: tuple[int, int]):
    return (position[0] >= 0
            and position[0] <= 7
            and position[1] >= 0
            and position[1] <= 7)

def _get_opposite_king(self, king):
    if king == BLACK_KING:
        return WHITE_KING
    elif king == WHITE_KING:
        return BLACK_KING
    raise ValueError("Invalid king provided")

def __len__(self):
    return len(self._figures)

def __repr__(self):
    return self._original_fen

def __str__(self):
    return self._original_fen

def __setitem__(self, key, item):
    self.__dict__[key] = item

def __getitem__(self, key):
    if len(key) != 2 or key[0] not in CHESS_COLUMN_TO_NUMERICAL:
        raise ValueError("Invalid position provided")

    row = int(key[1])
    col = int(CHESS_COLUMN_TO_NUMERICAL[key[0]])
    return self._board[row][col]

def get_white_score(self):
    return self._white_score

def get_black_score(self):
    return self._black_score

def white_is_winning(self):
    return self._black_score < self._white_score

def black_is_winning(self):
    return self._black_score > self._white_score

def is_equal(self):
    return self._black_score == self._white_score

class ChessScore: def init(self, pieces: list[str] = None): self._set_score(pieces)

def _set_score(self, pieces: list[str] = None):
    self._total = 0
    for piece in pieces:
        if piece in pieces:
            self._total += FIGURE_TO_POINTS[piece]

def __int__(self):
    return self._total

def __lt__(self, other):
    return self._total < int(other)

def __le__(self, other):
    return self._total <= int(other)

def __ge__(self, other):
    return self._total >= int(other)

def __eq__(self, other):
    return self._total == int(other)

def __gt__(self, other):
    return self._total > int(other)

def __add__(self, other):
    return self._total + int(other)

def __sub__(self, other):
    return self._total - int(other)

Емилиан обнови решението на 24.11.2022 12:21 (преди почти 2 години)

WHITE_KING = "K"
BLACK_KING = "k"
WHITE_PAWN = "P"
BLACK_PAWN = "p"
CHESS_COLUMN_TO_NUMERICAL = {
"A": 1,
"B": 2,
"C": 3,
"D": 4,
"E": 5,
"F": 6,
"G": 7,
"H": 8,
}
FIGURE_TO_POINTS = {
"r": 5,
"n": 3,
"b": 3,
"q": 9,
"k": 4,
"p": 1,
"R": 5,
"N": 3,
"B": 3,
"Q": 9,
"K": 4,
"P": 1,
}
-class ChessException(BaseException):
+class ChessException(Exception):
pass
class ChessPosition:
def __init__(self, fen_board: str = ""):
self._set_fen_board(fen_board)
def _set_fen_board(self, fen_board):
self._original_fen = fen_board
self._create_board(fen_board)
self._check_for_neighboring_kings(self._board)
self._check_for_correct_kings(self._board)
self._check_for_incorrect_pawns(self._board)
self._set_points(self._board)
self._set_figures(self._board)
def _set_figures(self, board):
self._figures = []
for row in board:
for cell in row:
if cell in FIGURE_TO_POINTS:
self._figures.append(cell)
def _set_points(self, board):
- self._white_points = 0
- self._black_points = 0
+ white_figures = []
+ black_figures = []
for row in board:
for cell in row:
if cell is not None and cell.isupper():
- self._white_points += FIGURE_TO_POINTS[cell]
+ white_figures.append(cell)
elif cell is not None and cell.islower():
- self._black_points += FIGURE_TO_POINTS[cell]
+ black_figures.append(cell)
+ self._white_score = ChessScore(white_figures)
+ self._black_score = ChessScore(black_figures)
def _create_board(self, fen_board):
self._board = [[None for _ in range(8)] for _ in range(8)]
- i = 0
j = 0
- for row in fen_board.split("/"):
+ for i, row in enumerate(fen_board.split("/")):
for cell in row:
if cell.isdigit():
for _ in range(int(cell)):
j += 1
else:
self._board[i][j] = cell
j += 1
- i += 1
j = 0
def _check_for_neighboring_kings(self, board):
for i, row in enumerate(board):
for j, cell in enumerate(row):
if cell == BLACK_KING or cell == WHITE_KING:
self._check_neighboring_squares((i, j))
def _check_for_correct_kings(self, board):
white_kings = 0
black_kings = 0
for _, row in enumerate(board):
for _, cell in enumerate(row):
if cell == BLACK_KING:
black_kings += 1
elif cell == WHITE_KING:
white_kings += 1
- if white_kings == 0 or white_kings > 1 or\
- black_kings == 0 or black_kings > 1:
+ if white_kings != 1 or black_kings != 1:
raise ChessException("kings")
def _check_for_incorrect_pawns(self, board):
- if BLACK_PAWN in board[0] or\
- WHITE_PAWN in board[0] or\
- BLACK_PAWN in board[-1] or\
- WHITE_PAWN in board[-1]:
+ if (BLACK_PAWN in board[0]
+ or WHITE_PAWN in board[0]
+ or BLACK_PAWN in board[-1]
+ or WHITE_PAWN in board[-1]):
raise ChessException("pawns")
def _check_neighboring_squares(self, position: tuple[int, int]):
neighbouring_positions = [
(position[0] - 1, position[1] - 1),
(position[0] - 1, position[1]),
(position[0], position[1] - 1),
(position[0], position[1] + 1),
(position[0] + 1, position[1]),
(position[0] - 1, position[1] + 1),
(position[0] + 1, position[1] - 1),
(position[0] + 1, position[1] + 1),
]
current_king = self._board[position[0]][position[1]]
opposite_king = self._get_opposite_king(current_king)
for nb in neighbouring_positions:
- if self._is_in_board(nb) and\
- self._board[nb[0]][nb[1]] == opposite_king:
+ if (self._is_in_board(nb)
+ and self._board[nb[0]][nb[1]] == opposite_king):
raise ChessException("kings")
def _is_in_board(self, position: tuple[int, int]):
- return position[0] > 0 and position[0] <= 7 \
- and position[1] > 0 and position[1] <= 7
+ return (position[0] >= 0
+ and position[0] <= 7
+ and position[1] >= 0
+ and position[1] <= 7)
def _get_opposite_king(self, king):
if king == BLACK_KING:
return WHITE_KING
elif king == WHITE_KING:
return BLACK_KING
- return ""
+ raise ValueError("Invalid king provided")
def __len__(self):
return len(self._figures)
def __repr__(self):
return self._original_fen
def __str__(self):
return self._original_fen
def __setitem__(self, key, item):
self.__dict__[key] = item
def __getitem__(self, key):
if len(key) != 2 or key[0] not in CHESS_COLUMN_TO_NUMERICAL:
- return None
+ raise ValueError("Invalid position provided")
row = int(key[1])
col = int(CHESS_COLUMN_TO_NUMERICAL[key[0]])
return self._board[row][col]
def get_white_score(self):
- return self._white_points
+ return self._white_score
def get_black_score(self):
- return self._black_points
+ return self._black_score
def white_is_winning(self):
- return self._black_points < self._white_points
+ return self._black_score < self._white_score
def black_is_winning(self):
- return self._black_points > self._white_points
+ return self._black_score > self._white_score
def is_equal(self):
- return self._black_points == self._white_points
+ return self._black_score == self._white_score
class ChessScore:
def __init__(self, pieces: list[str] = None):
self._set_score(pieces)
def _set_score(self, pieces: list[str] = None):
self._total = 0
for piece in pieces:
if piece in pieces:
self._total += FIGURE_TO_POINTS[piece]
- def get_total_score(self):
- return self._total
-
def __int__(self):
return self._total
def __lt__(self, other):
- return self._total < other.get_total_score()
+ return self._total < int(other)
def __le__(self, other):
- return self._total <= other.get_total_score()
+ return self._total <= int(other)
def __ge__(self, other):
- return self._total >= other.get_total_score()
+ return self._total >= int(other)
def __eq__(self, other):
- return self._total == other.get_total_score()
+ return self._total == int(other)
def __gt__(self, other):
- return self._total > other.get_total_score()
+ return self._total > int(other)
def __add__(self, other):
- return self._total + other.get_total_score()
+ return self._total + int(other)
def __sub__(self, other):
- return self._total - other.get_total_score()
+ return self._total - int(other)