PySimpleGUI need help planning an intricate measurements calculator - python

i'm working on a program that should figure out the dimensions of individual pieces in kitchen cabinet modules, so you only set: height, depth, width of the material(18mm), and then you select modules from a list and after setting the dimensions of each you should be presented with a list of pieces and their dimensions.
Since all of this is somewhat standardized individual pieces's dimensions are figured out by simple math, but each consists of it's own set of operations, which should be ran once and display the results in the interface(eventually i'll figure out how to write it to an excel compatible format)
as you can see here it can get to be complex, i can work it out over time no problem, but right now i'm not sure PYGUI is what i need.
import PySimpleGUI as sg
layout1 = [[sg.Text('Altura', size=(10,1)),sg.Input('',key='Alt')], #Height
[sg.Text('Densidad Placa', size=(10,1)),sg.Input('',key='Placa')],# Material's density
[sg.Text('Profundidad', size=(10,1)),sg.Input('',key='Prof')]] #Depth
layout2 = [[sg.Text('Ancho Modulo', size=(10,1)),sg.Input('',key='WM')], #Module's width
[sg.Text('lateral', size=(10,1)),sg.Text('',key='Lat'),sg.Text('x'),sg.Text('',key='Prof2')], #side pieces
[sg.Text('Piso', size=(10,1)),sg.Text('',key='WM2'),sg.Text('x'),sg.Text('',key='Prof2')], # bottom piece
[sg.Button('Go')]]
#Define Layout with Tabs
tabgrp = [[sg.TabGroup([[sg.Tab('1', layout1),
sg.Tab('2', layout2)]])]]
window =sg.Window("Tabs",tabgrp)
#Read values entered by user
while True:
event,values=window.read()
if event in (sg.WINDOW_CLOSED, 'Close'):
break
elif event == 'Go':
anc = values['WM']
altura = values['Alt']
placa = values['Placa']
prof = values['Prof']
try:
v = int(anc) #width
w = int(prof)#depth
x = int(altura)#height
y = int (placa)# Material's density
altlat = str(x - y) #height of side pieces
prof2 = int(w - y) #depth of pieces,(total depth incluiding the door)
ancm = int(v) #width
except ValueError:
altlat = "error"
prof2 = "error"
ancm = "error"
window['Lat'].update(value=altlat)
window['Prof2'].update(value=prof2)
window['WM2'].update(value=ancm)
window.refresh
#access all the values and if selected add them to a string
window.close()
i figured i use functions for every set of operations and call them as i need them, but keys can't be reused and every tutorial i've seen points towards them, and other implementations i tried failed,. i've been using python since last night, so i'm not sure how many options i have, nor how limited my options will be with PYGUI's toolset.

I think what you are asking is, how can I make a function that will take the values and run an operation on them? This seems to be more of a general python question than one about pyGUI, but here is a quick answer.
def calc_side_panel_height(altura, placa):
x = int(altura)#height
y = int (placa)# Material's density
return (x - y) #height of side pieces
try {
height_of_side = calc_side_panel_height(altura, place)
# use height here.
altlat = str(height_of_side)
}
does that start to make sense? You would call functions and in those functions do the calculations, so you don't have to rewrite the code.
more info: https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Functions
Let me know if I'm confused!

Related

How to use a 3d array (image-like) as an index-map to slice a 4d array (video) (a generalization of the rolling shutter effect)

I've been fooling around lately with taking the webcam's video steam and giving it a pixel-dependent time delay.
A very simple example for that idea is the famous rolling shutter, but when applied in order of seconds instead of 1/100ths, it looks like this https://youtu.be/mQ0hS7l9ckY
Now, rolling shutter is fun and all, but I want something more general. I want a delay map, a (height, width, 3) shaped array that tells my how far back to go in the video. A pseudo-code for this would be
output_image[y, x, c] = video_cache[delay_map[y,x,c], y, x, c]
where the first index of the video cache is time, y,x are self-explanatory, and c is the color channel (BGR because open cv is weird).
In essence, each pixel of the output is a pixel of the video at the same position, but at a time determined by the delay map at the very same position.
Here's the solution I have now: I flattened everything, I access the video cache similar to how you unravel multi-index nonsense, and once I'm done I reshape the result into an image.
This solution works pretty fast, and I'm pretty proud of it. It almost keeps up with my webcam's frame rate (I think I average on 20 of these per second).
I think the flattening and reshaping of each frame costs me some time, and if I could get rid of those I'd get much better results.
Link to the whole file at the bottom.
Here's a skeleton of my implementation.
I have a class called CircularCacheDelayAccess. It stores a cache of video frames (with given number of frames, called cache_size in my implementation). It enables you to store frames, and get the delay-mapped frame.
Instead of pushing all the frames around each time I store a new one, I keep an index that goes around in a circle, and video[delay=3] would be found via something like cache[index-3]. Thanks to python's funny negative index tricks, I don't even have to get the positive modulo.
The delay_map is actually a float array; when I use circ_cache.getFrame I input the integer part of delay_map.flatten(), and then I use the fractional part to interpolate between frames.
class CircularCacheDelayAccess:
def __init__(self, img_shape: tuple, cache_size: int):
self.image_shape = img_shape
self.cache_size = cache_size
# some useful stuff
self.multi_index_shape = (cache_size,) + img_shape
self.image_size = int(np.prod(img_shape))
self.size = cache_size * self.image_size
# the index, going around in circles
self.cache_index = 0
self.cache = np.empty(self.size)
# raveled_image_indices is a running index over a frame; it is the same thing as writing
# y, x, c = np.mgrid[0:height, 0:width, 0:3]
# raveled_image_indices = c + 3 * (x + width * y)
# but it's a lot easier
self.raveled_image_indices = np.arange(self.image_size)
def store(self, image: np.ndarray):
# (in my implementation I check that the shape matches and raise a ValueError if it does not)
self.cache_index = (self.cache_index + 1) % self.cache_size
# since cache holds entire image frames, the start of each frame is index * image size
cIndex = self.image_size * self.cache_index
self.cache[cIndex: cIndex + self.image_size] = image.flatten()
def getFrame(self, delay_map: np.ndarray):
# delay_map may either have shape == self.image_shape, or shape = (self.image_size,)
# (more asserts, for the shape of delay_map, and to check its values do not exceed the cache size)
# (if delay_map.shape == image_shape, I flatten it. If we were already given a flattened version,
# there's no need to do so)
frame = self.cache[self.image_size * (self.cache_index - delay_map) + self.raveled_image_indices]\
.reshape(self.image_shape)
return frame
As I've already stated, this works pretty good, but I think I could get it to work better if I could just side-step the flatten and reshape steps.
Also, keeping a flattened version of an array that makes sense in its full-shaped form is pretty awkward.
And, I've mentioned the interpolation part. It felt wrong to do that in CircularCacheDelayAccess, but doing the interpolation after I getFrame twice means I need the fractional part of delay_map to be in the full-shaped form, and I need the int part flattened, which is pretty silly.\
Here are some fun examples which would probably be pretty hard to understand without seeing the video, but are still fun to look at. It looks even better with a face, but I don't think I should show my face here, so sorry about that:
horizontal rolling shutter, color delay psychedelia, my weirdest effect so far
And here is a link to the entire code, with capture and stuff if you wanna mess around with it and read the entire code.
Thanks in advance!

Moving the cursor in relation to a certain fix-point in Python

is there any possibility to move the cursor in Python with % starting from a certain coordinate like (1,1)?
I am using pyautogui atm to automate and I thought it would be quite convenient if this is independent from the monitor size making it universal.
Thanks for your help in advance!
It's possible indirectly. As detailed at the top of the Mouse Control Functions page of the documentation, you can get the screen size using the size() function (which returns a tuple of (X, Y)). You can then do the math to figure out how many screen pixels equal the percentage you're looking for, then call moveTo() to go there.
# script to move mouse 50% to the right and down
import pyautogui as pag
percentage = 0.5
cur_X, cur_Y = pag.position() # current X and Y coordinates
size_X, size_Y = pag.size() # screen size
goto_X = (size_X - cur_X) * percentage + cur_X # current location plus half
goto_Y = (size_Y - cur_Y) * percentage + cur_Y # the distance to the edge
pag.moveTo(goto_X, goto_Y, 1) # move to new position, taking 1 second

Python - plt.savefig() resulting in blank image without plt.show()

I work on a crowd simulation, and I tried to get a simple representation at a given time like this : new to the site so here is the link. I work with Spyder and the code works wonderfully when I display the image in ipython with plt.show(), but when i try to save the images with plt.savefig() (I removed plt.show() prior to that, not the issue) i ended up with blank images. Here is the code :
p,v,t = resolve() #p[c][i] is the position vector of individual i at time t[c]
N = len(t) # number of instant
n = len(m) # number of individual
murs_x = [w[0] for w in W] # wall points x coordinates
murs_y = [w[1] for w in W] # wall points y coordinates
conv = 39.3701 #inch/m
L = longueur*conv/50 # width of figure
H = (largeur + decalage)*conv/50 # height of figure
for c in range(N):
fig1 = plt.figure(num="aff",figsize = (L,H), dpi = 200) # arbitrary num, allow to recreate the figure
ax = fig1.add_axes([1,1,1,1])
ax.set_axis_off() # visual purpose
ax.set_frame_on(False) # visual purpose
ax.axis([0,longueur,0,largeur+decalage])
ax.scatter(murs_x,murs_y,s=0.01,marker='.')
for i in range(n):
if p[c][i][1] <= (largeur + r[i]): # presence condition for individual i
ax.add_artist(plt.Circle((p[c][i][0], p[c][i][1]), r[i], alpha=1))
# drawing of the circle representing individual i
# here is the plt.show(), unused
fig1.savefig(str(c)+".png") # trying to save instant c visual represention
fig1.clf()
Moreover, without the 2 lines for visual purposes, the images are not totally blank but rather like this : another link.
I first attempted to use matplotlib.animation to create a video, however i had the same issue of a blank video with 2 cropped zeros in the upper right corner. I suppose that the issue is linked to the artist class (I had better results using scattered points instead of circles to represent each individual) but I am a beginner and do not know how to handle it precisely. At least the size of the image is the one expected one.
Thanks for reading this.

TDA - Sliding window on multiple signals

I'm trying to define a function in python that performs sliding window on multiple signals (and using the resulting SW as input for ripser).
What I want to achieve is this (examples with sines, sorry for bad drawing skills)
picture describing my goal
I have 14 signals of 10000 points, so a 14 x 10000 matrix, and I want to perform a sliding window on all the signals making them correlated in some way by grouping all the points for all the signals in each window, given its dimension.
I tried first using the code made by Christoper Tralie, but this gives me an error on the dimension of X, so now I'm trying to modify it.
def slidingWindowMultipleSignals(I, dim, Tau, dT):
'''
Performs the sliding window on multiple signals.
Author: Christopher J. Tralie
'''
N = I.shape[0] #Number of frames
P = I.shape[1] #Number of pixels (possibly after PCA)
pix = np.arange(P)
NWindows = int(np.floor((N-dim*Tau)/dT))
X = np.zeros((NWindows, dim*P))
idx = np.arange(N)
for i in range(NWindows):
idxx = dT*i + Tau*np.arange(dim)
start = int(np.floor(idxx[0]))
end = int(np.ceil(idxx[-1]))+2
if end >= I.shape[0]:
X = X[0:i, :]
break
f = scipy.interpolate.interp2d(pix, idx[start:end+1], I[idx[start:end+1], :], kind='linear')
X[i, :] = f(pix, idxx).flatten()
return X
The problem is that I don't know what to modify for making it doing the thing I described with the image.
Can someone point me to the right direction?
I suspect the problem is located in the line
NWindows = int(np.floor((N-dim*Tau)/dT))
specifically with the use of /. I'd check the dtypes of dim, Tau and dT. If all are integers, or if some are floats, / may not behave in exactly the same way.
Also, python expects the body of the function to be indented, which it isn't in your example.

How to simplify my codes?

I wrote a program for a class using recursion to mimic certain kinds of simple branching structures like trees. I thought my code was great until I showed my professor. He told my code was too complicated and said I would need to simplify it. Besides spacing them out, I'm not sure what else I could do. Any tips? (I'm a beginner so go easy on me.) This program creates multiple trees with varying thickness, number of branch and at different coordinates.
import random
import turtle
##I'm using a python module called turtle to visualize results
p1 = turtle.Pen()
##Creates a pen
p1.tracer(True)
## Shows pen drawing
p1.up()
p1.left(90)
d=random.randint(0,2)
## Varying thickness of branch
length=150
##Length of branches
contract=random.uniform(.5,1)
## Varying degree of contraction
branch=random.randint(5,8)
## Varying amount of branches
first=random.randint(30,70)
## Varying first degree of branch
next=random.randint(1,30)
## Varying degree between each branches
number1=random.randint(10,20)
number2=random.randint(-100,100)
number3=random.randint(-100,100)
# Range of numbers used for coordinates
def drawFern1(pen, depth, length, contractBy, branches, firstBranchAngle, nextBranchAngle):
if depth > 0:
#Pen's Position and heading
heading = pen.heading()
position = pen.position()
pen.width(depth)
pen.forward(length)
pen.left(firstBranchAngle)
for i in range(branches):
drawFern1(pen, depth-1, contractBy*length, contractBy,branches,firstBranchAngle,nextBranchAngle)
pen.right(nextBranchAngle)
pen.setheading(heading)
pen.setposition(position)
# Ensures that multiple trees are created each at different coordinates.
for i in range(number1):
p1.sety(number2)
p1.setx(number3)
p1.down()
drawFern1(p1,d,length,contract,branch,first,next)
number2 = random.randint(-100,100)
number3 = random.randint(-100,100)
p1.up()
This code looks pretty solid to me, especially for a Python beginner. I've seen much worse.
If I were writing it, I think I'd calculate number2 and number3 only inside the main for loop - a priming definition as you have here is often convenient for a while loop, but not necessary in this case. I would also try to use more explanatory variable names, and depending on the problem statement I might require the randomly generated depth value to be at least 1 - if depth is generated as 0, nothing will be drawn.
My version of this would look like this:
import random
import turtle
def drawFern(pen, depth, length, contraction, branches, firstBranchAngle, nextBranchAngle):
if depth > 0:
# Pen's Position and heading
heading = pen.heading()
position = pen.position()
pen.width(depth)
pen.forward(length)
pen.left(firstBranchAngle)
for i in xrange(branches):
drawFern(pen, depth-1, contraction*length, contraction, branches, firstBranchAngle, nextBranchAngle)
pen.right(nextBranchAngle)
pen.setheading(heading)
pen.setposition(position)
# I'm using a python module called turtle to visualize results
# Creates a pen
pen = turtle.Pen()
# Shows pen drawing
pen.tracer(True)
pen.up()
pen.left(90)
# Configure initial state
# Varying depth of recursive fern
depth = random.randint(1,2)
# Length of branches
length = 150
# Varying degree of contraction
contraction = random.uniform(.5,1)
# Varying number of branches
branches = random.randint(5,8)
# Varying first degree of branch
first_angle = random.randint(30,70)
# Varying degree between each branches
next_angle = random.randint(1,30)
number_of_trees =random.randint(10,20)
for i in xrange(number_of_trees):
new_x = random.randint(-100, 100)
new_y = random.randint(-100, 100)
pen.setx(new_x)
pen.sety(new_y)
pen.down()
drawFern(pen, depth, length, contraction, branches, first_angle, next_angle)
pen.up()
In addition to moving the x and y coordinate randomization into the main loop, moving the recursive function definition earlier in the file, and using some more explicit variable names, I've used xrange calls instead of range calls - a trivial optimization if you're on Python 2.x. If you're on Python 3, range is correct. But these are minor changes.
You could also throw in an if clause before the range(branches) loop to not even try if depth equals 1 - that's another minor optimization, although not one that will make a big difference.
I thought my code was great until I showed my professor. He told my
code was too complicated and said I would need to simplify it.
This is rather complicated code given the quality of trees that it draws:
Drawing just vertical lines and blank screens are within the random parameters of the program as written! Let's rework the program to move some of the randomness from the static configuration code into the recursive routine itself. We'll also fine tune the random ranges a bit and clean up the code, primarily by eliminating variables that are only set and used once:
from random import randint, uniform
from turtle import Screen, Pen # Using python turtle module to visualize results
# Configure initial state
DEPTH = randint(3, 4) # Varying thickness and splitting of branches
LENGTH = randint(125, 150) # Length of branches
CONTRACT_BY = uniform(0.4, 0.8) # Varying degree of contraction
def drawFern(pen, depth, length, contractBy):
if depth < 1:
return
# Save pen's position and heading
heading = pen.heading()
position = pen.position()
pen.width(depth * 1.5) # pen thickness depends on branching
pen.forward(length)
pen.left(randint(30, 70)) # Varying first degree of branch)
for _ in range(randint(5, 8)): # Varying amount of branches
drawFern(pen, depth - 1, contractBy * length, contractBy)
pen.right(randint(5, 30)) # Varying degree between each branches
# Restore pen's Position and heading
pen.setheading(heading)
pen.setposition(position)
screen = Screen()
pen = Pen(visible=False)
pen.left(90)
screen.tracer(False)
# Ensure that multiple trees are created each at different coordinates.
for i in range(randint(10, 20)):
pen.penup()
pen.setposition(randint(-200, 200), randint(-300, 0))
pen.pendown()
drawFern(pen, DEPTH, LENGTH, CONTRACT_BY)
screen.tracer(True)
screen.mainloop()

Categories