Python : Calculating probability of a dice throw function - python

Hello this is a question I have been tasked with.
..........................................................................................................
You are at the bottom of a staircase with a die. With each throw of the die, you
either move down one step (if you get a 1 or 2 on the dice) or move up one step (if you get a
3, 4, or 5 on the dice). If you throw a 6 on the die, you throw the die again and move up the
staircase by the number you get on that second throw. Note if you are at the base of the
staircase, you cannot move down!
The function has a parameter that takes a probability distribution over all
outcomes from a dice throw. For example (0.2,0.3,0.2,0.1,0.1,0.1) would suggest that the
probability of getting a 1 is 0.2, 2 is 0.3 etc. Calculate the probability of reaching a step
higher than the 200th one for the following case: 100 throws, [0.2,0.2,0.2,0.2,0.1,0.1] distribution.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
I have been able to create some code which serves as the function (I'm sure it could be simplified but I am new to this) however I am unsure as to how to work out the probability of it being higher than the 200th step.
import random
def rolldice(T:int, D): #T = throws, D = distribution in format [0.0,0.0,0.0,0.0,0.0,1] [0.2,0.2,0.2,0.2,0.1,0.1]
Stair = 0
for i in range(T):
print(i,Stair)
roll = random.choices([1,2,3,4,5,6], weights= D)
roll2 = random.choices([1,2,3,4,5,6])
roll1 = roll[0]
if roll[0] == 1 and Stair > 0:
Stair -= 1
elif roll[0] == 2 and Stair > 0:
Stair -= 1
elif roll[0] == 3:
Stair += 1
elif roll[0] == 4:
Stair += 1
elif roll[0] == 5:
Stair += 1
elif roll[0] == 6:
Stair += roll2[0]
return Stair
rolldice(100, [0.2,0.2,0.2,0.2,0.1,0.1])

You could assign T to 1000 by an input function and it would then loop for a certain amount of throws.

Related

Infinite Loop help in Python

Can someone help me figure out why this loop is infinite? The class I am in automatically inputs the variables for me per those last 2 lines. It passes the test with numbers 2 and 4. However there is another input, that I am unable to see, that keeps this running as an infinite loop. I can not figure out where there is a gap in this code that would allow an infinite loop. Any suggestions?
def shampoo_instructions(user_cycles):
N = 1
while N <= user_cycles:
if N < 1:
print('Too few')
elif N > 4:
print('Too many')
else:
print(N,': Lather and rinse.')
N = N + 1
print('Done.')
user_cycles = int(input())
shampoo_instructions(user_cycles)
Indent N = N + 1 out of the loop, otherwise it never get's to adding.
Or better use N += 1:
def shampoo_instructions(user_cycles):
N = 1
while N <= user_cycles:
if N < 1:
print('Too few')
elif N > 4:
print('Too many')
else:
print(N,': Lather and rinse.')
N = N + 1
print('Done.')
user_cycles = int(input())
shampoo_instructions(user_cycles)
First: get used to testing your code. Since you have conditionals involving the numbers 1 and 4, you should test numbers that are less than 1 and greater than 4 to see what happens beyond those edges. Sure enough, giving 5 as an input produces an infinite loop:
0
Done.
1
1 : Lather and rinse.
Done.
4
1 : Lather and rinse.
2 : Lather and rinse.
3 : Lather and rinse.
4 : Lather and rinse.
Done.
5
1 : Lather and rinse.
2 : Lather and rinse.
3 : Lather and rinse.
4 : Lather and rinse.
Too many
Too many
Too many
Too many
Too many
Too many
Why does that happen? user_cycles == 5 so the loop won't stop until N == 6 (or any value greater than 5.
What happens when N == 5? We print "Too many" and then continue the loop without incrementing N again. Hence the loop will always get stuck at N = 5.
Note that testing with these values also shows is that we never hit the Too few condition -- this is dead code! It's not possible to ever reach this condition because N always starts at 1 and is never decreased.
The way to fix the infinite loop depends on the desired behavior. You could break the loop as soon as N exceeds 4:
elif N > 4:
print('Too many')
break
Another option would be to make sure that N is always incremented, either by incrementing it inside that conditional block or incrementing it outside the entire if...elif...else statement rather than inside the else (which will only run for values between 1 and 4).

players roll 2 dice till one reaches 100

Each player roll two dice in a row on one turn. The amount of dice obtained is
added to the player's total points. The game ends when one of the players
the first has achieved at least 100 points.
from random import randint
dicesum2 = 0
dicesum1 = 0
while (dicesum1 < 100):
dice1 = [randint(1, 6) for i in range(2)]
dicesum1 += sum(dice1)
print('player 1',dice1,'|',dicesum1)
dice2 = [randint(1, 6) for i in range(2)]
dicesum2 += sum(dice2)
print('player 2',dice2,'|',dicesum2)
i need it to end when one reaches 100. how do i check both?
if a player throws exactly one single, he loses the points obtained in the turn;
how do i check when one of the generated numbers is 1?
I need it to end when one reaches 100. how do i check both?
Learn about what the or logical operator does:
dicesum1 < 100 or dicesum2 < 100
how do i check when one of the generated numbers is 1?
Learn what the in operator does:
if 1 in dice1:
# Apply penalty.
Take a look at this and see if it helps out
from random import randint
def roll():
return [randint(1, 6) for i in range(2)]
def check_for_one(rolls):
for roll in rolls:
# this could be simplified to "if 1 in rolls", this was just my preference
if roll == 1:
return True
return False
dicesum2 = 0
dicesum1 = 0
while True:
d1 = roll()
dicesum1 += sum(d1)
if check_for_one(d1):
print(f"Player 1 rolled a 1 in batch: {d1}")
print(f"Player 1 roll: {d1} | {dicesum1}")
d2 = roll()
dicesum2 += sum(d2)
if check_for_one(d2):
print(f"Player 2 rolled a 1 in batch: {d2}")
print(f"Player 2 roll: {d2} | {dicesum2}")
if dicesum1 >= 100:
print(f"Player 1 won with: {dicesum1}")
break
elif dicesum2 >= 100:
print(f"Player 2 won with: {dicesum2}")
break
So in this example, we shove the roll out to a function and check_for_one which iterates the list you are making checking for ones and returning a boolean.
I changed the loop to while True so the loop wasn't responsible for the more complex condition which can be limiting.
For each player, it performs the roll, sums, checks and reports if a 1 is in the batch, reports the roll.
Finally it checks for the winner and breaks if one is at or over 100, reporting their win.
You can change the while condition as follow :
while (dicesum1 < 100 and dicesum2 < 100):
Alternatively, you can also use break :
...
if dicesum1 >= 100:
break
...
if dicesum2 >= 100:
break

Monte Carlo simulation of amoeba population

I came across a brain teaser problem. Im trying to simulate it, but having trouble getting the answer. The problem goes like this: there is one amoeba. every minute, an amoeba either may die, stay the same, split into 2 or split into 3 with equal probability. All of its offspring will behave the same way, independent of other amoebas. What is the probability that amoeba population will die?
My implementation in python:
import numpy as np
def simulate(n):
prob = np.array([0.25]*4)
ans = np.random.choice(np.arange(4),1,p=prob)
if ans == 0:
n = n - 1
if ans == 1:
pass
if ans == 2:
n = n * 2
if ans == 3:
n = n*3
return n
count = 0
for i in range(10000):
nold = 1
while True:
nnew = simulate(nold)
if nnew == 0: #amoeba has died
count += 1
break;
nold = nnew
Im getting an infinite loop. Can anybody help? thanks. The answer is 41%
The While loop needs to have some sort of breakpoint.
You have not set what is False.
while count < 10000:
...

python while loop point system - running slow

I have to simulate a points game where the first person to reach 11 points and win by 2 clear points wins the game
I have used a function to decide who wins a point
def simulatePoint(winProbabilityA, winProbabilityB):
rNumber = random.random()
if rNumber - winProbabilityA <= 0:
# A wins the game
return 0
elif rNumber - winProbabilityA > 0:
# B wins the game
return 1
and another one to simulate a game
def simulateGame (playerA_winProb, playerB_winProb):
gameWon = False
pointsA = 0
pointsB = 0
while gameWon == False:
# Simulate point
point = simulatePoint(playerA_winProb, playerB_winProb)
if point == 0:
pointsA += 1
elif point == 1:
pointsB += 1
# Checks for points to be equal to 11
if (pointsA == 11) and (pointsA - pointsB >= 2):
# A wins the game
gameWon = True
return 0
elif (pointsB == 11) and (pointsB - pointsA >= 2):
# B wins the game
gameWon = True
return 1
This is where i believe i am going wrong, i think the while loop is causing the code to run slow
Any help is greatfully accepted
What if the difference becomes greater than or equal to 2, after they have won more than 11 games. So, the logic should have been like this
if (pointsA >= 11) and (pointsA - pointsB >= 2):
...
elif (pointsB >= 11) and (pointsB - pointsA >= 2):
...
I think your code is running infinitely.
Consider: pointsA and pointsB reach 10 and 10 respectively. Now, no matter what player gets the next point, neither of your terminating conditions will be reached because neither pointsA nor pointsB will be 11 and up by 2 at the same time. This creates an infinite loop.
You'd probably want to check if pointsA >= 11 and pointsB >= 11 instead of A == 11 and B == 11.
Looks like thefourtheye beat me by a bit - he gets my vote.

whats wrong with my code to simulate a squash game?

I am trying to simulate the scoring of a squash game using english rules.
These are:
Only the server is awarded a point if they win a rally.
If the server wins a rally, they receive a point and continue as server.
If the returner wins a rally, they become the server but don’t receive a point.
The first player to reach 9 points wins the game unless the score has reached 8-8.
If the score reaches 8-8, the player who reached 8 first decides whether to play to 9 or to 10.
The code I have is this:
import random
def eng_game(a,b):
A = 'bob'
B = 'susie'
players = [A, B]
server = random.choice(players)
print server
points_bob = 0
points_susie= 0
prob_A_wins = 0.4
prob_B_wins = 0.6
while points_bob or points_susie < 9:
probability = random.random()
print probability
if probability < prob_A_wins and server == A:
points_bob += 1
elif probability < prob_A_wins and server == B:
server == A
print server
if probability > prob_A_wins and server == B:
points_susie += 1
elif probability > prob_A_wins and server == A:
server == B
print server
print points_bob
print points_susie
This code returns that Susie wins 9-0 when in some cases the server should be swapped to Bob to win the point, but this doesn't happen. The serve stays with Susie and she wins the point.
I think the issue is the statements server == A and server == B should be server = A and server = B so that assignment takes place instead of a comparison.
Another edge case bug I see is if probability ends up exactly 0.4 your program will act like that virtual serve never took place.
I would change your loop to:
while points_bob < 9 and points_susie < 9:
probability = random.random()
print probability
if probability <= prob_A_wins and server == A:
points_bob += 1
elif probability <= prob_A_wins and server == B:
server = A
print server
if probability > prob_A_wins and server == B:
points_susie += 1
elif probability > prob_A_wins and server == A:
server = B
print server
print points_bob
print points_susie
I suspect your loop condition
while points_bob or points_susie < 9:
is not doing what you think. When interpreted as booleans, numbers are False if they are zero and True otherwise, meaning this will actually check (points_bob != 0) or (points_susie < 9). This will only be False (i.e., the loop will only stop) when Susie has at least 9 points and Bob has no points - if Bob gets any points, the game will go on forever.
To fix this, you should switch to an and condition. This will only continue while both players have less than nine points, or to put it another way, it will stop as soon as somebody reaches nine. Therefore, your loop condition should be
while points_bob < 9 and points_susie < 9:
If you want to change the winning condition to 10 points, then you'll need to compare the player's points to a variable rather than a constant, and then change the variable as needed:
winning_score = 9
while points_bob < winning_score and points_susie < winning_score:
# ...
# Accumulate your points etc.
# ...
# Now need to reach ten points to win.
winning_score = 10

Categories

Resources