UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

Help required with Checkpoint 4

Forums > 100 Days of SwiftUI

Can anyone help me with my code for Checkpoint 4?

Swift is telling me I need to include a return in my function, but I already have one. Do I have it in the wrong place? What else have I done wrong?

Appreciate any advice.

Andrew

My code

1      

Hint 1:
I wanted to copy your code into Playgrounds and give it a go. Instead, because you used a graphic, I had to retype your code. Please use the code tags next time!

Hint 2:
if number is 32...your code will process what?

  1. 1 x 1 is not 32. (FAIL the IF test. )
  2. 1 is NOT less than 1 nor is it greater than 10_000 (FAIL the ElseIf test)
  3. throw noRoot error? <--- Is this what you want to happen?

Hint 3:
Put your boundary tests first. Don't even get into a loop if your entry value fails the boundary tests. I liken the guard statement to guards at a gate. If your input values can't provide proper credentials, don't even let them in the castle.

Hint 4:
Variable names should start with lowercase letters. Also try to give them specific names.

Number may not be a good name for your variable. Swift actually has a class named Number. What are you referencing in your code? A parameter named Number? or the Swift class named Number? See the confusion? Plus it's uppercased. Class names start with uppercased letters. Variables, by convention, start with lowercased letters. potentialRoot may be a better choice?

Refactor your code, you might get better results! If not repost your code here, using the code tags, of course.

2      

Thanks for your reply @Obelix. Here's my revised code.

enum squareRootError: Error {
case outOfBounds, noRoot
}

func squareRoot (_ potentialRoot:Int) throws -> String {
if potentialRoot < 1 || potentialRoot > 10_000 {
    throw squareRootError.outOfBounds
}
for i in 1...100 {
    if potentialRoot == i * i {
        return "The square root of \(potentialRoot) is \(i)"
    }
}
for i in 1...100 {
    if potentialRoot != i * i {
        throw squareRootError.noRoot
    }
}
return ""
}

let test = 82
do {
let result = try squareRoot(test)
print((result))
}
catch squareRootError.outOfBounds{
print("Number out of bounds")
} catch squareRootError.noRoot {
print("Couldn't find the square root")
} catch {
print("There was an error")
}

It now works, but I'm still left with my original question. Why did I have to return a blank string (or any other string for that matter) to get it to work when I was already returning a string in the if?

Grateful for any response.

Andrew

1      

Andrew is asking the right questions! He asked:

It now works, but I'm still left with my original question. Why did I have to return a blank string (or any other string for that matter) to get it to work when I was already returning a string in the if?

Return Type is String

You declared your function must return a String. The compiler will complain if you don't.

What gets returned here if girlfriend's age is 42?

func girlFriendsAge() -> String {
    if girlFriendsAge < 30 {
        return "My lady is still young."
    }
}

Answer is nothing is returned. So the compiler will complain. To fix, you might return a blank string?

func girlFriendsAge() -> String {
    if girlFriendsAge < 30 {
        return "My lady is still young."
    }
    return ""   // <----- Not ideal, but make the compiler happy.
}

In short, none of your IF statements have else clauses. The compiler rightly notes that each of them might fail causing your function to end without returning a String.

1      

Refactoring

Take a look at this section of code:

for i in 1...100 {
    if potentialRoot == i * i {
        return "The square root of \(potentialRoot) is \(i)"
    }

    // if you loop through ALL 100 integers without finding a true root
    // you end up right here....  
    print("Why did you end up here? What can you conclude?")
    // What can you conclude about your original number and potential roots?
    // What might you THROW here ?
}

1      

Naming Variables

+1 for updating variable names. But you missed an opportunity.

Your user wants to find the square root of some number. Let's call that: targetNumber
Code grinds through 100 numbers in a brute force function to find a square root. Let's call each attempt: thePotentialRoot

See if this is clearer to future you?

// Find the square root of a target number.
func squareRoot (_ targetNumber:Int) throws -> String {
    // Nice! Guard the castle. Don't even try if targetNumber is out of bounds.
     if targetNumber < 1 || targetNumber > 10_000 {
        throw squareRootError.outOfBounds
     }

// Does this read better?
// Will future you understand the logic here?
for thePotentialRoot in 1...100 {
    if targetNumber == thePotentialRoot * thePotentialRoot {
        return "The square root of \(targetNumber) is \(thePotentialRoot)"
    }
}

Get in the habit of using descriptive variable names. XCode's code completion helps you, because you won't have to type out long names; it will do that for you. But future you will appreciate you using descriptive names.

CS193p Memorize

If you have a look at Paul Hagerty's Swift course at Stanford University (CS193p), in his lecture for his card matching game he creates an index named: indexOfTheOneAndOnlyFaceUpCard The point he makes in the lecture is that during game play, the tableau can have a state where the player has flipped over just one card. The matching function needs to know WHICH card on the table is currently face up. He could have used just i, or index, but he gives a good sermon on WHY it should have a longer descriptive name. It's Jedi level.

The whole series is excellent and adds perspective to @twostraws' excellent lectures. For convenience, here's the part where CS193p talks about descriptive variable names.

Jump to 01:12:00 > Memorize Game Logic

1      

Hacking with Swift is sponsored by RevenueCat

SPONSORED Take the pain out of configuring and testing your paywalls. RevenueCat's Paywalls allow you to remotely configure your entire paywall view without any code changes or app updates.

Learn more here

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.