Why is an exception being called when I set the text of a label to a object in an array? - objective-c

I have a label that I want to set its text as an object from and array peopleQuestionArray. I have generated an random int with values ranging from 1-4. My array currently has 4 objects in it. I expect that either the first, second, third, or fourth objects in my array will be displayed, but instead xcode gave me and exception. Does anyone know why. Here's the code I used to set the labels text :
int random = (arc4random() % 4) +1;
[quesetionLabel setText:[peopleQuestionArray objectAtIndex:random]];

Your index may go out of range. NSArray indices start from 0. So you need to generate a random number ranging from 0-3, not 1-4. Remove the +1 while calculating the random number.

Related

How to add record cell value to array variable (IE sum values in array)

I have a function returning a setof records. This can be seen in this picture
.
I have a range of boards of length 2.8m thru to 4.9m (ln28 thru ln49 respectively) they have characteristics that set bits as seen in bincodes (9,2049,4097 etc.) For each given board length, I need to sum the number of boards for each bincode. EG in this case ln28 (bincode 4097) would = 3+17+14 = 34. Where you see brdsource = 128 series is where I intend to store these values, so for row brdsource 128, bincodes 4097, I want to store 34 in ln28.
You will see that I have 0's in ln28 values for all brdsource = 128. I have generated extra records as part of my setof records, and am trying to use a multidimensional array to add the values and keep track of them as seen above with array - Summary[boardlength 0-8][bincode 0-4].
Question 1 - I see that if I add 1 (for argument sake, it can be any number) to an array location, it returns a null value (no error, just nothing in table cell). However if I first set the array location to 0, then add 1, it works perfectly. How can an array defined as type integer hold a null value?
Question 2 - How do I add my respective record (call it rc) board length count to the array. IE I want to do something like this
if (rc.bincode = 4097) then Summary[0][2] := Summary[0][2] + rc.ln28;
and then later, on, when injecting this into my table (during brdsource = 128 phase) :
if (rc.bincode = 4097) then rc.ln28 := Summary[0][2];
Of course I may be going about this in a completely unorthodox way (though to me SQL is just plain unorthodox, sigh). I have made attempts to sum all previous records based on the required conditions (eg using a case(when...end) statement, but I proved what I already suspected, ie that each returned record is simply a single row of data. There is just no means of accessing data in the previous record lines as returned by the functions FOR LOOP...END LOOP.
A final note is that everything discussed here is occurring inside the function. I am not attempting to add records etc. to data returned by the function.
I am using PostgreSQL 9.2.9, compiled by Visual C++ build 1600, 64-bit. And yes I am aware this is an older version.

Random 4x4 2D NSArray Objective-C

I'm trying to create a Minesweeper game.
I have a 4x4 set of buttons equally spaced in main.Storyboard.
My plan is to create a random array which places a 0 or * in the 1st/2nd/3rd/4th arrays. I would do this by using the arc4Random method.
With the remaining blank cells, I then have to check how many mines there could be for the 8 (potential) squares around the cell/button. This would be governed by the boundary conditions (0,0 to 3,3).
Once this is set up, I would then set the background and number label to the same colour. I could then write an if or else statement to change the colour after each button is pressed.
I'm quite struggling how to start this off and actually write this. Can anyone please give me some advice please?
Well,
you can get a boolean like this.
bool hasMine = arc4random() % 2;
this will give you 50% chance to get a bomb... if you want less bomb, increase the value (3 will give you 2 bomb free square, for one with a bomb, etc..)
then a "" or a "*" like this;
NSSString * value = hasMine ? #"*" : #"" ;
then it's just a matter of a for loop to populate your arrays.
for the sake of performance, I wouldn't use a n x n nested array but a single arrray of nxn size (in your case a array with 16 value). Then I will set a tag for 0 to (nxn -1) to each button based on its position, and on click I'll get the tag of the pressed button and retrive the value of the object at this position in the array

Optimal Solution: Get a random sample of items from a data set

So I recently had this as an interview question and I was wondering what the optimal solution would be. Code is in Objective-c.
Say we have a very large data set, and we want to get a random sample
of items from it for testing a new tool. Rather than worry about the
specifics of accessing things, let's assume the system provides these
things:
// Return a random number from the set 0, 1, 2, ..., n-2, n-1.
int Rand(int n);
// Interface to implementations other people write.
#interface Dataset : NSObject
// YES when there is no more data.
- (BOOL)endOfData;
// Get the next element and move forward.
- (NSString*)getNext;
#end
// This function reads elements from |input| until the end, and
// returns an array of |k| randomly-selected elements.
- (NSArray*)getSamples:(unsigned)k from:(Dataset*)input
{
// Describe how this works.
}
Edit: So you are supposed to randomly select items from a given array. So if k = 5, then I would want to randomly select 5 elements from the dataset and return an array of those items. Each element in the dataset has to have an equal chance of getting selected.
This seems like a good time to use Reservoir Sampling. The following is an Objective-C adaptation for this use case:
NSMutableArray* result = [[NSMutableArray alloc] initWithCapacity:k];
int i,j;
for (i = 0; i < k; i++) {
[result setObject:[input getNext] atIndexedSubscript:i];
}
for (i = k; ![input endOfData]; i++) {
j = Rand(i);
NSString* next = [input getNext];
if (j < k) {
[result setObject:next atIndexedSubscript:j];
}
}
return result;
The code above is not the most efficient reservoir sampling algorithm because it generates a random number for every entry of the reservoir past the entry at index k. Slightly more complex algorithms exist under the general category "reservoir sampling". This is an interesting read on an algorithm named "Algorithm Z". I would be curious if people find newer literature on reservoir sampling, too, because this article was published in 1985.
Interessting question, but as there is no count or similar method in DataSet and you are not allowed to iterate more than once, i can only come up with this solution to get good random samples (no k > Datasize handling):
- (NSArray *)getSamples:(unsigned)k from:(Dataset*)input {
NSMutableArray *source = [[NSMutableArray alloc] init];
while(![input endOfData]) {
[source addObject:[input getNext]];
}
NSMutableArray *ret = [[NSMutableArray alloc] initWithCapacity:k];
int count = [source count];
while ([ret count] < k) {
int index = Rand(count);
[ret addObject:[source objectAtIndex:index]];
[source removeObjectAtIndex:index];
count--;
}
return ret;
}
This is not the answer I did in the interview but here is what I wish I had done:
Store pointer to first element in dataset
Loop over dataset to get count
Reset dataset to point at first element
Create NSMutableDictionary for storing random indexes
Do for loop from i=0 to i=k. Each iteration, generate a random value, check if value exists in dictionary. If it does, keep generating a random value until you get a fresh value.
Loop over dataset. If the current index is within the dictionary, add it to a the array of random subset values.
Return array of random subsets.
There are multiple ways to do this, the first way:
1. use input parameter k to dynamically allocate an array of numbers
unsigned * numsArray = (unsigned *)malloc(sizeof(unsigned) * k);
2. run a loop that gets k random numbers and stores them into the numsArray (must be careful here to check each new random to see if we have gotten it before, and if we have, get another random, etc...)
3. sort numsArray
4. run a loop beginning at the beginning of DataSet with your own incrementing counter dataCount and another counter numsCount both beginning at 0. whenever dataCount is equal to numsArray[numsCount], grab the current data object and add it to your newly created random list then increment numsCount.
5. The loop in step 4 can end when either numsCount > k or when dataCount reaches the end of the dataset.
6. The only other step that may need to be added here is before any of this to use the next command of the object type to count how large the dataset is to be able to bound your random numbers and check to make sure k is less than or equal to that.
The 2nd way to do this would be to run through the actual list MULTIPLE times.
// one must assume that once we get to the end, we can start over within the set again
1. run a while loop that checks for endOfData
a. count up a count variable that is initialized to 0
2. run a loop from 0 through k-1
a. generate a random number that you constrain to the list size
b. run a loop that moves through the dataset until it hits the rand element
c. compare that element with all other elements in your new list to make sure it isnt already in your new list
d. store the element into your new list
there may be ways to speed up the 2nd method by storing a current list location, that way if you generate a random that is past the current pointer you dont have to move through the whole list again to get back to element 0, then to the element you wish to retreive.
A potential 3rd way to do this might be to:
1. run a loop from 0 through k-1
a. generate a random
b. use the generated random as a skip count, move skip count objects through the list
c. store the current item from the list into your new list
Problem with this 3rd method is without knowing how big the list is, you dont know how to constrain the random skip count. Further, even if you did, chances are that it wouldnt truly look like a randomly grabbed subset that could easily reach the last element in the list as it would become statistically unlikely that you would ever reach the end element (i.e. not every element is given an equal shot of being select.)
Arguably the FASTEST way to do this is method 1, where you generate the random numerics first, then traverse the list only once (yes its actually twice, once to get the size of the dataset list then again to grab the random elements)
We need a little probability theory. As others, I will ignore the case n < k. The probability that the n'th item will be selected into the set of size k is just C(n-1, k-1) / C(n, k) where C is the binomial coefficient. A bit of math says shows that this is just k/n. For the rest, note that the selection of the n'th item is independent of all other selections. In other words, "the past doesn't matter."
So an algorithm is:
S = set of up to k elements
n = 0
while not end of input
v = next value
n = n + 1
if |S| < k add v to S
else if random(0,1) >= k/n replace a randomly chosen element of S with v
I will let the coders code this one! It's pretty trivial. All you need is an array of size k and one pass over the data.
If you care about efficiency (as your tags suggest) and the number of items in the population is known, don't use reservior sampling. That would require you to loop through the entire data set and generate a random number for each.
Instead, pick five values ranges from 0 to n-1. In the unlikely case, there is a duplicate among the five indexes, replace the duplicate with another random value. Then use the five indexes to do a random-access lookup to the i-th element in the population.
This is simple. It uses a minimum number of calls the random number generator. And it accesses memory only for the relevant selections.
If you don't know the number of data elements in advance, you can loop-over the data once to get the population size and proceed as above.
If you aren't allow to iterate over the data more than once, use a chunked form of reservior sampling: 1) Choose the first five elements as the initial sample, each having a probability of 1/5th. 2) Read in a large chunk of data and choose five new samples from the new set (using only five calls to Rand). 3) Pairwise, decide whether to keep the new sample item or old sample element (with odds proportional the the probablities for each of the two sample groups). 4) Repeat until all the data has been read.
For example, assume there are 1000 data elements (but we don't know this in advance).
Choose the first five as the initial sample: current_sample = read(5); population=5.
Read a chunk of n datapoints (perhaps n=200 in this example):
subpop = read(200);
m = len(subpop);
new_sample = choose(5, subpop);
loop-over the two samples pairwise:
for (a, b) in (current_sample and new_sample): if random(0 to population + m) < population, then keep a, otherwise keep *b)
population += m
repeat

What could cause a for loop to not increment and then increment by two?

I am not sure how this is possible but I have a for loop not incrementing properly through an array.
Basically what I have is:
for (AISMessage *report in disarray){
NSLog(#"Position of array = %ld\n", [aisArray indexOfObject:report]);
}
There is more code in the loop but is nothing strange just formatting some of the data in the object and outputting it to a file.
The output of these lines would look something like:
Position of array = 0
...
Posiiton of array = 78176
Posiiton of array = 78177
Posiiton of array = 78178
Posiiton of array = 78178
Posiiton of array = 78180
Posiiton of array = 78181
...
Posiiton of array = 490187
For some reason the report at index 78178 gets read in twice and the report at 78179 gets skipped completely.
Any ideas on what may cause this?
I am totally confused.
Thanks in advance,
Jason
The object occurs twice in the array, so the indexOfObject finds the element at index 78179 at index 78178.
In other words, you have this case:
...
[78177] = x
[78178] = y
[78179] = y
[78180] = z
...
Also, you're not searching the same array you're iterating over, that might have something to do with it as well.
Since the positions reported are so high, I would try to find a better data structure than a simple array. For it to report a position of 78178, it will have to have compared the object against the preceeding 78177 elements, and this will only take more and more time as you get further into the array.
From the posted code you are iterating over AISMessage objects in the disarray array, but you are reporting on the position of the object in the aisArray array.
I have no idea if these are meant to be the same array or not. But if they are different arrays, then do you expect the objects to be in the same order?

Array bounds checking techniques in C or Objective-C

My goal is to prevent index out of bounds conditions for the lower bound when using a variable as a subscript to an array. In other words, I'd like to limit the integer variable values to >= 0. Sort of similar to an absolute value, except instead of making a negative number positive, it would make a negative number zero.
Is there any better method of doing this than using a macro such as:
#define gte0(value) (value < 0) ? 0 : value
and then wrapping my variables representing an index with this macro when I access an array element? Is there a standard practice bounds checking other than doing it manually in every place in your code before you access an array element with a variable representing the index?
I'm looking for any solutions in C or Objective-C.
Thanks!
Require unsigned int or NSUInteger primitives for indices. You'll then be guaranteed a value greater than or equal to zero, up to UINT_MAX or whatever limits.h defines, and you just need to check the upper bound.
There is no way of doing this automatically in C.