Merge: Stricter default arguments
[nit.git] / contrib / benitlux / src / report.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 import benitlux_model
16 import benitlux_db
17
18 # Sort beers by their availability
19 class BeerComparator
20 super Comparator
21
22 # 1st sorting priority
23 var map1: HashMap[COMPARED, Comparable]
24
25 # 2nd sorting priority
26 var map2: HashMap[COMPARED, Comparable]
27
28 # Key compare
29 redef fun compare(a, b) do return if map1[a] == map1[b] then
30 map2[a] <=> map2[b]
31 else map1[a] <=> map1[b]
32 end
33
34 # Use the local DB
35 var db_path = "benitlux_sherbrooke.db"
36 var db = new DB.open(db_path)
37
38 # All known beers
39 var beers = db.beers
40 assert beers != null
41 print "{beers.length} known beers"
42
43 # All days
44 var all_days = db.days
45 assert all_days != null
46 print "{all_days.length} days, from {all_days.first} to {all_days.last}"
47
48 # Beers availability by days
49 var beer2days = new HashMap[Beer, Array[String]]
50 for beer in beers do
51 var days = db.days(beer)
52 assert days != null
53 default_comparator.sort days
54 beer2days[beer] = days
55 end
56
57 # Sort beers by their availability and first date of appearance
58 var availability = new HashMap[Beer, Int]
59 var appearances = new HashMap[Beer, String]
60 for beer in beers do
61 var days = beer2days[beer]
62 if days.not_empty then
63 appearances[beer] = days.first
64 availability[beer] = -days.length # Opposite for inverse sort
65 else
66 appearances[beer] = "err"
67 availability[beer] = 1
68 end
69 end
70
71 # Sort by availability then appearance
72 var sorter: Comparator = new BeerComparator(availability, appearances)
73 sorter.sort beers
74
75 # List all beers
76 print "\nBeers:"
77 for beer in beers do
78 var days = beer2days[beer]
79
80 # Skip never-available beers, usually name errors
81 if days.is_empty then continue
82
83 var from = days.first
84 if from == all_days.first then from = " ... "
85
86 var to = days.last
87 if to == all_days.last then to = " ... "
88
89 print "- {days.length}\t{from} {to}\t{beer.name}: {beer.desc}"
90 end
91
92 # Sort by appearance then availability
93 sorter = new BeerComparator(appearances, availability)
94 sorter.sort beers
95
96 # Display the batch graph
97 print "\nBatches:"
98
99 # Compute `column_width` days from all the known days
100 var column_width = 70
101 var days_sample = [for i in column_width.times do all_days[i*all_days.length/column_width]]
102
103 for beer in beers do
104 var days = beer2days[beer]
105
106 # Skip never-available beers, usually name errors
107 if days.is_empty then continue
108
109 # Print a line looking like: " ############ ###### ######## : Beer"
110 for s in days_sample do printn if days.has(s) then "#" else " "
111 print ": {beer.name}"
112 end
113
114 db.close