ELEX 4653 Exam 2 Solutions

Instructions:

  • Answer all four (4) questions.

  • You have 110 minutes to complete the exam.

  • This is an open-book exam. All written material is allowed.

  • No electronic devices other than a flash drive and the lab PC may be used during the exam.

  • No communication with others (electronic, verbal, written or otherwise) is allowed during the exam. Violations will result in a mark of zero and disciplinary action.

  • Add the Python code described below in the cells provided.

  • Test your code using the menu item Cell ► Run All

  • The message Solution to question N may be correct. at the bottom of the notebook means that no errors were found in your answer to question N.

  • When the exam time is over, save the notebook (the .ipynb file) and upload it to the appropriate dropbox on the course web site.

Question 1

Write a function named longs(x,n) that takes a list argument x and an integer argument n. Your function should return a list of all the values of x whose length is n or more as determined by the len() function. For example, if x=[ "abc", "hi", "defg", "x"] then longs(x,3) should return ['abc', 'defg'].

In [1]:
def longs(x,n):
    return [s for s in x if len(s) >= n]
x=[ "abc", "hi", "defg", "x"]
longs(x,3)
Out[1]:
['abc', 'defg']

Question 2

Write a function named lookup(d,l) that takes one dict argument named d and one list argument named l. Your function should return a list values from d using the keys given in l. For example if d = {'a': (1,1), 'b': 9, 'c':'see'} and l=['b','a'] then lookup(d,l) should return [9, (1, 1)].

In [2]:
d =  {'a': (1,1), 'b': 9, 'c':'see'}
l=['b','a']
            
def lookup(d,l):
    return [d[k] for k in l]
lookup(d,l)
Out[2]:
[9, (1, 1)]

Question 3

Write a recursive function named appendlarger(a,b,n) that takes two list arguments , a and b and an integer argument n. Your function should append each value in b that is greater than n to the end of a. Your function does not have to return a value. For example if a=[1, 2, 3] and b=[4, 5, 6] then appendlarger(a,b,4) would set a to [1, 2, 3, 5, 6].

In [3]:
def appendlarger(a,b,n):
    if len(b):
        if b[0] > n:
            a.append(b[0])
        appendlarger(a,b[1:],n)
    return

a=[1, 2, 3]
b=[4, 5, 6]
appendlarger(a,b,4)
a
Out[3]:
[1, 2, 3, 5, 6]

Question 4

Set the variable pat to a regular expression that matches a part number string created according to the following sequence:

  1. the pattern is found at the start of the string
  2. the letters ALA
  3. one of the characters - or .
  4. a 5-digit number between 00000 and 19999
  5. the pattern is found at the end of the string

Hints: use \ to escape the special meaning of a character in a pattern. Use \\ to insert a \ in conventional string.

For example, re.search(pat,'ALA.00000') would return a match object but re.search(pat,'ALA-00000x') would not.

In [4]:
pat = r'^ALA[-\.][01][0-9]{4}$'

import re
re.search(pat,'ALA.00000'),re.search(pat,'ALA-00000x')
Out[4]:
(<re.Match object; span=(0, 9), match='ALA.00000'>, None)

Marking Code

In [5]:
# exam validation code; do not modify
def examcheck():
    import copy, hashlib, re
    from random import randint, choices, shuffle
    
    def randwords(n):
        l = set()
        while len(l)<n:
            l |= set((''.join([chr(randint(97,122)) for i in range(randint(2,5))]),))
        return list(l)
        
    def checkrecursive(f):
        s=f.__name__
        assert s in f.__code__.co_names, "{} is not recursive".format(s)
    
    def checkre(pat,ok,nok):
        for s in ok:
            assert re.search(pat,s), \
                "pattern '{}' didn't match string '{}'".format(pat,s)
        for s in nok:
            assert not re.search(pat,s), \
                "pattern '{}' matched string '{}'".format(pat,s)

    def q1():
        x=randwords(10)
        x0=copy.deepcopy(x)
        n=randint(2,3)
        y=longs(x,n)
        z=[1 if x0[i] == s else 0 
           for i,s in enumerate(x0) if len(s)>=n]
        assert len(z) == len(y) and all(z), \
            f'longs{x,n} returns {y}'

    def q2():
        n=randint(3,5)
        k=randwords(n)
        v=choices(range(100),k=n)
        d=dict(zip(k,v))
        l=choices(k,k=n//2)
        d0=copy.deepcopy(d)
        l0=copy.deepcopy(l)
        y=lookup(d,l)
        assert ( len(y) == len(l0) and 
        all([d0.__getitem__(s) == y[i] for i,s in enumerate(l0)]) ),\
            f'lookup{d0,l0} returns {y}'

    def q3():
        checkrecursive(appendlarger)
        n=randint(5,15)
        a=choices(range(20),k=randint(2,4))
        b=choices(range(20),k=randint(2,4))
        a0=copy.deepcopy(a)
        b0=copy.deepcopy(b)
        appendlarger(a,b,n)
        assert a == a0+list(filter(lambda x:x>n,b0)),\
            f'appendlarger{a0,b0,n} sets a to {a}'
       
    def q4():
        ok  = [ r'ALA-00000',r'ALA.00000',r'ALA-19999', r'ALA-00000' ]
        nok = [ r'ALB-00000',r'ALA00000',r'ALA-29999', r'ALA-0000', r'ALA-00000x' ]
        checkre(pat,ok,nok)  


    for i,s in ((i,'q%d'%i) for i in range(1,20)):
        if s in locals():
            try:
                locals()[s]()
                print(f"Solution to question {i} may be correct.")
            except Exception as e:
                print(f"Failed check for question {i}: {e}")    

examcheck()
Solution to question 1 may be correct.
Solution to question 2 may be correct.
Solution to question 3 may be correct.
Solution to question 4 may be correct.