ELEX 4653 Exam 3 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 your answer to question N may be correct.

  • 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 lesser that takes a dictionary argument named x and an integer argument m. Your function should return a list consisting of all the values in x that are less than m. You may ignore the keys. For example, if x={ 'a':34, 'b': 16, 'c':25, 'd':8} and m is 20 then lesser(x,m) should return a list containing the values 16 and 8 ([16,8] or [8,16]). The order of the values in the output does not matter.

In [1]:
def lesser(x,m):
    return [x[i] for i in x if x[i] < m]

x={ 'a':34, 'b': 16, 'c':25, 'd':8}
lesser(x,20)
Out[1]:
[16, 8]

Question 2

Write a function named mkdict that takes one dictionary argument named d. The keys of the dictionary d are strings and the values are lists. Your function should create a new dictionary with each key replaced by the first value in the corresponding key which is removed from the values in the list. For example if d = { 1: ['add', 1, 3], 1:['sum',8, -1, 6], 3: ['jmp',3]} then addlists(d) should return the dictionary {'add': [1,3], 'sum': [8, -1, 6], 'jmp': [3]}.

In [2]:
def mkdict(d):
    return {d[k][0]:d[k][1:] for k in d}

d = { 1: ['add', 1, 3], 2:['sum',8, -1, 6], 3: ['jmp',3]}
mkdict(d)
Out[2]:
{'add': [1, 3], 'sum': [8, -1, 6], 'jmp': [3]}

Question 3

Write a recursive function named rcall that takes an argument named l which is a list of integers and an argument named f which is a function. Your function should call the function f with each of the values in the list that is less than zero. For example if l=[0, 1, -3, 1, -7] then rcall(l,print) would print -3 and -7. Your function need not return a value.

In [3]:
def rcall(l,f):
    if not len(l):
        return
    else:
        if l[0]<0:
            f(l[0])
        rcall(l[1:],f)
        
l=[0, 1, -3, 1, -7]
rcall(l,print)
-3
-7

Question 4

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

  1. the letter T
  2. one of the letters F or D
  3. four digits
  4. the optional letter A
  5. one of HN, TW or UK
  6. the character /
  7. the letter N
  8. the digit 1 or 2

For example, re.search(pat,'TF1234AHN/N1') would return a match object but re.search(pat,'F1234AHN/N1') would not.

In [4]:
pat=r'^T[FD]\d{4}A?(HN|TW|UK)/N[12]$'

import re
print(re.search(pat,'TF1234AHN/N1'))
print(re.search(pat,'F1234AHN/N1'))                
<_sre.SRE_Match object; span=(0, 12), match='TF1234AHN/N1'>
None
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 checksorted(l):
        assert all((l[i] <= l[i+1] for i in range(len(l)-1))), \
            "result is not sorted: {}".format(l)

    def checkfunctions(f,l):
        u=[s for s in f.__code__.co_names if s not in l]
        assert not u, "You used the function(s): {}".format(u)
        
    def checkrecursive(f):
        s=f.__name__
        assert s in f.__code__.co_names, "{} is not recursive".format(s)

    def checkhash(l,n):
        # print(hashlib.md5(''.join(l).encode('utf8')).hexdigest())
        assert hashlib.md5(''.join(l).encode('utf8')).hexdigest() == n, \
                'wrong values in list: {} ... {}'.format(l[0],l[-1])
    
    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():
        n=randint(4,6)
        kl=randwords(n)
        vl=[randint(0,99) for i in range(n)]
        m=(max(vl)-min(vl))//2+min(vl)
        x={k:v for k,v in zip(kl,vl)}
        x0=copy.deepcopy(x)
        y=lesser(x,m)
        assert set(i for i in vl if i<m) == set(y), \
            "lesser({},{}) returns {}".format(x0,m,y)

    def q2():       
        n=randint(4,6)
        kl=range(n)
        vl=[choices(range(5),k=randint(1,4)) for i in range(n)]
        vw=randwords(n)
        vwl=[[w]+l for w,l in zip(vw,vl)]
        d={k:v for k,v in zip(kl,vwl)}
        d0=copy.deepcopy(d)
        y=mkdict(d)
        assert len(y) == len(d0) and set(y.keys()) == set(vw) \
            and sorted(vl) == sorted(y.values()), "mkdict({}) returns {}".format(d0,y)

    def q3():
        n=randint(7,10)
        l=[randint(-9,9) for i in range(n)]
        l0=copy.copy(l)
        ll=[]
        f=lambda x:ll.append(x)
        rcall(l,f)
        assert ll == [i for i in l0 if i<0], \
            "rcall({},f) calls f with: {}".format(l0,ll)
          
  
    def q4():
        ok=['TF1234AHN/N1', 'TD0000AHN/N1', 'TF1234HN/N1', 'TF1234AHN/N1', 
            'TF1234ATW/N1', 'TF1234AUK/N1', 'TF1234AUK/N2' ]
        nok=[' TF1234AHN/N1', 'T1234AHN/N1', 'TF123AHN/N1', 'TF1234XHN/N1',
             'TF1234AHA/N1', 'TF1234AHN.N1', 'TF1234AHN/N3', ]
        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("Solution to question {} may be correct.".format(i))
            except Exception as e:
                print("Failed check for question {}: {}".format(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.