Difference between revisions of "CSC111 Lab 8 2015b"

From dftwiki3
Jump to: navigation, search
Line 305: Line 305:
 
=Solution Programs=
 
=Solution Programs=
 
<br />
 
<br />
 +
==Text Processing==
 +
<br />
 +
::<source lang="python">
 +
import urllib.request
  
 +
 +
def getFileFromWeb( URL ):
 +
    """
 +
    Grabs the file located at the given URL, decodes
 +
    it as a regular text string, and returns the string.
 +
    """
 +
    response = urllib.request.urlopen(URL)
 +
    text = response.read().decode('utf-8')
 +
    #print( text )
 +
    return text
 +
 +
def findNapoleon( lines ):
 +
    """
 +
    Lists all the lines that contain the word Napoleon.
 +
    """
 +
    for line in lines:
 +
        #print( "line = ", line[0:40] )
 +
        if line.lower().find( "napoleon" ) != -1:
 +
            print( line )
 +
 +
def whoSaysNapoleon( lines ):
 +
    """
 +
    Figures out who of the 3 characters say the word
 +
    Napoleon
 +
    """
 +
    stanley = False
 +
    blanche = False
 +
    stella  = False
 +
    for line in lines:
 +
        if line.lower().find( "napoleon" )!= -1:
 +
            character = line.split()[0]
 +
            if character == "STANLEY:":
 +
                stanley = True
 +
            if character == "BLANCHE:":
 +
                blanche = True
 +
            if character == "STELLA:":
 +
                stella = True
 +
 +
    print()
 +
    print( "Napoleon" )
 +
    if stanley:
 +
        print( "Stanley" )
 +
    if blanche:
 +
        print( "blanche" )
 +
    if stella:
 +
        print( "stella" )
 +
 +
 +
def whoSaysLiquor( lines ):
 +
    """
 +
    Figures out who says words related to alcohol
 +
    the most.
 +
    """
 +
    # create 3 counters
 +
    stanley = 0
 +
    blanche = 0
 +
    stella  = 0
 +
 +
    # define the keywords to look for
 +
    keywords = ["drink", "liquor", "whiskey"]
 +
 +
    # process each line separately
 +
    for line in lines:
 +
        # get the lowercase version, just to be safe
 +
        line = line.lower()
 +
 +
        # check which keyword, if any, appears in each line
 +
        for keyword in keywords:
 +
            if line.find( keyword ) != -1:               
 +
                character = line.split()[0]
 +
                if character == "STANLEY:":
 +
                    stanley = stanley + 1
 +
                if character == "BLANCHE:":
 +
                    blanche = blanche + 1
 +
                if character == "STELLA:":
 +
                    stella = stella + 1
 +
 +
    print()
 +
    print( "liquor" )
 +
    if stanley > stella and stanley > blanche:
 +
        print( "Stanley" )
 +
    elif blanche > stella and blanche > stanley:
 +
        print( "blanche" )
 +
    else:
 +
        print( "stella" )
 +
   
 +
def main():
 +
    URL = "http://cs.smith.edu/~dthiebaut/classes/111/streetcar.txt"
 +
 +
    text = getFileFromWeb( URL )
 +
 +
    # transform text into lines for easier processing.
 +
    lines = text.splitlines()
 +
 +
    # print all the lines containing "Napoleon"
 +
    findNapoleon( lines )
 +
 +
    # figure out who says "Napoleon"
 +
    whoSaysNapoleon( lines )
 +
 +
    # figure out who says liquor the most
 +
    whoSaysLiquor( lines )
 +
   
 +
main()
 +
 +
</source>
 +
<br />
 
</showafterdate>
 
</showafterdate>
 
<br />
 
<br />

Revision as of 22:17, 26 October 2015

--D. Thiebaut (talk) 13:58, 26 October 2015 (EDT)




<showafterdate after="20151028 12:00" before="20151231 00:00">

Reminder: Please continue working in pairs. The deadline for submitting on Moodle is Friday 10/30/15, at 11:55 p.m.



Preamble


For the first part of this lab you will write a long program called lab8.py that will include all the functions that are the solutions to the various exercises. Your program will contain one main() function that will call and test all your functions.


Part 1: While Loops


Exercise 1: Robust Input with While Loops

QuestionMark1.jpg


def getPositiveNumber():
    #
    # put your code here
    #
    return 10   # just to make sure the code is accepted by Idle


def main():

    # Part 1, Exercise 1
    x = getPositiveNumber()
    print( "getPositiveNumber() returned", x )

if __name__=="__main__":
    main()


Remove the return 10 statement in getPositiveNumber(), and complete the function so that it asks the user for a number larger than 0, and keeps on prompting the user as long as she doesn't enter a valid number.

Below is an example of the interaction between computer and user.

Please enter a number greater than 0: -1
-1 is invalid.
Please enter a number greater than 0: -3
-3 is invalid.
Please enter a number greater than 0: 0
0 is invalid.
Please enter a number greater than 0: 20
getPositiveNumber() returned 20
>>>



Exercise 2: Ask for Yes/No answer

QuestionMark2.jpg



Same idea as in Exercise 1, but this time the new function, called likesChoco() will keep on asking a question until the user's input is "YES", "yes", "y", "NO", "no", or "n". Any combination of lower/upper case in the spelling is accepted ("yES" is valid). The function will return True if the user answers yes, and False otherwise.

Source


def likesChoco():
    #
    # put your code here
    #
    return True    # just to make sure the code works as is.
            
def main():
    # Part1, Exercise 2
    if likesChoco() == True:
        print( "Me too!" )
    else:
        print( "Sorry to hear that!" )
        
if __name__=="__main__":
    main()


Example output


Do you like chocolate (Y/N)? possibly
please enter by 'Yes' or 'No'

Do you like chocolate (Y/N)? I don't know
please enter by 'Yes' or 'No'

Do you like chocolate (Y/N)? Oui
please enter by 'Yes' or 'No'

Do you like chocolate (Y/N)? y
Me too!



Exercise 3: While Loop and Reading File

QuestionMark3.jpg


# createFile: creates a text file containing a haiku followed by the line <<<END>>>
# followed by some text about the source of the haiku and the rights of use.
def createFile( fileName ):

    # open the file
    file = open( fileName, "w" )

    # write some text
    file.write("""
    An old pond!
    A frog jumps in-
    The sound of water.
    <<<END>>>
    Haikus from http://www.toyomasu.com/haiku/
    Feel free to use anything from this page as
    long as you make references and links to HAIKU
    for PEOPLE. Last updated: Jan 10th. 2001.
    Edited by Kei Grieg Toyomasu,
    kei at toyomasu dot com""" )

    # close the file
    file.close()

def readFileTillMarker( fileName ):
    #
    # add your code here
    #
    return []   # just to make sure the code compiles. 

def main():
    # Part 1, Exercise 3
    # create a sample text file for testing.  The file will contain the string <<<END>>>
    # in it.
    createFile( "lab8Demo.txt" )

    # get all the lines before but not including <<<END>>>
    lines = readFileTillMarker( "lab8Demo.txt" )

    # display the lines returned.  We strip them to remove the extra \n at the end and
    # the extra spaces at the front of each line.
    print( "Lines found by readFileTillMarker(): " )
    for line in lines:
        print( line.strip() )
        
if __name__=="__main__":
    main()


Same idea as the previous 2 exercises. This time you need to add code to the function readFileTillMarker() so that it will read all the lines contained in the file whose name is passed as a parameter, and that appear before the marker string <<<END>>>. In other words, the function reads the lines, adds them to a list of lines, until it finds a line containing the string <<<END>>>. It returns a list of all the lines read.

The function createFile() creates a simple file you can use for testing. Take a look at it to make sure you understand the format of the data.

Here's an example of how your program should work.


Lines found by readFileTillMarker(): 

An old pond!
A frog jumps in-
The sound of water.



Exercise 4: A bit of mathematics

QuestionMark4.jpg


Pi can be computed by adding the following terms (http://en.wikipedia.org/wiki/Pi):

Pi expansion.png


Below is a program that loops 10 times and add up the terms of the series. The program shows how the variable sum, where we accumulate the terms, gets closer and closer to PI as the loop progresses.

def computePi():
    sum = 0
    multiplier = 1
    
    for i in range( 1, 20, 2 ):
        sum = sum + multiplier * 4.0 / i
        multiplier = -multiplier
        print( "Pi = ", sum )

Modify this program so that it stops when the first 3 digits of sum are equal to 3.14. It is not acceptable to run a large number of iterations to figure out how many are necessary and change the limit of the for-loop to make it stop at the right place. Instead, your solution should use a while loop, which will stop when the sum is a number of the form 3.14xxxxxxx. Make your modified function print only the last value of sum, not all the different values it takes.



Processing Text


This part of the lab deals with finding keywords in text, very similarly to the way keywords such as "mother" or "father" were found by the Eliza program in a conversation with the user.

Preparation


For this lab, you will be writing a program that looks for particular patterns in a play by Tennessee Williams: A Streetcar Named Desire. I have removed extra stage information from the play so that it contains only the dialogs.

  • Get a sample of the play using this seed program, called lab8key.py:


# lab8key.py
# your names
# Fetches a text file from a Web site and prints it.

from urllib.request import urlopen  # library for requesting 
    
def main():
    # the URL of the text file
    URL = "http://cs.smith.edu/~dthiebaut/classes/111/streetcarShort.txt"

    # open the URL
    response = urlopen(URL)

    # get its contents, and store it in a string called text
    text = response.read().decode('utf-8')

    # print the string
    print( text )


main()


  • Run this program. Verify that you get a dialog between two characters in the play, Stella, and her sister Blanche.


Note that every character's name will appear in uppercase at the beginning of each line. Every paragraph spoken by a character is a string that ends with a \n.


Who's speaking most often, Stella or Blanche?


  • Make your program count how many lines (and not words) each of the two character speaks.


Who's speaking the longest, Stella or Blanche?


  • Modify the program so that you will count how many words Blanche is speaking, and how many words Stella is.
  • Make your program output the name of the character who speaks more.
  • Hints: As an intermediate step, you may want to make your program output two lines, each line containing the name of a character followed by the number of words she speaks.


Who mentions Stanley first, Stella or Blanche?


  • An important character in the play is Stanley (who was played by Marlon Brando in the movie of the play). Who mentions Stanley first in this short excerpt from the play?
  • Hints: Remember that you can break out of a look when a given condition occurs!


Who is Drinking


  • Which of the two characters mentions the words "drink", "drinks", "liquor" the most?
  • Hints: you can use the in operator to see if a word is in a list of words...


Analyzing The Whole Play


  • Two characters mention the word "Napoleon" in this play. What lines does this word appear in?
  • What are the names only of the two characters who pronounce the word "Napoleon" in their line. For example, if Stanley says 5 lines containing the word Napoleonic, and Stella only one line, your program should output only
       Stanley
       Stella

  • Which of the three characters mentions the words "drink", "drinks", "liquor" or "whiskey" the most?



Moodle Submission


  • Save the program that answers the questions regarding the whole play in a file called lab8key.py and submit it to the Moodle LAB 8 section.


</showafterdate>

<showafterdate after="20151031 23:55" before="20151231 00:00">

Solution Programs


Text Processing


import urllib.request 


def getFileFromWeb( URL ):
    """
    Grabs the file located at the given URL, decodes
    it as a regular text string, and returns the string.
    """
    response = urllib.request.urlopen(URL)
    text = response.read().decode('utf-8')
    #print( text )
    return text

def findNapoleon( lines ):
    """
    Lists all the lines that contain the word Napoleon.
    """
    for line in lines:
        #print( "line = ", line[0:40] )
        if line.lower().find( "napoleon" ) != -1:
            print( line )

def whoSaysNapoleon( lines ):
    """
    Figures out who of the 3 characters say the word
    Napoleon
    """
    stanley = False
    blanche = False
    stella  = False
    for line in lines:
        if line.lower().find( "napoleon" )!= -1:
            character = line.split()[0]
            if character == "STANLEY:":
                stanley = True
            if character == "BLANCHE:":
                blanche = True
            if character == "STELLA:":
                stella = True

    print()
    print( "Napoleon" )
    if stanley:
        print( "Stanley" )
    if blanche:
        print( "blanche" )
    if stella:
        print( "stella" )


def whoSaysLiquor( lines ):
    """
    Figures out who says words related to alcohol
    the most.
    """
    # create 3 counters
    stanley = 0
    blanche = 0
    stella  = 0

    # define the keywords to look for
    keywords = ["drink", "liquor", "whiskey"]

    # process each line separately
    for line in lines:
        # get the lowercase version, just to be safe
        line = line.lower()

        # check which keyword, if any, appears in each line
        for keyword in keywords:
            if line.find( keyword ) != -1:                
                character = line.split()[0]
                if character == "STANLEY:":
                    stanley = stanley + 1
                if character == "BLANCHE:":
                    blanche = blanche + 1
                if character == "STELLA:":
                    stella = stella + 1

    print()
    print( "liquor" )
    if stanley > stella and stanley > blanche:
        print( "Stanley" )
    elif blanche > stella and blanche > stanley:
        print( "blanche" )
    else:
        print( "stella" )
    
def main():
    URL = "http://cs.smith.edu/~dthiebaut/classes/111/streetcar.txt"

    text = getFileFromWeb( URL )

    # transform text into lines for easier processing.
    lines = text.splitlines()

    # print all the lines containing "Napoleon"
    findNapoleon( lines ) 

    # figure out who says "Napoleon"
    whoSaysNapoleon( lines )

    # figure out who says liquor the most
    whoSaysLiquor( lines )
    
main()


</showafterdate>