Skip to content

Instantly share code, notes, and snippets.

@alice1017
Created September 3, 2018 05:36
Show Gist options
  • Save alice1017/2704aeb959c0d6b56289f112758d14a8 to your computer and use it in GitHub Desktop.
Save alice1017/2704aeb959c0d6b56289f112758d14a8 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
# coding: utf-8
import copy
import random
import unittest
# Helper funcs
# is_dict = (lambda obj: isinstance(obj, dict))
def random_choose(options):
return random.choice(options)
def init_db():
db = {"A": False, "B": False, "C": False}
hit = random_choose(db.keys())
db[hit] = True
return db, hit
def user_choose(db):
# NOTE:
# There are two cases of user choosing because I think
# it will change the result of monty-hole problem.
# case1: random choose
return random_choose(db.keys())
# case2: always choose 'B'
# return "B"
def show_false_door(db, user):
_db = copy.deepcopy(db)
if len(_db) != 3:
raise IndexError("error: the length of db object must be three.")
if _db.pop(user) is True:
return random_choose(_db.keys())
else:
doors = _db.keys()
other = doors[0]
another = doors[1]
other_door = _db[other]
return another if other_door is True else other
def change_door(db, user, false):
_db = copy.deepcopy(db)
_db.pop(false)
_db.pop(user)
return _db.keys()[0]
def game_user_changes():
# 1. init db
answer_db, true_door = init_db()
# 2. user chooses one door
user_chosen = user_choose(answer_db)
# 3. show false door
false_door = show_false_door(answer_db, user_chosen) # user knows
# 4. case1: change a door
changed_user_door = change_door(answer_db, user_chosen, false_door)
# 5. show true door
if changed_user_door == true_door:
return True
else:
return False
def game_not_changes():
# 1. init db
answer_db, true_door = init_db()
# 2. user chooses one door
user_chosen = user_choose(answer_db)
# 3. show false door
false_door = show_false_door(answer_db, user_chosen) # user knows
# 4. case2: don't change a door
# 5. show true door
if user_chosen == true_door:
return True
else:
return False
def game_test(total_times):
result_db1 = {True: 0, False: 0}
result_db2 = copy.deepcopy(result_db1)
for times in range(total_times):
result = game_user_changes()
if result is True:
result_db1[True] += 1
else:
result_db1[False] += 1
result2 = game_not_changes()
if result2 is True:
result_db2[True] += 1
else:
result_db2[False] += 1
print ""
print "GAME TYPE: user changes door"
print "-----------------------------------"
print "total: {0}".format(total_times)
print "GAME RESULT - TRUE: {0}".format(result_db1[True])
print " - FALSE: {0}".format(result_db1[False])
print ""
print "***********************************"
print ""
print "GAME TYPE: user don't changes door"
print "-----------------------------------"
print "total: {0}".format(total_times)
print "GAME RESULT - TRUE: {0}".format(result_db2[True])
print " - FALSE: {0}".format(result_db2[False])
class MontyHoleTestCase(unittest.TestCase):
def setUp(self):
self.db = init_db()
def test_init(self):
self.assertTrue(True in self.db.values())
def test_choose(self):
user_chosen = user_choose(self.db)
self.assertTrue(user_chosen in self.db.keys())
def test_false_door(self):
db = {"A": True, "B": False, "C": False}
testcase1 = "A"
testcase2 = "B"
result1 = show_false_door(db, testcase1)
result2 = show_false_door(db, testcase2)
self.assertTrue(result1 == "B" or result1 == "C")
self.assertEqual(result2, "C")
with self.assertRaises(IndexError):
show_false_door({"A": True, "B": False, "C": False, "D": False}, "B")
show_false_door({"A": True, "B": False, "C": False, "D": False}, "A")
if __name__ == "__main__":
# unittest.main(verbosity=2)
total_times = 100000
game_test(total_times)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment