Python while loop not reverting to original value when repeating itself - python

Here is my code:
import math
flag_acc = True
n_tri = 8
r = 1
error = 1
while flag_acc:
accuracy_desired = float(input('To what accuracy would you like pi? (enter number of decimal places desired)'))
acc_des = 1/(10**accuracy_desired)
while error > acc_des:
theta_deg = 360/n_tri
theta_rad = math.radians(theta_deg)
c = math.sqrt(2 - 2*math.cos(theta_rad))
circum = c*n_tri
pie = circum/2
n_tri += 1
error = ((math.pi -pie)/math.pi)
print('Accuracy desired was: %0.3e'%(acc_des))
print('The number of triangles used to meet the desired accuracy was: ',n_tri)
print('Estimate for pi based on number of triangles is: ', pie)
repeat = input('Would you like to repeat with a new precision? (y/n)')
if repeat in ['n', 'N']:
flag_acc = False
My problem is that every time I respond yes to 'repeat' the n_tri value can only increase, even when my new accuracy_desired value has decreased.
I have tried defining n_tri in multiple different places within my code (inside both while loops, and before the while loops as it is now), and in if statements throughout

keep a tag of old accuracy and new accuracy desired and last n_tri
check and increase or decrease the value of n_tri .. from the second time.
import math
flag_acc = True
n_tri = 8
r = 1
error = 1
old_acc=None
while flag_acc:
accuracy_desired = float(input('To what accuracy would you like pi? (enter number of decimal places desired)'))
if not old_acc and accuracy_desired<old_acc:
n_tri=last_tri-2 # n_tri will be one more thane
acc_des = 1/(10**accuracy_desired)
last_tri=n_tri
while error > acc_des:
theta_deg = 360/n_tri
theta_rad = math.radians(theta_deg)
c = math.sqrt(2 - 2*math.cos(theta_rad))
circum = c*n_tri
pie = circum/2
n_tri += 1
error = ((math.pi -pie)/math.pi)
old_acc=accuracy_desired
print('Accuracy desired was: %0.3e'%(acc_des))
print('The number of triangles used to meet the desired accuracy was: ',n_tri)
print('Estimate for pi based on number of triangles is: ', pie)
repeat = input('Would you like to repeat with a new precision? (y/n)')
if repeat in ['n', 'N']:
flag_acc = False

Related

How can I calculate the probability that two players different abilities will win a PARS squash game against each other? (Python)

I've created a function winProbability(ra, rb, n) and I want to simulate n games in order to estimate the probability that a player with the ability ra will win a game against a player with ability rb
I'll show the code I've done so far. If this seems like a easy issue it's because I am new to coding.
import random #import random allows for the use of randomly generated numbers
def game(ra, rb): #this function game sets out the way the game runs
p_a_point = ra/(ra+rb) #this line of code determines the probability that
#player a wins any given point
a_points = 0 #the amount of points player a has is defaulted to 0
b_points = 0 #the amount of points player b has is defaulted to 0
score_to_win = 11 #the winning score is defaulted to 11
while (a_points < score_to_win and b_points < score_to_win) or abs (a_points - b_points) < 2: #while player a's points and player b's points are less than the winning score:
p_b_point = random.random()#the probability b wins a point is set the a random value between 0 and 1
if p_b_point < p_a_point: #is the probability b wins a point is less than the probability a wins a point:
a_points = a_points + 1 #a wins 1 point
else: #if player a doesn't win a point:
b_points = b_points + 1 #b wins a point
return(a_points, b_points)#both players points are returned
print(game(70,30))#the function is called with two integer values as parameters
def winProbability(ra, rb, n):
To be honest from here I am unsure on how to go about this. I was thinking of doing a for loop so for example:
for n in game (ra, rb):
but I am unsure if I can use a previous function in this loop call. I'm also confused on how to calculate probabilities in code
The general aim is to call the function with two probabilities for example 70 and 30 and give a decimal answer for the probability player ra will win.
To previous commenters, I apologise for being vague before. I've never posted on here before.
See if this helps.
from random import randint, seed
seed()
rounds = input(" How many rounds will be played in the match? ")
print("\n Please enter skill levels as integers from 0 to 99.\n")
a = input(" What is the skill level of player 1? ")
b = input(" What is the skill level of player 2? ")
# Catch empty inputs
if not rounds: rounds = 10
if not a: a = 0
if not b: b = 0
# Python inputs are always strings. Convert them to integers.
rounds = int(rounds)
a = int(a)
b = int(b)
# If both skill levels are 0, set them to 1.
# (This will avoid a possible division by zero error.)
if a+b == 0: a = b = 1
# Catch and correct numbers that are too high.
if a > 99: a = 99
if b > 99: b = 99
# Convert integer skill levels to values between 0.0 and 0.99
a = a/100
b = b/100
print()
print(" Chance player 1 will win: "+str(int(100*a/(a+b)))+" percent.")
print(" Chance Player 2 will Win: "+str(int(100*b/(a+b)))+" percent.")
print()
for x in range(rounds):
roll = randint(0,999)/1000
print("roll =",roll, end =": ")
if roll <= a/(a+b): # <-- Compare roll to ratio of player skill levels.
print("Round "+str(x+1)+" Winner: Player 1")
else:
print("Round "+str(x+1)+" Winner: Player 2")
print()
this was my answer
import random
def winProbability(ra, rb, n):
winCount = 0 #used to count how many times 'a' won
probabilityRange = ra + rb
for i in range(n):
# pick a number between 0 and probabiilityRange
number = random.randint(0, probabilityRange)
# if number is < ra then 'a' won if number is > ra then 'b' won if number == ra then results in a draw
if number < ra:
winCount += 1
print ('win')
if number > ra:
print('loss')
if number == ra:
print ('draw') # draw doesn't count as win
return winCount*(100/n)
print (winProbability(10000,1,100000))
This prints the results of each game played, and returns the possibility that 'a' will win in percentile form.

Loop Table using distance = speed * time

The distance a vehicle travels can be calculated as follows:
distance = speed * time
Write a program that asks the user for the speed of a vehicle (in miles per hour) and how many hours it has traveled. The program should then use a loop to display the distance the vehicle has traveled for each hour of that time period. Here is an example of the output:
What is the speed of the vehicle in mph? 40
How many hours has it traveled? 3
Hour Distance Traveled
1 : 40
2 : 80
3 : 120
I've gotten everything done so far but can't manage to get the table to come out properly, as shown in the example table at the first hour (1) it should start at 40 but instead it starts at 120. Can someone help me fix the code? forgot to mention it should work for any value the user enters such as if someone was going 50 mph in 5 hours
g = 'y'
while g == 'Y' or g == 'y':
speed = int(input('Enter mph: '))
time = int(input('Enter hours: '))
if time <= 0 or speed <= 0:
print('Invalid Hours and mph must be greater than 0')
else:
for t in range(time):
distance = speed * time
print(t + 1,':', distance)
time = time * 2
g = 'n'
print('End')
Just change 2 things in your program. First, there's no need to double the time inside for loop, Second use variable t instead of time to calculate distance.
g = 'y'
while g == 'Y' or g == 'y':
speed = int(input('Enter mph: '))
time = int(input('Enter hours: '))
if time <= 0 or speed <= 0:
print('Invalid Hours and mph must be greater than 0')
else:
for t in range(time):
distance = speed * (t+1) // Use t+1 instead of time
print(t + 1,':', distance)
# time = time * 2 // No need to double the time
g = 'n'
print('End')
Input:
40
3
Output:
(1, ':', 40)
(2, ':', 80)
(3, ':', 120)
End
You need to remove the commas from the print line, and print out the numbers in string format and concat it to the string colon like:
print(str(t + 1) + ':' + str(distance))
You also need to increment the time by one not multiply by 2
time = time + 1
Your output distance also can be fixed by calculating it based on t instead of time
distance = speed * (t+1)

Adding a large number with a small number in Python

I wrote a program in python which the program has one number with high value (T) and another number with a low value (a). When I add them up, the small number is ignored due to its low value. How can I fix this problem. The part of my program which makes this problem is below.
import random
lambd = 110
T = 56562719533.0
a = random.expovariate(lambd)
T2 = T + a
print T
print T2
You did add the small number but didn't print enough significant figures to see it.
import random
lambd = 110
T = 56562719533.0
a = random.expovariate(lambd)
T2 = T + a
print a
print T
print '%.10f' % T2
# prints: 0.00436707252696
# prints: 56562719533.0
# prints: 56562719533.0043640137
The '%.10f' tells Python to print 10 digits after the decimal point.

python 3.x overwrite previous terminal line

I wrote a simple program to calculate average outcome of a dice throw (pretty pointless, but you have to start somewhere ;P):
import random, time
from random import randrange
count = 0
total = 0
one_count = 0
for x in range(10000000):
random = randrange(1,7)
count = count + 1
total = total + random
average = total / count
percentage = one_count / count * 100
if random == 1:
one_count = one_count + 1
print("the percentage of ones occurring is", percentage, "and the average outcome is", average)
# time.sleep(1)
To clean it up I want the output to overwrite the previous line. I tried everything I could find, but the only thing I managed to to is to print to the same line without erasing the previous content by changing the last line to:
print("the percentage of ones occuring is", percentage, "and the average outcome is", average, "/// ", end="")
which outputs:
the percentage of ones occuring is 0.0 and the average outcome is 4.0 /// the percentage of ones occuring is 0.0 and the average outcome is 4.5 /// the percentage of ones occuring is 0.0 and the average outcome is 3.6666666666666665 ///
Any ideas?
Add a \r at the end. That way, the next line you write will start at the beginning of the previous line. And then flush output so it shows immediately.
Note: If the next line is shorter, the remaining characters will still be there.
use end='\r:
for x in range(100000):
rnd = randrange(1,7) # don't use random
count += 1
total = total + rnd
average = total / count
percentage = one_count / count * 100
if rnd == 1:
one_count += 1
print("the percentage of ones occurring is {} and the average outcome is {}".format(percentage,average),end='\r')
time.sleep(.1)
On another note using total = total + random is not a good idea, you are importing the random module and using random as a variable name.

running a program over x amount of times

I'm trying to write a function that calls a function (roll die() which rolls a die 1000 times and counts on a list [1,2,3,4,5,6] so an outcome might be [100,200,100,300,200,100]) and tells it to run it x amount of times. It seems my code is printing it over and over again x times
#simulate rolling a six-sided die multiple tiems, and tabulate the results using a list
import random #import from the library random so you can generate a random int
def rollDie():
#have 6 variables and set the counter that equals 0
one = 0
two = 0
three = 0
four = 0
five = 0
six = 0
#use a for loop to code how many times you want it to run
for i in range(0,1000):
#generate a random integer between 1 and 6
flip = int(random.randint(1,6))
# the flip variable is the the number you rolled each time
#Every number has its own counter
#if the flip is equal to the corresponding number, add one
if flip == 1:
one = one + 1
elif flip == 2:
two = two + 1
elif flip == 3:
three = three + 1
elif flip == 4:
four = four + 1
elif flip == 5:
five = five + 1
elif flip == 6:
six = six + 1
#return the new variables as a list
return [one,two,three,four,five,six]
the new function that I am having problems with is:
def simulateRolls(value):
multipleGames = rollDie() * value
return multipleGames
I would like to see a result like this if you typed in 4 for value
[100,300,200,100,100,200]
[200,300,200,100,100,100]
[100,100,100,300,200,200]
[100,100,200,300,200,100]
Can someone guide me in the right direction?
You can get what you want like this:
def simulateRolls(value):
multipleGames = [rollDie() for _ in range(value)]
return multipleGames
By the way, your original function seems to work perfectly fine, but if you're interested, you can remove some redundancy like this:
def rollDie():
#have 6 variables and set the counter that equals 0
results = [0] * 6
#use a for loop to code how many times you want it to run
for i in range(0,1000):
#generate a random integer between 1 and 6
flip = int(random.randint(1,6))
# the flip variable is the the number you rolled each time
results[flip - 1] += 1
return results
The line
multipleGames = rollDie() * value
will evaluate rollDie() once and multiply the result by value.
To instead repeat the call value times do this.
return [rollDie() for i in xrange(value)]
You can also simplify your rollDie function by working with a list throughout
import random #import from the library random so you can generate a random int
def rollDie():
result = [0] * 6
for i in range(0,1000):
result[random.randint(0,5)] += 1
return result

Categories

Resources