Nested templated data: Difference between revisions

From Rosetta Code
Content deleted Content added
→‎{{header|Python}}: added zkl header
Line 173: Line 173:


=={{header|zkl}}==
=={{header|zkl}}==
Formatting is lost as zkl is format free. A pretty printer could be written but
<lang zkl></lang>
the tasks asks for a data structure.
<lang zkl></lang>

Void is used as a marker for an unknown payload.
<lang zkl>var payloads=[1..6].pump(List,"Payload#".append);

fcn get(n){ try{ payloads[n - 1] }catch{ Void } }
fcn sub(list){ list.pump(List, fcn(n){ if(n.isType(List)) sub(n) else get(n) }) }
fcn template(list){ list.pump(List,sub) }</lang>
<lang zkl>foreach p in (T(
T(T(T(1, 2),
T(3, 4, 1),
5),),
T(T(T(1, 2),
T(10,4, 1),
5),))){
println(" Template: %s\nData structure: %s".fmt(p,sub(p)));
}</lang>
{{out}}
{{out}}
<pre>
<pre>
Template: L(L(L(1,2),L(3,4,1),5))
Data structure: L(L(L("Payload#1","Payload#2"),L("Payload#3","Payload#4","Payload#1"),"Payload#5"))
Template: L(L(L(1,2),L(10,4,1),5),L())
Data structure: L(L(L("Payload#1","Payload#2"),L(Void,"Payload#4","Payload#1"),"Payload#5"),L())
</pre>
</pre>

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

Formatting is lost as zkl is format free. A pretty printer could be written but the tasks asks for a data structure.

Void is used as a marker for an unknown payload. <lang zkl>var payloads=[1..6].pump(List,"Payload#".append);

fcn get(n){ try{ payloads[n - 1] }catch{ Void } } fcn sub(list){ list.pump(List, fcn(n){ if(n.isType(List)) sub(n) else get(n) }) } fcn template(list){ list.pump(List,sub) }</lang> <lang zkl>foreach p in (T(

    T(T(T(1, 2),
        T(3, 4, 1),
        5),),
  T(T(T(1, 2),
      T(10,4, 1),
        5),))){
  println("      Template: %s\nData structure: %s".fmt(p,sub(p)));

}</lang>

Output:
      Template: L(L(L(1,2),L(3,4,1),5))
Data structure: L(L(L("Payload#1","Payload#2"),L("Payload#3","Payload#4","Payload#1"),"Payload#5"))
      Template: L(L(L(1,2),L(10,4,1),5),L())
Data structure: L(L(L("Payload#1","Payload#2"),L(Void,"Payload#4","Payload#1"),"Payload#5"),L())