Cannot index 2D array with (attempt to index field '?' (a nil value) ) - multidimensional-array

I have 2 different 2d Arrays set up in lua. The first loop
bubbleMat = {} --Set Up Table called bubbleMat
for i = 1, 10 do
bubbleMat[i] = {} --1D table with 10 components
for j = 1, 13 do
bubbleMat[i][j] = bubbleClass.new( (i*62) - 62, (j*62) - 62 ) --2D Table with 10x13 Matrix each cell given a coordinate as it is iterated through the loop
end
end
With this array i can print value of any position in the array to the console with
print(bubbleMat[x][y])
for whatever numbers of x and y
The second array for some reason does not work. The second array is as follows
bubbleMat = {} --Set Up Table called bubbleMat
for j = 1, 13 do
for i = 1, 10 do
bubbleMat[i] = {}
--bubbleMat[i][j] = {}
if j%2 == 0 then
bubbleMat[i][j] = bubbleClass.new( (i*62) - 31, (j*62) - 62 )
else
bubbleMat[i][j] = bubbleClass.new( (i*62) - 62, (j*62) - 62 )
end
end
end
print(bubbleMat)
I am unsure why I cannot index the second array
this is the following error I get in the console
attempt to index field '?' (a nil value)
Thanks in advance for any help.
Basically i want to display a grid of bubbles stored in a 2d array in the following pattern
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
as opposed to having the bubbles in the next line positioned directly underneath

Loop for j is outside and loop for i is inside. This is not necessarily false, but unusual.
However, bubbleMat[i] is initialized to {} in the innermost loop, which is clearly wrong.
Either move that initialization into the outermost loop, or use this syntax :
bubbleMat[i] = bubbleMat[i] or {}

Related

Printing vector of pair in C++

Here is the code to print the value in vector of pair
But why does it print the output mentioned below..?
#include<bits/stdc++.h>
using namespace std;
int main()
{
vector<pair<int,int>>vec(3,pair<int,int>()); // declaring the vector of pair.
for(auto x: vec)
x=make_pair(1,2); // looping through it to insert values
for(auto x:vec)
cout<<x.first<<" "<<x.second<<endl; // printing it
return 0;
}
Output :
0 0
0 0
0 0
Expected :
1 2
1 2
1 2
In your first for-loop you iterate through your vector "by value", meaning you copy the elements to auto x and afterwards set x to {1,2}, this does not change your original vector. To actually change your vector you have to iterate through it by reference:
for(auto& x: vec)
x=make_pair(1,2);

TCL recursively call procedure

I'm a beginner at TCL and while trying to build the GCD algorithm I ran into some problems I'd like some help with:
how can I call a proc inside a proc recursively like so
proc Stein_GCD { { u 0 } { v 0 } } {
if { $v == 0 } {
puts "$u\t\t$v\t\t$v"
}
if { [expr { $v % 2 } && { $u % 2 } ] == 0 } {
return [expr 2 * ${Stein_GCD 1 0} ]
}
}
set a [Stein_GCD 2 2 ]
puts $a
as you can see, I made the proc to evaluate GCD(the code does not make any sense because I'm trying to solve an example issue), and I'm trying to recursively call the proc again to continue evaluating(notice that I made an if statement that can understand the Stein_GCD 1 0 call, yet the tcl 8.6.6 online EDA emulator says:
can't read "Stein_GCD 1 0": no such variable
while executing
"expr 2 * ${Stein_GCD 1 0} "
(procedure "Stein_GCD" line 5)
invoked from within
"Stein_GCD 2 2 "
invoked from within
"set a [Stein_GCD 2 2 ]"
(file "main.tcl" line 7)
Can you tell me how to efficiently recursively call a proc, and where was my mistake?
will gladly provide more info in the case I did a bad job at explaining.
The error can't read "Stein_GCD 1 0": indicates that you are treating the data as a single string instead of separate arguments. The problem line:
return [expr 2 * ${Stein_GCD 1 0} ]
is not written correctly. ${Stean_GCD 1 0} is not a variable.
You should have:
return [expr 2 * [Stein_GCD 1 0] ]
You want the result from Stein_GCD 1 0, so the brackets should be used.

How to translate from decimal to bit-mask?

I have a ACLs system previously built by someone else and I am trying to understand how bit-masking works there. I have this 4 constants defined:
const NONE = 0;
const READ = 1;
const WRITE = 2;
const UPDATE = 4;
const DELETE = 8;
Then in DB I am seeing users with permissions like 1, 2, 5, 9, 15. I have tried to transform them using this tool and I end up with this result:
0 // NONE
1 // READ
2 // WRITE
3 // UPDATE|DELETE
4 // UPDATE
5 // WRITE|DELETE
6 // WRITE|UPDATE
7 // WRITE|UPDATE|DELETE
8 // DELETE
9 // READ|DELETE
10 // READ|UPDATE
11 // READ|UPDATE|DELETE
12 // READ|WRITE
13 // READ|WRITE|DELETE
14 // READ|WRITE|UPDATE
15 // READ|WRITE|DELETE|UPDATE
How I think this work is as follow:
Decimal Hexadecimal
3 00000011
Because the two last bits are 1 I am assuming that those users having 3 will have UPDATE|DELETE permissions (see table above). Is that right? If not what's the right way to translate from decimal to bit-mask?
0 = NONE is a special case which can be checked by simple comparison.
If you want to ask the question is constant cn with the value of 2^(n-1) set, then we do this with (1 = yes, 0 = no, % = modulo):
(value / cn) % 2
If we want to get all flags that are set, you can do this with the following pseudo code:
c := 1
while value > 0
if value % 2 = 1
// constant c is set
...
end if
value := value / 2
c := c * 2
end while

Stuck on an Ada Program - Stuck on Input

I have a pretty simple Ada project on my hands. The task is to take a collection of a "voter's" votes and compare it to each "candidate's" score and determine which candidate best matches the voter.
The input looks like this, followed by the output that should be put out:
Input:
0 0 0 1 1 1 -1 -1 -1 1
7
A
1 1 1 1 1 1 1 1 1 1
B
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1
C
1 -1 1 -1 1 -1 1 -1 1 -1
D
1 0 1 0 1 0 1 0 1 0
E
0 -1 0 -1 0 -1 0 -1 0 -1
F
1 1 1 1 0 0 0 0 0 0
G
0 0 0 1 -1 0 0 -1 1 1
Output:
A
F
G
So far, I have a procedure that will take the votes of each candidate and compare them to the votes of the voter. I know what I need to do as I have done it before in Java, but I am not sure how I should take the input in Ada. Here is what I have so far.
with Ada.Text_IO, Ada.Integer_Text_IO;
use Ada.Text_IO, Ada.Integer_Text_IO;
procedure Candidates is
-- take an array of candidates and determine which candidate best matches
-- the user's votes, then return those candidates
Number_Of_Candidates: Integer;
subtype VoterArray_Index is Integer range 1..10;
subtype CandidatesArray_Index is Integer range 1..Number_Of_Candidates;
type VoterArray is array(VoterArray_Index) of Integer;
type CandidatesArray is array(Character range 'A' .. 'Z') of array;
type Best_CandidatesArray is array(CandidatesArray_Index) of array;
Voter: VoterArray;
Candidates: CandidatesArray;
Best_Candidates: Best_CandidatesArray;
function Get_Input() is
-- get the input and put it into the correct arrays
Current_Line : string;
begin
Get(Current_Line);
function Get_Best_Score(CandidatesArray: in out CandidatesArray) is
-- go through the arrays and find the best score
SameAnswers: Integer;
DifferentAnswers: Integer;
BestScore: Integer;
subtype CandidateArray is array(VoterArray_Index) of Integer;
Candidate: CandidateArray;
begin
for I in CandidatesArray_Index loop
Candidate := Candidates(I);
for J in VoterArray_Index loop
if Candidate(J) /= 0 and Voter(J) /= 0 then
if Candidate(J) /= Voter(J) then
DifferentAnswers := DifferentAnswers + 1
else
SameAnswers := SameAnswers + 1
end if;
end if;
end loop;
if SameAnswers - DifferentAnswers >= BestScore then
Best_Candidates(I) := Candidate;
end if;
SameAnswers := 0;
DifferentAnswers := 0;
end loop;
end Get_Best_Score;
As you can see, I'm not sure how to take the numbers and put them into an array. If you have any suggestions or a different way I should go about things, I'm all ears.
Thanks in advance.
You could use streams in order to read the data in:
Integer'Read( STREAM_HANDLE, VARIABLE )
Another option is reading the values via Get for each element of your array, I'd recommend a helper-function in case you need to tweak the procedure for handling format changes:
Function Get_Vote ( File : File_Type ) Return Integer is
begin
Return Result : Integer do
Integer_IO.Get(
File => File,
Item => Result
);
End return;
end Read_Votes;
and
For Index in VOTE_ARRAY'range loop
VOTE_ARRAY( Index ) := Get_Vote( INPUT_FILE );
End loop;
Because the number of rows is given in the file, a constrained array has to be large enough to hold all possible elements. Instead, you can declare an unconstrained array:
subtype Voter_Index is Positive range 1 .. 10;
type Voter_Array is array(Voter_Index) of Integer;
type Candidate_Array is array(Character range <>) of Voter_Array;
Later, when you know the actual count, you can allocate only the space actually required for the array. This declaration puts Candidates on the stack in a nested scope:
Number_Of_Candidates := ...;
declare
Candidates : Candidate_Array(
'A' .. Character'Val(Character'Pos('A') + Number_Of_Candidates));
begin
...
end;
Alternatively, you can allocate space on the heap:
type Candidate_Array_Ptr is access Candidate_Array;
Candidates: Candidate_Array_Ptr;
begin
Number_Of_Candidates := ...;
Candidates := new Candidate_Array(
'A' .. Character'Val(Character'Pos('A') + Number_Of_Candidates));
end;
In either case, you can access the array elements as required:
for i in Candidates'Range loop
for j in Voter_Array'Range loop
Ada.Integer_Text_IO.put(Candidates(i)(j), 5);
end loop;
Ada.Text_IO.New_Line;
end loop;
Addendum: This approach assumes that candidate names are consecutive Characters. As an alternative, consider an array of Candidate_Record, where each Name is read from the file:
type Candidate_Record is
record
Name : Character;
Votes : Voter_Array;
end record;
type Candidate_Array is array(Positive range <>) of Candidate_Record;
Candidates : Candidate_Array(1 .. Number_Of_Candidates);
for i in Candidates'Range loop
Ada.Text_IO.Put(Candidates(i).Name & ':');
for j in Voter_Array'Range loop
Ada.Integer_Text_IO.Put(Candidates(i).Votes(j), 5);
end loop;
Ada.Text_IO.New_Line;
end loop;

Optimising R function that adds a new column to a data.frame

I have a function that at the moment programmed in a functional model and either want to speed it up and maybe solve the problem more in the spirit of R.
I have a data.frame and want to add a column based on information that's where every entry depends on two rows.
At the moment it looks like the following:
faultFinging <- function(heartData){
if(heartData$Pulse[[1]] == 0){
Group <- 0
}
else{
Group <- 1
}
for(i in seq(2, length(heartData$Pulse), 1)){
if(heartData$Pulse[[i-1]] != 0
&& heartData$Pulse[[i]] != 0
&& abs(heartData$Pulse[[i-1]] - heartData$Pulse[[i]])<20){
Group[[i]] <- 1
}
else{
if(heartData$Pulse[[i-1]] == 0 && heartData$Pulse[[i]] != 0){
Group[[i]] <- 1
}
else{
Group[[i]] <- 0
}
}
}
Pulse<-heartData$Pulse
Time<-heartData$Time
return(data.frame(Time,Pulse,Group))
}
I can't test this without sample data, but this is the general idea. You can avoid doing the for() loop entirely by using & and | which are vectorized versions of && and ||. Also, there's no need for an if-else statement if there's only one value (true or false).
faultFinging <- function(heartData){
Group <- as.numeric(c(heartData$Pulse[1] != 0,
(heartData$Pulse[-nrow(heartData)] != 0
& heartData$Pulse[-1] != 0
& abs(heartData$Pulse[-nrow(heartData)] - heartData$Pulse[-1])<20) |
(heartData$Pulse[-nrow(heartData)] == 0 & heartData$Pulse[-1] != 0)))
return(cbind(heartData, Group))
}
Putting as.numeric() around the index will set TRUE to 1 and FALSE to 0.
This can be done in a more vector way by separating your program into two parts: firstly a function which takes two time samples and determines if they meet your pulse specification:
isPulse <- function(previous, current)
{
(previous != 0 & current !=0 & (abs(previous-current) < 20)) |
(previous == 0 & current !=0)
}
Note the use of vector | instead of boolean ||.
And then invoke it, supplying the two vector streams 'previous' and 'current' offset by a suitable delay, in your case, 1:
delay <- 1
samples = length(heartData$pulse)
isPulse(heartData$pulse[-(samples-(1:delay))], heartData$pulse[-(1:delay)])
Let's try this on some made-up data:
sampleData = c(1,0,1,1,4,25,2,0,25,0)
heartData = data.frame(pulse=sampleData)
result = isPulse(heartData$pulse[-(samples-(1:delay))], heartData$pulse[-(1:delay)])
Note that the code heartData$pulse[-(samples-(1:delay))] trims delay samples from the end, for the previous stream, and heartData$pulse[-(1:delay)] trims delay samples from the start, for the current stream.
Doing it manually, the results should be (using F for false and T for true)
F,T,T,T,F,F,F,T,F
and by running it, we find that they are!:
> print(result)
FALSE TRUE TRUE TRUE FALSE FALSE FALSE TRUE FALSE
success!
Since you want to bind these back as a column into your original dataset, you should note that the new array is delay elements shorter than your original data, so you need to pad it at the start with delay FALSE elements. You may also want to convert it into 0,1 as per your data:
resultPadded <- c(rep(FALSE,delay), result)
heartData$result = ifelse(resultPadded, 1, 0)
which gives
> heartData
pulse result
1 1 0
2 0 0
3 1 1
4 1 1
5 4 1
6 25 0
7 2 0
8 0 0
9 25 1
10 0 0

Resources