tinytim 1.11.0__tar.gz → 1.12.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.
Files changed (56) hide show
  1. tinytim-1.12.0/PKG-INFO +387 -0
  2. tinytim-1.12.0/README.md +355 -0
  3. tinytim-1.12.0/pyproject.toml +106 -0
  4. tinytim-1.12.0/setup.py +11 -0
  5. {tinytim-1.11.0 → tinytim-1.12.0/src}/tinytim/__init__.py +4 -4
  6. tinytim-1.12.0/src/tinytim/columns.py +80 -0
  7. {tinytim-1.11.0 → tinytim-1.12.0/src}/tinytim/copy.py +12 -7
  8. tinytim-1.12.0/src/tinytim/custom_types.py +17 -0
  9. {tinytim-1.11.0 → tinytim-1.12.0/src}/tinytim/data.py +46 -39
  10. tinytim-1.12.0/src/tinytim/docs/conf.py +73 -0
  11. {tinytim-1.11.0 → tinytim-1.12.0/src}/tinytim/dropna.py +12 -11
  12. {tinytim-1.11.0 → tinytim-1.12.0/src}/tinytim/edit.py +112 -84
  13. {tinytim-1.11.0 → tinytim-1.12.0/src}/tinytim/fillna.py +38 -43
  14. {tinytim-1.11.0 → tinytim-1.12.0/src}/tinytim/filter.py +9 -10
  15. {tinytim-1.11.0 → tinytim-1.12.0/src}/tinytim/group.py +45 -43
  16. {tinytim-1.11.0 → tinytim-1.12.0/src}/tinytim/insert.py +4 -3
  17. tinytim-1.12.0/src/tinytim/interfaces.py +55 -0
  18. {tinytim-1.11.0 → tinytim-1.12.0/src}/tinytim/isna.py +7 -7
  19. {tinytim-1.11.0 → tinytim-1.12.0/src}/tinytim/join.py +92 -94
  20. {tinytim-1.11.0 → tinytim-1.12.0/src}/tinytim/json.py +12 -12
  21. tinytim-1.12.0/src/tinytim/na.py +4 -0
  22. tinytim-1.12.0/src/tinytim/py.typed +0 -0
  23. {tinytim-1.11.0 → tinytim-1.12.0/src}/tinytim/rows.py +39 -39
  24. tinytim-1.11.0/tinytim/columns.py → tinytim-1.12.0/src/tinytim/sequences.py +45 -122
  25. {tinytim-1.11.0 → tinytim-1.12.0/src}/tinytim/utils.py +16 -17
  26. {tinytim-1.11.0 → tinytim-1.12.0/src}/tinytim/validate.py +7 -5
  27. tinytim-1.12.0/src/tinytim.egg-info/PKG-INFO +387 -0
  28. tinytim-1.12.0/src/tinytim.egg-info/SOURCES.txt +46 -0
  29. tinytim-1.12.0/src/tinytim.egg-info/requires.txt +8 -0
  30. tinytim-1.12.0/tests/test_columns.py +16 -0
  31. tinytim-1.12.0/tests/test_copy.py +141 -0
  32. tinytim-1.12.0/tests/test_data.py +135 -0
  33. tinytim-1.12.0/tests/test_edit.py +309 -0
  34. tinytim-1.12.0/tests/test_filter.py +322 -0
  35. tinytim-1.12.0/tests/test_group.py +278 -0
  36. tinytim-1.12.0/tests/test_insert.py +106 -0
  37. tinytim-1.12.0/tests/test_isna.py +260 -0
  38. tinytim-1.12.0/tests/test_join.py +172 -0
  39. tinytim-1.12.0/tests/test_json.py +35 -0
  40. tinytim-1.12.0/tests/test_na.py +635 -0
  41. tinytim-1.12.0/tests/test_rows.py +214 -0
  42. tinytim-1.12.0/tests/test_sequences.py +226 -0
  43. tinytim-1.12.0/tests/test_utils.py +227 -0
  44. tinytim-1.12.0/tests/test_validate.py +67 -0
  45. tinytim-1.11.0/PKG-INFO +0 -51
  46. tinytim-1.11.0/README.md +0 -36
  47. tinytim-1.11.0/setup.py +0 -27
  48. tinytim-1.11.0/tinytim/na.py +0 -3
  49. tinytim-1.11.0/tinytim/types.py +0 -14
  50. tinytim-1.11.0/tinytim.egg-info/PKG-INFO +0 -51
  51. tinytim-1.11.0/tinytim.egg-info/SOURCES.txt +0 -26
  52. tinytim-1.11.0/tinytim.egg-info/requires.txt +0 -2
  53. {tinytim-1.11.0 → tinytim-1.12.0}/LICENSE.md +0 -0
  54. {tinytim-1.11.0 → tinytim-1.12.0}/setup.cfg +0 -0
  55. {tinytim-1.11.0 → tinytim-1.12.0/src}/tinytim.egg-info/dependency_links.txt +0 -0
  56. {tinytim-1.11.0 → tinytim-1.12.0/src}/tinytim.egg-info/top_level.txt +0 -0
@@ -0,0 +1,387 @@
1
+ Metadata-Version: 2.1
2
+ Name: tinytim
3
+ Version: 1.12.0
4
+ Summary: Pure Python data table functions.
5
+ Author-email: Odos Matthews <odosmatthews@gmail.com>
6
+ License: 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: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3 :: Only
16
+ Classifier: Programming Language :: Python :: 3.8
17
+ Classifier: Programming Language :: Python :: 3.9
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
22
+ Requires-Python: >=3.8
23
+ Description-Content-Type: text/markdown
24
+ License-File: LICENSE.md
25
+ Requires-Dist: hasattrs>=0.0.2
26
+ Provides-Extra: dev
27
+ Requires-Dist: pytest>=8.3.0; extra == "dev"
28
+ Requires-Dist: pytest-cov>=5.0.0; extra == "dev"
29
+ Requires-Dist: mypy>=1.11.0; extra == "dev"
30
+ Requires-Dist: ruff>=0.6.0; extra == "dev"
31
+ Requires-Dist: tox>=4.0.0; extra == "dev"
32
+
33
+ # TinyTim
34
+
35
+ A pure Python package for processing tabular data stored in dictionaries.
36
+
37
+ [![PyPI Latest Release](https://img.shields.io/pypi/v/tinytim.svg)](https://pypi.org/project/tinytim/)
38
+ ![Tests](https://github.com/eddiethedean/tinytim/actions/workflows/tests.yml/badge.svg)
39
+ [![Python Version](https://img.shields.io/pypi/pyversions/tinytim.svg)](https://pypi.org/project/tinytim/)
40
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
41
+
42
+ ## Description
43
+
44
+ TinyTim is a lightweight alternative to Pandas for processing tabular data. It's perfect for when you want to work with structured data but don't want to install Pandas and its many dependencies. TinyTim has **zero dependencies** outside of Python's standard library.
45
+
46
+ Data is stored in a simple dictionary format: `{column_name: column_values}`, making it easy to understand and work with.
47
+
48
+ ## Features
49
+
50
+ - **Zero dependencies** - Pure Python implementation
51
+ - **Lightweight** - Minimal footprint, fast installation
52
+ - **Familiar API** - Intuitive functions for data manipulation
53
+ - **Type hints** - Full type annotations for better IDE support
54
+ - **Well tested** - Comprehensive test suite
55
+
56
+ ## Installation
57
+
58
+ ```bash
59
+ pip install tinytim
60
+ ```
61
+
62
+ ## Requirements
63
+
64
+ - Python >= 3.8
65
+
66
+ ## Quick Start
67
+
68
+ ### Basic Data Operations
69
+
70
+ ```python
71
+ from tinytim.data import column_count, row_count, shape, head, tail
72
+
73
+ # Data is stored as {column_name: column_values}
74
+ data = {'x': [1, 2, 3, 4], 'y': [10, 20, 30, 40]}
75
+
76
+ # Get basic information
77
+ column_count(data)
78
+ # 2
79
+
80
+ row_count(data)
81
+ # 4
82
+
83
+ shape(data)
84
+ # (4, 2)
85
+
86
+ # Preview data
87
+ head(data, 2)
88
+ # {'x': [1, 2], 'y': [10, 20]}
89
+
90
+ tail(data, 2)
91
+ # {'x': [3, 4], 'y': [30, 40]}
92
+ ```
93
+
94
+ ### Working with Rows
95
+
96
+ ```python
97
+ from tinytim.rows import row_dict, iterrows, row_dicts_to_data
98
+
99
+ data = {'x': [1, 2, 3], 'y': [6, 7, 8]}
100
+
101
+ # Get a single row
102
+ row_dict(data, 1)
103
+ # {'x': 2, 'y': 7}
104
+
105
+ # Iterate over rows
106
+ for index, row in iterrows(data):
107
+ print(f"Row {index}: {row}")
108
+ # Row 0: {'x': 1, 'y': 6}
109
+ # Row 1: {'x': 2, 'y': 7}
110
+ # Row 2: {'x': 3, 'y': 8}
111
+
112
+ # Convert row dictionaries to data
113
+ rows = [{'x': 1, 'y': 20}, {'x': 2, 'y': 21}, {'x': 3, 'y': 22}]
114
+ result = row_dicts_to_data(rows)
115
+ # {'x': [1, 2, 3], 'y': [20, 21, 22]}
116
+ ```
117
+
118
+ ### Working with Columns
119
+
120
+ ```python
121
+ from tinytim.edit import add_to_column, multiply_column
122
+
123
+ data = {'x': [1, 2, 3, 4], 'y': [5, 6, 7, 8]}
124
+
125
+ # Add to a column
126
+ result = add_to_column(data, 'x', 10)
127
+ # {'x': [11, 12, 13, 14], 'y': [5, 6, 7, 8]}
128
+
129
+ # Multiply a column
130
+ result = multiply_column(data, 'x', 2)
131
+ # {'x': [2, 4, 6, 8], 'y': [5, 6, 7, 8]}
132
+
133
+ # Column-wise operations with sequences
134
+ result = add_to_column(data, 'x', [10, 20, 30, 40])
135
+ # {'x': [11, 22, 33, 44], 'y': [5, 6, 7, 8]}
136
+ ```
137
+
138
+ ### Filtering and Selection
139
+
140
+ ```python
141
+ from tinytim.filter import filter_by_column_gt, filter_by_column_isin
142
+
143
+ data = {'x': [1, 2, 3, 4, 5], 'y': [10, 20, 30, 40, 50]}
144
+
145
+ # Filter rows where column value is greater than threshold
146
+ filtered = filter_by_column_gt(data, 'x', 2)
147
+ # {'x': [3, 4, 5], 'y': [30, 40, 50]}
148
+
149
+ # Filter rows where column value is in a list
150
+ filtered = filter_by_column_isin(data, 'x', [1, 3, 5])
151
+ # {'x': [1, 3, 5], 'y': [10, 30, 50]}
152
+ ```
153
+
154
+ ### Handling Missing Values
155
+
156
+ ```python
157
+ from tinytim.na import isna, dropna, fillna
158
+
159
+ data = {'x': [1, None, 3], 'y': [10, 20, None]}
160
+
161
+ # Check for missing values
162
+ isna(data)
163
+ # {'x': [False, True, False], 'y': [False, False, True]}
164
+
165
+ # Drop rows with missing values
166
+ dropna(data)
167
+ # {'x': [1], 'y': [10]}
168
+
169
+ # Fill missing values
170
+ fillna(data, 0)
171
+ # {'x': [1, 0, 3], 'y': [10, 20, 0]}
172
+
173
+ # Forward fill
174
+ data2 = {'x': [None, 2, None, 4], 'y': [10, None, None, 40]}
175
+ fillna(data2, method='ffill')
176
+ # {'x': [None, 2, 2, 4], 'y': [10, 10, 10, 40]}
177
+ ```
178
+
179
+ ### Grouping and Aggregation
180
+
181
+ ```python
182
+ from tinytim.group import groupby, sum_groups
183
+
184
+ data = {'category': ['A', 'B', 'A', 'B'], 'value': [1, 2, 3, 4]}
185
+
186
+ # Group by column
187
+ groups = groupby(data, 'category')
188
+ # [('A', {'category': ['A', 'A'], 'value': [1, 3]}),
189
+ # ('B', {'category': ['B', 'B'], 'value': [2, 4]})]
190
+
191
+ # Sum grouped data
192
+ labels, sums = sum_groups(groups)
193
+ # labels: ['A', 'B']
194
+ # sums: {'value': [4, 6]}
195
+ ```
196
+
197
+ ### Joining Data
198
+
199
+ ```python
200
+ from tinytim.join import inner_join, left_join
201
+
202
+ left = {'id': [1, 2, 3], 'value': ['a', 'b', 'c']}
203
+ right = {'id': [2, 3, 4], 'score': [10, 20, 30]}
204
+
205
+ # Inner join on 'id' column
206
+ result = inner_join(left, right, 'id')
207
+ # {'id': [2, 3], 'value': ['b', 'c'], 'score': [10, 20]}
208
+
209
+ # Left join keeps all rows from left table
210
+ result = left_join(left, right, 'id')
211
+ # {'id': [1, 2, 3], 'value': ['a', 'b', 'c'], 'score': [None, 10, 20]}
212
+ ```
213
+
214
+ ## More Examples
215
+
216
+ ### Editing Data
217
+
218
+ ```python
219
+ from tinytim.edit import edit_row_items, drop_row, drop_column
220
+
221
+ data = {'name': ['Alice', 'Bob', 'Charlie'],
222
+ 'age': [25, 30, 35],
223
+ 'city': ['NYC', 'LA', 'SF']}
224
+
225
+ # Edit specific row values
226
+ result = edit_row_items(data, 1, {'age': 31, 'city': 'Seattle'})
227
+ # {'name': ['Alice', 'Bob', 'Charlie'],
228
+ # 'age': [25, 31, 35],
229
+ # 'city': ['NYC', 'Seattle', 'SF']}
230
+
231
+ # Drop a row
232
+ result = drop_row(data, 0)
233
+ # {'name': ['Bob', 'Charlie'], 'age': [30, 35], 'city': ['LA', 'SF']}
234
+
235
+ # Drop a column
236
+ result = drop_column(data, 'city')
237
+ # {'name': ['Alice', 'Bob', 'Charlie'], 'age': [25, 30, 35]}
238
+ ```
239
+
240
+ ### Inserting Data
241
+
242
+ ```python
243
+ from tinytim.insert import insert_row, insert_rows
244
+
245
+ data = {'x': [1, 2], 'y': [10, 20]}
246
+
247
+ # Insert a single row
248
+ result = insert_row(data, {'x': 3, 'y': 30})
249
+ # {'x': [1, 2, 3], 'y': [10, 20, 30]}
250
+
251
+ # Insert multiple rows
252
+ rows = [{'x': 4, 'y': 40}, {'x': 5, 'y': 50}]
253
+ result = insert_rows(data, rows)
254
+ # {'x': [1, 2, 4, 5], 'y': [10, 20, 40, 50]}
255
+ ```
256
+
257
+ ### Advanced Filtering
258
+
259
+ ```python
260
+ from tinytim.filter import (
261
+ filter_by_column_eq,
262
+ filter_by_column_ne,
263
+ filter_by_column_le,
264
+ sample
265
+ )
266
+
267
+ data = {'product': ['A', 'B', 'A', 'C', 'B'],
268
+ 'price': [10, 20, 15, 30, 25]}
269
+
270
+ # Filter by equality
271
+ result = filter_by_column_eq(data, 'product', 'A')
272
+ # {'product': ['A', 'A'], 'price': [10, 15]}
273
+
274
+ # Filter by inequality
275
+ result = filter_by_column_ne(data, 'product', 'A')
276
+ # {'product': ['B', 'C', 'B'], 'price': [20, 30, 25]}
277
+
278
+ # Filter by less than or equal
279
+ result = filter_by_column_le(data, 'price', 20)
280
+ # {'product': ['A', 'B', 'A'], 'price': [10, 20, 15]}
281
+
282
+ # Random sample
283
+ result = sample(data, 2, random_state=42)
284
+ # Returns 2 random rows (deterministic with random_state)
285
+ ```
286
+
287
+ ### Copying Data
288
+
289
+ ```python
290
+ from tinytim.copy import copy_table, deepcopy_table
291
+
292
+ data = {'x': [1, 2, 3], 'y': [[10], [20], [30]]}
293
+
294
+ # Shallow copy (copies dict and lists)
295
+ copy1 = copy_table(data)
296
+
297
+ # Deep copy (copies everything recursively)
298
+ copy2 = deepcopy_table(data)
299
+ copy2['y'][0][0] = 999
300
+ # Original data unchanged: data['y'][0][0] == 10
301
+ ```
302
+
303
+ ## Development
304
+
305
+ ### Setting up a development environment
306
+
307
+ ```bash
308
+ # Clone the repository
309
+ git clone https://github.com/eddiethedean/tinytim.git
310
+ cd tinytim
311
+
312
+ # Install development dependencies
313
+ pip install -e ".[dev]"
314
+
315
+ # Or use the requirements file
316
+ pip install -r requirements_dev.txt
317
+ ```
318
+
319
+ ### Running Tests
320
+
321
+ ```bash
322
+ # Run tests with pytest
323
+ pytest
324
+
325
+ # Run tests with coverage
326
+ pytest --cov=tinytim
327
+
328
+ # Run tests across multiple Python versions
329
+ tox
330
+ ```
331
+
332
+ ### Linting and Type Checking
333
+
334
+ ```bash
335
+ # Lint with ruff
336
+ ruff check src tests
337
+
338
+ # Format code with ruff
339
+ ruff format src tests
340
+
341
+ # Type check with mypy
342
+ mypy src
343
+ ```
344
+
345
+ ### Pre-commit Hooks
346
+
347
+ ```bash
348
+ # Install pre-commit hooks
349
+ pip install pre-commit
350
+ pre-commit install
351
+
352
+ # Run hooks manually
353
+ pre-commit run --all-files
354
+ ```
355
+
356
+ ## Examples
357
+
358
+ See the [examples](https://github.com/eddiethedean/tinytim/tree/main/examples) directory for Jupyter notebooks demonstrating various features:
359
+
360
+ - [data.ipynb](https://github.com/eddiethedean/tinytim/blob/main/examples/data.ipynb) - Basic data operations
361
+ - [rows.ipynb](https://github.com/eddiethedean/tinytim/blob/main/examples/rows.ipynb) - Working with rows
362
+ - [columns.ipynb](https://github.com/eddiethedean/tinytim/blob/main/examples/columns.ipynb) - Working with columns
363
+ - [join.ipynb](https://github.com/eddiethedean/tinytim/blob/main/examples/join.ipynb) - Joining datasets
364
+ - [group.ipynb](https://github.com/eddiethedean/tinytim/blob/main/examples/group.ipynb) - Grouping and aggregation
365
+ - [fillna.ipynb](https://github.com/eddiethedean/tinytim/blob/main/examples/fillna.ipynb) - Handling missing values
366
+
367
+ ## Contributing
368
+
369
+ Contributions are welcome! Please feel free to submit a Pull Request.
370
+
371
+ ## Author
372
+
373
+ **Odos Matthews** - [odosmatthews@gmail.com](mailto:odosmatthews@gmail.com)
374
+
375
+ ## License
376
+
377
+ This project is licensed under the MIT License - see the [LICENSE.md](https://github.com/eddiethedean/tinytim/blob/main/LICENSE.md) file for details.
378
+
379
+ ## Why TinyTim?
380
+
381
+ TinyTim is ideal for:
382
+
383
+ - **Embedded systems** or environments with limited resources
384
+ - **Lambda functions** or serverless applications where package size matters
385
+ - **Learning** data manipulation concepts without the complexity of Pandas
386
+ - **Scripts** where you need basic data operations without heavy dependencies
387
+ - **Distribution** of tools where you want to minimize user installation burden