Skip to content

Commit 0ffb74a

Browse files
committed
exe compiling changes, add rebuild option to dynamic data compilier, add columns example in read me
1 parent d448682 commit 0ffb74a

File tree

7 files changed

+231
-22
lines changed

7 files changed

+231
-22
lines changed

README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,28 @@ price_data = dynamic_data_compiler(start_time, end_time, table, raw_data_cache,
163163
If the option `fformat='parquet'` is provided then no feather files will be created, and a parquet file will be used instead.
164164
While feather might have faster read/write, parquet has excellent compression characteristics and good compatability with packages for handling large on-memory/cluster datasets (e.g. Dask). This helps with local storage (especially for Causer Pays data) and file size for version control.
165165

166+
#### Accessing additional table columns
167+
168+
By default NEMOSIS only includes a subset of an AEMO table's columns, the full set of columns are listed in the
169+
[MMS Data Model Reports](https://visualisations.aemo.com.au/aemo/di-help/Content/Data_Model/MMS_Data_Model.htm
170+
?TocPath=_____8), or can be seen by inspecting the CSVs in the raw data cache. Users of the python interface can add
171+
additional columns as shown below. If you using a feather or parquet based cache the rebuild option should be set to
172+
true so the additional columns are added to the cache files when they are rebuilt. This method of adding additional
173+
columns should also work with the `cache_compiler` function.
174+
175+
```python
176+
from nemosis import defaults, dynamic_data_compiler
177+
178+
defaults.table_columns['BIDPEROFFER_D'] += ['PASAAVAILABILITY']
179+
180+
start_time = '2017/01/01 00:00:00'
181+
end_time = '2017/01/01 00:05:00'
182+
table = 'BIDPEROFFER_D'
183+
raw_data_cache = 'C:/Users/your_data_storage'
184+
185+
volume_bid_data = dynamic_data_compiler(start_time, end_time, table, raw_data_cache, rebuild=True)
186+
```
187+
166188
##### Cache compiler
167189

168190
This may be useful if you're using NEMOSIS to

nemosis/compiling to exe

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@
33
3. Activate venv then comlpete the next steps
44
4. Install NEMOSIS to venv: pip install e .
55
5. Also install pyinstaller: pip install pyinstaller
6-
6. run pyinstaller: PyInstaller --onefile nemosis\gui.py
6+
6. run pyinstaller: pyi-makespec --onefile --icon=favicon.ico nemosis/gui.py
77
7. edit gui.spec by adding the following line after the 'a' variable is defined. The file path will need to be
88
adjusted.
99
a.datas += [('favicon.ico', 'C:\\Users\\user\\Documents\\GitHub\\nemosis\\nemosis\\favicon.ico', 'DATA')]
10-
8. rerun pyinstaller but use the spec file: Pyinstaller --onefile --icon=favicon.ico --clean gui.spec
10+
8. Also add "icon='nemosis\\favicon.ico'" to EXE call in spec
11+
8. rerun pyinstaller but use the spec file: Pyinstaller --clean gui.spec
1112

1213
Sample Spec:
1314
# -*- mode: python ; coding: utf-8 -*-
@@ -29,7 +30,7 @@ a = Analysis(['nemosis\\gui.py'],
2930
cipher=block_cipher,
3031
noarchive=False)
3132

32-
a.datas += [('favicon.ico', 'C:\\Users\\nick\\Documents\\GitHub\\Abi_NEMOSIS\\nemosis\\favicon.ico', 'DATA')]
33+
a.datas += [('favicon.ico', 'C:\\Users\\nick\\Documents\\GitHub\\nemosis\\nemosis\\favicon.ico', 'DATA')]
3334

3435
pyz = PYZ(a.pure, a.zipped_data,
3536
cipher=block_cipher)

nemosis/data_fetch_methods.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ def dynamic_data_compiler(start_time, end_time, table_name, raw_data_location,
1414
select_columns=None, filter_cols=None,
1515
filter_values=None, fformat='feather',
1616
keep_csv=True, parse_data_types=True,
17-
**kwargs):
17+
rebuild=False, **kwargs):
1818
"""
1919
Downloads and compiles data for all dynamic tables. For non-CSV formats,
2020
will save data typed as strings/objects. To save typed data (e.g.
@@ -42,6 +42,8 @@ def dynamic_data_compiler(start_time, end_time, table_name, raw_data_location,
4242
If False, will not return any data.
4343
parse_data_types (bool): infers data types of columns when reading
4444
data. default True for API use.
45+
rebuild (bool): If True then cache files are rebuilt
46+
even if they exist already. False by default.
4547
**kwargs: additional arguments passed to the pd.to_{fformat}() function
4648
4749
Returns:
@@ -77,6 +79,7 @@ def dynamic_data_compiler(start_time, end_time, table_name, raw_data_location,
7779
select_columns, date_filter,
7880
fformat=fformat,
7981
keep_csv=keep_csv,
82+
rebuild=rebuild,
8083
write_kwargs=kwargs)
8184
if data_tables:
8285
all_data = _pd.concat(data_tables, sort=False)

nemosis/date_generators.py

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from nemosis import defaults
22
from calendar import monthrange
3-
3+
from datetime import timedelta
44

55
def year_and_month_gen(start_time, end_time):
66

@@ -60,21 +60,14 @@ def year_month_day_index_gen(start_time, end_time):
6060

6161
def bid_table_gen(start_time, end_time):
6262

63-
6463
# Test for if we are after the date that aemo changes the datafiles to a daily format.
6564
if (start_time.year >= 2021 and start_time.month >= 4) or start_time.year >= 2022:
66-
if (start_time.day == 2 and start_time.hour <= 4) or start_time.day == 1:
67-
# If its a daily format only push the start buffer back by a day.
68-
if start_time.month == 1:
69-
start_time = start_time.replace(month=12)
70-
start_time = start_time.replace(day=31)
71-
start_time = start_time.replace(year=start_time.year - 1)
72-
else:
73-
start_time = start_time.replace(month=start_time.month - 1)
74-
last_day_previous_month = monthrange(start_time.year, start_time.month)[1]
75-
start_time = start_time.replace(day=last_day_previous_month)
65+
if start_time.day == 2 and start_time.hour <= 4:
66+
start_time = start_time - timedelta(days=2)
67+
elif start_time.hour <= 4 or start_time.day == 1:
68+
start_time = start_time - timedelta(days=1)
7669
else:
77-
if start_time.day == 1 and start_time.hour == 0 or start_time.minute == 0:
70+
if start_time.day == 1 and start_time.hour == 0 and start_time.minute == 0:
7871
# If its a monthly format push the buffer back by a month.
7972
if start_time.month == 1:
8073
start_time = start_time.replace(month=12)

nemosis/test_data_fetch_methods.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -384,8 +384,8 @@ def test_dispatch_tables_start_of_month(self):
384384
print('Passed')
385385

386386
def test_dispatch_tables_start_of_month_previous_market_day_but_not_start_calendar_month(self):
387-
start_time = '2021/06/01 03:00:00'
388-
end_time = '2021/06/01 03:15:00'
387+
start_time = '2021/06/05 03:00:00'
388+
end_time = '2021/06/05 03:15:00'
389389
for table in self.table_names:
390390
print(f'Testing {table} returning values at start of month two.')
391391
dat_col = defaults.primary_date_columns[table]
@@ -398,11 +398,11 @@ def test_dispatch_tables_start_of_month_previous_market_day_but_not_start_calend
398398
expected_last_time = pd.to_datetime(end_time, format='%Y/%m/%d %H:%M:%S')
399399
if table == 'BIDDAYOFFER_D':
400400
expected_length = 1 * 4
401-
expected_last_time = '2021/05/31 00:00:00'
401+
expected_last_time = '2021/06/04 00:00:00'
402402
expected_last_time = \
403403
pd.to_datetime(expected_last_time,
404404
format='%Y/%m/%d %H:%M:%S')
405-
expected_first_time = '2021/05/31 00:00:00'
405+
expected_first_time = '2021/06/04 00:00:00'
406406
expected_first_time =\
407407
pd.to_datetime(expected_first_time,
408408
format='%Y/%m/%d %H:%M:%S')

nemosis/test_date_generators.py

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,196 @@ def test_two_times_in_middle_of_jan_and_march_return_3_months(self):
8989
self.assertEqual(len(times), 3)
9090

9191

92+
class TestBidTableGen(unittest.TestCase):
93+
def setUp(self):
94+
pass
95+
96+
def test_two_times_not_at_edge_of_month_return_one_month(self):
97+
start_time = datetime.strptime('2017/01/02 00:00:00', '%Y/%m/%d %H:%M:%S')
98+
end_time = datetime.strptime('2017/01/03 00:00:00', '%Y/%m/%d %H:%M:%S')
99+
gen = date_generators.bid_table_gen(start_time, end_time)
100+
times = [(year, month, day, index) for year, month, day, index in gen]
101+
self.assertEqual(times[0][0], '2017')
102+
self.assertEqual(times[0][1], '01')
103+
self.assertEqual(times[0][2], None)
104+
self.assertEqual(times[0][3], None)
105+
self.assertEqual(len(times), 1)
106+
107+
108+
def test_two_times_first_at_edge_of_month_return_month_before_and_month_of_times(self):
109+
start_time = datetime.strptime('2017/02/01 00:00:00', '%Y/%m/%d %H:%M:%S')
110+
end_time = datetime.strptime('2017/02/03 00:00:00', '%Y/%m/%d %H:%M:%S')
111+
gen = date_generators.bid_table_gen(start_time, end_time)
112+
times = [(year, month, day, index) for year, month, day, index in gen]
113+
self.assertEqual(times[0][0], '2017')
114+
self.assertEqual(times[0][1], '01')
115+
self.assertEqual(times[0][2], None)
116+
self.assertEqual(times[0][3], None)
117+
self.assertEqual(times[1][0], '2017')
118+
self.assertEqual(times[1][1], '02')
119+
self.assertEqual(times[1][2], None)
120+
self.assertEqual(times[1][3], None)
121+
122+
def test_two_times_first_at_edge_of_year_return_month_before_and_month_of_times(self):
123+
start_time = datetime.strptime('2017/01/01 00:00:00', '%Y/%m/%d %H:%M:%S')
124+
end_time = datetime.strptime('2017/01/03 00:00:00', '%Y/%m/%d %H:%M:%S')
125+
gen = date_generators.bid_table_gen(start_time, end_time)
126+
times = [(year, month, day, index) for year, month, day, index in gen]
127+
self.assertEqual(times[0][0], '2016')
128+
self.assertEqual(times[0][1], '12')
129+
self.assertEqual(times[0][2], None)
130+
self.assertEqual(times[0][3], None)
131+
self.assertEqual(times[1][0], '2017')
132+
self.assertEqual(times[1][1], '01')
133+
self.assertEqual(times[1][2], None)
134+
self.assertEqual(times[1][3], None)
135+
136+
def test_two_times_second_at_edge_of_month_returns_one_month(self):
137+
start_time = datetime.strptime('2017/01/05 00:00:00', '%Y/%m/%d %H:%M:%S')
138+
end_time = datetime.strptime('2017/01/31 00:00:00', '%Y/%m/%d %H:%M:%S')
139+
gen = date_generators.bid_table_gen(start_time, end_time)
140+
times = [(year, month, day, index) for year, month, day, index in gen]
141+
self.assertEqual(times[0][0], '2017')
142+
self.assertEqual(times[0][1], '01')
143+
self.assertEqual(times[0][2], None)
144+
self.assertEqual(times[0][3], None)
145+
self.assertEqual(len(times), 1)
146+
147+
def test_two_times_second_at_edge_of_year_returns_one_month(self):
148+
start_time = datetime.strptime('2017/12/02 00:00:00', '%Y/%m/%d %H:%M:%S')
149+
end_time = datetime.strptime('2017/12/31 00:00:00', '%Y/%m/%d %H:%M:%S')
150+
gen = date_generators.bid_table_gen(start_time, end_time)
151+
times = [(year, month, day, index) for year, month, day, index in gen]
152+
self.assertEqual(times[0][0], '2017')
153+
self.assertEqual(times[0][1], '12')
154+
self.assertEqual(times[0][2], None)
155+
self.assertEqual(times[0][3], None)
156+
self.assertEqual(len(times), 1)
157+
158+
def test_two_times_in_middle_of_jan_and_march_return_3_months(self):
159+
start_time = datetime.strptime('2017/01/05 00:00:00', '%Y/%m/%d %H:%M:%S')
160+
end_time = datetime.strptime('2017/03/24 00:00:00', '%Y/%m/%d %H:%M:%S')
161+
gen = date_generators.bid_table_gen(start_time, end_time)
162+
times = [(year, month, day, index) for year, month, day, index in gen]
163+
self.assertEqual(times[0][0], '2017')
164+
self.assertEqual(times[0][1], '01')
165+
self.assertEqual(times[0][2], None)
166+
self.assertEqual(times[0][3], None)
167+
self.assertEqual(times[1][0], '2017')
168+
self.assertEqual(times[1][1], '02')
169+
self.assertEqual(times[1][2], None)
170+
self.assertEqual(times[1][3], None)
171+
self.assertEqual(times[2][0], '2017')
172+
self.assertEqual(times[2][1], '03')
173+
self.assertEqual(times[2][2], None)
174+
self.assertEqual(times[2][3], None)
175+
self.assertEqual(len(times), 3)
176+
177+
def test_change_from_months_to_days(self):
178+
start_time = datetime.strptime('2021/02/01 00:00:00', '%Y/%m/%d %H:%M:%S')
179+
end_time = datetime.strptime('2021/04/03 00:00:00', '%Y/%m/%d %H:%M:%S')
180+
gen = date_generators.bid_table_gen(start_time, end_time)
181+
times = [(year, month, day, index) for year, month, day, index in gen]
182+
# Note we expect the 1st of april to be skipped
183+
self.assertEqual(times[0][0], '2021')
184+
self.assertEqual(times[0][1], '01')
185+
self.assertEqual(times[0][2], None)
186+
self.assertEqual(times[0][3], None)
187+
self.assertEqual(times[1][0], '2021')
188+
self.assertEqual(times[1][1], '02')
189+
self.assertEqual(times[1][2], None)
190+
self.assertEqual(times[1][3], None)
191+
# Data for march and the first of april is missing from the AEMO website so we don't generate the dates
192+
# for these times.
193+
self.assertEqual(times[2][0], '2021')
194+
self.assertEqual(times[2][1], '04')
195+
self.assertEqual(times[2][2], '02')
196+
self.assertEqual(times[2][3], None)
197+
self.assertEqual(times[3][0], '2021')
198+
self.assertEqual(times[3][1], '04')
199+
self.assertEqual(times[3][2], '03')
200+
self.assertEqual(times[3][3], None)
201+
self.assertEqual(len(times), 4)
202+
203+
def test_day_given_in_april_2021(self):
204+
start_time = datetime.strptime('2021/04/01 00:00:00', '%Y/%m/%d %H:%M:%S')
205+
end_time = datetime.strptime('2021/04/03 00:00:00', '%Y/%m/%d %H:%M:%S')
206+
gen = date_generators.bid_table_gen(start_time, end_time)
207+
times = [(year, month, day, index) for year, month, day, index in gen]
208+
# Note we expect the 1st of april to be skipped
209+
self.assertEqual(times[0][0], '2021')
210+
self.assertEqual(times[0][1], '04')
211+
self.assertEqual(times[0][2], '02')
212+
self.assertEqual(times[0][3], None)
213+
self.assertEqual(times[1][0], '2021')
214+
self.assertEqual(times[1][1], '04')
215+
self.assertEqual(times[1][2], '03')
216+
self.assertEqual(times[1][3], None)
217+
self.assertEqual(len(times), 2)
218+
219+
def test_include_previous_market_day(self):
220+
start_time = datetime.strptime('2021/05/10 01:00:00', '%Y/%m/%d %H:%M:%S')
221+
end_time = datetime.strptime('2021/05/10 05:00:00', '%Y/%m/%d %H:%M:%S')
222+
gen = date_generators.bid_table_gen(start_time, end_time)
223+
times = [(year, month, day, index) for year, month, day, index in gen]
224+
# Note we expect the 1st of april to be skipped
225+
self.assertEqual(times[0][0], '2021')
226+
self.assertEqual(times[0][1], '05')
227+
self.assertEqual(times[0][2], '09')
228+
self.assertEqual(times[0][3], None)
229+
self.assertEqual(times[1][0], '2021')
230+
self.assertEqual(times[1][1], '05')
231+
self.assertEqual(times[1][2], '10')
232+
self.assertEqual(times[1][3], None)
233+
self.assertEqual(len(times), 2)
234+
235+
def test_include_previous_month_if_1st_market_day_of_month(self):
236+
start_time = datetime.strptime('2021/05/01 05:00:00', '%Y/%m/%d %H:%M:%S')
237+
end_time = datetime.strptime('2021/05/03 05:00:00', '%Y/%m/%d %H:%M:%S')
238+
gen = date_generators.bid_table_gen(start_time, end_time)
239+
times = [(year, month, day, index) for year, month, day, index in gen]
240+
self.assertEqual(times[0][0], '2021')
241+
self.assertEqual(times[0][1], '04')
242+
self.assertEqual(times[0][2], '30')
243+
self.assertEqual(times[0][3], None)
244+
self.assertEqual(times[1][0], '2021')
245+
self.assertEqual(times[1][1], '05')
246+
self.assertEqual(times[1][2], '01')
247+
self.assertEqual(times[1][3], None)
248+
self.assertEqual(times[2][0], '2021')
249+
self.assertEqual(times[2][1], '05')
250+
self.assertEqual(times[2][2], '02')
251+
self.assertEqual(times[2][3], None)
252+
self.assertEqual(times[3][0], '2021')
253+
self.assertEqual(times[3][1], '05')
254+
self.assertEqual(times[3][2], '03')
255+
self.assertEqual(times[3][3], None)
256+
self.assertEqual(len(times), 4)
257+
258+
def test_include_previous_month_if_1st_market_day_of_month_but_2nd_calendar_day(self):
259+
start_time = datetime.strptime('2021/05/02 04:00:00', '%Y/%m/%d %H:%M:%S')
260+
end_time = datetime.strptime('2021/05/03 05:00:00', '%Y/%m/%d %H:%M:%S')
261+
gen = date_generators.bid_table_gen(start_time, end_time)
262+
times = [(year, month, day, index) for year, month, day, index in gen]
263+
self.assertEqual(times[0][0], '2021')
264+
self.assertEqual(times[0][1], '04')
265+
self.assertEqual(times[0][2], '30')
266+
self.assertEqual(times[0][3], None)
267+
self.assertEqual(times[1][0], '2021')
268+
self.assertEqual(times[1][1], '05')
269+
self.assertEqual(times[1][2], '01')
270+
self.assertEqual(times[1][3], None)
271+
self.assertEqual(times[2][0], '2021')
272+
self.assertEqual(times[2][1], '05')
273+
self.assertEqual(times[2][2], '02')
274+
self.assertEqual(times[2][3], None)
275+
self.assertEqual(times[3][0], '2021')
276+
self.assertEqual(times[3][1], '05')
277+
self.assertEqual(times[3][2], '03')
278+
self.assertEqual(times[3][3], None)
279+
self.assertEqual(len(times), 4)
280+
281+
92282
class TestYearMonthDayIndexGen(unittest.TestCase):
93283
def setUp(self):
94284
pass

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
setuptools.setup(
77
name="nemosis",
8-
version="3.0.0",
8+
version="3.0.1",
99
author="Nicholas Gorman, Abhijith Prakash",
1010
author_email="n.gorman305@gmail.com",
1111
description="A tool for accessing AEMO data.",

0 commit comments

Comments
 (0)