CSC148H lab #2 -- week 3


This document contains the instructions for the week 3 CSC148H/A48H lab. To earn your lab mark, you must actively participate in the lab. We mark you in order to ensure a serious attempt at learning, not to make careful critical judgments on your work.

The lab this week is about programming with exceptions.

Pair Programming

Pick a navigator and driver. 


Creating, Raising, and Catching Exceptions

Download the file stack.py. Modify the file as follows:

  1. Create a new exception class called StackEmptyError.
  2. Create a __str__ method for StackEmptyError that returns the message "Tried popping an empty stack".
  3. Change the pop() method in the Stack class so that it raises StackEmptyError if pop() is called when the stack is empty.
In a new file, driver.py, write code that creates a new Stack and tries popping an element off of it. You should catch StackEmptyError, and print the exception object to the screen. When you print the exception object to the screen, you should see the message that you wrote in the __str__ method.

Show your TA your work when you are done the above.


Password Cracking

Switch navigator/driver roles. Download the file code.py. This module contains the following function:
The designer of the "secure" system wasn't particularly smart. Whenever a PasswordError is raised by the login function, the designer thought it would be helpful to provide information about the position in the attempted password at which the first incorrect character appears. In particular, PasswordError has the following method:
In case the attempted password is a proper prefix of the correct password, then the first incorrect position is one position after the end of the string. For example, if the attempted password is "CAR" and the correct password is "CARWASH", then first_wrong_pos() will return 3.

Your goal is to write code that automatically cracks the password and successfully logs into the secure system. That is, you have to figure out the correct string to pass to the login() method so that it doesn't raise a PasswordError exception. You may assume that the password only contains capital letters A to Z (no numbers, spaces, punctuation marks, etc).

Your solution will be written in driver.py. (You can erase the solution from the preceding lab exercise.) Your code should keep trying to login to the system until it is successful. Each login attempt will require that you guess the correct password. However, your guesses don't have to be entirely random. With each repeated login attempt, you gain some new information from the PasswordError exception, allowing you to modify your guess in an intelligent way.

With your partner, think carefully about how you might approach the problem. In particular, consider the following questions:
You may find the following helper function (provided in code.py) useful when modifying your guess:
update_guess() only modifies existing characters in your guess -- it does not add new characters. If you want to increase the length of your guess, you can do so with string concatenation (i.e., using the '+' operator). (For example, if s1 and s2 are strings, then s = s1 + s2 is the string that consists of s1 followed by s2.)

By the way, if you think that you can figure out the password just by looking into code.py, go ahead and look at its contents. The correct password is there, but it's in a special encoded form. Thus, in order to figure out the password, you have to actually implement the cracking method described above.

Once you have been able to successfully login to the system, show your TA your code and the correct password. (Please don't say the password out loud or share it with your neighbours.)


Enrolling a Student In A Course

Switch driver/navigator roles. Download the file enroll.py. It contains definitions for the following exceptions: EnrollmentError, PrerequisiteError, CourseClosedError, and CourseCancelledError. EnrollmentError is a superclass of all the other exceptions. enroll.py also contains the function enroll(student, course), which enrolls the student in the course.

Clean out the solutions from the preceding exercise in driver.py, and write code that asks the user for a student name and a course name. You can use  raw_input("Student name: ") and raw_input("Course name: ") to do this. Have your code enroll the student in the course by calling the enroll function,  enclosing the call in a try clause. If any of the previously mentioned exceptions are raised in the enroll function, print the exception object and re-ask the user for a student name and course name. Keep trying to enroll the student in the course until either enroll raises no exceptions or the user enters an empty string ('') for one of the inputs. Exceptions other than those mentioned in the previous paragraph should not be caught.

Write your code to minimize the number of except statements that you use. In particular, keep in mind that EnrollmentError is a superclass of the other exceptions listed in the first paragraph.

Try running your program with some random inputs. Also see what happens when you run with the student name "bob". Try another student name, with the course "csc108" and "csc148".

Show your TA your code.

Now modify your code so that if a CourseClosedError is raised, your program asks the user for a new course name but not a new student name. Your code should then try enrolling the same student in the new course. If any of the other exceptions are raised, your code should behave as before (i.e., ask for both a new student name and course name.)

Show your TA your code.