Nested templated data: Difference between revisions

From Rosetta Code
Content deleted Content added
Thundergnat (talk | contribs)
m →‎{{header|Perl 6}}: Grammar edits
→‎{{header|Python}}: added zkl header
Line 171: Line 171:
MISSING PAYLOADS:
MISSING PAYLOADS:
??#10</pre>
??#10</pre>

=={{header|zkl}}==
<lang zkl></lang>
<lang zkl></lang>
{{out}}
<pre>
</pre>

Revision as of 18:04, 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; 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

zkl

<lang zkl></lang> <lang zkl></lang>

Output: