Assignment 5 New! |
Due: Friday, April 3
This assignment contains one programming exercise (the ubbi dubbi exercise from the original Assignment 5) and an alternative programming problem for the virus simulation problem that was included on the original assignment. You can turn in your solutions any time on 4/3/20, and only need to submit an electronic copy of your code files. Your electronic submission is described in the section Uploading your completed work (there is no Google form to submit for this assignment). If you need an extension on this assignment, please contact Ellen or Stella. You do not need to work with a partner on any of this assignment work.
Reading
The following material from the fifth or sixth edition of the text is useful to review for this assignment: pages 187-188, 192-196, and 200-202. You should also review notes and examples from Lectures #10, 12, and 13, and Labs #5 and 6.
Getting Started: Download assign5_new
For the exercise on this assignment, create your own folder named assign5_exercise
.
You will create a code file named ubbi.m
from scratch and place it in your
assign5_exercise
folder. When you are ready to start the problem, use Cyberduck to
connect to the CS server and download a copy of the assign5_new
folder onto your
Desktop. This folder contains four files for the programming problem in this assignment: two
code files named cityDistance.m
and convertCoords.m
, a data file named
cities.mat
, and an image file named mapUS.png
.
Uploading your completed work
When you have completed the work for this assignment, your assign5_exercise
folder should contain one code file named ubbi.m
and your assign5_new
folder should contain its original contents (the four files noted above) plus six new
code files that you will write, named printCityInfo.m
, printCities.m
,
largestCity.m
, nearbyCities.m
, displayCities.m
, and
testCities.m
. Use Cyberduck to connect to the CS file server and navigate to your
cs112/drop/assign05
folder. Drag your assign5_exercise
and
assign5_new
folders to this drop folder. More details about this process
can be found on the webpage on Managing Assignment Work.
Exercise: ubbi dubbi
The old PBS show Zoom taught kids how to speak ubbidubbi, enabling them to speak to each other without their parents understanding what they were saying. You're going to write an ubbidubbi converter in MATLAB! (Never too late to learn a new language!) If you're interested, here's a YouTube video on how to learn ubbidubbi. (Ubbidubbi was also used by Penny and Amy in season 10 episode 7 of The Big Bang Theory to have a secret conversation to counter Sheldon and Leonard's use of Klingon.)
Write a function called ubbi
that takes a string as input and
returns the ubbidubbified string as output. The rule for conversion is to
insert 'ub' in front of every vowel.
This clip of MATLAB's command window shows what the function ubbi
should do:
>> newcs112 = ubbi('cs112') newcs112 = cs112 >> >> test = ubbi('I am flying to America!') test = ubI ubam flubyubing tubo ubAmuberubicuba! >>
Note in the examples above that
both lower case and upper case vowels work. You can put all the vowels into a single
string, which MATLAB will store in a vector of characters (see examples from Lecture
#10, of the 'Stella' string and our modification of makeBullseye
to use
a string of colors). Also
recall that using square brackets allows for string concatenation, as in:
>> disp(['a' 'whole' 'bunch'])
awholebunch
The ==
operator can be used to compare a string with a single
character. In this case, it returns a logical vector that contains 1's at the locations
where the character appears in the string, for example:
>> 'banana' == 'a'
ans =
0 1 0 1
0 1
Your function ubbi
should still work (i.e. no MATLAB error messages are
generated) if the user does not supply an input string, as shown in the example below:
>> ubbi Please supply a string to ubbidubbify >> >> ubbi('cs112 makes me so happy!') ans = cs112 mubakubes mube subo hubappuby! >>Hint: a
for
statement can be used to loop through the
characters of a string, and a new string can be created by starting with an empty string
and adding characters each time the body of the loop is executed. This is illustrated
in the following code example that prints the string 'allets' (the reverse of 'stella').
newstring = ''; for letter = 'stella' newstring = [letter newstring]; end disp(newstring)
Problem: Analyzing US Cities
In this problem, you will work with a vector of structures that contains information about
the 978 cities in the US whose population is at least 50,000. The cities.mat
file in the
assign5_new
folder contains
one variable named cityData
that is this vector of structures. Each structure has fields
for the name
of the city, state
(two-letter abbreviation), location
(vector of latitude and longitude), population (pop
), and density
(people per
square mile). The following screen shot illustrates the loading of the data file and the MATLAB printout
for the first and last structures in the cityData
vector:
To begin, set your Current Folder to the assign5_new
folder and start a new script
named testCities.m
to add code to test the four functions and script described below. (These
functions can be written independently, as they do not depend on one another.) Every function needs
to access the cityData
variable that stores the information about all the cities. Rather than
pass this variable as an input to each function, we will declare this variable as global
,
enabling it to be accessed inside function files. To do this, first add these statements to the top of
your testCities.m
script:
global cityData load cityData.mat
Then, as you define each function, place the same variable declaration at the start of the body of the function, as shown in this example:
function [output1, output2] = myFunction (input1, input2) % comments about myFunction global cityData ...
You will then be able to refer to cityData
within the rest of your function code.
(1) Print information about a single city
Define a new function named printCityInfo
that has two inputs and no outputs. The two
inputs are (1) a string that is the name of a city and (2) the two-letter abbreviation of the state name.
This function should print all the
information about the input city using disp
statements. Your function should print a message
like "city not found" if the city or state name are not valid. The loop that searches for the input
city (and state) should terminate immediately when the requested city is found (this can be done
with a for
loop that contains a break
statement, or a while
loop). Use strcmp
to compare two strings. The following printout illustrates this function
in action (add your own tests to the testCities.m
script):
>> printCityInfo('Boston', 'MA') name: Boston state: MA location: 42.3188 -71.0846 population: 4637537 density: 5472 >> printCityInfo('Ellen', 'WA') city not found >>
(2) Print all the cities in a state
Define a new function named printCities
that has one input and no outputs. The one
input is the two-letter abbreviation
of a state name. This function should print the name (with disp
) of each city in
the requested state. It should print a message like "state not found" if the input state is not
valid. The following printout illustrates this function in action
(add your own tests to the testCities.m
script):
>> printCities('UT') Provo West Jordan Logan Salt Lake City Sandy Lehi Layton St. George South Jordan West Valley City Millcreek Orem Taylorsville Ogden >> printCities('XY') state not found >>
(3) Largest city in a state
Define a new function named largestCity
that has one input and two outputs. The
input is the two-letter abbreviation
of a state name. The outputs are (1) city name and (2) population. This function should return the
name and population of the largest city in the requested state. It should print a message like
"state not found" and return an empty string for the city name and population of zero if the input state
is not valid. The following printout illustrates this function in action:
>> [city, pop] = largestCity('MT') city = 'Billings' pop = 120800 >> [city, pop] = largestCity('XY') state not found city = 0×0 empty char array pop = 0 >>
(4) Print nearby cities
Define a new function named nearbyCities
that has three inputs and no outputs. The
inputs are (1) the name of a city, (2) the
two-letter abbreviation of a state name, and (3) a distance in miles. This function should print
the name of each city that is within the requested distance of the input city. This function
should print a message like "city not found" if the city and state names are not a valid combination.
To assist with this function, the cityDistance
function (given in the
assign5_new
folder) calculates
the distance between two cities from their latitude and longitude values using the
Haversine formula.
The following printout illustrates both the cityDistance
and nearbyCities
functions in action (the printCityInfo
function is first used to get latitude and longitude
vectors for Boston and Chicago, to then illustrate the calculation of distance between these two cities,
in miles). Below the printout is a hint for how to implement this function. Add your own tests to the
testCities.m
script:
>> printCityInfo('Boston', 'MA') name: Boston state: MA location: 42.3188 -71.0846 population: 4637537 density: 5472 >> printCityInfo('Chicago', 'IL') name: Chicago state: IL location: 41.8373 -87.6862 population: 8675982 density: 4612 >> dist = cityDistance([42.3188 -71.0846], [41.8373 -87.6862]) dist = 850.7367 >> nearbyCities('Burlington', 'VT', 100) Glens Falls, NY >> nearbyCities('Denver', 'CO', 200) Cheyenne, WY Aurora, CO Thornton, CO Commerce City, CO Castle Rock, CO Colorado Springs, CO Lakewood, CO Pueblo, CO Highlands Ranch, CO Greeley, CO Boulder, CO Longmont, CO Centennial, CO Broomfield, CO Lafayette, CO Loveland, CO Parker, CO Arvada, CO Fort Collins, CO Westminster, CO >> nearbyCities(cityData, 'Stella', 'CO', 200) city not found >>
The following outline provides a hint for a strategy that you can use to implement this function:
for each city in the vector of structures (let's refer to it as cityA) if cityA has the requested city name and state for each city in the vector of structures (let's refer to it as cityB) if cityB is different from cityA and the distance between cityA and cityB is within the input distance print the name and state for cityB
(5) Display cities on a US map
Create a script file named displayCities.m
to display the following image of a US map
with a scatter plot superimposed that shows a dot at the location of each city stored in cityData
(dots are not shown here):
Graphics (like a scatter plot) can be drawn superimposed on an image by first displaying the image,
then specifying hold on
, and then calling graphics commands (like plot
or
scatter
) with x,y
coordinates that are specified in the coordinate frame of the image.
When loaded, the above image will be stored in a matrix with 884 rows and 1344 columns, so any superimposed
graphics that we want to appear on this image will need to have x
coordinates in the
range of 1 to 1344, and y
coordinates in the range of 1 to 844. The latitude and longitude values
for US cities are not within this range, but you are given a function named convertCoords
in the
assign5_new
folder that does this conversion for you. In your displayCities.m
script,
follow these steps to complete the task of showing the city locations on the US map:
- collect the latitude and longitude values from all 978 cities into two separate vectors, i.e., one vector that contains the 978 latitude values and a second vector that contains the 978 longitude values (it is ok to include cities in Alaska and Hawaii, even though they will not appear on the above map)
- use the
convertCoords
function to convert the latitude and longitude values tox,y
coordinates. Suppose the latitude values are stored in a vector namedlats
and longitude values are stored in a vector namedlongs
, and you want to create vectors namedxc
andyc
to store thex,y
coordinates. This can be done with the following function call:[xc, yc] = convertCoords(lats, longs);
- read in the
mapUS.png
image file (stored in theassign5_new
folder) usingimread
, display it withimshow
, and sethold on
- call the
scatter
function to create a scatter plot using the computedx,y
coordinates. Try a dot size in the 10-30 range and draw the dots as'filled'
To keep all your testing code in one place, you can add a statement to your testCities.m
script to
execute the displayCities.m
script.