technologydata 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- technologydata/__init__.py +41 -0
- technologydata/constants/__init__.py +12 -0
- technologydata/constants/energy_density.py +324 -0
- technologydata/datapackage.py +145 -0
- technologydata/package_data/dea_energy_storage/dea_energy_storage.py +691 -0
- technologydata/package_data/dea_energy_storage/sources.json +12 -0
- technologydata/package_data/dea_energy_storage/technologies.json +17508 -0
- technologydata/package_data/raw/Technology_datasheet_for_energy_storage.xlsx +0 -0
- technologydata/parameter.py +662 -0
- technologydata/source.py +430 -0
- technologydata/source_collection.py +243 -0
- technologydata/technologies/__init__.py +5 -0
- technologydata/technologies/growth_models.py +503 -0
- technologydata/technology.py +191 -0
- technologydata/technology_collection.py +466 -0
- technologydata/utils/__init__.py +13 -0
- technologydata/utils/carriers.txt +33 -0
- technologydata/utils/commons.py +310 -0
- technologydata/utils/heating_values.txt +17 -0
- technologydata/utils/units.py +519 -0
- technologydata-0.1.0.dist-info/METADATA +135 -0
- technologydata-0.1.0.dist-info/RECORD +25 -0
- technologydata-0.1.0.dist-info/WHEEL +5 -0
- technologydata-0.1.0.dist-info/licenses/LICENSE +18 -0
- technologydata-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: technologydata contributors
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: MIT
|
|
4
|
+
|
|
5
|
+
"""Classes for Commons methods."""
|
|
6
|
+
|
|
7
|
+
import enum
|
|
8
|
+
import logging
|
|
9
|
+
import re
|
|
10
|
+
from typing import Any
|
|
11
|
+
|
|
12
|
+
import dateutil
|
|
13
|
+
import pandas as pd
|
|
14
|
+
|
|
15
|
+
from technologydata.utils.units import CURRENCY_UNIT_PATTERN, get_iso3_to_currency_codes
|
|
16
|
+
|
|
17
|
+
logger = logging.getLogger(__name__)
|
|
18
|
+
|
|
19
|
+
all_currency_codes = set(get_iso3_to_currency_codes().values())
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class DateFormatEnum(str, enum.Enum):
|
|
23
|
+
"""
|
|
24
|
+
Enum for date formats used in different sources.
|
|
25
|
+
|
|
26
|
+
Attributes
|
|
27
|
+
----------
|
|
28
|
+
SOURCES_CSV : str
|
|
29
|
+
Date format for CSV sources, e.g., "2023-10-01 12:00:00".
|
|
30
|
+
WAYBACK : str
|
|
31
|
+
Date format for Wayback Machine, e.g., "20231001120000".
|
|
32
|
+
NONE : str
|
|
33
|
+
Represents an empty date format.
|
|
34
|
+
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
SOURCES_CSV = "%Y-%m-%d %H:%M:%S"
|
|
38
|
+
WAYBACK = "%Y%m%d%H%M%S"
|
|
39
|
+
NONE = ""
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class FileExtensionEnum(enum.Enum):
|
|
43
|
+
"""
|
|
44
|
+
An enumeration that maps various file extensions to their corresponding MIME types.
|
|
45
|
+
|
|
46
|
+
This Enum provides a structured way to associate common file extensions with their respective
|
|
47
|
+
MIME types, facilitating easy retrieval of file extensions based on content types. Each member
|
|
48
|
+
of the enumeration is a tuple containing the file extension and its associated MIME type.
|
|
49
|
+
|
|
50
|
+
Members
|
|
51
|
+
--------
|
|
52
|
+
TEXT_PLAIN : tuple
|
|
53
|
+
Represents the MIME type "text/plain" with the file extension ".txt".
|
|
54
|
+
TEXT_HTML : tuple
|
|
55
|
+
Represents the MIME type "text/html" with the file extension ".html".
|
|
56
|
+
TEXT_CSV : tuple
|
|
57
|
+
Represents the MIME type "text/csv" with the file extension ".csv".
|
|
58
|
+
TEXT_XML : tuple
|
|
59
|
+
Represents the MIME type "text/xml" with the file extension ".xml".
|
|
60
|
+
APPLICATION_MS_EXCEL : tuple
|
|
61
|
+
Represents the MIME type "application/vnd.ms-excel" with the file extension ".xls".
|
|
62
|
+
APPLICATION_ODS : tuple
|
|
63
|
+
Represents the MIME type "application/vnd.oasis.opendocument.spreadsheet" with the file extension ".ods".
|
|
64
|
+
APPLICATION_OPENXML_EXCEL : tuple
|
|
65
|
+
Represents the MIME type "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
|
66
|
+
with the file extension ".xlsx".
|
|
67
|
+
APPLICATION_JSON : tuple
|
|
68
|
+
Represents the MIME type "application/json" with the file extension ".json".
|
|
69
|
+
APPLICATION_XML : tuple
|
|
70
|
+
Represents the MIME type "application/xml" with the file extension ".xml".
|
|
71
|
+
APPLICATION_PDF : tuple
|
|
72
|
+
Represents the MIME type "application/pdf" with the file extension ".pdf".
|
|
73
|
+
APPLICATION_PARQUET : tuple
|
|
74
|
+
Represents the MIME type "application/parquet" with the file extension ".parquet".
|
|
75
|
+
APPLICATION_VDN_PARQUET : tuple
|
|
76
|
+
Represents the MIME type "application/vdn.apache.parquet" with the file extension ".parquet".
|
|
77
|
+
APPLICATION_RAR_WINDOWS : tuple
|
|
78
|
+
Represents the MIME type "application/x-rar-compressed" with the file extension ".rar".
|
|
79
|
+
APPLICATION_RAR : tuple
|
|
80
|
+
Represents the MIME type "application/vnd.rar" with the file extension ".rar".
|
|
81
|
+
APPLICATION_ZIP : tuple
|
|
82
|
+
Represents the MIME type "application/zip" with the file extension ".zip".
|
|
83
|
+
APPLICATION_ZIP_WINDOWS : tuple
|
|
84
|
+
Represents the MIME type "application/x-zip-compressed" with the file extension ".zip".
|
|
85
|
+
"""
|
|
86
|
+
|
|
87
|
+
TEXT_PLAIN = (".txt", "text/plain")
|
|
88
|
+
TEXT_HTML = (".html", "text/html")
|
|
89
|
+
TEXT_CSV = (".csv", "text/csv")
|
|
90
|
+
TEXT_XML = (".xml", "text/xml")
|
|
91
|
+
APPLICATION_MS_EXCEL = (".xls", "application/vnd.ms-excel")
|
|
92
|
+
APPLICATION_ODS = (".ods", "application/vnd.oasis.opendocument.spreadsheet")
|
|
93
|
+
APPLICATION_OPENXML_EXCEL = (
|
|
94
|
+
".xlsx",
|
|
95
|
+
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
96
|
+
)
|
|
97
|
+
APPLICATION_JSON = (".json", "application/json")
|
|
98
|
+
APPLICATION_XML = (".xml", "application/xml")
|
|
99
|
+
APPLICATION_PDF = (".pdf", "application/pdf")
|
|
100
|
+
APPLICATION_PARQUET = (".parquet", "application/parquet")
|
|
101
|
+
APPLICATION_VDN_PARQUET = (".parquet", "application/vdn.apache.parquet")
|
|
102
|
+
APPLICATION_RAR_WINDOWS = (".rar", "application/x-rar-compressed")
|
|
103
|
+
APPLICATION_RAR = (".rar", "application/vnd.rar")
|
|
104
|
+
APPLICATION_ZIP = (".zip", "application/zip")
|
|
105
|
+
APPLICATION_ZIP_WINDOWS = (".zip", "application/x-zip-compressed")
|
|
106
|
+
|
|
107
|
+
@classmethod
|
|
108
|
+
def get_extension(cls, content_type: str) -> str | None:
|
|
109
|
+
"""
|
|
110
|
+
Retrieve the file extension associated with a given MIME type.
|
|
111
|
+
|
|
112
|
+
Parameters
|
|
113
|
+
----------
|
|
114
|
+
content_type : str
|
|
115
|
+
The MIME type for which the corresponding file extension is to be retrieved.
|
|
116
|
+
|
|
117
|
+
Returns
|
|
118
|
+
-------
|
|
119
|
+
str | None
|
|
120
|
+
The file extension associated with the given MIME type, or None if the
|
|
121
|
+
MIME type is not supported.
|
|
122
|
+
|
|
123
|
+
Examples
|
|
124
|
+
--------
|
|
125
|
+
>>> FileExtensionEnum.get_extension("application/pdf")
|
|
126
|
+
>>> '.pdf'
|
|
127
|
+
|
|
128
|
+
>>> FileExtensionEnum.get_extension("application/unknown")
|
|
129
|
+
>>> None
|
|
130
|
+
|
|
131
|
+
"""
|
|
132
|
+
for member in cls:
|
|
133
|
+
if member.value[1] == content_type:
|
|
134
|
+
return member.value[0]
|
|
135
|
+
return None
|
|
136
|
+
|
|
137
|
+
@classmethod
|
|
138
|
+
def search_file_extension_in_url(cls, url: str) -> str | None:
|
|
139
|
+
"""
|
|
140
|
+
Search for the file extension in a given URL.
|
|
141
|
+
|
|
142
|
+
Parameters
|
|
143
|
+
----------
|
|
144
|
+
url : str
|
|
145
|
+
The URL to search for the file extension.
|
|
146
|
+
|
|
147
|
+
Returns
|
|
148
|
+
-------
|
|
149
|
+
str | None
|
|
150
|
+
The file extension, or None if no match is found.
|
|
151
|
+
|
|
152
|
+
Examples
|
|
153
|
+
--------
|
|
154
|
+
>>> FileExtensionEnum.search_file_extension_in_url("https://example.com/file.pdf")
|
|
155
|
+
'.pdf'
|
|
156
|
+
|
|
157
|
+
>>> FileExtensionEnum.search_file_extension_in_url("https://example.com/file.unknown")
|
|
158
|
+
None
|
|
159
|
+
|
|
160
|
+
"""
|
|
161
|
+
for member in cls:
|
|
162
|
+
if re.search(r"\b" + re.escape(member.value[0]) + r"\b", url):
|
|
163
|
+
return member.value[0]
|
|
164
|
+
return None
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
class Commons:
|
|
168
|
+
"""
|
|
169
|
+
A utility class for various helper functions.
|
|
170
|
+
|
|
171
|
+
This class provides static methods for common tasks, such as changing the format of datetime strings and replacing
|
|
172
|
+
special characters in strings. The methods are stateless and can be called without instantiating the class.
|
|
173
|
+
|
|
174
|
+
Methods
|
|
175
|
+
-------
|
|
176
|
+
change_datetime_format(input_datetime_string: str, output_datetime_format: DateFormatEnum) -> str | None:
|
|
177
|
+
Change the format of a given datetime string to a specified output format.
|
|
178
|
+
replace_special_characters(input_string: str) -> str:
|
|
179
|
+
Replace special characters and spaces in a string with underscores.
|
|
180
|
+
|
|
181
|
+
Examples
|
|
182
|
+
--------
|
|
183
|
+
>>> Commons.change_datetime_format("20250520144500", DateFormatEnum.SOURCES_CSV)
|
|
184
|
+
'2025-05-20 14:45:00'
|
|
185
|
+
>>> Commons.replace_special_characters("Hello, World! Welcome to Python @ 2023.")
|
|
186
|
+
'hello_world_welcome_to_python_2023'
|
|
187
|
+
|
|
188
|
+
"""
|
|
189
|
+
|
|
190
|
+
@staticmethod
|
|
191
|
+
def change_datetime_format(
|
|
192
|
+
input_datetime_string: str,
|
|
193
|
+
output_datetime_format: DateFormatEnum,
|
|
194
|
+
) -> str | Any:
|
|
195
|
+
"""
|
|
196
|
+
Change the format of a given datetime string to a specified output format.
|
|
197
|
+
|
|
198
|
+
The method takes a datetime string and automatically detects its format, then converts it to the specified output format.
|
|
199
|
+
If the input string cannot be parsed, it logs an error and returns None.
|
|
200
|
+
|
|
201
|
+
Parameters
|
|
202
|
+
----------
|
|
203
|
+
input_datetime_string : str
|
|
204
|
+
datetime string that needs to be reformatted
|
|
205
|
+
|
|
206
|
+
output_datetime_format : DateFormatEnum
|
|
207
|
+
desired format for the output datetime string, following the strftime format codes.
|
|
208
|
+
|
|
209
|
+
Returns
|
|
210
|
+
-------
|
|
211
|
+
str | None
|
|
212
|
+
reformatted datetime string if successful, otherwise None
|
|
213
|
+
|
|
214
|
+
Raises
|
|
215
|
+
------
|
|
216
|
+
ValueError
|
|
217
|
+
If the input datetime string cannot be parsed.
|
|
218
|
+
|
|
219
|
+
Examples
|
|
220
|
+
--------
|
|
221
|
+
>>> Commons.change_datetime_format("20250520144500", DateFormatEnum.SOURCES_CSV)
|
|
222
|
+
>>> "2025-05-20 14:45:00"
|
|
223
|
+
|
|
224
|
+
"""
|
|
225
|
+
try:
|
|
226
|
+
# Automatically detect the format of the input datetime string
|
|
227
|
+
dt = dateutil.parser.parse(input_datetime_string)
|
|
228
|
+
logger.debug(f"The datetime string has been parsed successfully: {dt}")
|
|
229
|
+
output_datetime_string = dt.strftime(output_datetime_format.value)
|
|
230
|
+
logger.debug(f"The format is now changed to {output_datetime_format.value}")
|
|
231
|
+
return output_datetime_string
|
|
232
|
+
except ValueError as e:
|
|
233
|
+
raise ValueError(f"Error during datetime formatting: {e}")
|
|
234
|
+
|
|
235
|
+
@staticmethod
|
|
236
|
+
def replace_special_characters(input_string: str) -> str:
|
|
237
|
+
"""
|
|
238
|
+
Replace special characters and spaces in a string.
|
|
239
|
+
|
|
240
|
+
The method replaces special characters and spaces in a string with underscores,
|
|
241
|
+
collapsing multiple consecutive underscores into a single underscore. Finally, it lowercases all characters of the string and removes leading or
|
|
242
|
+
trailing underscores.
|
|
243
|
+
|
|
244
|
+
Parameters
|
|
245
|
+
----------
|
|
246
|
+
input_string : str
|
|
247
|
+
The input string from which special characters and spaces will be replaced.
|
|
248
|
+
|
|
249
|
+
Returns
|
|
250
|
+
-------
|
|
251
|
+
str
|
|
252
|
+
A new string with all special characters and spaces replaced by a single underscore
|
|
253
|
+
where consecutive underscores occur.
|
|
254
|
+
|
|
255
|
+
Examples
|
|
256
|
+
--------
|
|
257
|
+
>>> replace_special_characters("Hello, World! Welcome to Python @ 2023.")
|
|
258
|
+
'hello_world_welcome_to_python_2023'
|
|
259
|
+
|
|
260
|
+
>>> replace_special_characters("Special#Characters$Are%Fun!")
|
|
261
|
+
'special_characters_are_fun'
|
|
262
|
+
|
|
263
|
+
"""
|
|
264
|
+
# Replace any character that is not a word character or whitespace with underscore
|
|
265
|
+
replaced = re.sub(r"[^\w\s]", "_", input_string)
|
|
266
|
+
# Replace whitespace with underscore
|
|
267
|
+
replaced = replaced.replace(" ", "_")
|
|
268
|
+
# Collapse multiple consecutive underscores into a single underscore
|
|
269
|
+
replaced = re.sub(r"_+", "_", replaced)
|
|
270
|
+
# Remove leading and trailing underscores
|
|
271
|
+
replaced = replaced.strip("_")
|
|
272
|
+
# Lower case the string
|
|
273
|
+
replaced = replaced.casefold()
|
|
274
|
+
return replaced
|
|
275
|
+
|
|
276
|
+
@staticmethod
|
|
277
|
+
def update_unit_with_currency_year(unit: str, currency_year: str) -> str:
|
|
278
|
+
"""
|
|
279
|
+
Update unit string to include currency year for currency-based units.
|
|
280
|
+
|
|
281
|
+
Parameters
|
|
282
|
+
----------
|
|
283
|
+
unit : str
|
|
284
|
+
A unit string
|
|
285
|
+
currency_year: str
|
|
286
|
+
A currency year string
|
|
287
|
+
|
|
288
|
+
Returns
|
|
289
|
+
-------
|
|
290
|
+
str
|
|
291
|
+
Updated unit
|
|
292
|
+
|
|
293
|
+
"""
|
|
294
|
+
# Check if the units contain a currency-like string, defined as "{3-letter currency code}_{year as YYYY}"
|
|
295
|
+
matches = CURRENCY_UNIT_PATTERN.findall(unit)
|
|
296
|
+
|
|
297
|
+
# Check if unit is a string, contains the currency, and currency_year is not null
|
|
298
|
+
if isinstance(unit, str) and pd.notna(currency_year):
|
|
299
|
+
for currency_code in all_currency_codes:
|
|
300
|
+
if (
|
|
301
|
+
pd.notna(currency_code)
|
|
302
|
+
and currency_code in unit
|
|
303
|
+
and len(matches) == 0
|
|
304
|
+
):
|
|
305
|
+
# Replace currency with currency_currency_year
|
|
306
|
+
unit = unit.replace(
|
|
307
|
+
currency_code, f"{currency_code}_{currency_year}"
|
|
308
|
+
)
|
|
309
|
+
|
|
310
|
+
return unit
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: technologydata contributors
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: MIT
|
|
4
|
+
|
|
5
|
+
# Definitions for the default heating values supported by the package.
|
|
6
|
+
# Each heating value is defined as an independent dimension.
|
|
7
|
+
# This way, pint allows for operations like division or multiplication,
|
|
8
|
+
# and at the same time prevents incompatible operations on these dimensions.
|
|
9
|
+
#
|
|
10
|
+
# See also: https://pint.readthedocs.io/en/latest/defining.html
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
# Format:
|
|
14
|
+
# <heating_value_name> = [<heating_value_name>] [= <alias>]
|
|
15
|
+
|
|
16
|
+
lower_heating_value = [lower_heating_value] = LHV = NCV = net_calorific_value
|
|
17
|
+
higher_heating_value = [higher_heating_value] = HHV = GCV = gross_calorific_value
|