Skip to content

Instantly share code, notes, and snippets.

@eddieantonio
Created December 11, 2017 14:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eddieantonio/ed7183608ab8c7aef92efa0c44bb7366 to your computer and use it in GitHub Desktop.
Save eddieantonio/ed7183608ab8c7aef92efa0c44bb7366 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
"""
A module for dice, dice rolls, and dice arithmetic.
"""
import sys
import re
from types import ModuleType
class DiceModule(ModuleType):
dice_pattern = re.compile(r'^d([1-9][0-9]*)$')
class Die:
__slots__ = 'sides',
def __init__(self, sides) -> None:
self.sides = sides
def roll(self) -> int:
from random import randint
return randint(1, self.sides)
def __rmul__(self, other) -> int:
if isinstance(other, int):
return other * self.roll()
return NotImplemented
def __getattr__(self, attr):
m = self.dice_pattern.match(attr)
if not m:
return super().__getattr__(attr)
return self.Die(int(m.group(1)))
sys.modules[__name__] = DiceModule(__name__, __doc__)
#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
import pytest
def test_import():
from dice import Die, d20
assert isinstance(d20, Die)
assert d20.sides == 20
def test_roll():
from dice import d20
for _ in range(20):
assert 1 <= d20.roll() <= 20
def test_roll_multiple():
from dice import d6
for _ in range(36):
assert 2 <= 2 * d6 <= 12
def test_arithmetic():
from dice import d6
for _ in range(36):
assert 2 + 5 <= 2 * d6 + 5 <= 36 + 5
def test_bonkers():
from dice import d34321
with pytest.raises(ImportError):
from dice import does_not_exist
with pytest.raises(ImportError):
from dice import d007
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment