I am new to Lua, and I downloaded and wanted to use the class.lua file from this link.
However, when I attempt to call the Board:addSign function from anywhere, no matter what I do, the arguments passed are the value of the place variable and nil instead of the values of the sign and place variables. How would I go around fixing that?
Here's my code, both main and the class itself.
Class = require 'class'
require 'Board'
board = Board()
for place = 1, 9 do
print('Input sign: ')
sign = io.read()
board.addSign(sign, place)
end
Board = Class{}
function Board:init()
array = {}
for n = 1, 9 do
array[n] = ' '
end
--
self.array = array
end
function Board:addSign(sign, place)
print(sign) -- outputs whatever I passed as place
print(place) -- outputs nil no matter what
self.array[place] = sign -- crashes here since place is nil
end
Use board:addSign instead of board.addSign.
function Board:addSign(sign, place) end
is syntactic sugar for
function Board.addSign(self, sign, place) end
This allows you to do things like self.array[place] = sign inside that function.
So you defined a function with 3 parameters but you only provide 2 when calling it.
board.addSign(sign, place)
Inside your function that basically results in
local self = sign
local sign = place
local place = nil
So either call Board:addSign(sign, place) or Board.addSign(Board, sign, place)
Related
Let's say, for instance, I have two classes: A & B. I have set B as the handle class and would like a property from A to instantiate this class (i.e. B).
Therefore, I have done something like this in class A:
% Constructor
function a = A()
a.objB = B(); % This works fine
...
for i = 1:10
a.var(i) = B(); % This causes an error to occur
end
end
The error is listed below:
"Error using double Conversion to double from B is not possible.
The code snippet inside the for loop seems to work if I change a.var(i) = B(); to var(i) = B();.
Do you have any idea why this is?
Your .var field is probably initialized to a double when you make the assignment (maybe to []). Using a.var(i) = xxx cannot change the type of a.var.
Try resetting the value the first time it is used. EG
for i = 1:10
if i == 1
a.var = B(); % Overwrite the existing value
else
a.var(i) = B(); % Now append to that value
end
end
This will cause your a.var field to be reallocated every loop. Pre-allocated your array will make everything go much faster. The easiest way to pre-allocate is actually to just loop backwards, like this:
for i = 10:-1:1
if i == 10
a.var = B(); % Overwrite the existing value, allocated room for 10 elements
else
a.var(i) = B(); % Assign each element in turn, 9 through 1
end
end
As a homework assignment, I'm writing a code that uses the bisection method to calculate the root of a function with one variable within a range. I created a user function that does the calculations, but one of the inputs of the function is supposed to be "fun" which is supposed to be set equal to the function.
Here is my code, before I go on:
function [ Ts ] = BisectionRoot( fun,a,b,TolMax )
%This function finds the value of Ts by finding the root of a given function within a given range to a given
%tolerance, using the Bisection Method.
Fa = fun(a);
Fb = fun(b);
if Fa * Fb > 0
disp('Error: The function has no roots in between the given bounds')
else
xNS = (a + b)/2;
toli = abs((b-a)/2);
FxNS = fun(xns);
if FxNS == 0
Ts = xNS;
break
end
if toli , TolMax
Ts = xNS;
break
end
if fun(a) * FxNS < 0
b = xNS;
else
a = xNS;
end
end
Ts
end
The input arguments are defined by our teacher, so I can't mess with them. We're supposed to set those variables in the command window before running the function. That way, we can use the program later on for other things. (Even though I think fzero() can be used to do this)
My problem is that I'm not sure how to set fun to something, and then use that in a way that I can do fun(a) or fun(b). In our book they do something they call defining f(x) as an anonymous function. They do this for an example problem:
F = # (x) 8-4.5*(x-sin(x))
But when I try doing that, I get the error, Error: Unexpected MATLAB operator.
If you guys want to try running the program to test your solutions before posting (hopefully my program works!) you can use these variables from an example in the book:
fun = 8 - 4.5*(x - sin(x))
a = 2
b = 3
TolMax = .001
The answer the get in the book for using those is 2.430664.
I'm sure the answer to this is incredibly easy and straightforward, but for some reason, I can't find a way to do it! Thank you for your help.
To get you going, it looks like your example is missing some syntax. Instead of either of these (from your question):
fun = 8 - 4.5*(x - sin(x)) % Missing function handle declaration symbol "#"
F = # (x) 8-4.5*(x-sin9(x)) %Unless you have defined it, there is no function "sin9"
Use
fun = #(x) 8 - 4.5*(x - sin(x))
Then you would call your function like this:
fun = #(x) 8 - 4.5*(x - sin(x));
a = 2;
b = 3;
TolMax = .001;
root = BisectionRoot( fun,a,b,TolMax );
To debug (which you will need to do), use the debugger.
The command dbstop if error stops execution and opens the file at the point of the problem, letting you examine the variable values and function stack.
Clicking on the "-" marks in the editor creates a break point, forcing the function to pause execution at that point, again so that you can examine the contents. Note that you can step through the code line by line using the debug buttons at the top of the editor.
dbquit quits debug mode
dbclear all clears all break points
I have two functions:
function [] = func_one()
S.pb = uicontrol('style','push','unit','pix','posit',[20 20 260 30],
'string','Print Choices','callback',{#func_two,S});
and I have the second function:
function [a] = func_two(varargin)
a = 'alon';
end
I want func_one to return the variable a of func_two. How can I do that please?
I tried:
function [a] = func_one()
But I guess I have to do something with 'callback',{#func_two,S})
Thank you all!
If, as you say, you want func_one to return the value a in func_two then the easiest way to do this without using a callback is:
function [a] = func_one()
S.pb = uicontrol('style','push','unit','pix','posit',[20 20 260 30],
'string','Print Choices');
a = func_two()
The above will allow you to say run a=func_one and a will be the string 'alon'.
If you really really want func_two() to be a callback of your pushbutton, and you want a='alon' to be assigned in the workspace of func_one (the function that calls func_two) then put this in func_two
assignin('caller','a',a)
And if neither is what you want, then maybe you can indicate why you want func_one to return what func_two returns - like the exact interaction you are hoping to have with your GUI and how it differs from what you're actually experiencing.
If you are designing a GUI programmatically, I suggest you use nested functions to share data. Example:
function IncrementExample()
x = 0;
uicontrol('Style','pushbutton', 'String','(0)', ...
'Callback',#callback);
function callback(o,e)
%# you can access the variable x in here
x = x + 1;
%# update button text
set(o, 'String',sprintf('(%d)',x))
drawnow
end
end
I have caught myself in a issue, I know its not that difficult but I couldnt figure out how to implement it. I have an m file that looks like
clear;
PVinv.m_SwF=20e3
for m=1:1:70;
PVinv.m_SwF=PVinv.m_SwF+1e3;
Lmin = PVinv.InductanceDimens();
Wa_Ac = PVinv.CoreSizeModel();
PVinv.CoreSelect(Wa_Ac);
[loss_ind_core,loss_ind_copper] = PVinv.InductorLossModel(PVinv.m_L_Selected);
Total_Inductor_Loss=loss_ind_core+loss_ind_copper
plot(PVinv.m_SwF,Total_Inductor_Loss,'--gs');
hold on
xlim([10e3 90e3])
set(gca,'XTickLabel',{'10';'20';'30';'40';'50';'60';'70';'80';'90'})
grid on
xlabel('Switching Frequency [kHz]');
ylabel('Power loss [W]');
end
And the function that is of interest is CoreSelect(Wa_Ac)
function obj = CoreSelect(obj, WaAc)
obj.m_Core_Available= obj.m_Core_List(i);
obj.m_L_Selected.m_Core = obj.m_Core_Available;
end
I want to change the value of i from obj.m_Core_List(1) to obj.m_Core_List(27) within that for loop of main m file. How can I get the value of the function coreselect when I call it in main m file
For eg for m=1 to 70 I want the function to take the value of i=1 then execute till plot command and then same with but i=2 and so on
Any suggestion would be really helpful
I'm not sure I understand your question perfectly, but I think you want to pass an index i to the CoreSelect function, and loop i from 1 to 27 outside of the function. Try this:
function obj = CoreSelect(obj, WaAc, i)
...
end
for i=1:27,
PVInv.CoreSelect(WaAc,i);
end
I'm new to Lua, so (naturally) I got stuck at the first thing I tried to program. I'm working with an example script provided with the Corona Developer package. Here's a simplified version of the function (irrelevant material removed) I'm trying to call:
function new( imageSet, slideBackground, top, bottom )
function g:jumpToImage(num)
print(num)
local i = 0
print("jumpToImage")
print("#images", #images)
for i = 1, #images do
if i < num then
images[i].x = -screenW*.5;
elseif i > num then
images[i].x = screenW*1.5 + pad
else
images[i].x = screenW*.5 - pad
end
end
imgNum = num
initImage(imgNum)
end
end
If I try to call that function like this:
local test = slideView.new( myImages )
test.jumpToImage(2)
I get this error:
attempt to compare number with nil
at line 225. It would seem that "num" is not getting passed into the function. Why is this?
Where are you declaring g? You're adding a method to g, which doesn't exist (as a local). Then you're never returning g either. But most likely those were just copying errors or something. The real error is probably the notation that you're using to call test:jumpToImage.
You declare g:jumpToImage(num). That colon there means that the first argument should be treated as self. So really, your function is g.jumpToImage(self, num)
Later, you call it as test.jumpToImage(2). That makes the actual arguments of self be 2 and num be nil. What you want to do is test:jumpToImage(2). The colon there makes the expression expand to test.jumpToImage(test, 2)
Take a look at this page for an explanation of Lua's : syntax.