Skip to main content

A delightful Python library for Reverse Polish Notation with Pydantic integration

Project description

๐Ÿงฎ Pydantic RPN

The most delightful Python library for Reverse Polish Notation that makes HP calculator engineers weep with joy! ๐Ÿš€

PyPI version Python Support License: MIT Tests

Finally! A Reverse Polish Notation library that doesn't make you want to throw your calculator out the window! ๐ŸŽฏ

If you've ever wondered what would happen if a HP-41C calculator had a baby with Pydantic and that baby was raised by Python wizards who appreciate both mathematical elegance AND having fun... this is it!

๐ŸŽช Why This Library is Epic

  • ๐Ÿš€ Lightning Fast: Sub-millisecond evaluations that make your CPU purr
  • ๐Ÿ”’ Type Safe: Pydantic-powered validation because we're not animals
  • ๐ŸŽฎ Battle-Tested: 31 brutal test cases covering everything from DOOM calculations to restaurant orders
  • ๐Ÿ—๏ธ Fluent Builder: Chain operations like a boss with our sexy Builder pattern
  • ๐ŸŽฏ Zero Dependencies: Just Pydantic and pure Python magic
  • ๐Ÿ“Š Memory Efficient: Zero leaks detected - your RAM will thank you
  • ๐Ÿ”„ Production Ready: Used in real-world applications (restaurant delivery, anyone?)

โšก Quick Start (The Fun Way!)

pip install pydantic-rpn
from pydantic_rpn import RPN, RPNBuilder, rpn

# ๐ŸŽฏ Basic usage that just works
result = RPN("3 4 +").eval()  # 7
result = rpn("3 4 +")()       # 7 (because why type more?)

# ๐Ÿ—๏ธ Builder pattern for when you're feeling fancy  
result = (RPNBuilder()
    .push(3).push(4).add()
    .push(2).mul().eval())  # (3+4) * 2 = 14

# ๐Ÿ”ฅ Variables because we're not cavemen
expr = RPN("x 2 * y +")
result = expr.eval(x=5, y=3)  # 5*2 + 3 = 13

# ๐ŸŽช Stack operations that would make a HP engineer cry (happy tears)
result = RPN("5 dup *").eval()      # 5ยฒ = 25 (duplicate and multiply)
result = RPN("3 4 swap -").eval()   # 4-3 = 1 (swap then subtract)

๐ŸŽฎ Epic Examples

๐Ÿ• Restaurant Order Calculator

# Real-world usage in a delivery app
order_total = RPN("item_price quantity * tax_rate 1 + * tip +")
total = order_total.eval(
    item_price=12.99, 
    quantity=2, 
    tax_rate=0.08, 
    tip=3.00
)  # $31.06 - exactly what you'd expect!

๐Ÿš€ DOOM Ballistics (Yes, Really!)

# Rocket splash damage calculation
splash_damage = RPN("max_damage 1 distance splash_radius / - 2 ** *")
damage = splash_damage.eval(
    max_damage=200, 
    distance=120, 
    splash_radius=128
)  # 0.78 damage at the edge - barely a scratch!

๐Ÿ“ HP Calculator Classics

# Quadratic formula like a boss
quadratic = RPN("0 b - b 2 ** 4 a * c * - sqrt + 2 a * /")
root = quadratic.eval(a=1, b=-5, c=6)  # xยฒ - 5x + 6 = 0 โ†’ root = 3.0

# Golden ratio because math is beautiful
golden = RPN("1 5 sqrt + 2 /").eval()  # ฯ† = 1.618034...

๐ŸŽช The Fun Stuff

Stack Operations (The HP Calculator Way!)

rpn("5 dup *").eval()        # 25 (duplicate and multiply)
rpn("3 4 swap -").eval()     # 1  (swap then subtract)  
rpn("1 2 3 rot + +").eval()  # 6  (rotate stack, then add all)
rpn("10 3 over / +").eval()  # 13.33 (copy second item over)

Mathematical Functions

rpn("25 sqrt").eval()     # 5.0
rpn("pi sin").eval()      # โ‰ˆ0 (sin of ฯ€)
rpn("e ln").eval()        # 1.0 (natural log of e)
rpn("-5 abs").eval()      # 5.0

Variables and Templates

# Variables with defaults
expr = RPN("x y +", defaults={"x": 10})
result = expr.eval(y=5)  # 15

# Template expressions for dynamic formulas
template = RPN.template("${price} ${tax} +")
result = template.eval(price=100, tax=10)  # 110

๐Ÿ—๏ธ Builder Pattern Mastery

When you need to build complex expressions programmatically:

# Financial calculation: compound interest
compound_interest = (RPNBuilder()
    .var("principal")
    .push(1).var("rate").add()        # (1 + rate)
    .var("years").pow()               # (1 + rate)^years  
    .mul())                           # principal * (1 + rate)^years

result = compound_interest.eval(principal=1000, rate=0.05, years=10)
# $1,628.89 after 10 years at 5%

๐ŸŽฏ Advanced Features

JSON Serialization

expr = RPN("x 2 ** y 2 ** + sqrt", metadata={"formula": "pythagorean"})
json_str = expr.to_json()
restored = RPN.from_json(json_str)  # Perfect round-trip!

Expression Composition

expr1 = RPN("3 4 +")
expr2 = RPN("2 *")
combined = expr1 + expr2  # "3 4 + 2 *" โ†’ 14

Interactive REPL

from pydantic_rpn import REPL

repl = REPL()
repl.run()
# 
# rpn> 3 4 +
# 7
# rpn> ans 2 *  
# 14

Command Line Interface

# Evaluate expressions
rpn "3 4 +"                    # 7

# Use variables
rpn "x 2 *" --var x=5         # 10

# Interactive mode
rpn --repl

# Show infix notation
rpn "3 4 + 2 *" --infix       # ((3 + 4) * 2)

๐Ÿ“Š Performance That Doesn't Suck

  • Sub-millisecond evaluation for most expressions
  • Linear scaling - handles 1000+ operations efficiently
  • Zero memory leaks detected in extensive testing
  • Production benchmarks - ready for high-throughput applications
# Benchmarks on a potato laptop:
# 1000 simple evaluations: ~4ms
# 1000 complex expressions: ~11ms  
# 100 expressions with 20 variables each: ~11ms
# This thing is FAST! ๐Ÿš€

๐Ÿงช Battle-Tested Quality

  • 31 brutal test cases covering every edge case we could think of
  • Property-based testing with Hypothesis for mathematical correctness
  • 100% test coverage because we're not monsters
  • Memory leak detection to keep your servers happy
  • Integration tested with real-world applications

๐ŸŽช Fun Examples Collection

This library comes with the most entertaining examples in mathematical computing:

  • ๐ŸŽฎ DOOM RPN: Ballistics calculations and demon slaying math
  • ๐Ÿ“ฑ HP Calculator Classics: The formulas that made engineers fall in love with RPN
  • ๐Ÿ•น๏ธ Retro Computing: From punch cards to pixels via RPN
  • ๐ŸŽช Fun Calculator Tricks: Upside-down words and mathematical magic

Check out the examples/ directory for hours of mathematical entertainment!

๐Ÿš€ Installation & Usage

Requirements

  • Python 3.8+
  • Pydantic 2.0+
  • A sense of mathematical adventure ๐Ÿงญ

Install

pip install pydantic-rpn

Quick Test

from pydantic_rpn import rpn
assert rpn("2 3 +")() == 5  # Math still works! ๐ŸŽ‰

๐Ÿค Contributing

Found a bug? Want to add more mathematical mayhem? We welcome contributions!

  1. Fork it ( https://github.com/rsp2k/pydantic-rpn/fork )
  2. Create your feature branch (git checkout -b my-awesome-feature)
  3. Add tests (we have standards!)
  4. Make sure everything passes (python -m pytest)
  5. Commit your changes (git commit -am 'Add awesome feature')
  6. Push to the branch (git push origin my-awesome-feature)
  7. Create a Pull Request ๐Ÿš€

๐Ÿ“œ License

MIT License - because sharing is caring! See LICENSE for details.

๐Ÿ™ Acknowledgments

  • HP Calculator Engineers - for making RPN cool before cool was cool
  • The Pydantic Team - for type safety that doesn't make us cry
  • John Backus - for showing us that postfix notation is the way
  • Everyone who suffered through infix notation - this one's for you! ๐Ÿป

Made with โค๏ธ and excessive amounts of โ˜• by developers who think math should be fun!

P.S. If this library doesn't make you at least 23% happier about doing math in Python, we'll refund your sense of wonder! (Offer not valid in reality, but the library is still awesome.)


๐Ÿ•ฐ๏ธ If you're into RPN, you might like my retro website: ryanmalloy.com - where the 1980s never ended! ๐Ÿ“Ÿ

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pydantic_rpn-0.1.0.tar.gz (46.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pydantic_rpn-0.1.0-py3-none-any.whl (15.1 kB view details)

Uploaded Python 3

File details

Details for the file pydantic_rpn-0.1.0.tar.gz.

File metadata

  • Download URL: pydantic_rpn-0.1.0.tar.gz
  • Upload date:
  • Size: 46.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for pydantic_rpn-0.1.0.tar.gz
Algorithm Hash digest
SHA256 728931f198bac4bc78c2694957da5c09a6209a17e4d35cee229d882c2e513c60
MD5 45f7ce98c348ebf1914c444deec36fa5
BLAKE2b-256 0bb6b235f3a744d830b00d6f6741921efea87c99f5bd15352d616803d822c4f9

See more details on using hashes here.

File details

Details for the file pydantic_rpn-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: pydantic_rpn-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 15.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for pydantic_rpn-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 7f8cde2e674bc81171072760a91c6b95589517729b7cc18342df2cfd3978f221
MD5 3e7a6c4b4d73809aa82c81b52ec17040
BLAKE2b-256 6f2eb3d168c0f86400dbfbab29b9a428962360f3047bf51f7fb66de5b94736ce

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page