I am trying to see if I can simplify input by using a function that produces more than one output for use with another function. Is there any way I can do this? Do I HAVE to make a function to return single variables for each input?
--here is a snippet of what im trying to do (for a game)
--Result is the same for game environment and lua demo.
en = {
box ={x=1,y=2,w=3}
}
sw = {
box = {x=1,y=2,w=3}
}
function en.getbox()
return en.box.x,en.box.y,en.box.w,en.box.w
end
function sw.getbox()
return sw.box.x,sw.box.y,sw.box.w,sw.box.w
end
function sw.getvis()
return true
end
function CheckCollision(x1,y1,w1,h1, x2,y2,w2,h2)
return x1 < x2+w2 and
x2 < x1+w1 and
y1 < y2+h2 and
y2 < y1+h1
end
if CheckCollision(en.getbox(),sw.getbox()) == true then
if sw.getvis() == true then
en.alive = false
end
end
print(tostring(en.alive))
I am expecting the enemy (en) to die (en.alive = false) but I am getting the error: input:25: attempt to perform arithmetic on a nil value (local 'w2')
You can find an explaination for the issue you are seeing here: Programming in Lua: 5.1 – Multiple Results
I suggest you read the whole page but here is a relevant section
A function call that is not the last element in the list always produces one result:
x,y = foo2(), 20 -- x='a', y=20
x,y = foo0(), 20, 30 -- x=nil, y=20, 30 is discarded
I suggest the following changes to get your code working. wrap your output from getbox into a table with clear keys that make it easy to understand.
function en.getbox()
return {
x = en.box.x,
y = en.box.y,
w = en.box.w,
h = en.box.w
}
end
function sw.getbox()
return {
x = sw.box.x,
y = sw.box.y,
w = sw.box.w,
h = sw.box.w
}
end
function CheckCollision(o1, o2)
return o1.x < o2.x + o2.w and
o2.x < o1.x + o1.w and
o1.y < o2.y + o2.h and
o2.y < o1.y + o1.h
end
Alternatively you can wrap the output of getbox "on the fly" like:
function CheckCollision(o1, o2)
return o1[1] < o2[1] + o2[3] and
o2[1] < o1[1] + o1[3] and
o1[2] < o2[2] + o2[4] and
o2[2] < o1[2] + o1[4]
end
if CheckCollision({en.getbox()}, {sw.getbox()}) == true then
if sw.getvis() == true then
en.alive = false
end
end
I do strongly encourage the first option over the last. The last option leads to code that is harder to follow and should be accompanied by clear comments explaining it.
When the below function is executed, I get the following error message "Output argument "max_idx" (and maybe others) not assigned during call to "find_node"."
I think the problem is in the fact that some output is produced after recursive loop. How can I solve this?
function max_idx = find_node(wt)
persistent all_idx_max;
node_degree=sum(wt,2);
maxval = max(node_degree);
all_nodes_with_max_val = ismember(node_degree,maxval);
idx_max = find(all_nodes_with_max_val);
if isempty(all_idx_max)
all_idx_max=1:8;
end
if size(idx_max,1)==3
max_idx=all_idx_max(idx_max(1))
elseif size(idx_max,1)>1
all_idx_max=idx_max;
find_node(wt(idx_max,idx_max)); <--problem happens in this path
else
max_idx=all_idx_max(idx_max)
end
I forgot to add output to the recursive part
function max_idx = find_node(wt)
persistent all_idx_max;
node_degree=sum(wt,2);
maxval = max(node_degree);
all_nodes_with_max_val = ismember(node_degree,maxval);
idx_max = find(all_nodes_with_max_val);
if isempty(all_idx_max)
all_idx_max=1:8;
end
if size(idx_max,1)==3
max_idx=all_idx_max(idx_max(1))
elseif size(idx_max,1)>1
all_idx_max=idx_max;
***max_idx =*** find_node(wt(idx_max,idx_max)); <--problem happens in this path
else
max_idx=all_idx_max(idx_max)
end
It is very convenient to use Tasks
to express a lazy collection / a generator.
Eg:
function fib()
Task() do
prev_prev = 0
prev = 1
produce(prev)
while true
cur = prev_prev + prev
produce(cur)
prev_prev = prev
prev = cur
end
end
end
collect(take(fib(), 10))
Output:
10-element Array{Int64,1}:
1
1
2
3
5
8
13
21
34
However, they do not follow good iterator conventions at all.
They are as badly behaved as they can be
They do not use the returned state state
start(fib()) == nothing #It has no state
So they are instead mutating the iterator object itself.
An proper iterator uses its state, rather than ever mutating itself, so they multiple callers can iterate it at once.
Creating that state with start, and advancing it during next.
Debate-ably, that state should be immutable with next returning a new state, so that can be trivially teeed. (On the other hand, allocating new memory -- though on the stack)
Further-more, the hidden state, it not advanced during next.
The following does not work:
#show ff = fib()
#show state = start(ff)
#show next(ff, state)
Output:
ff = fib() = Task (runnable) #0x00007fa544c12230
state = start(ff) = nothing
next(ff,state) = (nothing,nothing)
Instead the hidden state is advanced during done:
The following works:
#show ff = fib()
#show state = start(ff)
#show done(ff,state)
#show next(ff, state)
Output:
ff = fib() = Task (runnable) #0x00007fa544c12230
state = start(ff) = nothing
done(ff,state) = false
next(ff,state) = (1,nothing)
Advancing state during done isn't the worst thing in the world.
After all, it is often the case that it is hard to know when you are done, without going to try and find the next state. One would hope done would always be called before next.
Still it is not great, since the following happens:
ff = fib()
state = start(ff)
done(ff,state)
done(ff,state)
done(ff,state)
done(ff,state)
done(ff,state)
done(ff,state)
#show next(ff, state)
Output:
next(ff,state) = (8,nothing)
Which is really now what you expect. It is reasonably to assume that done is safe to call multiple times.
Basically Tasks make poor iterators. In many cases they are not compatible with other code that expects an iterator. (In many they are, but it is hard to tell which from which).
This is because Tasks are not really for use as iterators, in these "generator" functions. They are intended for low-level control flow.
And are optimized as such.
So what is the better way?
Writing an iterator for fib isn't too bad:
immutable Fib end
immutable FibState
prev::Int
prevprev::Int
end
Base.start(::Fib) = FibState(0,1)
Base.done(::Fib, ::FibState) = false
function Base.next(::Fib, s::FibState)
cur = s.prev + s.prevprev
ns = FibState(cur, s.prev)
cur, ns
end
Base.iteratoreltype(::Type{Fib}) = Base.HasEltype()
Base.eltype(::Type{Fib}) = Int
Base.iteratorsize(::Type{Fib}) = Base.IsInfinite()
But is is a bit less intuitive.
For more complex functions, it is much less nice.
So my question is:
What is a better way to have something that works like as Task does, as a way to buildup a iterator from a single function, but that is well behaved?
I would not be surprised if someone has already written a package with a macro to solve this.
The current iterator interface for Tasks is fairly simple:
# in share/julia/base/task.jl
275 start(t::Task) = nothing
276 function done(t::Task, val)
277 t.result = consume(t)
278 istaskdone(t)
279 end
280 next(t::Task, val) = (t.result, nothing)
Not sure why the devs chose to put the consumption step in the done function rather than the next function. This is what is producing your weird side-effect. To me it sounds much more straightforward to implement the interface like this:
import Base.start; function Base.start(t::Task) return t end
import Base.next; function Base.next(t::Task, s::Task) return consume(s), s end
import Base.done; function Base.done(t::Task, s::Task) istaskdone(s) end
Therefore, this is what I would propose as the answer to your question.
I think this simpler implementation is a lot more meaningful, fulfils your criteria above, and even has the desired outcome of outputting a meaningful state: the Task itself! (which you're allowed to "inspect" if you really want to, as long as that doesn't involve consumption :p ).
However, there are certain caveats:
Caveat 1: The task is REQUIRED to have a return value, signifying the final element in the iteration, otherwise "unexpected" behaviour might occur.
I'm assuming the devs chose the first approach to avoid exactly this kind of "unintended" output; however I believe this should have actually been the expected behaviour! A task expected to be used as an iterator should be expected to define an appropriate iteration endpoint (by means of a clear return value) by design!
Example 1: The wrong way to do it
julia> t = Task() do; for i in 1:10; produce(i); end; end;
julia> collect(t) |> show
Any[1,2,3,4,5,6,7,8,9,10,nothing] # last item is a return value of nothing
# correponding to the "return value" of the
# for loop statement, which is 'nothing'.
# Presumably not the intended output!
Example 2: Another wrong way to do it
julia> t = Task() do; produce(1); produce(2); produce(3); produce(4); end;
julia> collect(t) |> show
Any[1,2,3,4,()] # last item is the return value of the produce statement,
# which returns any items passed to it by the last
# 'consume' call; in this case an empty tuple.
# Presumably not the intended output!
Example 3: The (in my humble opinion) right way to do it!.
julia> t = Task() do; produce(1); produce(2); produce(3); return 4; end;
julia> collect(t) |> show
[1,2,3,4] # An appropriate return value ending the Task function ensures an
# appropriate final value for the iteration, as intended.
Caveat 2: The task should not be modified / consumed further inside the iteration (a common requirement with iterators in general), except in the understanding that this intentionally causes a 'skip' in the iteration (which would be a hack at best, and presumably not advisable).
Example:
julia> t = Task() do; produce(1); produce(2); produce(3); return 4; end;
julia> for i in t; show(consume(t)); end
24
More Subtle example:
julia> t = Task() do; produce(1); produce(2); produce(3); return 4; end;
julia> for i in t # collecting i is a consumption event
for j in t # collecting j is *also* a consumption event
show(j)
end
end # at the end of this loop, i = 1, and j = 4
234
Caveat 3: With this scheme it is expected behaviour that you can 'continue where you left off'. e.g.
julia> t = Task() do; produce(1); produce(2); produce(3); return 4; end;
julia> take(t, 2) |> collect |> show
[1,2]
julia> take(t, 2) |> collect |> show
[3,4]
However, if one would prefer the iterator to always start from the pre-consumption state of a task, the start function could be modified to achieve this:
import Base.start; function Base.start(t::Task) return Task(t.code) end;
import Base.next; function Base.next(t::Task, s::Task) consume(s), s end;
import Base.done; function Base.done(t::Task, s::Task) istaskdone(s) end;
julia> for i in t
for j in t
show(j)
end
end # at the end of this loop, i = 4, and j = 4 independently
1234123412341234
Interestingly, note how this variant would affect the 'inner consumption' scenario from 'caveat 2':
julia> t = Task() do; produce(1); produce(2); produce(3); return 4; end;
julia> for i in t; show(consume(t)); end
1234
julia> for i in t; show(consume(t)); end
4444
See if you can spot why this makes sense! :)
Having said all this, there is a philosophical point about whether it even matters that the way a Task behaves with the start, next, and done commands matters at all, in that, these functions are considered "an informal interface": i.e. they are supposed to be "under the hood" functions, not intended to be called manually.
Therefore, as long as they do their job and return the expected iteration values, you shouldn't care too much about how they do it under the hood, even if technically they don't quite follow the 'spec' while doing so, since you were never supposed to be calling them manually in the first place.
How about the following (uses fib defined in OP):
type NewTask
t::Task
end
import Base: start,done,next,iteratorsize,iteratoreltype
start(t::NewTask) = istaskdone(t.t)?nothing:consume(t.t)
next(t::NewTask,state) = (state==nothing || istaskdone(t.t)) ?
(state,nothing) : (state,consume(t.t))
done(t::NewTask,state) = state==nothing
iteratorsize(::Type{NewTask}) = Base.SizeUnknown()
iteratoreltype(::Type{NewTask}) = Base.EltypeUnknown()
function fib()
Task() do
prev_prev = 0
prev = 1
produce(prev)
while true
cur = prev_prev + prev
produce(cur)
prev_prev = prev
prev = cur
end
end
end
nt = NewTask(fib())
take(nt,10)|>collect
This is a good question, and is possibly better suited to the Julia list (now on Discourse platform). In any case, using defined NewTask an improved answer to a recent StackOverflow question is possible. See: https://stackoverflow.com/a/41068765/3580870
I have a problem with a function in matlab. This specific function is for filtering light signals. As you can see below I added the coding I’ve used in the function and in the while loop itself. The code is written for a NXT Lego robot.
Is there any tip how to get the count variable ( i = i + 1 ) to work in the function, so we can plot Light(i)? Because we’re getting a bunch of error messages when we try different codes to make it work.
function [light] = filter_func( i)
lightI(i) = GetLight(SENSOR_3);
if i==1
light(i)=lightI(i)
elseif i==2
light(i) = 0.55*lightI(i) + 0.45*lightI(i-1)
else
light(i) = 0.4*lightI(i) + 0.3*lightI(i-1) + 0.3*lightI(i-2);
end
end
i=1
while true
lightI(i) = GetLight(SENSOR_3); % Get’s a lightvalue between 0 and 1024.
if i>2
light =filter_func(i)
light=round(light);
else
light(i) = GetLight(SENSOR_3);;
end
i=1+i
plot(light(end-90:end), 'r-');
title('Lightvalue')
axis([0 100 0 1023]) ;
end
You probably mainly get errors because you are not allowed to mix script and functions like this in MATLAB (like you are in Python).
Your filter function is only used when i>2 so why are you doing the first 2 tests? It seems like you want lightI as a global variable, but that is not what you have done. The lightI inside the function is not the same as the one in the while loop.
Since your while loop runs forever, maybe you don't need to worry about updating the plot the first two times. In that case you can do this:
filter = [0.4 0.3 0.3]';
latest_filtered_light = nan(90,1);
lightI = [];
p = plot(latest_filtered_light, 'r-');
title('Lightvalue')
axis([0 100 0 1023]) ;
while True
lightI(end+1,1) = rand*1024; % Get’s a lightvalue between 0 and 1024.
if i>=3
new_val = lightI(end-2:end,1)'*filter;
latest_filtered_light = [latest_filtered_light(2:end);...
new_val];
set(p, 'ydata', latest_filtered_light)
drawnow
end
end
I think it is an important point to not call plot every time - at least if you are the least concerned about performance.
I've been looking around and I have not been able to find anything that has worked for me. I'm starting to learn more Lua and to start off I'm making a simple calculator. I was able to get each individual operation onto separate programs, but when I try to combine them I just can't get it to work. My script as it is now is
require "io"
require "operations.lua"
do
print ("Please enter the first number in your problem.")
x = io.read()
print ("Please enter the second number in your problem.")
y = io.read()
print ("Please choose the operation you wish to perform.")
print ("Use 1 for addition, 2 for subtraction, 3 for multiplication, and 4 for division.")
op = io.read()
op = 1 then
function addition
op = 2 then
function subtraction
op = 3 then
function multiplication
op = 4 then
function division
print (answer)
io.read()
end
and my operations.lua script is
function addition
return answer = x+y
end
function subtraction
return answer = x-y
end
function multiplication
return answer = x*y
end
function division
return answer = x/y
end
I've tried using
if op = 1 then
answer = x+y
print(answer)
if op = 2 then
answer = x-y
print(answer)
and I did that completing each operation. But it doesn't work. I can't even get the error code that it's returning because it closes so fast. What should I do?
In your example, make these changes: You require operations.lua without the extension. Include parameters in your operations function definitions. Return the operation expression directly versus returning a statement like answer = x+y.
All together:
Code for operations.lua
function addition(x,y)
return x + y
end
--more functions go here...
function division(x,y)
return x / y
end
Code for your hosting Lua script:
require "operations"
result = addition(5,7)
print(result)
result = division(9,3)
print(result)
Once you get that working, try re-adding your io logic.
Keep in mind that as it's coded, your functions will be defined globally. To avoid polluting the global table, consider defining operations.lua as a module. Take a look at the lua-users.org Modules Tutorial.
The right if-then-else syntax:
if op==1 then
answer = a+b
elseif op==2 then
answer = a*b
end
print(answer)
After: please check the correct function-declaration syntax.
After: return answer=x+y is incorrect. If you want set answer's value, set without return. If you want return the sum, please use return x+y.
And I think you should check Programming in Lua.
First of all, learn to use the command line so you can see the errors (on Windows that would be cmd.exe).
Second, change the second line to require("operations"). The way you did it the interpreter expects a directory operations with an underlying script lua.lua.