PA 2.1: Classy City¶

No description has been provided for this image No description has been provided for this image

CEGM1000 MUDE: Week 2.1. Due: complete this PA prior to class on Friday, Nov 15, 2024.

As a smart, young capable engineer with a wealth of Python skills, you have been recruited by a venture capital firm to make a huge financial profit by setting up a series of high quality food and beverage establishments in a brand new town in the Netherlands, Petaluma. The town will be home to a brand new Technical University and the location of the student houses has already been confirmed. In fact, they have been laid out in a triangular grid, each equal distance apart, in order to minimize the noise and disruption to the non-student citizens of Petaluma. The task at hand is to find the coordinates of the optimal locations of the food and beverage establishments so that the venture capital firm knows which buildings to purchase.

The conditions are:

  • the coordinates of the student houses are known and are laid out as a grid of equilateral triangles
  • the venture capital firm would like to start by looking at two types of establishments: bars and kapsalon shops
  • as it is important to keep the bars close to as many student houses as possible
  • as students get hungry after visiting the bars, it is important to keep the kapsalon shops close to as many bars as possible
  • therefore, you can assume the optimal location of the bars and shops are on a grid that is equal distance from the student houses and bars, respectively
  • the venture capital firm will want to reuse the analysis tool for investments in other cities around the world, so re-use of the code is essential

Fortunately, some Python code in city.py has already been written for you, and you only need to modify it to complete the analysis. The steps to complete this assignment are thus:

  1. Familiarize yourself with the student houses and the provided class Plan.
  2. Use the code to define "triangles" (regions between student houses).
  3. Modify the methods in the class Plan to find the locations of the bars and kapsalon shops.

Hint: before starting it may be useful to make a quick sketch by hand of where the three types of buildings are located in the X-Y plane. Note also that this will be very much analogous to the unstructured mesh that we will use to solve our modelling exercises in Week 2.1.

NOTE:

The cell below allows you to edit the contents of helper and incorporate the changes in the notebook without restarting the kernel.

Keep in mind, however, that error messages do not always display properly when using this feature; if you find that the Python traceback does not make sense while doing this assignment you should restart the kernal!

In [ ]:
%load_ext autoreload
%autoreload 2

import numpy as np
import matplotlib.pyplot as plt

Part 1: Getting Started¶

First we will need to familiarize ourselves with the student houses and the provided class Plan.

If you don't remember anything about Python classes remember to review the book chapter from Week 1.7 on OOP

Task 1.1:

First take a couple minutes to open the file city.py and read the contents. We will refer back to this file many times, so at this stage it is only necessary to look at the init method to see how the class can be instantiated, as well as scrolling through the file to get an overview for the (many!) and various types of methods that have been implemented.

Once you have read through the file, run the cell below to import the class.

In [ ]:
from city import *

If you read through the file closely, you will realize that we need two inputs to instantiate the class: coordinates and side_length. This is the way the location of the student houses are defined.

Task 1.2:

The cell below defines the coordinates of the student houses, all of which are spaced 2 units apart. Use this information to instantiate the class.

In [ ]:
coordinates = np.array(
              [[7.000, 1.000],
               [4.000, 2.732],
               [3.000, 1.000],
               [5.000, 1.000],
               [3.000, 4.464],
               [1.000, 4.464],
               [6.000, 2.732],
               [1.000, 1.000],
               [7.000, 4.464],
               [2.000, 2.732],
               [5.000, 4.464]])

my_plan = Plan(YOUR_CODE_HERE, YOUR_CODE_HERE)

Great, now we are ready to plan our city! To get an idea for what the layout of the city looks like, a method has already been included in the class to help you visualize it.

Task 1.3:

Visualize the layout of student houses by using the method plot_coordinates.

Note: throughout this entire assignment you will be expected to look through the contents of city.py and really read the contents in order to understand how to use the class Plan.

In [ ]:
YOUR_CODE_HERE

Part 2: Use the code to define "triangles" (regions between student houses).¶

Now that we are familiar with the class and the student house locations, we can start preparing the analysis. The first step is to recognize that we need to have a way to define the relationship between the points geometrically, as an arbitrary collection of coordinates does not allow us to evaluate the problem in a structured way. We will do this by defining triangles to represent the area defined by every set of three student houses.

To define a triangle, we will use a Python list in the following form:

[[a, b, c],
 [a, b, c],
  ...
  [a, b, c]]

Where:

  • the list contains N lists, and N is the total number of triangles (10, in our case)
  • each list within the list defines a triangle
  • a, b and c are integers that define the vertices of each triangle; they are the index of the row of each point in the array coordinate (defined above).

Our main goal in this part is to define all of the triangles that are implied by the layout of the student houses. Some methods are already included in the class to help you implement this correctly.

Task 2.1:

The code below is set up to illustrate how you can use the methods to try out various triangle specifications. Running the cell below will throw and assertion error because it begins with a poorly-defined triangle. Change the vertices of the triangle until you successfully define an equilateral triangle defined by 3 student houses.

There will be some warnings and tips in the output to help with this entire output. For this task you only need to define one triangle.

In [ ]:
my_plan.try_triangles([[0, 1, 2]])

Task 2.2:

Now let's define all of the triangles! Once you have successfully defined all 10 triangles, you will no longer see any error messages and the plot will be filled with green areas between all of the coordinates.

In [ ]:
all_triangles = [YOUR_CODE_HERE]
my_plan.try_triangles(all_triangles)

Task 2.3:

Once you have successfully defined all triangles above, you can add these as an attribute of the class: triangles. Once you read the code in city.py and identify the right attribute to define, the method plot_triangles will work successfully and should produce an identical plot to that in the previous task.

In [ ]:
YOUR_CODE_HERE
my_plan.plot_triangles();

Great, now we have a way to look at the space between each group of student houses! This will be useful for finding the locations of each bar.

Next, it is also going to be useful to have a way to look at the relationship between adjacent triangles...let's call them "shared sides." The class Plan has already been implemented with some features to look at the shared sides. However, first we need to define the syntax for specifying one, which we will do in (another) set of nested lists, as illustrated here:

[[[c1, c2], [t1, t2]],
 [[c1, c2], [t1, t2]],
   ...
 [[c1, c2], [t1, t2]]]

In this case we have a list of lists, where each item in the inner list contains two lists. Whoa, complex! Let's break it down:

  • each item in the outer list represents a single shared side between two triangles
  • within the list for each shared side, there are two lists: the first identifies the two coordinates defining the side and the second identifies the two triangles that share that side
  • c1 and c2 are integers specifying the index of the row in the attribute coordinates
  • t1 and t2 are integers specifying the index of the row in the attribute triangles (what you defined in the previous task)
  • the method plot_shared_sides can illustrate a shared side to help confirm you specify it properly

Let's see if you can specify a shared side!

Task 2.4:

The code cell below defines a shared side and two adjacent triangles incorrectly. Fix it by changing the values of the coordinates and/or triangles!

You can verify you have done it correctly if two adjacent green triangles are highlighted, along with the shared side being highlighted as a red dashed line.

Note: depending on the way in which you defined triangles above, there is a tiny chance the code cell below actually is correct for your case.

In [ ]:
my_plan.plot_shared_sides([[[9, 2], [3, 8]]]);

Task 2.5:

Now let's define all of the shared sides! Once you have successfully done so, you will no longer see any error messages and the plot will be filled with green green triangles and red dashed shared sides.

In [ ]:
sides = [YOUR_CODE_HERE] # remember to use format [[[a, b], [c, d]], ... ]
my_plan.plot_shared_sides(sides);

Task 2.6:

Once you have successfully defined all shared sides above, you can add these as an attribute of the class: shared_sides. If the plotting function succesfully runs without arguments (as written below), it confirms you did it correctly.

In [ ]:
YOUR_CODE_HERE
my_plan.plot_shared_sides();

Part 3: Modify the Class Plan¶

Now that we are familiar with the class, we are ready to modify the methods in Plan to find the locations of the bars and kapsalon shops. This means you will have to edit the file city.py!

If you are unsure of what to do in this part, remember that a lot of information was provided at the top of this notebook!

Task 3.1:

Complete the method get_bar_coordinates to find the optimal location of the bars. Note that there are many ways to do this; our suggestion is to first identify the key calculation that should be made and how it relates to each triangle. Then implementing the calculation can be accomplished with a simple loop.

You can check your work by executing the cell below, which will return errors and warnings until a plot with the correct points is produced.

In [ ]:
my_plan.get_bar_coordinates()
my_plan.plot_everything();

Task 3.2:

Complete the method get_kapsalon_coordinates to find the optimal location of the kapsalon shops. As with the bars, there are many ways to do this; this time you should consider how to take advantage of the shared sides defined earlier.

You can check your work by executing the cell below, which will return errors and warnings until a plot with the correct points is produced.

In [ ]:
my_plan.get_kapsalon_coordinates()
my_plan.plot_everything();

End of notebook.

Creative Commons License TU Delft MUDE

By MUDE Team © 2024 TU Delft. CC BY 4.0. doi: 10.5281/zenodo.16782515.