Nested templated data: Difference between revisions
(New draft task with python example.) |
Thundergnat (talk | contribs) (→{{header|Perl 6}}: Add a Perl6 example) |
||
Line 36: | Line 36: | ||
''Show output on this page.'' |
''Show output on this page.'' |
||
=={{header|Perl 6}}== |
|||
{{works with|Rakudo|2018.04.01}} |
|||
Explicitly not using strings, using one data structure to fill in another. Since it ''isn't'' a string, the output format removes the newlines from the template since line feeds aren't particularly significant in Perl 6 data structures. It does preserve the nesting though. In the second example, payload "buckets" that don't exist result in an undefined value being inserted; by default 'Any'. |
|||
<lang perl6>my @payloads = < |
|||
Payload#0 |
|||
Payload#1 |
|||
Payload#2 |
|||
Payload#3 |
|||
Payload#4 |
|||
Payload#5 |
|||
Payload#6 |
|||
>; |
|||
sub template ($pattern) { @payloads[|$pattern] }; |
|||
for [ |
|||
(((1, 2), |
|||
(3, 4, 1), |
|||
5),), |
|||
(((1, 2), |
|||
(10, 4, 1), |
|||
5),) |
|||
] { |
|||
say ' Template: ', $_.perl; |
|||
say "Data structure: { template($_).perl }\n"; |
|||
}</lang> |
|||
{{out}} |
|||
<pre> Template: $(((1, 2), (3, 4, 1), 5),) |
|||
Data structure: ((("Payload#1", "Payload#2"), ("Payload#3", "Payload#4", "Payload#1"), "Payload#5"),) |
|||
Template: $(((1, 2), (10, 4, 1), 5),) |
|||
Data structure: ((("Payload#1", "Payload#2"), (Any, "Payload#4", "Payload#1"), "Payload#5"),)</pre> |
|||
=={{header|Python}}== |
=={{header|Python}}== |
Revision as of 15:09, 28 May 2018
A template for data is an arbitrarily nested tree of integer indices.
Data payloads are given as a separate mapping, array or other simpler, flat,
association of indices to individual items of data, and are strings.
The idea is to create a data structure with the templates' nesting, and the
payload corresponding to each index appearing at the position of each index.
Answers using simple string replacement or regexp are to b avoided. The idea is to use the native, or usual implementation of lists/tuples etc of the language and to hierarchically traverse the template/generate the output.
- Task Detail
Given the following input template t
and list of payloads p
:
<lang># Square brackets are used here to denote nesting but may be changed for other,
- clear, visual representations of nested data appropriate to ones programming
- language.
t = [
[[1, 2], [3, 4, 1], 5]]
p = 'Payload#0' ... 'Payload#6'</lang>
The correct output should have the following structure, (although spacing and linefeeds may differ, the nesting and order should follow): <lang>[[['Payload#1', 'Payload#2'],
['Payload#3', 'Payload#4', 'Payload#1'], 'Payload#5']]</lang>
1. Generate the output for the above template, t
.
- Optional Extended tasks
2. Show which payloads remain unused.
3. Give some indication/handling of indices without a payload.
Show output on this page.
Perl 6
Explicitly not using strings, using one data structure to fill in another. Since it isn't a string, the output format removes the newlines from the template since line feeds aren't particularly significant in Perl 6 data structures. It does preserve the nesting though. In the second example, payload "buckets" that don't exist result in an undefined value being inserted; by default 'Any'. <lang perl6>my @payloads = <
Payload#0 Payload#1 Payload#2 Payload#3 Payload#4 Payload#5 Payload#6
>;
sub template ($pattern) { @payloads[|$pattern] };
for [
(((1, 2), (3, 4, 1), 5),),
(((1, 2), (10, 4, 1), 5),) ] { say ' Template: ', $_.perl; say "Data structure: { template($_).perl }\n";
}</lang>
- Output:
Template: $(((1, 2), (3, 4, 1), 5),) Data structure: ((("Payload#1", "Payload#2"), ("Payload#3", "Payload#4", "Payload#1"), "Payload#5"),) Template: $(((1, 2), (10, 4, 1), 5),) Data structure: ((("Payload#1", "Payload#2"), (Any, "Payload#4", "Payload#1"), "Payload#5"),)
Python
This uses f-strings from Python3.6+.
I choose to use nested tuples for the template structure, and a dict to map integer indices to corresponding payload strings.
A distinctive string is used to indicate missing payloads. <lang python>from pprint import pprint as pp
class Template():
def __init__(self, structure): self.structure = structure self.used_payloads, self.missed_payloads = [], [] def inject_payload(self, id2data): def _inject_payload(substruct, i2d, used, missed): used.extend(i2d[x] for x in substruct if type(x) is not tuple and x in i2d) missed.extend(f'??#{x}' for x in substruct if type(x) is not tuple and x not in i2d) return tuple(_inject_payload(x, i2d, used, missed) if type(x) is tuple else i2d.get(x, f'??#{x}') for x in substruct) ans = _inject_payload(self.structure, id2data, self.used_payloads, self.missed_payloads) self.unused_payloads = sorted(set(id2data.values()) - set(self.used_payloads)) self.missed_payloads = sorted(set(self.missed_payloads)) return ans
if __name__ == '__main__':
index2data = {p: f'Payload#{p}' for p in range(7)} print("##PAYLOADS:\n ", end=) print('\n '.join(list(index2data.values()))) for structure in [ (((1, 2), (3, 4, 1), 5),), (((1, 2), (10, 4, 1), 5),)]: print("\n\n# TEMPLATE:") pp(structure, width=13) print("\n TEMPLATE WITH PAYLOADS:") t = Template(structure) out = t.inject_payload(index2data) pp(out) print("\n UNUSED PAYLOADS:\n ", end=) unused = t.unused_payloads print('\n '.join(unused) if unused else '-') print(" MISSING PAYLOADS:\n ", end=) missed = t.missed_payloads print('\n '.join(missed) if missed else '-')</lang>
- Output:
##PAYLOADS: Payload#0 Payload#1 Payload#2 Payload#3 Payload#4 Payload#5 Payload#6 # TEMPLATE: (((1, 2), (3, 4, 1), 5),) TEMPLATE WITH PAYLOADS: ((('Payload#1', 'Payload#2'), ('Payload#3', 'Payload#4', 'Payload#1'), 'Payload#5'),) UNUSED PAYLOADS: Payload#0 Payload#6 MISSING PAYLOADS: - # TEMPLATE: (((1, 2), (10, 4, 1), 5),) TEMPLATE WITH PAYLOADS: ((('Payload#1', 'Payload#2'), ('??#10', 'Payload#4', 'Payload#1'), 'Payload#5'),) UNUSED PAYLOADS: Payload#0 Payload#3 Payload#6 MISSING PAYLOADS: ??#10