SWIFT Variable used before being initialized [duplicate] - swift

This question already has answers here:
Variable used before being initialized in function
(6 answers)
Closed 4 years ago.
I want to know why this code will not run. The error appears on the very last line (the print statement) (the last "letter grade") and says
"Variable 'letterGrade' used before being initialized"
let score = 86
var letterGrade: Character
if(score >= 90)
{
letterGrade = "A"
}
else if(score >= 80)
{
letterGrade = "C"
}
else if (score >= 70)
{
letterGrade = "C"
}
else if (score >= 60)
{
letterGrade = "D"
}
else if (score > 0)
{
letterGrade = "F"
}
print("Your letter grade is \(letterGrade)")

Yes, it is used before being assigned a grade (the compiler does not know that you've covered all the cases in your if statements before throwing this error - and in fact you haven't covered zero as #MartinR tells you ).
You could have a default value (in the UK a "U" is ungraded) by changing line 2 to
var letterGrade: Character = "U"
and better still use type inference to say
var letterGrade = "U"
You might also like to use a switch for this type of problem - look in the Swift documents using this link - https://docs.swift.org/swift-book/LanguageGuide/ControlFlow.html
But here is my version of your code using a switch
let score = 86
var letterGrade: Character
switch score {
case 90 ..< 100:
print("A")
case (80 ..< 90):
print("B")
case (70 ..< 80):
print("C")
case (0 ..< 70):
print("D")
default:
print("F")
}
This overcomes the problem of your compiler error.
Hope this helps you.

You cannot use a variable before initializing it (giving it an initial value).
You handled the cases where score >= 90 and score >= 80 and score >= 70 and score >= 60 and score > 0.
What if score was equal to 0? this case isn't handled, if it happened the variable letterGrade will stay uninitialized.
To fix this, you can use the answer by #stevenpcurtis, or you can replace the last else if statement with else only.
Also consider using a switch statement with a default case.

Related

Can i compare two bytes values on basis of nearly equal to in swift

i have two values in bytes in two different variables . i want to perform a certain action whenever values are nearly equal to each other.
I there any method in swift in which i can perform any action on variables values nearly equal to.
If recommend me some code , tutorial or article to achieve this.
I am new to swift so please avoid down voting.
let string1 = "Hello World"
let string2 = "Hello"
let byteArrayOfString1: [UInt8] = string1.utf8.map{UInt8($0)} //Converting HELLO WORLD into Byte Type Array
let byteArrayOfString2: [UInt8] = string2.utf8.map{UInt8($0)} //Converting HELLO into Byte Type Array
if byteArrayOfString1 == byteArrayOfString2 {
print("Match")
}else {
print("Not Match")
}
For more Help, Visit https://medium.com/#gorjanshukov/working-with-bytes-in-ios-swift-4-de316a389a0c
well exactly i don't think so there is such method that compare approx values but if you discuss what exactly you want to do we can find a better alternative solution.
Here is the Solution:
func nearlyEqual(a: Float, b: Float, epsilon: Float) -> Bool {
let absA = abs(a)
let absB = abs(b)
let diff = abs(a - b)
if a == b {
return true
} else if (a == 0 || b == 0 || absA + absB < Float.leastNonzeroMagnitude) {
// a or b is zero or both are extremely close to it
// relative error is less meaningful here
return diff < (epsilon * Float.leastNonzeroMagnitude)
} else {
return diff / (absA + absB) < epsilon
}
}
Then you can use it like :
print(nearlyEqual(a: 1.2, b: 1.4, epsilon: 0.2))
This will return true.

Declaring a var in Switch statement

Can I declare a variable which is "<" or ">" than some number in the following switch-statement?
var a = 150
switch a {
case 10...50:
print ("the value is 10 to 50")
fallthrough
case 100...125:
print ("the value is 100 to 125")
case 125...150:
print ("the value is 125 to 150")
default:
print ("the value is unknown")
}
Yes, You can use where clause to check for additional conditions in switch statement.
var a = 150
var x = 250
switch a {
case _ where a > x:
print ("a is greater than x")
case _ where a < x:
print ("a is less than x")
default:
print ("a is equal to x")
}
Or you can use One sided range operator to check if a number is greater or less than a particular number
switch a {
case ...50:
print ("the value is less than 50")
case 100...125:
print ("the value is 100 to 125")
case 125...:
print ("the value greater than 125")
default:
print ("the value is unknown")
}
Of course you can declare a variable that is < or > some number in a switch statement, but I don't think that's what you mean.
I think you're really trying to ask if you can use < or > in the case evaluations. Yes, you can do that using a where clause.
So, you can do this, for example:
var a = 150
let b = 160
switch a {
case 10...50 where b < a: print ("the value is 10 to 50 and b < a")
case 100...125 where b == a: print ("the value is 100 to 125 and b == a")
case 125...150 where b > a: print ("the value is 125 to 150 and b > a")
default: print ("default")
}
That will print:
the value is 125 to 150 and b > a
You can read more on Swift switch statements in the Swift documentation:
https://docs.swift.org/swift-book/LanguageGuide/ControlFlow.html

How do I fix the error "Result of operator '>=' is unused"

I have the error mentioned above for the two lines that are commented below, using an equals sign works, but when I use the '>=' sign... The error continues to show up. It's not an error with my pause function, I've tested it with the equals sign, so could you please tell me what to fix. Thanks!
func addScore(playerWhoWon : SKSpriteNode){
ball.position = CGPoint(x: 0, y: 0)
ball.physicsBody?.velocity = CGVector(dx: 0, dy: 0)
if playerWhoWon == main {
score[0] >= 10 // THAT"S WHERE I GET MY ERROR
pauseGame()
ball.physicsBody?.applyImpulse(CGVector(dx: 10, dy: 10))
}
else if playerWhoWon == enemy {
score[1] >= 10 // SECOND LINE WHERE I GET MY ERROR
pauseGame()
ball.physicsBody?.applyImpulse(CGVector(dx: -10, dy: -10))
}
topLbl.text = "\(score[1])"
btmLbl.text = "\(score[0])"
}
Based on your previous question, what you should be doing is creating an if statement:
if score[0] >= 10 {
pauseGame()
}
I also strongly urge you to spend lots of time reading the Swift Programming Language book from Apple.
Using an equal sign (=) means assignment. When you say: score[0] = 10 it means that you assign 10 to the first element of the array score. This is why it works.
Using greater than or equals sign (>=) means comparison, so it returns a boolean value as the result of the comparison. And you are not doing anything with that result, so this is why you are getting the warning.
When you use something that returns a result and you don't want to use that result, you can use:
_ = score[0] >= 10
You shouldn't do this in your case for sure, and as mentioned by #rmaddy, you should be using an if statement to fix your issue.

Prime Numbers Swift 3

After hours of Googling, I'm still at a standstill. I would appreciate if someone would point out the error in my formula or coding choice. Please keep in mind I'm new to Swift. I'm not used to non C-style for loops.
if textField.text != "" {
input = Double(textField.text!)! // parse input
// return if number less than 2 entered
if input < 2 {
resultLabel.text = "Enter a number greater than or equal to 2."
return;
}
// get square root of input and parse to int
inputSquared = Int(sqrt(input));
// loop from 2 to input iterating by 1
for i in stride(from: 2, through: input, by: 1) {
if inputSquared % Int(i) == 0 {
resultLabel.text = "\(Int(input)) is not a prime number."
}
else {
resultLabel.text = "\(Int(input)) is a prime number!"
}
}
}
I didn't know the formula on how to find a prime number. After looking up multiple formulas I have sorta settled on this one. Every result is a prime number, however. So my if condition is wrong. I just don't know how to fix it.
Check my algorithm.It works.But I'm not sure this is an effective algorithm for prime number
var input:Int = 30
var isPrime:Bool = true
if(input == 2){
print("Input value 2 is prim number")
}
else if(input < 2){
print("Input value must greater than 2")
}
else{
for i in 2...input-1{
if((input%i) == 0){
isPrime = false
break;
}
}
if(isPrime){
print("Your Input Value \(input) is Prime!")
}
}
A couple of solutions that work have been posted, but none of them explain why yours doesn't. Some of the comments get close, however.
Your basic problem is that you take the square root of input, then iterate from 2 to the input checking if the integer part of the square root is divisible by i. You got that the wrong way round. You need to iterate from 2 to the square root and check that the input is divisible by i. If it is, you stop because input is not prime. If you get to the end without finding a divisor, you have a prime.
try this code in playground you will get this better idea and try to use playground when you try the swift as you are not familiar with swift playground is best.
let input = 13 // add your code that take value from textfield
var prime = 1
// throw error less than 2 entered
if input < 2 {
assertionFailure("number should be 2 or greater")
}
// loop from 2 to input iterating by 1
for i in stride(from: 2, to: input, by: 1) {
if input % i == 0{
prime = 0
}
}
if prime == 1 {
print("\(input) number is prime")
} else {
print("\(input) number is not prime")
}

Reducing the number of brackets in Swift

Does anyone know if there is a way to use some kind shorthand in swift? more specifically, leaving out the braces in things like IF statements... eg
if num == 0
// Do something
instead of
if num == 0
{
// Do something
}
Those braces become rather space consuming when you have a few nested IF's.
PS. I do know I can do the following:
if num == 0 {
// Do something }
But I'm still curious if that sort of thing is possible
You can do that :
let x = 10, y = 20;
let max = (x < y) ? y : x ; // So max = 20
And so much interesting things :
let max = (x < y) ? "y is greater than x" : "x is greater than y" // max = "y is greater than x"
let max = (x < y) ? true : false // max = true
let max = (x > y) ? func() : anotherFunc() // max = anotherFunc()
(x < y) ? func() : anotherFunc() // code is running func()
This following stack : http://codereview.stackexchange.com can be better for your question ;)
Edit : ternary operators and compilation
By doing nothing more than replacing the ternary operator with an if else statement, the build time was reduced by 92.9%.
https://medium.com/#RobertGummesson/regarding-swift-build-time-optimizations-fc92cdd91e31#.42uncapwc
In swift you have to add braces even if there is just one statement in if:
if num == 0 {
// Do something
}
You cannot leave the braces, that how swift if statement work.
You could use a shorthand if statement like you would in objective-c:
num1 < num2 ? DO SOMETHING IF TRUE : DO SOMETHING IF FALSE
Swift 2.0 update
Method 1:
a != nil ? a! : b
Method 2: Shorthand if
b = a ?? ""
Referance: Apple Docs: Ternary Conditional Operator
and it does work,
u.dob = (userInfo["dob"] as? String) != nil ? (userInfo["dob"] as! String):""
I am replacing a json string with blank string if it is nil.
Edit: Adding Gerardo Medina`s suggestion...we can always use shorthand If
u.dob = userInfo["dob"] as? String ?? ""
It is called shorthand if-else condition. If you are into iOS development in Swift, then you can also manipulate your UI objects' behaviour with this property.
For e.g. - I want my button to be enabled only when there is some text in the textfield. In other words, should stay disabled when character count in textfield is zero.
button.enabled = (textField.characters.count > 0) ? true : false
its very simple :
in Swift 4
playButton.currentTitle == "Play" ? startPlay() : stopPlay()
Original Code is
if playButton.currentTitle == "Play"{
StartPlay()
}else{
StopPlay()
}
You could always put the entire if on one line:
if num == 0 { temp = 0 }