how to create a vertical histogram using in-built python modules? - python

Basically I need to create a vertical histogram that cascades downwards.
My code so far:
a = 1
b = 8
c = 6
d = 7
x = [a, b, c, d]
z = max(x)
print(z)
i = 0
while i < z:
i += 1
a -= 1
b -= 1
c -= 1
d -= 1
if a >= 0:
print("*".ljust(5), end="")
if b >= 0:
print("*".ljust(5), end="")
if c >= 0:
print("*".ljust(5), end="")
if d >= 0:
print("*".ljust(5))
output obtained:
* * * *
* * *
* * *
* * *
* * *
* * *
* *
*
Required output:
* * * *
* * *
* * *
* * *
* * *
* * *
* *
*
ps: I'm new to all this so please excuse my ignorance 😁

Your code is almost working as is, but the *s are shifting over between columns.
If I change the *s to be the variable they are for, your current output looks like this:
a b c d
b c d
b c d
b c d
b c d
b c d
b d
b
You just need to print some whitespace when your if conditions come up False. So each one becomes
if a >= 0:
print("*".ljust(5), end="")
else:
print(" ".ljust(5), end="")

Related

Cant exit while loop on Simpson's Rule

I am trying to calculate an integral using Simpson's Rule formula.The catch is that the value of the integral is the one that satisfies the following condition:You find the Ih and Ih/2.If the absolute of (Ih-Ih/2)<error the loop is complete.Otherwise you repeat the process with half the h,which means it calculates the absolute of (Ih/2-Ih/4) and so on and so on.
while True:
###Ih part
h = (b - a) / N
y1 = np.linspace(a, b, N)
Ez11 = (np.sqrt(ra ** 2 + R ** 2 - 2 * ra * R * np.cos(y1 - fa))) / (
(aa ** 2 - 2 * ra * R * np.cos(y1 - fa)) ** (3 / 2))
I11 = (h/3) * (Ez11[0] + 2*sum(Ez11[:N-2:2]) \
+ 4*sum(Ez11[1:N-1:2]) + Ez11[N-1])
#####Ih/2 part
h = (b-a)/(2*N)
y2 = np.linspace(a, b, 2*N)
Ez22 = (np.sqrt(ra ** 2 + R ** 2 - 2 * ra * R * np.cos(y2 - fa))) / (
(aa ** 2 - 2 * ra * R * np.cos(y2 - fa)) ** (3 / 2))
print(Ez22)
I22 = (h/ 3) * (Ez22[0] + 2 * sum(Ez22[:N - 2:2]) \
+ 4 * sum(Ez22[1:N - 1:2]) + Ez22[N - 1])
# error condition I1=Ih I2=Ih/2
if np.abs(I11 - I22) < error:
break
else:
N = 2*N # h/2
print(np.abs(I11 - I22))
As far as I can tell,my approach should be correct.However the loop goes on and on,never to stop.
My code is as follows:
import numpy as np
from scipy.integrate import simps
import scipy.integrate as integrate
import scipy.special as special
# variables
a = 0
b = np.pi * 2
N = 100
ra = 0.1 # ρα
R = 0.05
fa = 35 * (np.pi / 180) # φα
za = 0.4
Q = 10 ** (-6)
k = 9 * 10 ** 9
aa = np.sqrt(ra ** 2 + R ** 2 + za ** 2)
error = 0.55 * 10 ** (-8)
h=(b-a)/N
I1 = np.nan
I11 = np.nan
#Simpsons section
############ Ez
#automated Simpson
while True:
###Ih part
y1 = np.linspace(a, b, N)
Ez1 = (np.sqrt(ra ** 2 + R ** 2 - 2 * ra * R * np.cos(y1 - fa))) / (
(aa ** 2 - 2 * ra * R * np.cos(y1 - fa)) ** (3 / 2))
print(len(Ez1))
I1 = simps(Ez1, y1)
#####Ih/2 part
y2 = np.linspace(a, b, 2*N)
Ez2 = (np.sqrt(ra ** 2 + R ** 2 - 2 * ra * R * np.cos(y2 - fa))) / (
(aa ** 2 - 2 * ra * R * np.cos(y2 - fa)) ** (3 / 2))
I2 = simps(Ez2, y2)
# error condition I1=Ih I2=Ih/2
if np.abs(I1 - I2) < error:
break
else:
N *= 2 # h/2
#custom-made Simpson
N = 100
while True:
###Ih part
h = (b - a) / N
y1 = np.linspace(a, b, N)
Ez11 = (np.sqrt(ra ** 2 + R ** 2 - 2 * ra * R * np.cos(y1 - fa))) / (
(aa ** 2 - 2 * ra * R * np.cos(y1 - fa)) ** (3 / 2))
I11 = (h/3) * (Ez11[0] + 2*sum(Ez11[:N-2:2]) \
+ 4*sum(Ez11[1:N-1:2]) + Ez11[N-1])
#####Ih/2 part
h = (b-a)/(2*N)
y2 = np.linspace(a, b, 2*N)
Ez22 = (np.sqrt(ra ** 2 + R ** 2 - 2 * ra * R * np.cos(y2 - fa))) / (
(aa ** 2 - 2 * ra * R * np.cos(y2 - fa)) ** (3 / 2))
print(Ez22)
I22 = (h/ 3) * (Ez22[0] + 2 * sum(Ez22[:N - 2:2]) \
+ 4 * sum(Ez22[1:N - 1:2]) + Ez22[N - 1])
# error condition I1=Ih I2=Ih/2
if np.abs(I11 - I22) < error:
break
else:
N = 2*N # h/2
print(np.abs(I11 - I22))
print(I1)
print(I11)
Simpson's Rule is as follows:
After a while it's stuck in this situation
The 5.23 part is the absolute diff of those 2 which shouldnt be that high.

Trying to use Simpson's Law in Python

I am trying to write a program about Simpson's Law.What I am trying to do is use as error as shown in this picture:
.
In the code i write the Ih is my f1 and Ih/2 is my f2.If the error doesnt happen then the steps get halved.
However I get this error
Traceback (most recent call last):
File "C:\Users\Egw\Desktop\Analysh\Askhsh1\example.py", line 22, in <module>
sim2 = simps(f2, x2)
File "C:\Users\Egw\Desktop\Analysh\Askhsh1\venv\lib\site-packages\scipy\integrate\_quadrature.py", line 436, in simps
return simpson(y, x=x, dx=dx, axis=axis, even=even)
File "C:\Users\Egw\Desktop\Analysh\Askhsh1\venv\lib\site-packages\scipy\integrate\_quadrature.py", line 542, in simpson
last_dx = x[slice1] - x[slice2]
IndexError: index -1 is out of bounds for axis 0 with size 0
Process finished with exit code 1
My code is
import numpy as np
from sympy import *
from scipy.integrate import simps
a = 0
b = np.pi * 2
N = 100
ra = 0.1 # ρα
R = 0.05
fa = 35 * (np.pi/180) # φα
za = 0.4
Q = 10**(-6)
k = 9 * 10**9
aa = sqrt(ra**2 + R**2 + za**2)
error = 5 * 10**(-9)
while True:
x1 = np.linspace(a, b, N)
f1 = 1 / ((aa ** 2 - 2 * ra * R * np.cos(x1 - fa)) ** (3 / 2))
sim1 = simps(f1, x1)
x2 = np.linspace(a, b, int(N/2))
f2 = 1 / ((aa ** 2 - 2 * ra * R * np.cos(x2 - fa)) ** (3 / 2))
sim2 = simps(f2, x2)
if abs(sim1 - sim2) < error:
break
else:
N = int(N/2)
print(sim1)
I wasnt expecting any error,and basically expecting to calculate correctly.
When you reduce the grid step by half h -> h/2, the number of grid steps in turn grows N -> 2 * N, so you have to make two changes in your code:
Define x2 to have twice as many elements as x1
x2 = np.linspace(a, b, 2 * N)
Update N to be twice it was on the previous iteration
N = 2 * N
The resulting code would be
import numpy as np
from sympy import *
from scipy.integrate import simps
a = 0
b = np.pi * 2
N = 100
ra = 0.1 # ρα
R = 0.05
fa = 35 * (np.pi/180) # φα
za = 0.4
Q = 10**(-6)
k = 9 * 10**9
aa = sqrt(ra**2 + R**2 + za**2)
error = 5 * 10**(-9)
while True:
x1 = np.linspace(a, b, N)
f1 = 1 / ((aa ** 2 - 2 * ra * R * np.cos(x1 - fa)) ** (3 / 2))
sim1 = simps(f1, x1)
x2 = np.linspace(a, b, 2 * N)
f2 = 1 / ((aa ** 2 - 2 * ra * R * np.cos(x2 - fa)) ** (3 / 2))
sim2 = simps(f2, x2)
if abs(sim1 - sim2) < error:
break
else:
N = 2 * N
print(sim1)
And this prints the value
87.9765411043221
with error consistent with the threshold
abs(sim1 - sim2) = 4.66441463231604e-9
#DmitriChubarov's solution is correct. However, your implementation is very inefficient: it does double the work it needs to. Also, simps is deprecated, you should be using proper exponential notation, and your function expression can be simplified. For an equivalent error-free algorithm that still doubles the input array length on each iteration but doesn't throw away the intermediate result,
import numpy as np
from scipy.integrate import simpson
a = 0
b = 2*np.pi
N = 100
ra = 0.1 # ρα
R = 0.05
fa = np.radians(35) # φα
za = 0.4
aa = np.linalg.norm((ra, R, za))
error = 5e-9
sim1 = np.nan
while True:
x = np.linspace(a, b, N)
f = (aa**2 - 2*ra*R*np.cos(x - fa))**-1.5
sim2 = simpson(f, x)
if np.abs(sim1 - sim2) < error:
break
sim1 = sim2
N *= 2
print(sim1)
When I modified your code by adding two lines to print(len(x1), len(f1)) and print(len(x2), len(f2)), I got these results:
Output:
length of x1 and f1: 100 100
length of x2 and f2: 50 50
length of x1 and f1: 50 50
length of x2 and f2: 25 25
length of x1 and f1: 25 25
length of x2 and f2: 12 12
length of x1 and f1: 12 12
length of x2 and f2: 6 6
length of x1 and f1: 6 6
length of x2 and f2: 3 3
length of x1 and f1: 3 3
length of x2 and f2: 1 1
length of x1 and f1: 1 1
length of x2 and f2: 0 0
as you can see the length decreases each loop because N decreases and ends with an empty list length of x2 and f2: 0 0 and this causes the error you have had. To fix the issue of 'the empty list' I suggest that you duplicate N; this means using N*2 instead of N/2.

My output seems to be wrong in comparison to symbolab

Getting wrong output for this equation. Can someone review my code?
from math import cos
from math import sin
from math import pi
a0 = int(input("a0:"))
b0 = int(input("b0:"))
N = int(input("N:"))
L = int(input("L:"))
X = int(input("X:"))
n = 0
an = a0
bn = b0
y=0
for i in range(N):
an = an + 10 # since our first value would An = A0 +10 , we could just loop the values by adding 10 to it
bn = bn * 10
y= an * cos((n*pi*X/(L))) + bn*(sin(n*pi*X/(L)))
print(y)
y= an * cos((n*pi*X/(L))) + bn*(sin(n*pi*X/(L)))
There's never any change in the n variable! Given that n starts (and remains) at 0, you always calculate
an * cos(0) + bn * sin(0) == an * 1 + bn * 0 == an
Furthermore you need to add the result to the y variable, not just assign it. And you need to prime the y variable with a0.
an = a0
bn = b0
c = 0
d = pi * X / L # precalculating for efficiency
y = a0
for i in range(N):
an = an + 10
bn = bn * 10
c = c + d
y = y + an * cos(c) + bn * sin(c)
print(y)

How to print this diamond pattern using python?

I want to print this pattern in python:(10 rows rhombus increment-decrement numbers)
1
121
12321
1234321
123454321
12345654321
1234567654321
123456787654321
12345678987654321
1234567891987654321
12345678987654321
123456787654321
1234567654321
12345654321
123454321
12321
121
1
Note : 1234321 is missing in the last but fourth line, so I think it is not a perfect rhombus. Plus instead of 10, 1 is printed in the tenth line.How to achieve this shape? Please let me know.
I had no idea on how to do this using numbers so,tried the below basic program using * but I don't know how to print the same using numbers as shown above.
n=11
for i in range(n):
print(''*(n-i-1)+'* '*(i+1))
for j in range(n-1,0,-1):
print(''*(n-j)+'* '*(j))
Also this prints half the shape only
*
* *
* * *
* * * *
* * * * *
* * * * * *
* * * * * * *
* * * * * * * *
* * * * * * * * *
* * * * * * * * * *
* * * * * * * * * * *
* * * * * * * * * *
* * * * * * * * *
* * * * * * * *
* * * * * * *
* * * * * *
* * * * *
* * * *
* * *
* *
*
How to print the pattern I mentioned(using increment-decrement numbers)?
Plus is the question wrong because it misses 1234321 line or it can be achieved?
Please help me.I am new to coding so how to achieve this using the simplest way i.e using looping constructs like for loop? Thanks in advance for your help and time.
Here is a possibility for how to generate the geometry:
n = 11
for i in range(n // 2 + 1):
print(' ' * (n // 2 - i) + '* ' * (i + 1))
for i in reversed(range(n // 2)):
print(' ' * (n // 2 - i) + '* ' * (i + 1))
*
* *
* * *
* * * *
* * * * *
* * * * * *
* * * * *
* * * *
* * *
* *
*
EDIT: Here is an actual implementation with numbers, that fails at n = 10, unfortunately.
from itertools import chain
n = 9
ranges = chain(range(n), reversed(range(n - 1)))
for i in ranges:
print(' ' * (n - i - 1), *[x + 1 for x in range(i + 1)],
*[x + 1 for x in reversed(range(i))])
1
1 2 1
1 2 3 2 1
1 2 3 4 3 2 1
1 2 3 4 5 4 3 2 1
1 2 3 4 5 6 5 4 3 2 1
1 2 3 4 5 6 7 6 5 4 3 2 1
1 2 3 4 5 6 7 8 7 6 5 4 3 2 1
1 2 3 4 5 6 7 8 9 8 7 6 5 4 3 2 1
1 2 3 4 5 6 7 8 7 6 5 4 3 2 1
1 2 3 4 5 6 7 6 5 4 3 2 1
1 2 3 4 5 6 5 4 3 2 1
1 2 3 4 5 4 3 2 1
1 2 3 4 3 2 1
1 2 3 2 1
1 2 1
1
I'd do a function for one line, and run it twice, skipping the 4 at the end:
def oneline(i):
for j in range(i,10):
print(' ', end='')
for j in range(1, i+1):
print(j if j<10 else 1, end='')
for j in range(i-1, 0, -1):
print(j if j<10 else 1, end='')
print()
for i in range(1,11):
oneline(i)
for i in range(9,0,-1):
if i == 4:
continue
oneline(i)
Output:
1
121
12321
1234321
123454321
12345654321
1234567654321
123456787654321
12345678987654321
1234567891987654321
12345678987654321
123456787654321
1234567654321
12345654321
123454321
12321
121
1
I believe this would be more pythonic:
size = 10
pattern = (size-1)*" " + size*"123456789" # indented pattern
rhombus = [ pattern[i:i+size] for i in range(size) ] # top-left
rhombus = [ d+d[-2::-1] for d in rhombus ] # horizontal mirror
rhombus = rhombus+rhombus[-2::-1] # vertical mirror
The approach leverages the horizontal and vertical symmetry of the output by only generating the top-left corner and then mirroring horizontally and vertically
output:
for line in rhombus: print(line)
1
121
12321
1234321
123454321
12345654321
1234567654321
123456787654321
12345678987654321
1234567891987654321
12345678987654321
123456787654321
1234567654321
12345654321
123454321
1234321
12321
121
1
Alternatively, if you want to print as you go, you can work with the left side of the pattern for all the lines and print the horizontally mirrored substring of the pattern for each line:
size = 10
pattern = size*" " + size*"123456789" # indented pattern (1 based)
for i in range(1,size*2): # for each line (1 based)
line = pattern[size-abs(size-i):][:size] # left side of line
print(line + line[-2::-1]) # print mirrored line
Here's a simple version using for loops. Should work for large numbers.
def r(upper=10):
for i in range(-1 * (upper-1), upper):
j = upper - abs(i)
print(' ' * (abs(i)), end ='')
for k in range(-1 * (j-1), j):
print(str(j - abs(k))[0], end='')
print()
r(10)
..
1
121
12321
1234321
123454321
12345654321
1234567654321
123456787654321
12345678987654321
1234567891987654321
12345678987654321
123456787654321
1234567654321
12345654321
123454321
1234321
12321
121
1
Hope it helps :)

Using regex's to relabel and remove redundent items in a string

I am trying to use pythons regex features to relabel some identifiers in some text.
Here is an example of the text. I am essentially trying to number all the v's in numerical order.
#r=v4 "v4"
A -> C : B
Cell * kcat * B * A / (km + A)
#r=v4 "v4"
C -> C+D
Cell * v2_k * C
#r=v4 "v4"
C -> : D
Cell * kcat2 * D * C / (km2 + C)
#r=v4 "v4"
C -> C+D
Cell * v2_k * C
So the desired output would be
#r=v1 "v1"
A -> C : B
Cell * kcat * B * A / (km + A)
#r=v2 "v2"
C -> C+D
Cell * v2_k * C
#r=v3 "v3"
C -> : D
Cell * kcat2 * D * C / (km2 + C)
#r=v4 "v4"
C -> C+D
Cell * v2_k * C
However there is also a complication. If you look carefully you can see that the 'v2' and 'v4' elements are identical. This is therefore redundant information for me and needs to me removed.
My Code:
string='''
#r=v4 "v4"
A -> C : B
Cell * kcat * B * A / (km + A)
#r=v4 "v4"
C -> C+D
Cell * v2_k * C
#r=v4 "v4"
C -> : D
Cell * kcat2 * D * C / (km2 + C)
#r=v4 "v4"
C -> C+D
Cell * v2_k * C
'''
pattern=re.compile('#r=(.*)')
for i in range(len(re.findall(pattern,string))):
print re.sub(pattern,'#r=v{} "v{}"'.format(str(i+1),str(i+1)),string)
This however does not give me the desired output. Does anybody know how to do what I want? Thanks
Probable solution:
string='''#r=v4 "v4"
A -> C : B
Cell * kcat * B * A / (km + A)
#r=v4 "v4"
C -> C+D
Cell * v2_k * C
#r=v4 "v4"
C -> : D
Cell * kcat2 * D * C / (km2 + C)
#r=v4 "v4"
C -> C+D
Cell * v2_k * C'''
i = 0
for strg in string.splitlines():
if strg == '#r=v4 "v4"':
i += 1
print '#r=v{} "v{}"'.format(i,i)
else:
print strg
Output:
#r=v1 "v1"
A -> C : B
Cell * kcat * B * A / (km + A)
#r=v2 "v2"
C -> C+D
Cell * v2_k * C
#r=v3 "v3"
C -> : D
Cell * kcat2 * D * C / (km2 + C)
#r=v4 "v4"
C -> C+D
Cell * v2_k * C
You can easily concat all string and get text with relabeled identifiers. Like this:
new_text = ""
for strg in string.splitlines():
if strg == '#r=v4 "v4"':
i += 1
new_text += '#r=v{} "v{}"\n'.format(i,i)
else:
new_text += strg + '\n'
For just little bit more difficult case:
for strg in string.splitlines():
if strg in ['#r=v4 "v4"','#r=v2 "v2"','#r=v3 "v3"'] : # any string if there aren't huge amount of cases
i += 1
print '#r=v{} "v{}"'.format(i,i)
else:
print strg

Categories