Xcode complains about structure of if-statement using Swift and Xcode 6 - cocoa-touch

I was wondering what this if statement is wrong. I am using swift. What I am trying to do is to perform multiple checks from my textfields, mainly to restrict their text lenght between the ranges declared in the if statement. Here is my code:
if countElements(usernameTextField.text) < 16 &&
countElements(usernameTextField.text) > 4 &&
countElements(passwordTextField.text) > 5 &&
countElements(passwordTextField.text) < 16 {
//Do something
} else {
//Do something else
}
The compiler complains says the following:
"Type 'String!' does not conform to protocol '_CollectionType'"
Do you guys have any idea of why this is showing up?
Thank you in advance for your advice/recommendations/explanations.
Cheers!

text propety in UITextField declared as:
var text: String!
So you should rewrite your code to:
Option 1:
if countElements(usernameTextField.text!) < 16 { ... }
This option is preferable since it will take into account emoji character.
For instance if you add a flag character that counts for 4 places you will be counted as one.
Option 2 (do not use it):
if usernameTextField.text.utf16Count < 16 { ... }
This options counts utf16 symbols so in case of flag emoji you will have visible chars count +3. So do not go this track. I've added this just to show that it should not be used.

Related

Counting how many times specific character appears in string - Kotlin

How one may count how many times specific character appears in string in Kotlin?
From looking at https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-string/ there is nothing built-in and one needs to write loop every time (or may own extension function), but maybe I missed a better way to achieve this?
Easy with filter {} function
val str = "123 123 333"
val countOfSymbol = str
.filter { it == '3' } // 3 is your specific character
.length
println(countOfSymbol) // output 5
Another approach
val countOfSymbol = str.count { it == '3'} // 3 is your specific character
println(countOfSymbol) // output 5
From the point of view of saving computer resources, the count decision(second approach) is more correct.

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;

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
}

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.

Gimpel's PC Lint Value Tracking

I'm a newbie to this site, so if I mess up any question-asking etiquette here I apologize in advance... Thanks!
This is extremely simplified example code, but I think it shows what I'm talking about: I have a C++ method that makes a call into another method to test a value...
char m_array[MAX]; // class member, MAX is a #define
foo(unsigned int n)
{
if (validNumber(n)) //test n
{
// do stuff
m_array[n-1] = 0;
}
}
where: validNumber(unsigned int val) { return ((val > 0) && (val <= MAX)); }
The irritation I'm having is that PC Lint's Value Tracking seems to ignore the validNumber() call and gives a warning 661 possible access of out-of-bounds pointer (1 beyond end of data) by operator '['
However if I do it like this, Lint is happy:
if ((n > 0) && (n <= MAX)) //test n
...
So, does Lint's Value Tracking just not work if the test is a method call?
Thanks again,
HF
I'd guess that validNumber is defined after foo, but in any case, PC Lint normally makes one pass over the code, and in such cases it doesn't see validNumber as a check for the boundaries for n.
You could try the option -passes(2) or even 3, and see what Lint makes out of it. I think (but didn't try) that Lint would then correctly note that the value for n is within the correct bounds.