If statement not working in roblox studio - user-interface

local Frame = script.Parent.Parent.Frame.BackgroundTransparency
local Red = Frame.RedTeam.BackroundTransparency
local Blue = Frame.BlueTeam.BackroundTransparency
local Button = script.Parent
Button.MouseButton1Click:Connect(
if Frame = 1 then
Frame = 0
Red = 0
Blue = 0
end
if Frame = 0 then
Frame = 1
Red = 1
Blue = 1
)
At
if Frame = 1 then
Frame = 0
Red = 0
Blue = 0
end
I get "Expected else when parsing, instead got =".
Also, at the "end" I get "Expected eof, instead got end"
I cant figure this out and nothing is working.

Replace if Frame = 1 then with if Frame == 1 then
If you want to check wether two values are equal you need to use the equality operator ==, not the assignment operator =.
Also your second if statement is missing its closing end.
Further you probably want to think about your logic.
If Frame equals 0 you'll assign 1. But then you'll end up in the next if statement with the condition Frame == 1 and assign 0 again.
So your code basically does nothing useful.

In lua, if statements use operators which are ==, ~=, >, <, >=, and <=.
the '==' statement basically compares if the first argument they get is the same as the second argument they get, which is the case for you here.
So you'll need to change the Frame = 1 and the Frame = 0 to Frame == 1 and the Frame == 0.
and at the end of your function, it is missing an end there. And also at the start it is not calling a new function. And for peak optimization, instead of using 2 if statements, you can just use 1 with an elseif.
Correction:
local Frame = script.Parent.Parent.Frame.BackgroundTransparency
local Red = Frame.RedTeam.BackroundTransparency
local Blue = Frame.BlueTeam.BackroundTransparency
local Button = script.Parent
Button.MouseButton1Click:Connect(function()
if Frame == 1 then
Frame = 0
Red = 0
Blue = 0
elseif Frame == 0 then
Frame = 1
Red = 1
Blue = 1
end
end)

Related

Is there any way to use the return value as an argument to the same function during the previous recursion in merge sort

I am coding the Merge sort algorithm but somehow got stuck with a problem. The problem is that I need to use the return value of the merge function as an argument as an previous recursive call of the same merge function. Sorry for not being clear.
Here is my code:
a = [10,5,2,20,-50,30]
def mergeSort(arr):
l = 0
h = len(arr)-1
if h > l:
mid = (l+h) // 2
left = arr[l:mid+1]
right = arr[mid+1:]
mergeSort(left)
mergeSort(right)
merge(left, right)
def merge(l, r):
subarr = []
lc = 0
rc = 0
loop = True
while loop:
if lc > len(l)-1 and rc <= len(r)-1:
for i in range(rc, len(r)):
subarr.append(r[i])
loop = False
elif lc <= len(l)-1 and rc > len(r)-1:
for i in range(lc, len(l)):
subarr.append(l[i])
loop = False
elif l[lc] < r[rc]:
subarr.append(l[lc])
lc += 1
loop = True
elif r[rc] < l[lc]:
subarr.append(r[rc])
rc += 1
loop = True
elif l[lc] == r[rc]:
subarr.append(l[lc])
subarr.append(r[rc])
lc += 1
rc += 1
loop = True
mergeSort(a)
Any help will be appreciated thank you :)
First you need to actually return the result. Right now you return nothing so get None back.
Secondly, just assign to the same variable. left = mergeSort(left) and so on.
UPDATE:
Here is a debugged version.
a=[10,5,2,20,-50,30]
def mergeSort(arr):
l=0
h=len(arr)-1
if h>l:
mid=(l+h)//2
left=arr[l:mid+1]
right=arr[mid+1:]
# Capture the merge into variables here.
left=mergeSort(left)
right=mergeSort(right)
# Need a return of the merge.
return merge(left,right)
# Need to return arr if arr has 0 or 1 elements.
else:
return arr
def merge(l,r):
subarr=[]
lc=0
rc=0
loop=True
while loop:
if lc>len(l)-1 and rc<=len(r)-1:
for i in range(rc,len(r)):
subarr.append(r[i])
loop=False
elif lc<=len(l)-1 and rc>len(r)-1:
for i in range(lc,len(l)):
subarr.append(l[i])
loop=False
elif l[lc]<r[rc]:
subarr.append(l[lc])
lc+=1
loop=True
elif r[rc]<l[lc]:
subarr.append(r[rc])
rc+=1
loop=True
elif l[lc]==r[rc]:
subarr.append(l[lc])
subarr.append(r[rc])
lc+=1
rc+=1
loop=True
# Need to return the results of merge.
return subarr
# Need to actually try calling the function to see the result.
print(mergeSort(a))
I also indented more sanely. Trust me, it matters.
There are multiple problems in our code:
you do not return the sorted slice from mergeSort nor merge. Your implementation does not sort the array in place, so you must return subarr in merge and the return value of merge in mergeSort or arr if the length is less than 2.
your code is too complicated: there are many adjustments such as mid+1, len(l)-1, etc. It is highly recommended to use index values running from 0 to len(arr) excluded. This way you do not have to add error prone +1/-1 adjustments.
the merge function should proceed in 3 phases: merge the left and right arrays as long as both index values are less than the array lengths, then append remaining elements from the left array, finally append remaining elements from the right array.
there is no need to make 3 different tests to determine from which of the left and right array to take the next element, a single test is sufficient.
also use a consistent amount of white space to indent the blocks, 3 or 4 spaces are preferable, tabs are error prone as they expand to different amount of white space on different devices, mixing tabs and spaces, as you did is definitely a problem.
Here is a modified version:
def mergeSort(arr):
# no need to use l and h, use len(arr) directly
if len(arr) > 1:
# locate the middle point
mid = len(arr) // 2
# left has the elements before mid
left = arr[:mid]
# right has the elements from mid to the end
right = arr[mid:]
# sort the slices
left = mergeSort(left)
right = mergeSort(right)
# merge the slices into a new array and return it
return merge(left, right)
else:
# return the original array (should actually return a copy)
return arr
def merge(l, r):
subarr = []
lc = 0
rc = 0
# phase1: merge the arrays
while lc < len(l) and rc < len(r):
if l[lc] <= r[rc]:
subarr.append(l[lc])
lc += 1
else:
subarr.append(r[rc])
rc += 1
# phase2: copy remaining elements from l
while lc < len(l):
subarr.append(l[lc])
lc += 1
# phase3: copy remaining elements from r
while rc < len(r):
subarr.append(r[rc])
rc += 1
# return the merged array
return subarr
a = [10, 5, 2, 20, -50, 30]
print(mergeSort(a))

How to generate a matrix with a function pattern?

Background info (Optional reading):
I'm running simulations of reflections of sound waves in against boundaries. The medium conditions for the points in space are set using a matrix. Let's say the dimensions of the space is an N by N grid, and there are two speeds of sound I care about, c0 and c1.
Right now I'm using code like the following to generate barrier patterns
medium.sound_speed = c0*ones(N,N); % set the speed of sound to be c0 everywhere
medium.sound_speed(:, N/2:N) = c1; % set the right half of the grid to a different speed
medium.sound_speed(50:70, 50:70) = c1; % set a box to have a different speed
Or
% set all speeds to c0 except set the diagonal to c1
medium.sound_speed = c0*ones(N,N)-(c0*eye(N,N))+c1*eye(N,N);
However, I can't generate more complex boundaries with different curvatures.
Question
I want to programmatically create matrices with patterns reflecting functions. For instance, I want to enter f(x)=2 and for that to create a matrix that looked something like this, assuming N=6.
[ 0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
1 1 1 1 1 1
0 0 0 0 0 0
0 0 0 0 0 0 ]
Or f(x)=0.5*x+1
[ 0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 1 1
0 0 1 1 0 0
1 1 0 0 0 0
0 0 0 0 0 0]
I would also be able to generate curved patterns like f(x)=1/x, which seems to require some form of the Midpoint circle algorithm, used for drawing curvatures with pixels.
[ 1 0 0 0 0 0
1 0 0 0 0 0
0 1 0 0 0 0
0 0 1 1 0 0
0 0 0 0 1 1
0 0 0 0 0 0 ]
In reality, N is at least 128, so manually creating these matrices for shapes with some level of complexity is impractical, and I thought this was an interesting problem.
Does anyone know of some way to do this, or suggestions for alternative approaches?
Thank you in advance.
Edit:
I modified this implementation of Bresenham's algorithm to provide a matrix with the desired line given an origin and an ending point.
function M=bresenham_line(point)
if (abs(point(4)-point(2)) > abs(point(3)-point(1))) % If the line is steep
x0 = point(2);y0 = point(1); x1 = point(4);y1=point(3);% then it would be converted to
token =1; % non steep by changing coordinate
else
x0 = point(1);y0 = point(2); x1 = point(3);y1=point(4);
token = 0;
end
if(x0 >x1)
temp1 = x0; x0 = x1; x1 = temp1;
temp2 = y0; y0 = y1; y1 = temp2;
end
dx = abs(x1 - x0) ; % Distance to travel in x-direction
dy = abs(y1 - y0); % Distance to travel in y-direction
sx = sign(x1 - x0); % sx indicates direction of travel in X-dir
sy = sign(y1 - y0); % Ensures positive slope line
x = x0; y = y0; % Initialization of line
param = 2*dy - dx ; % Initialization of error parameter
for i = 0:dx-1 % FOR loop to travel along X
x_coord(i+1) = x; % Saving in matrix form for plot
y_coord(i+1) = y;
param = param + 2*dy; % parameter value is modified
if (param >0) % if parameter value is exceeded
y = y +1*sy; % then y coordinate is increased
param = param - 2*(dx ); % and parameter value is decreased
end
x = x + 1*sx; % X-coordinate is increased for next point
end
M = zeros(size(x_coord,2), size(y_coord,2));
for i=1:1:size(x_coord,2)
x = x_coord(i);
y = y_coord(i);
M(x,y) = 1;
end
M
Implemented like so:
c1 = 0;
M = bresenham_line([1 1 Nx/2+1 Ny+1]);
medium.sound_speed = c0*ones(Nx,Ny) - (c0*M) + c1*M;
No progress on curved function shapes yet.
A way to get some similar results:
f = #(x)0.5*x; %create the function (x should be written even if the function doesn't depend on x: #(x) 0*x + 2)
N = 6; %choose the size of the atrix
M = zeros(N,N); %create an empty matrix
x = (1:N);
y = round(f(x-1)); %discretization
x(y>N-1|y<0) = [];
y(y>N-1|y<0) = [];
M(sub2ind(size(M),y+1,x)) = 1;
M = flipud(M)
So you can choose your function, then the result in your matrix will look like a discretization of a normal plot.
This is a slightly 'dirty' way of getting something like this, although I you best bet might Bresenham's algorithm.
N = 128;
[X,Y] = meshgrid(1:N,1:N);
bound1 = Y<2*X;
bound2 = Y<2*X+1;
M = xor(bound1,bound2);
bound1 you can define any function y=f(x), and mark the area under it. with bound2 you select and area that is slightly higher (shifted up). Once you take and xor of the two area you get just the desired y=f(x) marked. I think that in order to get reasonable results the shift might be different for more complicated function.
For illustration I used imagesc (the flipud is just for make the (0,0) in the bottom left, instead of the top left):
imagesc(flipud(M));
Edit
Indeed for some function this might not be the best. For example for y=x^2, you have to increase the shift and still does not look great.
bound1 = Y<X.^2;
bound2 = Y<X.^2+15;
M = xor(bound1,bound2);

Arithmetic/Geometric series

The code below returns "Arithmetic", "Geometric" if the input array is an arithmetic and geometric series respectively and -1 if it is neither.
Although the code works fine, when I change
if s = arr.length - 1
to
if s == arr.length - 1
in the while loop, the code is not working properly anymore.
I do not understand why. Shouldn't == work instead of =?
def ArithGeo(arr)
# code goes here
len = arr.length
difference = arr[len-1] - arr[len-2]
ratio = arr[len-1]/arr[len-2]
k = 0
s = k + 1
while (arr[s] - arr[k]) == difference && s < arr.length
if s = arr.length - 1
return "Arithmetic"
end
k += 1
end
k = 0
while arr[s] / arr[k] == ratio && s < arr.length
if s = arr.length - 1
return "Geometric"
end
k += 1
end
return -1
end
You're never changing the value of s which I think you want to do. You should do that at the point that you increment k
k += 1
s = k + 1
Also, at the point where you reinitialize k for the geometric test, you want to reset s as well...
k = 0
s = k + 1
You could also get rid of the variable s completely and make it a method... add these three lines at the top of the code
def s(k)
k + 1
end
And remove all the lines where you assign a value to s and use s(k)... s(k) will be a method that always returns the next higher value to k
The difference between those two statements is that variable s is set for the first statement but not for the second. The first if statement has thus a side effect of setting s to arr.length - 1
if s = arr.length - 1 # s => arr.length - 1
if s == arr.length - 1 # s => undefined
Because the if statement is inside a while loop which uses s in its expression the change of the statement changes the behavior of the programm.
If you put == the statement will try to check if they are equals , with just = the statement work properly because your are only setting the value to a value , so this is always true.
If it's different compare something to equals than just set a variable , that can be always true.

How to convert a nested loop into parfor loop

This is my from my MATLAB script.
function [ Im ] = findBorders( I )
Im = false(size(I));
I = padarray(I, [1, 1], 1);
[h w] = size(Im);
bkgFound = false;
for row = 1 : h
for col = 1 : w
if I(row + 1, col + 1)
bkgFound = false;
for i = 0:2
for j = 0:2
if ~I(row + i, col + j)
Im(row, col) = 1;
bkgFound = true;
break;
end;
end;
if bkgFound
break;
end;
end;
end;
end;
end;
end
So, I need to convert it to parfor loop, to run into GPU.
I need help. I read some articles, but have no idea about how to convert this.
In MATLAB, parfor doesn't allow for things to run on the GPU. The best way to interface with the GPU through MATLAB is to convert your data to a gpuArray and then all operations performed on that data that are optimized for the GPU will be optimized there.
As #Daniel stated, the code that you have posted 1) is not ideal for any sort of parallel processing and 2) could likely be sped up only through vectorization.
I'm not entirely sure what you're trying to do, but it seems like you're trying to find pixels within an image that are surrounded by "not-background". For this I would usually use 2D convolution with a neighborhood kernel to figure out how many neighbors of a given value a pixel has.
For example, the following code locates any pixel which is itself false and completely surrounded by false values (assuming your input image is a logical)
I = [...
1 1 1 1 0;
1 0 0 0 0;
0 0 0 0 0;
0 0 0 0 0;
0 0 0 1 1;
0 0 0 1 0;
];
surrounded_by_zeros = conv2(double(I), ones(3), 'same') == 0
surrounded_by_zeros =
0 0 0 0 0
0 0 0 0 0
0 0 1 1 1
1 1 0 0 0
1 1 0 0 0
1 1 0 0 0
I personally like this solution, but if you have the Image Processing Toolbox, you can also use imerode or imdilate to basically do the same thing.
surrounded_by_zeros = ~imdilate(I, ones(3));
surrounded_by_zeros = imerode(~I, ones(3));
If for some reason you really needed to move this calculation to the GPU (you don't), you could cast this as a gpuArray and then perform the same operation and it would use the GPU behind the scenes
I = gpuArray(I);
surrounded_by_zeros_on_gpu = conv2(double(I), ones(3), 'same') == 0;
Keep in mind that this has the overhead of copying I over to the GPU which for large enough images can be a significant performance hit.

Changing a variable based on a user's input

I am trying to have xpos and ypos change based on the direction the player enters. The program succeeds in asking Where to? but the position does not change. The script also always defaults to the last condition (puts("You're drunk.")).
For example:
> n
0
1
However, my output is:
> n
You're drunk.
0
0
This is my current code:
north = "n"
west = "w"
south = "s"
east = "e"
xpos = 0
ypos = 0
puts("WHERE TO?")
compass = gets
if compass == north
ypos = ypos + 1
elseif compass == west
xpos = xpos - 1
elseif compass == south
ypos = ypos - 1
elseif compass == east
xpos = xpos + 1
else
puts("You're drunk.") #if the player does not submit a proper direction
puts(xpos) #for debugging. prints zero when called showing the player has not moved
puts(ypos)
end
As others have pointed out, it's probably the missing chomp and the elseif.
Just a suggestion, but this cries out for a case statement:
case compass
when 'north'
ypos = ypos + 1
when 'west'
xpos = xpos - 1
when 'south'
ypos = ypos - 1
when 'east'
xpos = xpos + 1
else
puts("You're drunk.") #if the player does not submit a proper direction
puts(xpos)#for debugging. prints zero when called showing the player has not moved
puts(ypos)
end
It looks like you have two main issues, at least that I can see. First, elseif should be elsif. I'm surprised you aren't getting a syntax error on that.
Second, Kernel::gets returns the next line entered, up to and including the linebreak. This means that you have to remove the linebreak at the end, so that comparing with strings that don't have \r\n or \n, depending on your platform, can be compared. This is very simple: Just replace
compass = gets
with
compass = gets.chomp
(String#chomp reference)
Alternatively, if you'd like to get rid of all whitespace before and after, you could use
compass = gets.strip
(String#strip reference)

Resources