Use of global declaration inside if statement (Julia Code) - scope

Why do I have declare variables global when they are in same if elseif else block? What am I missing?
function f(N)
for n in 0:N
if n == 0
fibonacci_n = 0
fibonacci_n_1 = fibonacci_n
elseif n == 1
fibonacci_n = 1
fibonacci_n_1 = fibonacci_n
fibonacci_n_2 = fibonacci_n_1
else
global fibonacci_n_1, fibonacci_n_2
fibonacci_n = fibonacci_n_1 + fibonacci_n_2
fibonacci_n_1 = fibonacci_n
fibonacci_n_2 = fibonacci_n_1
end
#printf "%5i %10i\n" n fibonacci_n
end
end

The problem you have is not really about global scope and you do not have to declare anything global here. global keyword is necessary if you would like a write access to a global variable.
Your global keyword introduce new global bindings fibonacci_n_1 and fibonacci_n_2. It does not matter where you put the global keyword in the scope. You can even access the last value of fibonacci_n_1 and fibonacci_n_2 after the function terminates: try f(5); println(fibonacci_n_1) in global scope.
If you remove the global declaration in your function, fibonacci_n_1 and fibonacci_n_2 will be defined in the local scope of your for-loop. Hence, there will not be a global scope access issue. The issue you have, however, will be about the following behavior of variables introduced in loop blocks.
for loops, while loops, and Comprehensions have the following behavior: any new variables introduced in their body scopes are freshly allocated for each loop iteration, as if the loop body were surrounded by a let block
https://docs.julialang.org/en/v1/manual/variables-and-scoping/#For-Loops-and-Comprehensions-1
This means that you cannot access a variable's value or binding in the previous iteration if you introduce that variable inside the for-loop. This is not similar to the behavior of variables introduced in Python or MATLAB loops.
Instead, you can define such variables outside the for loop but inside the function.
function f(N)
fibonacci_n, fibonacci_n_1, fibonacci_n_2 = 0, 0, 0
for n in 0:N
if n == 0
fibonacci_n = 0
fibonacci_n_1 = fibonacci_n
elseif n == 1
fibonacci_n = 1
fibonacci_n_2 = fibonacci_n_1
fibonacci_n_1 = fibonacci_n
else
fibonacci_n = fibonacci_n_1 + fibonacci_n_2
fibonacci_n_2 = fibonacci_n_1
fibonacci_n_1 = fibonacci_n
end
#printf "%5i %10i\n" n fibonacci_n
end
end
For more relevant discussion about scope of variables in Julia, please see the Scope of Variables section of Julia documentation.

Related

How to increase variables by 1 in Nim

I would like to know how to increase variables in Nim by 1, alike the (variablename)++ function in other programming languages.
My Code by far:
int i = 1
int j = 1
for i in countup(1, 10):
j = j + 1
echo "number: "
echo i
I want to change the j = j + 1 with the Nim version of: j++
You can use the += operator:
j += 1
You can increment a variable by one in Nim with the inc() function: inc(var_name)

How to continuously read from the serial port in Matlab?

This is my code:
serialPort = 'COM3';
s = serial(serialPort,'BaudRate',9600);
if (s.Status == 'closed')
s.BytesAvailableFcnMode = 'byte';
s.BytesAvailableFcnCount = 200;
s.BytesAvailableFcn = #Serial_OnDataReceived;
fopen(s);
end
This is the CallBack function
function Serial_OnDataReceived(obj,event)
global s;
global i;
global endCheck;
global yVals;
global xVals;
if (s.Status == 'open')
while s.BytesAvailable > 0 && endCheck ~= '1',
data = str2num(fgetl(s));
dlmwrite ('SensorsReading.csv', data, '-append');
yVals = circshift(yVals,-1);
yVals(end) = data(3);
xVals = circshift(xVals,-1);
i = i + 0.0125;
xVals(end) = i;
end
figure(1);
plot(xVals,yVals);
end
end
Right after the FOPEN function, I get this Warning:
The BytesAvailableFcn is being disabled. To enable the callback property
either connect to the hardware with FOPEN or set the BytesAvailableFcn property.
Does the logic that happens in the callback function Serial_OnDataReceived run on a different thread?
Is there a way to pass parameters to the function? I want to modify an array in the main script from the callback function, which is in a different file. What's the best way to do so?
I am also trying to plot the values when they're updated to show some kind of dynamic animation.
I am not sure about what is generating the warning, but to answer your other question (how to pass parameter to the callback and how to update the plot), a better way to go would be to prepare your plot outside of the callback, then pass the handle to the callback for update only.
nPointsInFigure = 10 ; %// number of "sliding points" in your figure
step = 0.0125 ; %// X points spacing
xVals = linspace(-(nPointsInFigure-1)*step,0,nPointsInFigure) ; %// prepare empty data for the plot
yVals = NaN(nPointsInFigure,1) ;
figure(1) ;
hp = plot( xVals , yVals ) ; %// Generate the plot (with empty data) it will be passed to the callback.
serialPort = 'COM3';
s = serial(serialPort,'BaudRate',9600);
if (s.Status == 'closed')
s.BytesAvailableFcnMode = 'byte';
s.BytesAvailableFcnCount = 200;
s.BytesAvailableFcn = {#Serial_OnDataReceived,hp,step} ; %// note how the parameters are passed to the callback
fopen(s);
end
Your callback will become:
function Serial_OnDataReceived(obj,event,hp,step)
global endCheck; %// I don't know how you use that so I could not get rid of it.
xVals = get(hp,'XData') ; %// retrieve the X values from the plot
yVals = get(hp,'YData') ; %// retrieve the Y values from the plot
while obj.BytesAvailable > 0 && endCheck ~= '1',
data = str2num(fgetl(s));
dlmwrite ('SensorsReading.csv', data, '-append');
yVals = circshift(yVals,-1);
yVals(end) = data(3);
xVals = circshift(xVals,-1);
xVals(end) = xVals(end-1) + step ;
end
set( hp , 'XData',xVals , 'YData',yVals ) ; %// update the plot with the new values
Also note: (1) You don't need to check for the state open/close of the serial port within the callback function. If the event was triggered it means the port was open. (2) you don't need to declare s as global, the obj parameter is actually the serial object itself.
If the suggestion from Hoki does not work, try using a timer.
% The following line is useful for debugging
mytimerCallback = #(~, ~) disp('Caught error For Tenzo Timer');
if isempty(timerXbee)
timerXbee = timer('ExecutionMode','FixedRate','Period',0.1,...
'TimerFcn',{#storeDataFromSerial},'ErrorFcn', mytimerCallback);
try
start(timerXbee);
catch
disp('Timer Xbee');
disp '******** InstrumentSubscription ERROR *********'
disp (exception.message);
disp '***********************************************'
end
end
% If you are using a polling approach, request data
sendRequest(cmd);
connectionRequested = true;
Then implement the timer function that will be called every period
function storeDataFromSerial(~,~,~)
while (get(xbee, 'BytesAvailable')~=0)
serialProtocol();
end
end
When you want to disconnect the device and close the communication don't forget to stop the timer with
stop(timerXbee)

Making and using an object-style Module in Lua

I've been trying to take a module in Lua and use it to imitate an object. i.e. I made a deck of cards:
local Card = require("Card")
local function firstCard()
Card.newDeck()
Card.drawCard()
return Card.getCard()
end
local function secondCard()
Card.newDeck()
Card.drawCard()
return Card.getCard()
end
first = firstCard()
second = secondCard()
print(first)
print(second)
I set first = firstCard() and second = secondCard() but when I print the two variables second occasionally results as nil. I'm honestly lost. Here's the actual module itself.
local Card = {}
local deck
local value
local number, suit
local index = 0
local getCard
local getValue
function Card.newDeck()
deck = {}
value = {}
for x = 1, 13 do
if x == 1 then
number = "Ace"
elseif x == 11 then
number = "Jack"
elseif x == 12 then
number = "Queen"
elseif x == 13 then
number = "King"
else
number = x
end
for x1 = 1, 4 do
if x1 == 1 then
suit = "Clubs"
elseif x1 == 2 then
suit = "Diamonds"
elseif x1 == 3 then
suit = "Hearts"
else
suit = "Spades"
end
index = index + 1
deck[index] = number.." of "..suit
value[index] = x
end
end
end
function Card.drawCard()
index = math.random(52)
getCard = deck[index]
getValue = value[index]
end
function Card.getCard()
return getCard
end
function Card.getValue()
return getValue
end
function Card.getIndex()
return index
end
return Card
I have limited knowledge of Lua when it comes to Object-Oriented programming and to be honest, I typically only use it for calculations or small games to keep me occupied I'm class- I'm only 16. I'm more used to Java, even though I started using Lua well before I picked up Java. I just want to know if and how I can make this work. For the most part it works, just those occasional nil values.
The problem is that you have declared the index variable local at the top level of your module. That means that the random value of index that you have calculated in your first drawCard() is reused in your second call to newDeck(). You can add print(index) at the start of newDeck() to see what I mean.
There are several ways to solve the problem. One would be to add index = 0 at the top of newDeck(). A better one would be to declare your variables with smaller scoping, i.e. make index local to each function that uses it.
Try to use this instead, seems to work fine, it should print "ERROR NO VALUE" if there is some issue with the index, if that occurs (it shouldn't though), just print the index (in the generateCard() function).
This is the test
local Card = require("Card");
local function firstCard()
Card.newDeck()
return Card.generateCard(); -- two parameters, deck and value
end
local function secondCard()
Card.newDeck()
return Card.generateCard();
end
first = firstCard()
second = secondCard()
print(first)
print(second)
This is the module
local Card = {deck={};value={};};
function Card.newDeck()
local self = Card
local deck = self.deck;
local value = self.value;
local cards = {[1]="Ace",[11]="Jack",[12]="Queen",[13]="King"};
local types = {[1]="Clubs",[2]="Diamonds",[3]="Hearts",[4]="Spades"};
for x = 1, 13 do
for i = 1, 4 do
local _card,_type=(cards[x] or x),types[i];
deck[#deck+1] = _card.." of ".._type
value[#deck+1] = x
end
end
end
function Card.generateCard()
local self = Card;
if(not math.round) then
math.round = function(value) local mi,ma=math.floor(value),math.ceil(value)return(mi+0.5>value and mi or ma)end;
end
local index = math.round(math.random(1000, 52000)/1000);
return (self.deck[index] or "NO VALUE FOR CARD"),(self.value[index] or "NO DECK FOR CARD");
end
return Card

when a spawn object moves across the screen, I want it to despawn once it gets to a certain x value?

I have random spawned objects that automatically moves across the screen. I want it so that when the objects reach a certain x position it despawns itself.
local mRandom = math.random
local objects = {"Vehicle11" ,"Vehicle21","Vehicle31","Vehicle41"}
local objectTag = 0
local object = {}
local function spawncarright()
local rightcar = {408,312}
objectTag = objectTag + 1
local objIdx = mRandom(#objects)
local objName = objects[objIdx]
object[objectTag] = display.newImage(objName..".png") -- see the difference here
object[objectTag].x = 32
object[objectTag].y = rightcar[math.random(1,2)]
object[objectTag].name = objectTag
transition.to(object[objectTag], {time = 3500, x = 348})
end
timer.performWithDelay(2000,spawncarright,0)
so once reaches object[objectTag].x = 348 the object despawn
Try this:
local function deSpawn()
for i=1,objectTag do
if(object[i]~=nil and object[i].x~=nil and object[i].x>=348)then
-- If you want to remove the object, then use the following 2 lines --
object[i]:removeSelf()
print("Removed object["..i.."]")
--or else if you want to reposition the object, then uncomment the following --
--[[
spawncarright()
--]]
end
end
end
Runtime:addEventListener("enterFrame",deSpawn)
Keep coding................... :)
You should do it within the transition.to call:
object[objectTag].deleteSelf = function(self)
object[self.name] = nil -- Remove reference to object in table
display.remove(self)
self = nil
end
local localObj = object[objectTag] -- Do this so the object doesn't change with the objectTag does; if objectTag is incremented, then when the transition ends, it won't be pointing to the same object when we call the function
transition.to(localObj, {time = 3500, x = 348, onComplete = function() localObj:deleteSelf() end})

Updating a string inside a callback

The following code is a graphic rendering of the Earth globe spinning eastward. I have two push buttons, Spin and Stop. Both share the same callback function, hAnimaCallback. In particular, this latter does not work. I pretend to use the strings (names) of the push buttons to create a switch that stops the movement. However, I can not get to change the string name inside the while loop and I do not understand why my method is wrong.
function example
fh = figure('Menu','none','Toolbar','none','Units','characters');
T = 0:pi/100:2*pi;
Y = zeros(numel(T),3);
Y(:,1) = 7000*cos(T);
Y(:,2) = 7000*sin(T);
hPanAni = uipanel('parent',fh,'Units','characters','Position',...
[22.6 10.4 53 23],'title','Controls','FontSize',11,...
'FontAngle','italic','FontWeight','bold');
hIniAni = uicontrol(hPanAni,'Style','pushbutton','Units','normalized',...
'Position',[0.14 0.64 0.5 0.12],'String','Spin',...
'FontSize',10,'Callback',#hAnimaCallback);
hFinAni = uicontrol(hPanAni,'Style','pushbutton','Units','normalized',...
'Position',[0.14 0.26 0.5 0.12],'String','Stop',...
'FontSize',10,'Callback',#hAnimaCallback);
hPantSim = uipanel('Parent',fh,'Units','characters',...
'Position',[107.87 8 157.447 42],'BorderType','none','title',...
'Screen','FontSize',11,'FontAngle','italic',...
'FontWeight','bold');
hPantSimInt = uipanel('Parent',hPantSim,'Units','normalized','Position',...
[0 0 1 1],'BorderType','line','BackgroundColor','black');
ah4 = axes('Parent',hPantSimInt,'Units','normalized','Position',...
[0 0 1 1],'Color','none','Visible','off','DataAspectRatio',...
[1 1 1],'NextPlot','add');
rotate3d(ah4);
hgrot = hgtransform('Parent',ah4);
Resf = 6378;
maptext = imread('tierra.jpg');
[X, map] = rgb2ind(maptext,128);
[x,y,z] = sphere(50);
x = Resf*x;
y = Resf*y;
z = Resf*z;
props.FaceColor= 'texture';
props.EdgeColor = 'none';
props.Parent = hgrot;
props.Cdata = flipud(X); % it is necesary to do this for getting the
% appropiate image on the sphere
hsurf = surface(x,y,z,props);
colormap(map);
axis equal;
view([71 14]);
set(gcf,'Renderer','opengl')
drawnow;
line('parent',ah4,'XData',Y(:,1),'YData',Y(:,2),'ZData',...
Y(:,3),'Color','red','LineWidth',2);
line('parent',ah4,'XData',Y(end,1),'YData',Y(end,2),...
'ZData',Y(end,3),'Marker','o','MarkerSize',6,'MarkerFaceColor','b');
axis square equal vis3d;
view(3);
handles.XLim = get(ah4,'XLim');
handles.YLim = get(ah4,'YLim');
handles.ZLim = get(ah4,'ZLim');
xmin = handles.XLim(1);
ymin = handles.YLim(1);
zmin = handles.ZLim(1);
xmax = handles.XLim(2);
ymax = handles.YLim(2);
zmax = handles.ZLim(2);
set(ah4, 'XLim', [xmin xmax],'YLim', [ymin ymax],'Zlim',[zmin zmax]);
az = 0;
function hAnimaCallback(hObject,evt)
while (ishandle(fh))
state = get(hObject,'String'), % state should change between the states of
% Spin and Stop but this does not occur
if (strcmp(state,'Stop'))
break;
else
az = az + 0.01745329252;
set(hgrot,'Matrix',makehgtform('zrotate',az));
drawnow;
end
end
end
end
It seems like you are running into some kind of race condition because of the repeated drawnow calls in the while loop. The state changes to Stop, when you press the Stop button, but it is to quick to notice. Basically, the while loop is running as fast as MATLAB can run. Instead of drawnow using a pause(0.1) command seems to work (with a little bit code logic changes):
az = 0;
spin = false;
function hAnimaCallback(hObject,~)
state = get(hObject,'String')
if strcmp(state, 'Spin')
spin = true;
else
spin = false;
end
while (spin)
az = az + 0.01745329252;
set(hgrot,'Matrix',makehgtform('zrotate',az));
pause(0.1);
end
end

Resources