I am trying to make a dice roller in python. the code is:
class die:
def __init__(self, num:int, die:int | str, mod:int=0, keep:int=None):
keep = keep if keep != None else num
if keep > num: keep = num
self.num, self.die, self.mod, self.keep = num, die, mod, keep
def __repr__(self) -> str:
mod = f"+{self.mod}" if self.mod > 0 else f"-{abs(self.mod)}" if self.mod < 0 else ''
keep = f"{f"{self.keep}kh" if self.keep > 0 else f"{abs(self.keep)}kl" if self.keep < 0 else ''}"
return f"{keep}{self.num}d{self.die}{mod}"
def roll(self) -> int:
log = []
die = range(0, self.num)
for _ in die:
log += [rand.randint(0, (10 if self.die == '%' else int(self.die)) * (10 if self.die == '%' else 1))]
if self.keep > 0:
log = [log] + [heapq.nlargest(self.keep, log)]
elif self.keep < 0:
log = [log] + [heapq.nsmallest(abs(self.keep), log)]
final = sum(log[1], self.mod)
return final
#Sorry if my code is hard to read.
I want to add the ability to pass a dice expression (example: 4d6+3) as well as individual options. is there any way I can pass a separate argument if there is only one argument provided. For example:
def __init__(self, num:int, die:int | str, mod:int=0, keep:int=None OR expression:str)
__init__is fine the way it is. The job of parsing a string into suitable arguments should be handled by a class method.Something like