Randomly remove half the content of Python data structures, like a Thanos snap.
Project description
ThanosPy 🫰
"Perfectly balanced... as all things should be."
thanosPy provides a simple function, snap(), that takes a Python built-in data structure or type and randomly removes approximately half of its contents, returning the result as the same type.
Features
- One Function: Simple
snap(data)interface. - Type Preservation: Output type matches input type (e.g., list in -> list out, tuple in -> tuple out).
- Random Removal: Uses
random.samplefor unbiased removal where applicable. - Supported Types:
list,tuplesetdict(removes key-value pairs)str(removes characters)bytes,bytearray(removes bytes)int(removes ~half the bits from binary representation)float(removes ~half the bits from IEEE 754 representation - Warning: may produce NaN/Inf/unexpected values)bool,None(returned unchanged)
- Python 3.8+
- Type Hinted
Installation
Install directly from PyPI:
pip install thanospy
Or install from the source repository:
pip install git+https://github.com/manyan-chan/thanosPy.git # Update USERNAME/REPO
For local development:
git clone https://github.com/manyan-chan/thanosPy.git # Update USERNAME/REPO
cd thanosPy
pip install -e .[test]
Usage Example
import thanospy
import random
# For reproducibility in example
random.seed(42)
my_list = list(range(10))
print(f"Original List: {my_list}")
snapped_list = thanospy.snap(my_list)
print(f"Snapped List: {snapped_list} (Length: {len(snapped_list)})")
# Example Output: Snapped List: [0, 1, 3, 4, 7] (Length: 5)
my_tuple = tuple(range(1, 11))
print(f"\nOriginal Tuple: {my_tuple}")
snapped_tuple = thanospy.snap(my_tuple)
print(f"Snapped Tuple: {snapped_tuple} (Length: {len(snapped_tuple)})")
# Example Output: Snapped Tuple: (1, 2, 4, 5, 10) (Length: 5)
my_set = set(chr(ord('a') + i) for i in range(8))
print(f"\nOriginal Set: {my_set}")
snapped_set = thanospy.snap(my_set)
print(f"Snapped Set: {snapped_set} (Length: {len(snapped_set)})")
# Example Output: Snapped Set: {'g', 'a', 'd', 'b'} (Length: 4)
my_dict = {i: i*i for i in range(7)}
print(f"\nOriginal Dict: {my_dict}")
snapped_dict = thanospy.snap(my_dict)
print(f"Snapped Dict: {snapped_dict} (Length: {len(snapped_dict)})")
# Example Output: Snapped Dict: {0: 0, 5: 25, 3: 9, 1: 1} (Length: 4)
my_string = "abcdefghijklmnopqrstuvwxyz"
print(f"\nOriginal String: '{my_string}'")
snapped_string = thanospy.snap(my_string)
print(f"Snapped String: '{snapped_string}' (Length: {len(snapped_string)})")
# Example Output: Snapped String: 'abcefhinopqsuwx' (Length: 13) # Corrected based on test seed
my_int = 1234567890
binary_int = bin(my_int)
print(f"\nOriginal Int: {my_int} ({binary_int})")
snapped_int = thanospy.snap(my_int)
binary_snapped_int = bin(snapped_int)
print(f"Snapped Int: {snapped_int} ({binary_snapped_int})")
# Example Output: Snapped Int: 3345 (0b110100010001) # Corrected based on test seed
my_float = 123.456
print(f"\nOriginal Float: {my_float}")
snapped_float = thanospy.snap(my_float)
print(f"Snapped Float: {snapped_float}")
# Example Output: Snapped Float: -1.918078863119037e-178 (Results vary wildly!)
print(f"\nOriginal Bool: {True}")
print(f"Snapped Bool: {thanospy.snap(True)}")
# Example Output: Snapped Bool: True
print(f"\nOriginal None: {None}")
print(f"Snapped None: {thanospy.snap(None)}")
# Example Output: Snapped None: None
# Unsupported type
try:
class Custom: pass
thanospy.snap(Custom())
except TypeError as e:
print(f"\nError for unsupported type: {e}")
# Example Output: Error for unsupported type: Unsupported data type for snap: CustomObject
How Snapping Works
- Sequences/Sets/Dicts: Randomly selects ~50% of the items/keys to keep. The number kept is
ceil(n / 2). - Integers: Converts the absolute value to its binary string representation (e.g.,
10->'1010'). Randomly keepsceil(num_bits / 2)bits. Converts the resulting binary string back to an integer. The original sign is reapplied. - Floats: Gets the IEEE 754 double-precision byte representation, converts to an integer, snaps the bits of that integer using the integer method, converts back to bytes, and then back to a float. Warning: This is a low-level manipulation and frequently results in very small numbers,
NaN,Infinity, or-Infinity. Use with caution! - Bool/None: These types are returned unchanged as "snapping" doesn't apply meaningfully.
Testing
The package uses pytest. To run tests:
- Install test dependencies:
pip install -e .[test] - Run from the root directory:
pytest
Contributing
Contributions (bug reports, feature requests, PRs) are welcome! Please check the GitHub Repository.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file py_thanos_snap-0.1.1-py3-none-any.whl.
File metadata
- Download URL: py_thanos_snap-0.1.1-py3-none-any.whl
- Upload date:
- Size: 7.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
026295143faeda0fd7e16a009c79c448edfc86305428ff6b2112ec6ebeab7dfd
|
|
| MD5 |
96b640d4311c77f32916b742240204ff
|
|
| BLAKE2b-256 |
9c25c6c4ce808343c74185604bf94abf9adf6fb1f5ced6982e3d195f053521e5
|
Provenance
The following attestation bundles were made for py_thanos_snap-0.1.1-py3-none-any.whl:
Publisher:
python-package.yml on manyan-chan/thanosPy
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
py_thanos_snap-0.1.1-py3-none-any.whl -
Subject digest:
026295143faeda0fd7e16a009c79c448edfc86305428ff6b2112ec6ebeab7dfd - Sigstore transparency entry: 197481751
- Sigstore integration time:
-
Permalink:
manyan-chan/thanosPy@5c0aa64ba2c2c49352d5a33098287b6b78c80485 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/manyan-chan
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-package.yml@5c0aa64ba2c2c49352d5a33098287b6b78c80485 -
Trigger Event:
push
-
Statement type: