Balladeer

Basics

Python is a very flexible language. It supports object oriented design, but at the same time its standard data types are extremely powerful and often sufficient just by themselves.

Balladeer tries to minimize the number of classes you need to learn. It’s less than a dozen in total.

Here are two which are fundamental to the Balladeer philosophy. We will see them in use soon. So let’s get some detail on them before we proceed further.

States

Whatever the genre of your narrative, it’s a safe bet that the characters you create will undergo change.

They may advance in their profession, lose weight, take up sewing, get drenched in a rainstorm, or disappear never to be seen again.

In Balladeer, you can model all these by defining and allocating State.

class balladeer.lite.types.State

A mix-in for Python’s standard enum.Enum.

Adds some convenient properties to help formatting state values as strings.

property label: str

Gives a consistent string to be used as a label even when the class defines multiple synonyms for each state value.

By way of example, here’s how you might create a state for political affiliation in the UK.

    class Politics(State, enum.Enum):
        con = ["Conservative", "Tory"]
        dem = ["Liberal Democrat", "LibDem"]
        grn = ["Green Party", "Green"]
        ind = ["Independent"]
        lab = ["Labour", "New Labour"]
        lib = ["Liberal"]
        ref = ["Reform Party"]
        res = ["Residents' Party"]
        ukp = ["UKIP", "UK Independence Party"]

Note how this class captures synonyms for the various parties. The label property gives you a preferred term for each one:

>>> Politics.ukp.label
'UKIP'

Grouping

Whether you are modelling a forest glade, a castle dungeon, or an alien space fleet, you will need to create objects for that model.

The next challenge is to organize those objects, sorting and filtering them so that you can isolate the ones you need to operate on (ie: modify their states).

This is what Grouping is for.

class balladeer.lite.types.Grouping

A subclass of Python’s standard defaultdict.

This data structure is used to return objects filtered, sorted, and grouped in a particular fashion, eg: by state or type.

classmethod typewise(items: list) defaultdict

Create a Grouping of items according to their type.

>>> pprint.pprint(Grouping.typewise([0, 1, 0.0, 1.0, True, False, None]))
Grouping(
    <class 'list'>,
    {
        <class 'bool'>: [True, False],
        <class 'float'>: [0.0, 1.0],
        <class 'int'>: [0, 1],
        <class 'NoneType'>: [None]
    }
)

Objects will be grouped against their class, as well as by any declared type (attributes type and types).

>>> pprint.pprint(Grouping.typewise([namespace(type='Cat'), namespace(types=['Feline', 'Leopard'])))
Grouping(
    <class 'list'>,
    {
        'Cat': [namespace(type='Cat')],
        'Feline': [namespace(types=['Feline', 'Leopard'])],
        'Leopard': [namespace(types=['Feline', 'Leopard'])],
         <class 'types.SimpleNamespace'>: [
            namespace(type='Cat'),
            namespace(types=['Feline', 'Leopard'])
         ]
    }
)
property all: list

Returns every entry in the grouping.

property each: list

Returns one of each entry in the grouping.