Claude Code for Pint: Python Physical Units and Quantities — Claude Skills 360 Blog
Blog / AI / Claude Code for Pint: Python Physical Units and Quantities
AI

Claude Code for Pint: Python Physical Units and Quantities

Published: February 28, 2028
Read time: 5 min read
By: Claude Skills 360

Pint performs arithmetic with physical units and converts between them. pip install pint. Setup: from pint import UnitRegistry; ureg = UnitRegistry(); Q_ = ureg.Quantity. Create: distance = 5 * ureg.meter. velocity = Q_(60, "km/hour"). Q_(100, "degF"). Convert: distance.to("feet"). velocity.to("m/s"). Q_(100, "degF").to("degC") → 37.78 °C. Q_(1, "kg").to("lbs"). Arithmetic: (5 * ureg.km) / (2 * ureg.hour) → “2.5 km/hour”. (10 * ureg.m) + (50 * ureg.cm) → “10.5 m”. Dimensionality: q.dimensionality[length] ** 1. q.check("[length]"). ureg.kilometer.dimensionality. Magnitude: q.magnitude → float. q.units → “meter”. str(q) → “5 meter”. Compact: q.to_compact() — choose best prefix automatically. numpy: import numpy as np; arr = np.array([1,2,3]) * ureg.meter. arr.to("feet"). Custom: ureg.define("pixel = 0.26458 mm = px"). ureg.define("dollar = [currency]"). Context: with ureg.context("spectroscopy"): Q_(500,"nm").to("eV"). wraps: @ureg.wraps("m/s", ["m","s"]) — enforce units on function parameters. @ureg.check("[length]"). pandas: df["distance_m"] = df["distance_ft"].apply(lambda x: Q_(x,"ft").to("m").magnitude). Claude Code generates pint unit converters, engineering calculators, and pandas unit pipelines.

CLAUDE.md for Pint

## Pint Stack
- Version: pint >= 0.23 | pip install pint
- Registry: from pint import UnitRegistry; ureg = UnitRegistry(); Q_ = ureg.Quantity
- Create: 5 * ureg.meter | Q_(60, "km/hour") | Q_(100, "degF")
- Convert: q.to("feet") | q.ito("m") in-place | q.to_compact() for best prefix
- Arithmetic: (10*ureg.m) + (50*ureg.cm) → auto-normalizes | dimensional analysis
- Check: q.dimensionality | q.check("[length]") | ureg.check("[mass]") decorator
- numpy: np.array([1,2,3]) * ureg.meter → vectorized; .to("feet") works on arrays

Pint Physical Units Pipeline

# app/units.py — pint unit-aware arithmetic, conversion, and pandas integration
from __future__ import annotations

from typing import Any

import numpy as np
from pint import UnitRegistry, errors as pint_errors

# ─────────────────────────────────────────────────────────────────────────────
# Shared registry — use one UnitRegistry per application
# ─────────────────────────────────────────────────────────────────────────────

ureg = UnitRegistry()
Q_   = ureg.Quantity   # shorthand constructor


# ─────────────────────────────────────────────────────────────────────────────
# 1. Conversion helpers
# ─────────────────────────────────────────────────────────────────────────────

def convert(value: float, from_unit: str, to_unit: str) -> float:
    """
    Convert a scalar value between units.
    Raises pint.DimensionalityError if the units are incompatible.
    """
    return Q_(value, from_unit).to(to_unit).magnitude


def convert_qty(value: float, from_unit: str, to_unit: str) -> Any:
    """Return the converted Quantity object (includes units in repr)."""
    return Q_(value, from_unit).to(to_unit)


def is_compatible(unit_a: str, unit_b: str) -> bool:
    """Return True if two units measure the same physical dimension."""
    try:
        a = ureg.Unit(unit_a)
        b = ureg.Unit(unit_b)
        return a.dimensionality == b.dimensionality
    except Exception:
        return False


def best_prefix(value: float, unit: str) -> str:
    """
    Return the quantity in its most readable prefix form.
    to_compact() picks the prefix that keeps the magnitude in [1, 1000).
    1_000_000 mm → "1.0 km"
    """
    return str(Q_(value, unit).to_compact())


# ─────────────────────────────────────────────────────────────────────────────
# 2. Temperature conversions
# ─────────────────────────────────────────────────────────────────────────────

def celsius_to_fahrenheit(c: float) -> float:
    return Q_(c, "degC").to("degF").magnitude


def fahrenheit_to_celsius(f: float) -> float:
    return Q_(f, "degF").to("degC").magnitude


def kelvin_to_celsius(k: float) -> float:
    return Q_(k, "kelvin").to("degC").magnitude


def temp_convert(value: float, from_scale: str, to_scale: str) -> float:
    """Generic temperature converter: degC, degF, kelvin."""
    return Q_(value, from_scale).to(to_scale).magnitude


# ─────────────────────────────────────────────────────────────────────────────
# 3. Distance / speed / area / volume
# ─────────────────────────────────────────────────────────────────────────────

def km_to_miles(km: float) -> float:
    return convert(km, "kilometer", "mile")


def mph_to_kph(mph: float) -> float:
    return convert(mph, "miles_per_hour", "kilometer / hour")


def meters_to_feet(m: float) -> float:
    return convert(m, "meter", "foot")


def liters_to_gallons(l: float, us: bool = True) -> float:
    target = "US_liquid_gallon" if us else "gallon"
    return convert(l, "liter", target)


def kg_to_lbs(kg: float) -> float:
    return convert(kg, "kilogram", "pound")


# ─────────────────────────────────────────────────────────────────────────────
# 4. Engineering calculations with dimensional analysis
# ─────────────────────────────────────────────────────────────────────────────

def speed(distance_m: float, time_s: float) -> dict[str, float]:
    """
    Calculate speed from distance (meters) and time (seconds).
    Pint tracks dimensions — dividing [length] / [time] → [velocity].
    Returns speed in m/s, km/h, and mph.
    """
    d = Q_(distance_m, "meter")
    t = Q_(time_s, "second")
    v = d / t  # → pint Quantity in "meter/second"
    return {
        "m_s":   v.magnitude,
        "km_h":  v.to("km/h").magnitude,
        "mph":   v.to("mph").magnitude,
    }


def fuel_efficiency(distance_km: float, fuel_liters: float) -> dict[str, float]:
    """Compute fuel efficiency in L/100km and MPG."""
    d  = Q_(distance_km, "kilometer")
    f  = Q_(fuel_liters, "liter")
    l100 = (f / d).to("L/100km")
    mpg  = (d / f).to("miles / US_liquid_gallon")
    return {
        "l_per_100km": l100.magnitude,
        "mpg":         mpg.magnitude,
    }


def pressure_drop(
    flow_rate_m3s: float,
    pipe_diameter_m: float,
    length_m: float,
    friction_factor: float,
    density_kgm3: float = 1000.0,
) -> float:
    """
    Darcy-Weisbach pressure drop (Pa).
    Demonstrates unit-aware formula: Δp = f * (L/D) * (ρv²/2)
    """
    Q   = Q_(flow_rate_m3s,   "m³/s")
    D   = Q_(pipe_diameter_m, "m")
    L   = Q_(length_m,        "m")
    rho = Q_(density_kgm3,    "kg/m³")
    A   = (3.14159 / 4) * D**2
    v   = Q / A                              # m/s
    dp  = friction_factor * (L / D) * (rho * v**2 / 2)
    return dp.to("pascal").magnitude


# ─────────────────────────────────────────────────────────────────────────────
# 5. NumPy array conversion
# ─────────────────────────────────────────────────────────────────────────────

def convert_array(
    values: list[float] | np.ndarray,
    from_unit: str,
    to_unit: str,
) -> np.ndarray:
    """
    Convert an array of values between units using numpy Quantity.
    Returns a plain numpy array of converted magnitudes.
    """
    arr = np.asarray(values)
    qty = Q_(arr, from_unit)
    return qty.to(to_unit).magnitude


def celsius_array_to_fahrenheit(temps_c: list[float]) -> np.ndarray:
    return convert_array(temps_c, "degC", "degF")


# ─────────────────────────────────────────────────────────────────────────────
# 6. Pandas integration
# ─────────────────────────────────────────────────────────────────────────────

def add_converted_column(
    df,
    source_col: str,
    from_unit: str,
    to_unit: str,
    new_col: str | None = None,
) -> Any:
    """
    Add a unit-converted column to a pandas DataFrame.
    new_col defaults to "{source_col}_{to_unit}".
    """
    import pandas as pd
    out_col = new_col or f"{source_col}_{to_unit.replace('/','_per_')}"
    values  = convert_array(df[source_col].values, from_unit, to_unit)
    df[out_col] = values
    return df


# ─────────────────────────────────────────────────────────────────────────────
# 7. Custom unit definition
# ─────────────────────────────────────────────────────────────────────────────

def define_custom_units() -> None:
    """
    Register domain-specific units.
    ureg.define("name = factor * base_unit = alias").
    Custom units persist in the registry for the process lifetime.
    """
    # CSS pixels: 96 dpi standard (1 inch = 96 px)
    try:
        ureg.define("pixel = 1/96 * inch = px")
    except Exception:
        pass

    # Story points (dimensionless effort unit)
    try:
        ureg.define("story_point = dimensionless = sp")
    except Exception:
        pass


# ─────────────────────────────────────────────────────────────────────────────
# 8. Unit-aware function decorators
# ─────────────────────────────────────────────────────────────────────────────

@ureg.wraps("m/s", (ureg.meter, ureg.second))
def compute_speed(distance, time):
    """Will raise if called with incompatible units."""
    return distance / time


# ─────────────────────────────────────────────────────────────────────────────
# Demo
# ─────────────────────────────────────────────────────────────────────────────

if __name__ == "__main__":
    print("=== Basic conversions ===")
    cases = [
        (100, "degF", "degC"),
        (1,   "mile", "kilometer"),
        (1,   "gallon", "liter"),
        (1,   "pound", "kilogram"),
        (1,   "horsepower", "watt"),
        (1,   "atmosphere", "pascal"),
        (1,   "calorie",    "joule"),
        (299_792_458, "m/s", "km/h"),
    ]
    for val, from_u, to_u in cases:
        result = convert(val, from_u, to_u)
        print(f"  {val} {from_u:15}{result:.4f} {to_u}")

    print("\n=== Temperature ===")
    for c in [0, 20, 37, 100, -40]:
        f = celsius_to_fahrenheit(c)
        print(f"  {c:6}°C = {f:.1f}°F")

    print("\n=== Speed calculation ===")
    s = speed(100, 9.58)  # Usain Bolt 100m sprint
    print(f"  100m in 9.58s: {s['m_s']:.2f} m/s = {s['km_h']:.2f} km/h = {s['mph']:.2f} mph")

    print("\n=== Fuel efficiency ===")
    fe = fuel_efficiency(500, 40)
    print(f"  500km, 40L: {fe['l_per_100km']:.1f} L/100km = {fe['mpg']:.1f} mpg")

    print("\n=== Array conversion ===")
    temps_c = [0, 20, 37, 100]
    temps_f = celsius_array_to_fahrenheit(temps_c)
    for c, f in zip(temps_c, temps_f):
        print(f"  {c}°C → {f:.1f}°F")

    print("\n=== Compact display ===")
    for val, unit in [(0.001, "meter"), (1e9, "meter"), (1500, "watt"), (0.000001, "gram")]:
        print(f"  {val} {unit}{best_prefix(val, unit)}")

    print("\n=== Dimensionality ===")
    samples = [
        Q_(5,   "meter"),
        Q_(60,  "km/h"),
        Q_(100, "degF"),
        Q_(1,   "kilogram * meter / second**2"),
    ]
    for q in samples:
        print(f"  {q!s:30} dim={q.dimensionality}")

For the astropy.units alternative — astropy.units is the gold standard for astrophysics (parsecs, light-years, solar masses, angular units), but Pint is the right choice for general engineering and scientific Python because it has a simpler API, doesn’t require the full astropy dependency, and covers all SI, imperial, and derived units; Pint’s ureg.define() makes it easy to add domain-specific units (CSS pixels, story points, custom chemical concentrations). For the quantities package alternative — quantities wraps numpy arrays with attached units but is less actively maintained and has a more complex API; Pint works naturally with plain numpy arrays (np.array([1,2,3]) * ureg.meter) and pandas Series, making it easier to integrate into existing data pipelines without restructuring code. The Claude Skills 360 bundle includes Pint skill sets covering UnitRegistry and Q_ shorthand, Q_(value, unit).to(target) conversion, magnitude and units attributes, to_compact() for best prefix selection, is_compatible() dimensionality check, temp_convert() for degC/degF/kelvin, speed() and fuel_efficiency() engineering calculations, convert_array() for numpy vectorized conversion, celsius_array_to_fahrenheit() array helper, add_converted_column() pandas integration, ureg.define() custom unit registration, and @ureg.wraps() unit-enforcing decorator. Start with the free tier to try unit-aware arithmetic code generation.

Keep Reading

AI

Claude Code for email.contentmanager: Python Email Content Accessors

Read and write EmailMessage body content with Python's email.contentmanager module and Claude Code — email contentmanager ContentManager for the class that maps content types to get and set handler functions allowing EmailMessage to support get_content and set_content with type-specific behaviour, email contentmanager raw_data_manager for the ContentManager instance that handles raw bytes and str payloads without any conversion, email contentmanager content_manager for the standard ContentManager instance used by email.policy.default that intelligently handles text plain text html multipart and binary content types, email contentmanager get_content_text for the handler that returns the decoded text payload of a text-star message part as a str, email contentmanager get_content_binary for the handler that returns the raw decoded bytes payload of a non-text message part, email contentmanager get_data_manager for the get-handler lookup used by EmailMessage get_content to find the right reader function for the content type, email contentmanager set_content text for the handler that creates and sets a text part correctly choosing charset and transfer encoding, email contentmanager set_content bytes for the handler that creates and sets a binary part with base64 encoding and optional filename Content-Disposition, email contentmanager EmailMessage get_content for the method that reads the message body using the registered content manager handlers, email contentmanager EmailMessage set_content for the method that sets the message body and MIME headers in one call, email contentmanager EmailMessage make_alternative make_mixed make_related for the methods that convert a simple message into a multipart container, email contentmanager EmailMessage add_attachment for the method that attaches a file or bytes to a multipart message, and email contentmanager integration with email.message and email.policy and email.mime and io for building high-level email readers attachment extractors text body accessors HTML readers and policy-aware MIME construction pipelines.

5 min read Feb 12, 2029
AI

Claude Code for email.charset: Python Email Charset Encoding

Control header and body encoding for international email with Python's email.charset module and Claude Code — email charset Charset for the class that wraps a character set name with the encoding rules for header encoding and body encoding describing how to encode text for that charset in email messages, email charset Charset header_encoding for the attribute specifying whether headers using this charset should use QP quoted-printable encoding BASE64 encoding or no encoding, email charset Charset body_encoding for the attribute specifying the Content-Transfer-Encoding to use for message bodies in this charset such as QP or BASE64, email charset Charset output_codec for the attribute giving the Python codec name used to encode the string to bytes for the wire format, email charset Charset input_codec for the attribute giving the Python codec name used to decode incoming bytes to str, email charset Charset get_output_charset for returning the output charset name, email charset Charset header_encode for encoding a header string using the charset's header_encoding method, email charset Charset body_encode for encoding body content using the charset's body_encoding, email charset Charset convert for converting a string from the input_codec to the output_codec, email charset add_charset for registering a new charset with custom encoding rules in the global charset registry, email charset add_alias for adding an alias name that maps to an existing registered charset, email charset add_codec for registering a codec name mapping for use by the charset machinery, and email charset integration with email.message and email.mime and email.policy and email.encoders for building international email senders non-ASCII header encoders Content-Transfer-Encoding selectors charset-aware message constructors and MIME encoding pipelines.

5 min read Feb 11, 2029
AI

Claude Code for email.utils: Python Email Address and Header Utilities

Parse and format RFC 2822 email addresses and dates with Python's email.utils module and Claude Code — email utils parseaddr for splitting a display-name plus angle-bracket address string into a realname and email address tuple, email utils formataddr for combining a realname and address string into a properly quoted RFC 2822 address with angle brackets, email utils getaddresses for parsing a list of raw address header strings each potentially containing multiple comma-separated addresses into a list of realname address tuples, email utils parsedate for parsing an RFC 2822 date string into a nine-tuple compatible with time.mktime, email utils parsedate_tz for parsing an RFC 2822 date string into a ten-tuple that includes the UTC offset timezone in seconds, email utils parsedate_to_datetime for parsing an RFC 2822 date string into an aware datetime object with timezone, email utils formatdate for formatting a POSIX timestamp or the current time as an RFC 2822 date string with optional usegmt and localtime flags, email utils format_datetime for formatting a datetime object as an RFC 2822 date string, email utils make_msgid for generating a globally unique Message-ID string with optional idstring and domain components, email utils decode_rfc2231 for decoding an RFC 2231 encoded parameter value into a tuple of charset language and value, email utils encode_rfc2231 for encoding a string as an RFC 2231 encoded parameter value, email utils collapse_rfc2231_value for collapsing a decoded RFC 2231 tuple to a Unicode string, and email utils integration with email.message and email.headerregistry and datetime and time for building address parsers date formatters message-id generators header extractors and RFC-compliant email construction utilities.

5 min read Feb 10, 2029

Put these ideas into practice

Claude Skills 360 gives you production-ready skills for everything in this article — and 2,350+ more. Start free or go all-in.

Back to Blog

Get 360 skills free