Unit tests, and API implemented.
This commit is contained in:
parent
f37debf73f
commit
32d1d2b507
2 changed files with 321 additions and 55 deletions
337
README.org
337
README.org
|
@ -6,6 +6,8 @@
|
||||||
#+PROPERTY: header-args :tangle pydiceprob.py
|
#+PROPERTY: header-args :tangle pydiceprob.py
|
||||||
* Introduction
|
* Introduction
|
||||||
:LOGBOOK:
|
:LOGBOOK:
|
||||||
|
CLOCK: [2024-04-20 Sat 09:05]
|
||||||
|
CLOCK: [2024-04-20 Sat 07:57]--[2024-04-20 Sat 09:04] => 1:07
|
||||||
CLOCK: [2024-04-19 Fri 10:33]--[2024-04-19 Fri 12:50] => 2:17
|
CLOCK: [2024-04-19 Fri 10:33]--[2024-04-19 Fri 12:50] => 2:17
|
||||||
CLOCK: [2024-04-17 Wed 13:40]--[2024-04-17 Wed 14:14] => 0:34
|
CLOCK: [2024-04-17 Wed 13:40]--[2024-04-17 Wed 14:14] => 0:34
|
||||||
:END:
|
:END:
|
||||||
|
@ -28,23 +30,40 @@ op8onal Header for “k”, and return:
|
||||||
- A single probability in JSON format if a “k” is provided in the Header
|
- A single probability in JSON format if a “k” is provided in the Header
|
||||||
#+end_quote
|
#+end_quote
|
||||||
|
|
||||||
* TODOS:
|
I appear to have completed the task, at a comfortable pace, in about 4 hours.
|
||||||
- Unit tests
|
I have omitted the unit tests for the API portion of this, as it would have been
|
||||||
- REST API
|
overkill.
|
||||||
|
|
||||||
|
I did choose to include 100 in the calculations, as I find that just a little
|
||||||
|
bit more elegant. There is something special about ending a list on a nice round number.
|
||||||
|
* Usage
|
||||||
|
This repository contains multiple files.
|
||||||
|
1. The pdf with the problem I was given.
|
||||||
|
2. README.org - an Emacs org-mode file, which you're reading right now.
|
||||||
|
3. pydiceprob.py - the main python file, which works in CLI as such:
|
||||||
|
- ~python pydiceprob.py [dice_size] [mode]~
|
||||||
|
- ~dice_size~ can be anything in the CLI, but note that excessively large
|
||||||
|
numbers are pointless, as the probability of a single throw will always be
|
||||||
|
1/dice_size, while the probability of winning in the game will always be
|
||||||
|
approaching 50%.
|
||||||
|
- The modes are:
|
||||||
|
- ~single~ (for single throw)
|
||||||
|
- ~single-table~ (for a table of probabilities to win on a single throw
|
||||||
|
across a variety of dice sizes)
|
||||||
|
- ~multi~ (winning probability in the game)
|
||||||
|
- ~multi-table~ (winning probabilities in the game across a variety of dice sizes)
|
||||||
|
- *Alternatively*, you can start a REST API (implemented using FastAPI) using
|
||||||
|
uvicorn. Run ~uvicorn pydiceprob:app~ from the same directory as the
|
||||||
|
=pydiceprob.py= file.
|
||||||
|
- You can then see the outputs using =curl=, such as:
|
||||||
|
- ~curl 127.0.0.1:8000~ or
|
||||||
|
- ~curl 127.0.0.1:8000 -H "k: [dice_size]"~
|
||||||
|
- Please note that I have chosen to limit the dice size to be between 6
|
||||||
|
and 100 inclusive on the API.
|
||||||
|
4. tests.py - simple tests for the probability calculations.
|
||||||
|
|
||||||
|
|
||||||
* Thinking
|
|
||||||
Given the problem's nature, we need the following functionality:
|
|
||||||
|
|
||||||
1. Output the probability for Bob to win.
|
|
||||||
2. Create an array of probabilities that contains the data for the output.
|
|
||||||
3. Calculate the probabilities based on the value of =k=.
|
|
||||||
4. Define the value of =k=, between 6 and 99 inclusive.
|
|
||||||
|
|
||||||
For the bonus secion:
|
|
||||||
1. Create a FastAPI endpoint that takes an optional Header for =k=.
|
|
||||||
2. Return either the full array of probabilities (no =k= provided), or return the
|
|
||||||
specific probability if =k= is provided.
|
|
||||||
* Code
|
* Code
|
||||||
The following is python code blocks, with the documentation attached. Using
|
The following is python code blocks, with the documentation attached. Using
|
||||||
=org-babel=, these are tangled into =pydiceprob.py=,
|
=org-babel=, these are tangled into =pydiceprob.py=,
|
||||||
|
@ -54,6 +73,8 @@ which is the final python script.
|
||||||
import sys
|
import sys
|
||||||
import json
|
import json
|
||||||
import pprint
|
import pprint
|
||||||
|
from fastapi import FastAPI, Header
|
||||||
|
from pydantic import BaseModel
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
#+RESULTS:
|
#+RESULTS:
|
||||||
|
@ -67,7 +88,7 @@ And a usage printe
|
||||||
#+begin_src python
|
#+begin_src python
|
||||||
def usagequit():
|
def usagequit():
|
||||||
print("""Usage: python pydiceprob.py [k] [mode]
|
print("""Usage: python pydiceprob.py [k] [mode]
|
||||||
k between 6 and 99
|
k between 6 and 99 (higher numbers are supported, up to however much your memory can handle; given that win probabilities approach 50%, this isn't very useful past about 100.)
|
||||||
modes: single, single-table, multi, multi-table
|
modes: single, single-table, multi, multi-table
|
||||||
single prints out the probability of a single throw with a k-sided dice yielding k.
|
single prints out the probability of a single throw with a k-sided dice yielding k.
|
||||||
single-table prints out a table between 6 and k with the probabilities of a single throw yielding k.
|
single-table prints out a table between 6 and k with the probabilities of a single throw yielding k.
|
||||||
|
@ -75,6 +96,29 @@ def usagequit():
|
||||||
multi-table prints out the probability of winning for a range between 6 and k if you have the first throw.""")
|
multi-table prints out the probability of winning for a range between 6 and k if you have the first throw.""")
|
||||||
quit()
|
quit()
|
||||||
#+end_src
|
#+end_src
|
||||||
|
** FastAPI
|
||||||
|
:LOGBOOK:
|
||||||
|
CLOCK: [2024-04-20 Sat 09:04]--[2024-04-20 Sat 09:05] => 0:01
|
||||||
|
:END:
|
||||||
|
#+begin_src python
|
||||||
|
app = FastAPI()
|
||||||
|
|
||||||
|
class APIget(BaseModel):
|
||||||
|
result: dict
|
||||||
|
@app.get("/")
|
||||||
|
async def api_get(k: int = Header(default=None)):
|
||||||
|
if not isinstance(k, int) and k is not None:
|
||||||
|
return {"message": "Header k must be an integer between 6 and 100 inclusive or not present."}
|
||||||
|
if k is None:
|
||||||
|
result = one_turn_table(100)
|
||||||
|
return {"Probabilities of throwing the highest number on dice of size": result}
|
||||||
|
elif k >= 6 and k <= 100:
|
||||||
|
result = one_turn_single(k)
|
||||||
|
return {f"Probability of throwing the highest number of dice of size {k}": result}
|
||||||
|
else:
|
||||||
|
return {"message": "Usage: no request body, use header k to specify what probability you want, if no k, then a table is given between dice sizes 6 and 100 inclusive."}
|
||||||
|
|
||||||
|
#+end_src
|
||||||
** Main
|
** Main
|
||||||
Main function for managing CLI interactions, and dispatch
|
Main function for managing CLI interactions, and dispatch
|
||||||
#+begin_src python
|
#+begin_src python
|
||||||
|
@ -102,37 +146,16 @@ def dispatch(mode, k):
|
||||||
if mode not in modes:
|
if mode not in modes:
|
||||||
usagequit()
|
usagequit()
|
||||||
if mode == "single":
|
if mode == "single":
|
||||||
print(first_turn_probability(k))
|
print(one_turn_single(k))
|
||||||
elif mode == "multi" :
|
elif mode == "multi" :
|
||||||
print(multi_turn_single(k))
|
print(multi_turn_single(k))
|
||||||
elif mode == "single-table":
|
elif mode == "single-table":
|
||||||
print(first_turn_protatbilities(k))
|
print(one_turn_table(k))
|
||||||
elif mode == "multi-table":
|
elif mode == "multi-table":
|
||||||
print(multi_turn_table(k))
|
print(multi_turn_table(k))
|
||||||
|
|
||||||
|
|
||||||
#+end_src
|
#+end_src
|
||||||
** Array of dice and players
|
|
||||||
Second, we need to grab the value of =k=, the size of the dice we're calculating
|
|
||||||
the probability for. Depending on the implementation we choose to use, we'll be either
|
|
||||||
grabbing it from the CLI, or the REST API. For now, this will remain in the CLI.
|
|
||||||
|
|
||||||
Then for the bonus code, we need several steps. First, we need to generate a list
|
|
||||||
such that we have numbers between 6 and 99 in it.
|
|
||||||
#+begin_src python
|
|
||||||
def dice(k):
|
|
||||||
if k < 6:
|
|
||||||
print("Dice must be at least 6-sided")
|
|
||||||
elif k == 6:
|
|
||||||
dice_array = [6]
|
|
||||||
else:
|
|
||||||
dice_array = list(range(6, k))
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
#+RESULTS:
|
|
||||||
: None
|
|
||||||
|
|
||||||
|
|
||||||
** Single turn win probability
|
** Single turn win probability
|
||||||
Then, we have to calculate the probability of a win on each throw given a dice
|
Then, we have to calculate the probability of a win on each throw given a dice
|
||||||
of size =k=.
|
of size =k=.
|
||||||
|
@ -147,14 +170,14 @@ for a = 6 and b = 10, it'll give an array of 4 items (10-6 = 4) as such:
|
||||||
|
|
||||||
Using =k+1= we can get the correct, inclusive array that we desire: ~[6, 7, 8, 9, 10]~.
|
Using =k+1= we can get the correct, inclusive array that we desire: ~[6, 7, 8, 9, 10]~.
|
||||||
#+begin_src python
|
#+begin_src python
|
||||||
def first_turn_probabilities(k):
|
def one_turn_table(k):
|
||||||
result = {}
|
result = {}
|
||||||
for k in range(6, int(k)+1):
|
for k in range(6, int(k)+1):
|
||||||
result[k] = 1/k
|
result[k] = 1/k
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def first_turn_probability(k):
|
def one_turn_single(k):
|
||||||
return first_turn_probabilities(k)[k]
|
return one_turn_table(k)[k]
|
||||||
|
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
|
@ -197,3 +220,235 @@ To run as a script.
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
#+end_src
|
#+end_src
|
||||||
|
* Unit testing
|
||||||
|
** Imports
|
||||||
|
#+begin_src python :tangle test.py
|
||||||
|
import unittest
|
||||||
|
import pydiceprob
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
** Single-turn win probabilities
|
||||||
|
Then we test the range from 6 to 100. The script supports more, but this is the
|
||||||
|
part that /must/ be correct.
|
||||||
|
|
||||||
|
Because the function =one_turn_single= pulls directly from
|
||||||
|
=one_turn_table=, we can simply iterate over =one_turn_single=,
|
||||||
|
ensuring that both functions work as desired at the same time.
|
||||||
|
|
||||||
|
This, however, is only because we're dealing with exceedingly trivial code,
|
||||||
|
where the singular function merely narrows down the data from the plural.
|
||||||
|
#+begin_src python :tangle test.py
|
||||||
|
class TestSingle(unittest.TestCase):
|
||||||
|
def test_single(self):
|
||||||
|
data = {6: 0.16666666666666666,
|
||||||
|
7: 0.14285714285714285,
|
||||||
|
8: 0.125,
|
||||||
|
9: 0.1111111111111111,
|
||||||
|
10: 0.1,
|
||||||
|
11: 0.09090909090909091,
|
||||||
|
12: 0.08333333333333333,
|
||||||
|
13: 0.07692307692307693,
|
||||||
|
14: 0.07142857142857142,
|
||||||
|
15: 0.06666666666666667,
|
||||||
|
16: 0.0625,
|
||||||
|
17: 0.058823529411764705,
|
||||||
|
18: 0.05555555555555555,
|
||||||
|
19: 0.05263157894736842,
|
||||||
|
20: 0.05,
|
||||||
|
21: 0.047619047619047616,
|
||||||
|
22: 0.045454545454545456,
|
||||||
|
23: 0.043478260869565216,
|
||||||
|
24: 0.041666666666666664,
|
||||||
|
25: 0.04,
|
||||||
|
26: 0.038461538461538464,
|
||||||
|
27: 0.037037037037037035,
|
||||||
|
28: 0.03571428571428571,
|
||||||
|
29: 0.034482758620689655,
|
||||||
|
30: 0.03333333333333333,
|
||||||
|
31: 0.03225806451612903,
|
||||||
|
32: 0.03125,
|
||||||
|
33: 0.030303030303030304,
|
||||||
|
34: 0.029411764705882353,
|
||||||
|
35: 0.02857142857142857,
|
||||||
|
36: 0.027777777777777776,
|
||||||
|
37: 0.02702702702702703,
|
||||||
|
38: 0.02631578947368421,
|
||||||
|
39: 0.02564102564102564,
|
||||||
|
40: 0.025,
|
||||||
|
41: 0.024390243902439025,
|
||||||
|
42: 0.023809523809523808,
|
||||||
|
43: 0.023255813953488372,
|
||||||
|
44: 0.022727272727272728,
|
||||||
|
45: 0.022222222222222223,
|
||||||
|
46: 0.021739130434782608,
|
||||||
|
47: 0.02127659574468085,
|
||||||
|
48: 0.020833333333333332,
|
||||||
|
49: 0.02040816326530612,
|
||||||
|
50: 0.02,
|
||||||
|
51: 0.0196078431372549,
|
||||||
|
52: 0.019230769230769232,
|
||||||
|
53: 0.018867924528301886,
|
||||||
|
54: 0.018518518518518517,
|
||||||
|
55: 0.01818181818181818,
|
||||||
|
56: 0.017857142857142856,
|
||||||
|
57: 0.017543859649122806,
|
||||||
|
58: 0.017241379310344827,
|
||||||
|
59: 0.01694915254237288,
|
||||||
|
60: 0.016666666666666666,
|
||||||
|
61: 0.01639344262295082,
|
||||||
|
62: 0.016129032258064516,
|
||||||
|
63: 0.015873015873015872,
|
||||||
|
64: 0.015625,
|
||||||
|
65: 0.015384615384615385,
|
||||||
|
66: 0.015151515151515152,
|
||||||
|
67: 0.014925373134328358,
|
||||||
|
68: 0.014705882352941176,
|
||||||
|
69: 0.014492753623188406,
|
||||||
|
70: 0.014285714285714285,
|
||||||
|
71: 0.014084507042253521,
|
||||||
|
72: 0.013888888888888888,
|
||||||
|
73: 0.0136986301369863,
|
||||||
|
74: 0.013513513513513514,
|
||||||
|
75: 0.013333333333333334,
|
||||||
|
76: 0.013157894736842105,
|
||||||
|
77: 0.012987012987012988,
|
||||||
|
78: 0.01282051282051282,
|
||||||
|
79: 0.012658227848101266,
|
||||||
|
80: 0.0125,
|
||||||
|
81: 0.012345679012345678,
|
||||||
|
82: 0.012195121951219513,
|
||||||
|
83: 0.012048192771084338,
|
||||||
|
84: 0.011904761904761904,
|
||||||
|
85: 0.011764705882352941,
|
||||||
|
86: 0.011627906976744186,
|
||||||
|
87: 0.011494252873563218,
|
||||||
|
88: 0.011363636363636364,
|
||||||
|
89: 0.011235955056179775,
|
||||||
|
90: 0.011111111111111112,
|
||||||
|
91: 0.01098901098901099,
|
||||||
|
92: 0.010869565217391304,
|
||||||
|
93: 0.010752688172043012,
|
||||||
|
94: 0.010638297872340425,
|
||||||
|
95: 0.010526315789473684,
|
||||||
|
96: 0.010416666666666666,
|
||||||
|
97: 0.010309278350515464,
|
||||||
|
98: 0.01020408163265306,
|
||||||
|
99: 0.010101010101010102,
|
||||||
|
100: 0.01}
|
||||||
|
for t in range(6, 100):
|
||||||
|
result = pydiceprob.one_turn_single(t)
|
||||||
|
self.assertEqual(result, data[t], f"Should be {data[t]} for dice size {t}.")
|
||||||
|
#+end_src
|
||||||
|
** Multi-turn test
|
||||||
|
As with the other test, we're feeding the correct values, iterating over the
|
||||||
|
possible outputs of the =multi_turn_single= function.
|
||||||
|
#+begin_src python :tangle test.py
|
||||||
|
def test_multi(self):
|
||||||
|
data = { 6: 0.5454545454545455,
|
||||||
|
7: 0.5384615384615383,
|
||||||
|
8: 0.5333333333333333,
|
||||||
|
9: 0.5294117647058822,
|
||||||
|
10: 0.5263157894736844,
|
||||||
|
11: 0.5238095238095235,
|
||||||
|
12: 0.5217391304347823,
|
||||||
|
13: 0.5200000000000005,
|
||||||
|
14: 0.5185185185185185,
|
||||||
|
15: 0.5172413793103451,
|
||||||
|
16: 0.5161290322580645,
|
||||||
|
17: 0.5151515151515152,
|
||||||
|
18: 0.5142857142857141,
|
||||||
|
19: 0.5135135135135128,
|
||||||
|
20: 0.5128205128205127,
|
||||||
|
21: 0.5121951219512191,
|
||||||
|
22: 0.511627906976745,
|
||||||
|
23: 0.5111111111111115,
|
||||||
|
24: 0.5106382978723412,
|
||||||
|
25: 0.510204081632653,
|
||||||
|
26: 0.5098039215686275,
|
||||||
|
27: 0.5094339622641498,
|
||||||
|
28: 0.5090909090909096,
|
||||||
|
29: 0.5087719298245623,
|
||||||
|
30: 0.5084745762711862,
|
||||||
|
31: 0.5081967213114762,
|
||||||
|
32: 0.5079365079365079,
|
||||||
|
33: 0.5076923076923086,
|
||||||
|
34: 0.5074626865671636,
|
||||||
|
35: 0.5072463768115941,
|
||||||
|
36: 0.507042253521126,
|
||||||
|
37: 0.506849315068494,
|
||||||
|
38: 0.5066666666666677,
|
||||||
|
39: 0.5064935064935064,
|
||||||
|
40: 0.5063291139240501,
|
||||||
|
41: 0.506172839506172,
|
||||||
|
42: 0.5060240963855414,
|
||||||
|
43: 0.5058823529411758,
|
||||||
|
44: 0.5057471264367819,
|
||||||
|
45: 0.5056179775280893,
|
||||||
|
46: 0.5054945054945053,
|
||||||
|
47: 0.505376344086021,
|
||||||
|
48: 0.5052631578947361,
|
||||||
|
49: 0.5051546391752573,
|
||||||
|
50: 0.5050505050505041,
|
||||||
|
51: 0.5049504950495041,
|
||||||
|
52: 0.504854368932038,
|
||||||
|
53: 0.5047619047619043,
|
||||||
|
54: 0.5046728971962623,
|
||||||
|
55: 0.5045871559633027,
|
||||||
|
56: 0.5045045045045037,
|
||||||
|
57: 0.5044247787610603,
|
||||||
|
58: 0.5043478260869556,
|
||||||
|
59: 0.5042735042735057,
|
||||||
|
60: 0.504201680672268,
|
||||||
|
61: 0.5041322314049588,
|
||||||
|
62: 0.5040650406504076,
|
||||||
|
63: 0.5039999999999981,
|
||||||
|
64: 0.5039370078740157,
|
||||||
|
65: 0.5038759689922497,
|
||||||
|
66: 0.5038167938931295,
|
||||||
|
67: 0.5037593984962382,
|
||||||
|
68: 0.5037037037037063,
|
||||||
|
69: 0.5036496350364972,
|
||||||
|
70: 0.5035971223021601,
|
||||||
|
71: 0.5035460992907805,
|
||||||
|
72: 0.5034965034965061,
|
||||||
|
73: 0.5034482758620673,
|
||||||
|
74: 0.5034013605442197,
|
||||||
|
75: 0.5033557046979886,
|
||||||
|
76: 0.5033112582781448,
|
||||||
|
77: 0.5032679738562092,
|
||||||
|
78: 0.5032258064516143,
|
||||||
|
79: 0.5031847133757983,
|
||||||
|
80: 0.5031446540880515,
|
||||||
|
81: 0.5031055900621104,
|
||||||
|
82: 0.503067484662576,
|
||||||
|
83: 0.5030303030303014,
|
||||||
|
84: 0.502994011976049,
|
||||||
|
85: 0.5029585798816592,
|
||||||
|
86: 0.5029239766081863,
|
||||||
|
87: 0.5028901734104042,
|
||||||
|
88: 0.5028571428571439,
|
||||||
|
89: 0.5028248587570601,
|
||||||
|
90: 0.502793296089388,
|
||||||
|
91: 0.5027624309392276,
|
||||||
|
92: 0.5027322404371553,
|
||||||
|
93: 0.5027027027027039,
|
||||||
|
94: 0.5026737967914459,
|
||||||
|
95: 0.5026455026455015,
|
||||||
|
96: 0.5026178010471216,
|
||||||
|
97: 0.5025906735751302,
|
||||||
|
98: 0.502564102564102,
|
||||||
|
99: 0.5025380710659929,
|
||||||
|
100: 0.5025125628140696}
|
||||||
|
for t in range(6, 100):
|
||||||
|
result = pydiceprob.multi_turn_single(t)
|
||||||
|
self.assertEqual(result, data[t], f"Should be {data[t]} for dice size {t}.")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#+end_src
|
||||||
|
** Test main entry
|
||||||
|
#+begin_src python :tangle test.py
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main()
|
||||||
|
|
||||||
|
#+end_src
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
import sys
|
import sys
|
||||||
import json
|
import json
|
||||||
import pprint
|
import pprint
|
||||||
|
from fastapi import FastAPI, Header
|
||||||
|
from pydantic import BaseModel
|
||||||
|
|
||||||
pp = pp.Printer = pprint.PrettyPrinter(indent=2, compact=True)
|
pp = pp.Printer = pprint.PrettyPrinter(indent=2, compact=True)
|
||||||
|
|
||||||
def usagequit():
|
def usagequit():
|
||||||
print("""Usage: python pydiceprob.py [k] [mode]
|
print("""Usage: python pydiceprob.py [k] [mode]
|
||||||
k between 6 and 99
|
k between 6 and 99 (higher numbers are supported, up to however much your memory can handle; given that win probabilities approach 50%, this isn't very useful past about 100.)
|
||||||
modes: single, single-table, multi, multi-table
|
modes: single, single-table, multi, multi-table
|
||||||
single prints out the probability of a single throw with a k-sided dice yielding k.
|
single prints out the probability of a single throw with a k-sided dice yielding k.
|
||||||
single-table prints out a table between 6 and k with the probabilities of a single throw yielding k.
|
single-table prints out a table between 6 and k with the probabilities of a single throw yielding k.
|
||||||
|
@ -14,6 +16,23 @@ def usagequit():
|
||||||
multi-table prints out the probability of winning for a range between 6 and k if you have the first throw.""")
|
multi-table prints out the probability of winning for a range between 6 and k if you have the first throw.""")
|
||||||
quit()
|
quit()
|
||||||
|
|
||||||
|
app = FastAPI()
|
||||||
|
|
||||||
|
class APIget(BaseModel):
|
||||||
|
result: dict
|
||||||
|
@app.get("/")
|
||||||
|
async def api_get(k: int = Header(default=None)):
|
||||||
|
if not isinstance(k, int) and k is not None:
|
||||||
|
return {"message": "Header k must be an integer between 6 and 100 inclusive or not present."}
|
||||||
|
if k is None:
|
||||||
|
result = one_turn_table(100)
|
||||||
|
return {"Probabilities of throwing the highest number on dice of size": result}
|
||||||
|
elif k >= 6 and k <= 100:
|
||||||
|
result = one_turn_single(k)
|
||||||
|
return {f"Probability of throwing the highest number of dice of size {k}": result}
|
||||||
|
else:
|
||||||
|
return {"message": "Usage: no request body, use header k to specify what probability you want, if no k, then a table is given between dice sizes 6 and 100 inclusive."}
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
global k
|
global k
|
||||||
try:
|
try:
|
||||||
|
@ -35,30 +54,22 @@ def dispatch(mode, k):
|
||||||
if mode not in modes:
|
if mode not in modes:
|
||||||
usagequit()
|
usagequit()
|
||||||
if mode == "single":
|
if mode == "single":
|
||||||
print(first_turn_probability(k))
|
print(one_turn_single(k))
|
||||||
elif mode == "multi" :
|
elif mode == "multi" :
|
||||||
print(multi_turn_single(k))
|
print(multi_turn_single(k))
|
||||||
elif mode == "single-table":
|
elif mode == "single-table":
|
||||||
print(first_turn_protatbilities(k))
|
print(one_turn_table(k))
|
||||||
elif mode == "multi-table":
|
elif mode == "multi-table":
|
||||||
print(multi_turn_table(k))
|
print(multi_turn_table(k))
|
||||||
|
|
||||||
def dice(k):
|
def one_turn_table(k):
|
||||||
if k < 6:
|
|
||||||
print("Dice must be at least 6-sided")
|
|
||||||
elif k == 6:
|
|
||||||
dice_array = [6]
|
|
||||||
else:
|
|
||||||
dice_array = list(range(6, k))
|
|
||||||
|
|
||||||
def first_turn_probabilities(k):
|
|
||||||
result = {}
|
result = {}
|
||||||
for k in range(6, int(k)+1):
|
for k in range(6, int(k)+1):
|
||||||
result[k] = 1/k
|
result[k] = 1/k
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def first_turn_probability(k):
|
def one_turn_single(k):
|
||||||
return first_turn_probabilities(k)[k]
|
return one_turn_table(k)[k]
|
||||||
|
|
||||||
def multi_turn_single(k):
|
def multi_turn_single(k):
|
||||||
p_win = 1 / k # Winning probability on any given throw
|
p_win = 1 / k # Winning probability on any given throw
|
||||||
|
|
Loading…
Reference in a new issue