Hurricane Analysis Project Step 4

Hello! I’m working on step 4 in the Hurricane Analysis project. I’m confused by part of the hint and the subsequent code in the solution:

The hint:

Our function iterates through each hurricane in our hurricanes dictionary, hurricanes , and records the year as current_year and the hurricane dictionary as current_cane .

We then check if current_year exists as a key in our new dictionary, and if not, initialize the value for that key [current_cane] .

If current_year does exist as a key, current_cane is appended to the list stored in the key.

– What’s the purpose of initializing the value for that key ‘current_cane]’.

Here’s the code:
def create_year_dictionary(hurricanes):
“”“Convert dictionary with hurricane name as key to a new dictionary with hurricane year as the key and return new dictionary.”""
hurricanes_by_year= dict()
for cane in hurricanes:
current_year = hurricanes[cane][‘Year’]
current_cane = hurricanes[cane]
if current_year not in hurricanes_by_year:
** hurricanes_by_year[current_year] = [current_cane]**
else:
hurricanes_by_year[current_year].append(current_cane)
return hurricanes_by_year

And a link the the project:

Project

Is this what your hurricanes dictionary looks like?

{
'Cuba I': {'Name': 'Cuba I', 'Month': 'October', 'Year': 1924, 'Max Sustained  Wind': 165, 'Areas Affected': ['Central America', 'Mexico', 'Cuba', 'Florida', 'The Bahamas'], 'Damage': 'Damages not recorded', 'Deaths': 90}, 
'San Felipe II Okeechobee': {'Name': 'San Felipe II Okeechobee', 'Month': 'September', 'Year': 1928, 'Max Sustained  Wind': 160, 'Areas Affected': ['Lesser Antilles', 'The Bahamas', 'United States East Coast', 'Atlantic Canada'], 'Damage': 100000000.0, 'Deaths': 4000}, 
'Bahamas': {'Name': 'Bahamas', 'Month': 'September', 'Year': 1932, 'Max Sustained  Wind': 160, 'Areas Affected': ['The Bahamas', 'Northeastern United States'], 'Damage': 'Damages not recorded', 'Deaths': 16}, 
'Cuba II': {'Name': 'Cuba II', 'Month': 'November', 'Year': 1932, 'Max Sustained  Wind': 175, 'Areas Affected': ['Lesser Antilles', 'Jamaica', 'Cayman Islands', 'Cuba', 'The Bahamas', 'Bermuda'], 'Damage': 40000000.0, 'Deaths': 3103}, 
'CubaBrownsville': {'Name': 'CubaBrownsville', 'Month': 'August', 'Year': 1933, 'Max Sustained  Wind': 160, 'Areas Affected': ['The Bahamas', 'Cuba', 'Florida', 'Texas', 'Tamaulipas'], 'Damage': 27900000.0, 'Deaths': 179}, 'Tampico': {'Name': 'Tampico', 'Month': 'September', 'Year': 1933, 'Max Sustained  Wind': 160, 'Areas Affected': ['Jamaica', 'Yucatn Peninsula'], 'Damage': 5000000.0, 'Deaths': 184}, 
'Labor Day': {'Name': 'Labor Day', 'Month': 'September', 'Year': 1935, 'Max Sustained  Wind': 185, 'Areas Affected': ['The Bahamas', 'Florida', 'Georgia', 'The Carolinas', 'Virginia'], 'Damage': 'Damages not recorded', 'Deaths': 408}, 
'New England': {'Name': 'New England', 'Month': 'September', 'Year': 1938, 'Max Sustained  Wind': 160, 'Areas Affected': ['Southeastern United States', 'Northeastern United States', 'Southwestern Quebec'], 'Damage': 306000000.0, 'Deaths': 682}, 
'Carol': {'Name': 'Carol', 'Month': 'September', 'Year': 1953, 'Max Sustained  Wind': 160, 'Areas Affected': ['Bermuda', 'New England', 'Atlantic Canada'], 'Damage': 2000000.0, 'Deaths': 5}, 
'Janet': {'Name': 'Janet', 'Month': 'September', 'Year': 1955, 'Max Sustained  Wind': 175, 'Areas Affected': ['Lesser Antilles', 'Central America'], 'Damage': 65800000.0, 'Deaths': 1023}, 
'Carla': {'Name': 'Carla', 'Month': 'September', 'Year': 1961, 'Max Sustained  Wind': 175, 'Areas Affected': ['Texas', 'Louisiana', 'Midwestern United States'], 'Damage': 326000000.0, 'Deaths': 43}, 
'Hattie': {'Name': 'Hattie', 'Month': 'October', 'Year': 1961, 'Max Sustained  Wind': 160, 'Areas Affected': ['Central America'], 'Damage': 60300000.0, 'Deaths': 319}, 
'Beulah': {'Name': 'Beulah', 'Month': 'September', 'Year': 1967, 'Max Sustained  Wind': 160, 'Areas Affected': ['The Caribbean', 'Mexico', 'Texas'], 'Damage': 208000000.0, 'Deaths': 688}, 
'Camille': {'Name': 'Camille', 'Month': 'August', 'Year': 1969, 'Max Sustained  Wind': 175, 'Areas Affected': ['Cuba', 'United States Gulf Coast'], 'Damage': 1420000000.0, 'Deaths': 259}, 
'Edith': {'Name': 'Edith', 'Month': 'September', 'Year': 1971, 'Max Sustained  Wind': 160, 'Areas Affected': ['The Caribbean', 'Central America', 'Mexico', 'United States Gulf Coast'], 'Damage': 25400000.0, 'Deaths': 37}, 
'Anita': {'Name': 'Anita', 'Month': 'September', 'Year': 1977, 'Max Sustained  Wind': 175, 'Areas Affected': ['Mexico'], 'Damage': 'Damages not recorded', 'Deaths': 11}, 
'David': {'Name': 'David', 'Month': 'August', 'Year': 1979, 'Max Sustained  Wind': 175, 'Areas Affected': ['The Caribbean', 'United States East coast'], 'Damage': 1540000000.0, 'Deaths': 2068}, 
'Allen': {'Name': 'Allen', 'Month': 'August', 'Year': 1980, 'Max Sustained  Wind': 190, 'Areas Affected': ['The Caribbean', 'Yucatn Peninsula', 'Mexico', 'South Texas'], 'Damage': 1240000000.0, 'Deaths': 269}, 
'Gilbert': {'Name': 'Gilbert', 'Month': 'September', 'Year': 1988, 'Max Sustained  Wind': 185, 'Areas Affected': ['Jamaica', 'Venezuela', 'Central America', 'Hispaniola', 'Mexico'], 'Damage': 7100000000.0, 'Deaths': 318}, 
'Hugo': {'Name': 'Hugo', 'Month': 'September', 'Year': 1989, 'Max Sustained  Wind': 160, 'Areas Affected': ['The Caribbean', 'United States East Coast'], 'Damage': 10000000000.0, 'Deaths': 107}, 'Andrew': {'Name': 'Andrew', 'Month': 'August', 'Year': 1992, 'Max Sustained  Wind': 175, 'Areas Affected': ['The Bahamas', 'Florida', 'United States Gulf Coast'], 'Damage': 26500000000.0, 'Deaths': 65}, 
'Mitch': {'Name': 'Mitch', 'Month': 'October', 'Year': 1998, 'Max Sustained  Wind': 180, 'Areas Affected': ['Central America', 'Yucatn Peninsula', 'South Florida'], 'Damage': 6200000000.0, 'Deaths': 19325}, 
'Isabel': {'Name': 'Isabel', 'Month': 'September', 'Year': 2003, 'Max Sustained  Wind': 165, 'Areas Affected': ['Greater Antilles', 'Bahamas', 'Eastern United States', 'Ontario'], 'Damage': 5370000000.0, 'Deaths': 51}, 
'Ivan': {'Name': 'Ivan', 'Month': 'September', 'Year': 2004, 'Max Sustained  Wind': 165, 'Areas Affected': ['The Caribbean', 'Venezuela', 'United States Gulf Coast'], 'Damage': 23300000000.0, 'Deaths': 124}, 
'Emily': {'Name': 'Emily', 'Month': 'July', 'Year': 2005, 'Max Sustained  Wind': 160, 'Areas Affected': ['Windward Islands', 'Jamaica', 'Mexico', 'Texas'], 'Damage': 1010000000.0, 'Deaths': 17}, 
'Katrina': {'Name': 'Katrina', 'Month': 'August', 'Year': 2005, 'Max Sustained  Wind': 175, 'Areas Affected': ['Bahamas', 'United States Gulf Coast'], 'Damage': 125000000000.0, 'Deaths': 1836}, 
'Rita': {'Name': 'Rita', 'Month': 'September', 'Year': 2005, 'Max Sustained  Wind': 180, 'Areas Affected': ['Cuba', 'United States Gulf Coast'], 'Damage': 12000000000.0, 'Deaths': 125}, 
'Wilma': {'Name': 'Wilma', 'Month': 'October', 'Year': 2005, 'Max Sustained  Wind': 185, 'Areas Affected': ['Greater Antilles', 'Central America', 'Florida'], 'Damage': 29400000000.0, 'Deaths': 87}, 
'Dean': {'Name': 'Dean', 'Month': 'August', 'Year': 2007, 'Max Sustained  Wind': 175, 'Areas Affected': ['The Caribbean', 'Central America'], 'Damage': 1760000000.0, 'Deaths': 45}, 'Felix': {'Name': 'Felix', 'Month': 'September', 'Year': 2007, 'Max Sustained  Wind': 175, 'Areas Affected': ['Nicaragua', 'Honduras'], 'Damage': 720000000.0, 'Deaths': 133}, 
'Matthew': {'Name': 'Matthew', 'Month': 'October', 'Year': 2016, 'Max Sustained  Wind': 165, 'Areas Affected': ['Antilles', 'Venezuela', 'Colombia', 'United States East Coast', 'Atlantic Canada'], 'Damage': 15100000000.0, 'Deaths': 603}, 
'Irma': {'Name': 'Irma', 'Month': 'September', 'Year': 2017, 'Max Sustained  Wind': 180, 'Areas Affected': ['Cape Verde', 'The Caribbean', 'British Virgin Islands', 'U.S. Virgin Islands', 'Cuba', 'Florida'], 'Damage': 64800000000.0, 'Deaths': 138}, 
'Maria': {'Name': 'Maria', 'Month': 'September', 'Year': 2017, 'Max Sustained  Wind': 175, 'Areas Affected': ['Lesser Antilles', 'Virgin Islands', 'Puerto Rico', 'Dominican Republic', 'Turks and Caicos Islands'], 'Damage': 91600000000.0, 'Deaths': 3057}, 
'Michael': {'Name': 'Michael', 'Month': 'October', 'Year': 2018, 'Max Sustained  Wind': 160, 'Areas Affected': ['Central America', 'United States Gulf Coast (especially Florida Panhandle)'], 'Damage': 25100000000.0, 'Deaths': 74}
}
print (hurricanes['Katrina'].get('Year'))    #  2005
1 Like

Thanks for you reply, mtf. Yep, that’s what my hurricane dictionary looks like.

Alright, that’s where we can start. All we need to do is create a new dictionary, with the years as primary keys. This is where we have to stop and think… Are there any hurricanes that occur in the same year?

1 Like

:slight_smile: Thanks, mtf.

I spent the last couple of hours working through the logic. (Should it really take me this long??) (If I started by adding print statements for each variable, I probably could have worked it out sooner… maybe.) (I need a drink.) (It’s only 10.30 a.m.)

Is this correct?

hurricanes_by_year is the new dictionary.
The for loop iterates through hurricanes and assigns the year to current_year and the hurricane name to current_cane.
It checks hurricanes_by_year to see if the current hurricane is in there. If it’s not, the current hurricane is added, with the key set to the year (hurricanes_by_year[current_year] ).

If the year already exists in hurricanes_by_year, then that means the current hurricane happened the same year as another and its dictionary needs to be added to the key for that year.

Thanks again!!
Kelly

2 Likes

Please show us the structure of your new hurricanes_by_year dictionary. (Just the structure, not the data, to be clear.)

Yes, especially if it meant a lot of digging, research and practice. If it came easy every cheater would cake walk through it.

We need to trust that we can come up with logic, and then turn around and not trust that logic. Only a serious learner can self-criticize. It all takes time. There is no clock on this.

2 Likes

What do you mean by structure exactly?

Like this?

{Year: [{Name:
{Month:
{Year:
{Max Sustained Wind:
{Areas Affected: [ ]
{Damage:
{Deaths: }]

1 Like

Pretty much. The shapes are all that concern us. A dictionary with keys to lists of dictionaries is the shape one was expecting. Looks like you caught on so no data got left out.

What logic did you follow in this step of construction? Did you end up with lists of dictionaries, as planned?

1 Like

Yes, but only because I reversed engineered the solution. I don’t think I could have done it without doing that first.

I do think that helped me understand the structure and how to achieve it, so hopefully I have a shot at completing the rest of the project without having to go to the solution so soon!

3 Likes

I too am having some issues with this particular problem. I initially tried to set the function up in a similar manner as the previous function that created the hurricane dictionary, but using “year” instead of “names”. That didn’t quite produce the results that were being asked for and after days of trying to figure it out I caved and took a gander at the code solutions.

I understand why they wrote the code that way (it seems so simple once I looked at it), but I am having issues with appending the info for the “current year” that already exists to the “current year” Key. I have attached a screenshot of what I am talking about. I have been going crazy trying to re- write it so that it works, but I think that I am missing something…

I think the example hints at using a defaultdict based on a list instead-
https://docs.python.org/3/library/collections.html#collections.defaultdict. It’s not essential but it may be easier. Either that or ensure every new key refers to a empty list and add to this list.

The reasoning for the list is that a single year might contain multiple values. If you do use that option make sure every hurricane dictionary you add to your dictionary based on years is appended to a list (if you directly assign then the key refers to a dictionary value and you get an error if you try to append again in the future).

Thanks for your quick response! So, correct me if I am wrong ( I am a super noob), but it sounds like .append will only work on empty lists, so if choosing to append to an empty dictionary then you have to append each one individually (which might be way more time consuming depending on how much information is involved), otherwise you will get an error. Is this correct?

The .append works on lists whether they’re empty or not. A dictionary doesn’t share the same method because it acts in a different way (there are several routes to change dictionaries but I think they’ll make this particular problem more complex so I won’t go into them).

But the problem with a dictionary is that each key must be unique, how would you decide what key to use to store each value? Re-use of a key replaces the value that key refers to. So in this case a list would be an easier container to work with (you don’t need to start thinking of how to generate a second set of keys).

1 Like

Ahh, Okay that makes sense! Thank you!

Aside

Consider all the data housed in an array as a list of dictionaries and then ported over to a dictionary keyed to the name attributes. There will be two copies of the data, the array (dlu), and the dictionary (nlu). So we can bring up any storm between 1924 and 2018, inclusive, by name.

We can use the same list data (dlu) to construct dictionaries with other keys, but bear in mind where the data stores are. How much do we need to move this data around when constructing the other dictionaries?

Answer: very little. For instance our years lookup (ylu) would look only like this,

{
  1924: ['Cuba I'], 
  1928: ['San Felipe II Okeechobee'], 
  1932: ['Bahamas', 'Cuba II'], 
  1933: ['CubaBrownsville', 'Tampico'], 
  1935: ['Labor Day'], 
  1938: ['New England'], 
  1953: ['Carol'], 
  1955: ['Janet'], 
  1961: ['Carla', 'Hattie'], 
  1967: ['Beulah'], 
  1969: ['Camille'], 
  1971: ['Edith'], 
  1977: ['Anita'], 
  1979: ['David'], 
  1980: ['Allen'], 
  1988: ['Gilbert'], 
  1989: ['Hugo'], 
  1992: ['Andrew'], 
  1998: ['Mitch'], 
  2003: ['Isabel'], 
  2004: ['Ivan'], 
  2005: ['Emily', 'Katrina', 'Rita', 'Wilma'], 
  2007: ['Dean', 'Felix'], 
  2016: ['Matthew'], 
  2017: ['Irma', 'Maria'], 
  2018: ['Michael']
}

Given the names, we can retrieve all the data from our nlu.

print (ylu[1988])
print (nlu[ylu[1988][0]])
['Gilbert']
{'name': 'Gilbert', 'month': 'September', 'year': 1988, 'max_sustained_winds': 185, 'areas_affected': ['Jamaica', 'Venezuela', 'Central America', 'Hispaniola', 'Mexico'], 'damages': 7100000000, 'deaths': 318}

>>> for x, y in ylu.items():
	for z in y:
		print (x, nlu[z])
...
1932 {'name': 'Bahamas', 'month': 'September', 'year': 1932, 'max_sustained_winds': 160, 'areas_affected': ['The Bahamas', 'Northeastern United States'], 'damages': 'Damages not recorded', 'deaths': 16}
1932 {'name': 'Cuba II', 'month': 'November', 'year': 1932, 'max_sustained_winds': 175, 'areas_affected': ['Lesser Antilles', 'Jamaica', 'Cayman Islands', 'Cuba', 'The Bahamas', 'Bermuda'], 'damages': 40000000, 'deaths': 3103}
1933 {'name': 'CubaBrownsville', 'month': 'August', 'year': 1933, 'max_sustained_winds': 160, 'areas_affected': ['The Bahamas', 'Cuba', 'Florida', 'Texas', 'Tamaulipas'], 'damages': 27900000, 'deaths': 179}
1933 {'name': 'Tampico', 'month': 'September', 'year': 1933, 'max_sustained_winds': 160, 'areas_affected': ['Jamaica', 'Yucatn Peninsula'], 'damages': 5000000, 'deaths': 184}
...
1961 {'name': 'Carla', 'month': 'September', 'year': 1961, 'max_sustained_winds': 175, 'areas_affected': ['Texas', 'Louisiana', 'Midwestern United States'], 'damages': 326000000, 'deaths': 43}
1961 {'name': 'Hattie', 'month': 'October', 'year': 1961, 'max_sustained_winds': 160, 'areas_affected': ['Central America'], 'damages': 60300000, 'deaths': 319}
...
2005 {'name': 'Emily', 'month': 'July', 'year': 2005, 'max_sustained_winds': 160, 'areas_affected': ['Windward Islands', 'Jamaica', 'Mexico', 'Texas'], 'damages': 1010000000, 'deaths': 17}
2005 {'name': 'Katrina', 'month': 'August', 'year': 2005, 'max_sustained_winds': 175, 'areas_affected': ['Bahamas', 'United States Gulf Coast'], 'damages': 125000000000, 'deaths': 1836}
2005 {'name': 'Rita', 'month': 'September', 'year': 2005, 'max_sustained_winds': 180, 'areas_affected': ['Cuba', 'United States Gulf Coast'], 'damages': 12000000000, 'deaths': 125}
2005 {'name': 'Wilma', 'month': 'October', 'year': 2005, 'max_sustained_winds': 185, 'areas_affected': ['Greater Antilles', 'Central America', 'Florida'], 'damages': 29400000000, 'deaths': 87}
2007 {'name': 'Dean', 'month': 'August', 'year': 2007, 'max_sustained_winds': 175, 'areas_affected': ['The Caribbean', 'Central America'], 'damages': 1760000000, 'deaths': 45}
2007 {'name': 'Felix', 'month': 'September', 'year': 2007, 'max_sustained_winds': 175, 'areas_affected': ['Nicaragua', 'Honduras'], 'damages': 720000000, 'deaths': 133}
...
2017 {'name': 'Irma', 'month': 'September', 'year': 2017, 'max_sustained_winds': 180, 'areas_affected': ['Cape Verde', 'The Caribbean', 'British Virgin Islands', 'U.S. Virgin Islands', 'Cuba', 'Florida'], 'damages': 64800000000, 'deaths': 138}
2017 {'name': 'Maria', 'month': 'September', 'year': 2017, 'max_sustained_winds': 175, 'areas_affected': ['Lesser Antilles', 'Virgin Islands', 'Puerto Rico', 'Dominican Republic', 'Turks and Caicos Islands'], 'damages': 91600000000, 'deaths': 3057}
...
>>> 

month is another useful key. We can use the dlu to construct a dictionary similar to the above. We know there are multiple months.

We have a dictionary similar to above where the keys are months and the values are lists of storm names in that month

mon = 'October'
oct = map(lambda x: nlu[x], mlu[mon])
try:
  while oct:
    print (f'{mon}:', next(oct))
except:
  print (len([*oct]))
October: {'name': 'Cuba I', 'month': 'October', 'year': 1924, 'max_sustained_winds': 165, 'areas_affected': ['Central America', 'Mexico', 'Cuba', 'Florida', 'The Bahamas'], 'damages': 'Damages not recorded', 'deaths': 90}
October: {'name': 'Hattie', 'month': 'October', 'year': 1961, 'max_sustained_winds': 160, 'areas_affected': ['Central America'], 'damages': 60300000, 'deaths': 319}
October: {'name': 'Mitch', 'month': 'October', 'year': 1998, 'max_sustained_winds': 180, 'areas_affected': ['Central America', 'Yucatn Peninsula', 'South Florida'], 'damages': 6200000000, 'deaths': 19325}
October: {'name': 'Wilma', 'month': 'October', 'year': 2005, 'max_sustained_winds': 185, 'areas_affected': ['Greater Antilles', 'Central America', 'Florida'], 'damages': 29400000000, 'deaths': 87}
October: {'name': 'Matthew', 'month': 'October', 'year': 2016, 'max_sustained_winds': 165, 'areas_affected': ['Antilles', 'Venezuela', 'Colombia', 'United States East Coast', 'Atlantic Canada'], 'damages': 15100000000, 'deaths': 603}
October: {'name': 'Michael', 'month': 'October', 'year': 2018, 'max_sustained_winds': 160, 'areas_affected': ['Central America', 'United States Gulf Coast (especially Florida Panhandle)'], 'damages': 25100000000, 'deaths': 74}

That leaves us affected regions as tangible keys. Looking at that data we see how it cross-references with other storms (four times in Central America in October, eg.). We’ll need to stategize how to compose that data into a dictionary, with regions as keys. Let’s ponder this one for a moment. I certainly will.

1 Like

Given that we’ve initialized alu,

for x in dlu:
  y = x['areas_affected']
  for z in y:
    alu[z] = []
for x in dlu:
  for y in x['areas_affected']:
    alu[y].append(x['name'])
>>> alu['Virginia']
['Labor Day']
>>> alu['Cuba']
['Cuba I', 'Cuba II', 'CubaBrownsville', 'Camille', 'Rita', 'Irma']
>>> alu['Central America']
['Cuba I', 'Janet', 'Hattie', 'Edith', 'Gilbert', 'Mitch', 'Wilma', 'Dean', 'Michael']
>>> 

Again, we are working with a name index with which we can access the nlu for storm data.

>>> nlu[alu['Georgia'][0]]
{'name': 'Labor Day', 'month': 'September', 'year': 1935, 'max_sustained_winds': 185, 'areas_affected': ['The Bahamas', 'Florida', 'Georgia', 'The Carolinas', 'Virginia'], 'damages': 'Damages not recorded', 'deaths': 408}
>>> 

Below we’ve played this out to arrive at a name keyed store and three other index stores. That gives us a name lookup, year lookup, month lookup, and areas affected lookup.

https://www.codecademy.com/workspaces/61bea3828f5e57a8e8521429

1 Like

This is fantastic! I have been studying some of the code that you were using because I haven’t learned some of it yet, but it is very enlightening!

1 Like

It’s only the indices, at present, and doesn’t answer many, or any of the questions in the project. My original project code is very different from this version which stems only from the initial data, apart from the abridgement of the damages values. I’ve added a Single Month Report so we can see how that data plays out.

As I’ve said before, this is a project we can keep coming back to expecting to learn a little more, each time.

I’m wondering if anyone can help. I’m apparently attempting this a different way. Here’s what I have:

def remove_repeats(lst):
list_no_repeats =
for item in lst:
if item not in list_no_repeats:
list_no_repeats.append(item)
return list_no_repeats
years_no_repeats = remove_repeats(years)

def convert_dictionary(dictionary, key_word, key_list):
New_Dictionary = {}
temp_list =
for item in key_list:
for entry in dictionary:

  if dictionary[entry][key_word] == item:
    print(dictionary[entry][key_word])
    temp_list.append(dictionary[entry])
New_Dictionary.update({item:temp_list})

return New_Dictionary

year_dictionary = convert_dictionary(name_dictionary, “Year”, years_no_repeats)
print(year_dictionary[1932])

This prints out the information for ALL the hurricanes, not just the ones in 1932. My thought is to iterate through the years, check the years against the values in name_dictionary and if they match add that entry to a list. Then update the new dictionary with the key (that is the year) and the list containing only those for that year. Something is going wrong, however. Sorry if this is too much code to ask about all at once. I’m fairly new to coding.
Thanks
Craig