ELEX 4653 Exam 1 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.

    Version 2 (fixed marking of Question 3)

Question 1

Write a function named evens that takes a list argument named x. Your function should return a (new) list consisting of all the values of x which are even. For example, if x=[0, 3, 4, 2] your function should return [0, 4, 2].

In [1]:
def evens(x):
    return [i for i in x if not i%2]

x=[0, 3, 4, 2]
evens(x)
Out[1]:
[0, 4, 2]

Question 2

Write a function named mergedicts that takes one list argument named l. The list l contains dictionaries. Your function should return one dictionary containing all key:value pairs in all dictionaries in l. For example if l = [{ 'a': 3, 'b': 9}, {1:2, "x":'y'}, {'sum':32}] then mergedicts(l) should return { 'a': 3, 'b': 9, 1:2, "x":'y', 'sum':32}. You may assume there are no duplicate keys.

In [2]:
def mergedicts(l):
    return {k:d[k] for d in l for k in d}

l = [{ 'a': 3, 'b': 9}, {1:2, "x":'y'}, {'sum':32}]
mergedicts(l)
Out[2]:
{'a': 3, 'b': 9, 1: 2, 'x': 'y', 'sum': 32}

Question 3

Write a recursive function named rcheck that takes a list argument named l and function argument f. Your function should call f with successive values of l until the return value is negative or all values of l have been tested. Your function does not return a value. For example if x=[1,2,3] and f(2) returns -1 then rcheck would call f(1) and f(2) and then return.

In [3]:
def rcheck(l,f):
    if len(l) < 1 or f(l[0]) < 0:
        return
    else:
        rcheck(l[1:],f)
        
def f(x):
    print(x)
    return -1 if x == 2 else 1

# alternative solution that modifies l
def rcheck(l,f):
    if l and f(l[0]) >= 0:
        l.pop(0)
        rcheck(l,f)
        
l=[1,2,3]
rcheck(l,f)
print(l)
1
2
[2, 3]

Question 4

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

  1. the letters CSTCE
  2. a 1- or 2-digit number
  3. the letter M
  4. one or two zeros (0 or 00)
  5. the letter G or V
  6. a 2-digit number
  7. an optional letter C
  8. the characters -R0

For example, re.search(pat,'CSTCE50M00G00C-R0') would return a match object but re.search(pat,'CSTCE50M0G00C-R00') would not.

In [4]:
pat=r'^CSTCE\d\d?M00?[GV]\d\dC?-R0$'

import re
print(re.search(pat,'CSTCE50M00G00C-R0'))
print(re.search(pat,'CSTCE50M0G00C-R00'))                
<_sre.SRE_Match object; span=(0, 17), match='CSTCE50M00G00C-R0'>
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(2,5)
        xe=choices(range(0,100,2),k=n)
        xo=choices(range(1,100,2),k=n)
        x=xe+xo
        shuffle(x)
        y=evens(x)
        assert len(y) == len(xe) and all((i in xe for i in y)), \
            "output is {} for input {}".format(y,x)

    def q2():
        ll=[randint(2,4) for i in range(randint(2,4))]
        n=sum(ll)
        r=randwords(n)+list(range(n))
        shuffle(r)
        l=[{r.pop():r.pop() for i in range(n)} for n in ll]
        l0=copy.deepcopy(l)
        y=mergedicts(l)
        assert len(y) == n and all([k in y and y[k] == d[k] for d in l0 for k in d]), \
            "mergedicts({}) returns {}".format(l0,y) 

    def q3():
        checkrecursive(rcheck)
        n=randint(3,5)
        l=[randint(0,9) for i in range(n)]
        fl=[]
        def found(x):
            fl.append(x)
            return -1 if x == 2 else 1
        l0=copy.copy(l)
        rcheck(l,found)
        m = l0.index(2)+1 if 2 in l0 else len(l0)
        assert fl == l0[:m], "rcheck({}) called f with {}".format(l0,fl)            
  
    def q4():
        ok=['CSTCE5M00G00C-R0', 'CSTCE50M0G00C-R0', 'CSTCE50M00V00C-R0', 
                'CSTCE50M00G45C-R0', 'CSTCE1M00G11-R0' ]
        nok=[' CSTCE50M00G00C-R0', 'CSTCE123M00G00C-R0', 'CSTCE50m000G00C-R0', 
                'CSTCE50M0000C-R0', 'CSTCE50M00G00C-R' ]
        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.