Skip to content

Commit

Permalink
Introduced utils.py, including get_all_rounds function
Browse files Browse the repository at this point in the history
  • Loading branch information
daankoning committed Oct 27, 2022
1 parent faca65c commit bbec95c
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 6 deletions.
3 changes: 2 additions & 1 deletion src/debaterpy/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
from .structures import *
from .structures import *
from .utils import *
16 changes: 11 additions & 5 deletions src/debaterpy/structures.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""A collection of simple classes that store information. This is mostly a pythonic, class-based wrapper around DebaterJSON."""
"""A collection of simple classes that store information. This is mostly a pythonic, class-based wrapper around
DebaterJSON."""
from __future__ import annotations
import json
from typing import Optional
Expand All @@ -7,7 +8,8 @@


class Item:
"""A single item that is being stored, mostly used so that some default behaviour doesn't need to be repeated as much."""
"""A single item that is being stored, mostly used so that some default behaviour doesn't need to be repeated as
much."""
def __iter__(self): # just using this as a workaround to make json serialization easier
def is_valid(key):
return not callable(self.__getattribute__(key)) \
Expand Down Expand Up @@ -86,7 +88,8 @@ class Round(Item):
outround: Optional[bool] = None
"""If this round was an outround."""
outround_category: Optional[str] = None
"""What speaker category this outround belongs to (e.g. open or ESL). Should only be used if the round is an outround."""
"""What speaker category this outround belongs to (e.g. open or ESL). Should only be used if the round is an
outround."""
prepped: Optional[bool] = None
"""Whether the round was a prepped round (if applicable)."""
date: Optional[datetime] = None
Expand All @@ -106,7 +109,9 @@ class Round(Item):
speeches: Optional[list[Speech]] = None
"""The speeches the speaker gave in this round."""
result: Optional[int] = None
"""How many points the debater's team got from this round. In two-team formats, a 1 or 0 simply mean a win or loss, respectively. For more complex formats, such as BP, please refer to the format's manuals for how many points a certain result yields."""
"""How many points the debater's team got from this round. In two-team formats, a 1 or 0 simply mean a win or loss,
respectively. For more complex formats, such as BP, please refer to the format's manuals for how many points a
certain result yields."""

@classmethod
def from_dict(cls, data: dict) -> Round:
Expand Down Expand Up @@ -136,7 +141,8 @@ def from_dict(cls, data: dict) -> Round:
class Speech(Item):
"""A speech in a round."""
number: Optional[int] = None
"""The number of this speech. Only counts speeches on the debater's side (e.g. in BP an opposition whip would be speech 4, not 8)."""
"""The number of this speech. Only counts speeches on the debater's side (e.g. in BP an opposition whip would be
speech 4, not 8)."""
speak: Optional[float] = None
"""The speak this speech received."""

Expand Down
24 changes: 24 additions & 0 deletions src/debaterpy/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
"""Various utilities to aid in the manipulation and analysis of the objects in `debaterpy.structures`."""
from .structures import *
from typing import Generator, Callable


def get_all_rounds(record: Record, function: Callable[[Tournament, Round], bool] = lambda x, y: True)\
-> Generator[Round, None, None]:
"""Gets all the rounds `record` for which `function` returns `True`.
This allows easier access to all the data such as for analysis of speaks or winrates. The `function` argument
behaves similarly to Python's built-in `filter`, it only allows entries for which `function(x, y)` is `True`. For
example, the following code will get all rounds in BP (which might be useful for splitting up analyses by format):
>>> get_all_rounds(record, lambda x, y: x.format == "BP")
<generator object get_all_rounds at 0x102861e40>
Args:
record: An instance of `structures.Record` from which the rounds will be extracted.
function: A callable returning a boolean which needs to be true for a record to be included. Receives instances
of `structures.Tournament` and `structures.Round`as arguments. Will default to including all rounds."""
for tournament in record.tournaments:
for round in tournament.rounds:
if function(tournament, round):
yield round

0 comments on commit bbec95c

Please sign in to comment.