Change the terminal-character size (with python) - python

I am trying to draw shapes in the python terminal but because letters are taller than wide, everything is distorted/stretched. Is there way to change the (don't know how it's called) cell size to something square like 10x10px? I wouldn't care if the actual characters are distorted (for example "H" being squashed together). I work in both Linux and Windows. I have added an example of what I mean. The coordinates of the square are generated with:
def getCPoints(x,y,r,steps):
coords = []
for n in range(steps):
coords.append(((x + r * math.cos(2 * math.pi * (n / steps))),y + r * math.sin(2 * math.pi * (n / steps))))
return coords

Related

Mismatched Vector Sizes: operands could not be broadcast together with shapes (2,) (99,) - need help checking array syntax/operations

I am attempting to calculate the following five-point symmetric scheme for the diffusion equation (temperature diffusing through a rod with end points having temp = 100 degrees C).
This is the formula for the interior points:
five-point symmetric scheme for interior points
and this is the formula for j=2:
enter image description here
I am trying to create a function in Python that allows me to solve this scheme, but I am having problems with array sizes not lining up and I'm not sure why.
I already had a scheme working for the FTCS scheme where I just copied the syntax. Where I could have gone wrong is in my array syntax (still new to Python), i.e. taking T[:2] for j-1 and turning that into T[:3] for j-2.
Here is my entire code:
import numpy as np
import math as m
from matplotlib import pyplot as plt
# Set parameters.
L = 1.0 # length of the rod (m)
nx = 101 # number of locations on the rod to run simulation
dx = L / (nx - 1) # distance between two consecutive locations
alpha = 0.01e-4 # thermal diffusivity of the rod (m^2/s)
nt = 2500 # number of time steps to compute
s = 0.1 # stability parameter
# Define the locations along the rod.
x = np.linspace(0.0, L, num=nx)
# Set the initial temperature along the rod.
T0 = np.zeros(nx)
T0[0] = 100.0 #(degrees C)
T0[-1] = T_end = 100.0 #(degrees C)
def five_point(T0, nt, s, dx):
'''
Computes and returns the temperature along the rod
after a provided number of time steps,
given the initial temperature and thermal diffusivity.
Uses five_point computation scheme.
Parameters:
T0 : The initial temperature along the rod.
nt : The number of time steps to compute.
s: parameter that determines stability
dx : The distance between two consecutive locations.
Returns:
T : The temperature along the rod.
'''
T = T0.copy()
dt = s * dx**2 / alpha
for n in range(nt):
#for j=2:
T[2] = (((11 * T[:2] /12) - (5 * T[1:-1] / 3) + (0.5 * T[2:]) + (T[3:] / 3) + (T[4:] / 12)) / (dx ** 2))
#for interior points:
T[2:-1] = (((-T[:3] / 12) + (4 * T[:2] / 3) - (2.5 * T[1:-1]) + (4 * T[2:] / 3) - (T[3:] / 12)) / (dx ** 2))
return T
T_five_point = five_point(T0, nt, s, dx)
I get the errror: operands could not be broadcast together with shapes (2,) (99,) pointing to the first line of code after the for loop, and I'm guessing there is a problem with T[2] not being registered as the third index in the array? Not sure, I am super new to Python so this error is throwing me for a loop (no pun intended).

Intersection of Parabolas for Voronoi Diagram

This is my first question on Stack Overflow, so if I have formatted something incorrectly or not added the correct information, please let me know and I will fix it when I can.
I'm trying to implement Fortune's Algorithm for creating a Voronoi Diagram in Roblox. Roblox uses a more limited version of Lua, so I can't just import modules or copy-paste most code. Fortune's Algorithm uses parabolas to find the points required to make the edges around each site and I found an equation in Fortunes Algorithm: An intuitive explanation that generates a parabola where every point on the parabola is equidistant from the focus and the directrix.
​I know how to find the intersection of two parabolas when they are in standard form, but I have been unable to get the above equation into standard form. I've tried (on paper) putting it on both sides of the equals sign, setting it equal to zero, then expanding the polynomials using wolframAlpha's polynomial expander, producing
[(-X^2 * fx) + (X^2 * f'y) + (2 * dy * fx * X) - (2 * dy * f'x * X) + (2 * f'x * fy * X) - (2 * fx * f'y * X) + (dy^2 * fy) - (dy^2 * f'y) - (dy * fy^2) + (dy * f'y^2) - (fy * f'y^2) + (f'y * fy^2) + (dy * f'x^2) - (f'x^2 * fy) - (dy * fx^2) + (f'y * fx^2)] / [2(dy^2) - (dy * fy) - (dy * f'x) + (fy * f'y))]
where X is a variable, fx and fy are the x and y coordinates of the first focus, f'x and f'y are the x and y coordinates of the second focus, and dy is the y coordinate of the directrix. I am unsure of where to go from here.
I asked this on Stack Overflow in the hopes of finding someone who has implemented it before, but I may also ask it on a more math-related website as I just need the formula that gives the intercept(s). Having said this, if anyone has a code answer to this, Python would be preferred as I am most familiar with it.
Unrelated to the main question, does anyone know if there is a way to format the equation in Stack Overflow that is more easy to look at than a single line, and if so, how?

Drawing a circle with Pyautogui from top to bottom

I would like to create a half circle from top to bottom with my mouse, using Pyautogui. Currently I am using a script that works from right to left or left to right. But I can't manage to make the script to work from top to bottom. Here is the current script,
import pyautogui
import math
R = 40
(x,y) = pyautogui.size()
(X,Y) = pyautogui.position(580,311)
pyautogui.moveTo(X+R,Y)
pyautogui.mouseDown();
for i in range(180):
if i%6==0:
pyautogui.moveTo(X+R*math.cos(math.radians(i)),Y+R*math.sin(math.radians(i)))
pyautogui.mouseUp()
So right now it goes to the location, adds the radius then starts drawing the circle. I would like it to add the radius on top and start drawing down. I know how to add the radius on top, but drawing downwards is the struggle. So if anyone can help that would be great!
Thanks,
GetRektOrElse
Hello there GetRektOrElse,
I would like to start this answer by apologising for my horrible code styling, I am primarily a mathematician and I am not very familiar with styling.
I have taken a different approach to solving this problem to yourself by using the equation of a circle in cartesian coordinates: (x ** 2 - a) + (y ** 2 - b) = r ** 2 where point (a, b) is the centre of the circle and r is the radius of the circle. By rearranging this equation you can find a formula for x in terms of y: sqrt((r ** 2) - ((y - b) ** 2)) + a. By iterating through integer values of y this equation can be used to find the relevant value for x on each pixel row from which you are able to draw you circle.
I believe that this approach is slightly more intuitive than the one which you have used and is more versatile for other transformations which one might want to do in the future.
import pyautogui
import math
r = 36
centrex = 2778
centrey = 505
y = centrey - r
x = math.sqrt((r ** 2) - ((y - centrey) ** 2)) + centrex
oldx = x
oldy = y
for i in range(r):
pyautogui.moveTo(x, y)
x = math.sqrt((r ** 2) - ((y - centrey) ** 2)) + centrex
pyautogui.dragTo(x, y)
tempx = centrex - math.sqrt((r ** 2) - ((y - centrey) ** 2))
tempoldx = centrex - math.sqrt((r ** 2) - ((oldy - centrey) ** 2))
pyautogui.moveTo(tempoldx, oldy)
pyautogui.dragTo(tempx, y)
pyautogui.dragTo(x, y) # comment this line if you want to disable fill
oldx = x
oldy = y
y = y + 1
Again I would like to apologise for how disgusting I'm sure this code is however it performs the function that you desire in the way I described above. If you have any questions please feel free to ask and thank you for asking such an interesting question!
Hope you are staying well,
bobbattalion
Change;
pyautogui.moveTo(X+R,Y)
To;
pyautogui.moveTo(X,Y+R)
Also if you want it to start top to bottom, use a negative figure for your radius.

Coupled map lattice in Python

I attempt to plot bifurcation diagram for following one-dimensional spatially extended system with boundary conditions
x[i,n+1] = (1-eps)*(r*x[i,n]*(1-x[i,n])) + 0.5*eps*( r*x[i-1,n]*(1-x[i-1,n]) + r*x[i+1,n]*(1-x[i+1,n])) + p
I am facing problem in getting desired output figure may be because of number of transients I am using. Can someone help me out by cross-checking my code, what values of nTransients should I choose or how many transients should I ignore ?
My Python code is as follows:
import numpy as np
from numpy import *
from pylab import *
L = 60 # no. of lattice sites
eps = 0.6 # diffusive coupling strength
r = 4.0 # control parameter r
np.random.seed(1010)
ic = np.random.uniform(0.1, 0.9, L) # random initial condition betn. (0,1)
nTransients = 900 # The iterates we'll throw away
nIterates = 1000 # This sets how much the attractor is filled in
nSteps = 400 # This sets how dense the bifurcation diagram will be
pLow = -0.4
pHigh = 0.0
pInc = (pHigh-pLow)/float(nSteps)
def LM(p, x):
x_new = []
for i in range(L):
if i==0:
x_new.append((1-eps)*(r*x[i]*(1-x[i])) + 0.5*eps*(r*x[L-1]*(1-x[L-1]) + r*x[i+1]*(1-x[i+1])) + p)
elif i==L-1:
x_new.append((1-eps)*(r*x[i]*(1-x[i])) + 0.5*eps*(r*x[i-1]*(1-x[i-1]) + r*x[0]*(1-x[0])) + p)
elif i>0 and i<L-1:
x_new.append((1-eps)*(r*x[i]*(1-x[i])) + 0.5*eps*(r*x[i-1]*(1-x[i-1]) + r*x[i+1]*(1-x[i+1])) + p)
return x_new
for p in arange(pLow, pHigh, pInc):
# set initial conditions
state = ic
# throw away the transient iterations
for i in range(nTransients):
state = LM(p, state)
# now stote the next batch of iterates
psweep = [] # store p values
x = [] # store iterates
for i in range(nIterates):
state = LM(p, state)
psweep.append(p)
x.append(state[L/2-1])
plot(psweep, x, 'k,') # Plot the list of (r,x) pairs as pixels
xlabel('Pinning Strength p')
ylabel('X(L/2)')
# Display plot in window
show()
Can someone also tell me figure displayed by pylab in the end has either dots or lines as a marker, if it is lines then how to get plot with dots.
This is my output image for reference, after using pixels:
It still isn't clear exactly what your desired output is, but I'm guessing you're aiming for something that looks like this image from Wikipedia:
Going with that assumption, I gave it my best shot, but I'm guessing your equations (with the boundary conditions and so on) give you something that simply doesn't look quite that pretty. Here's my result:
This plot by itself may not look like the best thing ever, however, if you zoom in, you can really see some beautiful detail (this is right from the center of the plot, where the two arms of the bifurcation come down, meet, and then branch away again):
Note that I have used horizontal lines, with alpha=0.1 (originally you were using solid, vertical lines, which was why the result didn't look good).
The code!
I essentially modified your program a little to make it vectorized: I removed the for loop over p, which made the whole thing run almost instantaneously. This enabled me to use a much denser sampling for p, and allowed me to plot horizontal lines.
from __future__ import print_function, division
import numpy as np
import matplotlib.pyplot as plt
L = 60 # no. of lattice sites
eps = 0.6 # diffusive coupling strength
r = 4.0 # control parameter r
np.random.seed(1010)
ic = np.random.uniform(0.1, 0.9, L) # random initial condition betn. (0,1)
nTransients = 100 # The iterates we'll throw away
nIterates = 100 # This sets how much the attractor is filled in
nSteps = 4000 # This sets how dense the bifurcation diagram will be
pLow = -0.4
pHigh = 0.0
pInc = (pHigh - pLow) / nSteps
def LM(p, x):
x_new = np.empty(x.shape)
for i in range(L):
if i == 0:
x_new[i] = ((1 - eps) * (r * x[i] * (1 - x[i])) + 0.5 * eps * (r * x[L - 1] * (1 - x[L - 1]) + r * x[i + 1] * (1 - x[i + 1])) + p)
elif i == L - 1:
x_new[i] = ((1 - eps) * (r * x[i] * (1 - x[i])) + 0.5 * eps * (r * x[i - 1] * (1 - x[i - 1]) + r * x[0] * (1 - x[0])) + p)
elif i > 0 and i < L - 1:
x_new[i] = ((1 - eps) * (r * x[i] * (1 - x[i])) + 0.5 * eps * (r * x[i - 1] * (1 - x[i - 1]) + r * x[i + 1] * (1 - x[i + 1])) + p)
return x_new
p = np.arange(pLow, pHigh, pInc)
state = np.tile(ic[:, np.newaxis], (1, p.size))
# set initial conditions
# throw away the transient iterations
for i in range(nTransients):
state = LM(p, state)
# now store the next batch of iterates
x = np.empty((p.size, nIterates)) # store iterates
for i in range(nIterates):
state = LM(p, state)
x[:, i] = state[L // 2 - 1]
# Plot the list of (r,x) pairs as pixels
plt.plot(p, x, c=(0, 0, 0, 0.1))
plt.xlabel('Pinning Strength p')
plt.ylabel('X(L/2)')
# Display plot in window
plt.show()
I don't want to try explaining the whole program to you: I've used a few standard numpy tricks, including broadcasting, but otherwise, I have not modified much. I've not modified your LM function at all.
Please don't hesitate to ask me in the comments if you have any questions! I'm happy to explain specifics that you want explained.
A note on transients and iterates: Hopefully, now that the program runs much faster, you can try playing with these elements yourself. To me, the number of transients seemed to decide for how long the plot remained "deterministic-looking". The number of iterates just increases the density of plot lines, so increasing this beyond a point didn't seem to make sense to me.
I tried increasing the number of transients all the way up till 10,000. Here's my result from that experiment, for your reference:

Python - Vincenty's inverse formula not converging (Finding distance between points on Earth)

I'm attempting to implement Vincenty's inverse problem as described on wiki HERE
The problem is that lambda is simply not converging. The value stays the same if I try to iterate over the sequence of formulas, and I'm really not sure why. Perhaps I've just stared myself blind on an obvious problem.
It should be noted that I'm new to Python and still learning the language, so I'm not sure if it's misuse of the language that might cause the problem, or if I do have some mistakes in some of the calculations that I perform. I just can't seem to find any mistakes in the formulas.
Basically, I've written in the code in as close of a format as I could to the wiki article, and the result is this:
import math
# Length of radius at equator of the ellipsoid
a = 6378137.0
# Flattening of the ellipsoid
f = 1/298.257223563
# Length of radius at the poles of the ellipsoid
b = (1 - f) * a
# Latitude points
la1, la2 = 10, 60
# Longitude points
lo1, lo2 = 5, 150
# For the inverse problem, we calculate U1, U2 and L.
# We set the initial value of lamb = L
u1 = math.atan( (1 - f) * math.tan(la1) )
u2 = math.atan( (1 - f) * math.tan(la2) )
L = (lo2 - lo1) * 0.0174532925
lamb = L
while True:
sinArc = math.sqrt( math.pow(math.cos(u2) * math.sin(lamb),2) + math.pow(math.cos(u1) * math.sin(u2) - math.sin(u1) * math.cos(u2) * math.cos(lamb),2) )
cosArc = math.sin(u1) * math.sin(u2) + math.cos(u1) * math.cos(u2) * math.cos(lamb)
arc = math.atan2(sinArc, cosArc)
sinAzimuth = ( math.cos(u1) * math.cos(u2) * math.sin(lamb) ) // ( sinArc )
cosAzimuthSqr = 1 - math.pow(sinAzimuth, 2)
cosProduct = cosArc - ((2 * math.sin(u1) * math.sin(u2) ) // (cosAzimuthSqr))
C = (f//16) * cosAzimuthSqr * (4 + f * (4 - 3 * cosAzimuthSqr))
lamb = L + (1 - C) * f * sinAzimuth * ( arc + C * sinArc * ( cosProduct + C * cosArc * (-1 + 2 * math.pow(cosProduct, 2))))
print(lamb)
As mentioned the problem is that the value "lamb" (lambda) will not become smaller. I've even tried to compare my code to other implementations, but they looked just about the same.
What am I doing wrong here? :-)
Thank you all!
First, you should convert you latitudes in radians too (you already do this for your longitudes):
u1 = math.atan( (1 - f) * math.tan(math.radians(la1)) )
u2 = math.atan( (1 - f) * math.tan(math.radians(la2)) )
L = math.radians((lo2 - lo1)) # better than * 0.0174532925
Once you do this and get rid of // (int divisions) and replace them by / (float divisions), lambda stops repeating the same value through your iterations and starts following this path (based on your example coordinates):
2.5325205864224847
2.5325167509030906
2.532516759118641
2.532516759101044
2.5325167591010813
2.5325167591010813
2.5325167591010813
As you seem to expect a convergence precision of 10^(−12), it seems to make the point.
You can now exit the loop (lambda having converged) and keep going until you compute the desired geodesic distance s.
Note: you can test your final value s here.
Even if it is correctly implemented, Vincenty's algorithm will fail to
converge for some points. (This problem was noted by Vincenty.)
I give an algorithm which is guaranteed to
converge in Algorithms for geodesics; there's a python
implementation available here. Finally, you can find more
information on the problem at the Wikipedia page,
Geodesics on an ellipsoid. (The talk page has examples
of pairs of points for which Vincenty, as implemented by the NGS,
fails to converge.)

Categories

Resources