Thank you for reading my question.
I am a totally beginner for python and English is not my primary language. Please ask if you don't understand my English. Thank you for your help.
Here's the question. I want to create a Venn diagram using these criteria:
10*P(B) = P(A)
P(C and notA) = 13 * P(B and notC and notA)
P(B and C and notA) = 5 * P(B and C and A)
P(B and C) = 0.18
P(B or C and notA) = 0.07
P(notC) = 0.922 -> P(C) = 0.078
P(B and A) = 0.01
I tried using 'random' but I think it's quite dumb to do so.
This is my code, but if you have a better solution, please do tell me.
oa means Only A, i.e. (A and notB and notC)
abnc: means A and B No C
import random
# a = lowgrade fever
# b = headace
# c = Muscle ache
def haha():
oa = random.random()
ob = random.random()
oc = random.random()
abnc = random.random()
acnb = random.random()
bcna = random.random()
abc = random.random()
a = oa + abnc + acnb + abc
b = ob + abnc + bcna + abc
c = oc + acnb + bcna + abc
ab = abnc + abc
ac = acnb + abc
bc = bcna + abc
# oa + ob + oc + abnc + acnb+ bcna + abc = 1
if (10 * b == a):
c1 = True
if ((oc + bcna) == 13 * ob):
c2 = True
if ((ob + bcna + oc) == 5*abc):
c3 = True
if ((bcna + abc) == 0.018):
c4 = True
if(ob + bcna + oc == 0.07):
c5 = True
if(1 - oc + bcna + abc + acnb == 0.922):
c6 = True
if(abnc + abc == 0.01):
c7 = True
if (c1 and c2 and c3 and c4 and c5 and c6 and c7):
allc = True
if allc:
print(oa)
print(ob)
print(oc)
print(bcna)
print(acnb)
print(abnc)
print(abc)
return allc
haha()
while (allc == False):
haha()
Thank you guys.
You are looking to find 8 different probabilities. Where ~A means not A. These probabilities are the unknowns of our problem.
P( A & B & C) [1]
P( A & B & ~C) [2]
P( A & ~B & C) [3]
P( A & ~B & ~C) [4]
P(~A & B & C) [5]
P(~A & ~B & C) [6]
P(~A & ~B & ~C) [7]
P(~A & B & ~C) [8]
The first step is to write your equations in the variables written above. We will use [1] as a shorthand for P(A & B & C)
<=> 10P(B) - P(A)=0
<=> 10*([1] + [2] + [5] + [8]) - 1*(([1] + [2] + [3] + [4]) = 0
<=> 9*[1] + 9*[2] + -1*[3]-1*[4] + 10*[5] + 0*[6] + 0*[7] + 10*[8] = 0
We can do this for all 7 equations. In linear algebra this is written as a system Ax = b. You might remember that you need 8 equations if you have 8 unknown variables. To get a full solution you must find an extra equation. (Hint: what is the sum of all probabilities?)
To solve the exercise in python can use the following code.
import numpy as np
A = np.array([
[9, 9, -1, -1, 10, 0, 0, 10], # 10P(B) = P(A)
... # Insert 7 more equations here
])
b = np.array([0, ....]) # Insert 7 more numbers here
x = np.linalg.solve(A,b)
print(x)
For convenience, I will use the following shorthand notation:
[1--] denotes P(A),
[0--] denotes P(not A),
[0-1] denotes P(not A and C),
[110] denotes P(A and B and not C),
etc. Using this notation your problem statement can be rewritten as follows:
1) 10*[-1-] = [1--]
2) [0-1] = 13*[010]
3) [011] = 5*[111]
4) [-11] = 0.18
5) [-1-] + [001] = 0.07
6) [--1] = 0.078
7) [11-] = 0.01
Let us now try to solve it manually:
Rewrite 4)
[011] + [111] = 0.18
Substitute 3 into 4)
5*[111] + [111] = 0.18
[111] = 0.03
Rewrite 7) and substitute [111]=0.03
[110] + [111] = 0.01
[110] = -0.02
A probability cannot be negative, hence we may stop here and conclude that there is no probabilistic solution to your problem.
The obtained result can also be explained as follows:
P(ABC) ≤ P(AB) = 0.01
P(~ABC) = 5*P(ABC) ≤ 0.05
Therefore, P(BC) = P(ABC) + P(~ABC) ≤ 0.01 + 0.05 = 0.06
This contradicts condition 4.
Related
A Pythagorean triplet is a set of three natural numbers, a < b < c,
for which,
a^2 + b^2 = c^2
For example, 3^2 + 4^2 = 9 + 16 = 25 = 5^2.
There exists exactly one Pythagorean triplet for which a + b + c =
1000. Find the product abc.
above is the question. when i run my code it works and runs how i expect it to, but the programme always finishes without finding an answer. any advice on how to improve my code would be appreciated.
for k in range (1,1000):
c = 1000 - k
for i in range (1,c):
b = c - i
c_sqr = c ** 2
b_sqr = b ** 2
a = c - b
a_sqr = a ** 2
if a_sqr + b_sqr == c_sqr:
if a + b + c == 1000:
product = a * b * c
print(f"{product} is the answer")
exit()
else:
print("Pythagorean triplet!")
else:
josephmama = 11
print("not a pythagorean triplet")
In your code c < 1000 and a + b == c are invariants. The sum (a + b + c) == 2 * c requires that the longest side(hypotenuse) of the right triangle to be as long as the sum of the other sides, and there's no such numbers that satisfy it and so the if body never executes.
for a in range(1, 1000):
for b in range(1, 1000):
c = 1000 - (a + b)
if (a ** 2 + b ** 2 == c ** 2):
print(a * b * c)
exit()
a is not always equal to c - b
by deriving b from c and a from c and b you are unnecessarily limiting the options of what b and a could be. Just loop through all combinations of a, b and c, add the constrains you have and you'll eventually get your triplet.
for a in range(1, 1000):
for b in range(1, 1000):
for c in range(1, 1000):
if a+b+c == 1000:
if a**2+b**2 == c**2:
if a < b:
if b < c:
print(f"My Triplet: a: {a}, b: {b}, c:{c}")
topic:
If A and B are both integers from 1 to 9, try to find out those (A, B) values that can meet the following conditions: AAB+BB=BAA
What I write:
for A in range (1,10):
for B in range(1,10):
if #I have no idea...
print(A,B)
Well, start with the fact that AAB is equal to A * 100 + A * 10 + B.
Apply that to the others, work out the expressions, and test for equality.
For example(1), to test if ABBA + AB is exactly seven greater than BBBB, you could use something like:
abba = A * 1000 + B * 100 + B * 10 + A # or A * 1001 + B * 110
ab = A * 10 + B
bbbb = B * 1000 + B * 100 + B * 10 + B # or B * 1111
if abba + ab == bbbb + 7:
do_something()
(1) Hopefully close enough that you can work it out for your specific question, but not so close that you can just plagiarise :-)
You can use:
from itertools import product
[(A,B,f'{A}{A}{B} + {B}{B} = {B}{A}{A}')
for A,B in product(range(1,10), range(1,10))
if A*100+A*10+B+B*10+B == B*100+A*10+A]
output: [(8, 9, '889 + 99 = 988')]
Using a classical loop:
for A in range(1,10):
for B in range(1,10):
if A*100+A*10+B+B*10+B == B*100+A*10+A:
print(f'A={A}, B={B} -> {A}{A}{B} + {B}{B} = {B}{A}{A}')
output:
A=8, B=9 -> 889 + 99 = 988
You can really simplify this by just casting to strings and back to integers. Since this is a small enough n there won't be any performance concerns.
You could apply math by adding factors of 10 in the appropriate places but to me, this is the most obvious what's going on.
for A in range (1, 10):
for B in range(1, 10):
AAB = int(str(A) + str(A) + str(B))
BB = int(str(B) + str(B))
BAA = int(str(B) + str(A) + str(A))
if AAB + BB == BAA:
print(A, B)
Or with f-strings.
for A in range (1, 10):
for B in range(1, 10):
AAB = int(f'{A}{A}{B}')
BB = int(f'{B}{B}')
BAA = int(f'{B}{A}{A}')
if AAB + BB == BAA:
print(A, B)
At first, lets simplify the expression.
AAB + BB = BAA == 100A + 10A + B + 10B + B = 100B + 10A + A == 99A = 88B == 9A = 8B.
As you can see, we can already suggest the right answer (A should be the value of B multiplier and vise versa).
But if you really need to write some Python code, here you go:
for a in range(1, 10):
for b in range(1, 10):
if a * 9 == b * 8:
print(f'A={a}, B={b}')
Output: A=8, B=9
I am trying to solve a system of nonlinear equations with Sympy and Python.
The result is almost right, but always with a extremly small imaginary part, and the process is time consuming.
I also try the same computation under Matlab, the result is pretty good and fast.
I know that small imaginary part can be ignored. But I think there must be something wrong in my code which result in slowly and imaginary part. Can any one help me with this?
Python:3.6
Sympy:1.1.1
import sympy
A1, B1, C1, D1, E1, F1 = (0.0019047619047619048,
-1.7494954273533616e-19,
0.0004761904761904762,
-8.747477136766808e-18,
0.047619047619047616,
1.0)
A2, B2, C2, D2, E2, F2 = (8.264462809917356e-05,
-0.0,
0.00033057851239669424,
-0.008264462809917356,
-0.03305785123966942,
1.0)
k, b = sympy.symbols('k b')
eq1 = B1 ** 2 * b ** 2 + 2 * B1 * D1 * b - 2 * B1 * E1 * b * k - 4 * F1 * B1 * k + D1 ** 2 + 2 * D1 * E1 * k + \
4 * C1 * D1 * b * k + E1 ** 2 * k ** 2 - 4 * A1 * E1 * b - 4 * A1 * C1 * b ** 2 - 4 * C1 * F1 * k ** 2 - 4 * A1 * F1
eq2 = B2 ** 2 * b ** 2 + 2 * B2 * D2 * b - 2 * B2 * E2 * b * k - 4 * F2 * B2 * k + D2 ** 2 + 2 * D2 * E2 * k + \
4 * C2 * D2 * b * k + E2 ** 2 * k ** 2 - 4 * A2 * E2 * b - 4 * A2 * C2 * b ** 2 - 4 * C2 * F2 * k ** 2 - 4 * A2 * F2
s=sympy.solve([eq1,eq2],[k,b])
print(s)
That's what I got under Python and Sympy, with an extremely small imaginary part. And it almost takes 10 seconds. That is not acceptable for my whole project.
[(1.07269682322063 + 2.8315655624133e-28*I, -27.3048937553762 + 0.e-27*I),
(1.79271658724978 - 2.83156477591471e-28*I, -76.8585791921325 - 0.e-27*I),
(2.34194482854222 + 2.83156702952074e-28*I, -19.2027508047623 - 0.e-26*I),
(5.20930842765403 - 2.83156580622397e-28*I, -105.800442914396 - 7.59430998293648e-28*I)]
That's what I got under MATLAB with 'solve'. It's pretty fast. That's what I wanted.
k =
5.2093
1.7927
1.0727
2.3419
b =
-105.8
-76.859
-27.305
-19.203
SymPy intends to be a symbolic package, not numeric, so the results should be expected. There is, however, the function nsolve that can be used to find numerical solutions. There is no dedicated method (that I am aware of) that will compute all roots of a polynomial -- in this case, a pair of quadratics -- in SymPy/mpmath. You would have to find roots one by one:
>>> list(nsolve((eq1, eq2), (k,b), (1, 1)))
[1.07269682322063, -27.3048937553762]
But one can use the existing tools to build a solver for such equations. The following is an example (with the potential for lots of numerical issues in corner cases):
def n2solve(eq1, eq2, x, y, n):
"""Return numerical solutions for 2 equations in
x and y where each is polynomial of order 2 or less
as would be true for equations describing geometrical
objects.
Examples
========
>>> n2solve(x**2 + y, y**2 - 3*x*y + 4, x, y, 3)
(-2.82, -7.96)
(-1.34, -1.80)
"""
from sympy.core.containers import Tuple
from sympy.solvers.solvers import unrad, solve
eqs = Tuple(eq1, eq2)
sym = set([x, y])
assert all(i.free_symbols == sym for i in eqs)
anx = solve(eq1, x)[0]
yeq = eq2.subs(x, anx)
z = unrad(yeq)
z = z[0] if z else yeq
yy = real_roots(z)
def norm(x,y):
return abs((x**2+y**2).n(2))
got=[]
for yi in yy:
yi = yi.n(n)
ty = eqs.subs(y, yi)
for xi in real_roots(ty[0]):
xi = xi.n(n)
got.append((norm(*ty.subs(x, xi)), xi, yi))
return sorted([(x,y) for e,x,y in sorted(got)[:len(got)//2]])
This gives the following solutions for the equations posed in the question:
[(1.07, -27.3),
(1.79, -76.9),
(2.34, -19.2),
(5.21, -106.)]
I have equations with multiple unknowns, and a number range:
eq1 = (x + 5 + y) #
ans = 15
no_range = [1..5]
I know that I can solve the equation by checking all possible combinations:
solved = False
for i in range(1, 5+1) # for x
for j in range(1, 5+1) # for y
if i + 5 + j == ans:
solved = True
So, the problem is that I want a function to deal with unknown_count amount of unknowns. So that both the following equations, or any, can be solved in the same manner above:
eq1 = (x + 5 + y)
ans = 15
eq2 = (x + 5 + y + z * a + 5 * b / c)
ans = 20
I just cannot think of a way, since for each unknown you need a for loop.
You could use itertools.product to generate the Cartesian product for an
arbitrary number of variables:
In [4]: import itertools
In [5]: list(itertools.product(range(1, 5+1), repeat=2))
Out[5]:
[(1, 1),
(1, 2),
(1, 3),
...
(5, 3),
(5, 4),
(5, 5)]
So you could modify your code like this:
import itertools as IT
unknown_count = 6
ans = 20
solved = False
def func(*args):
x, y, z, a, b, c = args
return x + 5 + y + z * a + 5 * b / c
for args in IT.product(range(1, 5+1), repeat=unknown_count):
if func(*args) == ans:
solved = True
print('{} + 5 + {} + {} * {} + 5 * {} / {} = {}'.format(*(args+(ans,))))
which yields a lot of solutions, such as
1 + 5 + 1 + 1 * 3 + 5 * 2 / 1 = 20
1 + 5 + 1 + 1 * 3 + 5 * 4 / 2 = 20
1 + 5 + 1 + 2 * 4 + 5 * 1 / 1 = 20
...
5 + 5 + 5 + 2 * 2 + 5 * 1 / 5 = 20
5 + 5 + 5 + 3 * 1 + 5 * 2 / 5 = 20
5 + 5 + 5 + 4 * 1 + 5 * 1 / 5 = 20
The * unpacking operator was used
to create a function, func, which accepts an arbitrary number of arguments (i.e. def func(*args)), and also to
pass an arbitrary number of arguments to func (i.e. func(*args)).
my question is about adding loops in python
I am trying to add iteration numbers like summation of all iteration results
For example
first iteration
a = 10
b = 5
a = a + b = 15
c = a = 15
second iteration
a = 15
b = 5
a = a + b = 20
c = a1 + a2 = 35
I know to iterate using for loop which is like this
for i in range(2)
a = 10
b = 5
a = a + b
which gives a = 20
but how to get c which is adding iteration results
a=10
b=5
c=0
for i in range(2):
a = a + b
c = c + a
print a
print c
Above one gives results of a and c
You can define your variable outside your for loop to update it with the sum of each iteration
a_values = [10, 15]
b_values = [5, 5]
c = 0
for a, b in zip(a_values, b_values):
c += a + b
print(c)
35
I am afraid you are quite confused OP. Why don't you just do this instead:
a = 10
b = 5
c = sum(a+b for _ in range(2))
The problem with your version is that after calculating a during the first iteration, you re-assign its value to 10 in the second. Your loop would work with some modifications:
a = 10
b = 5
c = 0
for i in range(2)
c += a + b
You actually don't need any loop if you apply some basic arithmetic:
print(a + n * b)
print(a * n + (n*(n+1))//2 * b)
With a = 10, b = 5 and n = 2, it outputs:
20
35