CS 21, Spring 2017

Week 3 - Friday

Once you finish your quiz, take a break for a few minutes and then begin working your way through these exercises. Please don't start typing until all of your classmates have finished the quiz. Until then, just use pencil and paper so as not to disturb anyone who is still working.

On Wednesday we discussed the logical operators—and, or, not—as well as multiway if-statements that include one or more elif blocks between the initial if block and the (optional) final else block. Today we will continue to get practice with these features of Python. We'll also continue to use plain if and if-else statements and the conditional operators: ==, !=, <, <=, >, >=.

There's one new conditional operator we'll encounter today called the in operator. This is different from the word in when it appears within a for loop, as we'll see. The in operator takes any value to its left and any sequence (list or string) to its right. It evaluates to True if the value is one of the items in the sequence, and to False otherwise. For instance, 1 in [1, 2, 3] and 'm' in 'swarthmore' evaluate to True whereas 10 in range(5) is False. It's also valid to use not in as an operator, which is True when in would have been False and is False when in would have been True.

  1. Write a program that asks the user to enter an integer and then tells the user whether the integer is even or odd. Use string formatting to generate the output string. Hint: use the % operator to find the remainder of the integer when it's divided by 2.

    $ python evenodd.py
    Enter an integer: 12
    12 is even
    $ python evenodd.py
    Enter an integer: 7
    7 is odd
    
  2. Fill in the blanks in the truth table below to verify De Morgan's Laws, which assert the following:

    # A and B are booleans
    not (A or B) == (not A) and (not B)
    not (A and B) == (not A) or (not B)
    A B not A not B A or B A and B not (A or B) (not A) and (not B) not (A and B) (not A) or (not B)
    T T F F T T
    T F F T T F
    F T T F T F
    F F T T F F

    Once you finish, if columns 7 and 8 are the same, that verifies De Morgan's first law. If columns 9 and 10 are the same, that verifies De Morgan's second law.

  3. Together we will write a program that helps the user decide what mode of transportation they should use when planning a trip. We'll ask the user how far they're going, whether there's a body of water along the route, and if there is a body of water, whether that body of water has a bridge over it. The table below will help us decide whether the program should recommend travel by foot, bike, car, train, boat, or plane.

    Distance in miles No water or water w/ bridge Water without bridge
    2 or less Foot Boat
    More than 2, up to 10 Bike Boat
    More than 10, up to 200 Car Boat
    More than 200, up to 500 Train Plane
    More than 500 Plane Plane

    Here's what running the program will look like:

    $ python travel.py
    How long is the journey in miles? 10
    Is there water along the route? n
    
    You should travel by bike.
    $ python travel.py
    How long is the journey in miles? 300
    Is there water along the route? y
    Is there a bridge over the water? y
    
    You should travel by train.
    

    When you log in and run update21 you'll get a file travel.py that does most of this program, but contains a bug. In case your classmates are still working on the quiz, I'll show the code here:

    """
    This program asks the user questions to help them determine
    what mode of transportation to use.
    
    David Mauskop and [YOUR NAME HERE], CS 21
    """
    
    def main():
        miles = int(raw_input("How long is the journey in miles? "))
        water = raw_input("Is there water along the route? ")
        if water == 'y':
            bridge = raw_input("Is there a bridge over the water? ")
    
        if (water == 'n') or (bridge == 'y'):
            if miles <= 2:
                mode = "foot"
            if miles <= 10:
                mode = "bike"
            if miles <= 200:
                mode = "car"
            if miles <= 500:
                mode = "train"
            else:
                mode = "plane"
        else:
            if miles <= 200:
                mode = "boat"
            else:
                mode = "plane"
    
        print("\nYou should travel by %s" % mode)
    
    main()

    Read the code and try to understand what it's doing. Note that when \n appears within a string that tells Python to print a blank line. Can you spot the bug? Here's an example run that illustrates the bug:

    $ python travel.py
    How long is the journey in miles? 10
    Is there water along the route? n
    
    You should travel by train.
    

    We don't get an error, but the program was supposed to tell the user to travel by bike. Do you see what we did wrong? If not, give it some thought and then ask me or the ninjas for help if you're still stuck.

    Once you fix the bug, let's extend the program to make it more flexible in terms of the inputs it will accept. All of the following should be registered as a 'yes' response: "y", "Y", "yes", "Yes". And all of these should count as a 'no' response: "n", "N", "no", "No". This would be a good time to use the in operator, as described at the top of the page. Add the following lines to the top of your program:

    yesses = ['y', 'Y', 'yes', 'Yes']
    nos = ['n', 'N', 'no', 'No']

    Then replace every use of the == operator with a use of the in operator, taking advantage of yesses and nos, each of which is a list of strings.

  4. Write a program, compatibility.py, that asks the user four questions about things they like, and then compares their favorite things to your favorite things.

    Running the program might look like this:

    $ python compatibility.py
    
    Favorite food? pizza
    ------- Me too!
    
    Favorite author? Steinbeck
    ------- Steinbeck is OK, but I prefer Tolkien.
    
    Favorite band? The Beatles
    ------- Me too!
    
    Favorite planet? Earth
    ------- Earth is OK, but I prefer Mars.
    
    2 out of 4 preferences the same.
    You're cool I guess.
    $ python compatibility.py
    
    Favorite food?  pizza
    ------- Me too!
    
    Favorite author? Tolkien
    ------- Me too!
    
    Favorite band? The Beatles
    ------- Me too!
    
    Favorite planet? Mars
    ------- Me too!
    
    4 out of 4 preferences the same.
    Did we just become best friends?
    

    Store the questions and preferences in a list of strings, like questions = ["food", "author", "band", "planet"] and prefs = ["pizza", "Tolkien", "The Beatles", "Mars"]. Feel free to pick your own questions and preferences. Use a for loop with indexing to avoid typing repetitive lines of code. Count how many preferences you and the user have in common. Show this to the user along with a suitable reaction to the results.

    It's okay if the answers are case-sensitive, as in the following example run:

    $ python compatibility.py
    Favorite food? Pizza
    ------- Pizza is OK, but I prefer pizza.
    
    Favorite author? tolkien
    ------- tolkien is OK, but I prefer Tolkien.
    
    Favorite band? beatles
    ------- beatles is OK, but I prefer The Beatles.
    
    Favorite planet? mars
    ------- mars is OK, but I prefer Mars.
    
    0 out of 4 preferences the same.
    We have absolutely nothing in common.
    
  5. Write a program that asks the user to enter a DNA strand, and determines whether the input is actually a DNA strand, i.e. it only consists of "A", "T", "C", and "G". To do this, create a boolean variable named valid_dna that's initially set to True. Traverse the input string with a for loop, and check each character to see whether it's valid. If you see an invalid character, set valid_dna variable to False. Once the for loop finishes, print a message depending on the final value of valid_dna. When we use a boolean variable in this way, it's sometimes referred to as a boolean flag.

    $ python dna.py
    Enter a DNA strand: ATCGAGTTACG
    That looks like valid DNA.
    $ python dna.py
    Enter a DNA strand: ATCCT@G
    That's not valid DNA.
    

Have a nice weekend!!