I am making a program in Lua that has a large amount of checkboxes. Each checkbox is ID-ed from 1 to 100 in the order they appear. When a checkbox is checked, a table saves the checkbox ID and sorts it, and when it is unchecked, the table is searched for that checkbox ID and then removes it if it finds it and then sorts the table again.
However, I am having problems with the first value not removing itself. It will get removed if I check an earlier ID value and then uncheck it, but not if I try unchecking it first.
Here is the code:
switchCounter = 0
switchID = {}
--if checkbox-is-checked then
switchID[switchCounter] = checkbox.id
switchCounter = switchCounter + 1
table.sort(switchID)
--elseif checkbox-is-unchecked then
for p = 0, #switchID do
if switchID[p] == checkbox.id then
table.remove(switchID, p)
end
end
switchCounter = #switchID+1
table.sort(switchID)
The table is not altered or touched after this point (yet). It works perfectly as long as it is not the first value I am trying to remove, upon which nothing happens.
This code is utilizing the Corona SDK if that is relevant to answering.
You're confusing Lua by starting your table index at 0. In Lua, tables are 1-indexed, unlike what you're used to from most programming languages. Unfortunately, most of this code actually still works even though you're using the wrong index range. However, when you call table.remove on the first element, since your first element has index 0, you'll end up calling table.remove(switchID, 0), at which point Lua looks at you with a raised eyebrow and proceeds to do...absolutely nothing. 0 isn't a valid table index to Lua, so it doesn't remove your first element.
Change your indices to start at 1 and all should be well:
switchCounter = 1
switchID = {}
--if checkbox-is-checked then
switchID[switchCounter] = checkbox.id
switchCounter = switchCounter + 1
table.sort(switchID)
--elseif checkbox-is-unchecked then
for p = 1, #switchID do
if switchID[p] == checkbox.id then
table.remove(switchID, p)
end
end
switchCounter = #switchID+1
table.sort(switchID)
EDIT: See nobody's excellent remarks below for better information about Lua's stance on indexing.
Related
I want to calculate the percent change between periods of each element in the "features" array (simply using the array as a grouping of financial time series data to report on). However the way the script is working now, it seems that it wants to calculate the percent change between each element in the array and not FOR each element in the array.
I don't think I've done anything wrong here in how I reference the array elements but I get the feeling there's some sort of 'under the hood' concept about how variables are processed by TV that is causing this issue.
//#version=4
study("My Script")
pct_change(source, period) =>
now = source
then = source[period]
missing_now = na(now)
missing_then = na(then)
if not missing_now and not missing_then
(now - then) / abs(then)
else
missing_now ? 0 : 1
evaluate(sources) =>
s = array.size(sources)
bar_changes = array.new_float()
for i = 0 to 99999
if i < s
source = array.get(sources, i)
array.push(bar_changes, pct_change(source, 1))
continue
else
break
bar_changes
features = array.new_float()
array.push(features, open)
array.push(features, high)
array.push(features, close)
bar_changes = evaluate(features)
plot(pct_change(open, 1))
plot(array.get(bar_changes, 0))
plot(pct_change(high, 1), color=color.aqua)
plot(array.get(bar_changes, 1), color=color.aqua)
plot(pct_change(close, 1), color=color.red)
plot(array.get(bar_changes, 2), color=color.red)
I think you have come across the same problem I'm faced with, and it relates to using history referencing operator [] in connection with setting array element values.
I've boiled it down to a very simple script illustrating the problem
here.
In essence what you are doing in your code is passing array element to a pct_change() function, which uses [] operator, and then use returned result in array.push() to set array element value.
I've experienced weird results when I was trying to experiment with arrays in my scripts as soon as they've been introduced, so I started to dig in order to find the root of the problem. And it came down to the script referenced in the link above. So far I believe that Pine Script still has some bugs when it comes to arrays so we just have to wait until they'll be fixed.
I have recently switched from STATA to R, and am stuck on some mechanisms of looping (I know looping is considered bad form here in lieu of writing a function, but my feeling is if I can figure out how to get a loop to do this, I can apply that to a function).
I regularly want to execute a call on nested variable name fragments. I cant get R to let me insert variable name fragments, either within a loop or a function; help! and while the variable name here is a number, often its a word or word fragment (a list of non-numeric, non-sequential characters, so i would like to be sure that whatever help i get isn't necessarily specific to inserting numbers!
here is an example. i would like to create an indicator variable for a patient having received a specific intervention in my dataframe called xdata. i have created several (8) intervention variables, and for each, a list of the specific patients (identified through the variable named id) who should be flagged as having received that intervention.
xdata <- data.frame(intervention1 = 0,
intervention2 = 0,
intervention3 = 0,
intervention4 = 0,
intervention5 = 0,
intervention6 = 0,
intervention7 = 0,
intervention8 = 0,
id = 1:2000)
ids <- list(dx1 = c(86, 1486, 1451),
dx2 = c(328, 1277,1458),
dx3 = c(535,1569,689),
dx4 = c(488,1335),
dx5 = c(1210,1425,932,1451,30,270,347,418,709,801,1278),
dx6 = c(282,721,749,1134),
dx7 = c(932,43,148,158,1441),
dx8 = c(932,801,1258))
for (i in 1:8) {
for (j in 1:length(ids[[i]]) {
parse(paste("xdata$intervention",i,"[xdata$id==",ids[[i]][j],"]<- 1"))
}
}
What I am hoping for the loop to do is to carry out in sequence this line of code "xdata$intervention",i,"[xdata$id==",ids[[i]][j],"]<- 1" for each iteration of a particular intervention and list of patients, as applicable. I want the loop to do this:
xdata$intervention1[xdata$id==86]<- 1
xdata$intervention1[xdata$id==1486]<- 1
xdata$intervention1[xdata$id==1451]<- 1
xdata$intervention2[xdata$id==328]<- 1
xdata$intervention2[xdata$id==1277]<- 1
xdata$intervention2[xdata$id==1458]<- 1
...
xdata$intervention8[xdata$id==932]<- 1
xdata$intervention8[xdata$id==801]<- 1
xdata$intervention8[xdata$id==1258]<- 1
Disclaimer/apology-- I have looked and looked for help with this in S.O., my guess is that the answer is out there, but one problem with being a newbie is that I have a hard time even knowing how to frame my question so the right answers will come up! If this is a duplicate I'm sorry; it was not for lack of trying that I didn't find it!
Hi I'm working on a macro in VBA for excel. I have a nested for loop in my code as seen below. The second loop does not run; even a MsgBox() command within the second loop doesn't result in any action and the program just seems to skip over the nested loop with no reported errors.
In plain English this nested loop should:
1) Take the string from the i entry in the array categories_string (first for loop).
2) iterate through the 300+ rows in column "AE" in the excel file (second for loop, "length" is the length of the column of data in "AE")
3) look for string matches and add 1 to the corresponding entry in the categories_value array which is populated with variables set to 0 (the if statement).
For i = LBound(categories_string) To UBound(categories_string)
For p = 1 To p = length
If Worksheets("sheet1").Cells(p + 2, "AE").Value = categories_string(i) Then
categories_value(i) = categories_value(i) + 1
End If
Next
Next
Change
For p = 1 To p = length
to
For p = 1 To length
Should fix you right up.
You may want to consider Scott Cranner's comment as well, especially if your categories_string is large and length is large. Or, just do it for the practice
The main issue from the below picture is that when "check Result end" statement is added it automatically fails and displays "CHECK_VIOLATION" error in debugger.
Also, the HASH_TABLE doesn't store all items given to it but I fixed that by switching HASH_TABLE[G, INTEGER] instead of using the current HASH_TABLE[INTEGER, G]
My main problem is why does it throw Check_violation always and fail whenever a "check result end" statement is seen? Maybe the HAS[...] function is bad?
Currently any test case feature with "check result end" makes it false and throw CHECK_VILOATION
code:
class
MY_BAG[G -> {HASHABLE, COMPARABLE}]
inherit
ADT_BAG[G]
create
make_empty, make_from_tupled_array
convert
make_from_tupled_array ({ARRAY [TUPLE [G, INTEGER]]})
feature{NONE} -- creation
make_empty
do
create table.make(1)
end
make_from_tupled_array (a_array: ARRAY [TUPLE [x: G; y: INTEGER]])
require else
non_empty: a_array.count >= 0
nonnegative: is_nonnegative(a_array)
do
create table.make(a_array.count)
across a_array as a
loop
table.force (a.item.y, a.item.x)
end
end
feature -- attributes
table: HASH_TABLE[INTEGER, G]
counter: INTEGER
testing code:
t6: BOOLEAN
local
bag: MY_BAG [STRING]
do
comment ("t6:repeated elements in contruction")
bag := <<["foo",4], ["bar",3], ["foo",2], ["bar",0]>> -- test passes
Result := bag ["foo"] = 5 -- test passes
check Result end -- test fails (really weird but as soon as check statement comes it fails)
Result := bag ["bar"] = 3
check Result end
Result := bag ["baz"] = 0
end
Most probably ADT_BAG stands for an abstraction of a multiset (also called a bag) that allows to keep items and to tell how many items equal to the given one are there (unlike a set, where at most one item may be present). If so, it is correct to use HASH_TABLE [INTEGER, G] as a storage. Then its keys are the elements and its items are the elements numbers.
So, if we add the same element multiple times, its count should be increased. In the initialization line we add 4 elements of "foo", 3 elements of "bar", 2 elements of "foo" again, and 0 elements of "bar" again. As a result we should have a bag with 6 elements of "foo" and 3 elements of "bar". Also there are no elements "baz".
According to this analysis, either initialization is incorrect (numbers for "foo" should be different) or the comparison should be done for 6 instead of 5.
As to the implementation of the class MY_BAG the idea would be to have a feature add (or whatever name specified in the interface of ADT_BAG) that
Checks if there are items with the given key.
If there are none, adds the new element with the given count.
Otherwise, replaces the current element count with the sum of the current element count and the given element count.
For simplicity the initialization procedure would use this feature to add new items instead of storing items in the hash table directly to process repeated items correctly.
I'm a beginner Lua user, I attempt to create something in Lua by using Love2D libraries.
In the loading function I create a table and upload it with elements (which are numbers) for use it later as a multidimensional array.
function love.load()
Maximum_X = 32
Maximum_Y = 16
Start_X = 64
Start_Y = 32
MapTable = {} -- empty table
for i=1,Maximum_X*Maximum_Y do -- uploading table
table.insert(MapTable, 2)
end
end
Then I make a function that takes changes in the table. Because I'm just experimenting with tables, there's only one changed value. At least, I thought.
function KatamoriGen()
MapTable[4] = 3
end
function love.update(dt)
KatamoriGen()
end
After that, I print the elements of the table in a matrix with 32 coloumns and 16 rows. I see here that not only the 4th element of 1st row is changed, but also the 2nd element of 2nd row and 1st element of 4th row becomes 3.
It obviously means that Table[posX*posY] doesn't work neither since the result of the multiplication is a number like 4 and the operation would change every elements where
X coordinate + Y coordinate = posX*posY
is true. In the example code, the right side of this equation was 4.
A small question: why is it happening?
The main question is: how can I identify elements of MapTable exactly? How can I implement X and Y dimensions to Lua tables? to use them as two-dimensional arrays? Maybe table of tables?
EDIT: this is the drawing function:
function love.draw()
for j=1,16 do
for i=1,32 do
love.graphics.draw(Tileset[MapTable[j*Maximum_X + i]], Start_X + 32*(i-1), Start_Y + 32*(j-1))
end
end
end
Now it's clear for me that this is wrong and the right rule is MapTable[j*Maximum_X + i] but I get an error for it: "expected parameter type: expected userdata"
You can also use multi-dim tables. Something like:
local MapTable = {}
local Maximum_X, Maximum_Y = 32, 16
local Start_X, Start_Y = 64, 32
function love.load()
for y = 1,Maximum_Y do
local row = {}
for x = 1,Maximum_X do
table.insert(row,2)
end
table.insert(MapTable,row)
end
end
function love.draw()
for y,row in ipairs(MapTable) do
for x,idx in ipairs(row) do
love.graphics.draw(Tileset[idx], Start_X + 32*(x-1), Start_Y + 32*(y-1))
end
end
end
As Alex shows it, the problem was not with the way how table works, but rather that I displayed the numbers on a wrong way. Tables can be used as one-dimensional arrays, and everything fine then.
Even though it's not a solution for using them as 2-dimensional array, the main problem is solved.