Stuck On Skyroute Graph Search

Project link:
https://www.codecademy.com/courses/learn-data-structures-and-algorithms-with-python/projects/skyroute-graph-search

My code:

from graph_search import bfs, dfs
from vc_metro import vc_metro
from vc_landmarks import vc_landmarks
from landmark_choices import landmark_choices

# Build your program below:
landmark_string = ""
stations_under_construction = ["Richmond-Brighouse"]

for letter, landmark in landmark_choices.items():
  landmark_string += f"{letter}: {landmark}\n"

def greet():
  print("Hi there and welcome to SkyRoute!")
  print(f"We'll help you find the shortest route between the following Vancouver landmarks:\n{landmark_string}.")

def skyroute():
  greet()
  new_route()
  goodbye()

def set_start_and_end(start_point, end_point):
  if start_point is not None:
    change_point = input("What would you like to change? You can enter 'o' for 'origin', 'd' for 'destination', or 'b' for 'both'.")
    if change_point == "b":
      start_point = get_start()
      end_point = get_end()

    elif change_point == "o":
      start_point = get_start()

    elif change_point == "d":
      end_point = get_end()

    else:
      print("Oops, that isn't 'o', 'd', or 'b'...")
      set_start_and_end(start_point, end_point)

  else:
    start_point = get_start()
    end_point = get_end()
    return start_point, end_point

def get_start():
  start_point_letter = input("Where are you coming from? Type in the corresponding letter: ")

  if start_point_letter in landmark_choices:
    start_point = landmark_choices[start_point_letter]
    return start_point

  else:
    print("Sorry, that's not a landmark we have data on. Let's try this again...")
    return get_start()

def get_end():
  end_point_letter = input("Ok, where are you headed? Type in the corresponding letter: ")

  if end_point_letter in landmark_choices:
    end_point = landmark_choices[end_point_letter]

  else:
    print("Sorry, that's not a landmark we have data on. Let's try this again...")
    return get_end()

def new_route(start_point = None, end_point = None):
  start_point, end_point = set_start_and_end(start_point, end_point)
  shortest_route = get_route(start_point, end_point)

  if shortest_route:
    shortest_route_string = "\n".join(shortest_route)

  else:
    print(f"Unfortunately, there is currently no path between {start_point} and {end_point} due to maintainance")
    print(f"The shortest metro route form {start_point} to {end_point} is: {shortest_route_string}.")
  again = input("Would you like to see another route? Enter y/n: ")

  if again == "y":
    show_landmarks()
    new_route(start_point, end_point)

def get_route(start_point, end_point):
  start_stations = vc_landmarks[start_point]
  end_stations = vc_landmarks[end_point]
  routes = []

  for start_station in start_stations:
    for end_station in end_stations:
      metro_system = get_active_stations() if stations_under_constructions else vc_metro

      if stations_under_construction:
        possible_route = dfs(metro_system, start_station, end_station)
        if not possible_route:
          return None

      route = bfs(metro_system, start_station, end_station)
      
      if route:
        routes.append(route)

  shortest_route = min(routes, key = len)
  return shortest_route

def show_landmarks():
  see_landmarks = input("Would you like to see the list of landmarks again Enter y/n: ")
  if see_landmarks == "y":
    print(landmark_string)

def goodbye():
  print("Thanks for using SkyRoute!")

def get_active_stations():
  updated_metro = vc_metro
  for station in stations_under_construction:
    for current_station, neigh_boring_stations in vc_metro.items():
      if current_station != stations_under_construction:
        updated_metro[current_station] -= set(stations_under_construction)

      else:
        updated_metro[current_station] = set([])

  return updated_metro

print(skyroute())

Error:


Why is the error there?

A key error suggests you’ve attempted to access a dictionary using a key that doesn’t exist-

dct = {}
dct["key"]  # this would be a KeyError

If you follow your stack trace given on the right it should lead you to the line where this occurred.

I knew that but why does this line end with a KeyError and how?

It says the key error is None.
If you want to see vc_landmarks, here it is:
vc_landmarks.py:

vc_landmarks = { 'Marine Building': set(['Burrard', 'Waterfront']), 'Scotiabank Field at Nat Bailey Stadium': set(['King Edward']), 'Vancouver Aquarium': set(['Burrard']), 'Vancouver Lookout': set(['Waterfront']), 'Canada Place': set(['Burrard', 'Waterfront']), 'Cathedral of Our Lady of the Holy Rosary': set(['Vancouver City Centre', 'Granville']), 'Library Square': set(['Vancouver City Centre', 'Stadium-Chinatown']), 'B.C. Place Stadium': set(['Stadium-Chinatown']), 'Lions Gate Bridge': set(['Burrard']), 'Gastown Steam Clock': set(['Waterfront']), 'Waterfront Station': set(['Waterfront']), 'Granville Street': set(['Granville', 'Vancouver City Centre']), 'Pacific Central Station': set(['Main Street-Science World']), 'Prospect Point Lighthouse': set(['Burrard']), 'Queen Elizabeth Theatre': set(['Stadium-Chinatown']), 'Stanley Park': set(['Burrard']), 'Granville Island Public Market': set(['Yaletown-Roundhouse']), 'Kitsilano Beach': set(['Olympic Village']), 'Dr. Sun Yat-Sen Classical Chinese Garden': set(['Stadium-Chinatown']), 'Museum of Vancouver': set(['Yaletown-Roundhouse']), 'Science World': set(['Main Street-Science World']), 'Robson Square': set(['Vancouver City Centre']), 'Samson V Maritime Museum': set(['Columbia']), 'Burnaby Lake': set(['Sperling / Burnaby Lake', 'Lake City Way', 'Production Way / University']), 'Nikkei National Museum & Cultural Centre': set(['Edmonds']), 'Central Park': set(['Patterson', 'Metrotown']) }

It’s about the keys you are attempting to access. The KeyError means it’s a key that doesn’t currently exist in that dictionary. Double check where you’re attempting to access this dictionary as you’re trying to access a key it simply doesn’t have, the error tells you what the key you attempted to use was, in this case None.

3 Likes

It’s because I used the default value for end_point which called the get_route function

, which called this with None

.
I should follow the path from how it took None as the end_point.

1 Like

Python’s stack traces are great. It takes a little getting used to them but they are remarkably helpful for locating errors since they follow a series of execution frames https://docs.python.org/3/reference/executionmodel.html#structure-of-a-program making it much easier to trace an error backwards through more than one code block.

1 Like

How do I get stack traces? What are they?

Now I get it, it called new_route() with both Nones which called get_route() which called this:

which is called with None which results in a key error. I should not use the default arguments for new_route(). The project told me to call new_route() with no arguments.
Look:


It says just to call new_route() with no arguments. Now, what arguments should I pass in?
I’m very confused! :thinking: I have almost no idea! I need to pass in the arguments not Nones but in I don’t know how to properly reach the start point and end point since they’re asked in other functions that are called in new_route().

Now, this is confusing.