TabbycatDebate / tabbycat

Debating tournament tabulation software for British Parliamentary and a variety of two-team parliamentary formats
https://tabbycat.readthedocs.io/
GNU Affero General Public License v3.0
245 stars 827 forks source link

Restructure draw code to keep track of details like brackets, one-up-one-downs, etc. #75

Closed czlee closed 10 years ago

czlee commented 10 years ago

Follows from #60.

The draw algorithms currently use a number of functions that pass around lists of tuples [(team1, team2), (team3, team4), ...]. While fit for the purpose of creating a draw, it's not very good at tracking flags and brackets and similar information. It would be nicer to have a draw generation architecture that can remember when it performs actions like swapping or balancing affs, so that that information can be displayed to a curious (or untrusting) user, and that is generally more extensible so it's easy to generate break rounds and so on. For example, draw algorithm classes might:

By "(relatively) custom", I meant that options and flags shouldn't be constrained by the architecture - they should be stored in an .options or .flags attribute or something.

This is probably a major job, and is probably not too high priority, since the current code does get the draw done fine (when it's not polluted by unconfirmed ballots). But it'd also be really nice to have in place for the unit tests in #71, and certainly it would give a lot more peace of mind at Australs.

czlee commented 10 years ago

Thinking out loud:

General principles:

Types of draws

Random

Manual

Power-paired

Break round

Interface in

All teams and standings lists are any iterable of objects with the attributes listed below. For draw types where teams are ordered, lists are assumed to be ordered from first to last. No other assumptions are made about the objects. It is illegal for a higher-ranked team to have fewer points than a lower-ranked team.

The attributes that teams must implement are:

Options for power-pairing rounds (other than history/institution limits) can be a string or a function. If it's a string, it refers to one of the built-in methods. If it's a function, the algorithm uses that function (and it must conform to the same specifications). Can be specified as keyword arguments to the constructor, but don't have to be. Defaults are those used at Australs.

The history and institution limits are always integers.

Interface out

The draw will be communicated as a list of Debate objects. Debate objects are not the same as the Debate Django model (the name might cause some confusion). Each Debate object has the following attributes:

There is no guarantee that all teams are included (in fact, for break rounds, they certainly won't).

czlee commented 10 years ago

This is basically done, but I didn't implement break rounds because they're hard. Hopefully what's there now is a good framework for doing so though.