Selection a bool through randomizer - objective-c

I have a total of 6 booleans and the only thing separating them is a number. They're named checker0 though 5.
So checker0, checker1, checker2, checker3, checker4 and checker5.
All of these grants or denies access to certain parts of the app wether the bool is true or false.
I then have a randomiser using:
randomQuestionNumber = arc4random_uniform(5);
So say we get number 3, checker3 = true;
But my question now is would it be possible to set this one to true without having to go thru if statements.
My idea was to implement the way you print a int to say the NSLog using the %d.
NSLog(#"The number is: %d", randomQuestionNumber);
So something like:
checker%d, randomQuestionNumber = true.
Would something like that be possible? So i won't have to do like this:
if (randomQuestionNumber == 0) {
checker0 = true;
}
else if (randomQuestionNumber == 1)
{
checker1 = true;
}
Thanks you very much! :)

Every time you find yourself in a situation when you name three or more variables checkerN you know with a high degree of probability that you've missed a place in code where you should have declared an array. This becomes especially apparent when you need to choose one of N based on an integer index.
The best solution would be to change the declaration to checker[6], and using an index instead of changing the name. If this is not possible for some reason, you could still make an array of pointers, and use it to make modifications to your values, like this:
BOOL *ptrChecker[] = {&checker0, &checker1, &checker2, ...};
...
*ptrChecker[randomQuestionNumber] = true;

Related

Convert a string into a int

I need some help here, I am currently making a game, but I got stuck somewhere. So, what I want is, if a Labels text is higher then the other labels text, then something will happen, I typed If Label26.Text > Label24.Text Then Label33.Visible = True which seems not to work, please, I need some help here, thanks. And yes, the labels text is NUMBERS.
The Text property of a label is a string. As far as computers go, you can't do math (using comparison operators like > will not return the result you are expecting) with strings because they are just a sequence of characters.
Even if the string only contains a number, the computer still sees it as a sequence of characters and not a number ("5" is a string literal with the character 5 in it, while 5 is an integer that can be used in a mathematic expression).
As some of the other commenters mentioned, you need to cast the Text property to an Integer or Double (or some other numeric data type). To do so, you'd want to use Int32.Parse to change the strings to integers.
If Int32.Parse(Label26.Text) > Int32.Parse(Label24.Text) Then Label33.Visible = True
You can use the int.tryParse to check if the content of the variable is a number or not. The output of the TryParse is a boolean, see the example below:
int num1 = 0;
bool num1_ = false;
num1_ = int.TryParse(txt1.Text.ToString(), out num1);
if (num1_)
{
// Is a number/integer
//Do something
}
else
{
//Is a string
//Do something else
}

Counter as variable in for-in-loops

When normally using a for-in-loop, the counter (in this case number) is a constant in each iteration:
for number in 1...10 {
// do something
}
This means I cannot change number in the loop:
for number in 1...10 {
if number == 5 {
++number
}
}
// doesn't compile, since the prefix operator '++' can't be performed on the constant 'number'
Is there a way to declare number as a variable, without declaring it before the loop, or using a normal for-loop (with initialization, condition and increment)?
To understand why i can’t be mutable involves knowing what for…in is shorthand for. for i in 0..<10 is expanded by the compiler to the following:
var g = (0..<10).generate()
while let i = g.next() {
// use i
}
Every time around the loop, i is a freshly declared variable, the value of unwrapping the next result from calling next on the generator.
Now, that while can be written like this:
while var i = g.next() {
// here you _can_ increment i:
if i == 5 { ++i }
}
but of course, it wouldn’t help – g.next() is still going to generate a 5 next time around the loop. The increment in the body was pointless.
Presumably for this reason, for…in doesn’t support the same var syntax for declaring it’s loop counter – it would be very confusing if you didn’t realize how it worked.
(unlike with where, where you can see what is going on – the var functionality is occasionally useful, similarly to how func f(var i) can be).
If what you want is to skip certain iterations of the loop, your better bet (without resorting to C-style for or while) is to use a generator that skips the relevant values:
// iterate over every other integer
for i in 0.stride(to: 10, by: 2) { print(i) }
// skip a specific number
for i in (0..<10).filter({ $0 != 5 }) { print(i) }
let a = ["one","two","three","four"]
// ok so this one’s a bit convoluted...
let everyOther = a.enumerate().filter { $0.0 % 2 == 0 }.map { $0.1 }.lazy
for s in everyOther {
print(s)
}
The answer is "no", and that's a good thing. Otherwise, a grossly confusing behavior like this would be possible:
for number in 1...10 {
if number == 5 {
// This does not work
number = 5000
}
println(number)
}
Imagine the confusion of someone looking at the number 5000 in the output of a loop that is supposedly bound to a range of 1 though 10, inclusive.
Moreover, what would Swift pick as the next value of 5000? Should it stop? Should it continue to the next number in the range before the assignment? Should it throw an exception on out-of-range assignment? All three choices have some validity to them, so there is no clear winner.
To avoid situations like that, Swift designers made loop variables in range loops immutable.
Update Swift 5
for var i in 0...10 {
print(i)
i+=1
}

Is there a less ugly way to do input in D than scanf()?

Currently the only way I know how to do input in D is with the scanf() function. But god damn it's ugly. You would think that since it's an upgrade from C that they would have fixed that.
I'm looking for a way to do it with a single argument. Currently you have to do:
int foo = 0;
scanf("%i", &foo);
writeln("%i", foo);
But it would look a lot cleaner with a single argument. Something like:
int foo = 0;
scanf(foo);
writeln(foo);
Thanks.
readf("%d", &foo); allows working with std.stdio.File rather than C FILE*
foo = readln().strip().to!int();
For reading entire files with lines formatted in the same way:
int[] numbers = slurp!int("filename", "%d");
There's a really cool user-input module here:
https://github.com/Abscissa/scriptlike/blob/master/src/scriptlike/interact.d
Example code:
if (userInput!bool("Do you want to continue?"))
{
auto outputFolder = pathLocation("Where you do want to place the output?");
auto color = menu!string("What color would you like to use?", ["Blue", "Green"]);
}
auto num = require!(int, "a > 0 && a <= 10")("Enter a number from 1 to 10");
The above answers are great. I just want to add my 2 cents.
I often have the following simple function lying around:
T read(T)()
{
T obj;
readf(" %s", &obj);
return obj;
}
It's generic and pretty handy - it swallows any white space and reads any type you ask. You can use it like this:
auto number = read!int;
auto floating_number = read!float;
// etc.

Objective-C: Adding to variable before assignment

I have the following code:
NSInteger variableScene = 10;
NSInteger numberOfRowsXX = //an Integer value; <-- I would like replace XX with the value of 'variableScene'
So it'll look like this:
NSInteger numberOfRows10 == //an Integer value;
How can I replace XX with the value of variableScene?
*Update*
Why I'm trying accomplish this?
It's a bit complicated. I'm using Core Data with remote Database. In a nutshell: I have 10 Scenes that'll be presented based on the User selection order. For each Scene I need to assign the numberOfRows to present at the end of all the Scenes with a UITableViewController.
I have a variableScene that I pass around from Scene to Scene.
I need to assign numberOfRowsSceneXX = //an integer
XX will come from variableScene, which could be any number from 1 - 10.
So when we get to the last scene, we'll have a value for each Section (numberOfRowInSection) which will be represented by each Scene: numberOfRowScene1, numberOfRowsScene2, etc.
I tried to simplify the question. Hope it makes sense.
Use arrays.
set it up as:
#define MAX_SCENES 10
NSInteger numberOfRows[MAX_SCENES];
then when you want to set the value:
if (variableScene < MAX_SCENES) {
numberOfRows[variableScene] = variable;
}

"used struct type value where scalar is required" at .layer.position

I want to make a selection before apply one of two animations,
what I thought is: make a Point one, if my myImageView is at the Point one, then apply animationNo1, else apply animationNo2, but I got this:"used struct type value where scalar is required", at line if (myImageView.layer.position = one)
What I do? how can I fix this?
Does anyone know exactly what makes the problem happen?
CGPoint one = CGPointMake(myImageView.layer.position.x, 100);
if (myImageView.layer.position = one)
{
animationNo1
}
else
{
animationNo2
}
First of all, your if-statement will not do what you think. If you want to compare something you have to use == (ie 2 =)
and you can't compare CGPoints like this.
use
if (CGPointEqualToPoint(one, self.view.layer.position))
if (myImageView.layer.position = one) { animationNo1 }
should be
if (CGPointIsEqualToPoint(myImageView.layer.position, one)) { animationNo1 }
You used a single = meaning assignment, rather than a == for comparison. But the == wouldn't do what you wanted here anyway.
You are passing a struct (int this case position) instead of a scalar. To do what you want you need to use CGPointIsEqualToPoint:
if (CGPointEqualToPoint(one, self.view.layer.position))
Full code with corrections:
CGPoint one = CGPointMake(myImageView.layer.position.x, 100);
if (CGPointEqualToPoint(one, self.view.layer.position))
{
animationNo1
}
else
{
animationNo2
}
Also, as others have pointed out: Be careful about = vs ==. They are different. In this case you don't use == for comparison fortunately, but if you use = for other stuff it will make it true instead of checking to see if it is true.