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 trialSebastian Shelley
1,388 PointsHaving trouble understanding parts of the method.
Hi guys, i'm having trouble understanding this part of the video.
for xCoord in (x-range)...(x+range) {
for yCoord in (y-range)...(y+range)
I understand the for loop's but how I don't understand how it iterates correctly. (x-range and x+range) If I change the parameters to
let coordinatePoint = Point(x: 1, y: 1)
instead of
let coordinatePoint = Point(x: 2, y: 2)
Shouldn't the iterations change to 0-2? instead of 1-3? as it's x-range and y+range?
Also if somebody could please explain this line of code in more detail that would be great.
let coordinatePoint = Point(x: xCoord, y: yCoord)
For example, why am I creating an instance inside the forloop? Didn't we call this instance outside the for loop here:
let coordinatePoint = Point(x: 1, y: 1)
Thanks Guys.
2 Answers
Corey F
Courses Plus Student 6,450 PointsI’m not sure if I’m 100% grasping your questions.
When I plug in
let coordinatePoint = Point(x: 1, y: 1)
coordinatePoint.surroundingPoints()
The iterations DO change to values between 0-2 for both x and y. The results I get are
(x,y) = [{x 0, y 0}, {x 0, y 1}, {x 0, y 2}, {x 1, y 0}, {x 1, y 1}, {x 1, y 2}, {x 2, y 0}, {x 2, y 1}, {x 2, y 2}]
As to your question for this line of code
Why does it exist? When we have a similar line of code outside?
let coordinatePoint = Point(x: 1, y: 1)
We could make this this and it would still work
let Awesome = Point(x: 1, y: 1)
Awesome.surroundingPoints()
Remember not only is this line of code outside our for loop. It is also outside our struct. Remember everything in a struct is a blueprint.
Architects use blueprints as plans to create a building. In the same way coders use structs as plans to create an object.
So when we use the above line of code outside the struct we are creating an instance from our blueprint. The same way an architect creates a building from his blueprint.
AFTER we create an instance, we have something real to work with. Before that line of code all we have are plans.
In the code our struct “blueprint” is just saying. Here’s a plan to create an object with an x and y co-ordinate. When we do create that object here’s a plan (an instance method) to tell us some points that surround it.
Creating an object outside the blueprint is what’s called creating an instance.
So what does this line of code do?
let coordinatePoint = Point(x: xCoord, y: yCoord)
Well it’s part of an instance method. A function is sequence of instructions that perform a very specific task packaged up as a unit. A method is any function that is associated with a particular type.
An instance method is one that can only be called once we have an actual instance.
So let’s say our architect has plans. He plans to build a building. After he builds the building he has instructions on how to figure out what other buildings surround his building.
We use our instance method on our metaphorical building to find what “buildings” or points surround it.
You can’t find buildings around a building that doesn’t exist.
That’s why we need an instance outside our blueprint.
Now the line of code while it looks similar, has nothing to do with the other line of code. It’s completely different. Again, we could make our code here with the constant coordinatePoint1A and it would still work.
struct Point {
let x: Int
let y: Int
init(x: Int, y: Int) {
self.x = x
self.y = y
}
func surroundingPoints(withRange range: Int = 1) -> [Point]
{
var results: [Point] = []
for xCoord in (x-range)...(x+range) {
for yCoord in (y-range)...(y+range) {
let coordinatePoint1A = Point(x: xCoord, y: yCoord)
results.append(coordinatePoint1A)
}
}
return results
}
}
let coordinatePoint = Point(x: 1, y: 1)
coordinatePoint.surroundingPoints()
What this says is if we ever create a point, say (1,1) (which we do create later on in the example above). We will generate points around it by doing the following.
- Our real “building” point (our instance) will give us x and y to be used. e.g. (x: 1, y: 1)
- We take a range of 1 (withRange range: Int = 1)
with a point (1,1) xCoord is values of 0 to 2 as per xCoord in (x-range)...(x+range) (1-1) … (1+1)
then on each x value in the range we have y values of 0 to 2 for the same reason.
We create points each time assigned to a constant coordinatePoint1A ,
let coordinatePoint1A = Point(x: xCoord, y: yCoord)
results.append(coordinatePoint1A)
and during each iteration of the loop we append coordinatePoint1A to our results array we set up earlier in the instance method
var results: [Point] = []
Again this only works on a real “building” that has co-ordinates. Before that all this is, is the method we will use. We make that building and figure out what surrounds it here
let coordinatePoint = Point(x: 1, y: 1)
coordinatePoint.surroundingPoints()
Again this is a confusing concept. Ask more questions if you need clarification.
Corey F
Courses Plus Student 6,450 PointsWe don't really create an instance in the for loop when we write the code. Or at least don't think of it that way. Until we call upon the instance method... it's just a bunch of directions.
Why? The line of code there relies on an instance and generates points from it.
Why is it a constant? Good question.
Think of it this way.
When we generate a point in the for loop we do it to get an array of points around a "building". Each point in that array is not to be changed. We want each point to be a constant.
We need a list of fixed points right?
Each time the for loop runs on the inside we start with a blank slate.
I think you get it since you said that coordinatePoint is constantly being created. If we we're using a variable we'd be changing what was already created.
We do not mutate coordinatePoint. We simply create it each time, and use it to assign to an array each time. If we mutated it, we couldn't get a list of fixed points. We'd just end up with a single point that kept changing.
We create it, assign it to the array, it no longer exists, the loop runs again.
NOW! The array (outside of the loop) is a variable.
var results: [Point] = []
Why?
Because we do continue to change it. Each time the for loop runs we modify it (*append it), with an additional fixed point.
Sebastian Shelley
1,388 PointsThanks a lot that really helped! :)
Sebastian Shelley
1,388 PointsSebastian Shelley
1,388 PointsGreat answer! Thanks for all the help. I'm still trying to understand why we create an instance inside the for loop. I understand why it's created outside the struct, but why inside still baffles me. But i'm sure I will figure it out in time.
I do have one question about the instance method. Shouldn't coordinatePoint be a variable and not a constant since each time around the loop the values change?
let coordinatePoint = Point(x: xCoord, y: yCoord)
Outside the struct it makes sense because it's only be creating once, but inside the loop isn't it being constantly created?
Morten Larsen
12,275 PointsMorten Larsen
12,275 PointsCorey F,
Thanks a million taking your time to explain this. One of the best answers I ever read! Thank You!