Revize 22211075
Přidáno uživatelem Roman Kalivoda před více než 3 roky(ů)
Server/ServerApp.sln | ||
---|---|---|
7 | 7 |
EndProject |
8 | 8 |
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestProject", "TestProject\TestProject.csproj", "{8A09DB8E-64B1-4D55-991E-7F7B21996B45}" |
9 | 9 |
EndProject |
10 |
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServerAppTests", "ServerAppTests\ServerAppTests.csproj", "{E068474B-98FB-431D-84EB-000AA36D0FC5}" |
|
11 |
EndProject |
|
12 | 10 |
Global |
13 | 11 |
GlobalSection(SolutionConfigurationPlatforms) = preSolution |
14 | 12 |
Debug|Any CPU = Debug|Any CPU |
... | ... | |
33 | 31 |
{8A09DB8E-64B1-4D55-991E-7F7B21996B45}.Release|Any CPU.Build.0 = Release|Any CPU |
34 | 32 |
{8A09DB8E-64B1-4D55-991E-7F7B21996B45}.Release|x64.ActiveCfg = Release|Any CPU |
35 | 33 |
{8A09DB8E-64B1-4D55-991E-7F7B21996B45}.Release|x64.Build.0 = Release|Any CPU |
36 |
{E068474B-98FB-431D-84EB-000AA36D0FC5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|
37 |
{E068474B-98FB-431D-84EB-000AA36D0FC5}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|
38 |
{E068474B-98FB-431D-84EB-000AA36D0FC5}.Debug|x64.ActiveCfg = Debug|Any CPU |
|
39 |
{E068474B-98FB-431D-84EB-000AA36D0FC5}.Debug|x64.Build.0 = Debug|Any CPU |
|
40 |
{E068474B-98FB-431D-84EB-000AA36D0FC5}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|
41 |
{E068474B-98FB-431D-84EB-000AA36D0FC5}.Release|Any CPU.Build.0 = Release|Any CPU |
|
42 |
{E068474B-98FB-431D-84EB-000AA36D0FC5}.Release|x64.ActiveCfg = Release|Any CPU |
|
43 |
{E068474B-98FB-431D-84EB-000AA36D0FC5}.Release|x64.Build.0 = Release|Any CPU |
|
44 | 34 |
EndGlobalSection |
45 | 35 |
GlobalSection(SolutionProperties) = preSolution |
46 | 36 |
HideSolutionNode = FALSE |
Server/ServerApp/Connection/XMLProtocolHandler/Request.cs | ||
---|---|---|
1 | 1 |
using System; |
2 |
using System.Collections.Generic; |
|
3 |
using System.Linq; |
|
4 |
using System.Text; |
|
5 |
using System.Threading.Tasks; |
|
2 | 6 |
using System.Xml.Serialization; |
3 | 7 |
|
4 | 8 |
namespace ServerApp.Connection.XMLProtocolHandler |
Server/ServerApp/Parser/Parsers/DataParser.cs | ||
---|---|---|
82 | 82 |
var jisFiles = downloader.GetData(pathJis, start, end); |
83 | 83 |
var loginFiles = downloader.GetData(pathLogIn, start, end); |
84 | 84 |
|
85 |
WeatherDataUsed = new List<string>(); |
|
86 |
ActivityDataUsed = new List<string>(); |
|
87 |
|
|
88 |
WeatherDataUsed.AddRange(weatherFiles); |
|
89 |
ActivityDataUsed.AddRange(jisFiles); |
|
90 |
ActivityDataUsed.AddRange(loginFiles); |
|
91 |
|
|
92 | 85 |
WeatherList = weatherParser.ParseWeatherData(weatherFiles, startTime, endTime, wholeDay, interval); |
93 | 86 |
jisList = jisParser.ParseJisData(jisFiles, startTime, endTime, wholeDay, interval); |
94 | 87 |
loginList = loginParser.ParseLogInData(loginFiles, startTime, endTime, wholeDay, interval); |
Server/ServerApp/Parser/Parsers/IDataParser.cs | ||
---|---|---|
21 | 21 |
List<ActivityInfo> attendanceList; |
22 | 22 |
public List<ActivityInfo> AttendanceList { get => attendanceList; internal set => attendanceList = value; } |
23 | 23 |
|
24 |
/// <summary> List of weather file names the parser was last used on </summary> |
|
25 |
List<String> weatherdataUsed; |
|
26 |
public List<string> WeatherDataUsed { get => weatherdataUsed; set => weatherdataUsed = value; } |
|
27 |
|
|
28 |
/// <summary> List of activity file names the parser was last used on </summary> |
|
29 |
List<String> activitydataUsed; |
|
30 |
public List<string> ActivityDataUsed { get => activitydataUsed; set => activitydataUsed = value; } |
|
31 |
|
|
32 |
|
|
33 | 24 |
/// <summary> |
34 | 25 |
/// Parse data |
35 | 26 |
/// </summary> |
Server/ServerApp/Predictor/FeatureExtractor.cs | ||
---|---|---|
13 | 13 |
/// <summary> |
14 | 14 |
/// A class responsible for preparation of features for classifiers. |
15 | 15 |
/// </summary> |
16 |
class FeatureExtractor |
|
16 |
public class FeatureExtractor
|
|
17 | 17 |
{ |
18 | 18 |
/// <summary> |
19 | 19 |
/// A DataParser instance used to access info objects. |
20 | 20 |
/// </summary> |
21 |
private readonly IDataParser DataParser;
|
|
21 |
private readonly IDataParser dataParser;
|
|
22 | 22 |
|
23 |
/// <summary> |
|
24 |
/// A configuration object of the <c>Predictor</c> package |
|
25 |
/// </summary> |
|
26 |
private PredictorConfiguration Configuration; |
|
23 |
private Dictionary<string, int> buildingsToAreas; |
|
27 | 24 |
|
28 | 25 |
/// <summary> |
29 | 26 |
/// Instantiates new FeatureExtractor class. |
30 | 27 |
/// </summary> |
31 | 28 |
/// <param name="dataParser">Data parser used to access training data.</param> |
32 |
public FeatureExtractor(IDataParser dataParser, PredictorConfiguration configuration)
|
|
29 |
public FeatureExtractor(IDataParser dataParser, Dictionary<string, int> buildingsToAreas)
|
|
33 | 30 |
{ |
34 |
this.DataParser = dataParser;
|
|
35 |
this.Configuration = configuration;
|
|
31 |
this.dataParser = dataParser;
|
|
32 |
this.buildingsToAreas = buildingsToAreas;
|
|
36 | 33 |
} |
37 | 34 |
|
38 | 35 |
/// <summary> |
... | ... | |
44 | 41 |
/// <param name="interval"></param> |
45 | 42 |
/// <param name="wholeDay"></param> |
46 | 43 |
/// <returns></returns> |
47 |
public List<ModelInput> PrepareTrainingInput(int area) |
|
44 |
public List<ModelInput> PrepareTrainingInput(int area, DateTime startDate, DateTime endDate, int interval = 1, bool wholeDay = true)
|
|
48 | 45 |
{ |
46 |
dataParser.Parse(startDate, endDate, interval, wholeDay); |
|
49 | 47 |
List<string> buildings = new List<string>(); |
50 | 48 |
|
51 | 49 |
// find all buildings in area |
52 |
foreach (KeyValuePair<string, int> kvp in Configuration.BuildingsToAreas)
|
|
50 |
foreach (KeyValuePair<string, int> kvp in buildingsToAreas)
|
|
53 | 51 |
{ |
54 | 52 |
if (kvp.Value == area) |
55 | 53 |
{ |
... | ... | |
58 | 56 |
} |
59 | 57 |
|
60 | 58 |
var res = new List<ModelInput>(); |
61 |
foreach (WeatherInfo val in DataParser.WeatherList)
|
|
59 |
foreach (WeatherInfo val in dataParser.WeatherList)
|
|
62 | 60 |
{ |
63 | 61 |
res.Add(new ModelInput |
64 | 62 |
{ |
65 |
Time = val.startTime, |
|
66 | 63 |
Temp = (float)val.temp, |
67 |
Hour = val.startTime.Hour,
|
|
64 |
Time = val.startTime,
|
|
68 | 65 |
Wind = (float)val.wind, |
69 | 66 |
Rain = (float)val.rain, |
70 | 67 |
}); |
71 | 68 |
} |
72 | 69 |
|
73 |
List<ActivityInfo> attendance = DataParser.AttendanceList;
|
|
70 |
List<ActivityInfo> attendance = dataParser.AttendanceList;
|
|
74 | 71 |
foreach (ModelInput input in res) |
75 | 72 |
{ |
76 | 73 |
List<int> amounts = new List<int>(); |
77 | 74 |
List<int> maxima = new List<int>(); |
78 | 75 |
foreach (string building in buildings) |
79 | 76 |
{ |
80 |
List<ActivityInfo> temp = attendance.Where(activity => activity.building.Equals(building)).ToList(); |
|
81 |
amounts.Add(temp.Where(activity => activity.startTime.Equals(input.Time)).Select(activity => activity.amount).First());
|
|
82 |
maxima.Add(temp.Select(activity => activity.amount).Max());
|
|
77 |
|
|
78 |
amounts.Add(attendance.Where(activity => activity.building.Equals(building) && activity.startTime.Equals(input.Time)).Select(activity => activity.amount).First());
|
|
79 |
maxima.Add(attendance.Where(activity => activity.building.Equals(building)).Select(activity => activity.amount).Max());
|
|
83 | 80 |
} |
84 | 81 |
double ratio = amounts.Sum() / (double)maxima.Sum(); |
85 | 82 |
input.Label = RatioToLabel(ratio); |
... | ... | |
93 | 90 |
if (ratio < 0.1f) |
94 | 91 |
{ |
95 | 92 |
return "10%"; |
96 |
} |
|
97 |
else if (ratio < 0.2f) |
|
93 |
} else if (ratio < 0.2f) |
|
98 | 94 |
{ |
99 | 95 |
return "20%"; |
100 |
} |
|
101 |
else if (ratio < 0.3f) |
|
96 |
} else if (ratio < 0.3f) |
|
102 | 97 |
{ |
103 | 98 |
return "30%"; |
104 |
} |
|
105 |
else if (ratio < 0.4f) |
|
99 |
} else if (ratio < 0.4f) |
|
106 | 100 |
{ |
107 | 101 |
return "40%"; |
108 |
} |
|
109 |
else if (ratio < 0.5f) |
|
102 |
} else if (ratio < 0.5f) |
|
110 | 103 |
{ |
111 | 104 |
return "50%"; |
112 |
} |
|
113 |
else if (ratio < 0.6f) |
|
105 |
} else if (ratio < 0.6f) |
|
114 | 106 |
{ |
115 | 107 |
return "60%"; |
116 |
} |
|
117 |
else if (ratio < 0.7f) |
|
118 |
{ |
|
108 |
} else if(ratio < 0.7f) { |
|
119 | 109 |
return "70%"; |
120 |
} |
|
121 |
else if (ratio < 0.8f) |
|
110 |
} else if (ratio < 0.8f) |
|
122 | 111 |
{ |
123 | 112 |
return "80%"; |
124 |
} |
|
125 |
else if (ratio < 0.9f) |
|
113 |
} else if (ratio < 0.9f) |
|
126 | 114 |
{ |
127 | 115 |
return "90%"; |
128 |
} |
|
129 |
else |
|
116 |
} else |
|
130 | 117 |
{ |
131 | 118 |
return "100%"; |
132 | 119 |
} |
133 | 120 |
} |
134 | 121 |
|
135 |
internal double LabelToRatio(string label)
|
|
122 |
private double LabelToRatio(string label)
|
|
136 | 123 |
{ |
137 |
if (label.Equals("10%")) |
|
138 |
{ |
|
124 |
if (label.Equals("10%")) { |
|
139 | 125 |
return 0.1f; |
140 | 126 |
} |
141 |
else if (label.Equals("20%")) |
|
142 |
{ |
|
127 |
else if (label.Equals("20%")) { |
|
143 | 128 |
return 0.2f; |
144 | 129 |
} |
145 |
else if (label.Equals("30%")) |
|
146 |
{ |
|
130 |
else if (label.Equals("30%")) { |
|
147 | 131 |
return 0.3f; |
148 | 132 |
} |
149 |
else if (label.Equals("40%")) |
|
150 |
{ |
|
133 |
else if (label.Equals("40%")) { |
|
151 | 134 |
return 0.4f; |
152 | 135 |
} |
153 |
else if (label.Equals("50%")) |
|
154 |
{ |
|
136 |
else if (label.Equals("50%")) { |
|
155 | 137 |
return 0.5f; |
156 | 138 |
} |
157 |
else if (label.Equals("60%")) |
|
158 |
{ |
|
139 |
else if (label.Equals("60%")) { |
|
159 | 140 |
return 0.6f; |
160 | 141 |
} |
161 |
else if (label.Equals("70%")) |
|
162 |
{ |
|
142 |
else if (label.Equals("70%")) { |
|
163 | 143 |
return 0.7f; |
164 | 144 |
} |
165 |
else if (label.Equals("80%")) |
|
166 |
{ |
|
145 |
else if (label.Equals("80%")) { |
|
167 | 146 |
return 0.8f; |
168 | 147 |
} |
169 |
else if (label.Equals("90%")) |
|
170 |
{ |
|
148 |
else if (label.Equals("90%")) { |
|
171 | 149 |
return 0.9f; |
172 | 150 |
} |
173 | 151 |
else |
Server/ServerApp/Predictor/IPredictionController.cs | ||
---|---|---|
2 | 2 |
// Author: Roman Kalivoda |
3 | 3 |
// |
4 | 4 |
|
5 |
using System; |
|
5 | 6 |
using System.Collections.Generic; |
7 |
using System.IO; |
|
8 |
using Microsoft.ML; |
|
6 | 9 |
using ServerApp.Connection.XMLProtocolHandler; |
10 |
using ServerApp.Parser.OutputInfo; |
|
7 | 11 |
|
8 | 12 |
namespace ServerApp.Predictor |
9 | 13 |
{ |
... | ... | |
28 | 32 |
/// </summary> |
29 | 33 |
/// <param name="locationKey">A string identifier of the location for which to load a predictor.</param> |
30 | 34 |
/// <param name="path">A path to folder with trained prediction model.</param> |
31 |
void Load(string locationKey = null, string path = null);
|
|
35 |
void Load(string locationKey = null,string path = null); |
|
32 | 36 |
|
33 | 37 |
/// <summary> |
34 | 38 |
/// Predicts turnout level at given time supposing given weather conditions. |
Server/ServerApp/Predictor/ModelInput.cs | ||
---|---|---|
13 | 13 |
/// </summary> |
14 | 14 |
public class ModelInput |
15 | 15 |
{ |
16 |
/// <summary> |
|
17 |
/// Start time of the information. |
|
18 |
/// </summary> |
|
19 |
public DateTime Time { get; set; } |
|
20 |
|
|
21 | 16 |
/// <summary> |
22 | 17 |
/// A label of this training input. |
23 | 18 |
/// </summary> |
... | ... | |
31 | 26 |
public float Temp { get; set; } |
32 | 27 |
|
33 | 28 |
/// <summary> |
34 |
/// Hour of the predicted turnout.
|
|
29 |
/// Time of the predicted turnout.
|
|
35 | 30 |
/// </summary> |
36 |
[ColumnName("Hour"), LoadColumn(2)]
|
|
37 |
public int Hour { get; set; }
|
|
31 |
[ColumnName("Time"), LoadColumn(2)]
|
|
32 |
public DateTime Time { get; set; }
|
|
38 | 33 |
|
39 | 34 |
/// <summary> |
40 |
/// Wind velocity in m/s
|
|
35 |
/// Wind velocity in ? units
|
|
41 | 36 |
/// </summary> |
42 | 37 |
[ColumnName("Wind"), LoadColumn(3)] |
43 | 38 |
public float Wind { get; set; } |
44 | 39 |
|
45 | 40 |
/// <summary> |
46 |
/// Precipitation in %
|
|
41 |
/// Precipitation |
|
47 | 42 |
/// </summary> |
48 | 43 |
[ColumnName("Rain"), LoadColumn(4)] |
49 | 44 |
public float Rain { get; set; } |
Server/ServerApp/Predictor/ModelOutput.cs | ||
---|---|---|
2 | 2 |
// Author: Roman Kalivoda |
3 | 3 |
// |
4 | 4 |
|
5 |
using System; |
|
5 | 6 |
using Microsoft.ML.Data; |
6 | 7 |
|
7 | 8 |
namespace ServerApp.Predictor |
... | ... | |
15 | 16 |
/// A predicted class. |
16 | 17 |
/// </summary> |
17 | 18 |
[ColumnName("PredictedLabel")] |
18 |
public string PredictedLabel { get; set; }
|
|
19 |
public String Prediction { get; set; }
|
|
19 | 20 |
|
20 | 21 |
} |
21 | 22 |
} |
Server/ServerApp/Predictor/NaiveBayesClassifier.cs | ||
---|---|---|
40 | 40 |
{ |
41 | 41 |
this._trainingDataView = _mlContext.Data.LoadFromEnumerable(trainInput); |
42 | 42 |
var pipeline = _mlContext.Transforms.Conversion.MapValueToKey(nameof(ModelInput.Label)) |
43 |
.Append(_mlContext.Transforms.Conversion.ConvertType(nameof(ModelInput.Hour))) |
|
44 |
.Append(_mlContext.Transforms.Concatenate("Features", |
|
45 |
new[] { nameof(ModelInput.Temp), nameof(ModelInput.Rain), nameof(ModelInput.Wind), nameof(ModelInput.Hour) })) |
|
46 |
.Append(_mlContext.Transforms.NormalizeMeanVariance("Features", useCdf:false)) |
|
43 |
.Append(_mlContext.Transforms.Concatenate("Features", new[] { "Temp" })) |
|
44 |
.Append(_mlContext.Transforms.NormalizeMinMax("Features", "Features")) |
|
47 | 45 |
.AppendCacheCheckpoint(_mlContext) |
48 | 46 |
.Append(_mlContext.MulticlassClassification.Trainers.NaiveBayes()) |
49 |
.Append(_mlContext.Transforms.Conversion.MapKeyToValue(nameof(ModelOutput.PredictedLabel)));
|
|
47 |
.Append(_mlContext.Transforms.Conversion.MapKeyToValue("PredictedLabel")); ;
|
|
50 | 48 |
|
51 |
var cvResults = _mlContext.MulticlassClassification.CrossValidate(this._trainingDataView, pipeline); |
|
52 |
foreach (var result in cvResults) |
|
53 |
{ |
|
54 |
var testMetrics = result.Metrics; |
|
55 |
Console.WriteLine($"*************************************************************************************************************"); |
|
56 |
Console.WriteLine($"* Metrics for Multi-class Classification model - Model #{result.Fold} "); |
|
57 |
Console.WriteLine($"*------------------------------------------------------------------------------------------------------------"); |
|
58 |
Console.WriteLine($"* MicroAccuracy: {testMetrics.MicroAccuracy:0.###}"); |
|
59 |
Console.WriteLine($"* MacroAccuracy: {testMetrics.MacroAccuracy:0.###}"); |
|
60 |
Console.WriteLine($"* LogLoss: {testMetrics.LogLoss:#.###}"); |
|
61 |
Console.WriteLine($"* LogLossReduction: {testMetrics.LogLossReduction:#.###}"); |
|
62 |
Console.WriteLine($"* Confusion Matrix: {testMetrics.ConfusionMatrix.GetFormattedConfusionTable()}"); |
|
63 |
Console.WriteLine($"*************************************************************************************************************"); |
|
64 |
} |
|
65 |
this._trainedModel = cvResults.OrderByDescending(fold => fold.Metrics.MicroAccuracy).Select(fold => fold.Model).First(); |
|
66 |
Console.WriteLine($"Selected the model #{cvResults.OrderByDescending(fold => fold.Metrics.MicroAccuracy).Select(fold => fold.Fold).First()} as the best."); |
|
49 |
this._trainedModel = pipeline.Fit(this._trainingDataView); |
|
67 | 50 |
this._predictionEngine = _mlContext.Model.CreatePredictionEngine<ModelInput, ModelOutput>(this._trainedModel); |
68 | 51 |
|
69 | 52 |
} |
70 | 53 |
|
71 | 54 |
public string Predict(ModelInput input) |
72 | 55 |
{ |
73 |
return this._predictionEngine.Predict(input).PredictedLabel;
|
|
56 |
return this._predictionEngine.Predict(input).Prediction;
|
|
74 | 57 |
} |
75 | 58 |
|
76 | 59 |
public void Evaluate(IEnumerable<ModelInput> modelInputs) |
77 | 60 |
{ |
78 | 61 |
var testDataView = this._mlContext.Data.LoadFromEnumerable(modelInputs); |
79 |
var data = _trainedModel.Transform(testDataView); |
|
80 |
var testMetrics = _mlContext.MulticlassClassification.Evaluate(data); |
|
62 |
var testMetrics = _mlContext.MulticlassClassification.Evaluate(_trainedModel.Transform(testDataView)); |
|
81 | 63 |
|
82 | 64 |
Console.WriteLine($"*************************************************************************************************************"); |
83 | 65 |
Console.WriteLine($"* Metrics for Multi-class Classification model - Test Data "); |
... | ... | |
86 | 68 |
Console.WriteLine($"* MacroAccuracy: {testMetrics.MacroAccuracy:0.###}"); |
87 | 69 |
Console.WriteLine($"* LogLoss: {testMetrics.LogLoss:#.###}"); |
88 | 70 |
Console.WriteLine($"* LogLossReduction: {testMetrics.LogLossReduction:#.###}"); |
89 |
Console.WriteLine($"* Confusion Matrix: {testMetrics.ConfusionMatrix.GetFormattedConfusionTable()}"); |
|
90 | 71 |
Console.WriteLine($"*************************************************************************************************************"); |
91 | 72 |
} |
92 | 73 |
} |
Server/ServerApp/Predictor/PredictionController.cs | ||
---|---|---|
4 | 4 |
|
5 | 5 |
using System; |
6 | 6 |
using System.Collections.Generic; |
7 |
using System.IO; |
|
8 |
using Microsoft.ML; |
|
7 | 9 |
using ServerApp.Connection.XMLProtocolHandler; |
8 |
using ServerApp.Parser.Parsers; |
|
9 |
using Newtonsoft.Json; |
|
10 |
using ServerApp.WeatherPredictionParser; |
|
11 | 10 |
using ServerApp.Parser.OutputInfo; |
11 |
using ServerApp.Parser.Parsers; |
|
12 | 12 |
|
13 | 13 |
namespace ServerApp.Predictor |
14 | 14 |
{ |
15 | 15 |
/// <summary> |
16 | 16 |
/// Implentation of the <c>IPredicitionController</c> interface. |
17 | 17 |
/// </summary> |
18 |
public class PredictionController : IPredictionController
|
|
18 |
class PredictionController : IPredictionController |
|
19 | 19 |
{ |
20 | 20 |
/// <summary> |
21 |
/// Configuration of the <c>Predictor</c>
|
|
21 |
/// A dictionary for storing trained predictors.
|
|
22 | 22 |
/// </summary> |
23 |
private PredictorConfiguration Configuration;
|
|
23 |
private Dictionary<string, int> buildingsToAreas;
|
|
24 | 24 |
|
25 |
private List<IPredictor> Predictors;
|
|
25 |
private List<IPredictor> predictors;
|
|
26 | 26 |
|
27 | 27 |
/// <summary> |
28 | 28 |
/// A reference to a data parser. |
29 | 29 |
/// </summary> |
30 |
private IDataParser DataParser;
|
|
30 |
private IDataParser dataParser;
|
|
31 | 31 |
|
32 | 32 |
/// <summary> |
33 | 33 |
/// A feature extractor instance. |
34 | 34 |
/// </summary> |
35 |
private FeatureExtractor FeatureExtractor; |
|
36 |
|
|
37 |
/// <summary> |
|
38 |
/// A weather prediction parser service |
|
39 |
/// </summary> |
|
40 |
private IJsonParser weatherService; |
|
35 |
private FeatureExtractor featureExtractor; |
|
41 | 36 |
|
42 | 37 |
/// <summary> |
43 | 38 |
/// Instantiates new prediction controller. |
44 | 39 |
/// </summary> |
45 | 40 |
/// <param name="dataParser">A data parser used to get training data.</param> |
46 |
public PredictionController(IJsonParser weatherService, IDataParser dataParser, string pathToConfig = null)
|
|
41 |
public PredictionController(IDataParser dataParser)
|
|
47 | 42 |
{ |
48 |
this.weatherService = weatherService; |
|
49 |
// load config or get the default one |
|
50 |
if (pathToConfig is null) |
|
51 |
{ |
|
52 |
pathToConfig = PredictorConfiguration.DEFAULT_CONFIG_PATH; |
|
53 |
} |
|
54 |
try |
|
55 |
{ |
|
56 |
string json = System.IO.File.ReadAllText(pathToConfig); |
|
57 |
this.Configuration = JsonConvert.DeserializeObject<PredictorConfiguration>(json); |
|
58 |
} catch (System.IO.IOException e) |
|
59 |
{ |
|
60 |
Console.WriteLine(e.ToString()); |
|
61 |
this.Configuration = PredictorConfiguration.GetDefaultConfig(); |
|
62 |
} |
|
63 |
|
|
64 |
this.DataParser = dataParser; |
|
65 |
this.Predictors = new List<IPredictor>(); |
|
66 |
this.FeatureExtractor = new FeatureExtractor(this.DataParser, this.Configuration); |
|
67 |
|
|
68 |
for (int i = 0; i < this.Configuration.PredictorCount; i++) |
|
43 |
this.dataParser = dataParser; |
|
44 |
this.predictors = new List<IPredictor>(); |
|
45 |
this.buildingsToAreas = new Dictionary<string, int>(); |
|
46 |
this.featureExtractor = new FeatureExtractor(dataParser, buildingsToAreas); |
|
47 |
|
|
48 |
// fill predictors with all available locationKeys |
|
49 |
// TODO Currently all locations use the same predictor. Try dividing locations into subareas with separate predictors. |
|
50 |
var locationKeys = TagInfo.buildings; |
|
51 |
foreach (string key in locationKeys) |
|
69 | 52 |
{ |
70 |
Predictors.Add(new NaiveBayesClassifier());
|
|
53 |
buildingsToAreas.Add(key, 0);
|
|
71 | 54 |
} |
72 |
PredictorConfiguration.SaveConfig(PredictorConfiguration.DEFAULT_CONFIG_PATH, Configuration); |
|
55 |
IPredictor predictor = new NaiveBayesClassifier(); |
|
56 |
predictors.Add(predictor); |
|
73 | 57 |
} |
74 | 58 |
public List<string> GetPredictors() |
75 | 59 |
{ |
76 |
return new List<string>(this.Configuration.BuildingsToAreas.Keys);
|
|
60 |
return new List<string>(buildingsToAreas.Keys);
|
|
77 | 61 |
} |
78 | 62 |
|
79 | 63 |
public void Load(string locationKey = null, string path = null) |
... | ... | |
90 | 74 |
|
91 | 75 |
public Response Predict(Request request) |
92 | 76 |
{ |
93 |
DateTime start = new DateTime(year: request.start.year, month: request.start.month, day: request.start.day, hour: request.start.hour, minute: 0, second: 0); |
|
94 |
List<Prediction> predictions = new List<Prediction>(); |
|
95 |
if (request.useEndDate) |
|
96 |
{ |
|
97 |
DateTime end = new DateTime(year: request.end.year, month: request.end.month, day: request.end.day, hour: request.end.hour, minute: 0, second: 0); |
|
98 |
DateTime current = start; |
|
99 |
while (current < end) |
|
100 |
{ |
|
101 |
while (current.Hour < Date.MAX_HOUR) |
|
102 |
{ |
|
103 |
var prediction = PredictSingle(request, current); |
|
104 |
predictions.Add(prediction); |
|
105 |
current = current.AddHours(this.Configuration.TimeResolution); |
|
106 |
} |
|
107 |
current = current.AddHours(23 - current.Hour + Date.MIN_HOUR); |
|
108 |
} |
|
109 |
} else |
|
110 |
{ |
|
111 |
if (request.useWeather) |
|
112 |
{ |
|
113 |
predictions.Add(PredictSingle(request, start)); |
|
114 |
} |
|
115 |
} |
|
116 |
var response = new Response(); |
|
117 |
response.hoursPerSegment = Configuration.TimeResolution; |
|
118 |
response.predicitons = predictions.ToArray(); |
|
119 |
return response; |
|
77 |
throw new NotImplementedException(); |
|
120 | 78 |
} |
121 | 79 |
|
122 |
private Prediction PredictSingle(Request request, DateTime current) |
|
123 |
{ |
|
124 |
double[] predictedValues = new double[this.Configuration.BuildingsToAreas.Count]; |
|
125 |
string[] predictedLabels = new string[this.Predictors.Count]; |
|
126 |
for (int i = 0; i < this.Predictors.Count; i++) |
|
127 |
{ |
|
128 |
if (request.useWeather) |
|
129 |
{ |
|
130 |
predictedLabels[i] = this.Predictors[i].Predict(new ModelInput |
|
131 |
{ |
|
132 |
Rain = (float)request.rain, |
|
133 |
Temp = (float)request.temperature, |
|
134 |
Wind = (float)request.wind, |
|
135 |
Hour = current.Hour, |
|
136 |
Time = current |
|
137 |
}); |
|
138 |
} |
|
139 |
else |
|
140 |
{ |
|
141 |
List<WeatherInfo> weatherInfos = weatherService.GetPredictionForTime(from: current, to: current.AddHours(this.Configuration.TimeResolution)); |
|
142 |
predictedLabels[i] = this.Predictors[i].Predict(new ModelInput |
|
143 |
{ |
|
144 |
Rain = weatherInfos[0].rain, |
|
145 |
Temp = (float)weatherInfos[0].temp, |
|
146 |
Wind = (float)weatherInfos[0].wind, |
|
147 |
Hour = current.Hour, |
|
148 |
Time = current |
|
149 |
}); |
|
150 |
} |
|
151 |
} |
|
152 |
for (int i = 0; i < predictedValues.Length; i++) |
|
153 |
{ |
|
154 |
predictedValues[i] = this.FeatureExtractor.LabelToRatio(predictedLabels[this.Configuration.BuildingsToAreas[TagInfo.buildings[i]]]) * 100; |
|
155 |
} |
|
156 |
|
|
157 |
Prediction prediction = new Prediction(); |
|
158 |
prediction.dateTime = new Date |
|
159 |
{ |
|
160 |
year = current.Year, |
|
161 |
month = current.Month, |
|
162 |
day = current.Day, |
|
163 |
hour = current.Hour |
|
164 |
}; |
|
165 |
prediction.predictions = predictedValues; |
|
166 |
return prediction; |
|
167 |
} |
|
168 | 80 |
|
169 | 81 |
public void Train(string locationKey = null) |
170 | 82 |
{ |
171 | 83 |
if (locationKey is null) |
172 | 84 |
// train all predictors |
173 | 85 |
{ |
174 |
DataParser.Parse(DateTime.MinValue, DateTime.MaxValue, this.Configuration.TimeResolution, wholeDay: false);
|
|
175 |
for (int i = 0; i < this.Predictors.Count; i++)
|
|
86 |
// TODO A single predictor is used for all areas, so training is done only once now.
|
|
87 |
for (int i = 0; i < this.predictors.Count; i++)
|
|
176 | 88 |
{ |
177 | 89 |
// train on all available data |
178 |
List<ModelInput> data = FeatureExtractor.PrepareTrainingInput(i); |
|
179 |
Console.WriteLine("Training predictor with {0} samples.", data.Count); |
|
180 |
this.Predictors[i].Fit(data); |
|
90 |
// TODO the train/test split is used just temporarily for demonstration. |
|
91 |
List<ModelInput> data = featureExtractor.PrepareTrainingInput(i, DateTime.MinValue, DateTime.MaxValue); |
|
92 |
List<ModelInput> trainingData = data.GetRange(index: 0, count: 500); |
|
93 |
List<ModelInput> testData = data.GetRange(index: 500, count: 94); |
|
94 |
Console.WriteLine("Training predictor with {0} samples.", trainingData.Count); |
|
95 |
this.predictors[i].Fit(trainingData); |
|
96 |
|
|
97 |
Console.WriteLine("Evaluating predictor with {0} samples.", testData.Count); |
|
98 |
this.predictors[i].Evaluate(testData); |
|
181 | 99 |
} |
182 |
} |
|
183 |
else |
|
100 |
} else |
|
184 | 101 |
// train specified predictor only |
185 | 102 |
{ |
186 | 103 |
throw new NotImplementedException(); |
Server/ServerApp/Predictor/PredictorConfiguration.cs | ||
---|---|---|
1 |
// |
|
2 |
// Author: Roman Kalivoda |
|
3 |
// |
|
4 |
|
|
5 |
using System.Collections.Generic; |
|
6 |
using System; |
|
7 |
using System.IO; |
|
8 |
using Newtonsoft.Json; |
|
9 |
|
|
10 |
namespace ServerApp.Predictor |
|
11 |
{ |
|
12 |
class PredictorConfiguration |
|
13 |
{ |
|
14 |
public static readonly string DEFAULT_CONFIG_PATH = Path.GetFullPath(Path.GetDirectoryName(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile) + @"\Predictor.config"); |
|
15 |
|
|
16 |
public int TimeResolution { get; set; } |
|
17 |
|
|
18 |
public Dictionary<string, int> BuildingsToAreas { get; set; } |
|
19 |
|
|
20 |
public int PredictorCount { get; set; } |
|
21 |
|
|
22 |
public static PredictorConfiguration LoadConfig(string filename) |
|
23 |
{ |
|
24 |
string json = System.IO.File.ReadAllText(filename); |
|
25 |
PredictorConfiguration configuration = JsonConvert.DeserializeObject<PredictorConfiguration>(json); |
|
26 |
return configuration; |
|
27 |
} |
|
28 |
|
|
29 |
public static void SaveConfig(string filename, PredictorConfiguration configuration) |
|
30 |
{ |
|
31 |
string json = JsonConvert.SerializeObject(configuration); |
|
32 |
System.IO.File.WriteAllText(filename, json); |
|
33 |
} |
|
34 |
|
|
35 |
public static PredictorConfiguration GetDefaultConfig() |
|
36 |
{ |
|
37 |
Dictionary<string, int> dict = new Dictionary<string, int>(); |
|
38 |
var locationKeys = Parser.Parsers.TagInfo.buildings; |
|
39 |
foreach (string key in locationKeys) |
|
40 |
{ |
|
41 |
dict.Add(key, 0); |
|
42 |
} |
|
43 |
|
|
44 |
return new PredictorConfiguration |
|
45 |
{ |
|
46 |
TimeResolution = 3, |
|
47 |
PredictorCount = 3, |
|
48 |
BuildingsToAreas = new Dictionary<string, int> |
|
49 |
{ |
|
50 |
{ "FST+FEK", 0 }, |
|
51 |
{ "FDU", 0 }, |
|
52 |
{ "FAV", 0 }, |
|
53 |
{ "FEL", 0 }, |
|
54 |
{ "REK", 0 }, |
|
55 |
{ "MENZA", 0 }, |
|
56 |
{ "LIB", 0 }, |
|
57 |
{ "CIV", 0 }, |
|
58 |
{ "UNI14", 0 }, |
|
59 |
{ "DOM", 1 }, |
|
60 |
{ "HUS", 1 }, |
|
61 |
{ "CHOD", 1 }, |
|
62 |
{ "JUNG", 1 }, |
|
63 |
{ "KLAT", 1 }, |
|
64 |
{ "KOLL", 1 }, |
|
65 |
{ "RIEG", 1 }, |
|
66 |
{ "SADY", 1 }, |
|
67 |
{ "SED+VEL", 1 }, |
|
68 |
{ "TES", 1 }, |
|
69 |
{ "TYL", 1 }, |
|
70 |
{ "KARMA", 2 }, |
|
71 |
{ "KBORY", 2 }, |
|
72 |
{ "KLOCH", 2 }, |
|
73 |
{ "KKLAT", 2 } |
|
74 |
} |
|
75 |
}; |
|
76 |
} |
|
77 |
} |
|
78 |
} |
Server/ServerApp/Program.cs | ||
---|---|---|
1 | 1 |
using ServerApp.Connection; |
2 | 2 |
using ServerApp.Connection.XMLProtocolHandler; |
3 | 3 |
using ServerApp.DataDownload; |
4 |
using ServerApp.Parser.OutputInfo; |
|
5 | 4 |
using ServerApp.Parser.Parsers; |
6 | 5 |
using ServerApp.Predictor; |
7 | 6 |
using ServerApp.User; |
... | ... | |
137 | 136 |
JsonParser jsonP = new JsonParser(null); |
138 | 137 |
jsonP.ParsePrediction(); |
139 | 138 |
|
140 |
var res = jsonP.GetPredictionForTime(jsonP.Predictions[5].startTime, jsonP.Predictions[20].startTime); |
|
141 |
Console.WriteLine("from " + jsonP.Predictions[5].startTime); |
|
142 |
Console.WriteLine("end " + jsonP.Predictions[20].startTime); |
|
143 |
foreach (WeatherInfo w in res) |
|
144 |
Console.WriteLine(w.ToString()); |
|
145 |
|
|
146 |
|
|
147 | 139 |
// TODO nastavit čas |
148 | 140 |
IDataParser p = new DataParser(dd); |
149 |
IPredictionController predictionController = new PredictionController(jsonP, p);
|
|
141 |
IPredictionController predictionController = new PredictionController(p); |
|
150 | 142 |
predictionController.Train(); |
151 | 143 |
//var results = predictionController.Predict() |
152 | 144 |
|
Server/ServerApp/ServerApp.csproj | ||
---|---|---|
179 | 179 |
<Compile Include="Parser\Parsers\DataParser.cs" /> |
180 | 180 |
<Compile Include="Parser\Parsers\IDataParser.cs" /> |
181 | 181 |
<Compile Include="Parser\Parsers\JisParser.cs" /> |
182 |
<Compile Include="Predictor\PredictorConfiguration.cs" /> |
|
183 | 182 |
<Compile Include="Predictor\FeatureExtractor.cs" /> |
184 | 183 |
<Compile Include="Predictor\IPredictionController.cs" /> |
185 | 184 |
<Compile Include="Predictor\PredictionController.cs" /> |
Server/ServerApp/WeatherPredictionParser/IJsonParser.cs | ||
---|---|---|
3 | 3 |
// |
4 | 4 |
|
5 | 5 |
using ServerApp.Parser.OutputInfo; |
6 |
using System; |
|
7 | 6 |
using System.Collections.Generic; |
8 | 7 |
|
9 | 8 |
namespace ServerApp.WeatherPredictionParser |
... | ... | |
11 | 10 |
/// <summary> |
12 | 11 |
/// Abstract class that every Json parser should inherit from |
13 | 12 |
/// </summary> |
14 |
public abstract class IJsonParser
|
|
13 |
abstract class IJsonParser |
|
15 | 14 |
{ |
16 | 15 |
|
17 | 16 |
/// <summary> Current weather </summary> |
18 | 17 |
WeatherInfo current; |
19 |
public WeatherInfo Current { get => current; set => current = value; }
|
|
18 |
public WeatherInfo Current { get => current; } |
|
20 | 19 |
|
21 | 20 |
/// <summary> Prediction for today, tommorrow and day after tommorrow </summary> |
22 | 21 |
List<WeatherInfo> predictions; |
... | ... | |
28 | 27 |
/// </summary> |
29 | 28 |
abstract public void ParsePrediction(); |
30 | 29 |
|
31 |
/// <summary> |
|
32 |
/// Get predictions from Predictions that are within specified time span |
|
33 |
/// </summary> |
|
34 |
/// <param name="from">DateTime from</param> |
|
35 |
/// <param name="to">DateTime to</param> |
|
36 |
/// <returns>List of predictions that fit specified criteria</returns> |
|
37 |
abstract public List<WeatherInfo> GetPredictionForTime(DateTime from, DateTime to); |
|
38 |
|
|
39 | 30 |
} |
40 | 31 |
|
41 | 32 |
} |
Server/ServerApp/WeatherPredictionParser/JsonParser.cs | ||
---|---|---|
20 | 20 |
/// <author>A. Konig</author> |
21 | 21 |
class JsonParser : IJsonParser |
22 | 22 |
{ |
23 |
/// <summary> Current weather </summary> |
|
24 |
WeatherInfo current; |
|
25 |
public new WeatherInfo Current { get => current; } |
|
26 |
/// <summary> Prediction for today, tommorrow and day after tommorrow </summary> |
|
27 |
List<WeatherInfo> predictions; |
|
28 |
public new List<WeatherInfo> Predictions { get => predictions; set => predictions = value; } |
|
29 |
|
|
23 | 30 |
/// <summary> Data loader </summary> |
24 | 31 |
DataDownloader loader; |
25 | 32 |
/// <summary> Currently parsed day </summary> |
... | ... | |
39 | 46 |
this.loader = loader; |
40 | 47 |
} |
41 | 48 |
|
42 |
/// <summary> |
|
43 |
/// Get predictions from Predictions that are within specified time span |
|
44 |
/// From-to including |
|
45 |
/// If from == null then all until to |
|
46 |
/// If to == null then all starting from from |
|
47 |
/// </summary> |
|
48 |
/// <param name="from">DateTime from</param> |
|
49 |
/// <param name="to">DateTime to</param> |
|
50 |
/// <returns>List of predictions that fit specified criteria or null if incorrect input</returns> |
|
51 |
public override List<WeatherInfo> GetPredictionForTime(DateTime from, DateTime to) |
|
52 |
{ |
|
53 |
if (Predictions == null) |
|
54 |
return null; |
|
55 |
|
|
56 |
List<WeatherInfo> res = new List<WeatherInfo>(); |
|
57 |
|
|
58 |
if (from == null) |
|
59 |
from = Predictions[0].startTime; |
|
60 |
|
|
61 |
if (to == null) |
|
62 |
from = Predictions[Predictions.Count].startTime; |
|
63 |
|
|
64 |
if (from > to) |
|
65 |
return null; |
|
66 |
|
|
67 |
foreach (WeatherInfo pred in Predictions) |
|
68 |
{ |
|
69 |
int hour = pred.startTime.Hour + pred.intervalLength; |
|
70 |
Console.WriteLine(pred.intervalLength); |
|
71 |
bool addDay = false; |
|
72 |
if (hour >= 24) |
|
73 |
{ |
|
74 |
hour -= 24; |
|
75 |
addDay = true; |
|
76 |
} |
|
77 |
DateTime endTime = new DateTime(pred.startTime.Year, pred.startTime.Month, pred.startTime.Day, hour, pred.startTime.Minute, pred.startTime.Second); |
|
78 |
if (addDay) |
|
79 |
endTime = endTime.AddDays(1); |
|
80 |
|
|
81 |
// if both end and start not outside of interval |
|
82 |
if (!((pred.startTime < from && endTime <= from) || (pred.startTime > to && endTime >= to))) |
|
83 |
res.Add(pred); |
|
84 |
} |
|
85 |
|
|
86 |
return res; |
|
87 |
} |
|
88 |
|
|
89 | 49 |
/// <summary> |
90 | 50 |
/// Parse weather prediction |
91 | 51 |
/// Results is in attributes current for current weather and pred for weather prediction for today, tommorrow and day after tommorrow |
... | ... | |
99 | 59 |
DateTime now = DateTime.Now; |
100 | 60 |
Console.WriteLine(File.Exists(file)); |
101 | 61 |
|
102 |
Current = new WeatherInfo();
|
|
103 |
Predictions = new List<WeatherInfo>();
|
|
62 |
current = new WeatherInfo();
|
|
63 |
predictions = new List<WeatherInfo>();
|
|
104 | 64 |
|
105 | 65 |
if (!File.Exists(file)) |
106 | 66 |
return; |
... | ... | |
124 | 84 |
case "current_condition": |
125 | 85 |
{ |
126 | 86 |
ArrayEnumerator currentWeather = weatherP.Current.Value.EnumerateArray(); |
127 |
Current = ParseCurrentWeather(currentWeather);
|
|
87 |
current = ParseCurrentWeather(currentWeather);
|
|
128 | 88 |
|
129 | 89 |
break; |
130 | 90 |
} |
... | ... | |
150 | 110 |
/// </summary> |
151 | 111 |
private void TestConsoleOutput() |
152 | 112 |
{ |
153 |
Console.WriteLine(Current);
|
|
154 |
foreach (WeatherInfo w in Predictions)
|
|
113 |
Console.WriteLine(current);
|
|
114 |
foreach (WeatherInfo w in predictions)
|
|
155 | 115 |
Console.WriteLine(w); |
156 | 116 |
} |
157 | 117 |
|
... | ... | |
177 | 137 |
private void EncompassSunRiseSetTimes() |
178 | 138 |
{ |
179 | 139 |
// change current weather |
180 |
if ((Current.startTime.TimeOfDay > sunsetTime.TimeOfDay) || (Current.startTime.TimeOfDay < sunriseTime.TimeOfDay))
|
|
181 |
Current.condition = WeatherConditions.Dark;
|
|
140 |
if ((current.startTime.TimeOfDay > sunsetTime.TimeOfDay) || (current.startTime.TimeOfDay < sunriseTime.TimeOfDay))
|
|
141 |
current.condition = WeatherConditions.Dark;
|
|
182 | 142 |
|
183 | 143 |
// change prediction |
184 |
for (int i = 0; i < Predictions.Count - 1; i++)
|
|
144 |
for (int i = 0; i < predictions.Count - 1; i++)
|
|
185 | 145 |
{ |
186 |
WeatherInfo w = Predictions[i];
|
|
187 |
WeatherInfo wNext = Predictions[i + 1];
|
|
146 |
WeatherInfo w = predictions[i];
|
|
147 |
WeatherInfo wNext = predictions[i + 1];
|
|
188 | 148 |
|
189 | 149 |
// if wNext time < than w time then it is prediction from the next day -> add 24 to correctly calculate timespan |
190 | 150 |
int timespan = wNext.startTime.Hour - w.startTime.Hour; |
... | ... | |
218 | 178 |
} |
219 | 179 |
|
220 | 180 |
// last prediction |
221 |
WeatherInfo wLast = Predictions[Predictions.Count - 1];
|
|
181 |
WeatherInfo wLast = predictions[predictions.Count - 1];
|
|
222 | 182 |
TimeSpan endTimeW = new TimeSpan(24, 0, 0); |
223 |
int timespanLast = 24 - wLast.startTime.Hour;
|
|
183 |
int timespanLast = endTimeW.Hours - wLast.startTime.Hour;
|
|
224 | 184 |
wLast.intervalLength = timespanLast; |
225 | 185 |
|
226 | 186 |
// if start under sunset |
... | ... | |
378 | 338 |
} |
379 | 339 |
|
380 | 340 |
// Console.WriteLine(weather.ToString()); |
381 |
Predictions.Add(weather);
|
|
341 |
predictions.Add(weather);
|
|
382 | 342 |
|
383 | 343 |
} |
384 | 344 |
|
... | ... | |
441 | 401 |
return res; |
442 | 402 |
} |
443 | 403 |
|
444 |
|
|
445 | 404 |
} |
446 | 405 |
} |
Server/ServerAppTests/Predictor/PredictionControllerTests.cs | ||
---|---|---|
1 |
// |
|
2 |
// Author: Roman Kalivoda |
|
3 |
// |
|
4 |
using Microsoft.VisualStudio.TestTools.UnitTesting; |
|
5 |
using ServerApp.Predictor; |
|
6 |
using System; |
|
7 |
using System.Collections.Generic; |
|
8 |
using System.Linq; |
|
9 |
using System.Text; |
|
10 |
using System.Threading.Tasks; |
|
11 |
|
|
12 |
namespace ServerApp.Predictor.Tests |
|
13 |
{ |
|
14 |
[TestClass()] |
|
15 |
public class PredictionControllerTests |
|
16 |
{ |
|
17 |
[TestInitialize] |
|
18 |
public void SetUp() |
|
19 |
{ |
|
20 |
|
|
21 |
} |
|
22 |
|
|
23 |
[TestMethod()] |
|
24 |
public void TrainTest() |
|
25 |
{ |
|
26 |
throw new NotImplementedException(); |
|
27 |
} |
|
28 |
} |
|
29 |
} |
Server/ServerAppTests/Properties/AssemblyInfo.cs | ||
---|---|---|
1 |
using System.Reflection; |
|
2 |
using System.Runtime.CompilerServices; |
|
3 |
using System.Runtime.InteropServices; |
|
4 |
|
|
5 |
// General Information about an assembly is controlled through the following |
|
6 |
// set of attributes. Change these attribute values to modify the information |
|
7 |
// associated with an assembly. |
|
8 |
[assembly: AssemblyTitle("ServerAppTests")] |
|
9 |
[assembly: AssemblyDescription("")] |
|
10 |
[assembly: AssemblyConfiguration("")] |
|
11 |
[assembly: AssemblyCompany("")] |
|
12 |
[assembly: AssemblyProduct("ServerAppTests")] |
|
13 |
[assembly: AssemblyCopyright("Copyright © 2021")] |
|
14 |
[assembly: AssemblyTrademark("")] |
|
15 |
[assembly: AssemblyCulture("")] |
|
16 |
|
|
17 |
// Setting ComVisible to false makes the types in this assembly not visible |
|
18 |
// to COM components. If you need to access a type in this assembly from |
|
19 |
// COM, set the ComVisible attribute to true on that type. |
|
20 |
[assembly: ComVisible(false)] |
|
21 |
|
|
22 |
// The following GUID is for the ID of the typelib if this project is exposed to COM |
|
23 |
[assembly: Guid("e068474b-98fb-431d-84eb-000aa36d0fc5")] |
|
24 |
|
|
25 |
// Version information for an assembly consists of the following four values: |
|
26 |
// |
|
27 |
// Major Version |
|
28 |
// Minor Version |
|
29 |
// Build Number |
|
30 |
// Revision |
|
31 |
// |
|
32 |
// You can specify all the values or you can default the Build and Revision Numbers |
|
33 |
// by using the '*' as shown below: |
|
34 |
// [assembly: AssemblyVersion("1.0.*")] |
|
35 |
[assembly: AssemblyVersion("1.0.0.0")] |
|
36 |
[assembly: AssemblyFileVersion("1.0.0.0")] |
Server/ServerAppTests/ServerAppTests.csproj | ||
---|---|---|
1 |
<?xml version="1.0" encoding="utf-8"?> |
|
2 |
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
|
3 |
<Import Project="..\packages\MSTest.TestAdapter.2.1.1\build\net45\MSTest.TestAdapter.props" Condition="Exists('..\packages\MSTest.TestAdapter.2.1.1\build\net45\MSTest.TestAdapter.props')" /> |
|
4 |
<PropertyGroup> |
|
5 |
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> |
|
6 |
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> |
|
7 |
<ProjectGuid>{E068474B-98FB-431D-84EB-000AA36D0FC5}</ProjectGuid> |
|
8 |
<OutputType>Library</OutputType> |
|
9 |
<AppDesignerFolder>Properties</AppDesignerFolder> |
|
10 |
<RootNamespace>ServerAppTests</RootNamespace> |
|
11 |
<AssemblyName>ServerAppTests</AssemblyName> |
|
12 |
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion> |
|
13 |
<FileAlignment>512</FileAlignment> |
|
14 |
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> |
|
15 |
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion> |
|
16 |
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath> |
|
17 |
<ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages</ReferencePath> |
|
18 |
<IsCodedUITest>False</IsCodedUITest> |
|
19 |
<TestProjectType>UnitTest</TestProjectType> |
|
20 |
<TargetFrameworkProfile /> |
|
21 |
<NuGetPackageImportStamp> |
|
22 |
</NuGetPackageImportStamp> |
|
23 |
</PropertyGroup> |
|
24 |
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> |
|
25 |
<DebugSymbols>true</DebugSymbols> |
|
26 |
<DebugType>full</DebugType> |
|
27 |
<Optimize>false</Optimize> |
|
28 |
<OutputPath>bin\Debug\</OutputPath> |
|
29 |
<DefineConstants>DEBUG;TRACE</DefineConstants> |
|
30 |
<ErrorReport>prompt</ErrorReport> |
|
31 |
<WarningLevel>4</WarningLevel> |
|
32 |
</PropertyGroup> |
|
33 |
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> |
|
34 |
<DebugType>pdbonly</DebugType> |
|
35 |
<Optimize>true</Optimize> |
|
36 |
<OutputPath>bin\Release\</OutputPath> |
|
37 |
<DefineConstants>TRACE</DefineConstants> |
|
38 |
<ErrorReport>prompt</ErrorReport> |
|
39 |
<WarningLevel>4</WarningLevel> |
|
40 |
</PropertyGroup> |
|
41 |
<ItemGroup> |
|
42 |
<Reference Include="Castle.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL"> |
|
43 |
<HintPath>..\packages\Castle.Core.4.4.0\lib\net45\Castle.Core.dll</HintPath> |
|
44 |
</Reference> |
|
45 |
<Reference Include="Microsoft.VisualStudio.TestPlatform.TestFramework, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> |
|
46 |
<HintPath>..\packages\MSTest.TestFramework.2.1.1\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.dll</HintPath> |
|
47 |
</Reference> |
|
48 |
<Reference Include="Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> |
|
49 |
<HintPath>..\packages\MSTest.TestFramework.2.1.1\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll</HintPath> |
|
50 |
</Reference> |
|
51 |
<Reference Include="Moq, Version=4.16.0.0, Culture=neutral, PublicKeyToken=69f491c39445e920, processorArchitecture=MSIL"> |
|
52 |
<HintPath>..\packages\Moq.4.16.1\lib\net45\Moq.dll</HintPath> |
|
53 |
</Reference> |
|
54 |
<Reference Include="System" /> |
|
55 |
<Reference Include="System.Configuration" /> |
|
56 |
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=4.0.4.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> |
|
57 |
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.4.5.3\lib\net461\System.Runtime.CompilerServices.Unsafe.dll</HintPath> |
|
58 |
</Reference> |
|
59 |
<Reference Include="System.Threading.Tasks.Extensions, Version=4.2.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL"> |
|
60 |
<HintPath>..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll</HintPath> |
|
61 |
</Reference> |
|
62 |
</ItemGroup> |
|
63 |
<Choose> |
|
64 |
<When Condition="('$(VisualStudioVersion)' == '10.0' or '$(VisualStudioVersion)' == '') and '$(TargetFrameworkVersion)' == 'v3.5'"> |
|
65 |
<ItemGroup> |
|
66 |
<Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" /> |
|
67 |
</ItemGroup> |
|
68 |
</When> |
|
69 |
<Otherwise /> |
|
70 |
</Choose> |
|
71 |
<ItemGroup> |
|
72 |
<Compile Include="Predictor\PredictionControllerTests.cs" /> |
|
73 |
<Compile Include="Properties\AssemblyInfo.cs" /> |
|
74 |
</ItemGroup> |
|
75 |
<ItemGroup> |
|
76 |
<None Include="app.config" /> |
|
77 |
<None Include="packages.config" /> |
|
78 |
</ItemGroup> |
|
79 |
<ItemGroup> |
|
80 |
<ProjectReference Include="..\ServerApp\ServerApp.csproj"> |
|
81 |
<Project>{18FCFB20-B860-4147-8E7C-8A0DD84C55D4}</Project> |
|
82 |
<Name>ServerApp</Name> |
|
83 |
</ProjectReference> |
|
84 |
</ItemGroup> |
|
85 |
<Choose> |
|
86 |
<When Condition="'$(VisualStudioVersion)' == '10.0' And '$(IsCodedUITest)' == 'True'"> |
|
87 |
<ItemGroup> |
|
88 |
<Reference Include="Microsoft.VisualStudio.QualityTools.CodedUITestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> |
|
89 |
<Private>False</Private> |
|
90 |
</Reference> |
|
91 |
<Reference Include="Microsoft.VisualStudio.TestTools.UITest.Common, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> |
|
92 |
<Private>False</Private> |
|
93 |
</Reference> |
|
94 |
<Reference Include="Microsoft.VisualStudio.TestTools.UITest.Extension, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> |
|
95 |
<Private>False</Private> |
|
96 |
</Reference> |
|
97 |
<Reference Include="Microsoft.VisualStudio.TestTools.UITesting, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> |
|
98 |
<Private>False</Private> |
|
99 |
</Reference> |
|
100 |
</ItemGroup> |
|
101 |
</When> |
|
102 |
</Choose> |
|
103 |
<Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" /> |
|
104 |
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> |
|
105 |
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild"> |
|
106 |
<PropertyGroup> |
|
107 |
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText> |
|
108 |
</PropertyGroup> |
|
109 |
<Error Condition="!Exists('..\packages\MSTest.TestAdapter.2.1.1\build\net45\MSTest.TestAdapter.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\MSTest.TestAdapter.2.1.1\build\net45\MSTest.TestAdapter.props'))" /> |
|
110 |
<Error Condition="!Exists('..\packages\MSTest.TestAdapter.2.1.1\build\net45\MSTest.TestAdapter.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\MSTest.TestAdapter.2.1.1\build\net45\MSTest.TestAdapter.targets'))" /> |
|
111 |
</Target> |
|
112 |
<Import Project="..\packages\MSTest.TestAdapter.2.1.1\build\net45\MSTest.TestAdapter.targets" Condition="Exists('..\packages\MSTest.TestAdapter.2.1.1\build\net45\MSTest.TestAdapter.targets')" /> |
|
113 |
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. |
|
114 |
Other similar extension points exist, see Microsoft.Common.targets. |
|
115 |
<Target Name="BeforeBuild"> |
|
116 |
</Target> |
|
117 |
<Target Name="AfterBuild"> |
|
118 |
</Target> |
|
119 |
--> |
|
120 |
</Project> |
Server/ServerAppTests/app.config | ||
---|---|---|
1 |
<?xml version="1.0" encoding="utf-8"?> |
|
2 |
<configuration> |
|
3 |
<runtime> |
|
4 |
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> |
|
5 |
<dependentAssembly> |
|
6 |
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> |
|
7 |
<bindingRedirect oldVersion="0.0.0.0-4.0.4.1" newVersion="4.0.4.1" /> |
|
8 |
</dependentAssembly> |
|
9 |
</assemblyBinding> |
|
10 |
</runtime> |
|
11 |
</configuration> |
Server/ServerAppTests/packages.config | ||
---|---|---|
1 |
<?xml version="1.0" encoding="utf-8"?> |
|
2 |
<packages> |
|
3 |
<package id="Castle.Core" version="4.4.0" targetFramework="net472" /> |
|
4 |
<package id="Moq" version="4.16.1" targetFramework="net472" /> |
|
5 |
<package id="MSTest.TestAdapter" version="2.1.1" targetFramework="net472" /> |
|
6 |
<package id="MSTest.TestFramework" version="2.1.1" targetFramework="net472" /> |
|
7 |
<package id="System.Runtime.CompilerServices.Unsafe" version="4.5.3" targetFramework="net472" /> |
|
8 |
<package id="System.Threading.Tasks.Extensions" version="4.5.4" targetFramework="net472" /> |
|
9 |
</packages> |
Také k dispozici: Unified diff
Revert "Merge branch 'PredictorAPI' into 'master'"
This reverts merge request !20