Lightweight, fun named utilities for number formatting, unit conversions and unix time handling.
Project description
๐ No Weird Utils
๐ฏ Lightweight, fun-named utilities for number formatting, unit conversions, and Unix time handling - because nobody likes weird numbers!
No Weird Utils is a comprehensive Python package that makes working with numbers, units, and time a breeze. Say goodbye to cryptic variable names and hello to intuitive, powerful tools that just work.
โจ Features
๐ noWeirdNumbersPls - Smart Number Formatting
- ๐ Flexible separators: Use any thousands/decimal separators (European style:
1.234.567,89) - ๐จ Multiple styles: Default, scientific, percentage, binary, hex, and even Roman numerals!
- ๐ Bidirectional: Format numbers for display and parse them back to numeric types
- ๐ Batch processing: Handle individual numbers or entire collections (lists, tuples, sets)
- ๐ง Precision control:
set_decimals()function for precise decimal rounding - ๐ Fluent Interface: Object-oriented
NotWeirdclass with chainable methods - ๐ฏ Smart Locale Support: Built-in
anglo()andnotAnglo()formatting presets - ๐ Method Chaining: Combine operations like
.notAnglo().add_prefix('โฌ').with_decimals(2) - ๐ Rich Properties: Access formatted values via properties like
.formatted,.raw_default, etc.
๐ metricFTW - Universal Unit Converter
- ๐ Length: From picometers to light-years, millimeters to miles
- โ๏ธ Mass: Picograms to tons, ounces to kilograms
- ๐ Area: Square millimeters to square miles, hectares to acres
- ๐ Volume: Milliliters to barrels, gallons to liters
- ๐ Speed: m/s to mph, km/h to knots
- โก Energy: Joules to BTU, calories to kilowatt-hours
- ๐จ Pressure: Pascals to atmospheres, PSI to bars
- ๐ Power: Watts to horsepower, kilowatts to BTU/hour
- ๐ก๏ธ Temperature: Celsius, Fahrenheit, Kelvin, and Rankine
- ๐ Batch conversions: Convert entire datasets at once
โฐ quanticTime - Intuitive Unix Time Handling
- ๐ Smart parsing: Auto-detect common date/time formats
- ๐ Timezone aware: Full pytz integration with 400+ timezones
- ๐ Format flexibility: Parse and output in any format you need
- ๐ Date arithmetic: Add/subtract time periods effortlessly
- ๐ Relative formatting: "2 hours ago", "in 3 days", etc.
๐ Quick Start
Installation
pip install noWeirdUtils
For enhanced features:
# With timezone support
pip install noWeirdUtils[timezone]
๐ฏ Number Formatting Examples
from noWeirdNumbersPls.format_number import format_number, deformat_number, set_decimals, NotWeird
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
# ๐ฅ NEW: Object-Oriented Fluent Interface with NotWeird Class
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
# Create a NotWeird instance with chainable methods
nw = NotWeird(1234567.89)
# Chain formatting operations - settings persist on the object
formatted = nw.notAnglo().add_prefix('โฌ').with_decimals(2).default()
print(formatted) # "โฌ1.234.567,89"
# Use different styles with the same settings
print(nw.percent()) # "โฌ123456789,00%"
print(nw.scientific()) # "โฌ1.234568e+06"
print(nw.binary()) # "โฌ0b100101101011010000111"
# Temporary override without changing object settings
print(nw.default(prefix='$')) # "$1.234.567,89"
print(nw.default()) # "โฌ1.234.567,89" (back to stored prefix)
# Rich property access for formatted values
print(nw.formatted) # "โฌ1.234.567,89" (fully formatted with prefix/suffix)
print(nw.raw_default) # "1.234.567,89" (without prefix/suffix)
print(nw.formatted_percent) # "โฌ123456789,00%"
print(nw.formatted_scientific) # "โฌ1.234568e+06"
# Parse formatted strings back to NotWeird objects
parsed_nw = NotWeird.parse("โฌ1.234.567,89", thou_sep='.', dec_sep=',', prefix='โฌ')
print(parsed_nw.number) # 1234567.89
# Apply precise rounding to the underlying number
nw.precise(decimals=1) # Modifies the internal number
print(nw.number) # 1234567.9
# Quick locale switching
nw.anglo() # Switch to US/UK format (, for thousands, . for decimal)
print(nw.default()) # "โฌ1,234,567.9"
nw.notAnglo() # Switch to European format (. for thousands, , for decimal)
print(nw.default()) # "โฌ1.234.567,9"
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
# ๐ Traditional Function-Based API (Still Available)
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
# European-style formatting
number = 1234567.89
formatted = format_number(number, thou_sep='.', dec_sep=',')
print(formatted) # "1.234.567,89"
# Multiple styles
print(format_number(0.1234, style='percent')) # "12.34%"
print(format_number(1000000, style='scientific')) # "1.000000e+06"
print(format_number(255, style='hex')) # "0xff"
print(format_number(42, style='roman')) # "XLII"
# With prefix and suffix
price = format_number(1299.99, prefix='$', suffix=' USD', decimals=2)
print(price) # "$1,299.99 USD"
# Batch processing
prices = [99.99, 149.50, 1299.99]
formatted_prices = format_number(prices, prefix='โฌ', thou_sep='.', dec_sep=',')
print(formatted_prices) # ['โฌ99,99', 'โฌ149,50', 'โฌ1.299,99']
# Parse back to numbers
parsed = deformat_number("1.234.567,89", thou_sep='.', dec_sep=',')
print(parsed) # 1234567.89
# Parse with type enforcement
parsed_int = deformat_number("1.234", thou_sep='.', enforce_type=int)
print(parsed_int) # 1234
# Parse special formats
hex_number = deformat_number("0xff", style='hex')
print(hex_number) # 255
roman_number = deformat_number("XLII", style='roman')
print(roman_number) # 42
# Precise decimal control
precise = set_decimals(3.14159265359, decimals=3)
print(precise) # 3.142
# Works with strings too
precise_str = set_decimals("2.71828", decimals=2, force_float=True)
print(precise_str) # 2.72
๐ Unit Conversion Examples
from metricFTW.converter import MetricFTW
converter = MetricFTW()
# Length conversions
print(converter.convert_longitude(100, 'cm', 'm')) # 1.0
print(converter.convert_longitude(1, 'mile', 'km')) # 1.609344
# Mass conversions
print(converter.convert_mass(1, 'kg', 'pound')) # 2.20462
print(converter.convert_mass(16, 'ounce', 'g')) # 453.592
# Temperature conversions
print(converter.convert_temperature(0, 'C', 'F')) # 32.0
print(converter.convert_temperature(100, 'C', 'K')) # 373.15
# Volume conversions
print(converter.convert_volume(1, 'gallon_us', 'l')) # 3.78541
print(converter.convert_volume(500, 'ml', 'cup')) # 2.083333
# Batch conversions
distances = [1, 5, 10, 26.2]
km_distances = converter.convert_longitude(distances, 'mile', 'km')
print(km_distances) # [1.609344, 8.04672, 16.09344, 42.164928]
# See all available conversions
converter.show_available_conversions(detailed=True)
โฐ Time Handling Examples
from quanticTime.core import QuanticTime
# Create from various sources
qt1 = QuanticTime(1640995200) # Unix timestamp
qt2 = QuanticTime.now() # Current time
qt3 = QuanticTime.today() # Today at midnight
qt4 = QuanticTime.from_string("2024-01-01 10:30:00", fmt="%Y-%m-%d %H:%M:%S")
# Auto-parse common formats
qt5 = QuanticTime("2024-01-01")
qt6 = QuanticTime("2024-01-01 15:30:00")
qt7 = QuanticTime("Jan 1, 2024")
# Format output
print(qt2.to_string("%Y-%m-%d %H:%M:%S"))
print(qt2.to_iso())
# Time arithmetic
future = qt2.add_seconds(3600) # Add 1 hour
past = qt2.add_days(-7) # Subtract 7 days
# Get datetime object with timezone
dt_santiago = qt2.to_datetime("America/Santiago")
dt_tokyo = qt2.to_datetime("Asia/Tokyo")
# Check properties
print(qt2.is_weekend())
start_day = qt2.start_of_day()
end_day = qt2.end_of_day()
# List available timezones
QuanticTime.print_timezones(show_common_only=True)
QuanticTime.print_timezones(filter_text="Chile", detailed=True)
๐ Detailed Documentation
๐จ Number Formatting Styles
| Style | Example Input | Example Output | Description |
|---|---|---|---|
default |
1234.56 |
"1,234.56" |
Standard formatting with separators |
scientific |
1234.56 |
"1.234560e+03" |
Scientific notation |
percent |
0.1234 |
"12.34%" |
Percentage format |
binary |
255 |
"0b11111111" |
Binary representation |
hex |
255 |
"0xff" |
Hexadecimal representation |
roman |
42 |
"XLII" |
Roman numerals (integers only) |
๐ Supported Unit Categories
๐ Length Units
Metric: pm, nm, ฮผm, mm, cm, dm, m, dam, hm, km Imperial/Other: inch, foot, yard, mile, nautical_mile, angstrom, mil, furlong, fathom, light_year, parsec, astronomical_unit
โ๏ธ Mass Units
Metric: pg, ng, ฮผg, mg, cg, dg, g, dag, hg, kg, t Imperial/Other: ounce, pound, stone, ton_us, ton_uk, grain, dram, troy_ounce, carat, slug
๐ Area Units
Metric: mmยฒ, cmยฒ, dmยฒ, mยฒ, damยฒ, hmยฒ, kmยฒ Imperial/Other: sqin, sqft, sqyd, acre, hectare, sqmile, barn, are, rood
๐ Volume Units
Metric: mmยณ, cmยณ, dmยณ, mยณ, l, ml, cl, dl, dal, hl, kl Imperial/Other: gallon_us, gallon_uk, quart, pint, cup, fluid_ounce, cubic_inch, tablespoon, teaspoon, barrel_oil, bushel
๐ Speed Units
Metric: mm/s, cm/s, m/s, km/h Imperial/Other: mph, knot, fps, mach
โก Energy Units
J, kJ, MJ, GJ, TJ, cal, kcal, Btu, kWh, eV, erg, therm, quad
๐จ Pressure Units
Pa, kPa, MPa, bar, mbar, atm, psi, torr, mmHg, inHg
๐ Power Units
W, kW, MW, GW, hp, Btu_h, cal_s, erg_s
โฐ Time Zone Support
QuanticTime supports 400+ time zones through pytz integration. Some examples:
- Americas:
America/New_York,America/Los_Angeles,America/Santiago,America/Mexico_City - Europe:
Europe/London,Europe/Paris,Europe/Berlin,Europe/Madrid - Asia:
Asia/Tokyo,Asia/Shanghai,Asia/Dubai,Asia/Kolkata - Oceania:
Australia/Sydney,Australia/Melbourne,Pacific/Auckland - Special:
UTC,GMT,US/Eastern,US/Pacific
๐ ๏ธ Advanced Usage
Custom Number Formatting Functions
from noWeirdNumbersPls.format_number import format_number, set_decimals, NotWeird
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
# ๐ฅ NEW: Advanced NotWeird Class Usage
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
def create_currency_formatter(currency="USD", european_style=False):
"""Factory function to create currency formatters with consistent settings."""
if european_style:
return NotWeird(0).notAnglo().add_prefix(f'{currency} ')
else:
return NotWeird(0).anglo().add_prefix(f'{currency}')
# Create reusable formatters
eur_formatter = create_currency_formatter("EUR", european_style=True)
usd_formatter = create_currency_formatter("USD", european_style=False)
# Use the formatters with different amounts
amounts = [1234.56, 9876.54, 15000.00]
for amount in amounts:
eur_formatter._number = amount # Update the number
usd_formatter._number = amount
print(f"EUR: {eur_formatter.with_decimals(2).default()}") # "EUR 1.234,56"
print(f"USD: {usd_formatter.with_decimals(2).default()}") # "USD1,234.56"
# Complex chaining example
nw = NotWeird(3.14159265359)
result = (nw.precise(decimals=3) # First apply precision
.notAnglo() # Then set European format
.add_prefix('ฯ โ ') # Add mathematical prefix
.add_suffix(' (rounded)')) # Add descriptive suffix
print(result.default()) # "ฯ โ 3,142 (rounded)"
# Working with collections using NotWeird
prices = [99.99, 149.50, 1299.99]
formatter = NotWeird(prices).notAnglo().add_prefix('โฌ').with_decimals(2)
formatted_list = formatter.default()
print(formatted_list) # ['โฌ99,99', 'โฌ149,50', 'โฌ1.299,99']
# Property-based access for different formats
sales_data = NotWeird(1234567.89).notAnglo().add_prefix('โฌ')
print(f"Default: {sales_data.formatted}")
print(f"Percentage: {sales_data.formatted_percent}")
print(f"Scientific: {sales_data.formatted_scientific}")
print(f"Raw (no prefix): {sales_data.raw_default}")
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
# ๐ Traditional Function-Based Approach
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
def format_currency(amount, currency="USD", european_style=False):
"""Format currency with locale-specific rules."""
if european_style:
return format_number(amount, thou_sep='.', dec_sep=',',
prefix=f'{currency} ', decimals=2)
else:
return format_number(amount, thou_sep=',', dec_sep='.',
prefix=f'{currency}', decimals=2)
# European format
print(format_currency(1234.56, "EUR", european_style=True)) # "EUR 1.234,56"
# US format
print(format_currency(1234.56, "USD", european_style=False)) # "USD1,234.56"
# Use set_decimals for precise rounding
precise_number = set_decimals(3.14159265359, decimals=3)
print(precise_number) # 3.142
Chained Unit Conversions
from metricFTW.converter import MetricFTW
converter = MetricFTW()
# Convert a recipe from US to metric
ingredients = {
'flour': (2, 'cup'), # cups to grams (approximately)
'milk': (1, 'cup'), # cups to ml
'temperature': (350, 'F') # Fahrenheit to Celsius
}
# Note: For cooking conversions, you might want to use density conversions
flour_ml = converter.convert_volume(ingredients['flour'][0], 'cup', 'ml')
milk_ml = converter.convert_volume(ingredients['milk'][0], 'cup', 'ml')
temp_c = converter.convert_temperature(ingredients['temperature'][0], 'F', 'C')
print(f"Flour: {flour_ml} ml") # Flour: 480.0 ml
print(f"Milk: {milk_ml} ml") # Milk: 240.0 ml
print(f"Temperature: {temp_c}ยฐC") # Temperature: 176.66666666666666ยฐC
Complex Time Operations
from quanticTime.core import QuanticTime
# Create a meeting scheduler
meeting_utc = QuanticTime.from_string("2024-03-15 14:00:00", tz="UTC")
# Show meeting time in different time zones
timezones = ["America/New_York", "Europe/London", "Asia/Tokyo", "America/Santiago"]
for tz in timezones:
local_time = meeting_utc.to_datetime(tz)
formatted_time = meeting_utc.to_string('%Y-%m-%d %H:%M %Z', tz)
print(f"{tz}: {formatted_time}")
# Calculate time until meeting
now = QuanticTime.now()
time_diff = meeting_utc.difference(now)
hours_until = time_diff / 3600
if hours_until > 0:
print(f"Meeting in {hours_until:.1f} hours")
else:
print(f"Meeting was {abs(hours_until):.1f} hours ago")
# Working with time ranges
start_day = meeting_utc.start_of_day()
end_day = meeting_utc.end_of_day()
is_weekend = meeting_utc.is_weekend("America/Santiago")
๐งช Testing
The package includes comprehensive tests to ensure reliability and accuracy. For detailed testing information, see TESTING.md.
Quick Test Commands
# Install development dependencies
pip install pytest pytest-cov
# Run all tests
pytest tests/
# Run tests with verbose output
pytest tests/ -v
# Run with coverage report
pytest tests/ --cov=metricFTW --cov=noWeirdNumbersPls --cov=quanticTime --cov-report=html
# Use the convenient test runner
python run_tests.py --coverage --verbose
Test Coverage
Current test coverage:
- metricFTW: 75% coverage
- noWeirdNumbersPls: 58% coverage
- quanticTime: 89% coverage
- Overall: 73% coverage
Test Categories
- Unit Tests: Test individual functions and classes
- Integration Tests: Test component interactions
- Verification Tests: Test against known accurate values
- Property Tests: Test object properties and formatting
๐ค Contributing
We welcome contributions! Here's how to get started:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes
- Run the tests (
python run_tests.py) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Please ensure:
- All tests pass
- New features include tests
- Code follows the existing style
- Documentation is updated as needed
Development Setup
# Clone the repository
git clone https://github.com/santiago897/no_weird_project.git
cd no_weird_project
# Install in development mode with all dependencies
poetry install --with test
# Or with pip
pip install -e .[test]
# Run tests
python run_tests.py
1. **Fork the repository**
2. **Create a feature branch**: `git checkout -b feature/amazing-feature`
3. **Make your changes** and add tests
4. **Run the test suite**: `pytest tests/`
5. **Commit your changes**: `git commit -m 'Add amazing feature'`
6. **Push to the branch**: `git push origin feature/amazing-feature`
7. **Open a Pull Request**
### Development Setup
```bash
# Clone the repo
git clone https://github.com/santiago897/no_weird_project.git
cd no_weird_project
# Install with development dependencies
pip install -e .[timezone]
pip install pytest pytest-cov black flake8
# Run tests
pytest tests/
# Format code
black .
๐ Requirements
- Python 3.8+
- Optional dependencies:
pytz ^2025.2: For timezone support in quanticTime
๐ License
This project is licensed under the MIT License - see the LICENSE file for details.
๐ Acknowledgments
- pytz - Special thanks to Stuart Bishop and the pytz team for creating and maintaining this incredible timezone library. pytz provides accurate and up-to-date timezone calculations for Python, making QuanticTime's timezone conversions possible across 400+ timezones worldwide. Without pytz, handling timezone-aware datetime operations would be significantly more complex and error-prone.
- Poetry for elegant dependency management and packaging
- The Python community for inspiration, feedback, and continuous innovation
๐ Links
- PyPI: https://pypi.org/project/no-weird-utils/
- GitHub: https://github.com/santiago897/no_weird_project
- Documentation: Coming soon!
- Issues: https://github.com/santiago897/no_weird_project/issues
Made with โค๏ธ by Santiago Matta
"Because life's too short for weird numbers!" ๐ฏ
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
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 noweirdutils-0.2.0.tar.gz.
File metadata
- Download URL: noweirdutils-0.2.0.tar.gz
- Upload date:
- Size: 25.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.9.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9b6cfad9ad3070e0fc5bf2b276e6d4d148b0d2511a8ef9d1fc3adf01cad18930
|
|
| MD5 |
c8e1e51fc92e58089d79f5b68f1dfb58
|
|
| BLAKE2b-256 |
a66fb598b4676ba69898836b2aea43b3067e9d1ae0b39ac6d01a1dec4e320858
|
File details
Details for the file noweirdutils-0.2.0-py3-none-any.whl.
File metadata
- Download URL: noweirdutils-0.2.0-py3-none-any.whl
- Upload date:
- Size: 25.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.9.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
91b75449d86b547deae194c2ce3ac2e8d2b9a9d11017e19cd61f24e78d2ba683
|
|
| MD5 |
5c3c3ba416a6af29cad40d5e11d39063
|
|
| BLAKE2b-256 |
31e13c13a51380a3f192993484c22ba275731c3c8161c5c89ada25e2f0cd2bda
|