createsonline 0.1.26__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.
- createsonline/__init__.py +46 -0
- createsonline/admin/__init__.py +7 -0
- createsonline/admin/content.py +526 -0
- createsonline/admin/crud.py +805 -0
- createsonline/admin/field_builder.py +559 -0
- createsonline/admin/integration.py +482 -0
- createsonline/admin/interface.py +2562 -0
- createsonline/admin/model_creator.py +513 -0
- createsonline/admin/model_manager.py +388 -0
- createsonline/admin/modern_dashboard.py +498 -0
- createsonline/admin/permissions.py +264 -0
- createsonline/admin/user_forms.py +594 -0
- createsonline/ai/__init__.py +202 -0
- createsonline/ai/fields.py +1226 -0
- createsonline/ai/orm.py +325 -0
- createsonline/ai/services.py +1244 -0
- createsonline/app.py +506 -0
- createsonline/auth/__init__.py +8 -0
- createsonline/auth/management.py +228 -0
- createsonline/auth/models.py +552 -0
- createsonline/cli/__init__.py +5 -0
- createsonline/cli/commands/__init__.py +122 -0
- createsonline/cli/commands/database.py +416 -0
- createsonline/cli/commands/info.py +173 -0
- createsonline/cli/commands/initdb.py +218 -0
- createsonline/cli/commands/project.py +545 -0
- createsonline/cli/commands/serve.py +173 -0
- createsonline/cli/commands/shell.py +93 -0
- createsonline/cli/commands/users.py +148 -0
- createsonline/cli/main.py +2041 -0
- createsonline/cli/manage.py +274 -0
- createsonline/config/__init__.py +9 -0
- createsonline/config/app.py +2577 -0
- createsonline/config/database.py +179 -0
- createsonline/config/docs.py +384 -0
- createsonline/config/errors.py +160 -0
- createsonline/config/orm.py +43 -0
- createsonline/config/request.py +93 -0
- createsonline/config/settings.py +176 -0
- createsonline/data/__init__.py +23 -0
- createsonline/data/dataframe.py +925 -0
- createsonline/data/io.py +453 -0
- createsonline/data/series.py +557 -0
- createsonline/database/__init__.py +60 -0
- createsonline/database/abstraction.py +440 -0
- createsonline/database/assistant.py +585 -0
- createsonline/database/fields.py +442 -0
- createsonline/database/migrations.py +132 -0
- createsonline/database/models.py +604 -0
- createsonline/database.py +438 -0
- createsonline/http/__init__.py +28 -0
- createsonline/http/client.py +535 -0
- createsonline/ml/__init__.py +55 -0
- createsonline/ml/classification.py +552 -0
- createsonline/ml/clustering.py +680 -0
- createsonline/ml/metrics.py +542 -0
- createsonline/ml/neural.py +560 -0
- createsonline/ml/preprocessing.py +784 -0
- createsonline/ml/regression.py +501 -0
- createsonline/performance/__init__.py +19 -0
- createsonline/performance/cache.py +444 -0
- createsonline/performance/compression.py +335 -0
- createsonline/performance/core.py +419 -0
- createsonline/project_init.py +789 -0
- createsonline/routing.py +528 -0
- createsonline/security/__init__.py +34 -0
- createsonline/security/core.py +811 -0
- createsonline/security/encryption.py +349 -0
- createsonline/server.py +295 -0
- createsonline/static/css/admin.css +263 -0
- createsonline/static/css/common.css +358 -0
- createsonline/static/css/dashboard.css +89 -0
- createsonline/static/favicon.ico +0 -0
- createsonline/static/icons/icon-128x128.png +0 -0
- createsonline/static/icons/icon-128x128.webp +0 -0
- createsonline/static/icons/icon-16x16.png +0 -0
- createsonline/static/icons/icon-16x16.webp +0 -0
- createsonline/static/icons/icon-180x180.png +0 -0
- createsonline/static/icons/icon-180x180.webp +0 -0
- createsonline/static/icons/icon-192x192.png +0 -0
- createsonline/static/icons/icon-192x192.webp +0 -0
- createsonline/static/icons/icon-256x256.png +0 -0
- createsonline/static/icons/icon-256x256.webp +0 -0
- createsonline/static/icons/icon-32x32.png +0 -0
- createsonline/static/icons/icon-32x32.webp +0 -0
- createsonline/static/icons/icon-384x384.png +0 -0
- createsonline/static/icons/icon-384x384.webp +0 -0
- createsonline/static/icons/icon-48x48.png +0 -0
- createsonline/static/icons/icon-48x48.webp +0 -0
- createsonline/static/icons/icon-512x512.png +0 -0
- createsonline/static/icons/icon-512x512.webp +0 -0
- createsonline/static/icons/icon-64x64.png +0 -0
- createsonline/static/icons/icon-64x64.webp +0 -0
- createsonline/static/image/android-chrome-192x192.png +0 -0
- createsonline/static/image/android-chrome-512x512.png +0 -0
- createsonline/static/image/apple-touch-icon.png +0 -0
- createsonline/static/image/favicon-16x16.png +0 -0
- createsonline/static/image/favicon-32x32.png +0 -0
- createsonline/static/image/favicon.ico +0 -0
- createsonline/static/image/favicon.svg +17 -0
- createsonline/static/image/icon-128x128.png +0 -0
- createsonline/static/image/icon-128x128.webp +0 -0
- createsonline/static/image/icon-16x16.png +0 -0
- createsonline/static/image/icon-16x16.webp +0 -0
- createsonline/static/image/icon-180x180.png +0 -0
- createsonline/static/image/icon-180x180.webp +0 -0
- createsonline/static/image/icon-192x192.png +0 -0
- createsonline/static/image/icon-192x192.webp +0 -0
- createsonline/static/image/icon-256x256.png +0 -0
- createsonline/static/image/icon-256x256.webp +0 -0
- createsonline/static/image/icon-32x32.png +0 -0
- createsonline/static/image/icon-32x32.webp +0 -0
- createsonline/static/image/icon-384x384.png +0 -0
- createsonline/static/image/icon-384x384.webp +0 -0
- createsonline/static/image/icon-48x48.png +0 -0
- createsonline/static/image/icon-48x48.webp +0 -0
- createsonline/static/image/icon-512x512.png +0 -0
- createsonline/static/image/icon-512x512.webp +0 -0
- createsonline/static/image/icon-64x64.png +0 -0
- createsonline/static/image/icon-64x64.webp +0 -0
- createsonline/static/image/logo-header-h100.png +0 -0
- createsonline/static/image/logo-header-h100.webp +0 -0
- createsonline/static/image/logo-header-h200@2x.png +0 -0
- createsonline/static/image/logo-header-h200@2x.webp +0 -0
- createsonline/static/image/logo.png +0 -0
- createsonline/static/js/admin.js +274 -0
- createsonline/static/site.webmanifest +35 -0
- createsonline/static/templates/admin/base.html +87 -0
- createsonline/static/templates/admin/dashboard.html +217 -0
- createsonline/static/templates/admin/model_form.html +270 -0
- createsonline/static/templates/admin/model_list.html +202 -0
- createsonline/static/test_script.js +15 -0
- createsonline/static/test_styles.css +59 -0
- createsonline/static_files.py +365 -0
- createsonline/templates/404.html +100 -0
- createsonline/templates/admin_login.html +169 -0
- createsonline/templates/base.html +102 -0
- createsonline/templates/index.html +151 -0
- createsonline/templates.py +205 -0
- createsonline/testing.py +322 -0
- createsonline/utils.py +448 -0
- createsonline/validation/__init__.py +49 -0
- createsonline/validation/fields.py +598 -0
- createsonline/validation/models.py +504 -0
- createsonline/validation/validators.py +561 -0
- createsonline/views.py +184 -0
- createsonline-0.1.26.dist-info/METADATA +46 -0
- createsonline-0.1.26.dist-info/RECORD +152 -0
- createsonline-0.1.26.dist-info/WHEEL +5 -0
- createsonline-0.1.26.dist-info/entry_points.txt +2 -0
- createsonline-0.1.26.dist-info/licenses/LICENSE +21 -0
- createsonline-0.1.26.dist-info/top_level.txt +1 -0
createsonline/data/io.py
ADDED
|
@@ -0,0 +1,453 @@
|
|
|
1
|
+
"""
|
|
2
|
+
CREATESONLINE Data I/O Operations
|
|
3
|
+
|
|
4
|
+
Pure Python data input/output operations.
|
|
5
|
+
CSV and JSON reading/writing functionality.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import json
|
|
9
|
+
import csv
|
|
10
|
+
from typing import Any, Dict, List, Optional, Union
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
from .dataframe import CreatesonlineDataFrame
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def read_csv(
|
|
16
|
+
filepath: Union[str, Path],
|
|
17
|
+
sep: str = ',',
|
|
18
|
+
header: Union[int, str, None] = 0,
|
|
19
|
+
index_col: Optional[Union[int, str]] = None,
|
|
20
|
+
usecols: Optional[List[Union[int, str]]] = None,
|
|
21
|
+
skiprows: Optional[Union[int, List[int]]] = None,
|
|
22
|
+
nrows: Optional[int] = None,
|
|
23
|
+
encoding: str = 'utf-8'
|
|
24
|
+
) -> CreatesonlineDataFrame:
|
|
25
|
+
"""
|
|
26
|
+
Read CSV file into CreatesonlineDataFrame
|
|
27
|
+
|
|
28
|
+
Args:
|
|
29
|
+
filepath: Path to CSV file
|
|
30
|
+
sep: Field separator
|
|
31
|
+
header: Row to use as column names (0 for first row, None for no header)
|
|
32
|
+
index_col: Column to use as row index
|
|
33
|
+
usecols: Columns to read
|
|
34
|
+
skiprows: Rows to skip
|
|
35
|
+
nrows: Number of rows to read
|
|
36
|
+
encoding: File encoding
|
|
37
|
+
|
|
38
|
+
Returns:
|
|
39
|
+
CreatesonlineDataFrame with CSV data
|
|
40
|
+
"""
|
|
41
|
+
filepath = Path(filepath)
|
|
42
|
+
|
|
43
|
+
if not filepath.exists():
|
|
44
|
+
raise FileNotFoundError(f"File not found: {filepath}")
|
|
45
|
+
|
|
46
|
+
with open(filepath, 'r', encoding=encoding, newline='') as f:
|
|
47
|
+
# Handle skiprows
|
|
48
|
+
if skiprows:
|
|
49
|
+
if isinstance(skiprows, int):
|
|
50
|
+
for _ in range(skiprows):
|
|
51
|
+
next(f, None)
|
|
52
|
+
else:
|
|
53
|
+
lines_to_skip = set(skiprows)
|
|
54
|
+
for i, line in enumerate(f):
|
|
55
|
+
if i not in lines_to_skip:
|
|
56
|
+
f.seek(0)
|
|
57
|
+
for _ in range(i):
|
|
58
|
+
next(f)
|
|
59
|
+
break
|
|
60
|
+
|
|
61
|
+
reader = csv.reader(f, delimiter=sep)
|
|
62
|
+
|
|
63
|
+
# Read all rows
|
|
64
|
+
rows = []
|
|
65
|
+
for i, row in enumerate(reader):
|
|
66
|
+
rows.append(row)
|
|
67
|
+
if nrows and i >= nrows - 1:
|
|
68
|
+
break
|
|
69
|
+
|
|
70
|
+
if not rows:
|
|
71
|
+
return CreatesonlineDataFrame()
|
|
72
|
+
|
|
73
|
+
# Handle header
|
|
74
|
+
if header == 0 or header is True:
|
|
75
|
+
columns = rows[0]
|
|
76
|
+
data_rows = rows[1:]
|
|
77
|
+
elif isinstance(header, int):
|
|
78
|
+
columns = rows[header]
|
|
79
|
+
data_rows = rows[header + 1:]
|
|
80
|
+
elif header is None:
|
|
81
|
+
columns = [f'col_{i}' for i in range(len(rows[0]))]
|
|
82
|
+
data_rows = rows
|
|
83
|
+
else:
|
|
84
|
+
raise ValueError("Invalid header parameter")
|
|
85
|
+
|
|
86
|
+
# Handle usecols
|
|
87
|
+
if usecols:
|
|
88
|
+
if all(isinstance(col, str) for col in usecols):
|
|
89
|
+
# Column names
|
|
90
|
+
col_indices = [columns.index(col) for col in usecols if col in columns]
|
|
91
|
+
columns = [columns[i] for i in col_indices]
|
|
92
|
+
else:
|
|
93
|
+
# Column indices
|
|
94
|
+
col_indices = [i for i in usecols if i < len(columns)]
|
|
95
|
+
columns = [columns[i] for i in col_indices]
|
|
96
|
+
|
|
97
|
+
data_rows = [[row[i] for i in col_indices] for row in data_rows]
|
|
98
|
+
|
|
99
|
+
# Convert to appropriate types
|
|
100
|
+
data = {}
|
|
101
|
+
for i, col in enumerate(columns):
|
|
102
|
+
col_data = []
|
|
103
|
+
for row in data_rows:
|
|
104
|
+
if i < len(row):
|
|
105
|
+
value = row[i].strip()
|
|
106
|
+
# Try to convert to number
|
|
107
|
+
if value == '':
|
|
108
|
+
col_data.append(None)
|
|
109
|
+
elif value.lower() in ('true', 'false'):
|
|
110
|
+
col_data.append(value.lower() == 'true')
|
|
111
|
+
else:
|
|
112
|
+
try:
|
|
113
|
+
if '.' in value:
|
|
114
|
+
col_data.append(float(value))
|
|
115
|
+
else:
|
|
116
|
+
col_data.append(int(value))
|
|
117
|
+
except ValueError:
|
|
118
|
+
col_data.append(value)
|
|
119
|
+
else:
|
|
120
|
+
col_data.append(None)
|
|
121
|
+
|
|
122
|
+
data[col] = col_data
|
|
123
|
+
|
|
124
|
+
df = CreatesonlineDataFrame(data=data)
|
|
125
|
+
|
|
126
|
+
# Handle index_col
|
|
127
|
+
if index_col is not None:
|
|
128
|
+
if isinstance(index_col, str):
|
|
129
|
+
df = df.set_index(index_col)
|
|
130
|
+
elif isinstance(index_col, int):
|
|
131
|
+
col_name = columns[index_col]
|
|
132
|
+
df = df.set_index(col_name)
|
|
133
|
+
|
|
134
|
+
return df
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def to_csv(
|
|
138
|
+
df: CreatesonlineDataFrame,
|
|
139
|
+
filepath: Union[str, Path],
|
|
140
|
+
sep: str = ',',
|
|
141
|
+
index: bool = True,
|
|
142
|
+
header: bool = True,
|
|
143
|
+
encoding: str = 'utf-8'
|
|
144
|
+
) -> None:
|
|
145
|
+
"""
|
|
146
|
+
Write CreatesonlineDataFrame to CSV file
|
|
147
|
+
|
|
148
|
+
Args:
|
|
149
|
+
df: DataFrame to write
|
|
150
|
+
filepath: Output file path
|
|
151
|
+
sep: Field separator
|
|
152
|
+
index: Whether to write row index
|
|
153
|
+
header: Whether to write column header
|
|
154
|
+
encoding: File encoding
|
|
155
|
+
"""
|
|
156
|
+
filepath = Path(filepath)
|
|
157
|
+
filepath.parent.mkdir(parents=True, exist_ok=True)
|
|
158
|
+
|
|
159
|
+
with open(filepath, 'w', encoding=encoding, newline='') as f:
|
|
160
|
+
writer = csv.writer(f, delimiter=sep)
|
|
161
|
+
|
|
162
|
+
# Write header
|
|
163
|
+
if header:
|
|
164
|
+
header_row = []
|
|
165
|
+
if index:
|
|
166
|
+
header_row.append('index')
|
|
167
|
+
header_row.extend(df.columns)
|
|
168
|
+
writer.writerow(header_row)
|
|
169
|
+
|
|
170
|
+
# Write data rows
|
|
171
|
+
for i in range(len(df.index)):
|
|
172
|
+
row = []
|
|
173
|
+
if index:
|
|
174
|
+
row.append(df.index[i])
|
|
175
|
+
|
|
176
|
+
for col in df.columns:
|
|
177
|
+
value = df._data[col][i]
|
|
178
|
+
row.append('' if value is None else str(value))
|
|
179
|
+
|
|
180
|
+
writer.writerow(row)
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
def read_json(
|
|
184
|
+
filepath: Union[str, Path],
|
|
185
|
+
orient: str = 'records',
|
|
186
|
+
encoding: str = 'utf-8'
|
|
187
|
+
) -> CreatesonlineDataFrame:
|
|
188
|
+
"""
|
|
189
|
+
Read JSON file into CreatesonlineDataFrame
|
|
190
|
+
|
|
191
|
+
Args:
|
|
192
|
+
filepath: Path to JSON file
|
|
193
|
+
orient: JSON orientation ('records', 'dict', 'list')
|
|
194
|
+
encoding: File encoding
|
|
195
|
+
|
|
196
|
+
Returns:
|
|
197
|
+
CreatesonlineDataFrame with JSON data
|
|
198
|
+
"""
|
|
199
|
+
filepath = Path(filepath)
|
|
200
|
+
|
|
201
|
+
if not filepath.exists():
|
|
202
|
+
raise FileNotFoundError(f"File not found: {filepath}")
|
|
203
|
+
|
|
204
|
+
with open(filepath, 'r', encoding=encoding) as f:
|
|
205
|
+
data = json.load(f)
|
|
206
|
+
|
|
207
|
+
if orient == 'records':
|
|
208
|
+
# List of {column: value} dicts
|
|
209
|
+
return CreatesonlineDataFrame(data=data)
|
|
210
|
+
elif orient == 'dict':
|
|
211
|
+
# {column: [values]} dict
|
|
212
|
+
return CreatesonlineDataFrame(data=data)
|
|
213
|
+
elif orient == 'list':
|
|
214
|
+
# {column: [values]} dict (same as dict)
|
|
215
|
+
return CreatesonlineDataFrame(data=data)
|
|
216
|
+
else:
|
|
217
|
+
raise ValueError(f"Invalid orient: {orient}")
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
def to_json(
|
|
221
|
+
df: CreatesonlineDataFrame,
|
|
222
|
+
filepath: Union[str, Path],
|
|
223
|
+
orient: str = 'records',
|
|
224
|
+
indent: Optional[int] = None,
|
|
225
|
+
encoding: str = 'utf-8'
|
|
226
|
+
) -> None:
|
|
227
|
+
"""
|
|
228
|
+
Write CreatesonlineDataFrame to JSON file
|
|
229
|
+
|
|
230
|
+
Args:
|
|
231
|
+
df: DataFrame to write
|
|
232
|
+
filepath: Output file path
|
|
233
|
+
orient: JSON orientation ('records', 'dict', 'list')
|
|
234
|
+
indent: JSON indentation
|
|
235
|
+
encoding: File encoding
|
|
236
|
+
"""
|
|
237
|
+
filepath = Path(filepath)
|
|
238
|
+
filepath.parent.mkdir(parents=True, exist_ok=True)
|
|
239
|
+
|
|
240
|
+
data = df.to_dict(orient=orient)
|
|
241
|
+
|
|
242
|
+
with open(filepath, 'w', encoding=encoding) as f:
|
|
243
|
+
json.dump(data, f, indent=indent, default=str, ensure_ascii=False)
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
def read_excel(
|
|
247
|
+
filepath: Union[str, Path],
|
|
248
|
+
sheet_name: Union[str, int] = 0,
|
|
249
|
+
header: Union[int, None] = 0,
|
|
250
|
+
index_col: Optional[Union[int, str]] = None,
|
|
251
|
+
usecols: Optional[List[Union[int, str]]] = None,
|
|
252
|
+
skiprows: Optional[Union[int, List[int]]] = None,
|
|
253
|
+
nrows: Optional[int] = None
|
|
254
|
+
) -> CreatesonlineDataFrame:
|
|
255
|
+
"""
|
|
256
|
+
Read Excel file into CreatesonlineDataFrame
|
|
257
|
+
|
|
258
|
+
Note: This is a basic implementation that reads Excel files as CSV.
|
|
259
|
+
For full Excel support, users should save as CSV first.
|
|
260
|
+
|
|
261
|
+
Args:
|
|
262
|
+
filepath: Path to Excel file
|
|
263
|
+
sheet_name: Sheet name or index
|
|
264
|
+
header: Row to use as column names
|
|
265
|
+
index_col: Column to use as row index
|
|
266
|
+
usecols: Columns to read
|
|
267
|
+
skiprows: Rows to skip
|
|
268
|
+
nrows: Number of rows to read
|
|
269
|
+
|
|
270
|
+
Returns:
|
|
271
|
+
CreatesonlineDataFrame with Excel data
|
|
272
|
+
"""
|
|
273
|
+
import logging
|
|
274
|
+
logger = logging.getLogger(__name__)
|
|
275
|
+
|
|
276
|
+
# Try to import pandas for Excel support
|
|
277
|
+
try:
|
|
278
|
+
import pandas as pd
|
|
279
|
+
logger.info("Using pandas for Excel reading")
|
|
280
|
+
|
|
281
|
+
# Use pandas to read Excel
|
|
282
|
+
df_pandas = pd.read_excel(
|
|
283
|
+
filepath,
|
|
284
|
+
sheet_name=sheet_name,
|
|
285
|
+
header=header,
|
|
286
|
+
index_col=index_col,
|
|
287
|
+
usecols=usecols,
|
|
288
|
+
skiprows=skiprows,
|
|
289
|
+
nrows=nrows
|
|
290
|
+
)
|
|
291
|
+
|
|
292
|
+
# Convert pandas DataFrame to CreatesonlineDataFrame
|
|
293
|
+
data = {}
|
|
294
|
+
for col in df_pandas.columns:
|
|
295
|
+
data[col] = df_pandas[col].tolist()
|
|
296
|
+
|
|
297
|
+
return CreatesonlineDataFrame(data=data, index=df_pandas.index.tolist())
|
|
298
|
+
|
|
299
|
+
except ImportError:
|
|
300
|
+
logger.warning("Pandas not available for Excel reading. Attempting CSV fallback.")
|
|
301
|
+
|
|
302
|
+
# Fallback: Try to find a CSV version of the file
|
|
303
|
+
filepath = Path(filepath)
|
|
304
|
+
csv_path = filepath.with_suffix('.csv')
|
|
305
|
+
|
|
306
|
+
if csv_path.exists():
|
|
307
|
+
logger.info(f"Found CSV version: {csv_path}")
|
|
308
|
+
return read_csv(
|
|
309
|
+
csv_path,
|
|
310
|
+
header=header,
|
|
311
|
+
index_col=index_col,
|
|
312
|
+
usecols=usecols,
|
|
313
|
+
skiprows=skiprows,
|
|
314
|
+
nrows=nrows
|
|
315
|
+
)
|
|
316
|
+
else:
|
|
317
|
+
# Create an informative error message with suggestions
|
|
318
|
+
error_msg = (
|
|
319
|
+
f"Excel reading requires pandas library. Install with: pip install pandas openpyxl\n"
|
|
320
|
+
f"Alternatively, save '{filepath}' as CSV and use read_csv() instead.\n"
|
|
321
|
+
f"Expected CSV path: {csv_path}"
|
|
322
|
+
)
|
|
323
|
+
logger.error(error_msg)
|
|
324
|
+
raise ImportError(error_msg)
|
|
325
|
+
|
|
326
|
+
|
|
327
|
+
def to_excel(
|
|
328
|
+
df: CreatesonlineDataFrame,
|
|
329
|
+
filepath: Union[str, Path],
|
|
330
|
+
sheet_name: str = 'Sheet1',
|
|
331
|
+
index: bool = True,
|
|
332
|
+
header: bool = True
|
|
333
|
+
) -> None:
|
|
334
|
+
"""
|
|
335
|
+
Write CreatesonlineDataFrame to Excel file
|
|
336
|
+
|
|
337
|
+
Note: This is a basic implementation that saves as CSV.
|
|
338
|
+
For full Excel support, users can convert CSV to Excel manually.
|
|
339
|
+
|
|
340
|
+
Args:
|
|
341
|
+
df: DataFrame to write
|
|
342
|
+
filepath: Output file path
|
|
343
|
+
sheet_name: Sheet name
|
|
344
|
+
index: Whether to write row index
|
|
345
|
+
header: Whether to write column header
|
|
346
|
+
"""
|
|
347
|
+
# Convert to CSV instead
|
|
348
|
+
csv_path = Path(filepath).with_suffix('.csv')
|
|
349
|
+
to_csv(df, csv_path, index=index, header=header)
|
|
350
|
+
|
|
351
|
+
|
|
352
|
+
# Utility functions for data conversion
|
|
353
|
+
def from_dict(data: Dict[str, List[Any]]) -> CreatesonlineDataFrame:
|
|
354
|
+
"""Create DataFrame from dictionary"""
|
|
355
|
+
return CreatesonlineDataFrame(data=data)
|
|
356
|
+
|
|
357
|
+
|
|
358
|
+
def from_records(records: List[Dict[str, Any]]) -> CreatesonlineDataFrame:
|
|
359
|
+
"""Create DataFrame from list of records"""
|
|
360
|
+
return CreatesonlineDataFrame(data=records)
|
|
361
|
+
|
|
362
|
+
|
|
363
|
+
def concat(
|
|
364
|
+
dataframes: List[CreatesonlineDataFrame],
|
|
365
|
+
axis: int = 0,
|
|
366
|
+
ignore_index: bool = False
|
|
367
|
+
) -> CreatesonlineDataFrame:
|
|
368
|
+
"""
|
|
369
|
+
Concatenate multiple DataFrames
|
|
370
|
+
|
|
371
|
+
Args:
|
|
372
|
+
dataframes: List of DataFrames to concatenate
|
|
373
|
+
axis: Axis to concatenate along (0=rows, 1=columns)
|
|
374
|
+
ignore_index: Reset index in result
|
|
375
|
+
|
|
376
|
+
Returns:
|
|
377
|
+
Concatenated DataFrame
|
|
378
|
+
"""
|
|
379
|
+
if not dataframes:
|
|
380
|
+
return CreatesonlineDataFrame()
|
|
381
|
+
|
|
382
|
+
result = dataframes[0].copy()
|
|
383
|
+
|
|
384
|
+
for df in dataframes[1:]:
|
|
385
|
+
result = result.concat(df, axis=axis)
|
|
386
|
+
|
|
387
|
+
if ignore_index:
|
|
388
|
+
result = result.reset_index(drop=True)
|
|
389
|
+
|
|
390
|
+
return result
|
|
391
|
+
|
|
392
|
+
|
|
393
|
+
# Data validation utilities
|
|
394
|
+
def validate_dataframe(df: CreatesonlineDataFrame) -> Dict[str, Any]:
|
|
395
|
+
"""
|
|
396
|
+
Validate DataFrame and return diagnostics
|
|
397
|
+
|
|
398
|
+
Args:
|
|
399
|
+
df: DataFrame to validate
|
|
400
|
+
|
|
401
|
+
Returns:
|
|
402
|
+
Dictionary with validation results
|
|
403
|
+
"""
|
|
404
|
+
return {
|
|
405
|
+
'shape': df.shape,
|
|
406
|
+
'columns': df.columns,
|
|
407
|
+
'null_counts': {
|
|
408
|
+
col: sum(1 for val in df._data[col] if val is None)
|
|
409
|
+
for col in df.columns
|
|
410
|
+
},
|
|
411
|
+
'data_types': {
|
|
412
|
+
col: type(df._data[col][0]).__name__ if df._data[col] else 'empty'
|
|
413
|
+
for col in df.columns
|
|
414
|
+
},
|
|
415
|
+
'memory_usage_estimate': f"{df.size * 8} bytes",
|
|
416
|
+
'duplicate_rows': 0, # Would need to implement duplicate detection
|
|
417
|
+
'is_valid': True
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
|
|
421
|
+
def sample_data(df: CreatesonlineDataFrame, n: int = 5, random_state: Optional[int] = None) -> CreatesonlineDataFrame:
|
|
422
|
+
"""
|
|
423
|
+
Sample n rows from DataFrame
|
|
424
|
+
|
|
425
|
+
Args:
|
|
426
|
+
df: DataFrame to sample from
|
|
427
|
+
n: Number of rows to sample
|
|
428
|
+
random_state: Random seed for reproducibility
|
|
429
|
+
|
|
430
|
+
Returns:
|
|
431
|
+
DataFrame with sampled rows
|
|
432
|
+
"""
|
|
433
|
+
import random
|
|
434
|
+
|
|
435
|
+
if random_state:
|
|
436
|
+
random.seed(random_state)
|
|
437
|
+
|
|
438
|
+
if n >= len(df):
|
|
439
|
+
return df.copy()
|
|
440
|
+
|
|
441
|
+
indices = random.sample(range(len(df)), n)
|
|
442
|
+
indices.sort()
|
|
443
|
+
|
|
444
|
+
new_data = {}
|
|
445
|
+
for col in df.columns:
|
|
446
|
+
new_data[col] = [df._data[col][i] for i in indices]
|
|
447
|
+
|
|
448
|
+
new_index = [df.index[i] for i in indices]
|
|
449
|
+
|
|
450
|
+
return CreatesonlineDataFrame(
|
|
451
|
+
data=new_data,
|
|
452
|
+
index=new_index
|
|
453
|
+
)
|