ELEX 4653 Sample 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 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 select that takes two list arguments named x and s. Your function should return a list consisting of all the values of x for which the corresponding value of s is true. For example, if x=[1, 'a', -1, "xyz"] and s=[True, 0, [], 3] your function should return [1, 'xyz']. You may assume both arguments are the same length.

In [1]:
def select(x,s):
    return [xi for xi,si in zip(x,s) if si]

x=[1, 'a', -1, "xyz"]
s=[True, 0, [], 3]
select(x,s)
Out[1]:
[1, 'xyz']

Question 2

Write a function named lookup that takes one dictionary argument named d and a list argument named l. The keys in d are strings and the values are integers. The values in l are strings. Your function should return a list of the values in d corresponding to the strings in l. For example if d = { 'add': 3, 'sub': 9, 'jmp': 32 } and l = ['sub', 'add', 'add'] then lookup(d,l) should return [9, 3, 3]. You may assume all the strings in l are keys in d.

In [2]:
def lookup(d,l):
    return [d[s] for s in l]

d = { 'add': 3, 'sub': 9, 'jmp': 32 }
l = ['sub', 'add', 'add']
lookup(d,l)
Out[2]:
[9, 3, 3]

Question 3

Write a recursive function named addsquares that takes a list argument named x and an integer argument m. Your function should append the values $m^2,(m-1)^2, \ldots$, 1$ to x. Your function does not return a value (it modifies x in place). For example if x=[1,2,3] then after calling addsquares(x,3) x would be equal to [1,2,3,9,4,1].

In [3]:
def addsquares(x,m):
    if m < 1:
        return
    else:
        x.append(m*m)
        addsquares(x,m-1)
        
x=[1,2,3]
addsquares(x,3)
x
Out[3]:
[1, 2, 3, 9, 4, 1]

Question 4

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

  1. a prefix of either JSM or CP
  2. a single digit between 1 and 4
  3. an optional letter S
  4. the letter A
  5. an optional letter H
  6. a dash
  7. the letters 12V or 24V

For example, re.search(pat,'JSM1SAH-12V') would return a match object but re.search(pat,'JSM1SAH-') would not.

In [4]:
pat=r'^(JSM|CP)[1234]S?AH?-(12|24)V$'

import re
print(re.search(pat,'JSM1SAH-12V'))
print(re.search(pat,'JSM1SAH-'))                
<_sre.SRE_Match object; span=(0, 11), match='JSM1SAH-12V'>
None
In [5]:
# exam validation code; do not modify
def examcheck():
    
    def randwords(n):
        from random import randint
        return [''.join([chr(randint(97,122)) for i in range(randint(2,5))]) 
           for j in range(n)]
    
    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):
        import hashlib
        # 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):
        import re
        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():
        from random import randint, choices
        import copy
        n=randint(4,7)
        s=choices([True, False, 0, 1, [], [1]],k=n)
        x=randwords(n)
        x0=copy.copy(x)
        y=select(x,s)
        assert all(x[i] in y for i in range(n) if s[i]), \
            "for x={} and s={} incorrect values included in result={}".format(x,s,y)
        assert len(y) == len([i for i in s if i]),"wrong number of values in result"

    def q2():
        from random import randint, shuffle
        n=randint(4,6)
        l=randwords(n)
        m=list(range(10,10+n))
        shuffle(m)
        d={s:m[i] for i,s in enumerate(l)}
        r={m[i]:s for i,s in enumerate(l)}
        x=lookup(d,l)
        assert all(r[n] == s for s,n in zip(l,x)) 

    def q3():
        from random import randint
        import copy
        checkrecursive(addsquares)
        n=randint(1,3)
        m=randint(2,4)
        x=list(range(n))
        x0=copy.copy(x)
        addsquares(x,m)
        sumsq=int((m/6)*(m+1)*(2*m+1)+0.5)
        msg="addsquare(x={},{}) results in x={}".format(x0,m,x)
        assert x[:n] == x0, "initial values changed: "+msg
        assert sum(x[n:]) == sumsq, "wrong squares: "+msg
            
  
    def q4():
        ok=['JSM1SAH-12V', 'CP4A-24V', 'JSM4AH-12V', 'CP3SA-12V', 'JSM2A-24V' ]
        nok=[' JSM1SAH-12V', 'JS1SAH-12V', 'JSM1SAH-', 'CPA-12V', 'CP1SA-24' ]
        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.