Last active
November 12, 2020 05:03
-
-
Save JackKuo-tw/2adeabc53049f9c61d699c6427fdb45b to your computer and use it in GitHub Desktop.
General Monty Hall Calculation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
import random | |
DOORS = 4 | |
EPOCH = 10000 | |
KEY_POINT_TIME = 2 | |
# ENUM | |
result = { | |
'win': 0, | |
'lose': 1, | |
'none': 2 | |
} | |
# global variable | |
game_history = [] | |
def main(): | |
customize() | |
for _ in range(EPOCH): | |
run_the_test() | |
cal_probability() | |
def do_guess(car, now_doors) -> (int, int, int): | |
"""Participant makes decision here""" | |
choose_this_time = random.choice(now_doors) | |
# remove the "car door" and the "door choose this time" | |
now_doors.remove(car) | |
if car != choose_this_time: | |
now_doors.remove(choose_this_time) | |
if len(now_doors) == 0: # choose_this_time != car | |
return None, choose_this_time, result['lose'] | |
elif len(now_doors) == 1 and choose_this_time == car: # choose_this_time == car | |
return None, choose_this_time, result['win'] | |
else: | |
now_open = random.choice(now_doors) | |
return now_open, choose_this_time, result['none'] | |
def judge(r, choose_history) -> None: | |
# if r: | |
# print("lose") | |
# else: | |
# print("win") | |
game_history.append({'choose': choose_history, 'result': r}) | |
def run_the_test() -> None: | |
"""Run the test for 1 time""" | |
# initialize the doors | |
now_doors = [i for i in range(DOORS)] | |
# choose which door has car | |
car = random.choice(now_doors) | |
# initialize the guess history | |
choose_history = [] | |
while len(now_doors) > 1: | |
now_open, choose_this_time, r = do_guess(car, now_doors.copy()) | |
choose_history.append(choose_this_time) | |
if r == result['none']: # not win, not lose, the game continues | |
now_doors.remove(now_open) | |
else: | |
judge(r, choose_history) | |
return | |
def cal_probability() -> None: | |
"""calculate the probability""" | |
change_win = 0 | |
change_lose = 0 | |
unchange_win = 0 | |
unchange_lose = 0 | |
for game in game_history: | |
# change | |
if game['choose'][KEY_POINT_TIME] != game['choose'][KEY_POINT_TIME - 1]: | |
if game['result'] == result['win']: | |
change_win += 1 | |
else: | |
change_lose += 1 | |
# unchange | |
else: | |
if game['result'] == result['win']: | |
unchange_win += 1 | |
else: | |
unchange_lose += 1 | |
print(f"Change at the time {str(KEY_POINT_TIME)}:") | |
if change_win + change_lose == 0: # prevent ZeroDivisionError | |
change_win_ratio = 100 | |
else: | |
change_win_ratio = round(change_win / (change_win + change_lose) * 100, 2) | |
print(f" Win:{change_win_ratio}%") | |
print(f" Lose:{round(100 - change_win_ratio, 2)}%") | |
print(f"Unchange at the time {str(KEY_POINT_TIME)}:") | |
if unchange_win + unchange_lose == 0: # prevent ZeroDivisionError | |
unchange_win_ratio = 100 | |
else: | |
unchange_win_ratio = round(unchange_win / (unchange_win + unchange_lose) * 100, 2) | |
print(f" Win:{unchange_win_ratio}%") | |
print(f" Lose:{round(100 - unchange_win_ratio, 2)}%") | |
def validate() -> None: | |
if KEY_POINT_TIME > (DOORS - 2): | |
print(f"**Error:up to {DOORS - 2} time in {DOORS} door**") | |
exit() | |
def customize() -> None: | |
"""Customize input parameter""" | |
global DOORS, EPOCH, KEY_POINT_TIME | |
try: | |
# Doors | |
q_doors = input(f"How many doors?[default {DOORS}] ") | |
if q_doors != '' and int(q_doors) > 2: | |
DOORS = int(q_doors) | |
# Epoch | |
q_epoch = input(f"How many times shoud it test?[default {EPOCH}] ") | |
if q_epoch != '' and int(q_epoch) > 0: | |
EPOCH = int(q_epoch) | |
# Key point time | |
q_key = input(f"Which time of asking?[default {KEY_POINT_TIME}] ") | |
if q_key != '' and int(q_key) > 0: | |
KEY_POINT_TIME = int(q_key) | |
print("\n--------\n") | |
validate() | |
print(f"{DOORS} doors, test {EPOCH} times, ask at the time {KEY_POINT_TIME}\n") | |
except ValueError: | |
print("**Error:please input a number**") | |
exit() | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment