|
| 1 | +# Tutorial 4: Simulations |
| 2 | +# Due: Tuesday, March 23 @ 11:55 PM |
| 3 | +# Hosna Hamdieh |
| 4 | +# A4: This assignment had 5 questions pluse an extra and in order to run each uncomment the function at the end of each |
| 5 | +############################ 1. Blood Pressure ######################### |
| 6 | +# High blood pressure can require immediate medical attention. Write a program that allows a |
| 7 | +# doctor to identify a patient's blood pressure category given the systolic and diastolic blood |
| 8 | +# pressure. |
| 9 | +class Doctor: |
| 10 | + def __init__(self,Systolic_Blood_Pressure,Diastolic_Blood_Pressure): |
| 11 | + self.Systolic_Blood_Pressure=Systolic_Blood_Pressure |
| 12 | + self.Diastolic_Blood_Pressure=Diastolic_Blood_Pressure |
| 13 | + |
| 14 | + def Blood_Pressure_Category(self): |
| 15 | + if self.Systolic_Blood_Pressure<120 and self.Diastolic_Blood_Pressure<80: |
| 16 | + self.Category="Normal" |
| 17 | + elif self.Systolic_Blood_Pressure<129 and self.Diastolic_Blood_Pressure<80: |
| 18 | + self.Category = "Elevated" |
| 19 | + elif self.Systolic_Blood_Pressure<139 or self.Diastolic_Blood_Pressure<89: |
| 20 | + self.Category = "Hypertension Stage 1 " |
| 21 | + elif self.Systolic_Blood_Pressure<180 or self.Diastolic_Blood_Pressure<120: |
| 22 | + self.Category = "Hypertension Stage 2 " |
| 23 | + elif self.Systolic_Blood_Pressure>180 or self.Diastolic_Blood_Pressure>120: |
| 24 | + self.Category = "Hypertensive crisis " |
| 25 | + return self.Category |
| 26 | + |
| 27 | +def Blood_Pressure(): |
| 28 | + print("Welcome") |
| 29 | + Systolic_Blood_Pressure = int(input("What is your Systolic_Blood_Pressure? ")) |
| 30 | + Diastolic_Blood_Pressure = int(input("What is your Diastolic_Blood_Pressure ")) |
| 31 | + BP=Doctor(Systolic_Blood_Pressure,Diastolic_Blood_Pressure) |
| 32 | + BPC = BP.Blood_Pressure_Category() |
| 33 | + print(f"Based on the information you have shared your blood pressure category is {BPC}") |
| 34 | + |
| 35 | +# Blood_Pressure() |
| 36 | + |
| 37 | +############################################## 2. Yahtzee ############################## |
| 38 | +# In the game of Yahtzee, players roll 5 dice, and score different points depending on the dice |
| 39 | +# they roll. A player rolls a “Yahtzee” when all 5 of the dice have the same value. Develop a Monte |
| 40 | +# Carlo simulation in Python to estimate the probability of rolling a Yahtzee. |
| 41 | + |
| 42 | +#roll the dice |
| 43 | +def roll(): |
| 44 | + import random |
| 45 | + Values = [] |
| 46 | + for i in range(0, 5): |
| 47 | + Value = random.randint(1,6) |
| 48 | + Values.append(Value) |
| 49 | + return Values |
| 50 | + |
| 51 | +# Yahtzee win |
| 52 | +def play(): |
| 53 | + Values = roll() |
| 54 | + Game="" |
| 55 | + if Values[0]==Values[1]==Values[2]==Values[3]==Values[4]: |
| 56 | + Game = "win" |
| 57 | + print("You have won in Yahtzee") |
| 58 | + else: |
| 59 | + print("Maybe next time") |
| 60 | + return Game |
| 61 | + |
| 62 | +# Monte Carlo simulation of Yahtzee |
| 63 | +def Yahtzee(): |
| 64 | + n=int(input("How many times do you want to run the simulation? ")) |
| 65 | + win=0 |
| 66 | + for i in range(n): |
| 67 | + Game = play() |
| 68 | + if Game == "win": |
| 69 | + win += 1 |
| 70 | + probability_of_win = win/n |
| 71 | + print(f"Out of {n} times you have won {win} which means the probability of winning this game is {probability_of_win} which is not that high") |
| 72 | + |
| 73 | +#Yahtzee() # needs n |
| 74 | +# Some results |
| 75 | +# Yahtzee() # for n=100 => Out of 100 times you have won 1 which means the probability of winning this game is 0.01 which is not that high |
| 76 | +# Yahtzee() # for n=1000 => Out of 1000 times you have won 1 which means the probability of winning this game is 0.001 which is not that high |
| 77 | +# Yahtzee() # for n=10000=> Out of 10000 times you have won 6 which means the probability of winning this game is 0.0006 which is not that high |
| 78 | +# Yahtzee() # for n=100000 => Out of 100000 times you have won 75 which means the probability of winning this game is 0.00075 which is not that high |
| 79 | +# Yahtzee() # for n=1000000 => Out of 1000000 times you have won 777 which means the probability of winning this game is 0.000777 which is not that high |
| 80 | + |
| 81 | +###################################################### 3. Birthdays #################### |
| 82 | +# The birthday problem concerns the probability that within a group of n randomly selected |
| 83 | +# people, two people will have the same birthday. For example, in a group of 70 random people, |
| 84 | +# there is a 99.9% chance that two people will share the same birthday. |
| 85 | +# https://en.wikipedia.org/wiki/Birthday_problem |
| 86 | +# Develop a Monte Carlo simulation in Python to estimate the probability that in our class of 30 |
| 87 | +# students, at least two students share a birthday. |
| 88 | +def Duplicate_Birthdays(n): |
| 89 | + global yes |
| 90 | + from random import randint |
| 91 | + BD=[] |
| 92 | + d=0 |
| 93 | + for i in range(n): |
| 94 | + bd=randint(1,365) |
| 95 | + if bd not in BD: |
| 96 | + BD.append(bd) |
| 97 | + else: |
| 98 | + d+=1 |
| 99 | + if d!=0: |
| 100 | + yes += 1 |
| 101 | + probability_of_duplicates = d/n |
| 102 | + print(f"Out of {n} people in the room same birthdays happened {d} times") |
| 103 | + return d |
| 104 | + |
| 105 | +def Birthdays(): |
| 106 | + m=int(input("How many times do you like to run the simulation: ")) |
| 107 | + global yes |
| 108 | + yes=0 |
| 109 | + n = int(input("How many people are in the class? ")) |
| 110 | + D=0 |
| 111 | + for i in range(m): |
| 112 | + d = Duplicate_Birthdays(n) |
| 113 | + D += d |
| 114 | + Pyes = yes/(m) |
| 115 | + # probability_of_duplicates=D/(m*n) |
| 116 | + print(f"The chances of at least two people having the same birthday in a room with {n} people after repeting the simulation {m} times is {Pyes} and in this run same birthdays happened {D} times") |
| 117 | +# Birthdays_Simulation() # inputs needed n,m |
| 118 | +# some results |
| 119 | +# Birthdays_Simulation() # for n=30,m=10000 => The chances of at least two people having the same birthday in a room with 30 people after repeting the simulation 10000 times is 0.7059 and in this run same birthdays happened 11523 times |
| 120 | +# Birthdays_Simulation() # for n=30,m=100000=> The chances of at least two people having the same birthday in a room with 30 people after repeting the simulation 100000 times is 0.70681 and in this run same birthdays happened 116114 times |
| 121 | + |
| 122 | +###################################################################### 4. Craps ############################ |
| 123 | +# Craps is a dice game played at many casinos. A player rolls a pair of normal six-sided dice. If |
| 124 | +# the initial roll is 2, 3, or 12, the player loses. If the roll is 7 or 11, the player wins. Any other initial |
| 125 | +# roll causes the player to "roll for point." That is, the player keeps rolling the dice until either |
| 126 | +# rolling a 7 or re-rolling the value of the initial roll. If the player re-rolls the initial value before |
| 127 | +# rolling a 7, it's a win. Rolling a 7 first is a loss. |
| 128 | +# Write a program to simulate multiple games of craps and estimate the probability that the player |
| 129 | +# wins. For example, if the player wins 249 out of 500 games, then the estimated probability of |
| 130 | +# winning is 249/500 = 0.498. |
| 131 | +import random |
| 132 | + |
| 133 | +rng = range |
| 134 | +inp = input |
| 135 | + |
| 136 | +def makeNSidedDie(n): |
| 137 | + _ri = random.randint |
| 138 | + return lambda: _ri(1,n) |
| 139 | + |
| 140 | +class Craps_Play(object): |
| 141 | + def __init__(self): |
| 142 | + super(Craps_Play,self).__init__() |
| 143 | + self.die = makeNSidedDie(6) |
| 144 | + self.firstRes = (0, 0, self.lose, self.lose, 0, 0, 0, self.win, 0, 0, 0, self.win, self.lose) |
| 145 | + self.reset() |
| 146 | + |
| 147 | + def reset(self): |
| 148 | + self.wins = 0 |
| 149 | + self.losses = 0 |
| 150 | + |
| 151 | + def win(self): |
| 152 | + self.wins += 1 |
| 153 | + return True |
| 154 | + |
| 155 | + def lose(self): |
| 156 | + self.losses += 1 |
| 157 | + return False |
| 158 | + |
| 159 | + def roll(self): |
| 160 | + return self.die() + self.die() |
| 161 | + |
| 162 | + def play(self): |
| 163 | + first = self.roll() |
| 164 | + res = self.firstRes[first] |
| 165 | + if res: |
| 166 | + return res() |
| 167 | + else: |
| 168 | + while True: |
| 169 | + second = self.roll() |
| 170 | + if second == 7: |
| 171 | + return self.lose() |
| 172 | + elif second == first: |
| 173 | + return self.win() |
| 174 | + |
| 175 | + def times(self, n): |
| 176 | + wins = sum(self.play() for i in rng(n)) |
| 177 | + return wins, n-wins |
| 178 | + |
| 179 | +def craps(): |
| 180 | + import random |
| 181 | + c = Craps_Play() |
| 182 | + m = 0 |
| 183 | + while True: |
| 184 | + try: |
| 185 | + n = int(input("How many rounds of craps would you like to play? (0 to quit) ")) |
| 186 | + m += n |
| 187 | + |
| 188 | + print("Won {0}, lost {1}".format(*(c.times(n)))) |
| 189 | + print("Based on the outcome the game probability of wining is {1} after {0} rounds""".format(n, (c.wins)/n)) |
| 190 | + |
| 191 | + except: |
| 192 | + print("You have chosen to finish the game") |
| 193 | + break |
| 194 | + print("""In Total number of wins are {0}, and losses are {1} |
| 195 | +The probability of wining in total after playing the game {2} times is {3}""".format(c.wins, c.losses, m, (c.wins)/m)) |
| 196 | + |
| 197 | +#craps() |
| 198 | + |
| 199 | +# Result |
| 200 | +"""How many rounds of craps would you like to play? (0 to quit) 10 |
| 201 | +Won 5, lost 5 |
| 202 | +Based on the outcome the game probability of wining is 0.5 after 10 rounds |
| 203 | +How many rounds of craps would you like to play? (0 to quit) 100 |
| 204 | +Won 43, lost 57 |
| 205 | +Based on the outcome the game probability of wining is 0.48 after 100 rounds |
| 206 | +How many rounds of craps would you like to play? (0 to quit) 1000 |
| 207 | +Won 505, lost 495 |
| 208 | +Based on the outcome the game probability of wining is 0.553 after 1000 rounds |
| 209 | +How many rounds of craps would you like to play? (0 to quit) |
| 210 | +You have chosen to finish the game |
| 211 | +In Total number of wins are 553, and losses are 557 |
| 212 | +The probability of wining in total after playing the game 1110 times is 0.4981981981981982""" |
| 213 | + |
| 214 | +########################################################## 5. Gaming ###################### |
| 215 | +# In a computer-based trading card game, players use in-game currency to draw cards. The |
| 216 | +# probability of drawing each card type is as follows: |
| 217 | +# Common: 94.3% |
| 218 | +# Rare: 5.1% |
| 219 | +# Legendary: 0.6% |
| 220 | +# However, because the rates for rare and legendary cards are so low, the game also includes the |
| 221 | +# following rules: |
| 222 | +# 1. If a Rare card is not drawn after 9 attempts, a Rare card is guaranteed on the 10th |
| 223 | +# attempt. |
| 224 | +# 2. If a Legendary card is not drawn after 75 attempts, the probability of drawing a |
| 225 | +# Legendary card on subsequent attempts increases to 30%. |
| 226 | +# 3. If a Legendary card is not drawn after 89 attempts, a Legendary card is guaranteed on |
| 227 | +# the 90th attempt. |
| 228 | +# Develop a Monte Carlo simulation to estimate the effective probabilities of drawing Rare and |
| 229 | +# Legendary cards. |
| 230 | +import random |
| 231 | +def drawCard(pc,pr,pl): |
| 232 | + r = random.random() |
| 233 | + if r < (pc/100): |
| 234 | + card = 'Common' |
| 235 | + elif r < (pc+pr)/100: |
| 236 | + card = "Rare" |
| 237 | + elif r >= (1-pl)/100: |
| 238 | + card = "Legendary" |
| 239 | + return card |
| 240 | + |
| 241 | +def Gaming(): |
| 242 | +# testing |
| 243 | + A = int(input("""Which one would you like: 1. Testing with the probabilities avaiable in the program or test it with the numbers you want? |
| 244 | +Answer (1 or 2): """)) |
| 245 | + if A == 1: |
| 246 | + pc, pr, pl = 94.3, 5.1, 0.6 |
| 247 | + elif A == 2: |
| 248 | + pc = int(input("What is the probability of getting a common card? pc= ")) |
| 249 | + pr = int(input("What is the probability of getting a rare card? pr= ")) |
| 250 | + pl = int(input("What is the probability of getting a legendary card? pl= ")) |
| 251 | + else: |
| 252 | + print("Your input is not valid") |
| 253 | + cards = [] |
| 254 | + rare = 0 |
| 255 | + legendary = 0 |
| 256 | + common = 0 |
| 257 | + i = 1 |
| 258 | + P = (input("How many times do you want to simulate the card function: ")) |
| 259 | + try: |
| 260 | + play = int(P) |
| 261 | + for i in range(play): |
| 262 | + # If a Legendary card is not drawn after 89 attempts, a Legendary card is guaranteed on the 90th attempt. |
| 263 | + if "Legendary" not in cards[-89:]: |
| 264 | + card = "Legendary" |
| 265 | + # If a Rare card is not drawn after 9 attempts, a Rare card is guaranteed on the 10th attempt. |
| 266 | + elif "Rare" not in cards[-9:]: |
| 267 | + card = "Rare" |
| 268 | + # If a Legendary card is not drawn after 75 attempts, the probability of drawing a Legendary card on subsequent attempts increases to 30%. |
| 269 | + elif "Legendary" not in cards[-75:]: |
| 270 | + pcn = pc - (30 - pl) |
| 271 | + pln = 30 |
| 272 | + card = drawCard(pcn, pr, pln) |
| 273 | + else: |
| 274 | + card = drawCard(pc, pr, pl) |
| 275 | + cards.append(card) |
| 276 | + if card == 'Common': |
| 277 | + common += 1 |
| 278 | + elif card == "Rare": |
| 279 | + rare += 1 |
| 280 | + else: |
| 281 | + legendary += 1 |
| 282 | + # play = input( |
| 283 | + # f"""You have randomly selected {i} cards up to now enter if you do not want to continue otherwise type more """) |
| 284 | + i += 1 |
| 285 | + # Probabilities after doing the simulation |
| 286 | + print(f"""You have randomly selected {i} cards and the list of cards is {cards} |
| 287 | +The total number of common cards is {common}, rare cards is {rare}, and you got {legendary} legendary cards |
| 288 | +Based on the simulation the probabilities are: |
| 289 | +The probability of getting a common card is {common/play}, |
| 290 | +The probability of getting a rare card is {rare/play}, |
| 291 | +The probability of getting a legendary card is {legendary/play} |
| 292 | +We can see that new roles have increased the probability of getting rare cards and legendary cards a bit""") |
| 293 | + except: |
| 294 | + print("Your input is not valid") |
| 295 | +#Gaming() # the number of sumilation is needed there is also a chance of changing the probabilities |
| 296 | +"""outcome after trying the simulation for n=1000 is: |
| 297 | +You have randomly selected 1000 cards |
| 298 | +The total number of common cards is 861, rare cards is 124, and you got 15 legendary cards |
| 299 | +Based on the simulation the probabilities are: |
| 300 | +The probability of getting a common card is 0.861, |
| 301 | +The probability of getting a rare card is 0.124, |
| 302 | +The probability of getting a legendary card is 0.015 |
| 303 | +We can see that new roles have increased the probability of getting rare cards and legendary cards a bit""" |
| 304 | +"""outcome after trying the simulation for n=100 is: |
| 305 | +The total number of common cards is 84, rare cards is 13, and you got 3 legendary cards |
| 306 | +Based on the simulation the probabilities are: |
| 307 | +The probability of getting a common card is 0.84, |
| 308 | +The probability of getting a rare card is 0.13, |
| 309 | +The probability of getting a legendary card is 0.03 |
| 310 | +We can see that new roles have increased the probability of getting rare cards and legendary cards a bit""" |
| 311 | + |
| 312 | +########################################## Bonus #################################### |
| 313 | +"""An E. coli bacterium is swimming in a porous circular bag with a radius of 1 mm. Every second, |
| 314 | +the bacterium randomly changes the direction that it is swimming in. If the bacterium starts in |
| 315 | +the centre of the bag, and swims at a rate of 0.06 mm per second, how long, on average, will it |
| 316 | +take the bacterium to escape the bag? """ |
| 317 | +"""To make things visible the scales were change and multiplied by 50 that is why the speed was changed from 0.06 to 3 and similarly to make things go faster the time step was changed from 1 second to 0.001 but each step is counted and the time is calculated based on each movement happening in one second. |
| 318 | +One problem was that the bag size had to be converted and it was not obvious at first. |
| 319 | +""" |
| 320 | + |
| 321 | +from math import * |
| 322 | +import graphics |
| 323 | +from random import * |
| 324 | +import time |
| 325 | +def Brownian_Motion(): |
| 326 | + win = graphics.GraphWin("Brownian", 500, 500) |
| 327 | + p0 = graphics.Point(250, 250) |
| 328 | + # converting the bage size based on the fact that each pixel is 26 mm in each side |
| 329 | + # making dimentions bigger to be visiable so all sizes are multiplied by 50 |
| 330 | + bag = graphics.Circle(p0, 5000/(26*(2**0.5))) |
| 331 | + bag.setFill("lightsteelblue") |
| 332 | + bag.draw(win) |
| 333 | + particle = graphics.Circle(p0, 10) |
| 334 | + particle.setFill("yellow") |
| 335 | + particle.draw(win) |
| 336 | + i = 1 |
| 337 | + x = [500] |
| 338 | + y = [500] |
| 339 | + while win.checkMouse() == None: |
| 340 | + # making the simulations faster by 1000 times |
| 341 | + time.sleep(0.001) |
| 342 | + p = particle.getCenter() |
| 343 | + angle = random() * 2 * pi |
| 344 | + x.append(x[i-1] + cos(angle)) |
| 345 | + y.append(y[i-1] + sin(angle)) |
| 346 | + #line = graphics.Line(p, p0).draw(win) |
| 347 | + d = (((((x[i] - x[0])/50) ** 2) + (((y[i] - y[0])/50) ** 2)) ** 0.5) |
| 348 | + if d <= 1: |
| 349 | + particle.move(sin(angle) * 0.06*50, cos(angle) * 0.06*50) |
| 350 | + pn = particle.getCenter() |
| 351 | + line = graphics.Line(p, pn).draw(win) |
| 352 | + print(f"the new point is located in x={x[i]} and y={y[i]} and is {d} far from the start point") |
| 353 | + # since each step should have been 1 second we can assume that the number of times we repeat it would be the time taken in seconds |
| 354 | + i += 1 |
| 355 | + else: |
| 356 | + print(f"It took {i} seconds for the Brownian to reach the bag's border and go out of it") |
| 357 | + break |
| 358 | + win.getMouse() |
| 359 | + win.close() |
| 360 | + return i |
| 361 | +def Bonous(): |
| 362 | + n = int(input("How many times do you want to simulate this function: ")) |
| 363 | + Ttime = 0 |
| 364 | + Times = [] |
| 365 | + for i in range(n): |
| 366 | + t = Brownian_Motion() |
| 367 | + Times.append(t) |
| 368 | + Ttime += t |
| 369 | + ta = Ttime/n |
| 370 | + print(f"""After repeating the process {n} times the average time of scape is {ta} |
| 371 | +List of scape times is: {Times}""") |
| 372 | +Bonous() # number of symulation is needed |
| 373 | +""" |
| 374 | +It took 6925 seconds for the Brownian to reach the bag's border and go out of it |
| 375 | +It took 2121 seconds for the Brownian to reach the bag's border and go out of it |
| 376 | +It took 5222 seconds for the Brownian to reach the bag's border and go out of it |
| 377 | +It took 3062 seconds for the Brownian to reach the bag's border and go out of it |
| 378 | +It took 1106 seconds for the Brownian to reach the bag's border and go out of it |
| 379 | +After repeating the process 5 times the average time of scape is 3687.2""" |
| 380 | + |
| 381 | +"""After repeating the process 10 times the average time of scape is 1907.0 |
| 382 | +List of scape times is: [4283, 2568, 1651, 504, 2335, 1537, 1099, 2957, 1565, 571]""" |
| 383 | + |
| 384 | +############################################## The End ################################## |
0 commit comments