Projekt

Obecné

Profil

Stáhnout (9.14 KB) Statistiky
| Větev: | Tag: | Revize:
1 734533a8 A-Konig
using System;
2 5d9a5bd9 A-Konig
using System.Collections.Generic;
3
using System.IO;
4 734533a8 A-Konig
using ServerApp.Parser.InputData;
5
using ServerApp.Parser.OutputInfo;
6 5d9a5bd9 A-Konig
7 734533a8 A-Konig
namespace ServerApp.Parser.Parsers
8 5d9a5bd9 A-Konig
{
9 734533a8 A-Konig
    /// <summary>
10
    /// Class parsing jis files into instances of ActivityInfo divided by given time interval
11
    /// Data parsed from 7am (included) to 18pm (included)
12
    /// </summary>
13 98b568bc A-Konig
    /// <author>Alex Konig</author>
14 5d9a5bd9 A-Konig
    class JisParser
15
    {
16 98b568bc A-Konig
17
        /// <summary> Datafile loader  </summary>
18
        DataLoader loader;
19
20
        /// <summary>
21
        /// Constructor
22
        /// </summary>
23
        /// <param name="loader">Datafile loader</param>
24
        public JisParser(DataLoader loader)
25
        {
26
            this.loader = loader;
27
        }
28
29 734533a8 A-Konig
        /// <summary>
30
        /// Parses jis data to ActivityInfo instances
31
        /// Data parsed from 7am (included) to 18pm (included)
32
        /// </summary>
33
        /// <param name="folder">Folder with login data files</param>
34
        /// <param name="wholeDay">Should data be parsed as one instance per day (if true parameter interval will be ignored)</param>
35
        /// <param name="interval">Time interval to divide days by, minimum is 1h</param>
36
        /// <returns></returns>
37
        public List<ActivityInfo> ParseJisData(string folder, bool wholeDay = true, int interval = 1)
38 5d9a5bd9 A-Konig
        {
39
            if (!Directory.Exists(folder))
40
                return null;
41
42 734533a8 A-Konig
            List<ActivityInfo> list = new List<ActivityInfo>();
43
44
            // parse all files
45 5d9a5bd9 A-Konig
            string[] fileEntries = Directory.GetFiles(folder);
46
            foreach (string fileName in fileEntries)
47
            {
48 734533a8 A-Konig
                List<ActivityInfo> loadedData = null;
49
50
                // parse as one instance per day
51 5d9a5bd9 A-Konig
                if (wholeDay)
52 0da0ac88 A-Konig
                    loadedData = ProcessOneJisFileAsDays(fileName);
53 734533a8 A-Konig
                // parse by interval length
54 5d9a5bd9 A-Konig
                else
55 260b1217 A-Konig
                    loadedData = ProcessOneJisFileAsIntervals(fileName, interval);
56 5d9a5bd9 A-Konig
57
                list.AddRange(loadedData);
58
            }
59
60
            return list;
61
        }
62
63 734533a8 A-Konig
        /// <summary>
64
        /// Parses data from one data file as one instance per day
65
        /// </summary>
66
        /// <param name="path">Path ti file</param>
67
        /// <returns>List with ActivityInfo instances</returns>
68 98b568bc A-Konig
        private List<ActivityInfo> ProcessOneJisFileAsDays(string path)
69 5d9a5bd9 A-Konig
        {
70 734533a8 A-Konig
            if (!File.Exists(path))
71
                return null;
72 5d9a5bd9 A-Konig
73 734533a8 A-Konig
            List<ActivityInfo> jisInfo = new List<ActivityInfo>();
74 98b568bc A-Konig
            List<JisInstance> list =  loader.LoadJisFile(path);
75 5d9a5bd9 A-Konig
76 734533a8 A-Konig
            // data for each faculty
77 5d9a5bd9 A-Konig
            int[] recordedAmount = new int[TagInfo.faculties.Length];
78 734533a8 A-Konig
            // min/max hour taken into account
79 0da0ac88 A-Konig
            int[] minmaxHour = new int[] { 7, 18 };
80 734533a8 A-Konig
            // interval length
81 0da0ac88 A-Konig
            int range = minmaxHour[1] - minmaxHour[0];
82 5d9a5bd9 A-Konig
83 734533a8 A-Konig
            // first day
84
            DateTime lastStartTime = new DateTime(list[0].dateTime.Year, list[0].dateTime.Month, list[0].dateTime.Day, minmaxHour[0], 0, 0);
85 5d9a5bd9 A-Konig
            for (int i = 0; i < list.Count; i++)
86
            {
87 0da0ac88 A-Konig
                int currHour = list[i].dateTime.Hour;
88
                if (currHour < minmaxHour[0] || currHour > minmaxHour[1])
89
                    continue;
90
91 734533a8 A-Konig
                // start of the day -> make an instance
92 0da0ac88 A-Konig
                string place = list[i].placeTag;
93 734533a8 A-Konig
                DateTime date = new DateTime(list[i].dateTime.Year, list[i].dateTime.Month, list[i].dateTime.Day, minmaxHour[0], 0, 0);
94 0da0ac88 A-Konig
                if (!date.Equals(lastStartTime)) 
95 5d9a5bd9 A-Konig
                {
96 734533a8 A-Konig
                    // data for each faculty separate
97 5d9a5bd9 A-Konig
                    for (int k = 0; k < TagInfo.faculties.Length; k++)
98
                    {
99 734533a8 A-Konig
                        ActivityInfo dayInfo = new ActivityInfo(TagInfo.faculties[k], recordedAmount[k], lastStartTime, range);
100 5d9a5bd9 A-Konig
                        jisInfo.Add(dayInfo);
101
                    }
102
103
                    recordedAmount = new int[TagInfo.faculties.Length];
104 0da0ac88 A-Konig
                    lastStartTime = date;
105 5d9a5bd9 A-Konig
                }
106
107 734533a8 A-Konig
                // aggregate data
108 0da0ac88 A-Konig
                if (TagInfo.jisPlaces.ContainsKey(place))
109
                {
110
                    int index = TagInfo.jisPlaces[place];
111
                    if (index == -1)
112
                        for (int l = 0; l < TagInfo.faculties.Length; l++)
113
                            recordedAmount[l] += list[i].amount;
114
                    else
115
                        recordedAmount[index] += list[i].amount;
116
117
                }
118 5d9a5bd9 A-Konig
                else
119
                {
120 734533a8 A-Konig
                    // TODO uknown code handling
121 5d9a5bd9 A-Konig
                    Console.WriteLine("Unknown code " + list[i].placeTag);
122
                }
123
124
            }
125
126 734533a8 A-Konig
            // last day
127 0da0ac88 A-Konig
            for (int k = 0; k < TagInfo.faculties.Length; k++)
128
            {
129 734533a8 A-Konig
                ActivityInfo dayInfo = new ActivityInfo(TagInfo.faculties[k], recordedAmount[k], lastStartTime, range);
130 0da0ac88 A-Konig
                jisInfo.Add(dayInfo);
131
            }
132
133
            return jisInfo;
134
        }
135
136 98b568bc A-Konig
        /// <summary>
137
        /// Parses data from one data file as instance per interval length in a day
138
        /// </summary>
139
        /// <param name="path">Path ti file</param>
140
        /// <param name="interval">Interval length</param>
141
        /// <returns>List with ActivityInfo instances</returns>
142
        private List<ActivityInfo> ProcessOneJisFileAsIntervals(string path, int interval)
143 0da0ac88 A-Konig
        {
144 260b1217 A-Konig
            if (!File.Exists(path))
145
                return null;
146
147
            List<ActivityInfo> jisInfo = new List<ActivityInfo>();
148 98b568bc A-Konig
            List<JisInstance> list = loader.LoadJisFile(path);
149 260b1217 A-Konig
150
            // data for each faculty
151
            int[] recordedAmount = new int[TagInfo.faculties.Length];
152
            // min/max hour taken into account
153
            int[] minmaxHour = new int[] { 7, 18 };
154
            int range = minmaxHour[1] - minmaxHour[0];
155
156
            if (interval > range)
157
                return null;
158
159
            int indices = (int) Math.Ceiling(range / (double)interval);
160 ecdce631 A-Konig
            int[] to = new int[indices];
161
            for (int i = 0; i < to.Length; i++) 
162
                to[i] = minmaxHour[0] + interval * (i+1);
163 260b1217 A-Konig
164
            // first day
165
            DateTime lastStartTime = new DateTime(list[0].dateTime.Year, list[0].dateTime.Month, list[0].dateTime.Day, minmaxHour[0], 0, 0);
166 ecdce631 A-Konig
            int endtime = to[0];
167 1db865ce A-Konig
            int startTime = minmaxHour[0];
168
            int index = 0;
169 260b1217 A-Konig
            for (int i = 0; i < list.Count; i++)
170
            {
171
                int currHour = list[i].dateTime.Hour;
172
                if (currHour < minmaxHour[0] || currHour > minmaxHour[1])
173
                    continue;
174
175
                // start of the day -> make an instance
176
                string place = list[i].placeTag;
177
                bool trigger = false;
178
                DateTime date = new DateTime(list[i].dateTime.Year, list[i].dateTime.Month, list[i].dateTime.Day, list[i].dateTime.Hour, 0, 0);
179 1db865ce A-Konig
180 260b1217 A-Konig
                // end of the day
181
                if (!(date.Year == lastStartTime.Year && date.Month == lastStartTime.Month && date.Day == lastStartTime.Day))
182 1db865ce A-Konig
                {
183 260b1217 A-Konig
                    trigger = true;
184 1db865ce A-Konig
                    index = 0;
185
                }
186 260b1217 A-Konig
187
                // end of interval period
188 ecdce631 A-Konig
                if ( date.Hour >= endtime || trigger) 
189 260b1217 A-Konig
                {
190 1db865ce A-Konig
                    // start time of last interval
191
                    DateTime stTime = new DateTime(lastStartTime.Year, lastStartTime.Month, lastStartTime.Day, startTime, 0, 0);
192 ecdce631 A-Konig
193
                    // find end and start time
194 1db865ce A-Konig
                    if (!trigger)
195 ecdce631 A-Konig
                        index++;
196
                    while (date.Hour >= to[index])
197
                        index++;
198 1db865ce A-Konig
199 ecdce631 A-Konig
                    endtime = to[index];
200
                    if (index == 0)
201
                        startTime = minmaxHour[0];
202
                    else
203
                        startTime = to[index - 1];
204 1db865ce A-Konig
205 260b1217 A-Konig
                    // data for each faculty separate
206
                    for (int k = 0; k < TagInfo.faculties.Length; k++)
207
                    {
208 1db865ce A-Konig
                        ActivityInfo dayInfo = new ActivityInfo(TagInfo.faculties[k], recordedAmount[k], stTime, interval);
209 260b1217 A-Konig
                        jisInfo.Add(dayInfo);
210
                    }
211
212
                    recordedAmount = new int[TagInfo.faculties.Length];
213
                    lastStartTime = date;
214
                }
215
216
                // aggregate data
217
                if (TagInfo.jisPlaces.ContainsKey(place))
218
                {
219 1db865ce A-Konig
                    int faculty = TagInfo.jisPlaces[place];
220
                    if (faculty == -1)
221 260b1217 A-Konig
                        for (int l = 0; l < TagInfo.faculties.Length; l++)
222
                            recordedAmount[l] += list[i].amount;
223
                    else
224 1db865ce A-Konig
                        recordedAmount[faculty] += list[i].amount;
225 260b1217 A-Konig
226
                }
227
                else
228
                {
229
                    // TODO uknown code handling
230
                    Console.WriteLine("Unknown code " + list[i].placeTag);
231
                }
232
233
            }
234
235
            // last day
236
            for (int k = 0; k < TagInfo.faculties.Length; k++)
237
            {
238
                ActivityInfo dayInfo = new ActivityInfo(TagInfo.faculties[k], recordedAmount[k], lastStartTime, interval);
239
                jisInfo.Add(dayInfo);
240
            }
241
242
            return jisInfo;
243 5d9a5bd9 A-Konig
        }
244
    }
245
}