Nested templated data: Difference between revisions

From Rosetta Code
Content added Content deleted
(New draft task with python example.)
 
(→‎{{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

Nested templated data is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

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,

  1. clear, visual representations of nested data appropriate to ones programming
  2. 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

Works with: Rakudo version 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>

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