Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

iOS Swift 2.0 Functions Function Parameters Returning Complex Values

Amy Nicholson
Amy Nicholson
783 Points

stuck swift code challenge tuple

Not sure how to write this, the challenge requests a tuple.

functions.swift
func getTowerCoordinates(location: String) -> (Double, Double) {

    switch location {
    case "Eiffel Tower": (lat: 48.8582, lon: 2.2945)
    case "Great Pyramid": (lat: 29.9792, lon: 31.1344)
    case "Sydney Opera House": (lat: 33.8587, lon: 151.2140)
    default: (lat: 0, lon: 0)
    }

    return (lat, lon)
}

getTowerCoordinates("Eiffel Tower")

5 Answers

Martin Wildfeuer
PLUS
Martin Wildfeuer
Courses Plus Student 11,071 Points

In your return statement you are trying to return the variables lat and lon. The problem is, those variables don't exist as they have not been defined anywhere outside the switch statement. In the switch statement however, you are just creating tuples without assigning them. The lat long in your tuples are actually labels, not variables.

So let's go through this step by step:

1. Variables and constants have a scope

Variables or constants you define inside case can be neither accessed outside the switch statement, nor are they shared between the different cases. Any variable defined in a case, does only live in this scope. Consider this example:

switch location {
case "Eiffel Tower":
    // Variables / constants defined in a case
    // are only available in this scope
    let test = "test"
    print(test) // Prints "test"
default:
    // Compiler won't complain here, as this is a new scope and
    // we are not defining test again
    let test = "test"
}

// This will not compile, as test is not defined here.
print(test) 

So if you wanted this to work, it would have to look like this:

var test = ""

switch location {
case "Eiffel Tower":
    test = "case Eiffel Tower"
default:
    test = "Default"
}

print(test) // prints out, depending on what location is, the corresponding string

To sum it up: If you want to change or assign a value in a switch statement, it has to defined, that is, created before.

2. You are not assigning your tuples
case "Eiffel Tower": (lat: 48.8582, lon: 2.2945)

You are not assigning this tuple to anything, you are just creating it. lat and lon are not variable names, but labels. Although you can do this, for this example get rid of those. Given the example before, if you wanted to assign this to a variable outside the switch statement, it would look like this:

var test: (Double, Double)

switch location {
case "Eiffel Tower":
    test = (48.8582,  2.2945)
default:
    test = (0, 0)
}

print(test) // Prints out the corresponding tuple

In a function, you can return a value any time at any point. It is possible to have multiple return statements, so you don't necessarily need to assign it to a variable anyhow, you can return it straight away, code below return will never be executed:

func getTowerCoordinates(location: String) -> (Double, Double) {
    switch location {
    case "Eiffel Tower": return (48.8582, 2.2945)
    case "Great Pyramid": return (29.9792, 31.1344)
    case "Sydney Opera House": return  33.8587, 151.2140)
    default: return (0, 0)
    }
}

getTowerCoordinates("Eiffel Tower") // (48.8582, 2.2945)
getTowerCoordinates("Eiffel Tower").0 // 48.8582
getTowerCoordinates("Eiffel Tower").1 //  2.2945

In fact, I have to say I do like the approach with only one single return statement better. So the same thing could look like this:

func getTowerCoordinates(location: String) -> (Double, Double) {

    var latLon = (0.0, 0.0) // We can already set a default value here

    switch location {
    case "Eiffel Tower":
        latLon = (48.8582, 2.2945)
    case "Great Pyramid":
        latLon = (29.9792, 31.1344)
    case "Sydney Opera House":
        latLon = (33.8587, 151.2140)
    default: break // If we end up here, lat lon already is (0.0, 0.0), nothing to do here ;)
    }

    return latLon
}

Phew, I know this was a lot information! If you don't understand these concepts, I strongly encourage you to watch the videos again, that will make it much easier :)

Jennifer Nordell
seal-mask
STAFF
.a{fill-rule:evenodd;}techdegree
Jennifer Nordell
Treehouse Teacher

It actually looks ok except that you don't need the lat or the lon. These haven't actually been declared in the code that we can see in the challenge. I know that they list it that way, and I'm not sure why. That's why you get the "undeclared identifier", because you're using something not previously defined.

func getTowerCoordinates(location: String) -> (Double, Double) {
  switch location {
    case "Eiffel Tower":
      return (48.8582, 2.2945)
    case "Great Pyramid":
      return (29.9792, 31.1344)
    case "Sydney Opera House":
      return (33.8587, 151.2140)
    default:
      return (0,0)
  }  
}
Amy Nicholson
Amy Nicholson
783 Points

Martin - thank you for all that info. Some of it makes my brain hurt (just cause I'm getting in too deep, being a newbie to programming) ... but... I think your last solution, with the single return, is what I was originally trying to do. Thanks again.

Martin Wildfeuer
Martin Wildfeuer
Courses Plus Student 11,071 Points

You are welcome :) This assignment covers a lot of Swift concepts, it is based on all previous courses, so, yes, there's a lot going on here. No worries if you don't understand everything yet, I know this can be overwhelming :)

Amy Nicholson
Amy Nicholson
783 Points

Yes, it is. And I am not really sure why I am doing it, other than I keep telling myself I want to learn programming, and I now have the time. I think the course, for me, moves too quickly through. Perhaps extra practice challenges can be added, for those who need them. One challenge per concept does not seem to be enough.

Martin Wildfeuer
Martin Wildfeuer
Courses Plus Student 11,071 Points

Swift is definitely a good language to start, though it's never easy, of course. If you find the courses are moving to fast, don't hesitate to post this in the forums, mentioning the author name with the @ sign. Moderators in this forum are not part of the staff, just students like you, so it's important to hear your feedback :)

Amy Nicholson
Amy Nicholson
783 Points

Thanks Martin! (Thought you were staff ...) Thanks for all your help.