I took the liberty to refactor your
Python program:
Code:
import re
def input_dice_as_polynomial_coefficients():
dice = []
print(
'Enter face values as non-negative integers, separated by spaces, commas, or semicolons. (e.g. "1,2;3 4 5 6")'
)
while inp := input("Die " + str(len(dice) + 1) + "? "):
# List of face values
raw_die = [
int(face.strip()) for face in re.split(r"[ ,;]", inp) if face.strip()
]
# Quantity of a single die spec
raw_qty = input("Quantity? [1] ")
qty = 1 if raw_qty == "" else int(raw_qty)
die = coefficients(raw_die)
dice += [die] * qty
print(f"{raw_die} x {qty}")
return dice
def coefficients(raw_die):
die = [0] * (max(raw_die) + 1)
for i in raw_die:
die[i] += 1
return die
def calculate_frequencies(dice):
previous, *rest = dice
for current in rest:
result = [0] * (len(previous) + len(current) - 1)
for i, u in enumerate(previous):
if u == 0:
continue
for j, v in enumerate(current):
result[i + j] += u * v
previous = result
return previous
def print_permutations(frequencies):
skip_zero = True
p = sum(frequencies)
f_cum = 0.0
print(f"Permutations: {p:.0f}")
print(f"{'Total':<6} {'Freq':<12} {'Prob':>10} {'p>=':>10} {'p<=':>10}")
for i, f in enumerate(frequencies):
f_cum += f
if f == 0 and skip_zero:
continue
skip_zero = False
print(
f"{i:<6} {f:<12} {f / p:>10.3%} {(p - f_cum + f) / p:>10.3%} {f_cum / p:>10.3%}"
)
if __name__ == "__main__":
dice = input_dice_as_polynomial_coefficients()
frequencies = calculate_frequencies(dice)
print_permutations(frequencies)
- extract method to break the program into smaller pieces
- this allows to write unit-tests for some of the functions
- use the __name__ == "__main__" check
- this allows to import the file as module without running it
- use f-strings
- use the walrus-operator :=
- rename some variables
- use black to format the code
Examples
Code:
Enter face values as non-negative integers, separated by spaces, commas, or semicolons. (e.g. "1,2;3 4 5 6")
Die 1? 0 1 2
Quantity? [1] 5
[0, 1, 2] x 5
Die 6?
Permutations: 243
Total Freq Prob p>= p<=
0 1 0.412% 100.000% 0.412%
1 5 2.058% 99.588% 2.469%
2 15 6.173% 97.531% 8.642%
3 30 12.346% 91.358% 20.988%
4 45 18.519% 79.012% 39.506%
5 51 20.988% 60.494% 60.494%
6 45 18.519% 39.506% 79.012%
7 30 12.346% 20.988% 91.358%
8 15 6.173% 8.642% 97.531%
9 5 2.058% 2.469% 99.588%
10 1 0.412% 0.412% 100.000%
Code:
Enter face values as non-negative integers, separated by spaces, commas, or semicolons. (e.g. "1,2;3 4 5 6")
Die 1? 0 0 0 1 1 2
Quantity? [1] 5
[0, 0, 0, 1, 1, 2] x 5
Die 6?
Permutations: 7776
Total Freq Prob p>= p<=
0 243 3.125% 100.000% 3.125%
1 810 10.417% 96.875% 13.542%
2 1485 19.097% 86.458% 32.639%
3 1800 23.148% 67.361% 55.787%
4 1590 20.448% 44.213% 76.235%
5 1052 13.529% 23.765% 89.763%
6 530 6.816% 10.237% 96.579%
7 200 2.572% 3.421% 99.151%
8 55 0.707% 0.849% 99.859%
9 10 0.129% 0.141% 99.987%
10 1 0.013% 0.013% 100.000%