- 17th Feb 2024
- 06:03 am
Question
What is the probability that at any given time, this coin is fair, or inversely what is the probability that the coin isn't fair? Changes need to be made in the file uploaded. We can create a function or use a function that already exists.
Solution
#!/usr/bin/env python # coding: utf-8 # In[1]: ## file name = LAST_FIRST_CP1.py # valid imports import numpy as np import time import pandas as pd import random as r from scipy.stats import binom # additional imports will result in failure. You certainly do not need to use all the imports.# class ENUMS: # this exact code will live in my test environment FAIR = 'FAIR' NOT_FAIR = 'NOT_FAIR' class Grader: # this will be hidden from you. Any attempt to interact with it other than Grader.flip_coin() will result in failure. def __init__(self, parameters = None): self.coin = Coin() if parameters == None: self.cost_of_collection = 1 #r.randint(1,5) # will be locked for all submissions at grading with a value in range self.cost_of_error = 1000 # r.randint(1,5)*1000 # will be locked for all submissions at grading with a value in range self.profit_from_correct = 500 #r.randint(1,5)*100 # will be locked for all submissions at grading with a value in range else: self.cost_of_collection, self.cost_of_error, self.profit_from_correct = parameters # rough approximation for grades at the values 1,1000,500 with 100 trials: # C > 15000 # B > 20000 # A > 25000 # processor cost = elapsed time squared see if name == __main__ code for implementation # auto fail at 1 minute for 10 trials. def get_parameters(self): print('cost of collection', 'cost of error', 'profit from correct') return self.cost_of_collection, self.cost_of_error, self.profit_from_correct def flip_coin(self): return self.coin.flip() def example_grader(self, submission, trials): submission:Submission correct_determinations = 0 rolls = 0 for i in range(trials): self.coin = Coin() submission.run() rolls += self.coin.n correct = self.coin.render_judgment(submission.verdict) if correct: correct_determinations += 1 score = correct_determinations*self.profit_from_correct - self.cost_of_collection*rolls - self.cost_of_error*(trials-correct_determinations) print(str(int(correct_determinations/trials*100)) + '% using ', rolls, 'total coin flips.') return score class Coin: # this will be hidden from you. Any attempt to interact with it result in failure. def __init__(self): self.p = r.randint(4,6)/10 self.n = 0 def flip(self): self.n += 1 return r.random()<self.p def render_judgment(self, judgment): if judgment == ENUMS.FAIR and self.p == .5 or judgment == ENUMS.NOT_FAIR and self.p != .5: return True return False class Submission: # this class contains the code you should change # #! says don't change me # #! as the first line of a function says don't change any of me # do not remove any functions # you may add functions def __init__(self, grader): self.author = 'LAST_FIRST' # LAST_FIRST self.collaborators = [] # LAST_FIRST of anyone you collaborated with e.g ['APEL_BOB','JANE_DOE'] self.grader = grader #! def run(self): #! self.history = [] self.gather_data() self.verdict = self.evaluate_coin(self.history) def flip_coin(self): #! self.history.append(self.grader.flip_coin()) def gather_data(self): # your logic for when to stop gathering data # the code below defaults to 1000 flips, you can and should change it. for i in range(200): self.flip_coin() @staticmethod def evaluate_coin(history): # this is called once and should render a FAIR or NOT_FAIR (enumed in Enum) # this is the place where your work should be. The code below results in a D with a sample of 200. p = sum(history)/len(history) if abs(p - 0.5) < 0.05: return ENUMS.FAIR else: return ENUMS.NOT_FAIR if __name__ == '__main__': # this will be run from my side of the world. It is here to give you an example of how I will evaluate your code. # though you can modify it I would not recommend it. # this code will not be run when your assignment is graded as the condition is not met. # for your own calibration, the example Submission, with a gather data hard set to 1000, uses .7 seconds processing time on my computer. scores = [] author = None start = time.time() fail = False runs = 10 trials_per_run = 100 for i in range(runs): # grader runs 100 tests each run so this is 1000 coins worth of assessments as currently configured. print(i) g = Grader([1,1000,500]) s = Submission(g) scores.append(g.example_grader(s,trials_per_run)) elapsed = time.time()-start if elapsed > 60: fail = True if fail: score = 0 else: score = pd.Series(scores).mean() score -= elapsed*elapsed if score < 0: score = 0 p = score/25000 if p > 1: extra_credit = p-1 if extra_credit > .2: extra_credit = .2 p = 1 + extra_credit print(s.author, 'scored', int(score),'out of 25000, and used', elapsed, 'seconds.') print('Translated to course points this is ', int(p * 20), ' out of 20.') # In[ ]: