fix mismatches in header and column counts

This commit is contained in:
evilchili 2022-08-13 12:32:52 -07:00
parent 9e7101945c
commit c8117cb66c
3 changed files with 51 additions and 8 deletions

View File

@ -1,6 +1,6 @@
[tool.poetry] [tool.poetry]
name = 'dnd-rolltable' name = 'dnd-rolltable'
version = '1.1.3' version = '1.1.4'
license = 'The Unlicense' license = 'The Unlicense'
authors = ['Greg Boyington <evilchili@gmail.com>'] authors = ['Greg Boyington <evilchili@gmail.com>']
description = 'Generate roll tables using weighted random distributions' description = 'Generate roll tables using weighted random distributions'

View File

@ -1,5 +1,6 @@
import yaml import yaml
import random import random
from collections.abc import Iterable
from typing import Optional, List, IO from typing import Optional, List, IO
@ -97,8 +98,10 @@ class RollTable:
struct = {} struct = {}
for row in self.rows[1:]: for row in self.rows[1:]:
struct[row[0]] = {} struct[row[0]] = {}
for idx, col in enumerate(row[1:]): # pad rows with empty cols as necessary
struct[row[0]][self.headers[idx]] = col cols = row[1:] + [''] * (len(self.headers) - len(row[1:]))
for idx, col in enumerate(cols):
struct[row[0]][self.headers[idx] if idx < len(self.headers) else '_'] = col
return yaml.dump(struct) return yaml.dump(struct)
@property @property
@ -147,8 +150,9 @@ class RollTable:
@property @property
def rows(self) -> List: def rows(self) -> List:
def formatted(lastrow, offset, row, i): def formatted(lastrow, offset, row, i):
fmt = f'd{i}' if offset + 1 == i else f'd{offset+1}-d{i}' thisrow = [f'd{i}' if offset + 1 == i else f'd{offset+1}-d{i}']
return self._column_filter([fmt] + lastrow) thisrow += self._flatten(lastrow)
return self._column_filter(thisrow)
lastrow = None lastrow = None
offset = 0 offset = 0
@ -203,9 +207,19 @@ class RollTable:
self._header_excludes.append(i+1) # +1 to account for the 'Roll' column self._header_excludes.append(i+1) # +1 to account for the 'Roll' column
def _column_filter(self, row): def _column_filter(self, row):
return [col for (pos, col) in enumerate(row) if pos not in self._header_excludes] cols = [col for (pos, col) in enumerate(row) if pos not in self._header_excludes]
# pad the row with empty columns if there are more headers than columns
return cols + [''] * (1 + len(self.headers) - len(row))
def _flatten(self, obj: List) -> List:
for member in obj:
if isinstance(member, Iterable) and not isinstance(member, (str, bytes)):
yield from self._flatten(member)
else:
yield member
def __repr__(self) -> str: def __repr__(self) -> str:
rows = list(self.rows) rows = list(self.rows)
print(rows)
str_format = '\t'.join(['{:10s}'] * len(rows[0])) str_format = '\t'.join(['{:10s}'] * len(rows[0]))
return "\n".join([str_format.format(*row) for row in rows]) return "\n".join([str_format.format(*row) for row in rows])

View File

@ -92,6 +92,28 @@ B2:
B3: B3:
""" """
fixture_lists = """
#
# one two three four
# foo bar baz quz
#
metadata:
headers:
- one
- two
- three
- four
foo:
- bar:
- baz
- quz
"""
def test_lists():
t = tables.RollTable([fixture_lists], die=1)
assert str(t)
def test_combined_tables(): def test_combined_tables():
combined = tables.RollTable([fixture_combined_A, fixture_combined_B], die=6) combined = tables.RollTable([fixture_combined_A, fixture_combined_B], die=6)
@ -134,6 +156,13 @@ def test_no_descriptions():
assert 'option 1' in str(t) assert 'option 1' in str(t)
def test_yaml(): def test_no_options():
t = tables.RollTable([fixture_no_options]) t = tables.RollTable([fixture_no_options])
print(t.as_yaml) assert str(t)
def test_yaml():
assert tables.RollTable([fixture_no_options]).as_yaml()
assert tables.RollTable([fixture_one_choice]).as_yaml()
assert tables.RollTable([fixture_metadata + fixture_source]).as_yaml()
assert tables.RollTable([fixture_source]).as_yaml()