That wasn't so bad, now was it? Now, let's take a look at my solution: ```coconut def diagonal_line(n) = range(n+1) |> map\$(i -> (i, n-i)) ``` Pretty simple, huh? We take `range(n+1)`, and use `map` to transform it into the right sequence of tuples. ### `linearized_plane` Now that we've created our diagonal lines, we need to join them together to make the full linearized plane, and to do that we're going to write the function `linearized_plane()`. `linearized_plane` should produce an iterator that goes through all the points in the plane, in order of all the points in the first `diagonal(0)`, then the second `diagonal(1)`, and so on. `linearized_plane` is going to be, by necessity, an infinite iterator, since it needs to loop through all the points in the plane, which have no end. To help you accomplish this, remember that the `::` operator is lazy, and won't evaluate its operands until they're needed, which means it can be used to construct infinite iterators. When you're ready to move on, scroll down. Tests: ```coconut # Note: these tests use \$[] notation, which we haven't introduced yet # but will introduce later in this case study; for now, just run the # tests, and make sure you get the same result as is in the comment linearized_plane()\$ |> print # (0, 0) linearized_plane()\$[:3] |> list |> print # [(0, 0), (0, 1), (1, 0)] ``` _Hint: instead of defining the function as `linearized_plane()`, try defining it as `linearized_plane(n=0)`, where `n` is the diagonal to start at, and use recursion to build up from there._

That was a little bit rougher than the first one, but hopefully still not too bad. Let's compare to my solution: ```coconut def linearized_plane(n=0) = diagonal_line(n) :: linearized_plane(n+1) ``` As you can see, it's a very fundamentally simple solution: just use `::` and recursion to join all the diagonals together in order. ### `vector_field` Now that we have a function that builds up all the points we need, it's time to turn them into vectors, and to do that we'll define the new function `vector_field()`, which should turn all the tuples in `linearized_plane` into vectors, using the n-vector class we defined earlier. Tests: ```coconut # You'll need to bring in the vector class from earlier to make these work vector_field()\$ |> print # vector(*pts=(0, 0)) vector_field()\$[2:3] |> list |> print # [vector(*pts=(1, 0))] ``` _Hint: Remember, the way we defined vector it takes the components as separate arguments, not a single tuple. You may find the [Coconut built-in `starmap`](./DOCS.md#starmap) useful in dealing with that._

Here's my solution for you to check against: ```coconut def __truediv__(self, other) = self.pts |> map\$(x -> x/other) |*> vector ``` ### `.unit` Next up, `.unit`. We're going to write a `unit` method that takes just `self` as its argument and returns a new vector the same size as `self` with each element divided by the magnitude of `self`, which we can retrieve with `abs`. This should be a very simple one-line function. Tests: ```coconut vector(0, 1).unit() |> print # vector(*pts=(0.0, 1.0)) vector(5, 0).unit() |> print # vector(*pts=(1.0, 0.0)) ```

Here's my solution: ```coconut def unit(self) = self / abs(self) ``` ### `.angle` This one is going to be a little bit more complicated. For starters, the mathematical formula for the angle between two vectors is the `math.acos` of the dot product of those vectors' respective unit vectors, and recall that we already implemented the dot product of two vectors when we wrote `__mul__`. So, `.angle` should take `self` as the first argument and `other` as the second argument, and if `other` is a vector, use that formula to compute the angle between `self` and `other`, or if `other` is not a vector, `.angle` should raise a `MatchError`. To accomplish this, we're going to want to use destructuring assignment to check that `other` is indeed a `vector`. Tests: ```coconut import math vector(2, 0).angle(vector(3, 0)) |> print # 0.0 print(vector(1, 0).angle(vector(0, 2)), math.pi/2) # should be the same vector(1, 2).angle(5) # MatchError ``` _Hint: Look back at how we checked whether the argument to `factorial` was an integer using pattern-matching._