The Boredless Tourist

Hi everyone

I’m hoping you guys can help me figure this code out. I watched the help video and went through my code line by line. As far as I can tell, my code matches the video.

I’m supposed to be returning:

“Hi Dereck Smill, we think you’ll like these places around Paris, France: the Arc de Triomphe”

Instead, I’m returning:

“Hi Dereck Smill, we think you’ll like these places around Paris, France:” I have no idea why I can’t get the final part to show up. I’ve spent hours trying to figure this out:

Here’s the code:

destinations = ["Paris, France", "Shanghai, China", "Los Angeles, USA", "So Paulo, Brazil", "Cairo, Egypt"]

test_traveler = ['Erin Wilkes', 'Shanghai, China', ['historical site', 'art']]

def get_destination_index(destination):
  destination_index = destinations.index(destination)
  return destination_index

def get_traveler_location(traveler):
  traveler_destination = traveler[1]
  traveler_destination_index = get_destination_index(traveler_destination)
  return traveler_destination_index

attractions = []
for destination in destinations:
  attractions.append([])
  
def add_attraction(destination, attraction):
  try:
    destination_index = get_destination_index(destination)
    attractions_for_destination = attractions[destination_index].append(attraction)
  except SyntaxError:
    return

add_attraction("Paris, France", ["the Louvre", ["art", "museum"]])
add_attraction("Paris, France", ["Arc de Triomphe", ["historical site", "monument"]])
add_attraction("Shanghai, China", ["Yu Garden", ["garden", "historcical site"]])
add_attraction("Shanghai, China", ["Yuz Museum", ["art", "museum"]])
add_attraction("Shanghai, China", ["Oriental Pearl Tower", ["skyscraper", "viewing deck"]])
add_attraction("Los Angeles, USA", ["LACMA", ["art", "museum"]])
add_attraction("So Paulo, Brazil", ["So Paulo Zoo", ["zoo"]])
add_attraction("So Paulo, Brazil", ["Ptio do Colgio", ["historical site"]])
add_attraction("Cairo, Egypt", ["Pyramids of Giza", ["monument", "historical site"]])
add_attraction("Cairo, Egypt", ["Egyptian Museum", ["museum"]])

def find_attractions(destination, interests):
  destination_index = get_destination_index(destination)
  attractions_in_city = attractions[destination_index]
  attractions_with_interest = []
  
  for attraction in attractions_in_city:
    possible_attraction = attraction
    attraction_tags = attraction[1]
    
    for interest in interests:
      if interest in attraction_tags:
        attractions_with_interest.append(possible_attraction[0])
    return attractions_with_interest
  
def get_attractions_for_traveler(traveler):
  traveler_destination = traveler[1]
  traveler_interests = traveler[2]
  traveler_attractions = find_attractions(traveler_destination, traveler_interests)
  
  interests_string = "Hi " + traveler[0] + ". We think you'll like these places around " + traveler_destination + ":"
  
  for i in range(len(traveler_attractions)):
    if traveler_attractions[-1] == traveler_attractions[i]:
      interests_string += " the " + traveler_attractions[i] + "."
    else:
      interests_string += " the " + traveler_attractions[i] + ", "
  return interests_string

smills_france = get_attractions_for_traveler(['Dereck Smill', "Paris, France", 'monument'])

print(smills_france)

It’s for this project:

https://www.codecademy.com/paths/computer-science/tracks/cspath-cumulative-tourism/modules/cspath-boredless-tourist/projects/the-boredless-tourist

Thank you all for your help!!!

Hey @tjohnson139

Firstly, never underestimate the power of a print call for debugging purposes. I went through your code, and added in several print calls so I could see what your code is working on at various points through its execution. Here’s what I ended up with:

destinations = ["Paris, France", "Shanghai, China", "Los Angeles, USA", "So Paulo, Brazil", "Cairo, Egypt"]

test_traveler = ['Erin Wilkes', 'Shanghai, China', ['historical site', 'art']]

def get_destination_index(destination):
  destination_index = destinations.index(destination)
  return destination_index

def get_traveler_location(traveler):
  traveler_destination = traveler[1]
  traveler_destination_index = get_destination_index(traveler_destination)
  return traveler_destination_index

attractions = []
for destination in destinations:
  attractions.append([])
  
def add_attraction(destination, attraction):
  try:
    destination_index = get_destination_index(destination)
    attractions_for_destination = attractions[destination_index].append(attraction)
  except SyntaxError:
    return

add_attraction("Paris, France", ["the Louvre", ["art", "museum"]])
add_attraction("Paris, France", ["Arc de Triomphe", ["historical site", "monument"]])
add_attraction("Shanghai, China", ["Yu Garden", ["garden", "historcical site"]])
add_attraction("Shanghai, China", ["Yuz Museum", ["art", "museum"]])
add_attraction("Shanghai, China", ["Oriental Pearl Tower", ["skyscraper", "viewing deck"]])
add_attraction("Los Angeles, USA", ["LACMA", ["art", "museum"]])
add_attraction("So Paulo, Brazil", ["So Paulo Zoo", ["zoo"]])
add_attraction("So Paulo, Brazil", ["Ptio do Colgio", ["historical site"]])
add_attraction("Cairo, Egypt", ["Pyramids of Giza", ["monument", "historical site"]])
add_attraction("Cairo, Egypt", ["Egyptian Museum", ["museum"]])

def find_attractions(destination, interests):
  destination_index = get_destination_index(destination)
  print("Destination index: %r" % destination_index)
  attractions_in_city = attractions[destination_index]
  print("Attractions in city: %r" % attractions_in_city)
  attractions_with_interest = []
  
  for attraction in attractions_in_city:
    possible_attraction = attraction
    print("Possible attraction: %r" % possible_attraction)
    attraction_tags = attraction[1]
    print("Attraction tags: %r" % attraction_tags)
    
    for interest in interests:
      print("Checking interest '%r'" % interest)
      if interest in attraction_tags:
        attractions_with_interest.append(possible_attraction[0])
        print("Matched attraction %r with interest %r" % (possible_attraction[0], interest))
      else:
        print("Discarding attraction %r as no match!" % possible_attraction[0])
    return attractions_with_interest
  
def get_attractions_for_traveler(traveler):
  traveler_destination = traveler[1]
  traveler_interests = traveler[2]
  traveler_attractions = find_attractions(traveler_destination, traveler_interests)
  
  interests_string = "Hi " + traveler[0] + ". We think you'll like these places around " + traveler_destination + ":"

  print("Traveler attractions: %r " % traveler_attractions)
  
  for i in range(len(traveler_attractions)):
    if traveler_attractions[-1] == traveler_attractions[i]:
      interests_string += " the " + traveler_attractions[i] + "."
    else:
      interests_string += " the " + traveler_attractions[i] + ", "
  return interests_string

smills_france = get_attractions_for_traveler(['Dereck Smill', "Paris, France", 'monument'])

print(smills_france)

The first thing that I noticed, whilst reading through your code and adding my prints is that you have an indentation issue in find_attractions:

def find_attractions(destination, interests):
  destination_index = get_destination_index(destination)
  attractions_in_city = attractions[destination_index]
  attractions_with_interest = []
  
  for attraction in attractions_in_city:
    possible_attraction = attraction
    attraction_tags = attraction[1]
    
    for interest in interests:
      if interest in attraction_tags:
        attractions_with_interest.append(possible_attraction[0])
    return attractions_with_interest ### this is indented incorrectly!!

The indentation for your return statement places it within the for structure of for attraction in attractions_in_city, so this loop will only ever execute once. I fixed that, then I ran your code. Here’s the output:

Destination index: 0
Attractions in city: [['the Louvre', ['art', 'museum']], ['Arc de Triomphe', ['historical site', 'monument']]]
Possible attraction: ['the Louvre', ['art', 'museum']]
Attraction tags: ['art', 'museum']
Checking interest ''m''
Discarding attraction 'the Louvre' as no match!
Checking interest ''o''
Discarding attraction 'the Louvre' as no match!
Checking interest ''n''
Discarding attraction 'the Louvre' as no match!
Checking interest ''u''
Discarding attraction 'the Louvre' as no match!
Checking interest ''m''
Discarding attraction 'the Louvre' as no match!
Checking interest ''e''
Discarding attraction 'the Louvre' as no match!
Checking interest ''n''
Discarding attraction 'the Louvre' as no match!
Checking interest ''t''
Discarding attraction 'the Louvre' as no match!
Possible attraction: ['Arc de Triomphe', ['historical site', 'monument']]
Attraction tags: ['historical site', 'monument']
Checking interest ''m''
Discarding attraction 'Arc de Triomphe' as no match!
Checking interest ''o''
Discarding attraction 'Arc de Triomphe' as no match!
Checking interest ''n''
Discarding attraction 'Arc de Triomphe' as no match!
Checking interest ''u''
Discarding attraction 'Arc de Triomphe' as no match!
Checking interest ''m''
Discarding attraction 'Arc de Triomphe' as no match!
Checking interest ''e''
Discarding attraction 'Arc de Triomphe' as no match!
Checking interest ''n''
Discarding attraction 'Arc de Triomphe' as no match!
Checking interest ''t''
Discarding attraction 'Arc de Triomphe' as no match!
Traveler attractions: [] 
Hi Dereck Smill. We think you'll like these places around Paris, France:

Can you see where your issue is coming from?

I'd invite you to try and fix it yourself before reading my solution here...

So, what’s happening is you’re passing a string to get_attractions_for_traveler in traveler[2]: that value is ‘monument’.

As strings are iterable, instead of checking each discrete interest ('monument' or 'historical site' for example) your code is checking each character of the interest ('m', 'o', 'n' etc…) against the interests of the site.

If you pass the interests of the traveller as a list when you call get_attractions_for_traveler or otherwise verify (and convert if necessary) the contents of traveler[2] are a list before iterating over it, you’ll get the output you’re expecting:

Destination index: 0
Attractions in city: [['the Louvre', ['art', 'museum']], ['Arc de Triomphe', ['historical site', 'monument']]]
Possible attraction: ['the Louvre', ['art', 'museum']]
Attraction tags: ['art', 'museum']
Checking interest ''monument''
Discarding attraction 'the Louvre' as no match!
Possible attraction: ['Arc de Triomphe', ['historical site', 'monument']]
Attraction tags: ['historical site', 'monument']
Checking interest ''monument''
Matched attraction 'Arc de Triomphe' with interest 'monument'
Traveler attractions: ['Arc de Triomphe'] 
Hi Dereck Smill. We think you'll like these places around Paris, France: the Arc de Triomphe.

Hope that helps. :slight_smile:

3 Likes

Thank you so much for spending so much time on this. You helped a ton! I’m new to coding but it’s frustrating one indent or one set of brackets can throw off your whole code :slight_smile:

Thank you again! I really appreciate it!!!

I just want to second this statement, bring it to a vote and pass it unanimously!!!

2 Likes

lol. I still don’t understand all the code he used in the print statements but that helped so much that’s one of my next things to learn :slight_smile:

1 Like

No problem at all, glad I could help. :slight_smile:

What in particular didn’t you understand in the print calls I added to your code? :slight_smile:

This part - %r" % - but that’s OK. I’m sure I’ll learn it. I’m working on another project now and putting random print statements in and it’s helping a lot. And I’m sure I’ll figure it out eventually. It’s a confusing language and it’s taking a lot of brain power and even more frustration. :slight_smile:

Thank you again for all your help. I can’t thank you enough for your time and help!

1 Like

Ah, I thought it might be that.

So, you know how you can pass variables into strings by using placeholders? For example:

the_math = 3 * 5
print("The answer is %d!" % the_math)

where %d tells Python to expect a variable, of type int.

%r tells Python to use the representation of the object, which is returned by the repr() function. So, if you have the following code:

print("The object looks like %r" % the_thing)

and the_thing = ['a','b','c','d'], then your output would be The object looks like ['a','b','c','d'].

If the_thing = 123, you’d get The object looks like 123.

%r basically gives you the friendly representation of the object you’re passing into the string.

If this still seems weird to you, there’s more info in the Python docs.

https://docs.python.org/3/library/stdtypes.html#printf-style-string-formatting

It explains what the modulo % operator is for, and how you can use it, in the context of formatting strings. :slight_smile:

Awesome. Thank you. That may actually help on the project I’m working on now.

Thanks again!!

1 Like

Hi everyone, this is driving me crazy, I understand what the error I am getting is, but I do not understand why I am getting it. I

The error: la_arts = find_attractions(“Los Angeles, U
SA”, [“art”])
File “script.py”, line 48, in find_attractio
ns
attractions_in_city = attractions[destinat
ion_index]
UnboundLocalError: local variable 'attractions
’ referenced before assignment

My code;

def find_attractions(destination, interests):
  destination_intex = get_destination_index(destination)
  attractions_in_city = attractions[destination_index]
  attractions_with_interest = []

  for attractions in attractions_in_city:
    possible_attraction = attraction
    attraction_tags = attraction[1]
    for interest in interests:
      if interest in attraction_tags: 
        attractions_with_interest.append(possible_attaction)
 
  return attractions_with_interest

la_arts = find_attractions("Los Angeles, USA", ["art"])
print(la_arts)