Difference between revisions of "CSC111 Lab 8 2015b"

From dftwiki3
Jump to: navigation, search
 
(31 intermediate revisions by 2 users not shown)
Line 10: Line 10:
 
</bluebox>
 
</bluebox>
 
<br />
 
<br />
<br />
 
=Preamble=
 
<br />
 
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. 
 
 
 
<br />
 
<br />
  
Line 44: Line 36:
 
     print( "getPositiveNumber() returned", x )
 
     print( "getPositiveNumber() returned", x )
  
if __name__=="__main__":
+
main()
    main()
 
 
</source>
 
</source>
 
<br />
 
<br />
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.
+
Remove the '''return 10''' statement in ''getPositiveNumber()'', and complete the function so that it asks the user for a number larger than 0, and will keep on repeating the prompting until the user enters a number greater than 0.  This way the function will always return a number greater than 0 to the main program.
  
 
Below is an example of the interaction between computer and user.
 
Below is an example of the interaction between computer and user.
Line 93: Line 84:
 
         print( "Sorry to hear that!" )
 
         print( "Sorry to hear that!" )
 
          
 
          
if __name__=="__main__":
+
main()
    main()
 
 
</source>
 
</source>
 
<br />
 
<br />
Line 101: Line 91:
 
::<source lang="text">
 
::<source lang="text">
 
Do you like chocolate (Y/N)? possibly
 
Do you like chocolate (Y/N)? possibly
please enter by 'Yes' or 'No'
+
please enter 'Yes' or 'No'
  
 
Do you like chocolate (Y/N)? I don't know
 
Do you like chocolate (Y/N)? I don't know
please enter by 'Yes' or 'No'
+
please enter 'Yes' or 'No'
  
 
Do you like chocolate (Y/N)? Oui
 
Do you like chocolate (Y/N)? Oui
please enter by 'Yes' or 'No'
+
please enter 'Yes' or 'No'
  
 
Do you like chocolate (Y/N)? y
 
Do you like chocolate (Y/N)? y
Line 118: Line 108:
 
|
 
|
  
==Exercise 3: While Loop and Reading File==
+
==Exercise 3: if/else versus elif==
 
|}
 
|}
 
[[Image:QuestionMark3.jpg|right|120px]]
 
[[Image:QuestionMark3.jpg|right|120px]]
 
+
<br />
 +
<br />
 +
* Create a new program (lab8_3.py) with the following bit of code:
 
<br />
 
<br />
 
::<source lang="python">
 
::<source lang="python">
# createFile: creates a text file containing a haiku followed by the line <<<END>>>
+
def main():
# followed by some text about the source of the haiku and the rights of use.
 
def createFile( fileName ):
 
  
     # open the file
+
     grade = input( "Grade? " ).upper().strip()
    file = open( fileName, "w" )
 
  
     # write some text
+
     if grade == "A":
    file.write("""
+
        print( "Excellent job!" )
     An old pond!
+
     else:
    A frog jumps in-
+
        if grade == "B":
    The sound of water.
+
            print( "Very nice" )
    <<<END>>>
+
        else:
    Haikus from http://www.toyomasu.com/haiku/
+
            print( "Below B.  Make an effort!" )
    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
+
main()
    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()
 
 
</source>
 
</source>
 
<br />
 
<br />
Same idea as the previous 2 exercisesThis 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.
+
* Run the codeVerify that it gives correct answers for all letters "A" to "F".
 +
* Complete the code with additional '''if''' and '''else''' statements so that your program will give  a different answer for "C", "D", and "F".
 +
<br />
 +
* You will have noticed that your code is indented to the right in a diagonal fashion.  That's typical of this type of decision programs.  Python supports the '''elif''' statement, though, that allows one to write cleaner code.  '''elif''' stands for '''else if'''. The code above, with '''elif''' would look something like this:
 +
<br />
 +
::<source lang="python">
 +
def main():
 +
    grade = input( "Grade? " ).upper().strip()
  
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.
+
    if grade == "A":
 +
        print( "Excellent job!" )
 +
    elif grade == "B":
 +
        print( "Very nice" )
 +
    else:
 +
        print( "Below B. Make an effort!" )
  
Here's an example of how your program should work.
+
main()
 
 
<br />
 
::<source lang="text">
 
Lines found by readFileTillMarker():
 
  
An old pond!
 
A frog jumps in-
 
The sound of water.
 
 
</source>
 
</source>
 
<br />
 
<br />
 
+
* When using if/elif/else, the general rule is that you should:
 +
::# start with an '''if'''
 +
::# use one or more '''elif''' statements
 +
::# end with an '''else'''
 +
* Complete the program above with additional '''elif''' statements so that it can have a different answer for 'A', 'B', 'C', 'D' and 'F'.
 
<br />
 
<br />
 
{| style="width:100%; background:silver"
 
{| style="width:100%; background:silver"
 
|-
 
|-
 
|
 
|
==Exercise 4: A bit of mathematics==
+
 
 +
==Exercise 4: While and Elifs==
 
|}
 
|}
 
[[Image:QuestionMark4.jpg|right|120px]]
 
[[Image:QuestionMark4.jpg|right|120px]]
  
 
<br />
 
<br />
Pi can be computed by adding the following terms (http://en.wikipedia.org/wiki/Pi):
 
 
<center>
 
[[Image:pi_expansion.png]]
 
</center>
 
 
<br />
 
<br />
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.
+
* Combine what you worked on today and put the section that asks for a grade and output a qualification of the grade inside a loop.   Make the loop output "Invalid grade" for any letter that is not 'A', 'B', 'C', 'D', or 'F', and make the loop stop when the grade entered is 'Q' (for quit).
 +
<br />
 +
* Example of how your program should work:
 
<br />
 
<br />
::<source lang="python">
+
::<source lang="text">
def computePi():
+
Grade? A
    sum = 0
+
Excellent job!
    multiplier = 1
+
 
   
+
Grade? B
    for i in range( 1, 20, 2 ):
+
Great job!
        sum = sum + multiplier * 4.0 / i
+
 
        multiplier = -multiplier
+
Grade? a
        print( "Pi = ", sum )
+
Excellent job!
 +
 
 +
Grade? z
 +
Invalid grade
 +
 
 +
Grade? lemon
 +
Invalid grade
  
</source>
+
Grade? q
 +
Good bye!
  
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.
+
>>>
  
<br />
+
</source>
 
----
 
----
 
=Processing Text=
 
=Processing Text=
 
<br />
 
<br />
 
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 [[Turing_Test_and_Eliza| Eliza program]] in a conversation with the user.
 
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 [[Turing_Test_and_Eliza| Eliza program]] in a conversation with the user.
 +
<br />
 +
==Video Introduction==
 +
<br />
 +
<center><videoflash>yN2K3tQjZ6c</videoflash></center>
 
<br />
 
<br />
 
==Preparation==
 
==Preparation==
Line 229: Line 208:
 
For this lab, you will be writing a program that looks for particular patterns in a play by Tennessee Williams: [https://www.youtube.com/watch?v=u9YgJjSCT08 ''A Streetcar Named Desire.'']  I have removed extra stage information from the play so that it contains only the dialogs.
 
For this lab, you will be writing a program that looks for particular patterns in a play by Tennessee Williams: [https://www.youtube.com/watch?v=u9YgJjSCT08 ''A Streetcar Named Desire.'']  I have removed extra stage information from the play so that it contains only the dialogs.
 
<br />
 
<br />
* Get a sample of the play using this seed program, called '''lab8key.py''':
+
* Get a sample of the play using this seed program, called '''lab8GetPlay.py''':
 
<br />
 
<br />
 
::<source lang="python">
 
::<source lang="python">
# lab8key.py
+
# lab8GetPlay.py
 
# your names
 
# your names
 
# Fetches a text file from a Web site and prints it.
 
# Fetches a text file from a Web site and prints it.
Line 248: Line 227:
 
     text = response.read().decode('utf-8')
 
     text = response.read().decode('utf-8')
  
     # print the string
+
     # save the string to file
     print( text )
+
     open( "streetcarShort.txt", "w" ).write( text )
  
  
Line 255: Line 234:
 
</source>
 
</source>
 
<br />
 
<br />
* Run this program.  Verify that you get a dialog between two characters in the play, Stella, and her sister Blanche.
+
* Run this program.  Verify that you have a new text file in the folder where you have saved the program.
 +
* Open the new file '''streetcarShort.txt''' and verify that you see a dialog between two characters in the play, Stella, and her sister Blanche.
 
<br />
 
<br />
 
<tanbox>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.   
 
<tanbox>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.   
 
</tanbox>
 
</tanbox>
 
<br />
 
<br />
==Who's speaking most often, Stella or Blanche?==
+
==Who's speaking most often, Stella, Stanley, or Blanche?==
 
<br />
 
<br />
* Make your program count how many '''lines''' (and not words) each of the two character speaks.
+
* Write a new program called '''lab8key.py''' that prompts the user for the name of a file, opens it, and counts how many '''lines''' (and not words) each of the three characters, Blanche, Stanley, or Stella, says.
<br />
+
* Hints 1: Look up the '''count()''' method in this [https://docs.python.org/3/library/stdtypes.html page], and see if it can help you out...
==Who's speaking the longest, Stella or Blanche?==
+
* Hints 2: You can also go through each line and ''count'' how often you see "STANLEY:", how often you see "STELLA:", and how often you see "BLANCHE:".
<br />
 
* 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.
 
 
<br />
 
<br />
 
==Who mentions Stanley first, Stella or Blanche?==
 
==Who mentions Stanley first, Stella or Blanche?==
 
<br />
 
<br />
 
* 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?
 
* 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!
+
* ''Hints:'' Remember that you can '''break''' out of a look when a given condition occurs!   To see if a line is being said by "Blanche", for example, you can write <tt>if "BLANCHE:" in line: </tt> or <tt>if line.find( "BLANCHE:" ) != -1: </tt>.
 
<br />
 
<br />
 
==Who is Drinking==
 
==Who is Drinking==
 
<br />
 
<br />
* Which of the two characters mentions the words "drink", "drinks", "liquor" the most?
+
* Which of the three characters mention(s) the words "drink", "liquor", or "whiskey"?  Here we don't want to know how many times they say the words, just the fact that they may have said one of them.
* ''Hints:'' you can use the '''in''' operator to see if a word is '''in''' a list of words...
+
* ''Hints:'' Loop through the alcohol keywords, and see if any one of them is in a line.  If one of them is, then see if "BLANCHE:", or "STANLEY:", or "STELLA:" also appears (is '''in''') the line.  Depending on which character name appears, you can "remember" that this character said such a word'''Boolean variables''' are perfect for that! 
 
<br />
 
<br />
 
==Analyzing The Whole Play==
 
==Analyzing The Whole Play==
 
<br />
 
<br />
* Change the URL in your program to http://cs.smith.edu/~dthiebaut/classes/111/streetcar.txt (i.e., the same as before, but remove the word '''Short''' from it).
+
* Modify the program '''lab8GetPlay.py''' and change the URL and the file name in the '''open(...)''' statement from '''streetcarShort.txt''' to '''streetcar.txt'''.
* Answer the following questions regarding the three main characters: Stanley, Stella, and Blanche.
+
* Run '''lab8GetPlay.txt''' and verify that you have a new file in your folder called '''streetcar.txt'''. It should contain the whole play.   The last line of the play is "The end."
::* Two characters mention the word "Napoleon" in this play.  What lines does this word appear in?
+
* Modify your '''lab8key.py''' program, and make it answer the following questions regarding the three main characters, Stanley, Stella, and Blanche:
::* 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
+
::* Several characters mention the word "Napoleon" in this play.  Print the lines where this word appears.
 +
::* What are the names, and only the names, of the characters who pronounce the word "Napoleon" in their lines.  For example, if Stanley says 5 lines containing the word Napoleonic, and Stella only one line, your program should output one blank line followed by
 
   
 
   
 +
 +
        Napoleon
 
         Stanley
 
         Stanley
 
         Stella
 
         Stella
 
   
 
   
::* Which of the three characters mentions the words "drink", "drinks", "liquor" or "whiskey" the most?
+
::: You should list the names in alphabetical order, i.e. Blanche should be first, if she's in the list, then Stanley, if he's in the list, then Stella, if she's in the list.
 +
::* Which of the three characters mentions the words "drink", "liquor" or "whiskey"?  List the answers in alphabetical order of their name under the heading "Liquor".  Example:
 +
 +
      Liquor
 +
      Stella
 +
 
  
 
<br />
 
<br />
 +
==Typical Program Output==
 +
<br />
 +
:Here is what your output '''could''' look like.  This may not be the solution to the lab!
 +
<br />
 +
::<source lang="text">
 +
File name? streetcar.txt
 +
 +
STANLEY:  Have you ever heard of the Napoleonic code?
 +
STELLA:  No, Stanley, I haven't heard of the Napoleonic code, if I have, I don't see what it--
 +
STANLEY:  In the state of Louisiana we have the Napoleonic code according to which what belongs to the  wife belongs to the husband and vice versa. For instance if I had a piece of property, or you had a  piece of property--
 +
STANLEY:  All right, I'll wait till she gets through soaking in a hot tub and then I'll inquire if she is  acquainted with the Napoleonic code. It looks to me like you have been swindled, baby, and  when you're swindled under the Napoleonic code I'm swindled too. And I don't like to be  swindled.
 +
STANLEY:  There is such a thing in this state of Louisiana as the Napoleonic code, according to which  whatever belongs to my wife is also mine--and vice versa.
 +
STANLEY:  You see, under the Napoleonic code--a man has to take an interest in his wife's affairs--especially  now that she's going to have a baby.   
 +
 +
Napoleon
 +
Stanley
 +
Stella
 +
 +
liquor
 +
Stella
 +
</source>
 
<br />
 
<br />
 
=Moodle Submission=
 
=Moodle Submission=
 
<br />
 
<br />
* 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.
+
* 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.  Moodle will run your program on three different sections of the play.  Note that some of the sections may not contain Napoleon or any alcohol information.
 
<br />
 
<br />
 
</showafterdate>
 
</showafterdate>
Line 305: Line 310:
 
=Solution Programs=
 
=Solution Programs=
 
<br />
 
<br />
 +
==Robust Loops==
 +
<br />
 +
::<source lang="python">
 +
def getPositiveNumber():
 +
    x = int( input( "Please enter a number greater than 0: " ) )
 +
    while x <= 0:
 +
        print( "Invalid number!" )
 +
        x = int( input( "Please enter a new number: " ) )
 +
       
 +
    return x
 +
 +
def likesChoco():
 +
    ans = input( "Do you like chocolate (Yes/No)? " )
 +
 +
    while not ans.upper() in [ "YES", "NO", "Y", "N" ]:
 +
        print( "Invalid input!" )
 +
        ans = input( "Do you like chocolate (Yes/No)? " )
 +
       
 +
    #
 +
    # put your code here
 +
    #
 +
    return ans.upper() in ["YES", "Y"]
 +
           
 +
       
 +
def main():
 +
    # Part 1, Exercise 1
 +
    x = getPositiveNumber()
 +
    print( "getPositiveNumber() returned", x )
 +
 +
    # Part1, Exercise 2
 +
    if likesChoco() == True:
 +
        print( "Me too!" )
 +
    else:
 +
        print( "Sorry to hear that!" )
 +
 +
main()
 +
 +
 +
</source>
 +
 
==Text Processing==
 
==Text Processing==
 +
 
<br />
 
<br />
 +
 +
===
 
::<source lang="python">
 
::<source lang="python">
import urllib.request
+
 
 +
# lab8key.py
 +
# D. Thiebaut
 +
#
 +
# Solution program for CSC111 Lab 8.
 +
# The program prompts the user for a file name that contains
 +
# a section (or the whole contents) of the play "Streetcar" and
 +
# outputs information about who says what in the play.
  
  
def getFileFromWeb( URL ):
+
def getLinesFromFile( fileName ):
 +
    """Open the file whose name is passed as a parameter,
 +
    and returns the lines it contains.
 
     """
 
     """
     Grabs the file located at the given URL, decodes
+
     return open( fileName, "r" ).readlines()
    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 ):
 
def findNapoleon( lines ):
Line 328: Line 379:
 
         #print( "line = ", line[0:40] )
 
         #print( "line = ", line[0:40] )
 
         if line.lower().find( "napoleon" ) != -1:
 
         if line.lower().find( "napoleon" ) != -1:
             print( line )
+
             print( line.strip() )
  
 
def whoSaysNapoleon( lines ):
 
def whoSaysNapoleon( lines ):
 
     """
 
     """
     Figures out who of the 3 characters say the word
+
     Figures out who of the 3 characters says the word
 
     Napoleon
 
     Napoleon
 
     """
 
     """
Line 340: Line 391:
 
     for line in lines:
 
     for line in lines:
 
         if line.lower().find( "napoleon" )!= -1:
 
         if line.lower().find( "napoleon" )!= -1:
            character = line.split()[0]
+
             if "STANLEY:" in line:
             if character == "STANLEY:":
 
 
                 stanley = True
 
                 stanley = True
             if character == "BLANCHE:":
+
             if "BLANCHE:" in line:
 
                 blanche = True
 
                 blanche = True
             if character == "STELLA:":
+
             if "STELLA:" in line:
 
                 stella = True
 
                 stella = True
  
 
     print()
 
     print()
 
     print( "Napoleon" )
 
     print( "Napoleon" )
 +
    if blanche:
 +
        print( "Blanche" )
 
     if stanley:
 
     if stanley:
 
         print( "Stanley" )
 
         print( "Stanley" )
    if blanche:
 
        print( "blanche" )
 
 
     if stella:
 
     if stella:
         print( "stella" )
+
         print( "Stella" )
  
  
Line 364: Line 414:
 
     """
 
     """
 
     # create 3 counters
 
     # create 3 counters
     stanley = 0
+
     stanley = False
     blanche = 0
+
     blanche = False
     stella  = 0
+
     stella  = False
  
 
     # define the keywords to look for
 
     # define the keywords to look for
Line 373: Line 423:
 
     # process each line separately
 
     # process each line separately
 
     for line in lines:
 
     for line in lines:
        # get the lowercase version, just to be safe
 
        line = line.lower()
 
 
 
         # check which keyword, if any, appears in each line
 
         # check which keyword, if any, appears in each line
 
         for keyword in keywords:
 
         for keyword in keywords:
             if line.find( keyword ) != -1:              
+
             if keyword in line.lower():
                 character = line.split()[0]
+
                 #print( "found alcohol in line: ", line )              
                 if character == "STANLEY:":
+
                 if "STANLEY:" in line:  
                     stanley = stanley + 1
+
                     stanley = True
                 if character == "BLANCHE:":
+
                 if "BLANCHE:" in line:
                     blanche = blanche + 1
+
                     blanche = True
                 if character == "STELLA:":
+
                 if "STELLA" in line:
                     stella = stella + 1
+
                     stella = True
  
 
     print()
 
     print()
     print( "liquor" )
+
     print( "Liquor" )
     if stanley > stella and stanley > blanche:
+
    if blanche:
 +
        print( "Blanche" )
 +
     if stanley:
 
         print( "Stanley" )
 
         print( "Stanley" )
     elif blanche > stella and blanche > stanley:
+
     if stella:  
         print( "blanche" )
+
         print( "Stella" )
    else:
 
        print( "stella" )
 
 
      
 
      
 
def main():
 
def main():
     URL = "http://cs.smith.edu/~dthiebaut/classes/111/streetcar.txt"
+
     fileName = input( "File name? " )
 
+
     lines = getLinesFromFile( fileName )
     text = getFileFromWeb( URL )
 
  
    # transform text into lines for easier processing.
 
    lines = text.splitlines()
 
  
 
     # print all the lines containing "Napoleon"
 
     # print all the lines containing "Napoleon"
Line 414: Line 458:
 
      
 
      
 
main()
 
main()
 +
 +
  
 
</source>
 
</source>

Latest revision as of 10:35, 29 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.



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 )

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 will keep on repeating the prompting until the user enters a number greater than 0. This way the function will always return a number greater than 0 to the main program.

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!" )
        
main()


Example output


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

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

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

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



Exercise 3: if/else versus elif

QuestionMark3.jpg



  • Create a new program (lab8_3.py) with the following bit of code:


def main():

    grade = input( "Grade? " ).upper().strip()

    if grade == "A":
        print( "Excellent job!" )
    else:
        if grade == "B":
            print( "Very nice" )
        else:
            print( "Below B.  Make an effort!" )

main()


  • Run the code. Verify that it gives correct answers for all letters "A" to "F".
  • Complete the code with additional if and else statements so that your program will give a different answer for "C", "D", and "F".


  • You will have noticed that your code is indented to the right in a diagonal fashion. That's typical of this type of decision programs. Python supports the elif statement, though, that allows one to write cleaner code. elif stands for else if. The code above, with elif would look something like this:


def main():
    grade = input( "Grade? " ).upper().strip()

    if grade == "A":
        print( "Excellent job!" )
    elif grade == "B":
        print( "Very nice" )
    else:
        print( "Below B.  Make an effort!" )

main()


  • When using if/elif/else, the general rule is that you should:
  1. start with an if
  2. use one or more elif statements
  3. end with an else
  • Complete the program above with additional elif statements so that it can have a different answer for 'A', 'B', 'C', 'D' and 'F'.


Exercise 4: While and Elifs

QuestionMark4.jpg



  • Combine what you worked on today and put the section that asks for a grade and output a qualification of the grade inside a loop. Make the loop output "Invalid grade" for any letter that is not 'A', 'B', 'C', 'D', or 'F', and make the loop stop when the grade entered is 'Q' (for quit).


  • Example of how your program should work:


Grade? A
Excellent job!

Grade? B
Great job!

Grade? a
Excellent job!

Grade? z
Invalid grade

Grade? lemon
Invalid grade

Grade? q
Good bye!

>>>

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.

Video Introduction



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 lab8GetPlay.py:


# lab8GetPlay.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')

    # save the string to file
    open( "streetcarShort.txt", "w" ).write( text )


main()


  • Run this program. Verify that you have a new text file in the folder where you have saved the program.
  • Open the new file streetcarShort.txt and verify that you see 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, Stanley, or Blanche?


  • Write a new program called lab8key.py that prompts the user for the name of a file, opens it, and counts how many lines (and not words) each of the three characters, Blanche, Stanley, or Stella, says.
  • Hints 1: Look up the count() method in this page, and see if it can help you out...
  • Hints 2: You can also go through each line and count how often you see "STANLEY:", how often you see "STELLA:", and how often you see "BLANCHE:".


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! To see if a line is being said by "Blanche", for example, you can write if "BLANCHE:" in line: or if line.find( "BLANCHE:" ) != -1: .


Who is Drinking


  • Which of the three characters mention(s) the words "drink", "liquor", or "whiskey"? Here we don't want to know how many times they say the words, just the fact that they may have said one of them.
  • Hints: Loop through the alcohol keywords, and see if any one of them is in a line. If one of them is, then see if "BLANCHE:", or "STANLEY:", or "STELLA:" also appears (is in) the line. Depending on which character name appears, you can "remember" that this character said such a word. Boolean variables are perfect for that!


Analyzing The Whole Play


  • Modify the program lab8GetPlay.py and change the URL and the file name in the open(...) statement from streetcarShort.txt to streetcar.txt.
  • Run lab8GetPlay.txt and verify that you have a new file in your folder called streetcar.txt. It should contain the whole play. The last line of the play is "The end."
  • Modify your lab8key.py program, and make it answer the following questions regarding the three main characters, Stanley, Stella, and Blanche:
  • Several characters mention the word "Napoleon" in this play. Print the lines where this word appears.
  • What are the names, and only the names, of the characters who pronounce the word "Napoleon" in their lines. For example, if Stanley says 5 lines containing the word Napoleonic, and Stella only one line, your program should output one blank line followed by


       Napoleon
       Stanley
       Stella

You should list the names in alphabetical order, i.e. Blanche should be first, if she's in the list, then Stanley, if he's in the list, then Stella, if she's in the list.
  • Which of the three characters mentions the words "drink", "liquor" or "whiskey"? List the answers in alphabetical order of their name under the heading "Liquor". Example:
      Liquor
      Stella



Typical Program Output


Here is what your output could look like. This may not be the solution to the lab!


File name? streetcar.txt

STANLEY:  Have you ever heard of the Napoleonic code?
STELLA:  No, Stanley, I haven't heard of the Napoleonic code, if I have, I don't see what it--
STANLEY:  In the state of Louisiana we have the Napoleonic code according to which what belongs to the  wife belongs to the husband and vice versa. For instance if I had a piece of property, or you had a  piece of property--
STANLEY:  All right, I'll wait till she gets through soaking in a hot tub and then I'll inquire if she is  acquainted with the Napoleonic code. It looks to me like you have been swindled, baby, and  when you're swindled under the Napoleonic code I'm swindled too. And I don't like to be  swindled.
STANLEY:  There is such a thing in this state of Louisiana as the Napoleonic code, according to which  whatever belongs to my wife is also mine--and vice versa.
STANLEY:  You see, under the Napoleonic code--a man has to take an interest in his wife's affairs--especially  now that she's going to have a baby.    

Napoleon
Stanley
Stella

liquor
Stella


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. Moodle will run your program on three different sections of the play. Note that some of the sections may not contain Napoleon or any alcohol information.


</showafterdate>

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

Solution Programs


Robust Loops


def getPositiveNumber():
    x = int( input( "Please enter a number greater than 0: " ) )
    while x <= 0:
        print( "Invalid number!" )
        x = int( input( "Please enter a new number: " ) )
        
    return x 

def likesChoco():
    ans = input( "Do you like chocolate (Yes/No)? " )

    while not ans.upper() in [ "YES", "NO", "Y", "N" ]:
        print( "Invalid input!" )
        ans = input( "Do you like chocolate (Yes/No)? " )
        
    #
    # put your code here
    #
    return ans.upper() in ["YES", "Y"]
            
        
def main():
    # Part 1, Exercise 1
    x = getPositiveNumber()
    print( "getPositiveNumber() returned", x )

    # Part1, Exercise 2
    if likesChoco() == True:
        print( "Me too!" )
    else:
        print( "Sorry to hear that!" )

main()

Text Processing


=

# lab8key.py
# D. Thiebaut
# 
# Solution program for CSC111 Lab 8.
# The program prompts the user for a file name that contains
# a section (or the whole contents) of the play "Streetcar" and
# outputs information about who says what in the play.


def getLinesFromFile( fileName ):
    """Open the file whose name is passed as a parameter,
    and returns the lines it contains.
    """
    return open( fileName, "r" ).readlines()

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.strip() )

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

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


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

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

    # process each line separately
    for line in lines:
        # check which keyword, if any, appears in each line
        for keyword in keywords:
            if keyword in line.lower():
                #print( "found alcohol in line: ", line )                
                if "STANLEY:" in line: 
                    stanley = True
                if "BLANCHE:" in line:
                    blanche = True
                if "STELLA" in line:
                    stella = True

    print()
    print( "Liquor" )
    if blanche:
        print( "Blanche" )
    if stanley:
        print( "Stanley" )
    if stella: 
        print( "Stella" )
    
def main():
    fileName = input( "File name? " )
    lines = getLinesFromFile( fileName )


    # 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>