refactoring
This commit is contained in:
parent
0fd4a69980
commit
fdbd96e9b1
|
@ -67,6 +67,69 @@ class DataSource:
|
||||||
frequencies.update(**self.metadata['frequencies'])
|
frequencies.update(**self.metadata['frequencies'])
|
||||||
self.frequencies = frequencies[self.frequency]
|
self.frequencies = frequencies[self.frequency]
|
||||||
|
|
||||||
|
def random_frequencies(self, count: int = 1) -> list:
|
||||||
|
"""
|
||||||
|
Choose random option names from the frequency table.
|
||||||
|
"""
|
||||||
|
weights = []
|
||||||
|
options = []
|
||||||
|
for (option, weight) in self.frequencies.items():
|
||||||
|
weights.append(weight)
|
||||||
|
options.append(option)
|
||||||
|
return random.choices(options, weights=weights, k=count)
|
||||||
|
|
||||||
|
def random_values(self, count: int = 1) -> list:
|
||||||
|
"""
|
||||||
|
Return a list of random values from the data set, as a list of lists.
|
||||||
|
"""
|
||||||
|
return [
|
||||||
|
self._random_choice_from_option(option) for option in self.random_frequencies(count)
|
||||||
|
]
|
||||||
|
|
||||||
|
def _random_choice_from_option(self, option: str) -> list:
|
||||||
|
"""
|
||||||
|
Select a random item from the specified option in the data source, and return a flattened
|
||||||
|
list of the option, the select item, and the item's value (if any).
|
||||||
|
"""
|
||||||
|
|
||||||
|
# If there is no data for the specified option, stop now.
|
||||||
|
flattened = [option]
|
||||||
|
if not self.data[option]:
|
||||||
|
return flattened
|
||||||
|
|
||||||
|
if hasattr(self.data[option], 'keys'):
|
||||||
|
# if the option is a dict, we assume the values are lists; we select a random item
|
||||||
|
# and prepend the key to the value list as our random selection. For example, given:
|
||||||
|
#
|
||||||
|
# >>> self.data[option] == {'One': ['bar', 'baz'], 'Two': ['qaz', 'qux']}
|
||||||
|
#
|
||||||
|
# choice might then be: ['One', 'bar', 'baz']
|
||||||
|
#
|
||||||
|
k, v = random.choice(list(self.data[option].items()))
|
||||||
|
choice = [k] + v
|
||||||
|
else:
|
||||||
|
# If the option is either a list or a string, just select it.
|
||||||
|
choice = random.choice(self.data[option])
|
||||||
|
|
||||||
|
# If the randomly-selected choice is a dict, choose a random item and return a list consisting
|
||||||
|
# of the option name, the key, and the value, flattening the # value if it is also a list.
|
||||||
|
if hasattr(choice, 'keys'):
|
||||||
|
for (k, v) in choice.items():
|
||||||
|
if type(v) is list:
|
||||||
|
flattened.extend([k, *v])
|
||||||
|
else:
|
||||||
|
flattened.extend([k, v])
|
||||||
|
return flattened
|
||||||
|
|
||||||
|
# if the member is a list, return the flattened list
|
||||||
|
if type(choice) is list:
|
||||||
|
flattened.extend(choice)
|
||||||
|
return flattened
|
||||||
|
|
||||||
|
# otherwise, return a list consisting of option and choice
|
||||||
|
flattened.append(choice)
|
||||||
|
return flattened
|
||||||
|
|
||||||
|
|
||||||
class RollTable:
|
class RollTable:
|
||||||
"""
|
"""
|
||||||
|
@ -128,40 +191,7 @@ class RollTable:
|
||||||
@property
|
@property
|
||||||
def _values(self) -> List:
|
def _values(self) -> List:
|
||||||
if not self._generated_values:
|
if not self._generated_values:
|
||||||
def values_from_datasource(ds):
|
ds_values = [t.random_values(self.die) for t in self._data]
|
||||||
weights = []
|
|
||||||
options = []
|
|
||||||
for (option, weight) in ds.frequencies.items():
|
|
||||||
weights.append(weight)
|
|
||||||
options.append(option)
|
|
||||||
freqs = random.choices(options, weights=weights, k=self.die)
|
|
||||||
values = []
|
|
||||||
for option in freqs:
|
|
||||||
if not ds.data[option]:
|
|
||||||
values.append([option])
|
|
||||||
continue
|
|
||||||
if hasattr(ds.data[option], 'keys'):
|
|
||||||
k, v = random.choice(list(ds.data[option].items()))
|
|
||||||
choice = [k] + v
|
|
||||||
else:
|
|
||||||
choice = random.choice(ds.data[option])
|
|
||||||
if hasattr(choice, 'keys'):
|
|
||||||
c = [option]
|
|
||||||
for (k, v) in choice.items():
|
|
||||||
if type(v) is list:
|
|
||||||
c.extend([k, *v])
|
|
||||||
else:
|
|
||||||
c.extend([k, v])
|
|
||||||
values.append(c)
|
|
||||||
else:
|
|
||||||
if type(choice) is list:
|
|
||||||
values.append([option, *choice])
|
|
||||||
else:
|
|
||||||
values.append([option, choice])
|
|
||||||
return sorted(values)
|
|
||||||
|
|
||||||
ds_values = [values_from_datasource(t) for t in self._data]
|
|
||||||
|
|
||||||
self._generated_values = []
|
self._generated_values = []
|
||||||
for face in range(self._die):
|
for face in range(self._die):
|
||||||
value = []
|
value = []
|
||||||
|
|
Loading…
Reference in New Issue
Block a user