Julia Variable value reset - function

I'm just starting in Julia after a strong background in C++. I'm having an issue with my integer variables being reset to what I initialized them as in the beginning of my program.. even though I changed the variable value inside a function. Can anyone explain why this is?
num = 0
function getNum()
num = 1
end
getNum()
num #this returns 0, not 1
This is a problem because I will need to reference that variable in another function.

num is in global scope (note that the same behavior applies in e.g. Python)
If necessary, you could modify it by referencing as a global:
function getNum()
global num = 1
end
However, it is worth considering whether there is a more effective way to structure your code. Global variables can be useful in some situations, but they can also make code more difficult to reason about.

Related

Julia - SymPy creating function

I'm trying to create a function in the for statement. But it didn't work.
Ex:
using SymPy
list=[1,1,-1]
a(x)=2^x
b(x)=3^x
c(x)=4^x
x = symbols("x")
for i=1:length(list)
if list[i]==1
a(x)=a(x)*b(x)
elseif list[i]==-1
a(x)=a(x)*c(x)
end
end
That is to say, I would like to yield,
a(x)=2^x*3^x*3^x*4^x
However, it only returned the original function.
a(x)=2^x
I am not sure is it functional or not.
Thanks :)
This looks like a scoping issue, check the docs here: https://docs.julialang.org/en/v1/manual/variables-and-scoping/
The for loop introduces its own scope, so the global a(x) that you declare outside the loop isn't affected by what's happening in your loop.
You can either wrap everything you do in a function:
function main()
list = [1, 1, -1]
...
return a(x)
end
or annotate the a(x) in your loop as global. Generally global variables are bad for performance and best avoided in Julia, so you should think about how you can structure your code into functions.
(FWIW I get a StackOverflowError for both of the solutions I mentioned here, but that's probably an issue with how you're using SymPy which I know nothing about unfortunately!)

Getting all functions in a Lua script

I'm trying to figure out a way to get all functions in a Lua script. This script has been compiled into a function through loadfile. For example, I'd want to get every function defined in the script below.
function example1()
end
local function example2()
end
local library = {}
function library:example3()
end
(function()
-- Functions like this too.
end)
The names aren't important, I'm just looking for a way to get the actual functions so I can use them in debug.getinfo and get information like the lines they were defined in. I have LuaJIT, if that makes this any easier. Is something like this even possible? Thanks in advance.
I guess the file declares its functions as global, or it would be really easy to track what is returned.
If that's the case, you can cycle through all the global items with a generic for loop, and only take the functions from them:
allFuncs = {}
for key, item in pairs(_G) do
if type(item) == "function" then
allFuncs[#allFuncs + 1] = item
end
end
(_G is the table holding all the global variables)
Then you will have a list (allFuncs) holding all the functions declared, but be aware that it will also contain default functions like setmetatable or xpcall.
It's easy to modify the code to not make this happen, but only use this for testing / learning:
function allFuncs()
local funcsTab = {}
for key, item in pairs(_G) do
if type(item) == "function" then
funcsTab[#funcsTab + 1] = item
end
end
return funcsTab
end
defaultFuncs = allFuncs()
--then you load your file: other functions get declared
--we create another table containg the default + the new functions
myFuncs = allFuncs()
--then you subtract the first table from the second
for i = 1, #myFuncs do
for o = 1, #defaultFuncs do
if myFuncs[i] == defaultFuncs[o] then
table.remove(myFuncs, i)
end
end
end
This is if your file doesn't return anything and declares its functions as globals.
If the file declares them as local and then returns a table containing them, just use the first piece of code replacing _G with that returned table.
This is not likely to be possible without syntax or bytecode analysis as each function definition is an assignment (just has different forms in your examples). See the bytecode inspector and a related discussion here. For the syntax analysis you can use metalua or something like lua-loose-parser. Keep in mind that even those tools won't give you the entire list of functions as some functions may be defined dynamically using loadstring (or similar methods).
If you only have access to the result of loadfile, then you best bet is to use the bytecode analyzer.
This is possible using jit.attach in LuaJIT.
You can attach callbacks to a number of compiler events with
jit.attach. The callback can be called:
when a function has been compiled to bytecode ("bc");
when trace recording starts or stops ("trace");
as a trace is being recorded ("record");
or when a trace exits through a side exit ("texit").
http://wiki.luajit.org/JIT-Compiler-API#jit-attach
jit.attach(function(f)
local funcInfo = jit.util.funcinfo(f)
end, "bc")

How to use Eiffel functions?

So I'm just starting to learn Eiffel. One of the first exercises in the book I'm using says to make a function that does base^exp without using ^. I've copied my code below.
class
APPLICATION
inherit
ARGUMENTS
create
make
feature {NONE} -- Initialization
make
-- Run application.
do
create power(2;3)
printf("2 to the power of 3 is " + answer)
end
power(base : REAL; exp : INTEGER) : REAL
-- computers base raised to the bower of exp without using ^
local
remain : INTEGER
do
remain := exp
if remain = 0 then
result := 1
else
from
until
remain = 0
loop
result := result * result
remain := remain -1
end
end
end
end
How do I use this? Do I need it on the same level as feature{NONE}'s make? I know how I'm calling it is wrong, and I can't find anything in the chapter I just read, or online on how to pass parameters into it or how to use it's results.
There are several issues with the original code:
create is used to create an object, but you are not going to create anything, but to get a result of a computation of the function power by calling it. Therefore the keyword create is not needed.
You are using an entity answer to report the result of evaluation on a screen. However it is not declared anywhere. I believe the proper place would be a local variable declaration section.
The entity answer is not initialized to the result of the function power. This is usually done by an assignment instruction.
Feature arguments are separated by a comma, not by a semicolon.
From the original code it's unclear what is the type of the variable answer. Assuming it matches the type of the function power, before adding it to a string, it needs to be converted to a string. This is done by calling the feature out.
The standard feature for printing a string to a console is print, not printf.
Combining the critical points above, we get
make
-- Run application.
local
answer: REAL
do
answer := power(2, 3)
print ("2 to the power of 3 is " + answer.out)
end
After that the code can be compiled. Now less critical points:
It is a good style to put features to a dedicated feature clauses, so I would add a line like feature -- Basic operations before the feature power.
The implementation of the feature power has at least two problems. I'm not going to detail them here, but would give two hints instead:
by default numeric Result is initialized to 0, this needs to be taken into account for operations that use it without first assigning any other value
even though an argument base is passed to the function power it remains unused in the original version of the code

'Invalid Handle object' when using a timer inside a function in MatLab

I am using a script in MatLab that works perfectly fine by itself, but I need to make a function out of it.
The script read a .csv file, extract all values, start a timer, and at each tick displays the corresponding coordinates extracted from the .csv, resulting in a 3D animation of my graph.
What I would like is to give it the location of the .csv, so that it starts displaying the graphs for this csv.
Here is what I have come up with:
function handFig(fileLoc)
csv=csvread(fileLoc,1,0);
both = csv(:,2:19);
ax=axes;
set(ax,'NextPlot','replacechildren');
Dt=0.1; %sampling period in secs
k=1;
hp1=text(both(k,1),both(k,2),both(k,3),'thumb'); %get handle to dot object
hold on;
hp2=text(both(k,4),both(k,5),both(k,6),'index');
hp3=text(both(k,7),both(k,8),both(k,9),'middle');
hp4=text(both(k,10),both(k,11),both(k,12),'ring');
hp5=text(both(k,13),both(k,14),both(k,15),'pinky');
hp6=text(both(k,16),both(k,17),both(k,18),'HAND');
L1=plot3([both(k,1),both(k,16)],[both(k,2),both(k,17)],[both(k,3),both(k,18)]);
L2=plot3([both(k,4),both(k,16)],[both(k,5),both(k,17)],[both(k,6),both(k,18)]);
L3=plot3([both(k,7),both(k,16)],[both(k,8),both(k,17)],[both(k,9),both(k,18)]);
L4=plot3([both(k,10),both(k,16)],[both(k,11),both(k,17)],[both(k,12),both(k,18)]);
L5=plot3([both(k,13),both(k,16)],[both(k,14),both(k,17)],[both(k,15),both(k,18)]);
hold off;
t1=timer('TimerFcn','k=doPlot(hp1,hp2,hp3,hp4,hp5,hp6,L1,L2,L3,L4,L5,both,t1,k)','Period', Dt,'ExecutionMode','fixedRate');
start(t1);
end
And the doplot function used:
function k=doPlot(hp1,hp2,hp3,hp4,hp5,hp6,L1,L2,L3,L4,L5,pos,t1,k)
k=k+1;
if k<5000%length(pos)
set(hp1,'pos',[pos(k,1),pos(k,2),pos(k,3)]);
axis([0 255 0 255 0 255]);
set(hp2,'pos',[pos(k,4),pos(k,5),pos(k,6)]);
set(hp3,'pos',[pos(k,7),pos(k,8),pos(k,9)]);
set(hp4,'pos',[pos(k,10),pos(k,11),pos(k,12)]);
set(hp5,'pos',[pos(k,13),pos(k,14),pos(k,15)]);
set(hp6,'pos',[pos(k,16),pos(k,17),pos(k,18)]);
set(L1,'XData',[pos(k,1),pos(k,16)],'YData',[pos(k,2),pos(k,17)],'ZData',[pos(k,3),pos(k,18)]);
set(L2,'XData',[pos(k,4),pos(k,16)],'YData',[pos(k,5),pos(k,17)],'ZData',[pos(k,6),pos(k,18)]);
set(L3,'XData',[pos(k,7),pos(k,16)],'YData',[pos(k,8),pos(k,17)],'ZData',[pos(k,9),pos(k,18)]);
set(L4,'XData',[pos(k,10),pos(k,16)],'YData',[pos(k,11),pos(k,17)],'ZData',[pos(k,12),pos(k,18)]);
set(L5,'XData',[pos(k,13),pos(k,16)],'YData',[pos(k,14),pos(k,17)],'ZData',[pos(k,15),pos(k,18)]);
else
k=1;
set(hp1,'pos',[pos(k,1),pos(k,2),pos(k,3)]);
axis([0 255 0 255 0 255]);
set(hp2,'pos',[pos(k,4),pos(k,5),pos(k,6)]);
set(hp3,'pos',[pos(k,7),pos(k,8),pos(k,9)]);
set(hp4,'pos',[pos(k,10),pos(k,11),pos(k,12)]);
set(hp5,'pos',[pos(k,13),pos(k,14),pos(k,15)]);
set(hp6,'pos',[pos(k,16),pos(k,17),pos(k,18)]);
end
However, when I run handFig('fileName.csv'), I obtain the same error everytime:
??? Error while evaluating TimerFcn for timer 'timer-7'
Invalid handle object.
I figured that it might come from the function trying to create a new 'csv' and 'both' everytime, so I tried removing them, and feeding the function the data directly, without results.
What is exactly the problem? Is there a solution?
Thanks a lot!
I think it's because when you call doPlot in the timer for the first time, you pass in t1 as an argument, and it might not exist the first time.
Does doPlot need t1 at all? I'd suggest modifying it so it's not used, and then your call to:
t1=timer('TimerFcn','k=doPlot(hp1,hp2,hp3,hp4,hp5,hp6,L1,L2,L3,L4,L5,both,k)','Period', Dt,'ExecutionMode','fixedRate');
Note the missing t1 in the doPlot call.
Either that, or initialise your t1 before you create the timer so it has some value to pass in.
Update (as an aside, can you use pause(Dct) in a loop instead? seems easier)
Actually, now I think it's a problem of scope.
It took a bit of digging to get to this, but looking at the Matlab documentation for function callbacks, it says:
When MATLAB evaluates function handles, the same variables are in scope as when the function handle was created. (In contrast, callbacks specified as strings are evaluated in the base workspace.)
You currently give your TimerFcn argument as a string, so k=doPlot(...) is evaluated in the base workspace. If you were to go to the matlab prompt, run handFig, and then type h1, you'd get an error because h1 is not available in the global workspace -- it's hidden inside handFig.
That's the problem you're running into.
However, the workaround is to specify your function as a function handle rather than a string (it says function handles are evaluated in the scope in which they are created, ie within handFig).
Function handles to TimerFcn have to have two arguments obj and event (see Creating Callback Functions). Also, that help file says you have to put doPlot in its own m-file to have it not evaluate in the base Matlab workspace.
In addition to these two required input arguments, your callback
function can accept application-specific arguments. To receive these
input arguments, you must use a cell array when specifying the name of
the function as the value of a callback property. For more
information, see Specifying the Value of Callback Function Properties.
It goes through an example of what you have to do to get this working. Something like:
% create timer
t = timer('Period', Dt,'ExecutionMode','fixedRate');
% attach `k` to t so it can be accessed within doPlot
set(t,'UserData',k);
% specify TimerFcn and its extra arguments:
t.TimerFcn = { #doPlot, hp1, hp2, hp3, ...., both };
start(t)
Note -- the reason k is set in UserData is because it needs to be somehow saved and modified between calls to doPlot.
Then modify your doPlot to have two arguments at the beginning (which aren't used), and not accept the k argument. To extract k you do get(timer_obj,'UserData') from within doPlot:
function k=doPlot(timer_obj, event, hp1,hp2,hp3,.....)
k = get(timer_obj,'UserData');
.... % rest of code here.
% save back k so it's changed for next time!
set(timer_obj,'UserData',k);
I think that's on the right track - play around with it. I'd highly recommend the mathworks forums for this sort of thing too, those people are whizzes.
This thread from the mathworks forum was what got me started and might prove helpful to you.
Good luck!

Lua "require" with global "local"?

Clearly I have some mixed up, but I figured that by using something like this in "main.lua":
local module = require("module")
local var = "I should be global?"
printthis()
with module.lua containing something like:
function printthis()
print(var)
end
that printthis(var) would work fine, because now the module.lua code is inside main.lua, no? Instead, printthis has no idea what var is. I read it's good practice to use "local" on Lua variables when possible, but in this case, do I have to make var global or is there a way for module.lua's printthis() function to read var properly?
No. That's not at all how it works.
The Lua interpreter provides one global table, referred to as _G normally, unless you're doing something kinky.
function printthis()
print(var)
end
This translates to, in reality
_G.printthis = function()
_G.print(_G.var);
end
And your code in main is equal to
local module = _G.require("module")
local var = "I should be global?"
_G.printthis()
But when you call printthis- where did _G.var get set? Nowhere. So the variable is nil, like all other accesses to a table where there is nothing at that key.
It might be inconvenient, but it's a much better idea in the long run to pass arguments than to set global variables instead. Once you come to change anything about the program, it's going to be completely impossible to make any changes, as the logic has no structure and you have no idea what happens where without reading every single line of code and understanding it at once. In addition, you can only use each key in one place, because it's a global table- so I sure hope nobody else wanted to use "var" as a variable name and you don't mind your code silently failing because you got a global name wrong.
The other two answers gloss over an important thing: lexical scoping.
This means, roughly, that code can access local variables that are defined where the code is defined. That probably sounds vague, so I'll give an example:
local cheese = 'sandwich'
print(cheese) -- prints sandwich
do -- this begins an anonymous block
local cheese = 22
print(cheese) -- prints 22
end
print(cheese) -- prints sandwich
So what we have here is two different variables: the outer one is "shadowed" by the inner one.
Now, onto functions:
do
local hotdog = 'hot'
function nonsense()
print(hotdog)
end
end
print(hotdog) -- prints nil, since there is no variable called hotdog here
nonsense() -- prints hot
Functions can see the local variables from where they are defined, not from where they are called. This is very important and very useful, once you get the hang of it.
I'm no expert in lua, but shouldn't var be passed as variable. Something like this:
function printthis(var)
print(var)
end
You're missing your var in function header. And you're passing your var in main.lua as an argument to printthis() function.