Practice Diagnostic 2 Solutions

For most problems there are several correct answers. Important: We stronly encourage you to attempt all of the problems before looking at the solutions. It is much easier to recognize a correct answer than to come up with one.

1. Debugging & Tracing

  • In the second for loop, range(result) will cause an index out of bounds error because result is longer than value_list.
  • The initial value of pos should not be 0 as this will cause the program to fail if value is larger than all values in the list. A good default value in this case would be len(result)-1.
  • The if statement in the third for loop should check if value < value_list[i]:/
  • i should be set to len(result)-1 rather than len(result) or there will be an index out of bounds error.
  • Off by one error in the while loop condition. It should be while i > pos.

2. Strings

Solution 1

      
def parse1(s):
  """
  >>> parse1('x @abc @xyz x')
  ['abc', 'xyz']
  >>> parse1('xx@xx$$')
  ['xx']
  >>> parse1('@a @ @c')
  ['a', '', 'c']
  """
  result = []
  in_tag = False      # Keep track of whether we are in a tag as we loop through string
  tag = ''
  for i in range(len(s)):
      if in_tag:      # If we're in a tag, we either continue to extend it or end it
          if s[i].isalnum():
              tag += s[i]
          else:       # We've reached the end of the tag
              in_tag = False
              result.append(tag)
      if not in_tag and s[i] == '@':  # Check to see if we entered a new tag
          in_tag = True
          tag = ''
  if in_tag:          # Make sure to include tag if it was at end of string
      result.append(tag)

  return result

    

Solution 2

    
def parse1(s):
  """
  >>> parse1('x @abc @xyz x')
  ['abc', 'xyz']
  >>> parse1('xx@xx$$')
  ['xx']
  >>> parse1('@a @ @c')
  ['a', '', 'c']
  """
  result = []
  in_tag = False      # Keep track of whether we are in a tag as we loop through string
  tag = ''
  for ch in s:
      if in_tag:      # If we're in a tag, we either continue to extend it or end it
          if ch.isalnum():
              tag += ch
          else:       # We've reached the end of the tag
              in_tag = False
              result.append(tag)
      if not in_tag and ch == '@':  # Check to see if we entered a new tag
          in_tag = True
          tag = ''
  if in_tag:          # Make sure to include tag if it was at end of string
      result.append(tag)
  return result

3. Lists and Files

        
INPUTFILE = 'data.txt'


# Compute and return the sum of all the elements of the list.
# Could use the sum function on a list, but this we provide an
# explicit function to sum a list for completeness.
def sum_list(lst):
    result = 0
    for num in lst:
        result += num
    return result


# Compute and return the product of all the elements of the list.
def prod_list(lst):
    result = 1
    for num in lst:
        result *= num
    return result


def main():
    num_list = []   # Keep track of list of numbers between operators
    with open(INPUTFILE) as file:
        for line in file:
            line = line.strip()             # Remove newline
            if line.isdigit():              # If this is a number, then add it to num_list
                num_list.append(int(line))
            elif line == '+':               # If we see '+', then sum the num_list
                print(sum_list(num_list))
                num_list = []
            elif line == '*':               # If we see '*', then get product of num_list
                print(prod_list(num_list))
                num_list = []
        
      

4. 2D Lists

  
def diagonal_line(my_grid):
  row1 = 0    # Used to store row of 1 in initial grid
  col1 = 0    # Used to store column of 1 in initial grid

  # Find the 1 in the initial grid.  Keep track of position in col1, row1
  for row in range(len(my_grid)):
      for col in range(len(my_grid[0])):
          if my_grid[row][col] == 1:
              row1 = row
              col1 = col

  # Generate the diagonal line of 1's by iterating through the rows of the
  # grid and adding 1's on the diagonal line (making sure not to go off the
  # ends of the grid.
  for row in range(len(my_grid)):
      col = col1 - row1 + row     # Determine column for new 1 based on row and col1, row1
      if col >= 0 and col < len(my_grid[0]):  # Make sure we don't go off the grid
          my_grid[row][col] = 1


5. Dictionary Prefix

  
def count_prefix(words):
  counts = {}

  for word in words:      # Loop through keys in words list
      if len(word) >= 2:  # Only count words with at least 2 characters
         prefix = word[0:2].lower()   # Convert prefix to lowercase to be case insensitive
         if prefix not in counts:
             counts[prefix] = 1       # First time we saw this prefix
         else:
             counts[prefix] += 1      # Subsequent times we saw this prefix

  # Print all the prefixes and their counts
  for key in counts:
    print(key, counts[key])