language: CLIPS (clips 6.24)
date: 132 days 0 hours ago
link:
visibility: public
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
                                                                   
"EXECIO * DISKR ORDERDAT (STEM orderData."                         
                                                                   
if 0 <> RC then                                                    
  do                                                               
    say 'ERROR: Unable to read in the ORDERDAT file'               
    exit 8                                                         
  end                                                              
                               
/**************************/   
/* Process the order data */                             
/**************************/                             
                                                         
/* Initialise our known retailers list and totals */     
retailers.0     = 0                                      
cancelledOrders = 0                                      
cancelledSales  = 0                                      
completedOrders = 0                                      
completedSales  = 0                                      
                                                         
/* Initialise the known items list */                    
items.0 = 0                                              
                                                         
/* Initialise the month names */                         
monthNames.0  = 12                                       
monthNames.1  = 'January'                                
monthNames.2  = 'February'                               
monthNames.3  = 'March'                                  
monthNames.4  = 'April'                                  
monthNames.5  = 'May'                                    
monthNames.6  = 'June'                                   
monthNames.7  = 'July'                                   
monthNames.8  = 'August'                                 
monthNames.9  = 'September'                              
monthNames.10 = 'October'                                
monthNames.11 = 'November'                               
monthNames.12 = 'December'                               
                                                         
/* Get the report month number from the parameters */    
parse arg reportMonth .                                  
                                                         
/* Validate the month number */                          
if ( (datatype(reportMonth) <> 'NUM'),                   
   | (reportMonth < 0),                                  
   | (reportMonth > monthNames.0) ) then                 
  do                                                     
    say 'ERROR: Invalid month number'                                  
    exit 8                                                             
  end                                                                  
                                                                       
/* Process each order data line */                                     
do i = 1 to orderData.0                                                
                                                                       
  /* Skip lines that have an asterisk in column 1 */                   
  if ( 1 = pos('*', orderData.i ) ) then                               
    iterate                                                            
                                                                       
  /* Parse the various fields out of the order data line */            
  parse var orderData.i,                                               
    orderNo','retailer','productID','productName','productPrice',',    
    quantity orderDate orderState                                      
                                                                       
  /* Check that the data looks valid */                                
  if ( datatype(orderNo) <> 'NUM',                                     
     | orderNo < 0 ) then                                    
    do                                                       
      say "ERROR: Invalid order number:" orderNo             
      exit 8                                                 
    end                                                      
                                                             
  if ( length(productID) <> 5 ) then                         
    do                                                       
      say "ERROR: Invalid product ID:" productID             
      exit 8                                                 
    end                                                      
                                                             
  if ( datatype(productPrice) <> 'NUM',                      
     | productPrice < 0 ) then                               
    do                                                       
      say "ERROR: Invalid product price:" productPrice       
      exit 8                                                 
    end                                                      
                                                                    
  if ( datatype(quantity) <> 'NUM',                                 
     | quantity < 0 ) then                                          
    do                                                              
      say "ERROR: Invalid order quantity:" quantity                 
      exit 8                                                        
    end                                                             
                                                                    
  if ( length(orderState) <> 1 ) then                               
    do                                                              
      say "ERROR: Invalid order state:" orderState                  
      exit 8                                                        
    end                                                             
                                                                    
  /* Check if the order is for the required month, if applicable */ 
  if ( reportMonth > 0 ) then                                       
    do                                                              
      parse var orderDate orderYear'-'orderMonth'-'orderDay         
                                                         
      /* Verify that it looks like a valid date */       
      if ( datatype(orderDay) <> 'NUM',                  
         | orderDay < 0 | orderDay > 31,                 
         | datatype(orderMonth) <> 'NUM',                
         | orderMonth < 0 | orderMonth > 12,             
         | datatype(orderYear) <> 'NUM',                 
         | orderYear < 0 ) then                          
        do                                               
          say "ERROR: Invalid order date:" orderDate     
          exit 8                                         
        end                                              
                                                         
      if ( reportMonth <> orderMonth ) then              
        iterate                                          
    end                                                  
                                                         
  /* Check if we've seen this retailer before */         
  retailerIdx = -1                                   
                                                     
  do r = 1 to retailers.0                            
                                                     
    if ( retailers.r.name = retailer ) then          
      do                                             
        retailerIdx = r                              
        leave r                                      
      end                                            
                                                     
  end /* r = ... */                                  
                                                     
  /* If we didn't find the retailer - add it */      
  if ( retailerIdx = -1 ) then                       
    do                                               
      retailerIdx = retailers.0 + 1                  
      retailers.0 = retailerIdx                      
      retailers.retailerIdx.name = retailer          
      retailers.retailerIdx.sales = 0                  
      retailers.retailerIdx.orders = 0                 
    end                                                
                                                       
  /* Check if we've seen this item before */           
  itemIdx = -1                                         
                                                       
  do s = 1 to items.0                                  
                                                       
    if ( items.s.code = productID ) then               
      do                                               
        itemIdx = s                                    
        leave s                                        
      end                                              
                                                       
  end /* s = ... */                                    
                                                       
  /* If we didn't find the item - add it */            
 if ( itemIdx = -1 ) then                                        
   do                                                            
     itemIdx = items.0 + 1                                       
     items.0 = itemIdx                                           
     items.itemIdx.code = productId                              
     items.itemIdx.name = productName                            
     items.itemIdx.sales = 0                                     
   end                                                           
                                                                 
 /* Check if the order was cancelled */                          
 if ( orderState = 'C' ) then                                    
   do                                                            
     cancelledOrders = cancelledOrders + 1                       
     cancelledSales = cancelledSales + (productPrice * quantity) 
   end                                                           
 else                                                            
   do                                                            
     /* Increment the number of orders */                        
      retailers.retailerIdx.orders = retailers.retailerIdx.orders + 1   
      completedOrders = completedOrders + 1                             
                                                                        
      /* Update the overall and retailer's sales totals */              
      retailers.retailerIdx.sales = retailers.retailerIdx.sales,        
                                  + (productPrice * quantity)           
      completedSales = completedSales + (productPrice * quantity)       
                                                                        
      /* Update the total sales for this item */                        
      items.itemIdx.sales = items.itemIdx.sales + quantity              
    end                                                                 
                                                                        
end /* i = ... */                                                       
                                   
/**********************/           
/* Sort the retailers */           
/**********************/           
call sortRetailers                                           
                                                             
/**********************************/                         
/* Sort the items by sales volume */                         
/**********************************/                         
                                                             
call sortItems                                               
                                                             
/********************************/                           
/* Prepare the generated report */                           
/********************************/                           
                                                             
/* First create the completed sales by retailer report */    
reportTitle = 'Completed Sales by Retailer'                  
                                                             
if ( reportMonth = 0 ) then                                  
  reportTitle = reportTitle' - All Dates'                    
else                                                         
  reportTitle = reportTitle' - 'monthNames.reportMonth                   
                                                                         
queue reportTitle                                                        
queue copies('=', length(reportTitle))                                   
queue ' '                                                                
queue 'Retailer              Orders  Total Sales'                        
queue '--------------------  ------  -----------'                        
                                                                         
do r = 1 to retailers.0                                                  
                                                                         
  /* Format the retailer orders to right align it */                     
  formattedOrders = format(retailers.r.orders, 6)                        
                                                                         
  /* Format the sales figure to right align it with 2 decimal places */  
  formattedSales = format(retailers.r.sales / 100, 8, 2)                 
                                                                         
  /* Generate the formatted line */                                      
  nextLine = retailers.r.name                                            
  nextLine = overlay(formattedOrders, nextLine, 23)             
  nextLine = overlay(formattedSales, nextLine, 31)              
                                                                
  /* Output the formatted line */                               
  queue nextLine                                                
                                                                
end /* r = ... */                                               
                                                                
queue '--------------------  ------  -----------'               
                                                                
/* Generate a line for the completed orders */                  
formattedOrders = format(completedOrders, 6)                    
formattedSales = format(completedSales / 100, 8, 2)             
                                                                
totalLine = overlay(formattedOrders, 'Total', 23)               
totalLine = overlay(formattedSales, totalLine, 31)              
                                                                
queue totalLine                                                 
queue '--------------------  ------  -----------'              
                                                               
queue ' '                                                      
queue 'In addition 'cancelledOrders' order(s) totalling',      
      format(cancelledSales / 100, ,2)' were cancelled.'       
                                                               
/* Now display the best selling items */                       
reportTitle = 'Top 5 Items by Sales Volume'                    
                                                               
if ( reportMonth = 0 ) then                                    
  reportTitle = reportTitle' - All Dates'                      
else                                                           
  reportTitle = reportTitle' - 'monthNames.reportMonth         
                                                               
queue ' '                                                      
queue reportTitle                                              
queue copies('=', length(reportTitle))                         
queue ' '                                                      
queue 'Item Code  Item Name                Quantity sold'  
queue '---------  -----------------------  -------------'  
                                                           
do s = 1 to min(5, items.0)                                
                                                           
  /* Format the quantity sold to right align it */         
  formattedQuantity = format(items.s.sales, 6)             
                                                           
  /* Generate the formatted line */                        
  nextLine = items.s.code                                  
  nextLine = overlay(items.s.name, nextLine, 12)           
  nextLine = overlay(formattedQuantity, nextLine, 44)      
                                                           
  /* Output the formatted line */                          
  queue nextLine                                           
                                                           
end /* s = ... */                                          
/* Now display the worst selling items */                   
reportTitle = 'Bottom 5 Items by Sales Volume'              
                                                            
if ( reportMonth = 0 ) then                                 
  reportTitle = reportTitle' - All Dates'                   
else                                                        
  reportTitle = reportTitle' - 'monthNames.reportMonth      
                                                            
queue ' '                                                   
queue reportTitle                                           
queue copies('=', length(reportTitle))                      
queue ' '                                                   
queue 'Item Code  Item Name                Quantity sold'   
queue '---------  -----------------------  -------------'   
                                                            
do s = max(1, items.0 - 4) to items.0                       
                                                            
  /* Format the quantity sold to right align it */          
  formattedQuantity = format(items.s.sales, 6)                   
                                                                 
  /* Generate the formatted line */                              
  nextLine = items.s.code                                        
  nextLine = overlay(items.s.name, nextLine, 12)                 
  nextLine = overlay(formattedQuantity, nextLine, 44)            
                                                                 
  /* Output the formatted line */                                
  queue nextLine                                                 
                                                                 
end /* s = ... */                                                
                                                                 
/* Generate a trailer indicating when report was generated */    
queue ' '                                                        
queue 'Report generated on 'date('W')' 'date('N')' at 'time('C') 
                                                                 
                                                                 
/*******************************/                                
/* Output the generated report */                                   
/*******************************/                                   
                                                                    
"EXECIO * DISKW REPORT (FINIS"                                      
                                                                    
if rc <> 0 then                                                     
do                                                                  
  say 'ERROR: Unable to write to the REPORT file'                   
  exit 8                                                            
end                                                                 
                                                                    
/* All done */                                                      
exit 0                                                              
                                                                    
/******************************************************/            
/* Subroutine to sort the retailers alphabetically by */            
/* name using the simple insertion sort algorithm.    */            
/******************************************************/            
                                                                     
sortRetailers: procedure expose retailers.                           
                                                                     
  /* At the end of each iteration elements 1 to i will be sorted */  
  do i = 2 to retailers.0                                            
                                                                     
    /* Take a copy of the 'current' retailer */                      
    tmpRetailer.name   = retailers.i.name                            
    tmpRetailer.orders = retailers.i.orders                          
    tmpRetailer.sales  = retailers.i.sales                           
                                                                     
    /* Shuffle up all preceding retailers, as applicable, */         
    /* to position the 'current' retailer in the correct  */         
    /* position relative to all of those prior to it in   */         
    /* the original, unsorted, list.                      */         
    positioned = 0                                                   
    j = i - 1                                                        
    k = i                                                            
                                                            
    do until ( positioned = 1 )                             
                                                            
      if retailers.j.name > tmpRetailer.name then           
        do                                                  
          retailers.k.name   = retailers.j.name             
          retailers.k.orders = retailers.j.orders           
          retailers.k.sales  = retailers.j.sales            
                                                            
          j = j - 1                                         
          k = k - 1                                         
                                                            
          if j < 1 then                                     
            positioned = 1                                  
        end                                                 
      else                                                  
        positioned = 1                                      
    end                                                               
                                                                      
    retailers.k.name   = tmpRetailer.name                             
    retailers.k.orders = tmpRetailer.orders                           
    retailers.k.sales  = tmpRetailer.sales                            
                                                                      
  end                                                                 
                                                                      
  return                                                              
                                                                      
/************************************************/                    
/* Subroutine to sort the items by sales volume */                    
/* using the simple insertion sort algorithm.   */                    
/************************************************/                    
                                                                      
sortItems: procedure expose items.                                    
                                                                      
  /* At the end of each iteration elements 1 to i will be sorted */   
  do i = 2 to items.0                                         
                                                              
    /* Take a copy of the 'current' retailer */               
    tmpItem.code  = items.i.code                              
    tmpItem.name  = items.i.name                              
    tmpItem.sales = items.i.sales                             
                                                              
    /* Shuffle up all preceding items, as applicable,   */    
    /* to position the 'current' item in the correct    */    
    /* position relative to all of those prior to it in */    
    /* the original, unsorted, list.                    */    
    positioned = 0                                            
    j = i - 1                                                 
    k = i                                                     
                                                              
    do until ( positioned = 1 )                               
                                                              
      if items.j.sales > tmpItem.sales then                   
       do                                             
         items.k.code  = items.j.code                 
         items.k.name  = items.j.name                 
         items.k.sales = items.j.sales                
                                                      
         j = j - 1                                    
         k = k - 1                                    
                                                      
         if j < 1 then                                
           positioned = 1                             
       end                                            
     else                                             
       positioned = 1                                 
                                                      
   end                                                
                                                      
   items.k.code  = tmpItem.code                       
   items.k.name  = tmpItem.name                       
    items.k.sales = tmpItem.sales  
                                   
  end                              
                                   
  return    
  • upload with new input
  • result: Runtime error     time: 0.03s    memory: 3072 kB     signal: -1

    123
    [COMMLINE1] Expected a '(', constant, or global variable
    [COMMLINE1] Expected a '(', constant, or global variable
    [COMMLINE1] Expected a '(', constant, or global variable
    [COMMLINE1] Expected a '(', constant, or global variable
    [COMMLINE1] Expected a '(', constant, or global variable
    [COMMLINE1] Expected a '(', constant, or global variable
    [COMMLINE1] Expected a '(', constant, or global variable
    [COMMLINE1] Expected a '(', constant, or global variable
    [COMMLINE1] Expected a '(', constant, or global variable
    [COMMLINE1] Expected a '(', constant, or global variable