Skip to content

Commit d354fe6

Browse files
author
Anh-Duy Le
committed
DLE-190516-Impl finish predicted rates
1 parent 8f00d1a commit d354fe6

File tree

13 files changed

+227
-73
lines changed

13 files changed

+227
-73
lines changed

.vscode/settings.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"python.pythonPath": "C:\\Program Files (x86)\\Python37-32\\python.exe"
3+
}

config.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
sys.path.append(os.path.dirname(ROOT_DIR + r'/'))# Add absolute path to current sys.path
77
# print('Path: ' + str(sys.path))
88

9-
from domains.domain_container import DomainContainer
9+
from domains.domain_factory import DomainFactory
1010

1111
class Configuration():
1212

@@ -15,8 +15,8 @@ def __init__(self):
1515
self.ConfigFileName = "config.json"
1616
self.ConfigFilePath = Path(ROOT_DIR + r'\\' + self.ConfigFileName)
1717
self.Platform = self.getOSplatform()
18-
self.domain_container = DomainContainer()
19-
self.ApiConfigModel = self.domain_container.init_ModelClass('ApiConfigModel')
18+
self.domain_factory = DomainFactory()
19+
self.ConfigApiModel = self.domain_factory.init_ModelClass('ConfigApiModel')
2020

2121

2222
def getOSplatform(self):
@@ -42,7 +42,7 @@ def getApiConfig(self, apiName):
4242
# print(config)
4343
for cf in list(config['configurations']):
4444
if(cf['type'] == "api" and cf['api_name'] == apiName):
45-
modelApiConfig = self.domain_container.map_JsonToAnDomainClass(self.ApiConfigModel, cf)
45+
modelApiConfig = self.domain_factory.map_JsonToDomainClass(self.ConfigApiModel, cf)
4646
return modelApiConfig
4747

4848
except Exception as ex:

core_utils/util_common.py

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from datetime import datetime
1+
from datetime import datetime, timedelta, date
22

33

44
class Core_UtilityCommon():
@@ -12,7 +12,46 @@ def validateDateFormat(self, date_text):
1212
if date_text != datetime.strptime(date_text, "%Y-%m-%d").strftime('%Y-%m-%d'):
1313
raise ValueError
1414
return True
15-
except ValueError:
15+
except ValueError as ex:
16+
print('Error: ', ex)
1617
return False
1718

18-
19+
def parseStringToDate(self, date_text):
20+
try:
21+
if(type(date_text) is date or type(date_text) is datetime):
22+
return date_text
23+
24+
date_obj = datetime.strptime(date_text, '%Y-%m-%d')
25+
datetime.combine(date_obj, datetime.min.time())
26+
# print('Date:', date_obj.date())
27+
return date_obj
28+
except Exception as ex:
29+
print('Error: ', ex)
30+
return None
31+
32+
def parseStringToDateTime(self, datetime_text):
33+
try:
34+
if(type(datetime_text) is date or type(datetime_text) is datetime):
35+
return datetime_text
36+
37+
date_time_obj = datetime.strptime(datetime_text, '%Y-%m-%d %H:%M:%S.%f')
38+
# print('Date:', date_time_obj.date())
39+
# print('Time:', date_time_obj.time())
40+
# print('Date-time:', date_time_obj)
41+
return date_time_obj
42+
except Exception as ex:
43+
print('Error: ', ex)
44+
return None
45+
46+
def dateRange(self, start_date, end_date):
47+
try:
48+
start_date = (type(start_date) is str) and self.parseStringToDate(start_date) or start_date
49+
end_date = (type(end_date) is str) and self.parseStringToDate(end_date) or end_date
50+
51+
for n in range(int ((end_date - start_date).days + 1)):
52+
yield start_date + timedelta(n)
53+
except Exception as ex:
54+
print('Error: ', ex)
55+
return None
56+
57+
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Facade Pattern
2+
"""
3+
doc: Model class with the decorator
4+
"""
5+
class ExchangeRateModel(object):
6+
"""
7+
A data descriptor that sets and returns values normally and optional prints a message logging their access.
8+
"""
9+
def __init__(self):
10+
pass
11+
12+
13+
@property
14+
def BaseCurrency(self):
15+
return self.__BaseCurrency
16+
@BaseCurrency.setter
17+
def BaseCurrency(self, val):
18+
self.__BaseCurrency = val
19+
20+
@property
21+
def ConvertedCurrency(self):
22+
return self.__ConvertedCurrency
23+
@ConvertedCurrency.setter
24+
def ConvertedCurrency(self, val):
25+
self.__ConvertedCurrency = val
26+
27+
@property
28+
def OnDate(self):
29+
return self.__OnDate
30+
@OnDate.setter
31+
def OnDate(self, val):
32+
self.__OnDate = val
33+
34+
35+
@property
36+
def RateValue(self):
37+
return self.__RateValue
38+
@RateValue.setter
39+
def RateValue(self, val):
40+
self.__RateValue = val
41+
42+
586 Bytes
Binary file not shown.

domains/api/ApiOpenExcRateModel.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
1+
# Facade Pattern
22
"""
33
doc: Model class with the decorator
44
"""

domains/config/ApiConfigModel.py renamed to domains/config/ConfigApiModel.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
1+
# Facade Pattern
22
"""
33
doc: Model class with the decorator
44
"""
5-
class ApiConfigModel(object):
5+
class ConfigApiModel(object):
66
"""
77
A data descriptor that sets and returns values normally and optional prints a message logging their access.
88
"""

domains/config/ApiParamConfigModel.py renamed to domains/config/ConfigApiParamModel.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
1+
# Facade Pattern
22
"""
33
doc: Model class with the decorator
44
"""
5-
class ApiParamConfigModel(object):
5+
class ConfigApiParamModel(object):
66
"""
77
A data descriptor that sets and returns values normally and optional prints a message logging their access.
88
"""

domains/domain_container.py renamed to domains/domain_factory.py

Lines changed: 12 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,24 @@
11
import inspect
22
import sys
33

4-
4+
from domains.analysis_data.ExchangeRateModel import ExchangeRateModel
55
from domains.api.ApiOpenExcRateModel import ApiOpenExcRateModel
6-
from domains.config.ApiConfigModel import ApiConfigModel
7-
from domains.config.ApiParamConfigModel import ApiParamConfigModel
6+
from domains.config.ConfigApiModel import ConfigApiModel
7+
from domains.config.ConfigApiParamModel import ConfigApiParamModel
88

9+
#Factory Pattern
910
"""
1011
doc: Container to declare all entities model
1112
"""
12-
class DomainContainer():
13+
class DomainFactory():
1314

1415
def __init__(self):
1516
pass
1617

1718

1819
def get_allDomainClassRegistered(self):
1920

20-
container = [(name, obj) for name, obj in list(inspect.getmembers(sys.modules[__name__], inspect.isclass)) if name not in DomainContainer.__name__]
21+
container = [(name, obj) for name, obj in list(inspect.getmembers(sys.modules[__name__], inspect.isclass)) if name not in DomainFactory.__name__]
2122
return container
2223

2324

@@ -29,27 +30,15 @@ def init_ModelClass(self, className):
2930
return obj
3031

3132

32-
# def print_ValueDomainClass(self, model):
33-
34-
# if(model is not None and inspect.isclass(type(model))):
35-
# attrs = [ (key, value) for key, value in inspect.getmembers(model)
36-
# if (key not in dir(type('dummy', (object,), {})))
37-
# and not (key.startswith('_') or key.endswith('_'))
38-
# ]
39-
40-
# for key, value in attrs:
41-
# print(str(key) + ': ' + str(value))
42-
33+
def init_ObjectClass(self, className):
4334

44-
# def print_ValueListDomainClass(self, listmodel):
45-
46-
# if(listmodel is not None):
47-
# for item in listmodel:
48-
# print('#'*40)
49-
# self.print_ValueDomainClass(item)
35+
clsmembers = self.get_allDomainClassRegistered()
36+
for name, obj in clsmembers:
37+
if name in className:
38+
return obj()
5039

5140

52-
def map_JsonToAnDomainClass(self, modelClass, obj):
41+
def map_JsonToDomainClass(self, modelClass, obj):
5342

5443
if modelClass is None or obj is None:
5544
return None

service/banking/exchangerate_service.py

Lines changed: 77 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
import os, sys
22
import inspect, types
3+
from datetime import timedelta, date, datetime
4+
5+
import matplotlib.pyplot as plt
6+
7+
from sklearn.linear_model import LinearRegression
8+
from sklearn.model_selection import train_test_split
9+
import joblib
310

411
ROOT_DIR = os.getcwd() # Get root directory
512
sys.path.append(os.path.dirname(ROOT_DIR + r'/'))# Add abase_serviceolute path to current sys.path
@@ -12,16 +19,20 @@
1219
"""
1320
class ExchangeRateService():
1421

22+
23+
1524
def __init__(self):
1625
self.base_service = BaseService()
17-
self.domain_container = self.base_service.DomainContainer()
26+
self.domain_factory = self.base_service.DomainFactory()
1827
self.util_common = self.base_service.UtilCommon()
19-
self.util_data = self.base_service.UtilData()
20-
self.ApiConfigModel = self.domain_container.init_ModelClass('ApiConfigModel')
21-
self.ApiParamConfigModel = self.domain_container.init_ModelClass('ApiParamConfigModel')
22-
self.ApiOpenExcRateModel = self.domain_container.init_ModelClass('ApiOpenExcRateModel')
28+
self.util_data = self.base_service.UtilData()
2329
self.ApiConfig1 = self.base_service.Config.getApiConfig("openexchangerates_exchange_rates")
2430

31+
self.ConfigApiModel = self.domain_factory.init_ModelClass('ConfigApiModel')
32+
self.ConfigApiParamModel = self.domain_factory.init_ModelClass('ConfigApiParamModel')
33+
self.ApiOpenExcRateModel = self.domain_factory.init_ModelClass('ApiOpenExcRateModel')
34+
self.ExchangeRateModel = self.domain_factory.init_ModelClass('ExchangeRateModel')
35+
2536

2637
def __init_apiUrl(self):
2738
if self.ApiConfig1:
@@ -31,7 +42,7 @@ def __init_apiUrl(self):
3142

3243
def __init_apiParamsString(self):
3344
if self.ApiConfig1:
34-
lstApiParam = self.domain_container.map_ListJsonToListDomainClass(self.ApiParamConfigModel, self.ApiConfig1.api_params)
45+
lstApiParam = self.domain_factory.map_ListJsonToListDomainClass(self.ConfigApiParamModel, self.ApiConfig1.api_params)
3546
apiStr = ""
3647
for idx, para in enumerate(lstApiParam):
3748
singleParam = "{0}={1}".format(para.param_name, para.default_value)
@@ -55,7 +66,7 @@ def get_exrate_byDate(self, dateReport, baseCurrency):
5566
def get_specific_exrate_byDate(self, dateReport, baseCurrency, toCurrency):
5667
data = self.get_exrate_byDate(dateReport, baseCurrency)
5768
for key, value in data.items():
58-
print(key + ' - ' + str(value))
69+
# print(key + ' - ' + str(value))
5970
if(isinstance(value, dict) and key == "rates"):
6071
for cur, rate in value.items():
6172
if(cur == toCurrency):
@@ -67,23 +78,67 @@ def get_specific_exrate_byDate(self, dateReport, baseCurrency, toCurrency):
6778
return None
6879

6980

70-
def get_specific_exrate_byDateRange(self, fromDate, toDate, baseCurrency, toCurrency):
71-
from datetime import timedelta, date
72-
73-
def daterange(start_date, end_date):
74-
for n in range(int ((end_date - start_date).days)):
75-
yield start_date + timedelta(n)
81+
def get_specific_exrate_byDateRange(self, fromDate, toDate, checkedDate, baseCurrency, toCurrency):
82+
# print('Checked Date: Exchange Rates')
83+
lstExcRates = []
84+
for single_date in self.util_common.dateRange(fromDate, toDate):
85+
if any(da == single_date.day for da in checkedDate):
86+
# if(single_date.day == checkedDate):
87+
data = self.get_specific_exrate_byDate(single_date.strftime("%Y-%m-%d"), baseCurrency, toCurrency)
88+
# print(single_date.strftime("%Y-%m-%d") + ': ' + str(data.RateValue))
89+
90+
model = self.ExchangeRateModel()
91+
model.BaseCurrency = baseCurrency
92+
model.ConvertedCurrency = toCurrency
93+
model.OnDate = single_date.month#datetime.timestamp(single_date)#convert datetime to timestamp
94+
model.RateValue = data.RateValue
95+
96+
lstExcRates.append(model)
97+
98+
return len(lstExcRates) > 0 and lstExcRates or None
99+
100+
def display_graph(self, listdata):
101+
102+
date = [x.OnDate for x in listdata]
103+
rate = [x.RateValue for x in listdata]
104+
105+
plt.scatter(
106+
date,
107+
rate,
108+
c='black'
109+
)
110+
plt.xlabel("Date")
111+
plt.ylabel("Rates")
112+
plt.show()
113+
114+
def training_model(self, listdata):
115+
date = [[x.OnDate] for x in listdata]
116+
rate = [[x.RateValue] for x in listdata]
117+
118+
#Use 70% of data as training, rest 30% to Test model
119+
x_train, x_test, y_train, y_test = train_test_split(date, rate, test_size=0.3)
120+
# training model
121+
linear = LinearRegression()
122+
linear.fit(x_train, y_train)
123+
124+
# evaluating model
125+
score_trained = linear.score(x_test, y_test)
126+
print("Model scored:", score_trained)
127+
128+
# saving model
129+
joblib.dump(linear, ROOT_DIR + r'/domains/analysis_data/linear_model_v1.pkl')
130+
131+
# loading model
132+
clf = joblib.load(ROOT_DIR + r'/domains/analysis_data/linear_model_v1.pkl')
133+
predicted = clf.predict(x_test)#linear.predict(x_test)
134+
print("Predicted Max:", predicted.max())
135+
print("Predicted Min:", predicted.min())
136+
print("Predicted: ", predicted)
137+
76138

77-
start_date = date(2013, 1, 1)
78-
end_date = date(2015, 6, 2)
79-
for single_date in daterange(start_date, end_date):
80-
print(single_date.strftime("%Y-%m-%d"))
81-
82-
# data = self.get_specific_exrate_byDate()
83-
84-
85139

86-
return None
140+
141+
87142

88143

89144

service/base_service.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from core_utils.util_common import Core_UtilityCommon
1010
from core_utils.util_data import Core_UtilityData
1111

12-
from domains.domain_container import DomainContainer
12+
from domains.domain_factory import DomainFactory
1313
from config import Configuration
1414

1515
"""
@@ -22,8 +22,8 @@ class BaseService():
2222
def __init__(self):
2323
pass
2424

25-
def DomainContainer(self):
26-
return DomainContainer()
25+
def DomainFactory(self):
26+
return DomainFactory()
2727

2828
def UtilCommon(self):
2929
return Core_UtilityCommon()

0 commit comments

Comments
 (0)