Reputation: 91
I've been trying to make a dart simulator using the Monte Carlo simulation in Python 3. So far, I have written the following code:
import random
import math
n = (input("Enter the number of darts you have. "))
count = 1
circleval = 0
squareval = 0
while count <= n:
y = 2*random.random()*2-1
x = 2*random.random()*2-1
if math.sqrt((x-1)**2+(y-1)**2)<=1:
circleval+=1
squareval+=1
else:
squareval+=1
count+=1
print("Pi is " + 4*(1.*circleval/squareval))
However, when I run this I reccive the following error message:
TypeError: '<=' not supported between instances of 'int' and 'str'
Upvotes: 1
Views: 1475
Reputation: 21284
In addition to the string-to-int issues already identified, you might find this simpler if you set your x
and y
bounds to [-1,1]
.
Also, consider using Numpy:
import numpy as np
n = int(input("Enter the number of darts you have. "))
count = 1
circleval = 0
squareval = 0
while count <= n:
y = np.random.uniform(low=-1, high=1)
x = np.random.uniform(low=-1, high=1)
if np.sqrt(x**2 + y**2) <= 1:
circleval+=1
squareval+=1
else:
squareval+=1
count+=1
print("Pi is", 4*(1.*circleval/squareval))
Output:
Enter the number of darts you have. 1000000
Pi is 3.142168
Notes:
- You don't need to keep track of squareval
, you can just use n
.
- You can use Numpy's vectorized operations to skip the while
-loop:
area = 4
n = int(input("Enter the number of darts you have. "))
X = np.random.uniform(low=-1, high=1, size=n)
Y = np.random.uniform(low=-1, high=1, size=n)
dist = np.sqrt(X**2+Y**2);
in_circle = np.sum(dist < 1.0)
print("Pi is", area * in_circle/n)
Upvotes: 1
Reputation: 477607
The main reason why this does not work is because:
n = (input("Enter the number of darts you have. "))
will put a string into n
, we can solve this with:
n = int(input("Enter the number of darts you have. "))
and:
print("Pi is " + 4*(1.*circleval/squareval))
expects a string, but you do not provide one, we can solve this with:
print("Pi is " + str(4*(1.*circleval/squareval)))
But that being said, the program is still incorrect: it gives 0.773
as output for Pi, which is clearly wrong.
The main problem is your sampling: you want to generate numbers between -1 and 1, but you generate numbers between -1 and 3. In your distance computations, you then use x-1
and y-1
shifting it to the -2 to 2 domain, but that is still too large. Furthermore the code not very elegant.
from random import random
n = int(input("Enter the number of darts you have. "))
c = 0
for i in range(n):
x = 2*random()-1
y = 2*random()-1
if x*x + y*y <= 1:
c += 1
print("Pi is %s" % (4.0*c/n))
for n=100000
, this has given me 3.14368
(although it might vary of course between several simulations).
Upvotes: 2
Reputation: 53545
Two issues:
n = input("Enter the number of darts you have. "))
should be:
n = int(input("Enter the number of darts you have. "))
(since you want to treat n
as an integer)
and
print("Pi is " + 4*(1.*circleval/squareval))
should be:
print("Pi is " + str(4*(1.*circleval/squareval)))
Since you can't add a string to a number
Other than that - I'm not sure if the calculation is correct - but that would be another issue.
Upvotes: 1