CSSE 120 — Introduction to Software Development

Homework 11

Reminder: for each class session and associated homework:

  • You do the Reading Quiz on Angel.
  • You do all other work in Eclipse in the project that you checked out for that session or will check out per the homework instruction.
  • Unless otherwise specified, use the form for functions and modules that we have modelled in all the modules that WE have supplied to you.
  • You turn in your Eclipse work by committing that project:
    • Right-click on the project name in the Pydev Package Explorer view.
    • Select Team → Commit
    • In the message box that appears, put a message to yourself if you wish (eventually, these messages will be for your teammates) and press OK.

Questions? Email csse120-staff@rose-hulman.edu.

Best place and time to do the homework: CSSE lab (Moench Hall, room F-217), 7 p.m. to 11 p.m., Sunday — Thursday.

Today's project: 11-WhileLoops

Main learning objectives for this homework:

  • Using WHILE loops (indefinite loops)
  • Procedural decomposition: Defining and using functions with parameters
  • Reading from a text file, including processing lines with multiple items of data
  • Constructing and using objects (in ZelleGraphics)
  • Doing input and output in a Graphical User Interface, using the ZelleGraphics Text and Entry classes

Additional learning objectives for this homework:

  • Lists and strings
  • The Accumulator Loop pattern
  • Returning multiple values (using a tuple) from a function

Do the following exercises. For problems 3 and following, use today's project: 11-WhileLoops

  1. Complete the assigned reading for the next session: Zelle, Chapter 9 — Simulation and Design, Sections 9.1 and 9.2 (7 pages).
  2. (26 points) Complete the ANGEL quiz over this reading, at the course ANGEL page, under Lessons → Homework → Homework 11 → Simulation and Design I
  3. (0 Points, but worth doing) Complete the exercise that you started in class in the 05-guessMyNumber.py module, per the TODO's in the module.
  4. (20 points) If you have not already done so, complete the 06-star.py module as described in the previous homework (i.e., hw10).
    • That module is part of the 10-DecisionStructures project from the previous homework.
  5. (60 points)

    This problem is not due until MONDAY at class time. If you have questions about it, bring those questions to class Thursday.

    Read the entire description of this problem before doing any of it.

    In this problem, you are given a file that contains numbers that are speeds generated by a radar gun that measures the speed of each vehicle on the road coming up the hill from the SRC. Your task is to read the numbers in the file and print the mean (average) of the numbers.

    Unfortunately, the file is a bit malformed. Due to an intermittent open circuit, occasionally multiple numbers are written on a single line, with one or more spaces between them, like this:

         23.2   15.6 19.8
    
    This makes this project more challenging.

    Additionally, your client has asked you to provide a graphical user interface (GUI) by which the user can enter the name of the file with the speeds data, instead of using Console input. This makes this project even more challenging.

    Finally, your client has asked you to do input validation on the filename that the user enters, that is, to be sure that the file exists and is in the current folder. This makes this project still more challenging!

    You decide, wisely, to apply procedural decomposition to this problem. That is, you decide to break this problem into sub-problems, with each sub-problem being a function that you design and implement. To that end, you decide to implement 4 functions, as follows.

    Function header (name and its parameters) Function specification (what the function should do)
    main()
    • 1. Constructs a GraphWin for the Graphical User Interface (GUI). Also constructs Entry and Text boxes to do the user input/output in the GUI. The Text entry will display messages to the user, while the Entry box will be the object into which the user types her input (here, the name of the file with the speeds data).
    • 2. Uses getInputFile() to get a valid filename from the user.
    • 3. Uses fileMean() to calculate the mean of the numbers in that file.
    • 4. Displays the mean on the GUI, using the Text object.
    • 5. When the user clicks in the GUI (after the mean is displayed), closes the window, closes the open file, and exits the program.
    getInputFile(window, entryBoxForUserInput, textBoxForMessagesToUser) Uses the given:
    • window (which is a GraphWin),
    • entryBoxForUserInput (which is an Entry), and
    • textBoxForMessagesToUser (which is a Text)
    to do the following:

    • 1. Displays the given textBoxForMessagesToUser in the given window.
      • The caller of this function should have put an appropriate message into that Text object, e.g. "Please enter a filename".
    • 2. Displays the given entryBoxForUserInput in the given window.
    • 3. Repeatedly does the following, stopping when the user enters a valid filename in Step 3b.
      • 3a. Waits for the user to click the mouse (anywhere in the window) after she has entered a filename in the displayed entryBoxForUserInput. (If the user messes up and enters an invalid filename or even no filename at all, the next substep will address that problem.)
      • 3b. Gets the filename that the user presumably entered in the entryBoxForUserInput. Checks that that filename is a file in the current folder.
        • If so: opens the file and returns the object returned by open(...) [hence exits the loop]
        • If not: Changes the message in the textBoxForMessagesToUser to a message that indicates to the user that her filename is invalid and that she should re-enter another one.

    fileMean(file)

    Reads numbers from the given text file, which must already be open for reading, and returns the mean (average) of all the numbers found.

    To do so, it loops through the lines in the given text file and calls lineSumAndCount() on each line of the text file, thus getting the sum and count from each line. It totals up those sums and counts, and uses those totals to compute and return the mean (average) of all the numbers in the given text file.

    lineSumAndCount(line)

    Returns the sum and count of the numbers in the given line of text. For example, if the line is:

         23.2   15.6 19.8
    
    then this function would return:
         58.6, 3
    

    When you write more complicated programs, you should be able to test them as you go. Typically, software developers write a set of tests for each small part of the program (thus they are called unit tests).

    We have provided, in the file     7-speedReadingUnitTests.py     (note the 7), unit tests for the first 2 functions you will write in     speedReading.py .

    • IMPORTANT: I made an error in naming the files. If you have not already done so, please:
      • In Eclipse, in the     11-WhileLoops     project, right-click on the     6-speedReading.py     module. In the dialog that pops up, select     Rename     and change the name from     6-speedReading.py     to     speedReading.py. That is, remove the first two characters of that module's name.

    So, implement your project in the following steps:
    • Step 1: Write     lineSumAndCount()     in     speedReading.py     first.
    • Step 2: Then run     7-speedReadingUnitTests.py     (note the 7) to test whether your function works correctly. If so, great! If not, correct errors in your code as needed.
    • Step 3: Then write and test     fileMean()     in the same way.
    • Step 4: Finish up by implementing the     main()     and     getInputFile()     functions, as described above. Test your code using the sample file     speeds.txt     already in your project, by running     speedReading.py.
      • The average of the speeds in that file should be around 20.16.

    Finally, two technical notes:

    • To display text (words) on a GraphWin, construct a Text object and apply its draw method, like this:
      
          textObject = Text(Point(300, 30)), "this is what shows up")
          textObject.draw(window)
      
      
      where window is the GraphWin onto which to draw the Text object. You can use the Text's setText(...) method to reset the Text that the object shows.
    • To get input from the user in a GraphWin, construct an Entry object and apply its draw method, like this:
      
          entryObject = Entry(Point(300, 30)), 15)
          entryObject.draw(window)
      
      
      where window is the GraphWin onto which to draw the Entry object. Then, you can use the Entry's getText() method to get the string that the user typed into the Entry box that was displayed. (The Entry box above displays space for 15 characters.)
    See the zellegraphics documentation if you need more information about these classes.

    One final comment: Yes, there are many other ways that you could solve this speeds problem. We're asking you to follow our specification so you can get practice working with the sort of situations that come up in real world, group projects, where you often must implement someone else's design. Additionally, this approach lets you:

    • see procedural decomposition in action
    • see unit testing in action
    • use a GUI for input and output
    • confront and clear up some misunderstandings that you may have about functions
  6. BONUS: (10 Points)

    This OPTIONAL problem is not due until MONDAY at class time. If you have questions about it, bring those questions to class Thursday.

    Augment your program so that it also displays, at the bottom of your window, a bar graph of the mean speeds for each line of the text file, along with a horizontal line showing the mean speed for the entire file.

    You are allowed to pass more parameters to your functions to get it to work. In particular, you will almost certainly want to pass the GraphWin into fileMean, and possibly from there to lineSumAndCount. (You'll need this so that you can draw each vertical line of the bar chart onto the GraphWin as you are processing each line of the file.)

  7. Web link: Debugging, by Dave Agans. A book on debugging that can be helpful to neophytes as well as pros. See the sample chapters at the bottom of the web page!