联系方式

  • QQ:99515681
  • 邮箱:99515681@qq.com
  • 工作时间:8:00-23:00
  • 微信:codinghelp

您当前位置:首页 >> Python编程Python编程

日期:2019-05-28 10:43

FILE: skyroute.py

Introduction

Vancouver’s public metro system has asked you to help create a program to help commuters get from one

landmark to another. You’ll be building out “SkyRoute,” a routing tool that uses breadth-first search, depthfirst

search, and Python dictionaries to accomplish this feat. For the purposes of this project, you can assume

that it takes the same amount of time to get from each station to each of its connected neighboring stations.

First, tab through the files you have at your disposal:

graph_search.py has the bfs() and dfs() functions implemented in Python

vc_metro.py contains a graph of all stations in the Vancouver metro system

vc_landmarks.py contains a dictionary of Vancouver landmarks mapped to their nearest metro

station(s)

landmark_choices.py contains a dictionary of letters of the alphabet mapped to landmarks to make it

easier for users to make a selection

We import the files listed above here.

In [1]:

import graph_search

import vc_metro

import vc_landmarks

import landmark_choices

First, define a variable that we’ll be using throughout our program:

landmark_string should be a string that joins all of the landmarks together, each with its corresponding

letter of the alphabet from landmark_choices on a new line.

In [ ]:

Below landmark_string , define a function greet() with no parameters. In the function body, print out

two statements:

"Hi there and welcome to SkyRoute!"

"We'll help you find the shortest route between the following Vancouver landmarks:\n" + landmark_string

See how that landmark_string already came in handy?

In [ ]:

Outside of greet() , define a new function skyroute() which will contain our full program. It won’t take

any parameters. Inside, call greet() .

Great! Now, try calling skyroute() at the bottom of the file, save your code, and enter python3

skyroute.py in your console to see what happens.

In [ ]:

Let’s jump out of the skyroute() function body and define a few new functions. Add pass into the function

body for each for the moment.

First, set_start_and_end() , which takes two parameters: start_point and end_point . This will

handle setting the selected origin and destination points.

Next, get_start() , which takes no parameters. It will be used to request an origin from the user.

Finally, get_end() , which is also void of parameters. Can you guess how it will be used?

In [ ]:

In the function body of set_start_and_end() , remove pass and check if start_point has a value other

than None . If it does, we already have an origin and destination, but the user wants to make a change.

Luckily, we’re prepared for that!

Collect input from the user using the following question and assign the response to a new variable

change_point:

"What would you like to change? You can enter 'o' for 'origin', 'd' for 'destination',

or 'b' for 'both': "

In [ ]:

Before we handle change_point , add an else condition in case no start_point has been set yet.

Inside the else condition:

set start_point equal to get_start()

set end_point equal to get_end()

Below the else condition (outside of it, but still inside the function), employ multiple return to return

both start_point and end_point from the function.

In [ ]:

Now let’s get back into that if statement and tackle change_point. Below your definition of change_point ,

we’ll add a little control flow to handle the input:

If change_point is equal to "b" , then reset start_point and end_point using get_start()

and get_end() respectively.

Use elif to check if change point is "o" . If it is, then only reset start_point .

Use another elif statement to check if change point is "d" . If it is, then only reset end_point .

Use else to handle cases in which the user typed some other value. Inside the condition, print "Oops,

that isn't 'o' , 'd' , or 'b' ..." and recursively call set_start_and_end() on start_point and

end_point so that the user has a chance to try again.

In [ ]:

Try calling set_start_and_end() with None and None as the arguments and printing the result. Save

your code and enter python3 skyroute.py in the terminal to see what happens!

After all that work, why are you getting back "None, None" ? Oh right, you still need to set up

get_start() and get_end() ! The good news is that these functions are very similar.

Make sure to remove your call of set_start_and_end() .

In [ ]:

Let’s begin with get_start() . In the function body, remove pass and set start_point_letter equal to

user input from the question "Where are you coming from? Type in the corresponding letter: " .

We need to make sure make sure the user entered a real landmark name! Use a conditional to check if

start_point_letter exists as a key in landmark_choices .

If it does, set start_point equal to landmark_choices[start_point_letter] and return

start_point from the function.

In [ ]:

Add an else condition. In the body of the else condition, print "Sorry, that's not a landmark we

have data on. Let's try this again..." and recursively return a call of get_start() so that the

user gets a chance to get it right.

In [ ]:

Set up get_end() in exactly the same way as you set up get_start() except with:

end_point in lieu of start_point

a recursive call of get_end() in lieu of get_start() "Ok, where are you headed? Type in the

corresponding letter: " instead of "Where are you coming from? "

In [ ]:

Try calling set_start_and_end() with None and None as the arguments and printing the result to the

console again. Did you get the right return values?

In [ ]:

Let’s build a wrapper function for the bulk of the program that we can use to:

get and set the origin and destination

call search to get the recommended route

allow users to search for another route To accomplish this, define a new function new_route() , which

takes two parameters: start_point and end_point . Give both a default value of None .

We do this because start_point and end_point may need to be defined for the first time or redefined

upon subsequent new_route() calls.

In [ ]:

In the new_route() function, set start_point and end_point equal to the function call of

set_start_and_end() with start_point and end_point as arguments.

In [ ]:

We have the function to set the origin and destination for our route. It’s time for a bit of breadth-first search to

spice things up and actually find the best route between those selected points!

Outside new_route() , define a new function get_route() which takes two parameters. Can you guess

what they are?

In [ ]:

You may be itching to run bfs() on your start and end points (with the vc_metro graph). You can even try

it out, but if you run that code, you won’t get what you’re looking for. That is, unless what you’re looking for

happens to be a pile of errors.

Why all the errors?

Your start_point and end_point are landmarks, not metro stations. And if you take a look at

vc_landmarks.py again, you’ll see that some landmarks have more than one metro station. In order to get

the metro stations closest to to each landmark, you’ll need to access them through the vc_landmarks

dictionary.

Inside the get_route() function, create a variable start_stations and set it equal to

vc_landmarks[start_point] . This should grab a set of at least one metro station.

In [ ]:

Below start_stations , set another variable end_stations using the same logic.

In [ ]:

Because some landmarks have more than one station, there is sometimes more than one route between

landmarks. That means it’s our job to collect all of the shortest routes between stations and then compare

them based on path length.

For example, you could get from Herald Square in Midtown, NYC to Codecademy in Soho, NYC in a few

ways. You can start at 34th Street-Herald Square station and end either at Prince Street station or BroadwayLafayette

station.

The shortest path between 34th Street-Herald Square and Prince Street is five stops. The shortest path

between 34th Street-Herald Square and Broadway-Lafayette is two stops. If we compare those two possible

shortest routes, we have a clear shortest route.

To collect our shortest routes for comparison, create an empty list called routes under the stations

variables you just defined in get_route() .

In [ ]:

Ready to get your loop on? To get each combination, we can use a Python for loop to loop through each

start_station in start_stations and then, inside, loop through each end_station in

end_stations .

In [ ]:

Inside the inner for loop, create a variable route and set it equal to a call of bfs() on vc_metro as the

graph, start_station as the start vertex, and end_station as the end vertex.

In [ ]:

Check if route exits. If it does, add this new shortest route to the routes list that you created. If you’ll

recall, this route returned from bfs() is a Python list that represents the path.

In [ ]:

Outside of both loops but still inside the get_route() function, we can now get our shortest route from our

routes list based on list length using a nifty Python trick:

min(list_name, key=len)

Save the final resulting shortest route to a variable shortest_route and then return shortest_route

from the function.

In [ ]:

Let’s see if the get_route() function does what it’s supposed to! Call get_route() with two landmark

names (you can grab these from the vc_landmarks keys) and print the result. Now save your code and in

the console enter: python3 skyroute.py .

In [ ]:

It’s time to take this awesomeness back to the new_route() function. In your new_route() function body,

create a variable shortest_route and set it equal to get_route() called on the start_point and

end_point variables you defined above.

In [ ]:

As you may have noticed, shortest_route is in a format that isn’t all that user-friendly. Let’s change that!

Create a new variable called shortest_route_string set to a string that has each station from

shortest_route on a new line. Hint:

some_string = '\n'.join(list_name)

In [ ]:

Below this new string variable, print the following to the console:

"The shortest metro route from {0} to {1} is:\n{2}".format(start_point,

end_point, shortest_route_string)

In [ ]:

At this point, we have a pretty solid tool. Call new_route() in the body of skyroute() below

greeting() . Now try calling skyroute() in your console. Pretty cool, right?

In [ ]:

What if someone wants to know about more than one route? Let’s give them a chance to get that info before

the program abruptly closes down. Under the final print statement in new_route() , collect user input for the

question "Would you like to see another route? Enter y/n: " and save it to the variable again .

In [ ]:

Check if again is equal to “y” . If it is, make a recursive call of new_route() with the current values of

start_point and end_point passed in.

In [ ]:

After a few calls, it might be helpful for the user to see the list of landmarks again. Above the recursive call of

new_route() , call a function show_landmarks() without any arguments.

In [ ]:

Outside of new_route() , define show_landmarks() without any parameters. In the function body, use a

new variable see_landmarks to capture user input for the the question "Would you like to see the

list of landmarks again? Enter y/n: ".

In [ ]:

On the next line (still in the show_landmarks() function), check if see_landmarks is equal to “y” . If it

is, print out the landmark_string for the user.

In [ ]:

Now our function will loop as long as our user wants to look up new directions! Pretty neat, right? But we still

have a bit of an abrupt ending. Let’s fix that. Outside all your functions, create another function goodbye() .

In it, print "Thanks for using SkyRoute!" , giving our user some pleasant parting words.

In [ ]:

Add a call of goodbye() at the end of the skyroute() function body. Test out your function in the console

to see how it works!

In [ ]:


版权所有:留学生编程辅导网 2020 All Rights Reserved 联系方式:QQ:99515681 微信:codinghelp 电子信箱:99515681@qq.com
免责声明:本站部分内容从网络整理而来,只供参考!如有版权问题可联系本站删除。 站长地图

python代写
微信客服:codinghelp