1
votes

I'm very new to computer programming and am currently writing a program in PyCharm Community that, when given the name of a student at my school, will print out directions to said student's house from the school.

Everything has been going very well, and I got the base of it working last night. Today I opened my computer and for some reason my program refuses to run my 'if'/'elif' statements and will only run the else statement even when it's given a value that satisfies the 'if'/'elif' statement.

I have tried rewriting the program, restarting PyCharm multiple times, making sure I'm consistent with spaces and tabs, and made sure that my variables can all communicate with each other. I have dug for awhile on here and other websites and I just cannot see a reason as to why my code was working yesterday but now refuses to run anything but the else statement.

Here is my code, it will ask the user "Where would you like to go?" and then will receive an input of " house". Once it receives this it will print out their directions. Instead of this, it runs the 'else' statement every single time.

# Storing the names and directions of users:
David = "Directions to David's home from T... \n East on X, \n South on Y.," \
            " \n West on Z., \n South on A., \n first white house on the right."

Caroline = "Directions to Caroline's home from T... \n East on x, \n South on y.," \
        " \n East on z., \n South on p., \n East on q," \
        " \n West on t., \n last brick house in the cul-de-sac."

William = "Directions to Will's home from T... \n East on x, \n South on y.," \
        " \n West on z., \n South on Fa., \n West on b., \n first house on the right."

Bannon = "<Insert directions to Bannon's house>"

# User gives a specific name and then receives a location:
while True:
    destination = input("Where would you like to go? ")

    if destination.casefold() == 'Davids house':
        print(David)
        continue

    elif destination.casefold() == 'Carolines house':
        print(Caroline)
        continue

    elif destination.casefold() == 'Wills house':
        print(William)
        continue

    elif destination.casefold() == 'Bannons house':
        print(Bannon)
        continue

    # If an invalid location is given, this code will run:
    else:
        print("Sorry, that location wasn't found! Please try again.")
        continue
3
The .casefold() will convert the destination input to lowercase, and you're comparing it to text with an uppercase letter, so it won't ever work like that. Either remove casefold or convert all the strings you are comparing them to into lowercasemarsnebulasoup

3 Answers

2
votes

casefold converts the string to lowercase, and your reference strings include uppercase characters.

As a simple fix, you could change 'Davids house' to 'davids house', etc.

Long term, you might want to implement a slightly less fragile comparison, but that's a big exercise and depends on how your program is going to be used and what the consequences of failure-to-parse are.

2
votes

For typo correction and support for users doing things that break the tests, here is an example using string similarity comparison to determine if the input is close to any user's name:

import difflib
# Storing the names and directions of users: 
#This is called a dictionary. More info here https://www.w3schools.com/python/python_dictionaries.asp
directions= {
    "David": "Directions to David's home from T... \n East on X, \n South on Y.," \
            " \n West on Z., \n South on A., \n first white house on the right.",

    "Caroline": "Directions to Caroline's home from T... \n East on x, \n South on y.," \
        " \n East on z., \n South on p., \n East on q," \
        " \n West on t., \n last brick house in the cul-de-sac.",

    "William":"Directions to Will's home from T... \n East on x, \n South on y.," \
        " \n West on z., \n South on Fa., \n West on b., \n first house on the right.",

    "Bannon":"<Insert directions to Bannon's house>"
}

# User gives a specific name and then receives a location:
while True:
    destination = input("Where would you like to go? ")

    highest = 0 #highest score between the user name and input
    user_key = "" #name of the user who most closely matches the input
    for user in directions: #iterate through all the user's names in the directions dictionary
      similarity = difflib.SequenceMatcher( #for each user's name, compare it to the input
          None, destination, user).ratio()
      if(similarity > highest): #if the similarity score is greater than the highest recorded score, update the score
        highest = similarity
        user_key = user
    
    #Code that runs if a match is too low are not found
    if(highest < 0.5): #adjust this based on how close you want the match to be. highest will always be between 0.0 and 1.0
      print("Sorry, that location wasn't found! Please try again.")
      continue

    #Print user's directions
    else:
      print('\n\nGetting directions to ' + user_key + '\'s house\n\n')
      print(directions[user_key] + "\n\n\n")

So if you enter 'William's house', 'William', 'William's house', 'Williamm', or something close to 'William', you'll get the directions to William's house.

Run it online: https://repl.it/@marsnebulasoup/UprightMutedSymbol

1
votes

Minimize the program and test! You posted more code than needed to demonstrate the problem. Once you get something like if destination.casefold() == 'Davids house': not working, minimize to that one issue with canned data

destination = "david's house"
if not destination.casefold() == "Davids house":
    print(repr(destination), "failed")

This prints

"david's house" failed

The help for casefold says Return a version of the string suitable for caseless comparisons.. Ah, that's it. You need to casefold both sides. And then there is that pesky apostrophe. Maybe you need more normalization like getting rid of non-alphabetic characters.

By minimizing, you wrote a good test for your code. You could write a small compare function that does the casefold and other normalization. You could then write a dozen tests on that function to test all of the edge cases.