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

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.

Related

How to avoid !! in a function which returns a non-nullable

In the sample below, the function should return a non-null data.
Since the data could be changed in the process, it needs to be var, and can only be nullable to start with.
I can't use lateinit because the first call of if (d == null) will throw.
After the process it will be assigned a non-null data, but the return has to use the !! (double bang or non-null assertion operator).
What is the best approach to avoid the !!?
fun testGetLowest (dataArray: List<Data>) : Data {
var d: Data? = null
for (i in dataArray.indecs) {
if (d == null) {// first run
d = dataArray[i]
} else if {
d.level < dataArray[i].level
d = dataArray[i]
}
}
return d!!
}
If you don't like !! then supply a default value for it. You'll realize you can only supply the default value if the list is not empty, but, as you said, the list is already known to be non-empty. The good part of this story is that the type system doesn't track list size so when you say dataArray[0], it will take your word for it.
fun testGetLowest(dataArray: List<Data>) : Data {
var d: Data = dataArray[0]
for (i in 1 until dataArray.size) {
if (d.level < dataArray[i].level) {
d = dataArray[i]
}
}
return d
}
Normally, you can and should lean on the compiler to infer nullability. This is not always possible, and in the contrived example if the inner loop runs but once d is non-null. This is guaranteed to happen if dataArray has at least one member.
Using this knowledge you could refactor the code slightly using require to check the arguments (for at least one member of the array) and checkNotNull to assert the state of the dataArray as a post-condition.
fun testGetLowest (dataArray: List<Data>) : Data {
require(dataArray.size > 0, { "Expected dataArray to have size of at least 1: $dataArray")
var d: Data? = null
for (i in dataArray.indecs) {
if (d == null) {// first run
d = dataArray[i]
} else if {
d.level < dataArray[i].level
d = dataArray[i]
}
}
return checkNotNull(d, { "Expected d to be non-null through dataArray having at least one element and d being assigned in first iteration of loop" })
}
Remember you can return the result of a checkNotNull (and similar operators):
val checkedD = checkNotNull(d)
See Google Guava's Preconditions for something similar.
Even if you were to convert it to an Option, you would still have to deal with the case when dataArray is empty and so the value returned is undefined.
If you wanted to make this a complete function instead of throwing an exception, you can return an Option<Data> instead of a Data so that the case of an empty dataArray would return a None and leave it up to the caller to deal with how to handle the sad path.
How to do the same check, and cover the empty case
fun testGetLowest(dataArray: List<Data>)
= dataArray.minBy { it.level } ?: throw AssertionError("List was empty")
This uses the ?: operator to either get the minimum, or if the minimum is null (the list is empty) throws an error instead.
The accepted answer is completly fine but just to mentioned another way to solve your problem by changing one line in your code: return d ?: dataArray[0]

understanding a piece of code with ``boolean`` and ``switch``

i was looking some examples of interactions with the keyboard and stumbled upon this code that i found interesting. But i'm having trouble understanding a certain part of it(it's marked down below).I don't get how all this whole ''boolean'' declaration, ''switch'' and ''CASE'' works, i tried to look in the reference but still. Could someone explain in a simple maner how these work?
float x = 300;
float y = 300;
float speed = 5;
boolean isLeft, isRight, isUp, isDown;
int i = 0;
void keyPressed() {
setMove(keyCode, true);
if (isLeft ){
x -= speed;
}
if(isRight){
x += speed;
}
}
void keyReleased() {
setMove(keyCode, false);
}
boolean setMove(int k, boolean b) {// <<<--- From this part down
switch (k) {
case UP:
return isUp = b;
case DOWN:
return isDown = b;
case LEFT:
return isLeft = b;
case RIGHT:
return isRight = b;
default:
return b; }
}
Questions like these are best answered by the reference:
Works like an if else structure, but switch() is more convenient when you need to select between three or more alternatives. Program controls jumps to the case with the same value as the expression. All remaining statements in the switch are executed unless redirected by a break. Only primitive datatypes which can convert to an integer (byte, char, and int) may be used as the expression parameter. The default is optional.
The rest of the code is setting the corresponding variable to whatever value you passed in as the b parameter, and then returning it.
You should get into the habit of debugging your code. Add print statements to figure out exactly what the code is doing.

Selection a bool through randomizer

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;

Objective C: Using a BOOL to return 'YES' if a condition can be applied

Hi there I have some code at the moment that gives me the error ("0") is not equal to ("50") - condition not applied correctly Basically I am currently using a traditional for loop within a BOOL which goes through the list of items and checks whether or not the condition can be applied, if it can be applied to an item then the BOOL will return YES. I cannot see where I am currently going wrong and need guidance. My code is shown below:
-(BOOL)conditionCanBeApplied:(NSArray *)items{
bool itemConditionCanBeApplied = NO;
for (int i = 0; i < items.count; i++)
{
id myItem = [[items valueForKeyPath:#"itemId"]objectAtIndex: i];
if ([self.applicableItems containsObject:myItem]) {
itemConditionCanBeApplied = YES;
}
}
return itemConditionCanBeApplied;
}
First, don't mix BOOL and bool, they might be very similar but they aren't the same data type. Second, always use fast enumeration if you have a choice. I am assuming in the code below that your items collection is something like an NSArray. Also, there is no reason to test with an if statement just to set a BOOL since the test is a boolean statement. (I am doing it in my example to allow for the break) Lastly, short-circuiting your logic with a break keeps the processor from doing unnecessary work once you have at least one match.
Do something like this:
- (BOOL)conditionTest
{
BOOL itemConditionCanBeApplied = NO;
for (id item in items) {
if ([self.applicableItems containsObject:item]) {
itemConditionCanBeApplied = YES;
break;
}
}
return itemConditionCanBeApplied;
}

If statements not working correctly

I am developing an app where the user receives an overall score and are judged from that score and given a title. However, with the code I am using, the end result is always the same, no matter what score the subject gets. I dont know if this a math problem or a code problem, as it always comes up with the first option: You have no SWAG whatsoever...
if (totalScore<24) {
describe.text = #"You have no SWAG whatsoever...";
}
else if (25<totalScore<49) {
describe.text = #"You seem to be new to SWAG.";
}
else if (50<totalScore<74) {
describe.text = #"You have a bit of SWAG, not enough though.";
}
else if (75<totalScore<99) {
describe.text = #"You definately have SWAG!";
}
else if (totalScore == 100) {
describe.text = #"You are a GOD of SWAG.";
}
else if (25<totalScore<49) {
should be:
else if (25<totalScore && totalScore<49) {
The way you wrote it is parsed as if you'd written:
else if ((25<totalScore) < 49) {
25<totalScore will be either 1 or 0 depending on whether it's true or false. Either way, it's less than 49.
Also, all your comparisons should be <= rather than <. Otherwise, you're excluding all the boundary values.
building if in this way
if (25<totalScore<49) {...}
is risky.In reality you do something like
25<totalScore -> YES/NO (values will be casted from BOOL to int as 1/0)
and then you will do
0/1 < 49 which will be always true.
so in total your if is wrong.
Your first line of code looks right from what you have displayed so far? You need to output what total score is. You are maybe not setting it before running your code?
Failing that, are you sure its compiling properly? You need to use && in your subsequent if statements.
Also, you need to use <=, because at the moment, if the score is 24 it wont work.