tinytim 1.11.0__tar.gz → 1.13.0__tar.gz
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.
- tinytim-1.13.0/PKG-INFO +429 -0
- tinytim-1.13.0/README.md +395 -0
- tinytim-1.13.0/pyproject.toml +112 -0
- tinytim-1.13.0/setup.py +11 -0
- {tinytim-1.11.0 → tinytim-1.13.0/src}/tinytim/__init__.py +4 -4
- tinytim-1.13.0/src/tinytim/columns.py +81 -0
- {tinytim-1.11.0 → tinytim-1.13.0/src}/tinytim/copy.py +12 -7
- tinytim-1.13.0/src/tinytim/custom_types.py +18 -0
- {tinytim-1.11.0 → tinytim-1.13.0/src}/tinytim/data.py +40 -39
- {tinytim-1.11.0 → tinytim-1.13.0/src}/tinytim/dropna.py +113 -108
- {tinytim-1.11.0 → tinytim-1.13.0/src}/tinytim/edit.py +114 -84
- {tinytim-1.11.0 → tinytim-1.13.0/src}/tinytim/fillna.py +137 -138
- {tinytim-1.11.0 → tinytim-1.13.0/src}/tinytim/filter.py +16 -18
- {tinytim-1.11.0 → tinytim-1.13.0/src}/tinytim/group.py +49 -46
- {tinytim-1.11.0 → tinytim-1.13.0/src}/tinytim/insert.py +5 -4
- tinytim-1.13.0/src/tinytim/interfaces.py +61 -0
- {tinytim-1.11.0 → tinytim-1.13.0/src}/tinytim/isna.py +8 -7
- {tinytim-1.11.0 → tinytim-1.13.0/src}/tinytim/join.py +202 -149
- {tinytim-1.11.0 → tinytim-1.13.0/src}/tinytim/json.py +14 -13
- tinytim-1.13.0/src/tinytim/na.py +4 -0
- tinytim-1.13.0/src/tinytim/py.typed +0 -0
- {tinytim-1.11.0 → tinytim-1.13.0/src}/tinytim/rows.py +44 -43
- tinytim-1.11.0/tinytim/columns.py → tinytim-1.13.0/src/tinytim/sequences.py +47 -123
- {tinytim-1.11.0 → tinytim-1.13.0/src}/tinytim/utils.py +29 -21
- {tinytim-1.11.0 → tinytim-1.13.0/src}/tinytim/validate.py +8 -7
- tinytim-1.13.0/src/tinytim.egg-info/PKG-INFO +429 -0
- tinytim-1.13.0/src/tinytim.egg-info/SOURCES.txt +45 -0
- tinytim-1.13.0/src/tinytim.egg-info/requires.txt +11 -0
- tinytim-1.13.0/tests/test_columns.py +16 -0
- tinytim-1.13.0/tests/test_copy.py +141 -0
- tinytim-1.13.0/tests/test_data.py +135 -0
- tinytim-1.13.0/tests/test_edit.py +309 -0
- tinytim-1.13.0/tests/test_filter.py +322 -0
- tinytim-1.13.0/tests/test_group.py +278 -0
- tinytim-1.13.0/tests/test_insert.py +106 -0
- tinytim-1.13.0/tests/test_isna.py +260 -0
- tinytim-1.13.0/tests/test_join.py +172 -0
- tinytim-1.13.0/tests/test_json.py +34 -0
- tinytim-1.13.0/tests/test_na.py +634 -0
- tinytim-1.13.0/tests/test_rows.py +214 -0
- tinytim-1.13.0/tests/test_sequences.py +226 -0
- tinytim-1.13.0/tests/test_utils.py +226 -0
- tinytim-1.13.0/tests/test_validate.py +67 -0
- tinytim-1.11.0/PKG-INFO +0 -51
- tinytim-1.11.0/README.md +0 -36
- tinytim-1.11.0/setup.py +0 -27
- tinytim-1.11.0/tinytim/na.py +0 -3
- tinytim-1.11.0/tinytim/types.py +0 -14
- tinytim-1.11.0/tinytim.egg-info/PKG-INFO +0 -51
- tinytim-1.11.0/tinytim.egg-info/SOURCES.txt +0 -26
- tinytim-1.11.0/tinytim.egg-info/requires.txt +0 -2
- {tinytim-1.11.0 → tinytim-1.13.0}/LICENSE.md +0 -0
- {tinytim-1.11.0 → tinytim-1.13.0}/setup.cfg +0 -0
- {tinytim-1.11.0 → tinytim-1.13.0/src}/tinytim.egg-info/dependency_links.txt +0 -0
- {tinytim-1.11.0 → tinytim-1.13.0/src}/tinytim.egg-info/top_level.txt +0 -0
tinytim-1.13.0/PKG-INFO
ADDED
|
@@ -0,0 +1,429 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: tinytim
|
|
3
|
+
Version: 1.13.0
|
|
4
|
+
Summary: Pure Python data table functions.
|
|
5
|
+
Author-email: Odos Matthews <odosmatthews@gmail.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/eddiethedean/tinytim
|
|
8
|
+
Project-URL: Repository, https://github.com/eddiethedean/tinytim
|
|
9
|
+
Project-URL: Issues, https://github.com/eddiethedean/tinytim/issues
|
|
10
|
+
Keywords: data,table,dataframe,pure-python,lightweight
|
|
11
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.15
|
|
20
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
21
|
+
Requires-Python: >=3.11
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
License-File: LICENSE.md
|
|
24
|
+
Provides-Extra: dev
|
|
25
|
+
Requires-Dist: pytest>=8.3.0; extra == "dev"
|
|
26
|
+
Requires-Dist: pytest-cov>=5.0.0; extra == "dev"
|
|
27
|
+
Requires-Dist: mypy>=1.11.0; extra == "dev"
|
|
28
|
+
Requires-Dist: ruff>=0.6.0; extra == "dev"
|
|
29
|
+
Requires-Dist: tox>=4.0.0; extra == "dev"
|
|
30
|
+
Provides-Extra: docs
|
|
31
|
+
Requires-Dist: sphinx>=8.0; extra == "docs"
|
|
32
|
+
Requires-Dist: furo>=2024.8.6; extra == "docs"
|
|
33
|
+
Dynamic: license-file
|
|
34
|
+
|
|
35
|
+
# TinyTim
|
|
36
|
+
|
|
37
|
+
A pure Python package for processing tabular data stored in dictionaries.
|
|
38
|
+
|
|
39
|
+
[](https://pypi.org/project/tinytim/)
|
|
40
|
+
[](https://github.com/eddiethedean/tinytim/actions/workflows/commit.yml)
|
|
41
|
+
[](https://pypi.org/project/tinytim/)
|
|
42
|
+
[](https://opensource.org/licenses/MIT)
|
|
43
|
+
|
|
44
|
+
## Description
|
|
45
|
+
|
|
46
|
+
TinyTim provides small, pure-Python tools for working with tabular data when a full dataframe library is more than a project needs. It has **no runtime dependencies** beyond the Python standard library.
|
|
47
|
+
|
|
48
|
+
Tables are mappings of column names to sequences of values, such as `{"name": ["Ada", "Lin"], "score": [95, 88]}`. Keep every column the same length; use `tinytim.validate.valid_table_mapping` to check a table. Functions without an `_inplace` suffix return new table data, while their `_inplace` counterparts modify the input.
|
|
49
|
+
|
|
50
|
+
## Features
|
|
51
|
+
|
|
52
|
+
- **No runtime dependencies** - Uses only the Python standard library
|
|
53
|
+
- **Lightweight** - Minimal footprint, fast installation
|
|
54
|
+
- **Familiar API** - Intuitive functions for data manipulation
|
|
55
|
+
- **Type hints** - Full type annotations for better IDE support
|
|
56
|
+
- **Well tested** - Comprehensive test suite
|
|
57
|
+
|
|
58
|
+
## Installation
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
pip install tinytim
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Requirements
|
|
65
|
+
|
|
66
|
+
- Python >= 3.11
|
|
67
|
+
|
|
68
|
+
## Documentation
|
|
69
|
+
|
|
70
|
+
The [Sphinx user guide](src/tinytim/docs/index.rst) covers common operations, and the [API reference](src/tinytim/docs/modules.rst) documents the public modules. Runnable notebooks are available in the [examples](examples/) directory.
|
|
71
|
+
|
|
72
|
+
## Quick Start
|
|
73
|
+
|
|
74
|
+
### Basic Data Operations
|
|
75
|
+
|
|
76
|
+
```python
|
|
77
|
+
from tinytim.data import column_count, row_count, shape, head, tail
|
|
78
|
+
|
|
79
|
+
# Data is stored as {column_name: column_values}
|
|
80
|
+
data = {'x': [1, 2, 3, 4], 'y': [10, 20, 30, 40]}
|
|
81
|
+
|
|
82
|
+
# Get basic information
|
|
83
|
+
column_count(data)
|
|
84
|
+
# 2
|
|
85
|
+
|
|
86
|
+
row_count(data)
|
|
87
|
+
# 4
|
|
88
|
+
|
|
89
|
+
shape(data)
|
|
90
|
+
# (4, 2)
|
|
91
|
+
|
|
92
|
+
# Preview data
|
|
93
|
+
head(data, 2)
|
|
94
|
+
# {'x': [1, 2], 'y': [10, 20]}
|
|
95
|
+
|
|
96
|
+
tail(data, 2)
|
|
97
|
+
# {'x': [3, 4], 'y': [30, 40]}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Working with Rows
|
|
101
|
+
|
|
102
|
+
```python
|
|
103
|
+
from tinytim.rows import row_dict, iterrows, row_dicts_to_data
|
|
104
|
+
|
|
105
|
+
data = {'x': [1, 2, 3], 'y': [6, 7, 8]}
|
|
106
|
+
|
|
107
|
+
# Get a single row
|
|
108
|
+
row_dict(data, 1)
|
|
109
|
+
# {'x': 2, 'y': 7}
|
|
110
|
+
|
|
111
|
+
# Iterate over rows
|
|
112
|
+
for index, row in iterrows(data):
|
|
113
|
+
print(f"Row {index}: {row}")
|
|
114
|
+
# Row 0: {'x': 1, 'y': 6}
|
|
115
|
+
# Row 1: {'x': 2, 'y': 7}
|
|
116
|
+
# Row 2: {'x': 3, 'y': 8}
|
|
117
|
+
|
|
118
|
+
# Convert row dictionaries to data
|
|
119
|
+
rows = [{'x': 1, 'y': 20}, {'x': 2, 'y': 21}, {'x': 3, 'y': 22}]
|
|
120
|
+
result = row_dicts_to_data(rows)
|
|
121
|
+
# {'x': [1, 2, 3], 'y': [20, 21, 22]}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Working with Columns
|
|
125
|
+
|
|
126
|
+
```python
|
|
127
|
+
from tinytim.edit import add_to_column, multiply_column
|
|
128
|
+
|
|
129
|
+
data = {'x': [1, 2, 3, 4], 'y': [5, 6, 7, 8]}
|
|
130
|
+
|
|
131
|
+
# Add to a column
|
|
132
|
+
result = add_to_column(data, 'x', 10)
|
|
133
|
+
# {'x': [11, 12, 13, 14], 'y': [5, 6, 7, 8]}
|
|
134
|
+
|
|
135
|
+
# Multiply a column
|
|
136
|
+
result = multiply_column(data, 'x', 2)
|
|
137
|
+
# {'x': [2, 4, 6, 8], 'y': [5, 6, 7, 8]}
|
|
138
|
+
|
|
139
|
+
# Column-wise operations with sequences
|
|
140
|
+
result = add_to_column(data, 'x', [10, 20, 30, 40])
|
|
141
|
+
# {'x': [11, 22, 33, 44], 'y': [5, 6, 7, 8]}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Filtering and Selection
|
|
145
|
+
|
|
146
|
+
```python
|
|
147
|
+
from tinytim.filter import filter_by_column_gt, filter_by_column_isin
|
|
148
|
+
|
|
149
|
+
data = {'x': [1, 2, 3, 4, 5], 'y': [10, 20, 30, 40, 50]}
|
|
150
|
+
|
|
151
|
+
# Filter rows where column value is greater than threshold
|
|
152
|
+
filtered = filter_by_column_gt(data, 'x', 2)
|
|
153
|
+
# {'x': [3, 4, 5], 'y': [30, 40, 50]}
|
|
154
|
+
|
|
155
|
+
# Filter rows where column value is in a list
|
|
156
|
+
filtered = filter_by_column_isin(data, 'x', [1, 3, 5])
|
|
157
|
+
# {'x': [1, 3, 5], 'y': [10, 30, 50]}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Handling Missing Values
|
|
161
|
+
|
|
162
|
+
```python
|
|
163
|
+
from tinytim.na import isna, dropna, fillna
|
|
164
|
+
|
|
165
|
+
data = {'x': [1, None, 3], 'y': [10, 20, None]}
|
|
166
|
+
|
|
167
|
+
# Check for missing values
|
|
168
|
+
isna(data)
|
|
169
|
+
# {'x': [False, True, False], 'y': [False, False, True]}
|
|
170
|
+
|
|
171
|
+
# Drop rows with missing values
|
|
172
|
+
dropna(data)
|
|
173
|
+
# {'x': [1], 'y': [10]}
|
|
174
|
+
|
|
175
|
+
# Fill missing values
|
|
176
|
+
fillna(data, 0)
|
|
177
|
+
# {'x': [1, 0, 3], 'y': [10, 20, 0]}
|
|
178
|
+
|
|
179
|
+
# Forward fill
|
|
180
|
+
data2 = {'x': [None, 2, None, 4], 'y': [10, None, None, 40]}
|
|
181
|
+
fillna(data2, method='ffill')
|
|
182
|
+
# {'x': [None, 2, 2, 4], 'y': [10, 10, 10, 40]}
|
|
183
|
+
|
|
184
|
+
# Limit each forward-filled gap to one value
|
|
185
|
+
fillna({'x': [1, None, None, 4, None]}, method='ffill', limit=1)
|
|
186
|
+
# {'x': [1, 1, None, 4, 4]}
|
|
187
|
+
|
|
188
|
+
# Get indexes of rows retained by dropna
|
|
189
|
+
dropna(data, remaining=True)
|
|
190
|
+
# [0]
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
`dropna(..., axis='columns', remaining=True)` returns the names of the retained columns. Missing values default to `None`; pass `na_value` to use another sentinel.
|
|
194
|
+
|
|
195
|
+
### Grouping and Aggregation
|
|
196
|
+
|
|
197
|
+
```python
|
|
198
|
+
from tinytim.group import groupby, sum_groups
|
|
199
|
+
|
|
200
|
+
data = {'category': ['A', 'B', 'A', 'B'], 'value': [1, 2, 3, 4]}
|
|
201
|
+
|
|
202
|
+
# Group by column
|
|
203
|
+
groups = groupby(data, 'category')
|
|
204
|
+
# [('A', {'category': ['A', 'A'], 'value': [1, 3]}),
|
|
205
|
+
# ('B', {'category': ['B', 'B'], 'value': [2, 4]})]
|
|
206
|
+
|
|
207
|
+
# Sum grouped data
|
|
208
|
+
labels, sums = sum_groups(groups)
|
|
209
|
+
# labels: ['A', 'B']
|
|
210
|
+
# sums: {'value': [4, 6]}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### Joining Data
|
|
214
|
+
|
|
215
|
+
```python
|
|
216
|
+
from tinytim.join import inner_join, left_join
|
|
217
|
+
|
|
218
|
+
left = {'id': [1, 2, 3], 'value': ['a', 'b', 'c']}
|
|
219
|
+
right = {'id': [2, 3, 4], 'score': [10, 20, 30]}
|
|
220
|
+
|
|
221
|
+
# Inner join on 'id' column
|
|
222
|
+
result = inner_join(left, right, 'id')
|
|
223
|
+
# {'id': [2, 3], 'value': ['b', 'c'], 'score': [10, 20]}
|
|
224
|
+
|
|
225
|
+
# Left join keeps all rows from left table
|
|
226
|
+
result = left_join(left, right, 'id')
|
|
227
|
+
# {'id': [1, 2, 3], 'value': ['a', 'b', 'c'], 'score': [None, 10, 20]}
|
|
228
|
+
|
|
229
|
+
# Same-named non-key columns receive suffixes
|
|
230
|
+
left = {'id': [1, 2], 'value': ['a', 'b']}
|
|
231
|
+
right = {'id': [2, 3], 'value': ['c', 'd']}
|
|
232
|
+
result = inner_join(left, right, 'id')
|
|
233
|
+
# {'id': [2], 'value_x': ['b'], 'value_y': ['c']}
|
|
234
|
+
|
|
235
|
+
# Join on multiple columns and choose custom suffixes
|
|
236
|
+
left = {'account': [10, 10], 'year': [2025, 2026], 'amount': [100, 120]}
|
|
237
|
+
right = {'account': [10, 10], 'year': [2025, 2026], 'amount': [95, 125]}
|
|
238
|
+
result = inner_join(left, right, ['account', 'year'], suffixes=('_left', '_right'))
|
|
239
|
+
# The result contains amount_left and amount_right.
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
## More Examples
|
|
243
|
+
|
|
244
|
+
### Editing Data
|
|
245
|
+
|
|
246
|
+
```python
|
|
247
|
+
from tinytim.edit import edit_row_items, drop_row, drop_column
|
|
248
|
+
|
|
249
|
+
data = {'name': ['Alice', 'Bob', 'Charlie'],
|
|
250
|
+
'age': [25, 30, 35],
|
|
251
|
+
'city': ['NYC', 'LA', 'SF']}
|
|
252
|
+
|
|
253
|
+
# Edit specific row values
|
|
254
|
+
result = edit_row_items(data, 1, {'age': 31, 'city': 'Seattle'})
|
|
255
|
+
# {'name': ['Alice', 'Bob', 'Charlie'],
|
|
256
|
+
# 'age': [25, 31, 35],
|
|
257
|
+
# 'city': ['NYC', 'Seattle', 'SF']}
|
|
258
|
+
|
|
259
|
+
# Drop a row
|
|
260
|
+
result = drop_row(data, 0)
|
|
261
|
+
# {'name': ['Bob', 'Charlie'], 'age': [30, 35], 'city': ['LA', 'SF']}
|
|
262
|
+
|
|
263
|
+
# Drop a column
|
|
264
|
+
result = drop_column(data, 'city')
|
|
265
|
+
# {'name': ['Alice', 'Bob', 'Charlie'], 'age': [25, 30, 35]}
|
|
266
|
+
|
|
267
|
+
# Add a column to a table in place
|
|
268
|
+
from tinytim.edit import edit_column_inplace
|
|
269
|
+
edit_column_inplace(data, 'active', [True, False, True])
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### Inserting Data
|
|
273
|
+
|
|
274
|
+
```python
|
|
275
|
+
from tinytim.insert import insert_row, insert_rows
|
|
276
|
+
|
|
277
|
+
data = {'x': [1, 2], 'y': [10, 20]}
|
|
278
|
+
|
|
279
|
+
# Insert a single row
|
|
280
|
+
result = insert_row(data, {'x': 3, 'y': 30})
|
|
281
|
+
# {'x': [1, 2, 3], 'y': [10, 20, 30]}
|
|
282
|
+
|
|
283
|
+
# Insert multiple rows
|
|
284
|
+
rows = [{'x': 4, 'y': 40}, {'x': 5, 'y': 50}]
|
|
285
|
+
result = insert_rows(data, rows)
|
|
286
|
+
# {'x': [1, 2, 4, 5], 'y': [10, 20, 40, 50]}
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
### Advanced Filtering
|
|
290
|
+
|
|
291
|
+
```python
|
|
292
|
+
from tinytim.filter import (
|
|
293
|
+
filter_by_column_eq,
|
|
294
|
+
filter_by_column_ne,
|
|
295
|
+
filter_by_column_le,
|
|
296
|
+
sample
|
|
297
|
+
)
|
|
298
|
+
|
|
299
|
+
data = {'product': ['A', 'B', 'A', 'C', 'B'],
|
|
300
|
+
'price': [10, 20, 15, 30, 25]}
|
|
301
|
+
|
|
302
|
+
# Filter by equality
|
|
303
|
+
result = filter_by_column_eq(data, 'product', 'A')
|
|
304
|
+
# {'product': ['A', 'A'], 'price': [10, 15]}
|
|
305
|
+
|
|
306
|
+
# Filter by inequality
|
|
307
|
+
result = filter_by_column_ne(data, 'product', 'A')
|
|
308
|
+
# {'product': ['B', 'C', 'B'], 'price': [20, 30, 25]}
|
|
309
|
+
|
|
310
|
+
# Filter by less than or equal
|
|
311
|
+
result = filter_by_column_le(data, 'price', 20)
|
|
312
|
+
# {'product': ['A', 'B', 'A'], 'price': [10, 20, 15]}
|
|
313
|
+
|
|
314
|
+
# Random sample
|
|
315
|
+
result = sample(data, 2, random_state=42)
|
|
316
|
+
# Returns 2 random rows (deterministic with random_state)
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
### Copying Data
|
|
320
|
+
|
|
321
|
+
```python
|
|
322
|
+
from tinytim.copy import copy_table, deepcopy_table
|
|
323
|
+
|
|
324
|
+
data = {'x': [1, 2, 3], 'y': [[10], [20], [30]]}
|
|
325
|
+
|
|
326
|
+
# Shallow copy (copies dict and lists)
|
|
327
|
+
copy1 = copy_table(data)
|
|
328
|
+
|
|
329
|
+
# Deep copy (copies everything recursively)
|
|
330
|
+
copy2 = deepcopy_table(data)
|
|
331
|
+
copy2['y'][0][0] = 999
|
|
332
|
+
# Original data unchanged: data['y'][0][0] == 10
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
## Development
|
|
336
|
+
|
|
337
|
+
### Setting up a development environment
|
|
338
|
+
|
|
339
|
+
```bash
|
|
340
|
+
# Clone the repository
|
|
341
|
+
git clone https://github.com/eddiethedean/tinytim.git
|
|
342
|
+
cd tinytim
|
|
343
|
+
|
|
344
|
+
# Install development dependencies
|
|
345
|
+
pip install -e ".[dev,docs]"
|
|
346
|
+
|
|
347
|
+
# Or use the requirements file
|
|
348
|
+
pip install -r requirements_dev.txt
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
### Running Tests
|
|
352
|
+
|
|
353
|
+
```bash
|
|
354
|
+
# Run tests with pytest
|
|
355
|
+
pytest
|
|
356
|
+
|
|
357
|
+
# Run tests with coverage
|
|
358
|
+
pytest --cov-report=xml
|
|
359
|
+
|
|
360
|
+
# Run tests across multiple Python versions
|
|
361
|
+
tox
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
### Linting and Type Checking
|
|
365
|
+
|
|
366
|
+
```bash
|
|
367
|
+
# Lint with ruff
|
|
368
|
+
ruff check src tests
|
|
369
|
+
|
|
370
|
+
# Format code with ruff
|
|
371
|
+
ruff format src tests
|
|
372
|
+
|
|
373
|
+
# Type check with mypy
|
|
374
|
+
mypy src
|
|
375
|
+
|
|
376
|
+
# Build the Sphinx documentation
|
|
377
|
+
python -m sphinx -b html src/tinytim/docs build/docs
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
### Pre-commit Hooks
|
|
381
|
+
|
|
382
|
+
```bash
|
|
383
|
+
# Install pre-commit hooks
|
|
384
|
+
pip install pre-commit
|
|
385
|
+
pre-commit install
|
|
386
|
+
|
|
387
|
+
# Run hooks manually
|
|
388
|
+
pre-commit run --all-files
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
## Examples
|
|
392
|
+
|
|
393
|
+
See the [examples](https://github.com/eddiethedean/tinytim/tree/main/examples) directory for Jupyter notebooks demonstrating various features:
|
|
394
|
+
|
|
395
|
+
- [data.ipynb](https://github.com/eddiethedean/tinytim/blob/main/examples/data.ipynb) - Basic data operations
|
|
396
|
+
- [rows.ipynb](https://github.com/eddiethedean/tinytim/blob/main/examples/rows.ipynb) - Working with rows
|
|
397
|
+
- [columns.ipynb](https://github.com/eddiethedean/tinytim/blob/main/examples/columns.ipynb) - Working with columns
|
|
398
|
+
- [edit.ipynb](https://github.com/eddiethedean/tinytim/blob/main/examples/edit.ipynb) - Editing data
|
|
399
|
+
- [join.ipynb](https://github.com/eddiethedean/tinytim/blob/main/examples/join.ipynb) - Joining datasets
|
|
400
|
+
- [group.ipynb](https://github.com/eddiethedean/tinytim/blob/main/examples/group.ipynb) - Grouping and aggregation
|
|
401
|
+
- [dropna.ipynb](https://github.com/eddiethedean/tinytim/blob/main/examples/dropna.ipynb) - Dropping missing values
|
|
402
|
+
- [fillna.ipynb](https://github.com/eddiethedean/tinytim/blob/main/examples/fillna.ipynb) - Handling missing values
|
|
403
|
+
- [json.ipynb](https://github.com/eddiethedean/tinytim/blob/main/examples/json.ipynb) - Reading and writing JSON
|
|
404
|
+
|
|
405
|
+
## Contributing
|
|
406
|
+
|
|
407
|
+
Contributions are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md) for development, CI, and release instructions.
|
|
408
|
+
|
|
409
|
+
## Releasing
|
|
410
|
+
|
|
411
|
+
Push a `vX.Y.Z` tag matching the package version to run the release workflow. It checks the code, builds the source and wheel distributions, and publishes them to PyPI using Trusted Publishing. Configure the PyPI publisher as described in [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
412
|
+
|
|
413
|
+
## Author
|
|
414
|
+
|
|
415
|
+
**Odos Matthews** - [odosmatthews@gmail.com](mailto:odosmatthews@gmail.com)
|
|
416
|
+
|
|
417
|
+
## License
|
|
418
|
+
|
|
419
|
+
This project is licensed under the MIT License - see the [LICENSE.md](https://github.com/eddiethedean/tinytim/blob/main/LICENSE.md) file for details.
|
|
420
|
+
|
|
421
|
+
## Why TinyTim?
|
|
422
|
+
|
|
423
|
+
TinyTim is ideal for:
|
|
424
|
+
|
|
425
|
+
- **Embedded systems** or environments with limited resources
|
|
426
|
+
- **Lambda functions** or serverless applications where package size matters
|
|
427
|
+
- **Learning** data manipulation concepts without the complexity of Pandas
|
|
428
|
+
- **Scripts** where you need basic data operations without heavy dependencies
|
|
429
|
+
- **Distribution** of tools where you want to minimize user installation burden
|