Projekt

Obecné

Profil

Stáhnout (11.5 KB) Statistiky
| Větev: | Tag: | Revize:
1 cdf3c217 A-Konig
//
2
// Author: A. Konig
3
//
4
5
using ServerApp.Parser.InputData;
6 734533a8 A-Konig
using ServerApp.Parser.OutputInfo;
7 0da0ac88 A-Konig
using System;
8 5d9a5bd9 A-Konig
using System.Collections.Generic;
9 0da0ac88 A-Konig
using System.IO;
10 5d9a5bd9 A-Konig
11 734533a8 A-Konig
namespace ServerApp.Parser.Parsers
12 5d9a5bd9 A-Konig
{
13 734533a8 A-Konig
    /// <summary>
14
    /// Class parsing login files into instances of ActivityInfo divided by given time interval
15
    /// Data parsed from 7am (included) to 18pm (included)
16
    /// </summary>
17 cdf3c217 A-Konig
    /// <author>A. Konig</author>
18 4b847de5 A-Konig
    public class LogInParser
19 5d9a5bd9 A-Konig
    {
20 98b568bc A-Konig
        /// <summary> Datafile loader  </summary>
21 cdf3c217 A-Konig
        IDataLoader loader;
22 98b568bc A-Konig
23
        /// <summary>
24
        /// Constructor
25
        /// </summary>
26
        /// <param name="loader">Datafile loader</param>
27 cdf3c217 A-Konig
        public LogInParser(IDataLoader loader)
28 98b568bc A-Konig
        {
29
            this.loader = loader;
30
        }
31
32 734533a8 A-Konig
        /// <summary>
33
        /// Parses login data to ActivityInfo instances
34
        /// Data parsed from 7am (included) to 18pm (included)
35
        /// </summary>
36 cdf3c217 A-Konig
        /// <param name="loginFiles">Paths to files with login data files</param>
37
        /// <param name="endTime">End time of related data</param>
38
        /// <param name="startTime">Start time of related data</param>
39 734533a8 A-Konig
        /// <param name="wholeDay">Should data be parsed as one instance per day (if true parameter interval will be ignored)</param>
40
        /// <param name="interval">Time interval to divide days by, minimum is 1h</param>
41
        /// <returns></returns>
42 cdf3c217 A-Konig
        public List<ActivityInfo> ParseLogInData(List<string> loginFiles, DateTime startTime, DateTime endTime, bool wholeDay = true, int interval = 1)
43 0da0ac88 A-Konig
        {
44 734533a8 A-Konig
            List<ActivityInfo> list = new List<ActivityInfo>();
45 0da0ac88 A-Konig
46 23e8ae04 A-Konig
            if (loginFiles == null || interval <= 0)
47 cdf3c217 A-Konig
                return list;
48
49 23e8ae04 A-Konig
            string current = "";
50
            try
51 0da0ac88 A-Konig
            {
52 23e8ae04 A-Konig
                // for all files in folder
53
                foreach (string fileName in loginFiles)
54
                {
55
                    current = fileName;
56 0da0ac88 A-Konig
57 23e8ae04 A-Konig
                    if (!File.Exists(fileName))
58
                        continue;
59
60
                    // parse as one instance per day
61
                    List<ActivityInfo> loadedData = null;
62
                    if (wholeDay)
63
                        loadedData = ProcessOneLogInFileAsDays(fileName, startTime, endTime);
64
                    // parse by interval length
65
                    else
66
                        loadedData = ProcessOneLoginFileAsIntervals(fileName, interval, startTime, endTime);
67
68
                    list.AddRange(loadedData);
69
                }
70
            } catch
71
            {
72
                Console.WriteLine("Incorrect Login input file " + current);
73 0da0ac88 A-Konig
            }
74
75
            return list;
76
        }
77
78 734533a8 A-Konig
        /// <summary>
79
        /// Parses data from one data file as one instance per day
80
        /// </summary>
81
        /// <param name="path">Path ti file</param>
82 cdf3c217 A-Konig
        /// <param name="endTime">End time of related data</param>
83
        /// <param name="startTime">Start time of related data</param>
84 734533a8 A-Konig
        /// <returns>List with ActivityInfo instances</returns>
85 cdf3c217 A-Konig
        private List<ActivityInfo> ProcessOneLogInFileAsDays(string path, DateTime startTime, DateTime endTime)
86 0da0ac88 A-Konig
        {
87 cdf3c217 A-Konig
            List<ActivityInfo> loginInfo = new List<ActivityInfo>();
88
89 98b568bc A-Konig
            List<LogInInstance> list = loader.LoadLoginFile(path);
90 3729dcae A-Konig
            if (list == null || list.Count == 0)
91 a53b1de8 A-Konig
                return loginInfo;
92 0da0ac88 A-Konig
93 734533a8 A-Konig
            // data for each faculty
94 d39750f3 A-Konig
            int[] recordedAmount = new int[TagInfo.buildings.Length];
95 734533a8 A-Konig
            // min/max hour taken into account
96 0da0ac88 A-Konig
            int[] minmaxHour = new int[] { 7, 18 };
97 734533a8 A-Konig
            // interval length
98 0da0ac88 A-Konig
            int range = minmaxHour[1] - minmaxHour[0];
99
100 734533a8 A-Konig
            // first day
101
            DateTime lastStartDay = new DateTime(list[0].date.Year, list[0].date.Month, list[0].date.Day, minmaxHour[0], 0, 0);
102 0da0ac88 A-Konig
            for (int i = 0; i < list.Count; i++)
103
            {
104 93452c41 A-Konig
                int currHour = list[i].lessonStart.Hour;
105 0da0ac88 A-Konig
                if (currHour < minmaxHour[0] || currHour > minmaxHour[1])
106
                    continue;
107
108 734533a8 A-Konig
                // start of the day -> make an instance
109 0da0ac88 A-Konig
                string place = list[i].building;
110 734533a8 A-Konig
                DateTime date = new DateTime(list[i].date.Year, list[i].date.Month, list[i].date.Day, minmaxHour[0], 0, 0);
111 4b847de5 A-Konig
                DateTime dateOfLessonStart = new DateTime(list[i].date.Year, list[i].date.Month, list[i].date.Day, list[i].lessonStart.Hour, list[i].lessonStart.Minute, list[i].lessonStart.Second);
112 0da0ac88 A-Konig
                if (!date.Equals(lastStartDay))
113
                {
114 734533a8 A-Konig
                    // data for each faculty separate
115 d39750f3 A-Konig
                    for (int k = 0; k < TagInfo.buildings.Length; k++)
116 0da0ac88 A-Konig
                    {
117 d39750f3 A-Konig
                        ActivityInfo dayInfo = new ActivityInfo(TagInfo.buildings[k], recordedAmount[k], lastStartDay, range); 
118 4b847de5 A-Konig
                        if (recordedAmount[k] != 0)
119
                            loginInfo.Add(dayInfo);
120 0da0ac88 A-Konig
                    }
121
122 d39750f3 A-Konig
                    recordedAmount = new int[TagInfo.buildings.Length];
123 0da0ac88 A-Konig
                    lastStartDay = date;
124
                }
125
126 cdf3c217 A-Konig
                // if not in allowed time window -> discard
127 4b847de5 A-Konig
                if (dateOfLessonStart < startTime || dateOfLessonStart > endTime)
128 cdf3c217 A-Konig
                    continue;
129
130 734533a8 A-Konig
                // aggregate data
131 0da0ac88 A-Konig
                if (TagInfo.buildingTags.ContainsKey(place))
132
                {
133
                    int index = TagInfo.buildingTags[place];
134 d39750f3 A-Konig
                    //Console.WriteLine(place + " " + index);
135
136 734533a8 A-Konig
                    // to all
137 0da0ac88 A-Konig
                    if (index == -1)
138 d39750f3 A-Konig
                        for (int l = 0; l < TagInfo.buildings.Length; l++)
139 0da0ac88 A-Konig
                            recordedAmount[l] += list[i].amount;
140
                    else
141
                        recordedAmount[index] += list[i].amount;
142
143
                }
144
                else
145
                {
146 d39750f3 A-Konig
                    // TODO uknown code handling -> to file?
147
                    // Console.WriteLine("Unknown code " + list[i].building);
148 0da0ac88 A-Konig
                }
149
150
            }
151
152 734533a8 A-Konig
            // last day
153 d39750f3 A-Konig
            for (int k = 0; k < TagInfo.buildings.Length; k++)
154 0da0ac88 A-Konig
            {
155 d39750f3 A-Konig
                ActivityInfo dayInfo = new ActivityInfo(TagInfo.buildings[k], recordedAmount[k], lastStartDay, range);
156 4b847de5 A-Konig
                if (recordedAmount[k] != 0)
157
                    loginInfo.Add(dayInfo);
158 0da0ac88 A-Konig
            }
159
160
            return loginInfo;
161
        }
162
163 98b568bc A-Konig
        /// <summary>
164
        /// Parses data from one data file as one instance per interval length
165
        /// </summary>
166
        /// <param name="path">Path to file</param>
167
        /// <param name="interval">Interval length</param>
168 cdf3c217 A-Konig
        /// <param name="endTime">End time of related data</param>
169
        /// <param name="startTime">Start time of related data</param>
170 98b568bc A-Konig
        /// <returns>List with ActivityInfo instances</returns>
171 cdf3c217 A-Konig
        private List<ActivityInfo> ProcessOneLoginFileAsIntervals(string path, int interval, DateTime startTime, DateTime endTime)
172 0da0ac88 A-Konig
        {
173 cdf3c217 A-Konig
            List<ActivityInfo> loginInfo = new List<ActivityInfo>();
174
            
175 98b568bc A-Konig
            List<LogInInstance> list = loader.LoadLoginFile(path);
176 3729dcae A-Konig
            if (list == null || list.Count == 0)
177 a53b1de8 A-Konig
                return loginInfo;
178 54fb2bde A-Konig
179
            // min/max hour taken into account
180
            int[] minmaxHour = new int[] { 7, 18 };
181
            int range = minmaxHour[1] - minmaxHour[0];
182
183
            if (interval > range)
184
                return null;
185
186
            int indices = (int)Math.Ceiling(range / (double)interval);
187
            int[] to = new int[indices];
188
            int[][] data = new int[indices][];
189
            for (int i = 0; i < to.Length; i++)
190
            {
191
                to[i] = minmaxHour[0] + interval * (i + 1);
192 d39750f3 A-Konig
                data[i] = new int[TagInfo.buildings.Length];
193 54fb2bde A-Konig
            }
194
            
195
            // first day
196
            DateTime lastStartTime = new DateTime(list[0].date.Year, list[0].date.Month, list[0].date.Day, minmaxHour[0], 0, 0);
197
            int index = 0;
198
            for (int i = 0; i < list.Count; i++)
199
            {
200
                int currHour = list[i].lessonStart.Hour;
201
                if (currHour < minmaxHour[0] || currHour > minmaxHour[1])
202
                    continue;
203
204
                // start of the day -> make an instance
205
                string place = list[i].building;
206
                DateTime date = new DateTime(list[i].date.Year, list[i].date.Month, list[i].date.Day, list[i].lessonStart.Hour, 0, 0);
207 4b847de5 A-Konig
                DateTime dateOfLessonStart = new DateTime(list[i].date.Year, list[i].date.Month, list[i].date.Day, list[i].lessonStart.Hour, list[i].lessonStart.Minute, list[i].lessonStart.Second);
208 54fb2bde A-Konig
209
                // end of the day
210
                if (!(date.Year == lastStartTime.Year && date.Month == lastStartTime.Month && date.Day == lastStartTime.Day))
211
                {
212
                    // note down all aggregated data
213
                    for (int k = 0; k < to.Length; k++)
214
                    {
215
                        DateTime stTime = new DateTime(lastStartTime.Year, lastStartTime.Month, lastStartTime.Day, to[k] - interval, 0, 0);
216
217
                        // data for each faculty separate
218 d39750f3 A-Konig
                        for (int l = 0; l < TagInfo.buildings.Length; l++)
219 54fb2bde A-Konig
                        {
220 d39750f3 A-Konig
                            ActivityInfo dayInfo = new ActivityInfo(TagInfo.buildings[l], data[k][l], stTime, interval);
221 4b847de5 A-Konig
                            if (data[k][l] != 0)
222
                                loginInfo.Add(dayInfo);
223 54fb2bde A-Konig
                        }
224
225 d39750f3 A-Konig
                        data[k] = new int[TagInfo.buildings.Length];
226 54fb2bde A-Konig
                    }
227
                    lastStartTime = date;
228
                }
229
230 cdf3c217 A-Konig
                // if not in allowed time window -> discard
231 4b847de5 A-Konig
                if (dateOfLessonStart < startTime || dateOfLessonStart > endTime)
232 cdf3c217 A-Konig
                    continue;
233
234 54fb2bde A-Konig
                // find index for current instance
235
                index = 0;
236
                for (int k = 1; k < to.Length; k++)
237
                {
238
                    if (to[k] > list[i].lessonStart.Hour && to[k - 1] <= list[i].lessonStart.Hour)
239
                    {
240
                        index = k;
241
                        break;
242
                    }
243
                }
244
245
                // aggregate data
246
                if (TagInfo.buildingTags.ContainsKey(place))
247
                {
248
                    int faculty = TagInfo.buildingTags[place];
249
                    // to all
250
                    if (faculty == -1)
251 d39750f3 A-Konig
                        for (int l = 0; l < TagInfo.buildings.Length; l++)
252 54fb2bde A-Konig
                            data[index][l] += list[i].amount;
253
                    // to first two
254
                    else if (faculty == -2)
255
                    {
256
                        data[index][0] += list[i].amount;
257
                        data[index][1] += list[i].amount;
258
                    }
259
                    else
260
                        data[index][faculty] += list[i].amount;
261
262
                }
263
                else
264
                {
265 d39750f3 A-Konig
                    // TODO uknown code handling -> write to file?
266
                    // Console.WriteLine("Unknown code " + list[i].building);
267 54fb2bde A-Konig
                }
268
269
            }
270
271
            for (int k = 0; k < to.Length; k++)
272
            {
273
                DateTime stTime = new DateTime(lastStartTime.Year, lastStartTime.Month, lastStartTime.Day, to[k] - interval, 0, 0);
274
275
                // data for each faculty separate
276 d39750f3 A-Konig
                for (int l = 0; l < TagInfo.buildings.Length; l++)
277 54fb2bde A-Konig
                {
278 d39750f3 A-Konig
                    ActivityInfo dayInfo = new ActivityInfo(TagInfo.buildings[l], data[k][l], stTime, interval);
279 4b847de5 A-Konig
                    if (data[k][l] != 0)
280
                        loginInfo.Add(dayInfo);
281 54fb2bde A-Konig
                }
282
            }
283
284 cdf3c217 A-Konig
            return loginInfo;
285 0da0ac88 A-Konig
        }
286
287 5d9a5bd9 A-Konig
    }
288 54fb2bde A-Konig
}