ICS 31 -- Winter 2013 -- Quiz 5

  1. Below are four function headers (with parameter types and a docstring comment describing the function's behavior):
    def function1(L: 'list of numbers') -> None:
    ''' Print, one per line, double the value of each item in the parameter '''

    def function2(L: 'list of numbers') -> None:
    ''' Print the parameter in bracketed Python list notation '''

    def function3(L: 'list of numbers') -> 'list of numbers':
    ''' Return a list containing each item of the parameter, doubled; leave
    parameter unchanged '''

    def function4(L: 'list of numbers') -> 'list of numbers':
    ''' Double each item in parameter, changing corresponding argument;
    also return changed list '''
    Each of the following groups of statements is consistent with exactly one of the above headers. For each of the statement groups below, indicate which of the above functions (function1 through function4) matches it.
    1.     print(L)
      return
      Answer Feedback:
      function2
    2.     for n in range(len(L)):
      L[n] = L[n] * 2
      return L
      Answer Feedback:
      function4. Here we're mutating the list---changing it in place, by assigning a new value to each individual indexed element of the list.
    3.     doubled = [ ]
      for i in L:
      doubled = doubled + [i * 2]
      return doubled
      Answer Feedback:
      function3. This leaves the parameter L unchanged; the new list (doubled) is created with the specified result.
    4.     for i in L:
      print(2 * i)
      return
      Answer Feedback:
      function1
  2. Suppose we have a collection of images (as we might on Flickr or with Facebook photos). We could represent each image as a namedtuple, with numbers for the height and width and an additional field for the content of the image itself (whose form we don't need to worry about now).

    Image = namedtuple('Image', 'height width content')
    image1 = Image(250, 150, "w")
    image2 = Image(150, 250, "x")
    image3 = Image(100, 100, "y")
    image4 = Image(1500, 1000, "z")
    image_list = [image1, image2, image3, image4]

    1. A portrait-style image is taller than it is wide. (A landscape-style image is wider than it is tall.) Complete the following function definition according to the header, docstring, and assertions shown.


      def is_portrait(i: Image) -> bool:
      ''' Return True if image is portrait-style (taller than wide) and False otherwise
      '''




      assert(is_portrait(image1))
      assert(not is_portrait(image2))
      assert(not is_portrait(image3))
      Answer Feedback:
          return i.height > i.width
    2. Complete the definition of the function below according to the header
      and docstring shown, with one identifier name, constant, or operator in each blank space.
      Where applicable, use functions from elsewhere in this quiz rather than duplicating code.


      def keep_portraits(L: 'list of Image') -> 'list of Image':
      ''' Extract portrait-style images from parameter, returning them in a list
      '''
      result = [ ]
      for i in _______________:

      if _______________ (_______________):

      _______________.append(_______________)

      return _______________
      Answer Feedback:
          result = [ ]
      for i in L:
      if is_portrait(i):
      result.append(i)
      return result
    3. Write two assert statements to test keep_portraits.
      One should use the definitions above; the other should test it with an empty list.

      Answer Feedback:
      assert(keep_portraits(image_list) == [image1, image4])
      assert(keep_portraits([]) == [] )

      Creating a thorough set of test cases is another programmer's skill. In particular, you should always test for the case where the main data is empty or zero; generally you want your function to return gracefully in those cases, perhaps the values empty or zero.
  3. Suppose we have a list of Student objects as defined in class:

    Student = namedtuple('Student', 'ID name level major studylist')
    # All are strings except studylist, which is a list of Courses.
    # An example showing the form of the data:
    s1 = Student('11223344', 'Anteater, Peter', 'FR', 'PSB', [ics31, wr39a, bio97, mgt1])

    Each Student object contains a list of Course objects defined as follows:

    Course = namedtuple('Course', 'dept num title instr units')
    # All are strings except number of units
    # An example showing the form of the data:
    ics31 = Course('ICS', '31', 'Intro to Programming', 'Kay', 4)

    1. Complete the definition of the function below according to the header and docstring shown.


      # Note:  The annotation [Student] below means the same thing as 'list of Student'
      def class_level_count(SB: [Student], class_level: str) -> int:
      ''' Return the number of students in the list SB whose class level matches the specified value.
      '''





      Answer Feedback:
      def class_level_count(SB: [Student], class_level: str) -> int:
      ''' Return the number of students in the list SB whose class level matches the specified value.
      '''
      result = 0
      for s in SB:
      if s.level == class_level:
      result += 1
      return result

    2. Complete the definition of the function below according to the header and docstring shown. You may define a second function if it helps you organize your solution.


      def enrollments_for_instructor(SB: [Student], instructor_name: str) -> int:
      ''' Return the number of students enrolled in courses taught by named instructor
      '''












      Answer Feedback:
      def enrollments_for_instructor(SB: [Student], instructor_name: str) -> int:
      ''' Return the number of students enrolled in courses taught by named instructor
      '''
      result = 0
      for s in SB:
      result = result + enrollments_on_studylist(s.studylist, instructor_name)
      return result

      def enrollments_on_studylist(courses: [Course], instructor_name: str) -> int:
      ''' Return the number of enrollments for this students in courses taught by named instructor
      '''
      result = 0 # Of course this is a separate (local) variable from the one in the other function.
      for c in courses:
      if c.instr == instructor_name:
      result += 1
      return result